33#include "data.h"
44#include "log.h"
55#include "macros.h"
6+ #include "mapper.h"
67#include "num.h"
78#include "stdinc.h"
89#include "string.h"
@@ -82,16 +83,6 @@ static void GameBoy_reset(GameBoy *const self)
8283
8384static void GameBoy_validate_rom (const GameBoy * const self )
8485{
85- BAIL_IF (self -> rom [RomHeader_CartridgeType ] != 0x00 ,
86- "Unsupported cartridge type (ctype: $%02X)" ,
87- self -> rom [RomHeader_CartridgeType ]);
88-
89- BAIL_IF (
90- !CartridgeType_has_ram (self -> rom [RomHeader_CartridgeType ]) &&
91- self -> rom [RomHeader_RamSize ] != 0 ,
92- "Cartridge type does not have RAM, but header indicates otherwise (ctype: $%02, RAM size: $%02X)" ,
93- self -> rom [RomHeader_CartridgeType ], self -> rom [RomHeader_RamSize ]);
94-
9586 BAIL_IF (
9687 self -> rom_len != 0x8000 * ((size_t )1 << self -> rom [RomHeader_RomSize ]),
9788 "Actual ROM size does not match header-specified size. (specified: $%02X, was: $%02X)" ,
@@ -137,9 +128,11 @@ GameBoy GameBoy_new(const u8 *const boot_rom)
137128void GameBoy_destroy (GameBoy * const self )
138129{
139130 free (self -> rom );
140-
141131 self -> rom = nullptr ;
142132 self -> rom_len = 0 ;
133+
134+ Mapper_destroy (self -> mapper );
135+ self -> mapper = nullptr ;
143136}
144137
145138void GameBoy_log_cartridge_info (const GameBoy * const self )
@@ -166,19 +159,22 @@ void GameBoy_load_rom(GameBoy *const self, const u8 *const rom,
166159 free (self -> rom );
167160
168161 self -> rom = malloc (rom_len * sizeof (self -> rom [0 ]));
169- BAIL_IF (self -> rom == nullptr , "Could not allocate memory for new ROM" );
162+ BAIL_IF_NULL (self -> rom );
170163
171164 memcpy (self -> rom , rom , rom_len * sizeof (self -> rom [0 ]));
172165 self -> rom_len = rom_len ;
173166
174167 GameBoy_validate_rom (self );
168+
169+ Mapper_destroy (self -> mapper );
170+ self -> mapper = Mapper_from_rom (self -> rom , self -> rom_len );
171+
175172 GameBoy_reset (self );
176173
177174 if (!self -> boot_rom_exists )
178175 GameBoy_simulate_boot (self );
179176}
180177
181- // NOLINTNEXTLINE
182178u8 GameBoy_read_io (const GameBoy * const self , const u16 addr )
183179{
184180 if (addr == 0xFF00 ) // FF00 (joypad input)
@@ -271,15 +267,15 @@ u8 GameBoy_read_mem(const void *const ctx, const u16 addr)
271267 if (self -> rom == nullptr )
272268 BAIL ("Tried to read non-existing ROM" );
273269
274- // 0000-7FFF (ROM bank )
275- return self -> rom [ addr ] ;
270+ // 0000-8FFF (from cartridge )
271+ return Mapper_read ( self -> mapper , self -> rom , self -> rom_len , addr ) ;
276272 }
277273
278274 if (addr <= 0x9FFF ) // 8000-9FFF (VRAM)
279275 return self -> vram [addr - 0x8000 ];
280276
281- if (addr <= 0xBFFF ) // A000-BFFF (External RAM )
282- BAIL ( "TODO: GameBoy_read_mem (addr = $%04X)" , addr );
277+ if (addr <= 0xBFFF ) // A000-BFFF (from cartridge )
278+ return Mapper_read ( self -> mapper , self -> rom , self -> rom_len , addr );
283279
284280 if (addr <= 0xDFFF ) // C000-DFFF (WRAM)
285281 return self -> ram [addr - 0xC000 ];
@@ -310,7 +306,6 @@ u16 GameBoy_read_mem_u16(GameBoy *const self, u16 addr)
310306 return concat_u16 (hi , lo );
311307}
312308
313- // NOLINTNEXTLINE
314309void GameBoy_write_io (GameBoy * const self , const u16 addr , const u8 value )
315310{
316311 if (addr == 0xFF00 ) {
@@ -368,12 +363,12 @@ void GameBoy_write_io(GameBoy *const self, const u16 addr, const u8 value)
368363 case 0xFF47 : self -> bgp = value ; break ;
369364 case 0xFF48 : self -> obp0 = value ; break ;
370365 case 0xFF49 : self -> obp1 = value ; break ;
371- default : BAIL ("Unexpected I/O LCD write (addr = $%04X, value = $%02X)" , addr , value );
366+ default : log_warn ("Unexpected I/O LCD write (addr = $%04X, value = $%02X)" , addr , value );
372367 }
373368 // clang-format on
374369 } else if (addr == 0xFF4F ) {
375370 // FF4F
376- BAIL ("I/O VRAM bank select write ($%04X, $%02X)" , addr , value );
371+ log_warn ("I/O VRAM bank select write ($%04X, $%02X)" , addr , value );
377372 } else if (addr == 0xFF50 ) {
378373 // FF50 (boot ROM disable)
379374 if (value != 0 )
@@ -384,10 +379,9 @@ void GameBoy_write_io(GameBoy *const self, const u16 addr, const u8 value)
384379 // FF68-FF6B (LCD color palettes, CGB-only)
385380 } else if (addr == 0xFF70 ) {
386381 // FF70 (WRAM bank select, CGB-only)
387- } else if (addr == 0xFF7F ) {
388- // Tetris tries to write here. Probably a no-op.
389382 } else {
390- BAIL ("Unexpected I/O write (addr = $%04X, value = $%02X)" , addr , value );
383+ log_warn ("Unexpected I/O write (addr = $%04X, value = $%02X)" , addr ,
384+ value );
391385 }
392386}
393387
@@ -399,14 +393,13 @@ void GameBoy_write_mem(void *const ctx, const u16 addr, const u8 value)
399393
400394 if (addr <= 0x7FFF ) {
401395 // 0000-7FFF (ROM bank)
402- log_debug ("TODO: GameBoy_write_mem ROM (addr = $%04X, $%02X)" , addr ,
403- value );
396+ Mapper_write (self -> mapper , addr , value );
404397 } else if (addr <= 0x9FFF ) {
405398 // 8000-9FFF (VRAM)
406399 self -> vram [addr - 0x8000 ] = value ;
407400 } else if (addr <= 0xBFFF ) {
408401 // A000-BFFF (External RAM)
409- BAIL ( "TODO: GameBoy_write_mem ERAM (addr = $%04X, $%02X)" , addr , value );
402+ Mapper_write ( self -> mapper , addr , value );
410403 } else if (addr <= 0xDFFF ) {
411404 // C000-DFFF (WRAM)
412405 self -> ram [addr - 0xC000 ] = value ;
0 commit comments