mirror of
https://github.com/pevans/erc-c.git
synced 2025-01-17 19:30:13 +00:00
Formerly "BAD" instructions are now forms of NOPs
But weird forms. In most cases they basically are NOPs, except with different opcodes. In other cases, we call them NP2 and NP3s, and do so because they consume 2 or 3 bytes respectively (vs. just 1 with NOP). We had to teach some arcane magic to the emulator for this to work. We may want to refactor to decouple the number of bytes consumed from the address mode.
This commit is contained in:
parent
691387894a
commit
978ad1faaf
@ -47,6 +47,8 @@ enum addr_mode {
|
||||
ABS, // absolute
|
||||
ABX, // absolute x-index
|
||||
ABY, // absolute y-index
|
||||
BY2, // Consume 2 bytes (for NP2)
|
||||
BY3, // Consume 3 bytes (for NP3)
|
||||
IMM, // immediate
|
||||
IMP, // implied
|
||||
IND, // indirect
|
||||
@ -102,6 +104,8 @@ enum instruction {
|
||||
LDY, // LoaD Y
|
||||
LSR, // Logical Shift Right
|
||||
NOP, // NO oPeration
|
||||
NP2, // No oPeration (2 bytes consumed)
|
||||
NP3, // No oPeration (3 bytes consumed)
|
||||
ORA, // OR with Accumulator
|
||||
PHA, // PusH Accumulator
|
||||
PHP, // PusH Predicate register
|
||||
|
@ -211,6 +211,8 @@ DECL_INST(ldx);
|
||||
DECL_INST(ldy);
|
||||
DECL_INST(lsr);
|
||||
DECL_INST(nop);
|
||||
DECL_INST(np2);
|
||||
DECL_INST(np3);
|
||||
DECL_INST(ora);
|
||||
DECL_INST(pha);
|
||||
DECL_INST(php);
|
||||
|
@ -19,22 +19,22 @@
|
||||
*/
|
||||
static int addr_modes[] = {
|
||||
// 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
|
||||
IMP, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, ACC, NOA, ABS, ABS, ABS, NOA, // 0x
|
||||
REL, IDY, ZPG, NOA, ZPG, ZPX, ZPX, NOA, IMP, ABY, ACC, NOA, ABS, ABX, ABX, NOA, // 1x
|
||||
ABS, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, ACC, NOA, ABS, ABS, ABS, NOA, // 2x
|
||||
REL, IDY, ZPG, NOA, ZPX, ZPX, ZPX, NOA, IMP, ABY, ACC, NOA, ABX, ABX, ABX, NOA, // 3x
|
||||
IMP, IDX, NOA, NOA, NOA, ZPG, ZPG, NOA, IMP, IMM, ACC, NOA, ABS, ABS, ABS, NOA, // 4x
|
||||
REL, IDY, ZPG, NOA, NOA, ZPX, ZPX, NOA, IMP, ABY, IMP, NOA, NOA, ABX, ABX, NOA, // 5x
|
||||
IMP, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, ACC, NOA, IND, ABS, ABS, NOA, // 6x
|
||||
REL, IDY, ZPG, NOA, ZPX, ZPX, ZPX, NOA, IMP, ABY, IMP, NOA, ABX, ABX, ABX, NOA, // 7x
|
||||
REL, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, IMP, NOA, ABS, ABS, ABS, NOA, // 8x
|
||||
REL, IDY, ZPG, NOA, ZPX, ZPX, ZPY, NOA, IMP, ABY, IMP, NOA, ABS, ABX, ABX, NOA, // 9x
|
||||
IMM, IDX, IMM, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, IMP, NOA, ABS, ABS, ABS, NOA, // Ax
|
||||
REL, IDY, ZPG, NOA, ZPX, ZPX, ZPY, NOA, IMP, ABY, IMP, NOA, ABX, ABX, ABY, NOA, // Bx
|
||||
IMM, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, IMP, NOA, ABS, ABS, ABS, NOA, // Cx
|
||||
REL, IDY, ZPG, NOA, NOA, ZPX, ZPX, NOA, IMP, ABY, IMP, NOA, NOA, ABX, ABX, NOA, // Dx
|
||||
IMM, IDX, NOA, NOA, ZPG, ZPG, ZPG, NOA, IMP, IMM, IMP, NOA, ABS, ABS, ABS, NOA, // Ex
|
||||
REL, IDY, ZPG, NOA, NOA, ZPX, ZPX, NOA, IMP, ABY, IMP, NOA, NOA, ABX, ABX, NOA, // Fx
|
||||
IMP, IDX, BY2, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, ACC, IMP, ABS, ABS, ABS, IMP, // 0x
|
||||
REL, IDY, ZPG, IMP, ZPG, ZPX, ZPX, IMP, IMP, ABY, ACC, IMP, ABS, ABX, ABX, IMP, // 1x
|
||||
ABS, IDX, BY2, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, ACC, IMP, ABS, ABS, ABS, IMP, // 2x
|
||||
REL, IDY, ZPG, IMP, ZPX, ZPX, ZPX, IMP, IMP, ABY, ACC, IMP, ABX, ABX, ABX, IMP, // 3x
|
||||
IMP, IDX, BY2, IMP, BY2, ZPG, ZPG, IMP, IMP, IMM, ACC, IMP, ABS, ABS, ABS, IMP, // 4x
|
||||
REL, IDY, ZPG, IMP, BY2, ZPX, ZPX, IMP, IMP, ABY, IMP, IMP, BY3, ABX, ABX, IMP, // 5x
|
||||
IMP, IDX, BY2, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, ACC, IMP, IND, ABS, ABS, IMP, // 6x
|
||||
REL, IDY, ZPG, IMP, ZPX, ZPX, ZPX, IMP, IMP, ABY, IMP, IMP, ABX, ABX, ABX, IMP, // 7x
|
||||
REL, IDX, BY2, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP, // 8x
|
||||
REL, IDY, ZPG, IMP, ZPX, ZPX, ZPY, IMP, IMP, ABY, IMP, IMP, ABS, ABX, ABX, IMP, // 9x
|
||||
IMM, IDX, IMM, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP, // Ax
|
||||
REL, IDY, ZPG, IMP, ZPX, ZPX, ZPY, IMP, IMP, ABY, IMP, IMP, ABX, ABX, ABY, IMP, // Bx
|
||||
IMM, IDX, BY2, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP, // Cx
|
||||
REL, IDY, ZPG, IMP, BY2, ZPX, ZPX, IMP, IMP, ABY, IMP, IMP, BY3, ABX, ABX, IMP, // Dx
|
||||
IMM, IDX, BY2, IMP, ZPG, ZPG, ZPG, IMP, IMP, IMM, IMP, IMP, ABS, ABS, ABS, IMP, // Ex
|
||||
REL, IDY, ZPG, IMP, BY2, ZPX, ZPX, IMP, IMP, ABY, IMP, IMP, BY3, ABX, ABX, IMP, // Fx
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -27,22 +27,22 @@
|
||||
*/
|
||||
static int instructions[] = {
|
||||
// 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
|
||||
BRK, ORA, BAD, BAD, TSB, ORA, ASL, BAD, PHP, ORA, ASL, BAD, TSB, ORA, ASL, BAD, // 0x
|
||||
BPL, ORA, ORA, BAD, TRB, ORA, ASL, BAD, CLC, ORA, INC, BAD, TRB, ORA, ASL, BAD, // 1x
|
||||
JSR, AND, BAD, BAD, BIT, AND, ROL, BAD, PLP, AND, ROL, BAD, BIT, AND, ROL, BAD, // 2x
|
||||
BMI, AND, AND, BAD, BIT, AND, ROL, BAD, SEC, AND, DEC, BAD, BIT, AND, ROL, BAD, // 3x
|
||||
RTI, EOR, BAD, BAD, BAD, EOR, LSR, BAD, PHA, EOR, LSR, BAD, JMP, EOR, LSR, BAD, // 4x
|
||||
BVC, EOR, EOR, BAD, BAD, EOR, LSR, BAD, CLI, EOR, PHY, BAD, BAD, EOR, LSR, BAD, // 5x
|
||||
RTS, ADC, BAD, BAD, STZ, ADC, ROR, BAD, PLA, ADC, ROR, BAD, JMP, ADC, ROR, BAD, // 6x
|
||||
BVS, ADC, ADC, BAD, STZ, ADC, ROR, BAD, SEI, ADC, PLY, BAD, JMP, ADC, ROR, BAD, // 7x
|
||||
BRA, STA, BAD, BAD, STY, STA, STX, BAD, DEY, BIM, TXA, BAD, STY, STA, STX, BAD, // 8x
|
||||
BCC, STA, STA, BAD, STY, STA, STX, BAD, TYA, STA, TXS, BAD, STZ, STA, STZ, BAD, // 9x
|
||||
LDY, LDA, LDX, BAD, LDY, LDA, LDX, BAD, TAY, LDA, TAX, BAD, LDY, LDA, LDX, BAD, // Ax
|
||||
BCS, LDA, LDA, BAD, LDY, LDA, LDX, BAD, CLV, LDA, TSX, BAD, LDY, LDA, LDX, BAD, // Bx
|
||||
CPY, CMP, BAD, BAD, CPY, CMP, DEC, BAD, INY, CMP, DEX, BAD, CPY, CMP, DEC, BAD, // Cx
|
||||
BNE, CMP, CMP, BAD, BAD, CMP, DEC, BAD, CLD, CMP, PHX, BAD, BAD, CMP, DEC, BAD, // Dx
|
||||
CPX, SBC, BAD, BAD, CPX, SBC, INC, BAD, INX, SBC, NOP, BAD, CPX, SBC, INC, BAD, // Ex
|
||||
BEQ, SBC, SBC, BAD, BAD, SBC, INC, BAD, SED, SBC, PLX, BAD, BAD, SBC, INC, BAD, // Fx
|
||||
BRK, ORA, NP2, NOP, TSB, ORA, ASL, NOP, PHP, ORA, ASL, NOP, TSB, ORA, ASL, NOP, // 0x
|
||||
BPL, ORA, ORA, NOP, TRB, ORA, ASL, NOP, CLC, ORA, INC, NOP, TRB, ORA, ASL, NOP, // 1x
|
||||
JSR, AND, NP2, NOP, BIT, AND, ROL, NOP, PLP, AND, ROL, NOP, BIT, AND, ROL, NOP, // 2x
|
||||
BMI, AND, AND, NOP, BIT, AND, ROL, NOP, SEC, AND, DEC, NOP, BIT, AND, ROL, NOP, // 3x
|
||||
RTI, EOR, NP2, NOP, NP2, EOR, LSR, NOP, PHA, EOR, LSR, NOP, JMP, EOR, LSR, NOP, // 4x
|
||||
BVC, EOR, EOR, NOP, NP2, EOR, LSR, NOP, CLI, EOR, PHY, NOP, NP3, EOR, LSR, NOP, // 5x
|
||||
RTS, ADC, NP2, NOP, STZ, ADC, ROR, NOP, PLA, ADC, ROR, NOP, JMP, ADC, ROR, NOP, // 6x
|
||||
BVS, ADC, ADC, NOP, STZ, ADC, ROR, NOP, SEI, ADC, PLY, NOP, JMP, ADC, ROR, NOP, // 7x
|
||||
BRA, STA, NP2, NOP, STY, STA, STX, NOP, DEY, BIM, TXA, NOP, STY, STA, STX, NOP, // 8x
|
||||
BCC, STA, STA, NOP, STY, STA, STX, NOP, TYA, STA, TXS, NOP, STZ, STA, STZ, NOP, // 9x
|
||||
LDY, LDA, LDX, NOP, LDY, LDA, LDX, NOP, TAY, LDA, TAX, NOP, LDY, LDA, LDX, NOP, // Ax
|
||||
BCS, LDA, LDA, NOP, LDY, LDA, LDX, NOP, CLV, LDA, TSX, NOP, LDY, LDA, LDX, NOP, // Bx
|
||||
CPY, CMP, NP2, NOP, CPY, CMP, DEC, NOP, INY, CMP, DEX, NOP, CPY, CMP, DEC, NOP, // Cx
|
||||
BNE, CMP, CMP, NOP, NP2, CMP, DEC, NOP, CLD, CMP, PHX, NOP, NP3, CMP, DEC, NOP, // Dx
|
||||
CPX, SBC, NP2, NOP, CPX, SBC, INC, NOP, INX, SBC, NOP, NOP, CPX, SBC, INC, NOP, // Ex
|
||||
BEQ, SBC, SBC, NOP, NP2, SBC, INC, NOP, SED, SBC, PLX, NOP, NP3, SBC, INC, NOP, // Fx
|
||||
};
|
||||
|
||||
/*
|
||||
@ -94,6 +94,8 @@ static mos6502_instruction_handler instruction_handlers[] = {
|
||||
INST_HANDLER(ldy),
|
||||
INST_HANDLER(lsr),
|
||||
INST_HANDLER(nop),
|
||||
INST_HANDLER(np2),
|
||||
INST_HANDLER(np3),
|
||||
INST_HANDLER(ora),
|
||||
INST_HANDLER(pha),
|
||||
INST_HANDLER(php),
|
||||
@ -132,22 +134,22 @@ static mos6502_instruction_handler instruction_handlers[] = {
|
||||
*/
|
||||
static int cycles[] = {
|
||||
// 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
|
||||
7, 6, 0, 0, 5, 3, 5, 0, 3, 2, 2, 0, 6, 4, 6, 0, // 0x
|
||||
2, 5, 5, 0, 5, 4, 6, 0, 2, 4, 2, 0, 6, 4, 6, 0, // 1x
|
||||
6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 4, 4, 6, 0, // 2x
|
||||
2, 5, 5, 0, 4, 4, 6, 0, 2, 4, 2, 0, 4, 4, 6, 0, // 3x
|
||||
6, 6, 0, 0, 0, 3, 5, 0, 3, 2, 2, 0, 3, 4, 6, 0, // 4x
|
||||
2, 5, 5, 0, 0, 4, 6, 0, 2, 4, 3, 0, 0, 4, 6, 0, // 5x
|
||||
6, 6, 0, 0, 3, 3, 5, 0, 4, 2, 2, 0, 5, 4, 6, 0, // 6x
|
||||
2, 5, 5, 0, 4, 4, 6, 0, 2, 4, 4, 0, 6, 4, 6, 0, // 7x
|
||||
3, 6, 0, 0, 3, 3, 3, 0, 2, 2, 2, 0, 4, 4, 4, 0, // 8x
|
||||
2, 6, 5, 0, 4, 4, 4, 0, 2, 5, 2, 0, 4, 5, 5, 0, // 9x
|
||||
2, 6, 2, 0, 3, 3, 3, 0, 2, 2, 2, 0, 4, 4, 4, 0, // Ax
|
||||
2, 5, 5, 0, 4, 4, 4, 0, 2, 4, 2, 0, 4, 4, 4, 0, // Bx
|
||||
2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 3, 0, // Cx
|
||||
2, 5, 5, 0, 0, 4, 6, 0, 2, 4, 3, 0, 0, 4, 7, 0, // Dx
|
||||
2, 6, 0, 0, 3, 3, 5, 0, 2, 2, 2, 0, 4, 4, 6, 0, // Ex
|
||||
2, 5, 5, 0, 0, 4, 6, 0, 2, 4, 4, 0, 0, 4, 7, 0, // Fx
|
||||
7, 6, 2, 1, 5, 3, 5, 1, 3, 2, 2, 1, 6, 4, 6, 1, // 0x
|
||||
2, 5, 5, 1, 5, 4, 6, 1, 2, 4, 2, 1, 6, 4, 6, 1, // 1x
|
||||
6, 6, 2, 1, 3, 3, 5, 1, 4, 2, 2, 1, 4, 4, 6, 1, // 2x
|
||||
2, 5, 5, 1, 4, 4, 6, 1, 2, 4, 2, 1, 4, 4, 6, 1, // 3x
|
||||
6, 6, 2, 1, 3, 3, 5, 1, 3, 2, 2, 1, 3, 4, 6, 1, // 4x
|
||||
2, 5, 5, 1, 4, 4, 6, 1, 2, 4, 3, 1, 8, 4, 6, 1, // 5x
|
||||
6, 6, 2, 1, 3, 3, 5, 1, 4, 2, 2, 1, 5, 4, 6, 1, // 6x
|
||||
2, 5, 5, 1, 4, 4, 6, 1, 2, 4, 4, 1, 6, 4, 6, 1, // 7x
|
||||
3, 6, 2, 1, 3, 3, 3, 1, 2, 2, 2, 1, 4, 4, 4, 1, // 8x
|
||||
2, 6, 5, 1, 4, 4, 4, 1, 2, 5, 2, 1, 4, 5, 5, 1, // 9x
|
||||
2, 6, 2, 1, 3, 3, 3, 1, 2, 2, 2, 1, 4, 4, 4, 1, // Ax
|
||||
2, 5, 5, 1, 4, 4, 4, 1, 2, 4, 2, 1, 4, 4, 4, 1, // Bx
|
||||
2, 6, 2, 1, 3, 3, 5, 1, 2, 2, 2, 1, 4, 4, 3, 1, // Cx
|
||||
2, 5, 5, 1, 4, 4, 6, 1, 2, 4, 3, 1, 4, 4, 7, 1, // Dx
|
||||
2, 6, 2, 1, 3, 3, 5, 1, 2, 2, 2, 1, 4, 4, 6, 1, // Ex
|
||||
2, 5, 5, 1, 4, 4, 6, 1, 2, 4, 4, 1, 4, 4, 7, 1, // Fx
|
||||
};
|
||||
|
||||
/*
|
||||
@ -462,6 +464,8 @@ mos6502_would_jump(int inst_code)
|
||||
inst_code == BVS ||
|
||||
inst_code == JMP ||
|
||||
inst_code == JSR ||
|
||||
inst_code == NP2 || // this is KIND of a hack, but it works!
|
||||
inst_code == NP3 || // these jump ahead by 2 or 3 bytes (respectively)
|
||||
inst_code == RTS ||
|
||||
inst_code == RTI;
|
||||
}
|
||||
|
@ -78,6 +78,8 @@ static char *instruction_strings[] = {
|
||||
"LDY",
|
||||
"LSR",
|
||||
"NOP",
|
||||
"NP2",
|
||||
"NP3",
|
||||
"ORA",
|
||||
"PHA",
|
||||
"PHP",
|
||||
@ -231,11 +233,17 @@ int
|
||||
mos6502_dis_expected_bytes(int addr_mode)
|
||||
{
|
||||
switch (addr_mode) {
|
||||
// This is kind of not a real address mode? We use it to tell
|
||||
// the code to skip three bytes for opcodes that use it.
|
||||
case BY3:
|
||||
return 3;
|
||||
|
||||
// These are 16-bit operands, because they work with absolute
|
||||
// addresses in memory.
|
||||
case ABS:
|
||||
case ABY:
|
||||
case ABX:
|
||||
case BY2: // (also not a real address mode!)
|
||||
case IND:
|
||||
return 2;
|
||||
|
||||
|
@ -68,6 +68,14 @@ DEFINE_INST(nop)
|
||||
// do nothing
|
||||
}
|
||||
|
||||
DEFINE_INST(np2)
|
||||
{
|
||||
}
|
||||
|
||||
DEFINE_INST(np3)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Here we return from an interrupt, which effectively resets the PC
|
||||
* register to the last value on the stack.
|
||||
|
@ -124,6 +124,8 @@ Test(mos6502, would_jump)
|
||||
case BVS:
|
||||
case JMP:
|
||||
case JSR:
|
||||
case NP2:
|
||||
case NP3:
|
||||
case RTS:
|
||||
case RTI:
|
||||
expect = true;
|
||||
|
@ -45,6 +45,13 @@ Test(mos6502_exec, jsr)
|
||||
cr_assert_eq(mos6502_pop_stack(cpu), 125);
|
||||
}
|
||||
|
||||
/*
|
||||
* In addition to nop, we also have np2 and np3 which also do nothing.
|
||||
* We're just passing on those.
|
||||
*
|
||||
* Test(mos6502_exec, np2)
|
||||
* Test(mos6502_exec, np3)
|
||||
*/
|
||||
Test(mos6502_exec, nop)
|
||||
{
|
||||
// currently this test does nothing -- we _should_ test to see if we
|
||||
|
Loading…
x
Reference in New Issue
Block a user