diff --git a/src/cartridge.ml b/src/cartridge.ml index 19f8c40..a3ec9ef 100644 --- a/src/cartridge.ml +++ b/src/cartridge.ml @@ -10,27 +10,46 @@ type memory_bank_controller = type t = { nintendo_logo : bytes; title : string; - mem_type : memory_bank_controller; +(* mem_type : memory_bank_controller; rom_size : int; ram_size : int; 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 = - print_endline file; - let fd = openfile file [Unix.O_RDONLY] 0o644 in + try + 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 _ = read fd n_logo 0 48 in - print_endline "Nintendo logo:"; - Hexa.print_bytes n_logo ~width:16; + let nin_logo_size = 48 in + let nintendo_logo = Bytes.create nin_logo_size in + if (read fd nintendo_logo 0 nin_logo_size) != nin_logo_size + then raise Read_error; - let title_b = Bytes.create 16 in - let _ = read fd title_b 0 16 in - let title = Bytes.to_string title_b in - printf "ROM title: %s\n" title; + let title_size = 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 - Unix.close fd + Unix.close fd; + Some { nintendo_logo; title } + + with Read_error -> Unix.close fd; None + + with Unix_error(err, cmd, msg) -> None diff --git a/src/oboy.ml b/src/oboy.ml index 54cb30e..a780a63 100644 --- a/src/oboy.ml +++ b/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 () = if Array.length Sys.argv < 2 - then print_endline "Please specify a ROM." - else Cartridge.read_cartridge Sys.argv.(1) + then print_endline "Please specify a ROM."; + + let cartridge = Cartridge.read_cartridge Sys.argv.(1) in + match cartridge with + | None -> print_endline "Invalid ROM file." + | Some c -> power_up c