NAME__
NAME__

Reputation: 633

6502 Emulation Enhanced Basic Infinite Loop $C000 to $E0ED

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

Answers (1)

Tommy
Tommy

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 00s 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

Related Questions