92 lines
2.4 KiB
C++
92 lines
2.4 KiB
C++
#include "mem.h"
|
|
#include "sm83.h"
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
#include "mbc_none.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;
|
|
};
|
|
}
|
|
|
|
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++;
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|