/*****************************************************************************/ /* */ /* */ /* 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 */ /* */ /* */ /*****************************************************************************/ /* this module is inoperable */ #include "cpmemu.h" static int numbytes; static void byte(char *s, unsigned o) { static char hextab[] = "0123456789abcdef"; s[0] = hextab[o >> 4]; s[1] = hextab[o & 15]; } #define NBIOSCALLS 17 static int dis_sub(unsigned pc, char *s) { if (pc >= BIOS) { static const char *biosfunc[] = { "COLDBOOT", "WARMBOOT", "Console Status", "Console Input", "Console Output", "List Output", "Punch Output", "Reader Input", "Home", "Select Disk", "Set Track", "Set Sector", "Set DMA", "Read", "Write", "List Status", "Sector Translate" }; #if 0 /* here are jumps which may lead elsewhere */ if (pc < BIOS + 3 * NBIOSCALLS && !((pc-BIOS) % 3)) { sprintf(s, "BIOS %s\n", biosfunc[(pc-BIOS)/3]); return 3; } #endif if (pc >= 0xff6cU && pc < 0xff6cU+NBIOSCALLS) { sprintf(s, "BIOS %s", biosfunc[pc-0xff6cU]); return 1; } if (pc < BIOS + 3 * NBIOSCALLS && !((pc-BIOS) % 3)) ; else { sprintf(s, "BIOS (illegal place)"); return 1; } } if ((pc == BDOS || pc == 5) && z80regs.pc == pc) { 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", "Write Random with Zero Fill", /* 41 */ "Change directory (extension)" }; if ((z80regs.bc & 0xff) < sizeof(bdosfunc) / sizeof(bdosfunc[0])) sprintf(s, "BDOS %s, arg %04x", bdosfunc[z80regs.bc & 0xff], z80regs.de); else sprintf(s, "BDOS (0x%02x), arg %04x", z80regs.bc & 0xff, z80regs.de); return 3; } { unsigned const char *PC; PC = disz80(z80mem+pc, s, pc); if (!(PC - z80mem - pc)) { sprintf(s, "unknown"); return 1; } return PC - z80mem - pc; } } static char *disassemble(unsigned pc) { static char s[60]; int i; numbytes = dis_sub(pc, s+12); memset(s, ' ', 12); for (i = 0; i < numbytes; ++i) byte(s+3*i, z80mem[pc+i]); 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; } }