#include "mem.h" #include "sm83.h" #include #include #include "mbc_none.h" #include "mbc1.h" namespace mem { void (*reset)(void); uint8_t(*readMem)(uint16_t); void (*writeMem)(uint16_t, uint8_t); uint8_t(*getTag)(uint16_t); void (*setTag)(uint16_t, uint8_t); void (*saveState)(FILE*); void (*loadState)(FILE*); uint8_t*(*rawPtr)(uint16_t); char *title = nullptr; uint16_t dma_address = 0; uint8_t dma_pos = 160; uint16_t dma_dots = 0; uint16_t div_counter = 0; uint16_t timer_counter = 0; void init(uint8_t* rom, const int size) { //if (memory) free(memory); //memory = (uint8_t*)malloc(size); title = (char*)&rom[0x134]; uint8_t mapper_type = rom[0x147]; uint32_t rom_size = 32768 * (1 << rom[0x148]); int sizes[] = { 0, 0, 8, 32, 128, 64}; uint32_t ram_size = sizes[rom[0x149]] * 1024; switch (mapper_type) { case 0x00: mbc_none::init(rom, rom_size, ram_size); break; case 0x01: case 0x02: case 0x03: mbc1::init(rom, rom_size, ram_size); break; }; } void init_dma_transfer(uint8_t source) { dma_address = source << 8; dma_pos = 0; dma_dots = 0; } uint16_t timer_frequencies[4] { 256*4, 4*4, 16*4, 64*4 }; void update_mapped(const uint32_t dt) { // DIV Divider register (0xFF04) (val com a timer bàsic) div_counter += dt; if (div_counter>=256) { div_counter -= 256; uint8_t *div = mem::rawPtr(0xff04); *div = *div + 1; } // Timer uint8_t *t_regs = mem::rawPtr(0xff05); if (*(t_regs+2)&0x4) { // if bit 3 of mem(0xff07) is 1, timer enabled uint16_t freq = timer_frequencies[*(t_regs+2)&0x03]; timer_counter += dt; if (timer_counter>=freq) { timer_counter -= freq; if ((*t_regs)<255) (*t_regs)++; else { *t_regs = *(t_regs+1); sm83::interrupt(INTERRUPT_TIMER); } } } // OAM DMA if (dma_pos<160) { dma_dots += dt; while (dma_dots >= 4 && dma_pos<160) { dma_dots -= 4; mem::writeMem(0xfe00|dma_pos, mem::readMem(dma_address|dma_pos)); dma_pos++; } } } }