#include #include "../perfect6502.h" /* XXX hook up memory[] with RAM[] in runtime.c */ /************************************************************ * * Interface to OS Library Code / Monitor * ************************************************************/ extern int kernal_dispatch(); /* imported by runtime.c */ unsigned char A, X, Y, S, P; unsigned short PC; int N, Z, C; void init_monitor() { FILE *f; f = fopen("cbmbasic/cbmbasic.bin", "r"); fread(memory + 0xA000, 1, 17591, f); fclose(f); /* * fill the KERNAL jumptable with JMP $F800; * we will put code there later that loads * the CPU state and returns */ for (unsigned short addr = 0xFF90; addr < 0xFFF3; addr += 3) { memory[addr+0] = 0x4C; memory[addr+1] = 0x00; memory[addr+2] = 0xF8; } /* * cbmbasic scribbles over 0x01FE/0x1FF, so we can't start * with a stackpointer of 0 (which seems to be the state * after a RESET), so RESET jumps to 0xF000, which contains * a JSR to the actual start of cbmbasic */ memory[0xf000] = 0x20; memory[0xf001] = 0x94; memory[0xf002] = 0xE3; memory[0xfffc] = 0x00; memory[0xfffd] = 0xF0; } void handle_monitor(void *state) { PC = readPC(state); if (PC >= 0xFF90 && ((PC - 0xFF90) % 3 == 0)) { /* get register status out of 6502 */ A = readA(state); X = readX(state); Y = readY(state); S = readSP(state); P = readP(state); N = P >> 7; Z = (P >> 1) & 1; C = P & 1; kernal_dispatch(); /* encode processor status */ P &= 0x7C; /* clear N, Z, C */ P |= (N << 7) | (Z << 1) | C; /* * all KERNAL calls make the 6502 jump to $F800, so we * put code there that loads the return state of the * KERNAL function and returns to the caller */ memory[0xf800] = 0xA9; /* LDA #P */ memory[0xf801] = P; memory[0xf802] = 0x48; /* PHA */ memory[0xf803] = 0xA9; /* LHA #A */ memory[0xf804] = A; memory[0xf805] = 0xA2; /* LDX #X */ memory[0xf806] = X; memory[0xf807] = 0xA0; /* LDY #Y */ memory[0xf808] = Y; memory[0xf809] = 0x28; /* PLP */ memory[0xf80a] = 0x60; /* RTS */ /* * XXX we could do RTI instead of PLP/RTS, but RTI seems to be * XXX broken in the chip dump - after the KERNAL call at 0xFF90, * XXX the 6502 gets heavily confused about its program counter * XXX and executes garbage instructions */ } }