#ifndef NES_MAPPER_H_ #define NES_MAPPER_H_ #include #ifdef DEBUG_MAPPER #define MAP_LOG(fmt, ...) printf("MAP: " fmt "\n" __VA_OPT__(,) __VA_ARGS__) #else #define MAP_LOG(...) do {} while (0) #endif struct nes_cart_t; typedef struct nes_mapper_t { const char* name; void* (*init)(struct nes_mapper_t*, struct nes_cart_t* cart); void (*reset)(void*); void (*done)(void*); uint8_t (*read)(void*, uint16_t addr); void (*write)(void*, uint16_t addr, uint8_t val); uint8_t* (*chr_addr)(void*, uint16_t addr); uint8_t* (*vram_addr)(void*, uint16_t addr); void (*chr_write)(void*, uint16_t addr, uint8_t val); void (*scanline)(void*); void (*irq_callback)(void* irq_arg, int); void* irq_arg; void* (*sram)(void*); int (*sram_size)(void*); int (*state_size)(const void* map); int (*state_read)(void* map, const void* data, int len); int (*state_write)(const void* map, void* data, int len); } nes_mapper; static inline void* nes_map_init(nes_mapper* map, struct nes_cart_t* cart) { return map->init(map, cart); } static inline void nes_map_reset(nes_mapper* map, void* data) { map->reset(data); } static inline void nes_map_done(nes_mapper* map, void* data) { map->done(data); } static inline void nes_map_set_irq(nes_mapper* map, void(*callback)(void*, int), void* arg) { map->irq_callback = callback; map->irq_arg = arg; } static inline void nes_map_trigger_irq(nes_mapper* map, int active) { map->irq_callback(map->irq_arg, active); } static inline uint8_t nes_map_read(nes_mapper* map, void* data, uint16_t addr) { return map->read(data, addr); } static inline void nes_map_write(nes_mapper* map, void* data, uint16_t addr, uint8_t val) { map->write(data, addr, val); } static inline uint8_t* nes_map_chr_addr(nes_mapper* map, void* data, uint16_t addr) { return map->chr_addr(data, addr); } static inline uint8_t nes_chr_read(nes_mapper* map, void* data, uint16_t addr) { return *(nes_map_chr_addr(map, data, addr)); } static inline void nes_chr_write(nes_mapper* map, void* data, uint16_t addr, uint8_t val) { return map->chr_write(data, addr, val); } static inline uint8_t* nes_map_vram_addr(nes_mapper* map, void* data, uint16_t addr) { return map->vram_addr(data, addr & 0x1FFFU); } static inline uint8_t nes_vram_read(nes_mapper* map, void* data, uint16_t addr) { return *(nes_map_vram_addr(map, data, addr)); } static inline void nes_vram_write(nes_mapper* map, void* data, uint16_t addr, uint8_t val) { *(nes_map_vram_addr(map, data, addr)) = val; } extern nes_mapper* nes_mappers[]; #endif