mirror of https://github.com/bsnes-emu/bsnes.git
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:
parent
402c146a53
commit
970dcea0ac
21
bsnes.cfg
21
bsnes.cfg
|
@ -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_g2.exe
BIN
bsnes_g2.exe
Binary file not shown.
23
license.txt
23
license.txt
|
@ -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
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
#include "../base.h"
|
||||
#include "dapu.cpp"
|
|
@ -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);
|
||||
};
|
|
@ -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;
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
};
|
|
@ -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"
|
||||
}
|
|
@ -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();
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
cl /ML /O2 bapugen.cpp
|
||||
@pause
|
||||
@del *.obj
|
|
@ -0,0 +1 @@
|
|||
@del *.exe
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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));
|
||||
}
|
|
@ -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();
|
||||
};
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -1,3 +1,4 @@
|
|||
#include <time.h>
|
||||
#include "lib/libbase.h"
|
||||
|
||||
//structs
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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();
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
@ -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();
|
||||
}
|
|
@ -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
|
@ -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);
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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;
|
||||
}
|
Binary file not shown.
|
@ -0,0 +1,3 @@
|
|||
cl /ML /O2 bcpugen.cpp
|
||||
@pause
|
||||
@del *.obj
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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++;
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
|
@ -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 {
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
libconfig : version 0.01 ~byuu
|
||||
libconfig : version 0.02 ~byuu
|
||||
*/
|
||||
|
||||
#ifndef __LIBCONFIG
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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++;
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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) {}
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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) {}
|
||||
};
|
|
@ -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;
|
||||
}
|
|
@ -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) {}
|
||||
};
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
}
|
|
@ -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);
|
|
@ -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);
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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
Loading…
Reference in New Issue