diff --git a/src/cartridge.ml b/src/cartridge.ml index a3ec9ef..89aa89d 100644 --- a/src/cartridge.ml +++ b/src/cartridge.ml @@ -3,6 +3,8 @@ open Printf (** http://bgb.bircd.org/pandocs.htm#thecartridgeheader *) +exception Read_error + type memory_bank_controller = | ROM_ONLY | MBC1 @@ -10,9 +12,9 @@ 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; +(* ram_size : int; header_checksum : bytes; global_checksum : bytes; *) } @@ -25,7 +27,22 @@ let check_nintendo_logo cartridge = \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 +(** ROM size is expressed in KB *) +let get_ROM_size b = + match Bytes.get b 0 |> int_of_char with + | 0x00 -> 32 (* no ROM banking *) + | 0x01 -> 64 (* 4 banks *) + | 0x02 -> 128 (* 8 banks *) + | 0x03 -> 256 (* 16 banks *) + | 0x04 -> 512 (* 32 banks *) + | 0x05 -> 1000 (* 64 banks - only 63 banks used by MBC1 *) + | 0x06 -> 2000 (* 128 banks - only 125 banks used by MBC1 *) + | 0x07 -> 4000 (* 256 banks *) + | 0x52 -> 1100 (* 72 banks *) + | 0x53 -> 1200 (* 80 banks *) + | 0x54 -> 1500 (* 96 banks *) + | _ -> raise Read_error + let read_cartridge file = try @@ -47,8 +64,14 @@ let read_cartridge file = then raise Read_error; let title = Bytes.to_string title_b in + let size_b = Bytes.create 1 in + let _ = lseek fd 4 SEEK_CUR in + if (read fd size_b 0 1) != 1 + then raise Read_error; + let rom_size = get_ROM_size size_b in + Unix.close fd; - Some { nintendo_logo; title } + Some { nintendo_logo; title; rom_size } with Read_error -> Unix.close fd; None diff --git a/src/oboy.ml b/src/oboy.ml index a780a63..9526883 100644 --- a/src/oboy.ml +++ b/src/oboy.ml @@ -1,9 +1,15 @@ -(** Power up sequence *) +open Printf + +(** 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." + else + print_endline "Valid ROM."; + printf "ROM size: %iKB\n" cartridge.rom_size + let () = if Array.length Sys.argv < 2