|
|
@ -67,26 +67,26 @@ void CPU::update() |
|
|
|
print("running opcode: {:#x}\n", opcode); |
|
|
|
print("running opcode: {:#x}\n", opcode); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
|
|
|
|
|
|
|
|
case 0x20: jr8(); break; |
|
|
|
case 0x01: ldi16(); break; |
|
|
|
case 0x01: ld16(); break; |
|
|
|
|
|
|
|
case 0x02: ldr8(); break; |
|
|
|
case 0x02: ldr8(); break; |
|
|
|
case 0x06: ldi8(); break; |
|
|
|
case 0x06: ldi8(); break; |
|
|
|
case 0x08: ld16(); break; |
|
|
|
case 0x08: lda16(); break; |
|
|
|
case 0x0a: ldr8(); break; |
|
|
|
case 0x0a: ldr8(); break; |
|
|
|
case 0x0d: dec8(); break; |
|
|
|
case 0x0d: dec8(); break; |
|
|
|
case 0x0e: ldi8(); break; |
|
|
|
case 0x0e: ldi8(); break; |
|
|
|
case 0x11: ld16(); break; |
|
|
|
case 0x11: ldi16(); break; |
|
|
|
case 0x12: ldr8(); break; |
|
|
|
case 0x12: ldr8(); break; |
|
|
|
case 0x16: ldi8(); break; |
|
|
|
case 0x16: ldi8(); break; |
|
|
|
case 0x1a: ldr8(); break; |
|
|
|
case 0x1a: ldr8(); break; |
|
|
|
case 0x1e: ldi8(); break; |
|
|
|
case 0x1e: ldi8(); break; |
|
|
|
case 0x21: ld16(); break; |
|
|
|
case 0x20: jr8(); break; |
|
|
|
|
|
|
|
case 0x21: ldi16(); break; |
|
|
|
case 0x22: ldr8(); break; |
|
|
|
case 0x22: ldr8(); break; |
|
|
|
case 0x26: ldi8(); break; |
|
|
|
case 0x26: ldi8(); break; |
|
|
|
case 0x2a: ldr8(); break; |
|
|
|
case 0x2a: ldr8(); break; |
|
|
|
case 0x2e: ldi8(); break; |
|
|
|
case 0x2e: ldi8(); break; |
|
|
|
case 0x2f: misc(); break; |
|
|
|
case 0x2f: misc(); break; |
|
|
|
case 0x31: ld16(); break; |
|
|
|
case 0x31: ldi16(); break; |
|
|
|
case 0x32: ldr8(); break; |
|
|
|
case 0x32: ldr8(); break; |
|
|
|
case 0x36: ldi8(); break; |
|
|
|
case 0x36: ldi8(); break; |
|
|
|
case 0x3a: ldr8(); break; |
|
|
|
case 0x3a: ldr8(); break; |
|
|
@ -98,8 +98,8 @@ void CPU::update() |
|
|
|
case 0xcd: call(); break; |
|
|
|
case 0xcd: call(); break; |
|
|
|
case 0xe0: ldffi8(); break; |
|
|
|
case 0xe0: ldffi8(); break; |
|
|
|
case 0xf0: ldffi8(); break; |
|
|
|
case 0xf0: ldffi8(); break; |
|
|
|
case 0xf8: ld16(); break; |
|
|
|
case 0xf8: ldr16(); break; |
|
|
|
case 0xf9: ld16(); break; |
|
|
|
case 0xf9: ldr16(); break; |
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
default: |
|
|
|
print("opcode {:#x} not implemented\n", opcode); |
|
|
|
print("opcode {:#x} not implemented\n", opcode); |
|
|
@ -175,6 +175,67 @@ void CPU::xor8() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CPU::lda8() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
|
|
|
|
switch (opcode) { |
|
|
|
|
|
|
|
case 0x22: { // LD (HL+),A == LD (HLI),A == LDI (HL),A
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Put A into memory address in HL
|
|
|
|
|
|
|
|
uint32_t address = hl(); |
|
|
|
|
|
|
|
write(address, m_a); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Increment HL
|
|
|
|
|
|
|
|
address = (address + 1) & 0xffff; |
|
|
|
|
|
|
|
m_l = address & 0xff; |
|
|
|
|
|
|
|
m_h = address >> 8; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
case 0x2a: { // LD A,(HL+) == LD A,(HLI) == LDI A,(HL)
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Put value at address in HL into A
|
|
|
|
|
|
|
|
uint32_t address = hl(); |
|
|
|
|
|
|
|
m_a = read(address); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Increment HL
|
|
|
|
|
|
|
|
address = (address + 1) & 0xffff; |
|
|
|
|
|
|
|
m_l = address & 0xff; |
|
|
|
|
|
|
|
m_h = address >> 8; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
case 0x32: { // LD (HL-),A == LD (HLD),A == LDD (HL),A
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Put A into memory address in HL
|
|
|
|
|
|
|
|
uint32_t address = hl(); |
|
|
|
|
|
|
|
write(address, m_a); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Decrement HL
|
|
|
|
|
|
|
|
address = (address - 1) & 0xffff; |
|
|
|
|
|
|
|
m_l = address & 0xff; |
|
|
|
|
|
|
|
m_h = address >> 8; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
case 0x3a: { // LD A,(HL-) == LD A,(HLD) == LDD A,(HL)
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Put value at address in HL into A
|
|
|
|
|
|
|
|
uint32_t address = hl(); |
|
|
|
|
|
|
|
m_a = read(address); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Decrement HL
|
|
|
|
|
|
|
|
address = (address + 1) & 0xffff; |
|
|
|
|
|
|
|
m_l = address & 0xff; |
|
|
|
|
|
|
|
m_h = address >> 8; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
VERIFY_NOT_REACHED(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void CPU::ldi8() |
|
|
|
void CPU::ldi8() |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
@ -231,58 +292,6 @@ void CPU::ldr8() |
|
|
|
m_wait_cycles += 8; |
|
|
|
m_wait_cycles += 8; |
|
|
|
m_a = read(de()); |
|
|
|
m_a = read(de()); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x22: { // LD (HL+),A == LD (HLI),A == LDI (HL),A
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Put A into memory address in HL
|
|
|
|
|
|
|
|
uint32_t address = hl(); |
|
|
|
|
|
|
|
write(address, m_a); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Increment HL
|
|
|
|
|
|
|
|
address = (address + 1) & 0xffff; |
|
|
|
|
|
|
|
m_l = address & 0xff; |
|
|
|
|
|
|
|
m_h = address >> 8; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
case 0x2a: { // LD A,(HL+) == LD A,(HLI) == LDI A,(HL)
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Put value at address in HL into A
|
|
|
|
|
|
|
|
uint32_t address = hl(); |
|
|
|
|
|
|
|
m_a = read(address); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Increment HL
|
|
|
|
|
|
|
|
address = (address + 1) & 0xffff; |
|
|
|
|
|
|
|
m_l = address & 0xff; |
|
|
|
|
|
|
|
m_h = address >> 8; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
case 0x32: { // LD (HL-),A == LD (HLD),A == LDD (HL),A
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Put A into memory address in HL
|
|
|
|
|
|
|
|
uint32_t address = hl(); |
|
|
|
|
|
|
|
write(address, m_a); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Decrement HL
|
|
|
|
|
|
|
|
address = (address - 1) & 0xffff; |
|
|
|
|
|
|
|
m_l = address & 0xff; |
|
|
|
|
|
|
|
m_h = address >> 8; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
case 0x3a: { // LD A,(HL-) == LD A,(HLD) == LDD A,(HL)
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Put value at address in HL into A
|
|
|
|
|
|
|
|
uint32_t address = hl(); |
|
|
|
|
|
|
|
m_a = read(address); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Decrement HL
|
|
|
|
|
|
|
|
address = (address + 1) & 0xffff; |
|
|
|
|
|
|
|
m_l = address & 0xff; |
|
|
|
|
|
|
|
m_h = address >> 8; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
default: |
|
|
|
default: |
|
|
|
VERIFY_NOT_REACHED(); |
|
|
|
VERIFY_NOT_REACHED(); |
|
|
|
} |
|
|
|
} |
|
|
@ -309,15 +318,10 @@ void CPU::ldffi8() |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void CPU::ld16() |
|
|
|
void CPU::lda16() |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
case 0x01: { // LD BC,i16
|
|
|
|
|
|
|
|
m_wait_cycles += 12; |
|
|
|
|
|
|
|
write(bc(), pcRead16()); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
case 0x08: { // LD a16,SP
|
|
|
|
case 0x08: { // LD a16,SP
|
|
|
|
m_wait_cycles += 20; |
|
|
|
m_wait_cycles += 20; |
|
|
|
|
|
|
|
|
|
|
@ -325,6 +329,20 @@ void CPU::ld16() |
|
|
|
// TODO
|
|
|
|
// TODO
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
VERIFY_NOT_REACHED(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CPU::ldi16() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
|
|
|
|
switch (opcode) { |
|
|
|
|
|
|
|
case 0x01: { // LD BC,i16
|
|
|
|
|
|
|
|
m_wait_cycles += 12; |
|
|
|
|
|
|
|
write(bc(), pcRead16()); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
case 0x11: // LD DE,i16
|
|
|
|
case 0x11: // LD DE,i16
|
|
|
|
m_wait_cycles += 12; |
|
|
|
m_wait_cycles += 12; |
|
|
|
write(de(), pcRead16()); |
|
|
|
write(de(), pcRead16()); |
|
|
@ -338,6 +356,15 @@ void CPU::ld16() |
|
|
|
m_sp = pcRead16(); |
|
|
|
m_sp = pcRead16(); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
default: |
|
|
|
|
|
|
|
VERIFY_NOT_REACHED(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void CPU::ldr16() |
|
|
|
|
|
|
|
{ |
|
|
|
|
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
|
|
|
|
switch (opcode) { |
|
|
|
case 0xf8: { // LD HL,SP + s8 == LDHL SP,s8, flags: 0 0 H C
|
|
|
|
case 0xf8: { // LD HL,SP + s8 == LDHL SP,s8, flags: 0 0 H C
|
|
|
|
m_wait_cycles += 12; |
|
|
|
m_wait_cycles += 12; |
|
|
|
|
|
|
|
|
|
|
|