diff --git a/opcodes.go b/opcodes.go index 1e2e0d1..fdb15ae 100644 --- a/opcodes.go +++ b/opcodes.go @@ -1093,7 +1093,13 @@ func (z *CPU) execOpcode(opcode byte) { z.B-- z.condJr(z.B != 0) // djnz * case 0x18: - z.PC += uint16(z.nextB()) // jr * + // jr * + offset := z.nextB() + if offset&0x80 == 0 { + z.PC += uint16(offset) + } else { + z.PC += 0xFF00 | uint16(offset) + } z.MemPtr = z.PC case 0x20: z.condJr(!z.Flags.Z) // jr nz, * diff --git a/z80go_test.go b/z80go_test.go index 96026bf..16bcfdb 100644 --- a/z80go_test.go +++ b/z80go_test.go @@ -593,3 +593,23 @@ func checkComputerState(t *testing.T, name string) { } } } + +func setMemory(addr uint16, value []byte) { + for i := 0; i < len(value); i++ { + computer.memory[addr+uint16(i)] = value[i] + } +} + +var testJRm = []byte{0x70, 0x7d, 0xb3, 0x3c, 0x28, 0x09, 0xb3, 0xab, 0x4f, 0x7d, 0xa3, 0xb1, 0x6f, 0x18, 0xf1, 0x7d} + +func TestZ80_JR_mnn(t *testing.T) { + setMemory(0x31eb, testJRm) + state := computer.cpu.GetState() + state.PC = 0x31F8 + computer.cpu.SetState(state) + computer.cpu.RunInstruction() + expected := uint16(0x31EB) + if computer.cpu.PC != expected { + t.Errorf("Error JR -nn, result PC=0x%04X, expected: 0x%04X", computer.cpu.PC, expected) + } +}