mirror of https://github.com/bsnes-emu/bsnes.git
parent
11e0a2ac18
commit
b0a8de0208
10
src/Makefile
10
src/Makefile
|
@ -94,8 +94,8 @@ link += $(if $(findstring input.rawinput,$(ruby)),$(call mklib,xinput) $(call mk
|
|||
|
||||
objects = libco ruby libfilter string \
|
||||
reader cart cheat \
|
||||
memory smemory cpu scpu smp ssmp sdsp ppu bppu snes \
|
||||
bsx srtc sdd1 spc7110 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st010
|
||||
memory smemory cpu cpucore scpu smp ssmp sdsp ppu bppu snes \
|
||||
sa1 bsx srtc sdd1 spc7110 cx4 dsp1 dsp2 dsp3 dsp4 obc1 st010
|
||||
|
||||
ifeq ($(enable_gzip),true)
|
||||
objects += adler32 compress crc32 deflate gzio inffast inflate inftrees ioapi trees unzip zip zutil
|
||||
|
@ -159,8 +159,9 @@ obj/smemory.$(obj): memory/smemory/smemory.cpp memory/smemory/* memory/smemory/m
|
|||
### cpu ###
|
||||
###########
|
||||
|
||||
obj/cpu.$(obj) : cpu/cpu.cpp cpu/*
|
||||
obj/scpu.$(obj): cpu/scpu/scpu.cpp cpu/scpu/* cpu/scpu/core/* cpu/scpu/dma/* cpu/scpu/memory/* cpu/scpu/mmio/* cpu/scpu/timing/*
|
||||
obj/cpu.$(obj) : cpu/cpu.cpp cpu/*
|
||||
obj/cpucore.$(obj): cpu/core/core.cpp cpu/core/* cpu/core/disasm/*
|
||||
obj/scpu.$(obj) : cpu/scpu/scpu.cpp cpu/scpu/* cpu/scpu/dma/* cpu/scpu/memory/* cpu/scpu/mmio/* cpu/scpu/timing/*
|
||||
|
||||
###########
|
||||
### smp ###
|
||||
|
@ -193,6 +194,7 @@ obj/snes.$(obj): snes/snes.cpp snes/* snes/scheduler/* snes/video/* snes/audio/*
|
|||
### special chips ###
|
||||
#####################
|
||||
|
||||
obj/sa1.$(obj) : chip/sa1/sa1.cpp chip/sa1/* chip/sa1/bus/* chip/sa1/dma/* chip/sa1/memory/* chip/sa1/mmio/*
|
||||
obj/bsx.$(obj) : chip/bsx/bsx.cpp chip/bsx/*
|
||||
obj/srtc.$(obj) : chip/srtc/srtc.cpp chip/srtc/*
|
||||
obj/sdd1.$(obj) : chip/sdd1/sdd1.cpp chip/sdd1/*
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
#define BSNES_VERSION "0.042"
|
||||
#define BSNES_VERSION "0.043"
|
||||
#define BSNES_TITLE "bsnes v" BSNES_VERSION
|
||||
|
||||
#define BUSCORE sBus
|
||||
|
@ -40,10 +40,8 @@ using namespace nall;
|
|||
typedef int8_t int8;
|
||||
typedef int16_t int16;
|
||||
typedef int32_t int32;
|
||||
typedef int64_t int64;
|
||||
typedef uint8_t uint8;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint64_t uint64;
|
||||
|
||||
#include "interface.hpp"
|
||||
|
|
|
@ -27,6 +27,7 @@ public:
|
|||
HiROM,
|
||||
ExLoROM,
|
||||
ExHiROM,
|
||||
SA1ROM,
|
||||
SPC7110ROM,
|
||||
BSCLoROM,
|
||||
BSCHiROM,
|
||||
|
|
|
@ -91,8 +91,9 @@ void Cartridge::read_header(cartinfo_t &info, const uint8_t *data, unsigned size
|
|||
info.superfx = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x23 && (rom_type == 0x34 || rom_type == 0x35)) {
|
||||
if(mapper == 0x23 && (rom_type == 0x32 || rom_type == 0x34 || rom_type == 0x35)) {
|
||||
info.sa1 = true;
|
||||
info.mapper = SA1ROM;
|
||||
}
|
||||
|
||||
if(mapper == 0x35 && rom_type == 0x55) {
|
||||
|
|
|
@ -217,10 +217,11 @@ bool Cartridge::load_image(const char *filename, uint8_t *&data, unsigned &size,
|
|||
|
||||
uint8_t *pdata;
|
||||
unsigned psize;
|
||||
if(load_file(get_filename(filename, "ups", snes.config.path.patch), pdata, psize, CompressionInspect) == true) {
|
||||
apply_patch(pdata, psize, data, size);
|
||||
string path = (snes.config.path.patch == "" ? basepath(filename) : snes.config.path.patch);
|
||||
if(load_file(get_filename(filename, "ups", path), pdata, psize, CompressionInspect) == true) {
|
||||
bool result = apply_patch(pdata, psize, data, size);
|
||||
delete[] pdata;
|
||||
patched = true;
|
||||
patched = result;
|
||||
} else {
|
||||
patched = false;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
::@mingw32-make platform=win compiler=mingw32-gcc
|
||||
@mingw32-make platform=win compiler=mingw32-gcc enable_gzip=true enable_jma=true
|
||||
@mingw32-make platform=win compiler=mingw32-gcc
|
||||
::@mingw32-make platform=win compiler=mingw32-gcc enable_gzip=true enable_jma=true
|
||||
@pause
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
make platform=x compiler=gcc
|
||||
#make platform=x compiler=gcc enable_gzip=true enable_jma=true
|
||||
#make platform=x compiler=gcc
|
||||
make platform=x compiler=gcc enable_gzip=true enable_jma=true
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#include "sa1/sa1.hpp"
|
||||
#include "bsx/bsx.hpp"
|
||||
#include "srtc/srtc.hpp"
|
||||
#include "sdd1/sdd1.hpp"
|
||||
|
|
|
@ -30,8 +30,8 @@ uint16 addr = 0x0080 + (r * 3);
|
|||
}
|
||||
|
||||
void Cx4::mul(uint32 x, uint32 y, uint32 &rl, uint32 &rh) {
|
||||
int64 rx = x & 0xffffff;
|
||||
int64 ry = y & 0xffffff;
|
||||
int64_t rx = x & 0xffffff;
|
||||
int64_t ry = y & 0xffffff;
|
||||
if(rx & 0x800000)rx |= ~0x7fffff;
|
||||
if(ry & 0x800000)ry |= ~0x7fffff;
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ uint8 OBC1::read(unsigned addr) {
|
|||
addr &= 0x1fff;
|
||||
if((addr & 0x1ff8) != 0x1ff0) return ram_read(addr);
|
||||
|
||||
switch(addr) { default: //never used, avoids compiler warning
|
||||
switch(addr) { default: //never used, avoids compiler warning
|
||||
case 0x1ff0: return ram_read(status.baseptr + (status.address << 2) + 0);
|
||||
case 0x1ff1: return ram_read(status.baseptr + (status.address << 2) + 1);
|
||||
case 0x1ff2: return ram_read(status.baseptr + (status.address << 2) + 2);
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
#ifdef SA1_CPP
|
||||
|
||||
namespace memory {
|
||||
namespace cpu {
|
||||
CPUIRAM iram;
|
||||
CPUBWRAM bwram;
|
||||
}
|
||||
|
||||
namespace sa1 {
|
||||
SA1IRAM iram;
|
||||
SA1BWRAM bwram;
|
||||
SA1BitmapRAM bitmapram;
|
||||
}
|
||||
}
|
||||
|
||||
void SA1Bus::init() {
|
||||
for(uint32_t i = 0x0000; i <= 0xffff; i++) {
|
||||
map(i << 8, memory::memory_unmapped, 0);
|
||||
}
|
||||
|
||||
for(uint16_t i = 0x2200; i <= 0x23ff; i++) {
|
||||
memory::mmio.map(i, sa1);
|
||||
}
|
||||
|
||||
map(MapLinear, 0x00, 0x3f, 0x0000, 0x07ff, memory::sa1::iram);
|
||||
map(MapDirect, 0x00, 0x3f, 0x2200, 0x23ff, memory::mmio);
|
||||
map(MapLinear, 0x00, 0x3f, 0x3000, 0x37ff, memory::sa1::iram);
|
||||
map(MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::sa1::bwram);
|
||||
map(MapLinear, 0x00, 0x3f, 0x8000, 0xffff, memory::cartrom);
|
||||
map(MapLinear, 0x40, 0x4f, 0x0000, 0xffff, memory::sa1::bwram, 0, 0x040000);
|
||||
map(MapLinear, 0x60, 0x6f, 0x0000, 0xffff, memory::sa1::bitmapram);
|
||||
map(MapLinear, 0x80, 0xbf, 0x0000, 0x07ff, memory::sa1::iram);
|
||||
map(MapDirect, 0x80, 0xbf, 0x2200, 0x23ff, memory::mmio);
|
||||
map(MapLinear, 0x80, 0xbf, 0x3000, 0x37ff, memory::sa1::iram);
|
||||
map(MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::sa1::bwram);
|
||||
map(MapLinear, 0x80, 0xbf, 0x8000, 0xffff, memory::cartrom);
|
||||
map(MapLinear, 0xc0, 0xff, 0x0000, 0xffff, memory::cartrom);
|
||||
|
||||
bus.map(MapLinear, 0x00, 0x3f, 0x3000, 0x37ff, memory::cpu::iram);
|
||||
bus.map(MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cpu::bwram);
|
||||
bus.map(MapLinear, 0x00, 0x3f, 0x8000, 0xffff, memory::cartrom);
|
||||
bus.map(MapLinear, 0x40, 0x4f, 0x0000, 0xffff, memory::cpu::bwram, 0, 0x040000);
|
||||
bus.map(MapLinear, 0x80, 0xbf, 0x3000, 0x37ff, memory::cpu::iram);
|
||||
bus.map(MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cpu::bwram);
|
||||
bus.map(MapLinear, 0x80, 0xbf, 0x8000, 0xffff, memory::cartrom);
|
||||
bus.map(MapLinear, 0xc0, 0xff, 0x0000, 0xffff, memory::cartrom);
|
||||
}
|
||||
|
||||
//=======
|
||||
//CPUIRAM
|
||||
//=======
|
||||
|
||||
unsigned CPUIRAM::size() const {
|
||||
return sizeof(sa1.iram);
|
||||
}
|
||||
|
||||
uint8_t CPUIRAM::read(unsigned addr) {
|
||||
return sa1.iram[addr];
|
||||
}
|
||||
|
||||
void CPUIRAM::write(unsigned addr, uint8_t data) {
|
||||
uint8_t wpbit = (addr >> 8) & 7;
|
||||
if(1 || sa1.mmio.siwp & wpbit) {
|
||||
//allow only when write-protection is disabled
|
||||
sa1.iram[addr] = data;
|
||||
}
|
||||
}
|
||||
|
||||
//========
|
||||
//CPUBWRAM
|
||||
//========
|
||||
|
||||
unsigned CPUBWRAM::size() const {
|
||||
return memory::cartram.size();
|
||||
}
|
||||
|
||||
uint8_t CPUBWRAM::read(unsigned addr) {
|
||||
if(cc1dma) return sa1.dma_cc1_read(addr);
|
||||
return memory::cartram.read(addr);
|
||||
}
|
||||
|
||||
void CPUBWRAM::write(unsigned addr, uint8_t data) {
|
||||
if(sa1.mmio.swen == false) {
|
||||
//write-protection enabled
|
||||
unsigned limit = 0x100 << sa1.mmio.bwp;
|
||||
//if(addr < limit) return;
|
||||
}
|
||||
|
||||
memory::cartram.write(addr, data);
|
||||
}
|
||||
|
||||
//=======
|
||||
//SA1IRAM
|
||||
//=======
|
||||
|
||||
unsigned SA1IRAM::size() const {
|
||||
return sizeof(sa1.iram);
|
||||
}
|
||||
|
||||
uint8_t SA1IRAM::read(unsigned addr) {
|
||||
return sa1.iram[addr];
|
||||
}
|
||||
|
||||
void SA1IRAM::write(unsigned addr, uint8_t data) {
|
||||
uint8_t wpbit = (addr >> 8) & 7;
|
||||
if(1 || sa1.mmio.ciwp & wpbit) {
|
||||
//allow only when write-protection is disabled
|
||||
sa1.iram[addr] = data;
|
||||
}
|
||||
}
|
||||
|
||||
//========
|
||||
//SA1BWRAM
|
||||
//========
|
||||
|
||||
unsigned SA1BWRAM::size() const {
|
||||
return memory::cartram.size();
|
||||
}
|
||||
|
||||
uint8_t SA1BWRAM::read(unsigned addr) {
|
||||
return memory::cartram.read(addr);
|
||||
}
|
||||
|
||||
void SA1BWRAM::write(unsigned addr, uint8_t data) {
|
||||
if(sa1.mmio.cwen == false) {
|
||||
//write-protection enabled
|
||||
unsigned limit = 0x100 << sa1.mmio.bwp;
|
||||
//if(addr < limit) return;
|
||||
}
|
||||
|
||||
memory::cartram.write(addr, data);
|
||||
}
|
||||
|
||||
//============
|
||||
//SA1BitmapRAM
|
||||
//============
|
||||
|
||||
unsigned SA1BitmapRAM::size() const {
|
||||
return 0x100000;
|
||||
}
|
||||
|
||||
uint8_t SA1BitmapRAM::read(unsigned addr) {
|
||||
if(sa1.mmio.bbf == 0) {
|
||||
//4bpp
|
||||
unsigned shift = addr & 1;
|
||||
addr = (addr >> 1) & (memory::cartram.size() - 1);
|
||||
switch(shift) {
|
||||
case 0: return (memory::cartram.read(addr) >> 0) & 15;
|
||||
case 1: return (memory::cartram.read(addr) >> 4) & 15;
|
||||
}
|
||||
} else {
|
||||
//2bpp
|
||||
unsigned shift = addr & 3;
|
||||
addr = (addr >> 2) & (memory::cartram.size() - 1);
|
||||
switch(shift) {
|
||||
case 0: return (memory::cartram.read(addr) >> 0) & 3;
|
||||
case 1: return (memory::cartram.read(addr) >> 2) & 3;
|
||||
case 2: return (memory::cartram.read(addr) >> 4) & 3;
|
||||
case 3: return (memory::cartram.read(addr) >> 6) & 3;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SA1BitmapRAM::write(unsigned addr, uint8_t data) {
|
||||
if(sa1.mmio.bbf == 0) {
|
||||
//4bpp
|
||||
uint8_t shift = addr & 1;
|
||||
addr = (addr >> 1) & (memory::cartram.size() - 1);
|
||||
switch(shift) {
|
||||
case 0: data = (memory::cartram.read(addr) & 0xf0) | ((data & 15) << 0); break;
|
||||
case 1: data = (memory::cartram.read(addr) & 0x0f) | ((data & 15) << 4); break;
|
||||
}
|
||||
} else {
|
||||
//2bpp
|
||||
uint8_t shift = addr & 3;
|
||||
addr = (addr >> 2) & (memory::cartram.size() - 1);
|
||||
switch(shift) {
|
||||
case 0: data = (memory::cartram.read(addr) & 0xfc) | ((data & 3) << 0); break;
|
||||
case 1: data = (memory::cartram.read(addr) & 0xf3) | ((data & 3) << 2); break;
|
||||
case 2: data = (memory::cartram.read(addr) & 0xcf) | ((data & 3) << 4); break;
|
||||
case 3: data = (memory::cartram.read(addr) & 0x3f) | ((data & 3) << 6); break;
|
||||
}
|
||||
}
|
||||
|
||||
memory::cartram.write(addr, data);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,49 @@
|
|||
class SA1Bus : public Bus {
|
||||
public:
|
||||
void init();
|
||||
};
|
||||
|
||||
struct CPUIRAM : Memory {
|
||||
unsigned size() const;
|
||||
uint8_t read(unsigned);
|
||||
void write(unsigned, uint8_t);
|
||||
};
|
||||
|
||||
struct CPUBWRAM : Memory {
|
||||
bool cc1dma;
|
||||
|
||||
unsigned size() const;
|
||||
uint8_t read(unsigned);
|
||||
void write(unsigned, uint8_t);
|
||||
};
|
||||
|
||||
struct SA1IRAM : Memory {
|
||||
unsigned size() const;
|
||||
uint8_t read(unsigned);
|
||||
void write(unsigned, uint8_t);
|
||||
};
|
||||
|
||||
struct SA1BWRAM : Memory {
|
||||
unsigned size() const;
|
||||
uint8_t read(unsigned);
|
||||
void write(unsigned, uint8_t);
|
||||
};
|
||||
|
||||
struct SA1BitmapRAM : Memory {
|
||||
unsigned size() const;
|
||||
uint8_t read(unsigned);
|
||||
void write(unsigned, uint8_t);
|
||||
};
|
||||
|
||||
namespace memory {
|
||||
namespace cpu {
|
||||
extern CPUIRAM iram;
|
||||
extern CPUBWRAM bwram;
|
||||
}
|
||||
|
||||
namespace sa1 {
|
||||
extern SA1IRAM iram;
|
||||
extern SA1BWRAM bwram;
|
||||
extern SA1BitmapRAM bitmapram;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,145 @@
|
|||
#ifdef SA1_CPP
|
||||
|
||||
//====================
|
||||
//direct data transfer
|
||||
//====================
|
||||
|
||||
void SA1::dma_normal() {
|
||||
while(mmio.dtc--) {
|
||||
uint8_t data = regs.mdr;
|
||||
uint32_t dsa = mmio.dsa++;
|
||||
uint32_t dda = mmio.dda++;
|
||||
add_clocks(4);
|
||||
scheduler.sync_copcpu();
|
||||
|
||||
if(mmio.sd == DMA::SourceBWRAM && mmio.dd == DMA::DestBWRAM) continue;
|
||||
if(mmio.sd == DMA::SourceIRAM && mmio.dd == DMA::DestIRAM ) continue;
|
||||
|
||||
switch(mmio.sd) {
|
||||
case DMA::SourceROM: {
|
||||
if((dsa & 0x408000) == 0x008000 || (dsa & 0xc00000) == 0xc00000) {
|
||||
data = sa1bus.read(dsa);
|
||||
}
|
||||
} break;
|
||||
|
||||
case DMA::SourceBWRAM: {
|
||||
if((dsa & 0x40e000) == 0x006000 || (dsa & 0xf00000) == 0x400000) {
|
||||
data = sa1bus.read(dsa);
|
||||
}
|
||||
} break;
|
||||
|
||||
case DMA::SourceIRAM: {
|
||||
data = iram[dsa & 0x07ff];
|
||||
} break;
|
||||
}
|
||||
|
||||
switch(mmio.dd) {
|
||||
case DMA::DestBWRAM: {
|
||||
if((dda & 0x40e000) == 0x006000 || (dda & 0xf00000) == 0x400000) {
|
||||
sa1bus.write(dda, data);
|
||||
}
|
||||
} break;
|
||||
|
||||
case DMA::DestIRAM: {
|
||||
iram[dda & 0x07ff] = data;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
dma.mode = DMA::Inactive;
|
||||
mmio.dma_irqfl = true;
|
||||
if(mmio.dma_irqen) mmio.dma_irqcl = 0;
|
||||
}
|
||||
|
||||
//===========================
|
||||
//type-1 character conversion
|
||||
//===========================
|
||||
|
||||
void SA1::dma_cc1() {
|
||||
memory::cpu::bwram.cc1dma = true;
|
||||
|
||||
dma.tile = 0;
|
||||
dma.mode = DMA::Inactive;
|
||||
mmio.chdma_irqfl = true;
|
||||
if(mmio.chdma_irqen) {
|
||||
mmio.chdma_irqcl = 0;
|
||||
cpu.regs.irq = 1;
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t SA1::dma_cc1_read(unsigned addr) {
|
||||
//16 bytes/char (2bpp); 32 bytes/char (4bpp); 64 bytes/char (8bpp)
|
||||
unsigned charmask = (1 << (6 - mmio.dmacb)) - 1;
|
||||
|
||||
if((addr & charmask) == 0) {
|
||||
//buffer next character to I-RAM
|
||||
unsigned bpp = 2 << (2 - mmio.dmacb);
|
||||
unsigned bpl = (8 << mmio.dmasize) >> mmio.dmacb;
|
||||
unsigned bwmask = memory::sa1::bwram.size() - 1;
|
||||
unsigned tile = ((addr - mmio.dsa) & bwmask) >> (6 - mmio.dmacb);
|
||||
unsigned ty = (tile >> mmio.dmasize);
|
||||
unsigned tx = tile & ((1 << mmio.dmasize) - 1);
|
||||
unsigned bwaddr = mmio.dsa + ty * 8 * bpl + tx * bpp;
|
||||
|
||||
for(unsigned y = 0; y < 8; y++) {
|
||||
uint64_t data = 0;
|
||||
for(unsigned n = 0; n < bpp; n++) {
|
||||
data |= (uint64_t)memory::sa1::bwram.read((bwaddr + n) & bwmask) << (n << 3);
|
||||
}
|
||||
bwaddr += bpl;
|
||||
|
||||
uint8_t out[] = { 0, 0, 0, 0, 0, 0, 0, 0 };
|
||||
for(unsigned x = 0; x < 8; x++) {
|
||||
out[0] |= (data & 1) << (7 - x); data >>= 1;
|
||||
out[1] |= (data & 1) << (7 - x); data >>= 1;
|
||||
if(mmio.dmacb == 2) continue;
|
||||
out[2] |= (data & 1) << (7 - x); data >>= 1;
|
||||
out[3] |= (data & 1) << (7 - x); data >>= 1;
|
||||
if(mmio.dmacb == 1) continue;
|
||||
out[4] |= (data & 1) << (7 - x); data >>= 1;
|
||||
out[5] |= (data & 1) << (7 - x); data >>= 1;
|
||||
out[6] |= (data & 1) << (7 - x); data >>= 1;
|
||||
out[7] |= (data & 1) << (7 - x); data >>= 1;
|
||||
}
|
||||
|
||||
for(unsigned n = 0; n < bpp; n++) {
|
||||
static const unsigned index[] = { 0, 1, 16, 17, 32, 33, 48, 49 };
|
||||
unsigned p = mmio.dda + (y << 1) + index[n];
|
||||
iram[p & 0x07ff] = out[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return iram[(mmio.dda + (addr & charmask)) & 0x07ff];
|
||||
}
|
||||
|
||||
//===========================
|
||||
//type-2 character conversion
|
||||
//===========================
|
||||
|
||||
void SA1::dma_cc2() {
|
||||
//select register file index (0-7 or 8-F)
|
||||
const uint8_t *brf = &mmio.brf[(dma.line & 1) << 3];
|
||||
unsigned bpp = 2 << (2 - mmio.dmacb);
|
||||
unsigned addr = mmio.dda & 0x07ff;
|
||||
addr &= ~((1 << (7 - mmio.dmacb)) - 1);
|
||||
addr += (dma.line & 8) * bpp;
|
||||
addr += (dma.line & 7) * 2;
|
||||
|
||||
for(unsigned byte = 0; byte < bpp; byte++) {
|
||||
uint8_t output = 0;
|
||||
for(unsigned bit = 0; bit < 8; bit++) {
|
||||
output |= ((brf[bit] >> byte) & 1) << (7 - bit);
|
||||
}
|
||||
|
||||
static const unsigned index[] = { 0, 1, 16, 17, 32, 33, 48, 49 };
|
||||
iram[addr + index[byte]] = output;
|
||||
add_clocks(4);
|
||||
scheduler.sync_copcpu();
|
||||
}
|
||||
|
||||
dma.mode = DMA::Inactive;
|
||||
dma.line = (dma.line + 1) & 15;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,15 @@
|
|||
struct DMA {
|
||||
enum CDEN { DmaNormal = 0, DmaCharConversion = 1 };
|
||||
enum SD { SourceROM = 0, SourceBWRAM = 1, SourceIRAM = 2 };
|
||||
enum DD { DestIRAM = 0, DestBWRAM = 1 };
|
||||
|
||||
enum Mode { Inactive, Normal, CC1, CC2 } mode;
|
||||
unsigned clocks;
|
||||
bool tile;
|
||||
unsigned line;
|
||||
} dma;
|
||||
|
||||
void dma_normal();
|
||||
void dma_cc1();
|
||||
uint8_t dma_cc1_read(unsigned addr);
|
||||
void dma_cc2();
|
|
@ -0,0 +1,59 @@
|
|||
#ifdef SA1_CPP
|
||||
|
||||
//==========================
|
||||
//SA-1 opcode core functions
|
||||
//==========================
|
||||
|
||||
void SA1::op_io() {
|
||||
add_clocks(2);
|
||||
if(regs.wai) scheduler.sync_copcpu();
|
||||
cycle_edge();
|
||||
}
|
||||
|
||||
uint8_t SA1::op_read(unsigned addr) {
|
||||
add_clocks(bus_speed(addr));
|
||||
scheduler.sync_copcpu();
|
||||
regs.mdr = sa1bus.read(addr);
|
||||
cycle_edge();
|
||||
return regs.mdr;
|
||||
}
|
||||
|
||||
void SA1::op_write(unsigned addr, uint8_t data) {
|
||||
add_clocks(bus_speed(addr));
|
||||
scheduler.sync_copcpu();
|
||||
sa1bus.write(addr, regs.mdr = data);
|
||||
cycle_edge();
|
||||
}
|
||||
|
||||
void SA1::cycle_edge() {
|
||||
switch(dma.mode) {
|
||||
case DMA::Normal: dma_normal(); break;
|
||||
case DMA::CC1: dma_cc1(); break;
|
||||
case DMA::CC2: dma_cc2(); break;
|
||||
}
|
||||
}
|
||||
|
||||
//$[00-3f:80-bf]:[8000-ffff]
|
||||
//$[c0-ff] :[0000-ffff]
|
||||
#define ROM(n) ( \
|
||||
((n & 0x408000) == 0x008000) \
|
||||
|| ((n & 0xc00000) == 0xc00000) \
|
||||
)
|
||||
|
||||
//$[00-3f|80-bf]:[0000-07ff]
|
||||
//$[00-3f|80-bf]:[3000-37ff]
|
||||
#define IRAM(n) ( \
|
||||
((n & 0x40f800) == 0x000000) \
|
||||
|| ((n & 0x40f800) == 0x003000) \
|
||||
)
|
||||
|
||||
unsigned SA1::bus_speed(unsigned addr) {
|
||||
if(IRAM(addr)) return 2;
|
||||
if(ROM(addr)) return (ROM(cpu.regs.bus) ? 4 : 2);
|
||||
return 4; //MMIO, BW-RAM
|
||||
}
|
||||
|
||||
#undef ROM
|
||||
#undef IRAM
|
||||
|
||||
#endif
|
|
@ -0,0 +1,5 @@
|
|||
void op_io();
|
||||
uint8_t op_read(unsigned addr);
|
||||
void op_write(unsigned addr, uint8_t data);
|
||||
void cycle_edge();
|
||||
unsigned bus_speed(unsigned addr);
|
|
@ -0,0 +1,591 @@
|
|||
#ifdef SA1_CPP
|
||||
|
||||
//(CCNT) SA-1 control
|
||||
void SA1::mmio_w2200(uint8_t data) {
|
||||
if(mmio.sa1_resb && !(data & 0x80)) {
|
||||
//reset SA-1 CPU
|
||||
regs.pc.w = mmio.crv;
|
||||
regs.pc.b = 0x00;
|
||||
}
|
||||
|
||||
mmio.sa1_irq = (data & 0x80);
|
||||
mmio.sa1_rdyb = (data & 0x40);
|
||||
mmio.sa1_resb = (data & 0x20);
|
||||
mmio.sa1_nmi = (data & 0x10);
|
||||
mmio.smeg = (data & 0x0f);
|
||||
|
||||
if(mmio.sa1_irq) {
|
||||
mmio.sa1_irqfl = true;
|
||||
if(mmio.sa1_irqen) mmio.sa1_irqcl = 0;
|
||||
}
|
||||
|
||||
if(mmio.sa1_nmi) {
|
||||
mmio.sa1_nmifl = true;
|
||||
if(mmio.sa1_nmien) mmio.sa1_nmicl = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//(SIE) S-CPU interrupt enable
|
||||
void SA1::mmio_w2201(uint8_t data) {
|
||||
if(!mmio.cpu_irqen && (data & 0x80)) {
|
||||
if(mmio.cpu_irqfl) {
|
||||
mmio.cpu_irqcl = 0;
|
||||
cpu.regs.irq = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(!mmio.chdma_irqen && (data & 0x20)) {
|
||||
if(mmio.chdma_irqfl) {
|
||||
mmio.chdma_irqcl = 0;
|
||||
cpu.regs.irq = 1;
|
||||
}
|
||||
}
|
||||
|
||||
mmio.cpu_irqen = (data & 0x80);
|
||||
mmio.chdma_irqen = (data & 0x20);
|
||||
}
|
||||
|
||||
//(SIC) S-CPU interrupt clear
|
||||
void SA1::mmio_w2202(uint8_t data) {
|
||||
mmio.cpu_irqcl = (data & 0x80);
|
||||
mmio.chdma_irqcl = (data & 0x20);
|
||||
|
||||
if(mmio.cpu_irqcl ) mmio.cpu_irqfl = false;
|
||||
if(mmio.chdma_irqcl) mmio.chdma_irqfl = false;
|
||||
|
||||
if(!mmio.cpu_irqfl && !mmio.chdma_irqfl) cpu.regs.irq = 0;
|
||||
}
|
||||
|
||||
//(CRV) SA-1 reset vector
|
||||
void SA1::mmio_w2203(uint8_t data) { mmio.crv = (mmio.crv & 0xff00) | data; }
|
||||
void SA1::mmio_w2204(uint8_t data) { mmio.crv = (data << 8) | (mmio.crv & 0xff); }
|
||||
|
||||
//(CNV) SA-1 NMI vector
|
||||
void SA1::mmio_w2205(uint8_t data) { mmio.cnv = (mmio.cnv & 0xff00) | data; }
|
||||
void SA1::mmio_w2206(uint8_t data) { mmio.cnv = (data << 8) | (mmio.cnv & 0xff); }
|
||||
|
||||
//(CIV) SA-1 IRQ vector
|
||||
void SA1::mmio_w2207(uint8_t data) { mmio.civ = (mmio.civ & 0xff00) | data; }
|
||||
void SA1::mmio_w2208(uint8_t data) { mmio.civ = (data << 8) | (mmio.civ & 0xff); }
|
||||
|
||||
//(SCNT) S-CPU control
|
||||
void SA1::mmio_w2209(uint8_t data) {
|
||||
mmio.cpu_irq = (data & 0x80);
|
||||
mmio.cpu_ivsw = (data & 0x40);
|
||||
mmio.cpu_nvsw = (data & 0x10);
|
||||
mmio.cmeg = (data & 0x0f);
|
||||
|
||||
if(mmio.cpu_irq) {
|
||||
mmio.cpu_irqfl = true;
|
||||
if(mmio.cpu_irqen) {
|
||||
mmio.cpu_irqcl = 0;
|
||||
cpu.regs.irq = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//(CIE) SA-1 interrupt enable
|
||||
void SA1::mmio_w220a(uint8_t data) {
|
||||
if(!mmio.sa1_irqen && (data & 0x80)) {
|
||||
if(mmio.sa1_irqfl) mmio.sa1_irqcl = 0;
|
||||
}
|
||||
|
||||
if(!mmio.dma_irqen && (data & 0x20)) {
|
||||
if(mmio.dma_irqfl) mmio.dma_irqcl = 0;
|
||||
}
|
||||
|
||||
if(!mmio.sa1_nmien && (data & 0x10)) {
|
||||
if(mmio.sa1_nmifl) mmio.sa1_nmicl = 0;
|
||||
}
|
||||
|
||||
mmio.sa1_irqen = (data & 0x80);
|
||||
mmio.timer_irqen = (data & 0x40);
|
||||
mmio.dma_irqen = (data & 0x20);
|
||||
mmio.sa1_nmien = (data & 0x10);
|
||||
}
|
||||
|
||||
//(CIC) SA-1 interrupt clear
|
||||
void SA1::mmio_w220b(uint8_t data) {
|
||||
mmio.sa1_irqcl = (data & 0x80);
|
||||
mmio.timer_irqcl = (data & 0x40);
|
||||
mmio.dma_irqcl = (data & 0x20);
|
||||
mmio.sa1_nmicl = (data & 0x10);
|
||||
|
||||
if(mmio.sa1_irqcl) mmio.sa1_irqfl = false;
|
||||
if(mmio.dma_irqcl) mmio.dma_irqfl = false;
|
||||
if(mmio.sa1_nmicl) mmio.sa1_nmifl = false;
|
||||
}
|
||||
|
||||
//(SNV) S-CPU NMI vector
|
||||
void SA1::mmio_w220c(uint8_t data) { mmio.snv = (mmio.snv & 0xff00) | data; }
|
||||
void SA1::mmio_w220d(uint8_t data) { mmio.snv = (data << 8) | (mmio.snv & 0xff); }
|
||||
|
||||
//(SIV) S-CPU IRQ vector
|
||||
void SA1::mmio_w220e(uint8_t data) { mmio.siv = (mmio.siv & 0xff00) | data; }
|
||||
void SA1::mmio_w220f(uint8_t data) { mmio.siv = (data << 8) | (mmio.siv & 0xff); }
|
||||
|
||||
//(TMC) H/V timer control
|
||||
void SA1::mmio_w2210(uint8_t data) {
|
||||
mmio.hvselb = (data & 0x80);
|
||||
mmio.ven = (data & 0x02);
|
||||
mmio.hen = (data & 0x01);
|
||||
}
|
||||
|
||||
//(CTR) SA-1 timer restart
|
||||
void SA1::mmio_w2211(uint8_t data) {
|
||||
status.vcounter = 0;
|
||||
status.hcounter = 0;
|
||||
}
|
||||
|
||||
//(HCNT) H-count
|
||||
void SA1::mmio_w2212(uint8_t data) { mmio.hcnt = (mmio.hcnt & 0xff00) | (data << 0); }
|
||||
void SA1::mmio_w2213(uint8_t data) { mmio.hcnt = (mmio.hcnt & 0x00ff) | (data << 8); }
|
||||
|
||||
//(VCNT) V-count
|
||||
void SA1::mmio_w2214(uint8_t data) { mmio.vcnt = (mmio.vcnt & 0xff00) | (data << 0); }
|
||||
void SA1::mmio_w2215(uint8_t data) { mmio.vcnt = (mmio.vcnt & 0x00ff) | (data << 8); }
|
||||
|
||||
//(CXB) Super MMC bank C
|
||||
void SA1::mmio_w2220(uint8_t data) {
|
||||
mmio.cbmode = (data & 0x80);
|
||||
mmio.cb = (data & 0x07);
|
||||
|
||||
bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, memory::cartrom, (mmio.cbmode == 0) ? 0x000000 : (mmio.cb << 20));
|
||||
sa1bus.map(Bus::MapLinear, 0x00, 0x1f, 0x8000, 0xffff, memory::cartrom, (mmio.cbmode == 0) ? 0x000000 : (mmio.cb << 20));
|
||||
bus.map(Bus::MapLinear, 0xc0, 0xcf, 0x0000, 0xffff, memory::cartrom, mmio.cb << 20);
|
||||
sa1bus.map(Bus::MapLinear, 0xc0, 0xcf, 0x0000, 0xffff, memory::cartrom, mmio.cb << 20);
|
||||
}
|
||||
|
||||
//(DXB) Super MMC bank D
|
||||
void SA1::mmio_w2221(uint8_t data) {
|
||||
mmio.dbmode = (data & 0x80);
|
||||
mmio.db = (data & 0x07);
|
||||
|
||||
bus.map(Bus::MapLinear, 0x20, 0x3f, 0x8000, 0xffff, memory::cartrom, (mmio.dbmode == 0) ? 0x100000 : (mmio.db << 20));
|
||||
sa1bus.map(Bus::MapLinear, 0x20, 0x3f, 0x8000, 0xffff, memory::cartrom, (mmio.dbmode == 0) ? 0x100000 : (mmio.db << 20));
|
||||
bus.map(Bus::MapLinear, 0xd0, 0xdf, 0x0000, 0xffff, memory::cartrom, mmio.db << 20);
|
||||
sa1bus.map(Bus::MapLinear, 0xd0, 0xdf, 0x0000, 0xffff, memory::cartrom, mmio.db << 20);
|
||||
}
|
||||
|
||||
//(EXB) Super MMC bank E
|
||||
void SA1::mmio_w2222(uint8_t data) {
|
||||
mmio.ebmode = (data & 0x80);
|
||||
mmio.eb = (data & 0x07);
|
||||
|
||||
bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom, (mmio.ebmode == 0) ? 0x200000 : (mmio.eb << 20));
|
||||
sa1bus.map(Bus::MapLinear, 0x80, 0x9f, 0x8000, 0xffff, memory::cartrom, (mmio.ebmode == 0) ? 0x200000 : (mmio.eb << 20));
|
||||
bus.map(Bus::MapLinear, 0xe0, 0xef, 0x0000, 0xffff, memory::cartrom, mmio.eb << 20);
|
||||
sa1bus.map(Bus::MapLinear, 0xe0, 0xef, 0x0000, 0xffff, memory::cartrom, mmio.eb << 20);
|
||||
}
|
||||
|
||||
//(FXB) Super MMC bank F
|
||||
void SA1::mmio_w2223(uint8_t data) {
|
||||
mmio.fbmode = (data & 0x80);
|
||||
mmio.fb = (data & 0x07);
|
||||
|
||||
bus.map(Bus::MapLinear, 0xa0, 0xbf, 0x8000, 0xffff, memory::cartrom, (mmio.fbmode == 0) ? 0x300000 : (mmio.fb << 20));
|
||||
sa1bus.map(Bus::MapLinear, 0xa0, 0xbf, 0x8000, 0xffff, memory::cartrom, (mmio.fbmode == 0) ? 0x300000 : (mmio.fb << 20));
|
||||
bus.map(Bus::MapLinear, 0xf0, 0xff, 0x0000, 0xffff, memory::cartrom, mmio.fb << 20);
|
||||
sa1bus.map(Bus::MapLinear, 0xf0, 0xff, 0x0000, 0xffff, memory::cartrom, mmio.fb << 20);
|
||||
}
|
||||
|
||||
//(BMAPS) S-CPU BW-RAM address mapping
|
||||
void SA1::mmio_w2224(uint8_t data) {
|
||||
mmio.sbm = (data & 0x1f);
|
||||
|
||||
bus.map(Bus::MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::cpu::bwram, mmio.sbm * 0x2000, 0x2000);
|
||||
bus.map(Bus::MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::cpu::bwram, mmio.sbm * 0x2000, 0x2000);
|
||||
}
|
||||
|
||||
//(BMAP) SA-1 BW-RAM address mapping
|
||||
void SA1::mmio_w2225(uint8_t data) {
|
||||
mmio.sw46 = (data & 0x80);
|
||||
mmio.cbm = (data & 0x7f);
|
||||
|
||||
if(mmio.sw46 == 0) {
|
||||
//$[40-43]:[0000-ffff] x 32 projection
|
||||
sa1bus.map(Bus::MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::sa1::bwram, (mmio.cbm & 0x1f) * 0x2000, 0x2000);
|
||||
sa1bus.map(Bus::MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::sa1::bwram, (mmio.cbm & 0x1f) * 0x2000, 0x2000);
|
||||
} else {
|
||||
//$[60-6f]:[0000-ffff] x 128 projection
|
||||
sa1bus.map(Bus::MapLinear, 0x00, 0x3f, 0x6000, 0x7fff, memory::sa1::bitmapram, mmio.cbm * 0x2000, 0x2000);
|
||||
sa1bus.map(Bus::MapLinear, 0x80, 0xbf, 0x6000, 0x7fff, memory::sa1::bitmapram, mmio.cbm * 0x2000, 0x2000);
|
||||
}
|
||||
}
|
||||
|
||||
//(SWBE) S-CPU BW-RAM write enable
|
||||
void SA1::mmio_w2226(uint8_t data) {
|
||||
mmio.swen = (data & 0x80);
|
||||
}
|
||||
|
||||
//(CWBE) SA-1 BW-RAM write enable
|
||||
void SA1::mmio_w2227(uint8_t data) {
|
||||
mmio.cwen = (data & 0x80);
|
||||
}
|
||||
|
||||
//(BWPA) BW-RAM write-protected area
|
||||
void SA1::mmio_w2228(uint8_t data) {
|
||||
mmio.bwp = (data & 0x0f);
|
||||
}
|
||||
|
||||
//(SIWP) S-CPU I-RAM write protection
|
||||
void SA1::mmio_w2229(uint8_t data) {
|
||||
mmio.siwp = data;
|
||||
}
|
||||
|
||||
//(CIWP) SA-1 I-RAM write protection
|
||||
void SA1::mmio_w222a(uint8_t data) {
|
||||
mmio.ciwp = data;
|
||||
}
|
||||
|
||||
//(DCNT) DMA control
|
||||
void SA1::mmio_w2230(uint8_t data) {
|
||||
mmio.dmaen = (data & 0x80);
|
||||
mmio.dprio = (data & 0x40);
|
||||
mmio.cden = (data & 0x20);
|
||||
mmio.cdsel = (data & 0x10);
|
||||
mmio.dd = (data & 0x04);
|
||||
mmio.sd = (data & 0x03);
|
||||
|
||||
if(mmio.dmaen == 0) dma.line = 0;
|
||||
}
|
||||
|
||||
//(CDMA) character conversion DMA parameters
|
||||
void SA1::mmio_w2231(uint8_t data) {
|
||||
mmio.chdend = (data & 0x80);
|
||||
mmio.dmasize = (data >> 2) & 7;
|
||||
mmio.dmacb = (data & 0x03);
|
||||
|
||||
if(mmio.chdend) memory::cpu::bwram.cc1dma = false;
|
||||
if(mmio.dmasize > 5) mmio.dmasize = 5;
|
||||
if(mmio.dmacb > 2) mmio.dmacb = 2;
|
||||
}
|
||||
|
||||
//(SDA) DMA source device start address
|
||||
void SA1::mmio_w2232(uint8_t data) { mmio.dsa = (mmio.dsa & 0xffff00) | (data << 0); }
|
||||
void SA1::mmio_w2233(uint8_t data) { mmio.dsa = (mmio.dsa & 0xff00ff) | (data << 8); }
|
||||
void SA1::mmio_w2234(uint8_t data) { mmio.dsa = (mmio.dsa & 0x00ffff) | (data << 16); }
|
||||
|
||||
//(DDA) DMA destination start address
|
||||
void SA1::mmio_w2235(uint8_t data) {
|
||||
mmio.dda = (mmio.dda & 0xffff00) | (data << 0);
|
||||
}
|
||||
|
||||
void SA1::mmio_w2236(uint8_t data) {
|
||||
mmio.dda = (mmio.dda & 0xff00ff) | (data << 8);
|
||||
|
||||
if(dma.mode == DMA::Inactive) {
|
||||
if(mmio.cden == 0 && mmio.dd == DMA::DestIRAM) {
|
||||
dma.mode = DMA::Normal;
|
||||
} else if(mmio.cden == 1 && mmio.cdsel == 1) {
|
||||
dma.mode = DMA::CC1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SA1::mmio_w2237(uint8_t data) {
|
||||
mmio.dda = (mmio.dda & 0x00ffff) | (data << 16);
|
||||
|
||||
if(dma.mode == DMA::Inactive) {
|
||||
if(mmio.cden == 0 && mmio.dd == DMA::DestBWRAM) {
|
||||
dma.mode = DMA::Normal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//(DTC) DMA terminal counter
|
||||
void SA1::mmio_w2238(uint8_t data) { mmio.dtc = (mmio.dtc & 0xff00) | (data << 0); }
|
||||
void SA1::mmio_w2239(uint8_t data) { mmio.dtc = (mmio.dtc & 0x00ff) | (data << 8); }
|
||||
|
||||
//(BBF) BW-RAM bitmap format
|
||||
void SA1::mmio_w223f(uint8_t data) {
|
||||
mmio.bbf = (data & 0x80);
|
||||
}
|
||||
|
||||
//(BRF) bitmap register files
|
||||
void SA1::mmio_w2240(uint8_t data) { mmio.brf[ 0] = data; }
|
||||
void SA1::mmio_w2241(uint8_t data) { mmio.brf[ 1] = data; }
|
||||
void SA1::mmio_w2242(uint8_t data) { mmio.brf[ 2] = data; }
|
||||
void SA1::mmio_w2243(uint8_t data) { mmio.brf[ 3] = data; }
|
||||
void SA1::mmio_w2244(uint8_t data) { mmio.brf[ 4] = data; }
|
||||
void SA1::mmio_w2245(uint8_t data) { mmio.brf[ 5] = data; }
|
||||
void SA1::mmio_w2246(uint8_t data) { mmio.brf[ 6] = data; }
|
||||
void SA1::mmio_w2247(uint8_t data) { mmio.brf[ 7] = data;
|
||||
if(dma.mode == DMA::Inactive) {
|
||||
if(mmio.cden == 1 && mmio.cdsel == 0) {
|
||||
dma.mode = DMA::CC2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SA1::mmio_w2248(uint8_t data) { mmio.brf[ 8] = data; }
|
||||
void SA1::mmio_w2249(uint8_t data) { mmio.brf[ 9] = data; }
|
||||
void SA1::mmio_w224a(uint8_t data) { mmio.brf[10] = data; }
|
||||
void SA1::mmio_w224b(uint8_t data) { mmio.brf[11] = data; }
|
||||
void SA1::mmio_w224c(uint8_t data) { mmio.brf[12] = data; }
|
||||
void SA1::mmio_w224d(uint8_t data) { mmio.brf[13] = data; }
|
||||
void SA1::mmio_w224e(uint8_t data) { mmio.brf[14] = data; }
|
||||
void SA1::mmio_w224f(uint8_t data) { mmio.brf[15] = data;
|
||||
if(dma.mode == DMA::Inactive) {
|
||||
if(mmio.cden == 1 && mmio.cdsel == 0) {
|
||||
dma.mode = DMA::CC2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//(MCNT) arithmetic control
|
||||
void SA1::mmio_w2250(uint8_t data) {
|
||||
mmio.acm = (data & 0x02);
|
||||
mmio.md = (data & 0x01);
|
||||
|
||||
if(mmio.acm) mmio.mr = 0;
|
||||
}
|
||||
|
||||
//(MAL) multiplicand / dividend low
|
||||
void SA1::mmio_w2251(uint8_t data) {
|
||||
mmio.ma = (mmio.ma & 0xff00) | data;
|
||||
}
|
||||
|
||||
//(MAH) multiplicand / dividend high
|
||||
void SA1::mmio_w2252(uint8_t data) {
|
||||
mmio.ma = (data << 8) | (mmio.ma & 0x00ff);
|
||||
}
|
||||
|
||||
//(MBL) multiplier / divisor low
|
||||
void SA1::mmio_w2253(uint8_t data) {
|
||||
mmio.mb = (mmio.mb & 0xff00) | data;
|
||||
}
|
||||
|
||||
//(MBH) multiplier / divisor high
|
||||
//multiplication / cumulative sum only resets MB
|
||||
//division resets both MA and MB
|
||||
void SA1::mmio_w2254(uint8_t data) {
|
||||
mmio.mb = (data << 8) | (mmio.mb & 0x00ff);
|
||||
|
||||
if(mmio.acm == 0) {
|
||||
if(mmio.md == 0) {
|
||||
//signed multiplication
|
||||
mmio.mr = (int16_t)mmio.ma * (int16_t)mmio.mb;
|
||||
mmio.mb = 0;
|
||||
} else {
|
||||
//unsigned division
|
||||
if(mmio.mb == 0) {
|
||||
mmio.mr = 0;
|
||||
} else {
|
||||
int16_t quotient = (int16_t)mmio.ma / (uint16_t)mmio.mb;
|
||||
uint16_t remainder = (int16_t)mmio.ma % (uint16_t)mmio.mb;
|
||||
mmio.mr = (remainder << 16) | quotient;
|
||||
}
|
||||
mmio.ma = 0;
|
||||
mmio.mb = 0;
|
||||
}
|
||||
} else {
|
||||
//sigma (accumulative multiplication)
|
||||
mmio.mr += (int16_t)mmio.ma * (int16_t)mmio.mb;
|
||||
mmio.overflow = (mmio.mr >= (1ULL << 40));
|
||||
mmio.mr &= (1ULL << 40) - 1;
|
||||
mmio.ma = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//(VBD) variable-length bit processing
|
||||
void SA1::mmio_w2258(uint8_t data) {
|
||||
mmio.hl = (data & 0x80);
|
||||
mmio.vb = (data & 0x0f);
|
||||
if(mmio.vb == 0) mmio.vb = 16;
|
||||
|
||||
if(mmio.hl == 0) {
|
||||
//fixed mode
|
||||
mmio.vbit += mmio.vb;
|
||||
mmio.va += (mmio.vbit >> 3);
|
||||
mmio.vbit &= 7;
|
||||
}
|
||||
}
|
||||
|
||||
//(VDA) variable-length bit game pak ROM start address
|
||||
void SA1::mmio_w2259(uint8_t data) { mmio.va = (mmio.va & 0xffff00) | (data << 0); }
|
||||
void SA1::mmio_w225a(uint8_t data) { mmio.va = (mmio.va & 0xff00ff) | (data << 8); }
|
||||
void SA1::mmio_w225b(uint8_t data) { mmio.va = (mmio.va & 0x00ffff) | (data << 16); mmio.vbit = 0; }
|
||||
|
||||
//(SFR) S-CPU flag read
|
||||
uint8_t SA1::mmio_r2300() {
|
||||
uint8_t data;
|
||||
data = mmio.cpu_irqfl << 7;
|
||||
data |= mmio.cpu_ivsw << 6;
|
||||
data |= mmio.chdma_irqfl << 5;
|
||||
data |= mmio.cpu_nvsw << 4;
|
||||
data |= mmio.cmeg;
|
||||
return data;
|
||||
}
|
||||
|
||||
//(CFR) SA-1 flag read
|
||||
uint8_t SA1::mmio_r2301() {
|
||||
uint8_t data;
|
||||
data = mmio.sa1_irqfl << 7;
|
||||
data |= mmio.timer_irqfl << 6;
|
||||
data |= mmio.dma_irqfl << 5;
|
||||
data |= mmio.sa1_nmifl << 4;
|
||||
data |= mmio.smeg;
|
||||
return data;
|
||||
}
|
||||
|
||||
//(HCR) hcounter read
|
||||
uint8_t SA1::mmio_r2302() {
|
||||
//latch counters
|
||||
mmio.hcr = status.hcounter >> 2;
|
||||
mmio.vcr = status.vcounter;
|
||||
return mmio.hcr >> 0; }
|
||||
uint8_t SA1::mmio_r2303() { return mmio.hcr >> 8; }
|
||||
|
||||
//(VCR) vcounter read
|
||||
uint8_t SA1::mmio_r2304() { return mmio.vcr >> 0; }
|
||||
uint8_t SA1::mmio_r2305() { return mmio.vcr >> 8; }
|
||||
|
||||
//(MR) arithmetic result
|
||||
uint8_t SA1::mmio_r2306() { return mmio.mr >> 0; }
|
||||
uint8_t SA1::mmio_r2307() { return mmio.mr >> 8; }
|
||||
uint8_t SA1::mmio_r2308() { return mmio.mr >> 16; }
|
||||
uint8_t SA1::mmio_r2309() { return mmio.mr >> 24; }
|
||||
uint8_t SA1::mmio_r230a() { return mmio.mr >> 32; }
|
||||
|
||||
//(OF) arithmetic overflow flag
|
||||
uint8_t SA1::mmio_r230b() { return mmio.overflow << 7; }
|
||||
|
||||
//(VDPL) variable-length data read port low
|
||||
uint8_t SA1::mmio_r230c() {
|
||||
uint32_t data = (sa1bus.read(mmio.va + 0) << 0)
|
||||
| (sa1bus.read(mmio.va + 1) << 8)
|
||||
| (sa1bus.read(mmio.va + 2) << 16);
|
||||
data >>= mmio.vbit;
|
||||
return data >> 0;
|
||||
}
|
||||
|
||||
//(VDPH) variable-length data read port high
|
||||
uint8_t SA1::mmio_r230d() {
|
||||
uint32_t data = (sa1bus.read(mmio.va + 0) << 0)
|
||||
| (sa1bus.read(mmio.va + 1) << 8)
|
||||
| (sa1bus.read(mmio.va + 2) << 16);
|
||||
data >>= mmio.vbit;
|
||||
|
||||
if(mmio.hl == 1) {
|
||||
//auto-increment mode
|
||||
mmio.vbit += mmio.vb;
|
||||
mmio.va += (mmio.vbit >> 3);
|
||||
mmio.vbit &= 7;
|
||||
}
|
||||
|
||||
return data >> 8;
|
||||
}
|
||||
|
||||
//(VC) version code register
|
||||
uint8_t SA1::mmio_r230e() {
|
||||
return 0x01; //true value unknown
|
||||
}
|
||||
|
||||
uint8_t SA1::mmio_read(unsigned addr) {
|
||||
addr &= 0xffff;
|
||||
|
||||
switch(addr) {
|
||||
case 0x2300: return mmio_r2300();
|
||||
case 0x2301: return mmio_r2301();
|
||||
case 0x2302: return mmio_r2302();
|
||||
case 0x2303: return mmio_r2303();
|
||||
case 0x2304: return mmio_r2304();
|
||||
case 0x2305: return mmio_r2305();
|
||||
case 0x2306: return mmio_r2306();
|
||||
case 0x2307: return mmio_r2307();
|
||||
case 0x2308: return mmio_r2308();
|
||||
case 0x2309: return mmio_r2309();
|
||||
case 0x230a: return mmio_r230a();
|
||||
case 0x230b: return mmio_r230b();
|
||||
case 0x230c: return mmio_r230c();
|
||||
case 0x230d: return mmio_r230d();
|
||||
case 0x230e: return mmio_r230e();
|
||||
}
|
||||
|
||||
return 0x00;
|
||||
}
|
||||
|
||||
void SA1::mmio_write(unsigned addr, uint8_t data) {
|
||||
addr &= 0xffff;
|
||||
|
||||
switch(addr) {
|
||||
case 0x2200: return mmio_w2200(data);
|
||||
case 0x2201: return mmio_w2201(data);
|
||||
case 0x2202: return mmio_w2202(data);
|
||||
case 0x2203: return mmio_w2203(data);
|
||||
case 0x2204: return mmio_w2204(data);
|
||||
case 0x2205: return mmio_w2205(data);
|
||||
case 0x2206: return mmio_w2206(data);
|
||||
case 0x2207: return mmio_w2207(data);
|
||||
case 0x2208: return mmio_w2208(data);
|
||||
case 0x2209: return mmio_w2209(data);
|
||||
case 0x220a: return mmio_w220a(data);
|
||||
case 0x220b: return mmio_w220b(data);
|
||||
case 0x220c: return mmio_w220c(data);
|
||||
case 0x220d: return mmio_w220d(data);
|
||||
case 0x220e: return mmio_w220e(data);
|
||||
case 0x220f: return mmio_w220f(data);
|
||||
|
||||
case 0x2210: return mmio_w2210(data);
|
||||
case 0x2211: return mmio_w2211(data);
|
||||
case 0x2212: return mmio_w2212(data);
|
||||
case 0x2213: return mmio_w2213(data);
|
||||
case 0x2214: return mmio_w2214(data);
|
||||
case 0x2215: return mmio_w2215(data);
|
||||
|
||||
case 0x2220: return mmio_w2220(data);
|
||||
case 0x2221: return mmio_w2221(data);
|
||||
case 0x2222: return mmio_w2222(data);
|
||||
case 0x2223: return mmio_w2223(data);
|
||||
case 0x2224: return mmio_w2224(data);
|
||||
case 0x2225: return mmio_w2225(data);
|
||||
case 0x2226: return mmio_w2226(data);
|
||||
case 0x2227: return mmio_w2227(data);
|
||||
case 0x2228: return mmio_w2228(data);
|
||||
case 0x2229: return mmio_w2229(data);
|
||||
case 0x222a: return mmio_w222a(data);
|
||||
|
||||
case 0x2230: return mmio_w2230(data);
|
||||
case 0x2231: return mmio_w2231(data);
|
||||
case 0x2232: return mmio_w2232(data);
|
||||
case 0x2233: return mmio_w2233(data);
|
||||
case 0x2234: return mmio_w2234(data);
|
||||
case 0x2235: return mmio_w2235(data);
|
||||
case 0x2236: return mmio_w2236(data);
|
||||
case 0x2237: return mmio_w2237(data);
|
||||
case 0x2238: return mmio_w2238(data);
|
||||
case 0x2239: return mmio_w2239(data);
|
||||
|
||||
case 0x223f: return mmio_w223f(data);
|
||||
case 0x2240: return mmio_w2240(data);
|
||||
case 0x2241: return mmio_w2241(data);
|
||||
case 0x2242: return mmio_w2242(data);
|
||||
case 0x2243: return mmio_w2243(data);
|
||||
case 0x2244: return mmio_w2244(data);
|
||||
case 0x2245: return mmio_w2245(data);
|
||||
case 0x2246: return mmio_w2246(data);
|
||||
case 0x2247: return mmio_w2247(data);
|
||||
case 0x2248: return mmio_w2248(data);
|
||||
case 0x2249: return mmio_w2249(data);
|
||||
case 0x224a: return mmio_w224a(data);
|
||||
case 0x224b: return mmio_w224b(data);
|
||||
case 0x224c: return mmio_w224c(data);
|
||||
case 0x224d: return mmio_w224d(data);
|
||||
case 0x224e: return mmio_w224e(data);
|
||||
case 0x224f: return mmio_w224f(data);
|
||||
|
||||
case 0x2250: return mmio_w2250(data);
|
||||
case 0x2251: return mmio_w2251(data);
|
||||
case 0x2252: return mmio_w2252(data);
|
||||
case 0x2253: return mmio_w2253(data);
|
||||
case 0x2254: return mmio_w2254(data);
|
||||
|
||||
case 0x2258: return mmio_w2258(data);
|
||||
case 0x2259: return mmio_w2259(data);
|
||||
case 0x225a: return mmio_w225a(data);
|
||||
case 0x225b: return mmio_w225b(data);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -0,0 +1,255 @@
|
|||
uint8_t mmio_read(unsigned addr);
|
||||
void mmio_write(unsigned addr, uint8_t data);
|
||||
|
||||
struct MMIO {
|
||||
//$2200 CCNT
|
||||
bool sa1_irq;
|
||||
bool sa1_rdyb;
|
||||
bool sa1_resb;
|
||||
bool sa1_nmi;
|
||||
uint8_t smeg;
|
||||
|
||||
//$2201 SIE
|
||||
bool cpu_irqen;
|
||||
bool chdma_irqen;
|
||||
|
||||
//$2202 SIC
|
||||
bool cpu_irqcl;
|
||||
bool chdma_irqcl;
|
||||
|
||||
//$2203,$2204 CRV
|
||||
uint16_t crv;
|
||||
|
||||
//$2205,$2206 CNV
|
||||
uint16_t cnv;
|
||||
|
||||
//$2207,$2208 CIV
|
||||
uint16_t civ;
|
||||
|
||||
//$2209 SCNT
|
||||
bool cpu_irq;
|
||||
bool cpu_ivsw;
|
||||
bool cpu_nvsw;
|
||||
uint8_t cmeg;
|
||||
|
||||
//$220a CIE
|
||||
bool sa1_irqen;
|
||||
bool timer_irqen;
|
||||
bool dma_irqen;
|
||||
bool sa1_nmien;
|
||||
|
||||
//$220b CIC
|
||||
bool sa1_irqcl;
|
||||
bool timer_irqcl;
|
||||
bool dma_irqcl;
|
||||
bool sa1_nmicl;
|
||||
|
||||
//$220c,$220d SNV
|
||||
uint16_t snv;
|
||||
|
||||
//$220e,$220f SIV
|
||||
uint16_t siv;
|
||||
|
||||
//$2210 TMC
|
||||
bool hvselb;
|
||||
bool ven;
|
||||
bool hen;
|
||||
|
||||
//$2212,$2213
|
||||
uint16_t hcnt;
|
||||
|
||||
//$2214,$2215
|
||||
uint16_t vcnt;
|
||||
|
||||
//$2220 CXB
|
||||
bool cbmode;
|
||||
uint8_t cb;
|
||||
|
||||
//$2221 DXB
|
||||
bool dbmode;
|
||||
uint8_t db;
|
||||
|
||||
//$2222 EXB
|
||||
bool ebmode;
|
||||
uint8_t eb;
|
||||
|
||||
//$2223 FXB
|
||||
bool fbmode;
|
||||
uint8_t fb;
|
||||
|
||||
//$2224 BMAPS
|
||||
uint8_t sbm;
|
||||
|
||||
//$2225 BMAP
|
||||
bool sw46;
|
||||
uint8_t cbm;
|
||||
|
||||
//$2226 SBWE
|
||||
bool swen;
|
||||
|
||||
//$2227 CBWE
|
||||
bool cwen;
|
||||
|
||||
//$2228 BWPA
|
||||
uint8_t bwp;
|
||||
|
||||
//$2229 SIWP
|
||||
uint8_t siwp;
|
||||
|
||||
//$222a CIWP
|
||||
uint8_t ciwp;
|
||||
|
||||
//$2230 DCNT
|
||||
bool dmaen;
|
||||
bool dprio;
|
||||
bool cden;
|
||||
bool cdsel;
|
||||
bool dd;
|
||||
uint8_t sd;
|
||||
|
||||
//$2231 CDMA
|
||||
bool chdend;
|
||||
uint8_t dmasize;
|
||||
uint8_t dmacb;
|
||||
|
||||
//$2232-$2234 SDA
|
||||
uint32_t dsa;
|
||||
|
||||
//$2235-$2237 DDA
|
||||
uint32_t dda;
|
||||
|
||||
//$2238,$2239 DTC
|
||||
uint16_t dtc;
|
||||
|
||||
//$223f BBF
|
||||
bool bbf;
|
||||
|
||||
//$2240-224f BRF
|
||||
uint8_t brf[16];
|
||||
|
||||
//$2250 MCNT
|
||||
bool acm;
|
||||
bool md;
|
||||
|
||||
//$2251,$2252 MA
|
||||
uint16_t ma;
|
||||
|
||||
//$2253,$2254 MB
|
||||
uint16_t mb;
|
||||
|
||||
//$2258 VBD
|
||||
bool hl;
|
||||
uint8_t vb;
|
||||
|
||||
//$2259-$225b VDA
|
||||
uint32_t va;
|
||||
uint8_t vbit;
|
||||
|
||||
//$2300 SFR
|
||||
bool cpu_irqfl;
|
||||
bool chdma_irqfl;
|
||||
|
||||
//$2301 CFR
|
||||
bool sa1_irqfl;
|
||||
bool timer_irqfl;
|
||||
bool dma_irqfl;
|
||||
bool sa1_nmifl;
|
||||
|
||||
//$2302,$2303 HCR
|
||||
uint16_t hcr;
|
||||
|
||||
//$2304,$2305 VCR
|
||||
uint16_t vcr;
|
||||
|
||||
//$2306-230a MR
|
||||
uint64_t mr;
|
||||
|
||||
//$230b OF
|
||||
bool overflow;
|
||||
} mmio;
|
||||
|
||||
void mmio_w2200(uint8_t); //CCNT
|
||||
void mmio_w2201(uint8_t); //SIE
|
||||
void mmio_w2202(uint8_t); //SIC
|
||||
void mmio_w2203(uint8_t); //CRVL
|
||||
void mmio_w2204(uint8_t); //CRVH
|
||||
void mmio_w2205(uint8_t); //CNVL
|
||||
void mmio_w2206(uint8_t); //CNVH
|
||||
void mmio_w2207(uint8_t); //CIVL
|
||||
void mmio_w2208(uint8_t); //CIVH
|
||||
void mmio_w2209(uint8_t); //SCNT
|
||||
void mmio_w220a(uint8_t); //CIE
|
||||
void mmio_w220b(uint8_t); //CIC
|
||||
void mmio_w220c(uint8_t); //SNVL
|
||||
void mmio_w220d(uint8_t); //SNVH
|
||||
void mmio_w220e(uint8_t); //SIVL
|
||||
void mmio_w220f(uint8_t); //SIVH
|
||||
void mmio_w2210(uint8_t); //TMC
|
||||
void mmio_w2211(uint8_t); //CTR
|
||||
void mmio_w2212(uint8_t); //HCNTL
|
||||
void mmio_w2213(uint8_t); //HCNTH
|
||||
void mmio_w2214(uint8_t); //VCNTL
|
||||
void mmio_w2215(uint8_t); //VCNTH
|
||||
void mmio_w2220(uint8_t); //CXB
|
||||
void mmio_w2221(uint8_t); //DXB
|
||||
void mmio_w2222(uint8_t); //EXB
|
||||
void mmio_w2223(uint8_t); //FXB
|
||||
void mmio_w2224(uint8_t); //BMAPS
|
||||
void mmio_w2225(uint8_t); //BMAP
|
||||
void mmio_w2226(uint8_t); //SBWE
|
||||
void mmio_w2227(uint8_t); //CBWE
|
||||
void mmio_w2228(uint8_t); //BWPA
|
||||
void mmio_w2229(uint8_t); //SIWP
|
||||
void mmio_w222a(uint8_t); //CIWP
|
||||
void mmio_w2230(uint8_t); //DCNT
|
||||
void mmio_w2231(uint8_t); //CDMA
|
||||
void mmio_w2232(uint8_t); //SDAL
|
||||
void mmio_w2233(uint8_t); //SDAH
|
||||
void mmio_w2234(uint8_t); //SDAB
|
||||
void mmio_w2235(uint8_t); //DDAL
|
||||
void mmio_w2236(uint8_t); //DDAH
|
||||
void mmio_w2237(uint8_t); //DDAB
|
||||
void mmio_w2238(uint8_t); //DTCL
|
||||
void mmio_w2239(uint8_t); //DTCH
|
||||
void mmio_w223f(uint8_t); //BBF
|
||||
void mmio_w2240(uint8_t); //BRF0
|
||||
void mmio_w2241(uint8_t); //BRF1
|
||||
void mmio_w2242(uint8_t); //BRF2
|
||||
void mmio_w2243(uint8_t); //BRF3
|
||||
void mmio_w2244(uint8_t); //BRF4
|
||||
void mmio_w2245(uint8_t); //BRF5
|
||||
void mmio_w2246(uint8_t); //BRF6
|
||||
void mmio_w2247(uint8_t); //BRF7
|
||||
void mmio_w2248(uint8_t); //BRF8
|
||||
void mmio_w2249(uint8_t); //BRF9
|
||||
void mmio_w224a(uint8_t); //BRFA
|
||||
void mmio_w224b(uint8_t); //BRFB
|
||||
void mmio_w224c(uint8_t); //BRFC
|
||||
void mmio_w224d(uint8_t); //BRFD
|
||||
void mmio_w224e(uint8_t); //BRFE
|
||||
void mmio_w224f(uint8_t); //BRFF
|
||||
void mmio_w2250(uint8_t); //MCNT
|
||||
void mmio_w2251(uint8_t); //MAL
|
||||
void mmio_w2252(uint8_t); //MAH
|
||||
void mmio_w2253(uint8_t); //MBL
|
||||
void mmio_w2254(uint8_t); //MBH
|
||||
void mmio_w2258(uint8_t); //VBD
|
||||
void mmio_w2259(uint8_t); //VDAL
|
||||
void mmio_w225a(uint8_t); //VDAH
|
||||
void mmio_w225b(uint8_t); //VDAB
|
||||
|
||||
uint8_t mmio_r2300(); //SFR
|
||||
uint8_t mmio_r2301(); //CFR
|
||||
uint8_t mmio_r2302(); //HCRL
|
||||
uint8_t mmio_r2303(); //HCRH
|
||||
uint8_t mmio_r2304(); //VCRL
|
||||
uint8_t mmio_r2305(); //VCRH
|
||||
uint8_t mmio_r2306(); //MR [00-07]
|
||||
uint8_t mmio_r2307(); //MR [08-15]
|
||||
uint8_t mmio_r2308(); //MR [16-23]
|
||||
uint8_t mmio_r2309(); //MR [24-31]
|
||||
uint8_t mmio_r230a(); //MR [32-40]
|
||||
uint8_t mmio_r230b(); //OF
|
||||
uint8_t mmio_r230c(); //VDPL
|
||||
uint8_t mmio_r230d(); //VDPH
|
||||
uint8_t mmio_r230e(); //VC
|
|
@ -0,0 +1,341 @@
|
|||
#include <../base.hpp>
|
||||
#include <../cart/cart.hpp>
|
||||
#define SA1_CPP
|
||||
|
||||
#include "sa1.hpp"
|
||||
#include "bus/bus.cpp"
|
||||
#include "dma/dma.cpp"
|
||||
#include "memory/memory.cpp"
|
||||
#include "mmio/mmio.cpp"
|
||||
|
||||
void SA1::enter() {
|
||||
while(true) {
|
||||
while(mmio.sa1_rdyb || mmio.sa1_resb) {
|
||||
//SA-1 co-processor is asleep
|
||||
add_clocks(4);
|
||||
scheduler.sync_copcpu();
|
||||
}
|
||||
|
||||
#if 0
|
||||
static FILE *fp = fopen("/home/byuu/Desktop/sa1log.txt", "wb");
|
||||
char t[1024];
|
||||
disassemble_opcode(t);
|
||||
fprintf(fp, "%s\n", t);
|
||||
#endif
|
||||
|
||||
if(status.interrupt_pending) {
|
||||
status.interrupt_pending = false;
|
||||
interrupt(status.interrupt_vector);
|
||||
}
|
||||
|
||||
(this->*opcode_table[op_readpc()])();
|
||||
}
|
||||
}
|
||||
|
||||
void SA1::last_cycle() {
|
||||
if(mmio.sa1_nmi && !mmio.sa1_nmicl) {
|
||||
status.interrupt_pending = true;
|
||||
status.interrupt_vector = mmio.cnv;
|
||||
mmio.sa1_nmifl = true;
|
||||
mmio.sa1_nmicl = 1;
|
||||
regs.wai = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(mmio.timer_irqen && !mmio.timer_irqcl) {
|
||||
status.interrupt_pending = true;
|
||||
status.interrupt_vector = mmio.civ;
|
||||
mmio.timer_irqfl = true;
|
||||
mmio.timer_irqcl = 1;
|
||||
regs.wai = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(mmio.dma_irqen && !mmio.dma_irqcl) {
|
||||
status.interrupt_pending = true;
|
||||
status.interrupt_vector = mmio.civ;
|
||||
mmio.dma_irqfl = true;
|
||||
mmio.dma_irqcl = 1;
|
||||
regs.wai = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if(!regs.p.i && mmio.sa1_irq && !mmio.sa1_irqcl) {
|
||||
status.interrupt_pending = true;
|
||||
status.interrupt_vector = mmio.civ;
|
||||
mmio.sa1_irqfl = true;
|
||||
regs.wai = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void SA1::interrupt(uint16_t vector) {
|
||||
op_read(regs.pc.d);
|
||||
op_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);
|
||||
add_clocks(8);
|
||||
regs.pc.w = vector;
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
}
|
||||
|
||||
bool SA1::interrupt_pending() {
|
||||
return status.interrupt_pending;
|
||||
}
|
||||
|
||||
void SA1::add_clocks(unsigned clocks) {
|
||||
scheduler.addclocks_cop(clocks);
|
||||
|
||||
uint16_t last_hcounter = status.hcounter;
|
||||
uint16_t last_vcounter = status.vcounter;
|
||||
|
||||
//adjust counters:
|
||||
//note that internally, status counters are in clocks;
|
||||
//whereas MMIO register counters are in dots (4 clocks = 1 dot)
|
||||
if(mmio.hvselb == 0) {
|
||||
//HV timer
|
||||
status.hcounter += clocks;
|
||||
if(status.hcounter >= 1364) {
|
||||
status.hcounter -= 1364;
|
||||
status.vcounter++;
|
||||
if(status.vcounter >= status.scanlines) {
|
||||
status.vcounter = 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//linear timer
|
||||
status.hcounter += clocks;
|
||||
status.vcounter += (status.hcounter >> 11);
|
||||
status.hcounter &= 0x07ff;
|
||||
status.vcounter &= 0x01ff;
|
||||
}
|
||||
|
||||
//test counters for timer IRQ
|
||||
uint32_t lo = (last_vcounter << 11) + last_hcounter;
|
||||
uint32_t hi = (status.vcounter << 11) + status.hcounter;
|
||||
uint32_t trigger = (mmio.vcnt << 11) + (mmio.hcnt << 2);
|
||||
|
||||
if(lo > hi) {
|
||||
if(trigger <= hi) goto trigger_irq;
|
||||
hi += 1 << 20;
|
||||
}
|
||||
|
||||
if(lo < trigger && trigger <= hi) goto trigger_irq;
|
||||
return;
|
||||
|
||||
trigger_irq:
|
||||
mmio.timer_irqfl = true;
|
||||
if(mmio.timer_irqen) mmio.timer_irqcl = 0;
|
||||
}
|
||||
|
||||
void SA1::init() {
|
||||
}
|
||||
|
||||
void SA1::enable() {
|
||||
}
|
||||
|
||||
void SA1::power() {
|
||||
regs.a = regs.x = regs.y = 0x0000;
|
||||
regs.s = 0x01ff;
|
||||
|
||||
reset();
|
||||
}
|
||||
|
||||
void SA1::reset() {
|
||||
sa1bus.init();
|
||||
|
||||
regs.pc.d = 0x000000;
|
||||
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;
|
||||
regs.wai = false;
|
||||
update_table();
|
||||
|
||||
memset(iram, 0, sizeof iram);
|
||||
|
||||
status.interrupt_pending = false;
|
||||
status.interrupt_vector = 0x0000;
|
||||
|
||||
status.scanlines = (snes.region() == SNES::NTSC ? 261 : 311);
|
||||
status.vcounter = 0;
|
||||
status.hcounter = 0;
|
||||
|
||||
dma.mode = DMA::Inactive;
|
||||
dma.clocks = 4;
|
||||
dma.tile = 0;
|
||||
dma.line = 0;
|
||||
|
||||
//$2200 CCNT
|
||||
mmio.sa1_irq = false;
|
||||
mmio.sa1_rdyb = false;
|
||||
mmio.sa1_resb = true;
|
||||
mmio.sa1_nmi = false;
|
||||
mmio.smeg = 0;
|
||||
|
||||
//$2201 SIE
|
||||
mmio.cpu_irqen = false;
|
||||
mmio.chdma_irqen = false;
|
||||
|
||||
//$2202 SIC
|
||||
mmio.cpu_irqcl = false;
|
||||
mmio.chdma_irqcl = false;
|
||||
|
||||
//$2203,$2204 CRV
|
||||
mmio.crv = 0x0000;
|
||||
|
||||
//$2205,$2206 CNV
|
||||
mmio.cnv = 0x0000;
|
||||
|
||||
//$2207,$2208 CIV
|
||||
mmio.civ = 0x0000;
|
||||
|
||||
//$2209 SCNT
|
||||
mmio.cpu_irq = false;
|
||||
mmio.cpu_ivsw = false;
|
||||
mmio.cpu_nvsw = false;
|
||||
mmio.cmeg = 0;
|
||||
|
||||
//$220a CIE
|
||||
mmio.sa1_irqen = false;
|
||||
mmio.timer_irqen = false;
|
||||
mmio.dma_irqen = false;
|
||||
mmio.sa1_nmien = false;
|
||||
|
||||
//$220b CIC
|
||||
mmio.sa1_irqcl = false;
|
||||
mmio.timer_irqcl = false;
|
||||
mmio.dma_irqcl = false;
|
||||
mmio.sa1_nmicl = false;
|
||||
|
||||
//$220c,$220d SNV
|
||||
mmio.snv = 0x0000;
|
||||
|
||||
//$220e,$220f SIV
|
||||
mmio.siv = 0x0000;
|
||||
|
||||
//$2210
|
||||
mmio.hvselb = false;
|
||||
mmio.ven = false;
|
||||
mmio.hen = false;
|
||||
|
||||
//$2212,$2213 HCNT
|
||||
mmio.hcnt = 0x0000;
|
||||
|
||||
//$2214,$2215 VCNT
|
||||
mmio.vcnt = 0x0000;
|
||||
|
||||
//$2220-2223 CXB, DXB, EXB, FXB
|
||||
mmio.cbmode = 0;
|
||||
mmio.dbmode = 0;
|
||||
mmio.ebmode = 0;
|
||||
mmio.fbmode = 0;
|
||||
|
||||
mmio.cb = 0x00;
|
||||
mmio.db = 0x01;
|
||||
mmio.eb = 0x02;
|
||||
mmio.fb = 0x03;
|
||||
|
||||
//$2224 BMAPS
|
||||
mmio.sbm = 0x00;
|
||||
|
||||
//$2225 BMAP
|
||||
mmio.sw46 = false;
|
||||
mmio.cbm = 0x00;
|
||||
|
||||
//$2226 SWBE
|
||||
mmio.swen = false;
|
||||
|
||||
//$2227 CWBE
|
||||
mmio.cwen = false;
|
||||
|
||||
//$2228 BWPA
|
||||
mmio.bwp = 0x0f;
|
||||
|
||||
//$2229 SIWP
|
||||
mmio.siwp = 0x00;
|
||||
|
||||
//$222a CIWP
|
||||
mmio.ciwp = 0x00;
|
||||
|
||||
//$2230 DCNT
|
||||
mmio.dmaen = false;
|
||||
mmio.dprio = false;
|
||||
mmio.cden = false;
|
||||
mmio.cdsel = false;
|
||||
mmio.dd = 0;
|
||||
mmio.sd = 0;
|
||||
|
||||
//$2231 CDMA
|
||||
mmio.chdend = false;
|
||||
mmio.dmasize = 0;
|
||||
mmio.dmacb = 0;
|
||||
|
||||
//$2232-$2234 SDA
|
||||
mmio.dsa = 0x000000;
|
||||
|
||||
//$2235-$2237 DDA
|
||||
mmio.dda = 0x000000;
|
||||
|
||||
//$2238,$2239 DTC
|
||||
mmio.dtc = 0x0000;
|
||||
|
||||
//$223f BBF
|
||||
mmio.bbf = 0;
|
||||
|
||||
//$2240-$224f BRF
|
||||
for(unsigned i = 0; i < 16; i++) {
|
||||
mmio.brf[i] = 0x00;
|
||||
}
|
||||
|
||||
//$2250 MCNT
|
||||
mmio.acm = 0;
|
||||
mmio.md = 0;
|
||||
|
||||
//$2251,$2252 MA
|
||||
mmio.ma = 0x0000;
|
||||
|
||||
//$2253,$2254 MB
|
||||
mmio.mb = 0x0000;
|
||||
|
||||
//$2258 VBD
|
||||
mmio.hl = false;
|
||||
mmio.vb = 16;
|
||||
|
||||
//$2259-$225b
|
||||
mmio.va = 0x000000;
|
||||
mmio.vbit = 0;
|
||||
|
||||
//$2300 SFR
|
||||
mmio.cpu_irqfl = false;
|
||||
mmio.chdma_irqfl = false;
|
||||
|
||||
//$2301 CFR
|
||||
mmio.sa1_irqfl = false;
|
||||
mmio.timer_irqfl = false;
|
||||
mmio.dma_irqfl = false;
|
||||
mmio.sa1_nmifl = false;
|
||||
|
||||
//$2302,$2303 HCR
|
||||
mmio.hcr = 0x0000;
|
||||
|
||||
//$2304,$2305 VCR
|
||||
mmio.vcr = 0x0000;
|
||||
|
||||
//$2306-$230a MR
|
||||
mmio.mr = 0;
|
||||
|
||||
//$230b
|
||||
mmio.overflow = false;
|
||||
}
|
||||
|
||||
SA1::SA1() {
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#include "bus/bus.hpp"
|
||||
|
||||
class SA1 : public CPUcore, public MMIO {
|
||||
public:
|
||||
#include "dma/dma.hpp"
|
||||
#include "memory/memory.hpp"
|
||||
#include "mmio/mmio.hpp"
|
||||
uint8_t iram[2048];
|
||||
|
||||
struct Status {
|
||||
bool interrupt_pending;
|
||||
uint16_t interrupt_vector;
|
||||
|
||||
uint16_t scanlines;
|
||||
uint16_t vcounter;
|
||||
uint16_t hcounter;
|
||||
} status;
|
||||
|
||||
void enter();
|
||||
void interrupt(uint16_t vector);
|
||||
void add_clocks(unsigned);
|
||||
|
||||
void last_cycle();
|
||||
bool interrupt_pending();
|
||||
|
||||
void init();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
SA1();
|
||||
};
|
||||
|
||||
extern SA1 sa1;
|
||||
extern SA1Bus sa1bus;
|
|
@ -0,0 +1,3 @@
|
|||
clear
|
||||
bpp opcode_functions.cpp opcode_functions.bpp
|
||||
bpp opcode_headers.hpp opcode_headers.bpp
|
|
@ -0,0 +1,45 @@
|
|||
#include <../base.hpp>
|
||||
|
||||
#include "opcode_algorithms.cpp"
|
||||
#include "opcode_functions.cpp"
|
||||
#include "opcode_tables.cpp"
|
||||
#include "disasm/disasm.cpp"
|
||||
|
||||
//immediate, 2-cycle opcodes with I/O cycle will become bus read
|
||||
//when an IRQ is to be triggered immediately after opcode completion.
|
||||
//this affects the following opcodes:
|
||||
// clc, cld, cli, clv, sec, sed, sei,
|
||||
// tax, tay, txa, txy, tya, tyx,
|
||||
// tcd, tcs, tdc, tsc, tsx, txs,
|
||||
// inc, inx, iny, dec, dex, dey,
|
||||
// asl, lsr, rol, ror, nop, xce.
|
||||
alwaysinline void CPUcore::op_io_irq() {
|
||||
if(interrupt_pending()) {
|
||||
//modify I/O cycle to bus read cycle, do not increment PC
|
||||
op_read(regs.pc.d);
|
||||
} else {
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void CPUcore::op_io_cond2() {
|
||||
if(regs.d.l != 0x00) {
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void CPUcore::op_io_cond4(uint16 x, uint16 y) {
|
||||
if(!regs.p.x || (x & 0xff00) != (y & 0xff00)) {
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void CPUcore::op_io_cond6(uint16 addr) {
|
||||
if(regs.e && (regs.pc.w & 0xff00) != (addr & 0xff00)) {
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
CPUcore::CPUcore() {
|
||||
initialize_opcode_table();
|
||||
}
|
|
@ -1,54 +1,79 @@
|
|||
reg24_t aa, rd;
|
||||
uint8_t dp, sp;
|
||||
|
||||
void op_irq();
|
||||
|
||||
inline bool in_opcode() { return status.in_opcode; }
|
||||
|
||||
//op_read
|
||||
void op_adc_b();
|
||||
void op_adc_w();
|
||||
void op_and_b();
|
||||
void op_and_w();
|
||||
void op_bit_b();
|
||||
void op_bit_w();
|
||||
void op_cmp_b();
|
||||
void op_cmp_w();
|
||||
void op_cpx_b();
|
||||
void op_cpx_w();
|
||||
void op_cpy_b();
|
||||
void op_cpy_w();
|
||||
void op_eor_b();
|
||||
void op_eor_w();
|
||||
void op_lda_b();
|
||||
void op_lda_w();
|
||||
void op_ldx_b();
|
||||
void op_ldx_w();
|
||||
void op_ldy_b();
|
||||
void op_ldy_w();
|
||||
void op_ora_b();
|
||||
void op_ora_w();
|
||||
void op_sbc_b();
|
||||
void op_sbc_w();
|
||||
//op_rmw
|
||||
void op_inc_b();
|
||||
void op_inc_w();
|
||||
void op_dec_b();
|
||||
void op_dec_w();
|
||||
void op_asl_b();
|
||||
void op_asl_w();
|
||||
void op_lsr_b();
|
||||
void op_lsr_w();
|
||||
void op_rol_b();
|
||||
void op_rol_w();
|
||||
void op_ror_b();
|
||||
void op_ror_w();
|
||||
void op_trb_b();
|
||||
void op_trb_w();
|
||||
void op_tsb_b();
|
||||
void op_tsb_w();
|
||||
class CPUcore {
|
||||
public:
|
||||
#include "registers.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "opcode_headers.hpp"
|
||||
#include "disasm/disasm.hpp"
|
||||
|
||||
void op_io_irq();
|
||||
void op_io_cond2();
|
||||
void op_io_cond4(uint16 x, uint16 y);
|
||||
void op_io_cond6(uint16 addr);
|
||||
regs_t regs;
|
||||
reg24_t aa, rd;
|
||||
uint8_t sp, dp;
|
||||
|
||||
virtual void op_io() = 0;
|
||||
virtual uint8_t op_read(uint32_t addr) = 0;
|
||||
virtual void op_write(uint32_t addr, uint8_t data) = 0;
|
||||
virtual void last_cycle() = 0;
|
||||
virtual bool interrupt_pending() = 0;
|
||||
|
||||
void op_io_irq();
|
||||
void op_io_cond2();
|
||||
void op_io_cond4(uint16 x, uint16 y);
|
||||
void op_io_cond6(uint16 addr);
|
||||
|
||||
void op_adc_b();
|
||||
void op_adc_w();
|
||||
void op_and_b();
|
||||
void op_and_w();
|
||||
void op_bit_b();
|
||||
void op_bit_w();
|
||||
void op_cmp_b();
|
||||
void op_cmp_w();
|
||||
void op_cpx_b();
|
||||
void op_cpx_w();
|
||||
void op_cpy_b();
|
||||
void op_cpy_w();
|
||||
void op_eor_b();
|
||||
void op_eor_w();
|
||||
void op_lda_b();
|
||||
void op_lda_w();
|
||||
void op_ldx_b();
|
||||
void op_ldx_w();
|
||||
void op_ldy_b();
|
||||
void op_ldy_w();
|
||||
void op_ora_b();
|
||||
void op_ora_w();
|
||||
void op_sbc_b();
|
||||
void op_sbc_w();
|
||||
|
||||
void op_inc_b();
|
||||
void op_inc_w();
|
||||
void op_dec_b();
|
||||
void op_dec_w();
|
||||
void op_asl_b();
|
||||
void op_asl_w();
|
||||
void op_lsr_b();
|
||||
void op_lsr_w();
|
||||
void op_rol_b();
|
||||
void op_rol_w();
|
||||
void op_ror_b();
|
||||
void op_ror_w();
|
||||
void op_trb_b();
|
||||
void op_trb_w();
|
||||
void op_tsb_b();
|
||||
void op_tsb_w();
|
||||
|
||||
void (CPUcore::**opcode_table)();
|
||||
void (CPUcore::*op_table[256 * 5])();
|
||||
void initialize_opcode_table();
|
||||
void update_table();
|
||||
|
||||
enum {
|
||||
table_EM = 0, // 8-bit accumulator, 8-bit index (emulation mode)
|
||||
table_MX = 256, // 8-bit accumulator, 8-bit index
|
||||
table_Mx = 512, // 8-bit accumulator, 16-bit index
|
||||
table_mX = 768, //16-bit accumulator, 8-bit index
|
||||
table_mx = 1024, //16-bit accumulator, 16-bit index
|
||||
};
|
||||
|
||||
CPUcore();
|
||||
};
|
|
@ -1,483 +1,479 @@
|
|||
#ifdef CPU_CPP
|
||||
uint8 CPUcore::dreadb(uint32 addr) {
|
||||
if((addr & 0x40ffff) >= 0x2000 && (addr & 0x40ffff) <= 0x5fff) {
|
||||
//$[00-3f|80-bf]:[2000-5fff]
|
||||
//do not read MMIO registers within debugger
|
||||
return 0x00;
|
||||
}
|
||||
return bus.read(addr);
|
||||
}
|
||||
|
||||
uint8 CPU::dreadb(uint32 addr) {
|
||||
if((addr & 0x40ffff) >= 0x2000 && (addr & 0x40ffff) <= 0x5fff) {
|
||||
//$[00-3f|80-bf]:[2000-5fff]
|
||||
//do not read MMIO registers within debugger
|
||||
return 0x00;
|
||||
}
|
||||
return bus.read(addr);
|
||||
}
|
||||
|
||||
uint16 CPU::dreadw(uint32 addr) {
|
||||
uint16 r;
|
||||
r = dreadb((addr + 0) & 0xffffff) << 0;
|
||||
r |= dreadb((addr + 1) & 0xffffff) << 8;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32 CPU::dreadl(uint32 addr) {
|
||||
uint32 r;
|
||||
r = dreadb((addr + 0) & 0xffffff) << 0;
|
||||
r |= dreadb((addr + 1) & 0xffffff) << 8;
|
||||
r |= dreadb((addr + 2) & 0xffffff) << 16;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32 CPU::decode(uint8 offset_type, uint32 addr) {
|
||||
uint32 r = 0;
|
||||
|
||||
switch(offset_type) {
|
||||
case OPTYPE_DP:
|
||||
r = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_DPX:
|
||||
r = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_DPY:
|
||||
r = (regs.d + regs.y + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_IDP:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = (regs.db << 16) + dreadw(addr);
|
||||
break;
|
||||
case OPTYPE_IDPX:
|
||||
addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
|
||||
r = (regs.db << 16) + dreadw(addr);
|
||||
break;
|
||||
case OPTYPE_IDPY:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = (regs.db << 16) + dreadw(addr) + regs.y;
|
||||
break;
|
||||
case OPTYPE_ILDP:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = dreadl(addr);
|
||||
break;
|
||||
case OPTYPE_ILDPY:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = dreadl(addr) + regs.y;
|
||||
break;
|
||||
case OPTYPE_ADDR:
|
||||
r = (regs.db << 16) + (addr & 0xffff);
|
||||
break;
|
||||
case OPTYPE_ADDR_PC:
|
||||
r = (regs.pc.b << 16) + (addr & 0xffff);
|
||||
break;
|
||||
case OPTYPE_ADDRX:
|
||||
r = (regs.db << 16) + (addr & 0xffff) + regs.x;
|
||||
break;
|
||||
case OPTYPE_ADDRY:
|
||||
r = (regs.db << 16) + (addr & 0xffff) + regs.y;
|
||||
break;
|
||||
case OPTYPE_IADDR_PC:
|
||||
r = (regs.pc.b << 16) + (addr & 0xffff);
|
||||
break;
|
||||
case OPTYPE_IADDRX:
|
||||
r = (regs.pc.b << 16) + ((addr + regs.x) & 0xffff);
|
||||
break;
|
||||
case OPTYPE_ILADDR:
|
||||
r = addr;
|
||||
break;
|
||||
case OPTYPE_LONG:
|
||||
r = addr;
|
||||
break;
|
||||
case OPTYPE_LONGX:
|
||||
r = (addr + regs.x);
|
||||
break;
|
||||
case OPTYPE_SR:
|
||||
r = (regs.s + (addr & 0xff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_ISRY:
|
||||
addr = (regs.s + (addr & 0xff)) & 0xffff;
|
||||
r = (regs.db << 16) + dreadw(addr) + regs.y;
|
||||
break;
|
||||
case OPTYPE_RELB:
|
||||
r = (regs.pc.b << 16) + ((regs.pc.w + 2) & 0xffff);
|
||||
r += int8(addr);
|
||||
break;
|
||||
case OPTYPE_RELW:
|
||||
r = (regs.pc.b << 16) + ((regs.pc.w + 3) & 0xffff);
|
||||
r += int16(addr);
|
||||
break;
|
||||
}
|
||||
|
||||
return(r & 0xffffff);
|
||||
}
|
||||
|
||||
void CPU::disassemble_opcode(char *output) {
|
||||
static reg24_t pc;
|
||||
char t[256];
|
||||
char *s = output;
|
||||
|
||||
if(in_opcode() == true) {
|
||||
strcpy(s, "?????? <CPU within opcode>");
|
||||
return;
|
||||
}
|
||||
|
||||
pc.d = regs.pc.d;
|
||||
sprintf(s, "%.6x ", (uint32)pc.d);
|
||||
|
||||
uint8 op = dreadb(pc.d); pc.w++;
|
||||
uint8 op0 = dreadb(pc.d); pc.w++;
|
||||
uint8 op1 = dreadb(pc.d); pc.w++;
|
||||
uint8 op2 = dreadb(pc.d);
|
||||
|
||||
#define op8 ((op0))
|
||||
#define op16 ((op0) | (op1 << 8))
|
||||
#define op24 ((op0) | (op1 << 8) | (op2 << 16))
|
||||
#define a8 (regs.e || regs.p.m)
|
||||
#define x8 (regs.e || regs.p.x)
|
||||
|
||||
switch(op) {
|
||||
case 0x00: sprintf(t, "brk #$%.2x ", op8); break;
|
||||
case 0x01: sprintf(t, "ora ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x02: sprintf(t, "cop #$%.2x ", op8); break;
|
||||
case 0x03: sprintf(t, "ora $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x04: sprintf(t, "tsb $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x05: sprintf(t, "ora $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x06: sprintf(t, "asl $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x07: sprintf(t, "ora [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x08: sprintf(t, "php "); break;
|
||||
case 0x09: if(a8)sprintf(t, "ora #$%.2x ", op8);
|
||||
else sprintf(t, "ora #$%.4x ", op16); break;
|
||||
case 0x0a: sprintf(t, "asl a "); break;
|
||||
case 0x0b: sprintf(t, "phd "); break;
|
||||
case 0x0c: sprintf(t, "tsb $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x0d: sprintf(t, "ora $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x0e: sprintf(t, "asl $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x0f: sprintf(t, "ora $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x10: sprintf(t, "bpl $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x11: sprintf(t, "ora ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x12: sprintf(t, "ora ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x13: sprintf(t, "ora ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x14: sprintf(t, "trb $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x15: sprintf(t, "ora $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x16: sprintf(t, "asl $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x17: sprintf(t, "ora [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x18: sprintf(t, "clc "); break;
|
||||
case 0x19: sprintf(t, "ora $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x1a: sprintf(t, "inc "); break;
|
||||
case 0x1b: sprintf(t, "tcs "); break;
|
||||
case 0x1c: sprintf(t, "trb $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x1d: sprintf(t, "ora $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x1e: sprintf(t, "asl $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x1f: sprintf(t, "ora $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x20: sprintf(t, "jsr $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break;
|
||||
case 0x21: sprintf(t, "and ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x22: sprintf(t, "jsl $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x23: sprintf(t, "and $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x24: sprintf(t, "bit $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x25: sprintf(t, "and $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x26: sprintf(t, "rol $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x27: sprintf(t, "and [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x28: sprintf(t, "plp "); break;
|
||||
case 0x29: if(a8)sprintf(t, "and #$%.2x ", op8);
|
||||
else sprintf(t, "and #$%.4x ", op16); break;
|
||||
case 0x2a: sprintf(t, "rol a "); break;
|
||||
case 0x2b: sprintf(t, "pld "); break;
|
||||
case 0x2c: sprintf(t, "bit $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x2d: sprintf(t, "and $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x2e: sprintf(t, "rol $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x2f: sprintf(t, "and $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x30: sprintf(t, "bmi $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x31: sprintf(t, "and ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x32: sprintf(t, "and ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x33: sprintf(t, "and ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x34: sprintf(t, "bit $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x35: sprintf(t, "and $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x36: sprintf(t, "rol $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x37: sprintf(t, "and [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x38: sprintf(t, "sec "); break;
|
||||
case 0x39: sprintf(t, "and $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x3a: sprintf(t, "dec "); break;
|
||||
case 0x3b: sprintf(t, "tsc "); break;
|
||||
case 0x3c: sprintf(t, "bit $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x3d: sprintf(t, "and $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x3e: sprintf(t, "rol $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x3f: sprintf(t, "and $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x40: sprintf(t, "rti "); break;
|
||||
case 0x41: sprintf(t, "eor ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x42: sprintf(t, "wdm "); break;
|
||||
case 0x43: sprintf(t, "eor $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x44: sprintf(t, "mvp $%.2x,$%.2x ", op1, op8); break;
|
||||
case 0x45: sprintf(t, "eor $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x46: sprintf(t, "lsr $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x47: sprintf(t, "eor [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x48: sprintf(t, "pha "); break;
|
||||
case 0x49: if(a8)sprintf(t, "eor #$%.2x ", op8);
|
||||
else sprintf(t, "eor #$%.4x ", op16); break;
|
||||
case 0x4a: sprintf(t, "lsr a "); break;
|
||||
case 0x4b: sprintf(t, "phk "); break;
|
||||
case 0x4c: sprintf(t, "jmp $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break;
|
||||
case 0x4d: sprintf(t, "eor $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x4e: sprintf(t, "lsr $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x4f: sprintf(t, "eor $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x50: sprintf(t, "bvc $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x51: sprintf(t, "eor ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x52: sprintf(t, "eor ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x53: sprintf(t, "eor ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x54: sprintf(t, "mvn $%.2x,$%.2x ", op1, op8); break;
|
||||
case 0x55: sprintf(t, "eor $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x56: sprintf(t, "lsr $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x57: sprintf(t, "eor [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x58: sprintf(t, "cli "); break;
|
||||
case 0x59: sprintf(t, "eor $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x5a: sprintf(t, "phy "); break;
|
||||
case 0x5b: sprintf(t, "tcd "); break;
|
||||
case 0x5c: sprintf(t, "jml $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x5d: sprintf(t, "eor $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x5e: sprintf(t, "lsr $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x5f: sprintf(t, "eor $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x60: sprintf(t, "rts "); break;
|
||||
case 0x61: sprintf(t, "adc ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x62: sprintf(t, "per $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x63: sprintf(t, "adc $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x64: sprintf(t, "stz $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x65: sprintf(t, "adc $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x66: sprintf(t, "ror $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x67: sprintf(t, "adc [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x68: sprintf(t, "pla "); break;
|
||||
case 0x69: if(a8)sprintf(t, "adc #$%.2x ", op8);
|
||||
else sprintf(t, "adc #$%.4x ", op16); break;
|
||||
case 0x6a: sprintf(t, "ror a "); break;
|
||||
case 0x6b: sprintf(t, "rtl "); break;
|
||||
case 0x6c: sprintf(t, "jmp ($%.4x) [$%.6x]", op16, decode(OPTYPE_IADDR_PC, op16)); break;
|
||||
case 0x6d: sprintf(t, "adc $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x6e: sprintf(t, "ror $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x6f: sprintf(t, "adc $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x70: sprintf(t, "bvs $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x71: sprintf(t, "adc ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x72: sprintf(t, "adc ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x73: sprintf(t, "adc ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x74: sprintf(t, "stz $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x75: sprintf(t, "adc $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x76: sprintf(t, "ror $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x77: sprintf(t, "adc [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x78: sprintf(t, "sei "); break;
|
||||
case 0x79: sprintf(t, "adc $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x7a: sprintf(t, "ply "); break;
|
||||
case 0x7b: sprintf(t, "tdc "); break;
|
||||
case 0x7c: sprintf(t, "jmp ($%.4x,x) [$%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break;
|
||||
case 0x7d: sprintf(t, "adc $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x7e: sprintf(t, "ror $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x7f: sprintf(t, "adc $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x80: sprintf(t, "bra $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x81: sprintf(t, "sta ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x82: sprintf(t, "brl $%.4x [$%.6x]", uint16(decode(OPTYPE_RELW, op16)), decode(OPTYPE_RELW, op16)); break;
|
||||
case 0x83: sprintf(t, "sta $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x84: sprintf(t, "sty $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x85: sprintf(t, "sta $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x86: sprintf(t, "stx $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x87: sprintf(t, "sta [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x88: sprintf(t, "dey "); break;
|
||||
case 0x89: if(a8)sprintf(t, "bit #$%.2x ", op8);
|
||||
else sprintf(t, "bit #$%.4x ", op16); break;
|
||||
case 0x8a: sprintf(t, "txa "); break;
|
||||
case 0x8b: sprintf(t, "phb "); break;
|
||||
case 0x8c: sprintf(t, "sty $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x8d: sprintf(t, "sta $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x8e: sprintf(t, "stx $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x8f: sprintf(t, "sta $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x90: sprintf(t, "bcc $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x91: sprintf(t, "sta ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x92: sprintf(t, "sta ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x93: sprintf(t, "sta ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x94: sprintf(t, "sty $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x95: sprintf(t, "sta $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x96: sprintf(t, "stx $%.2x,y [$%.6x]", op8, decode(OPTYPE_DPY, op8)); break;
|
||||
case 0x97: sprintf(t, "sta [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x98: sprintf(t, "tya "); break;
|
||||
case 0x99: sprintf(t, "sta $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x9a: sprintf(t, "txs "); break;
|
||||
case 0x9b: sprintf(t, "txy "); break;
|
||||
case 0x9c: sprintf(t, "stz $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x9d: sprintf(t, "sta $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x9e: sprintf(t, "stz $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x9f: sprintf(t, "sta $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0xa0: if(x8)sprintf(t, "ldy #$%.2x ", op8);
|
||||
else sprintf(t, "ldy #$%.4x ", op16); break;
|
||||
case 0xa1: sprintf(t, "lda ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0xa2: if(x8)sprintf(t, "ldx #$%.2x ", op8);
|
||||
else sprintf(t, "ldx #$%.4x ", op16); break;
|
||||
case 0xa3: sprintf(t, "lda $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0xa4: sprintf(t, "ldy $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xa5: sprintf(t, "lda $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xa6: sprintf(t, "ldx $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xa7: sprintf(t, "lda [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0xa8: sprintf(t, "tay "); break;
|
||||
case 0xa9: if(a8)sprintf(t, "lda #$%.2x ", op8);
|
||||
else sprintf(t, "lda #$%.4x ", op16); break;
|
||||
case 0xaa: sprintf(t, "tax "); break;
|
||||
case 0xab: sprintf(t, "plb "); break;
|
||||
case 0xac: sprintf(t, "ldy $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xad: sprintf(t, "lda $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xae: sprintf(t, "ldx $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xaf: sprintf(t, "lda $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0xb0: sprintf(t, "bcs $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xb1: sprintf(t, "lda ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0xb2: sprintf(t, "lda ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xb3: sprintf(t, "lda ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0xb4: sprintf(t, "ldy $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xb5: sprintf(t, "lda $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xb6: sprintf(t, "ldx $%.2x,y [$%.6x]", op8, decode(OPTYPE_DPY, op8)); break;
|
||||
case 0xb7: sprintf(t, "lda [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0xb8: sprintf(t, "clv "); break;
|
||||
case 0xb9: sprintf(t, "lda $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0xba: sprintf(t, "tsx "); break;
|
||||
case 0xbb: sprintf(t, "tyx "); break;
|
||||
case 0xbc: sprintf(t, "ldy $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xbd: sprintf(t, "lda $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xbe: sprintf(t, "ldx $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0xbf: sprintf(t, "lda $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0xc0: if(x8)sprintf(t, "cpy #$%.2x ", op8);
|
||||
else sprintf(t, "cpy #$%.4x ", op16); break;
|
||||
case 0xc1: sprintf(t, "cmp ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0xc2: sprintf(t, "rep #$%.2x ", op8); break;
|
||||
case 0xc3: sprintf(t, "cmp $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0xc4: sprintf(t, "cpy $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xc5: sprintf(t, "cmp $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xc6: sprintf(t, "dec $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xc7: sprintf(t, "cmp [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0xc8: sprintf(t, "iny "); break;
|
||||
case 0xc9: if(a8)sprintf(t, "cmp #$%.2x ", op8);
|
||||
else sprintf(t, "cmp #$%.4x ", op16); break;
|
||||
case 0xca: sprintf(t, "dex "); break;
|
||||
case 0xcb: sprintf(t, "wai "); break;
|
||||
case 0xcc: sprintf(t, "cpy $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xcd: sprintf(t, "cmp $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xce: sprintf(t, "dec $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xcf: sprintf(t, "cmp $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0xd0: sprintf(t, "bne $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xd1: sprintf(t, "cmp ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0xd2: sprintf(t, "cmp ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xd3: sprintf(t, "cmp ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0xd4: sprintf(t, "pei ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xd5: sprintf(t, "cmp $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xd6: sprintf(t, "dec $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xd7: sprintf(t, "cmp [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0xd8: sprintf(t, "cld "); break;
|
||||
case 0xd9: sprintf(t, "cmp $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0xda: sprintf(t, "phx "); break;
|
||||
case 0xdb: sprintf(t, "stp "); break;
|
||||
case 0xdc: sprintf(t, "jmp [$%.4x] [$%.6x]", op16, decode(OPTYPE_ILADDR, op16)); break;
|
||||
case 0xdd: sprintf(t, "cmp $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xde: sprintf(t, "dec $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xdf: sprintf(t, "cmp $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0xe0: if(x8)sprintf(t, "cpx #$%.2x ", op8);
|
||||
else sprintf(t, "cpx #$%.4x ", op16); break;
|
||||
case 0xe1: sprintf(t, "sbc ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0xe2: sprintf(t, "sep #$%.2x ", op8); break;
|
||||
case 0xe3: sprintf(t, "sbc $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0xe4: sprintf(t, "cpx $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xe5: sprintf(t, "sbc $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xe6: sprintf(t, "inc $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xe7: sprintf(t, "sbc [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0xe8: sprintf(t, "inx "); break;
|
||||
case 0xe9: if(a8)sprintf(t, "sbc #$%.2x ", op8);
|
||||
else sprintf(t, "sbc #$%.4x ", op16); break;
|
||||
case 0xea: sprintf(t, "nop "); break;
|
||||
case 0xeb: sprintf(t, "xba "); break;
|
||||
case 0xec: sprintf(t, "cpx $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xed: sprintf(t, "sbc $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xee: sprintf(t, "inc $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xef: sprintf(t, "sbc $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0xf0: sprintf(t, "beq $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xf1: sprintf(t, "sbc ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0xf2: sprintf(t, "sbc ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xf3: sprintf(t, "sbc ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0xf4: sprintf(t, "pea $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xf5: sprintf(t, "sbc $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xf6: sprintf(t, "inc $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xf7: sprintf(t, "sbc [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0xf8: sprintf(t, "sed "); break;
|
||||
case 0xf9: sprintf(t, "sbc $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0xfa: sprintf(t, "plx "); break;
|
||||
case 0xfb: sprintf(t, "xce "); break;
|
||||
case 0xfc: sprintf(t, "jsr ($%.4x,x) [$%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break;
|
||||
case 0xfd: sprintf(t, "sbc $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xfe: sprintf(t, "inc $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xff: sprintf(t, "sbc $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
}
|
||||
|
||||
#undef op8
|
||||
#undef op16
|
||||
#undef op24
|
||||
#undef a8
|
||||
#undef x8
|
||||
|
||||
strcat(s, t);
|
||||
strcat(s, " ");
|
||||
|
||||
sprintf(t, "A:%.4x X:%.4x Y:%.4x S:%.4x D:%.4x DB:%.2x ",
|
||||
regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d.w, regs.db);
|
||||
strcat(s, t);
|
||||
|
||||
if(regs.e) {
|
||||
sprintf(t, "%c%c%c%c%c%c%c%c",
|
||||
regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v',
|
||||
regs.p.m ? '1' : '0', regs.p.x ? 'B' : 'b',
|
||||
regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i',
|
||||
regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c');
|
||||
} else {
|
||||
sprintf(t, "%c%c%c%c%c%c%c%c",
|
||||
regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v',
|
||||
regs.p.m ? 'M' : 'm', regs.p.x ? 'X' : 'x',
|
||||
regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i',
|
||||
regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c');
|
||||
}
|
||||
|
||||
strcat(s, t);
|
||||
strcat(s, " ");
|
||||
|
||||
sprintf(t, "V:%3d H:%4d", ppu.vcounter(), ppu.hcounter());
|
||||
strcat(s, t);
|
||||
}
|
||||
|
||||
//opcode_length() retrieves the length of the next opcode
|
||||
//to be executed. It is used by the debugger to step over,
|
||||
//disable and proceed cpu opcodes.
|
||||
//
|
||||
//5 and 6 are special cases, 5 is used for #consts based on
|
||||
//the A register size, 6 for the X/Y register size. the
|
||||
//rest are literal sizes. There's no need to test for
|
||||
//emulation mode, as regs.p.m/regs.p.x should *always* be
|
||||
//set in emulation mode.
|
||||
|
||||
uint8 CPU::opcode_length() {
|
||||
uint8 op, len;
|
||||
static uint8 op_len_tbl[256] = {
|
||||
//0,1,2,3, 4,5,6,7, 8,9,a,b, c,d,e,f
|
||||
|
||||
2,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x0n
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x1n
|
||||
3,2,4,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x2n
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x3n
|
||||
|
||||
1,2,2,2, 3,2,2,2, 1,5,1,1, 3,3,3,4, //0x4n
|
||||
2,2,2,2, 3,2,2,2, 1,3,1,1, 4,3,3,4, //0x5n
|
||||
1,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x6n
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x7n
|
||||
|
||||
2,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x8n
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x9n
|
||||
6,2,6,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xan
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xbn
|
||||
|
||||
6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xcn
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xdn
|
||||
6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xen
|
||||
2,2,2,2, 3,2,2,2, 1,3,1,1, 3,3,3,4 //0xfn
|
||||
};
|
||||
|
||||
if(in_opcode() == true) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
op = dreadb(regs.pc.d);
|
||||
len = op_len_tbl[op];
|
||||
if(len == 5) return (regs.e || regs.p.m) ? 2 : 3;
|
||||
if(len == 6) return (regs.e || regs.p.x) ? 2 : 3;
|
||||
return len;
|
||||
}
|
||||
uint16 CPUcore::dreadw(uint32 addr) {
|
||||
uint16 r;
|
||||
r = dreadb((addr + 0) & 0xffffff) << 0;
|
||||
r |= dreadb((addr + 1) & 0xffffff) << 8;
|
||||
return r;
|
||||
}
|
||||
|
||||
#endif //ifdef CPU_CPP
|
||||
uint32 CPUcore::dreadl(uint32 addr) {
|
||||
uint32 r;
|
||||
r = dreadb((addr + 0) & 0xffffff) << 0;
|
||||
r |= dreadb((addr + 1) & 0xffffff) << 8;
|
||||
r |= dreadb((addr + 2) & 0xffffff) << 16;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint32 CPUcore::decode(uint8 offset_type, uint32 addr) {
|
||||
uint32 r = 0;
|
||||
|
||||
switch(offset_type) {
|
||||
case OPTYPE_DP:
|
||||
r = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_DPX:
|
||||
r = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_DPY:
|
||||
r = (regs.d + regs.y + (addr & 0xffff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_IDP:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = (regs.db << 16) + dreadw(addr);
|
||||
break;
|
||||
case OPTYPE_IDPX:
|
||||
addr = (regs.d + regs.x + (addr & 0xffff)) & 0xffff;
|
||||
r = (regs.db << 16) + dreadw(addr);
|
||||
break;
|
||||
case OPTYPE_IDPY:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = (regs.db << 16) + dreadw(addr) + regs.y;
|
||||
break;
|
||||
case OPTYPE_ILDP:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = dreadl(addr);
|
||||
break;
|
||||
case OPTYPE_ILDPY:
|
||||
addr = (regs.d + (addr & 0xffff)) & 0xffff;
|
||||
r = dreadl(addr) + regs.y;
|
||||
break;
|
||||
case OPTYPE_ADDR:
|
||||
r = (regs.db << 16) + (addr & 0xffff);
|
||||
break;
|
||||
case OPTYPE_ADDR_PC:
|
||||
r = (regs.pc.b << 16) + (addr & 0xffff);
|
||||
break;
|
||||
case OPTYPE_ADDRX:
|
||||
r = (regs.db << 16) + (addr & 0xffff) + regs.x;
|
||||
break;
|
||||
case OPTYPE_ADDRY:
|
||||
r = (regs.db << 16) + (addr & 0xffff) + regs.y;
|
||||
break;
|
||||
case OPTYPE_IADDR_PC:
|
||||
r = (regs.pc.b << 16) + (addr & 0xffff);
|
||||
break;
|
||||
case OPTYPE_IADDRX:
|
||||
r = (regs.pc.b << 16) + ((addr + regs.x) & 0xffff);
|
||||
break;
|
||||
case OPTYPE_ILADDR:
|
||||
r = addr;
|
||||
break;
|
||||
case OPTYPE_LONG:
|
||||
r = addr;
|
||||
break;
|
||||
case OPTYPE_LONGX:
|
||||
r = (addr + regs.x);
|
||||
break;
|
||||
case OPTYPE_SR:
|
||||
r = (regs.s + (addr & 0xff)) & 0xffff;
|
||||
break;
|
||||
case OPTYPE_ISRY:
|
||||
addr = (regs.s + (addr & 0xff)) & 0xffff;
|
||||
r = (regs.db << 16) + dreadw(addr) + regs.y;
|
||||
break;
|
||||
case OPTYPE_RELB:
|
||||
r = (regs.pc.b << 16) + ((regs.pc.w + 2) & 0xffff);
|
||||
r += int8(addr);
|
||||
break;
|
||||
case OPTYPE_RELW:
|
||||
r = (regs.pc.b << 16) + ((regs.pc.w + 3) & 0xffff);
|
||||
r += int16(addr);
|
||||
break;
|
||||
}
|
||||
|
||||
return(r & 0xffffff);
|
||||
}
|
||||
|
||||
void CPUcore::disassemble_opcode(char *output) {
|
||||
static reg24_t pc;
|
||||
char t[256];
|
||||
char *s = output;
|
||||
|
||||
if(false /* in_opcode() == true */) {
|
||||
strcpy(s, "?????? <CPU within opcode>");
|
||||
return;
|
||||
}
|
||||
|
||||
pc.d = regs.pc.d;
|
||||
sprintf(s, "%.6x ", (uint32)pc.d);
|
||||
|
||||
uint8 op = dreadb(pc.d); pc.w++;
|
||||
uint8 op0 = dreadb(pc.d); pc.w++;
|
||||
uint8 op1 = dreadb(pc.d); pc.w++;
|
||||
uint8 op2 = dreadb(pc.d);
|
||||
|
||||
#define op8 ((op0))
|
||||
#define op16 ((op0) | (op1 << 8))
|
||||
#define op24 ((op0) | (op1 << 8) | (op2 << 16))
|
||||
#define a8 (regs.e || regs.p.m)
|
||||
#define x8 (regs.e || regs.p.x)
|
||||
|
||||
switch(op) {
|
||||
case 0x00: sprintf(t, "brk #$%.2x ", op8); break;
|
||||
case 0x01: sprintf(t, "ora ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x02: sprintf(t, "cop #$%.2x ", op8); break;
|
||||
case 0x03: sprintf(t, "ora $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x04: sprintf(t, "tsb $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x05: sprintf(t, "ora $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x06: sprintf(t, "asl $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x07: sprintf(t, "ora [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x08: sprintf(t, "php "); break;
|
||||
case 0x09: if(a8)sprintf(t, "ora #$%.2x ", op8);
|
||||
else sprintf(t, "ora #$%.4x ", op16); break;
|
||||
case 0x0a: sprintf(t, "asl a "); break;
|
||||
case 0x0b: sprintf(t, "phd "); break;
|
||||
case 0x0c: sprintf(t, "tsb $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x0d: sprintf(t, "ora $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x0e: sprintf(t, "asl $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x0f: sprintf(t, "ora $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x10: sprintf(t, "bpl $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x11: sprintf(t, "ora ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x12: sprintf(t, "ora ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x13: sprintf(t, "ora ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x14: sprintf(t, "trb $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x15: sprintf(t, "ora $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x16: sprintf(t, "asl $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x17: sprintf(t, "ora [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x18: sprintf(t, "clc "); break;
|
||||
case 0x19: sprintf(t, "ora $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x1a: sprintf(t, "inc "); break;
|
||||
case 0x1b: sprintf(t, "tcs "); break;
|
||||
case 0x1c: sprintf(t, "trb $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x1d: sprintf(t, "ora $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x1e: sprintf(t, "asl $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x1f: sprintf(t, "ora $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x20: sprintf(t, "jsr $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break;
|
||||
case 0x21: sprintf(t, "and ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x22: sprintf(t, "jsl $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x23: sprintf(t, "and $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x24: sprintf(t, "bit $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x25: sprintf(t, "and $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x26: sprintf(t, "rol $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x27: sprintf(t, "and [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x28: sprintf(t, "plp "); break;
|
||||
case 0x29: if(a8)sprintf(t, "and #$%.2x ", op8);
|
||||
else sprintf(t, "and #$%.4x ", op16); break;
|
||||
case 0x2a: sprintf(t, "rol a "); break;
|
||||
case 0x2b: sprintf(t, "pld "); break;
|
||||
case 0x2c: sprintf(t, "bit $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x2d: sprintf(t, "and $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x2e: sprintf(t, "rol $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x2f: sprintf(t, "and $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x30: sprintf(t, "bmi $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x31: sprintf(t, "and ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x32: sprintf(t, "and ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x33: sprintf(t, "and ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x34: sprintf(t, "bit $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x35: sprintf(t, "and $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x36: sprintf(t, "rol $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x37: sprintf(t, "and [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x38: sprintf(t, "sec "); break;
|
||||
case 0x39: sprintf(t, "and $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x3a: sprintf(t, "dec "); break;
|
||||
case 0x3b: sprintf(t, "tsc "); break;
|
||||
case 0x3c: sprintf(t, "bit $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x3d: sprintf(t, "and $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x3e: sprintf(t, "rol $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x3f: sprintf(t, "and $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x40: sprintf(t, "rti "); break;
|
||||
case 0x41: sprintf(t, "eor ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x42: sprintf(t, "wdm "); break;
|
||||
case 0x43: sprintf(t, "eor $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x44: sprintf(t, "mvp $%.2x,$%.2x ", op1, op8); break;
|
||||
case 0x45: sprintf(t, "eor $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x46: sprintf(t, "lsr $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x47: sprintf(t, "eor [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x48: sprintf(t, "pha "); break;
|
||||
case 0x49: if(a8)sprintf(t, "eor #$%.2x ", op8);
|
||||
else sprintf(t, "eor #$%.4x ", op16); break;
|
||||
case 0x4a: sprintf(t, "lsr a "); break;
|
||||
case 0x4b: sprintf(t, "phk "); break;
|
||||
case 0x4c: sprintf(t, "jmp $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR_PC, op16)); break;
|
||||
case 0x4d: sprintf(t, "eor $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x4e: sprintf(t, "lsr $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x4f: sprintf(t, "eor $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x50: sprintf(t, "bvc $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x51: sprintf(t, "eor ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x52: sprintf(t, "eor ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x53: sprintf(t, "eor ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x54: sprintf(t, "mvn $%.2x,$%.2x ", op1, op8); break;
|
||||
case 0x55: sprintf(t, "eor $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x56: sprintf(t, "lsr $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x57: sprintf(t, "eor [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x58: sprintf(t, "cli "); break;
|
||||
case 0x59: sprintf(t, "eor $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x5a: sprintf(t, "phy "); break;
|
||||
case 0x5b: sprintf(t, "tcd "); break;
|
||||
case 0x5c: sprintf(t, "jml $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x5d: sprintf(t, "eor $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x5e: sprintf(t, "lsr $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x5f: sprintf(t, "eor $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x60: sprintf(t, "rts "); break;
|
||||
case 0x61: sprintf(t, "adc ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x62: sprintf(t, "per $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x63: sprintf(t, "adc $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x64: sprintf(t, "stz $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x65: sprintf(t, "adc $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x66: sprintf(t, "ror $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x67: sprintf(t, "adc [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x68: sprintf(t, "pla "); break;
|
||||
case 0x69: if(a8)sprintf(t, "adc #$%.2x ", op8);
|
||||
else sprintf(t, "adc #$%.4x ", op16); break;
|
||||
case 0x6a: sprintf(t, "ror a "); break;
|
||||
case 0x6b: sprintf(t, "rtl "); break;
|
||||
case 0x6c: sprintf(t, "jmp ($%.4x) [$%.6x]", op16, decode(OPTYPE_IADDR_PC, op16)); break;
|
||||
case 0x6d: sprintf(t, "adc $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x6e: sprintf(t, "ror $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x6f: sprintf(t, "adc $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x70: sprintf(t, "bvs $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x71: sprintf(t, "adc ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x72: sprintf(t, "adc ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x73: sprintf(t, "adc ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x74: sprintf(t, "stz $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x75: sprintf(t, "adc $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x76: sprintf(t, "ror $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x77: sprintf(t, "adc [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x78: sprintf(t, "sei "); break;
|
||||
case 0x79: sprintf(t, "adc $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x7a: sprintf(t, "ply "); break;
|
||||
case 0x7b: sprintf(t, "tdc "); break;
|
||||
case 0x7c: sprintf(t, "jmp ($%.4x,x) [$%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break;
|
||||
case 0x7d: sprintf(t, "adc $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x7e: sprintf(t, "ror $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x7f: sprintf(t, "adc $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0x80: sprintf(t, "bra $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x81: sprintf(t, "sta ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0x82: sprintf(t, "brl $%.4x [$%.6x]", uint16(decode(OPTYPE_RELW, op16)), decode(OPTYPE_RELW, op16)); break;
|
||||
case 0x83: sprintf(t, "sta $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0x84: sprintf(t, "sty $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x85: sprintf(t, "sta $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x86: sprintf(t, "stx $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0x87: sprintf(t, "sta [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0x88: sprintf(t, "dey "); break;
|
||||
case 0x89: if(a8)sprintf(t, "bit #$%.2x ", op8);
|
||||
else sprintf(t, "bit #$%.4x ", op16); break;
|
||||
case 0x8a: sprintf(t, "txa "); break;
|
||||
case 0x8b: sprintf(t, "phb "); break;
|
||||
case 0x8c: sprintf(t, "sty $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x8d: sprintf(t, "sta $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x8e: sprintf(t, "stx $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x8f: sprintf(t, "sta $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0x90: sprintf(t, "bcc $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0x91: sprintf(t, "sta ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0x92: sprintf(t, "sta ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0x93: sprintf(t, "sta ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0x94: sprintf(t, "sty $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x95: sprintf(t, "sta $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0x96: sprintf(t, "stx $%.2x,y [$%.6x]", op8, decode(OPTYPE_DPY, op8)); break;
|
||||
case 0x97: sprintf(t, "sta [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0x98: sprintf(t, "tya "); break;
|
||||
case 0x99: sprintf(t, "sta $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0x9a: sprintf(t, "txs "); break;
|
||||
case 0x9b: sprintf(t, "txy "); break;
|
||||
case 0x9c: sprintf(t, "stz $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0x9d: sprintf(t, "sta $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x9e: sprintf(t, "stz $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0x9f: sprintf(t, "sta $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0xa0: if(x8)sprintf(t, "ldy #$%.2x ", op8);
|
||||
else sprintf(t, "ldy #$%.4x ", op16); break;
|
||||
case 0xa1: sprintf(t, "lda ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0xa2: if(x8)sprintf(t, "ldx #$%.2x ", op8);
|
||||
else sprintf(t, "ldx #$%.4x ", op16); break;
|
||||
case 0xa3: sprintf(t, "lda $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0xa4: sprintf(t, "ldy $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xa5: sprintf(t, "lda $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xa6: sprintf(t, "ldx $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xa7: sprintf(t, "lda [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0xa8: sprintf(t, "tay "); break;
|
||||
case 0xa9: if(a8)sprintf(t, "lda #$%.2x ", op8);
|
||||
else sprintf(t, "lda #$%.4x ", op16); break;
|
||||
case 0xaa: sprintf(t, "tax "); break;
|
||||
case 0xab: sprintf(t, "plb "); break;
|
||||
case 0xac: sprintf(t, "ldy $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xad: sprintf(t, "lda $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xae: sprintf(t, "ldx $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xaf: sprintf(t, "lda $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0xb0: sprintf(t, "bcs $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xb1: sprintf(t, "lda ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0xb2: sprintf(t, "lda ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xb3: sprintf(t, "lda ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0xb4: sprintf(t, "ldy $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xb5: sprintf(t, "lda $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xb6: sprintf(t, "ldx $%.2x,y [$%.6x]", op8, decode(OPTYPE_DPY, op8)); break;
|
||||
case 0xb7: sprintf(t, "lda [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0xb8: sprintf(t, "clv "); break;
|
||||
case 0xb9: sprintf(t, "lda $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0xba: sprintf(t, "tsx "); break;
|
||||
case 0xbb: sprintf(t, "tyx "); break;
|
||||
case 0xbc: sprintf(t, "ldy $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xbd: sprintf(t, "lda $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xbe: sprintf(t, "ldx $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0xbf: sprintf(t, "lda $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0xc0: if(x8)sprintf(t, "cpy #$%.2x ", op8);
|
||||
else sprintf(t, "cpy #$%.4x ", op16); break;
|
||||
case 0xc1: sprintf(t, "cmp ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0xc2: sprintf(t, "rep #$%.2x ", op8); break;
|
||||
case 0xc3: sprintf(t, "cmp $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0xc4: sprintf(t, "cpy $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xc5: sprintf(t, "cmp $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xc6: sprintf(t, "dec $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xc7: sprintf(t, "cmp [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0xc8: sprintf(t, "iny "); break;
|
||||
case 0xc9: if(a8)sprintf(t, "cmp #$%.2x ", op8);
|
||||
else sprintf(t, "cmp #$%.4x ", op16); break;
|
||||
case 0xca: sprintf(t, "dex "); break;
|
||||
case 0xcb: sprintf(t, "wai "); break;
|
||||
case 0xcc: sprintf(t, "cpy $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xcd: sprintf(t, "cmp $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xce: sprintf(t, "dec $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xcf: sprintf(t, "cmp $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0xd0: sprintf(t, "bne $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xd1: sprintf(t, "cmp ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0xd2: sprintf(t, "cmp ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xd3: sprintf(t, "cmp ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0xd4: sprintf(t, "pei ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xd5: sprintf(t, "cmp $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xd6: sprintf(t, "dec $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xd7: sprintf(t, "cmp [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0xd8: sprintf(t, "cld "); break;
|
||||
case 0xd9: sprintf(t, "cmp $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0xda: sprintf(t, "phx "); break;
|
||||
case 0xdb: sprintf(t, "stp "); break;
|
||||
case 0xdc: sprintf(t, "jmp [$%.4x] [$%.6x]", op16, decode(OPTYPE_ILADDR, op16)); break;
|
||||
case 0xdd: sprintf(t, "cmp $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xde: sprintf(t, "dec $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xdf: sprintf(t, "cmp $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
case 0xe0: if(x8)sprintf(t, "cpx #$%.2x ", op8);
|
||||
else sprintf(t, "cpx #$%.4x ", op16); break;
|
||||
case 0xe1: sprintf(t, "sbc ($%.2x,x) [$%.6x]", op8, decode(OPTYPE_IDPX, op8)); break;
|
||||
case 0xe2: sprintf(t, "sep #$%.2x ", op8); break;
|
||||
case 0xe3: sprintf(t, "sbc $%.2x,s [$%.6x]", op8, decode(OPTYPE_SR, op8)); break;
|
||||
case 0xe4: sprintf(t, "cpx $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xe5: sprintf(t, "sbc $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xe6: sprintf(t, "inc $%.2x [$%.6x]", op8, decode(OPTYPE_DP, op8)); break;
|
||||
case 0xe7: sprintf(t, "sbc [$%.2x] [$%.6x]", op8, decode(OPTYPE_ILDP, op8)); break;
|
||||
case 0xe8: sprintf(t, "inx "); break;
|
||||
case 0xe9: if(a8)sprintf(t, "sbc #$%.2x ", op8);
|
||||
else sprintf(t, "sbc #$%.4x ", op16); break;
|
||||
case 0xea: sprintf(t, "nop "); break;
|
||||
case 0xeb: sprintf(t, "xba "); break;
|
||||
case 0xec: sprintf(t, "cpx $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xed: sprintf(t, "sbc $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xee: sprintf(t, "inc $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xef: sprintf(t, "sbc $%.6x [$%.6x]", op24, decode(OPTYPE_LONG, op24)); break;
|
||||
case 0xf0: sprintf(t, "beq $%.4x [$%.6x]", uint16(decode(OPTYPE_RELB, op8)), decode(OPTYPE_RELB, op8)); break;
|
||||
case 0xf1: sprintf(t, "sbc ($%.2x),y [$%.6x]", op8, decode(OPTYPE_IDPY, op8)); break;
|
||||
case 0xf2: sprintf(t, "sbc ($%.2x) [$%.6x]", op8, decode(OPTYPE_IDP, op8)); break;
|
||||
case 0xf3: sprintf(t, "sbc ($%.2x,s),y [$%.6x]", op8, decode(OPTYPE_ISRY, op8)); break;
|
||||
case 0xf4: sprintf(t, "pea $%.4x [$%.6x]", op16, decode(OPTYPE_ADDR, op16)); break;
|
||||
case 0xf5: sprintf(t, "sbc $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xf6: sprintf(t, "inc $%.2x,x [$%.6x]", op8, decode(OPTYPE_DPX, op8)); break;
|
||||
case 0xf7: sprintf(t, "sbc [$%.2x],y [$%.6x]", op8, decode(OPTYPE_ILDPY, op8)); break;
|
||||
case 0xf8: sprintf(t, "sed "); break;
|
||||
case 0xf9: sprintf(t, "sbc $%.4x,y [$%.6x]", op16, decode(OPTYPE_ADDRY, op16)); break;
|
||||
case 0xfa: sprintf(t, "plx "); break;
|
||||
case 0xfb: sprintf(t, "xce "); break;
|
||||
case 0xfc: sprintf(t, "jsr ($%.4x,x) [$%.6x]", op16, decode(OPTYPE_IADDRX, op16)); break;
|
||||
case 0xfd: sprintf(t, "sbc $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xfe: sprintf(t, "inc $%.4x,x [$%.6x]", op16, decode(OPTYPE_ADDRX, op16)); break;
|
||||
case 0xff: sprintf(t, "sbc $%.6x,x [$%.6x]", op24, decode(OPTYPE_LONGX, op24)); break;
|
||||
}
|
||||
|
||||
#undef op8
|
||||
#undef op16
|
||||
#undef op24
|
||||
#undef a8
|
||||
#undef x8
|
||||
|
||||
strcat(s, t);
|
||||
strcat(s, " ");
|
||||
|
||||
sprintf(t, "A:%.4x X:%.4x Y:%.4x S:%.4x D:%.4x DB:%.2x ",
|
||||
regs.a.w, regs.x.w, regs.y.w, regs.s.w, regs.d.w, regs.db);
|
||||
strcat(s, t);
|
||||
|
||||
if(regs.e) {
|
||||
sprintf(t, "%c%c%c%c%c%c%c%c",
|
||||
regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v',
|
||||
regs.p.m ? '1' : '0', regs.p.x ? 'B' : 'b',
|
||||
regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i',
|
||||
regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c');
|
||||
} else {
|
||||
sprintf(t, "%c%c%c%c%c%c%c%c",
|
||||
regs.p.n ? 'N' : 'n', regs.p.v ? 'V' : 'v',
|
||||
regs.p.m ? 'M' : 'm', regs.p.x ? 'X' : 'x',
|
||||
regs.p.d ? 'D' : 'd', regs.p.i ? 'I' : 'i',
|
||||
regs.p.z ? 'Z' : 'z', regs.p.c ? 'C' : 'c');
|
||||
}
|
||||
|
||||
strcat(s, t);
|
||||
strcat(s, " ");
|
||||
|
||||
sprintf(t, "V:%3d H:%4d", ppu.vcounter(), ppu.hcounter());
|
||||
strcat(s, t);
|
||||
}
|
||||
|
||||
//opcode_length() retrieves the length of the next opcode
|
||||
//to be executed. It is used by the debugger to step over,
|
||||
//disable and proceed cpu opcodes.
|
||||
//
|
||||
//5 and 6 are special cases, 5 is used for #consts based on
|
||||
//the A register size, 6 for the X/Y register size. the
|
||||
//rest are literal sizes. There's no need to test for
|
||||
//emulation mode, as regs.p.m/regs.p.x should *always* be
|
||||
//set in emulation mode.
|
||||
|
||||
uint8 CPUcore::opcode_length() {
|
||||
uint8 op, len;
|
||||
static uint8 op_len_tbl[256] = {
|
||||
//0,1,2,3, 4,5,6,7, 8,9,a,b, c,d,e,f
|
||||
|
||||
2,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x0n
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x1n
|
||||
3,2,4,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x2n
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x3n
|
||||
|
||||
1,2,2,2, 3,2,2,2, 1,5,1,1, 3,3,3,4, //0x4n
|
||||
2,2,2,2, 3,2,2,2, 1,3,1,1, 4,3,3,4, //0x5n
|
||||
1,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x6n
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x7n
|
||||
|
||||
2,2,3,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0x8n
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0x9n
|
||||
6,2,6,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xan
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xbn
|
||||
|
||||
6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xcn
|
||||
2,2,2,2, 2,2,2,2, 1,3,1,1, 3,3,3,4, //0xdn
|
||||
6,2,2,2, 2,2,2,2, 1,5,1,1, 3,3,3,4, //0xen
|
||||
2,2,2,2, 3,2,2,2, 1,3,1,1, 3,3,3,4 //0xfn
|
||||
};
|
||||
|
||||
if(false /* in_opcode() == true */) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
op = dreadb(regs.pc.d);
|
||||
len = op_len_tbl[op];
|
||||
if(len == 5) return (regs.e || regs.p.m) ? 2 : 3;
|
||||
if(len == 6) return (regs.e || regs.p.x) ? 2 : 3;
|
||||
return len;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
enum {
|
||||
OPTYPE_DP = 0, //dp
|
||||
OPTYPE_DPX, //dp,x
|
||||
OPTYPE_DPY, //dp,y
|
||||
OPTYPE_IDP, //(dp)
|
||||
OPTYPE_IDPX, //(dp,x)
|
||||
OPTYPE_IDPY, //(dp),y
|
||||
OPTYPE_ILDP, //[dp]
|
||||
OPTYPE_ILDPY, //[dp],y
|
||||
OPTYPE_ADDR, //addr
|
||||
OPTYPE_ADDRX, //addr,x
|
||||
OPTYPE_ADDRY, //addr,y
|
||||
OPTYPE_IADDRX, //(addr,x)
|
||||
OPTYPE_ILADDR, //[addr]
|
||||
OPTYPE_LONG, //long
|
||||
OPTYPE_LONGX, //long, x
|
||||
OPTYPE_SR, //sr,s
|
||||
OPTYPE_ISRY, //(sr,s),y
|
||||
OPTYPE_ADDR_PC, //pbr:addr
|
||||
OPTYPE_IADDR_PC, //pbr:(addr)
|
||||
OPTYPE_RELB, //relb
|
||||
OPTYPE_RELW, //relw
|
||||
};
|
||||
|
||||
void disassemble_opcode(char *output);
|
||||
uint8 dreadb(uint32 addr);
|
||||
uint16 dreadw(uint32 addr);
|
||||
uint32 dreadl(uint32 addr);
|
||||
uint32 decode(uint8 offset_type, uint32 addr);
|
||||
uint8 opcode_length();
|
|
@ -0,0 +1,77 @@
|
|||
alwaysinline uint8_t op_readpc() {
|
||||
return op_read((regs.pc.b << 16) + regs.pc.w++);
|
||||
}
|
||||
|
||||
alwaysinline uint8_t op_readstack() {
|
||||
regs.e ? regs.s.l++ : regs.s.w++;
|
||||
return op_read(regs.s.w);
|
||||
}
|
||||
|
||||
alwaysinline uint8_t op_readstackn() {
|
||||
return op_read(++regs.s.w);
|
||||
}
|
||||
|
||||
alwaysinline uint8_t op_readaddr(uint32_t addr) {
|
||||
return op_read(addr & 0xffff);
|
||||
}
|
||||
|
||||
alwaysinline uint8_t op_readlong(uint32_t addr) {
|
||||
return op_read(addr & 0xffffff);
|
||||
}
|
||||
|
||||
alwaysinline uint8_t op_readdbr(uint32_t addr) {
|
||||
return op_read(((regs.db << 16) + addr) & 0xffffff);
|
||||
}
|
||||
|
||||
alwaysinline uint8_t op_readpbr(uint32_t addr) {
|
||||
return op_read((regs.pc.b << 16) + (addr & 0xffff));
|
||||
}
|
||||
|
||||
alwaysinline uint8_t op_readdp(uint32_t 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_t op_readsp(uint32_t addr) {
|
||||
return op_read((regs.s + (addr & 0xffff)) & 0xffff);
|
||||
}
|
||||
|
||||
alwaysinline void op_writestack(uint8_t data) {
|
||||
op_write(regs.s.w, data);
|
||||
regs.e ? regs.s.l-- : regs.s.w--;
|
||||
}
|
||||
|
||||
alwaysinline void op_writestackn(uint8_t data) {
|
||||
op_write(regs.s.w--, data);
|
||||
}
|
||||
|
||||
alwaysinline void op_writeaddr(uint32_t addr, uint8_t data) {
|
||||
op_write(addr & 0xffff, data);
|
||||
}
|
||||
|
||||
alwaysinline void op_writelong(uint32_t addr, uint8_t data) {
|
||||
op_write(addr & 0xffffff, data);
|
||||
}
|
||||
|
||||
alwaysinline void op_writedbr(uint32_t addr, uint8_t data) {
|
||||
op_write(((regs.db << 16) + addr) & 0xffffff, data);
|
||||
}
|
||||
|
||||
alwaysinline void op_writepbr(uint32_t addr, uint8_t data) {
|
||||
op_write((regs.pc.b << 16) + (addr & 0xffff), data);
|
||||
}
|
||||
|
||||
alwaysinline void op_writedp(uint32_t addr, uint8_t 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 op_writesp(uint32_t addr, uint8_t data) {
|
||||
op_write((regs.s + (addr & 0xffff)) & 0xffff, data);
|
||||
}
|
|
@ -1,7 +1,4 @@
|
|||
#ifdef SCPU_CPP
|
||||
|
||||
//op_read
|
||||
inline void sCPU::op_adc_b() {
|
||||
inline void CPUcore::op_adc_b() {
|
||||
int r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.l ) & 15;
|
||||
|
@ -29,7 +26,7 @@ inline void sCPU::op_adc_b() {
|
|||
regs.a.l = r;
|
||||
}
|
||||
|
||||
inline void sCPU::op_adc_w() {
|
||||
inline void CPUcore::op_adc_w() {
|
||||
int r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.w ) & 15;
|
||||
|
@ -69,133 +66,133 @@ inline void sCPU::op_adc_w() {
|
|||
regs.a.w = r;
|
||||
}
|
||||
|
||||
inline void sCPU::op_and_b() {
|
||||
inline void CPUcore::op_and_b() {
|
||||
regs.a.l &= rd.l;
|
||||
regs.p.n = regs.a.l & 0x80;
|
||||
regs.p.z = regs.a.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_and_w() {
|
||||
inline void CPUcore::op_and_w() {
|
||||
regs.a.w &= rd.w;
|
||||
regs.p.n = regs.a.w & 0x8000;
|
||||
regs.p.z = regs.a.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_bit_b() {
|
||||
inline void CPUcore::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 sCPU::op_bit_w() {
|
||||
inline void CPUcore::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 sCPU::op_cmp_b() {
|
||||
inline void CPUcore::op_cmp_b() {
|
||||
int r = regs.a.l - rd.l;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_cmp_w() {
|
||||
inline void CPUcore::op_cmp_w() {
|
||||
int r = regs.a.w - rd.w;
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_cpx_b() {
|
||||
inline void CPUcore::op_cpx_b() {
|
||||
int r = regs.x.l - rd.l;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_cpx_w() {
|
||||
inline void CPUcore::op_cpx_w() {
|
||||
int r = regs.x.w - rd.w;
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_cpy_b() {
|
||||
inline void CPUcore::op_cpy_b() {
|
||||
int r = regs.y.l - rd.l;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_cpy_w() {
|
||||
inline void CPUcore::op_cpy_w() {
|
||||
int r = regs.y.w - rd.w;
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_eor_b() {
|
||||
inline void CPUcore::op_eor_b() {
|
||||
regs.a.l ^= rd.l;
|
||||
regs.p.n = regs.a.l & 0x80;
|
||||
regs.p.z = regs.a.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_eor_w() {
|
||||
inline void CPUcore::op_eor_w() {
|
||||
regs.a.w ^= rd.w;
|
||||
regs.p.n = regs.a.w & 0x8000;
|
||||
regs.p.z = regs.a.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_lda_b() {
|
||||
inline void CPUcore::op_lda_b() {
|
||||
regs.a.l = rd.l;
|
||||
regs.p.n = regs.a.l & 0x80;
|
||||
regs.p.z = regs.a.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_lda_w() {
|
||||
inline void CPUcore::op_lda_w() {
|
||||
regs.a.w = rd.w;
|
||||
regs.p.n = regs.a.w & 0x8000;
|
||||
regs.p.z = regs.a.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ldx_b() {
|
||||
inline void CPUcore::op_ldx_b() {
|
||||
regs.x.l = rd.l;
|
||||
regs.p.n = regs.x.l & 0x80;
|
||||
regs.p.z = regs.x.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ldx_w() {
|
||||
inline void CPUcore::op_ldx_w() {
|
||||
regs.x.w = rd.w;
|
||||
regs.p.n = regs.x.w & 0x8000;
|
||||
regs.p.z = regs.x.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ldy_b() {
|
||||
inline void CPUcore::op_ldy_b() {
|
||||
regs.y.l = rd.l;
|
||||
regs.p.n = regs.y.l & 0x80;
|
||||
regs.p.z = regs.y.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ldy_w() {
|
||||
inline void CPUcore::op_ldy_w() {
|
||||
regs.y.w = rd.w;
|
||||
regs.p.n = regs.y.w & 0x8000;
|
||||
regs.p.z = regs.y.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ora_b() {
|
||||
inline void CPUcore::op_ora_b() {
|
||||
regs.a.l |= rd.l;
|
||||
regs.p.n = regs.a.l & 0x80;
|
||||
regs.p.z = regs.a.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ora_w() {
|
||||
inline void CPUcore::op_ora_w() {
|
||||
regs.a.w |= rd.w;
|
||||
regs.p.n = regs.a.w & 0x8000;
|
||||
regs.p.z = regs.a.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_sbc_b() {
|
||||
inline void CPUcore::op_sbc_b() {
|
||||
int r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.l ) & 15;
|
||||
|
@ -223,7 +220,7 @@ inline void sCPU::op_sbc_b() {
|
|||
regs.a.l = r;
|
||||
}
|
||||
|
||||
inline void sCPU::op_sbc_w() {
|
||||
inline void CPUcore::op_sbc_w() {
|
||||
int r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.w ) & 15;
|
||||
|
@ -263,60 +260,59 @@ inline void sCPU::op_sbc_w() {
|
|||
regs.a.w = r;
|
||||
}
|
||||
|
||||
//op_rmw
|
||||
inline void sCPU::op_inc_b() {
|
||||
inline void CPUcore::op_inc_b() {
|
||||
rd.l++;
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_inc_w() {
|
||||
inline void CPUcore::op_inc_w() {
|
||||
rd.w++;
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_dec_b() {
|
||||
inline void CPUcore::op_dec_b() {
|
||||
rd.l--;
|
||||
regs.p.n = rd.l & 0x80;
|
||||
regs.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_dec_w() {
|
||||
inline void CPUcore::op_dec_w() {
|
||||
rd.w--;
|
||||
regs.p.n = rd.w & 0x8000;
|
||||
regs.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_asl_b() {
|
||||
inline void CPUcore::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 sCPU::op_asl_w() {
|
||||
inline void CPUcore::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 sCPU::op_lsr_b() {
|
||||
inline void CPUcore::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 sCPU::op_lsr_w() {
|
||||
inline void CPUcore::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 sCPU::op_rol_b() {
|
||||
inline void CPUcore::op_rol_b() {
|
||||
unsigned carry = (unsigned)regs.p.c;
|
||||
regs.p.c = rd.l & 0x80;
|
||||
rd.l = (rd.l << 1) | carry;
|
||||
|
@ -324,7 +320,7 @@ inline void sCPU::op_rol_b() {
|
|||
regs.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_rol_w() {
|
||||
inline void CPUcore::op_rol_w() {
|
||||
unsigned carry = (unsigned)regs.p.c;
|
||||
regs.p.c = rd.w & 0x8000;
|
||||
rd.w = (rd.w << 1) | carry;
|
||||
|
@ -332,7 +328,7 @@ inline void sCPU::op_rol_w() {
|
|||
regs.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ror_b() {
|
||||
inline void CPUcore::op_ror_b() {
|
||||
unsigned carry = (unsigned)regs.p.c << 7;
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l = carry | (rd.l >> 1);
|
||||
|
@ -340,7 +336,7 @@ inline void sCPU::op_ror_b() {
|
|||
regs.p.z = rd.l == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_ror_w() {
|
||||
inline void CPUcore::op_ror_w() {
|
||||
unsigned carry = (unsigned)regs.p.c << 15;
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w = carry | (rd.w >> 1);
|
||||
|
@ -348,24 +344,22 @@ inline void sCPU::op_ror_w() {
|
|||
regs.p.z = rd.w == 0;
|
||||
}
|
||||
|
||||
inline void sCPU::op_trb_b() {
|
||||
inline void CPUcore::op_trb_b() {
|
||||
regs.p.z = (rd.l & regs.a.l) == 0;
|
||||
rd.l &= ~regs.a.l;
|
||||
}
|
||||
|
||||
inline void sCPU::op_trb_w() {
|
||||
inline void CPUcore::op_trb_w() {
|
||||
regs.p.z = (rd.w & regs.a.w) == 0;
|
||||
rd.w &= ~regs.a.w;
|
||||
}
|
||||
|
||||
inline void sCPU::op_tsb_b() {
|
||||
inline void CPUcore::op_tsb_b() {
|
||||
regs.p.z = (rd.l & regs.a.l) == 0;
|
||||
rd.l |= regs.a.l;
|
||||
}
|
||||
|
||||
inline void sCPU::op_tsb_w() {
|
||||
inline void CPUcore::op_tsb_w() {
|
||||
regs.p.z = (rd.w & regs.a.w) == 0;
|
||||
rd.w |= regs.a.w;
|
||||
}
|
||||
|
||||
#endif //ifdef SCPU_CPP
|
|
@ -0,0 +1,13 @@
|
|||
//opcode_functions.cpp was generated via bpp -> opcode_functions.bpp
|
||||
|
||||
@global class CPUcore
|
||||
@global lc last_cycle();
|
||||
@global wai regs.wai
|
||||
|
||||
@include "opcode_read.bpp"
|
||||
@include "opcode_write.bpp"
|
||||
@include "opcode_rmw.bpp"
|
||||
@include "opcode_pc.bpp"
|
||||
@include "opcode_misc.bpp"
|
||||
|
||||
@include "opcode_list.bpp"
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,386 @@
|
|||
//===============
|
||||
//opcode_read.bpp
|
||||
//===============
|
||||
|
||||
@macro op_read_const(name)
|
||||
void op_{name}_const_b();
|
||||
void op_{name}_const_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_bit_const()
|
||||
void op_bit_const_b();
|
||||
void op_bit_const_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_addr(name)
|
||||
void op_{name}_addr_b();
|
||||
void op_{name}_addr_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_addrx(name)
|
||||
void op_{name}_addrx_b();
|
||||
void op_{name}_addrx_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_addry(name)
|
||||
void op_{name}_addry_b();
|
||||
void op_{name}_addry_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_long(name)
|
||||
void op_{name}_long_b();
|
||||
void op_{name}_long_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_longx(name)
|
||||
void op_{name}_longx_b();
|
||||
void op_{name}_longx_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_dp(name)
|
||||
void op_{name}_dp_b();
|
||||
void op_{name}_dp_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_dpr(name, r)
|
||||
void op_{name}_dpr_b();
|
||||
void op_{name}_dpr_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_idp(name)
|
||||
void op_{name}_idp_b();
|
||||
void op_{name}_idp_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_idpx(name)
|
||||
void op_{name}_idpx_b();
|
||||
void op_{name}_idpx_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_idpy(name)
|
||||
void op_{name}_idpy_b();
|
||||
void op_{name}_idpy_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_ildp(name)
|
||||
void op_{name}_ildp_b();
|
||||
void op_{name}_ildp_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_ildpy(name)
|
||||
void op_{name}_ildpy_b();
|
||||
void op_{name}_ildpy_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_sr(name)
|
||||
void op_{name}_sr_b();
|
||||
void op_{name}_sr_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_read_isry(name)
|
||||
void op_{name}_isry_b();
|
||||
void op_{name}_isry_w();
|
||||
@endmacro
|
||||
|
||||
//================
|
||||
//opcode_write.bpp
|
||||
//================
|
||||
|
||||
@macro op_store_addr(name, r)
|
||||
void op_{name}_addr_b();
|
||||
void op_{name}_addr_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_store_addrr(name, suffix, r, index)
|
||||
void op_{name}_addr{suffix}_b();
|
||||
void op_{name}_addr{suffix}_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_store_longr(name, suffix, index)
|
||||
void op_{name}_long{suffix}_b();
|
||||
void op_{name}_long{suffix}_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_store_dp(name, r)
|
||||
void op_{name}_dp_b();
|
||||
void op_{name}_dp_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_store_dpr(name, r, index)
|
||||
void op_{name}_dpr_b();
|
||||
void op_{name}_dpr_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_idp()
|
||||
void op_sta_idp_b();
|
||||
void op_sta_idp_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_ildp()
|
||||
void op_sta_ildp_b();
|
||||
void op_sta_ildp_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_idpx()
|
||||
void op_sta_idpx_b();
|
||||
void op_sta_idpx_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_idpy()
|
||||
void op_sta_idpy_b();
|
||||
void op_sta_idpy_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_ildpy()
|
||||
void op_sta_ildpy_b();
|
||||
void op_sta_ildpy_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_sr()
|
||||
void op_sta_sr_b();
|
||||
void op_sta_sr_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_isry()
|
||||
void op_sta_isry_b();
|
||||
void op_sta_isry_w();
|
||||
@endmacro
|
||||
|
||||
//==============
|
||||
//opcode_rmw.bpp
|
||||
//==============
|
||||
|
||||
@macro op_adjust(name, r, op)
|
||||
void op_{name}_imm_b();
|
||||
void op_{name}_imm_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_asl()
|
||||
void op_asl_imm_b();
|
||||
void op_asl_imm_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_lsr()
|
||||
void op_lsr_imm_b();
|
||||
void op_lsr_imm_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_rol()
|
||||
void op_rol_imm_b();
|
||||
void op_rol_imm_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_ror()
|
||||
void op_ror_imm_b();
|
||||
void op_ror_imm_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_adjust_addr(name)
|
||||
void op_{name}_addr_b();
|
||||
void op_{name}_addr_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_adjust_addrx(name)
|
||||
void op_{name}_addrx_b();
|
||||
void op_{name}_addrx_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_adjust_dp(name)
|
||||
void op_{name}_dp_b();
|
||||
void op_{name}_dp_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_adjust_dpx(name)
|
||||
void op_{name}_dpx_b();
|
||||
void op_{name}_dpx_w();
|
||||
@endmacro
|
||||
|
||||
//=============
|
||||
//opcode_pc.bpp
|
||||
//=============
|
||||
|
||||
@macro op_branch(name, condition)
|
||||
void op_{name}();
|
||||
@endmacro
|
||||
|
||||
@macro op_bra()
|
||||
void op_bra();
|
||||
@endmacro
|
||||
|
||||
@macro op_brl()
|
||||
void op_brl();
|
||||
@endmacro
|
||||
|
||||
@macro op_jmp_addr()
|
||||
void op_jmp_addr();
|
||||
@endmacro
|
||||
|
||||
@macro op_jmp_long()
|
||||
void op_jmp_long();
|
||||
@endmacro
|
||||
|
||||
@macro op_jmp_iaddr()
|
||||
void op_jmp_iaddr();
|
||||
@endmacro
|
||||
|
||||
@macro op_jmp_iaddrx()
|
||||
void op_jmp_iaddrx();
|
||||
@endmacro
|
||||
|
||||
@macro op_jmp_iladdr()
|
||||
void op_jmp_iladdr();
|
||||
@endmacro
|
||||
|
||||
@macro op_jsr_addr()
|
||||
void op_jsr_addr();
|
||||
@endmacro
|
||||
|
||||
@macro op_jsr_long()
|
||||
void op_jsr_long_e();
|
||||
void op_jsr_long_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_jsr_iaddrx()
|
||||
void op_jsr_iaddrx_e();
|
||||
void op_jsr_iaddrx_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_rti()
|
||||
void op_rti_e();
|
||||
void op_rti_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_rts()
|
||||
void op_rts();
|
||||
@endmacro
|
||||
|
||||
@macro op_rtl()
|
||||
void op_rtl_e();
|
||||
void op_rtl_n();
|
||||
@endmacro
|
||||
|
||||
//===============
|
||||
//opcode_misc.bpp
|
||||
//===============
|
||||
|
||||
@macro op_nop()
|
||||
void op_nop();
|
||||
@endmacro
|
||||
|
||||
@macro op_wdm()
|
||||
void op_wdm();
|
||||
@endmacro
|
||||
|
||||
@macro op_xba()
|
||||
void op_xba();
|
||||
@endmacro
|
||||
|
||||
@macro op_move(name, op)
|
||||
void op_{name}_b();
|
||||
void op_{name}_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_interrupt(name, vectorE, vectorN)
|
||||
void op_{name}_e();
|
||||
void op_{name}_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_stp()
|
||||
void op_stp();
|
||||
@endmacro
|
||||
|
||||
@macro op_wai()
|
||||
void op_wai();
|
||||
@endmacro
|
||||
|
||||
@macro op_xce()
|
||||
void op_xce();
|
||||
@endmacro
|
||||
|
||||
@macro op_flag(name, rule)
|
||||
void op_{name}();
|
||||
@endmacro
|
||||
|
||||
@macro op_pflag(name, op)
|
||||
void op_{name}_e();
|
||||
void op_{name}_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_transfer(name, from, to)
|
||||
void op_{name}_b();
|
||||
void op_{name}_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_transfer_word(name, from, to)
|
||||
void op_{name}();
|
||||
@endmacro
|
||||
|
||||
@macro op_tcs()
|
||||
void op_tcs_e();
|
||||
void op_tcs_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_tsc()
|
||||
void op_tsc_e();
|
||||
void op_tsc_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_tsx()
|
||||
void op_tsx_b();
|
||||
void op_tsx_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_txs()
|
||||
void op_txs_e();
|
||||
void op_txs_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_push(name, r)
|
||||
void op_{name}_b();
|
||||
void op_{name}_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_phd()
|
||||
void op_phd_e();
|
||||
void op_phd_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_push_byte(name, r)
|
||||
void op_{name}();
|
||||
@endmacro
|
||||
|
||||
@macro op_pull(name, r)
|
||||
void op_{name}_b();
|
||||
void op_{name}_w();
|
||||
@endmacro
|
||||
|
||||
@macro op_pld()
|
||||
void op_pld_e();
|
||||
void op_pld_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_plb()
|
||||
void op_plb();
|
||||
@endmacro
|
||||
|
||||
@macro op_plp()
|
||||
void op_plp_e();
|
||||
void op_plp_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_pea()
|
||||
void op_pea_e();
|
||||
void op_pea_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_pei()
|
||||
void op_pei_e();
|
||||
void op_pei_n();
|
||||
@endmacro
|
||||
|
||||
@macro op_per()
|
||||
void op_per_e();
|
||||
void op_per_n();
|
||||
@endmacro
|
||||
|
||||
@include "opcode_list.bpp"
|
|
@ -0,0 +1,892 @@
|
|||
//===============
|
||||
//opcode_read.bpp
|
||||
//===============
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//================
|
||||
//opcode_write.bpp
|
||||
//================
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//==============
|
||||
//opcode_rmw.bpp
|
||||
//==============
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//=============
|
||||
//opcode_pc.bpp
|
||||
//=============
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//===============
|
||||
//opcode_misc.bpp
|
||||
//===============
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//===============
|
||||
//opcode_read.bpp
|
||||
//===============
|
||||
|
||||
void op_adc_const_b();
|
||||
void op_adc_const_w();
|
||||
|
||||
void op_and_const_b();
|
||||
void op_and_const_w();
|
||||
|
||||
void op_cmp_const_b();
|
||||
void op_cmp_const_w();
|
||||
|
||||
void op_cpx_const_b();
|
||||
void op_cpx_const_w();
|
||||
|
||||
void op_cpy_const_b();
|
||||
void op_cpy_const_w();
|
||||
|
||||
void op_eor_const_b();
|
||||
void op_eor_const_w();
|
||||
|
||||
void op_lda_const_b();
|
||||
void op_lda_const_w();
|
||||
|
||||
void op_ldx_const_b();
|
||||
void op_ldx_const_w();
|
||||
|
||||
void op_ldy_const_b();
|
||||
void op_ldy_const_w();
|
||||
|
||||
void op_ora_const_b();
|
||||
void op_ora_const_w();
|
||||
|
||||
void op_sbc_const_b();
|
||||
void op_sbc_const_w();
|
||||
|
||||
|
||||
void op_bit_const_b();
|
||||
void op_bit_const_w();
|
||||
|
||||
|
||||
void op_adc_addr_b();
|
||||
void op_adc_addr_w();
|
||||
|
||||
void op_and_addr_b();
|
||||
void op_and_addr_w();
|
||||
|
||||
void op_bit_addr_b();
|
||||
void op_bit_addr_w();
|
||||
|
||||
void op_cmp_addr_b();
|
||||
void op_cmp_addr_w();
|
||||
|
||||
void op_cpx_addr_b();
|
||||
void op_cpx_addr_w();
|
||||
|
||||
void op_cpy_addr_b();
|
||||
void op_cpy_addr_w();
|
||||
|
||||
void op_eor_addr_b();
|
||||
void op_eor_addr_w();
|
||||
|
||||
void op_lda_addr_b();
|
||||
void op_lda_addr_w();
|
||||
|
||||
void op_ldx_addr_b();
|
||||
void op_ldx_addr_w();
|
||||
|
||||
void op_ldy_addr_b();
|
||||
void op_ldy_addr_w();
|
||||
|
||||
void op_ora_addr_b();
|
||||
void op_ora_addr_w();
|
||||
|
||||
void op_sbc_addr_b();
|
||||
void op_sbc_addr_w();
|
||||
|
||||
|
||||
void op_adc_addrx_b();
|
||||
void op_adc_addrx_w();
|
||||
|
||||
void op_and_addrx_b();
|
||||
void op_and_addrx_w();
|
||||
|
||||
void op_bit_addrx_b();
|
||||
void op_bit_addrx_w();
|
||||
|
||||
void op_cmp_addrx_b();
|
||||
void op_cmp_addrx_w();
|
||||
|
||||
void op_eor_addrx_b();
|
||||
void op_eor_addrx_w();
|
||||
|
||||
void op_lda_addrx_b();
|
||||
void op_lda_addrx_w();
|
||||
|
||||
void op_ldy_addrx_b();
|
||||
void op_ldy_addrx_w();
|
||||
|
||||
void op_ora_addrx_b();
|
||||
void op_ora_addrx_w();
|
||||
|
||||
void op_sbc_addrx_b();
|
||||
void op_sbc_addrx_w();
|
||||
|
||||
|
||||
void op_adc_addry_b();
|
||||
void op_adc_addry_w();
|
||||
|
||||
void op_and_addry_b();
|
||||
void op_and_addry_w();
|
||||
|
||||
void op_cmp_addry_b();
|
||||
void op_cmp_addry_w();
|
||||
|
||||
void op_eor_addry_b();
|
||||
void op_eor_addry_w();
|
||||
|
||||
void op_lda_addry_b();
|
||||
void op_lda_addry_w();
|
||||
|
||||
void op_ldx_addry_b();
|
||||
void op_ldx_addry_w();
|
||||
|
||||
void op_ora_addry_b();
|
||||
void op_ora_addry_w();
|
||||
|
||||
void op_sbc_addry_b();
|
||||
void op_sbc_addry_w();
|
||||
|
||||
|
||||
void op_adc_long_b();
|
||||
void op_adc_long_w();
|
||||
|
||||
void op_and_long_b();
|
||||
void op_and_long_w();
|
||||
|
||||
void op_cmp_long_b();
|
||||
void op_cmp_long_w();
|
||||
|
||||
void op_eor_long_b();
|
||||
void op_eor_long_w();
|
||||
|
||||
void op_lda_long_b();
|
||||
void op_lda_long_w();
|
||||
|
||||
void op_ora_long_b();
|
||||
void op_ora_long_w();
|
||||
|
||||
void op_sbc_long_b();
|
||||
void op_sbc_long_w();
|
||||
|
||||
|
||||
void op_adc_longx_b();
|
||||
void op_adc_longx_w();
|
||||
|
||||
void op_and_longx_b();
|
||||
void op_and_longx_w();
|
||||
|
||||
void op_cmp_longx_b();
|
||||
void op_cmp_longx_w();
|
||||
|
||||
void op_eor_longx_b();
|
||||
void op_eor_longx_w();
|
||||
|
||||
void op_lda_longx_b();
|
||||
void op_lda_longx_w();
|
||||
|
||||
void op_ora_longx_b();
|
||||
void op_ora_longx_w();
|
||||
|
||||
void op_sbc_longx_b();
|
||||
void op_sbc_longx_w();
|
||||
|
||||
|
||||
void op_adc_dp_b();
|
||||
void op_adc_dp_w();
|
||||
|
||||
void op_and_dp_b();
|
||||
void op_and_dp_w();
|
||||
|
||||
void op_bit_dp_b();
|
||||
void op_bit_dp_w();
|
||||
|
||||
void op_cmp_dp_b();
|
||||
void op_cmp_dp_w();
|
||||
|
||||
void op_cpx_dp_b();
|
||||
void op_cpx_dp_w();
|
||||
|
||||
void op_cpy_dp_b();
|
||||
void op_cpy_dp_w();
|
||||
|
||||
void op_eor_dp_b();
|
||||
void op_eor_dp_w();
|
||||
|
||||
void op_lda_dp_b();
|
||||
void op_lda_dp_w();
|
||||
|
||||
void op_ldx_dp_b();
|
||||
void op_ldx_dp_w();
|
||||
|
||||
void op_ldy_dp_b();
|
||||
void op_ldy_dp_w();
|
||||
|
||||
void op_ora_dp_b();
|
||||
void op_ora_dp_w();
|
||||
|
||||
void op_sbc_dp_b();
|
||||
void op_sbc_dp_w();
|
||||
|
||||
|
||||
void op_adc_dpr_b();
|
||||
void op_adc_dpr_w();
|
||||
|
||||
void op_and_dpr_b();
|
||||
void op_and_dpr_w();
|
||||
|
||||
void op_bit_dpr_b();
|
||||
void op_bit_dpr_w();
|
||||
|
||||
void op_cmp_dpr_b();
|
||||
void op_cmp_dpr_w();
|
||||
|
||||
void op_eor_dpr_b();
|
||||
void op_eor_dpr_w();
|
||||
|
||||
void op_lda_dpr_b();
|
||||
void op_lda_dpr_w();
|
||||
|
||||
void op_ldx_dpr_b();
|
||||
void op_ldx_dpr_w();
|
||||
|
||||
void op_ldy_dpr_b();
|
||||
void op_ldy_dpr_w();
|
||||
|
||||
void op_ora_dpr_b();
|
||||
void op_ora_dpr_w();
|
||||
|
||||
void op_sbc_dpr_b();
|
||||
void op_sbc_dpr_w();
|
||||
|
||||
|
||||
void op_adc_idp_b();
|
||||
void op_adc_idp_w();
|
||||
|
||||
void op_and_idp_b();
|
||||
void op_and_idp_w();
|
||||
|
||||
void op_cmp_idp_b();
|
||||
void op_cmp_idp_w();
|
||||
|
||||
void op_eor_idp_b();
|
||||
void op_eor_idp_w();
|
||||
|
||||
void op_lda_idp_b();
|
||||
void op_lda_idp_w();
|
||||
|
||||
void op_ora_idp_b();
|
||||
void op_ora_idp_w();
|
||||
|
||||
void op_sbc_idp_b();
|
||||
void op_sbc_idp_w();
|
||||
|
||||
|
||||
void op_adc_idpx_b();
|
||||
void op_adc_idpx_w();
|
||||
|
||||
void op_and_idpx_b();
|
||||
void op_and_idpx_w();
|
||||
|
||||
void op_cmp_idpx_b();
|
||||
void op_cmp_idpx_w();
|
||||
|
||||
void op_eor_idpx_b();
|
||||
void op_eor_idpx_w();
|
||||
|
||||
void op_lda_idpx_b();
|
||||
void op_lda_idpx_w();
|
||||
|
||||
void op_ora_idpx_b();
|
||||
void op_ora_idpx_w();
|
||||
|
||||
void op_sbc_idpx_b();
|
||||
void op_sbc_idpx_w();
|
||||
|
||||
|
||||
void op_adc_idpy_b();
|
||||
void op_adc_idpy_w();
|
||||
|
||||
void op_and_idpy_b();
|
||||
void op_and_idpy_w();
|
||||
|
||||
void op_cmp_idpy_b();
|
||||
void op_cmp_idpy_w();
|
||||
|
||||
void op_eor_idpy_b();
|
||||
void op_eor_idpy_w();
|
||||
|
||||
void op_lda_idpy_b();
|
||||
void op_lda_idpy_w();
|
||||
|
||||
void op_ora_idpy_b();
|
||||
void op_ora_idpy_w();
|
||||
|
||||
void op_sbc_idpy_b();
|
||||
void op_sbc_idpy_w();
|
||||
|
||||
|
||||
void op_adc_ildp_b();
|
||||
void op_adc_ildp_w();
|
||||
|
||||
void op_and_ildp_b();
|
||||
void op_and_ildp_w();
|
||||
|
||||
void op_cmp_ildp_b();
|
||||
void op_cmp_ildp_w();
|
||||
|
||||
void op_eor_ildp_b();
|
||||
void op_eor_ildp_w();
|
||||
|
||||
void op_lda_ildp_b();
|
||||
void op_lda_ildp_w();
|
||||
|
||||
void op_ora_ildp_b();
|
||||
void op_ora_ildp_w();
|
||||
|
||||
void op_sbc_ildp_b();
|
||||
void op_sbc_ildp_w();
|
||||
|
||||
|
||||
void op_adc_ildpy_b();
|
||||
void op_adc_ildpy_w();
|
||||
|
||||
void op_and_ildpy_b();
|
||||
void op_and_ildpy_w();
|
||||
|
||||
void op_cmp_ildpy_b();
|
||||
void op_cmp_ildpy_w();
|
||||
|
||||
void op_eor_ildpy_b();
|
||||
void op_eor_ildpy_w();
|
||||
|
||||
void op_lda_ildpy_b();
|
||||
void op_lda_ildpy_w();
|
||||
|
||||
void op_ora_ildpy_b();
|
||||
void op_ora_ildpy_w();
|
||||
|
||||
void op_sbc_ildpy_b();
|
||||
void op_sbc_ildpy_w();
|
||||
|
||||
|
||||
void op_adc_sr_b();
|
||||
void op_adc_sr_w();
|
||||
|
||||
void op_and_sr_b();
|
||||
void op_and_sr_w();
|
||||
|
||||
void op_cmp_sr_b();
|
||||
void op_cmp_sr_w();
|
||||
|
||||
void op_eor_sr_b();
|
||||
void op_eor_sr_w();
|
||||
|
||||
void op_lda_sr_b();
|
||||
void op_lda_sr_w();
|
||||
|
||||
void op_ora_sr_b();
|
||||
void op_ora_sr_w();
|
||||
|
||||
void op_sbc_sr_b();
|
||||
void op_sbc_sr_w();
|
||||
|
||||
|
||||
void op_adc_isry_b();
|
||||
void op_adc_isry_w();
|
||||
|
||||
void op_and_isry_b();
|
||||
void op_and_isry_w();
|
||||
|
||||
void op_cmp_isry_b();
|
||||
void op_cmp_isry_w();
|
||||
|
||||
void op_eor_isry_b();
|
||||
void op_eor_isry_w();
|
||||
|
||||
void op_lda_isry_b();
|
||||
void op_lda_isry_w();
|
||||
|
||||
void op_ora_isry_b();
|
||||
void op_ora_isry_w();
|
||||
|
||||
void op_sbc_isry_b();
|
||||
void op_sbc_isry_w();
|
||||
|
||||
|
||||
//================
|
||||
//opcode_write.bpp
|
||||
//================
|
||||
|
||||
void op_sta_addr_b();
|
||||
void op_sta_addr_w();
|
||||
|
||||
void op_stx_addr_b();
|
||||
void op_stx_addr_w();
|
||||
|
||||
void op_sty_addr_b();
|
||||
void op_sty_addr_w();
|
||||
|
||||
void op_stz_addr_b();
|
||||
void op_stz_addr_w();
|
||||
|
||||
|
||||
void op_sta_addrx_b();
|
||||
void op_sta_addrx_w();
|
||||
|
||||
void op_sta_addry_b();
|
||||
void op_sta_addry_w();
|
||||
|
||||
void op_stz_addrx_b();
|
||||
void op_stz_addrx_w();
|
||||
|
||||
|
||||
void op_sta_long_b();
|
||||
void op_sta_long_w();
|
||||
|
||||
void op_sta_longx_b();
|
||||
void op_sta_longx_w();
|
||||
|
||||
|
||||
void op_sta_dp_b();
|
||||
void op_sta_dp_w();
|
||||
|
||||
void op_stx_dp_b();
|
||||
void op_stx_dp_w();
|
||||
|
||||
void op_sty_dp_b();
|
||||
void op_sty_dp_w();
|
||||
|
||||
void op_stz_dp_b();
|
||||
void op_stz_dp_w();
|
||||
|
||||
|
||||
void op_sta_dpr_b();
|
||||
void op_sta_dpr_w();
|
||||
|
||||
void op_stx_dpr_b();
|
||||
void op_stx_dpr_w();
|
||||
|
||||
void op_sty_dpr_b();
|
||||
void op_sty_dpr_w();
|
||||
|
||||
void op_stz_dpr_b();
|
||||
void op_stz_dpr_w();
|
||||
|
||||
|
||||
void op_sta_idp_b();
|
||||
void op_sta_idp_w();
|
||||
|
||||
void op_sta_ildp_b();
|
||||
void op_sta_ildp_w();
|
||||
|
||||
void op_sta_idpx_b();
|
||||
void op_sta_idpx_w();
|
||||
|
||||
void op_sta_idpy_b();
|
||||
void op_sta_idpy_w();
|
||||
|
||||
void op_sta_ildpy_b();
|
||||
void op_sta_ildpy_w();
|
||||
|
||||
void op_sta_sr_b();
|
||||
void op_sta_sr_w();
|
||||
|
||||
void op_sta_isry_b();
|
||||
void op_sta_isry_w();
|
||||
|
||||
|
||||
//==============
|
||||
//opcode_rmw.bpp
|
||||
//==============
|
||||
|
||||
void op_inc_imm_b();
|
||||
void op_inc_imm_w();
|
||||
|
||||
void op_inx_imm_b();
|
||||
void op_inx_imm_w();
|
||||
|
||||
void op_iny_imm_b();
|
||||
void op_iny_imm_w();
|
||||
|
||||
void op_dec_imm_b();
|
||||
void op_dec_imm_w();
|
||||
|
||||
void op_dex_imm_b();
|
||||
void op_dex_imm_w();
|
||||
|
||||
void op_dey_imm_b();
|
||||
void op_dey_imm_w();
|
||||
|
||||
|
||||
void op_asl_imm_b();
|
||||
void op_asl_imm_w();
|
||||
|
||||
void op_lsr_imm_b();
|
||||
void op_lsr_imm_w();
|
||||
|
||||
void op_rol_imm_b();
|
||||
void op_rol_imm_w();
|
||||
|
||||
void op_ror_imm_b();
|
||||
void op_ror_imm_w();
|
||||
|
||||
|
||||
void op_inc_addr_b();
|
||||
void op_inc_addr_w();
|
||||
|
||||
void op_dec_addr_b();
|
||||
void op_dec_addr_w();
|
||||
|
||||
void op_asl_addr_b();
|
||||
void op_asl_addr_w();
|
||||
|
||||
void op_lsr_addr_b();
|
||||
void op_lsr_addr_w();
|
||||
|
||||
void op_rol_addr_b();
|
||||
void op_rol_addr_w();
|
||||
|
||||
void op_ror_addr_b();
|
||||
void op_ror_addr_w();
|
||||
|
||||
void op_trb_addr_b();
|
||||
void op_trb_addr_w();
|
||||
|
||||
void op_tsb_addr_b();
|
||||
void op_tsb_addr_w();
|
||||
|
||||
|
||||
void op_inc_addrx_b();
|
||||
void op_inc_addrx_w();
|
||||
|
||||
void op_dec_addrx_b();
|
||||
void op_dec_addrx_w();
|
||||
|
||||
void op_asl_addrx_b();
|
||||
void op_asl_addrx_w();
|
||||
|
||||
void op_lsr_addrx_b();
|
||||
void op_lsr_addrx_w();
|
||||
|
||||
void op_rol_addrx_b();
|
||||
void op_rol_addrx_w();
|
||||
|
||||
void op_ror_addrx_b();
|
||||
void op_ror_addrx_w();
|
||||
|
||||
|
||||
void op_inc_dp_b();
|
||||
void op_inc_dp_w();
|
||||
|
||||
void op_dec_dp_b();
|
||||
void op_dec_dp_w();
|
||||
|
||||
void op_asl_dp_b();
|
||||
void op_asl_dp_w();
|
||||
|
||||
void op_lsr_dp_b();
|
||||
void op_lsr_dp_w();
|
||||
|
||||
void op_rol_dp_b();
|
||||
void op_rol_dp_w();
|
||||
|
||||
void op_ror_dp_b();
|
||||
void op_ror_dp_w();
|
||||
|
||||
void op_trb_dp_b();
|
||||
void op_trb_dp_w();
|
||||
|
||||
void op_tsb_dp_b();
|
||||
void op_tsb_dp_w();
|
||||
|
||||
|
||||
void op_inc_dpx_b();
|
||||
void op_inc_dpx_w();
|
||||
|
||||
void op_dec_dpx_b();
|
||||
void op_dec_dpx_w();
|
||||
|
||||
void op_asl_dpx_b();
|
||||
void op_asl_dpx_w();
|
||||
|
||||
void op_lsr_dpx_b();
|
||||
void op_lsr_dpx_w();
|
||||
|
||||
void op_rol_dpx_b();
|
||||
void op_rol_dpx_w();
|
||||
|
||||
void op_ror_dpx_b();
|
||||
void op_ror_dpx_w();
|
||||
|
||||
|
||||
//=============
|
||||
//opcode_pc.bpp
|
||||
//=============
|
||||
|
||||
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_e();
|
||||
void op_jsr_long_n();
|
||||
|
||||
void op_jsr_iaddrx_e();
|
||||
void op_jsr_iaddrx_n();
|
||||
|
||||
void op_rti_e();
|
||||
void op_rti_n();
|
||||
|
||||
void op_rts();
|
||||
|
||||
void op_rtl_e();
|
||||
void op_rtl_n();
|
||||
|
||||
|
||||
//===============
|
||||
//opcode_misc.bpp
|
||||
//===============
|
||||
|
||||
void op_nop();
|
||||
|
||||
void op_wdm();
|
||||
|
||||
void op_xba();
|
||||
|
||||
|
||||
void op_mvn_b();
|
||||
void op_mvn_w();
|
||||
|
||||
void op_mvp_b();
|
||||
void op_mvp_w();
|
||||
|
||||
|
||||
void op_brk_e();
|
||||
void op_brk_n();
|
||||
|
||||
void op_cop_e();
|
||||
void op_cop_n();
|
||||
|
||||
|
||||
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_e();
|
||||
void op_rep_n();
|
||||
|
||||
void op_sep_e();
|
||||
void op_sep_n();
|
||||
|
||||
|
||||
void op_tax_b();
|
||||
void op_tax_w();
|
||||
|
||||
void op_tay_b();
|
||||
void op_tay_w();
|
||||
|
||||
void op_txa_b();
|
||||
void op_txa_w();
|
||||
|
||||
void op_txy_b();
|
||||
void op_txy_w();
|
||||
|
||||
void op_tya_b();
|
||||
void op_tya_w();
|
||||
|
||||
void op_tyx_b();
|
||||
void op_tyx_w();
|
||||
|
||||
|
||||
void op_tcd();
|
||||
|
||||
void op_tdc();
|
||||
|
||||
|
||||
void op_tcs_e();
|
||||
void op_tcs_n();
|
||||
|
||||
void op_tsc_e();
|
||||
void op_tsc_n();
|
||||
|
||||
void op_tsx_b();
|
||||
void op_tsx_w();
|
||||
|
||||
void op_txs_e();
|
||||
void op_txs_n();
|
||||
|
||||
|
||||
void op_pha_b();
|
||||
void op_pha_w();
|
||||
|
||||
void op_phx_b();
|
||||
void op_phx_w();
|
||||
|
||||
void op_phy_b();
|
||||
void op_phy_w();
|
||||
|
||||
void op_phd_e();
|
||||
void op_phd_n();
|
||||
|
||||
void op_phb();
|
||||
|
||||
void op_phk();
|
||||
|
||||
void op_php();
|
||||
|
||||
|
||||
void op_pla_b();
|
||||
void op_pla_w();
|
||||
|
||||
void op_plx_b();
|
||||
void op_plx_w();
|
||||
|
||||
void op_ply_b();
|
||||
void op_ply_w();
|
||||
|
||||
void op_pld_e();
|
||||
void op_pld_n();
|
||||
|
||||
void op_plb();
|
||||
|
||||
void op_plp_e();
|
||||
void op_plp_n();
|
||||
|
||||
|
||||
void op_pea_e();
|
||||
void op_pea_n();
|
||||
|
||||
void op_pei_e();
|
||||
void op_pei_n();
|
||||
|
||||
void op_per_e();
|
||||
void op_per_n();
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,317 @@
|
|||
//===============
|
||||
//opcode_read.bpp
|
||||
//===============
|
||||
|
||||
@op_read_const(adc)
|
||||
@op_read_const(and)
|
||||
@op_read_const(cmp)
|
||||
@op_read_const(cpx)
|
||||
@op_read_const(cpy)
|
||||
@op_read_const(eor)
|
||||
@op_read_const(lda)
|
||||
@op_read_const(ldx)
|
||||
@op_read_const(ldy)
|
||||
@op_read_const(ora)
|
||||
@op_read_const(sbc)
|
||||
|
||||
@op_read_bit_const()
|
||||
|
||||
@op_read_addr(adc)
|
||||
@op_read_addr(and)
|
||||
@op_read_addr(bit)
|
||||
@op_read_addr(cmp)
|
||||
@op_read_addr(cpx)
|
||||
@op_read_addr(cpy)
|
||||
@op_read_addr(eor)
|
||||
@op_read_addr(lda)
|
||||
@op_read_addr(ldx)
|
||||
@op_read_addr(ldy)
|
||||
@op_read_addr(ora)
|
||||
@op_read_addr(sbc)
|
||||
|
||||
@op_read_addrx(adc)
|
||||
@op_read_addrx(and)
|
||||
@op_read_addrx(bit)
|
||||
@op_read_addrx(cmp)
|
||||
@op_read_addrx(eor)
|
||||
@op_read_addrx(lda)
|
||||
@op_read_addrx(ldy)
|
||||
@op_read_addrx(ora)
|
||||
@op_read_addrx(sbc)
|
||||
|
||||
@op_read_addry(adc)
|
||||
@op_read_addry(and)
|
||||
@op_read_addry(cmp)
|
||||
@op_read_addry(eor)
|
||||
@op_read_addry(lda)
|
||||
@op_read_addry(ldx)
|
||||
@op_read_addry(ora)
|
||||
@op_read_addry(sbc)
|
||||
|
||||
@op_read_long(adc)
|
||||
@op_read_long(and)
|
||||
@op_read_long(cmp)
|
||||
@op_read_long(eor)
|
||||
@op_read_long(lda)
|
||||
@op_read_long(ora)
|
||||
@op_read_long(sbc)
|
||||
|
||||
@op_read_longx(adc)
|
||||
@op_read_longx(and)
|
||||
@op_read_longx(cmp)
|
||||
@op_read_longx(eor)
|
||||
@op_read_longx(lda)
|
||||
@op_read_longx(ora)
|
||||
@op_read_longx(sbc)
|
||||
|
||||
@op_read_dp(adc)
|
||||
@op_read_dp(and)
|
||||
@op_read_dp(bit)
|
||||
@op_read_dp(cmp)
|
||||
@op_read_dp(cpx)
|
||||
@op_read_dp(cpy)
|
||||
@op_read_dp(eor)
|
||||
@op_read_dp(lda)
|
||||
@op_read_dp(ldx)
|
||||
@op_read_dp(ldy)
|
||||
@op_read_dp(ora)
|
||||
@op_read_dp(sbc)
|
||||
|
||||
@op_read_dpr(adc, x)
|
||||
@op_read_dpr(and, x)
|
||||
@op_read_dpr(bit, x)
|
||||
@op_read_dpr(cmp, x)
|
||||
@op_read_dpr(eor, x)
|
||||
@op_read_dpr(lda, x)
|
||||
@op_read_dpr(ldx, y)
|
||||
@op_read_dpr(ldy, x)
|
||||
@op_read_dpr(ora, x)
|
||||
@op_read_dpr(sbc, x)
|
||||
|
||||
@op_read_idp(adc)
|
||||
@op_read_idp(and)
|
||||
@op_read_idp(cmp)
|
||||
@op_read_idp(eor)
|
||||
@op_read_idp(lda)
|
||||
@op_read_idp(ora)
|
||||
@op_read_idp(sbc)
|
||||
|
||||
@op_read_idpx(adc)
|
||||
@op_read_idpx(and)
|
||||
@op_read_idpx(cmp)
|
||||
@op_read_idpx(eor)
|
||||
@op_read_idpx(lda)
|
||||
@op_read_idpx(ora)
|
||||
@op_read_idpx(sbc)
|
||||
|
||||
@op_read_idpy(adc)
|
||||
@op_read_idpy(and)
|
||||
@op_read_idpy(cmp)
|
||||
@op_read_idpy(eor)
|
||||
@op_read_idpy(lda)
|
||||
@op_read_idpy(ora)
|
||||
@op_read_idpy(sbc)
|
||||
|
||||
@op_read_ildp(adc)
|
||||
@op_read_ildp(and)
|
||||
@op_read_ildp(cmp)
|
||||
@op_read_ildp(eor)
|
||||
@op_read_ildp(lda)
|
||||
@op_read_ildp(ora)
|
||||
@op_read_ildp(sbc)
|
||||
|
||||
@op_read_ildpy(adc)
|
||||
@op_read_ildpy(and)
|
||||
@op_read_ildpy(cmp)
|
||||
@op_read_ildpy(eor)
|
||||
@op_read_ildpy(lda)
|
||||
@op_read_ildpy(ora)
|
||||
@op_read_ildpy(sbc)
|
||||
|
||||
@op_read_sr(adc)
|
||||
@op_read_sr(and)
|
||||
@op_read_sr(cmp)
|
||||
@op_read_sr(eor)
|
||||
@op_read_sr(lda)
|
||||
@op_read_sr(ora)
|
||||
@op_read_sr(sbc)
|
||||
|
||||
@op_read_isry(adc)
|
||||
@op_read_isry(and)
|
||||
@op_read_isry(cmp)
|
||||
@op_read_isry(eor)
|
||||
@op_read_isry(lda)
|
||||
@op_read_isry(ora)
|
||||
@op_read_isry(sbc)
|
||||
|
||||
//================
|
||||
//opcode_write.bpp
|
||||
//================
|
||||
|
||||
@op_store_addr(sta, regs.a.w)
|
||||
@op_store_addr(stx, regs.x.w)
|
||||
@op_store_addr(sty, regs.y.w)
|
||||
@op_store_addr(stz, 0x0000)
|
||||
|
||||
@op_store_addrr(sta, x, regs.a.w, regs.x.w)
|
||||
@op_store_addrr(sta, y, regs.a.w, regs.y.w)
|
||||
@op_store_addrr(stz, x, 0x0000, regs.x.w)
|
||||
|
||||
@op_store_longr(sta, , 0x0000)
|
||||
@op_store_longr(sta, x, regs.x.w)
|
||||
|
||||
@op_store_dp(sta, regs.a.w)
|
||||
@op_store_dp(stx, regs.x.w)
|
||||
@op_store_dp(sty, regs.y.w)
|
||||
@op_store_dp(stz, 0x0000)
|
||||
|
||||
@op_store_dpr(sta, regs.a.w, x)
|
||||
@op_store_dpr(stx, regs.x.w, y)
|
||||
@op_store_dpr(sty, regs.y.w, x)
|
||||
@op_store_dpr(stz, 0x0000, x)
|
||||
|
||||
@op_sta_idp()
|
||||
@op_sta_ildp()
|
||||
@op_sta_idpx()
|
||||
@op_sta_idpy()
|
||||
@op_sta_ildpy()
|
||||
@op_sta_sr()
|
||||
@op_sta_isry()
|
||||
|
||||
//==============
|
||||
//opcode_rmw.bpp
|
||||
//==============
|
||||
|
||||
@op_adjust(inc, a, ++)
|
||||
@op_adjust(inx, x, ++)
|
||||
@op_adjust(iny, y, ++)
|
||||
@op_adjust(dec, a, --)
|
||||
@op_adjust(dex, x, --)
|
||||
@op_adjust(dey, y, --)
|
||||
|
||||
@op_asl()
|
||||
@op_lsr()
|
||||
@op_rol()
|
||||
@op_ror()
|
||||
|
||||
@op_adjust_addr(inc)
|
||||
@op_adjust_addr(dec)
|
||||
@op_adjust_addr(asl)
|
||||
@op_adjust_addr(lsr)
|
||||
@op_adjust_addr(rol)
|
||||
@op_adjust_addr(ror)
|
||||
@op_adjust_addr(trb)
|
||||
@op_adjust_addr(tsb)
|
||||
|
||||
@op_adjust_addrx(inc)
|
||||
@op_adjust_addrx(dec)
|
||||
@op_adjust_addrx(asl)
|
||||
@op_adjust_addrx(lsr)
|
||||
@op_adjust_addrx(rol)
|
||||
@op_adjust_addrx(ror)
|
||||
|
||||
@op_adjust_dp(inc)
|
||||
@op_adjust_dp(dec)
|
||||
@op_adjust_dp(asl)
|
||||
@op_adjust_dp(lsr)
|
||||
@op_adjust_dp(rol)
|
||||
@op_adjust_dp(ror)
|
||||
@op_adjust_dp(trb)
|
||||
@op_adjust_dp(tsb)
|
||||
|
||||
@op_adjust_dpx(inc)
|
||||
@op_adjust_dpx(dec)
|
||||
@op_adjust_dpx(asl)
|
||||
@op_adjust_dpx(lsr)
|
||||
@op_adjust_dpx(rol)
|
||||
@op_adjust_dpx(ror)
|
||||
|
||||
//=============
|
||||
//opcode_pc.bpp
|
||||
//=============
|
||||
|
||||
@op_branch(bcc, !regs.p.c)
|
||||
@op_branch(bcs, regs.p.c)
|
||||
@op_branch(bne, !regs.p.z)
|
||||
@op_branch(beq, regs.p.z)
|
||||
@op_branch(bpl, !regs.p.n)
|
||||
@op_branch(bmi, regs.p.n)
|
||||
@op_branch(bvc, !regs.p.v)
|
||||
@op_branch(bvs, regs.p.v)
|
||||
|
||||
@op_bra()
|
||||
@op_brl()
|
||||
@op_jmp_addr()
|
||||
@op_jmp_long()
|
||||
@op_jmp_iaddr()
|
||||
@op_jmp_iaddrx()
|
||||
@op_jmp_iladdr()
|
||||
@op_jsr_addr()
|
||||
@op_jsr_long()
|
||||
@op_jsr_iaddrx()
|
||||
@op_rti()
|
||||
@op_rts()
|
||||
@op_rtl()
|
||||
|
||||
//===============
|
||||
//opcode_misc.bpp
|
||||
//===============
|
||||
|
||||
@op_nop()
|
||||
@op_wdm()
|
||||
@op_xba()
|
||||
|
||||
@op_move(mvn, ++)
|
||||
@op_move(mvp, --)
|
||||
|
||||
@op_interrupt(brk, 0xfffe, 0xffe6)
|
||||
@op_interrupt(cop, 0xfff4, 0xffe4)
|
||||
|
||||
@op_stp()
|
||||
@op_wai()
|
||||
@op_xce()
|
||||
|
||||
@op_flag(clc, regs.p.c = 0)
|
||||
@op_flag(cld, regs.p.d = 0)
|
||||
@op_flag(cli, regs.p.i = 0)
|
||||
@op_flag(clv, regs.p.v = 0)
|
||||
@op_flag(sec, regs.p.c = 1)
|
||||
@op_flag(sed, regs.p.d = 1)
|
||||
@op_flag(sei, regs.p.i = 1)
|
||||
|
||||
@op_pflag(rep, &=~)
|
||||
@op_pflag(sep, |=)
|
||||
|
||||
@op_transfer(tax, a, x)
|
||||
@op_transfer(tay, a, y)
|
||||
@op_transfer(txa, x, a)
|
||||
@op_transfer(txy, x, y)
|
||||
@op_transfer(tya, y, a)
|
||||
@op_transfer(tyx, y, x)
|
||||
|
||||
@op_transfer_word(tcd, a, d)
|
||||
@op_transfer_word(tdc, d, a)
|
||||
|
||||
@op_tcs()
|
||||
@op_tsc()
|
||||
@op_tsx()
|
||||
@op_txs()
|
||||
|
||||
@op_push(pha, a)
|
||||
@op_push(phx, x)
|
||||
@op_push(phy, y)
|
||||
@op_phd()
|
||||
@op_push_byte(phb, regs.db)
|
||||
@op_push_byte(phk, regs.pc.b)
|
||||
@op_push_byte(php, regs.p)
|
||||
|
||||
@op_pull(pla, a)
|
||||
@op_pull(plx, x)
|
||||
@op_pull(ply, y)
|
||||
@op_pld()
|
||||
@op_plb()
|
||||
@op_plp()
|
||||
|
||||
@op_pea()
|
||||
@op_pei()
|
||||
@op_per()
|
|
@ -0,0 +1,397 @@
|
|||
@macro op_nop()
|
||||
void {class}::op_nop() {
|
||||
{lc}op_io_irq();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_wdm()
|
||||
void {class}::op_wdm() {
|
||||
{lc}op_readpc();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_xba()
|
||||
void {class}::op_xba() {
|
||||
op_io();
|
||||
{lc}op_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);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_move(name, op)
|
||||
void {class}::op_{name}_b() {
|
||||
dp = op_readpc();
|
||||
sp = op_readpc();
|
||||
regs.db = dp;
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
op_io();
|
||||
regs.x.l {op};
|
||||
regs.y.l {op};
|
||||
{lc}op_io();
|
||||
if(regs.a.w--) regs.pc.w -= 3;
|
||||
}
|
||||
|
||||
void {class}::op_{name}_w() {
|
||||
dp = op_readpc();
|
||||
sp = op_readpc();
|
||||
regs.db = dp;
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
op_io();
|
||||
regs.x.w {op};
|
||||
regs.y.w {op};
|
||||
{lc}op_io();
|
||||
if(regs.a.w--) regs.pc.w -= 3;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_interrupt(name, vectorE, vectorN)
|
||||
void {class}::op_{name}_e() {
|
||||
op_readpc();
|
||||
op_writestack(regs.pc.h);
|
||||
op_writestack(regs.pc.l);
|
||||
op_writestack(regs.p);
|
||||
rd.l = op_readlong({vectorE} + 0);
|
||||
regs.pc.b = 0;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
{lc}rd.h = op_readlong({vectorE} + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
void {class}::op_{name}_n() {
|
||||
op_readpc();
|
||||
op_writestack(regs.pc.b);
|
||||
op_writestack(regs.pc.h);
|
||||
op_writestack(regs.pc.l);
|
||||
op_writestack(regs.p);
|
||||
rd.l = op_readlong({vectorN} + 0);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
{lc}rd.h = op_readlong({vectorN} + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_stp()
|
||||
void {class}::op_stp() {
|
||||
while({wai} = true) {
|
||||
{lc} op_io();
|
||||
}
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_wai()
|
||||
void {class}::op_wai() {
|
||||
{wai} = true;
|
||||
while({wai}) {
|
||||
{lc} op_io();
|
||||
}
|
||||
op_io();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_xce()
|
||||
void {class}::op_xce() {
|
||||
{lc}op_io_irq();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = regs.e;
|
||||
regs.e = carry;
|
||||
if(regs.e) {
|
||||
regs.p |= 0x30;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
update_table();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_flag(name, rule)
|
||||
void {class}::op_{name}() {
|
||||
{lc}op_io_irq();
|
||||
{rule};
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_pflag(name, op)
|
||||
void {class}::op_{name}_e() {
|
||||
rd.l = op_readpc();
|
||||
{lc}op_io();
|
||||
regs.p {op} rd.l;
|
||||
regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
update_table();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_n() {
|
||||
rd.l = op_readpc();
|
||||
{lc}op_io();
|
||||
regs.p {op} rd.l;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
update_table();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_transfer(name, from, to)
|
||||
void {class}::op_{name}_b() {
|
||||
{lc}op_io_irq();
|
||||
regs.{to}.l = regs.{from}.l;
|
||||
regs.p.n = (regs.{to}.l & 0x80);
|
||||
regs.p.z = (regs.{to}.l == 0);
|
||||
}
|
||||
|
||||
void {class}::op_{name}_w() {
|
||||
{lc}op_io_irq();
|
||||
regs.{to}.w = regs.{from}.w;
|
||||
regs.p.n = (regs.{to}.w & 0x8000);
|
||||
regs.p.z = (regs.{to}.w == 0);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_transfer_word(name, from, to)
|
||||
void {class}::op_{name}() {
|
||||
{lc}op_io_irq();
|
||||
regs.{to}.w = regs.{from}.w;
|
||||
regs.p.n = (regs.{to}.w & 0x8000);
|
||||
regs.p.z = (regs.{to}.w == 0);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_tcs()
|
||||
void {class}::op_tcs_e() {
|
||||
{lc}op_io_irq();
|
||||
regs.s.l = regs.a.l;
|
||||
}
|
||||
|
||||
void {class}::op_tcs_n() {
|
||||
{lc}op_io_irq();
|
||||
regs.s.w = regs.a.w;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_tsc()
|
||||
void {class}::op_tsc_e() {
|
||||
{lc}op_io_irq();
|
||||
regs.a.w = regs.s.w;
|
||||
regs.p.n = (regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void {class}::op_tsc_n() {
|
||||
{lc}op_io_irq();
|
||||
regs.a.w = regs.s.w;
|
||||
regs.p.n = (regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_tsx()
|
||||
void {class}::op_tsx_b() {
|
||||
{lc}op_io_irq();
|
||||
regs.x.l = regs.s.l;
|
||||
regs.p.n = (regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
}
|
||||
|
||||
void {class}::op_tsx_w() {
|
||||
{lc}op_io_irq();
|
||||
regs.x.w = regs.s.w;
|
||||
regs.p.n = (regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_txs()
|
||||
void {class}::op_txs_e() {
|
||||
{lc}op_io_irq();
|
||||
regs.s.l = regs.x.l;
|
||||
}
|
||||
|
||||
void {class}::op_txs_n() {
|
||||
{lc}op_io_irq();
|
||||
regs.s.w = regs.x.w;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_push(name, r)
|
||||
void {class}::op_{name}_b() {
|
||||
op_io();
|
||||
{lc}op_writestack(regs.{r}.l);
|
||||
}
|
||||
|
||||
void {class}::op_{name}_w() {
|
||||
op_io();
|
||||
op_writestack(regs.{r}.h);
|
||||
{lc}op_writestack(regs.{r}.l);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_phd()
|
||||
void {class}::op_phd_e() {
|
||||
op_io();
|
||||
op_writestackn(regs.d.h);
|
||||
{lc}op_writestackn(regs.d.l);
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void {class}::op_phd_n() {
|
||||
op_io();
|
||||
op_writestackn(regs.d.h);
|
||||
{lc}op_writestackn(regs.d.l);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_push_byte(name, r)
|
||||
void {class}::op_{name}() {
|
||||
op_io();
|
||||
{lc}op_writestack({r});
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_pull(name, r)
|
||||
void {class}::op_{name}_b() {
|
||||
op_io();
|
||||
op_io();
|
||||
{lc}regs.{r}.l = op_readstack();
|
||||
regs.p.n = (regs.{r}.l & 0x80);
|
||||
regs.p.z = (regs.{r}.l == 0);
|
||||
}
|
||||
|
||||
void {class}::op_{name}_w() {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.{r}.l = op_readstack();
|
||||
{lc}regs.{r}.h = op_readstack();
|
||||
regs.p.n = (regs.{r}.w & 0x8000);
|
||||
regs.p.z = (regs.{r}.w == 0);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_pld()
|
||||
void {class}::op_pld_e() {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.d.l = op_readstackn();
|
||||
{lc}regs.d.h = op_readstackn();
|
||||
regs.p.n = (regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void {class}::op_pld_n() {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.d.l = op_readstackn();
|
||||
{lc}regs.d.h = op_readstackn();
|
||||
regs.p.n = (regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_plb()
|
||||
void {class}::op_plb() {
|
||||
op_io();
|
||||
op_io();
|
||||
{lc}regs.db = op_readstack();
|
||||
regs.p.n = (regs.db & 0x80);
|
||||
regs.p.z = (regs.db == 0);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_plp()
|
||||
void {class}::op_plp_e() {
|
||||
op_io();
|
||||
op_io();
|
||||
{lc}regs.p = op_readstack() | 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
update_table();
|
||||
}
|
||||
|
||||
void {class}::op_plp_n() {
|
||||
op_io();
|
||||
op_io();
|
||||
{lc}regs.p = op_readstack();
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
update_table();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_pea()
|
||||
void {class}::op_pea_e() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_writestackn(aa.h);
|
||||
{lc}op_writestackn(aa.l);
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void {class}::op_pea_n() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_writestackn(aa.h);
|
||||
{lc}op_writestackn(aa.l);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_pei()
|
||||
void {class}::op_pei_e() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_writestackn(aa.h);
|
||||
{lc}op_writestackn(aa.l);
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void {class}::op_pei_n() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_writestackn(aa.h);
|
||||
{lc}op_writestackn(aa.l);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_per()
|
||||
void {class}::op_per_e() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.w = regs.pc.d + (int16_t)aa.w;
|
||||
op_writestackn(rd.h);
|
||||
{lc}op_writestackn(rd.l);
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void {class}::op_per_n() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.w = regs.pc.d + (int16_t)aa.w;
|
||||
op_writestackn(rd.h);
|
||||
{lc}op_writestackn(rd.l);
|
||||
}
|
||||
@endmacro
|
|
@ -0,0 +1,205 @@
|
|||
@macro op_branch(name, condition)
|
||||
void {class}::op_{name}() {
|
||||
if({condition} == false) {
|
||||
{lc} rd.l = op_readpc();
|
||||
} else {
|
||||
rd.l = op_readpc();
|
||||
aa.w = regs.pc.d + (int8_t)rd.l;
|
||||
op_io_cond6(aa.w);
|
||||
{lc} op_io();
|
||||
regs.pc.w = aa.w;
|
||||
}
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_bra()
|
||||
void {class}::op_bra() {
|
||||
rd.l = op_readpc();
|
||||
aa.w = regs.pc.d + (int8_t)rd.l;
|
||||
op_io_cond6(aa.w);
|
||||
{lc}op_io();
|
||||
regs.pc.w = aa.w;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_brl()
|
||||
void {class}::op_brl() {
|
||||
rd.l = op_readpc();
|
||||
rd.h = op_readpc();
|
||||
{lc}op_io();
|
||||
regs.pc.w = regs.pc.d + (int16_t)rd.w;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_jmp_addr()
|
||||
void {class}::op_jmp_addr() {
|
||||
rd.l = op_readpc();
|
||||
{lc}rd.h = op_readpc();
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_jmp_long()
|
||||
void {class}::op_jmp_long() {
|
||||
rd.l = op_readpc();
|
||||
rd.h = op_readpc();
|
||||
{lc}rd.b = op_readpc();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_jmp_iaddr()
|
||||
void {class}::op_jmp_iaddr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readaddr(aa.w + 0);
|
||||
{lc}rd.h = op_readaddr(aa.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_jmp_iaddrx()
|
||||
void {class}::op_jmp_iaddrx() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readpbr(aa.w + regs.x.w + 0);
|
||||
{lc}rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_jmp_iladdr()
|
||||
void {class}::op_jmp_iladdr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readaddr(aa.w + 0);
|
||||
rd.h = op_readaddr(aa.w + 1);
|
||||
{lc}rd.b = op_readaddr(aa.w + 2);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_jsr_addr()
|
||||
void {class}::op_jsr_addr() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
regs.pc.w--;
|
||||
op_writestack(regs.pc.h);
|
||||
{lc}op_writestack(regs.pc.l);
|
||||
regs.pc.w = aa.w;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_jsr_long()
|
||||
void {class}::op_jsr_long_e() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_writestackn(regs.pc.b);
|
||||
op_io();
|
||||
aa.b = op_readpc();
|
||||
regs.pc.w--;
|
||||
op_writestackn(regs.pc.h);
|
||||
{lc}op_writestackn(regs.pc.l);
|
||||
regs.pc.d = aa.d & 0xffffff;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void {class}::op_jsr_long_n() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_writestackn(regs.pc.b);
|
||||
op_io();
|
||||
aa.b = op_readpc();
|
||||
regs.pc.w--;
|
||||
op_writestackn(regs.pc.h);
|
||||
{lc}op_writestackn(regs.pc.l);
|
||||
regs.pc.d = aa.d & 0xffffff;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_jsr_iaddrx()
|
||||
void {class}::op_jsr_iaddrx_e() {
|
||||
aa.l = op_readpc();
|
||||
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 + 0);
|
||||
{lc}rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void {class}::op_jsr_iaddrx_n() {
|
||||
aa.l = op_readpc();
|
||||
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 + 0);
|
||||
{lc}rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_rti()
|
||||
void {class}::op_rti_e() {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.p = op_readstack() | 0x30;
|
||||
rd.l = op_readstack();
|
||||
{lc}rd.h = op_readstack();
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
void {class}::op_rti_n() {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.p = op_readstack();
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
rd.l = op_readstack();
|
||||
rd.h = op_readstack();
|
||||
{lc}rd.b = op_readstack();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
update_table();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_rts()
|
||||
void {class}::op_rts() {
|
||||
op_io();
|
||||
op_io();
|
||||
rd.l = op_readstack();
|
||||
rd.h = op_readstack();
|
||||
{lc}op_io();
|
||||
regs.pc.w = ++rd.w;
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_rtl()
|
||||
void {class}::op_rtl_e() {
|
||||
op_io();
|
||||
op_io();
|
||||
rd.l = op_readstackn();
|
||||
rd.h = op_readstackn();
|
||||
{lc}rd.b = op_readstackn();
|
||||
regs.pc.b = rd.b;
|
||||
regs.pc.w = ++rd.w;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
void {class}::op_rtl_n() {
|
||||
op_io();
|
||||
op_io();
|
||||
rd.l = op_readstackn();
|
||||
rd.h = op_readstackn();
|
||||
{lc}rd.b = op_readstackn();
|
||||
regs.pc.b = rd.b;
|
||||
regs.pc.w = ++rd.w;
|
||||
}
|
||||
@endmacro
|
|
@ -0,0 +1,307 @@
|
|||
@macro op_read_const(name)
|
||||
void {class}::op_{name}_const_b() {
|
||||
{lc}rd.l = op_readpc();
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_const_w() {
|
||||
rd.l = op_readpc();
|
||||
{lc}rd.h = op_readpc();
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_bit_const()
|
||||
void {class}::op_bit_const_b() {
|
||||
{lc}rd.l = op_readpc();
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
}
|
||||
|
||||
void {class}::op_bit_const_w() {
|
||||
rd.l = op_readpc();
|
||||
{lc}rd.h = op_readpc();
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_addr(name)
|
||||
void {class}::op_{name}_addr_b() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
{lc}rd.l = op_readdbr(aa.w);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_addr_w() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w + 0);
|
||||
{lc}rd.h = op_readdbr(aa.w + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_addrx(name)
|
||||
void {class}::op_{name}_addrx_b() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io_cond4(aa.w, aa.w + regs.x.w);
|
||||
{lc}rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_addrx_w() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io_cond4(aa.w, aa.w + regs.x.w);
|
||||
rd.l = op_readdbr(aa.w + regs.x.w + 0);
|
||||
{lc}rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_addry(name)
|
||||
void {class}::op_{name}_addry_b() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io_cond4(aa.w, aa.w + regs.y.w);
|
||||
{lc}rd.l = op_readdbr(aa.w + regs.y.w);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_addry_w() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io_cond4(aa.w, aa.w + regs.y.w);
|
||||
rd.l = op_readdbr(aa.w + regs.y.w + 0);
|
||||
{lc}rd.h = op_readdbr(aa.w + regs.y.w + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_long(name)
|
||||
void {class}::op_{name}_long_b() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
aa.b = op_readpc();
|
||||
{lc}rd.l = op_readlong(aa.d);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_long_w() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
aa.b = op_readpc();
|
||||
rd.l = op_readlong(aa.d + 0);
|
||||
{lc}rd.h = op_readlong(aa.d + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_longx(name)
|
||||
void {class}::op_{name}_longx_b() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
aa.b = op_readpc();
|
||||
{lc}rd.l = op_readlong(aa.d + regs.x.w);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_longx_w() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
aa.b = op_readpc();
|
||||
rd.l = op_readlong(aa.d + regs.x.w + 0);
|
||||
{lc}rd.h = op_readlong(aa.d + regs.x.w + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_dp(name)
|
||||
void {class}::op_{name}_dp_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
{lc}rd.l = op_readdp(dp);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_dp_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp + 0);
|
||||
{lc}rd.h = op_readdp(dp + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_dpr(name, r)
|
||||
void {class}::op_{name}_dpr_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
{lc}rd.l = op_readdp(dp + regs.{r}.w);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_dpr_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
{lc}rd.l = op_readdp(dp + regs.{r}.w + 0);
|
||||
rd.h = op_readdp(dp + regs.{r}.w + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_idp(name)
|
||||
void {class}::op_{name}_idp_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
{lc}rd.l = op_readdbr(aa.w);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_idp_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
rd.l = op_readdbr(aa.w + 0);
|
||||
{lc}rd.h = op_readdbr(aa.w + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_idpx(name)
|
||||
void {class}::op_{name}_idpx_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
aa.l = op_readdp(dp + regs.x.w + 0);
|
||||
aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
{lc}rd.l = op_readdbr(aa.w);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_idpx_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
aa.l = op_readdp(dp + regs.x.w + 0);
|
||||
aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
rd.l = op_readdbr(aa.w + 0);
|
||||
{lc}rd.h = op_readdbr(aa.w + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_idpy(name)
|
||||
void {class}::op_{name}_idpy_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_io_cond4(aa.w, aa.w + regs.y.w);
|
||||
{lc}rd.l = op_readdbr(aa.w + regs.y.w);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_idpy_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_io_cond4(aa.w, aa.w + regs.y.w);
|
||||
rd.l = op_readdbr(aa.w + regs.y.w + 0);
|
||||
{lc}rd.h = op_readdbr(aa.w + regs.y.w + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_ildp(name)
|
||||
void {class}::op_{name}_ildp_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
{lc}rd.l = op_readlong(aa.d);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_ildp_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
rd.l = op_readlong(aa.d + 0);
|
||||
{lc}rd.h = op_readlong(aa.d + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_ildpy(name)
|
||||
void {class}::op_{name}_ildpy_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
{lc}rd.l = op_readlong(aa.d + regs.y.w);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_ildpy_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
rd.l = op_readlong(aa.d + regs.y.w + 0);
|
||||
{lc}rd.h = op_readlong(aa.d + regs.y.w + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_sr(name)
|
||||
void {class}::op_{name}_sr_b() {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
{lc}rd.l = op_readsp(sp);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_sr_w() {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readsp(sp + 0);
|
||||
{lc}rd.h = op_readsp(sp + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_read_isry(name)
|
||||
void {class}::op_{name}_isry_b() {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
aa.l = op_readsp(sp + 0);
|
||||
aa.h = op_readsp(sp + 1);
|
||||
op_io();
|
||||
{lc}rd.l = op_readdbr(aa.w + regs.y.w);
|
||||
op_{name}_b();
|
||||
}
|
||||
|
||||
void {class}::op_{name}_isry_w() {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
aa.l = op_readsp(sp + 0);
|
||||
aa.h = op_readsp(sp + 1);
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.y.w + 0);
|
||||
{lc}rd.h = op_readdbr(aa.w + regs.y.w + 1);
|
||||
op_{name}_w();
|
||||
}
|
||||
@endmacro
|
|
@ -0,0 +1,183 @@
|
|||
@macro op_adjust(name, r, op)
|
||||
void {class}::op_{name}_imm_b() {
|
||||
{lc}op_io_irq();
|
||||
regs.{r}.l {op};
|
||||
regs.p.n = (regs.{r}.l & 0x80);
|
||||
regs.p.z = (regs.{r}.l == 0);
|
||||
}
|
||||
|
||||
void {class}::op_{name}_imm_w() {
|
||||
{lc}op_io_irq();
|
||||
regs.{r}.w {op};
|
||||
regs.p.n = (regs.{r}.w & 0x8000);
|
||||
regs.p.z = (regs.{r}.w == 0);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_asl()
|
||||
void {class}::op_asl_imm_b() {
|
||||
{lc}op_io_irq();
|
||||
regs.p.c = (regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.p.n = (regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void {class}::op_asl_imm_w() {
|
||||
{lc}op_io_irq();
|
||||
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);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_lsr()
|
||||
void {class}::op_lsr_imm_b() {
|
||||
{lc}op_io_irq();
|
||||
regs.p.c = (regs.a.l & 0x01);
|
||||
regs.a.l >>= 1;
|
||||
regs.p.n = (regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void {class}::op_lsr_imm_w() {
|
||||
{lc}op_io_irq();
|
||||
regs.p.c = (regs.a.w & 0x0001);
|
||||
regs.a.w >>= 1;
|
||||
regs.p.n = (regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_rol()
|
||||
void {class}::op_rol_imm_b() {
|
||||
{lc}op_io_irq();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = (regs.a.l & 0x80);
|
||||
regs.a.l = (regs.a.l << 1) | carry;
|
||||
regs.p.n = (regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void {class}::op_rol_imm_w() {
|
||||
{lc}op_io_irq();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = (regs.a.w & 0x8000);
|
||||
regs.a.w = (regs.a.w << 1) | carry;
|
||||
regs.p.n = (regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_ror()
|
||||
void {class}::op_ror_imm_b() {
|
||||
{lc}op_io_irq();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = (regs.a.l & 0x01);
|
||||
regs.a.l = (carry << 7) | (regs.a.l >> 1);
|
||||
regs.p.n = (regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
void {class}::op_ror_imm_w() {
|
||||
{lc}op_io_irq();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = (regs.a.w & 0x0001);
|
||||
regs.a.w = (carry << 15) | (regs.a.w >> 1);
|
||||
regs.p.n = (regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_adjust_addr(name)
|
||||
void {class}::op_{name}_addr_b() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
op_io();
|
||||
op_{name}_b();
|
||||
{lc}op_writedbr(aa.w, rd.l);
|
||||
}
|
||||
|
||||
void {class}::op_{name}_addr_w() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w + 0);
|
||||
rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
op_{name}_w();
|
||||
op_writedbr(aa.w + 1, rd.h);
|
||||
{lc}op_writedbr(aa.w + 0, rd.l);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_adjust_addrx(name)
|
||||
void {class}::op_{name}_addrx_b() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
op_io();
|
||||
op_{name}_b();
|
||||
{lc}op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void {class}::op_{name}_addrx_w() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w + 0);
|
||||
rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
op_{name}_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h);
|
||||
{lc}op_writedbr(aa.w + regs.x.w + 0, rd.l);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_adjust_dp(name)
|
||||
void {class}::op_{name}_dp_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
op_io();
|
||||
op_{name}_b();
|
||||
{lc}op_writedp(dp, rd.l);
|
||||
}
|
||||
|
||||
void {class}::op_{name}_dp_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp + 0);
|
||||
rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
op_{name}_w();
|
||||
op_writedp(dp + 1, rd.h);
|
||||
{lc}op_writedp(dp + 0, rd.l);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_adjust_dpx(name)
|
||||
void {class}::op_{name}_dpx_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
op_io();
|
||||
op_{name}_b();
|
||||
{lc}op_writedp(dp + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
void {class}::op_{name}_dpx_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w + 0);
|
||||
rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
op_{name}_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h);
|
||||
{lc}op_writedp(dp + regs.x.w + 0, rd.l);
|
||||
}
|
||||
@endmacro
|
|
@ -0,0 +1,138 @@
|
|||
void CPUcore::initialize_opcode_table() {
|
||||
for(unsigned i = 0; i < 256 * 5; i++) op_table[i] = 0;
|
||||
|
||||
//same implementation for all processor states
|
||||
#define opA(id, name) \
|
||||
op_table[table_EM + id] = &sCPU::op_ ## name; \
|
||||
op_table[table_MX + id] = &sCPU::op_ ## name; \
|
||||
op_table[table_Mx + id] = &sCPU::op_ ## name; \
|
||||
op_table[table_mX + id] = &sCPU::op_ ## name; \
|
||||
op_table[table_mx + id] = &sCPU::op_ ## name;
|
||||
|
||||
//implementation changes based on E processor state
|
||||
#define opE(id, name) \
|
||||
op_table[table_EM + id] = &sCPU::op_ ## name ## _e; \
|
||||
op_table[table_MX + id] = &sCPU::op_ ## name ## _n; \
|
||||
op_table[table_Mx + id] = &sCPU::op_ ## name ## _n; \
|
||||
op_table[table_mX + id] = &sCPU::op_ ## name ## _n; \
|
||||
op_table[table_mx + id] = &sCPU::op_ ## name ## _n; \
|
||||
|
||||
//implementation changes based on M processor state
|
||||
#define opM(id, name) \
|
||||
op_table[table_EM + id] = &sCPU::op_ ## name ## _b; \
|
||||
op_table[table_MX + id] = &sCPU::op_ ## name ## _b; \
|
||||
op_table[table_Mx + id] = &sCPU::op_ ## name ## _b; \
|
||||
op_table[table_mX + id] = &sCPU::op_ ## name ## _w; \
|
||||
op_table[table_mx + id] = &sCPU::op_ ## name ## _w;
|
||||
|
||||
//implementation changes based on X processor state
|
||||
#define opX(id, name) \
|
||||
op_table[table_EM + id] = &sCPU::op_ ## name ## _b; \
|
||||
op_table[table_MX + id] = &sCPU::op_ ## name ## _b; \
|
||||
op_table[table_Mx + id] = &sCPU::op_ ## name ## _w; \
|
||||
op_table[table_mX + id] = &sCPU::op_ ## name ## _b; \
|
||||
op_table[table_mx + id] = &sCPU::op_ ## name ## _w;
|
||||
|
||||
opE(0x00, brk) opM(0x01, ora_idpx) opE(0x02, cop) opM(0x03, ora_sr)
|
||||
opM(0x04, tsb_dp) opM(0x05, ora_dp) opM(0x06, asl_dp) opM(0x07, ora_ildp)
|
||||
opA(0x08, php) opM(0x09, ora_const) opM(0x0a, asl_imm) opE(0x0b, phd)
|
||||
opM(0x0c, tsb_addr) opM(0x0d, ora_addr) opM(0x0e, asl_addr) opM(0x0f, ora_long)
|
||||
|
||||
opA(0x10, bpl) opM(0x11, ora_idpy) opM(0x12, ora_idp) opM(0x13, ora_isry)
|
||||
opM(0x14, trb_dp) opM(0x15, ora_dpr) opM(0x16, asl_dpx) opM(0x17, ora_ildpy)
|
||||
opA(0x18, clc) opM(0x19, ora_addry) opM(0x1a, inc_imm) opE(0x1b, tcs)
|
||||
opM(0x1c, trb_addr) opM(0x1d, ora_addrx) opM(0x1e, asl_addrx) opM(0x1f, ora_longx)
|
||||
|
||||
opA(0x20, jsr_addr) opM(0x21, and_idpx) opE(0x22, jsr_long) opM(0x23, and_sr)
|
||||
opM(0x24, bit_dp) opM(0x25, and_dp) opM(0x26, rol_dp) opM(0x27, and_ildp)
|
||||
opE(0x28, plp) opM(0x29, and_const) opM(0x2a, rol_imm) opE(0x2b, pld)
|
||||
opM(0x2c, bit_addr) opM(0x2d, and_addr) opM(0x2e, rol_addr) opM(0x2f, and_long)
|
||||
|
||||
opA(0x30, bmi) opM(0x31, and_idpy) opM(0x32, and_idp) opM(0x33, and_isry)
|
||||
opM(0x34, bit_dpr) opM(0x35, and_dpr) opM(0x36, rol_dpx) opM(0x37, and_ildpy)
|
||||
opA(0x38, sec) opM(0x39, and_addry) opM(0x3a, dec_imm) opE(0x3b, tsc)
|
||||
opM(0x3c, bit_addrx) opM(0x3d, and_addrx) opM(0x3e, rol_addrx) opM(0x3f, and_longx)
|
||||
|
||||
opE(0x40, rti) opM(0x41, eor_idpx) opA(0x42, wdm) opM(0x43, eor_sr)
|
||||
opX(0x44, mvp) opM(0x45, eor_dp) opM(0x46, lsr_dp) opM(0x47, eor_ildp)
|
||||
opM(0x48, pha) opM(0x49, eor_const) opM(0x4a, lsr_imm) opA(0x4b, phk)
|
||||
opA(0x4c, jmp_addr) opM(0x4d, eor_addr) opM(0x4e, lsr_addr) opM(0x4f, eor_long)
|
||||
|
||||
opA(0x50, bvc) opM(0x51, eor_idpy) opM(0x52, eor_idp) opM(0x53, eor_isry)
|
||||
opX(0x54, mvn) opM(0x55, eor_dpr) opM(0x56, lsr_dpx) opM(0x57, eor_ildpy)
|
||||
opA(0x58, cli) opM(0x59, eor_addry) opX(0x5a, phy) opA(0x5b, tcd)
|
||||
opA(0x5c, jmp_long) opM(0x5d, eor_addrx) opM(0x5e, lsr_addrx) opM(0x5f, eor_longx)
|
||||
|
||||
opA(0x60, rts) opM(0x61, adc_idpx) opE(0x62, per) opM(0x63, adc_sr)
|
||||
opM(0x64, stz_dp) opM(0x65, adc_dp) opM(0x66, ror_dp) opM(0x67, adc_ildp)
|
||||
opM(0x68, pla) opM(0x69, adc_const) opM(0x6a, ror_imm) opE(0x6b, rtl)
|
||||
opA(0x6c, jmp_iaddr) opM(0x6d, adc_addr) opM(0x6e, ror_addr) opM(0x6f, adc_long)
|
||||
|
||||
opA(0x70, bvs) opM(0x71, adc_idpy) opM(0x72, adc_idp) opM(0x73, adc_isry)
|
||||
opM(0x74, stz_dpr) opM(0x75, adc_dpr) opM(0x76, ror_dpx) opM(0x77, adc_ildpy)
|
||||
opA(0x78, sei) opM(0x79, adc_addry) opX(0x7a, ply) opA(0x7b, tdc)
|
||||
opA(0x7c, jmp_iaddrx) opM(0x7d, adc_addrx) opM(0x7e, ror_addrx) opM(0x7f, adc_longx)
|
||||
|
||||
opA(0x80, bra) opM(0x81, sta_idpx) opA(0x82, brl) opM(0x83, sta_sr)
|
||||
opX(0x84, sty_dp) opM(0x85, sta_dp) opX(0x86, stx_dp) opM(0x87, sta_ildp)
|
||||
opX(0x88, dey_imm) opM(0x89, bit_const) opM(0x8a, txa) opA(0x8b, phb)
|
||||
opX(0x8c, sty_addr) opM(0x8d, sta_addr) opX(0x8e, stx_addr) opM(0x8f, sta_long)
|
||||
|
||||
opA(0x90, bcc) opM(0x91, sta_idpy) opM(0x92, sta_idp) opM(0x93, sta_isry)
|
||||
opX(0x94, sty_dpr) opM(0x95, sta_dpr) opX(0x96, stx_dpr) opM(0x97, sta_ildpy)
|
||||
opM(0x98, tya) opM(0x99, sta_addry) opE(0x9a, txs) opX(0x9b, txy)
|
||||
opM(0x9c, stz_addr) opM(0x9d, sta_addrx) opM(0x9e, stz_addrx) opM(0x9f, sta_longx)
|
||||
|
||||
opX(0xa0, ldy_const) opM(0xa1, lda_idpx) opX(0xa2, ldx_const) opM(0xa3, lda_sr)
|
||||
opX(0xa4, ldy_dp) opM(0xa5, lda_dp) opX(0xa6, ldx_dp) opM(0xa7, lda_ildp)
|
||||
opX(0xa8, tay) opM(0xa9, lda_const) opX(0xaa, tax) opA(0xab, plb)
|
||||
opX(0xac, ldy_addr) opM(0xad, lda_addr) opX(0xae, ldx_addr) opM(0xaf, lda_long)
|
||||
|
||||
opA(0xb0, bcs) opM(0xb1, lda_idpy) opM(0xb2, lda_idp) opM(0xb3, lda_isry)
|
||||
opX(0xb4, ldy_dpr) opM(0xb5, lda_dpr) opX(0xb6, ldx_dpr) opM(0xb7, lda_ildpy)
|
||||
opA(0xb8, clv) opM(0xb9, lda_addry) opX(0xba, tsx) opX(0xbb, tyx)
|
||||
opX(0xbc, ldy_addrx) opM(0xbd, lda_addrx) opX(0xbe, ldx_addry) opM(0xbf, lda_longx)
|
||||
|
||||
opX(0xc0, cpy_const) opM(0xc1, cmp_idpx) opE(0xc2, rep) opM(0xc3, cmp_sr)
|
||||
opX(0xc4, cpy_dp) opM(0xc5, cmp_dp) opM(0xc6, dec_dp) opM(0xc7, cmp_ildp)
|
||||
opX(0xc8, iny_imm) opM(0xc9, cmp_const) opX(0xca, dex_imm) opA(0xcb, wai)
|
||||
opX(0xcc, cpy_addr) opM(0xcd, cmp_addr) opM(0xce, dec_addr) opM(0xcf, cmp_long)
|
||||
|
||||
opA(0xd0, bne) opM(0xd1, cmp_idpy) opM(0xd2, cmp_idp) opM(0xd3, cmp_isry)
|
||||
opE(0xd4, pei) opM(0xd5, cmp_dpr) opM(0xd6, dec_dpx) opM(0xd7, cmp_ildpy)
|
||||
opA(0xd8, cld) opM(0xd9, cmp_addry) opX(0xda, phx) opA(0xdb, stp)
|
||||
opA(0xdc, jmp_iladdr) opM(0xdd, cmp_addrx) opM(0xde, dec_addrx) opM(0xdf, cmp_longx)
|
||||
|
||||
opX(0xe0, cpx_const) opM(0xe1, sbc_idpx) opE(0xe2, sep) opM(0xe3, sbc_sr)
|
||||
opX(0xe4, cpx_dp) opM(0xe5, sbc_dp) opM(0xe6, inc_dp) opM(0xe7, sbc_ildp)
|
||||
opX(0xe8, inx_imm) opM(0xe9, sbc_const) opA(0xea, nop) opA(0xeb, xba)
|
||||
opX(0xec, cpx_addr) opM(0xed, sbc_addr) opM(0xee, inc_addr) opM(0xef, sbc_long)
|
||||
|
||||
opA(0xf0, beq) opM(0xf1, sbc_idpy) opM(0xf2, sbc_idp) opM(0xf3, sbc_isry)
|
||||
opE(0xf4, pea) opM(0xf5, sbc_dpr) opM(0xf6, inc_dpx) opM(0xf7, sbc_ildpy)
|
||||
opA(0xf8, sed) opM(0xf9, sbc_addry) opX(0xfa, plx) opA(0xfb, xce)
|
||||
opE(0xfc, jsr_iaddrx) opM(0xfd, sbc_addrx) opM(0xfe, inc_addrx) opM(0xff, sbc_longx)
|
||||
|
||||
#undef opA
|
||||
#undef opE
|
||||
#undef opM
|
||||
#undef opX
|
||||
}
|
||||
|
||||
void CPUcore::update_table() {
|
||||
if(regs.e) {
|
||||
opcode_table = &op_table[table_EM];
|
||||
} else if(regs.p.m) {
|
||||
if(regs.p.x) {
|
||||
opcode_table = &op_table[table_MX];
|
||||
} else {
|
||||
opcode_table = &op_table[table_Mx];
|
||||
}
|
||||
} else {
|
||||
if(regs.p.x) {
|
||||
opcode_table = &op_table[table_mX];
|
||||
} else {
|
||||
opcode_table = &op_table[table_mx];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,219 @@
|
|||
@macro op_store_addr(name, r)
|
||||
void {class}::op_{name}_addr_b() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
{lc}op_writedbr(aa.w, {r});
|
||||
}
|
||||
|
||||
void {class}::op_{name}_addr_w() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_writedbr(aa.w + 0, {r} >> 0);
|
||||
{lc}op_writedbr(aa.w + 1, {r} >> 8);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_store_addrr(name, suffix, r, index)
|
||||
void {class}::op_{name}_addr{suffix}_b() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
{lc}op_writedbr(aa.w + {index}, {r});
|
||||
}
|
||||
|
||||
void {class}::op_{name}_addr{suffix}_w() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
op_writedbr(aa.w + {index} + 0, {r} >> 0);
|
||||
{lc}op_writedbr(aa.w + {index} + 1, {r} >> 8);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_store_longr(name, suffix, index)
|
||||
void {class}::op_{name}_long{suffix}_b() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
aa.b = op_readpc();
|
||||
{lc}op_writelong(aa.d + {index}, regs.a.l);
|
||||
}
|
||||
|
||||
void {class}::op_{name}_long{suffix}_w() {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
aa.b = op_readpc();
|
||||
op_writelong(aa.d + {index} + 0, regs.a.l);
|
||||
{lc}op_writelong(aa.d + {index} + 1, regs.a.h);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_store_dp(name, r)
|
||||
void {class}::op_{name}_dp_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
{lc}op_writedp(dp, {r});
|
||||
}
|
||||
|
||||
void {class}::op_{name}_dp_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_writedp(dp + 0, {r} >> 0);
|
||||
{lc}op_writedp(dp + 1, {r} >> 8);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_store_dpr(name, r, index)
|
||||
void {class}::op_{name}_dpr_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
{lc}op_writedp(dp + regs.{index}.w, {r});
|
||||
}
|
||||
|
||||
void {class}::op_{name}_dpr_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
op_writedp(dp + regs.{index}.w + 0, {r} >> 0);
|
||||
{lc}op_writedp(dp + regs.{index}.w + 1, {r} >> 8);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_idp()
|
||||
void {class}::op_sta_idp_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
{lc}op_writedbr(aa.w, regs.a.l);
|
||||
}
|
||||
|
||||
void {class}::op_sta_idp_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_writedbr(aa.w + 0, regs.a.l);
|
||||
{lc}op_writedbr(aa.w + 1, regs.a.h);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_ildp()
|
||||
void {class}::op_sta_ildp_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
{lc}op_writelong(aa.d, regs.a.l);
|
||||
}
|
||||
|
||||
void {class}::op_sta_ildp_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
op_writelong(aa.d + 0, regs.a.l);
|
||||
{lc}op_writelong(aa.d + 1, regs.a.h);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_idpx()
|
||||
void {class}::op_sta_idpx_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
aa.l = op_readdp(dp + regs.x.w + 0);
|
||||
aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
{lc}op_writedbr(aa.w, regs.a.l);
|
||||
}
|
||||
|
||||
void {class}::op_sta_idpx_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
aa.l = op_readdp(dp + regs.x.w + 0);
|
||||
aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_writedbr(aa.w + 0, regs.a.l);
|
||||
{lc}op_writedbr(aa.w + 1, regs.a.h);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_idpy()
|
||||
void {class}::op_sta_idpy_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
{lc}op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
}
|
||||
|
||||
void {class}::op_sta_idpy_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
op_writedbr(aa.w + regs.y.w + 0, regs.a.l);
|
||||
{lc}op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_ildpy()
|
||||
void {class}::op_sta_ildpy_b() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
{lc}op_writelong(aa.d + regs.y.w, regs.a.l);
|
||||
}
|
||||
|
||||
void {class}::op_sta_ildpy_w() {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp + 0);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
op_writelong(aa.d + regs.y.w + 0, regs.a.l);
|
||||
{lc}op_writelong(aa.d + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_sr()
|
||||
void {class}::op_sta_sr_b() {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
{lc}op_writesp(sp, regs.a.l);
|
||||
}
|
||||
|
||||
void {class}::op_sta_sr_w() {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
op_writesp(sp + 0, regs.a.l);
|
||||
{lc}op_writesp(sp + 1, regs.a.h);
|
||||
}
|
||||
@endmacro
|
||||
|
||||
@macro op_sta_isry()
|
||||
void {class}::op_sta_isry_b() {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
aa.l = op_readsp(sp + 0);
|
||||
aa.h = op_readsp(sp + 1);
|
||||
op_io();
|
||||
{lc}op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
}
|
||||
|
||||
void {class}::op_sta_isry_w() {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
aa.l = op_readsp(sp + 0);
|
||||
aa.h = op_readsp(sp + 1);
|
||||
op_io();
|
||||
op_writedbr(aa.w + regs.y.w + 0, regs.a.l);
|
||||
{lc}op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
@endmacro
|
|
@ -68,7 +68,13 @@ struct regs_t {
|
|||
reg24_t pc;
|
||||
reg16_t a, x, y, s, d;
|
||||
flag_t p;
|
||||
uint8_t db, mdr;
|
||||
uint8_t db;
|
||||
bool e;
|
||||
regs_t() : db(0), mdr(0), e(false) {}
|
||||
|
||||
bool irq; //IRQ pin (0 = low, 1 = trigger)
|
||||
bool wai; //raised during wai, cleared after interrupt triggered
|
||||
uint32_t bus; //address on bus; -1U = I/O cycle
|
||||
uint8_t mdr; //memory data register
|
||||
|
||||
regs_t() : db(0), e(false), irq(false), wai(false), bus(-1U), mdr(0) {}
|
||||
};
|
|
@ -1,8 +1,6 @@
|
|||
#include <../base.hpp>
|
||||
#define CPU_CPP
|
||||
|
||||
#include "dcpu.cpp"
|
||||
|
||||
void CPU::power() {
|
||||
cpu_version = snes.config.cpu.version;
|
||||
}
|
||||
|
|
|
@ -13,62 +13,10 @@ public:
|
|||
virtual uint8 port_read(uint8 port) = 0;
|
||||
virtual void port_write(uint8 port, uint8 value) = 0;
|
||||
|
||||
#include "cpuregs.hpp"
|
||||
regs_t regs;
|
||||
|
||||
virtual void scanline() = 0;
|
||||
virtual void power();
|
||||
virtual void reset();
|
||||
|
||||
/*****
|
||||
* in opcode-based CPU emulators, the main emulation routine
|
||||
* will only be able to call the disassemble_opcode() function
|
||||
* on clean opcode edges. but with cycle-based CPU emulators,
|
||||
* the CPU may be in the middle of executing an opcode when the
|
||||
* emulator (e.g. debugger) wants to disassemble an opcode. this
|
||||
* would mean that important registers may not reflect what they
|
||||
* did at the start of the opcode (especially regs.pc), so in
|
||||
* cycle-based emulators, this function should be overridden to
|
||||
* reflect whether or not an opcode has only been partially
|
||||
* executed. if not, the debugger should abort attempts to skip,
|
||||
* disable, or disassemble the current opcode.
|
||||
*****/
|
||||
virtual bool in_opcode() { return false; }
|
||||
|
||||
/*****
|
||||
* opcode disassembler
|
||||
*****/
|
||||
enum {
|
||||
OPTYPE_DP = 0, //dp
|
||||
OPTYPE_DPX, //dp,x
|
||||
OPTYPE_DPY, //dp,y
|
||||
OPTYPE_IDP, //(dp)
|
||||
OPTYPE_IDPX, //(dp,x)
|
||||
OPTYPE_IDPY, //(dp),y
|
||||
OPTYPE_ILDP, //[dp]
|
||||
OPTYPE_ILDPY, //[dp],y
|
||||
OPTYPE_ADDR, //addr
|
||||
OPTYPE_ADDRX, //addr,x
|
||||
OPTYPE_ADDRY, //addr,y
|
||||
OPTYPE_IADDRX, //(addr,x)
|
||||
OPTYPE_ILADDR, //[addr]
|
||||
OPTYPE_LONG, //long
|
||||
OPTYPE_LONGX, //long, x
|
||||
OPTYPE_SR, //sr,s
|
||||
OPTYPE_ISRY, //(sr,s),y
|
||||
OPTYPE_ADDR_PC, //pbr:addr
|
||||
OPTYPE_IADDR_PC, //pbr:(addr)
|
||||
OPTYPE_RELB, //relb
|
||||
OPTYPE_RELW, //relw
|
||||
};
|
||||
|
||||
void disassemble_opcode(char *output);
|
||||
uint8 dreadb(uint32 addr);
|
||||
uint16 dreadw(uint32 addr);
|
||||
uint32 dreadl(uint32 addr);
|
||||
uint32 decode(uint8 offset_type, uint32 addr);
|
||||
uint8 opcode_length();
|
||||
|
||||
CPU();
|
||||
virtual ~CPU();
|
||||
};
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
g++ -c scpugen.cpp -I../../../lib
|
||||
g++ -c ../../../lib/nall/string.cpp -I../../../lib
|
||||
g++ -o scpugen scpugen.o string.o
|
||||
rm *.o
|
|
@ -1 +0,0 @@
|
|||
rm scpugen
|
|
@ -1,90 +0,0 @@
|
|||
#ifdef SCPU_CPP
|
||||
|
||||
#include "opfn.cpp"
|
||||
|
||||
void sCPU::enter() {
|
||||
initialize:
|
||||
//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_clocks(186);
|
||||
|
||||
loop:
|
||||
if(status.interrupt_pending) {
|
||||
status.interrupt_pending = false;
|
||||
if(status.nmi_pending) {
|
||||
status.nmi_pending = false;
|
||||
status.interrupt_vector = (regs.e == false ? 0xffea : 0xfffa);
|
||||
} else if(status.irq_pending) {
|
||||
status.irq_pending = false;
|
||||
status.interrupt_vector = (regs.e == false ? 0xffee : 0xfffe);
|
||||
}
|
||||
op_irq();
|
||||
}
|
||||
|
||||
tracer.trace_cpuop(); //traces CPU opcode (only if tracer is enabled)
|
||||
|
||||
status.in_opcode = true;
|
||||
switch(op_readpc()) {
|
||||
#include "op_read.cpp"
|
||||
#include "op_write.cpp"
|
||||
#include "op_rmw.cpp"
|
||||
#include "op_pc.cpp"
|
||||
#include "op_misc.cpp"
|
||||
}
|
||||
status.in_opcode = false;
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
void sCPU::op_irq() {
|
||||
op_read(regs.pc.d);
|
||||
op_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_read(status.interrupt_vector + 0);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
rd.h = op_read(status.interrupt_vector + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
//immediate, 2-cycle opcodes with I/O cycle will become bus read
|
||||
//when an IRQ is to be triggered immediately after opcode completion
|
||||
//this affects the following opcodes:
|
||||
// clc, cld, cli, clv, sec, sed, sei,
|
||||
// tax, tay, txa, txy, tya, tyx,
|
||||
// tcd, tcs, tdc, tsc, tsx, txs,
|
||||
// inc, inx, iny, dec, dex, dey,
|
||||
// asl, lsr, rol, ror, nop, xce.
|
||||
alwaysinline void sCPU::op_io_irq() {
|
||||
if(status.interrupt_pending) {
|
||||
//IRQ pending, modify I/O cycle to bus read cycle, do not increment PC
|
||||
op_read(regs.pc.d);
|
||||
} else {
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_io_cond2() {
|
||||
if(regs.d.l != 0x00) {
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_io_cond4(uint16 x, uint16 y) {
|
||||
if(!regs.p.x || (x & 0xff00) != (y & 0xff00)) {
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_io_cond6(uint16 addr) {
|
||||
if(regs.e && (regs.pc.w & 0xff00) != (addr & 0xff00)) {
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,298 +0,0 @@
|
|||
nop(0xea) {
|
||||
1:last_cycle();
|
||||
op_io_irq();
|
||||
}
|
||||
|
||||
wdm(0x42) {
|
||||
1:last_cycle();
|
||||
op_readpc();
|
||||
}
|
||||
|
||||
xba(0xeb) {
|
||||
1:op_io();
|
||||
2:last_cycle();
|
||||
op_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:op_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();
|
||||
op_io();
|
||||
if(regs.a.w--) regs.pc.w -= 3;
|
||||
}
|
||||
|
||||
brk(0x00, 0xfffe, 0xffff, 0xffe6, 0xffe7),
|
||||
cop(0x02, 0xfff4, 0xfff5, 0xffe4, 0xffe5) {
|
||||
1:op_readpc();
|
||||
2:if(!regs.e) 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:op_io();
|
||||
2:last_cycle();
|
||||
while(true) op_io();
|
||||
}
|
||||
|
||||
wai(0xcb) {
|
||||
//last_cycle() will clear status.wai_lock once an NMI / IRQ edge is reached
|
||||
1:status.wai_lock = true;
|
||||
while(status.wai_lock) {
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
2:op_io();
|
||||
}
|
||||
|
||||
xce(0xfb) {
|
||||
1:last_cycle();
|
||||
op_io_irq();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = regs.e;
|
||||
regs.e = carry;
|
||||
if(regs.e) {
|
||||
regs.p |= 0x30;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
op_io_irq();
|
||||
$1;
|
||||
}
|
||||
|
||||
rep(0xc2, &=~),
|
||||
sep(0xe2, |=) {
|
||||
1:rd.l = op_readpc();
|
||||
2:last_cycle();
|
||||
op_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();
|
||||
op_io_irq();
|
||||
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();
|
||||
op_io_irq();
|
||||
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();
|
||||
op_io_irq();
|
||||
regs.s.w = regs.a.w;
|
||||
if(regs.e) regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
tdc(0x7b) {
|
||||
1:last_cycle();
|
||||
op_io_irq();
|
||||
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();
|
||||
op_io_irq();
|
||||
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();
|
||||
op_io_irq();
|
||||
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();
|
||||
op_io_irq();
|
||||
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) {
|
||||
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) {
|
||||
1:op_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) {
|
||||
1:op_io();
|
||||
2:op_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);
|
||||
}
|
||||
|
||||
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 = !!(regs.db & 0x80);
|
||||
regs.p.z = (regs.db == 0);
|
||||
}
|
||||
|
||||
plp(0x28) {
|
||||
1:op_io();
|
||||
2:op_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_writestackn(aa.h);
|
||||
4:last_cycle();
|
||||
op_writestackn(aa.l);
|
||||
if(regs.e) regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
pei(0xd4) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:op_writestackn(aa.h);
|
||||
6:last_cycle();
|
||||
op_writestackn(aa.l);
|
||||
if(regs.e) regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
per(0x62) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io();
|
||||
rd.w = regs.pc.d + (int16)aa.w;
|
||||
4:op_writestackn(rd.h);
|
||||
5:last_cycle();
|
||||
op_writestackn(rd.l);
|
||||
if(regs.e) regs.s.h = 0x01;
|
||||
}
|
|
@ -1,539 +0,0 @@
|
|||
#ifdef SCPU_CPP
|
||||
|
||||
//nop
|
||||
case 0xea: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
} break;
|
||||
|
||||
//wdm
|
||||
case 0x42: {
|
||||
last_cycle();
|
||||
op_readpc();
|
||||
} break;
|
||||
|
||||
//xba
|
||||
case 0xeb: {
|
||||
op_io();
|
||||
last_cycle();
|
||||
op_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);
|
||||
} break;
|
||||
|
||||
//mvn
|
||||
case 0x54: {
|
||||
dp = op_readpc();
|
||||
sp = op_readpc();
|
||||
regs.db = dp;
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l ++;
|
||||
regs.y.l ++;
|
||||
} else {
|
||||
regs.x.w ++;
|
||||
regs.y.w ++;
|
||||
}
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.a.w--) regs.pc.w -= 3;
|
||||
} break;
|
||||
|
||||
//mvp
|
||||
case 0x44: {
|
||||
dp = op_readpc();
|
||||
sp = op_readpc();
|
||||
regs.db = dp;
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
op_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l --;
|
||||
regs.y.l --;
|
||||
} else {
|
||||
regs.x.w --;
|
||||
regs.y.w --;
|
||||
}
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.a.w--) regs.pc.w -= 3;
|
||||
} break;
|
||||
|
||||
//brk
|
||||
case 0x00: {
|
||||
op_readpc();
|
||||
if(!regs.e) op_writestack(regs.pc.b);
|
||||
op_writestack(regs.pc.h);
|
||||
op_writestack(regs.pc.l);
|
||||
op_writestack(regs.p);
|
||||
rd.l = op_readlong(regs.e ? 0xfffe : 0xffe6);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
last_cycle();
|
||||
rd.h = op_readlong(regs.e ? 0xffff : 0xffe7);
|
||||
regs.pc.w = rd.w;
|
||||
} break;
|
||||
|
||||
//cop
|
||||
case 0x02: {
|
||||
op_readpc();
|
||||
if(!regs.e) op_writestack(regs.pc.b);
|
||||
op_writestack(regs.pc.h);
|
||||
op_writestack(regs.pc.l);
|
||||
op_writestack(regs.p);
|
||||
rd.l = op_readlong(regs.e ? 0xfff4 : 0xffe4);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
last_cycle();
|
||||
rd.h = op_readlong(regs.e ? 0xfff5 : 0xffe5);
|
||||
regs.pc.w = rd.w;
|
||||
} break;
|
||||
|
||||
//stp
|
||||
case 0xdb: {
|
||||
op_io();
|
||||
last_cycle();
|
||||
while(true) op_io();
|
||||
} break;
|
||||
|
||||
//wai
|
||||
case 0xcb: {
|
||||
//last_cycle() will clear status.wai_lock once an NMI / IRQ edge is reached
|
||||
status.wai_lock = true;
|
||||
while(status.wai_lock) {
|
||||
last_cycle();
|
||||
op_io();
|
||||
}
|
||||
op_io();
|
||||
} break;
|
||||
|
||||
//xce
|
||||
case 0xfb: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = regs.e;
|
||||
regs.e = carry;
|
||||
if(regs.e) {
|
||||
regs.p |= 0x30;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
} break;
|
||||
|
||||
//clc
|
||||
case 0x18: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
regs.p.c = 0;
|
||||
} break;
|
||||
|
||||
//cld
|
||||
case 0xd8: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
regs.p.d = 0;
|
||||
} break;
|
||||
|
||||
//cli
|
||||
case 0x58: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
regs.p.i = 0;
|
||||
} break;
|
||||
|
||||
//clv
|
||||
case 0xb8: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
regs.p.v = 0;
|
||||
} break;
|
||||
|
||||
//sec
|
||||
case 0x38: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
regs.p.c = 1;
|
||||
} break;
|
||||
|
||||
//sed
|
||||
case 0xf8: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
regs.p.d = 1;
|
||||
} break;
|
||||
|
||||
//sei
|
||||
case 0x78: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
regs.p.i = 1;
|
||||
} break;
|
||||
|
||||
//rep
|
||||
case 0xc2: {
|
||||
rd.l = op_readpc();
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p &=~ rd.l;
|
||||
if(regs.e) regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
} break;
|
||||
|
||||
//sep
|
||||
case 0xe2: {
|
||||
rd.l = op_readpc();
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p |= rd.l;
|
||||
if(regs.e) regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
} break;
|
||||
|
||||
//tax
|
||||
case 0xaa: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
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);
|
||||
}
|
||||
} break;
|
||||
|
||||
//tay
|
||||
case 0xa8: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
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);
|
||||
}
|
||||
} break;
|
||||
|
||||
//txa
|
||||
case 0x8a: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
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);
|
||||
}
|
||||
} break;
|
||||
|
||||
//txy
|
||||
case 0x9b: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
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);
|
||||
}
|
||||
} break;
|
||||
|
||||
//tya
|
||||
case 0x98: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
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);
|
||||
}
|
||||
} break;
|
||||
|
||||
//tyx
|
||||
case 0xbb: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
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);
|
||||
}
|
||||
} break;
|
||||
|
||||
//tcd
|
||||
case 0x5b: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
regs.d.w = regs.a.w;
|
||||
regs.p.n = !!(regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
} break;
|
||||
|
||||
//tcs
|
||||
case 0x1b: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
regs.s.w = regs.a.w;
|
||||
if(regs.e) regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
//tdc
|
||||
case 0x7b: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
regs.a.w = regs.d.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
} break;
|
||||
|
||||
//tsc
|
||||
case 0x3b: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
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);
|
||||
}
|
||||
} break;
|
||||
|
||||
//tsx
|
||||
case 0xba: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
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);
|
||||
}
|
||||
} break;
|
||||
|
||||
//txs
|
||||
case 0x9a: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
if(regs.e) {
|
||||
regs.s.l = regs.x.l;
|
||||
} else {
|
||||
regs.s.w = regs.x.w;
|
||||
}
|
||||
} break;
|
||||
|
||||
//pha
|
||||
case 0x48: {
|
||||
op_io();
|
||||
if(!regs.p.m)op_writestack(regs.a.h);
|
||||
last_cycle();
|
||||
op_writestack(regs.a.l);
|
||||
} break;
|
||||
|
||||
//phx
|
||||
case 0xda: {
|
||||
op_io();
|
||||
if(!regs.p.x)op_writestack(regs.x.h);
|
||||
last_cycle();
|
||||
op_writestack(regs.x.l);
|
||||
} break;
|
||||
|
||||
//phy
|
||||
case 0x5a: {
|
||||
op_io();
|
||||
if(!regs.p.x)op_writestack(regs.y.h);
|
||||
last_cycle();
|
||||
op_writestack(regs.y.l);
|
||||
} break;
|
||||
|
||||
//phd
|
||||
case 0x0b: {
|
||||
op_io();
|
||||
op_writestackn(regs.d.h);
|
||||
last_cycle();
|
||||
op_writestackn(regs.d.l);
|
||||
if(regs.e) regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
//phb
|
||||
case 0x8b: {
|
||||
op_io();
|
||||
last_cycle();
|
||||
op_writestack(regs.db);
|
||||
} break;
|
||||
|
||||
//phk
|
||||
case 0x4b: {
|
||||
op_io();
|
||||
last_cycle();
|
||||
op_writestack(regs.pc.b);
|
||||
} break;
|
||||
|
||||
//php
|
||||
case 0x08: {
|
||||
op_io();
|
||||
last_cycle();
|
||||
op_writestack(regs.p);
|
||||
} break;
|
||||
|
||||
//pla
|
||||
case 0x68: {
|
||||
op_io();
|
||||
op_io();
|
||||
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);
|
||||
break;
|
||||
}
|
||||
last_cycle();
|
||||
regs.a.h = op_readstack();
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
} break;
|
||||
|
||||
//plx
|
||||
case 0xfa: {
|
||||
op_io();
|
||||
op_io();
|
||||
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);
|
||||
break;
|
||||
}
|
||||
last_cycle();
|
||||
regs.x.h = op_readstack();
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
} break;
|
||||
|
||||
//ply
|
||||
case 0x7a: {
|
||||
op_io();
|
||||
op_io();
|
||||
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);
|
||||
break;
|
||||
}
|
||||
last_cycle();
|
||||
regs.y.h = op_readstack();
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
} break;
|
||||
|
||||
//pld
|
||||
case 0x2b: {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.d.l = op_readstackn();
|
||||
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;
|
||||
} break;
|
||||
|
||||
//plb
|
||||
case 0xab: {
|
||||
op_io();
|
||||
op_io();
|
||||
last_cycle();
|
||||
regs.db = op_readstack();
|
||||
regs.p.n = !!(regs.db & 0x80);
|
||||
regs.p.z = (regs.db == 0);
|
||||
} break;
|
||||
|
||||
//plp
|
||||
case 0x28: {
|
||||
op_io();
|
||||
op_io();
|
||||
last_cycle();
|
||||
regs.p = op_readstack();
|
||||
if(regs.e) regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
} break;
|
||||
|
||||
//pea
|
||||
case 0xf4: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_writestackn(aa.h);
|
||||
last_cycle();
|
||||
op_writestackn(aa.l);
|
||||
if(regs.e) regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
//pei
|
||||
case 0xd4: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_writestackn(aa.h);
|
||||
last_cycle();
|
||||
op_writestackn(aa.l);
|
||||
if(regs.e) regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
//per
|
||||
case 0x62: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.w = regs.pc.d + (int16)aa.w;
|
||||
op_writestackn(rd.h);
|
||||
last_cycle();
|
||||
op_writestackn(rd.l);
|
||||
if(regs.e) regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
#endif
|
|
@ -1,163 +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:op_io_cond6(aa.w);
|
||||
3:last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
bra(0x80) {
|
||||
1:rd.l = op_readpc();
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
2:op_io_cond6(aa.w);
|
||||
3:last_cycle();
|
||||
op_io();
|
||||
}
|
||||
|
||||
brl(0x82) {
|
||||
1:rd.l = op_readpc();
|
||||
2:rd.h = op_readpc();
|
||||
3:last_cycle();
|
||||
op_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:op_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:op_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_writestackn(regs.pc.b);
|
||||
4:op_io();
|
||||
5:aa.b = op_readpc();
|
||||
6:regs.pc.w--;
|
||||
op_writestackn(regs.pc.h);
|
||||
7:last_cycle();
|
||||
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_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();
|
||||
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:op_io();
|
||||
2:op_io();
|
||||
3:rd.l = op_readstack();
|
||||
4:rd.h = op_readstack();
|
||||
5:last_cycle();
|
||||
op_io();
|
||||
regs.pc.w = rd.w;
|
||||
regs.pc.w++;
|
||||
}
|
||||
|
||||
rtl(0x6b) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:rd.l = op_readstackn();
|
||||
4:rd.h = op_readstackn();
|
||||
5:last_cycle();
|
||||
rd.b = op_readstackn();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
regs.pc.w++;
|
||||
if(regs.e) regs.s.h = 0x01;
|
||||
}
|
|
@ -1,279 +0,0 @@
|
|||
#ifdef SCPU_CPP
|
||||
|
||||
//bcc
|
||||
case 0x90: {
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
} break;
|
||||
|
||||
//bcs
|
||||
case 0xb0: {
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
} break;
|
||||
|
||||
//bne
|
||||
case 0xd0: {
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
} break;
|
||||
|
||||
//beq
|
||||
case 0xf0: {
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
} break;
|
||||
|
||||
//bpl
|
||||
case 0x10: {
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
} break;
|
||||
|
||||
//bmi
|
||||
case 0x30: {
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
} break;
|
||||
|
||||
//bvc
|
||||
case 0x50: {
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
} break;
|
||||
|
||||
//bvs
|
||||
case 0x70: {
|
||||
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 {
|
||||
break;
|
||||
}
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
} break;
|
||||
|
||||
//bra
|
||||
case 0x80: {
|
||||
rd.l = op_readpc();
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
op_io_cond6(aa.w);
|
||||
last_cycle();
|
||||
op_io();
|
||||
} break;
|
||||
|
||||
//brl
|
||||
case 0x82: {
|
||||
rd.l = op_readpc();
|
||||
rd.h = op_readpc();
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.pc.w = regs.pc.d + (int16)rd.w;
|
||||
} break;
|
||||
|
||||
//jmp_addr
|
||||
case 0x4c: {
|
||||
rd.l = op_readpc();
|
||||
last_cycle();
|
||||
rd.h = op_readpc();
|
||||
regs.pc.w = rd.w;
|
||||
} break;
|
||||
|
||||
//jmp_long
|
||||
case 0x5c: {
|
||||
rd.l = op_readpc();
|
||||
rd.h = op_readpc();
|
||||
last_cycle();
|
||||
rd.b = op_readpc();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
} break;
|
||||
|
||||
//jmp_iaddr
|
||||
case 0x6c: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readaddr(aa.w);
|
||||
last_cycle();
|
||||
rd.h = op_readaddr(aa.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
} break;
|
||||
|
||||
//jmp_iaddrx
|
||||
case 0x7c: {
|
||||
aa.l = op_readpc();
|
||||
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;
|
||||
} break;
|
||||
|
||||
//jmp_iladdr
|
||||
case 0xdc: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readaddr(aa.w);
|
||||
rd.h = op_readaddr(aa.w + 1);
|
||||
last_cycle();
|
||||
rd.b = op_readaddr(aa.w + 2);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
} break;
|
||||
|
||||
//jsr_addr
|
||||
case 0x20: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
regs.pc.w--;
|
||||
op_writestack(regs.pc.h);
|
||||
last_cycle();
|
||||
op_writestack(regs.pc.l);
|
||||
regs.pc.w = aa.w;
|
||||
} break;
|
||||
|
||||
//jsr_long
|
||||
case 0x22: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_writestackn(regs.pc.b);
|
||||
op_io();
|
||||
aa.b = op_readpc();
|
||||
regs.pc.w--;
|
||||
op_writestackn(regs.pc.h);
|
||||
last_cycle();
|
||||
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_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
|
||||
case 0x40: {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.p = op_readstack();
|
||||
if(regs.e) regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
rd.l = op_readstack();
|
||||
if(regs.e) last_cycle();
|
||||
rd.h = op_readstack();
|
||||
if(regs.e) {
|
||||
regs.pc.w = rd.w;
|
||||
break;
|
||||
}
|
||||
last_cycle();
|
||||
rd.b = op_readstack();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
} break;
|
||||
|
||||
//rts
|
||||
case 0x60: {
|
||||
op_io();
|
||||
op_io();
|
||||
rd.l = op_readstack();
|
||||
rd.h = op_readstack();
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.pc.w = rd.w;
|
||||
regs.pc.w++;
|
||||
} break;
|
||||
|
||||
//rtl
|
||||
case 0x6b: {
|
||||
op_io();
|
||||
op_io();
|
||||
rd.l = op_readstackn();
|
||||
rd.h = op_readstackn();
|
||||
last_cycle();
|
||||
rd.b = op_readstackn();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
regs.pc.w++;
|
||||
if(regs.e) regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
#endif
|
|
@ -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:op_io_cond4(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:op_io_cond4(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:op_io_cond2();
|
||||
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:op_io_cond2();
|
||||
3:op_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:op_io_cond2();
|
||||
3:op_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:op_io_cond2();
|
||||
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:op_io_cond2();
|
||||
3:op_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:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:op_io_cond4(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:op_io_cond2();
|
||||
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:op_io_cond2();
|
||||
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:op_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:op_io();
|
||||
3:aa.l = op_readsp(sp);
|
||||
4:aa.h = op_readsp(sp + 1);
|
||||
5:op_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
|
@ -1,181 +0,0 @@
|
|||
inc(0x1a, regs.p.m, a),
|
||||
inx(0xe8, regs.p.x, x),
|
||||
iny(0xc8, regs.p.x, y) {
|
||||
1:last_cycle();
|
||||
op_io_irq();
|
||||
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();
|
||||
op_io_irq();
|
||||
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();
|
||||
op_io_irq();
|
||||
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();
|
||||
op_io_irq();
|
||||
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();
|
||||
op_io_irq();
|
||||
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();
|
||||
op_io_irq();
|
||||
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);
|
||||
4:if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
|
||||
5:op_io();
|
||||
if(regs.p.m) { op_$1_b(); }
|
||||
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:op_io();
|
||||
4:rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
5:if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
6:op_io();
|
||||
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();
|
||||
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:op_io_cond2();
|
||||
3:rd.l = op_readdp(dp);
|
||||
4:if(!regs.p.m) rd.h = op_readdp(dp + 1);
|
||||
5:op_io();
|
||||
if(regs.p.m) { op_$1_b(); }
|
||||
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:op_io_cond2();
|
||||
3:op_io();
|
||||
4:rd.l = op_readdp(dp + regs.x.w);
|
||||
5:if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
6:op_io();
|
||||
if(regs.p.m) { op_$1_b(); }
|
||||
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);
|
||||
}
|
|
@ -1,573 +0,0 @@
|
|||
#ifdef SCPU_CPP
|
||||
|
||||
//inc
|
||||
case 0x1a: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
if(regs.p.m) {
|
||||
regs.a.l++;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.a.w++;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
} break;
|
||||
|
||||
//inx
|
||||
case 0xe8: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
if(regs.p.x) {
|
||||
regs.x.l++;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w++;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
} break;
|
||||
|
||||
//iny
|
||||
case 0xc8: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
if(regs.p.x) {
|
||||
regs.y.l++;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
} else {
|
||||
regs.y.w++;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
} break;
|
||||
|
||||
//dec
|
||||
case 0x3a: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
if(regs.p.m) {
|
||||
regs.a.l--;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.a.w--;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
} break;
|
||||
|
||||
//dex
|
||||
case 0xca: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
if(regs.p.x) {
|
||||
regs.x.l--;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w--;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
} break;
|
||||
|
||||
//dey
|
||||
case 0x88: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
if(regs.p.x) {
|
||||
regs.y.l--;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
} else {
|
||||
regs.y.w--;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
} break;
|
||||
|
||||
//asl
|
||||
case 0x0a: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
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);
|
||||
}
|
||||
} break;
|
||||
|
||||
//lsr
|
||||
case 0x4a: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
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);
|
||||
}
|
||||
} break;
|
||||
|
||||
//rol
|
||||
case 0x2a: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
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);
|
||||
}
|
||||
} break;
|
||||
|
||||
//ror
|
||||
case 0x6a: {
|
||||
last_cycle();
|
||||
op_io_irq();
|
||||
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);
|
||||
}
|
||||
} break;
|
||||
|
||||
//inc_addr
|
||||
case 0xee: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_inc_b(); }
|
||||
else { op_inc_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
} break;
|
||||
|
||||
//dec_addr
|
||||
case 0xce: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_dec_b(); }
|
||||
else { op_dec_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
} break;
|
||||
|
||||
//asl_addr
|
||||
case 0x0e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_asl_b(); }
|
||||
else { op_asl_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
} break;
|
||||
|
||||
//lsr_addr
|
||||
case 0x4e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_lsr_b(); }
|
||||
else { op_lsr_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
} break;
|
||||
|
||||
//rol_addr
|
||||
case 0x2e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_rol_b(); }
|
||||
else { op_rol_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
} break;
|
||||
|
||||
//ror_addr
|
||||
case 0x6e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_ror_b(); }
|
||||
else { op_ror_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
} break;
|
||||
|
||||
//trb_addr
|
||||
case 0x1c: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_trb_b(); }
|
||||
else { op_trb_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
} break;
|
||||
|
||||
//tsb_addr
|
||||
case 0x0c: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_tsb_b(); }
|
||||
else { op_tsb_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
} break;
|
||||
|
||||
//inc_addrx
|
||||
case 0xfe: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_inc_b(); }
|
||||
else { op_inc_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
} break;
|
||||
|
||||
//dec_addrx
|
||||
case 0xde: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_dec_b(); }
|
||||
else { op_dec_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
} break;
|
||||
|
||||
//asl_addrx
|
||||
case 0x1e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_asl_b(); }
|
||||
else { op_asl_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
} break;
|
||||
|
||||
//lsr_addrx
|
||||
case 0x5e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_lsr_b(); }
|
||||
else { op_lsr_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
} break;
|
||||
|
||||
//rol_addrx
|
||||
case 0x3e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_rol_b(); }
|
||||
else { op_rol_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
} break;
|
||||
|
||||
//ror_addrx
|
||||
case 0x7e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.p.m) rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_ror_b(); }
|
||||
else { op_ror_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
} break;
|
||||
|
||||
//inc_dp
|
||||
case 0xe6: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_inc_b(); }
|
||||
else { op_inc_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
} break;
|
||||
|
||||
//dec_dp
|
||||
case 0xc6: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_dec_b(); }
|
||||
else { op_dec_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
} break;
|
||||
|
||||
//asl_dp
|
||||
case 0x06: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_asl_b(); }
|
||||
else { op_asl_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
} break;
|
||||
|
||||
//lsr_dp
|
||||
case 0x46: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_lsr_b(); }
|
||||
else { op_lsr_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
} break;
|
||||
|
||||
//rol_dp
|
||||
case 0x26: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_rol_b(); }
|
||||
else { op_rol_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
} break;
|
||||
|
||||
//ror_dp
|
||||
case 0x66: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_ror_b(); }
|
||||
else { op_ror_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
} break;
|
||||
|
||||
//trb_dp
|
||||
case 0x14: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_trb_b(); }
|
||||
else { op_trb_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
} break;
|
||||
|
||||
//tsb_dp
|
||||
case 0x04: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_tsb_b(); }
|
||||
else { op_tsb_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
} break;
|
||||
|
||||
//inc_dpx
|
||||
case 0xf6: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_inc_b(); }
|
||||
else { op_inc_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
} break;
|
||||
|
||||
//dec_dpx
|
||||
case 0xd6: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_dec_b(); }
|
||||
else { op_dec_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
} break;
|
||||
|
||||
//asl_dpx
|
||||
case 0x16: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_asl_b(); }
|
||||
else { op_asl_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
} break;
|
||||
|
||||
//lsr_dpx
|
||||
case 0x56: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_lsr_b(); }
|
||||
else { op_lsr_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
} break;
|
||||
|
||||
//rol_dpx
|
||||
case 0x36: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_rol_b(); }
|
||||
else { op_rol_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
} break;
|
||||
|
||||
//ror_dpx
|
||||
case 0x76: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.p.m) rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.p.m) { op_ror_b(); }
|
||||
else { op_ror_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
} break;
|
||||
|
||||
#endif
|
|
@ -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:op_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:op_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:op_io_cond2();
|
||||
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:op_io_cond2();
|
||||
3:op_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:op_io_cond2();
|
||||
3:op_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:op_io_cond2();
|
||||
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:op_io_cond2();
|
||||
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:op_io_cond2();
|
||||
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.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:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:op_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:op_io_cond2();
|
||||
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:op_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:op_io();
|
||||
3:aa.l = op_readsp(sp);
|
||||
4:aa.h = op_readsp(sp + 1);
|
||||
5:op_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);
|
||||
}
|
|
@ -1,293 +0,0 @@
|
|||
#ifdef SCPU_CPP
|
||||
|
||||
//sta_addr
|
||||
case 0x8d: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedbr(aa.w, regs.a.w);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.w >> 8);
|
||||
} break;
|
||||
|
||||
//stx_addr
|
||||
case 0x8e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
if(regs.p.x) last_cycle();
|
||||
op_writedbr(aa.w, regs.x.w);
|
||||
if(regs.p.x) break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.x.w >> 8);
|
||||
} break;
|
||||
|
||||
//sty_addr
|
||||
case 0x8c: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
if(regs.p.x) last_cycle();
|
||||
op_writedbr(aa.w, regs.y.w);
|
||||
if(regs.p.x) break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.y.w >> 8);
|
||||
} break;
|
||||
|
||||
//stz_addr
|
||||
case 0x9c: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedbr(aa.w, 0x0000);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, 0x0000 >> 8);
|
||||
} break;
|
||||
|
||||
//sta_addrx
|
||||
case 0x9d: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, regs.a.w);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w + 1, regs.a.w >> 8);
|
||||
} break;
|
||||
|
||||
//stz_addrx
|
||||
case 0x9e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, 0x0000);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w + 1, 0x0000 >> 8);
|
||||
} break;
|
||||
|
||||
//sta_addry
|
||||
case 0x99: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
} break;
|
||||
|
||||
//sta_long
|
||||
case 0x8f: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
aa.b = op_readpc();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
} break;
|
||||
|
||||
//sta_longx
|
||||
case 0x9f: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
aa.b = op_readpc();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writelong(aa.d + regs.x.w, regs.a.l);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
|
||||
} break;
|
||||
|
||||
//sta_dp
|
||||
case 0x85: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedp(dp, regs.a.w);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, regs.a.w >> 8);
|
||||
} break;
|
||||
|
||||
//stx_dp
|
||||
case 0x86: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
if(regs.p.x) last_cycle();
|
||||
op_writedp(dp, regs.x.w);
|
||||
if(regs.p.x) break;
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, regs.x.w >> 8);
|
||||
} break;
|
||||
|
||||
//sty_dp
|
||||
case 0x84: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
if(regs.p.x) last_cycle();
|
||||
op_writedp(dp, regs.y.w);
|
||||
if(regs.p.x) break;
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, regs.y.w >> 8);
|
||||
} break;
|
||||
|
||||
//stz_dp
|
||||
case 0x64: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedp(dp, 0x0000);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, 0x0000 >> 8);
|
||||
} break;
|
||||
|
||||
//sta_dpx
|
||||
case 0x95: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedp(dp + regs.x.w, regs.a.w);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, regs.a.w >> 8);
|
||||
} break;
|
||||
|
||||
//sty_dpx
|
||||
case 0x94: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
if(regs.p.x) last_cycle();
|
||||
op_writedp(dp + regs.x.w, regs.y.w);
|
||||
if(regs.p.x) break;
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, regs.y.w >> 8);
|
||||
} break;
|
||||
|
||||
//stz_dpx
|
||||
case 0x74: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedp(dp + regs.x.w, 0x0000);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, 0x0000 >> 8);
|
||||
} break;
|
||||
|
||||
//stx_dpy
|
||||
case 0x96: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
if(regs.p.x) last_cycle();
|
||||
op_writedp(dp + regs.y.w, regs.x.l);
|
||||
if(regs.p.x) break;
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.y.w + 1, regs.x.h);
|
||||
} break;
|
||||
|
||||
//sta_idp
|
||||
case 0x92: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
} break;
|
||||
|
||||
//sta_ildp
|
||||
case 0x87: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
} break;
|
||||
|
||||
//sta_idpx
|
||||
case 0x81: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
aa.l = op_readdp(dp + regs.x.w);
|
||||
aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
} break;
|
||||
|
||||
//sta_idpy
|
||||
case 0x91: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
} break;
|
||||
|
||||
//sta_ildpy
|
||||
case 0x97: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writelong(aa.d + regs.y.w, regs.a.l);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
|
||||
} break;
|
||||
|
||||
//sta_sr
|
||||
case 0x83: {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writesp(sp, regs.a.l);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writesp(sp + 1, regs.a.h);
|
||||
} break;
|
||||
|
||||
//sta_isry
|
||||
case 0x93: {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
aa.l = op_readsp(sp);
|
||||
aa.h = op_readsp(sp + 1);
|
||||
op_io();
|
||||
if(regs.p.m) last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m) break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
} break;
|
||||
|
||||
#endif
|
|
@ -1,12 +0,0 @@
|
|||
#define CLASS_NAME "sCPU"
|
||||
#include <tool/opgen_switch.cpp>
|
||||
|
||||
int main() {
|
||||
generate("op_read.cpp", "op_read.b");
|
||||
generate("op_write.cpp", "op_write.b");
|
||||
generate("op_rmw.cpp", "op_rmw.b");
|
||||
generate("op_pc.cpp", "op_pc.b");
|
||||
generate("op_misc.cpp", "op_misc.b");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -3,6 +3,8 @@
|
|||
void sCPU::dma_add_clocks(unsigned clocks) {
|
||||
status.dma_clocks += clocks;
|
||||
add_clocks(clocks);
|
||||
scheduler.sync_cpucop();
|
||||
scheduler.sync_cpuppu();
|
||||
}
|
||||
|
||||
bool sCPU::dma_addr_valid(uint32 abus) {
|
||||
|
|
|
@ -1,125 +1,46 @@
|
|||
#ifdef SCPU_CPP
|
||||
|
||||
/*****
|
||||
* These 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 cycles.
|
||||
* they are either 6, 8, or 12 bus cycles long, depending
|
||||
* both on location and the $420d.d0 FastROM enable bit.
|
||||
*****/
|
||||
|
||||
void sCPU::op_io() {
|
||||
status.clock_count = 6;
|
||||
precycle_edge();
|
||||
add_clocks(6);
|
||||
cycle_edge();
|
||||
}
|
||||
|
||||
uint8 sCPU::op_read(uint32 addr) {
|
||||
status.clock_count = bus.speed(addr);
|
||||
precycle_edge();
|
||||
add_clocks(status.clock_count - 4);
|
||||
regs.mdr = bus.read(addr);
|
||||
add_clocks(4);
|
||||
cycle_edge();
|
||||
return regs.mdr;
|
||||
}
|
||||
|
||||
void sCPU::op_write(uint32 addr, uint8 data) {
|
||||
status.clock_count = bus.speed(addr);
|
||||
precycle_edge();
|
||||
add_clocks(status.clock_count);
|
||||
regs.mdr = data;
|
||||
bus.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);
|
||||
}
|
||||
void sCPU::op_io() {
|
||||
regs.bus = -1U;
|
||||
status.clock_count = 6;
|
||||
precycle_edge();
|
||||
add_clocks(6);
|
||||
if(regs.wai) scheduler.sync_cpucop();
|
||||
cycle_edge();
|
||||
}
|
||||
|
||||
#endif //ifdef SCPU_CPP
|
||||
uint8 sCPU::op_read(uint32 addr) {
|
||||
status.clock_count = speed(regs.bus = addr);
|
||||
precycle_edge();
|
||||
add_clocks(status.clock_count - 4);
|
||||
|
||||
scheduler.sync_cpucop();
|
||||
scheduler.sync_cpuppu();
|
||||
regs.mdr = bus.read(addr);
|
||||
add_clocks(4);
|
||||
cycle_edge();
|
||||
return regs.mdr;
|
||||
}
|
||||
|
||||
void sCPU::op_write(uint32 addr, uint8 data) {
|
||||
status.clock_count = speed(regs.bus = addr);
|
||||
precycle_edge();
|
||||
add_clocks(status.clock_count);
|
||||
|
||||
scheduler.sync_cpucop();
|
||||
scheduler.sync_cpuppu();
|
||||
bus.write(addr, regs.mdr = data);
|
||||
cycle_edge();
|
||||
}
|
||||
|
||||
unsigned sCPU::speed(unsigned addr) const {
|
||||
if(addr & 0x408000) {
|
||||
if(addr & 0x800000) return status.rom_speed;
|
||||
return 8;
|
||||
}
|
||||
if((addr + 0x6000) & 0x4000) return 8;
|
||||
if((addr - 0x4000) & 0x7e00) return 6;
|
||||
return 12;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,35 +1,16 @@
|
|||
/*****
|
||||
* CPU<>APU communication ports
|
||||
*****/
|
||||
uint8 apu_port[4];
|
||||
uint8 port_read(uint8 port) { return apu_port[port & 3]; }
|
||||
void port_write(uint8 port, uint8 data) { apu_port[port & 3] = data; }
|
||||
//============================
|
||||
//CPU<>APU communication ports
|
||||
//============================
|
||||
|
||||
/*****
|
||||
* core CPU bus functions
|
||||
*****/
|
||||
void op_io();
|
||||
uint8 op_read(uint32 addr);
|
||||
void op_write(uint32 addr, uint8 data);
|
||||
uint8 apu_port[4];
|
||||
uint8 port_read(uint8 port) { return apu_port[port & 3]; }
|
||||
void port_write(uint8 port, uint8 data) { apu_port[port & 3] = data; }
|
||||
|
||||
/*****
|
||||
* helper memory addressing functions used by CPU core
|
||||
*****/
|
||||
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);
|
||||
//======================
|
||||
//core CPU bus functions
|
||||
//======================
|
||||
|
||||
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);
|
||||
void op_io();
|
||||
uint8 op_read(uint32 addr);
|
||||
void op_write(uint32 addr, uint8 data);
|
||||
alwaysinline unsigned speed(unsigned addr) const;
|
||||
|
|
|
@ -157,7 +157,7 @@ void sCPU::mmio_w420c(uint8 data) {
|
|||
|
||||
//MEMSEL
|
||||
void sCPU::mmio_w420d(uint8 data) {
|
||||
bus.set_speed(data & 1);
|
||||
status.rom_speed = (data & 1 ? 6 : 8);
|
||||
}
|
||||
|
||||
//RDNMI
|
||||
|
@ -402,6 +402,9 @@ void sCPU::mmio_reset() {
|
|||
status.hirq_pos = 0x01ff;
|
||||
status.virq_pos = 0x01ff;
|
||||
|
||||
//$420d
|
||||
status.rom_speed = 8;
|
||||
|
||||
//$4214-$4217
|
||||
status.r4214 = 0x0000;
|
||||
status.r4216 = 0x0000;
|
||||
|
|
|
@ -4,12 +4,53 @@
|
|||
#include <nall/priorityqueue.hpp>
|
||||
priority_queue<unsigned> event(512, bind(&sCPU::queue_event, &cpu));
|
||||
|
||||
#include "core/core.cpp"
|
||||
#include "dma/dma.cpp"
|
||||
#include "memory/memory.cpp"
|
||||
#include "mmio/mmio.cpp"
|
||||
#include "timing/timing.cpp"
|
||||
|
||||
void sCPU::enter() {
|
||||
regs.pc.l = bus.read(0xfffc);
|
||||
regs.pc.h = bus.read(0xfffd);
|
||||
|
||||
//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_clocks(186);
|
||||
|
||||
while(true) {
|
||||
if(status.interrupt_pending) {
|
||||
status.interrupt_pending = false;
|
||||
if(status.nmi_pending) {
|
||||
status.nmi_pending = false;
|
||||
status.interrupt_vector = (regs.e == false ? 0xffea : 0xfffa);
|
||||
} else if(status.irq_pending) {
|
||||
status.irq_pending = false;
|
||||
status.interrupt_vector = (regs.e == false ? 0xffee : 0xfffe);
|
||||
}
|
||||
op_irq();
|
||||
}
|
||||
|
||||
tracer.trace_cpuop(); //traces CPU opcode (only if tracer is enabled)
|
||||
(this->*opcode_table[op_readpc()])();
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::op_irq() {
|
||||
op_read(regs.pc.d);
|
||||
op_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_read(status.interrupt_vector + 0);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
rd.h = op_read(status.interrupt_vector + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
void sCPU::power() {
|
||||
CPU::power();
|
||||
|
||||
|
@ -26,11 +67,8 @@ void sCPU::power() {
|
|||
void sCPU::reset() {
|
||||
CPU::reset();
|
||||
|
||||
regs.pc.d = 0x000000;
|
||||
regs.pc.l = bus.read(0xfffc);
|
||||
regs.pc.h = bus.read(0xfffd);
|
||||
|
||||
//note: some registers are not fully reset by SNES
|
||||
regs.pc = 0x000000;
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
regs.s.h = 0x01;
|
||||
|
@ -39,8 +77,9 @@ void sCPU::reset() {
|
|||
regs.p = 0x34;
|
||||
regs.e = 1;
|
||||
regs.mdr = 0x00;
|
||||
regs.wai = false;
|
||||
update_table();
|
||||
|
||||
status.wai_lock = false;
|
||||
status.interrupt_pending = false;
|
||||
status.interrupt_vector = 0xfffc; //reset vector address
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
class sCPU : public CPU {
|
||||
class sCPU : public CPU, public CPUcore {
|
||||
public:
|
||||
void enter();
|
||||
void op_irq();
|
||||
bool interrupt_pending() { return status.interrupt_pending; }
|
||||
|
||||
#include "core/core.hpp"
|
||||
#include "dma/dma.hpp"
|
||||
#include "memory/memory.hpp"
|
||||
#include "mmio/mmio.hpp"
|
||||
|
@ -11,11 +12,6 @@ public:
|
|||
enum DmaState { DmaInactive, DmaRun, DmaCpuSync };
|
||||
|
||||
struct {
|
||||
//core
|
||||
uint8 opcode;
|
||||
bool in_opcode;
|
||||
|
||||
bool wai_lock;
|
||||
bool interrupt_pending;
|
||||
uint16 interrupt_vector;
|
||||
|
||||
|
@ -75,6 +71,9 @@ public:
|
|||
//$4207-$420a
|
||||
uint16 hirq_pos, virq_pos;
|
||||
|
||||
//$420d
|
||||
unsigned rom_speed;
|
||||
|
||||
//$4214-$4217
|
||||
uint16 r4214;
|
||||
uint16 r4216;
|
||||
|
|
|
@ -93,14 +93,14 @@ bool sCPU::timeup() {
|
|||
bool sCPU::nmi_test() {
|
||||
if(!status.nmi_transition) return false;
|
||||
status.nmi_transition = false;
|
||||
status.wai_lock = false;
|
||||
regs.wai = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool sCPU::irq_test() {
|
||||
if(!status.irq_transition) return false;
|
||||
status.irq_transition = false;
|
||||
status.wai_lock = false;
|
||||
bool sCPU::irq_test() {
|
||||
if(!status.irq_transition && !regs.irq) return false;
|
||||
status.irq_transition = false;
|
||||
regs.wai = false;
|
||||
return !regs.p.i;
|
||||
}
|
||||
|
||||
|
|
|
@ -29,6 +29,9 @@ void sCPU::scanline() {
|
|||
if(ppu.vcounter() == 0) {
|
||||
//hdma init triggers once every frame
|
||||
event.enqueue(cpu_version == 1 ? 12 + 8 - dma_counter() : 12 + dma_counter(), EventHdmaInit);
|
||||
|
||||
//forcefully sync S-CPU and S-SMP, in case chips are not communicating
|
||||
scheduler.sync_cpusmp();
|
||||
}
|
||||
|
||||
//dram refresh occurs once every scanline
|
||||
|
|
|
@ -582,6 +582,7 @@ int32 fir_samplel, fir_sampler;
|
|||
|
||||
snes.audio.update(msamplel, msampler);
|
||||
scheduler.addclocks_dsp(32 * 3 * 8);
|
||||
scheduler.sync_dspsmp();
|
||||
}
|
||||
|
||||
aDSP::aDSP() {}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#if !defined(USE_STATE_MACHINE)
|
||||
#define phase_start() while(true) {
|
||||
#define phase(n)
|
||||
#define tick() scheduler.addclocks_dsp(3 * 8)
|
||||
#define tick() scheduler.addclocks_dsp(3 * 8); scheduler.sync_dspsmp()
|
||||
#define phase_end() }
|
||||
#else
|
||||
#define phase_start() switch(phase_index) {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "memory/smemory/smemory.hpp"
|
||||
|
||||
#include "cpu/cpu.hpp"
|
||||
#include "cpu/core/core.hpp"
|
||||
#include "cpu/scpu/scpu.hpp"
|
||||
|
||||
#include "ppu/ppu.hpp"
|
||||
|
|
|
@ -0,0 +1,175 @@
|
|||
#include "bpp.hpp"
|
||||
|
||||
bool BPP::process_macro(Macro ¯o, const lstring &arg) {
|
||||
lstring linedata;
|
||||
linedata.split("\n", macro.data);
|
||||
|
||||
for(unsigned i = 0; i < linedata.size(); i++) {
|
||||
string line = linedata[i];
|
||||
|
||||
for(unsigned j = 0; j < macro.args; j++) {
|
||||
line.replace(macro.arg[j], arg[j]);
|
||||
}
|
||||
|
||||
for(unsigned j = 0; j < global.size(); j++) {
|
||||
line.replace(global[j].name, global[j].data);
|
||||
}
|
||||
|
||||
output.print(string() << line << "\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BPP::process(const char *inputfn) {
|
||||
string filedata;
|
||||
if(filedata.readfile(inputfn) == false) {
|
||||
fprintf(stdout, "error: failed to open input file '%s'\n", inputfn);
|
||||
return false;
|
||||
}
|
||||
|
||||
filedata.replace("\r", "");
|
||||
lstring linedata;
|
||||
linedata.split("\n", filedata);
|
||||
|
||||
for(unsigned i = 0; i < linedata.size();) {
|
||||
string line = linedata[i];
|
||||
trim(line);
|
||||
line.replace("\t", " ");
|
||||
|
||||
if(strbegin(line, "@") == false) {
|
||||
output.print(string() << linedata[i] << "\n");
|
||||
i++;
|
||||
} else if(strbegin(line, "@include ")) {
|
||||
ltrim(line, "@include ");
|
||||
trim(line, "\"");
|
||||
if(process(line) == false) return false;
|
||||
i++;
|
||||
} else if(strbegin(line, "@global ")) {
|
||||
ltrim(line, "@global ");
|
||||
while(qstrpos(line, " ") >= 0) line.replace(" ", " ");
|
||||
|
||||
lstring part;
|
||||
part.qsplit(" ", line);
|
||||
if(part.size() != 2) {
|
||||
fprintf(stdout, "error: malformed global\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned n = global.size();
|
||||
global[n].name = string() << "{" << part[0] << "}";
|
||||
global[n].data = trim(part[1], "\"");
|
||||
i++;
|
||||
} else if(strbegin(line, "@macro ")) {
|
||||
ltrim(line, "@macro ");
|
||||
|
||||
int pos = strpos(line, "(");
|
||||
if(pos < 0 || !strend(line, ")")) {
|
||||
fprintf(stdout, "error: malformed macro\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
string name = substr(line, 0, pos);
|
||||
line = substr(line, pos);
|
||||
ltrim(line, "(");
|
||||
rtrim(line, ")");
|
||||
line.qreplace(" ", "");
|
||||
|
||||
unsigned n = macro.size();
|
||||
macro[n].name = name;
|
||||
|
||||
if(line == "") {
|
||||
macro[n].args = 0;
|
||||
} else {
|
||||
lstring arg;
|
||||
arg.split(",", line);
|
||||
if(arg.size() >= 8) {
|
||||
fprintf(stdout, "error: too many macro arguments\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
macro[n].args = arg.size();
|
||||
for(unsigned j = 0; j < arg.size(); j++) {
|
||||
macro[n].arg[j] = string() << "{" << arg[j] << "}";
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
|
||||
while(i < linedata.size()) {
|
||||
string line = linedata[i];
|
||||
trim(line);
|
||||
if(line == "@endmacro") break;
|
||||
macro[n].data << linedata[i++] << "\n";
|
||||
}
|
||||
|
||||
i++;
|
||||
} else {
|
||||
ltrim(line, "@");
|
||||
int pos = strpos(line, "(");
|
||||
if(pos < 0 || !strend(line, ")")) {
|
||||
fprintf(stdout, "error: malformed macro invocation\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
string name = substr(line, 0, pos);
|
||||
line = substr(line, pos);
|
||||
ltrim(line, "(");
|
||||
rtrim(line, ")");
|
||||
line.qreplace(" ", "");
|
||||
|
||||
lstring arg;
|
||||
if(line != "") arg.qsplit(",", line);
|
||||
for(unsigned j = 0; j < arg.size(); j++) {
|
||||
trim(arg[j], "\"");
|
||||
}
|
||||
|
||||
bool success = false;
|
||||
for(unsigned j = 0; j < macro.size(); j++) {
|
||||
if(name == macro[j].name && arg.size() == macro[j].args) {
|
||||
success = process_macro(macro[j], arg);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(success == false) {
|
||||
fprintf(stdout, "error: unable to process macro '%s'\n", (const char*)name);
|
||||
return false;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BPP::process(const char *outputfn, const char *inputfn) {
|
||||
if(file::exists(inputfn) == false) {
|
||||
fprintf(stdout, "error: failed to open input file\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if(output.open(outputfn, file::mode_write) == false) {
|
||||
fprintf(stdout, "error: failed to open output file\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = process(inputfn);
|
||||
output.close();
|
||||
return result;
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
if(argc != 3) {
|
||||
fprintf(stdout, "bpp v0.01\n");
|
||||
fprintf(stdout, "author: byuu\n");
|
||||
fprintf(stdout, "usage: bpp output input\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
BPP bpp;
|
||||
bool success = bpp.process(argv[1], argv[2]);
|
||||
if(success == false) fprintf(stdout, "error: pre-processing failed\n");
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
#include <nall/array.hpp>
|
||||
#include <nall/file.hpp>
|
||||
#include <nall/stdint.hpp>
|
||||
#include <nall/string.hpp>
|
||||
#include <nall/vector.hpp>
|
||||
using namespace nall;
|
||||
|
||||
class BPP {
|
||||
public:
|
||||
bool process(const char *outputfn, const char *inputfn);
|
||||
|
||||
private:
|
||||
nall::file output;
|
||||
|
||||
struct Global {
|
||||
string name;
|
||||
string data;
|
||||
};
|
||||
vector<Global> global;
|
||||
|
||||
struct Macro {
|
||||
string name;
|
||||
unsigned args;
|
||||
string arg[8];
|
||||
string data;
|
||||
};
|
||||
vector<Macro> macro;
|
||||
|
||||
bool process_macro(Macro ¯o, const lstring &arg);
|
||||
bool process(const char *inputfn);
|
||||
};
|
|
@ -1,6 +1,15 @@
|
|||
rm -r nall
|
||||
rm -r ruby
|
||||
rm -r bpp
|
||||
|
||||
cp -r ../../../nall ./nall
|
||||
cp -r ../../../ruby ./ruby
|
||||
cp -r ../../../bpp ./bpp
|
||||
|
||||
rm ruby/test*
|
||||
rm ruby/cc.*
|
||||
|
||||
rm bpp/test*
|
||||
rm bpp/*.bpp
|
||||
rm bpp/bpp
|
||||
rm bpp/cc.*
|
||||
|
|
|
@ -16,9 +16,9 @@ int32_t op_count, line_num;
|
|||
void clear_op_list() {
|
||||
op_count = 0;
|
||||
for(unsigned i = 0; i < 64; i++) {
|
||||
strcpy(op_list[i].name, "");
|
||||
op_list[i].name = "";
|
||||
for(unsigned l = 0; l < 8; l++) {
|
||||
strcpy(op_list[i].arg[l], "");
|
||||
op_list[i].arg[l] = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -32,22 +32,22 @@ void gen_begin() {
|
|||
string temp = line[i];
|
||||
rtrim(temp, "),");
|
||||
rtrim(temp, ") {");
|
||||
split(subpart, "(", temp);
|
||||
strcpy(op_list[z].name, subpart[0]);
|
||||
split(part, ", ", subpart[1]);
|
||||
for(unsigned l = 0; l < count(part); l++) {
|
||||
strcpy(op_list[z].arg[l], part[l]);
|
||||
subpart.split("(", temp);
|
||||
op_list[z].name = subpart[0];
|
||||
part.split(", ", subpart[1]);
|
||||
for(unsigned l = 0; l < part.size(); l++) {
|
||||
op_list[z].arg[l] = part[l];
|
||||
}
|
||||
if(strend(line[i], " {") == true) break;
|
||||
i++;
|
||||
}
|
||||
|
||||
strcpy(output_op, "//$$\r\ncase $0: {\r\n");
|
||||
output_op = "//$$\r\ncase $0: {\r\n";
|
||||
line_num = i + 1;
|
||||
}
|
||||
|
||||
void update_line(int i) {
|
||||
replace(line[i], "end;", "break;");
|
||||
line[i].replace("end;", "break;");
|
||||
}
|
||||
|
||||
void gen_op() {
|
||||
|
@ -57,7 +57,7 @@ void gen_op() {
|
|||
if(!strcmp(line[i], "}"))break;
|
||||
|
||||
//remove cycle number
|
||||
n = strdec((const char*)line[i]);
|
||||
n = strunsigned(line[i]);
|
||||
sprintf(t, "%d:", n);
|
||||
ltrim(line[i], t);
|
||||
//sprintf(t, "//%d:\r\n", n);
|
||||
|
@ -65,9 +65,9 @@ void gen_op() {
|
|||
|
||||
update_line(i);
|
||||
if(strcmp(line[i], "")) {
|
||||
strcat(output_op, " ");
|
||||
strcat(output_op, line[i]);
|
||||
strcat(output_op, "\r\n");
|
||||
output_op << " ";
|
||||
output_op << line[i];
|
||||
output_op << "\r\n";
|
||||
}
|
||||
|
||||
i++;
|
||||
|
@ -75,14 +75,14 @@ void gen_op() {
|
|||
if(line[i][1] == ':' || line[i][2] == ':' || line[i] == "}") break;
|
||||
|
||||
update_line(i);
|
||||
strcat(output_op, line[i]);
|
||||
strcat(output_op, "\r\n");
|
||||
output_op << line[i];
|
||||
output_op << "\r\n";
|
||||
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
strcat(output_op, "} break;");
|
||||
output_op << "} break;";
|
||||
line_num = i + 1;
|
||||
}
|
||||
|
||||
|
@ -90,32 +90,32 @@ void gen_end() {
|
|||
string t;
|
||||
for(unsigned i = 0; i < op_count; i++) {
|
||||
t = output_op;
|
||||
replace(t, "$$", op_list[i].name);
|
||||
replace(t, "$0", op_list[i].arg[0]);
|
||||
replace(t, "$1", op_list[i].arg[1]);
|
||||
replace(t, "$2", op_list[i].arg[2]);
|
||||
replace(t, "$3", op_list[i].arg[3]);
|
||||
replace(t, "$4", op_list[i].arg[4]);
|
||||
replace(t, "$5", op_list[i].arg[5]);
|
||||
replace(t, "$6", op_list[i].arg[6]);
|
||||
replace(t, "$7", op_list[i].arg[7]);
|
||||
t.replace("$$", op_list[i].name);
|
||||
t.replace("$0", op_list[i].arg[0]);
|
||||
t.replace("$1", op_list[i].arg[1]);
|
||||
t.replace("$2", op_list[i].arg[2]);
|
||||
t.replace("$3", op_list[i].arg[3]);
|
||||
t.replace("$4", op_list[i].arg[4]);
|
||||
t.replace("$5", op_list[i].arg[5]);
|
||||
t.replace("$6", op_list[i].arg[6]);
|
||||
t.replace("$7", op_list[i].arg[7]);
|
||||
fprintf(fp, "%s\r\n\r\n", (const char*)t);
|
||||
}
|
||||
}
|
||||
|
||||
void generate(const char *dest, const char *src) {
|
||||
fread(data, src);
|
||||
replace(data, "\r\n", "\n");
|
||||
split(line, "\n", data);
|
||||
data.readfile(src);
|
||||
data.replace("\r\n", "\n");
|
||||
line.split("\n", data);
|
||||
|
||||
fp = fopen(dest, "wb");
|
||||
string header = CLASS_NAME;
|
||||
fprintf(fp, "#ifdef %s_CPP\n\n", (const char*)strupper(header)); //inclusion guard
|
||||
|
||||
line_num = 0;
|
||||
while(line_num < count(line)) {
|
||||
while(line_num < count(line) && !strcmp(line[line_num], "")) line_num++;
|
||||
if(line_num >= count(line)) break;
|
||||
while(line_num < line.size()) {
|
||||
while(line_num < line.size() && !strcmp(line[line_num], "")) line_num++;
|
||||
if(line_num >= line.size()) break;
|
||||
|
||||
gen_begin();
|
||||
gen_op();
|
||||
|
|
|
@ -67,7 +67,6 @@ void Bus::map(
|
|||
) {
|
||||
assert(bank_lo <= bank_hi);
|
||||
assert(addr_lo <= addr_hi);
|
||||
|
||||
if(access.size() == -1U) return;
|
||||
|
||||
uint8 page_lo = addr_lo >> 8;
|
||||
|
|
|
@ -91,25 +91,11 @@ public:
|
|||
return p.access->write(p.offset + addr, data);
|
||||
}
|
||||
|
||||
void set_speed(bool fast) {
|
||||
fastSpeed = fast ? 6 : 8;
|
||||
}
|
||||
virtual bool load_cart() { return false; }
|
||||
virtual void unload_cart() {}
|
||||
|
||||
alwaysinline unsigned speed(unsigned addr) const {
|
||||
if(addr & 0x408000) {
|
||||
if(addr & 0x800000) return fastSpeed;
|
||||
return 8;
|
||||
}
|
||||
if((addr + 0x6000) & 0x4000) return 8;
|
||||
if((addr - 0x4000) & 0x7e00) return 6;
|
||||
return 12;
|
||||
}
|
||||
|
||||
virtual bool load_cart() = 0;
|
||||
virtual void unload_cart() = 0;
|
||||
|
||||
virtual void power() = 0;
|
||||
virtual void reset() = 0;
|
||||
virtual void power() {}
|
||||
virtual void reset() {}
|
||||
|
||||
Bus() {}
|
||||
virtual ~Bus() {}
|
||||
|
@ -119,7 +105,6 @@ protected:
|
|||
Memory *access;
|
||||
unsigned offset;
|
||||
} page[65536];
|
||||
unsigned fastSpeed;
|
||||
};
|
||||
|
||||
namespace memory {
|
||||
|
|
|
@ -32,6 +32,10 @@ void sBus::map_generic() {
|
|||
map_generic_sram();
|
||||
} break;
|
||||
|
||||
case Cartridge::SA1ROM: {
|
||||
//mapped via SA1Bus::init();
|
||||
} break;
|
||||
|
||||
case Cartridge::SPC7110ROM: {
|
||||
map(MapDirect, 0x00, 0x00, 0x6000, 0x7fff, spc7110); //save RAM w/custom logic
|
||||
map(MapShadow, 0x00, 0x0f, 0x8000, 0xffff, memory::cartrom); //program ROM
|
||||
|
|
|
@ -14,7 +14,6 @@ void sBus::power() {
|
|||
}
|
||||
|
||||
void sBus::reset() {
|
||||
set_speed(false);
|
||||
}
|
||||
|
||||
bool sBus::load_cart() {
|
||||
|
|
|
@ -36,6 +36,7 @@ void bPPU::enter() {
|
|||
void bPPU::add_clocks(unsigned clocks) {
|
||||
tock(clocks);
|
||||
scheduler.addclocks_ppu(clocks);
|
||||
scheduler.sync_ppucpu();
|
||||
}
|
||||
|
||||
void bPPU::scanline() {
|
||||
|
|
|
@ -2,20 +2,25 @@
|
|||
|
||||
#include "opfn.cpp"
|
||||
|
||||
void sSMP::enter() { loop:
|
||||
tracer.trace_smpop(); //traces SMP opcode (only if tracer is enabled)
|
||||
void sSMP::enter() {
|
||||
while(true) {
|
||||
tracer.trace_smpop(); //traces SMP opcode (only if tracer is enabled)
|
||||
|
||||
status.in_opcode = true;
|
||||
switch(op_readpc()) {
|
||||
#include "op_mov.cpp"
|
||||
#include "op_pc.cpp"
|
||||
#include "op_read.cpp"
|
||||
#include "op_rmw.cpp"
|
||||
#include "op_misc.cpp"
|
||||
switch(op_readpc()) {
|
||||
#include "op_mov.cpp"
|
||||
#include "op_pc.cpp"
|
||||
#include "op_read.cpp"
|
||||
#include "op_rmw.cpp"
|
||||
#include "op_misc.cpp"
|
||||
}
|
||||
|
||||
//forcefully sync S-CPU and S-SMP, in case chips are not communicating
|
||||
static unsigned counter = 0;
|
||||
if(++counter & 4096) {
|
||||
counter = 0;
|
||||
scheduler.sync_smpcpu();
|
||||
}
|
||||
}
|
||||
status.in_opcode = false;
|
||||
|
||||
goto loop;
|
||||
}
|
||||
|
||||
#endif //ifdef SSMP_CPP
|
||||
|
|
|
@ -2,6 +2,11 @@
|
|||
|
||||
void sSMP::add_clocks(unsigned clocks) {
|
||||
scheduler.addclocks_smp(clocks);
|
||||
#if !defined(USE_STATE_MACHINE)
|
||||
scheduler.sync_smpdsp();
|
||||
#else
|
||||
while(scheduler.clock.smpdsp < 0) dsp.enter();
|
||||
#endif
|
||||
}
|
||||
|
||||
void sSMP::tick_timers() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
template<uint8 cycle_frequency>
|
||||
template<uint8_t cycle_frequency>
|
||||
class sSMPTimer {
|
||||
public:
|
||||
uint8 target;
|
||||
|
@ -31,4 +31,4 @@ public:
|
|||
|
||||
alwaysinline void add_clocks(unsigned clocks);
|
||||
alwaysinline void tick_timers();
|
||||
uint32 clocks_executed();
|
||||
uint32_t clocks_executed();
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
Scheduler scheduler;
|
||||
|
||||
void threadentry_cpu() { cpu.enter(); }
|
||||
void threadentry_cop() { snes.coprocessor_enter(); }
|
||||
void threadentry_smp() { smp.enter(); }
|
||||
void threadentry_ppu() { ppu.enter(); }
|
||||
void threadentry_dsp() { dsp.enter(); }
|
||||
|
@ -10,6 +11,7 @@ void threadentry_dsp() { dsp.enter(); }
|
|||
void Scheduler::enter() {
|
||||
switch(clock.active) {
|
||||
case THREAD_CPU: co_switch(thread_cpu); break;
|
||||
case THREAD_COP: co_switch(thread_cop); break;
|
||||
case THREAD_SMP: co_switch(thread_smp); break;
|
||||
case THREAD_PPU: co_switch(thread_ppu); break;
|
||||
case THREAD_DSP: co_switch(thread_dsp); break;
|
||||
|
@ -29,17 +31,20 @@ void Scheduler::init() {
|
|||
: snes.config.smp.pal_clock_rate;
|
||||
|
||||
clock.active = THREAD_CPU;
|
||||
clock.cpucop = 0;
|
||||
clock.cpuppu = 0;
|
||||
clock.cpusmp = 0;
|
||||
clock.smpdsp = 0;
|
||||
|
||||
if(thread_cpu) co_delete(thread_cpu);
|
||||
if(thread_cop) co_delete(thread_cop);
|
||||
if(thread_smp) co_delete(thread_smp);
|
||||
if(thread_ppu) co_delete(thread_ppu);
|
||||
if(thread_dsp) co_delete(thread_dsp);
|
||||
|
||||
thread_snes = co_active();
|
||||
thread_cpu = co_create(65536 * sizeof(void*), threadentry_cpu);
|
||||
thread_cop = co_create(65536 * sizeof(void*), threadentry_cop);
|
||||
thread_smp = co_create(65536 * sizeof(void*), threadentry_smp);
|
||||
thread_ppu = co_create(65536 * sizeof(void*), threadentry_ppu);
|
||||
thread_dsp = co_create(65536 * sizeof(void*), threadentry_dsp);
|
||||
|
@ -48,9 +53,10 @@ void Scheduler::init() {
|
|||
Scheduler::Scheduler() {
|
||||
thread_snes = 0;
|
||||
thread_cpu = 0;
|
||||
thread_cop = 0;
|
||||
thread_smp = 0;
|
||||
thread_ppu = 0;
|
||||
thread_dsp = 0;
|
||||
}
|
||||
|
||||
#endif //ifdef SNES_CPP
|
||||
#endif
|
||||
|
|
|
@ -1,13 +1,20 @@
|
|||
//scheduler thread relationships:
|
||||
//S-PPU <-> S-CPU <-> cartridge co-processor
|
||||
// <|>
|
||||
// S-SMP <-> S-DSP
|
||||
|
||||
class Scheduler {
|
||||
public:
|
||||
cothread_t thread_snes;
|
||||
cothread_t thread_cpu;
|
||||
cothread_t thread_smp;
|
||||
cothread_t thread_ppu;
|
||||
cothread_t thread_dsp;
|
||||
cothread_t thread_cpu; //S-CPU (5a22)
|
||||
cothread_t thread_cop; //cartridge co-processor (SuperFX, SA-1, ...)
|
||||
cothread_t thread_smp; //S-SMP (SPC700)
|
||||
cothread_t thread_ppu; //S-PPU
|
||||
cothread_t thread_dsp; //S-DSP
|
||||
|
||||
enum ActiveThread {
|
||||
THREAD_CPU,
|
||||
THREAD_COP,
|
||||
THREAD_SMP,
|
||||
THREAD_PPU,
|
||||
THREAD_DSP,
|
||||
|
@ -18,11 +25,30 @@ public:
|
|||
unsigned smp_freq;
|
||||
|
||||
ActiveThread active;
|
||||
int64 cpuppu;
|
||||
int64 cpusmp;
|
||||
int64 smpdsp;
|
||||
int64_t cpucop;
|
||||
int64_t cpuppu;
|
||||
int64_t cpusmp;
|
||||
int64_t smpdsp;
|
||||
} clock;
|
||||
|
||||
//==========
|
||||
//CPU <> COP
|
||||
//==========
|
||||
|
||||
alwaysinline void sync_cpucop() {
|
||||
if(clock.cpucop < 0) {
|
||||
clock.active = THREAD_COP;
|
||||
co_switch(thread_cop);
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sync_copcpu() {
|
||||
if(clock.cpucop >= 0) {
|
||||
clock.active = THREAD_CPU;
|
||||
co_switch(thread_cpu);
|
||||
}
|
||||
}
|
||||
|
||||
//==========
|
||||
//CPU <> PPU
|
||||
//==========
|
||||
|
@ -77,40 +103,31 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
//======
|
||||
//timing
|
||||
//======
|
||||
//==========
|
||||
//add clocks
|
||||
//==========
|
||||
|
||||
alwaysinline void addclocks_cpu(unsigned clocks) {
|
||||
clock.cpucop -= clocks;
|
||||
clock.cpuppu -= clocks;
|
||||
sync_cpuppu();
|
||||
clock.cpusmp -= clocks * (uint64_t)clock.smp_freq;
|
||||
}
|
||||
|
||||
clock.cpusmp -= clocks * (uint64)clock.smp_freq;
|
||||
if(clock.cpusmp < -(20000 * (int64)24000000)) sync_cpusmp();
|
||||
alwaysinline void addclocks_cop(unsigned clocks) {
|
||||
clock.cpucop += clocks;
|
||||
}
|
||||
|
||||
alwaysinline void addclocks_ppu(unsigned clocks) {
|
||||
clock.cpuppu += clocks;
|
||||
sync_ppucpu();
|
||||
}
|
||||
|
||||
alwaysinline void addclocks_smp(unsigned clocks) {
|
||||
clock.cpusmp += clocks * (uint64)clock.cpu_freq;
|
||||
if(clock.cpusmp > +(20000 * (int64)24000000)) sync_smpcpu();
|
||||
|
||||
clock.cpusmp += clocks * (uint64_t)clock.cpu_freq;
|
||||
clock.smpdsp -= clocks;
|
||||
#if !defined(USE_STATE_MACHINE)
|
||||
sync_smpdsp();
|
||||
#else
|
||||
while(clock.smpdsp < 0) dsp.enter();
|
||||
#endif
|
||||
}
|
||||
|
||||
alwaysinline void addclocks_dsp(unsigned clocks) {
|
||||
clock.smpdsp += clocks;
|
||||
#if !defined(USE_STATE_MACHINE)
|
||||
sync_dspsmp();
|
||||
#endif
|
||||
}
|
||||
|
||||
void enter();
|
||||
|
|
|
@ -10,6 +10,8 @@ SMPCORE smp;
|
|||
DSPCORE dsp;
|
||||
PPUCORE ppu;
|
||||
|
||||
SA1 sa1;
|
||||
SA1Bus sa1bus;
|
||||
BSXBase bsxbase;
|
||||
BSXCart bsxcart;
|
||||
BSXFlash bsxflash;
|
||||
|
@ -31,6 +33,15 @@ ST010 st010;
|
|||
#include "audio/audio.cpp"
|
||||
#include "input/input.cpp"
|
||||
|
||||
void SNES::coprocessor_enter() {
|
||||
if(cartridge.has_sa1()) sa1.enter();
|
||||
|
||||
while(true) {
|
||||
scheduler.addclocks_cop(64 * 1024 * 1024);
|
||||
scheduler.sync_copcpu();
|
||||
}
|
||||
}
|
||||
|
||||
void SNES::run() {
|
||||
}
|
||||
|
||||
|
@ -39,6 +50,7 @@ void SNES::runtoframe() {
|
|||
}
|
||||
|
||||
void SNES::init() {
|
||||
sa1.init();
|
||||
bsxbase.init();
|
||||
bsxcart.init();
|
||||
bsxflash.init();
|
||||
|
@ -84,6 +96,7 @@ void SNES::power() {
|
|||
if(cartridge.mode() == Cartridge::ModeBsx) bsxcart.power();
|
||||
if(cartridge.bsx_flash_loaded()) bsxflash.power();
|
||||
|
||||
if(cartridge.has_sa1()) sa1.power();
|
||||
if(cartridge.has_srtc()) srtc.power();
|
||||
if(cartridge.has_sdd1()) sdd1.power();
|
||||
if(cartridge.has_spc7110()) spc7110.power();
|
||||
|
@ -106,6 +119,7 @@ void SNES::power() {
|
|||
if(cartridge.mode() == Cartridge::ModeBsx) bsxcart.enable();
|
||||
if(cartridge.bsx_flash_loaded()) bsxflash.enable();
|
||||
|
||||
if(cartridge.has_sa1()) sa1.enable();
|
||||
if(cartridge.has_srtc()) srtc.enable();
|
||||
if(cartridge.has_sdd1()) sdd1.enable();
|
||||
if(cartridge.has_spc7110()) spc7110.enable();
|
||||
|
@ -137,6 +151,7 @@ void SNES::reset() {
|
|||
if(cartridge.mode() == Cartridge::ModeBsx) bsxcart.reset();
|
||||
if(cartridge.bsx_flash_loaded()) bsxflash.reset();
|
||||
|
||||
if(cartridge.has_sa1()) sa1.reset();
|
||||
if(cartridge.has_srtc()) srtc.reset();
|
||||
if(cartridge.has_sdd1()) sdd1.reset();
|
||||
if(cartridge.has_spc7110()) spc7110.reset();
|
||||
|
|
|
@ -6,6 +6,8 @@ class VideoFilter;
|
|||
|
||||
class SNES {
|
||||
public:
|
||||
void coprocessor_enter();
|
||||
|
||||
enum Region { NTSC = 0, PAL = 1 };
|
||||
enum RegionAutodetect { Autodetect = 2 };
|
||||
enum ExpansionPortDevice { ExpansionNone = 0, ExpansionBSX = 1 };
|
||||
|
|
|
@ -16,7 +16,6 @@ void tprintf(const char *s, ...) {
|
|||
void Tracer::trace_cpuop() {
|
||||
if(enabled() == false) return;
|
||||
if(cpuop_enabled() == false) return;
|
||||
if(cpu.in_opcode() == true) return;
|
||||
|
||||
if(cpuopmask_enabled() == true) {
|
||||
unsigned addr = cpu.regs.pc.d;
|
||||
|
@ -32,7 +31,6 @@ void Tracer::trace_cpuop() {
|
|||
void Tracer::trace_smpop() {
|
||||
if(enabled() == false) return;
|
||||
if(smpop_enabled() == false) return;
|
||||
if(smp.in_opcode() == true) return;
|
||||
|
||||
if(smpopmask_enabled() == true) {
|
||||
unsigned addr = smp.regs.pc;
|
||||
|
|
|
@ -3,7 +3,7 @@ void MainWindow::setup() {
|
|||
window->setObjectName("main-window");
|
||||
window->setWindowTitle(BSNES_TITLE);
|
||||
|
||||
system = window->menuBar()->addMenu("&System");
|
||||
system = window->menuBar()->addMenu("System");
|
||||
system_load = system->addAction("&Load Cartridge ...");
|
||||
system->addSeparator();
|
||||
system_power = system->addMenu("&Power");
|
||||
|
@ -41,7 +41,7 @@ void MainWindow::setup() {
|
|||
system_exit = system->addAction("E&xit");
|
||||
system_exit->setMenuRole(QAction::QuitRole);
|
||||
|
||||
settings = window->menuBar()->addMenu("S&ettings");
|
||||
settings = window->menuBar()->addMenu("Settings");
|
||||
settings_videoMode = settings->addMenu("&Video Mode");
|
||||
settings_videoMode_1x = settings_videoMode->addAction("Scale &1x");
|
||||
settings_videoMode_1x->setCheckable(true);
|
||||
|
@ -110,7 +110,7 @@ void MainWindow::setup() {
|
|||
settings_configuration = settings->addAction("&Configuration ...");
|
||||
settings_configuration->setMenuRole(QAction::PreferencesRole);
|
||||
|
||||
help = window->menuBar()->addMenu("&Help");
|
||||
help = window->menuBar()->addMenu("Help");
|
||||
help_documentation = help->addAction("Documentation ...");
|
||||
help_license = help->addAction("License ...");
|
||||
help->addSeparator();
|
||||
|
|
|
@ -117,7 +117,8 @@ int Application::main(int argc, char **argv) {
|
|||
inputManager.refresh();
|
||||
|
||||
if(config.input.focusPolicy == Configuration::Input::FocusPolicyPauseEmulation) {
|
||||
bool inactive = (winMain->window->isActiveWindow() == false);
|
||||
bool inactive = (winMain->window->isActiveWindow() == false)
|
||||
|| (winMain->window->isMinimized() == true);
|
||||
if(!autopause && inactive) {
|
||||
autopause = true;
|
||||
audio.clear();
|
||||
|
|
|
@ -37,8 +37,8 @@ void InputCaptureWindow::setup() {
|
|||
connect(mouseAxes, SIGNAL(released()), this, SLOT(assignMouseAxis()));
|
||||
connect(mouseButtons, SIGNAL(released()), this, SLOT(assignMouseButton()));
|
||||
|
||||
winInputMouseCaptureWindow = new InputMouseCaptureWindow;
|
||||
winInputMouseCaptureWindow->setup();
|
||||
winInputMouseCapture = new InputMouseCaptureWindow;
|
||||
winInputMouseCapture->setup();
|
||||
|
||||
winInputCalibration = new InputCalibrationWindow;
|
||||
winInputCalibration->setup();
|
||||
|
@ -96,8 +96,8 @@ void InputCaptureWindow::inputEvent(uint16_t code, bool forceAssign /* = false *
|
|||
//input polling is global, need to block mouse actions that may be UI interactions.
|
||||
//custom controls on window allow mouse assignment instead.
|
||||
if(forceAssign == false) {
|
||||
if(winInputMouseCaptureWindow->window->isActiveWindow()) {
|
||||
winInputMouseCaptureWindow->inputEvent(code);
|
||||
if(winInputMouseCapture->window->isActiveWindow()) {
|
||||
winInputMouseCapture->inputEvent(code);
|
||||
return;
|
||||
}
|
||||
if(!window->isActiveWindow()) return;
|
||||
|
@ -205,7 +205,7 @@ void InputCaptureWindow::inputEvent(uint16_t code, bool forceAssign /* = false *
|
|||
|
||||
if(!activeGroup) {
|
||||
window->hide();
|
||||
winInputMouseCaptureWindow->window->hide();
|
||||
winInputMouseCapture->window->hide();
|
||||
} else {
|
||||
//try and map the next code in this input group
|
||||
groupIndex++;
|
||||
|
@ -214,7 +214,7 @@ void InputCaptureWindow::inputEvent(uint16_t code, bool forceAssign /* = false *
|
|||
} else {
|
||||
//all group codes mapped
|
||||
window->hide();
|
||||
winInputMouseCaptureWindow->window->hide();
|
||||
winInputMouseCapture->window->hide();
|
||||
activeGroup = 0;
|
||||
}
|
||||
}
|
||||
|
@ -224,12 +224,12 @@ void InputCaptureWindow::assignMouseAxis() {
|
|||
//refresh input state so that mouse release event (from SIGNAL(released())
|
||||
//is not sent immediately after window is visible.
|
||||
inputManager.refresh();
|
||||
winInputMouseCaptureWindow->activate(InputMouseCaptureWindow::AxisMode);
|
||||
winInputMouseCapture->activate(InputMouseCaptureWindow::AxisMode);
|
||||
}
|
||||
|
||||
void InputCaptureWindow::assignMouseButton() {
|
||||
inputManager.refresh();
|
||||
winInputMouseCaptureWindow->activate(InputMouseCaptureWindow::ButtonMode);
|
||||
winInputMouseCapture->activate(InputMouseCaptureWindow::ButtonMode);
|
||||
}
|
||||
|
||||
InputCaptureWindow::InputCaptureWindow() {
|
||||
|
@ -243,6 +243,9 @@ void InputCaptureWindow::Window::closeEvent(QCloseEvent*) {
|
|||
//window closed by user, cancel key assignment
|
||||
winInputCapture->activeObject = 0;
|
||||
winInputCapture->activeGroup = 0;
|
||||
|
||||
winInputMouseCapture->window->hide();
|
||||
winInputCalibration->dismiss();
|
||||
}
|
||||
|
||||
void InputCaptureWindow::ImageWidget::paintEvent(QPaintEvent*) {
|
||||
|
@ -452,3 +455,7 @@ void InputCalibrationWindow::dismiss() {
|
|||
void InputCalibrationWindow::Window::closeEvent(QCloseEvent*) {
|
||||
winInputCalibration->dismiss();
|
||||
}
|
||||
|
||||
InputCalibrationWindow::InputCalibrationWindow() {
|
||||
activeJoypad = -1;
|
||||
}
|
||||
|
|
|
@ -61,7 +61,7 @@ public slots:
|
|||
private:
|
||||
Mode activeMode;
|
||||
signed activeMouse;
|
||||
} *winInputMouseCaptureWindow;
|
||||
} *winInputMouseCapture;
|
||||
|
||||
class InputCalibrationWindow : public QObject {
|
||||
Q_OBJECT
|
||||
|
@ -77,6 +77,7 @@ public:
|
|||
|
||||
void setup();
|
||||
void activate(unsigned joy);
|
||||
InputCalibrationWindow();
|
||||
|
||||
public slots:
|
||||
void dismiss();
|
||||
|
|
|
@ -90,10 +90,9 @@ void Utility::modifySystemState(system_state_t state) {
|
|||
//warn if unsupported hardware detected
|
||||
string chip;
|
||||
if(cartridge.has_superfx()) chip = "SuperFX";
|
||||
else if(cartridge.has_sa1()) chip = "SA-1";
|
||||
else if(cartridge.has_st011()) chip = "ST011";
|
||||
else if(cartridge.has_st018()) chip = "ST018";
|
||||
else if(cartridge.has_dsp3()) chip = "DSP-3";
|
||||
else if(cartridge.has_dsp3()) chip = "DSP-3"; //unplayable; only partially supported
|
||||
if(chip != "") {
|
||||
QMessageBox::warning(winMain->window, "Warning", utf8()
|
||||
<< "<p><b>Warning:</b><br>Unsupported " << chip << " chip detected. "
|
||||
|
|
|
@ -2,31 +2,39 @@
|
|||
void Utility::showCentered(QWidget *window) {
|
||||
QRect deskRect = QApplication::desktop()->availableGeometry(window);
|
||||
|
||||
//place window offscreen, so that it can be shown to get proper frameSize()
|
||||
window->move(std::numeric_limits<signed>::max(), std::numeric_limits<signed>::max());
|
||||
#ifdef _WIN32
|
||||
if(window->isMinimized() == false) {
|
||||
//place window offscreen, so that it can be shown to get proper frameSize()
|
||||
window->move(std::numeric_limits<signed>::max(), std::numeric_limits<signed>::max());
|
||||
}
|
||||
window->showNormal();
|
||||
|
||||
//force-resize window to be as small as minimumSize() will allow, and then center it
|
||||
window->resize(0, 0);
|
||||
window->move(
|
||||
deskRect.center().x() - (window->frameSize().width() / 2),
|
||||
deskRect.center().y() - (window->frameSize().height() / 2)
|
||||
);
|
||||
#else
|
||||
if(window->isVisible() == false) window->showMinimized();
|
||||
window->resize(0, 0);
|
||||
|
||||
#ifndef _WIN32
|
||||
//Xlib frame size (excluding inside) is QSize(0, 0) at first, wait for it to be valid
|
||||
//Xlib returns a frame size of 0,0 at first; wait for it to be valid
|
||||
for(unsigned counter = 0; counter < 4096; counter++) {
|
||||
if(window->frameSize() != window->size()) break;
|
||||
application.processEvents();
|
||||
}
|
||||
#endif
|
||||
|
||||
//in case frame size changed, recenter window
|
||||
window->move(
|
||||
deskRect.center().x() - (window->frameSize().width() / 2),
|
||||
deskRect.center().y() - (window->frameSize().height() / 2)
|
||||
);
|
||||
|
||||
for(unsigned counter = 0; counter < 4096; counter++) {
|
||||
window->showNormal();
|
||||
application.processEvents();
|
||||
if(window->isMinimized() == false) break;
|
||||
}
|
||||
#endif
|
||||
|
||||
//ensure window has focus
|
||||
application.processEvents();
|
||||
window->activateWindow();
|
||||
|
@ -84,6 +92,15 @@ void Utility::resizeMainWindow() {
|
|||
//get effective desktop work area region (ignore Windows taskbar, OS X doc, etc.)
|
||||
QRect deskRect = QApplication::desktop()->availableGeometry(winMain->window);
|
||||
|
||||
if(winMain->window->isVisible() == false) {
|
||||
#ifdef _WIN32
|
||||
winMain->window->move(std::numeric_limits<signed>::max(), std::numeric_limits<signed>::max());
|
||||
winMain->window->showNormal();
|
||||
#else
|
||||
winMain->window->showMinimized();
|
||||
#endif
|
||||
}
|
||||
|
||||
//calculate frame geometry (window border + menubar + statusbar)
|
||||
unsigned frameWidth = winMain->window->frameSize().width() - winMain->canvasContainer->size().width();
|
||||
unsigned frameHeight = winMain->window->frameSize().height() - winMain->canvasContainer->size().height();
|
||||
|
|
Loading…
Reference in New Issue