Add flag register.

master
Fabien Freling 2015-03-23 12:50:02 +01:00
parent e5bc9bc4db
commit f3916dfd64
2 changed files with 46 additions and 15 deletions

View File

@ -17,15 +17,16 @@ type registers = {
mutable pc : int; (* program counter *)
}
(* type flags = {
z : bool; (* zero *)
n : bool; (* substraction *)
h : bool; (* half-carry *)
cy : bool; (* carry *)
} *)
type flags = {
mutable z : bool; (* zero *)
mutable n : bool; (* substraction *)
mutable h : bool; (* half-carry *)
mutable c : bool; (* carry *)
}
type t = {
reg : registers;
flag : flags;
mutable cycles : int;
}
@ -44,8 +45,20 @@ let init_registers =
pc = 0x0100;
}
let init_flags =
{
z = false; n = false; h = false; c = false
}
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 =
cpu.reg.pc <- cpu.reg.pc + count
@ -72,10 +85,18 @@ let inc_BC cpu =
cpu.reg.c <- low;
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 *)
let run cpu (mem: Memory.map) =
let n = Memory.get mem (cpu.reg.pc + 1) in
let nn = Memory.get mem (cpu.reg.pc + 2) in
let n = Memory.get mem (cpu.reg.pc + 1) |> int_of_char in
(* let nn = Memory.get mem (cpu.reg.pc + 2) in *)
(* Hexa.print_slice cartridge.full_rom cpu.reg.pc (cpu.reg.pc + 7); *)
match Memory.get mem cpu.reg.pc with
| '\x00' -> printf " NOP\n";
@ -85,8 +106,8 @@ let run cpu (mem: Memory.map) =
inc_BC cpu;
inc_pc cpu 1; inc_cycles cpu 8
| '\x3E' -> printf " LD \tA, 0x%02X\n" (int_of_char n);
cpu.reg.a <- n;
| '\x3E' -> printf " LD \tA, 0x%02X\n" n;
cpu.reg.a <- char_of_int(n);
inc_pc cpu 2; inc_cycles cpu 8
| '\xAF' -> printf " XOR \tA, A\n";
@ -98,16 +119,20 @@ let run cpu (mem: Memory.map) =
printf " JP \t0x%04X\n" addr;
cpu.reg.pc <- addr; inc_cycles cpu 16
| '\xE0' -> printf " LDH \t(0xFF%02X), A\n" (int_of_char n);
Memory.set mem (0xFF00 + (int_of_char n)) cpu.reg.a;
| '\xE0' -> printf " LDH \t(0xFF%02X), A\n" n;
Memory.set mem (0xFF00 + n) cpu.reg.a;
inc_pc cpu 2; inc_cycles cpu 12
| '\xF0' -> printf " LDH \tA, (0xFF%02X)\n" (int_of_char n);
cpu.reg.a = Memory.get mem (0xFF00 + (int_of_char n));
| '\xF0' -> printf " LDH \tA, (0xFF%02X)\n" n;
cpu.reg.a <- Memory.get mem (0xFF00 + n);
inc_pc cpu 2; inc_cycles cpu 12
| '\xF3' -> printf " DI\n";
(* fixme *)
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."

View File

@ -8,6 +8,8 @@ type map = {
rom_bank_01 : bytes; (* additional bank, 16KB *)
vram : bytes; (* Video RAM, 8KB *)
io : bytes; (* I/O ports *)
hram : bytes; (* High RAM, 8KB *)
interrupt : bytes; (* Interrupt Enable Register *)
}
let init (cartridge: Cartridge.t) =
@ -16,6 +18,8 @@ let init (cartridge: Cartridge.t) =
rom_bank_01 = create 0x4000;
vram = create 0x2000;
io = create 0x0080;
hram = create 0x2000;
interrupt = create 1
}
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 < 0xFF00 -> failwith "Unimplemented memory range."
| x when x < 0xFF80 -> mem.io, x - 0xFF00
| x when x < 0xFFFF -> mem.hram, x - 0xFF80
| 0xFFFF -> mem.interrupt, 0
| _ -> failwith "Invalid memory range."