Verify Nintendo logo checksum.
Handle read errors when loading the cartridge.
This commit is contained in:
parent
840c00e30b
commit
b0df091425
|
@ -10,27 +10,46 @@ type memory_bank_controller =
|
||||||
type t = {
|
type t = {
|
||||||
nintendo_logo : bytes;
|
nintendo_logo : bytes;
|
||||||
title : string;
|
title : string;
|
||||||
mem_type : memory_bank_controller;
|
(* mem_type : memory_bank_controller;
|
||||||
rom_size : int;
|
rom_size : int;
|
||||||
ram_size : int;
|
ram_size : int;
|
||||||
header_checksum : bytes;
|
header_checksum : bytes;
|
||||||
global_checksum : bytes;
|
global_checksum : bytes; *)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
(** The Nintendo logo is a checksum in the header *)
|
||||||
|
let check_nintendo_logo cartridge =
|
||||||
|
let reference = Bytes.of_string
|
||||||
|
"\xCE\xED\x66\x66\xCC\x0D\x00\x0B\x03\x73\x00\x83\x00\x0C\x00\x0D\
|
||||||
|
\x00\x08\x11\x1F\x88\x89\x00\x0E\xDC\xCC\x6E\xE6\xDD\xDD\xD9\x99\
|
||||||
|
\xBB\xBB\x67\x63\x6E\x0E\xEC\xCC\xDD\xDC\x99\x9F\xBB\xB9\x33\x3E" in
|
||||||
|
(Bytes.compare cartridge.nintendo_logo reference) == 0
|
||||||
|
|
||||||
|
exception Read_error
|
||||||
|
|
||||||
let read_cartridge file =
|
let read_cartridge file =
|
||||||
print_endline file;
|
try
|
||||||
let fd = openfile file [Unix.O_RDONLY] 0o644 in
|
let fd = openfile file [Unix.O_RDONLY] 0o644 in
|
||||||
|
|
||||||
let _ = lseek fd 0x0104 SEEK_SET in
|
try
|
||||||
|
let nin_logo_offset = 0x0104 in
|
||||||
|
if (lseek fd nin_logo_offset SEEK_SET) != nin_logo_offset
|
||||||
|
then raise Read_error;
|
||||||
|
|
||||||
let n_logo = Bytes.create 48 in
|
let nin_logo_size = 48 in
|
||||||
let _ = read fd n_logo 0 48 in
|
let nintendo_logo = Bytes.create nin_logo_size in
|
||||||
print_endline "Nintendo logo:";
|
if (read fd nintendo_logo 0 nin_logo_size) != nin_logo_size
|
||||||
Hexa.print_bytes n_logo ~width:16;
|
then raise Read_error;
|
||||||
|
|
||||||
let title_b = Bytes.create 16 in
|
let title_size = 16 in
|
||||||
let _ = read fd title_b 0 16 in
|
let title_b = Bytes.create title_size in
|
||||||
|
if (read fd title_b 0 title_size) != title_size
|
||||||
|
then raise Read_error;
|
||||||
let title = Bytes.to_string title_b in
|
let title = Bytes.to_string title_b in
|
||||||
printf "ROM title: %s\n" title;
|
|
||||||
|
|
||||||
Unix.close fd
|
Unix.close fd;
|
||||||
|
Some { nintendo_logo; title }
|
||||||
|
|
||||||
|
with Read_error -> Unix.close fd; None
|
||||||
|
|
||||||
|
with Unix_error(err, cmd, msg) -> None
|
||||||
|
|
15
src/oboy.ml
15
src/oboy.ml
|
@ -1,4 +1,15 @@
|
||||||
|
(** Power up sequence *)
|
||||||
|
let power_up cartridge =
|
||||||
|
(** Nintendo logo scrolling *)
|
||||||
|
if not (Cartridge.check_nintendo_logo cartridge)
|
||||||
|
then print_endline "Invalid ROM."
|
||||||
|
else print_endline "Valid ROM."
|
||||||
|
|
||||||
let () =
|
let () =
|
||||||
if Array.length Sys.argv < 2
|
if Array.length Sys.argv < 2
|
||||||
then print_endline "Please specify a ROM."
|
then print_endline "Please specify a ROM.";
|
||||||
else Cartridge.read_cartridge Sys.argv.(1)
|
|
||||||
|
let cartridge = Cartridge.read_cartridge Sys.argv.(1) in
|
||||||
|
match cartridge with
|
||||||
|
| None -> print_endline "Invalid ROM file."
|
||||||
|
| Some c -> power_up c
|
||||||
|
|
Loading…
Reference in a new issue