2015-03-22 16:57:03 +01:00
|
|
|
open Bytes
|
2015-03-23 22:38:11 +01:00
|
|
|
open Printf
|
2015-03-22 16:57:03 +01:00
|
|
|
|
2015-03-22 13:56:32 +01:00
|
|
|
(** http://bgb.bircd.org/pandocs.htm#memorymap
|
|
|
|
http://imrannazar.com/GameBoy-Emulation-in-JavaScript:-Memory *)
|
|
|
|
|
|
|
|
type map = {
|
|
|
|
rom_bank_00 : bytes; (* cartridge, 16KB *)
|
|
|
|
rom_bank_01 : bytes; (* additional bank, 16KB *)
|
|
|
|
vram : bytes; (* Video RAM, 8KB *)
|
2015-03-22 16:57:03 +01:00
|
|
|
io : bytes; (* I/O ports *)
|
2015-03-23 12:50:02 +01:00
|
|
|
hram : bytes; (* High RAM, 8KB *)
|
|
|
|
interrupt : bytes; (* Interrupt Enable Register *)
|
2015-03-22 13:56:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
let init (cartridge: Cartridge.t) =
|
|
|
|
{
|
|
|
|
rom_bank_00 = sub cartridge.full_rom 0 0x4000;
|
|
|
|
rom_bank_01 = create 0x4000;
|
|
|
|
vram = create 0x2000;
|
2015-03-22 16:57:03 +01:00
|
|
|
io = create 0x0080;
|
2015-03-23 12:50:02 +01:00
|
|
|
hram = create 0x2000;
|
|
|
|
interrupt = create 1
|
2015-03-22 13:56:32 +01:00
|
|
|
}
|
2015-03-22 16:57:03 +01:00
|
|
|
|
|
|
|
let get_mem_bank mem addr =
|
|
|
|
match addr with
|
|
|
|
| x when x < 0x4000 -> mem.rom_bank_00, x
|
|
|
|
| x when x < 0x8000 -> mem.rom_bank_01, (x - 0x4000)
|
|
|
|
| x when x < 0xA000 -> mem.vram, (x - 0x8000)
|
|
|
|
| x when x < 0xFF00 -> failwith "Unimplemented memory range."
|
|
|
|
| x when x < 0xFF80 -> mem.io, x - 0xFF00
|
2015-03-23 12:50:02 +01:00
|
|
|
| x when x < 0xFFFF -> mem.hram, x - 0xFF80
|
|
|
|
| 0xFFFF -> mem.interrupt, 0
|
2015-03-23 22:38:11 +01:00
|
|
|
| x -> eprintf "Memory access 0x%08X\n" x;
|
|
|
|
failwith "Invalid memory range."
|
2015-03-22 16:57:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
let get mem addr =
|
|
|
|
let m, x = get_mem_bank mem addr in
|
|
|
|
get m x
|
|
|
|
|
|
|
|
let set mem addr c =
|
|
|
|
let m, x = get_mem_bank mem addr in
|
|
|
|
set m x c
|