home *** CD-ROM | disk | FTP | other *** search
- /*****************************************************************************/
- /* */
- /* */
- /* CP/M emulator version 0.1 */
- /* */
- /* written by Michael Bischoff (mbi@mo.math.nat.tu-bs.de) */
- /* June-1994 */
- /* */
- /* This file is distributed under the GNU COPYRIGHT */
- /* see COPYRIGHT.GNU for Copyright details */
- /* */
- /* */
- /*****************************************************************************/
- #include "cpmemu.h"
-
- #define X 12 /* offset for memnonic */
- static const char *dtab1[] = { "B", "C", "D", "E", "H", "L", "(HL)", "A" };
- static const char *dtab2[] = { "BC", "DE", "HL", "SP" };
- /*static const char *dtab3[] = { "BC", "DE", "HL", "AF" }; */
- static const char *dtab4[] = { "NZ", "Z", "NC", "C", "PO", "PE", "P", "M" };
- static const char *dtab5[] = { "ADD A,", "ADC A,", "SUB ", "SBC A,", "AND ", "XOR ", "OR ", "CP " };
- static const char *op1tab[] = {
- "NOP", "LD BC,%04x", "LD (BC),A", "INC BC", NULL, NULL, NULL, "RLCA", "EX AF,AF'", "ADD HL,BC", "LD A,(BC)", "DEC BC", NULL, NULL, NULL, "RRCA",
- "DJNZ %04x", "LD DE,%04x", "LD (DE),A", "INC DE", NULL, NULL, NULL, "RLA", "JR %04x", "ADD HL,DE", "LD A,(DE)", "DEC DE", NULL, NULL, NULL, "RRA",
- "JR NZ,%04x", "LD HL,%04x", "LD (%04x),HL","INC HL", NULL, NULL, NULL, "DAA", "JR Z,%04x", "ADD HL,HL", "LD HL,(%04x)","DEC HL", NULL, NULL, NULL, "CPL",
- "JR NC,%04x", "LD SP,%04x", "LD (%04x),A", "INC SP", NULL, NULL, NULL, "SCF", "JR C,%04x", "ADD HL,SP", "LD A,(%04x)", "DEC SP", NULL, NULL, NULL, "CCF" };
- static const char *op2tab[] = {
- NULL, "POP BC", NULL, "JP %04x", NULL, "PUSH BC", NULL, NULL, NULL, "RET", NULL, "???", NULL, "CALL %04x", NULL, NULL,
- NULL, "POP DE", NULL, "OUT (%03x),A", NULL, "PUSH DE", NULL, NULL, NULL, "EXX", NULL, "IN A,(%03x)", NULL, "???", NULL, NULL,
- NULL, "POP HL", NULL, "EX (SP),HL", NULL, "PUSH HL", NULL, NULL, NULL, "JP (HL)", NULL, "EX DE,HL", NULL, "???", NULL, NULL,
- NULL, "POP AF", NULL, "DI", NULL, "PUSH AF", NULL, NULL, NULL, "LD SP,HL",NULL, "EI", NULL, "???", NULL, NULL };
- static const char *cbtab1[] = {
- "RLC", "RRC", "RL", "RR", "SLA", "SRA", "? SLIA", "SRL" };
- static const char *cbtab2[] = {
- NULL, "BIT", "RES", "SET" };
-
- static int numbytes;
-
- static void byte1(char *s, unsigned o) {
- static char hextab[] = "0123456789abcdef";
- s[3] = hextab[o >> 4];
- s[4] = hextab[o & 15];
- numbytes = 2;
- }
- static void byte2(char *s, unsigned o) {
- static char hextab[] = "0123456789abcdef";
- s[6] = hextab[o >> 4];
- s[7] = hextab[o & 15];
- numbytes = 3;
- }
- static void byte3(char *s, unsigned o) {
- static char hextab[] = "0123456789abcdef";
- s[9] = hextab[o >> 4];
- s[10] = hextab[o & 15];
- numbytes = 4;
- }
- static void word1(char *s, unsigned w) {
- byte1(s, w & 0xff);
- byte2(s, w >> 8);
- }
- static void word2(char *s, unsigned w) {
- byte2(s, w & 0xff);
- byte3(s, w >> 8);
- }
-
- static const char *bdosfunc[] = {
- /* 00 */ "System Reset", "Console Input", "Console Output",
- /* 03 */ "Aux. Input", "Aux. Output", "List Output",
- /* 06 */ "Direct I/O", "Aux. Input Status", "Aux. Output Status",
- /* 09 */ "Print String", "Read Console Buffer", "Get Console Status",
- /* 12 */ "Return Version Number", "Reset Disk System",
- /* 14 */ "Select Disk", "Open File", "Close File",
- /* 17 */ "Search for First", "Search for Next", "Delete File",
- /* 20 */ "Read Sequential", "Write Sequential", "Make File",
- /* 23 */ "Rename File", "Return Login Vector", "Return Current Disk",
- /* 26 */ "Set DMA Address", "Get Addr(Alloc)", "Write Protect Disk",
- /* 29 */ "Get R/O-Vector", "Set File Attributes", "Get Addr. of DPB",
- /* 32 */ "Set/Get User Code", "Read Random", "Write Random",
- /* 35 */ "Compute File Size", "Set Random Record", "Reset Drive",
- /* 38 */ "Access Drive", "Free Drive" };
- /* extension: 40: change directory */
-
- static char *disassemble(unsigned pc) {
- static char s[60];
- int o, m, r, b, w;
-
- numbytes = 1;
- if (pc >= BIOS) {
- switch (pc) {
- case 0xff6c:
- case BIOS: sprintf(s, "BIOS COLDBOOT");
- break;
- case 0xff6d:
- case BIOS+3: sprintf(s, "BIOS WARMBOOT");
- break;
- case 0xff6e:
- case BIOS+6: sprintf(s, "BIOS Console Status");
- break;
- case 0xff6f:
- case BIOS+9: sprintf(s, "BIOS Console Input");
- break;
- case 0xff70:
- case BIOS+0x0c: sprintf(s, "BIOS Console Output");
- break;
- case 0xff71:
- case BIOS+0x0f: sprintf(s, "BIOS List Output");
- break;
- case 0xff72:
- case BIOS+0x12: sprintf(s, "BIOS Punch Output");
- break;
- case 0xff73:
- case BIOS+0x15: sprintf(s, "BIOS Reader Input");
- break;
- case 0xff74:
- case BIOS+0x18: sprintf(s, "BIOS Home");
- break;
- case 0xff75:
- case BIOS+0x1b: sprintf(s, "BIOS Select Disk");
- break;
- case 0xff76:
- case BIOS+0x1e: sprintf(s, "BIOS Set Track");
- break;
- case 0xff77:
- case BIOS+0x21: sprintf(s, "BIOS Set Sector");
- break;
- case 0xff78:
- case BIOS+0x24: sprintf(s, "BIOS Set DMA");
- break;
- case 0xff79:
- case BIOS+0x27: sprintf(s, "BIOS Read");
- break;
- case 0xff7a:
- case BIOS+0x2a: sprintf(s, "BIOS Write");
- break;
- case 0xff7b:
- case BIOS+0x2d: sprintf(s, "BIOS List Status");
- break;
- case 0xff7c:
- case BIOS+0x30: sprintf(s, "BIOS Sector Translate");
- break;
- default: sprintf(s, "BIOS");
- }
- return s;
- } else if ((pc == BDOS || pc == 5) && z80regs.pc == pc) {
- if ((z80regs.bc & 0xff) < sizeof(bdosfunc) / sizeof(bdosfunc[0]))
- sprintf(s, "BDOS %s", bdosfunc[z80regs.bc & 0xff]);
- else
- sprintf(s, "BDOS (0x%02x)", z80regs.bc & 0xff);
- return s;
- }
- o = z80mem[pc];
- sprintf(s, "%02x ", o);
- m = (o >> 3) & 7;
- r = o & 7;
- switch (o >> 6) {
- case 0: switch(o & 7) {
- case 4: sprintf(s+X, "INC %s", dtab1[m]);
- break;
- case 5: sprintf(s+X, "DEC %s", dtab1[m]);
- break;
- case 6: sprintf(s+X, "LD %s,0%02x", dtab1[m], b = z80mem[pc+1]);
- byte1(s, b);
- break;
- default:switch (o) {
- case 0x22: case 0x2a: case 0x32: case 0x3a:
- case 0x01: case 0x11: case 0x21: case 0x31:
- w = z80mem[pc+1] + (z80mem[pc+2] << 8);
- word1(s, w);
- break;
- case 0x08: case 0x10: case 0x18: case 0x20: case 0x28: case 0x30: case 0x38:
- w = ((char *)z80mem)[pc+1];
- byte1(s, w & 0xff);
- w += pc + 2;
- break;
- }
- sprintf(s+X, op1tab[o], w);
- break;
- }
- break;
- case 1: if (o != 0x76)
- sprintf(s+X, "LD %s,%s", dtab1[m], dtab1[r]);
- else
- strcpy(s+X, "HALT");
- break;
- case 2: strcpy(s+X, dtab5[m]);
- strcat(s+X, dtab1[r]);
- break;
- case 3: switch(o & 7) {
- case 0: sprintf(s+X, "RET %s", dtab4[m]);
- break;
- case 2: w = z80mem[pc+1] + (z80mem[pc+2] << 8);
- word1(s, w);
- sprintf(s+X, "JP %s,%04x", dtab4[m], w);
- break;
- case 4: w = z80mem[pc+1] + (z80mem[pc+2] << 8);
- word1(s, w);
- sprintf(s+X, "CALL %s,%04x", dtab4[m], w);
- break;
- case 6: w = z80mem[pc+1];
- sprintf(s+X, "%s0%02x", dtab5[m], w);
- byte1(s, w);
- break;
- case 7: sprintf(s+X, "RST %03xH", m << 3);
- break;
- default:switch (o) {
- case 0xc3: case 0xcd:
- w = z80mem[pc+1] + (z80mem[pc+2] << 8);
- word1(s, w);
- break;
- case 0xd3: case 0xdb:
- w = z80mem[pc+1];
- break;
- case 0xcb:
- o = z80mem[pc+1];
- byte1(s, o);
- m = (o >> 3) & 7;
- r = o & 7;
- if (o & 0xc0)
- sprintf(s+X, "%s %d,%s", cbtab2[o >> 6], m, dtab1[r]);
- else
- sprintf(s+X, "%s %s", cbtab1[m], dtab1[r]);
- return s;
- case 0xed:
- o = z80mem[pc+1];
- byte1(s, o);
- switch (o & 0xcf) {
- case 0x42: sprintf(s+X, "SBC HL,%s", dtab2[(o & 0x30) >> 4]);
- break;
- case 0x43: w = z80mem[pc+2] + (z80mem[pc+3] << 8);
- word2(s, w);
- sprintf(s+X, "LD (%04x),%s", w, dtab2[(o & 0x30) >> 4]);
- break;
- case 0x4a: sprintf(s+X, "ADC HL,%s", dtab2[(o & 0x30) >> 4]);
- break;
- case 0x4b: w = z80mem[pc+2] + (z80mem[pc+3] << 8);
- word2(s, w);
- sprintf(s+X, "LD %s,(%04x)", dtab2[(o & 0x30) >> 4], w);
- break;
- default: switch (o) {
- case 0x44: sprintf(s+X, "NEG");
- break;
- case 0xa0: sprintf(s+X, "LDI");
- break;
- case 0xb0: sprintf(s+X, "LDIR");
- break;
- case 0xb8: sprintf(s+X, "LDDR");
- break;
- default: sprintf(s+X, "unrec.");
- }
- }
- return s;
- }
- sprintf(s+X, op2tab[o & 63], w);
- break;
- }
- break;
- }
- return s;
- }
-
- void disassem(unsigned *loc, int num) {
- while (num--) {
- printf("%04x %s\n", *loc, disassemble(*loc));
- *loc = (*loc + numbytes) & 0xffff;
- }
- }
-
- static char *flags(unsigned f) {
- static char s[10];
- const char *fl = "SZ0H0VNC";
- int i;
- strcpy(s, " ");
- for (i = 0; i < 8; ++i) {
- if (f & 0x80)
- s[i] = fl[i];
- f <<= 1;
- }
- return s;
- }
-
- void dispregs(unsigned pc) {
- printf("%s A=%02x BC=%04x DE=%04x HL=%04x SP=%04x PC=%04x %s\n",
- flags(z80regs.af >> 8), z80regs.af & 0xff,
- z80regs.bc, z80regs.de, z80regs.hl, z80regs.sp,
- pc, disassemble(pc));
- fflush(stdout);
- }
-
- void dispregs2(void) {
- printf("%s a=%02x bc=%04x de=%04x hl=%04x IX=%04x IY=%04x I=%02x R=%02x\n",
- flags(z80regs.af2 >> 8), z80regs.af2 & 0xff,
- z80regs.bc2, z80regs.de2, z80regs.hl2, z80regs.ix, z80regs.iy, z80regs.ir >> 8, z80regs.ir & 0xff);
- fflush(stdout);
- }
-
- void memdump(unsigned addr, int lines) {
- int i, j;
- for (i = 0; i < lines; ++i) {
- printf("%04x ", addr);
- for (j = 0; j < 16; ++j) {
- if (j == 8)
- printf(" -");
- printf(" %02x", z80mem[addr+j]);
- }
- printf(" ");
- for (j = 0; j < 16; ++j) {
- if (j == 8)
- printf(" ");
- printf("%c", z80mem[addr+j] < ' ' ? '.' : z80mem[addr+j]);
- }
- printf("\n");
- addr += 16;
- }
- }
-