#include #include #include #include #include #include "../types.h" #include "cart.h" #include "snes.h" static uint8_t cart_readLorom(Cart* cart, uint8_t bank, uint16_t adr); static void cart_writeLorom(Cart* cart, uint8_t bank, uint16_t adr, uint8_t val); static uint8_t cart_readHirom(Cart* cart, uint8_t bank, uint16_t adr); static void cart_writeHirom(Cart* cart, uint8_t bank, uint16_t adr, uint8_t val); Cart* cart_init(Snes* snes) { Cart* cart = malloc(sizeof(Cart)); cart->snes = snes; cart->type = 0; cart->rom = NULL; cart->romSize = 0; cart->ram = NULL; cart->ramSize = 0; return cart; } void cart_free(Cart* cart) { free(cart); } void cart_reset(Cart* cart) { //if(cart->ramSize > 0 && cart->ram != NULL) memset(cart->ram, 0, cart->ramSize); // for now } void cart_saveload(Cart *cart, SaveLoadFunc *func, void *ctx) { func(ctx, cart->ram, cart->ramSize); } void cart_load(Cart* cart, int type, uint8_t* rom, int romSize, int ramSize) { cart->type = type; if(cart->rom != NULL) free(cart->rom); if(cart->ram != NULL) free(cart->ram); cart->rom = malloc(romSize); cart->romSize = romSize; if(ramSize > 0) { cart->ram = malloc(ramSize); memset(cart->ram, 0, ramSize); } else { cart->ram = NULL; } cart->ramSize = ramSize; memcpy(cart->rom, rom, romSize); } uint8_t cart_read(Cart* cart, uint8_t bank, uint16_t adr) { switch(cart->type) { case 0: assert(0); return cart->snes->openBus; case 1: return cart_readLorom(cart, bank, adr); case 2: return cart_readHirom(cart, bank, adr); } assert(0); return cart->snes->openBus; } void cart_write(Cart* cart, uint8_t bank, uint16_t adr, uint8_t val) { switch(cart->type) { case 0: break; case 1: cart_writeLorom(cart, bank, adr, val); break; case 2: cart_writeHirom(cart, bank, adr, val); break; } } void DumpCpuHistory(); static uint8_t cart_readLorom(Cart* cart, uint8_t bank, uint16_t adr) { if(((bank >= 0x70 && bank < 0x7e) || bank >= 0xf0) && adr < 0x8000 && cart->ramSize > 0) { // banks 70-7e and f0-ff, adr 0000-7fff return cart->ram[(((bank & 0xf) << 15) | adr) & (cart->ramSize - 1)]; } bank &= 0x7f; if(adr >= 0x8000 || bank >= 0x40) { // adr 8000-ffff in all banks or all addresses in banks 40-7f and c0-ff return cart->rom[((bank << 15) | (adr & 0x7fff)) & (cart->romSize - 1)]; } printf("While trying to read from 0x%x\n", bank << 16 | adr); DumpCpuHistory(); Die("The game crashed in cart_readLorom"); return cart->snes->openBus; } static void cart_writeLorom(Cart* cart, uint8_t bank, uint16_t adr, uint8_t val) { if(((bank >= 0x70 && bank < 0x7e) || bank > 0xf0) && adr < 0x8000 && cart->ramSize > 0) { // banks 70-7e and f0-ff, adr 0000-7fff cart->ram[(((bank & 0xf) << 15) | adr) & (cart->ramSize - 1)] = val; } } static uint8_t cart_readHirom(Cart* cart, uint8_t bank, uint16_t adr) { bank &= 0x7f; if(bank < 0x40 && adr >= 0x6000 && adr < 0x8000 && cart->ramSize > 0) { // banks 00-3f and 80-bf, adr 6000-7fff return cart->ram[(((bank & 0x3f) << 13) | (adr & 0x1fff)) & (cart->ramSize - 1)]; } if(adr >= 0x8000 || bank >= 0x40) { // adr 8000-ffff in all banks or all addresses in banks 40-7f and c0-ff return cart->rom[(((bank & 0x3f) << 16) | adr) & (cart->romSize - 1)]; } assert(0); return cart->snes->openBus; } static void cart_writeHirom(Cart* cart, uint8_t bank, uint16_t adr, uint8_t val) { bank &= 0x7f; if(bank < 0x40 && adr >= 0x6000 && adr < 0x8000 && cart->ramSize > 0) { // banks 00-3f and 80-bf, adr 6000-7fff cart->ram[(((bank & 0x3f) << 13) | (adr & 0x1fff)) & (cart->ramSize - 1)] = val; } }