d52-3.4.1.orig/0000700000175000017500000000000010755573413011232 5ustar uweuwed52-3.4.1.orig/analyze52.c0000644000175000017500000004164310666545141013230 0ustar uweuwe /* * D52 8052 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * analyze52.c - 8052 disassembler code analyzer specific data and routines * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include "d52.h" #include "common.h" #include "analyze.h" #include "analyze52.h" #include "d52table.h" //#define DEBUG // Global variables // Vector table of traceable addresses: // IE0, TF0, IE1, TF1, and RI+TI int vectortable[] = { 0x0003, 0x000b, 0x0013, 0x001b, 0x0023, 0 }; int dptrval = 0; int dstackPtr = 0; int dstack[STACK_DEPTH * 4]; // dptr references stack // Code // Attempt to determine the type of non-code data // (locations that haven't been traced). bool aPass1(void) { int i, j; int start, stop, pc; int adrs, begin; byte aflag, lastflag, data = 0, lastdata; char code; pc = start = stop = begin = offset; lastflag = analysisFlags[offset]; for (i=offset; i= MIN_STR_LEN) // if at min ascii chars in code = 't'; // a row, tag the block as text data = pgmmem[pc]; } if (analysisFlags[start + 1] == ANALYZE_NONE) { // check for possible vector in data adrs = (int) pgmmem[start] << 8; adrs |= ((int) pgmmem[start + 1] & 0xff); adrs &= WORD_MASK; // D52 uses dstack here, DZ80 uses vstack if ((adrs > offset) && (adrs < himark)) { // if it might be a vector... for (j=0; j offset) && (adrs < himark)) // looks like a vector { analysisFlags[pc] = ANALYZE_VECTOR | ANALYZE_TRACED; pc++; lastdata |= analysisFlags[pc]; analysisFlags[pc] = ANALYZE_VECTOR | ANALYZE_TRACED; if (analysisFlags[adrs] == ANALYZE_NONE) { if (trace(adrs)) return TRUE; } } else // not a vector, must be binary { analysisFlags[pc] = ANALYZE_BINARY | ANALYZE_TRACED; } pc++; lastdata |= analysisFlags[pc]; lastdata |= analysisFlags[pc + 1]; } if (analysisFlags[pc] == ANALYZE_NONE) analysisFlags[pc] = ANALYZE_BINARY | ANALYZE_TRACED; } } } } if (isprint(data) && (data != '"')) // see if it might be a text string { if (code != 't') { for (j=1; j= MIN_STR_LEN) // yup, looks like a text string { code = 't'; for (adrs=start+1; adrs= pc) analysisFlags[start] = ANALYZE_BINARY | ANALYZE_TRACED; // start might be >= pc else { for (adrs=start+1; adrs i) i = pc; code = 0; break; case (ANALYZE_CODE + ANALYZE_TRACED): code = 'c'; break; case (ANALYZE_VECTOR + ANALYZE_TRACED): code = 'a'; break; } lastflag = aflag; start = i; } // end of if ((aflag != lastflag) || (i == himark - 1)) } // end of for (i=offset; i= STACK_DEPTH) { analysisWarning("trace stack overflow!"); return TRUE; } break; case OPCODE_LCALL: pushLevelSave = pushLevel; pushLevel = 0; tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; adrs = pgmmem[tpc++] << 8; analysisFlags[tpc] = ANALYZE_TAGGED; adrs |= (pgmmem[tpc++] & 0xff); adrs &= WORD_MASK; astack[astackPtr++] = tpc; if (astackPtr >= STACK_DEPTH) { analysisWarning("trace stack overflow!"); return TRUE; } tpc = adrs; break; // Saving dptr on vector stack at a return instruction catches those // sequences whereby code is accessed through a table of vectors pointed // to by dptr and the address has been pushed on the 8052 stack. // A typical sequence might be: // // mov dptr,#jumptable ; accumulator is table index // rl a ; double it // push acc ; and save it // movc a,@a+dptr ; fetch 8 bits of address // mov r2,a ; save address // inc dptr // pop acc ; recover offset into table // movc a,@a+dptr ; get remainder of address // push acc // mov a,r2 // push acc ; push address on stack // ret ; go there case OPCODE_RET: if ((pushLevel > 0) && dptr) { pushLevel = pushLevelSave; vstack[vstackPtr++] = dptr; if (vstackPtr >= STACK_DEPTH) { analysisWarning("vector stack overflow!"); return TRUE; } } // break; // flow through to check astack case OPCODE_RETI: if (astackPtr) { --astackPtr; tpc = astack[astackPtr]; } else done = TRUE; break; case OPCODE_JMPDPTR: // jmp @a+dptr if (astackPtr) { --astackPtr; tpc = astack[astackPtr]; } else done = TRUE; dptr = dptrval; if (dptr) { analysisFlags[dptr] = ANALYZE_CODE; code = pgmmem[dptr]; // see if this is a jump table switch (code) { case OPCODE_AJMP: while (pgmmem[dptr] == code) { analysisFlags[dptr++] = ANALYZE_CODE; adrs = pgmmem[dptr] & 0xff; analysisFlags[dptr++] = ANALYZE_CODE; adrs |= (dptr & 0xff); if ((adrs >= offset) && (adrs <= himark)) analysisFlags[adrs] = ANALYZE_CODE; } break; case OPCODE_LJMP: while (pgmmem[dptr] == code) { analysisFlags[dptr++] = ANALYZE_CODE; adrs = pgmmem[dptr] << 8; analysisFlags[dptr++] = ANALYZE_CODE; adrs |= (pgmmem[dptr] & 0xff); analysisFlags[dptr++] = ANALYZE_CODE; dptr++; // must be on even boundary if ((adrs >= offset) && (adrs <= himark)) analysisFlags[adrs] = ANALYZE_CODE; } break; case OPCODE_SJMP: while (pgmmem[dptr] == code) { analysisFlags[dptr++] = ANALYZE_CODE; adrs = pgmmem[dptr]; analysisFlags[dptr++] = ANALYZE_CODE; adrs += dptr; if ((adrs >= offset) && (adrs <= himark)) analysisFlags[adrs] = ANALYZE_CODE; } break; } } break; // conditional jumps case OPCODE_JC: case OPCODE_JNC: case OPCODE_JZ: case OPCODE_JNZ: adrs = tpc + 2; tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; dest = (int) pgmmem[tpc++] & 0xff; if (dest & 0x80) dest |= 0xff00; adrs += dest; adrs &= WORD_MASK; astack[astackPtr++] = adrs; // save jump address on analysis stack if (astackPtr >= STACK_DEPTH) { analysisWarning("trace stack overflow!"); return TRUE; } break; // unconditional jump case OPCODE_SJMP: adrs = tpc + 2; tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; dest = (int) pgmmem[tpc++] & 0xff; if (dest & 0x80) dest |= 0xff00; adrs += dest; adrs &= WORD_MASK; tpc = adrs; break; case OPCODE_PUSH: tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; pushLevel++; break; case OPCODE_POP: tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; if (pushLevel > 0) --pushLevel; break; case OPCODE_MOVDPTR: tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; dptr = pgmmem[tpc++] << 8; analysisFlags[tpc] = ANALYZE_TAGGED; dptr |= (pgmmem[tpc++] & 0xff); dptr &= WORD_MASK; dptrval = dptr; if (dptrtrace) { for (stuffdptr = 1, dptrcount=0; dptrcount < dstackPtr; dptrcount++) { if (dptr == dstack[dptrcount]) { stuffdptr = 0; break; } } if (stuffdptr) // treat dptr stack overflow as warning, not error { dstack[dstackPtr++] = dptr; if (dstackPtr >= STACK_DEPTH) { analysisWarning("dptr stack overflow!"); dptrtrace = 0; } } } break; default: if ((code & OPCODE_AJMP_MASK) == OPCODE_AJMP) { tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; adrs = tpc + 1; dest = ((int) code & 0xe0) << 3; dest += ((int) pgmmem[tpc++] & 0xff); dest &= WORD_MASK; adrs = dest; tpc = adrs; } else if ((code & OPCODE_ACALL_MASK) == OPCODE_ACALL) { pushLevelSave = pushLevel; pushLevel = 0; tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; adrs = tpc + 1; dest = ((int) code & 0xe0) << 3; dest |= ((int) pgmmem[tpc++] & 0xff); dest &= WORD_MASK; adrs = dest; astack[astackPtr++] = tpc; if (astackPtr >= STACK_DEPTH) { analysisWarning("trace stack overflow!"); return TRUE; } tpc = adrs; } else if ((code == OPCODE_DJNZ1) || (code >= OPCODE_CJNE1 && code <= OPCODE_CJNE2)) { tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; adrs = tpc + 1; dest = (int) pgmmem[tpc++] & 0xff; if (dest & 0x80) dest |= 0xff00; adrs += dest; adrs &= WORD_MASK; astack[astackPtr++] = tpc; if (astackPtr >= STACK_DEPTH) { analysisWarning("trace stack overflow!"); return TRUE; } tpc = adrs; } else if ((code & OPCODE_DJNZ_MASK) == OPCODE_DJNZ) { tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; adrs = tpc + 1; dest = (int) pgmmem[tpc++] & 0xff; if (dest & 0x80) dest |= 0xff00; adrs += dest; adrs &= WORD_MASK; astack[astackPtr++] = tpc; if (astackPtr >= STACK_DEPTH) { analysisWarning("trace stack overflow!"); return TRUE; } tpc = adrs; } else { if (opttbl[code] & OPT_2) { tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; } else if (opttbl[code] & OPT_3) { tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; } else tpc++; } break; } } return FALSE; } // end of analyze52.c d52-3.4.1.orig/analyze52.h0000664000175000017500000000331510666547723013241 0ustar uweuwe /* * D52 8052 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * analyze52.h - 8052 disassembler code analyzer * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _ANALYZE52_H_ #define _ANALYZE52_H_ // Defined Constants #define OPCODE_AJMP 0x01 #define OPCODE_LJMP 0x02 #define OPCODE_JBC 0x10 #define OPCODE_ACALL 0x11 #define OPCODE_LCALL 0x12 #define OPCODE_JB 0x20 #define OPCODE_RET 0x22 #define OPCODE_JNB 0x30 #define OPCODE_RETI 0x32 #define OPCODE_JC 0x40 #define OPCODE_JNC 0x50 #define OPCODE_JZ 0x60 #define OPCODE_JNZ 0x70 #define OPCODE_JMPDPTR 0x73 #define OPCODE_SJMP 0x80 #define OPCODE_CJNE1 0xb4 #define OPCODE_CJNE2 0xbf #define OPCODE_PUSH 0xc0 #define OPCODE_POP 0xd0 #define OPCODE_DJNZ1 0xd5 #define OPCODE_DJNZ 0xd8 #define OPCODE_ACALL_MASK 0x1f #define OPCODE_AJMP_MASK 0x1f #define OPCODE_DJNZ_MASK 0xf8 #define OPCODE_MOVDPTR 0x90 #endif // _ANALYZE52_H_ d52-3.4.1.orig/analyze.c0000644000175000017500000004772710666553776013107 0ustar uweuwe /* * DZ80 Z80 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * analyze.c - 8052/Z80 disassembler code analyzer common data and routines * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ // Common data and routines for 8052 and Z80 code analyzers #include #include #include #include #include #include "defs.h" #include "common.h" #include "analyze.h" //#define DEBUG // Global variables byte *analysisFlags = NULL; int tpc; // trace pc int pushLevel = 0; int astackPtr = 0; int astack[STACK_DEPTH]; // analysis stack, for returns and branches int vstackPtr = 0; int vstack[STACK_DEPTH]; // possible vector references stack char alertMessage[128]; #ifdef DEBUG int pushLevelMax = 0; #endif FILE *ctlfp; int listCount = 0; char fileName[256]; char fileExt[128]; char tempString[128]; char dateString[64]; STRLIST *ctlLineList; // Code #ifdef DEBUG void dumpAnalysisFlags(void) { int i; fprintf(stderr, "\nAnalysis flags:\n"); for (i=offset; i offset) && (dptr < himark)) { while (1) { if (analysisFlags[dptr] != ANALYZE_NONE) break; adrs = dptr; vector = ((int) pgmmem[dptr++] << 8); vector |= ((int) pgmmem[dptr++] & 0xff); vector &= WORD_MASK; if ((vector > offset) && (vector < himark)) { analysisFlags[adrs] = ANALYZE_VECTOR | ANALYZE_TRACED; analysisFlags[adrs + 1] = ANALYZE_VECTOR | ANALYZE_TRACED; if (trace(vector)) return TRUE; } else break; if (dptr >= himark) break; } } } } return FALSE; } #if 0 // Attempt to determine the type of non-code data. // (locations that haven't been traced). bool aPass1(void) { int i, j; int start, stop, pc; int adrs, begin; byte aflag, lastflag, data = 0, lastdata; char code; pc = start = stop = begin = offset; lastflag = analysisFlags[offset]; for (i=offset; i= MIN_STR_LEN) // if at min ascii chars in code = 't'; // a row, tag the block as text data = pgmmem[pc]; } if (analysisFlags[start + 1] == ANALYZE_NONE) { // check for possible vector in data adrs = (int) pgmmem[start] << 8; adrs |= ((int) pgmmem[start + 1] & 0xff); adrs &= WORD_MASK; // D52 uses dstack here, DZ80 uses vstack if ((adrs > offset) && (adrs < himark)) { // if it might be a vector... for (j=0; j offset) && (adrs < himark)) // looks like a vector { analysisFlags[pc] = ANALYZE_VECTOR | ANALYZE_TRACED; pc++; lastdata |= analysisFlags[pc]; analysisFlags[pc] = ANALYZE_VECTOR | ANALYZE_TRACED; if (analysisFlags[adrs] == ANALYZE_NONE) { if (trace(adrs)) return TRUE; } } else // not a vector, must be binary { analysisFlags[pc] = ANALYZE_BINARY | ANALYZE_TRACED; } pc++; lastdata |= analysisFlags[pc]; lastdata |= analysisFlags[pc + 1]; } if (analysisFlags[pc] == ANALYZE_NONE) analysisFlags[pc] = ANALYZE_BINARY | ANALYZE_TRACED; } } } } if (isprint(data) && (data != '"')) // see if it might be a text string { if (code != 't') { for (j=1; j= MIN_STR_LEN) // yup, looks like a text string { code = 't'; for (adrs=start+1; adrs= pc) analysisFlags[start] = ANALYZE_BINARY | ANALYZE_TRACED; // start might be >= pc else { for (adrs=start+1; adrs i) i = pc; code = 0; break; case (ANALYZE_CODE + ANALYZE_TRACED): code = 'c'; break; case (ANALYZE_VECTOR + ANALYZE_TRACED): code = 'a'; break; } lastflag = aflag; start = i; } // end of if ((aflag != lastflag) || (i == himark - 1)) } // end of for (i=offset; i offset) && (adrs < himark)) // looks like a vector { if (analysisFlags[adrs] == ANALYZE_NONE || analysisFlags[adrs] == ANALYZE_TAGGED) { analysisFlags[start] = ANALYZE_VECTOR | ANALYZE_TRACED; analysisFlags[start + 1] = ANALYZE_VECTOR | ANALYZE_TRACED; if (analysisFlags[adrs] == ANALYZE_NONE) trace(adrs); start++; tagged = TRUE; } } if (!tagged) analysisFlags[start] = ANALYZE_BINARY | ANALYZE_TRACED; } else analysisFlags[start] = ANALYZE_BINARY | ANALYZE_TRACED; start++; } start = begin; } begin++; } start = i; j = TRUE; } } } return FALSE; } // Check if data at 'pc' appears to be an ascii string. // Return TRUE if so, else return FALSE. bool isString(int pc, int stop) { int i; bool retval = FALSE; byte data; data = pgmmem[pc]; if (isprint(data) && data != '"') { for (i=0; i= MIN_STR_LEN) // if at least min ascii chars in retval = TRUE; // a row, then might be ascii text } return retval; } // Return address of end of string at 'pc'. // Assumes that pc does point to a string. int getEndOfString(int pc, int stop) { byte data; data = pgmmem[pc]; while (isprint(data) && data != '"' && pc < stop) { pc++; data = pgmmem[pc]; } return pc; } // Check if code at 'pc' appears to be traceable. // Return TRUE if so, else return FALSE. // We assume it's not valid code if it's a series // of TRACE_CHECK_LEN bytes of 0x00 or 0xff in a row. bool isTraceableCode(int pc) { int i; bool retval = FALSE; byte code; for (i=0; i 1) { sprintf(ostr, "i 0000-%04x\t; Invalid data", offset - 1); addListEntry(ostr); } for (i=offset; i= start) { if (stop > start) sprintf(ostr, "%c %04x-%04x", code, start, stop); else sprintf(ostr, "%c %04x\t", code, start); strcat(ostr, datatype); addListEntry(ostr); } start = i; lastflag = aflag; } } } // Pass "D52" or "DZ80" in dtext int createLineList(char *dtext) { int year; time_t tp; if (ctlLineList) deleteLineList(); ctlLineList = malloc(sizeof(STRLIST)); if (!ctlLineList) { printf("No memory for line list.\n"); if (ctlfp) { fclose(ctlfp); ctlfp = NULL; } return -1; } ctlLineList->str = NULL; ctlLineList->prev = NULL; ctlLineList->next = NULL; addListEntry(";"); strcpy(tempString, "; "); strcat(tempString, dtext); strcat(tempString, " configuration file for "); strcat(tempString, src); addListEntry(tempString); sprintf(tempString, "; Generated by %s V%d.%d.%d on ", dtext, VERSION, MAJORREV, MINORREV); time(&tp); // get current time date_time = localtime(&tp); // convert to hr/min/day etc year = date_time->tm_year + 1900; sprintf(dateString, "%d/%02d/%02d %02d:%02d", year, date_time->tm_mon + 1, date_time->tm_mday, date_time->tm_hour, date_time->tm_min); strcat(tempString, dateString); addListEntry(tempString); addListEntry(";"); if (offset) { sprintf(tempString, "o %04x\t\t; program offset", offset); addListEntry(tempString); } return listCount; } void deleteLineList(void) { STRLIST *list, *prev; list = ctlLineList; while (list) { prev = list; list = list->next; free(prev->str); free(prev); } ctlLineList = NULL; listCount = 0; } int writeCtlFile(void) { STRLIST *list; char *str = NULL; list = ctlLineList; if (!list) { if (ctlfp) { fclose(ctlfp); ctlfp = NULL; } return -1; } if (ctlfp) { fclose(ctlfp); strcpy(fileName, ctl); strcat(fileName, ".backup"); rename(ctl, fileName); } ctlfp = fopen(ctl, "w"); // reopen ctl file for writing if (!ctlfp) return -1; while (list) { str = list->str; if (str && *str) fprintf(ctlfp, "%s\n", str); list = list->next; } fflush(ctlfp); fclose(ctlfp); ctlfp = NULL; return 0; } bool addListEntry(char *str) { STRLIST *list = ctlLineList; if (!list) return FALSE; while (list->next) list = list->next; list->next = malloc(sizeof(STRLIST)); if (!list->next) return FALSE; list->next->prev = list; list = list->next; list->next = NULL; list->str = malloc(strlen(str) + 2); if (!list->str) return FALSE; strcpy(list->str, str); listCount++; return TRUE; } void analysisWarning(char *msg) { sprintf(alertMessage, "\nAnalysis warning - "); strcat(alertMessage, msg); printf("%s\n", alertMessage); } void analysisError(char *msg) { sprintf(alertMessage, "\nAnalysis incomplete - "); strcat(alertMessage, msg); printf("%s\n", alertMessage); } // end of analyze.c d52-3.4.1.orig/analyze.h0000644000175000017500000000520610666547776013101 0ustar uweuwe /* * D52 8052 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * analyze.h - 8052/Z80 disassembler code analyzer common code * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _ANALYZE_H_ #define _ANALYZE_H_ // Defined Constants #define STACK_DEPTH 1024 #define MIN_STR_LEN 5 // minimum number of characters to ID a string #define TRACE_CHECK_LEN 4 // number of code bytes to check for valid code #define ANALYZE_NONE 0x00 #define ANALYZE_TRACED 0x01 #define ANALYZE_CODE 0x02 #define ANALYZE_VECTOR 0x04 #define ANALYZE_BINARY 0x08 #define ANALYZE_ASCII 0x10 #define ANALYZE_IGNORE 0x20 #define ANALYZE_TAGGED (ANALYZE_TRACED | ANALYZE_CODE) #define ANALYZE_END 0x80 typedef struct strlist { char *str; struct strlist *prev; struct strlist *next; } STRLIST; // Data extern int vectortable[]; extern FILE *ctlfp; extern int listCount; extern char fileName[256]; extern char fileExt[128]; extern char tempString[128]; extern char dateString[64]; extern byte *analysisFlags; extern int tpc; // trace pc extern int pushLevel; extern int astackPtr; extern int astack[STACK_DEPTH]; // analysis stack, for returns and branches extern int vstackPtr; extern int vstack[STACK_DEPTH]; // possible vector references stack extern char alertMessage[128]; // Prototypes extern bool analyzeCode(char *dtext); extern bool analyze(void); extern bool aPass1(void); extern bool aPass2(void); extern bool trace(int pc); extern bool isString(int pc, int stop); extern int getEndOfString(int pc, int stop); extern bool isTraceableCode(int pc); extern void genAnalysisList(void); extern int createLineList(char *dtext); extern void deleteLineList(void); extern int writeCtlFile(void); extern bool addListEntry(char *str); extern void analysisWarning(char *msg); extern void analysisError(char *msg); #endif // _ANALYZE_H_ d52-3.4.1.orig/analyzez80.c0000644000175000017500000004131310666545212013414 0ustar uweuwe /* * DZ80 Z80 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * analyzez80.c - Z80 disassembler code analyzer specific data and routines * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include "dz80.h" #include "common.h" #include "analyze.h" #include "analyzez80.h" #include "dz80table.h" //#define DEBUG // Global variables // Traceable reset and NMI vectors int vectortable[] = { 0x0008, 0x0010, 0x0018, 0x0020, 0x0028, 0x0030, 0x0038, 0x0066, 0 }; // reset, rst, and nmi vector addresses int vectoradrstbl[] = { 0x0001, 0x0009, 0x0011, 0x0019, 0x0021, 0x0029, 0x0031, 0x0039, 0x0067, 0 }; int hlreg = 0, ixreg = 0, iyreg = 0; #ifdef DEBUG int pushLevelMax = 0; #endif int astackMax = 0; int vstackMax = 0; // Code // Attempt to determine the type of non-code data. // (locations that haven't been traced). bool aPass1(void) { int i, j; int start, stop, pc; int adrs, begin; byte aflag, lastflag, data = 0, lastdata; char code; pc = start = stop = begin = offset; lastflag = analysisFlags[offset]; for (i=offset; i= MIN_STR_LEN) // if at min ascii chars in code = 't'; // a row, tag the block as text data = pgmmem[pc]; } if (analysisFlags[start + 1] == ANALYZE_NONE) { // check for possible vector in data adrs = (int) pgmmem[start] << 8; adrs |= ((int) pgmmem[start + 1] & 0xff); adrs &= WORD_MASK; // D52 uses dstack here, DZ80 uses vstack if ((adrs > offset) && (adrs < himark)) { // if it might be a vector... for (j=0; j offset) && (adrs < himark)) // looks like a vector { analysisFlags[pc] = ANALYZE_VECTOR | ANALYZE_TRACED; pc++; lastdata |= analysisFlags[pc]; analysisFlags[pc] = ANALYZE_VECTOR | ANALYZE_TRACED; if (analysisFlags[adrs] == ANALYZE_NONE) { if (trace(adrs)) return TRUE; } } else // not a vector, must be binary { analysisFlags[pc] = ANALYZE_BINARY | ANALYZE_TRACED; } pc++; lastdata |= analysisFlags[pc]; lastdata |= analysisFlags[pc + 1]; } if (analysisFlags[pc] == ANALYZE_NONE) analysisFlags[pc] = ANALYZE_BINARY | ANALYZE_TRACED; } } } } if (isprint(data) && (data != '"')) // see if it might be a text string { if (code != 't') { for (j=1; j= MIN_STR_LEN) // yup, looks like a text string { code = 't'; for (adrs=start+1; adrs= pc) analysisFlags[start] = ANALYZE_BINARY | ANALYZE_TRACED; // start might be >= pc else { for (adrs=start+1; adrs i) i = pc; code = 0; break; case (ANALYZE_CODE + ANALYZE_TRACED): code = 'c'; break; case (ANALYZE_VECTOR + ANALYZE_TRACED): code = 'a'; break; } lastflag = aflag; start = i; } // end of if ((aflag != lastflag) || (i == himark - 1)) } // end of for (i=offset; i astackMax) astackMax = astackPtr; if (astackPtr >= STACK_DEPTH) { analysisWarning("trace stack overflow!"); return TRUE; } tpc = adrs; break; case OPCODE_RET: case OPCODE_RETI: case OPCODE_RETN: if (astackPtr) { --astackPtr; tpc = astack[astackPtr]; } else done = TRUE; break; case OPCODE_JPHL: // jp (hl) - we don't know where this will go if ((hlreg > offset) && (hlreg < himark)) { vstack[vstackPtr++] = hlreg; if (vstackPtr > vstackMax) vstackMax = vstackPtr; if (vstackPtr >= STACK_DEPTH) { analysisWarning("vector stack overflow!"); return TRUE; } } break; case OPCODE_JPIX: if ((ixreg > offset) && (ixreg < himark)) { vstack[vstackPtr++] = ixreg; if (vstackPtr > vstackMax) vstackMax = vstackPtr; if (vstackPtr >= STACK_DEPTH) { analysisWarning("vector stack overflow!"); return TRUE; } } break; case OPCODE_JPIY: if ((iyreg > offset) && (iyreg < himark)) { vstack[vstackPtr++] = iyreg; if (vstackPtr > vstackMax) vstackMax = vstackPtr; if (vstackPtr >= STACK_DEPTH) { analysisWarning("vector stack overflow!"); return TRUE; } } break; case OPCODE_JR: adrs = tpc + 2; tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; dest = (int) pgmmem[tpc++] & 0xff; if (dest & 0x80) dest |= 0xff00; adrs += dest; adrs &= WORD_MASK; tpc = adrs; break; case OPCODE_JRC: case OPCODE_JRNC: case OPCODE_JRZ: case OPCODE_JRNZ: adrs = tpc + 2; tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; dest = (int) pgmmem[tpc++] & 0xff; if (dest & 0x80) dest |= 0xff00; adrs += dest; adrs &= WORD_MASK; astack[astackPtr++] = adrs; if (astackPtr > astackMax) astackMax = astackPtr; if (astackPtr >= STACK_DEPTH) { analysisWarning("trace stack overflow!"); return TRUE; } break; case OPCODE_JP: adrs = tpc + 3; analysisFlags[tpc + 1] = ANALYZE_TAGGED; analysisFlags[tpc + 2] = ANALYZE_TAGGED; tpc++; dest = (int) pgmmem[tpc++] & 0xff; dest |= (((int) pgmmem[tpc++] & 0xff) << 8); tpc = dest; break; case OPCODE_JPC: case OPCODE_JPNC: case OPCODE_JPZ: case OPCODE_JPNZ: case OPCODE_JPPE: case OPCODE_JPPO: case OPCODE_JPM: case OPCODE_JPP: adrs = tpc + 3; analysisFlags[tpc + 1] = ANALYZE_TAGGED; analysisFlags[tpc + 2] = ANALYZE_TAGGED; tpc++; dest = (int) pgmmem[tpc++] & 0xff; dest |= (((int) pgmmem[tpc++] & 0xff) << 8); astack[astackPtr++] = dest; if (astackPtr > astackMax) astackMax = astackPtr; if (astackPtr >= STACK_DEPTH) { analysisWarning("trace stack overflow!"); return TRUE; } break; case OPCODE_PUSHAF: case OPCODE_PUSHBC: case OPCODE_PUSHDE: case OPCODE_PUSHHL: analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; pushLevel++; #ifdef DEBUG if (pushLevel > pushLevelMax) pushLevelMax = pushLevel; #endif break; case OPCODE_PUSHIX: case OPCODE_PUSHIY: tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; pushLevel++; #ifdef DEBUG if (pushLevel > pushLevelMax) pushLevelMax = pushLevel; #endif break; case OPCODE_POPAF: case OPCODE_POPBC: case OPCODE_POPDE: case OPCODE_POPHL: analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; if (pushLevel > 0) --pushLevel; break; case OPCODE_POPIX: case OPCODE_POPIY: tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; if (pushLevel > 0) --pushLevel; break; default: if (code == OPCODE_DJNZ) { tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; adrs = tpc + 1; dest = (int) pgmmem[tpc++] & 0xff; if (dest & 0x80) dest |= 0xff00; adrs += dest; adrs &= WORD_MASK; astack[astackPtr++] = tpc; if (astackPtr > astackMax) astackMax = astackPtr; if (astackPtr >= STACK_DEPTH) { analysisWarning("trace stack overflow!"); return TRUE; } tpc = adrs; } else if (code < 0x100) { if (code == OPCODE_LDHL) // ld hl,nn { hlreg = pgmmem[tpc + 1] & 0xff; hlreg |= ((pgmmem[tpc + 2] & 0xff) << 8); } else if (code == OPCODE_LDHLI) // ld hl,(nn) { dptr = pgmmem[tpc + 1] & 0xff; dptr |= ((pgmmem[tpc + 2] & 0xff) << 8); hlreg = pgmmem[dptr] & 0xff; hlreg |= ((pgmmem[dptr + 1] & 0xff) << 8); } else if (code == OPCODE_LDNNHL) // ld (nn),hl { dptr = pgmmem[tpc + 1] & 0xff; dptr |= ((pgmmem[tpc + 2] & 0xff) << 8); i = 0; while (vectoradrstbl[i]) { if (dptr == vectoradrstbl[i]) { if ((hlreg >= offset) && (hlreg < himark)) { astack[astackPtr++] = hlreg; if (astackPtr > astackMax) astackMax = astackPtr; if (astackPtr >= STACK_DEPTH) { analysisWarning("trace stack overflow!"); return TRUE; } } break; } i++; } } if (opttbl[code] & OPT_2) { tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; } else if (opttbl[code] & OPT_3) { tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; } else tpc++; } else // code >= 0x100 { if (code == OPCODE_LDIX) // ld ix,nn { ixreg = pgmmem[tpc + 1] & 0xff; ixreg |= ((pgmmem[tpc + 2] & 0xff) << 8); } else if (code == OPCODE_LDIXI) // ld ix,(nn) { dptr = pgmmem[tpc + 1] & 0xff; dptr |= ((pgmmem[tpc + 2] & 0xff) << 8); ixreg = pgmmem[dptr] & 0xff; ixreg |= ((pgmmem[dptr + 1] & 0xff) << 8); } else if (code == OPCODE_LDIY) // ld iy,nn { iyreg = pgmmem[tpc + 1] & 0xff; iyreg |= ((pgmmem[tpc + 2] & 0xff) << 8); } else if (code == OPCODE_LDIYI) // ld iy,(nn) { dptr = pgmmem[tpc + 1] & 0xff; dptr |= ((pgmmem[tpc + 2] & 0xff) << 8); iyreg = pgmmem[dptr] & 0xff; iyreg |= ((pgmmem[dptr + 1] & 0xff) << 8); } tpc++; analysisFlags[tpc] = ANALYZE_TAGGED; tpc++; } break; } } return FALSE; } // end of analyzez80.c d52-3.4.1.orig/analyzez80.h0000664000175000017500000000567110666550020013423 0ustar uweuwe /* * D52 8052 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * analyzez80.h - Z80 disassembler code analyzer * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _ANALYZEZ80_H_ #define _ANALYZEZ80_H_ // Defined Constants #define OPCODE_LDHL 0x21 // ld hl,nn #define OPCODE_LDHLI 0x2a // ld hl,(nn) #define OPCODE_LDNNHL 0x22 // ld (nn),hl #define OPCODE_LDIX 0xdd21 // ld ix,nn #define OPCODE_LDIY 0xfd21 // ld iy,nn #define OPCODE_LDIXI 0xdd2a // ld ix,(nn) #define OPCODE_LDIYI 0xfd2a // ld iy,(nn) #define OPCODE_JP 0xc3 #define OPCODE_JPC 0xda #define OPCODE_JPNC 0xd2 #define OPCODE_JPZ 0xca #define OPCODE_JPNZ 0xc2 #define OPCODE_JPPE 0xea #define OPCODE_JPPO 0xe2 #define OPCODE_JPM 0xfa #define OPCODE_JPP 0xf2 #define OPCODE_JPHL 0xe9 #define OPCODE_JPIX 0xdde9 #define OPCODE_JPIY 0xfde9 #define OPCODE_JR 0x18 #define OPCODE_JRC 0x38 #define OPCODE_JRNC 0x30 #define OPCODE_JRZ 0x28 #define OPCODE_JRNZ 0x20 #define OPCODE_DJNZ 0x10 #define OPCODE_CALL 0xcd #define OPCODE_CALLC 0xdc #define OPCODE_CALLNC 0xd4 #define OPCODE_CALLZ 0xcc #define OPCODE_CALLNZ 0xc4 #define OPCODE_CALLPE 0xec #define OPCODE_CALLPO 0xe4 #define OPCODE_CALLM 0xfc #define OPCODE_CALLP 0xf4 #define OPCODE_RST00 0xc7 #define OPCODE_RST08 0xcf #define OPCODE_RST10 0xd7 #define OPCODE_RST18 0xdf #define OPCODE_RST20 0xe7 #define OPCODE_RST28 0xef #define OPCODE_RST30 0xf7 #define OPCODE_RST38 0xff #define OPCODE_RET 0xc9 #define OPCODE_RETC 0xd8 #define OPCODE_RETNC 0xd0 #define OPCODE_RETZ 0xc8 #define OPCODE_RETNZ 0xc0 #define OPCODE_RETPE 0xe8 #define OPCODE_RETPO 0xe0 #define OPCODE_RETM 0xf8 #define OPCODE_RETP 0xf0 #define OPCODE_RETI 0xed4d #define OPCODE_RETN 0xed45 #define OPCODE_PUSHAF 0xf5 #define OPCODE_PUSHBC 0xc5 #define OPCODE_PUSHDE 0xd5 #define OPCODE_PUSHHL 0xe5 #define OPCODE_PUSHIX 0xdde5 #define OPCODE_PUSHIY 0xfde5 #define OPCODE_POPAF 0xf1 #define OPCODE_POPBC 0xc1 #define OPCODE_POPDE 0xd1 #define OPCODE_POPHL 0xe1 #define OPCODE_POPIX 0xdde1 #define OPCODE_POPIY 0xfde1 #endif // _ANALYZEZ80_H_ d52-3.4.1.orig/common.c0000644000175000017500000013365710666553732012722 0ustar uweuwe /* * Disassembler common routines * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * common.c - Support routines * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include "d52.h" #include "common.h" // Global variables char src[FN_LEN], dst[FN_LEN]; // file name buffers char baseFileName[FN_LEN]; // source file name without extension char ctl[FN_LEN]; // control file name char linebuffer[MAX_LINE]; // input line buffer FILE *fp; // dos file struct int hexflag; // append hex flag int fileflag; // file type flag int upperflag; // upper case output flag int baseflag; int traceflag; // trace and analyze code int kcnt; // output char counter int pc; // current program counter int himark; // highest data adrs int offset; // program counter offset byte *pgmmem; // program data pointer int *pgmflags; // pointer to program flags #ifdef EXTENDED_MEM byte *epgmmem[EXT_PGM_SEGS]; // extended program memory pointers int *epgmflags[EXT_PGM_SEGS]; // extended program flags pointers #endif char string[ASCLIMIT]; // ascii data for defb int asc_cnt; // count for string data byte byte_data[BYTELIMIT]; // binary data for defb int byte_cnt; // count for binary data int word_data[WORDLIMIT]; // binary data for defw int word_cnt; // count for word data byte dump; // dump just done flag byte ascii_flag; // use ascii string flag char defbstr[8]; // string for defined bytes char defwstr[8]; // string for defined words char ascistr[8]; // string for defined ascii char orgstr[8] = "org"; // org pseudo-op string char equstr[8] = "equ"; // equ pseudo-op string struct sym *sym_tab; // symbol table pointer struct sym *lab_tab; // label table pointer struct sym *name_tab; // operand names pointer struct sym *sym_tab_last; // last symbol table pointer struct sym *lab_tab_last; // lastlabel table pointer struct sym *name_tab_last; // last name table pointer int symbol_count; // number of symbols int label_count; // number of labels int name_count; // number of operand names SYM_PTR *sym_val_index; // array of pointers SYM_PTR *lab_val_index; // for binary search SYM_PTR *name_val_index; struct sym *tail_ptr, *head_ptr; // sort pointers struct comment *comment_list; // header comment list struct comment *icomment_list; // inline comment list struct comment *patch_list; // patch list int newline; // just output newline flag struct tm *date_time; // disassembly time bool cycleflag; bool cycle_exclude; bool cycle_alwaystake; CYCLE_RANGE_PTR cycle_r; // cycles CYCLE_RANGE_PTR cycle_current; char licenseText[] = "\nReleased under the GNU General Public License Version 3\n"; // // Code // #if defined __LCC__ int strcasecmp(char *s1, char *s2) { while (*s1 != '\0' && tolower(*s1) == tolower(*s2)) { s1++; s2++; } return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); } int strncasecmp(char *s1, char *s2, size_t n) { if (n == 0) return 0; while (n-- != 0 && tolower(*s1) == tolower(*s2)) { if (n == 0 || *s1 == '\0' || *s2 == '\0') break; s1++; s2++; } return tolower(*(unsigned char *) s1) - tolower(*(unsigned char *) s2); } #endif bool init_memory(void) { int count; #ifdef EXTENDED_MEM for (count=0; count = PMEMSIZE) // exceeded 64K limit { printf("\nInput file too large!\n\n"); break; } pgmmem[pc] = linebuffer[j]; // copy to program space pgmflags[pc] = PF_DATA; pc++; if ((pc & 0xff) == 0) printf("\r%04x", pc); // show progress } if (pc & WORD_MASK) himark = pc; else himark = WORD_MASK; // flag highest location } } else // else hex file... { page = 0; rectype = 0; while (!feof(fp)) // until end of file... { *linebuffer = '\0'; // clear previous line fgets(linebuffer, MAX_LINE - 1, fp);// read one line line++; if (sscanf(linebuffer, "%*c%2x%4x%2x", &i, &pc, &rectype) != EOF) { // get count and address pc += offset; // add offset to address pc += page; // add segment to address if (rectype == 1) break; // done if end of hex record if ((pc + i) > PMEMSIZE) { printf("\nInput file too large!\n\n"); break; } if (rectype == 2) // extended segment address record { sscanf((char *) &linebuffer[9], "%4x", &page); page <<= 4; } else if (rectype == 0) // data record { if (i > 64) // oops! line too long { printf("invalid count (%d) in line %d:\n", i, line); printf("%s", linebuffer); exit(FILE_ERROR); } for (j=0; j himark) himark = pc; } } } } if (himark >= PMEMSIZE) himark = PMEMSIZE - 1; fclose(fp); // done reading input file printf("\rHighest location = "); // show last location if (himark == WORD_MASK) printf("%04x\n", himark); else printf("%04x\n", himark - 1); return 0; } // Read control file and search for Offset directive void getCTLoffset(void) { FILE *fpc; char *inp; if (!offset && !traceflag) // get possible offset from control file { fpc = fopen(ctl, "r"); if (fpc) { while (!feof(fpc)) { inp = fgets(linebuffer, MAX_LINE - 1, fpc); if (!inp) break; if (toupper(*inp) == 'O') { inp++; while (*inp != ' ' && *inp != '\t') inp++; get_adrs(inp, &offset); break; } } fclose(fpc); } } } // // Put ascii hex data into binary array // void getcode(char *from, byte *loc) { byte c, i; c = *from++ - 0x30; c = (c > 10) ? c - 7 : c; i = c << 4; c = *from++ - 0x30; c = (c > 10) ? c - 7 : c; *loc = i | c; } // // Get hexadecimal number from line in control file. // Return updated character pointer. // char *get_adrs(char *text, int *val) { int result, start; char c; result = start = 0; c = toupper(*text); while (c) { if (c == ';') // beginning of comment, ignore all else break; if (c == '\n') // necessary because isspace() includes \n break; if (isspace(c)) // skip leading whitespace { text++; if (start) // if result already begun... break; } else if (isxdigit(c)) { start = 1; // flag beginning of result conversion c = (c > '9') ? c - 0x37 : c - 0x30; result <<= 4; result |= ((int) c & 0xf); text++; } else if ((c == 'X') && !result && (start == 1)) // allow for prefix "0x" { start++; text++; } else // done if not hexadecimal character break; c = toupper(*text); // get next digit } *val = result; // pass number back to caller return(text); // and return updated text pointer } void error(char *str1, char *str2) // fatal error trap { printf("\n%s%s", str1, str2); exit(FILE_ERROR); } // Sort label or symbol table // First sort by name so that we can check for duplicates, // then sort by value, check for duplicates, and set up // pointer array for binary search. // struct sym *sort(struct sym *list, SYM_PTR *array, int count) { int i; struct sym *sptr, *temp; sptr = sort_by_name(list); if (list == name_tab) chk_dup_op_name(sptr, count); else chk_dup_name(sptr, count); sptr = sort_by_value(sptr); if (list == name_tab) chk_dup_op_value(sptr, count); else chk_dup_value(sptr, count); temp = sptr; for (i=0; inext; } return(sptr); } // // In-place non-recursive merge sort using label text as key // struct sym *sort_by_name(struct sym *list) { int i, n; struct sym *a, *b, *todo, *t; head_ptr = (struct sym *) malloc(sizeof(struct sym)); head_ptr->next = list; a = tail_ptr; for (n=1; a != head_ptr->next; n = n + n) { todo = head_ptr->next; list = head_ptr; while (todo != tail_ptr) { t = todo; a = t; for (i=1; inext; b = t->next; t->next = tail_ptr; t = b; for (i=1; inext; todo = t->next; t->next = tail_ptr; list->next = merge_by_name(a, b); for (i=1; i<=n+n; i++) list = list->next; } } return(head_ptr->next); } // // In-place non-recursive merge sort using value as key // struct sym *sort_by_value(struct sym *list) { int i, n; struct sym *a, *b, *todo, *t; head_ptr = (struct sym *) malloc(sizeof(struct sym)); head_ptr->next = list; a = tail_ptr; for (n=1; a != head_ptr->next; n = n + n) { todo = head_ptr->next; list = head_ptr; while (todo != tail_ptr) { t = todo; a = t; for (i=1; inext; b = t->next; t->next = tail_ptr; t = b; for (i=1; inext; todo = t->next; t->next = tail_ptr; list->next = merge_by_value(a, b); for (i=1; i<=n+n; i++) list = list->next; } } return(head_ptr->next); } // // Merge sub-lists by text field // struct sym *merge_by_name(struct sym *a, struct sym *b) { int i; struct sym *c; c = tail_ptr; do { i = strcasecmp(a->name, b->name); if (i <= 0) { c->next = a; c = a; a = a->next; } else { c->next = b; c = b; b = b->next; } } while (c != tail_ptr); c = tail_ptr->next; tail_ptr->next = tail_ptr; return(c); } // // Merge sub-lists by value field // struct sym *merge_by_value(struct sym *a, struct sym *b) { struct sym *c; c = tail_ptr; do { if (a->val < b->val) { c->next = a; c = a; a = a->next; } else { c->next = b; c = b; b = b->next; } } while (c != tail_ptr); c = tail_ptr->next; tail_ptr->next = tail_ptr; return(c); } // // Check for redefinitions of label/symbol names // void chk_dup_name(struct sym *list, int count) { int i; for (i=0; iname, list->next->name)) { printf("\nAttempted redefinition of name (%s), value 0x%x," " as value 0x%x.\n", list->name, list->val, list->next->val); exit(USER_ERROR); } list = list->next; } } // // Check for redefinitions of operand names // void chk_dup_op_name(struct sym *list, int count) { int i, adrs, val, next_adrs, next_val; for (i=0; iname, list->next->name)) { adrs = list->val; val = pgmmem[adrs]; if (pgmflags[adrs] & PF_WORD) { val <<= 8; val |= pgmmem[adrs + 1]; } next_adrs = list->next->val; next_val = pgmmem[next_adrs]; if (pgmflags[next_adrs] & PF_WORD) { next_val <<= 8; next_val |= pgmmem[next_adrs + 1]; } if (val != next_val) { printf("\nAttempted redefinition of operand name (%s) at address 0x%x, value 0x%x," "\n as value 0x%x, previously defined at address 0x%x.\n", list->name, next_adrs, val, next_val, adrs); exit(USER_ERROR); } } list = list->next; } } // // Check for redefinitions of values // void chk_dup_value(struct sym *list, int count) { int i; for (i=0; ival == list->next->val) { printf("\nAttempted redefinition of value 0x%x, '%s', as '%s'.\n", list->val, list->name, list->next->name); exit(USER_ERROR); } list = list->next; } } // // Check for redefinitions of operand values // void chk_dup_op_value(struct sym *list, int count) { int i; for (i=0; ival == list->next->val) { if (strcasecmp(list->name, list->next->name)) { printf("\nAttempted redefinition of operand 0x%x at 0x%x, (%s), as '%s'.\n", pgmmem[list->val], list->val, list->name, list->next->name); exit(USER_ERROR); } } list = list->next; } } // Find symbol or label by value // // Binary search using table of pointers to list nodes. // This search is based on the fact that: // list[first-1] <= key < list[last+1] // is an invariant. This allows the while loop to involve // only one boolean expression, rather than two. The 'if' // statement also involves only one boolean expression. // The test for equality (has it been found?) is not done // until the loop is complete. This significantly speeds // up the search compared to a standard binary search. // char *find_entry(int val, int count, SYM_PTR *table) { struct sym *ptr; int first, mid, last; char *ret; first = 1; last = count; while (first <= last) // while more to search... { mid = (first + last) >> 1; // begin in middle of remaining array ptr = table[mid - 1]; // get pointer to node if (ptr->val > val) // determine which way to go last = mid - 1; // search before midpoint else first = mid + 1; // search after midpoint } ret = NULL; // assume not found if (last > 0) // are we still within the array? { ptr = table[last - 1]; // if so, get last pointer if (val == ptr->val) // is it what we're searching for? { if (ptr->used == FALSE) ptr->used = TRUE; // label/symbol has been used ret = ptr->name; // return pointer to caller } } return(ret); } // // Find symbol or label by name // Table must be sorted by name // SYM_PTR find_name(char *name, int count, SYM_PTR *table) { int i; SYM_PTR ptr; int first, mid, last; first = 1; last = count; while (first <= last) // while more to search... { mid = (first + last) >> 1; // begin in middle of remaining array ptr = table[mid - 1]; // get pointer to node i = strcasecmp(ptr->name, name); if (i > 0) last = mid - 1; // search before midpoint else first = mid + 1; // search after midpoint } ptr = NULL; // assume not found if (last > 0) // are we still within the array? { ptr = table[last - 1]; // if so, get last pointer if (strcasecmp(name, ptr->name)) ptr = NULL; } return(ptr); } // // Allocate new entry in symbol table or label table // struct sym *get_smem(int type, int req_size) { struct sym *ptr; ptr = (struct sym*) malloc(sizeof(struct sym) + req_size + 1); // get memory from OS if (ptr == NULL) // what? out of memory?... { printf("\nINTERNAL ERROR! - No memory for "); switch (type) { case LABEL_TYPE: printf("label"); break; case SYMBOL_TYPE: printf("symbol"); break; case NAME_TYPE: printf("name"); break; default: printf("\nUnknown table type: %d\n", type); exit(PROGRAM_ERROR); break; } printf(" table!\n"); exit(MEM_ERROR); } ptr->next = NULL; return(ptr); // give caller the address } // // Add symbol or label to table // struct sym *add_entry(int val, char *symbol, int type) { struct sym *nptr, *tbl_ptr; char *cptr; int isquote = 0; char tbl_name[8]; cptr = symbol; // ensure that input string is null terminated if ((*symbol == '\'') || (*symbol == '"')) // quoted character or string { isquote = *symbol; cptr++; } while (*cptr) { if (!isgraph(*cptr)) // if not a visible character... { if (!isquote) // and not in quoted char or string break; // we're done } else if (isquote) // else if in quoted char or string... { if (isquote == *cptr) // if end of quote... isquote = 0; // terminate at next non-visible character } cptr++; } *cptr = '\0'; if (upperflag) makeupper(symbol); switch (type) { case LABEL_TYPE: tbl_ptr = lab_tab; // get pointer to correct table strcpy(tbl_name, "label"); label_count++; break; case SYMBOL_TYPE: tbl_ptr = sym_tab; strcpy(tbl_name, "symbol"); symbol_count++; break; case NAME_TYPE: tbl_ptr = name_tab; strcpy(tbl_name, "name"); name_count++; break; default: printf("\nUnknown table type: %d\n", type); exit(PROGRAM_ERROR); break; } nptr = get_smem(type, strlen(symbol)); if (tbl_ptr == NULL) // if first symbol or label... { switch (type) { case LABEL_TYPE: lab_tab = nptr; break; case SYMBOL_TYPE: sym_tab = nptr; break; case NAME_TYPE: name_tab = nptr; break; default: printf("\nUnknown table type: %d\n", type); exit(PROGRAM_ERROR); break; } } else { switch (type) { case LABEL_TYPE: lab_tab_last->next = nptr; break; case SYMBOL_TYPE: sym_tab_last->next = nptr; break; case NAME_TYPE: name_tab_last->next = nptr; break; default: printf("\nUnknown table type: %d\n", type); exit(PROGRAM_ERROR); break; } } switch (type) { case LABEL_TYPE: lab_tab_last = nptr; break; case SYMBOL_TYPE: sym_tab_last = nptr; break; case NAME_TYPE: name_tab_last = nptr; break; default: printf("\nUnknown table type: %d\n", type); exit(PROGRAM_ERROR); break; } nptr->used = FALSE; nptr->val = val; // set value in new entry nptr->name = malloc(strlen(symbol) + 1); if (!nptr->name) { printf("\nCan't allocate memory for "); switch (type) { case LABEL_TYPE: printf("label: %s\n", symbol); break; case SYMBOL_TYPE: printf("symbol: %s\n", symbol); break; case NAME_TYPE: printf("name: %s\n", symbol); break; default: printf("Unknown table type: %d: %s\n", type, symbol); break; } exit(MEM_ERROR); } strcpy(nptr->name, symbol); // and copy text to entry return nptr; } // // Output header comment(s) associated with 'adrs' // Expand newlines // void output_comment(int adrs) { COMMENT_PTR cmt; char *str; cmt = comment_list; while (cmt) // search through list for all { // entries that match adrs if (cmt->adrs == adrs) { str = cmt->str; fprintf(fp, "\n;"); if (strlen(str) > 3 && str[2] == '\\' && str[3] == 'n') { fprintf(fp, "\n; "); str += 4; } else str++; while (*str) { if (*str == '\\' && *(str + 1) && (*(str + 1) == 'n')) { str++; fprintf(fp, "\n;"); if (*(str + 1)) fputc(' ', fp); } else fputc(*str, fp); str++; } } cmt = cmt->next; } } // // Output inline comment associated with 'adrs' // void output_icomment(int adrs) { COMMENT_PTR cmt; cmt = icomment_list; while (cmt) // search through list for all { // entries that match adrs if (cmt->adrs == adrs) fprintf(fp, "\t%s", cmt->str); cmt = cmt->next; } } // // Output patch string(s) associated with 'adrs' // Expand newlines // void output_patch(int adrs) { COMMENT_PTR patch; char *str; patch = patch_list; while (patch) // search through list for all { // entries that match adrs if (patch->adrs == adrs) { str = patch->str; fprintf(fp, "\n"); while (*str) { if (*str == '\\' && *(str + 1) && (*(str + 1) == 'n')) { str++; fprintf(fp, "\n"); } else fputc(*str, fp); str++; } } patch = patch->next; } } // // Add comment string to linked list in memory // void add_comment(int adrs, char *str) { int len; char *ctext; COMMENT_PTR cmt_ptr; len = strlen(str) - 1; if (len >= 0 && (str[len] == '\n' || str[len] == '\r')) str[len] = '\0'; // get rid of newline if (!comment_list) // first comment { comment_list = malloc(sizeof(struct comment)); if (comment_list == NULL) { printf("\nNo memory for comment struct"); exit(MEM_ERROR); } cmt_ptr = comment_list; } else // add comment to list { cmt_ptr = comment_list; while (cmt_ptr->next) // find end of list cmt_ptr = cmt_ptr->next; cmt_ptr->next = malloc(sizeof(struct comment)); if (cmt_ptr->next == NULL) { printf("\nNo memory for comment struct"); exit(MEM_ERROR); } cmt_ptr = cmt_ptr->next; } cmt_ptr->adrs = adrs; ctext = malloc(strlen(str) + 3); if (ctext == NULL) { printf("\nNo memory for comment string"); exit(MEM_ERROR); } cmt_ptr->str = ctext; if (len >= 0) { strcpy(ctext, "; "); strcat(ctext, str); } else strcpy(ctext, ";"); cmt_ptr->next = NULL; } void add_icomment(int adrs, char *str) { int len; char *ctext; COMMENT_PTR cmt_ptr; len = strlen(str) - 1; if (str[len] == '\n' || str[len] == '\r') str[len] = '\0'; // get rid of newline if (!icomment_list) // first comment { icomment_list = malloc(sizeof(struct comment)); if (icomment_list == NULL) { printf("\nNo memory for comment struct"); exit(MEM_ERROR); } cmt_ptr = icomment_list; } else // add comment to list { cmt_ptr = icomment_list; while (cmt_ptr->next) // find end of list cmt_ptr = cmt_ptr->next; cmt_ptr->next = malloc(sizeof(struct comment)); if (cmt_ptr->next == NULL) { printf("\nNo memory for comment struct"); exit(MEM_ERROR); } cmt_ptr = cmt_ptr->next; } cmt_ptr->adrs = adrs; ctext = malloc(strlen(str) + 3); if (ctext == NULL) { printf("\nNo memory for comment string"); exit(MEM_ERROR); } cmt_ptr->str = ctext; strcpy(ctext, "; "); strcat(ctext, str); cmt_ptr->next = NULL; } // // Add patch string to linked list in memory // void add_patch(int adrs, char *str) { int len; char *ctext; COMMENT_PTR patch_ptr; len = strlen(str) - 1; if (len >= 0 && (str[len] == '\n' || str[len] == '\r')) str[len] = '\0'; // get rid of newline if (!patch_list) // first patch { patch_list = malloc(sizeof(struct comment)); if (patch_list == NULL) { printf("\nNo memory for patch struct"); exit(MEM_ERROR); } patch_ptr = patch_list; } else // add patch to list { patch_ptr = patch_list; while (patch_ptr->next) // find end of list patch_ptr = patch_ptr->next; patch_ptr->next = malloc(sizeof(struct comment)); if (patch_ptr->next == NULL) { printf("\nNo memory for patch struct"); exit(MEM_ERROR); } patch_ptr = patch_ptr->next; } patch_ptr->adrs = adrs; ctext = malloc(strlen(str) + 3); if (ctext == NULL) { printf("\nNo memory for patch string"); exit(MEM_ERROR); } patch_ptr->str = ctext; if (len >= 0) strcpy(ctext, str); else strcpy(ctext, ";"); patch_ptr->next = NULL; } // // Output hexadecimal operand // void puthex(int j) { j &= WORD_MASK; if (baseflag) { if (upperflag) kcnt += fprintf(fp, "0x%X", j); else kcnt += fprintf(fp, "0x%x", j); return; } if (j < 10) { if (upperflag) kcnt += fprintf(fp, "%X", j); else kcnt += fprintf(fp, "%x", j); } else if (j < 16) { if (upperflag) kcnt += fprintf(fp, "0%XH", j); else kcnt += fprintf(fp, "0%xh", j); } else if (j < 0xa0) { if (upperflag) kcnt += fprintf(fp, "%XH", j); else kcnt += fprintf(fp, "%xh", j); } else if (j < 0x100) { if (upperflag) kcnt += fprintf(fp, "0%XH", j); else kcnt += fprintf(fp, "0%xh", j); } else if (j < 0xa00) { if (upperflag) kcnt += fprintf(fp, "%XH", j); else kcnt += fprintf(fp, "%xh", j); } else if (j < 0x1000) { if (upperflag) kcnt += fprintf(fp, "0%XH", j); else kcnt += fprintf(fp, "0%xh", j); } else if (j < 0xa000) { if (upperflag) kcnt += fprintf(fp, "%XH", j); else kcnt += fprintf(fp, "%xh", j); } else { if (upperflag) kcnt += fprintf(fp, "0%XH", j); else kcnt += fprintf(fp, "0%xh", j); } } // // Convert code to printable ascii // int ascii(int i) { i = i & 0x7f; if (i == 0x7f) return ('.'); else if (i < 0x20) return ('.'); else return (i); } // // Check if data is printable ascii other than the string delimiter // int is_ascii(byte data) { if (data < ' ' || data > 0x7e || data == '\'') return(0); return(1); } // // Convert ascii hex to hexadecimal for X option // int atox(char *str) { char c; int i; i = 0; c = (char) toupper(*str++); while (c) { if (isxdigit((int) c)) { c = (c > '9') ? c - 0x37 : c & 0xf; i = (i << 4) | c; } else break; c = (char) toupper(*str++); } return(i); } // // Check for reference to address in middle of // code and flag split reference if true // void splitcheck(int i) { if (pgmflags[i] & PF_REF) // ignore if not referenced pgmflags[i] |= PF_SPLIT; // else flag split ref } // // Add label to output line if current location marked as referenced // void chk_ref(int i) { int cnt; char *cptr; if ((pgmflags[i] & (PF_REF | PF_NOLABEL)) == PF_REF) { pgmflags[i] |= PF_LABGEN; cptr = find_entry(i, label_count, lab_val_index); // see if label exists if (cptr == NULL) // if not, output hex value { if (upperflag) cnt = fprintf(fp, "\nX%04X:", i); else cnt = fprintf(fp, "\nX%04x:", i); } else cnt = fprintf(fp, "\n%s:", cptr); // else output label text if (cnt > 8) fprintf(fp, "\n\t"); else fprintf(fp, "\t"); } else fprintf(fp, "\n\t"); } // // Add label to output line if current location marked as referenced // For PF_WORD and PF_ADRS data // void chk_label(int i) { char *cptr; if ((pgmflags[i] & (PF_REF | PF_NOLABEL)) == PF_REF) { pgmflags[i] |= PF_LABGEN; cptr = find_entry(i, label_count, lab_val_index); // see if label exists if (cptr == NULL) // if not, output hex value { if (upperflag) fprintf(fp, "\nX%04X:", i); else fprintf(fp, "\nX%04x:", i); } else fprintf(fp, "\n%s:", cptr); // else output label text fprintf(fp, "\t"); } else fprintf(fp, "\n\t"); } // // Output opcode for current code // void doopcode(char *mnem) { char c; c = *mnem++; if (upperflag) c = toupper(c); while (c) // output text from opcode table { if (c == ' ') // convert spaces to tabs { putc('\t', fp); kcnt = (kcnt + 8) & 0x78; } else { putc(c, fp); kcnt++; } c = *mnem++; if (upperflag) c = toupper(c); } } // // Output ascii data accumulated in buffer // void dump_ascii(int adrs) { int padrs, off, cnt; char *cptr; padrs = adrs - asc_cnt; // print address for comment field adrs = padrs; // address in program array cnt = off = 0; // cnt = char count, off = buffer offset while (asc_cnt) // while data in ascii buffer... { if (!(pgmflags[adrs] & PF_NOLABEL) && (pgmflags[adrs] & PF_REF)) // if addresss is referenced... { if (cnt) { putc('\'', fp); // terminate line kcnt++; if (hexflag) // if comment field requested... { do // show hex address { putc('\t', fp); // but tab out to field first kcnt = (kcnt + 8) & 0x78; } while (kcnt < XSTOP); fprintf(fp, "; %04x", padrs); } padrs += cnt; // update print address cnt = 0; // clear char count for this line } pgmflags[adrs] |= PF_LABGEN; cptr = find_entry(adrs, label_count, lab_val_index); // see if label exists for this adrs if (cptr == NULL) // if not, show address in hex fprintf(fp, "\nX%04x:\t%s\t'", adrs, ascistr); else // else show label name { if (strlen(cptr) > 8) fprintf(fp, "\n%s:\n\t%s\t'", cptr, ascistr); else fprintf(fp, "\n%s:\t%s\t'", cptr, ascistr); } kcnt = 17; } else if (!cnt) { fprintf(fp, "\n\t%s\t'", ascistr); kcnt = 17; } putc(string[off], fp); // output data in ascii kcnt++; // character position in this line cnt++; // increment char in this line off++; // increment offset into asci buffer adrs++; // offset into program memory if (cnt >= ASCLINE) // if max characters per line... { putc('\'', fp); // terminate line kcnt++; if (hexflag) // if comment field requested { do // show hex address { putc('\t', fp); kcnt = (kcnt + 8) & 0x78; } while (kcnt < XSTOP); fprintf(fp, "; %04x", padrs); } padrs += cnt; // update print address cnt = 0; } --asc_cnt; } putc('\'', fp); // terminate line kcnt++; if (hexflag && cnt) // if comment field requested... { do // show address { putc('\t', fp); kcnt = (kcnt + 8) & 0x78; } while (kcnt < XSTOP); fprintf(fp, "; %04x", padrs); } dump = 1; } // // Output binary data accumulated in buffer // void dump_bytes(int adrs) { int padrs, bcnt, off, k; char *cptr, chr; padrs = adrs - byte_cnt; // compute adrs to print in ascii part adrs = padrs; bcnt = off = 0; // no bytes output yet while (byte_cnt) // while data in binary buffer... { if (!(pgmflags[adrs] & PF_NOLABEL) && (pgmflags[adrs] & PF_REF)) // if addresss is referenced... { if (off && hexflag) // dump any remaining ascii first { do { putc('\t', fp); kcnt = (kcnt + 8) & 0x78; } while (kcnt < XSTOP); fprintf(fp, "; %04x ", padrs); for (k=0; k 8) fprintf(fp, "\n%s:\n\t%s\t", cptr, defbstr); else fprintf(fp, "\n%s:\t%s\t", cptr, defbstr); } // } kcnt = 16; bcnt = 0; } else if (!bcnt) // else if first byte... { kcnt = 16; fprintf(fp, "\n\t%s\t", defbstr); } else { putc(',', fp); // else separate bytes kcnt++; } if (pgmflags[adrs] & PF_NAME) cptr = find_entry(adrs, name_count, name_val_index); else if ((pgmflags[adrs] & (PF_LABEL | PF_SYMBOL)) == (PF_LABEL | PF_SYMBOL)) cptr = NULL; else cptr = find_entry(pgmmem[adrs], symbol_count, sym_val_index); if (cptr) kcnt += fprintf(fp, "%s", cptr); else { if (!(pgmflags[adrs] & PF_ASCII)) puthex(pgmmem[adrs] & 0xff); else // user defined this as ascii text { // even though it's not; let's try chr = pgmmem[adrs]; // to give him what he wants. if (chr & 0x80) // if flagged binary byte because { // high bit is set... chr &= 0x7f; if (chr >= ' ' && chr <= 'z') // would it be ascii { // without bit 7 set? kcnt += fprintf(fp, "'%c'+80h", chr); // yes // bcnt += 3; } else // else do as binary and remove { // ascii flag puthex(pgmmem[adrs] & 0xff); pgmflags[adrs] &= ~PF_ASCII; } } else // high bit not set, so is { // really binary, not ascii puthex(pgmmem[adrs] & 0xff); pgmflags[adrs] &= ~PF_ASCII; } } } bcnt++; k = (kcnt + 8) & 0x78; // where we will be if we tab k = 80 - k; // how many spaces left k -= (bcnt + 11); // minus what it takes for ascii output if (pgmflags[adrs + 1] & PF_NAME) // see if the next byte has a name entry cptr = find_entry(adrs + 1, name_count, name_val_index); else if ((pgmflags[adrs + 1] & (PF_LABEL | PF_SYMBOL)) == (PF_LABEL | PF_SYMBOL)) cptr = NULL; else cptr = find_entry(pgmmem[adrs + 1], symbol_count, sym_val_index); if (cptr) // if next byte has a name entry... k -= strlen(cptr); // subtract its length from available space if (bcnt >= BYTELINE || pgmflags[adrs] & PF_ICMT || k < 1) // if max line length... { bcnt = 0; if (hexflag) // do ascii dump of previous bytes { do { putc('\t', fp); kcnt = (kcnt + 8) & 0x78; } while (kcnt < XSTOP); fprintf(fp, "; %04x ", padrs); for (k=0; k<=off; k++) putc(ascii(pgmmem[padrs + k]), fp); padrs += k; off = 0; } } else off++; if (pgmflags[adrs] & PF_ICMT) output_icomment(adrs); --byte_cnt; adrs++; } if (off && hexflag) // generate comment line { do { putc('\t', fp); kcnt = (kcnt + 8) & 0x78; } while (kcnt < XSTOP); fprintf(fp, "; %04x ", padrs); // show address and ascii for data for (k=0; k= 'A') && (c <= 'F')) c = c - 'A' + '9' + 1; if ((c >= '0') && (c <= ('9' + 6))) { b = b * 16 + (c - '0'); text++; } switch (pos) { case 0: opcode = b; pos++; break; case 2: cycles[opcode] = b; cycles2[opcode] = b; pos++; break; case 4: cycles2[opcode] = b; pos++; break; default: c = 'Q'; // we deliberately replace c with an invalid // character to cause error, when hexadecimal number // encountered in an unexpected field } if (c != 'Q') break; // for the error case fall over, so that // it falls over to the error handling (bruhaha) case '-': // opcode and first cycle count separator if (pos == 1) { pos++; break; } else c = 'Q'; // explanation for the invalid character see above case '/': // first and second cycle count separator if (pos == 3) { pos++; break; } else c = 'Q'; // explanation for the invalid character see above case '#': case ';': case '\n': case '\r': case '\0': // remark or end of line -> exit for the next line if ((pos == 0) || (pos == 3) || (pos == 5)) // exit only if blank line or one or both values were given { if (c == '#') printf("%s", text); // remark to be written to output file pos = -1; break; } else c = 'Q'; // explanation for the invalid character see above default: printf("\n* Can't reasonably interpret the following line: *\n%s", linebuffer); exit(FILE_ERROR); } } while (pos >= 0); } } // this is just a "nested" function for the following cycle counting function // - returns the current cycle_range for address num CYCLE_RANGE_PTR cycle_in_in(int num) { CYCLE_RANGE_PTR cr, cx; bool found; cx = NULL; cr = cycle_r; do { found = FALSE; while ((!found) && (cr != NULL)) { if ((num >= cr->min) && (num <= cr->max)) { cx = cr; found = TRUE; } else cr = cr->next; } if (found) cr = cx -> child; } while (found); return(cx); } // checks if cycle counting is on for line number num // - at the same time adds the cycle count cnt to the appropriate "counter" // - prints the needed text into comment // - sets also the cycle_current pointer to the currently counted cycle range // (to be used in cycle_end) // void cycle_in(int num, int next_num, int cnt, int cnt2) { CYCLE_RANGE_PTR cx, cy; cx = cycle_in_in(num); cycle_current = cx; if (cx == NULL) fprintf(fp, " "); else { if (cx->mul == 0) cycle_exclude = TRUE; // setting this flag enables to write "-" // next to cycle counts in the excluded range, even for the // children (which might have nonzero multiplier to know the // excluded code length) if (cx->cnt2 == 2) cycle_alwaystake = TRUE; // "worst case" analysis (jumps always taken // etc) for this range including subranges if (cx->val != 0) { cnt = cx->val; fprintf(fp, ";=%2d", cnt); // this is if the range has explicit // one-off value, as specified by "=" in the control file } else if ( (cx->min == cx->max) && // for autorepeated in Z80 - have to // specify cycle count explicitly for this single line! (cnt2 != cnt) && // and the two tables have to contain // different count values (and, implicitly in this // branch of if, the explicit val == 0) (cx -> mul > 1) ) { fprintf(fp,";%3d = %d * %dx + %d", cnt2 * (cx->mul - 1) + cnt, cnt2, cx->mul - 1, cnt); cnt= cnt2 * (cx->mul - 1) + cnt; cx->cnt2 = 1; // indicate autorepeated instruction, so that summary // printing in cycle-end is suppressed } else { cy = cycle_in_in(next_num); if (( (cy == NULL) || // if there is no counting specified // for the following instruction ((cy->min == next_num) && (cy->mul == 0)) || // or the cycle counting status just changed to inactive (cycle_alwaystake) // or this range explicitly requires // "worst case" (= "jump always taken") analysis ) && (cnt != cnt2) // and if this _is_ an instruction // with alternative length ) { // then this is the case for "taken jump" and // the value from second table should be taken cnt = cnt2; fprintf(fp, ";^%2d", cnt); // indicate taken jump } else fprintf(fp, "; %2d", cnt); // normal instruction } cx->cnt += cnt; if (cycle_exclude) fprintf(fp, "-"); // indicate excluded range else fprintf(fp, " "); } return; } // cycle counting - check end range for address num and emit code appropriately void cycle_end(int num) { CYCLE_RANGE_PTR cr, cx; int cycles; cr = cycle_current; while (cr != NULL) { if (num > cr->max) { if (cr->val == 0) // if nonzero explicit value of cycle count, // don't write summary { if ( (cr->min == cr->max) && // for autorepeated in Z80 - have to // specify cycle count explicitly for this single line! (cr->cnt2 == 1) && // and the two tables have to contain // different count values (cr->val == 0) && // and there is no explicitly entered // value for this range in the control file via "=" (cr->mul > 1)) { cycles = cr->cnt; // autorepeated instruction - this was // already printed in-line, so print nothing here... } else { cycles = cr->cnt; if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n; --- Cycle count %04x-%04x = %d", cr->min, cr->max, cycles); if (cr->mul > 1) { cycles *= cr->mul; fprintf(fp, " * %dx = %d", cr->mul, cycles); } if (cr->mul == 0) // as a consequence of "-" suffix { fprintf(fp, " - not included to the parent cycle count."); cycles = 0; } fprintf(fp, "\n;"); newline = TRUE; } } else cycles = cr->val; // this is the explicitly set cycles count if (cr->mul == 0) // reset the "cycle_exclude" flag when cycle_exclude = FALSE; // leaving an excluded range if (cr->cnt2 == 2) // reset the "worst case" analysis flag cycle_alwaystake = FALSE; // when leaving a range with this flag cx = cr->parent; if (cx != NULL) cx->cnt += cycles; //cr->cnt * cr->mul; cr->cnt = 0; cr = cx; } else cr = NULL; } } // end of common.c d52-3.4.1.orig/common.h0000644000175000017500000001515110666551024012703 0ustar uweuwe /* * Disassembler common routines * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * common.h - Support routines * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _COMMON_H_ #define _COMMON_H_ #ifdef EXTENDED_MEM #define EXT_PGM_SEGS 8 /* maximum number of extended segments: 8 * 64kb = 512kb */ #endif // Global variables extern char licenseText[]; extern char src[FN_LEN], dst[FN_LEN]; // file name buffers extern char baseFileName[FN_LEN]; // source file name without extension extern char ctl[FN_LEN]; // control file name extern char linebuffer[MAX_LINE]; // input line buffer extern FILE *fp; // dos file struct extern int hexflag; // append hex flag extern int fileflag; // file type flag extern int upperflag; // upper case output flag extern int baseflag; extern bool traceflag; // trace and analyze code extern int kcnt; // output char counter extern int pc; // current program counter extern int himark; // highest data adrs extern int offset; // program counter offset extern byte *pgmmem; // program data pointer extern int *pgmflags; // pointer to program flags #ifdef EXTENDED_MEM extern byte *epgmmem[EXT_PGM_SEGS]; // extended program memory pointers extern int *epgmflags[EXT_PGM_SEGS]; // extended program flags pointers #endif extern char string[ASCLIMIT]; // ascii data for defb extern int asc_cnt; // count for string data extern byte byte_data[BYTELIMIT]; // binary data for defb extern int byte_cnt; // count for binary data extern int word_data[WORDLIMIT]; // binary data for defw extern int word_cnt; // count for word data extern byte dump; // dump just done flag extern byte ascii_flag; // use ascii string flag extern char defbstr[8]; // string for defined bytes extern char defwstr[8]; // string for defined words extern char ascistr[8]; // string for defined ascii extern char orgstr[8]; // org pseudo-op string extern char equstr[8]; // equ pseudo-op string extern struct sym *sym_tab; // symbol table pointer extern struct sym *lab_tab; // label table pointer extern struct sym *name_tab; // operand names pointer extern struct sym *sym_tab_last; // last symbol table pointer extern struct sym *lab_tab_last; // lastlabel table pointer extern struct sym *name_tab_last; // last name table pointer extern int symbol_count; // number of symbols extern int label_count; // number of labels extern int name_count; // number of operand names extern SYM_PTR *sym_val_index; // array of pointers extern SYM_PTR *lab_val_index; // for binary search extern SYM_PTR *name_val_index; extern struct sym *tail_ptr, *head_ptr; // sort pointers extern struct comment *comment_list; // header comment list extern struct comment *icomment_list; // inline comment list extern struct comment *patch_list; // patch list extern int newline; // just output newline flag extern struct tm *date_time; // disassembly time extern bool cycleflag; // cycle counting global on/off switch extern bool cycle_exclude; // cycle counting suspended flag extern bool cycle_alwaystake; // cycle counting "always take" (worst case) flag extern CYCLE_RANGE_PTR cycle_r; // cycle counting root range extern CYCLE_RANGE_PTR cycle_current; // cycle counting current range // // Prototypes // #if defined __LCC__ extern int strcasecmp(char *s1, char *s2); extern int strncasecmp(char *s1, char *s2, size_t n); #endif extern bool init_memory(void); #ifdef EXTENDED_MEM extern byte *get_extended_mem(int width); #endif extern char *makeupper(char *str); extern int parseFileName(char *str, char *ext); extern int readfile(char *filename); extern void getCTLoffset(void); extern void getcode(char *from, byte *loc); extern char *get_adrs(char *text, int *val); extern void error(char *str1, char *str2); // fatal error trap extern struct sym *sort(struct sym *list, SYM_PTR *array, int count); extern struct sym *sort_by_name(struct sym *list); extern struct sym *sort_by_value(struct sym *list); extern struct sym *merge_by_name(struct sym *a, struct sym *b); extern struct sym *merge_by_value(struct sym *a, struct sym *b); extern void chk_dup_name(struct sym *list, int count); extern void chk_dup_op_name(struct sym *list, int count); extern void chk_dup_value(struct sym *list, int count); extern void chk_dup_op_value(struct sym *list, int count); extern char *find_entry(int val, int count, SYM_PTR *table); extern SYM_PTR find_name(char *name, int count, SYM_PTR *table); extern struct sym *get_smem(int type, int req_size); extern struct sym *add_entry(int val, char *symbol, int type); extern void output_comment(int adrs); extern void output_icomment(int adrs); extern void output_patch(int adrs); extern void add_comment(int adrs, char *str); extern void add_icomment(int adrs, char *str); extern void add_patch(int adrs, char *str); extern void puthex(int j); extern int ascii(int i); extern int is_ascii(byte data); extern int atox(char *str); extern void splitcheck(int i); extern void chk_ref(int i); extern void chk_label(int i); extern void doopcode(char *mnem); extern void dump_ascii(int adrs); extern void dump_bytes(int adrs); extern void readcyclefile(char *c); extern void cycle_in(int num, int next_num, int cnt, int cnt2); extern void cycle_end(int num); // --- although I know this is not properly declared here, // I know no better way how to make it usable in common.c --- // (haven't I told that I am not really into C? :-) ) -- JW // so it is assumed that all 3 ports (d52, d48, dz80) do have // these tables implemented (in XXXtables.c) extern unsigned char cycles[256]; extern unsigned char cycles2[256]; #endif // _COMMON_H_ d52-3.4.1.orig/COPYING0000600000175000017500000010437410650170421012262 0ustar uweuwe GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . d52-3.4.1.orig/cyclefiles/0000775000175000017500000000000010666334466013374 5ustar uweuwed52-3.4.1.orig/cyclefiles/8051.cyc0000664000175000017500000000440310570514332014454 0ustar uweuwe;'51 - 12x ;'RD2 - 6x ;P89LPC9xx - 2x ; ;This is a cycle counting file for the d52 disassembler. ; ;GNU General Public License - for details see copying.txt ;(C) 2007 by Jan Waclawek, wek at efton dot sk ; ;Disclaimer: cycle counts in this file may be wrong. Use at your own risk. ;Please correct it if you encounter an error and report to d52 author, Jeff Post. ;Please contribute cycle count files for new '51 derivatives ;or new uses or variations of existing files. ;Manufacturers, please contribute "known good" cycle count files. ; # ------------------------------ #| "classic" 8051 - 12x clock | #| 'RD2 - 6x clock | #| '66x - 6x clock | #| LPC9xx - 2x clock | # ------------------------------ # 00-1 01-2 02-2 03-1 04-1 05-1 06-1 07-1 08-1 09-1 0A-1 0B-1 0C-1 0D-1 0E-1 0F-1 10-2 11-2 12-2 13-1 14-1 15-1 16-1 17-1 18-1 19-1 1A-1 1B-1 1C-1 1D-1 1E-1 1F-1 20-2 21-2 22-2 23-1 24-1 25-1 26-1 27-1 28-1 29-1 2A-1 2B-1 2C-1 2D-1 2E-1 2F-1 30-2 31-2 32-2 33-1 34-1 35-1 36-1 37-1 38-1 39-1 3A-1 3B-1 3C-1 3D-1 3E-1 3F-1 40-2 41-2 42-1 43-2 44-1 45-1 46-1 47-1 48-1 49-1 4A-1 4B-1 4C-1 4D-1 4E-1 4F-1 50-2 51-2 52-1 53-2 54-1 55-1 56-1 57-1 58-1 59-1 5A-1 5B-1 5C-1 5D-1 5E-1 5F-1 60-2 61-2 62-1 63-2 64-1 65-1 66-1 67-1 68-1 69-1 6A-1 6B-1 6C-1 6D-1 6E-1 6F-1 70-2 71-2 72-2 73-2 74-1 75-2 76-1 77-1 78-1 79-1 7A-1 7B-1 7C-1 7D-1 7E-1 7F-1 80-2 81-2 82-2 83-2 84-4 85-2 86-2 87-2 88-2 89-2 8A-2 8B-2 8C-2 8D-2 8E-2 8F-2 90-2 91-2 92-2 93-2 94-1 95-1 96-1 97-1 98-1 99-1 9A-1 9B-1 9C-1 9D-1 9E-1 9F-1 A0-2 A1-2 A2-1 A3-2 A4-4 A6-2 A7-2 A8-2 A9-2 AA-2 AB-2 AC-2 AD-2 AE-2 AF-2 B0-2 B1-2 B2-1 B3-1 B4-2 B5-2 B6-2 B7-2 B8-2 B9-2 BA-2 BB-2 BC-2 BD-2 BE-2 BF-2 C0-2 C1-2 C2-1 C3-1 C4-1 C5-1 C6-1 C7-1 C8-1 C9-1 CA-1 CB-1 CC-1 CD-1 CE-1 CF-1 D0-2 D1-2 D2-1 D3-1 D4-1 D5-2 D6-1 D7-1 D8-2 D9-2 DA-2 DB-2 DC-2 DD-2 DE-2 DF-2 E0-2 E1-2 E2-2 E3-2 E4-1 E5-1 E6-1 E7-1 E8-1 E9-1 EA-1 EB-1 EC-1 ED-1 EE-1 EF-1 F0-2 F1-2 F2-2 F3-2 F4-1 F5-1 F6-1 F7-1 F8-1 F9-1 FA-1 FB-1 FC-1 FD-1 FE-1 FF-1 d52-3.4.1.orig/cyclefiles/ADuC84x.cyc0000664000175000017500000000415010570514344015201 0ustar uweuwe;ADuC84x - 1x ; ;This is a cycle counting file for the d52 disassembler. ; ;GNU General Public License - for details see copying.txt ;(C) 2007 by Jan Waclawek, wek at efton dot sk ; ;Disclaimer: cycle counts in this file may be wrong. Use at your own risk. ;Please correct it if you encounter an error and report to d52 author, Jeff Post. ;Please contribute cycle count files for new '51 derivatives ;or new uses or variations of existing files. ;Manufacturers, please contribute "known good" cycle count files. ; # ---------------------- #| ADuC84x - 1x clock | # ---------------------- # 00-1 01-3 02-4 03-1 04-1 05-2 06-2 07-2 08-1 09-1 0A-1 0B-1 0C-1 0D-1 0E-1 0F-1 10-4 11-3 12-4 13-1 14-1 15-2 16-2 17-2 18-1 19-1 1A-1 1B-1 1C-1 1D-1 1E-1 1F-1 20-4 21-3 22-4 23-1 24-2 25-2 26-2 27-2 28-1 29-1 2A-1 2B-1 2C-1 2D-1 2E-1 2F-1 30-4 31-3 32-4 33-1 34-2 35-2 36-2 37-2 38-1 39-1 3A-1 3B-1 3C-1 3D-1 3E-1 3F-1 40-3 41-3 42-2 43-3 44-2 45-2 46-2 47-2 48-1 49-1 4A-1 4B-1 4C-1 4D-1 4E-1 4F-1 50-3 51-3 52-2 53-3 54-2 55-2 56-2 57-2 58-1 59-1 5A-1 5B-1 5C-1 5D-1 5E-1 5F-1 60-3 61-3 62-2 63-3 64-2 65-2 66-2 67-2 68-1 69-1 6A-1 6B-1 6C-1 6D-1 6E-1 6F-1 70-3 71-3 72-2 73-3 74-2 75-3 76-2 77-2 78-2 79-2 7A-2 7B-2 7C-2 7D-2 7E-2 7F-2 80-3 81-3 82-2 83-4 84-9 85-3 86-2 87-2 88-2 89-2 8A-2 8B-2 8C-2 8D-2 8E-2 8F-2 90-3 91-3 92-2 93-4 94-2 95-2 96-2 97-2 98-1 99-1 9A-1 9B-1 9C-1 9D-1 9E-1 9F-1 A0-2 A1-3 A2-2 A3-3 A4-9 A6-2 A7-2 A8-2 A9-2 AA-2 AB-2 AC-2 AD-2 AE-2 AF-2 B0-2 B1-3 B2-2 B3-1 B4-4 B5-4 B6-4 B7-4 B8-4 B9-4 BA-4 BB-4 BC-4 BD-4 BE-4 BF-4 C0-2 C1-3 C2-2 C3-1 C4-1 C5-2 C6-2 C7-2 C8-1 C9-1 CA-1 CB-1 CC-1 CD-1 CE-1 CF-1 D0-2 D1-3 D2-2 D3-1 D4-2 D5-4 D6-2 D7-2 D8-3 D9-3 DA-3 DB-3 DC-3 DD-3 DE-3 DF-3 E0-4 E1-3 E2-4 E3-4 E4-1 E5-2 E6-2 E7-2 E8-1 E9-1 EA-1 EB-1 EC-1 ED-1 EE-1 EF-1 F0-4 F1-3 F2-4 F3-4 F4-1 F5-2 F6-2 F7-2 F8-1 F9-1 FA-1 FB-1 FC-1 FD-1 FE-1 FF-1 d52-3.4.1.orig/cyclefiles/AT89LP.cyc0000664000175000017500000000427610570514362015013 0ustar uweuwe;AT89LPxxxx - 1x ; ;This is a cycle counting file for the d52 disassembler. ; ;GNU General Public License - for details see copying.txt ;(C) 2007 by Jan Waclawek, wek at efton dot sk ; ;Disclaimer: cycle counts in this file may be wrong. Use at your own risk. ;Please correct it if you encounter an error and report to d52 author, Jeff Post. ;Please contribute cycle count files for new '51 derivatives ;or new uses or variations of existing files. ;Manufacturers, please contribute "known good" cycle count files. ; # ------------------------- #| AT89LPxxxx - 1x clock | # ------------------------- # 00-1 01-3 02-4 03-1 04-1 05-2 06-2 07-2 08-1 09-1 0A-1 0B-1 0C-1 0D-1 0E-1 0F-1 10-4 11-3 12-4 13-1 14-1 15-2 16-2 17-2 18-1 19-1 1A-1 1B-1 1C-1 1D-1 1E-1 1F-1 20-4 21-3 22-4 23-1 24-2 25-2 26-2 27-2 28-1 29-1 2A-1 2B-1 2C-1 2D-1 2E-1 2F-1 30-4 31-3 32-4 33-1 34-2 35-2 36-2 37-2 38-1 39-1 3A-1 3B-1 3C-1 3D-1 3E-1 3F-1 40-3 41-3 42-2 43-3 44-2 45-2 46-2 47-2 48-1 49-1 4A-1 4B-1 4C-1 4D-1 4E-1 4F-1 50-3 51-3 52-2 53-3 54-2 55-2 56-2 57-2 58-1 59-1 5A-1 5B-1 5C-1 5D-1 5E-1 5F-1 60-3 61-3 62-2 63-3 64-2 65-2 66-2 67-2 68-1 69-1 6A-1 6B-1 6C-1 6D-1 6E-1 6F-1 70-3 71-3 72-2 73-3 74-2 75-3 76-2 77-2 78-2 79-2 7A-2 7B-2 7C-2 7D-2 7E-2 7F-2 80-3 81-3 82-2 83-3 84-4 85-3 86-2 87-2 88-2 89-2 8A-2 8B-2 8C-2 8D-2 8E-2 8F-2 90-3 91-3 92-2 93-3 94-2 95-2 96-2 97-2 98-1 99-1 9A-1 9B-1 9C-1 9D-1 9E-1 9F-1 A0-2 A1-3 A2-2 A3-2 A4-2 A6-2 A7-2 A8-2 A9-2 AA-2 AB-2 AC-2 AD-2 AE-2 AF-2 B0-2 B1-3 B2-2 B3-1 B4-4 B5-4 B6-4 B7-4 B8-4 B9-4 BA-4 BB-4 BC-4 BD-4 BE-4 BF-4 C0-2 C1-3 C2-2 C3-1 C4-1 C5-2 C6-2 C7-2 C8-1 C9-1 CA-1 CB-1 CC-1 CD-1 CE-1 CF-1 D0-2 D1-3 D2-2 D3-1 D4-1 D5-4 D6-2 D7-2 D8-3 D9-3 DA-3 DB-3 DC-3 DD-3 DE-3 DF-3 ;E0, E2, E3, F0, F2, F3 are irrelevant for '51 without external bus access ;E0- E1-3 ;E2- ;E3- E4-1 E5-2 E6-2 E7-2 E8-1 E9-1 EA-1 EB-1 EC-1 ED-1 EE-1 EF-1 ;F0- F1-3 ;F2- ;F3- F4-1 F5-2 F6-1 F7-1 F8-1 F9-1 FA-1 FB-1 FC-1 FD-1 FE-1 FF-1 d52-3.4.1.orig/cyclefiles/bench0.a510000664000175000017500000000132310570443174015031 0ustar uweuwe$mod52 DSEG AT 20h TI_PTR: DS 1 Rx_Head: DS 1 Rx_Tail: DS 1 TxBuff: DS 5 TxBuffEnd: RxBuff: DS 5 RxBuffEnd: CSEG SerialISR: PUSH PSW PUSH ACC SETB RS0 JBC TI,TI_ISR TI_ISREnd: JBC RI,RI_ISR SerialISREnd: POP ACC POP PSW RETI TI_ISR: MOV A,TI_PTR JZ TI_ISREnd DEC TI_PTR ADD A,#LOW(TxBuff-1) MOV R0,A MOV R2,P2 CLR A ADDC A,#HIGH(TxBuff-1) MOV P2,A MOVX A,@R0 MOV P2,R2 MOV SBUF,A SJMP TI_ISREnd RI_ISR: MOV R1,RX_Head MOV @R1,SBUF INC R1 CJNE R1,#RXBuffEnd,RI_ISR_X1 MOV R1,#RXBuff RI_ISR_X1: MOV A,R1 CJNE A,RX_Tail,RI_ISR_X2 SJMP SerialISREnd RI_ISR_X2: MOV RX_Head,A SJMP SerialISREnd endd52-3.4.1.orig/cyclefiles/bench0.aduc84x.d520000664000175000017500000000140410570463262016314 0ustar uweuwe; ; D52 V3.4.0 8052 Disassembly of bench0.hex ; 02/25/07 20:48 ; org 0 ; push psw ; 2 push acc ; 2 setb rs0 ; 2 jbc ti,X0011 ; 4 X0009: jbc ri,X0028 ; 4 X000c: pop acc ; 2 pop psw ; 2 reti ; 4 ; X0011: mov a,20h ; 2 jz X0009 ; 3 dec 20h ; 2 add a,#22h ; 2 mov r0,a ; 1 mov r2,p2 ; 2 clr a ; 1 addc a,#0 ; 2 mov p2,a ; 2 movx a,@r0 ; 4 mov p2,r2 ; 2 mov sbuf,a ; 2 sjmp X0009 ; 3 ; X0028: mov r1,21h ; 2 mov @r1,sbuf ; 2 inc r1 ; 1 cjne r1,#2dh,X0032 ; 4 mov r1,#28h ; 2 X0032: mov a,r1 ; 1 cjne a,22h,X0038 ; 4 sjmp X000c ; 3 ; X0038: mov 21h,a ; 2 sjmp X000c ; 3 ; ; --- Cycle count 0000-ffff = 74 ; end ; d52-3.4.1.orig/cyclefiles/bench0.at89lp.d520000664000175000017500000000140410570463350016153 0ustar uweuwe; ; D52 V3.4.0 8052 Disassembly of bench0.hex ; 02/25/07 20:49 ; org 0 ; push psw ; 2 push acc ; 2 setb rs0 ; 2 jbc ti,X0011 ; 4 X0009: jbc ri,X0028 ; 4 X000c: pop acc ; 2 pop psw ; 2 reti ; 4 ; X0011: mov a,20h ; 2 jz X0009 ; 3 dec 20h ; 2 add a,#22h ; 2 mov r0,a ; 1 mov r2,p2 ; 2 clr a ; 1 addc a,#0 ; 2 mov p2,a ; 2 movx a,@r0 ; 0 mov p2,r2 ; 2 mov sbuf,a ; 2 sjmp X0009 ; 3 ; X0028: mov r1,21h ; 2 mov @r1,sbuf ; 2 inc r1 ; 1 cjne r1,#2dh,X0032 ; 4 mov r1,#28h ; 2 X0032: mov a,r1 ; 1 cjne a,22h,X0038 ; 4 sjmp X000c ; 3 ; X0038: mov 21h,a ; 2 sjmp X000c ; 3 ; ; --- Cycle count 0000-ffff = 70 ; end ; d52-3.4.1.orig/cyclefiles/Bench0.ctl0000664000175000017500000000001710570454010015153 0ustar uweuweZ 0-ffff^ d52-3.4.1.orig/cyclefiles/bench0.ds80c320.d520000664000175000017500000000140410570463116016200 0ustar uweuwe; ; D52 V3.4.0 8052 Disassembly of bench0.hex ; 02/25/07 20:47 ; org 0 ; push psw ; 2 push acc ; 2 setb rs0 ; 2 jbc ti,X0011 ; 4 X0009: jbc ri,X0028 ; 4 X000c: pop acc ; 2 pop psw ; 2 reti ; 4 ; X0011: mov a,20h ; 2 jz X0009 ; 3 dec 20h ; 2 add a,#22h ; 2 mov r0,a ; 1 mov r2,p2 ; 2 clr a ; 1 addc a,#0 ; 2 mov p2,a ; 2 movx a,@r0 ; 2 mov p2,r2 ; 2 mov sbuf,a ; 2 sjmp X0009 ; 3 ; X0028: mov r1,21h ; 2 mov @r1,sbuf ; 2 inc r1 ; 1 cjne r1,#2dh,X0032 ; 4 mov r1,#28h ; 2 X0032: mov a,r1 ; 1 cjne a,22h,X0038 ; 4 sjmp X000c ; 3 ; X0038: mov 21h,a ; 2 sjmp X000c ; 3 ; ; --- Cycle count 0000-ffff = 72 ; end ; d52-3.4.1.orig/cyclefiles/bench0.ds89c4x0.d520000664000175000017500000000140410570463220016314 0ustar uweuwe; ; D52 V3.4.0 8052 Disassembly of bench0.hex ; 02/25/07 20:48 ; org 0 ; push psw ; 2 push acc ; 2 setb rs0 ; 2 jbc ti,X0011 ; 4 X0009: jbc ri,X0028 ; 4 X000c: pop acc ; 2 pop psw ; 2 reti ; 3 ; X0011: mov a,20h ; 2 jz X0009 ; 3 dec 20h ; 2 add a,#22h ; 2 mov r0,a ; 1 mov r2,p2 ; 2 clr a ; 1 addc a,#0 ; 2 mov p2,a ; 2 movx a,@r0 ; 2 mov p2,r2 ; 2 mov sbuf,a ; 2 sjmp X0009 ; 3 ; X0028: mov r1,21h ; 2 mov @r1,sbuf ; 2 inc r1 ; 1 cjne r1,#2dh,X0032 ; 4 mov r1,#28h ; 2 X0032: mov a,r1 ; 1 cjne a,22h,X0038 ; 5 sjmp X000c ; 3 ; X0038: mov 21h,a ; 2 sjmp X000c ; 3 ; ; --- Cycle count 0000-ffff = 72 ; end ; d52-3.4.1.orig/cyclefiles/BENCH0.HEX0000664000175000017500000000027110570443176014632 0ustar uweuwe:10000000C0D0C0E0D2D310990810981CD0E0D0D056 :1000100032E52060F415202422F8AAA0E43400F58B :10002000A0E28AA0F59980E1A921A79909B92D023A :0C0030007928E9B5220280D4F52180D0A7 :00000001FF d52-3.4.1.orig/cyclefiles/BENCH0.LST0000664000175000017500000000714610570443176014660 0ustar uweuwe BENCH0 PAGE 1 1 $mod52 2 0020 3 DSEG AT 20h 0020 4 TI_PTR: DS 1 0021 5 Rx_Head: DS 1 0022 6 Rx_Tail: DS 1 0023 7 TxBuff: DS 5 0028 8 TxBuffEnd: 0028 9 RxBuff: DS 5 002D 10 RxBuffEnd: 11 ---- 12 CSEG 13 0000 C0D0 14 SerialISR: PUSH PSW 0002 C0E0 15 PUSH ACC 0004 D2D3 16 SETB RS0 0006 109908 17 JBC TI,TI_ISR 0009 10981C 18 TI_ISREnd: JBC RI,RI_ISR 000C D0E0 19 SerialISREnd: POP ACC 000E D0D0 20 POP PSW 0010 32 21 RETI 0011 E520 22 TI_ISR: MOV A,TI_PTR 0013 60F4 23 JZ TI_ISREnd 0015 1520 24 DEC TI_PTR 0017 2422 25 ADD A,#LOW(TxBuff-1) 0019 F8 26 MOV R0,A 001A AAA0 27 MOV R2,P2 001C E4 28 CLR A 001D 3400 29 ADDC A,#HIGH(TxBuff-1) 001F F5A0 30 MOV P2,A 0021 E2 31 MOVX A,@R0 0022 8AA0 32 MOV P2,R2 0024 F599 33 MOV SBUF,A 0026 80E1 34 SJMP TI_ISREnd 0028 A921 35 RI_ISR: MOV R1,RX_Head 002A A799 36 MOV @R1,SBUF 002C 09 37 INC R1 002D B92D02 38 CJNE R1,#RXBuffEnd,RI_ISR_X1 0030 7928 39 MOV R1,#RXBuff 0032 E9 40 RI_ISR_X1: MOV A,R1 0033 B52202 41 CJNE A,RX_Tail,RI_ISR_X2 0036 80D4 42 SJMP SerialISREnd 0038 F521 43 RI_ISR_X2: MOV RX_Head,A 003A 80D0 44 SJMP SerialISREnd 45 end VERSION 1.2k ASSEMBLY COMPLETE, 0 ERRORS FOUND BENCH0 PAGE 2 ACC. . . . . . . . . . . . . . . D ADDR 00E0H PREDEFINED P2 . . . . . . . . . . . . . . . D ADDR 00A0H PREDEFINED PSW. . . . . . . . . . . . . . . D ADDR 00D0H PREDEFINED RI . . . . . . . . . . . . . . . B ADDR 0098H PREDEFINED RI_ISR . . . . . . . . . . . . . C ADDR 0028H RI_ISR_X1. . . . . . . . . . . . C ADDR 0032H RI_ISR_X2. . . . . . . . . . . . C ADDR 0038H RS0. . . . . . . . . . . . . . . B ADDR 00D3H PREDEFINED RXBUFF . . . . . . . . . . . . . D ADDR 0028H RXBUFFEND. . . . . . . . . . . . D ADDR 002DH RX_HEAD. . . . . . . . . . . . . D ADDR 0021H RX_TAIL. . . . . . . . . . . . . D ADDR 0022H SBUF . . . . . . . . . . . . . . D ADDR 0099H PREDEFINED SERIALISR. . . . . . . . . . . . C ADDR 0000H NOT USED SERIALISREND . . . . . . . . . . C ADDR 000CH TI . . . . . . . . . . . . . . . B ADDR 0099H PREDEFINED TI_ISR . . . . . . . . . . . . . C ADDR 0011H TI_ISREND. . . . . . . . . . . . C ADDR 0009H TI_PTR . . . . . . . . . . . . . D ADDR 0020H TXBUFF . . . . . . . . . . . . . D ADDR 0023H TXBUFFEND. . . . . . . . . . . . D ADDR 0028H NOT USED d52-3.4.1.orig/cyclefiles/bench0.msc12xx.d520000664000175000017500000000140410570463534016343 0ustar uweuwe; ; D52 V3.4.0 8052 Disassembly of bench0.hex ; 02/25/07 20:51 ; org 0 ; push psw ; 2 push acc ; 2 setb rs0 ; 2 jbc ti,X0011 ; 4 X0009: jbc ri,X0028 ; 4 X000c: pop acc ; 2 pop psw ; 2 reti ; 4 ; X0011: mov a,20h ; 2 jz X0009 ; 3 dec 20h ; 2 add a,#22h ; 2 mov r0,a ; 1 mov r2,p2 ; 2 clr a ; 1 addc a,#0 ; 2 mov p2,a ; 2 movx a,@r0 ; 2 mov p2,r2 ; 2 mov sbuf,a ; 2 sjmp X0009 ; 3 ; X0028: mov r1,21h ; 2 mov @r1,sbuf ; 2 inc r1 ; 1 cjne r1,#2dh,X0032 ; 4 mov r1,#28h ; 2 X0032: mov a,r1 ; 1 cjne a,22h,X0038 ; 4 sjmp X000c ; 3 ; X0038: mov 21h,a ; 2 sjmp X000c ; 3 ; ; --- Cycle count 0000-ffff = 72 ; end ; d52-3.4.1.orig/cyclefiles/bench0.silabs.d520000664000175000017500000000140410570451054016305 0ustar uweuwe; ; D52 V3.4.0 8052 Disassembly of bench0.hex ; 02/25/07 19:21 ; org 0 ; push psw ; 2 push acc ; 2 setb rs0 ; 2 jbc ti,X0011 ;^ 4 X0009: jbc ri,X0028 ;^ 4 X000c: pop acc ; 2 pop psw ; 2 reti ; 5 ; X0011: mov a,20h ; 2 jz X0009 ;^ 3 dec 20h ; 2 add a,#22h ; 2 mov r0,a ; 1 mov r2,p2 ; 2 clr a ; 1 addc a,#0 ; 2 mov p2,a ; 2 movx a,@r0 ; 3 mov p2,r2 ; 2 mov sbuf,a ; 2 sjmp X0009 ; 3 ; X0028: mov r1,21h ; 2 mov @r1,sbuf ; 2 inc r1 ; 1 cjne r1,#2dh,X0032 ;^ 4 mov r1,#28h ; 2 X0032: mov a,r1 ; 1 cjne a,22h,X0038 ;^ 4 sjmp X000c ; 3 ; X0038: mov 21h,a ; 2 sjmp X000c ; 3 ; ; --- Cycle count 0000-ffff = 74 ; end ; d52-3.4.1.orig/cyclefiles/bench0.w77e.d520000664000175000017500000000140410570463454015630 0ustar uweuwe; ; D52 V3.4.0 8052 Disassembly of bench0.hex ; 02/25/07 20:50 ; org 0 ; push psw ; 2 push acc ; 2 setb rs0 ; 2 jbc ti,X0011 ; 4 X0009: jbc ri,X0028 ; 4 X000c: pop acc ; 2 pop psw ; 2 reti ; 2 ; X0011: mov a,20h ; 2 jz X0009 ; 3 dec 20h ; 2 add a,#22h ; 2 mov r0,a ; 1 mov r2,p2 ; 2 clr a ; 1 addc a,#0 ; 2 mov p2,a ; 2 movx a,@r0 ; 2 mov p2,r2 ; 2 mov sbuf,a ; 2 sjmp X0009 ; 3 ; X0028: mov r1,21h ; 2 mov @r1,sbuf ; 2 inc r1 ; 1 cjne r1,#2dh,X0032 ; 4 mov r1,#28h ; 2 X0032: mov a,r1 ; 1 cjne a,22h,X0038 ; 4 sjmp X000c ; 3 ; X0038: mov 21h,a ; 2 sjmp X000c ; 3 ; ; --- Cycle count 0000-ffff = 70 ; end ; d52-3.4.1.orig/cyclefiles/cycle_counting.doc0000664000175000017500000007200010570507650017056 0ustar uweuweÐÏࡱá>þÿ 57þÿÿÿ4ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿì¥Áq`ð¿=bjbjqPqP-(::=ÿÿÿÿÿÿ¤,,,,,,,šäBBBBV~ TŽvvvvvQQQ—™™™dýlilÕ$âhJ0ù,QQQQQù,,vvÛQf,v,v—Q—?,,gvj @lnb.YÇB·úW‹ $0T_z±Xzgz,g$QQQQQQQùù  QQQTQQQQ~ ~ ~ ÄB~ ~ ~ B@4t"–,,,,,,ÿÿÿÿ Cycle Counting for D52 and D48 and DZ80 by Jan Waclawek, wek at efton dot sk, Feb 2007 Some pseudo-legal stuff Absolutely no guarantee. Use at your own risk. What else would you expect? How? Add Z directives to the .ctl file, with range for which the cycle counting has to be performed. The output file will contain a cycle number for each instruction in the comment field, and a summary after end of each range. Ranges for Z directives can be nested and can be defined in any order, but must not partially overlap. All cycle counts are in given in instruction cycles. For clock cycles, multiply by clock/instruction value. More details... Z[range][suffix[value]] Range can be defined as usual with other directives in .ctl files - either as startend or as start+length. Range can also be a single number (except where the "-" suffix is needed - see known issues), which is equivalent to a start-start range. Suffix is one of: * - the total cycle count of this range is multiplied by the given value, and this value will be added to the parent range cycle count. Useful for cycle counting in cycles. See also (auto)repeat in special cases below. - - this range (including its subranges) will be excluded from cycle count of the parent; however, the total count of this range will be written to output file. No value needed. The individual instructions' cycle count will be suffixed by “-” in the output file for this range. See also taken/not taken in special cases below. = - the calculated cycle count for this range will be overriden by the given value. Intended to be used for individual instructions, use for a bigger range for extra fun with unexpected results. The individual instructions' cycle count will be prefixed by “=” in the output file for this range. ^ - in this range, the alternative (higher) cycle count is always used, if available. The individual instructions' cycle count will be prefixed by “^” in the output file for this range. See also taken/not taken in special cases below. Caution, value is entered in hexadecimal with no prefix nor suffix, just as the addresses in the range. Special cases Some processors, such as the Z80 and the SiLabs singleclock '51 core, have some instructions with two different cycle counts - conditional jumps (calls, returns), with different timing for the taken/not taken jump; and autorepeated instructions. The default value is the smaller, jump-not-taken, or, for the autorepeated instructions, last-repeat (single-pass), value. However, there are exceptions. Repeated and autorepeated instructions can be properly counted, if a single-address range is given for the first byte of the instruction, with a * suffix, giving the number of repeats. In this case, the instruction's cycle count is calculated as the number of repeats less one times the bigger count, plus the smaller count. This calculation is written to the comment field and there will be no summary for this range. For example, if Z addr*23 directive is used for a djnz at address addr, the following will be output (note that value is 23 hexadecimal = 35 decimal): addr: djnz begin ;450 = 13 * 34x + 8 ; Note, that this won't work if the range is bigger than this. Thus, for example, if there is a cycle ending by a djnz (Z80-style) executed multiple times, the proper cycle count cannot be obtained using a single Z begin-end*repeats directive; the following construction has to be used instead: Z begin-addr1*repeats ;addr1 is the address just before djnz (addr1=addr2-1) Z addr2*repeats ;addr2 is the address of djnz Z begin-addr2 ;this range gives the final count A similar construction can be used for a cycle ending by any conditional jump. Conditional jumps are guessed to be taken, if the following instruction falls outside any range, or an excluding range (suffix -) begins on the following instruction, or, of course, if “explicit taken” has been defined (see ^ suffix). In this case, the jump instruction's cycle count will be prefixed by “^” in the output file. If the guesses work out bad, try to use the = prefix for overriding it by explicit cycle count value. Customized cycle files The default cycles counts can be overriden by a user-definable list of cycle counts. This is imported using a command-line –z switch. The filename must be added immediately after –z, with not space. The format of each line in the file is the following: [opcode - cycle count[/ alternative cycle count]][; comment][# comment] Opcode and cycle counts are given in hexadecimal with no prefix/suffix, maximum two digits. Alternative cycle count is for conditional jumps and autorepeated instructions, see special cases above. Opcodes can be in any order. Missing opcodes will be given cycle count = 0. Comment with ; is ignored, comment with # is printed to console when file is read in. Known issues There is no 8080 support in DZ80. In the import of user definable cycle files, there is no support for the prefixed Z80 instructions. If the - suffix has to be used to specify an excluded range for a single instruction, the one-address format cannot be used, i.e. Z address- won't work properly. Use Z addressaddress instead. Why in disassembler? (WÄÅèí½ Ã Ú ã # 8 ž ç ì í ð ø ý þ   ' } ˆ ‘ — £ ¤ æ ë Y e i v ~  " ' n o ¬ ° ½ Å Æ ÆÇì퀯¾ÂÏàåôÿGN\cÝåêöno™?%dúôíéäéäéäéäéäéäéߨßéߨßéäéßéäéäéßéßéßéäéßéäéßéßéäéßéäéäéäéßéßéäéäéäéäéäéäéäéÐéÐéÐéhw\½OJQJ hw\½56 hw\½6 hw\½5hw\½ hw\½6CJ hw\½CJ hw\½CJ$R(WXp»À ž  q ™ ‘ £ ~ Å ì×?MÝ€öíèèãÞãÞÞÞÞãÞÞÞÑÑÑÑÞãÞÞÞ $„„„nþ^„„`„nþa$$a$$a$$a$$¤¤wa$$¤î¤a$=ý?d±ß^¦ #ê hÏÜþb$9:;<=úúïïïæÝúØúúúúÖúúúÖúúúú$a$$¤¤wa$$¤q¤wa$ $ Æ ¤a$$a$d7IK^p‚‡ÝÞÒÓxž éí ()67RS]^Ã%†‡¡¢ÎÏåôþ4`abijäî$=øôðôðôëôëôëôëôëôðãðôðôðÛðÛðÛðÛðôÓôËôËôðôÄôÀ¹ÀôÀ±À©À©¤©¤Àô h•Le6h•Leh•Le6h•Leh•Le5 h•Leh•Leh•Le h•Lehw\½hw\½hw\½5hw\½hw\½6hSˆhSˆ5hw\½hSˆ5 hw\½5hSˆhw\½hw\½OJQJ9+;0°. °ÅA!°n"°n#n$n%°°Ä°Ä ĆœV@ñÿV Normálny*$1$5$7$8$9DH$CJ_HmH sH tH>`> Nadpis 1  & F@&5CJ D`D Nadpis 2 & F¤Ñ¤w@&564@4 Nadpis 3@&5FA@òÿ¡F Predvolené písmo odseku^i@óÿ³^ Normálna tabu>ka :V ö4Ö4Ö laö 0k@ôÿÁ0 Bez zoznamu 6þOòÿñ6 BulletsCJOJQJkH*FB@F Základný text¤x CJOJQJBþOB Heading $¤ð¤x CJOJQJ(/@"( Zoznam>þO2> Caption  $¤x¤x6CJ*þOB* Index $JþORJ Preformatted Text CJOJQJ=(ÿÿÿÿ ÿÿ§#£ ÿÿ§#£ ÿÿ§#£ÿ$=Þ(WXp»À žq™‘£~Åì×?MÝ €  ? d ± ß ^¦ #ê hÏÜþb$9:;<?¦%/¦%HÖ¦%@ܦ%8_¦% )¦%8_¦% )¦%8_¦%8_¦%8_¦%8_¦% )¦%8_¦%8_¦%8_¦%8_¦%8_¦%8_¦%8_¦%8_¦% )¦%8_¦%8_ÿ¦%¸¦%Èÿ¦%(Ö ¦%Ȧ%Ȧ%Ȧ%8_¦%8_¦%8_¦% )¦%8_¦%8_¦%8_¦%8_¦% )¦%8_¦%8_¦%8_¦% )¦%8_¦%8_¦%8_¦%8_(WXp»À žq™‘£~Åì×?MÝ €  ? d ± ß ^¦ #ê hÏÜþb$9:;<? 0€€ 0€€˜0€˜0€ 0˜0€X 0˜0€»˜0€»˜0€»˜0€» 0˜0€q˜0€q˜0€q˜0€q˜0€q˜0€q˜0€q˜0€q 0˜0€?˜0€?˜0€?˜0€?˜0€?˜0€?˜0€?˜0€?˜0€?˜0€?˜0€? 0˜0€ ˜0€ ˜0€€˜0€€ 0˜0€€˜0€€˜0€€ 0˜0€7˜0€7˜0€7˜0€7d===ð8ð@ñÿÿÿ€€€÷ð’ðð0ð( ð ððB ðS ð¿Ëÿ ?ð/79<@EJLÙÜÑÔøœ¥ûv|}ˆ( 4 ê ö ’ – ² ¶ Â Æ    ! ¯ ³ œ   Ú Þ DM!'hnù-4RY+7?(*pˆˆŠôýQT+O^eš £   ? D z € Á Ç í ò !'_f‡ßâ?::::::::::::::::::::77IKxéøÎÜýþ#<??ûÿÿÿjA*ÿÿÿÿÿÿÿÿÿ@ÿÿÿÿÿÿÿûÿÿÿÿÿÿÿÿÿÿÿå•LeSˆw\½?ÿ@Microsoft Office Document Image WriterNe00:winspoolMicrosoft Office Document Image Writer DriverMicrosoft Office Document ImagÜ/ d,,LetterwidmþÈMicrosoft Office Document ImagÜ/ d,,LetterwidmþÈ€##ˆw66##=P@ÿÿUnknownÿÿÿÿÿÿÿÿÿÿÿÿGî‡z €ÿTimes New Roman5€Symbol3&î ‡z €ÿArial?5î ‡z €ÿCourier New_ StarSymbolArial Unicode MS7&î ‡ ŸVerdanaBAˆÅhi¬ûEëͲ8 ƒ$8 $!„¥Àxx€24d333ƒ„ÿßHP(ðÿ?âÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿSˆ2ÿÿala þÿà…ŸòùOh«‘+'³Ù0x˜ ¬¸ÄÐÜð ü ( 4 @ LX`hpâ Normal.dotala5Microsoft Office Word@¦÷_@˜þJ@v…#0¸º@òM.YÇ8þÿÕÍÕœ.“—+,ù®0è hp|„Œ” œ¤¬´ ¼ Éâ$ 3æ  Názov þÿÿÿ !"#þÿÿÿ%&'()*+þÿÿÿ-./0123þÿÿÿýÿÿÿ6þÿÿÿþÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRoot Entryÿÿÿÿÿÿÿÿ ÀF:†b.YÇ8€1TableÿÿÿÿÿÿÿÿŠWordDocumentÿÿÿÿÿÿÿÿ-(SummaryInformation(ÿÿÿÿ$DocumentSummaryInformation8ÿÿÿÿÿÿÿÿÿÿÿÿ,CompObjÿÿÿÿÿÿÿÿÿÿÿÿzÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþÿ ÿÿÿÿ ÀF(Dokument programu Microsoft Office Word MSWordDocWord.Document.8ô9²qd52-3.4.1.orig/cyclefiles/cycle_counting.htm0000664000175000017500000006476310570510566017122 0ustar uweuwe Cycle Counting for D52

Cycle Counting for D52

and D48 and DZ80

by Jan Waclawek, wek at efton dot sk, Feb 2007

 

Some pseudo-legal stuff

Absolutely no guarantee. Use at your own risk. What else would you expect?

How?

Add Z directives to the .ctl file, with range for which the cycle counting has to be performed.

The output file will contain a cycle number for each instruction in the comment field, and a summary after end of each range.

Ranges for Z directives can be nested and can be defined in any order, but must not partially overlap.

All cycle counts are in given in instruction cycles. For clock cycles, multiply by clock/instruction value.

More details...

Z[range][suffix[value]]

Range can be defined as usual with other directives in .ctl files - either as startend or as  start+length. Range can also be a single number (except where the "-" suffix is needed - see known issues), which is equivalent to a start-start range.

Suffix is one of:

* - the total cycle count of this range is multiplied by the given value, and this value will be added to the parent range cycle count. Useful for cycle counting in cycles. See also (auto)repeat in special cases below.

- -  this range (including its subranges) will be excluded from cycle count of the parent; however, the total count of this range will be written to output file. No value needed. The individual instructions' cycle count will be suffixed by “-” in the output file for this range. See also taken/not taken in special cases below.

= - the calculated cycle count for this range will be overriden by the given value. Intended to be used for individual instructions, use for a bigger range for extra fun with unexpected results. The individual instructions' cycle count will be prefixed by “=” in the output file for this range.

^ - in this range, the alternative (higher) cycle count is always used, if available. The individual instructions' cycle count will be prefixed by “^” in the output file for this range. See also taken/not taken in special cases below.

Caution, value is entered in hexadecimal with no prefix nor suffix, just as the addresses in the range.

Special cases

Some processors, such as the Z80 and the SiLabs singleclock '51 core, have some instructions with two different cycle counts - conditional jumps (calls, returns), with different timing for the taken/not taken jump; and autorepeated instructions. The default value is the smaller, jump-not-taken, or, for the autorepeated instructions, last-repeat (single-pass), value. However, there are exceptions.

Repeated and autorepeated instructions can be properly counted, if a single-address range is given for the first byte of the instruction, with a * suffix, giving the number of repeats. In this case, the instruction's cycle count is calculated as the number of repeats less one times the bigger count, plus the smaller count. This calculation is written to the comment field and there will be no summary for this range.

For example, if Z addr*23 directive is used for a djnz at address addr, the following will be output (note that value is 23 hexadecimal = 35 decimal):

addr: djnz  begin       ;450 = 13 * 34x + 8 ;

Note, that this won't work if the range is bigger than this. Thus, for example, if there is a cycle ending by a djnz (Z80-style) executed multiple times, the proper cycle count cannot be obtained using a single Z begin-end*repeats directive; the following construction has to be used instead:

Z begin-addr1*repeats   ;addr1 is the address just before djnz (addr1=addr2-1)

Z addr2*repeats         ;addr2 is the address of djnz

Z begin-addr2           ;this range gives the final count

A similar construction can be used for a cycle ending by any conditional jump.

Conditional jumps are guessed to be taken, if the following instruction falls outside any range, or an excluding range (suffix -) begins on the following instruction, or, of course, if “explicit taken” has been defined (see ^ suffix). In this case, the jump instruction's cycle count will be prefixed by “^” in the output file.

If the guesses work out bad, try to use the = prefix for overriding it by explicit cycle count value.

Customized cycle files

The default cycles counts can be overriden by a user-definable list of cycle counts. This is imported using a command-line –z switch. The filename must be added immediately after –z, with not space.

The format of each line in the file is the following:

[opcode - cycle count[/ alternative cycle count]][; comment][# comment]

Opcode and cycle counts are given in hexadecimal with no prefix/suffix, maximum two digits. Alternative cycle count is for conditional jumps and autorepeated instructions, see special cases above. Opcodes can be in any order. Missing opcodes will be given cycle count = 0. Comment with ; is ignored, comment with # is printed to console when file is read in.

Known issues

There is no 8080 support in DZ80.

In the import of user definable cycle files, there is no support for the prefixed Z80 instructions.

If the - suffix has to be used to specify an excluded range for a single instruction, the one-address format cannot be used, i.e. Z address- won't work properly. Use Z address‑address‑ instead.

Why in disassembler?

Cycle counting is used usually to optimize a certain section of a newly written program. It would be more convenient to have the cycle count in assembler and/or compiler output, no doubt.

However, having it in disassembler, the cycle counting gets assembler/compiler independent. Most of assemblers/compilers are closed source, even if some of them are provided free. Support for cycle counting is therefore upon to the goodwill of the assembler/compiler author. Also, it is not likely that a common library would fit universally, which makes cycle counting availability accross multiple tools less likely.

That's why.

 

d52-3.4.1.orig/cyclefiles/cycle_counting.rtf0000664000175000017500000005003410570510542017101 0ustar uweuwe{\rtf1\ansi\ansicpg1250\uc1\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang1051\deflangfe1051{\fonttbl{\f0\froman\fcharset238\fprq2{\*\panose 02020603050405020304}Times New Roman;} {\f1\fswiss\fcharset238\fprq2{\*\panose 020b0604020202020204}Arial;}{\f2\fmodern\fcharset238\fprq1{\*\panose 02070309020205020404}Courier New;}{\f36\fnil\fcharset2\fprq0{\*\panose 00000000000000000000}StarSymbol{\*\falt Arial Unicode MS};} {\f37\fswiss\fcharset238\fprq2{\*\panose 020b0604030504040204}Verdana;}{\f40\froman\fcharset0\fprq2 Times New Roman;}{\f39\froman\fcharset204\fprq2 Times New Roman Cyr;}{\f41\froman\fcharset161\fprq2 Times New Roman Greek;} {\f42\froman\fcharset162\fprq2 Times New Roman Tur;}{\f43\froman\fcharset177\fprq2 Times New Roman (Hebrew);}{\f44\froman\fcharset178\fprq2 Times New Roman (Arabic);}{\f45\froman\fcharset186\fprq2 Times New Roman Baltic;} {\f46\froman\fcharset163\fprq2 Times New Roman (Vietnamese);}{\f50\fswiss\fcharset0\fprq2 Arial;}{\f49\fswiss\fcharset204\fprq2 Arial Cyr;}{\f51\fswiss\fcharset161\fprq2 Arial Greek;}{\f52\fswiss\fcharset162\fprq2 Arial Tur;} {\f53\fswiss\fcharset177\fprq2 Arial (Hebrew);}{\f54\fswiss\fcharset178\fprq2 Arial (Arabic);}{\f55\fswiss\fcharset186\fprq2 Arial Baltic;}{\f56\fswiss\fcharset163\fprq2 Arial (Vietnamese);}{\f60\fmodern\fcharset0\fprq1 Courier New;} {\f59\fmodern\fcharset204\fprq1 Courier New Cyr;}{\f61\fmodern\fcharset161\fprq1 Courier New Greek;}{\f62\fmodern\fcharset162\fprq1 Courier New Tur;}{\f63\fmodern\fcharset177\fprq1 Courier New (Hebrew);} {\f64\fmodern\fcharset178\fprq1 Courier New (Arabic);}{\f65\fmodern\fcharset186\fprq1 Courier New Baltic;}{\f66\fmodern\fcharset163\fprq1 Courier New (Vietnamese);}{\f410\fswiss\fcharset0\fprq2 Verdana;}{\f409\fswiss\fcharset204\fprq2 Verdana Cyr;} {\f411\fswiss\fcharset161\fprq2 Verdana Greek;}{\f412\fswiss\fcharset162\fprq2 Verdana Tur;}{\f415\fswiss\fcharset186\fprq2 Verdana Baltic;}{\f416\fswiss\fcharset163\fprq2 Verdana (Vietnamese);}}{\colortbl;\red0\green0\blue0;\red0\green0\blue255; \red0\green255\blue255;\red0\green255\blue0;\red255\green0\blue255;\red255\green0\blue0;\red255\green255\blue0;\red255\green255\blue255;\red0\green0\blue128;\red0\green128\blue128;\red0\green128\blue0;\red128\green0\blue128;\red128\green0\blue0; \red128\green128\blue0;\red128\green128\blue128;\red192\green192\blue192;}{\stylesheet{\ql \li0\ri0\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \fs24\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 \snext0 Normal;}{ \s1\ql \li0\ri0\sb240\sa120\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\ls1\outlinelevel0\rin0\lin0\itap0 \b\f1\fs32\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 \sbasedon17 \snext16 heading 1;}{ \s2\ql \li0\ri0\sb465\sa119\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\ls1\ilvl1\outlinelevel1\rin0\lin0\itap0 \b\i\f1\fs28\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 \sbasedon17 \snext16 heading 2;}{ \s3\ql \li0\ri0\sb240\sa120\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\outlinelevel2\rin0\lin0\itap0 \b\f1\fs28\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 \sbasedon17 \snext16 heading 3;}{\*\cs10 \additive \ssemihidden Default Paragraph Font;} {\*\ts11\tsrowd\trftsWidthB3\trpaddl108\trpaddr108\trpaddfl3\trpaddft3\trpaddfb3\trpaddfr3\trcbpat1\trcfpat1\tscellwidthfts0\tsvertalt\tsbrdrt\tsbrdrl\tsbrdrb\tsbrdrr\tsbrdrdgl\tsbrdrdgr\tsbrdrh\tsbrdrv \ql \li0\ri0\widctlpar\aspalpha\aspnum\faauto\adjustright\rin0\lin0\itap0 \fs20\lang1024\langfe1024\cgrid\langnp1024\langfenp1024 \snext11 \ssemihidden Normal Table;}{\*\cs15 \additive \f36\fs18 Bullets;}{ \s16\ql \li0\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 \sbasedon0 \snext16 Body Text;}{ \s17\ql \li0\ri0\sb240\sa120\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \f1\fs28\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 \sbasedon0 \snext16 Heading;}{ \s18\ql \li0\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 \sbasedon16 \snext18 List;}{ \s19\ql \li0\ri0\sb120\sa120\nowidctlpar\noline\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \i\fs20\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 \sbasedon0 \snext19 Caption;}{ \s20\ql \li0\ri0\nowidctlpar\noline\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \fs24\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 \sbasedon0 \snext20 Index;}{\s21\ql \li0\ri0\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \f2\fs20\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 \sbasedon0 \snext21 Preformatted Text;}}{\*\latentstyles\lsdstimax156\lsdlockeddef0}{\*\listtable{\list\listtemplateid705839466{\listlevel\levelnfc255\levelnfcn255\leveljc0\leveljcn0\levelfollow2 \levelstartat1\levelspace0\levelindent0{\leveltext\'00;}{\levelnumbers;}\s1}{\listlevel\levelnfc255\levelnfcn255\leveljc0\leveljcn0\levelfollow0\levelstartat1\levelold\levelspace0\levelindent0{\leveltext\'00;}{\levelnumbers;}\s2}{\listlevel\levelnfc255 \levelnfcn255\leveljc0\leveljcn0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\'00;}{\levelnumbers;}}{\listlevel\levelnfc255\levelnfcn255\leveljc0\leveljcn0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext \'00;}{\levelnumbers;}}{\listlevel\levelnfc255\levelnfcn255\leveljc0\leveljcn0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\'00;}{\levelnumbers;}}{\listlevel\levelnfc255\levelnfcn255\leveljc0\leveljcn0\levelfollow0\levelstartat0 \levelspace0\levelindent0{\leveltext\'00;}{\levelnumbers;}}{\listlevel\levelnfc255\levelnfcn255\leveljc0\leveljcn0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\'00;}{\levelnumbers;}}{\listlevel\levelnfc255\levelnfcn255\leveljc0\leveljcn0 \levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\'00;}{\levelnumbers;}}{\listlevel\levelnfc255\levelnfcn255\leveljc0\leveljcn0\levelfollow0\levelstartat0\levelspace0\levelindent0{\leveltext\'00;}{\levelnumbers;}}{\listname ;}\listid-5}} {\*\listoverridetable{\listoverride\listid-5\listoverridecount0\ls1}}{\*\rsidtbl \rsid2897750\rsid6638741\rsid8934144\rsid12409975\rsid14363219}{\*\generator Microsoft Word 11.0.5604;}{\info{\title Cycle Counting for D52}{\author ala}{\operator ala} {\creatim\yr2007\mo2\dy25\hr23\min50}{\revtim\yr2007\mo2\dy25\hr23\min50}{\version2}{\edmins2}{\nofpages3}{\nofwords865}{\nofchars4933}{\nofcharsws5787}{\vern24689}}\paperw11905\paperh16837\margl1134\margr1134\margt1134\margb1134 \deftab709\widowctrl\ftntj\aenddoc\nospaceforul\lytprtmet\formshade\horzdoc\dghspace120\dgvspace120\dghorigin1701\dgvorigin1984\dghshow1\dgvshow0\jexpand\viewkind1\viewscale100\pgbrdrhead\pgbrdrfoot\bdrrlswsix\nolnhtadjtbl\oldas\rsidroot8934144 \fet0 \sectd \linex0\headery708\footery708\colsx708\endnhere\sectdefaultcl\sftntj {\*\pnseclvl1\pnucrm\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl2\pnucltr\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl3\pndec\pnstart1\pnindent720\pnhang {\pntxta .}}{\*\pnseclvl4\pnlcltr\pnstart1\pnindent720\pnhang {\pntxta )}}{\*\pnseclvl5\pndec\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl6\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl7 \pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl8\pnlcltr\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\*\pnseclvl9\pnlcrm\pnstart1\pnindent720\pnhang {\pntxtb (}{\pntxta )}}{\listtext\tab}\pard\plain \s1\qc \li0\ri0\sb238\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\ls1\outlinelevel0\rin0\lin0\itap0 \b\f1\fs32\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\fs36\insrsid12409975 Cycle Counting for D52 \par {\listtext\tab}}\pard \s1\qc \li0\ri0\sa119\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\ls1\outlinelevel0\rin0\lin0\itap0 {\fs24\insrsid12409975 and D48 and DZ80 \par }\pard\plain \s16\qc \li0\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\i\fs16\insrsid12409975 by Jan Waclawek, wek at efton dot sk, Feb 2007 \par }{\insrsid12409975 \par {\listtext\tab}}\pard\plain \s2\qj \li0\ri0\sb465\sa119\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\ls1\ilvl1\outlinelevel1\rin0\lin0\itap0 \b\i\f1\fs28\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid12409975 Some pseudo-legal stuff \par }\pard\plain \s16\qj \li0\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid12409975 Absolutely no guarantee. Use at your own risk. What else would you expect? \par {\listtext\tab}}\pard\plain \s2\qj \li0\ri0\sb465\sa119\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\ls1\ilvl1\outlinelevel1\rin0\lin0\itap0 \b\i\f1\fs28\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid12409975 How? \par }\pard\plain \s16\qj \li0\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid12409975 Add }{\b\insrsid12409975 Z}{\insrsid12409975 directives to the .ctl file, with }{ \b\insrsid12409975 range}{\insrsid12409975 for which the cycle counting has to be performed. \par The output file will contain a cycle number for each instruction in the comment field, and a summary after end of each range. \par Ranges for Z directives can be }{\b\insrsid12409975 nested}{\insrsid12409975 and can be defined in }{\b\insrsid12409975 any order}{\insrsid12409975 , but must not partially overlap. \par All cycle counts are in given }{\b\insrsid12409975 in instruction cycles}{\insrsid12409975 . For clock cycles, multiply by clock/instruction value. \par {\listtext\tab}}\pard\plain \s2\qj \li0\ri0\sb465\sa119\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\ls1\ilvl1\outlinelevel1\rin0\lin0\itap0 \b\i\f1\fs28\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid12409975 More details... \par }\pard\plain \s16\qj \li0\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\b\insrsid12409975 Z[range][suffix[value]] \par Range}{\insrsid12409975 can be defined as usual with other directives in .ctl files - either as }{\i\insrsid12409975 start}{\b\i\insrsid12409975 \_}{\i\insrsid12409975 end}{\insrsid12409975 or as }{\i\insrsid12409975 start}{\b\i\insrsid12409975 +}{ \i\insrsid12409975 length. }{\insrsid12409975 Range can also be a }{\b\insrsid12409975 single number}{\insrsid12409975 (except where the "-" suffix is needed - see known issues), which is equivalent to a }{\i\insrsid12409975 start-start}{ \insrsid12409975 range. \par }{\b\insrsid12409975 Suffix}{\insrsid12409975 is one of: \par }\pard \s16\qj \fi-402\li388\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin388\itap0 {\b\insrsid12409975 *}{\insrsid12409975 -\tab the total cycle count of this range is multiplied by the given }{\i\insrsid12409975 value}{\insrsid12409975 , and this value will be added to the parent range cycle count. Useful for cycle counting in cycles. See also }{\i\insrsid12409975 (auto)repeat}{\insrsid12409975 in }{\i\insrsid12409975 special cases}{\insrsid12409975 below. \par }{\b\insrsid12409975 -}{\insrsid12409975 -\tab this range (including its subranges) will be excluded from cycle count of the parent; however, the total count of this range will be written to output file. No }{\i\insrsid12409975 value}{\insrsid12409975 needed. The individual instructions' cycle count will be suffixed by \'93}{\b\insrsid12409975 -}{\insrsid12409975 \'94 in the output file for this range. See also }{\i\insrsid12409975 taken/not taken}{\insrsid12409975 in }{\i\insrsid12409975 special cases}{\insrsid12409975 below. \par }{\b\insrsid12409975 =}{\insrsid12409975 -\tab the calculated cycle count for this range will be overriden by the given }{\i\insrsid12409975 value}{\insrsid12409975 . Intended to be used for individual instructions, use for a bigger range for extra fun with unexpected results. The individual instructions' cycle count will be prefixed by \'93}{\b\insrsid12409975 =}{\insrsid12409975 \'94 in the output file for this range. \par }{\b\insrsid12409975 ^}{\insrsid12409975 -\tab in this range, the alternative (higher) cycle count is always used, if available. The individual instructions' cycle count will be prefixed by \'93}{\b\insrsid12409975 ^}{\insrsid12409975 \'94 in the output file for this range. See also }{\i\insrsid12409975 taken/not taken}{\insrsid12409975 in }{\i\insrsid12409975 special cases}{\insrsid12409975 below. \par }\pard \s16\qj \li0\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 {\insrsid12409975 Caution, }{\b\insrsid12409975 value}{\insrsid12409975 is entered in }{\b\insrsid12409975 hexadecimal}{\insrsid12409975 with no prefix nor suffix, just as the addresses in the range. \par {\listtext\tab}}\pard\plain \s2\qj \li0\ri0\sb465\sa119\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\ls1\ilvl1\outlinelevel1\rin0\lin0\itap0 \b\i\f1\fs28\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid12409975 Special cases \par }\pard\plain \s16\qj \li0\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid12409975 Some processors, such as the Z80 and the SiLabs singleclock '51 core, have some instructions with two different cycle counts - conditional jumps (calls, returns), with different timing for the taken/not taken jump; and autorepeated instructions. The }{ \b\insrsid12409975 default}{\insrsid12409975 value is the }{\b\insrsid12409975 smaller}{\insrsid12409975 , jump-not-taken, or, for the autorepeated instructions, last-repeat (single-pass), value. However, there are exceptions. \par }{\b\insrsid12409975 Repeated}{\insrsid12409975 and }{\b\insrsid12409975 autorepeated}{\insrsid12409975 instructions can be properly counted, if a single-address range is given for the first byte of the instruction, with a }{\b\insrsid12409975 *}{ \insrsid12409975 suffix, giving the number of repeats. In this case, the instruction's cycle count is calculated as the number of repeats less one times the bigg er count, plus the smaller count. This calculation is written to the comment field and there will be no summary for this range. \par For example, if }{\f2\insrsid12409975 Z addr*23}{\insrsid12409975 directive is used for a djnz at address addr, the following will be output (note that value is 23 hexadecimal = 35 decimal): \par }{\f2\insrsid12409975 addr:\tab djnz\tab begin\tab \tab ;450 = 13 * 34x + 8 ; \par }{\insrsid12409975 Note, that this won't work if the range is bigger than this. Thus, for example, if there is a cycle ending by a djnz (Z80-style) executed multiple times, the proper cycle count cannot be obtained using a single }{\f2\insrsid12409975 Z begin-end*repeats}{\insrsid12409975 directive; the following construction has to be used instead: \par }\pard \s16\qj \li0\ri0\nowidctlpar\tx2839\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 {\f2\insrsid12409975 Z begin-addr1*repeats\tab ;addr1 is the address just before djnz (addr1=addr2-1) \par Z addr2*repeats\tab ;addr2 is the address of djnz \par Z begin-addr2\tab ;this range gives the final count \par }\pard \s16\qj \li0\ri0\sb113\sa119\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 {\insrsid12409975 A similar }{\insrsid8934144 construction can be used for a}{\insrsid12409975 cycle ending by a}{\insrsid8934144 ny}{\insrsid12409975 conditional jump. \par }\pard \s16\qj \li0\ri0\sb283\sa119\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 {\b\insrsid12409975 Conditional jumps }{\insrsid12409975 are guessed to be }{\b\insrsid12409975 taken}{\insrsid12409975 , if the following instruction falls outside any range, or an excluding range (suffix }{\b\insrsid12409975 -}{\insrsid12409975 ) begins on the following instruction, or, of course, if \'93explicit taken\'94 has been defined (see ^ suffix). In this case, the jump instruction's cycle count will be prefixed by \'93}{\b\insrsid12409975 ^}{\insrsid12409975 \'94 in the output file. \par }\pard \s16\qj \li0\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 {\insrsid12409975 If the guesses work out bad, try to use the }{\b\insrsid12409975 =}{\insrsid12409975 prefix for overriding it by explicit cycle count value. \par {\listtext\tab}}\pard\plain \s2\qj \li0\ri0\sb465\sa119\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\ls1\ilvl1\outlinelevel1\rin0\lin0\itap0 \b\i\f1\fs28\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid12409975 Customized cycle files \par }\pard\plain \s16\qj \li0\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid12409975 The default cycles counts can be overriden by a user-definable list of cycle counts. }{\insrsid8934144 This is imported using a command-line }{\b\insrsid8934144\charrsid12409975 \endash z}{\insrsid8934144 switch. The filename must be added immediately after \endash z, with not space.}{\insrsid12409975 \par The}{\insrsid8934144 format of each line in the file is the following:}{\insrsid12409975 \par }{\insrsid8934144 [opcode }{\b\insrsid8934144\charrsid8934144 -}{\insrsid8934144 cycle count[}{\b\insrsid8934144\charrsid8934144 /}{\insrsid8934144 alternative cycle count]][}{\b\insrsid8934144\charrsid8934144 ;}{\insrsid8934144 comment][}{ \b\insrsid8934144\charrsid8934144 #}{\insrsid8934144 comment] \par Opcode and cycle counts are given in hexadecimal with no prefix/suffix, maximum two digits.}{\insrsid12409975 Alternative cycle count is for conditional jumps and autorepeated instructions, see }{\i\insrsid12409975\charrsid12409975 special cases}{ \insrsid12409975 above. Opcodes can be in any order. Missing opcodes will be given cycle count = 0. Comment with }{\b\insrsid12409975\charrsid12409975 ;}{\insrsid12409975 is ignored, comment with }{\b\insrsid12409975\charrsid12409975 #}{ \insrsid12409975 is printed to console when file is read in.}{\insrsid8934144 \par {\listtext\tab}}\pard\plain \s2\ql \li0\ri0\sb465\sa119\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\ls1\ilvl1\outlinelevel1\rin0\lin0\itap0 \b\i\f1\fs28\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid12409975 Known issues \par }\pard\plain \s16\qj \li0\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid12409975 There is }{\insrsid12409975\charrsid6638741 no 8080 support}{\insrsid12409975 in DZ80. \par }{\insrsid6638741 In the import of user definable cycle files, there is }{\insrsid6638741\charrsid6638741 no support for the prefixed Z80 instructions}{\insrsid6638741 .}{\insrsid12409975 \par }{\insrsid6638741 If the }{\b\insrsid6638741\charrsid6638741 -}{\insrsid6638741 suffix has to be used to specify an excluded range for a single instruction, the one-address format cannot be used, i.e. }{\i\insrsid6638741\charrsid6638741 Z address-}{ \insrsid6638741 won't work properly. Use }{\i\insrsid6638741\charrsid6638741 Z address}{\i\insrsid6638741 \_}{\i\insrsid6638741\charrsid6638741 address}{\i\insrsid6638741 \_}{\insrsid6638741 instead. \par {\listtext\tab}}\pard\plain \s2\ql \li0\ri0\sb465\sa119\keepn\nowidctlpar\hyphpar0\nooverflow\faroman\ls1\ilvl1\outlinelevel1\rin0\lin0\itap0 \b\i\f1\fs28\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid12409975 Why in disassembler? \par }\pard\plain \s16\qj \li0\ri0\sa120\nowidctlpar\hyphpar0\nooverflow\faroman\rin0\lin0\itap0 \f37\fs20\lang1033\langfe1051\cgrid\langnp1033\langfenp1051 {\insrsid14363219 Cycle counting is used usually to optimize a certain section of a newly written program. It would be more convenient to have the cycle count in assembler and/or compiler output, no doubt.}{\insrsid12409975 \par }{\insrsid14363219 However, having it in disassembler, the cycle counting gets assembler/compiler independent. Most of assemblers/compilers are closed source, even if some of them are provided free. Support for cycle counting is }{\insrsid2897750 therefore upon to the goodwill of the assembler/compiler author. Also, it is not likely that a common library would fit universally, which makes cycle counting availability accross multiple tools less likely. \par }{\insrsid14363219 That's why. \par }{\insrsid12409975 \par }}d52-3.4.1.orig/cyclefiles/DS80C320.cyc0000664000175000017500000000444710570514410015072 0ustar uweuwe;DS80C320 - 4x ; ;This is a cycle counting file for the d52 disassembler. ; ;GNU General Public License - for details see copying.txt ;(C) 2007 by Jan Waclawek, wek at efton dot sk ; ;Disclaimer: cycle counts in this file may be wrong. Use at your own risk. ;Please correct it if you encounter an error and report to d52 author, Jeff Post. ;Please contribute cycle count files for new '51 derivatives ;or new uses or variations of existing files. ;Manufacturers, please contribute "known good" cycle count files. ; # ----------------------- #| DS80C320 - 4x clock | # ----------------------- # # Note that instruction for external memories access # may have different timing - adjust cycle files # or individual instructions' timing according your HW. # # 00-1 01-3 02-4 03-1 04-1 05-2 06-1 07-1 08-1 09-1 0A-1 0B-1 0C-1 0D-1 0E-1 0F-1 10-4 11-3 12-4 13-1 14-1 15-2 16-1 17-1 18-1 19-1 1A-1 1B-1 1C-1 1D-1 1E-1 1F-1 20-4 21-3 22-4 23-1 24-2 25-2 26-1 27-1 28-1 29-1 2A-1 2B-1 2C-1 2D-1 2E-1 2F-1 30-4 31-3 32-4 33-1 34-2 35-2 36-1 37-1 38-1 39-1 3A-1 3B-1 3C-1 3D-1 3E-1 3F-1 40-3 41-3 42-2 43-3 44-2 45-2 46-1 47-1 48-1 49-1 4A-1 4B-1 4C-1 4D-1 4E-1 4F-1 50-3 51-3 52-2 53-3 54-2 55-2 56-1 57-1 58-1 59-1 5A-1 5B-1 5C-1 5D-1 5E-1 5F-1 60-3 61-3 62-2 63-3 64-2 65-2 66-1 67-1 68-1 69-1 6A-1 6B-1 6C-1 6D-1 6E-1 6F-1 70-3 71-3 72-2 73-3 74-2 75-3 76-2 77-2 78-2 79-2 7A-2 7B-2 7C-2 7D-2 7E-2 7F-2 80-3 81-3 82-2 83-3 84-5 85-3 86-2 87-2 88-2 89-2 8A-2 8B-2 8C-2 8D-2 8E-2 8F-2 90-3 91-3 92-2 93-3 94-2 95-2 96-1 97-1 98-1 99-1 9A-1 9B-1 9C-1 9D-1 9E-1 9F-1 A0-2 A1-3 A2-2 A3-3 A4-5 A6-2 A7-2 A8-2 A9-2 AA-2 AB-2 AC-2 AD-2 AE-2 AF-2 B0-2 B1-3 B2-2 B3-1 B4-4 B5-4 B6-4 B7-4 B8-4 B9-4 BA-4 BB-4 BC-4 BD-4 BE-4 BF-4 C0-2 C1-3 C2-2 C3-1 C4-1 C5-2 C6-1 C7-1 C8-1 C9-1 CA-1 CB-1 CC-1 CD-1 CE-1 CF-1 D0-2 D1-3 D2-2 D3-1 D4-1 D5-4 D6-1 D7-1 D8-3 D9-3 DA-3 DB-3 DC-3 DD-3 DE-3 DF-3 E0-2 ;-9 E1-3 E2-2 ;-9 E3-2 ;-9 E4-1 E5-2 E6-1 E7-1 E8-1 E9-1 EA-1 EB-1 EC-1 ED-1 EE-1 EF-1 F0-2 ;-9 F1-3 F2-2 ;-9 F3-2 ;-9 F4-1 F5-2 F6-1 F7-1 F8-1 F9-1 FA-1 FB-1 FC-1 FD-1 FE-1 FF-1 d52-3.4.1.orig/cyclefiles/DS89C4x0.cyc0000664000175000017500000000442410570514420015206 0ustar uweuwe;DS89C4x0 - 1x ; ;This is a cycle counting file for the d52 disassembler. ; ;GNU General Public License - for details see copying.txt ;(C) 2007 by Jan Waclawek, wek at efton dot sk ; ;Disclaimer: cycle counts in this file may be wrong. Use at your own risk. ;Please correct it if you encounter an error and report to d52 author, Jeff Post. ;Please contribute cycle count files for new '51 derivatives ;or new uses or variations of existing files. ;Manufacturers, please contribute "known good" cycle count files. ; # ----------------------- #| DS89C4x0 - 1x clock | # ----------------------- # # Note that instruction for external memories access # may have different timing - adjust cycle files # or individual instructions' timing according your HW. # # 00-1 01-2 02-3 03-1 04-1 05-2 06-2 07-2 08-1 09-1 0A-1 0B-1 0C-1 0D-1 0E-1 0F-1 10-4 11-2 12-3 13-1 14-1 15-2 16-2 17-2 18-1 19-1 1A-1 1B-1 1C-1 1D-1 1E-1 1F-1 20-4 21-2 22-3 23-1 24-2 25-2 26-2 27-2 28-1 29-1 2A-1 2B-1 2C-1 2D-1 2E-1 2F-1 30-4 31-2 32-3 33-1 34-2 35-2 36-2 37-2 38-2 39-2 3A-2 3B-2 3C-2 3D-2 3E-2 3F-2 40-3 41-2 42-2 43-3 44-2 45-2 46-2 47-2 48-1 49-1 4A-1 4B-1 4C-1 4D-1 4E-1 4F-1 50-3 51-2 52-2 53-3 54-2 55-2 56-2 57-2 58-1 59-1 5A-1 5B-1 5C-1 5D-1 5E-1 5F-1 60-3 61-2 62-2 63-3 64-2 65-2 66-2 67-2 68-1 69-1 6A-1 6B-1 6C-1 6D-1 6E-1 6F-1 70-3 71-2 72-2 73-3 74-2 75-3 76-2 77-2 78-2 79-2 7A-2 7B-2 7C-2 7D-2 7E-2 7F-2 80-3 81-2 82-2 83-3 84-10 85-3 86-2 87-2 88-2 89-2 8A-2 8B-2 8C-2 8D-2 8E-2 8F-2 90-3 91-2 92-2 93-3 94-2 95-2 96-2 97-2 98-1 99-1 9A-1 9B-1 9C-1 9D-1 9E-1 9F-1 A0-2 A1-2 A2-2 A3-1 A4-9 A6-2 A7-2 A8-2 A9-2 AA-2 AB-2 AC-2 AD-2 AE-2 AF-2 B0-2 B1-2 B2-2 B3-1 B4-4 B5-5 B6-5 B7-5 B8-4 B9-4 BA-4 BB-4 BC-4 BD-4 BE-4 BF-4 C0-2 C1-2 C2-2 C3-1 C4-1 C5-3 C6-3 C7-3 C8-2 C9-2 CA-2 CB-2 CC-2 CD-2 CE-2 CF-2 D0-2 D1-2 D2-2 D3-1 D4-2 D5-5 D6-3 D7-3 D8-4 D9-4 DA-4 DB-4 DC-4 DD-4 DE-4 DF-4 E0-2 E1-2 E2-2 E3-2 E4-1 E5-2 E6-2 E7-2 E8-1 E9-1 EA-1 EB-1 EC-1 ED-1 EE-1 EF-1 F0-2 F1-2 F2-2 F3-2 F4-1 F5-2 F6-1 F7-1 F8-1 F9-1 FA-1 FB-1 FC-1 FD-1 FE-1 FF-1 d52-3.4.1.orig/cyclefiles/MSC12xx.cyc0000664000175000017500000000444310570514434015233 0ustar uweuwe;MSC12xx - 4x ; ;This is a cycle counting file for the d52 disassembler. ; ;GNU General Public License - for details see copying.txt ;(C) 2007 by Jan Waclawek, wek at efton dot sk ; ;Disclaimer: cycle counts in this file may be wrong. Use at your own risk. ;Please correct it if you encounter an error and report to d52 author, Jeff Post. ;Please contribute cycle count files for new '51 derivatives ;or new uses or variations of existing files. ;Manufacturers, please contribute "known good" cycle count files. ; # ---------------------- #| MSC12xx - 4x clock | # ---------------------- # # Note that instruction for external memories access # may have different timing - adjust cycle files # or individual instructions' timing according your HW. # # 00-1 01-3 02-4 03-1 04-1 05-2 06-1 07-1 08-1 09-1 0A-1 0B-1 0C-1 0D-1 0E-1 0F-1 10-4 11-3 12-4 13-1 14-1 15-2 16-1 17-1 18-1 19-1 1A-1 1B-1 1C-1 1D-1 1E-1 1F-1 20-4 21-3 22-4 23-1 24-2 25-2 26-1 27-1 28-1 29-1 2A-1 2B-1 2C-1 2D-1 2E-1 2F-1 30-4 31-3 32-4 33-1 34-2 35-2 36-1 37-1 38-1 39-1 3A-1 3B-1 3C-1 3D-1 3E-1 3F-1 40-3 41-3 42-2 43-3 44-2 45-2 46-1 47-1 48-1 49-1 4A-1 4B-1 4C-1 4D-1 4E-1 4F-1 50-3 51-3 52-2 53-3 54-2 55-2 56-1 57-1 58-1 59-1 5A-1 5B-1 5C-1 5D-1 5E-1 5F-1 60-3 61-3 62-2 63-3 64-2 65-2 66-1 67-1 68-1 69-1 6A-1 6B-1 6C-1 6D-1 6E-1 6F-1 70-3 71-3 72-2 73-3 74-2 75-3 76-2 77-2 78-2 79-2 7A-2 7B-2 7C-2 7D-2 7E-2 7F-2 80-3 81-3 82-2 83-3 84-5 85-3 86-2 87-2 88-2 89-2 8A-2 8B-2 8C-2 8D-2 8E-2 8F-2 90-3 91-3 92-2 93-3 94-2 95-2 96-1 97-1 98-1 99-1 9A-1 9B-1 9C-1 9D-1 9E-1 9F-1 A0-2 A1-3 A2-2 A3-3 A4-5 A6-2 A7-2 A8-2 A9-2 AA-2 AB-2 AC-2 AD-2 AE-2 AF-2 B0-2 B1-3 B2-2 B3-1 B4-4 B5-4 B6-4 B7-4 B8-4 B9-4 BA-4 BB-4 BC-4 BD-4 BE-4 BF-4 C0-2 C1-3 C2-2 C3-1 C4-1 C5-2 C6-1 C7-1 C8-1 C9-1 CA-1 CB-1 CC-1 CD-1 CE-1 CF-1 D0-2 D1-3 D2-2 D3-1 D4-1 D5-4 D6-1 D7-1 D8-3 D9-3 DA-3 DB-3 DC-3 DD-3 DE-3 DF-3 E0-2 ;-9 E1-3 E2-2 ;-9 E3-2 ;-9 E4-1 E5-2 E6-1 E7-1 E8-1 E9-1 EA-1 EB-1 EC-1 ED-1 EE-1 EF-1 F0-2 ;-9 F1-3 F2-2 ;-9 F3-2 ;-9 F4-1 F5-2 F6-1 F7-1 F8-1 F9-1 FA-1 FB-1 FC-1 FD-1 FE-1 FF-1 d52-3.4.1.orig/cyclefiles/SiLabs.cyc0000664000175000017500000000450010570514446015240 0ustar uweuwe;SiLabs - 1x ; ;This is a cycle counting file for the d52 disassembler. ; ;GNU General Public License - for details see copying.txt ;(C) 2007 by Jan Waclawek, wek at efton dot sk ; ;Disclaimer: cycle counts in this file may be wrong. Use at your own risk. ;Please correct it if you encounter an error and report to d52 author, Jeff Post. ;Please contribute cycle count files for new '51 derivatives ;or new uses or variations of existing files. ;Manufacturers, please contribute "known good" cycle count files. ; # --------------------- #| SiLabs - 1x clock | # --------------------- #Note that the 50MHz and 100MHz C8051F1xx have a jump cache, # and upon cache miss, up to extra 4 cycles might be added # to each jump (call, ret, interrupt). # # 00-1 01-3 02-4 03-1 04-1 05-2 06-2 07-2 08-1 09-1 0A-1 0B-1 0C-1 0D-1 0E-1 0F-1 10-3/4 11-3 12-4 13-1 14-1 15-2 16-2 17-2 18-1 19-1 1A-1 1B-1 1C-1 1D-1 1E-1 1F-1 20-3/4 21-3 22-5 23-1 24-2 25-2 26-2 27-2 28-1 29-1 2A-1 2B-1 2C-1 2D-1 2E-1 2F-1 30-3/4 31-3 32-5 33-1 34-2 35-2 36-2 37-2 38-1 39-1 3A-1 3B-1 3C-1 3D-1 3E-1 3F-1 40-2/3 41-3 42-2 43-3 44-2 45-2 46-2 47-2 48-1 49-1 4A-1 4B-1 4C-1 4D-1 4E-1 4F-1 50-2/3 51-3 52-2 53-3 54-2 55-2 56-2 57-2 58-1 59-1 5A-1 5B-1 5C-1 5D-1 5E-1 5F-1 60-2/3 61-3 62-2 63-3 64-2 65-2 66-2 67-2 68-1 69-1 6A-1 6B-1 6C-1 6D-1 6E-1 6F-1 70-2/3 71-3 72-2 73-3 74-2 75-3 76-2 77-2 78-2 79-2 7A-2 7B-2 7C-2 7D-2 7E-2 7F-2 80-3 81-3 82-2 83-3 84-8 85-3 86-2 87-2 88-2 89-2 8A-2 8B-2 8C-2 8D-2 8E-2 8F-2 90-3 91-3 92-2 93-3 94-2 95-2 96-2 97-2 98-1 99-1 9A-1 9B-1 9C-1 9D-1 9E-1 9F-1 A0-2 A1-3 A2-2 A3-1 A4-4 A6-2 A7-2 A8-2 A9-2 AA-2 AB-2 AC-2 AD-2 AE-2 AF-2 B0-2 B1-3 B2-2 B3-1 B4-3/4 B5-3/4 B6-4/5 B7-4/5 B8-3/4 B9-3/4 BA-3/4 BB-3/4 BC-3/4 BD-3/4 BE-3/4 BF-3/4 C0-2 C1-3 C2-2 C3-1 C4-1 C5-2 C6-2 C7-2 C8-1 C9-1 CA-1 CB-1 CC-1 CD-1 CE-1 CF-1 D0-2 D1-3 D2-2 D3-1 D4-1 D5-3/4 D6-2 D7-2 D8-2/3 D9-2/3 DA-2/3 DB-2/3 DC-2/3 DD-2/3 DE-2/3 DF-2/3 E0-3 E1-3 E2-3 E3-3 E4-1 E5-2 E6-2 E7-2 E8-1 E9-1 EA-1 EB-1 EC-1 ED-1 EE-1 EF-1 F0-3 F1-3 F2-3 F3-3 F4-1 F5-2 F6-2 F7-2 F8-1 F9-1 FA-1 FB-1 FC-1 FD-1 FE-1 FF-1 d52-3.4.1.orig/cyclefiles/upsd33xx.cyc0000664000175000017500000000456110570621632015567 0ustar uweuwe; uPSD33xx, uPSD34xx - 4x ; ;This is a cycle counting file for the d52 disassembler. ; ;GNU General Public License - for details see copying.txt ;(C) 2007 by Jan Waclawek, wek at efton dot sk ; ;Disclaimer: cycle counts in this file may be wrong. Use at your own risk. ;Please correct it if you encounter an error and report to d52 author, Jeff Post. ;Please contribute cycle count files for new '51 derivatives ;or new uses or variations of existing files. ;Manufacturers, please contribute "known good" cycle count files. ; # -------------------------------- #| uPSD33xx, uPSD34xx - 4x clock | # -------------------------------- #Note that the 4-clocker uPSD have a jump cache, # and upon cache miss, extra cycles might be added # to each jump (call, ret, interrupt). #Other than this, the cycle count set is the same # than in the standard '51. # # 00-1 01-2 02-2 03-1 04-1 05-1 06-1 07-1 08-1 09-1 0A-1 0B-1 0C-1 0D-1 0E-1 0F-1 10-2 11-2 12-2 13-1 14-1 15-1 16-1 17-1 18-1 19-1 1A-1 1B-1 1C-1 1D-1 1E-1 1F-1 20-2 21-2 22-2 23-1 24-1 25-1 26-1 27-1 28-1 29-1 2A-1 2B-1 2C-1 2D-1 2E-1 2F-1 30-2 31-2 32-2 33-1 34-1 35-1 36-1 37-1 38-1 39-1 3A-1 3B-1 3C-1 3D-1 3E-1 3F-1 40-2 41-2 42-1 43-2 44-1 45-1 46-1 47-1 48-1 49-1 4A-1 4B-1 4C-1 4D-1 4E-1 4F-1 50-2 51-2 52-1 53-2 54-1 55-1 56-1 57-1 58-1 59-1 5A-1 5B-1 5C-1 5D-1 5E-1 5F-1 60-2 61-2 62-1 63-2 64-1 65-1 66-1 67-1 68-1 69-1 6A-1 6B-1 6C-1 6D-1 6E-1 6F-1 70-2 71-2 72-2 73-2 74-1 75-2 76-1 77-1 78-1 79-1 7A-1 7B-1 7C-1 7D-1 7E-1 7F-1 80-2 81-2 82-2 83-2 84-4 85-2 86-2 87-2 88-2 89-2 8A-2 8B-2 8C-2 8D-2 8E-2 8F-2 90-2 91-2 92-2 93-2 94-1 95-1 96-1 97-1 98-1 99-1 9A-1 9B-1 9C-1 9D-1 9E-1 9F-1 A0-2 A1-2 A2-1 A3-2 A4-4 A6-2 A7-2 A8-2 A9-2 AA-2 AB-2 AC-2 AD-2 AE-2 AF-2 B0-2 B1-2 B2-1 B3-1 B4-2 B5-2 B6-2 B7-2 B8-2 B9-2 BA-2 BB-2 BC-2 BD-2 BE-2 BF-2 C0-2 C1-2 C2-1 C3-1 C4-1 C5-1 C6-1 C7-1 C8-1 C9-1 CA-1 CB-1 CC-1 CD-1 CE-1 CF-1 D0-2 D1-2 D2-1 D3-1 D4-1 D5-2 D6-1 D7-1 D8-2 D9-2 DA-2 DB-2 DC-2 DD-2 DE-2 DF-2 E0-2 E1-2 E2-2 E3-2 E4-1 E5-1 E6-1 E7-1 E8-1 E9-1 EA-1 EB-1 EC-1 ED-1 EE-1 EF-1 F0-2 F1-2 F2-2 F3-2 F4-1 F5-1 F6-1 F7-1 F8-1 F9-1 FA-1 FB-1 FC-1 FD-1 FE-1 FF-1 d52-3.4.1.orig/cyclefiles/W77e.cyc0000664000175000017500000000444310570514462014620 0ustar uweuwe;W77E5x - 4x ; ;This is a cycle counting file for the d52 disassembler. ; ;GNU General Public License - for details see copying.txt ;(C) 2007 by Jan Waclawek, wek at efton dot sk ; ;Disclaimer: cycle counts in this file may be wrong. Use at your own risk. ;Please correct it if you encounter an error and report to d52 author, Jeff Post. ;Please contribute cycle count files for new '51 derivatives ;or new uses or variations of existing files. ;Manufacturers, please contribute "known good" cycle count files. ; # --------------------- #| W77E5x - 4x clock | # --------------------- # # Note that instruction for external memories access # may have different timing - adjust cycle files # or individual instructions' timing according your HW. # # 00-1 01-3 02-4 03-1 04-1 05-2 06-1 07-1 08-1 09-1 0A-1 0B-1 0C-1 0D-1 0E-1 0F-1 10-4 11-3 12-4 13-1 14-1 15-2 16-1 17-1 18-1 19-1 1A-1 1B-1 1C-1 1D-1 1E-1 1F-1 20-4 21-3 22-2 23-1 24-2 25-2 26-1 27-1 28-1 29-1 2A-1 2B-1 2C-1 2D-1 2E-1 2F-1 30-4 31-3 32-2 33-1 34-2 35-2 36-1 37-1 38-1 39-1 3A-1 3B-1 3C-1 3D-1 3E-1 3F-1 40-3 41-3 42-2 43-3 44-2 45-2 46-1 47-1 48-1 49-1 4A-1 4B-1 4C-1 4D-1 4E-1 4F-1 50-3 51-3 52-2 53-3 54-2 55-2 56-1 57-1 58-1 59-1 5A-1 5B-1 5C-1 5D-1 5E-1 5F-1 60-3 61-3 62-2 63-3 64-2 65-2 66-1 67-1 68-1 69-1 6A-1 6B-1 6C-1 6D-1 6E-1 6F-1 70-3 71-3 72-2 73-2 74-2 75-3 76-2 77-2 78-2 79-2 7A-2 7B-2 7C-2 7D-2 7E-2 7F-2 80-3 81-3 82-2 83-2 84-5 85-3 86-2 87-2 88-2 89-2 8A-2 8B-2 8C-2 8D-2 8E-2 8F-2 90-3 91-3 92-2 93-2 94-2 95-2 96-1 97-1 98-1 99-1 9A-1 9B-1 9C-1 9D-1 9E-1 9F-1 A0-2 A1-3 A2-2 A3-2 A4-5 A6-2 A7-2 A8-2 A9-2 AA-2 AB-2 AC-2 AD-2 AE-2 AF-2 B0-2 B1-3 B2-2 B3-1 B4-4 B5-4 B6-4 B7-4 B8-4 B9-4 BA-4 BB-4 BC-4 BD-4 BE-4 BF-4 C0-2 C1-3 C2-2 C3-1 C4-1 C5-2 C6-1 C7-1 C8-1 C9-1 CA-1 CB-1 CC-1 CD-1 CE-1 CF-1 D0-2 D1-3 D2-2 D3-1 D4-1 D5-4 D6-1 D7-1 D8-3 D9-3 DA-3 DB-3 DC-3 DD-3 DE-3 DF-3 E0-2 ;-9 E1-3 E2-2 ;-9 E3-2 ;-9 E4-1 E5-2 E6-1 E7-1 E8-1 E9-1 EA-1 EB-1 EC-1 ED-1 EE-1 EF-1 F0-2 ;-9 F1-3 F2-2 ;-9 F3-2 ;-9 F4-1 F5-2 F6-1 F7-1 F8-1 F9-1 FA-1 FB-1 FC-1 FD-1 FE-1 FF-1 d52-3.4.1.orig/cyclefiles/z.bin0000664000175000017500000000004710570425176014331 0ustar uweuwe#‰ý"(0 íªíºÝw#ýwUË”ÝË–ýË"þ‰ ü d52-3.4.1.orig/cyclefiles/z.ctl0000664000175000017500000000041010570437336014336 0ustar uweuwe ;Z 2-4*23 ;this won't work for proper counting of djnz, the following construction is needed Z 2*23 Z 3*23 Z 2-4 Z 2-1e Z 7-b- Z 9-b- Z d-d*12 ;this is a similar construction than that for djnz Z 20-ffff Z 22-23*5 Z 24*5 z 22-24 z 26-26- d52-3.4.1.orig/cyclefiles/z.z800000664000175000017500000000277410570437426014214 0ustar uweuwe; ; DZ80 V3.4.0 Z80 Disassembly of z.bin ; 02/25/07 17:59 ; org 0 ; ld b,23h ; 0000 06 23 .# X0002: adc a,c ; 4 ; 0002 89 . ; ; --- Cycle count 0002-0002 = 4 * 35x = 140 ; djnz X0002 ;450 = 13 * 34x + 8 ; 0003 10 fd .} ; ; --- Cycle count 0002-0004 = 590 ; jr X0029 ; 12 ; 0005 18 22 ." ; jr z,X0019 ;^12-; 0007 28 10 (. jr nc,X0015 ; 7-; 0009 30 0a 0. ind ; 16-; 000b ed aa m* ; ; --- Cycle count 0009-000b = 23 - not included to the parent cycle count. ; ; --- Cycle count 0007-000b = 12 - not included to the parent cycle count. ; indr ;373 = 21 * 17x + 16 ; 000d ed ba m: ld (ix+23h),a ; 19 ; 000f dd 77 23 ]w# ld (iy+55h),a ; 19 ; 0012 fd 77 55 }wU X0015: res 2,h ; 8 ; 0015 cb 94 K. res 2,(ix+12h) ; 23 ; 0017 dd cb 12 96 ]K.. set 7,(iy+22h) ; 23 ; 001b fd cb 22 fe }K"~ ; ; --- Cycle count 0002-001e = 1067 ; nop ; 001f 00 . ld c,5 ; 7 ; 0020 0e 05 .. X0022: adc a,c ; 4 ; 0022 89 . dec c ; 4 ; 0023 0d . ; ; --- Cycle count 0022-0023 = 8 * 5x = 40 ; jr nz,X0022 ; 55 = 12 * 4x + 7 ; 0024 20 fc | ; ; --- Cycle count 0022-0024 = 95 ; inc c ; 4-; 0026 0c . ; ; --- Cycle count 0026-0026 = 4 - not included to the parent cycle count. ; ; --- Cycle count 0020-ffff = 102 ; ; Miscellaneous equates ; ; These are addresses referenced in the code but ; which are in the middle of a multibyte instruction ; or are addresses outside the initialized space ; X0029 equ 29h ; end ; d52-3.4.1.orig/d48.c0000644000175000017500000001635210666557322012020 0ustar uweuwe /* * D48 8048/8041 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * d48.c - Main File * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include "d48.h" #include "common.h" #include "d48pass.h" #include "d48table.h" // // Global variables // byte flag41; // 8041 flag int dotpseudo = 0; #include "dispass0.c" #include "dispass3.c" void usage(void) { printf("\nUsage: d48 [options] \n" "Options may be entered Unix style (-d) or DOS style (/b)\n" "\t-1 disassemble 8041 code.\n" "\t-a use ascii macro instead of db/defb for text.\n" "\t-b force .bin extension on input file.\n" "\t-d include address and data in comment field.\n" "\t-h force .hex extension on input file.\n" "\t If neither 'b' nor 'h' is specified, D48 will first search\n" "\t for a .hex file, and if not found, then a .bin file.\n" "\t-n use C style for hexadecimal operands\n" "\t-p put dot '.' at beginning of pseudo ops\n" "\t-s change 'db' and 'dw' to 'defb' and 'defw'.\n" "\t-u output labels, symbols, and mnemonics in upper case.\n" "\nOptions may be entered in a freeform fashion as long " "as a dash (-) or\n" "a slash (/) preceeds any option that preceeds the filename." "\nExamples:\n" "\td48 filename bd\n" "\td48 -d filename b\n" "\td48 /b -d filename\n\n"); exit(GOOD_EXIT); } // // The Main Program // int main(int argc, char *argv[]) { char c, *inp; int count; int line; #ifdef ALPHA printf("\nD48 8048/8041 Disassembler V %d.%d.%d Alpha %d" "\nCopyright (C) 1996-%d by J. L. Post%s", VERSION, MAJORREV, MINORREV, ALPHA, YEAR, licenseText); #else #ifdef BETA printf("\nD48 8048/8041 Disassembler V %d.%d.%d Beta %d" "\nCopyright (C) 1996-%d by J. L. Post%s", VERSION, MAJORREV, MINORREV, BETA, YEAR, licenseText); #else printf("\nD48 8048/8041 Disassembler V %d.%d.%d" "\nCopyright (C) 1996-%d by J. L. Post%s", VERSION, MAJORREV, MINORREV, YEAR, licenseText); #endif #endif if (argc < 2) usage(); /***************************************** allocate memory for program and flags *****************************************/ if (!init_memory()) exit(MEM_ERROR); strcpy(defbstr, "db"); // init define byte and word strings strcpy(defwstr, "dw"); strcpy(ascistr, "db"); // init define ascii string sym_tab = NULL; // no symbols or labels yet lab_tab = NULL; name_tab = NULL; fileflag = EITHERFILE; // assume search for either file type hexflag = FALSE; upperflag = FALSE; flag41 = FALSE; dump = FALSE; ascii_flag = FALSE; /******************************* find filename in command line *******************************/ for (line=1; line 2) // test for options { for (count=1; count
, where mb ; is 0 or 1. ; ; R - Register Specify name for register ; (instead of rb2r5 for example). ; ; S - Symbol Generate a symbol for this value. ; ; T - Text ASCII text (db). ; ; W - Word binary Sixteen bit binary data (dw). ; ; X - Operand name Specify special name for operand. ; ; Y - Operand name Specify special name for operand, suppress EQU generation. ; ; # - Comment Add header comment to output file. ; ; ! - Inline comment Add comment to end of line. ; ; The difference between labels and symbols is that a label refers ; to a referenced address, whereas a symbol may be used for 8 or 16 ; bit immediate data. For some opcodes (eg: mov r2,#xx) only the symbol ; table will be searched. Other opcodes (eg: mov dptr,#) will search ; the label table first and then search the symbol table only if the ; value is not found in the label table. ; ; Values for some control codes may specify ranges, ie: ; ; A 100-11f specifies a table of addresses starting at address ; 0x100 and continuing to address 0x11f. ; ; T 100-120 specifies that addresses 0x100 through (and including) ; address 0x120 contain ascii text data. ; ; Range specifications are allowed for codes A, B, C, I, T, and W, but ; obviously don't apply to codes L, R, S, and X. ; ;--------------------------------------------------------------------------- ; ; labels for interrupt vectors ; L 0 reset L 3 intvec L 7 tcvec ; ; tell D48 to disassemble code at interrupt vector locations ; C 0 ; reset C 3 ; interrupt C 7 ; timer/counter interrupt ; ; end of control file ; d52-3.4.1.orig/d48.h0000644000175000017500000000300110666551145012005 0ustar uweuwe /* * D48 8048/8041 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * d48.h - 8048 disassembler definitions * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _D48_H_ #define _D48_H_ #define CPU_BIG_ENDIAN // 8048 is big endian processor #ifndef _DEFS_H_ #include "defs.h" #endif // option table values: #define OPT_XFER 0x80 // unconditional transfer #define OPT_INVAL 0x08 // invalid opcode #define OPT_EXT 0x04 // extended memory reference #define OPT_PAGE 0x02 // memory ref in current page #define OPT_IMM 0x01 // immediate data #define OPT_NONE 0x00 // single byte, no options // // Prototypes // void usage(void); // // Global variables // extern byte flag41; // 8041 flag #endif // _D48_H_ d52-3.4.1.orig/d48pass.c0000644000175000017500000003761210666553641012711 0ustar uweuwe /* * D48 8048/8041 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * d48pass.c - Disassembly Passes 1 and 2 * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include "d48.h" #include "common.h" #include "d48pass.h" #include "d48table.h" // // Global variables // /* none */ // // Pass one of disassembly // // Examine opcodes for internal references to other memory locations. // If such references are found, flag the referenced location so that // a label can be generated in the output file during pass two. // void pass1(void) { int i, j, pc, mbank; byte k; int mask; printf("\rPass 1"); pc = mbank = 0; mask = (int) (PF_SPLIT | PF_MB0 | PF_MB1 | PF_FORCE); for (i=0; i PMEMSIZE - 1)) i++; // ignore un-initialized data // ignore if last byte in address space // since second byte of opcode can't be // within the allowed address space else if (!(pgmflags[i] & (PF_ADRS | PF_WORD | PF_BYTE | PF_ASCII))) { // if code... k = pgmmem[i]; // get stored opcode if (!flag41) { if (k == 0xe5) mbank = 0; // modify if select bank code else if (k == 0xf5) mbank = 1; } j = optbl[k] & 0xe; // get flags byte if (j == OPT_PAGE) // if memory reference in current page { pc = i & 0xf00; // get current page pc = pc | (pgmmem[i + 1] & 0xff); // add address from opcode pgmflags[pc] = (pgmflags[pc] & ~mask) | PF_REF; // flag reference } if (j == OPT_EXT) /* if extended memory reference */ { pc = (k & 0xe0) << 3; // extract page number pc = pc | (pgmmem[i + 1] & 0xff); // add address from opcode if (mbank) pc = pc | 0x800; if (pc < PMEMSIZE) // flag reference pgmflags[pc] = (pgmflags[pc] & ~mask) | PF_REF; if (!flag41) mbank = (i < 2048) ? 0 : 1; } i = i + bctbl[k]; // update location pointer } else // not executable code i++; if ((!flag41) && (i == 2048)) mbank = 1; // passing into upper bank } printf("\rPass 1 - Reference search complete"); } // End of Pass 1 // // Pass two of disassembly // // Rescan data array and generate output file. Generate label if // location flagged as referenced by some other opcode. If un-initialized // data is encountered, ignore it but set skip flag so that an ORG // statement can be generated when the next initialized data is found. // void pass2(void) { char *cptr; int i, j, k, skip, mbank, year; int q, temp; time_t tp; j = -1; k = 0; mbank = 0; dump = 0; byte_cnt = 0; asc_cnt = 0; newline = FALSE; skip = TRUE; printf("\nPass 2"); if ((fp = fopen(dst, "w")) == NULL) { printf("\n* Can't open file %s *\n", dst); exit(FILE_ERROR); } i = flag41 ? 8041 : 8048; fprintf(fp, ";\n; D48 V%d.%d.%d %d Disassembly of %s", VERSION, MAJORREV, MINORREV, i, src); time(&tp); // get current time date_time = localtime(&tp); // convert to hr/min/day etc year = date_time->tm_year + 1900; fprintf(fp, "\n; %d/%02d/%02d %02d:%02d", year, date_time->tm_mon + 1, date_time->tm_mday, date_time->tm_hour, date_time->tm_min); if (ascii_flag) // if user specified A on command line... { if (upperflag) { fprintf(fp, "\n;\nASCII\tMACRO\tx"); // generate macro for text fprintf(fp, "\n\t%s\t'#x#'", defbstr); fprintf(fp, "\n\tENDM"); strcpy(ascistr, "ASCII"); } else { fprintf(fp, "\n;\nascii\tmacro\tx"); // generate macro for text fprintf(fp, "\n\t%s\t'#x#'", defbstr); fprintf(fp, "\n\tendm"); strcpy(ascistr, "ascii"); } } // // Generate output file // for (i=0; i= ASCLIMIT) dump_ascii(i + 1); } else // else treat it as binary data { pgmflags[i] |= PF_BYTE; if (asc_cnt) // dump any accumulated ascii dump_ascii(i); byte_data[byte_cnt] = pgmmem[i]; // add data to buffer byte_cnt++; } break; case PF_WORD: // if word data... if (byte_cnt) // dump any binary or ascii in buffers dump_bytes(i); if (asc_cnt) dump_ascii(i); if (skip) // insert ORG statement { if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } chk_label(i); // add label if referenced q = ((int) pgmmem[i] & 0xff) << 8; // get word value temp = pgmmem[i + 1] & 0xff; q |= temp; fprintf(fp, "%s\t", defwstr); if (pgmflags[i] & PF_NAME) cptr = find_entry(i, name_count, name_val_index); else cptr = find_entry(q, symbol_count, sym_val_index); // see if symbol exists if (cptr == NULL) // if not, do hex value puthex(q); else fprintf(fp, "%s", cptr); // else output symbol if (hexflag) // add comment field { fprintf(fp, "\t\t; %04x - %02x %02x %c%c", i, pgmmem[i] & 0xff, pgmmem[i + 1] & 0xff, ascii(pgmmem[i]) & 0xff, ascii(pgmmem[i + 1] & 0xff)); } if (pgmflags[i] & PF_ICMT) output_icomment(i); i++; if (pgmflags[i + 2] != PF_ADRS && pgmflags[i + 2] != PF_WORD) { fprintf(fp, "\n;"); newline = TRUE; } break; case PF_ADRS: // if address data... if (byte_cnt) // output any pending binary or dump_bytes(i); // ascii data from buffers if (asc_cnt) dump_ascii(i); if (skip) // insert ORG statement { if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } chk_label(i); // add label if referenced q = ((int) pgmmem[i]) << 8; // get address value temp = pgmmem[i + 1] & 0xff; q |= temp; fprintf(fp, "%s\t", defwstr); cptr = find_entry(q, label_count, lab_val_index); // see if label exists if (cptr == NULL) // if not, output hex { cptr = find_entry(q, symbol_count, sym_val_index); if (cptr == NULL) { if (upperflag) fprintf(fp, "X%04X", q); else fprintf(fp, "X%04x", q); } else fprintf(fp, "%s", cptr); } else fprintf(fp, "%s", cptr); // else output label text if (hexflag) // do comment field { fprintf(fp, "\t\t; %04x %02x %02x %c%c", i, pgmmem[i], pgmmem[i + 1], ascii(pgmmem[i]), ascii(pgmmem[i + 1])); } if (pgmflags[i] & PF_ICMT) output_icomment(i); i++; if (pgmflags[i + 2] != PF_ADRS) { fprintf(fp, "\n;"); newline = TRUE; } break; default: // default = binary data... if (asc_cnt) // output any pending ascii data dump_ascii(i); if (skip) // insert ORG statement { if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } byte_data[byte_cnt] = pgmmem[i]; // add data to buffer byte_cnt++; if (byte_cnt >= BYTELIMIT) // if end of buffer... dump_bytes(i + 1); // dump accumulated data } i++; // next program location if (!(pgmflags[i] & PF_NOINIT) && (pgmflags[i] & PF_ASCII)) { // if next byte is flagged as if (!is_ascii(pgmmem[i])) // ascii, but is not... pgmflags[i] |= PF_BYTE; // then flag it as binary } } // // If previous data was an unconditional transfer, AND current // location is not referenced by some other opcode, AND current // byte is 0 or 0FFH, then treat this byte as un-initialized data. // else if ((j & OPT_XFER) && (!(pgmflags[i] & PF_REF)) && ((!pgmmem[i]) || (pgmmem[i] == NO_DATA)) && !(pgmflags[i] & PF_FORCE)) { if (byte_cnt) // since we're going to skip some dump_bytes(i); // data, output any pending ascii if (asc_cnt) // or binary data remaining in buffers dump_ascii(i); if (dump) // if ascii or binary output was done, { // stick in a newline fprintf(fp, "\n;"); dump = 0; newline = TRUE; } pgmflags[i] = PF_NOINIT;// flag as uninitialized data i++; skip = TRUE; byte_cnt = 0; } // // If previous opcode was 0 or 0FFH, AND current location is not // referenced but is initialized, AND current opcode is 0 or 0ffh, // un-initialize it. // else if (((k == 0) || (k == 0xff)) && (!(pgmflags[i] & PF_REF)) && ((!pgmmem[i]) || (pgmmem[i] == 0xff)) && !(pgmflags[i] & PF_NOINIT) && !(pgmflags[i] & PF_FORCE)) { pgmflags[i] = PF_NOINIT; // flag as uninitialized data i++; skip = TRUE; j = -1; } else // IT'S EXECUTABLE CODE! { pgmflags[i] &= ~PF_NOINIT; // clear for label search in pass 3 if (byte_cnt) // if any ascii or binary data remains dump_bytes(i); // in the buffers, output them now if (asc_cnt) dump_ascii(i); if (dump) { fprintf(fp, "\n;"); dump = 0; newline = TRUE; } byte_cnt = 0; if (cycleflag) // cycle count summary cycle_end(i); if (skip) // insert ORG statement { if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } k = pgmmem[i] & 0xff; // get opcode offset into table if ((!flag41) && (k == 0xe5)) mbank = 0; // set memory bank if ((!flag41) && (k == 0xf5)) mbank = 1; j = optbl[k]; if ((j & OPT_INVAL) && !newline) { fprintf(fp, "\n;"); newline = TRUE; } chk_ref(i); // add label if referenced kcnt = 8; doopcode(mnemtbl[k].mnem); // output opcode // // Generate operands // if (j == OPT_INVAL) // if invalid opcode puthex(k); // put hex defb in file else if (j == OPT_IMM) // if immediate data { if (pgmflags[i + 1] & PF_NAME) cptr = find_entry(i + 1, name_count, name_val_index); else cptr = find_entry(pgmmem[i + 1], symbol_count, sym_val_index); if (cptr == NULL) puthex(pgmmem[i + 1] & 0xff); else kcnt += fprintf(fp, "%s", cptr); splitcheck(i + 1); // test for split ref } else if ((j & 0xe) == OPT_PAGE) // if page address { q = (i & 0xff00) | (pgmmem[i + 1] & 0xff); cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) // put address { if (upperflag) kcnt += fprintf(fp, "X%04X", q); else kcnt += fprintf(fp, "X%04x", q); } else kcnt += fprintf(fp, "%s", cptr); splitcheck(i + 1); } else if ((j & 0xe) == OPT_EXT) // if extended address { q = ((k & 0xe0) << 3) | (pgmmem[i + 1] & 0xff); if (!flag41 && mbank) q |= 0x800; cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (upperflag) kcnt += fprintf(fp, "X%04X", q); else kcnt += fprintf(fp, "X%04x", q); } else kcnt += fprintf(fp, "%s", cptr); if (!flag41) mbank = (i < 2048) ? 0 : 1; splitcheck(i + 1); } if (cycleflag) // do cycle counting { while (kcnt < TSTOP) { fprintf(fp, "\t"); kcnt = (kcnt + 8) & 0x78; } cycle_in(i, i + bctbl[k], cycles[pgmmem[i] & 0xff], cycles2[pgmmem[i] & 0xff]); } if (hexflag) // do comment field { while (kcnt < TSTOP) { putc('\t', fp); kcnt = (kcnt + 8) & 0x78; } fprintf(fp,"; %04x - %02x", i, pgmmem[i] & 0xff); if (bctbl[k] > 1) fprintf(fp, " %02x", pgmmem[i + 1] & 0xff); fprintf(fp, "\t%c", ascii(pgmmem[i])); if (bctbl[k] > 1) fprintf(fp, "%c", ascii(pgmmem[i + 1])); } if (pgmflags[i] & PF_ICMT) output_icomment(i); newline = FALSE; if ((j & OPT_XFER) | (j == OPT_INVAL)) { // if unconditional transfer or fprintf(fp, "\n;"); // invalid code, add a newline newline = TRUE; } i += bctbl[k]; // update location counter } if ((!flag41) && (i == 2048)) mbank = 1; // passing into upper bank } if (cycleflag) // any remaining cycle count summary cycle_end(PMEMSIZE + 1); // specifying a number above any possible // maximum address makes cycle_end to emit all // remaining sums (i would probably suffice, too (?)) if (byte_cnt) // if any remaining ascii or binary, dump_bytes(i); // output it now if (asc_cnt) dump_ascii(i); printf("\rPass 2 - Source generation complete"); } // end of d48pass.c d52-3.4.1.orig/d48pass.h0000644000175000017500000000214710666551264012710 0ustar uweuwe /* * D48 8048/8041 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * d48pass.h - Disassembly passes 1 and 2 * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _D48PASS_H_ #define _D48PASS_H_ // // Prototypes // extern void pass1(void); extern void pass2(void); // // Global variables // /* none */ #endif // _D48PASS_H_ d52-3.4.1.orig/d48table.c0000644000175000017500000003614410666553621013027 0ustar uweuwe /* * D48 8048/8041 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * d48table.c - 8048 Disassembly Tables * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include "d48.h" /* flags entry in opcode table: 0 = single byte opcode, no options 1 = double byte, immediate data 2 = double byte, current page address (djnz, jnz, etc) 4 = double byte, extended address (jmp and call) 8 = single byte, invalid opcode (will become DB in output) if flags + 80H, is unconditional transfer code (JMP, RET, etc) */ byte optbl[256] = { 0x00, 0x00, 0x00, 0x01, // 00 - 03 0x85, 0x00, 0x00, 0x00, // 04 - 07 0x00, 0x00, 0x00, 0x00, // 08 - 0b 0x00, 0x00, 0x00, 0x00, // 0c - 0f 0x00, 0x00, 0x02, 0x01, // 10 - 13 0x05, 0x00, 0x02, 0x00, // 14 - 17 0x00, 0x00, 0x00, 0x00, // 18 - 1b 0x00, 0x00, 0x00, 0x00, // 1c - 1f 0x00, 0x00, 0x04, 0x01, // 20 - 23 0x85, 0x00, 0x02, 0x00, // 24 - 27 0x00, 0x00, 0x00, 0x00, // 28 - 2b 0x00, 0x00, 0x00, 0x00, // 2c - 2f 0x00, 0x00, 0x02, 0x04, // 30 - 33 0x05, 0x00, 0x02, 0x00, // 34 - 37 0x04, 0x00, 0x00, 0x04, // 38 - 3b 0x00, 0x00, 0x00, 0x00, // 3c - 3f 0x00, 0x00, 0x00, 0x01, // 40 - 43 0x85, 0x00, 0x02, 0x00, // 44 - 47 0x00, 0x00, 0x00, 0x00, // 48 - 4b 0x00, 0x00, 0x00, 0x00, // 4c - 4f 0x00, 0x00, 0x02, 0x01, // 50 - 53 0x05, 0x00, 0x02, 0x00, // 54 - 57 0x00, 0x00, 0x00, 0x00, // 58 - 5b 0x00, 0x00, 0x00, 0x00, // 5c - 5f 0x00, 0x00, 0x00, 0x04, // 60 - 63 0x85, 0x00, 0x04, 0x00, // 64 - 67 0x00, 0x00, 0x00, 0x00, // 68 - 6b 0x00, 0x00, 0x00, 0x00, // 6c - 6f 0x00, 0x00, 0x02, 0x04, // 70 - 73 0x05, 0x00, 0x02, 0x00, // 74 - 77 0x00, 0x00, 0x00, 0x00, // 78 - 7b 0x00, 0x00, 0x00, 0x00, // 7c - 7f 0x00, 0x00, 0x04, 0x80, // 80 - 83 0x85, 0x00, 0x02, 0x04, // 84 - 87 0x01, 0x01, 0x01, 0x04, // 88 - 8b 0x00, 0x00, 0x00, 0x00, // 8c - 8f 0x00, 0x00, 0x02, 0x80, // 90 - 93 0x05, 0x00, 0x02, 0x00, // 94 - 97 0x01, 0x01, 0x01, 0x04, // 98 - 9b 0x00, 0x00, 0x00, 0x00, // 9c - 9f 0x00, 0x00, 0x04, 0x00, // a0 - a3 0x85, 0x00, 0x04, 0x00, // a4 - a7 0x00, 0x00, 0x00, 0x00, // a8 - ab 0x00, 0x00, 0x00, 0x00, // ac - af 0x01, 0x01, 0x02, 0x80, // b0 - b3 0x05, 0x00, 0x02, 0x04, // b4 - b7 0x01, 0x01, 0x01, 0x01, // b8 - bb 0x01, 0x01, 0x01, 0x01, // bc - bf 0x04, 0x04, 0x04, 0x04, // c0 - c3 0x85, 0x00, 0x02, 0x00, // c4 - c7 0x00, 0x00, 0x00, 0x00, // c8 - cb 0x00, 0x00, 0x00, 0x00, // cc - cf 0x00, 0x00, 0x02, 0x01, // d0 - d3 0x05, 0x00, 0x04, 0x00, // d4 - d7 0x00, 0x00, 0x00, 0x00, // d8 - db 0x00, 0x00, 0x00, 0x00, // dc - df 0x04, 0x04, 0x04, 0x00, // e0 - e3 0x85, 0x00, 0x02, 0x00, // e4 - e7 0x02, 0x02, 0x02, 0x02, // e8 - eb 0x02, 0x02, 0x02, 0x02, // ec - ef 0x00, 0x00, 0x02, 0x04, // f0 - f3 0x05, 0x00, 0x02, 0x00, // f4 - f7 0x00, 0x00, 0x00, 0x00, // f8 - fb 0x00, 0x00, 0x00, 0x00 // fc - ff }; byte bctbl[256] = { 1, 1, 1, 2, 2, 1, 1, 1, // 00 - 07 1, 1, 1, 1, 1, 1, 1, 1, // 08 - 0f 1, 1, 2, 2, 2, 1, 2, 1, // 10 - 17 1, 1, 1, 1, 1, 1, 1, 1, // 18 - 1f 1, 1, 1, 2, 2, 1, 2, 1, // 20 - 27 1, 1, 1, 1, 1, 1, 1, 1, // 28 - 2f 1, 1, 2, 1, 2, 1, 2, 1, // 30 - 37 1, 1, 1, 1, 1, 1, 1, 1, // 38 - 3f 1, 1, 1, 2, 2, 1, 2, 1, // 40 - 47 1, 1, 1, 1, 1, 1, 1, 1, // 48 - 4f 1, 1, 2, 2, 2, 1, 2, 1, // 50 - 57 1, 1, 1, 1, 1, 1, 1, 1, // 58 - 5f 1, 1, 1, 1, 2, 1, 1, 1, // 60 - 67 1, 1, 1, 1, 1, 1, 1, 1, // 68 - 6f 1, 1, 2, 1, 2, 1, 2, 1, // 70 - 77 1, 1, 1, 1, 1, 1, 1, 1, // 78 - 7f 1, 1, 1, 1, 2, 1, 2, 1, // 80 - 87 2, 2, 2, 1, 1, 1, 1, 1, // 88 - 8f 1, 1, 2, 1, 2, 1, 2, 1, // 90 - 97 2, 2, 2, 1, 1, 1, 1, 1, // 98 - 9f 1, 1, 1, 1, 2, 1, 1, 1, // a0 - a7 1, 1, 1, 1, 1, 1, 1, 1, // a8 - af 2, 2, 2, 1, 2, 1, 2, 1, // b0 - b7 2, 2, 2, 2, 2, 2, 2, 2, // b8 - bf 1, 1, 1, 1, 2, 1, 2, 1, // c0 - c7 1, 1, 1, 1, 1, 1, 1, 1, // c8 - cf 1, 1, 2, 2, 2, 1, 1, 1, // d0 - d7 1, 1, 1, 1, 1, 1, 1, 1, // d8 - df 1, 1, 1, 1, 2, 1, 2, 1, // e0 - e7 2, 2, 2, 2, 2, 2, 2, 2, // e8 - ef 1, 1, 2, 1, 2, 1, 2, 1, // f0 - f7 1, 1, 1, 1, 1, 1, 1, 1 // f8 - ff }; struct mnementry mnemtbl[256] = { {"nop"}, {"idl"}, // 00 - 01 {"outl bus,a"}, {"add a,#"}, // 02 - 03 {"jmp "}, {"en i"}, // 04 - 05 {""}, {"dec a"}, // 06 - 07 {"ins a,bus"}, {"in a,p1"}, // 08 - 09 {"in a,p2"}, {""}, // 0a - 0b {"movd a,p4"}, {"movd a,p5"}, // 0c - 0d {"movd a,p6"}, {"movd a,p7"}, // 0e - 0f {"inc @r0"}, {"inc @r1"}, // 10 - 11 {"jb0 "}, {"addc a,#"}, // 12 - 13 {"call "}, {"dis i"}, // 14 - 15 {"jtf "}, {"inc a"}, // 16 - 17 {"inc r0"}, {"inc r1"}, // 18 - 19 {"inc r2"}, {"inc r3"}, // 1a - 1b {"inc r4"}, {"inc r5"}, // 1c - 1d {"inc r6"}, {"inc r7"}, // 1e - 1f {"xch a,@r0"}, {"xch a,@r1"}, // 20 - 21 {""}, {"mov a,#"}, // 22 - 23 {"jmp "}, {"en tcnti"}, // 24 - 25 {"jnt0 "}, {"clr a"}, // 26 - 27 {"xch a,r0"}, {"xch a,r1"}, // 28 - 29 {"xch a,r2"}, {"xch a,r3"}, // 2a - 2b {"xch a,r4"}, {"xch a,r5"}, // 2c - 2d {"xch a,r6"}, {"xch a,r7"}, // 2e - 2f {"xchd a,@r0"}, {"xchd a,@r1"}, // 30 - 31 {"jb1 "}, {""}, // 32 - 33 {"call "}, {"dis tcnti"}, // 34 - 35 {"jt0 "}, {"cpl a"}, // 36 - 37 {""}, {"outl p1,a"}, // 38 - 39 {"outl p2,a"}, {""}, // 3a - 3b {"movd p4,a"}, {"movd p5,a"}, // 3c - 3d {"movd p6,a"}, {"movd p7,a"}, // 3e - 3f {"orl a,@r0"}, {"orl a,@r1"}, // 40 - 41 {"mov a,t"}, {"orl a,#"}, // 42 - 43 {"jmp "}, {"strt cnt"}, // 44 - 45 {"jnt1 "}, {"swap a"}, // 46 - 47 {"orl a,r0"}, {"orl a,r1"}, // 48 - 49 {"orl a,r2"}, {"orl a,r3"}, // 4a - 4b {"orl a,r4"}, {"orl a,r5"}, // 4c - 4d {"orl a,r6"}, {"orl a,r7"}, // 4e - 4f {"anl a,@r0"}, {"anl a,@r1"}, // 50 - 51 {"jb2 "}, {"anl a,#"}, // 52 - 53 {"call "}, {"strt t"}, // 54 - 55 {"jt1 "}, {"da a"}, // 56 - 57 {"anl a,r0"}, {"anl a,r1"}, // 58 - 59 {"anl a,r2"}, {"anl a,r3"}, // 5a - 5b {"anl a,r4"}, {"anl a,r5"}, // 5c - 5d {"anl a,r6"}, {"anl a,r7"}, // 5e - 5f {"add a,@r0"}, {"add a,@r1"}, // 60 - 61 {"mov t,a"}, {""}, // 62 - 63 {"jmp "}, {"stop tcnt"}, // 64 - 65 {""}, {"rrc a"}, // 66 - 67 {"add a,r0"}, {"add a,r1"}, // 68 - 69 {"add a,r2"}, {"add a,r3"}, // 6a - 6b {"add a,r4"}, {"add a,r5"}, // 6c - 6d {"add a,r6"}, {"add a,r7"}, // 6e - 6f {"addc a,@r0"}, {"addc a,@r1"}, // 70 - 71 {"jb3 "}, {""}, // 72 - 73 {"call "}, {"ent0 clk"}, // 74 - 75 {"jf1 "}, {"rr a"}, // 76 - 77 {"addc a,r0"}, {"addc a,r1"}, // 78 - 79 {"addc a,r2"}, {"addc a,r3"}, // 7a - 7b {"addc a,r4"}, {"addc a,r5"}, // 7c - 7d {"addc a,r6"}, {"addc a,r7"}, // 7e - 7f {"movx a,@r0"}, {"movx a,@r1"}, // 80 - 81 {""}, {"ret"}, // 82 - 83 {"jmp "}, {"clr f0"}, // 84 - 85 {"jni "}, {""}, // 86 - 87 {"orl bus,#"}, {"orl p1,#"}, // 88 - 89 {"orl p2,#"}, {""}, // 8a - 8b {"orld p4,a"}, {"orld p5,a"}, // 8c - 8d {"orld p6,a"}, {"orld p7,a"}, // 8e - 8f {"movx @r0,a"}, {"movx @r1,a"}, // 90 - 91 {"jb4 "}, {"retr"}, // 92 - 93 {"call "}, {"cpl f0"}, // 94 - 95 {"jnz "}, {"clr c"}, // 96 - 97 {"anl bus,#"}, {"anl p1,#"}, // 98 - 99 {"anl p2,#"}, {""}, // 9a - 9b {"anld p4,a"}, {"anld p5,a"}, // 9c - 9d {"anld p6,a"}, {"anld p7,a"}, // 9e - 9f {"mov @r0,a"}, {"mov @r1,a"}, // a0 - a1 {""}, {"movp a,@a"}, // a2 - a3 {"jmp "}, {"clr f1"}, // a4 - a5 {""}, {"cpl c"}, // a6 - a7 {"mov r0,a"}, {"mov r1,a"}, // a8 - a9 {"mov r2,a"}, {"mov r3,a"}, // aa - ab {"mov r4,a"}, {"mov r5,a"}, // ac - ad {"mov r6,a"}, {"mov r7,a"}, // ae - af {"mov @r0,#"}, {"mov @r1,#"}, // b0 - b1 {"jb5 "}, {"jmpp @a"}, // b2 - b3 {"call "}, {"cpl f1"}, // b4 - b5 {"jf0 "}, {""}, // b6 - b7 {"mov r0,#"}, {"mov r1,#"}, // b8 - b9 {"mov r2,#"}, {"mov r3,#"}, // ba - bb {"mov r4,#"}, {"mov r5,#"}, // bc - bd {"mov r6,#"}, {"mov r7,#"}, // be - bf {""}, {""}, // c0 - c1 {""}, {""}, // c2 - c3 {"jmp "}, {"sel rb0"}, // c4 - c5 {"jz "}, {"mov a,psw"}, // c6 - c7 {"dec r0"}, {"dec r1"}, // c8 - c9 {"dec r2"}, {"dec r3"}, // ca - cb {"dec r4"}, {"dec r5"}, // cc - cd {"dec r6"}, {"dec r7"}, // ce - cf {"xrl a,@r0"}, {"xrl a,@r1"}, // d0 - d1 {"jb6 "}, {"xrl a,#"}, // d2 - d3 {"call "}, {"sel rb1"}, // d4 - d5 {""}, {"mov psw,a"}, // d6 - d7 {"xrl a,r0"}, {"xrl a,r1"}, // d8 - d9 {"xrl a,r2"}, {"xrl a,r3"}, // da - db {"xrl a,r4"}, {"xrl a,r5"}, // dc - dd {"xrl a,r6"}, {"xrl a,r7"}, // de - df {""}, {""}, // e0 - e1 {""}, {"movp3 a,@a"}, // e2 - e3 {"jmp "}, {"sel mb0"}, // e4 - e5 {"jnc "}, {"rl a"}, // e6 - e7 {"djnz r0,"}, {"djnz r1,"}, // e8 - e9 {"djnz r2,"}, {"djnz r3,"}, // ea - eb {"djnz r4,"}, {"djnz r5,"}, // ec - ed {"djnz r6,"}, {"djnz r7,"}, // ee - ef {"mov a,@r0"}, {"mov a,@r1"}, // f0 - f1 {"jb7 "}, {""}, // f2 - f3 {"call "}, {"sel mb1"}, // f4 - f5 {"jc "}, {"rlc a"}, // f6 - f7 {"mov a,r0"}, {"mov a,r1"}, // f8 - f9 {"mov a,r2"}, {"mov a,r3"}, // fa - fb {"mov a,r4"}, {"mov a,r5"}, // fc - fd {"mov a,r6"}, {"mov a,r7"} // fe - ff }; // Register names struct sfrentry rbname[] = { {"rb0r0"}, {"rb0r1"}, {"rb0r2"}, {"rb0r3"}, {"rb0r4"}, {"rb0r5"}, {"rb0r6"}, {"rb0r7"}, {"rb1r0"}, {"rb1r1"}, {"rb1r2"}, {"rb1r3"}, {"rb1r4"}, {"rb1r5"}, {"rb1r6"}, {"rb1r7"}, } ; // Default cycles for standard 8048 // No cycle count for unimplemented opcodes: // 06, 0b, 22, 33, // 38, 3b, 63, 66, // 73, 82, 87, 8b, // 9b, a2, a6, b7, // c0, c1, c2, c3, // d6, e0, e1, e2, // f3 unsigned char cycles[256] = { 1,1,2,2, 2,1,0,1, 2,2,2,0, 2,2,2,2, // 00-0f 1,1,2,2, 2,1,2,1, 1,1,1,1, 1,1,1,1, // 10-1f 1,1,0,2, 2,1,2,1, 1,1,1,1, 1,1,1,1, // 20-2f 1,1,2,0, 2,1,2,1, 0,2,2,0, 2,2,2,2, // 30-3f 1,1,1,2, 2,1,2,1, 1,1,1,1, 1,1,1,1, // 40-4f 1,1,2,2, 2,1,2,1, 1,1,1,1, 1,1,1,1, // 50-5f 1,1,1,0, 2,1,0,1, 1,1,1,1, 1,1,1,1, // 60-6f 1,1,2,0, 2,1,2,1, 1,1,1,1, 1,1,1,1, // 70-7f 2,2,0,2, 2,1,2,0, 2,2,2,0, 2,2,2,2, // 80-8f 2,2,2,2, 2,1,2,1, 2,2,2,0, 2,2,2,2, // 90-9f 1,1,0,2, 2,1,0,1, 1,1,1,1, 1,1,1,1, // a0-af 2,2,2,2, 2,1,2,0, 2,2,2,2, 2,2,2,2, // b0-bf 0,0,0,0, 2,1,2,1, 1,1,1,1, 1,1,1,1, // c0-cf 1,1,2,2, 2,1,0,1, 1,1,1,1, 1,1,1,1, // d0-df 0,0,0,2, 2,1,2,1, 2,2,2,2, 2,2,2,2, // e0-ef 1,1,2,0, 2,1,2,1, 1,1,1,1, 1,1,1,1 // f0-ff }; // by default identical to cycles unsigned char cycles2[256] = { 1,1,2,2, 2,1,0,1, 2,2,2,0, 2,2,2,2, // 00-0f 1,1,2,2, 2,1,2,1, 1,1,1,1, 1,1,1,1, // 10-1f 1,1,0,2, 2,1,2,1, 1,1,1,1, 1,1,1,1, // 20-2f 1,1,2,0, 2,1,2,1, 0,2,2,0, 2,2,2,2, // 30-3f 1,1,1,2, 2,1,2,1, 1,1,1,1, 1,1,1,1, // 40-4f 1,1,2,2, 2,1,2,1, 1,1,1,1, 1,1,1,1, // 50-5f 1,1,1,0, 2,1,0,1, 1,1,1,1, 1,1,1,1, // 60-6f 1,1,2,0, 2,1,2,1, 1,1,1,1, 1,1,1,1, // 70-7f 2,2,0,2, 2,1,2,0, 2,2,2,0, 2,2,2,2, // 80-8f 2,2,2,2, 2,1,2,1, 2,2,2,0, 2,2,2,2, // 90-9f 1,1,0,2, 2,1,0,1, 1,1,1,1, 1,1,1,1, // a0-af 2,2,2,2, 2,1,2,0, 2,2,2,2, 2,2,2,2, // b0-bf 0,0,0,0, 2,1,2,1, 1,1,1,1, 1,1,1,1, // c0-cf 1,1,2,2, 2,1,0,1, 1,1,1,1, 1,1,1,1, // d0-df 0,0,0,2, 2,1,2,1, 2,2,2,2, 2,2,2,2, // e0-ef 1,1,2,0, 2,1,2,1, 1,1,1,1, 1,1,1,1 // f0-ff }; // end of d48table.c d52-3.4.1.orig/d48table.h0000644000175000017500000000214510666551350013023 0ustar uweuwe /* * D48 8048/8041 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _D48TABLE_H_ #define _D48TABLE_H_ // // Global variables // extern byte optbl[256]; extern byte bctbl[256]; extern struct mnementry mnemtbl[256]; extern struct sfrentry rbname[]; #endif // _D48TABLE_H_ d52-3.4.1.orig/d52.c0000644000175000017500000002013310666553574012010 0ustar uweuwe /* * D52 8052 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * d52.c - Main File * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include "d52.h" #include "common.h" #include "analyze.h" #include "d52pass1.h" #include "d52pass2.h" #include "d52table.h" // // Global variables // int incflag; // include file flag int keilflag; // Keil A51 compatibility int dotpseudo = 0; byte dirregs[128]; // access flags for dir reg byte sfrflags[128]; // SFR name change flags byte sbflags[128]; // SFR bit name change flags byte mbflags[128]; // bit adrs mem name chg flgs #include "dispass0.c" #include "dispass3.c" void usage(void) { printf("\nUsage: d52 [options] \n" "Options may be entered Unix style (-d) or DOS style (/b)\n" "\t-a use ascii macro instead of db/defb for text.\n" "\t-b disassemble file with .bin extension.\n" "\t-d include address and data in the comment field.\n" "\t-h disassemble file with .hex extension.\n" "\t If neither 'b' nor 'h' is specified, D52 will first search\n" "\t for a .hex file, and if not found, then a .bin file\n" "\t-i put statement in output file to include 'sfr52.inc'.\n" "\t-k disassemble for Keil A51 (obsolete).\n" "\t-n use C style for hexadecimal operands\n" "\t-p put dot '.' at beginning of pseudo ops\n" "\t-s use 'defb' and 'defw' instead of 'db' and 'dw' for binary data.\n" "\t-t trace and analyze code before disassembly.\n" "\t (-t will overwrite any existing ctl file for the 8052 file\n" "\t being disassembled.)\n" "\t-u output labels, symbols, and mnemonics in upper case.\n" "\t-x add a hexadecimal offset to file addresses.\n" "\t-z[filename] read cycle count file.\n" "\nOptions may be entered in a freeform fashion as long " "as a dash (-) or\n" "a slash (/) preceeds any option that preceeds the filename." "\nExamples:\n" "\td52 filename bd\n" "\td52 -d filename x100\n" "\td52 /h filename d -x100\n\n"); exit(GOOD_EXIT); } // // The Main Program // int main(int argc, char *argv[]) { char c; int count; char *inp; int line; char tempstr[16]; #ifdef ALPHA printf("\nD52 8052 Disassembler V%d.%d.%d Alpha %d" "\nCopyright (C) 1995-%d by J. L. Post%s", VERSION, MAJORREV, MINORREV, ALPHA, YEAR, licenseText); #else #ifdef BETA printf("\nD52 8052 Disassembler V%d.%d.%d Beta %d" "\nCopyright (C) 1995-%d by J. L. Post%s", VERSION, MAJORREV, MINORREV, BETA, YEAR, licenseText); #else printf("\nD52 8052 Disassembler V%d.%d.%d" "\nCopyright (C) 1995-%d by J. L. Post%s", VERSION, MAJORREV, MINORREV, YEAR, licenseText); #endif #endif strcpy(defbstr, "db"); // init define byte and word strings strcpy(defwstr, "dw"); strcpy(ascistr, "db"); // init define ascii string sym_tab = NULL; // no symbols or labels yet lab_tab = NULL; name_tab = NULL; fp = NULL; fileflag = EITHERFILE; // assume search for either file type hexflag = FALSE; // no data in comment field upperflag = FALSE; baseflag = FALSE; traceflag = FALSE; offset = 0; // default start at address 0 ascii_flag = FALSE; keilflag = FALSE; incflag = FALSE; cycleflag = FALSE; // no cycle counting by default cycle_r = NULL; // cycles list is empty cycle_current = NULL; // init current (last updated) cycle counter pointer cycle_exclude = FALSE; // no exclusion from cycle counting until explicitly // given in control file if (argc < 2) usage(); // find filename in command line for (line=1; line 2) // test for options { for (count=1; count pacbell net * * d52.h - 8052 disassembler definitions * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _D52_H_ #define _D52_H_ #define CPU_BIG_ENDIAN // 8052 is big endian processor #ifndef _DEFS_H_ #include "defs.h" #endif // Defined Constants // opttbl bits: #define OPT_XFER 0x80 // unconditional transfer #define OPT_11 0x40 // 11 bit addressing #define OPT_REL 0x20 // relative addressing #define OPT_BIT 0x10 // bit addressing #define OPT_DIR 0x08 // direct addressing #define OPT_IMM 0x04 // immediate data #define OPT_3 0x02 // 3 byte instruction #define OPT_2 0x01 // 2 byte instruction #define OPT_MASK (~OPT_XFER) // options mask #define OPT_NONE 0 // single byte, no options #define OPT_SIZE (OPT_3 | OPT_2) // additional byte count #define OPT_LREF (OPT_IMM | OPT_3) // ljmp, lcall or mov dptr #define OPT_IMM2 (OPT_IMM | OPT_2) // 2 byte immediate data #define OPT_DIR2 (OPT_DIR | OPT_2) // 2 byte direct adrs #define OPT_DIR3 (OPT_DIR | OPT_3) // 3 byte direct adrs #define OPT_DMM3 (OPT_DIR | OPT_IMM | OPT_3) // 3 byte dir & imm #define OPT_BIT2 (OPT_BIT | OPT_2) // 2 byte bit adrs #define OPT_REL2 (OPT_REL | OPT_2) // 2 byte relative adrs #define OPT_IR3 (OPT_REL | OPT_IMM | OPT_3) // 3 byte rel & imm #define OPT_DR3 (OPT_REL | OPT_DIR | OPT_3) // 3 byte rel & dir #define OPT_RELB (OPT_REL | OPT_BIT | OPT_3) // 3 byte rel & bit #define OPT_112 (OPT_11 | OPT_2) // 2 byte 11 bit adrs // // Prototypes // extern void usage(void); // // Global Variables // extern int keilflag; // Keil A51 compatibility extern int incflag; // include file flag extern byte dirregs[128]; // access flags for dir reg extern byte sfrflags[128]; // SFR name change flags extern byte sbflags[128]; // SFR bit name change flags extern byte mbflags[128]; // bit adrs mem name chg flgs #endif // _D52_H_ d52-3.4.1.orig/d52manual.html0000600000175000017500000020340110666332247013711 0ustar uweuwe D52 Disassembler User's Manual
D52 Disassembler User's Manual

8052 Disassembler for Linux and Windows
GNU General Public License Version 3
Copyright 2007 by Jeffery L. Post
 j_post <AT> pacbell <DOT> net
Hosted on www.8052.com

Version 3.4.1 - September, 2007

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

The file COPYING contains the full text of the GNU General Public License, Version 3.

NOTE: As Novell and Microsoft are in violation of the GPL, this software may not be distributed by either Novell or Microsoft. The same prohibition applies to any company that enters into an agreement with Microsoft regarding Microsoft's phony patent claims against Linux. In addition, no one who cannot or will not honor ALL the requirements of GPL version 3 may distribute this software.

TABLE OF CONTENTS



Back to top

Introduction


The D52 disassembler allows the user to specify memory areas as code, binary data (8 or 16 bit), ascii text, address tables, or data that should be ignored (not disassembled). You may specify such areas in an ascii text file with the same name as the file to be disassembled, but with an extension of ctl (for example: program.ctl controls the disassembly of program.hex or program.bin).

With the use of a control file, you can, by an iterative process, get a progressively more meaningful disassembly by modifying the control file based on examination of the output of previous runs of the disassembler. You can also specify names for labels and symbols in the control file, resulting in a much more readable source file.

Labels and symbols may have as many characters as will fit in one line of the control file, but some cross assemblers (and especially cross linkers) will truncate any more than some fixed number of characters. Consult your cross development tool documentation. Labels and symbols are not case sensitive.

The control file may exist in either the current directory or the directory of the file to be disassembled. If it is in both directories, the control file in the current directory will take precedence. The output file will always be placed in the current directory.

The getting started section of this document gives some minimal information for users who are eager to try out the disassembler. For best use of the disassembler, however, you should read the sections on command line options and control file directives before proceeding.

Much of the information in this manual also applies to the 8048 and Z80 disassemblers. Invoking the disassemblers without any command line parameters will display a list of options.

Disclaimer
D52 is a tool for educational use and for recovering source code that has been lost or is unavailable. Disassembling a program may be unethical or illegal under some circumstances. It is your sole responsibility to determine whether use of D52 for a particular purpose is both legal and ethical.



Back to top

Getting Started


D52 is a command line disassembler. To disassemble a file called 'program.bin' or 'program.hex', type in (at the command line prompt):
d52 -d program
A control file with the same name as the file to be disassembled, but with an extension of '.ctl' can be created in which you can specify areas of memory to be ascii text, 8-bit binary data, 16-bit binary data, etc. A control file is not necessary for disassembly, but as will be seen, it will provide for a much more complete disassembly. The t option will cause D52 to trace and analyze the code before disassembly, and will create a preliminary control file.

If a file extension is not provided and neither the b option nor the h option is specified on the command line, the disassembler will first search for a hex file and, if it is not found, will then search for a bin file. The disassembler can be forced to look for only one or the other by specifying either the binary or the hex option on the command line:
d52 -db program for the file program.bin, or
d52 -dh program for the file program.hex
If a file extension of '.hex' or '.bin' is provided in the filename (ie: d52 test.hex), that is equivalent to using the h option or b option.

D52 will produce a file named 'program.d52' containing the disassembly of the 8051/8052 instructions in the original hex or binary file. It is very useful on the first few disassemblies to use the d option , which adds a comment field to every line. The comment field contains the hexadecimal address of each instruction, the hex data for each byte in the instruction, and the ascii code for each byte of the instruction.
Example:
(opcode/operands)(address)(data)(ascii)
orl a,#42h; 0df644 42DB
This makes it easy to spot areas of ascii text or other nonexecutable code, and you can then modify the control file to tell the disassembler that these areas should be treated as some other kind of data on subsequent disassemblies. Please see the section on control file directives for specific information.

By examining the output file and then modifying the control file based on the information obtained, you can get a progressively better disassembly of your program. Generally, about half a dozen iterations of the disassembly are enough to produce a very readable source file that can then be modified and reassembled.

Back to top

Command Line Options


Command line options modify the operation of the disassembler. They may be specified on the command line using either Unix style options:
d52 -db filename
or DOS style options:
d52 /d /b filename
Options may be entered in a freeform fashion (in any order or format) provided that any options preceeding the filename of the program to be disassembled must begin with either a dash (-) or a slash (/). For example:
d52 /db filename -x1000
d52 filename -d b x1000
d52 -d filename bx1000
all mean exactly the same thing and will cause the disassembler to behave in exactly the same way. Exceptions are that the X option , if used, must be the last option given, and if both the A option and the S option are used, the S option must preceed the A option.

Note that the file name specified on the command line does not include the .hex or .bin extention.

Command line options are:

A Option (ascii macro)

The A option tells the disassembler to change the db/defb pseudo op to the ascii macro (pseudo op 'ascii' instead of 'db' or 'defb') for areas defined as ascii text. This will cause the disassembler to include a macro definition in the disassembly output file that should expand to 'db' for the cross assembler. To use this option, your cross assembler must be able to handle macros, and in particular, D52's macro format. If used in conjunction with the S option , the S option must come first on the command line.

There are some caveats regarding the ascii macro. The intent of this macro is to make ascii text easier to find in the output file. Once you're satisfied with the readability of the output file, you may want to run the disassembler once more without the A option to produce a file compatible with your cross assembler.

Some cross assemblers treat certain characters within a macro as special meta-characters. The Huntsville Microsystems HMA8051, for example, regards the characters '#', '.' and '\' as special within a macro. If these characters occur in ascii text using the ascii macro of D52, the assembler will do strange and not so wonderful things with them. If this happens, just do not use the A option (by default, it is off).

A problem that will be common with all cross assemblers is that the disassembler does not currently treat the single quote (') character differently than it does other characters within ascii text. Since the disassembler delineates ascii text (whether using the A option or not) with the single quote character, its presence in ascii text areas will cause problems. The only solution to this is to manually edit the output file of the disassembler or to define the byte of the single quote as a binary byte in the control file (see the B control file directive ).

B Option (read binary file)

The B option forces the disassembler to read a binary file (extention '.bin') instead of an Intel hex file (extention .hex). If neither the B option nor the H option are specified, the disassembler will first search for a file with an extention of .hex, and if not found, will then search for a binary file with an extention of .bin.

D Option (put data in comment field)

The D option tells the disassembler to include a comment field in each disassembled line. The comment field will contain the hexadecimal address of each instruction, the hex data for each byte in the instruction, and the ascii code for each byte of the instruction. Example:
(opcode/operands) (address)(data)(ascii)
orl a,#42h ; 0df644 42DB
This makes it easy to spot areas of ascii text or other nonexecutable code, and then modify the control file to tell the disassembler that these areas should be treated as some other kind of data on subsequent disassemblies. Please see the section on control file directives for specific information.

H Option (read hexadecimal file)

The H option forces the disassembler to read an Intel hex file (extention '.hex') instead of a binary file (extention '.bin'). If neither the B option nor the H option are specified, the disassembler will first search for a file with an extention of '.hex', and if not found, will then search for a binary file with an extention of '.bin'.

I option (add include for 'sfr52.inc' file)

The I option adds this line to the .d52 disassembly file:

	include	"sfr52.inc"


The file 'sfr52.inc' includes equates for 8052 special function registers and SFR bits that may be needed by some cross assemblers. The sfr52.inc file should be modified to suite your 8052 cross assembler since the equates required will vary from assembler to assembler. For example, one cross assembler I test with requires the equate for 'acc', and yet another cross assembler not only does not require it, but will generate an error if it is present. You may also need to edit the 'include' pseudo-op in the disassembly file if your cross assembler uses some other pseudo-op to include files (or edit the source file 'd52p2.c' and recompile).

It is best to start out with all the equates in sfr52.inc commented out, find out what undefined label errors your cross assembler generates, then uncomment the required equates in sfr52.inc.

This option is incompatible with the K option.

K Option (disassemble for Keil's A51 assembler)

Tells D52 to generate source code compatible with the older Keil A51 assembler.

NOTE: Newer versions of Keil's A51 assembler (tested with version 7.10) have come into compliance with the rest of the world. Do not use this option with newer versions of A51.

N Option (use C type operands)

Use this option to have the disassembler output hexadecimal operands using C notation, ie: 0xcd instead of the default 0cdh.

P Option (add dot in front of pseudo ops)

Some assemblers require pseudo operations to begin with a dot. Use this option to have the disassembler output ".equ" instead of "equ" and similar for org and other pseudo operations.

S Option (set string pseudo op)

This option tells the disassembler to generate the pseudo ops 'defb' and 'defw' instead of 'db' and 'dw' for those cross assemblers that may require this. Most cross assemblers understand 'db' and 'dw', so these are the defaults for the disassembler. Use this option for cross assemblers that do not recognize 'db' and 'dw'. If used in conjunction with the A option , the S option must preceed the A option on the command line.

T Option (trace and analyze code)

This option tells D52 to trace and analyze the 8052 code before disassembling it. D52 will attempt to determine which parts of the code are actually code, and which parts are ascii text, binary data, pointers, etc. While it does a reasonably good job of analyzing the code on most files, no program can do as good a job as a human programmer. A control file with the same name as the hex or bin file, but with an extension of '.ctl', will be created before the actual disassembly is performed. You can then edit the control file to correct any erroneous directives, or to add new directives.

Warning: Using this option will overwrite any control file that may already exist for the code file being disassembled. It is intended to be used on the first disassembly only.

U Option (upper case output)

Causes labels, symbols, mnemonics, etc to be output in upper case, for cross assemblers that may require upper case code. Comments, literal data values, strings, and other output are not affected by this option.

X Option (add hexadecimal offset to addresses)

This option causes the disassembler to add a hexadecimal offset to the address of every location in the code file. This may be useful for disassembling code that was read from the second (or subsequent) rom of a set of roms. For example, suppose that binary data was obtained from a set of 4K byte eproms (call them rom1 and rom2). Then the first file should be disassembled with the command line:
d52 -d rom1
and the second should be disassembled with the X option:
d52 -d rom2 x1000
The two files then can be combined into one and all references within the disassembled code will be to the correct addresses.

If given on the command line, the X option overrides any O directive in the control file.

Z Option (read cycle count file - d52 only)

Jan Waclawek has added code to generate cycle counts for all three disassemblers. In addition, d52 can read customized cycle count files for 8052 derivatives. See the Z directive for more information. Please read Jan's documentation in the 'cyclefiles' directory.
d52 -zfilename
Many thanks to Jan for a great job!

Back to top

Control File Directives


Control directives tell the disassembler to treat specified areas of the code to be disassembled as something other than executable code. The user specifies control directives by editing (with any text editor) a control file with the same name as the file to be disassembled, but with a file extention of .ctl (eg: program.ctl to control the disassembly of the file program.hex or program.bin). A generic control file called 'generic.ctl' is provided to get the user started. Copy 'generic.ctl' to 'file.ctl' where 'file' is the name of the binary or Intel hex file to be disassembled, and modify as required based on the output of the disassembler. Then run the disassembler again to get a more readable disassembly of the code.

All directives consist of a character that specifies the type of data, followed by a hexadecimal number specifying the value or range of values of the data. In the case of a label or symbol directive, the hexadecimal number is followed by ascii text defining the label or symbol. See individual directives for examples. All directives must be in the first column of the line. Directives may be complete words, but only the first character is significant, ie:
Label 0 reset and
looney 0 reset
will both generate the label "reset" for address 0. Note that they are not case sensitive.

Numerical values must be in hexadecimal and may optionally be preceeded by "0x". For example, a hexadecimal number may be entered as "1234" or "0x1234". Either will be interpreted as the number 1234H.

Everything following a semi-colon (;) is a comment and will be ignored by the disassembler.

Label and symbol directives differ in that a label refers to an address and a symbol refers to any 8 or 16 bit immediate data. Therefore an opcode such as
mov r2,#data
will cause the disassembler to search only the symbol table for a matching value whereas an opcode such as
mov dptr,#data
will cause the disassembler to search the label table first, and if no matching value is found, to then search the symbol table.

Symbols apply only to immediate data. To specify a symbol for an 8052 data memory location, use the R directive , or to force name substitution for an operand at a given address, use the X directive.

Single values are specified by entering just the value; ranges of values are specified by a start and stop address separated by a dash (-), or by a start address and count separated by a plus (+), ie:
t 1000 the data at address 1000H is ascii text.
t 1000-1010 the data from address 1000H to (and including) address 1010H is ascii text.
t 1000+6 ascii text starting at 1000H for 6 bytes.
Directives are processed in the order in which they are read from the control file. Specifying an area as ascii data and then later specifying it as data to be ignored (uninitialized data) will cause that area to not be disassembled at all. Care must be taken in specifying areas in the control file.

A Directive (address data)

Specifies that the address contains a word value corresponding to an address for which a label should be generated. For example, a vector table may be located at address 0x1000 containing four entries. The user can modify the control file by adding the following entry:
a 1000-1007
This will cause the disassembler to generate the following output lines:
dw vec1
dw vec2
dw vec3
dw vec4
assuming that the control file also contains entries for the values found at those addresses to generate the labels vec1 through vec4. The addresses referenced will be flagged so that labels will be generated in the output file at those addresses.

B Directive (byte binary data)

Specifies that the data is to be interpreted as 8 bit binary data. For example:
b 1000-1007
tells the disassembler that the data from address 1000H to 1007H should generate the line:
db 0,1,2,3,4,5,6,7
assuming that the data at address 1000H and up is 00H, 01H, etc.

C Directive (code data)

Forces the disassembler to interpret the data as executable code. This may be necessary because the disassembler skips over strings of 00H or ffH bytes that occur since they are unlikely to be real code. However, sometimes programmers insert several NOPs for timing purposes.

D Directive (define data type (label or symbol))

d address [0 or label] search label table only
d address [1 or symbol] search symbol table only
d address [2 or none] don't search either table
Forces the disassembler to search only the label or symbol table. This allows you to specify a label and a symbol for the same value. For example:
mov dptr,#1234
would normally search only the label table assuming that the data refers to a code address. If the data is really a constant with the same value as a label, then
d 1 address
will force the disassmbler to look only in the symbol table for the string that represents the value of the data. The address is the address of the opcode, not the code location of the data operand.

Note that the last parameter can be either a number (0, 1, or 2) or a word (label, symbol, none). If the last parameter is a word, only the first character is checked for L, S, or N, and is not case sensitive.

F Directive (SFR label definition)

Causes reference to an SFR (special function register) to generate a label for the specified SFR address. This is useful for naming SFR's for non-standard members of the 8052 family. For example, suppose that some manufacturer designs a new 8052 variant and decides to use address efH as a new special function register called 'NEWREG'. Then by adding:
f ef newreg
to the control file, D52 will disassemble the opcodes f5 ef as:
mov newreg,a
instead of:
mov 0efh,a
SFR label names are limited to fifteen characters.

I Directive (ignore data)

Tells the disassembler to ignore a range of addresses that may be initialized by the input file. This is useful when the input file is a binary file generated by an eprom programmer that dumps the entire eprom space. The valid data from a 4K eprom might only be, say, 3K in length. By adding
i c00-fff
to the control file, you tell the disassembler to not disassemble the data from address 0c00H to 0fffH.

K Directive (SFR bit definition)

As with the F directive , you can give a name to a new SFR bit. If a new variant of the 8052 family adds a new interrupt, for instance, its enable bit in the IE register might be bit 6. By adding:
k ae newint (ae is the address of IE.6)
you define bit 6 of the interrupt enable register to be 'ie.newint'. Like SFR label names, SFR bit names are limited to fifteen characters.

L Directive (label definition)

Defines a label to the disassembler. Labels are generated in the output disassembly file whenever a reference to the address is found and the label exists in the label table. Suppose that address 0000H contains the code 01 43 (ajmp 0043H). Then the entry
l 43 start
in the control file will cause D52 to disassemble this code as:
ajmp start
rather than:
ajmp X0043
The code beginning at address 43H will then have the label 'start' in the label field rather than the label 'X0043'. See the entry for the S directive for an explanation of the difference between labels and symbols.

M Directive (bit addressable memory label)

Similar to the K directive , the M directive gives a name to a bit addressable memory location. Example:
m 12 bitflag (12h is the bit address of 22h.2)
would cause the bytes d2 12 to be disassembled as
setb bitflag
instead of
setb 22h.2
As with the K directive, names are limited to fifteen characters.

N Directive (suppress address label generation)

The disassembler will generate labels for addresses that are referenced by code such as
mov dptr,#6
If the operand represents a constant rather than an address, you can suppress the automatic generation of a label (X0006) for address 6h by entering
n 6
in the control file. You'd want to make sure that address 6h isn't legitimately addressed by some other code before using this directive.

O Directive (add hexadecimal offset to addresses)

This directive causes the disassembler to add a hexadecimal offset to the address of every location in the code file. See the X option for details. It will be overridden by any X option specified on the command line. If the T option (trace and analyze code) is given on the command line, the O directive has no effect since any existing control file will be rewritten. In this case you must use the command line X option to specify an offset.

P Directive (patch inline code)

This directive is of dubious value, but has been added for anyone who might find it useful. The P directive is similar to the comment directive except that the user supplied string is patched into the output stream as code, not as a comment. You could, for instance, patch in a macro definition or an include statement. Patching in executable code is not a real good idea.

R Directive (register definition)

This directive specifies a name for an 8052 register. Direct accesses to registers will normally be disassembled as:
mov rb2r5,a
in the case of register 5 of register bank 2. If the user determines that register 5 of bank 2 is being used as a loop counter, for example, he can give it the name loop by adding:
r 15 loop
to the control file, and the above code will be disassembled as:
mov loop,a
The R directive can assign a name to any internal memory location below the SFR address space.

S Directive (symbol definition)

Defines a symbol to the disassembler. Symbols are output to the disassembly file whenever the value is encountered in the input file and the symbol exists in the symbol table. The user can specify a symbol for a value by a line such as:
s 20 space
Code which uses this value, such as:
mov a,#20h
will then be disassembled as:
mov a,#space
Labels and symbols differ in that a label applies to an address, whereas a symbol applies to any 8 or 16 bit immediate data. For code which can only refer to values, such as
mov a,#20h
only the symbol table will be searched for a matching value. For code which could refer to either an address or a value, such as:
mov dptr,#1234h
the label table will be searched first, and only if no matching value is found will the symbol table then be searched. This search behavior can be modified by use of the d directive or the x directive.

T Directive (text [ascii] data)

Forces the data in the range specified to be disassembled as text (ascii data). Thus the code: 48 69 20 74 68 65 72 65 at address 1000H will be disassembled as:
db 'Hi there' or
ascii 'Hi there' (command line option A used)
by putting the line:
t 1000-1007
in the control file. Otherwise it would be interpreted as:
orl a,r0 ; 1000 48 H
xrl a,r1 ; 1001 69 i
jb 2eh.4,X106d ; 1002 20 74 68 th
xrl a,72h ; 1005 65 72 er
xrl a,t3 ; 1007 65 ff e.
which is unlikely to be what was intended by the original programmer. Data specified by this directive is not checked to verify that it really is ascii data--be careful.

W Directive (word binary data)

Specifies that the data is to be interpreted as 16 bit binary data. For example:
w 1000-1007
tells the disassembler that the data from address 1000H to 1007H should generate the lines:
dw 0
dw 1
dw 2
dw 3
assuming that the data at address 1000H and up is 00H, 00H, 00H, 01H, 00H, 02H, etc. This differs from the A (address) directive in that the A directive also causes a reference to be made to the indirect address. In other words, if the data at address 1000H is 1234H, the A directive will cause a label (X1234) to be put in the output file at address 1234H, whereas the W directive will not.

X Directive (specify name for operand data)

Specify a name for an operand at a particular address. This is similar to the S directive except that it applies only to the given address. For example, if the symbol 'CR' is defined as 0dh, every instance of 0dh as an operand will have the symbol 'CR' substituted. It may be, however, that the value 0dh has a different meaning when used as an operand for a particular instruction. The X directive allows you to modify the interpretation of an operand at specific operand locations. Why not then use the X directive exclusively? Because that would force you to place an X directive in the control file for every instance in which that value appeared as an operand. The S directive, defined only once for an operand value, will substitute the symbol text for every occurrance of that operand value unless overridden by the X directive. Note that the address defined in the X directive is the address of the operand, not the address of the instruction. For example:
X 102 loopinit
forces substitution of the text 'loopinit' for the operand located at address 102h. Therefore an instruction that should be interpreted as
mov r0,#loopinit
will not be disassembled as
mov r0,#CR
if the control file contains the above x directive, and also contains an S directive defining 0dh as 'CR', and the value of the operand for the mov instruction happens to also be 0dh.

Y Directive (specify name for operand data but suppress EQU generation)

This is similar to the X directive except that the disassembler will not generate an EQU statement for the operand value in the output file. This should be used when you want to specify a name for an operand that is an assembler pseudo-op such as LOW() or HIGH().

Z Directive (specify code for which to generate cycle count information)

Specify addresses for which cycle count information will be added in the disassembly file. Also see the Z option.
Please read Jan's documentation in the 'cyclefiles' directory.

# Directive (header comment string)

Defines a comment string to be output prior to disassembly at the specified address. For example:

        # 95
        # 95 Start of initialization
        # 95


in the ctl file would cause the output

        ;
        ; Start of initialization
        ;
                clr  ea           ;0095     c2 af     B/


assuming that the code 'c2 af' was located at address 0x95. Since ASCII strings consume prodigious amounts of memory, it is wise to use this directive sparingly. It is, however, useful for marking blocks of code that have been identified in previous runs of D52.

! Directive (inline comment string)

Defines a comment string to be output after disassembly at the specified address. For example:

        ! 95 Start of initialization


in the ctl file would cause the output

                clr  ea           ;0095     c2 af     B/    ; Start of initialization


for the above example. Note that inline comments are only available for code and word data, and will do nothing if the data at the specified address is defined as data other than code or word data (ascii text, for example).

Back to top

A Note on Symbols, Labels and Names


An example will best explain the difference between labels, symbols, operand names and register names. Labels refer to program code locations, symbols refer to immediate operands, register names and operand names refer to data memory locations.

Given the hex or binary file produced from the follow source code:

org 30h
mainmov a,30h
mov 30h,r0
mov r1,#30h
sjmp main
end

and this control file:

l 30main; label for code address
x 33thirty; name for operand at address 33h
s 30alsothirty; symbol for immediate operand
r 30counter; name for data memory address (register) at 30h


D52 will produce the following output:

;
org30h
;
main:mova,counter; 0030 e5 30e0
movthirty,r0; 0032 88 30.0
movr1,#alsothirty; 0034 79 30y0
sjmpmain; 0036 80 f8.x
;
counterequ30h
alsothirtyequ30h
thirtyequ30h
;
end
;


Note that the label, symbol, register name, and operand name all have the same value: 30h. But the operand name directive ( x directive) in the control file specifies the address of the operand (in this case 33h), and the other three control file directives refer to the value of the operand. The x directive allows you to use a different name for the same value (unlike a symbol), so that, for example, an operand value of 0dh in one place can be disassembled with the name 'CR' and in another place as, say, 'loop_init_count'.

Format of Output File


The output file for D52 (extention '.d52') contains 8052 instructions and pseudo ops in a format that should be acceptable to any 8052 cross assembler. When assembled, the source file should produce an Intel hex file or binary file that is identical to the original. Identical, in this case, means that the code is the same, not that it necessarily has the same format. The number of bytes in each line of the hex file may differ from the original depending on whether the original was produced by an assembler or was read from an eprom. Each output line is in the following format:
LABEL: OPCODE OPERANDS ; COMMENT
The label field will be generated only if the address of the code is referenced by some other code (a call, for instance), or if the user has specified a label for that address in the control file. The comment field is only generated if the user specifies the D option on the command line. Comments begin with a semicolon and are followed by the hexadecimal address of the instruction, the hex value of the byte(s) for the instruction, and finally by the ascii representation of the instruction byte(s). For example:
X004f: orl p3,#0ffh ; 004f 43 b0 ff C0.
label opcode operands comment
Several things should be noted in this example. The label is 'X' followed by the address of the instruction in four hex digits. This type of label is created by the disassembler when some other code references the address. If the user specifies a label name for the address in the control file ('what' for example), the generated code becomes:
what: orl p3,#0ffh ; 004f 43 b0 ff C0.
If the user were to specify the symbol 'ones' for the value 0ffH, the output would then become:
what: orl p3,#ones ; 004f 43 b0 ff C0.
Also note the ascii representation of the instruction bytes. Bit 7 is forced to zero so that ascii with the high bit set can be viewed (b0H in the example becomes 30H, which is ascii '0'). Any code which is not printable ascii (a control code, for example) is output as a period. This is the case for the byte 0ffH above.

The comment field starts at a different position in the output line depending on the type of data in the input file. For normal executable code, the comment field starts in column 32; for hex data it starts at column 49, and for ascii data it starts in column 56. For many programs, this makes for a more readable source file, but if there is a mix of data types in a short range of addresses, this can lead to some strange looking formatting. The user may want to correct this with a text editor in the final disassembly before modification and reassembly.

Back to top


Summary


D52 is distributed under the GNU General Public License. See the file COPYING for details. D52 versions 3.1 and higher are a continuation of the earlier disassembler named D51.

D52 allows the user to specify how code should be disassembled via a control file that defines given areas of the code as ascii text, binary data or other types of non-executable code. By an iterative process of disassembly, control file modification, and further disassembly, the user can obtain a very readable source file that can then be modified and re-assembled by a cross assembler. Several public domain cross assemblers are available.

I've encountered several problems when reassembling the output of D52. Almost all are due to the cross assembler not recognizing SFRs of some of the newer or more exotic 8052 variants. The D52 tables include names for all SFRs that I'm aware of as of May 1995 (there are likely some that I'm not aware of). Such errors might be corrected just by defining a symbol for the SFR in the control file (see the F directive ), but this depends on whether your cross assembler will accept it as a valid operand. If all else fails, replace the offending instruction with a 'db' pseudo op and put the mnemonic and operand in a comment. A similar problem is the assembler not being able to handle a bit addressable SFR address; the only solution I see to this is to use a 'db' pseudo op. All other problems I've seen (not many) have been due to disassembling data as code; this is easily corrected by modifying the control file to specify the correct data type.

Many thanks to numerous beta testers who have made invaluable suggestions for improvement and found more bugs than I care to think about. Also thanks to all the users who have, over the years, also made significant contributions to the betterment of D52. Any remaining deficiencies are solely my fault.

Summary of command line options and control file directives

Command line options:
  • A - Change db/defb pseudo op to 'ascii' macro for text
  • B - Force read of binary file (.bin extention)
  • D - Add address and data info in comment field
  • H - Force read of Intel hex file (.hex extention)
  • I - Add statement to include file 'sfr52.inc' in output file
  • K - Disassemble for older Keil A51 assembler
  • N - Output C style hexadecimal operands
  • P - Add a dot '.' to beginning of pseudo operation codes
  • S - Change db and dw pseudo ops to defb and defw
  • T - Trace and analyze code before disassembly
  • U - Output labels, mnemonics, etc in upper case
  • X - Add hexadecimal offset to all program locations
  • Z - Read cycle count file (d52 only)
Control file directives:
  • A - Specifies that words in program space are addresses
  • B - Data is 8 bit binary
  • C - Program space is executable code
  • D - Force search of only label table or only symbol table for operand name
  • F - Specify SFR label
  • I - Ignore data (uninitialize program space)
  • K - Specify label for SFR bit
  • L - Define label
  • M - Specify label for bit addressable memory
  • N - Suppress generation of address label
  • O - Add hexadecimal offset to all program locations
  • P - Patch inline code
  • R - Define register name
  • S - Define symbol
  • T - Specify ascii text
  • W - Data is 16 bit binary
  • X - Specify name for a specific operand
  • Y - Specify name for a specific operand but do not generate an EQU statement
  • Z - Specify addresses for which to generate cycle count information
  • # - Define a header comment string
  • ! - Define an inline comment string


Back to top

8052 Register Maps


Addresses of 8052 registers:
BankR0R1R2R3R4R5R6R7
00001020304050607
108090A0B0C0D0E0F
21011121314151617
318191A1B1C1D1E1F


Addresses of 8052 Special Function Registers:
AddressSymbolName
80 P0 Port 0
81 SP Stack Pointer
82 DPL Data Pointer (low byte)
83 DPH Data Pointer (high byte)
87 PCON Power Control
88 TCON Timer/Counter Control
89 TMOD Timer/Counter Mode
8A TL0 Timer/Counter 0 (low byte)
8B TL1 Timer/Counter 1 (low byte)
8C TH0 Timer/Counter 0 (high byte)
8D TH1 Timer/Counter 1 (high byte)
90 P1 Port 1
98 SCON Serial Port Control
99 SBUF Serial Data Buffer
A0 P2 Port 2
A8 IE Interrupt Enable
B0 P3 Port 3
B8 IP Interrupt Priority
D0 PSW Program Status Word
E0 ACC Accumulator
F0 B B Register


Back to top

Bit Addressable Special Function Registers

AddressSymbolBit nameFunction
80-87 P0.0-7 Port 0
88 IT0 TCON.0 External Interrupt 0 Type Control
89 IE0 TCON.1 External Interrupt 0 Edge Control
8A IT1 TCON.2 External Interrupt 1 Type Control
8B IE1 TCON.3 External Interrupt 1 Edge Control
8C TR0 TCON.4 Timer 0 Run Control
8D TF0 TCON.5 Timer 0 Overflow Flag
8E TR1 TCON.6 Timer 1 Run Control
8F TF1 TCON.7 Timer 1 Overflow Flag
90-97 P1.0-7 Port 1
98 RI SCON.0 Serial Receive Interrupt Flag
99 TI SCON.1 Serial Transmit Interrupt Flag
9A RB8 SCON.2 Serial Receive Bit 8
9B TB8 SCON.3 Serial Transmit Bit 8
9C REN SCON.4 Serial Receive Enable
9D SM2 SCON.5 Serial Port Mode Specifier
9E SM1 SCON.6 Serial Port Mode Specifier
9F SM0 SCON.7 Serial Port Mode Specifier
A0-A7 P2.0-7 Port 2
A8 EX0 IE.0 Enable External Interrupt 0
A9 ET0 IE.1 Enable Timer 0 Interrupt
AA EX1 IE.2 Enable External Interrupt 1
AB ET1 IE.3 Enable Timer 1 Interrupt
AC ES IE.4 Enable Serial Port Interrupt
AF EA IE.7 Enable Interrupts
B0-B7 P3.0-7 Port 3
B8 PX0 IP.0 External Interrupt 0 Priority
B9 PT0 IP.1 Timer 0 Interrupt Priority
BA PX1 IP.2 External Interrupt 1 Priority
BB PT1 IP.3 Timer 1 Interrupt Priority
BC PS IP.4 Serial Port Interrupt Priority
D0 P PSW.0 Parity
D2 OV PSW.2 Overflow Flag
D3 RS0 PSW.3 Register Bank Select Bit 0
D4 RS1 PSW.4 Register Bank Select Bit 1
D5 F0 PSW.5 Flag 0 (general purpose flag)
D6 AC PSW.6 Auxiliary Carry Flag
D7 CY PSW.7 Carry Flag
E0-E7 ACC.0-7 Accumulator Bits
F0-F7 B.0-7 B Register Bits


Back to top

Addresses of Bit Addressable Memory Locations

AddressMemory location
00-0720.0 - 20.7
08-0F21.0 - 21.7
10-1722.0 - 22.7
18-1F23.0 - 23.7
20-2724.0 - 24.7
28-2F25.0 - 25.7
30-3726.0 - 26.7
38-3F27.0 - 27.7
40-4728.0 - 28.7
48-4F29.0 - 29.7
50-572A.0 - 2A.7
58-5F2B.0 - 2B.7
60-672C.0 - 2C.7
68-6F2D.0 - 2D.7
70-772E.0 - 2E.7
78-7F2F.0 - 2F.7


Back to top




d52-3.4.1.orig/d52pass1.c0000644000175000017500000000662510666553554012770 0ustar uweuwe /* * D52 8052 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * d52pass1.c - Disassembly pass 1 * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include "d52.h" #include "common.h" #include "d52pass1.h" #include "d52pass2.h" #include "d52table.h" // // Pass one of disassembly // // Examine opcodes for internal references to other memory locations. // If such references are found, flag the referenced location so that // a label can be generated in the output file during pass two. // void pass1(void) { int i, l, pc, rel; byte j, k, temp, mask; printf("\nPass 1 0000"); for (i=offset; i= offset && pc <= himark) mask |= PF_NOINIT; pgmflags[pc] = (pgmflags[pc] & ~mask) | PF_REF; // flag reference } if (j & OPT_11) // if 11 bit adrs (ajmp & acall) { pc = ((i + 2) & 0xf800) | ((k & 0xe0) << 3) | (pgmmem[i+1] & 0xff); if (pc >= offset && pc <= himark) mask |= PF_NOINIT; pgmflags[pc] = (pgmflags[pc] & ~mask) | PF_REF; // flag reference } if (j & OPT_REL) // if relative reference { if (j & OPT_3) // if 3 byte relative address { temp = pgmmem[i + 2]; // get offset rel = (temp > 0x7f) ? temp | 0xff00 : temp & 0xff; pc = i + 3; } else // else 2 byte relative address { temp = pgmmem[i+1]; // get offset rel = (temp > 0x7f) ? temp | 0xff00 : temp & 0xff; pc = i + 2; } pc += rel; pc &= WORD_MASK; if (pc >= offset && pc <= himark) mask |= PF_NOINIT; pgmflags[pc] = (pgmflags[pc] & ~mask) | PF_REF; // flag reference } pc = i; i = i + (opttbl[k] & OPT_SIZE) + 1; // update location pointer i &= WORD_MASK; } else { pc = i; i++; i &= WORD_MASK; } if (i < pc) // oops! wrapped around... break; if ((i & 0xff) < l) printf("\rPass 1 %04x", i & 0xff00); } printf("\rPass 1 - Reference search complete"); } // End of Pass 1 // end of d52pass1.c d52-3.4.1.orig/d52pass1.h0000644000175000017500000000202410666551423012753 0ustar uweuwe /* * D52 8052 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * d52pass1.h - Disassembly pass 1 * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _D52PASS1_H_ #define _D52PASS1_H_ // Prototypes extern void pass1(void); #endif // _D52PASS1_H_ d52-3.4.1.orig/d52pass2.c0000600000175000017500000005357210666553504012757 0ustar uweuwe /* * D52 8052 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * d52pass2.C - Disassembly pass 2 * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include "d52.h" #include "common.h" #include "d52pass1.h" #include "d52pass2.h" #include "d52table.h" // // Defined Constants // /* none */ // // Global variables // /* none */ // // Pass two of disassembly. Rescan data array and generate output file. // Generate label if location flagged as referenced by some other opcode. // If un-initialized data is encountered, ignore it but set skip flag so // that an ORG statement can be generated when the next initialized data // is found. // void pass2(void) { char *cptr; int skip, year; int i, l, q, temp, oldpc; byte j, k; int pflag; time_t tp; if (upperflag) // convert SFR, register, etc text to upper case { for (i=0; i<128; i++) makeupper(sfr[i].dent); for (i=0; i<128; i++) makeupper(keilsfr[i].dent); for (i=0; i<128; i++) makeupper(sfrbits[i].dent); for (i=0; i<128; i++) makeupper(keilsfrbits[i].dent); for (i=0; i<128; i++) makeupper(membits[i].dent); for (i=0; i<128; i++) makeupper(keilmembits[i].dent); for (i=0; i<128; i++) makeupper(rbname[i].dent); } k = 0; j = 0xff; skip = TRUE; dump = FALSE; byte_cnt = 0; asc_cnt = 0; newline = FALSE; printf("\nPass 2 0000"); fp = fopen(dst, "w"); // open output source file if (!fp) { printf("\n* Can't open output file %s *\n", dst); exit(FILE_ERROR); } // output header fprintf(fp, ";\n; D52 V%d.%d.%d 8052 Disassembly of %s", VERSION, MAJORREV, MINORREV, src); time(&tp); // get current time date_time = localtime(&tp); // convert to hr/min/day etc year = date_time->tm_year + 1900; fprintf(fp, "\n; %d/%02d/%02d %02d:%02d", year, date_time->tm_mon + 1, date_time->tm_mday, date_time->tm_hour, date_time->tm_min); if (incflag) fprintf(fp, "\n;\n\tinclude\t\"sfr52.inc\""); if (ascii_flag) // if user specified A on command line... { fprintf(fp, "\n;\nascii\tmacro\tx"); // generate macro for text fprintf(fp, "\n\t%s\t'#x#'", defbstr); fprintf(fp, "\n\tendm"); strcpy(ascistr, "ascii"); } // // Generate output file // for (i=offset; i<=himark; ) { if (pgmflags[i] & PF_CMT) { if (byte_cnt) // dump any pending binary dump_bytes(i); if (asc_cnt) // dump any accumulated ascii dump_ascii(i); output_comment(i); } if (pgmflags[i] & PF_PATCH) { if (byte_cnt) // dump any pending binary dump_bytes(i); if (asc_cnt) // dump any accumulated ascii dump_ascii(i); output_patch(i); } oldpc = i; l = i & 0xff; pflag = pgmflags[i]; if (pflag & PF_NOINIT) // ignore un-initialized data { if (byte_cnt) // if binary or ascii data in buffers... dump_bytes(i); // output them now if (asc_cnt) dump_ascii(i); if (dump) // if we had to flush buffers... { // do a newline, since we will dump = FALSE; // be doing an org (or end) fprintf(fp, "\n;"); newline = TRUE; } i++; // next program location skip = TRUE; // flag skip for ORG statement j = -1; } else if (pflag & (PF_ADRS | PF_WORD | PF_BYTE | PF_ASCII)) { // if not executable code if (!(j & 0x80) && !skip) { j = -1; fprintf(fp, "\n;"); newline = TRUE; } switch (pflag & (PF_ADRS | PF_WORD | PF_BYTE | PF_ASCII)) // ignore irrelevant bits { case PF_ASCII: // if ascii text... if (byte_cnt) // dump any pending binary dump_bytes(i); if (skip) // insert ORG statement { if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } if (is_ascii(pgmmem[i])) // if it really is ascii... { string[asc_cnt] = pgmmem[i]; asc_cnt++; if (asc_cnt >= ASCLIMIT) dump_ascii(i + 1); } else // else treat it as binary data { pgmflags[i] |= PF_BYTE; if (asc_cnt) // dump any accumulated ascii dump_ascii(i); byte_data[byte_cnt] = pgmmem[i]; // add data to buffer byte_cnt++; } break; case PF_WORD: // if word data... if (byte_cnt) // dump any binary or ascii in buffers dump_bytes(i); if (asc_cnt) dump_ascii(i); if (skip) // insert ORG statement { if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } chk_label(i); // add label if referenced q = ((int) pgmmem[i] & 0xff) << 8; // get word value temp = pgmmem[i + 1] & 0xff; q |= temp; fprintf(fp, "%s\t", defwstr); cptr = find_entry(q, symbol_count, sym_val_index); // see if symbol exists if (cptr == NULL) // if not, do hex value puthex(q); else fprintf(fp, "%s", cptr); // else output symbol if (hexflag) // add comment field { fprintf(fp, "\t\t; %04x %02x %02x %c%c", i, pgmmem[i], pgmmem[i + 1], ascii(pgmmem[i]), ascii(pgmmem[i + 1])); } if (pgmflags[i] & PF_ICMT) output_icomment(i); i++; if (pgmflags[i + 2] != PF_ADRS && pgmflags[i + 2] != PF_WORD) { fprintf(fp, "\n;"); newline = TRUE; } break; case PF_ADRS: // if address data... if (byte_cnt) // output any pending binary or dump_bytes(i); // ascii data from buffers if (asc_cnt) dump_ascii(i); if (skip) // insert ORG statement { if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } chk_label(i); // add label if referenced q = ((int) pgmmem[i]) << 8; // get address value temp = pgmmem[i + 1] & 0xff; q |= temp; fprintf(fp, "%s\t", defwstr); cptr = find_entry(q, label_count, lab_val_index); // see if label exists if (cptr == NULL) // if not, output hex { if (!pgmflags[i] & PF_LABEL) // search symbol table only if not defined as label cptr = find_entry(q, symbol_count, sym_val_index); if (cptr == NULL) { if (!upperflag) fprintf(fp, "X%04x", q); else fprintf(fp, "X%04X", q); } else fprintf(fp, "%s", cptr); } else fprintf(fp, "%s", cptr); // else output label text if (hexflag) // do comment field { fprintf(fp, "\t\t; %04x %02x %02x %c%c", i, pgmmem[i], pgmmem[i + 1], ascii(pgmmem[i]), ascii(pgmmem[i + 1])); } if (pgmflags[i] & PF_ICMT) output_icomment(i); i++; if (pgmflags[i + 2] != PF_ADRS) { fprintf(fp, "\n;"); newline = TRUE; } break; default: // default = binary data... if (asc_cnt) // output any pending ascii data dump_ascii(i); if (skip) // insert ORG statement { if (byte_cnt) dump_bytes(i); if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } byte_data[byte_cnt] = pgmmem[i]; // add data to buffer byte_cnt++; if (byte_cnt >= BYTELIMIT) // if end of buffer... dump_bytes(i + 1); // dump accumulated data } i++; // next program location if (!(pgmflags[i] & PF_NOINIT) && (pgmflags[i] & PF_ASCII)) { // if next byte is flagged as if (!is_ascii(pgmmem[i])) // ascii, but is not... pgmflags[i] |= PF_BYTE; // then flag it as binary } } // // If previous data was an unconditional transfer, AND // current location is not referenced by some other opcode, AND // current byte is 0 or 0FFH, THEN // treat this byte as un-initialized data. // else if ((j & 0x80) && (!(pflag & PF_REF)) && ((pgmmem[i] == 0) || (pgmmem[i] == NO_DATA)) && (!(pflag & PF_FORCE))) { if (byte_cnt) // since we're going to skip some dump_bytes(i); // data, output any pending ascii if (asc_cnt) // or binary data remaining in buffers dump_ascii(i); if (dump) // if ascii or binary output was done, { // stick in a newline fprintf(fp, "\n;"); dump = FALSE; newline = TRUE; } pgmflags[i] = PF_NOINIT;// flag as uninitialized data i++; skip = TRUE; byte_cnt = 0; } // // If previous opcode was 0 or 0ffH, AND current location is not // referenced but is initialized, AND current opcode is 0 or 0ffH, // un-initialize it. // else if (((k == 0) || (k == 0xff)) && (!(pflag & PF_REF)) && ((pgmmem[i] == 0) || (pgmmem[i] == NO_DATA)) && !(pflag & PF_NOINIT) && !(pflag & PF_FORCE)) { pgmflags[i] = PF_NOINIT; i++; skip = TRUE; j = -1; } else // IT'S EXECUTABLE CODE! { pgmflags[i] &= ~PF_NOINIT; // clear for label search in pass 3 if (byte_cnt) // if any ascii or binary data remains dump_bytes(i); // in the buffers, output them now if (asc_cnt) dump_ascii(i); if (dump) { fprintf(fp, "\n;"); dump = FALSE; newline = TRUE; } byte_cnt = 0; if (cycleflag) // cycle count summary cycle_end(i); if (skip) // insert ORG statement { if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } k = pgmmem[i]; // get opcode if (k == 0xa5 && !newline) // if invalid opcode { fprintf(fp, "\n;"); newline = TRUE; } chk_ref(i); // add label if referenced kcnt = 8; j = opttbl[k]; // get options doopcode(mnemtbl[k].mnem); // output mnemonic // // Generate operands // switch (j & OPT_MASK) { case OPT_NONE: // single byte - no options break; case OPT_IMM2: // 2 byte immediate data q = (int) pgmmem[i + 1] & 0xff; if (pgmflags[i + 1] & PF_NAME) cptr = find_entry(i + 1, name_count, name_val_index); else cptr = find_entry(q, symbol_count, sym_val_index); if (cptr == NULL) puthex(q); else kcnt += fprintf(fp, "%s", cptr); splitcheck(i + 1); break; case OPT_LREF: // 3 byte immediate data q = ((pgmmem[i + 1] & 0xff) << 8) | (pgmmem[i + 2] & 0xff); if (pgmflags[i + 1] & PF_NAME) { pgmflags[i + 1] |= PF_2BYTE; cptr = find_entry(i + 1, name_count, name_val_index); } else { cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { cptr = find_entry(q, symbol_count, sym_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "X%04x", q); else kcnt += fprintf(fp, "X%04X", q); } } } if (cptr != NULL) kcnt += fprintf(fp, "%s", cptr); splitcheck(i + 1); splitcheck(i + 2); break; case OPT_DIR2: // 2 byte direct addressing dodir(fp, i + 1); if ((k & 0xf) == 2 || k == 0xf5) { if (!upperflag) kcnt += fprintf(fp, ",a"); else kcnt += fprintf(fp, ",A"); } else if ((k & 0xf0) == 0x80) { kcnt += fprintf(fp, ","); if (k < 0x88) { if (!upperflag) kcnt += fprintf(fp, "@r%d", k & 1); else kcnt += fprintf(fp, "@R%d", k & 1); } else { if (!upperflag) kcnt += fprintf(fp, "r%d", k & 7); else kcnt += fprintf(fp, "R%d", k & 7); } } splitcheck(i + 1); break; case OPT_DIR3: // mov dir,dir dodir(fp, i + 2); kcnt += fprintf(fp, ","); dodir(fp, i + 1); splitcheck(i + 1); splitcheck(i + 2); break; case OPT_DMM3: // 3 byte direct and immediate addressing dodir(fp, i + 1); kcnt += fprintf(fp, ",#"); q = (int) pgmmem[i + 2] & 0xff; if (pgmflags[i + 2] & PF_NAME) cptr = find_entry(i + 2, name_count, name_val_index); else cptr = find_entry(q, symbol_count, sym_val_index); if (cptr == NULL) puthex(q); else kcnt += fprintf(fp, "%s", cptr); splitcheck(i + 1); splitcheck(i + 2); break; case OPT_BIT2: // 2 byte bit addressing dobit(fp, pgmmem[i + 1]); if (k == 0x92) { if (!upperflag) kcnt += fprintf(fp, ",c"); else kcnt += fprintf(fp, ",C"); } splitcheck(i + 1); break; case OPT_REL2: // 2 byte relative addressing q = pgmmem[i + 1] & 0xff; q = (q > 0x7f) ? q | 0xff00 : q; q = i + 2 + q; q &= WORD_MASK; if (pgmflags[i + 1] & PF_NAME) cptr = find_entry(i + 1, name_count, name_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "X%04x", q); else kcnt += fprintf(fp, "X%04X", q); } else kcnt += fprintf(fp, "%s", cptr); splitcheck(i + 1); break; case OPT_IR3: // 3 byte immediate and relative addressing q = (int) pgmmem[i + 1] & 0xff; if (pgmflags[i + 1] & PF_NAME) cptr = find_entry(i + 1, name_count, name_val_index); else cptr = find_entry(q, symbol_count, sym_val_index); if (cptr == NULL) puthex(q); else kcnt += fprintf(fp, "%s", cptr); q = pgmmem[i + 2] & 0xff; q = (q > 0x7f) ? q | 0xff00 : q; q = i + 3 + q; q &= WORD_MASK; if (pgmflags[i + 2] & PF_NAME) cptr = find_entry(i + 2, name_count, name_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, ",X%04x", q); else kcnt += fprintf(fp, ",X%04X", q); } else kcnt += fprintf(fp, ",%s", cptr); splitcheck(i + 1); splitcheck(i + 2); break; case OPT_DR3: // 3 byte direct and relative addressing dodir(fp, i + 1); q = pgmmem[i + 2] & 0xff; q = (q > 0x7f) ? q | 0xff00 : q; q = i + 3 + q; q &= WORD_MASK; if (pgmflags[i + 2] & PF_NAME) cptr = find_entry(i + 2, name_count, name_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, ",X%04x", q); else kcnt += fprintf(fp, ",X%04X", q); } else kcnt += fprintf(fp, ",%s", cptr); splitcheck(i + 1); splitcheck(i + 2); break; case OPT_RELB: // 3 byte bit and relative addressing dobit(fp, pgmmem[i + 1]); q = pgmmem[i + 2] & 0xff; q = (q > 0x7f) ? q | 0xff00 : q; q = i + 3 + q; q &= WORD_MASK; if (pgmflags[i + 2] & PF_NAME) cptr = find_entry(i + 2, name_count, name_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, ",X%04x", q); else kcnt += fprintf(fp, ",X%04X", q); } else kcnt += fprintf(fp, ",%s", cptr); splitcheck(i + 1); splitcheck(i + 2); break; case OPT_112: // 2 byte 11 bit adrs (ajmp & acall) q = ((k & 0xe0) << 3) | ((i + 2) & 0xf800); q = q | (pgmmem[i + 1] & 0xff); if (pgmflags[i + 1] & PF_NAME) cptr = find_entry(i + 1, name_count, name_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "X%04x", q); else kcnt += fprintf(fp, "X%04X", q); } else kcnt += fprintf(fp, "%s", cptr); splitcheck(i + 1); break; } if (k == 0xa5) // if invalid opcode puthex(k); // put hex defb in file if (cycleflag) // do cycle counting and printout per instruction { while (kcnt < TSTOP) { fprintf(fp, "\t"); kcnt = (kcnt + 8) & 0x78; } cycle_in(i, i + (opttbl[k] & OPT_SIZE) + 1, cycles[pgmmem[i] & 0xff], cycles2[pgmmem[i] & 0xff]); } if (hexflag) // do comment field { while (kcnt < TSTOP) { fprintf(fp, "\t"); kcnt = (kcnt + 8) & 0x78; } fprintf(fp,"; %04x %02x", i, pgmmem[i] & 0xff); switch (opttbl[k] & OPT_SIZE) // additional data bytes { case 0: fprintf(fp, " "); break; case 1: fprintf(fp, " %02x ", pgmmem[i + 1] & 0xff); break; case 2: fprintf(fp, " %02x %02x", pgmmem[i + 1] & 0xff, pgmmem[i + 2] & 0xff); } fprintf(fp, " %c", ascii(pgmmem[i])); switch (opttbl[k] & OPT_SIZE) // additional ascii { case 1: fprintf(fp, "%c", ascii(pgmmem[i + 1])); break; case 2: fprintf(fp, "%c%c", ascii(pgmmem[i + 1]), ascii(pgmmem[i + 2])); } } if (pgmflags[i] & PF_ICMT) output_icomment(i); newline = FALSE; i = i + (opttbl[k] & OPT_SIZE) + 1; // update location counter if (j & OPT_XFER || k == 0xa5) // if unconditional transfer or { // invalid code, add a newline fprintf(fp, "\n;"); newline = TRUE; } } if (i < oldpc) // oops! wrapped around... break; if ((i & 0xff) < l) printf("\rPass 2 %04x", i & 0xff00); } if (cycleflag) // any remaining cycle count summary cycle_end(PMEMSIZE + 1); // specifying a number above any possible // maximum address makes cycle_end to emit all // remaining sums (i would probably suffice, too (?)) if (byte_cnt) // if any remaining ascii or binary, dump_bytes(i); // output it now if (asc_cnt) dump_ascii(i); printf("\rPass 2 - Source generation complete"); // // add equates for register names // j = 0; for (i=0; i<128; i++) { if (dirregs[i] == 3) { if (!j) { if (!newline || dump) fprintf(fp, "\n;"); fprintf(fp, "\n;\tRegister/Memory Equates\n;"); newline = FALSE; } fprintf(fp, "\n%s\t%s\t", &rbname[i].dent[0], equstr); puthex(i); j = 1; } } // // add equates for SFR names // j = 0; for (i=0; i<128; i++) { if (sfrflags[i] && isalpha(sfr[i].dent[0])) { if (!j) { if (!newline || dump) fprintf(fp, "\n;"); fprintf(fp, "\n;\tSFR Equates\n;"); newline = FALSE; } fprintf(fp, "\n%s\t%s\t", &sfr[i].dent[0], equstr); puthex(i + 0x80); j = 1; } } // // add equates for SFR bit names // j = 0; for (i=0; i<128; i++) { if (sbflags[i] && isalpha(sfrbits[i].dent[0])) { if (!j) { if (!newline || dump) fprintf(fp, "\n;"); fprintf(fp, "\n;\tSFR bit Equates\n;"); newline = FALSE; } fprintf(fp, "\n%s\t%s\t", &sfrbits[i].dent[0], equstr); puthex(i + 0x80); j = 1; } } // // add equates for memory bit names // j = 0; for (i=0; i<128; i++) { if (mbflags[i]) { if (!j) { if (!newline || dump) fprintf(fp, "\n;"); fprintf(fp, "\n;\tMemory bit Equates\n;"); newline = FALSE; } if (!keilflag) fprintf(fp, "\n%s\t%s\t", &membits[i].dent[0], equstr); else fprintf(fp, "\n%s\t%s\t", &keilmembits[i].dent[0], equstr); puthex(i); j = 1; } } } // end of Pass 2 // // Output operand for direct addressing // void dodir(FILE *fp, int adrs) { int dir; char *cptr; dir = pgmmem[adrs]; if (pgmflags[adrs] & PF_NAME) { cptr = find_entry(adrs, name_count, name_val_index); kcnt += fprintf(fp, "%s", cptr); } else if (dir < 0x80) { kcnt += fprintf(fp, rbname[dir].dent); dirregs[dir] |= 1; } else { if (keilflag) kcnt += fprintf(fp, "%s", keilsfr[dir & 0x7f].dent); else kcnt += fprintf(fp, "%s", sfr[dir & 0x7f].dent); } } // // Output sfr bit name // void dobit(FILE *fp, int bit) { bit &= 0xff; if (bit < 0x80) { if (!keilflag) kcnt += fprintf(fp, "%s", membits[bit].dent); else kcnt += fprintf(fp, "%s", keilmembits[bit].dent); } else { if (!keilflag) kcnt += fprintf(fp, "%s", sfrbits[bit & 0x7f].dent); else kcnt += fprintf(fp, "%s", keilsfrbits[bit & 0x7f].dent); } } // end of d52pass2.c d52-3.4.1.orig/d52pass2.h0000644000175000017500000000220710666552046012761 0ustar uweuwe /* * D52 8052 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * d52pass2.h - Disassembly pass 2 * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _D52PASS2_H_ #define _D52PASS2_H_ // Prototypes extern void pass2(void); extern void dodir(FILE *fp, int adrs); extern void dobit(FILE *fp, int bit); // Global variables /* none */ #endif // _D52PASS2_H_ d52-3.4.1.orig/d52table.c0000644000175000017500000005741110666553435013025 0ustar uweuwe /* * D52 8052 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * d52table.c - Mnemonic Table * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include "d52.h" struct mnementry mnemtbl[256] = { {"nop "}, {"ajmp "}, {"ljmp "}, {"rr a"}, // 00 - 03 {"inc a"}, {"inc "}, {"inc @r0"}, {"inc @r1"}, // 04 - 07 {"inc r0"}, {"inc r1"}, {"inc r2"}, {"inc r3"}, // 08 - 0b {"inc r4"}, {"inc r5"}, {"inc r6"}, {"inc r7"}, // 0c - 0f {"jbc "}, {"acall "}, {"lcall "}, {"rrc a"}, // 10 - 13 {"dec a"}, {"dec "}, {"dec @r0"}, {"dec @r1"}, // 14 - 17 {"dec r0"}, {"dec r1"}, {"dec r2"}, {"dec r3"}, // 18 - 1b {"dec r4"}, {"dec r5"}, {"dec r6"}, {"dec r7"}, // 1c - 1f {"jb "}, {"ajmp "}, {"ret "}, {"rl a"}, // 20 - 23 {"add a,#"}, {"add a,"}, {"add a,@r0"}, {"add a,@r1"}, // 24 - 27 {"add a,r0"}, {"add a,r1"}, {"add a,r2"}, {"add a,r3"}, // 28 - 2b {"add a,r4"}, {"add a,r5"}, {"add a,r6"}, {"add a,r7"}, // 2c - 2f {"jnb "}, {"acall "}, {"reti "}, {"rlc a"}, // 30 - 33 {"addc a,#"}, {"addc a,"}, {"addc a,@r0"},{"addc a,@r1"}, // 34 - 37 {"addc a,r0"}, {"addc a,r1"}, {"addc a,r2"}, {"addc a,r3"}, // 38 - 3b {"addc a,r4"}, {"addc a,r5"}, {"addc a,r6"}, {"addc a,r7"}, // 3c - 3f {"jc "}, {"ajmp "}, {"orl "}, {"orl "}, // 40 - 43 {"orl a,#"}, {"orl a,"}, {"orl a,@r0"}, {"orl a,@r1"}, // 44 - 47 {"orl a,r0"}, {"orl a,r1"}, {"orl a,r2"}, {"orl a,r3"}, // 48 - 4b {"orl a,r4"}, {"orl a,r5"}, {"orl a,r6"}, {"orl a,r7"}, // 4c - 4f {"jnc "}, {"acall "}, {"anl "}, {"anl "}, // 50 - 53 {"anl a,#"}, {"anl a,"}, {"anl a,@r0"}, {"anl a,@r1"}, // 54 - 57 {"anl a,r0"}, {"anl a,r1"}, {"anl a,r2"}, {"anl a,r3"}, // 58 - 5b {"anl a,r4"}, {"anl a,r5"}, {"anl a,r6"}, {"anl a,r7"}, // 5c - 5f {"jz "}, {"ajmp "}, {"xrl "}, {"xrl "}, // 60 - 63 {"xrl a,#"}, {"xrl a,"}, {"xrl a,@r0"}, {"xrl a,@r1"}, // 64 - 67 {"xrl a,r0"}, {"xrl a,r1"}, {"xrl a,r2"}, {"xrl a,r3"}, // 68 - 6b {"xrl a,r4"}, {"xrl a,r5"}, {"xrl a,r6"}, {"xrl a,r7"}, // 6c - 6f {"jnz "}, {"acall "}, {"orl c,"}, {"jmp @a+dptr"}, // 70 - 73 {"mov a,#"}, {"mov "}, {"mov @r0,#"}, {"mov @r1,#"}, // 74 - 77 {"mov r0,#"}, {"mov r1,#"}, {"mov r2,#"}, {"mov r3,#"}, // 78 - 7b {"mov r4,#"}, {"mov r5,#"}, {"mov r6,#"}, {"mov r7,#"}, // 7c - 7f {"sjmp "}, {"ajmp "}, {"anl c,"}, {"movc a,@a+pc"}, // 80 - 83 {"div ab"}, {"mov "}, {"mov "}, {"mov "}, // 84 - 87 {"mov "}, {"mov "}, {"mov "}, {"mov "}, // 88 - 8b {"mov "}, {"mov "}, {"mov "}, {"mov "}, // 8c - 8f {"mov dptr,#"},{"acall "}, {"mov "}, {"movc a,@a+dptr"}, // 90 -93 {"subb a,#"}, {"subb a,"}, {"subb a,@r0"},{"subb a,@r1"}, // 94 - 97 {"subb a,r0"}, {"subb a,r1"}, {"subb a,r2"}, {"subb a,r3"}, // 98 - 9b {"subb a,r4"}, {"subb a,r5"}, {"subb a,r6"}, {"subb a,r7"}, // 9c - 9f {"orl c,/"}, {"ajmp "}, {"mov c,"}, {"inc dptr"}, // a0 - a3 {"mul ab"}, {"db "}, {"mov @r0,"}, {"mov @r1,"}, // a4 - a7 {"mov r0,"}, {"mov r1,"}, {"mov r2,"}, {"mov r3,"}, // a8 - ab {"mov r4,"}, {"mov r5,"}, {"mov r6,"}, {"mov r7,"}, // ac - af {"anl c,/"}, {"acall "}, {"cpl "}, {"cpl c"}, // b0 - b3 {"cjne a,#"}, {"cjne a,"}, {"cjne @r0,#"},{"cjne @r1,#"}, // b4 - b7 {"cjne r0,#"}, {"cjne r1,#"}, {"cjne r2,#"}, {"cjne r3,#"}, // b8 - bb {"cjne r4,#"}, {"cjne r5,#"}, {"cjne r6,#"}, {"cjne r7,#"}, // bc - bf {"push "}, {"ajmp "}, {"clr "}, {"clr c"}, // c0 - c3 {"swap a"}, {"xch a,"}, {"xch a,@r0"}, {"xch a,@r1"}, // c4 - c7 {"xch a,r0"}, {"xch a,r1"}, {"xch a,r2"}, {"xch a,r3"}, // c8 - cb {"xch a,r4"}, {"xch a,r5"}, {"xch a,r6"}, {"xch a,r7"}, // cc - cf {"pop "}, {"acall "}, {"setb "}, {"setb c"}, // d0 - d3 {"da a"}, {"djnz "}, {"xchd a,@r0"},{"xchd a,@r1"}, // d4 - d7 {"djnz r0,"}, {"djnz r1,"}, {"djnz r2,"}, {"djnz r3,"}, // d8 - db {"djnz r4,"}, {"djnz r5,"}, {"djnz r6,"}, {"djnz r7,"}, // dc - df {"movx a,@dptr"},{"ajmp "}, {"movx a,@r0"},{"movx a,@r1"}, // e0 - e3 {"clr a"}, {"mov a,"}, {"mov a,@r0"}, {"mov a,@r1"}, // e4 - e7 {"mov a,r0"}, {"mov a,r1"}, {"mov a,r2"}, {"mov a,r3"}, // e8 - eb {"mov a,r4"}, {"mov a,r5"}, {"mov a,r6"}, {"mov a,r7"}, // ec - ef {"movx @dptr,a"},{"acall "}, {"movx @r0,a"},{"movx @r1,a"}, // f0 - f3 {"cpl a"}, {"mov "}, {"mov @r0,a"}, {"mov @r1,a"}, // f4 - f7 {"mov r0,a"}, {"mov r1,a"}, {"mov r2,a"}, {"mov r3,a"}, // f8 - fb {"mov r4,a"}, {"mov r5,a"}, {"mov r6,a"}, {"mov r7,a"} // fc - ff } ; /* OPTTBL (option table) entries: bit 7 = unconditional transfer instruction bit 6 = 11 bit addressing bit 5 = relative addressing bit 4 = bit addressing bit 3 = direct addressing bit 2 = immediate data bit 1 = 3 byte instruction bit 0 = 2 byte instruction if entry = 0, instruction is single byte, no options */ unsigned char opttbl[256] = { 0x00, 0xc1, 0x86, 0x00, 0x00, 0x09, 0x00, 0x00, // 00 - 07 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 08 - 0f 0x32, 0x41, 0x06, 0x00, 0x00, 0x09, 0x00, 0x00, // 10 - 17 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 18 - 1f 0x32, 0xc1, 0x80, 0x00, 0x05, 0x09, 0x00, 0x00, // 20 - 27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 28 - 2f 0x32, 0x41, 0x80, 0x00, 0x05, 0x09, 0x00, 0x00, // 30 - 37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 38 - 3f 0x21, 0xc1, 0x09, 0x0e, 0x05, 0x09, 0x00, 0x00, // 40 - 47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 48 - 4f 0x21, 0x41, 0x09, 0x0e, 0x05, 0x09, 0x00, 0x00, // 50 - 57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 58 - 5f 0x21, 0xc1, 0x09, 0x0e, 0x05, 0x09, 0x00, 0x00, // 60 - 67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 68 - 6f 0x21, 0x41, 0x11, 0x80, 0x05, 0x0e, 0x05, 0x05, // 70 - 77 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 78 - 7f 0xa1, 0xc1, 0x11, 0x00, 0x00, 0x0a, 0x09, 0x09, // 80 - 87 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, // 88 - 8f 0x06, 0x41, 0x11, 0x00, 0x05, 0x09, 0x00, 0x00, // 90 - 97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 98 - 9f 0x11, 0xc1, 0x11, 0x00, 0x00, 0x00, 0x09, 0x09, // a0 - a7 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, // a8 - af 0x11, 0x41, 0x11, 0x00, 0x26, 0x2a, 0x26, 0x26, // b0 - b7 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, 0x26, // b8 - bf 0x09, 0xc1, 0x11, 0x00, 0x00, 0x09, 0x00, 0x00, // c0 - c7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // c8 - cf 0x09, 0x41, 0x11, 0x00, 0x00, 0x2a, 0x00, 0x00, // d0 - d7 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // d8 - df 0x00, 0xc1, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, // e0 - e7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // e8 - ef 0x00, 0x41, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, // f0 - f7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // f8 - ff } ; // Names for Special Function Registers struct sfrentry sfr[128] = { {"p0"}, {"sp"}, {"dpl"}, {"dph"}, // 80 - 83 {"adat"}, {"85h"}, {"86h"}, {"pcon"}, // 84 - 87 {"tcon"}, {"tmod"}, {"tl0"}, {"tl1"}, // 88 - 8b {"th0"}, {"th1"}, {"pwcm"}, {"pwmp"}, // 8a - 8f {"p1"}, {"91h"}, {"92h"}, {"93h"}, // 90 - 93 {"94h"}, {"95h"}, {"96h"}, {"97h"}, // 94 - 97 {"scon"}, {"sbuf"}, {"9ah"}, {"9bh"}, // 98 - 9b {"9ch"}, {"9dh"}, {"9eh"}, {"9fh"}, // 9c - 9f {"p2"}, {"0a1h"}, {"0a2h"}, {"0a3h"}, // a0 - a3 {"0a4h"}, {"0a5h"}, {"0a6h"}, {"0a7h"}, // a4 - a7 {"ie"}, {"cml0"}, {"cml1"}, {"cml2"}, // a8 - ab {"ctl0"}, {"ctl1"}, {"ctl2"}, {"ctl3"}, // ac - af {"p3"}, {"0b1h"}, {"0b2h"}, {"0b3h"}, // b0 - b3 {"0b4h"}, {"0b5h"}, {"0b6h"}, {"0b7h"}, // b4 - b7 {"ip"}, {"0b9h"}, {"0bah"}, {"0bbh"}, // b8 - bb {"0bch"}, {"0bdh"}, {"0beh"}, {"0bfh"}, // bc - bf {"p4"}, {"0c1h"}, {"0c2h"}, {"0c3h"}, // c0 - c3 {"p5"}, {"adcon"}, {"adch"}, {"0c7h"}, // c4 - c7 {"t2con"}, {"cmh0"}, {"rcap2l"}, {"rcap2h"}, // c8 - cb {"tl2"}, {"th2"}, {"cth2"}, {"cth3"}, // cc - cf {"psw"}, {"0d1h"}, {"0d2h"}, {"0d3h"}, // d0 - d3 {"0d4h"}, {"0d5h"}, {"0d6h"}, {"0d7h"}, // d4 - d7 {"i2cfg"}, {"s1sta"}, {"s1dat"}, {"s1adr"}, // d8 - db {"0dch"}, {"0ddh"}, {"0deh"}, {"0dfh"}, // dc - df {"acc"}, {"0e1h"}, {"0e2h"}, {"0e3h"}, // e0 - e3 {"0e4h"}, {"0e5h"}, {"0e6h"}, {"0e7h"}, // e4 - e7 {"csr"}, {"0e9h"}, {"tm2con"}, {"ctcon"}, // e8 - eb {"tml2"}, {"tmh2"}, {"ste"}, {"rte"}, // ec - ef {"b"}, {"0f1h"}, {"0f2h"}, {"0f3h"}, // f0 - f3 {"0f4h"}, {"0f5h"}, {"0f6h"}, {"0f7h"}, // f4 - f7 {"i2sta"}, {"0f9h"}, {"0fah"}, {"0fbh"}, // f8 - fb {"pwm0"}, {"pwm1"}, {"pwena"}, {"t3"} // fc - ff } ; // Names for Special Function Registers for Keil A51 compatibility struct sfrentry keilsfr[128] = { {"p0"}, {"sp"}, {"dpl"}, {"dph"}, // 80 - 83 {"84h"}, {"85h"}, {"86h"}, {"pcon"}, // 84 - 87 {"tcon"}, {"tmod"}, {"tl0"}, {"tl1"}, // 88 - 8b {"th0"}, {"th1"}, {"8eh"}, {"8fh"}, // 8a - 8f {"p1"}, {"91h"}, {"92h"}, {"93h"}, // 90 - 93 {"94h"}, {"95h"}, {"96h"}, {"97h"}, // 94 - 97 {"scon"}, {"sbuf"}, {"9ah"}, {"9bh"}, // 98 - 9b {"9ch"}, {"9dh"}, {"9eh"}, {"9fh"}, // 9c - 9f {"p2"}, {"0a1h"}, {"0a2h"}, {"0a3h"}, // a0 - a3 {"0a4h"}, {"0a5h"}, {"0a6h"}, {"0a7h"}, // a4 - a7 {"ie"}, {"0a9h"}, {"0aah"}, {"0abh"}, // a8 - ab {"0ach"}, {"0adh"}, {"0aeh"}, {"0afh"}, // ac - af {"p3"}, {"0b1h"}, {"0b2h"}, {"0b3h"}, // b0 - b3 {"0b4h"}, {"0b5h"}, {"0b6h"}, {"0b7h"}, // b4 - b7 {"ip"}, {"0b9h"}, {"0bah"}, {"0bbh"}, // b8 - bb {"0bch"}, {"0bdh"}, {"0beh"}, {"0bfh"}, // bc - bf {"0c0h"}, {"0c1h"}, {"0c2h"}, {"0c3h"}, // c0 - c3 {"0c4h"}, {"0c5h"}, {"0c6h"}, {"0c7h"}, // c4 - c7 {"0c8h"}, {"0c9h"}, {"0cah"}, {"0cbh"}, // c8 - cb {"0cch"}, {"0cdh"}, {"0ceh"}, {"0cfh"}, // cc - cf {"psw"}, {"0d1h"}, {"0d2h"}, {"0d3h"}, // d0 - d3 {"0d4h"}, {"0d5h"}, {"0d6h"}, {"0d7h"}, // d4 - d7 {"0d8h"}, {"0d9h"}, {"0dah"}, {"0dbh"}, // d8 - db {"0dch"}, {"0ddh"}, {"0deh"}, {"0dfh"}, // dc - df {"acc"}, {"0e1h"}, {"0e2h"}, {"0e3h"}, // e0 - e3 {"0e4h"}, {"0e5h"}, {"0e6h"}, {"0e7h"}, // e4 - e7 {"0e8h"}, {"0e9h"}, {"0eah"}, {"0ebh"}, // e8 - eb {"0ech"}, {"0edh"}, {"0eeh"}, {"0efh"}, // ec - ef {"b"}, {"0f1h"}, {"0f2h"}, {"0f3h"}, // f0 - f3 {"0f4h"}, {"0f5h"}, {"0f6h"}, {"0f7h"}, // f4 - f7 {"i2sta"}, {"0f9h"}, {"0fah"}, {"0fbh"}, // f8 - fb {"0fch"}, {"0fdh"}, {"0feh"}, {"0ffh"} // fc - ff } ; // Names for Special Function Register bits struct sfrentry sfrbits[128] = { {"p0.0"}, {"p0.1"}, {"p0.2"}, {"p0.3"}, // 80 - 83 {"p0.4"}, {"p0.5"}, {"p0.6"}, {"p0.7"}, // 84 - 87 {"it0"}, {"ie0"}, {"it1"}, {"ie1"}, // 88 - 8b {"tr0"}, {"tf0"}, {"tr1"}, {"tf1"}, // 8c - 8f {"p1.0"}, {"p1.1"}, {"p1.2"}, {"p1.3"}, // 90 - 93 {"p1.4"}, {"p1.5"}, {"p1.6"}, {"p1.7"}, // 94 - 97 {"ri"}, {"ti"}, {"rb8"}, {"tb8"}, // 98 - 9b {"ren"}, {"sm2"}, {"sm1"}, {"sm0"}, // 9c - 9f {"p2.0"}, {"p2.1"}, {"p2.2"}, {"p2.3"}, // a0 - a3 {"p2.4"}, {"p2.5"}, {"p2.6"}, {"p2.7"}, // a4 - a7 {"ex0"}, {"et0"}, {"ex1"}, {"et1"}, // a8 - ab {"es"}, {"ie.5"}, {"ie.6"}, {"ea"}, // ac - af {"rxd"}, {"txd"}, {"int0"}, {"int1"}, // b0 - b3 {"t0"}, {"t1"}, {"wr"}, {"rd"}, // b4 - b7 {"px0"}, {"pt0"}, {"px1"}, {"pt1"}, // b8 - bb {"ps"}, {"ip.5"}, {"ip.6"}, {"ip.7"}, // bc - bf {"0c0h.0"}, {"0c0h.1"}, {"0c0h.2"}, {"0c0h.3"}, // c0 - c3 {"0c0h.4"}, {"0c0h.5"}, {"0c0h.6"}, {"0c0h.7"}, // c4 - c7 {"cprl2"}, {"ct2"}, {"tr2"}, {"exen2"}, // c8 - cb {"tclk"}, {"rclk"}, {"exf2"}, {"tf2"}, // cc - cf {"p"}, {"psw.1"}, {"ov"}, {"rs0"}, // d0 - d3 {"rs1"}, {"f0"}, {"ac"}, {"cy"}, // d4 - d7 {"ct0"}, {"ct1"}, {"i2cfg.2"},{"i2cfg.3"},// d8 - db {"tirun"}, {"clrti"}, {"mastrq"}, {"slaven"}, // dc - df {"acc.0"}, {"acc.1"}, {"acc.2"}, {"acc.3"}, // e0 - e3 {"acc.4"}, {"acc.5"}, {"acc.6"}, {"acc.7"}, // e4 - e7 {"ibf"}, {"obf"}, {"idsm"}, {"obfc"}, // e8 - eb {"ma0"}, {"ma1"}, {"mb0"}, {"mb1"}, // ec - ef {"b.0"}, {"b.1"}, {"b.2"}, {"b.3"}, // f0 - f3 {"b.4"}, {"b.5"}, {"b.6"}, {"b.7"}, // f4 - f7 {"xstp"}, {"xstr"}, {"makstp"}, {"makstr"}, // f8 - fb {"xactv"}, {"xdata"}, {"idle"}, {"i2sta.7"} // fc - ff } ; // Names for Special Function Register bits for Keil A51 compatibility struct sfrentry keilsfrbits[128] = { {"p0.0"}, {"p0.1"}, {"p0.2"}, {"p0.3"}, // 80 - 83 {"p0.4"}, {"p0.5"}, {"p0.6"}, {"p0.7"}, // 84 - 87 {"it0"}, {"ie0"}, {"it1"}, {"ie1"}, // 88 - 8b {"tr0"}, {"tf0"}, {"tr1"}, {"tf1"}, // 8c - 8f {"p1.0"}, {"p1.1"}, {"p1.2"}, {"p1.3"}, // 90 - 93 {"p1.4"}, {"p1.5"}, {"p1.6"}, {"p1.7"}, // 94 - 97 {"ri"}, {"ti"}, {"rb8"}, {"tb8"}, // 98 - 9b {"ren"}, {"sm2"}, {"sm1"}, {"sm0"}, // 9c - 9f {"p2.0"}, {"p2.1"}, {"p2.2"}, {"p2.3"}, // a0 - a3 {"p2.4"}, {"p2.5"}, {"p2.6"}, {"p2.7"}, // a4 - a7 {"ex0"}, {"et0"}, {"ex1"}, {"et1"}, // a8 - ab {"es"}, {"ie.5"}, {"ie.6"}, {"ea"}, // ac - af {"rxd"}, {"txd"}, {"int0"}, {"int1"}, // b0 - b3 {"t0"}, {"t1"}, {"wr"}, {"rd"}, // b4 - b7 {"px0"}, {"pt0"}, {"px1"}, {"pt1"}, // b8 - bb {"ps"}, {"ip.5"}, {"ip.6"}, {"ip.7"}, // bc - bf {"0c0h.0"}, {"0c0h.1"}, {"0c0h.2"}, {"0c0h.3"}, // c0 - c3 {"0c0h.4"}, {"0c0h.5"}, {"0c0h.6"}, {"0c0h.7"}, // c4 - c7 {"0c8h.0"}, {"0c8h.1"}, {"0c8h.2"}, {"0c8h.3"}, // c8 - cb {"0c8h.4"}, {"0c8h.5"}, {"0c8h.6"}, {"0c8h.7"}, // cc - cf {"p"}, {"psw.1"}, {"ov"}, {"rs0"}, // d0 - d3 {"rs1"}, {"f0"}, {"ac"}, {"cy"}, // d4 - d7 {"0d8h.0"}, {"0d8h.1"}, {"0d8h.2"}, {"0d8h.3"}, // d8 - db {"0d8h.4"}, {"0d8h.5"}, {"0d8h.6"}, {"0d8h.7"}, // dc - df {"acc.0"}, {"acc.1"}, {"acc.2"}, {"acc.3"}, // e0 - e3 {"acc.4"}, {"acc.5"}, {"acc.6"}, {"acc.7"}, // e4 - e7 {"0e8h.0"}, {"0e8h.1"}, {"0e8h.2"}, {"0e8h.3"}, // e8 - eb {"0e8h.4"}, {"0e8h.5"}, {"0e8h.6"}, {"0e8h.7"}, // ec - ef {"b.0"}, {"b.1"}, {"b.2"}, {"b.3"}, // f0 - f3 {"b.4"}, {"b.5"}, {"b.6"}, {"b.7"}, // f4 - f7 {"0f8h.0"}, {"0f8h.1"}, {"0f8h.2"}, {"0f8h.3"}, // f8 - fb {"0f8h.4"}, {"0f8h.5"}, {"0f8h.6"}, {"0f8h.7"} // fc - ff } ; // Names for bit addressable memory struct sfrentry membits[128] = { {"20h.0"}, {"20h.1"}, {"20h.2"}, {"20h.3"}, {"20h.4"}, {"20h.5"}, {"20h.6"}, {"20h.7"}, {"21h.0"}, {"21h.1"}, {"21h.2"}, {"21h.3"}, {"21h.4"}, {"21h.5"}, {"21h.6"}, {"21h.7"}, {"22h.0"}, {"22h.1"}, {"22h.2"}, {"22h.3"}, {"22h.4"}, {"22h.5"}, {"22h.6"}, {"22h.7"}, {"23h.0"}, {"23h.1"}, {"23h.2"}, {"23h.3"}, {"23h.4"}, {"23h.5"}, {"23h.6"}, {"23h.7"}, {"24h.0"}, {"24h.1"}, {"24h.2"}, {"24h.3"}, {"24h.4"}, {"24h.5"}, {"24h.6"}, {"24h.7"}, {"25h.0"}, {"25h.1"}, {"25h.2"}, {"25h.3"}, {"25h.4"}, {"25h.5"}, {"25h.6"}, {"25h.7"}, {"26h.0"}, {"26h.1"}, {"26h.2"}, {"26h.3"}, {"26h.4"}, {"26h.5"}, {"26h.6"}, {"26h.7"}, {"27h.0"}, {"27h.1"}, {"27h.2"}, {"27h.3"}, {"27h.4"}, {"27h.5"}, {"27h.6"}, {"27h.7"}, {"28h.0"}, {"28h.1"}, {"28h.2"}, {"28h.3"}, {"28h.4"}, {"28h.5"}, {"28h.6"}, {"28h.7"}, {"29h.0"}, {"29h.1"}, {"29h.2"}, {"29h.3"}, {"29h.4"}, {"29h.5"}, {"29h.6"}, {"29h.7"}, {"2ah.0"}, {"2ah.1"}, {"2ah.2"}, {"2ah.3"}, {"2ah.4"}, {"2ah.5"}, {"2ah.6"}, {"2ah.7"}, {"2bh.0"}, {"2bh.1"}, {"2bh.2"}, {"2bh.3"}, {"2bh.4"}, {"2bh.5"}, {"2bh.6"}, {"2bh.7"}, {"2ch.0"}, {"2ch.1"}, {"2ch.2"}, {"2ch.3"}, {"2ch.4"}, {"2ch.5"}, {"2ch.6"}, {"2ch.7"}, {"2dh.0"}, {"2dh.1"}, {"2dh.2"}, {"2dh.3"}, {"2dh.4"}, {"2dh.5"}, {"2dh.6"}, {"2dh.7"}, {"2eh.0"}, {"2eh.1"}, {"2eh.2"}, {"2eh.3"}, {"2eh.4"}, {"2eh.5"}, {"2eh.6"}, {"2eh.7"}, {"2fh.0"}, {"2fh.1"}, {"2fh.2"}, {"2fh.3"}, {"2fh.4"}, {"2fh.5"}, {"2fh.6"}, {"2fh.7"}, }; // Names for bit addressable memory for Keil A51 compatibility struct sfrentry keilmembits[128] = { {"00h.0"}, {"00h.1"}, {"00h.2"}, {"00h.3"}, {"00h.4"}, {"00h.5"}, {"00h.6"}, {"00h.7"}, {"08h.0"}, {"08h.1"}, {"08h.2"}, {"08h.3"}, {"08h.4"}, {"08h.5"}, {"08h.6"}, {"08h.7"}, {"10h.0"}, {"10h.1"}, {"10h.2"}, {"10h.3"}, {"10h.4"}, {"10h.5"}, {"10h.6"}, {"10h.7"}, {"18h.0"}, {"18h.1"}, {"18h.2"}, {"18h.3"}, {"18h.4"}, {"18h.5"}, {"18h.6"}, {"18h.7"}, {"20h.0"}, {"20h.1"}, {"20h.2"}, {"20h.3"}, {"20h.4"}, {"20h.5"}, {"20h.6"}, {"20h.7"}, {"28h.0"}, {"28h.1"}, {"28h.2"}, {"28h.3"}, {"28h.4"}, {"28h.5"}, {"28h.6"}, {"28h.7"}, {"30h.0"}, {"30h.1"}, {"30h.2"}, {"30h.3"}, {"30h.4"}, {"30h.5"}, {"30h.6"}, {"30h.7"}, {"38h.0"}, {"38h.1"}, {"38h.2"}, {"38h.3"}, {"38h.4"}, {"38h.5"}, {"38h.6"}, {"38h.7"}, {"40h.0"}, {"40h.1"}, {"40h.2"}, {"40h.3"}, {"40h.4"}, {"40h.5"}, {"40h.6"}, {"40h.7"}, {"48h.0"}, {"48h.1"}, {"48h.2"}, {"48h.3"}, {"48h.4"}, {"48h.5"}, {"48h.6"}, {"48h.7"}, {"50h.0"}, {"50h.1"}, {"50h.2"}, {"50h.3"}, {"50h.4"}, {"50h.5"}, {"50h.6"}, {"50h.7"}, {"58h.0"}, {"58h.1"}, {"58h.2"}, {"58h.3"}, {"58h.4"}, {"58h.5"}, {"58h.6"}, {"58h.7"}, {"60h.0"}, {"60h.1"}, {"60h.2"}, {"60h.3"}, {"60h.4"}, {"60h.5"}, {"60h.6"}, {"60h.7"}, {"68h.0"}, {"68h.1"}, {"68h.2"}, {"68h.3"}, {"68h.4"}, {"68h.5"}, {"68h.6"}, {"68h.7"}, {"70h.0"}, {"70h.1"}, {"70h.2"}, {"70h.3"}, {"70h.4"}, {"70h.5"}, {"70h.6"}, {"70h.7"}, {"78h.0"}, {"78h.1"}, {"78h.2"}, {"78h.3"}, {"78h.4"}, {"78h.5"}, {"78h.6"}, {"78h.7"}, }; // Names for direct addressing of registers and internal data memory struct sfrentry rbname[128] = { {"rb0r0"}, {"rb0r1"}, {"rb0r2"}, {"rb0r3"}, {"rb0r4"}, {"rb0r5"}, {"rb0r6"}, {"rb0r7"}, {"rb1r0"}, {"rb1r1"}, {"rb1r2"}, {"rb1r3"}, {"rb1r4"}, {"rb1r5"}, {"rb1r6"}, {"rb1r7"}, {"rb2r0"}, {"rb2r1"}, {"rb2r2"}, {"rb2r3"}, {"rb2r4"}, {"rb2r5"}, {"rb2r6"}, {"rb2r7"}, {"rb3r0"}, {"rb3r1"}, {"rb3r2"}, {"rb3r3"}, {"rb3r4"}, {"rb3r5"}, {"rb3r6"}, {"rb3r7"}, {"20h"}, {"21h"}, {"22h"}, {"23h"}, {"24h"}, {"25h"}, {"26h"}, {"27h"}, {"28h"}, {"29h"}, {"2ah"}, {"2bh"}, {"2ch"}, {"2dh"}, {"2eh"}, {"2fh"}, {"30h"}, {"31h"}, {"32h"}, {"33h"}, {"34h"}, {"35h"}, {"36h"}, {"37h"}, {"38h"}, {"39h"}, {"3ah"}, {"3bh"}, {"3ch"}, {"3dh"}, {"3eh"}, {"3fh"}, {"40h"}, {"41h"}, {"42h"}, {"43h"}, {"44h"}, {"45h"}, {"46h"}, {"47h"}, {"48h"}, {"49h"}, {"4ah"}, {"4bh"}, {"4ch"}, {"4dh"}, {"4eh"}, {"4fh"}, {"50h"}, {"51h"}, {"52h"}, {"53h"}, {"54h"}, {"55h"}, {"56h"}, {"57h"}, {"58h"}, {"59h"}, {"5ah"}, {"5bh"}, {"5ch"}, {"5dh"}, {"5eh"}, {"5fh"}, {"60h"}, {"61h"}, {"62h"}, {"63h"}, {"64h"}, {"65h"}, {"66h"}, {"67h"}, {"68h"}, {"69h"}, {"6ah"}, {"6bh"}, {"6ch"}, {"6dh"}, {"6eh"}, {"6fh"}, {"70h"}, {"71h"}, {"72h"}, {"73h"}, {"74h"}, {"75h"}, {"76h"}, {"77h"}, {"78h"}, {"79h"}, {"7ah"}, {"7bh"}, {"7ch"}, {"7dh"}, {"7eh"}, {"7fh"}, }; // Default cycles for standard 8051 unsigned char cycles[256] = { 1,2,2,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 00-0f 2,2,2,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 10-1f 2,2,2,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 20-2f 2,2,2,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 30-3f 2,2,1,2, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 40-4f 2,2,1,2, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 50-5f 2,2,1,2, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 60-6f 2,2,2,2, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 70-7f 2,2,2,2, 4,2,2,2, 2,2,2,2, 2,2,2,2, // 80-8f 2,2,2,2, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 90-9f 2,2,1,2, 4,1,2,2, 2,2,2,2, 2,2,2,2, // a0-af 2,2,1,1, 2,2,2,2, 2,2,2,2, 2,2,2,2, // b0-bf 2,2,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // c0-cf 2,2,1,1, 1,2,1,1, 2,2,2,2, 2,2,2,2, // d0-df 2,2,2,2, 1,1,1,1, 1,1,1,1, 1,1,1,1, // e0-ef 2,2,2,2, 1,1,1,1, 1,1,1,1, 1,1,1,1 // f0-ff }; // alternative table for "taken" in conditional, and // "non-last autorepeated (BC>0)" cycles (latter not in '51, but Z80) // this default table is the same as cycles[] as it is true for the vanilla 8051 unsigned char cycles2[256] = { 1,2,2,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 00-0f 2,2,2,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 10-1f 2,2,2,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 20-2f 2,2,2,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 30-3f 2,2,1,2, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 40-4f 2,2,1,2, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 50-5f 2,2,1,2, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 60-6f 2,2,2,2, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 70-7f 2,2,2,2, 4,2,2,2, 2,2,2,2, 2,2,2,2, // 80-8f 2,2,2,2, 1,1,1,1, 1,1,1,1, 1,1,1,1, // 90-9f 2,2,1,2, 4,1,2,2, 2,2,2,2, 2,2,2,2, // a0-af 2,2,1,1, 2,2,2,2, 2,2,2,2, 2,2,2,2, // b0-bf 2,2,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1, // c0-cf 2,2,1,1, 1,2,1,1, 2,2,2,2, 2,2,2,2, // d0-df 2,2,2,2, 1,1,1,1, 1,1,1,1, 1,1,1,1, // e0-ef 2,2,2,2, 1,1,1,1, 1,1,1,1, 1,1,1,1 // f0-ff }; // end of d52table.c d52-3.4.1.orig/d52table.h0000644000175000017500000000264510666552075013030 0ustar uweuwe /* * D52 8052 Disassembler * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * d52table.h - 8052 disassembly tables * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _D52TABLE_H_ #define _D52TABLE_H_ // Defined Constants /* none */ // Prototypes /* none */ // Global Variables extern struct mnementry mnemtbl[256]; extern unsigned char opttbl[256]; extern struct sfrentry sfr[128]; extern struct sfrentry keilsfr[128]; extern struct sfrentry sfrbits[128]; extern struct sfrentry keilsfrbits[128]; extern struct sfrentry membits[128]; extern struct sfrentry keilmembits[128]; extern struct sfrentry rbname[128]; #endif // _D52TABLE_H_ d52-3.4.1.orig/d80table.c0000664000175000017500000002015010666553451013014 0ustar uweuwe /* * 8080/8085 Disassembler * Copyright (C) 1990-2007 by Jeffery L. Post * j_post pacbell net * * d80table.c - Mnemonic Tables * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "dz80.h" // blank entries are defb invalid opcodes struct mnementry mnemtbl80[] = { {"nop"}, {"lxi b,"}, {"stax b"}, {"inx b"}, // 00 - 03 {"inr b"}, {"dcr b"}, {"mvi b,"}, {"rlc"}, // 04 - 07 {""}, {"dad b"}, {"ldax b"}, {"dcx b"}, // 08 - 0b {"inr c"}, {"dcr c"}, {"mvi c,"}, {"rrc"}, // 0c - 0f {""}, {"lxi d,"}, {"stax d"}, {"inx d"}, // 10 - 13 {"inr d"}, {"dcr d"}, {"mvi d,"}, {"ral"}, // 14 - 17 {""}, {"dad d"}, {"ldax d"}, {"dcx d"}, // 18 - 1b {"inr e"}, {"dcr e"}, {"mvi e,"}, {"rar"}, // 1c - 1f {"rim"}, {"lxi h,"}, {"shld "}, {"inx h"}, // 20 - 23 {"inr h"}, {"dcr h"}, {"mvi h,"}, {"daa"}, // 24 - 27 {""}, {"dad h"}, {"lhld "}, {"dcx h"}, // 28 - 2b {"inr l"}, {"dcr l"}, {"mvi l,"}, {"cma"}, // 2c - 2f {"sim"}, {"lxi sp,"}, {"sta "}, {"inx sp"}, // 30 - 33 {"inr m"}, {"dcr m"}, {"mvi m,"}, {"stc"}, // 34 - 37 {""}, {"dad sp"}, {"lda "}, {"dcx sp"}, // 38 - 3b {"inr a"}, {"dcr a"}, {"mvi a,"}, {"cmc"}, // 3c - 3f {"mov b,b"}, {"mov b,c"}, {"mov b,d"}, {"mov b,e"},// 40 - 43 {"mov b,h"}, {"mov b,l"}, {"mov b,m"}, {"mov b,a"},// 44 - 47 {"mov c,b"}, {"mov c,c"}, {"mov c,d"}, {"mov c,e"},// 48 - 4b {"mov c,h"}, {"mov c,l"}, {"mov c,m"}, {"mov c,a"},// 4c - 4f {"mov d,b"}, {"mov d,c"}, {"mov d,d"}, {"mov d,e"},// 50 - 53 {"mov d,h"}, {"mov d,l"}, {"mov d,m"}, {"mov d,a"},// 54 - 57 {"mov e,b"}, {"mov e,c"}, {"mov e,d"}, {"mov e,e"},// 58 - 5b {"mov e,h"}, {"mov e,l"}, {"mov e,m"}, {"mov e,a"},// 5c - 5f {"mov h,b"}, {"mov h,c"}, {"mov h,d"}, {"mov h,e"},// 60 - 63 {"mov h,h"}, {"mov h,l"}, {"mov h,m"}, {"mov h,a"},// 64 - 67 {"mov l,b"}, {"mov l,c"}, {"mov l,d"}, {"mov l,e"},// 68 - 6b {"mov l,h"}, {"mov l,l"}, {"mov l,m"}, {"mov l,a"},// 6c - 6f {"mov m,b"}, {"mov m,c"}, {"mov m,d"}, {"mov m,e"},// 70 - 73 {"mov m,h"}, {"mov m,l"}, {"hlt"}, {"mov m,a"},// 74 - 77 {"mov a,b"}, {"mov a,c"}, {"mov a,d"}, {"mov a,e"},// 78 - 7b {"mov a,h"}, {"mov a,l"}, {"mov a,m"}, {"mov a,a"},// 7c - 7f {"add b"}, {"add c"}, {"add d"}, {"add e"}, // 80 - 83 {"add h"}, {"add l"}, {"add m"}, {"add a"}, // 84 - 87 {"adc b"}, {"adc c"}, {"adc d"}, {"adc e"}, // 88 - 8b {"adc h"}, {"adc l"}, {"adc m"}, {"adc a"}, // 8c - 8f {"sub b"}, {"sub c"}, {"sub d"}, {"sub e"}, // 90 - 93 {"sub h"}, {"sub l"}, {"sub m"}, {"sub a"}, // 94 - 97 {"sbb b"}, {"sbb c"}, {"sbb d"}, {"sbb e"}, // 98 - 9b {"sbb h"}, {"sbb l"}, {"sbb m"}, {"sbb a"}, // 9c - 9f {"ana b"}, {"ana c"}, {"ana d"}, {"ana e"}, // a0 - a3 {"ana h"}, {"ana l"}, {"ana m"}, {"ana a"}, // a4 - a7 {"xra b"}, {"xra c"}, {"xra d"}, {"xra e"}, // a8 - ab {"xra h"}, {"xra l"}, {"xra m"}, {"xra a"}, // ac - af {"ora b"}, {"ora c"}, {"ora d"}, {"ora e"}, // a0 - a3 {"ora h"}, {"ora l"}, {"ora m"}, {"ora a"}, // a4 - a7 {"cmp b"}, {"cmp c"}, {"cmp d"}, {"cmp e"}, // a8 - ab {"cmp h"}, {"cmp l"}, {"cmp m"}, {"cmp a"}, // ac - af {"rnz"}, {"pop b"}, {"jnz "}, {"jmp "}, // c0 - c3 {"cnz "}, {"push b"}, {"adi "}, {"rst 0"}, // c4 - c7 {"rz"}, {"ret"}, {"jz "}, {""}, // c8 - cb {"cz "}, {"call "}, {"aci "}, {"rst 1"}, // cc - cf {"rnc"}, {"pop d"}, {"jnc "}, {"out "}, // d0 - d3 {"cnc "}, {"push d"}, {"sui "}, {"rst 2"}, // d4 - d7 {"rc"}, {""}, {"jc "}, {"in "}, // d8 - db {"cc "}, {""}, {"sbi "}, {"rst 3"}, // dc - df {"rpo"}, {"pop h"}, {"jpo "}, {"xthl"}, // e0 - e3 {"cpo "}, {"push h"}, {"ani "}, {"rst 4"}, // e4 - e7 {"rpe"}, {"pchl"}, {"jpe "}, {"xchg"}, // e8 - eb {"cpe "}, {""}, {"xri "}, {"rst 5"}, // ec - ef {"rp"}, {"pop psw"}, {"jp "}, {"di"}, // f0 - f3 {"cp "}, {"push psw"}, {"ori "}, {"rst 6"}, // f4 - f7 {"rm"}, {"sphl"}, {"jm "}, {"ei"}, // f8 - fb {"cm "}, {""}, {"cpi "}, {"rst 7"} // fc - ff } ; /* OPTTBL (option table) entries: bit 7 = unconditional transfer instruction bit 6 = unused bit 5 = unused bit 4 = direct reference (jmp, call, etc) bit 3 = invalid opcode (defb) bit 2 = immediate data bit 1 = 3 byte instruction bit 0 = 2 byte instruction if entry = 0, instruction is single byte, no options */ unsigned char opttbl80[] = { 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, // 00 - 07 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, // 08 - 0f 0x08, 0x16, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, // 10 - 17 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, // 18 - 1f 0x00, 0x16, 0x16, 0x00, 0x00, 0x00, 0x05, 0x00, // 20 - 27 0x08, 0x00, 0x16, 0x00, 0x00, 0x00, 0x05, 0x00, // 28 - 2f 0x00, 0x16, 0x16, 0x00, 0x00, 0x00, 0x05, 0x00, // 30 - 37 0x08, 0x00, 0x16, 0x00, 0x00, 0x00, 0x05, 0x00, // 38 - 3f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 40 - 47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 48 - 4f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 50 - 57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 58 - 5f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 60 - 67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 68 - 6f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, // 70 - 77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 78 - 7f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 80 - 87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 88 - 8f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 90 - 97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 98 - 9f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // a0 - a7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // a8 - af 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // b0 - b7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // b8 - bf 0x00, 0x00, 0x16, 0x96, 0x16, 0x00, 0x05, 0x00, // c0 - c7 0x00, 0x80, 0x16, 0x08, 0x16, 0x16, 0x05, 0x00, // c8 - cf 0x00, 0x00, 0x16, 0x05, 0x16, 0x00, 0x05, 0x00, // d0 - d7 0x00, 0x08, 0x16, 0x05, 0x16, 0x08, 0x05, 0x00, // d8 - df 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x05, 0x00, // e0 - e7 0x00, 0x80, 0x16, 0x00, 0x16, 0x08, 0x05, 0x00, // e8 - ef 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x05, 0x00, // f0 - f7 0x00, 0x00, 0x16, 0x00, 0x16, 0x08, 0x05, 0x00 // f8 - ff } ; // end of d80table.c d52-3.4.1.orig/d80table.h0000664000175000017500000000206510666552715013030 0ustar uweuwe /* * 8080/8085 Disassembler * Copyright (C) 1990-2007 by Jeffery L. Post * j_post pacbell net * * d80table.h - 8080 disassembler tables * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _D80TABLE_H_ #define _D80TABLE_H_ extern struct mnementry mnemtbl80[]; extern unsigned char opttbl80[]; #endif // _D80TABLE_H_ d52-3.4.1.orig/defs.h0000644000175000017500000001072210666552621012337 0ustar uweuwe /* * Disassembler common definitions * Copyright (C) 2007 by Jeffery L. Post * j_post pacbell net * * defs.h - Disassmbler constants and structures * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _DEFS_H_ #define _DEFS_H_ // Defined Constants #define VERSION 3 #define MAJORREV 4 #define MINORREV 1 //#define ALPHA 1 //#define BETA 1 #define YEAR 2007 #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif #define byte unsigned char #define bool int #define WORD_MASK 0xffff #define FN_LEN 256 #define MAX_LINE 256 #define TSTOP 32 // tab stop #define ASTOP 56 // ascii stop #define XSTOP 49 // hex stop #define PMEMSIZE 65536 // program memory size #define EITHERFILE 0 #define HEXFILE 1 #define BINFILE 2 #define CPMFILE 3 #define GOOD_EXIT 0 #define MEM_ERROR 1 #define FILE_ERROR 2 #define USER_ERROR 3 #define PROGRAM_ERROR 4 #define SYMBOL_TYPE 0 #define LABEL_TYPE 1 #define NAME_TYPE 2 #define ASCLINE 32 // max length of ascii defb line #define ASCLIMIT 512 // size of ascii buffer #define BYTELINE 8 // max length of binary defb line #define BYTELIMIT 512 // size of byte binary buffer #define WORDLINE 6 // max length of defw line #define WORDLIMIT 512 // size of word binary buffer #define NO_DATA 0xff // pgmmem uninitialized value // pgmflags bits: #define PF_DATA 0x00000 // data valid from file #define PF_NOLABEL 0x40000 // suppress label generation #define PF_LABGEN 0x20000 // label generated in pass 2 #define PF_PATCH 0x10000 // patch flag #define PF_MB0 0x08000 // force memory bank 0 reference #define PF_MB1 0x04000 // force memory bank 1 reference #define PF_2BYTE 0x02000 // 2 byte operand for name #define PF_FORCE 0x01000 // force code disassembly #define PF_ICMT 0x00800 // inline comment #define PF_NAME 0x00400 // search data name table #define PF_LABEL 0x00200 // search only label table #define PF_SYMBOL 0x00100 // search only symbol table #define PF_CMT 0x00080 // comment flag #define PF_NOINIT 0x00040 // set if uninitialized space #define PF_ADRS 0x00020 // address data #define PF_WORD 0x00010 // word binary data #define PF_BYTE 0x00008 // byte binary data #define PF_ASCII 0x00004 // ascii text #define PF_SPLIT 0x00002 // set if split opcode #define PF_REF 0x00001 // set if referenced // // Structure Definitions // // symbol table and label table entries struct sym { struct sym *next; int val; byte used; char *name; }; typedef struct sym * SYM_PTR; // comment structure struct comment { int adrs; char *str; struct comment *next; }; typedef struct comment * COMMENT_PTR; // mnemonic table entries struct mnementry { char mnem[16]; }; // special function register name entries struct sfrentry { char dent[16]; }; // cycle count ranges struct cycle_range { struct cycle_range *next, // pointer to the next range in the same level // (NULL = no more ranges in this level) *child, // pointer to the first child (NULL = no children) *parent; // pointer back to parent (NULL = this is a top level range) int min, // the beginning address of range max, // the end address of range mul, // count multiplier; default is 1; 0 // (after using the "-" suffix) means exclusion from cycle // counting cnt, // current cycle count for this range cnt2, // started as an alternative cycle count, but now is used as // flags (I am lazy to rename it in all those 1e6 files...) val; // explicit value, as given by '=NNNN' suffix (and a source // of many joy and unexpected results :-) ) }; typedef struct cycle_range* CYCLE_RANGE_PTR; #endif // _DEFS_H_ d52-3.4.1.orig/dispass0.c0000600000175000017500000004455010666553343013137 0ustar uweuwe /* * Pass 0 for Disassemblers * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ // // Read control file, if it exists, and flag areas as code, text, // or whatever. Also handle labels, symbols, etc. // // Some strange things happen here with oring and anding on the // flag bits; this is so the user can define something as code, // data, or whatever, and assign a label for the same location. // We should handle the result intelligently regardless of the // order in which such things are found in the control file. // #include "common.h" void pass0(void) { int i; char *text, func, c, *ltext; int start, stop, code, temp; FILE *fpc; SYM_PTR sym; CYCLE_RANGE_PTR cr, cx, cy, cn; int found; if (upperflag) { makeupper(defbstr); makeupper(defwstr); makeupper(ascistr); makeupper(orgstr); makeupper(equstr); } fpc = fopen(ctl, "r"); if (!fpc) return; if (fpc != NULL) // if control file exists... { printf("\nReading control file "); while (!feof(fpc)) // until end of file... { start = stop = 0; *linebuffer = '\0'; // clear previous line text = fgets(linebuffer, MAX_LINE - 1, fpc); // read one line i = 0; if (!text) break; while (linebuffer[i] && linebuffer[i] != '\n') i++; linebuffer[i] = '\0'; text = &linebuffer[1]; while (isgraph(*text)) // skip remaining chars in first word text++; text = get_adrs(text, &start); while (1) { c = *text++; if (c != ' ' && c != '\t') // skip whitespace break; } if (c == '\n' || c == ';') // if only one numeric... --text; // back up to newline func = c; // save operator ltext = text; --ltext; text = get_adrs(text, &stop); if (func == '+') // check for valid operator stop += (start - 1); else if (func == '-' && !stop) stop = start; switch (toupper(linebuffer[0])) { case 'A': // address if (start < PMEMSIZE && stop < PMEMSIZE) { do { // get address to reference #ifdef CPU_BIG_ENDIAN code = (pgmmem[start]) << 8; temp = pgmmem[start + 1] & 0xff; #else code = pgmmem[start] & 0xff; temp = (pgmmem[start + 1] & 0xff) << 8; #endif code |= temp; if (code < PMEMSIZE) { pgmflags[code] |= PF_REF; // flag referenced address pgmflags[code] &= ~PF_SPLIT; pgmflags[start] |= PF_ADRS; // set flags to adrs code pgmflags[start++] &= ~(PF_NOINIT | PF_WORD | PF_BYTE | PF_ASCII | PF_SPLIT); pgmflags[start] |= PF_ADRS; pgmflags[start++] &= ~(PF_NOINIT | PF_WORD | PF_BYTE | PF_ASCII | PF_SPLIT); } else { pgmflags[start++] |= PF_WORD; pgmflags[start++] |= PF_WORD; } } while (start < stop); } else printf("\rinvalid address specified: %x, %x\n", start, stop); break; case 'B': // byte binary if (start < PMEMSIZE && stop < PMEMSIZE) { do { pgmflags[start] |= PF_BYTE; pgmflags[start++] &= ~(PF_NOINIT | PF_ADRS | PF_WORD | PF_ASCII | PF_SPLIT); } while (start <= stop); } else printf("\rinvalid address specified: %x, %x\n", start, stop); break; case 'C': // code if (start < PMEMSIZE && stop < PMEMSIZE) { do { pgmflags[start] &= #ifdef _D48_H_ ~(PF_NOINIT | PF_ADRS | PF_WORD | PF_BYTE | PF_ASCII | PF_SPLIT | PF_MB0 | PF_MB1); #else ~(PF_NOINIT | PF_ADRS | PF_WORD | PF_BYTE | PF_ASCII | PF_SPLIT); #endif pgmflags[start++] |= PF_FORCE; } while (start <= stop); } else printf("\rinvalid address specified: %x, %x\n", start, stop); break; case 'D': // define data type switch (toupper(*ltext)) { case '0': case 'L': pgmflags[start] |= PF_LABEL; // 0 or (l)abel = search label table only break; case '1': case 'S': pgmflags[start] |= PF_SYMBOL; // 1 or (s)ymbol = search symbol table only break; case '2': case 'N': pgmflags[start] |= (PF_LABEL | PF_SYMBOL); // 2 or (n)one = don't search either table break; default: printf("\nInvalid data type flag: %s\n", linebuffer); break; } break; #ifdef EXTENDED_MEM #ifndef _D48_H_ case 'E': // extended memory specification // incomplete break; #endif #endif #ifdef _D52_H_ case 'F': // modify SFR name if (start < 0x80 || start > 0xff) { printf("\rInvalid SFR address: 0x%x in '%s'\n", start, (char *) &linebuffer[2]); } else { start &= 0x7f; for (stop=0; stop<15; stop++) // transfer new name { func = *ltext++; if (isgraph(func)) sfr[start].dent[stop] = func; else { sfr[start].dent[stop] = '\0'; // terminate name break; } } sfrflags[start] = 1; if (stop >= 15) sfr[start].dent[15] = '\0'; } break; #endif case 'I': // ignore if (start < PMEMSIZE && stop < PMEMSIZE) { do { pgmflags[start++] = PF_NOINIT; } while (start <= stop); } else printf("\rinvalid address specified: %x, %x\n", start, stop); break; #ifdef _D52_H_ case 'K': // modify SFR bit name if (start < 0x80 || start > 0xff) { printf("\rInvalid SFR bit address: 0x%x in '%s'\n", start, (char *) &linebuffer[2]); } else { start &= 0x7f; for (stop=0; stop<15; stop++) // transfer name { func = *ltext++; if (isgraph(func)) sfrbits[start].dent[stop] = func; else { sfrbits[start].dent[stop] = '\0'; break; } } sbflags[start] = 1; if (stop >= 15) sfrbits[start].dent[15] = '\0'; } break; #endif case 'L': // label if (start < PMEMSIZE) { pgmflags[start] |= PF_REF; // flag reference pgmflags[start] &= ~PF_SPLIT; if (isgraph(*ltext)) add_entry(start, ltext, LABEL_TYPE); } else printf("\rinvalid address specified: %x, %x\n", start, stop); break; #ifdef _D48_H_ case 'M': // force memory bank selection get_adrs(ltext, &stop); if (start) pgmflags[stop] |= PF_MB1; else pgmflags[stop] |= PF_MB0; break; #endif #ifdef _D52_H_ case 'M': // modify memory bit name if (start > 0x7f) { printf("\rInvalid memory bit address: 0x%x in '%s'\n", start, (char *) &linebuffer[2]); } else { for (stop=0; stop<15; stop++) // transfer name { func = *ltext++; if (isgraph(func)) { if (!keilflag) membits[start].dent[stop] = func; else keilmembits[start].dent[stop] = func; } else { if (!keilflag) membits[start].dent[stop] = '\0'; else keilmembits[start].dent[stop] = '\0'; break; } } mbflags[start] = 1; if (stop >= 15) { if (!keilflag) membits[start].dent[15] = '\0'; else keilmembits[start].dent[15] = '\0'; } } break; #endif case 'N': pgmflags[start] |= PF_NOLABEL; break; case 'O': // hex offset for program if (!offset) offset = start; break; case 'P': // patch code (add inline code) pgmflags[start] |= PF_PATCH; // flag address text = get_adrs((char *) &linebuffer[1], &start); add_patch(start, text); break; #ifdef _D48_H_ case 'R': // register name if (start > 15) { printf("\rInvalid register address: 0x%x in '%s'\n", linebuffer[0], linebuffer); } else { for (stop=0; stop<7; stop++) // transfer register name { func = *ltext++; if (upperflag) func = toupper(func); if (isalnum(func)) rbname[start].dent[stop] = func; else { rbname[start].dent[stop] = '\0'; break; } } } if (stop >= 7) rbname[start].dent[7] = '\0'; // null terminate reg name break; #endif #ifdef _D52_H_ case 'R': // modify register name if (start > 0x7f) { printf("\rInvalid register/memory address: 0x%x in '%s'\n", start, (char *) &linebuffer[2]); } else { dirregs[start] |= 2; for (stop=0; stop<15; stop++) // transfer register name { func = *ltext++; if (upperflag) func = toupper(func); if (isgraph(func)) rbname[start].dent[stop] = func; else { rbname[start].dent[stop] = '\0'; break; } } if (stop >= 15) rbname[start].dent[15] = '\0'; } break; #endif case 'S': // symbol add_entry(start, ltext, SYMBOL_TYPE); break; case 'T': // ascii text do { pgmflags[start] |= PF_ASCII; pgmflags[start++] &= ~(PF_NOINIT | PF_ADRS | PF_WORD | PF_BYTE | PF_SPLIT); } while (start <= stop); break; #ifdef EXTENDED_MEM #ifndef _D48_H_ case 'U': // use extended memory translation // incomplete break; #endif #endif case 'W': // word binary if (start < PMEMSIZE && stop < PMEMSIZE) { do { pgmflags[start] |= PF_WORD; pgmflags[start++] &= ~(PF_NOINIT | PF_ADRS | PF_BYTE | PF_ASCII | PF_SPLIT); } while (start <= stop); } else printf("\rinvalid address specified: %x, %x\n", start, stop); break; case 'X': // operand name pgmflags[start] |= PF_NAME; sym = add_entry(start, ltext, NAME_TYPE); sym->used = FALSE; break; case 'Y': // operand name, no equ generation pgmflags[start] |= PF_NAME; sym = add_entry(start, ltext, NAME_TYPE); sym->used = -1; break; case 'Z': // cycle counting if ((cn = (CYCLE_RANGE_PTR) malloc(sizeof(struct cycle_range))) == NULL) exit(1); // error handling !!! cn->cnt = 0; // fill up with default cn->cnt2 = 0; cn->min = start; cn->max = stop; cn->mul = 1; cn->val = 0; // the explicit one-off value, see '=' below cn->child = NULL; cn->parent = NULL; cn->next = NULL; // patch the single-num-range--and-third-parameter cases // (we are unable to parse the xxxx- case, that would need to // rewrite a portion of parsing above which we don't want for // backwards compatibility reasons - let's document it, making // a "feature" from the bug... :-) if (func == '*') { cn->mul = stop; cn->max = stop = start; } else if (func == '=') { cn->val = stop; cn->max = stop = start; } // get the third numeral - I've simply stolen Jeff's code from above... -- JW while (1) { c = *text++; if (c != ' ' && c != '\t') // skip whitespace break; } if (c == '\n' || c == ';') // if no more arguments --text; // back up to newline if (c == '*') text = get_adrs(text, &cn->mul); else if (c == '=') text = get_adrs(text, &cn->val); else if (c == '^') // indicate maximum overdrive, cn->cnt2 = 2; // sorry, "worst case" ("jump always taken") else if (c == '-') cn->mul = 0; // zero multiplier to indicate "exclude from // overall count" - for the "not taken" branch if (stop > PMEMSIZE) stop = PMEMSIZE; // sanity if (stop < start) // sanity exit(1); //!!! error handling !!! cx = NULL; // now let's find, where could this range fit cy = NULL; cr = cycle_r; do { found = 0; while ((!found) && (cr != NULL)) { if ((start >= cr->min) && (stop <= cr->max)) { // our new range would fit into this one cx = cr; found = 1; } else if ((start <= cr->min) && (stop >= cr->max)) { //our new range eats this one if (cy == NULL) // init conditon - only one range is there yet cycle_r = cn; else if (cy->child == cr) { cy->child = cn; cn->parent = cx; } else { cy->next = cn; // first swap in the new for the old cn->parent = cy->parent; } cn->child = cr; // the old is now child of the new cr->parent = cn; while ((cx = cr->next) != NULL) { // determine, siblings of old will be siblings or children of new if ((start <= cx->min) && (stop >= cx->max)) { // remains a child - but child of cn! cx->parent = cr->parent; } else if ( ((cx->min < start) && (cx->max > start) && (cx->max < stop)) || ((cx->min > start) && (cx->min < stop) && (cx->max > stop)) ) { //pathologic partial overlap exit(1); //!!! error handling !!! } else // goes outside cn range so it's sibling - the // 4th option is impossible from context { cr->next = cx->next; // detach from old chain cx->next = cn->next; cx->parent = cn->parent; cn->next = cx; // insert into new chain } cr = cx; // and go for the next } found = 2; // when finished, get out of the whole new // range handling the shortest way } else if ( ((cr->min < start) && (cr->max > start) && (cr->max < stop)) || ((cr->min > start) && (cr->min < stop) && (cr->max > stop)) ) { // pathologic partial overlap exit(1); // !!! error handling !!! } else { cy = cr; cr = cy->next; // none of those - ignore - but let cy // always point to the currently probed one } } if (found == 1) { cy = cx; cr = cx -> child; } } while (found == 1); if (found == 0) // this means the new range fits into an old ... { // cx contains the would-be parent if (cy == NULL) // special case: first record of the day... :-) cycle_r = cn; else if (cx == NULL) // no matching record in the topmost level cy->next = cn; else { cn->next = cx->child; // insert as a new child of cx cn->parent = cx; cx->child = cn; } } cycleflag = TRUE; // oh yes, we almost forgot to flip on the // main cycle counting switch... break; case 0x00: // ignore empty lines case '\n': case '\r': case '\t': case ' ': case ';': // ignore commented out lines break; case '#': // comment string pgmflags[start] |= PF_CMT; // flag address text = get_adrs((char *) &linebuffer[1], &start); add_comment(start, text); break; case '!': // inline comment string pgmflags[start] |= PF_ICMT; text = get_adrs((char *) &linebuffer[1], &start); add_icomment(start, text); break; default: // somebody didn't read the docs... printf("\nUnknown control code: 0x%02x in '%s'\n", linebuffer[0], linebuffer); break; } } if (label_count || symbol_count || name_count) // set up tail node for sort { tail_ptr = (struct sym *) malloc(sizeof(struct sym)); if (tail_ptr == NULL) { printf("\nNo memory for symbol pointers!\n"); exit(MEM_ERROR); } tail_ptr->next = tail_ptr; tail_ptr->name = malloc(4); tail_ptr->name[0] = 0xfe; // set max values for sort tail_ptr->name[1] = 0; tail_ptr->val = 0xfffff; // set an invalid value to mark end of list } if (label_count) // if labels encountered... { lab_tab_last->next = tail_ptr; // set up pointer array for sort lab_val_index = malloc(sizeof(SYM_PTR) * label_count); if (lab_val_index == NULL) { printf("\nNo memory for label pointers"); exit(MEM_ERROR); } lab_tab = sort(lab_tab, lab_val_index, label_count); if (!lab_tab) exit(USER_ERROR); } if (symbol_count) // if symbols encountered... { sym_tab_last->next = tail_ptr; sym_val_index = malloc(sizeof(SYM_PTR) * symbol_count); if (sym_val_index == NULL) { printf("\nNo memory for symbol pointers"); exit(MEM_ERROR); } sym_tab = sort(sym_tab, sym_val_index, symbol_count); if (!sym_tab) exit(USER_ERROR); } if (name_count) // if operand symbols encountered... { name_tab_last->next = tail_ptr; name_val_index = malloc(sizeof(SYM_PTR) * name_count); if (name_val_index == NULL) { printf("\nNo memory for operand name pointers!\n"); exit(MEM_ERROR); } name_tab = sort(name_tab, name_val_index, name_count); if (!name_tab) exit(USER_ERROR); } fclose(fpc); } else printf("No control file found\n\n"); } // end of dispass0.c d52-3.4.1.orig/dispass3.c0000644000175000017500000002170010666553310013134 0ustar uweuwe /* * Pass 3 for Disassemblers * Copyright (C) 1995-2007 by Jeffery L. Post * j_post pacbell net * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include "common.h" // // Defined Constants // /* MISC_EQU_TAG is used in pass 3 to determine whether a miscellaneous equate statement should be generated. The equate statement will be written to the disassembly file if the location is referenced by some instruction and either it is a split reference or the location is uninitialized and the location does not have an entry in the label table. If the above requirements are met except that the location has an entry in the label table, then an equate statement will be generated as a label equate. */ #define MISC_EQU_TAG ((pflag & PF_REF) && ((pflag & PF_SPLIT) | (pflag & PF_NOINIT))) bool isnumeric(char *str); // // Global variables // /* none */ // Return TRUE if string is a simple expression based on a defined // symbol, label, or operand name, eg: label+10 or symbol*4 bool isnumexpression(char *str) { int i, len; bool arith = FALSE, valid = FALSE; char name[MAX_LINE]; len = strlen(str); for (i=0; i 1) // allow negative i = 1; } for ( ; inext; } } if (symbol_count) { sym_tab = sort_by_name(sym_tab); ptr = sym_tab; for (i=0; inext; } } if (name_count) { name_tab = sort_by_name(name_tab); ptr = name_tab; for (i=0; inext; } } // search label table for labels referenced but not generated j = TRUE; for (index=0; indexname); // ignore if numeric expression if (ptr->used && !isnum) { val = ptr->val; val = pgmflags[val]; val &= (PF_NOINIT | PF_SPLIT | PF_REF); if (val == (PF_REF | PF_SPLIT) || val == (PF_REF | PF_NOINIT)) { if (j) // do header if first one { j = FALSE; if (!newline || dump) fprintf(fp, "\n;"); fprintf(fp, "\n;\tLabel equates\n;\n;" " These are labels in the control file that reference\n;" " the middle of a multibyte instruction or reference\n;" " an address outside the initialized space\n;"); } fprintf(fp, "\n%s\t%s\t", ptr->name, equstr); puthex(ptr->val); newline = FALSE; } } } // now do equates for symbol table j = TRUE; for (index=0; indexname); // ignore if numeric expression if (ptr->used && !isnum) { if (j) // do header if first one { j = FALSE; if (!newline || dump) fprintf(fp, "\n;"); fprintf(fp, "\n;\tSymbol equates\n;\n;" " These are symbols from the control\n;" " file that are referenced in the code\n;"); } fprintf(fp, "\n%s\t%s\t", ptr->name, equstr); puthex(ptr->val); newline = FALSE; } } // now do equates for operand name table j = TRUE; ptr = name_tab; for (index=0; indexname); // ignore if numeric expression if ((ptr->used != 255) && !isnum) { if (!strcasecmp(ptr->name, ptr->next->name)) { adrs = ptr->val; val = pgmmem[adrs]; if (pgmflags[adrs] & PF_2BYTE) #ifdef CPU_BIG_ENDIAN { val <<= 8; val |= pgmmem[adrs + 1]; } #else val |= (pgmmem[adrs + 1] << 8); #endif next_adrs = ptr->next->val; next_val = pgmmem[next_adrs]; if (pgmflags[next_adrs] & PF_2BYTE) #ifdef CPU_BIG_ENDIAN { next_val <<= 8; next_val |= pgmmem[next_adrs + 1]; } #else next_val |= (pgmmem[next_adrs + 1] << 8); #endif if (val != next_val) ok = TRUE; } else ok = TRUE; if (ok) { if (j) // do header if first one { j = FALSE; if (!newline || dump) fprintf(fp, "\n;"); fprintf(fp, "\n;\tOperand symbol equates\n;\n;" " These are operand symbols from the control\n;" " file that are referenced in the code\n;"); } adrs = ptr->val; val = pgmmem[adrs] & 0xff; if (pgmflags[adrs] & PF_2BYTE) #ifdef CPU_BIG_ENDIAN { val <<= 8; val |= pgmmem[adrs + 1]; } #else val |= (pgmmem[adrs + 1] << 8); #endif fprintf(fp, "\n%s\t%s\t", ptr->name, equstr); puthex(val); newline = FALSE; } } ptr = ptr->next; } // to do miscellaneous equates, we need to resort labels by value if (label_count) lab_tab = sort(lab_tab, lab_val_index, label_count); j = TRUE; for (i=0; ; ) { k = i & 0xfff; pflag = pgmflags[i]; // if location is referenced and un-initialized or is a split ref if (MISC_EQU_TAG) { cptr = find_entry(i, label_count, lab_val_index); if ((cptr == NULL) && !(pflag & PF_LABGEN)) // if not in label list { if (j) // do header if first one { j = FALSE; if (!newline || dump) fprintf(fp, "\n;"); fprintf(fp, "\n;\tMiscellaneous equates\n;\n;" " These are addresses referenced in the code but\n;" " which are in the middle of a multibyte instruction\n;" " or are addresses outside the initialized space\n;"); newline = FALSE; } if (!upperflag) fprintf(fp, "\nX%04x\t%s\t", i, equstr); // do EQU statement else fprintf(fp, "\nX%04X\t%s\t", i, equstr); puthex(i); } } i++; if (!(i & WORD_MASK)) break; if ((i & 0xfff) < k) printf("\rPass 3 %04x", i); } printf("\rPass 3 - Equate generation complete"); if (!newline || dump) fprintf(fp, "\n;"); if (upperflag) fprintf(fp, "\n\tEND\n;\n\n"); else fprintf(fp, "\n\tend\n;\n\n"); fflush(fp); fclose(fp); } // End of Pass 3 // end of dispass3.c d52-3.4.1.orig/dz80.c0000644000175000017500000001770310666553245012207 0ustar uweuwe /* * Z80 Disassembler * Copyright (C) 1990-2007 by Jeffery L. Post * j_post pacbell net * * dz80.c - Main File * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include "dz80.h" #include "common.h" #include "analyze.h" #include "dz80pass1.h" #include "dz80pass2.h" #include "dz80table.h" #include "d80table.h" // // Global variables // int d8080; // 0 for z80, 1 for 8080, 2 for 8085 int dotpseudo = 0; #include "dispass0.c" #include "dispass3.c" void usage(void) { printf("\nUsage: dz80 [options] \n" "Options may be entered Unix style (-d) or DOS style (/b)\n" "\t-a use ascii macro instead of db/defb for text.\n" "\t-b force .bin extension on input file.\n" "\t-c disassemble CP/M .com file (implies -x100).\n" "\t-d include address and data in comment field.\n" "\t-h force .hex extension on input file.\n" "\t If neither 'b', 'c', nor 'h' is specified, DZ80 will first search\n" "\t for a .hex file, and if not found, then a .bin file\n" "\t-n use C style for hexadecimal operands\n" "\t-p put dot '.' at beginning of pseudo ops\n" "\t-s change 'db' and 'dw' to 'defb' and 'defw'.\n" "\t-t trace and analyze code before disassembly.\n" "\t (-t will overwrite any existing ctl file for the Z80 file\n" "\t being disassembled.)\n" "\t-u output labels, symbols, and mnemonics in upper case.\n" "\t-x add hexadecimal offset to program addresses.\n" "\t-80 generate 8080 mnemonics.\n" "\t-85 generate 8085 mnemonics.\n" "\nOptions may be entered in a freeform fashion as long " "as a dash (-) or\n" "a slash (/) preceeds any option that preceeds the filename." "\nExamples:\n" "\tdz80 filename bd\n" "\tdz80 -d filename b\n" "\tdz80 /b -d filename\n\n"); exit(GOOD_EXIT); } // // The Main Program // int main(int argc, char *argv[]) { char c; int count; char *inp; int line; char tempstr[16]; #ifdef ALPHA printf("\nDZ80 Z80/8080/8085 Disassembler V %d.%d.%d Alpha %d" "\nCopyright (C) 1990-%d by J. L. Post%s", VERSION, MAJORREV, MINORREV, ALPHA, YEAR, licenseText); #else #ifdef BETA printf("\nDZ80 Z80/8080/8085 Disassembler V %d.%d.%d Beta %d" "\nCopyright (C) 1990-%d by J. L. Post%s", VERSION, MAJORREV, MINORREV, BETA, YEAR, licenseText); #else printf("\nDZ80 Z80/8080/8085 Disassembler V %d.%d.%d" "\nCopyright (C) 1990-%d by J. L. Post%s", VERSION, MAJORREV, MINORREV, YEAR, licenseText); #endif #endif if (argc < 2) usage(); strcpy(defbstr, "db"); // init define byte and word strings strcpy(defwstr, "dw"); strcpy(ascistr, "db"); // init define ascii string sym_tab = NULL; // no symbols or labels yet lab_tab = NULL; name_tab = NULL; fp = NULL; fileflag = EITHERFILE; // assume search for either file type hexflag = FALSE; // no data in comment field upperflag = FALSE; baseflag = FALSE; traceflag = FALSE; offset = 0; // default start at address 0 ascii_flag = FALSE; d8080 = 0; // find filename in command line for (line=1; line 2) // test for options { for (count=1; count DZ80/D48 Disassembler User's Manual
DZ80/D48 Addendum to D52 Disassembler User's Manual

Z80 and 8048 Disassemblers for Linux and Windows
GNU General Public License Version 3
Copyright 2007 by Jeffery L. Post
 j_post <AT> pacbell <DOT> net
Hosted on www.8052.com

Version 3.4.1 - August, 2007

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

The file COPYING contains the full text of the GNU General Public License, Version 3.

NOTE: As Novell and Microsoft are in violation of the GPL, this software may not be distributed by either Novell or Microsoft. The same prohibition applies to any company that enters into an agreement with Microsoft regarding Microsoft's phony patent claims against Linux. In addition, no one who cannot honor ALL the requirements of GPL version 3 may distribute this software.


This documentation contains information regarding the differences between D52, DZ80 and D48. Please see the D52 documentation (d52manual.html) for a description of the features common to all three disassemblers.


TABLE OF CONTENTS



Introduction


DZ80 (Z80 disassembler) and D48 (8048 disassembler) are very much like the 8052 disassembler D52. This document describes the differences between D52 and the Z80 and 8048 disassemblers.

Command Line Options



The following D52 options do not apply to DZ80 or D48:

I option - add include pseudo-op for sfr52.inc header file.
K option - disassemble for Keil A51.

The T option (trace and analyze code) is still experimental in DZ80, and does not exist at all in D48.

C Option (disassemble CP/M .com file - DZ80)

Disassembles a CP/M .com executable file beginning at address 100H. Use of this option will cause DZ80 to look for a file with a .com extension, as opposed to a .bin or .hex extension. This option also sets the offset to 100H without the need to do so with the -x option. You do not need to use the -c option if you specify a filename with a '.com' extension (ie: dz80 program.com). This option is compatible withe the -80 and -85 options.

80 Option (disassemble 8080 code - DZ80)

Disassembles code using 8080 opcodes instead of Z80 opcodes.

85 Option (disassemble 8085 code - DZ80)

Disassembles code using 8085 opcodes instead of Z80 opcodes. The only difference between -80 and -85 is that the 8085 has two additional opcodes: rim and sim, which will be treated as invalid with the -80 option.

1 Option (disassemble 8041 code - D48)

Disassembles code using 8041 opcodes instead of 8048 opcodes. (Note that this is the digit 1, not the letter L.)

Control File Directives



The following control file directives do not apply to DZ80 or D48:

F directive - modify SFR name.
K directive - modify SFR bit name.
M directive - modify memory location name (different meaning in D48).
R directive - modify register name (used in D48, but not DZ80).

M Directive (force memory bank selection - D48)

Forces code to be disassembled as if a sel mb0 or sel mb1 instruction had been encountered, regardless of the actual state of the memory bank selection.

Back to top




d52-3.4.1.orig/dz80.h0000644000175000017500000000521610666552544012211 0ustar uweuwe /* * Z80 Disassembler * Copyright (C) 1990-2007 by Jeffery L. Post * j_post pacbell net * * dz80.h - Z80 disassembler definitions * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _DZ80_H_ #define _DZ80_H_ #define CPU_LITTLE_ENDIAN // Z80 is little endian processor #ifndef _DEFS_H_ #include "defs.h" #endif // // Defined Constants // // opttbl bits: #define OPT_XFER 0x80 // unconditional transfer #define OPT_SPEC 0x40 // special codes (cd, dd, ed, fd) #define OPT_REL 0x20 // relative addressing #define OPT_DIR 0x10 // direct addressing (jp, call) #define OPT_PAR 0x08 // parenthesized address #define OPT_IMM 0x04 // immediate data #define OPT_3 0x02 // 3 byte instruction #define OPT_2 0x01 // 2 byte instruction #define OPT_NONE 0x00 // single byte, no options #define OPT_SIZE (OPT_2 | OPT_3) #define OPT_IMM2 (OPT_IMM | OPT_2) #define OPT_PAR2 (OPT_PAR | OPT_2) #define OPT_DIR_IMM3 (OPT_DIR | OPT_IMM | OPT_3) #define OPT_PAR_IMM3 (OPT_PAR | OPT_DIR_IMM3) #define OPT_REL2 (OPT_REL | OPT_2) #define OPT_SPEC2 (OPT_SPEC | OPT_2) // ED option bits: #define OPT_ED_2 0x01 // 2 byte, entry in edtbl #define OPT_ED_STORE 0x03 // write 16 bit register to memory #define OPT_ED_LD_BC 0x13 // load bc from memory #define OPT_ED_LD_DE 0x23 // load de from memory #define OPT_ED_LD_SP 0x33 // load sp from memory #define OPT_ED_RET 0x81 // retn or reti // DD and FD option bits: #define OPT_DD_2 0x01 // 2 byte, entry in dd1tbl #define OPT_DD_LOAD 0x02 // 3 byte loads #define OPT_DD_DIR 0x03 // 4 byte direct addressing #define OPT_DD_ARTH 0x06 // 3 byte arithmetic codes #define OPT_DD_CB 0x07 // 4 byte dd/fd cb codes struct snementry { char mcode[8]; }; struct entry { char mnem[16]; }; // // Prototypes // extern void usage(void); // // Global Variables // extern int d8080; // 8080 mnemonic flag #endif // _DZ80_H_ d52-3.4.1.orig/dz80pass1.c0000644000175000017500000000760010666553225013150 0ustar uweuwe /* * Z80 Disassembler * Copyright (C) 1990-2007 by Jeffery L. Post * j_post pacbell net * * dz80pass1.c - Disassembly pass 1 * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include "dz80.h" #include "common.h" #include "dz80pass1.h" #include "dz80pass2.h" #include "dz80table.h" #include "d80table.h" // // Defined Constants // /* none */ // // Global variables // /* none */ // // Pass one of disassembly // // Examine opcodes for internal references to other memory locations. // If such references are found, flag the referenced location so that // a label can be generated in the output file during pass two. // void pass1(void) { int i, l, pc, rel; byte j, k, mask; printf("Pass 1 0000"); for (i=offset; i= offset && pc <= himark) mask |= PF_NOINIT; if (!(pgmflags[pc] & PF_NOLABEL)) pgmflags[pc] = (pgmflags[pc] & ~mask) | PF_REF; // flag reference } if (j & OPT_REL) // if relative memory reference { j = pgmmem[i + 1]; // get offset rel = (j > 0x7f) ? j | 0xff00 : j & 0xff; // sign extend offset pc = i + 2; pc += rel; pc &= WORD_MASK; if (pc >= offset && pc <= himark) mask |= PF_NOINIT; if (!(pgmflags[pc] & PF_NOLABEL)) pgmflags[pc] = (pgmflags[pc] & ~mask) | PF_REF; // flag reference } if (j & OPT_SPEC) // if special processing { j = pgmmem[i + 1]; // get second byte switch (k) { case 0xed: if (edcode[j] & 2) { pc = (pgmmem[i + 2] & 0xff) | ((pgmmem[i + 3] << 8) & 0xff00); if (pc >= offset && pc <= himark) mask |= PF_NOINIT; if (!(pgmflags[pc] & PF_NOLABEL)) pgmflags[pc] = (pgmflags[pc] & ~mask) | PF_REF; } i += (edcode[j] & 3); break; case 0xdd: case 0xfd: if (j == 0x21 || j == 0x22 || j == 0x2a) { pc = (pgmmem[i + 2] & 0xff) | ((pgmmem[i + 3] << 8) & 0xff00); if (pc >= offset && pc <= himark) mask |= PF_NOINIT; if (!(pgmflags[pc] & PF_NOLABEL)) pgmflags[pc] = pgmflags[pc] | PF_REF; } i += (ddcode[j] & 3); break; } } if (d8080) i = i + (opttbl80[k] & OPT_SIZE) + 1; // update location pointer else i = i + (opttbl[k] & OPT_SIZE) + 1; // update location pointer } else i++; if ((i & 0xff) < l) printf("\rPass 1 %04x", i & 0xff00); } printf("\rPass 1 - Reference search complete"); } // End of Pass 1 // end of dz80pass1.c d52-3.4.1.orig/dz80pass1.h0000644000175000017500000000210510666552510013144 0ustar uweuwe /* * Z80 Disassembler * Copyright (C) 1990-2007 by Jeffery L. Post * j_post pacbell net * * dz80pass1.h - Disassembly pass 1 * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _DZ80PASS1_H_ #define _DZ80PASS1_H_ // // Prototypes // extern void pass1(void); // // Global variables // /* none */ #endif // _DZ80PASS1_H_ d52-3.4.1.orig/dz80pass2.c0000644000175000017500000007702210666553201013150 0ustar uweuwe /* * Z80 Disassembler * Copyright (C) 1990-2007 by Jeffery L. Post * j_post pacbell net * * dz80pass2.c - Disassembly pass 2 * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include "dz80.h" #include "common.h" #include "dz80pass1.h" #include "dz80pass2.h" #include "dz80table.h" #include "d80table.h" // // Defined Constants // /* none */ // // Global variables // int opcount; // bytes/opcode count // // Pass two of disassembly. // // Rescan data array and generate output file. Generate label if location // flagged as referenced by some other opcode. If un-initialized data is // encountered, ignore it but set skip flag so that an ORG statement can // be generated when the next initialized data is found. // void pass2(void) { char c, *cptr; int skip, year; int i, l, q, temp; byte j, k; int pflag; time_t tp; int cyc, cyc2; // for cycle counting k = 0; j = 0xff; skip = TRUE; dump = FALSE; byte_cnt = 0; asc_cnt = 0; newline = FALSE; printf("\nPass 2 0000"); if ((fp = fopen(dst, "w")) == NULL) // open output source file { printf("\n* Can't open file %s *\n", dst); exit(FILE_ERROR); } fprintf(fp, ";\n; DZ80 V%d.%d.%d ", VERSION, MAJORREV, MINORREV); // output header switch (d8080) { case 1: fprintf(fp, "8080"); break; case 2: fprintf(fp, "8085"); break; default: fprintf(fp, "Z80"); break; } fprintf(fp, " Disassembly of %s", src); time(&tp); // get current time date_time = localtime(&tp); // convert to hr/min/day etc year = date_time->tm_year + 1900; fprintf(fp, "\n; %d/%02d/%02d %02d:%02d", year, date_time->tm_mon + 1, date_time->tm_mday, date_time->tm_hour, date_time->tm_min); // // Generate output file // for (i=offset; i= ASCLIMIT) dump_ascii(i + 1); } else // else treat it as binary data { pgmflags[i] |= PF_BYTE; if (asc_cnt) // dump any accumulated ascii dump_ascii(i); byte_data[byte_cnt] = pgmmem[i]; // add data to buffer byte_cnt++; } break; case PF_WORD: // if word data... if (byte_cnt) // dump any binary or ascii in buffers dump_bytes(i); if (asc_cnt) dump_ascii(i); if (skip) // insert ORG statement { if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } chk_label(i); // add label if referenced q = ((int) pgmmem[i + 1]) << 8; // get word value temp = pgmmem[i] & 0xff; q |= temp; fprintf(fp, "%s\t", defwstr); if (pgmflags[i] & PF_LABEL) cptr = find_entry(q, label_count, lab_val_index); // see if label exists else cptr = find_entry(q, symbol_count, sym_val_index); // see if symbol exists if (cptr == NULL) // if not, do hex value puthex(q); else fprintf(fp, "%s", cptr); // else output symbol if (hexflag) // add comment field { fprintf(fp, "\t\t; %04x %02x %02x %c%c", i, pgmmem[i], pgmmem[i + 1], ascii(pgmmem[i]), ascii(pgmmem[i + 1])); } if (pgmflags[i] & PF_ICMT) output_icomment(i); i++; if (pgmflags[i + 2] != PF_ADRS && pgmflags[i + 2] != PF_WORD) { fprintf(fp, "\n;"); newline = TRUE; } break; case PF_ADRS: // if address data... if (byte_cnt) // output any pending binary or dump_bytes(i); // ascii data from buffers if (asc_cnt) dump_ascii(i); if (skip) // insert ORG statement { if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } chk_label(i); // add label if referenced q = ((int) pgmmem[i + 1]) << 8; // get address value temp = pgmmem[i] & 0xff; q |= temp; fprintf(fp, "%s\t", defwstr); cptr = find_entry(q, label_count, lab_val_index); // see if label exists if (cptr == NULL) // if not, output hex { if (!pgmflags[i] & PF_LABEL) // search symbol table only if not defined as label cptr = find_entry(q, symbol_count, sym_val_index); if (cptr == NULL) { if (!upperflag) fprintf(fp, "X%04x", q); else fprintf(fp, "X%04X", q); } else fprintf(fp, "%s", cptr); // output symbol text } else fprintf(fp, "%s", cptr); // else output label text if (hexflag) // do comment field { fprintf(fp, "\t\t; %04x %02x %02x %c%c", i, pgmmem[i], pgmmem[i + 1], ascii(pgmmem[i]), ascii(pgmmem[i + 1])); } if (pgmflags[i] & PF_ICMT) output_icomment(i); i++; if (pgmflags[i + 2] != PF_ADRS) { fprintf(fp, "\n;"); newline = TRUE; } break; default: // default = binary data... if (asc_cnt) // output any pending ascii data dump_ascii(i); if (skip) // insert ORG statement { if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } byte_data[byte_cnt] = pgmmem[i]; // add data to buffer byte_cnt++; if (byte_cnt >= BYTELIMIT) // if end of buffer... dump_bytes(i + 1); // dump accumulated data } i++; // next program location if (!(pgmflags[i] & PF_NOINIT) && (pgmflags[i] & PF_ASCII)) { // if next byte is flagged as if (!is_ascii(pgmmem[i])) // ascii, but is not... pgmflags[i] |= PF_BYTE; // then flag it as binary } } // // If previous data was an unconditional transfer, AND current // location is not referenced by some other opcode, AND current // byte is 0 or 0FFH, then treat this byte as un-initialized data. // else if ((j & 0x10) && (!(pflag & PF_REF)) && ((pgmmem[i] == 0) || (pgmmem[i] == NO_DATA)) && (!(pflag & PF_FORCE))) { if (byte_cnt) // since we're going to skip some dump_bytes(i); // data, output any pending ascii if (asc_cnt) // or binary data remaining in buffers dump_ascii(i); if (dump) // if ascii or binary output was done, { // stick in a newline fprintf(fp, "\n;"); dump = FALSE; newline = TRUE; } pgmflags[i] = PF_NOINIT;// flag as uninitialized data i++; skip = TRUE; byte_cnt = 0; } // // If previous opcode was 0 or 0ffH, AND current location is not // referenced but is initialized, AND current opcode is 0 or 0ffH, // un-initialize it. // else if (((k == 0) || (k == 0xff)) && (!(pflag & PF_REF)) && ((pgmmem[i] == 0) || (pgmmem[i] == NO_DATA)) && !(pflag & PF_NOINIT) && !(pflag & PF_FORCE)) { pgmflags[i] = PF_NOINIT; i++; skip = TRUE; j = -1; } else // IT'S EXECUTABLE CODE! { pgmflags[i] &= ~PF_NOINIT; // clear for label search in pass 3 if (byte_cnt) // if any ascii or binary data remains dump_bytes(i); // in the buffers, output them now if (asc_cnt) dump_ascii(i); if (dump) { fprintf(fp, "\n;"); dump = FALSE; newline = TRUE; } byte_cnt = 0; if (cycleflag) // cycle count summary cycle_end(i); if (skip) // insert ORG statement { if (!newline) fprintf(fp, "\n;"); fprintf(fp, "\n\t%s\t", orgstr); puthex(i); fprintf(fp, "\n;"); newline = TRUE; skip = FALSE; // reset skip flag } chk_ref(i); // add label if referenced kcnt = 8; opcount = 1; k = pgmmem[i]; // get opcode if (d8080) { j = opttbl80[k]; // get options if ((k == 0x20 || k == 0x30) && (d8080 != 2)) // sim/rim not in 8080 { doopcode(defbstr); fprintf(fp, "\t"); kcnt = (kcnt + 8) & 0x78; q = (int) pgmmem[i] & 0xff; if (pgmflags[i] & PF_NAME) cptr = find_entry(i, name_count, name_val_index); else cptr = find_entry(q, symbol_count, sym_val_index); if (cptr == NULL) puthex(pgmmem[i]); else kcnt += fprintf(fp, "%s", cptr); } else doopcode(mnemtbl80[k].mnem); // output mnemonic } else { j = opttbl[k]; // get options doopcode(mnemtbl[k].mnem); // output mnemonic } // // Generate operands // switch (j & ~OPT_XFER) { case OPT_NONE: // single byte - no options break; case OPT_PAR: // should only occur if 8080/8085 mnemonics if (!d8080) { fprintf(stderr, "\nZ80 PROCESSING ERROR!\n"); fflush(stderr); } doopcode(defbstr); fprintf(fp, "\t"); kcnt = (kcnt + 8) & 0x78; q = (int) pgmmem[i] & 0xff; if (pgmflags[i] & PF_NAME) cptr = find_entry(i, name_count, name_val_index); else cptr = find_entry(q, symbol_count, sym_val_index); if (cptr == NULL) puthex(pgmmem[i]); else kcnt += fprintf(fp, "%s", cptr); break; case OPT_IMM2: // 2 byte immediate data q = (int) pgmmem[i + 1] & 0xff; if (pgmflags[i + 1] & PF_NAME) cptr = find_entry(i + 1, name_count, name_val_index); else cptr = find_entry(q, symbol_count, sym_val_index); if (cptr == NULL) puthex(pgmmem[i + 1]); else kcnt += fprintf(fp, "%s", cptr); splitcheck(i + 1); break; case OPT_PAR2: // 2 byte parenthesized address (in, out) fprintf(fp, "("); kcnt++; q = (int) pgmmem[i + 1] & 0xff; if (pgmflags[i + 1] & PF_NAME) cptr = find_entry(i + 1, name_count, name_val_index); else cptr = find_entry(q, symbol_count, sym_val_index); if (cptr == NULL) puthex(pgmmem[i + 1]); else kcnt += fprintf(fp, "%s", cptr); fprintf(fp, ")"); kcnt++; if (!(k & 8)) // if out (n),a { if (!upperflag) fprintf(fp, ",a"); else fprintf(fp, ",A"); kcnt += 2; } splitcheck(i + 1); break; case OPT_DIR_IMM3: // 3 byte immediate data q = (pgmmem[i + 2] << 8) | pgmmem[i + 1]; q &= WORD_MASK; if (pgmflags[i + 1] & PF_NAME) { pgmflags[i + 1] |= PF_2BYTE; cptr = find_entry(i + 1, name_count, name_val_index); } else if (pgmflags[i] & PF_SYMBOL) cptr = find_entry(q, symbol_count, sym_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "X%04x", q); else kcnt += fprintf(fp, "X%04X", q); } else kcnt += fprintf(fp, "%s", cptr); splitcheck(i + 1); splitcheck(i + 2); break; case OPT_PAR_IMM3: // 3 byte parenthesized address, immediate data q = (pgmmem[i + 2] << 8) | pgmmem[i + 1]; q &= WORD_MASK; if (pgmflags[i + 1] & PF_NAME) { pgmflags[i + 1] |= PF_2BYTE; cptr = find_entry(i + 1, name_count, name_val_index); } else if (pgmflags[i] & PF_SYMBOL) cptr = find_entry(q, symbol_count, sym_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "(X%04x", q); else kcnt += fprintf(fp, "(X%04X", q); } else kcnt += fprintf(fp, "(%s", cptr); switch (k) { case 0x22: if (!upperflag) kcnt += fprintf(fp, "),hl"); else kcnt += fprintf(fp, "),HL"); break; case 0x2a: case 0x3a: kcnt += fprintf(fp, ")"); break; case 0x32: if (!upperflag) kcnt += fprintf(fp, "),a"); else kcnt += fprintf(fp, "),A"); break; } splitcheck(i + 1); splitcheck(i + 2); break; case OPT_REL2: // 2 byte relative addressing q = pgmmem[i + 1] & 0xff; q = (q > 0x7f) ? q | 0xff00 : q; q = i + 2 + q; q &= WORD_MASK; cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "X%04x", q); else kcnt += fprintf(fp, "X%04X", q); } else kcnt += fprintf(fp, "%s", cptr); splitcheck(i + 1); break; case OPT_SPEC: // special processing codes (dd, ed, fd) opcount = 2; switch (k) { case 0xed: k = pgmmem[i + 1]; // get 2nd byte if (edcode[k]) { c = (k < 0xa0) ? k - 0x40 : k - 0x64; doopcode(edtbl[(byte) c].mnem); switch (edcode[k]) { case OPT_ED_2: break; case OPT_ED_STORE: q = (pgmmem[i + 3] << 8) | pgmmem[i + 2]; q &= WORD_MASK; if (pgmflags[i + 2] & PF_NAME) { pgmflags[i + 2] |= PF_2BYTE; cptr = find_entry(i + 2, name_count, name_val_index); } else if (pgmflags[i] & PF_SYMBOL) cptr = find_entry(q, symbol_count, sym_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "(X%04x)", q); else kcnt += fprintf(fp, "(X%04X)", q); } else kcnt += fprintf(fp, "(%s)", cptr); opcount = 4; break; case OPT_ED_LD_BC: q = (pgmmem[i + 3] << 8) | pgmmem[i + 2]; q &= WORD_MASK; if (pgmflags[i + 2] & PF_NAME) { pgmflags[i + 2] |= PF_2BYTE; cptr = find_entry(i + 2, name_count, name_val_index); } else if (pgmflags[i] & PF_SYMBOL) cptr = find_entry(q, symbol_count, sym_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "(X%04x)", q); else kcnt += fprintf(fp, "(X%04X)", q); } else kcnt += fprintf(fp, "(%s)", cptr); if (!upperflag) kcnt += fprintf(fp, ",bc"); else kcnt += fprintf(fp, ",BC"); opcount = 4; break; case OPT_ED_LD_DE: q = (pgmmem[i + 3] << 8) | pgmmem[i + 2]; q &= WORD_MASK; if (pgmflags[i + 2] & PF_NAME) { pgmflags[i + 2] |= PF_2BYTE; cptr = find_entry(i + 2, name_count, name_val_index); } else if (pgmflags[i] & PF_SYMBOL) cptr = find_entry(q, symbol_count, sym_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "(X%04x)", q); else kcnt += fprintf(fp, "(X%04X)", q); } else kcnt += fprintf(fp, "(%s)", cptr); if (!upperflag) kcnt += fprintf(fp, ",de"); else kcnt += fprintf(fp, ",DE"); opcount = 4; break; case OPT_ED_LD_SP: q = (pgmmem[i + 3] << 8) | pgmmem[i + 2]; q &= WORD_MASK; if (pgmflags[i + 2] & PF_NAME) { pgmflags[i + 2] |= PF_2BYTE; cptr = find_entry(i + 2, name_count, name_val_index); } else if (pgmflags[i] & PF_SYMBOL) cptr = find_entry(q, symbol_count, sym_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "(X%04x)", q); else kcnt += fprintf(fp, "(X%04X)", q); } else kcnt += fprintf(fp, "(%s)", cptr); if (!upperflag) kcnt += fprintf(fp, ",sp"); else kcnt += fprintf(fp, ",SP"); opcount = 4; break; case OPT_ED_RET: // retn or reti j |= 0x80; break; } } else { invalided(k); j |= 0x80; } break; case 0xdd: j |= doindex(i, 'x'); break; case 0xfd: j |= doindex(i, 'y'); break; } break; case OPT_SPEC2: // cb special codes c = pgmmem[i + 1] & 0xff; temp = (int) (c >> 3) & 0x1f; if (*cbtbl[temp].mnem == '\0') { doopcode(defbstr); putc('\t', fp); kcnt = (kcnt + 8) & 0x78; puthex(0xcb); putc(',', fp); kcnt++; puthex(c); j |= 0x80; } else { doopcode(cbtbl[temp].mnem); doopcode(regtbl[c & 7].mnem); } break; } if (cycleflag) // do cycle counting and printout per instruction { while (kcnt < TSTOP) { fprintf(fp, "\t"); kcnt = (kcnt + 8) & 0x78; } // get cycles - here would come 8080 support, would we have the appropriate tables ready cyc = cycles[pgmmem[i] & 0xff]; cyc2 = cycles2[pgmmem[i] & 0xff]; switch (pgmmem[i] & 0xff) { case 0xed: cyc = edcycles[pgmmem[i+1] & 0xff]; cyc2 = edcycles2[pgmmem[i+1] & 0xff]; break; case 0xcb: cyc = cbcycles[pgmmem[i+1] & 0xff]; cyc2 = cyc; break; case 0xdd: if ((pgmmem[i+1] & 0xff) == 0xcb) cyc = ddcbcycles[pgmmem[i+3] & 0xff]; else cyc = ddcycles[pgmmem[i+1] & 0xff]; cyc2 = cyc; break; case 0xfd: if ((pgmmem[i+1] & 0xff) == 0xcb) cyc = fdcbcycles[pgmmem[i+3] & 0xff]; else cyc = fdcycles[pgmmem[i+1] & 0xff]; cyc2 = cyc; break; } // would be for 8080 support d8080 ? i = i + (opttbl80[k] & OPT_SIZE) + opcount : i + (opttbl[k] & OPT_SIZE) + opcount, cycle_in(i, i + (opttbl[k] & OPT_SIZE) + opcount, cyc, cyc2); } if (hexflag) // do comment field { while (kcnt < TSTOP) { fprintf(fp, "\t"); kcnt = (kcnt + 8) & 0x78; } kcnt += fprintf(fp, "; %04x ", i); if (d8080) q = (opttbl80[k] & OPT_SIZE) + opcount; else q = (opttbl[k] & OPT_SIZE) + opcount; for (c=0; c> 4; switch (k & 0xf) { case OPT_DD_2: doopcode(dd1tbl[j].mnem); q = 0; switch (j) { case 0: if (!upperflag) kcnt += fprintf(fp, "i%c,bc", index); else kcnt += fprintf(fp, "I%c,BC", index); break; case 1: if (!upperflag) kcnt += fprintf(fp, "i%c,de", index); else kcnt += fprintf(fp, "I%c,DE", index); break; case 2: case 4: case 6: case 8: case 7: case 10: if (!upperflag) kcnt += fprintf(fp, "i%c", index); else kcnt += fprintf(fp, "I%c", index); break; case 9: if (!upperflag) kcnt += fprintf(fp, "i%c)", index); else kcnt += fprintf(fp, "I%c)", index); q = 0x80; break; case 3: if (!upperflag) kcnt += fprintf(fp, "i%c,i%c", index, index); else kcnt += fprintf(fp, "I%c,I%c", index, index); break; case 5: if (!upperflag) kcnt += fprintf(fp, "i%c,sp", index); else kcnt += fprintf(fp, "I%c,SP", index); break; default: break; } opcount = 2; return(q); case OPT_DD_LOAD: switch (j) { case 0: doopcode("inc (i"); kcnt += fprintf(fp, "%c+", index); v = (int) pgmmem[i + 2] & 0xff; cptr = find_entry(v, symbol_count, sym_val_index); if (cptr == NULL) puthex(v); else kcnt += fprintf(fp, "%s", cptr); putc(')', fp); kcnt++; break; case 1: doopcode("dec (i"); kcnt += fprintf(fp, "%c+", index); v = (int) pgmmem[i + 2] & 0xff; cptr = find_entry(v, symbol_count, sym_val_index); if (cptr == NULL) puthex(v); else kcnt += fprintf(fp, "%s", cptr); putc(')', fp); kcnt++; break; case 2: indxld1(i, 'b', index); break; case 3: indxld1(i, 'c', index); break; case 4: indxld1(i, 'd', index); break; case 5: indxld1(i, 'e', index); break; case 6: indxld1(i, 'h', index); break; case 7: indxld1(i, 'l', index); break; case 8: indxld2(i, 'b', index); break; case 9: indxld2(i, 'c', index); break; case 10: indxld2(i, 'd', index); break; case 11: indxld2(i, 'e', index); break; case 12: indxld2(i, 'h', index); break; case 13: indxld2(i, 'l', index); break; case 14: indxld2(i, 'a', index); break; case 15: indxld1(i, 'a', index); break; } opcount = 3; return(0); case OPT_DD_DIR: doopcode("ld "); q = (pgmmem[i + 2] & 0xff) | ((pgmmem[i + 3] << 8) & 0xff00); switch (j) { case 0: if (pgmflags[i + 2] & PF_NAME) { pgmflags[i + 2] |= PF_2BYTE; cptr = find_entry(i + 2, name_count, name_val_index); } else if (pgmflags[i] & PF_SYMBOL) cptr = find_entry(q, symbol_count, sym_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "i%c,X%04x", index, q); else kcnt += fprintf(fp, "I%c,X%04X", index, q); } else { if (!upperflag) kcnt += fprintf(fp, "i%c,%s", index, cptr); else kcnt += fprintf(fp, "I%c,%s", index, cptr); } break; case 1: if (pgmflags[i + 2] & PF_NAME) { pgmflags[i + 2] |= PF_2BYTE; cptr = find_entry(i + 2, name_count, name_val_index); } else if (pgmflags[i] & PF_SYMBOL) cptr = find_entry(q, symbol_count, sym_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "(X%04x),i%c", q, index); else kcnt += fprintf(fp, "(X%04X),I%c", q, index); } else { if (!upperflag) kcnt += fprintf(fp, "(%s),i%c", cptr, index); else kcnt += fprintf(fp, "(%s),I%c", cptr, index); } break; case 2: if (pgmflags[i + 2] & PF_NAME) { pgmflags[i + 2] |= PF_2BYTE; cptr = find_entry(i + 2, name_count, name_val_index); } else if (pgmflags[i] & PF_SYMBOL) cptr = find_entry(q, symbol_count, sym_val_index); else cptr = find_entry(q, label_count, lab_val_index); if (cptr == NULL) { if (!upperflag) kcnt += fprintf(fp, "i%c,(X%04x)", index, q); else kcnt += fprintf(fp, "I%c,(X%04X)", index, q); } else { if (!upperflag) kcnt += fprintf(fp, "i%c,(%s)", index, cptr); else kcnt += fprintf(fp, "I%c,(%s)", index, cptr); } break; case 3: // this applies only to ld (ix+n),data and ld (iy+n),data if (!upperflag) kcnt += fprintf(fp, "(i%c+", index); else kcnt += fprintf(fp, "(I%c+", index); v = (int) pgmmem[i + 2] & 0xff; cptr = find_entry(v, symbol_count, sym_val_index); if (cptr == NULL) puthex(v); else kcnt += fprintf(fp, "%s", cptr); kcnt += fprintf(fp,"),"); v = (int) pgmmem[i + 3] & 0xff; if (pgmflags[i + 2] & PF_NAME) cptr = find_entry(i + 2, name_count, name_val_index); else if (pgmflags[i] & PF_LABEL) cptr = find_entry(q, label_count, lab_val_index); else cptr = find_entry(v, symbol_count, sym_val_index); if (cptr == NULL) puthex(v); else kcnt += fprintf(fp, "%s", cptr); break; } opcount = 4; return(0); case OPT_DD_ARTH: doopcode(dd2tbl[j].mnem); kcnt += fprintf(fp, "%c+", index); v = (int) pgmmem[i + 2] & 0xff; if (pgmflags[i + 2] & PF_NAME) cptr = find_entry(i + 2, name_count, name_val_index); else if (pgmflags[i] & PF_LABEL) cptr = find_entry(q, label_count, lab_val_index); else cptr = find_entry(v, symbol_count, sym_val_index); if (cptr == NULL) puthex(v); else kcnt += fprintf(fp, "%s", cptr); putc(')', fp); kcnt++; opcount = 3; return(0); case OPT_DD_CB: j = pgmmem[i + 3]; // get cb ext byte if (j == 0x36 || (j & 7) != 6) return(0); if (j < 0x40) { k = j >> 3; doopcode(ddcbtbl[k].mnem); } else { k = (j >> 6) + 7; doopcode(ddcbtbl[k].mnem); putc(((j >> 3) & 7) | 0x30, fp); putc(',', fp); kcnt += 2; } if (!upperflag) kcnt += fprintf(fp, "(i%c+", index); else kcnt += fprintf(fp, "(I%c+", index); v = (int) pgmmem[i + 2] & 0xff; if (pgmflags[i + 2] & PF_NAME) cptr = find_entry(i + 2, name_count, name_val_index); else if (pgmflags[i] & PF_LABEL) cptr = find_entry(q, label_count, lab_val_index); else cptr = find_entry(v, symbol_count, sym_val_index); if (cptr == NULL) puthex(v); else kcnt += fprintf(fp, "%s", cptr); putc(')', fp); kcnt++; opcount = 4; return(0); } return(0); } void indxld1(int i, char reg, char idx) { char *cptr; int v; doopcode("ld "); if (upperflag) { reg = toupper(reg); idx = toupper(idx); } if (upperflag) kcnt += fprintf(fp, "%c,(I%c+", reg, idx); else kcnt += fprintf(fp, "%c,(i%c+", reg, idx); v = (int) pgmmem[i + 2] & 0xff; if (pgmflags[i + 2] & PF_NAME) cptr = find_entry(i + 2, name_count, name_val_index); else if (pgmflags[i] & PF_LABEL) cptr = find_entry(v, label_count, lab_val_index); else cptr = find_entry(v, symbol_count, sym_val_index); if (cptr == NULL) puthex(v); else kcnt += fprintf(fp, "%s", cptr); putc(')', fp); kcnt++; } void indxld2(int i, char reg, char idx) { char *cptr; int v; doopcode("ld "); if (upperflag) { reg = toupper(reg); idx = toupper(idx); } if (upperflag) kcnt += fprintf(fp, "(I%c+", idx); else kcnt += fprintf(fp, "(i%c+", idx); v = (int) pgmmem[i + 2] & 0xff; if (pgmflags[i + 2] & PF_NAME) cptr = find_entry(i + 2, name_count, name_val_index); else if (pgmflags[i] & PF_LABEL) cptr = find_entry(v, label_count, lab_val_index); else cptr = find_entry(v, symbol_count, sym_val_index); if (cptr == NULL) puthex(v); else kcnt += fprintf(fp, "%s", cptr); kcnt += fprintf(fp, "),%c", reg); } // end of dz80pass2.c d52-3.4.1.orig/dz80pass2.h0000644000175000017500000000235710666554312013160 0ustar uweuwe /* * Z80 Disassembler * Copyright (C) 1990-2007 by Jeffery L. Post * j_post pacbell net * * dz80pass2.h - Disassembly pass 2 * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _DZ80PASS2_H_ #define _DZ80PASS2_H_ // // Prototypes // extern void pass2(void); extern void invalided(byte k); extern int doindex(int i, char index); extern void indxld1(int i, char reg, char idx); extern void indxld2(int i, char reg, char idx); // // Global variables // /* none */ #endif // _DZ80PASS2_H_ d52-3.4.1.orig/dz80table.c0000644000175000017500000006526510666553117013223 0ustar uweuwe /* * Z80 Disassembler * Copyright (C) 1990-2007 by Jeffery L. Post * j_post pacbell net * * dz80table.c - Mnemonic Tables * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include "dz80.h" struct mnementry mnemtbl[] = { {"nop"}, {"ld bc,"}, {"ld (bc),a"}, {"inc bc"}, // 00 - 03 {"inc b"}, {"dec b"}, {"ld b,"}, {"rlca"}, // 04 - 07 {"ex af,af'"}, {"add hl,bc"}, {"ld a,(bc)"}, {"dec bc"}, // 08 - 0b {"inc c"}, {"dec c"}, {"ld c,"}, {"rrca"}, // 0c - 0f {"djnz "}, {"ld de,"}, {"ld (de),a"}, {"inc de"}, // 10 - 13 {"inc d"}, {"dec d"}, {"ld d,"}, {"rla"}, // 14 - 17 {"jr "}, {"add hl,de"}, {"ld a,(de)"}, {"dec de"}, // 18 - 1b {"inc e"}, {"dec e"}, {"ld e,"}, {"rra"}, // 1c - 1f {"jr nz,"}, {"ld hl,"}, {"ld "}, {"inc hl"}, // 20 - 23 {"inc h"}, {"dec h"}, {"ld h,"}, {"daa"}, // 24 - 27 {"jr z,"}, {"add hl,hl"}, {"ld hl,"}, {"dec hl"}, // 28 - 2b {"inc l"}, {"dec l"}, {"ld l,"}, {"cpl"}, // 2c - 2f {"jr nc,"}, {"ld sp,"}, {"ld "}, {"inc sp"}, // 30 - 33 {"inc (hl)"}, {"dec (hl)"}, {"ld (hl),"}, {"scf"}, // 34 - 37 {"jr c,"}, {"add hl,sp"}, {"ld a,"}, {"dec sp"}, // 38 - 3b {"inc a"}, {"dec a"}, {"ld a,"}, {"ccf"}, // 3c - 3f {"ld b,b"}, {"ld b,c"}, {"ld b,d"}, {"ld b,e"}, // 40 - 43 {"ld b,h"}, {"ld b,l"}, {"ld b,(hl)"}, {"ld b,a"}, // 44 - 47 {"ld c,b"}, {"ld c,c"}, {"ld c,d"}, {"ld c,e"}, // 48 - 4b {"ld c,h"}, {"ld c,l"}, {"ld c,(hl)"}, {"ld c,a"}, // 4c - 4f {"ld d,b"}, {"ld d,c"}, {"ld d,d"}, {"ld d,e"}, // 50 - 53 {"ld d,h"}, {"ld d,l"}, {"ld d,(hl)"}, {"ld d,a"}, // 54 - 57 {"ld e,b"}, {"ld e,c"}, {"ld e,d"}, {"ld e,e"}, // 58 - 5b {"ld e,h"}, {"ld e,l"}, {"ld e,(hl)"}, {"ld e,a"}, // 5c - 5f {"ld h,b"}, {"ld h,c"}, {"ld h,d"}, {"ld h,e"}, // 60 - 63 {"ld h,h"}, {"ld h,l"}, {"ld h,(hl)"}, {"ld h,a"}, // 64 - 67 {"ld l,b"}, {"ld l,c"}, {"ld l,d"}, {"ld l,e"}, // 68 - 6b {"ld l,h"}, {"ld l,l"}, {"ld l,(hl)"}, {"ld l,a"}, // 6c - 6f {"ld (hl),b"}, {"ld (hl),c"}, {"ld (hl),d"}, {"ld (hl),e"}, // 70 - 73 {"ld (hl),h"}, {"ld (hl),l"}, {"halt"}, {"ld (hl),a"}, // 74 - 77 {"ld a,b"}, {"ld a,c"}, {"ld a,d"}, {"ld a,e"}, // 78 - 7b {"ld a,h"}, {"ld a,l"}, {"ld a,(hl)"}, {"ld a,a"}, // 7c - 7f {"add a,b"}, {"add a,c"}, {"add a,d"}, {"add a,e"}, // 80 - 83 {"add a,h"}, {"add a,l"}, {"add a,(hl)"}, {"add a,a"}, // 84 - 87 {"adc a,b"}, {"adc a,c"}, {"adc a,d"}, {"adc a,e"}, // 88 - 8b {"adc a,h"}, {"adc a,l"}, {"adc a,(hl)"}, {"adc a,a"}, // 8c - 8f {"sub b"}, {"sub c"}, {"sub d"}, {"sub e"}, // 90 - 93 {"sub h"}, {"sub l"}, {"sub (hl)"}, {"sub a"}, // 94 - 97 {"sbc a,b"}, {"sbc a,c"}, {"sbc a,d"}, {"sbc a,e"}, // 98 - 9b {"sbc a,h"}, {"sbc a,l"}, {"sbc a,(hl)"}, {"sbc a,a"}, // 9c - 9f {"and b"}, {"and c"}, {"and d"}, {"and e"}, // a0 - a3 {"and h"}, {"and l"}, {"and (hl)"}, {"and a"}, // a4 - a7 {"xor b"}, {"xor c"}, {"xor d"}, {"xor e"}, // a8 - ab {"xor h"}, {"xor l"}, {"xor (hl)"}, {"xor a"}, // ac - af {"or b"}, {"or c"}, {"or d"}, {"or e"}, // a0 - a3 {"or h"}, {"or l"}, {"or (hl)"}, {"or a"}, // a4 - a7 {"cp b"}, {"cp c"}, {"cp d"}, {"cp e"}, // a8 - ab {"cp h"}, {"cp l"}, {"cp (hl)"}, {"cp a"}, // ac - af {"ret nz"}, {"pop bc"}, {"jp nz,"}, {"jp "}, // c0 - c3 {"call nz,"}, {"push bc"}, {"add a,"}, {"rst 0"}, // c4 - c7 {"ret z"}, {"ret"}, {"jp z,"}, {""}, // c8 - cb {"call z,"}, {"call "}, {"adc a,"}, {"rst 8"}, // cc - cf {"ret nc"}, {"pop de"}, {"jp nc,"}, {"out "}, // d0 - d3 {"call nc,"}, {"push de"}, {"sub "}, {"rst 10h"}, // d4 - d7 {"ret c"}, {"exx"}, {"jp c,"}, {"in a,"}, // d8 - db {"call c,"}, {""}, {"sbc a,"}, {"rst 18h"}, // dc - df {"ret po"}, {"pop hl"}, {"jp po,"}, {"ex (sp),hl"},// e0 - e3 {"call po,"}, {"push hl"}, {"and "}, {"rst 20h"}, // e4 - e7 {"ret pe"}, {"jp (hl)"}, {"jp pe,"}, {"ex de,hl"}, // e8 - eb {"call pe,"}, {""}, {"xor "}, {"rst 28h"}, // ec - ef {"ret p"}, {"pop af"}, {"jp p,"}, {"di"}, // f0 - f3 {"call p,"}, {"push af"}, {"or "}, {"rst 30h"}, // f4 - f7 {"ret m"}, {"ld sp,hl"}, {"jp m,"}, {"ei"}, // f8 - fb {"call m,"}, {""}, {"cp "}, {"rst 38h"} // fc - ff } ; // Indexed codes (dd, fd ..) struct mnementry cbtbl[] = { {"rlc "}, {"rrc "}, {"rl "}, {"rr "}, // 00 - 1f {"sla "}, {"sra "}, {""}, {"srl "}, // 20 - 3f {"bit 0,"}, {"bit 1,"}, {"bit 2,"}, {"bit 3,"}, // 40 - 5f {"bit 4,"}, {"bit 5,"}, {"bit 6,"}, {"bit 7,"}, // 60 - 7f {"res 0,"}, {"res 1,"}, {"res 2,"}, {"res 3,"}, // 80 - 9f {"res 4,"}, {"res 5,"}, {"res 6,"}, {"res 7,"}, // a0 - bf {"set 0,"}, {"set 1,"}, {"set 2,"}, {"set 3,"}, // c0 - df {"set 4,"}, {"set 5,"}, {"set 6,"}, {"set 7,"} // e0 - ff }; struct mnementry regtbl[] = { {"b"}, {"c"}, {"d"}, {"e"}, {"h"}, {"l"}, {"(hl)"}, {"a"}, }; struct mnementry ddcbtbl[] = { {"rlc "}, {"rrc "}, {"rl "}, {"rr "}, {"sla "}, {"sra "}, {"??? "}, {"srl "}, {"bit "}, {"res "}, {"set "} }; struct mnementry dd1tbl[] = { {"add "}, {"add "}, {"inc "}, {"add "}, {"dec "}, {"add "}, {"pop "}, {"ex (sp),"}, {"push "}, {"jp ("}, {"ld sp,"} }; struct mnementry dd2tbl[] = { {"add a,(i"}, {"adc a,(i"}, {"sub (i"}, {"sbc a,(i"}, {"and (i"}, {"xor (i"}, {"or (i"}, {"cp (i"} }; // Miscellaneous codes (ed ..) struct mnementry edtbl[] = { {"in b,(c)"}, {"out (c),b"}, {"sbc hl,bc"}, {"ld "}, // 40-43 {"neg"}, {"retn"}, {"im 0"}, {"ld i,a"}, // 44-47 {"in c,(c)"}, {"out (c),c"}, {"adc hl,bc"}, {"ld bc,"}, // 48-4b {"defb "}, {"reti"}, {"defb "}, {"ld r,a"}, // 4c-4f {"in d,(c)"}, {"out (c),d"}, {"sbc hl,de"}, {"ld "}, // 50-53 {"defb "}, {"defb "}, {"im 1"}, {"ld a,i"}, // 54-57 {"in e,(c)"}, {"out (c),e"}, {"adc hl,de"}, {"ld de,"}, // 58-5b {"defb "}, {"defb "}, {"im 2"}, {"ld a,r"}, // 5c-5f {"in h,(c)"}, {"out (c),h"}, {"sbc hl,hl"}, {"defb "}, // 60-63 {"defb "}, {"defb "}, {"defb "}, {"rrd"}, // 64-67 {"in l,(c)"}, {"out (c),l"}, {"adc hl,hl"}, {"defb "}, // 68-6b {"defb "}, {"defb "}, {"defb "}, {"rld"}, // 6c-6f {"defb "}, {"defb "}, {"sbc hl,sp"}, {"ld "}, // 70-73 {"defb "}, {"defb "}, {"defb "}, {"defb "}, // 74-77 {"in a,(c)"}, {"out (c),a"}, {"adc hl,sp"}, {"ld sp,"}, // 78-7b {"ldi"}, {"cpi"}, {"ini"}, {"outi"}, // a0-a3 {"defb "}, {"defb "}, {"defb "}, {"defb "}, // a4-a7 {"ldd"}, {"cpd"}, {"ind"}, {"outd"}, // a8-ab {"defb "}, {"defb "}, {"defb "}, {"defb "}, // ac-af {"ldir"}, {"cpir"}, {"inir"}, {"otir"}, // b0-b3 {"defb "}, {"defb "}, {"defb "}, {"defb "}, // b4-b7 {"lddr"}, {"cpdr"}, {"indr"}, {"otdr"} // b8-bb }; /* OPTTBL (option table) entries: bit 7 = unconditional transfer instruction bit 6 = special processing (cb, dd, ed, fd opcodes) bit 5 = relative addressing (jr & djnz instructions) bit 4 = direct reference (jp or call) bit 3 = parenthesized address bit 2 = immediate data bit 1 = 3 byte instruction bit 0 = 2 byte instruction if entry = 0, instruction is single byte, no options */ unsigned char opttbl[] = { 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, // 00 - 07 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, // 08 - 0f 0x21, 0x16, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, // 10 - 17 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, // 18 - 1f 0x21, 0x16, 0x1e, 0x00, 0x00, 0x00, 0x05, 0x00, // 20 - 27 0x21, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x05, 0x00, // 28 - 2f 0x21, 0x16, 0x1e, 0x00, 0x00, 0x00, 0x05, 0x00, // 30 - 37 0x21, 0x00, 0x1e, 0x00, 0x00, 0x00, 0x05, 0x00, // 38 - 3f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 40 - 47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 48 - 4f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 50 - 57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 58 - 5f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 60 - 67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 68 - 6f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, // 70 - 77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 78 - 7f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 80 - 87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 88 - 8f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 90 - 97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 98 - 9f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // a0 - a7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // a8 - af 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // b0 - b7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // b8 - bf 0x00, 0x00, 0x16, 0x96, 0x16, 0x00, 0x05, 0x00, // c0 - c7 0x00, 0x80, 0x16, 0x41, 0x16, 0x16, 0x05, 0x00, // c8 - cf 0x00, 0x00, 0x16, 0x09, 0x16, 0x00, 0x05, 0x00, // d0 - d7 0x00, 0x00, 0x16, 0x09, 0x16, 0x40, 0x05, 0x00, // d8 - df 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x05, 0x00, // e0 - e7 0x00, 0x80, 0x16, 0x00, 0x16, 0x40, 0x05, 0x00, // e8 - ef 0x00, 0x00, 0x16, 0x00, 0x16, 0x00, 0x05, 0x00, // f0 - f7 0x00, 0x00, 0x16, 0x00, 0x16, 0x40, 0x05, 0x00 // f8 - ff } ; /* Flags for ED codes: 00 - invalid code 01 - 2 byte, entry in edtbl 03 - xx,(nn) where xx = bc, de, or sp 13 - (nn),bc 23 - (nn),de 33 - (nn),sp 81 - retn or reti */ unsigned char edcode[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 00 - 07 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 08 - 0f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 10 - 17 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 18 - 1f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 20 - 27 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 28 - 2f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 30 - 37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 38 - 3f 0x01, 0x01, 0x01, 0x13, 0x01, 0x81, 0x01, 0x01, // 40 - 47 0x01, 0x01, 0x01, 0x03, 0x00, 0x81, 0x00, 0x01, // 48 - 4f 0x01, 0x01, 0x01, 0x23, 0x00, 0x00, 0x01, 0x01, // 50 - 57 0x01, 0x01, 0x01, 0x03, 0x00, 0x00, 0x01, 0x01, // 58 - 5f 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, // 60 - 67 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, // 68 - 6f 0x00, 0x00, 0x01, 0x33, 0x00, 0x00, 0x00, 0x00, // 70 - 77 0x01, 0x01, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, // 78 - 7f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 80 - 87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 88 - 8f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 90 - 97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 98 - 9f 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, // a0 - a7 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, // a8 - af 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, // b0 - b7 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, // b8 - bf 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // c0 - c7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // c8 - cf 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // d0 - d7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // d8 - df 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // e0 - e7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // e8 - ef 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // f0 - f7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // f8 - ff } ; /* Flags for DD and FD codes: 00 - invalid code x1 - 2 byte entry in dd1tbl x2 - 3 byte load codes x3 - 4 byte direct address codes x6 - 3 byte arithmetic codes x7 - 4 byte dd/fd cb codes */ unsigned char ddcode[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 00 - 07 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 08 - 0f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 10 - 17 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 18 - 1f 0x00, 0x03, 0x13, 0x21, 0x00, 0x00, 0x00, 0x00, // 20 - 27 0x00, 0x31, 0x23, 0x41, 0x00, 0x00, 0x00, 0x00, // 28 - 2f 0x00, 0x00, 0x00, 0x00, 0x02, 0x12, 0x33, 0x00, // 30 - 37 0x00, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 38 - 3f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x00, // 40 - 47 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, // 48 - 4f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x00, // 50 - 57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52, 0x00, // 58 - 5f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x00, // 60 - 67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, // 68 - 6f 0x82, 0x92, 0xa2, 0xb2, 0xc2, 0xd2, 0x00, 0xe2, // 70 - 77 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf2, 0x00, // 78 - 7f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, // 80 - 87 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, // 88 - 8f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26, 0x00, // 90 - 97 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, // 98 - 9f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x00, // a0 - a7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x00, // a8 - af 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, // b0 - b7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x00, // b8 - bf 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // c0 - c7 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, // c8 - cf 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // d0 - d7 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // d8 - df 0x00, 0x61, 0x00, 0x71, 0x00, 0x81, 0x00, 0x00, // e0 - e7 0x00, 0x91, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // e8 - ef 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // f0 - f7 0x00, 0xa1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // f8 - ff } ; // T-state counts for Z80 // this is the "not taken" (conditional JR, CALL and RET) and // "last autorepeated" (B=0 - DJNZ) table unsigned char cycles[256] = { 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 00-0f 8,10, 7, 6, 4, 4, 7, 4, 12,11, 7, 6, 4, 4, 7, 4, // 10-1f 7,10,16, 6, 4, 4, 7, 4, 7,11,16, 6, 4, 4, 7, 4, // 20-2f 7,10,13, 6, 11,11,10, 4, 7,11,13, 6, 4, 4, 7, 4, // 30-3f 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 40-4f 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 50-5f 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 60-6f 7, 7, 7, 7, 7, 7, 0, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 70-7f 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 80-8f 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 90-9f 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // a0-af 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // b0-bf 5,10,10,10, 10,11, 7,11, 5,10,10, 0, 10,17, 7,11, // c0-cf 5,10,10,11, 10,11, 0,11, 5, 4,10,11, 10, 0, 0,11, // d0-df 5,10,10,19, 10,11, 7,11, 5, 4,10, 4, 10, 0, 7,11, // e0-ef 5,10,10, 0, 10,11, 7,11, 5, 6,10, 4, 10, 0, 7,11 // f0-ff }; // this is the "taken conditional" and "nonlast autorepeated (B/BC>0) table unsigned char cycles2[256] = { 4,10, 7, 6, 4, 4, 7, 4, 4,11, 7, 6, 4, 4, 7, 4, // 00-0f 13,10, 7, 6, 4, 4, 7, 4, 12,11, 7, 6, 4, 4, 7, 4, // 10-1f 12,10,16, 6, 4, 4, 7, 4, 12,11,16, 6, 4, 4, 7, 4, // 20-2f 12,10,13, 6, 11,11,10, 4, 12,11,13, 6, 4, 4, 7, 4, // 30-3f 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 40-4f 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 50-5f 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 60-6f 7, 7, 7, 7, 7, 7, 0, 7, 4, 4, 4, 4, 4, 4, 7, 4, // 70-7f 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 80-8f 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // 90-9f 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // a0-af 4, 4, 4, 4, 4, 4, 7, 4, 4, 4, 4, 4, 4, 4, 7, 4, // b0-bf 11,10,10,10, 17,11, 7,11, 11,10,10, 0, 17,17, 7,11, // c0-cf 11,10,10,11, 17,11, 0,11, 11, 4,10,11, 17, 0, 0,11, // d0-df 11,10,10,19, 17,11, 7,11, 11, 4,10, 4, 17, 0, 7,11, // e0-ef 11,10,10, 0, 17,11, 7,11, 11, 6,10, 4, 17, 0, 7,11 // f0-ff }; unsigned char cbcycles[256] = { 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8, // 00-0f 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8, // 10-1f 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8, // 20-2f 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8,15, 8, // 30-3f 8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8, // 40-4f 8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8, // 50-5f 8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8, // 60-6f 8, 8, 8, 8, 8, 8,12, 8, 8, 8, 8, 8, 8, 8,12, 8, // 70-7f 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8, // 80-8f 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8, // 90-9f 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8, // a0-af 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8, // b0-bf 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8, // c0-cf 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8, // d0-df 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8, // e0-ef 8, 8, 8, 8, 8, 8,15, 8, 8, 8, 8, 8, 8, 8,15, 8 // f0-ff }; unsigned char ddcycles[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0, // 00-0f 0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0, // 10-1f 0,14,20,10, 0, 0, 0, 0, 0,15,20,10, 0, 0, 0, 0, // 20-2f 0, 0, 0, 0, 23,23,19, 0, 0,15, 0, 0, 0, 0, 0, 0, // 30-3f 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // 40-4f 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // 50-5f 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // 60-6f 19,19,19,19, 19,19, 0,19, 0, 0, 0, 0, 0, 0,19, 0, // 70-7f 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // 80-8f 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // 90-9f 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // a0-af 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // b0-bf 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // c0-cf 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // d0-df 0,14, 0,23, 0,15, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, // e0-ef 0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0, 0, 0, 0, 0 // f0-ff }; // this is the "last autorepeated" (BC=0 - LDxR, CPxR, INxR, OUTxR) table unsigned char edcycles[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00-0f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10-1f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20-2f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 30-3f 12,12,15,20, 8,14, 8, 9, 12,12,15,20, 0,14, 0, 9, // 40-4f 12,12,15,20, 0, 0, 8, 9, 12,12,15,20, 0, 0, 8, 9, // 50-5f 12,12,15,20, 0, 0, 0,18, 12,12,15,20, 0, 0, 0,18, // 60-6f 0, 0,15,20, 0, 0, 0, 0, 12,12,15,20, 0, 0, 0, 0, // 70-7f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,19, 0, // 80-8f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90-9f 16,16,16,16, 0, 0, 0, 0, 16,16,16,16, 0, 0, 0, 0, // a0-af 16,16,16,16, 0, 0, 0, 0, 16,16,16,16, 0, 0, 0, 0, // b0-bf 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // c0-cf 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // d0-df 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // e0-ef 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // f0-ff }; // this is the "nonlast autorepeated" (BC>0) table unsigned char edcycles2[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00-0f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10-1f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20-2f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 30-3f 12,12,15,20, 8,14, 8, 9, 12,12,15,20, 0,14, 0, 9, // 40-4f 12,12,15,20, 0, 0, 8, 9, 12,12,15,20, 0, 0, 8, 9, // 50-5f 12,12,15,20, 0, 0, 0,18, 12,12,15,20, 0, 0, 0,18, // 60-6f 0, 0,15,20, 0, 0, 0, 0, 12,12,15,20, 0, 0, 0, 0, // 70-7f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,19, 0, // 80-8f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90-9f 16,16,16,16, 0, 0, 0, 0, 16,16,16,16, 0, 0, 0, 0, // a0-af 21,21,21,21, 0, 0, 0, 0, 21,21,21,21, 0, 0, 0, 0, // b0-bf 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // c0-cf 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // d0-df 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // e0-ef 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // f0-ff }; unsigned char fdcycles[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0, // 00-0f 0, 0, 0, 0, 0, 0, 0, 0, 0,15, 0, 0, 0, 0, 0, 0, // 10-1f 0,14,20,10, 0, 0, 0, 0, 0,15,20,10, 0, 0, 0, 0, // 20-2f 0, 0, 0, 0, 23,23,19, 0, 0,15, 0, 0, 0, 0, 0, 0, // 30-3f 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // 40-4f 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // 50-5f 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // 60-6f 19,19,19,19, 19,19, 0,19, 0, 0, 0, 0, 0, 0,19, 0, // 70-7f 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // 80-8f 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // 90-9f 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // a0-af 0, 0, 0, 0, 0, 0,19, 0, 0, 0, 0, 0, 0, 0,19, 0, // b0-bf 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // c0-cf 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // d0-df 0,14, 0,23, 0,15, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, // e0-ef 0, 0, 0, 0, 0, 0, 0, 0, 0,10, 0, 0, 0, 0, 0, 0 // f0-ff }; unsigned char ddcbcycles[256] = { 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // 00-0f 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // 10-1f 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // 20-2f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,23, 0, // 30-3f 0, 0, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,20, 0, // 40-4f 0, 0, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,20, 0, // 50-5f 0, 0, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,20, 0, // 60-6f 0, 0, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,20, 0, // 70-7f 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // 80-8f 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // 90-9f 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // a0-af 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // b0-bf 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // c0-cf 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // d0-df 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // e0-ef 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0 // f0-ff }; unsigned char fdcbcycles[256] = { 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // 00-0f 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // 10-1f 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // 20-2f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,23, 0, // 30-3f 0, 0, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,20, 0, // 40-4f 0, 0, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,20, 0, // 50-5f 0, 0, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,20, 0, // 60-6f 0, 0, 0, 0, 0, 0,20, 0, 0, 0, 0, 0, 0, 0,20, 0, // 70-7f 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // 80-8f 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // 90-9f 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // a0-af 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // b0-bf 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // c0-cf 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // d0-df 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0, // e0-ef 0, 0, 0, 0, 0, 0,23, 0, 0, 0, 0, 0, 0, 0,23, 0 // f0-ff }; /* unsigned char blankcycles[256] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 00-0f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 10-1f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 20-2f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 30-3f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 40-4f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 50-5f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 60-6f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 70-7f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 80-8f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 90-9f 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // a0-af 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // b0-bf 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // c0-cf 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // d0-df 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // e0-ef 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // f0-ff }; */ // end of dz80table.c d52-3.4.1.orig/dz80table.h0000644000175000017500000000312110666552317013210 0ustar uweuwe /* * Z80 Disassembler * Copyright (C) 1990-2007 by Jeffery L. Post * j_post pacbell net * * dz80table.h - Z80 disassembler tables * * Version 3.4.1 - 2007/09/02 * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #ifndef _DZ80TABLE_H_ #define _DZ80TABLE_H_ extern struct mnementry mnemtbl[]; extern struct mnementry cbtbl[]; extern struct mnementry regtbl[]; extern struct mnementry ddcbtbl[]; extern struct mnementry dd1tbl[]; extern struct mnementry dd2tbl[]; extern struct mnementry edtbl[]; extern unsigned char opttbl[]; extern unsigned char edcode[]; extern unsigned char ddcode[]; extern unsigned char cbcycles[256]; extern unsigned char ddcycles[256]; extern unsigned char edcycles[256]; extern unsigned char edcycles2[256]; extern unsigned char fdcycles[256]; extern unsigned char ddcbcycles[256]; extern unsigned char fdcbcycles[256]; #endif // _DZ80TABLE_H_ d52-3.4.1.orig/Makefile0000644000175000017500000001315410666425566012716 0ustar uweuwe# # Disassembler makefile for Linux # OBJDIR = ./obj CC = gcc CFLAGS = -Wall -O2 LIBS = D52OBJS = $(OBJDIR)/d52.o $(OBJDIR)/common.o $(OBJDIR)/d52pass1.o $(OBJDIR)/d52pass2.o $(OBJDIR)/d52table.o $(OBJDIR)/analyze52.o $(OBJDIR)/analyze.o D48OBJS = $(OBJDIR)/d48.o $(OBJDIR)/common.o $(OBJDIR)/d48pass.o $(OBJDIR)/d48table.o DZ80OBJS = $(OBJDIR)/dz80.o $(OBJDIR)/common.o $(OBJDIR)/dz80pass1.o $(OBJDIR)/dz80pass2.o $(OBJDIR)/dz80table.o $(OBJDIR)/d80table.o $(OBJDIR)/analyzez80.o $(OBJDIR)/analyze.o WINCC=/usr/local/cross-tools/bin/i386-mingw32msvc-gcc WINCFLAGS=-Wall -O2 -fomit-frame-pointer -s -I/usr/local/cross-tools/include -D_WIN32 -DWIN32 WINLIBS= WIND52OBJS = $(OBJDIR)/d52.obj $(OBJDIR)/common.obj $(OBJDIR)/d52pass1.obj $(OBJDIR)/d52pass2.obj $(OBJDIR)/d52table.obj $(OBJDIR)/analyze52.obj $(OBJDIR)/analyze.obj WIND48OBJS = $(OBJDIR)/d48.obj $(OBJDIR)/common.obj $(OBJDIR)/d48pass.obj $(OBJDIR)/d48table.obj WINDZ80OBJS = $(OBJDIR)/dz80.obj $(OBJDIR)/common.obj $(OBJDIR)/dz80pass1.obj $(OBJDIR)/dz80pass2.obj $(OBJDIR)/dz80table.obj $(OBJDIR)/d80table.obj $(OBJDIR)/analyzez80.obj $(OBJDIR)/analyze.obj all: d52 d48 dz80 install: d52 d48 dz80 cp -f d52 /usr/local/bin cp -f d48 /usr/local/bin cp -f dz80 /usr/local/bin d52: $(D52OBJS) $(CC) $(CFLAGS) $(D52OBJS) -o d52 $(LIBS) strip d52 d48: $(D48OBJS) $(CC) $(CFLAGS) $(D48OBJS) -o d48 $(LIBS) strip d48 dz80: $(DZ80OBJS) $(CC) $(CFLAGS) $(DZ80OBJS) -o dz80 $(LIBS) strip dz80 $(OBJDIR)/d52.o: d52.c defs.h d52.h dispass0.c d52pass1.h d52pass2.h dispass3.c d52table.h analyze.h analyze.c analyze52.h analyze52.c common.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/d48.o: d48.c defs.h d48.h dispass0.c d48pass.h dispass3.c d48table.h common.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/dz80.o: dz80.c defs.h dz80.h dispass0.c dz80pass1.h dz80pass2.h dispass3.c dz80table.h analyze.h analyze.c analyzez80.h analyzez80.c common.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/common.o: common.c defs.h d52.h common.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/d52pass1.o: d52pass1.c defs.h d52.h d52pass1.h d52pass2.h d52table.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/d52pass2.o: d52pass2.c defs.h d52.h d52pass1.h d52pass2.h d52table.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/d52table.o: d52table.c defs.h d52.h d52table.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/d48pass.o: d48pass.c defs.h d48.h d48pass.h d48table.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/d48table.o: d48table.c defs.h d48.h d48table.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/dz80pass1.o: dz80pass1.c defs.h dz80.h dz80pass1.h dz80pass2.h dz80table.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/dz80pass2.o: dz80pass2.c defs.h dz80.h dz80pass1.h dz80pass2.h dz80table.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/dz80table.o: dz80table.c defs.h dz80.h dz80table.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/d80table.o: d80table.c defs.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/analyze.o: analyze.c defs.h analyze.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/analyze52.o: analyze52.c defs.h d52.h analyze.h analyze.c analyze52.h d52pass2.h $(CC) $(CFLAGS) -c $< -o $@ $(OBJDIR)/analyzez80.o: analyzez80.c defs.h d52.h analyze.h analyze.c analyzez80.h d52pass2.h $(CC) $(CFLAGS) -c $< -o $@ clean: rm -f $(OBJDIR)/*.o rm -f d52 d48 dz80 win: d52.exe d48.exe dz80.exe wind52: d52.exe wind48: d48.exe windz80: dz80.exe d52.exe: $(WIND52OBJS) $(WINCC) $(WINCFLAGS) $(WIND52OBJS) -o d52.exe $(WINLIBS) d48.exe: $(WIND48OBJS) $(WINCC) $(WINCFLAGS) $(WIND48OBJS) -o d48.exe $(WINLIBS) dz80.exe: $(WINDZ80OBJS) $(WINCC) $(WINCFLAGS) $(WINDZ80OBJS) -o dz80.exe $(WINLIBS) $(OBJDIR)/d52.obj: d52.c defs.h d52.h dispass0.c d52pass1.h d52pass2.h dispass3.c d52table.h analyze.h analyze.c analyze52.h analyze52.c common.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/d48.obj: d48.c defs.h d48.h dispass0.c d48pass.h dispass3.c d48table.h common.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/dz80.obj: dz80.c defs.h dz80.h dispass0.c dz80pass1.h dz80pass2.h dispass3.c dz80table.h analyze.h analyze.c analyzez80.h analyzez80.c common.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/common.obj: common.c defs.h d52.h common.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/d52pass1.obj: d52pass1.c defs.h d52.h d52pass1.h d52pass2.h d52table.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/d52pass2.obj: d52pass2.c defs.h d52.h d52pass1.h d52pass2.h d52table.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/d52table.obj: d52table.c defs.h d52.h d52table.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/d48pass.obj: d48pass.c defs.h d48.h d48pass.h d48table.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/d48table.obj: d48table.c defs.h d48.h d48table.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/dz80pass1.obj: dz80pass1.c defs.h dz80.h dz80pass1.h dz80pass2.h dz80table.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/dz80pass2.obj: dz80pass2.c defs.h dz80.h dz80pass1.h dz80pass2.h dz80table.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/dz80table.obj: dz80table.c defs.h dz80.h dz80table.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/d80table.obj: d80table.c defs.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/analyze.obj: analyze.c defs.h analyze.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/analyze52.obj: analyze52.c defs.h d52.h analyze.h analyze.c analyze52.h d52pass2.h $(WINCC) -o $@ $(WINCFLAGS) -c $< $(OBJDIR)/analyzez80.obj: analyzez80.c defs.h d52.h analyze.h analyze.c analyzez80.h d52pass2.h $(WINCC) -o $@ $(WINCFLAGS) -c $< winclean: rm -f $(OBJDIR)/*.obj rm -f d52.exe d48.exe dz80.exe # end of file d52-3.4.1.orig/obj/0000775000175000017500000000000010666556505012024 5ustar uweuwed52-3.4.1.orig/README0000644000175000017500000001514210666325052012122 0ustar uweuwe D52 8052 Disassembler Version 3.4.1 (includes D48 and DZ80) ========================================================= Licence: GNU General Public License version 3 (see the file COPYING). NOTE: As Novell and Microsoft are in violation of the GPL, this software may not be distributed by either Novell or Microsoft. The same prohibition applies to any company that enters into an agreement with Microsoft regarding Microsoft's phony patent claims against Linux. In addition, no one who cannot honor ALL the requirements of GPL version 3 may distribute this software. The latest release version of D52 will always be available on 8052.com (or as long as Craig Steiner graciously allows me space on 8052.com--thanks Craig!). The disassemblers (with Linux and Windows binaries) are also available on my web site: http://home.pacbell.net/theposts. New Features: ------------- Version 3.3 now includes a code analysis option for the 8052 disassembler. The -t command line option causes D52 to trace and analyze the code in the file to be disassembled to determine which parts of the file are actually executable code, and which parts are data, such as ascii text, 8-bit binary data, 16-bit binary data or pointers. The results of the analysis are written to a control file which is then used in the disassembly process. Use of the -t option will overwrite any existing control file for the program to be disassembled, and so should only be used on the first disassembly. You may modify the control file with any text editor to correct any analysis errors or to add new directives for subsequent disassemblies of a file. The code analysis option is available only in D52 and DZ80. This feature should be considered beta test, although D52 as a whole is a mature program. History: -------- Version 3.4.1 Changed license to GNU General Public License Version 3. Improved code analysis routines. If code analysis (-t option) fails, outputs a warning message instead of an error message. Increased size of trace stacks for code analysis. Changed date/time output to year/month/day format. Added address offset directive ('o' control file directive that has the same effect as the x command line option. Fixed errors in 8048 cycle table. Applied Frieder Ferlemann's patch to allow hexadecimal values in the control file to optionally be prefixed with "0x" (ie: either 1234 or 0x1234). Fixed bug that would cause all data from an Intel hex record to be lost if the addresses for the block included 0ffffh. Version 3.4.0 Added cycle count directive('z' control file directive) and command line option to read cycle count file for d52 derivatives. Many thanks to Jan Waclawek for suggesting this feature and for implementing the code. Please read Jan's documetation in the 'cyclefiles' directory. Bug fixes for the 8048 disassembler. Improvements in output formatting. Improved control file error messages. Fixed bug that caused quoted operand symbols (ie: ' ') with non-visible characters to be truncated. Added Y directive. This is the same as the X directive except that an EQU statement will not be generated for the operand name. Added N directive to suppress automatic generation of a label for addresses referenced that are really constants instead of addresses. Added N command line option to output operands in C style (0xcd instead of 0cdh). Added P command line option to output pseudo ops with a leading dot (eg: .equ). Version 3.3.9 Adds dz80 flags -80 and -85 for disasembling with 8080 or 8085 mnemonics. Version 3.3.8 Fixes compile errors on Mac OSX and BSD unixes. Also fixed error in Z80 analysis trace routine. Thanks to Brian Foley for spotting these problems. Version 3.3.7 Adds the 'n' directive to suppress automatic generation of a label for a referenced address. Version 3.3.6 Now allows you to specify the file extension of the file to be disassembled (eg: d52 -d testfile.hex). If you specify the extention, the -b (binary), -h (Intel hex), and -c (CP/M .com file if using DZ80) flags are not required. Fixed bug that caused assembler pseudo opcodes to not be output in upper case if the -u option was given on the command line, but no control file existed for the file to be disassembled. Suppress generation of an equ statement for an address if a label for that address had already been output. (This bug would cause some cross- assemblers to output an error even though the value of the equ matched the address of the label.) The keil A51 option (-k) should be used only if you intend to re-assemble the output file using the older DOS version of A51. Version 3.3.5 Fixes bug with patch directive. Code cleanup and minor bug fixes. Will no longer abort if input file exceeds 64KB, but code beyond 64K will be ignored. Version 3.3.4 Adds a new command line option and a new control file directive. The -u option causes mnemonics, labels, symbols, etc to be output in upper case for cross assemblers that may require upper case code. Strings, literal data, and comments are not affected. The P directive is similar to the header comment directive (#) except that the user string will be output as code, rather than as a comment. May be useful for inserting include statements or macro definitions into the output file. A preliminary trace option has been added to the Z80 disassembler (DZ80), but is still experimental--use it with caution. V3.3.4 also includes some bug fixes. Version 3.3.3 Corrects a bug that would allow more than one equate statement to be generated for name symbols with the same value. Inline comments now allowed for byte (8-bit) data. Corrected endian problem with Z80 disassembler. Changed format of 'd' directive. Version 3.3.2 Allows inline comments after address and word data. Corrects a bug that would force word data following a header comment to be interpreted as byte data. Version 3.3.1 D52 corrects a bug regarding the Keil flag. Version 3.3 DZ80 now has a command line option (-c) to disassemble CP/M .com files, in addition to hex and binary files. The Future: ----------- Dis52, a GUI front end for D52, D48 and DZ80, is currently under development, and a preview version for Linux (or other Unix-like OS) is now available. (Due to flaws in the design of Windows, Dis52 is not available for Windows.) Dis52 requires the SDL (Simple DirectMedia Layer) library. SDL can be downloaded from http://www.libsdl.org. Jeff Post j_post pacbell net September, 2007