perfect6502/cbmbasic/runtime_init.c

99 lines
2.3 KiB
C

#include <stdio.h>
#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
*/
}
}