mirror of
https://github.com/trudnai/Steve2.git
synced 2025-03-30 14:30:01 +00:00
Undocumented instructions
This commit is contained in:
parent
16aa7a8d69
commit
81a929a889
@ -921,13 +921,13 @@
|
||||
<action selector="ROM_Selected:" target="Voe-Tx-rLC" id="dhI-7d-ciT"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Apple //e" state="on" identifier="Apple2e" id="MeE-Kj-pad">
|
||||
<menuItem title="Apple //e" identifier="Apple2e" id="MeE-Kj-pad">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="ROM_Selected:" target="Voe-Tx-rLC" id="2W2-oY-Osz"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Apple //e Enhanced" identifier="Apple2e_Enhanced" id="cDl-MC-vGJ">
|
||||
<menuItem title="Apple //e Enhanced" state="on" identifier="Apple2e_Enhanced" id="cDl-MC-vGJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="ROM_Selected:" target="Voe-Tx-rLC" id="Fob-HD-kdv"/>
|
||||
|
@ -98,7 +98,7 @@ class ViewController: NSViewController {
|
||||
|
||||
static var charConvTbl = charConvTblFlashOn
|
||||
|
||||
static var romFileName = "Apple2e.rom";
|
||||
static var romFileName = "Apple2e_Enhanced.rom";
|
||||
|
||||
static let textLineOfs : [Int] = [
|
||||
0x000, 0x080, 0x100, 0x180, 0x200, 0x280, 0x300, 0x380, 0x028, 0x0A8, 0x128, 0x1A8,
|
||||
|
145
src/cpu/6502.c
145
src/cpu/6502.c
@ -5,6 +5,13 @@
|
||||
// Created by Tamas Rudnai on 7/14/19.
|
||||
// Copyright © 2019 GameAlloy. All rights reserved.
|
||||
//
|
||||
// Documentations:
|
||||
//
|
||||
// http://nesdev.com/6502_cpu.txt
|
||||
// http://www.oxyron.de/html/opcodes02.html
|
||||
// https://macgui.com/kb/article/46
|
||||
// https://www.masswerk.at/6502/6502_instruction_set.html
|
||||
//
|
||||
|
||||
#define CLK_WAIT
|
||||
|
||||
@ -407,7 +414,7 @@ INLINE int m6502_Step() {
|
||||
case 0x01: ORA( src_X_ind() ); return 6; // ORA X,ind
|
||||
case 0x02: KIL(); return 0; // KIL - Hangs the CPU // t jams
|
||||
case 0x03: SLO( addr_zp_X() ); return 8; // SLO* zpg,X (undocumented)
|
||||
case 0x04: NOP2( src_zp() ); return 3; // NOP* zpg (undocumented)
|
||||
case 0x04: NOP(); src_zp(); return 3; // NOP* zpg (undocumented)
|
||||
case 0x05: ORA( src_zp() ); return 3; // ORA zpg
|
||||
case 0x06: ASL( addr_zp() ); return 5; // ASL zpg
|
||||
case 0x07: SLO( addr_zp() ); return 5; // SLO* zpg (undocumented)
|
||||
@ -415,7 +422,7 @@ INLINE int m6502_Step() {
|
||||
case 0x09: ORA( imm() ); return 2; // ORA imm
|
||||
case 0x0A: ASLA(); return 2; // ASL A
|
||||
case 0x0B: ANC( imm() ); return 2; // ANC** imm (undocumented)
|
||||
case 0x0C: NOP2( src_abs() ); return 4; // NOP* (undocumented)
|
||||
case 0x0C: NOP(); src_abs(); return 4; // NOP* (undocumented)
|
||||
case 0x0D: ORA( src_abs() ); return 4; // ORA abs
|
||||
case 0x0E: ASL( addr_abs() ); return 6; // ASL abs
|
||||
case 0x0F: SLO( addr_abs() ); return 6; // SLO* (undocumented)
|
||||
@ -423,7 +430,7 @@ INLINE int m6502_Step() {
|
||||
case 0x11: ORA( src_ind_Y() ); return 5; // ORA ind,Y
|
||||
case 0x12: KIL(); return 0; // KIL - Hangs the CPU // t jams
|
||||
case 0x13: SLO( addr_zp_Y() ); return 8; // SLO* zpg,Y (undocumented)
|
||||
case 0x14: NOP2( addr_zp_X() ); return 4; // NOP* zpg,X (undocumented)
|
||||
case 0x14: NOP(); addr_zp_X(); return 4; // NOP* zpg,X (undocumented)
|
||||
case 0x15: ORA( src_zp_X() ); return 4; // ORA zpg,X
|
||||
case 0x16: ASL( addr_zp_X() ); return 6; // ASL zpg,X
|
||||
case 0x17: SLO( addr_zp_X() ); return 6; // SLO* zpg,X (undocumented)
|
||||
@ -431,7 +438,7 @@ INLINE int m6502_Step() {
|
||||
case 0x19: ORA( src_abs_Y() ); return 4; // ORA abs,Y
|
||||
case 0x1A: NOP(); return 2; // NOP* (undocumented)
|
||||
case 0x1B: SLO( addr_abs_Y() ); return 7; // SLO* abs,Y (undocumented)
|
||||
case 0x1C: NOP2( src_abs_X() ); return 4; // NOP* (undocumented)
|
||||
case 0x1C: NOP(); src_abs_X(); return 4; // NOP* (undocumented)
|
||||
case 0x1D: ORA( src_abs_X() ); return 4; // ORA abs,X
|
||||
case 0x1E: ASL( addr_abs_X() ); return 7; // ASL abs,X
|
||||
case 0x1F: SLO( addr_abs_X() ); return 7; // SLO* abs,X (undocumented)
|
||||
@ -455,7 +462,7 @@ INLINE int m6502_Step() {
|
||||
case 0x31: AND( src_ind_Y() ); return 5; // AND ind,Y
|
||||
case 0x32: KIL(); return 0; // KIL - Hangs the CPU
|
||||
case 0x33: RLA( addr_ind_Y() ); return 8; // RLA* izy 8 (undocumented)
|
||||
case 0x34: NOP2( src_zp_X() ); return 4; // NOP* zpx 4 (undocumented)
|
||||
case 0x34: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
|
||||
case 0x35: AND( src_zp_X() ); return 4; // AND zpg,X
|
||||
case 0x36: ROL( addr_zp_X() ); return 6; // ROL zpg,X
|
||||
case 0x37: RLA( addr_zp_X() ); return 6; // RLA* zpx 6 (undocumented)
|
||||
@ -463,7 +470,7 @@ INLINE int m6502_Step() {
|
||||
case 0x39: AND( src_abs_Y() ); return 4; // AND abs,Y
|
||||
case 0x3A: NOP(); return 2; // NOP* 2 (undocumented)
|
||||
case 0x3B: RLA( addr_abs_Y() ); return 7; // RLA* aby 7 (undocumented)
|
||||
case 0x3C: NOP2( src_abs_X() ); return 4; // NOP* abx 4 (undocumented)
|
||||
case 0x3C: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
|
||||
case 0x3D: AND( src_abs_X() ); return 4; // AND abs,X
|
||||
case 0x3E: ROL( addr_abs_X() ); return 7; // ROL abs,X
|
||||
case 0x3F: RLA( addr_abs_X() ); return 7; // RLA* abx 7 (undocumented)
|
||||
@ -487,7 +494,7 @@ INLINE int m6502_Step() {
|
||||
case 0x51: EOR( src_ind_Y() ); return 5; // EOR ind,Y
|
||||
case 0x52: KIL(); return 0; // KIL - Hangs the CPU
|
||||
case 0x53: SRE( addr_ind_Y() ); return 8; // SRE* izy 8 (undocumented)
|
||||
case 0x54: NOP2( src_zp_X() ); return 4; // NOP* zpx 4 (undocumented)
|
||||
case 0x54: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
|
||||
case 0x55: EOR( src_zp_X() ); return 4; // AND zpg,X
|
||||
case 0x56: LSR( addr_zp_X() ); return 6; // LSR zpg,X
|
||||
case 0x57: SRE( addr_ind_X() ); return 6; // SRE* zpx 6 (undocumented)
|
||||
@ -495,170 +502,170 @@ INLINE int m6502_Step() {
|
||||
case 0x59: EOR( src_abs_Y() ); return 4; // EOR abs,Y
|
||||
case 0x5A: NOP(); return 2; // NOP* 2 (undocumented)
|
||||
case 0x5B: SRE( addr_abs_Y() ); return 7; // SRE* aby 7 (undocumented)
|
||||
case 0x5C: NOP2( src_abs_X() ); return 4; // NOP* abx 4 (undocumented)
|
||||
case 0x5C: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
|
||||
case 0x5D: EOR( src_abs_X() ); return 4; // EOR abs,X
|
||||
case 0x5E: LSR( addr_abs_X() ); return 7; // LSR abs,X
|
||||
case 0x5F: SRE( addr_abs_X() ); return 7; // SRE* abx 7 (undocumented)
|
||||
case 0x60: RTS(); return 6; // RTS
|
||||
case 0x61: ADC( src_X_ind() ); return 6; // ADC X,ind
|
||||
case 0x62: KIL(); return 0; // KIL - Hangs the CPU
|
||||
// case 0x63: RRA izx 8
|
||||
case 0x63: RRA( addr_ind_X() ); return 8; // RRA* izx 8 (undocumented)
|
||||
case 0x64: NOP(); return 3; // NOP* zp 3 (undocumented)
|
||||
case 0x65: ADC( src_zp() ); return 3; // ADC zpg
|
||||
case 0x66: ROR( addr_zp() ); return 5; // ROR zpg
|
||||
// case 0x67: RRA zp 5
|
||||
case 0x67: RRA( addr_zp() ); return 5; // RRA* zp 5 (undocumented)
|
||||
case 0x68: PLA(); break; // PLA
|
||||
case 0x69: ADC( imm() ); return 2; // ADC imm
|
||||
case 0x6A: RORA(); return 2; // ROR A
|
||||
// case 0x6B: ARR imm 2
|
||||
case 0x6B: ARC( imm() ); return 2; // ARR/ARC* imm 2 (undocumented)
|
||||
case 0x6C: JMP( ind_addr() ); return 5; // JMP ind
|
||||
case 0x6D: ADC( src_abs() ); return 4; // ADC abs
|
||||
case 0x6E: ROR( addr_abs() ); return 6; // ROR abs
|
||||
// case 0x6F: RRA abs 6
|
||||
case 0x6F: RRA( abs_addr() ); return 6; // RRA* abs 6 (undocumented)
|
||||
case 0x70: BVS( rel_addr() ); return 3; // BVS rel
|
||||
case 0x71: ADC( src_ind_Y() ); return 5; // ADC ind,Y
|
||||
// case 0x72:
|
||||
// case 0x73:
|
||||
// case 0x74:
|
||||
case 0x72: KIL(); return 0; // KIL - Hangs the CPU
|
||||
case 0x73: RRA( addr_ind_Y() ); return 8; // RRA* izy 8 (undocumented)
|
||||
case 0x74: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
|
||||
case 0x75: ADC( src_zp_X() ); return 4; // ADC zpg,X
|
||||
case 0x76: ROR( addr_zp_X() ); return 6; // ROR zpg,X
|
||||
// case 0x77:
|
||||
case 0x77: RRA( addr_zp_X() ); return 6; // RRA* zpx 6 (undocumented)
|
||||
case 0x78: SEI(); return 2; // SEI
|
||||
case 0x79: ADC( src_abs_Y() ); return 4; // ADC abs,Y
|
||||
// case 0x7A:
|
||||
// case 0x7B:
|
||||
// case 0x7C:
|
||||
case 0x7A: NOP(); return 2; // NOP* 2 (undocumented)
|
||||
case 0x7B: RRA( addr_abs_Y() ); return 7; // RRA* aby 7 (undocumented)
|
||||
case 0x7C: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
|
||||
case 0x7D: ADC( src_abs_X() ); return 4; // ADC abs,X
|
||||
case 0x7E: ROR( addr_abs_X() ); return 7; // ROR abs,X
|
||||
// case 0x7F:
|
||||
// case 0x80:
|
||||
case 0x7F: RRA( addr_abs_X() ); return 7; // RRA* abx 7 (undocumented)
|
||||
case 0x80: NOP(); imm(); return 2; // NOP* imm 2 (undocumented)
|
||||
case 0x81: STA( addr_ind_X() ) ; return 6; // STA X,ind
|
||||
// case 0x82:
|
||||
// case 0x83:
|
||||
case 0x82: NOP(); imm(); return 2; // NOP* imm 2 (undocumented)
|
||||
case 0x83: SAX( addr_ind_X() ); return 6; // SAX* izx 6 (undocumented)
|
||||
case 0x84: STY( addr_zp() ); return 3; // STY zpg
|
||||
case 0x85: STA( addr_zp() ); return 3; // STA zpg
|
||||
case 0x86: STX( addr_zp() ); return 3; // STX zpg
|
||||
// case 0x87:
|
||||
case 0x87: SAX( addr_zp() ); return 3; // SAX* izx 6 (undocumented)
|
||||
case 0x88: DEY(); return 2; // DEY
|
||||
// case 0x89: NOP(); imm(); return 4; // NOP imm
|
||||
case 0x89: NOP(); imm(); return 2; // NOP* imm (undocumented)
|
||||
case 0x8A: TXA(); return 2; // TXA
|
||||
// case 0x8B:
|
||||
case 0x8B: XAA( imm() ); return 2; // XAA* imm 2 (undocumented, highly unstable!)
|
||||
case 0x8C: STY( addr_abs() ); return 4; // STY abs
|
||||
case 0x8D: STA( addr_abs() ); return 4; // STA abs
|
||||
case 0x8E: STX( addr_abs() ); return 4; // STX abs
|
||||
// case 0x8F:
|
||||
case 0x8F: SAX( addr_abs() ); return 4; // SAX* abs 4 (undocumented)
|
||||
case 0x90: BCC( rel_addr() ); return 3; // BCC rel
|
||||
case 0x91: STA( addr_ind_Y() ); return 6; // STA ind,Y
|
||||
// case 0x92:
|
||||
// case 0x93:
|
||||
case 0x92: KIL(); return 0; // KIL* (undocumented)
|
||||
case 0x93: SHA( addr_ind_Y() ); return 6; // SHA* izy 6 (undocumented, unstable)
|
||||
case 0x94: STY( addr_zp_X() ); return 4; // STY zpg,X
|
||||
case 0x95: STA( addr_zp_X() ); return 4; // STA zpg,X
|
||||
case 0x96: STX( addr_zp_Y() ); return 4; // STX zpg,Y
|
||||
// case 0x97:
|
||||
case 0x97: SAX( addr_zp_Y() ); return 4; // SAX* izy 4 (undocumented)
|
||||
case 0x98: TYA(); return 2; // TYA
|
||||
case 0x99: STA( addr_abs_Y() ); return 5; // STA abs,Y
|
||||
case 0x9A: TXS(); return 2; // TXS
|
||||
// case 0x9B:
|
||||
// case 0x9C:
|
||||
case 0x9B: SAS( addr_abs_Y() ); return 5; // SAS* aby 5 (undocumented, unstable)
|
||||
case 0x9C: SHY( addr_abs_X() ); return 5; // SHY* abx 5 (undocumented, unstable)
|
||||
case 0x9D: STA( addr_abs_X() ); return 5; // STA abs,X
|
||||
// case 0x9E:
|
||||
// case 0x9F:
|
||||
case 0x9E: SHX( addr_abs_Y() ); return 5; // SHX* aby 5 (undocumented, unstable)
|
||||
case 0x9F: SAX( addr_abs_Y() ); return 5; // SAX* aby 5 (undocumented, unstable)
|
||||
case 0xA0: LDY( imm() ); return 2; // LDY imm
|
||||
case 0xA1: LDA( src_X_ind() ) ; return 6; // LDA X,ind
|
||||
case 0xA2: LDX( imm() ); return 2; // LDX imm
|
||||
// case 0xA3:
|
||||
case 0xA3: LAX( src_X_ind() ); return 6; // LAX* izx 6 (undocumented)
|
||||
case 0xA4: LDY( src_zp() ); return 3; // LDY zpg
|
||||
case 0xA5: LDA( src_zp() ); return 3; // LDA zpg
|
||||
case 0xA6: LDX( src_zp() ); return 3; // LDX zpg
|
||||
// case 0xA7:
|
||||
case 0xA7: LAX( src_zp() ); return 3; // LAX* zpg 3 (undocumented)
|
||||
case 0xA8: TAY(); return 2; // TAY
|
||||
case 0xA9: LDA( imm() ); return 2; // LDA imm
|
||||
case 0xAA: TAX(); return 2; // TAX
|
||||
// case 0xAB:
|
||||
case 0xAB: LAX( imm() ); return 2; // LAX* imm 2 (undocumented, highly unstable)
|
||||
case 0xAC: LDY( src_abs() ); return 4; // LDY abs
|
||||
case 0xAD: LDA( src_abs() ); return 4; // LDA abs
|
||||
case 0xAE: LDX( src_abs() ); return 4; // LDX abs
|
||||
// case 0xAF:
|
||||
case 0xAF: LAX( src_abs() ); return 4; // LAX* abs 4 (undocumented)
|
||||
case 0xB0: BCS( rel_addr() ); return 3; // BCS rel
|
||||
case 0xB1: LDA( src_ind_Y() ); return 5; // LDA ind,Y
|
||||
// case 0xB2:
|
||||
// case 0xB3:
|
||||
case 0xB2: KIL(); return 0; // KIL - Hangs the CPU // t jams
|
||||
case 0xB3: LAX( src_ind_Y() ); return 5; // LAX* izy 5 (undocumented)
|
||||
case 0xB4: LDY( src_zp_X() ); return 4; // LDY zpg,X
|
||||
case 0xB5: LDA( src_zp_X() ); return 4; // LDA zpg,X
|
||||
case 0xB6: LDX( src_zp_Y() ); return 4; // LDX zpg,Y
|
||||
// case 0xB7:
|
||||
case 0xB7: LAX( src_zp_Y() ); return 4; // LAX* zpy 4 (undocumented)
|
||||
case 0xB8: CLV(); return 2; // CLV
|
||||
case 0xB9: LDA( src_abs_Y() ); return 4; // LDA abs,Y
|
||||
case 0xBA: TSX(); return 2; // TSX
|
||||
// case 0xBB:
|
||||
case 0xBB: LAS( src_abs_Y() ); return 4; // LAX* aby 4 (undocumented)
|
||||
case 0xBC: LDY( src_abs_X() ); return 4; // LDY abs,X
|
||||
case 0xBD: LDA( src_abs_X() ); return 4; // LDA abs,X
|
||||
case 0xBE: LDX( src_abs_Y() ); return 4; // LDX abs,Y
|
||||
// case 0xBF:
|
||||
case 0xBF: LAX( src_abs_Y() ); return 4; // LAX* aby 4 (undocumented)
|
||||
case 0xC0: CPY( imm() ); return 2; // CPY imm
|
||||
case 0xC1: CMP( src_X_ind() ) ; return 6; // LDA X,ind
|
||||
// case 0xC2:
|
||||
// case 0xC3:
|
||||
case 0xC2: NOP(); imm(); return 2; // NOP* imm 2 (undocumented)
|
||||
case 0xC3: DCP( addr_ind_X() ); return 8; // DCP* izx 8 (undocumented)
|
||||
case 0xC4: CPY( src_zp() ); return 3; // CPY zpg
|
||||
case 0xC5: CMP( src_zp() ); return 3; // CMP zpg
|
||||
case 0xC6: DEC( addr_zp() ); return 5; // DEC zpg
|
||||
// case 0xC7:
|
||||
case 0xC7: DCP( addr_zp() ); return 5; // DCP* zpg 5 (undocumented)
|
||||
case 0xC8: INY(); return 2; // INY
|
||||
case 0xC9: CMP( imm() ); return 2; // CMP imm
|
||||
case 0xCA: DEX(); return 2; // DEX
|
||||
// case 0xCB:
|
||||
case 0xCB: SBX( imm() ); return 2; // SBX* imm 2 (undocumented)
|
||||
case 0xCC: CPY( src_abs() ); return 4; // CPY abs
|
||||
case 0xCD: CMP( src_abs() ); return 4; // CMP abs
|
||||
case 0xCE: DEC( addr_abs() ); return 6; // DEC abs
|
||||
// case 0xCF:
|
||||
case 0xCF: DCP( addr_abs() ); return 6; // DCP* abs 6 (undocumented)
|
||||
case 0xD0: BNE( rel_addr() ); return 3; // BNE rel
|
||||
case 0xD1: CMP( src_ind_Y() ); return 5; // CMP ind,Y
|
||||
// case 0xD2:
|
||||
// case 0xD3:
|
||||
// case 0xD4:
|
||||
case 0xD2: KIL(); return 0; // KIL - Hangs the CPU // t jams
|
||||
case 0xD3: DCP( addr_ind_Y() ); return 8; // DCP* izy 8 (undocumented)
|
||||
case 0xD4: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
|
||||
case 0xD5: CMP( src_zp_X() ); return 4; // CMP zpg,X
|
||||
case 0xD6: DEC( addr_zp_X() ); return 6; // DEC zpg,X
|
||||
// case 0xD7:
|
||||
case 0xD7: DCP( addr_zp_X() ); return 6; // DCP* zpx 6 (undocumented)
|
||||
case 0xD8: CLD(); return 2; // CLD
|
||||
case 0xD9: CMP( src_abs_Y() ); return 4; // CMP abs,Y
|
||||
// case 0xDA:
|
||||
// case 0xDB:
|
||||
// case 0xDC:
|
||||
case 0xDA: NOP(); return 2; // NOP* 2 (undocumented)
|
||||
case 0xDB: DCP( addr_abs_Y() ); return 7; // DCP* aby 7 (undocumented)
|
||||
case 0xDC: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
|
||||
case 0xDD: CMP( src_abs_X() ); return 4; // CMP abs,X
|
||||
case 0xDE: DEC( addr_abs_X() ); return 7; // DEC abs,X
|
||||
// case 0xDF:
|
||||
case 0xDF: DCP( addr_abs_X() ); return 7; // DCP* abx 7 (undocumented)
|
||||
case 0xE0: CPX( imm() ); return 2; // CPX imm
|
||||
case 0xE1: SBC( src_X_ind() ) ; return 6; // SBC (X,ind)
|
||||
// case 0xE2:
|
||||
// case 0xE3:
|
||||
case 0xE2: NOP(); imm(); return 2; // NOP* imm 2 (undocumented)
|
||||
case 0xE3: ISB( addr_ind_X() ); return 8; // ISB* izx 8 (undocumented)
|
||||
case 0xE4: CPX( src_zp() ); return 3; // CPX zpg
|
||||
case 0xE5: SBC( src_zp() ); return 3; // SBC zpg
|
||||
case 0xE6: INC( addr_zp() ); return 5; // INC zpg
|
||||
// case 0xE7:
|
||||
case 0xE7: ISB( addr_zp() ); return 5; // ISB* zpg 5 (undocumented)
|
||||
case 0xE8: INX(); return 2; // INX
|
||||
case 0xE9: SBC( imm() ); return 2; // SBC imm
|
||||
case 0xEA: NOP(); return 2; // NOP
|
||||
// case 0xEB:
|
||||
case 0xEB: SBC( imm() ); return 2; // SBC* imm 2 (undocumented)
|
||||
case 0xEC: CPX( src_abs() ); return 4; // CPX abs
|
||||
case 0xED: SBC( src_abs() ); return 4; // SBC abs
|
||||
case 0xEE: INC( addr_abs() ); return 6; // INC abs
|
||||
// case 0xEF:
|
||||
case 0xEF: ISB( addr_abs() ); return 6; // ISB* abs 6 (undocumented)
|
||||
case 0xF0: BEQ( rel_addr() ); return 3; // BEQ rel
|
||||
case 0xF1: SBC( src_ind_Y() ); return 5; // SBC ind,Y
|
||||
// case 0xF2:
|
||||
// case 0xF3:
|
||||
// case 0xF4:
|
||||
case 0xF2: KIL(); return 0; // KIL - Hangs the CPU // t jams
|
||||
case 0xF3: ISB( addr_ind_Y() ); return 8; // ISB* izy 8 (undocumented)
|
||||
case 0xF4: NOP(); src_zp_X(); return 4; // NOP* zpx 4 (undocumented)
|
||||
case 0xF5: SBC( src_zp_X() ); return 4; // SBC zpg,X
|
||||
case 0xF6: INC( addr_zp_X() ); return 6; // INC zpg,X
|
||||
// case 0xF7:
|
||||
case 0xF7: ISB( addr_zp_X() ); return 6; // ISB* zpx 6 (undocumented)
|
||||
case 0xF8: SED(); return 2; // SED
|
||||
case 0xF9: SBC( src_abs_Y() ); return 4; // SBC abs,Y
|
||||
// case 0xFA:
|
||||
// case 0xFB:
|
||||
// case 0xFC:
|
||||
case 0xFA: NOP(); return 2; // NOP
|
||||
case 0xFB: ISB( addr_abs_Y() ); return 7; // ISB* aby 7 (undocumented)
|
||||
case 0xFC: NOP(); src_abs_X(); return 4; // NOP* abx 4 (undocumented)
|
||||
case 0xFD: SBC( src_abs_X() ); return 4; // SBC abs,X
|
||||
case 0xFE: INC( addr_abs_X() ); return 7; // INC abs,X
|
||||
// case 0xFF:
|
||||
case 0xFF: ISB( addr_abs_X() ); return 7; // ISB* abx 7 (undocumented)
|
||||
|
||||
default:
|
||||
dbgPrintf("%04X: Unimplemented Instruction 0x%02X\n", m6502.PC -1, memread( m6502.PC -1 ));
|
||||
|
@ -88,11 +88,7 @@ INLINE void ADC( uint8_t src ) {
|
||||
(indirect,X) SBC (oper,X) E1 2 6
|
||||
(indirect),Y SBC (oper),Y F1 2 5*
|
||||
**/
|
||||
INLINE void SBC( uint8_t src ) {
|
||||
dbgPrintf("SBC(%02X) ", src);
|
||||
disPrintf(disassembly.inst, "SBC");
|
||||
// ADC( ~src );
|
||||
|
||||
INLINE void _SBC( uint8_t src ) {
|
||||
uint16_t tmp;
|
||||
|
||||
if( m6502.D ) {
|
||||
@ -109,14 +105,19 @@ INLINE void SBC( uint8_t src ) {
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
{
|
||||
tmp = m6502.A - src - !m6502.C;
|
||||
}
|
||||
}
|
||||
|
||||
m6502.C = tmp < 0x100;
|
||||
m6502.V = ( (m6502.A ^ tmp) & 0x80 ) && ( (m6502.A ^ src) & 0x80 );
|
||||
set_flags_NZ( m6502.A = tmp );
|
||||
}
|
||||
INLINE void SBC( uint8_t src ) {
|
||||
dbgPrintf("SBC(%02X) ", src);
|
||||
disPrintf(disassembly.inst, "SBC");
|
||||
_SBC(src);
|
||||
}
|
||||
|
||||
#endif // __6502_INSTR_ARITHMETIC_H__
|
||||
|
||||
|
@ -48,10 +48,13 @@ INLINE void BIT( uint8_t src ) {
|
||||
(indirect,X) CMP (oper,X) C1 2 6
|
||||
(indirect),Y CMP (oper),Y D1 2 5*
|
||||
**/
|
||||
INLINE void _CMP( uint8_t src ) {
|
||||
set_flags_NZC( (int16_t)m6502.A - src );
|
||||
}
|
||||
INLINE void CMP( uint8_t src ) {
|
||||
dbgPrintf("CMP(%02X) ", src);
|
||||
disPrintf(disassembly.inst, "CMP");
|
||||
set_flags_NZC( (int16_t)m6502.A - src );
|
||||
_CMP(src);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,11 +23,12 @@
|
||||
absolute INC oper EE 3 6
|
||||
absolute,X INC oper,X FE 3 7
|
||||
**/
|
||||
INLINE void INC( uint16_t addr ) {
|
||||
dbgPrintf("INC %02X -> ", WRLOMEM[addr]);
|
||||
disPrintf(disassembly.inst, "INC");
|
||||
INLINE void _INC( uint16_t addr ) {
|
||||
set_flags_NZ( ++(WRLOMEM[addr]) );
|
||||
dbgPrintf("%02X ", WRLOMEM[addr]);
|
||||
}
|
||||
INLINE void INC( uint16_t addr ) {
|
||||
disPrintf(disassembly.inst, "INC");
|
||||
_INC(addr);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,11 +78,12 @@ INLINE void INY() {
|
||||
absolute DEC oper CE 3 3
|
||||
absolute,X DEC oper,X DE 3 7
|
||||
**/
|
||||
INLINE void DEC( uint16_t addr ) {
|
||||
dbgPrintf("DEC %02X -> ", WRLOMEM[addr]);
|
||||
disPrintf(disassembly.inst, "DEC");
|
||||
INLINE void _DEC( uint16_t addr ) {
|
||||
set_flags_NZ( --(WRLOMEM[addr]) );
|
||||
dbgPrintf("%02X ", WRLOMEM[addr]);
|
||||
}
|
||||
INLINE void DEC( uint16_t addr ) {
|
||||
disPrintf(disassembly.inst, "DEC");
|
||||
_DEC(addr);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -27,10 +27,13 @@
|
||||
(indirect,X) ORA (oper,X) 01 2 6
|
||||
(indirect),Y ORA (oper),Y 11 2 5*
|
||||
**/
|
||||
INLINE void _ORA( uint8_t src ) {
|
||||
set_flags_NZ( m6502.A |= src );
|
||||
}
|
||||
INLINE void ORA( uint8_t src ) {
|
||||
dbgPrintf("ORA(%02X) ", src);
|
||||
disPrintf(disassembly.inst, "ORA");
|
||||
set_flags_NZ( m6502.A |= src );
|
||||
_ORA(src);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,10 +53,13 @@ INLINE void ORA( uint8_t src ) {
|
||||
(indirect,X) AND (oper,X) 21 2 6
|
||||
(indirect),Y AND (oper),Y 31 2 5*
|
||||
**/
|
||||
INLINE void _AND( uint8_t src ) {
|
||||
set_flags_NZ( m6502.A &= src );
|
||||
}
|
||||
INLINE void AND( uint8_t src ) {
|
||||
dbgPrintf("AND(%02X) ", src);
|
||||
disPrintf(disassembly.inst, "AND");
|
||||
set_flags_NZ( m6502.A &= src );
|
||||
_AND(src);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -24,11 +24,14 @@
|
||||
absolute ASL oper 0E 3 6
|
||||
absolute,X ASL oper,X 1E 3 7
|
||||
**/
|
||||
INLINE void _ASL( uint16_t addr ) {
|
||||
m6502.C = WRLOMEM[addr] & 0x80;
|
||||
set_flags_NZ( WRLOMEM[addr] <<= 1 );
|
||||
}
|
||||
INLINE void ASL( uint16_t addr ) {
|
||||
dbgPrintf("ASL ");
|
||||
disPrintf(disassembly.inst, "ASL");
|
||||
m6502.C = WRLOMEM[addr] & 0x80;
|
||||
set_flags_NZ( WRLOMEM[addr] <<= 1 );
|
||||
_ASL(addr);
|
||||
}
|
||||
INLINE void ASLA() {
|
||||
dbgPrintf("ASL ");
|
||||
@ -78,14 +81,17 @@ INLINE void LSRA() {
|
||||
absolute ROL oper 2E 3 6
|
||||
absolute,X ROL oper,X 3E 3 7
|
||||
**/
|
||||
INLINE void ROL( uint16_t addr ) {
|
||||
dbgPrintf("ROL ");
|
||||
disPrintf(disassembly.inst, "ROL");
|
||||
INLINE void _ROL( uint16_t addr ) {
|
||||
uint8_t C = m6502.C != 0;
|
||||
m6502.C = WRLOMEM[addr] & 0x80;
|
||||
WRLOMEM[addr] <<= 1;
|
||||
set_flags_NZ( WRLOMEM[addr] |= C );
|
||||
}
|
||||
INLINE void ROL( uint16_t addr ) {
|
||||
dbgPrintf("ROL ");
|
||||
disPrintf(disassembly.inst, "ROL");
|
||||
_ROL(addr);
|
||||
}
|
||||
INLINE void ROLA() {
|
||||
dbgPrintf("ROL ");
|
||||
disPrintf(disassembly.inst, "ROL");
|
||||
|
@ -25,6 +25,29 @@ INLINE void ANC ( uint8_t src ) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
ARC - "AND" Memory with Accumulator
|
||||
THEN Copy Bit 7 of Result into Carry
|
||||
THEN Rotate Accumulator One Bit Right
|
||||
(Carry unaffected)
|
||||
|
||||
(M "AND" A) -> A
|
||||
THEN msb(A) -> C
|
||||
THEN ROR A
|
||||
**/
|
||||
INLINE void ARC ( uint8_t src ) {
|
||||
disPrintf(disassembly.inst, "ARC");
|
||||
|
||||
_AND(src);
|
||||
m6502.C = m6502.A >> 7;
|
||||
|
||||
// RORA -- Carry not affected
|
||||
uint8_t C = m6502.C != 0;
|
||||
m6502.A >>= 1;
|
||||
set_flags_NZ( m6502.A |= C << 7);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
ASR - "AND" Memory with Accumulator
|
||||
THEN Shift Accumulator One Bit Right
|
||||
@ -45,20 +68,52 @@ INLINE void ASR ( uint8_t src ) {
|
||||
|
||||
|
||||
/**
|
||||
NOP No Operation
|
||||
DCP - Decrement Memory by One
|
||||
THEN Compare Memory with Accumulator
|
||||
|
||||
--- N Z C I D V
|
||||
- - - - - -
|
||||
|
||||
addressing assembler opc bytes cyles
|
||||
--------------------------------------------
|
||||
implied NOP EA ? ?
|
||||
(M - 1) -> M
|
||||
THEN CMP M
|
||||
**/
|
||||
INLINE void NOP2( uint8_t src ) {
|
||||
disPrintf(disassembly.inst, "NOP2");
|
||||
INLINE void DCP ( uint16_t addr ) {
|
||||
disPrintf(disassembly.inst, "DCP");
|
||||
_DEC(addr);
|
||||
_CMP(WRLOMEM[addr]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
LAS - Stores {adr} & S into A, X and S
|
||||
**/
|
||||
INLINE void LAS ( uint8_t src ) {
|
||||
disPrintf(disassembly.inst, "LAS");
|
||||
set_flags_NZ( m6502.A = m6502.X = m6502.SP = m6502.SP & src );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
ISB / ISC / INS - Increment Memory by One
|
||||
THEN Subtract Memory from Accumulator with Borrow
|
||||
|
||||
(M + 1) -> M
|
||||
THEN (A - M - ~C) -> A
|
||||
**/
|
||||
INLINE void ISB ( uint16_t addr ) {
|
||||
disPrintf(disassembly.inst, "ISB");
|
||||
_INC(addr);
|
||||
_SBC(WRLOMEM[addr]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
LAX - Load Index X and Accumulator with Memory
|
||||
|
||||
M -> X,A
|
||||
**/
|
||||
INLINE void LAX ( uint8_t src ) {
|
||||
disPrintf(disassembly.inst, "LAX");
|
||||
set_flags_NZ(m6502.A = m6502.X = src);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
RLA - Rotate Memory One Bit Left
|
||||
@ -70,15 +125,8 @@ INLINE void NOP2( uint8_t src ) {
|
||||
INLINE void RLA ( uint16_t addr ) {
|
||||
disPrintf(disassembly.inst, "RLA");
|
||||
|
||||
// ROL M
|
||||
uint8_t C = m6502.C != 0;
|
||||
m6502.C = WRLOMEM[addr] & 0x80;
|
||||
WRLOMEM[addr] <<= 1;
|
||||
WRLOMEM[addr] |= C;
|
||||
|
||||
// AND M
|
||||
set_flags_NZ( m6502.A &= WRLOMEM[addr] );
|
||||
|
||||
_ROL(addr);
|
||||
_AND(WRLOMEM[addr]);
|
||||
}
|
||||
|
||||
|
||||
@ -96,6 +144,92 @@ INLINE void RRA ( uint16_t addr ) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
SAS - "AND" Accumulator with Index X into Stack Pointer
|
||||
THEN Store Result "AND" (MSB(Address)+1) in Memory
|
||||
|
||||
(A "AND" X) -> SP
|
||||
THEN (SP "AND" (MSB(adr)+1)) -> M
|
||||
**/
|
||||
|
||||
INLINE void SAS ( uint16_t addr ) {
|
||||
disPrintf(disassembly.inst, "SAS");
|
||||
m6502.SP = m6502.A & m6502.X;
|
||||
set_flags_NZ( WRLOMEM[addr] = m6502.SP & ((addr >> 8) + 1) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
SBX - Store Index X "AND" Accumulator in Memory
|
||||
|
||||
Carry and Decimal flags are ignored but the
|
||||
Carry flag will be set in substraction. This
|
||||
is due to the CMP command, which is executed
|
||||
instead of the real SBC.
|
||||
|
||||
(A & X) - Immediate -> X
|
||||
|
||||
The 'SBX' ($CB) may seem to be very complex operation, even though it
|
||||
is a combination of the subtraction of accumulator and parameter, as
|
||||
in the 'CMP' instruction, and the command 'DEX'. As a result, both A
|
||||
and X are connected to ALU but only the subtraction takes place. Since
|
||||
the comparison logic was used, the result of subtraction should be
|
||||
normally ignored, but the 'DEX' now happily stores to X the value of
|
||||
(A & X) - Immediate. That is why this instruction does not have any
|
||||
decimal mode, and it does not affect the V flag. Also Carry flag will
|
||||
be ignored in the subtraction but set according to the result.
|
||||
|
||||
**/
|
||||
INLINE void SBX ( uint8_t src ) {
|
||||
disPrintf(disassembly.inst, "SBX");
|
||||
|
||||
uint16_t tmp;
|
||||
|
||||
// Decimal flag is ignored
|
||||
tmp = (m6502.A & m6502.X) - src;
|
||||
|
||||
m6502.C = tmp < 0x100;
|
||||
m6502.V = ( (m6502.A ^ tmp) & 0x80 ) && ( (m6502.A ^ src) & 0x80 );
|
||||
set_flags_NZ( m6502.X = tmp );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
SHA - Store Index X "AND" Accumulator in Memory
|
||||
|
||||
(X "AND" A "AND" addr.H) -> M
|
||||
**/
|
||||
|
||||
INLINE void SHA ( uint16_t addr ) {
|
||||
disPrintf(disassembly.inst, "SHA");
|
||||
set_flags_NZ( WRLOMEM[addr] = m6502.X & m6502.A & ((addr >> 8) + 1) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
SHY - Store (MSB(Address)+1) "AND" Index Y in Memory
|
||||
|
||||
((MSB(adr)+1) "AND" Y) -> M
|
||||
**/
|
||||
|
||||
INLINE void SHY ( uint16_t addr ) {
|
||||
disPrintf(disassembly.inst, "SHY");
|
||||
set_flags_NZ( WRLOMEM[addr] = m6502.Y &((addr >> 8) + 1) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
SHX - Store (MSB(Address)+1) "AND" Index Y in Memory
|
||||
|
||||
((MSB(adr)+1) "AND" X) -> M
|
||||
**/
|
||||
|
||||
INLINE void SHX ( uint16_t addr ) {
|
||||
disPrintf(disassembly.inst, "SHX");
|
||||
set_flags_NZ( WRLOMEM[addr] = m6502.X &((addr >> 8) + 1) );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
SLO - Shift Memory One Bit Left
|
||||
THEN "OR" Memory with Accumulator
|
||||
@ -109,13 +243,24 @@ INLINE void RRA ( uint16_t addr ) {
|
||||
INLINE void SLO ( uint16_t addr ) {
|
||||
disPrintf(disassembly.inst, "SLO");
|
||||
|
||||
m6502.C = WRLOMEM[addr] & 0x80;
|
||||
WRLOMEM[addr] <<= 1; // ASL M -> M
|
||||
m6502.A ^= WRLOMEM[addr]; // EOR M -> A
|
||||
_ASL(addr);
|
||||
_ORA( WRLOMEM[addr] );
|
||||
set_flags_NZ( WRLOMEM[addr] = m6502.A ); // A -> M
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
SAX - Store Accumulator "AND" Index X in Memory
|
||||
|
||||
(A "AND" X) -> M
|
||||
**/
|
||||
|
||||
INLINE void SAX ( uint16_t addr ) {
|
||||
disPrintf(disassembly.inst, "SAX");
|
||||
set_flags_NZ( WRLOMEM[addr] = m6502.A & m6502.X );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
SRE - Shift Memory One Bit Right
|
||||
THEN "OR" Memory with Accumulator
|
||||
@ -137,6 +282,17 @@ INLINE void SRE ( uint16_t addr ) {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
XAA - "AND" Memory with Index X into Accumulator
|
||||
|
||||
(M "AND" X) -> A
|
||||
**/
|
||||
INLINE void XAA ( uint8_t src ) {
|
||||
disPrintf(disassembly.inst, "XAA");
|
||||
set_flags_NZ( m6502.A = m6502.X & src );
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif // __6502_INSTR_UNDOC_H__
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user