74 lines
1.9 KiB
OCaml
74 lines
1.9 KiB
OCaml
|
(**
|
||
|
* Copyright (c) 2015, Fabien Freling
|
||
|
* All rights reserved.
|
||
|
*
|
||
|
* This source code is licensed under the BSD 2-clause license found in the
|
||
|
* LICENSE file at the top level directory of this source tree.
|
||
|
*)
|
||
|
|
||
|
open Printf
|
||
|
|
||
|
let fps = 60
|
||
|
let cycles_per_frame = Cpu.frequence / fps
|
||
|
|
||
|
let rec run (cpu: Cpu.t) (mem: Memory.t) (screen: Screen.t) =
|
||
|
let start = Unix.gettimeofday () in
|
||
|
printf "start %f\n" start;
|
||
|
|
||
|
let rec run_for cpu (mem: Memory.t) cycles_remaining =
|
||
|
if cycles_remaining > 0 then begin
|
||
|
printf "\n";
|
||
|
let inst, cycles = Cpu.run cpu mem.map in
|
||
|
printf "[Instruction] %s\n" inst;
|
||
|
|
||
|
Cpu.handle_interrupts cpu mem.map;
|
||
|
|
||
|
Memory.update_timers mem cycles;
|
||
|
|
||
|
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
|
||
|
http://bgb.bircd.org/pandocs.htm#powerupsequence *)
|
||
|
let power_up cartridge =
|
||
|
(* Nintendo logo scrolling *)
|
||
|
if not (Cartridge.check_nintendo_logo cartridge)
|
||
|
then print_endline "Invalid ROM."
|
||
|
else
|
||
|
print_endline "Valid ROM.";
|
||
|
Cartridge.print_info cartridge;
|
||
|
|
||
|
let cpu = Cpu.init_cpu in
|
||
|
let mem = Memory.init cartridge in
|
||
|
let screen = Screen.init in
|
||
|
|
||
|
(*Graphics.open_graph "";
|
||
|
Graphics.resize_window Screen.width Screen.height;
|
||
|
*)
|
||
|
run cpu mem screen
|
||
|
|
||
|
|
||
|
let () =
|
||
|
if Array.length Sys.argv < 2 then begin
|
||
|
prerr_endline "Please specify a ROM.";
|
||
|
eprintf "Usage: %s path/to/rom\n" Sys.argv.(0);
|
||
|
exit 1;
|
||
|
end;
|
||
|
|
||
|
let cartridge = Cartridge.read_cartridge Sys.argv.(1) in
|
||
|
match cartridge with
|
||
|
| None -> print_endline "Invalid ROM file."
|
||
|
| Some c -> power_up c
|