/*****************************************************************************/ /* */ /* */ /* 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" /* run z80 a single instruction */ void z80step(int extracond) { if (bdos_emulate && z80regs.pc == BDOS) check_BDOS_hook(); else if (extracond && z80regs.pc >= BIOS) { if (!check_BIOS_hook()) /* perform any I/O? */ return; /* invalid here! */ } singlestep(); /* if bios: perform return. else: do a step */ } struct breakpoint breakpoint[NBREAKS+1]; int break_at_BIOS = 0; /* run z80 with breakpoints on */ /* a breakpoint or listpoint sets either docontinue of mustbreak */ /* another breaking reason is a BIOS trap. BIOS traps break only */ /* if there is a breakpoint at the same location */ void z80run(void) { int i, docontinue, mustbreak; struct breakpoint *bp; /* special case to allow continuous pressing of 'b' */ z80step(break_at_BIOS); do { if (bdos_emulate && z80regs.pc == BDOS) check_BDOS_hook(); else if (z80regs.pc >= BIOS) { if (break_at_BIOS) { /* run until next BIOS call? */ break_at_BIOS = 0; return; } if (!check_BIOS_hook()) /* perform any I/O? */ return; /* invalid here! */ } docontinue = 0; mustbreak = 0; singlestep(); /* step over possible breakpoint */ bp = breakpoint; /* insert breakpoints */ for (i = 0; i <= NBREAKS; ++i, ++bp) if (bp->action) { bp->where &= 0xffff; bp->byte = z80mem[bp->where]; z80mem[bp->where] = 0x76; /* HALT instruction */ } if (bdos_emulate) z80mem[BDOS] = 0x76; emulate(); /* RUN! */ bp = breakpoint; /* remove breakpoints */ for (i = 0; i <= NBREAKS; ++i, ++bp) if (bp->action) z80mem[bp->where] = bp->byte; /* restore */ /* check for multi-breakpoints or different actions */ bp = breakpoint; /* remove breakpoints */ for (i = 0; i <= NBREAKS; ++i, ++bp) if (bp->action) if (z80regs.pc == bp->where) /* here we are */ if (++bp->curcnt == bp->maxcnt) { bp->curcnt = 0; switch (bp->action) { case AC_BREAK: mustbreak = 1; if (i != NBREAKS) printf("\r\nStopped at breakpoint %d\n", bp-breakpoint+1); break; case AC_LIST: dispregs(z80regs.pc); docontinue = 1; break; } } else docontinue = 1; /* count not reached */ if (!docontinue && !mustbreak) { /* reason code: TRAP or BIOS hook or BDOS hook */ if ((bdos_emulate && z80regs.pc == BDOS) || z80regs.pc >= BIOS) docontinue = 1; else debug = 2; /* TRAP */ } } while (docontinue); }