Update to bsnes v018r04 release.

Ok, _please_ be courteous to my webhost and only download this WIP if
you're going to test it on a processor that hasn't been tested thus
far.

             byuu.org/files/bsnes_v018_wip4.zip
             byuu.org/files/bsnes_tests.zip

 This has two separate builds. Neither have PGO, SSE, SSE2, ZIP or JMA
support. They are identical except for the FAVOR_ flag define and
title of the program.

             FAVOR_ACCURACY [bsnes_accurate.exe]:
             - Always tests OAM RTO flags even on skipped frames
             - Tests NMI/IRQ trigger every clock cycle

             FAVOR_SPEED [bsnes_fast.exe]:
             - Only tests OAM RTO flags on rendered frames (always
with no frameskipping)
             - Tests NMI/IRQ trigger using ranges

 If you'd like to test, please run demo_mode3.smc on both versions of
bsnes, turn off speed regulation, and report the framerate both with a
frameskip of zero and a frameskip of nine (max), along with your
processor speed.

 The other test ROMs are just to verify that IRQ behavior is still
reliable in both versions. A blue screen indicates passing, they all
pass on both versions. Don't expect test_* ROMs to pass on other
emulators, but demo_* ones should.

             Example (my main PC):
             AMD Athlon 3500+

             Accurate:
             - 121.5 fps w/o frameskipping
             - 171 fps w/max frameskipping

             Fast:
             - 146.5 fps w/o frameskipping
             - 271.5 fps w/max frameskipping

             -----

             As you can see, there are _major_ speed differences on my
A64. Personally, I'm all for accuracy, but I also want people to
actually be able to use this program in the interim. Perhaps in the
future when a low end computer is a current low-end Core 2 Duo, we can
remove all of the "speedhack" code. And in the meantime, the full 100%
precision is there for people who have the CPU power to afford it.

             -----

             If anyone wants to try and help, heh.
 src/cpu/scpu/timing/irqtiming_accurate.cpp and
src/cpu/scpu/timing/irqtiming_fast.cpp are the two versions of the IRQ
testing code. If you see any ways to optimize either (preferrably the
former, obviously), I'd greatly appreciate it. Understand that both
the CPU counters (VCOUNTER, HCLOCK) and the IRQ timing positions
(VIRQPOS, HIRQPOS) can wrap not only the horizontal clock position
(1362->0), but the vertical position as well (261->0). And also that
they are "misaligned" by 10 clocks (which is really more of an
internal CPU IC delay thing, we aren't entirely sure why the
difference is there). You probably shouldn't mess with the code if you
don't understand the implications of this on eg range testing :/
This commit is contained in:
byuu 2006-10-20 03:53:34 +00:00
parent f24d17859f
commit 04118be59a
99 changed files with 1435 additions and 17598 deletions

BIN
bsnes_accurate.exe Normal file

Binary file not shown.

BIN
bsnes_fast.exe Normal file

Binary file not shown.

BIN
cart.db Normal file

Binary file not shown.

35
license.txt Normal file
View File

@ -0,0 +1,35 @@
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 program nor its 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:
http://www.gnu.org/copyleft/lesser.html
JMA License:
------------
JMA is licensed under the GNU GPL. I have received special exemption from
Nach to use this library in bsnes.
Licensing Exemptions:
---------------------
libco, the cooperative multithreading library used by bsnes, is public domain.
You may obtain the latest version at: http://byuu.org/
Richard Bannister has asked for and received my permission to distribute
a binary-only port of bsnes on the Mac OS X platform.

124
readme.txt Normal file
View File

@ -0,0 +1,124 @@
bsnes
Version 0.018
Author: byuu
General
-------
bsnes is a Super Nintendo / Super Famicom emulator that began on
October 14th, 2004.
The latest version can be downloaded from:
http://byuu.org/
Please see license.txt for important licensing information.
Known Bugs
----------
Koushien 2 (J):
- Severity: critical
- Issue: game periodically crashes
- Cause: unknown, possibly S-SMP related
Mega lo Mania (J):
- Severity: minor
- Issue: horizontal line flickering during intro
- Cause: caching of OAM occurs too early. Not fixable without dot-based PPU core
Street Racer (J):
- Severity: minor
- Issue: track sometimes flickers every several frames
- Cause: unknown, possibly timing related
Unirally (J), Uniracers (U, E):
- Severity: critical
- Issue: 2-player mode sprites do not display at the correct positions
- Cause: mid-frame OAM writes. Not fixable without dot-based PPU core
Known Limitations
-----------------
S-CPU
- Invalid DMA / HDMA transfers (eg WRAM<>WRAM) not fully emulated
- Multiply / Divide register delays not implemented
S-SMP
- Cycle breakdown of opcodes is theoretical, but mostly correct
S-PPU
- Uses scanline-based renderer. This is very inaccurate, but very
few games rely on mid-scanline writes to function correctly
- Does not support FirstSprite+Y priority
- OAM / CGRAM accesses during active display not supported correctly
- RTO flags are not calculated on frames that are skipped when frameskipping
is enabled. This provides a major speedup, however it will cause in issues
in games that test these flags, eg the SNES Test Program Electronics Test.
Turning frameskipping off will allow RTO flag calculation on every frame
S-DSP
- Runs at 32khz. Hardware S-DSP likely runs at 1.024mhz to perform
multiple reads / writes per sample. Sound is still output at 32khz,
of course
Hardware Bugs
- CPUr1 HDMA crashing bug not emulated
- CPU<>APU communication bus conflicts not emulated
Unsupported Hardware
--------------------
SA-1
Coprocessor used in many popular games, including:
- Dragon Ball Z Hyper Dimension
- Kirby Super Star
- Kirby's Dreamland 3
- Marvelous
- SD Gundam G-NEXT
- Super Mario RPG
Super FX
Coprocessor used in many popular games, including:
- Doom
- Star Fox
- Star Fox 2 (unreleased beta)
- Super Mario World 2: Yoshi's Island
SPC7110
Coprocessor used only by the following games:
- Far East of Eden Zero
- Far East of Eden Zero: Shounen Jump no Shou
- Momotarou Densetsu Happy
- Super Power League 4
DSP-3
Coprocessor used only by SD Gundam GX
DSP-4
Coprocessor used only by Top Gear 3000
ST010 / ST011 / ST018
SETA coprocessors used by very few games
BS-X (Broadcast Satellite)
Add-on unit sold only in Japan that played specially-made games that
were downloaded via satellite
BS-X Flashcart
Flash cartridge used by BS-X, as well as some standalone games by
Asciisoft
Bandai Sufami Turbo
Special cartloader to play some Bandai games
Super Gameboy
Cartridge passthrough used for playing Gameboy games
Unsupported controllers
-----------------------
Mouse
Super Scope
Justifier
Multitap (4-port)
Multitap (5-port)

View File

@ -1,4 +1,4 @@
#define BSNES_VERSION "0.018"
#define BSNES_VERSION "0.018.04"
#define BSNES_TITLE "bsnes v" BSNES_VERSION
#define MEMCORE bMemBus
@ -14,10 +14,10 @@
#define CHEAT_SYSTEM
//enable GZ, ZIP format support
#define GZIP_SUPPORT
//#define GZIP_SUPPORT
//enable JMA support
#define JMA_SUPPORT
//#define JMA_SUPPORT
//snes core polymorphism
//(allow runtime cpu/smp/dsp/ppu/bus selection, ~10% speed hit)

View File

@ -1,97 +0,0 @@
#include "../../base.h"
#include "core/core.cpp"
#include "memory/memory.cpp"
#include "dma/dma.cpp"
#include "timing/timing.cpp"
#include "bcpu_exec.cpp"
#include "bcpu_mmio.cpp"
#include "bcpu_int.cpp"
uint8 bCPU::pio_status() { return status.pio; }
void bCPU::run() {
if(run_state.hdma) {
exec_hdma();
return;
}
if(run_state.dma) {
exec_dma();
return;
}
if(status.cycle_pos == 0) { //interrupts only trigger on opcode edges
if(run_state.irq && !run_state.stp) {
run_state.irq = false;
if(time.nmi_pending == true) {
time.nmi_pending = false;
aa.w = (regs.e == false) ? 0xffea : 0xfffa;
} else if(time.irq_pending == true) {
time.irq_pending = false;
aa.w = (regs.e == false) ? 0xffee : 0xfffe;
}
irq_run();
}
}
exec_cycle();
}
void bCPU::power() {
region = snes->region();
regs.a = regs.x = regs.y = 0x0000;
regs.s = 0x01ff;
reset();
}
void bCPU::reset() {
//reset vector location
regs.pc.d = 0;
regs.pc.l = r_mem->read(0xfffc);
regs.pc.h = r_mem->read(0xfffd);
//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;
regs.mdr = 0x00;
time_reset();
mmio_reset();
dma_reset();
run_state.hdma = false;
run_state.dma = false;
run_state.irq = false;
run_state.wai = false;
run_state.stp = false;
status.cycle_pos = 0;
status.cycle_count = 0;
status.cycles_executed = 0;
apu_port[0] = 0x00;
apu_port[1] = 0x00;
apu_port[2] = 0x00;
apu_port[3] = 0x00;
frame();
//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]
add_cycles(186);
}
bCPU::bCPU() {
init_op_tables();
}
bCPU::~bCPU() {}

View File

@ -1,165 +0,0 @@
class bCPU : public CPU {
public:
#include "core/core.h"
#include "memory/memory.h"
#include "dma/dma.h"
#include "timing/timing.h"
enum { NTSC = 0, PAL = 1 };
uint8 region;
enum {
DMASTATE_DMASYNC,
DMASTATE_DMASYNC2,
DMASTATE_DMASYNC3,
DMASTATE_RUN,
DMASTATE_CPUSYNC,
HDMASTATE_IDMASYNC,
HDMASTATE_IDMASYNC2,
HDMASTATE_IDMASYNC3,
HDMASTATE_ICPUSYNC,
HDMASTATE_DMASYNC,
HDMASTATE_DMASYNC2,
HDMASTATE_DMASYNC3,
HDMASTATE_RUN,
HDMASTATE_CPUSYNC
};
struct {
bool hdma;
bool dma;
bool irq;
bool stp;
bool wai;
} run_state;
struct {
uint8 cycle_pos, cycle_count;
uint8 opcode;
uint32 cycles_executed;
uint8 dma_state, hdma_state;
uint32 dma_cycle_count, hdma_cycle_count;
//$4207-$420a
uint16 virq_trigger, hirq_trigger;
//$2181-$2183
uint32 wram_addr;
//$4016-$4017
bool joypad_strobe_latch;
uint8 joypad1_read_pos, joypad2_read_pos;
//$4200
bool nmi_enabled;
bool hirq_enabled, virq_enabled;
bool auto_joypad_poll;
//$4201
uint8 pio;
//$4202-$4203
uint8 mul_a, mul_b;
//$4204-$4206
uint16 div_a;
uint8 div_b;
//$4207-$420a
uint16 hirq_pos, virq_pos;
//$4214-$4216
uint16 r4214;
uint16 r4216;
} status;
inline bool hdma_test();
inline bool nmi_test();
inline bool irq_test();
inline uint8 pio_status();
inline void run();
inline uint32 clocks_executed();
inline void power();
inline void reset();
inline void irq_run();
//mmio commands
void mmio_reset();
uint8 mmio_r2180();
uint8 mmio_r4016();
uint8 mmio_r4017();
uint8 mmio_r4210();
uint8 mmio_r4211();
uint8 mmio_r4212();
uint8 mmio_r4213();
uint8 mmio_r4214();
uint8 mmio_r4215();
uint8 mmio_r4216();
uint8 mmio_r4217();
uint8 mmio_r4218();
uint8 mmio_r4219();
uint8 mmio_r421a();
uint8 mmio_r421b();
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);
void mmio_w2183(uint8 value);
void mmio_w4016(uint8 value);
void mmio_w4200(uint8 value);
void mmio_w4201(uint8 value);
void mmio_w4202(uint8 value);
void mmio_w4203(uint8 value);
void mmio_w4204(uint8 value);
void mmio_w4205(uint8 value);
void mmio_w4206(uint8 value);
void mmio_w4207(uint8 value);
void mmio_w4208(uint8 value);
void mmio_w4209(uint8 value);
void mmio_w420a(uint8 value);
void mmio_w420b(uint8 value);
void mmio_w420c(uint8 value);
void mmio_w420d(uint8 value);
void mmio_w43x0(uint8 value, uint8 i);
void mmio_w43x1(uint8 value, uint8 i);
void mmio_w43x2(uint8 value, uint8 i);
void mmio_w43x3(uint8 value, uint8 i);
void mmio_w43x4(uint8 value, uint8 i);
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);
uint8 mmio_read (uint16 addr);
void mmio_write(uint16 addr, uint8 data);
enum { CYCLE_OPREAD, CYCLE_READ, CYCLE_WRITE, CYCLE_IO };
inline void pre_exec_cycle();
inline void exec_hdma();
inline void exec_dma();
inline void exec_cycle();
inline void last_cycle();
inline bool in_opcode();
bCPU();
~bCPU();
};

View File

@ -1,163 +0,0 @@
void bCPU::last_cycle() {
time.nmi_pending |= nmi_test();
time.irq_pending |= irq_test();
run_state.irq = (time.nmi_pending || time.irq_pending);
}
void bCPU::pre_exec_cycle() {
if(!run_state.dma && !run_state.hdma)return;
int c, z;
if(run_state.hdma) {
switch(status.hdma_state) {
case HDMASTATE_ICPUSYNC:
case HDMASTATE_CPUSYNC:
c = status.cycle_count;
z = c - (status.hdma_cycle_count % c);
if(!z)z = c;
add_cycles(z);
run_state.hdma = false;
break;
}
}
if(run_state.dma) {
switch(status.dma_state) {
case DMASTATE_CPUSYNC:
c = status.cycle_count;
z = c - (status.dma_cycle_count % c);
if(!z)z = c;
add_cycles(z);
run_state.dma = false;
break;
}
}
}
void bCPU::exec_hdma() {
int n;
static int z;
switch(status.hdma_state) {
case HDMASTATE_IDMASYNC:
status.hdma_cycle_count = 0;
z = 0;
if(!run_state.dma) {
exec_cycle();
status.hdma_state = HDMASTATE_IDMASYNC2;
} else {
status.hdma_state = HDMASTATE_IDMASYNC3;
}
break;
case HDMASTATE_IDMASYNC2:
n = 8 - dma_counter() + 8;
add_cycles(n);
status.hdma_cycle_count += n;
status.hdma_state = HDMASTATE_IDMASYNC3;
break;
case HDMASTATE_IDMASYNC3:
hdma_init();
if(!run_state.dma) {
status.hdma_state = HDMASTATE_ICPUSYNC;
} else {
run_state.hdma = false;
}
break;
case HDMASTATE_ICPUSYNC:
exec_cycle();
break;
case HDMASTATE_DMASYNC:
status.hdma_cycle_count = 0;
z = 0;
if(!run_state.dma) {
exec_cycle();
status.hdma_state = HDMASTATE_DMASYNC2;
} else {
status.hdma_state = HDMASTATE_DMASYNC3;
}
break;
case HDMASTATE_DMASYNC2:
n = 8 - dma_counter() + 8;
add_cycles(n);
status.hdma_cycle_count += n;
status.hdma_state = HDMASTATE_DMASYNC3;
break;
case HDMASTATE_DMASYNC3:
if(channel[z].hdma_line_counter) {
add_cycles(8);
status.hdma_cycle_count += 8;
}
if(++z < 8)break;
status.hdma_state = HDMASTATE_RUN;
break;
case HDMASTATE_RUN:
hdma_run(); //updates status.hdma_cycle_count
if(!run_state.dma) {
status.hdma_state = HDMASTATE_CPUSYNC;
} else {
run_state.hdma = false;
}
break;
case HDMASTATE_CPUSYNC:
exec_cycle();
break;
}
}
void bCPU::exec_dma() {
int n;
static int z;
switch(status.dma_state) {
case DMASTATE_DMASYNC:
exec_cycle();
status.dma_state = DMASTATE_DMASYNC2;
break;
case DMASTATE_DMASYNC2:
n = 8 - dma_counter() + 8;
add_cycles(n);
status.dma_cycle_count = n;
z = 0;
status.dma_state = DMASTATE_DMASYNC3;
break;
case DMASTATE_DMASYNC3:
if(channel[z].dma_enabled == true) {
add_cycles(8);
status.dma_cycle_count += 8;
}
if(++z < 8)break;
status.dma_state = DMASTATE_RUN;
break;
case DMASTATE_RUN:
dma_run(); //updates status.dma_cycle_count
cycle_edge();
break;
case DMASTATE_CPUSYNC:
exec_cycle();
break;
}
}
void bCPU::exec_cycle() {
if(status.cycle_pos) {
(this->*optbl[status.opcode])();
#ifdef DEBUGGER
if(status.cycle_pos == 0) {
snes->notify(SNES::CPU_EXEC_OPCODE_END);
}
#endif
return;
}
//on first cycle?
#ifdef DEBUGGER
snes->notify(SNES::CPU_EXEC_OPCODE_BEGIN);
#endif
status.opcode = op_readpc();
status.cycle_pos = 1;
}
//only return true when we are on an opcode edge
bool bCPU::in_opcode() {
return (status.cycle_pos != 0);
}

View File

@ -1,50 +0,0 @@
void bCPU::irq_run() {
mem_read(regs.pc.d);
cpu_io();
if(!regs.e)op_writestack(regs.pc.b);
op_writestack(regs.pc.h);
op_writestack(regs.pc.l);
op_writestack(regs.e ? (regs.p & ~0x10) : regs.p);
rd.l = op_readaddr(aa.w + 0);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
rd.h = op_readaddr(aa.w + 1);
regs.pc.w = rd.w;
#ifdef DEBUGGER
//let debugger know the new IRQ opcode address
snes->notify(SNES::CPU_EXEC_OPCODE_END);
#endif
}
bool bCPU::nmi_test() {
if(time.nmi_transition == 0)return false;
time.nmi_transition = 0;
run_state.wai = false;
return true;
}
bool bCPU::irq_test() {
if(time.irq_transition == 1)goto _true;
if(time.irq_read == 0) {
if(time.irq_line == 1 && (irq_trigger_pos_match(0) || irq_trigger_pos_match(2))) {
return false;
}
goto _true;
}
if(time.irq_line == 0) {
time.irq_line = 1;
goto _true;
}
return false;
_true:
time.irq_transition = 0;
run_state.wai = false;
return (regs.p.i) ? false : true;
}

View File

@ -1,650 +0,0 @@
void bCPU::mmio_reset() {
//$2181-$2183
status.wram_addr = 0x000000;
//$4016-$4017
status.joypad_strobe_latch = 0;
status.joypad1_read_pos = 0;
status.joypad2_read_pos = 0;
//$4200
status.nmi_enabled = false;
status.hirq_enabled = false;
status.virq_enabled = false;
status.auto_joypad_poll = false;
//$4201
status.pio = 0xff;
//$4202-$4203
status.mul_a = 0xff;
status.mul_b = 0xff;
//$4204-$4206
status.div_a = 0xffff;
status.div_b = 0xff;
//$4207-$420a
status.hirq_pos = 0x01ff;
status.virq_pos = 0x01ff;
//$4214-$4217
status.r4214 = 0x0000;
status.r4216 = 0x0000;
}
//WMDATA
uint8 bCPU::mmio_r2180() {
uint8 r;
r = r_mem->read(0x7e0000 | status.wram_addr);
status.wram_addr++;
status.wram_addr &= 0x01ffff;
return r;
}
//JOYSER0
//7-2 = MDR
//1-0 = Joypad serial data
/* The joypad contains a small bit shifter that has 16 bits.
* Reading from 4016 reads one bit from this buffer, then moves
* the buffer left one, and adds a '1' to the rightmost bit.
* Writing a one to $4016 will fill the buffer with the current
* joypad button states, and lock the bit shifter at position
* zero. All reads will be the first buffer state, or 'B'.
* A zero must be written back to $4016 to unlock the buffer,
* so that reads will increment the bit shifting position.
*/
uint8 bCPU::mmio_r4016() {
uint8 r;
r = regs.mdr & 0xfc;
if(status.joypad_strobe_latch == 1) {
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_B);
} else {
switch(status.joypad1_read_pos) {
case 0: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_B); break;
case 1: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_Y); break;
case 2: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_SELECT); break;
case 3: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_START); break;
case 4: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_UP); break;
case 5: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_DOWN); break;
case 6: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_LEFT); break;
case 7: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_RIGHT); break;
case 8: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_A); break;
case 9: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_X); break;
case 10: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_L); break;
case 11: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_R); break;
case 12: break;
case 13: break;
case 14: break;
case 15: break; //bits 12-15 always return 0
//all subsequent reads return joypad connection status
case 16: r |= 1; break; //joypad connected bit
}
if(++status.joypad1_read_pos > 16)status.joypad1_read_pos = 16;
}
return r;
}
//JOYSER1
//7-5 = MDR
//4-2 = Always 1 (pins are connected to GND)
//1-0 = Joypad serial data
uint8 bCPU::mmio_r4017() {
uint8 r;
r = regs.mdr & 0xe0;
r |= 0x1c;
if(status.joypad_strobe_latch == 1) {
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_B);
} else {
switch(status.joypad2_read_pos) {
case 0: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_B); break;
case 1: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_Y); break;
case 2: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_SELECT); break;
case 3: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_START); break;
case 4: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_UP); break;
case 5: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_DOWN); break;
case 6: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_LEFT); break;
case 7: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_RIGHT); break;
case 8: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_A); break;
case 9: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_X); break;
case 10: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_L); break;
case 11: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_R); break;
case 12: break;
case 13: break;
case 14: break;
case 15: break; //bits 12-15 always return 0
//all subsequent reads return joypad connection status
case 16: r |= 1; break; //joypad connected bit
}
if(++status.joypad2_read_pos > 16)status.joypad2_read_pos = 16;
}
return r;
}
//RDNMI
//7 = NMI acknowledge
//6-4 = MDR
//3-0 = CPU (5a22) version
uint8 bCPU::mmio_r4210() {
uint8 r;
r = regs.mdr & 0x70;
r |= uint8(!time.nmi_read) << 7;
if(!nmi_trigger_pos_match(0) && !nmi_trigger_pos_match(2)) {
time.nmi_read = 1;
}
r |= (cpu_version & 0x0f);
return r;
}
//TIMEUP
//7 = IRQ acknowledge
//6-0 = MDR
uint8 bCPU::mmio_r4211() {
uint8 r;
r = regs.mdr & 0x7f;
r |= uint8(!time.irq_read) << 7;
if(!irq_trigger_pos_match(0) && !irq_trigger_pos_match(2)) {
time.irq_read = 1;
time.irq_line = 1;
time.irq_transition = 0;
}
return r;
}
//HVBJOY
//7 = in vblank
//6 = in hblank
//5-1 = MDR
//0 = joypad ready
uint8 bCPU::mmio_r4212() {
uint8 r;
r = regs.mdr & 0x3e;
uint16 vs = overscan() ? 240 : 225;
//auto joypad polling
if(time.v >= vs && time.v <= (vs + 2))r |= 0x01;
//hblank
if(time.hc <= 2 || time.hc >= 1096)r |= 0x40;
//vblank
if(time.v >= vs)r |= 0x80;
return r;
}
//RDIO
uint8 bCPU::mmio_r4213() {
return status.pio;
}
//RDDIVL
uint8 bCPU::mmio_r4214() {
return status.r4214;
}
//RDDIVH
uint8 bCPU::mmio_r4215() {
return status.r4214 >> 8;
}
//RDMPYL
uint8 bCPU::mmio_r4216() {
return status.r4216;
}
//RDMPYH
uint8 bCPU::mmio_r4217() {
return status.r4216 >> 8;
}
//JOY1L
uint8 bCPU::mmio_r4218() {
uint8 r = 0x00;
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::DEVICEID_JOYPAD1, SNES::JOYPAD_A) << 7;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_X) << 6;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_L) << 5;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_R) << 4;
return r;
}
//JOY1H
uint8 bCPU::mmio_r4219() {
uint8 r = 0x00;
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::DEVICEID_JOYPAD1, SNES::JOYPAD_B) << 7;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_Y) << 6;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_SELECT) << 5;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_START) << 4;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_UP) << 3;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_DOWN) << 2;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_LEFT) << 1;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_RIGHT);
return r;
}
//JOY2L
uint8 bCPU::mmio_r421a() {
uint8 r = 0x00;
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::DEVICEID_JOYPAD2, SNES::JOYPAD_A) << 7;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_X) << 6;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_L) << 5;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_R) << 4;
return r;
}
//JOY2H
uint8 bCPU::mmio_r421b() {
uint8 r = 0x00;
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::DEVICEID_JOYPAD2, SNES::JOYPAD_B) << 7;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_Y) << 6;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_SELECT) << 5;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_START) << 4;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_UP) << 3;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_DOWN) << 2;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_LEFT) << 1;
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_RIGHT);
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].srcbank;
}
//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_ibank;
}
//A2AxL
uint8 bCPU::mmio_r43x8(uint8 i) {
return channel[i].hdma_addr;
}
//A2AxH
uint8 bCPU::mmio_r43x9(uint8 i) {
return channel[i].hdma_addr >> 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 bCPU::mmio_read(uint16 addr) {
//APU
if((addr & 0xffc0) == 0x2140) { //$2140-$217f
return r_smp->port_read(addr & 3);
}
//HDMA
if((addr & 0xff80) == 0x4300) { //$4300-$437f
uint i = (addr >> 4) & 7;
switch(addr & 0xf) {
case 0x0: return mmio_r43x0(i);
case 0x1: return mmio_r43x1(i);
case 0x2: return mmio_r43x2(i);
case 0x3: return mmio_r43x3(i);
case 0x4: return mmio_r43x4(i);
case 0x5: return mmio_r43x5(i);
case 0x6: return mmio_r43x6(i);
case 0x7: return mmio_r43x7(i);
case 0x8: return mmio_r43x8(i);
case 0x9: return mmio_r43x9(i);
case 0xa: return mmio_r43xa(i);
case 0xb: return mmio_r43xb(i);
case 0xc: return regs.mdr; //unmapped
case 0xd: return regs.mdr; //unmapped
case 0xe: return regs.mdr; //unmapped
case 0xf: return mmio_r43xb(i); //mirror of 43xb
}
}
switch(addr) {
case 0x2180: return mmio_r2180(); //WMDATA
case 0x4016: return mmio_r4016(); //JOYSER0
case 0x4017: return mmio_r4017(); //JOYSER1
case 0x4210: return mmio_r4210(); //RDNMI
case 0x4211: return mmio_r4211(); //TIMEUP
case 0x4212: return mmio_r4212(); //HVBJOY
case 0x4213: return mmio_r4213(); //RDIO
case 0x4214: return mmio_r4214(); //RDDIVL
case 0x4215: return mmio_r4215(); //RDDIVH
case 0x4216: return mmio_r4216(); //RDMPYL
case 0x4217: return mmio_r4217(); //RDMPYH
case 0x4218: return mmio_r4218(); //JOY1L
case 0x4219: return mmio_r4219(); //JOY1H
case 0x421a: return mmio_r421a(); //JOY2L
case 0x421b: return mmio_r421b(); //JOY2H
case 0x421c: return 0x00;
case 0x421d: return 0x00;
case 0x421e: return 0x00;
case 0x421f: return 0x00;
}
return regs.mdr;
}
//WMDATA
void bCPU::mmio_w2180(uint8 value) {
r_mem->write(0x7e0000 | status.wram_addr, value);
status.wram_addr++;
status.wram_addr &= 0x01ffff;
}
//WMADDL
void bCPU::mmio_w2181(uint8 value) {
status.wram_addr = (status.wram_addr & 0xffff00) | value;
status.wram_addr &= 0x01ffff;
}
//WMADDM
void bCPU::mmio_w2182(uint8 value) {
status.wram_addr = (status.wram_addr & 0xff00ff) | (value << 8);
status.wram_addr &= 0x01ffff;
}
//WMADDH
void bCPU::mmio_w2183(uint8 value) {
status.wram_addr = (status.wram_addr & 0x00ffff) | (value << 16);
status.wram_addr &= 0x01ffff;
}
//JOYSER0
//bit 0 is shared between JOYSER0 and JOYSER1, therefore
//strobing $4016.d0 affects both controller port latches.
//$4017 bit 0 writes are ignored.
void bCPU::mmio_w4016(uint8 value) {
status.joypad_strobe_latch = bool(value & 1);
if(status.joypad_strobe_latch == 1) {
snes->poll_input();
status.joypad1_read_pos = 0;
status.joypad2_read_pos = 0;
}
}
//NMITIMEN
void bCPU::mmio_w4200(uint8 value) {
status.nmi_enabled = bool(value & 0x80);
status.virq_enabled = bool(value & 0x20);
status.hirq_enabled = bool(value & 0x10);
status.auto_joypad_poll = bool(value & 0x01);
if(time.nmi_read == 0) {
if(time.nmi_line == 1 && !status.nmi_enabled == 0) {
time.nmi_transition = 1;
}
time.nmi_line = !status.nmi_enabled;
}
if(status.virq_enabled == false && status.hirq_enabled == false) {
time.irq_line = 1;
time.irq_read = 1;
time.irq_transition = 0;
}
update_interrupts();
}
//WRIO
void bCPU::mmio_w4201(uint8 value) {
if((status.pio & 0x80) && !(value & 0x80)) {
r_ppu->latch_counters();
}
status.pio = value;
}
//WRMPYA
void bCPU::mmio_w4202(uint8 value) {
status.mul_a = value;
}
//WRMPYB
void bCPU::mmio_w4203(uint8 value) {
status.mul_b = value;
status.r4216 = status.mul_a * status.mul_b;
}
//WRDIVL
void bCPU::mmio_w4204(uint8 value) {
status.div_a = (status.div_a & 0xff00) | (value);
}
//WRDIVH
void bCPU::mmio_w4205(uint8 value) {
status.div_a = (status.div_a & 0x00ff) | (value << 8);
}
//WRDIVB
void bCPU::mmio_w4206(uint8 value) {
status.div_b = value;
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
void bCPU::mmio_w4207(uint8 value) {
status.hirq_pos = ((status.hirq_pos & 0xff00) | value) & 0x01ff;
update_interrupts();
}
//HTIMEH
void bCPU::mmio_w4208(uint8 value) {
status.hirq_pos = ((status.hirq_pos & 0x00ff) | (value << 8)) & 0x01ff;
update_interrupts();
}
//VTIMEL
void bCPU::mmio_w4209(uint8 value) {
status.virq_pos = ((status.virq_pos & 0xff00) | value) & 0x01ff;
update_interrupts();
}
//VTIMEH
void bCPU::mmio_w420a(uint8 value) {
status.virq_pos = ((status.virq_pos & 0x00ff) | (value << 8)) & 0x01ff;
update_interrupts();
}
//DMAEN
//DMA enable does not disable active HDMA channels
void bCPU::mmio_w420b(uint8 value) {
if(value != 0x00) {
run_state.dma = true;
status.dma_state = DMASTATE_DMASYNC;
}
for(int i = 0; i < 8; i++) {
channel[i].dma_enabled = bool(value & (1 << i));
//TODO: clearing read_index may interfere with DMA+HDMA occurring simultaneously
if(channel[i].dma_enabled)channel[i].read_index = 0;
}
}
//HDMAEN
void bCPU::mmio_w420c(uint8 value) {
for(int i = 0; i < 8; i++) {
channel[i].hdma_enabled = bool(value & (1 << i));
}
}
//MEMSEL
void bCPU::mmio_w420d(uint8 value) {
r_mem->set_speed(value & 1);
}
//DMAPx
void bCPU::mmio_w43x0(uint8 value, uint8 i) {
channel[i].dmap = value;
channel[i].direction = bool(value & 0x80);
channel[i].hdma_indirect = bool(value & 0x40);
channel[i].incmode = (value & 0x10) ? -1 : 1;
channel[i].fixedxfer = bool(value & 0x08);
channel[i].xfermode = value & 7;
}
//BBADx
void bCPU::mmio_w43x1(uint8 value, uint8 i) {
channel[i].destaddr = value;
}
//A1TxL
void bCPU::mmio_w43x2(uint8 value, uint8 i) {
channel[i].srcaddr = (channel[i].srcaddr & 0xff00) | value;
}
//A1TxH
void bCPU::mmio_w43x3(uint8 value, uint8 i) {
channel[i].srcaddr = (channel[i].srcaddr & 0x00ff) | (value << 8);
}
//A1Bx
void bCPU::mmio_w43x4(uint8 value, uint8 i) {
channel[i].srcbank = value;
}
//DASxL
void bCPU::mmio_w43x5(uint8 value, uint8 i) {
channel[i].xfersize = (channel[i].xfersize & 0xff00) | value;
}
//DASxH
void bCPU::mmio_w43x6(uint8 value, uint8 i) {
channel[i].xfersize = (channel[i].xfersize & 0x00ff) | (value << 8);
}
//DASBx
void bCPU::mmio_w43x7(uint8 value, uint8 i) {
channel[i].hdma_ibank = value;
}
//A2AxL
void bCPU::mmio_w43x8(uint8 value, uint8 i) {
channel[i].hdma_addr = (channel[i].hdma_addr & 0xff00) | value;
}
//A2AxH
void bCPU::mmio_w43x9(uint8 value, uint8 i) {
channel[i].hdma_addr = (channel[i].hdma_addr & 0x00ff) | (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 bCPU::mmio_write(uint16 addr, uint8 data) {
//APU
if((addr & 0xffc0) == 0x2140) { //$2140-$217f
port_write(addr & 3, data);
return;
}
//HDMA
if((addr & 0xff80) == 0x4300) { //$4300-$437f
uint i = (addr >> 4) & 7;
switch(addr & 0xf) {
case 0x0: mmio_w43x0(data, i); return;
case 0x1: mmio_w43x1(data, i); return;
case 0x2: mmio_w43x2(data, i); return;
case 0x3: mmio_w43x3(data, i); return;
case 0x4: mmio_w43x4(data, i); return;
case 0x5: mmio_w43x5(data, i); return;
case 0x6: mmio_w43x6(data, i); return;
case 0x7: mmio_w43x7(data, i); return;
case 0x8: mmio_w43x8(data, i); return;
case 0x9: mmio_w43x9(data, i); return;
case 0xa: mmio_w43xa(data, i); return;
case 0xb: mmio_w43xb(data, i); return;
case 0xc: return; //unmapped
case 0xd: return; //unmapped
case 0xe: return; //unmapped
case 0xf: mmio_w43xb(data, i); return; //mirror of 43xb
}
}
switch(addr) {
case 0x2180: mmio_w2180(data); return; //WMDATA
case 0x2181: mmio_w2181(data); return; //WMADDL
case 0x2182: mmio_w2182(data); return; //WMADDM
case 0x2183: mmio_w2183(data); return; //WMADDH
case 0x4016: mmio_w4016(data); return; //JOYSER0
case 0x4017: return; //unmapped
case 0x4200: mmio_w4200(data); return; //NMITIMEN
case 0x4201: mmio_w4201(data); return; //WRIO
case 0x4202: mmio_w4202(data); return; //WRMPYA
case 0x4203: mmio_w4203(data); return; //WRMPYB
case 0x4204: mmio_w4204(data); return; //WRDIVL
case 0x4205: mmio_w4205(data); return; //WRDIVH
case 0x4206: mmio_w4206(data); return; //WRDIVB
case 0x4207: mmio_w4207(data); return; //HTIMEL
case 0x4208: mmio_w4208(data); return; //HTIMEH
case 0x4209: mmio_w4209(data); return; //VTIMEL
case 0x420a: mmio_w420a(data); return; //VTIMEH
case 0x420b: mmio_w420b(data); return; //DMAEN
case 0x420c: mmio_w420c(data); return; //HDMAEN
case 0x420d: mmio_w420d(data); return; //MEMSEL
}
}

View File

@ -1,18 +0,0 @@
#define CLASS_NAME "bCPU"
#include "../../../lib/opgen.cpp"
int main() {
fph = fopen("op.h", "wb");
fpt = fopen("optable.cpp", "wb");
generate("op_read.cpp", "op_read.b");
generate("op_rmw.cpp", "op_rmw.b");
generate("op_write.cpp", "op_write.b");
generate("op_pc.cpp", "op_pc.b");
generate("op_misc.cpp", "op_misc.b");
fclose(fph);
fclose(fpt);
return 0;
}

View File

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

View File

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

View File

@ -1,28 +0,0 @@
#include "opfn.cpp"
#include "op_read.cpp"
#include "op_rmw.cpp"
#include "op_write.cpp"
#include "op_pc.cpp"
#include "op_misc.cpp"
void bCPU::cpu_c2() {
if(regs.d.l != 0x00) {
cpu_io();
}
}
void bCPU::cpu_c4(uint16 x, uint16 y) {
if(!regs.p.x || (x & 0xff00) != (y & 0xff00)) {
cpu_io();
}
}
void bCPU::cpu_c6(uint16 addr) {
if(regs.e && (regs.pc.w & 0xff00) != (addr & 0xff00)) {
cpu_io();
}
}
void bCPU::init_op_tables() {
#include "optable.cpp"
}

View File

@ -1,62 +0,0 @@
/* External functions:
* void last_cycle();
* void cpu_io();
* uint8 mem_read(uint32 addr);
* void mem_write(uint32 addr, uint8 value);
*/
void (bCPU::*optbl[256])();
CPUReg24 aa, rd;
uint8 dp, sp;
//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();
inline void cpu_c2();
inline void cpu_c4(uint16 x, uint16 y);
inline void cpu_c6(uint16 addr);
inline void init_op_tables();
#include "op.h"

View File

@ -1,256 +0,0 @@
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_bcc();
void op_bcs();
void op_bne();
void op_beq();
void op_bpl();
void op_bmi();
void op_bvc();
void op_bvs();
void op_bra();
void op_brl();
void op_jmp_addr();
void op_jmp_long();
void op_jmp_iaddr();
void op_jmp_iaddrx();
void op_jmp_iladdr();
void op_jsr_addr();
void op_jsr_long();
void op_jsr_iaddrx();
void op_rti();
void op_rts();
void op_rtl();
void op_nop();
void op_wdm();
void op_xba();
void op_mvn();
void op_mvp();
void op_brk();
void op_cop();
void op_stp();
void op_wai();
void op_xce();
void op_clc();
void op_cld();
void op_cli();
void op_clv();
void op_sec();
void op_sed();
void op_sei();
void op_rep();
void op_sep();
void op_tax();
void op_tay();
void op_txa();
void op_txy();
void op_tya();
void op_tyx();
void op_tcd();
void op_tcs();
void op_tdc();
void op_tsc();
void op_tsx();
void op_txs();
void op_pha();
void op_phx();
void op_phy();
void op_phd();
void op_phb();
void op_phk();
void op_php();
void op_pla();
void op_plx();
void op_ply();
void op_pld();
void op_plb();
void op_plp();
void op_pea();
void op_pei();
void op_per();

View File

@ -1,282 +0,0 @@
nop(0xea) {
1:last_cycle();
cpu_io();
}
wdm(0x42) {
1:last_cycle();
op_readpc();
}
xba(0xeb) {
1:cpu_io();
2:last_cycle();
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_readpc();
2:sp = op_readpc();
3:regs.db = dp;
rd.l = op_readlong((sp << 16) | regs.x.w);
4:op_writelong((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:last_cycle();
cpu_io();
if(regs.a.w--)regs.pc.w -= 3;
}
brk(0x00, 0xfffe, 0xffff, 0xffe6, 0xffe7),
cop(0x02, 0xfff4, 0xfff5, 0xffe4, 0xffe5) {
1:op_readpc();
if(regs.e)skip;
2:op_writestack(regs.pc.b);
3:op_writestack(regs.pc.h);
4:op_writestack(regs.pc.l);
5:op_writestack(regs.p);
6:rd.l = op_readlong((regs.e) ? $1 : $3);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
7:last_cycle();
rd.h = op_readlong((regs.e) ? $2 : $4);
regs.pc.w = rd.w;
}
stp(0xdb) {
1:cpu_io();
run_state.stp = true;
2:last_cycle();
cpu_io();
regs.pc.w--;
}
wai(0xcb) {
1:cpu_io();
run_state.wai = true;
2:last_cycle();
cpu_io();
//no wakeup delay if last_cycle() cancelled wai
if(run_state.wai == false)end;
3:last_cycle();
cpu_io();
//sleep another i/o cycle
//note: this should alert the debugger that wai is continuing...
if(run_state.wai == true)status.cycle_pos--;
//wai wakeup delay (one i/o cycle)
4:last_cycle();
cpu_io();
}
xce(0xfb) {
1:last_cycle();
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:last_cycle();
cpu_io();
$1;
}
rep(0xc2, &=~),
sep(0xe2, |=) {
1:rd.l = op_readpc();
2:last_cycle();
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:last_cycle();
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:last_cycle();
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:last_cycle();
cpu_io();
regs.s.w = regs.a.w;
if(regs.e)regs.s.h = 0x01;
}
tdc(0x7b) {
1:last_cycle();
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:last_cycle();
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:last_cycle();
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:last_cycle();
cpu_io();
if(regs.e) {
regs.s.l = regs.x.l;
} else {
regs.s.w = regs.x.w;
}
}
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:op_writestack(regs.$2.h);
3:last_cycle();
op_writestack(regs.$2.l);
}
phb(0x8b, regs.db),
phk(0x4b, regs.pc.b),
php(0x08, regs.p) {
1:cpu_io();
2:last_cycle();
op_writestack($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:if($1)last_cycle();
regs.$2.l = op_readstack();
if($1) {
regs.p.n = !!(regs.$2.l & 0x80);
regs.p.z = (regs.$2.l == 0);
end;
}
4:last_cycle();
regs.$2.h = op_readstack();
regs.p.n = !!(regs.$2.w & 0x8000);
regs.p.z = (regs.$2.w == 0);
}
plb(0xab) {
1:cpu_io();
2:cpu_io();
3:last_cycle();
regs.db = op_readstack();
regs.p.n = !!(regs.db & 0x80);
regs.p.z = (regs.db == 0);
}
plp(0x28) {
1:cpu_io();
2:cpu_io();
3:last_cycle();
regs.p = op_readstack();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
}
pea(0xf4) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:op_writestack(aa.h);
4:last_cycle();
op_writestack(aa.l);
}
pei(0xd4) {
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:op_writestack(aa.h);
6:last_cycle();
op_writestack(aa.l);
}
per(0x62) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:cpu_io();
rd.w = regs.pc.d + (int16)aa.w;
4:op_writestack(rd.h);
5:last_cycle();
op_writestack(rd.l);
}

View File

@ -1,864 +0,0 @@
void bCPU::op_nop() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_wdm() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
op_readpc();
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_xba() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
last_cycle();
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);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_mvn() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
sp = op_readpc();
} break;
case 3: {
regs.db = dp;
rd.l = op_readlong((sp << 16) | regs.x.w);
} break;
case 4: {
op_writelong((dp << 16) | regs.y.w, rd.l);
} break;
case 5: {
cpu_io();
if(regs.p.x) { regs.x.l++; regs.y.l++; }
else { regs.x.w++; regs.y.w++; }
} break;
case 6: {
last_cycle();
cpu_io();
if(regs.a.w--)regs.pc.w -= 3;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_mvp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
sp = op_readpc();
} break;
case 3: {
regs.db = dp;
rd.l = op_readlong((sp << 16) | regs.x.w);
} break;
case 4: {
op_writelong((dp << 16) | regs.y.w, rd.l);
} break;
case 5: {
cpu_io();
if(regs.p.x) { regs.x.l--; regs.y.l--; }
else { regs.x.w--; regs.y.w--; }
} break;
case 6: {
last_cycle();
cpu_io();
if(regs.a.w--)regs.pc.w -= 3;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_brk() {
switch(status.cycle_pos++) {
case 1: {
op_readpc();
if(regs.e)status.cycle_pos++;
} break;
case 2: {
op_writestack(regs.pc.b);
} break;
case 3: {
op_writestack(regs.pc.h);
} break;
case 4: {
op_writestack(regs.pc.l);
} break;
case 5: {
op_writestack(regs.p);
} break;
case 6: {
rd.l = op_readlong((regs.e) ? 0xfffe : 0xffe6);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
} break;
case 7: {
last_cycle();
rd.h = op_readlong((regs.e) ? 0xffff : 0xffe7);
regs.pc.w = rd.w;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_cop() {
switch(status.cycle_pos++) {
case 1: {
op_readpc();
if(regs.e)status.cycle_pos++;
} break;
case 2: {
op_writestack(regs.pc.b);
} break;
case 3: {
op_writestack(regs.pc.h);
} break;
case 4: {
op_writestack(regs.pc.l);
} break;
case 5: {
op_writestack(regs.p);
} break;
case 6: {
rd.l = op_readlong((regs.e) ? 0xfff4 : 0xffe4);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
} break;
case 7: {
last_cycle();
rd.h = op_readlong((regs.e) ? 0xfff5 : 0xffe5);
regs.pc.w = rd.w;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_stp() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
run_state.stp = true;
} break;
case 2: {
last_cycle();
cpu_io();
regs.pc.w--;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_wai() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
run_state.wai = true;
} break;
case 2: {
last_cycle();
cpu_io();
//no wakeup delay if last_cycle() cancelled wai
if(run_state.wai == false)status.cycle_pos = 0;
} break;
case 3: {
last_cycle();
cpu_io();
//sleep another i/o cycle
//note: this should alert the debugger that wai is continuing...
if(run_state.wai == true)status.cycle_pos--;
//wai wakeup delay (one i/o cycle)
} break;
case 4: {
last_cycle();
cpu_io();
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_xce() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
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;
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_clc() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
regs.p.c = 0;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_cld() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
regs.p.d = 0;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_cli() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
regs.p.i = 0;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_clv() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
regs.p.v = 0;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sec() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
regs.p.c = 1;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sed() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
regs.p.d = 1;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sei() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
regs.p.i = 1;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_rep() {
switch(status.cycle_pos++) {
case 1: {
rd.l = op_readpc();
} break;
case 2: {
last_cycle();
cpu_io();
regs.p &=~ rd.l;
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sep() {
switch(status.cycle_pos++) {
case 1: {
rd.l = op_readpc();
} break;
case 2: {
last_cycle();
cpu_io();
regs.p |= rd.l;
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_tax() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
if(regs.p.x) {
regs.x.l = regs.a.l;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
} else {
regs.x.w = regs.a.w;
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_tay() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
if(regs.p.x) {
regs.y.l = regs.a.l;
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
} else {
regs.y.w = regs.a.w;
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_txa() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
if(regs.p.m) {
regs.a.l = regs.x.l;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.a.w = regs.x.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_txy() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
if(regs.p.x) {
regs.y.l = regs.x.l;
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
} else {
regs.y.w = regs.x.w;
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_tya() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
if(regs.p.m) {
regs.a.l = regs.y.l;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.a.w = regs.y.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_tyx() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
if(regs.p.x) {
regs.x.l = regs.y.l;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
} else {
regs.x.w = regs.y.w;
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_tcd() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
regs.d.w = regs.a.w;
regs.p.n = !!(regs.d.w & 0x8000);
regs.p.z = (regs.d.w == 0);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_tcs() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
regs.s.w = regs.a.w;
if(regs.e)regs.s.h = 0x01;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_tdc() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
regs.a.w = regs.d.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_tsc() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
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);
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_tsx() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
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);
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_txs() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
cpu_io();
if(regs.e) {
regs.s.l = regs.x.l;
} else {
regs.s.w = regs.x.w;
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_pha() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
if(regs.p.m)status.cycle_pos++;
} break;
case 2: {
op_writestack(regs.a.h);
} break;
case 3: {
last_cycle();
op_writestack(regs.a.l);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_phx() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
if(regs.p.x)status.cycle_pos++;
} break;
case 2: {
op_writestack(regs.x.h);
} break;
case 3: {
last_cycle();
op_writestack(regs.x.l);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_phy() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
if(regs.p.x)status.cycle_pos++;
} break;
case 2: {
op_writestack(regs.y.h);
} break;
case 3: {
last_cycle();
op_writestack(regs.y.l);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_phd() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
if(0)status.cycle_pos++;
} break;
case 2: {
op_writestack(regs. d.h);
} break;
case 3: {
last_cycle();
op_writestack(regs. d.l);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_phb() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
last_cycle();
op_writestack(regs.db);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_phk() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
last_cycle();
op_writestack(regs.pc.b);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_php() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
last_cycle();
op_writestack(regs.p);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_pla() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
cpu_io();
} break;
case 3: {
if(regs.p.m)last_cycle();
regs.a.l = op_readstack();
if(regs.p.m) {
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
status.cycle_pos = 0;
}
} break;
case 4: {
last_cycle();
regs.a.h = op_readstack();
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_plx() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
cpu_io();
} break;
case 3: {
if(regs.p.x)last_cycle();
regs.x.l = op_readstack();
if(regs.p.x) {
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
status.cycle_pos = 0;
}
} break;
case 4: {
last_cycle();
regs.x.h = op_readstack();
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_ply() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
cpu_io();
} break;
case 3: {
if(regs.p.x)last_cycle();
regs.y.l = op_readstack();
if(regs.p.x) {
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
status.cycle_pos = 0;
}
} break;
case 4: {
last_cycle();
regs.y.h = op_readstack();
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_pld() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
cpu_io();
} break;
case 3: {
if(0)last_cycle();
regs. d.l = op_readstack();
if(0) {
regs.p.n = !!(regs. d.l & 0x80);
regs.p.z = (regs. d.l == 0);
status.cycle_pos = 0;
}
} break;
case 4: {
last_cycle();
regs. d.h = op_readstack();
regs.p.n = !!(regs. d.w & 0x8000);
regs.p.z = (regs. d.w == 0);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_plb() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
cpu_io();
} break;
case 3: {
last_cycle();
regs.db = op_readstack();
regs.p.n = !!(regs.db & 0x80);
regs.p.z = (regs.db == 0);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_plp() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
cpu_io();
} break;
case 3: {
last_cycle();
regs.p = op_readstack();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_pea() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
op_writestack(aa.h);
} break;
case 4: {
last_cycle();
op_writestack(aa.l);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_pei() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
aa.l = op_readdp(dp);
} break;
case 4: {
aa.h = op_readdp(dp + 1);
} break;
case 5: {
op_writestack(aa.h);
} break;
case 6: {
last_cycle();
op_writestack(aa.l);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_per() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
cpu_io();
rd.w = regs.pc.d + (int16)aa.w;
} break;
case 4: {
op_writestack(rd.h);
} break;
case 5: {
last_cycle();
op_writestack(rd.l);
status.cycle_pos = 0;
} break;
}
}

View File

@ -1,160 +0,0 @@
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:if(!$1)last_cycle();
rd.l = op_readpc();
if($1) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
end;
}
2:cpu_c6(aa.w);
3:last_cycle();
cpu_io();
}
bra(0x80) {
1:rd.l = op_readpc();
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
2:cpu_c6(aa.w);
3:last_cycle();
cpu_io();
}
brl(0x82) {
1:rd.l = op_readpc();
2:rd.h = op_readpc();
3:last_cycle();
cpu_io();
regs.pc.w = regs.pc.d + (int16)rd.w;
}
jmp_addr(0x4c) {
1:rd.l = op_readpc();
2:last_cycle();
rd.h = op_readpc();
regs.pc.w = rd.w;
}
jmp_long(0x5c) {
1:rd.l = op_readpc();
2:rd.h = op_readpc();
3:last_cycle();
rd.b = op_readpc();
regs.pc.d = rd.d & 0xffffff;
}
jmp_iaddr(0x6c) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:rd.l = op_readaddr(aa.w);
4:last_cycle();
rd.h = op_readaddr(aa.w + 1);
regs.pc.w = rd.w;
}
jmp_iaddrx(0x7c) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:cpu_io();
4:rd.l = op_readpbr(aa.w + regs.x.w);
5:last_cycle();
rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
}
jmp_iladdr(0xdc) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:rd.l = op_readaddr(aa.w);
4:rd.h = op_readaddr(aa.w + 1);
5:last_cycle();
rd.b = op_readaddr(aa.w + 2);
regs.pc.d = rd.d & 0xffffff;
}
jsr_addr(0x20) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:cpu_io();
4:regs.pc.w--;
op_writestack(regs.pc.h);
5:last_cycle();
op_writestack(regs.pc.l);
regs.pc.w = aa.w;
}
jsr_long(0x22) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:op_writestack(regs.pc.b);
4:cpu_io();
5:aa.b = op_readpc();
6:regs.pc.w--;
op_writestack(regs.pc.h);
7:last_cycle();
op_writestack(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
}
jsr_iaddrx(0xfc) {
1:aa.l = op_readpc();
2:op_writestack(regs.pc.h);
3:op_writestack(regs.pc.l);
4:aa.h = op_readpc();
5:cpu_io();
6:rd.l = op_readpbr(aa.w + regs.x.w);
7:last_cycle();
rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
}
rti(0x40) {
1:cpu_io();
2:cpu_io();
3:regs.p = op_readstack();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
4:rd.l = op_readstack();
5:if(regs.e)last_cycle();
rd.h = op_readstack();
if(regs.e) {
regs.pc.w = rd.w;
end;
}
6:last_cycle();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
}
rts(0x60) {
1:cpu_io();
2:cpu_io();
3:rd.l = op_readstack();
4:rd.h = op_readstack();
5:last_cycle();
cpu_io();
regs.pc.w = rd.w;
regs.pc.w++;
}
rtl(0x6b) {
1:cpu_io();
2:cpu_io();
3:rd.l = op_readstack();
4:rd.h = op_readstack();
5:last_cycle();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
regs.pc.w++;
}

View File

@ -1,483 +0,0 @@
void bCPU::op_bcc() {
switch(status.cycle_pos++) {
case 1: {
if(!!regs.p.c)last_cycle();
rd.l = op_readpc();
if(!regs.p.c) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
status.cycle_pos = 0;
}
} break;
case 2: {
cpu_c6(aa.w);
} break;
case 3: {
last_cycle();
cpu_io();
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_bcs() {
switch(status.cycle_pos++) {
case 1: {
if(!regs.p.c)last_cycle();
rd.l = op_readpc();
if(regs.p.c) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
status.cycle_pos = 0;
}
} break;
case 2: {
cpu_c6(aa.w);
} break;
case 3: {
last_cycle();
cpu_io();
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_bne() {
switch(status.cycle_pos++) {
case 1: {
if(!!regs.p.z)last_cycle();
rd.l = op_readpc();
if(!regs.p.z) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
status.cycle_pos = 0;
}
} break;
case 2: {
cpu_c6(aa.w);
} break;
case 3: {
last_cycle();
cpu_io();
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_beq() {
switch(status.cycle_pos++) {
case 1: {
if(!regs.p.z)last_cycle();
rd.l = op_readpc();
if(regs.p.z) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
status.cycle_pos = 0;
}
} break;
case 2: {
cpu_c6(aa.w);
} break;
case 3: {
last_cycle();
cpu_io();
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_bpl() {
switch(status.cycle_pos++) {
case 1: {
if(!!regs.p.n)last_cycle();
rd.l = op_readpc();
if(!regs.p.n) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
status.cycle_pos = 0;
}
} break;
case 2: {
cpu_c6(aa.w);
} break;
case 3: {
last_cycle();
cpu_io();
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_bmi() {
switch(status.cycle_pos++) {
case 1: {
if(!regs.p.n)last_cycle();
rd.l = op_readpc();
if(regs.p.n) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
status.cycle_pos = 0;
}
} break;
case 2: {
cpu_c6(aa.w);
} break;
case 3: {
last_cycle();
cpu_io();
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_bvc() {
switch(status.cycle_pos++) {
case 1: {
if(!!regs.p.v)last_cycle();
rd.l = op_readpc();
if(!regs.p.v) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
status.cycle_pos = 0;
}
} break;
case 2: {
cpu_c6(aa.w);
} break;
case 3: {
last_cycle();
cpu_io();
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_bvs() {
switch(status.cycle_pos++) {
case 1: {
if(!regs.p.v)last_cycle();
rd.l = op_readpc();
if(regs.p.v) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} else {
status.cycle_pos = 0;
}
} break;
case 2: {
cpu_c6(aa.w);
} break;
case 3: {
last_cycle();
cpu_io();
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_bra() {
switch(status.cycle_pos++) {
case 1: {
rd.l = op_readpc();
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} break;
case 2: {
cpu_c6(aa.w);
} break;
case 3: {
last_cycle();
cpu_io();
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_brl() {
switch(status.cycle_pos++) {
case 1: {
rd.l = op_readpc();
} break;
case 2: {
rd.h = op_readpc();
} break;
case 3: {
last_cycle();
cpu_io();
regs.pc.w = regs.pc.d + (int16)rd.w;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_jmp_addr() {
switch(status.cycle_pos++) {
case 1: {
rd.l = op_readpc();
} break;
case 2: {
last_cycle();
rd.h = op_readpc();
regs.pc.w = rd.w;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_jmp_long() {
switch(status.cycle_pos++) {
case 1: {
rd.l = op_readpc();
} break;
case 2: {
rd.h = op_readpc();
} break;
case 3: {
last_cycle();
rd.b = op_readpc();
regs.pc.d = rd.d & 0xffffff;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_jmp_iaddr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
rd.l = op_readaddr(aa.w);
} break;
case 4: {
last_cycle();
rd.h = op_readaddr(aa.w + 1);
regs.pc.w = rd.w;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_jmp_iaddrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
cpu_io();
} break;
case 4: {
rd.l = op_readpbr(aa.w + regs.x.w);
} break;
case 5: {
last_cycle();
rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_jmp_iladdr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
rd.l = op_readaddr(aa.w);
} break;
case 4: {
rd.h = op_readaddr(aa.w + 1);
} break;
case 5: {
last_cycle();
rd.b = op_readaddr(aa.w + 2);
regs.pc.d = rd.d & 0xffffff;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_jsr_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
cpu_io();
} break;
case 4: {
regs.pc.w--;
op_writestack(regs.pc.h);
} break;
case 5: {
last_cycle();
op_writestack(regs.pc.l);
regs.pc.w = aa.w;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_jsr_long() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
op_writestack(regs.pc.b);
} break;
case 4: {
cpu_io();
} break;
case 5: {
aa.b = op_readpc();
} break;
case 6: {
regs.pc.w--;
op_writestack(regs.pc.h);
} break;
case 7: {
last_cycle();
op_writestack(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_jsr_iaddrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
op_writestack(regs.pc.h);
} break;
case 3: {
op_writestack(regs.pc.l);
} break;
case 4: {
aa.h = op_readpc();
} break;
case 5: {
cpu_io();
} break;
case 6: {
rd.l = op_readpbr(aa.w + regs.x.w);
} break;
case 7: {
last_cycle();
rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_rti() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
cpu_io();
} break;
case 3: {
regs.p = op_readstack();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
} break;
case 4: {
rd.l = op_readstack();
} break;
case 5: {
if(regs.e)last_cycle();
rd.h = op_readstack();
if(regs.e) {
regs.pc.w = rd.w;
status.cycle_pos = 0;
}
} break;
case 6: {
last_cycle();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_rts() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
cpu_io();
} break;
case 3: {
rd.l = op_readstack();
} break;
case 4: {
rd.h = op_readstack();
} break;
case 5: {
last_cycle();
cpu_io();
regs.pc.w = rd.w;
regs.pc.w++;
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_rtl() {
switch(status.cycle_pos++) {
case 1: {
cpu_io();
} break;
case 2: {
cpu_io();
} break;
case 3: {
rd.l = op_readstack();
} break;
case 4: {
rd.h = op_readstack();
} break;
case 5: {
last_cycle();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
regs.pc.w++;
status.cycle_pos = 0;
} break;
}
}

View File

@ -1,317 +0,0 @@
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:if($2)last_cycle();
rd.l = op_readpc();
if($2) { op_$1_b(); end; }
2:last_cycle();
rd.h = op_readpc();
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_readpc();
2:aa.h = op_readpc();
3:if($2)last_cycle();
rd.l = op_readdbr(aa.w);
if($2) { op_$1_b(); end; }
4:last_cycle();
rd.h = op_readdbr(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_readpc();
2:aa.h = op_readpc();
3:cpu_c4(aa.w, aa.w + regs.x.w);
4:if($2)last_cycle();
rd.l = op_readdbr(aa.w + regs.x.w);
if($2) { op_$1_b(); end; }
5:last_cycle();
rd.h = op_readdbr(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_readpc();
2:aa.h = op_readpc();
3:cpu_c4(aa.w, aa.w + regs.y.w);
4:if($2)last_cycle();
rd.l = op_readdbr(aa.w + regs.y.w);
if($2) { op_$1_b(); end; }
5:last_cycle();
rd.h = op_readdbr(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_readpc();
2:aa.h = op_readpc();
3:aa.b = op_readpc();
4:if($2)last_cycle();
rd.l = op_readlong(aa.d);
if($2) { op_$1_b(); end; }
5:last_cycle();
rd.h = op_readlong(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_readpc();
2:aa.h = op_readpc();
3:aa.b = op_readpc();
4:if($2)last_cycle();
rd.l = op_readlong(aa.d + regs.x.w);
if($2) { op_$1_b(); end; }
5:last_cycle();
rd.h = op_readlong(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_readpc();
2:cpu_c2();
3:if($2)last_cycle();
rd.l = op_readdp(dp);
if($2) { op_$1_b(); end; }
4:last_cycle();
rd.h = op_readdp(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_readpc();
2:cpu_c2();
3:cpu_io();
4:if($2)last_cycle();
rd.l = op_readdp(dp + regs.x.w);
if($2) { op_$1_b(); end; }
5:last_cycle();
rd.h = op_readdp(dp + regs.x.w + 1);
op_$1_w();
}
ldx_dpy(0xb6, ldx, regs.p.x) {
1:dp = op_readpc();
2:cpu_c2();
3:cpu_io();
4:if($2)last_cycle();
rd.l = op_readdp(dp + regs.y.w);
if($2) { op_$1_b(); end; }
5:last_cycle();
rd.h = op_readdp(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_readpc();
2:cpu_c2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:if($2)last_cycle();
rd.l = op_readdbr(aa.w);
if($2) { op_$1_b(); end; }
6:last_cycle();
rd.h = op_readdbr(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_readpc();
2:cpu_c2();
3:cpu_io();
4:aa.l = op_readdp(dp + regs.x.w);
5:aa.h = op_readdp(dp + regs.x.w + 1);
6:if($2)last_cycle();
rd.l = op_readdbr(aa.w);
if($2) { op_$1_b(); end; }
7:last_cycle();
rd.h = op_readdbr(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_readpc();
2:cpu_c2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:cpu_c4(aa.w, aa.w + regs.y.w);
6:if($2)last_cycle();
rd.l = op_readdbr(aa.w + regs.y.w);
if($2) { op_$1_b(); end; }
7:last_cycle();
rd.h = op_readdbr(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_readpc();
2:cpu_c2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:aa.b = op_readdp(dp + 2);
6:if($2)last_cycle();
rd.l = op_readlong(aa.d);
if($2) { op_$1_b(); end; }
7:last_cycle();
rd.h = op_readlong(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_readpc();
2:cpu_c2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:aa.b = op_readdp(dp + 2);
6:if($2)last_cycle();
rd.l = op_readlong(aa.d + regs.y.w);
if($2) { op_$1_b(); end; }
7:last_cycle();
rd.h = op_readlong(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_readpc();
2:cpu_io();
3:if($2)last_cycle();
rd.l = op_readsp(sp);
if($2) { op_$1_b(); end; }
4:last_cycle();
rd.h = op_readsp(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_readpc();
2:cpu_io();
3:aa.l = op_readsp(sp);
4:aa.h = op_readsp(sp + 1);
5:cpu_io();
6:if(regs.p.m)last_cycle();
rd.l = op_readdbr(aa.w + regs.y.w);
if(regs.p.m) { op_$1_b(); end; }
7:last_cycle();
rd.h = op_readdbr(aa.w + regs.y.w + 1);
op_$1_w();
}
bit_const(0x89) {
1:if(regs.p.m)last_cycle();
rd.l = op_readpc();
if(regs.p.m) {
regs.p.z = ((rd.l & regs.a.l) == 0);
end;
}
2:last_cycle();
rd.h = op_readpc();
regs.p.z = ((rd.w & regs.a.w) == 0);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,185 +0,0 @@
inc(0x1a, regs.p.m, a),
inx(0xe8, regs.p.x, x),
iny(0xc8, regs.p.x, y) {
1:last_cycle();
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:last_cycle();
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:last_cycle();
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:last_cycle();
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:last_cycle();
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:last_cycle();
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_readpc();
2:aa.h = op_readpc();
3:rd.l = op_readdbr(aa.w);
if(regs.p.m)skip;
4:rd.h = op_readdbr(aa.w + 1);
5:cpu_io();
if(regs.p.m) { op_$1_b(); skip; }
else op_$1_w();
6:op_writedbr(aa.w + 1, rd.h);
7:last_cycle();
op_writedbr(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_readpc();
2:aa.h = op_readpc();
3:cpu_io();
4:rd.l = op_readdbr(aa.w + regs.x.w);
if(regs.p.m)skip;
5:rd.h = op_readdbr(aa.w + regs.x.w + 1);
6:cpu_io();
if(regs.p.m) { op_$1_b(); skip; }
else op_$1_w();
7:op_writedbr(aa.w + regs.x.w + 1, rd.h);
8:last_cycle();
op_writedbr(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_readpc();
2:cpu_c2();
3:rd.l = op_readdp(dp);
if(regs.p.m)skip;
4:rd.h = op_readdp(dp + 1);
5:cpu_io();
if(regs.p.m) { op_$1_b(); skip; }
else op_$1_w();
6:op_writedp(dp + 1, rd.h);
7:last_cycle();
op_writedp(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_readpc();
2:cpu_c2();
3:cpu_io();
4:rd.l = op_readdp(dp + regs.x.w);
if(regs.p.m)skip;
5:rd.h = op_readdp(dp + regs.x.w + 1);
6:cpu_io();
if(regs.p.m) { op_$1_b(); skip; }
else op_$1_w();
7:op_writedp(dp + regs.x.w + 1, rd.h);
8:last_cycle();
op_writedp(dp + regs.x.w, rd.l);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,181 +0,0 @@
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_readpc();
2:aa.h = op_readpc();
3:if($1)last_cycle();
op_writedbr(aa.w, $2);
if($1)end;
4:last_cycle();
op_writedbr(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_readpc();
2:aa.h = op_readpc();
3:cpu_io();
4:if($1)last_cycle();
op_writedbr(aa.w + regs.x.w, $2);
if($1)end;
5:last_cycle();
op_writedbr(aa.w + regs.x.w + 1, $2 >> 8);
}
sta_addry(0x99) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:cpu_io();
4:if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m)end;
5:last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}
sta_long(0x8f) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:aa.b = op_readpc();
4:if(regs.p.m)last_cycle();
op_writelong(aa.d, regs.a.l);
if(regs.p.m)end;
5:last_cycle();
op_writelong(aa.d + 1, regs.a.h);
}
sta_longx(0x9f) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:aa.b = op_readpc();
4:if(regs.p.m)last_cycle();
op_writelong(aa.d + regs.x.w, regs.a.l);
if(regs.p.m)end;
5:last_cycle();
op_writelong(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_readpc();
2:cpu_c2();
3:if($1)last_cycle();
op_writedp(dp, $2);
if($1)end;
4:last_cycle();
op_writedp(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_readpc();
2:cpu_c2();
3:cpu_io();
4:if($1)last_cycle();
op_writedp(dp + regs.x.w, $2);
if($1)end;
5:last_cycle();
op_writedp(dp + regs.x.w + 1, $2 >> 8);
}
stx_dpy(0x96) {
1:dp = op_readpc();
2:cpu_c2();
3:cpu_io();
4:if(regs.p.x)last_cycle();
op_writedp(dp + regs.y.w, regs.x.l);
if(regs.p.x)end;
5:last_cycle();
op_writedp(dp + regs.y.w + 1, regs.x.h);
}
sta_idp(0x92) {
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:if(regs.p.m)last_cycle();
op_writedbr(aa.w, regs.a.l);
if(regs.p.m)end;
6:last_cycle();
op_writedbr(aa.w + 1, regs.a.h);
}
sta_ildp(0x87) {
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:aa.b = op_readdp(dp + 2);
6:if(regs.p.m)last_cycle();
op_writelong(aa.d, regs.a.l);
if(regs.p.m)end;
7:last_cycle();
op_writelong(aa.d + 1, regs.a.h);
}
sta_idpx(0x81) {
1:dp = op_readpc();
2:cpu_c2();
3:cpu_io();
4:aa.l = op_readdp(dp + regs.x.w);
5:aa.h = op_readdp(dp + regs.x.w + 1);
6:if(regs.p.m)last_cycle();
op_writedbr(aa.w, regs.a.l);
if(regs.p.m)end;
7:last_cycle();
op_writedbr(aa.w + 1, regs.a.h);
}
sta_idpy(0x91) {
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:cpu_io();
6:if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m)end;
7:last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}
sta_ildpy(0x97) {
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:aa.b = op_readdp(dp + 2);
6:if(regs.p.m)last_cycle();
op_writelong(aa.d + regs.y.w, regs.a.l);
if(regs.p.m)end;
7:last_cycle();
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
}
sta_sr(0x83) {
1:sp = op_readpc();
2:cpu_io();
3:if(regs.p.m)last_cycle();
op_writesp(sp, regs.a.l);
if(regs.p.m)end;
4:last_cycle();
op_writesp(sp + 1, regs.a.h);
}
sta_isry(0x93) {
1:sp = op_readpc();
2:cpu_io();
3:aa.l = op_readsp(sp);
4:aa.h = op_readsp(sp + 1);
5:cpu_io();
6:if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m)end;
7:last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}

View File

@ -1,582 +0,0 @@
void bCPU::op_sta_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
if(regs.p.m)last_cycle();
op_writedbr(aa.w, regs.a.w);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_writedbr(aa.w + 1, regs.a.w >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_stx_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
if(regs.p.x)last_cycle();
op_writedbr(aa.w, regs.x.w);
if(regs.p.x)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_writedbr(aa.w + 1, regs.x.w >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sty_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
if(regs.p.x)last_cycle();
op_writedbr(aa.w, regs.y.w);
if(regs.p.x)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_writedbr(aa.w + 1, regs.y.w >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_stz_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
if(regs.p.m)last_cycle();
op_writedbr(aa.w, 0x0000);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_writedbr(aa.w + 1, 0x0000 >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_addrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
cpu_c4(aa.w, aa.w + regs.x.w);
} break;
case 4: {
if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.x.w, regs.a.w);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_writedbr(aa.w + regs.x.w + 1, regs.a.w >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_stz_addrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
cpu_c4(aa.w, aa.w + regs.x.w);
} break;
case 4: {
if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.x.w, 0x0000);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_writedbr(aa.w + regs.x.w + 1, 0x0000 >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_addry() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
cpu_c4(aa.w, aa.w + regs.y.w);
} break;
case 4: {
if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_long() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
aa.b = op_readpc();
} break;
case 4: {
if(regs.p.m)last_cycle();
op_writelong(aa.d, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_writelong(aa.d + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_longx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_readpc();
} break;
case 3: {
aa.b = op_readpc();
} break;
case 4: {
if(regs.p.m)last_cycle();
op_writelong(aa.d + regs.x.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
if(regs.p.m)last_cycle();
op_writedp(dp, regs.a.w);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_writedp(dp + 1, regs.a.w >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_stx_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
if(regs.p.x)last_cycle();
op_writedp(dp, regs.x.w);
if(regs.p.x)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_writedp(dp + 1, regs.x.w >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sty_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
if(regs.p.x)last_cycle();
op_writedp(dp, regs.y.w);
if(regs.p.x)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_writedp(dp + 1, regs.y.w >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_stz_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
if(regs.p.m)last_cycle();
op_writedp(dp, 0x0000);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_writedp(dp + 1, 0x0000 >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_dpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
cpu_io();
} break;
case 4: {
if(regs.p.m)last_cycle();
op_writedp(dp + regs.x.w, regs.a.w);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_writedp(dp + regs.x.w + 1, regs.a.w >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sty_dpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
cpu_io();
} break;
case 4: {
if(regs.p.x)last_cycle();
op_writedp(dp + regs.x.w, regs.y.w);
if(regs.p.x)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_writedp(dp + regs.x.w + 1, regs.y.w >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_stz_dpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
cpu_io();
} break;
case 4: {
if(regs.p.m)last_cycle();
op_writedp(dp + regs.x.w, 0x0000);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_writedp(dp + regs.x.w + 1, 0x0000 >> 8);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_stx_dpy() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
cpu_io();
} break;
case 4: {
if(regs.p.x)last_cycle();
op_writedp(dp + regs.y.w, regs.x.l);
if(regs.p.x)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_writedp(dp + regs.y.w + 1, regs.x.h);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_idp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
aa.l = op_readdp(dp);
} break;
case 4: {
aa.h = op_readdp(dp + 1);
} break;
case 5: {
if(regs.p.m)last_cycle();
op_writedbr(aa.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 6: {
last_cycle();
op_writedbr(aa.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_ildp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
aa.l = op_readdp(dp);
} break;
case 4: {
aa.h = op_readdp(dp + 1);
} break;
case 5: {
aa.b = op_readdp(dp + 2);
} break;
case 6: {
if(regs.p.m)last_cycle();
op_writelong(aa.d, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 7: {
last_cycle();
op_writelong(aa.d + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_idpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
cpu_io();
} break;
case 4: {
aa.l = op_readdp(dp + regs.x.w);
} break;
case 5: {
aa.h = op_readdp(dp + regs.x.w + 1);
} break;
case 6: {
if(regs.p.m)last_cycle();
op_writedbr(aa.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 7: {
last_cycle();
op_writedbr(aa.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_idpy() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
aa.l = op_readdp(dp);
} break;
case 4: {
aa.h = op_readdp(dp + 1);
} break;
case 5: {
cpu_c4(aa.w, aa.w + regs.y.w);
} break;
case 6: {
if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 7: {
last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_ildpy() {
switch(status.cycle_pos++) {
case 1: {
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
aa.l = op_readdp(dp);
} break;
case 4: {
aa.h = op_readdp(dp + 1);
} break;
case 5: {
aa.b = op_readdp(dp + 2);
} break;
case 6: {
if(regs.p.m)last_cycle();
op_writelong(aa.d + regs.y.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 7: {
last_cycle();
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_sr() {
switch(status.cycle_pos++) {
case 1: {
sp = op_readpc();
} break;
case 2: {
cpu_io();
} break;
case 3: {
if(regs.p.m)last_cycle();
op_writesp(sp, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_writesp(sp + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
}
void bCPU::op_sta_isry() {
switch(status.cycle_pos++) {
case 1: {
sp = op_readpc();
} break;
case 2: {
cpu_io();
} break;
case 3: {
aa.l = op_readsp(sp);
} break;
case 4: {
aa.h = op_readsp(sp + 1);
} break;
case 5: {
cpu_io();
} break;
case 6: {
if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 7: {
last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
}

View File

@ -1,377 +0,0 @@
//op_read
inline void bCPU::op_adc_b() {
int32 r = regs.a.l + rd.l + regs.p.c;
if(regs.p.d) {
uint8 n0 = (regs.a.l ) & 15;
uint8 n1 = (regs.a.l >> 4) & 15;
n0 += ((rd.l) & 15) + regs.p.c;
if(n0 > 9) {
n0 -= 10;
n0 &= 15;
n1++;
}
n1 += ((rd.l >> 4) & 15);
if(n1 > 9) {
n1 -= 10;
n1 &= 15;
regs.p.c = 1;
} else {
regs.p.c = 0;
}
r = (n1 << 4) | (n0);
} else {
r = regs.a.l + rd.l + regs.p.c;
regs.p.c = (r > 0xff);
}
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.a.l = r;
}
inline void bCPU::op_adc_w() {
int32 r;
if(regs.p.d) {
uint8 n0 = (regs.a.w ) & 15;
uint8 n1 = (regs.a.w >> 4) & 15;
uint8 n2 = (regs.a.w >> 8) & 15;
uint8 n3 = (regs.a.w >> 12) & 15;
n0 += ((rd.w) & 15) + regs.p.c;
if(n0 > 9) {
n0 -= 10;
n0 &= 15;
n1++;
}
n1 += ((rd.w >> 4) & 15);
if(n1 > 9) {
n1 -= 10;
n1 &= 15;
n2++;
}
n2 += ((rd.w >> 8) & 15);
if(n2 > 9) {
n2 -= 10;
n2 &= 15;
n3++;
}
n3 += ((rd.w >> 12) & 15);
if(n3 > 9) {
n3 -= 10;
n3 &= 15;
regs.p.c = 1;
} else {
regs.p.c = 0;
}
r = (n3 << 12) | (n2 << 8) | (n1 << 4) | (n0);
} else {
r = regs.a.w + rd.w + regs.p.c;
regs.p.c = (r > 0xffff);
}
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.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;
if(regs.p.d) {
uint8 n0 = (regs.a.l ) & 15;
uint8 n1 = (regs.a.l >> 4) & 15;
n0 -= ((rd.l ) & 15) + !regs.p.c;
n1 -= ((rd.l >> 4) & 15);
if(n0 > 9) {
n0 += 10;
n1--;
}
if(n1 > 9) {
n1 += 10;
regs.p.c = 0;
} else {
regs.p.c = 1;
}
r = (n1 << 4) | (n0);
} else {
r = regs.a.l - rd.l - !regs.p.c;
regs.p.c = (r >= 0);
}
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.a.l = r;
}
inline void bCPU::op_sbc_w() {
int32 r;
if(regs.p.d) {
uint8 n0 = (regs.a.w ) & 15;
uint8 n1 = (regs.a.w >> 4) & 15;
uint8 n2 = (regs.a.w >> 8) & 15;
uint8 n3 = (regs.a.w >> 12) & 15;
n0 -= ((rd.w ) & 15) + !regs.p.c;
n1 -= ((rd.w >> 4) & 15);
n2 -= ((rd.w >> 8) & 15);
n3 -= ((rd.w >> 12) & 15);
if(n0 > 9) {
n0 += 10;
n1--;
}
if(n1 > 9) {
n1 += 10;
n2--;
}
if(n2 > 9) {
n2 += 10;
n3--;
}
if(n3 > 9) {
n3 += 10;
regs.p.c = 0;
} else {
regs.p.c = 1;
}
r = (n3 << 12) | (n2 << 8) | (n1 << 4) | (n0);
} else {
r = regs.a.w - rd.w - !regs.p.c;
regs.p.c = (r >= 0);
}
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.a.w = r;
}
//op_rmw
inline void bCPU::op_inc_b() {
rd.l++;
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void bCPU::op_inc_w() {
rd.w++;
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void bCPU::op_dec_b() {
rd.l--;
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void bCPU::op_dec_w() {
rd.w--;
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void bCPU::op_asl_b() {
regs.p.c = !!(rd.l & 0x80);
rd.l <<= 1;
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void bCPU::op_asl_w() {
regs.p.c = !!(rd.w & 0x8000);
rd.w <<= 1;
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void bCPU::op_lsr_b() {
regs.p.c = rd.l & 1;
rd.l >>= 1;
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void bCPU::op_lsr_w() {
regs.p.c = rd.w & 1;
rd.w >>= 1;
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void bCPU::op_rol_b() {
uint16 c = regs.p.c;
regs.p.c = !!(rd.l & 0x80);
rd.l <<= 1;
rd.l |= c;
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void bCPU::op_rol_w() {
uint16 c = regs.p.c;
regs.p.c = !!(rd.w & 0x8000);
rd.w <<= 1;
rd.w |= c;
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void bCPU::op_ror_b() {
uint16 c = (regs.p.c)?0x80:0;
regs.p.c = rd.l & 1;
rd.l >>= 1;
rd.l |= c;
regs.p.n = !!(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void bCPU::op_ror_w() {
uint16 c = (regs.p.c)?0x8000:0;
regs.p.c = rd.w & 1;
rd.w >>= 1;
rd.w |= c;
regs.p.n = !!(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void bCPU::op_trb_b() {
regs.p.z = ((rd.l & regs.a.l) == 0);
rd.l &= ~regs.a.l;
}
inline void bCPU::op_trb_w() {
regs.p.z = ((rd.w & regs.a.w) == 0);
rd.w &= ~regs.a.w;
}
inline void bCPU::op_tsb_b() {
regs.p.z = ((rd.l & regs.a.l) == 0);
rd.l |= regs.a.l;
}
inline void bCPU::op_tsb_w() {
regs.p.z = ((rd.w & regs.a.w) == 0);
rd.w |= regs.a.w;
}

View File

@ -1,256 +0,0 @@
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[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[0x80] = &bCPU::op_bra;
optbl[0x82] = &bCPU::op_brl;
optbl[0x4c] = &bCPU::op_jmp_addr;
optbl[0x5c] = &bCPU::op_jmp_long;
optbl[0x6c] = &bCPU::op_jmp_iaddr;
optbl[0x7c] = &bCPU::op_jmp_iaddrx;
optbl[0xdc] = &bCPU::op_jmp_iladdr;
optbl[0x20] = &bCPU::op_jsr_addr;
optbl[0x22] = &bCPU::op_jsr_long;
optbl[0xfc] = &bCPU::op_jsr_iaddrx;
optbl[0x40] = &bCPU::op_rti;
optbl[0x60] = &bCPU::op_rts;
optbl[0x6b] = &bCPU::op_rtl;
optbl[0xea] = &bCPU::op_nop;
optbl[0x42] = &bCPU::op_wdm;
optbl[0xeb] = &bCPU::op_xba;
optbl[0x54] = &bCPU::op_mvn;
optbl[0x44] = &bCPU::op_mvp;
optbl[0x00] = &bCPU::op_brk;
optbl[0x02] = &bCPU::op_cop;
optbl[0xdb] = &bCPU::op_stp;
optbl[0xcb] = &bCPU::op_wai;
optbl[0xfb] = &bCPU::op_xce;
optbl[0x18] = &bCPU::op_clc;
optbl[0xd8] = &bCPU::op_cld;
optbl[0x58] = &bCPU::op_cli;
optbl[0xb8] = &bCPU::op_clv;
optbl[0x38] = &bCPU::op_sec;
optbl[0xf8] = &bCPU::op_sed;
optbl[0x78] = &bCPU::op_sei;
optbl[0xc2] = &bCPU::op_rep;
optbl[0xe2] = &bCPU::op_sep;
optbl[0xaa] = &bCPU::op_tax;
optbl[0xa8] = &bCPU::op_tay;
optbl[0x8a] = &bCPU::op_txa;
optbl[0x9b] = &bCPU::op_txy;
optbl[0x98] = &bCPU::op_tya;
optbl[0xbb] = &bCPU::op_tyx;
optbl[0x5b] = &bCPU::op_tcd;
optbl[0x1b] = &bCPU::op_tcs;
optbl[0x7b] = &bCPU::op_tdc;
optbl[0x3b] = &bCPU::op_tsc;
optbl[0xba] = &bCPU::op_tsx;
optbl[0x9a] = &bCPU::op_txs;
optbl[0x48] = &bCPU::op_pha;
optbl[0xda] = &bCPU::op_phx;
optbl[0x5a] = &bCPU::op_phy;
optbl[0x0b] = &bCPU::op_phd;
optbl[0x8b] = &bCPU::op_phb;
optbl[0x4b] = &bCPU::op_phk;
optbl[0x08] = &bCPU::op_php;
optbl[0x68] = &bCPU::op_pla;
optbl[0xfa] = &bCPU::op_plx;
optbl[0x7a] = &bCPU::op_ply;
optbl[0x2b] = &bCPU::op_pld;
optbl[0xab] = &bCPU::op_plb;
optbl[0x28] = &bCPU::op_plp;
optbl[0xf4] = &bCPU::op_pea;
optbl[0xd4] = &bCPU::op_pei;
optbl[0x62] = &bCPU::op_per;

View File

@ -1,260 +0,0 @@
/* used by both DMA and HDMA
* prevents transfer across same bus (a->a or b->b)
*/
void bCPU::dma_transfer_byte(bool direction, uint8 bbus, uint32 abus) {
uint8 r;
if(direction == 0) {
//read from address bus a, write to address bus b
//DMA address bus a cannot read from or write to the following addresses:
//$[00-3f|80-bf]:21[00-ff] <address bus b>
//$[00-3f|80-bf]:43[00-7f] <DMA control registers>
//$[00-3f|80-bf]:420b <DMA enable register>
//$[00-3f|80-bf]:420c <HDMA enable register>
if((abus & 0x40ff00) == 0x2100 || (abus & 0x40ff80) == 0x4300 ||
(abus & 0x40ffff) == 0x420b || (abus & 0x40ffff) == 0x420c) {
//these invalid reads will return open bus
r = r_cpu->regs.mdr;
} else {
r = r_mem->read(abus);
}
r_mem->write(0x2100 | bbus, r);
} else {
//read from address bus b, write to address bus a
//block invalid writes, see comments above
r = r_mem->read(0x2100 | bbus);
if((abus & 0x40ff00) == 0x2100 || (abus & 0x40ff80) == 0x4300 ||
(abus & 0x40ffff) == 0x420b || (abus & 0x40ffff) == 0x420c)return;
r_mem->write(abus, r);
}
}
uint8 bCPU::dma_bbus(uint8 i, uint8 index) {
switch(channel[i].xfermode) {
default:
case 0: return (channel[i].destaddr); break; //0
case 1: return (channel[i].destaddr + (index & 1)); break; //0,1
case 2: return (channel[i].destaddr); break; //0,0
case 3: return (channel[i].destaddr + ((index >> 1) & 1)); break; //0,0,1,1
case 4: return (channel[i].destaddr + (index & 3)); break; //0,1,2,3
case 5: return (channel[i].destaddr + (index & 1)); break; //0,1,0,1
case 6: return (channel[i].destaddr); break; //0,0 [2]
case 7: return (channel[i].destaddr + ((index >> 1) & 1)); break; //0,0,1,1 [3]
}
}
void bCPU::dma_add_cycles(uint32 cycles) {
status.dma_cycle_count += cycles;
}
void bCPU::hdma_add_cycles(uint32 cycles) {
if(run_state.dma) {
status.dma_cycle_count += cycles;
}
status.hdma_cycle_count += cycles;
}
uint32 bCPU::dma_addr(uint8 i) {
uint32 r;
r = (channel[i].srcbank << 16) | (channel[i].srcaddr);
if(channel[i].fixedxfer == false) {
channel[i].srcaddr += channel[i].incmode;
}
return r;
}
void bCPU::dma_cputommio(uint8 i, uint8 bbus) {
if(cartridge.info.sdd1 == true && sdd1->dma_active() == true) {
r_mem->write(0x2100 | bbus, sdd1->dma_read());
} else {
dma_transfer_byte(0, bbus, dma_addr(i));
}
add_cycles(8);
channel[i].xfersize--;
}
void bCPU::dma_mmiotocpu(uint8 i, uint8 bbus) {
dma_transfer_byte(1, bbus, dma_addr(i));
add_cycles(8);
channel[i].xfersize--;
}
void bCPU::dma_write(uint8 i, uint8 index) {
if(channel[i].direction == 0) {
dma_cputommio(i, index);
} else {
dma_mmiotocpu(i, index);
}
}
void bCPU::dma_run() {
for(int i = 0; i < 8; i++) {
if(channel[i].dma_enabled == false)continue;
//first byte transferred?
if(cartridge.info.sdd1 == true && channel[i].read_index == 0) {
sdd1->dma_begin(i, (channel[i].srcbank << 16) | (channel[i].srcaddr),
channel[i].xfersize);
}
dma_write(i, dma_bbus(i, channel[i].read_index++));
dma_add_cycles(8);
if(channel[i].xfersize == 0) {
channel[i].dma_enabled = false;
}
return;
}
status.dma_state = DMASTATE_CPUSYNC;
}
uint32 bCPU::hdma_addr(uint8 i) {
return (channel[i].srcbank << 16) | (channel[i].hdma_addr++);
}
uint32 bCPU::hdma_iaddr(uint8 i) {
return (channel[i].hdma_ibank << 16) | (channel[i].hdma_iaddr++);
}
void bCPU::hdma_update(uint8 i) {
channel[i].hdma_line_counter = r_mem->read(hdma_addr(i));
add_cycles(8);
hdma_add_cycles(8);
if(channel[i].hdma_indirect) {
channel[i].hdma_iaddr = r_mem->read(hdma_addr(i)) << 8;
add_cycles(8);
hdma_add_cycles(8);
}
if(channel[i].hdma_line_counter == 0) {
channel[i].hdma_completed = true;
channel[i].hdma_do_transfer = false;
return;
}
channel[i].hdma_do_transfer = true;
if(channel[i].hdma_indirect) {
channel[i].hdma_iaddr >>= 8;
channel[i].hdma_iaddr |= r_mem->read(hdma_addr(i)) << 8;
add_cycles(8);
hdma_add_cycles(8);
}
}
void bCPU::hdma_run() {
static uint8 hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
for(int i = 0; i < 8; i++) {
if(!channel[i].hdma_enabled || channel[i].hdma_completed)continue;
if(channel[i].hdma_do_transfer) {
int xferlen = hdma_xferlen[channel[i].xfermode];
for(channel[i].read_index = 0; channel[i].read_index < xferlen; channel[i].read_index++) {
if(bool(config::cpu.hdma_enable) == true) {
dma_transfer_byte(channel[i].direction, dma_bbus(i, channel[i].read_index),
channel[i].hdma_indirect ? hdma_iaddr(i) : hdma_addr(i));
}
add_cycles(8);
hdma_add_cycles(8);
}
}
channel[i].hdma_line_counter--;
channel[i].hdma_do_transfer = bool(channel[i].hdma_line_counter & 0x80);
if((channel[i].hdma_line_counter & 0x7f) == 0) {
hdma_update(i);
}
}
}
void bCPU::hdma_init() {
for(int i = 0; i < 8; i++) {
if(!channel[i].hdma_enabled)continue;
channel[i].hdma_addr = channel[i].srcaddr;
hdma_update(i);
}
}
uint8 bCPU::hdma_enabled_channels() {
int r = 0;
for(int i = 0; i < 8; i++) {
if(channel[i].hdma_enabled)r++;
}
return r;
}
uint8 bCPU::hdma_active_channels() {
int r = 0;
for(int i = 0; i < 8; i++) {
if(channel[i].hdma_enabled && !channel[i].hdma_completed)r++;
}
return r;
}
/* hdmainit_activate()
* hdma_activate()
*
* Functions are called by CPU timing routine
* when an HDMA event (init or run) occurs.
*/
void bCPU::hdmainit_activate() {
for(int i = 0; i < 8; i++) {
channel[i].hdma_completed = false;
channel[i].hdma_do_transfer = false;
}
if(hdma_enabled_channels() != 0) {
status.hdma_state = HDMASTATE_IDMASYNC;
run_state.hdma = true;
}
}
void bCPU::hdma_activate() {
if(hdma_active_channels() != 0) {
status.hdma_state = HDMASTATE_DMASYNC;
run_state.hdma = true;
}
}
void bCPU::dma_reset() {
status.dma_state = DMASTATE_CPUSYNC;
status.hdma_state = HDMASTATE_CPUSYNC;
status.dma_cycle_count = 0;
status.hdma_cycle_count = 0;
for(int i = 0; i < 8; i++) {
channel[i].read_index = 0;
channel[i].dma_enabled = false;
channel[i].hdma_enabled = false;
channel[i].dmap = 0xff;
channel[i].direction = 1;
channel[i].hdma_indirect = 1;
channel[i].incmode = -1;
channel[i].fixedxfer = 1;
channel[i].xfermode = 7;
channel[i].destaddr = 0xff;
channel[i].srcaddr = 0xffff;
channel[i].srcbank = 0xff;
channel[i].xfersize = 0xffff;
//xfersize and hdma_iaddr are of union { uint16 };
//channel[i].hdma_iaddr = 0xffff;
channel[i].hdma_ibank = 0xff;
channel[i].hdma_addr = 0xffff;
channel[i].hdma_line_counter = 0xff;
channel[i].hdma_unknown = 0xff;
channel[i].hdma_completed = false;
channel[i].hdma_do_transfer = false;
}
}

View File

@ -1,61 +0,0 @@
struct {
uint32 read_index; //set to 0 at beginning of DMA/HDMA
//$420b
bool dma_enabled;
//$420c
bool hdma_enabled;
//$43x0
uint8 dmap;
bool direction;
bool hdma_indirect;
int8 incmode;
bool fixedxfer;
uint8 xfermode;
//$43x1
uint8 destaddr;
//$43x2-$43x3
uint16 srcaddr;
//$43x4
uint8 srcbank;
//$43x5-$43x6
union {
uint16 xfersize;
uint16 hdma_iaddr;
};
//$43x7
uint8 hdma_ibank;
//$43x8-$43x9
uint16 hdma_addr;
//$43xa
uint8 hdma_line_counter;
//$43xb/$43xf
uint8 hdma_unknown;
//hdma-specific
bool hdma_completed; //for this frame
bool hdma_do_transfer;
uint8 hdma_current_channel;
uint8 hdma_current_pos;
} channel[8];
inline void dma_transfer_byte(bool direction, uint8 bbus, uint32 abus);
inline uint8 dma_bbus(uint8 i, uint8 index);
inline void dma_add_cycles(uint32 cycles);
inline void hdma_add_cycles(uint32 cycles);
inline void dma_run();
inline void hdma_run();
inline void hdma_init();
inline void hdma_update(uint8 i);
inline uint8 hdma_enabled_channels();
inline uint8 hdma_active_channels();
inline void hdmainit_activate();
inline void hdma_activate();
inline void dma_cputommio(uint8 i, uint8 index);
inline void dma_mmiotocpu(uint8 i, uint8 index);
inline void dma_write(uint8 i, uint8 index);
inline uint32 dma_addr(uint8 i);
inline uint32 hdma_addr(uint8 i);
inline uint32 hdma_iaddr(uint8 i);
inline void dma_reset();

View File

@ -1,40 +0,0 @@
uint8 bCPU::port_read(uint8 port) {
return apu_port[port & 3];
}
void bCPU::port_write(uint8 port, uint8 value) {
apu_port[port & 3] = value;
}
/* The next 3 functions control bus timing for the CPU.
* cpu_io is an I/O cycle, and always 6 clock cycles long.
* mem_read / mem_write indicate memory access bus cycle,
* they are either 6, 8, or 12 bus cycles long, depending
* both on location and the $420d.d0 FastROM enable bit.
*/
void bCPU::cpu_io() {
status.cycle_count = 6;
pre_exec_cycle();
add_cycles(6);
cycle_edge();
}
uint8 bCPU::mem_read(uint32 addr) {
status.cycle_count = r_mem->speed(addr);
pre_exec_cycle();
add_cycles(status.cycle_count - 4);
regs.mdr = r_mem->read(addr);
add_cycles(4);
cycle_edge();
return regs.mdr;
}
void bCPU::mem_write(uint32 addr, uint8 value) {
status.cycle_count = r_mem->speed(addr);
pre_exec_cycle();
add_cycles(status.cycle_count);
regs.mdr = value;
r_mem->write(addr, value);
cycle_edge();
}

View File

@ -1,27 +0,0 @@
uint8 apu_port[4];
inline uint8 port_read (uint8 port);
inline void port_write(uint8 port, uint8 value);
inline void cpu_io();
inline uint8 mem_read(uint32 addr);
inline void mem_write(uint32 addr, uint8 value);
/*****
* helper memory addressing functions used by CPU core
*****/
uint8 op_readpc () { return mem_read((regs.pc.b << 16) + regs.pc.w++); }
uint8 op_readstack() { (regs.e) ? regs.s.l++ : regs.s.w++; return mem_read(regs.s.w); }
uint8 op_readaddr (uint32 addr) { return mem_read(uclip<16>(addr)); }
uint8 op_readlong (uint32 addr) { return mem_read(uclip<24>(addr)); }
uint8 op_readdbr (uint32 addr) { return mem_read(uclip<24>((regs.db << 16) + addr)); }
uint8 op_readpbr (uint32 addr) { return mem_read((regs.pc.b << 16) + uclip<16>(addr)); }
uint8 op_readdp (uint32 addr) { return mem_read(uclip<16>(regs.d + uclip<16>(addr))); }
uint8 op_readsp (uint32 addr) { return mem_read(uclip<16>(regs.s + uclip<16>(addr))); }
void op_writestack(uint8 data) { mem_write(regs.s.w, data); (regs.e) ? regs.s.l-- : regs.s.w--; }
void op_writeaddr (uint32 addr, uint8 data) { mem_write(uclip<16>(addr), data); }
void op_writelong (uint32 addr, uint8 data) { mem_write(uclip<24>(addr), data); }
void op_writedbr (uint32 addr, uint8 data) { mem_write(uclip<24>((regs.db << 16) + addr), data); }
void op_writepbr (uint32 addr, uint8 data) { mem_write((regs.pc.b << 16) + uclip<16>(addr), data); }
void op_writedp (uint32 addr, uint8 data) { mem_write(uclip<16>(regs.d + uclip<16>(addr)), data); }
void op_writesp (uint32 addr, uint8 data) { mem_write(uclip<16>(regs.s + uclip<16>(addr)), data); }

View File

@ -1,338 +0,0 @@
/* Notes about PAL timing:
* As I do not have PAL hardware to run timing tests on, I've
* had to guess on a lot of things. Below is how I've arrived
* at various calculations:
*
* NTSC timing crystal: ~21477272hz
* PAL timing crystal: ~21281370hz
* NTSC ~60fps, PAL ~50fps
* NTSC ~262 lines/frame, PAL ~312 lines/frame
* NTSC 21477272 / (262 * 60) = ~1366 cycles/line
* PAL 21281370 / (312 * 50) = ~1364 cycles/line
*
* As the cycles/line are very close between the two systems,
* I have left the known NTSC anomalies intact for PAL timing.
* In reality, some of these may not exist, and some may be
* slightly different.
*
* [known]
* - DRAM refresh occurs at about the same time every
* scanline on PAL units (per Overload).
* [unknown]
* - Are dots 323/327 still 2 cycles longer than the
* other dots?
* - Is scanline 240 on non-interlace odd frames still
* 4 cycles short?
*/
uint16 bCPU::vcounter() { return time.v; }
uint16 bCPU::hclock() { return time.hc; }
bool bCPU::interlace() { return time.interlace; }
bool bCPU::interlace_field() { return time.interlace_field; }
bool bCPU::overscan() { return time.overscan; }
uint16 bCPU::region_scanlines() { return time.region_scanlines; }
void bCPU::set_interlace(bool r) { time.interlace = r; update_interrupts(); }
void bCPU::set_overscan (bool r) { time.overscan = r; update_interrupts(); }
uint8 bCPU::dma_counter() { return (time.dma_counter + time.hc) & 6; }
uint16 bCPU::hcounter() {
if(time.v == 240 && time.interlace == false && time.interlace_field == 1) {
return time.hc >> 2;
}
return (time.hc - ((time.hc > 1292) << 1) - ((time.hc > 1310) << 1)) >> 2;
}
bool bCPU::nmi_trigger_pos_match(uint32 offset) {
uint16 v = overscan() ? 240 : 225;
uint16 hc = 2 + offset;
return (time.v == v && time.hc == hc);
}
bool bCPU::irq_trigger_pos_match(uint32 offset) {
uint16 v = status.virq_pos;
uint16 hc = (status.hirq_enabled) ? status.hirq_pos : 0;
uint16 vlimit = region_scanlines() >> 1;
//positions that can never be latched
//region_scanlines() = 525/NTSC, 625/PAL
//PAL results are unverified on hardware
if(v == 240 && hc == 339 && interlace() == false && interlace_field() == 1)return false;
if(v == (vlimit - 1) && hc == 339 && interlace() == false)return false;
if(v == vlimit && interlace() == false)return false;
if(v == vlimit && hc == 339)return false;
if(v > vlimit)return false;
if(hc > 339)return false;
hc = (hc != 0) ? ((hc << 2) + 14) : 10;
hc += offset;
if(hc >= time.line_cycles) {
hc -= time.line_cycles;
if(++v >= time.frame_lines) {
v = 0;
}
}
if((status.virq_enabled == true && time.v == v) || status.virq_enabled == false) {
return (time.hc == hc);
}
return false;
}
void bCPU::update_nmi() {
if(time.v == (overscan() ? 240 : 225)) {
time.nmi_read_trigger_pos = 2;
time.nmi_line_trigger_pos = 6;
} else {
time.nmi_read_trigger_pos = -64;
time.nmi_line_trigger_pos = -64;
}
}
void bCPU::update_irq() {
int vpos = status.virq_pos;
int hpos = (status.hirq_enabled) ? status.hirq_pos : 0;
int vlimit = region_scanlines() >> 1;
//positions that can never be latched
//region_scanlines() = 262/NTSC, 312/PAL
//PAL results are unverified on hardware
if(vpos == 240 && hpos == 339 && interlace() == false && interlace_field() == 1)goto _nolatch;
if(vpos == (vlimit - 1) && hpos == 339 && interlace() == false)goto _nolatch;
if(vpos == vlimit && interlace() == false)goto _nolatch;
if(vpos == vlimit && hpos == 339)goto _nolatch;
if(vpos > vlimit)goto _nolatch;
if(hpos > 339)goto _nolatch;
hpos = (hpos != 0) ? ((hpos << 2) + 14) : 10;
if(hpos >= time.line_cycles) {
hpos -= time.line_cycles;
if(++vpos >= time.frame_lines) {
vpos = 0;
}
}
if((status.virq_enabled == true && time.v == vpos) || status.virq_enabled == false) {
time.irq_read_trigger_pos = hpos;
} else {
time.irq_read_trigger_pos = -64;
}
hpos += 4;
if(hpos >= time.line_cycles) {
hpos -= time.line_cycles;
if(++vpos >= time.frame_lines) {
vpos = 0;
}
}
if((status.virq_enabled == true && time.v == vpos) || status.virq_enabled == false) {
time.irq_line_trigger_pos = hpos;
} else {
time.irq_line_trigger_pos = -64;
}
return;
_nolatch:
time.irq_read_trigger_pos = -64;
time.irq_line_trigger_pos = -64;
}
void bCPU::update_interrupts() {
update_nmi();
update_irq();
}
void bCPU::poll_interrupts(int cycles) {
int16 hc, hc_end;
if(time.hc == 0) {
hc = -1;
hc_end = cycles;
} else {
hc = time.hc;
hc_end = time.hc + cycles;
}
if(hc < time.nmi_read_trigger_pos && time.nmi_read_trigger_pos <= hc_end) {
//nmi_read can go low even with NMI interrupts disabled in $4200.d7
time.nmi_read = 0;
}
if(hc < time.nmi_line_trigger_pos && time.nmi_line_trigger_pos <= hc_end) {
if(status.nmi_enabled == true) {
if(time.nmi_line == 1) {
time.nmi_transition = 1;
}
time.nmi_line = 0;
}
}
if(hc < time.irq_read_trigger_pos && time.irq_read_trigger_pos <= hc_end) {
if(status.virq_enabled == true || status.hirq_enabled == true) {
time.irq_read = 0;
}
}
if(hc < time.irq_line_trigger_pos && time.irq_line_trigger_pos <= hc_end) {
if(status.virq_enabled == true || status.hirq_enabled == true) {
time.irq_line = 0;
time.irq_transition = 1;
}
}
}
uint32 bCPU::clocks_executed() {
uint32 r = status.cycles_executed;
status.cycles_executed = 0;
return r;
}
void bCPU::cycle_edge() {
if(time.line_rendered == false) {
if(time.hc >= 192) {
time.line_rendered = true;
r_ppu->render_scanline();
}
}
if(time.hdmainit_triggered == false) {
if(time.hc >= time.hdmainit_trigger_pos || time.v) {
time.hdmainit_triggered = true;
hdmainit_activate();
}
}
if(time.hdma_triggered == false) {
//hdma_triggered only set to false for v <= (overscan ? 239 : 224)
if(time.hc >= 1106) {
time.hdma_triggered = true;
hdma_activate();
}
}
}
void bCPU::add_cycles(int cycles) {
status.cycles_executed += cycles;
poll_interrupts(cycles);
if(time.hc + cycles >= time.line_cycles) {
cycles = (time.hc + cycles) - time.line_cycles;
time.hc = 0;
scanline();
poll_interrupts(cycles);
}
time.hc += cycles;
if(time.dram_refreshed == false) {
if(time.hc >= time.dram_refresh_pos) {
time.dram_refreshed = true;
add_cycles(40);
return;
}
}
}
void bCPU::scanline() {
if(++time.v >= time.frame_lines) {
frame();
}
time.dma_counter += time.line_cycles;
if(time.v == 240 && time.interlace == false && time.interlace_field == 1) {
time.line_cycles = 1360;
} else {
time.line_cycles = 1364;
}
time.dram_refreshed = false;
time.line_rendered =
time.hdma_triggered = (time.v <= (!overscan() ? 224 : 239)) ? false : true;
r_ppu->scanline();
snes->scanline();
update_interrupts();
if(vcounter() == (!overscan() ? 227 : 242) && 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.
status.joypad1_read_pos = 16;
status.joypad2_read_pos = 16;
}
}
void bCPU::frame() {
time.nmi_read = 1;
time.nmi_line = 1;
time.nmi_transition = 0;
time.v = 0;
time.interlace_field ^= 1;
if(interlace() == true && interlace_field() == 0) {
time.frame_lines = (time.region_scanlines >> 1) + 1;
} else {
time.frame_lines = (time.region_scanlines >> 1);
}
if(cpu_version == 2) {
time.hdmainit_trigger_pos = 12 + dma_counter();
} else {
time.hdmainit_trigger_pos = 12 + 8 - dma_counter();
}
time.hdmainit_triggered = false;
r_ppu->frame();
snes->frame();
}
void bCPU::time_reset() {
time.v = 0;
time.hc = 0;
//upon SNES reset, start at scanline 0 non-interlace
time.interlace = 0;
time.interlace_field = 0;
time.overscan = false;
time.line_cycles = 1364;
time.dram_refreshed = false;
time.dram_refresh_pos = (cpu_version == 2) ? 538 : 530;
time.dma_counter = 0;
//set at V=0,H=0
time.hdmainit_trigger_pos = 0;
time.hdmainit_triggered = true;
time.hdma_triggered = false;
time.nmi_pending = false;
time.irq_pending = false;
time.nmi_line = time.nmi_read = 1;
time.irq_line = time.irq_read = 1;
time.nmi_transition = 0;
time.irq_transition = 0;
update_interrupts();
switch(region) {
case NTSC:
time.region_scanlines = 525;
break;
case PAL:
time.region_scanlines = 625;
break;
}
time.frame_lines = time.region_scanlines >> 1;
}

View File

@ -1,74 +0,0 @@
struct {
uint16 v, hc;
bool interlace, interlace_field, overscan;
uint16 line_cycles, frame_lines;
bool line_rendered;
bool dram_refreshed;
uint16 dram_refresh_pos;
uint8 dma_counter;
uint16 hdmainit_trigger_pos;
bool hdmainit_triggered;
bool hdma_triggered;
uint16 region_scanlines;
//nmi_pending, irq_pending are used by last_cycle()
//nmi_line = /NMI, nmi_read = $4210.7
//irq_line = /IRQ, irq_read = $4211.7
bool nmi_pending, nmi_line, nmi_read;
bool irq_pending, irq_line, irq_read;
//NMI is edge-sensitive, meaning it triggers when /NMI
//transitions from high to low. This value is set to 1
//when that happens, and cleared after the nmi_test()
//routine acknowledges it and invokes the NMI interrupt
bool nmi_transition;
//IRQ is level-sensitive, so it does not need to keep
//track of transitions from high to low. IRQs will
//continue to fire as long as /IRQ stays low.
//However, if a write to $4200 forces IRQs high at the
//exact same clock cycle that /IRQ goes low, the /IRQ
//will still occur. Hence the need for this variable.
bool irq_transition;
//position is relative to time.hc, set at start of each scanline
//-64 means no trigger point on this scanline
//$4210/$4211 status bits get set before /NMI and /IRQ go low,
//hence the need for two variables for each.
int32 nmi_read_trigger_pos, nmi_line_trigger_pos;
int32 irq_read_trigger_pos, irq_line_trigger_pos;
} time;
inline uint16 vcounter();
inline uint16 hcounter();
inline uint16 hclock();
inline bool interlace();
inline bool interlace_field();
inline bool overscan();
inline uint16 region_scanlines();
inline bool nmi_trigger_pos_match(uint32 offset);
inline bool irq_trigger_pos_match(uint32 offset);
inline void update_nmi();
inline void update_irq();
inline void update_interrupts();
inline void poll_interrupts(int cycles);
inline void set_interlace(bool r);
inline void set_overscan (bool r);
inline uint8 dma_counter();
inline void cycle_edge();
inline void add_cycles(int cycles);
inline void scanline();
inline void frame();
inline void time_reset();

View File

@ -1,6 +1,10 @@
#include "cpuregs.h"
class CPU : public MMIO {
public:
thread_t thread;
virtual void enter() = 0;
public:
//CPU version number
//* 1 and 2 are known
@ -30,9 +34,6 @@ CPURegs regs;
FLAG_Z = 0x02, FLAG_C = 0x01
};
virtual uint8 pio_status() = 0;
virtual void main() {}
virtual void run() = 0;
virtual uint32 clocks_executed() = 0;
virtual void scanline() = 0;
virtual void frame() = 0;
virtual void power() = 0;

View File

@ -71,6 +71,5 @@ CPURegFlags p;
uint8 db;
uint8 mdr;
bool e;
bool acc_8b, idx_8b;
CPURegs() : db(0), mdr(0x00), e(false), acc_8b(true), idx_8b(true) {}
CPURegs() : db(0), mdr(0x00), e(false) {}
};

View File

@ -1,6 +1,6 @@
#include "opfn.cpp"
void sCPU::main() {
void sCPU::enter() {
for(;;) {
if(event.irq) {
event.irq = false;
@ -27,10 +27,6 @@ void sCPU::main() {
}
status.in_opcode = false;
#ifdef FAVOR_SPEED
co_return();
#endif
}
}

View File

@ -3,10 +3,9 @@
CPUReg24 aa, rd;
uint8 dp, sp;
inline void main();
inline void op_irq();
void op_irq();
inline bool in_opcode() { return status.in_opcode; }
inline bool in_opcode() { return status.in_opcode; }
//op_read
void op_adc_b();

View File

@ -15,7 +15,7 @@ xba(0xeb) {
regs.a.l ^= regs.a.h;
regs.a.h ^= regs.a.l;
regs.a.l ^= regs.a.h;
regs.p.n = bool(regs.a.l & 0x80);
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
@ -27,10 +27,12 @@ mvp(0x44, --) {
rd.l = op_readlong((sp << 16) | regs.x.w);
4:op_writelong((dp << 16) | regs.y.w, rd.l);
5:op_io();
if(regs.idx_8b) {
regs.x.l $1; regs.y.l $1;
if(regs.p.x) {
regs.x.l $1;
regs.y.l $1;
} else {
regs.x.w $1; regs.y.w $1;
regs.x.w $1;
regs.y.w $1;
}
6:last_cycle();
op_io();
@ -58,7 +60,6 @@ stp(0xdb) {
2:last_cycle();
while(1) {
op_io();
co_return();
}
}
@ -70,7 +71,6 @@ wai(0xcb) {
3:while(event.wai) {
last_cycle();
op_io();
co_return();
}
}
@ -80,10 +80,11 @@ xce(0xfb) {
bool c = regs.p.c;
regs.p.c = regs.e;
regs.e = c;
if(regs.e)regs.s.h = 0x01;
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
if(regs.e) {
regs.p |= 0x30;
regs.s.h = 0x01;
}
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
@ -107,29 +108,28 @@ sep(0xe2, |=) {
2:last_cycle();
op_io();
regs.p $1 rd.l;
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
}
tax(0xaa, regs.idx_8b, x, a),
tay(0xa8, regs.idx_8b, y, a),
txa(0x8a, regs.acc_8b, a, x),
txy(0x9b, regs.idx_8b, y, x),
tya(0x98, regs.acc_8b, a, y),
tyx(0xbb, regs.idx_8b, x, y) {
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:last_cycle();
op_io();
if($1) {
regs.$2.l = regs.$3.l;
regs.p.n = bool(regs.$2.l & 0x80);
regs.p.n = !!(regs.$2.l & 0x80);
regs.p.z = (regs.$2.l == 0);
} else {
regs.$2.w = regs.$3.w;
regs.p.n = bool(regs.$2.w & 0x8000);
regs.p.n = !!(regs.$2.w & 0x8000);
regs.p.z = (regs.$2.w == 0);
}
}
@ -138,7 +138,7 @@ tcd(0x5b) {
1:last_cycle();
op_io();
regs.d.w = regs.a.w;
regs.p.n = bool(regs.d.w & 0x8000);
regs.p.n = !!(regs.d.w & 0x8000);
regs.p.z = (regs.d.w == 0);
}
@ -153,7 +153,7 @@ tdc(0x7b) {
1:last_cycle();
op_io();
regs.a.w = regs.d.w;
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
@ -162,10 +162,10 @@ tsc(0x3b) {
op_io();
regs.a.w = regs.s.w;
if(regs.e) {
regs.p.n = bool(regs.a.l & 0x80);
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
@ -173,13 +173,13 @@ tsc(0x3b) {
tsx(0xba) {
1:last_cycle();
op_io();
if(regs.idx_8b) {
if(regs.p.x) {
regs.x.l = regs.s.l;
regs.p.n = bool(regs.x.l & 0x80);
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
} else {
regs.x.w = regs.s.w;
regs.p.n = bool(regs.x.w & 0x8000);
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
}
@ -194,16 +194,23 @@ txs(0x9a) {
}
}
pha(0x48, regs.acc_8b, a),
phx(0xda, regs.idx_8b, x),
phy(0x5a, regs.idx_8b, y),
phd(0x0b, 0, d) {
pha(0x48, regs.p.m, a),
phx(0xda, regs.p.x, x),
phy(0x5a, regs.p.x, y) {
1:op_io();
2:if(!$1)op_writestack(regs.$2.h);
3:last_cycle();
op_writestack(regs.$2.l);
}
phd(0x0b) {
1:op_io();
2:op_writestackn(regs.d.h);
3:last_cycle();
op_writestackn(regs.d.l);
if(regs.e)regs.s.h = 0x01;
}
phb(0x8b, regs.db),
phk(0x4b, regs.pc.b),
php(0x08, regs.p) {
@ -212,31 +219,41 @@ php(0x08, regs.p) {
op_writestack($1);
}
pla(0x68, regs.acc_8b, a),
plx(0xfa, regs.idx_8b, x),
ply(0x7a, regs.idx_8b, y),
pld(0x2b, 0, d) {
pla(0x68, regs.p.m, a),
plx(0xfa, regs.p.x, x),
ply(0x7a, regs.p.x, y) {
1:op_io();
2:op_io();
3:if($1)last_cycle();
regs.$2.l = op_readstack();
if($1) {
regs.p.n = bool(regs.$2.l & 0x80);
regs.p.n = !!(regs.$2.l & 0x80);
regs.p.z = (regs.$2.l == 0);
end;
}
4:last_cycle();
regs.$2.h = op_readstack();
regs.p.n = bool(regs.$2.w & 0x8000);
regs.p.n = !!(regs.$2.w & 0x8000);
regs.p.z = (regs.$2.w == 0);
}
pld(0x2b) {
1:op_io();
2:op_io();
3:regs.d.l = op_readstackn();
4:last_cycle();
regs.d.h = op_readstackn();
regs.p.n = !!(regs.d.w & 0x8000);
regs.p.z = (regs.d.w == 0);
if(regs.e)regs.s.h = 0x01;
}
plb(0xab) {
1:op_io();
2:op_io();
3:last_cycle();
regs.db = op_readstack();
regs.p.n = bool(regs.db & 0x80);
regs.p.n = !!(regs.db & 0x80);
regs.p.z = (regs.db == 0);
}
@ -245,9 +262,8 @@ plp(0x28) {
2:op_io();
3:last_cycle();
regs.p = op_readstack();
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
@ -256,9 +272,10 @@ plp(0x28) {
pea(0xf4) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:op_writestack(aa.h);
3:op_writestackn(aa.h);
4:last_cycle();
op_writestack(aa.l);
op_writestackn(aa.l);
if(regs.e)regs.s.h = 0x01;
}
pei(0xd4) {
@ -266,9 +283,10 @@ pei(0xd4) {
2:op_io_cond2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:op_writestack(aa.h);
5:op_writestackn(aa.h);
6:last_cycle();
op_writestack(aa.l);
op_writestackn(aa.l);
if(regs.e)regs.s.h = 0x01;
}
per(0x62) {
@ -276,7 +294,8 @@ per(0x62) {
2:aa.h = op_readpc();
3:op_io();
rd.w = regs.pc.d + (int16)aa.w;
4:op_writestack(rd.h);
4:op_writestackn(rd.h);
5:last_cycle();
op_writestack(rd.l);
op_writestackn(rd.l);
if(regs.e)regs.s.h = 0x01;
}

View File

@ -18,7 +18,7 @@ case 0xeb: {
regs.a.l ^= regs.a.h;
regs.a.h ^= regs.a.l;
regs.a.l ^= regs.a.h;
regs.p.n = bool(regs.a.l & 0x80);
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} break;
@ -30,10 +30,12 @@ case 0x54: {
rd.l = op_readlong((sp << 16) | regs.x.w);
op_writelong((dp << 16) | regs.y.w, rd.l);
op_io();
if(regs.idx_8b) {
regs.x.l ++; regs.y.l ++;
if(regs.p.x) {
regs.x.l ++;
regs.y.l ++;
} else {
regs.x.w ++; regs.y.w ++;
regs.x.w ++;
regs.y.w ++;
}
last_cycle();
op_io();
@ -48,10 +50,12 @@ case 0x44: {
rd.l = op_readlong((sp << 16) | regs.x.w);
op_writelong((dp << 16) | regs.y.w, rd.l);
op_io();
if(regs.idx_8b) {
regs.x.l --; regs.y.l --;
if(regs.p.x) {
regs.x.l --;
regs.y.l --;
} else {
regs.x.w --; regs.y.w --;
regs.x.w --;
regs.y.w --;
}
last_cycle();
op_io();
@ -96,7 +100,6 @@ case 0xdb: {
last_cycle();
while(1) {
op_io();
co_return();
}
} break;
@ -109,7 +112,6 @@ case 0xcb: {
while(event.wai) {
last_cycle();
op_io();
co_return();
}
} break;
@ -120,10 +122,11 @@ case 0xfb: {
bool c = regs.p.c;
regs.p.c = regs.e;
regs.e = c;
if(regs.e)regs.s.h = 0x01;
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
if(regs.e) {
regs.p |= 0x30;
regs.s.h = 0x01;
}
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
@ -184,9 +187,8 @@ case 0xc2: {
last_cycle();
op_io();
regs.p &=~ rd.l;
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
@ -198,9 +200,8 @@ case 0xe2: {
last_cycle();
op_io();
regs.p |= rd.l;
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
@ -210,13 +211,13 @@ case 0xe2: {
case 0xaa: {
last_cycle();
op_io();
if(regs.idx_8b) {
if(regs.p.x) {
regs.x.l = regs.a.l;
regs.p.n = bool(regs.x.l & 0x80);
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
} else {
regs.x.w = regs.a.w;
regs.p.n = bool(regs.x.w & 0x8000);
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
} break;
@ -225,13 +226,13 @@ case 0xaa: {
case 0xa8: {
last_cycle();
op_io();
if(regs.idx_8b) {
if(regs.p.x) {
regs.y.l = regs.a.l;
regs.p.n = bool(regs.y.l & 0x80);
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
} else {
regs.y.w = regs.a.w;
regs.p.n = bool(regs.y.w & 0x8000);
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
} break;
@ -240,13 +241,13 @@ case 0xa8: {
case 0x8a: {
last_cycle();
op_io();
if(regs.acc_8b) {
if(regs.p.m) {
regs.a.l = regs.x.l;
regs.p.n = bool(regs.a.l & 0x80);
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.a.w = regs.x.w;
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
} break;
@ -255,13 +256,13 @@ case 0x8a: {
case 0x9b: {
last_cycle();
op_io();
if(regs.idx_8b) {
if(regs.p.x) {
regs.y.l = regs.x.l;
regs.p.n = bool(regs.y.l & 0x80);
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
} else {
regs.y.w = regs.x.w;
regs.p.n = bool(regs.y.w & 0x8000);
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
} break;
@ -270,13 +271,13 @@ case 0x9b: {
case 0x98: {
last_cycle();
op_io();
if(regs.acc_8b) {
if(regs.p.m) {
regs.a.l = regs.y.l;
regs.p.n = bool(regs.a.l & 0x80);
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.a.w = regs.y.w;
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
} break;
@ -285,13 +286,13 @@ case 0x98: {
case 0xbb: {
last_cycle();
op_io();
if(regs.idx_8b) {
if(regs.p.x) {
regs.x.l = regs.y.l;
regs.p.n = bool(regs.x.l & 0x80);
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
} else {
regs.x.w = regs.y.w;
regs.p.n = bool(regs.x.w & 0x8000);
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
} break;
@ -301,7 +302,7 @@ case 0x5b: {
last_cycle();
op_io();
regs.d.w = regs.a.w;
regs.p.n = bool(regs.d.w & 0x8000);
regs.p.n = !!(regs.d.w & 0x8000);
regs.p.z = (regs.d.w == 0);
} break;
@ -318,7 +319,7 @@ case 0x7b: {
last_cycle();
op_io();
regs.a.w = regs.d.w;
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
} break;
@ -328,10 +329,10 @@ case 0x3b: {
op_io();
regs.a.w = regs.s.w;
if(regs.e) {
regs.p.n = bool(regs.a.l & 0x80);
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
} break;
@ -340,13 +341,13 @@ case 0x3b: {
case 0xba: {
last_cycle();
op_io();
if(regs.idx_8b) {
if(regs.p.x) {
regs.x.l = regs.s.l;
regs.p.n = bool(regs.x.l & 0x80);
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
} else {
regs.x.w = regs.s.w;
regs.p.n = bool(regs.x.w & 0x8000);
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
} break;
@ -365,7 +366,7 @@ case 0x9a: {
//pha
case 0x48: {
op_io();
if(!regs.acc_8b)op_writestack(regs.a.h);
if(!regs.p.m)op_writestack(regs.a.h);
last_cycle();
op_writestack(regs.a.l);
} break;
@ -373,7 +374,7 @@ case 0x48: {
//phx
case 0xda: {
op_io();
if(!regs.idx_8b)op_writestack(regs.x.h);
if(!regs.p.x)op_writestack(regs.x.h);
last_cycle();
op_writestack(regs.x.l);
} break;
@ -381,7 +382,7 @@ case 0xda: {
//phy
case 0x5a: {
op_io();
if(!regs.idx_8b)op_writestack(regs.y.h);
if(!regs.p.x)op_writestack(regs.y.h);
last_cycle();
op_writestack(regs.y.l);
} break;
@ -389,9 +390,10 @@ case 0x5a: {
//phd
case 0x0b: {
op_io();
if(!0)op_writestack(regs. d.h);
op_writestackn(regs.d.h);
last_cycle();
op_writestack(regs. d.l);
op_writestackn(regs.d.l);
if(regs.e)regs.s.h = 0x01;
} break;
//phb
@ -419,16 +421,16 @@ case 0x08: {
case 0x68: {
op_io();
op_io();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
regs.a.l = op_readstack();
if(regs.acc_8b) {
regs.p.n = bool(regs.a.l & 0x80);
if(regs.p.m) {
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
break;
}
last_cycle();
regs.a.h = op_readstack();
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
} break;
@ -436,16 +438,16 @@ case 0x68: {
case 0xfa: {
op_io();
op_io();
if(regs.idx_8b)last_cycle();
if(regs.p.x)last_cycle();
regs.x.l = op_readstack();
if(regs.idx_8b) {
regs.p.n = bool(regs.x.l & 0x80);
if(regs.p.x) {
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
break;
}
last_cycle();
regs.x.h = op_readstack();
regs.p.n = bool(regs.x.w & 0x8000);
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
} break;
@ -453,16 +455,16 @@ case 0xfa: {
case 0x7a: {
op_io();
op_io();
if(regs.idx_8b)last_cycle();
if(regs.p.x)last_cycle();
regs.y.l = op_readstack();
if(regs.idx_8b) {
regs.p.n = bool(regs.y.l & 0x80);
if(regs.p.x) {
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
break;
}
last_cycle();
regs.y.h = op_readstack();
regs.p.n = bool(regs.y.w & 0x8000);
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
} break;
@ -470,17 +472,12 @@ case 0x7a: {
case 0x2b: {
op_io();
op_io();
if(0)last_cycle();
regs. d.l = op_readstack();
if(0) {
regs.p.n = bool(regs. d.l & 0x80);
regs.p.z = (regs. d.l == 0);
break;
}
regs.d.l = op_readstackn();
last_cycle();
regs. d.h = op_readstack();
regs.p.n = bool(regs. d.w & 0x8000);
regs.p.z = (regs. d.w == 0);
regs.d.h = op_readstackn();
regs.p.n = !!(regs.d.w & 0x8000);
regs.p.z = (regs.d.w == 0);
if(regs.e)regs.s.h = 0x01;
} break;
//plb
@ -489,7 +486,7 @@ case 0xab: {
op_io();
last_cycle();
regs.db = op_readstack();
regs.p.n = bool(regs.db & 0x80);
regs.p.n = !!(regs.db & 0x80);
regs.p.z = (regs.db == 0);
} break;
@ -499,9 +496,8 @@ case 0x28: {
op_io();
last_cycle();
regs.p = op_readstack();
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
@ -511,9 +507,10 @@ case 0x28: {
case 0xf4: {
aa.l = op_readpc();
aa.h = op_readpc();
op_writestack(aa.h);
op_writestackn(aa.h);
last_cycle();
op_writestack(aa.l);
op_writestackn(aa.l);
if(regs.e)regs.s.h = 0x01;
} break;
//pei
@ -522,9 +519,10 @@ case 0xd4: {
op_io_cond2();
aa.l = op_readdp(dp);
aa.h = op_readdp(dp + 1);
op_writestack(aa.h);
op_writestackn(aa.h);
last_cycle();
op_writestack(aa.l);
op_writestackn(aa.l);
if(regs.e)regs.s.h = 0x01;
} break;
//per
@ -533,8 +531,9 @@ case 0x62: {
aa.h = op_readpc();
op_io();
rd.w = regs.pc.d + (int16)aa.w;
op_writestack(rd.h);
op_writestackn(rd.h);
last_cycle();
op_writestack(rd.l);
op_writestackn(rd.l);
if(regs.e)regs.s.h = 0x01;
} break;

View File

@ -48,7 +48,7 @@ jmp_long(0x5c) {
2:rd.h = op_readpc();
3:last_cycle();
rd.b = op_readpc();
regs.pc.d = uclip<24>(rd.d);
regs.pc.d = rd.d & 0xffffff;
}
jmp_iaddr(0x6c) {
@ -77,7 +77,7 @@ jmp_iladdr(0xdc) {
4:rd.h = op_readaddr(aa.w + 1);
5:last_cycle();
rd.b = op_readaddr(aa.w + 2);
regs.pc.d = uclip<24>(rd.d);
regs.pc.d = rd.d & 0xffffff;
}
jsr_addr(0x20) {
@ -94,35 +94,36 @@ jsr_addr(0x20) {
jsr_long(0x22) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:op_writestack(regs.pc.b);
3:op_writestackn(regs.pc.b);
4:op_io();
5:aa.b = op_readpc();
6:regs.pc.w--;
op_writestack(regs.pc.h);
op_writestackn(regs.pc.h);
7:last_cycle();
op_writestack(regs.pc.l);
regs.pc.d = uclip<24>(aa.d);
op_writestackn(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
if(regs.e)regs.s.h = 0x01;
}
jsr_iaddrx(0xfc) {
1:aa.l = op_readpc();
2:op_writestack(regs.pc.h);
3:op_writestack(regs.pc.l);
2:op_writestackn(regs.pc.h);
3:op_writestackn(regs.pc.l);
4:aa.h = op_readpc();
5:op_io();
6:rd.l = op_readpbr(aa.w + regs.x.w);
7:last_cycle();
rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
if(regs.e)regs.s.h = 0x01;
}
rti(0x40) {
1:op_io();
2:op_io();
3:regs.p = op_readstack();
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
@ -135,7 +136,7 @@ rti(0x40) {
}
6:last_cycle();
rd.b = op_readstack();
regs.pc.d = uclip<24>(rd.d);
regs.pc.d = rd.d & 0xffffff;
}
rts(0x60) {
@ -152,10 +153,11 @@ rts(0x60) {
rtl(0x6b) {
1:op_io();
2:op_io();
3:rd.l = op_readstack();
4:rd.h = op_readstack();
3:rd.l = op_readstackn();
4:rd.h = op_readstackn();
5:last_cycle();
rd.b = op_readstack();
regs.pc.d = uclip<24>(rd.d);
rd.b = op_readstackn();
regs.pc.d = rd.d & 0xffffff;
regs.pc.w++;
if(regs.e)regs.s.h = 0x01;
}

View File

@ -151,7 +151,7 @@ case 0x5c: {
rd.h = op_readpc();
last_cycle();
rd.b = op_readpc();
regs.pc.d = uclip<24>(rd.d);
regs.pc.d = rd.d & 0xffffff;
} break;
//jmp_iaddr
@ -183,7 +183,7 @@ case 0xdc: {
rd.h = op_readaddr(aa.w + 1);
last_cycle();
rd.b = op_readaddr(aa.w + 2);
regs.pc.d = uclip<24>(rd.d);
regs.pc.d = rd.d & 0xffffff;
} break;
//jsr_addr
@ -202,27 +202,29 @@ case 0x20: {
case 0x22: {
aa.l = op_readpc();
aa.h = op_readpc();
op_writestack(regs.pc.b);
op_writestackn(regs.pc.b);
op_io();
aa.b = op_readpc();
regs.pc.w--;
op_writestack(regs.pc.h);
op_writestackn(regs.pc.h);
last_cycle();
op_writestack(regs.pc.l);
regs.pc.d = uclip<24>(aa.d);
op_writestackn(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
if(regs.e)regs.s.h = 0x01;
} break;
//jsr_iaddrx
case 0xfc: {
aa.l = op_readpc();
op_writestack(regs.pc.h);
op_writestack(regs.pc.l);
op_writestackn(regs.pc.h);
op_writestackn(regs.pc.l);
aa.h = op_readpc();
op_io();
rd.l = op_readpbr(aa.w + regs.x.w);
last_cycle();
rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
if(regs.e)regs.s.h = 0x01;
} break;
//rti
@ -230,9 +232,8 @@ case 0x40: {
op_io();
op_io();
regs.p = op_readstack();
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
@ -245,7 +246,7 @@ case 0x40: {
}
last_cycle();
rd.b = op_readstack();
regs.pc.d = uclip<24>(rd.d);
regs.pc.d = rd.d & 0xffffff;
} break;
//rts
@ -264,11 +265,12 @@ case 0x60: {
case 0x6b: {
op_io();
op_io();
rd.l = op_readstack();
rd.h = op_readstack();
rd.l = op_readstackn();
rd.h = op_readstackn();
last_cycle();
rd.b = op_readstack();
regs.pc.d = uclip<24>(rd.d);
rd.b = op_readstackn();
regs.pc.d = rd.d & 0xffffff;
regs.pc.w++;
if(regs.e)regs.s.h = 0x01;
} break;

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
inc(0x1a, regs.acc_8b, a),
inx(0xe8, regs.idx_8b, x),
iny(0xc8, regs.idx_8b, y) {
inc(0x1a, regs.p.m, a),
inx(0xe8, regs.p.x, x),
iny(0xc8, regs.p.x, y) {
1:last_cycle();
op_io();
if($1) {
@ -14,9 +14,9 @@ iny(0xc8, regs.idx_8b, y) {
}
}
dec(0x3a, regs.acc_8b, a),
dex(0xca, regs.idx_8b, x),
dey(0x88, regs.idx_8b, y) {
dec(0x3a, regs.p.m, a),
dex(0xca, regs.p.x, x),
dey(0x88, regs.p.x, y) {
1:last_cycle();
op_io();
if($1) {
@ -33,7 +33,7 @@ dey(0x88, regs.idx_8b, y) {
asl(0x0a) {
1:last_cycle();
op_io();
if(regs.acc_8b) {
if(regs.p.m) {
regs.p.c = bool(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.p.n = bool(regs.a.l & 0x80);
@ -49,7 +49,7 @@ asl(0x0a) {
lsr(0x4a) {
1:last_cycle();
op_io();
if(regs.acc_8b) {
if(regs.p.m) {
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
regs.p.n = bool(regs.a.l & 0x80);
@ -66,7 +66,7 @@ rol(0x2a) {
1:last_cycle();
op_io();
uint16 c = regs.p.c;
if(regs.acc_8b) {
if(regs.p.m) {
regs.p.c = bool(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.a.l |= c;
@ -85,7 +85,7 @@ ror(0x6a) {
1:last_cycle();
op_io();
uint16 c;
if(regs.acc_8b) {
if(regs.p.m) {
c = (regs.p.c)?0x80:0;
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
@ -113,9 +113,9 @@ tsb_addr(0x0c, tsb) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:rd.l = op_readdbr(aa.w);
4:if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
4:if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
5:op_io();
if(regs.acc_8b) { op_$1_b(); }
if(regs.p.m) { op_$1_b(); }
else { op_$1_w();
6:op_writedbr(aa.w + 1, rd.h); }
7:last_cycle();
@ -132,9 +132,9 @@ ror_addrx(0x7e, ror) {
2:aa.h = op_readpc();
3:op_io();
4:rd.l = op_readdbr(aa.w + regs.x.w);
5:if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
5:if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
6:op_io();
if(regs.acc_8b) { op_$1_b(); }
if(regs.p.m) { op_$1_b(); }
else { op_$1_w();
7:op_writedbr(aa.w + regs.x.w + 1, rd.h); }
8:last_cycle();
@ -152,9 +152,9 @@ tsb_dp(0x04, tsb) {
1:dp = op_readpc();
2:op_io_cond2();
3:rd.l = op_readdp(dp);
4:if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
4:if(!regs.p.m)rd.h = op_readdp(dp + 1);
5:op_io();
if(regs.acc_8b) { op_$1_b(); }
if(regs.p.m) { op_$1_b(); }
else { op_$1_w();
6:op_writedp(dp + 1, rd.h); }
7:last_cycle();
@ -171,9 +171,9 @@ ror_dpx(0x76, ror) {
2:op_io_cond2();
3:op_io();
4:rd.l = op_readdp(dp + regs.x.w);
5:if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
5:if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
6:op_io();
if(regs.acc_8b) { op_$1_b(); }
if(regs.p.m) { op_$1_b(); }
else { op_$1_w();
7:op_writedp(dp + regs.x.w + 1, rd.h); }
8:last_cycle();

View File

@ -2,7 +2,7 @@
case 0x1a: {
last_cycle();
op_io();
if(regs.acc_8b) {
if(regs.p.m) {
regs.a.l++;
regs.p.n = bool(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
@ -17,7 +17,7 @@ case 0x1a: {
case 0xe8: {
last_cycle();
op_io();
if(regs.idx_8b) {
if(regs.p.x) {
regs.x.l++;
regs.p.n = bool(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
@ -32,7 +32,7 @@ case 0xe8: {
case 0xc8: {
last_cycle();
op_io();
if(regs.idx_8b) {
if(regs.p.x) {
regs.y.l++;
regs.p.n = bool(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
@ -47,7 +47,7 @@ case 0xc8: {
case 0x3a: {
last_cycle();
op_io();
if(regs.acc_8b) {
if(regs.p.m) {
regs.a.l--;
regs.p.n = bool(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
@ -62,7 +62,7 @@ case 0x3a: {
case 0xca: {
last_cycle();
op_io();
if(regs.idx_8b) {
if(regs.p.x) {
regs.x.l--;
regs.p.n = bool(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
@ -77,7 +77,7 @@ case 0xca: {
case 0x88: {
last_cycle();
op_io();
if(regs.idx_8b) {
if(regs.p.x) {
regs.y.l--;
regs.p.n = bool(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
@ -92,7 +92,7 @@ case 0x88: {
case 0x0a: {
last_cycle();
op_io();
if(regs.acc_8b) {
if(regs.p.m) {
regs.p.c = bool(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.p.n = bool(regs.a.l & 0x80);
@ -109,7 +109,7 @@ case 0x0a: {
case 0x4a: {
last_cycle();
op_io();
if(regs.acc_8b) {
if(regs.p.m) {
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
regs.p.n = bool(regs.a.l & 0x80);
@ -127,7 +127,7 @@ case 0x2a: {
last_cycle();
op_io();
uint16 c = regs.p.c;
if(regs.acc_8b) {
if(regs.p.m) {
regs.p.c = bool(regs.a.l & 0x80);
regs.a.l <<= 1;
regs.a.l |= c;
@ -147,7 +147,7 @@ case 0x6a: {
last_cycle();
op_io();
uint16 c;
if(regs.acc_8b) {
if(regs.p.m) {
c = (regs.p.c)?0x80:0;
regs.p.c = regs.a.l & 1;
regs.a.l >>= 1;
@ -169,9 +169,9 @@ case 0xee: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.acc_8b) { op_inc_b(); }
if(regs.p.m) { op_inc_b(); }
else { op_inc_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
@ -183,9 +183,9 @@ case 0xce: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.acc_8b) { op_dec_b(); }
if(regs.p.m) { op_dec_b(); }
else { op_dec_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
@ -197,9 +197,9 @@ case 0x0e: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.acc_8b) { op_asl_b(); }
if(regs.p.m) { op_asl_b(); }
else { op_asl_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
@ -211,9 +211,9 @@ case 0x4e: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.acc_8b) { op_lsr_b(); }
if(regs.p.m) { op_lsr_b(); }
else { op_lsr_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
@ -225,9 +225,9 @@ case 0x2e: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.acc_8b) { op_rol_b(); }
if(regs.p.m) { op_rol_b(); }
else { op_rol_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
@ -239,9 +239,9 @@ case 0x6e: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.acc_8b) { op_ror_b(); }
if(regs.p.m) { op_ror_b(); }
else { op_ror_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
@ -253,9 +253,9 @@ case 0x1c: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.acc_8b) { op_trb_b(); }
if(regs.p.m) { op_trb_b(); }
else { op_trb_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
@ -267,9 +267,9 @@ case 0x0c: {
aa.l = op_readpc();
aa.h = op_readpc();
rd.l = op_readdbr(aa.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
op_io();
if(regs.acc_8b) { op_tsb_b(); }
if(regs.p.m) { op_tsb_b(); }
else { op_tsb_w();
op_writedbr(aa.w + 1, rd.h); }
last_cycle();
@ -282,9 +282,9 @@ case 0xfe: {
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
if(regs.acc_8b) { op_inc_b(); }
if(regs.p.m) { op_inc_b(); }
else { op_inc_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
last_cycle();
@ -297,9 +297,9 @@ case 0xde: {
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
if(regs.acc_8b) { op_dec_b(); }
if(regs.p.m) { op_dec_b(); }
else { op_dec_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
last_cycle();
@ -312,9 +312,9 @@ case 0x1e: {
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
if(regs.acc_8b) { op_asl_b(); }
if(regs.p.m) { op_asl_b(); }
else { op_asl_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
last_cycle();
@ -327,9 +327,9 @@ case 0x5e: {
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
if(regs.acc_8b) { op_lsr_b(); }
if(regs.p.m) { op_lsr_b(); }
else { op_lsr_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
last_cycle();
@ -342,9 +342,9 @@ case 0x3e: {
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
if(regs.acc_8b) { op_rol_b(); }
if(regs.p.m) { op_rol_b(); }
else { op_rol_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
last_cycle();
@ -357,9 +357,9 @@ case 0x7e: {
aa.h = op_readpc();
op_io();
rd.l = op_readdbr(aa.w + regs.x.w);
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_io();
if(regs.acc_8b) { op_ror_b(); }
if(regs.p.m) { op_ror_b(); }
else { op_ror_w();
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
last_cycle();
@ -371,9 +371,9 @@ case 0xe6: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
if(!regs.p.m)rd.h = op_readdp(dp + 1);
op_io();
if(regs.acc_8b) { op_inc_b(); }
if(regs.p.m) { op_inc_b(); }
else { op_inc_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
@ -385,9 +385,9 @@ case 0xc6: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
if(!regs.p.m)rd.h = op_readdp(dp + 1);
op_io();
if(regs.acc_8b) { op_dec_b(); }
if(regs.p.m) { op_dec_b(); }
else { op_dec_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
@ -399,9 +399,9 @@ case 0x06: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
if(!regs.p.m)rd.h = op_readdp(dp + 1);
op_io();
if(regs.acc_8b) { op_asl_b(); }
if(regs.p.m) { op_asl_b(); }
else { op_asl_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
@ -413,9 +413,9 @@ case 0x46: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
if(!regs.p.m)rd.h = op_readdp(dp + 1);
op_io();
if(regs.acc_8b) { op_lsr_b(); }
if(regs.p.m) { op_lsr_b(); }
else { op_lsr_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
@ -427,9 +427,9 @@ case 0x26: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
if(!regs.p.m)rd.h = op_readdp(dp + 1);
op_io();
if(regs.acc_8b) { op_rol_b(); }
if(regs.p.m) { op_rol_b(); }
else { op_rol_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
@ -441,9 +441,9 @@ case 0x66: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
if(!regs.p.m)rd.h = op_readdp(dp + 1);
op_io();
if(regs.acc_8b) { op_ror_b(); }
if(regs.p.m) { op_ror_b(); }
else { op_ror_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
@ -455,9 +455,9 @@ case 0x14: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
if(!regs.p.m)rd.h = op_readdp(dp + 1);
op_io();
if(regs.acc_8b) { op_trb_b(); }
if(regs.p.m) { op_trb_b(); }
else { op_trb_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
@ -469,9 +469,9 @@ case 0x04: {
dp = op_readpc();
op_io_cond2();
rd.l = op_readdp(dp);
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
if(!regs.p.m)rd.h = op_readdp(dp + 1);
op_io();
if(regs.acc_8b) { op_tsb_b(); }
if(regs.p.m) { op_tsb_b(); }
else { op_tsb_w();
op_writedp(dp + 1, rd.h); }
last_cycle();
@ -484,9 +484,9 @@ case 0xf6: {
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
if(regs.acc_8b) { op_inc_b(); }
if(regs.p.m) { op_inc_b(); }
else { op_inc_w();
op_writedp(dp + regs.x.w + 1, rd.h); }
last_cycle();
@ -499,9 +499,9 @@ case 0xd6: {
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
if(regs.acc_8b) { op_dec_b(); }
if(regs.p.m) { op_dec_b(); }
else { op_dec_w();
op_writedp(dp + regs.x.w + 1, rd.h); }
last_cycle();
@ -514,9 +514,9 @@ case 0x16: {
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
if(regs.acc_8b) { op_asl_b(); }
if(regs.p.m) { op_asl_b(); }
else { op_asl_w();
op_writedp(dp + regs.x.w + 1, rd.h); }
last_cycle();
@ -529,9 +529,9 @@ case 0x56: {
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
if(regs.acc_8b) { op_lsr_b(); }
if(regs.p.m) { op_lsr_b(); }
else { op_lsr_w();
op_writedp(dp + regs.x.w + 1, rd.h); }
last_cycle();
@ -544,9 +544,9 @@ case 0x36: {
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
if(regs.acc_8b) { op_rol_b(); }
if(regs.p.m) { op_rol_b(); }
else { op_rol_w();
op_writedp(dp + regs.x.w + 1, rd.h); }
last_cycle();
@ -559,9 +559,9 @@ case 0x76: {
op_io_cond2();
op_io();
rd.l = op_readdp(dp + regs.x.w);
if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
op_io();
if(regs.acc_8b) { op_ror_b(); }
if(regs.p.m) { op_ror_b(); }
else { op_ror_w();
op_writedp(dp + regs.x.w + 1, rd.h); }
last_cycle();

View File

@ -1,7 +1,7 @@
sta_addr(0x8d, regs.acc_8b, regs.a.w),
stx_addr(0x8e, regs.idx_8b, regs.x.w),
sty_addr(0x8c, regs.idx_8b, regs.y.w),
stz_addr(0x9c, regs.acc_8b, 0x0000) {
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_readpc();
2:aa.h = op_readpc();
3:if($1)last_cycle();
@ -11,8 +11,8 @@ stz_addr(0x9c, regs.acc_8b, 0x0000) {
op_writedbr(aa.w + 1, $2 >> 8);
}
sta_addrx(0x9d, regs.acc_8b, regs.a.w),
stz_addrx(0x9e, regs.acc_8b, 0x0000) {
sta_addrx(0x9d, regs.p.m, regs.a.w),
stz_addrx(0x9e, regs.p.m, 0x0000) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:op_io();
@ -27,9 +27,9 @@ sta_addry(0x99) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:op_io();
4:if(regs.acc_8b)last_cycle();
4:if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.acc_8b)end;
if(regs.p.m)end;
5:last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}
@ -38,9 +38,9 @@ sta_long(0x8f) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:aa.b = op_readpc();
4:if(regs.acc_8b)last_cycle();
4:if(regs.p.m)last_cycle();
op_writelong(aa.d, regs.a.l);
if(regs.acc_8b)end;
if(regs.p.m)end;
5:last_cycle();
op_writelong(aa.d + 1, regs.a.h);
}
@ -49,17 +49,17 @@ sta_longx(0x9f) {
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:aa.b = op_readpc();
4:if(regs.acc_8b)last_cycle();
4:if(regs.p.m)last_cycle();
op_writelong(aa.d + regs.x.w, regs.a.l);
if(regs.acc_8b)end;
if(regs.p.m)end;
5:last_cycle();
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
}
sta_dp(0x85, regs.acc_8b, regs.a.w),
stx_dp(0x86, regs.idx_8b, regs.x.w),
sty_dp(0x84, regs.idx_8b, regs.y.w),
stz_dp(0x64, regs.acc_8b, 0x0000) {
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_readpc();
2:op_io_cond2();
3:if($1)last_cycle();
@ -69,9 +69,9 @@ stz_dp(0x64, regs.acc_8b, 0x0000) {
op_writedp(dp + 1, $2 >> 8);
}
sta_dpx(0x95, regs.acc_8b, regs.a.w),
sty_dpx(0x94, regs.idx_8b, regs.y.w),
stz_dpx(0x74, regs.acc_8b, 0x0000) {
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_readpc();
2:op_io_cond2();
3:op_io();
@ -86,9 +86,9 @@ stx_dpy(0x96) {
1:dp = op_readpc();
2:op_io_cond2();
3:op_io();
4:if(regs.idx_8b)last_cycle();
4:if(regs.p.x)last_cycle();
op_writedp(dp + regs.y.w, regs.x.l);
if(regs.idx_8b)end;
if(regs.p.x)end;
5:last_cycle();
op_writedp(dp + regs.y.w + 1, regs.x.h);
}
@ -98,9 +98,9 @@ sta_idp(0x92) {
2:op_io_cond2();
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:if(regs.acc_8b)last_cycle();
5:if(regs.p.m)last_cycle();
op_writedbr(aa.w, regs.a.l);
if(regs.acc_8b)end;
if(regs.p.m)end;
6:last_cycle();
op_writedbr(aa.w + 1, regs.a.h);
}
@ -111,9 +111,9 @@ sta_ildp(0x87) {
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:aa.b = op_readdp(dp + 2);
6:if(regs.acc_8b)last_cycle();
6:if(regs.p.m)last_cycle();
op_writelong(aa.d, regs.a.l);
if(regs.acc_8b)end;
if(regs.p.m)end;
7:last_cycle();
op_writelong(aa.d + 1, regs.a.h);
}
@ -124,9 +124,9 @@ sta_idpx(0x81) {
3:op_io();
4:aa.l = op_readdp(dp + regs.x.w);
5:aa.h = op_readdp(dp + regs.x.w + 1);
6:if(regs.acc_8b)last_cycle();
6:if(regs.p.m)last_cycle();
op_writedbr(aa.w, regs.a.l);
if(regs.acc_8b)end;
if(regs.p.m)end;
7:last_cycle();
op_writedbr(aa.w + 1, regs.a.h);
}
@ -137,9 +137,9 @@ sta_idpy(0x91) {
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:op_io();
6:if(regs.acc_8b)last_cycle();
6:if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.acc_8b)end;
if(regs.p.m)end;
7:last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}
@ -150,9 +150,9 @@ sta_ildpy(0x97) {
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:aa.b = op_readdp(dp + 2);
6:if(regs.acc_8b)last_cycle();
6:if(regs.p.m)last_cycle();
op_writelong(aa.d + regs.y.w, regs.a.l);
if(regs.acc_8b)end;
if(regs.p.m)end;
7:last_cycle();
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
}
@ -160,9 +160,9 @@ sta_ildpy(0x97) {
sta_sr(0x83) {
1:sp = op_readpc();
2:op_io();
3:if(regs.acc_8b)last_cycle();
3:if(regs.p.m)last_cycle();
op_writesp(sp, regs.a.l);
if(regs.acc_8b)end;
if(regs.p.m)end;
4:last_cycle();
op_writesp(sp + 1, regs.a.h);
}
@ -173,9 +173,9 @@ sta_isry(0x93) {
3:aa.l = op_readsp(sp);
4:aa.h = op_readsp(sp + 1);
5:op_io();
6:if(regs.acc_8b)last_cycle();
6:if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.acc_8b)end;
if(regs.p.m)end;
7:last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}

View File

@ -2,9 +2,9 @@
case 0x8d: {
aa.l = op_readpc();
aa.h = op_readpc();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedbr(aa.w, regs.a.w);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedbr(aa.w + 1, regs.a.w >> 8);
} break;
@ -13,9 +13,9 @@ case 0x8d: {
case 0x8e: {
aa.l = op_readpc();
aa.h = op_readpc();
if(regs.idx_8b)last_cycle();
if(regs.p.x)last_cycle();
op_writedbr(aa.w, regs.x.w);
if(regs.idx_8b)break;
if(regs.p.x)break;
last_cycle();
op_writedbr(aa.w + 1, regs.x.w >> 8);
} break;
@ -24,9 +24,9 @@ case 0x8e: {
case 0x8c: {
aa.l = op_readpc();
aa.h = op_readpc();
if(regs.idx_8b)last_cycle();
if(regs.p.x)last_cycle();
op_writedbr(aa.w, regs.y.w);
if(regs.idx_8b)break;
if(regs.p.x)break;
last_cycle();
op_writedbr(aa.w + 1, regs.y.w >> 8);
} break;
@ -35,9 +35,9 @@ case 0x8c: {
case 0x9c: {
aa.l = op_readpc();
aa.h = op_readpc();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedbr(aa.w, 0x0000);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedbr(aa.w + 1, 0x0000 >> 8);
} break;
@ -47,9 +47,9 @@ case 0x9d: {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.x.w, regs.a.w);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedbr(aa.w + regs.x.w + 1, regs.a.w >> 8);
} break;
@ -59,9 +59,9 @@ case 0x9e: {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.x.w, 0x0000);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedbr(aa.w + regs.x.w + 1, 0x0000 >> 8);
} break;
@ -71,9 +71,9 @@ case 0x99: {
aa.l = op_readpc();
aa.h = op_readpc();
op_io();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
} break;
@ -83,9 +83,9 @@ case 0x8f: {
aa.l = op_readpc();
aa.h = op_readpc();
aa.b = op_readpc();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writelong(aa.d, regs.a.l);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writelong(aa.d + 1, regs.a.h);
} break;
@ -95,9 +95,9 @@ case 0x9f: {
aa.l = op_readpc();
aa.h = op_readpc();
aa.b = op_readpc();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writelong(aa.d + regs.x.w, regs.a.l);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
} break;
@ -106,9 +106,9 @@ case 0x9f: {
case 0x85: {
dp = op_readpc();
op_io_cond2();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedp(dp, regs.a.w);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedp(dp + 1, regs.a.w >> 8);
} break;
@ -117,9 +117,9 @@ case 0x85: {
case 0x86: {
dp = op_readpc();
op_io_cond2();
if(regs.idx_8b)last_cycle();
if(regs.p.x)last_cycle();
op_writedp(dp, regs.x.w);
if(regs.idx_8b)break;
if(regs.p.x)break;
last_cycle();
op_writedp(dp + 1, regs.x.w >> 8);
} break;
@ -128,9 +128,9 @@ case 0x86: {
case 0x84: {
dp = op_readpc();
op_io_cond2();
if(regs.idx_8b)last_cycle();
if(regs.p.x)last_cycle();
op_writedp(dp, regs.y.w);
if(regs.idx_8b)break;
if(regs.p.x)break;
last_cycle();
op_writedp(dp + 1, regs.y.w >> 8);
} break;
@ -139,9 +139,9 @@ case 0x84: {
case 0x64: {
dp = op_readpc();
op_io_cond2();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedp(dp, 0x0000);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedp(dp + 1, 0x0000 >> 8);
} break;
@ -151,9 +151,9 @@ case 0x95: {
dp = op_readpc();
op_io_cond2();
op_io();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedp(dp + regs.x.w, regs.a.w);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedp(dp + regs.x.w + 1, regs.a.w >> 8);
} break;
@ -163,9 +163,9 @@ case 0x94: {
dp = op_readpc();
op_io_cond2();
op_io();
if(regs.idx_8b)last_cycle();
if(regs.p.x)last_cycle();
op_writedp(dp + regs.x.w, regs.y.w);
if(regs.idx_8b)break;
if(regs.p.x)break;
last_cycle();
op_writedp(dp + regs.x.w + 1, regs.y.w >> 8);
} break;
@ -175,9 +175,9 @@ case 0x74: {
dp = op_readpc();
op_io_cond2();
op_io();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedp(dp + regs.x.w, 0x0000);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedp(dp + regs.x.w + 1, 0x0000 >> 8);
} break;
@ -187,9 +187,9 @@ case 0x96: {
dp = op_readpc();
op_io_cond2();
op_io();
if(regs.idx_8b)last_cycle();
if(regs.p.x)last_cycle();
op_writedp(dp + regs.y.w, regs.x.l);
if(regs.idx_8b)break;
if(regs.p.x)break;
last_cycle();
op_writedp(dp + regs.y.w + 1, regs.x.h);
} break;
@ -200,9 +200,9 @@ case 0x92: {
op_io_cond2();
aa.l = op_readdp(dp);
aa.h = op_readdp(dp + 1);
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedbr(aa.w, regs.a.l);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedbr(aa.w + 1, regs.a.h);
} break;
@ -214,9 +214,9 @@ case 0x87: {
aa.l = op_readdp(dp);
aa.h = op_readdp(dp + 1);
aa.b = op_readdp(dp + 2);
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writelong(aa.d, regs.a.l);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writelong(aa.d + 1, regs.a.h);
} break;
@ -228,9 +228,9 @@ case 0x81: {
op_io();
aa.l = op_readdp(dp + regs.x.w);
aa.h = op_readdp(dp + regs.x.w + 1);
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedbr(aa.w, regs.a.l);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedbr(aa.w + 1, regs.a.h);
} break;
@ -242,9 +242,9 @@ case 0x91: {
aa.l = op_readdp(dp);
aa.h = op_readdp(dp + 1);
op_io();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
} break;
@ -256,9 +256,9 @@ case 0x97: {
aa.l = op_readdp(dp);
aa.h = op_readdp(dp + 1);
aa.b = op_readdp(dp + 2);
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writelong(aa.d + regs.y.w, regs.a.l);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
} break;
@ -267,9 +267,9 @@ case 0x97: {
case 0x83: {
sp = op_readpc();
op_io();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writesp(sp, regs.a.l);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writesp(sp + 1, regs.a.h);
} break;
@ -281,9 +281,9 @@ case 0x93: {
aa.l = op_readsp(sp);
aa.h = op_readsp(sp + 1);
op_io();
if(regs.acc_8b)last_cycle();
if(regs.p.m)last_cycle();
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.acc_8b)break;
if(regs.p.m)break;
last_cycle();
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
} break;

View File

@ -31,7 +31,6 @@ uint8 r;
status.dma_clocks += 8;
add_clocks(8);
co_return();
cycle_edge();
}
@ -130,7 +129,7 @@ void sCPU::dma_run() {
channel[i].dma_enabled = false;
}
counter_set(counter.irq_delay, 24);
counter.set(counter.irq_delay, 24);
}
/*****
@ -199,7 +198,6 @@ static uint8 hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
!channel[i].hdma_indirect ? hdma_addr(i) : hdma_iaddr(i));
} else {
add_clocks(8);
co_return();
cycle_edge();
}
}
@ -212,7 +210,7 @@ static uint8 hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
}
}
counter_set(counter.irq_delay, 24);
counter.set(counter.irq_delay, 24);
}
void sCPU::hdma_init_reset() {
@ -231,7 +229,7 @@ void sCPU::hdma_init() {
hdma_update(i);
}
counter_set(counter.irq_delay, 24);
counter.set(counter.irq_delay, 24);
}
/*****

View File

@ -10,7 +10,6 @@ void sCPU::op_io() {
status.clock_count = 6;
precycle_edge();
add_clocks(6);
//co_return();
cycle_edge();
}
@ -18,9 +17,6 @@ uint8 sCPU::op_read(uint32 addr) {
status.clock_count = r_mem->speed(addr);
precycle_edge();
add_clocks(status.clock_count - 4);
#ifdef FAVOR_ACCURACY
co_return();
#endif
regs.mdr = r_mem->read(addr);
add_clocks(4);
cycle_edge();
@ -31,10 +27,95 @@ void sCPU::op_write(uint32 addr, uint8 data) {
status.clock_count = r_mem->speed(addr);
precycle_edge();
add_clocks(status.clock_count);
#ifdef FAVOR_ACCURACY
co_return();
#endif
regs.mdr = data;
r_mem->write(addr, regs.mdr);
cycle_edge();
}
//
alwaysinline uint8 sCPU::op_readpc() {
return op_read((regs.pc.b << 16) + regs.pc.w++);
}
alwaysinline uint8 sCPU::op_readstack() {
if(regs.e) {
regs.s.l++;
} else {
regs.s.w++;
}
return op_read(regs.s.w);
}
alwaysinline uint8 sCPU::op_readstackn() {
return op_read(++regs.s.w);
}
alwaysinline uint8 sCPU::op_readaddr(uint32 addr) {
return op_read(addr & 0xffff);
}
alwaysinline uint8 sCPU::op_readlong(uint32 addr) {
return op_read(addr & 0xffffff);
}
alwaysinline uint8 sCPU::op_readdbr(uint32 addr) {
return op_read(((regs.db << 16) + addr) & 0xffffff);
}
alwaysinline uint8 sCPU::op_readpbr(uint32 addr) {
return op_read((regs.pc.b << 16) + (addr & 0xffff));
}
alwaysinline uint8 sCPU::op_readdp(uint32 addr) {
if(regs.e && regs.d.l == 0x00) {
return op_read((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff));
} else {
return op_read((regs.d + (addr & 0xffff)) & 0xffff);
}
}
alwaysinline uint8 sCPU::op_readsp(uint32 addr) {
return op_read((regs.s + (addr & 0xffff)) & 0xffff);
}
alwaysinline void sCPU::op_writestack(uint8 data) {
op_write(regs.s.w, data);
if(regs.e) {
regs.s.l--;
} else {
regs.s.w--;
}
}
alwaysinline void sCPU::op_writestackn(uint8 data) {
op_write(regs.s.w--, data);
}
alwaysinline void sCPU::op_writeaddr(uint32 addr, uint8 data) {
op_write(addr & 0xffff, data);
}
alwaysinline void sCPU::op_writelong(uint32 addr, uint8 data) {
op_write(addr & 0xffffff, data);
}
alwaysinline void sCPU::op_writedbr(uint32 addr, uint8 data) {
op_write(((regs.db << 16) + addr) & 0xffffff, data);
}
alwaysinline void sCPU::op_writepbr(uint32 addr, uint8 data) {
op_write((regs.pc.b << 16) + (addr & 0xffff), data);
}
alwaysinline void sCPU::op_writedp(uint32 addr, uint8 data) {
if(regs.e && regs.d.l == 0x00) {
op_write((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff), data);
} else {
op_write((regs.d + (addr & 0xffff)) & 0xffff, data);
}
}
alwaysinline void sCPU::op_writesp(uint32 addr, uint8 data) {
op_write((regs.s + (addr & 0xffff)) & 0xffff, data);
}

View File

@ -15,19 +15,21 @@ uint8 apu_port[4];
/*****
* helper memory addressing functions used by CPU core
*****/
uint8 op_readpc () { return op_read((regs.pc.b << 16) + regs.pc.w++); }
uint8 op_readstack() { (regs.e) ? regs.s.l++ : regs.s.w++; return op_read(regs.s.w); }
uint8 op_readaddr (uint32 addr) { return op_read(addr & 0xffff); }
uint8 op_readlong (uint32 addr) { return op_read(addr & 0xffffff); }
uint8 op_readdbr (uint32 addr) { return op_read(((regs.db << 16) + addr) & 0xffffff); }
uint8 op_readpbr (uint32 addr) { return op_read((regs.pc.b << 16) + (addr & 0xffff)); }
uint8 op_readdp (uint32 addr) { return op_read((regs.d + (addr & 0xffff)) & 0xffff); }
uint8 op_readsp (uint32 addr) { return op_read((regs.s + (addr & 0xffff)) & 0xffff); }
uint8 op_readpc ();
uint8 op_readstack ();
uint8 op_readstackn();
uint8 op_readaddr (uint32 addr);
uint8 op_readlong (uint32 addr);
uint8 op_readdbr (uint32 addr);
uint8 op_readpbr (uint32 addr);
uint8 op_readdp (uint32 addr);
uint8 op_readsp (uint32 addr);
void op_writestack(uint8 data) { op_write(regs.s.w, data); (regs.e) ? regs.s.l-- : regs.s.w--; }
void op_writeaddr (uint32 addr, uint8 data) { op_write(addr & 0xffff, data); }
void op_writelong (uint32 addr, uint8 data) { op_write(addr & 0xffffff, data); }
void op_writedbr (uint32 addr, uint8 data) { op_write(((regs.db << 16) + addr) & 0xffffff, data); }
void op_writepbr (uint32 addr, uint8 data) { op_write((regs.pc.b << 16) + (addr & 0xffff), data); }
void op_writedp (uint32 addr, uint8 data) { op_write((regs.d + (addr & 0xffff)) & 0xffff, data); }
void op_writesp (uint32 addr, uint8 data) { op_write((regs.s + (addr & 0xffff)) & 0xffff, data); }
void op_writestack (uint8 data);
void op_writestackn(uint8 data);
void op_writeaddr (uint32 addr, uint8 data);
void op_writelong (uint32 addr, uint8 data);
void op_writedbr (uint32 addr, uint8 data);
void op_writepbr (uint32 addr, uint8 data);
void op_writedp (uint32 addr, uint8 data);
void op_writesp (uint32 addr, uint8 data);

View File

@ -99,7 +99,7 @@ void sCPU::mmio_w4200(uint8 data) {
}
update_interrupts();
counter_set(counter.irq_delay, 2);
counter.set(counter.irq_delay, 2);
}
//WRIO
@ -119,7 +119,7 @@ void sCPU::mmio_w4202(uint8 data) {
void sCPU::mmio_w4203(uint8 data) {
status.mul_b = data;
status.r4216 = status.mul_a * status.mul_b;
//counter_set(counter.hw_math, 48);
//counter.set(counter.hw_math, 48);
}
//WRDIVL
@ -137,7 +137,7 @@ void sCPU::mmio_w4206(uint8 data) {
status.div_b = data;
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;
//counter_set(counter.hw_math, 96);
//counter.set(counter.hw_math, 96);
}
//HTIMEL
@ -145,10 +145,7 @@ void sCPU::mmio_w4207(uint8 data) {
status.hirq_pos = (status.hirq_pos & ~0xff) | (data);
status.hirq_pos &= 0x01ff;
update_interrupts();
uint vpos = status.vcounter, hpos = status.hclock;
timeshift_backward(10, vpos, hpos);
if(hpos < status.hirq_trigger_pos) { status.irq_lock = false; }
irqpos_update(0x4207);
}
//HTIMEH
@ -156,10 +153,7 @@ void sCPU::mmio_w4208(uint8 data) {
status.hirq_pos = (status.hirq_pos & 0xff) | (data << 8);
status.hirq_pos &= 0x01ff;
update_interrupts();
uint vpos = status.vcounter, hpos = status.hclock;
timeshift_backward(10, vpos, hpos);
if(hpos < status.hirq_trigger_pos) { status.irq_lock = false; }
irqpos_update(0x4208);
}
//VTIMEL
@ -167,10 +161,7 @@ void sCPU::mmio_w4209(uint8 data) {
status.virq_pos = (status.virq_pos & ~0xff) | (data);
status.virq_pos &= 0x01ff;
update_interrupts();
uint vpos = status.vcounter, hpos = status.hclock;
timeshift_backward(10, vpos, hpos);
if(hpos < status.hirq_trigger_pos) { status.irq_lock = false; }
irqpos_update(0x4209);
}
//VTIMEH
@ -178,10 +169,7 @@ void sCPU::mmio_w420a(uint8 data) {
status.virq_pos = (status.virq_pos & 0xff) | (data << 8);
status.virq_pos &= 0x01ff;
update_interrupts();
uint vpos = status.vcounter, hpos = status.hclock;
timeshift_backward(10, vpos, hpos);
if(hpos < status.hirq_trigger_pos) { status.irq_lock = false; }
irqpos_update(0x420a);
}
//DMAEN
@ -215,7 +203,7 @@ uint8 sCPU::mmio_r4210() {
uint8 r = (regs.mdr & 0x70);
r |= (uint8)(!status.nmi_read) << 7;
if(!counter.nmi_fire) {
if(!nmi_edge()) {
status.nmi_read = 1;
}
@ -230,7 +218,7 @@ uint8 sCPU::mmio_r4211() {
uint8 r = (regs.mdr & 0x7f);
r |= (uint8)(!status.irq_read) << 7;
if(!counter.irq_fire) {
if(!irq_edge()) {
status.irq_read = 1;
status.irq_line = 1;
status.irq_transition = 0;
@ -479,9 +467,7 @@ void sCPU::mmio_reset() {
uint8 sCPU::mmio_read(uint16 addr) {
//APU
if((addr & 0xffc0) == 0x2140) { //$2140-$217f
#ifdef FAVOR_SPEED
co_return();
#endif
scheduler.sync_cpusmp();
return r_smp->port_read(addr & 3);
}
@ -536,9 +522,7 @@ uint8 sCPU::mmio_read(uint16 addr) {
void sCPU::mmio_write(uint16 addr, uint8 data) {
//APU
if((addr & 0xffc0) == 0x2140) { //$2140-$217f
#ifdef FAVOR_SPEED
co_return();
#endif
scheduler.sync_cpusmp();
port_write(addr & 3, data);
return;
}

View File

@ -6,16 +6,8 @@
#include "mmio/mmio.cpp"
#include "timing/timing.cpp"
void scpu_entry_point() {
r_cpu->main();
}
void sCPU::run() {
co_call(thread);
}
void sCPU::power() {
status.region = bool(snes->region());
status.region = (bool)snes->region();
regs.a = regs.x = regs.y = 0x0000;
regs.s = 0x01ff;
@ -28,16 +20,10 @@ void sCPU::power() {
}
void sCPU::reset() {
if(thread)co_delete(thread);
thread = co_create(scpu_entry_point, 65536);
regs.pc.d = 0x000000;
regs.pc.l = r_mem->read(0xfffc);
regs.pc.h = r_mem->read(0xfffd);
regs.acc_8b = true;
regs.idx_8b = true;
//note: some registers are not fully reset by SNES
regs.x.h = 0x00;
regs.y.h = 0x00;
@ -62,11 +48,5 @@ void sCPU::reset() {
apu_port[3] = 0x00;
}
sCPU::sCPU() {
//#include "core/optable.cpp"
thread = 0;
}
sCPU::~sCPU() {
if(thread)co_delete(thread);
}
sCPU::sCPU() {}
sCPU::~sCPU() {}

View File

@ -1,4 +1,7 @@
class sCPU : public CPU {
public:
void enter();
public:
#include "core/core.h"
#include "dma/dma.h"
@ -6,8 +9,6 @@ public:
#include "mmio/mmio.h"
#include "timing/timing.h"
thread_t thread;
struct {
bool wai;
bool irq;
@ -15,11 +16,22 @@ struct {
} event;
struct {
bool enabled;
uint irq_delay;
uint irq_fire;
uint nmi_fire;
uint irq_fire;
uint irq_delay;
uint hw_math;
alwaysinline void set(uint &ctr, uint clocks) {
if(clocks >= ctr) { ctr = clocks; }
}
alwaysinline void sub(uint &ctr, uint clocks) {
if(ctr >= clocks) {
ctr -= clocks;
} else {
ctr = 0;
}
}
} counter;
enum {
@ -35,7 +47,6 @@ struct {
bool in_opcode;
uint clock_count;
uint clocks_executed;
//timing
bool region;
@ -60,10 +71,12 @@ struct {
uint16 irq_delay;
uint16 nmi_trigger_pos;
uint16 nmi_read_pos, nmi_line_pos;
bool nmi_read, nmi_line, nmi_transition;
bool nmi_pending;
bool nmi_lock, nmi_pending;
uint16 virq_trigger_pos, hirq_trigger_pos;
uint16 irq_read_pos, irq_line_pos;
bool irq_read, irq_line, irq_transition;
bool irq_lock, irq_pending;
@ -114,7 +127,6 @@ struct {
uint8 joy4l, joy4h;
} status;
void run();
void power();
void reset();

View File

@ -1,61 +1,8 @@
void sCPU::update_interrupts() {
status.nmi_trigger_pos = (status.vcounter == status.vblstart) ? 2 : IRQ_TRIGGER_NEVER;
if(irq_pos_valid() == true) {
status.virq_trigger_pos = status.virq_pos;
status.hirq_trigger_pos = (status.hirq_enabled) ? ((status.hirq_pos + 1) * 4) : 0;
} else {
status.virq_trigger_pos = IRQ_TRIGGER_NEVER;
status.hirq_trigger_pos = IRQ_TRIGGER_NEVER;
}
}
alwaysinline void sCPU::nmi_tick() {
counter.nmi_fire -= 2;
if(counter.nmi_fire != 0) { return; }
if(status.nmi_enabled == true && status.nmi_line == 1) {
status.nmi_line = 0;
status.nmi_transition = 1;
}
}
alwaysinline void sCPU::irq_tick() {
counter.irq_fire -= 2;
if(counter.irq_fire != 0) { return; }
if(status.virq_enabled == true || status.hirq_enabled == true) {
status.irq_line = 0;
status.irq_transition = 1;
}
}
alwaysinline void sCPU::poll_interrupts() {
if(status.hclock == status.nmi_trigger_pos) {
status.nmi_read = 0;
counter.nmi_fire = 4;
}
if(status.hclock == 10) { status.irq_lock = false; }
if(status.hirq_trigger_pos == IRQ_TRIGGER_NEVER)return;
if(status.virq_enabled == false && status.hirq_enabled == false)return;
if(status.irq_lock == true)return;
uint vpos = status.vcounter;
uint hpos = status.hclock;
timeshift_backward(10, vpos, hpos);
bool trigger_irq = true;
if(status.virq_enabled == true && vpos != status.virq_trigger_pos)trigger_irq = false;
if(status.hirq_enabled == true && hpos != status.hirq_trigger_pos)trigger_irq = false;
if(trigger_irq == true) {
status.irq_lock = true;
status.irq_read = 0;
counter.irq_fire = 4;
}
}
#if defined(FAVOR_ACCURACY)
#include "irqtiming_accurate.cpp"
#elif defined(FAVOR_SPEED)
#include "irqtiming_fast.cpp"
#endif
bool sCPU::irq_pos_valid() {
uint vpos = status.virq_pos;
@ -86,7 +33,7 @@ alwaysinline bool sCPU::irq_test() {
if(status.irq_transition == 1)goto irq_trigger;
if(status.irq_read == 0) {
if(status.irq_line == 1 && counter.irq_fire) {
if(status.irq_line == 1 && irq_edge()) {
return false;
}
goto irq_trigger;

View File

@ -0,0 +1,76 @@
void sCPU::update_interrupts() {
status.nmi_trigger_pos = (status.vcounter == status.vblstart) ? 2 : IRQ_TRIGGER_NEVER;
if(irq_pos_valid() == true) {
status.virq_trigger_pos = status.virq_pos;
status.hirq_trigger_pos = 4 * ((status.hirq_enabled) ? (status.hirq_pos + 1) : 0);
} else {
status.virq_trigger_pos = IRQ_TRIGGER_NEVER;
status.hirq_trigger_pos = IRQ_TRIGGER_NEVER;
}
}
alwaysinline void sCPU::poll_interrupts(uint clocks) {
clocks >>= 1;
while(clocks--) {
status.hclock += 2;
if(status.hclock >= status.line_clocks) { scanline(); }
//NMI tick
if(counter.nmi_fire) {
counter.nmi_fire -= 2;
if(counter.nmi_fire == 0) {
if(status.nmi_enabled == true && status.nmi_line == 1) {
status.nmi_line = 0;
status.nmi_transition = 1;
}
}
}
//IRQ tick
if(counter.irq_fire) {
counter.irq_fire -= 2;
if(counter.irq_fire == 0) {
if(status.virq_enabled == true || status.hirq_enabled == true) {
status.irq_line = 0;
status.irq_transition = 1;
}
}
}
//NMI test
if(status.hclock == status.nmi_trigger_pos) {
status.nmi_read = 0;
counter.nmi_fire = 4;
}
//IRQ test
if(status.hclock == 10) { status.irq_lock = false; }
if(status.hirq_trigger_pos == IRQ_TRIGGER_NEVER) { continue; }
if(status.virq_enabled == false && status.hirq_enabled == false) { continue; }
if(status.irq_lock == true) { continue; }
uint vpos = status.vcounter, hpos = status.hclock;
timeshift_backward(10, vpos, hpos);
bool trigger_irq = true;
if(status.virq_enabled == true && vpos != status.virq_trigger_pos)trigger_irq = false;
if(status.hirq_enabled == true && hpos != status.hirq_trigger_pos)trigger_irq = false;
if(trigger_irq == true) {
status.irq_lock = true;
status.irq_read = 0;
counter.irq_fire = 4;
}
}
}
bool sCPU::nmi_edge() { return (counter.nmi_fire != 0); }
bool sCPU::irq_edge() { return (counter.irq_fire != 0); }
void sCPU::irqpos_update(uint16 addr) {
uint vpos = status.vcounter, hpos = status.hclock;
timeshift_backward(10, vpos, hpos);
if(hpos < status.hirq_trigger_pos) { status.irq_lock = false; }
}

View File

@ -0,0 +1,111 @@
void sCPU::update_interrupts() {
status.nmi_read_pos = (status.vcounter == status.vblstart) ? 2 : IRQ_TRIGGER_NEVER;
status.nmi_line_pos = (status.vcounter == status.vblstart) ? 6 : IRQ_TRIGGER_NEVER;
if(irq_pos_valid() == false) {
status.irq_read_pos = IRQ_TRIGGER_NEVER;
status.irq_line_pos = IRQ_TRIGGER_NEVER;
return;
}
uint vpos = status.virq_pos;
uint hpos = 4 * ((status.hirq_enabled) ? (status.hirq_pos + 1) : 0);
timeshift_forward(10, vpos, hpos);
if(!status.virq_enabled || (status.virq_enabled && status.vcounter == vpos)) {
status.irq_read_pos = hpos;
} else {
status.irq_read_pos = IRQ_TRIGGER_NEVER;
}
timeshift_forward(4, vpos, hpos);
if(!status.virq_enabled || (status.virq_enabled && status.vcounter == vpos)) {
status.irq_line_pos = hpos;
} else {
status.irq_line_pos = IRQ_TRIGGER_NEVER;
}
}
alwaysinline void sCPU::poll_interrupts(uint clocks) {
if(status.hclock + clocks >= status.line_clocks) {
clocks = (status.hclock + clocks) - status.line_clocks;
poll_interrupts_range(status.line_clocks - status.hclock);
scanline();
status.irq_lock = false;
if(clocks == 0) { return; }
}
poll_interrupts_range(clocks);
status.hclock += clocks;
}
alwaysinline void sCPU::poll_interrupts_range(uint clocks) {
int start, end;
if(status.hclock == 0) {
start = -1;
end = clocks;
} else {
start = status.hclock;
end = status.hclock + clocks;
}
if(start < status.nmi_read_pos && status.nmi_read_pos <= end) {
status.nmi_read = 0;
}
if(start < status.nmi_line_pos && status.nmi_line_pos <= end) {
if(status.nmi_enabled == true) {
if(status.nmi_line == 1) {
status.nmi_transition = 1;
}
status.nmi_line = 0;
}
}
if(status.virq_enabled == false && status.hirq_enabled == false) {
return;
}
if(status.hirq_enabled == false) {
if(status.irq_lock == false) {
if(end >= status.irq_read_pos) {
status.irq_read = 0;
}
if(end >= status.irq_line_pos) {
status.irq_lock = true;
status.irq_line = 0;
status.irq_transition = 1;
}
}
} else {
if(start < status.irq_read_pos && status.irq_read_pos <= end) {
status.irq_read = 0;
}
if(start < status.irq_line_pos && status.irq_line_pos <= end) {
status.irq_lock = true;
status.irq_line = 0;
status.irq_transition = 1;
}
}
}
bool sCPU::nmi_edge() {
uint vpos = status.vcounter, hpos = status.hclock;
if(hpos == status.nmi_read_pos)return true;
timeshift_backward(2, vpos, hpos);
if(hpos == status.nmi_read_pos)return true;
return false;
}
bool sCPU::irq_edge() {
uint vpos = status.vcounter, hpos = status.hclock;
if(hpos == status.irq_read_pos)return true;
timeshift_backward(2, vpos, hpos);
if(hpos == status.irq_read_pos)return true;
return false;
}
void sCPU::irqpos_update(uint16 addr) {
if(status.hclock < status.irq_line_pos) { status.irq_lock = false; }
}

View File

@ -45,35 +45,21 @@ uint16 sCPU::hcounter() {
}
void sCPU::add_clocks(uint clocks) {
status.clocks_executed += clocks;
if(counter.irq_delay) {
counter.irq_delay = (counter.irq_delay > clocks) ? (counter.irq_delay - clocks) : 0;
if(status.dram_refreshed == false) {
if(status.hclock + clocks >= status.dram_refresh_position) {
status.dram_refreshed = true;
clocks += 40;
}
}
if(status.hclock + clocks >= status.line_clocks) {
clocks = (status.hclock + clocks) - status.line_clocks;
while(status.hclock < status.line_clocks - 2) { tick(); }
scanline();
}
counter.sub(counter.irq_delay, clocks);
scheduler.addclocks_cpu(clocks);
clocks >>= 1;
while(clocks--) { tick(); }
}
alwaysinline void sCPU::tick() {
status.hclock += 2;
if(counter.nmi_fire) { nmi_tick(); }
if(counter.irq_fire) { irq_tick(); }
if(status.dram_refreshed == false && status.hclock >= status.dram_refresh_position) {
status.dram_refreshed = true;
add_clocks(40);
return;
}
poll_interrupts();
//TODO: rename function to more descriptive term
//below function is responsible for incrementing status.hclock
//by clocks, calling scanline() when a new line is reached, and
//testing for and triggering NMIs and IRQs
poll_interrupts(clocks);
}
void sCPU::scanline() {
@ -231,30 +217,16 @@ void sCPU::last_cycle() {
event.irq = (status.nmi_pending || status.irq_pending);
}
/*****
* clocks_executed()
*
* Return number of clocks executed since last call to this function.
* Used by class SNES to control CPU<>APU synchronization.
*****/
uint32 sCPU::clocks_executed() {
uint32 r = status.clocks_executed;
status.clocks_executed = 0;
return r;
}
void sCPU::timing_power() {
}
void sCPU::timing_reset() {
counter.enabled = false;
counter.nmi_fire = 0;
counter.irq_fire = 0;
counter.irq_delay = 0;
counter.hw_math = 0;
counter.irq_fire = 0;
counter.nmi_fire = 0;
status.clock_count = 0;
status.clocks_executed = 0;
status.clock_count = 0;
status.vcounter = 0;
status.hcounter = 0;
@ -285,6 +257,7 @@ void sCPU::timing_reset() {
status.nmi_read = 1;
status.nmi_line = 1;
status.nmi_transition = 0;
status.nmi_lock = false;
status.nmi_pending = false;
status.irq_read = 1;

View File

@ -13,7 +13,6 @@
uint dma_counter();
void add_clocks(uint clocks);
void tick();
void scanline();
void frame();
@ -25,10 +24,6 @@
void timing_power();
void timing_reset();
void counter_set(uint &ctr, uint clocks) {
if(clocks >= ctr) { ctr = clocks; }
}
//timeshift.cpp
void timeshift_forward (uint clocks, uint &v, uint &h);
void timeshift_backward(uint clocks, uint &v, uint &h);
@ -36,9 +31,13 @@
//irq.cpp
enum { IRQ_TRIGGER_NEVER = 0x3fff };
void update_interrupts();
void nmi_tick();
void irq_tick();
void poll_interrupts();
void poll_interrupts(uint clocks);
#ifdef FAVOR_SPEED
void poll_interrupts_range(uint clocks);
#endif
bool nmi_edge();
bool irq_edge();
void irqpos_update(uint16 addr);
bool irq_pos_valid();
bool nmi_test();
bool irq_test();

View File

@ -20,11 +20,9 @@
#include "cpu/cpu.h"
#include "cpu/scpu/scpu.h"
//#include "cpu/bcpu/bcpu.h"
#include "smp/smp.h"
#include "smp/ssmp/ssmp.h"
//#include "smp/bsmp/bsmp.h"
#include "dsp/dsp.h"
#include "dsp/bdsp/bdsp.h"

View File

@ -1,60 +0,0 @@
#include "../../base.h"
#include "core/core.cpp"
#include "memory/memory.cpp"
#include "timing/timing.cpp"
void bSMP::run() {
exec();
}
void bSMP::power() {
memset(spcram, 0x00, 65536);
reset();
}
void bSMP::reset() {
regs.pc = 0xffc0;
regs.a = 0x00;
regs.x = 0x00;
regs.y = 0x00;
regs.sp = 0xef;
regs.p = 0x02;
status.cycle_pos = 0;
status.clocks_executed = 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;
}
bSMP::bSMP() {
init_op_table();
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;
}
bSMP::~bSMP() {}

View File

@ -1,24 +0,0 @@
class bSMP : public SMP {
public:
#include "core/core.h"
#include "memory/memory.h"
#include "timing/timing.h"
struct {
uint8 cycle_pos, opcode;
uint32 clocks_executed;
//$f1
bool iplrom_enabled;
//$f2
uint8 dsp_addr;
} status;
inline void run();
inline void power();
inline void reset();
bSMP();
~bSMP();
};

View File

@ -1,18 +0,0 @@
#define CLASS_NAME "bSMP"
#include "../../../lib/opgen.cpp"
int main() {
fph = fopen("op.h", "wb");
fpt = fopen("optable.cpp", "wb");
generate("op_mov.cpp", "op_mov.b");
generate("op_pc.cpp", "op_pc.b");
generate("op_read.cpp", "op_read.b");
generate("op_rmw.cpp", "op_rmw.b");
generate("op_misc.cpp", "op_misc.b");
fclose(fph);
fclose(fpt);
return 0;
}

View File

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

View File

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

View File

@ -1,28 +0,0 @@
#include "opfn.cpp"
#include "op_mov.cpp"
#include "op_pc.cpp"
#include "op_read.cpp"
#include "op_rmw.cpp"
#include "op_misc.cpp"
void bSMP::exec() {
if(status.cycle_pos) {
(this->*optbl[status.opcode])();
add_cycles(1);
return;
}
//on first cycle?
status.opcode = op_read();
status.cycle_pos = 1;
add_cycles(1);
}
//only return true when we are on an opcode edge
bool bSMP::in_opcode() {
return (status.cycle_pos != 0);
}
void bSMP::init_op_table() {
#include "optable.cpp"
}

View File

@ -1,25 +0,0 @@
void (bSMP::*optbl[256])();
uint16 dp, sp, rd, wr, bit, ya;
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);
inline void exec();
inline bool in_opcode();
inline void init_op_table();
#include "op.h"

View File

@ -1,256 +0,0 @@
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();

View File

@ -1,164 +0,0 @@
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);
}

View File

@ -1,643 +0,0 @@
void bSMP::op_nop() {
switch(status.cycle_pos++) {
case 1: {
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_sleep() {
switch(status.cycle_pos++) {
case 1: {
} break;
case 2: {
regs.pc--;
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_stop() {
switch(status.cycle_pos++) {
case 1: {
} break;
case 2: {
regs.pc--;
status.cycle_pos = 0;
} break;
}
}
void bSMP::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 bSMP::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 bSMP::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 bSMP::op_clrc() {
switch(status.cycle_pos++) {
case 1: {
regs.p.c = 0;
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_clrp() {
switch(status.cycle_pos++) {
case 1: {
regs.p.p = 0;
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_setc() {
switch(status.cycle_pos++) {
case 1: {
regs.p.c = 1;
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_setp() {
switch(status.cycle_pos++) {
case 1: {
regs.p.p = 1;
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_clrv() {
switch(status.cycle_pos++) {
case 1: {
regs.p.v = 0;
regs.p.h = 0;
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_notc() {
switch(status.cycle_pos++) {
case 1: {
} break;
case 2: {
regs.p.c ^= 1;
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_ei() {
switch(status.cycle_pos++) {
case 1: {
} break;
case 2: {
regs.p.i = 1;
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_di() {
switch(status.cycle_pos++) {
case 1: {
} break;
case 2: {
regs.p.i = 0;
status.cycle_pos = 0;
} break;
}
}
void bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::op_div_ya_x() {
switch(status.cycle_pos++) {
case 1: {
} break;
case 2: {
} break;
case 3: {
} break;
case 4: {
} break;
case 5: {
} break;
case 6: {
} break;
case 7: {
} break;
case 8: {
} break;
case 9: {
} break;
case 10: {
} break;
case 11: {
ya = regs.ya;
//overflow set if quotient >= 256
regs.p.v = !!(regs.y >= regs.x);
regs.p.h = !!((regs.y & 15) >= (regs.x & 15));
if(regs.y < (regs.x << 1)) {
//if quotient is <= 511 (will fit into 9-bit result)
regs.a = ya / regs.x;
regs.y = ya % regs.x;
} else {
//otherwise, the quotient won't fit into regs.p.v + regs.a
//this emulates the odd behavior of the SPC700 in this case
regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x);
regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x);
}
//result is set based on a (quotient) only
regs.p.n = !!(regs.a & 0x80);
regs.p.z = (regs.a == 0);
status.cycle_pos = 0;
} break;
}
}

View File

@ -1,210 +0,0 @@
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) {
1:regs.$1 = regs.$2;
regs.p.n = !!(regs.$1 & 0x80);
regs.p.z = (regs.$1 == 0);
}
mov_sp_x(0xbd, sp, x) {
1:regs.$1 = regs.$2;
}
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);
}

View File

@ -1,708 +0,0 @@
void bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::op_mov_sp_x() {
switch(status.cycle_pos++) {
case 1: {
regs.sp = regs.x;
status.cycle_pos = 0;
} break;
}
}
void bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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;
}
}

View File

@ -1,166 +0,0 @@
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) {
1:dp = op_read();
2:rd = op_read();
3:sp = op_read(OPMODE_DP, dp);
4:if(regs.a == sp)end;
5:
6:regs.pc += (int8)rd;
}
cbne_dpx(0xde) {
1:dp = op_read();
2:rd = op_read();
3:
4:sp = op_read(OPMODE_DP, dp + regs.x);
5:if(regs.a == sp)end;
6:
7: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;
}

File diff suppressed because it is too large Load Diff

View File

@ -1,194 +0,0 @@
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));
}

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,452 +0,0 @@
void bSMP::op_inc_a() {
switch(status.cycle_pos++) {
case 1: {
regs.a = op_inc(regs.a);
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_inc_x() {
switch(status.cycle_pos++) {
case 1: {
regs.x = op_inc(regs.x);
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_inc_y() {
switch(status.cycle_pos++) {
case 1: {
regs.y = op_inc(regs.y);
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_dec_a() {
switch(status.cycle_pos++) {
case 1: {
regs.a = op_dec(regs.a);
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_dec_x() {
switch(status.cycle_pos++) {
case 1: {
regs.x = op_dec(regs.x);
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_dec_y() {
switch(status.cycle_pos++) {
case 1: {
regs.y = op_dec(regs.y);
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_asl_a() {
switch(status.cycle_pos++) {
case 1: {
regs.a = op_asl(regs.a);
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_lsr_a() {
switch(status.cycle_pos++) {
case 1: {
regs.a = op_lsr(regs.a);
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_rol_a() {
switch(status.cycle_pos++) {
case 1: {
regs.a = op_rol(regs.a);
status.cycle_pos = 0;
} break;
}
}
void bSMP::op_ror_a() {
switch(status.cycle_pos++) {
case 1: {
regs.a = op_ror(regs.a);
status.cycle_pos = 0;
} break;
}
}
void bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::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 bSMP::op_decw_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
} break;
case 2: {
rd = op_read(OPMODE_DP, dp);
} break;
case 3: {
rd |= op_read(OPMODE_DP, dp + 1) << 8;
} break;
case 4: {
rd = op_decw(rd);
op_write(OPMODE_DP, dp + 1, rd >> 8);
} break;
case 5: {
op_write(OPMODE_DP, dp, rd);
status.cycle_pos = 0;
} break;
}
}

View File

@ -1,138 +0,0 @@
uint8 bSMP::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 bSMP::op_addw(uint16 x, uint16 y) {
int16 r;
regs.p.c = 0;
r = op_adc(x, y);
r |= op_adc(x >> 8, y >> 8) << 8;
regs.p.z = ((uint16)r == 0);
return r;
}
uint8 bSMP::op_and(uint8 x, uint8 y) {
x &= y;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 bSMP::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 bSMP::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 bSMP::op_eor(uint8 x, uint8 y) {
x ^= y;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 bSMP::op_or(uint8 x, uint8 y) {
x |= y;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 bSMP::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 bSMP::op_subw(uint16 x, uint16 y) {
int16 r;
regs.p.c = 1;
r = op_sbc(x, y);
r |= op_sbc(x >> 8, y >> 8) << 8;
regs.p.z = ((uint16)r == 0);
return r;
}
uint8 bSMP::op_inc(uint8 x) {
x++;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint16 bSMP::op_incw(uint16 x) {
x++;
regs.p.n = !!(x & 0x8000);
regs.p.z = (x == 0);
return x;
}
uint8 bSMP::op_dec(uint8 x) {
x--;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint16 bSMP::op_decw(uint16 x) {
x--;
regs.p.n = !!(x & 0x8000);
regs.p.z = (x == 0);
return x;
}
uint8 bSMP::op_asl(uint8 x) {
regs.p.c = !!(x & 0x80);
x <<= 1;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 bSMP::op_lsr(uint8 x) {
regs.p.c = !!(x & 0x01);
x >>= 1;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 bSMP::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 bSMP::op_ror(uint8 x) {
uint8 c = (regs.p.c)?0x80:0x00;
regs.p.c = !!(x & 0x01);
x >>= 1;
x |= c;
regs.p.n = !!(x & 0x80);
regs.p.z = (x == 0);
return x;
}

View File

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

View File

@ -1,184 +0,0 @@
uint8 bSMP::ram_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 = r_dsp->read(status.dsp_addr & 0x7f);
break;
case 0xf4: //CPUIO0
case 0xf5: //CPUIO1
case 0xf6: //CPUIO2
case 0xf7: //CPUIO3
r = 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];
}
}
return r;
}
void bSMP::ram_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 SMP port read registers,
//emulated by simulating CPU writes of 0x00
if(value & 0x20) {
r_cpu->port_write(2, 0x00);
r_cpu->port_write(3, 0x00);
}
if(value & 0x10) {
r_cpu->port_write(0, 0x00);
r_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) {
r_dsp->write(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;
}
}
uint8 bSMP::port_read(uint8 port) {
return spcram[0xf4 + (port & 3)];
}
void bSMP::port_write(uint8 port, uint8 value) {
spcram[0xf4 + (port & 0x03)] = value;
}
uint8 bSMP::op_read() {
uint8 r;
r = ram_read(regs.pc);
regs.pc++;
return r;
}
uint8 bSMP::op_read(uint8 mode, uint16 addr) {
uint8 r;
switch(mode) {
case OPMODE_ADDR:
r = ram_read(addr);
break;
case OPMODE_DP:
r = ram_read(((regs.p.p)?0x100:0x000) + (addr & 0xff));
break;
}
return r;
}
void bSMP::op_write(uint8 mode, uint16 addr, uint8 value) {
switch(mode) {
case OPMODE_ADDR:
ram_write(addr, value);
break;
case OPMODE_DP:
ram_write(((regs.p.p)?0x100:0x000) + (addr & 0xff), value);
break;
}
}
uint8 bSMP::stack_read() {
regs.sp++;
return ram_read(0x0100 | regs.sp);
}
void bSMP::stack_write(uint8 value) {
ram_write(0x0100 | regs.sp, value);
regs.sp--;
}

View File

@ -1,11 +0,0 @@
enum { OPMODE_ADDR, OPMODE_DP };
inline uint8 ram_read (uint16 addr);
inline void ram_write(uint16 addr, uint8 value);
inline uint8 port_read (uint8 port);
inline void port_write(uint8 port, uint8 value);
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);

View File

@ -1,35 +0,0 @@
void bSMP::add_cycles(int cycles) {
status.clocks_executed += cycles;
t0.add_cycles(cycles);
t1.add_cycles(cycles);
t2.add_cycles(cycles);
}
uint32 bSMP::clocks_executed() {
uint32 r = status.clocks_executed;
status.clocks_executed = 0;
return (r << 4) + (r << 3);
}
//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 bSMP::bSMPTimer::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;
}

View File

@ -1,9 +0,0 @@
class bSMPTimer {
public:
uint8 cycle_frequency, target;
uint8 stage1_ticks, stage2_ticks, stage3_ticks;
bool enabled;
inline void add_cycles(int cycles);
} t0, t1, t2;
inline void add_cycles(int cycles);
inline uint32 clocks_executed();

View File

@ -1,6 +1,10 @@
#include "smpregs.h"
class SMP {
public:
thread_t thread;
virtual void enter() = 0;
public:
SMPRegs regs;
uint8 spcram[65536];
@ -17,9 +21,6 @@ static const uint8 iplrom[64];
virtual void port_write(uint8 port, uint8 value) = 0;
virtual uint8 *get_spcram_handle() { return spcram; }
virtual void main() {}
virtual void run() = 0;
virtual uint32 clocks_executed() = 0;
virtual void power() = 0;
virtual void reset() = 0;

View File

@ -1,6 +1,6 @@
#include "opfn.cpp"
void sSMP::main() {
void sSMP::enter() {
for(;;) {
tracer.trace_smpop(); //traces SMP opcode (only if tracer is enabled)
@ -15,9 +15,5 @@ void sSMP::main() {
}
status.in_opcode = false;
#ifdef FAVOR_SPEED
co_return();
#endif
}
}

View File

@ -25,10 +25,7 @@ alwaysinline uint8 sSMP::op_busread(uint16 addr) {
uint8 r;
if((addr & 0xfff0) == 0x00f0) {
//addr >= 0x00f0 && addr <= 0x00ff
#ifdef FAVOR_SPEED
co_return();
#endif
scheduler.sync_smpcpu();
switch(addr) {
@ -99,10 +96,7 @@ uint8 r;
alwaysinline void sSMP::op_buswrite(uint16 addr, uint8 data) {
if((addr & 0xfff0) == 0x00f0) {
//addr >= 0x00f0 && addr >= 0x00ff
#ifdef FAVOR_SPEED
co_return();
#endif
scheduler.sync_smpcpu();
if(status.mmio_disabled == true)return;
@ -208,25 +202,48 @@ alwaysinline void sSMP::op_buswrite(uint16 addr, uint8 data) {
//
alwaysinline void sSMP::op_io() {
void sSMP::op_io() {
add_clocks(status.clock_speed);
//co_return();
}
alwaysinline uint8 sSMP::op_read(uint16 addr) {
uint8 sSMP::op_read(uint16 addr) {
add_clocks(status.clock_speed >> 1);
#ifdef FAVOR_ACCURACY
co_return();
#endif
uint8 r = op_busread(addr);
add_clocks(status.clock_speed >> 1);
return r;
}
alwaysinline void sSMP::op_write(uint16 addr, uint8 data) {
void sSMP::op_write(uint16 addr, uint8 data) {
add_clocks(status.clock_speed);
#ifdef FAVOR_ACCURACY
co_return();
#endif
op_buswrite(addr, data);
}
//
alwaysinline uint8 sSMP::op_readpc() {
return op_read(regs.pc++);
}
alwaysinline uint8 sSMP::op_readstack() {
return op_read(0x0100 | ++regs.sp);
}
alwaysinline void sSMP::op_writestack(uint8 data) {
op_write(0x0100 | regs.sp--, data);
}
alwaysinline uint8 sSMP::op_readaddr(uint16 addr) {
return op_read(addr);
}
alwaysinline void sSMP::op_writeaddr(uint16 addr, uint8 data) {
op_write(addr, data);
}
alwaysinline uint8 sSMP::op_readdp(uint8 addr) {
return op_read(((uint)regs.p.p << 8) + addr);
}
alwaysinline void sSMP::op_writedp(uint8 addr, uint8 data) {
op_write(((uint)regs.p.p << 8) + addr, data);
}

View File

@ -17,13 +17,13 @@
/*****
* helper memory addressing functions used by SMP core
*****/
uint8 op_readpc () { return op_read(regs.pc++); }
uint8 op_readpc ();
uint8 op_readstack () { return op_read(0x0100 | ++regs.sp); }
void op_writestack(uint8 data) { op_write(0x0100 | regs.sp--, data); }
uint8 op_readstack ();
void op_writestack(uint8 data);
uint8 op_readaddr (uint16 addr) { return op_read(addr); }
void op_writeaddr (uint16 addr, uint8 data) { op_write(addr, data); }
uint8 op_readaddr (uint16 addr);
void op_writeaddr (uint16 addr, uint8 data);
uint8 op_readdp (uint8 addr) { return op_read(((uint)regs.p.p << 8) + addr); }
void op_writedp (uint8 addr, uint8 data) { op_write(((uint)regs.p.p << 8) + addr, data); }
uint8 op_readdp (uint8 addr);
void op_writedp (uint8 addr, uint8 data);

View File

@ -4,14 +4,6 @@
#include "memory/memory.cpp"
#include "timing/timing.cpp"
void ssmp_entry_point() {
r_smp->main();
}
void sSMP::run() {
co_call(thread);
}
void sSMP::power() {
//for(int i = 0; i < 65536; i += 64) {
// memset(spcram + i, 0x00, 32);
@ -29,9 +21,6 @@ void sSMP::power() {
}
void sSMP::reset() {
if(thread)co_delete(thread);
thread = co_create(ssmp_entry_point, 65536);
regs.pc = 0xffc0;
regs.a = 0x00;
regs.x = 0x00;
@ -39,7 +28,8 @@ void sSMP::reset() {
regs.sp = 0xef;
regs.p = 0x02;
status.clocks_executed = 0;
status.clock_counter = 0;
status.dsp_counter = 0;
//$00f0
status.clock_speed = 24 * 3 / 3;
@ -69,10 +59,5 @@ void sSMP::reset() {
t2.stage3_ticks = 0;
}
sSMP::sSMP() {
thread = 0;
}
sSMP::~sSMP() {
if(thread)co_delete(thread);
}
sSMP::sSMP() {}
sSMP::~sSMP() {}

View File

@ -1,18 +1,19 @@
class sSMP : public SMP {
public:
void enter();
public:
#include "core/core.h"
#include "memory/memory.h"
#include "timing/timing.h"
thread_t thread;
struct {
uint8 opcode;
bool in_opcode;
//timing
uint32 clocks_executed;
uint32 clock_counter;
uint32 dsp_counter;
//$00f0
uint8 clock_speed;
@ -27,9 +28,6 @@ struct {
} status;
//ssmp.cpp
void main();
void run();
void power();
void reset();

View File

@ -1,6 +1,7 @@
inline void sSMP::add_clocks(uint clocks) {
status.clocks_executed += clocks;
status.clock_counter += clocks;
alwaysinline void sSMP::add_clocks(uint clocks) {
scheduler.addclocks_smp(clocks);
status.clock_counter += clocks;
//update timers
while(status.clock_counter >= 24) {
@ -8,11 +9,12 @@ inline void sSMP::add_clocks(uint clocks) {
t0.tick();
t1.tick();
t2.tick();
//24 * 32 = 768 clocks/DSP tick
//1024000 / 768 = 32000 DSP ticks/second
if(++status.dsp_counter == 32) {
status.dsp_counter = 0;
snes->audio_update(r_dsp->run());
}
}
}
inline uint32 sSMP::clocks_executed() {
uint32 r = status.clocks_executed;
status.clocks_executed = 0;
return r;
}

View File

@ -0,0 +1,49 @@
Scheduler scheduler;
//
void threadentry_cpu() { r_cpu->enter(); }
void threadentry_smp() { r_smp->enter(); }
//
void Scheduler::enter() {
switch(clock.active) {
case THREAD_CPU:
co_jump(thread_cpu);
break;
case THREAD_SMP:
co_jump(thread_smp);
break;
}
}
void Scheduler::exit() {
co_jump(thread_snes);
}
void Scheduler::init() {
clock.cpu_freq = snes->region() == SNES::NTSC ?
config::cpu.ntsc_clock_rate :
config::cpu.pal_clock_rate;
clock.smp_freq = snes->region() == SNES::NTSC ?
config::smp.ntsc_clock_rate :
config::smp.pal_clock_rate;
clock.active = THREAD_CPU;
clock.cpusmp = 0;
if(thread_cpu)co_delete(thread_cpu);
if(thread_smp)co_delete(thread_smp);
thread_cpu = co_create(threadentry_cpu, 65536);
thread_smp = co_create(threadentry_smp, 65536);
}
//
Scheduler::Scheduler() {
thread_snes = co_active();
thread_cpu = 0;
thread_smp = 0;
}

View File

@ -0,0 +1,52 @@
class Scheduler {
public:
thread_t thread_snes;
thread_t thread_cpu;
thread_t thread_smp;
enum ActiveThread {
THREAD_CPU,
THREAD_SMP,
};
struct {
uint cpu_freq;
uint smp_freq;
ActiveThread active;
int64 cpusmp;
} clock;
alwaysinline void sync_cpusmp() {
if(clock.cpusmp < 0) {
clock.active = THREAD_SMP;
co_jump(thread_smp);
}
}
alwaysinline void sync_smpcpu() {
if(clock.cpusmp >= 0) {
clock.active = THREAD_CPU;
co_jump(thread_cpu);
}
}
alwaysinline void addclocks_cpu(uint clocks) {
clock.cpusmp -= clocks * (uint64)clock.smp_freq;
if(clock.cpusmp < -(275000 * (int64)24000000))sync_cpusmp();
}
alwaysinline void addclocks_smp(uint clocks) {
clock.cpusmp += clocks * (uint64)clock.cpu_freq;
if(clock.cpusmp > +(275000 * (int64)24000000))sync_smpcpu();
}
void enter();
void exit();
void init();
Scheduler();
};
extern Scheduler scheduler;

View File

@ -2,37 +2,17 @@
SNES *snes;
#include "scheduler/scheduler.cpp"
#include "tracer/tracer.cpp"
#include "video/filter.cpp"
#include "video/video.cpp"
#include "audio/audio.cpp"
#include "input/input.cpp"
void SNES::run() {
if(sync.counter <= 0) {
r_cpu->run();
uint32 clocks = r_cpu->clocks_executed();
sync.counter += sync.apu_multbl[clocks];
} else {
r_smp->run();
uint32 clocks = r_smp->clocks_executed();
sync.counter -= sync.cpu_multbl[clocks];
//1024000(SPC700) / 32000(DSP) = 32spc/dsp ticks
//24576000(Sound clock crystal) / 32000(DSP) = 768crystal/dsp ticks
sync.dsp_counter += clocks;
while(sync.dsp_counter >= 768) {
sync.dsp_counter -= 768;
audio_update(r_dsp->run());
}
}
}
void SNES::run() {}
void SNES::runtoframe() {
while(r_ppu->status.frame_executed == false) {
SNES::run();
}
r_ppu->status.frame_executed = false;
scheduler.enter();
}
void SNES::init() {
@ -60,6 +40,8 @@ void SNES::term() {
}
void SNES::power() {
scheduler.init();
r_cpu->power();
r_smp->power();
r_dsp->power();
@ -92,8 +74,7 @@ void SNES::power() {
}
void SNES::reset() {
sync.counter = -sync.cpu_multbl[32];
sync.dsp_counter = 0;
scheduler.init();
r_cpu->reset();
r_smp->reset();
@ -118,6 +99,7 @@ void SNES::scanline() {
//video output seem more responsive to controller input
if(r_cpu->vcounter() == 241) {
video_update();
scheduler.exit();
}
}
@ -135,36 +117,8 @@ void SNES::set_region(uint8 new_region) {
} else {
alert("Unsupported region : %0.2x", new_region);
}
update_timing();
}
uint8 SNES::region() { return snes_region; }
/*****
* Timing
*
* Note: Stock PAL CPU speed is currently unknown.
* It is thought to be 21281370hz, but this causes
* sound errors in certain games. Therefore, the PAL
* CPU is currently clocked 40000hz slower, at
* 21241370hz.
*****/
void SNES::update_timing() {
sync.counter = 0;
sync.dsp_counter = 0;
sync.cpu_freq = (snes_region == NTSC) ? config::cpu.ntsc_clock_rate : config::cpu.pal_clock_rate;
sync.apu_freq = (snes_region == NTSC) ? config::smp.ntsc_clock_rate : config::smp.pal_clock_rate;
for(int64 i = 0; i < 1024; i++) {
sync.cpu_multbl[i] = i * sync.cpu_freq;
sync.apu_multbl[i] = i * sync.apu_freq;
}
}
SNES::SNES() {
snes_region = NTSC;
update_timing();
}
SNES::SNES() {}

View File

@ -1,3 +1,4 @@
#include "scheduler/scheduler.h"
#include "tracer/tracer.h"
class VideoFilter;
@ -6,15 +7,6 @@ class SNES {
protected:
uint8 snes_region;
//CPU<>APU synchronization
struct {
int64 counter, dsp_counter;
int64 cpu_freq, apu_freq;
int64 cpu_multbl[1024], apu_multbl[1024];
} sync;
void update_timing();
public:
enum { NTSC = 0, PAL = 1 };

View File

@ -1,3 +1,5 @@
#include "filter.cpp"
void SNES::set_video_format(uint filter, uint video_standard, uint pixel_format) {
//only make changes at the start of a new frame
video_format.filter = filter;

View File

@ -118,10 +118,10 @@ OBJS = main.$(OBJ) \
bdsp.$(OBJ) \
ppu.$(OBJ) bppu.$(OBJ) \
snes.$(OBJ) \
srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) dsp2.$(OBJ) obc1.$(OBJ) \
adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) gzio.$(OBJ) inffast.$(OBJ) \
inflate.$(OBJ) inftrees.$(OBJ) ioapi.$(OBJ) trees.$(OBJ) unzip.$(OBJ) zip.$(OBJ) zutil.$(OBJ) \
jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ)
srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) dsp2.$(OBJ) obc1.$(OBJ)
# adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) gzio.$(OBJ) inffast.$(OBJ) \
# inflate.$(OBJ) inftrees.$(OBJ) ioapi.$(OBJ) trees.$(OBJ) unzip.$(OBJ) zip.$(OBJ) zutil.$(OBJ) \
# jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ)
ifeq ($(OS),win)
ifeq ($(CC),cl)
@ -182,9 +182,6 @@ cpu.$(OBJ): ../cpu/*
scpu.$(OBJ): ../cpu/scpu/* ../cpu/scpu/core/* ../cpu/scpu/dma/* ../cpu/scpu/memory/* ../cpu/scpu/mmio/* ../cpu/scpu/timing/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../cpu/scpu/scpu.cpp
bcpu.$(OBJ): ../cpu/bcpu/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../cpu/bcpu/bcpu.cpp
###########
### smp ###
###########
@ -194,9 +191,6 @@ smp.$(OBJ): ../smp/*
ssmp.$(OBJ): ../smp/ssmp/* ../smp/ssmp/core/* ../smp/ssmp/memory/* ../smp/ssmp/timing/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../smp/ssmp/ssmp.cpp
bsmp.$(OBJ): ../smp/bsmp/*
$(CXX) $(CFLAGS) $(COBJFLAG) ../smp/bsmp/bsmp.cpp
###########
### dsp ###
###########

View File

@ -1,3 +1,3 @@
@make PLATFORM=win-visualc
@make PLATFORM=win-visualc-wip
@move bsnes.exe ../../bsnes.exe>nul
@pause