Update to bsnes v016r38 release.

Ok, this WIP rewrites the input code and modifies the PAL clock speed.
Fairly major changes. Ideally, this will wipe out four bugs without
causing any new ones since wip37.

             Bug fixes :
             Earthworm Jim 2 (E) - adjusted PAL CPU clock speed.
Please test for *new* sound problems in PAL games
             La Wares (J) + Galivan 2 (J) - no longer return 0 when
auto joypad is off for polling $4218-$421f
             Super Conflict (J) - added anomie's new OAM RTO findings
to fix title screen

 The input code was almost completely rewritten to simulate real
hardware more. As such, it's very possible there are new input bugs.

             Ok, so then
byuu.cinnamonpirate.com/files/bsnes_v016_wip38.zip
 Please only download if you intend to test games and report feedback.
This version is slower than normal, lacks ZIP+JMA loading, and has the
debugger enabled (that is only useful to me, it lacks a functional
user interface) which slows down emulation even more. eg you're better
off with v0.016 official if you just want to run games.
             As always, please don't post this link anywhere else, or
I will be forced to remove the file to conserve bandwidth.

 If anyone posts bugs that hasn't tested against wip37, can I please
have someone with wip37 verify/deny the bug presence in wip37 as well
as in 016 official? wip37 isn't on my website because I don't have a
lot of web space to spare.

             Thank you to everyone in advance for helping.
This commit is contained in:
byuu 2006-07-27 23:56:42 +00:00
parent e492268025
commit 6010bffe5d
152 changed files with 4239 additions and 5758 deletions

BIN
bsnes.exe

Binary file not shown.

BIN
cart.db Normal file

Binary file not shown.

View File

@ -23,12 +23,13 @@ union {
bit<0x01> c;
};
APURegFlags() { data = 0; }
inline operator unsigned() { return data; }
inline operator unsigned() const { return data; }
inline unsigned operator = (const uint8 i) { data = i; return data; }
inline unsigned operator |= (const uint8 i) { data |= i; return data; }
inline unsigned operator ^= (const uint8 i) { data ^= i; return data; }
inline unsigned operator &= (const uint8 i) { data &= i; return data; }
APURegFlags() : data(0) {}
};
class APURegs {

View File

@ -1,15 +1,9 @@
#include "opfn.cpp"
//#include "op_mov.cpp"
//#include "op_pc.cpp"
//#include "op_read.cpp"
//#include "op_rmw.cpp"
//#include "op_misc.cpp"
void sAPU::main() {
for(;;) {
status.in_opcode = true;
// (this->*optbl[op_readpc()])();
switch(op_readpc()) {
#include "op_mov.cpp"
#include "op_pc.cpp"

View File

@ -1,8 +1,8 @@
uint8 sAPU::op_adc(uint8 x, uint8 y) {
int16 r = x + y + regs.p.c;
regs.p.n = !!(r & 0x80);
regs.p.v = !!(~(x ^ y) & (y ^ (uint8)r) & 0x80);
regs.p.h = !!((x ^ y ^ (uint8)r) & 0x10);
regs.p.n = bool(r & 0x80);
regs.p.v = bool(~(x ^ y) & (y ^ (uint8)r) & 0x80);
regs.p.h = bool((x ^ y ^ (uint8)r) & 0x10);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r > 0xff);
return r;
@ -19,14 +19,14 @@ int16 r;
uint8 sAPU::op_and(uint8 x, uint8 y) {
x &= y;
regs.p.n = !!(x & 0x80);
regs.p.n = bool(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 sAPU::op_cmp(uint8 x, uint8 y) {
int16 r = x - y;
regs.p.n = !!(r & 0x80);
regs.p.n = bool(r & 0x80);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r >= 0);
return x;
@ -34,7 +34,7 @@ int16 r = x - y;
uint16 sAPU::op_cmpw(uint16 x, uint16 y) {
int32 r = x - y;
regs.p.n = !!(r & 0x8000);
regs.p.n = bool(r & 0x8000);
regs.p.z = ((uint16)r == 0);
regs.p.c = (r >= 0);
return x;
@ -42,22 +42,22 @@ int32 r = x - y;
uint8 sAPU::op_eor(uint8 x, uint8 y) {
x ^= y;
regs.p.n = !!(x & 0x80);
regs.p.n = bool(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 sAPU::op_or(uint8 x, uint8 y) {
x |= y;
regs.p.n = !!(x & 0x80);
regs.p.n = bool(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 sAPU::op_sbc(uint8 x, uint8 y) {
int16 r = x - y - !regs.p.c;
regs.p.n = !!(r & 0x80);
regs.p.v = !!((x ^ y) & (x ^ (uint8)r) & 0x80);
regs.p.n = bool(r & 0x80);
regs.p.v = bool((x ^ y) & (x ^ (uint8)r) & 0x80);
regs.p.h = !((x ^ y ^ (uint8)r) & 0x10);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r >= 0);
@ -75,64 +75,64 @@ int16 r;
uint8 sAPU::op_inc(uint8 x) {
x++;
regs.p.n = !!(x & 0x80);
regs.p.n = bool(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint16 sAPU::op_incw(uint16 x) {
x++;
regs.p.n = !!(x & 0x8000);
regs.p.n = bool(x & 0x8000);
regs.p.z = (x == 0);
return x;
}
uint8 sAPU::op_dec(uint8 x) {
x--;
regs.p.n = !!(x & 0x80);
regs.p.n = bool(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint16 sAPU::op_decw(uint16 x) {
x--;
regs.p.n = !!(x & 0x8000);
regs.p.n = bool(x & 0x8000);
regs.p.z = (x == 0);
return x;
}
uint8 sAPU::op_asl(uint8 x) {
regs.p.c = !!(x & 0x80);
regs.p.c = bool(x & 0x80);
x <<= 1;
regs.p.n = !!(x & 0x80);
regs.p.n = bool(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 sAPU::op_lsr(uint8 x) {
regs.p.c = !!(x & 0x01);
regs.p.c = bool(x & 0x01);
x >>= 1;
regs.p.n = !!(x & 0x80);
regs.p.n = bool(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 sAPU::op_rol(uint8 x) {
uint8 c = regs.p.c;
regs.p.c = !!(x & 0x80);
regs.p.c = bool(x & 0x80);
x <<= 1;
x |= c;
regs.p.n = !!(x & 0x80);
regs.p.n = bool(x & 0x80);
regs.p.z = (x == 0);
return x;
}
uint8 sAPU::op_ror(uint8 x) {
uint8 c = (regs.p.c)?0x80:0x00;
regs.p.c = !!(x & 0x01);
regs.p.c = bool(x & 0x01);
x >>= 1;
x |= c;
regs.p.n = !!(x & 0x80);
regs.p.n = bool(x & 0x80);
regs.p.z = (x == 0);
return x;
}

View File

@ -2,6 +2,11 @@ uint8 sAPU::spcram_read(uint16 addr) {
uint8 r;
if((addr & 0xfff0) == 0x00f0) {
//addr >= 0x00f0 && addr <= 0x00ff
#ifdef FAVOR_SPEED
co_return();
#endif
switch(addr) {
case 0xf0: //TEST -- operation unknown, supposedly returns 0x00
r = 0x00;
@ -20,9 +25,6 @@ uint8 r;
case 0xf5: //CPUIO1
case 0xf6: //CPUIO2
case 0xf7: //CPUIO3
#ifdef FAVOR_SPEED
co_return();
#endif
r = r_cpu->port_read(addr & 3);
break;
case 0xf8: //???
@ -66,6 +68,11 @@ uint8 r;
void sAPU::spcram_write(uint16 addr, uint8 data) {
if((addr & 0xfff0) == 0x00f0) {
//addr >= 0x00f0 && addr >= 0x00ff
#ifdef FAVOR_SPEED
co_return();
#endif
switch(addr) {
case 0xf0: //TEST -- operation unknown
break;
@ -115,9 +122,6 @@ void sAPU::spcram_write(uint16 addr, uint8 data) {
case 0xf5: //CPUIO1
case 0xf6: //CPUIO2
case 0xf7: //CPUIO3
#ifdef FAVOR_SPEED
co_return();
#endif
port_write(addr & 3, data);
break;
case 0xf8: //???

View File

@ -1,4 +1,4 @@
#define BSNES_VERSION "0.016.27a"
#define BSNES_VERSION "0.016.38"
#define BSNES_TITLE "bsnes v" BSNES_VERSION
#define MEMCORE bMemBus
@ -14,44 +14,33 @@
#define CHEAT_SYSTEM
//enable GZ, ZIP format support
#define GZIP_SUPPORT
//#define GZIP_SUPPORT
//enable JMA support
#define JMA_SUPPORT
//#define JMA_SUPPORT
//debugging extensions (~10% speed hit)
//#define DEBUGGER
#define DEBUGGER
//snes core polymorphism
//(allow mem/cpu/apu/ppu overriding, ~10% speed hit)
//#define POLYMORPHISM
//this should be declared in the port-specific makefile
//#define ARCH_LSB
//#define ARCH_MSB
#ifndef ARCH_LSB
#ifndef ARCH_MSB
#define ARCH_LSB
#endif
#endif
#if defined(_WIN32)
#define _WIN32_
#undef _UNIX_
#elif defined(__GNUC__)
#define _UNIX_
#undef _WIN32_
#if defined(PROCESSOR_X86)
#define ARCH_LSB
#elif defined(PROCESSOR_X86)
#define ARCH_LSB
#elif defined(PROCESSOR_G5)
#define ARCH_MSB
#else
#error "unknown architecture"
#error "unsupported processor"
#endif
#include "lib/libco_x86.h"
#include "lib/libbase.h"
#include "lib/libco_x86.h"
#include "lib/libvector.h"
#include "lib/libstring.h"
#include "lib/libconfig.h"
#include "lib/libbpf.h"
inline uint16 read16(uint8 *addr, uint pos) {
#ifdef ARCH_LSB

View File

@ -1,87 +1,112 @@
#include "../base.h"
#include "database.cpp"
void Cartridge::read_dbi() {
info.srtc = false;
info.sdd1 = false;
info.c4 = false;
info.dsp1 = false;
info.dsp2 = false;
info.obc1 = false;
info.dsp1_mapper = 0;
info.header_index = 0x7fc0;
info.mapper = PCB;
strcpy(info.name, dbi.name);
strcpy(info.pcb, dbi.pcb);
info.region = NTSC;
info.cart_mmio = false;
info.rom_size = dbi.rom;
info.ram_size = dbi.ram;
}
void Cartridge::read_header() {
cart.srtc = false;
cart.sdd1 = false;
cart.c4 = false;
cart.dsp1 = false;
cart.dsp2 = false;
cart.obc1 = false;
info.srtc = false;
info.sdd1 = false;
info.c4 = false;
info.dsp1 = false;
info.dsp2 = false;
info.obc1 = false;
cart.dsp1_mapper = 0;
info.dsp1_mapper = 0;
if(cart.header_index == 0x7fc0 && cart.rom_size >= 0x401000) {
cart.mapper = EXLOROM;
} else if(cart.header_index == 0x7fc0 && rom[cart.header_index + MAPPER] == 0x32) {
cart.mapper = EXLOROM;
} else if(cart.header_index == 0x7fc0) {
cart.mapper = LOROM;
} else if(cart.header_index == 0xffc0) {
cart.mapper = HIROM;
} else { //cart.header_index == 0x40ffc0
cart.mapper = EXHIROM;
if(info.header_index == 0x7fc0 && info.rom_size >= 0x401000) {
info.mapper = EXLOROM;
strcpy(info.pcb, "UNL-EXLOROM");
} else if(info.header_index == 0x7fc0 && rom[info.header_index + MAPPER] == 0x32) {
info.mapper = EXLOROM;
strcpy(info.pcb, "UNL-EXLOROM");
} else if(info.header_index == 0x7fc0) {
info.mapper = LOROM;
strcpy(info.pcb, "UNL-LOROM");
} else if(info.header_index == 0xffc0) {
info.mapper = HIROM;
strcpy(info.pcb, "UNL-HIROM");
} else { //info.header_index == 0x40ffc0
info.mapper = EXHIROM;
strcpy(info.pcb, "UNL-EXHIROM");
}
uint8 mapper = rom[cart.header_index + MAPPER];
uint8 rom_type = rom[cart.header_index + ROM_TYPE];
uint8 mapper = rom[info.header_index + MAPPER];
uint8 rom_type = rom[info.header_index + ROM_TYPE];
if(mapper == 0x35 && rom_type == 0x55) {
cart.srtc = true;
info.srtc = true;
}
if(mapper == 0x32 && (rom_type == 0x43 || rom_type == 0x45)) {
cart.sdd1 = true;
info.sdd1 = true;
}
if(mapper == 0x20 && rom_type == 0xf3) {
cart.c4 = true;
info.c4 = true;
}
if((mapper == 0x20 || mapper == 0x21) && rom_type == 0x03) {
cart.dsp1 = true;
info.dsp1 = true;
}
if(mapper == 0x30 && rom_type == 0x05) {
cart.dsp1 = true;
info.dsp1 = true;
}
if(mapper == 0x31 && (rom_type == 0x03 || rom_type == 0x05)) {
cart.dsp1 = true;
info.dsp1 = true;
}
if(cart.dsp1 == true) {
if((mapper & 0x2f) == 0x20 && rom_size <= 0x100000) {
cart.dsp1_mapper = DSP1_LOROM_1MB;
if(info.dsp1 == true) {
if((mapper & 0x2f) == 0x20 && info.rom_size <= 0x100000) {
info.dsp1_mapper = DSP1_LOROM_1MB;
} else if((mapper & 0x2f) == 0x20) {
cart.dsp1_mapper = DSP1_LOROM_2MB;
info.dsp1_mapper = DSP1_LOROM_2MB;
} else if((mapper & 0x2f) == 0x21) {
cart.dsp1_mapper = DSP1_HIROM;
info.dsp1_mapper = DSP1_HIROM;
}
}
if(mapper == 0x20 && rom_type == 0x05) {
cart.dsp2 = true;
info.dsp2 = true;
}
if(mapper == 0x30 && rom_type == 0x25) {
cart.obc1 = true;
info.obc1 = true;
}
cart.cart_mmio = cart.c4 | cart.dsp1 | cart.dsp2 | cart.obc1;
info.cart_mmio = info.c4 | info.dsp1 | info.dsp2 | info.obc1;
if(rom[cart.header_index + SRAM_SIZE] & 7) {
cart.sram_size = 1024 << (rom[cart.header_index + SRAM_SIZE] & 7);
if(rom[info.header_index + SRAM_SIZE] & 7) {
info.ram_size = 1024 << (rom[info.header_index + SRAM_SIZE] & 7);
} else {
cart.sram_size = 0;
info.ram_size = 0;
}
cart.region = ((rom[cart.header_index + REGION] & 0x7f) < 2) ? NTSC : PAL;
memcpy(&cart.name, &rom[cart.header_index + CART_NAME], 21);
cart.name[21] = 0;
memcpy(&info.name, &rom[info.header_index + CART_NAME], 21);
info.name[21] = 0;
for(int i = 0; i < 22; i++) {
if(cart.name[i] & 0x80) {
cart.name[i] = '?';
if(info.name[i] & 0x80) {
info.name[i] = '?';
}
}
}
@ -91,9 +116,9 @@ int32 score_lo = 0,
score_hi = 0,
score_ex = 0;
if(rom_size < 0x010000) {
if(info.rom_size < 0x010000) {
//cart too small to be anything but lorom
cart.header_index = 0x007fc0;
info.header_index = 0x007fc0;
return;
}
@ -115,6 +140,9 @@ int32 score_lo = 0,
if(rom[0x7fc0 + LICENSE] < 3)score_lo++;
if(rom[0xffc0 + LICENSE] < 3)score_hi++;
if(rom[0x7fc0 + RESH] & 0x80)score_lo += 2;
if(rom[0xffc0 + RESH] & 0x80)score_hi += 2;
uint16 cksum, icksum;
cksum = rom[0x7fc0 + CKSUM] | (rom[0x7fc0 + CKSUM + 1] << 8);
icksum = rom[0x7fc0 + ICKSUM] | (rom[0x7fc0 + ICKSUM + 1] << 8);
@ -128,7 +156,7 @@ uint16 cksum, icksum;
score_hi += 8;
}
if(rom_size < 0x401000) {
if(info.rom_size < 0x401000) {
score_ex = 0;
} else {
if(rom[0x7fc0 + MAPPER] == 0x32)score_lo++;
@ -136,100 +164,78 @@ uint16 cksum, icksum;
}
if(score_lo >= score_hi && score_lo >= score_ex) {
cart.header_index = 0x007fc0;
info.header_index = 0x007fc0;
} else if(score_hi >= score_ex) {
cart.header_index = 0x00ffc0;
info.header_index = 0x00ffc0;
} else {
cart.header_index = 0x40ffc0;
info.header_index = 0x40ffc0;
}
}
void Cartridge::load_sram() {
if(cart.sram_size == 0) {
if(info.ram_size == 0) {
sram = 0;
return;
}
FileReader ff(sram_fn);
if(!ff.ready()) {
sram = (uint8*)malloc(cart.sram_size);
memset(sram, 0, cart.sram_size);
sram = (uint8*)malloc(info.ram_size);
memset(sram, 0, info.ram_size);
return;
}
sram = ff.read(cart.sram_size);
sram = ff.read(info.ram_size);
}
void Cartridge::save_sram() {
if(cart.sram_size == 0)return;
if(info.ram_size == 0)return;
FileWriter ff(sram_fn);
if(!ff.ready())return;
ff.write(sram, cart.sram_size);
ff.write(sram, info.ram_size);
}
void Cartridge::load_rom(Reader *rf) {
base_rom = rf->read();
rom_size = rf->size();
if((rom_size & 0x7fff) == 0x0200) {
rom = base_rom + 512;
rom_size -= 512;
} else {
rom = base_rom;
uint Cartridge::mirror_rom(uint size) {
uint i;
//find largest power of two <= size
for(i = 31; i >= 0; i--) {
if(size & (1 << i))break;
}
cart.rom_size = rom_size;
uint P0_size = 1 << i;
size -= P0_size;
if(size == 0)return P0_size;
cart.crc32 = 0xffffffff;
for(int32 i = 0; i < cart.rom_size; i++) {
cart.crc32 = crc32_adjust(cart.crc32, rom[i]);
//find smallest power of two >= size
for(i = 0; i <= 31; i++) {
if((1 << i) >= size)break;
}
cart.crc32 = ~cart.crc32;
uint P1_size = 1 << i;
return P0_size + P1_size;
}
void Cartridge::patch_rom(Reader *rf) {
uint8 *patch_data = rf->read();
uint32 patch_size = rf->size();
BPF bpf;
if(patch_size < 34)return;
uint32 target;
target = patch_data[BPF::INDEX_FORMAT + 0] << 0;
target |= patch_data[BPF::INDEX_FORMAT + 1] << 8;
target |= patch_data[BPF::INDEX_FORMAT + 2] << 16;
target |= patch_data[BPF::INDEX_FORMAT + 3] << 24;
if(target != BPF::FORMAT_SNES) {
alert("Warning: BPF patch file is not in SNES format!\n\n"
"The patch will still be applied, but it will not be "
"possible to determine whether the patch was created "
"against an image with a header or without a header.\n\n"
"bsnes is now forced to assume the patch was created "
"against a headerless source image. If this is not the "
"case, then patching will fail!\n\n"
"If you are the author of this patch, please recreate "
"the patch in SNES format.\n\n"
"If you are not the patch author, please contact the "
"author and ask them to create an SNES format BPF patch.");
void Cartridge::load_rom(Reader &rf) {
info.rom_size = rf.size();
bool header = false;
if((info.rom_size & 0x7fff) == 0x0200) {
info.rom_size -= 512;
header = true;
}
if(bpf.apply_patch(patch_size, patch_data, rom_size, rom) == true) {
SafeFree(base_rom);
uint8 *temp = bpf.get_output_handle(rom_size);
base_rom = (uint8*)malloc(rom_size);
memcpy(base_rom, temp, rom_size);
rom = base_rom;
cart.rom_size = rom_size;
} else {
alert("Failed to apply patch.\n\nThis could be because the patch itself "
"does not match its internal checksum, because the ROM loaded does not "
"match the patch information for either the original or modified file, "
"or because the patched file does not match the checksum of either the "
"original or modified file that is stored inside the patch.\n\n"
"The original ROM image will be used instead.");
info.rom_size = mirror_rom(info.rom_size);
base_rom = rf.read(info.rom_size + ((header) ? 512 : 0));
rom = base_rom;
if(header)rom += 512;
info.crc32 = 0xffffffff;
for(int32 i = 0; i < info.rom_size; i++) {
info.crc32 = crc32_adjust(info.crc32, rom[i]);
}
SafeFree(patch_data);
info.crc32 = ~info.crc32;
}
bool Cartridge::load(const char *fn) {
@ -247,7 +253,7 @@ bool Cartridge::load(const char *fn) {
alert("Error loading image file (%s)!", rom_fn);
return false;
}
load_rom(static_cast<Reader*>(&ff));
load_rom(ff);
break;
}
#ifdef GZIP_SUPPORT
@ -257,12 +263,12 @@ bool Cartridge::load(const char *fn) {
alert("Error loading image file (%s)!", rom_fn);
return false;
}
load_rom(static_cast<Reader*>(&gf));
load_rom(gf);
break;
}
case Reader::RF_ZIP: {
ZipReader zf(rom_fn);
load_rom(static_cast<Reader*>(&zf));
load_rom(zf);
break;
}
#endif
@ -270,7 +276,7 @@ bool Cartridge::load(const char *fn) {
case Reader::RF_JMA: {
try {
JMAReader jf(rom_fn);
load_rom(static_cast<Reader*>(&jf));
load_rom(jf);
} catch(JMA::jma_errors jma_error) {
alert("Error loading image file (%s)!", rom_fn);
return false;
@ -289,25 +295,6 @@ bool Cartridge::load(const char *fn) {
}
}
//check for bpf patch
#ifdef GZIP_SUPPORT
strcpy(patch_fn, sram_fn);
strcat(patch_fn, ".bpz");
if(fexists(patch_fn)) {
ZipReader zf(patch_fn);
patch_rom(static_cast<Reader*>(&zf));
} else {
#endif
strcpy(patch_fn, sram_fn);
strcat(patch_fn, ".bpf");
if(fexists(patch_fn)) {
FileReader ff(patch_fn);
patch_rom(static_cast<Reader*>(&ff));
}
#ifdef GZIP_SUPPORT
}
#endif
//add SRAM extension
strcat(sram_fn, ".");
strcat(sram_fn, config::fs.save_ext.sget());
@ -343,13 +330,19 @@ bool Cartridge::load(const char *fn) {
strcat(cheat_fn, ".cht");
if(fexists(cheat_fn) == true) {
FileReader ff(cheat_fn);
cheat.load(static_cast<Reader*>(&ff));
cheat.load(ff);
}
if(read_database() == true) {
read_dbi();
} else {
find_header();
read_header();
}
find_header();
read_header();
load_sram();
cart_loaded = true;
r_mem->load_cart();
return true;
}
@ -370,7 +363,7 @@ bool Cartridge::unload() {
if(cheat.count() > 0 || fexists(cheat_fn)) {
FileWriter ff(cheat_fn);
cheat.save(static_cast<Writer*>(&ff));
cheat.save(ff);
cheat.clear();
}
@ -379,12 +372,13 @@ bool Cartridge::unload() {
}
Cartridge::Cartridge() {
load_database();
cart_loaded = false;
base_rom = 0;
rom = 0;
sram = 0;
rom_size = 0;
}
Cartridge::~Cartridge() {

View File

@ -1,10 +1,24 @@
class Cartridge {
public:
/*****
* cart database
*****/
#include "db/db.h"
db_item dbi;
uint8 *database;
uint database_size;
uint database_blocksize;
void load_database();
bool read_database();
//
bool cart_loaded;
char rom_fn[4096], sram_fn[4096], cheat_fn[4096], patch_fn[4096];
uint8 *base_rom, *rom, *sram;
uint32 rom_size;
enum {
//header fields
@ -18,12 +32,15 @@ enum {
VERSION = 0x1b,
ICKSUM = 0x1c,
CKSUM = 0x1e,
RESL = 0x3c,
RESH = 0x3d,
//regions
NTSC = 0,
PAL = 1,
//memory mappers
PCB = 0x00,
LOROM = 0x20,
HIROM = 0x21,
EXLOROM = 0x22,
@ -37,14 +54,13 @@ enum {
struct {
uint32 crc32;
uint32 header_index;
char name[128];
char pcb[32];
char name[32];
uint32 rom_size;
uint32 sram_size;
bool region;
uint32 mapper;
uint region;
uint mapper;
uint rom_size;
uint ram_size;
//set to true for games that need cart MMIO mapping (c4, dsp-n, ...),
//for games that map outside the standard MMIO range of $2000-$5fff
@ -57,12 +73,16 @@ struct {
bool obc1;
uint dsp1_mapper;
} cart;
void load_rom(Reader *rf);
void patch_rom(Reader *rf);
//HiROM / LoROM specific code
uint header_index;
} info;
uint mirror_rom(uint size);
void load_rom(Reader &rf);
void load_sram();
void save_sram();
void read_dbi();
void find_header();
void read_header();
bool loaded() { return cart_loaded; }

37
src/cart/database.cpp Normal file
View File

@ -0,0 +1,37 @@
void Cartridge::load_database() {
database = 0;
database_size = 0;
FILE *fp;
fp = fopen("cart.db", "rb");
if(!fp)return;
uint size = fsize(fp);
if(size < 8) {
fclose(fp);
return;
}
database = (uint8*)malloc(size);
fread(database, 1, size, fp);
fclose(fp);
database_blocksize = (database[6] << 0) | (database[7] << 8);
database_size = (size - 8) / database_blocksize;
}
bool Cartridge::read_database() {
uint i, crc32;
for(i = 0; i < database_size; i++) {
uint8 *p = database + 8 + (i * database_blocksize);
crc32 = *(p++) << 0;
crc32 |= *(p++) << 8;
crc32 |= *(p++) << 16;
crc32 |= *(p++) << 24;
if(crc32 == cartridge.info.crc32)break;
}
if(i >= database_size)return false;
db_read(dbi, database + 8 + (i * database_blocksize));
return true;
}

BIN
src/cart/db/cart.db Normal file

Binary file not shown.

41
src/cart/db/cartdb.txt Normal file
View File

@ -0,0 +1,41 @@
[0x7aedd703]
name = "Der Langrisser (Japan) [!]"
pcb = "SHVC-1A3M-30"
rom = 16mbit
ram = 64kbit
[0x35f9eecc]
name = "Der Langrisser (Japan) (V1.1)"
pcb = "SHVC-1A3M-30" ;unverified (guess)
rom = 16mbit
ram = 64kbit
[0x19bdcb19]
name = "Derby Stallion '96 (Japan) [!]"
pcb = "BSC-1A5M-01"
rom = 24mbit
ram = 256kbit
[0x9684526d]
name = "Romancing SaGa (Japan) (V1.1) [!]"
pcb = "SHVC-1A3B-12"
rom = 8mbit
ram = 64kbit
[0x675b6382]
name = "RPG Tsukuru 2 (Japan)"
pcb = "BSC-1A7M-01" ;unverified
rom = 16mbit
ram = 512kbit
[0x5ebf7246]
name = "Sound Novel Tsukuru (Japan) [!]"
pcb = "BSC-1A7M-10"
rom = 24mbit
ram = 512kbit
[0x64a91e64]
name = "Wanderers from Ys (USA) [!]"
pcb = "SHVC-1A3B-12"
rom = 8mbit
ram = 64kbit

3
src/cart/db/cc.bat Normal file
View File

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

1
src/cart/db/clean.bat Normal file
View File

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

2
src/cart/db/create.bat Normal file
View File

@ -0,0 +1,2 @@
dbcreate
@copy cart.db ..\..\..\cart.db

47
src/cart/db/db.h Normal file
View File

@ -0,0 +1,47 @@
struct db_item {
uint32 crc32;
char name[128];
char pcb [32];
uint32 rom;
uint32 ram;
};
void db_write(FILE *fp, db_item &dbi) {
fputc(dbi.crc32 >> 0, fp);
fputc(dbi.crc32 >> 8, fp);
fputc(dbi.crc32 >> 16, fp);
fputc(dbi.crc32 >> 24, fp);
fwrite(dbi.name, 1, 128, fp);
fwrite(dbi.pcb, 1, 32, fp);
fputc(dbi.rom >> 0, fp);
fputc(dbi.rom >> 8, fp);
fputc(dbi.rom >> 16, fp);
fputc(dbi.rom >> 24, fp);
fputc(dbi.ram >> 0, fp);
fputc(dbi.ram >> 8, fp);
fputc(dbi.ram >> 16, fp);
fputc(dbi.ram >> 24, fp);
}
void db_read(db_item &dbi, uint8 *data) {
dbi.crc32 = (*data++) << 0;
dbi.crc32 |= (*data++) << 8;
dbi.crc32 |= (*data++) << 16;
dbi.crc32 |= (*data++) << 24;
memcpy(dbi.name, data, 128); dbi.name[127] = 0; data += 128;
memcpy(dbi.pcb, data, 32); dbi.pcb [ 31] = 0; data += 32;
dbi.rom = (*data++) << 0;
dbi.rom |= (*data++) << 8;
dbi.rom |= (*data++) << 16;
dbi.rom |= (*data++) << 24;
dbi.ram = (*data++) << 0;
dbi.ram |= (*data++) << 8;
dbi.ram |= (*data++) << 16;
dbi.ram |= (*data++) << 24;
}

117
src/cart/db/dbcreate.cpp Normal file
View File

@ -0,0 +1,117 @@
#include "../../lib/libbase.h"
#include "../../lib/libvector.h"
#include "../../lib/libstring.h"
#include "../../lib/libstring.cpp"
#include "db.h"
FILE *fp;
uint decode_size(substring &str) {
//hex encoding
if(strbegin(str, "0x")) {
strltrim(str, "0x");
return strhex(str);
}
//mbit encoding
if(strend(str, "mbit")) {
strrtrim(str, "mbit");
return strdec(str) * 1024 * 1024 / 8;
}
//kbit encoding
if(strend(str, "kbit")) {
strrtrim(str, "kbit");
return strdec(str) * 1024 / 8;
}
//decimal encoding
return strdec(str);
}
void build_block(substring &block) {
string line, hashpart, part;
split(line, "\n", block);
if(strbegin(line[0], "[") == false) {
printf("error: invalid block detected: '%s'\n", strptr(line[0]));
return;
}
strltrim(line[0], "[");
strrtrim(line[0], "]");
replace(line[0], "0x", "");
split(hashpart, ",", line[0]);
db_item dbi;
dbi.crc32 = 0;
*dbi.name = 0;
*dbi.pcb = 0;
dbi.rom = 0;
dbi.ram = 0;
for(int i = 1; i < count(line); i++) {
uint pos;
if(strpos(line[i], ";", pos) == true) {
strset(line[i], pos, 0);
}
if(strmatch(line[i], ""))continue;
split(part, "=", line[i]);
strunquote(part[1]);
if(strmatch(part[0], "name")) {
strncpy(dbi.name, strptr(part[1]), 128);
dbi.name[128] = 0;
}
if(strmatch(part[0], "pcb")) {
strncpy(dbi.pcb, strptr(part[1]), 32);
dbi.pcb[31] = 0;
}
if(strmatch(part[0], "rom")) {
dbi.rom = decode_size(part[1]);
}
if(strmatch(part[0], "ram")) {
dbi.ram = decode_size(part[1]);
}
}
for(int i = 0; i < count(hashpart); i++) {
dbi.crc32 = strhex(hashpart[i]);
db_write(fp, dbi);
}
}
void build_database() {
string data, block;
if(strfread(data, "cartdb.txt") == false)return;
fp = fopen("cart.db", "wb");
fprintf(fp, "SNESDB");
uint blocksize = 4 + 128 + 32 + 4 + 4;
fputc(blocksize >> 0, fp);
fputc(blocksize >> 8, fp);
replace (data, "\r", "");
qreplace(data, " ", "");
qreplace(data, "\t", "");
split(block, "\n\n", data);
for(int i = 0; i < count(block); i++) {
build_block(block[i]);
}
fclose(fp);
}
int main() {
build_database();
return 0;
}

BIN
src/cart/db/dbcreate.exe Normal file

Binary file not shown.

View File

@ -266,12 +266,12 @@ void Cheat::disable(uint32 n) {
* cheat file manipulation routines
*****/
bool Cheat::load(Reader *rf) {
if(!rf->ready())return false;
bool Cheat::load(Reader &rf) {
if(!rf.ready())return false;
uint8 *raw_data = rf->read();
uint8 *raw_data = rf.read();
string data;
raw_data[rf->size()] = 0;
raw_data[rf.size()] = 0;
strcpy(data, (char*)raw_data);
SafeFree(raw_data);
replace(data, "\r\n", "\n");
@ -297,8 +297,8 @@ string line;
return true;
}
bool Cheat::save(Writer *wf) {
if(!wf->ready())return false;
bool Cheat::save(Writer &wf) {
if(!wf.ready())return false;
string data;
char t[4096];
@ -308,7 +308,7 @@ char t[4096];
strcat(data, t);
}
wf->write((uint8*)strptr(data), strlen(data));
wf.write((uint8*)strptr(data), strlen(data));
return true;
}

View File

@ -38,8 +38,8 @@ public:
bool enabled(uint32 n);
void enable (uint32 n);
void disable(uint32 n);
bool load(Reader *rf);
bool save(Writer *wf);
bool load(Reader &rf);
bool save(Writer &wf);
void clear();
Cheat();

File diff suppressed because it is too large Load Diff

View File

@ -1,126 +0,0 @@
// DSP-1's emulation code
//
// Based on research by Overload, The Dumper, Neviksti and Andreas Naive
// Date: June 2006
#ifndef __DSP1EMUL_H
#define __DSP1EMUL_H
#define DSP1_VERSION 0x0102
class Dsp1
{
public:
// The DSP-1 status register has 16 bits, but only
// the upper 8 bits can be accessed from an external device, so all these
// positions are referred to the upper byte (bits D8 to D15)
enum SrFlags {DRC=0x04, DRS=0x10, RQM=0x80};
// According to Overload's docs, these are the meanings of the flags:
// DRC: The Data Register Control (DRC) bit specifies the data transfer length to and from the host CPU.
// 0: Data transfer to and from the DSP-1 is 16 bits.
// 1: Data transfer to and from the DSP-1 is 8 bits.
// DRS: The Data Register Status (DRS) bit indicates the data transfer status in the case of transfering 16-bit data.
// 0: Data transfer has terminated.
// 1: Data transfer in progress.
// RQM: The Request for Master (RQM) indicates that the DSP1 is requesting host CPU for data read/write.
// 0: Internal Data Register Transfer.
// 1: External Data Register Transfer.
Dsp1();
uint8 getSr() const; // return the status register's high byte
uint8 getDr();
void setDr(uint8 iDr);
void reset();
private:
enum FsmMajorState {WAIT_COMMAND, READ_DATA, WRITE_DATA};
enum MaxDataAccesses {MAX_READS=7, MAX_WRITES=1024};
struct Command {
void (Dsp1::*callback)(int16 *, int16 *);
unsigned int reads;
unsigned int writes;
};
static const Command mCommandTable[];
static const int16 MaxAZS_Exp[16];
static const int16 SinTable[];
static const int16 MulTable[];
static const uint16 DataRom[];
struct SharedData { // some RAM variables shared between commands
int16 MatrixA[3][3]; // attitude matrix A
int16 MatrixB[3][3];
int16 MatrixC[3][3];
int16 CentreX, CentreY, CentreZ; // center of projection
int16 CentreZ_C, CentreZ_E;
int16 VOffset; // vertical offset of the screen with regard to the centre of projection
int16 Les, C_Les, E_Les;
int16 SinAas, CosAas;
int16 SinAzs, CosAzs;
int16 SinAZS, CosAZS;
int16 SecAZS_C1, SecAZS_E1;
int16 SecAZS_C2, SecAZS_E2;
int16 Nx, Ny, Nz; // normal vector to the screen (norm 1, points toward the center of projection)
int16 Gx, Gy, Gz; // center of the screen (global coordinates)
int16 Hx, Hy; // horizontal vector of the screen (Hz=0, norm 1, points toward the right of the screen)
int16 Vx, Vy, Vz; // vertical vector of the screen (norm 1, points toward the top of the screen)
} shared;
uint8 mSr; // status register
uint16 mDr; // "internal" representation of the data register
FsmMajorState mFsmMajorState; // current major state of the FSM
uint8 mCommand; // current command processed by the FSM
uint8 mDataCounter; // #uint16 read/writes counter used by the FSM
int16 mReadBuffer[MAX_READS];
int16 mWriteBuffer[MAX_WRITES];
bool mFreeze; // need explanation? ;)
void fsmStep(bool read, uint8 &data); // FSM logic
// commands
void memoryTest(int16 *input, int16 *output);
void memoryDump(int16 *input, int16 *output);
void memorySize(int16 *input, int16 *output);
void multiply(int16* input, int16* output);
void multiply2(int16* input, int16* output);
void inverse(int16 *input, int16 *output);
void triangle(int16 *input, int16 *output);
void radius(int16 *input, int16 *output);
void range(int16 *input, int16 *output);
void range2(int16 *input, int16 *output);
void distance(int16 *input, int16 *output);
void rotate(int16 *input, int16 *output);
void polar(int16 *input, int16 *output);
void attitudeA(int16 *input, int16 *output);
void attitudeB(int16 *input, int16 *output);
void attitudeC(int16 *input, int16 *output);
void objectiveA(int16 *input, int16 *output);
void objectiveB(int16 *input, int16 *output);
void objectiveC(int16 *input, int16 *output);
void subjectiveA(int16 *input, int16 *output);
void subjectiveB(int16 *input, int16 *output);
void subjectiveC(int16 *input, int16 *output);
void scalarA(int16 *input, int16 *output);
void scalarB(int16 *input, int16 *output);
void scalarC(int16 *input, int16 *output);
void gyrate(int16 *input, int16 *output);
void parameter(int16 *input, int16 *output);
void raster(int16 *input, int16 *output);
void target(int16 *input, int16 *output);
void project(int16 *input, int16 *output);
// auxiliar functions
int16 sin(int16 Angle);
int16 cos(int16 Angle);
void inverse(int16 Coefficient, int16 Exponent, int16 &iCoefficient, int16 &iExponent);
int16 denormalizeAndClip(int16 C, int16 E);
void normalize(int16 m, int16 &Coefficient, int16 &Exponent);
void normalizeDouble(int32 Product, int16 &Coefficient, int16 &Exponent);
int16 shiftR(int16 C, int16 E);
};
#endif

View File

@ -24,7 +24,7 @@ void DSP1::reset() {
* of expected ranges
*****/
bool DSP1::addr_decode(uint16 addr) {
switch(cartridge.cart.dsp1_mapper) {
switch(cartridge.info.dsp1_mapper) {
case Cartridge::DSP1_LOROM_1MB:
//$[20-3f]:[8000-bfff] = DR, $[20-3f]:[c000-ffff] = SR

View File

@ -1,4 +1,4 @@
// DSP-1's emulation code
// DSP-1's emulation code
//
// Based on research by Overload, The Dumper, Neviksti and Andreas Naive
// Date: June 2006
@ -859,8 +859,8 @@ const int16 Dsp1::MaxAZS_Exp[16] = {
// (Fx, Fy, Fz)-> coordinates of base point (global coordinates)
// Lfe-> distance between the base point and the viewpoint (center of projection)
// Les-> distance between the base point and the screen
// Aas-> azimuth angle (0º is east; 90ª is north)
// Azs-> zenith angle (0º is zenith)
// Aas-> azimuth angle (0 degrees is east; 90 degrees is north)
// Azs-> zenith angle (0 degrees is zenith)
// Output:
// Vof-> raster line of imaginary center (whatever it means ;) )
// Vva-> raster line representing the horizon line
@ -1025,7 +1025,7 @@ void Dsp1::parameter(int16 *input, int16 *output)
// you consider the "reference case" (center of projection at an unit of height),
// the projection of a thin strip containing the raster line will have the same
// width (as the raster line would be on the ground in this case, but will suffer a
// change of scale in height (as the ground and the vertical axis would form an angle of 180º-Azs).
// change of scale in height (as the ground and the vertical axis would form an angle of 180-Azs degrees).
// This scale factor, when the angle 'center of screen-center of projection-raster line' is small,
// can be aproximated by the one of the center of the screen, 1/cos(Azs).(**) (Here is when it's used
// SecAZS). By last, you have to consider the effect of the azimuth angle Aas, and you are done.

View File

@ -22,53 +22,23 @@ void bCPU::run() {
return;
}
if(status.cycle_pos == 0) {
//interrupts only trigger on opcode edges
if(!run_state.irq && !run_state.stp) {
if(status.cycle_pos == 0) { //interrupts only trigger on opcode edges
if(run_state.irq && !run_state.stp) {
run_state.irq = false;
if(time.nmi_pending == true) {
time.nmi_pending = false;
aa.w = (regs.e == false) ? 0xffea : 0xfffa;
run_state.irq = true;
} else if(time.irq_pending == true) {
time.irq_pending = false;
aa.w = (regs.e == false) ? 0xffee : 0xfffe;
run_state.irq = true;
}
irq_run();
}
}
exec_cycle();
}
void bCPU::scanline() {
time.hdma_triggered = (vcounter() <= (!overscan() ? 224 : 239)) ? false : true;
if(vcounter() == (!overscan() ? 227 : 242) && status.auto_joypad_poll == true) {
snes->poll_input(SNES::DEV_JOYPAD1);
snes->poll_input(SNES::DEV_JOYPAD2);
//When the SNES auto-polls the joypads, it writes 1, then 0 to
//$4016, then reads from each 16 times to get the joypad state
//information. As a result, the joypad read positions are set
//to 16 after such a poll. Position 16 is the controller
//connected status bit.
status.joypad1_read_pos = 16;
status.joypad2_read_pos = 16;
}
}
void bCPU::frame() {
time.nmi_read = 1;
time.nmi_line = 1;
time.nmi_transition = 0;
if(cpu_version == 2) {
time.hdmainit_trigger_pos = 12 + dma_counter();
} else {
time.hdmainit_trigger_pos = 12 + 8 - dma_counter();
}
time.hdmainit_triggered = false;
}
void bCPU::power() {
region = snes->region();

View File

@ -83,8 +83,6 @@ struct {
inline uint8 pio_status();
inline void run();
inline uint32 clocks_executed();
inline void scanline();
inline void frame();
inline void power();
inline void reset();

View File

@ -1,8 +1,8 @@
void bCPU::last_cycle() {
//DMV27: keep previous nmi value,
//to allow wai and irq to work properly
time.nmi_pending |= nmi_test();
time.irq_pending |= irq_test();
run_state.irq = (time.nmi_pending || time.irq_pending);
}
void bCPU::pre_exec_cycle() {
@ -139,12 +139,6 @@ static int z;
}
void bCPU::exec_cycle() {
//irq active? run one bus cycle of the irq event and return
if(run_state.irq) {
irq_run();
return;
}
if(status.cycle_pos) {
(this->*optbl[status.opcode])();
#ifdef DEBUGGER
@ -159,7 +153,7 @@ void bCPU::exec_cycle() {
#ifdef DEBUGGER
snes->notify(SNES::CPU_EXEC_OPCODE_BEGIN);
#endif
status.opcode = op_read();
status.opcode = op_readpc();
status.cycle_pos = 1;
}

View File

@ -1,57 +1,20 @@
/*
[IRQ cycles]
[0] pbr,pc ; opcode
[1] pbr,pc ; io
[2] 0,s ; pbr
[3] 0,s-1 ; pch
[4] 0,s-2 ; pcl
[5] 0,s-3 ; p
[6] 0,va ; aavl
[7] 0,va+1 ; aavh
*/
void bCPU::irq_run() {
//WDC documentation is incorrect, first cycle
//is a memory read fetch from PBR:PC
switch(status.cycle_pos++) {
case 0:
//read from PBR:PC, but do not increment PC counter
mem_read(regs.pc.d);
break;
case 1:
cpu_io();
if(regs.e)status.cycle_pos++;
break;
case 2:
stack_write(regs.pc.b);
break;
case 3:
stack_write(regs.pc.h);
break;
case 4:
stack_write(regs.pc.l);
break;
case 5:
//emulation-mode irqs clear brk bit 0x10
stack_write(regs.e ? (regs.p & ~0x10) : regs.p);
break;
case 6:
//todo: test if NMI can override IRQ here...
rd.l = op_read(OPMODE_ADDR, aa.w);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
break;
case 7:
rd.h = op_read(OPMODE_ADDR, aa.w + 1);
regs.pc.w = rd.w;
#ifdef DEBUGGER
//let debugger know the new IRQ opcode address
snes->notify(SNES::CPU_EXEC_OPCODE_END);
#endif
status.cycle_pos = 0;
run_state.irq = false;
break;
}
mem_read(regs.pc.d);
cpu_io();
if(!regs.e)op_writestack(regs.pc.b);
op_writestack(regs.pc.h);
op_writestack(regs.pc.l);
op_writestack(regs.e ? (regs.p & ~0x10) : regs.p);
rd.l = op_readaddr(aa.w + 0);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
rd.h = op_readaddr(aa.w + 1);
regs.pc.w = rd.w;
#ifdef DEBUGGER
//let debugger know the new IRQ opcode address
snes->notify(SNES::CPU_EXEC_OPCODE_END);
#endif
}
bool bCPU::nmi_test() {

View File

@ -23,68 +23,6 @@ void bCPU::cpu_c6(uint16 addr) {
}
}
uint32 bCPU::op_addr(uint8 mode, uint32 addr) {
switch(mode) {
case OPMODE_ADDR:
addr &= 0xffff;
break;
case OPMODE_LONG:
addr &= 0xffffff;
break;
case OPMODE_DBR:
addr = ((regs.db << 16) + addr) & 0xffffff;
break;
case OPMODE_PBR:
addr &= 0xffff;
addr = (regs.pc.b << 16) + addr;
break;
case OPMODE_DP:
addr &= 0xffff;
addr = (regs.d + addr) & 0xffff;
break;
case OPMODE_SP:
addr &= 0xffff;
addr = (regs.s + addr) & 0xffff;
break;
}
return addr;
}
uint8 bCPU::op_read() {
uint8 r;
r = mem_read(regs.pc.d);
regs.pc.w++;
return r;
}
uint8 bCPU::op_read(uint8 mode, uint32 addr) {
addr = op_addr(mode, addr);
return mem_read(addr);
}
void bCPU::op_write(uint8 mode, uint32 addr, uint8 value) {
addr = op_addr(mode, addr);
mem_write(addr, value);
}
uint8 bCPU::stack_read() {
if(regs.e) {
regs.s.l++;
} else {
regs.s.w++;
}
return mem_read(regs.s);
}
void bCPU::stack_write(uint8 value) {
mem_write(regs.s, value);
if(regs.e) {
regs.s.l--;
} else {
regs.s.w--;
}
}
void bCPU::init_op_tables() {
#include "optable.cpp"
}

View File

@ -57,18 +57,6 @@ uint8 dp, sp;
inline void cpu_c4(uint16 x, uint16 y);
inline void cpu_c6(uint16 addr);
enum {
OPMODE_ADDR, OPMODE_LONG,
OPMODE_DBR, OPMODE_PBR,
OPMODE_DP, OPMODE_SP
};
inline uint32 op_addr(uint8 mode, uint32 addr);
inline uint8 op_read();
inline uint8 op_read(uint8 mode, uint32 addr);
inline void op_write(uint8 mode, uint32 addr, uint8 value);
inline uint8 stack_read();
inline void stack_write(uint8 value);
inline void init_op_tables();
#include "op.h"

View File

@ -5,7 +5,7 @@ nop(0xea) {
wdm(0x42) {
1:last_cycle();
op_read();
op_readpc();
}
xba(0xeb) {
@ -21,11 +21,11 @@ xba(0xeb) {
mvn(0x54, ++),
mvp(0x44, --) {
1:dp = op_read();
2:sp = op_read();
1:dp = op_readpc();
2:sp = op_readpc();
3:regs.db = dp;
rd.l = op_read(OPMODE_LONG, (sp << 16) | regs.x.w);
4:op_write(OPMODE_LONG, (dp << 16) | regs.y.w, rd.l);
rd.l = op_readlong((sp << 16) | regs.x.w);
4:op_writelong((dp << 16) | regs.y.w, rd.l);
5:cpu_io();
if(regs.p.x) { regs.x.l$1; regs.y.l$1; }
else { regs.x.w$1; regs.y.w$1; }
@ -36,18 +36,18 @@ mvp(0x44, --) {
brk(0x00, 0xfffe, 0xffff, 0xffe6, 0xffe7),
cop(0x02, 0xfff4, 0xfff5, 0xffe4, 0xffe5) {
1:op_read();
1:op_readpc();
if(regs.e)skip;
2:stack_write(regs.pc.b);
3:stack_write(regs.pc.h);
4:stack_write(regs.pc.l);
5:stack_write(regs.p);
6:rd.l = op_read(OPMODE_LONG, (regs.e) ? $1 : $3);
2:op_writestack(regs.pc.b);
3:op_writestack(regs.pc.h);
4:op_writestack(regs.pc.l);
5:op_writestack(regs.p);
6:rd.l = op_readlong((regs.e) ? $1 : $3);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
7:last_cycle();
rd.h = op_read(OPMODE_LONG, (regs.e) ? $2 : $4);
rd.h = op_readlong((regs.e) ? $2 : $4);
regs.pc.w = rd.w;
}
@ -104,7 +104,7 @@ sei(0x78, regs.p.i = 1) {
rep(0xc2, &=~),
sep(0xe2, |=) {
1:rd.l = op_read();
1:rd.l = op_readpc();
2:last_cycle();
cpu_io();
regs.p $1 rd.l;
@ -200,9 +200,9 @@ phy(0x5a, regs.p.x, y),
phd(0x0b, 0, d) {
1:cpu_io();
if($1)skip;
2:stack_write(regs.$2.h);
2:op_writestack(regs.$2.h);
3:last_cycle();
stack_write(regs.$2.l);
op_writestack(regs.$2.l);
}
phb(0x8b, regs.db),
@ -210,7 +210,7 @@ phk(0x4b, regs.pc.b),
php(0x08, regs.p) {
1:cpu_io();
2:last_cycle();
stack_write($1);
op_writestack($1);
}
pla(0x68, regs.p.m, a),
@ -220,14 +220,14 @@ pld(0x2b, 0, d) {
1:cpu_io();
2:cpu_io();
3:if($1)last_cycle();
regs.$2.l = stack_read();
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 = stack_read();
regs.$2.h = op_readstack();
regs.p.n = !!(regs.$2.w & 0x8000);
regs.p.z = (regs.$2.w == 0);
}
@ -236,7 +236,7 @@ plb(0xab) {
1:cpu_io();
2:cpu_io();
3:last_cycle();
regs.db = stack_read();
regs.db = op_readstack();
regs.p.n = !!(regs.db & 0x80);
regs.p.z = (regs.db == 0);
}
@ -245,7 +245,7 @@ plp(0x28) {
1:cpu_io();
2:cpu_io();
3:last_cycle();
regs.p = stack_read();
regs.p = op_readstack();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
@ -254,29 +254,29 @@ plp(0x28) {
}
pea(0xf4) {
1:aa.l = op_read();
2:aa.h = op_read();
3:stack_write(aa.h);
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:op_writestack(aa.h);
4:last_cycle();
stack_write(aa.l);
op_writestack(aa.l);
}
pei(0xd4) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:stack_write(aa.h);
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:op_writestack(aa.h);
6:last_cycle();
stack_write(aa.l);
op_writestack(aa.l);
}
per(0x62) {
1:aa.l = op_read();
2:aa.h = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:cpu_io();
rd.w = regs.pc.d + (int16)aa.w;
4:stack_write(rd.h);
4:op_writestack(rd.h);
5:last_cycle();
stack_write(rd.l);
op_writestack(rd.l);
}

View File

@ -12,7 +12,7 @@ void bCPU::op_wdm() {
switch(status.cycle_pos++) {
case 1: {
last_cycle();
op_read();
op_readpc();
status.cycle_pos = 0;
} break;
}
@ -39,17 +39,17 @@ void bCPU::op_xba() {
void bCPU::op_mvn() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
sp = op_read();
sp = op_readpc();
} break;
case 3: {
regs.db = dp;
rd.l = op_read(OPMODE_LONG, (sp << 16) | regs.x.w);
rd.l = op_readlong((sp << 16) | regs.x.w);
} break;
case 4: {
op_write(OPMODE_LONG, (dp << 16) | regs.y.w, rd.l);
op_writelong((dp << 16) | regs.y.w, rd.l);
} break;
case 5: {
cpu_io();
@ -68,17 +68,17 @@ void bCPU::op_mvn() {
void bCPU::op_mvp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
sp = op_read();
sp = op_readpc();
} break;
case 3: {
regs.db = dp;
rd.l = op_read(OPMODE_LONG, (sp << 16) | regs.x.w);
rd.l = op_readlong((sp << 16) | regs.x.w);
} break;
case 4: {
op_write(OPMODE_LONG, (dp << 16) | regs.y.w, rd.l);
op_writelong((dp << 16) | regs.y.w, rd.l);
} break;
case 5: {
cpu_io();
@ -97,30 +97,30 @@ void bCPU::op_mvp() {
void bCPU::op_brk() {
switch(status.cycle_pos++) {
case 1: {
op_read();
op_readpc();
if(regs.e)status.cycle_pos++;
} break;
case 2: {
stack_write(regs.pc.b);
op_writestack(regs.pc.b);
} break;
case 3: {
stack_write(regs.pc.h);
op_writestack(regs.pc.h);
} break;
case 4: {
stack_write(regs.pc.l);
op_writestack(regs.pc.l);
} break;
case 5: {
stack_write(regs.p);
op_writestack(regs.p);
} break;
case 6: {
rd.l = op_read(OPMODE_LONG, (regs.e) ? 0xfffe : 0xffe6);
rd.l = op_readlong((regs.e) ? 0xfffe : 0xffe6);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
} break;
case 7: {
last_cycle();
rd.h = op_read(OPMODE_LONG, (regs.e) ? 0xffff : 0xffe7);
rd.h = op_readlong((regs.e) ? 0xffff : 0xffe7);
regs.pc.w = rd.w;
status.cycle_pos = 0;
} break;
@ -130,30 +130,30 @@ void bCPU::op_brk() {
void bCPU::op_cop() {
switch(status.cycle_pos++) {
case 1: {
op_read();
op_readpc();
if(regs.e)status.cycle_pos++;
} break;
case 2: {
stack_write(regs.pc.b);
op_writestack(regs.pc.b);
} break;
case 3: {
stack_write(regs.pc.h);
op_writestack(regs.pc.h);
} break;
case 4: {
stack_write(regs.pc.l);
op_writestack(regs.pc.l);
} break;
case 5: {
stack_write(regs.p);
op_writestack(regs.p);
} break;
case 6: {
rd.l = op_read(OPMODE_LONG, (regs.e) ? 0xfff4 : 0xffe4);
rd.l = op_readlong((regs.e) ? 0xfff4 : 0xffe4);
regs.pc.b = 0x00;
regs.p.i = 1;
regs.p.d = 0;
} break;
case 7: {
last_cycle();
rd.h = op_read(OPMODE_LONG, (regs.e) ? 0xfff5 : 0xffe5);
rd.h = op_readlong((regs.e) ? 0xfff5 : 0xffe5);
regs.pc.w = rd.w;
status.cycle_pos = 0;
} break;
@ -302,7 +302,7 @@ void bCPU::op_sei() {
void bCPU::op_rep() {
switch(status.cycle_pos++) {
case 1: {
rd.l = op_read();
rd.l = op_readpc();
} break;
case 2: {
last_cycle();
@ -321,7 +321,7 @@ void bCPU::op_rep() {
void bCPU::op_sep() {
switch(status.cycle_pos++) {
case 1: {
rd.l = op_read();
rd.l = op_readpc();
} break;
case 2: {
last_cycle();
@ -548,11 +548,11 @@ void bCPU::op_pha() {
if(regs.p.m)status.cycle_pos++;
} break;
case 2: {
stack_write(regs.a.h);
op_writestack(regs.a.h);
} break;
case 3: {
last_cycle();
stack_write(regs.a.l);
op_writestack(regs.a.l);
status.cycle_pos = 0;
} break;
}
@ -565,11 +565,11 @@ void bCPU::op_phx() {
if(regs.p.x)status.cycle_pos++;
} break;
case 2: {
stack_write(regs.x.h);
op_writestack(regs.x.h);
} break;
case 3: {
last_cycle();
stack_write(regs.x.l);
op_writestack(regs.x.l);
status.cycle_pos = 0;
} break;
}
@ -582,11 +582,11 @@ void bCPU::op_phy() {
if(regs.p.x)status.cycle_pos++;
} break;
case 2: {
stack_write(regs.y.h);
op_writestack(regs.y.h);
} break;
case 3: {
last_cycle();
stack_write(regs.y.l);
op_writestack(regs.y.l);
status.cycle_pos = 0;
} break;
}
@ -599,11 +599,11 @@ void bCPU::op_phd() {
if(0)status.cycle_pos++;
} break;
case 2: {
stack_write(regs. d.h);
op_writestack(regs. d.h);
} break;
case 3: {
last_cycle();
stack_write(regs. d.l);
op_writestack(regs. d.l);
status.cycle_pos = 0;
} break;
}
@ -616,7 +616,7 @@ void bCPU::op_phb() {
} break;
case 2: {
last_cycle();
stack_write(regs.db);
op_writestack(regs.db);
status.cycle_pos = 0;
} break;
}
@ -629,7 +629,7 @@ void bCPU::op_phk() {
} break;
case 2: {
last_cycle();
stack_write(regs.pc.b);
op_writestack(regs.pc.b);
status.cycle_pos = 0;
} break;
}
@ -642,7 +642,7 @@ void bCPU::op_php() {
} break;
case 2: {
last_cycle();
stack_write(regs.p);
op_writestack(regs.p);
status.cycle_pos = 0;
} break;
}
@ -658,7 +658,7 @@ void bCPU::op_pla() {
} break;
case 3: {
if(regs.p.m)last_cycle();
regs.a.l = stack_read();
regs.a.l = op_readstack();
if(regs.p.m) {
regs.p.n = !!(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
@ -667,7 +667,7 @@ void bCPU::op_pla() {
} break;
case 4: {
last_cycle();
regs.a.h = stack_read();
regs.a.h = op_readstack();
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
status.cycle_pos = 0;
@ -685,7 +685,7 @@ void bCPU::op_plx() {
} break;
case 3: {
if(regs.p.x)last_cycle();
regs.x.l = stack_read();
regs.x.l = op_readstack();
if(regs.p.x) {
regs.p.n = !!(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
@ -694,7 +694,7 @@ void bCPU::op_plx() {
} break;
case 4: {
last_cycle();
regs.x.h = stack_read();
regs.x.h = op_readstack();
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
status.cycle_pos = 0;
@ -712,7 +712,7 @@ void bCPU::op_ply() {
} break;
case 3: {
if(regs.p.x)last_cycle();
regs.y.l = stack_read();
regs.y.l = op_readstack();
if(regs.p.x) {
regs.p.n = !!(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
@ -721,7 +721,7 @@ void bCPU::op_ply() {
} break;
case 4: {
last_cycle();
regs.y.h = stack_read();
regs.y.h = op_readstack();
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
status.cycle_pos = 0;
@ -739,7 +739,7 @@ void bCPU::op_pld() {
} break;
case 3: {
if(0)last_cycle();
regs. d.l = stack_read();
regs. d.l = op_readstack();
if(0) {
regs.p.n = !!(regs. d.l & 0x80);
regs.p.z = (regs. d.l == 0);
@ -748,7 +748,7 @@ void bCPU::op_pld() {
} break;
case 4: {
last_cycle();
regs. d.h = stack_read();
regs. d.h = op_readstack();
regs.p.n = !!(regs. d.w & 0x8000);
regs.p.z = (regs. d.w == 0);
status.cycle_pos = 0;
@ -766,7 +766,7 @@ void bCPU::op_plb() {
} break;
case 3: {
last_cycle();
regs.db = stack_read();
regs.db = op_readstack();
regs.p.n = !!(regs.db & 0x80);
regs.p.z = (regs.db == 0);
status.cycle_pos = 0;
@ -784,7 +784,7 @@ void bCPU::op_plp() {
} break;
case 3: {
last_cycle();
regs.p = stack_read();
regs.p = op_readstack();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
@ -798,17 +798,17 @@ void bCPU::op_plp() {
void bCPU::op_pea() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
stack_write(aa.h);
op_writestack(aa.h);
} break;
case 4: {
last_cycle();
stack_write(aa.l);
op_writestack(aa.l);
status.cycle_pos = 0;
} break;
}
@ -817,23 +817,23 @@ void bCPU::op_pea() {
void bCPU::op_pei() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
aa.l = op_read(OPMODE_DP, dp);
aa.l = op_readdp(dp);
} break;
case 4: {
aa.h = op_read(OPMODE_DP, dp + 1);
aa.h = op_readdp(dp + 1);
} break;
case 5: {
stack_write(aa.h);
op_writestack(aa.h);
} break;
case 6: {
last_cycle();
stack_write(aa.l);
op_writestack(aa.l);
status.cycle_pos = 0;
} break;
}
@ -842,21 +842,21 @@ void bCPU::op_pei() {
void bCPU::op_per() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
cpu_io();
rd.w = regs.pc.d + (int16)aa.w;
} break;
case 4: {
stack_write(rd.h);
op_writestack(rd.h);
} break;
case 5: {
last_cycle();
stack_write(rd.l);
op_writestack(rd.l);
status.cycle_pos = 0;
} break;
}

View File

@ -7,7 +7,7 @@ bmi(0x30, regs.p.n),
bvc(0x50, !regs.p.v),
bvs(0x70, regs.p.v) {
1:if(!$1)last_cycle();
rd.l = op_read();
rd.l = op_readpc();
if($1) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
@ -20,7 +20,7 @@ bvs(0x70, regs.p.v) {
}
bra(0x80) {
1:rd.l = op_read();
1:rd.l = op_readpc();
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
2:cpu_c6(aa.w);
@ -29,119 +29,119 @@ bra(0x80) {
}
brl(0x82) {
1:rd.l = op_read();
2:rd.h = op_read();
1:rd.l = op_readpc();
2:rd.h = op_readpc();
3:last_cycle();
cpu_io();
regs.pc.w = regs.pc.d + (int16)rd.w;
}
jmp_addr(0x4c) {
1:rd.l = op_read();
1:rd.l = op_readpc();
2:last_cycle();
rd.h = op_read();
rd.h = op_readpc();
regs.pc.w = rd.w;
}
jmp_long(0x5c) {
1:rd.l = op_read();
2:rd.h = op_read();
1:rd.l = op_readpc();
2:rd.h = op_readpc();
3:last_cycle();
rd.b = op_read();
rd.b = op_readpc();
regs.pc.d = rd.d & 0xffffff;
}
jmp_iaddr(0x6c) {
1:aa.l = op_read();
2:aa.h = op_read();
3:rd.l = op_read(OPMODE_ADDR, aa.w);
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:rd.l = op_readaddr(aa.w);
4:last_cycle();
rd.h = op_read(OPMODE_ADDR, aa.w + 1);
rd.h = op_readaddr(aa.w + 1);
regs.pc.w = rd.w;
}
jmp_iaddrx(0x7c) {
1:aa.l = op_read();
2:aa.h = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:cpu_io();
4:rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w);
4:rd.l = op_readpbr(aa.w + regs.x.w);
5:last_cycle();
rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1);
rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
}
jmp_iladdr(0xdc) {
1:aa.l = op_read();
2:aa.h = op_read();
3:rd.l = op_read(OPMODE_ADDR, aa.w);
4:rd.h = op_read(OPMODE_ADDR, aa.w + 1);
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_read(OPMODE_ADDR, aa.w + 2);
rd.b = op_readaddr(aa.w + 2);
regs.pc.d = rd.d & 0xffffff;
}
jsr_addr(0x20) {
1:aa.l = op_read();
2:aa.h = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:cpu_io();
4:regs.pc.w--;
stack_write(regs.pc.h);
op_writestack(regs.pc.h);
5:last_cycle();
stack_write(regs.pc.l);
op_writestack(regs.pc.l);
regs.pc.w = aa.w;
}
jsr_long(0x22) {
1:aa.l = op_read();
2:aa.h = op_read();
3:stack_write(regs.pc.b);
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:op_writestack(regs.pc.b);
4:cpu_io();
5:aa.b = op_read();
5:aa.b = op_readpc();
6:regs.pc.w--;
stack_write(regs.pc.h);
op_writestack(regs.pc.h);
7:last_cycle();
stack_write(regs.pc.l);
op_writestack(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
}
jsr_iaddrx(0xfc) {
1:aa.l = op_read();
2:stack_write(regs.pc.h);
3:stack_write(regs.pc.l);
4:aa.h = op_read();
1:aa.l = op_readpc();
2:op_writestack(regs.pc.h);
3:op_writestack(regs.pc.l);
4:aa.h = op_readpc();
5:cpu_io();
6:rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w);
6:rd.l = op_readpbr(aa.w + regs.x.w);
7:last_cycle();
rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1);
rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
}
rti(0x40) {
1:cpu_io();
2:cpu_io();
3:regs.p = stack_read();
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 = stack_read();
4:rd.l = op_readstack();
5:if(regs.e)last_cycle();
rd.h = stack_read();
rd.h = op_readstack();
if(regs.e) {
regs.pc.w = rd.w;
end;
}
6:last_cycle();
rd.b = stack_read();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
}
rts(0x60) {
1:cpu_io();
2:cpu_io();
3:rd.l = stack_read();
4:rd.h = stack_read();
3:rd.l = op_readstack();
4:rd.h = op_readstack();
5:last_cycle();
cpu_io();
regs.pc.w = rd.w;
@ -151,10 +151,10 @@ rts(0x60) {
rtl(0x6b) {
1:cpu_io();
2:cpu_io();
3:rd.l = stack_read();
4:rd.h = stack_read();
3:rd.l = op_readstack();
4:rd.h = op_readstack();
5:last_cycle();
rd.b = stack_read();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
regs.pc.w++;
}

View File

@ -2,7 +2,7 @@ void bCPU::op_bcc() {
switch(status.cycle_pos++) {
case 1: {
if(!!regs.p.c)last_cycle();
rd.l = op_read();
rd.l = op_readpc();
if(!regs.p.c) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
@ -25,7 +25,7 @@ void bCPU::op_bcs() {
switch(status.cycle_pos++) {
case 1: {
if(!regs.p.c)last_cycle();
rd.l = op_read();
rd.l = op_readpc();
if(regs.p.c) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
@ -48,7 +48,7 @@ void bCPU::op_bne() {
switch(status.cycle_pos++) {
case 1: {
if(!!regs.p.z)last_cycle();
rd.l = op_read();
rd.l = op_readpc();
if(!regs.p.z) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
@ -71,7 +71,7 @@ void bCPU::op_beq() {
switch(status.cycle_pos++) {
case 1: {
if(!regs.p.z)last_cycle();
rd.l = op_read();
rd.l = op_readpc();
if(regs.p.z) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
@ -94,7 +94,7 @@ void bCPU::op_bpl() {
switch(status.cycle_pos++) {
case 1: {
if(!!regs.p.n)last_cycle();
rd.l = op_read();
rd.l = op_readpc();
if(!regs.p.n) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
@ -117,7 +117,7 @@ void bCPU::op_bmi() {
switch(status.cycle_pos++) {
case 1: {
if(!regs.p.n)last_cycle();
rd.l = op_read();
rd.l = op_readpc();
if(regs.p.n) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
@ -140,7 +140,7 @@ void bCPU::op_bvc() {
switch(status.cycle_pos++) {
case 1: {
if(!!regs.p.v)last_cycle();
rd.l = op_read();
rd.l = op_readpc();
if(!regs.p.v) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
@ -163,7 +163,7 @@ void bCPU::op_bvs() {
switch(status.cycle_pos++) {
case 1: {
if(!regs.p.v)last_cycle();
rd.l = op_read();
rd.l = op_readpc();
if(regs.p.v) {
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
@ -185,7 +185,7 @@ void bCPU::op_bvs() {
void bCPU::op_bra() {
switch(status.cycle_pos++) {
case 1: {
rd.l = op_read();
rd.l = op_readpc();
aa.w = regs.pc.d + (int8)rd.l;
regs.pc.w = aa.w;
} break;
@ -203,10 +203,10 @@ void bCPU::op_bra() {
void bCPU::op_brl() {
switch(status.cycle_pos++) {
case 1: {
rd.l = op_read();
rd.l = op_readpc();
} break;
case 2: {
rd.h = op_read();
rd.h = op_readpc();
} break;
case 3: {
last_cycle();
@ -220,11 +220,11 @@ void bCPU::op_brl() {
void bCPU::op_jmp_addr() {
switch(status.cycle_pos++) {
case 1: {
rd.l = op_read();
rd.l = op_readpc();
} break;
case 2: {
last_cycle();
rd.h = op_read();
rd.h = op_readpc();
regs.pc.w = rd.w;
status.cycle_pos = 0;
} break;
@ -234,14 +234,14 @@ void bCPU::op_jmp_addr() {
void bCPU::op_jmp_long() {
switch(status.cycle_pos++) {
case 1: {
rd.l = op_read();
rd.l = op_readpc();
} break;
case 2: {
rd.h = op_read();
rd.h = op_readpc();
} break;
case 3: {
last_cycle();
rd.b = op_read();
rd.b = op_readpc();
regs.pc.d = rd.d & 0xffffff;
status.cycle_pos = 0;
} break;
@ -251,17 +251,17 @@ void bCPU::op_jmp_long() {
void bCPU::op_jmp_iaddr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
rd.l = op_read(OPMODE_ADDR, aa.w);
rd.l = op_readaddr(aa.w);
} break;
case 4: {
last_cycle();
rd.h = op_read(OPMODE_ADDR, aa.w + 1);
rd.h = op_readaddr(aa.w + 1);
regs.pc.w = rd.w;
status.cycle_pos = 0;
} break;
@ -271,20 +271,20 @@ void bCPU::op_jmp_iaddr() {
void bCPU::op_jmp_iaddrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w);
rd.l = op_readpbr(aa.w + regs.x.w);
} break;
case 5: {
last_cycle();
rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1);
rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
status.cycle_pos = 0;
} break;
@ -294,20 +294,20 @@ void bCPU::op_jmp_iaddrx() {
void bCPU::op_jmp_iladdr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
rd.l = op_read(OPMODE_ADDR, aa.w);
rd.l = op_readaddr(aa.w);
} break;
case 4: {
rd.h = op_read(OPMODE_ADDR, aa.w + 1);
rd.h = op_readaddr(aa.w + 1);
} break;
case 5: {
last_cycle();
rd.b = op_read(OPMODE_ADDR, aa.w + 2);
rd.b = op_readaddr(aa.w + 2);
regs.pc.d = rd.d & 0xffffff;
status.cycle_pos = 0;
} break;
@ -317,21 +317,21 @@ void bCPU::op_jmp_iladdr() {
void bCPU::op_jsr_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
cpu_io();
} break;
case 4: {
regs.pc.w--;
stack_write(regs.pc.h);
op_writestack(regs.pc.h);
} break;
case 5: {
last_cycle();
stack_write(regs.pc.l);
op_writestack(regs.pc.l);
regs.pc.w = aa.w;
status.cycle_pos = 0;
} break;
@ -341,27 +341,27 @@ void bCPU::op_jsr_addr() {
void bCPU::op_jsr_long() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
stack_write(regs.pc.b);
op_writestack(regs.pc.b);
} break;
case 4: {
cpu_io();
} break;
case 5: {
aa.b = op_read();
aa.b = op_readpc();
} break;
case 6: {
regs.pc.w--;
stack_write(regs.pc.h);
op_writestack(regs.pc.h);
} break;
case 7: {
last_cycle();
stack_write(regs.pc.l);
op_writestack(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
status.cycle_pos = 0;
} break;
@ -371,26 +371,26 @@ void bCPU::op_jsr_long() {
void bCPU::op_jsr_iaddrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
stack_write(regs.pc.h);
op_writestack(regs.pc.h);
} break;
case 3: {
stack_write(regs.pc.l);
op_writestack(regs.pc.l);
} break;
case 4: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 5: {
cpu_io();
} break;
case 6: {
rd.l = op_read(OPMODE_PBR, aa.w + regs.x.w);
rd.l = op_readpbr(aa.w + regs.x.w);
} break;
case 7: {
last_cycle();
rd.h = op_read(OPMODE_PBR, aa.w + regs.x.w + 1);
rd.h = op_readpbr(aa.w + regs.x.w + 1);
regs.pc.w = rd.w;
status.cycle_pos = 0;
} break;
@ -406,7 +406,7 @@ void bCPU::op_rti() {
cpu_io();
} break;
case 3: {
regs.p = stack_read();
regs.p = op_readstack();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.x.h = 0x00;
@ -414,11 +414,11 @@ void bCPU::op_rti() {
}
} break;
case 4: {
rd.l = stack_read();
rd.l = op_readstack();
} break;
case 5: {
if(regs.e)last_cycle();
rd.h = stack_read();
rd.h = op_readstack();
if(regs.e) {
regs.pc.w = rd.w;
status.cycle_pos = 0;
@ -426,7 +426,7 @@ void bCPU::op_rti() {
} break;
case 6: {
last_cycle();
rd.b = stack_read();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
status.cycle_pos = 0;
} break;
@ -442,10 +442,10 @@ void bCPU::op_rts() {
cpu_io();
} break;
case 3: {
rd.l = stack_read();
rd.l = op_readstack();
} break;
case 4: {
rd.h = stack_read();
rd.h = op_readstack();
} break;
case 5: {
last_cycle();
@ -466,14 +466,14 @@ void bCPU::op_rtl() {
cpu_io();
} break;
case 3: {
rd.l = stack_read();
rd.l = op_readstack();
} break;
case 4: {
rd.h = stack_read();
rd.h = op_readstack();
} break;
case 5: {
last_cycle();
rd.b = stack_read();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
regs.pc.w++;
status.cycle_pos = 0;

View File

@ -10,10 +10,10 @@ 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_read();
rd.l = op_readpc();
if($2) { op_$1_b(); end; }
2:last_cycle();
rd.h = op_read();
rd.h = op_readpc();
op_$1_w();
}
@ -29,13 +29,13 @@ ldx_addr(0xae, ldx, regs.p.x),
ldy_addr(0xac, ldy, regs.p.x),
ora_addr(0x0d, ora, regs.p.m),
sbc_addr(0xed, sbc, regs.p.m) {
1:aa.l = op_read();
2:aa.h = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:if($2)last_cycle();
rd.l = op_read(OPMODE_DBR, aa.w);
rd.l = op_readdbr(aa.w);
if($2) { op_$1_b(); end; }
4:last_cycle();
rd.h = op_read(OPMODE_DBR, aa.w + 1);
rd.h = op_readdbr(aa.w + 1);
op_$1_w();
}
@ -48,14 +48,14 @@ lda_addrx(0xbd, lda, regs.p.m),
ldy_addrx(0xbc, ldy, regs.p.x),
ora_addrx(0x1d, ora, regs.p.m),
sbc_addrx(0xfd, sbc, regs.p.m) {
1:aa.l = op_read();
2:aa.h = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:cpu_c4(aa.w, aa.w + regs.x.w);
4:if($2)last_cycle();
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
rd.l = op_readdbr(aa.w + regs.x.w);
if($2) { op_$1_b(); end; }
5:last_cycle();
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
rd.h = op_readdbr(aa.w + regs.x.w + 1);
op_$1_w();
}
@ -67,14 +67,14 @@ lda_addry(0xb9, lda, regs.p.m),
ldx_addry(0xbe, ldx, regs.p.x),
ora_addry(0x19, ora, regs.p.m),
sbc_addry(0xf9, sbc, regs.p.m) {
1:aa.l = op_read();
2:aa.h = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:cpu_c4(aa.w, aa.w + regs.y.w);
4:if($2)last_cycle();
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w);
rd.l = op_readdbr(aa.w + regs.y.w);
if($2) { op_$1_b(); end; }
5:last_cycle();
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1);
rd.h = op_readdbr(aa.w + regs.y.w + 1);
op_$1_w();
}
@ -85,14 +85,14 @@ eor_long(0x4f, eor, regs.p.m),
lda_long(0xaf, lda, regs.p.m),
ora_long(0x0f, ora, regs.p.m),
sbc_long(0xef, sbc, regs.p.m) {
1:aa.l = op_read();
2:aa.h = op_read();
3:aa.b = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:aa.b = op_readpc();
4:if($2)last_cycle();
rd.l = op_read(OPMODE_LONG, aa.d);
rd.l = op_readlong(aa.d);
if($2) { op_$1_b(); end; }
5:last_cycle();
rd.h = op_read(OPMODE_LONG, aa.d + 1);
rd.h = op_readlong(aa.d + 1);
op_$1_w();
}
@ -103,14 +103,14 @@ eor_longx(0x5f, eor, regs.p.m),
lda_longx(0xbf, lda, regs.p.m),
ora_longx(0x1f, ora, regs.p.m),
sbc_longx(0xff, sbc, regs.p.m) {
1:aa.l = op_read();
2:aa.h = op_read();
3:aa.b = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:aa.b = op_readpc();
4:if($2)last_cycle();
rd.l = op_read(OPMODE_LONG, aa.d + regs.x.w);
rd.l = op_readlong(aa.d + regs.x.w);
if($2) { op_$1_b(); end; }
5:last_cycle();
rd.h = op_read(OPMODE_LONG, aa.d + regs.x.w + 1);
rd.h = op_readlong(aa.d + regs.x.w + 1);
op_$1_w();
}
@ -126,13 +126,13 @@ ldx_dp(0xa6, ldx, regs.p.x),
ldy_dp(0xa4, ldy, regs.p.x),
ora_dp(0x05, ora, regs.p.m),
sbc_dp(0xe5, sbc, regs.p.m) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:if($2)last_cycle();
rd.l = op_read(OPMODE_DP, dp);
rd.l = op_readdp(dp);
if($2) { op_$1_b(); end; }
4:last_cycle();
rd.h = op_read(OPMODE_DP, dp + 1);
rd.h = op_readdp(dp + 1);
op_$1_w();
}
@ -145,26 +145,26 @@ lda_dpx(0xb5, lda, regs.p.m),
ldy_dpx(0xb4, ldy, regs.p.x),
ora_dpx(0x15, ora, regs.p.m),
sbc_dpx(0xf5, sbc, regs.p.m) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:cpu_io();
4:if($2)last_cycle();
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
rd.l = op_readdp(dp + regs.x.w);
if($2) { op_$1_b(); end; }
5:last_cycle();
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
rd.h = op_readdp(dp + regs.x.w + 1);
op_$1_w();
}
ldx_dpy(0xb6, ldx, regs.p.x) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:cpu_io();
4:if($2)last_cycle();
rd.l = op_read(OPMODE_DP, dp + regs.y.w);
rd.l = op_readdp(dp + regs.y.w);
if($2) { op_$1_b(); end; }
5:last_cycle();
rd.h = op_read(OPMODE_DP, dp + regs.y.w + 1);
rd.h = op_readdp(dp + regs.y.w + 1);
op_$1_w();
}
@ -175,15 +175,15 @@ eor_idp(0x52, eor, regs.p.m),
lda_idp(0xb2, lda, regs.p.m),
ora_idp(0x12, ora, regs.p.m),
sbc_idp(0xf2, sbc, regs.p.m) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:if($2)last_cycle();
rd.l = op_read(OPMODE_DBR, aa.w);
rd.l = op_readdbr(aa.w);
if($2) { op_$1_b(); end; }
6:last_cycle();
rd.h = op_read(OPMODE_DBR, aa.w + 1);
rd.h = op_readdbr(aa.w + 1);
op_$1_w();
}
@ -194,16 +194,16 @@ eor_idpx(0x41, eor, regs.p.m),
lda_idpx(0xa1, lda, regs.p.m),
ora_idpx(0x01, ora, regs.p.m),
sbc_idpx(0xe1, sbc, regs.p.m) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:cpu_io();
4:aa.l = op_read(OPMODE_DP, dp + regs.x.w);
5:aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
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_read(OPMODE_DBR, aa.w);
rd.l = op_readdbr(aa.w);
if($2) { op_$1_b(); end; }
7:last_cycle();
rd.h = op_read(OPMODE_DBR, aa.w + 1);
rd.h = op_readdbr(aa.w + 1);
op_$1_w();
}
@ -214,16 +214,16 @@ eor_idpy(0x51, eor, regs.p.m),
lda_idpy(0xb1, lda, regs.p.m),
ora_idpy(0x11, ora, regs.p.m),
sbc_idpy(0xf1, sbc, regs.p.m) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:cpu_c4(aa.w, aa.w + regs.y.w);
6:if($2)last_cycle();
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w);
rd.l = op_readdbr(aa.w + regs.y.w);
if($2) { op_$1_b(); end; }
7:last_cycle();
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1);
rd.h = op_readdbr(aa.w + regs.y.w + 1);
op_$1_w();
}
@ -234,16 +234,16 @@ eor_ildp(0x47, eor, regs.p.m),
lda_ildp(0xa7, lda, regs.p.m),
ora_ildp(0x07, ora, regs.p.m),
sbc_ildp(0xe7, sbc, regs.p.m) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:aa.b = op_read(OPMODE_DP, dp + 2);
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_read(OPMODE_LONG, aa.d);
rd.l = op_readlong(aa.d);
if($2) { op_$1_b(); end; }
7:last_cycle();
rd.h = op_read(OPMODE_LONG, aa.d + 1);
rd.h = op_readlong(aa.d + 1);
op_$1_w();
}
@ -254,16 +254,16 @@ eor_ildpy(0x57, eor, regs.p.m),
lda_ildpy(0xb7, lda, regs.p.m),
ora_ildpy(0x17, ora, regs.p.m),
sbc_ildpy(0xf7, sbc, regs.p.m) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:aa.b = op_read(OPMODE_DP, dp + 2);
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_read(OPMODE_LONG, aa.d + regs.y.w);
rd.l = op_readlong(aa.d + regs.y.w);
if($2) { op_$1_b(); end; }
7:last_cycle();
rd.h = op_read(OPMODE_LONG, aa.d + regs.y.w + 1);
rd.h = op_readlong(aa.d + regs.y.w + 1);
op_$1_w();
}
@ -274,13 +274,13 @@ eor_sr(0x43, eor, regs.p.m),
lda_sr(0xa3, lda, regs.p.m),
ora_sr(0x03, ora, regs.p.m),
sbc_sr(0xe3, sbc, regs.p.m) {
1:sp = op_read();
1:sp = op_readpc();
2:cpu_io();
3:if($2)last_cycle();
rd.l = op_read(OPMODE_SP, sp);
rd.l = op_readsp(sp);
if($2) { op_$1_b(); end; }
4:last_cycle();
rd.h = op_read(OPMODE_SP, sp + 1);
rd.h = op_readsp(sp + 1);
op_$1_w();
}
@ -291,27 +291,27 @@ eor_isry(0x53, eor),
lda_isry(0xb3, lda),
ora_isry(0x13, ora),
sbc_isry(0xf3, sbc) {
1:sp = op_read();
1:sp = op_readpc();
2:cpu_io();
3:aa.l = op_read(OPMODE_SP, sp);
4:aa.h = op_read(OPMODE_SP, sp + 1);
3:aa.l = op_readsp(sp);
4:aa.h = op_readsp(sp + 1);
5:cpu_io();
6:if(regs.p.m)last_cycle();
rd.l = op_read(OPMODE_DBR, aa.w + regs.y.w);
rd.l = op_readdbr(aa.w + regs.y.w);
if(regs.p.m) { op_$1_b(); end; }
7:last_cycle();
rd.h = op_read(OPMODE_DBR, aa.w + regs.y.w + 1);
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_read();
rd.l = op_readpc();
if(regs.p.m) {
regs.p.z = ((rd.l & regs.a.l) == 0);
end;
}
2:last_cycle();
rd.h = op_read();
rd.h = op_readpc();
regs.p.z = ((rd.w & regs.a.w) == 0);
}

File diff suppressed because it is too large Load Diff

View File

@ -110,17 +110,17 @@ rol_addr(0x2e, rol),
ror_addr(0x6e, ror),
trb_addr(0x1c, trb),
tsb_addr(0x0c, tsb) {
1:aa.l = op_read();
2:aa.h = op_read();
3:rd.l = op_read(OPMODE_DBR, aa.w);
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:rd.l = op_readdbr(aa.w);
if(regs.p.m)skip;
4:rd.h = op_read(OPMODE_DBR, aa.w + 1);
4:rd.h = op_readdbr(aa.w + 1);
5:cpu_io();
if(regs.p.m) { op_$1_b(); skip; }
else op_$1_w();
6:op_write(OPMODE_DBR, aa.w + 1, rd.h);
6:op_writedbr(aa.w + 1, rd.h);
7:last_cycle();
op_write(OPMODE_DBR, aa.w, rd.l);
op_writedbr(aa.w, rd.l);
}
inc_addrx(0xfe, inc),
@ -129,18 +129,18 @@ asl_addrx(0x1e, asl),
lsr_addrx(0x5e, lsr),
rol_addrx(0x3e, rol),
ror_addrx(0x7e, ror) {
1:aa.l = op_read();
2:aa.h = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:cpu_io();
4:rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
4:rd.l = op_readdbr(aa.w + regs.x.w);
if(regs.p.m)skip;
5:rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
5:rd.h = op_readdbr(aa.w + regs.x.w + 1);
6:cpu_io();
if(regs.p.m) { op_$1_b(); skip; }
else op_$1_w();
7:op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
7:op_writedbr(aa.w + regs.x.w + 1, rd.h);
8:last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
op_writedbr(aa.w + regs.x.w, rd.l);
}
inc_dp(0xe6, inc),
@ -151,17 +151,17 @@ rol_dp(0x26, rol),
ror_dp(0x66, ror),
trb_dp(0x14, trb),
tsb_dp(0x04, tsb) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:rd.l = op_read(OPMODE_DP, dp);
3:rd.l = op_readdp(dp);
if(regs.p.m)skip;
4:rd.h = op_read(OPMODE_DP, dp + 1);
4:rd.h = op_readdp(dp + 1);
5:cpu_io();
if(regs.p.m) { op_$1_b(); skip; }
else op_$1_w();
6:op_write(OPMODE_DP, dp + 1, rd.h);
6:op_writedp(dp + 1, rd.h);
7:last_cycle();
op_write(OPMODE_DP, dp, rd.l);
op_writedp(dp, rd.l);
}
inc_dpx(0xf6, inc),
@ -170,16 +170,16 @@ asl_dpx(0x16, asl),
lsr_dpx(0x56, lsr),
rol_dpx(0x36, rol),
ror_dpx(0x76, ror) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:cpu_io();
4:rd.l = op_read(OPMODE_DP, dp + regs.x.w);
4:rd.l = op_readdp(dp + regs.x.w);
if(regs.p.m)skip;
5:rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
5:rd.h = op_readdp(dp + regs.x.w + 1);
6:cpu_io();
if(regs.p.m) { op_$1_b(); skip; }
else op_$1_w();
7:op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
7:op_writedp(dp + regs.x.w + 1, rd.h);
8:last_cycle();
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
op_writedp(dp + regs.x.w, rd.l);
}

View File

@ -207,17 +207,17 @@ void bCPU::op_ror() {
void bCPU::op_inc_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
rd.l = op_read(OPMODE_DBR, aa.w);
rd.l = op_readdbr(aa.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DBR, aa.w + 1);
rd.h = op_readdbr(aa.w + 1);
} break;
case 5: {
cpu_io();
@ -225,11 +225,11 @@ void bCPU::op_inc_addr() {
else op_inc_w();
} break;
case 6: {
op_write(OPMODE_DBR, aa.w + 1, rd.h);
op_writedbr(aa.w + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DBR, aa.w, rd.l);
op_writedbr(aa.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -238,17 +238,17 @@ void bCPU::op_inc_addr() {
void bCPU::op_dec_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
rd.l = op_read(OPMODE_DBR, aa.w);
rd.l = op_readdbr(aa.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DBR, aa.w + 1);
rd.h = op_readdbr(aa.w + 1);
} break;
case 5: {
cpu_io();
@ -256,11 +256,11 @@ void bCPU::op_dec_addr() {
else op_dec_w();
} break;
case 6: {
op_write(OPMODE_DBR, aa.w + 1, rd.h);
op_writedbr(aa.w + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DBR, aa.w, rd.l);
op_writedbr(aa.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -269,17 +269,17 @@ void bCPU::op_dec_addr() {
void bCPU::op_asl_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
rd.l = op_read(OPMODE_DBR, aa.w);
rd.l = op_readdbr(aa.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DBR, aa.w + 1);
rd.h = op_readdbr(aa.w + 1);
} break;
case 5: {
cpu_io();
@ -287,11 +287,11 @@ void bCPU::op_asl_addr() {
else op_asl_w();
} break;
case 6: {
op_write(OPMODE_DBR, aa.w + 1, rd.h);
op_writedbr(aa.w + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DBR, aa.w, rd.l);
op_writedbr(aa.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -300,17 +300,17 @@ void bCPU::op_asl_addr() {
void bCPU::op_lsr_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
rd.l = op_read(OPMODE_DBR, aa.w);
rd.l = op_readdbr(aa.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DBR, aa.w + 1);
rd.h = op_readdbr(aa.w + 1);
} break;
case 5: {
cpu_io();
@ -318,11 +318,11 @@ void bCPU::op_lsr_addr() {
else op_lsr_w();
} break;
case 6: {
op_write(OPMODE_DBR, aa.w + 1, rd.h);
op_writedbr(aa.w + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DBR, aa.w, rd.l);
op_writedbr(aa.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -331,17 +331,17 @@ void bCPU::op_lsr_addr() {
void bCPU::op_rol_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
rd.l = op_read(OPMODE_DBR, aa.w);
rd.l = op_readdbr(aa.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DBR, aa.w + 1);
rd.h = op_readdbr(aa.w + 1);
} break;
case 5: {
cpu_io();
@ -349,11 +349,11 @@ void bCPU::op_rol_addr() {
else op_rol_w();
} break;
case 6: {
op_write(OPMODE_DBR, aa.w + 1, rd.h);
op_writedbr(aa.w + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DBR, aa.w, rd.l);
op_writedbr(aa.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -362,17 +362,17 @@ void bCPU::op_rol_addr() {
void bCPU::op_ror_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
rd.l = op_read(OPMODE_DBR, aa.w);
rd.l = op_readdbr(aa.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DBR, aa.w + 1);
rd.h = op_readdbr(aa.w + 1);
} break;
case 5: {
cpu_io();
@ -380,11 +380,11 @@ void bCPU::op_ror_addr() {
else op_ror_w();
} break;
case 6: {
op_write(OPMODE_DBR, aa.w + 1, rd.h);
op_writedbr(aa.w + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DBR, aa.w, rd.l);
op_writedbr(aa.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -393,17 +393,17 @@ void bCPU::op_ror_addr() {
void bCPU::op_trb_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
rd.l = op_read(OPMODE_DBR, aa.w);
rd.l = op_readdbr(aa.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DBR, aa.w + 1);
rd.h = op_readdbr(aa.w + 1);
} break;
case 5: {
cpu_io();
@ -411,11 +411,11 @@ void bCPU::op_trb_addr() {
else op_trb_w();
} break;
case 6: {
op_write(OPMODE_DBR, aa.w + 1, rd.h);
op_writedbr(aa.w + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DBR, aa.w, rd.l);
op_writedbr(aa.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -424,17 +424,17 @@ void bCPU::op_trb_addr() {
void bCPU::op_tsb_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
rd.l = op_read(OPMODE_DBR, aa.w);
rd.l = op_readdbr(aa.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DBR, aa.w + 1);
rd.h = op_readdbr(aa.w + 1);
} break;
case 5: {
cpu_io();
@ -442,11 +442,11 @@ void bCPU::op_tsb_addr() {
else op_tsb_w();
} break;
case 6: {
op_write(OPMODE_DBR, aa.w + 1, rd.h);
op_writedbr(aa.w + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DBR, aa.w, rd.l);
op_writedbr(aa.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -455,20 +455,20 @@ void bCPU::op_tsb_addr() {
void bCPU::op_inc_addrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
rd.l = op_readdbr(aa.w + regs.x.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 5: {
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
rd.h = op_readdbr(aa.w + regs.x.w + 1);
} break;
case 6: {
cpu_io();
@ -476,11 +476,11 @@ void bCPU::op_inc_addrx() {
else op_inc_w();
} break;
case 7: {
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
op_writedbr(aa.w + regs.x.w + 1, rd.h);
} break;
case 8: {
last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
op_writedbr(aa.w + regs.x.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -489,20 +489,20 @@ void bCPU::op_inc_addrx() {
void bCPU::op_dec_addrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
rd.l = op_readdbr(aa.w + regs.x.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 5: {
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
rd.h = op_readdbr(aa.w + regs.x.w + 1);
} break;
case 6: {
cpu_io();
@ -510,11 +510,11 @@ void bCPU::op_dec_addrx() {
else op_dec_w();
} break;
case 7: {
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
op_writedbr(aa.w + regs.x.w + 1, rd.h);
} break;
case 8: {
last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
op_writedbr(aa.w + regs.x.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -523,20 +523,20 @@ void bCPU::op_dec_addrx() {
void bCPU::op_asl_addrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
rd.l = op_readdbr(aa.w + regs.x.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 5: {
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
rd.h = op_readdbr(aa.w + regs.x.w + 1);
} break;
case 6: {
cpu_io();
@ -544,11 +544,11 @@ void bCPU::op_asl_addrx() {
else op_asl_w();
} break;
case 7: {
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
op_writedbr(aa.w + regs.x.w + 1, rd.h);
} break;
case 8: {
last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
op_writedbr(aa.w + regs.x.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -557,20 +557,20 @@ void bCPU::op_asl_addrx() {
void bCPU::op_lsr_addrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
rd.l = op_readdbr(aa.w + regs.x.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 5: {
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
rd.h = op_readdbr(aa.w + regs.x.w + 1);
} break;
case 6: {
cpu_io();
@ -578,11 +578,11 @@ void bCPU::op_lsr_addrx() {
else op_lsr_w();
} break;
case 7: {
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
op_writedbr(aa.w + regs.x.w + 1, rd.h);
} break;
case 8: {
last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
op_writedbr(aa.w + regs.x.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -591,20 +591,20 @@ void bCPU::op_lsr_addrx() {
void bCPU::op_rol_addrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
rd.l = op_readdbr(aa.w + regs.x.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 5: {
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
rd.h = op_readdbr(aa.w + regs.x.w + 1);
} break;
case 6: {
cpu_io();
@ -612,11 +612,11 @@ void bCPU::op_rol_addrx() {
else op_rol_w();
} break;
case 7: {
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
op_writedbr(aa.w + regs.x.w + 1, rd.h);
} break;
case 8: {
last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
op_writedbr(aa.w + regs.x.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -625,20 +625,20 @@ void bCPU::op_rol_addrx() {
void bCPU::op_ror_addrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_DBR, aa.w + regs.x.w);
rd.l = op_readdbr(aa.w + regs.x.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 5: {
rd.h = op_read(OPMODE_DBR, aa.w + regs.x.w + 1);
rd.h = op_readdbr(aa.w + regs.x.w + 1);
} break;
case 6: {
cpu_io();
@ -646,11 +646,11 @@ void bCPU::op_ror_addrx() {
else op_ror_w();
} break;
case 7: {
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, rd.h);
op_writedbr(aa.w + regs.x.w + 1, rd.h);
} break;
case 8: {
last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w, rd.l);
op_writedbr(aa.w + regs.x.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -659,17 +659,17 @@ void bCPU::op_ror_addrx() {
void bCPU::op_inc_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
rd.l = op_read(OPMODE_DP, dp);
rd.l = op_readdp(dp);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DP, dp + 1);
rd.h = op_readdp(dp + 1);
} break;
case 5: {
cpu_io();
@ -677,11 +677,11 @@ void bCPU::op_inc_dp() {
else op_inc_w();
} break;
case 6: {
op_write(OPMODE_DP, dp + 1, rd.h);
op_writedp(dp + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DP, dp, rd.l);
op_writedp(dp, rd.l);
status.cycle_pos = 0;
} break;
}
@ -690,17 +690,17 @@ void bCPU::op_inc_dp() {
void bCPU::op_dec_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
rd.l = op_read(OPMODE_DP, dp);
rd.l = op_readdp(dp);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DP, dp + 1);
rd.h = op_readdp(dp + 1);
} break;
case 5: {
cpu_io();
@ -708,11 +708,11 @@ void bCPU::op_dec_dp() {
else op_dec_w();
} break;
case 6: {
op_write(OPMODE_DP, dp + 1, rd.h);
op_writedp(dp + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DP, dp, rd.l);
op_writedp(dp, rd.l);
status.cycle_pos = 0;
} break;
}
@ -721,17 +721,17 @@ void bCPU::op_dec_dp() {
void bCPU::op_asl_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
rd.l = op_read(OPMODE_DP, dp);
rd.l = op_readdp(dp);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DP, dp + 1);
rd.h = op_readdp(dp + 1);
} break;
case 5: {
cpu_io();
@ -739,11 +739,11 @@ void bCPU::op_asl_dp() {
else op_asl_w();
} break;
case 6: {
op_write(OPMODE_DP, dp + 1, rd.h);
op_writedp(dp + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DP, dp, rd.l);
op_writedp(dp, rd.l);
status.cycle_pos = 0;
} break;
}
@ -752,17 +752,17 @@ void bCPU::op_asl_dp() {
void bCPU::op_lsr_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
rd.l = op_read(OPMODE_DP, dp);
rd.l = op_readdp(dp);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DP, dp + 1);
rd.h = op_readdp(dp + 1);
} break;
case 5: {
cpu_io();
@ -770,11 +770,11 @@ void bCPU::op_lsr_dp() {
else op_lsr_w();
} break;
case 6: {
op_write(OPMODE_DP, dp + 1, rd.h);
op_writedp(dp + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DP, dp, rd.l);
op_writedp(dp, rd.l);
status.cycle_pos = 0;
} break;
}
@ -783,17 +783,17 @@ void bCPU::op_lsr_dp() {
void bCPU::op_rol_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
rd.l = op_read(OPMODE_DP, dp);
rd.l = op_readdp(dp);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DP, dp + 1);
rd.h = op_readdp(dp + 1);
} break;
case 5: {
cpu_io();
@ -801,11 +801,11 @@ void bCPU::op_rol_dp() {
else op_rol_w();
} break;
case 6: {
op_write(OPMODE_DP, dp + 1, rd.h);
op_writedp(dp + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DP, dp, rd.l);
op_writedp(dp, rd.l);
status.cycle_pos = 0;
} break;
}
@ -814,17 +814,17 @@ void bCPU::op_rol_dp() {
void bCPU::op_ror_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
rd.l = op_read(OPMODE_DP, dp);
rd.l = op_readdp(dp);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DP, dp + 1);
rd.h = op_readdp(dp + 1);
} break;
case 5: {
cpu_io();
@ -832,11 +832,11 @@ void bCPU::op_ror_dp() {
else op_ror_w();
} break;
case 6: {
op_write(OPMODE_DP, dp + 1, rd.h);
op_writedp(dp + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DP, dp, rd.l);
op_writedp(dp, rd.l);
status.cycle_pos = 0;
} break;
}
@ -845,17 +845,17 @@ void bCPU::op_ror_dp() {
void bCPU::op_trb_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
rd.l = op_read(OPMODE_DP, dp);
rd.l = op_readdp(dp);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DP, dp + 1);
rd.h = op_readdp(dp + 1);
} break;
case 5: {
cpu_io();
@ -863,11 +863,11 @@ void bCPU::op_trb_dp() {
else op_trb_w();
} break;
case 6: {
op_write(OPMODE_DP, dp + 1, rd.h);
op_writedp(dp + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DP, dp, rd.l);
op_writedp(dp, rd.l);
status.cycle_pos = 0;
} break;
}
@ -876,17 +876,17 @@ void bCPU::op_trb_dp() {
void bCPU::op_tsb_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
rd.l = op_read(OPMODE_DP, dp);
rd.l = op_readdp(dp);
if(regs.p.m)status.cycle_pos++;
} break;
case 4: {
rd.h = op_read(OPMODE_DP, dp + 1);
rd.h = op_readdp(dp + 1);
} break;
case 5: {
cpu_io();
@ -894,11 +894,11 @@ void bCPU::op_tsb_dp() {
else op_tsb_w();
} break;
case 6: {
op_write(OPMODE_DP, dp + 1, rd.h);
op_writedp(dp + 1, rd.h);
} break;
case 7: {
last_cycle();
op_write(OPMODE_DP, dp, rd.l);
op_writedp(dp, rd.l);
status.cycle_pos = 0;
} break;
}
@ -907,7 +907,7 @@ void bCPU::op_tsb_dp() {
void bCPU::op_inc_dpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
@ -916,11 +916,11 @@ void bCPU::op_inc_dpx() {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
rd.l = op_readdp(dp + regs.x.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 5: {
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
rd.h = op_readdp(dp + regs.x.w + 1);
} break;
case 6: {
cpu_io();
@ -928,11 +928,11 @@ void bCPU::op_inc_dpx() {
else op_inc_w();
} break;
case 7: {
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
op_writedp(dp + regs.x.w + 1, rd.h);
} break;
case 8: {
last_cycle();
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
op_writedp(dp + regs.x.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -941,7 +941,7 @@ void bCPU::op_inc_dpx() {
void bCPU::op_dec_dpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
@ -950,11 +950,11 @@ void bCPU::op_dec_dpx() {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
rd.l = op_readdp(dp + regs.x.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 5: {
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
rd.h = op_readdp(dp + regs.x.w + 1);
} break;
case 6: {
cpu_io();
@ -962,11 +962,11 @@ void bCPU::op_dec_dpx() {
else op_dec_w();
} break;
case 7: {
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
op_writedp(dp + regs.x.w + 1, rd.h);
} break;
case 8: {
last_cycle();
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
op_writedp(dp + regs.x.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -975,7 +975,7 @@ void bCPU::op_dec_dpx() {
void bCPU::op_asl_dpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
@ -984,11 +984,11 @@ void bCPU::op_asl_dpx() {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
rd.l = op_readdp(dp + regs.x.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 5: {
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
rd.h = op_readdp(dp + regs.x.w + 1);
} break;
case 6: {
cpu_io();
@ -996,11 +996,11 @@ void bCPU::op_asl_dpx() {
else op_asl_w();
} break;
case 7: {
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
op_writedp(dp + regs.x.w + 1, rd.h);
} break;
case 8: {
last_cycle();
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
op_writedp(dp + regs.x.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -1009,7 +1009,7 @@ void bCPU::op_asl_dpx() {
void bCPU::op_lsr_dpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
@ -1018,11 +1018,11 @@ void bCPU::op_lsr_dpx() {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
rd.l = op_readdp(dp + regs.x.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 5: {
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
rd.h = op_readdp(dp + regs.x.w + 1);
} break;
case 6: {
cpu_io();
@ -1030,11 +1030,11 @@ void bCPU::op_lsr_dpx() {
else op_lsr_w();
} break;
case 7: {
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
op_writedp(dp + regs.x.w + 1, rd.h);
} break;
case 8: {
last_cycle();
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
op_writedp(dp + regs.x.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -1043,7 +1043,7 @@ void bCPU::op_lsr_dpx() {
void bCPU::op_rol_dpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
@ -1052,11 +1052,11 @@ void bCPU::op_rol_dpx() {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
rd.l = op_readdp(dp + regs.x.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 5: {
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
rd.h = op_readdp(dp + regs.x.w + 1);
} break;
case 6: {
cpu_io();
@ -1064,11 +1064,11 @@ void bCPU::op_rol_dpx() {
else op_rol_w();
} break;
case 7: {
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
op_writedp(dp + regs.x.w + 1, rd.h);
} break;
case 8: {
last_cycle();
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
op_writedp(dp + regs.x.w, rd.l);
status.cycle_pos = 0;
} break;
}
@ -1077,7 +1077,7 @@ void bCPU::op_rol_dpx() {
void bCPU::op_ror_dpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
@ -1086,11 +1086,11 @@ void bCPU::op_ror_dpx() {
cpu_io();
} break;
case 4: {
rd.l = op_read(OPMODE_DP, dp + regs.x.w);
rd.l = op_readdp(dp + regs.x.w);
if(regs.p.m)status.cycle_pos++;
} break;
case 5: {
rd.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
rd.h = op_readdp(dp + regs.x.w + 1);
} break;
case 6: {
cpu_io();
@ -1098,11 +1098,11 @@ void bCPU::op_ror_dpx() {
else op_ror_w();
} break;
case 7: {
op_write(OPMODE_DP, dp + regs.x.w + 1, rd.h);
op_writedp(dp + regs.x.w + 1, rd.h);
} break;
case 8: {
last_cycle();
op_write(OPMODE_DP, dp + regs.x.w, rd.l);
op_writedp(dp + regs.x.w, rd.l);
status.cycle_pos = 0;
} break;
}

View File

@ -2,180 +2,180 @@ sta_addr(0x8d, regs.p.m, regs.a.w),
stx_addr(0x8e, regs.p.x, regs.x.w),
sty_addr(0x8c, regs.p.x, regs.y.w),
stz_addr(0x9c, regs.p.m, 0x0000) {
1:aa.l = op_read();
2:aa.h = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:if($1)last_cycle();
op_write(OPMODE_DBR, aa.w, $2);
op_writedbr(aa.w, $2);
if($1)end;
4:last_cycle();
op_write(OPMODE_DBR, aa.w + 1, $2 >> 8);
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_read();
2:aa.h = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:cpu_c4(aa.w, aa.w + regs.x.w);
4:if($1)last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w, $2);
op_writedbr(aa.w + regs.x.w, $2);
if($1)end;
5:last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, $2 >> 8);
op_writedbr(aa.w + regs.x.w + 1, $2 >> 8);
}
sta_addry(0x99) {
1:aa.l = op_read();
2:aa.h = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:cpu_c4(aa.w, aa.w + regs.y.w);
4:if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l);
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m)end;
5:last_cycle();
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h);
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}
sta_long(0x8f) {
1:aa.l = op_read();
2:aa.h = op_read();
3:aa.b = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:aa.b = op_readpc();
4:if(regs.p.m)last_cycle();
op_write(OPMODE_LONG, aa.d, regs.a.l);
op_writelong(aa.d, regs.a.l);
if(regs.p.m)end;
5:last_cycle();
op_write(OPMODE_LONG, aa.d + 1, regs.a.h);
op_writelong(aa.d + 1, regs.a.h);
}
sta_longx(0x9f) {
1:aa.l = op_read();
2:aa.h = op_read();
3:aa.b = op_read();
1:aa.l = op_readpc();
2:aa.h = op_readpc();
3:aa.b = op_readpc();
4:if(regs.p.m)last_cycle();
op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l);
op_writelong(aa.d + regs.x.w, regs.a.l);
if(regs.p.m)end;
5:last_cycle();
op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h);
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_read();
1:dp = op_readpc();
2:cpu_c2();
3:if($1)last_cycle();
op_write(OPMODE_DP, dp, $2);
op_writedp(dp, $2);
if($1)end;
4:last_cycle();
op_write(OPMODE_DP, dp + 1, $2 >> 8);
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_read();
1:dp = op_readpc();
2:cpu_c2();
3:cpu_io();
4:if($1)last_cycle();
op_write(OPMODE_DP, dp + regs.x.w, $2);
op_writedp(dp + regs.x.w, $2);
if($1)end;
5:last_cycle();
op_write(OPMODE_DP, dp + regs.x.w + 1, $2 >> 8);
op_writedp(dp + regs.x.w + 1, $2 >> 8);
}
stx_dpy(0x96) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:cpu_io();
4:if(regs.p.x)last_cycle();
op_write(OPMODE_DP, dp + regs.y.w, regs.x.l);
op_writedp(dp + regs.y.w, regs.x.l);
if(regs.p.x)end;
5:last_cycle();
op_write(OPMODE_DP, dp + regs.y.w + 1, regs.x.h);
op_writedp(dp + regs.y.w + 1, regs.x.h);
}
sta_idp(0x92) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w, regs.a.l);
op_writedbr(aa.w, regs.a.l);
if(regs.p.m)end;
6:last_cycle();
op_write(OPMODE_DBR, aa.w + 1, regs.a.h);
op_writedbr(aa.w + 1, regs.a.h);
}
sta_ildp(0x87) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:aa.b = op_read(OPMODE_DP, dp + 2);
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_write(OPMODE_LONG, aa.d, regs.a.l);
op_writelong(aa.d, regs.a.l);
if(regs.p.m)end;
7:last_cycle();
op_write(OPMODE_LONG, aa.d + 1, regs.a.h);
op_writelong(aa.d + 1, regs.a.h);
}
sta_idpx(0x81) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:cpu_io();
4:aa.l = op_read(OPMODE_DP, dp + regs.x.w);
5:aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
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_write(OPMODE_DBR, aa.w, regs.a.l);
op_writedbr(aa.w, regs.a.l);
if(regs.p.m)end;
7:last_cycle();
op_write(OPMODE_DBR, aa.w + 1, regs.a.h);
op_writedbr(aa.w + 1, regs.a.h);
}
sta_idpy(0x91) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
3:aa.l = op_readdp(dp);
4:aa.h = op_readdp(dp + 1);
5:cpu_c4(aa.w, aa.w + regs.y.w);
6:if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l);
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m)end;
7:last_cycle();
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h);
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}
sta_ildpy(0x97) {
1:dp = op_read();
1:dp = op_readpc();
2:cpu_c2();
3:aa.l = op_read(OPMODE_DP, dp);
4:aa.h = op_read(OPMODE_DP, dp + 1);
5:aa.b = op_read(OPMODE_DP, dp + 2);
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_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l);
op_writelong(aa.d + regs.y.w, regs.a.l);
if(regs.p.m)end;
7:last_cycle();
op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h);
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
}
sta_sr(0x83) {
1:sp = op_read();
1:sp = op_readpc();
2:cpu_io();
3:if(regs.p.m)last_cycle();
op_write(OPMODE_SP, sp, regs.a.l);
op_writesp(sp, regs.a.l);
if(regs.p.m)end;
4:last_cycle();
op_write(OPMODE_SP, sp + 1, regs.a.h);
op_writesp(sp + 1, regs.a.h);
}
sta_isry(0x93) {
1:sp = op_read();
1:sp = op_readpc();
2:cpu_io();
3:aa.l = op_read(OPMODE_SP, sp);
4:aa.h = op_read(OPMODE_SP, sp + 1);
3:aa.l = op_readsp(sp);
4:aa.h = op_readsp(sp + 1);
5:cpu_io();
6:if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l);
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m)end;
7:last_cycle();
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h);
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
}

View File

@ -1,19 +1,19 @@
void bCPU::op_sta_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w, regs.a.w);
op_writedbr(aa.w, regs.a.w);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_write(OPMODE_DBR, aa.w + 1, regs.a.w >> 8);
op_writedbr(aa.w + 1, regs.a.w >> 8);
status.cycle_pos = 0;
} break;
}
@ -22,19 +22,19 @@ void bCPU::op_sta_addr() {
void bCPU::op_stx_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
if(regs.p.x)last_cycle();
op_write(OPMODE_DBR, aa.w, regs.x.w);
op_writedbr(aa.w, regs.x.w);
if(regs.p.x)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_write(OPMODE_DBR, aa.w + 1, regs.x.w >> 8);
op_writedbr(aa.w + 1, regs.x.w >> 8);
status.cycle_pos = 0;
} break;
}
@ -43,19 +43,19 @@ void bCPU::op_stx_addr() {
void bCPU::op_sty_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
if(regs.p.x)last_cycle();
op_write(OPMODE_DBR, aa.w, regs.y.w);
op_writedbr(aa.w, regs.y.w);
if(regs.p.x)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_write(OPMODE_DBR, aa.w + 1, regs.y.w >> 8);
op_writedbr(aa.w + 1, regs.y.w >> 8);
status.cycle_pos = 0;
} break;
}
@ -64,19 +64,19 @@ void bCPU::op_sty_addr() {
void bCPU::op_stz_addr() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w, 0x0000);
op_writedbr(aa.w, 0x0000);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_write(OPMODE_DBR, aa.w + 1, 0x0000 >> 8);
op_writedbr(aa.w + 1, 0x0000 >> 8);
status.cycle_pos = 0;
} break;
}
@ -85,22 +85,22 @@ void bCPU::op_stz_addr() {
void bCPU::op_sta_addrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
cpu_c4(aa.w, aa.w + regs.x.w);
} break;
case 4: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w, regs.a.w);
op_writedbr(aa.w + regs.x.w, regs.a.w);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, regs.a.w >> 8);
op_writedbr(aa.w + regs.x.w + 1, regs.a.w >> 8);
status.cycle_pos = 0;
} break;
}
@ -109,22 +109,22 @@ void bCPU::op_sta_addrx() {
void bCPU::op_stz_addrx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
cpu_c4(aa.w, aa.w + regs.x.w);
} break;
case 4: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w, 0x0000);
op_writedbr(aa.w + regs.x.w, 0x0000);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_write(OPMODE_DBR, aa.w + regs.x.w + 1, 0x0000 >> 8);
op_writedbr(aa.w + regs.x.w + 1, 0x0000 >> 8);
status.cycle_pos = 0;
} break;
}
@ -133,22 +133,22 @@ void bCPU::op_stz_addrx() {
void bCPU::op_sta_addry() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
cpu_c4(aa.w, aa.w + regs.y.w);
} break;
case 4: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l);
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h);
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
@ -157,22 +157,22 @@ void bCPU::op_sta_addry() {
void bCPU::op_sta_long() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
aa.b = op_read();
aa.b = op_readpc();
} break;
case 4: {
if(regs.p.m)last_cycle();
op_write(OPMODE_LONG, aa.d, regs.a.l);
op_writelong(aa.d, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_write(OPMODE_LONG, aa.d + 1, regs.a.h);
op_writelong(aa.d + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
@ -181,22 +181,22 @@ void bCPU::op_sta_long() {
void bCPU::op_sta_longx() {
switch(status.cycle_pos++) {
case 1: {
aa.l = op_read();
aa.l = op_readpc();
} break;
case 2: {
aa.h = op_read();
aa.h = op_readpc();
} break;
case 3: {
aa.b = op_read();
aa.b = op_readpc();
} break;
case 4: {
if(regs.p.m)last_cycle();
op_write(OPMODE_LONG, aa.d + regs.x.w, regs.a.l);
op_writelong(aa.d + regs.x.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_write(OPMODE_LONG, aa.d + regs.x.w + 1, regs.a.h);
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
@ -205,19 +205,19 @@ void bCPU::op_sta_longx() {
void bCPU::op_sta_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DP, dp, regs.a.w);
op_writedp(dp, regs.a.w);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_write(OPMODE_DP, dp + 1, regs.a.w >> 8);
op_writedp(dp + 1, regs.a.w >> 8);
status.cycle_pos = 0;
} break;
}
@ -226,19 +226,19 @@ void bCPU::op_sta_dp() {
void bCPU::op_stx_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
if(regs.p.x)last_cycle();
op_write(OPMODE_DP, dp, regs.x.w);
op_writedp(dp, regs.x.w);
if(regs.p.x)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_write(OPMODE_DP, dp + 1, regs.x.w >> 8);
op_writedp(dp + 1, regs.x.w >> 8);
status.cycle_pos = 0;
} break;
}
@ -247,19 +247,19 @@ void bCPU::op_stx_dp() {
void bCPU::op_sty_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
if(regs.p.x)last_cycle();
op_write(OPMODE_DP, dp, regs.y.w);
op_writedp(dp, regs.y.w);
if(regs.p.x)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_write(OPMODE_DP, dp + 1, regs.y.w >> 8);
op_writedp(dp + 1, regs.y.w >> 8);
status.cycle_pos = 0;
} break;
}
@ -268,19 +268,19 @@ void bCPU::op_sty_dp() {
void bCPU::op_stz_dp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DP, dp, 0x0000);
op_writedp(dp, 0x0000);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_write(OPMODE_DP, dp + 1, 0x0000 >> 8);
op_writedp(dp + 1, 0x0000 >> 8);
status.cycle_pos = 0;
} break;
}
@ -289,7 +289,7 @@ void bCPU::op_stz_dp() {
void bCPU::op_sta_dpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
@ -299,12 +299,12 @@ void bCPU::op_sta_dpx() {
} break;
case 4: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DP, dp + regs.x.w, regs.a.w);
op_writedp(dp + regs.x.w, regs.a.w);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_write(OPMODE_DP, dp + regs.x.w + 1, regs.a.w >> 8);
op_writedp(dp + regs.x.w + 1, regs.a.w >> 8);
status.cycle_pos = 0;
} break;
}
@ -313,7 +313,7 @@ void bCPU::op_sta_dpx() {
void bCPU::op_sty_dpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
@ -323,12 +323,12 @@ void bCPU::op_sty_dpx() {
} break;
case 4: {
if(regs.p.x)last_cycle();
op_write(OPMODE_DP, dp + regs.x.w, regs.y.w);
op_writedp(dp + regs.x.w, regs.y.w);
if(regs.p.x)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_write(OPMODE_DP, dp + regs.x.w + 1, regs.y.w >> 8);
op_writedp(dp + regs.x.w + 1, regs.y.w >> 8);
status.cycle_pos = 0;
} break;
}
@ -337,7 +337,7 @@ void bCPU::op_sty_dpx() {
void bCPU::op_stz_dpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
@ -347,12 +347,12 @@ void bCPU::op_stz_dpx() {
} break;
case 4: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DP, dp + regs.x.w, 0x0000);
op_writedp(dp + regs.x.w, 0x0000);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_write(OPMODE_DP, dp + regs.x.w + 1, 0x0000 >> 8);
op_writedp(dp + regs.x.w + 1, 0x0000 >> 8);
status.cycle_pos = 0;
} break;
}
@ -361,7 +361,7 @@ void bCPU::op_stz_dpx() {
void bCPU::op_stx_dpy() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
@ -371,12 +371,12 @@ void bCPU::op_stx_dpy() {
} break;
case 4: {
if(regs.p.x)last_cycle();
op_write(OPMODE_DP, dp + regs.y.w, regs.x.l);
op_writedp(dp + regs.y.w, regs.x.l);
if(regs.p.x)status.cycle_pos = 0;
} break;
case 5: {
last_cycle();
op_write(OPMODE_DP, dp + regs.y.w + 1, regs.x.h);
op_writedp(dp + regs.y.w + 1, regs.x.h);
status.cycle_pos = 0;
} break;
}
@ -385,25 +385,25 @@ void bCPU::op_stx_dpy() {
void bCPU::op_sta_idp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
aa.l = op_read(OPMODE_DP, dp);
aa.l = op_readdp(dp);
} break;
case 4: {
aa.h = op_read(OPMODE_DP, dp + 1);
aa.h = op_readdp(dp + 1);
} break;
case 5: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w, regs.a.l);
op_writedbr(aa.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 6: {
last_cycle();
op_write(OPMODE_DBR, aa.w + 1, regs.a.h);
op_writedbr(aa.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
@ -412,28 +412,28 @@ void bCPU::op_sta_idp() {
void bCPU::op_sta_ildp() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
aa.l = op_read(OPMODE_DP, dp);
aa.l = op_readdp(dp);
} break;
case 4: {
aa.h = op_read(OPMODE_DP, dp + 1);
aa.h = op_readdp(dp + 1);
} break;
case 5: {
aa.b = op_read(OPMODE_DP, dp + 2);
aa.b = op_readdp(dp + 2);
} break;
case 6: {
if(regs.p.m)last_cycle();
op_write(OPMODE_LONG, aa.d, regs.a.l);
op_writelong(aa.d, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 7: {
last_cycle();
op_write(OPMODE_LONG, aa.d + 1, regs.a.h);
op_writelong(aa.d + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
@ -442,7 +442,7 @@ void bCPU::op_sta_ildp() {
void bCPU::op_sta_idpx() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
@ -451,19 +451,19 @@ void bCPU::op_sta_idpx() {
cpu_io();
} break;
case 4: {
aa.l = op_read(OPMODE_DP, dp + regs.x.w);
aa.l = op_readdp(dp + regs.x.w);
} break;
case 5: {
aa.h = op_read(OPMODE_DP, dp + regs.x.w + 1);
aa.h = op_readdp(dp + regs.x.w + 1);
} break;
case 6: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w, regs.a.l);
op_writedbr(aa.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 7: {
last_cycle();
op_write(OPMODE_DBR, aa.w + 1, regs.a.h);
op_writedbr(aa.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
@ -472,28 +472,28 @@ void bCPU::op_sta_idpx() {
void bCPU::op_sta_idpy() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
aa.l = op_read(OPMODE_DP, dp);
aa.l = op_readdp(dp);
} break;
case 4: {
aa.h = op_read(OPMODE_DP, dp + 1);
aa.h = op_readdp(dp + 1);
} break;
case 5: {
cpu_c4(aa.w, aa.w + regs.y.w);
} break;
case 6: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l);
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 7: {
last_cycle();
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h);
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
@ -502,28 +502,28 @@ void bCPU::op_sta_idpy() {
void bCPU::op_sta_ildpy() {
switch(status.cycle_pos++) {
case 1: {
dp = op_read();
dp = op_readpc();
} break;
case 2: {
cpu_c2();
} break;
case 3: {
aa.l = op_read(OPMODE_DP, dp);
aa.l = op_readdp(dp);
} break;
case 4: {
aa.h = op_read(OPMODE_DP, dp + 1);
aa.h = op_readdp(dp + 1);
} break;
case 5: {
aa.b = op_read(OPMODE_DP, dp + 2);
aa.b = op_readdp(dp + 2);
} break;
case 6: {
if(regs.p.m)last_cycle();
op_write(OPMODE_LONG, aa.d + regs.y.w, regs.a.l);
op_writelong(aa.d + regs.y.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 7: {
last_cycle();
op_write(OPMODE_LONG, aa.d + regs.y.w + 1, regs.a.h);
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
@ -532,19 +532,19 @@ void bCPU::op_sta_ildpy() {
void bCPU::op_sta_sr() {
switch(status.cycle_pos++) {
case 1: {
sp = op_read();
sp = op_readpc();
} break;
case 2: {
cpu_io();
} break;
case 3: {
if(regs.p.m)last_cycle();
op_write(OPMODE_SP, sp, regs.a.l);
op_writesp(sp, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 4: {
last_cycle();
op_write(OPMODE_SP, sp + 1, regs.a.h);
op_writesp(sp + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}
@ -553,28 +553,28 @@ void bCPU::op_sta_sr() {
void bCPU::op_sta_isry() {
switch(status.cycle_pos++) {
case 1: {
sp = op_read();
sp = op_readpc();
} break;
case 2: {
cpu_io();
} break;
case 3: {
aa.l = op_read(OPMODE_SP, sp);
aa.l = op_readsp(sp);
} break;
case 4: {
aa.h = op_read(OPMODE_SP, sp + 1);
aa.h = op_readsp(sp + 1);
} break;
case 5: {
cpu_io();
} break;
case 6: {
if(regs.p.m)last_cycle();
op_write(OPMODE_DBR, aa.w + regs.y.w, regs.a.l);
op_writedbr(aa.w + regs.y.w, regs.a.l);
if(regs.p.m)status.cycle_pos = 0;
} break;
case 7: {
last_cycle();
op_write(OPMODE_DBR, aa.w + regs.y.w + 1, regs.a.h);
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
status.cycle_pos = 0;
} break;
}

View File

@ -68,7 +68,7 @@ uint32 r;
}
void bCPU::dma_cputommio(uint8 i, uint8 bbus) {
if(cartridge.cart.sdd1 == true && sdd1->dma_active() == true) {
if(cartridge.info.sdd1 == true && sdd1->dma_active() == true) {
r_mem->write(0x2100 | bbus, sdd1->dma_read());
} else {
dma_transfer_byte(0, bbus, dma_addr(i));
@ -98,7 +98,7 @@ void bCPU::dma_run() {
if(channel[i].dma_enabled == false)continue;
//first byte transferred?
if(cartridge.cart.sdd1 == true && channel[i].read_index == 0) {
if(cartridge.info.sdd1 == true && channel[i].read_index == 0) {
sdd1->dma_begin(i, (channel[i].srcbank << 16) | (channel[i].srcaddr),
channel[i].xfersize);
}

View File

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

View File

@ -26,7 +26,6 @@
*/
uint16 bCPU::vcounter() { return time.v; }
uint16 bCPU::hcounter() { return get_hcounter(); }
uint16 bCPU::hcycles() { return time.hc; }
bool bCPU::interlace() { return time.interlace; }
@ -39,6 +38,13 @@ void bCPU::set_overscan (bool r) { time.overscan = r; update_interrupts(); }
uint8 bCPU::dma_counter() { return (time.dma_counter + time.hc) & 6; }
uint16 bCPU::hcounter() {
if(time.v == 240 && time.interlace == false && time.interlace_field == 1) {
return time.hc >> 2;
}
return (time.hc - ((time.hc > 1292) << 1) - ((time.hc > 1310) << 1)) >> 2;
}
bool bCPU::nmi_trigger_pos_match(uint32 offset) {
uint16 v = overscan() ? 240 : 225;
uint16 hc = 2 + offset;
@ -179,62 +185,6 @@ int16 hc, hc_end;
}
}
//all scanlines are 1364 cycles long, except scanline 240
//on non-interlace odd-frames, which is 1360 cycles long.
//[NTSC]
//interlace mode has 525 scanlines: 263 on the even frame,
//and 262 on the odd.
//non-interlace mode has 524 scanlines: 262 scanlines on
//both even and odd frames.
//[PAL] <PAL info is unverified on hardware>
//interlace mode has 625 scanlines: 313 on the even frame,
//and 312 on the odd.
//non-interlace mode has 624 scanlines: 312 scanlines on
//both even and odd frames.
//
//cycles per frame:
// 263 * 1364 = 358732
// 262 * 1364 = 357368
// 262 * 1364 - 4 = 357364
void bCPU::inc_vcounter() {
time.v++;
if(time.v >= time.frame_lines) {
time.v = 0;
time.interlace_field ^= 1;
if(interlace() == true && interlace_field() == 0) {
time.frame_lines = (time.region_scanlines >> 1) + 1;
} else {
time.frame_lines = (time.region_scanlines >> 1);
}
}
time.dma_counter += time.line_cycles;
if(time.v == 240 && time.interlace == false && time.interlace_field == 1) {
time.line_cycles = 1360;
} else {
time.line_cycles = 1364;
}
time.dram_refreshed = false;
update_interrupts();
}
//all dots are 4 cycles long, except dots 323 and 327. dots 323 and 327
//are 6 cycles long. this holds true for all scanlines except scanline
//240 on non-interlace odd frames. the reason for this is because this
//scanline is only 1360 cycles long, instead of 1364 like all other
//scanlines.
//this makes the effective range of hscan_pos 0-339 at all times.
//dot 323 range = { 1292, 1294, 1296 }
//dot 327 range = { 1310, 1312, 1314 }
uint16 bCPU::get_hcounter() {
if(time.v == 240 && time.interlace == false && time.interlace_field == 1) {
return time.hc >> 2;
}
return (time.hc - ((time.hc > 1292) << 1) - ((time.hc > 1310) << 1)) >> 2;
}
uint32 bCPU::clocks_executed() {
uint32 r = status.cycles_executed;
status.cycles_executed = 0;
@ -242,6 +192,13 @@ uint32 r = status.cycles_executed;
}
void bCPU::cycle_edge() {
if(time.line_rendered == false) {
if(time.hc >= 128) {
time.line_rendered = true;
r_ppu->render_scanline();
}
}
if(time.hdmainit_triggered == false) {
if(time.hc >= time.hdmainit_trigger_pos || time.v) {
time.hdmainit_triggered = true;
@ -265,20 +222,7 @@ void bCPU::add_cycles(int cycles) {
if(time.hc + cycles >= time.line_cycles) {
cycles = (time.hc + cycles) - time.line_cycles;
time.hc = 0;
inc_vcounter();
if(time.v == 0) {
frame();
r_ppu->frame();
snes->frame();
}
scanline();
r_ppu->scanline();
snes->scanline();
time.line_rendered = false;
poll_interrupts(cycles);
}
@ -291,38 +235,64 @@ void bCPU::add_cycles(int cycles) {
return;
}
}
/*
if(time.dram_refreshed == false) {
if(time.hc + cycles >= time.dram_refresh_pos) {
time.dram_refreshed = true;
status.cycles_executed += 40;
cycles = (time.hc + cycles) - time.dram_refresh_pos;
time.hc = time.dram_refresh_pos + 40;
}
if(cpu_version == 2) {
if(time.v != 240 || time.interlace != false || time.interlace_field != 1) {
if(time.dram_refresh_pos == 534) {
time.dram_refresh_pos = 538;
} else {
time.dram_refresh_pos = 534;
}
}
}
}
}
*/
if(time.line_rendered == false) {
//rendering should start at H=18 (+256=274), but since the
//current PPU emulation renders the entire scanline at once,
//PPU register changes mid-scanline do not show up.
//therefore, wait a few dots before rendering the scanline
if(time.hc >= (48 * 4)) {
time.line_rendered = true;
r_ppu->render_scanline();
}
void bCPU::scanline() {
if(++time.v >= time.frame_lines) {
frame();
}
//time.hc += cycles;
time.dma_counter += time.line_cycles;
if(time.v == 240 && time.interlace == false && time.interlace_field == 1) {
time.line_cycles = 1360;
} else {
time.line_cycles = 1364;
}
time.dram_refreshed = false;
time.line_rendered =
time.hdma_triggered = (time.v <= (!overscan() ? 224 : 239)) ? false : true;
r_ppu->scanline();
snes->scanline();
update_interrupts();
if(vcounter() == (!overscan() ? 227 : 242) && status.auto_joypad_poll == true) {
snes->poll_input(SNES::DEV_JOYPAD1);
snes->poll_input(SNES::DEV_JOYPAD2);
//When the SNES auto-polls the joypads, it writes 1, then 0 to
//$4016, then reads from each 16 times to get the joypad state
//information. As a result, the joypad read positions are set
//to 16 after such a poll. Position 16 is the controller
//connected status bit.
status.joypad1_read_pos = 16;
status.joypad2_read_pos = 16;
}
}
void bCPU::frame() {
time.nmi_read = 1;
time.nmi_line = 1;
time.nmi_transition = 0;
time.v = 0;
time.interlace_field ^= 1;
if(interlace() == true && interlace_field() == 0) {
time.frame_lines = (time.region_scanlines >> 1) + 1;
} else {
time.frame_lines = (time.region_scanlines >> 1);
}
if(cpu_version == 2) {
time.hdmainit_trigger_pos = 12 + dma_counter();
} else {
time.hdmainit_trigger_pos = 12 + 8 - dma_counter();
}
time.hdmainit_triggered = false;
r_ppu->frame();
snes->frame();
}
void bCPU::time_reset() {

View File

@ -67,8 +67,8 @@ struct {
inline uint8 dma_counter();
inline void inc_vcounter();
inline uint16 get_hcounter();
inline void cycle_edge();
inline void add_cycles(int cycles);
inline void scanline();
inline void frame();
inline void time_reset();

View File

@ -23,12 +23,13 @@ union {
bit<0x01> c;
};
CPURegFlags() { data = 0; }
inline operator unsigned() { return data; }
inline operator unsigned() const { return data; }
inline unsigned operator = (const uint8 i) { data = i; return data; }
inline unsigned operator |= (const uint8 i) { data |= i; return data; }
inline unsigned operator ^= (const uint8 i) { data ^= i; return data; }
inline unsigned operator &= (const uint8 i) { data &= i; return data; }
CPURegFlags() : data(0) {}
};
class CPUReg16 {
@ -38,8 +39,7 @@ union {
struct { uint8 order_lsb2(l, h); };
};
CPUReg16() { w = 0; }
inline operator unsigned() { return w; }
inline operator unsigned() const { return w; }
template<typename T> inline unsigned operator = (const T i) { w = i; return w; }
template<typename T> inline unsigned operator |= (const T i) { w |= i; return w; }
template<typename T> inline unsigned operator ^= (const T i) { w ^= i; return w; }
@ -51,6 +51,8 @@ union {
template<typename T> inline unsigned operator *= (const T i) { w *= i; return w; }
template<typename T> inline unsigned operator /= (const T i) { w /= i; return w; }
template<typename T> inline unsigned operator %= (const T i) { w %= i; return w; }
CPUReg16() : w(0) {}
};
class CPUReg24 {
@ -61,8 +63,7 @@ union {
struct { uint8 order_lsb4(l, h, b, bh); };
};
CPUReg24() { d = 0; }
inline operator unsigned() { return d; }
inline operator unsigned() const { return d; }
template<typename T> inline unsigned operator = (const T i) { d = uclip<24>(i); return d; }
template<typename T> inline unsigned operator |= (const T i) { d = uclip<24>(d | i); return d; }
template<typename T> inline unsigned operator ^= (const T i) { d = uclip<24>(d ^ i); return d; }
@ -74,6 +75,8 @@ union {
template<typename T> inline unsigned operator *= (const T i) { d = uclip<24>(d * i); return d; }
template<typename T> inline unsigned operator /= (const T i) { d = uclip<24>(d / i); return d; }
template<typename T> inline unsigned operator %= (const T i) { d = uclip<24>(d % i); return d; }
CPUReg24() : d(0) {}
};
class CPURegs {
@ -84,5 +87,6 @@ CPURegFlags p;
uint8 db;
uint8 mdr;
bool e;
CPURegs() { db = 0; mdr = 0x00; e = false; }
bool acc_8b, idx_8b;
CPURegs() : db(0), mdr(0x00), e(false), acc_8b(true), idx_8b(true) {}
};

View File

@ -1,12 +1,11 @@
#include "opfn.cpp"
//#include "op_read.cpp"
//#include "op_write.cpp"
//#include "op_rmw.cpp"
//#include "op_pc.cpp"
//#include "op_misc.cpp"
void sCPU::main() {
for(;;) {
#ifdef DEBUGGER
snes->notify(SNES::CPU_EXEC_OPCODE_BEGIN);
#endif
status.in_opcode = true;
if(event.irq) {
@ -21,7 +20,6 @@ void sCPU::main() {
op_irq();
}
// (this->*optbl[op_readpc()])();
switch(op_readpc()) {
#include "op_read.cpp"
#include "op_write.cpp"
@ -31,7 +29,14 @@ void sCPU::main() {
}
status.in_opcode = false;
opcode_edge();
#ifdef DEBUGGER
snes->notify(SNES::CPU_EXEC_OPCODE_END);
#endif
#ifdef FAVOR_SPEED
co_return();
#endif
}
}

View File

@ -6,7 +6,7 @@ uint8 dp, sp;
inline void main();
inline void op_irq();
bool in_opcode() { return status.in_opcode; }
inline bool in_opcode() { return status.in_opcode; }
//op_read
void op_adc_b();

View File

@ -15,7 +15,7 @@ xba(0xeb) {
regs.a.l ^= regs.a.h;
regs.a.h ^= regs.a.l;
regs.a.l ^= regs.a.h;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.n = bool(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
@ -27,8 +27,11 @@ mvp(0x44, --) {
rd.l = op_readlong((sp << 16) | regs.x.w);
4:op_writelong((dp << 16) | regs.y.w, rd.l);
5:op_io();
if(regs.p.x) { regs.x.l$1; regs.y.l$1; }
else { regs.x.w$1; regs.y.w$1; }
if(regs.idx_8b) {
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;
@ -77,11 +80,12 @@ xce(0xfb) {
bool c = regs.p.c;
regs.p.c = regs.e;
regs.e = c;
if(regs.e) {
regs.p |= 0x30;
if(regs.e)regs.s.h = 0x01;
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
regs.x.h = 0x00;
regs.y.h = 0x00;
regs.s.h = 0x01;
}
}
@ -103,28 +107,29 @@ sep(0xe2, |=) {
2:last_cycle();
op_io();
regs.p $1 rd.l;
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
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) {
tax(0xaa, regs.idx_8b, x, a),
tay(0xa8, regs.idx_8b, y, a),
txa(0x8a, regs.acc_8b, a, x),
txy(0x9b, regs.idx_8b, y, x),
tya(0x98, regs.acc_8b, a, y),
tyx(0xbb, regs.idx_8b, x, y) {
1:last_cycle();
op_io();
if($1) {
regs.$2.l = regs.$3.l;
regs.p.n = !!(regs.$2.l & 0x80);
regs.p.n = bool(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.n = bool(regs.$2.w & 0x8000);
regs.p.z = (regs.$2.w == 0);
}
}
@ -133,7 +138,7 @@ tcd(0x5b) {
1:last_cycle();
op_io();
regs.d.w = regs.a.w;
regs.p.n = !!(regs.d.w & 0x8000);
regs.p.n = bool(regs.d.w & 0x8000);
regs.p.z = (regs.d.w == 0);
}
@ -148,7 +153,7 @@ tdc(0x7b) {
1:last_cycle();
op_io();
regs.a.w = regs.d.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
@ -157,10 +162,10 @@ tsc(0x3b) {
op_io();
regs.a.w = regs.s.w;
if(regs.e) {
regs.p.n = !!(regs.a.l & 0x80);
regs.p.n = bool(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
}
@ -168,13 +173,13 @@ tsc(0x3b) {
tsx(0xba) {
1:last_cycle();
op_io();
if(regs.p.x) {
if(regs.idx_8b) {
regs.x.l = regs.s.l;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.n = bool(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.n = bool(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
}
@ -189,10 +194,10 @@ txs(0x9a) {
}
}
pha(0x48, regs.p.m, a),
phx(0xda, regs.p.x, x),
phy(0x5a, regs.p.x, y),
phd(0x0b, 0, d) {
pha(0x48, regs.acc_8b, a),
phx(0xda, regs.idx_8b, x),
phy(0x5a, regs.idx_8b, y),
phd(0x0b, 0, d) {
1:op_io();
2:if(!$1)op_writestack(regs.$2.h);
3:last_cycle();
@ -207,22 +212,22 @@ php(0x08, regs.p) {
op_writestack($1);
}
pla(0x68, regs.p.m, a),
plx(0xfa, regs.p.x, x),
ply(0x7a, regs.p.x, y),
pld(0x2b, 0, d) {
pla(0x68, regs.acc_8b, a),
plx(0xfa, regs.idx_8b, x),
ply(0x7a, regs.idx_8b, y),
pld(0x2b, 0, d) {
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.n = bool(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.n = bool(regs.$2.w & 0x8000);
regs.p.z = (regs.$2.w == 0);
}
@ -231,7 +236,7 @@ plb(0xab) {
2:op_io();
3:last_cycle();
regs.db = op_readstack();
regs.p.n = !!(regs.db & 0x80);
regs.p.n = bool(regs.db & 0x80);
regs.p.z = (regs.db == 0);
}
@ -240,8 +245,9 @@ plp(0x28) {
2:op_io();
3:last_cycle();
regs.p = op_readstack();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}

View File

@ -18,7 +18,7 @@ case 0xeb: {
regs.a.l ^= regs.a.h;
regs.a.h ^= regs.a.l;
regs.a.l ^= regs.a.h;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.n = bool(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} break;
@ -30,8 +30,11 @@ case 0x54: {
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++; }
if(regs.idx_8b) {
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;
@ -45,8 +48,11 @@ case 0x44: {
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--; }
if(regs.idx_8b) {
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;
@ -114,11 +120,12 @@ case 0xfb: {
bool c = regs.p.c;
regs.p.c = regs.e;
regs.e = c;
if(regs.e) {
regs.p |= 0x30;
if(regs.e)regs.s.h = 0x01;
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
regs.x.h = 0x00;
regs.y.h = 0x00;
regs.s.h = 0x01;
}
} break;
@ -177,8 +184,9 @@ case 0xc2: {
last_cycle();
op_io();
regs.p &=~ rd.l;
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
@ -190,8 +198,9 @@ case 0xe2: {
last_cycle();
op_io();
regs.p |= rd.l;
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
@ -201,13 +210,13 @@ case 0xe2: {
case 0xaa: {
last_cycle();
op_io();
if(regs.p.x) {
if(regs.idx_8b) {
regs.x.l = regs.a.l;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.n = bool(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.n = bool(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
} break;
@ -216,13 +225,13 @@ case 0xaa: {
case 0xa8: {
last_cycle();
op_io();
if(regs.p.x) {
if(regs.idx_8b) {
regs.y.l = regs.a.l;
regs.p.n = !!(regs.y.l & 0x80);
regs.p.n = bool(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.n = bool(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
} break;
@ -231,13 +240,13 @@ case 0xa8: {
case 0x8a: {
last_cycle();
op_io();
if(regs.p.m) {
if(regs.acc_8b) {
regs.a.l = regs.x.l;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.n = bool(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.n = bool(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
} break;
@ -246,13 +255,13 @@ case 0x8a: {
case 0x9b: {
last_cycle();
op_io();
if(regs.p.x) {
if(regs.idx_8b) {
regs.y.l = regs.x.l;
regs.p.n = !!(regs.y.l & 0x80);
regs.p.n = bool(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.n = bool(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
} break;
@ -261,13 +270,13 @@ case 0x9b: {
case 0x98: {
last_cycle();
op_io();
if(regs.p.m) {
if(regs.acc_8b) {
regs.a.l = regs.y.l;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.n = bool(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.n = bool(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
} break;
@ -276,13 +285,13 @@ case 0x98: {
case 0xbb: {
last_cycle();
op_io();
if(regs.p.x) {
if(regs.idx_8b) {
regs.x.l = regs.y.l;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.n = bool(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.n = bool(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
} break;
@ -292,7 +301,7 @@ case 0x5b: {
last_cycle();
op_io();
regs.d.w = regs.a.w;
regs.p.n = !!(regs.d.w & 0x8000);
regs.p.n = bool(regs.d.w & 0x8000);
regs.p.z = (regs.d.w == 0);
} break;
@ -309,7 +318,7 @@ case 0x7b: {
last_cycle();
op_io();
regs.a.w = regs.d.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
} break;
@ -319,10 +328,10 @@ case 0x3b: {
op_io();
regs.a.w = regs.s.w;
if(regs.e) {
regs.p.n = !!(regs.a.l & 0x80);
regs.p.n = bool(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
} else {
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
} break;
@ -331,13 +340,13 @@ case 0x3b: {
case 0xba: {
last_cycle();
op_io();
if(regs.p.x) {
if(regs.idx_8b) {
regs.x.l = regs.s.l;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.n = bool(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.n = bool(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
} break;
@ -356,7 +365,7 @@ case 0x9a: {
//pha
case 0x48: {
op_io();
if(!regs.p.m)op_writestack(regs.a.h);
if(!regs.acc_8b)op_writestack(regs.a.h);
last_cycle();
op_writestack(regs.a.l);
} break;
@ -364,7 +373,7 @@ case 0x48: {
//phx
case 0xda: {
op_io();
if(!regs.p.x)op_writestack(regs.x.h);
if(!regs.idx_8b)op_writestack(regs.x.h);
last_cycle();
op_writestack(regs.x.l);
} break;
@ -372,7 +381,7 @@ case 0xda: {
//phy
case 0x5a: {
op_io();
if(!regs.p.x)op_writestack(regs.y.h);
if(!regs.idx_8b)op_writestack(regs.y.h);
last_cycle();
op_writestack(regs.y.l);
} break;
@ -380,9 +389,9 @@ case 0x5a: {
//phd
case 0x0b: {
op_io();
if(!0)op_writestack(regs. d.h);
if(!0)op_writestack(regs. d.h);
last_cycle();
op_writestack(regs. d.l);
op_writestack(regs. d.l);
} break;
//phb
@ -410,16 +419,16 @@ case 0x08: {
case 0x68: {
op_io();
op_io();
if(regs.p.m)last_cycle();
if(regs.acc_8b)last_cycle();
regs.a.l = op_readstack();
if(regs.p.m) {
regs.p.n = !!(regs.a.l & 0x80);
if(regs.acc_8b) {
regs.p.n = bool(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.n = bool(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
} break;
@ -427,16 +436,16 @@ case 0x68: {
case 0xfa: {
op_io();
op_io();
if(regs.p.x)last_cycle();
if(regs.idx_8b)last_cycle();
regs.x.l = op_readstack();
if(regs.p.x) {
regs.p.n = !!(regs.x.l & 0x80);
if(regs.idx_8b) {
regs.p.n = bool(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.n = bool(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
} break;
@ -444,16 +453,16 @@ case 0xfa: {
case 0x7a: {
op_io();
op_io();
if(regs.p.x)last_cycle();
if(regs.idx_8b)last_cycle();
regs.y.l = op_readstack();
if(regs.p.x) {
regs.p.n = !!(regs.y.l & 0x80);
if(regs.idx_8b) {
regs.p.n = bool(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.n = bool(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
} break;
@ -462,16 +471,16 @@ case 0x2b: {
op_io();
op_io();
if(0)last_cycle();
regs. d.l = op_readstack();
regs. d.l = op_readstack();
if(0) {
regs.p.n = !!(regs. d.l & 0x80);
regs.p.z = (regs. d.l == 0);
regs.p.n = bool(regs. d.l & 0x80);
regs.p.z = (regs. d.l == 0);
break;
}
last_cycle();
regs. d.h = op_readstack();
regs.p.n = !!(regs. d.w & 0x8000);
regs.p.z = (regs. d.w == 0);
regs. d.h = op_readstack();
regs.p.n = bool(regs. d.w & 0x8000);
regs.p.z = (regs. d.w == 0);
} break;
//plb
@ -480,7 +489,7 @@ case 0xab: {
op_io();
last_cycle();
regs.db = op_readstack();
regs.p.n = !!(regs.db & 0x80);
regs.p.n = bool(regs.db & 0x80);
regs.p.z = (regs.db == 0);
} break;
@ -490,8 +499,9 @@ case 0x28: {
op_io();
last_cycle();
regs.p = op_readstack();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}

View File

@ -48,7 +48,7 @@ jmp_long(0x5c) {
2:rd.h = op_readpc();
3:last_cycle();
rd.b = op_readpc();
regs.pc.d = rd.d & 0xffffff;
regs.pc.d = uclip<24>(rd.d);
}
jmp_iaddr(0x6c) {
@ -77,7 +77,7 @@ jmp_iladdr(0xdc) {
4:rd.h = op_readaddr(aa.w + 1);
5:last_cycle();
rd.b = op_readaddr(aa.w + 2);
regs.pc.d = rd.d & 0xffffff;
regs.pc.d = uclip<24>(rd.d);
}
jsr_addr(0x20) {
@ -101,7 +101,7 @@ jsr_long(0x22) {
op_writestack(regs.pc.h);
7:last_cycle();
op_writestack(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
regs.pc.d = uclip<24>(aa.d);
}
jsr_iaddrx(0xfc) {
@ -120,8 +120,9 @@ rti(0x40) {
1:op_io();
2:op_io();
3:regs.p = op_readstack();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
@ -134,7 +135,7 @@ rti(0x40) {
}
6:last_cycle();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
regs.pc.d = uclip<24>(rd.d);
}
rts(0x60) {
@ -155,6 +156,6 @@ rtl(0x6b) {
4:rd.h = op_readstack();
5:last_cycle();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
regs.pc.d = uclip<24>(rd.d);
regs.pc.w++;
}

View File

@ -151,7 +151,7 @@ case 0x5c: {
rd.h = op_readpc();
last_cycle();
rd.b = op_readpc();
regs.pc.d = rd.d & 0xffffff;
regs.pc.d = uclip<24>(rd.d);
} break;
//jmp_iaddr
@ -183,7 +183,7 @@ case 0xdc: {
rd.h = op_readaddr(aa.w + 1);
last_cycle();
rd.b = op_readaddr(aa.w + 2);
regs.pc.d = rd.d & 0xffffff;
regs.pc.d = uclip<24>(rd.d);
} break;
//jsr_addr
@ -209,7 +209,7 @@ case 0x22: {
op_writestack(regs.pc.h);
last_cycle();
op_writestack(regs.pc.l);
regs.pc.d = aa.d & 0xffffff;
regs.pc.d = uclip<24>(aa.d);
} break;
//jsr_iaddrx
@ -230,8 +230,9 @@ case 0x40: {
op_io();
op_io();
regs.p = op_readstack();
if(regs.e)regs.p |= 0x30;
if(regs.p.x) {
regs.acc_8b = (regs.e || regs.p.m);
regs.idx_8b = (regs.e || regs.p.x);
if(regs.idx_8b) {
regs.x.h = 0x00;
regs.y.h = 0x00;
}
@ -244,7 +245,7 @@ case 0x40: {
}
last_cycle();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
regs.pc.d = uclip<24>(rd.d);
} break;
//rts
@ -267,7 +268,7 @@ case 0x6b: {
rd.h = op_readstack();
last_cycle();
rd.b = op_readstack();
regs.pc.d = rd.d & 0xffffff;
regs.pc.d = uclip<24>(rd.d);
regs.pc.w++;
} break;

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

@ -23,8 +23,8 @@ int32 r = regs.a.l + rd.l + regs.p.c;
r = regs.a.l + rd.l + regs.p.c;
regs.p.c = (r > 0xff);
}
regs.p.n = !!(r & 0x80);
regs.p.v = !!(~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
regs.p.n = bool(r & 0x80);
regs.p.v = bool(~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
regs.p.z = ((uint8)r == 0);
regs.a.l = r;
}
@ -67,135 +67,135 @@ int32 r;
r = regs.a.w + rd.w + regs.p.c;
regs.p.c = (r > 0xffff);
}
regs.p.n = !!(r & 0x8000);
regs.p.v = !!(~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
regs.p.n = bool(r & 0x8000);
regs.p.v = bool(~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
regs.p.z = ((uint16)r == 0);
regs.a.w = r;
}
inline void sCPU::op_and_b() {
regs.a.l &= rd.l;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.n = bool(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
inline void sCPU::op_and_w() {
regs.a.w &= rd.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
inline void sCPU::op_bit_b() {
regs.p.n = !!(rd.l & 0x80);
regs.p.v = !!(rd.l & 0x40);
regs.p.n = bool(rd.l & 0x80);
regs.p.v = bool(rd.l & 0x40);
regs.p.z = ((rd.l & regs.a.l) == 0);
}
inline void sCPU::op_bit_w() {
regs.p.n = !!(rd.w & 0x8000);
regs.p.v = !!(rd.w & 0x4000);
regs.p.n = bool(rd.w & 0x8000);
regs.p.v = bool(rd.w & 0x4000);
regs.p.z = ((rd.w & regs.a.w) == 0);
}
inline void sCPU::op_cmp_b() {
int32 r = regs.a.l - rd.l;
regs.p.n = !!(r & 0x80);
regs.p.n = bool(r & 0x80);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r >= 0);
}
inline void sCPU::op_cmp_w() {
int32 r = regs.a.w - rd.w;
regs.p.n = !!(r & 0x8000);
regs.p.n = bool(r & 0x8000);
regs.p.z = ((uint16)r == 0);
regs.p.c = (r >= 0);
}
inline void sCPU::op_cpx_b() {
int32 r = regs.x.l - rd.l;
regs.p.n = !!(r & 0x80);
regs.p.n = bool(r & 0x80);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r >= 0);
}
inline void sCPU::op_cpx_w() {
int32 r = regs.x.w - rd.w;
regs.p.n = !!(r & 0x8000);
regs.p.n = bool(r & 0x8000);
regs.p.z = ((uint16)r == 0);
regs.p.c = (r >= 0);
}
inline void sCPU::op_cpy_b() {
int32 r = regs.y.l - rd.l;
regs.p.n = !!(r & 0x80);
regs.p.n = bool(r & 0x80);
regs.p.z = ((uint8)r == 0);
regs.p.c = (r >= 0);
}
inline void sCPU::op_cpy_w() {
int32 r = regs.y.w - rd.w;
regs.p.n = !!(r & 0x8000);
regs.p.n = bool(r & 0x8000);
regs.p.z = ((uint16)r == 0);
regs.p.c = (r >= 0);
}
inline void sCPU::op_eor_b() {
regs.a.l ^= rd.l;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.n = bool(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
inline void sCPU::op_eor_w() {
regs.a.w ^= rd.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
inline void sCPU::op_lda_b() {
regs.a.l = rd.l;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.n = bool(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
inline void sCPU::op_lda_w() {
regs.a.w = rd.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
inline void sCPU::op_ldx_b() {
regs.x.l = rd.l;
regs.p.n = !!(regs.x.l & 0x80);
regs.p.n = bool(regs.x.l & 0x80);
regs.p.z = (regs.x.l == 0);
}
inline void sCPU::op_ldx_w() {
regs.x.w = rd.w;
regs.p.n = !!(regs.x.w & 0x8000);
regs.p.n = bool(regs.x.w & 0x8000);
regs.p.z = (regs.x.w == 0);
}
inline void sCPU::op_ldy_b() {
regs.y.l = rd.l;
regs.p.n = !!(regs.y.l & 0x80);
regs.p.n = bool(regs.y.l & 0x80);
regs.p.z = (regs.y.l == 0);
}
inline void sCPU::op_ldy_w() {
regs.y.w = rd.w;
regs.p.n = !!(regs.y.w & 0x8000);
regs.p.n = bool(regs.y.w & 0x8000);
regs.p.z = (regs.y.w == 0);
}
inline void sCPU::op_ora_b() {
regs.a.l |= rd.l;
regs.p.n = !!(regs.a.l & 0x80);
regs.p.n = bool(regs.a.l & 0x80);
regs.p.z = (regs.a.l == 0);
}
inline void sCPU::op_ora_w() {
regs.a.w |= rd.w;
regs.p.n = !!(regs.a.w & 0x8000);
regs.p.n = bool(regs.a.w & 0x8000);
regs.p.z = (regs.a.w == 0);
}
@ -221,8 +221,8 @@ int32 r;
r = regs.a.l - rd.l - !regs.p.c;
regs.p.c = (r >= 0);
}
regs.p.n = !!(r & 0x80);
regs.p.v = !!((regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
regs.p.n = bool(r & 0x80);
regs.p.v = bool((regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
regs.p.z = ((uint8)r == 0);
regs.a.l = r;
}
@ -261,8 +261,8 @@ int32 r;
r = regs.a.w - rd.w - !regs.p.c;
regs.p.c = (r >= 0);
}
regs.p.n = !!(r & 0x8000);
regs.p.v = !!((regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
regs.p.n = bool(r & 0x8000);
regs.p.v = bool((regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
regs.p.z = ((uint16)r == 0);
regs.a.w = r;
}
@ -270,71 +270,71 @@ int32 r;
//op_rmw
inline void sCPU::op_inc_b() {
rd.l++;
regs.p.n = !!(rd.l & 0x80);
regs.p.n = bool(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void sCPU::op_inc_w() {
rd.w++;
regs.p.n = !!(rd.w & 0x8000);
regs.p.n = bool(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void sCPU::op_dec_b() {
rd.l--;
regs.p.n = !!(rd.l & 0x80);
regs.p.n = bool(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void sCPU::op_dec_w() {
rd.w--;
regs.p.n = !!(rd.w & 0x8000);
regs.p.n = bool(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void sCPU::op_asl_b() {
regs.p.c = !!(rd.l & 0x80);
regs.p.c = bool(rd.l & 0x80);
rd.l <<= 1;
regs.p.n = !!(rd.l & 0x80);
regs.p.n = bool(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void sCPU::op_asl_w() {
regs.p.c = !!(rd.w & 0x8000);
regs.p.c = bool(rd.w & 0x8000);
rd.w <<= 1;
regs.p.n = !!(rd.w & 0x8000);
regs.p.n = bool(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void sCPU::op_lsr_b() {
regs.p.c = rd.l & 1;
rd.l >>= 1;
regs.p.n = !!(rd.l & 0x80);
regs.p.n = bool(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void sCPU::op_lsr_w() {
regs.p.c = rd.w & 1;
rd.w >>= 1;
regs.p.n = !!(rd.w & 0x8000);
regs.p.n = bool(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
inline void sCPU::op_rol_b() {
uint16 c = regs.p.c;
regs.p.c = !!(rd.l & 0x80);
regs.p.c = bool(rd.l & 0x80);
rd.l <<= 1;
rd.l |= c;
regs.p.n = !!(rd.l & 0x80);
regs.p.n = bool(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
inline void sCPU::op_rol_w() {
uint16 c = regs.p.c;
regs.p.c = !!(rd.w & 0x8000);
regs.p.c = bool(rd.w & 0x8000);
rd.w <<= 1;
rd.w |= c;
regs.p.n = !!(rd.w & 0x8000);
regs.p.n = bool(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}
@ -343,7 +343,7 @@ uint16 c = (regs.p.c)?0x80:0;
regs.p.c = rd.l & 1;
rd.l >>= 1;
rd.l |= c;
regs.p.n = !!(rd.l & 0x80);
regs.p.n = bool(rd.l & 0x80);
regs.p.z = (rd.l == 0);
}
@ -352,7 +352,7 @@ uint16 c = (regs.p.c)?0x8000:0;
regs.p.c = rd.w & 1;
rd.w >>= 1;
rd.w |= c;
regs.p.n = !!(rd.w & 0x8000);
regs.p.n = bool(rd.w & 0x8000);
regs.p.z = (rd.w == 0);
}

View File

@ -77,7 +77,7 @@ uint32 sCPU::hdma_iaddr(uint8 i) {
*****/
void sCPU::dma_transfertobusb(uint8 i, uint8 bbus) {
if(cartridge.cart.sdd1 == true && sdd1->dma_active() == true) {
if(cartridge.info.sdd1 == true && sdd1->dma_active() == true) {
r_mem->write(0x2100 | bbus, sdd1->dma_read());
} else {
dma_transfer(0, bbus, dma_addr(i));
@ -105,8 +105,9 @@ void sCPU::dma_run() {
for(int i = 0; i < 8; i++) {
if(channel[i].dma_enabled == false)continue;
add_clocks(8);
if(cartridge.cart.sdd1 == true) {
if(cartridge.info.sdd1 == true) {
sdd1->dma_begin(i, (channel[i].srcbank << 16) | (channel[i].srcaddr),
channel[i].xfersize);
}
@ -114,10 +115,12 @@ void sCPU::dma_run() {
uint index = 0;
do {
dma_write(i, dma_bbus(i, index++));
} while(channel[i].xfersize);
} while(channel[i].dma_enabled && channel[i].xfersize);
channel[i].dma_enabled = false;
}
set_irq_delay(24);
}
/*****
@ -176,6 +179,8 @@ void sCPU::hdma_run() {
static uint8 hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
for(int i = 0; i < 8; i++) {
if(hdma_active(i) == false)continue;
channel[i].dma_enabled = false; //HDMA run during DMA will stop DMA mid-transfer
add_clocks(8);
if(channel[i].hdma_do_transfer) {
int xferlen = hdma_xferlen[channel[i].xfermode];
@ -197,6 +202,8 @@ static uint8 hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
hdma_update(i);
}
}
set_irq_delay(24);
}
void sCPU::hdma_init() {
@ -211,17 +218,20 @@ void sCPU::hdma_init() {
for(int i = 0; i < 8; i++) {
if(!channel[i].hdma_enabled)continue;
channel[i].dma_enabled = false; //HDMA init during DMA will stop DMA mid-transfer
channel[i].hdma_addr = channel[i].srcaddr;
hdma_update(i);
}
set_irq_delay(24);
}
/*****
* power / reset functions
*****/
void sCPU::dma_reset() {
void sCPU::dma_power() {
for(int i = 0; i < 8; i++) {
channel[i].dma_enabled = false;
channel[i].hdma_enabled = false;
@ -245,7 +255,11 @@ void sCPU::dma_reset() {
channel[i].hdma_addr = 0xffff;
channel[i].hdma_line_counter = 0xff;
channel[i].unknown = 0xff;
}
}
void sCPU::dma_reset() {
for(int i = 0; i < 8; i++) {
channel[i].hdma_completed = false;
channel[i].hdma_do_transfer = false;
}

View File

@ -64,4 +64,5 @@ struct {
void hdma_run();
void hdma_init();
void dma_power();
void dma_reset();

View File

@ -31,8 +31,7 @@ void sCPU::op_write(uint32 addr, uint8 data) {
#ifdef FAVOR_ACCURACY
co_return();
#endif
//below needs to be verified on hardware
//regs.mdr = data;
r_mem->write(addr, data);
regs.mdr = data;
r_mem->write(addr, regs.mdr);
cycle_edge();
}

View File

@ -41,45 +41,18 @@ void sCPU::mmio_w2183(uint8 data) {
* Joypad registers
*****/
//TODO: test whether strobe latch of zero returns
//realtime or buffered status of joypadN.b
//JOYSER0
//7-2 = MDR
//1-0 = Joypad serial data
/*****
* The joypad contains a small bit shifter that has 16 bits.
* Reading from 4016 reads one bit from this buffer, then moves
* the buffer left one, and adds a '1' to the rightmost bit.
* Writing a one to $4016 will fill the buffer with the current
* joypad button states, and lock the bit shifter at position
* zero. All reads will be the first buffer state, or 'B'.
* A zero must be written back to $4016 to unlock the buffer,
* so that reads will increment the bit shifting position.
*****/
uint8 sCPU::mmio_r4016() {
uint8 r = regs.mdr & 0xfc;
if(status.joypad_strobe_latch == 1) {
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_B));
} else {
switch(status.joypad1_read_pos) {
case 0: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_B)); break;
case 1: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_Y)); break;
case 2: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_SELECT)); break;
case 3: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_START)); break;
case 4: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_UP)); break;
case 5: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_DOWN)); break;
case 6: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_LEFT)); break;
case 7: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_RIGHT)); break;
case 8: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_A)); break;
case 9: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_X)); break;
case 10: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_L)); break;
case 11: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_R)); break;
case 12: break;
case 13: break;
case 14: break;
case 15: break; //bits 12-15 always return 0
//all subsequent reads return joypad connection status
case 16: r |= 1; break; //joypad connected bit
}
if(++status.joypad1_read_pos > 16)status.joypad1_read_pos = 16;
r |= status.joypad1_bits & 1;
if(status.joypad_strobe_latch == 0) {
status.joypad1_bits >>= 1;
status.joypad1_bits |= ~0xffff;
}
return r;
@ -91,87 +64,25 @@ uint8 r = regs.mdr & 0xfc;
//1-0 = Joypad serial data
uint8 sCPU::mmio_r4017() {
uint8 r = (regs.mdr & 0xe0) | 0x1c;
if(status.joypad_strobe_latch == 1) {
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_B));
} else {
switch(status.joypad2_read_pos) {
case 0: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_B)); break;
case 1: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_Y)); break;
case 2: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_SELECT)); break;
case 3: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_START)); break;
case 4: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_UP)); break;
case 5: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_DOWN)); break;
case 6: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_LEFT)); break;
case 7: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_RIGHT)); break;
case 8: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_A)); break;
case 9: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_X)); break;
case 10: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_L)); break;
case 11: r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_R)); break;
case 12: break;
case 13: break;
case 14: break;
case 15: break; //bits 12-15 always return 0
//all subsequent reads return joypad connection status
case 16: r |= 1; break; //joypad connected bit
}
if(++status.joypad2_read_pos > 16)status.joypad2_read_pos = 16;
r |= status.joypad2_bits & 1;
if(status.joypad_strobe_latch == 0) {
status.joypad2_bits >>= 1;
status.joypad2_bits |= ~0xffff;
}
return r;
}
//JOY1L
//TODO: handle reads during joypad polling (v=225-227)
uint8 sCPU::mmio_r4218() {
uint8 r = 0x00;
if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_A)) << 7;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_X)) << 6;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_L)) << 5;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_R)) << 4;
return r;
}
//JOY1H
uint8 sCPU::mmio_r4219() {
uint8 r = 0x00;
if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_B)) << 7;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_Y)) << 6;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_SELECT)) << 5;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_START)) << 4;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_UP)) << 3;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_DOWN)) << 2;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_LEFT)) << 1;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_RIGHT));
return r;
}
//JOY2L
uint8 sCPU::mmio_r421a() {
uint8 r = 0x00;
if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_A)) << 7;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_X)) << 6;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_L)) << 5;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_R)) << 4;
return r;
}
//JOY2H
uint8 sCPU::mmio_r421b() {
uint8 r = 0x00;
if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_B)) << 7;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_Y)) << 6;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_SELECT)) << 5;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_START)) << 4;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_UP)) << 3;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_DOWN)) << 2;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_LEFT)) << 1;
r |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_RIGHT));
return r;
}
uint8 sCPU::mmio_r4218() { return status.joy1l; } //JOY1L
uint8 sCPU::mmio_r4219() { return status.joy1h; } //JOY1H
uint8 sCPU::mmio_r421a() { return status.joy2l; } //JOY2L
uint8 sCPU::mmio_r421b() { return status.joy2h; } //JOY2H
uint8 sCPU::mmio_r421c() { return status.joy3l; } //JOY3L
uint8 sCPU::mmio_r421d() { return status.joy3h; } //JOY3H
uint8 sCPU::mmio_r421e() { return status.joy4l; } //JOY4L
uint8 sCPU::mmio_r421f() { return status.joy4h; } //JOY4H
//JOYSER0
//bit 0 is shared between JOYSER0 and JOYSER1, therefore
@ -181,10 +92,7 @@ void sCPU::mmio_w4016(uint8 data) {
status.joypad_strobe_latch = bool(data & 1);
if(status.joypad_strobe_latch == 1) {
snes->poll_input(SNES::DEV_JOYPAD1);
snes->poll_input(SNES::DEV_JOYPAD2);
status.joypad1_read_pos = 0;
status.joypad2_read_pos = 0;
run_manual_joypad_poll();
}
}
@ -234,7 +142,7 @@ uint8 r = (regs.mdr & 0x3e);
uint16 vs = !overscan() ? 225 : 240;
//auto joypad polling
if(status.hclock >= vs && status.hclock <= (vs + 2))r |= 0x01;
if(status.vcounter >= vs && status.vcounter <= (vs + 2))r |= 0x01;
//hblank
if(status.hclock <= 2 || status.hclock >= 1096)r |= 0x40;
@ -252,6 +160,8 @@ void sCPU::mmio_w4200(uint8 data) {
status.hirq_enabled = bool(data & 0x10);
status.auto_joypad_poll = bool(data & 0x01);
//if(!status.nmi_enabled)status.nmi_read=1;
if(status.nmi_read == 0) {
if(status.nmi_line == 1 && !status.nmi_enabled == 0) {
status.nmi_transition = 1;
@ -266,6 +176,7 @@ void sCPU::mmio_w4200(uint8 data) {
}
update_interrupts();
set_irq_delay(2);
}
//HTIMEL
@ -519,14 +430,17 @@ void sCPU::mmio_w43xb(uint8 i, uint8 data) {
* reset / read / write
*****/
void sCPU::mmio_power() {
}
void sCPU::mmio_reset() {
//$2181-$2183
status.wram_addr = 0x000000;
//$4016-$4017
status.joypad_strobe_latch = 0;
status.joypad1_read_pos = 0;
status.joypad2_read_pos = 0;
status.joypad1_bits = ~0;
status.joypad2_bits = ~0;
//$4200
status.nmi_enabled = false;
@ -552,6 +466,16 @@ void sCPU::mmio_reset() {
//$4214-$4217
status.r4214 = 0x0000;
status.r4216 = 0x0000;
//$4218-$421f
status.joy1l = 0x00;
status.joy1h = 0x00;
status.joy2l = 0x00;
status.joy2h = 0x00;
status.joy3l = 0x00;
status.joy3h = 0x00;
status.joy4l = 0x00;
status.joy4h = 0x00;
}
uint8 sCPU::mmio_read(uint16 addr) {
@ -602,10 +526,10 @@ uint8 sCPU::mmio_read(uint16 addr) {
case 0x4219: return mmio_r4219();
case 0x421a: return mmio_r421a();
case 0x421b: return mmio_r421b();
case 0x421c: return 0x00;
case 0x421d: return 0x00;
case 0x421e: return 0x00;
case 0x421f: return 0x00;
case 0x421c: return mmio_r421c();
case 0x421d: return mmio_r421d();
case 0x421e: return mmio_r421e();
case 0x421f: return mmio_r421f();
}
return regs.mdr;

View File

@ -1,3 +1,4 @@
void mmio_power();
void mmio_reset();
uint8 mmio_read (uint16 addr);
void mmio_write(uint16 addr, uint8 data);
@ -19,6 +20,10 @@
uint8 mmio_r4219();
uint8 mmio_r421a();
uint8 mmio_r421b();
uint8 mmio_r421c();
uint8 mmio_r421d();
uint8 mmio_r421e();
uint8 mmio_r421f();
uint8 mmio_r43x0(uint8 i);
uint8 mmio_r43x1(uint8 i);
uint8 mmio_r43x2(uint8 i);

View File

@ -19,6 +19,11 @@ void sCPU::power() {
regs.a = regs.x = regs.y = 0x0000;
regs.s = 0x01ff;
mmio_power();
dma_power();
timing_power();
reset();
}
@ -30,7 +35,10 @@ void sCPU::reset() {
regs.pc.l = r_mem->read(0xfffc);
regs.pc.h = r_mem->read(0xfffd);
//some registers are not fully reset by SNES
regs.acc_8b = true;
regs.idx_8b = true;
//note: some registers are not fully reset by SNES
regs.x.h = 0x00;
regs.y.h = 0x00;
regs.s.h = 0x01;

View File

@ -35,6 +35,8 @@ struct {
bool hdmainit_triggered;
bool hdma_triggered;
uint16 irq_delay;
int16 nmi_read_pos, nmi_line_pos;
bool nmi_read, nmi_line, nmi_transition;
bool nmi_pending;
@ -50,7 +52,8 @@ struct {
//$4016-$4017
bool joypad_strobe_latch;
uint8 joypad1_read_pos, joypad2_read_pos;
uint32 joypad1_bits;
uint32 joypad2_bits;
//$4200
bool nmi_enabled;
@ -73,6 +76,12 @@ struct {
//$4214-$4217
uint16 r4214;
uint16 r4216;
//$4218-$421f
uint8 joy1l, joy1h;
uint8 joy2l, joy2h;
uint8 joy3l, joy3h;
uint8 joy4l, joy4h;
} status;
void run();

View File

@ -1,3 +1,9 @@
void sCPU::set_irq_delay(uint clocks) {
if(status.irq_delay < clocks) {
status.irq_delay = clocks;
}
}
void sCPU::update_interrupts() {
if(status.vcounter == (!overscan() ? 225 : 240)) {
status.nmi_read_pos = 2;

View File

@ -0,0 +1,71 @@
void sCPU::run_manual_joypad_poll() {
snes->poll_input(SNES::DEV_JOYPAD1);
snes->poll_input(SNES::DEV_JOYPAD2);
status.joypad1_bits = uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_B)) << 0;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_Y)) << 1;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_SELECT)) << 2;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_START)) << 3;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_UP)) << 4;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_DOWN)) << 5;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_LEFT)) << 6;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_RIGHT)) << 7;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_A)) << 8;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_X)) << 9;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_L)) << 10;
status.joypad1_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD1, SNES::JOYPAD_R)) << 11;
status.joypad1_bits |= ~0xffff;
status.joypad2_bits = uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_B)) << 0;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_Y)) << 1;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_SELECT)) << 2;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_START)) << 3;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_UP)) << 4;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_DOWN)) << 5;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_LEFT)) << 6;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_RIGHT)) << 7;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_A)) << 8;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_X)) << 9;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_L)) << 10;
status.joypad2_bits |= uint8(snes->get_input_status(SNES::DEV_JOYPAD2, SNES::JOYPAD_R)) << 11;
status.joypad2_bits |= ~0xffff;
}
/*****
* The joypad contains a small bit shifter that has 16 bits.
* Reading from 4016 reads one bit from this buffer, then moves
* the buffer left one, and adds a '1' to the rightmost bit.
* Writing a one to $4016 will fill the buffer with the current
* joypad button states, and lock the bit shifter at position
* zero. All reads will be the first buffer state, or 'B'.
* A zero must be written back to $4016 to unlock the buffer,
* so that reads will increment the bit shifting position.
*****/
void sCPU::run_auto_joypad_poll() {
run_manual_joypad_poll();
uint16 joy1 = 0x0000, joy2 = 0x0000;
for(int i = 0; i < 16; i++) {
joy1 |= (!!(status.joypad1_bits & (0x8000 >> i))) << i;
joy2 |= (!!(status.joypad2_bits & (0x8000 >> i))) << i;
}
status.joy1l = joy1;
status.joy1h = joy1 >> 8;
status.joy2l = joy2;
status.joy2h = joy2 >> 8;
status.joy3l = 0x00;
status.joy3h = 0x00;
status.joy4l = 0x00;
status.joy4h = 0x00;
status.joypad1_bits >>= 16;
status.joypad2_bits >>= 16;
status.joypad1_bits |= ~0xffff;
status.joypad2_bits |= ~0xffff;
}

View File

@ -3,6 +3,7 @@
status.interlace == false && status.interlace_field == 1)
#include "irq.cpp"
#include "joypad.cpp"
uint16 sCPU::vcounter() { return status.vcounter; }
uint16 sCPU::hcycles() { return status.hclock; }
@ -33,6 +34,14 @@ uint16 sCPU::hcounter() {
}
void sCPU::add_clocks(uint clocks) {
if(status.irq_delay) {
if(status.irq_delay >= clocks) {
status.irq_delay -= clocks;
} else {
status.irq_delay = 0;
}
}
status.clocks_executed += clocks;
poll_interrupts(clocks);
@ -73,16 +82,8 @@ void sCPU::scanline() {
update_interrupts();
if(status.vcounter == (!overscan() ? 227 : 242) && status.auto_joypad_poll == true) {
snes->poll_input(SNES::DEV_JOYPAD1);
snes->poll_input(SNES::DEV_JOYPAD2);
//When the SNES auto-polls the joypads, it writes 1, then 0 to
//$4016, then reads from each 16 times to get the joypad state
//information. As a result, the joypad read positions are set
//to 16 after such a poll. Position 16 is the controller
//connected status bit.
status.joypad1_read_pos = 16;
status.joypad2_read_pos = 16;
if(status.auto_joypad_poll == true && status.vcounter == (!overscan() ? 227 : 242)) {
run_auto_joypad_poll();
}
}
@ -104,18 +105,11 @@ void sCPU::frame() {
}
/*****
* opcode_edge()
* precycle_edge()
*
* Used for DMA/HDMA bus synchronization
*****/
void sCPU::opcode_edge() {
#ifdef FAVOR_SPEED
co_return();
#endif
if(status.line_rendered == false) {
if(status.hclock >= 128) {
status.line_rendered = true;
r_ppu->render_scanline();
}
}
void sCPU::precycle_edge() {
}
/*****
@ -124,6 +118,13 @@ void sCPU::opcode_edge() {
* Used to test for HDMA, which can trigger on the edge of every opcode cycle.
*****/
void sCPU::cycle_edge() {
if(status.line_rendered == false) {
if(status.hclock >= 128) {
status.line_rendered = true;
r_ppu->render_scanline();
}
}
if(status.hdmainit_triggered == false) {
if(status.hclock >= 12 || status.vcounter) {
status.hdmainit_triggered = true;
@ -144,8 +145,13 @@ void sCPU::cycle_edge() {
*
* Used to test for NMI/IRQ, which can trigger on the edge of every opcode.
* Test one cycle early to simulate two-stage pipeline of x816 CPU.
*
* status.irq_delay is used to simulate hardware delay before interrupts can
* trigger during certain events (immediately after DMA, writes to $4200, etc)
*****/
void sCPU::last_cycle() {
if(status.irq_delay)return;
status.nmi_pending |= nmi_test();
status.irq_pending |= irq_test();
@ -164,6 +170,9 @@ uint32 r = status.clocks_executed;
return r;
}
void sCPU::timing_power() {
}
void sCPU::timing_reset() {
status.clock_count = 0;
status.clocks_executed = 0;
@ -185,6 +194,8 @@ void sCPU::timing_reset() {
status.hdmainit_triggered = false;
status.hdma_triggered = false;
status.irq_delay = 0;
status.nmi_read = 1;
status.nmi_line = 1;
status.nmi_transition = 0;

View File

@ -14,13 +14,16 @@
void scanline();
void frame();
void opcode_edge();
void precycle_edge();
void cycle_edge();
void last_cycle();
uint32 clocks_executed();
void timing_power();
void timing_reset();
//irq.cpp
void set_irq_delay(uint clocks);
void update_interrupts();
void poll_interrupts(int clocks);
bool nmi_read_pos_match(uint offset);
@ -28,3 +31,7 @@
bool irq_pos_valid();
bool nmi_test();
bool irq_test();
//joypad.cpp
void run_manual_joypad_poll();
void run_auto_joypad_poll();

View File

@ -1,27 +1,31 @@
/*
libbase : version 0.08 ~byuu (07/08/06)
libbase : version 0.08a ~byuu (07/14/06)
*/
#ifndef __LIBBASE
#define __LIBBASE
#ifdef _MSC_VER
#if defined(_MSC_VER)
//disable libc deprecation warnings in MSVC 2k5+
#pragma warning(disable:4996)
#pragma warning(disable:4996)
#endif
/*****
* inline expansion
*****/
#ifdef _MSC_VER
#if defined(_MSC_VER)
#define noinline __declspec(noinline)
#define inline inline
#define forceinline __forceinline
#else
#define fastcall __fastcall
#elif defined(__GNUC__)
#define noinline
#define inline inline
#define forceinline inline
#define fastcall __attribute__((fastcall))
#else
#error "unsupported compiler"
#endif
#include <stdio.h>
@ -32,11 +36,11 @@
#include <math.h>
#ifndef FALSE
#define FALSE 0
#define FALSE 0
#endif
#ifndef TRUE
#define TRUE !FALSE
#define TRUE !FALSE
#endif
#define SafeFree(__n) if(__n) { free(__n); __n = 0; }
@ -289,7 +293,7 @@ const uint32 crc32_table[256] = {
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
};
inline uint32 crc32_adjust(uint32 crc32, uint32 input) {
inline uint32 crc32_adjust(uint32 crc32, uint8 input) {
return ((crc32 >> 8) & 0x00ffffff) ^ crc32_table[(crc32 ^ input) & 0xff];
}

View File

@ -1,625 +0,0 @@
#include "libbase.h"
#include "libvector.h"
#include "libbpf.h"
void BPF::Handle::seek(uint32 new_pos) {
if(pos == new_pos)return;
pos = new_pos;
if(mode == MODE_FILE) {
fseek(handle, new_pos, SEEK_SET);
}
}
void BPF::Handle::write(uint8 x) {
if(mode == MODE_MEMORY) {
data[pos] = x;
} else {
fputc(x, handle);
}
if(++pos > size)size = pos;
crc32 = crc32_adjust(crc32, x);
}
uint8 BPF::Handle::read() {
uint8 r;
if(pos >= size) {
return 0x00;
} else if(mode == MODE_MEMORY) {
r = data[pos];
} else {
r = fgetc(handle);
}
pos++;
crc32 = crc32_adjust(crc32, r);
return r;
}
uint32 BPF::Handle::calc_crc32() {
crc32 = 0xffffffff;
seek(0);
for(uint32 i = 0; i < size; i++) {
read();
}
seek(0);
crc32 = ~crc32;
return crc32;
}
bool BPF::Handle::open(uint8 _access, uint32 _size, uint8 *_data) {
close();
mode = MODE_MEMORY;
access = _access;
pos = 0;
size = _size;
crc32 = 0xffffffff;
if(access == ACCESS_READ) {
data.resize(_size);
data.copy(_data, _size);
} else {
data.resize(_size);
data.clear();
}
return true;
}
bool BPF::Handle::open(uint8 _access, const char *fn) {
close();
mode = MODE_FILE;
access = _access;
pos = 0;
crc32 = 0xffffffff;
if(access == ACCESS_READ) {
handle = fopen(fn, "rb");
if(!handle)return false;
size = fsize(handle);
} else if(access == ACCESS_WRITE) {
handle = fopen(fn, "wb");
if(!handle)return false;
size = 0;
}
return true;
}
bool BPF::Handle::load(const char *fn) {
close();
FILE *fp = fopen(fn, "rb");
if(!fp)return false;
size = fsize(fp);
uint8 *buffer = (uint8*)malloc(size);
memset(buffer, 0, size);
fread(buffer, 1, size, fp);
fclose(fp);
return open(ACCESS_READ, size, buffer);
}
bool BPF::Handle::save(const char *fn) {
if(mode != MODE_MEMORY)return false;
FILE *fp = fopen(fn, "wb");
if(!fp)return false;
fwrite(data.handle(), 1, size, fp);
fclose(fp);
return true;
}
void BPF::Handle::close() {
if(mode == MODE_MEMORY) {
data.release();
} else if(mode == MODE_FILE) {
if(handle) {
fclose(handle);
handle = 0;
}
}
}
uint8 *BPF::load(const char *fn, uint32 &size) {
FILE *fp = fopen(fn, "rb");
if(!fp)return 0;
size = fsize(fp);
uint8 *buffer = (uint8*)malloc(size);
fread(buffer, 1, size, fp);
fclose(fp);
fp = 0;
return buffer;
}
void BPF::save(const char *fn, uint8 *data, uint32 size) {
FILE *fp = fopen(fn, "wb");
if(!fp)return;
fwrite(data, 1, size, fp);
fclose(fp);
fp = 0;
}
void BPF::write_ptr(uint32 ptr) {
if(ptr <= 0xef) {
patch.write(ptr);
return;
}
ptr -= 0xf0;
if(ptr <= 0xffff) {
patch.write(0xf0);
patch.write(ptr);
patch.write(ptr >> 8);
return;
}
ptr -= 0x10000;
if(ptr <= 0xffffff) {
patch.write(0xf1);
patch.write(ptr);
patch.write(ptr >> 8);
patch.write(ptr >> 16);
return;
}
ptr -= 0x1000000;
patch.write(0xf2);
patch.write(ptr);
patch.write(ptr >> 8);
patch.write(ptr >> 16);
patch.write(ptr >> 24);
}
uint32 BPF::read_ptr() {
uint32 len = patch.read();
if(len <= 0xef) {
return len;
}
len &= 0x0f;
uint32 ptr = 0;
for(int i = 0; i < (len + 2); i++) {
ptr |= patch.read() << (i << 3);
}
ptr += 0xf0;
if(len >= 1)ptr += 0x10000;
if(len >= 2)ptr += 0x1000000;
return ptr;
}
void BPF::create_patch_binary() {
original.seek(0);
modified.seek(0);
uint32 last_ptr = 0, rle_count, last_out, rep_count;
for(uint32 i = 0; i < info.size_max;) {
uint8 r = original.read() ^ modified.read();
i++;
if(r == 0x00)continue;
//ptr
write_ptr((i - 1) - last_ptr);
//data
patch.write(r);
last_out = r;
rep_count = 0;
do {
r = original.read() ^ modified.read();
i++;
patch.write(r);
if(last_out == r) {
if(++rep_count == 2) {
rle_count = 0;
do {
r = original.read() ^ modified.read();
i++;
if(r != last_out || r == 0x00)break;
rle_count++;
} while(i < info.size_max);
write_ptr(rle_count);
if(i < info.size_max)patch.write(r);
rep_count = 0;
}
} else {
rep_count = 0;
}
last_out = r;
if(r == 0x00)break;
} while(i < info.size_max);
last_ptr = i;
}
}
bool BPF::create_patch(uint32 format, const char *fn) {
patch.open(ACCESS_WRITE, fn);
//header
patch.write('b');
patch.write('p');
patch.write('f');
patch.write(0x00);
//version (high-byte = major, low-byte = minor)
patch.write(0x00);
patch.write(0x01);
//bytes per pointer
info.size_max = (original.size >= modified.size) ? original.size : modified.size;
info.size_min = (original.size >= modified.size) ? modified.size : original.size;
if(info.size_max <= 0xff) {
info.ptr_size = 1;
} else if(info.size_max <= 0xffff) {
info.ptr_size = 2;
} else if(info.size_max <= 0xffffff) {
info.ptr_size = 3;
} else {
info.ptr_size = 4;
}
patch.write(info.ptr_size);
patch.write(info.ptr_size >> 8);
//format
patch.write(format);
patch.write(format >> 8);
patch.write(format >> 16);
patch.write(format >> 24);
//flags
uint32 flags = 0;
patch.write(flags);
patch.write(flags >> 8);
patch.write(flags >> 16);
patch.write(flags >> 24);
//original size
for(int i = 0; i < info.ptr_size; i++) {
patch.write(original.size >> (i << 3));
}
//modified size
for(int i = 0; i < info.ptr_size; i++) {
patch.write(modified.size >> (i << 3));
}
//patch data offset (currently unused)
uint32 pos = patch.pos + 4;
for(int i = 0; i < 4; i++) {
patch.write(pos >> (i << 3));
}
create_patch_binary();
//write crc32 of original file
for(int i = 0; i < 4; i++) {
patch.write(~original.crc32 >> (i << 3));
}
//write crc32 of modified file
for(int i = 0; i < 4; i++) {
patch.write(~modified.crc32 >> (i << 3));
}
uint32 patch_crc32 = patch.crc32;
//write crc32 of patch file
for(int i = 0; i < 4; i++) {
patch.write(~patch_crc32 >> (i << 3));
}
patch.close();
return true;
}
void BPF::apply_patch_binary() {
//copy old data info output buffer
output.seek(0);
input.seek(0);
for(uint32 z = 0; z < output.size; z++) {
output.write(input.read());
}
output.seek(0);
input.seek(0);
patch.seek(info.patch_start);
//the below routine may modify output.size if the input
//size is larger, so save the correct output size...
uint32 start_size = output.size;
//subtract 12 to ignore crc32 for original, modified, and patch files
uint32 rle_count, last_in, rep_count;
for(; patch.pos < (patch.size - 12);) {
//ptr
uint32 ptr = read_ptr();
//data
output.seek(output.pos + ptr);
input.seek(input.pos + ptr);
last_in = 0;
rep_count = 0;
do {
uint8 r = patch.read();
output.write(r ^ input.read());
if(r == last_in) {
if(++rep_count == 2) {
rle_count = read_ptr();
while(rle_count--) {
output.write(r ^ input.read());
}
rep_count = 0;
}
} else {
rep_count = 0;
}
last_in = r;
if(r == 0x00)break;
} while(patch.pos < (patch.size - 12));
}
//...and restore it when finished patching
output.size = start_size;
}
bool BPF::apply_patch() {
//verify patch is large enough to be a valid patchfile
if(patch.size < 34)return false;
patch.seek(INDEX_SIG);
//verify signature
if(patch.read() != 'b')return false;
if(patch.read() != 'p')return false;
if(patch.read() != 'f')return false;
if(patch.read() != 0x00)return false;
//read pointer size
patch.seek(INDEX_PTRSIZE);
info.ptr_size = patch.read();
info.ptr_size |= patch.read() << 8;
//read flags
uint32 flags;
patch.seek(INDEX_FLAGS);
flags = patch.read();
flags |= patch.read() << 8;
flags |= patch.read() << 16;
flags |= patch.read() << 24;
uint32 sx = 0, sy = 0;
patch.seek(INDEX_VARIABLE);
for(int i = 0; i < info.ptr_size; i++) {
sx |= patch.read() << (i << 3);
}
for(int i = 0; i < info.ptr_size; i++) {
sy |= patch.read() << (i << 3);
}
uint32 cx = 0, cy = 0, cp = 0;
patch.seek(patch.size - 12);
for(int i = 0; i < 4; i++) {
cx |= patch.read() << (i << 3);
}
for(int i = 0; i < 4; i++) {
cy |= patch.read() << (i << 3);
}
for(int i = 0; i < 4; i++) {
cp |= patch.read() << (i << 3);
}
input.calc_crc32();
//skip the stored patch crc32 when calculating
patch.size -= 4;
patch.calc_crc32();
patch.size += 4;
//validate patch crc32
if(patch.crc32 != cp) {
return false;
}
//validate input crc32 + size
bool input_num = 0;
if(input.crc32 == cx && input.size == sx) {
output.open(ACCESS_WRITE, sy);
input_num = 0;
} else if(input.crc32 == cy && input.size == sy) {
output.open(ACCESS_WRITE, sx);
input_num = 1;
} else {
return false;
}
patch.seek(INDEX_FORMAT);
info.format = 0;
for(int i = 0; i < 4; i++) {
info.format |= patch.read() << (i << 3);
}
info.patch_start = 0;
patch.seek(INDEX_VARIABLE + info.ptr_size * 2);
for(int i = 0; i < 4; i++) {
info.patch_start |= patch.read() << (i << 3);
}
apply_patch_binary();
output.calc_crc32();
return (output.crc32 == ((input_num == 0) ? cy : cx));
}
//main library interface functions
bool BPF::create_patch(uint32 format, const char *fn_patch, const char *fn_x, const char *fn_y) {
uint32 size_x = fsize(fn_x);
uint32 size_y = fsize(fn_y);
bool lim_x = (size_x >= settings.memory_limit);
bool lim_y = (size_y >= settings.memory_limit);
switch(format) {
case FORMAT_BINARY: {
if(lim_x == false) {
original.load(fn_x);
} else {
original.open(ACCESS_READ, fn_x);
}
if(lim_y == false) {
modified.load(fn_y);
} else {
modified.open(ACCESS_READ, fn_y);
}
} break;
case FORMAT_SNES: {
if(lim_x == true || lim_y == true) {
//files must be loaded into memory to manipulate, but
//one or more files exceed the memory limit setting
return false;
}
uint32 size;
uint8 *data;
//remove header, if it exists
data = load(fn_x, size);
if((size & 0x1fff) == 0x0200) {
original.open(ACCESS_READ, size - 512, data + 512);
} else {
original.open(ACCESS_READ, size, data);
}
SafeFree(data);
//remove header, if it exists
data = load(fn_y, size);
if((size & 0x1fff) == 0x0200) {
modified.open(ACCESS_READ, size - 512, data + 512);
} else {
modified.open(ACCESS_READ, size, data);
}
SafeFree(data);
} break;
}
bool result = create_patch(format, fn_patch);
original.close();
modified.close();
return result;
}
bool BPF::apply_patch(const char *fn_patch, const char *fn_input) {
uint32 size_p = fsize(fn_patch);
uint32 size_i = fsize(fn_input);
bool lim_p = (size_p >= settings.memory_limit);
bool lim_i = (size_i >= settings.memory_limit);
if(lim_p == false) {
patch.load(fn_patch);
} else {
patch.open(ACCESS_READ, fn_patch);
}
patch.seek(INDEX_FORMAT);
uint32 format;
format = patch.read();
format |= patch.read() << 8;
format |= patch.read() << 16;
format |= patch.read() << 24;
patch.seek(0);
switch(format) {
case FORMAT_BINARY: {
if(lim_i == false) {
input.load(fn_input);
} else {
input.open(ACCESS_READ, fn_input);
}
} break;
case FORMAT_SNES: {
if(lim_i == true) {
//file too large to load into memory?
patch.close();
return false;
}
uint32 size;
uint8 *data = load(fn_input, size);
//remove header, if it exists
if((size & 0x1fff) == 0x0200) {
input.open(ACCESS_READ, size - 512, data + 512);
} else {
input.open(ACCESS_READ, size, data);
}
SafeFree(data);
} break;
}
bool result = apply_patch();
patch.close();
input.close();
return result;
}
bool BPF::apply_patch(uint32 s_patch, uint8 *p_patch, uint32 s_input, uint8 *p_input) {
patch.open(ACCESS_READ, s_patch, p_patch);
patch.seek(INDEX_FORMAT);
uint32 format;
format = patch.read();
format |= patch.read() << 8;
format |= patch.read() << 16;
format |= patch.read() << 24;
patch.seek(0);
switch(format) {
case FORMAT_BINARY: {
input.open(ACCESS_READ, s_input, p_input);
} break;
case FORMAT_SNES: {
//remove header, if it exists
if((s_input & 0x1fff) == 0x0200) {
input.open(ACCESS_READ, s_input - 512, p_input + 512);
} else {
input.open(ACCESS_READ, s_input, p_input);
}
} break;
}
bool result = apply_patch();
patch.close();
input.close();
return result;
}
uint8 *BPF::get_output_handle(uint32 &size) {
size = output.size;
return (uint8*)output.data.handle();
}
void BPF::save_output(const char *fn) {
output.save(fn);
}
void BPF::clear_settings() {
settings.memory_limit = (16 * 1024 * 1024) + 4096;
settings.insert_data.enabled = false;
settings.insert_data.mode = 0;
settings.insert_data.handle = 0;
settings.insert_data.data = 0;
settings.insert_data.size = 0;
strcpy(settings.insert_data.fn, "");
}
BPF::BPF() {
clear_settings();
original.set_parent(this);
modified.set_parent(this);
output.set_parent(this);
input.set_parent(this);
patch.set_parent(this);
}
BPF::~BPF() {
original.close();
modified.close();
output.close();
input.close();
patch.close();
}

View File

@ -1,104 +0,0 @@
/*
libbpf : version 0.01 ~byuu (12/18/05)
*/
#ifndef __LIBBPF
#define __LIBBPF
#include "libbase.h"
#include "libvector.h"
class BPF;
class BPF {
public:
enum {
//patch formats
FORMAT_BINARY = 0x0000,
FORMAT_SNES = 0x0001,
};
enum {
INDEX_SIG = 0x00, //4 bytes
INDEX_VERSION = 0x04, //2 bytes
INDEX_PTRSIZE = 0x06, //2 bytes
INDEX_FORMAT = 0x08, //4 bytes
INDEX_FLAGS = 0x0c, //4 bytes
INDEX_VARIABLE = 0x10, //variable data follows
};
enum { MODE_MEMORY, MODE_FILE };
enum { ACCESS_READ, ACCESS_WRITE };
struct Handle {
BPF *parent;
uint8 mode, access;
vector<uint8> data;
FILE *handle;
uint32 size, pos, crc32;
void seek(uint32 new_pos);
void write(uint8 x);
uint8 read();
uint32 calc_crc32();
bool open(uint8 _mode, uint32 size, uint8 *_data = 0);
bool open(uint8 _mode, const char *fn);
bool load(const char *fn);
bool save(const char *fn);
void close();
void set_parent(BPF *_bpf) { parent = _bpf; }
Handle() {
mode = 0; access = 0;
crc32 = 0; handle = 0;
size = 0; pos = 0;
}
} original, modified, output, input, patch;
struct {
uint32 memory_limit;
struct {
bool enabled;
uint8 mode;
char fn[4096];
FILE *handle;
uint8 *data;
uint32 size;
} insert_data;
} settings;
struct {
uint16 ptr_size;
uint32 size_min, size_max;
uint32 patch_start;
uint32 format;
} info;
uint8 *load(const char *fn, uint32 &size);
void save(const char *fn, uint8 *data, uint32 size);
void write_ptr(uint32 ptr);
uint32 read_ptr();
void create_patch_binary();
bool create_patch(uint32 format, const char *fn);
bool create_patch(uint32 format, const char *fn_patch, const char *fn_x, const char *fn_y);
void apply_patch_binary();
bool apply_patch();
bool apply_patch(const char *fn_patch, const char *fn_input);
bool apply_patch(uint32 s_patch, uint8 *p_patch, uint32 s_input, uint8 *p_input);
uint8 *get_output_handle(uint32 &size);
void save_output(const char *fn);
void clear_settings();
BPF();
~BPF();
};
#endif

View File

@ -5,11 +5,11 @@
typedef void (*thread_t);
typedef void (*thread_p)();
extern "C" void __fastcall co_init();
extern "C" void __fastcall co_term();
extern "C" thread_t __fastcall co_active();
extern "C" thread_t __fastcall co_create(thread_p coentry, unsigned int heapsize);
extern "C" void __fastcall co_delete(thread_t cothread);
extern "C" void __fastcall co_jump(thread_t cothread);
extern "C" void __fastcall co_call(thread_t cothread);
extern "C" void __fastcall co_return();
extern "C" void fastcall co_init();
extern "C" void fastcall co_term();
extern "C" thread_t fastcall co_active();
extern "C" thread_t fastcall co_create(thread_p coentry, unsigned int heapsize);
extern "C" void fastcall co_delete(thread_t cothread);
extern "C" void fastcall co_jump(thread_t cothread);
extern "C" void fastcall co_call(thread_t cothread);
extern "C" void fastcall co_return();

View File

@ -1,5 +1,5 @@
/*
libconfig : version 0.08 ~byuu (07/02/06)
libconfig : version 0.08a ~byuu (07/16/06)
*/
#ifndef __LIBCONFIG
@ -19,7 +19,7 @@ class Config;
// class T : public Setting { public: SettingOperators(T); } t;
// t = 0; // -> t.set(0);
#define SettingOperators(__name) \
template<typename T> inline __name &operator=(const T x) { set(T(x)); return *this; } \
template<typename T> inline __name &operator=(const T &x) { set(x); return *this; } \
void toggle() { data ^= 1; set(data); } \
__name(Config *_parent, char *_name, char *_desc, uint _data, uint _type) : \
Setting(_parent, _name, _desc, _data, _type) {} \
@ -60,14 +60,14 @@ substring char_data, char_def;
Setting(Config *_parent, char *_name, char *_desc, uint _data, uint _type);
Setting(Config *_parent, char *_name, char *_desc, char *_data);
template<typename T> inline operator T() { return T(get()); }
template<typename T> inline Setting &operator=(const T x) { set(T(x)); return *this; }
template<typename T> inline bool operator==(const T x) { return T(get()) == x; }
template<typename T> inline bool operator!=(const T x) { return T(get()) != x; }
template<typename T> inline bool operator>=(const T x) { return T(get()) >= x; }
template<typename T> inline bool operator> (const T x) { return T(get()) > x; }
template<typename T> inline bool operator<=(const T x) { return T(get()) <= x; }
template<typename T> inline bool operator< (const T x) { return T(get()) < x; }
template<typename T> inline operator T() { return (T)get(); }
template<typename T> inline Setting &operator=(const T &x) { set(x); return *this; }
template<typename T> inline bool operator==(const T &x) { return (T)get() == x; }
template<typename T> inline bool operator!=(const T &x) { return (T)get() != x; }
template<typename T> inline bool operator>=(const T &x) { return (T)get() >= x; }
template<typename T> inline bool operator> (const T &x) { return (T)get() > x; }
template<typename T> inline bool operator<=(const T &x) { return (T)get() <= x; }
template<typename T> inline bool operator< (const T &x) { return (T)get() < x; }
};
class Config {

49
src/lib/libfile.cpp Normal file
View File

@ -0,0 +1,49 @@
#include "libbase.h"
#include "libvector.h"
#include "libfile.h"
/*****
* c wrappers
*****/
void fread(file *s, uint8 *data, uint length) { s->read(data, length); }
uint8 fread(file *s) { return s->read(); }
uint8 fgetc(file *s) { return s->read(); }
void fwrite(file *s, uint8 *data, uint length) { s->write(data, length); }
void fwrite(file *s, uint8 data) { s->write(data); }
void fputc(file *s, uint8 data) { s->write(data); }
void fseek(file *s, uint offset, uint mode) { s->seek(offset, mode); }
uint foffset(file *s) { return s->offset(); }
uint ftell(file *s) { return s->offset(); }
uint fsize(file *s) { return s->size(); }
bool feof(file *s) { return s->eof(); }
bool fopen(file *s, const char *filename, uint mode) { return s->open(filename, mode); }
bool fopen(file *s) { return s->open(); }
bool fflush(file *s) { return s->flush(); }
bool fclose(file *s) { return s->close(); }
/*****
* c++ wrappers
*****/
void fread(file &s, uint8 *data, uint length) { s.read(data, length); }
uint8 fread(file &s) { return s.read(); }
uint8 fgetc(file &s) { return s.read(); }
void fwrite(file &s, uint8 *data, uint length) { s.write(data, length); }
void fwrite(file &s, uint8 data) { s.write(data); }
void fputc(file &s, uint8 data) { s.write(data); }
void fseek(file &s, uint offset, uint mode) { s.seek(offset, mode); }
uint foffset(file &s) { return s.offset(); }
uint ftell(file &s) { return s.offset(); }
uint fsize(file &s) { return s.size(); }
bool feof(file &s) { return s.eof(); }
bool fopen(file &s, const char *filename, uint mode) { return s.open(filename, mode); }
bool fopen(file &s) { return s.open(); }
bool fflush(file &s) { return s.flush(); }
bool fclose(file &s) { return s.close(); }

334
src/lib/libfile.h Normal file
View File

@ -0,0 +1,334 @@
/*
libfile : version 0.02 ~byuu (06/17/06)
*/
#ifndef __LIBFILE
#define __LIBFILE
/*****
* file base class
*****/
class file {
public:
enum { mode_read, mode_write, mode_readwrite, mode_writeread };
enum { seek_start, seek_end, seek_back, seek_forward };
virtual void read(uint8 *data, uint length) = 0;
virtual uint8 read() = 0;
virtual void write(uint8 *data, uint length) = 0;
virtual void write(uint8 data) = 0;
virtual void seek(uint offset, uint mode = seek_start) = 0;
virtual uint offset() = 0;
virtual uint size() = 0;
virtual bool eof() = 0;
virtual bool open(const char *filename, uint mode) = 0;
virtual bool open() = 0;
virtual bool flush() = 0;
virtual bool close() = 0;
};
/*****
* c wrappers
*****/
void fread(file *s, uint8 *data, uint length);
uint8 fread(file *s);
uint8 fgetc(file *s);
void fwrite(file *s, uint8 *data, uint length);
void fwrite(file *s, uint8 data);
void fputc(file *s, uint8 data);
void fseek(file *s, uint offset, uint mode = file::seek_start);
uint foffset(file *s);
uint ftell(file *s);
uint fsize(file *s);
bool feof(file *s);
bool fopen(file *s, const char *filename, uint mode);
bool fopen(file *s);
bool fflush(file *s);
bool fclose(file *s);
/*****
* c++ wrappers
*****/
void fread(file &s, uint8 *data, uint length);
uint8 fread(file &s);
uint8 fgetc(file &s);
void fwrite(file &s, uint8 *data, uint length);
void fwrite(file &s, uint8 data);
void fputc(file &s, uint8 data);
void fseek(file &s, uint offset, uint mode = file::seek_start);
uint foffset(file &s);
uint ftell(file &s);
uint fsize(file &s);
bool feof(file &s);
bool fopen(file &s, const char *filename, uint mode);
bool fopen(file &s);
bool fflush(file &s);
bool fclose(file &s);
/*****
* ramfile
*****/
class ramfile : public file {
private:
FILE *fp;
vector<uint8> filedata;
char filename[1024];
uint filepos;
uint filesize;
uint filemode;
bool fileopen;
public:
void read(uint8 *data, uint length) {
if(!fileopen || filemode == mode_write) { return; }
filedata.read(filepos, data, length);
filepos += length;
if(filepos > filesize)filepos = filesize;
}
uint8 read() {
if(!fileopen || filemode == mode_write) { return 0; }
uint8 r = filedata[filepos++];
if(filepos > filesize)filepos = filesize;
return r;
}
void write(uint8 *data, uint length) {
if(!fileopen || filemode == mode_read) { return; }
filedata.write(filepos, data, length);
filepos += length;
if(filepos > filesize)filesize = filepos;
}
void write(uint8 data) {
if(!fileopen || filemode == mode_read) { return; }
filedata[filepos++] = data;
if(filepos > filesize)filesize = filepos;
}
void seek(uint offset, uint mode = seek_start) {
if(!fileopen) { return; }
switch(mode) {
case seek_start: filepos = offset; break;
case seek_end: filepos = filesize - offset; break;
case seek_back: filepos -= offset; break;
case seek_forward: filepos += offset; break;
}
if(filemode == mode_read) {
if(filepos > filesize)filepos = filesize;
} else {
if(filepos > filesize)filesize = filepos;
}
}
uint offset() {
if(!fileopen) { return 0; }
return filepos;
}
uint size() {
if(!fileopen) { return 0; }
return filesize;
}
bool eof() {
if(!fileopen) { return true; }
return (filepos >= filesize);
}
bool open(const char *fn, uint mode) {
if(fileopen) { return false; }
strcpy(filename, fn);
filemode = mode;
switch(filemode) {
case mode_read:
case mode_readwrite:
fp = fopen(filename, "rb");
if(!fp) { return false; }
filesize = fsize(fp);
fread(filedata.handle(filesize), 1, filesize, fp);
fclose(fp);
break;
default:
filesize = 0;
break;
}
filepos = 0;
fileopen = true;
return true;
}
bool open() {
return fileopen;
}
bool flush() {
if(!fileopen) { return false; }
switch(filemode) {
case mode_readwrite:
case mode_write:
case mode_writeread:
fp = fopen(filename, "wb");
if(!fp) { return false; }
fwrite(filedata.handle(filesize), 1, filesize, fp);
fclose(fp);
break;
}
return true;
}
bool close() {
if(!fileopen) { return false; }
bool result = flush();
fileopen = false;
filedata.release();
return result;
}
ramfile() {
fileopen = false;
}
~ramfile() {
if(fileopen) { close(); }
}
};
/*****
* diskfile
*****/
class diskfile : public file {
private:
FILE *fp;
uint filemode;
public:
void read(uint8 *data, uint length) {
if(!fp || filemode == mode_write) { return; }
fread(data, 1, length, fp);
}
uint8 read() {
if(!fp || filemode == mode_write) { return 0; }
return fgetc(fp);
}
void write(uint8 *data, uint length) {
if(!fp || filemode == mode_read) { return; }
fwrite(data, 1, length, fp);
}
void write(uint8 data) {
if(!fp || filemode == mode_read) { return; }
fputc(data, fp);
}
void seek(uint offset, uint mode = seek_start) {
if(!fp) { return; }
switch(mode) {
default:
case seek_start: fseek(fp, offset, SEEK_SET); break;
case seek_end: fseek(fp, offset, SEEK_END); break;
case seek_back: fseek(fp, -offset, SEEK_CUR); break;
case seek_forward: fseek(fp, offset, SEEK_CUR); break;
}
}
uint offset() {
if(!fp) { return 0; }
return ftell(fp);
}
uint size() {
if(!fp) { return 0; }
uint pos = ftell(fp);
fseek(fp, 0, SEEK_END);
uint filesize = ftell(fp);
fseek(fp, pos, SEEK_SET);
return filesize;
}
bool eof() {
if(!fp) { return true; }
return feof(fp);
}
bool open(const char *filename, uint mode) {
if(fp) { return false; }
filemode = mode;
char m[8];
switch(filemode) {
default:
case mode_read: strcpy(m, "rb"); break;
case mode_write: strcpy(m, "wb"); break;
case mode_readwrite: strcpy(m, "rb+"); break;
case mode_writeread: strcpy(m, "wb+"); break;
}
fp = fopen(filename, m);
if(!fp) { return false; }
return true;
}
bool open() {
return (fp != 0);
}
bool flush() {
if(!fp) { return false; }
fflush(fp);
return true;
}
bool close() {
if(!fp) { return false; }
fclose(fp);
fp = 0;
return true;
}
diskfile() {
fp = 0;
}
~diskfile() {
if(fp) { fclose(fp); }
}
};
#endif

129
src/lib/libkeymap.h Normal file
View File

@ -0,0 +1,129 @@
/*
libkeymap : version 0.01 ~byuu (07/14/06)
*/
#ifndef __LIBKEYMAP
#define __LIBKEYMAP
class keymap {
public:
uint esc;
uint f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12;
uint print_screen, scroll_lock, pause;
uint tilde;
uint num_0, num_1, num_2, num_3, num_4;
uint num_5, num_6, num_7, num_8, num_9;
uint minus, plus, backspace;
uint ins, del, home, end, page_up, page_down;
uint a, b, c, d, e, f, g, h, i, j, k, l, m;
uint n, o, p, q, r, s, t, u, v, w, x, y, z;
uint lbracket, rbracket;
uint pipe, colon, quote, comma, period, question;
uint numpad_0, numpad_1, numpad_2, numpad_3, numpad_4;
uint numpad_5, numpad_6, numpad_7, numpad_8, numpad_9;
uint numpad_plus, numpad_minus, numpad_mul;
uint numpad_div, numpad_enter, numpad_point;
uint numlock, capslock;
uint up, down, left, right;
uint tab, enter, space;
uint lctrl, rctrl, lalt, ralt, lshift, rshift;
uint lwin, rwin, menu;
uint find(const char *key) {
#define match(n) if(!strcmp(#n, key))return n;
match(esc)
match(f1) match(f2) match(f3) match(f4) match(f5) match(f6)
match(f7) match(f8) match(f9) match(f10) match(f11) match(f12)
match(print_screen) match(scroll_lock) match(pause)
match(tilde)
match(num_0) match(num_1) match(num_2) match(num_3) match(num_4)
match(num_5) match(num_6) match(num_7) match(num_8) match(num_9)
match(minus) match(plus) match(backspace)
match(ins) match(del) match(home)
match(end) match(page_up) match(page_down)
match(a) match(b) match(c) match(d) match(e) match(f)
match(g) match(h) match(i) match(j) match(k) match(l)
match(m) match(n) match(o) match(p) match(q) match(r)
match(s) match(t) match(u) match(v) match(w) match(x)
match(y) match(z)
match(lbracket) match(rbracket)
match(pipe) match(colon) match(quote)
match(comma) match(period) match(question)
match(numpad_0) match(numpad_1) match(numpad_2) match(numpad_3)
match(numpad_4) match(numpad_5) match(numpad_6) match(numpad_7)
match(numpad_8) match(numpad_9)
match(numpad_plus) match(numpad_minus) match(numpad_mul)
match(numpad_div) match(numpad_enter) match(numpad_point)
match(numlock) match(capslock)
match(up) match(down) match(left) match(right)
match(tab) match(enter) match(space)
match(lctrl) match(rctrl) match(lalt)
match(ralt) match(lshift) match(rshift)
match(lwin) match(rwin) match(menu)
#undef match
}
const char *find(uint key) {
#define match(n) if(n == key)return #n;
match(esc)
match(f1) match(f2) match(f3) match(f4) match(f5) match(f6)
match(f7) match(f8) match(f9) match(f10) match(f11) match(f12)
match(print_screen) match(scroll_lock) match(pause)
match(tilde)
match(num_0) match(num_1) match(num_2) match(num_3) match(num_4)
match(num_5) match(num_6) match(num_7) match(num_8) match(num_9)
match(minus) match(plus) match(backspace)
match(ins) match(del) match(home)
match(end) match(page_up) match(page_down)
match(a) match(b) match(c) match(d) match(e) match(f)
match(g) match(h) match(i) match(j) match(k) match(l)
match(m) match(n) match(o) match(p) match(q) match(r)
match(s) match(t) match(u) match(v) match(w) match(x)
match(y) match(z)
match(lbracket) match(rbracket)
match(pipe) match(colon) match(quote)
match(comma) match(period) match(question)
match(numpad_0) match(numpad_1) match(numpad_2) match(numpad_3)
match(numpad_4) match(numpad_5) match(numpad_6) match(numpad_7)
match(numpad_8) match(numpad_9)
match(numpad_plus) match(numpad_minus) match(numpad_mul)
match(numpad_div) match(numpad_enter) match(numpad_point)
match(numlock) match(capslock)
match(up) match(down) match(left) match(right)
match(tab) match(enter) match(space)
match(lctrl) match(rctrl) match(lalt)
match(ralt) match(lshift) match(rshift)
match(lwin) match(rwin) match(menu)
#undef match
}
keymap() {
esc = 0;
f1 = f2 = f3 = f4 = f5 = f6 = 0;
f7 = f8 = f9 = f10 = f11 = f12 = 0;
print_screen = scroll_lock = pause = 0;
tilde = 0;
num_0 = num_1 = num_2 = num_3 = num_4 = 0;
num_5 = num_6 = num_7 = num_8 = num_9 = 0;
minus = plus = backspace = 0;
ins = del = home = end = page_up = page_down = 0;
a = b = c = d = e = f = g = h = i = 0;
j = k = l = m = n = o = p = q = r = 0;
s = t = u = v = w = x = y = z = 0;
lbracket = rbracket = 0;
pipe = colon = quote = comma = period = question = 0;
numpad_0 = numpad_1 = numpad_2 = numpad_3 = numpad_4 = 0;
numpad_5 = numpad_6 = numpad_7 = numpad_8 = numpad_9 = 0;
numpad_plus = numpad_minus = numpad_mul = 0;
numpad_div = numpad_enter = numpad_point = 0;
numlock = capslock = 0;
up = down = left = right = 0;
tab = enter = space = 0;
lctrl = rctrl = lalt = ralt = lshift = rshift = 0;
lwin = rwin = menu = 0;
}
};
#endif

View File

@ -523,6 +523,23 @@ substring &btoa(substring &str, uint num) {
return str;
}
bool strfread(substring &str, const char *filename) {
strcpy(str, "");
FILE *fp = fopen(filename, "rb");
if(!fp)return false;
uint size = fsize(fp);
char *fdata = (char*)malloc(size + 1);
fread(fdata, 1, size, fp);
fclose(fp);
fdata[size] = 0;
strcpy(str, fdata);
free(fdata);
return true;
}
#include "libstring_math.cpp"
#include "libstring_split.cpp"
#include "libstring_replace.cpp"

View File

@ -1,5 +1,5 @@
/*
libstring : version 0.11 ~byuu (07/02/06)
libstring : version 0.11b ~byuu (07/16/06)
*/
#ifndef __LIBSTRING
@ -141,11 +141,10 @@ substring &uhtoa(substring &str, uint num);
char *btoa(char *str, uint num);
substring &btoa(substring &str, uint num);
uint strmath(const char *in_str);
uint strmath(substring &in_str);
bool strfread(substring &str, const char *filename);
bool strmathentity(const char *str);
bool strmathentity(substring &str);
int strmath(const char *in_str);
int strmath(substring &in_str);
substring &replace(substring &str, const char *key, const char *token);
substring &replace(substring &str, const char *key, substring &token);
@ -166,9 +165,6 @@ class substring {
public:
char *s;
uint size;
//inline char* operator*() { return s; }
//inline operator char*() { return s; }
substring();
~substring();
};
@ -189,10 +185,8 @@ uint listcount, count;
void addto(uint num); //creates all needed strings to make list[num] valid
substring &str(uint num); //gets a substring reference, creating it + new strings if needed
//inline char* operator*() { return strptr(str(0)); }
//inline operator char*() { return str(0).s; }
inline operator substring&() { return str(0); }
template<typename T> inline substring& operator[](T i) { return str(i); }
inline operator substring&() { return str(0); }
template<typename T> inline substring& operator[](const T i) { return str(i); }
string();
~string();

View File

@ -1,179 +1,121 @@
#define STRMATH_ADD 1
#define STRMATH_SUB 2
#define STRMATH_MUL 3
#define STRMATH_DIV 4
#define STRMATH_MOD 5
#define STRMATH_AND 6
#define STRMATH_OR 7
#define STRMATH_XOR 8
#define STRMATH_SHL 9
#define STRMATH_SHR 10
/*
c-style Math Evaluator v1.0 (07/03/2006)
Algorithm: Recursive Descent Processor
Written by: gladius
Optimized by: gladius and byuu
Public Domain
*/
#define STRMATH_LINKED 64
#define STRMATHMODE_NEG 1
#define STRMATHMODE_NOT 2
#define __strunktonum() \
if (s1[0] == '0' && s1[1] == 'x')r = strhex(s1 + 2); \
else if(s1[0] == '0' && s1[1] == 'b')r = strbin(s1 + 2); \
else r = strdec(s1)
#define __strmath_setmode() \
if (str[i] == '-') { mode = STRMATHMODE_NEG; i++; } \
else if(str[i] == '~') { mode = STRMATHMODE_NOT; i++; } \
else if(str[i] == '+') { i++; } \
else mode=0
#define __strmath_modeset() \
if (mode == STRMATHMODE_NEG)r *= -1; \
else if(mode == STRMATHMODE_NOT)r =~ r
#define __strmath_set(__x) \
s1[z] = 0; \
z = 0; \
__strunktonum(); \
__strmath_modeset(); \
array[array_size++] = r; \
array_gate[array_size] = __x
/***************************************
strmath(str)
resolves all math entities from within
str, and returns numerical result
example: strmath("5+5")=10
***************************************/
uint p_strmath(const char *str) {
int i = 0, ssl = strlen(str);
uint r, array[128], array_size = 0, z = 0;
uint8 x, mode = 0;
uint8 array_gate[128];
char *s1;
if(!ssl)return 0;
s1 = (char*)malloc(ssl + 1);
__strmath_setmode();
while(i < ssl) {
x = str[i++];
if (x == '+') { __strmath_set(STRMATH_ADD); __strmath_setmode(); }
else if(x == '-') { __strmath_set(STRMATH_SUB); __strmath_setmode(); }
else if(x == '*') { __strmath_set(STRMATH_MUL); __strmath_setmode(); }
else if(x == '/') { __strmath_set(STRMATH_DIV); __strmath_setmode(); }
else if(x == '%') { __strmath_set(STRMATH_MOD); __strmath_setmode(); }
else if(x == '&') { __strmath_set(STRMATH_AND); __strmath_setmode(); }
else if(x == '|') { __strmath_set(STRMATH_OR ); __strmath_setmode(); }
else if(x == '^') { __strmath_set(STRMATH_XOR); __strmath_setmode(); }
else if(x == '<' && str[i] == '<') { __strmath_set(STRMATH_SHL); i++; __strmath_setmode(); }
else if(x == '>' && str[i] == '>') { __strmath_set(STRMATH_SHR); i++; __strmath_setmode(); }
else s1[z++] = x;
}
s1[z] = 0;
__strunktonum();
__strmath_modeset();
array[array_size++] = r;
free(s1);
for(i=1;i<array_size;i++) {
if (array_gate[i] == STRMATH_SHL) { array[i-1] <<= array[i]; array_gate[i] = STRMATH_LINKED; }
else if(array_gate[i] == STRMATH_SHR) { array[i-1] >>= array[i]; array_gate[i] = STRMATH_LINKED; }
}
for(i=1;i<array_size;i++) {
if (array_gate[i] == STRMATH_MUL) { array[i-1] *= array[i]; array_gate[i] = STRMATH_LINKED; }
else if(array_gate[i] == STRMATH_DIV) { array[i-1] /= array[i]; array_gate[i] = STRMATH_LINKED; }
}
r = array[0];
for(i=1;i<array_size;i++) {
if (array_gate[i] == STRMATH_ADD)r += array[i];
else if(array_gate[i] == STRMATH_SUB)r -= array[i];
else if(array_gate[i] == STRMATH_MOD)r %= array[i];
else if(array_gate[i] == STRMATH_AND)r &= array[i];
else if(array_gate[i] == STRMATH_OR )r |= array[i];
else if(array_gate[i] == STRMATH_XOR)r ^= array[i];
}
return r;
}
uint strmath(const char *in_str) {
uint r = 0;
uint pdepth = 0, cpdepth, maxpdepth = 0;
uint pstart, pend, spos;
int i, sc, sl = strlen(in_str);
char *str = (char*)malloc(sl + 1), *str0;
char *pstr;
char num[64];
strcpy(str, in_str);
for(i=0;i<sl;i++) {
if(str[i]=='(') {
pdepth++;
if(pdepth > maxpdepth)maxpdepth = pdepth;
} else if(str[i]==')') {
if(pdepth == 0) {
free(str);
return 0; //error! too many )'s
}
pdepth --;
#define maxlevel 12
int strmath_rdp(const char *&s, int level = 0) {
if(level == maxlevel) {
if(*s == '(') {
int result = strmath_rdp(++s, 0);
s++;
return result;
} else if(*s == '+') {
return +strmath_rdp(++s, maxlevel);
} else if(*s == '-') {
return -strmath_rdp(++s, maxlevel);
} else if(*s == '!') {
return !strmath_rdp(++s, maxlevel);
} else if(*s == '~') {
return ~strmath_rdp(++s, maxlevel);
} else if(*s >= '0' && *s <= '9') {
int num, len;
sscanf(s, "%d%n", &num, &len);
s += len;
return num;
}
}
if(pdepth != 0) {
free(str);
return 0; //error! unequal ('s to )'s
}
pdepth = maxpdepth;
while(pdepth) {
cpdepth = 0;
for(i=0;i<sl;) {
if(str[i] == '(')cpdepth++;
if(str[i] == ')')cpdepth--;
i++;
if(cpdepth == pdepth) {
pstart = i;
while(str[i] != ')')i++;
pend = i;
pstr = (char*)malloc(pend-pstart+1);
memcpy(pstr, str+pstart, pend-pstart);
pstr[pend-pstart]=0;
r = p_strmath(pstr);
free(pstr);
sprintf(num, "%d", r);
str0 = (char*)malloc(sl + strlen(num) + 1);
memcpy(str0, str, pstart - 1);
spos = pstart - 1;
memcpy(str0+spos, num, strlen(num));
spos += strlen(num);
sc = spos;
memcpy(str0+spos, str+pend+1, sl-pend-1);
spos += sl - pend - 1;
sl = spos;
str0[sl] = 0;
free(str);
str = str0;
cpdepth--;
i = sc;
}
int lhs = strmath_rdp(s, level + 1);
while(*s) {
int a = *s;
int b = *s ? *(s + 1) : 0;
switch(level) {
case 0:
if(a == '?')break;
return lhs;
case 1:
if(a == '|' && b == '|') { s++; break; }
return lhs;
case 2:
if(a == '^' && b == '^') { s++; break; }
return lhs;
case 3:
if(a == '&' && b == '&') { s++; break; }
return lhs;
case 4:
if(a == '|' && b != '|')break;
return lhs;
case 5:
if(a == '^' && b != '^')break;
return lhs;
case 6:
if(a == '&' && b != '&')break;
return lhs;
case 7:
if(a == '=' && b == '=') { s++; break; }
if(a == '!' && b == '=') { s++; break; }
return lhs;
case 8:
if(a == '<' && b == '=') { s++; break; }
if(a == '>' && b == '=') { s++; break; }
if(a == '<')break;
if(a == '>')break;
return lhs;
case 9:
if(a == '<' && b == '<') { s++; break; }
if(a == '>' && b == '>') { s++; break; }
return lhs;
case 10:
if(a == '+')break;
if(a == '-')break;
return lhs;
case 11:
if(a == '*')break;
if(a == '/')break;
if(a == '%')break;
return lhs;
}
if(a == '?') {
int tr = strmath_rdp(++s, level);
int fr = strmath_rdp(++s, level);
lhs = (lhs) ? tr : fr;
} else {
int rhs = strmath_rdp(++s, level + 1);
if (a == '|' && b == '|') lhs = (lhs || rhs);
else if(a == '^' && b == '^') lhs = (!lhs != !rhs);
else if(a == '&' && b == '&') lhs = (lhs && rhs);
else if(a == '|' && b != '|') lhs |= rhs;
else if(a == '^' && b != '^') lhs ^= rhs;
else if(a == '&' && b != '&') lhs &= rhs;
else if(a == '=' && b == '=') lhs = (lhs == rhs);
else if(a == '!' && b == '=') lhs = (lhs != rhs);
else if(a == '<' && b == '=') lhs = (lhs <= rhs);
else if(a == '>' && b == '=') lhs = (lhs >= rhs);
else if(a == '<' && b != '<') lhs = (lhs < rhs);
else if(a == '>' && b != '>') lhs = (lhs > rhs);
else if(a == '<' && b == '<') lhs <<= rhs;
else if(a == '>' && b == '>') lhs >>= rhs;
else if(a == '+') lhs += rhs;
else if(a == '-') lhs -= rhs;
else if(a == '*') lhs *= rhs;
else if(a == '/') lhs /= rhs;
else if(a == '%') lhs %= rhs;
}
pdepth--;
}
r = p_strmath(str);
free(str);
return r;
return lhs;
}
uint strmath(substring &in_str) { return strmath(strptr(in_str)); }
#undef maxlevel
bool strmathentity(const char *str) {
int i, ssl = strlen(str);
for(i=0;i<ssl;i++) {
if(str[i] == '+' || str[i] == '-' || str[i] == '*' || str[i] == '/' ||
str[i] == '%' || str[i] == '&' || str[i] == '|' || str[i] == '^' ||
(str[i] == '<' && str[i+1] == '<') || (str[i] == '>' && str[i+1] == '>'))return true;
}
return false;
int strmath(const char *s) {
return strmath_rdp(s);
}
bool strmathentity(substring &str) { return strmathentity(strptr(str)); }
#ifdef __LIBSTRING
int strmath(substring &s) {
return strmath(strptr(s));
}
#endif

View File

@ -1,5 +1,5 @@
/*
libvector : version 0.04 ~byuu (12/24/05)
libvector : version 0.04a ~byuu (06/15/05)
*/
#ifndef __LIBVECTOR
@ -41,40 +41,48 @@ public:
//used to free up memory used by vector, but without
//actually destroying the vector itself
void release() {
resize(16);
void release() { resize(16); }
T *handle(uint req_size = 0) {
if(req_size > size)resize(req_size);
return (T*)array;
}
T *handle() { return (T*)array; }
void copy(T *source, uint32 copy_size) {
if(copy_size > size) {
resize(copy_size);
copy_size = size;
}
memcpy(array, source, copy_size * sizeof(T));
void read(uint start, T *source, uint length) {
if(start + length > size)resize(start + length);
memcpy(array + start, source, length);
}
void clear() {
memset(array, 0, size * sizeof(T));
void read(T *source, uint length) { read(0, source, length); }
void write(uint start, T *dest, uint length) {
if(start + length > size)resize(start + length);
memcpy(dest, array + start, length);
}
void write(T *dest, uint length) { write(0, dest, length); }
void clear() { memset(array, 0, size * sizeof(T)); }
vector(int newsize, int newsizelimit) {
size = newsize;
sizelimit = newsizelimit;
array = (T*)calloc(size, sizeof(T));
array = (T*)malloc(size * sizeof(T));
clear();
}
vector(int newsize) {
size = newsize;
sizelimit = 1 << 24;
array = (T*)calloc(size, sizeof(T));
array = (T*)malloc(size * sizeof(T));
clear();
}
vector() {
size = 16;
sizelimit = 1 << 24;
array = (T*)calloc(size, sizeof(T));
array = (T*)malloc(size * sizeof(T));
clear();
}
~vector() {

View File

@ -1,72 +1,93 @@
#include "../../base.h"
#include "mapper/mapper.cpp"
#include "bmemory_rw.cpp"
#include "bmemory_mapper_generic.cpp"
void bMemBus::load_cart() {
if(rom_loaded == true)return;
uint8 *rom = cartridge.rom;
uint16 index = cartridge.cart.header_index;
dprintf("* Image Name : \"%s\"", cartridge.cart.name);
dprintf("* Region : %s", (cartridge.cart.region == Cartridge::NTSC) ? "NTSC" : "PAL");
dprintf("* Address Decoder : %0.2x", cartridge.cart.mapper);
dprintf("* SRAM Size : %dkb", cartridge.cart.sram_size / 1024);
char t[256];
strcpy(t, "");
if(cartridge.cart.srtc)strcat(t, "S-RTC, ");
if(cartridge.cart.sdd1)strcat(t, "S-DD1, ");
if(cartridge.cart.c4) strcat(t, "Cx4, ");
if(cartridge.cart.dsp1)strcat(t, "DSP-1, ");
if(cartridge.cart.dsp2)strcat(t, "DSP-2, ");
if(cartridge.cart.obc1)strcat(t, "OBC-1, ");
strrtrim(t, ", ");
dprintf("* Coprocessor(s) : %s", (strlen(t) == 0) ? "None" : t);
dprintf("* Reset:%0.4x NMI[n]:%0.4x IRQ[n]:%0.4x BRK[n]:%0.4x COP[n]:%0.4x",
read16(rom, index + 0x3c), //Reset
read16(rom, index + 0x2a), //NMI
read16(rom, index + 0x2e), //IRQ
read16(rom, index + 0x26), //BRK
read16(rom, index + 0x24) //COP
);
//BRK[e] should be $fff6, however emulation mode brk is technically not supported.
//this needs verification, but I believe brk jumps to IRQ[e] vector.
dprintf("* NMI[e]:%0.4x IRQ[e]:%0.4x BRK[e]:%0.4x COP[e]:%0.4x",
read16(rom, index + 0x3a), //NMI
read16(rom, index + 0x3e), //IRQ
read16(rom, index + 0x3e), //BRK
read16(rom, index + 0x34) //COP
);
dprintf("* CRC32 : %0.8x", cartridge.cart.crc32);
dprintf("");
cart_map_reset();
switch(cartridge.cart.mapper) {
switch(cartridge.info.mapper) {
case Cartridge::PCB:
if(!strcmp(cartridge.info.pcb, "SHVC-1A3B-01")) { cart_map_shvc_1a3b_13(); break; }
if(!strcmp(cartridge.info.pcb, "SHVC-1A3B-11")) { cart_map_shvc_1a3b_13(); break; }
if(!strcmp(cartridge.info.pcb, "SHVC-1A3B-12")) { cart_map_shvc_1a3b_13(); break; }
if(!strcmp(cartridge.info.pcb, "SHVC-1A3B-13")) { cart_map_shvc_1a3b_13(); break; }
if(!strcmp(cartridge.info.pcb, "SHVC-1A3B-20")) { cart_map_shvc_1a3b_20(); break; }
if(!strcmp(cartridge.info.pcb, "SHVC-1A3M-10")) { cart_map_shvc_1a3m_30(); break; }
if(!strcmp(cartridge.info.pcb, "SHVC-1A3M-20")) { cart_map_shvc_1a3m_30(); break; }
if(!strcmp(cartridge.info.pcb, "SHVC-1A3M-21")) { cart_map_shvc_1a3m_30(); break; }
if(!strcmp(cartridge.info.pcb, "SHVC-1A3M-30")) { cart_map_shvc_1a3m_30(); break; }
if(!strcmp(cartridge.info.pcb, "BSC-1A5M-01")) { cart_map_bsc_1a5m_01(); break; }
if(!strcmp(cartridge.info.pcb, "BSC-1A7M-01")) { cart_map_bsc_1a7m_01(); break; }
if(!strcmp(cartridge.info.pcb, "BSC-1A7M-10")) { cart_map_bsc_1a7m_10(); break; }
dprintf("* PCB mapper not found");
return;
case Cartridge::LOROM:
case Cartridge::HIROM:
case Cartridge::EXLOROM:
case Cartridge::EXHIROM:
cart_map_generic(cartridge.cart.mapper);
cart_map_generic(cartridge.info.mapper);
break;
default:
dprintf("* generic mapper not found");
return;
}
if(cartridge.cart.sdd1)cart_map_sdd1();
if(cartridge.cart.c4) cart_map_c4();
if(cartridge.cart.dsp1)cart_map_dsp1();
if(cartridge.cart.dsp2)cart_map_dsp2();
if(cartridge.cart.obc1)cart_map_obc1();
if(cartridge.info.sdd1)cart_map_sdd1();
if(cartridge.info.c4) cart_map_c4();
if(cartridge.info.dsp1)cart_map_dsp1();
if(cartridge.info.dsp2)cart_map_dsp2();
if(cartridge.info.obc1)cart_map_obc1();
cart_map_system();
if(cartridge.cart.region == Cartridge::NTSC) {
uint region = read(0xffd9) & 0x7f;
cartridge.info.region = (region == 0 || region == 1 || region == 13) ? Cartridge::NTSC : Cartridge::PAL;
if(cartridge.info.region == Cartridge::NTSC) {
snes->set_region(SNES::NTSC);
} else {
snes->set_region(SNES::PAL);
}
rom_loaded = true;
//print cartridge info to debug console
dprintf("* CRC32 : %0.8x", cartridge.info.crc32);
dprintf("* Name : \"%s\"", cartridge.info.name);
dprintf("* PCB : %s", cartridge.info.pcb);
dprintf("* ROM Size : %dmbit", cartridge.info.rom_size / 1024 / 1024 * 8);
dprintf("* RAM Size : %dkbit", cartridge.info.ram_size / 1024 * 8);
dprintf("* Region : %s", (cartridge.info.region == Cartridge::NTSC) ? "NTSC" : "PAL");
char t[256];
strcpy(t, "");
if(cartridge.info.srtc)strcat(t, "S-RTC, ");
if(cartridge.info.sdd1)strcat(t, "S-DD1, ");
if(cartridge.info.c4) strcat(t, "Cx4, ");
if(cartridge.info.dsp1)strcat(t, "DSP-1, ");
if(cartridge.info.dsp2)strcat(t, "DSP-2, ");
if(cartridge.info.obc1)strcat(t, "OBC-1, ");
strrtrim(t, ", ");
dprintf("* Coprocessor(s) : %s", (strlen(t) == 0) ? "None" : t);
dprintf("* Reset:%0.4x NMI[n]:%0.4x IRQ[n]:%0.4x BRK[n]:%0.4x COP[n]:%0.4x",
(read(0xfffc) << 0) | (read(0xfffd) << 8), //Reset
(read(0xffea) << 0) | (read(0xffeb) << 8), //NMI
(read(0xffee) << 0) | (read(0xffef) << 8), //IRQ
(read(0xffe6) << 0) | (read(0xffe7) << 8), //BRK
(read(0xffe4) << 0) | (read(0xffe5) << 8) //COP
);
//BRK[e] should be $fff6, however emulation mode brk is technically not supported.
//this needs verification, but I believe brk jumps to IRQ[e] vector.
dprintf("* NMI[e]:%0.4x IRQ[e]:%0.4x BRK[e]:%0.4x COP[e]:%0.4x",
(read(0xfffa) << 0) | (read(0xfffb) << 8), //NMI
(read(0xfffe) << 0) | (read(0xffff) << 8), //IRQ
(read(0xfffe) << 0) | (read(0xffff) << 8), //BRK
(read(0xfff4) << 0) | (read(0xfff5) << 8) //COP
);
dprintf("");
}
void bMemBus::unload_cart() {
@ -177,12 +198,12 @@ void bMemBus::cart_map_system() {
void bMemBus::power() {
cart_write_protect(true);
memset(wram, 0, 0x020000);
memset(wram, 0xff, 0x020000);
reset();
}
void bMemBus::reset() {
set_speed(false);
set_speed(0);
}
bMemBus::bMemBus() {

View File

@ -7,6 +7,8 @@ uint8 *page_handle[65536];
uint8 (bMemBus::*page_read [65536])(uint32 addr);
void (bMemBus::*page_write[65536])(uint32 addr, uint8 data);
#include "mapper/mapper.h"
enum { LOROM = 0x20, HIROM = 0x21, EXLOROM = 0x22, EXHIROM = 0x25 };
enum { TYPE_WRAM, TYPE_MMIO, TYPE_CART };

View File

@ -16,8 +16,8 @@
*****/
void bMemBus::cart_map_generic(uint type) {
uint32 P0_size, P1_size, ROM_mask, ROM_size, SRAM_size;
ROM_size = cartridge.cart.rom_size;
SRAM_size = cartridge.cart.sram_size;
ROM_size = cartridge.info.rom_size;
SRAM_size = cartridge.info.ram_size;
//calculate highest power of 2, which is the size of the first ROM chip
P0_size = 0x800000;
@ -64,7 +64,7 @@ uint32 P0_size, P1_size, ROM_mask, ROM_size, SRAM_size;
//LoROM SRAM region
//$[70-7f|f0-ff]:[0000-7fff]
//Note: WRAM is remapped over $[7e-7f]:[0000-ffff]
if((bank & 0x7f) >= 0x70 && (bank & 0x7f) <= 0x7f && (addr & 0x8000) == 0x0000) {
if(bank >= 0x70 && bank <= 0x7f && (addr & 0x8000) == 0x0000) {
if(SRAM_size == 0)continue;
if(type == Cartridge::LOROM || !(bank & 0x80)) {
@ -141,40 +141,48 @@ void bMemBus::cart_map_c4() {
}
void bMemBus::cart_map_dsp1() {
if(cartridge.cart.dsp1_mapper == Cartridge::DSP1_LOROM_1MB) {
//$[20-3f]:[8000-ffff]
if(cartridge.info.dsp1_mapper == Cartridge::DSP1_LOROM_1MB) {
//$[20-3f|a0-bf]:[8000-ffff]
for(uint bank = 0x20; bank <= 0x3f; bank++) {
for(uint page = 0x80; page <= 0xff; page++) {
page_read [(bank << 8) + page] = &bMemBus::read_dsp1;
page_write[(bank << 8) + page] = &bMemBus::write_dsp1;
page_read [0x0000 + (bank << 8) + page] = &bMemBus::read_dsp1;
page_read [0x8000 + (bank << 8) + page] = &bMemBus::read_dsp1;
page_write[0x0000 + (bank << 8) + page] = &bMemBus::write_dsp1;
page_write[0x8000 + (bank << 8) + page] = &bMemBus::write_dsp1;
}
}
} else if(cartridge.cart.dsp1_mapper == Cartridge::DSP1_LOROM_2MB) {
//$[60-6f]:[0000-7fff]
} else if(cartridge.info.dsp1_mapper == Cartridge::DSP1_LOROM_2MB) {
//$[60-6f|e0-ef]:[0000-7fff]
for(uint bank = 0x60; bank <= 0x6f; bank++) {
for(uint page = 0x00; page <= 0x7f; page++) {
page_read [(bank << 8) + page] = &bMemBus::read_dsp1;
page_write[(bank << 8) + page] = &bMemBus::write_dsp1;
page_read [0x0000 + (bank << 8) + page] = &bMemBus::read_dsp1;
page_read [0x8000 + (bank << 8) + page] = &bMemBus::read_dsp1;
page_write[0x0000 + (bank << 8) + page] = &bMemBus::write_dsp1;
page_write[0x8000 + (bank << 8) + page] = &bMemBus::write_dsp1;
}
}
} else if(cartridge.cart.dsp1_mapper == Cartridge::DSP1_HIROM) {
//$[00-1f]:[6000-7fff]
} else if(cartridge.info.dsp1_mapper == Cartridge::DSP1_HIROM) {
//$[00-1f|80-9f]:[6000-7fff]
for(uint bank = 0x00; bank <= 0x1f; bank++) {
for(uint page = 0x60; page <= 0x7f; page++) {
page_read [(bank << 8) + page] = &bMemBus::read_dsp1;
page_write[(bank << 8) + page] = &bMemBus::write_dsp1;
page_read [0x0000 + (bank << 8) + page] = &bMemBus::read_dsp1;
page_read [0x8000 + (bank << 8) + page] = &bMemBus::read_dsp1;
page_write[0x0000 + (bank << 8) + page] = &bMemBus::write_dsp1;
page_write[0x8000 + (bank << 8) + page] = &bMemBus::write_dsp1;
}
}
}
}
void bMemBus::cart_map_dsp2() {
//$[20-3f]:[6000-6fff|8000-bfff]
//$[20-3f|a0-bf]:[6000-6fff|8000-bfff]
for(uint bank = 0x20; bank <= 0x3f; bank++) {
for(uint page = 0x60; page <= 0xbf; page++) {
if(page >= 0x70 && page <= 0x7f)continue;
page_read [(bank << 8) + page] = &bMemBus::read_dsp2;
page_write[(bank << 8) + page] = &bMemBus::write_dsp2;
page_read [0x0000 + (bank << 8) + page] = &bMemBus::read_dsp2;
page_read [0x8000 + (bank << 8) + page] = &bMemBus::read_dsp2;
page_write[0x0000 + (bank << 8) + page] = &bMemBus::write_dsp2;
page_write[0x8000 + (bank << 8) + page] = &bMemBus::write_dsp2;
}
}
}

View File

@ -39,13 +39,13 @@ void bMemBus::write_ram(uint32 addr, uint8 data) {
//
uint8 bMemBus::read_sdd1(uint32 addr) {
addr = sdd1->offset(addr) % cartridge.cart.rom_size;
addr = sdd1->offset(addr) % cartridge.info.rom_size;
return cartridge.rom[addr];
}
void bMemBus::write_sdd1(uint32 addr, uint8 data) {
if(cart_write_protect_enabled == true)return;
addr = sdd1->offset(addr) % cartridge.cart.rom_size;
addr = sdd1->offset(addr) % cartridge.info.rom_size;
cartridge.rom[addr] = data;
}

View File

@ -0,0 +1,56 @@
void bMemBus::cart_map_range(
uint8 bank_lo, uint8 bank_hi,
uint8 page_lo, uint8 page_hi,
uint type, uint offset
) {
uint8 *data = 0;
uint size = 0;
uint index = 0;
switch(type) {
case MAP_ROM: {
data = cartridge.rom;
size = cartridge.info.rom_size;
} break;
case MAP_RAM: {
data = cartridge.sram;
size = cartridge.info.ram_size;
} break;
}
if(size) { index = (index + offset) % size; }
for(uint bank = bank_lo; bank <= bank_hi; bank++) {
for(uint page = page_lo; page <= page_hi; page++) {
uint16 n = (bank << 8) + page;
page_handle[n] = data + index;
if(size) { index = (index + 256) % size; }
switch(type) {
case MAP_ROM: {
page_read [n] = &bMemBus::read_rom;
page_write[n] = &bMemBus::write_rom;
} break;
case MAP_RAM: {
page_read [n] = &bMemBus::read_ram;
page_write[n] = &bMemBus::write_ram;
} break;
}
}
}
}
#define mapper(name) void bMemBus::cart_map_##name()
#define map cart_map_range
#include "mapper_pcb.cpp"
#undef cart_map_range
#undef mapper

View File

@ -0,0 +1,21 @@
enum {
MAP_ROM,
MAP_RAM,
MAP_BSX,
MAP_SDD1,
MAP_CX4,
MAP_DSP1,
MAP_DSP2,
MAP_OBC1,
};
void cart_map_range(uint8 bank_lo, uint8 bank_hi, uint8 page_lo, uint8 page_hi, uint type, uint offset = 0);
#define mapper(name) void cart_map_##name()
mapper(shvc_1a3b_13);
mapper(shvc_1a3b_20);
mapper(shvc_1a3m_30);
mapper(bsc_1a5m_01);
mapper(bsc_1a7m_01);
mapper(bsc_1a7m_10);
#undef mapper

View File

@ -0,0 +1,95 @@
//SHVC-1A3B-01
//SHVC-1A3B-11
//SHVC-1A3B-12
//SHVC-1A3B-13
//
//$[00-1f]:[8000-ffff] ROM P0
//$[70-7f]:[0000-ffff] RAM
//$[80-9f]:[8000-ffff] ROM P0
//$[f0-ff]:[0000-ffff] RAM
mapper(shvc_1a3b_13) {
map(0x00, 0x1f, 0x80, 0xff, MAP_ROM);
map(0x70, 0x7f, 0x00, 0xff, MAP_RAM);
map(0x80, 0x9f, 0x80, 0xff, MAP_ROM);
map(0xf0, 0xff, 0x00, 0xff, MAP_RAM);
}
//SHVC-1A3B-20
//
//$[00-7f]:[8000-ffff] ROM P0
//$[70-7f]:[0000-7fff] RAM
//$[80-ff]:[8000-ffff] ROM P0
//$[f0-ff]:[0000-7fff] RAM
mapper(shvc_1a3b_20) {
map(0x00, 0x7f, 0x80, 0xff, MAP_ROM);
map(0x70, 0x7f, 0x00, 0x7f, MAP_RAM);
map(0x80, 0xff, 0x80, 0xff, MAP_ROM);
map(0xf0, 0xff, 0x00, 0x7f, MAP_RAM);
}
//SHVC-1A3M-10
//SHVC-1A3M-20
//SHVC-1A3M-21
//SHVC-1A3M-30
//
//$[00-7f]:[8000-ffff]
//$[70-7f]:[0000-7fff]
//$[80-ff]:[8000-ffff]
//$[f0-ff]:[0000-7fff]
mapper(shvc_1a3m_30) {
map(0x00, 0x7f, 0x80, 0xff, MAP_ROM);
map(0x70, 0x7f, 0x00, 0x7f, MAP_RAM);
map(0x80, 0xff, 0x80, 0xff, MAP_ROM);
map(0xf0, 0xff, 0x00, 0x7f, MAP_RAM);
}
//unverified
//BSC-1A5M-01
//
//$[00-1f]:[8000-ffff] ROM P0
//$[20-3f]:[8000-ffff] ROM P1
//$[70-7f]:[0000-7fff] RAM
//$[80-9f]:[8000-ffff] ROM P2
//$[a0-bf]:[8000-ffff] ROM P1
//$[c0-ef]:[0000-ffff] BSX
mapper(bsc_1a5m_01) {
map(0x00, 0x1f, 0x80, 0xff, MAP_ROM, 0x000000);
map(0x20, 0x3f, 0x80, 0xff, MAP_ROM, 0x100000);
map(0x70, 0x7f, 0x00, 0x7f, MAP_RAM);
map(0x80, 0x9f, 0x80, 0xff, MAP_ROM, 0x200000);
map(0xa0, 0xbf, 0x80, 0xff, MAP_ROM, 0x100000);
}
//unverified
//BSC-1A7M-01
//
//$[00-1f]:[8000-ffff] ROM P0
//$[20-3f]:[8000-ffff] ROM P1
//$[70-7f]:[0000-7fff] RAM
//$[80-9f]:[8000-ffff] ROM P0
//$[a0-bf]:[8000-ffff] ROM P1
//$[c0-ef]:[0000-ffff] BSX
mapper(bsc_1a7m_01) {
map(0x00, 0x1f, 0x80, 0xff, MAP_ROM, 0x000000);
map(0x20, 0x3f, 0x80, 0xff, MAP_ROM, 0x100000);
map(0x70, 0x7f, 0x00, 0x7f, MAP_RAM);
map(0x80, 0x9f, 0x80, 0xff, MAP_ROM, 0x000000);
map(0xa0, 0xbf, 0x80, 0xff, MAP_ROM, 0x100000);
}
//unverified
//BSC-1A7M-10
//
//$[00-1f]:[8000-ffff] ROM P0
//$[20-3f]:[8000-ffff] ROM P1
//$[70-7f]:[0000-7fff] RAM
//$[80-9f]:[8000-ffff] ROM P2
//$[a0-bf]:[8000-ffff] ROM P1
//$[c0-ef]:[0000-ffff] BSX
mapper(bsc_1a7m_10) {
map(0x00, 0x1f, 0x80, 0xff, MAP_ROM, 0x000000);
map(0x20, 0x3f, 0x80, 0xff, MAP_ROM, 0x100000);
map(0x70, 0x7f, 0x00, 0x7f, MAP_RAM);
map(0x80, 0x9f, 0x80, 0xff, MAP_ROM, 0x200000);
map(0xa0, 0xbf, 0x80, 0xff, MAP_ROM, 0x100000);
}

View File

@ -10,21 +10,6 @@ void bPPU::scanline() {
line.interlace = r_cpu->interlace();
line.interlace_field = r_cpu->interlace_field();
//this should probably only be done once per frame (at the
//start of vblank), however it is currently done every scanline
//as an attempt to emulate FirstSprite+Y priority mode
if(regs.oam_priority == true) {
if((regs.oam_addr & 3) == 3) {
//FirstSprite+Y priority (untested)
regs.oam_firstsprite = (regs.oam_addr >> 2) + (line.y - 1);
} else {
regs.oam_firstsprite = (regs.oam_addr >> 2);
}
regs.oam_firstsprite &= 127;
} else {
regs.oam_firstsprite = 0;
}
if(line.y == 0) {
//RTO flag reset
regs.time_over = false;
@ -39,6 +24,13 @@ void bPPU::scanline() {
regs.mosaic_countdown = regs.mosaic_size + 1;
regs.mosaic_countdown--;
//OAM sprite priority rotation
if(regs.oam_priority == false) {
regs.oam_firstsprite = 0;
} else {
regs.oam_firstsprite = (regs.oam_addr >> 2) & 127;
}
} else {
for(int32 bg = BG1; bg <= BG4; bg++) {
if(!regs.mosaic_enabled[bg] || !regs.mosaic_countdown) {
@ -52,8 +44,7 @@ void bPPU::scanline() {
regs.mosaic_countdown--;
}
//TODO: line.y position needs to be verified
if(line.y == (r_cpu->overscan() ? 240 : 225) && regs.display_disabled == false) {
if(line.y == (!r_cpu->overscan() ? 225 : 240) && regs.display_disabled == false) {
//OAM address reset
regs.oam_addr = regs.oam_baseaddr << 1;
}
@ -72,9 +63,14 @@ void bPPU::scanline() {
}
void bPPU::render_scanline() {
#ifdef FAVOR_SPEED
//bypass RTO status flag calculations
if(status.render_output == false)return;
#endif
if(line.y > 0 && line.y < (r_cpu->overscan() ? 240 : 225)) {
render_line_oam_rto();
if(status.render_output == false)return;
render_line();
}
}

View File

@ -150,8 +150,8 @@ struct {
void cgram_write(uint16 addr, uint8 value);
uint16 get_vram_address();
bool vram_can_read();
bool vram_can_write(uint8 &value);
uint8 vram_mmio_read (uint16 addr);
void vram_mmio_write(uint16 addr, uint8 data);
void mmio_w2100(uint8 value); //INIDISP
void mmio_w2101(uint8 value); //OBSEL

View File

@ -8,17 +8,17 @@ uint16 bPPU::get_vram_address() {
uint16 addr;
addr = regs.vram_addr;
switch(regs.vram_mapping) {
case 0:break;
case 1:addr = (addr & 0xff00) | ((addr & 0x001f) << 3) | ((addr >> 5) & 7);break;
case 2:addr = (addr & 0xfe00) | ((addr & 0x003f) << 3) | ((addr >> 6) & 7);break;
case 3:addr = (addr & 0xfc00) | ((addr & 0x007f) << 3) | ((addr >> 7) & 7);break;
case 0: break;
case 1: addr = (addr & 0xff00) | ((addr & 0x001f) << 3) | ((addr >> 5) & 7); break;
case 2: addr = (addr & 0xfe00) | ((addr & 0x003f) << 3) | ((addr >> 6) & 7); break;
case 3: addr = (addr & 0xfc00) | ((addr & 0x007f) << 3) | ((addr >> 7) & 7); break;
}
return (addr << 1);
}
bool bPPU::vram_can_read() {
uint8 bPPU::vram_mmio_read(uint16 addr) {
if(regs.display_disabled == true) {
return true;
return vram_read(addr);
}
uint16 v = r_cpu->vcounter();
@ -26,39 +26,57 @@ uint16 hc = r_cpu->hcycles();
uint16 ls = (r_cpu->region_scanlines() >> 1) - 1;
if(r_cpu->interlace() && !r_cpu->interlace_field())ls++;
if(v == ls && hc == 1362)return false;
if(v < (!r_cpu->overscan() ? 224 : 239))return false;
if(v == (!r_cpu->overscan() ? 224 : 239)) {
if(hc == 1362)return true;
return false;
if(v == ls && hc == 1362) {
return 0x00;
}
return true;
if(v < (!r_cpu->overscan() ? 224 : 239)) {
return 0x00;
}
if(v == (!r_cpu->overscan() ? 224 : 239)) {
if(hc == 1362) {
return vram_read(addr);
}
return 0x00;
}
return vram_read(addr);
}
bool bPPU::vram_can_write(uint8 &value) {
void bPPU::vram_mmio_write(uint16 addr, uint8 data) {
if(regs.display_disabled == true) {
return true;
vram_write(addr, data);
return;
}
uint16 v = r_cpu->vcounter();
uint16 hc = r_cpu->hcycles();
if(v == 0) {
if(hc <= 4)return true;
if(hc == 6) { value = r_cpu->regs.mdr; return true; }
return false;
if(hc <= 4) {
vram_write(addr, data);
return;
}
if(hc == 6) {
vram_write(addr, r_cpu->regs.mdr);
return;
}
return;
}
if(v < (r_cpu->overscan() ? 240 : 225))return false;
if(v == (r_cpu->overscan() ? 240 : 225)) {
if(hc <= 4)return false;
return true;
if(v < (!r_cpu->overscan() ? 225 : 240)) {
return;
}
return true;
if(v == (!r_cpu->overscan() ? 225 : 240)) {
if(hc <= 4) {
return;
}
vram_write(addr, data);
return;
}
vram_write(addr, data);
}
//INIDISP
@ -78,6 +96,12 @@ void bPPU::mmio_w2101(uint8 value) {
void bPPU::mmio_w2102(uint8 value) {
regs.oam_baseaddr = (regs.oam_baseaddr & 0x100) | value;
regs.oam_addr = regs.oam_baseaddr << 1;
if(regs.oam_priority == false) {
regs.oam_firstsprite = 0;
} else {
regs.oam_firstsprite = (regs.oam_addr >> 2) & 127;
}
}
//OAMADDH
@ -85,24 +109,34 @@ void bPPU::mmio_w2103(uint8 value) {
regs.oam_priority = bool(value & 0x80);
regs.oam_baseaddr = ((value & 1) << 8) | (regs.oam_baseaddr & 0xff);
regs.oam_addr = regs.oam_baseaddr << 1;
if(regs.oam_priority == false) {
regs.oam_firstsprite = 0;
} else {
regs.oam_firstsprite = (regs.oam_addr >> 2) & 127;
}
}
//OAMDATA
void bPPU::mmio_w2104(uint8 value) {
if(regs.oam_addr >= 0x0200) {
//does this happen?
//if(!(regs.oam_addr & 1)) {
// regs.oam_latchdata = value;
//}
oam_write(regs.oam_addr, value);
} else if(!(regs.oam_addr & 1)) {
regs.oam_latchdata = value;
} else {
oam_write((regs.oam_addr & 0x01fe), regs.oam_latchdata);
oam_write((regs.oam_addr & 0x01fe) + 0, regs.oam_latchdata);
oam_write((regs.oam_addr & 0x01fe) + 1, value);
}
regs.oam_addr++;
regs.oam_addr &= 0x03ff;
if(!(regs.oam_addr & 1)) {
if(regs.oam_priority == false) {
regs.oam_firstsprite = 0;
} else {
regs.oam_firstsprite = (regs.oam_addr >> 2) & 127;
}
}
}
//BGMODE
@ -220,10 +254,10 @@ void bPPU::mmio_w2115(uint8 value) {
regs.vram_incmode = bool(value & 0x80);
regs.vram_mapping = (value >> 2) & 3;
switch(value & 3) {
case 0:regs.vram_incsize = 1;break;
case 1:regs.vram_incsize = 32;break;
case 2:regs.vram_incsize = 128;break;
case 3:regs.vram_incsize = 128;break;
case 0: regs.vram_incsize = 1; break;
case 1: regs.vram_incsize = 32; break;
case 2: regs.vram_incsize = 128; break;
case 3: regs.vram_incsize = 128; break;
}
}
@ -231,35 +265,25 @@ void bPPU::mmio_w2115(uint8 value) {
void bPPU::mmio_w2116(uint8 value) {
regs.vram_addr = (regs.vram_addr & 0xff00) | value;
uint16 addr = get_vram_address();
if(vram_can_read()) {
regs.vram_readbuffer = vram_read(addr);
regs.vram_readbuffer |= vram_read(addr + 1) << 8;
} else {
regs.vram_readbuffer = 0x0000;
}
regs.vram_readbuffer = vram_mmio_read(addr + 0);
regs.vram_readbuffer |= vram_mmio_read(addr + 1) << 8;
}
//VMADDH
void bPPU::mmio_w2117(uint8 value) {
regs.vram_addr = (value << 8) | (regs.vram_addr & 0x00ff);
uint16 addr = get_vram_address();
if(vram_can_read()) {
regs.vram_readbuffer = vram_read(addr);
regs.vram_readbuffer |= vram_read(addr + 1) << 8;
} else {
regs.vram_readbuffer = 0x0000;
}
regs.vram_readbuffer = vram_mmio_read(addr + 0);
regs.vram_readbuffer |= vram_mmio_read(addr + 1) << 8;
}
//VMDATAL
void bPPU::mmio_w2118(uint8 value) {
uint16 addr = get_vram_address();
if(vram_can_write(value)) {
vram_write(addr, value);
bg_tiledata_state[TILE_2BIT][(addr >> 4)] = 1;
bg_tiledata_state[TILE_4BIT][(addr >> 5)] = 1;
bg_tiledata_state[TILE_8BIT][(addr >> 6)] = 1;
}
vram_mmio_write(addr, value);
bg_tiledata_state[TILE_2BIT][(addr >> 4)] = 1;
bg_tiledata_state[TILE_4BIT][(addr >> 5)] = 1;
bg_tiledata_state[TILE_8BIT][(addr >> 6)] = 1;
if(regs.vram_incmode == 0) {
regs.vram_addr += regs.vram_incsize;
@ -269,12 +293,10 @@ uint16 addr = get_vram_address();
//VMDATAH
void bPPU::mmio_w2119(uint8 value) {
uint16 addr = get_vram_address() + 1;
if(vram_can_write(value)) {
vram_write(addr, value);
bg_tiledata_state[TILE_2BIT][(addr >> 4)] = 1;
bg_tiledata_state[TILE_4BIT][(addr >> 5)] = 1;
bg_tiledata_state[TILE_8BIT][(addr >> 6)] = 1;
}
vram_mmio_write(addr, value);
bg_tiledata_state[TILE_2BIT][(addr >> 4)] = 1;
bg_tiledata_state[TILE_4BIT][(addr >> 5)] = 1;
bg_tiledata_state[TILE_8BIT][(addr >> 6)] = 1;
if(regs.vram_incmode == 1) {
regs.vram_addr += regs.vram_incsize;
@ -529,14 +551,17 @@ uint8 bPPU::mmio_r2137() {
//OAMDATAREAD
uint8 bPPU::mmio_r2138() {
regs.ppu1_mdr = oam_read(regs.oam_addr);
//DMV27: OAM writes do not affect latch data
//byuu: Even if they do, this should only affect the low table
//byuu: Disable for now, see what happens... test on hardware
//if(!(regs.oam_addr & 1)) {
// regs.oam_latchdata = regs.ppu1_mdr;
//}
regs.oam_addr++;
regs.oam_addr &= 0x03ff;
if(!(regs.oam_addr & 1)) {
if(regs.oam_priority == false) {
regs.oam_firstsprite = 0;
} else {
regs.oam_firstsprite = (regs.oam_addr >> 2) & 127;
}
}
return regs.ppu1_mdr;
}
@ -546,12 +571,8 @@ uint16 addr = get_vram_address();
regs.ppu1_mdr = regs.vram_readbuffer;
if(regs.vram_incmode == 0) {
addr &= 0xfffe;
if(vram_can_read()) {
regs.vram_readbuffer = vram_read(addr);
regs.vram_readbuffer |= vram_read(addr + 1) << 8;
} else {
regs.vram_readbuffer = 0x0000;
}
regs.vram_readbuffer = vram_mmio_read(addr + 0);
regs.vram_readbuffer |= vram_mmio_read(addr + 1) << 8;
regs.vram_addr += regs.vram_incsize;
}
return regs.ppu1_mdr;
@ -563,12 +584,8 @@ uint16 addr = get_vram_address() + 1;
regs.ppu1_mdr = regs.vram_readbuffer >> 8;
if(regs.vram_incmode == 1) {
addr &= 0xfffe;
if(vram_can_read()) {
regs.vram_readbuffer = vram_read(addr);
regs.vram_readbuffer |= vram_read(addr + 1) << 8;
} else {
regs.vram_readbuffer = 0x0000;
}
regs.vram_readbuffer = vram_mmio_read(addr + 0);
regs.vram_readbuffer |= vram_mmio_read(addr + 1) << 8;
regs.vram_addr += regs.vram_incsize;
}
return regs.ppu1_mdr;

View File

@ -161,14 +161,14 @@ void bPPU::render_line() {
update_bg_info();
switch(regs.bg_mode) {
case 0:render_line_mode0();break;
case 1:render_line_mode1();break;
case 2:render_line_mode2();break;
case 3:render_line_mode3();break;
case 4:render_line_mode4();break;
case 5:render_line_mode5();break;
case 6:render_line_mode6();break;
case 7:render_line_mode7();break;
case 0: render_line_mode0(); break;
case 1: render_line_mode1(); break;
case 2: render_line_mode2(); break;
case 3: render_line_mode3(); break;
case 4: render_line_mode4(); break;
case 5: render_line_mode5(); break;
case 6: render_line_mode6(); break;
case 7: render_line_mode7(); break;
}
render_line_output();

View File

@ -77,6 +77,7 @@ void build_sprite_list();
bool is_sprite_on_scanline();
void load_oam_tiles();
void render_oam_tile(int tile_num);
void render_line_oam_rto();
void render_line_oam(uint8 pri0_pos, uint8 pri1_pos, uint8 pri2_pos, uint8 pri3_pos);
void render_line_oam_lores(uint8 pri0_pos, uint8 pri1_pos, uint8 pri2_pos, uint8 pri3_pos);

View File

@ -54,40 +54,40 @@ void bPPU::render_line_bg(uint8 bg, uint8 color_depth, uint8 pri0_pos, uint8 pri
//nothing to render?
if(!pri0_pos && !pri1_pos)return;
bool bg_enabled = regs.bg_enabled[bg];
bool bgsub_enabled = regs.bgsub_enabled[bg];
bool bg_enabled = regs.bg_enabled[bg];
bool bgsub_enabled = regs.bgsub_enabled[bg];
uint16 opt_valid_bit = (bg == BG1) ? 0x2000 : (bg == BG2) ? 0x4000 : 0x0000;
uint8 bgpal_index = (regs.bg_mode == 0) ? (bg << 5) : 0;
uint16 opt_valid_bit = (bg == BG1) ? 0x2000 : (bg == BG2) ? 0x4000 : 0x0000;
uint8 bgpal_index = (regs.bg_mode == 0) ? (bg << 5) : 0;
uint8 pal_size = 2 << color_depth; //<<2 (*4), <<4 (*16), <<8 (*256)
uint16 tile_mask = 0x0fff >> color_depth; //0x0fff, 0x07ff, 0x03ff
uint8 pal_size = 2 << color_depth; //<<2 (*4), <<4 (*16), <<8 (*256)
uint16 tile_mask = 0x0fff >> color_depth; //0x0fff, 0x07ff, 0x03ff
//4 + color_depth = >>(4-6) -- / {16, 32, 64 } bytes/tile
//index is a tile number count to add to base tile number
uint tiledata_index = regs.bg_tdaddr[bg] >> (4 + color_depth);
uint8 *bg_td = (uint8*)bg_tiledata[color_depth];
uint8 *bg_td_state = (uint8*)bg_tiledata_state[color_depth];
uint8 *bg_td = (uint8*)bg_tiledata[color_depth];
uint8 *bg_td_state = (uint8*)bg_tiledata_state[color_depth];
uint8 tile_width = bg_info[bg].tw;
uint8 tile_height = bg_info[bg].th;
uint16 mask_x = bg_info[bg].mx; //screen width mask
uint16 mask_y = bg_info[bg].my; //screen height mask
uint8 tile_width = bg_info[bg].tw;
uint8 tile_height = bg_info[bg].th;
uint16 mask_x = bg_info[bg].mx; //screen width mask
uint16 mask_y = bg_info[bg].my; //screen height mask
uint x = 0;
uint y = regs.bg_y[bg];
if(regs.interlace && regs.hires) {
y = (y << 1) + line.interlace_field;
uint16 x = 0;
uint16 y = regs.bg_y[bg];
uint16 hscroll = regs.bg_hofs[bg];
uint16 vscroll = regs.bg_vofs[bg];
if(regs.hires) {
hscroll <<= 1;
if(regs.interlace) {
vscroll <<= 1;
y = (y << 1) + line.interlace_field;
}
}
uint16 hscroll = (regs.hires) ? (regs.bg_hofs[bg] << 1) : regs.bg_hofs[bg];
uint16 vscroll = (regs.interlace && regs.hires) ? (regs.bg_vofs[bg] << 1) : regs.bg_vofs[bg];
hscroll &= mask_x;
vscroll &= mask_y;
uint16 *mtable = (uint16*)mosaic_table[(regs.mosaic_enabled[bg]) ? regs.mosaic_size : 0];
uint16 mosaic_x;
uint16 mosaic_y;
uint16 hval, vval;
uint16 t, tile_pri, tile_num;
@ -104,7 +104,7 @@ uint8 *wt_sub = window[bg].sub;
int32 prev_x = -1, prev_y = -1;
for(x = 0; x < line.width; x++) {
hoffset = x + hscroll;
hoffset = mtable[x] + hscroll;
voffset = y + vscroll;
if(is_opt_mode) {
@ -139,27 +139,27 @@ int32 prev_x = -1, prev_y = -1;
}
}
mosaic_x = mtable[hoffset & mask_x];
mosaic_y = voffset & mask_y;
hoffset &= mask_x;
voffset &= mask_y;
if((mosaic_x >> 3) != prev_x || (mosaic_y >> 3) != prev_y) {
prev_x = (mosaic_x >> 3);
prev_y = (mosaic_y >> 3);
if((hoffset >> 3) != prev_x || (voffset >> 3) != prev_y) {
prev_x = (hoffset >> 3);
prev_y = (voffset >> 3);
t = bg_get_tile(bg, mosaic_x, mosaic_y);
t = bg_get_tile(bg, hoffset, voffset);
mirror_y = bool(t & 0x8000);
mirror_x = bool(t & 0x4000);
mirror_y = bool(t & 0x8000);
mirror_x = bool(t & 0x4000);
tile_pri = (t & 0x2000) ? pri1_pos : pri0_pos;
tile_num = t;
if(tile_width == 4) { //16x16 horizontal tile mirroring
if(bool(mosaic_x & 8) != mirror_x)tile_num++;
if(bool(hoffset & 8) != mirror_x)tile_num++;
}
if(tile_height == 4) { //16x16 vertical tile mirroring
if(bool(mosaic_y & 8) != mirror_y)tile_num += 16;
if(bool(voffset & 8) != mirror_y)tile_num += 16;
}
tile_num &= 0x03ff;
@ -173,13 +173,13 @@ int32 prev_x = -1, prev_y = -1;
pal_num = ((t >> 10) & 7);
pal_index = bgpal_index + (pal_num << pal_size);
ypos = mosaic_y & 7;
ypos = voffset & 7;
if(mirror_y)ypos ^= 7; //invert y tile pos
tile_ptr = (uint8*)bg_td + (tile_num * 64) + (ypos * 8);
}
xpos = mosaic_x & 7;
xpos = hoffset & 7;
if(mirror_x)xpos ^= 7; //invert x tile pos
col = *(tile_ptr + xpos);
if(col) {

View File

@ -1,27 +1,24 @@
#define render_bg_tile_line_4(__m) \
col = 0; \
if(d0 & __m)col += 1; \
if(d1 & __m)col += 2; \
#define render_bg_tile_line_2bpp(mask) \
col = bool(d0 & mask) << 0; \
col += bool(d1 & mask) << 1; \
*dest++ = col
#define render_bg_tile_line_16(__m) \
col = 0; \
if(d0 & __m)col += 1; \
if(d1 & __m)col += 2; \
if(d2 & __m)col += 4; \
if(d3 & __m)col += 8; \
#define render_bg_tile_line_4bpp(mask) \
col = bool(d0 & mask) << 0; \
col += bool(d1 & mask) << 1; \
col += bool(d2 & mask) << 2; \
col += bool(d3 & mask) << 3; \
*dest++ = col
#define render_bg_tile_line_256(__m) \
col = 0; \
if(d0 & __m)col += 1; \
if(d1 & __m)col += 2; \
if(d2 & __m)col += 4; \
if(d3 & __m)col += 8; \
if(d4 & __m)col += 16; \
if(d5 & __m)col += 32; \
if(d6 & __m)col += 64; \
if(d7 & __m)col += 128; \
#define render_bg_tile_line_8bpp(mask) \
col = bool(d0 & mask) << 0; \
col += bool(d1 & mask) << 1; \
col += bool(d2 & mask) << 2; \
col += bool(d3 & mask) << 3; \
col += bool(d4 & mask) << 4; \
col += bool(d5 & mask) << 5; \
col += bool(d6 & mask) << 6; \
col += bool(d7 & mask) << 7; \
*dest++ = col
void bPPU::render_bg_tile(uint8 color_depth, uint16 tile_num) {
@ -37,14 +34,14 @@ uint8 *dest;
while(y--) {
d0 = vram[pos ];
d1 = vram[pos + 1];
render_bg_tile_line_4(0x80);
render_bg_tile_line_4(0x40);
render_bg_tile_line_4(0x20);
render_bg_tile_line_4(0x10);
render_bg_tile_line_4(0x08);
render_bg_tile_line_4(0x04);
render_bg_tile_line_4(0x02);
render_bg_tile_line_4(0x01);
render_bg_tile_line_2bpp(0x80);
render_bg_tile_line_2bpp(0x40);
render_bg_tile_line_2bpp(0x20);
render_bg_tile_line_2bpp(0x10);
render_bg_tile_line_2bpp(0x08);
render_bg_tile_line_2bpp(0x04);
render_bg_tile_line_2bpp(0x02);
render_bg_tile_line_2bpp(0x01);
pos += 2;
}
bg_tiledata_state[TILE_2BIT][tile_num] = 0;
@ -58,14 +55,14 @@ uint8 *dest;
d1 = vram[pos + 1];
d2 = vram[pos + 16];
d3 = vram[pos + 17];
render_bg_tile_line_16(0x80);
render_bg_tile_line_16(0x40);
render_bg_tile_line_16(0x20);
render_bg_tile_line_16(0x10);
render_bg_tile_line_16(0x08);
render_bg_tile_line_16(0x04);
render_bg_tile_line_16(0x02);
render_bg_tile_line_16(0x01);
render_bg_tile_line_4bpp(0x80);
render_bg_tile_line_4bpp(0x40);
render_bg_tile_line_4bpp(0x20);
render_bg_tile_line_4bpp(0x10);
render_bg_tile_line_4bpp(0x08);
render_bg_tile_line_4bpp(0x04);
render_bg_tile_line_4bpp(0x02);
render_bg_tile_line_4bpp(0x01);
pos += 2;
}
bg_tiledata_state[TILE_4BIT][tile_num] = 0;
@ -83,14 +80,14 @@ uint8 *dest;
d5 = vram[pos + 33];
d6 = vram[pos + 48];
d7 = vram[pos + 49];
render_bg_tile_line_256(0x80);
render_bg_tile_line_256(0x40);
render_bg_tile_line_256(0x20);
render_bg_tile_line_256(0x10);
render_bg_tile_line_256(0x08);
render_bg_tile_line_256(0x04);
render_bg_tile_line_256(0x02);
render_bg_tile_line_256(0x01);
render_bg_tile_line_8bpp(0x80);
render_bg_tile_line_8bpp(0x40);
render_bg_tile_line_8bpp(0x20);
render_bg_tile_line_8bpp(0x10);
render_bg_tile_line_8bpp(0x08);
render_bg_tile_line_8bpp(0x04);
render_bg_tile_line_8bpp(0x02);
render_bg_tile_line_8bpp(0x01);
pos += 2;
}
bg_tiledata_state[TILE_8BIT][tile_num] = 0;
@ -98,9 +95,9 @@ uint8 *dest;
}
}
#undef render_bg_tile_line_4
#undef render_bg_tile_line_16
#undef render_bg_tile_line_256
#undef render_bg_tile_line_2bpp
#undef render_bg_tile_line_4bpp
#undef render_bg_tile_line_8bpp
inline void bPPU::clear_pixel_cache() {
uint16 main = get_palette(0);

View File

@ -25,15 +25,15 @@ void bPPU::render_line_mode7(uint8 bg, uint8 pri0_pos, uint8 pri1_pos) {
int32 px, py;
int32 tx, ty, tile, palette;
int32 a = sclip<15>(regs.m7a); //int32(int16(regs.m7a));
int32 b = sclip<15>(regs.m7b); //int32(int16(regs.m7b));
int32 c = sclip<15>(regs.m7c); //int32(int16(regs.m7c));
int32 d = sclip<15>(regs.m7d); //int32(int16(regs.m7d));
int32 a = sclip<16>(regs.m7a);
int32 b = sclip<16>(regs.m7b);
int32 c = sclip<16>(regs.m7c);
int32 d = sclip<16>(regs.m7d);
int32 cx = sclip<13>(regs.m7x); //(int32(regs.m7x) << 19) >> 19;
int32 cy = sclip<13>(regs.m7y); //(int32(regs.m7y) << 19) >> 19;
int32 hofs = sclip<13>(regs.m7_hofs); //(int32(regs.m7_hofs) << 19) >> 19;
int32 vofs = sclip<13>(regs.m7_vofs); //(int32(regs.m7_vofs + 0) << 19) >> 19;
int32 cx = sclip<13>(regs.m7x);
int32 cy = sclip<13>(regs.m7y);
int32 hofs = sclip<13>(regs.m7_hofs);
int32 vofs = sclip<13>(regs.m7_vofs);
int _pri, _x;
bool _bg_enabled = regs.bg_enabled[bg];

View File

@ -95,7 +95,8 @@ uint16 chry = (spr->character >> 4) & 15;
for(uint tx = 0; tx < tile_width; tx++) {
uint sx = (x + (tx << 3)) & 511;
if(sx > 256 && (sx + 7) < 512)continue; //ignore sprites that are offscreen
//ignore sprites that are offscreen, x==256 is a special case that loads all tiles in OBJ
if(x != 256 && sx >= 256 && (sx + 7) < 512)continue;
if(regs.oam_tilecount++ > 34)break;
uint n = regs.oam_tilecount - 1;
@ -136,7 +137,7 @@ uint8 *tile_ptr = (uint8*)oam_td + (t->tile << 6) + ((t->y & 7) << 3);
}
}
void bPPU::render_line_oam(uint8 pri0_pos, uint8 pri1_pos, uint8 pri2_pos, uint8 pri3_pos) {
void bPPU::render_line_oam_rto() {
build_sprite_list();
regs.oam_itemcount = 0;
@ -158,14 +159,11 @@ void bPPU::render_line_oam(uint8 pri0_pos, uint8 pri1_pos, uint8 pri2_pos, uint8
load_oam_tiles();
}
for(int s = 0; s < 34; s++) {
if(oam_tilelist[s].tile == 0xffff)continue;
render_oam_tile(s);
}
regs.time_over |= (regs.oam_tilecount > 34);
regs.range_over |= (regs.oam_itemcount > 32);
}
void bPPU::render_line_oam(uint8 pri0_pos, uint8 pri1_pos, uint8 pri2_pos, uint8 pri3_pos) {
if(regs.bg_enabled[OAM] == false && regs.bgsub_enabled[OAM] == false)return;
//are layers disabled by user?
@ -176,6 +174,11 @@ void bPPU::render_line_oam(uint8 pri0_pos, uint8 pri1_pos, uint8 pri2_pos, uint8
//nothing to render?
if(!pri0_pos && !pri1_pos && !pri2_pos && !pri3_pos)return;
for(int s = 0; s < 34; s++) {
if(oam_tilelist[s].tile == 0xffff)continue;
render_oam_tile(s);
}
render_line_oam_lores(pri0_pos, pri1_pos, pri2_pos, pri3_pos);
}

View File

@ -112,6 +112,7 @@ void SNES::log_audio_disable() {
}
void SNES::audio_init() {
pcmfp = 0;
}
void SNES::audio_term() {

View File

@ -61,12 +61,12 @@ void SNES::power() {
r_ppu->power();
r_mem->power();
if(cartridge.cart.srtc)srtc->power();
if(cartridge.cart.sdd1)sdd1->power();
if(cartridge.cart.c4) c4->power();
if(cartridge.cart.dsp1)dsp1->power();
if(cartridge.cart.dsp2)dsp2->power();
if(cartridge.cart.obc1)obc1->power();
if(cartridge.info.srtc)srtc->power();
if(cartridge.info.sdd1)sdd1->power();
if(cartridge.info.c4) c4->power();
if(cartridge.info.dsp1)dsp1->power();
if(cartridge.info.dsp2)dsp2->power();
if(cartridge.info.obc1)obc1->power();
r_mem->flush_mmio_mappers();
for(int i = 0x2100; i <= 0x213f; i++)r_mem->set_mmio_mapper(i, r_ppu);
@ -76,12 +76,12 @@ void SNES::power() {
for(int i = 0x4200; i <= 0x421f; i++)r_mem->set_mmio_mapper(i, r_cpu);
for(int i = 0x4300; i <= 0x437f; i++)r_mem->set_mmio_mapper(i, r_cpu);
if(cartridge.cart.srtc)srtc->enable();
if(cartridge.cart.sdd1)sdd1->enable();
if(cartridge.cart.c4) c4->enable();
if(cartridge.cart.dsp1)dsp1->enable();
if(cartridge.cart.dsp2)dsp2->enable();
if(cartridge.cart.obc1)obc1->enable();
if(cartridge.info.srtc)srtc->enable();
if(cartridge.info.sdd1)sdd1->enable();
if(cartridge.info.c4) c4->enable();
if(cartridge.info.dsp1)dsp1->enable();
if(cartridge.info.dsp2)dsp2->enable();
if(cartridge.info.obc1)obc1->enable();
video_update();
}
@ -96,12 +96,12 @@ void SNES::reset() {
r_ppu->reset();
r_mem->reset();
if(cartridge.cart.srtc)srtc->reset();
if(cartridge.cart.sdd1)sdd1->reset();
if(cartridge.cart.c4) c4->reset();
if(cartridge.cart.dsp1)dsp1->reset();
if(cartridge.cart.dsp2)dsp2->reset();
if(cartridge.cart.obc1)obc1->reset();
if(cartridge.info.srtc)srtc->reset();
if(cartridge.info.sdd1)sdd1->reset();
if(cartridge.info.c4) c4->reset();
if(cartridge.info.dsp1)dsp1->reset();
if(cartridge.info.dsp2)dsp2->reset();
if(cartridge.info.obc1)obc1->reset();
video_update();
}
@ -118,9 +118,9 @@ void SNES::scanline() {
void SNES::frame() {}
/****************
*** PAL/NTSC ***
****************/
/*****
* PAL/NTSC
*****/
void SNES::set_region(uint8 new_region) {
if(new_region == NTSC) {
@ -136,13 +136,21 @@ void SNES::set_region(uint8 new_region) {
uint8 SNES::region() { return snes_region; }
/**************
*** Timing ***
**************/
/*****
* Timing
*
* Note: Stock PAL CPU speed is currently unknown.
* It is thought to be 21281370hz, but this causes
* sound errors in certain games. Therefore, the PAL
* CPU is currently clocked 40000hz slower, at
* 21241370hz.
*****/
void SNES::update_timing() {
sync.counter = 0;
sync.cpu_freq = (snes_region == NTSC) ? 21477272 : 21281370;
sync.counter = 0;
sync.dsp_counter = 0;
sync.cpu_freq = (snes_region == NTSC) ? 21477272 : 21241370;
sync.apu_freq = 24576000;
for(int64 i = 0; i < 1024; i++) {
@ -151,9 +159,9 @@ void SNES::update_timing() {
}
}
/***************************
*** Debugging functions ***
***************************/
/*****
* Debugging functions
*****/
void SNES::notify(uint32 message, uint32 param1, uint32 param2) {}

198
src/ui/Makefile Normal file
View File

@ -0,0 +1,198 @@
ifeq ($(PLATFORM),win-visualc)
CC = cl
CXX = cl
AS = nasm
RM = del
OBJ = obj
CFLAGS = /nologo /O2 /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86
COMPILE = $(CC) $(CFLAGS) /c
ASSEMBLE = $(AS) -f win32
LINK =
LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \
d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
endif
ifeq ($(PLATFORM),win-visualc-wip)
CC = cl
CXX = cl
AS = nasm
RM = del
OBJ = obj
CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86
COMPILE = $(CC) $(CFLAGS) /c
ASSEMBLE = $(AS) -f win32
LINK = /link /LTCG
LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \
d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
endif
ifeq ($(PLATFORM),win-visualc-pgi)
CC = cl
CXX = cl
AS = nasm
RM = del
OBJ = obj
CFLAGS = /nologo /O2 /GL /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86
COMPILE = $(CC) $(CFLAGS) /c
ASSEMBLE = $(AS) -f win32
LINK = /link /PGD:bsnes.pgd /LTCG:PGINSTRUMENT
LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \
d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
endif
ifeq ($(PLATFORM),win-visualc-pgo)
CC = cl
CXX = cl
AS = nasm
RM = del
OBJ = obj
CFLAGS = /nologo /O2 /arch:SSE2 /DPLATFORM_WIN /DCOMPILER_VISUALC /DPROCESSOR_X86
COMPILE = $(CC) $(CFLAGS) /c
ASSEMBLE = $(AS) -f win32
LINK = /link /PGD:bsnes.pgd /LTCG:PGOPTIMIZE
LIBS = kernel32.lib user32.lib gdi32.lib winmm.lib comdlg32.lib comctl32.lib \
d3d9.lib d3dx9.lib ddraw.lib dsound.lib dinput8.lib dxguid.lib
endif
OBJS = main.$(OBJ) \
libco.$(OBJ) libstring.$(OBJ) libconfig.$(OBJ) \
reader.$(OBJ) cart.$(OBJ) cheat.$(OBJ) \
memory.$(OBJ) bmemory.$(OBJ) \
cpu.$(OBJ) scpu.$(OBJ) bcpu.$(OBJ) \
apu.$(OBJ) sapu.$(OBJ) bapu.$(OBJ) \
bdsp.$(OBJ) \
ppu.$(OBJ) bppu.$(OBJ) \
snes.$(OBJ) \
srtc.$(OBJ) sdd1.$(OBJ) c4.$(OBJ) dsp1.$(OBJ) dsp2.$(OBJ) obc1.$(OBJ)
# adler32.$(OBJ) compress.$(OBJ) crc32.$(OBJ) deflate.$(OBJ) gzio.$(OBJ) inffast.$(OBJ) \
# inflate.$(OBJ) inftrees.$(OBJ) ioapi.$(OBJ) trees.$(OBJ) unzip.$(OBJ) zip.$(OBJ) zutil.$(OBJ) \
# jma.$(OBJ) jcrc32.$(OBJ) lzmadec.$(OBJ) 7zlzma.$(OBJ) iiostrm.$(OBJ) inbyte.$(OBJ) lzma.$(OBJ) winout.$(OBJ)
all: $(OBJS)
rc /r /fobsnes.res bsnes.rc
$(CC) /Febsnes.exe $(CFLAGS) $(OBJS) bsnes.res $(LIBS) $(LINK)
clean:
$(RM) *.$(OBJ)
$(RM) *.res
$(RM) *.pgd
$(RM) *.pgc
$(RM) *.ilk
$(RM) *.pdb
#########################
### platform-specific ###
#########################
main.$(OBJ): *.cpp *.h video/* audio/* input/* ../config/* win/* win/settings/* win/debugger/*
$(COMPILE) main.cpp
#################
### libraries ###
#################
libco.$(OBJ): ../lib/*
$(ASSEMBLE) -o libco.$(OBJ) ../lib/libco_x86.asm
libstring.$(OBJ): ../lib/*.cpp ../lib/*.h
$(COMPILE) ../lib/libstring.cpp
libconfig.$(OBJ): ../lib/*.cpp ../lib/*.h
$(COMPILE) ../lib/libconfig.cpp
##############
### memory ###
##############
memory.$(OBJ): ../memory/memory.cpp ../memory/memory.h
$(COMPILE) ../memory/memory.cpp
bmemory.$(OBJ): ../memory/bmemory/* ../memory/bmemory/mapper/*
$(COMPILE) ../memory/bmemory/bmemory.cpp
###########
### cpu ###
###########
cpu.$(OBJ): ../cpu/*
$(COMPILE) ../cpu/cpu.cpp
scpu.$(OBJ): ../cpu/scpu/* ../cpu/scpu/core/* ../cpu/scpu/dma/* ../cpu/scpu/memory/* ../cpu/scpu/mmio/* ../cpu/scpu/timing/*
$(COMPILE) ../cpu/scpu/scpu.cpp
bcpu.$(OBJ): ../cpu/bcpu/*
$(COMPILE) ../cpu/bcpu/bcpu.cpp
###########
### apu ###
###########
apu.$(OBJ): ../apu/*
$(COMPILE) ../apu/apu.cpp
sapu.$(OBJ): ../apu/sapu/* ../apu/sapu/core/* ../apu/sapu/memory/* ../apu/sapu/timing/*
$(COMPILE) ../apu/sapu/sapu.cpp
bapu.$(OBJ): ../apu/bapu/*
$(COMPILE) ../apu/bapu/bapu.cpp
###########
### dsp ###
###########
bdsp.$(OBJ): ../dsp/bdsp/*
$(COMPILE) ../dsp/bdsp/bdsp.cpp
###########
### ppu ###
###########
ppu.$(OBJ): ../ppu/*.cpp ../ppu/*.h
$(COMPILE) ../ppu/ppu.cpp
bppu.$(OBJ): ../ppu/bppu/*
$(COMPILE) ../ppu/bppu/bppu.cpp
#################
### utilities ###
#################
reader.$(OBJ): ../reader/*.cpp ../reader/*.h
$(COMPILE) ../reader/reader.cpp
cart.$(OBJ): ../cart/*.cpp ../cart/*.h
$(COMPILE) ../cart/cart.cpp
cheat.$(OBJ): ../cheat/*.cpp ../cheat/*.h
$(COMPILE) ../cheat/cheat.cpp
############
### snes ###
############
snes.$(OBJ): ../snes/* ../snes/video/* ../snes/audio/* ../snes/input/*
$(COMPILE) ../snes/snes.cpp
#####################
### special chips ###
#####################
srtc.$(OBJ): ../chip/srtc/*
$(COMPILE) ../chip/srtc/srtc.cpp
sdd1.$(OBJ): ../chip/sdd1/*
$(COMPILE) ../chip/sdd1/sdd1.cpp
c4.$(OBJ): ../chip/c4/*
$(COMPILE) ../chip/c4/c4.cpp
dsp1.$(OBJ): ../chip/dsp1/*
$(COMPILE) ../chip/dsp1/dsp1.cpp
dsp2.$(OBJ): ../chip/dsp2/*
$(COMPILE) ../chip/dsp2/dsp2.cpp
obc1.$(OBJ): ../chip/obc1/*
$(COMPILE) ../chip/obc1/obc1.cpp
############
### zlib ###
############
adler32.$(OBJ): ../reader/zlib/*.c ../reader/zlib/*.h
$(COMPILE) ../reader/zlib/*.c
###########
### jma ###
###########
jma.$(OBJ): ../reader/jma/*.cpp ../reader/jma/*.h
$(COMPILE) ../reader/jma/*.cpp

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