Fixes #108 Bring back the --strict option

This commit is contained in:
Stefan Arentz 2016-12-28 23:13:05 -05:00
parent 692d8a42ac
commit a5fdc45431
4 changed files with 132 additions and 109 deletions

View File

@ -111,8 +111,10 @@ static int cpu_execute_instruction(struct cpu_t *cpu) {
/* Fetch instruction */
struct cpu_instruction_t *i = &cpu->instructions[mem_get_byte(cpu, cpu->state.pc)];
if (i->handler == NULL) {
return EWM_CPU_ERR_UNIMPLEMENTED_INSTRUCTION;
if (i->name[0] == '?') {
if (cpu->strict) {
return EWM_CPU_ERR_UNIMPLEMENTED_INSTRUCTION;
}
}
// If strict mode and if we need the stack, check if that works out

214
src/ins.c
View File

@ -907,272 +907,276 @@ static void tya(struct cpu_t *cpu) {
update_zn(cpu, cpu->state.a);
}
static void unimplemented(struct cpu_t *cpu) {
// This is handled in cpu_execute_instruction() if strict mode is enabled.
}
/* Instruction dispatch table */
struct cpu_instruction_t instructions[256] = {
/* 0x00 */ { "BRK", 0x00, 1, 2, 3, (void*) brk },
/* 0x01 */ { "ORA", 0x01, 2, 6, 0, (void*) ora_indx },
/* 0x02 */ { "???", 0x02, 1, 2, 0, (void*) NULL },
/* 0x03 */ { "???", 0x03, 1, 2, 0, (void*) NULL },
/* 0x04 */ { "???", 0x04, 1, 2, 0, (void*) NULL },
/* 0x02 */ { "???", 0x02, 1, 2, 0, (void*) unimplemented },
/* 0x03 */ { "???", 0x03, 1, 2, 0, (void*) unimplemented },
/* 0x04 */ { "???", 0x04, 1, 2, 0, (void*) unimplemented },
/* 0x05 */ { "ORA", 0x05, 2, 2, 0, (void*) ora_zpg },
/* 0x06 */ { "ASL", 0x06, 2, 5, 0, (void*) asl_zpg },
/* 0x07 */ { "???", 0x07, 1, 2, 0, (void*) NULL },
/* 0x07 */ { "???", 0x07, 1, 2, 0, (void*) unimplemented },
/* 0x08 */ { "PHP", 0x08, 1, 3, 0, (void*) php },
/* 0x09 */ { "ORA", 0x09, 2, 2, 0, (void*) ora_imm },
/* 0x0a */ { "ASL", 0x0a, 1, 2, 0, (void*) asl_acc },
/* 0x0b */ { "???", 0x0b, 1, 2, 0, (void*) NULL },
/* 0x0c */ { "???", 0x0c, 1, 2, 0, (void*) NULL },
/* 0x0b */ { "???", 0x0b, 1, 2, 0, (void*) unimplemented },
/* 0x0c */ { "???", 0x0c, 1, 2, 0, (void*) unimplemented },
/* 0x0d */ { "ORA", 0x0d, 3, 4, 0, (void*) ora_abs },
/* 0x0e */ { "ASL", 0x0e, 3, 6, 0, (void*) asl_abs },
/* 0x0f */ { "???", 0x0f, 1, 2, 0, (void*) NULL },
/* 0x0f */ { "???", 0x0f, 1, 2, 0, (void*) unimplemented },
/* 0x10 */ { "BPL", 0x10, 2, 2, 0, (void*) bpl },
/* 0x11 */ { "ORA", 0x11, 2, 5, 0, (void*) ora_indy },
/* 0x12 */ { "???", 0x12, 1, 2, 0, (void*) NULL },
/* 0x13 */ { "???", 0x13, 1, 2, 0, (void*) NULL },
/* 0x14 */ { "???", 0x14, 1, 2, 0, (void*) NULL },
/* 0x12 */ { "???", 0x12, 1, 2, 0, (void*) unimplemented },
/* 0x13 */ { "???", 0x13, 1, 2, 0, (void*) unimplemented },
/* 0x14 */ { "???", 0x14, 1, 2, 0, (void*) unimplemented },
/* 0x15 */ { "ORA", 0x15, 2, 3, 0, (void*) ora_zpgx },
/* 0x16 */ { "ASL", 0x16, 2, 6, 0, (void*) asl_zpgx },
/* 0x17 */ { "???", 0x17, 1, 2, 0, (void*) NULL },
/* 0x17 */ { "???", 0x17, 1, 2, 0, (void*) unimplemented },
/* 0x18 */ { "CLC", 0x18, 1, 2, 0, (void*) clc },
/* 0x19 */ { "ORA", 0x19, 3, 4, 0, (void*) ora_absy },
/* 0x1a */ { "???", 0x1a, 1, 2, 0, (void*) NULL },
/* 0x1b */ { "???", 0x1b, 1, 2, 0, (void*) NULL },
/* 0x1c */ { "???", 0x1c, 1, 2, 0, (void*) NULL },
/* 0x1a */ { "???", 0x1a, 1, 2, 0, (void*) unimplemented },
/* 0x1b */ { "???", 0x1b, 1, 2, 0, (void*) unimplemented },
/* 0x1c */ { "???", 0x1c, 1, 2, 0, (void*) unimplemented },
/* 0x1d */ { "ORA", 0x1d, 3, 4, 0, (void*) ora_absx },
/* 0x1e */ { "ASL", 0x1e, 3, 7, 0, (void*) asl_absx },
/* 0x1f */ { "???", 0x1f, 1, 2, 0, (void*) NULL },
/* 0x1f */ { "???", 0x1f, 1, 2, 0, (void*) unimplemented },
/* 0x20 */ { "JSR", 0x20, 3, 6, 2, (void*) jsr_abs },
/* 0x21 */ { "AND", 0x21, 2, 6, 0, (void*) and_indx },
/* 0x22 */ { "???", 0x22, 1, 2, 0, (void*) NULL },
/* 0x23 */ { "???", 0x23, 1, 2, 0, (void*) NULL },
/* 0x22 */ { "???", 0x22, 1, 2, 0, (void*) unimplemented },
/* 0x23 */ { "???", 0x23, 1, 2, 0, (void*) unimplemented },
/* 0x24 */ { "BIT", 0x24, 2, 3, 0, (void*) bit_zpg },
/* 0x25 */ { "AND", 0x25, 2, 3, 0, (void*) and_zpg },
/* 0x26 */ { "ROL", 0x26, 2, 5, 0, (void*) rol_zpg },
/* 0x27 */ { "???", 0x27, 1, 2, 0, (void*) NULL },
/* 0x27 */ { "???", 0x27, 1, 2, 0, (void*) unimplemented },
/* 0x28 */ { "PLP", 0x28, 1, 4, 0, (void*) plp },
/* 0x29 */ { "AND", 0x29, 2, 2, 0, (void*) and_imm },
/* 0x2a */ { "ROL", 0x2a, 1, 2, 0, (void*) rol_acc },
/* 0x2b */ { "???", 0x2b, 1, 2, 0, (void*) NULL },
/* 0x2b */ { "???", 0x2b, 1, 2, 0, (void*) unimplemented },
/* 0x2c */ { "BIT", 0x2c, 3, 4, 0, (void*) bit_abs },
/* 0x2d */ { "AND", 0x2d, 3, 4, 0, (void*) and_abs },
/* 0x2e */ { "ROL", 0x2e, 3, 6, 0, (void*) rol_abs },
/* 0x2f */ { "???", 0x2f, 1, 2, 0, (void*) NULL },
/* 0x2f */ { "???", 0x2f, 1, 2, 0, (void*) unimplemented },
/* 0x30 */ { "BMI", 0x30, 2, 2, 0, (void*) bmi },
/* 0x31 */ { "AND", 0x31, 2, 5, 0, (void*) and_indy },
/* 0x32 */ { "???", 0x32, 1, 2, 0, (void*) NULL },
/* 0x33 */ { "???", 0x33, 1, 2, 0, (void*) NULL },
/* 0x34 */ { "???", 0x34, 1, 2, 0, (void*) NULL },
/* 0x32 */ { "???", 0x32, 1, 2, 0, (void*) unimplemented },
/* 0x33 */ { "???", 0x33, 1, 2, 0, (void*) unimplemented },
/* 0x34 */ { "???", 0x34, 1, 2, 0, (void*) unimplemented },
/* 0x35 */ { "AND", 0x35, 2, 4, 0, (void*) and_zpgx },
/* 0x36 */ { "ROL", 0x36, 2, 6, 0, (void*) rol_zpgx },
/* 0x37 */ { "???", 0x37, 1, 2, 0, (void*) NULL },
/* 0x37 */ { "???", 0x37, 1, 2, 0, (void*) unimplemented },
/* 0x38 */ { "SEC", 0x38, 1, 2, 0, (void*) sec },
/* 0x39 */ { "AND", 0x39, 3, 4, 0, (void*) and_absy },
/* 0x3a */ { "???", 0x3a, 1, 2, 0, (void*) NULL },
/* 0x3b */ { "???", 0x3b, 1, 2, 0, (void*) NULL },
/* 0x3c */ { "???", 0x3c, 1, 2, 0, (void*) NULL },
/* 0x3a */ { "???", 0x3a, 1, 2, 0, (void*) unimplemented },
/* 0x3b */ { "???", 0x3b, 1, 2, 0, (void*) unimplemented },
/* 0x3c */ { "???", 0x3c, 1, 2, 0, (void*) unimplemented },
/* 0x3d */ { "AND", 0x3d, 3, 4, 0, (void*) and_absx },
/* 0x3e */ { "ROL", 0x3e, 3, 7, 0, (void*) rol_absx },
/* 0x3f */ { "???", 0x3f, 1, 2, 0, (void*) NULL },
/* 0x3f */ { "???", 0x3f, 1, 2, 0, (void*) unimplemented },
/* 0x40 */ { "RTI", 0x40, 1, 6, -3, (void*) rti },
/* 0x41 */ { "EOR", 0x41, 2, 6, 0, (void*) eor_indx },
/* 0x42 */ { "???", 0x42, 1, 2, 0, (void*) NULL },
/* 0x43 */ { "???", 0x43, 1, 2, 0, (void*) NULL },
/* 0x44 */ { "???", 0x44, 1, 2, 0, (void*) NULL },
/* 0x42 */ { "???", 0x42, 1, 2, 0, (void*) unimplemented },
/* 0x43 */ { "???", 0x43, 1, 2, 0, (void*) unimplemented },
/* 0x44 */ { "???", 0x44, 1, 2, 0, (void*) unimplemented },
/* 0x45 */ { "EOR", 0x45, 2, 3, 0, (void*) eor_zpg },
/* 0x46 */ { "LSR", 0x46, 2, 5, 0, (void*) lsr_zpg },
/* 0x47 */ { "???", 0x47, 1, 2, 0, (void*) NULL },
/* 0x47 */ { "???", 0x47, 1, 2, 0, (void*) unimplemented },
/* 0x48 */ { "PHA", 0x48, 1, 3, 1, (void*) pha },
/* 0x49 */ { "EOR", 0x49, 2, 2, 0, (void*) eor_imm },
/* 0x4a */ { "LSR", 0x4a, 1, 2, 0, (void*) lsr_acc },
/* 0x4b */ { "???", 0x4b, 1, 2, 0, (void*) NULL },
/* 0x4b */ { "???", 0x4b, 1, 2, 0, (void*) unimplemented },
/* 0x4c */ { "JMP", 0x4c, 3, 3, 0, (void*) jmp_abs },
/* 0x4d */ { "EOR", 0x4d, 3, 4, 0, (void*) eor_abs },
/* 0x4e */ { "LSR", 0x4e, 3, 6, 0, (void*) lsr_abs },
/* 0x4f */ { "???", 0x4f, 1, 2, 0, (void*) NULL },
/* 0x4f */ { "???", 0x4f, 1, 2, 0, (void*) unimplemented },
/* 0x50 */ { "BVC", 0x50, 2, 2, 0, (void*) bvc },
/* 0x51 */ { "EOR", 0x51, 2, 5, 0, (void*) eor_indy },
/* 0x52 */ { "???", 0x52, 1, 2, 0, (void*) NULL },
/* 0x53 */ { "???", 0x53, 1, 2, 0, (void*) NULL },
/* 0x54 */ { "???", 0x54, 1, 2, 0, (void*) NULL },
/* 0x52 */ { "???", 0x52, 1, 2, 0, (void*) unimplemented },
/* 0x53 */ { "???", 0x53, 1, 2, 0, (void*) unimplemented },
/* 0x54 */ { "???", 0x54, 1, 2, 0, (void*) unimplemented },
/* 0x55 */ { "EOR", 0x55, 2, 4, 0, (void*) eor_zpgx },
/* 0x56 */ { "LSR", 0x56, 2, 6, 0, (void*) lsr_zpgx },
/* 0x57 */ { "???", 0x57, 1, 2, 0, (void*) NULL },
/* 0x57 */ { "???", 0x57, 1, 2, 0, (void*) unimplemented },
/* 0x58 */ { "CLI", 0x58, 1, 2, 0, (void*) cli },
/* 0x59 */ { "EOR", 0x59, 3, 4, 0, (void*) eor_absy },
/* 0x5a */ { "???", 0x5a, 1, 2, 0, (void*) NULL },
/* 0x5b */ { "???", 0x5b, 1, 2, 0, (void*) NULL },
/* 0x5c */ { "???", 0x5c, 1, 2, 0, (void*) NULL },
/* 0x5a */ { "???", 0x5a, 1, 2, 0, (void*) unimplemented },
/* 0x5b */ { "???", 0x5b, 1, 2, 0, (void*) unimplemented },
/* 0x5c */ { "???", 0x5c, 1, 2, 0, (void*) unimplemented },
/* 0x5d */ { "EOR", 0x5d, 3, 4, 0, (void*) eor_absx },
/* 0x5e */ { "LSR", 0x5e, 3, 7, 0, (void*) lsr_absx },
/* 0x5f */ { "???", 0x5f, 1, 2, 0, (void*) NULL },
/* 0x5f */ { "???", 0x5f, 1, 2, 0, (void*) unimplemented },
/* 0x60 */ { "RTS", 0x60, 1, 6, -2, (void*) rts },
/* 0x61 */ { "ADC", 0x61, 2, 6, 0, (void*) adc_indx },
/* 0x62 */ { "???", 0x62, 1, 2, 0, (void*) NULL },
/* 0x63 */ { "???", 0x63, 1, 2, 0, (void*) NULL },
/* 0x64 */ { "???", 0x64, 1, 2, 0, (void*) NULL },
/* 0x62 */ { "???", 0x62, 1, 2, 0, (void*) unimplemented },
/* 0x63 */ { "???", 0x63, 1, 2, 0, (void*) unimplemented },
/* 0x64 */ { "???", 0x64, 1, 2, 0, (void*) unimplemented },
/* 0x65 */ { "ADC", 0x65, 2, 3, 0, (void*) adc_zpg },
/* 0x66 */ { "ROR", 0x66, 2, 5, 0, (void*) ror_zpg },
/* 0x67 */ { "???", 0x67, 1, 2, 0, (void*) NULL },
/* 0x67 */ { "???", 0x67, 1, 2, 0, (void*) unimplemented },
/* 0x68 */ { "PLA", 0x68, 1, 4, -1, (void*) pla },
/* 0x69 */ { "ADC", 0x69, 2, 2, 0, (void*) adc_imm },
/* 0x6a */ { "ROR", 0x6a, 1, 2, 0, (void*) ror_acc },
/* 0x6b */ { "???", 0x6b, 1, 2, 0, (void*) NULL },
/* 0x6b */ { "???", 0x6b, 1, 2, 0, (void*) unimplemented },
/* 0x6c */ { "JMP", 0x6c, 3, 5, 0, (void*) jmp_ind },
/* 0x6d */ { "ADC", 0x6d, 3, 4, 0, (void*) adc_abs },
/* 0x6e */ { "ROR", 0x6e, 3, 6, 0, (void*) ror_abs },
/* 0x6f */ { "???", 0x6f, 1, 2, 0, (void*) NULL },
/* 0x6f */ { "???", 0x6f, 1, 2, 0, (void*) unimplemented },
/* 0x70 */ { "BVS", 0x70, 2, 2, 0, (void*) bvs },
/* 0x71 */ { "ADC", 0x71, 2, 5, 0, (void*) adc_indy },
/* 0x72 */ { "???", 0x72, 1, 2, 0, (void*) NULL },
/* 0x73 */ { "???", 0x73, 1, 2, 0, (void*) NULL },
/* 0x74 */ { "???", 0x74, 1, 2, 0, (void*) NULL },
/* 0x72 */ { "???", 0x72, 1, 2, 0, (void*) unimplemented },
/* 0x73 */ { "???", 0x73, 1, 2, 0, (void*) unimplemented },
/* 0x74 */ { "???", 0x74, 1, 2, 0, (void*) unimplemented },
/* 0x75 */ { "ADC", 0x75, 2, 4, 0, (void*) adc_zpgx },
/* 0x76 */ { "ROR", 0x76, 2, 6, 0, (void*) ror_zpgx },
/* 0x77 */ { "???", 0x77, 1, 2, 0, (void*) NULL },
/* 0x77 */ { "???", 0x77, 1, 2, 0, (void*) unimplemented },
/* 0x78 */ { "SEI", 0x78, 1, 2, 0, (void*) sei },
/* 0x79 */ { "ADC", 0x79, 3, 4, 0, (void*) adc_absy },
/* 0x7a */ { "???", 0x7a, 1, 2, 0, (void*) NULL },
/* 0x7b */ { "???", 0x7b, 1, 2, 0, (void*) NULL },
/* 0x7c */ { "???", 0x7c, 1, 2, 0, (void*) NULL },
/* 0x7a */ { "???", 0x7a, 1, 2, 0, (void*) unimplemented },
/* 0x7b */ { "???", 0x7b, 1, 2, 0, (void*) unimplemented },
/* 0x7c */ { "???", 0x7c, 1, 2, 0, (void*) unimplemented },
/* 0x7d */ { "ADC", 0x7d, 3, 4, 0, (void*) adc_absx },
/* 0x7e */ { "ROR", 0x7e, 3, 7, 0, (void*) ror_absx },
/* 0x7f */ { "???", 0x7f, 1, 2, 0, (void*) NULL },
/* 0x7f */ { "???", 0x7f, 1, 2, 0, (void*) unimplemented },
/* 0x80 */ { "???", 0x80, 1, 2, 0, (void*) NULL },
/* 0x80 */ { "???", 0x80, 1, 2, 0, (void*) unimplemented },
/* 0x81 */ { "STA", 0x81, 2, 6, 0, (void*) sta_indx },
/* 0x82 */ { "???", 0x82, 1, 2, 0, (void*) NULL },
/* 0x83 */ { "???", 0x83, 1, 2, 0, (void*) NULL },
/* 0x82 */ { "???", 0x82, 1, 2, 0, (void*) unimplemented },
/* 0x83 */ { "???", 0x83, 1, 2, 0, (void*) unimplemented },
/* 0x84 */ { "STY", 0x84, 2, 3, 0, (void*) sty_zpg },
/* 0x85 */ { "STA", 0x85, 2, 3, 0, (void*) sta_zpg },
/* 0x86 */ { "STX", 0x86, 2, 3, 0, (void*) stx_zpg },
/* 0x87 */ { "???", 0x87, 1, 2, 0, (void*) NULL },
/* 0x87 */ { "???", 0x87, 1, 2, 0, (void*) unimplemented },
/* 0x88 */ { "DEY", 0x88, 1, 2, 0, (void*) dey },
/* 0x89 */ { "???", 0x89, 1, 2, 0, (void*) NULL },
/* 0x89 */ { "???", 0x89, 1, 2, 0, (void*) unimplemented },
/* 0x8a */ { "TXA", 0x8a, 1, 2, 0, (void*) txa },
/* 0x8b */ { "???", 0x8b, 1, 2, 0, (void*) NULL },
/* 0x8b */ { "???", 0x8b, 1, 2, 0, (void*) unimplemented },
/* 0x8c */ { "STY", 0x8c, 3, 4, 0, (void*) sty_abs },
/* 0x8d */ { "STA", 0x8d, 3, 4, 0, (void*) sta_abs },
/* 0x8e */ { "STX", 0x8e, 3, 4, 0, (void*) stx_abs },
/* 0x8f */ { "???", 0x8f, 1, 2, 0, (void*) NULL },
/* 0x8f */ { "???", 0x8f, 1, 2, 0, (void*) unimplemented },
/* 0x90 */ { "BCC", 0x90, 2, 2, 0, (void*) bcc },
/* 0x91 */ { "STA", 0x91, 2, 6, 0, (void*) sta_indy },
/* 0x92 */ { "???", 0x92, 1, 2, 0, (void*) NULL },
/* 0x93 */ { "???", 0x93, 1, 2, 0, (void*) NULL },
/* 0x92 */ { "???", 0x92, 1, 2, 0, (void*) unimplemented },
/* 0x93 */ { "???", 0x93, 1, 2, 0, (void*) unimplemented },
/* 0x94 */ { "STY", 0x94, 2, 4, 0, (void*) sty_zpgx },
/* 0x95 */ { "STA", 0x95, 2, 4, 0, (void*) sta_zpgx },
/* 0x96 */ { "STX", 0x96, 2, 4, 0, (void*) stx_zpgy },
/* 0x97 */ { "???", 0x97, 1, 2, 0, (void*) NULL },
/* 0x97 */ { "???", 0x97, 1, 2, 0, (void*) unimplemented },
/* 0x98 */ { "TYA", 0x98, 1, 2, 0, (void*) tya },
/* 0x99 */ { "STA", 0x99, 3, 5, 0, (void*) sta_absy },
/* 0x9a */ { "TXS", 0x9a, 1, 2, 0, (void*) txs },
/* 0x9b */ { "???", 0x9b, 1, 2, 0, (void*) NULL },
/* 0x9c */ { "???", 0x9c, 1, 2, 0, (void*) NULL },
/* 0x9b */ { "???", 0x9b, 1, 2, 0, (void*) unimplemented },
/* 0x9c */ { "???", 0x9c, 1, 2, 0, (void*) unimplemented },
/* 0x9d */ { "STA", 0x9d, 3, 5, 0, (void*) sta_absx },
/* 0x9e */ { "???", 0x9e, 1, 2, 0, (void*) NULL },
/* 0x9f */ { "???", 0x9f, 1, 2, 0, (void*) NULL },
/* 0x9e */ { "???", 0x9e, 1, 2, 0, (void*) unimplemented },
/* 0x9f */ { "???", 0x9f, 1, 2, 0, (void*) unimplemented },
/* 0xa0 */ { "LDY", 0xa0, 2, 2, 0, (void*) ldy_imm },
/* 0xa1 */ { "LDA", 0xa1, 2, 6, 0, (void*) lda_indx },
/* 0xa2 */ { "LDX", 0xa2, 2, 2, 0, (void*) ldx_imm },
/* 0xa3 */ { "???", 0xa3, 1, 2, 0, (void*) NULL },
/* 0xa3 */ { "???", 0xa3, 1, 2, 0, (void*) unimplemented },
/* 0xa4 */ { "LDY", 0xa4, 2, 3, 0, (void*) ldy_zpg },
/* 0xa5 */ { "LDA", 0xa5, 2, 3, 0, (void*) lda_zpg },
/* 0xa6 */ { "LDX", 0xa6, 2, 3, 0, (void*) ldx_zpg },
/* 0xa7 */ { "???", 0xa7, 1, 2, 0, (void*) NULL },
/* 0xa7 */ { "???", 0xa7, 1, 2, 0, (void*) unimplemented },
/* 0xa8 */ { "TAY", 0xa8, 1, 2, 0, (void*) tay },
/* 0xa9 */ { "LDA", 0xa9, 2, 2, 0, (void*) lda_imm },
/* 0xaa */ { "TAX", 0xaa, 1, 2, 0, (void*) tax },
/* 0xab */ { "???", 0xab, 1, 2, 0, (void*) NULL },
/* 0xab */ { "???", 0xab, 1, 2, 0, (void*) unimplemented },
/* 0xac */ { "LDY", 0xac, 3, 4, 0, (void*) ldy_abs },
/* 0xad */ { "LDA", 0xad, 3, 4, 0, (void*) lda_abs },
/* 0xae */ { "LDX", 0xae, 3, 4, 0, (void*) ldx_abs },
/* 0xaf */ { "???", 0xaf, 1, 2, 0, (void*) NULL },
/* 0xaf */ { "???", 0xaf, 1, 2, 0, (void*) unimplemented },
/* 0xb0 */ { "BCS", 0xb0, 2, 2, 0, (void*) bcs },
/* 0xb1 */ { "LDA", 0xb1, 2, 5, 0, (void*) lda_indy },
/* 0xb2 */ { "???", 0xb2, 1, 2, 0, (void*) NULL },
/* 0xb3 */ { "???", 0xb3, 1, 2, 0, (void*) NULL },
/* 0xb2 */ { "???", 0xb2, 1, 2, 0, (void*) unimplemented },
/* 0xb3 */ { "???", 0xb3, 1, 2, 0, (void*) unimplemented },
/* 0xb4 */ { "LDY", 0xb4, 2, 4, 0, (void*) ldy_zpgx },
/* 0xb5 */ { "LDA", 0xb5, 2, 4, 0, (void*) lda_zpgx },
/* 0xb6 */ { "LDX", 0xb6, 2, 4, 0, (void*) ldx_zpgy },
/* 0xb7 */ { "???", 0xb7, 1, 2, 0, (void*) NULL },
/* 0xb7 */ { "???", 0xb7, 1, 2, 0, (void*) unimplemented },
/* 0xb8 */ { "CLV", 0xb8, 1, 2, 0, (void*) clv },
/* 0xb9 */ { "LDA", 0xb9, 3, 4, 0, (void*) lda_absy },
/* 0xba */ { "TSX", 0xba, 1, 2, 0, (void*) tsx },
/* 0xbb */ { "???", 0xbb, 1, 2, 0, (void*) NULL },
/* 0xbb */ { "???", 0xbb, 1, 2, 0, (void*) unimplemented },
/* 0xbc */ { "LDY", 0xbc, 3, 4, 0, (void*) ldy_absx },
/* 0xbd */ { "LDA", 0xbd, 3, 4, 0, (void*) lda_absx },
/* 0xbe */ { "LDX", 0xbe, 3, 4, 0, (void*) ldx_absy },
/* 0xbf */ { "???", 0xbf, 1, 2, 0, (void*) NULL },
/* 0xbf */ { "???", 0xbf, 1, 2, 0, (void*) unimplemented },
/* 0xc0 */ { "CPY", 0xc0, 2, 2, 0, (void*) cpy_imm },
/* 0xc1 */ { "CMP", 0xc1, 2, 6, 0, (void*) cmp_indx },
/* 0xc2 */ { "???", 0xc2, 1, 2, 0, (void*) NULL },
/* 0xc3 */ { "???", 0xc3, 1, 2, 0, (void*) NULL },
/* 0xc2 */ { "???", 0xc2, 1, 2, 0, (void*) unimplemented },
/* 0xc3 */ { "???", 0xc3, 1, 2, 0, (void*) unimplemented },
/* 0xc4 */ { "CPY", 0xc4, 2, 3, 0, (void*) cpy_zpg },
/* 0xc5 */ { "CMP", 0xc5, 2, 3, 0, (void*) cmp_zpg },
/* 0xc6 */ { "DEC", 0xc6, 2, 5, 0, (void*) dec_zpg },
/* 0xc7 */ { "???", 0xc7, 1, 2, 0, (void*) NULL },
/* 0xc7 */ { "???", 0xc7, 1, 2, 0, (void*) unimplemented },
/* 0xc8 */ { "INY", 0xc8, 1, 2, 0, (void*) iny },
/* 0xc9 */ { "CMP", 0xc9, 2, 2, 0, (void*) cmp_imm },
/* 0xca */ { "DEX", 0xca, 1, 2, 0, (void*) dex },
/* 0xcb */ { "???", 0xcb, 1, 2, 0, (void*) NULL },
/* 0xcb */ { "???", 0xcb, 1, 2, 0, (void*) unimplemented },
/* 0xcc */ { "CPY", 0xcc, 3, 4, 0, (void*) cpy_abs },
/* 0xcd */ { "CMP", 0xcd, 3, 4, 0, (void*) cmp_abs },
/* 0xce */ { "DEC", 0xce, 3, 3, 0, (void*) dec_abs },
/* 0xcf */ { "???", 0xcf, 1, 2, 0, (void*) NULL },
/* 0xcf */ { "???", 0xcf, 1, 2, 0, (void*) unimplemented },
/* 0xd0 */ { "BNE", 0xd0, 2, 2, 0, (void*) bne },
/* 0xd1 */ { "CMP", 0xd1, 2, 5, 0, (void*) cmp_indy },
/* 0xd2 */ { "???", 0xd2, 1, 2, 0, (void*) NULL },
/* 0xd3 */ { "???", 0xd3, 1, 2, 0, (void*) NULL },
/* 0xd4 */ { "???", 0xd4, 1, 2, 0, (void*) NULL },
/* 0xd2 */ { "???", 0xd2, 1, 2, 0, (void*) unimplemented },
/* 0xd3 */ { "???", 0xd3, 1, 2, 0, (void*) unimplemented },
/* 0xd4 */ { "???", 0xd4, 1, 2, 0, (void*) unimplemented },
/* 0xd5 */ { "CMP", 0xd5, 2, 4, 0, (void*) cmp_zpgx },
/* 0xd6 */ { "DEC", 0xd6, 2, 6, 0, (void*) dec_zpgx },
/* 0xd7 */ { "???", 0xd7, 1, 2, 0, (void*) NULL },
/* 0xd7 */ { "???", 0xd7, 1, 2, 0, (void*) unimplemented },
/* 0xd8 */ { "CLD", 0xd8, 1, 2, 0, (void*) cld },
/* 0xd9 */ { "CMP", 0xd9, 3, 4, 0, (void*) cmp_absy },
/* 0xda */ { "???", 0xda, 1, 2, 0, (void*) NULL },
/* 0xdb */ { "???", 0xdb, 1, 2, 0, (void*) NULL },
/* 0xdc */ { "???", 0xdc, 1, 2, 0, (void*) NULL },
/* 0xda */ { "???", 0xda, 1, 2, 0, (void*) unimplemented },
/* 0xdb */ { "???", 0xdb, 1, 2, 0, (void*) unimplemented },
/* 0xdc */ { "???", 0xdc, 1, 2, 0, (void*) unimplemented },
/* 0xdd */ { "CMP", 0xdd, 3, 4, 0, (void*) cmp_absx },
/* 0xde */ { "DEC", 0xde, 3, 7, 0, (void*) dec_absx },
/* 0xdf */ { "???", 0xdf, 1, 2, 0, (void*) NULL },
/* 0xdf */ { "???", 0xdf, 1, 2, 0, (void*) unimplemented },
/* 0xe0 */ { "CPX", 0xe0, 2, 2, 0, (void*) cpx_imm },
/* 0xe1 */ { "SBC", 0xe1, 2, 2, 0, (void*) sbc_indx },
/* 0xe2 */ { "???", 0xe2, 1, 2, 0, (void*) NULL },
/* 0xe3 */ { "???", 0xe3, 1, 2, 0, (void*) NULL },
/* 0xe2 */ { "???", 0xe2, 1, 2, 0, (void*) unimplemented },
/* 0xe3 */ { "???", 0xe3, 1, 2, 0, (void*) unimplemented },
/* 0xe4 */ { "CPX", 0xe4, 2, 3, 0, (void*) cpx_zpg },
/* 0xe5 */ { "SBC", 0xe5, 2, 2, 0, (void*) sbc_zpg },
/* 0xe6 */ { "INC", 0xe6, 2, 5, 0, (void*) inc_zpg },
/* 0xe7 */ { "???", 0xe7, 1, 2, 0, (void*) NULL },
/* 0xe7 */ { "???", 0xe7, 1, 2, 0, (void*) unimplemented },
/* 0xe8 */ { "INX", 0xe8, 1, 2, 0, (void*) inx },
/* 0xe9 */ { "SBC", 0xe9, 2, 2, 0, (void*) sbc_imm },
/* 0xea */ { "NOP", 0xea, 1, 2, 0, (void*) nop },
/* 0xeb */ { "???", 0xeb, 1, 2, 0, (void*) NULL },
/* 0xeb */ { "???", 0xeb, 1, 2, 0, (void*) unimplemented },
/* 0xec */ { "CPX", 0xec, 3, 4, 0, (void*) cpx_abs },
/* 0xed */ { "SBC", 0xed, 3, 2, 0, (void*) sbc_abs },
/* 0xee */ { "INC", 0xee, 3, 6, 0, (void*) inc_abs },
/* 0xef */ { "???", 0xef, 1, 2, 0, (void*) NULL },
/* 0xef */ { "???", 0xef, 1, 2, 0, (void*) unimplemented },
/* 0xf0 */ { "BEQ", 0xf0, 2, 2, 0, (void*) beq },
/* 0xf1 */ { "SBC", 0xf1, 2, 2, 0, (void*) sbc_indy },
/* 0xf2 */ { "???", 0xf2, 1, 2, 0, (void*) NULL },
/* 0xf3 */ { "???", 0xf3, 1, 2, 0, (void*) NULL },
/* 0xf4 */ { "???", 0xf4, 1, 2, 0, (void*) NULL },
/* 0xf2 */ { "???", 0xf2, 1, 2, 0, (void*) unimplemented },
/* 0xf3 */ { "???", 0xf3, 1, 2, 0, (void*) unimplemented },
/* 0xf4 */ { "???", 0xf4, 1, 2, 0, (void*) unimplemented },
/* 0xf5 */ { "SBC", 0xf5, 2, 2, 0, (void*) sbc_zpgx },
/* 0xf6 */ { "INC", 0xf6, 2, 6, 0, (void*) inc_zpgx },
/* 0xf7 */ { "???", 0xf7, 1, 2, 0, (void*) NULL },
/* 0xf7 */ { "???", 0xf7, 1, 2, 0, (void*) unimplemented },
/* 0xf8 */ { "SED", 0xf8, 1, 2, 0, (void*) sed },
/* 0xf9 */ { "SBC", 0xf9, 3, 2, 0, (void*) sbc_absy },
/* 0xfa */ { "???", 0xfa, 1, 2, 0, (void*) NULL },
/* 0xfb */ { "???", 0xfb, 1, 2, 0, (void*) NULL },
/* 0xfc */ { "???", 0xfc, 1, 2, 0, (void*) NULL },
/* 0xfa */ { "???", 0xfa, 1, 2, 0, (void*) unimplemented },
/* 0xfb */ { "???", 0xfb, 1, 2, 0, (void*) unimplemented },
/* 0xfc */ { "???", 0xfc, 1, 2, 0, (void*) unimplemented },
/* 0xfd */ { "SBC", 0xfd, 3, 2, 0, (void*) sbc_absx },
/* 0xfe */ { "INC", 0xfe, 3, 7, 0, (void*) inc_absx },
/* 0xff */ { "???", 0xff, 1, 2, 0, (void*) NULL }
/* 0xff */ { "???", 0xff, 1, 2, 0, (void*) unimplemented }
};
// EWM_CPU_MODEL_65C02

View File

@ -155,6 +155,7 @@ static bool ewm_one_step_cpu(struct ewm_one_t *one, int cycles) {
while (true) {
int ret = cpu_step(one->cpu);
if (ret < 0) {
// These only happen in strict mode
switch (ret) {
case EWM_CPU_ERR_UNIMPLEMENTED_INSTRUCTION:
fprintf(stderr, "CPU: Exited because of unimplemented instructions 0x%.2x at 0x%.4x\n",
@ -167,7 +168,7 @@ static bool ewm_one_step_cpu(struct ewm_one_t *one, int cycles) {
fprintf(stderr, "CPU: Exited because of stack underflow at 0x%.4x\n", one->cpu->state.pc);
break;
}
cpu_nmi(one->cpu);
return false;
}
cycles -= ret;
@ -181,11 +182,13 @@ static bool ewm_one_step_cpu(struct ewm_one_t *one, int cycles) {
#define EWM_ONE_OPT_MODEL (0)
#define EWM_ONE_OPT_MEMORY (1)
#define EWM_ONE_OPT_TRACE (2)
#define EWM_ONE_OPT_STRICT (3)
static struct option one_options[] = {
{ "model", required_argument, NULL, EWM_ONE_OPT_MODEL },
{ "memory", required_argument, NULL, EWM_ONE_OPT_MEMORY },
{ "trace", optional_argument, NULL, EWM_ONE_OPT_TRACE },
{ "strict", no_argument, NULL, EWM_ONE_OPT_STRICT },
{ NULL, 0, NULL, 0 }
};
@ -194,6 +197,7 @@ int ewm_one_main(int argc, char **argv) {
int model = EWM_ONE_MODEL_DEFAULT;
struct ewm_memory_option_t *extra_memory = NULL;
char *trace_path = NULL;
bool strict = false;
int ch;
while ((ch = getopt_long_only(argc, argv, "", one_options, NULL)) != -1) {
@ -222,6 +226,10 @@ int ewm_one_main(int argc, char **argv) {
trace_path = optarg ? optarg : "/dev/stderr";
break;
}
case EWM_ONE_OPT_STRICT: {
strict = true;
break;
}
}
}
@ -262,6 +270,7 @@ int ewm_one_main(int argc, char **argv) {
}
}
cpu_strict(one->cpu, strict);
cpu_trace(one->cpu, trace_path);
cpu_reset(one->cpu);

View File

@ -470,6 +470,7 @@ static bool ewm_two_step_cpu(struct ewm_two_t *two, int cycles) {
while (true) {
int ret = cpu_step(two->cpu);
if (ret < 0) {
// These only happen in strict mode
switch (ret) {
case EWM_CPU_ERR_UNIMPLEMENTED_INSTRUCTION:
fprintf(stderr, "CPU: Exited because of unimplemented instructions 0x%.2x at 0x%.4x\n",
@ -482,7 +483,7 @@ static bool ewm_two_step_cpu(struct ewm_two_t *two, int cycles) {
fprintf(stderr, "CPU: Exited because of stack underflow at 0x%.4x\n", two->cpu->state.pc);
break;
}
cpu_nmi(two->cpu);
return false;
}
cycles -= ret;
if (cycles <= 0) {
@ -498,6 +499,7 @@ static bool ewm_two_step_cpu(struct ewm_two_t *two, int cycles) {
#define EWM_TWO_OPT_FPS (3)
#define EWM_TWO_OPT_MEMORY (4)
#define EWM_TWO_OPT_TRACE (5)
#define EWM_TWO_OPT_STRICT (6)
static struct option one_options[] = {
{ "drive1", required_argument, NULL, EWM_TWO_OPT_DRIVE1 },
@ -506,6 +508,7 @@ static struct option one_options[] = {
{ "fps", required_argument, NULL, EWM_TWO_OPT_FPS },
{ "memory", required_argument, NULL, EWM_TWO_OPT_MEMORY },
{ "trace", optional_argument, NULL, EWM_TWO_OPT_TRACE },
{ "strict", no_argument, NULL, EWM_TWO_OPT_STRICT },
{ NULL, 0, NULL, 0 }
};
@ -518,6 +521,7 @@ int ewm_two_main(int argc, char **argv) {
uint32_t fps = EWM_TWO_FPS_DEFAULT;
struct ewm_memory_option_t *extra_memory = NULL;
char *trace_path = NULL;
bool strict = false;
int ch;
while ((ch = getopt_long_only(argc, argv, "", one_options, NULL)) != -1) {
@ -546,6 +550,9 @@ int ewm_two_main(int argc, char **argv) {
case EWM_TWO_OPT_TRACE:
trace_path = optarg ? optarg : "/dev/stderr";
break;
case EWM_TWO_OPT_STRICT:
strict = true;
break;
}
}
@ -611,6 +618,7 @@ int ewm_two_main(int argc, char **argv) {
}
}
cpu_strict(two->cpu, strict);
cpu_trace(two->cpu, trace_path);
cpu_reset(two->cpu);