From 09f1ffb488426831ca6cd9621cdf9673a4ee755e Mon Sep 17 00:00:00 2001 From: Fabien Freling Date: Sat, 21 Feb 2015 17:11:18 +0100 Subject: [PATCH] Read Nintendo checksum in cartridge header. This first commit parses the ROM to extract the Nintendo Logo and display it on stdout. --- .gitignore | 7 +++++++ LICENSE | 24 ++++++++++++++++++++++++ Makefile | 2 ++ _tags | 1 + src/cartridge.ml | 28 ++++++++++++++++++++++++++++ src/hexa.ml | 14 ++++++++++++++ src/oboy.ml | 4 ++++ 7 files changed, 80 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 _tags create mode 100644 src/cartridge.ml create mode 100644 src/hexa.ml create mode 100644 src/oboy.ml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..184af6d --- /dev/null +++ b/.gitignore @@ -0,0 +1,7 @@ +# vim +.*.swp + +# OCaml +_build +*.byte +*.native diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..276e070 --- /dev/null +++ b/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2015, Fabien Freling +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..de36db5 --- /dev/null +++ b/Makefile @@ -0,0 +1,2 @@ +all: + ocamlbuild -use-ocamlfind -I src oboy.byte diff --git a/_tags b/_tags new file mode 100644 index 0000000..1f1927d --- /dev/null +++ b/_tags @@ -0,0 +1 @@ +true: package(unix) diff --git a/src/cartridge.ml b/src/cartridge.ml new file mode 100644 index 0000000..db15484 --- /dev/null +++ b/src/cartridge.ml @@ -0,0 +1,28 @@ +open Unix +open Printf + +(** http://bgb.bircd.org/pandocs.htm#thecartridgeheader *) + +type memory_bank_controller = + | ROM_ONLY + | MBC1 + +type t = { + nintendo_logo : bytes; + title : string; + mem_type : memory_bank_controller; + rom_size : int; + ram_size : int; + header_checksum : bytes; + global_checksum : bytes; +} + +let read_cartridge file = + print_endline file; + let fd = openfile file [Unix.O_RDONLY] 0o644 in + let n_logo = Bytes.create 48 in + let _ = lseek fd 0x0104 SEEK_SET in + let _ = read fd n_logo 0 48 in + print_endline "Nintendo logo:"; + Hexa.print_bytes n_logo ~width:16; + Unix.close fd diff --git a/src/hexa.ml b/src/hexa.ml new file mode 100644 index 0000000..e176b6d --- /dev/null +++ b/src/hexa.ml @@ -0,0 +1,14 @@ +open Printf + +let print_bytes b ?(width=8) = + let l = Bytes.length b in + let rec print_line b start last = + if start < last then + let max = min (start + width - 1) last in + for i = start to max do + printf "%02X " (Bytes.get b i |> int_of_char) + done; + print_newline (); + print_line b (start + width) last + in + print_line b 0 l diff --git a/src/oboy.ml b/src/oboy.ml new file mode 100644 index 0000000..54cb30e --- /dev/null +++ b/src/oboy.ml @@ -0,0 +1,4 @@ +let () = + if Array.length Sys.argv < 2 + then print_endline "Please specify a ROM." + else Cartridge.read_cartridge Sys.argv.(1)