snes9x/apu/bapu/smp/core.cpp

143 lines
3.4 KiB
C++

void SMP::tick() {
timer0.tick();
timer1.tick();
timer2.tick();
#ifndef SNES9X
clock += cycle_step_cpu;
dsp.clock -= 24;
synchronize_dsp();
#else
clock++;
dsp.clock++;
#endif
}
void SMP::tick(unsigned clocks) {
timer0.tick(clocks);
timer1.tick(clocks);
timer2.tick(clocks);
clock += clocks;
dsp.clock += clocks;
}
void SMP::op_io() {
#if defined(CYCLE_ACCURATE)
tick();
#endif
}
void SMP::op_io(unsigned clocks) {
tick(clocks);
}
uint8 SMP::op_read(uint16 addr) {
#if defined(CYCLE_ACCURATE)
tick();
#endif
if((addr & 0xfff0) == 0x00f0) return mmio_read(addr);
if(addr >= 0xffc0 && status.iplrom_enable) return iplrom[addr & 0x3f];
return apuram[addr];
}
void SMP::op_write(uint16 addr, uint8 data) {
#if defined(CYCLE_ACCURATE)
tick();
#endif
if((addr & 0xfff0) == 0x00f0) mmio_write(addr, data);
apuram[addr] = data; //all writes go to RAM, even MMIO writes
}
void SMP::op_step() {
#define op_readpc() op_read(regs.pc++)
#define op_readdp(addr) op_read((regs.p.p << 8) + addr)
#define op_writedp(addr, data) op_write((regs.p.p << 8) + addr, data)
#define op_readaddr(addr) op_read(addr)
#define op_writeaddr(addr, data) op_write(addr, data)
#define op_readstack() op_read(0x0100 | ++regs.sp)
#define op_writestack(data) op_write(0x0100 | regs.sp--, data)
#if defined(CYCLE_ACCURATE)
#if defined(PSEUDO_CYCLE)
if(opcode_cycle == 0)
opcode_number = op_readpc();
switch(opcode_number) {
#include "core/oppseudo_misc.cpp"
#include "core/oppseudo_mov.cpp"
#include "core/oppseudo_pc.cpp"
#include "core/oppseudo_read.cpp"
#include "core/oppseudo_rmw.cpp"
}
#else
if(opcode_cycle == 0) {
opcode_number = op_readpc();
opcode_cycle++;
} else switch(opcode_number) {
#include "core/opcycle_misc.cpp"
#include "core/opcycle_mov.cpp"
#include "core/opcycle_pc.cpp"
#include "core/opcycle_read.cpp"
#include "core/opcycle_rmw.cpp"
}
#endif // defined(PSEUDO_CYCLE)
#else
unsigned opcode = op_readpc();
switch(opcode) {
#include "core/op_misc.cpp"
#include "core/op_mov.cpp"
#include "core/op_pc.cpp"
#include "core/op_read.cpp"
#include "core/op_rmw.cpp"
}
//TODO: untaken branches should consume less cycles
timer0.tick(cycle_count_table[opcode]);
timer1.tick(cycle_count_table[opcode]);
timer2.tick(cycle_count_table[opcode]);
#ifndef SNES9X
clock += cycle_table_cpu[opcode];
dsp.clock -= cycle_table_dsp[opcode];
synchronize_dsp();
#else
clock += cycle_count_table[opcode];
dsp.clock += cycle_count_table[opcode];
#endif
#endif // defined(CYCLE_ACCURATE)
}
const unsigned SMP::cycle_count_table[256] = {
#define c 12
//0 1 2 3 4 5 6 7 8 9 A B C D E F
2,8,4,7, 3,4,3,6, 2,6,5,4, 5,4,6,8, //0
4,8,4,7, 4,5,5,6, 5,5,6,5, 2,2,4,6, //1
2,8,4,7, 3,4,3,6, 2,6,5,4, 5,4,7,4, //2
4,8,4,7, 4,5,5,6, 5,5,6,5, 2,2,3,8, //3
2,8,4,7, 3,4,3,6, 2,6,4,4, 5,4,6,6, //4
4,8,4,7, 4,5,5,6, 5,5,4,5, 2,2,4,3, //5
2,8,4,7, 3,4,3,6, 2,6,4,4, 5,4,7,5, //6
4,8,4,7, 4,5,5,6, 5,5,5,5, 2,2,3,6, //7
2,8,4,7, 3,4,3,6, 2,6,5,4, 5,2,4,5, //8
4,8,4,7, 4,5,5,6, 5,5,5,5, 2,2,c,5, //9
3,8,4,7, 3,4,3,6, 2,6,4,4, 5,2,4,4, //A
4,8,4,7, 4,5,5,6, 5,5,5,5, 2,2,3,4, //B
3,8,4,7, 4,5,4,7, 2,5,6,4, 5,2,4,9, //C
4,8,4,7, 5,6,6,7, 4,5,5,5, 2,2,8,3, //D
2,8,4,7, 3,4,3,6, 2,4,5,3, 4,3,4,1, //E
4,8,4,7, 4,5,5,6, 3,4,5,4, 2,2,6,1, //F
#undef c
};