From 013fd9abe40894c45adb6b2bc4039c081ba91169 Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Mon, 17 Aug 2015 22:26:11 +0200 Subject: [PATCH] Add fps to main loop --- _tags | 2 +- src/cpu.ml | 66 +++++++++++++++++++++++++++++------------------------ src/oboy.ml | 30 +++++++++++++++++++++--- 3 files changed, 64 insertions(+), 34 deletions(-) diff --git a/_tags b/_tags index 46e4883..651910e 100644 --- a/_tags +++ b/_tags @@ -1,2 +1,2 @@ -true: package(unix), package(graphics), warn(A-40-42) +true: package(unix), thread, package(graphics), warn(A-40-42) : package(ounit) diff --git a/src/cpu.ml b/src/cpu.ml index e594efb..9f13e3d 100644 --- a/src/cpu.ml +++ b/src/cpu.ml @@ -1,5 +1,7 @@ open Printf +let frequence = 4194304 + (** http://bgb.bircd.org/pandocs.htm#cpuregistersandflags http://gameboy.mongenel.com/dmg/lesson1.html *) @@ -133,12 +135,11 @@ let pop_stack cpu mem = https://github.com/sinamas/gambatte/blob/master/libgambatte/src/cpu.cpp *) let run cpu (mem: Memory.map) = - printf "\n"; print_cpu_state cpu; let opcode = read_pc_byte cpu mem |> char_of_int in (* Hexa.print_slice cartridge.full_rom cpu.reg.pc (cpu.reg.pc + 7); *) - let inst = match opcode with + let inst, cycles = match opcode with (* 8-bit load *) (* LD r,(HL) *) @@ -146,20 +147,20 @@ let run cpu (mem: Memory.map) = let hl = merge_bytes cpu.reg.l cpu.reg.h in cpu.reg.a <- Memory.get mem hl; inc_cycles cpu 8; - inst + inst, 8 | '\x36' -> let n = read_pc_byte cpu mem in let inst = sprintf "LD \t(HL) 0x%02X" n in let hl = merge_bytes cpu.reg.l cpu.reg.h in Memory.set mem hl (char_of_int n); inc_cycles cpu 12; - inst + inst, 12 (* CPU control *) | '\x00' -> let inst = sprintf "NOP" in inc_cycles cpu 4; - inst + inst, 4 (* jump *) @@ -170,30 +171,34 @@ let run cpu (mem: Memory.map) = begin inc_pc cpu (s - 2); (* we read 2 bytes from PC, opcode and n *) inc_cycles cpu 12; - end else + inst, 12 + end else begin inc_cycles cpu 8; - inst + inst, 8 + end | '\xC9' -> let inst = sprintf "RET" in cpu.reg.pc <- pop_stack cpu mem; inc_cycles cpu 16; - inst + inst, 16 | '\xC0' -> let inst = sprintf "RET \tNZ" in if cpu.flag.z = false then begin cpu.reg.pc <- pop_stack cpu mem; inc_cycles cpu 20; - end else + inst, 20 + end else begin inc_cycles cpu 8; - inst + inst, 8 + end | '\x03' -> let inst = sprintf "INC \tBC" in inc_BC cpu; inc_cycles cpu 8; - inst + inst, 8 | '\x05' -> let inst = sprintf "DEC \tB" in let dec = int_of_char(cpu.reg.b) - 1 in @@ -202,18 +207,18 @@ let run cpu (mem: Memory.map) = cpu.flag.h <- dec < 0; cpu.reg.b <- char_of_int @@ if dec >= 0 then dec else 0; inc_cycles cpu 4; - inst + inst, 4 | '\x06' -> let n = read_pc_byte cpu mem in let inst = sprintf "LD \tB, 0x%02X" n in cpu.reg.b <- char_of_int n; inc_cycles cpu 8; - inst + inst, 8 | '\x18' -> let n = read_pc_byte cpu mem in let inst = sprintf "JP \t0x%02X" n in inc_pc cpu (n - 1); inc_cycles cpu 12; - inst + inst, 12 | '\x21' -> let nn = read_pc_2bytes cpu mem in let inst = sprintf "LD \tHL, 0x%04X" nn in @@ -221,7 +226,7 @@ let run cpu (mem: Memory.map) = cpu.reg.h <- high; cpu.reg.l <- low; inc_cycles cpu 12; - inst + inst, 12 | '\x22' -> let inst = sprintf "LDI \t(HL), A" in let hl = merge_bytes cpu.reg.l cpu.reg.h in @@ -230,7 +235,7 @@ let run cpu (mem: Memory.map) = cpu.reg.h <- high; cpu.reg.l <- low; inc_cycles cpu 8; - inst + inst, 8 | '\x28' -> let n = read_pc_byte cpu mem in @@ -238,9 +243,11 @@ let run cpu (mem: Memory.map) = if cpu.flag.z = true then begin inc_pc cpu (n - 1); inc_cycles cpu 12; - end else + inst, 12 + end else begin inc_cycles cpu 8; - inst + inst, 8 + end | '\x34' -> let inst = sprintf "INC \t(HL)" in let hl = merge_bytes cpu.reg.l cpu.reg.h in @@ -250,65 +257,64 @@ let run cpu (mem: Memory.map) = cpu.flag.h <- v = 0b00001111; Memory.set mem hl (char_of_int (v + 1)); inc_cycles cpu 12; - inst + inst, 12 | '\x3E' -> let n = read_pc_byte cpu mem in let inst = sprintf "LD \tA, 0x%02X" n in cpu.reg.a <- char_of_int n; inc_cycles cpu 8; - inst + inst, 8 | '\xAF' -> let inst = sprintf "XOR \tA, A" in let int_A = int_of_char cpu.reg.a in cpu.reg.a <- char_of_int @@ int_A lxor int_A; inc_cycles cpu 4; - inst + inst, 4 | '\xC3' -> let addr = read_pc_2bytes cpu mem in let inst = sprintf "JP \t0x%04X" addr in cpu.reg.pc <- addr; inc_cycles cpu 16; - inst + inst, 16 | '\xE0' -> let n = read_pc_byte cpu mem in let inst = sprintf "LDH \t(0xFF%02X), A" n in Memory.set mem (0xFF00 + n) cpu.reg.a; inc_cycles cpu 12; - inst + inst, 12 | '\xEA' -> let addr = read_pc_2bytes cpu mem in let inst = sprintf "LD \t(0X%04X), A" addr in Memory.set mem addr cpu.reg.a; inc_cycles cpu 16; - inst + inst, 16 | '\xF0' -> let n = read_pc_byte cpu mem in let inst = sprintf "LDH \tA, (0xFF%02X)" n in cpu.reg.a <- Memory.get mem (0xFF00 + n); inc_cycles cpu 12; - inst + inst, 12 | '\xF3' -> let inst = sprintf "DI" in (* fixme *) inc_cycles cpu 4; - inst + inst, 4 | '\xFE' -> let n = read_pc_byte cpu mem in let inst = sprintf "CP \t0x%02X" n in cmp_A cpu n; inc_cycles cpu 8; - inst + inst, 8 | '\xFB' -> let inst = sprintf "EI" in (* enable interrupts, IME=1 *) inc_cycles cpu 4; - inst + inst, 4 | x -> eprintf "opcode 0x%02X\n" (int_of_char x); eprintf "#cycles: %d\n" cpu.cycles; failwith "Unimplemented opcode." in - - printf "[Instruction] %s\n" inst + inst, cycles diff --git a/src/oboy.ml b/src/oboy.ml index 785710d..107e23d 100644 --- a/src/oboy.ml +++ b/src/oboy.ml @@ -1,7 +1,31 @@ open Printf +let fps = 60 +let cycles_per_frame = Cpu.frequence / fps + let rec run (cpu: Cpu.t) (mem: Memory.map) (screen: Screen.t) = - Cpu.run cpu mem; + printf "\n"; + let start = Unix.gettimeofday () in + printf "start %f\n" start; + + let rec run_for cpu mem cycles_remaining = + if cycles_remaining > 0 then + begin + let inst, cycles = Cpu.run cpu mem in + printf "[Instruction] %s\n" inst; + run_for cpu mem (cycles_remaining - cycles) + end + in + run_for cpu mem cycles_per_frame; + + let stop = Unix.gettimeofday () in + let delay = (1. -. (stop -. start)) /. (float_of_int fps) in + printf "stop %f\n" stop; + printf "delta %f\n" (stop -. start); + printf "delay %f\n" delay; + flush_all (); + + if delay > 0. then Thread.delay delay; run cpu mem screen (** Power up sequence @@ -18,9 +42,9 @@ let power_up cartridge = let mem = Memory.init cartridge in let screen = Screen.init in - Graphics.open_graph ""; + (*Graphics.open_graph ""; Graphics.resize_window Screen.width Screen.height; - + *) run cpu mem screen