diff --git a/src/cpu.ml b/src/cpu.ml index d2dc4e9..776e696 100644 --- a/src/cpu.ml +++ b/src/cpu.ml @@ -93,15 +93,23 @@ let cmp_A cpu n = cpu.flag.c <- diff > 0xFF || diff < 0; update_flag_reg cpu +let read_pc_byte cpu mem = + let b = Memory.get mem cpu.reg.pc in + inc_pc cpu 1; + int_of_char b + +let read_pc_2bytes cpu mem = + let word = read_2B mem cpu.reg.pc in + inc_pc cpu 2; + word + + (** http://imrannazar.com/GameBoy-Z80-Opcode-Map https://github.com/sinamas/gambatte/blob/master/libgambatte/src/cpu.cpp *) let run cpu (mem: Memory.map) = - let opcode = Memory.get mem cpu.reg.pc in - inc_pc cpu 1; - let n = Memory.get mem cpu.reg.pc |> int_of_char in - let nn = Memory.get mem (cpu.reg.pc + 1) |> int_of_char in + let opcode = read_pc_byte cpu mem |> char_of_int in (* Hexa.print_slice cartridge.full_rom cpu.reg.pc (cpu.reg.pc + 7); *) match opcode with | '\x00' -> printf " NOP\n"; @@ -111,38 +119,43 @@ let run cpu (mem: Memory.map) = inc_BC cpu; inc_cycles cpu 8 - | '\x18' -> printf " JP\t 0x%02X\n" n; - inc_pc cpu n; inc_cycles cpu 12 + | '\x18' -> let n = read_pc_byte cpu mem in + printf " JP\t 0x%02X\n" n; + inc_pc cpu (n - 1); inc_cycles cpu 12 - | '\x20' -> printf " JR\t NZ, 0x%02X\n" n; + | '\x20' -> let n = read_pc_byte cpu mem in + printf " JR\t NZ, 0x%02X\n" n; if cpu.flag.z = false then begin - inc_pc cpu n; inc_cycles cpu 12 + inc_pc cpu (n - 1); inc_cycles cpu 12 end else begin - inc_pc cpu 1; inc_cycles cpu 8 + inc_cycles cpu 8 end - | '\x21' -> let addr = read_2B mem cpu.reg.pc in - printf " LD\t HL, 0x%04X\n" addr; - cpu.reg.h <- char_of_int nn; - cpu.reg.l <- char_of_int n; + | '\x21' -> let nn = read_pc_2bytes cpu mem in + printf " LD\t HL, 0x%04X\n" nn; + let high, low = split_2B nn in + cpu.reg.h <- high; + cpu.reg.l <- low; inc_cycles cpu 12 - | '\x28' -> printf " JR\t Z, 0x%02X\n" n; + | '\x28' -> let n = read_pc_byte cpu mem in + printf " JR\t Z, 0x%02X\n" n; if cpu.flag.z = true then begin - inc_pc cpu n; inc_cycles cpu 12 + inc_pc cpu (n - 1); inc_cycles cpu 12 end else begin - inc_pc cpu 1; inc_cycles cpu 8 + inc_cycles cpu 8 end - | '\x3E' -> printf " LD \tA, 0x%02X\n" n; - cpu.reg.a <- char_of_int(n); - inc_pc cpu 1; inc_cycles cpu 8 + | '\x3E' -> let n = read_pc_byte cpu mem in + printf " LD \tA, 0x%02X\n" n; + cpu.reg.a <- char_of_int n; + inc_cycles cpu 8 | '\xAF' -> printf " XOR \tA, A\n"; let int_A = int_of_char cpu.reg.a in @@ -157,25 +170,28 @@ let run cpu (mem: Memory.map) = end else inc_cycles cpu 8 - | '\xC3' -> let addr = read_2B mem cpu.reg.pc in + | '\xC3' -> let addr = read_pc_2bytes cpu mem in printf " JP \t0x%04X\n" addr; cpu.reg.pc <- addr; inc_cycles cpu 16 - | '\xE0' -> printf " LDH \t(0xFF%02X), A\n" n; + | '\xE0' -> let n = read_pc_byte cpu mem in + printf " LDH \t(0xFF%02X), A\n" n; Memory.set mem (0xFF00 + n) cpu.reg.a; - inc_pc cpu 1; inc_cycles cpu 12 + inc_cycles cpu 12 - | '\xF0' -> printf " LDH \tA, (0xFF%02X)\n" n; + | '\xF0' -> let n = read_pc_byte cpu mem in + printf " LDH \tA, (0xFF%02X)\n" n; cpu.reg.a <- Memory.get mem (0xFF00 + n); - inc_pc cpu 1; inc_cycles cpu 12 + inc_cycles cpu 12 | '\xF3' -> printf " DI\n"; (* fixme *) inc_cycles cpu 4 - | '\xFE' -> printf " CP\t0x%02X\n" n; + | '\xFE' -> let n = read_pc_byte cpu mem in + printf " CP\t0x%02X\n" n; cmp_A cpu n; - inc_pc cpu 1; inc_cycles cpu 8 + inc_cycles cpu 8 | x -> eprintf "opcode 0x%02X\n" (int_of_char x); failwith "Unimplemented opcode."