|
|
@ -114,8 +114,7 @@ void CPU::add() |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t immediate = pcRead(); |
|
|
|
uint8_t immediate = pcRead(); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
case 0xc6: |
|
|
|
case 0xc6: // ADD A,i8, flags: Z 0 H C
|
|
|
|
// ADD A,i8, flags: Z 0 H C
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
// Set flags
|
|
|
|
// Set flags
|
|
|
@ -138,8 +137,7 @@ void CPU::dec8() |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
case 0x0d: { |
|
|
|
case 0x0d: { // DEC C, flags: Z 1 H -
|
|
|
|
// DEC C, flags: Z 1 H -
|
|
|
|
|
|
|
|
m_wait_cycles += 4; |
|
|
|
m_wait_cycles += 4; |
|
|
|
|
|
|
|
|
|
|
|
// Set flags
|
|
|
|
// Set flags
|
|
|
@ -162,14 +160,12 @@ void CPU::xor8() |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
case 0xa8: |
|
|
|
case 0xa8: // XOR B, flags: Z 0 0 0
|
|
|
|
// XOR B, flags: Z 0 0 0
|
|
|
|
|
|
|
|
m_nf = m_hf = m_cf = 0; |
|
|
|
m_nf = m_hf = m_cf = 0; |
|
|
|
m_a ^= m_b; |
|
|
|
m_a ^= m_b; |
|
|
|
m_zf = m_a == 0; |
|
|
|
m_zf = m_a == 0; |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0xaf: |
|
|
|
case 0xaf: // XOR A, flags: 1 0 0 0
|
|
|
|
// XOR A, flags: 1 0 0 0
|
|
|
|
|
|
|
|
// A ^ A will always be 0
|
|
|
|
// A ^ A will always be 0
|
|
|
|
m_a = m_nf = m_hf = m_cf = 0; |
|
|
|
m_a = m_nf = m_hf = m_cf = 0; |
|
|
|
m_zf = 1; |
|
|
|
m_zf = 1; |
|
|
@ -183,77 +179,59 @@ void CPU::ldi8() |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
case 0x06: |
|
|
|
case 0x06: // LD B,i8
|
|
|
|
// LD B,i8
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
m_b = pcRead(); |
|
|
|
m_b = pcRead(); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x0e: |
|
|
|
case 0x0e: // LD C,i8
|
|
|
|
// LD C,i8
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
m_c = pcRead(); |
|
|
|
m_c = pcRead(); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x16: |
|
|
|
case 0x16: // LD D,i8
|
|
|
|
// LD D,i8
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
m_d = pcRead(); |
|
|
|
m_d = pcRead(); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x1e: |
|
|
|
case 0x1e: // LD E,i8
|
|
|
|
// LD E,i8
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
m_e = pcRead(); |
|
|
|
m_e = pcRead(); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x26: |
|
|
|
case 0x26: // LD H,i8
|
|
|
|
// LD H,i8
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
m_h = pcRead(); |
|
|
|
m_h = pcRead(); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x2e: |
|
|
|
case 0x2e: // LD L,i8
|
|
|
|
// LD L,i8
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
m_l = pcRead(); |
|
|
|
m_l = pcRead(); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x36: |
|
|
|
case 0x36: // LD (HL),i8
|
|
|
|
// LD (HL),i8
|
|
|
|
m_wait_cycles += 4; |
|
|
|
m_wait_cycles += 12; |
|
|
|
|
|
|
|
write(hl(), pcRead()); |
|
|
|
write(hl(), pcRead()); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x3e: |
|
|
|
case 0x3e: // LD A,i8
|
|
|
|
// LD A,i8
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
m_a = pcRead(); |
|
|
|
m_a = pcRead(); |
|
|
|
break; |
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
VERIFY_NOT_REACHED(); |
|
|
|
VERIFY_NOT_REACHED(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
void CPU::ldr8() |
|
|
|
void CPU::ldr8() |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
case 0x02: |
|
|
|
case 0x02: // LD (BC),A
|
|
|
|
// LD (BC),A
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
m_wait_cycles += 8; |
|
|
|
write(bc(), m_a); |
|
|
|
write(bc(), m_a); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x0a: |
|
|
|
case 0x0a: // LD A,(BC)
|
|
|
|
// LD A,(BC)
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
m_wait_cycles += 8; |
|
|
|
m_a = read(bc()); |
|
|
|
m_a = read(bc()); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x12: |
|
|
|
case 0x12: // LD (DE),A
|
|
|
|
// LD (DE),A
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
m_wait_cycles += 8; |
|
|
|
write(de(), m_a); |
|
|
|
write(de(), m_a); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x1a: |
|
|
|
case 0x1a: // LD A,(DE)
|
|
|
|
// LD A,(DE)
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
m_wait_cycles += 8; |
|
|
|
m_a = read(de()); |
|
|
|
m_a = read(de()); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x22: { |
|
|
|
case 0x22: { // LD (HL+),A == LD (HLI),A == LDI (HL),A
|
|
|
|
// LD (HL+),A == LD (HLI),A == LDI (HL),A
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
// Put A into memory address in HL
|
|
|
|
// Put A into memory address in HL
|
|
|
@ -266,8 +244,7 @@ void CPU::ldr8() |
|
|
|
m_h = address >> 8; |
|
|
|
m_h = address >> 8; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case 0x2a: { |
|
|
|
case 0x2a: { // LD A,(HL+) == LD A,(HLI) == LDI A,(HL)
|
|
|
|
// LD A,(HL+) == LD A,(HLI) == LDI A,(HL)
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
// Put value at address in HL into A
|
|
|
|
// Put value at address in HL into A
|
|
|
@ -280,8 +257,7 @@ void CPU::ldr8() |
|
|
|
m_h = address >> 8; |
|
|
|
m_h = address >> 8; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case 0x32: { |
|
|
|
case 0x32: { // LD (HL-),A == LD (HLD),A == LDD (HL),A
|
|
|
|
// LD (HL-),A == LD (HLD),A == LDD (HL),A
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
// Put A into memory address in HL
|
|
|
|
// Put A into memory address in HL
|
|
|
@ -294,8 +270,7 @@ void CPU::ldr8() |
|
|
|
m_h = address >> 8; |
|
|
|
m_h = address >> 8; |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case 0x3a: { |
|
|
|
case 0x3a: { // LD A,(HL-) == LD A,(HLD) == LDD A,(HL)
|
|
|
|
// LD A,(HL-) == LD A,(HLD) == LDD A,(HL)
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
// Put value at address in HL into A
|
|
|
|
// Put value at address in HL into A
|
|
|
@ -317,15 +292,13 @@ void CPU::ldffi8() |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
case 0xe0: |
|
|
|
case 0xe0: // LD ($ff00 + i8),A == LDH (io8),A
|
|
|
|
// LD ($ff00 + i8),A == LDH (io8),A
|
|
|
|
|
|
|
|
m_wait_cycles += 12; |
|
|
|
m_wait_cycles += 12; |
|
|
|
|
|
|
|
|
|
|
|
// Put value in A into address (0xff00 + next byte in memory)
|
|
|
|
// Put value in A into address (0xff00 + next byte in memory)
|
|
|
|
ffWrite(pcRead(), m_a); |
|
|
|
ffWrite(pcRead(), m_a); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0xf0: |
|
|
|
case 0xf0: // LD A,($ff00 + i8) == LDH A,(io8)
|
|
|
|
// LD A,($ff00 + i8) == LDH A,(io8)
|
|
|
|
|
|
|
|
m_wait_cycles += 12; |
|
|
|
m_wait_cycles += 12; |
|
|
|
|
|
|
|
|
|
|
|
// Put value at address (0xff00 + next byte in memory) into A
|
|
|
|
// Put value at address (0xff00 + next byte in memory) into A
|
|
|
@ -340,37 +313,32 @@ void CPU::ld16() |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
case 0x01: { |
|
|
|
case 0x01: { // LD BC,i16
|
|
|
|
m_wait_cycles += 12; |
|
|
|
m_wait_cycles += 12; |
|
|
|
write(bc(), pcRead16()); |
|
|
|
write(bc(), pcRead16()); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case 0x08: { |
|
|
|
case 0x08: { // LD a16,SP
|
|
|
|
// LD a16,SP
|
|
|
|
|
|
|
|
m_wait_cycles += 20; |
|
|
|
m_wait_cycles += 20; |
|
|
|
|
|
|
|
|
|
|
|
// Put value of SP into address given by next 2 bytes in memory
|
|
|
|
// Put value of SP into address given by next 2 bytes in memory
|
|
|
|
// TODO
|
|
|
|
// TODO
|
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case 0x11: |
|
|
|
case 0x11: // LD DE,i16
|
|
|
|
// LD DE,i16
|
|
|
|
|
|
|
|
m_wait_cycles += 12; |
|
|
|
m_wait_cycles += 12; |
|
|
|
write(de(), pcRead16()); |
|
|
|
write(de(), pcRead16()); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x21: |
|
|
|
case 0x21: // LD HL,i16
|
|
|
|
// LD HL,i16
|
|
|
|
|
|
|
|
m_wait_cycles += 12; |
|
|
|
m_wait_cycles += 12; |
|
|
|
write(hl(), pcRead16()); |
|
|
|
write(hl(), pcRead16()); |
|
|
|
break; |
|
|
|
break; |
|
|
|
case 0x31: { |
|
|
|
case 0x31: { // LD SP,i16
|
|
|
|
// LD SP,i16
|
|
|
|
|
|
|
|
m_wait_cycles += 12; |
|
|
|
m_wait_cycles += 12; |
|
|
|
m_sp = pcRead16(); |
|
|
|
m_sp = pcRead16(); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case 0xf8: { |
|
|
|
case 0xf8: { // LD HL,SP + s8 == LDHL SP,s8, flags: 0 0 H C
|
|
|
|
// LD HL,SP + s8 == LDHL SP,s8, flags: 0 0 H C
|
|
|
|
|
|
|
|
m_wait_cycles += 12; |
|
|
|
m_wait_cycles += 12; |
|
|
|
|
|
|
|
|
|
|
|
// Put SP + next (signed) byte in memory into HL
|
|
|
|
// Put SP + next (signed) byte in memory into HL
|
|
|
@ -386,8 +354,7 @@ void CPU::ld16() |
|
|
|
m_cf = isCarry(m_sp, signed_data, 0x100); |
|
|
|
m_cf = isCarry(m_sp, signed_data, 0x100); |
|
|
|
break; |
|
|
|
break; |
|
|
|
} |
|
|
|
} |
|
|
|
case 0xf9: { |
|
|
|
case 0xf9: { // LD SP,HL
|
|
|
|
// LD SP,HL
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
m_wait_cycles += 8; |
|
|
|
m_sp = hl(); |
|
|
|
m_sp = hl(); |
|
|
|
break; |
|
|
|
break; |
|
|
@ -401,8 +368,7 @@ void CPU::call() |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
case 0xcd: { |
|
|
|
case 0xcd: { // CALL a16
|
|
|
|
// CALL a16
|
|
|
|
|
|
|
|
m_wait_cycles += 24; |
|
|
|
m_wait_cycles += 24; |
|
|
|
|
|
|
|
|
|
|
|
uint32_t data = pcRead16(); |
|
|
|
uint32_t data = pcRead16(); |
|
|
@ -426,8 +392,7 @@ void CPU::jp16() |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
case 0xc3: |
|
|
|
case 0xc3: // JP a16
|
|
|
|
// JP a16
|
|
|
|
|
|
|
|
m_wait_cycles += 16; |
|
|
|
m_wait_cycles += 16; |
|
|
|
m_pc = pcRead16(); |
|
|
|
m_pc = pcRead16(); |
|
|
|
break; |
|
|
|
break; |
|
|
@ -441,8 +406,7 @@ void CPU::jr8() |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
case 0x20: { |
|
|
|
case 0x20: { // JR NZ,s8
|
|
|
|
// JR NZ,s8
|
|
|
|
|
|
|
|
m_wait_cycles += 8; |
|
|
|
m_wait_cycles += 8; |
|
|
|
|
|
|
|
|
|
|
|
if (!m_zf) { |
|
|
|
if (!m_zf) { |
|
|
@ -460,8 +424,7 @@ void CPU::misc() |
|
|
|
{ |
|
|
|
{ |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
uint8_t opcode = pcRead(); |
|
|
|
switch (opcode) { |
|
|
|
switch (opcode) { |
|
|
|
case 0x2f: |
|
|
|
case 0x2f: // CPL, flags: - 1 1 -
|
|
|
|
// CPL, flags: - 1 1 -
|
|
|
|
|
|
|
|
m_wait_cycles += 4; |
|
|
|
m_wait_cycles += 4; |
|
|
|
|
|
|
|
|
|
|
|
// Complement register A (flip all bits)
|
|
|
|
// Complement register A (flip all bits)
|
|
|
|