Update to bsnes v010 release.

bsnes now supports SPC700 emulation (no DSP or sound support, however), and has greatly improved compatibility. It also now contains a keyboard-only joypad configuration tool.
This commit is contained in:
byuu 2005-08-03 21:22:42 +00:00
parent 402c146a53
commit 970dcea0ac
150 changed files with 16980 additions and 10971 deletions

View File

@ -1,5 +1,8 @@
#[bsnes v0.009 configuration file]
#[apu enable]
apu.enabled = true
#[video mode]
# 0: 256x224w
# 1: 512x448w
@ -34,3 +37,21 @@ gui.show_fps = true
#[wait for vertical retrace]
video.vblank = false
#[joypad 1 configuration]
# Key numbers are standard windows VK_* keys.
# Unfortunately, I don't have a table of common
# key mappings to list here... use GUI joypad
# configuration utility to edit these.
input.joypad1.up = 0x26
input.joypad1.down = 0x28
input.joypad1.left = 0x25
input.joypad1.right = 0x27
input.joypad1.a = 0x58
input.joypad1.b = 0x5a
input.joypad1.x = 0x53
input.joypad1.y = 0x41
input.joypad1.l = 0x44
input.joypad1.r = 0x43
input.joypad1.select = 0x10
input.joypad1.start = 0x0d

BIN
bsnes.exe Normal file

Binary file not shown.

Binary file not shown.

View File

@ -1,10 +1,21 @@
bsnes Licensing Agreement:
bsnes License:
--------------
You are free to redistribute this software, and its source code; provided
there is no charge for the software, nor any charge for the medium used to
distribute the software. You are also free to use and modify the source code
as you desire for personal use only. No publically-released derivative works
of this source code are permitted without my permission. You must also abide
by the terms of any additional source code licenses contained within my code.
At present, this only includes the mode7 renderer, which was derived from the
snes9x mode7 renderer.
of this source code are permitted without my permission, though I will likely
grant you permission if you ask me. You must also abide by the terms of any
additional source code licenses contained within this program.
Simple DirectMedia Layer License:
---------------------------------
The Simple DirectMedia Layer (SDL for short) is a cross-platform library
designed to make it easy to write multi-media software, such as games and
emulators.
The Simple DirectMedia Layer library source code is available from:
http://www.libsdl.org/
This library is distributed under the terms of the GNU LGPL license:
http://www.gnu.org/copyleft/lesser.html

2
src/apu/apu.cpp Normal file
View File

@ -0,0 +1,2 @@
#include "../base.h"
#include "dapu.cpp"

28
src/apu/apu.h Normal file
View File

@ -0,0 +1,28 @@
#define _APU_IPLROM
#include "iplrom.h"
#include "apuregs.h"
class APU {
public:
APURegs regs;
enum {
FLAG_N = 0x80, FLAG_V = 0x40,
FLAG_P = 0x20, FLAG_B = 0x10,
FLAG_H = 0x08, FLAG_I = 0x04,
FLAG_Z = 0x02, FLAG_C = 0x01
};
virtual uint8 spcram_read (uint16 addr) = 0;
virtual void spcram_write(uint16 addr, uint8 value) = 0;
//$f4-$f7
virtual uint8 port_read (uint8 port) = 0;
virtual void port_write(uint8 port, uint8 value) = 0;
virtual void run() = 0;
virtual uint32 cycles_executed() = 0;
virtual void power() = 0;
virtual void reset() = 0;
void disassemble_opcode(char *output);
inline uint16 __relb(int8 offset, int op_len);
};

48
src/apu/apuregs.h Normal file
View File

@ -0,0 +1,48 @@
class APURegFlags {
private:
template <uint8 B> class bit {
public:
uint8 _b;
inline operator bool() { return (_b & B); }
inline bool operator = (bool i) { (i) ? _b |= B : _b &= ~B; return (_b & B); }
inline bool operator & (bool i) { if(i)_b &= ~B; return (_b & B); }
inline bool operator &= (bool i) { if(i)_b &= ~B; return (_b & B); }
inline bool operator | (bool i) { if(i)_b |= B; return (_b & B); }
inline bool operator |= (bool i) { if(i)_b |= B; return (_b & B); }
inline bool operator ^ (bool i) { if(i)_b ^= B; return (_b & B); }
inline bool operator ^= (bool i) { if(i)_b ^= B; return (_b & B); }
};
public:
union {
uint8 _b;
bit<0x80> n;
bit<0x40> v;
bit<0x20> p;
bit<0x10> b;
bit<0x08> h;
bit<0x04> i;
bit<0x02> z;
bit<0x01> c;
};
APURegFlags() { _b = 0; }
inline operator uint8() { return _b; }
inline unsigned operator = (uint8 i) { _b = i; return _b; }
inline unsigned operator &= (uint8 i) { _b &= i; return _b; }
inline unsigned operator |= (uint8 i) { _b |= i; return _b; }
inline unsigned operator ^= (uint8 i) { _b ^= i; return _b; }
};
class APURegs {
public:
uint16 pc;
union {
uint16 ya;
//not endian-safe
struct {
uint8 a, y;
};
};
uint8 x, sp;
APURegFlags p;
};

293
src/apu/bapu/bapu.cpp Normal file
View File

@ -0,0 +1,293 @@
#include "../../base.h"
#include "bapu_op_fn.cpp"
#include "bapu_op_mov.cpp"
#include "bapu_op_pc.cpp"
#include "bapu_op_read.cpp"
#include "bapu_op_rmw.cpp"
#include "bapu_op_misc.cpp"
#include "bapu_exec.cpp"
uint8 bAPU::spcram_read(uint16 addr) {
uint8 r;
if(addr >= 0x00f0 && addr <= 0x00ff) {
switch(addr) {
case 0xf0: //TEST -- operation unknown, supposedly returns 0x00
r = 0x00;
break;
case 0xf1: //CONTROL -- write-only register, always returns 0x00
r = 0x00;
break;
case 0xf2: //DSPADDR
r = status.dsp_addr;
break;
case 0xf3: //DSPDATA
//0x80-0xff is a read-only mirror of 0x00-0x7f
r = dsp_regs[status.dsp_addr & 0x7f];
break;
case 0xf4: //CPUIO0
case 0xf5: //CPUIO1
case 0xf6: //CPUIO2
case 0xf7: //CPUIO3
r = cpu->port_read(addr & 3);
break;
case 0xf8: //???
case 0xf9: //??? -- Mapped to SPCRAM
r = spcram[addr];
break;
case 0xfa: //T0TARGET
case 0xfb: //T1TARGET
case 0xfc: //T2TARGET -- write-only registers, always return 0x00
r = 0x00;
break;
case 0xfd: //T0OUT -- 4-bit counter value
r = t0.stage3_ticks & 15;
t0.stage3_ticks = 0;
break;
case 0xfe: //T1OUT -- 4-bit counter value
r = t1.stage3_ticks & 15;
t1.stage3_ticks = 0;
break;
case 0xff: //T2OUT -- 4-bit counter value
r = t2.stage3_ticks & 15;
t2.stage3_ticks = 0;
break;
}
} else if(addr < 0xffc0) {
r = spcram[addr];
} else {
if(status.iplrom_enabled == true) {
r = iplrom[addr & 0x3f];
} else {
r = spcram[addr];
}
}
snes->notify(SNES::SPCRAM_READ, addr, r);
return r;
}
void bAPU::spcram_write(uint16 addr, uint8 value) {
if(addr >= 0x00f0 && addr <= 0x00ff) {
switch(addr) {
case 0xf0: //TEST -- operation unknown
break;
case 0xf1: //CONTROL
status.iplrom_enabled = !!(value & 0x80);
//one-time clearing of APU port read registers,
//emulated by simulating CPU writes of 0x00
if(value & 0x20) {
cpu->port_write(2, 0x00);
cpu->port_write(3, 0x00);
}
if(value & 0x10) {
cpu->port_write(0, 0x00);
cpu->port_write(1, 0x00);
}
//0->1 transistion resets timers
if(t2.enabled == false && (value & 0x04)) {
t2.stage2_ticks = 0;
t2.stage3_ticks = 0;
}
t2.enabled = !!(value & 0x04);
if(t1.enabled == false && (value & 0x02)) {
t1.stage2_ticks = 0;
t1.stage3_ticks = 0;
}
t1.enabled = !!(value & 0x02);
if(t0.enabled == false && (value & 0x01)) {
t0.stage2_ticks = 0;
t0.stage3_ticks = 0;
}
t0.enabled = !!(value & 0x01);
break;
case 0xf2: //DSPADDR
status.dsp_addr = value;
break;
case 0xf3: //DSPDATA
//0x80-0xff is a read-only mirror of 0x00-0x7f
if(status.dsp_addr < 0x80) {
dsp_regs[status.dsp_addr & 0x7f] = value;
}
break;
case 0xf4: //CPUIO0
case 0xf5: //CPUIO1
case 0xf6: //CPUIO2
case 0xf7: //CPUIO3
port_write(addr & 3, value);
break;
case 0xf8: //???
case 0xf9: //??? - Mapped to SPCRAM
spcram[addr] = value;
break;
case 0xfa: //T0TARGET
t0.target = value;
break;
case 0xfb: //T1TARGET
t1.target = value;
break;
case 0xfc: //T2TARGET
t2.target = value;
break;
case 0xfd: //T0OUT
case 0xfe: //T1OUT
case 0xff: //T2OUT -- read-only registers
break;
}
} else {
//writes to $ffc0-$ffff always go to spcram,
//even if the iplrom is enabled.
spcram[addr] = value;
}
snes->notify(SNES::SPCRAM_WRITE, addr, value);
}
uint8 bAPU::port_read(uint8 port) {
return spcram[0xf4 + (port & 3)];
}
void bAPU::port_write(uint8 port, uint8 value) {
spcram[0xf4 + (port & 0x03)] = value;
}
void bAPU::add_cycles(int cycles) {
status.cycles_executed += cycles;
t0.add_cycles(cycles);
t1.add_cycles(cycles);
t2.add_cycles(cycles);
}
uint32 bAPU::cycles_executed() {
uint32 r = status.cycles_executed;
status.cycles_executed = 0;
return (r << 4) + (r << 3);
}
uint8 bAPU::op_read() {
uint8 r;
r = spcram_read(regs.pc);
regs.pc++;
return r;
}
uint8 bAPU::op_read(uint8 mode, uint16 addr) {
uint8 r;
switch(mode) {
case OPMODE_ADDR:
r = spcram_read(addr);
break;
case OPMODE_DP:
r = spcram_read(((regs.p.p)?0x100:0x000) + (addr & 0xff));
break;
}
return r;
}
void bAPU::op_write(uint8 mode, uint16 addr, uint8 value) {
switch(mode) {
case OPMODE_ADDR:
spcram_write(addr, value);
break;
case OPMODE_DP:
spcram_write(((regs.p.p)?0x100:0x000) + (addr & 0xff), value);
break;
}
}
uint8 bAPU::stack_read() {
regs.sp++;
return spcram_read(0x0100 | regs.sp);
}
void bAPU::stack_write(uint8 value) {
spcram_write(0x0100 | regs.sp, value);
regs.sp--;
}
void bAPU::run() {
exec_cycle();
}
void bAPU::power() {
memset(spcram, 0x00, 65536);
reset();
}
void bAPU::reset() {
regs.pc = 0xffc0;
regs.a = 0x00;
regs.x = 0x00;
regs.y = 0x00;
regs.sp = 0xef;
regs.p = 0x02;
status.cycle_pos = 0;
//$f1
status.iplrom_enabled = true;
t0.enabled = false;
t1.enabled = false;
t2.enabled = false;
t0.stage1_ticks = 0;
t1.stage1_ticks = 0;
t2.stage1_ticks = 0;
t0.stage2_ticks = 0;
t1.stage2_ticks = 0;
t2.stage2_ticks = 0;
t0.stage3_ticks = 0;
t1.stage3_ticks = 0;
t2.stage3_ticks = 0;
memset(dsp_regs, 0, 128);
}
bAPU::bAPU() {
init_op_table();
spcram = (uint8*)malloc(65536);
memcpy(iplrom, spc700_iplrom, 64);
t0.cycle_frequency = 128; //1.024mhz / 8khz = 128
t1.cycle_frequency = 128; //1.024mhz / 8khz = 128
t2.cycle_frequency = 16; //1.024mhz / 64khz = 16
//targets not initialized/changed upon reset
t0.target = 0;
t1.target = 0;
t2.target = 0;
}
bAPU::~bAPU() {
if(spcram)free(spcram);
}
//cycles should never be greater than 12. since the minimum
//cycle_frequency value is 16, we don't have to worry about
//two ticks occuring in one call to this function.
void bAPUTimer::add_cycles(int cycles) {
//stage 1 increment
stage1_ticks += cycles;
if(stage1_ticks < cycle_frequency)return;
stage1_ticks -= cycle_frequency;
if(enabled == false)return;
//stage 2 increment
stage2_ticks++;
if(stage2_ticks != target)return;
//stage 3 increment
stage2_ticks = 0;
stage3_ticks++;
stage3_ticks &= 15;
}

79
src/apu/bapu/bapu.h Normal file
View File

@ -0,0 +1,79 @@
class bAPU;
class bAPUTimer {
public:
uint8 cycle_frequency, target;
uint8 stage1_ticks, stage2_ticks, stage3_ticks;
bool enabled;
inline void add_cycles(int cycles);
};
class bAPU : public APU {
private:
typedef void (bAPU::*op)();
op optbl[256];
public:
uint16 dp, sp, rd, wr, bit, ya;
struct {
uint8 cycle_pos, opcode;
uint32 cycles_executed;
//$f1
bool iplrom_enabled;
//$f2
uint8 dsp_addr;
}status;
bAPUTimer t0, t1, t2;
uint8 *spcram, iplrom[64], dsp_regs[128];
inline uint8 spcram_read (uint16 addr);
inline void spcram_write(uint16 addr, uint8 value);
inline uint8 port_read (uint8 port);
inline void port_write(uint8 port, uint8 value);
inline void run();
inline uint32 cycles_executed();
inline void power();
inline void reset();
inline void add_cycles(int cycles);
enum {
OPMODE_ADDR = 0,
OPMODE_DP = 1
};
inline uint8 op_read();
inline uint8 op_read (uint8 mode, uint16 addr);
inline void op_write(uint8 mode, uint16 addr, uint8 value);
inline uint8 stack_read();
inline void stack_write(uint8 value);
inline void exec_cycle();
inline void init_op_table();
inline uint8 op_adc (uint8 x, uint8 y);
inline uint16 op_addw(uint16 x, uint16 y);
inline uint8 op_and (uint8 x, uint8 y);
inline uint8 op_cmp (uint8 x, uint8 y);
inline uint16 op_cmpw(uint16 x, uint16 y);
inline uint8 op_eor (uint8 x, uint8 y);
inline uint8 op_inc (uint8 x);
inline uint16 op_incw(uint16 x);
inline uint8 op_dec (uint8 x);
inline uint16 op_decw(uint16 x);
inline uint8 op_or (uint8 x, uint8 y);
inline uint8 op_sbc (uint8 x, uint8 y);
inline uint16 op_subw(uint16 x, uint16 y);
inline uint8 op_asl (uint8 x);
inline uint8 op_lsr (uint8 x);
inline uint8 op_rol (uint8 x);
inline uint8 op_ror (uint8 x);
#include "bapu_op.h"
bAPU();
~bAPU();
};

View File

@ -0,0 +1,20 @@
void bAPU::exec_cycle() {
uint8 op;
if(status.cycle_pos == 0) {
op = spcram_read(regs.pc);
snes->notify(SNES::APU_EXEC_OPCODE_BEGIN);
status.opcode = op_read();
status.cycle_pos = 1;
add_cycles(1);
} else {
(this->*optbl[status.opcode])();
add_cycles(1);
if(status.cycle_pos == 0) {
snes->notify(SNES::APU_EXEC_OPCODE_END);
}
}
}
void bAPU::init_op_table() {
#include "bapu_optable.cpp"
}

256
src/apu/bapu/bapu_op.h Normal file
View File

@ -0,0 +1,256 @@
void op_mov_a_x();
void op_mov_a_y();
void op_mov_x_a();
void op_mov_y_a();
void op_mov_x_sp();
void op_mov_sp_x();
void op_mov_a_const();
void op_mov_x_const();
void op_mov_y_const();
void op_mov_a_ix();
void op_mov_a_ixinc();
void op_mov_a_dp();
void op_mov_x_dp();
void op_mov_y_dp();
void op_mov_a_dpx();
void op_mov_x_dpy();
void op_mov_y_dpx();
void op_mov_a_addr();
void op_mov_x_addr();
void op_mov_y_addr();
void op_mov_a_addrx();
void op_mov_a_addry();
void op_mov_a_idpx();
void op_mov_a_idpy();
void op_mov_dp_dp();
void op_mov_dp_const();
void op_mov_ix_a();
void op_mov_ixinc_a();
void op_mov_dp_a();
void op_mov_dp_x();
void op_mov_dp_y();
void op_mov_dpx_a();
void op_mov_dpy_x();
void op_mov_dpx_y();
void op_mov_addr_a();
void op_mov_addr_x();
void op_mov_addr_y();
void op_mov_addrx_a();
void op_mov_addry_a();
void op_mov_idpx_a();
void op_mov_idpy_a();
void op_movw_ya_dp();
void op_movw_dp_ya();
void op_mov1_c_bit();
void op_mov1_bit_c();
void op_bra();
void op_beq();
void op_bne();
void op_bcs();
void op_bcc();
void op_bvs();
void op_bvc();
void op_bmi();
void op_bpl();
void op_bbs0();
void op_bbc0();
void op_bbs1();
void op_bbc1();
void op_bbs2();
void op_bbc2();
void op_bbs3();
void op_bbc3();
void op_bbs4();
void op_bbc4();
void op_bbs5();
void op_bbc5();
void op_bbs6();
void op_bbc6();
void op_bbs7();
void op_bbc7();
void op_cbne_dp();
void op_cbne_dpx();
void op_dbnz_dp();
void op_dbnz_y();
void op_jmp_addr();
void op_jmp_iaddrx();
void op_call();
void op_pcall();
void op_tcall_0();
void op_tcall_1();
void op_tcall_2();
void op_tcall_3();
void op_tcall_4();
void op_tcall_5();
void op_tcall_6();
void op_tcall_7();
void op_tcall_8();
void op_tcall_9();
void op_tcall_10();
void op_tcall_11();
void op_tcall_12();
void op_tcall_13();
void op_tcall_14();
void op_tcall_15();
void op_brk();
void op_ret();
void op_reti();
void op_adc_a_const();
void op_and_a_const();
void op_cmp_a_const();
void op_cmp_x_const();
void op_cmp_y_const();
void op_eor_a_const();
void op_or_a_const();
void op_sbc_a_const();
void op_adc_a_ix();
void op_and_a_ix();
void op_cmp_a_ix();
void op_eor_a_ix();
void op_or_a_ix();
void op_sbc_a_ix();
void op_adc_a_dp();
void op_and_a_dp();
void op_cmp_a_dp();
void op_cmp_x_dp();
void op_cmp_y_dp();
void op_eor_a_dp();
void op_or_a_dp();
void op_sbc_a_dp();
void op_adc_a_dpx();
void op_and_a_dpx();
void op_cmp_a_dpx();
void op_eor_a_dpx();
void op_or_a_dpx();
void op_sbc_a_dpx();
void op_adc_a_addr();
void op_and_a_addr();
void op_cmp_a_addr();
void op_cmp_x_addr();
void op_cmp_y_addr();
void op_eor_a_addr();
void op_or_a_addr();
void op_sbc_a_addr();
void op_adc_a_addrx();
void op_adc_a_addry();
void op_and_a_addrx();
void op_and_a_addry();
void op_cmp_a_addrx();
void op_cmp_a_addry();
void op_eor_a_addrx();
void op_eor_a_addry();
void op_or_a_addrx();
void op_or_a_addry();
void op_sbc_a_addrx();
void op_sbc_a_addry();
void op_adc_a_idpx();
void op_and_a_idpx();
void op_cmp_a_idpx();
void op_eor_a_idpx();
void op_or_a_idpx();
void op_sbc_a_idpx();
void op_adc_a_idpy();
void op_and_a_idpy();
void op_cmp_a_idpy();
void op_eor_a_idpy();
void op_or_a_idpy();
void op_sbc_a_idpy();
void op_adc_ix_iy();
void op_and_ix_iy();
void op_cmp_ix_iy();
void op_eor_ix_iy();
void op_or_ix_iy();
void op_sbc_ix_iy();
void op_adc_dp_dp();
void op_and_dp_dp();
void op_cmp_dp_dp();
void op_eor_dp_dp();
void op_or_dp_dp();
void op_sbc_dp_dp();
void op_adc_dp_const();
void op_and_dp_const();
void op_cmp_dp_const();
void op_eor_dp_const();
void op_or_dp_const();
void op_sbc_dp_const();
void op_addw_ya_dp();
void op_cmpw_ya_dp();
void op_subw_ya_dp();
void op_and1_bit();
void op_and1_notbit();
void op_eor1_bit();
void op_not1_bit();
void op_or1_bit();
void op_or1_notbit();
void op_inc_a();
void op_inc_x();
void op_inc_y();
void op_dec_a();
void op_dec_x();
void op_dec_y();
void op_asl_a();
void op_lsr_a();
void op_rol_a();
void op_ror_a();
void op_inc_dp();
void op_dec_dp();
void op_asl_dp();
void op_lsr_dp();
void op_rol_dp();
void op_ror_dp();
void op_inc_dpx();
void op_dec_dpx();
void op_asl_dpx();
void op_lsr_dpx();
void op_rol_dpx();
void op_ror_dpx();
void op_inc_addr();
void op_dec_addr();
void op_asl_addr();
void op_lsr_addr();
void op_rol_addr();
void op_ror_addr();
void op_incw_dp();
void op_decw_dp();
void op_nop();
void op_sleep();
void op_stop();
void op_xcn();
void op_daa();
void op_das();
void op_clrc();
void op_clrp();
void op_setc();
void op_setp();
void op_clrv();
void op_notc();
void op_ei();
void op_di();
void op_set0_dp();
void op_clr0_dp();
void op_set1_dp();
void op_clr1_dp();
void op_set2_dp();
void op_clr2_dp();
void op_set3_dp();
void op_clr3_dp();
void op_set4_dp();
void op_clr4_dp();
void op_set5_dp();
void op_clr5_dp();
void op_set6_dp();
void op_clr6_dp();
void op_set7_dp();
void op_clr7_dp();
void op_tset_addr_a();
void op_tclr_addr_a();
void op_push_a();
void op_push_x();
void op_push_y();
void op_push_p();
void op_pop_a();
void op_pop_x();
void op_pop_y();
void op_pop_p();
void op_mul_ya();
void op_div_ya_x();

140
src/apu/bapu/bapu_op_fn.cpp Normal file
View File

@ -0,0 +1,140 @@
uint8 bAPU::op_adc(uint8 x, uint8 y) {
int16 r = x + y + regs.p.c;
regs.p.n = !!(r & 0x80);
regs.p.v = !!(~(x ^ y) & (y ^ (uint8)r) & 0x80);
regs.p.h = !!((x ^ y ^ (uint8)r) & 0x10);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r > 0xff);
return r;
}
uint16 bAPU::op_addw(uint16 x, uint16 y) {
int32 r = x + y;
regs.p.n = !!(r & 0x8000);
regs.p.v = !!(~(x ^ y) & (y ^ (uint16)r) & 0x8000);
regs.p.h = !!((x ^ y ^ (uint16)r) & 0x10);
regs.p.z = ((uint16)r == 0);
regs.p.c = (r > 0xffff);
return r;
}
uint8 bAPU::op_and(uint8 x, uint8 y) {
x &= y;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 bAPU::op_cmp(uint8 x, uint8 y) {
int16 r = x - y;
regs.p.n = !!(r & 0x80);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r >= 0);
return x;
}
uint16 bAPU::op_cmpw(uint16 x, uint16 y) {
int32 r = x - y;
regs.p.n = !!(r & 0x8000);
regs.p.z = ((uint16)r == 0);
regs.p.c = (r >= 0);
return x;
}
uint8 bAPU::op_eor(uint8 x, uint8 y) {
x ^= y;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 bAPU::op_or(uint8 x, uint8 y) {
x |= y;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 bAPU::op_sbc(uint8 x, uint8 y) {
int16 r = x - y - !regs.p.c;
regs.p.n = !!(r & 0x80);
regs.p.v = !!((x ^ y) & (x ^ (uint8)r) & 0x80);
regs.p.h = !((x ^ y ^ (uint8)r) & 0x10);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r >= 0);
return r;
}
uint16 bAPU::op_subw(uint16 x, uint16 y) {
int32 r = x - y;
regs.p.n = !!(r & 0x8000);
regs.p.v = !!((x ^ y) & (x ^ (uint16)r) & 0x8000);
regs.p.h = !((x ^ y ^ (uint16)r) & 0x10);
regs.p.z = ((uint16)r == 0);
regs.p.c = (r >= 0);
return r;
}
uint8 bAPU::op_inc(uint8 x) {
x++;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint16 bAPU::op_incw(uint16 x) {
x++;
regs.p.n = !!(x & 0x8000);
regs.p.z = (x == 0);
return x;
}
uint8 bAPU::op_dec(uint8 x) {
x--;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint16 bAPU::op_decw(uint16 x) {
x--;
regs.p.n = !!(x & 0x8000);
regs.p.z = (x == 0);
return x;
}
uint8 bAPU::op_asl(uint8 x) {
regs.p.c = !!(x & 0x80);
x <<= 1;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 bAPU::op_lsr(uint8 x) {
regs.p.c = !!(x & 0x01);
x >>= 1;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 bAPU::op_rol(uint8 x) {
uint8 c = regs.p.c;
regs.p.c = !!(x & 0x80);
x <<= 1;
x |= c;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 bAPU::op_ror(uint8 x) {
uint8 c = (regs.p.c)?0x80:0x00;
regs.p.c = !!(x & 0x01);
x >>= 1;
x |= c;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}

View File

@ -0,0 +1,643 @@
void bAPU::op_nop() {
switch(status.cycle_pos++) {
case 1:
status.cycle_pos = 0;
break;
}
}
void bAPU::op_sleep() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
regs.pc--;
status.cycle_pos = 0;
break;
}
}
void bAPU::op_stop() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
regs.pc--;
status.cycle_pos = 0;
break;
}
}
void bAPU::op_xcn() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
regs.a = (regs.a >> 4) | (regs.a << 4);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_daa() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
if(regs.p.c || (regs.a) > 0x99) {
regs.a += 0x60;
regs.p.c = 1;
}
if(regs.p.h || (regs.a & 15) > 0x09) {
regs.a += 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_das() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
if(!regs.p.c || (regs.a) > 0x99) {
regs.a -= 0x60;
regs.p.c = 0;
}
if(!regs.p.h || (regs.a & 15) > 0x09) {
regs.a -= 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_clrc() {
switch(status.cycle_pos++) {
case 1:
regs.p.c = 0;
status.cycle_pos = 0;
break;
}
}
void bAPU::op_clrp() {
switch(status.cycle_pos++) {
case 1:
regs.p.p = 0;
status.cycle_pos = 0;
break;
}
}
void bAPU::op_setc() {
switch(status.cycle_pos++) {
case 1:
regs.p.c = 1;
status.cycle_pos = 0;
break;
}
}
void bAPU::op_setp() {
switch(status.cycle_pos++) {
case 1:
regs.p.p = 1;
status.cycle_pos = 0;
break;
}
}
void bAPU::op_clrv() {
switch(status.cycle_pos++) {
case 1:
regs.p.v = 0;
regs.p.h = 0;
status.cycle_pos = 0;
break;
}
}
void bAPU::op_notc() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
regs.p.c ^= 1;
status.cycle_pos = 0;
break;
}
}
void bAPU::op_ei() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
regs.p.i = 1;
status.cycle_pos = 0;
break;
}
}
void bAPU::op_di() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
regs.p.i = 0;
status.cycle_pos = 0;
break;
}
}
void bAPU::op_set0_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd |= 0x01;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_clr0_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd &= ~0x01;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_set1_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd |= 0x02;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_clr1_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd &= ~0x02;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_set2_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd |= 0x04;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_clr2_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd &= ~0x04;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_set3_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd |= 0x08;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_clr3_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd &= ~0x08;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_set4_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd |= 0x10;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_clr4_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd &= ~0x10;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_set5_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd |= 0x20;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_clr5_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd &= ~0x20;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_set6_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd |= 0x40;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_clr6_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd &= ~0x40;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_set7_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd |= 0x80;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_clr7_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd &= ~0x80;
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_tset_addr_a() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
rd = op_read(OPMODE_ADDR, dp);
break;
case 4:
regs.p.n = !!((rd & regs.a) & 0x80);
regs.p.z = ((rd & regs.a) == 0);
rd |= regs.a;
break;
case 5:
op_write(OPMODE_ADDR, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_tclr_addr_a() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
rd = op_read(OPMODE_ADDR, dp);
break;
case 4:
regs.p.n = !!((rd & regs.a) & 0x80);
regs.p.z = ((rd & regs.a) == 0);
rd &=~ regs.a;
break;
case 5:
op_write(OPMODE_ADDR, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_push_a() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
stack_write(regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_push_x() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
stack_write(regs.x);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_push_y() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
stack_write(regs.y);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_push_p() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
stack_write(regs.p);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_pop_a() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
regs.a = stack_read();
status.cycle_pos = 0;
break;
}
}
void bAPU::op_pop_x() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
regs.x = stack_read();
status.cycle_pos = 0;
break;
}
}
void bAPU::op_pop_y() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
regs.y = stack_read();
status.cycle_pos = 0;
break;
}
}
void bAPU::op_pop_p() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
regs.p = stack_read();
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mul_ya() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
ya = regs.y * regs.a;
regs.a = ya;
regs.y = ya >> 8;
//result is set based on y (high-byte) only
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_div_ya_x() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
break;
case 6:
break;
case 7:
break;
case 8:
break;
case 9:
break;
case 10:
break;
case 11:
ya = regs.ya;
//overflow set if quotient >= 256
regs.p.v = !!(regs.y >= regs.x);
regs.p.h = !!((regs.y & 15) >= (regs.x & 15));
if(regs.y < (regs.x << 1)) {
//if quotient is <= 511 (will fit into 9-bit result)
regs.a = ya / regs.x;
regs.y = ya % regs.x;
} else {
//otherwise, the quotient won't fit into regs.p.v + regs.a
//this emulates the odd behavior of the SPC700 in this case
regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x);
regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x);
}
//result is set based on a (quotient) only
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}

View File

@ -0,0 +1,710 @@
void bAPU::op_mov_a_x() {
switch(status.cycle_pos++) {
case 1:
regs.a = regs.x;
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_a_y() {
switch(status.cycle_pos++) {
case 1:
regs.a = regs.y;
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_x_a() {
switch(status.cycle_pos++) {
case 1:
regs.x = regs.a;
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_y_a() {
switch(status.cycle_pos++) {
case 1:
regs.y = regs.a;
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_x_sp() {
switch(status.cycle_pos++) {
case 1:
regs.x = regs.sp;
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_sp_x() {
switch(status.cycle_pos++) {
case 1:
regs.sp = regs.x;
regs.p.n = !!(regs.sp & 0x80);
regs.p.z = (regs.sp == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_a_const() {
switch(status.cycle_pos++) {
case 1:
regs.a = op_read();
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_x_const() {
switch(status.cycle_pos++) {
case 1:
regs.x = op_read();
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_y_const() {
switch(status.cycle_pos++) {
case 1:
regs.y = op_read();
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_a_ix() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
regs.a = op_read(OPMODE_DP, regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_a_ixinc() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
regs.a = op_read(OPMODE_DP, regs.x++);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_a_dp() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
regs.a = op_read(OPMODE_DP, sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_x_dp() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
regs.x = op_read(OPMODE_DP, sp);
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_y_dp() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
regs.y = op_read(OPMODE_DP, sp);
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_a_dpx() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
break;
case 3:
regs.a = op_read(OPMODE_DP, sp + regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_x_dpy() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
break;
case 3:
regs.x = op_read(OPMODE_DP, sp + regs.y);
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_y_dpx() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
break;
case 3:
regs.y = op_read(OPMODE_DP, sp + regs.x);
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_a_addr() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
sp |= op_read() << 8;
break;
case 3:
regs.a = op_read(OPMODE_ADDR, sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_x_addr() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
sp |= op_read() << 8;
break;
case 3:
regs.x = op_read(OPMODE_ADDR, sp);
regs.p.n = !!(regs.x & 0x80);
regs.p.z = (regs.x == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_y_addr() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
sp |= op_read() << 8;
break;
case 3:
regs.y = op_read(OPMODE_ADDR, sp);
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_a_addrx() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
sp |= op_read() << 8;
break;
case 3:
break;
case 4:
regs.a = op_read(OPMODE_ADDR, sp + regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_a_addry() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
sp |= op_read() << 8;
break;
case 3:
break;
case 4:
regs.a = op_read(OPMODE_ADDR, sp + regs.y);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_a_idpx() {
switch(status.cycle_pos++) {
case 1:
dp = op_read() + regs.x;
break;
case 2:
break;
case 3:
sp = op_read(OPMODE_DP, dp);
break;
case 4:
sp |= op_read(OPMODE_DP, dp + 1) << 8;
break;
case 5:
regs.a = op_read(OPMODE_ADDR, sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_a_idpy() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
sp = op_read(OPMODE_DP, dp);
break;
case 4:
sp |= op_read(OPMODE_DP, dp + 1) << 8;
break;
case 5:
regs.a = op_read(OPMODE_ADDR, sp + regs.y);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_dp_dp() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
dp = op_read();
break;
case 3:
rd = op_read(OPMODE_DP, sp);
break;
case 4:
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_dp_const() {
switch(status.cycle_pos++) {
case 1:
rd = op_read();
break;
case 2:
dp = op_read();
break;
case 3:
break;
case 4:
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_ix_a() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
op_write(OPMODE_DP, regs.x, regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_ixinc_a() {
switch(status.cycle_pos++) {
case 1:
break;
case 2:
break;
case 3:
op_write(OPMODE_DP, regs.x++, regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_dp_a() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
op_write(OPMODE_DP, dp, regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_dp_x() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
op_write(OPMODE_DP, dp, regs.x);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_dp_y() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
op_write(OPMODE_DP, dp, regs.y);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_dpx_a() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
break;
case 4:
op_write(OPMODE_DP, dp + regs.x, regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_dpy_x() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
break;
case 4:
op_write(OPMODE_DP, dp + regs.y, regs.x);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_dpx_y() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
break;
case 4:
op_write(OPMODE_DP, dp + regs.x, regs.y);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_addr_a() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
break;
case 4:
op_write(OPMODE_ADDR, dp, regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_addr_x() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
break;
case 4:
op_write(OPMODE_ADDR, dp, regs.x);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_addr_y() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
break;
case 4:
op_write(OPMODE_ADDR, dp, regs.y);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_addrx_a() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
break;
case 4:
break;
case 5:
op_write(OPMODE_ADDR, dp + regs.x, regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_addry_a() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
break;
case 4:
break;
case 5:
op_write(OPMODE_ADDR, dp + regs.y, regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_idpx_a() {
switch(status.cycle_pos++) {
case 1:
sp = op_read() + regs.x;
break;
case 2:
break;
case 3:
dp = op_read(OPMODE_DP, sp);
break;
case 4:
dp |= op_read(OPMODE_DP, sp + 1) << 8;
break;
case 5:
break;
case 6:
op_write(OPMODE_ADDR, dp, regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov_idpy_a() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
break;
case 3:
dp = op_read(OPMODE_DP, sp);
break;
case 4:
dp |= op_read(OPMODE_DP, sp + 1) << 8;
break;
case 5:
break;
case 6:
op_write(OPMODE_ADDR, dp + regs.y, regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_movw_ya_dp() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
break;
case 3:
regs.a = op_read(OPMODE_DP, sp);
break;
case 4:
regs.y = op_read(OPMODE_DP, sp + 1);
regs.p.n = !!(regs.ya & 0x8000);
regs.p.z = (regs.ya == 0);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_movw_dp_ya() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
op_write(OPMODE_DP, dp, regs.a);
break;
case 4:
op_write(OPMODE_DP, dp + 1, regs.y);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov1_c_bit() {
switch(status.cycle_pos++) {
case 1:
sp = op_read();
break;
case 2:
sp |= op_read() << 8;
break;
case 3:
bit = sp >> 13;
sp &= 0x1fff;
rd = op_read(OPMODE_ADDR, sp);
regs.p.c = !!(rd & (1 << bit));
status.cycle_pos = 0;
break;
}
}
void bAPU::op_mov1_bit_c() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
bit = dp >> 13;
dp &= 0x1fff;
rd = op_read(OPMODE_ADDR, dp);
if(regs.p.c)rd |= (1 << bit);
else rd &= ~(1 << bit);
break;
case 4:
op_write(OPMODE_ADDR, dp, rd);
status.cycle_pos = 0;
break;
}
}

1155
src/apu/bapu/bapu_op_pc.cpp Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,452 @@
void bAPU::op_inc_a() {
switch(status.cycle_pos++) {
case 1:
regs.a = op_inc(regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_inc_x() {
switch(status.cycle_pos++) {
case 1:
regs.x = op_inc(regs.x);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_inc_y() {
switch(status.cycle_pos++) {
case 1:
regs.y = op_inc(regs.y);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_dec_a() {
switch(status.cycle_pos++) {
case 1:
regs.a = op_dec(regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_dec_x() {
switch(status.cycle_pos++) {
case 1:
regs.x = op_dec(regs.x);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_dec_y() {
switch(status.cycle_pos++) {
case 1:
regs.y = op_dec(regs.y);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_asl_a() {
switch(status.cycle_pos++) {
case 1:
regs.a = op_asl(regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_lsr_a() {
switch(status.cycle_pos++) {
case 1:
regs.a = op_lsr(regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_rol_a() {
switch(status.cycle_pos++) {
case 1:
regs.a = op_rol(regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_ror_a() {
switch(status.cycle_pos++) {
case 1:
regs.a = op_ror(regs.a);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_inc_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd = op_inc(rd);
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_dec_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd = op_dec(rd);
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_asl_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd = op_asl(rd);
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_lsr_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd = op_lsr(rd);
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_rol_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd = op_rol(rd);
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_ror_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd = op_ror(rd);
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_inc_dpx() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
rd = op_read(OPMODE_DP, dp + regs.x);
break;
case 4:
rd = op_inc(rd);
op_write(OPMODE_DP, dp + regs.x, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_dec_dpx() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
rd = op_read(OPMODE_DP, dp + regs.x);
break;
case 4:
rd = op_dec(rd);
op_write(OPMODE_DP, dp + regs.x, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_asl_dpx() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
rd = op_read(OPMODE_DP, dp + regs.x);
break;
case 4:
rd = op_asl(rd);
op_write(OPMODE_DP, dp + regs.x, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_lsr_dpx() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
rd = op_read(OPMODE_DP, dp + regs.x);
break;
case 4:
rd = op_lsr(rd);
op_write(OPMODE_DP, dp + regs.x, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_rol_dpx() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
rd = op_read(OPMODE_DP, dp + regs.x);
break;
case 4:
rd = op_rol(rd);
op_write(OPMODE_DP, dp + regs.x, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_ror_dpx() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
break;
case 3:
rd = op_read(OPMODE_DP, dp + regs.x);
break;
case 4:
rd = op_ror(rd);
op_write(OPMODE_DP, dp + regs.x, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_inc_addr() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
rd = op_read(OPMODE_ADDR, dp);
break;
case 4:
rd = op_inc(rd);
op_write(OPMODE_ADDR, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_dec_addr() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
rd = op_read(OPMODE_ADDR, dp);
break;
case 4:
rd = op_dec(rd);
op_write(OPMODE_ADDR, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_asl_addr() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
rd = op_read(OPMODE_ADDR, dp);
break;
case 4:
rd = op_asl(rd);
op_write(OPMODE_ADDR, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_lsr_addr() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
rd = op_read(OPMODE_ADDR, dp);
break;
case 4:
rd = op_lsr(rd);
op_write(OPMODE_ADDR, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_rol_addr() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
rd = op_read(OPMODE_ADDR, dp);
break;
case 4:
rd = op_rol(rd);
op_write(OPMODE_ADDR, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_ror_addr() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
dp |= op_read() << 8;
break;
case 3:
rd = op_read(OPMODE_ADDR, dp);
break;
case 4:
rd = op_ror(rd);
op_write(OPMODE_ADDR, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_incw_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd |= op_read(OPMODE_DP, dp + 1) << 8;
break;
case 4:
rd = op_incw(rd);
op_write(OPMODE_DP, dp + 1, rd >> 8);
break;
case 5:
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}
void bAPU::op_decw_dp() {
switch(status.cycle_pos++) {
case 1:
dp = op_read();
break;
case 2:
rd = op_read(OPMODE_DP, dp);
break;
case 3:
rd |= op_read(OPMODE_DP, dp + 1) << 8;
break;
case 4:
rd = op_decw(rd);
op_write(OPMODE_DP, dp + 1, rd >> 8);
break;
case 5:
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
break;
}
}

View File

@ -0,0 +1,256 @@
optbl[0x7d] = &bAPU::op_mov_a_x;
optbl[0xdd] = &bAPU::op_mov_a_y;
optbl[0x5d] = &bAPU::op_mov_x_a;
optbl[0xfd] = &bAPU::op_mov_y_a;
optbl[0x9d] = &bAPU::op_mov_x_sp;
optbl[0xbd] = &bAPU::op_mov_sp_x;
optbl[0xe8] = &bAPU::op_mov_a_const;
optbl[0xcd] = &bAPU::op_mov_x_const;
optbl[0x8d] = &bAPU::op_mov_y_const;
optbl[0xe6] = &bAPU::op_mov_a_ix;
optbl[0xbf] = &bAPU::op_mov_a_ixinc;
optbl[0xe4] = &bAPU::op_mov_a_dp;
optbl[0xf8] = &bAPU::op_mov_x_dp;
optbl[0xeb] = &bAPU::op_mov_y_dp;
optbl[0xf4] = &bAPU::op_mov_a_dpx;
optbl[0xf9] = &bAPU::op_mov_x_dpy;
optbl[0xfb] = &bAPU::op_mov_y_dpx;
optbl[0xe5] = &bAPU::op_mov_a_addr;
optbl[0xe9] = &bAPU::op_mov_x_addr;
optbl[0xec] = &bAPU::op_mov_y_addr;
optbl[0xf5] = &bAPU::op_mov_a_addrx;
optbl[0xf6] = &bAPU::op_mov_a_addry;
optbl[0xe7] = &bAPU::op_mov_a_idpx;
optbl[0xf7] = &bAPU::op_mov_a_idpy;
optbl[0xfa] = &bAPU::op_mov_dp_dp;
optbl[0x8f] = &bAPU::op_mov_dp_const;
optbl[0xc6] = &bAPU::op_mov_ix_a;
optbl[0xaf] = &bAPU::op_mov_ixinc_a;
optbl[0xc4] = &bAPU::op_mov_dp_a;
optbl[0xd8] = &bAPU::op_mov_dp_x;
optbl[0xcb] = &bAPU::op_mov_dp_y;
optbl[0xd4] = &bAPU::op_mov_dpx_a;
optbl[0xd9] = &bAPU::op_mov_dpy_x;
optbl[0xdb] = &bAPU::op_mov_dpx_y;
optbl[0xc5] = &bAPU::op_mov_addr_a;
optbl[0xc9] = &bAPU::op_mov_addr_x;
optbl[0xcc] = &bAPU::op_mov_addr_y;
optbl[0xd5] = &bAPU::op_mov_addrx_a;
optbl[0xd6] = &bAPU::op_mov_addry_a;
optbl[0xc7] = &bAPU::op_mov_idpx_a;
optbl[0xd7] = &bAPU::op_mov_idpy_a;
optbl[0xba] = &bAPU::op_movw_ya_dp;
optbl[0xda] = &bAPU::op_movw_dp_ya;
optbl[0xaa] = &bAPU::op_mov1_c_bit;
optbl[0xca] = &bAPU::op_mov1_bit_c;
optbl[0x2f] = &bAPU::op_bra;
optbl[0xf0] = &bAPU::op_beq;
optbl[0xd0] = &bAPU::op_bne;
optbl[0xb0] = &bAPU::op_bcs;
optbl[0x90] = &bAPU::op_bcc;
optbl[0x70] = &bAPU::op_bvs;
optbl[0x50] = &bAPU::op_bvc;
optbl[0x30] = &bAPU::op_bmi;
optbl[0x10] = &bAPU::op_bpl;
optbl[0x03] = &bAPU::op_bbs0;
optbl[0x13] = &bAPU::op_bbc0;
optbl[0x23] = &bAPU::op_bbs1;
optbl[0x33] = &bAPU::op_bbc1;
optbl[0x43] = &bAPU::op_bbs2;
optbl[0x53] = &bAPU::op_bbc2;
optbl[0x63] = &bAPU::op_bbs3;
optbl[0x73] = &bAPU::op_bbc3;
optbl[0x83] = &bAPU::op_bbs4;
optbl[0x93] = &bAPU::op_bbc4;
optbl[0xa3] = &bAPU::op_bbs5;
optbl[0xb3] = &bAPU::op_bbc5;
optbl[0xc3] = &bAPU::op_bbs6;
optbl[0xd3] = &bAPU::op_bbc6;
optbl[0xe3] = &bAPU::op_bbs7;
optbl[0xf3] = &bAPU::op_bbc7;
optbl[0x2e] = &bAPU::op_cbne_dp;
optbl[0xde] = &bAPU::op_cbne_dpx;
optbl[0x6e] = &bAPU::op_dbnz_dp;
optbl[0xfe] = &bAPU::op_dbnz_y;
optbl[0x5f] = &bAPU::op_jmp_addr;
optbl[0x1f] = &bAPU::op_jmp_iaddrx;
optbl[0x3f] = &bAPU::op_call;
optbl[0x4f] = &bAPU::op_pcall;
optbl[0x01] = &bAPU::op_tcall_0;
optbl[0x11] = &bAPU::op_tcall_1;
optbl[0x21] = &bAPU::op_tcall_2;
optbl[0x31] = &bAPU::op_tcall_3;
optbl[0x41] = &bAPU::op_tcall_4;
optbl[0x51] = &bAPU::op_tcall_5;
optbl[0x61] = &bAPU::op_tcall_6;
optbl[0x71] = &bAPU::op_tcall_7;
optbl[0x81] = &bAPU::op_tcall_8;
optbl[0x91] = &bAPU::op_tcall_9;
optbl[0xa1] = &bAPU::op_tcall_10;
optbl[0xb1] = &bAPU::op_tcall_11;
optbl[0xc1] = &bAPU::op_tcall_12;
optbl[0xd1] = &bAPU::op_tcall_13;
optbl[0xe1] = &bAPU::op_tcall_14;
optbl[0xf1] = &bAPU::op_tcall_15;
optbl[0x0f] = &bAPU::op_brk;
optbl[0x6f] = &bAPU::op_ret;
optbl[0x7f] = &bAPU::op_reti;
optbl[0x88] = &bAPU::op_adc_a_const;
optbl[0x28] = &bAPU::op_and_a_const;
optbl[0x68] = &bAPU::op_cmp_a_const;
optbl[0xc8] = &bAPU::op_cmp_x_const;
optbl[0xad] = &bAPU::op_cmp_y_const;
optbl[0x48] = &bAPU::op_eor_a_const;
optbl[0x08] = &bAPU::op_or_a_const;
optbl[0xa8] = &bAPU::op_sbc_a_const;
optbl[0x86] = &bAPU::op_adc_a_ix;
optbl[0x26] = &bAPU::op_and_a_ix;
optbl[0x66] = &bAPU::op_cmp_a_ix;
optbl[0x46] = &bAPU::op_eor_a_ix;
optbl[0x06] = &bAPU::op_or_a_ix;
optbl[0xa6] = &bAPU::op_sbc_a_ix;
optbl[0x84] = &bAPU::op_adc_a_dp;
optbl[0x24] = &bAPU::op_and_a_dp;
optbl[0x64] = &bAPU::op_cmp_a_dp;
optbl[0x3e] = &bAPU::op_cmp_x_dp;
optbl[0x7e] = &bAPU::op_cmp_y_dp;
optbl[0x44] = &bAPU::op_eor_a_dp;
optbl[0x04] = &bAPU::op_or_a_dp;
optbl[0xa4] = &bAPU::op_sbc_a_dp;
optbl[0x94] = &bAPU::op_adc_a_dpx;
optbl[0x34] = &bAPU::op_and_a_dpx;
optbl[0x74] = &bAPU::op_cmp_a_dpx;
optbl[0x54] = &bAPU::op_eor_a_dpx;
optbl[0x14] = &bAPU::op_or_a_dpx;
optbl[0xb4] = &bAPU::op_sbc_a_dpx;
optbl[0x85] = &bAPU::op_adc_a_addr;
optbl[0x25] = &bAPU::op_and_a_addr;
optbl[0x65] = &bAPU::op_cmp_a_addr;
optbl[0x1e] = &bAPU::op_cmp_x_addr;
optbl[0x5e] = &bAPU::op_cmp_y_addr;
optbl[0x45] = &bAPU::op_eor_a_addr;
optbl[0x05] = &bAPU::op_or_a_addr;
optbl[0xa5] = &bAPU::op_sbc_a_addr;
optbl[0x95] = &bAPU::op_adc_a_addrx;
optbl[0x96] = &bAPU::op_adc_a_addry;
optbl[0x35] = &bAPU::op_and_a_addrx;
optbl[0x36] = &bAPU::op_and_a_addry;
optbl[0x75] = &bAPU::op_cmp_a_addrx;
optbl[0x76] = &bAPU::op_cmp_a_addry;
optbl[0x55] = &bAPU::op_eor_a_addrx;
optbl[0x56] = &bAPU::op_eor_a_addry;
optbl[0x15] = &bAPU::op_or_a_addrx;
optbl[0x16] = &bAPU::op_or_a_addry;
optbl[0xb5] = &bAPU::op_sbc_a_addrx;
optbl[0xb6] = &bAPU::op_sbc_a_addry;
optbl[0x87] = &bAPU::op_adc_a_idpx;
optbl[0x27] = &bAPU::op_and_a_idpx;
optbl[0x67] = &bAPU::op_cmp_a_idpx;
optbl[0x47] = &bAPU::op_eor_a_idpx;
optbl[0x07] = &bAPU::op_or_a_idpx;
optbl[0xa7] = &bAPU::op_sbc_a_idpx;
optbl[0x97] = &bAPU::op_adc_a_idpy;
optbl[0x37] = &bAPU::op_and_a_idpy;
optbl[0x77] = &bAPU::op_cmp_a_idpy;
optbl[0x57] = &bAPU::op_eor_a_idpy;
optbl[0x17] = &bAPU::op_or_a_idpy;
optbl[0xb7] = &bAPU::op_sbc_a_idpy;
optbl[0x99] = &bAPU::op_adc_ix_iy;
optbl[0x39] = &bAPU::op_and_ix_iy;
optbl[0x79] = &bAPU::op_cmp_ix_iy;
optbl[0x59] = &bAPU::op_eor_ix_iy;
optbl[0x19] = &bAPU::op_or_ix_iy;
optbl[0xb9] = &bAPU::op_sbc_ix_iy;
optbl[0x89] = &bAPU::op_adc_dp_dp;
optbl[0x29] = &bAPU::op_and_dp_dp;
optbl[0x69] = &bAPU::op_cmp_dp_dp;
optbl[0x49] = &bAPU::op_eor_dp_dp;
optbl[0x09] = &bAPU::op_or_dp_dp;
optbl[0xa9] = &bAPU::op_sbc_dp_dp;
optbl[0x98] = &bAPU::op_adc_dp_const;
optbl[0x38] = &bAPU::op_and_dp_const;
optbl[0x78] = &bAPU::op_cmp_dp_const;
optbl[0x58] = &bAPU::op_eor_dp_const;
optbl[0x18] = &bAPU::op_or_dp_const;
optbl[0xb8] = &bAPU::op_sbc_dp_const;
optbl[0x7a] = &bAPU::op_addw_ya_dp;
optbl[0x5a] = &bAPU::op_cmpw_ya_dp;
optbl[0x9a] = &bAPU::op_subw_ya_dp;
optbl[0x4a] = &bAPU::op_and1_bit;
optbl[0x6a] = &bAPU::op_and1_notbit;
optbl[0x8a] = &bAPU::op_eor1_bit;
optbl[0xea] = &bAPU::op_not1_bit;
optbl[0x0a] = &bAPU::op_or1_bit;
optbl[0x2a] = &bAPU::op_or1_notbit;
optbl[0xbc] = &bAPU::op_inc_a;
optbl[0x3d] = &bAPU::op_inc_x;
optbl[0xfc] = &bAPU::op_inc_y;
optbl[0x9c] = &bAPU::op_dec_a;
optbl[0x1d] = &bAPU::op_dec_x;
optbl[0xdc] = &bAPU::op_dec_y;
optbl[0x1c] = &bAPU::op_asl_a;
optbl[0x5c] = &bAPU::op_lsr_a;
optbl[0x3c] = &bAPU::op_rol_a;
optbl[0x7c] = &bAPU::op_ror_a;
optbl[0xab] = &bAPU::op_inc_dp;
optbl[0x8b] = &bAPU::op_dec_dp;
optbl[0x0b] = &bAPU::op_asl_dp;
optbl[0x4b] = &bAPU::op_lsr_dp;
optbl[0x2b] = &bAPU::op_rol_dp;
optbl[0x6b] = &bAPU::op_ror_dp;
optbl[0xbb] = &bAPU::op_inc_dpx;
optbl[0x9b] = &bAPU::op_dec_dpx;
optbl[0x1b] = &bAPU::op_asl_dpx;
optbl[0x5b] = &bAPU::op_lsr_dpx;
optbl[0x3b] = &bAPU::op_rol_dpx;
optbl[0x7b] = &bAPU::op_ror_dpx;
optbl[0xac] = &bAPU::op_inc_addr;
optbl[0x8c] = &bAPU::op_dec_addr;
optbl[0x0c] = &bAPU::op_asl_addr;
optbl[0x4c] = &bAPU::op_lsr_addr;
optbl[0x2c] = &bAPU::op_rol_addr;
optbl[0x6c] = &bAPU::op_ror_addr;
optbl[0x3a] = &bAPU::op_incw_dp;
optbl[0x1a] = &bAPU::op_decw_dp;
optbl[0x00] = &bAPU::op_nop;
optbl[0xef] = &bAPU::op_sleep;
optbl[0xff] = &bAPU::op_stop;
optbl[0x9f] = &bAPU::op_xcn;
optbl[0xdf] = &bAPU::op_daa;
optbl[0xbe] = &bAPU::op_das;
optbl[0x60] = &bAPU::op_clrc;
optbl[0x20] = &bAPU::op_clrp;
optbl[0x80] = &bAPU::op_setc;
optbl[0x40] = &bAPU::op_setp;
optbl[0xe0] = &bAPU::op_clrv;
optbl[0xed] = &bAPU::op_notc;
optbl[0xa0] = &bAPU::op_ei;
optbl[0xc0] = &bAPU::op_di;
optbl[0x02] = &bAPU::op_set0_dp;
optbl[0x12] = &bAPU::op_clr0_dp;
optbl[0x22] = &bAPU::op_set1_dp;
optbl[0x32] = &bAPU::op_clr1_dp;
optbl[0x42] = &bAPU::op_set2_dp;
optbl[0x52] = &bAPU::op_clr2_dp;
optbl[0x62] = &bAPU::op_set3_dp;
optbl[0x72] = &bAPU::op_clr3_dp;
optbl[0x82] = &bAPU::op_set4_dp;
optbl[0x92] = &bAPU::op_clr4_dp;
optbl[0xa2] = &bAPU::op_set5_dp;
optbl[0xb2] = &bAPU::op_clr5_dp;
optbl[0xc2] = &bAPU::op_set6_dp;
optbl[0xd2] = &bAPU::op_clr6_dp;
optbl[0xe2] = &bAPU::op_set7_dp;
optbl[0xf2] = &bAPU::op_clr7_dp;
optbl[0x0e] = &bAPU::op_tset_addr_a;
optbl[0x4e] = &bAPU::op_tclr_addr_a;
optbl[0x2d] = &bAPU::op_push_a;
optbl[0x4d] = &bAPU::op_push_x;
optbl[0x6d] = &bAPU::op_push_y;
optbl[0x0d] = &bAPU::op_push_p;
optbl[0xae] = &bAPU::op_pop_a;
optbl[0xce] = &bAPU::op_pop_x;
optbl[0xee] = &bAPU::op_pop_y;
optbl[0x8e] = &bAPU::op_pop_p;
optbl[0xcf] = &bAPU::op_mul_ya;
optbl[0x9e] = &bAPU::op_div_ya_x;

168
src/apu/bapu/bapugen.cpp Normal file
View File

@ -0,0 +1,168 @@
#include "../../lib/libbase.h"
#include "../../lib/libstring.h"
#include "../../lib/libstring.cpp"
FILE *fp, *fph, *fpt;
string data, line, part, subpart;
string output_table, output_header, output_op;
int op_count;
struct _op_list {
string name;
string arg;
}op_list[64];
int line_num;
void clear_op_list() {
op_count = 0;
for(int i=0;i<64;i++) {
strcpy(op_list[i].name, "");
for(int l=0;l<8;l++) {
strcpy(op_list[i].arg[l], "");
}
}
}
void gen_header() {
int i = line_num, l, n, z;
char t[4096];
clear_op_list();
while(1) {
z = op_count++;
strcpy(part, line[i]);
strrtrim(part, "),");
strrtrim(part, ") {");
split(subpart, "(", part);
strcpy(op_list[z].name, subpart[0]);
split(part, ", ", subpart[1]);
for(l=0;l<count(part);l++) {
strcpy(op_list[z].arg[l], part[l]);
}
if(!strend(line[i], " {"))break;
i++;
}
sprintf(output_op, "void bAPU::op_$$() {\r\n switch(status.cycle_pos++) {\r\n");
sprintf(output_header, "void op_$$();\r\n");
sprintf(output_table, "optbl[$0] = &bAPU::op_$$;\r\n");
line_num = i + 1;
}
void update_line(int i, int n) {
replace(line[i], "end;", "status.cycle_pos = 0;");
}
void gen_op() {
int i = line_num, n;
char t[4096];
while(1) {
if(!strcmp(line[i], "}"))break;
n = strdec(line[i]);
sprintf(t, "%d:", n);
strltrim(line[i], t);
sprintf(t, " case %d:\r\n", n);
strcat(output_op, t);
update_line(i, n);
if(strcmp(line[i], "")) {
strcat(output_op, " ");
strcat(output_op, line[i]);
strcat(output_op, "\r\n");
}
i++;
while(1) {
if((strptr(line[i])[1]) == ':' || (strptr(line[i])[2]) == ':' || !strcmp(line[i], "}"))break;
update_line(i, n);
strcat(output_op, " ");
strcat(output_op, line[i]);
strcat(output_op, "\r\n");
i++;
}
if(!strcmp(line[i], "}"))strcat(output_op, " status.cycle_pos = 0;\r\n");
strcat(output_op, " break;\r\n");
}
strcat(output_op, " }\r\n}");
line_num = i + 1;
}
void gen_final() {
string t;
int i, l;
for(i=0;i<op_count;i++) {
strcpy(t, output_op);
replace(t, "$$", op_list[i].name);
replace(t, "$0", op_list[i].arg[0]);
replace(t, "$1", op_list[i].arg[1]);
replace(t, "$2", op_list[i].arg[2]);
replace(t, "$3", op_list[i].arg[3]);
replace(t, "$4", op_list[i].arg[4]);
replace(t, "$5", op_list[i].arg[5]);
replace(t, "$6", op_list[i].arg[6]);
replace(t, "$7", op_list[i].arg[7]);
fprintf(fp, "%s\r\n\r\n", *t);
strcpy(t, output_header);
replace(t, "$$", op_list[i].name);
fprintf(fph, "%s", *t);
strcpy(t, output_table);
replace(t, "$$", op_list[i].name);
replace(t, "$0", op_list[i].arg[0]);
fprintf(fpt, "%s", *t);
}
}
void generate(char *dest, char *src) {
fp = fopen(src, "rb");
fseek(fp, 0, SEEK_END);
int fsize = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *buf = (char*)malloc(fsize + 1);
fread(buf, 1, fsize, fp);
fclose(fp);
buf[fsize] = 0;
strcpy(data, buf);
free(buf);
replace(data, "\r\n", "\n");
split(line, "\n", data);
fp = fopen(dest, "wb");
line_num = 0;
while(line_num < count(line)) {
while(!strcmp(line[line_num], "") && line_num < count(line))line_num++;
if(line_num >= count(line))break;
gen_header();
gen_op();
gen_final();
}
fclose(fp);
}
int main() {
fph = fopen("bapu_op.h", "wb");
fpt = fopen("bapu_optable.cpp", "wb");
generate("bapu_op_mov.cpp", "op_mov.b");
generate("bapu_op_pc.cpp", "op_pc.b");
generate("bapu_op_read.cpp", "op_read.b");
generate("bapu_op_rmw.cpp", "op_rmw.b");
generate("bapu_op_misc.cpp", "op_misc.b");
fclose(fph);
fclose(fpt);
return 0;
}

BIN
src/apu/bapu/bapugen.exe Normal file

Binary file not shown.

3
src/apu/bapu/cc.bat Normal file
View File

@ -0,0 +1,3 @@
cl /ML /O2 bapugen.cpp
@pause
@del *.obj

1
src/apu/bapu/clean.bat Normal file
View File

@ -0,0 +1 @@
@del *.exe

164
src/apu/bapu/op_misc.b Normal file
View File

@ -0,0 +1,164 @@
nop(0x00) {
1:
}
sleep(0xef),
stop(0xff) {
1:
2:regs.pc--;
}
xcn(0x9f) {
1:
2:
3:
4:regs.a = (regs.a >> 4) | (regs.a << 4);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
daa(0xdf) {
1:
2:if(regs.p.c || (regs.a) > 0x99) {
regs.a += 0x60;
regs.p.c = 1;
}
if(regs.p.h || (regs.a & 15) > 0x09) {
regs.a += 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
das(0xbe) {
1:
2:if(!regs.p.c || (regs.a) > 0x99) {
regs.a -= 0x60;
regs.p.c = 0;
}
if(!regs.p.h || (regs.a & 15) > 0x09) {
regs.a -= 0x06;
}
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
clrc(0x60, regs.p.c = 0),
clrp(0x20, regs.p.p = 0),
setc(0x80, regs.p.c = 1),
setp(0x40, regs.p.p = 1) {
1:$1;
}
clrv(0xe0) {
1:regs.p.v = 0;
regs.p.h = 0;
}
notc(0xed) {
1:
2:regs.p.c ^= 1;
}
ei(0xa0, 1),
di(0xc0, 0) {
1:
2:regs.p.i = $1;
}
set0_dp(0x02, rd |= 0x01),
clr0_dp(0x12, rd &= ~0x01),
set1_dp(0x22, rd |= 0x02),
clr1_dp(0x32, rd &= ~0x02),
set2_dp(0x42, rd |= 0x04),
clr2_dp(0x52, rd &= ~0x04),
set3_dp(0x62, rd |= 0x08),
clr3_dp(0x72, rd &= ~0x08),
set4_dp(0x82, rd |= 0x10),
clr4_dp(0x92, rd &= ~0x10),
set5_dp(0xa2, rd |= 0x20),
clr5_dp(0xb2, rd &= ~0x20),
set6_dp(0xc2, rd |= 0x40),
clr6_dp(0xd2, rd &= ~0x40),
set7_dp(0xe2, rd |= 0x80),
clr7_dp(0xf2, rd &= ~0x80) {
1:dp = op_read();
2:rd = op_read(OPMODE_DP, dp);
3:$1;
op_write(OPMODE_DP, dp, rd);
}
tset_addr_a(0x0e, |=),
tclr_addr_a(0x4e, &=~) {
1:dp = op_read();
2:dp |= op_read() << 8;
3:rd = op_read(OPMODE_ADDR, dp);
4:regs.p.n = !!((rd & regs.a) & 0x80);
regs.p.z = ((rd & regs.a) == 0);
rd $1 regs.a;
5:op_write(OPMODE_ADDR, dp, rd);
}
push_a(0x2d, a),
push_x(0x4d, x),
push_y(0x6d, y),
push_p(0x0d, p) {
1:
2:
3:stack_write(regs.$1);
}
pop_a(0xae, a),
pop_x(0xce, x),
pop_y(0xee, y),
pop_p(0x8e, p) {
1:
2:
3:regs.$1 = stack_read();
}
mul_ya(0xcf) {
1:
2:
3:
4:
5:
6:
7:
8:ya = regs.y * regs.a;
regs.a = ya;
regs.y = ya >> 8;
//result is set based on y (high-byte) only
regs.p.n = !!(regs.y & 0x80);
regs.p.z = (regs.y == 0);
}
div_ya_x(0x9e) {
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:ya = regs.ya;
//overflow set if quotient >= 256
regs.p.v = !!(regs.y >= regs.x);
regs.p.h = !!((regs.y & 15) >= (regs.x & 15));
if(regs.y < (regs.x << 1)) {
//if quotient is <= 511 (will fit into 9-bit result)
regs.a = ya / regs.x;
regs.y = ya % regs.x;
} else {
//otherwise, the quotient won't fit into regs.p.v + regs.a
//this emulates the odd behavior of the SPC700 in this case
regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x);
regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x);
}
//result is set based on a (quotient) only
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}

207
src/apu/bapu/op_mov.b Normal file
View File

@ -0,0 +1,207 @@
mov_a_x(0x7d, a, x),
mov_a_y(0xdd, a, y),
mov_x_a(0x5d, x, a),
mov_y_a(0xfd, y, a),
mov_x_sp(0x9d, x, sp),
mov_sp_x(0xbd, sp, x) {
1:regs.$1 = regs.$2;
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_const(0xe8, a),
mov_x_const(0xcd, x),
mov_y_const(0x8d, y) {
1:regs.$1 = op_read();
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_ix(0xe6) {
1:
2:regs.a = op_read(OPMODE_DP, regs.x);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_a_ixinc(0xbf) {
1:
2:
3:regs.a = op_read(OPMODE_DP, regs.x++);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_a_dp(0xe4, a),
mov_x_dp(0xf8, x),
mov_y_dp(0xeb, y) {
1:sp = op_read();
2:regs.$1 = op_read(OPMODE_DP, sp);
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_dpx(0xf4, a, x),
mov_x_dpy(0xf9, x, y),
mov_y_dpx(0xfb, y, x) {
1:sp = op_read();
2:
3:regs.$1 = op_read(OPMODE_DP, sp + regs.$2);
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_addr(0xe5, a),
mov_x_addr(0xe9, x),
mov_y_addr(0xec, y) {
1:sp = op_read();
2:sp |= op_read() << 8;
3:regs.$1 = op_read(OPMODE_ADDR, sp);
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_a_addrx(0xf5, x),
mov_a_addry(0xf6, y) {
1:sp = op_read();
2:sp |= op_read() << 8;
3:
4:regs.a = op_read(OPMODE_ADDR, sp + regs.$1);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_a_idpx(0xe7) {
1:dp = op_read() + regs.x;
2:
3:sp = op_read(OPMODE_DP, dp);
4:sp |= op_read(OPMODE_DP, dp + 1) << 8;
5:regs.a = op_read(OPMODE_ADDR, sp);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_a_idpy(0xf7) {
1:dp = op_read();
2:
3:sp = op_read(OPMODE_DP, dp);
4:sp |= op_read(OPMODE_DP, dp + 1) << 8;
5:regs.a = op_read(OPMODE_ADDR, sp + regs.y);
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
}
mov_dp_dp(0xfa) {
1:sp = op_read();
2:dp = op_read();
3:rd = op_read(OPMODE_DP, sp);
4:op_write(OPMODE_DP, dp, rd);
}
mov_dp_const(0x8f) {
1:rd = op_read();
2:dp = op_read();
3:
4:op_write(OPMODE_DP, dp, rd);
}
mov_ix_a(0xc6) {
1:
2:
3:op_write(OPMODE_DP, regs.x, regs.a);
}
mov_ixinc_a(0xaf) {
1:
2:
3:op_write(OPMODE_DP, regs.x++, regs.a);
}
mov_dp_a(0xc4, a),
mov_dp_x(0xd8, x),
mov_dp_y(0xcb, y) {
1:dp = op_read();
2:
3:op_write(OPMODE_DP, dp, regs.$1);
}
mov_dpx_a(0xd4, x, a),
mov_dpy_x(0xd9, y, x),
mov_dpx_y(0xdb, x, y) {
1:dp = op_read();
2:
3:
4:op_write(OPMODE_DP, dp + regs.$1, regs.$2);
}
mov_addr_a(0xc5, a),
mov_addr_x(0xc9, x),
mov_addr_y(0xcc, y) {
1:dp = op_read();
2:dp |= op_read() << 8;
3:
4:op_write(OPMODE_ADDR, dp, regs.$1);
}
mov_addrx_a(0xd5, x),
mov_addry_a(0xd6, y) {
1:dp = op_read();
2:dp |= op_read() << 8;
3:
4:
5:op_write(OPMODE_ADDR, dp + regs.$1, regs.a);
}
mov_idpx_a(0xc7) {
1:sp = op_read() + regs.x;
2:
3:dp = op_read(OPMODE_DP, sp);
4:dp |= op_read(OPMODE_DP, sp + 1) << 8;
5:
6:op_write(OPMODE_ADDR, dp, regs.a);
}
mov_idpy_a(0xd7) {
1:sp = op_read();
2:
3:dp = op_read(OPMODE_DP, sp);
4:dp |= op_read(OPMODE_DP, sp + 1) << 8;
5:
6:op_write(OPMODE_ADDR, dp + regs.y, regs.a);
}
movw_ya_dp(0xba) {
1:sp = op_read();
2:
3:regs.a = op_read(OPMODE_DP, sp);
4:regs.y = op_read(OPMODE_DP, sp + 1);
regs.p.n = !!(regs.ya & 0x8000);
regs.p.z = (regs.ya == 0);
}
movw_dp_ya(0xda) {
1:dp = op_read();
2:
3:op_write(OPMODE_DP, dp, regs.a);
4:op_write(OPMODE_DP, dp + 1, regs.y);
}
mov1_c_bit(0xaa) {
1:sp = op_read();
2:sp |= op_read() << 8;
3:bit = sp >> 13;
sp &= 0x1fff;
rd = op_read(OPMODE_ADDR, sp);
regs.p.c = !!(rd & (1 << bit));
}
mov1_bit_c(0xca) {
1:dp = op_read();
2:dp |= op_read() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_read(OPMODE_ADDR, dp);
if(regs.p.c)rd |= (1 << bit);
else rd &= ~(1 << bit);
4:op_write(OPMODE_ADDR, dp, rd);
}

157
src/apu/bapu/op_pc.b Normal file
View File

@ -0,0 +1,157 @@
bra(0x2f, 0),
beq(0xf0, !regs.p.z),
bne(0xd0, regs.p.z),
bcs(0xb0, !regs.p.c),
bcc(0x90, regs.p.c),
bvs(0x70, !regs.p.v),
bvc(0x50, regs.p.v),
bmi(0x30, !regs.p.n),
bpl(0x10, regs.p.n) {
1:rd = op_read();
if($1)end;
2:
3:regs.pc += (int8)rd;
}
bbs0(0x03, 0x01, !=),
bbc0(0x13, 0x01, ==),
bbs1(0x23, 0x02, !=),
bbc1(0x33, 0x02, ==),
bbs2(0x43, 0x04, !=),
bbc2(0x53, 0x04, ==),
bbs3(0x63, 0x08, !=),
bbc3(0x73, 0x08, ==),
bbs4(0x83, 0x10, !=),
bbc4(0x93, 0x10, ==),
bbs5(0xa3, 0x20, !=),
bbc5(0xb3, 0x20, ==),
bbs6(0xc3, 0x40, !=),
bbc6(0xd3, 0x40, ==),
bbs7(0xe3, 0x80, !=),
bbc7(0xf3, 0x80, ==) {
1:dp = op_read();
2:rd = op_read();
3:sp = op_read(OPMODE_DP, dp);
4:if((sp & $1) $2 $1)end;
5:
6:regs.pc += (int8)rd;
}
cbne_dp(0x2e, 0),
cbne_dpx(0xde, regs.x) {
1:dp = op_read();
2:rd = op_read();
3:sp = op_read(OPMODE_DP, dp + $1);
4:if(regs.a == sp)end;
5:
6:regs.pc += (int8)rd;
}
dbnz_dp(0x6e) {
1:dp = op_read();
2:rd = op_read();
3:wr = op_read(OPMODE_DP, dp);
4:wr--;
op_write(OPMODE_DP, dp, wr);
if(wr == 0x00)end;
5:
6:regs.pc += (int8)rd;
}
dbnz_y(0xfe) {
1:rd = op_read();
2:regs.y--;
3:if(regs.y == 0x00)end;
4:
5:regs.pc += (int8)rd;
}
jmp_addr(0x5f) {
1:rd = op_read();
2:rd |= op_read() << 8;
regs.pc = rd;
}
jmp_iaddrx(0x1f) {
1:dp = op_read();
2:dp |= op_read() << 8;
3:dp += regs.x;
4:rd = op_read(OPMODE_ADDR, dp);
5:rd |= op_read(OPMODE_ADDR, dp + 1) << 8;
regs.pc = rd;
}
call(0x3f) {
1:rd = op_read();
2:rd |= op_read() << 8;
3:
4:
5:
6:stack_write(regs.pc >> 8);
7:stack_write(regs.pc);
regs.pc = rd;
}
pcall(0x4f) {
1:rd = op_read();
2:
3:
4:stack_write(regs.pc >> 8);
5:stack_write(regs.pc);
regs.pc = 0xff00 | rd;
}
tcall_0(0x01, 0),
tcall_1(0x11, 1),
tcall_2(0x21, 2),
tcall_3(0x31, 3),
tcall_4(0x41, 4),
tcall_5(0x51, 5),
tcall_6(0x61, 6),
tcall_7(0x71, 7),
tcall_8(0x81, 8),
tcall_9(0x91, 9),
tcall_10(0xa1, 10),
tcall_11(0xb1, 11),
tcall_12(0xc1, 12),
tcall_13(0xd1, 13),
tcall_14(0xe1, 14),
tcall_15(0xf1, 15) {
1:dp = 0xffde - ($1 << 1);
rd = op_read(OPMODE_ADDR, dp);
2:rd |= op_read(OPMODE_ADDR, dp + 1) << 8;
3:
4:
5:
6:stack_write(regs.pc >> 8);
7:stack_write(regs.pc);
regs.pc = rd;
}
brk(0x0f) {
1:rd = op_read(OPMODE_ADDR, 0xffde);
2:rd |= op_read(OPMODE_ADDR, 0xffdf) << 8;
3:
4:
5:stack_write(regs.pc >> 8);
6:stack_write(regs.pc);
7:stack_write(regs.p);
regs.pc = rd;
regs.p.b = 1;
regs.p.i = 0;
}
ret(0x6f) {
1:rd = stack_read();
2:rd |= stack_read() << 8;
3:
4:regs.pc = rd;
}
reti(0x7f) {
1:regs.p = stack_read();
2:rd = stack_read();
3:rd |= stack_read() << 8;
4:
5:regs.pc = rd;
}

194
src/apu/bapu/op_read.b Normal file
View File

@ -0,0 +1,194 @@
adc_a_const(0x88, adc, a),
and_a_const(0x28, and, a),
cmp_a_const(0x68, cmp, a),
cmp_x_const(0xc8, cmp, x),
cmp_y_const(0xad, cmp, y),
eor_a_const(0x48, eor, a),
or_a_const(0x08, or, a),
sbc_a_const(0xa8, sbc, a) {
1:rd = op_read();
regs.$2 = op_$1(regs.$2, rd);
}
adc_a_ix(0x86, adc),
and_a_ix(0x26, and),
cmp_a_ix(0x66, cmp),
eor_a_ix(0x46, eor),
or_a_ix(0x06, or),
sbc_a_ix(0xa6, sbc) {
1:rd = op_read(OPMODE_DP, regs.x);
2:regs.a = op_$1(regs.a, rd);
}
adc_a_dp(0x84, adc, a),
and_a_dp(0x24, and, a),
cmp_a_dp(0x64, cmp, a),
cmp_x_dp(0x3e, cmp, x),
cmp_y_dp(0x7e, cmp, y),
eor_a_dp(0x44, eor, a),
or_a_dp(0x04, or, a),
sbc_a_dp(0xa4, sbc, a) {
1:dp = op_read();
2:rd = op_read(OPMODE_DP, dp);
regs.$2 = op_$1(regs.$2, rd);
}
adc_a_dpx(0x94, adc),
and_a_dpx(0x34, and),
cmp_a_dpx(0x74, cmp),
eor_a_dpx(0x54, eor),
or_a_dpx(0x14, or),
sbc_a_dpx(0xb4, sbc) {
1:dp = op_read();
2:
3:rd = op_read(OPMODE_DP, dp + regs.x);
regs.a = op_$1(regs.a, rd);
}
adc_a_addr(0x85, adc, a),
and_a_addr(0x25, and, a),
cmp_a_addr(0x65, cmp, a),
cmp_x_addr(0x1e, cmp, x),
cmp_y_addr(0x5e, cmp, y),
eor_a_addr(0x45, eor, a),
or_a_addr(0x05, or, a),
sbc_a_addr(0xa5, sbc, a) {
1:dp = op_read();
2:dp |= op_read() << 8;
3:rd = op_read(OPMODE_ADDR, dp);
regs.$2 = op_$1(regs.$2, rd);
}
adc_a_addrx(0x95, adc, x),
adc_a_addry(0x96, adc, y),
and_a_addrx(0x35, and, x),
and_a_addry(0x36, and, y),
cmp_a_addrx(0x75, cmp, x),
cmp_a_addry(0x76, cmp, y),
eor_a_addrx(0x55, eor, x),
eor_a_addry(0x56, eor, y),
or_a_addrx(0x15, or, x),
or_a_addry(0x16, or, y),
sbc_a_addrx(0xb5, sbc, x),
sbc_a_addry(0xb6, sbc, y) {
1:dp = op_read();
2:dp |= op_read() << 8;
3:
4:rd = op_read(OPMODE_ADDR, dp + regs.$2);
regs.a = op_$1(regs.a, rd);
}
adc_a_idpx(0x87, adc),
and_a_idpx(0x27, and),
cmp_a_idpx(0x67, cmp),
eor_a_idpx(0x47, eor),
or_a_idpx(0x07, or),
sbc_a_idpx(0xa7, sbc) {
1:dp = op_read() + regs.x;
2:
3:sp = op_read(OPMODE_DP, dp);
4:sp |= op_read(OPMODE_DP, dp + 1) << 8;
5:rd = op_read(OPMODE_ADDR, sp);
regs.a = op_$1(regs.a, rd);
}
adc_a_idpy(0x97, adc),
and_a_idpy(0x37, and),
cmp_a_idpy(0x77, cmp),
eor_a_idpy(0x57, eor),
or_a_idpy(0x17, or),
sbc_a_idpy(0xb7, sbc) {
1:dp = op_read();
2:
3:sp = op_read(OPMODE_DP, dp);
4:sp |= op_read(OPMODE_DP, dp + 1) << 8;
5:rd = op_read(OPMODE_ADDR, sp + regs.y);
regs.a = op_$1(regs.a, rd);
}
adc_ix_iy(0x99, adc, 1),
and_ix_iy(0x39, and, 1),
cmp_ix_iy(0x79, cmp, 0),
eor_ix_iy(0x59, eor, 1),
or_ix_iy(0x19, or, 1),
sbc_ix_iy(0xb9, sbc, 1) {
1:wr = op_read(OPMODE_DP, regs.x);
2:rd = op_read(OPMODE_DP, regs.y);
3:wr = op_$1(wr, rd);
4:if($2)op_write(OPMODE_DP, regs.x, wr);
}
adc_dp_dp(0x89, adc, 1),
and_dp_dp(0x29, and, 1),
cmp_dp_dp(0x69, cmp, 0),
eor_dp_dp(0x49, eor, 1),
or_dp_dp(0x09, or, 1),
sbc_dp_dp(0xa9, sbc, 1) {
1:sp = op_read();
2:dp = op_read();
3:wr = op_read(OPMODE_DP, dp);
4:rd = op_read(OPMODE_DP, sp);
5:wr = op_$1(wr, rd);
if($2)op_write(OPMODE_DP, dp, wr);
}
adc_dp_const(0x98, adc, 1),
and_dp_const(0x38, and, 1),
cmp_dp_const(0x78, cmp, 0),
eor_dp_const(0x58, eor, 1),
or_dp_const(0x18, or, 1),
sbc_dp_const(0xb8, sbc, 1) {
1:rd = op_read();
2:dp = op_read();
3:wr = op_read(OPMODE_DP, dp);
4:wr = op_$1(wr, rd);
if($2)op_write(OPMODE_DP, dp, wr);
}
addw_ya_dp(0x7a, addw),
cmpw_ya_dp(0x5a, cmpw),
subw_ya_dp(0x9a, subw) {
1:dp = op_read();
2:rd = op_read(OPMODE_DP, dp);
3:rd |= op_read(OPMODE_DP, dp + 1) << 8;
4:regs.ya = op_$1(regs.ya, rd);
}
and1_bit(0x4a, !!),
and1_notbit(0x6a, !) {
1:dp = op_read();
2:dp |= op_read() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_read(OPMODE_ADDR, dp);
regs.p.c = regs.p.c & $1(rd & (1 << bit));
}
eor1_bit(0x8a) {
1:dp = op_read();
2:dp |= op_read() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_read(OPMODE_ADDR, dp);
4:regs.p.c = regs.p.c ^ !!(rd & (1 << bit));
}
not1_bit(0xea) {
1:dp = op_read();
2:dp |= op_read() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_read(OPMODE_ADDR, dp);
rd ^= (1 << bit);
4:op_write(OPMODE_ADDR, dp, rd);
}
or1_bit(0x0a, !!),
or1_notbit(0x2a, !) {
1:dp = op_read();
2:dp |= op_read() << 8;
3:bit = dp >> 13;
dp &= 0x1fff;
rd = op_read(OPMODE_ADDR, dp);
4:regs.p.c = regs.p.c | $1(rd & (1 << bit));
}

60
src/apu/bapu/op_rmw.b Normal file
View File

@ -0,0 +1,60 @@
inc_a(0xbc, inc, a),
inc_x(0x3d, inc, x),
inc_y(0xfc, inc, y),
dec_a(0x9c, dec, a),
dec_x(0x1d, dec, x),
dec_y(0xdc, dec, y),
asl_a(0x1c, asl, a),
lsr_a(0x5c, lsr, a),
rol_a(0x3c, rol, a),
ror_a(0x7c, ror, a) {
1:regs.$2 = op_$1(regs.$2);
}
inc_dp(0xab, inc),
dec_dp(0x8b, dec),
asl_dp(0x0b, asl),
lsr_dp(0x4b, lsr),
rol_dp(0x2b, rol),
ror_dp(0x6b, ror) {
1:dp = op_read();
2:rd = op_read(OPMODE_DP, dp);
3:rd = op_$1(rd);
op_write(OPMODE_DP, dp, rd);
}
inc_dpx(0xbb, inc),
dec_dpx(0x9b, dec),
asl_dpx(0x1b, asl),
lsr_dpx(0x5b, lsr),
rol_dpx(0x3b, rol),
ror_dpx(0x7b, ror) {
1:dp = op_read();
2:
3:rd = op_read(OPMODE_DP, dp + regs.x);
4:rd = op_$1(rd);
op_write(OPMODE_DP, dp + regs.x, rd);
}
inc_addr(0xac, inc),
dec_addr(0x8c, dec),
asl_addr(0x0c, asl),
lsr_addr(0x4c, lsr),
rol_addr(0x2c, rol),
ror_addr(0x6c, ror) {
1:dp = op_read();
2:dp |= op_read() << 8;
3:rd = op_read(OPMODE_ADDR, dp);
4:rd = op_$1(rd);
op_write(OPMODE_ADDR, dp, rd);
}
incw_dp(0x3a, incw),
decw_dp(0x1a, decw) {
1:dp = op_read();
2:rd = op_read(OPMODE_DP, dp);
3:rd |= op_read(OPMODE_DP, dp + 1) << 8;
4:rd = op_$1(rd);
op_write(OPMODE_DP, dp + 1, rd >> 8);
5:op_write(OPMODE_DP, dp, rd);
}

View File

@ -0,0 +1,171 @@
#include "../../base.h"
uint8 bAPUSkip::spcram_read (uint16 addr) { return 0xff; }
void bAPUSkip::spcram_write(uint16 addr, uint8 value) {}
/*
This routine is very serious. It will eat holes through
the ROM to skip APU test conditions. Or in other words,
it will disable and/or force branches when neccesary.
It can very easily break or corrupt a game and prevent it
from being playable until the ROM is reloaded (ROM writes
are only performed in memory, of course).
However, this kind of brute force approach is required to
get many games playable without proper SPC700 emulation.
*/
uint8 bAPUSkip::port_read(uint8 port) {
port &= 3;
_apu_port *p = &apu_port[port];
int i, x, y, z, t;
uint32 addr;
addr = cpu->regs.pc.d;
p->read_addr[p->read_pos & 31] = addr;
//- lda $214x
// cmp $214x
// bne -
// cmp ???
// beq/bne -
__test1:
//look for an lda/cmp read pattern
if(addr == p->read_addr[(p->read_pos - 1) & 31])goto __test2;
if(addr != p->read_addr[(p->read_pos - 2) & 31])goto __test2;
if(addr == p->read_addr[(p->read_pos - 3) & 31])goto __test2;
if(addr != p->read_addr[(p->read_pos - 4) & 31])goto __test2;
if(p->read_addr[(p->read_pos - 1) & 31] != p->read_addr[(p->read_pos - 3) & 31])goto __test2;
//try and find compare opcode
for(i=0;i<24;i++) {
x = mem_bus->read(addr + i);
if(x == OP_CMP_CONST || x == OP_CPX_CONST || x == OP_CPY_CONST)break;
if(x == OP_CMP_ADDR || x == OP_CPX_ADDR || x == OP_CPY_ADDR) break;
if(x == OP_CMP_LONG)break;
}
if(i == 24)goto __test2;
//seek to next opcode
if(x == OP_CMP_CONST) {
i += (cpu->regs.p.m)?2:3;
} else if(x == OP_CPX_CONST || x == OP_CPY_CONST) {
i += (cpu->regs.p.x)?2:3;
} else if(x == OP_CMP_ADDR || x == OP_CPX_ADDR || x == OP_CPY_ADDR) {
i += 3;
} else { //(x == OP_CMP_LONG) {
i += 4;
}
x = mem_bus->read(addr + i);
if(x == OP_BNE) {
mem_bus->cart->write_protect(false);
mem_bus->write(addr + i, OP_NOP);
mem_bus->write(addr + i + 1, OP_NOP);
mem_bus->cart->write_protect(true);
} else if(x == OP_BEQ) {
mem_bus->cart->write_protect(false);
mem_bus->write(addr + i, OP_BRA);
mem_bus->cart->write_protect(true);
} else goto __test2;
goto __pass;
//- lda $214x
// cmp ???
// beq/bne -
__test2:
//look for a repeated read pattern
if(addr != p->read_addr[(p->read_pos - 1) & 31])goto __test3;
if(addr != p->read_addr[(p->read_pos - 2) & 31])goto __test3;
if(addr != p->read_addr[(p->read_pos - 3) & 31])goto __test3;
if(addr != p->read_addr[(p->read_pos - 4) & 31])goto __test3;
if(addr != p->read_addr[(p->read_pos - 5) & 31])goto __test3;
if(addr != p->read_addr[(p->read_pos - 6) & 31])goto __test3;
if(addr != p->read_addr[(p->read_pos - 7) & 31])goto __test3;
if(addr != p->read_addr[(p->read_pos - 8) & 31])goto __test3;
//try and find compare opcode
for(i=0;i<24;i++) {
x = mem_bus->read(addr + i);
if(x == OP_CMP_CONST || x == OP_CPX_CONST || x == OP_CPY_CONST)break;
if(x == OP_CMP_ADDR || x == OP_CPX_ADDR || x == OP_CPY_ADDR) break;
if(x == OP_CMP_LONG)break;
}
if(i == 24)goto __test3;
//seek to next opcode
if(x == OP_CMP_CONST) {
i += (cpu->regs.p.m)?2:3;
} else if(x == OP_CPX_CONST || x == OP_CPY_CONST) {
i += (cpu->regs.p.x)?2:3;
} else if(x == OP_CMP_ADDR || x == OP_CPX_ADDR || x == OP_CPY_ADDR) {
i += 3;
} else if(x == OP_CMP_LONG) {
i += 4;
}
x = mem_bus->read(addr + i);
if(x == OP_BNE) {
mem_bus->cart->write_protect(false);
mem_bus->write(addr + i, OP_NOP);
mem_bus->write(addr + i + 1, OP_NOP);
mem_bus->cart->write_protect(true);
} else if(x == OP_BEQ) {
mem_bus->cart->write_protect(false);
mem_bus->write(addr + i, OP_BRA);
mem_bus->cart->write_protect(true);
} else goto __test3;
goto __pass;
//fallback
__test3:
if(p->pos < 4) {
if(!(port & 1)) {
p->value = cpu->regs.a.l;
} else {
p->value = cpu->regs.a.h;
}
} else if(p->pos < 8) {
if(!(port & 1)) {
p->value = cpu->regs.x.l;
} else {
p->value = cpu->regs.x.h;
}
} else if(p->pos < 12) {
if(!(port & 1)) {
p->value = cpu->regs.y.l;
} else {
p->value = cpu->regs.y.h;
}
} else if(p->pos < 16) {
p->value = rand();
}
if(++p->pos == 16)p->pos = 0;
__pass:
p->read_pos++;
p->read_pos &= 31;
return p->value;
}
void bAPUSkip::port_write(uint8 port, uint8 value) {
port &= 3;
apu_port[port].value = value;
}
void bAPUSkip::run() {
snes->notify(SNES::APU_EXEC_OPCODE_BEGIN);
snes->notify(SNES::APU_EXEC_OPCODE_END);
}
void bAPUSkip::power() {
reset();
}
void bAPUSkip::reset() {
regs.a = 0x00;
regs.x = 0x00;
regs.y = 0x00;
regs.sp = 0x00;
regs.p = 0x02;
regs.pc = 0xffc0;
memset(&apu_port[0], 0, sizeof(_apu_port));
memset(&apu_port[1], 0, sizeof(_apu_port));
memset(&apu_port[2], 0, sizeof(_apu_port));
memset(&apu_port[3], 0, sizeof(_apu_port));
}

View File

@ -0,0 +1,33 @@
class bAPUSkip : public APU {
public:
struct _apu_port {
uint8 value;
uint8 step, pos;
uint32 read_addr[32], read_pos;
}apu_port[4];
enum {
OP_CMP_CONST = 0xc9,
OP_CPX_CONST = 0xe0,
OP_CPY_CONST = 0xc0,
OP_CMP_ADDR = 0xcd,
OP_CPX_ADDR = 0xec,
OP_CPY_ADDR = 0xcc,
OP_CMP_LONG = 0xcf,
OP_BNE = 0xd0,
OP_BEQ = 0xf0,
OP_BRA = 0x80,
OP_NOP = 0xea
};
uint8 spcram_read (uint16 addr);
void spcram_write(uint16 addr, uint8 value);
uint8 port_read (uint8 port);
void port_write (uint8 port, uint8 value);
void run();
uint32 cycles_executed() { return 12 * 24; }
void power();
void reset();
};

295
src/apu/dapu.cpp Normal file
View File

@ -0,0 +1,295 @@
uint16 APU::__relb(int8 offset, int op_len) {
uint16 pc = regs.pc + op_len;
return pc + offset;
}
void APU::disassemble_opcode(char *output) {
char *s = output, t[512];
uint8 op, op0, op1;
uint16 opw, opdp0, opdp1;
sprintf(s, "..%0.4x ", regs.pc);
op = spcram_read(regs.pc);
op0 = spcram_read(regs.pc + 1);
op1 = spcram_read(regs.pc + 2);
opw = (op0) | (op1 << 8);
opdp0 = ((regs.p.p)?0x100:0x000) + op0;
opdp1 = ((regs.p.p)?0x100:0x000) + op1;
strcpy(t, " ");
switch(op) {
case 0x00:sprintf(t, "nop"); break;
case 0x01:sprintf(t, "tcall 0"); break;
case 0x02:sprintf(t, "set0 $%0.3x", opdp0); break;
case 0x03:sprintf(t, "bbs0 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0x04:sprintf(t, "or a,$%0.3x", opdp0); break;
case 0x05:sprintf(t, "or a,$%0.4x", opw); break;
case 0x06:sprintf(t, "or a,(x)"); break;
case 0x07:sprintf(t, "or a,($%0.3x+x)", opdp0); break;
case 0x08:sprintf(t, "or a,#$%0.2x", op0); break;
case 0x09:sprintf(t, "or $%0.3x,$%0.3x", opdp1, opdp0); break;
case 0x0a:sprintf(t, "or1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break;
case 0x0b:sprintf(t, "asl $%0.3x", opdp0); break;
case 0x0c:sprintf(t, "asl $%0.4x", opw); break;
case 0x0d:sprintf(t, "push p"); break;
case 0x0e:sprintf(t, "tset $%0.4x,a", opw); break;
case 0x0f:sprintf(t, "brk"); break;
case 0x10:sprintf(t, "bpl $%0.4x", __relb(op0, 2)); break;
case 0x11:sprintf(t, "tcall 1"); break;
case 0x12:sprintf(t, "clr0 $%0.3x", opdp0); break;
case 0x13:sprintf(t, "bbc0 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0x14:sprintf(t, "or a,$%0.3x+x", opdp0); break;
case 0x15:sprintf(t, "or a,$%0.4x+x", opw); break;
case 0x16:sprintf(t, "or a,$%0.4x+y", opw); break;
case 0x17:sprintf(t, "or a,($%0.3x)+y", opdp0); break;
case 0x18:sprintf(t, "or $%0.3x,#$%0.2x", opdp1, op0); break;
case 0x19:sprintf(t, "or (x),(y)"); break;
case 0x1a:sprintf(t, "decw $%0.3x", opdp0); break;
case 0x1b:sprintf(t, "asl $%0.3x+x", opdp0); break;
case 0x1c:sprintf(t, "asl a"); break;
case 0x1d:sprintf(t, "dec x"); break;
case 0x1e:sprintf(t, "cmp x,$%0.4x", opw); break;
case 0x1f:sprintf(t, "jmp ($%0.4x+x)", opw); break;
case 0x20:sprintf(t, "clrp"); break;
case 0x21:sprintf(t, "tcall 2"); break;
case 0x22:sprintf(t, "set1 $%0.3x", opdp0); break;
case 0x23:sprintf(t, "bbs1 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0x24:sprintf(t, "and a,$%0.3x", opdp0); break;
case 0x25:sprintf(t, "and a,$%0.4x", opw); break;
case 0x26:sprintf(t, "and a,(x)"); break;
case 0x27:sprintf(t, "and a,($%0.3x+x)", opdp0); break;
case 0x28:sprintf(t, "and a,#$%0.2x", op0); break;
case 0x29:sprintf(t, "and $%0.3x,$%0.3x", opdp1, opdp0); break;
case 0x2a:sprintf(t, "or1 c,!$%0.4x:%d", opw & 0x1fff, opw >> 13); break;
case 0x2b:sprintf(t, "rol $%0.3x", opdp0); break;
case 0x2c:sprintf(t, "rol $%0.4x", opw); break;
case 0x2d:sprintf(t, "push a"); break;
case 0x2e:sprintf(t, "cbne $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0x2f:sprintf(t, "bra $%0.4x", __relb(op0, 2)); break;
case 0x30:sprintf(t, "bmi $%0.4x", __relb(op0, 2)); break;
case 0x31:sprintf(t, "tcall 3"); break;
case 0x32:sprintf(t, "clr1 $%0.3x", opdp0); break;
case 0x33:sprintf(t, "bbc1 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0x34:sprintf(t, "and a,$%0.3x+x", opdp0); break;
case 0x35:sprintf(t, "and a,$%0.4x+x", opw); break;
case 0x36:sprintf(t, "and a,$%0.4x+y", opw); break;
case 0x37:sprintf(t, "and a,($%0.3x)+y", opdp0); break;
case 0x38:sprintf(t, "and $%0.3x,#$%0.2x", opdp1, op0); break;
case 0x39:sprintf(t, "and (x),(y)"); break;
case 0x3a:sprintf(t, "incw $%0.3x", opdp0); break;
case 0x3b:sprintf(t, "rol $%0.3x+x", opdp0); break;
case 0x3c:sprintf(t, "rol a"); break;
case 0x3d:sprintf(t, "inc x"); break;
case 0x3e:sprintf(t, "cmp x,$%0.3x", opdp0); break;
case 0x3f:sprintf(t, "call $%0.4x", opw); break;
case 0x40:sprintf(t, "setp"); break;
case 0x41:sprintf(t, "tcall 4"); break;
case 0x42:sprintf(t, "set2 $%0.3x", opdp0); break;
case 0x43:sprintf(t, "bbs2 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0x44:sprintf(t, "eor a,$%0.3x", opdp0); break;
case 0x45:sprintf(t, "eor a,$%0.4x", opw); break;
case 0x46:sprintf(t, "eor a,(x)"); break;
case 0x47:sprintf(t, "eor a,($%0.3x+x)", opdp0); break;
case 0x48:sprintf(t, "eor a,#$%0.2x", op0); break;
case 0x49:sprintf(t, "eor $%0.3x,$%0.3x", opdp1, opdp0); break;
case 0x4a:sprintf(t, "and1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break;
case 0x4b:sprintf(t, "lsr $%0.3x", opdp0); break;
case 0x4c:sprintf(t, "lsr $%0.4x", opw); break;
case 0x4d:sprintf(t, "push x"); break;
case 0x4e:sprintf(t, "tclr $%0.4x,a", opw); break;
case 0x4f:sprintf(t, "pcall $ff%0.2x", op0); break;
case 0x50:sprintf(t, "bvc $%0.4x", __relb(op0, 2)); break;
case 0x51:sprintf(t, "tcall 5"); break;
case 0x52:sprintf(t, "clr2 $%0.3x", opdp0); break;
case 0x53:sprintf(t, "bbc2 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0x54:sprintf(t, "eor a,$%0.3x+x", opdp0); break;
case 0x55:sprintf(t, "eor a,$%0.4x+x", opw); break;
case 0x56:sprintf(t, "eor a,$%0.4x+y", opw); break;
case 0x57:sprintf(t, "eor a,($%0.3x)+y", opdp0); break;
case 0x58:sprintf(t, "eor $%0.3x,#$%0.2x", opdp1, op0); break;
case 0x59:sprintf(t, "eor (x),(y)"); break;
case 0x5a:sprintf(t, "cmpw ya,$%0.3x", opdp0); break;
case 0x5b:sprintf(t, "lsr $%0.3x+x", opdp0); break;
case 0x5c:sprintf(t, "lsr a"); break;
case 0x5d:sprintf(t, "mov x,a"); break;
case 0x5e:sprintf(t, "cmp y,$%0.4x", opw); break;
case 0x5f:sprintf(t, "jmp $%0.4x", opw); break;
case 0x60:sprintf(t, "clrc"); break;
case 0x61:sprintf(t, "tcall 6"); break;
case 0x62:sprintf(t, "set3 $%0.3x", opdp0); break;
case 0x63:sprintf(t, "bbs3 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0x64:sprintf(t, "cmp a,$%0.3x", opdp0); break;
case 0x65:sprintf(t, "cmp a,$%0.4x", opw); break;
case 0x66:sprintf(t, "cmp a,(x)"); break;
case 0x67:sprintf(t, "cmp a,($%0.3x+x)", opdp0); break;
case 0x68:sprintf(t, "cmp a,#$%0.2x", op0); break;
case 0x69:sprintf(t, "cmp $%0.3x,$%0.3x", opdp1, opdp0); break;
case 0x6a:sprintf(t, "and1 c,!$%0.4x:%d", opw & 0x1fff, opw >> 13); break;
case 0x6b:sprintf(t, "ror $%0.3x", opdp0); break;
case 0x6c:sprintf(t, "ror $%0.4x", opw); break;
case 0x6d:sprintf(t, "push y"); break;
case 0x6e:sprintf(t, "dbnz $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0x6f:sprintf(t, "ret"); break;
case 0x70:sprintf(t, "bvs $%0.4x", __relb(op0, 2)); break;
case 0x71:sprintf(t, "tcall 7"); break;
case 0x72:sprintf(t, "clr3 $%0.3x", opdp0); break;
case 0x73:sprintf(t, "bbc3 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0x74:sprintf(t, "cmp a,$%0.3x+x", opdp0); break;
case 0x75:sprintf(t, "cmp a,$%0.4x+x", opw); break;
case 0x76:sprintf(t, "cmp a,$%0.4x+y", opw); break;
case 0x77:sprintf(t, "cmp a,($%0.3x)+y", opdp0); break;
case 0x78:sprintf(t, "cmp $%0.3x,#$%0.2x", opdp1, op0); break;
case 0x79:sprintf(t, "cmp (x),(y)"); break;
case 0x7a:sprintf(t, "addw ya,$%0.3x", opdp0); break;
case 0x7b:sprintf(t, "ror $%0.3x+x", opdp0); break;
case 0x7c:sprintf(t, "ror a"); break;
case 0x7d:sprintf(t, "mov a,x"); break;
case 0x7e:sprintf(t, "cmp y,$%0.3x", opdp0); break;
case 0x7f:sprintf(t, "reti"); break;
case 0x80:sprintf(t, "setc"); break;
case 0x81:sprintf(t, "tcall 8"); break;
case 0x82:sprintf(t, "set4 $%0.3x", opdp0); break;
case 0x83:sprintf(t, "bbs4 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0x84:sprintf(t, "adc a,$%0.3x", opdp0); break;
case 0x85:sprintf(t, "adc a,$%0.4x", opw); break;
case 0x86:sprintf(t, "adc a,(x)"); break;
case 0x87:sprintf(t, "adc a,($%0.3x+x)", opdp0); break;
case 0x88:sprintf(t, "adc a,#$%0.2x", op0); break;
case 0x89:sprintf(t, "adc $%0.3x,$%0.3x", opdp1, opdp0); break;
case 0x8a:sprintf(t, "eor1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break;
case 0x8b:sprintf(t, "dec $%0.3x", opdp0); break;
case 0x8c:sprintf(t, "dec $%0.4x", opw); break;
case 0x8d:sprintf(t, "mov y,#$%0.2x", op0); break;
case 0x8e:sprintf(t, "pop p"); break;
case 0x8f:sprintf(t, "mov $%0.3x,#$%0.2x", opdp1, op0); break;
case 0x90:sprintf(t, "bcc $%0.4x", __relb(op0, 2)); break;
case 0x91:sprintf(t, "tcall 9"); break;
case 0x92:sprintf(t, "clr4 $%0.3x", opdp0); break;
case 0x93:sprintf(t, "bbc4 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0x94:sprintf(t, "adc a,$%0.3x+x", opdp0); break;
case 0x95:sprintf(t, "adc a,$%0.4x+x", opw); break;
case 0x96:sprintf(t, "adc a,$%0.4x+y", opw); break;
case 0x97:sprintf(t, "adc a,($%0.3x)+y", opdp0); break;
case 0x98:sprintf(t, "adc $%0.3x,#$%0.2x", opdp1, op0); break;
case 0x99:sprintf(t, "adc (x),(y)"); break;
case 0x9a:sprintf(t, "subw ya,$%0.3x", opdp0); break;
case 0x9b:sprintf(t, "dec $%0.3x+x", opdp0); break;
case 0x9c:sprintf(t, "dec a"); break;
case 0x9d:sprintf(t, "mov x,sp"); break;
case 0x9e:sprintf(t, "div ya,x"); break;
case 0x9f:sprintf(t, "xcn a"); break;
case 0xa0:sprintf(t, "ei"); break;
case 0xa1:sprintf(t, "tcall 10"); break;
case 0xa2:sprintf(t, "set5 $%0.3x", opdp0); break;
case 0xa3:sprintf(t, "bbs5 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0xa4:sprintf(t, "sbc a,$%0.3x", opdp0); break;
case 0xa5:sprintf(t, "sbc a,$%0.4x", opw); break;
case 0xa6:sprintf(t, "sbc a,(x)"); break;
case 0xa7:sprintf(t, "sbc a,($%0.3x+x)", opdp0); break;
case 0xa8:sprintf(t, "sbc a,#$%0.2x", op0); break;
case 0xa9:sprintf(t, "sbc $%0.3x,$%0.3x", opdp1, opdp0); break;
case 0xaa:sprintf(t, "mov1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break;
case 0xab:sprintf(t, "inc $%0.3x", opdp0); break;
case 0xac:sprintf(t, "inc $%0.4x", opw); break;
case 0xad:sprintf(t, "cmp y,#$%0.2x", op0); break;
case 0xae:sprintf(t, "pop a"); break;
case 0xaf:sprintf(t, "mov (x)+,a"); break;
case 0xb0:sprintf(t, "bcs $%0.4x", __relb(op0, 2)); break;
case 0xb1:sprintf(t, "tcall 11"); break;
case 0xb2:sprintf(t, "clr5 $%0.3x", opdp0); break;
case 0xb3:sprintf(t, "bbc5 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0xb4:sprintf(t, "sbc a,$%0.3x+x", opdp0); break;
case 0xb5:sprintf(t, "sbc a,$%0.4x+x", opw); break;
case 0xb6:sprintf(t, "sbc a,$%0.4x+y", opw); break;
case 0xb7:sprintf(t, "sbc a,($%0.3x)+y", opdp0); break;
case 0xb8:sprintf(t, "sbc $%0.3x,#$%0.2x", opdp1, op0); break;
case 0xb9:sprintf(t, "sbc (x),(y)"); break;
case 0xba:sprintf(t, "movw ya,$%0.3x", opdp0); break;
case 0xbb:sprintf(t, "inc $%0.3x+x", opdp0); break;
case 0xbc:sprintf(t, "inc a"); break;
case 0xbd:sprintf(t, "mov sp,x"); break;
case 0xbe:sprintf(t, "das a"); break;
case 0xbf:sprintf(t, "mov a,(x)+"); break;
case 0xc0:sprintf(t, "di"); break;
case 0xc1:sprintf(t, "tcall 12"); break;
case 0xc2:sprintf(t, "set6 $%0.3x", opdp0); break;
case 0xc3:sprintf(t, "bbs6 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0xc4:sprintf(t, "mov $%0.3x,a", opdp0); break;
case 0xc5:sprintf(t, "mov $%0.4x,a", opw); break;
case 0xc6:sprintf(t, "mov (x),a"); break;
case 0xc7:sprintf(t, "mov ($%0.3x+x),a", opdp0); break;
case 0xc8:sprintf(t, "cmp x,#$%0.2x", op0); break;
case 0xc9:sprintf(t, "mov $%0.4x,x", opw); break;
case 0xca:sprintf(t, "mov1 $%0.4x:%d,c", opw & 0x1fff, opw >> 13); break;
case 0xcb:sprintf(t, "mov $%0.3x,y", opdp0); break;
case 0xcc:sprintf(t, "mov $%0.4x,y", opw); break;
case 0xcd:sprintf(t, "mov x,#$%0.2x", op0); break;
case 0xce:sprintf(t, "pop x"); break;
case 0xcf:sprintf(t, "mul ya"); break;
case 0xd0:sprintf(t, "bne $%0.4x", __relb(op0, 2)); break;
case 0xd1:sprintf(t, "tcall 13"); break;
case 0xd2:sprintf(t, "clr6 $%0.3x", opdp0); break;
case 0xd3:sprintf(t, "bbc6 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0xd4:sprintf(t, "mov $%0.3x+x,a", opdp0); break;
case 0xd5:sprintf(t, "mov $%0.4x+x,a", opw); break;
case 0xd6:sprintf(t, "mov $%0.4x+y,a", opw); break;
case 0xd7:sprintf(t, "mov ($%0.3x)+y,a", opdp0); break;
case 0xd8:sprintf(t, "mov $%0.3x,x", opdp0); break;
case 0xd9:sprintf(t, "mov $%0.3x+y,x", opdp0); break;
case 0xda:sprintf(t, "movw $%0.3x,ya", opdp0); break;
case 0xdb:sprintf(t, "mov $%0.3x+x,y", opdp0); break;
case 0xdc:sprintf(t, "dec y"); break;
case 0xdd:sprintf(t, "mov a,y"); break;
case 0xde:sprintf(t, "cbne $%0.3x+x,$%0.4x", opdp0, __relb(op1, 3));break;
case 0xdf:sprintf(t, "daa a"); break;
case 0xe0:sprintf(t, "clrv"); break;
case 0xe1:sprintf(t, "tcall 14"); break;
case 0xe2:sprintf(t, "set7 $%0.3x", opdp0); break;
case 0xe3:sprintf(t, "bbs7 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0xe4:sprintf(t, "mov a,$%0.3x", opdp0); break;
case 0xe5:sprintf(t, "mov a,$%0.4x", opw); break;
case 0xe6:sprintf(t, "mov a,(x)"); break;
case 0xe7:sprintf(t, "mov a,($%0.3x+x)", opdp0); break;
case 0xe8:sprintf(t, "mov a,#$%0.2x", op0); break;
case 0xe9:sprintf(t, "mov x,$%0.4x", opw); break;
case 0xea:sprintf(t, "not1 c,$%0.4x:%d", opw & 0x1fff, opw >> 13); break;
case 0xeb:sprintf(t, "mov y,$%0.3x", opdp0); break;
case 0xec:sprintf(t, "mov y,$%0.4x", opw); break;
case 0xed:sprintf(t, "notc"); break;
case 0xee:sprintf(t, "pop y"); break;
case 0xef:sprintf(t, "sleep"); break;
case 0xf0:sprintf(t, "beq $%0.4x", __relb(op0, 2)); break;
case 0xf1:sprintf(t, "tcall 15"); break;
case 0xf2:sprintf(t, "clr7 $%0.3x", opdp0); break;
case 0xf3:sprintf(t, "bbc7 $%0.3x,$%0.4x", opdp0, __relb(op1, 3)); break;
case 0xf4:sprintf(t, "mov a,$%0.3x+x", opdp0); break;
case 0xf5:sprintf(t, "mov a,$%0.4x+x", opw); break;
case 0xf6:sprintf(t, "mov a,$%0.4x+y", opw); break;
case 0xf7:sprintf(t, "mov a,($%0.3x)+y", opdp0); break;
case 0xf8:sprintf(t, "mov x,$%0.3x", opdp0); break;
case 0xf9:sprintf(t, "mov x,$%0.3x+y", opdp0); break;
case 0xfa:sprintf(t, "mov $%0.3x,$%0.3x", opdp1, opdp0); break;
case 0xfb:sprintf(t, "mov y,$%0.3x+x", opdp0); break;
case 0xfc:sprintf(t, "inc y"); break;
case 0xfd:sprintf(t, "mov y,a"); break;
case 0xfe:sprintf(t, "dbnz y,$%0.4x", __relb(op0, 2)); break;
case 0xff:sprintf(t, "stop"); break;
}
t[strlen(t)] = ' ';
strcat(s, t);
sprintf(t, "A:%0.2x X:%0.2x Y:%0.2x SP:01%0.2x YA:%0.4x ",
regs.a, regs.x, regs.y, regs.sp, regs.ya);
strcat(s, t);
sprintf(t, "%c%c%c%c%c%c%c%c",
(regs.p.n)?'N':'n',
(regs.p.v)?'V':'v',
(regs.p.p)?'P':'p',
(regs.p.b)?'B':'b',
(regs.p.h)?'H':'h',
(regs.p.i)?'I':'i',
(regs.p.z)?'Z':'z',
(regs.p.c)?'C':'c');
strcat(s, t);
}

48
src/apu/iplrom.h Normal file
View File

@ -0,0 +1,48 @@
//This is the IPLROM for the SPC700 coprocessor.
//This array is *read-only*. The SPC700 does not
//allow writing to the IPLROM, all writes are
//instead mapped to the extended SPC700 RAM region,
//accessible when $f1 bit 7 is clear.
//If you use this buffer directly, make sure not
//to write to it, as this will break other APU
//implementations that attempt to use this buffer.
#ifdef _APU_IPLROM
const uint8 spc700_iplrom[64] = {
/*ffc0*/ 0xcd, 0xef, //mov x,#$ef
/*ffc2*/ 0xbd, //mov sp,x
/*ffc3*/ 0xe8, 0x00, //mov a,#$00
/*ffc5*/ 0xc6, //mov (x),a
/*ffc6*/ 0x1d, //dec x
/*ffc7*/ 0xd0, 0xfc, //bne $ffc5
/*ffc9*/ 0x8f, 0xaa, 0xf4, //mov $f4,#$aa
/*ffcc*/ 0x8f, 0xbb, 0xf5, //mov $f5,#$bb
/*ffcf*/ 0x78, 0xcc, 0xf4, //cmp $f4,#$cc
/*ffd2*/ 0xd0, 0xfb, //bne $ffcf
/*ffd4*/ 0x2f, 0x19, //bra $ffef
/*ffd6*/ 0xeb, 0xf4, //mov y,$f4
/*ffd8*/ 0xd0, 0xfc, //bne $ffd6
/*ffda*/ 0x7e, 0xf4, //cmp y,$f4
/*ffdc*/ 0xd0, 0x0b, //bne $ffe9
/*ffde*/ 0xe4, 0xf5, //mov a,$f5
/*ffe0*/ 0xcb, 0xf4, //mov $f4,y
/*ffe2*/ 0xd7, 0x00, //mov ($00)+y,a
/*ffe4*/ 0xfc, //inc y
/*ffe5*/ 0xd0, 0xf3, //bne $ffda
/*ffe7*/ 0xab, 0x01, //inc $01
/*ffe9*/ 0x10, 0xef, //bpl $ffda
/*ffeb*/ 0x7e, 0xf4, //cmp y,$f4
/*ffed*/ 0x10, 0xeb, //bpl $ffda
/*ffef*/ 0xba, 0xf6, //movw ya,$f6
/*fff1*/ 0xda, 0x00, //movw $00,ya
/*fff3*/ 0xba, 0xf4, //movw ya,$f4
/*fff5*/ 0xc4, 0xf4, //mov $f4,a
/*fff7*/ 0xdd, //mov a,y
/*fff8*/ 0x5d, //mov x,a
/*fff9*/ 0xd0, 0xdb, //bne $ffd6
/*fffb*/ 0x1f, 0x00, 0x00, //jmp ($0000+x)
/*fffe*/ 0xc0, 0xff //---reset vector location ($ffc0)
};
#else
extern const uint8 spc700_iplrom[64];
#endif

View File

@ -1,3 +1,4 @@
#include <time.h>
#include "lib/libbase.h"
//structs

View File

@ -1,201 +0,0 @@
#include "../../base.h"
void bClock::frameskip_update_status() {
if(frameskip.changed == true) {
frameskip.changed = false;
frameskip.count = frameskip.new_count;
frameskip.pos = 0;
} else {
frameskip.pos++;
frameskip.pos %= (frameskip.count + 1);
}
frameskip.notify_ppu = (frameskip.pos == 0)?true:false;
}
void bClock::dram_refresh_test() {
if(cc1.dram_refreshed == false && status.hcycles >= cc1.dram_refresh_pos) {
cc1.dram_refreshed = true;
if(status.interlace != false || status.interlace_field != 1 || status.vcounter != 240) {
if(cc1.dram_refresh_pos == 534) {
cc1.dram_refresh_pos = 538;
} else { //cc1.dram_refresh_pos == 538
cc1.dram_refresh_pos = 534;
}
}
cc1.pos += 40;
cc1.frame_pos += 40;
status.hcycles += 40;
}
}
/*
all scanlines are 1364 cycles long, except scanline 240
on non-interlace odd-frames, which is 1360 cycles long.
interlace mode has 525 scanlines: 263 on the even frame,
and 262 on the odd.
non-interlace mode has 524 scanlines: 262 scanlines on
both even and odd frames.
cycles per frame:
263 * 1364 = 358732
262 * 1364 = 357368
262 * 1364 - 4 = 357364
*/
void bClock::inc_vcounter() {
status.hcycles -= cc1.line_cycles;
status.vcounter++;
if(status.vcounter >= cc1.frame_lines) {
frameskip_update_status();
cc1.frame_pos -= cc1.frame_cycles;
status.vcounter = 0;
status.interlace_field ^= 1;
if(status.interlace == true) {
if(status.interlace_field == 0) {
cc1.frame_cycles = 263 * 1364;
cc1.frame_lines = 263;
} else {
cc1.frame_cycles = 262 * 1364;
cc1.frame_lines = 262;
}
} else {
if(status.interlace_field == 0) {
cc1.frame_cycles = 262 * 1364;
cc1.frame_lines = 262;
} else {
cc1.frame_cycles = (262 * 1364) - 4;
cc1.frame_lines = 262;
}
}
signal_frame = true;
}
if(status.interlace == false && status.interlace_field == 1 && status.vcounter == 240) {
cc1.line_cycles = 1360;
} else {
cc1.line_cycles = 1364;
}
cc1.dram_refreshed = false;
signal_scanline = true;
}
/*
all dots are 4 cycles long, except dots 322 and 326. dots 322 and 326
are 6 cycles long. this holds true for all scanlines except scanline
240 on non-interlace odd frames. the reason for this is because this
scanline is only 1360 cycles long, instead of 1364 like all other
scanlines.
this makes the effective range of hscan_pos 0-339 at all times.
dot 322 range = { 1288, 1290, 1292 }
dot 326 range = { 1306, 1308, 1310 }
*/
void bClock::sync() {
uint32 new_cycles, cycles;
new_cycles = cc1.pos - cc1.last_pos;
while(new_cycles) {
if(new_cycles > 40) {
cycles = 40;
new_cycles -= 40;
} else {
cycles = new_cycles;
new_cycles = 0;
}
status.hcycles += cycles;
cc1.frame_pos += cycles;
dram_refresh_test();
if(status.hcycles >= cc1.line_cycles) {
inc_vcounter();
}
}
if(status.interlace == false && status.interlace_field == 1 && status.vcounter == 240) {
status.hcounter = status.hcycles >> 2;
} else {
//1288 = 322 * 4, 1306 = 326 * 4 + 2
status.hcounter = (status.hcycles - ((status.hcycles > 1288) << 1) - ((status.hcycles > 1306) << 1)) >> 2;
}
cc1.last_pos = cc1.pos;
if(cc1.pos > cc1.frequency) {
cc1.pos -= cc1.frequency;
cc1.last_pos -= cc1.frequency;
}
}
void bClock::set_frameskip(uint8 fs) {
frameskip.changed = true;
frameskip.new_count = fs;
}
void bClock::power() {
reset();
}
void bClock::reset() {
//upon SNES reset, start at scanline 0 non-interlace
cc1.frame_cycles = 262 * 1364;
cc1.frame_lines = 262;
cc1.line_cycles = 1364;
/*
Initial latch values for $213c/$213d
0035:0000 (53.0 -> 212) [lda $2137]
0038:0000 (56.5 -> 226) [nop : lda $2137]
*/
cc1.pos = 188;
cc1.last_pos = 0;
cc1.frame_pos = 0;
status.vcounter = 0;
status.hcounter = 0;
status.hcycles = 0;
cc1.dram_refresh_pos = 538;
cc1.dram_refreshed = false;
cc2.pos = 0;
signal_scanline = false;
signal_frame = false;
sync();
}
void bClock::run() {
cpu->run();
if(frameskip.notify_ppu == true)ppu->run();
sync();
if(signal_frame == true) {
signal_frame = false;
cpu->frame();
if(frameskip.notify_ppu == true)ppu->frame();
}
if(signal_scanline == true) {
signal_scanline = false;
cpu->scanline();
if(frameskip.notify_ppu == true)ppu->scanline();
}
}
void bClock::add_cc1_cycles(uint32 cycles) {
cc1.pos += cycles;
}
void bClock::add_cc2_cycles(uint32 cycles) {
cc2.pos += cycles;
}
bClock::bClock() {
cc1.frequency = 21477272;
cc2.frequency = 24576000;
frameskip.changed = false;
frameskip.count = 0;
frameskip.pos = 0;
}

View File

@ -1,37 +0,0 @@
class bClock : public Clock {
private:
struct {
bool changed, notify_ppu;
uint8 count, new_count, pos;
}frameskip;
bool signal_scanline, signal_frame;
inline void frameskip_update_status();
inline void inc_vcounter();
inline void dram_refresh_test();
public:
struct {
uint32 frequency;
uint32 pos, last_pos;
uint32 frame_cycles, frame_lines, frame_pos;
uint16 line_cycles;
bool dram_refreshed; //whether or not dram has been refreshed on this line
uint16 dram_refresh_pos;
}cc1;
struct {
uint32 frequency;
uint32 pos, last_pos;
}cc2;
inline void set_frameskip(uint8 fs);
inline void add_cc1_cycles(uint32 cycles);
inline void add_cc2_cycles(uint32 cycles);
inline void sync();
inline void run();
inline void power();
inline void reset();
bClock();
~bClock();
};

View File

@ -1,49 +0,0 @@
#include "../base.h"
void Clock::enable_overscan(bool n) {
status.overscan = n;
}
void Clock::enable_interlace(bool n) {
status.interlace = n;
}
bool Clock::overscan() {
return status.overscan;
}
bool Clock::interlace() {
return status.interlace;
}
bool Clock::interlace_field() {
return status.interlace_field;
}
uint16 Clock::vcounter() {
return status.vcounter;
}
uint16 Clock::hcounter() {
return status.hcounter;
}
uint16 Clock::hcycles() {
return status.hcycles;
}
uint16 Clock::visible_scanlines() {
return (status.overscan)?239:224;
}
void Clock::set_frameskip(uint8 fs) {}
Clock::Clock() {
status.overscan = false;
status.interlace = false;
status.interlace_field = 0;
status.vcounter = 0;
status.hcounter = 0;
status.hcycles = 0;
}

View File

@ -1,36 +0,0 @@
class Clock {
private:
struct {
bool overscan;
bool interlace;
bool interlace_field;
uint16 vcounter;
uint16 hcounter;
uint16 hcycles;
}status;
public:
virtual void enable_overscan(bool n);
virtual void enable_interlace(bool n);
virtual bool overscan();
virtual bool interlace();
virtual bool interlace_field();
virtual uint16 vcounter();
virtual uint16 hcounter();
virtual uint16 hcycles();
virtual uint16 visible_scanlines();
virtual void set_frameskip(uint8 fs);
virtual void add_cc1_cycles(uint32 cycles) = 0;
virtual void add_cc2_cycles(uint32 cycles) = 0;
virtual void sync() = 0;
virtual void run() = 0;
virtual void power() = 0;
virtual void reset() = 0;
Clock();
friend class bClock;
};

View File

@ -1,20 +1,19 @@
#include "../../base.h"
#include "bcpu_op_adc.cpp"
#include "bcpu_op_and.cpp"
#include "bcpu_op_cmp.cpp"
#include "bcpu_op_eor.cpp"
#include "bcpu_op_incdec.cpp"
#include "bcpu_op_lda.cpp"
#include "bcpu_op_misc.cpp"
#include "bcpu_op_ora.cpp"
#include "srtc.cpp"
#include "bcpu_opfn.cpp"
#include "bcpu_op_read.cpp"
#include "bcpu_op_rmw.cpp"
#include "bcpu_op_write.cpp"
#include "bcpu_op_pc.cpp"
#include "bcpu_op_sbc.cpp"
#include "bcpu_op_shift.cpp"
#include "bcpu_op_sta.cpp"
#include "bcpu_op_stack.cpp"
#include "bcpu_op_misc.cpp"
#include "bcpu_exec.cpp"
#include "bcpu_mmio.cpp"
#include "bcpu_dma.cpp"
#include "bcpu_timing.cpp"
uint8 bCPU::pio_status() {
return status.pio;
@ -24,7 +23,7 @@ uint8 bCPU::pio_status() {
*** IRQ ***
***********
cycles:
[1] pbr,pc ; io
[1] pbr,pc ; io/opcode
[2] pbr,pc ; io
[3] 0,s ; pbr
[4] 0,s-1 ; pch
@ -34,90 +33,117 @@ cycles:
[8] 0,va+1 ; aavh
*/
void bCPU::irq(uint16 addr) {
if(cpustate == CPUSTATE_WAI) {
if(status.cpu_state == CPUSTATE_WAI) {
status.cpu_state = CPUSTATE_RUN;
regs.pc.w++;
cpustate = CPUSTATE_RUN;
}
clock->add_cc1_cycles(mem_bus->speed(regs.pc)); //1
clock->add_cc1_cycles(6); //2
stack_write(regs.pc.b); //3
stack_write(regs.pc.h); //4
stack_write(regs.pc.l); //5
stack_write(regs.p); //6
rd.l = op_read(OPMODE_ADDR, addr); //7
rd.h = op_read(OPMODE_ADDR, addr + 1); //8
//GTE documentation is incorrect, first cycle
//is a memory read fetch from PBR:PC
add_cycles(mem_bus->speed(regs.pc.d));
add_cycles(6);
stack_write(regs.pc.b);
stack_write(regs.pc.h);
stack_write(regs.pc.l);
stack_write(regs.p);
rd.l = op_read(OPMODE_ADDR, addr);
rd.h = op_read(OPMODE_ADDR, addr + 1);
regs.pc.b = 0x00;
regs.pc.w = rd.w;
regs.p.i = 1;
regs.p.d = 0;
regs.p.d = 0;
regs.p.i = 1;
//let debugger know the new IRQ opcode address
snes->notify(SNES::CPU_EXEC_OPCODE_END);
}
snes->notify(SNES::CPU_EXEC_OPCODE);
bool bCPU::hdma_test() {
if(status.hdma_triggered == false) {
if(vcounter() < (overscan()?239:224) && hcounter() >= 278) {
status.hdma_triggered = true;
return true;
}
}
return false;
}
bool bCPU::nmi_test() {
if(vcounter() >= ((overscan()?239:224) + 1) && status.nmi_triggered == false) {
if((vcounter() == ((overscan()?239:224) + 1) && hcycles() >= 12) || (vcounter() > ((overscan()?239:224) + 1))) {
status.nmi_triggered = true;
status.nmi_pin = 0;
if(status.nmi_enabled == true) {
return true;
}
}
}
return false;
}
bool bCPU::irq_test() {
int vpos, hpos;
if(regs.p.i)return false; //no interrupt can occur with I flag set
if(status.irq_pin == 0)return false; //same as above
if(status.virq_enabled == false && status.hirq_enabled == false)return false;
//calculate V/H positions required for IRQ to trigger
vpos = status.virq_pos;
hpos = (status.hirq_enabled) ? status.hirq_pos : 0;
//positions that can never be latched
if(vpos == 261 && hpos == 339 && interlace() == false)return false;
if(vpos == 262 && interlace() == false)return false;
if(vpos == 262 && hpos == 339)return false;
if(vpos > 262)return false;
if(hpos > 339)return false;
if(hpos == 0) {
hpos = 24;
} else {
hpos <<= 2;
hpos += 24; //30 - status.cycle_count;
//it should be OK to use the current line cycles/frame lines,
//as the IRQ will only trigger on the correct scanline anyway...
if(hpos >= time.line_cycles) {
hpos -= time.line_cycles;
vpos++;
if(vpos >= time.frame_lines) {
vpos = 0;
}
}
}
if(status.virq_enabled == true && vcounter() != vpos)return false;
if(hcycles() >= hpos && status.irq_pin == 1) {
//dprintf("* vpos=%3d,hpos=%4d; v=%3d,h=%4d; lc=%d,virq=%3d,hirq=%3d",
// vpos, hpos, vcounter(), hcycles(), status.cycle_count, status.virq_pos, status.hirq_pos);
status.irq_triggered = true;
status.irq_pin = 0;
return true;
}
return false;
}
void bCPU::run() {
uint16 v, h, hc, vs;
v = clock->vcounter();
h = clock->hcounter();
hc = clock->hcycles();
vs = clock->visible_scanlines();
//HDMA test
if(v < vs && h >= 278) {
if(status.hdma_triggered == false) {
status.hdma_triggered = true;
dma->hdma_run();
return;
}
}
switch(cpustate) {
switch(status.cpu_state) {
case CPUSTATE_DMA:
dma_run();
break;
case CPUSTATE_RUN:
case CPUSTATE_WAI:
//NMI test
if(v >= (vs + 1) && status.nmi_triggered == false) {
if((v == (vs + 1) && hc >= 12) || (v > (vs + 1))) {
status.nmi_triggered = true;
status.nmi_pin = 0;
if(status.nmi_enabled == true) {
irq(0xffea);
return;
}
}
if(nmi_test() == true) {
irq(0xffea);
break;
}
//IRQ test
if(!regs.p.i) {
if(status.virq_enabled == true && status.hirq_enabled == true) {
if(v == status.virq_pos && h >= status.hirq_pos && status.irq_pin == 1) {
status.irq_triggered = true;
status.irq_pin = 0;
irq(0xffee);
return;
}
} else if(status.virq_enabled == true) {
if(v == status.virq_pos && status.irq_pin == 1) {
status.irq_triggered = true;
status.irq_pin = 0;
irq(0xffee);
return;
}
} else if(status.hirq_enabled == true) {
if(h >= status.hirq_pos && status.irq_pin == 1) {
status.irq_triggered = true;
status.irq_pin = 0;
irq(0xffee);
return;
}
}
if(irq_test() == true) {
irq(0xffee);
break;
}
exec_opcode();
break;
case CPUSTATE_DMA:
dma->run();
break;
case CPUSTATE_STP:
exec_opcode();
break;
@ -125,62 +151,25 @@ uint16 v, h, hc, vs;
}
void bCPU::scanline() {
uint16 v = clock->vcounter();
status.hdma_triggered = false;
if(v == 225 && status.auto_joypad_poll == true) {
if(vcounter() == 225 && status.auto_joypad_poll == true) {
snes->poll_input();
//When the SNES auto-polls the joypads, it writes 1, then 0 to
//$4016, then reads from each 16 times to get the joypad state
//information. As a result, the joypad read positions are set
//to 16 after such a poll. Position 16 is the controller
//connected status bit.
//When the SNES auto-polls the joypads, it writes 1, then 0 to
//$4016, then reads from each 16 times to get the joypad state
//information. As a result, the joypad read positions are set
//to 16 after such a poll. Position 16 is the controller
//connected status bit.
status.joypad1_read_pos = 16;
}
if(status.virq_enabled == false) {
status.irq_pin = 1;
}
}
void bCPU::frame() {
status.hdma_triggered = false;
status.nmi_triggered = false;
status.r4210_read = false;
status.irq_triggered = false;
status.irq_pin = 1;
dma->hdma_initialize();
}
void bCPU::power() {
regs.a = regs.x = regs.y = 0x0000;
regs.s = 0x01ff;
reset();
}
void bCPU::reset() {
/* reset vector location */
regs.pc = mem_bus->read(0xfffc) | (mem_bus->read(0xfffd) << 8);
/* registers are not fully reset by SNES */
regs.x.h = 0x00;
regs.y.h = 0x00;
regs.s.h = 0x01;
regs.d = 0x0000;
regs.db = 0x00;
regs.p = 0x34;
regs.e = 1;
cpustate = CPUSTATE_RUN;
dma->reset();
mmio_reset();
optbl = optbl_e;
status.hdma_triggered = false;
hdma_initialize();
status.nmi_triggered = false;
status.nmi_pin = 1;
@ -190,113 +179,164 @@ void bCPU::reset() {
status.irq_pin = 1;
}
void bCPU::power() {
srtc_power();
regs.a = regs.x = regs.y = 0x0000;
regs.s = 0x01ff;
reset();
}
void bCPU::reset() {
srtc_reset();
frame();
//reset vector location
regs.pc = mem_bus->read(0xfffc) | (mem_bus->read(0xfffd) << 8);
//registers are not fully reset by SNES
regs.x.h = 0x00;
regs.y.h = 0x00;
regs.s.h = 0x01;
regs.d = 0x0000;
regs.db = 0x00;
regs.p = 0x34;
regs.e = 1;
time_reset();
mmio_reset();
dma_reset();
status.cpu_state = CPUSTATE_RUN;
status.hdma_triggered = false;
status.nmi_triggered = false;
status.nmi_pin = 1;
status.r4210_read = false;
status.irq_triggered = false;
status.irq_pin = 1;
apu_port[0] = 0x00;
apu_port[1] = 0x00;
apu_port[2] = 0x00;
apu_port[3] = 0x00;
}
uint8 bCPU::port_read(uint8 port) {
return apu_port[port & 3];
}
void bCPU::port_write(uint8 port, uint8 value) {
apu_port[port & 3] = value;
}
void bCPU::cpu_c2() {
if(regs.d.l != 0x00) {
clock->add_cc1_cycles(6);
status.cycle_count = 6;
cycle_edge();
add_cycles(6);
}
}
void bCPU::cpu_c4(uint16 a, uint16 b) {
if(((a & 0xff00) != (b & 0xff00)) || !regs.p.x) {
clock->add_cc1_cycles(6);
void bCPU::cpu_c4(uint16 x, uint16 y) {
if(!regs.p.x && (x & 0xff00) != (y & 0xff00)) {
status.cycle_count = 6;
cycle_edge();
add_cycles(6);
}
}
void bCPU::cpu_c6(uint16 a) {
if(regs.e) {
if((regs.pc.w & 0xff00) != (a & 0xff00)) {
clock->add_cc1_cycles(6);
}
void bCPU::cpu_c6(uint16 addr) {
if(regs.e && (regs.pc.w & 0xff00) != (addr & 0xff00)) {
status.cycle_count = 6;
cycle_edge();
add_cycles(6);
}
}
void bCPU::cpu_io() {
clock->add_cc1_cycles(6);
status.cycle_count = 6;
cycle_edge();
add_cycles(6);
}
uint8 bCPU::mem_read(uint32 addr) {
uint8 r;
status.cycle_count = mem_bus->speed(addr);
cycle_edge();
add_cycles(2);
r = mem_bus->read(addr);
add_cycles(status.cycle_count - 2);
return r;
}
void bCPU::mem_write(uint32 addr, uint8 value) {
status.cycle_count = mem_bus->speed(addr);
cycle_edge();
add_cycles(6);
mem_bus->write(addr, value);
add_cycles(status.cycle_count - 6);
}
uint32 bCPU::op_addr(uint8 mode, uint32 addr) {
switch(mode) {
case OPMODE_ADDR:
addr &= 0xffff;
break;
case OPMODE_LONG:
addr &= 0xffffff;
break;
case OPMODE_DBR:
addr &= 0xffffff;
addr = (regs.db << 16) + addr;
break;
case OPMODE_PBR:
addr &= 0xffff;
addr = (regs.pc.b << 16) | addr;
break;
case OPMODE_DP:
addr &= 0xffff;
addr = (regs.d + addr) & 0xffff;
break;
case OPMODE_SP:
addr &= 0xffff;
addr = (regs.s + addr) & 0xffff;
break;
}
return addr;
}
uint8 bCPU::op_read() {
uint8 r;
r = mem_bus->read(regs.pc);
clock->add_cc1_cycles(mem_bus->speed(regs.pc));
r = mem_read(regs.pc.d);
regs.pc.w++;
return r;
}
uint8 bCPU::op_read(uint8 mode, uint32 addr) {
uint8 r;
switch(mode) {
case OPMODE_ADDR:
addr &= 0xffff;
break;
case OPMODE_LONG:
addr &= 0xffffff;
break;
case OPMODE_DBR:
addr &= 0xffffff;
addr = (regs.db << 16) + addr;
break;
case OPMODE_PBR:
addr &= 0xffff;
addr = (regs.pc.b << 16) | addr;
break;
case OPMODE_DP:
addr &= 0xffff;
addr = (regs.d + addr) & 0xffff;
break;
case OPMODE_SP:
addr &= 0xffff;
addr = (regs.s + addr) & 0xffff;
break;
}
r = mem_bus->read(addr);
clock->add_cc1_cycles(mem_bus->speed(addr));
return r;
addr = op_addr(mode, addr);
return mem_read(addr);
}
void bCPU::op_write(uint8 mode, uint32 addr, uint8 value) {
switch(mode) {
case OPMODE_ADDR:
addr &= 0xffff;
break;
case OPMODE_LONG:
addr &= 0xffffff;
break;
case OPMODE_DBR:
addr &= 0xffffff;
addr = (regs.db << 16) + addr;
break;
case OPMODE_PBR:
addr &= 0xffff;
addr = (regs.pc.b << 16) | addr;
break;
case OPMODE_DP:
addr &= 0xffff;
addr = (regs.d + addr) & 0xffff;
break;
case OPMODE_SP:
addr &= 0xffff;
addr = (regs.s + addr) & 0xffff;
break;
}
mem_bus->write(addr, value);
clock->add_cc1_cycles(mem_bus->speed(addr));
addr = op_addr(mode, addr);
mem_write(addr, value);
}
uint8 bCPU::stack_read() {
byte r;
if(regs.e) {
regs.s.l++;
} else {
regs.s.w++;
}
r = mem_bus->read(regs.s);
clock->add_cc1_cycles(mem_bus->speed(regs.s));
return r;
return mem_read(regs.s);
}
void bCPU::stack_write(uint8 value) {
mem_bus->write(regs.s, value);
clock->add_cc1_cycles(mem_bus->speed(regs.s));
mem_write(regs.s, value);
if(regs.e) {
regs.s.l--;
} else {
@ -305,7 +345,7 @@ void bCPU::stack_write(uint8 value) {
}
bCPU::bCPU() {
dma = new bDMA(this);
time_init();
mmio = new bCPUMMIO(this);
init_op_tables();
@ -313,5 +353,4 @@ bCPU::bCPU() {
bCPU::~bCPU() {
delete(mmio);
delete(dma);
}

View File

@ -1,79 +1,55 @@
class bCPU;
class bDMA {
public:
bCPU *cpu;
struct {
//$420b
bool active;
//$420c
bool hdma_active;
//$43x0
bool direction;
bool hdma_indirect;
int8 incmode;
bool fixedxfer;
uint8 xfermode;
//$43x1
uint8 destaddr;
//$43x2-$43x4
uint32 srcaddr;
//$43x5-$43x6
uint16 xfersize;
//$43x7
uint8 hdma_indirect_bank;
//hdma-specific
bool hdma_first_line;
bool hdma_repeat;
uint16 hdma_line_counter;
uint32 hdma_address, hdma_iaddress;
bool hdma_completed;
}channel[8];
void hdma_write(uint8 i, uint8 l, uint8 x);
void hdma_run();
void hdma_initialize();
void run();
void reset();
uint16 dma_cputommio(uint8 i, uint8 index);
uint16 dma_mmiotocpu(uint8 i, uint8 index);
void dma_xfer_type0(uint8 i);
void dma_xfer_type1(uint8 i);
void dma_xfer_type2(uint8 i);
void dma_xfer_type3(uint8 i);
void dma_xfer_type4(uint8 i);
void dma_xfer_type5(uint8 i);
bDMA(bCPU *_cpu);
};
class bCPUMMIO : public MMIO {
public:
bCPU *cpu;
uint8 read (uint32 addr);
void write(uint32 addr, uint8 value);
inline uint8 read (uint32 addr);
inline void write(uint32 addr, uint8 value);
bCPUMMIO(bCPU *_cpu);
};
class bCPU : public CPU {
private:
typedef void (bCPU::*op)();
op *optbl, optbl_e[256], optbl_MX[256], optbl_Mx[256], optbl_mX[256], optbl_mx[256];
op optbl[256];
public:
enum { CPUSTATE_RUN = 0, CPUSTATE_DMA, CPUSTATE_WAI, CPUSTATE_STP };
uint8 cpustate;
#include "srtc.h"
#include "bcpu_timing.h"
uint8 apu_port[4];
inline uint8 port_read (uint8 port);
inline void port_write(uint8 port, uint8 value);
enum {
OPMODE_ADDR = 1, OPMODE_LONG = 2,
OPMODE_DBR = 3, OPMODE_PBR = 4,
OPMODE_DP = 5, OPMODE_SP = 6
};
bDMA *dma;
enum {
OPMODE_ADDR = 1, OPMODE_LONG = 2,
OPMODE_DBR = 3, OPMODE_PBR = 4,
OPMODE_DP = 5, OPMODE_SP = 6
};
CPUReg24 aa, rd;
uint8 dp, sp;
enum {
CPUSTATE_RUN = 0,
CPUSTATE_WAI,
CPUSTATE_STP,
CPUSTATE_DMA
};
enum {
DMASTATE_STOP = 0,
DMASTATE_INIT,
DMASTATE_DMASYNC,
DMASTATE_RUN,
DMASTATE_CPUSYNC
};
struct {
uint8 cpu_state, cycle_count;
uint8 dma_state;
uint32 dma_cycle_count;
bool hdma_triggered;
bool nmi_triggered;
@ -82,6 +58,7 @@ struct {
bool irq_triggered;
bool irq_pin;
uint16 virq_trigger, hirq_trigger;
//$2181-$2183
uint32 wram_addr;
@ -113,13 +90,66 @@ struct {
uint16 r4216;
}status;
uint8 pio_status();
void irq(uint16 addr);
void run();
void scanline();
void frame();
void power();
void reset();
struct {
//$420b
bool active;
//$420c
bool hdma_active;
//$43x0
uint8 dmap;
bool direction;
bool hdma_indirect;
int8 incmode;
bool fixedxfer;
uint8 xfermode;
//$43x1
uint8 destaddr;
//$43x2-$43x4
uint32 srcaddr;
//$43x5-$43x6
uint16 xfersize;
//$43x7
uint8 hdma_indirect_bank;
//$43x8-$43x9
uint32 hdma_taddr;
//$43xa
uint8 hdma_line_counter;
//$43xb/$43xf
uint8 hdma_unknown;
//hdma-specific
bool hdma_first_line;
bool hdma_repeat;
uint32 hdma_itaddr;
bool hdma_completed;
}channel[8];
inline bool hdma_test();
inline bool nmi_test();
inline bool irq_test();
inline void irq(uint16 addr);
inline uint8 pio_status();
inline void run();
inline void scanline();
inline void frame();
inline void power();
inline void reset();
//dma commands
inline void dma_run();
inline void hdma_run();
inline void hdma_initialize();
inline uint16 dma_cputommio(uint8 i, uint8 index);
inline uint16 dma_mmiotocpu(uint8 i, uint8 index);
inline void dma_xfer_type0(uint8 i);
inline void dma_xfer_type1(uint8 i);
inline void dma_xfer_type2(uint8 i);
inline void dma_xfer_type3(uint8 i);
inline void dma_xfer_type4(uint8 i);
inline void dma_xfer_type5(uint8 i);
inline void hdma_write(uint8 i, uint8 l, uint8 x);
inline void dma_reset();
//mmio commands
void mmio_reset();
@ -137,6 +167,18 @@ struct {
uint8 mmio_r4217();
uint8 mmio_r4218();
uint8 mmio_r4219();
uint8 mmio_r43x0(uint8 i);
uint8 mmio_r43x1(uint8 i);
uint8 mmio_r43x2(uint8 i);
uint8 mmio_r43x3(uint8 i);
uint8 mmio_r43x4(uint8 i);
uint8 mmio_r43x5(uint8 i);
uint8 mmio_r43x6(uint8 i);
uint8 mmio_r43x7(uint8 i);
uint8 mmio_r43x8(uint8 i);
uint8 mmio_r43x9(uint8 i);
uint8 mmio_r43xa(uint8 i);
uint8 mmio_r43xb(uint8 i);
void mmio_w2180(uint8 value);
void mmio_w2181(uint8 value);
void mmio_w2182(uint8 value);
@ -164,520 +206,76 @@ struct {
void mmio_w43x5(uint8 value, uint8 i);
void mmio_w43x6(uint8 value, uint8 i);
void mmio_w43x7(uint8 value, uint8 i);
void mmio_w43x8(uint8 value, uint8 i);
void mmio_w43x9(uint8 value, uint8 i);
void mmio_w43xa(uint8 value, uint8 i);
void mmio_w43xb(uint8 value, uint8 i);
inline void exec_opcode();
inline uint8 op_read ();
inline uint8 op_read (uint8 mode, uint32 addr);
inline void op_write(uint8 mode, uint32 addr, uint8 value);
inline uint8 stack_read ();
inline void stack_write(uint8 value);
enum { CYCLE_OPREAD = 0, CYCLE_READ, CYCLE_WRITE, CYCLE_IO };
inline void exec_opcode();
inline void cycle_edge();
//cpu extra-cycle conditions
inline void cpu_c2();
inline void cpu_c4(uint16 a, uint16 b);
inline void cpu_c6(uint16 a);
inline void cpu_c4(uint16 x, uint16 y);
inline void cpu_c6(uint16 addr);
inline void cpu_io();
//opcode functions
void init_op_tables();
inline uint8 mem_read (uint32 addr);
inline void mem_write(uint32 addr, uint8 value);
inline uint32 op_addr(uint8 mode, uint32 addr);
inline uint8 op_read();
inline uint8 op_read(uint8 mode, uint32 addr);
inline void op_write(uint8 mode, uint32 addr, uint8 value);
inline uint8 stack_read();
inline void stack_write(uint8 value);
//op_adc
inline void flags_adc_b();
inline void flags_adc_w();
void op_adc_constb();
void op_adc_constw();
void op_adc_addrb();
void op_adc_addrw();
void op_adc_addrxb();
void op_adc_addrxw();
void op_adc_dpb();
void op_adc_dpw();
void op_adc_idpb();
void op_adc_idpw();
void op_adc_ildpb();
void op_adc_ildpw();
void op_adc_longb();
void op_adc_longw();
void op_adc_longxb();
void op_adc_longxw();
void op_adc_addryb();
void op_adc_addryw();
void op_adc_dpxb();
void op_adc_dpxw();
void op_adc_idpxb();
void op_adc_idpxw();
void op_adc_idpyb();
void op_adc_idpyw();
void op_adc_ildpyb();
void op_adc_ildpyw();
void op_adc_srb();
void op_adc_srw();
void op_adc_isryb();
void op_adc_isryw();
//op_and
inline void flags_and_b();
inline void flags_and_w();
void op_and_constb();
void op_and_constw();
void op_and_addrb();
void op_and_addrw();
void op_and_addrxb();
void op_and_addrxw();
void op_and_dpb();
void op_and_dpw();
void op_and_idpb();
void op_and_idpw();
void op_and_ildpb();
void op_and_ildpw();
void op_and_longb();
void op_and_longw();
void op_and_longxb();
void op_and_longxw();
void op_and_addryb();
void op_and_addryw();
void op_and_dpxb();
void op_and_dpxw();
void op_and_idpxb();
void op_and_idpxw();
void op_and_idpyb();
void op_and_idpyw();
void op_and_ildpyb();
void op_and_ildpyw();
void op_and_srb();
void op_and_srw();
void op_and_isryb();
void op_and_isryw();
//op_cmp
inline void flags_cmp_b();
inline void flags_cmp_w();
void op_cmp_constb();
void op_cmp_constw();
void op_cmp_addrb();
void op_cmp_addrw();
void op_cmp_addrxb();
void op_cmp_addrxw();
void op_cmp_dpb();
void op_cmp_dpw();
void op_cmp_idpb();
void op_cmp_idpw();
void op_cmp_ildpb();
void op_cmp_ildpw();
void op_cmp_longb();
void op_cmp_longw();
void op_cmp_longxb();
void op_cmp_longxw();
void op_cmp_addryb();
void op_cmp_addryw();
void op_cmp_dpxb();
void op_cmp_dpxw();
void op_cmp_idpxb();
void op_cmp_idpxw();
void op_cmp_idpyb();
void op_cmp_idpyw();
void op_cmp_ildpyb();
void op_cmp_ildpyw();
void op_cmp_srb();
void op_cmp_srw();
void op_cmp_isryb();
void op_cmp_isryw();
//op_eor
inline void flags_eor_b();
inline void flags_eor_w();
void op_eor_constb();
void op_eor_constw();
void op_eor_addrb();
void op_eor_addrw();
void op_eor_addrxb();
void op_eor_addrxw();
void op_eor_dpb();
void op_eor_dpw();
void op_eor_idpb();
void op_eor_idpw();
void op_eor_ildpb();
void op_eor_ildpw();
void op_eor_longb();
void op_eor_longw();
void op_eor_longxb();
void op_eor_longxw();
void op_eor_addryb();
void op_eor_addryw();
void op_eor_dpxb();
void op_eor_dpxw();
void op_eor_idpxb();
void op_eor_idpxw();
void op_eor_idpyb();
void op_eor_idpyw();
void op_eor_ildpyb();
void op_eor_ildpyw();
void op_eor_srb();
void op_eor_srw();
void op_eor_isryb();
void op_eor_isryw();
//op_incdec
void op_incb();
void op_incw();
void op_inc_addrb();
void op_inc_addrw();
void op_inc_addrxb();
void op_inc_addrxw();
void op_inc_dpb();
void op_inc_dpw();
void op_inc_dpxb();
void op_inc_dpxw();
void op_inxb();
void op_inxw();
void op_inyb();
void op_inyw();
void op_decb();
void op_decw();
void op_dec_addrb();
void op_dec_addrw();
void op_dec_addrxb();
void op_dec_addrxw();
void op_dec_dpb();
void op_dec_dpw();
void op_dec_dpxb();
void op_dec_dpxw();
void op_dexb();
void op_dexw();
void op_deyb();
void op_deyw();
//op_lda
inline void flags_lda_b();
inline void flags_lda_w();
void op_lda_constb();
void op_lda_constw();
void op_lda_addrb();
void op_lda_addrw();
void op_lda_addrxb();
void op_lda_addrxw();
void op_lda_dpb();
void op_lda_dpw();
void op_lda_idpb();
void op_lda_idpw();
void op_lda_ildpb();
void op_lda_ildpw();
void op_lda_longb();
void op_lda_longw();
void op_lda_longxb();
void op_lda_longxw();
void op_lda_addryb();
void op_lda_addryw();
void op_lda_dpxb();
void op_lda_dpxw();
void op_lda_idpxb();
void op_lda_idpxw();
void op_lda_idpyb();
void op_lda_idpyw();
void op_lda_ildpyb();
void op_lda_ildpyw();
void op_lda_srb();
void op_lda_srw();
void op_lda_isryb();
void op_lda_isryw();
//op_misc
inline void flags_bit_b();
inline void flags_bit_w();
void op_bit_constb();
void op_bit_constw();
void op_bit_addrb();
void op_bit_addrw();
void op_bit_addrxb();
void op_bit_addrxw();
void op_bit_dpb();
void op_bit_dpw();
void op_bit_dpxb();
void op_bit_dpxw();
inline void flags_cpx_b();
inline void flags_cpx_w();
void op_cpx_constb();
void op_cpx_constw();
void op_cpx_addrb();
void op_cpx_addrw();
void op_cpx_dpb();
void op_cpx_dpw();
inline void flags_cpy_b();
inline void flags_cpy_w();
void op_cpy_constb();
void op_cpy_constw();
void op_cpy_addrb();
void op_cpy_addrw();
void op_cpy_dpb();
void op_cpy_dpw();
inline void flags_ldx_b();
inline void flags_ldx_w();
void op_ldx_constb();
void op_ldx_constw();
void op_ldx_addrb();
void op_ldx_addrw();
void op_ldx_addryb();
void op_ldx_addryw();
void op_ldx_dpb();
void op_ldx_dpw();
void op_ldx_dpyb();
void op_ldx_dpyw();
inline void flags_ldy_b();
inline void flags_ldy_w();
void op_ldy_constb();
void op_ldy_constw();
void op_ldy_addrb();
void op_ldy_addrw();
void op_ldy_addrxb();
void op_ldy_addrxw();
void op_ldy_dpb();
void op_ldy_dpw();
void op_ldy_dpxb();
void op_ldy_dpxw();
void op_stx_addrb();
void op_stx_addrw();
void op_stx_dpb();
void op_stx_dpw();
void op_stx_dpyb();
void op_stx_dpyw();
void op_sty_addrb();
void op_sty_addrw();
void op_sty_dpb();
void op_sty_dpw();
void op_sty_dpxb();
void op_sty_dpxw();
void op_stz_addrb();
void op_stz_addrw();
void op_stz_addrxb();
void op_stz_addrxw();
void op_stz_dpb();
void op_stz_dpw();
void op_stz_dpxb();
void op_stz_dpxw();
void op_xba();
void op_trb_addrb();
void op_trb_addrw();
void op_trb_dpb();
void op_trb_dpw();
void op_tsb_addrb();
void op_tsb_addrw();
void op_tsb_dpb();
void op_tsb_dpw();
void op_mvn();
void op_mvp();
void op_brk();
void op_cop();
void op_stp();
void op_wai();
void op_xce();
void op_nop();
void op_wdm();
void op_clc();
void op_cld();
void op_cli();
void op_clv();
void op_sec();
void op_sed();
void op_sei();
void op_rep();
void op_sep();
void op_taxb();
void op_taxw();
void op_tayb();
void op_tayw();
void op_tcd();
void op_tcs();
void op_tdc();
void op_tsc();
void op_tsxb();
void op_tsxw();
void op_txab();
void op_txaw();
void op_txsb();
void op_txsw();
void op_txyb();
void op_txyw();
void op_tyab();
void op_tyaw();
void op_tyxb();
void op_tyxw();
//op_ora
inline void flags_ora_b();
inline void flags_ora_w();
void op_ora_constb();
void op_ora_constw();
void op_ora_addrb();
void op_ora_addrw();
void op_ora_addrxb();
void op_ora_addrxw();
void op_ora_dpb();
void op_ora_dpw();
void op_ora_idpb();
void op_ora_idpw();
void op_ora_ildpb();
void op_ora_ildpw();
void op_ora_longb();
void op_ora_longw();
void op_ora_longxb();
void op_ora_longxw();
void op_ora_addryb();
void op_ora_addryw();
void op_ora_dpxb();
void op_ora_dpxw();
void op_ora_idpxb();
void op_ora_idpxw();
void op_ora_idpyb();
void op_ora_idpyw();
void op_ora_ildpyb();
void op_ora_ildpyw();
void op_ora_srb();
void op_ora_srw();
void op_ora_isryb();
void op_ora_isryw();
//op_pc
void op_jmp_addr();
void op_jmp_long();
void op_jmp_iaddr();
void op_jmp_iaddrx();
void op_jmp_iladdr();
void op_jsr_addr();
void op_jsr_long();
void op_jsr_iaddrx();
void op_rtie();
void op_rtin();
void op_rts();
void op_rtl();
void op_bra();
void op_brl();
void op_bcc();
void op_bcs();
void op_bne();
void op_beq();
void op_bpl();
void op_bmi();
void op_bvc();
void op_bvs();
//op_sbc
inline void flags_sbc_b();
inline void flags_sbc_w();
void op_sbc_constb();
void op_sbc_constw();
void op_sbc_addrb();
void op_sbc_addrw();
void op_sbc_addrxb();
void op_sbc_addrxw();
void op_sbc_dpb();
void op_sbc_dpw();
void op_sbc_idpb();
void op_sbc_idpw();
void op_sbc_ildpb();
void op_sbc_ildpw();
void op_sbc_longb();
void op_sbc_longw();
void op_sbc_longxb();
void op_sbc_longxw();
void op_sbc_addryb();
void op_sbc_addryw();
void op_sbc_dpxb();
void op_sbc_dpxw();
void op_sbc_idpxb();
void op_sbc_idpxw();
void op_sbc_idpyb();
void op_sbc_idpyw();
void op_sbc_ildpyb();
void op_sbc_ildpyw();
void op_sbc_srb();
void op_sbc_srw();
void op_sbc_isryb();
void op_sbc_isryw();
//op_shift
void op_aslb();
void op_aslw();
void op_asl_addrb();
void op_asl_addrw();
void op_asl_addrxb();
void op_asl_addrxw();
void op_asl_dpb();
void op_asl_dpw();
void op_asl_dpxb();
void op_asl_dpxw();
void op_lsrb();
void op_lsrw();
void op_lsr_addrb();
void op_lsr_addrw();
void op_lsr_addrxb();
void op_lsr_addrxw();
void op_lsr_dpb();
void op_lsr_dpw();
void op_lsr_dpxb();
void op_lsr_dpxw();
void op_rolb();
void op_rolw();
void op_rol_addrb();
void op_rol_addrw();
void op_rol_addrxb();
void op_rol_addrxw();
void op_rol_dpb();
void op_rol_dpw();
void op_rol_dpxb();
void op_rol_dpxw();
void op_rorb();
void op_rorw();
void op_ror_addrb();
void op_ror_addrw();
void op_ror_addrxb();
void op_ror_addrxw();
void op_ror_dpb();
void op_ror_dpw();
void op_ror_dpxb();
void op_ror_dpxw();
//op_sta
void op_sta_addrb();
void op_sta_addrw();
void op_sta_addrxb();
void op_sta_addrxw();
void op_sta_dpb();
void op_sta_dpw();
void op_sta_idpb();
void op_sta_idpw();
void op_sta_ildpb();
void op_sta_ildpw();
void op_sta_longb();
void op_sta_longw();
void op_sta_longxb();
void op_sta_longxw();
void op_sta_addryb();
void op_sta_addryw();
void op_sta_dpxb();
void op_sta_dpxw();
void op_sta_idpxb();
void op_sta_idpxw();
void op_sta_idpyb();
void op_sta_idpyw();
void op_sta_ildpyb();
void op_sta_ildpyw();
void op_sta_srb();
void op_sta_srw();
void op_sta_isryb();
void op_sta_isryw();
//op_stack
void op_phab();
void op_phaw();
void op_phb();
void op_phd();
void op_phk();
void op_php();
void op_phxb();
void op_phxw();
void op_phyb();
void op_phyw();
void op_plab();
void op_plaw();
void op_plb();
void op_pld();
void op_plp();
void op_plxb();
void op_plxw();
void op_plyb();
void op_plyw();
void op_pea();
void op_pei();
void op_per();
//opcode functions
inline void init_op_tables();
//op_read
inline void op_adc_b();
inline void op_adc_w();
inline void op_and_b();
inline void op_and_w();
inline void op_bit_b();
inline void op_bit_w();
inline void op_cmp_b();
inline void op_cmp_w();
inline void op_cpx_b();
inline void op_cpx_w();
inline void op_cpy_b();
inline void op_cpy_w();
inline void op_eor_b();
inline void op_eor_w();
inline void op_lda_b();
inline void op_lda_w();
inline void op_ldx_b();
inline void op_ldx_w();
inline void op_ldy_b();
inline void op_ldy_w();
inline void op_ora_b();
inline void op_ora_w();
inline void op_sbc_b();
inline void op_sbc_w();
//op_rmw
inline void op_inc_b();
inline void op_inc_w();
inline void op_dec_b();
inline void op_dec_w();
inline void op_asl_b();
inline void op_asl_w();
inline void op_lsr_b();
inline void op_lsr_w();
inline void op_rol_b();
inline void op_rol_w();
inline void op_ror_b();
inline void op_ror_w();
inline void op_trb_b();
inline void op_trb_w();
inline void op_tsb_b();
inline void op_tsb_w();
#include "bcpu_op.h"
bCPU();
~bCPU();

241
src/cpu/bcpu/bcpu_dma.cpp Normal file
View File

@ -0,0 +1,241 @@
uint16 bCPU::dma_cputommio(uint8 i, uint8 index) {
uint8 x;
x = mem_bus->read(channel[i].srcaddr);
mem_bus->write(0x2100 | ((channel[i].destaddr + index) & 0xff), x);
if(channel[i].fixedxfer == false) {
channel[i].srcaddr = (channel[i].srcaddr & 0xff0000) + ((channel[i].srcaddr + channel[i].incmode) & 0xffff);
}
add_cycles(8);
return --channel[i].xfersize;
}
uint16 bCPU::dma_mmiotocpu(uint8 i, uint8 index) {
uint8 x;
x = mem_bus->read(0x2100 | ((channel[i].destaddr + index) & 0xff));
mem_bus->write(channel[i].srcaddr, x);
if(channel[i].fixedxfer == false) {
channel[i].srcaddr = (channel[i].srcaddr & 0xff0000) + ((channel[i].srcaddr + channel[i].incmode) & 0xffff);
}
add_cycles(8);
return --channel[i].xfersize;
}
void bCPU::dma_xfer_type0(uint8 i) {
if(channel[i].direction == 0) {
if(dma_cputommio(i, 0) == 0)return;
} else {
if(dma_mmiotocpu(i, 0) == 0)return;
}
}
void bCPU::dma_xfer_type1(uint8 i) {
if(channel[i].direction == 0) {
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 1) == 0)return;
} else {
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 1) == 0)return;
}
}
void bCPU::dma_xfer_type2(uint8 i) {
if(channel[i].direction == 0) {
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 0) == 0)return;
} else {
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 0) == 0)return;
}
}
void bCPU::dma_xfer_type3(uint8 i) {
if(channel[i].direction == 0) {
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 1) == 0)return;
if(dma_cputommio(i, 1) == 0)return;
} else {
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 1) == 0)return;
if(dma_mmiotocpu(i, 1) == 0)return;
}
}
void bCPU::dma_xfer_type4(uint8 i) {
if(channel[i].direction == 0) {
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 1) == 0)return;
if(dma_cputommio(i, 2) == 0)return;
if(dma_cputommio(i, 3) == 0)return;
} else {
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 1) == 0)return;
if(dma_mmiotocpu(i, 2) == 0)return;
if(dma_mmiotocpu(i, 3) == 0)return;
}
}
void bCPU::dma_xfer_type5(uint8 i) {
if(channel[i].direction == 0) {
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 1) == 0)return;
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 1) == 0)return;
} else {
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 1) == 0)return;
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 1) == 0)return;
}
}
void bCPU::dma_run() {
int i;
for(i=0;i<8;i++) {
if(channel[i].active == false)continue;
switch(channel[i].xfermode) {
case 0:dma_xfer_type0(i);break;
case 1:dma_xfer_type1(i);break;
case 2:dma_xfer_type2(i);break;
case 3:dma_xfer_type3(i);break;
case 4:dma_xfer_type4(i);break;
case 5:dma_xfer_type5(i);break;
case 6:dma_xfer_type2(i);break;
case 7:dma_xfer_type3(i);break;
}
if(channel[i].xfersize == 0) {
channel[i].active = false;
}
return;
}
status.dma_state = DMASTATE_CPUSYNC;
}
void bCPU::hdma_write(uint8 i, uint8 l, uint8 x) {
switch(channel[i].xfermode) {
case 0:mem_bus->write(0x2100 | ((channel[i].destaddr) & 0xff), x);break;
case 1:mem_bus->write(0x2100 | ((channel[i].destaddr + l) & 0xff), x);break;
case 2:mem_bus->write(0x2100 | ((channel[i].destaddr) & 0xff), x);break;
case 3:mem_bus->write(0x2100 | ((channel[i].destaddr + (l >> 1)) & 0xff), x);break;
case 4:mem_bus->write(0x2100 | ((channel[i].destaddr + l) & 0xff), x);break;
case 5:mem_bus->write(0x2100 | ((channel[i].destaddr + (l & 1)) & 0xff), x);break;
case 6:mem_bus->write(0x2100 | ((channel[i].destaddr) & 0xff), x);break;
case 7:mem_bus->write(0x2100 | ((channel[i].destaddr + (l >> 1)) & 0xff), x);break;
}
}
void bCPU::hdma_run() {
int l, xferlen;
uint8 x, active_channels = 0;
for(int i=0;i<8;i++) {
if(channel[i].hdma_completed == true)continue;
// add_cycles(8);
active_channels++;
if(channel[i].hdma_line_counter == 0) {
channel[i].hdma_line_counter = mem_bus->read(channel[i].hdma_taddr++);
if(channel[i].hdma_line_counter == 0) {
channel[i].hdma_completed = true;
continue;
}
if(channel[i].hdma_line_counter > 0x80) {
channel[i].hdma_repeat = true;
channel[i].hdma_line_counter -= 0x80;
} else {
channel[i].hdma_repeat = false;
}
channel[i].hdma_first_line = true;
if(channel[i].hdma_indirect == false) {
channel[i].hdma_itaddr = channel[i].hdma_taddr;
} else {
channel[i].hdma_itaddr = mem_bus->read(channel[i].hdma_taddr++);
channel[i].hdma_itaddr |= mem_bus->read(channel[i].hdma_taddr++) << 8;
channel[i].hdma_itaddr |= channel[i].hdma_indirect_bank << 16;
// add_cycles(16);
}
}
channel[i].hdma_line_counter--;
if(channel[i].hdma_first_line == false && channel[i].hdma_repeat == false)continue;
channel[i].hdma_first_line = false;
if(channel[i].hdma_indirect == false) {
channel[i].hdma_itaddr = channel[i].hdma_taddr;
}
switch(channel[i].xfermode) {
case 0: xferlen = 1;break;
case 1:case 2:case 6: xferlen = 2;break;
case 3:case 4:case 5:case 7:xferlen = 4;break;
}
for(l=0;l<xferlen;l++) {
x = mem_bus->read(channel[i].hdma_itaddr++);
if(channel[i].hdma_indirect == false) {
channel[i].hdma_taddr++;
}
hdma_write(i, l, x);
// add_cycles(8);
}
}
if(active_channels != 0) {
// add_cycles(18);
}
}
void bCPU::hdma_initialize() {
uint8 active_channels = 0;
for(int i=0;i<8;i++) {
if(channel[i].hdma_active == false) {
channel[i].hdma_completed = true;
continue;
}
active_channels++;
channel[i].hdma_first_line = true;
channel[i].hdma_repeat = false;
channel[i].hdma_taddr = channel[i].srcaddr;
channel[i].hdma_line_counter = 0x00;
channel[i].hdma_completed = false;
if(channel[i].hdma_indirect == false) {
add_cycles(8);
} else {
add_cycles(24);
}
}
if(active_channels != 0) {
add_cycles(18);
}
}
void bCPU::dma_reset() {
for(int i=0;i<8;i++) {
channel[i].active = false;
channel[i].hdma_active = false;
channel[i].dmap = 0x00;
channel[i].direction = 0;
channel[i].hdma_indirect = false;
channel[i].incmode = 1;
channel[i].fixedxfer = false;
channel[i].xfermode = 0;
channel[i].destaddr = 0;
channel[i].srcaddr = 0;
channel[i].xfersize = 0;
channel[i].hdma_indirect_bank = 0;
channel[i].hdma_taddr = 0x000000;
channel[i].hdma_line_counter = 0x00;
channel[i].hdma_unknown = 0x00;
channel[i].hdma_first_line = false;
channel[i].hdma_repeat = false;
channel[i].hdma_itaddr = 0x000000;
channel[i].hdma_completed = true;
}
}

View File

@ -1,519 +1,42 @@
inline void bCPU::cycle_edge() {
int c, n, z;
if(status.dma_state != DMASTATE_STOP) {
switch(status.dma_state) {
case DMASTATE_INIT:
status.dma_state = DMASTATE_DMASYNC;
break;
case DMASTATE_DMASYNC:
n = 8 - dma_counter() + 8;
add_cycles(n);
status.dma_cycle_count = n;
for(z=0;z<8;z++) {
if(channel[z].active == false)continue;
add_cycles(8);
status.dma_cycle_count += 8;
status.dma_cycle_count += channel[z].xfersize << 3;
}
status.cpu_state = CPUSTATE_DMA;
status.dma_state = DMASTATE_RUN;
while(status.dma_state == DMASTATE_RUN) {
dma_run();
}
status.cpu_state = CPUSTATE_RUN;
c = status.cycle_count;
z = c - (status.dma_cycle_count % c);
if(!z)z = c;
add_cycles(z);
status.dma_state = DMASTATE_STOP;
break;
}
}
}
void bCPU::exec_opcode() {
snes->notify(SNES::CPU_EXEC_OPCODE_BEGIN);
(this->*optbl[op_read()])();
snes->notify(SNES::CPU_EXEC_OPCODE);
snes->notify(SNES::CPU_EXEC_OPCODE_END);
}
void bCPU::init_op_tables() {
optbl = optbl_e;
/* 0x */
optbl[0x00] = op_brk;
optbl[0x01] = op_ora_idpxb;
optbl[0x02] = op_cop;
optbl[0x03] = op_ora_srb;
optbl[0x04] = op_tsb_dpb;
optbl[0x05] = op_ora_dpb;
optbl[0x06] = op_asl_dpb;
optbl[0x07] = op_ora_ildpb;
optbl[0x08] = op_php;
optbl[0x09] = op_ora_constb;
optbl[0x0a] = op_aslb;
optbl[0x0b] = op_phd;
optbl[0x0c] = op_tsb_addrb;
optbl[0x0d] = op_ora_addrb;
optbl[0x0e] = op_asl_addrb;
optbl[0x0f] = op_ora_longb;
/* 1x */
optbl[0x10] = op_bpl;
optbl[0x11] = op_ora_idpyb;
optbl[0x12] = op_ora_idpb;
optbl[0x13] = op_ora_isryb;
optbl[0x14] = op_trb_dpb;
optbl[0x15] = op_ora_dpxb;
optbl[0x16] = op_asl_dpxb;
optbl[0x17] = op_ora_ildpyb;
optbl[0x18] = op_clc;
optbl[0x19] = op_ora_addryb;
optbl[0x1a] = op_incb;
optbl[0x1b] = op_tcs;
optbl[0x1c] = op_trb_addrb;
optbl[0x1d] = op_ora_addrxb;
optbl[0x1e] = op_asl_addrxb;
optbl[0x1f] = op_ora_longxb;
/* 2x */
optbl[0x20] = op_jsr_addr;
optbl[0x21] = op_and_idpxb;
optbl[0x22] = op_jsr_long;
optbl[0x23] = op_and_srb;
optbl[0x24] = op_bit_dpb;
optbl[0x25] = op_and_dpb;
optbl[0x26] = op_rol_dpb;
optbl[0x27] = op_and_ildpb;
optbl[0x28] = op_plp;
optbl[0x29] = op_and_constb;
optbl[0x2a] = op_rolb;
optbl[0x2b] = op_pld;
optbl[0x2c] = op_bit_addrb;
optbl[0x2d] = op_and_addrb;
optbl[0x2e] = op_rol_addrb;
optbl[0x2f] = op_and_longb;
/* 3x */
optbl[0x30] = op_bmi;
optbl[0x31] = op_and_idpyb;
optbl[0x32] = op_and_idpb;
optbl[0x33] = op_and_isryb;
optbl[0x34] = op_bit_dpxb;
optbl[0x35] = op_and_dpxb;
optbl[0x36] = op_rol_dpxb;
optbl[0x37] = op_and_ildpyb;
optbl[0x38] = op_sec;
optbl[0x39] = op_and_addryb;
optbl[0x3a] = op_decb;
optbl[0x3b] = op_tsc;
optbl[0x3c] = op_bit_addrxb;
optbl[0x3d] = op_and_addrxb;
optbl[0x3e] = op_rol_addrxb;
optbl[0x3f] = op_and_longxb;
/* 4x */
optbl[0x40] = op_rtie;
optbl[0x41] = op_eor_idpxb;
optbl[0x42] = op_wdm;
optbl[0x43] = op_eor_srb;
optbl[0x44] = op_mvp;
optbl[0x45] = op_eor_dpb;
optbl[0x46] = op_lsr_dpb;
optbl[0x47] = op_eor_ildpb;
optbl[0x48] = op_phab;
optbl[0x49] = op_eor_constb;
optbl[0x4a] = op_lsrb;
optbl[0x4b] = op_phk;
optbl[0x4c] = op_jmp_addr;
optbl[0x4d] = op_eor_addrb;
optbl[0x4e] = op_lsr_addrb;
optbl[0x4f] = op_eor_longb;
/* 5x */
optbl[0x50] = op_bvc;
optbl[0x51] = op_eor_idpyb;
optbl[0x52] = op_eor_idpb;
optbl[0x53] = op_eor_isryb;
optbl[0x54] = op_mvn;
optbl[0x55] = op_eor_dpxb;
optbl[0x56] = op_lsr_dpxb;
optbl[0x57] = op_eor_ildpyb;
optbl[0x58] = op_cli;
optbl[0x59] = op_eor_addryb;
optbl[0x5a] = op_phyb;
optbl[0x5b] = op_tcd;
optbl[0x5c] = op_jmp_long;
optbl[0x5d] = op_eor_addrxb;
optbl[0x5e] = op_lsr_addrxb;
optbl[0x5f] = op_eor_longxb;
/* 6x */
optbl[0x60] = op_rts;
optbl[0x61] = op_adc_idpxb;
optbl[0x62] = op_per;
optbl[0x63] = op_adc_srb;
optbl[0x64] = op_stz_dpb;
optbl[0x65] = op_adc_dpb;
optbl[0x66] = op_ror_dpb;
optbl[0x67] = op_adc_ildpb;
optbl[0x68] = op_plab;
optbl[0x69] = op_adc_constb;
optbl[0x6a] = op_rorb;
optbl[0x6b] = op_rtl;
optbl[0x6c] = op_jmp_iaddr;
optbl[0x6d] = op_adc_addrb;
optbl[0x6e] = op_ror_addrb;
optbl[0x6f] = op_adc_longb;
/* 7x */
optbl[0x70] = op_bvs;
optbl[0x71] = op_adc_idpyb;
optbl[0x72] = op_adc_idpb;
optbl[0x73] = op_adc_isryb;
optbl[0x74] = op_stz_dpxb;
optbl[0x75] = op_adc_dpxb;
optbl[0x76] = op_ror_dpxb;
optbl[0x77] = op_adc_ildpyb;
optbl[0x78] = op_sei;
optbl[0x79] = op_adc_addryb;
optbl[0x7a] = op_plyb;
optbl[0x7b] = op_tdc;
optbl[0x7c] = op_jmp_iaddrx;
optbl[0x7d] = op_adc_addrxb;
optbl[0x7e] = op_ror_addrxb;
optbl[0x7f] = op_adc_longxb;
/* 8x */
optbl[0x80] = op_bra;
optbl[0x81] = op_sta_idpxb;
optbl[0x82] = op_brl;
optbl[0x83] = op_sta_srb;
optbl[0x84] = op_sty_dpb;
optbl[0x85] = op_sta_dpb;
optbl[0x86] = op_stx_dpb;
optbl[0x87] = op_sta_ildpb;
optbl[0x88] = op_deyb;
optbl[0x89] = op_bit_constb;
optbl[0x8a] = op_txab;
optbl[0x8b] = op_phb;
optbl[0x8c] = op_sty_addrb;
optbl[0x8d] = op_sta_addrb;
optbl[0x8e] = op_stx_addrb;
optbl[0x8f] = op_sta_longb;
/* 9x */
optbl[0x90] = op_bcc;
optbl[0x91] = op_sta_idpyb;
optbl[0x92] = op_sta_idpb;
optbl[0x93] = op_sta_isryb;
optbl[0x94] = op_sty_dpxb;
optbl[0x95] = op_sta_dpxb;
optbl[0x96] = op_stx_dpyb;
optbl[0x97] = op_sta_ildpyb;
optbl[0x98] = op_tyab;
optbl[0x99] = op_sta_addryb;
optbl[0x9a] = op_txsb;
optbl[0x9b] = op_txyb;
optbl[0x9c] = op_stz_addrb;
optbl[0x9d] = op_sta_addrxb;
optbl[0x9e] = op_stz_addrxb;
optbl[0x9f] = op_sta_longxb;
/* ax */
optbl[0xa0] = op_ldy_constb;
optbl[0xa1] = op_lda_idpxb;
optbl[0xa2] = op_ldx_constb;
optbl[0xa3] = op_lda_srb;
optbl[0xa4] = op_ldy_dpb;
optbl[0xa5] = op_lda_dpb;
optbl[0xa6] = op_ldx_dpb;
optbl[0xa7] = op_lda_ildpb;
optbl[0xa8] = op_tayb;
optbl[0xa9] = op_lda_constb;
optbl[0xaa] = op_taxb;
optbl[0xab] = op_plb;
optbl[0xac] = op_ldy_addrb;
optbl[0xad] = op_lda_addrb;
optbl[0xae] = op_ldx_addrb;
optbl[0xaf] = op_lda_longb;
/* bx */
optbl[0xb0] = op_bcs;
optbl[0xb1] = op_lda_idpyb;
optbl[0xb2] = op_lda_idpb;
optbl[0xb3] = op_lda_isryb;
optbl[0xb4] = op_ldy_dpxb;
optbl[0xb5] = op_lda_dpxb;
optbl[0xb6] = op_ldx_dpyb;
optbl[0xb7] = op_lda_ildpyb;
optbl[0xb8] = op_clv;
optbl[0xb9] = op_lda_addryb;
optbl[0xba] = op_tsxb;
optbl[0xbb] = op_tyxb;
optbl[0xbc] = op_ldy_addrxb;
optbl[0xbd] = op_lda_addrxb;
optbl[0xbe] = op_ldx_addryb;
optbl[0xbf] = op_lda_longxb;
/* cx */
optbl[0xc0] = op_cpy_constb;
optbl[0xc1] = op_cmp_idpxb;
optbl[0xc2] = op_rep;
optbl[0xc3] = op_cmp_srb;
optbl[0xc4] = op_cpy_dpb;
optbl[0xc5] = op_cmp_dpb;
optbl[0xc6] = op_dec_dpb;
optbl[0xc7] = op_cmp_ildpb;
optbl[0xc8] = op_inyb;
optbl[0xc9] = op_cmp_constb;
optbl[0xca] = op_dexb;
optbl[0xcb] = op_wai;
optbl[0xcc] = op_cpy_addrb;
optbl[0xcd] = op_cmp_addrb;
optbl[0xce] = op_dec_addrb;
optbl[0xcf] = op_cmp_longb;
/* dx */
optbl[0xd0] = op_bne;
optbl[0xd1] = op_cmp_idpyb;
optbl[0xd2] = op_cmp_idpb;
optbl[0xd3] = op_cmp_isryb;
optbl[0xd4] = op_pei;
optbl[0xd5] = op_cmp_dpxb;
optbl[0xd6] = op_dec_dpxb;
optbl[0xd7] = op_cmp_ildpyb;
optbl[0xd8] = op_cld;
optbl[0xd9] = op_cmp_addryb;
optbl[0xda] = op_phxb;
optbl[0xdb] = op_stp;
optbl[0xdc] = op_jmp_iladdr;
optbl[0xdd] = op_cmp_addrxb;
optbl[0xde] = op_dec_addrxb;
optbl[0xdf] = op_cmp_longxb;
/* ex */
optbl[0xe0] = op_cpx_constb;
optbl[0xe1] = op_sbc_idpxb;
optbl[0xe2] = op_sep;
optbl[0xe3] = op_sbc_srb;
optbl[0xe4] = op_cpx_dpb;
optbl[0xe5] = op_sbc_dpb;
optbl[0xe6] = op_inc_dpb;
optbl[0xe7] = op_sbc_ildpb;
optbl[0xe8] = op_inxb;
optbl[0xe9] = op_sbc_constb;
optbl[0xea] = op_nop;
optbl[0xeb] = op_xba;
optbl[0xec] = op_cpx_addrb;
optbl[0xed] = op_sbc_addrb;
optbl[0xee] = op_inc_addrb;
optbl[0xef] = op_sbc_longb;
/* fx */
optbl[0xf0] = op_beq;
optbl[0xf1] = op_sbc_idpyb;
optbl[0xf2] = op_sbc_idpb;
optbl[0xf3] = op_sbc_isryb;
optbl[0xf4] = op_pea;
optbl[0xf5] = op_sbc_dpxb;
optbl[0xf6] = op_inc_dpxb;
optbl[0xf7] = op_sbc_ildpyb;
optbl[0xf8] = op_sed;
optbl[0xf9] = op_sbc_addryb;
optbl[0xfa] = op_plxb;
optbl[0xfb] = op_xce;
optbl[0xfc] = op_jsr_iaddrx;
optbl[0xfd] = op_sbc_addrxb;
optbl[0xfe] = op_inc_addrxb;
optbl[0xff] = op_sbc_longxb;
memcpy(optbl_MX, optbl_e, sizeof(optbl_e));
memcpy(optbl_Mx, optbl_e, sizeof(optbl_e));
memcpy(optbl_mX, optbl_e, sizeof(optbl_e));
memcpy(optbl_mx, optbl_e, sizeof(optbl_e));
/* adc */
optbl_mX[0x69] = optbl_mx[0x69] = op_adc_constw;
optbl_mX[0x6d] = optbl_mx[0x6d] = op_adc_addrw;
optbl_mX[0x7d] = optbl_mx[0x7d] = op_adc_addrxw;
optbl_mX[0x65] = optbl_mx[0x65] = op_adc_dpw;
optbl_mX[0x72] = optbl_mx[0x72] = op_adc_idpw;
optbl_mX[0x67] = optbl_mx[0x67] = op_adc_ildpw;
optbl_mX[0x6f] = optbl_mx[0x6f] = op_adc_longw;
optbl_mX[0x7f] = optbl_mx[0x7f] = op_adc_longxw;
optbl_mX[0x79] = optbl_mx[0x79] = op_adc_addryw;
optbl_mX[0x75] = optbl_mx[0x75] = op_adc_dpxw;
optbl_mX[0x61] = optbl_mx[0x61] = op_adc_idpxw;
optbl_mX[0x71] = optbl_mx[0x71] = op_adc_idpyw;
optbl_mX[0x77] = optbl_mx[0x77] = op_adc_ildpyw;
optbl_mX[0x63] = optbl_mx[0x63] = op_adc_srw;
optbl_mX[0x73] = optbl_mx[0x73] = op_adc_isryw;
/* and */
optbl_mX[0x29] = optbl_mx[0x29] = op_and_constw;
optbl_mX[0x2d] = optbl_mx[0x2d] = op_and_addrw;
optbl_mX[0x3d] = optbl_mx[0x3d] = op_and_addrxw;
optbl_mX[0x25] = optbl_mx[0x25] = op_and_dpw;
optbl_mX[0x32] = optbl_mx[0x32] = op_and_idpw;
optbl_mX[0x27] = optbl_mx[0x27] = op_and_ildpw;
optbl_mX[0x2f] = optbl_mx[0x2f] = op_and_longw;
optbl_mX[0x3f] = optbl_mx[0x3f] = op_and_longxw;
optbl_mX[0x39] = optbl_mx[0x39] = op_and_addryw;
optbl_mX[0x35] = optbl_mx[0x35] = op_and_dpxw;
optbl_mX[0x21] = optbl_mx[0x21] = op_and_idpxw;
optbl_mX[0x31] = optbl_mx[0x31] = op_and_idpyw;
optbl_mX[0x37] = optbl_mx[0x37] = op_and_ildpyw;
optbl_mX[0x23] = optbl_mx[0x23] = op_and_srw;
optbl_mX[0x33] = optbl_mx[0x33] = op_and_isryw;
/* cmp */
optbl_mX[0xc9] = optbl_mx[0xc9] = op_cmp_constw;
optbl_mX[0xcd] = optbl_mx[0xcd] = op_cmp_addrw;
optbl_mX[0xdd] = optbl_mx[0xdd] = op_cmp_addrxw;
optbl_mX[0xc5] = optbl_mx[0xc5] = op_cmp_dpw;
optbl_mX[0xd2] = optbl_mx[0xd2] = op_cmp_idpw;
optbl_mX[0xc7] = optbl_mx[0xc7] = op_cmp_ildpw;
optbl_mX[0xcf] = optbl_mx[0xcf] = op_cmp_longw;
optbl_mX[0xdf] = optbl_mx[0xdf] = op_cmp_longxw;
optbl_mX[0xd9] = optbl_mx[0xd9] = op_cmp_addryw;
optbl_mX[0xd5] = optbl_mx[0xd5] = op_cmp_dpxw;
optbl_mX[0xc1] = optbl_mx[0xc1] = op_cmp_idpxw;
optbl_mX[0xd1] = optbl_mx[0xd1] = op_cmp_idpyw;
optbl_mX[0xd7] = optbl_mx[0xd7] = op_cmp_ildpyw;
optbl_mX[0xc3] = optbl_mx[0xc3] = op_cmp_srw;
optbl_mX[0xd3] = optbl_mx[0xd3] = op_cmp_isryw;
/* eor */
optbl_mX[0x49] = optbl_mx[0x49] = op_eor_constw;
optbl_mX[0x4d] = optbl_mx[0x4d] = op_eor_addrw;
optbl_mX[0x5d] = optbl_mx[0x5d] = op_eor_addrxw;
optbl_mX[0x45] = optbl_mx[0x45] = op_eor_dpw;
optbl_mX[0x52] = optbl_mx[0x52] = op_eor_idpw;
optbl_mX[0x47] = optbl_mx[0x47] = op_eor_ildpw;
optbl_mX[0x4f] = optbl_mx[0x4f] = op_eor_longw;
optbl_mX[0x5f] = optbl_mx[0x5f] = op_eor_longxw;
optbl_mX[0x59] = optbl_mx[0x59] = op_eor_addryw;
optbl_mX[0x55] = optbl_mx[0x55] = op_eor_dpxw;
optbl_mX[0x41] = optbl_mx[0x41] = op_eor_idpxw;
optbl_mX[0x51] = optbl_mx[0x51] = op_eor_idpyw;
optbl_mX[0x57] = optbl_mx[0x57] = op_eor_ildpyw;
optbl_mX[0x43] = optbl_mx[0x43] = op_eor_srw;
optbl_mX[0x53] = optbl_mx[0x53] = op_eor_isryw;
/* lda */
optbl_mX[0xa9] = optbl_mx[0xa9] = op_lda_constw;
optbl_mX[0xad] = optbl_mx[0xad] = op_lda_addrw;
optbl_mX[0xbd] = optbl_mx[0xbd] = op_lda_addrxw;
optbl_mX[0xa5] = optbl_mx[0xa5] = op_lda_dpw;
optbl_mX[0xb2] = optbl_mx[0xb2] = op_lda_idpw;
optbl_mX[0xa7] = optbl_mx[0xa7] = op_lda_ildpw;
optbl_mX[0xaf] = optbl_mx[0xaf] = op_lda_longw;
optbl_mX[0xbf] = optbl_mx[0xbf] = op_lda_longxw;
optbl_mX[0xb9] = optbl_mx[0xb9] = op_lda_addryw;
optbl_mX[0xb5] = optbl_mx[0xb5] = op_lda_dpxw;
optbl_mX[0xa1] = optbl_mx[0xa1] = op_lda_idpxw;
optbl_mX[0xb1] = optbl_mx[0xb1] = op_lda_idpyw;
optbl_mX[0xb7] = optbl_mx[0xb7] = op_lda_ildpyw;
optbl_mX[0xa3] = optbl_mx[0xa3] = op_lda_srw;
optbl_mX[0xb3] = optbl_mx[0xb3] = op_lda_isryw;
/* ora */
optbl_mX[0x09] = optbl_mx[0x09] = op_ora_constw;
optbl_mX[0x0d] = optbl_mx[0x0d] = op_ora_addrw;
optbl_mX[0x1d] = optbl_mx[0x1d] = op_ora_addrxw;
optbl_mX[0x05] = optbl_mx[0x05] = op_ora_dpw;
optbl_mX[0x12] = optbl_mx[0x12] = op_ora_idpw;
optbl_mX[0x07] = optbl_mx[0x07] = op_ora_ildpw;
optbl_mX[0x0f] = optbl_mx[0x0f] = op_ora_longw;
optbl_mX[0x1f] = optbl_mx[0x1f] = op_ora_longxw;
optbl_mX[0x19] = optbl_mx[0x19] = op_ora_addryw;
optbl_mX[0x15] = optbl_mx[0x15] = op_ora_dpxw;
optbl_mX[0x01] = optbl_mx[0x01] = op_ora_idpxw;
optbl_mX[0x11] = optbl_mx[0x11] = op_ora_idpyw;
optbl_mX[0x17] = optbl_mx[0x17] = op_ora_ildpyw;
optbl_mX[0x03] = optbl_mx[0x03] = op_ora_srw;
optbl_mX[0x13] = optbl_mx[0x13] = op_ora_isryw;
/* sbc */
optbl_mX[0xe9] = optbl_mx[0xe9] = op_sbc_constw;
optbl_mX[0xed] = optbl_mx[0xed] = op_sbc_addrw;
optbl_mX[0xfd] = optbl_mx[0xfd] = op_sbc_addrxw;
optbl_mX[0xe5] = optbl_mx[0xe5] = op_sbc_dpw;
optbl_mX[0xf2] = optbl_mx[0xf2] = op_sbc_idpw;
optbl_mX[0xe7] = optbl_mx[0xe7] = op_sbc_ildpw;
optbl_mX[0xef] = optbl_mx[0xef] = op_sbc_longw;
optbl_mX[0xff] = optbl_mx[0xff] = op_sbc_longxw;
optbl_mX[0xf9] = optbl_mx[0xf9] = op_sbc_addryw;
optbl_mX[0xf5] = optbl_mx[0xf5] = op_sbc_dpxw;
optbl_mX[0xe1] = optbl_mx[0xe1] = op_sbc_idpxw;
optbl_mX[0xf1] = optbl_mx[0xf1] = op_sbc_idpyw;
optbl_mX[0xf7] = optbl_mx[0xf7] = op_sbc_ildpyw;
optbl_mX[0xe3] = optbl_mx[0xe3] = op_sbc_srw;
optbl_mX[0xf3] = optbl_mx[0xf3] = op_sbc_isryw;
/* sta */
optbl_mX[0x8d] = optbl_mx[0x8d] = op_sta_addrw;
optbl_mX[0x9d] = optbl_mx[0x9d] = op_sta_addrxw;
optbl_mX[0x85] = optbl_mx[0x85] = op_sta_dpw;
optbl_mX[0x92] = optbl_mx[0x92] = op_sta_idpw;
optbl_mX[0x87] = optbl_mx[0x87] = op_sta_ildpw;
optbl_mX[0x8f] = optbl_mx[0x8f] = op_sta_longw;
optbl_mX[0x9f] = optbl_mx[0x9f] = op_sta_longxw;
optbl_mX[0x99] = optbl_mx[0x99] = op_sta_addryw;
optbl_mX[0x95] = optbl_mx[0x95] = op_sta_dpxw;
optbl_mX[0x81] = optbl_mx[0x81] = op_sta_idpxw;
optbl_mX[0x91] = optbl_mx[0x91] = op_sta_idpyw;
optbl_mX[0x97] = optbl_mx[0x97] = op_sta_ildpyw;
optbl_mX[0x83] = optbl_mx[0x83] = op_sta_srw;
optbl_mX[0x93] = optbl_mx[0x93] = op_sta_isryw;
/* incdec */
optbl_mX[0x1a] = optbl_mx[0x1a] = op_incw;
optbl_mX[0xee] = optbl_mx[0xee] = op_inc_addrw;
optbl_mX[0xfe] = optbl_mx[0xfe] = op_inc_addrxw;
optbl_mX[0xe6] = optbl_mx[0xe6] = op_inc_dpw;
optbl_mX[0xf6] = optbl_mx[0xf6] = op_inc_dpxw;
optbl_mX[0x3a] = optbl_mx[0x3a] = op_decw;
optbl_mX[0xce] = optbl_mx[0xce] = op_dec_addrw;
optbl_mX[0xde] = optbl_mx[0xde] = op_dec_addrxw;
optbl_mX[0xc6] = optbl_mx[0xc6] = op_dec_dpw;
optbl_mX[0xd6] = optbl_mx[0xd6] = op_dec_dpxw;
optbl_Mx[0xe8] = optbl_mx[0xe8] = op_inxw;
optbl_Mx[0xc8] = optbl_mx[0xc8] = op_inyw;
optbl_Mx[0xca] = optbl_mx[0xca] = op_dexw;
optbl_Mx[0x88] = optbl_mx[0x88] = op_deyw;
/* misc */
optbl_mX[0x89] = optbl_mx[0x89] = op_bit_constw;
optbl_mX[0x2c] = optbl_mx[0x2c] = op_bit_addrw;
optbl_mX[0x3c] = optbl_mx[0x3c] = op_bit_addrxw;
optbl_mX[0x24] = optbl_mx[0x24] = op_bit_dpw;
optbl_mX[0x34] = optbl_mx[0x34] = op_bit_dpxw;
optbl_mX[0x9c] = optbl_mx[0x9c] = op_stz_addrw;
optbl_mX[0x9e] = optbl_mx[0x9e] = op_stz_addrxw;
optbl_mX[0x64] = optbl_mx[0x64] = op_stz_dpw;
optbl_mX[0x74] = optbl_mx[0x74] = op_stz_dpxw;
optbl_mX[0x1c] = optbl_mx[0x1c] = op_trb_addrw;
optbl_mX[0x14] = optbl_mx[0x14] = op_trb_dpw;
optbl_mX[0x0c] = optbl_mx[0x0c] = op_tsb_addrw;
optbl_mX[0x04] = optbl_mx[0x04] = op_tsb_dpw;
optbl_mX[0x8a] = optbl_mx[0x8a] = op_txaw;
optbl_mX[0x98] = optbl_mx[0x98] = op_tyaw;
optbl_Mx[0xe0] = optbl_mx[0xe0] = op_cpx_constw;
optbl_Mx[0xec] = optbl_mx[0xec] = op_cpx_addrw;
optbl_Mx[0xe4] = optbl_mx[0xe4] = op_cpx_dpw;
optbl_Mx[0xc0] = optbl_mx[0xc0] = op_cpy_constw;
optbl_Mx[0xcc] = optbl_mx[0xcc] = op_cpy_addrw;
optbl_Mx[0xc4] = optbl_mx[0xc4] = op_cpy_dpw;
optbl_Mx[0xa2] = optbl_mx[0xa2] = op_ldx_constw;
optbl_Mx[0xae] = optbl_mx[0xae] = op_ldx_addrw;
optbl_Mx[0xbe] = optbl_mx[0xbe] = op_ldx_addryw;
optbl_Mx[0xa6] = optbl_mx[0xa6] = op_ldx_dpw;
optbl_Mx[0xb6] = optbl_mx[0xb6] = op_ldx_dpyw;
optbl_Mx[0xa0] = optbl_mx[0xa0] = op_ldy_constw;
optbl_Mx[0xac] = optbl_mx[0xac] = op_ldy_addrw;
optbl_Mx[0xbc] = optbl_mx[0xbc] = op_ldy_addrxw;
optbl_Mx[0xa4] = optbl_mx[0xa4] = op_ldy_dpw;
optbl_Mx[0xb4] = optbl_mx[0xb4] = op_ldy_dpxw;
optbl_Mx[0x8e] = optbl_mx[0x8e] = op_stx_addrw;
optbl_Mx[0x86] = optbl_mx[0x86] = op_stx_dpw;
optbl_Mx[0x96] = optbl_mx[0x96] = op_stx_dpyw;
optbl_Mx[0x8c] = optbl_mx[0x8c] = op_sty_addrw;
optbl_Mx[0x84] = optbl_mx[0x84] = op_sty_dpw;
optbl_Mx[0x94] = optbl_mx[0x94] = op_sty_dpxw;
optbl_Mx[0xaa] = optbl_mx[0xaa] = op_taxw;
optbl_Mx[0xa8] = optbl_mx[0xa8] = op_tayw;
optbl_Mx[0xba] = optbl_mx[0xba] = op_tsxw;
optbl_Mx[0x9a] = optbl_mx[0x9a] = op_txsw;
optbl_Mx[0x9b] = optbl_mx[0x9b] = op_txyw;
optbl_Mx[0xbb] = optbl_mx[0xbb] = op_tyxw;
/* pc */
optbl_MX[0x40] = optbl_Mx[0x40] = op_rtin;
optbl_mX[0x40] = optbl_mx[0x40] = op_rtin;
/* shift */
optbl_mX[0x0a] = optbl_mx[0x0a] = op_aslw;
optbl_mX[0x0e] = optbl_mx[0x0e] = op_asl_addrw;
optbl_mX[0x1e] = optbl_mx[0x1e] = op_asl_addrxw;
optbl_mX[0x06] = optbl_mx[0x06] = op_asl_dpw;
optbl_mX[0x16] = optbl_mx[0x16] = op_asl_dpxw;
optbl_mX[0x4a] = optbl_mx[0x4a] = op_lsrw;
optbl_mX[0x4e] = optbl_mx[0x4e] = op_lsr_addrw;
optbl_mX[0x5e] = optbl_mx[0x5e] = op_lsr_addrxw;
optbl_mX[0x46] = optbl_mx[0x46] = op_lsr_dpw;
optbl_mX[0x56] = optbl_mx[0x56] = op_lsr_dpxw;
optbl_mX[0x2a] = optbl_mx[0x2a] = op_rolw;
optbl_mX[0x2e] = optbl_mx[0x2e] = op_rol_addrw;
optbl_mX[0x3e] = optbl_mx[0x3e] = op_rol_addrxw;
optbl_mX[0x26] = optbl_mx[0x26] = op_rol_dpw;
optbl_mX[0x36] = optbl_mx[0x36] = op_rol_dpxw;
optbl_mX[0x6a] = optbl_mx[0x6a] = op_rorw;
optbl_mX[0x6e] = optbl_mx[0x6e] = op_ror_addrw;
optbl_mX[0x7e] = optbl_mx[0x7e] = op_ror_addrxw;
optbl_mX[0x66] = optbl_mx[0x66] = op_ror_dpw;
optbl_mX[0x76] = optbl_mx[0x76] = op_ror_dpxw;
/* stack */
optbl_mX[0x48] = optbl_mx[0x48] = op_phaw;
optbl_mX[0x68] = optbl_mx[0x68] = op_plaw;
optbl_Mx[0xda] = optbl_mx[0xda] = op_phxw;
optbl_Mx[0x5a] = optbl_mx[0x5a] = op_phyw;
optbl_Mx[0xfa] = optbl_mx[0xfa] = op_plxw;
optbl_Mx[0x7a] = optbl_mx[0x7a] = op_plyw;
#include "bcpu_optable.cpp"
}

View File

@ -91,26 +91,22 @@ uint8 r = 0x00;
//RDNMI
uint8 bCPU::mmio_r4210() {
uint8 r = 0x00;
uint16 v, h, hcycles, visible_scanlines;
v = clock->vcounter();
h = clock->hcounter();
hcycles = clock->hcycles();
visible_scanlines = clock->visible_scanlines();
uint16 v, h, hc, vs;
v = vcounter();
h = hcounter();
hc = hcycles();
vs = (overscan()?239:224);
if(status.r4210_read == false) {
if(v == 0 && hcycles < 2) {
r |= 0x80;
status.r4210_read = true;
} else if(v == (visible_scanlines + 1) && hcycles >= 2) {
r |= 0x80;
status.r4210_read = true;
} else if(v >= (visible_scanlines + 1)) {
if((v == (vs + 1) && hc >= 2) || v > (vs + 1)) {
r |= 0x80;
status.r4210_read = true;
status.nmi_pin = 1;
}
}
r |= 0x40;
r |= 0x02; //cpu version number
status.nmi_pin = 1;
return r;
}
@ -126,24 +122,22 @@ uint8 r = 0x00;
//HVBJOY
uint8 bCPU::mmio_r4212() {
uint8 r;
uint16 v, h, hcycles, visible_scanlines;
uint16 v, h, hc, vs;
r = 0x00;
v = clock->vcounter();
h = clock->hcounter();
hcycles = clock->hcycles();
visible_scanlines = clock->visible_scanlines();
v = vcounter();
h = hcounter();
hc = hcycles();
vs = (overscan()?239:224);
//auto joypad polling
if(v >= (visible_scanlines + 1) && v <= (visible_scanlines + 3))r |= 0x01;
if(v >= (vs + 1) && v <= (vs + 3))r |= 0x01;
//hblank
if(hcycles <= 4 || hcycles >= 1098)r |= 0x40;
if(hc <= 2 || hc >= 1096)r |= 0x40;
//vblank
if(v == 0 && hcycles < 2)r |= 0x80;
if(v == (visible_scanlines + 1) && hcycles >= 2)r |= 0x80;
if(v > (visible_scanlines + 1))r |= 0x80;
if(v >= (vs + 1))r |= 0x80;
return r;
}
@ -175,7 +169,7 @@ uint8 bCPU::mmio_r4217() {
//JOY1L
uint8 bCPU::mmio_r4218() {
uint8 r = 0x00;
uint16 v = clock->vcounter();
uint16 v = vcounter();
if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled
//if(v >= 225 && v <= 227)return 0x00; //can't read joypad while SNES is polling input
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_A) << 7;
@ -188,7 +182,7 @@ uint16 v = clock->vcounter();
//JOY1H
uint8 bCPU::mmio_r4219() {
uint8 r = 0x00;
uint16 v = clock->vcounter();
uint16 v = vcounter();
if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled
//if(v >= 225 && v <= 227)return 0x00; //can't read joypad while SNES is polling input
r |= (uint8)snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_B) << 7;
@ -202,12 +196,103 @@ uint16 v = clock->vcounter();
return r;
}
//DMAPx
uint8 bCPU::mmio_r43x0(uint8 i) {
return channel[i].dmap;
}
//BBADx
uint8 bCPU::mmio_r43x1(uint8 i) {
return channel[i].destaddr;
}
//A1TxL
uint8 bCPU::mmio_r43x2(uint8 i) {
return channel[i].srcaddr;
}
//A1TxH
uint8 bCPU::mmio_r43x3(uint8 i) {
return channel[i].srcaddr >> 8;
}
//A1Bx
uint8 bCPU::mmio_r43x4(uint8 i) {
return channel[i].srcaddr >> 16;
}
//DASxL
uint8 bCPU::mmio_r43x5(uint8 i) {
return channel[i].xfersize;
}
//DASxH
uint8 bCPU::mmio_r43x6(uint8 i) {
return channel[i].xfersize >> 8;
}
//DASBx
uint8 bCPU::mmio_r43x7(uint8 i) {
return channel[i].hdma_indirect_bank;
}
//A2AxL
uint8 bCPU::mmio_r43x8(uint8 i) {
return channel[i].hdma_taddr;
}
//A2AxH
uint8 bCPU::mmio_r43x9(uint8 i) {
return channel[i].hdma_taddr >> 8;
}
//NTRLx
uint8 bCPU::mmio_r43xa(uint8 i) {
return channel[i].hdma_line_counter;
}
//???
uint8 bCPU::mmio_r43xb(uint8 i) {
return channel[i].hdma_unknown;
}
uint8 bCPUMMIO::read(uint32 addr) {
clock->sync();
uint8 i;
//cpu->sync();
//APU
if(addr >= 0x2140 && addr <= 0x217f) {
return apu->port_read(addr & 3);
}
//HDMA
if(addr >= 0x4300 && addr <= 0x437f) {
i = (addr >> 4) & 7;
switch(addr & 0xf) {
case 0x0:return cpu->mmio_r43x0(i);
case 0x1:return cpu->mmio_r43x1(i);
case 0x2:return cpu->mmio_r43x2(i);
case 0x3:return cpu->mmio_r43x3(i);
case 0x4:return cpu->mmio_r43x4(i);
case 0x5:return cpu->mmio_r43x5(i);
case 0x6:return cpu->mmio_r43x6(i);
case 0x7:return cpu->mmio_r43x7(i);
case 0x8:return cpu->mmio_r43x8(i);
case 0x9:return cpu->mmio_r43x9(i);
case 0xa:return cpu->mmio_r43xa(i);
case 0xb:return cpu->mmio_r43xb(i);
case 0xc:return 0x43; //unmapped
case 0xd:return 0x43; //unmapped
case 0xe:return 0x43; //unmapped
case 0xf:return cpu->mmio_r43xb(i); //mirror of 43xb
}
}
switch(addr) {
case 0x2180:return cpu->mmio_r2180(); //WMDATA
case 0x21c2:return cpu->mmio_r21c2(); //???
case 0x21c3:return cpu->mmio_r21c3(); //???
case 0x2800:return cpu->srtc_read();
case 0x4016:return cpu->mmio_r4016(); //JOYSER0
case 0x4210:return cpu->mmio_r4210(); //RDNMI
case 0x4211:return cpu->mmio_r4211(); //TIMEUP
@ -219,6 +304,7 @@ uint8 bCPUMMIO::read(uint32 addr) {
case 0x4217:return cpu->mmio_r4217(); //RDMPYH
case 0x4218:return cpu->mmio_r4218(); //JOY1L
case 0x4219:return cpu->mmio_r4219(); //JOY1H
case 0x421a:case 0x421b:case 0x421c:case 0x421d:case 0x421e:case 0x421f:return 0x00;
}
return 0x00;
}
@ -263,6 +349,14 @@ void bCPU::mmio_w4200(uint8 value) {
status.virq_enabled = !!(value & 0x20);
status.hirq_enabled = !!(value & 0x10);
status.auto_joypad_poll = !!(value & 0x01);
if(status.nmi_enabled == false) {
status.nmi_pin = 0;
}
if(status.virq_enabled == false && status.hirq_enabled == false) {
status.irq_pin = 0;
}
}
//WRIO
@ -296,8 +390,8 @@ void bCPU::mmio_w4205(uint8 value) {
//WRDIVB
void bCPU::mmio_w4206(uint8 value) {
status.div_b = value;
status.r4214 = (status.div_b)?status.div_a / status.div_b:0;
status.r4216 = (status.div_b)?status.div_a % status.div_b:0;
status.r4214 = (status.div_b)?status.div_a / status.div_b : 0xffff;
status.r4216 = (status.div_b)?status.div_a % status.div_b : status.div_a;
}
//HTIMEL
@ -327,15 +421,13 @@ void bCPU::mmio_w420a(uint8 value) {
//DMAEN
void bCPU::mmio_w420b(uint8 value) {
if(value != 0x00) {
clock->add_cc1_cycles(18);
status.dma_state = DMASTATE_INIT;
}
for(int i=0;i<8;i++) {
if(value & (1 << i)) {
dma->channel[i].active = true;
dma->channel[i].hdma_active = false;
clock->add_cc1_cycles(8);
cpustate = CPUSTATE_DMA;
channel[i].active = true;
channel[i].hdma_active = false;
}
}
}
@ -343,7 +435,7 @@ void bCPU::mmio_w420b(uint8 value) {
//HDMAEN
void bCPU::mmio_w420c(uint8 value) {
for(int i=0;i<8;i++) {
dma->channel[i].hdma_active = !!(value & (1 << i));
channel[i].hdma_active = !!(value & (1 << i));
}
}
@ -354,56 +446,108 @@ void bCPU::mmio_w420d(uint8 value) {
//DMAPx
void bCPU::mmio_w43x0(uint8 value, uint8 i) {
dma->channel[i].direction = !!(value & 0x80);
dma->channel[i].hdma_indirect = !!(value & 0x40);
dma->channel[i].incmode = (value & 0x10)?-1:1;
dma->channel[i].fixedxfer = !!(value & 0x08);
dma->channel[i].xfermode = value & 7;
channel[i].dmap = value;
channel[i].direction = !!(value & 0x80);
channel[i].hdma_indirect = !!(value & 0x40);
channel[i].incmode = (value & 0x10)?-1:1;
channel[i].fixedxfer = !!(value & 0x08);
channel[i].xfermode = value & 7;
}
//BBADx
void bCPU::mmio_w43x1(uint8 value, uint8 i) {
dma->channel[i].destaddr = value;
channel[i].destaddr = value;
}
//A1TxL
void bCPU::mmio_w43x2(uint8 value, uint8 i) {
dma->channel[i].srcaddr = (dma->channel[i].srcaddr & 0xffff00) | value;
channel[i].srcaddr = (channel[i].srcaddr & 0xffff00) | value;
}
//A1TxH
void bCPU::mmio_w43x3(uint8 value, uint8 i) {
dma->channel[i].srcaddr = (dma->channel[i].srcaddr & 0xff00ff) | (value << 8);
channel[i].srcaddr = (channel[i].srcaddr & 0xff00ff) | (value << 8);
}
//A1Bx
void bCPU::mmio_w43x4(uint8 value, uint8 i) {
dma->channel[i].srcaddr = (dma->channel[i].srcaddr & 0x00ffff) | (value << 16);
channel[i].srcaddr = (channel[i].srcaddr & 0x00ffff) | (value << 16);
}
//DASxL
void bCPU::mmio_w43x5(uint8 value, uint8 i) {
dma->channel[i].xfersize = (dma->channel[i].xfersize & 0xff00) | value;
channel[i].xfersize = (channel[i].xfersize & 0xff00) | value;
}
//DASxH
void bCPU::mmio_w43x6(uint8 value, uint8 i) {
dma->channel[i].xfersize = (dma->channel[i].xfersize & 0x00ff) | (value << 8);
channel[i].xfersize = (channel[i].xfersize & 0x00ff) | (value << 8);
}
//DASBx
void bCPU::mmio_w43x7(uint8 value, uint8 i) {
dma->channel[i].hdma_indirect_bank = value;
channel[i].hdma_indirect_bank = value;
}
//A2AxL
void bCPU::mmio_w43x8(uint8 value, uint8 i) {
channel[i].hdma_taddr = (channel[i].hdma_taddr & 0xffff00) | value;
}
//A2AxH
void bCPU::mmio_w43x9(uint8 value, uint8 i) {
channel[i].hdma_taddr = (channel[i].hdma_taddr & 0xff00ff) | (value << 8);
}
//NTRLx
void bCPU::mmio_w43xa(uint8 value, uint8 i) {
channel[i].hdma_line_counter = value;
}
//???
void bCPU::mmio_w43xb(uint8 value, uint8 i) {
channel[i].hdma_unknown = value;
}
void bCPUMMIO::write(uint32 addr, uint8 value) {
int i;
clock->sync();
uint8 i;
//cpu->sync();
//APU
if(addr >= 0x2140 && addr <= 0x217f) {
cpu->port_write(addr & 3, value);
return;
}
//HDMA
if(addr >= 0x4300 && addr <= 0x437f) {
i = (addr >> 4) & 7;
switch(addr & 0xf) {
case 0x0:cpu->mmio_w43x0(value, i);return;
case 0x1:cpu->mmio_w43x1(value, i);return;
case 0x2:cpu->mmio_w43x2(value, i);return;
case 0x3:cpu->mmio_w43x3(value, i);return;
case 0x4:cpu->mmio_w43x4(value, i);return;
case 0x5:cpu->mmio_w43x5(value, i);return;
case 0x6:cpu->mmio_w43x6(value, i);return;
case 0x7:cpu->mmio_w43x7(value, i);return;
case 0x8:cpu->mmio_w43x8(value, i);return;
case 0x9:cpu->mmio_w43x9(value, i);return;
case 0xa:cpu->mmio_w43xa(value, i);return;
case 0xb:cpu->mmio_w43xb(value, i);return;
case 0xc:return; //unmapped
case 0xd:return; //unmapped
case 0xe:return; //unmapped
case 0xf:cpu->mmio_w43xb(value, i);return; //mirror of 43xb
}
}
switch(addr) {
case 0x2180:cpu->mmio_w2180(value);return; //WMDATA
case 0x2181:cpu->mmio_w2181(value);return; //WMADDL
case 0x2182:cpu->mmio_w2182(value);return; //WMADDM
case 0x2183:cpu->mmio_w2183(value);return; //WMADDH
case 0x2801:cpu->srtc_write(value);return;
case 0x4016:cpu->mmio_w4016(value);return; //JOYSER0
case 0x4200:cpu->mmio_w4200(value);return; //NMITIMEN
case 0x4201:cpu->mmio_w4201(value);return; //WRIO
@ -419,288 +563,9 @@ int i;
case 0x420b:cpu->mmio_w420b(value);return; //DMAEN
case 0x420c:cpu->mmio_w420c(value);return; //HDMAEN
case 0x420d:cpu->mmio_w420d(value);return; //MEMSEL
//DMAPx
case 0x4300:case 0x4310:case 0x4320:case 0x4330:
case 0x4340:case 0x4350:case 0x4360:case 0x4370:
cpu->mmio_w43x0(value, (addr >> 4) & 7);
return;
//BBADx
case 0x4301:case 0x4311:case 0x4321:case 0x4331:
case 0x4341:case 0x4351:case 0x4361:case 0x4371:
cpu->mmio_w43x1(value, (addr >> 4) & 7);
return;
//A1TxL
case 0x4302:case 0x4312:case 0x4322:case 0x4332:
case 0x4342:case 0x4352:case 0x4362:case 0x4372:
cpu->mmio_w43x2(value, (addr >> 4) & 7);
return;
//A1TxH
case 0x4303:case 0x4313:case 0x4323:case 0x4333:
case 0x4343:case 0x4353:case 0x4363:case 0x4373:
cpu->mmio_w43x3(value, (addr >> 4) & 7);
return;
//A1Bx
case 0x4304:case 0x4314:case 0x4324:case 0x4334:
case 0x4344:case 0x4354:case 0x4364:case 0x4374:
cpu->mmio_w43x4(value, (addr >> 4) & 7);
return;
//DASxL
case 0x4305:case 0x4315:case 0x4325:case 0x4335:
case 0x4345:case 0x4355:case 0x4365:case 0x4375:
cpu->mmio_w43x5(value, (addr >> 4) & 7);
return;
//DASxH
case 0x4306:case 0x4316:case 0x4326:case 0x4336:
case 0x4346:case 0x4356:case 0x4366:case 0x4376:
cpu->mmio_w43x6(value, (addr >> 4) & 7);
return;
//DASBx
case 0x4307:case 0x4317:case 0x4327:case 0x4337:
case 0x4347:case 0x4357:case 0x4367:case 0x4377:
cpu->mmio_w43x7(value, (addr >> 4) & 7);
return;
}
}
bCPUMMIO::bCPUMMIO(bCPU *_cpu) {
cpu = _cpu;
}
uint16 bDMA::dma_cputommio(uint8 i, uint8 index) {
uint8 x;
x = mem_bus->read(channel[i].srcaddr);
mem_bus->write(0x2100 | ((channel[i].destaddr + index) & 0xff), x);
if(channel[i].fixedxfer == false) {
channel[i].srcaddr = (channel[i].srcaddr & 0xff0000) + ((channel[i].srcaddr + channel[i].incmode) & 0xffff);
}
clock->add_cc1_cycles(8);
return --channel[i].xfersize;
}
uint16 bDMA::dma_mmiotocpu(uint8 i, uint8 index) {
uint8 x;
x = mem_bus->read(0x2100 | ((channel[i].destaddr + index) & 0xff));
mem_bus->write(channel[i].srcaddr, x);
if(channel[i].fixedxfer == false) {
channel[i].srcaddr = (channel[i].srcaddr & 0xff0000) + ((channel[i].srcaddr + channel[i].incmode) & 0xffff);
}
clock->add_cc1_cycles(8);
return --channel[i].xfersize;
}
void bDMA::dma_xfer_type0(uint8 i) {
if(channel[i].direction == 0) {
if(dma_cputommio(i, 0) == 0)return;
} else {
if(dma_mmiotocpu(i, 0) == 0)return;
}
}
void bDMA::dma_xfer_type1(uint8 i) {
if(channel[i].direction == 0) {
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 1) == 0)return;
} else {
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 1) == 0)return;
}
}
void bDMA::dma_xfer_type2(uint8 i) {
if(channel[i].direction == 0) {
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 0) == 0)return;
} else {
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 0) == 0)return;
}
}
void bDMA::dma_xfer_type3(uint8 i) {
if(channel[i].direction == 0) {
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 1) == 0)return;
if(dma_cputommio(i, 1) == 0)return;
} else {
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 1) == 0)return;
if(dma_mmiotocpu(i, 1) == 0)return;
}
}
void bDMA::dma_xfer_type4(uint8 i) {
if(channel[i].direction == 0) {
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 1) == 0)return;
if(dma_cputommio(i, 2) == 0)return;
if(dma_cputommio(i, 3) == 0)return;
} else {
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 1) == 0)return;
if(dma_mmiotocpu(i, 2) == 0)return;
if(dma_mmiotocpu(i, 3) == 0)return;
}
}
void bDMA::dma_xfer_type5(uint8 i) {
if(channel[i].direction == 0) {
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 1) == 0)return;
if(dma_cputommio(i, 0) == 0)return;
if(dma_cputommio(i, 1) == 0)return;
} else {
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 1) == 0)return;
if(dma_mmiotocpu(i, 0) == 0)return;
if(dma_mmiotocpu(i, 1) == 0)return;
}
}
void bDMA::run() {
for(int i=0;i<8;i++) {
if(channel[i].active == false)continue;
switch(channel[i].xfermode) {
case 0:dma_xfer_type0(i);break;
case 1:dma_xfer_type1(i);break;
case 2:dma_xfer_type2(i);break;
case 3:dma_xfer_type3(i);break;
case 4:dma_xfer_type4(i);break;
case 5:dma_xfer_type5(i);break;
case 6:dma_xfer_type2(i);break;
case 7:dma_xfer_type3(i);break;
}
if(channel[i].xfersize == 0) {
channel[i].active = false;
}
return;
}
cpu->cpustate = bCPU::CPUSTATE_RUN;
}
void bDMA::hdma_write(uint8 i, uint8 l, uint8 x) {
switch(channel[i].xfermode) {
case 0:mem_bus->write(0x2100 | ((channel[i].destaddr) & 0xff), x);break;
case 1:mem_bus->write(0x2100 | ((channel[i].destaddr + l) & 0xff), x);break;
case 2:mem_bus->write(0x2100 | ((channel[i].destaddr) & 0xff), x);break;
case 3:mem_bus->write(0x2100 | ((channel[i].destaddr + (l >> 1)) & 0xff), x);break;
case 4:mem_bus->write(0x2100 | ((channel[i].destaddr + l) & 0xff), x);break;
case 5:mem_bus->write(0x2100 | ((channel[i].destaddr + (l & 1)) & 0xff), x);break;
case 6:mem_bus->write(0x2100 | ((channel[i].destaddr) & 0xff), x);break;
case 7:mem_bus->write(0x2100 | ((channel[i].destaddr + (l >> 1)) & 0xff), x);break;
}
}
void bDMA::hdma_run() {
int l, xferlen;
uint8 x, active_channels = 0;
for(int i=0;i<8;i++) {
if(channel[i].hdma_completed == true)continue;
clock->add_cc1_cycles(8);
active_channels++;
if(channel[i].hdma_line_counter == 0) {
channel[i].hdma_line_counter = mem_bus->read(channel[i].hdma_address++);
// channel[i].r43x8 = channel[i].hdma_address;
if(channel[i].hdma_line_counter == 0) {
channel[i].hdma_completed = true;
continue;
}
if(channel[i].hdma_line_counter > 0x80) {
channel[i].hdma_repeat = true;
channel[i].hdma_line_counter -= 0x80;
} else {
channel[i].hdma_repeat = false;
}
channel[i].hdma_first_line = true;
if(channel[i].hdma_indirect == false) {
channel[i].hdma_iaddress = channel[i].hdma_address;
} else {
channel[i].hdma_iaddress = mem_bus->read(channel[i].hdma_address);
channel[i].hdma_iaddress |= mem_bus->read(channel[i].hdma_address + 1) << 8;
channel[i].hdma_iaddress |= channel[i].hdma_indirect_bank << 16;
channel[i].hdma_address += 2;
clock->add_cc1_cycles(16);
}
}
channel[i].hdma_line_counter--;
if(channel[i].hdma_first_line == false && channel[i].hdma_repeat == false)continue;
channel[i].hdma_first_line = false;
if(channel[i].hdma_indirect == false) {
channel[i].hdma_iaddress = channel[i].hdma_address;
}
switch(channel[i].xfermode) {
case 0: xferlen = 1;break;
case 1:case 2:case 6: xferlen = 2;break;
case 3:case 4:case 5:case 7:xferlen = 4;break;
}
for(l=0;l<xferlen;l++) {
x = mem_bus->read(channel[i].hdma_iaddress++);
if(channel[i].hdma_indirect == false) {
channel[i].hdma_address++;
}
hdma_write(i, l, x);
clock->add_cc1_cycles(8);
}
}
if(active_channels != 0) {
clock->add_cc1_cycles(18);
}
}
void bDMA::hdma_initialize() {
uint8 active_channels = 0;
for(int i=0;i<8;i++) {
if(channel[i].hdma_active == false) {
channel[i].hdma_completed = true;
continue;
}
active_channels++;
channel[i].hdma_first_line = true;
channel[i].hdma_repeat = false;
channel[i].hdma_line_counter = 0;
channel[i].hdma_address = channel[i].srcaddr;
channel[i].hdma_completed = false;
if(channel[i].hdma_indirect == false) {
clock->add_cc1_cycles(8);
} else {
clock->add_cc1_cycles(24);
}
}
if(active_channels != 0) {
clock->add_cc1_cycles(18);
}
}
void bDMA::reset() {
for(int i=0;i<8;i++) {
channel[i].active = false;
channel[i].hdma_active = false;
channel[i].direction = 0;
channel[i].hdma_indirect = false;
channel[i].incmode = 1;
channel[i].fixedxfer = false;
channel[i].xfermode = 0;
channel[i].destaddr = 0;
channel[i].srcaddr = 0;
channel[i].xfersize = 0;
channel[i].hdma_indirect_bank = 0;
channel[i].hdma_first_line = false;
channel[i].hdma_repeat = false;
channel[i].hdma_line_counter = 0;
channel[i].hdma_address = 0;
channel[i].hdma_iaddress = 0;
channel[i].hdma_completed = true;
}
}
bDMA::bDMA(bCPU *_cpu) {
cpu = _cpu;
reset();
}

256
src/cpu/bcpu/bcpu_op.h Normal file
View File

@ -0,0 +1,256 @@
void op_adc_const();
void op_and_const();
void op_cmp_const();
void op_cpx_const();
void op_cpy_const();
void op_eor_const();
void op_lda_const();
void op_ldx_const();
void op_ldy_const();
void op_ora_const();
void op_sbc_const();
void op_adc_addr();
void op_and_addr();
void op_bit_addr();
void op_cmp_addr();
void op_cpx_addr();
void op_cpy_addr();
void op_eor_addr();
void op_lda_addr();
void op_ldx_addr();
void op_ldy_addr();
void op_ora_addr();
void op_sbc_addr();
void op_adc_addrx();
void op_and_addrx();
void op_bit_addrx();
void op_cmp_addrx();
void op_eor_addrx();
void op_lda_addrx();
void op_ldy_addrx();
void op_ora_addrx();
void op_sbc_addrx();
void op_adc_addry();
void op_and_addry();
void op_cmp_addry();
void op_eor_addry();
void op_lda_addry();
void op_ldx_addry();
void op_ora_addry();
void op_sbc_addry();
void op_adc_long();
void op_and_long();
void op_cmp_long();
void op_eor_long();
void op_lda_long();
void op_ora_long();
void op_sbc_long();
void op_adc_longx();
void op_and_longx();
void op_cmp_longx();
void op_eor_longx();
void op_lda_longx();
void op_ora_longx();
void op_sbc_longx();
void op_adc_dp();
void op_and_dp();
void op_bit_dp();
void op_cmp_dp();
void op_cpx_dp();
void op_cpy_dp();
void op_eor_dp();
void op_lda_dp();
void op_ldx_dp();
void op_ldy_dp();
void op_ora_dp();
void op_sbc_dp();
void op_adc_dpx();
void op_and_dpx();
void op_bit_dpx();
void op_cmp_dpx();
void op_eor_dpx();
void op_lda_dpx();
void op_ldy_dpx();
void op_ora_dpx();
void op_sbc_dpx();
void op_ldx_dpy();
void op_adc_idp();
void op_and_idp();
void op_cmp_idp();
void op_eor_idp();
void op_lda_idp();
void op_ora_idp();
void op_sbc_idp();
void op_adc_idpx();
void op_and_idpx();
void op_cmp_idpx();
void op_eor_idpx();
void op_lda_idpx();
void op_ora_idpx();
void op_sbc_idpx();
void op_adc_idpy();
void op_and_idpy();
void op_cmp_idpy();
void op_eor_idpy();
void op_lda_idpy();
void op_ora_idpy();
void op_sbc_idpy();
void op_adc_ildp();
void op_and_ildp();
void op_cmp_ildp();
void op_eor_ildp();
void op_lda_ildp();
void op_ora_ildp();
void op_sbc_ildp();
void op_adc_ildpy();
void op_and_ildpy();
void op_cmp_ildpy();
void op_eor_ildpy();
void op_lda_ildpy();
void op_ora_ildpy();
void op_sbc_ildpy();
void op_adc_sr();
void op_and_sr();
void op_cmp_sr();
void op_eor_sr();
void op_lda_sr();
void op_ora_sr();
void op_sbc_sr();
void op_adc_isry();
void op_and_isry();
void op_cmp_isry();
void op_eor_isry();
void op_lda_isry();
void op_ora_isry();
void op_sbc_isry();
void op_bit_const();
void op_inc();
void op_inx();
void op_iny();
void op_dec();
void op_dex();
void op_dey();
void op_asl();
void op_lsr();
void op_rol();
void op_ror();
void op_inc_addr();
void op_dec_addr();
void op_asl_addr();
void op_lsr_addr();
void op_rol_addr();
void op_ror_addr();
void op_trb_addr();
void op_tsb_addr();
void op_inc_addrx();
void op_dec_addrx();
void op_asl_addrx();
void op_lsr_addrx();
void op_rol_addrx();
void op_ror_addrx();
void op_inc_dp();
void op_dec_dp();
void op_asl_dp();
void op_lsr_dp();
void op_rol_dp();
void op_ror_dp();
void op_trb_dp();
void op_tsb_dp();
void op_inc_dpx();
void op_dec_dpx();
void op_asl_dpx();
void op_lsr_dpx();
void op_rol_dpx();
void op_ror_dpx();
void op_sta_addr();
void op_stx_addr();
void op_sty_addr();
void op_stz_addr();
void op_sta_addrx();
void op_stz_addrx();
void op_sta_addry();
void op_sta_long();
void op_sta_longx();
void op_sta_dp();
void op_stx_dp();
void op_sty_dp();
void op_stz_dp();
void op_sta_dpx();
void op_sty_dpx();
void op_stz_dpx();
void op_stx_dpy();
void op_sta_idp();
void op_sta_ildp();
void op_sta_idpx();
void op_sta_idpy();
void op_sta_ildpy();
void op_sta_sr();
void op_sta_isry();
void op_bra();
void op_bcc();
void op_bcs();
void op_bne();
void op_beq();
void op_bpl();
void op_bmi();
void op_bvc();
void op_bvs();
void op_brl();
void op_jmp_addr();
void op_jmp_long();
void op_jmp_iaddr();
void op_jmp_iaddrx();
void op_jmp_iladdr();
void op_jsr_addr();
void op_jsr_long();
void op_jsr_iaddrx();
void op_rti();
void op_rts();
void op_rtl();
void op_nop();
void op_wdm();
void op_xba();
void op_mvn();
void op_mvp();
void op_brk();
void op_cop();
void op_stp();
void op_wai();
void op_xce();
void op_clc();
void op_cld();
void op_cli();
void op_clv();
void op_sec();
void op_sed();
void op_sei();
void op_rep();
void op_sep();
void op_tax();
void op_tay();
void op_txa();
void op_txy();
void op_tya();
void op_tyx();
void op_tcd();
void op_tcs();
void op_tdc();
void op_tsc();
void op_tsx();
void op_txs();
void op_pha();
void op_phx();
void op_phy();
void op_phd();
void op_phb();
void op_phk();
void op_php();
void op_pla();
void op_plx();
void op_ply();
void op_pld();
void op_plb();
void op_plp();
void op_pea();
void op_pei();
void op_per();

View File

@ -1,464 +0,0 @@
inline void bCPU::flags_adc_b() {
int32 r = regs.a.l + rd.l + regs.p.c;
//bcd
if(regs.p.d) {
if(((r ) & 15) > 9)r += 6;
if(((r >> 4) & 15) > 9)r += 6 << 4;
}
regs.p.n = !!(r & 0x80);
regs.p.v = !!(~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
regs.p.z = ((byte)r == 0);
regs.p.c = (r > 0xff);
regs.a.l = r;
}
inline void bCPU::flags_adc_w() {
int32 r = regs.a.w + rd.w + regs.p.c;
//bcd
if(regs.p.d) {
if(((r ) & 15) > 9)r += 6;
if(((r >> 4) & 15) > 9)r += 6 << 4;
if(((r >> 8) & 15) > 9)r += 6 << 8;
if(((r >> 12) & 15) > 9)r += 6 << 12;
}
regs.p.n = !!(r & 0x8000);
regs.p.v = !!(~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
regs.p.z = ((word)r == 0);
regs.p.c = (r > 0xffff);
regs.a.w = r;
}
/************************
*** 0x69: adc #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void bCPU::op_adc_constb() {
rd.l = op_read(); //2
flags_adc_b();
}
void bCPU::op_adc_constw() {
rd.l = op_read(); //2
rd.h = op_read(); //2a
flags_adc_w();
}
/**********************
*** 0x6d: adc addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_adc_addrb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
flags_adc_b();
}
void bCPU::op_adc_addrw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
flags_adc_w();
}
/************************
*** 0x7d: adc addr,x ***
************************
cycles:
[1 ] pbr,pc ; operadc
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void bCPU::op_adc_addrxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
flags_adc_b();
}
void bCPU::op_adc_addrxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
flags_adc_w();
}
/********************
*** 0x65: adc dp ***
********************
cycles:
[1 ] pbr,pc ; operadc
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void bCPU::op_adc_dpb() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
flags_adc_b();
}
void bCPU::op_adc_dpw() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
rd.h = op_read(OPMODE_DP, dp + 1); //3a
flags_adc_w();
}
/**********************
*** 0x72: adc (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_adc_idpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
rd.l = op_read(OPMODE_DBR, aa.w); //5
flags_adc_b();
}
void bCPU::op_adc_idpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
rd.l = op_read(OPMODE_DBR, aa.w); //5
rd.h = op_read(OPMODE_DBR, aa.w + 1); //5
flags_adc_w();
}
/**********************
*** 0x67: adc [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void bCPU::op_adc_ildpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
rd.l = op_read(OPMODE_LONG, aa.d); //6
flags_adc_b();
}
void bCPU::op_adc_ildpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
rd.l = op_read(OPMODE_LONG, aa.d); //6
rd.h = op_read(OPMODE_LONG, aa.d + 1); //6a
flags_adc_w();
}
/**********************
*** 0x6f: adc long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void bCPU::op_adc_longb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
rd.l = op_read(OPMODE_LONG, aa.d); //5
flags_adc_b();
}
void bCPU::op_adc_longw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
rd.l = op_read(OPMODE_LONG, aa.d); //5
rd.h = op_read(OPMODE_LONG, aa.d + 1); //5a
flags_adc_w();
}
/************************
*** 0x7f: adc long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void bCPU::op_adc_longxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
flags_adc_b();
}
void bCPU::op_adc_longxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
flags_adc_w();
}
/************************
*** 0x79: adc addr,y ***
************************
cycles:
[1 ] pbr,pc ; operadc
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_adc_addryb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
flags_adc_b();
}
void bCPU::op_adc_addryw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
flags_adc_w();
}
/**********************
*** 0x75: adc dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void bCPU::op_adc_dpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
flags_adc_b();
}
void bCPU::op_adc_dpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
flags_adc_w();
}
/************************
*** 0x61: adc (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_adc_idpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
rd.l = op_read(OPMODE_DBR, aa.w); //6
flags_adc_b();
}
void bCPU::op_adc_idpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
rd.l = op_read(OPMODE_DBR, aa.w); //6
rd.h = op_read(OPMODE_DBR, aa.w + 1); //6a
flags_adc_w();
}
/************************
*** 0x71: adc (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_adc_idpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
flags_adc_b();
}
void bCPU::op_adc_idpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
flags_adc_w();
}
/************************
*** 0x77: adc [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void bCPU::op_adc_ildpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
flags_adc_b();
}
void bCPU::op_adc_ildpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
flags_adc_w();
}
/**********************
*** 0x63: adc sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void bCPU::op_adc_srb() {
sp = op_read(); //2
cpu_io(); //3
rd.l = op_read(OPMODE_SP, sp); //4
flags_adc_b();
}
void bCPU::op_adc_srw() {
sp = op_read(); //2
cpu_io(); //3
rd.l = op_read(OPMODE_SP, sp); //4
rd.h = op_read(OPMODE_SP, sp + 1); //4a
flags_adc_w();
}
/**************************
*** 0x73: adc (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_adc_isryb() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
flags_adc_b();
}
void bCPU::op_adc_isryw() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
flags_adc_w();
}

View File

@ -1,444 +0,0 @@
inline void bCPU::flags_and_b() {
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
inline void bCPU::flags_and_w() {
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
/************************
*** 0x29: and #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void bCPU::op_and_constb() {
regs.a.l &= op_read(); //2
flags_and_b();
}
void bCPU::op_and_constw() {
regs.a.l &= op_read(); //2
regs.a.h &= op_read(); //2a
flags_and_w();
}
/**********************
*** 0x2d: and addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_and_addrb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
regs.a.l &= op_read(OPMODE_DBR, aa.w); //4
flags_and_b();
}
void bCPU::op_and_addrw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
regs.a.l &= op_read(OPMODE_DBR, aa.w); //4
regs.a.h &= op_read(OPMODE_DBR, aa.w + 1); //4a
flags_and_w();
}
/************************
*** 0x3d: and addr,x ***
************************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void bCPU::op_and_addrxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.x.w); //4
flags_and_b();
}
void bCPU::op_and_addrxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.x.w); //4
regs.a.h &= op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
flags_and_w();
}
/********************
*** 0x25: and dp ***
********************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void bCPU::op_and_dpb() {
dp = op_read(); //2
cpu_c2(); //2a
regs.a.l &= op_read(OPMODE_DP, dp); //3
flags_and_b();
}
void bCPU::op_and_dpw() {
dp = op_read(); //2
cpu_c2(); //2a
regs.a.l &= op_read(OPMODE_DP, dp); //3
regs.a.h &= op_read(OPMODE_DP, dp + 1); //3a
flags_and_w();
}
/**********************
*** 0x32: and (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_and_idpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
regs.a.l &= op_read(OPMODE_DBR, aa.w); //5
flags_and_b();
}
void bCPU::op_and_idpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
regs.a.l &= op_read(OPMODE_DBR, aa.w); //5
regs.a.h &= op_read(OPMODE_DBR, aa.w + 1); //5
flags_and_w();
}
/**********************
*** 0x27: and [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void bCPU::op_and_ildpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l &= op_read(OPMODE_LONG, aa.d); //6
flags_and_b();
}
void bCPU::op_and_ildpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l &= op_read(OPMODE_LONG, aa.d); //6
regs.a.h &= op_read(OPMODE_LONG, aa.d + 1); //6a
flags_and_w();
}
/**********************
*** 0x2f: and long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void bCPU::op_and_longb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l &= op_read(OPMODE_LONG, aa.d); //5
flags_and_b();
}
void bCPU::op_and_longw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l &= op_read(OPMODE_LONG, aa.d); //5
regs.a.h &= op_read(OPMODE_LONG, aa.d + 1); //5a
flags_and_w();
}
/************************
*** 0x3f: and long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void bCPU::op_and_longxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l &= op_read(OPMODE_LONG, aa.d + regs.x.w); //5
flags_and_b();
}
void bCPU::op_and_longxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l &= op_read(OPMODE_LONG, aa.d + regs.x.w); //5
regs.a.h &= op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
flags_and_w();
}
/************************
*** 0x39: and addr,y ***
************************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_and_addryb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //4
flags_and_b();
}
void bCPU::op_and_addryw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //4
regs.a.h &= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
flags_and_w();
}
/**********************
*** 0x35: and dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void bCPU::op_and_dpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
regs.a.l &= op_read(OPMODE_DP, dp + regs.x.w); //4
flags_and_b();
}
void bCPU::op_and_dpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
regs.a.l &= op_read(OPMODE_DP, dp + regs.x.w); //4
regs.a.h &= op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
flags_and_w();
}
/************************
*** 0x21: and (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_and_idpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
regs.a.l &= op_read(OPMODE_DBR, aa.w); //6
flags_and_b();
}
void bCPU::op_and_idpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
regs.a.l &= op_read(OPMODE_DBR, aa.w); //6
regs.a.h &= op_read(OPMODE_DBR, aa.w + 1); //6a
flags_and_w();
}
/************************
*** 0x31: and (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_and_idpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //5
flags_and_b();
}
void bCPU::op_and_idpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //5
regs.a.h &= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
flags_and_w();
}
/************************
*** 0x37: and [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void bCPU::op_and_ildpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l &= op_read(OPMODE_LONG, aa.d + regs.y.w); //6
flags_and_b();
}
void bCPU::op_and_ildpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l &= op_read(OPMODE_LONG, aa.d + regs.y.w); //6
regs.a.h &= op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
flags_and_w();
}
/**********************
*** 0x23: and sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void bCPU::op_and_srb() {
sp = op_read(); //2
cpu_io(); //3
regs.a.l &= op_read(OPMODE_SP, sp); //4
flags_and_b();
}
void bCPU::op_and_srw() {
sp = op_read(); //2
cpu_io(); //3
regs.a.l &= op_read(OPMODE_SP, sp); //4
regs.a.h &= op_read(OPMODE_SP, sp + 1); //4a
flags_and_w();
}
/**************************
*** 0x33: and (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_and_isryb() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //7
flags_and_b();
}
void bCPU::op_and_isryw() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
regs.a.l &= op_read(OPMODE_DBR, aa.w + regs.y.w); //7
regs.a.h &= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
flags_and_w();
}

View File

@ -1,448 +0,0 @@
inline void bCPU::flags_cmp_b() {
int32 r = regs.a.l - rd.l;
regs.p.n = !!(r & 0x80);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r >= 0);
}
inline void bCPU::flags_cmp_w() {
int32 r = regs.a.w - rd.w;
regs.p.n = !!(r & 0x8000);
regs.p.z = ((uint16)r == 0);
regs.p.c = (r >= 0);
}
/************************
*** 0xc9: cmp #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void bCPU::op_cmp_constb() {
rd.l = op_read(); //2
flags_cmp_b();
}
void bCPU::op_cmp_constw() {
rd.l = op_read(); //2
rd.h = op_read(); //2a
flags_cmp_w();
}
/**********************
*** 0xcd: cmp addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_cmp_addrb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
flags_cmp_b();
}
void bCPU::op_cmp_addrw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
flags_cmp_w();
}
/************************
*** 0xdd: cmp addr,x ***
************************
cycles:
[1 ] pbr,pc ; opercmp
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void bCPU::op_cmp_addrxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
flags_cmp_b();
}
void bCPU::op_cmp_addrxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
flags_cmp_w();
}
/********************
*** 0xc5: cmp dp ***
********************
cycles:
[1 ] pbr,pc ; opercmp
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void bCPU::op_cmp_dpb() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
flags_cmp_b();
}
void bCPU::op_cmp_dpw() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
rd.h = op_read(OPMODE_DP, dp + 1); //3a
flags_cmp_w();
}
/**********************
*** 0xd2: cmp (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_cmp_idpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
rd.l = op_read(OPMODE_DBR, aa.w); //5
flags_cmp_b();
}
void bCPU::op_cmp_idpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
rd.l = op_read(OPMODE_DBR, aa.w); //5
rd.h = op_read(OPMODE_DBR, aa.w + 1); //5
flags_cmp_w();
}
/**********************
*** 0xc7: cmp [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void bCPU::op_cmp_ildpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
rd.l = op_read(OPMODE_LONG, aa.d); //6
flags_cmp_b();
}
void bCPU::op_cmp_ildpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
rd.l = op_read(OPMODE_LONG, aa.d); //6
rd.h = op_read(OPMODE_LONG, aa.d + 1); //6a
flags_cmp_w();
}
/**********************
*** 0xcf: cmp long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void bCPU::op_cmp_longb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
rd.l = op_read(OPMODE_LONG, aa.d); //5
flags_cmp_b();
}
void bCPU::op_cmp_longw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
rd.l = op_read(OPMODE_LONG, aa.d); //5
rd.h = op_read(OPMODE_LONG, aa.d + 1); //5a
flags_cmp_w();
}
/************************
*** 0xdf: cmp long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void bCPU::op_cmp_longxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
flags_cmp_b();
}
void bCPU::op_cmp_longxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
flags_cmp_w();
}
/************************
*** 0xd9: cmp addr,y ***
************************
cycles:
[1 ] pbr,pc ; opercmp
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_cmp_addryb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
flags_cmp_b();
}
void bCPU::op_cmp_addryw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
flags_cmp_w();
}
/**********************
*** 0xd5: cmp dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void bCPU::op_cmp_dpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
flags_cmp_b();
}
void bCPU::op_cmp_dpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
flags_cmp_w();
}
/************************
*** 0xc1: cmp (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_cmp_idpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
rd.l = op_read(OPMODE_DBR, aa.w); //6
flags_cmp_b();
}
void bCPU::op_cmp_idpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
rd.l = op_read(OPMODE_DBR, aa.w); //6
rd.h = op_read(OPMODE_DBR, aa.w + 1); //6a
flags_cmp_w();
}
/************************
*** 0xd1: cmp (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_cmp_idpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
flags_cmp_b();
}
void bCPU::op_cmp_idpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
flags_cmp_w();
}
/************************
*** 0xd7: cmp [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void bCPU::op_cmp_ildpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
flags_cmp_b();
}
void bCPU::op_cmp_ildpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
flags_cmp_w();
}
/**********************
*** 0xc3: cmp sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void bCPU::op_cmp_srb() {
sp = op_read(); //2
cpu_io(); //3
rd.l = op_read(OPMODE_SP, sp); //4
flags_cmp_b();
}
void bCPU::op_cmp_srw() {
sp = op_read(); //2
cpu_io(); //3
rd.l = op_read(OPMODE_SP, sp); //4
rd.h = op_read(OPMODE_SP, sp + 1); //4a
flags_cmp_w();
}
/**************************
*** 0xd3: cmp (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_cmp_isryb() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
flags_cmp_b();
}
void bCPU::op_cmp_isryw() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
flags_cmp_w();
}

View File

@ -1,444 +0,0 @@
inline void bCPU::flags_eor_b() {
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
inline void bCPU::flags_eor_w() {
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
/************************
*** 0x49: eor #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void bCPU::op_eor_constb() {
regs.a.l ^= op_read(); //2
flags_eor_b();
}
void bCPU::op_eor_constw() {
regs.a.l ^= op_read(); //2
regs.a.h ^= op_read(); //2a
flags_eor_w();
}
/**********************
*** 0x4d: eor addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_eor_addrb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
regs.a.l ^= op_read(OPMODE_DBR, aa.w); //4
flags_eor_b();
}
void bCPU::op_eor_addrw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
regs.a.l ^= op_read(OPMODE_DBR, aa.w); //4
regs.a.h ^= op_read(OPMODE_DBR, aa.w + 1); //4a
flags_eor_w();
}
/************************
*** 0x5d: eor addr,x ***
************************
cycles:
[1 ] pbr,pc ; opereor
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void bCPU::op_eor_addrxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.x.w); //4
flags_eor_b();
}
void bCPU::op_eor_addrxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.x.w); //4
regs.a.h ^= op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
flags_eor_w();
}
/********************
*** 0x45: eor dp ***
********************
cycles:
[1 ] pbr,pc ; opereor
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void bCPU::op_eor_dpb() {
dp = op_read(); //2
cpu_c2(); //2a
regs.a.l ^= op_read(OPMODE_DP, dp); //3
flags_eor_b();
}
void bCPU::op_eor_dpw() {
dp = op_read(); //2
cpu_c2(); //2a
regs.a.l ^= op_read(OPMODE_DP, dp); //3
regs.a.h ^= op_read(OPMODE_DP, dp + 1); //3a
flags_eor_w();
}
/**********************
*** 0x52: eor (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_eor_idpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
regs.a.l ^= op_read(OPMODE_DBR, aa.w); //5
flags_eor_b();
}
void bCPU::op_eor_idpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
regs.a.l ^= op_read(OPMODE_DBR, aa.w); //5
regs.a.h ^= op_read(OPMODE_DBR, aa.w + 1); //5
flags_eor_w();
}
/**********************
*** 0x47: eor [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void bCPU::op_eor_ildpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l ^= op_read(OPMODE_LONG, aa.d); //6
flags_eor_b();
}
void bCPU::op_eor_ildpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l ^= op_read(OPMODE_LONG, aa.d); //6
regs.a.h ^= op_read(OPMODE_LONG, aa.d + 1); //6a
flags_eor_w();
}
/**********************
*** 0x4f: eor long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void bCPU::op_eor_longb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l ^= op_read(OPMODE_LONG, aa.d); //5
flags_eor_b();
}
void bCPU::op_eor_longw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l ^= op_read(OPMODE_LONG, aa.d); //5
regs.a.h ^= op_read(OPMODE_LONG, aa.d + 1); //5a
flags_eor_w();
}
/************************
*** 0x5f: eor long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void bCPU::op_eor_longxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l ^= op_read(OPMODE_LONG, aa.d + regs.x.w); //5
flags_eor_b();
}
void bCPU::op_eor_longxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l ^= op_read(OPMODE_LONG, aa.d + regs.x.w); //5
regs.a.h ^= op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
flags_eor_w();
}
/************************
*** 0x59: eor addr,y ***
************************
cycles:
[1 ] pbr,pc ; opereor
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_eor_addryb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //4
flags_eor_b();
}
void bCPU::op_eor_addryw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //4
regs.a.h ^= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
flags_eor_w();
}
/**********************
*** 0x55: eor dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void bCPU::op_eor_dpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
regs.a.l ^= op_read(OPMODE_DP, dp + regs.x.w); //4
flags_eor_b();
}
void bCPU::op_eor_dpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
regs.a.l ^= op_read(OPMODE_DP, dp + regs.x.w); //4
regs.a.h ^= op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
flags_eor_w();
}
/************************
*** 0x41: eor (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_eor_idpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
regs.a.l ^= op_read(OPMODE_DBR, aa.w); //6
flags_eor_b();
}
void bCPU::op_eor_idpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
regs.a.l ^= op_read(OPMODE_DBR, aa.w); //6
regs.a.h ^= op_read(OPMODE_DBR, aa.w + 1); //6a
flags_eor_w();
}
/************************
*** 0x51: eor (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_eor_idpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //5
flags_eor_b();
}
void bCPU::op_eor_idpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //5
regs.a.h ^= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
flags_eor_w();
}
/************************
*** 0x57: eor [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void bCPU::op_eor_ildpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l ^= op_read(OPMODE_LONG, aa.d + regs.y.w); //6
flags_eor_b();
}
void bCPU::op_eor_ildpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l ^= op_read(OPMODE_LONG, aa.d + regs.y.w); //6
regs.a.h ^= op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
flags_eor_w();
}
/**********************
*** 0x43: eor sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void bCPU::op_eor_srb() {
sp = op_read(); //2
cpu_io(); //3
regs.a.l ^= op_read(OPMODE_SP, sp); //4
flags_eor_b();
}
void bCPU::op_eor_srw() {
sp = op_read(); //2
cpu_io(); //3
regs.a.l ^= op_read(OPMODE_SP, sp); //4
regs.a.h ^= op_read(OPMODE_SP, sp + 1); //4a
flags_eor_w();
}
/**************************
*** 0x53: eor (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_eor_isryb() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //7
flags_eor_b();
}
void bCPU::op_eor_isryw() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
regs.a.l ^= op_read(OPMODE_DBR, aa.w + regs.y.w); //7
regs.a.h ^= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
flags_eor_w();
}

View File

@ -1,433 +0,0 @@
/*****************
*** 0x1a: inc ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void bCPU::op_incb() {
cpu_io(); //2
regs.a.l++;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
void bCPU::op_incw() {
cpu_io(); //2
regs.a.w++;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
/**********************
*** 0xee: inc addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
[5 ] dbr,aa+1 ; io
[6a] dbr,aa+1 ; data high [1]
[6 ] dbr,aa ; data low
*/
void bCPU::op_inc_addrb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
rd.l++;
cpu_io(); //5
op_write(OPMODE_DBR, aa.w, rd.l); //6
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_inc_addrw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
rd.w++;
cpu_io(); //5
op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a
op_write(OPMODE_DBR, aa.w, rd.l); //6
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/************************
*** 0xfe: inc addr,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aah,aal+xl ; io
[5 ] dbr,aa+x ; data low
[5a] dbr,aa+x+1 ; data high [1]
[6 ] dbr,aa+x+1 ; io
[7a] dbr,aa+x+1 ; data high [1]
[7 ] dbr,aa+x ; data low
*/
void bCPU::op_inc_addrxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
rd.l++;
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_inc_addrxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a
rd.w++;
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/********************
*** 0xe6: inc dp ***
********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
[4 ] 0,d+dp+1 ; io
[5a] 0,d+dp+1 ; data high [1]
[5 ] 0,d+dp ; data low
*/
void bCPU::op_inc_dpb() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
rd.l++;
cpu_io(); //4
op_write(OPMODE_DP, dp, rd.l); //5
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_inc_dpw() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
rd.h = op_read(OPMODE_DP, dp + 1); //3a
rd.w++;
cpu_io(); //4
op_write(OPMODE_DP, dp + 1, rd.h); //5a
op_write(OPMODE_DP, dp, rd.l); //5
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/**********************
*** 0xf6: inc dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high [1]
[5 ] 0,d+dp+x+1 ; io
[6a] 0,d+dp+x+1 ; data high [1]
[6 ] 0,d+dp+x ; data low
*/
void bCPU::op_inc_dpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
rd.l++;
cpu_io(); //5
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_inc_dpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
rd.w++;
cpu_io(); //5
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/*****************
*** 0xe8: inx ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void bCPU::op_inxb() {
cpu_io(); //2
regs.x.l++;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
}
void bCPU::op_inxw() {
cpu_io(); //2
regs.x.w++;
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
/*****************
*** 0xc8: iny ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void bCPU::op_inyb() {
cpu_io(); //2
regs.y.l++;
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
}
void bCPU::op_inyw() {
cpu_io(); //2
regs.y.w++;
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
/*****************
*** 0x3a: dec ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void bCPU::op_decb() {
cpu_io(); //2
regs.a.l--;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
void bCPU::op_decw() {
cpu_io(); //2
regs.a.w--;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
/**********************
*** 0xce: dec addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
[5 ] dbr,aa+1 ; io
[6a] dbr,aa+1 ; data high [1]
[6 ] dbr,aa ; data low
*/
void bCPU::op_dec_addrb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
rd.l--;
cpu_io(); //5
op_write(OPMODE_DBR, aa.w, rd.l); //6
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_dec_addrw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
rd.w--;
cpu_io(); //5
op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a
op_write(OPMODE_DBR, aa.w, rd.l); //6
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/************************
*** 0xde: dec addr,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aah,aal+xl ; io
[5 ] dbr,aa+x ; data low
[5a] dbr,aa+x+1 ; data high [1]
[6 ] dbr,aa+x+1 ; io
[7a] dbr,aa+x+1 ; data high [1]
[7 ] dbr,aa+x ; data low
*/
void bCPU::op_dec_addrxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
rd.l--;
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_dec_addrxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a
rd.w--;
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/********************
*** 0xc6: dec dp ***
********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
[4 ] 0,d+dp+1 ; io
[5a] 0,d+dp+1 ; data high [1]
[5 ] 0,d+dp ; data low
*/
void bCPU::op_dec_dpb() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
rd.l--;
cpu_io(); //4
op_write(OPMODE_DP, dp, rd.l); //5
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_dec_dpw() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
rd.h = op_read(OPMODE_DP, dp + 1); //3a
rd.w--;
cpu_io(); //4
op_write(OPMODE_DP, dp + 1, rd.h); //5a
op_write(OPMODE_DP, dp, rd.l); //5
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/**********************
*** 0xd6: dec dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high [1]
[5 ] 0,d+dp+x+1 ; io
[6a] 0,d+dp+x+1 ; data high [1]
[6 ] 0,d+dp+x ; data low
*/
void bCPU::op_dec_dpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
rd.l--;
cpu_io(); //5
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_dec_dpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
rd.w--;
cpu_io(); //5
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/*****************
*** 0xca: dex ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void bCPU::op_dexb() {
cpu_io(); //2
regs.x.l--;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
}
void bCPU::op_dexw() {
cpu_io(); //2
regs.x.w--;
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
/*****************
*** 0x88: dey ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void bCPU::op_deyb() {
cpu_io(); //2
regs.y.l--;
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
}
void bCPU::op_deyw() {
cpu_io(); //2
regs.y.w--;
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}

View File

@ -1,444 +0,0 @@
inline void bCPU::flags_lda_b() {
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
inline void bCPU::flags_lda_w() {
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
/************************
*** 0xa9: lda #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void bCPU::op_lda_constb() {
regs.a.l = op_read(); //2
flags_lda_b();
}
void bCPU::op_lda_constw() {
regs.a.l = op_read(); //2
regs.a.h = op_read(); //2a
flags_lda_w();
}
/**********************
*** 0xad: lda addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_lda_addrb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
regs.a.l = op_read(OPMODE_DBR, aa.w); //4
flags_lda_b();
}
void bCPU::op_lda_addrw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
regs.a.l = op_read(OPMODE_DBR, aa.w); //4
regs.a.h = op_read(OPMODE_DBR, aa.w + 1); //4a
flags_lda_w();
}
/************************
*** 0xbd: lda addr,x ***
************************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void bCPU::op_lda_addrxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
flags_lda_b();
}
void bCPU::op_lda_addrxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
regs.a.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
flags_lda_w();
}
/********************
*** 0xa5: lda dp ***
********************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void bCPU::op_lda_dpb() {
dp = op_read(); //2
cpu_c2(); //2a
regs.a.l = op_read(OPMODE_DP, dp); //3
flags_lda_b();
}
void bCPU::op_lda_dpw() {
dp = op_read(); //2
cpu_c2(); //2a
regs.a.l = op_read(OPMODE_DP, dp); //3
regs.a.h = op_read(OPMODE_DP, dp + 1); //3a
flags_lda_w();
}
/**********************
*** 0xb2: lda (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_lda_idpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
regs.a.l = op_read(OPMODE_DBR, aa.w); //5
flags_lda_b();
}
void bCPU::op_lda_idpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
regs.a.l = op_read(OPMODE_DBR, aa.w); //5
regs.a.h = op_read(OPMODE_DBR, aa.w + 1); //5
flags_lda_w();
}
/**********************
*** 0xa7: lda [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void bCPU::op_lda_ildpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l = op_read(OPMODE_LONG, aa.d); //6
flags_lda_b();
}
void bCPU::op_lda_ildpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l = op_read(OPMODE_LONG, aa.d); //6
regs.a.h = op_read(OPMODE_LONG, aa.d + 1); //6a
flags_lda_w();
}
/**********************
*** 0xaf: lda long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void bCPU::op_lda_longb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l = op_read(OPMODE_LONG, aa.d); //5
flags_lda_b();
}
void bCPU::op_lda_longw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l = op_read(OPMODE_LONG, aa.d); //5
regs.a.h = op_read(OPMODE_LONG, aa.d + 1); //5a
flags_lda_w();
}
/************************
*** 0xbf: lda long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void bCPU::op_lda_longxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
flags_lda_b();
}
void bCPU::op_lda_longxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
regs.a.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
flags_lda_w();
}
/************************
*** 0xb9: lda addr,y ***
************************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_lda_addryb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
flags_lda_b();
}
void bCPU::op_lda_addryw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
regs.a.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
flags_lda_w();
}
/**********************
*** 0xb5: lda dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void bCPU::op_lda_dpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
regs.a.l = op_read(OPMODE_DP, dp + regs.x.w); //4
flags_lda_b();
}
void bCPU::op_lda_dpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
regs.a.l = op_read(OPMODE_DP, dp + regs.x.w); //4
regs.a.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
flags_lda_w();
}
/************************
*** 0xa1: lda (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_lda_idpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
regs.a.l = op_read(OPMODE_DBR, aa.w); //6
flags_lda_b();
}
void bCPU::op_lda_idpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
regs.a.l = op_read(OPMODE_DBR, aa.w); //6
regs.a.h = op_read(OPMODE_DBR, aa.w + 1); //6a
flags_lda_w();
}
/************************
*** 0xb1: lda (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_lda_idpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
flags_lda_b();
}
void bCPU::op_lda_idpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
regs.a.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
flags_lda_w();
}
/************************
*** 0xb7: lda [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void bCPU::op_lda_ildpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
flags_lda_b();
}
void bCPU::op_lda_ildpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
regs.a.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
flags_lda_w();
}
/**********************
*** 0xa3: lda sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void bCPU::op_lda_srb() {
sp = op_read(); //2
cpu_io(); //3
regs.a.l = op_read(OPMODE_SP, sp); //4
flags_lda_b();
}
void bCPU::op_lda_srw() {
sp = op_read(); //2
cpu_io(); //3
regs.a.l = op_read(OPMODE_SP, sp); //4
regs.a.h = op_read(OPMODE_SP, sp + 1); //4a
flags_lda_w();
}
/**************************
*** 0xb3: lda (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_lda_isryb() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
flags_lda_b();
}
void bCPU::op_lda_isryw() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
regs.a.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
regs.a.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
flags_lda_w();
}

File diff suppressed because it is too large Load Diff

View File

@ -1,444 +0,0 @@
inline void bCPU::flags_ora_b() {
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
inline void bCPU::flags_ora_w() {
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
/************************
*** 0x09: ora #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void bCPU::op_ora_constb() {
regs.a.l |= op_read(); //2
flags_ora_b();
}
void bCPU::op_ora_constw() {
regs.a.l |= op_read(); //2
regs.a.h |= op_read(); //2a
flags_ora_w();
}
/**********************
*** 0x0d: ora addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_ora_addrb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
regs.a.l |= op_read(OPMODE_DBR, aa.w); //4
flags_ora_b();
}
void bCPU::op_ora_addrw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
regs.a.l |= op_read(OPMODE_DBR, aa.w); //4
regs.a.h |= op_read(OPMODE_DBR, aa.w + 1); //4a
flags_ora_w();
}
/************************
*** 0x1d: ora addr,x ***
************************
cycles:
[1 ] pbr,pc ; operora
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void bCPU::op_ora_addrxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.x.w); //4
flags_ora_b();
}
void bCPU::op_ora_addrxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.x.w); //4
regs.a.h |= op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
flags_ora_w();
}
/********************
*** 0x05: ora dp ***
********************
cycles:
[1 ] pbr,pc ; operora
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void bCPU::op_ora_dpb() {
dp = op_read(); //2
cpu_c2(); //2a
regs.a.l |= op_read(OPMODE_DP, dp); //3
flags_ora_b();
}
void bCPU::op_ora_dpw() {
dp = op_read(); //2
cpu_c2(); //2a
regs.a.l |= op_read(OPMODE_DP, dp); //3
regs.a.h |= op_read(OPMODE_DP, dp + 1); //3a
flags_ora_w();
}
/**********************
*** 0x12: ora (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_ora_idpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
regs.a.l |= op_read(OPMODE_DBR, aa.w); //5
flags_ora_b();
}
void bCPU::op_ora_idpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
regs.a.l |= op_read(OPMODE_DBR, aa.w); //5
regs.a.h |= op_read(OPMODE_DBR, aa.w + 1); //5
flags_ora_w();
}
/**********************
*** 0x07: ora [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void bCPU::op_ora_ildpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l |= op_read(OPMODE_LONG, aa.d); //6
flags_ora_b();
}
void bCPU::op_ora_ildpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l |= op_read(OPMODE_LONG, aa.d); //6
regs.a.h |= op_read(OPMODE_LONG, aa.d + 1); //6a
flags_ora_w();
}
/**********************
*** 0x0f: ora long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void bCPU::op_ora_longb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l |= op_read(OPMODE_LONG, aa.d); //5
flags_ora_b();
}
void bCPU::op_ora_longw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l |= op_read(OPMODE_LONG, aa.d); //5
regs.a.h |= op_read(OPMODE_LONG, aa.d + 1); //5a
flags_ora_w();
}
/************************
*** 0x1f: ora long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void bCPU::op_ora_longxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l |= op_read(OPMODE_LONG, aa.d + regs.x.w); //5
flags_ora_b();
}
void bCPU::op_ora_longxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
regs.a.l |= op_read(OPMODE_LONG, aa.d + regs.x.w); //5
regs.a.h |= op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
flags_ora_w();
}
/************************
*** 0x19: ora addr,y ***
************************
cycles:
[1 ] pbr,pc ; operora
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_ora_addryb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //4
flags_ora_b();
}
void bCPU::op_ora_addryw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //4
regs.a.h |= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
flags_ora_w();
}
/**********************
*** 0x15: ora dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void bCPU::op_ora_dpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
regs.a.l |= op_read(OPMODE_DP, dp + regs.x.w); //4
flags_ora_b();
}
void bCPU::op_ora_dpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
regs.a.l |= op_read(OPMODE_DP, dp + regs.x.w); //4
regs.a.h |= op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
flags_ora_w();
}
/************************
*** 0x01: ora (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_ora_idpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
regs.a.l |= op_read(OPMODE_DBR, aa.w); //6
flags_ora_b();
}
void bCPU::op_ora_idpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
regs.a.l |= op_read(OPMODE_DBR, aa.w); //6
regs.a.h |= op_read(OPMODE_DBR, aa.w + 1); //6a
flags_ora_w();
}
/************************
*** 0x11: ora (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_ora_idpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //5
flags_ora_b();
}
void bCPU::op_ora_idpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //5
regs.a.h |= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
flags_ora_w();
}
/************************
*** 0x17: ora [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void bCPU::op_ora_ildpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l |= op_read(OPMODE_LONG, aa.d + regs.y.w); //6
flags_ora_b();
}
void bCPU::op_ora_ildpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
regs.a.l |= op_read(OPMODE_LONG, aa.d + regs.y.w); //6
regs.a.h |= op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
flags_ora_w();
}
/**********************
*** 0x03: ora sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void bCPU::op_ora_srb() {
sp = op_read(); //2
cpu_io(); //3
regs.a.l |= op_read(OPMODE_SP, sp); //4
flags_ora_b();
}
void bCPU::op_ora_srw() {
sp = op_read(); //2
cpu_io(); //3
regs.a.l |= op_read(OPMODE_SP, sp); //4
regs.a.h |= op_read(OPMODE_SP, sp + 1); //4a
flags_ora_w();
}
/**************************
*** 0x13: ora (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_ora_isryb() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //7
flags_ora_b();
}
void bCPU::op_ora_isryw() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
regs.a.l |= op_read(OPMODE_DBR, aa.w + regs.y.w); //7
regs.a.h |= op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
flags_ora_w();
}

View File

@ -1,441 +1,310 @@
/**********************
*** 0x4c: jmp addr ***
**********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; new pcl
[3] pbr,pc+2 ; new pch
*/
void bCPU::op_bra() {
l1:
rd.l = op_read();
if(1) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
return;
}
l2:
cpu_c6(aa.w);
l3:
cpu_io();
}
void bCPU::op_bcc() {
l1:
rd.l = op_read();
if(!regs.p.c) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
return;
}
l2:
cpu_c6(aa.w);
l3:
cpu_io();
}
void bCPU::op_bcs() {
l1:
rd.l = op_read();
if(regs.p.c) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
return;
}
l2:
cpu_c6(aa.w);
l3:
cpu_io();
}
void bCPU::op_bne() {
l1:
rd.l = op_read();
if(!regs.p.z) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
return;
}
l2:
cpu_c6(aa.w);
l3:
cpu_io();
}
void bCPU::op_beq() {
l1:
rd.l = op_read();
if(regs.p.z) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
return;
}
l2:
cpu_c6(aa.w);
l3:
cpu_io();
}
void bCPU::op_bpl() {
l1:
rd.l = op_read();
if(!regs.p.n) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
return;
}
l2:
cpu_c6(aa.w);
l3:
cpu_io();
}
void bCPU::op_bmi() {
l1:
rd.l = op_read();
if(regs.p.n) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
return;
}
l2:
cpu_c6(aa.w);
l3:
cpu_io();
}
void bCPU::op_bvc() {
l1:
rd.l = op_read();
if(!regs.p.v) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
return;
}
l2:
cpu_c6(aa.w);
l3:
cpu_io();
}
void bCPU::op_bvs() {
l1:
rd.l = op_read();
if(regs.p.v) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
return;
}
l2:
cpu_c6(aa.w);
l3:
cpu_io();
}
void bCPU::op_brl() {
l1:
rd.l = op_read();
l2:
rd.h = op_read();
l3:
cpu_io();
regs.pc.w = regs.pc.d + (int16)rd.w;
}
void bCPU::op_jmp_addr() {
rd.l = op_read(); //2
rd.h = op_read(); //3
l1:
rd.l = op_read();
l2:
rd.h = op_read();
regs.pc.w = rd.w;
}
/**********************
*** 0x5c: jmp long ***
**********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; new pcl
[3] pbr,pc+2 ; new pch
[4] pbr,pc+3 ; new pbr
*/
void bCPU::op_jmp_long() {
rd.l = op_read(); //2
rd.h = op_read(); //3
rd.b = op_read(); //4
regs.pc.d = rd.d;
l1:
rd.l = op_read();
l2:
rd.h = op_read();
l3:
rd.b = op_read();
regs.pc.d = rd.d & 0xffffff;
}
/************************
*** 0x6c: jmp (addr) ***
************************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; aal
[3] pbr,pc+2 ; aah
[4] 0,aa ; new pcl
[5] 0,aa+1 ; new pch
*/
void bCPU::op_jmp_iaddr() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_ADDR, aa.w); //4
rd.h = op_read(OPMODE_ADDR, aa.w + 1); //5
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
rd.l = op_read(OPMODE_ADDR, aa.w);
l4:
rd.h = op_read(OPMODE_ADDR, aa.w + 1);
regs.pc.w = rd.w;
}
/**************************
*** 0x7c: jmp (addr,x) ***
**************************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; aal
[3] pbr,pc+2 ; aah
[4] pbr,pc+2 ; io
[5] pbr,aa+x ; new pcl
[6] pbr,aa+x+1 ; new pch
*/
void bCPU::op_jmp_iaddrx() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); //5
rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); //6
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w);
l5:
rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
}
/************************
*** 0xdc: jmp [addr] ***
************************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; aal
[3] pbr,pc+2 ; aah
[4] 0,aa ; new pcl
[5] 0,aa+1 ; new pch
[6] 0,aa+2 ; new pbr
*/
void bCPU::op_jmp_iladdr() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_ADDR, aa.w); //4
rd.h = op_read(OPMODE_ADDR, aa.w + 1); //5
rd.b = op_read(OPMODE_ADDR, aa.w + 2); //6
regs.pc.d = rd.d;
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
rd.l = op_read(OPMODE_ADDR, aa.w);
l4:
rd.h = op_read(OPMODE_ADDR, aa.w + 1);
l5:
rd.b = op_read(OPMODE_ADDR, aa.w + 2);
regs.pc.d = rd.d & 0xffffff;
}
/**********************
*** 0x20: jsr addr ***
**********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; new pcl
[3] pbr,pc+2 ; new pch
[4] pbr,pc+2 ; io
[5] 0,s ; pch
[6] 0,s-1 ; pcl
*/
void bCPU::op_jsr_addr() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
cpu_io();
l4:
regs.pc.w--;
stack_write(regs.pc.h); //5
stack_write(regs.pc.l); //6
stack_write(regs.pc.h);
l5:
stack_write(regs.pc.l);
regs.pc.w = aa.w;
}
/**********************
*** 0x22: jsr long ***
**********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; new pcl
[3] pbr,pc+2 ; new pch
[4] 0,s ; pbr
[5] 0,s ; io
[6] pbr,pc+3 ; new pbr
[7] 0,s-1 ; pch
[8] 0,s-2 ; pcl
*/
void bCPU::op_jsr_long() {
aa.l = op_read(); //2
aa.h = op_read(); //3
stack_write(regs.pc.b); //4
cpu_io(); //5
aa.b = op_read(); //6
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
stack_write(regs.pc.b);
l4:
cpu_io();
l5:
aa.b = op_read();
l6:
regs.pc.w--;
stack_write(regs.pc.h); //7
stack_write(regs.pc.l); //8
regs.pc.d = aa.d;
stack_write(regs.pc.h);
l7:
stack_write(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
}
/**************************
*** 0xfc: jsr (addr,x) ***
**************************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; aal
[3] 0,s ; pch
[4] 0,s-1 ; pcl
[5] pbr,pc+2 ; aah
[6] pbr,pc+2 ; io
[7] pbr,aa+x ; new pcl
[8] pbr,aa+x+1 ; new pch
*/
void bCPU::op_jsr_iaddrx() {
aa.l = op_read(); //2
stack_write(regs.pc.h); //3
stack_write(regs.pc.l); //4
aa.h = op_read(); //5
cpu_io(); //6
rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w); //7
rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1); //8
l1:
aa.l = op_read();
l2:
stack_write(regs.pc.h);
l3:
stack_write(regs.pc.l);
l4:
aa.h = op_read();
l5:
cpu_io();
l6:
rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w);
l7:
rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
}
/*****************
*** 0x40: rti ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
[3] pbr,pc+1 ; io
[4] 0,s+1 ; p
[5] 0,s+2 ; new pcl
[6] 0,s+3 ; new pch
[7] 0,s+4 ; pbr [7]
*/
void bCPU::op_rtie() {
cpu_io(); //2
cpu_io(); //3
regs.p = stack_read(); //4
rd.l = stack_read(); //5
rd.h = stack_read(); //6
void bCPU::op_rti() {
l1:
cpu_io();
l2:
cpu_io();
l3:
regs.p = stack_read();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
regs.pc.w = rd.w;
l4:
rd.l = stack_read();
l5:
rd.h = stack_read();
if(regs.e) {
regs.pc.w = rd.w;
return;
}
l6:
rd.b = stack_read();
regs.pc.d = rd.d & 0xffffff;
}
void bCPU::op_rtin() {
cpu_io(); //2
cpu_io(); //3
regs.p = stack_read(); //4
rd.l = stack_read(); //5
rd.h = stack_read(); //6
rd.b = stack_read(); //7
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
regs.pc.d = rd.d;
switch((regs.p >> 4) & 3) {
case 0:optbl = optbl_mx;break;
case 1:optbl = optbl_mX;break;
case 2:optbl = optbl_Mx;break;
case 3:optbl = optbl_MX;break;
}
}
/*****************
*** 0x60: rts ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
[3] pbr,pc+1 ; io
[4] 0,s+1 ; pcl
[5] 0,s+2 ; pch
[6] 0,s+2 ; io
*/
void bCPU::op_rts() {
cpu_io(); //2
cpu_io(); //3
rd.l = stack_read(); //4
rd.h = stack_read(); //5
cpu_io(); //6
l1:
cpu_io();
l2:
cpu_io();
l3:
rd.l = stack_read();
l4:
rd.h = stack_read();
l5:
cpu_io();
regs.pc.w = rd.w;
regs.pc.w++;
}
/*****************
*** 0x6b: rtl ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
[3] pbr,pc+1 ; io
[4] 0,s+1 ; pcl
[5] 0,s+2 ; pch
[6] 0,s+3 ; pbr
*/
void bCPU::op_rtl() {
cpu_io(); //2
cpu_io(); //3
rd.l = stack_read(); //4
rd.h = stack_read(); //5
rd.b = stack_read(); //6
regs.pc.d = rd.d;
l1:
cpu_io();
l2:
cpu_io();
l3:
rd.l = stack_read();
l4:
rd.h = stack_read();
l5:
rd.b = stack_read();
regs.pc.d = rd.d & 0xffffff;
regs.pc.w++;
}
/**********************
*** 0x80: bra near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void bCPU::op_bra() {
uint16 r;
rd.l = op_read(); //2
cpu_io(); //2a
r = regs.pc + (int8)rd.l;
cpu_c6(r); //2b
regs.pc.w = r;
}
/*********************
*** 0x82: brl far ***
*********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; offset low
[3] pbr,pc+2 ; offset high
[4] pbr,pc+2 ; io
*/
void bCPU::op_brl() {
uint16 r;
rd.l = op_read(); //2
rd.h = op_read(); //3
cpu_io(); //4
r = regs.pc + (int16)rd.w;
regs.pc.w = r;
}
/**********************
*** 0x90: bcc near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void bCPU::op_bcc() {
uint16 r;
rd.l = op_read(); //2
if(!regs.p.c) {
cpu_io(); //2a
r = regs.pc + (int8)rd.l;
cpu_c6(r); //2b
regs.pc.w = r;
}
}
/**********************
*** 0xb0: bcs near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void bCPU::op_bcs() {
uint16 r;
rd.l = op_read(); //2
if(regs.p.c) {
cpu_io(); //2a
r = regs.pc + (int8)rd.l;
cpu_c6(r); //2b
regs.pc.w = r;
}
}
/**********************
*** 0xd0: bne near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void bCPU::op_bne() {
uint16 r;
rd.l = op_read(); //2
if(!regs.p.z) {
cpu_io(); //2a
r = regs.pc + (int8)rd.l;
cpu_c6(r); //2b
regs.pc.w = r;
}
}
/**********************
*** 0xf0: beq near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void bCPU::op_beq() {
uint16 r;
rd.l = op_read(); //2
if(regs.p.z) {
cpu_io(); //2a
r = regs.pc + (int8)rd.l;
cpu_c6(r); //2b
regs.pc.w = r;
}
}
/**********************
*** 0x10: bpl near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void bCPU::op_bpl() {
uint16 r;
rd.l = op_read(); //2
if(!regs.p.n) {
cpu_io(); //2a
r = regs.pc + (int8)rd.l;
cpu_c6(r); //2b
regs.pc.w = r;
}
}
/**********************
*** 0x30: bmi near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void bCPU::op_bmi() {
uint16 r;
rd.l = op_read(); //2
if(regs.p.n) {
cpu_io(); //2a
r = regs.pc + (int8)rd.l;
cpu_c6(r); //2b
regs.pc.w = r;
}
}
/**********************
*** 0x50: bvc near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void bCPU::op_bvc() {
uint16 r;
rd.l = op_read(); //2
if(!regs.p.v) {
cpu_io(); //2a
r = regs.pc + (int8)rd.l;
cpu_c6(r); //2b
regs.pc.w = r;
}
}
/**********************
*** 0x70: bvs near ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; offset
[2a] pbr,pc+1 ; io [5]
[2b] pbr,pc+1 ; io [6]
*/
void bCPU::op_bvs() {
uint16 r;
rd.l = op_read(); //2
if(regs.p.v) {
cpu_io(); //2a
r = regs.pc + (int8)rd.l;
cpu_c6(r); //2b
regs.pc.w = r;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,740 @@
void bCPU::op_inc() {
l1:
cpu_io();
if(regs.p.m) {
regs.a.l++;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.a.w++;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
void bCPU::op_inx() {
l1:
cpu_io();
if(regs.p.x) {
regs.x.l++;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
} else {
regs.x.w++;
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
}
void bCPU::op_iny() {
l1:
cpu_io();
if(regs.p.x) {
regs.y.l++;
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
} else {
regs.y.w++;
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
}
void bCPU::op_dec() {
l1:
cpu_io();
if(regs.p.m) {
regs.a.l--;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.a.w--;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
void bCPU::op_dex() {
l1:
cpu_io();
if(regs.p.x) {
regs.x.l--;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
} else {
regs.x.w--;
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
}
void bCPU::op_dey() {
l1:
cpu_io();
if(regs.p.x) {
regs.y.l--;
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
} else {
regs.y.w--;
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
}
void bCPU::op_asl() {
l1:
cpu_io();
if(regs.p.m) {
regs.p.c = !!(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.c = !!(regs.a.w & 0x8000);
regs.a.w <<= 1;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
void bCPU::op_lsr() {
l1:
cpu_io();
if(regs.p.m) {
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.c = regs.a.w & 1;
regs.a.w >>= 1;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
void bCPU::op_rol() {
l1:
cpu_io();
uint16 c = regs.p.c;
if(regs.p.m) {
regs.p.c = !!(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.a.l |= c;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.c = !!(regs.a.w & 0x8000);
regs.a.w <<= 1;
regs.a.w |= c;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
void bCPU::op_ror() {
l1:
cpu_io();
uint16 c;
if(regs.p.m) {
c = (regs.p.c)?0x80:0;
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
regs.a.l |= c;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
c = (regs.p.c)?0x8000:0;
regs.p.c = regs.a.w & 1;
regs.a.w >>= 1;
regs.a.w |= c;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
void bCPU::op_inc_addr() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
rd.l = op_read(OPMODE_DBR, aa.w);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DBR, aa.w + 1);
l5:
cpu_io();
if(regs.p.m) { op_inc_b(); goto l7; }
else op_inc_w();
l6:
op_write(OPMODE_DBR, aa.w + 1, rd.h);
l7:
op_write(OPMODE_DBR, aa.w, rd.l);
}
void bCPU::op_dec_addr() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
rd.l = op_read(OPMODE_DBR, aa.w);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DBR, aa.w + 1);
l5:
cpu_io();
if(regs.p.m) { op_dec_b(); goto l7; }
else op_dec_w();
l6:
op_write(OPMODE_DBR, aa.w + 1, rd.h);
l7:
op_write(OPMODE_DBR, aa.w, rd.l);
}
void bCPU::op_asl_addr() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
rd.l = op_read(OPMODE_DBR, aa.w);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DBR, aa.w + 1);
l5:
cpu_io();
if(regs.p.m) { op_asl_b(); goto l7; }
else op_asl_w();
l6:
op_write(OPMODE_DBR, aa.w + 1, rd.h);
l7:
op_write(OPMODE_DBR, aa.w, rd.l);
}
void bCPU::op_lsr_addr() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
rd.l = op_read(OPMODE_DBR, aa.w);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DBR, aa.w + 1);
l5:
cpu_io();
if(regs.p.m) { op_lsr_b(); goto l7; }
else op_lsr_w();
l6:
op_write(OPMODE_DBR, aa.w + 1, rd.h);
l7:
op_write(OPMODE_DBR, aa.w, rd.l);
}
void bCPU::op_rol_addr() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
rd.l = op_read(OPMODE_DBR, aa.w);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DBR, aa.w + 1);
l5:
cpu_io();
if(regs.p.m) { op_rol_b(); goto l7; }
else op_rol_w();
l6:
op_write(OPMODE_DBR, aa.w + 1, rd.h);
l7:
op_write(OPMODE_DBR, aa.w, rd.l);
}
void bCPU::op_ror_addr() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
rd.l = op_read(OPMODE_DBR, aa.w);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DBR, aa.w + 1);
l5:
cpu_io();
if(regs.p.m) { op_ror_b(); goto l7; }
else op_ror_w();
l6:
op_write(OPMODE_DBR, aa.w + 1, rd.h);
l7:
op_write(OPMODE_DBR, aa.w, rd.l);
}
void bCPU::op_trb_addr() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
rd.l = op_read(OPMODE_DBR, aa.w);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DBR, aa.w + 1);
l5:
cpu_io();
if(regs.p.m) { op_trb_b(); goto l7; }
else op_trb_w();
l6:
op_write(OPMODE_DBR, aa.w + 1, rd.h);
l7:
op_write(OPMODE_DBR, aa.w, rd.l);
}
void bCPU::op_tsb_addr() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
rd.l = op_read(OPMODE_DBR, aa.w);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DBR, aa.w + 1);
l5:
cpu_io();
if(regs.p.m) { op_tsb_b(); goto l7; }
else op_tsb_w();
l6:
op_write(OPMODE_DBR, aa.w + 1, rd.h);
l7:
op_write(OPMODE_DBR, aa.w, rd.l);
}
void bCPU::op_inc_addrx() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
if(regs.p.m)goto l6;
l5:
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
l6:
cpu_io();
if(regs.p.m) { op_inc_b(); goto l8; }
else op_inc_w();
l7:
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
l8:
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
}
void bCPU::op_dec_addrx() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
if(regs.p.m)goto l6;
l5:
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
l6:
cpu_io();
if(regs.p.m) { op_dec_b(); goto l8; }
else op_dec_w();
l7:
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
l8:
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
}
void bCPU::op_asl_addrx() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
if(regs.p.m)goto l6;
l5:
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
l6:
cpu_io();
if(regs.p.m) { op_asl_b(); goto l8; }
else op_asl_w();
l7:
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
l8:
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
}
void bCPU::op_lsr_addrx() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
if(regs.p.m)goto l6;
l5:
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
l6:
cpu_io();
if(regs.p.m) { op_lsr_b(); goto l8; }
else op_lsr_w();
l7:
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
l8:
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
}
void bCPU::op_rol_addrx() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
if(regs.p.m)goto l6;
l5:
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
l6:
cpu_io();
if(regs.p.m) { op_rol_b(); goto l8; }
else op_rol_w();
l7:
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
l8:
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
}
void bCPU::op_ror_addrx() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
if(regs.p.m)goto l6;
l5:
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
l6:
cpu_io();
if(regs.p.m) { op_ror_b(); goto l8; }
else op_ror_w();
l7:
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
l8:
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
}
void bCPU::op_inc_dp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
rd.l = op_read(OPMODE_DP, dp);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DP, dp + 1);
l5:
cpu_io();
if(regs.p.m) { op_inc_b(); goto l7; }
else op_inc_w();
l6:
op_write(OPMODE_DP, dp + 1, rd.h);
l7:
op_write(OPMODE_DP, dp, rd.l);
}
void bCPU::op_dec_dp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
rd.l = op_read(OPMODE_DP, dp);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DP, dp + 1);
l5:
cpu_io();
if(regs.p.m) { op_dec_b(); goto l7; }
else op_dec_w();
l6:
op_write(OPMODE_DP, dp + 1, rd.h);
l7:
op_write(OPMODE_DP, dp, rd.l);
}
void bCPU::op_asl_dp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
rd.l = op_read(OPMODE_DP, dp);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DP, dp + 1);
l5:
cpu_io();
if(regs.p.m) { op_asl_b(); goto l7; }
else op_asl_w();
l6:
op_write(OPMODE_DP, dp + 1, rd.h);
l7:
op_write(OPMODE_DP, dp, rd.l);
}
void bCPU::op_lsr_dp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
rd.l = op_read(OPMODE_DP, dp);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DP, dp + 1);
l5:
cpu_io();
if(regs.p.m) { op_lsr_b(); goto l7; }
else op_lsr_w();
l6:
op_write(OPMODE_DP, dp + 1, rd.h);
l7:
op_write(OPMODE_DP, dp, rd.l);
}
void bCPU::op_rol_dp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
rd.l = op_read(OPMODE_DP, dp);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DP, dp + 1);
l5:
cpu_io();
if(regs.p.m) { op_rol_b(); goto l7; }
else op_rol_w();
l6:
op_write(OPMODE_DP, dp + 1, rd.h);
l7:
op_write(OPMODE_DP, dp, rd.l);
}
void bCPU::op_ror_dp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
rd.l = op_read(OPMODE_DP, dp);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DP, dp + 1);
l5:
cpu_io();
if(regs.p.m) { op_ror_b(); goto l7; }
else op_ror_w();
l6:
op_write(OPMODE_DP, dp + 1, rd.h);
l7:
op_write(OPMODE_DP, dp, rd.l);
}
void bCPU::op_trb_dp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
rd.l = op_read(OPMODE_DP, dp);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DP, dp + 1);
l5:
cpu_io();
if(regs.p.m) { op_trb_b(); goto l7; }
else op_trb_w();
l6:
op_write(OPMODE_DP, dp + 1, rd.h);
l7:
op_write(OPMODE_DP, dp, rd.l);
}
void bCPU::op_tsb_dp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
rd.l = op_read(OPMODE_DP, dp);
if(regs.p.m)goto l5;
l4:
rd.h = op_read(OPMODE_DP, dp + 1);
l5:
cpu_io();
if(regs.p.m) { op_tsb_b(); goto l7; }
else op_tsb_w();
l6:
op_write(OPMODE_DP, dp + 1, rd.h);
l7:
op_write(OPMODE_DP, dp, rd.l);
}
void bCPU::op_inc_dpx() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
if(regs.p.m)goto l6;
l5:
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
l6:
cpu_io();
if(regs.p.m) { op_inc_b(); goto l8; }
else op_inc_w();
l7:
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
l8:
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
}
void bCPU::op_dec_dpx() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
if(regs.p.m)goto l6;
l5:
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
l6:
cpu_io();
if(regs.p.m) { op_dec_b(); goto l8; }
else op_dec_w();
l7:
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
l8:
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
}
void bCPU::op_asl_dpx() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
if(regs.p.m)goto l6;
l5:
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
l6:
cpu_io();
if(regs.p.m) { op_asl_b(); goto l8; }
else op_asl_w();
l7:
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
l8:
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
}
void bCPU::op_lsr_dpx() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
if(regs.p.m)goto l6;
l5:
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
l6:
cpu_io();
if(regs.p.m) { op_lsr_b(); goto l8; }
else op_lsr_w();
l7:
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
l8:
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
}
void bCPU::op_rol_dpx() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
if(regs.p.m)goto l6;
l5:
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
l6:
cpu_io();
if(regs.p.m) { op_rol_b(); goto l8; }
else op_rol_w();
l7:
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
l8:
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
}
void bCPU::op_ror_dpx() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
cpu_io();
l4:
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
if(regs.p.m)goto l6;
l5:
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
l6:
cpu_io();
if(regs.p.m) { op_ror_b(); goto l8; }
else op_ror_w();
l7:
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
l8:
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
}

View File

@ -1,464 +0,0 @@
inline void bCPU::flags_sbc_b() {
int32 r = regs.a.l - rd.l - !regs.p.c;
//bcd
if(regs.p.d) {
if(((r ) & 15) > 9)r -= 6;
if(((r >> 4) & 15) > 9)r -= 6 << 4;
}
regs.p.n = !!(r & 0x80);
regs.p.v = !!((regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
regs.p.z = ((byte)r == 0);
regs.p.c = (r >= 0);
regs.a.l = r;
}
inline void bCPU::flags_sbc_w() {
int32 r = regs.a.w - rd.w - !regs.p.c;
//bcd
if(regs.p.d) {
if(((r ) & 15) > 9)r -= 6;
if(((r >> 4) & 15) > 9)r -= 6 << 4;
if(((r >> 8) & 15) > 9)r -= 6 << 8;
if(((r >> 12) & 15) > 9)r -= 6 << 12;
}
regs.p.n = !!(r & 0x8000);
regs.p.v = !!((regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
regs.p.z = ((word)r == 0);
regs.p.c = (r >= 0);
regs.a.w = r;
}
/************************
*** 0xe9: sbc #const ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; idl
[2a] pbr,pc+2 ; idh [1]
*/
void bCPU::op_sbc_constb() {
rd.l = op_read(); //2
flags_sbc_b();
}
void bCPU::op_sbc_constw() {
rd.l = op_read(); //2
rd.h = op_read(); //2a
flags_sbc_w();
}
/**********************
*** 0xed: sbc addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_sbc_addrb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
flags_sbc_b();
}
void bCPU::op_sbc_addrw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
flags_sbc_w();
}
/************************
*** 0xfd: sbc addr,x ***
************************
cycles:
[1 ] pbr,pc ; opersbc
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void bCPU::op_sbc_addrxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
flags_sbc_b();
}
void bCPU::op_sbc_addrxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //4a
flags_sbc_w();
}
/********************
*** 0xe5: sbc dp ***
********************
cycles:
[1 ] pbr,pc ; opersbc
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void bCPU::op_sbc_dpb() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
flags_sbc_b();
}
void bCPU::op_sbc_dpw() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
rd.h = op_read(OPMODE_DP, dp + 1); //3a
flags_sbc_w();
}
/**********************
*** 0xf2: sbc (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_sbc_idpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
rd.l = op_read(OPMODE_DBR, aa.w); //5
flags_sbc_b();
}
void bCPU::op_sbc_idpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
rd.l = op_read(OPMODE_DBR, aa.w); //5
rd.h = op_read(OPMODE_DBR, aa.w + 1); //5
flags_sbc_w();
}
/**********************
*** 0xe7: sbc [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void bCPU::op_sbc_ildpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
rd.l = op_read(OPMODE_LONG, aa.d); //6
flags_sbc_b();
}
void bCPU::op_sbc_ildpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
rd.l = op_read(OPMODE_LONG, aa.d); //6
rd.h = op_read(OPMODE_LONG, aa.d + 1); //6a
flags_sbc_w();
}
/**********************
*** 0xef: sbc long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void bCPU::op_sbc_longb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
rd.l = op_read(OPMODE_LONG, aa.d); //5
flags_sbc_b();
}
void bCPU::op_sbc_longw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
rd.l = op_read(OPMODE_LONG, aa.d); //5
rd.h = op_read(OPMODE_LONG, aa.d + 1); //5a
flags_sbc_w();
}
/************************
*** 0xff: sbc long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void bCPU::op_sbc_longxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
flags_sbc_b();
}
void bCPU::op_sbc_longxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w); //5
rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1); //5a
flags_sbc_w();
}
/************************
*** 0xf9: sbc addr,y ***
************************
cycles:
[1 ] pbr,pc ; opersbc
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_sbc_addryb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
flags_sbc_b();
}
void bCPU::op_sbc_addryw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //4a
flags_sbc_w();
}
/**********************
*** 0xf5: sbc dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void bCPU::op_sbc_dpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
flags_sbc_b();
}
void bCPU::op_sbc_dpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
flags_sbc_w();
}
/************************
*** 0xe1: sbc (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_sbc_idpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
rd.l = op_read(OPMODE_DBR, aa.w); //6
flags_sbc_b();
}
void bCPU::op_sbc_idpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
rd.l = op_read(OPMODE_DBR, aa.w); //6
rd.h = op_read(OPMODE_DBR, aa.w + 1); //6a
flags_sbc_w();
}
/************************
*** 0xf1: sbc (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_sbc_idpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
flags_sbc_b();
}
void bCPU::op_sbc_idpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //5
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //5a
flags_sbc_w();
}
/************************
*** 0xf7: sbc [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void bCPU::op_sbc_ildpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
flags_sbc_b();
}
void bCPU::op_sbc_ildpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w); //6
rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1); //6a
flags_sbc_w();
}
/**********************
*** 0xe3: sbc sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void bCPU::op_sbc_srb() {
sp = op_read(); //2
cpu_io(); //3
rd.l = op_read(OPMODE_SP, sp); //4
flags_sbc_b();
}
void bCPU::op_sbc_srw() {
sp = op_read(); //2
cpu_io(); //3
rd.l = op_read(OPMODE_SP, sp); //4
rd.h = op_read(OPMODE_SP, sp + 1); //4a
flags_sbc_w();
}
/**************************
*** 0xf3: sbc (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_sbc_isryb() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
flags_sbc_b();
}
void bCPU::op_sbc_isryw() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w); //7
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1); //7a
flags_sbc_w();
}

View File

@ -1,779 +0,0 @@
/*****************
*** 0x0a: asl ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void bCPU::op_aslb() {
cpu_io(); //2
regs.p.c = !!(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
void bCPU::op_aslw() {
cpu_io(); //2
regs.p.c = !!(regs.a.w & 0x8000);
regs.a.w <<= 1;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
/**********************
*** 0x0e: asl addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
[5 ] dbr,aa+1 ; io
[6a] dbr,aa+1 ; data high [1]
[6 ] dbr,aa ; data low
*/
void bCPU::op_asl_addrb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
regs.p.c = !!(rd.l & 0x80);
rd.l <<= 1;
cpu_io(); //5
op_write(OPMODE_DBR, aa.w, rd.l); //6
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_asl_addrw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
regs.p.c = !!(rd.w & 0x8000);
rd.w <<= 1;
cpu_io(); //5
op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a
op_write(OPMODE_DBR, aa.w, rd.l); //6
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/************************
*** 0x1e: asl addr,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aah,aal+xl ; io
[5 ] dbr,aa+x ; data low
[5a] dbr,aa+x+1 ; data high [1]
[6 ] dbr,aa+x+1 ; io
[7a] dbr,aa+x+1 ; data high [1]
[7 ] dbr,aa+x ; data low
*/
void bCPU::op_asl_addrxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
regs.p.c = !!(rd.l & 0x80);
rd.l <<= 1;
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_asl_addrxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a
regs.p.c = !!(rd.w & 0x8000);
rd.w <<= 1;
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/********************
*** 0x06: asl dp ***
********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
[4 ] 0,d+dp+1 ; io
[5a] 0,d+dp+1 ; data high [1]
[5 ] 0,d+dp ; data low
*/
void bCPU::op_asl_dpb() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
regs.p.c = !!(rd.l & 0x80);
rd.l <<= 1;
cpu_io(); //4
op_write(OPMODE_DP, dp, rd.l); //5
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_asl_dpw() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
rd.h = op_read(OPMODE_DP, dp + 1); //3a
regs.p.c = !!(rd.w & 0x8000);
rd.w <<= 1;
cpu_io(); //4
op_write(OPMODE_DP, dp + 1, rd.h); //5a
op_write(OPMODE_DP, dp, rd.l); //5
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/**********************
*** 0x16: asl dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high [1]
[5 ] 0,d+dp+x+1 ; io
[6a] 0,d+dp+x+1 ; data high [1]
[6 ] 0,d+dp+x ; data low
*/
void bCPU::op_asl_dpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
regs.p.c = !!(rd.l & 0x80);
rd.l <<= 1;
cpu_io(); //5
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_asl_dpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
regs.p.c = !!(rd.w & 0x8000);
rd.w <<= 1;
cpu_io(); //5
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/*****************
*** 0x4a: lsr ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void bCPU::op_lsrb() {
cpu_io(); //2
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
void bCPU::op_lsrw() {
cpu_io(); //2
regs.p.c = regs.a.w & 1;
regs.a.w >>= 1;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
/**********************
*** 0x4e: lsr addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
[5 ] dbr,aa+1 ; io
[6a] dbr,aa+1 ; data high [1]
[6 ] dbr,aa ; data low
*/
void bCPU::op_lsr_addrb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
regs.p.c = rd.l & 1;
rd.l >>= 1;
cpu_io(); //5
op_write(OPMODE_DBR, aa.w, rd.l); //6
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_lsr_addrw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
regs.p.c = rd.w & 1;
rd.w >>= 1;
cpu_io(); //5
op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a
op_write(OPMODE_DBR, aa.w, rd.l); //6
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/************************
*** 0x5e: lsr addr,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aah,aal+xl ; io
[5 ] dbr,aa+x ; data low
[5a] dbr,aa+x+1 ; data high [1]
[6 ] dbr,aa+x+1 ; io
[7a] dbr,aa+x+1 ; data high [1]
[7 ] dbr,aa+x ; data low
*/
void bCPU::op_lsr_addrxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
regs.p.c = rd.l & 1;
rd.l >>= 1;
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_lsr_addrxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a
regs.p.c = rd.w & 1;
rd.w >>= 1;
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/********************
*** 0x46: lsr dp ***
********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
[4 ] 0,d+dp+1 ; io
[5a] 0,d+dp+1 ; data high [1]
[5 ] 0,d+dp ; data low
*/
void bCPU::op_lsr_dpb() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
regs.p.c = rd.l & 1;
rd.l >>= 1;
cpu_io(); //4
op_write(OPMODE_DP, dp, rd.l); //5
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_lsr_dpw() {
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
rd.h = op_read(OPMODE_DP, dp + 1); //3a
regs.p.c = rd.w & 1;
rd.w >>= 1;
cpu_io(); //4
op_write(OPMODE_DP, dp + 1, rd.h); //5a
op_write(OPMODE_DP, dp, rd.l); //5
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/**********************
*** 0x56: lsr dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high [1]
[5 ] 0,d+dp+x+1 ; io
[6a] 0,d+dp+x+1 ; data high [1]
[6 ] 0,d+dp+x ; data low
*/
void bCPU::op_lsr_dpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
regs.p.c = rd.l & 1;
rd.l >>= 1;
cpu_io(); //5
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_lsr_dpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
regs.p.c = rd.w & 1;
rd.w >>= 1;
cpu_io(); //5
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/*****************
*** 0x2a: rol ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void bCPU::op_rolb() {
uint8 c = regs.p.c;
cpu_io(); //2
regs.p.c = !!(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.a.l |= c;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
void bCPU::op_rolw() {
uint16 c = regs.p.c;
cpu_io(); //2
regs.p.c = !!(regs.a.w & 0x8000);
regs.a.w <<= 1;
regs.a.w |= c;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
/**********************
*** 0x2e: rol addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
[5 ] dbr,aa+1 ; io
[6a] dbr,aa+1 ; data high [1]
[6 ] dbr,aa ; data low
*/
void bCPU::op_rol_addrb() {
uint8 c = regs.p.c;
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
regs.p.c = !!(rd.l & 0x80);
rd.l <<= 1;
rd.l |= c;
cpu_io(); //5
op_write(OPMODE_DBR, aa.w, rd.l); //6
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_rol_addrw() {
uint16 c = regs.p.c;
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
regs.p.c = !!(rd.w & 0x8000);
rd.w <<= 1;
rd.w |= c;
cpu_io(); //5
op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a
op_write(OPMODE_DBR, aa.w, rd.l); //6
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/************************
*** 0x3e: rol addr,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aah,aal+xl ; io
[5 ] dbr,aa+x ; data low
[5a] dbr,aa+x+1 ; data high [1]
[6 ] dbr,aa+x+1 ; io
[7a] dbr,aa+x+1 ; data high [1]
[7 ] dbr,aa+x ; data low
*/
void bCPU::op_rol_addrxb() {
uint8 c = regs.p.c;
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
regs.p.c = !!(rd.l & 0x80);
rd.l <<= 1;
rd.l |= c;
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_rol_addrxw() {
uint16 c = regs.p.c;
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a
regs.p.c = !!(rd.w & 0x8000);
rd.w <<= 1;
rd.w |= c;
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/********************
*** 0x26: rol dp ***
********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
[4 ] 0,d+dp+1 ; io
[5a] 0,d+dp+1 ; data high [1]
[5 ] 0,d+dp ; data low
*/
void bCPU::op_rol_dpb() {
uint8 c = regs.p.c;
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
regs.p.c = !!(rd.l & 0x80);
rd.l <<= 1;
rd.l |= c;
cpu_io(); //4
op_write(OPMODE_DP, dp, rd.l); //5
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_rol_dpw() {
uint16 c = regs.p.c;
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
rd.h = op_read(OPMODE_DP, dp + 1); //3a
regs.p.c = !!(rd.w & 0x8000);
rd.w <<= 1;
rd.w |= c;
cpu_io(); //4
op_write(OPMODE_DP, dp + 1, rd.h); //5a
op_write(OPMODE_DP, dp, rd.l); //5
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/**********************
*** 0x36: rol dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high [1]
[5 ] 0,d+dp+x+1 ; io
[6a] 0,d+dp+x+1 ; data high [1]
[6 ] 0,d+dp+x ; data low
*/
void bCPU::op_rol_dpxb() {
uint8 c = regs.p.c;
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
regs.p.c = !!(rd.l & 0x80);
rd.l <<= 1;
rd.l |= c;
cpu_io(); //5
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_rol_dpxw() {
uint16 c = regs.p.c;
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
regs.p.c = !!(rd.w & 0x8000);
rd.w <<= 1;
rd.w |= c;
cpu_io(); //5
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/*****************
*** 0x6a: ror ***
*****************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; io
*/
void bCPU::op_rorb() {
uint8 c = (regs.p.c)?0x80:0;
cpu_io(); //2
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
regs.a.l |= c;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
void bCPU::op_rorw() {
uint16 c = (regs.p.c)?0x8000:0;
cpu_io(); //2
regs.p.c = regs.a.w & 1;
regs.a.w >>= 1;
regs.a.w |= c;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
/**********************
*** 0x6e: ror addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
[5 ] dbr,aa+1 ; io
[6a] dbr,aa+1 ; data high [1]
[6 ] dbr,aa ; data low
*/
void bCPU::op_ror_addrb() {
uint8 c = (regs.p.c)?0x80:0;
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
regs.p.c = rd.l & 1;
rd.l >>= 1;
rd.l |= c;
cpu_io(); //5
op_write(OPMODE_DBR, aa.w, rd.l); //6
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_ror_addrw() {
uint16 c = (regs.p.c)?0x8000:0;
aa.l = op_read(); //2
aa.h = op_read(); //3
rd.l = op_read(OPMODE_DBR, aa.w); //4
rd.h = op_read(OPMODE_DBR, aa.w + 1); //4a
regs.p.c = rd.w & 1;
rd.w >>= 1;
rd.w |= c;
cpu_io(); //5
op_write(OPMODE_DBR, aa.w + 1, rd.h); //6a
op_write(OPMODE_DBR, aa.w, rd.l); //6
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/************************
*** 0x7e: ror addr,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aah,aal+xl ; io
[5 ] dbr,aa+x ; data low
[5a] dbr,aa+x+1 ; data high [1]
[6 ] dbr,aa+x+1 ; io
[7a] dbr,aa+x+1 ; data high [1]
[7 ] dbr,aa+x ; data low
*/
void bCPU::op_ror_addrxb() {
uint8 c = (regs.p.c)?0x80:0;
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
regs.p.c = rd.l & 1;
rd.l >>= 1;
rd.l |= c;
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_ror_addrxw() {
uint16 c = (regs.p.c)?0x8000:0;
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w); //5
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1); //5a
regs.p.c = rd.w & 1;
rd.w >>= 1;
rd.w |= c;
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h); //7a
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l); //7
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/********************
*** 0x66: ror dp ***
********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
[4 ] 0,d+dp+1 ; io
[5a] 0,d+dp+1 ; data high [1]
[5 ] 0,d+dp ; data low
*/
void bCPU::op_ror_dpb() {
uint8 c = (regs.p.c)?0x80:0;
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
regs.p.c = rd.l & 1;
rd.l >>= 1;
rd.l |= c;
cpu_io(); //4
op_write(OPMODE_DP, dp, rd.l); //5
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_ror_dpw() {
uint16 c = (regs.p.c)?0x8000:0;
dp = op_read(); //2
cpu_c2(); //2a
rd.l = op_read(OPMODE_DP, dp); //3
rd.h = op_read(OPMODE_DP, dp + 1); //3a
regs.p.c = rd.w & 1;
rd.w >>= 1;
rd.w |= c;
cpu_io(); //4
op_write(OPMODE_DP, dp + 1, rd.h); //5a
op_write(OPMODE_DP, dp, rd.l); //5
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
/**********************
*** 0x76: ror dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high [1]
[5 ] 0,d+dp+x+1 ; io
[6a] 0,d+dp+x+1 ; data high [1]
[6 ] 0,d+dp+x ; data low
*/
void bCPU::op_ror_dpxb() {
uint8 c = (regs.p.c)?0x80:0;
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
regs.p.c = rd.l & 1;
rd.l >>= 1;
rd.l |= c;
cpu_io(); //5
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
void bCPU::op_ror_dpxw() {
uint16 c = (regs.p.c)?0x8000:0;
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
rd.l = op_read(OPMODE_DP, dp + regs.x.w); //4
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //4a
regs.p.c = rd.w & 1;
rd.w >>= 1;
rd.w |= c;
cpu_io(); //5
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h); //6a
op_write(OPMODE_DP, dp + regs.x.w, rd.l); //6
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}

View File

@ -1,387 +0,0 @@
/**********************
*** 0x8d: sta addr ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] dbr,aa ; data low
[4a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_sta_addrb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
op_write(OPMODE_DBR, aa.w, regs.a.l); //4
}
void bCPU::op_sta_addrw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
op_write(OPMODE_DBR, aa.w, regs.a.l); //4
op_write(OPMODE_DBR, aa.w + 1, regs.a.h); //4a
}
/************************
*** 0x9d: sta addr,x ***
************************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+xl ; io [4]
[4 ] dbr,aa+x ; data low
[4a] dbr,aa+x+1 ; data high [1]
*/
void bCPU::op_sta_addrxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
op_write(OPMODE_DBR, aa.w + regs.x.w, regs.a.l); //4
}
void bCPU::op_sta_addrxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.x.w); //3a
op_write(OPMODE_DBR, aa.w + regs.x.w, regs.a.l); //4
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, regs.a.h); //4a
}
/********************
*** 0x85: sta dp ***
********************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; data low
[3a] 0,d+dp+1 ; data high [1]
*/
void bCPU::op_sta_dpb() {
dp = op_read(); //2
cpu_c2(); //2a
op_write(OPMODE_DP, dp, regs.a.l); //3
}
void bCPU::op_sta_dpw() {
dp = op_read(); //2
cpu_c2(); //2a
op_write(OPMODE_DP, dp, regs.a.l); //3
op_write(OPMODE_DP, dp + 1, regs.a.h); //3a
}
/**********************
*** 0x92: sta (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] dbr,aa ; data low
[5a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_sta_idpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
op_write(OPMODE_DBR, aa.w, regs.a.l); //5
}
void bCPU::op_sta_idpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
op_write(OPMODE_DBR, aa.w, regs.a.l); //5
op_write(OPMODE_DBR, aa.w + 1, regs.a.h); //5
}
/**********************
*** 0x87: sta [dp] ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa ; data low
[6a] aab,aa+1 ; data high [1]
*/
void bCPU::op_sta_ildpb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
op_write(OPMODE_LONG, aa.d, regs.a.l); //6
}
void bCPU::op_sta_ildpw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
op_write(OPMODE_LONG, aa.d, regs.a.l); //6
op_write(OPMODE_LONG, aa.d + 1, regs.a.h); //6a
}
/**********************
*** 0x8f: sta long ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa ; data low
[5a] aab,aa+1 ; data high
*/
void bCPU::op_sta_longb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
op_write(OPMODE_LONG, aa.d, regs.a.l); //5
}
void bCPU::op_sta_longw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
op_write(OPMODE_LONG, aa.d, regs.a.l); //5
op_write(OPMODE_LONG, aa.d + 1, regs.a.h); //5a
}
/************************
*** 0x9f: sta long,x ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[4 ] pbr,pc+3 ; aab
[5 ] aab,aa+x ; data low
[5a] aab,aa+x+1 ; data high
*/
void bCPU::op_sta_longxb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l); //5
}
void bCPU::op_sta_longxw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
aa.b = op_read(); //4
op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l); //5
op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h); //5a
}
/************************
*** 0x99: sta addr,y ***
************************
cycles:
[1 ] pbr,pc ; operand
[2 ] pbr,pc+1 ; aal
[3 ] pbr,pc+2 ; aah
[3a] dbr,aah,aal+yl ; io [4]
[4 ] dbr,aa+y ; data low
[4a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_sta_addryb() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //4
}
void bCPU::op_sta_addryw() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_c4(aa.w, aa.w + regs.y.w); //3a
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //4
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); //4a
}
/**********************
*** 0x95: sta dp,x ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; data low
[4a] 0,d+dp+x+1 ; data high
*/
void bCPU::op_sta_dpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
op_write(OPMODE_DP, dp + regs.x.w, regs.a.l); //4
}
void bCPU::op_sta_dpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
op_write(OPMODE_DP, dp + regs.x.w, regs.a.l); //4
op_write(OPMODE_DP, dp + regs.x.w + 1, regs.a.h); //4a
}
/************************
*** 0x81: sta (dp,x) ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] pbr,pc+1 ; io
[4 ] 0,d+dp+x ; aal
[5 ] 0,d+dp+x+1 ; aah
[6 ] dbr,aa ; data low
[6a] dbr,aa+1 ; data high [1]
*/
void bCPU::op_sta_idpxb() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
op_write(OPMODE_DBR, aa.w, regs.a.l); //6
}
void bCPU::op_sta_idpxw() {
dp = op_read(); //2
cpu_c2(); //2a
cpu_io(); //3
aa.l = op_read(OPMODE_DP, dp + regs.x.w); //4
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1); //5
op_write(OPMODE_DBR, aa.w, regs.a.l); //6
op_write(OPMODE_DBR, aa.w + 1, regs.a.h); //6a
}
/************************
*** 0x91: sta (dp),y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[4a] dbr,aah,aal+yl ; io [4]
[5 ] dbr,aa+y ; data low
[5a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_sta_idpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //5
}
void bCPU::op_sta_idpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
cpu_c4(aa.w, aa.w + regs.y.w); //4a
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //5
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); //5a
}
/************************
*** 0x97: sta [dp],y ***
************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io [2]
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,d+dp+2 ; aab
[6 ] aab,aa+y ; data low
[6a] aab,aa+y+1 ; data high [1]
*/
void bCPU::op_sta_ildpyb() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l); //6
}
void bCPU::op_sta_ildpyw() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
aa.b = op_read(OPMODE_DP, dp + 2); //5
op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l); //6
op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h); //6a
}
/**********************
*** 0x83: sta sr,s ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; data low
[4a] 0,s+sp+1 ; data high [1]
*/
void bCPU::op_sta_srb() {
sp = op_read(); //2
cpu_io(); //3
op_write(OPMODE_SP, sp, regs.a.l); //4
}
void bCPU::op_sta_srw() {
sp = op_read(); //2
cpu_io(); //3
op_write(OPMODE_SP, sp, regs.a.l); //4
op_write(OPMODE_SP, sp + 1, regs.a.h); //4a
}
/**************************
*** 0x93: sta (sr,s),y ***
**************************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; sp
[3 ] pbr,pc+1 ; io
[4 ] 0,s+sp ; aal
[5 ] 0,s+sp+1 ; aah
[6 ] 0,s+sp+1 ; io
[7 ] dbr,aa+y ; data low
[7a] dbr,aa+y+1 ; data high [1]
*/
void bCPU::op_sta_isryb() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //7
}
void bCPU::op_sta_isryw() {
sp = op_read(); //2
cpu_io(); //3
aa.l = op_read(OPMODE_SP, sp); //4
aa.h = op_read(OPMODE_SP, sp + 1); //5
cpu_io(); //6
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l); //7
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h); //7a
}

View File

@ -1,317 +0,0 @@
/*****************
*** 0x48: pha ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3a] 0,s ; reg high [1]
[3 ] 0,s-1 ; reg low
*/
void bCPU::op_phab() {
cpu_io(); //2
stack_write(regs.a.l); //3
}
void bCPU::op_phaw() {
cpu_io(); //2
stack_write(regs.a.h); //3a
stack_write(regs.a.l); //3
}
/*****************
*** 0x8b: phb ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] 0,s-1 ; dbr
*/
void bCPU::op_phb() {
cpu_io(); //2
stack_write(regs.db); //3
}
/*****************
*** 0x0b: phd ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3a] 0,s ; reg high
[3 ] 0,s-1 ; reg low
*/
void bCPU::op_phd() {
cpu_io(); //2
stack_write(regs.d.h); //3a
stack_write(regs.d.l); //3
}
/*****************
*** 0x4b: phk ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] 0,s-1 ; pcb
*/
void bCPU::op_phk() {
cpu_io(); //2
stack_write(regs.pc.b); //3
}
/*****************
*** 0x08: php ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] 0,s-1 ; reg low
*/
void bCPU::op_php() {
cpu_io(); //2
stack_write(regs.p); //3
}
/*****************
*** 0xda: phx ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3a] 0,s ; reg high [1]
[3 ] 0,s-1 ; reg low
*/
void bCPU::op_phxb() {
cpu_io(); //2
stack_write(regs.x.l); //3
}
void bCPU::op_phxw() {
cpu_io(); //2
stack_write(regs.x.h); //3a
stack_write(regs.x.l); //3
}
/*****************
*** 0x5a: phy ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3a] 0,s ; reg high [1]
[3 ] 0,s-1 ; reg low
*/
void bCPU::op_phyb() {
cpu_io(); //2
stack_write(regs.y.l); //3
}
void bCPU::op_phyw() {
cpu_io(); //2
stack_write(regs.y.h); //3a
stack_write(regs.y.l); //3
}
/*****************
*** 0x68: pla ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,s+1 ; reg low
[4a] 0,s+2 ; reg high [1]
*/
void bCPU::op_plab() {
cpu_io(); //2
cpu_io(); //3
regs.a.l = stack_read(); //4
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
void bCPU::op_plaw() {
cpu_io(); //2
cpu_io(); //3
regs.a.l = stack_read(); //4
regs.a.h = stack_read(); //4a
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
/*****************
*** 0xab: plb ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,s+1 ; reg low
*/
void bCPU::op_plb() {
cpu_io(); //2
cpu_io(); //3
regs.db = stack_read(); //4
regs.p.n = !!(regs.db & 0x80);
regs.p.z = (regs.db == 0);
}
/*****************
*** 0x2b: pld ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,s+1 ; reg low
[4a] 0,s+2 ; reg high
*/
void bCPU::op_pld() {
cpu_io(); //2
cpu_io(); //3
regs.d.l = stack_read(); //4
regs.d.h = stack_read(); //4a
regs.p.n = !!(regs.d.w & 0x8000);
regs.p.z = (regs.d.w == 0);
}
/*****************
*** 0x28: plp ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,s+1 ; reg low
*/
void bCPU::op_plp() {
cpu_io(); //2
cpu_io(); //3
regs.p = stack_read(); //4
if(regs.e) {
regs.p |= 0x30;
} else {
switch((regs.p >> 4) & 3) {
case 0:optbl = optbl_mx;break;
case 1:optbl = optbl_mX;break;
case 2:optbl = optbl_Mx;break;
case 3:optbl = optbl_MX;break;
}
}
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
}
/*****************
*** 0xfa: plx ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,s+1 ; reg low
[4a] 0,s+2 ; reg high [1]
*/
void bCPU::op_plxb() {
cpu_io(); //2
cpu_io(); //3
regs.x.l = stack_read(); //4
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
}
void bCPU::op_plxw() {
cpu_io(); //2
cpu_io(); //3
regs.x.l = stack_read(); //4
regs.x.h = stack_read(); //4a
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
/*****************
*** 0x7a: ply ***
*****************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; io
[3 ] pbr,pc+1 ; io
[4 ] 0,s+1 ; reg low
[4a] 0,s+2 ; reg high [1]
*/
void bCPU::op_plyb() {
cpu_io(); //2
cpu_io(); //3
regs.y.l = stack_read(); //4
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
}
void bCPU::op_plyw() {
cpu_io(); //2
cpu_io(); //3
regs.y.l = stack_read(); //4
regs.y.h = stack_read(); //4a
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
/**********************
*** 0xf4: pea addr ***
**********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; aal
[3] pbr,pc+2 ; aah
[4] 0,s ; aah
[5] 0,s-1 ; aal
*/
void bCPU::op_pea() {
aa.l = op_read(); //2
aa.h = op_read(); //3
stack_write(aa.h); //4
stack_write(aa.l); //5
}
/**********************
*** 0xd4: pei (dp) ***
**********************
cycles:
[1 ] pbr,pc ; opcode
[2 ] pbr,pc+1 ; dp
[2a] pbr,pc+1 ; io
[3 ] 0,d+dp ; aal
[4 ] 0,d+dp+1 ; aah
[5 ] 0,s ; aah
[6 ] 0,s-1 ; aal
*/
void bCPU::op_pei() {
dp = op_read(); //2
cpu_c2(); //2a
aa.l = op_read(OPMODE_DP, dp); //3
aa.h = op_read(OPMODE_DP, dp + 1); //4
stack_write(aa.h); //5
stack_write(aa.l); //6
}
/**********************
*** 0x62: per addr ***
**********************
cycles:
[1] pbr,pc ; opcode
[2] pbr,pc+1 ; offset low
[3] pbr,pc+2 ; offset high
[4] pbr,pc+2 ; io
[5] 0,s ; pch+offset
[6] 0,s-1 ; pcl+offset
*/
void bCPU::op_per() {
aa.l = op_read(); //2
aa.h = op_read(); //3
cpu_io(); //4
rd.w = regs.pc.d + (int16)aa.w;
stack_write(rd.h); //5
stack_write(rd.l); //6
}

View File

@ -0,0 +1,340 @@
void bCPU::op_sta_addr() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
op_write(OPMODE_DBR, aa.w, regs.a.w);
if(regs.p.m)return;
l4:
op_write(OPMODE_DBR, aa.w + 1, regs.a.w >> 8);
}
void bCPU::op_stx_addr() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
op_write(OPMODE_DBR, aa.w, regs.x.w);
if(regs.p.x)return;
l4:
op_write(OPMODE_DBR, aa.w + 1, regs.x.w >> 8);
}
void bCPU::op_sty_addr() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
op_write(OPMODE_DBR, aa.w, regs.y.w);
if(regs.p.x)return;
l4:
op_write(OPMODE_DBR, aa.w + 1, regs.y.w >> 8);
}
void bCPU::op_stz_addr() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
op_write(OPMODE_DBR, aa.w, 0x0000);
if(regs.p.m)return;
l4:
op_write(OPMODE_DBR, aa.w + 1, 0x0000 >> 8);
}
void bCPU::op_sta_addrx() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
cpu_c4(aa.w, aa.w + regs.x.w);
l4:
op_write(OPMODE_DBR, aa.w + regs.x.w, regs.a.w);
if(regs.p.m)return;
l5:
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, regs.a.w >> 8);
}
void bCPU::op_stz_addrx() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
cpu_c4(aa.w, aa.w + regs.x.w);
l4:
op_write(OPMODE_DBR, aa.w + regs.x.w, 0x0000);
if(regs.p.m)return;
l5:
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, 0x0000 >> 8);
}
void bCPU::op_sta_addry() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
cpu_c4(aa.w, aa.w + regs.y.w);
l4:
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l);
if(regs.p.m)return;
l5:
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h);
}
void bCPU::op_sta_long() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
aa.b = op_read();
l4:
op_write(OPMODE_LONG, aa.d, regs.a.l);
if(regs.p.m)return;
l5:
op_write(OPMODE_LONG, aa.d + 1, regs.a.h);
}
void bCPU::op_sta_longx() {
l1:
aa.l = op_read();
l2:
aa.h = op_read();
l3:
aa.b = op_read();
l4:
op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l);
if(regs.p.m)return;
l5:
op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h);
}
void bCPU::op_sta_dp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
op_write(OPMODE_DP, dp, regs.a.w);
if(regs.p.m)return;
l4:
op_write(OPMODE_DP, dp + 1, regs.a.w >> 8);
}
void bCPU::op_stx_dp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
op_write(OPMODE_DP, dp, regs.x.w);
if(regs.p.x)return;
l4:
op_write(OPMODE_DP, dp + 1, regs.x.w >> 8);
}
void bCPU::op_sty_dp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
op_write(OPMODE_DP, dp, regs.y.w);
if(regs.p.x)return;
l4:
op_write(OPMODE_DP, dp + 1, regs.y.w >> 8);
}
void bCPU::op_stz_dp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
op_write(OPMODE_DP, dp, 0x0000);
if(regs.p.m)return;
l4:
op_write(OPMODE_DP, dp + 1, 0x0000 >> 8);
}
void bCPU::op_sta_dpx() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
cpu_io();
l4:
op_write(OPMODE_DP, dp + regs.x.w, regs.a.w);
if(regs.p.m)return;
l5:
op_write(OPMODE_DP, dp + regs.x.w + 1, regs.a.w >> 8);
}
void bCPU::op_sty_dpx() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
cpu_io();
l4:
op_write(OPMODE_DP, dp + regs.x.w, regs.y.w);
if(regs.p.x)return;
l5:
op_write(OPMODE_DP, dp + regs.x.w + 1, regs.y.w >> 8);
}
void bCPU::op_stz_dpx() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
cpu_io();
l4:
op_write(OPMODE_DP, dp + regs.x.w, 0x0000);
if(regs.p.m)return;
l5:
op_write(OPMODE_DP, dp + regs.x.w + 1, 0x0000 >> 8);
}
void bCPU::op_stx_dpy() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
cpu_io();
l4:
op_write(OPMODE_DP, dp + regs.y.w, regs.x.l);
if(regs.p.x)return;
l5:
op_write(OPMODE_DP, dp + regs.y.w + 1, regs.x.h);
}
void bCPU::op_sta_idp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
aa.l = op_read(OPMODE_DP, dp);
l4:
aa.h = op_read(OPMODE_DP, dp + 1);
l5:
op_write(OPMODE_DBR, aa.w, regs.a.l);
if(regs.p.m)return;
l6:
op_write(OPMODE_DBR, aa.w + 1, regs.a.h);
}
void bCPU::op_sta_ildp() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
aa.l = op_read(OPMODE_DP, dp);
l4:
aa.h = op_read(OPMODE_DP, dp + 1);
l5:
aa.b = op_read(OPMODE_DP, dp + 2);
l6:
op_write(OPMODE_LONG, aa.d, regs.a.l);
if(regs.p.m)return;
l7:
op_write(OPMODE_LONG, aa.d + 1, regs.a.h);
}
void bCPU::op_sta_idpx() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
cpu_io();
l4:
aa.l = op_read(OPMODE_DP, dp + regs.x.w);
l5:
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
l6:
op_write(OPMODE_DBR, aa.w, regs.a.l);
if(regs.p.m)return;
l7:
op_write(OPMODE_DBR, aa.w + 1, regs.a.h);
}
void bCPU::op_sta_idpy() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
aa.l = op_read(OPMODE_DP, dp);
l4:
aa.h = op_read(OPMODE_DP, dp + 1);
l5:
cpu_c4(aa.w, aa.w + regs.y.w);
l6:
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l);
if(regs.p.m)return;
l7:
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h);
}
void bCPU::op_sta_ildpy() {
l1:
dp = op_read();
l2:
cpu_c2();
l3:
aa.l = op_read(OPMODE_DP, dp);
l4:
aa.h = op_read(OPMODE_DP, dp + 1);
l5:
aa.b = op_read(OPMODE_DP, dp + 2);
l6:
op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l);
if(regs.p.m)return;
l7:
op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h);
}
void bCPU::op_sta_sr() {
l1:
sp = op_read();
l2:
cpu_io();
l3:
op_write(OPMODE_SP, sp, regs.a.l);
if(regs.p.m)return;
l4:
op_write(OPMODE_SP, sp + 1, regs.a.h);
}
void bCPU::op_sta_isry() {
l1:
sp = op_read();
l2:
cpu_io();
l3:
aa.l = op_read(OPMODE_SP, sp);
l4:
aa.h = op_read(OPMODE_SP, sp + 1);
l5:
cpu_io();
l6:
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l);
if(regs.p.m)return;
l7:
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h);
}

295
src/cpu/bcpu/bcpu_opfn.cpp Normal file
View File

@ -0,0 +1,295 @@
//op_read
inline void bCPU::op_adc_b() {
int32 r = regs.a.l + rd.l + regs.p.c;
//bcd
if(regs.p.d) {
if(((r ) & 15) > 9)r += 6;
if(((r >> 4) & 15) > 9)r += 6 << 4;
}
regs.p.n = !!(r & 0x80);
regs.p.v = !!(~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r > 0xff);
regs.a.l = r;
}
inline void bCPU::op_adc_w() {
int32 r = regs.a.w + rd.w + regs.p.c;
//bcd
if(regs.p.d) {
if(((r ) & 15) > 9)r += 6;
if(((r >> 4) & 15) > 9)r += 6 << 4;
if(((r >> 8) & 15) > 9)r += 6 << 8;
if(((r >> 12) & 15) > 9)r += 6 << 12;
}
regs.p.n = !!(r & 0x8000);
regs.p.v = !!(~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
regs.p.z = ((uint16)r == 0);
regs.p.c = (r > 0xffff);
regs.a.w = r;
}
inline void bCPU::op_and_b() {
regs.a.l &= rd.l;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
inline void bCPU::op_and_w() {
regs.a.w &= rd.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
inline void bCPU::op_bit_b() {
regs.p.n = !!(rd.l & 0x80);
regs.p.v = !!(rd.l & 0x40);
regs.p.z = ((rd.l & regs.a.l) == 0);
}
inline void bCPU::op_bit_w() {
regs.p.n = !!(rd.w & 0x8000);
regs.p.v = !!(rd.w & 0x4000);
regs.p.z = ((rd.w & regs.a.w) == 0);
}
inline void bCPU::op_cmp_b() {
int32 r = regs.a.l - rd.l;
regs.p.n = !!(r & 0x80);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r >= 0);
}
inline void bCPU::op_cmp_w() {
int32 r = regs.a.w - rd.w;
regs.p.n = !!(r & 0x8000);
regs.p.z = ((uint16)r == 0);
regs.p.c = (r >= 0);
}
inline void bCPU::op_cpx_b() {
int32 r = regs.x.l - rd.l;
regs.p.n = !!(r & 0x80);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r >= 0);
}
inline void bCPU::op_cpx_w() {
int32 r = regs.x.w - rd.w;
regs.p.n = !!(r & 0x8000);
regs.p.z = ((uint16)r == 0);
regs.p.c = (r >= 0);
}
inline void bCPU::op_cpy_b() {
int32 r = regs.y.l - rd.l;
regs.p.n = !!(r & 0x80);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r >= 0);
}
inline void bCPU::op_cpy_w() {
int32 r = regs.y.w - rd.w;
regs.p.n = !!(r & 0x8000);
regs.p.z = ((uint16)r == 0);
regs.p.c = (r >= 0);
}
inline void bCPU::op_eor_b() {
regs.a.l ^= rd.l;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
inline void bCPU::op_eor_w() {
regs.a.w ^= rd.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
inline void bCPU::op_lda_b() {
regs.a.l = rd.l;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
inline void bCPU::op_lda_w() {
regs.a.w = rd.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
inline void bCPU::op_ldx_b() {
regs.x.l = rd.l;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
}
inline void bCPU::op_ldx_w() {
regs.x.w = rd.w;
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
inline void bCPU::op_ldy_b() {
regs.y.l = rd.l;
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
}
inline void bCPU::op_ldy_w() {
regs.y.w = rd.w;
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
inline void bCPU::op_ora_b() {
regs.a.l |= rd.l;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
inline void bCPU::op_ora_w() {
regs.a.w |= rd.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
inline void bCPU::op_sbc_b() {
int32 r = regs.a.l - rd.l - !regs.p.c;
//bcd
if(regs.p.d) {
if(((r ) & 15) > 9)r -= 6;
if(((r >> 4) & 15) > 9)r -= 6 << 4;
}
regs.p.n = !!(r & 0x80);
regs.p.v = !!((regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
regs.p.z = ((byte)r == 0);
regs.p.c = (r >= 0);
regs.a.l = r;
}
inline void bCPU::op_sbc_w() {
int32 r = regs.a.w - rd.w - !regs.p.c;
//bcd
if(regs.p.d) {
if(((r ) & 15) > 9)r -= 6;
if(((r >> 4) & 15) > 9)r -= 6 << 4;
if(((r >> 8) & 15) > 9)r -= 6 << 8;
if(((r >> 12) & 15) > 9)r -= 6 << 12;
}
regs.p.n = !!(r & 0x8000);
regs.p.v = !!((regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
regs.p.z = ((word)r == 0);
regs.p.c = (r >= 0);
regs.a.w = r;
}
//op_rmw
inline void bCPU::op_inc_b() {
rd.l++;
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void bCPU::op_inc_w() {
rd.w++;
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void bCPU::op_dec_b() {
rd.l--;
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void bCPU::op_dec_w() {
rd.w--;
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void bCPU::op_asl_b() {
regs.p.c = !!(rd.l & 0x80);
rd.l <<= 1;
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void bCPU::op_asl_w() {
regs.p.c = !!(rd.w & 0x8000);
rd.w <<= 1;
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void bCPU::op_lsr_b() {
regs.p.c = rd.l & 1;
rd.l >>= 1;
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void bCPU::op_lsr_w() {
regs.p.c = rd.w & 1;
rd.w >>= 1;
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void bCPU::op_rol_b() {
uint16 c = regs.p.c;
regs.p.c = !!(rd.l & 0x80);
rd.l <<= 1;
rd.l |= c;
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void bCPU::op_rol_w() {
uint16 c = regs.p.c;
regs.p.c = !!(rd.w & 0x8000);
rd.w <<= 1;
rd.w |= c;
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void bCPU::op_ror_b() {
uint16 c = (regs.p.c)?0x80:0;
regs.p.c = rd.l & 1;
rd.l >>= 1;
rd.l |= c;
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void bCPU::op_ror_w() {
uint16 c = (regs.p.c)?0x8000:0;
regs.p.c = rd.w & 1;
rd.w >>= 1;
rd.w |= c;
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void bCPU::op_trb_b() {
regs.p.z = ((rd.l & regs.a.l) == 0);
rd.l &= ~regs.a.l;
}
inline void bCPU::op_trb_w() {
regs.p.z = ((rd.w & regs.a.w) == 0);
rd.w &= ~regs.a.w;
}
inline void bCPU::op_tsb_b() {
regs.p.z = ((rd.l & regs.a.l) == 0);
rd.l |= regs.a.l;
}
inline void bCPU::op_tsb_w() {
regs.p.z = ((rd.w & regs.a.w) == 0);
rd.w |= regs.a.w;
}

View File

@ -0,0 +1,256 @@
optbl[0x69] = &bCPU::op_adc_const;
optbl[0x29] = &bCPU::op_and_const;
optbl[0xc9] = &bCPU::op_cmp_const;
optbl[0xe0] = &bCPU::op_cpx_const;
optbl[0xc0] = &bCPU::op_cpy_const;
optbl[0x49] = &bCPU::op_eor_const;
optbl[0xa9] = &bCPU::op_lda_const;
optbl[0xa2] = &bCPU::op_ldx_const;
optbl[0xa0] = &bCPU::op_ldy_const;
optbl[0x09] = &bCPU::op_ora_const;
optbl[0xe9] = &bCPU::op_sbc_const;
optbl[0x6d] = &bCPU::op_adc_addr;
optbl[0x2d] = &bCPU::op_and_addr;
optbl[0x2c] = &bCPU::op_bit_addr;
optbl[0xcd] = &bCPU::op_cmp_addr;
optbl[0xec] = &bCPU::op_cpx_addr;
optbl[0xcc] = &bCPU::op_cpy_addr;
optbl[0x4d] = &bCPU::op_eor_addr;
optbl[0xad] = &bCPU::op_lda_addr;
optbl[0xae] = &bCPU::op_ldx_addr;
optbl[0xac] = &bCPU::op_ldy_addr;
optbl[0x0d] = &bCPU::op_ora_addr;
optbl[0xed] = &bCPU::op_sbc_addr;
optbl[0x7d] = &bCPU::op_adc_addrx;
optbl[0x3d] = &bCPU::op_and_addrx;
optbl[0x3c] = &bCPU::op_bit_addrx;
optbl[0xdd] = &bCPU::op_cmp_addrx;
optbl[0x5d] = &bCPU::op_eor_addrx;
optbl[0xbd] = &bCPU::op_lda_addrx;
optbl[0xbc] = &bCPU::op_ldy_addrx;
optbl[0x1d] = &bCPU::op_ora_addrx;
optbl[0xfd] = &bCPU::op_sbc_addrx;
optbl[0x79] = &bCPU::op_adc_addry;
optbl[0x39] = &bCPU::op_and_addry;
optbl[0xd9] = &bCPU::op_cmp_addry;
optbl[0x59] = &bCPU::op_eor_addry;
optbl[0xb9] = &bCPU::op_lda_addry;
optbl[0xbe] = &bCPU::op_ldx_addry;
optbl[0x19] = &bCPU::op_ora_addry;
optbl[0xf9] = &bCPU::op_sbc_addry;
optbl[0x6f] = &bCPU::op_adc_long;
optbl[0x2f] = &bCPU::op_and_long;
optbl[0xcf] = &bCPU::op_cmp_long;
optbl[0x4f] = &bCPU::op_eor_long;
optbl[0xaf] = &bCPU::op_lda_long;
optbl[0x0f] = &bCPU::op_ora_long;
optbl[0xef] = &bCPU::op_sbc_long;
optbl[0x7f] = &bCPU::op_adc_longx;
optbl[0x3f] = &bCPU::op_and_longx;
optbl[0xdf] = &bCPU::op_cmp_longx;
optbl[0x5f] = &bCPU::op_eor_longx;
optbl[0xbf] = &bCPU::op_lda_longx;
optbl[0x1f] = &bCPU::op_ora_longx;
optbl[0xff] = &bCPU::op_sbc_longx;
optbl[0x65] = &bCPU::op_adc_dp;
optbl[0x25] = &bCPU::op_and_dp;
optbl[0x24] = &bCPU::op_bit_dp;
optbl[0xc5] = &bCPU::op_cmp_dp;
optbl[0xe4] = &bCPU::op_cpx_dp;
optbl[0xc4] = &bCPU::op_cpy_dp;
optbl[0x45] = &bCPU::op_eor_dp;
optbl[0xa5] = &bCPU::op_lda_dp;
optbl[0xa6] = &bCPU::op_ldx_dp;
optbl[0xa4] = &bCPU::op_ldy_dp;
optbl[0x05] = &bCPU::op_ora_dp;
optbl[0xe5] = &bCPU::op_sbc_dp;
optbl[0x75] = &bCPU::op_adc_dpx;
optbl[0x35] = &bCPU::op_and_dpx;
optbl[0x34] = &bCPU::op_bit_dpx;
optbl[0xd5] = &bCPU::op_cmp_dpx;
optbl[0x55] = &bCPU::op_eor_dpx;
optbl[0xb5] = &bCPU::op_lda_dpx;
optbl[0xb4] = &bCPU::op_ldy_dpx;
optbl[0x15] = &bCPU::op_ora_dpx;
optbl[0xf5] = &bCPU::op_sbc_dpx;
optbl[0xb6] = &bCPU::op_ldx_dpy;
optbl[0x72] = &bCPU::op_adc_idp;
optbl[0x32] = &bCPU::op_and_idp;
optbl[0xd2] = &bCPU::op_cmp_idp;
optbl[0x52] = &bCPU::op_eor_idp;
optbl[0xb2] = &bCPU::op_lda_idp;
optbl[0x12] = &bCPU::op_ora_idp;
optbl[0xf2] = &bCPU::op_sbc_idp;
optbl[0x61] = &bCPU::op_adc_idpx;
optbl[0x21] = &bCPU::op_and_idpx;
optbl[0xc1] = &bCPU::op_cmp_idpx;
optbl[0x41] = &bCPU::op_eor_idpx;
optbl[0xa1] = &bCPU::op_lda_idpx;
optbl[0x01] = &bCPU::op_ora_idpx;
optbl[0xe1] = &bCPU::op_sbc_idpx;
optbl[0x71] = &bCPU::op_adc_idpy;
optbl[0x31] = &bCPU::op_and_idpy;
optbl[0xd1] = &bCPU::op_cmp_idpy;
optbl[0x51] = &bCPU::op_eor_idpy;
optbl[0xb1] = &bCPU::op_lda_idpy;
optbl[0x11] = &bCPU::op_ora_idpy;
optbl[0xf1] = &bCPU::op_sbc_idpy;
optbl[0x67] = &bCPU::op_adc_ildp;
optbl[0x27] = &bCPU::op_and_ildp;
optbl[0xc7] = &bCPU::op_cmp_ildp;
optbl[0x47] = &bCPU::op_eor_ildp;
optbl[0xa7] = &bCPU::op_lda_ildp;
optbl[0x07] = &bCPU::op_ora_ildp;
optbl[0xe7] = &bCPU::op_sbc_ildp;
optbl[0x77] = &bCPU::op_adc_ildpy;
optbl[0x37] = &bCPU::op_and_ildpy;
optbl[0xd7] = &bCPU::op_cmp_ildpy;
optbl[0x57] = &bCPU::op_eor_ildpy;
optbl[0xb7] = &bCPU::op_lda_ildpy;
optbl[0x17] = &bCPU::op_ora_ildpy;
optbl[0xf7] = &bCPU::op_sbc_ildpy;
optbl[0x63] = &bCPU::op_adc_sr;
optbl[0x23] = &bCPU::op_and_sr;
optbl[0xc3] = &bCPU::op_cmp_sr;
optbl[0x43] = &bCPU::op_eor_sr;
optbl[0xa3] = &bCPU::op_lda_sr;
optbl[0x03] = &bCPU::op_ora_sr;
optbl[0xe3] = &bCPU::op_sbc_sr;
optbl[0x73] = &bCPU::op_adc_isry;
optbl[0x33] = &bCPU::op_and_isry;
optbl[0xd3] = &bCPU::op_cmp_isry;
optbl[0x53] = &bCPU::op_eor_isry;
optbl[0xb3] = &bCPU::op_lda_isry;
optbl[0x13] = &bCPU::op_ora_isry;
optbl[0xf3] = &bCPU::op_sbc_isry;
optbl[0x89] = &bCPU::op_bit_const;
optbl[0x1a] = &bCPU::op_inc;
optbl[0xe8] = &bCPU::op_inx;
optbl[0xc8] = &bCPU::op_iny;
optbl[0x3a] = &bCPU::op_dec;
optbl[0xca] = &bCPU::op_dex;
optbl[0x88] = &bCPU::op_dey;
optbl[0x0a] = &bCPU::op_asl;
optbl[0x4a] = &bCPU::op_lsr;
optbl[0x2a] = &bCPU::op_rol;
optbl[0x6a] = &bCPU::op_ror;
optbl[0xee] = &bCPU::op_inc_addr;
optbl[0xce] = &bCPU::op_dec_addr;
optbl[0x0e] = &bCPU::op_asl_addr;
optbl[0x4e] = &bCPU::op_lsr_addr;
optbl[0x2e] = &bCPU::op_rol_addr;
optbl[0x6e] = &bCPU::op_ror_addr;
optbl[0x1c] = &bCPU::op_trb_addr;
optbl[0x0c] = &bCPU::op_tsb_addr;
optbl[0xfe] = &bCPU::op_inc_addrx;
optbl[0xde] = &bCPU::op_dec_addrx;
optbl[0x1e] = &bCPU::op_asl_addrx;
optbl[0x5e] = &bCPU::op_lsr_addrx;
optbl[0x3e] = &bCPU::op_rol_addrx;
optbl[0x7e] = &bCPU::op_ror_addrx;
optbl[0xe6] = &bCPU::op_inc_dp;
optbl[0xc6] = &bCPU::op_dec_dp;
optbl[0x06] = &bCPU::op_asl_dp;
optbl[0x46] = &bCPU::op_lsr_dp;
optbl[0x26] = &bCPU::op_rol_dp;
optbl[0x66] = &bCPU::op_ror_dp;
optbl[0x14] = &bCPU::op_trb_dp;
optbl[0x04] = &bCPU::op_tsb_dp;
optbl[0xf6] = &bCPU::op_inc_dpx;
optbl[0xd6] = &bCPU::op_dec_dpx;
optbl[0x16] = &bCPU::op_asl_dpx;
optbl[0x56] = &bCPU::op_lsr_dpx;
optbl[0x36] = &bCPU::op_rol_dpx;
optbl[0x76] = &bCPU::op_ror_dpx;
optbl[0x8d] = &bCPU::op_sta_addr;
optbl[0x8e] = &bCPU::op_stx_addr;
optbl[0x8c] = &bCPU::op_sty_addr;
optbl[0x9c] = &bCPU::op_stz_addr;
optbl[0x9d] = &bCPU::op_sta_addrx;
optbl[0x9e] = &bCPU::op_stz_addrx;
optbl[0x99] = &bCPU::op_sta_addry;
optbl[0x8f] = &bCPU::op_sta_long;
optbl[0x9f] = &bCPU::op_sta_longx;
optbl[0x85] = &bCPU::op_sta_dp;
optbl[0x86] = &bCPU::op_stx_dp;
optbl[0x84] = &bCPU::op_sty_dp;
optbl[0x64] = &bCPU::op_stz_dp;
optbl[0x95] = &bCPU::op_sta_dpx;
optbl[0x94] = &bCPU::op_sty_dpx;
optbl[0x74] = &bCPU::op_stz_dpx;
optbl[0x96] = &bCPU::op_stx_dpy;
optbl[0x92] = &bCPU::op_sta_idp;
optbl[0x87] = &bCPU::op_sta_ildp;
optbl[0x81] = &bCPU::op_sta_idpx;
optbl[0x91] = &bCPU::op_sta_idpy;
optbl[0x97] = &bCPU::op_sta_ildpy;
optbl[0x83] = &bCPU::op_sta_sr;
optbl[0x93] = &bCPU::op_sta_isry;
optbl[0x80] = &bCPU::op_bra;
optbl[0x90] = &bCPU::op_bcc;
optbl[0xb0] = &bCPU::op_bcs;
optbl[0xd0] = &bCPU::op_bne;
optbl[0xf0] = &bCPU::op_beq;
optbl[0x10] = &bCPU::op_bpl;
optbl[0x30] = &bCPU::op_bmi;
optbl[0x50] = &bCPU::op_bvc;
optbl[0x70] = &bCPU::op_bvs;
optbl[0x82] = &bCPU::op_brl;
optbl[0x4c] = &bCPU::op_jmp_addr;
optbl[0x5c] = &bCPU::op_jmp_long;
optbl[0x6c] = &bCPU::op_jmp_iaddr;
optbl[0x7c] = &bCPU::op_jmp_iaddrx;
optbl[0xdc] = &bCPU::op_jmp_iladdr;
optbl[0x20] = &bCPU::op_jsr_addr;
optbl[0x22] = &bCPU::op_jsr_long;
optbl[0xfc] = &bCPU::op_jsr_iaddrx;
optbl[0x40] = &bCPU::op_rti;
optbl[0x60] = &bCPU::op_rts;
optbl[0x6b] = &bCPU::op_rtl;
optbl[0xea] = &bCPU::op_nop;
optbl[0x42] = &bCPU::op_wdm;
optbl[0xeb] = &bCPU::op_xba;
optbl[0x54] = &bCPU::op_mvn;
optbl[0x44] = &bCPU::op_mvp;
optbl[0x00] = &bCPU::op_brk;
optbl[0x02] = &bCPU::op_cop;
optbl[0xdb] = &bCPU::op_stp;
optbl[0xcb] = &bCPU::op_wai;
optbl[0xfb] = &bCPU::op_xce;
optbl[0x18] = &bCPU::op_clc;
optbl[0xd8] = &bCPU::op_cld;
optbl[0x58] = &bCPU::op_cli;
optbl[0xb8] = &bCPU::op_clv;
optbl[0x38] = &bCPU::op_sec;
optbl[0xf8] = &bCPU::op_sed;
optbl[0x78] = &bCPU::op_sei;
optbl[0xc2] = &bCPU::op_rep;
optbl[0xe2] = &bCPU::op_sep;
optbl[0xaa] = &bCPU::op_tax;
optbl[0xa8] = &bCPU::op_tay;
optbl[0x8a] = &bCPU::op_txa;
optbl[0x9b] = &bCPU::op_txy;
optbl[0x98] = &bCPU::op_tya;
optbl[0xbb] = &bCPU::op_tyx;
optbl[0x5b] = &bCPU::op_tcd;
optbl[0x1b] = &bCPU::op_tcs;
optbl[0x7b] = &bCPU::op_tdc;
optbl[0x3b] = &bCPU::op_tsc;
optbl[0xba] = &bCPU::op_tsx;
optbl[0x9a] = &bCPU::op_txs;
optbl[0x48] = &bCPU::op_pha;
optbl[0xda] = &bCPU::op_phx;
optbl[0x5a] = &bCPU::op_phy;
optbl[0x0b] = &bCPU::op_phd;
optbl[0x8b] = &bCPU::op_phb;
optbl[0x4b] = &bCPU::op_phk;
optbl[0x08] = &bCPU::op_php;
optbl[0x68] = &bCPU::op_pla;
optbl[0xfa] = &bCPU::op_plx;
optbl[0x7a] = &bCPU::op_ply;
optbl[0x2b] = &bCPU::op_pld;
optbl[0xab] = &bCPU::op_plb;
optbl[0x28] = &bCPU::op_plp;
optbl[0xf4] = &bCPU::op_pea;
optbl[0xd4] = &bCPU::op_pei;
optbl[0x62] = &bCPU::op_per;

View File

@ -0,0 +1,141 @@
uint16 bCPU::vcounter() { return time.v; }
uint16 bCPU::hcounter() { return get_hcounter(); }
uint16 bCPU::hcycles() { return time.hc; }
bool bCPU::interlace() { return time.interlace; }
bool bCPU::interlace_field() { return time.interlace_field; }
bool bCPU::overscan() { return time.overscan; }
void bCPU::set_interlace(bool r) { time.interlace = r; }
void bCPU::set_overscan(bool r) { time.overscan = r; }
uint8 bCPU::dma_counter() { return (time.dma_counter + time.hc) & 6; }
//all scanlines are 1364 cycles long, except scanline 240
//on non-interlace odd-frames, which is 1360 cycles long.
//interlace mode has 525 scanlines: 263 on the even frame,
//and 262 on the odd.
//non-interlace mode has 524 scanlines: 262 scanlines on
//both even and odd frames.
//
//cycles per frame:
// 263 * 1364 = 358732
// 262 * 1364 = 357368
// 262 * 1364 - 4 = 357364
void bCPU::inc_vcounter() {
time.v++;
if(time.v >= time.frame_lines) {
time.v = 0;
time.interlace_field ^= 1;
if(time.interlace == true && time.interlace_field == 0) {
time.frame_lines = 263;
} else {
time.frame_lines = 262;
}
}
time.hc = 0;
time.dma_counter = time.line_cycles & 6;
if(time.v == 240 && time.interlace == false && time.interlace_field == 1) {
time.line_cycles = 1360;
} else {
time.line_cycles = 1364;
}
time.dram_refreshed = false;
}
//all dots are 4 cycles long, except dots 322 and 326. dots 322 and 326
//are 6 cycles long. this holds true for all scanlines except scanline
//240 on non-interlace odd frames. the reason for this is because this
//scanline is only 1360 cycles long, instead of 1364 like all other
//scanlines.
//this makes the effective range of hscan_pos 0-339 at all times.
//dot 322 range = { 1288, 1290, 1292 }
//dot 326 range = { 1306, 1308, 1310 }
uint16 bCPU::get_hcounter() {
if(time.v == 240 && time.interlace == false && time.interlace_field == 1) {
return time.hc >> 2;
}
return (time.hc - ((time.hc > 1288) << 1) - ((time.hc > 1306) << 1)) >> 2;
}
void bCPU::apu_sync() {
int cycles;
while(apusync.cycles >= 0) {
apu->run();
cycles = apu->cycles_executed();
if(cycles) {
apusync.cycles -= apusync.cpu_multbl[cycles];
}
}
}
void bCPU::dram_refresh() {
time.dram_refreshed = true;
add_cycles(40);
if(time.v != 240 || time.interlace != false || time.interlace_field != 1) {
//alternate between 534 and 538 every scanline except 240ni1
time.dram_refresh_pos ^= 12;
}
}
void bCPU::add_cycles(int cycles) {
cycles >>= 1;
while(cycles--) {
apusync.cycles += apusync.apu_freq << 1;
apu_sync();
time.hc += 2;
if(time.hc >= time.line_cycles) {
inc_vcounter();
if(time.v == 0) {
frame();
ppu->frame();
}
scanline();
ppu->scanline();
}
if(time.dram_refreshed == false && time.hc >= time.dram_refresh_pos) {
dram_refresh();
}
if(hdma_test() == true) {
hdma_run();
}
}
}
void bCPU::time_reset() {
//initial latch values for $213c/$213d
//[x]0035 : [y]0000 (53.0 -> 212) [lda $2137]
//[x]0038 : [y]0000 (56.5 -> 226) [nop : lda $2137]
time.v = 0;
time.hc = 186;
//upon SNES reset, start at scanline 0 non-interlace
time.interlace = false;
time.interlace_field = false;
time.overscan = false;
time.line_cycles = 1364;
time.frame_lines = 262;
time.dram_refreshed = false;
time.dram_refresh_pos = 538;
time.dma_counter = 0;
apusync.cycles = apusync.cpu_multbl[255];
}
void bCPU::time_init() {
apusync.cpu_freq = 21477272 >> 3;
apusync.apu_freq = 24576000 >> 3;
int i;
for(i=0;i<1024;i++) {
apusync.cpu_multbl[i] = i * apusync.cpu_freq;
apusync.apu_multbl[i] = i * apusync.apu_freq;
}
}

View File

@ -0,0 +1,38 @@
struct {
uint16 v, hc;
bool interlace, interlace_field, overscan;
uint16 line_cycles, frame_lines;
bool dram_refreshed;
uint16 dram_refresh_pos;
uint8 dma_counter;
}time;
inline uint16 vcounter();
inline uint16 hcounter();
inline uint16 hcycles();
inline bool interlace();
inline bool interlace_field();
inline bool overscan();
inline void set_interlace(bool r);
inline void set_overscan (bool r);
inline uint8 dma_counter();
inline void inc_vcounter();
inline uint16 get_hcounter();
inline void apu_sync();
inline void dram_refresh();
inline void add_cycles(int cycles);
inline void time_reset();
inline void time_init();
//APU synchronization
struct {
int32 cpu_freq, apu_freq;
int32 cpu_multbl[1024], apu_multbl[1024];
int32 cycles;
}apusync;

168
src/cpu/bcpu/bcpugen.cpp Normal file
View File

@ -0,0 +1,168 @@
#include "../../lib/libbase.h"
#include "../../lib/libstring.h"
#include "../../lib/libstring.cpp"
FILE *fp, *fph, *fpt;
string data, line, part, subpart;
string output_table, output_header, output_op;
int op_count;
struct _op_list {
string name;
string arg;
}op_list[64];
int line_num;
void clear_op_list() {
op_count = 0;
for(int i=0;i<64;i++) {
strcpy(op_list[i].name, "");
for(int l=0;l<8;l++) {
strcpy(op_list[i].arg[l], "");
}
}
}
void gen_header() {
int i = line_num, l, n, z;
char t[4096];
clear_op_list();
while(1) {
z = op_count++;
strcpy(part, line[i]);
strrtrim(part, "),");
strrtrim(part, ") {");
split(subpart, "(", part);
strcpy(op_list[z].name, subpart[0]);
split(part, ", ", subpart[1]);
for(l=0;l<count(part);l++) {
strcpy(op_list[z].arg[l], part[l]);
}
if(!strend(line[i], " {"))break;
i++;
}
sprintf(output_op, "void bCPU::op_$$() {\r\n");
sprintf(output_header, "void op_$$();\r\n");
sprintf(output_table, "optbl[$0] = &bCPU::op_$$;\r\n");
line_num = i + 1;
}
void update_line(int i, int n) {
char t[4096];
sprintf(t, "goto l%d;", n + 2);
replace(line[i], "end;", "return;");
replace(line[i], "skip;", t);
}
void gen_op() {
int i = line_num, n, c;
char t[4096];
while(1) {
if(!strcmp(line[i], "}"))break;
n = strdec(line[i]);
sprintf(t, "%d:", n);
strltrim(line[i], t);
sprintf(t, "l%d:\r\n", n);
strcat(output_op, t);
update_line(i, n);
if(strcmp(line[i], "")) {
strcat(output_op, " ");
strcat(output_op, line[i]);
strcat(output_op, "\r\n");
}
i++;
while(1) {
if((strptr(line[i])[1]) == ':' || !strcmp(line[i], "}"))break;
update_line(i, n);
strcat(output_op, line[i]);
strcat(output_op, "\r\n");
i++;
}
}
strcat(output_op, "}");
line_num = i + 1;
}
void gen_final() {
string t;
int i, l;
for(i=0;i<op_count;i++) {
strcpy(t, output_op);
replace(t, "$$", op_list[i].name);
replace(t, "$0", op_list[i].arg[0]);
replace(t, "$1", op_list[i].arg[1]);
replace(t, "$2", op_list[i].arg[2]);
replace(t, "$3", op_list[i].arg[3]);
replace(t, "$4", op_list[i].arg[4]);
replace(t, "$5", op_list[i].arg[5]);
replace(t, "$6", op_list[i].arg[6]);
replace(t, "$7", op_list[i].arg[7]);
fprintf(fp, "%s\r\n\r\n", *t);
strcpy(t, output_header);
replace(t, "$$", op_list[i].name);
fprintf(fph, "%s", *t);
strcpy(t, output_table);
replace(t, "$$", op_list[i].name);
replace(t, "$0", op_list[i].arg[0]);
fprintf(fpt, "%s", *t);
}
}
void generate(char *dest, char *src) {
fp = fopen(src, "rb");
fseek(fp, 0, SEEK_END);
int fsize = ftell(fp);
fseek(fp, 0, SEEK_SET);
char *buf = (char*)malloc(fsize + 1);
fread(buf, 1, fsize, fp);
fclose(fp);
buf[fsize] = 0;
strcpy(data, buf);
free(buf);
replace(data, "\r\n", "\n");
split(line, "\n", data);
fp = fopen(dest, "wb");
line_num = 0;
while(line_num < count(line)) {
while(!strcmp(line[line_num], "") && line_num < count(line))line_num++;
if(line_num >= count(line))break;
gen_header();
gen_op();
gen_final();
}
fclose(fp);
}
int main() {
fph = fopen("bcpu_op.h", "wb");
fpt = fopen("bcpu_optable.cpp", "wb");
generate("bcpu_op_read.cpp", "op_read.b");
generate("bcpu_op_rmw.cpp", "op_rmw.b");
generate("bcpu_op_write.cpp", "op_write.b");
generate("bcpu_op_pc.cpp", "op_pc.b");
generate("bcpu_op_misc.cpp", "op_misc.b");
fclose(fph);
fclose(fpt);
return 0;
}

BIN
src/cpu/bcpu/bcpugen.exe Normal file

Binary file not shown.

3
src/cpu/bcpu/cc.bat Normal file
View File

@ -0,0 +1,3 @@
cl /ML /O2 bcpugen.cpp
@pause
@del *.obj

8
src/cpu/bcpu/clean.bat Normal file
View File

@ -0,0 +1,8 @@
@del *.exe
@del bcpu_op_misc.cpp
@del bcpu_op_pc.cpp
@del bcpu_op_read.cpp
@del bcpu_op_rmw.cpp
@del bcpu_op_write.cpp
@del bcpu_optable.cpp
@del bcpu_op.h

252
src/cpu/bcpu/op_misc.b Normal file
View File

@ -0,0 +1,252 @@
nop(0xea) {
1:cpu_io();
}
wdm(0x42) {
1:cpu_io();
regs.pc.w++;
}
xba(0xeb) {
1:cpu_io();
2:cpu_io();
regs.a.l ^= regs.a.h;
regs.a.h ^= regs.a.l;
regs.a.l ^= regs.a.h;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
mvn(0x54, ++),
mvp(0x44, --) {
1:dp = op_read();
2:sp = op_read();
3:regs.db = dp;
rd.l = op_read(OPMODE_LONG, (sp << 16) | regs.x.w);
4:op_write(OPMODE_LONG, (dp << 16) | regs.y.w, rd.l);
5:cpu_io();
if(regs.p.x) { regs.x.l$1; regs.y.l$1; }
else { regs.x.w$1; regs.y.w$1; }
6:cpu_io();
if(regs.a.w--)regs.pc.w -= 3;
}
brk(0x00, 0xfffe, 0xffff, 0xffe6, 0xffe7),
cop(0x02, 0xfff4, 0xfff5, 0xffe4, 0xffe5) {
1:op_read();
if(regs.e)skip;
2:stack_write(regs.pc.b);
3:stack_write(regs.pc.h);
4:stack_write(regs.pc.l);
5:stack_write(regs.p);
6:rd.l = op_read(OPMODE_LONG, (regs.e)?$1:$3);
7:rd.h = op_read(OPMODE_LONG, (regs.e)?$2:$4);
regs.pc.b = 0x00;
regs.pc.w = rd.w;
regs.p.i = 1;
regs.p.d = 0;
}
stp(0xdb) {
1:cpu_io();
status.cpu_state = CPUSTATE_STP;
2:cpu_io();
regs.pc.w--;
}
wai(0xcb) {
1:cpu_io();
status.cpu_state = CPUSTATE_WAI;
2:cpu_io();
regs.pc.w--;
}
xce(0xfb) {
1:cpu_io();
bool c = regs.p.c;
regs.p.c = regs.e;
regs.e = c;
if(regs.e) {
regs.p |= 0x30;
regs.x.h = 0x00;
regs.y.h = 0x00;
regs.s.h = 0x01;
}
}
clc(0x18, regs.p.c = 0),
cld(0xd8, regs.p.d = 0),
cli(0x58, regs.p.i = 0),
clv(0xb8, regs.p.v = 0),
sec(0x38, regs.p.c = 1),
sed(0xf8, regs.p.d = 1),
sei(0x78, regs.p.i = 1) {
1:cpu_io();
$1;
}
rep(0xc2, &=~),
sep(0xe2, |=) {
1:rd.l = op_read();
2:cpu_io();
regs.p $1 rd.l;
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
}
tax(0xaa, regs.p.x, x, a),
tay(0xa8, regs.p.x, y, a),
txa(0x8a, regs.p.m, a, x),
txy(0x9b, regs.p.x, y, x),
tya(0x98, regs.p.m, a, y),
tyx(0xbb, regs.p.x, x, y) {
1:cpu_io();
if($1) {
regs.$2.l = regs.$3.l;
regs.p.n = !!(regs.$2.l & 0x80);
regs.p.z = (regs.$2.l == 0);
} else {
regs.$2.w = regs.$3.w;
regs.p.n = !!(regs.$2.w & 0x8000);
regs.p.z = (regs.$2.w == 0);
}
}
tcd(0x5b) {
1:cpu_io();
regs.d.w = regs.a.w;
regs.p.n = !!(regs.d.w & 0x8000);
regs.p.z = (regs.d.w == 0);
}
tcs(0x1b) {
1:cpu_io();
regs.s.w = regs.a.w;
if(regs.e)regs.s.h = 0x01;
}
tdc(0x7b) {
1:cpu_io();
regs.a.w = regs.d.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
tsc(0x3b) {
1:cpu_io();
regs.a.w = regs.s.w;
if(regs.e) {
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
tsx(0xba) {
1:cpu_io();
if(regs.p.x) {
regs.x.l = regs.s.l;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
} else {
regs.x.w = regs.s.w;
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
}
txs(0x9a) {
1:cpu_io();
if(regs.e) {
regs.s.l = regs.x.l;
regs.p.n = !!(regs.s.l & 0x80);
regs.p.z = (regs.s.l == 0);
} else {
regs.s.w = regs.x.w;
regs.p.n = !!(regs.s.w & 0x8000);
regs.p.z = (regs.s.w == 0);
}
}
pha(0x48, regs.p.m, a),
phx(0xda, regs.p.x, x),
phy(0x5a, regs.p.x, y),
phd(0x0b, 0, d) {
1:cpu_io();
if($1)skip;
2:stack_write(regs.$2.h);
3:stack_write(regs.$2.l);
}
phb(0x8b, regs.db),
phk(0x4b, regs.pc.b),
php(0x08, regs.p) {
1:cpu_io();
2:stack_write($1);
}
pla(0x68, regs.p.m, a),
plx(0xfa, regs.p.x, x),
ply(0x7a, regs.p.x, y),
pld(0x2b, 0, d) {
1:cpu_io();
2:cpu_io();
3:regs.$2.l = stack_read();
if($1) {
regs.p.n = !!(regs.$2.l & 0x80);
regs.p.z = (regs.$2.l == 0);
end;
}
4:regs.$2.h = stack_read();
regs.p.n = !!(regs.$2.w & 0x8000);
regs.p.z = (regs.$2.w == 0);
}
plb(0xab) {
1:cpu_io();
2:cpu_io();
3:regs.db = stack_read();
regs.p.n = !!(regs.db & 0x80);
regs.p.z = (regs.db == 0);
}
plp(0x28) {
1:cpu_io();
2:cpu_io();
3:regs.p = stack_read();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
}
pea(0xf4) {
1:aa.l = op_read();
2:aa.h = op_read();
3:stack_write(aa.h);
4:stack_write(aa.l);
}
pei(0xd4) {
1:dp = op_read();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:stack_write(aa.h);
6:stack_write(aa.l);
}
per(0x62) {
1:aa.l = op_read();
2:aa.h = op_read();
3:cpu_io();
rd.w = regs.pc.d + (int16)aa.w;
4:stack_write(rd.h);
5:stack_write(rd.l);
}

137
src/cpu/bcpu/op_pc.b Normal file
View File

@ -0,0 +1,137 @@
bra(0x80, 1),
bcc(0x90, !regs.p.c),
bcs(0xb0, regs.p.c),
bne(0xd0, !regs.p.z),
beq(0xf0, regs.p.z),
bpl(0x10, !regs.p.n),
bmi(0x30, regs.p.n),
bvc(0x50, !regs.p.v),
bvs(0x70, regs.p.v) {
1:rd.l = op_read();
if($1) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
end;
}
2:cpu_c6(aa.w);
3:cpu_io();
}
brl(0x82) {
1:rd.l = op_read();
2:rd.h = op_read();
3:cpu_io();
regs.pc.w = regs.pc.d + (int16)rd.w;
}
jmp_addr(0x4c) {
1:rd.l = op_read();
2:rd.h = op_read();
regs.pc.w = rd.w;
}
jmp_long(0x5c) {
1:rd.l = op_read();
2:rd.h = op_read();
3:rd.b = op_read();
regs.pc.d = rd.d & 0xffffff;
}
jmp_iaddr(0x6c) {
1:aa.l = op_read();
2:aa.h = op_read();
3:rd.l = op_read(OPMODE_ADDR, aa.w);
4:rd.h = op_read(OPMODE_ADDR, aa.w + 1);
regs.pc.w = rd.w;
}
jmp_iaddrx(0x7c) {
1:aa.l = op_read();
2:aa.h = op_read();
3:cpu_io();
4:rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w);
5:rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
}
jmp_iladdr(0xdc) {
1:aa.l = op_read();
2:aa.h = op_read();
3:rd.l = op_read(OPMODE_ADDR, aa.w);
4:rd.h = op_read(OPMODE_ADDR, aa.w + 1);
5:rd.b = op_read(OPMODE_ADDR, aa.w + 2);
regs.pc.d = rd.d & 0xffffff;
}
jsr_addr(0x20) {
1:aa.l = op_read();
2:aa.h = op_read();
3:cpu_io();
4:regs.pc.w--;
stack_write(regs.pc.h);
5:stack_write(regs.pc.l);
regs.pc.w = aa.w;
}
jsr_long(0x22) {
1:aa.l = op_read();
2:aa.h = op_read();
3:stack_write(regs.pc.b);
4:cpu_io();
5:aa.b = op_read();
6:regs.pc.w--;
stack_write(regs.pc.h);
7:stack_write(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
}
jsr_iaddrx(0xfc) {
1:aa.l = op_read();
2:stack_write(regs.pc.h);
3:stack_write(regs.pc.l);
4:aa.h = op_read();
5:cpu_io();
6:rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w);
7:rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
}
rti(0x40) {
1:cpu_io();
2:cpu_io();
3:regs.p = stack_read();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
4:rd.l = stack_read();
5:rd.h = stack_read();
if(regs.e) {
regs.pc.w = rd.w;
end;
}
6:rd.b = stack_read();
regs.pc.d = rd.d & 0xffffff;
}
rts(0x60) {
1:cpu_io();
2:cpu_io();
3:rd.l = stack_read();
4:rd.h = stack_read();
5:cpu_io();
regs.pc.w = rd.w;
regs.pc.w++;
}
rtl(0x6b) {
1:cpu_io();
2:cpu_io();
3:rd.l = stack_read();
4:rd.h = stack_read();
5:rd.b = stack_read();
regs.pc.d = rd.d & 0xffffff;
regs.pc.w++;
}

283
src/cpu/bcpu/op_read.b Normal file
View File

@ -0,0 +1,283 @@
adc_const(0x69, adc, regs.p.m),
and_const(0x29, and, regs.p.m),
cmp_const(0xc9, cmp, regs.p.m),
cpx_const(0xe0, cpx, regs.p.x),
cpy_const(0xc0, cpy, regs.p.x),
eor_const(0x49, eor, regs.p.m),
lda_const(0xa9, lda, regs.p.m),
ldx_const(0xa2, ldx, regs.p.x),
ldy_const(0xa0, ldy, regs.p.x),
ora_const(0x09, ora, regs.p.m),
sbc_const(0xe9, sbc, regs.p.m) {
1:rd.l = op_read();
if($2) { op_$1_b(); end; }
2:rd.h = op_read();
op_$1_w();
}
adc_addr(0x6d, adc, regs.p.m),
and_addr(0x2d, and, regs.p.m),
bit_addr(0x2c, bit, regs.p.m),
cmp_addr(0xcd, cmp, regs.p.m),
cpx_addr(0xec, cpx, regs.p.x),
cpy_addr(0xcc, cpy, regs.p.x),
eor_addr(0x4d, eor, regs.p.m),
lda_addr(0xad, lda, regs.p.m),
ldx_addr(0xae, ldx, regs.p.x),
ldy_addr(0xac, ldy, regs.p.x),
ora_addr(0x0d, ora, regs.p.m),
sbc_addr(0xed, sbc, regs.p.m) {
1:aa.l = op_read();
2:aa.h = op_read();
3:rd.l = op_read(OPMODE_DBR, aa.w);
if($2) { op_$1_b(); end; }
4:rd.h = op_read(OPMODE_DBR, aa.w + 1);
op_$1_w();
}
adc_addrx(0x7d, adc, regs.p.m),
and_addrx(0x3d, and, regs.p.m),
bit_addrx(0x3c, bit, regs.p.m),
cmp_addrx(0xdd, cmp, regs.p.m),
eor_addrx(0x5d, eor, regs.p.m),
lda_addrx(0xbd, lda, regs.p.m),
ldy_addrx(0xbc, ldy, regs.p.x),
ora_addrx(0x1d, ora, regs.p.m),
sbc_addrx(0xfd, sbc, regs.p.m) {
1:aa.l = op_read();
2:aa.h = op_read();
3:cpu_c4(aa.w, aa.w + regs.x.w);
4:rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
if($2) { op_$1_b(); end; }
5:rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
op_$1_w();
}
adc_addry(0x79, adc, regs.p.m),
and_addry(0x39, and, regs.p.m),
cmp_addry(0xd9, cmp, regs.p.m),
eor_addry(0x59, eor, regs.p.m),
lda_addry(0xb9, lda, regs.p.m),
ldx_addry(0xbe, ldx, regs.p.x),
ora_addry(0x19, ora, regs.p.m),
sbc_addry(0xf9, sbc, regs.p.m) {
1:aa.l = op_read();
2:aa.h = op_read();
3:cpu_c4(aa.w, aa.w + regs.y.w);
4:rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w);
if($2) { op_$1_b(); end; }
5:rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1);
op_$1_w();
}
adc_long(0x6f, adc, regs.p.m),
and_long(0x2f, and, regs.p.m),
cmp_long(0xcf, cmp, regs.p.m),
eor_long(0x4f, eor, regs.p.m),
lda_long(0xaf, lda, regs.p.m),
ora_long(0x0f, ora, regs.p.m),
sbc_long(0xef, sbc, regs.p.m) {
1:aa.l = op_read();
2:aa.h = op_read();
3:aa.b = op_read();
4:rd.l = op_read(OPMODE_LONG, aa.d);
if($2) { op_$1_b(); end; }
5:rd.h = op_read(OPMODE_LONG, aa.d + 1);
op_$1_w();
}
adc_longx(0x7f, adc, regs.p.m),
and_longx(0x3f, and, regs.p.m),
cmp_longx(0xdf, cmp, regs.p.m),
eor_longx(0x5f, eor, regs.p.m),
lda_longx(0xbf, lda, regs.p.m),
ora_longx(0x1f, ora, regs.p.m),
sbc_longx(0xff, sbc, regs.p.m) {
1:aa.l = op_read();
2:aa.h = op_read();
3:aa.b = op_read();
4:rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w);
if($2) { op_$1_b(); end; }
5:rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1);
op_$1_w();
}
adc_dp(0x65, adc, regs.p.m),
and_dp(0x25, and, regs.p.m),
bit_dp(0x24, bit, regs.p.m),
cmp_dp(0xc5, cmp, regs.p.m),
cpx_dp(0xe4, cpx, regs.p.x),
cpy_dp(0xc4, cpy, regs.p.x),
eor_dp(0x45, eor, regs.p.m),
lda_dp(0xa5, lda, regs.p.m),
ldx_dp(0xa6, ldx, regs.p.x),
ldy_dp(0xa4, ldy, regs.p.x),
ora_dp(0x05, ora, regs.p.m),
sbc_dp(0xe5, sbc, regs.p.m) {
1:dp = op_read();
2:cpu_c2();
3:rd.l = op_read(OPMODE_DP, dp);
if($2) { op_$1_b(); end; }
4:rd.h = op_read(OPMODE_DP, dp + 1);
op_$1_w();
}
adc_dpx(0x75, adc, regs.p.m),
and_dpx(0x35, and, regs.p.m),
bit_dpx(0x34, bit, regs.p.m),
cmp_dpx(0xd5, cmp, regs.p.m),
eor_dpx(0x55, eor, regs.p.m),
lda_dpx(0xb5, lda, regs.p.m),
ldy_dpx(0xb4, ldy, regs.p.x),
ora_dpx(0x15, ora, regs.p.m),
sbc_dpx(0xf5, sbc, regs.p.m) {
1:dp = op_read();
2:cpu_c2();
3:cpu_io();
4:rd.l = op_read(OPMODE_DP, dp + regs.x.w);
if($2) { op_$1_b(); end; }
5:rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
op_$1_w();
}
ldx_dpy(0xb6, ldx, regs.p.x) {
1:dp = op_read();
2:cpu_c2();
3:cpu_io();
4:rd.l = op_read(OPMODE_DP, dp + regs.y.w);
if($2) { op_$1_b(); end; }
5:rd.h = op_read(OPMODE_DP, dp + regs.y.w + 1);
op_$1_w();
}
adc_idp(0x72, adc, regs.p.m),
and_idp(0x32, and, regs.p.m),
cmp_idp(0xd2, cmp, regs.p.m),
eor_idp(0x52, eor, regs.p.m),
lda_idp(0xb2, lda, regs.p.m),
ora_idp(0x12, ora, regs.p.m),
sbc_idp(0xf2, sbc, regs.p.m) {
1:dp = op_read();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:rd.l = op_read(OPMODE_DBR, aa.w);
if($2) { op_$1_b(); end; }
6:rd.h = op_read(OPMODE_DBR, aa.w + 1);
op_$1_w();
}
adc_idpx(0x61, adc, regs.p.m),
and_idpx(0x21, and, regs.p.m),
cmp_idpx(0xc1, cmp, regs.p.m),
eor_idpx(0x41, eor, regs.p.m),
lda_idpx(0xa1, lda, regs.p.m),
ora_idpx(0x01, ora, regs.p.m),
sbc_idpx(0xe1, sbc, regs.p.m) {
1:dp = op_read();
2:cpu_c2();
3:cpu_io();
4:aa.l = op_read(OPMODE_DP, dp + regs.x.w);
5:aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
6:rd.l = op_read(OPMODE_DBR, aa.w);
if($2) { op_$1_b(); end; }
7:rd.h = op_read(OPMODE_DBR, aa.w + 1);
op_$1_w();
}
adc_idpy(0x71, adc, regs.p.m),
and_idpy(0x31, and, regs.p.m),
cmp_idpy(0xd1, cmp, regs.p.m),
eor_idpy(0x51, eor, regs.p.m),
lda_idpy(0xb1, lda, regs.p.m),
ora_idpy(0x11, ora, regs.p.m),
sbc_idpy(0xf1, sbc, regs.p.m) {
1:dp = op_read();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:cpu_c4(aa.w, aa.w + regs.y.w);
6:rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w);
if($2) { op_$1_b(); end; }
7:rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1);
op_$1_w();
}
adc_ildp(0x67, adc, regs.p.m),
and_ildp(0x27, and, regs.p.m),
cmp_ildp(0xc7, cmp, regs.p.m),
eor_ildp(0x47, eor, regs.p.m),
lda_ildp(0xa7, lda, regs.p.m),
ora_ildp(0x07, ora, regs.p.m),
sbc_ildp(0xe7, sbc, regs.p.m) {
1:dp = op_read();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:aa.b = op_read(OPMODE_DP, dp + 2);
6:rd.l = op_read(OPMODE_LONG, aa.d);
if($2) { op_$1_b(); end; }
7:rd.h = op_read(OPMODE_LONG, aa.d + 1);
op_$1_w();
}
adc_ildpy(0x77, adc, regs.p.m),
and_ildpy(0x37, and, regs.p.m),
cmp_ildpy(0xd7, cmp, regs.p.m),
eor_ildpy(0x57, eor, regs.p.m),
lda_ildpy(0xb7, lda, regs.p.m),
ora_ildpy(0x17, ora, regs.p.m),
sbc_ildpy(0xf7, sbc, regs.p.m) {
1:dp = op_read();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:aa.b = op_read(OPMODE_DP, dp + 2);
6:rd.l = op_read(OPMODE_LONG, aa.d + regs.y.w);
if($2) { op_$1_b(); end; }
7:rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1);
op_$1_w();
}
adc_sr(0x63, adc, regs.p.m),
and_sr(0x23, and, regs.p.m),
cmp_sr(0xc3, cmp, regs.p.m),
eor_sr(0x43, eor, regs.p.m),
lda_sr(0xa3, lda, regs.p.m),
ora_sr(0x03, ora, regs.p.m),
sbc_sr(0xe3, sbc, regs.p.m) {
1:sp = op_read();
2:cpu_io();
3:rd.l = op_read(OPMODE_SP, sp);
if($2) { op_$1_b(); end; }
4:rd.h = op_read(OPMODE_SP, sp + 1);
op_$1_w();
}
adc_isry(0x73, adc),
and_isry(0x33, and),
cmp_isry(0xd3, cmp),
eor_isry(0x53, eor),
lda_isry(0xb3, lda),
ora_isry(0x13, ora),
sbc_isry(0xf3, sbc) {
1:sp = op_read();
2:cpu_io();
3:aa.l = op_read(OPMODE_SP, sp);
4:aa.h = op_read(OPMODE_SP, sp + 1);
5:cpu_io();
6:rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w);
if(regs.p.m) { op_$1_b(); end; }
7:rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1);
op_$1_w();
}
bit_const(0x89) {
1:rd.l = op_read();
if(regs.p.m) {
regs.p.z = ((rd.l & regs.a.l) == 0);
end;
}
2:rd.h = op_read();
regs.p.z = ((rd.w & regs.a.w) == 0);
}

175
src/cpu/bcpu/op_rmw.b Normal file
View File

@ -0,0 +1,175 @@
inc(0x1a, regs.p.m, a),
inx(0xe8, regs.p.x, x),
iny(0xc8, regs.p.x, y) {
1:cpu_io();
if($1) {
regs.$2.l++;
regs.p.n = !!(regs.$2.l & 0x80);
regs.p.z = (regs.$2.l == 0);
} else {
regs.$2.w++;
regs.p.n = !!(regs.$2.w & 0x8000);
regs.p.z = (regs.$2.w == 0);
}
}
dec(0x3a, regs.p.m, a),
dex(0xca, regs.p.x, x),
dey(0x88, regs.p.x, y) {
1:cpu_io();
if($1) {
regs.$2.l--;
regs.p.n = !!(regs.$2.l & 0x80);
regs.p.z = (regs.$2.l == 0);
} else {
regs.$2.w--;
regs.p.n = !!(regs.$2.w & 0x8000);
regs.p.z = (regs.$2.w == 0);
}
}
asl(0x0a) {
1:cpu_io();
if(regs.p.m) {
regs.p.c = !!(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.c = !!(regs.a.w & 0x8000);
regs.a.w <<= 1;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
lsr(0x4a) {
1:cpu_io();
if(regs.p.m) {
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.c = regs.a.w & 1;
regs.a.w >>= 1;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
rol(0x2a) {
1:cpu_io();
uint16 c = regs.p.c;
if(regs.p.m) {
regs.p.c = !!(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.a.l |= c;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.c = !!(regs.a.w & 0x8000);
regs.a.w <<= 1;
regs.a.w |= c;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
ror(0x6a) {
1:cpu_io();
uint16 c;
if(regs.p.m) {
c = (regs.p.c)?0x80:0;
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
regs.a.l |= c;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
c = (regs.p.c)?0x8000:0;
regs.p.c = regs.a.w & 1;
regs.a.w >>= 1;
regs.a.w |= c;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
inc_addr(0xee, inc),
dec_addr(0xce, dec),
asl_addr(0x0e, asl),
lsr_addr(0x4e, lsr),
rol_addr(0x2e, rol),
ror_addr(0x6e, ror),
trb_addr(0x1c, trb),
tsb_addr(0x0c, tsb) {
1:aa.l = op_read();
2:aa.h = op_read();
3:rd.l = op_read(OPMODE_DBR, aa.w);
if(regs.p.m)skip;
4:rd.h = op_read(OPMODE_DBR, aa.w + 1);
5:cpu_io();
if(regs.p.m) { op_$1_b(); skip; }
else op_$1_w();
6:op_write(OPMODE_DBR, aa.w + 1, rd.h);
7:op_write(OPMODE_DBR, aa.w, rd.l);
}
inc_addrx(0xfe, inc),
dec_addrx(0xde, dec),
asl_addrx(0x1e, asl),
lsr_addrx(0x5e, lsr),
rol_addrx(0x3e, rol),
ror_addrx(0x7e, ror) {
1:aa.l = op_read();
2:aa.h = op_read();
3:cpu_io();
4:rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
if(regs.p.m)skip;
5:rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
6:cpu_io();
if(regs.p.m) { op_$1_b(); skip; }
else op_$1_w();
7:op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
8:op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
}
inc_dp(0xe6, inc),
dec_dp(0xc6, dec),
asl_dp(0x06, asl),
lsr_dp(0x46, lsr),
rol_dp(0x26, rol),
ror_dp(0x66, ror),
trb_dp(0x14, trb),
tsb_dp(0x04, tsb) {
1:dp = op_read();
2:cpu_c2();
3:rd.l = op_read(OPMODE_DP, dp);
if(regs.p.m)skip;
4:rd.h = op_read(OPMODE_DP, dp + 1);
5:cpu_io();
if(regs.p.m) { op_$1_b(); skip; }
else op_$1_w();
6:op_write(OPMODE_DP, dp + 1, rd.h);
7:op_write(OPMODE_DP, dp, rd.l);
}
inc_dpx(0xf6, inc),
dec_dpx(0xd6, dec),
asl_dpx(0x16, asl),
lsr_dpx(0x56, lsr),
rol_dpx(0x36, rol),
ror_dpx(0x76, ror) {
1:dp = op_read();
2:cpu_c2();
3:cpu_io();
4:rd.l = op_read(OPMODE_DP, dp + regs.x.w);
if(regs.p.m)skip;
5:rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
6:cpu_io();
if(regs.p.m) { op_$1_b(); skip; }
else op_$1_w();
7:op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
8:op_write(OPMODE_DP, dp + regs.x.w, rd.l);
}

151
src/cpu/bcpu/op_write.b Normal file
View File

@ -0,0 +1,151 @@
sta_addr(0x8d, regs.p.m, regs.a.w),
stx_addr(0x8e, regs.p.x, regs.x.w),
sty_addr(0x8c, regs.p.x, regs.y.w),
stz_addr(0x9c, regs.p.m, 0x0000) {
1:aa.l = op_read();
2:aa.h = op_read();
3:op_write(OPMODE_DBR, aa.w, $2);
if($1)end;
4:op_write(OPMODE_DBR, aa.w + 1, $2 >> 8);
}
sta_addrx(0x9d, regs.p.m, regs.a.w),
stz_addrx(0x9e, regs.p.m, 0x0000) {
1:aa.l = op_read();
2:aa.h = op_read();
3:cpu_c4(aa.w, aa.w + regs.x.w);
4:op_write(OPMODE_DBR, aa.w + regs.x.w, $2);
if($1)end;
5:op_write(OPMODE_DBR, aa.w + regs.x.w + 1, $2 >> 8);
}
sta_addry(0x99) {
1:aa.l = op_read();
2:aa.h = op_read();
3:cpu_c4(aa.w, aa.w + regs.y.w);
4:op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l);
if(regs.p.m)end;
5:op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h);
}
sta_long(0x8f) {
1:aa.l = op_read();
2:aa.h = op_read();
3:aa.b = op_read();
4:op_write(OPMODE_LONG, aa.d, regs.a.l);
if(regs.p.m)end;
5:op_write(OPMODE_LONG, aa.d + 1, regs.a.h);
}
sta_longx(0x9f) {
1:aa.l = op_read();
2:aa.h = op_read();
3:aa.b = op_read();
4:op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l);
if(regs.p.m)end;
5:op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h);
}
sta_dp(0x85, regs.p.m, regs.a.w),
stx_dp(0x86, regs.p.x, regs.x.w),
sty_dp(0x84, regs.p.x, regs.y.w),
stz_dp(0x64, regs.p.m, 0x0000) {
1:dp = op_read();
2:cpu_c2();
3:op_write(OPMODE_DP, dp, $2);
if($1)end;
4:op_write(OPMODE_DP, dp + 1, $2 >> 8);
}
sta_dpx(0x95, regs.p.m, regs.a.w),
sty_dpx(0x94, regs.p.x, regs.y.w),
stz_dpx(0x74, regs.p.m, 0x0000) {
1:dp = op_read();
2:cpu_c2();
3:cpu_io();
4:op_write(OPMODE_DP, dp + regs.x.w, $2);
if($1)end;
5:op_write(OPMODE_DP, dp + regs.x.w + 1, $2 >> 8);
}
stx_dpy(0x96) {
1:dp = op_read();
2:cpu_c2();
3:cpu_io();
4:op_write(OPMODE_DP, dp + regs.y.w, regs.x.l);
if(regs.p.x)end;
5:op_write(OPMODE_DP, dp + regs.y.w + 1, regs.x.h);
}
sta_idp(0x92) {
1:dp = op_read();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:op_write(OPMODE_DBR, aa.w, regs.a.l);
if(regs.p.m)end;
6:op_write(OPMODE_DBR, aa.w + 1, regs.a.h);
}
sta_ildp(0x87) {
1:dp = op_read();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:aa.b = op_read(OPMODE_DP, dp + 2);
6:op_write(OPMODE_LONG, aa.d, regs.a.l);
if(regs.p.m)end;
7:op_write(OPMODE_LONG, aa.d + 1, regs.a.h);
}
sta_idpx(0x81) {
1:dp = op_read();
2:cpu_c2();
3:cpu_io();
4:aa.l = op_read(OPMODE_DP, dp + regs.x.w);
5:aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
6:op_write(OPMODE_DBR, aa.w, regs.a.l);
if(regs.p.m)end;
7:op_write(OPMODE_DBR, aa.w + 1, regs.a.h);
}
sta_idpy(0x91) {
1:dp = op_read();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:cpu_c4(aa.w, aa.w + regs.y.w);
6:op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l);
if(regs.p.m)end;
7:op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h);
}
sta_ildpy(0x97) {
1:dp = op_read();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:aa.b = op_read(OPMODE_DP, dp + 2);
6:op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l);
if(regs.p.m)end;
7:op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h);
}
sta_sr(0x83) {
1:sp = op_read();
2:cpu_io();
3:op_write(OPMODE_SP, sp, regs.a.l);
if(regs.p.m)end;
4:op_write(OPMODE_SP, sp + 1, regs.a.h);
}
sta_isry(0x93) {
1:sp = op_read();
2:cpu_io();
3:aa.l = op_read(OPMODE_SP, sp);
4:aa.h = op_read(OPMODE_SP, sp + 1);
5:cpu_io();
6:op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l);
if(regs.p.m)end;
7:op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h);
}

158
src/cpu/bcpu/srtc.cpp Normal file
View File

@ -0,0 +1,158 @@
/*
S-RTC chip emulation
Used by Hudson Soft in Dai Kaijuu Monogatari II and Far East of Eden Zero.
Currently, only the former is supported by bsnes.
Original S-RTC emulation code via John Weidman/SNES9x
Rewritten for compatibility with bsnes via byuu
The S-RTC is a real-time clock chip that was added to the above two carts
to allow the games to maintain the current time, even when the game was not
powered on. Thus allowing special events at certain times, and on certain
dates. Hudson Soft called this the PLG (Player's Life Gameplay System).
This chip is a special case to the term 'emulation' itself.
There are a few different ways to go about emulating this chip, and each
result in a different style of emulation.
The first is to simply return the current PC system time when the S-RTC is
read from. This emulates the original S-RTC in the sense that it always
returns the true current time, ignoring the speed that the SNES itself is
running at. The downside to this method is that you lose the ability to set
the time to whatever you choose inside the game itself. It will always return
the true time, regardless. This can be overcome by changing the PC system time,
which actually adds a greater degree of control over event timing, very useful
for emulation. It also has a timeshifting flaw discussed below.
The second is to run the S-RTC relative to the SNES speed. This means that
if the emulator is sped up (via fast forward key, frameskipping, etc), or
slowed down (via slowdown key, system bottlenecking, etc); the time increments
slower, thus ~60 frames on the SNES equal one second. Without this, timeshifting
will occur between the S-RTC and the real SNES.
The third and final method is to save a copy of the local system time when the
S-RTC is initially set, and compare the current system time against this value
when setting the S-RTC time. This overcomes the first methods' shortcoming of
not allowing the player to set the time in-game, however a new problem arises.
You now have to save the time when the RTC was initially set to both savestates
and to save-game data. This would require an extra file, or the breaking of
perhaps the only standard format (.srm savegame backups) in the entire SNES
emulation scene. You also give up the control of being able to override the
RTC clock at will via the PC system time outside of emulation.
The first method has another advantage over the third: Dai Kaijuu Monogatari II
only allows dates in the range of the years 1996-2199. The first method gets
around this limitation. But who knows, maybe it will break something in the
game if the date exceeds 2199... I guess we'll worry about that in two hundred
years from now.
For my implementation, I chose to go with the first method. Both for simplicity
and because I did not wish to create a new method for saving the system time
whenever the RTC is set.
*/
void bCPU::srtc_set_time() {
time_t rawtime;
tm *t;
::time(&rawtime);
t = localtime(&rawtime);
//see srtc.h for format of srtc.data[]
srtc.data[0] = t->tm_sec % 10;
srtc.data[1] = t->tm_sec / 10;
srtc.data[2] = t->tm_min % 10;
srtc.data[3] = t->tm_min / 10;
srtc.data[4] = t->tm_hour % 10;
srtc.data[5] = t->tm_hour / 10;
srtc.data[6] = t->tm_mday % 10;
srtc.data[7] = t->tm_mday / 10;
srtc.data[8] = t->tm_mon + 1;
srtc.data[9] = t->tm_year % 10;
srtc.data[10] = (t->tm_year / 10) % 10;
srtc.data[11] = 9 + (t->tm_year / 100);
srtc.data[12] = t->tm_wday;
}
void bCPU::srtc_power() {
memset(&srtc, 0, sizeof(srtc));
reset();
}
void bCPU::srtc_reset() {
srtc.index = -1;
srtc.mode = SRTC_READ;
}
//Please see notes above about the implementation of the S-RTC
//Writes are stored the srtc.data[] array, but they are ignored
//as reads will refresh the data array with the current system
//time. The write method is only here for the sake of faux
//emulation of the real hardware.
void bCPU::srtc_write(uint8 data) {
data &= 0x0f; //only the low four bits are used
if(data >= 0x0d) {
switch(data) {
case 0x0d:
srtc.mode = SRTC_READ;
srtc.index = -1;
break;
case 0x0e:
srtc.mode = SRTC_COMMAND;
break;
case 0x0f:
//unknown behaviour
break;
}
return;
}
if(srtc.mode == SRTC_WRITE) {
if(srtc.index >= 0 && srtc.index < MAX_SRTC_INDEX) {
srtc.data[srtc.index++] = data;
if(srtc.index == MAX_SRTC_INDEX) {
//all S-RTC data has been loaded by program
srtc.data[srtc.index++] = 0x00; //day_of_week
}
}
} else if(srtc.mode == SRTC_COMMAND) {
switch(data) {
case SRTC_COMMAND_CLEAR:
memset(srtc.data, 0, MAX_SRTC_INDEX + 1);
srtc.index = -1;
srtc.mode = SRTC_READY;
break;
case SRTC_COMMAND_WRITE:
srtc.index = 0;
srtc.mode = SRTC_WRITE;
break;
default:
//unknown behaviour
srtc.mode = SRTC_READY;
break;
}
} else {
if(srtc.mode == SRTC_READ) {
//ignore writes while in read mode
} else if(srtc.mode == SRTC_READY) {
//unknown behaviour
}
}
}
uint8 bCPU::srtc_read() {
if(srtc.mode == SRTC_READ) {
if(srtc.index < 0) {
srtc_set_time();
srtc.index++;
return 0x0f; //send start message
} else if(srtc.index > MAX_SRTC_INDEX) {
srtc.index = -1;
return 0x0f; //send finished message
} else {
return srtc.data[srtc.index++];
}
} else {
return 0x00;
}
}

48
src/cpu/bcpu/srtc.h Normal file
View File

@ -0,0 +1,48 @@
void srtc_set_time();
void srtc_power();
void srtc_reset();
void srtc_write(uint8 data);
uint8 srtc_read();
#define MAX_SRTC_INDEX 0x0c
enum {
SRTC_READ = 0,
SRTC_WRITE,
SRTC_COMMAND,
SRTC_READY
};
enum {
SRTC_COMMAND_WRITE = 0,
SRTC_COMMAND_CLEAR = 4
};
#define DAYTICKS (60*60*24)
#define HOURTICKS (60*60)
#define MINUTETICKS (60)
/******************************
[srtc.data structure]
Index Description Range
----- ----------- -----
0 Seconds low 0-9
1 Seconds high 0-5
2 Minutes low 0-9
3 Minutes high 0-5
4 Hour low 0-9
5 Hour high 0-2
6 Day low 0-9
7 Day high 0-3
8 Month 1-12
9 Year ones 0-9
10 Year tens 0-9
11 Year hundreds 9-11 (9=19xx, 10=20xx, 11=21xx)
12 Day of week 0-6 (0=Sunday, ...)
******************************/
struct {
int8 index;
uint8 mode;
uint8 data[MAX_SRTC_INDEX + 1];
}srtc;

View File

@ -2,20 +2,34 @@
class CPU {
public:
//timing
virtual uint16 vcounter() = 0;
virtual uint16 hcounter() = 0;
virtual uint16 hcycles() = 0;
virtual bool interlace() = 0;
virtual bool interlace_field() = 0;
virtual bool overscan() = 0;
virtual void set_interlace(bool r) = 0;
virtual void set_overscan (bool r) = 0;
MMIO *mmio;
CPURegs regs;
virtual uint8 port_read (uint8 port) = 0;
virtual void port_write(uint8 port, uint8 value) = 0;
enum {
FLAG_N = 0x80, FLAG_V = 0x40,
FLAG_M = 0x20, FLAG_X = 0x10,
FLAG_D = 0x08, FLAG_I = 0x04,
FLAG_Z = 0x02, FLAG_C = 0x01
};
virtual uint8 pio_status() = 0;
virtual void run() = 0;
virtual void scanline() = 0;
virtual void frame() = 0;
virtual void power() = 0;
virtual void reset() = 0;
virtual uint8 pio_status() = 0;
virtual void run() = 0;
virtual void scanline() = 0;
virtual void frame() = 0;
virtual void power() = 0;
virtual void reset() = 0;
//opcode disassembler
enum {

View File

@ -2,32 +2,35 @@ class CPURegFlags {
private:
template <uint8 B> class bit {
public:
uint8 b;
inline operator bool() { return (b & B); }
inline operator = (bool i) { (i) ? b |= B : b &= ~B; return (b & B); }
inline operator & (bool i) { if(i)b &= ~B; return (b & B); }
inline operator | (bool i) { if(i)b |= B; return (b & B); }
inline operator ^ (bool i) { if(i)b ^= B; return (b & B); }
uint8 _b;
inline operator bool() { return (_b & B); }
inline bool operator = (bool i) { (i) ? _b |= B : _b &= ~B; return (_b & B); }
inline bool operator & (bool i) { if(i)_b &= ~B; return (_b & B); }
inline bool operator &= (bool i) { if(i)_b &= ~B; return (_b & B); }
inline bool operator | (bool i) { if(i)_b |= B; return (_b & B); }
inline bool operator |= (bool i) { if(i)_b |= B; return (_b & B); }
inline bool operator ^ (bool i) { if(i)_b ^= B; return (_b & B); }
inline bool operator ^= (bool i) { if(i)_b ^= B; return (_b & B); }
};
public:
union {
uint8 b;
uint8 _b;
bit<0x80> n;
bit<0x40> v;
bit<0x20> m;
bit<0x10> x;
bit<0x20> m, p;
bit<0x10> x, b;
bit<0x08> d;
bit<0x04> i;
bit<0x02> z;
bit<0x01> c;
};
CPURegFlags() { b = 0; }
inline operator uint8() { return b; }
inline unsigned operator = (uint8 i) { b = i; return b; }
inline unsigned operator &= (uint8 i) { b &= i; return b; }
inline unsigned operator |= (uint8 i) { b |= i; return b; }
inline unsigned operator ^= (uint8 i) { b ^= i; return b; }
CPURegFlags() { _b = 0; }
inline operator uint8() { return _b; }
inline unsigned operator = (uint8 i) { _b = i; return _b; }
inline unsigned operator &= (uint8 i) { _b &= i; return _b; }
inline unsigned operator |= (uint8 i) { _b |= i; return _b; }
inline unsigned operator ^= (uint8 i) { _b ^= i; return _b; }
};
class CPUReg16 {

View File

@ -378,7 +378,7 @@ uint8 op, op0, op1, op2;
strcat(s, " ");
sprintf(t, "A:%0.4x X:%0.4x Y:%0.4x S:%0.4x D:%0.4x DB:%0.2x ",
regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d, regs.db);
regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d.w, regs.db);
strcat(s, t);
if(regs.e) {
sprintf(t, "%c%c%c%c%c%c%c%c",

View File

@ -1,9 +1,5 @@
#include "reader/reader.h"
#include "clock/clock.h"
#include "clock/bclock/bclock.h"
extern Clock *clock;
#include "memory/memory.h"
#include "memory/bmemory/bmemory.h"
extern MMIO mmio_unmapped;
@ -13,6 +9,11 @@ extern MemBus *mem_bus;
#include "cpu/bcpu/bcpu.h"
extern CPU *cpu;
#include "apu/apu.h"
#include "apu/bapu/bapu.h"
#include "apu/bapuskip/bapuskip.h"
extern APU *apu;
#include "ppu/ppu.h"
#include "ppu/bppu/bppu.h"
extern PPU *ppu;
@ -21,9 +22,9 @@ extern PPU *ppu;
extern SNES *snes;
#ifdef INTERFACE_MAIN
Clock *clock;
MemBus *mem_bus;
CPU *cpu;
PPU *ppu;
SNES *snes;
MemBus *mem_bus;
CPU *cpu;
APU *apu;
PPU *ppu;
SNES *snes;
#endif

View File

@ -1,18 +1,29 @@
#include "libbase.h"
#include "libconfig.h"
//if this function returns true, the option is written
//to the configuration file. by always returning true,
//every option is always written. disable the first line
//to only output options after they have been changed by
//the program from their default values first.
bool config_item::changed() {
return (is_string == true) ? (*strsource != strdef) : (*source != def);
return true;
if(is_string == true) {
if(!strcmp(*strsource, strdef))return false;
return true;
}
return (*source != def);
}
config_item::config_item() {
strcpy(name, "");
strcpy(strdef, "");
is_string = false;
source = 0;
strsource = 0;
def = 0;
strdef = "";
type = 0;
name = "";
}
void config::add(uint32 *variable, char *name, uint32 def, uint32 type) {
@ -21,13 +32,12 @@ int n;
n = item_count;
item[n] = new config_item();
strcpy(item[n]->name, name);
item[n]->is_string = false;
item[n]->name = name;
item[n]->source = variable;
item[n]->def = def;
item[n]->type = type;
item[n]->source = variable;
*item[n]->source = item[n]->def;
item[n]->type = type;
item_count++;
}
@ -38,18 +48,19 @@ int n;
n = item_count;
item[n] = new config_item();
item[n]->is_string = true;
item[n]->name = name;
item[n]->strsource = variable;
item[n]->strdef = def;
*item[n]->strsource = item[n]->strdef;
strcpy(item[n]->name, name);
item[n]->is_string = true;
strcpy(item[n]->strdef, def);
item[n]->strsource = variable;
strcpy(*item[n]->strsource, item[n]->strdef);
item[n]->type = type;
item_count++;
}
uint32 config::find(char *name) {
for(int i=0;i<item_count;i++) {
if(item[i]->name == name) {
if(!strcmp(item[i]->name, name)) {
return i;
}
}
@ -66,7 +77,7 @@ string &config::strget(char *name) {
int i = find(name);
if(i == null) {
static string not_found;
not_found = "";
strcmp(not_found, "");
return not_found;
}
return *item[i]->strsource;
@ -81,7 +92,7 @@ int i = find(name);
void config::set(char *name, char *value) {
int i = find(name);
if(i == null)return;
*item[i]->strsource = value;
strcpy(*item[i]->strsource, value);
}
void config::load(char *fn) {
@ -90,14 +101,14 @@ char *buffer;
int i, fsize;
uint32 l;
fp = fopen(fn, "rb");
/* file doesn't exist yet, do nothing */
//file doesn't exist yet, do nothing
if(!fp)return;
fseek(fp, 0, SEEK_END);
fsize = ftell(fp);
fseek(fp, 0, SEEK_SET);
/* blank file, do nothing */
//blank file, do nothing
if(fsize == 0) {
fclose(fp);
return;
@ -108,7 +119,7 @@ uint32 l;
fclose(fp);
buffer[fsize] = 0;
data = buffer;
strcpy(data, buffer);
free(buffer);
replace(data, "\r\n", "\n");
qreplace(data, "\t", " ");
@ -118,29 +129,31 @@ uint32 l;
for(i=0;i<count(line);i++) {
qreplace(line[i], " ", "");
/* remove comment, if it exists */
//remove comment, if it exists
if(strqpos(line[i], "#") != null) {
strset(line[i], strqpos(line[i], "#"), 0);
}
/* ignore blank lines */
//ignore blank lines
if(strlen(line[i]) == 0)continue;
qsplit(part, "=", line[i]);
l = find(*part[0]);
if(l != null) {
/* if the config item name is valid... update item value */
//if the config item name is valid... update item value
if(item[l]->is_string == true) {
strunquote(part[1]);
*item[l]->strsource = part[1];
strcpy(*item[l]->strsource, part[1]);
} else {
if(part[1] == "true" || part[1] == "yes" || part[1] == "on" || part[1] == "enabled") {
if(!strcmp(part[1], "true") || !strcmp(part[1], "yes") ||
!strcmp(part[1], "on") || !strcmp(part[1], "enabled")) {
*item[l]->source = 1;
} else if(part[1] == "false" || part[1] == "no" || part[1] == "off" || part[1] == "disabled") {
} else if(!strcmp(part[1], "false") || !strcmp(part[1], "no") ||
!strcmp(part[1], "off") || !strcmp(part[1], "disabled")) {
*item[l]->source = 0;
} else if(item[l]->type == HEX) {
*item[l]->source = strhex(part[1]);
*item[l]->source = strhex(*part[1] + 2); //skip 0x prefix
} else { /* fall back on DEC */
*item[l]->source = strdec(part[1]);
}
@ -149,38 +162,38 @@ uint32 l;
}
}
/* create a text string from config item[i] to be output via config->save() */
//create a text string from config item[i] to be output via config->save()
void config::set_newline(int i) {
char t[16];
if(item[i]->is_string == true) {
newline = item[i]->name;
newline += " = \"";
newline += *item[i]->strsource;
newline += "\"";
strcpy(newline, item[i]->name);
strcat(newline, " = \"");
strcat(newline, *item[i]->strsource);
strcat(newline, "\"");
} else {
newline = item[i]->name;
newline += " = ";
strcpy(newline, item[i]->name);
strcat(newline, " = ");
switch(item[i]->type) {
case TRUEFALSE:
newline += (*item[i]->source)?"true":"false";
strcat(newline, (*item[i]->source)?"true":"false");
break;
case YESNO:
newline += (*item[i]->source)?"yes":"no";
strcat(newline, (*item[i]->source)?"yes":"no");
break;
case ONOFF:
newline += (*item[i]->source)?"on":"off";
strcat(newline, (*item[i]->source)?"on":"off");
break;
case ENABLED:
newline += (*item[i]->source)?"enabled":"disabled";
strcat(newline, (*item[i]->source)?"enabled":"disabled");
break;
case HEX:
sprintf(t, "%x", *item[i]->source);
newline += t;
sprintf(t, "0x%0.2x", *item[i]->source);
strcat(newline, t);
break;
case DEC:
default:
sprintf(t, "%d", *item[i]->source);
newline += t;
strcat(newline, t);
break;
}
}
@ -206,21 +219,21 @@ bool blank = false;
} else {
buffer = (char*)malloc(fsize + 1);
fread(buffer, 1, fsize, fp);
fclose(fp);
buffer[fsize] = 0;
data = buffer;
strcpy(data, buffer);
free(buffer);
}
fclose(fp);
}
fp = fopen(fn, "wb");
/* no write access? */
//no write access?
if(!fp)return;
/* list of config items. if the item is set in the
existing config file, then don't test it to see
if it needs to be written again later on */
//list of config items. if the item is set in the
//existing config file, then don't test it to see
//if it needs to be written again later on
memset(set, 0, item_count);
if(blank == false) {
@ -237,9 +250,9 @@ bool blank = false;
strset(line[i], strqpos(line[i], "#"), 0);
}
/* this line is empty, restore the old line and continue */
//this line is empty, restore the old line and continue
if(strlen(line[i]) == 0) {
line[i] = oldline[i];
strcpy(line[i], oldline[i]);
continue;
}
@ -247,44 +260,44 @@ bool blank = false;
l = find(*part[0]);
if(l == null) {
/* invalid item name, restore the old line and continue */
line[i] = oldline[i];
//invalid item name, restore the old line and continue
strcpy(line[i], oldline[i]);
continue;
}
set[l] = 1;
set_newline(l);
/* copy the user comment from the old config file, if it exists */
//copy the user comment from the old config file, if it exists
if(strqpos(oldline[i], "#") != null) {
newline += " ";
newline += *oldline[i] + strqpos(oldline[i], "#");
strcat(newline, " ");
strcat(newline, *oldline[i] + strqpos(oldline[i], "#"));
}
line[i] = newline;
strcpy(line[i], newline);
}
/* write out the old config file + changes first */
//write out the old config file + changes first
for(i=0;i<count(line);) {
fprintf(fp, "%s", *line[i]);
/* write a line feed on all lines but the last.
keeps the file from growing everytime it is saved */
//write a line feed on all lines but the last.
//keeps the file from growing everytime it is saved
if(++i < count(line))fprintf(fp, "\r\n");
}
}
int lines_written;
for(i=lines_written=0;i<item_count;i++) {
/* if the item was written to the file above... */
//if the item was written to the file above...
if(set[i] == 1)continue;
/* ...or if it is still set to the default value,
then don't output it to the file here */
//...or if it is still set to the default value,
//then don't output it to the file here
if(item[i]->changed() == false)continue;
set_newline(i);
/* prevent a newline from appearing at the top of the file
when the config file is created for the first time */
//prevent a newline from appearing at the top of the file
//when the config file is created for the first time
if(lines_written == 0 && blank == false)fprintf(fp, "\r\n");
fprintf(fp, "%s\r\n", *newline);
lines_written++;

View File

@ -1,5 +1,5 @@
/*
libconfig : version 0.01 ~byuu
libconfig : version 0.02 ~byuu
*/
#ifndef __LIBCONFIG

View File

@ -247,10 +247,10 @@ int ssl = strlen(str), ksl = strlen(key);
/* does not work on type char* because function increases string length */
void strquote(_string &str) {
static string t;
t = "\"";
t += str;
t += "\"";
str = t;
strcpy(t, "\"");
strcat(t, str);
strcat(t, "\"");
strcpy(str, t);
}
bool strunquote(char *str) {

View File

@ -1,5 +1,5 @@
/*
libstring : version 0.04 ~byuu
libstring : version 0.05 ~byuu
*/
#ifndef __LIBSTRING
@ -49,34 +49,29 @@ class _string {
public:
char *s;
uint32 size;
/* * */
inline char* operator*() { return s; }
/* = */
#ifdef __LIBSTRING_OVERLOADS
inline _string& operator=(char *cpy);
inline _string& operator=(_string &cpy);
inline _string& operator=(string &cpy);
/* += */
inline _string& operator+=(char *cat);
inline _string& operator+=(_string &cat);
inline _string& operator+=(string &cat);
/* -= */
inline _string& operator-=(char *cut);
inline _string& operator-=(_string &cut);
inline _string& operator-=(string &cut);
/* == */
inline bool operator==(char *cmp);
inline bool operator==(_string &cmp);
inline bool operator==(string &cmp);
/* != */
inline bool operator!=(char *cmp);
inline bool operator!=(_string &cmp);
inline bool operator!=(string &cmp);
#endif
inline operator char*() { return s; }
@ -91,33 +86,29 @@ uint32 count, listcount;
void addto(uint32 num); //creates all needed strings to make list[num] valid
_string &str(uint32 num); //gets a _string reference, creating it + new strings if needed
/* * */
inline char* operator*() { return strptr(str(0)); }
/* = */
#ifdef __LIBSTRING_OVERLOADS
inline string& operator=(char *cpy);
inline string& operator=(_string &cpy);
inline string& operator=(string &cpy);
/* += */
inline string& operator+=(char *cat);
inline string& operator+=(_string &cat);
inline string& operator+=(string &cat);
/* -= */
inline string& operator-=(char *cut);
inline string& operator-=(_string &cut);
inline string& operator-=(string &cut);
/* == */
inline bool operator==(char *cmp);
inline bool operator==(_string &cmp);
inline bool operator==(string &cmp);
/* != */
inline bool operator!=(char *cmp);
inline bool operator!=(_string &cmp);
inline bool operator!=(string &cmp);
#endif
inline operator char*() { return str(0).s; }
inline operator _string&() { return str(0); }
@ -128,9 +119,7 @@ uint32 count, listcount;
~string();
};
//
// =
//
#ifdef __LIBSTRING_OVERLOADS
inline _string& _string::operator=(char *cpy) {
strcpy(*this, cpy);
return *this;
@ -157,9 +146,6 @@ inline string& string::operator=(string &cpy) {
return *this;
}
//
// +=
//
inline _string& _string::operator+=(char *cat) {
strcat(*this, cat);
return *this;
@ -186,9 +172,6 @@ inline string& string::operator+=(string &cat) {
return *this;
}
//
// -=
//
inline _string& _string::operator-=(char *cut) {
strrtrim(*this, cut);
return *this;
@ -215,9 +198,6 @@ inline string& string::operator-=(string &cut) {
return *this;
}
//
// ==
//
inline bool _string::operator==(char *cmp) {
if(!strcmp(*this, cmp))return true;
return false;
@ -244,9 +224,6 @@ inline bool string::operator==(string &cmp) {
return false;
}
//
// !=
//
inline bool _string::operator!=(char *cmp) {
if(!strcmp(*this, cmp))return false;
return true;
@ -272,5 +249,6 @@ inline bool string::operator!=(string &cmp) {
if(!strcmp(str(0), cmp.str(0)))return false;
return true;
}
#endif //__LIBSTRING_OVERLOADS
#endif
#endif //__LIBSTRING

View File

@ -17,7 +17,7 @@ uint8 pad_type, pad_len;
uint32 num;
char *r;
va_start(args, s);
strcpy(str, "");
strcpy(*str, "");
for(i=0;i<strlen(s);i++) {
if(s[i] == '%') {
i++;

View File

@ -61,9 +61,8 @@ int size, sizelimit;
}
inline T &operator[](int index) {
static T __null = (T)0;
if(index >= size)resize(index + 1);
if(index > sizelimit)return __null;
if(index > sizelimit)return array[size - 1];
return array[index];
}
};

View File

@ -0,0 +1,108 @@
void bCartExHiROM::write_protect(bool r) { write_protected = r; }
uint8 bCartExHiROM::read(uint32 addr) {
uint32 b, w;
addr &= 0xffffff;
b = (addr >> 16);
w = (addr & 0xffff);
//SRAM Region A
if((b & 0x7f) >= 0x30 && (b & 0x7f) <= 0x3f && (w & 0xe000) == 0x6000) {
b &= 0x7f;
if(b >= 0x30 && b <= 0x3f) {
if(sram_size) {
addr = (b - 0x30) * 0x2000 + (w - 0x6000);
addr &= (sram_size - 1);
return sram[addr];
} else {
return 0x00; //no SRAM available
}
} else {
return 0x00; //unmapped
}
}
//SRAM Region B
if(b >= 0x70 && b <= 0x7d) {
if(sram_size) {
addr = (addr & 0xffffff) - 0x700000;
addr &= (sram_size - 1);
return sram[addr];
} else {
return 0x00; //no SRAM available
}
}
if(b <= 0x3f) {
addr &= 0x3fffff;
addr += 0x400000;
} else if(b <= 0x7f) {
addr &= 0x3fffff;
addr += 0x400000;
} else if(b <= 0xbf) {
addr &= 0x3fffff;
} else {
addr &= 0x3fffff;
}
if(addr < rom_size)return rom[addr];
return 0x00;
}
void bCartExHiROM::write(uint32 addr, uint8 value) {
uint32 b, w;
addr &= 0xffffff;
b = (addr >> 16);
w = (addr & 0xffff);
//SRAM Region A
if((b & 0x7f) >= 0x30 && (b & 0x7f) <= 0x3f && (w & 0xe000) == 0x6000) {
b &= 0x7f;
if(b >= 0x30 && b <= 0x3f) {
if(sram_size) {
addr = (b - 0x30) * 0x2000 + (w - 0x6000);
addr &= (sram_size - 1);
sram[addr] = value;
return;
} else {
return; //no SRAM available
}
} else {
return; //unmapped
}
}
//SRAM Region B
if(b >= 0x70 && b <= 0x7d) {
if(sram_size) {
addr = (addr & 0xffffff) - 0x700000;
addr &= (sram_size - 1);
sram[addr] = value;
} else {
return; //no SRAM available
}
}
if(write_protected == true)return;
if(b <= 0x3f) {
addr &= 0x3fffff;
addr += 0x400000;
} else if(b <= 0x7f) {
addr &= 0x3fffff;
addr += 0x400000;
} else if(b <= 0xbf) {
addr &= 0x3fffff;
} else {
addr &= 0x3fffff;
}
if(addr < rom_size)rom[addr] = value;
}
void bCartExHiROM::set_cartinfo(CartInfo *ci) {
rom = ci->rom;
sram = ci->sram;
rom_size = ci->rom_size;
sram_size = ci->sram_size;
}

View File

@ -0,0 +1,14 @@
class bCartExHiROM : public Cart {
private:
bool write_protected;
public:
uint8 *rom, *sram;
uint32 rom_size, sram_size;
uint8 read (uint32 addr);
void write(uint32 addr, byte value);
void write_protect(bool r);
void set_cartinfo(CartInfo *ci);
bCartExHiROM() : write_protected(true) {}
};

View File

@ -0,0 +1,86 @@
void bCartHiROM::write_protect(bool r) { write_protected = r; }
uint8 bCartHiROM::read(uint32 addr) {
uint32 b, w;
addr &= 0xffffff;
b = (addr >> 16);
w = (addr & 0xffff);
//SRAM Region A
if((b & 0x7f) >= 0x30 && (b & 0x7f) <= 0x3f && (w & 0xe000) == 0x6000) {
b &= 0x7f;
if(b >= 0x30 && b <= 0x3f) {
if(sram_size) {
addr = (b - 0x30) * 0x2000 + (w - 0x6000);
addr &= (sram_size - 1);
return sram[addr];
} else {
return 0x00; //no SRAM available
}
} else {
return 0x00; //unmapped
}
}
//SRAM Region B
if(b >= 0x70 && b <= 0x7d) {
if(sram_size) {
addr = (addr & 0xffffff) - 0x700000;
addr &= (sram_size - 1);
return sram[addr];
} else {
return 0x00; //no SRAM available
}
}
addr &= 0x3fffff;
if(addr < rom_size)return rom[addr];
return 0x00;
}
void bCartHiROM::write(uint32 addr, uint8 value) {
uint32 b, w;
addr &= 0xffffff;
b = (addr >> 16);
w = (addr & 0xffff);
//SRAM Region A
if((b & 0x7f) >= 0x30 && (b & 0x7f) <= 0x3f && (w & 0xe000) == 0x6000) {
b &= 0x7f;
if(b >= 0x30 && b <= 0x3f) {
if(sram_size) {
addr = (b - 0x30) * 0x2000 + (w - 0x6000);
addr &= (sram_size - 1);
sram[addr] = value;
return;
} else {
return; //no SRAM available
}
} else {
return; //unmapped
}
}
//SRAM Region B
if(b >= 0x70 && b <= 0x7d) {
if(sram_size) {
addr = (addr & 0xffffff) - 0x700000;
addr &= (sram_size - 1);
sram[addr] = value;
} else {
return; //no SRAM available
}
}
if(write_protected == true)return;
addr &= 0x3fffff;
if(addr < rom_size)rom[addr] = value;
}
void bCartHiROM::set_cartinfo(CartInfo *ci) {
rom = ci->rom;
sram = ci->sram;
rom_size = ci->rom_size;
sram_size = ci->sram_size;
}

View File

@ -0,0 +1,14 @@
class bCartHiROM : public Cart {
private:
bool write_protected;
public:
uint8 *rom, *sram;
uint32 rom_size, sram_size;
uint8 read (uint32 addr);
void write(uint32 addr, byte value);
void write_protect(bool r);
void set_cartinfo(CartInfo *ci);
bCartHiROM() : write_protected(true) {}
};

View File

@ -0,0 +1,104 @@
void bCartLoROM::write_protect(bool r) { write_protected = r; }
uint8 bCartLoROM::read(uint32 addr) {
uint32 b, w;
addr &= 0xffffff;
b = (addr >> 16);
w = (addr & 0xffff);
//SRAM Region A
if((b & 0x7f) >= 0x30 && (b & 0x7f) <= 0x3f && (w & 0xe000) == 0x6000) {
b &= 0x7f;
if(b >= 0x30 && b <= 0x3f) {
if(sram_size) {
addr = (b - 0x30) * 0x2000 + (w - 0x6000);
addr &= (sram_size - 1);
return sram[addr];
} else {
return 0x00; //no SRAM available
}
} else {
return 0x00; //unmapped
}
}
//SRAM Region B
if(b >= 0x70 && b <= 0x7d) {
if(sram_size) {
addr = (addr & 0xffffff) - 0x700000;
addr &= (sram_size - 1);
return sram[addr];
} else {
return 0x00; //no SRAM available
}
}
if(w & 0x8000) {
b &= 0x7f;
b %= 0x60;
addr = (b << 15) | (addr & 0x7fff);
} else {
b &= 0x7f;
b %= 0x60;
if(b == 0x00)b = 0x60;
addr = (((b << 15) | (addr & 0x7fff)) - 0x8000);
}
if(addr < rom_size)return rom[addr];
return 0x00;
}
void bCartLoROM::write(uint32 addr, uint8 value) {
uint32 b, w;
addr &= 0xffffff;
b = (addr >> 16);
w = (addr & 0xffff);
//SRAM Region A
if((b & 0x7f) >= 0x30 && (b & 0x7f) <= 0x3f && (w & 0xe000) == 0x6000) {
b &= 0x7f;
if(b >= 0x30 && b <= 0x3f) {
if(sram_size) {
addr = (b - 0x30) * 0x2000 + (w - 0x6000);
addr &= (sram_size - 1);
sram[addr] = value;
return;
} else {
return; //no SRAM available
}
} else {
return; //unmapped
}
}
//SRAM Region B
if(b >= 0x70 && b <= 0x7d) {
if(sram_size) {
addr = (addr & 0xffffff) - 0x700000;
addr &= (sram_size - 1);
sram[addr] = value;
} else {
return; //no SRAM available
}
}
if(write_protected == true)return;
if(w & 0x8000) {
b &= 0x7f;
b %= 0x60;
addr = (b << 15) | (addr & 0x7fff);
} else {
b &= 0x7f;
b %= 0x60;
if(b == 0x00)b = 0x60;
addr = (((b << 15) | (addr & 0x7fff)) - 0x8000);
}
if(addr < rom_size)rom[addr] = value;
}
void bCartLoROM::set_cartinfo(CartInfo *ci) {
rom = ci->rom;
sram = ci->sram;
rom_size = ci->rom_size;
sram_size = ci->sram_size;
}

View File

@ -0,0 +1,14 @@
class bCartLoROM : public Cart {
private:
bool write_protected;
public:
uint8 *rom, *sram;
uint32 rom_size, sram_size;
uint8 read (uint32 addr);
void write(uint32 addr, byte value);
void write_protect(bool r);
void set_cartinfo(CartInfo *ci);
bCartLoROM() : write_protected(true) {}
};

View File

@ -1,147 +1,32 @@
#include "../../base.h"
#include "bcart_lorom.cpp"
#include "bcart_hirom.cpp"
#include "bcart_exhirom.cpp"
uint8 bROM::read(uint32 addr) {
uint32 b, w;
addr &= 0xffffff;
b = (addr >> 16);
w = (addr & 0xffff);
bool bMemBus::load_cart(Reader *rf) {
uint32 cksum, icksum, index;
char cart_title[24];
uint8 mapper;
if(rom_loaded == true)return false;
/* SRAM Region A */
if((b & 0x7f) >= 0x30 && (b & 0x7f) <= 0x3f && (w & 0xe000) == 0x6000) {
b &= 0x7f;
if(b >= 0x30 && b <= 0x3f) {
if(sram_size) {
addr = (b - 0x30) * 0x2000 + (w - 0x6000);
addr &= (sram_size - 1);
return sram_data[addr];
} else {
return 0x00; //no SRAM available
}
} else {
return 0x00; //unmapped
}
}
rf->read(&rom);
/* SRAM Region B */
if(b >= 0x70 && b <= 0x7d) {
if(sram_size) {
addr = (addr & 0xffffff) - 0x700000;
addr &= (sram_size - 1);
return sram_data[addr];
} else {
return 0x00; //no SRAM available
}
}
rom_size = rf->size();
switch(mapper) {
case LOROM:
if(w & 0x8000) {
b &= 0x7f;
b %= 0x60;
addr = (b << 15) | (addr & 0x7fff);
} else {
b &= 0x7f;
b %= 0x60;
if(b == 0x00)b = 0x60;
addr = (((b << 15) | (addr & 0x7fff)) - 0x8000);
}
if(addr < size)return data[addr];
break;
case HIROM:
addr &= 0x3fffff;
if(addr < size)return data[addr];
break;
}
return 0x00;
}
if(rom_size < 32768)return false;
void bROM::write(uint32 addr, uint8 value) {
uint32 b, w;
addr &= 0xffffff;
b = (addr >> 16);
w = (addr & 0xffff);
/* SRAM Region A */
if((b & 0x7f) >= 0x30 && (b & 0x7f) <= 0x3f && (w & 0xe000) == 0x6000) {
b &= 0x7f;
if(b >= 0x30 && b <= 0x3f) {
if(sram_size) {
addr = (b - 0x30) * 0x2000 + (w - 0x6000);
addr &= (sram_size - 1);
sram_data[addr] = value;
return;
} else {
return; //no SRAM available
}
} else {
return; //unmapped
}
}
/* SRAM Region B */
if(b >= 0x70 && b <= 0x7d) {
if(sram_size) {
addr = (addr & 0xffffff) - 0x700000;
addr &= (sram_size - 1);
sram_data[addr] = value;
} else {
return; //no SRAM available
}
}
/* Block write attempts to ROM by default, debugger can override this */
if(write_protection == true)return;
switch(mapper) {
case LOROM:
if(w & 0x8000) {
b &= 0x7f;
b %= 0x60;
addr = (b << 15) | (addr & 0x7fff);
} else {
b &= 0x7f;
b %= 0x60;
if(b == 0x00)b = 0x60;
addr = (((b << 15) | (addr & 0x7fff)) - 0x8000);
}
if(addr < size)data[addr] = value;
break;
case HIROM:
addr &= 0x3fffff;
if(addr < size)data[addr] = value;
break;
}
}
void bROM::load_sram(Reader *rf) {
if(rom_loaded == false)return;
rf->read(&sram_data, sram_size);
}
void bROM::save_sram(Writer *wf) {
if(rom_loaded == false)return;
if(!sram_size)return;
wf->write(sram_data, sram_size);
}
void bROM::load_rom(Reader *rf) {
uint16 cksum, icksum, index;
char cart_title[24];
if(rom_loaded == true)return;
rf->read(&data);
size = rf->size();
if(size < 65536) {
mapper = LOROM;
strcpy(cart_title, "");
if(rom_size >= 0x410000) {
mapper = EXHIROM;
goto end;
}
cksum = data[0xffdc] | (data[0xffdd] << 8);
icksum = data[0xffde] | (data[0xffdf] << 8);
if(rom_size < 65536) {
mapper = LOROM;
goto end;
}
cksum = rom[0xffdc] | (rom[0xffdd] << 8);
icksum = rom[0xffde] | (rom[0xffdf] << 8);
if(cksum + icksum == 0xffff) {
mapper = HIROM;
} else {
@ -149,13 +34,15 @@ char cart_title[24];
}
end:
if(size >= 32768) {
memcpy(cart_title, (char*)data + ((mapper == LOROM)?0x7fc0:0xffc0), 21);
} else *cart_title = 0;
switch(mapper) {
case LOROM: index = 0x007fc0;break;
case HIROM: index = 0x00ffc0;break;
case EXHIROM:index = 0x40ffc0;break;
}
memcpy(cart_title, (char*)rom + index, 21);
cart_title[21] = 0;
index = (mapper == HIROM)?0x8000:0x0000;
switch(data[index + 0x7fd8] & 7) {
switch(rom[index + 0x18] & 7) {
case 0:sram_size = 0; break;
case 1:sram_size = 2 * 1024;break;
case 2:sram_size = 4 * 1024;break;
@ -166,45 +53,73 @@ end:
case 7:sram_size = 128 * 1024;break;
}
dprintf("Image Name : \"%s\"", cart_title);
dprintf("Image Type : %s", (mapper == LOROM)?"LoROM":"HiROM");
dprintf("SRAM Size : %dkb", sram_size / 1024);
dprintf("Reset:%0.4x NMI:%0.4x IRQ:%0.4x BRK[n]:%0.4x COP[n]:%0.4x BRK[e]:%0.4x COP[e]:%0.4x",
data[index + 0x7ffc] | (data[index + 0x7ffd] << 8), //Reset
data[index + 0x7fea] | (data[index + 0x7feb] << 8), //NMI
data[index + 0x7fee] | (data[index + 0x7fef] << 8), //IRQ
data[index + 0x7fe6] | (data[index + 0x7fe7] << 8), //BRK[n]
data[index + 0x7fe4] | (data[index + 0x7fe5] << 8), //COP[n]
data[index + 0x7ffe] | (data[index + 0x7fff] << 8), //BRK[e]
data[index + 0x7ff4] | (data[index + 0x7ff5] << 8) //COP[e]
dprintf("* Image Name : \"%s\"", cart_title);
dprintf("* MAD : %0.2x", mapper);
dprintf("* SRAM Size : %dkb", sram_size / 1024);
dprintf("* Reset:%0.4x NMI:%0.4x IRQ:%0.4x BRK[n]:%0.4x COP[n]:%0.4x BRK[e]:%0.4x COP[e]:%0.4x",
rom[index + 0x3c] | (rom[index + 0x3d] << 8), //Reset
rom[index + 0x2a] | (rom[index + 0x2b] << 8), //NMI
rom[index + 0x2e] | (rom[index + 0x2f] << 8), //IRQ
rom[index + 0x26] | (rom[index + 0x27] << 8), //BRK[n]
rom[index + 0x24] | (rom[index + 0x25] << 8), //COP[n]
rom[index + 0x3e] | (rom[index + 0x3f] << 8), //BRK[e]
rom[index + 0x34] | (rom[index + 0x35] << 8) //COP[e]
);
dprintf("");
CartInfo ci;
ci.rom = rom;
ci.sram = sram;
ci.rom_size = rom_size;
ci.sram_size = sram_size;
switch(mapper) {
case LOROM: cart = new bCartLoROM(); break;
case HIROM: cart = new bCartHiROM(); break;
case EXHIROM:cart = new bCartExHiROM();break;
default:return false;
}
cart->set_cartinfo(&ci);
rom_loaded = true;
return true;
}
void bROM::unload() {
bool bMemBus::load_sram(Reader *rf) {
if(rom_loaded == false || sram_size == 0)return false;
rf->read(&sram, sram_size);
CartInfo ci;
ci.rom = rom;
ci.sram = sram;
ci.rom_size = rom_size;
ci.sram_size = sram_size;
cart->set_cartinfo(&ci);
return true;
}
bool bMemBus::save_sram(Writer *wf) {
if(rom_loaded == false || sram_size == 0)return false;
wf->write(sram, sram_size);
return true;
}
void bMemBus::unload_cart() {
if(rom_loaded == false)return;
if(data)memfree(data, "bROM::data");
if(sram_data)memfree(sram_data, "bROM::sram_data");
if(rom) free(rom);
if(sram)free(sram);
delete(cart);
rom_loaded = false;
}
void bROM::write_protect(bool yn) {
write_protection = yn;
}
bROM::bROM() {
sram_size = 0;
sram_data = 0;
write_protection = true;
rom_loaded = false;
}
bROM::~bROM() {
void bMemBus::get_cartinfo(CartInfo *ci) {
ci->rom = rom;
ci->sram = sram;
ci->rom_size = rom_size;
ci->sram_size = sram_size;
}
/***********************
@ -235,10 +150,10 @@ uint32 b, w, r;
} else if(w <= 0x5fff) {
r = mmio[w - 0x2000]->read(w);
} else {
r = rom->read(addr);
r = cart->read(addr);
}
} else if(b <= 0x7d) {
r = rom->read(addr);
r = cart->read(addr);
} else if(b <= 0x7f) {
r = wram[addr & 0x01ffff];
} else if(b <= 0xbf) {
@ -247,10 +162,10 @@ uint32 b, w, r;
} else if(w <= 0x5fff) {
r = mmio[w - 0x2000]->read(w);
} else {
r = rom->read(addr);
r = cart->read(addr);
}
} else {
r = rom->read(addr);
r = cart->read(addr);
}
snes->notify(SNES::MEM_READ, addr, r);
@ -269,10 +184,10 @@ uint32 b, w;
} else if(w <= 0x5fff) {
mmio[w - 0x2000]->write(w, value);
} else {
rom->write(addr, value);
cart->write(addr, value);
}
} else if(b <= 0x7d) {
rom->write(addr, value);
cart->write(addr, value);
} else if(b <= 0x7f) {
wram[addr & 0x01ffff] = value;
} else if(b <= 0xbf) {
@ -281,10 +196,10 @@ uint32 b, w;
} else if(w <= 0x5fff) {
mmio[w - 0x2000]->write(w, value);
} else {
rom->write(addr, value);
cart->write(addr, value);
}
} else {
rom->write(addr, value);
cart->write(addr, value);
}
snes->notify(SNES::MEM_WRITE, addr, value);
@ -300,14 +215,11 @@ void bMemBus::reset() {
}
bMemBus::bMemBus() {
rom = new bROM();
wram = (byte*)memalloc(0x020000, "bMemBus::wram");
wram = (byte*)malloc(0x020000);
memset(wram, 0, 0x020000);
rom_loaded = false;
}
bMemBus::~bMemBus() {
delete(rom);
if(wram)memfree(wram, "bMemBus::wram");
if(wram)free(wram);
}

View File

@ -1,31 +1,24 @@
class bROM : public ROM {
private:
bool write_protection;
bool rom_loaded;
public:
enum { LOROM = 0, HIROM = 1 };
uint8 *data, *sram_data;
uint8 mapper;
uint32 size, sram_size;
void load_rom(Reader *rf);
void load_sram(Reader *rf);
void save_sram(Writer *wf);
void unload();
uint8 read (uint32 addr);
void write(uint32 addr, byte value);
void write_protect(bool yn);
bROM();
~bROM();
};
#include "bcart_lorom.h"
#include "bcart_hirom.h"
#include "bcart_exhirom.h"
class bMemBus : public MemBus {
public:
byte *wram;
uint8 *rom, *sram, *wram;
uint32 rom_size, sram_size;
bool rom_loaded;
enum { LOROM = 0x20, HIROM = 0x21, EXHIROM = 0x25 };
uint8 read (uint32 addr);
void write(uint32 addr, byte value);
bool load_cart(Reader *rf);
bool load_sram(Reader *rf);
bool save_sram(Writer *wf);
void unload_cart();
void get_cartinfo(CartInfo *ci);
void power();
void reset();

View File

@ -9,13 +9,15 @@ enum { WRAP_NONE = 0, WRAP_BANK = 1, WRAP_PAGE = 2 };
virtual void write_long(uint32 addr, uint32 value, uint8 wrap = WRAP_NONE);
};
class ROM : public Memory {
typedef struct {
uint8 *rom, *sram;
uint32 rom_size, sram_size;
}CartInfo;
class Cart : public Memory {
public:
virtual void load_rom(Reader *rf) = 0;
virtual void load_sram(Reader *rf) = 0;
virtual void save_sram(Writer *wf) = 0;
virtual void unload() = 0;
virtual void write_protect(bool yn) = 0;
virtual void write_protect(bool r) = 0;
virtual void set_cartinfo(CartInfo *ci) = 0;
};
class MMIO : public Memory {
@ -26,13 +28,19 @@ public:
class MemBus : public Memory {
public:
ROM *rom;
Cart *cart;
MMIO *mmio[0x4000];
bool fastROM;
virtual void flush_mmio_mappers();
virtual bool set_mmio_mapper(uint16 addr, MMIO *mapper);
virtual uint8 speed(uint32 addr);
virtual bool load_cart(Reader *rf) = 0;
virtual bool load_sram(Reader *rf) = 0;
virtual bool save_sram(Writer *wf) = 0;
virtual void unload_cart() = 0;
virtual void get_cartinfo(CartInfo *ci) = 0;
virtual void power() = 0;
virtual void reset() = 0;

View File

@ -1,21 +1,39 @@
#include "../../base.h"
#include "bppu_mmio.cpp"
#ifdef _BPPU_OLDRENDER
#include "bppu_old_render.cpp"
#else
#include "bppu_render.cpp"
#endif
void bPPU::run() {}
void bPPU::scanline() {
_y = clock->vcounter();
_y = cpu->vcounter();
_screen_width = (regs.bg_mode == 5 || regs.bg_mode == 6)?512:256;
_interlace = clock->interlace();
_interlace_field = clock->interlace_field();
_interlace = cpu->interlace();
_interlace_field = cpu->interlace_field();
if(_y > 0 && _y < clock->visible_scanlines()) {
if(_y == 0) {
//RTO flag reset
regs.time_over = false;
regs.range_over = false;
}
if(_y == 1) {
//OAM FirstSprite priority set
if(regs.oam_priority == true) {
regs.oam_firstsprite = (regs.oam_addr & 0xfe) >> 1;
} else {
regs.oam_firstsprite = 0;
}
}
if(_y == (cpu->overscan()?239:224) && regs.display_disabled == false) {
//OAM address reset
regs.oam_addr = ((regs.oam_addrh << 8) | regs.oam_addrl) << 1;
}
//only allow frameskip setting to ignore actual rendering; not RTO, etc.
if(settings.frameskip_pos != 0)return;
if(_y > 0 && _y < (cpu->overscan()?239:224)) {
if(regs.bg_mode == 5 || regs.bg_mode == 6) {
output->hires = true;
output->line[_y].hires = true;
@ -29,6 +47,16 @@ void bPPU::scanline() {
}
void bPPU::frame() {
if(settings.frameskip_changed == true) {
settings.frameskip_changed = false;
settings.frameskip_pos = 0;
} else {
settings.frameskip_pos++;
settings.frameskip_pos %= (settings.frameskip + 1);
}
if(settings.frameskip_pos != 0)return;
snes->notify(SNES::RENDER_FRAME);
output->hires = false;
output->interlace = false;
@ -38,6 +66,11 @@ void bPPU::frame() {
}
}
void bPPU::set_frameskip(int fs) {
settings.frameskip = fs;
settings.frameskip_changed = true;
}
void bPPU::power() {
memset(vram, 0, 65536);
memset(oam, 0, 544);
@ -49,6 +82,8 @@ void bPPU::reset() {
memset(output->buffer, 0, 512 * 478 * 2);
frame();
memset(sprite_list, 0, sizeof(sprite_list));
//$2100
regs.display_disabled = 0;
regs.display_brightness = 0;
@ -59,10 +94,12 @@ void bPPU::reset() {
regs.oam_tdaddr = 0x0000;
//$2102-$2103
regs.oam_addrl = 0x00;
regs.oam_addrh = 0x00;
regs.oam_addr = 0x0000;
regs.oam_latchdata = 0x00;
regs.oam_addrl = 0x00;
regs.oam_addrh = 0x00;
regs.oam_addr = 0x0000;
regs.oam_latchdata = 0x00;
regs.oam_priority = false;
regs.oam_firstsprite = 0x00;
//$2105
regs.bg_tilesize[BG1] = 0;
@ -226,6 +263,11 @@ void bPPU::reset() {
//$2139-$213a
regs.vram_readbuffer = 0x0000;
//$213e
regs.time_over = false;
regs.range_over = false;
update_sprite_list_sizes();
clear_tiledata_cache();
}
@ -252,6 +294,7 @@ uint8 r;
void bPPU::oam_write(uint16 addr, uint8 value) {
if(addr >= 0x0200)addr = 0x0200 | (addr & 31);
oam[addr] = value;
update_sprite_list(addr);
snes->notify(SNES::OAM_WRITE, addr, value);
}
@ -268,6 +311,10 @@ void bPPU::cgram_write(uint16 addr, uint8 value) {
}
bPPU::bPPU() {
settings.frameskip = 0;
settings.frameskip_pos = 0;
settings.frameskip_changed = false;
mmio = new bPPUMMIO(this);
vram = (uint8*)memalloc(65536, "bPPU::vram");
@ -301,9 +348,9 @@ uint16 *ptr;
if(l == 0) { r = g = b = 0; }
else if(l == 15);
else {
r = (double)r * m;
g = (double)g * m;
b = (double)b * m;
r = (uint8)((double)r * m);
g = (uint8)((double)g * m);
b = (uint8)((double)b * m);
}
*ptr++ = (r) | (g << 5) | (b << 10);
}

View File

@ -1,5 +1,3 @@
//#define _BPPU_OLDRENDER
class bPPU;
class bPPUMMIO : public MMIO {
@ -17,6 +15,21 @@ uint8 *vram, *oam, *cgram;
enum { BG1 = 0, BG2 = 1, BG3 = 2, BG4 = 3, OAM = 4, BACK = 5 };
enum { SC_32x32 = 0, SC_32x64 = 1, SC_64x32 = 2, SC_64x64 = 3 };
struct sprite_item {
uint8 width, height;
uint16 x, y;
uint8 character;
bool use_nameselect;
bool vflip, hflip;
uint8 palette;
uint8 priority;
}sprite_list[128];
struct {
int32 frameskip, frameskip_pos;
bool frameskip_changed;
}settings;
struct {
//$2100
bool display_disabled;
@ -31,6 +44,8 @@ struct {
uint8 oam_addrl, oam_addrh;
uint16 oam_addr;
uint8 oam_latchdata;
bool oam_priority;
uint8 oam_firstsprite;
//$2105
bool bg_tilesize[4];
@ -118,6 +133,10 @@ struct {
//$2139-$213a
uint16 vram_readbuffer;
//$213e
bool time_over, range_over;
uint16 oam_itemcount, oam_tilecount;
}regs;
uint8 vram_read (uint16 addr);
void vram_write (uint16 addr, uint8 value);
@ -126,6 +145,9 @@ struct {
uint8 cgram_read (uint16 addr);
void cgram_write(uint16 addr, uint8 value);
void get_sprite_size(int i, bool size);
void update_sprite_list(uint16 addr);
void update_sprite_list_sizes();
uint16 get_vram_address();
void mmio_w2100(uint8 value); //INIDISP
@ -197,22 +219,20 @@ struct {
/* PPU render functions */
#ifdef _BPPU_OLDRENDER
#include "bppu_old_render.h"
#else
#include "bppu_render.h"
#endif
uint16 *light_table;
uint16 *mosaic_table[16];
void render_line();
void update_oam_status();
/* Required functions */
void run();
void scanline();
void frame();
void power();
void reset();
void set_frameskip(int fs);
bPPU();
~bPPU();

View File

@ -1,6 +1,6 @@
void bPPU::latch_counters() {
regs.hcounter = clock->hcounter();
regs.vcounter = clock->vcounter();
regs.hcounter = cpu->hcounter();
regs.vcounter = cpu->vcounter();
regs.counters_latched = true;
}
@ -27,6 +27,7 @@ void bPPU::mmio_w2101(uint8 value) {
regs.oam_basesize = (value >> 5) & 7;
regs.oam_nameselect = (value >> 3) & 3;
regs.oam_tdaddr = (value & 3) << 14;
update_sprite_list_sizes();
}
//OAMADDL
@ -37,8 +38,9 @@ void bPPU::mmio_w2102(uint8 value) {
//OAMADDH
void bPPU::mmio_w2103(uint8 value) {
regs.oam_addrh = value & 1;
regs.oam_addr = ((regs.oam_addrh << 8) | regs.oam_addrl) << 1;
regs.oam_priority = !!(value & 0x80);
regs.oam_addrh = value & 1;
regs.oam_addr = ((regs.oam_addrh << 8) | regs.oam_addrl) << 1;
}
//OAMDATA
@ -168,11 +170,17 @@ void bPPU::mmio_w2115(uint8 value) {
//VMADDL
void bPPU::mmio_w2116(uint8 value) {
regs.vram_addr = (regs.vram_addr & 0xff00) | value;
uint16 addr = get_vram_address();
regs.vram_readbuffer = vram_read(addr);
regs.vram_readbuffer |= vram_read(addr + 1) << 8;
}
//VMADDH
void bPPU::mmio_w2117(uint8 value) {
regs.vram_addr = (value << 8) | (regs.vram_addr & 0x00ff);
uint16 addr = get_vram_address();
regs.vram_readbuffer = vram_read(addr);
regs.vram_readbuffer |= vram_read(addr + 1) << 8;
}
//VMDATAL
@ -388,8 +396,8 @@ void bPPU::mmio_w2133(uint8 value) {
regs.oam_halve = !!(value & 0x02);
regs.interlace = !!(value & 0x01);
clock->enable_overscan(regs.overscan);
clock->enable_interlace(regs.interlace);
cpu->set_overscan(regs.overscan);
cpu->set_interlace(regs.interlace);
}
//MPYL
@ -487,6 +495,8 @@ uint16 r = regs.vcounter;
//STAT77
uint8 bPPU::mmio_r213e() {
uint8 r = 0x00;
r |= (regs.time_over) ?0x80:0x00;
r |= (regs.range_over)?0x40:0x00;
r |= 0x01; //PPU1 version number
return r;
}
@ -497,7 +507,7 @@ uint8 r = 0x00;
regs.latch_hcounter = 0;
regs.latch_vcounter = 0;
r |= clock->interlace_field() << 7;
r |= cpu->interlace_field() << 7;
if(!(cpu->pio_status() & 0x80)) {
r |= 1 << 6;
} else if(regs.counters_latched == true) {
@ -510,7 +520,7 @@ uint8 r = 0x00;
}
uint8 bPPUMMIO::read(uint32 addr) {
clock->sync();
//cpu->sync();
switch(addr) {
case 0x2134:return ppu->mmio_r2134(); //MPYL
case 0x2135:return ppu->mmio_r2135(); //MPYM
@ -524,36 +534,12 @@ uint8 bPPUMMIO::read(uint32 addr) {
case 0x213d:return ppu->mmio_r213d(); //OPVCT
case 0x213e:return ppu->mmio_r213e(); //STAT77
case 0x213f:return ppu->mmio_r213f(); //STAT78
case 0x2140:case 0x2141:case 0x2142:case 0x2143:
static uint8 t = 0, counter = 0;
uint8 x, port = (addr & 3);
if(rand() & 1) {
x = rand() & 7;
if(x == 0) {
if(!(port & 1))t = cpu->regs.a;
else t = cpu->regs.a >> 8;
}
else if(x == 1) {
if(!(port & 1))t = cpu->regs.x;
else t = cpu->regs.x >> 8;
}
else if(x == 2) {
if(!(port & 1))t = cpu->regs.y;
else t = cpu->regs.y >> 8;
}
else if(x == 3)t = 0xaa;
else if(x == 4)t = 0xbb;
else if(x == 5)t = 0xcc;
else { t = counter++; }
}
return t;
}
return 0x00;
}
void bPPUMMIO::write(uint32 addr, uint8 value) {
clock->sync();
//cpu->sync();
switch(addr) {
case 0x2100:ppu->mmio_w2100(value);return; //INIDISP
case 0x2101:ppu->mmio_w2101(value);return; //OBSEL

View File

@ -1,133 +0,0 @@
#include "bppu_old_render_cache.cpp"
#include "bppu_old_render_windows.cpp"
#include "bppu_old_render_main.cpp"
#include "bppu_old_render_mode7.cpp"
namespace bPPURenderTables {
enum { BG1 = 0, BG2 = 1, BG3 = 2, BG4 = 3, OAM = 4, BACK = 5 };
uint8 lookup_mode0[12] = {
BG4, BG3, OAM, BG4, BG3, OAM, BG2, BG1, OAM, BG2, BG1, OAM
};
uint8 lookup_mode1_pri0[10] = {
BG3, OAM, BG3, OAM, BG2, BG1, OAM, BG2, BG1, OAM
};
uint8 lookup_mode1_pri1[10] = {
BG3, OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM, BG3
};
uint8 lookup_mode2[8] = {
OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM
};
uint8 lookup_mode3[8] = {
OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM
};
uint8 lookup_mode4[8] = {
OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM
};
uint8 lookup_mode5[8] = {
OAM, OAM, BG2, BG1, OAM, BG2, BG1, OAM
};
uint8 lookup_mode6[6] = {
OAM, OAM, BG1, OAM, BG1, OAM
};
uint8 lookup_mode7[5] = {
OAM, BG1, OAM, OAM, OAM
};
uint8 lookup_mode7_extbg[6] = {
BG2, OAM, OAM, BG2, OAM, OAM
};
};
void bPPU::render_line_mode0() {
render_line_bg (7, 10, COLORDEPTH_4, BG1);
render_line_bg (6, 9, COLORDEPTH_4, BG2);
render_line_bg (1, 4, COLORDEPTH_4, BG3);
render_line_bg (0, 3, COLORDEPTH_4, BG4);
render_line_oam(2, 5, 8, 11);
set_layer_pixels(12, bPPURenderTables::lookup_mode0);
}
void bPPU::render_line_mode1() {
switch(regs.bg3_priority) {
case 0:
render_line_bg (5, 8, COLORDEPTH_16, BG1);
render_line_bg (4, 7, COLORDEPTH_16, BG2);
render_line_bg (0, 2, COLORDEPTH_4, BG3);
render_line_oam(1, 3, 6, 9);
set_layer_pixels(10, bPPURenderTables::lookup_mode1_pri0);
break;
case 1:
render_line_bg (4, 7, COLORDEPTH_16, BG1);
render_line_bg (3, 6, COLORDEPTH_16, BG2);
render_line_bg (0, 9, COLORDEPTH_4, BG3);
render_line_oam(1, 2, 5, 8);
set_layer_pixels(10, bPPURenderTables::lookup_mode1_pri1);
break;
}
}
void bPPU::render_line_mode2() {
render_line_bg (3, 6, COLORDEPTH_16, BG1);
render_line_bg (2, 5, COLORDEPTH_16, BG2);
render_line_oam(0, 1, 4, 7);
set_layer_pixels(8, bPPURenderTables::lookup_mode2);
}
void bPPU::render_line_mode3() {
render_line_bg (3, 6, COLORDEPTH_256, BG1);
render_line_bg (2, 5, COLORDEPTH_16, BG2);
render_line_oam(0, 1, 4, 7);
set_layer_pixels(8, bPPURenderTables::lookup_mode3);
}
void bPPU::render_line_mode4() {
render_line_bg (3, 6, COLORDEPTH_256, BG1);
render_line_bg (2, 5, COLORDEPTH_4, BG2);
render_line_oam(0, 1, 4, 7);
set_layer_pixels(8, bPPURenderTables::lookup_mode4);
}
void bPPU::render_line_mode5() {
render_line_bg (3, 6, COLORDEPTH_16, BG1);
render_line_bg (2, 5, COLORDEPTH_4, BG2);
render_line_oam(0, 1, 4, 7);
set_layer_pixels(8, bPPURenderTables::lookup_mode5);
}
void bPPU::render_line_mode6() {
render_line_bg (2, 4, COLORDEPTH_16, BG1);
render_line_oam(0, 1, 3, 5);
set_layer_pixels(8, bPPURenderTables::lookup_mode6);
}
void bPPU::render_line_mode7() {
if(regs.mode7_extbg == false) {
render_line_m7 (1, 0, 0); //bg2 priorities are ignored
render_line_oam(0, 2, 3, 4);
set_layer_pixels(5, bPPURenderTables::lookup_mode7);
} else {
render_line_m7 (0, 0, 3); //bg1 priority is ignored
render_line_oam(1, 2, 4, 5);
set_layer_pixels(6, bPPURenderTables::lookup_mode7_extbg);
}
}
void bPPU::render_line() {
if(regs.display_disabled == true) {
memset(output->buffer + (_y << 1) * 512, 0, 2048);
return;
}
clear_layer_cache();
clear_pixel_cache();
switch(regs.bg_mode) {
case 0:render_line_mode0();break;
case 1:render_line_mode1();break;
case 2:render_line_mode2();break;
case 3:render_line_mode3();break;
case 4:render_line_mode4();break;
case 5:render_line_mode5();break;
case 6:render_line_mode6();break;
case 7:render_line_mode7();break;
}
render_line_to_output();
}

View File

@ -1,70 +0,0 @@
//bppu_render.cpp
void render_line_mode0();
void render_line_mode1();
void render_line_mode2();
void render_line_mode3();
void render_line_mode4();
void render_line_mode5();
void render_line_mode6();
void render_line_mode7();
//bppu_render_cache.cpp
enum { BLENDTYPE_BACK = 0, BLENDTYPE_MAIN = 1, BLENDTYPE_SUB = 2, BLENDTYPE_COMBINE = 3 };
enum { COLORDEPTH_4 = 0, COLORDEPTH_16 = 1, COLORDEPTH_256 = 2 };
enum { TILE_2BIT = 0, TILE_4BIT = 1, TILE_8BIT = 2 };
struct {
uint8 color_main, color_sub;
uint8 src_main, src_sub;
uint8 blend_type;
}pixel_cache[512];
uint8 layer_cache[512 * 12];
uint8 *bg_tiledata[3];
uint8 *bg_tiledata_state[3];
void clear_pixel_cache(void);
void clear_layer_cache(void);
void init_tiledata_cache(void);
void clear_tiledata_cache(void);
//bppu_render_windows.cpp
enum { WINDOWMASK_OR = 0, WINDOWMASK_AND = 1, WINDOWMASK_XOR = 2, WINDOWMASK_XNOR = 3 };
bool windows_not_obstructing(uint8 layer, uint8 bg, uint16 x);
bool color_windows_not_obstructing(uint16 x, uint8 color_mask_type);
//bppu_render_main.cpp
enum {
SH_2 = 1, SH_4 = 2, SH_8 = 3, SH_16 = 4,
SH_32 = 5, SH_64 = 6, SH_128 = 7, SH_256 = 8,
SH_512 = 9, SH_1024 = 10, SH_2048 = 11, SH_4096 = 12
};
enum { COLORMODE_ADD = 0, COLORMODE_SUB = 1 };
enum { PPU_MAIN = 0, PPU_SUB = 1 };
enum { OAM_PRI_NONE = 4 };
uint8 oam_line_pal[512], oam_line_pri[512];
struct {
byte num;
byte width, height;
word x, y;
word character;
byte v_flip, h_flip;
byte palette;
byte priority;
}current_sprite;
void render_line_to_output();
inline uint16 addsub_pixels(uint8 x, uint8 cdest_index, uint8 cdest_bg, uint8 csrc_index, uint8 csrc_bg);
inline uint16 addsub_pixel(uint8 x, uint8 cdest_index, uint8 cdest_bg);
void render_bg_tile(uint8 color_depth, uint8 bg, uint16 tile_num);
void set_pixel(uint8 bg, uint16 x, uint8 pal_index);
void set_layer_pixels(uint8 layer_count, uint8 *layer_bg_lookup);
void set_sprite_attributes(uint8 sprite_num);
void render_oam_sprite(void);
void render_line_oam(uint8 layer_pos_pri0, uint8 layer_pos_pri1, uint8 layer_pos_pri2, uint8 layer_pos_pri3);
void render_line_bg(uint8 layer_pos_pri0, uint8 layer_pos_pri1, uint8 color_depth, uint8 bg);
//bppu_render_mode7.cpp
void render_line_m7(uint8 layer_pos_bg1, uint8 layer_pos_bg2_pri0, uint8 layer_pos_bg2_pri1);

View File

@ -1,33 +0,0 @@
//this should be reset once every scanline
void bPPU::clear_pixel_cache(void) {
for(int i=0;i<512;i++) {
pixel_cache[i].color_main = 0;
pixel_cache[i].color_sub = 0;
pixel_cache[i].src_main = BACK;
pixel_cache[i].src_sub = BACK;
pixel_cache[i].blend_type = BLENDTYPE_BACK;
}
}
//this should be reset once every scanline
void bPPU::clear_layer_cache(void) {
memset(&layer_cache, 0, 512 * 12);
}
void bPPU::init_tiledata_cache(void) {
bg_tiledata[TILE_2BIT] = (uint8*)malloc(262144);
bg_tiledata[TILE_4BIT] = (uint8*)malloc(131072);
bg_tiledata[TILE_8BIT] = (uint8*)malloc( 65536);
bg_tiledata_state[TILE_2BIT] = (uint8*)malloc( 4096);
bg_tiledata_state[TILE_4BIT] = (uint8*)malloc( 2048);
bg_tiledata_state[TILE_8BIT] = (uint8*)malloc( 1024);
}
void bPPU::clear_tiledata_cache(void) {
memset(bg_tiledata[TILE_2BIT], 0, 262144);
memset(bg_tiledata[TILE_4BIT], 0, 131072);
memset(bg_tiledata[TILE_4BIT], 0, 65536);
memset(bg_tiledata_state[TILE_2BIT], 0, 4096);
memset(bg_tiledata_state[TILE_4BIT], 0, 2048);
memset(bg_tiledata_state[TILE_8BIT], 0, 1024);
}

View File

@ -1,696 +0,0 @@
#define set_layer_pixel(__x, __c) layer_cache[(__x) * 12 + layer_pos] = __c
#define pal_pixel(__i) (*((uint16*)cgram + __i))
namespace bPPUAddSubTables {
uint8 adjust_buffer_full[96] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31
};
uint8 adjust_buffer_half[96] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63
};
};
inline uint16 bPPU::addsub_pixels(uint8 x, uint8 cdest_index, uint8 cdest_bg, uint8 csrc_index, uint8 csrc_bg) {
int r, g, b;
uint16 cdest = pal_pixel(cdest_index);
uint16 csrc = pal_pixel(csrc_index);
uint16 res;
//oam palettes 0-3 are not affected by color add/sub
if(cdest_bg == OAM) {
if(cdest_index < 192) {
return cdest;
}
}
switch(regs.color_mode) {
case COLORMODE_ADD:
if(regs.bg_color_enabled[cdest_bg] == true && regs.color_halve == true) {
r = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )) >> 1;
g = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )) >> 1;
b = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )) >> 1;
} else {
r = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) ));
g = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) ));
b = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) ));
}
break;
case COLORMODE_SUB:
if(regs.bg_color_enabled[cdest_bg] == true && regs.color_halve == true) {
r = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )) >> 1;
g = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )) >> 1;
b = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )) >> 1;
} else {
r = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest ) & 31) - ((csrc ) & 31) ));
g = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 5) & 31) - ((csrc >> 5) & 31) ));
b = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 10) & 31) - ((csrc >> 10) & 31) ));
}
break;
}
return ((r) | (g << 5) | (b << 10));
}
inline uint16 bPPU::addsub_pixel(uint8 x, uint8 cdest_index, uint8 cdest_bg) {
int r, g, b;
uint16 cdest = pal_pixel(cdest_index);
uint16 csrc = (regs.color_r) | (regs.color_g << 5) | (regs.color_b << 10);
uint16 res;
//only oam palettes 4-7 are affected by color add/sub
if(cdest_bg == OAM) {
if(cdest_index < 192) {
return cdest;
}
}
switch(regs.color_mode) {
case COLORMODE_ADD:
if(regs.bg_color_enabled[cdest_bg] == true && regs.color_halve == true && regs.addsub_mode == 0) {
r = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )) >> 1;
g = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )) >> 1;
b = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )) >> 1;
} else {
r = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) ));
g = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) ));
b = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) ));
}
break;
case COLORMODE_SUB:
if(regs.bg_color_enabled[cdest_bg] == true && regs.color_halve == true && regs.addsub_mode == 0) {
r = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest ) & 31) + ((csrc ) & 31) )) >> 1;
g = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 5) & 31) + ((csrc >> 5) & 31) )) >> 1;
b = *(bPPUAddSubTables::adjust_buffer_half + 32 + ( ((cdest >> 10) & 31) + ((csrc >> 10) & 31) )) >> 1;
} else {
r = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest ) & 31) - ((csrc ) & 31) ));
g = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 5) & 31) - ((csrc >> 5) & 31) ));
b = *(bPPUAddSubTables::adjust_buffer_full + 32 + ( ((cdest >> 10) & 31) - ((csrc >> 10) & 31) ));
}
break;
}
return ((r) | (g << 5) | (b << 10));
}
#define render_bg_tile_line_4(__m) \
col = 0; \
if(d0 & __m)col += 1; \
if(d1 & __m)col += 2; \
*dest++ = col
#define render_bg_tile_line_16(__m) \
col = 0; \
if(d0 & __m)col += 1; \
if(d1 & __m)col += 2; \
if(d2 & __m)col += 4; \
if(d3 & __m)col += 8; \
*dest++ = col
#define render_bg_tile_line_256(__m) \
col = 0; \
if(d0 & __m)col += 1; \
if(d1 & __m)col += 2; \
if(d2 & __m)col += 4; \
if(d3 & __m)col += 8; \
if(d4 & __m)col += 16; \
if(d5 & __m)col += 32; \
if(d6 & __m)col += 64; \
if(d7 & __m)col += 128; \
*dest++ = col
void bPPU::render_bg_tile(uint8 color_depth, uint8 bg, uint16 tile_num) {
uint8 mask, d0, d1, d2, d3, d4, d5, d6, d7, col;
int x, y;
uint32 pos;
uint8 *dest;
switch(color_depth) {
case COLORDEPTH_4:
dest = (uint8*)bg_tiledata[TILE_2BIT] + tile_num * 64;
pos = tile_num * 16;
y = 8;
while(y--) {
d0 = vram[pos ];
d1 = vram[pos + 1];
render_bg_tile_line_4(0x80);
render_bg_tile_line_4(0x40);
render_bg_tile_line_4(0x20);
render_bg_tile_line_4(0x10);
render_bg_tile_line_4(0x08);
render_bg_tile_line_4(0x04);
render_bg_tile_line_4(0x02);
render_bg_tile_line_4(0x01);
pos += 2;
}
bg_tiledata_state[TILE_2BIT][tile_num] = 0;
break;
case COLORDEPTH_16:
dest = (uint8*)bg_tiledata[TILE_4BIT] + tile_num * 64;
pos = tile_num * 32;
y = 8;
while(y--) {
d0 = vram[pos ];
d1 = vram[pos + 1];
d2 = vram[pos + 16];
d3 = vram[pos + 17];
render_bg_tile_line_16(0x80);
render_bg_tile_line_16(0x40);
render_bg_tile_line_16(0x20);
render_bg_tile_line_16(0x10);
render_bg_tile_line_16(0x08);
render_bg_tile_line_16(0x04);
render_bg_tile_line_16(0x02);
render_bg_tile_line_16(0x01);
pos += 2;
}
bg_tiledata_state[TILE_4BIT][tile_num] = 0;
break;
case COLORDEPTH_256:
dest = (uint8*)bg_tiledata[TILE_8BIT] + tile_num * 64;
pos = tile_num * 64;
y = 8;
while(y--) {
d0 = vram[pos ];
d1 = vram[pos + 1];
d2 = vram[pos + 16];
d3 = vram[pos + 17];
d4 = vram[pos + 32];
d5 = vram[pos + 33];
d6 = vram[pos + 48];
d7 = vram[pos + 49];
render_bg_tile_line_256(0x80);
render_bg_tile_line_256(0x40);
render_bg_tile_line_256(0x20);
render_bg_tile_line_256(0x10);
render_bg_tile_line_256(0x08);
render_bg_tile_line_256(0x04);
render_bg_tile_line_256(0x02);
render_bg_tile_line_256(0x01);
pos += 2;
}
bg_tiledata_state[TILE_8BIT][tile_num] = 0;
break;
}
}
void bPPU::render_line_to_output() {
int x, x1;
uint16 *ptr, *ltable;
uint16 c, cx, cy;
uint16 screen_width;
uint16 v, vline_pos = clock->vcounter();
v = vline_pos;
screen_width = (output->line[v].hires)?512:256;
if(output->line[v].interlace == false) {
ptr = (uint16*)output->buffer + ((vline_pos << 1)) * 512;
} else {
ptr = (uint16*)output->buffer + ((vline_pos << 1) + clock->interlace_field()) * 512;
}
ltable = (uint16*)light_table + (regs.display_brightness * 65536);
for(x=x1=0;x<screen_width;x++) {
switch(pixel_cache[x].blend_type) {
case BLENDTYPE_BACK:
if(color_windows_not_obstructing(x, PPU_MAIN) == true) {
cx = 0x0000;
} else if(regs.bg_color_enabled[BACK] == true && color_windows_not_obstructing(x, PPU_SUB) == false) {
cx = addsub_pixel(x, 0, BACK);
} else {
cx = pal_pixel(0);
}
break;
case BLENDTYPE_MAIN:
if(regs.bg_color_enabled[pixel_cache[x].src_main] == true && color_windows_not_obstructing(x, PPU_MAIN) == true) {
cx = 0x0000;
} else if(regs.bg_color_enabled[pixel_cache[x].src_main] == true && color_windows_not_obstructing(x, PPU_SUB) == false) {
cx = addsub_pixel(x, pixel_cache[x].color_main, pixel_cache[x].src_main);
} else {
cx = pal_pixel(pixel_cache[x].color_main);
}
break;
case BLENDTYPE_SUB:
if(regs.bg_color_enabled[BACK] && color_windows_not_obstructing(x, PPU_SUB) == false) {
cx = addsub_pixels(x, 0, BACK, pixel_cache[x].color_sub, pixel_cache[x].src_sub);
} else {
cx = pal_pixel(pixel_cache[x].color_sub);
}
break;
case BLENDTYPE_COMBINE:
if(color_windows_not_obstructing(x, PPU_SUB) == false) {
if(pixel_cache[x].src_sub == BACK) {
cx = addsub_pixels(x, pixel_cache[x].color_main, pixel_cache[x].src_main, 0, BACK);
} else {
cx = addsub_pixels(x, pixel_cache[x].color_main, pixel_cache[x].src_main,
pixel_cache[x].color_sub, pixel_cache[x].src_sub);
}
} else {
cx = pal_pixel(pixel_cache[x].color_main);
}
break;
}
if(screen_width == 256) {
*(ptr + (x1)) = *(ltable + cx);
x1 += 2;
} else {
*(ptr + (x1)) = *(ltable + cx);
x1 += 1;
}
}
}
void bPPU::set_pixel(uint8 bg, uint16 x, uint8 pal_index) {
if(regs.bg_enabled[bg] == true && regs.bgsub_enabled[bg] == true) {
if(windows_not_obstructing(PPU_MAIN, bg, x) == false)return;
pixel_cache[x].blend_type = BLENDTYPE_MAIN;
pixel_cache[x].src_main = bg;
pixel_cache[x].color_main = pal_index;
if(color_windows_not_obstructing(x, PPU_SUB) == false) {
pixel_cache[x].src_sub = bg;
pixel_cache[x].color_sub = pal_index;
}
} else if(regs.bg_enabled[bg] == true && bg == OAM && pal_index < 192) {
if(windows_not_obstructing(PPU_MAIN, bg, x) == false)return;
pixel_cache[x].blend_type = BLENDTYPE_MAIN;
pixel_cache[x].src_main = bg;
pixel_cache[x].color_main = pal_index;
} else if(regs.bg_enabled[bg] == true) {
if(windows_not_obstructing(PPU_MAIN, bg, x) == false)return;
if(regs.bg_color_enabled[bg] == true && pixel_cache[x].src_sub != BACK) {
pixel_cache[x].blend_type = BLENDTYPE_COMBINE;
} else {
pixel_cache[x].blend_type = BLENDTYPE_MAIN;
}
pixel_cache[x].src_main = bg;
pixel_cache[x].color_main = pal_index;
} else if(regs.bgsub_enabled[bg] == true) {
if(windows_not_obstructing(PPU_SUB, bg, x) == false)return;
pixel_cache[x].src_sub = bg;
pixel_cache[x].color_sub = pal_index;
if(pixel_cache[x].blend_type == BLENDTYPE_BACK) {
pixel_cache[x].blend_type = BLENDTYPE_SUB;
} else if(pixel_cache[x].blend_type == BLENDTYPE_MAIN) {
if(pixel_cache[x].src_main != OAM || (pixel_cache[x].src_main == OAM && pixel_cache[x].color_main >= 192)) {
if(regs.bg_color_enabled[pixel_cache[x].src_main] == true) {
pixel_cache[x].blend_type = BLENDTYPE_COMBINE;
}
}
}
}
}
void bPPU::set_layer_pixels(uint8 layer_count, uint8 *layer_bg_lookup) {
int layer, x = 0, x1;
uint8 pal;
uint16 width = (regs.bg_mode == 5 || regs.bg_mode == 6)?512:256;
do {
layer = 0;
x1 = x * 12;
do {
pal = layer_cache[x1 + layer];
if(pal) {
set_pixel(layer_bg_lookup[layer], x, pal);
}
layer++;
} while(layer < layer_count);
x++;
} while(x < width);
}
void bPPU::set_sprite_attributes(uint8 sprite_num) {
uint32 t;
uint8 size, b;
uint16 x;
t = *((uint32*)oam + sprite_num);
b = oam[512 + (sprite_num >> 2)];
switch(sprite_num & 3) {
case 0: size = !!(b & 0x02); x = (b & 0x01)?0x100:0; break;
case 1: size = !!(b & 0x08); x = (b & 0x04)?0x100:0; break;
case 2: size = !!(b & 0x20); x = (b & 0x10)?0x100:0; break;
case 3: size = !!(b & 0x80); x = (b & 0x40)?0x100:0; break;
}
current_sprite.num = sprite_num;
current_sprite.priority = (t >> 28) & 3;
current_sprite.x = x | (t & 0xff);
current_sprite.y = ((t >> 8) + 1) & 0xff;
current_sprite.v_flip = !!(t & 0x80000000);
current_sprite.h_flip = !!(t & 0x40000000);
current_sprite.palette = (t >> 25) & 7;
current_sprite.character = (t >> 16) & 0x01ff;
//size: 0 = small, 1 = large
switch(regs.oam_basesize) {
case 0:
if(!size) { current_sprite.width = 8; current_sprite.height = 8; }
else { current_sprite.width = 16; current_sprite.height = 16; }
break;
case 1:
if(!size) { current_sprite.width = 8; current_sprite.height = 8; }
else { current_sprite.width = 32; current_sprite.height = 32; }
break;
case 2:
if(!size) { current_sprite.width = 8; current_sprite.height = 8; }
else { current_sprite.width = 64; current_sprite.height = 64; }
break;
case 3:
if(!size) { current_sprite.width = 16; current_sprite.height = 16; }
else { current_sprite.width = 32; current_sprite.height = 32; }
break;
case 4:
if(!size) { current_sprite.width = 16; current_sprite.height = 16; }
else { current_sprite.width = 64; current_sprite.height = 64; }
break;
case 5:
if(!size) { current_sprite.width = 32; current_sprite.height = 32; }
else { current_sprite.width = 64; current_sprite.height = 64; }
break;
case 6:
if(!size) { current_sprite.width = 16; current_sprite.height = 32; }
else { current_sprite.width = 32; current_sprite.height = 64; }
break;
case 7:
if(!size) { current_sprite.width = 16; current_sprite.height = 32; }
else { current_sprite.width = 32; current_sprite.height = 32; }
break;
}
}
void bPPU::render_oam_sprite(void) {
uint16 pos, col, chr, tiledata_inc;
uint8 d0, d1, d2, d3, pal_index;
int x, y, z, x1, mx, mask, p;
int tile_width;
int vline_pos = clock->vcounter();
int snes_width = (regs.bg_mode == 5 || regs.bg_mode == 6)?512:256;
if(regs.bg_enabled[OAM] == false && regs.bgsub_enabled[OAM] == false)return;
tile_width = current_sprite.width >> SH_8; //e.x. 16x16 sprite = 2x2 tiles
if(clock->interlace() == true && (regs.bg_mode == 5 || regs.bg_mode == 6)) {
y = (vline_pos << SH_2) + clock->interlace_field();
} else {
y = vline_pos;
}
x = current_sprite.x;
if(snes_width == 512) {
x <<= SH_2;
}
if(current_sprite.v_flip) {
y = ((current_sprite.height - 1) - (vline_pos - current_sprite.y));
} else {
y = (vline_pos - current_sprite.y);
}
y &= 255;
if(regs.oam_halve == true) {
y <<= 1;
y += clock->interlace_field();
}
chr = current_sprite.character;
tiledata_inc = (chr & 0x100)?(regs.oam_nameselect << 13):0;
chr += (y >> SH_8) << SH_16;
pal_index = (current_sprite.palette << SH_16);
for(x1=0;x1<tile_width;x1++) {
if(current_sprite.h_flip)mx = (tile_width - 1) - x1;
else mx = x1;
pos = regs.oam_tdaddr + ((chr + mx) << SH_32) + ((y & 7) << SH_2) + tiledata_inc;
d0 = vram[pos ];
d1 = vram[pos + 1];
d2 = vram[pos + 16];
d3 = vram[pos + 17];
for(z=0;z<8;z++) {
if(current_sprite.h_flip) {
mask = 0x01 << z;
} else {
mask = 0x80 >> z;
}
x &= 511;
if(x < snes_width) {
col = 0;
if(d0 & mask)col += 1;
if(d1 & mask)col += 2;
if(d2 & mask)col += 4;
if(d3 & mask)col += 8;
if(col) {
col += pal_index;
col += 128;
if(oam_line_pri[x] == OAM_PRI_NONE) {
oam_line_pal[x] = col;
oam_line_pri[x] = current_sprite.priority;
}
if(snes_width == 512) {
if(oam_line_pri[x + 1] == OAM_PRI_NONE) {
oam_line_pal[x + 1] = col;
oam_line_pri[x + 1] = current_sprite.priority;
}
}
}
}
x++;
if(snes_width == 512) {
x++;
}
}
}
}
void bPPU::render_line_oam(uint8 layer_pos_pri0, uint8 layer_pos_pri1, uint8 layer_pos_pri2, uint8 layer_pos_pri3) {
int i, s;
int vline_pos = clock->vcounter();
int snes_width = (regs.bg_mode == 5 || regs.bg_mode == 6)?512:256;
uint8 layer_pos;
if(regs.bg_enabled[OAM] != true && regs.bgsub_enabled[OAM] != true)return;
memset(oam_line_pri, OAM_PRI_NONE, 512);
for(s=0;s<128;s++) {
set_sprite_attributes(s);
if(regs.oam_halve == false) {
if(vline_pos >= current_sprite.y && vline_pos < (current_sprite.y + current_sprite.height)) {
render_oam_sprite();
} else if((current_sprite.y + current_sprite.height) >= 256 && vline_pos < ((current_sprite.y + current_sprite.height) & 255)) {
render_oam_sprite();
}
} else {
if(vline_pos >= current_sprite.y && vline_pos < (current_sprite.y + (current_sprite.height >> 1))) {
render_oam_sprite();
} else if((current_sprite.y + current_sprite.height) >= 256 && vline_pos < ((current_sprite.y + (current_sprite.height >> 1)) & 255)) {
render_oam_sprite();
}
}
}
for(i=0;i<snes_width;i++) {
if(oam_line_pri[i] != OAM_PRI_NONE) {
switch(oam_line_pri[i]) {
case 0:layer_pos = layer_pos_pri0;break;
case 1:layer_pos = layer_pos_pri1;break;
case 2:layer_pos = layer_pos_pri2;break;
case 3:layer_pos = layer_pos_pri3;break;
}
set_layer_pixel(i, oam_line_pal[i]);
}
}
}
void bPPU::render_line_bg(uint8 layer_pos_pri0, uint8 layer_pos_pri1, uint8 color_depth, uint8 bg) {
int x, y, z, x1, y1;
int mirror_x, mirror_y, p;
int screen_x, screen_y;
int bg_x, bg_y;
int xpos, ypos, mosaic_x, mosaic_y;
int snes_width = (regs.bg_mode == 5 || regs.bg_mode == 6)?512:256;
int vline_pos = clock->vcounter();
uint16 t, base_xpos, base_pos, pos, ppos = 0;
uint16 col;
uint8 *src, *bg_td, *bg_td_state, *tile_ptr;
uint8 tiledata_size;
uint8 tile_size, tile_width, tile_height, tile_x;
uint8 mask, pal_index, pal_size;
uint16 tile_num, screen_width, screen_height, screen_width_mask, screen_height_mask, map_index;
uint16 *mtable;
uint8 layer_pos;
uint16 opt_valid_bit, voffset, hoffset, vscroll, hscroll;
if(regs.bg_enabled[bg] == false && regs.bgsub_enabled[bg] == false)return;
if (bg == BG1)opt_valid_bit = 0x2000;
else if(bg == BG2)opt_valid_bit = 0x4000;
else opt_valid_bit = 0x0000;
switch(color_depth) {
case COLORDEPTH_4:
pal_size = 4;
tiledata_size = SH_16;
break;
case COLORDEPTH_16:
pal_size = 16;
tiledata_size = SH_32;
break;
case COLORDEPTH_256:
pal_size = 256;
tiledata_size = SH_64;
break;
}
bg_td = (byte*)bg_tiledata[color_depth];
bg_td_state = (byte*)bg_tiledata_state[color_depth];
screen_width = snes_width;
screen_height = snes_width; //this is correct -- ppu tilemap is based around 256x256, etc.
tile_size = (regs.bg_tilesize[bg])?SH_16:SH_8;
tile_width = tile_size;
tile_height = tile_size;
if(clock->interlace() == true && (regs.bg_mode == 5 || regs.bg_mode == 6)) {
screen_y = (vline_pos << SH_2) + clock->interlace_field();
} else {
screen_y = vline_pos;
}
//Modes 5 and 6 seem to force 16-width tiles due to having twice the resolution.
//The tile size attribute in $2105 has no effect on tile width.
if(regs.bg_mode == 5 || regs.bg_mode == 6) {
tile_width = SH_16;
}
if(tile_size == SH_16) {
screen_width <<= SH_2;
screen_height <<= SH_2;
}
if(regs.bg_scsize[bg] & 0x01)screen_width <<= SH_2;
if(regs.bg_scsize[bg] & 0x02)screen_height <<= SH_2;
screen_width_mask = screen_width - 1;
screen_height_mask = screen_height - 1;
if(snes_width == 512) {
hscroll = (regs.bg_hofs[bg] << SH_2) & screen_width_mask;
} else {
hscroll = regs.bg_hofs[bg] & screen_width_mask;
}
bg_x = hscroll;
if(snes_width == 512 && clock->interlace() == true) {
vscroll = (regs.bg_vofs[bg] << SH_2) & screen_height_mask;
} else {
vscroll = regs.bg_vofs[bg] & screen_height_mask;
}
bg_y = (screen_y + vscroll) & screen_height_mask;
if(regs.mosaic_enabled[bg] == true) {
mtable = (uint16*)mosaic_table[regs.mosaic_size];
} else {
mtable = (uint16*)mosaic_table[0];
}
mosaic_x = mtable[bg_x];
mosaic_y = mtable[bg_y];
for(screen_x=0;screen_x<snes_width;screen_x++) {
if(regs.bg_mode == 2 || regs.bg_mode == 4 || regs.bg_mode == 6) {
if(regs.bg_mode == 6) {
tile_x = (mtable[screen_x + (hscroll & 15)] >> SH_16);
} else {
tile_x = (mtable[screen_x + (hscroll & 7)] >> SH_8);
}
hoffset = hscroll;
voffset = vscroll;
if(tile_x != 0) {
tile_x = (tile_x - 1) & 31;
if(regs.bg_mode == 4) {
pos = regs.bg_scaddr[BG3] + (tile_x << SH_2);
t = *((uint16*)vram + (pos >> SH_2));
if(t & opt_valid_bit) {
if(!(t & 0x8000)) {
hoffset = ((t & 0x1ff8) | (hscroll & 7)) & screen_width_mask;
} else {
voffset = (t & 0x1fff) & screen_height_mask;
}
}
} else {
pos = regs.bg_scaddr[BG3] + (tile_x << SH_2);
t = *((uint16*)vram + (pos >> SH_2));
if(t & opt_valid_bit) {
hoffset = ((t & 0x1ff8) | (hscroll & 7)) & screen_width_mask;
}
pos = regs.bg_scaddr[BG3] + 64 + (tile_x << SH_2);
t = *((uint16*)vram + (pos >> SH_2));
if(t & opt_valid_bit) {
voffset = (t & 0x1fff) & screen_height_mask;
}
}
}
mosaic_x = mtable[(screen_x + hoffset) & screen_width_mask ];
mosaic_y = mtable[(screen_y + voffset) & screen_height_mask];
}
switch(regs.bg_scsize[bg]) {
case 0:
map_index = 0;
break;
case 1:
map_index = ((mosaic_x >> tile_size) >> SH_32) << SH_2048;
break;
case 2:
map_index = ((mosaic_y >> tile_size) >> SH_32) << SH_2048;
break;
case 3:
map_index = ((mosaic_x >> tile_size) >> SH_32) << SH_2048 |
((mosaic_y >> tile_size) >> SH_32) << SH_4096;
break;
}
base_xpos = ((mosaic_x >> SH_8) & 31);
base_pos = (((mosaic_y >> tile_height) & 31) << SH_32) + ((mosaic_x >> tile_width) & 31);
pos = regs.bg_scaddr[bg] + map_index + (base_pos << SH_2);
t = *((uint16*)vram + (pos >> SH_2));
mirror_y = (t & 0x8000)?1:0;
mirror_x = (t & 0x4000)?1:0;
if((t & 0x2000) == 0) {
layer_pos = layer_pos_pri0;
} else {
layer_pos = layer_pos_pri1;
}
tile_num = t & 0x03ff;
if(tile_width == SH_16) {
if(((mosaic_x & 15) >= 8 && !mirror_x) ||
((mosaic_x & 15) < 8 && mirror_x))tile_num++;
tile_num &= 0x03ff;
}
if(tile_height == SH_16) {
if(((mosaic_y & 15) >= 8 && !mirror_y) ||
((mosaic_y & 15) < 8 && mirror_y))tile_num += 16;
tile_num &= 0x03ff;
}
tile_num += (regs.bg_tdaddr[bg] >> tiledata_size);
if(bg_td_state[tile_num] == 1) {
render_bg_tile(color_depth, bg, tile_num);
}
pal_index = ((t >> 10) & 7) * pal_size;
if(mirror_y) { ypos = (7 - (mosaic_y & 7)); }
else { ypos = ( (mosaic_y & 7)); }
//loop while we are rendering from the same tile, as there's no need to do all of the above work
//unless we have rendered all of the visible tile, taking mosaic into account.
tile_ptr = (uint8*)bg_td + (tile_num << SH_64) + (ypos << SH_8);
while(1) {
if(mirror_x) { xpos = (7 - (mosaic_x & 7)); }
else { xpos = ( (mosaic_x & 7)); }
col = *(tile_ptr + xpos);
if(col) {
set_layer_pixel(screen_x, col + pal_index);
}
bg_x++;
bg_x &= screen_width_mask;
mosaic_x = mtable[bg_x];
if(base_xpos != ((mosaic_x >> SH_8) & 31))break;
screen_x++;
if(screen_x >= snes_width)break;
}
}
}

View File

@ -1,110 +0,0 @@
#define CLIP_10BIT_SIGNED(x) \
((x) & ((1 << 10) - 1)) + (((((x) & (1 << 13)) ^ (1 << 13)) - (1 << 13)) >> 3)
#define CAST_WORDTOINT(x) \
(int)(((x & 0x8000)?(x | 0xffff0000):(x & 0x00007fff)))
void bPPU::render_line_m7(uint8 layer_pos_bg1, uint8 layer_pos_bg2_pri0, uint8 layer_pos_bg2_pri1) {
int x;
int step_m7a, step_m7c, m7a, m7b, m7c, m7d;
int hoffset, voffset;
int centerx, centery;
int xx, yy;
int px, py;
int tx, ty, tile, palette, priority;
uint8 layer_pos;
hoffset = (CAST_WORDTOINT(regs.bg_hofs[BG1]) << 7) >> 7;
voffset = (CAST_WORDTOINT(regs.bg_vofs[BG1]) << 7) >> 7;
centerx = (CAST_WORDTOINT(regs.m7x) << 7) >> 7;
centery = (CAST_WORDTOINT(regs.m7y) << 7) >> 7;
if(regs.mode7_vflip == true) {
yy = 223 - clock->vcounter();
} else {
yy = clock->vcounter();
}
yy += CLIP_10BIT_SIGNED(voffset - centery);
m7b = CAST_WORDTOINT(regs.m7b) * yy + (centerx << 8);
m7d = CAST_WORDTOINT(regs.m7d) * yy + (centery << 8);
step_m7a = CAST_WORDTOINT(regs.m7a);
step_m7c = CAST_WORDTOINT(regs.m7c);
xx = CLIP_10BIT_SIGNED(hoffset - centerx);
m7a = CAST_WORDTOINT(regs.m7a) * xx;
m7c = CAST_WORDTOINT(regs.m7c) * xx;
for(x=0;x<256;x++) {
px = ((m7a + m7b) >> 8);
py = ((m7c + m7d) >> 8);
switch(regs.mode7_repeat) {
case 0: //screen repitition outside of screen area
case 1: //same as case 0
px &= 1023;
py &= 1023;
tx = ((px >> SH_8) & 127);
ty = ((py >> SH_8) & 127);
tile = vram[(ty * 128 + tx) << 1];
palette = vram[(((tile << SH_64) + ((py & 7) << SH_8) + (px & 7)) << 1) + 1];
break;
case 2: //character 0 repetition outside of screen area
if(px < 0 || px > 1023 || py < 0 || py > 1023) {
tx = 0;
ty = 0;
} else {
px &= 1023;
py &= 1023;
tx = ((px >> SH_8) & 127);
ty = ((py >> SH_8) & 127);
}
tile = vram[(ty * 128 + tx) << 1];
palette = vram[(((tile << SH_64) + ((py & 7) << SH_8) + (px & 7)) << 1) + 1];
break;
case 3: //palette color 0 outside of screen area
if(px < 0 || px > 1023 || py < 0 || py > 1023) {
palette = 0;
} else {
px &= 1023;
py &= 1023;
tx = ((px >> SH_8) & 127);
ty = ((py >> SH_8) & 127);
tile = vram[(ty * 128 + tx) << 1];
palette = vram[(((tile << SH_64) + ((py & 7) << SH_8) + (px & 7)) << 1) + 1];
}
break;
}
if(regs.mode7_extbg == false) {
if(palette) {
layer_pos = layer_pos_bg1;
if(regs.mode7_hflip == true) {
set_layer_pixel(255 - x, palette);
} else {
set_layer_pixel(x, palette);
}
}
} else {
priority = (palette >> 7);
palette &= 0x7f;
if(palette) {
if(priority == 0) {
layer_pos = layer_pos_bg2_pri0;
} else {
layer_pos = layer_pos_bg2_pri1;
}
if(regs.mode7_hflip == true) {
set_layer_pixel(255 - x, palette);
} else {
set_layer_pixel(x, palette);
}
}
}
m7a += step_m7a;
m7c += step_m7c;
}
}

Some files were not shown because too many files have changed in this diff Show More