Add flag register.
This commit is contained in:
parent
e5bc9bc4db
commit
f3916dfd64
55
src/cpu.ml
55
src/cpu.ml
|
@ -17,15 +17,16 @@ type registers = {
|
||||||
mutable pc : int; (* program counter *)
|
mutable pc : int; (* program counter *)
|
||||||
}
|
}
|
||||||
|
|
||||||
(* type flags = {
|
type flags = {
|
||||||
z : bool; (* zero *)
|
mutable z : bool; (* zero *)
|
||||||
n : bool; (* substraction *)
|
mutable n : bool; (* substraction *)
|
||||||
h : bool; (* half-carry *)
|
mutable h : bool; (* half-carry *)
|
||||||
cy : bool; (* carry *)
|
mutable c : bool; (* carry *)
|
||||||
} *)
|
}
|
||||||
|
|
||||||
type t = {
|
type t = {
|
||||||
reg : registers;
|
reg : registers;
|
||||||
|
flag : flags;
|
||||||
mutable cycles : int;
|
mutable cycles : int;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +45,20 @@ let init_registers =
|
||||||
pc = 0x0100;
|
pc = 0x0100;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let init_flags =
|
||||||
|
{
|
||||||
|
z = false; n = false; h = false; c = false
|
||||||
|
}
|
||||||
|
|
||||||
let init_cpu =
|
let init_cpu =
|
||||||
{ reg = init_registers; cycles = 0 }
|
{ reg = init_registers; flag = init_flags; cycles = 0 }
|
||||||
|
|
||||||
|
let update_flag_reg cpu =
|
||||||
|
let z = if cpu.flag.z then 0b10000000 else 0 in
|
||||||
|
let n = if cpu.flag.n then 0b01000000 else 0 in
|
||||||
|
let h = if cpu.flag.h then 0b00100000 else 0 in
|
||||||
|
let c = if cpu.flag.c then 0b00010000 else 0 in
|
||||||
|
cpu.reg.f <- char_of_int @@ z + n + h + c
|
||||||
|
|
||||||
let inc_pc cpu count =
|
let inc_pc cpu count =
|
||||||
cpu.reg.pc <- cpu.reg.pc + count
|
cpu.reg.pc <- cpu.reg.pc + count
|
||||||
|
@ -72,10 +85,18 @@ let inc_BC cpu =
|
||||||
cpu.reg.c <- low;
|
cpu.reg.c <- low;
|
||||||
cpu.reg.b <- high
|
cpu.reg.b <- high
|
||||||
|
|
||||||
|
let cmp_A cpu n =
|
||||||
|
let diff = int_of_char (cpu.reg.a) - n in
|
||||||
|
cpu.flag.z <- diff = 0;
|
||||||
|
cpu.flag.n <- true;
|
||||||
|
cpu.flag.h <- diff > 0x0F || diff < 0;
|
||||||
|
cpu.flag.c <- diff > 0xFF || diff < 0;
|
||||||
|
update_flag_reg cpu
|
||||||
|
|
||||||
(** http://imrannazar.com/GameBoy-Z80-Opcode-Map *)
|
(** http://imrannazar.com/GameBoy-Z80-Opcode-Map *)
|
||||||
let run cpu (mem: Memory.map) =
|
let run cpu (mem: Memory.map) =
|
||||||
let n = Memory.get mem (cpu.reg.pc + 1) in
|
let n = Memory.get mem (cpu.reg.pc + 1) |> int_of_char in
|
||||||
let nn = Memory.get mem (cpu.reg.pc + 2) in
|
(* let nn = Memory.get mem (cpu.reg.pc + 2) in *)
|
||||||
(* Hexa.print_slice cartridge.full_rom cpu.reg.pc (cpu.reg.pc + 7); *)
|
(* Hexa.print_slice cartridge.full_rom cpu.reg.pc (cpu.reg.pc + 7); *)
|
||||||
match Memory.get mem cpu.reg.pc with
|
match Memory.get mem cpu.reg.pc with
|
||||||
| '\x00' -> printf " NOP\n";
|
| '\x00' -> printf " NOP\n";
|
||||||
|
@ -85,8 +106,8 @@ let run cpu (mem: Memory.map) =
|
||||||
inc_BC cpu;
|
inc_BC cpu;
|
||||||
inc_pc cpu 1; inc_cycles cpu 8
|
inc_pc cpu 1; inc_cycles cpu 8
|
||||||
|
|
||||||
| '\x3E' -> printf " LD \tA, 0x%02X\n" (int_of_char n);
|
| '\x3E' -> printf " LD \tA, 0x%02X\n" n;
|
||||||
cpu.reg.a <- n;
|
cpu.reg.a <- char_of_int(n);
|
||||||
inc_pc cpu 2; inc_cycles cpu 8
|
inc_pc cpu 2; inc_cycles cpu 8
|
||||||
|
|
||||||
| '\xAF' -> printf " XOR \tA, A\n";
|
| '\xAF' -> printf " XOR \tA, A\n";
|
||||||
|
@ -98,16 +119,20 @@ let run cpu (mem: Memory.map) =
|
||||||
printf " JP \t0x%04X\n" addr;
|
printf " JP \t0x%04X\n" addr;
|
||||||
cpu.reg.pc <- addr; inc_cycles cpu 16
|
cpu.reg.pc <- addr; inc_cycles cpu 16
|
||||||
|
|
||||||
| '\xE0' -> printf " LDH \t(0xFF%02X), A\n" (int_of_char n);
|
| '\xE0' -> printf " LDH \t(0xFF%02X), A\n" n;
|
||||||
Memory.set mem (0xFF00 + (int_of_char n)) cpu.reg.a;
|
Memory.set mem (0xFF00 + n) cpu.reg.a;
|
||||||
inc_pc cpu 2; inc_cycles cpu 12
|
inc_pc cpu 2; inc_cycles cpu 12
|
||||||
|
|
||||||
| '\xF0' -> printf " LDH \tA, (0xFF%02X)\n" (int_of_char n);
|
| '\xF0' -> printf " LDH \tA, (0xFF%02X)\n" n;
|
||||||
cpu.reg.a = Memory.get mem (0xFF00 + (int_of_char n));
|
cpu.reg.a <- Memory.get mem (0xFF00 + n);
|
||||||
inc_pc cpu 2; inc_cycles cpu 12
|
inc_pc cpu 2; inc_cycles cpu 12
|
||||||
|
|
||||||
| '\xF3' -> printf " DI\n";
|
| '\xF3' -> printf " DI\n";
|
||||||
(* fixme *)
|
(* fixme *)
|
||||||
inc_pc cpu 1; inc_cycles cpu 4
|
inc_pc cpu 1; inc_cycles cpu 4
|
||||||
|
|
||||||
|
| '\xFE' -> printf " CP\t0x%02X\n" n;
|
||||||
|
cmp_A cpu n;
|
||||||
|
inc_pc cpu 2; inc_cycles cpu 8
|
||||||
|
|
||||||
| _ as x -> eprintf "opcode %02X\n" (int_of_char x); failwith "Unimplemented opcode."
|
| _ as x -> eprintf "opcode %02X\n" (int_of_char x); failwith "Unimplemented opcode."
|
||||||
|
|
|
@ -8,6 +8,8 @@ type map = {
|
||||||
rom_bank_01 : bytes; (* additional bank, 16KB *)
|
rom_bank_01 : bytes; (* additional bank, 16KB *)
|
||||||
vram : bytes; (* Video RAM, 8KB *)
|
vram : bytes; (* Video RAM, 8KB *)
|
||||||
io : bytes; (* I/O ports *)
|
io : bytes; (* I/O ports *)
|
||||||
|
hram : bytes; (* High RAM, 8KB *)
|
||||||
|
interrupt : bytes; (* Interrupt Enable Register *)
|
||||||
}
|
}
|
||||||
|
|
||||||
let init (cartridge: Cartridge.t) =
|
let init (cartridge: Cartridge.t) =
|
||||||
|
@ -16,6 +18,8 @@ let init (cartridge: Cartridge.t) =
|
||||||
rom_bank_01 = create 0x4000;
|
rom_bank_01 = create 0x4000;
|
||||||
vram = create 0x2000;
|
vram = create 0x2000;
|
||||||
io = create 0x0080;
|
io = create 0x0080;
|
||||||
|
hram = create 0x2000;
|
||||||
|
interrupt = create 1
|
||||||
}
|
}
|
||||||
|
|
||||||
let get_mem_bank mem addr =
|
let get_mem_bank mem addr =
|
||||||
|
@ -25,6 +29,8 @@ let get_mem_bank mem addr =
|
||||||
| x when x < 0xA000 -> mem.vram, (x - 0x8000)
|
| x when x < 0xA000 -> mem.vram, (x - 0x8000)
|
||||||
| x when x < 0xFF00 -> failwith "Unimplemented memory range."
|
| x when x < 0xFF00 -> failwith "Unimplemented memory range."
|
||||||
| x when x < 0xFF80 -> mem.io, x - 0xFF00
|
| x when x < 0xFF80 -> mem.io, x - 0xFF00
|
||||||
|
| x when x < 0xFFFF -> mem.hram, x - 0xFF80
|
||||||
|
| 0xFFFF -> mem.interrupt, 0
|
||||||
| _ -> failwith "Invalid memory range."
|
| _ -> failwith "Invalid memory range."
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue