1
0
mirror of https://github.com/mist64/perfect6502.git synced 2024-06-08 12:29:28 +00:00
This commit is contained in:
Michael Steil 2010-09-23 08:06:26 +00:00
parent 5404b65b21
commit 36fe254fae

View File

@ -81,7 +81,6 @@ setupNodesAndTransistors()
count_t i;
for (i = 0; i < sizeof(segdefs)/sizeof(*segdefs); i++) {
nodes_pullup[i] = segdefs[i];
nodes_state[i] = STATE_FL;
nodes_gatecount[i] = 0;
nodes_c1c2count[i] = 0;
}
@ -97,6 +96,8 @@ setupNodesAndTransistors()
nodes_c1c2s[c1][nodes_c1c2count[c1]++] = i;
nodes_c1c2s[c2][nodes_c1c2count[c2]++] = i;
}
nodes_state[ngnd] = STATE_GND;
nodes_state[npwr] = STATE_VCC;
}
#ifdef DEBUG
@ -577,26 +578,6 @@ chipStatus()
readNOTIR() ^ 0xFF);
}
/************************************************************
*
* Main CLock Loop
*
************************************************************/
void
halfStep()
{
BOOL clk = isNodeHigh(clk0);
setNode(clk0, !clk);
if (clk && isNodeHigh(rw))
writeDataBus(mRead(readAddressBus()));
if (!clk && !isNodeHigh(rw))
mWrite(readAddressBus(), readDataBus());
}
/************************************************************
*
* Interface to OS Library Code / Monitor
@ -610,12 +591,24 @@ init_monitor()
f = fopen("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 (uint16_t 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;
@ -628,7 +621,9 @@ void
handle_monitor()
{
PC = readPC();
if (PC >= 0xFF90 && ((PC - 0xFF90) % 3 == 0) && isNodeHigh(clk0)) {
/* get register status out of 6502 */
A = readA();
X = readX();
Y = readY();
@ -640,64 +635,54 @@ handle_monitor()
kernal_dispatch();
/* encode processor status */
P &= 0x7C; // clear N, Z, C
P |= (N << 7) | (Z << 1) | C;
/*
LDA #P
PHA
LDA #A
LDX #X
LDY #Y
PLP
RTS
//XXX we could do RTI instead, but RTI is broken!
*/
memory[0xf800] = 0xA9;
* 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;
memory[0xf803] = 0xA9;
memory[0xf802] = 0x48; /* PHA */
memory[0xf803] = 0xA9; /* LHA #A */
memory[0xf804] = A;
memory[0xf805] = 0xA2;
memory[0xf805] = 0xA2; /* LDX #X */
memory[0xf806] = X;
memory[0xf807] = 0xA0;
memory[0xf807] = 0xA0; /* LDY #Y */
memory[0xf808] = Y;
memory[0xf809] = 0x28;
memory[0xf80a] = 0x60;
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
*/
}
}
/************************************************************
*
* Initialization
* Main Clock Loop
*
************************************************************/
void
initChip()
halfStep()
{
for (nodenum_t nn = 0; nn < NODES; nn++)
nodes_state[nn] = STATE_FL;
nodes_state[ngnd] = STATE_GND;
nodes_state[npwr] = STATE_VCC;
for (transnum_t tn = 0; tn < TRANSISTORS; tn++)
set_transistors_on(tn, NO);
setLow(res);
setLow(clk0);
setHigh(rdy);
setLow(so);
setHigh(irq);
setHigh(nmi);
recalcAllNodes();
BOOL clk = isNodeHigh(clk0);
/* hold RESET for 8 cycles to finish executing instruction */
for (int i = 0; i < 16; i++)
setNode(clk0, !(i & 1));
/* invert clock */
setNode(clk0, !clk);
setHigh(res);
cycle = 0;
/* handle memory reads and writes */
if (clk && isNodeHigh(rw))
writeDataBus(mRead(readAddressBus()));
if (!clk && !isNodeHigh(rw))
mWrite(readAddressBus(), readDataBus());
}
void
@ -711,29 +696,52 @@ step()
handle_monitor();
}
/************************************************************
*
* Initialization
*
************************************************************/
void
steps()
initChip()
{
#ifdef DEBUG
printf("%s\n", __func__);
#endif
for (;;)
/* all nodes are floating */
for (nodenum_t nn = 0; nn < NODES; nn++)
nodes_state[nn] = STATE_FL;
/* all transistors are off */
for (transnum_t tn = 0; tn < TRANSISTORS; tn++)
set_transistors_on(tn, NO);
cycle = 0;
setLow(res);
setLow(clk0);
setHigh(rdy);
setLow(so);
setHigh(irq);
setHigh(nmi);
recalcAllNodes();
/* hold RESET for 8 cycles */
for (int i = 0; i < 16; i++)
step();
}
void
setup()
{
setupNodesAndTransistors();
initChip();
init_monitor();
steps();
/* release RESET */
setHigh(res);
}
int
main()
{
setup();
return 0;
/* set up data structures for efficient emulation */
setupNodesAndTransistors();
/* set initial state of nodes, transistors, inputs; RESET chip */
initChip();
/* set up memory for user program */
init_monitor();
/* emulate the 6502! */
for (;;)
step();
}