Add basic support for MBC.
This commit is contained in:
		
							parent
							
								
									0f83810230
								
							
						
					
					
						commit
						02e2ef3caf
					
				
					 3 changed files with 30 additions and 6 deletions
				
			
		| 
						 | 
					@ -9,7 +9,7 @@ type t = {
 | 
				
			||||||
  full_rom : bytes;
 | 
					  full_rom : bytes;
 | 
				
			||||||
  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;
 | 
				
			||||||
| 
						 | 
					@ -24,6 +24,16 @@ let check_nintendo_logo cartridge =
 | 
				
			||||||
  \xBB\xBB\x67\x63\x6E\x0E\xEC\xCC\xDD\xDC\x99\x9F\xBB\xB9\x33\x3E" in
 | 
					  \xBB\xBB\x67\x63\x6E\x0E\xEC\xCC\xDD\xDC\x99\x9F\xBB\xB9\x33\x3E" in
 | 
				
			||||||
  (Bytes.compare cartridge.nintendo_logo reference) == 0
 | 
					  (Bytes.compare cartridge.nintendo_logo reference) == 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let get_cartridge_type = function
 | 
				
			||||||
 | 
					  | 0x00 -> ROM_ONLY
 | 
				
			||||||
 | 
					  | 0x01 -> MBC1
 | 
				
			||||||
 | 
					  | x -> Printf.printf "%02X\n" x; failwith "Invalid cartridge type."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let mem_type_name = function
 | 
				
			||||||
 | 
					  | ROM_ONLY -> "ROM_ONLY"
 | 
				
			||||||
 | 
					  | MBC1 -> "MBC1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
(** ROM size is expressed in KB *)
 | 
					(** ROM size is expressed in KB *)
 | 
				
			||||||
let get_ROM_size = function
 | 
					let get_ROM_size = function
 | 
				
			||||||
  | 0x00 -> 32 (* no ROM banking *)
 | 
					  | 0x00 -> 32 (* no ROM banking *)
 | 
				
			||||||
| 
						 | 
					@ -69,6 +79,10 @@ let read_cartridge file =
 | 
				
			||||||
      let title_b = Bytes.sub full_rom title_offset title_size in
 | 
					      let title_b = Bytes.sub full_rom title_offset title_size in
 | 
				
			||||||
      let title = Bytes.to_string title_b in
 | 
					      let title = Bytes.to_string title_b in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      (* Cartridge type - memory bank *)
 | 
				
			||||||
 | 
					      let mem_type_code = Bytes.get full_rom 0x0147 |> int_of_char in
 | 
				
			||||||
 | 
					      let mem_type = get_cartridge_type mem_type_code in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      (* ROM size *)
 | 
					      (* ROM size *)
 | 
				
			||||||
      let rom_size_code = Bytes.get full_rom 0x0148 |> int_of_char in
 | 
					      let rom_size_code = Bytes.get full_rom 0x0148 |> int_of_char in
 | 
				
			||||||
      let rom_size = get_ROM_size rom_size_code in
 | 
					      let rom_size = get_ROM_size rom_size_code in
 | 
				
			||||||
| 
						 | 
					@ -77,9 +91,17 @@ let read_cartridge file =
 | 
				
			||||||
      let ram_size_code = Bytes.get full_rom 0x0149 |> int_of_char in
 | 
					      let ram_size_code = Bytes.get full_rom 0x0149 |> int_of_char in
 | 
				
			||||||
      let ram_size = get_RAM_size ram_size_code in
 | 
					      let ram_size = get_RAM_size ram_size_code in
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      Some { full_rom; nintendo_logo; title; rom_size; ram_size }
 | 
					      Some { full_rom; nintendo_logo; title; mem_type; rom_size; ram_size }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  with
 | 
					  with
 | 
				
			||||||
  | Sys_error msg
 | 
					  | Sys_error msg
 | 
				
			||||||
  | Invalid_argument msg (* This is triggered by Bytes.sub *)
 | 
					  | Invalid_argument msg (* This is triggered by Bytes.sub *)
 | 
				
			||||||
  | Failure msg -> prerr_endline msg; None
 | 
					  | Failure msg -> prerr_endline msg; None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					let print_info cartridge =
 | 
				
			||||||
 | 
					  let open Printf in
 | 
				
			||||||
 | 
					  printf "Title: %s\n" cartridge.title;
 | 
				
			||||||
 | 
					  printf "Mem. type: %s\n" (cartridge.mem_type |> mem_type_name);
 | 
				
			||||||
 | 
					  printf "ROM size: %iKB\n" cartridge.rom_size;
 | 
				
			||||||
 | 
					  printf "RAM size: %iKB\n" cartridge.ram_size
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -99,7 +99,11 @@ let run cpu (cartridge: Cartridge.t) =
 | 
				
			||||||
              printf "  JP \t0x%04X\n" addr;
 | 
					              printf "  JP \t0x%04X\n" addr;
 | 
				
			||||||
              cpu.reg.pc <- addr; inc_cycles cpu 16
 | 
					              cpu.reg.pc <- addr; inc_cycles cpu 16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  | '\xE0' -> printf "  LDH \t(0x%02X), A\n" (int_of_char n);
 | 
					  | '\xE0' -> printf "  LDH \t(0xFF%02X), A\n" (int_of_char n);
 | 
				
			||||||
 | 
					              (* fixme *)
 | 
				
			||||||
 | 
					              inc_pc cpu 2; inc_cycles cpu 12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  | '\xF0' -> printf "  LDH \tA, (0xFF%02X)\n" (int_of_char n);
 | 
				
			||||||
              (* fixme *)
 | 
					              (* fixme *)
 | 
				
			||||||
              inc_pc cpu 2; inc_cycles cpu 12
 | 
					              inc_pc cpu 2; inc_cycles cpu 12
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,9 +12,7 @@ let power_up cartridge =
 | 
				
			||||||
  then print_endline "Invalid ROM."
 | 
					  then print_endline "Invalid ROM."
 | 
				
			||||||
  else
 | 
					  else
 | 
				
			||||||
    print_endline "Valid ROM.";
 | 
					    print_endline "Valid ROM.";
 | 
				
			||||||
    printf "Title: %s\n" cartridge.title;
 | 
					    Cartridge.print_info cartridge;
 | 
				
			||||||
    printf "ROM size: %iKB\n" cartridge.rom_size;
 | 
					 | 
				
			||||||
    printf "RAM size: %iKB\n" cartridge.ram_size;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let cpu = Cpu.init_cpu in
 | 
					    let cpu = Cpu.init_cpu in
 | 
				
			||||||
    run cpu cartridge
 | 
					    run cpu cartridge
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue