#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 { void* data; int (*init)(struct nes_mapper_t*, struct nes_cart_t* cart); void (*reset)(struct nes_mapper_t*); void (*done)(struct nes_mapper_t*); uint8_t (*read)(struct nes_mapper_t*, uint16_t addr); void (*write)(struct nes_mapper_t*, uint16_t addr, uint8_t val); uint8_t* (*chr_addr)(struct nes_mapper_t*, uint16_t addr); uint8_t* (*vram_addr)(struct nes_mapper_t*, uint16_t addr); void (*chr_write)(struct nes_mapper_t*, uint16_t addr, uint8_t val); void (*scanline)(struct nes_mapper_t*); void (*irq_callback)(void*, int); void* irq_arg; } nes_mapper; static inline int 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) { map->reset(map); } static inline void nes_map_done(nes_mapper* map) { map->done(map); } 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, uint16_t addr) { return map->read(map, addr); } static inline void nes_map_write(nes_mapper* map, uint16_t addr, uint8_t val) { map->write(map, addr, val); } static inline uint8_t* nes_map_chr_addr(nes_mapper* map, uint16_t addr) { return map->chr_addr(map, addr); } static inline uint8_t nes_chr_read(nes_mapper* map, uint16_t addr) { return *(nes_map_chr_addr(map, addr)); } static inline void nes_chr_write(nes_mapper* map, uint16_t addr, uint8_t val) { return map->chr_write(map, addr, val); } static inline uint8_t* nes_map_vram_addr(nes_mapper* map, uint16_t addr) { return map->vram_addr(map, addr & 0x1FFFU); } static inline uint8_t nes_vram_read(nes_mapper* map, uint16_t addr) { return *(nes_map_vram_addr(map, addr)); } static inline void nes_vram_write(nes_mapper* map, uint16_t addr, uint8_t val) { *(nes_map_vram_addr(map, addr)) = val; } extern nes_mapper* nes_mappers[]; #endif