Reputation: 633
I finally got to the point where my 6502 emulator passed all of the tests in AllSuiteA.asm, but my emulator is failing to emulate Enhanced Basic, which I have loaded at $C000. What happens is PC slowly climbs up to $C03E, and then JSRs to $C892. After that it steadily rises until $C908, where it JSRs again to $E0ED, and then JMPs indirectly to $0.
Why is Enhanced Basic infinitely looping, despite AllSuiteA saying my emulator was fine?
Here are the relevant functions:
Opcodes:
JSR:
case "JSR":
var t = pc + 1;
memory[0x0100 + sp] = (t & 0xFF00) >> 8;
sp--;
memory[0x0100 + sp] = t & 0x00FF;
sp--;
pc = address - opcode[2];
break;
JMP:
case "JMP":
pc = address - opcode[2];
break;
Addressing Modes:
IND:
case "IND":
var b1 = memory[pc + 1];
var b2 = memory[pc + 2];
var mem = (b2 << 8) | b1;
var bb1 = memory[mem];
var bb2 = memory[mem + 1];
address = (bb2 << 8) | bb1;
break;
ABS:
case "ABS":
var b1 = memory[pc + 1];
var b2 = memory[pc + 2];
address = (b2 << 8) | b1;
break;
Note: opcode[2] is the number of bytes of the opcode being executed
And here is a JSFiddle of the running program. Included in this fiddle is a hexadecimal representation of ehbasic.bin.
Upvotes: 3
Views: 395
Reputation: 100622
Short version: as you have your assemble configured, your CPU needs to simulate a reset, not just jump in at C000
. Jump in at FF80
if you just want to fix things in a single line.
Working from the source code:
C892
is LAB_CRLF
, which should "print CR/LF".
The first thing that routine does is load A with 0D
and then JSR LAB_PRNA
to output that. That takes you up to C8ED
.
The code there compares the character to be printed to ' ' and branches to LAB_18F9
/ C90A
upon discovering that it's printing a control character.
At C90A
is the long jump to E0ED
, which is V_OUTP
. That's just an indirect JSR
through VEC_OUT
, which is at 0207
. Your code appears to find only 00
s at 0207
and 0208
so vectors incorrectly.
It looks like you're using min_mon.asm
. That sets up the relevant input/output vectors as part of the reset routine at FF80
(which is reached from the 6502 reset vector, at FFFC
). However your emulator doesn't emulate a reset, it just starts with PC = C000
.
Hence the vectors are never initialised and the jump, though correctly emulated, doesn't go to where it should.
Upvotes: 3