mirror of
https://github.com/ares-emulator/ares.git
synced 2026-11-10 17:02:56 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ebdb69516 | ||
|
|
add0f74387 | ||
|
|
b20f70f333 | ||
|
|
9aebf7bc6b | ||
|
|
a7bf219d5d | ||
|
|
04118be59a | ||
|
|
f24d17859f |
No files matched your search
+35
@@ -0,0 +1,35 @@
|
||||
bsnes License:
|
||||
--------------
|
||||
You are free to redistribute this software, and its source code; provided
|
||||
there is no charge for the software, nor any charge for the medium used to
|
||||
distribute the software. You are also free to use and modify the source code
|
||||
as you desire for personal use only. No publically-released derivative works
|
||||
of this program nor its source code are permitted without my permission,
|
||||
though I will likely grant you permission if you ask me. You must also abide
|
||||
by the terms of any additional source code licenses contained within this
|
||||
program.
|
||||
|
||||
Simple DirectMedia Layer License:
|
||||
---------------------------------
|
||||
The Simple DirectMedia Layer (SDL for short) is a cross-platform library
|
||||
designed to make it easy to write multi-media software, such as games and
|
||||
emulators.
|
||||
|
||||
The Simple DirectMedia Layer library source code is available from:
|
||||
http://www.libsdl.org/
|
||||
|
||||
This library is distributed under the terms of the GNU LGPL:
|
||||
http://www.gnu.org/copyleft/lesser.html
|
||||
|
||||
JMA License:
|
||||
------------
|
||||
JMA is licensed under the GNU GPL. I have received special exemption from
|
||||
Nach to use this library in bsnes.
|
||||
|
||||
Licensing Exemptions:
|
||||
---------------------
|
||||
libco, the cooperative multithreading library used by bsnes, is public domain.
|
||||
You may obtain the latest version at: http://byuu.org/
|
||||
|
||||
Richard Bannister has asked for and received my permission to distribute
|
||||
a binary-only port of bsnes on the Mac OS X platform.
|
||||
+98
@@ -0,0 +1,98 @@
|
||||
bsnes
|
||||
Version 0.019
|
||||
Author: byuu
|
||||
|
||||
|
||||
General
|
||||
-------
|
||||
bsnes is a Super Nintendo / Super Famicom emulator that began on
|
||||
October 14th, 2004.
|
||||
|
||||
The latest version can be downloaded from:
|
||||
http://byuu.org/
|
||||
|
||||
Please see license.txt for important licensing information.
|
||||
|
||||
|
||||
Known Limitations
|
||||
-----------------
|
||||
S-CPU
|
||||
- Invalid DMA / HDMA transfers (eg WRAM<>WRAM) not fully emulated
|
||||
- Multiply / Divide register delays not implemented
|
||||
|
||||
S-SMP
|
||||
- Cycle breakdown of opcodes is theoretical, but mostly correct
|
||||
|
||||
S-PPU
|
||||
- Uses scanline-based renderer. This is very inaccurate, but very
|
||||
few games rely on mid-scanline writes to function correctly
|
||||
- Does not support FirstSprite+Y priority
|
||||
- OAM / CGRAM accesses during active display not supported correctly
|
||||
- RTO flags are not calculated on frames that are skipped when frameskipping
|
||||
is enabled. This provides a major speedup, however it will cause in issues
|
||||
in games that test these flags, eg the SNES Test Program Electronics Test.
|
||||
Turning frameskipping off will allow RTO flag calculation on every frame
|
||||
|
||||
S-DSP
|
||||
- Runs at 32khz. Hardware S-DSP likely runs at 1.024mhz to perform
|
||||
multiple reads / writes per sample. Sound is still output at 32khz,
|
||||
of course
|
||||
|
||||
Hardware Bugs
|
||||
- CPUr1 HDMA crashing bug not emulated
|
||||
- CPU<>APU communication bus conflicts not emulated
|
||||
|
||||
|
||||
Unsupported Hardware
|
||||
--------------------
|
||||
SA-1
|
||||
Coprocessor used in many popular games, including:
|
||||
- Dragon Ball Z Hyper Dimension
|
||||
- Kirby Super Star
|
||||
- Kirby's Dreamland 3
|
||||
- Marvelous
|
||||
- SD Gundam G-NEXT
|
||||
- Super Mario RPG
|
||||
|
||||
Super FX
|
||||
Coprocessor used in many popular games, including:
|
||||
- Doom
|
||||
- Star Fox
|
||||
- Star Fox 2 (unreleased beta)
|
||||
- Super Mario World 2: Yoshi's Island
|
||||
|
||||
SPC7110
|
||||
Coprocessor used only by the following games:
|
||||
- Far East of Eden Zero
|
||||
- Far East of Eden Zero: Shounen Jump no Shou
|
||||
- Momotarou Densetsu Happy
|
||||
- Super Power League 4
|
||||
|
||||
DSP-3
|
||||
Coprocessor used only by SD Gundam GX
|
||||
|
||||
DSP-4
|
||||
Coprocessor used only by Top Gear 3000
|
||||
|
||||
ST010 / ST011 / ST018
|
||||
SETA coprocessors used by very few games
|
||||
|
||||
BS-X (Broadcast Satellite)
|
||||
Add-on unit sold only in Japan that played specially-made games that
|
||||
were downloaded via satellite
|
||||
|
||||
BS-X Flashcart
|
||||
Flash cartridge used by BS-X, as well as some standalone games by
|
||||
Asciisoft
|
||||
|
||||
Super Gameboy
|
||||
Cartridge passthrough used for playing Gameboy games
|
||||
|
||||
|
||||
Unsupported controllers
|
||||
-----------------------
|
||||
Mouse
|
||||
Super Scope
|
||||
Justifier
|
||||
Multitap (4-port)
|
||||
Multitap (5-port)
|
||||
+4
-3
@@ -1,4 +1,4 @@
|
||||
#define BSNES_VERSION "0.018"
|
||||
#define BSNES_VERSION "0.019"
|
||||
#define BSNES_TITLE "bsnes v" BSNES_VERSION
|
||||
|
||||
#define MEMCORE bMemBus
|
||||
@@ -14,10 +14,10 @@
|
||||
#define CHEAT_SYSTEM
|
||||
|
||||
//enable GZ, ZIP format support
|
||||
#define GZIP_SUPPORT
|
||||
//#define GZIP_SUPPORT
|
||||
|
||||
//enable JMA support
|
||||
#define JMA_SUPPORT
|
||||
//#define JMA_SUPPORT
|
||||
|
||||
//snes core polymorphism
|
||||
//(allow runtime cpu/smp/dsp/ppu/bus selection, ~10% speed hit)
|
||||
@@ -34,6 +34,7 @@
|
||||
#endif
|
||||
|
||||
#include "lib/libbase.h"
|
||||
#include "lib/libsort.h"
|
||||
#include "lib/libco_x86.h"
|
||||
#include "lib/libarray.h"
|
||||
#include "lib/libvector.h"
|
||||
|
||||
+91
-353
@@ -1,9 +1,20 @@
|
||||
#include "../base.h"
|
||||
#include "database.cpp"
|
||||
|
||||
#include "cart_file.cpp"
|
||||
#include "cart_header.cpp"
|
||||
|
||||
Cartridge cartridge;
|
||||
|
||||
void Cartridge::read_dbi() {
|
||||
#include "cart_normal.cpp"
|
||||
#include "cart_st.cpp"
|
||||
#include "cart_stdual.cpp"
|
||||
|
||||
void Cartridge::load_begin(uint cart_type) {
|
||||
if(loaded() == true)return;
|
||||
|
||||
info.type = cart_type;
|
||||
|
||||
info.srtc = false;
|
||||
info.sdd1 = false;
|
||||
info.c4 = false;
|
||||
@@ -13,372 +24,89 @@ void Cartridge::read_dbi() {
|
||||
|
||||
info.dsp1_mapper = 0;
|
||||
|
||||
info.header_index = 0x7fc0;
|
||||
info.header_index = 0xffc0;
|
||||
info.mapper = PCB;
|
||||
strcpy(info.name, dbi.name);
|
||||
strcpy(info.pcb, dbi.pcb);
|
||||
strcpy(info.name, "");
|
||||
strcpy(info.pcb, "");
|
||||
info.region = NTSC;
|
||||
info.cart_mmio = false;
|
||||
|
||||
info.rom_size = dbi.rom;
|
||||
info.ram_size = dbi.ram;
|
||||
}
|
||||
info.rom_size = 0;
|
||||
info.ram_size = 0;
|
||||
|
||||
void Cartridge::read_header() {
|
||||
info.srtc = false;
|
||||
info.sdd1 = false;
|
||||
info.c4 = false;
|
||||
info.dsp1 = false;
|
||||
info.dsp2 = false;
|
||||
info.obc1 = false;
|
||||
|
||||
info.dsp1_mapper = 0;
|
||||
|
||||
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[info.header_index + MAPPER];
|
||||
uint8 rom_type = rom[info.header_index + ROM_TYPE];
|
||||
if(mapper == 0x35 && rom_type == 0x55) {
|
||||
info.srtc = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x32 && (rom_type == 0x43 || rom_type == 0x45)) {
|
||||
info.sdd1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x20 && rom_type == 0xf3) {
|
||||
info.c4 = true;
|
||||
}
|
||||
|
||||
if((mapper == 0x20 || mapper == 0x21) && rom_type == 0x03) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x05) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x31 && (rom_type == 0x03 || rom_type == 0x05)) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(info.dsp1 == true) {
|
||||
if((mapper & 0x2f) == 0x20 && info.rom_size <= 0x100000) {
|
||||
info.dsp1_mapper = DSP1_LOROM_1MB;
|
||||
} else if((mapper & 0x2f) == 0x20) {
|
||||
info.dsp1_mapper = DSP1_LOROM_2MB;
|
||||
} else if((mapper & 0x2f) == 0x21) {
|
||||
info.dsp1_mapper = DSP1_HIROM;
|
||||
}
|
||||
}
|
||||
|
||||
if(mapper == 0x20 && rom_type == 0x05) {
|
||||
info.dsp2 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x25) {
|
||||
info.obc1 = true;
|
||||
}
|
||||
|
||||
info.cart_mmio = info.c4 | info.dsp1 | info.dsp2 | info.obc1;
|
||||
|
||||
if(rom[info.header_index + SRAM_SIZE] & 7) {
|
||||
info.ram_size = 1024 << (rom[info.header_index + SRAM_SIZE] & 7);
|
||||
} else {
|
||||
info.ram_size = 0;
|
||||
}
|
||||
|
||||
memcpy(&info.name, &rom[info.header_index + CART_NAME], 21);
|
||||
info.name[21] = 0;
|
||||
|
||||
for(int i = 0; i < 22; i++) {
|
||||
if(info.name[i] & 0x80) {
|
||||
info.name[i] = '?';
|
||||
}
|
||||
file.count = 0;
|
||||
for(int i = 0; i < 8; i++) {
|
||||
strcpy(file.rom_name[i], "");
|
||||
strcpy(file.ram_name[i], "");
|
||||
file.rom_size[i] = 0;
|
||||
file.ram_size[i] = 0;
|
||||
file.rom_data[i] = 0;
|
||||
file.ram_data[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::find_header() {
|
||||
int32 score_lo = 0,
|
||||
score_hi = 0,
|
||||
score_ex = 0;
|
||||
void Cartridge::load(const char *rom_fn) {
|
||||
if(!rom_fn || !*rom_fn)return;
|
||||
|
||||
if(info.rom_size < 0x010000) {
|
||||
//cart too small to be anything but lorom
|
||||
info.header_index = 0x007fc0;
|
||||
return;
|
||||
}
|
||||
|
||||
if((rom[0x7fc0 + MAPPER] & ~0x10) == 0x20)score_lo++;
|
||||
if((rom[0xffc0 + MAPPER] & ~0x10) == 0x21)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + ROM_TYPE] < 0x08)score_lo++;
|
||||
if(rom[0xffc0 + ROM_TYPE] < 0x08)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + ROM_SIZE] < 0x10)score_lo++;
|
||||
if(rom[0xffc0 + ROM_SIZE] < 0x10)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + SRAM_SIZE] < 0x08)score_lo++;
|
||||
if(rom[0xffc0 + SRAM_SIZE] < 0x08)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + REGION] < 14)score_lo++;
|
||||
if(rom[0xffc0 + REGION] < 14)score_hi++;
|
||||
|
||||
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);
|
||||
if((cksum + icksum) == 0xffff && (cksum != 0) && (icksum != 0)) {
|
||||
score_lo += 8;
|
||||
}
|
||||
|
||||
cksum = rom[0xffc0 + CKSUM] | (rom[0xffc0 + CKSUM + 1] << 8);
|
||||
icksum = rom[0xffc0 + ICKSUM] | (rom[0xffc0 + ICKSUM + 1] << 8);
|
||||
if((cksum + icksum) == 0xffff && (cksum != 0) && (icksum != 0)) {
|
||||
score_hi += 8;
|
||||
}
|
||||
|
||||
if(info.rom_size < 0x401000) {
|
||||
score_ex = 0;
|
||||
} else {
|
||||
if(rom[0x7fc0 + MAPPER] == 0x32)score_lo++;
|
||||
else score_ex += 16;
|
||||
}
|
||||
|
||||
if(score_lo >= score_hi && score_lo >= score_ex) {
|
||||
info.header_index = 0x007fc0;
|
||||
} else if(score_hi >= score_ex) {
|
||||
info.header_index = 0x00ffc0;
|
||||
} else {
|
||||
info.header_index = 0x40ffc0;
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::load_sram() {
|
||||
if(info.ram_size == 0) {
|
||||
sram = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
FileReader ff(sram_fn);
|
||||
if(!ff.ready()) {
|
||||
sram = (uint8*)malloc(info.ram_size);
|
||||
memset(sram, 0xff, info.ram_size);
|
||||
return;
|
||||
}
|
||||
|
||||
sram = ff.read(info.ram_size);
|
||||
}
|
||||
|
||||
void Cartridge::save_sram() {
|
||||
if(info.ram_size == 0)return;
|
||||
|
||||
FileWriter ff(sram_fn);
|
||||
if(!ff.ready())return;
|
||||
|
||||
ff.write(sram, info.ram_size);
|
||||
}
|
||||
|
||||
void Cartridge::load_rom(Reader &rf) {
|
||||
uint size = rf.size();
|
||||
bool header = ((size & 0x7fff) == 512);
|
||||
info.rom_size = size - (header ? 512 : 0);
|
||||
if(info.rom_size & 0x7fff) {
|
||||
info.rom_size += 0x8000 - (info.rom_size & 0x7fff);
|
||||
}
|
||||
|
||||
uint8 *base_rom = rf.read(info.rom_size + (header ? 512 : 0));
|
||||
if(header) {
|
||||
memcpy(rom_header, base_rom, 512);
|
||||
} else {
|
||||
memset(rom_header, 0x00, 512);
|
||||
}
|
||||
|
||||
rom = (uint8*)malloc(info.rom_size);
|
||||
memcpy(rom, base_rom + (header ? 512 : 0), info.rom_size);
|
||||
SafeFree(base_rom);
|
||||
|
||||
info.crc32 = 0xffffffff;
|
||||
for(int32 i = 0; i < info.rom_size; i++) {
|
||||
info.crc32 = crc32_adjust(info.crc32, rom[i]);
|
||||
}
|
||||
info.crc32 = ~info.crc32;
|
||||
}
|
||||
|
||||
void Cartridge::patch_rom(Reader &rf) {
|
||||
UPS<ramfile, ramfile, ramfile> ups;
|
||||
uint patchsize = rf.size();
|
||||
uint8 *patchdata = rf.read();
|
||||
|
||||
fopen(ups.original, 0, file::mode_writeread);
|
||||
fopen(ups.modified, 0, file::mode_writeread);
|
||||
fopen(ups.patch.fp, 0, file::mode_writeread);
|
||||
|
||||
fwrite(ups.original, rom, info.rom_size);
|
||||
fwrite(ups.patch.fp, patchdata, patchsize);
|
||||
|
||||
if(ups.apply() == true) {
|
||||
info.crc32 = ups.modified_crc32;
|
||||
info.rom_size = ups.modified_filesize;
|
||||
rom = (uint8*)realloc(rom, info.rom_size);
|
||||
fseek(ups.modified, 0, file::seek_start);
|
||||
fread(ups.modified, rom, info.rom_size);
|
||||
}
|
||||
}
|
||||
|
||||
bool Cartridge::load(const char *fn) {
|
||||
if(cart_loaded == true)return false;
|
||||
if(strlen(fn) < 3)return false;
|
||||
|
||||
dprintf("* Loading \"%s\"...", fn);
|
||||
|
||||
strcpy(rom_fn, fn);
|
||||
|
||||
switch(Reader::detect(rom_fn)) {
|
||||
|
||||
case Reader::RF_NORMAL: {
|
||||
FileReader ff(rom_fn);
|
||||
if(!ff.ready()) {
|
||||
alert("Error loading image file (%s)!", rom_fn);
|
||||
return false;
|
||||
}
|
||||
load_rom(ff);
|
||||
} break;
|
||||
|
||||
#ifdef GZIP_SUPPORT
|
||||
case Reader::RF_GZ: {
|
||||
GZReader gf(rom_fn);
|
||||
if(!gf.ready()) {
|
||||
alert("Error loading image file (%s)!", rom_fn);
|
||||
return false;
|
||||
}
|
||||
load_rom(gf);
|
||||
} break;
|
||||
|
||||
case Reader::RF_ZIP: {
|
||||
ZipReader zf(rom_fn);
|
||||
load_rom(zf);
|
||||
} break;
|
||||
#endif
|
||||
|
||||
#ifdef JMA_SUPPORT
|
||||
case Reader::RF_JMA: {
|
||||
try {
|
||||
JMAReader jf(rom_fn);
|
||||
load_rom(jf);
|
||||
} catch(JMA::jma_errors jma_error) {
|
||||
alert("Error loading image file (%s)!", rom_fn);
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//remove ROM extension
|
||||
strcpy(sram_fn, fn);
|
||||
char fn[4096], ram_fn[4096];
|
||||
strcpy(fn, rom_fn);
|
||||
//correct folder slashes
|
||||
for(int i = strlen(fn) - 1; i >= 0; i--) {
|
||||
if(sram_fn[i] == '.') {
|
||||
sram_fn[i] = 0;
|
||||
if(fn[i] == '\\')fn[i] = '/';
|
||||
}
|
||||
|
||||
uint i = file.count++;
|
||||
strcpy(file.rom_name[i], fn);
|
||||
|
||||
strcpy(fn, rom_fn);
|
||||
//remove ROM extension
|
||||
for(int i = strlen(fn) - 1; i >= 0; i--) {
|
||||
if(fn[i] == '.') {
|
||||
fn[i] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//add SRAM extension
|
||||
strcat(sram_fn, ".");
|
||||
strcat(sram_fn, config::fs.save_ext.sget());
|
||||
if(i == 0) {
|
||||
strcpy(file.patch_name, fn);
|
||||
strcat(file.patch_name, ".ups");
|
||||
}
|
||||
strcpy(fn, strptr(config::file_updatepath(fn, config::path.save)));
|
||||
if(i == 0) {
|
||||
strcpy(file.cheat_name, fn);
|
||||
strcat(file.cheat_name, ".cht");
|
||||
}
|
||||
strcpy(file.ram_name[i], fn);
|
||||
strcat(file.ram_name[i], ".");
|
||||
strcat(file.ram_name[i], config::path.save_ext);
|
||||
}
|
||||
|
||||
stringarray save_path;
|
||||
strcpy(save_path, config::fs.save_path.sget());
|
||||
replace(save_path, "\\", "/");
|
||||
if(strlen(save_path) && !strend(save_path, "/")) { strcat(save_path, "/"); }
|
||||
|
||||
if(strlen(save_path) != 0) {
|
||||
//override default path (current directory)
|
||||
stringarray new_fn, parts;
|
||||
strcpy(new_fn, sram_fn);
|
||||
replace(new_fn, "\\", "/");
|
||||
split(parts, "/", new_fn);
|
||||
|
||||
//add new SRAM path
|
||||
strcpy(new_fn, save_path);
|
||||
|
||||
//append fs.base_path if fs.sram_path is not fully-qualified path
|
||||
if(strbegin(new_fn, "./") == true) {
|
||||
strltrim(new_fn, "./");
|
||||
strcpy(new_fn[1], new_fn[0]);
|
||||
strcpy(new_fn[0], config::fs.base_path.sget());
|
||||
strcat(new_fn[0], new_fn[1]);
|
||||
}
|
||||
|
||||
//finally, append SRAM file name
|
||||
strcat(new_fn, parts[count(parts) - 1]);
|
||||
strcpy(sram_fn, strptr(new_fn));
|
||||
bool Cartridge::load_end() {
|
||||
for(int i = 0; i < file.count; i++) {
|
||||
load_file(file.rom_name[i], file.rom_data[i], file.rom_size[i]);
|
||||
}
|
||||
|
||||
//load cheat file if it exists
|
||||
strcpy(cheat_fn, sram_fn);
|
||||
strrtrim(cheat_fn, config::fs.save_ext.sget());
|
||||
strrtrim(cheat_fn, ".");
|
||||
strcat(cheat_fn, ".cht");
|
||||
|
||||
if(fexists(cheat_fn) == true) {
|
||||
FileReader ff(cheat_fn);
|
||||
cheat.load(ff);
|
||||
if(fexists(file.cheat_name) == true) {
|
||||
cheat.clear();
|
||||
cheat.load(file.cheat_name);
|
||||
}
|
||||
|
||||
//load patch file if it exists
|
||||
strcpy(patch_fn, sram_fn);
|
||||
strrtrim(patch_fn, config::fs.save_ext.sget());
|
||||
strrtrim(patch_fn, ".");
|
||||
strcat(patch_fn, ".ups");
|
||||
|
||||
if(fexists(patch_fn) == true) {
|
||||
FileReader ff(patch_fn);
|
||||
patch_rom(ff);
|
||||
switch(info.type) {
|
||||
case CART_NORMAL: {
|
||||
load_rom_normal();
|
||||
load_ram_normal();
|
||||
} break;
|
||||
case CART_ST: {
|
||||
load_rom_st();
|
||||
load_ram_st();
|
||||
} break;
|
||||
case CART_STDUAL: {
|
||||
load_rom_stdual();
|
||||
load_ram_stdual();
|
||||
} break;
|
||||
}
|
||||
|
||||
#ifdef GZIP_SUPPORT
|
||||
else {
|
||||
strrtrim(patch_fn, ".ups");
|
||||
strcat(patch_fn, ".upz");
|
||||
if(fexists(patch_fn) == true) {
|
||||
ZipReader zf(patch_fn);
|
||||
patch_rom(zf);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if(read_database() == true) {
|
||||
read_dbi();
|
||||
} else {
|
||||
find_header();
|
||||
read_header();
|
||||
}
|
||||
|
||||
load_sram();
|
||||
cart_loaded = true;
|
||||
|
||||
r_mem->load_cart();
|
||||
return true;
|
||||
}
|
||||
@@ -388,13 +116,23 @@ bool Cartridge::unload() {
|
||||
|
||||
r_mem->unload_cart();
|
||||
|
||||
if(sram) { save_sram(); }
|
||||
SafeFree(rom);
|
||||
SafeFree(sram);
|
||||
switch(info.type) {
|
||||
case CART_NORMAL: {
|
||||
save_ram_normal();
|
||||
} break;
|
||||
case CART_ST: {
|
||||
save_ram_st();
|
||||
} break;
|
||||
case CART_STDUAL: {
|
||||
save_ram_stdual();
|
||||
} break;
|
||||
}
|
||||
|
||||
if(cheat.count() > 0 || fexists(cheat_fn)) {
|
||||
FileWriter ff(cheat_fn);
|
||||
cheat.save(ff);
|
||||
SafeFree(rom);
|
||||
SafeFree(ram);
|
||||
|
||||
if(cheat.count() > 0 || fexists(file.cheat_name) == true) {
|
||||
cheat.save(file.cheat_name);
|
||||
cheat.clear();
|
||||
}
|
||||
|
||||
@@ -407,8 +145,8 @@ Cartridge::Cartridge() {
|
||||
|
||||
cart_loaded = false;
|
||||
|
||||
rom = 0;
|
||||
sram = 0;
|
||||
rom = 0;
|
||||
ram = 0;
|
||||
}
|
||||
|
||||
Cartridge::~Cartridge() {
|
||||
|
||||
+39
-10
@@ -15,10 +15,15 @@ db_item dbi;
|
||||
|
||||
//
|
||||
|
||||
bool cart_loaded;
|
||||
char rom_fn[4096], sram_fn[4096], cheat_fn[4096], patch_fn[4096];
|
||||
enum {
|
||||
CART_NORMAL,
|
||||
CART_ST,
|
||||
CART_STDUAL,
|
||||
};
|
||||
|
||||
uint8 rom_header[512], *rom, *sram;
|
||||
bool cart_loaded;
|
||||
|
||||
uint8 rom_header[512], *rom, *ram;
|
||||
|
||||
enum {
|
||||
//header fields
|
||||
@@ -26,7 +31,7 @@ enum {
|
||||
MAPPER = 0x15,
|
||||
ROM_TYPE = 0x16,
|
||||
ROM_SIZE = 0x17,
|
||||
SRAM_SIZE = 0x18,
|
||||
RAM_SIZE = 0x18,
|
||||
REGION = 0x19,
|
||||
LICENSE = 0x1a,
|
||||
VERSION = 0x1b,
|
||||
@@ -53,6 +58,17 @@ enum {
|
||||
};
|
||||
|
||||
struct {
|
||||
uint count;
|
||||
char cheat_name[4096], patch_name[4096];
|
||||
char rom_name[8][4096], ram_name[8][4096];
|
||||
uint rom_size[8], ram_size[8];
|
||||
uint8 *rom_data[8], *ram_data[8];
|
||||
} file;
|
||||
|
||||
struct {
|
||||
uint type;
|
||||
|
||||
//cart information
|
||||
uint32 crc32;
|
||||
char name[128];
|
||||
char pcb[32];
|
||||
@@ -78,15 +94,28 @@ struct {
|
||||
uint header_index;
|
||||
} info;
|
||||
|
||||
void load_rom(Reader &rf);
|
||||
void patch_rom(Reader &rf);
|
||||
void load_sram();
|
||||
void save_sram();
|
||||
void read_dbi();
|
||||
bool load_file(const char *fn, uint8 *&data, uint &size);
|
||||
bool save_file(const char *fn, uint8 *data, uint size);
|
||||
|
||||
void load_rom_normal();
|
||||
void load_ram_normal();
|
||||
void save_ram_normal();
|
||||
|
||||
void load_rom_st();
|
||||
void load_ram_st();
|
||||
void save_ram_st();
|
||||
|
||||
void load_rom_stdual();
|
||||
void load_ram_stdual();
|
||||
void save_ram_stdual();
|
||||
|
||||
void find_header();
|
||||
void read_header();
|
||||
|
||||
bool loaded() { return cart_loaded; }
|
||||
bool load(const char *fn);
|
||||
void load_begin(uint cart_type);
|
||||
void load(const char *rom_fn);
|
||||
bool load_end();
|
||||
bool unload();
|
||||
|
||||
Cartridge();
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
bool Cartridge::load_file(const char *fn, uint8 *&data, uint &size) {
|
||||
dprintf("* Loading \"%s\"...", fn);
|
||||
|
||||
if(fexists(fn) == false) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(Reader::detect(fn)) {
|
||||
|
||||
case Reader::RF_NORMAL: {
|
||||
FileReader ff(fn);
|
||||
if(!ff.ready()) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
size = ff.size();
|
||||
data = ff.read();
|
||||
} break;
|
||||
|
||||
#ifdef GZIP_SUPPORT
|
||||
case Reader::RF_GZ: {
|
||||
GZReader gf(fn);
|
||||
if(!gf.ready()) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
size = gf.size();
|
||||
data = gf.read();
|
||||
} break;
|
||||
|
||||
case Reader::RF_ZIP: {
|
||||
ZipReader zf(fn);
|
||||
size = zf.size();
|
||||
data = zf.read();
|
||||
} break;
|
||||
#endif
|
||||
|
||||
#ifdef JMA_SUPPORT
|
||||
case Reader::RF_JMA: {
|
||||
try {
|
||||
JMAReader jf(fn);
|
||||
size = jf.size();
|
||||
data = jf.read();
|
||||
} catch(JMA::jma_errors jma_error) {
|
||||
alert("Error loading image file (%s)!", fn);
|
||||
return false;
|
||||
}
|
||||
} break;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cartridge::save_file(const char *fn, uint8 *data, uint size) {
|
||||
FileWriter ff(fn);
|
||||
if(!ff.ready())return false;
|
||||
ff.write(data, size);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
void Cartridge::read_header() {
|
||||
info.srtc = false;
|
||||
info.sdd1 = false;
|
||||
info.c4 = false;
|
||||
info.dsp1 = false;
|
||||
info.dsp2 = false;
|
||||
info.obc1 = false;
|
||||
|
||||
info.dsp1_mapper = 0;
|
||||
|
||||
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[info.header_index + MAPPER];
|
||||
uint8 rom_type = rom[info.header_index + ROM_TYPE];
|
||||
if(mapper == 0x35 && rom_type == 0x55) {
|
||||
info.srtc = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x32 && (rom_type == 0x43 || rom_type == 0x45)) {
|
||||
info.sdd1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x20 && rom_type == 0xf3) {
|
||||
info.c4 = true;
|
||||
}
|
||||
|
||||
if((mapper == 0x20 || mapper == 0x21) && rom_type == 0x03) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x05) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x31 && (rom_type == 0x03 || rom_type == 0x05)) {
|
||||
info.dsp1 = true;
|
||||
}
|
||||
|
||||
if(info.dsp1 == true) {
|
||||
if((mapper & 0x2f) == 0x20 && info.rom_size <= 0x100000) {
|
||||
info.dsp1_mapper = DSP1_LOROM_1MB;
|
||||
} else if((mapper & 0x2f) == 0x20) {
|
||||
info.dsp1_mapper = DSP1_LOROM_2MB;
|
||||
} else if((mapper & 0x2f) == 0x21) {
|
||||
info.dsp1_mapper = DSP1_HIROM;
|
||||
}
|
||||
}
|
||||
|
||||
if(mapper == 0x20 && rom_type == 0x05) {
|
||||
info.dsp2 = true;
|
||||
}
|
||||
|
||||
if(mapper == 0x30 && rom_type == 0x25) {
|
||||
info.obc1 = true;
|
||||
}
|
||||
|
||||
info.cart_mmio = info.c4 | info.dsp1 | info.dsp2 | info.obc1;
|
||||
|
||||
if(rom[info.header_index + RAM_SIZE] & 7) {
|
||||
info.ram_size = 1024 << (rom[info.header_index + RAM_SIZE] & 7);
|
||||
} else {
|
||||
info.ram_size = 0;
|
||||
}
|
||||
|
||||
memcpy(&info.name, &rom[info.header_index + CART_NAME], 21);
|
||||
info.name[21] = 0;
|
||||
|
||||
for(int i = 0; i < 22; i++) {
|
||||
if(info.name[i] & 0x80) {
|
||||
info.name[i] = '?';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::find_header() {
|
||||
int32 score_lo = 0,
|
||||
score_hi = 0,
|
||||
score_ex = 0;
|
||||
|
||||
if(info.rom_size < 0x010000) {
|
||||
//cart too small to be anything but lorom
|
||||
info.header_index = 0x007fc0;
|
||||
return;
|
||||
}
|
||||
|
||||
if((rom[0x7fc0 + MAPPER] & ~0x10) == 0x20)score_lo++;
|
||||
if((rom[0xffc0 + MAPPER] & ~0x10) == 0x21)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + ROM_TYPE] < 0x08)score_lo++;
|
||||
if(rom[0xffc0 + ROM_TYPE] < 0x08)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + ROM_SIZE] < 0x10)score_lo++;
|
||||
if(rom[0xffc0 + ROM_SIZE] < 0x10)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + RAM_SIZE] < 0x08)score_lo++;
|
||||
if(rom[0xffc0 + RAM_SIZE] < 0x08)score_hi++;
|
||||
|
||||
if(rom[0x7fc0 + REGION] < 14)score_lo++;
|
||||
if(rom[0xffc0 + REGION] < 14)score_hi++;
|
||||
|
||||
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);
|
||||
if((cksum + icksum) == 0xffff && (cksum != 0) && (icksum != 0)) {
|
||||
score_lo += 8;
|
||||
}
|
||||
|
||||
cksum = rom[0xffc0 + CKSUM] | (rom[0xffc0 + CKSUM + 1] << 8);
|
||||
icksum = rom[0xffc0 + ICKSUM] | (rom[0xffc0 + ICKSUM + 1] << 8);
|
||||
if((cksum + icksum) == 0xffff && (cksum != 0) && (icksum != 0)) {
|
||||
score_hi += 8;
|
||||
}
|
||||
|
||||
if(info.rom_size < 0x401000) {
|
||||
score_ex = 0;
|
||||
} else {
|
||||
if(rom[0x7fc0 + MAPPER] == 0x32)score_lo++;
|
||||
else score_ex += 16;
|
||||
}
|
||||
|
||||
if(score_lo >= score_hi && score_lo >= score_ex) {
|
||||
info.header_index = 0x007fc0;
|
||||
} else if(score_hi >= score_ex) {
|
||||
info.header_index = 0x00ffc0;
|
||||
} else {
|
||||
info.header_index = 0x40ffc0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
void Cartridge::load_rom_normal() {
|
||||
uint size = 0;
|
||||
for(int i = 0; i < file.count; i++) {
|
||||
size += file.rom_size[i] - (((file.rom_size[i] & 0x7fff) == 512) ? 512 : 0);
|
||||
}
|
||||
|
||||
info.rom_size = size;
|
||||
rom = (uint8*)malloc(info.rom_size);
|
||||
memset(rom, 0, info.rom_size);
|
||||
|
||||
uint offset = 0;
|
||||
for(int i = 0; i < file.count; i++) {
|
||||
uint8 *data = file.rom_data[i] + (((file.rom_size[i] & 0x7fff) == 512) ? 512 : 0);
|
||||
uint size = file.rom_size[i] - (((file.rom_size[i] & 0x7fff) == 512) ? 512 : 0);
|
||||
memcpy(rom + offset, data, size);
|
||||
offset += size;
|
||||
safe_free(file.rom_data[i]);
|
||||
}
|
||||
|
||||
info.crc32 = crc32_calculate(rom, info.rom_size);
|
||||
|
||||
if(read_database() == true) {
|
||||
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 = 0xffc0;
|
||||
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;
|
||||
} else {
|
||||
find_header();
|
||||
read_header();
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::load_ram_normal() {
|
||||
if(info.ram_size == 0) {
|
||||
ram = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
ram = (uint8*)malloc(info.ram_size);
|
||||
memset(ram, 0xff, info.ram_size);
|
||||
|
||||
if(load_file(file.ram_name[0], file.ram_data[0], file.ram_size[0]) == true) {
|
||||
memcpy(ram, file.ram_data[0], min(info.ram_size, file.ram_size[0]));
|
||||
safe_free(file.ram_data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::save_ram_normal() {
|
||||
if(info.ram_size == 0)return;
|
||||
|
||||
save_file(file.ram_name[0], ram, info.ram_size);
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
void Cartridge::load_rom_st() {
|
||||
uint8 *data;
|
||||
uint size;
|
||||
string bios = config::file_updatepath("stbios.bin", config::path.bios);
|
||||
info.rom_size = 0x200000;
|
||||
rom = (uint8*)malloc(info.rom_size);
|
||||
memset(rom, 0, info.rom_size);
|
||||
|
||||
load_file(strptr(bios), data, size);
|
||||
memcpy(rom, data, min(size, 0x040000));
|
||||
safe_free(data);
|
||||
|
||||
memcpy(rom + 0x100000, file.rom_data[0], min(file.rom_size[0], 0x100000));
|
||||
safe_free(file.rom_data[0]);
|
||||
|
||||
//
|
||||
strcpy(info.name, "???");
|
||||
strcpy(info.pcb, "STC-SOLO");
|
||||
|
||||
info.mapper = PCB;
|
||||
info.region = NTSC;
|
||||
|
||||
info.rom_size = 0x200000;
|
||||
info.ram_size = 0x020000;
|
||||
//
|
||||
|
||||
info.crc32 = crc32_calculate(rom + 0x100000, file.rom_size[0]);
|
||||
if(read_database() == true) {
|
||||
strcpy(info.name, dbi.name);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::load_ram_st() {
|
||||
ram = (uint8*)malloc(info.ram_size);
|
||||
memset(ram, 0xff, info.ram_size);
|
||||
|
||||
if(load_file(file.ram_name[0], file.ram_data[0], file.ram_size[0]) == true) {
|
||||
memcpy(ram, file.ram_data[0], min(file.ram_size[0], 0x020000));
|
||||
safe_free(file.ram_data[0]);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::save_ram_st() {
|
||||
save_file(file.ram_name[0], ram, 0x020000);
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
void Cartridge::load_rom_stdual() {
|
||||
uint8 *data;
|
||||
uint size;
|
||||
string bios = config::file_updatepath("stbios.bin", config::path.bios);
|
||||
info.rom_size = 0x300000;
|
||||
rom = (uint8*)malloc(info.rom_size);
|
||||
memset(rom, 0, info.rom_size);
|
||||
|
||||
load_file(strptr(bios), data, size);
|
||||
memcpy(rom, data, min(size, 0x040000));
|
||||
safe_free(data);
|
||||
|
||||
memcpy(rom + 0x100000, file.rom_data[0], min(file.rom_size[0], 0x100000));
|
||||
safe_free(file.rom_data[0]);
|
||||
|
||||
memcpy(rom + 0x200000, file.rom_data[1], min(file.rom_size[1], 0x100000));
|
||||
safe_free(file.rom_data[1]);
|
||||
|
||||
char name_a[4096], name_b[4096];
|
||||
strcpy(name_a, "???");
|
||||
strcpy(name_b, "???");
|
||||
//
|
||||
info.mapper = PCB;
|
||||
info.region = NTSC;
|
||||
|
||||
info.rom_size = 0x300000;
|
||||
info.ram_size = 0x040000;
|
||||
//
|
||||
|
||||
info.crc32 = crc32_calculate(rom + 0x100000, file.rom_size[0]);
|
||||
if(read_database() == true) {
|
||||
strcpy(name_a, dbi.name);
|
||||
}
|
||||
|
||||
info.crc32 = crc32_calculate(rom + 0x200000, file.rom_size[1]);
|
||||
if(read_database() == true) {
|
||||
strcpy(name_b, dbi.name);
|
||||
}
|
||||
|
||||
//
|
||||
info.crc32 = 0;
|
||||
strcpy(info.name, name_a);
|
||||
strcat(info.name, " + ");
|
||||
strcat(info.name, name_b);
|
||||
strcpy(info.pcb, "STC-DUAL");
|
||||
}
|
||||
|
||||
void Cartridge::load_ram_stdual() {
|
||||
ram = (uint8*)malloc(info.ram_size);
|
||||
memset(ram, 0xff, info.ram_size);
|
||||
|
||||
if(load_file(file.ram_name[0], file.ram_data[0], file.ram_size[0]) == true) {
|
||||
memcpy(ram + 0x000000, file.ram_data[0], min(file.ram_size[0], 0x020000));
|
||||
safe_free(file.ram_data[0]);
|
||||
}
|
||||
|
||||
if(load_file(file.ram_name[1], file.ram_data[1], file.ram_size[1]) == true) {
|
||||
memcpy(ram + 0x020000, file.ram_data[1], min(file.ram_size[1], 0x020000));
|
||||
safe_free(file.ram_data[1]);
|
||||
}
|
||||
}
|
||||
|
||||
void Cartridge::save_ram_stdual() {
|
||||
save_file(file.ram_name[0], ram + 0x000000, 0x020000);
|
||||
save_file(file.ram_name[1], ram + 0x020000, 0x020000);
|
||||
}
|
||||
Binary file not shown.
+77
-11
@@ -1,32 +1,98 @@
|
||||
[0xbb5c4238]
|
||||
name = "Bishoujo Senshi Sailor Moon Sailor Stars - Fuwa Fuwa Panic 2 (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 8mbit
|
||||
ram = 32kbit
|
||||
|
||||
[0x8eb753f3]
|
||||
name = "Crayon Shin-chan - Nagagutsu Dobon!! (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[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
|
||||
|
||||
[0x4296500d]
|
||||
name = "Gegege no Kitarou - Youkai Donjara (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 16kbit
|
||||
|
||||
[0x14c66fca]
|
||||
name = "Gekisou Sentai Car Rangers (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x32b2b3dd]
|
||||
name = "Poi Poi Ninja World (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[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
|
||||
[0xafd74dcb]
|
||||
name = "SD Gundam Generation A - Ichinen Sensouki (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x48ecae44]
|
||||
name = "SD Gundam Generation B - Grips Senki (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x72b4235f]
|
||||
name = "SD Gundam Generation C - Axis Senki (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x792d884c]
|
||||
name = "SD Gundam Generation D - Babylonia Kenkoku Senki (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0xefd3a865]
|
||||
name = "SD Gundam Generation E - Zanskar Senki (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0xc5dfa8fd]
|
||||
name = "SD Gundam Generation F - Colony Kakutouki (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x43ad5a45]
|
||||
name = "SD Ultra Battle - Seven Densetsu (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0x04939d14]
|
||||
name = "SD Ultra Battle - Ultra Densetsu (Japan)"
|
||||
pcb = "STC-????"
|
||||
rom = 4mbit
|
||||
ram = 8kbit
|
||||
|
||||
[0xa5c0045e]
|
||||
name = "Secret of Evermore (USA) [!]"
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
FILE *fp;
|
||||
|
||||
uint decode_size(substring &str) {
|
||||
uint decode_size(string &str) {
|
||||
//hex encoding
|
||||
if(strbegin(str, "0x")) {
|
||||
strltrim(str, "0x");
|
||||
@@ -31,8 +31,8 @@ uint decode_size(substring &str) {
|
||||
return strdec(str);
|
||||
}
|
||||
|
||||
void build_block(substring &block) {
|
||||
string line, hashpart, part;
|
||||
void build_block(string &block) {
|
||||
stringarray line, hashpart, part;
|
||||
split(line, "\n", block);
|
||||
|
||||
if(strbegin(line[0], "[") == false) {
|
||||
@@ -58,26 +58,26 @@ db_item dbi;
|
||||
strset(line[i], pos, 0);
|
||||
}
|
||||
|
||||
if(strmatch(line[i], ""))continue;
|
||||
if(line[i] == "")continue;
|
||||
|
||||
split(part, "=", line[i]);
|
||||
strunquote(part[1]);
|
||||
|
||||
if(strmatch(part[0], "name")) {
|
||||
if(part[0] == "name") {
|
||||
strncpy(dbi.name, strptr(part[1]), 128);
|
||||
dbi.name[128] = 0;
|
||||
}
|
||||
|
||||
if(strmatch(part[0], "pcb")) {
|
||||
if(part[0] == "pcb") {
|
||||
strncpy(dbi.pcb, strptr(part[1]), 32);
|
||||
dbi.pcb[31] = 0;
|
||||
}
|
||||
|
||||
if(strmatch(part[0], "rom")) {
|
||||
if(part[0] == "rom") {
|
||||
dbi.rom = decode_size(part[1]);
|
||||
}
|
||||
|
||||
if(strmatch(part[0], "ram")) {
|
||||
if(part[0] == "ram") {
|
||||
dbi.ram = decode_size(part[1]);
|
||||
}
|
||||
}
|
||||
@@ -89,7 +89,7 @@ db_item dbi;
|
||||
}
|
||||
|
||||
void build_database() {
|
||||
string data, block;
|
||||
stringarray data, block;
|
||||
if(strfread(data, "cartdb.txt") == false)return;
|
||||
|
||||
fp = fopen("cart.db", "wb");
|
||||
|
||||
+4
-2
@@ -268,7 +268,8 @@ void Cheat::disable(uint32 n) {
|
||||
* cheat file manipulation routines
|
||||
*****/
|
||||
|
||||
bool Cheat::load(Reader &rf) {
|
||||
bool Cheat::load(const char *fn) {
|
||||
FileReader rf(fn);
|
||||
if(!rf.ready())return false;
|
||||
|
||||
uint8 *raw_data = rf.read();
|
||||
@@ -299,7 +300,8 @@ stringarray data, line;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Cheat::save(Writer &wf) {
|
||||
bool Cheat::save(const char *fn) {
|
||||
FileWriter wf(fn);
|
||||
if(!wf.ready())return false;
|
||||
|
||||
string data;
|
||||
|
||||
+2
-2
@@ -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(const char *fn);
|
||||
bool save(const char *fn);
|
||||
void clear();
|
||||
|
||||
Cheat();
|
||||
|
||||
+21
-21
@@ -10,34 +10,34 @@ void OBC1::power() {
|
||||
}
|
||||
|
||||
void OBC1::reset() {
|
||||
memset(cartridge.sram, 0xff, 0x2000);
|
||||
status.baseptr = (cartridge.sram[0x1ff5] & 1) ? 0x1800 : 0x1c00;
|
||||
status.address = (cartridge.sram[0x1ff6] & 0x7f);
|
||||
status.shift = (cartridge.sram[0x1ff6] & 3) << 1;
|
||||
memset(cartridge.ram, 0xff, 0x2000);
|
||||
status.baseptr = (cartridge.ram[0x1ff5] & 1) ? 0x1800 : 0x1c00;
|
||||
status.address = (cartridge.ram[0x1ff6] & 0x7f);
|
||||
status.shift = (cartridge.ram[0x1ff6] & 3) << 1;
|
||||
}
|
||||
|
||||
uint8 OBC1::read(uint16 addr) {
|
||||
addr &= 0x1fff;
|
||||
|
||||
if((addr & 0x1ff8) != 0x1ff0) {
|
||||
return cartridge.sram[addr];
|
||||
return cartridge.ram[addr];
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x1ff0:
|
||||
return cartridge.sram[status.baseptr + (status.address << 2) + 0];
|
||||
return cartridge.ram[status.baseptr + (status.address << 2) + 0];
|
||||
case 0x1ff1:
|
||||
return cartridge.sram[status.baseptr + (status.address << 2) + 1];
|
||||
return cartridge.ram[status.baseptr + (status.address << 2) + 1];
|
||||
case 0x1ff2:
|
||||
return cartridge.sram[status.baseptr + (status.address << 2) + 2];
|
||||
return cartridge.ram[status.baseptr + (status.address << 2) + 2];
|
||||
case 0x1ff3:
|
||||
return cartridge.sram[status.baseptr + (status.address << 2) + 3];
|
||||
return cartridge.ram[status.baseptr + (status.address << 2) + 3];
|
||||
case 0x1ff4:
|
||||
return cartridge.sram[status.baseptr + (status.address >> 2) + 0x200];
|
||||
return cartridge.ram[status.baseptr + (status.address >> 2) + 0x200];
|
||||
case 0x1ff5:
|
||||
case 0x1ff6:
|
||||
case 0x1ff7:
|
||||
return cartridge.sram[addr];
|
||||
return cartridge.ram[addr];
|
||||
}
|
||||
|
||||
//never used, blocks compiler warning
|
||||
@@ -48,40 +48,40 @@ void OBC1::write(uint16 addr, uint8 data) {
|
||||
addr &= 0x1fff;
|
||||
|
||||
if((addr & 0x1ff8) != 0x1ff0) {
|
||||
cartridge.sram[addr] = data;
|
||||
cartridge.ram[addr] = data;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x1ff0:
|
||||
cartridge.sram[status.baseptr + (status.address << 2) + 0] = data;
|
||||
cartridge.ram[status.baseptr + (status.address << 2) + 0] = data;
|
||||
break;
|
||||
case 0x1ff1:
|
||||
cartridge.sram[status.baseptr + (status.address << 2) + 1] = data;
|
||||
cartridge.ram[status.baseptr + (status.address << 2) + 1] = data;
|
||||
break;
|
||||
case 0x1ff2:
|
||||
cartridge.sram[status.baseptr + (status.address << 2) + 2] = data;
|
||||
cartridge.ram[status.baseptr + (status.address << 2) + 2] = data;
|
||||
break;
|
||||
case 0x1ff3:
|
||||
cartridge.sram[status.baseptr + (status.address << 2) + 3] = data;
|
||||
cartridge.ram[status.baseptr + (status.address << 2) + 3] = data;
|
||||
break;
|
||||
case 0x1ff4: {
|
||||
uint8 temp;
|
||||
temp = cartridge.sram[status.baseptr + (status.address >> 2) + 0x200];
|
||||
temp = cartridge.ram[status.baseptr + (status.address >> 2) + 0x200];
|
||||
temp = (temp & ~(3 << status.shift)) | ((data & 3) << status.shift);
|
||||
cartridge.sram[status.baseptr + (status.address >> 2) + 0x200] = temp;
|
||||
cartridge.ram[status.baseptr + (status.address >> 2) + 0x200] = temp;
|
||||
} break;
|
||||
case 0x1ff5:
|
||||
status.baseptr = (data & 1) ? 0x1800 : 0x1c00;
|
||||
cartridge.sram[addr] = data;
|
||||
cartridge.ram[addr] = data;
|
||||
break;
|
||||
case 0x1ff6:
|
||||
status.address = (data & 0x7f);
|
||||
status.shift = (data & 3) << 1;
|
||||
cartridge.sram[addr] = data;
|
||||
cartridge.ram[addr] = data;
|
||||
break;
|
||||
case 0x1ff7:
|
||||
cartridge.sram[addr] = data;
|
||||
cartridge.ram[addr] = data;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
+66
-32
@@ -2,24 +2,52 @@ Config config_file;
|
||||
|
||||
namespace config {
|
||||
|
||||
Setting FS::base_path(0, "fs.base_path",
|
||||
"Directory that bsnes resides in", "");
|
||||
Setting FS::rom_path(&config_file, "fs.rom_path",
|
||||
"Default path to look for ROM files in (\"\" = use default directory)", "");
|
||||
Setting FS::save_path(&config_file, "fs.save_path",
|
||||
"Default path for all save RAM and cheat files (\"\" = use current directory)", "");
|
||||
string file_updatepath(const char *req_file, const char *req_path) {
|
||||
string file(req_file);
|
||||
replace(file, "\\", "/");
|
||||
if(!req_path || strlen(req_path) == 0) { return file; }
|
||||
|
||||
Setting FS::save_ext(&config_file, "fs.save_ext",
|
||||
string path(req_path);
|
||||
replace(path, "\\", "/");
|
||||
if(!strend(path, "/")) { strcat(path, "/"); }
|
||||
|
||||
if(strbegin(path, "./")) {
|
||||
strltrim(path, "./");
|
||||
string temp;
|
||||
strcpy(temp, config::path.base);
|
||||
strcat(temp, path);
|
||||
strcpy(path, temp);
|
||||
}
|
||||
|
||||
stringarray part;
|
||||
split(part, "/", file);
|
||||
strcat(path, part[count(part) - 1]);
|
||||
return path;
|
||||
}
|
||||
|
||||
Setting Path::base(0, "fs.base_path",
|
||||
"Path that bsnes resides in", "");
|
||||
Setting Path::rom(&config_file, "path.rom",
|
||||
"Default path to look for ROM files in (\"\" = use default directory)", "");
|
||||
Setting Path::save(&config_file, "path.save",
|
||||
"Default path for all save RAM and cheat files (\"\" = use current directory)", "");
|
||||
Setting Path::bios(&config_file, "path.bios",
|
||||
"Path where BIOS file(s) are located\n"
|
||||
"Supported BIOS files:\n"
|
||||
"stbios.bin - Bandai Sufami Turbo"
|
||||
"", "./bios");
|
||||
|
||||
Setting Path::save_ext(&config_file, "path.save_ext",
|
||||
"Extension to be used for all save RAM files", "srm");
|
||||
|
||||
Setting SNES::gamma_ramp(&config_file, "snes.colorfilter.gamma_ramp",
|
||||
"Use precalculated TV-style gamma ramp", true, Setting::TRUE_FALSE);
|
||||
"Use precalculated TV-style gamma ramp", true, Setting::BOOL);
|
||||
Setting SNES::sepia(&config_file, "snes.colorfilter.sepia",
|
||||
"Convert color to sepia tone", false, Setting::TRUE_FALSE);
|
||||
"Convert color to sepia tone", false, Setting::BOOL);
|
||||
Setting SNES::grayscale(&config_file, "snes.colorfilter.grayscale",
|
||||
"Convert color to grayscale tone", false, Setting::TRUE_FALSE);
|
||||
"Convert color to grayscale tone", false, Setting::BOOL);
|
||||
Setting SNES::invert(&config_file, "snes.colorfilter.invert",
|
||||
"Invert output image colors", false, Setting::TRUE_FALSE);
|
||||
"Invert output image colors", false, Setting::BOOL);
|
||||
Setting SNES::contrast(&config_file, "snes.colorfilter.contrast",
|
||||
"Contrast", 0, Setting::DEC);
|
||||
Setting SNES::brightness(&config_file, "snes.colorfilter.brightness",
|
||||
@@ -30,10 +58,10 @@ Setting SNES::gamma(&config_file, "snes.colorfilter.gamma",
|
||||
Setting SNES::ntsc_merge_fields(&config_file, "snes.ntsc_merge_fields",
|
||||
"Merge fields in NTSC video filter\n"
|
||||
"Set to true if using filter at any refresh rate other than 60hz\n"
|
||||
"", true, Setting::TRUE_FALSE);
|
||||
"", true, Setting::BOOL);
|
||||
|
||||
Setting SNES::mute(&config_file, "snes.mute", "Mutes SNES audio output when enabled",
|
||||
false, Setting::TRUE_FALSE);
|
||||
false, Setting::BOOL);
|
||||
|
||||
Setting SNES::controller_port0(&config_file, "snes.controller_port_1",
|
||||
"Controller attached to SNES port 1", ::SNES::DEVICEID_JOYPAD1, Setting::DEC);
|
||||
@@ -43,31 +71,37 @@ Setting SNES::controller_port1(&config_file, "snes.controller_port_2",
|
||||
Setting CPU::ntsc_clock_rate(&config_file, "cpu.ntsc_clock_rate",
|
||||
"NTSC S-CPU clock rate (in hz)", 21477272, Setting::DEC);
|
||||
Setting CPU::pal_clock_rate(&config_file, "cpu.pal_clock_rate",
|
||||
"PAL S-CPU clock rate (in hz)", 21241370, Setting::DEC);
|
||||
"PAL S-CPU clock rate (in hz)", 21281370, Setting::DEC);
|
||||
|
||||
Setting CPU::hdma_enable(0, "cpu.hdma_enable",
|
||||
"Enable HDMA effects", true, Setting::TRUE_FALSE);
|
||||
"Enable HDMA effects", true, Setting::BOOL);
|
||||
|
||||
Setting SMP::ntsc_clock_rate(&config_file, "smp.ntsc_clock_rate",
|
||||
"NTSC S-SMP clock rate (in hz)", 24576000, Setting::DEC);
|
||||
"NTSC S-SMP clock rate (in hz)", 24606720, Setting::DEC);
|
||||
Setting SMP::pal_clock_rate(&config_file, "smp.pal_clock_rate",
|
||||
"PAL S-SMP clock rate (in hz)", 24576000, Setting::DEC);
|
||||
"PAL S-SMP clock rate (in hz)", 24606720, Setting::DEC);
|
||||
|
||||
Setting PPU::render_scanline_position(&config_file, "ppu.render_scanline_position",
|
||||
Setting PPU::Hack::render_scanline_position(&config_file, "ppu.hack.render_scanline_position",
|
||||
"Approximate HCLOCK position to render at for scanline-based renderers",
|
||||
256, Setting::DEC);
|
||||
Setting PPU::opt_enable(0, "ppu.opt_enable", "Enable offset-per-tile effects", true, Setting::TRUE_FALSE);
|
||||
512, Setting::DEC);
|
||||
Setting PPU::Hack::obj_cache(&config_file, "ppu.hack.obj_cache",
|
||||
"Cache OAM OBJ attributes one scanline before rendering\n"
|
||||
"This is technically closer to the actual operation of the SNES,\n"
|
||||
"but can cause problems in many games if enabled",
|
||||
false, Setting::BOOL);
|
||||
|
||||
Setting PPU::bg1_pri0_enable(0, "ppu.bg1_pri0_enable", "Enable BG1 Priority 0", true, Setting::TRUE_FALSE);
|
||||
Setting PPU::bg1_pri1_enable(0, "ppu.bg1_pri1_enable", "Enable BG1 Priority 1", true, Setting::TRUE_FALSE);
|
||||
Setting PPU::bg2_pri0_enable(0, "ppu.bg2_pri0_enable", "Enable BG2 Priority 0", true, Setting::TRUE_FALSE);
|
||||
Setting PPU::bg2_pri1_enable(0, "ppu.bg2_pri1_enable", "Enable BG2 Priority 1", true, Setting::TRUE_FALSE);
|
||||
Setting PPU::bg3_pri0_enable(0, "ppu.bg3_pri0_enable", "Enable BG3 Priority 0", true, Setting::TRUE_FALSE);
|
||||
Setting PPU::bg3_pri1_enable(0, "ppu.bg3_pri1_enable", "Enable BG3 Priority 1", true, Setting::TRUE_FALSE);
|
||||
Setting PPU::bg4_pri0_enable(0, "ppu.bg4_pri0_enable", "Enable BG4 Priority 0", true, Setting::TRUE_FALSE);
|
||||
Setting PPU::bg4_pri1_enable(0, "ppu.bg4_pri1_enable", "Enable BG4 Priority 1", true, Setting::TRUE_FALSE);
|
||||
Setting PPU::oam_pri0_enable(0, "ppu.oam_pri0_enable", "Enable OAM Priority 0", true, Setting::TRUE_FALSE);
|
||||
Setting PPU::oam_pri1_enable(0, "ppu.oam_pri1_enable", "Enable OAM Priority 1", true, Setting::TRUE_FALSE);
|
||||
Setting PPU::oam_pri2_enable(0, "ppu.oam_pri2_enable", "Enable OAM Priority 2", true, Setting::TRUE_FALSE);
|
||||
Setting PPU::oam_pri3_enable(0, "ppu.oam_pri3_enable", "Enable OAM Priority 3", true, Setting::TRUE_FALSE);
|
||||
Setting PPU::opt_enable(0, "ppu.opt_enable", "Enable offset-per-tile effects", true, Setting::BOOL);
|
||||
Setting PPU::bg1_pri0_enable(0, "ppu.bg1_pri0_enable", "Enable BG1 Priority 0", true, Setting::BOOL);
|
||||
Setting PPU::bg1_pri1_enable(0, "ppu.bg1_pri1_enable", "Enable BG1 Priority 1", true, Setting::BOOL);
|
||||
Setting PPU::bg2_pri0_enable(0, "ppu.bg2_pri0_enable", "Enable BG2 Priority 0", true, Setting::BOOL);
|
||||
Setting PPU::bg2_pri1_enable(0, "ppu.bg2_pri1_enable", "Enable BG2 Priority 1", true, Setting::BOOL);
|
||||
Setting PPU::bg3_pri0_enable(0, "ppu.bg3_pri0_enable", "Enable BG3 Priority 0", true, Setting::BOOL);
|
||||
Setting PPU::bg3_pri1_enable(0, "ppu.bg3_pri1_enable", "Enable BG3 Priority 1", true, Setting::BOOL);
|
||||
Setting PPU::bg4_pri0_enable(0, "ppu.bg4_pri0_enable", "Enable BG4 Priority 0", true, Setting::BOOL);
|
||||
Setting PPU::bg4_pri1_enable(0, "ppu.bg4_pri1_enable", "Enable BG4 Priority 1", true, Setting::BOOL);
|
||||
Setting PPU::oam_pri0_enable(0, "ppu.oam_pri0_enable", "Enable OAM Priority 0", true, Setting::BOOL);
|
||||
Setting PPU::oam_pri1_enable(0, "ppu.oam_pri1_enable", "Enable OAM Priority 1", true, Setting::BOOL);
|
||||
Setting PPU::oam_pri2_enable(0, "ppu.oam_pri2_enable", "Enable OAM Priority 2", true, Setting::BOOL);
|
||||
Setting PPU::oam_pri3_enable(0, "ppu.oam_pri3_enable", "Enable OAM Priority 3", true, Setting::BOOL);
|
||||
|
||||
};
|
||||
+10
-5
@@ -2,10 +2,12 @@ extern Config config_file;
|
||||
|
||||
namespace config {
|
||||
|
||||
extern struct FS {
|
||||
static Setting base_path, rom_path, save_path;
|
||||
string file_updatepath(const char *, const char *);
|
||||
|
||||
extern struct Path {
|
||||
static Setting base, rom, save, bios;
|
||||
static Setting save_ext;
|
||||
} fs;
|
||||
} path;
|
||||
|
||||
extern struct SNES {
|
||||
static Setting gamma_ramp, sepia, grayscale, invert, contrast, brightness, gamma;
|
||||
@@ -25,9 +27,12 @@ extern struct SMP {
|
||||
} smp;
|
||||
|
||||
extern struct PPU {
|
||||
static Setting render_scanline_position;
|
||||
static Setting opt_enable;
|
||||
struct Hack {
|
||||
static Setting render_scanline_position;
|
||||
static Setting obj_cache;
|
||||
} hack;
|
||||
|
||||
static Setting opt_enable;
|
||||
static Setting bg1_pri0_enable, bg1_pri1_enable;
|
||||
static Setting bg2_pri0_enable, bg2_pri1_enable;
|
||||
static Setting bg3_pri0_enable, bg3_pri1_enable;
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
#include "../../base.h"
|
||||
|
||||
#include "core/core.cpp"
|
||||
#include "memory/memory.cpp"
|
||||
#include "dma/dma.cpp"
|
||||
#include "timing/timing.cpp"
|
||||
|
||||
#include "bcpu_exec.cpp"
|
||||
#include "bcpu_mmio.cpp"
|
||||
#include "bcpu_int.cpp"
|
||||
|
||||
uint8 bCPU::pio_status() { return status.pio; }
|
||||
|
||||
void bCPU::run() {
|
||||
if(run_state.hdma) {
|
||||
exec_hdma();
|
||||
return;
|
||||
}
|
||||
|
||||
if(run_state.dma) {
|
||||
exec_dma();
|
||||
return;
|
||||
}
|
||||
|
||||
if(status.cycle_pos == 0) { //interrupts only trigger on opcode edges
|
||||
if(run_state.irq && !run_state.stp) {
|
||||
run_state.irq = false;
|
||||
if(time.nmi_pending == true) {
|
||||
time.nmi_pending = false;
|
||||
aa.w = (regs.e == false) ? 0xffea : 0xfffa;
|
||||
} else if(time.irq_pending == true) {
|
||||
time.irq_pending = false;
|
||||
aa.w = (regs.e == false) ? 0xffee : 0xfffe;
|
||||
}
|
||||
irq_run();
|
||||
}
|
||||
}
|
||||
|
||||
exec_cycle();
|
||||
}
|
||||
|
||||
void bCPU::power() {
|
||||
region = snes->region();
|
||||
|
||||
regs.a = regs.x = regs.y = 0x0000;
|
||||
regs.s = 0x01ff;
|
||||
reset();
|
||||
}
|
||||
|
||||
void bCPU::reset() {
|
||||
//reset vector location
|
||||
regs.pc.d = 0;
|
||||
regs.pc.l = r_mem->read(0xfffc);
|
||||
regs.pc.h = r_mem->read(0xfffd);
|
||||
|
||||
//registers are not fully reset by SNES
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
regs.s.h = 0x01;
|
||||
regs.d = 0x0000;
|
||||
regs.db = 0x00;
|
||||
regs.p = 0x34;
|
||||
regs.e = 1;
|
||||
regs.mdr = 0x00;
|
||||
|
||||
time_reset();
|
||||
mmio_reset();
|
||||
dma_reset();
|
||||
|
||||
run_state.hdma = false;
|
||||
run_state.dma = false;
|
||||
run_state.irq = false;
|
||||
run_state.wai = false;
|
||||
run_state.stp = false;
|
||||
|
||||
status.cycle_pos = 0;
|
||||
status.cycle_count = 0;
|
||||
status.cycles_executed = 0;
|
||||
|
||||
apu_port[0] = 0x00;
|
||||
apu_port[1] = 0x00;
|
||||
apu_port[2] = 0x00;
|
||||
apu_port[3] = 0x00;
|
||||
|
||||
frame();
|
||||
|
||||
//initial latch values for $213c/$213d
|
||||
//[x]0035 : [y]0000 (53.0 -> 212) [lda $2137]
|
||||
//[x]0038 : [y]0000 (56.5 -> 226) [nop : lda $2137]
|
||||
add_cycles(186);
|
||||
}
|
||||
|
||||
bCPU::bCPU() {
|
||||
init_op_tables();
|
||||
}
|
||||
|
||||
bCPU::~bCPU() {}
|
||||
@@ -1,165 +0,0 @@
|
||||
class bCPU : public CPU {
|
||||
public:
|
||||
#include "core/core.h"
|
||||
#include "memory/memory.h"
|
||||
#include "dma/dma.h"
|
||||
#include "timing/timing.h"
|
||||
|
||||
enum { NTSC = 0, PAL = 1 };
|
||||
uint8 region;
|
||||
|
||||
enum {
|
||||
DMASTATE_DMASYNC,
|
||||
DMASTATE_DMASYNC2,
|
||||
DMASTATE_DMASYNC3,
|
||||
DMASTATE_RUN,
|
||||
DMASTATE_CPUSYNC,
|
||||
|
||||
HDMASTATE_IDMASYNC,
|
||||
HDMASTATE_IDMASYNC2,
|
||||
HDMASTATE_IDMASYNC3,
|
||||
HDMASTATE_ICPUSYNC,
|
||||
|
||||
HDMASTATE_DMASYNC,
|
||||
HDMASTATE_DMASYNC2,
|
||||
HDMASTATE_DMASYNC3,
|
||||
HDMASTATE_RUN,
|
||||
HDMASTATE_CPUSYNC
|
||||
};
|
||||
|
||||
struct {
|
||||
bool hdma;
|
||||
bool dma;
|
||||
bool irq;
|
||||
bool stp;
|
||||
bool wai;
|
||||
} run_state;
|
||||
|
||||
struct {
|
||||
uint8 cycle_pos, cycle_count;
|
||||
uint8 opcode;
|
||||
uint32 cycles_executed;
|
||||
|
||||
uint8 dma_state, hdma_state;
|
||||
uint32 dma_cycle_count, hdma_cycle_count;
|
||||
|
||||
//$4207-$420a
|
||||
uint16 virq_trigger, hirq_trigger;
|
||||
|
||||
//$2181-$2183
|
||||
uint32 wram_addr;
|
||||
|
||||
//$4016-$4017
|
||||
bool joypad_strobe_latch;
|
||||
uint8 joypad1_read_pos, joypad2_read_pos;
|
||||
|
||||
//$4200
|
||||
bool nmi_enabled;
|
||||
bool hirq_enabled, virq_enabled;
|
||||
bool auto_joypad_poll;
|
||||
|
||||
//$4201
|
||||
uint8 pio;
|
||||
|
||||
//$4202-$4203
|
||||
uint8 mul_a, mul_b;
|
||||
|
||||
//$4204-$4206
|
||||
uint16 div_a;
|
||||
uint8 div_b;
|
||||
|
||||
//$4207-$420a
|
||||
uint16 hirq_pos, virq_pos;
|
||||
|
||||
//$4214-$4216
|
||||
uint16 r4214;
|
||||
uint16 r4216;
|
||||
} status;
|
||||
|
||||
inline bool hdma_test();
|
||||
inline bool nmi_test();
|
||||
inline bool irq_test();
|
||||
|
||||
inline uint8 pio_status();
|
||||
inline void run();
|
||||
inline uint32 clocks_executed();
|
||||
inline void power();
|
||||
inline void reset();
|
||||
|
||||
inline void irq_run();
|
||||
|
||||
//mmio commands
|
||||
void mmio_reset();
|
||||
uint8 mmio_r2180();
|
||||
uint8 mmio_r4016();
|
||||
uint8 mmio_r4017();
|
||||
uint8 mmio_r4210();
|
||||
uint8 mmio_r4211();
|
||||
uint8 mmio_r4212();
|
||||
uint8 mmio_r4213();
|
||||
uint8 mmio_r4214();
|
||||
uint8 mmio_r4215();
|
||||
uint8 mmio_r4216();
|
||||
uint8 mmio_r4217();
|
||||
uint8 mmio_r4218();
|
||||
uint8 mmio_r4219();
|
||||
uint8 mmio_r421a();
|
||||
uint8 mmio_r421b();
|
||||
uint8 mmio_r43x0(uint8 i);
|
||||
uint8 mmio_r43x1(uint8 i);
|
||||
uint8 mmio_r43x2(uint8 i);
|
||||
uint8 mmio_r43x3(uint8 i);
|
||||
uint8 mmio_r43x4(uint8 i);
|
||||
uint8 mmio_r43x5(uint8 i);
|
||||
uint8 mmio_r43x6(uint8 i);
|
||||
uint8 mmio_r43x7(uint8 i);
|
||||
uint8 mmio_r43x8(uint8 i);
|
||||
uint8 mmio_r43x9(uint8 i);
|
||||
uint8 mmio_r43xa(uint8 i);
|
||||
uint8 mmio_r43xb(uint8 i);
|
||||
void mmio_w2180(uint8 value);
|
||||
void mmio_w2181(uint8 value);
|
||||
void mmio_w2182(uint8 value);
|
||||
void mmio_w2183(uint8 value);
|
||||
void mmio_w4016(uint8 value);
|
||||
void mmio_w4200(uint8 value);
|
||||
void mmio_w4201(uint8 value);
|
||||
void mmio_w4202(uint8 value);
|
||||
void mmio_w4203(uint8 value);
|
||||
void mmio_w4204(uint8 value);
|
||||
void mmio_w4205(uint8 value);
|
||||
void mmio_w4206(uint8 value);
|
||||
void mmio_w4207(uint8 value);
|
||||
void mmio_w4208(uint8 value);
|
||||
void mmio_w4209(uint8 value);
|
||||
void mmio_w420a(uint8 value);
|
||||
void mmio_w420b(uint8 value);
|
||||
void mmio_w420c(uint8 value);
|
||||
void mmio_w420d(uint8 value);
|
||||
void mmio_w43x0(uint8 value, uint8 i);
|
||||
void mmio_w43x1(uint8 value, uint8 i);
|
||||
void mmio_w43x2(uint8 value, uint8 i);
|
||||
void mmio_w43x3(uint8 value, uint8 i);
|
||||
void mmio_w43x4(uint8 value, uint8 i);
|
||||
void mmio_w43x5(uint8 value, uint8 i);
|
||||
void mmio_w43x6(uint8 value, uint8 i);
|
||||
void mmio_w43x7(uint8 value, uint8 i);
|
||||
void mmio_w43x8(uint8 value, uint8 i);
|
||||
void mmio_w43x9(uint8 value, uint8 i);
|
||||
void mmio_w43xa(uint8 value, uint8 i);
|
||||
void mmio_w43xb(uint8 value, uint8 i);
|
||||
|
||||
uint8 mmio_read (uint16 addr);
|
||||
void mmio_write(uint16 addr, uint8 data);
|
||||
|
||||
enum { CYCLE_OPREAD, CYCLE_READ, CYCLE_WRITE, CYCLE_IO };
|
||||
inline void pre_exec_cycle();
|
||||
inline void exec_hdma();
|
||||
inline void exec_dma();
|
||||
inline void exec_cycle();
|
||||
inline void last_cycle();
|
||||
inline bool in_opcode();
|
||||
|
||||
bCPU();
|
||||
~bCPU();
|
||||
};
|
||||
@@ -1,163 +0,0 @@
|
||||
void bCPU::last_cycle() {
|
||||
time.nmi_pending |= nmi_test();
|
||||
time.irq_pending |= irq_test();
|
||||
|
||||
run_state.irq = (time.nmi_pending || time.irq_pending);
|
||||
}
|
||||
|
||||
void bCPU::pre_exec_cycle() {
|
||||
if(!run_state.dma && !run_state.hdma)return;
|
||||
|
||||
int c, z;
|
||||
if(run_state.hdma) {
|
||||
switch(status.hdma_state) {
|
||||
case HDMASTATE_ICPUSYNC:
|
||||
case HDMASTATE_CPUSYNC:
|
||||
c = status.cycle_count;
|
||||
z = c - (status.hdma_cycle_count % c);
|
||||
if(!z)z = c;
|
||||
add_cycles(z);
|
||||
run_state.hdma = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(run_state.dma) {
|
||||
switch(status.dma_state) {
|
||||
case DMASTATE_CPUSYNC:
|
||||
c = status.cycle_count;
|
||||
z = c - (status.dma_cycle_count % c);
|
||||
if(!z)z = c;
|
||||
add_cycles(z);
|
||||
run_state.dma = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::exec_hdma() {
|
||||
int n;
|
||||
static int z;
|
||||
switch(status.hdma_state) {
|
||||
case HDMASTATE_IDMASYNC:
|
||||
status.hdma_cycle_count = 0;
|
||||
z = 0;
|
||||
if(!run_state.dma) {
|
||||
exec_cycle();
|
||||
status.hdma_state = HDMASTATE_IDMASYNC2;
|
||||
} else {
|
||||
status.hdma_state = HDMASTATE_IDMASYNC3;
|
||||
}
|
||||
break;
|
||||
case HDMASTATE_IDMASYNC2:
|
||||
n = 8 - dma_counter() + 8;
|
||||
add_cycles(n);
|
||||
status.hdma_cycle_count += n;
|
||||
status.hdma_state = HDMASTATE_IDMASYNC3;
|
||||
break;
|
||||
case HDMASTATE_IDMASYNC3:
|
||||
hdma_init();
|
||||
if(!run_state.dma) {
|
||||
status.hdma_state = HDMASTATE_ICPUSYNC;
|
||||
} else {
|
||||
run_state.hdma = false;
|
||||
}
|
||||
break;
|
||||
case HDMASTATE_ICPUSYNC:
|
||||
exec_cycle();
|
||||
break;
|
||||
|
||||
case HDMASTATE_DMASYNC:
|
||||
status.hdma_cycle_count = 0;
|
||||
z = 0;
|
||||
if(!run_state.dma) {
|
||||
exec_cycle();
|
||||
status.hdma_state = HDMASTATE_DMASYNC2;
|
||||
} else {
|
||||
status.hdma_state = HDMASTATE_DMASYNC3;
|
||||
}
|
||||
break;
|
||||
case HDMASTATE_DMASYNC2:
|
||||
n = 8 - dma_counter() + 8;
|
||||
add_cycles(n);
|
||||
status.hdma_cycle_count += n;
|
||||
status.hdma_state = HDMASTATE_DMASYNC3;
|
||||
break;
|
||||
case HDMASTATE_DMASYNC3:
|
||||
if(channel[z].hdma_line_counter) {
|
||||
add_cycles(8);
|
||||
status.hdma_cycle_count += 8;
|
||||
}
|
||||
if(++z < 8)break;
|
||||
status.hdma_state = HDMASTATE_RUN;
|
||||
break;
|
||||
case HDMASTATE_RUN:
|
||||
hdma_run(); //updates status.hdma_cycle_count
|
||||
if(!run_state.dma) {
|
||||
status.hdma_state = HDMASTATE_CPUSYNC;
|
||||
} else {
|
||||
run_state.hdma = false;
|
||||
}
|
||||
break;
|
||||
case HDMASTATE_CPUSYNC:
|
||||
exec_cycle();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::exec_dma() {
|
||||
int n;
|
||||
static int z;
|
||||
switch(status.dma_state) {
|
||||
case DMASTATE_DMASYNC:
|
||||
exec_cycle();
|
||||
status.dma_state = DMASTATE_DMASYNC2;
|
||||
break;
|
||||
case DMASTATE_DMASYNC2:
|
||||
n = 8 - dma_counter() + 8;
|
||||
add_cycles(n);
|
||||
status.dma_cycle_count = n;
|
||||
z = 0;
|
||||
status.dma_state = DMASTATE_DMASYNC3;
|
||||
break;
|
||||
case DMASTATE_DMASYNC3:
|
||||
if(channel[z].dma_enabled == true) {
|
||||
add_cycles(8);
|
||||
status.dma_cycle_count += 8;
|
||||
}
|
||||
if(++z < 8)break;
|
||||
status.dma_state = DMASTATE_RUN;
|
||||
break;
|
||||
case DMASTATE_RUN:
|
||||
dma_run(); //updates status.dma_cycle_count
|
||||
cycle_edge();
|
||||
break;
|
||||
case DMASTATE_CPUSYNC:
|
||||
exec_cycle();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::exec_cycle() {
|
||||
if(status.cycle_pos) {
|
||||
(this->*optbl[status.opcode])();
|
||||
#ifdef DEBUGGER
|
||||
if(status.cycle_pos == 0) {
|
||||
snes->notify(SNES::CPU_EXEC_OPCODE_END);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
//on first cycle?
|
||||
#ifdef DEBUGGER
|
||||
snes->notify(SNES::CPU_EXEC_OPCODE_BEGIN);
|
||||
#endif
|
||||
status.opcode = op_readpc();
|
||||
status.cycle_pos = 1;
|
||||
}
|
||||
|
||||
//only return true when we are on an opcode edge
|
||||
bool bCPU::in_opcode() {
|
||||
return (status.cycle_pos != 0);
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
void bCPU::irq_run() {
|
||||
mem_read(regs.pc.d);
|
||||
cpu_io();
|
||||
if(!regs.e)op_writestack(regs.pc.b);
|
||||
op_writestack(regs.pc.h);
|
||||
op_writestack(regs.pc.l);
|
||||
op_writestack(regs.e ? (regs.p & ~0x10) : regs.p);
|
||||
rd.l = op_readaddr(aa.w + 0);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
rd.h = op_readaddr(aa.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
#ifdef DEBUGGER
|
||||
//let debugger know the new IRQ opcode address
|
||||
snes->notify(SNES::CPU_EXEC_OPCODE_END);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool bCPU::nmi_test() {
|
||||
if(time.nmi_transition == 0)return false;
|
||||
time.nmi_transition = 0;
|
||||
|
||||
run_state.wai = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool bCPU::irq_test() {
|
||||
if(time.irq_transition == 1)goto _true;
|
||||
|
||||
if(time.irq_read == 0) {
|
||||
if(time.irq_line == 1 && (irq_trigger_pos_match(0) || irq_trigger_pos_match(2))) {
|
||||
return false;
|
||||
}
|
||||
goto _true;
|
||||
}
|
||||
|
||||
if(time.irq_line == 0) {
|
||||
time.irq_line = 1;
|
||||
goto _true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
_true:
|
||||
time.irq_transition = 0;
|
||||
|
||||
run_state.wai = false;
|
||||
return (regs.p.i) ? false : true;
|
||||
}
|
||||
@@ -1,650 +0,0 @@
|
||||
void bCPU::mmio_reset() {
|
||||
//$2181-$2183
|
||||
status.wram_addr = 0x000000;
|
||||
|
||||
//$4016-$4017
|
||||
status.joypad_strobe_latch = 0;
|
||||
status.joypad1_read_pos = 0;
|
||||
status.joypad2_read_pos = 0;
|
||||
|
||||
//$4200
|
||||
status.nmi_enabled = false;
|
||||
status.hirq_enabled = false;
|
||||
status.virq_enabled = false;
|
||||
status.auto_joypad_poll = false;
|
||||
|
||||
//$4201
|
||||
status.pio = 0xff;
|
||||
|
||||
//$4202-$4203
|
||||
status.mul_a = 0xff;
|
||||
status.mul_b = 0xff;
|
||||
|
||||
//$4204-$4206
|
||||
status.div_a = 0xffff;
|
||||
status.div_b = 0xff;
|
||||
|
||||
//$4207-$420a
|
||||
status.hirq_pos = 0x01ff;
|
||||
status.virq_pos = 0x01ff;
|
||||
|
||||
//$4214-$4217
|
||||
status.r4214 = 0x0000;
|
||||
status.r4216 = 0x0000;
|
||||
}
|
||||
|
||||
//WMDATA
|
||||
uint8 bCPU::mmio_r2180() {
|
||||
uint8 r;
|
||||
r = r_mem->read(0x7e0000 | status.wram_addr);
|
||||
status.wram_addr++;
|
||||
status.wram_addr &= 0x01ffff;
|
||||
return r;
|
||||
}
|
||||
|
||||
//JOYSER0
|
||||
//7-2 = MDR
|
||||
//1-0 = Joypad serial data
|
||||
/* The joypad contains a small bit shifter that has 16 bits.
|
||||
* Reading from 4016 reads one bit from this buffer, then moves
|
||||
* the buffer left one, and adds a '1' to the rightmost bit.
|
||||
* Writing a one to $4016 will fill the buffer with the current
|
||||
* joypad button states, and lock the bit shifter at position
|
||||
* zero. All reads will be the first buffer state, or 'B'.
|
||||
* A zero must be written back to $4016 to unlock the buffer,
|
||||
* so that reads will increment the bit shifting position.
|
||||
*/
|
||||
uint8 bCPU::mmio_r4016() {
|
||||
uint8 r;
|
||||
r = regs.mdr & 0xfc;
|
||||
|
||||
if(status.joypad_strobe_latch == 1) {
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_B);
|
||||
} else {
|
||||
switch(status.joypad1_read_pos) {
|
||||
case 0: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_B); break;
|
||||
case 1: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_Y); break;
|
||||
case 2: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_SELECT); break;
|
||||
case 3: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_START); break;
|
||||
case 4: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_UP); break;
|
||||
case 5: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_DOWN); break;
|
||||
case 6: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_LEFT); break;
|
||||
case 7: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_RIGHT); break;
|
||||
case 8: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_A); break;
|
||||
case 9: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_X); break;
|
||||
case 10: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_L); break;
|
||||
case 11: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_R); break;
|
||||
case 12: break;
|
||||
case 13: break;
|
||||
case 14: break;
|
||||
case 15: break; //bits 12-15 always return 0
|
||||
//all subsequent reads return joypad connection status
|
||||
case 16: r |= 1; break; //joypad connected bit
|
||||
}
|
||||
if(++status.joypad1_read_pos > 16)status.joypad1_read_pos = 16;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//JOYSER1
|
||||
//7-5 = MDR
|
||||
//4-2 = Always 1 (pins are connected to GND)
|
||||
//1-0 = Joypad serial data
|
||||
uint8 bCPU::mmio_r4017() {
|
||||
uint8 r;
|
||||
r = regs.mdr & 0xe0;
|
||||
r |= 0x1c;
|
||||
|
||||
if(status.joypad_strobe_latch == 1) {
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_B);
|
||||
} else {
|
||||
switch(status.joypad2_read_pos) {
|
||||
case 0: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_B); break;
|
||||
case 1: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_Y); break;
|
||||
case 2: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_SELECT); break;
|
||||
case 3: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_START); break;
|
||||
case 4: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_UP); break;
|
||||
case 5: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_DOWN); break;
|
||||
case 6: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_LEFT); break;
|
||||
case 7: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_RIGHT); break;
|
||||
case 8: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_A); break;
|
||||
case 9: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_X); break;
|
||||
case 10: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_L); break;
|
||||
case 11: r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_R); break;
|
||||
case 12: break;
|
||||
case 13: break;
|
||||
case 14: break;
|
||||
case 15: break; //bits 12-15 always return 0
|
||||
//all subsequent reads return joypad connection status
|
||||
case 16: r |= 1; break; //joypad connected bit
|
||||
}
|
||||
if(++status.joypad2_read_pos > 16)status.joypad2_read_pos = 16;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//RDNMI
|
||||
//7 = NMI acknowledge
|
||||
//6-4 = MDR
|
||||
//3-0 = CPU (5a22) version
|
||||
uint8 bCPU::mmio_r4210() {
|
||||
uint8 r;
|
||||
r = regs.mdr & 0x70;
|
||||
r |= uint8(!time.nmi_read) << 7;
|
||||
|
||||
if(!nmi_trigger_pos_match(0) && !nmi_trigger_pos_match(2)) {
|
||||
time.nmi_read = 1;
|
||||
}
|
||||
|
||||
r |= (cpu_version & 0x0f);
|
||||
return r;
|
||||
}
|
||||
|
||||
//TIMEUP
|
||||
//7 = IRQ acknowledge
|
||||
//6-0 = MDR
|
||||
uint8 bCPU::mmio_r4211() {
|
||||
uint8 r;
|
||||
r = regs.mdr & 0x7f;
|
||||
r |= uint8(!time.irq_read) << 7;
|
||||
|
||||
if(!irq_trigger_pos_match(0) && !irq_trigger_pos_match(2)) {
|
||||
time.irq_read = 1;
|
||||
time.irq_line = 1;
|
||||
time.irq_transition = 0;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//HVBJOY
|
||||
//7 = in vblank
|
||||
//6 = in hblank
|
||||
//5-1 = MDR
|
||||
//0 = joypad ready
|
||||
uint8 bCPU::mmio_r4212() {
|
||||
uint8 r;
|
||||
r = regs.mdr & 0x3e;
|
||||
|
||||
uint16 vs = overscan() ? 240 : 225;
|
||||
|
||||
//auto joypad polling
|
||||
if(time.v >= vs && time.v <= (vs + 2))r |= 0x01;
|
||||
|
||||
//hblank
|
||||
if(time.hc <= 2 || time.hc >= 1096)r |= 0x40;
|
||||
|
||||
//vblank
|
||||
if(time.v >= vs)r |= 0x80;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
//RDIO
|
||||
uint8 bCPU::mmio_r4213() {
|
||||
return status.pio;
|
||||
}
|
||||
|
||||
//RDDIVL
|
||||
uint8 bCPU::mmio_r4214() {
|
||||
return status.r4214;
|
||||
}
|
||||
|
||||
//RDDIVH
|
||||
uint8 bCPU::mmio_r4215() {
|
||||
return status.r4214 >> 8;
|
||||
}
|
||||
|
||||
//RDMPYL
|
||||
uint8 bCPU::mmio_r4216() {
|
||||
return status.r4216;
|
||||
}
|
||||
|
||||
//RDMPYH
|
||||
uint8 bCPU::mmio_r4217() {
|
||||
return status.r4216 >> 8;
|
||||
}
|
||||
|
||||
//JOY1L
|
||||
uint8 bCPU::mmio_r4218() {
|
||||
uint8 r = 0x00;
|
||||
uint16 v = vcounter();
|
||||
if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled
|
||||
//if(v >= 225 && v <= 227)return 0x00; //can't read joypad while SNES is polling input
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_A) << 7;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_X) << 6;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_L) << 5;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_R) << 4;
|
||||
return r;
|
||||
}
|
||||
|
||||
//JOY1H
|
||||
uint8 bCPU::mmio_r4219() {
|
||||
uint8 r = 0x00;
|
||||
uint16 v = vcounter();
|
||||
if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled
|
||||
//if(v >= 225 && v <= 227)return 0x00; //can't read joypad while SNES is polling input
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_B) << 7;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_Y) << 6;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_SELECT) << 5;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_START) << 4;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_UP) << 3;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_DOWN) << 2;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_LEFT) << 1;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD1, SNES::JOYPAD_RIGHT);
|
||||
return r;
|
||||
}
|
||||
|
||||
//JOY2L
|
||||
uint8 bCPU::mmio_r421a() {
|
||||
uint8 r = 0x00;
|
||||
uint16 v = vcounter();
|
||||
if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled
|
||||
//if(v >= 225 && v <= 227)return 0x00; //can't read joypad while SNES is polling input
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_A) << 7;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_X) << 6;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_L) << 5;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_R) << 4;
|
||||
return r;
|
||||
}
|
||||
|
||||
//JOY2H
|
||||
uint8 bCPU::mmio_r421b() {
|
||||
uint8 r = 0x00;
|
||||
uint16 v = vcounter();
|
||||
if(status.auto_joypad_poll == false)return 0x00; //can't read joypad if auto polling not enabled
|
||||
//if(v >= 225 && v <= 227)return 0x00; //can't read joypad while SNES is polling input
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_B) << 7;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_Y) << 6;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_SELECT) << 5;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_START) << 4;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_UP) << 3;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_DOWN) << 2;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_LEFT) << 1;
|
||||
r |= (uint8)snes->get_input_status(SNES::DEVICEID_JOYPAD2, SNES::JOYPAD_RIGHT);
|
||||
return r;
|
||||
}
|
||||
|
||||
//DMAPx
|
||||
uint8 bCPU::mmio_r43x0(uint8 i) {
|
||||
return channel[i].dmap;
|
||||
}
|
||||
|
||||
//BBADx
|
||||
uint8 bCPU::mmio_r43x1(uint8 i) {
|
||||
return channel[i].destaddr;
|
||||
}
|
||||
|
||||
//A1TxL
|
||||
uint8 bCPU::mmio_r43x2(uint8 i) {
|
||||
return channel[i].srcaddr;
|
||||
}
|
||||
|
||||
//A1TxH
|
||||
uint8 bCPU::mmio_r43x3(uint8 i) {
|
||||
return channel[i].srcaddr >> 8;
|
||||
}
|
||||
|
||||
//A1Bx
|
||||
uint8 bCPU::mmio_r43x4(uint8 i) {
|
||||
return channel[i].srcbank;
|
||||
}
|
||||
|
||||
//DASxL
|
||||
uint8 bCPU::mmio_r43x5(uint8 i) {
|
||||
return channel[i].xfersize;
|
||||
}
|
||||
|
||||
//DASxH
|
||||
uint8 bCPU::mmio_r43x6(uint8 i) {
|
||||
return channel[i].xfersize >> 8;
|
||||
}
|
||||
|
||||
//DASBx
|
||||
uint8 bCPU::mmio_r43x7(uint8 i) {
|
||||
return channel[i].hdma_ibank;
|
||||
}
|
||||
|
||||
//A2AxL
|
||||
uint8 bCPU::mmio_r43x8(uint8 i) {
|
||||
return channel[i].hdma_addr;
|
||||
}
|
||||
|
||||
//A2AxH
|
||||
uint8 bCPU::mmio_r43x9(uint8 i) {
|
||||
return channel[i].hdma_addr >> 8;
|
||||
}
|
||||
|
||||
//NTRLx
|
||||
uint8 bCPU::mmio_r43xa(uint8 i) {
|
||||
return channel[i].hdma_line_counter;
|
||||
}
|
||||
|
||||
//???
|
||||
uint8 bCPU::mmio_r43xb(uint8 i) {
|
||||
return channel[i].hdma_unknown;
|
||||
}
|
||||
|
||||
uint8 bCPU::mmio_read(uint16 addr) {
|
||||
//APU
|
||||
if((addr & 0xffc0) == 0x2140) { //$2140-$217f
|
||||
return r_smp->port_read(addr & 3);
|
||||
}
|
||||
|
||||
//HDMA
|
||||
if((addr & 0xff80) == 0x4300) { //$4300-$437f
|
||||
uint i = (addr >> 4) & 7;
|
||||
switch(addr & 0xf) {
|
||||
case 0x0: return mmio_r43x0(i);
|
||||
case 0x1: return mmio_r43x1(i);
|
||||
case 0x2: return mmio_r43x2(i);
|
||||
case 0x3: return mmio_r43x3(i);
|
||||
case 0x4: return mmio_r43x4(i);
|
||||
case 0x5: return mmio_r43x5(i);
|
||||
case 0x6: return mmio_r43x6(i);
|
||||
case 0x7: return mmio_r43x7(i);
|
||||
case 0x8: return mmio_r43x8(i);
|
||||
case 0x9: return mmio_r43x9(i);
|
||||
case 0xa: return mmio_r43xa(i);
|
||||
case 0xb: return mmio_r43xb(i);
|
||||
case 0xc: return regs.mdr; //unmapped
|
||||
case 0xd: return regs.mdr; //unmapped
|
||||
case 0xe: return regs.mdr; //unmapped
|
||||
case 0xf: return mmio_r43xb(i); //mirror of 43xb
|
||||
}
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x2180: return mmio_r2180(); //WMDATA
|
||||
case 0x4016: return mmio_r4016(); //JOYSER0
|
||||
case 0x4017: return mmio_r4017(); //JOYSER1
|
||||
case 0x4210: return mmio_r4210(); //RDNMI
|
||||
case 0x4211: return mmio_r4211(); //TIMEUP
|
||||
case 0x4212: return mmio_r4212(); //HVBJOY
|
||||
case 0x4213: return mmio_r4213(); //RDIO
|
||||
case 0x4214: return mmio_r4214(); //RDDIVL
|
||||
case 0x4215: return mmio_r4215(); //RDDIVH
|
||||
case 0x4216: return mmio_r4216(); //RDMPYL
|
||||
case 0x4217: return mmio_r4217(); //RDMPYH
|
||||
case 0x4218: return mmio_r4218(); //JOY1L
|
||||
case 0x4219: return mmio_r4219(); //JOY1H
|
||||
case 0x421a: return mmio_r421a(); //JOY2L
|
||||
case 0x421b: return mmio_r421b(); //JOY2H
|
||||
case 0x421c: return 0x00;
|
||||
case 0x421d: return 0x00;
|
||||
case 0x421e: return 0x00;
|
||||
case 0x421f: return 0x00;
|
||||
}
|
||||
|
||||
return regs.mdr;
|
||||
}
|
||||
|
||||
//WMDATA
|
||||
void bCPU::mmio_w2180(uint8 value) {
|
||||
r_mem->write(0x7e0000 | status.wram_addr, value);
|
||||
status.wram_addr++;
|
||||
status.wram_addr &= 0x01ffff;
|
||||
}
|
||||
|
||||
//WMADDL
|
||||
void bCPU::mmio_w2181(uint8 value) {
|
||||
status.wram_addr = (status.wram_addr & 0xffff00) | value;
|
||||
status.wram_addr &= 0x01ffff;
|
||||
}
|
||||
|
||||
//WMADDM
|
||||
void bCPU::mmio_w2182(uint8 value) {
|
||||
status.wram_addr = (status.wram_addr & 0xff00ff) | (value << 8);
|
||||
status.wram_addr &= 0x01ffff;
|
||||
}
|
||||
|
||||
//WMADDH
|
||||
void bCPU::mmio_w2183(uint8 value) {
|
||||
status.wram_addr = (status.wram_addr & 0x00ffff) | (value << 16);
|
||||
status.wram_addr &= 0x01ffff;
|
||||
}
|
||||
|
||||
//JOYSER0
|
||||
//bit 0 is shared between JOYSER0 and JOYSER1, therefore
|
||||
//strobing $4016.d0 affects both controller port latches.
|
||||
//$4017 bit 0 writes are ignored.
|
||||
void bCPU::mmio_w4016(uint8 value) {
|
||||
status.joypad_strobe_latch = bool(value & 1);
|
||||
|
||||
if(status.joypad_strobe_latch == 1) {
|
||||
snes->poll_input();
|
||||
status.joypad1_read_pos = 0;
|
||||
status.joypad2_read_pos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//NMITIMEN
|
||||
void bCPU::mmio_w4200(uint8 value) {
|
||||
status.nmi_enabled = bool(value & 0x80);
|
||||
status.virq_enabled = bool(value & 0x20);
|
||||
status.hirq_enabled = bool(value & 0x10);
|
||||
status.auto_joypad_poll = bool(value & 0x01);
|
||||
|
||||
if(time.nmi_read == 0) {
|
||||
if(time.nmi_line == 1 && !status.nmi_enabled == 0) {
|
||||
time.nmi_transition = 1;
|
||||
}
|
||||
time.nmi_line = !status.nmi_enabled;
|
||||
}
|
||||
|
||||
if(status.virq_enabled == false && status.hirq_enabled == false) {
|
||||
time.irq_line = 1;
|
||||
time.irq_read = 1;
|
||||
time.irq_transition = 0;
|
||||
}
|
||||
|
||||
update_interrupts();
|
||||
}
|
||||
|
||||
//WRIO
|
||||
void bCPU::mmio_w4201(uint8 value) {
|
||||
if((status.pio & 0x80) && !(value & 0x80)) {
|
||||
r_ppu->latch_counters();
|
||||
}
|
||||
status.pio = value;
|
||||
}
|
||||
|
||||
//WRMPYA
|
||||
void bCPU::mmio_w4202(uint8 value) {
|
||||
status.mul_a = value;
|
||||
}
|
||||
|
||||
//WRMPYB
|
||||
void bCPU::mmio_w4203(uint8 value) {
|
||||
status.mul_b = value;
|
||||
status.r4216 = status.mul_a * status.mul_b;
|
||||
}
|
||||
|
||||
//WRDIVL
|
||||
void bCPU::mmio_w4204(uint8 value) {
|
||||
status.div_a = (status.div_a & 0xff00) | (value);
|
||||
}
|
||||
|
||||
//WRDIVH
|
||||
void bCPU::mmio_w4205(uint8 value) {
|
||||
status.div_a = (status.div_a & 0x00ff) | (value << 8);
|
||||
}
|
||||
|
||||
//WRDIVB
|
||||
void bCPU::mmio_w4206(uint8 value) {
|
||||
status.div_b = value;
|
||||
status.r4214 = (status.div_b) ? status.div_a / status.div_b : 0xffff;
|
||||
status.r4216 = (status.div_b) ? status.div_a % status.div_b : status.div_a;
|
||||
}
|
||||
|
||||
//HTIMEL
|
||||
void bCPU::mmio_w4207(uint8 value) {
|
||||
status.hirq_pos = ((status.hirq_pos & 0xff00) | value) & 0x01ff;
|
||||
update_interrupts();
|
||||
}
|
||||
|
||||
//HTIMEH
|
||||
void bCPU::mmio_w4208(uint8 value) {
|
||||
status.hirq_pos = ((status.hirq_pos & 0x00ff) | (value << 8)) & 0x01ff;
|
||||
update_interrupts();
|
||||
}
|
||||
|
||||
//VTIMEL
|
||||
void bCPU::mmio_w4209(uint8 value) {
|
||||
status.virq_pos = ((status.virq_pos & 0xff00) | value) & 0x01ff;
|
||||
update_interrupts();
|
||||
}
|
||||
|
||||
//VTIMEH
|
||||
void bCPU::mmio_w420a(uint8 value) {
|
||||
status.virq_pos = ((status.virq_pos & 0x00ff) | (value << 8)) & 0x01ff;
|
||||
update_interrupts();
|
||||
}
|
||||
|
||||
//DMAEN
|
||||
//DMA enable does not disable active HDMA channels
|
||||
void bCPU::mmio_w420b(uint8 value) {
|
||||
if(value != 0x00) {
|
||||
run_state.dma = true;
|
||||
status.dma_state = DMASTATE_DMASYNC;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 8; i++) {
|
||||
channel[i].dma_enabled = bool(value & (1 << i));
|
||||
//TODO: clearing read_index may interfere with DMA+HDMA occurring simultaneously
|
||||
if(channel[i].dma_enabled)channel[i].read_index = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//HDMAEN
|
||||
void bCPU::mmio_w420c(uint8 value) {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
channel[i].hdma_enabled = bool(value & (1 << i));
|
||||
}
|
||||
}
|
||||
|
||||
//MEMSEL
|
||||
void bCPU::mmio_w420d(uint8 value) {
|
||||
r_mem->set_speed(value & 1);
|
||||
}
|
||||
|
||||
//DMAPx
|
||||
void bCPU::mmio_w43x0(uint8 value, uint8 i) {
|
||||
channel[i].dmap = value;
|
||||
channel[i].direction = bool(value & 0x80);
|
||||
channel[i].hdma_indirect = bool(value & 0x40);
|
||||
channel[i].incmode = (value & 0x10) ? -1 : 1;
|
||||
channel[i].fixedxfer = bool(value & 0x08);
|
||||
channel[i].xfermode = value & 7;
|
||||
}
|
||||
|
||||
//BBADx
|
||||
void bCPU::mmio_w43x1(uint8 value, uint8 i) {
|
||||
channel[i].destaddr = value;
|
||||
}
|
||||
|
||||
//A1TxL
|
||||
void bCPU::mmio_w43x2(uint8 value, uint8 i) {
|
||||
channel[i].srcaddr = (channel[i].srcaddr & 0xff00) | value;
|
||||
}
|
||||
|
||||
//A1TxH
|
||||
void bCPU::mmio_w43x3(uint8 value, uint8 i) {
|
||||
channel[i].srcaddr = (channel[i].srcaddr & 0x00ff) | (value << 8);
|
||||
}
|
||||
|
||||
//A1Bx
|
||||
void bCPU::mmio_w43x4(uint8 value, uint8 i) {
|
||||
channel[i].srcbank = value;
|
||||
}
|
||||
|
||||
//DASxL
|
||||
void bCPU::mmio_w43x5(uint8 value, uint8 i) {
|
||||
channel[i].xfersize = (channel[i].xfersize & 0xff00) | value;
|
||||
}
|
||||
|
||||
//DASxH
|
||||
void bCPU::mmio_w43x6(uint8 value, uint8 i) {
|
||||
channel[i].xfersize = (channel[i].xfersize & 0x00ff) | (value << 8);
|
||||
}
|
||||
|
||||
//DASBx
|
||||
void bCPU::mmio_w43x7(uint8 value, uint8 i) {
|
||||
channel[i].hdma_ibank = value;
|
||||
}
|
||||
|
||||
//A2AxL
|
||||
void bCPU::mmio_w43x8(uint8 value, uint8 i) {
|
||||
channel[i].hdma_addr = (channel[i].hdma_addr & 0xff00) | value;
|
||||
}
|
||||
|
||||
//A2AxH
|
||||
void bCPU::mmio_w43x9(uint8 value, uint8 i) {
|
||||
channel[i].hdma_addr = (channel[i].hdma_addr & 0x00ff) | (value << 8);
|
||||
}
|
||||
|
||||
//NTRLx
|
||||
void bCPU::mmio_w43xa(uint8 value, uint8 i) {
|
||||
channel[i].hdma_line_counter = value;
|
||||
}
|
||||
|
||||
//???
|
||||
void bCPU::mmio_w43xb(uint8 value, uint8 i) {
|
||||
channel[i].hdma_unknown = value;
|
||||
}
|
||||
|
||||
void bCPU::mmio_write(uint16 addr, uint8 data) {
|
||||
//APU
|
||||
if((addr & 0xffc0) == 0x2140) { //$2140-$217f
|
||||
port_write(addr & 3, data);
|
||||
return;
|
||||
}
|
||||
|
||||
//HDMA
|
||||
if((addr & 0xff80) == 0x4300) { //$4300-$437f
|
||||
uint i = (addr >> 4) & 7;
|
||||
switch(addr & 0xf) {
|
||||
case 0x0: mmio_w43x0(data, i); return;
|
||||
case 0x1: mmio_w43x1(data, i); return;
|
||||
case 0x2: mmio_w43x2(data, i); return;
|
||||
case 0x3: mmio_w43x3(data, i); return;
|
||||
case 0x4: mmio_w43x4(data, i); return;
|
||||
case 0x5: mmio_w43x5(data, i); return;
|
||||
case 0x6: mmio_w43x6(data, i); return;
|
||||
case 0x7: mmio_w43x7(data, i); return;
|
||||
case 0x8: mmio_w43x8(data, i); return;
|
||||
case 0x9: mmio_w43x9(data, i); return;
|
||||
case 0xa: mmio_w43xa(data, i); return;
|
||||
case 0xb: mmio_w43xb(data, i); return;
|
||||
case 0xc: return; //unmapped
|
||||
case 0xd: return; //unmapped
|
||||
case 0xe: return; //unmapped
|
||||
case 0xf: mmio_w43xb(data, i); return; //mirror of 43xb
|
||||
}
|
||||
}
|
||||
|
||||
switch(addr) {
|
||||
case 0x2180: mmio_w2180(data); return; //WMDATA
|
||||
case 0x2181: mmio_w2181(data); return; //WMADDL
|
||||
case 0x2182: mmio_w2182(data); return; //WMADDM
|
||||
case 0x2183: mmio_w2183(data); return; //WMADDH
|
||||
case 0x4016: mmio_w4016(data); return; //JOYSER0
|
||||
case 0x4017: return; //unmapped
|
||||
case 0x4200: mmio_w4200(data); return; //NMITIMEN
|
||||
case 0x4201: mmio_w4201(data); return; //WRIO
|
||||
case 0x4202: mmio_w4202(data); return; //WRMPYA
|
||||
case 0x4203: mmio_w4203(data); return; //WRMPYB
|
||||
case 0x4204: mmio_w4204(data); return; //WRDIVL
|
||||
case 0x4205: mmio_w4205(data); return; //WRDIVH
|
||||
case 0x4206: mmio_w4206(data); return; //WRDIVB
|
||||
case 0x4207: mmio_w4207(data); return; //HTIMEL
|
||||
case 0x4208: mmio_w4208(data); return; //HTIMEH
|
||||
case 0x4209: mmio_w4209(data); return; //VTIMEL
|
||||
case 0x420a: mmio_w420a(data); return; //VTIMEH
|
||||
case 0x420b: mmio_w420b(data); return; //DMAEN
|
||||
case 0x420c: mmio_w420c(data); return; //HDMAEN
|
||||
case 0x420d: mmio_w420d(data); return; //MEMSEL
|
||||
}
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
#define CLASS_NAME "bCPU"
|
||||
#include "../../../lib/opgen.cpp"
|
||||
|
||||
int main() {
|
||||
fph = fopen("op.h", "wb");
|
||||
fpt = fopen("optable.cpp", "wb");
|
||||
|
||||
generate("op_read.cpp", "op_read.b");
|
||||
generate("op_rmw.cpp", "op_rmw.b");
|
||||
generate("op_write.cpp", "op_write.b");
|
||||
generate("op_pc.cpp", "op_pc.b");
|
||||
generate("op_misc.cpp", "op_misc.b");
|
||||
|
||||
fclose(fph);
|
||||
fclose(fpt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
cl /O2 /wd4996 bcpugen.cpp
|
||||
@pause
|
||||
@del *.obj
|
||||
@@ -1 +0,0 @@
|
||||
@del *.exe
|
||||
@@ -1,28 +0,0 @@
|
||||
#include "opfn.cpp"
|
||||
#include "op_read.cpp"
|
||||
#include "op_rmw.cpp"
|
||||
#include "op_write.cpp"
|
||||
#include "op_pc.cpp"
|
||||
#include "op_misc.cpp"
|
||||
|
||||
void bCPU::cpu_c2() {
|
||||
if(regs.d.l != 0x00) {
|
||||
cpu_io();
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::cpu_c4(uint16 x, uint16 y) {
|
||||
if(!regs.p.x || (x & 0xff00) != (y & 0xff00)) {
|
||||
cpu_io();
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::cpu_c6(uint16 addr) {
|
||||
if(regs.e && (regs.pc.w & 0xff00) != (addr & 0xff00)) {
|
||||
cpu_io();
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::init_op_tables() {
|
||||
#include "optable.cpp"
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/* External functions:
|
||||
* void last_cycle();
|
||||
* void cpu_io();
|
||||
* uint8 mem_read(uint32 addr);
|
||||
* void mem_write(uint32 addr, uint8 value);
|
||||
*/
|
||||
|
||||
void (bCPU::*optbl[256])();
|
||||
|
||||
CPUReg24 aa, rd;
|
||||
uint8 dp, sp;
|
||||
|
||||
//op_read
|
||||
inline void op_adc_b();
|
||||
inline void op_adc_w();
|
||||
inline void op_and_b();
|
||||
inline void op_and_w();
|
||||
inline void op_bit_b();
|
||||
inline void op_bit_w();
|
||||
inline void op_cmp_b();
|
||||
inline void op_cmp_w();
|
||||
inline void op_cpx_b();
|
||||
inline void op_cpx_w();
|
||||
inline void op_cpy_b();
|
||||
inline void op_cpy_w();
|
||||
inline void op_eor_b();
|
||||
inline void op_eor_w();
|
||||
inline void op_lda_b();
|
||||
inline void op_lda_w();
|
||||
inline void op_ldx_b();
|
||||
inline void op_ldx_w();
|
||||
inline void op_ldy_b();
|
||||
inline void op_ldy_w();
|
||||
inline void op_ora_b();
|
||||
inline void op_ora_w();
|
||||
inline void op_sbc_b();
|
||||
inline void op_sbc_w();
|
||||
//op_rmw
|
||||
inline void op_inc_b();
|
||||
inline void op_inc_w();
|
||||
inline void op_dec_b();
|
||||
inline void op_dec_w();
|
||||
inline void op_asl_b();
|
||||
inline void op_asl_w();
|
||||
inline void op_lsr_b();
|
||||
inline void op_lsr_w();
|
||||
inline void op_rol_b();
|
||||
inline void op_rol_w();
|
||||
inline void op_ror_b();
|
||||
inline void op_ror_w();
|
||||
inline void op_trb_b();
|
||||
inline void op_trb_w();
|
||||
inline void op_tsb_b();
|
||||
inline void op_tsb_w();
|
||||
|
||||
inline void cpu_c2();
|
||||
inline void cpu_c4(uint16 x, uint16 y);
|
||||
inline void cpu_c6(uint16 addr);
|
||||
|
||||
inline void init_op_tables();
|
||||
|
||||
#include "op.h"
|
||||
@@ -1,256 +0,0 @@
|
||||
void op_adc_const();
|
||||
void op_and_const();
|
||||
void op_cmp_const();
|
||||
void op_cpx_const();
|
||||
void op_cpy_const();
|
||||
void op_eor_const();
|
||||
void op_lda_const();
|
||||
void op_ldx_const();
|
||||
void op_ldy_const();
|
||||
void op_ora_const();
|
||||
void op_sbc_const();
|
||||
void op_adc_addr();
|
||||
void op_and_addr();
|
||||
void op_bit_addr();
|
||||
void op_cmp_addr();
|
||||
void op_cpx_addr();
|
||||
void op_cpy_addr();
|
||||
void op_eor_addr();
|
||||
void op_lda_addr();
|
||||
void op_ldx_addr();
|
||||
void op_ldy_addr();
|
||||
void op_ora_addr();
|
||||
void op_sbc_addr();
|
||||
void op_adc_addrx();
|
||||
void op_and_addrx();
|
||||
void op_bit_addrx();
|
||||
void op_cmp_addrx();
|
||||
void op_eor_addrx();
|
||||
void op_lda_addrx();
|
||||
void op_ldy_addrx();
|
||||
void op_ora_addrx();
|
||||
void op_sbc_addrx();
|
||||
void op_adc_addry();
|
||||
void op_and_addry();
|
||||
void op_cmp_addry();
|
||||
void op_eor_addry();
|
||||
void op_lda_addry();
|
||||
void op_ldx_addry();
|
||||
void op_ora_addry();
|
||||
void op_sbc_addry();
|
||||
void op_adc_long();
|
||||
void op_and_long();
|
||||
void op_cmp_long();
|
||||
void op_eor_long();
|
||||
void op_lda_long();
|
||||
void op_ora_long();
|
||||
void op_sbc_long();
|
||||
void op_adc_longx();
|
||||
void op_and_longx();
|
||||
void op_cmp_longx();
|
||||
void op_eor_longx();
|
||||
void op_lda_longx();
|
||||
void op_ora_longx();
|
||||
void op_sbc_longx();
|
||||
void op_adc_dp();
|
||||
void op_and_dp();
|
||||
void op_bit_dp();
|
||||
void op_cmp_dp();
|
||||
void op_cpx_dp();
|
||||
void op_cpy_dp();
|
||||
void op_eor_dp();
|
||||
void op_lda_dp();
|
||||
void op_ldx_dp();
|
||||
void op_ldy_dp();
|
||||
void op_ora_dp();
|
||||
void op_sbc_dp();
|
||||
void op_adc_dpx();
|
||||
void op_and_dpx();
|
||||
void op_bit_dpx();
|
||||
void op_cmp_dpx();
|
||||
void op_eor_dpx();
|
||||
void op_lda_dpx();
|
||||
void op_ldy_dpx();
|
||||
void op_ora_dpx();
|
||||
void op_sbc_dpx();
|
||||
void op_ldx_dpy();
|
||||
void op_adc_idp();
|
||||
void op_and_idp();
|
||||
void op_cmp_idp();
|
||||
void op_eor_idp();
|
||||
void op_lda_idp();
|
||||
void op_ora_idp();
|
||||
void op_sbc_idp();
|
||||
void op_adc_idpx();
|
||||
void op_and_idpx();
|
||||
void op_cmp_idpx();
|
||||
void op_eor_idpx();
|
||||
void op_lda_idpx();
|
||||
void op_ora_idpx();
|
||||
void op_sbc_idpx();
|
||||
void op_adc_idpy();
|
||||
void op_and_idpy();
|
||||
void op_cmp_idpy();
|
||||
void op_eor_idpy();
|
||||
void op_lda_idpy();
|
||||
void op_ora_idpy();
|
||||
void op_sbc_idpy();
|
||||
void op_adc_ildp();
|
||||
void op_and_ildp();
|
||||
void op_cmp_ildp();
|
||||
void op_eor_ildp();
|
||||
void op_lda_ildp();
|
||||
void op_ora_ildp();
|
||||
void op_sbc_ildp();
|
||||
void op_adc_ildpy();
|
||||
void op_and_ildpy();
|
||||
void op_cmp_ildpy();
|
||||
void op_eor_ildpy();
|
||||
void op_lda_ildpy();
|
||||
void op_ora_ildpy();
|
||||
void op_sbc_ildpy();
|
||||
void op_adc_sr();
|
||||
void op_and_sr();
|
||||
void op_cmp_sr();
|
||||
void op_eor_sr();
|
||||
void op_lda_sr();
|
||||
void op_ora_sr();
|
||||
void op_sbc_sr();
|
||||
void op_adc_isry();
|
||||
void op_and_isry();
|
||||
void op_cmp_isry();
|
||||
void op_eor_isry();
|
||||
void op_lda_isry();
|
||||
void op_ora_isry();
|
||||
void op_sbc_isry();
|
||||
void op_bit_const();
|
||||
void op_inc();
|
||||
void op_inx();
|
||||
void op_iny();
|
||||
void op_dec();
|
||||
void op_dex();
|
||||
void op_dey();
|
||||
void op_asl();
|
||||
void op_lsr();
|
||||
void op_rol();
|
||||
void op_ror();
|
||||
void op_inc_addr();
|
||||
void op_dec_addr();
|
||||
void op_asl_addr();
|
||||
void op_lsr_addr();
|
||||
void op_rol_addr();
|
||||
void op_ror_addr();
|
||||
void op_trb_addr();
|
||||
void op_tsb_addr();
|
||||
void op_inc_addrx();
|
||||
void op_dec_addrx();
|
||||
void op_asl_addrx();
|
||||
void op_lsr_addrx();
|
||||
void op_rol_addrx();
|
||||
void op_ror_addrx();
|
||||
void op_inc_dp();
|
||||
void op_dec_dp();
|
||||
void op_asl_dp();
|
||||
void op_lsr_dp();
|
||||
void op_rol_dp();
|
||||
void op_ror_dp();
|
||||
void op_trb_dp();
|
||||
void op_tsb_dp();
|
||||
void op_inc_dpx();
|
||||
void op_dec_dpx();
|
||||
void op_asl_dpx();
|
||||
void op_lsr_dpx();
|
||||
void op_rol_dpx();
|
||||
void op_ror_dpx();
|
||||
void op_sta_addr();
|
||||
void op_stx_addr();
|
||||
void op_sty_addr();
|
||||
void op_stz_addr();
|
||||
void op_sta_addrx();
|
||||
void op_stz_addrx();
|
||||
void op_sta_addry();
|
||||
void op_sta_long();
|
||||
void op_sta_longx();
|
||||
void op_sta_dp();
|
||||
void op_stx_dp();
|
||||
void op_sty_dp();
|
||||
void op_stz_dp();
|
||||
void op_sta_dpx();
|
||||
void op_sty_dpx();
|
||||
void op_stz_dpx();
|
||||
void op_stx_dpy();
|
||||
void op_sta_idp();
|
||||
void op_sta_ildp();
|
||||
void op_sta_idpx();
|
||||
void op_sta_idpy();
|
||||
void op_sta_ildpy();
|
||||
void op_sta_sr();
|
||||
void op_sta_isry();
|
||||
void op_bcc();
|
||||
void op_bcs();
|
||||
void op_bne();
|
||||
void op_beq();
|
||||
void op_bpl();
|
||||
void op_bmi();
|
||||
void op_bvc();
|
||||
void op_bvs();
|
||||
void op_bra();
|
||||
void op_brl();
|
||||
void op_jmp_addr();
|
||||
void op_jmp_long();
|
||||
void op_jmp_iaddr();
|
||||
void op_jmp_iaddrx();
|
||||
void op_jmp_iladdr();
|
||||
void op_jsr_addr();
|
||||
void op_jsr_long();
|
||||
void op_jsr_iaddrx();
|
||||
void op_rti();
|
||||
void op_rts();
|
||||
void op_rtl();
|
||||
void op_nop();
|
||||
void op_wdm();
|
||||
void op_xba();
|
||||
void op_mvn();
|
||||
void op_mvp();
|
||||
void op_brk();
|
||||
void op_cop();
|
||||
void op_stp();
|
||||
void op_wai();
|
||||
void op_xce();
|
||||
void op_clc();
|
||||
void op_cld();
|
||||
void op_cli();
|
||||
void op_clv();
|
||||
void op_sec();
|
||||
void op_sed();
|
||||
void op_sei();
|
||||
void op_rep();
|
||||
void op_sep();
|
||||
void op_tax();
|
||||
void op_tay();
|
||||
void op_txa();
|
||||
void op_txy();
|
||||
void op_tya();
|
||||
void op_tyx();
|
||||
void op_tcd();
|
||||
void op_tcs();
|
||||
void op_tdc();
|
||||
void op_tsc();
|
||||
void op_tsx();
|
||||
void op_txs();
|
||||
void op_pha();
|
||||
void op_phx();
|
||||
void op_phy();
|
||||
void op_phd();
|
||||
void op_phb();
|
||||
void op_phk();
|
||||
void op_php();
|
||||
void op_pla();
|
||||
void op_plx();
|
||||
void op_ply();
|
||||
void op_pld();
|
||||
void op_plb();
|
||||
void op_plp();
|
||||
void op_pea();
|
||||
void op_pei();
|
||||
void op_per();
|
||||
@@ -1,282 +0,0 @@
|
||||
nop(0xea) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
}
|
||||
|
||||
wdm(0x42) {
|
||||
1:last_cycle();
|
||||
op_readpc();
|
||||
}
|
||||
|
||||
xba(0xeb) {
|
||||
1:cpu_io();
|
||||
2:last_cycle();
|
||||
cpu_io();
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.a.h ^= regs.a.l;
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
mvn(0x54, ++),
|
||||
mvp(0x44, --) {
|
||||
1:dp = op_readpc();
|
||||
2:sp = op_readpc();
|
||||
3:regs.db = dp;
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
4:op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
5:cpu_io();
|
||||
if(regs.p.x) { regs.x.l$1; regs.y.l$1; }
|
||||
else { regs.x.w$1; regs.y.w$1; }
|
||||
6:last_cycle();
|
||||
cpu_io();
|
||||
if(regs.a.w--)regs.pc.w -= 3;
|
||||
}
|
||||
|
||||
brk(0x00, 0xfffe, 0xffff, 0xffe6, 0xffe7),
|
||||
cop(0x02, 0xfff4, 0xfff5, 0xffe4, 0xffe5) {
|
||||
1:op_readpc();
|
||||
if(regs.e)skip;
|
||||
2:op_writestack(regs.pc.b);
|
||||
3:op_writestack(regs.pc.h);
|
||||
4:op_writestack(regs.pc.l);
|
||||
5:op_writestack(regs.p);
|
||||
6:rd.l = op_readlong((regs.e) ? $1 : $3);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
7:last_cycle();
|
||||
rd.h = op_readlong((regs.e) ? $2 : $4);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
stp(0xdb) {
|
||||
1:cpu_io();
|
||||
run_state.stp = true;
|
||||
2:last_cycle();
|
||||
cpu_io();
|
||||
regs.pc.w--;
|
||||
}
|
||||
|
||||
wai(0xcb) {
|
||||
1:cpu_io();
|
||||
run_state.wai = true;
|
||||
2:last_cycle();
|
||||
cpu_io();
|
||||
//no wakeup delay if last_cycle() cancelled wai
|
||||
if(run_state.wai == false)end;
|
||||
3:last_cycle();
|
||||
cpu_io();
|
||||
//sleep another i/o cycle
|
||||
//note: this should alert the debugger that wai is continuing...
|
||||
if(run_state.wai == true)status.cycle_pos--;
|
||||
//wai wakeup delay (one i/o cycle)
|
||||
4:last_cycle();
|
||||
cpu_io();
|
||||
}
|
||||
|
||||
xce(0xfb) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
bool c = regs.p.c;
|
||||
regs.p.c = regs.e;
|
||||
regs.e = c;
|
||||
if(regs.e) {
|
||||
regs.p |= 0x30;
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
}
|
||||
|
||||
clc(0x18, regs.p.c = 0),
|
||||
cld(0xd8, regs.p.d = 0),
|
||||
cli(0x58, regs.p.i = 0),
|
||||
clv(0xb8, regs.p.v = 0),
|
||||
sec(0x38, regs.p.c = 1),
|
||||
sed(0xf8, regs.p.d = 1),
|
||||
sei(0x78, regs.p.i = 1) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
$1;
|
||||
}
|
||||
|
||||
rep(0xc2, &=~),
|
||||
sep(0xe2, |=) {
|
||||
1:rd.l = op_readpc();
|
||||
2:last_cycle();
|
||||
cpu_io();
|
||||
regs.p $1 rd.l;
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
tax(0xaa, regs.p.x, x, a),
|
||||
tay(0xa8, regs.p.x, y, a),
|
||||
txa(0x8a, regs.p.m, a, x),
|
||||
txy(0x9b, regs.p.x, y, x),
|
||||
tya(0x98, regs.p.m, a, y),
|
||||
tyx(0xbb, regs.p.x, x, y) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
if($1) {
|
||||
regs.$2.l = regs.$3.l;
|
||||
regs.p.n = !!(regs.$2.l & 0x80);
|
||||
regs.p.z = (regs.$2.l == 0);
|
||||
} else {
|
||||
regs.$2.w = regs.$3.w;
|
||||
regs.p.n = !!(regs.$2.w & 0x8000);
|
||||
regs.p.z = (regs.$2.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
tcd(0x5b) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
regs.d.w = regs.a.w;
|
||||
regs.p.n = !!(regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
}
|
||||
|
||||
tcs(0x1b) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
regs.s.w = regs.a.w;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
tdc(0x7b) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
regs.a.w = regs.d.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
tsc(0x3b) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
regs.a.w = regs.s.w;
|
||||
if(regs.e) {
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
tsx(0xba) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l = regs.s.l;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w = regs.s.w;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
txs(0x9a) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
if(regs.e) {
|
||||
regs.s.l = regs.x.l;
|
||||
} else {
|
||||
regs.s.w = regs.x.w;
|
||||
}
|
||||
}
|
||||
|
||||
pha(0x48, regs.p.m, a),
|
||||
phx(0xda, regs.p.x, x),
|
||||
phy(0x5a, regs.p.x, y),
|
||||
phd(0x0b, 0, d) {
|
||||
1:cpu_io();
|
||||
if($1)skip;
|
||||
2:op_writestack(regs.$2.h);
|
||||
3:last_cycle();
|
||||
op_writestack(regs.$2.l);
|
||||
}
|
||||
|
||||
phb(0x8b, regs.db),
|
||||
phk(0x4b, regs.pc.b),
|
||||
php(0x08, regs.p) {
|
||||
1:cpu_io();
|
||||
2:last_cycle();
|
||||
op_writestack($1);
|
||||
}
|
||||
|
||||
pla(0x68, regs.p.m, a),
|
||||
plx(0xfa, regs.p.x, x),
|
||||
ply(0x7a, regs.p.x, y),
|
||||
pld(0x2b, 0, d) {
|
||||
1:cpu_io();
|
||||
2:cpu_io();
|
||||
3:if($1)last_cycle();
|
||||
regs.$2.l = op_readstack();
|
||||
if($1) {
|
||||
regs.p.n = !!(regs.$2.l & 0x80);
|
||||
regs.p.z = (regs.$2.l == 0);
|
||||
end;
|
||||
}
|
||||
4:last_cycle();
|
||||
regs.$2.h = op_readstack();
|
||||
regs.p.n = !!(regs.$2.w & 0x8000);
|
||||
regs.p.z = (regs.$2.w == 0);
|
||||
}
|
||||
|
||||
plb(0xab) {
|
||||
1:cpu_io();
|
||||
2:cpu_io();
|
||||
3:last_cycle();
|
||||
regs.db = op_readstack();
|
||||
regs.p.n = !!(regs.db & 0x80);
|
||||
regs.p.z = (regs.db == 0);
|
||||
}
|
||||
|
||||
plp(0x28) {
|
||||
1:cpu_io();
|
||||
2:cpu_io();
|
||||
3:last_cycle();
|
||||
regs.p = op_readstack();
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
pea(0xf4) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_writestack(aa.h);
|
||||
4:last_cycle();
|
||||
op_writestack(aa.l);
|
||||
}
|
||||
|
||||
pei(0xd4) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:op_writestack(aa.h);
|
||||
6:last_cycle();
|
||||
op_writestack(aa.l);
|
||||
}
|
||||
|
||||
per(0x62) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:cpu_io();
|
||||
rd.w = regs.pc.d + (int16)aa.w;
|
||||
4:op_writestack(rd.h);
|
||||
5:last_cycle();
|
||||
op_writestack(rd.l);
|
||||
}
|
||||
@@ -1,864 +0,0 @@
|
||||
void bCPU::op_nop() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_wdm() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
op_readpc();
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_xba() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.a.h ^= regs.a.l;
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_mvn() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
sp = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
regs.db = dp;
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
} break;
|
||||
case 4: {
|
||||
op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
} break;
|
||||
case 5: {
|
||||
cpu_io();
|
||||
if(regs.p.x) { regs.x.l++; regs.y.l++; }
|
||||
else { regs.x.w++; regs.y.w++; }
|
||||
} break;
|
||||
case 6: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
if(regs.a.w--)regs.pc.w -= 3;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_mvp() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
sp = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
regs.db = dp;
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
} break;
|
||||
case 4: {
|
||||
op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
} break;
|
||||
case 5: {
|
||||
cpu_io();
|
||||
if(regs.p.x) { regs.x.l--; regs.y.l--; }
|
||||
else { regs.x.w--; regs.y.w--; }
|
||||
} break;
|
||||
case 6: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
if(regs.a.w--)regs.pc.w -= 3;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_brk() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
op_readpc();
|
||||
if(regs.e)status.cycle_pos++;
|
||||
} break;
|
||||
case 2: {
|
||||
op_writestack(regs.pc.b);
|
||||
} break;
|
||||
case 3: {
|
||||
op_writestack(regs.pc.h);
|
||||
} break;
|
||||
case 4: {
|
||||
op_writestack(regs.pc.l);
|
||||
} break;
|
||||
case 5: {
|
||||
op_writestack(regs.p);
|
||||
} break;
|
||||
case 6: {
|
||||
rd.l = op_readlong((regs.e) ? 0xfffe : 0xffe6);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
} break;
|
||||
case 7: {
|
||||
last_cycle();
|
||||
rd.h = op_readlong((regs.e) ? 0xffff : 0xffe7);
|
||||
regs.pc.w = rd.w;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_cop() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
op_readpc();
|
||||
if(regs.e)status.cycle_pos++;
|
||||
} break;
|
||||
case 2: {
|
||||
op_writestack(regs.pc.b);
|
||||
} break;
|
||||
case 3: {
|
||||
op_writestack(regs.pc.h);
|
||||
} break;
|
||||
case 4: {
|
||||
op_writestack(regs.pc.l);
|
||||
} break;
|
||||
case 5: {
|
||||
op_writestack(regs.p);
|
||||
} break;
|
||||
case 6: {
|
||||
rd.l = op_readlong((regs.e) ? 0xfff4 : 0xffe4);
|
||||
regs.pc.b = 0x00;
|
||||
regs.p.i = 1;
|
||||
regs.p.d = 0;
|
||||
} break;
|
||||
case 7: {
|
||||
last_cycle();
|
||||
rd.h = op_readlong((regs.e) ? 0xfff5 : 0xffe5);
|
||||
regs.pc.w = rd.w;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_stp() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
run_state.stp = true;
|
||||
} break;
|
||||
case 2: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.pc.w--;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_wai() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
run_state.wai = true;
|
||||
} break;
|
||||
case 2: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
//no wakeup delay if last_cycle() cancelled wai
|
||||
if(run_state.wai == false)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
//sleep another i/o cycle
|
||||
//note: this should alert the debugger that wai is continuing...
|
||||
if(run_state.wai == true)status.cycle_pos--;
|
||||
//wai wakeup delay (one i/o cycle)
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_xce() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
bool c = regs.p.c;
|
||||
regs.p.c = regs.e;
|
||||
regs.e = c;
|
||||
if(regs.e) {
|
||||
regs.p |= 0x30;
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_clc() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.p.c = 0;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_cld() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.p.d = 0;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_cli() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.p.i = 0;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_clv() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.p.v = 0;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sec() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.p.c = 1;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sed() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.p.d = 1;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sei() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.p.i = 1;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_rep() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
rd.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.p &=~ rd.l;
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sep() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
rd.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.p |= rd.l;
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_tax() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l = regs.a.l;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w = regs.a.w;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_tay() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
if(regs.p.x) {
|
||||
regs.y.l = regs.a.l;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
} else {
|
||||
regs.y.w = regs.a.w;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_txa() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
if(regs.p.m) {
|
||||
regs.a.l = regs.x.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.a.w = regs.x.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_txy() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
if(regs.p.x) {
|
||||
regs.y.l = regs.x.l;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
} else {
|
||||
regs.y.w = regs.x.w;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_tya() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
if(regs.p.m) {
|
||||
regs.a.l = regs.y.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.a.w = regs.y.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_tyx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l = regs.y.l;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w = regs.y.w;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_tcd() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.d.w = regs.a.w;
|
||||
regs.p.n = !!(regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_tcs() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.s.w = regs.a.w;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_tdc() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.a.w = regs.d.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_tsc() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.a.w = regs.s.w;
|
||||
if(regs.e) {
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_tsx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
if(regs.p.x) {
|
||||
regs.x.l = regs.s.l;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w = regs.s.w;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_txs() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
if(regs.e) {
|
||||
regs.s.l = regs.x.l;
|
||||
} else {
|
||||
regs.s.w = regs.x.w;
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_pha() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
if(regs.p.m)status.cycle_pos++;
|
||||
} break;
|
||||
case 2: {
|
||||
op_writestack(regs.a.h);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
op_writestack(regs.a.l);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_phx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
if(regs.p.x)status.cycle_pos++;
|
||||
} break;
|
||||
case 2: {
|
||||
op_writestack(regs.x.h);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
op_writestack(regs.x.l);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_phy() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
if(regs.p.x)status.cycle_pos++;
|
||||
} break;
|
||||
case 2: {
|
||||
op_writestack(regs.y.h);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
op_writestack(regs.y.l);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_phd() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
if(0)status.cycle_pos++;
|
||||
} break;
|
||||
case 2: {
|
||||
op_writestack(regs. d.h);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
op_writestack(regs. d.l);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_phb() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
last_cycle();
|
||||
op_writestack(regs.db);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_phk() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
last_cycle();
|
||||
op_writestack(regs.pc.b);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_php() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
last_cycle();
|
||||
op_writestack(regs.p);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_pla() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 3: {
|
||||
if(regs.p.m)last_cycle();
|
||||
regs.a.l = op_readstack();
|
||||
if(regs.p.m) {
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
regs.a.h = op_readstack();
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_plx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 3: {
|
||||
if(regs.p.x)last_cycle();
|
||||
regs.x.l = op_readstack();
|
||||
if(regs.p.x) {
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
regs.x.h = op_readstack();
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_ply() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 3: {
|
||||
if(regs.p.x)last_cycle();
|
||||
regs.y.l = op_readstack();
|
||||
if(regs.p.x) {
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
regs.y.h = op_readstack();
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_pld() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 3: {
|
||||
if(0)last_cycle();
|
||||
regs. d.l = op_readstack();
|
||||
if(0) {
|
||||
regs.p.n = !!(regs. d.l & 0x80);
|
||||
regs.p.z = (regs. d.l == 0);
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
regs. d.h = op_readstack();
|
||||
regs.p.n = !!(regs. d.w & 0x8000);
|
||||
regs.p.z = (regs. d.w == 0);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_plb() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
regs.db = op_readstack();
|
||||
regs.p.n = !!(regs.db & 0x80);
|
||||
regs.p.z = (regs.db == 0);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_plp() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
regs.p = op_readstack();
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_pea() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
op_writestack(aa.h);
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
op_writestack(aa.l);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_pei() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
aa.l = op_readdp(dp);
|
||||
} break;
|
||||
case 4: {
|
||||
aa.h = op_readdp(dp + 1);
|
||||
} break;
|
||||
case 5: {
|
||||
op_writestack(aa.h);
|
||||
} break;
|
||||
case 6: {
|
||||
last_cycle();
|
||||
op_writestack(aa.l);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_per() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
cpu_io();
|
||||
rd.w = regs.pc.d + (int16)aa.w;
|
||||
} break;
|
||||
case 4: {
|
||||
op_writestack(rd.h);
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
op_writestack(rd.l);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,160 +0,0 @@
|
||||
bcc(0x90, !regs.p.c),
|
||||
bcs(0xb0, regs.p.c),
|
||||
bne(0xd0, !regs.p.z),
|
||||
beq(0xf0, regs.p.z),
|
||||
bpl(0x10, !regs.p.n),
|
||||
bmi(0x30, regs.p.n),
|
||||
bvc(0x50, !regs.p.v),
|
||||
bvs(0x70, regs.p.v) {
|
||||
1:if(!$1)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if($1) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
end;
|
||||
}
|
||||
2:cpu_c6(aa.w);
|
||||
3:last_cycle();
|
||||
cpu_io();
|
||||
}
|
||||
|
||||
bra(0x80) {
|
||||
1:rd.l = op_readpc();
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
2:cpu_c6(aa.w);
|
||||
3:last_cycle();
|
||||
cpu_io();
|
||||
}
|
||||
|
||||
brl(0x82) {
|
||||
1:rd.l = op_readpc();
|
||||
2:rd.h = op_readpc();
|
||||
3:last_cycle();
|
||||
cpu_io();
|
||||
regs.pc.w = regs.pc.d + (int16)rd.w;
|
||||
}
|
||||
|
||||
jmp_addr(0x4c) {
|
||||
1:rd.l = op_readpc();
|
||||
2:last_cycle();
|
||||
rd.h = op_readpc();
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
jmp_long(0x5c) {
|
||||
1:rd.l = op_readpc();
|
||||
2:rd.h = op_readpc();
|
||||
3:last_cycle();
|
||||
rd.b = op_readpc();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
jmp_iaddr(0x6c) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:rd.l = op_readaddr(aa.w);
|
||||
4:last_cycle();
|
||||
rd.h = op_readaddr(aa.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
jmp_iaddrx(0x7c) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:cpu_io();
|
||||
4:rd.l = op_readpbr(aa.w + regs.x.w);
|
||||
5:last_cycle();
|
||||
rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
jmp_iladdr(0xdc) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:rd.l = op_readaddr(aa.w);
|
||||
4:rd.h = op_readaddr(aa.w + 1);
|
||||
5:last_cycle();
|
||||
rd.b = op_readaddr(aa.w + 2);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
jsr_addr(0x20) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:cpu_io();
|
||||
4:regs.pc.w--;
|
||||
op_writestack(regs.pc.h);
|
||||
5:last_cycle();
|
||||
op_writestack(regs.pc.l);
|
||||
regs.pc.w = aa.w;
|
||||
}
|
||||
|
||||
jsr_long(0x22) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_writestack(regs.pc.b);
|
||||
4:cpu_io();
|
||||
5:aa.b = op_readpc();
|
||||
6:regs.pc.w--;
|
||||
op_writestack(regs.pc.h);
|
||||
7:last_cycle();
|
||||
op_writestack(regs.pc.l);
|
||||
regs.pc.d = aa.d & 0xffffff;
|
||||
}
|
||||
|
||||
jsr_iaddrx(0xfc) {
|
||||
1:aa.l = op_readpc();
|
||||
2:op_writestack(regs.pc.h);
|
||||
3:op_writestack(regs.pc.l);
|
||||
4:aa.h = op_readpc();
|
||||
5:cpu_io();
|
||||
6:rd.l = op_readpbr(aa.w + regs.x.w);
|
||||
7:last_cycle();
|
||||
rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
}
|
||||
|
||||
rti(0x40) {
|
||||
1:cpu_io();
|
||||
2:cpu_io();
|
||||
3:regs.p = op_readstack();
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
4:rd.l = op_readstack();
|
||||
5:if(regs.e)last_cycle();
|
||||
rd.h = op_readstack();
|
||||
if(regs.e) {
|
||||
regs.pc.w = rd.w;
|
||||
end;
|
||||
}
|
||||
6:last_cycle();
|
||||
rd.b = op_readstack();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
rts(0x60) {
|
||||
1:cpu_io();
|
||||
2:cpu_io();
|
||||
3:rd.l = op_readstack();
|
||||
4:rd.h = op_readstack();
|
||||
5:last_cycle();
|
||||
cpu_io();
|
||||
regs.pc.w = rd.w;
|
||||
regs.pc.w++;
|
||||
}
|
||||
|
||||
rtl(0x6b) {
|
||||
1:cpu_io();
|
||||
2:cpu_io();
|
||||
3:rd.l = op_readstack();
|
||||
4:rd.h = op_readstack();
|
||||
5:last_cycle();
|
||||
rd.b = op_readstack();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
regs.pc.w++;
|
||||
}
|
||||
@@ -1,483 +0,0 @@
|
||||
void bCPU::op_bcc() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
if(!!regs.p.c)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(!regs.p.c) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c6(aa.w);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_bcs() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
if(!regs.p.c)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(regs.p.c) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c6(aa.w);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_bne() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
if(!!regs.p.z)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(!regs.p.z) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c6(aa.w);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_beq() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
if(!regs.p.z)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(regs.p.z) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c6(aa.w);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_bpl() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
if(!!regs.p.n)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(!regs.p.n) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c6(aa.w);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_bmi() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
if(!regs.p.n)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(regs.p.n) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c6(aa.w);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_bvc() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
if(!!regs.p.v)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(!regs.p.v) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c6(aa.w);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_bvs() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
if(!regs.p.v)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(regs.p.v) {
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} else {
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c6(aa.w);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_bra() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
rd.l = op_readpc();
|
||||
aa.w = regs.pc.d + (int8)rd.l;
|
||||
regs.pc.w = aa.w;
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c6(aa.w);
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_brl() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
rd.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
rd.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.pc.w = regs.pc.d + (int16)rd.w;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_jmp_addr() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
rd.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
last_cycle();
|
||||
rd.h = op_readpc();
|
||||
regs.pc.w = rd.w;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_jmp_long() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
rd.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
rd.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
last_cycle();
|
||||
rd.b = op_readpc();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_jmp_iaddr() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
rd.l = op_readaddr(aa.w);
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
rd.h = op_readaddr(aa.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_jmp_iaddrx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 4: {
|
||||
rd.l = op_readpbr(aa.w + regs.x.w);
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_jmp_iladdr() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
rd.l = op_readaddr(aa.w);
|
||||
} break;
|
||||
case 4: {
|
||||
rd.h = op_readaddr(aa.w + 1);
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
rd.b = op_readaddr(aa.w + 2);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_jsr_addr() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 4: {
|
||||
regs.pc.w--;
|
||||
op_writestack(regs.pc.h);
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
op_writestack(regs.pc.l);
|
||||
regs.pc.w = aa.w;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_jsr_long() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
op_writestack(regs.pc.b);
|
||||
} break;
|
||||
case 4: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 5: {
|
||||
aa.b = op_readpc();
|
||||
} break;
|
||||
case 6: {
|
||||
regs.pc.w--;
|
||||
op_writestack(regs.pc.h);
|
||||
} break;
|
||||
case 7: {
|
||||
last_cycle();
|
||||
op_writestack(regs.pc.l);
|
||||
regs.pc.d = aa.d & 0xffffff;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_jsr_iaddrx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
op_writestack(regs.pc.h);
|
||||
} break;
|
||||
case 3: {
|
||||
op_writestack(regs.pc.l);
|
||||
} break;
|
||||
case 4: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 5: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 6: {
|
||||
rd.l = op_readpbr(aa.w + regs.x.w);
|
||||
} break;
|
||||
case 7: {
|
||||
last_cycle();
|
||||
rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_rti() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 3: {
|
||||
regs.p = op_readstack();
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
} break;
|
||||
case 4: {
|
||||
rd.l = op_readstack();
|
||||
} break;
|
||||
case 5: {
|
||||
if(regs.e)last_cycle();
|
||||
rd.h = op_readstack();
|
||||
if(regs.e) {
|
||||
regs.pc.w = rd.w;
|
||||
status.cycle_pos = 0;
|
||||
}
|
||||
} break;
|
||||
case 6: {
|
||||
last_cycle();
|
||||
rd.b = op_readstack();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_rts() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 3: {
|
||||
rd.l = op_readstack();
|
||||
} break;
|
||||
case 4: {
|
||||
rd.h = op_readstack();
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
cpu_io();
|
||||
regs.pc.w = rd.w;
|
||||
regs.pc.w++;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_rtl() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 3: {
|
||||
rd.l = op_readstack();
|
||||
} break;
|
||||
case 4: {
|
||||
rd.h = op_readstack();
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
rd.b = op_readstack();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
regs.pc.w++;
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,317 +0,0 @@
|
||||
adc_const(0x69, adc, regs.p.m),
|
||||
and_const(0x29, and, regs.p.m),
|
||||
cmp_const(0xc9, cmp, regs.p.m),
|
||||
cpx_const(0xe0, cpx, regs.p.x),
|
||||
cpy_const(0xc0, cpy, regs.p.x),
|
||||
eor_const(0x49, eor, regs.p.m),
|
||||
lda_const(0xa9, lda, regs.p.m),
|
||||
ldx_const(0xa2, ldx, regs.p.x),
|
||||
ldy_const(0xa0, ldy, regs.p.x),
|
||||
ora_const(0x09, ora, regs.p.m),
|
||||
sbc_const(0xe9, sbc, regs.p.m) {
|
||||
1:if($2)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if($2) { op_$1_b(); end; }
|
||||
2:last_cycle();
|
||||
rd.h = op_readpc();
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_addr(0x6d, adc, regs.p.m),
|
||||
and_addr(0x2d, and, regs.p.m),
|
||||
bit_addr(0x2c, bit, regs.p.m),
|
||||
cmp_addr(0xcd, cmp, regs.p.m),
|
||||
cpx_addr(0xec, cpx, regs.p.x),
|
||||
cpy_addr(0xcc, cpy, regs.p.x),
|
||||
eor_addr(0x4d, eor, regs.p.m),
|
||||
lda_addr(0xad, lda, regs.p.m),
|
||||
ldx_addr(0xae, ldx, regs.p.x),
|
||||
ldy_addr(0xac, ldy, regs.p.x),
|
||||
ora_addr(0x0d, ora, regs.p.m),
|
||||
sbc_addr(0xed, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:if($2)last_cycle();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
4:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_addrx(0x7d, adc, regs.p.m),
|
||||
and_addrx(0x3d, and, regs.p.m),
|
||||
bit_addrx(0x3c, bit, regs.p.m),
|
||||
cmp_addrx(0xdd, cmp, regs.p.m),
|
||||
eor_addrx(0x5d, eor, regs.p.m),
|
||||
lda_addrx(0xbd, lda, regs.p.m),
|
||||
ldy_addrx(0xbc, ldy, regs.p.x),
|
||||
ora_addrx(0x1d, ora, regs.p.m),
|
||||
sbc_addrx(0xfd, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:cpu_c4(aa.w, aa.w + regs.x.w);
|
||||
4:if($2)last_cycle();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
5:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_addry(0x79, adc, regs.p.m),
|
||||
and_addry(0x39, and, regs.p.m),
|
||||
cmp_addry(0xd9, cmp, regs.p.m),
|
||||
eor_addry(0x59, eor, regs.p.m),
|
||||
lda_addry(0xb9, lda, regs.p.m),
|
||||
ldx_addry(0xbe, ldx, regs.p.x),
|
||||
ora_addry(0x19, ora, regs.p.m),
|
||||
sbc_addry(0xf9, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:cpu_c4(aa.w, aa.w + regs.y.w);
|
||||
4:if($2)last_cycle();
|
||||
rd.l = op_readdbr(aa.w + regs.y.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
5:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + regs.y.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_long(0x6f, adc, regs.p.m),
|
||||
and_long(0x2f, and, regs.p.m),
|
||||
cmp_long(0xcf, cmp, regs.p.m),
|
||||
eor_long(0x4f, eor, regs.p.m),
|
||||
lda_long(0xaf, lda, regs.p.m),
|
||||
ora_long(0x0f, ora, regs.p.m),
|
||||
sbc_long(0xef, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:aa.b = op_readpc();
|
||||
4:if($2)last_cycle();
|
||||
rd.l = op_readlong(aa.d);
|
||||
if($2) { op_$1_b(); end; }
|
||||
5:last_cycle();
|
||||
rd.h = op_readlong(aa.d + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_longx(0x7f, adc, regs.p.m),
|
||||
and_longx(0x3f, and, regs.p.m),
|
||||
cmp_longx(0xdf, cmp, regs.p.m),
|
||||
eor_longx(0x5f, eor, regs.p.m),
|
||||
lda_longx(0xbf, lda, regs.p.m),
|
||||
ora_longx(0x1f, ora, regs.p.m),
|
||||
sbc_longx(0xff, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:aa.b = op_readpc();
|
||||
4:if($2)last_cycle();
|
||||
rd.l = op_readlong(aa.d + regs.x.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
5:last_cycle();
|
||||
rd.h = op_readlong(aa.d + regs.x.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_dp(0x65, adc, regs.p.m),
|
||||
and_dp(0x25, and, regs.p.m),
|
||||
bit_dp(0x24, bit, regs.p.m),
|
||||
cmp_dp(0xc5, cmp, regs.p.m),
|
||||
cpx_dp(0xe4, cpx, regs.p.x),
|
||||
cpy_dp(0xc4, cpy, regs.p.x),
|
||||
eor_dp(0x45, eor, regs.p.m),
|
||||
lda_dp(0xa5, lda, regs.p.m),
|
||||
ldx_dp(0xa6, ldx, regs.p.x),
|
||||
ldy_dp(0xa4, ldy, regs.p.x),
|
||||
ora_dp(0x05, ora, regs.p.m),
|
||||
sbc_dp(0xe5, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:if($2)last_cycle();
|
||||
rd.l = op_readdp(dp);
|
||||
if($2) { op_$1_b(); end; }
|
||||
4:last_cycle();
|
||||
rd.h = op_readdp(dp + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_dpx(0x75, adc, regs.p.m),
|
||||
and_dpx(0x35, and, regs.p.m),
|
||||
bit_dpx(0x34, bit, regs.p.m),
|
||||
cmp_dpx(0xd5, cmp, regs.p.m),
|
||||
eor_dpx(0x55, eor, regs.p.m),
|
||||
lda_dpx(0xb5, lda, regs.p.m),
|
||||
ldy_dpx(0xb4, ldy, regs.p.x),
|
||||
ora_dpx(0x15, ora, regs.p.m),
|
||||
sbc_dpx(0xf5, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:cpu_io();
|
||||
4:if($2)last_cycle();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
5:last_cycle();
|
||||
rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
ldx_dpy(0xb6, ldx, regs.p.x) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:cpu_io();
|
||||
4:if($2)last_cycle();
|
||||
rd.l = op_readdp(dp + regs.y.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
5:last_cycle();
|
||||
rd.h = op_readdp(dp + regs.y.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_idp(0x72, adc, regs.p.m),
|
||||
and_idp(0x32, and, regs.p.m),
|
||||
cmp_idp(0xd2, cmp, regs.p.m),
|
||||
eor_idp(0x52, eor, regs.p.m),
|
||||
lda_idp(0xb2, lda, regs.p.m),
|
||||
ora_idp(0x12, ora, regs.p.m),
|
||||
sbc_idp(0xf2, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:if($2)last_cycle();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
6:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_idpx(0x61, adc, regs.p.m),
|
||||
and_idpx(0x21, and, regs.p.m),
|
||||
cmp_idpx(0xc1, cmp, regs.p.m),
|
||||
eor_idpx(0x41, eor, regs.p.m),
|
||||
lda_idpx(0xa1, lda, regs.p.m),
|
||||
ora_idpx(0x01, ora, regs.p.m),
|
||||
sbc_idpx(0xe1, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:cpu_io();
|
||||
4:aa.l = op_readdp(dp + regs.x.w);
|
||||
5:aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
6:if($2)last_cycle();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
7:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_idpy(0x71, adc, regs.p.m),
|
||||
and_idpy(0x31, and, regs.p.m),
|
||||
cmp_idpy(0xd1, cmp, regs.p.m),
|
||||
eor_idpy(0x51, eor, regs.p.m),
|
||||
lda_idpy(0xb1, lda, regs.p.m),
|
||||
ora_idpy(0x11, ora, regs.p.m),
|
||||
sbc_idpy(0xf1, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:cpu_c4(aa.w, aa.w + regs.y.w);
|
||||
6:if($2)last_cycle();
|
||||
rd.l = op_readdbr(aa.w + regs.y.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
7:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + regs.y.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_ildp(0x67, adc, regs.p.m),
|
||||
and_ildp(0x27, and, regs.p.m),
|
||||
cmp_ildp(0xc7, cmp, regs.p.m),
|
||||
eor_ildp(0x47, eor, regs.p.m),
|
||||
lda_ildp(0xa7, lda, regs.p.m),
|
||||
ora_ildp(0x07, ora, regs.p.m),
|
||||
sbc_ildp(0xe7, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:aa.b = op_readdp(dp + 2);
|
||||
6:if($2)last_cycle();
|
||||
rd.l = op_readlong(aa.d);
|
||||
if($2) { op_$1_b(); end; }
|
||||
7:last_cycle();
|
||||
rd.h = op_readlong(aa.d + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_ildpy(0x77, adc, regs.p.m),
|
||||
and_ildpy(0x37, and, regs.p.m),
|
||||
cmp_ildpy(0xd7, cmp, regs.p.m),
|
||||
eor_ildpy(0x57, eor, regs.p.m),
|
||||
lda_ildpy(0xb7, lda, regs.p.m),
|
||||
ora_ildpy(0x17, ora, regs.p.m),
|
||||
sbc_ildpy(0xf7, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:aa.b = op_readdp(dp + 2);
|
||||
6:if($2)last_cycle();
|
||||
rd.l = op_readlong(aa.d + regs.y.w);
|
||||
if($2) { op_$1_b(); end; }
|
||||
7:last_cycle();
|
||||
rd.h = op_readlong(aa.d + regs.y.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_sr(0x63, adc, regs.p.m),
|
||||
and_sr(0x23, and, regs.p.m),
|
||||
cmp_sr(0xc3, cmp, regs.p.m),
|
||||
eor_sr(0x43, eor, regs.p.m),
|
||||
lda_sr(0xa3, lda, regs.p.m),
|
||||
ora_sr(0x03, ora, regs.p.m),
|
||||
sbc_sr(0xe3, sbc, regs.p.m) {
|
||||
1:sp = op_readpc();
|
||||
2:cpu_io();
|
||||
3:if($2)last_cycle();
|
||||
rd.l = op_readsp(sp);
|
||||
if($2) { op_$1_b(); end; }
|
||||
4:last_cycle();
|
||||
rd.h = op_readsp(sp + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_isry(0x73, adc),
|
||||
and_isry(0x33, and),
|
||||
cmp_isry(0xd3, cmp),
|
||||
eor_isry(0x53, eor),
|
||||
lda_isry(0xb3, lda),
|
||||
ora_isry(0x13, ora),
|
||||
sbc_isry(0xf3, sbc) {
|
||||
1:sp = op_readpc();
|
||||
2:cpu_io();
|
||||
3:aa.l = op_readsp(sp);
|
||||
4:aa.h = op_readsp(sp + 1);
|
||||
5:cpu_io();
|
||||
6:if(regs.p.m)last_cycle();
|
||||
rd.l = op_readdbr(aa.w + regs.y.w);
|
||||
if(regs.p.m) { op_$1_b(); end; }
|
||||
7:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + regs.y.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
bit_const(0x89) {
|
||||
1:if(regs.p.m)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(regs.p.m) {
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
end;
|
||||
}
|
||||
2:last_cycle();
|
||||
rd.h = op_readpc();
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,185 +0,0 @@
|
||||
inc(0x1a, regs.p.m, a),
|
||||
inx(0xe8, regs.p.x, x),
|
||||
iny(0xc8, regs.p.x, y) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
if($1) {
|
||||
regs.$2.l++;
|
||||
regs.p.n = !!(regs.$2.l & 0x80);
|
||||
regs.p.z = (regs.$2.l == 0);
|
||||
} else {
|
||||
regs.$2.w++;
|
||||
regs.p.n = !!(regs.$2.w & 0x8000);
|
||||
regs.p.z = (regs.$2.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
dec(0x3a, regs.p.m, a),
|
||||
dex(0xca, regs.p.x, x),
|
||||
dey(0x88, regs.p.x, y) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
if($1) {
|
||||
regs.$2.l--;
|
||||
regs.p.n = !!(regs.$2.l & 0x80);
|
||||
regs.p.z = (regs.$2.l == 0);
|
||||
} else {
|
||||
regs.$2.w--;
|
||||
regs.p.n = !!(regs.$2.w & 0x8000);
|
||||
regs.p.z = (regs.$2.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
asl(0x0a) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
if(regs.p.m) {
|
||||
regs.p.c = !!(regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = !!(regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
lsr(0x4a) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
if(regs.p.m) {
|
||||
regs.p.c = regs.a.l & 1;
|
||||
regs.a.l >>= 1;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = regs.a.w & 1;
|
||||
regs.a.w >>= 1;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
rol(0x2a) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
uint16 c = regs.p.c;
|
||||
if(regs.p.m) {
|
||||
regs.p.c = !!(regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.a.l |= c;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = !!(regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.a.w |= c;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
ror(0x6a) {
|
||||
1:last_cycle();
|
||||
cpu_io();
|
||||
uint16 c;
|
||||
if(regs.p.m) {
|
||||
c = (regs.p.c)?0x80:0;
|
||||
regs.p.c = regs.a.l & 1;
|
||||
regs.a.l >>= 1;
|
||||
regs.a.l |= c;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
c = (regs.p.c)?0x8000:0;
|
||||
regs.p.c = regs.a.w & 1;
|
||||
regs.a.w >>= 1;
|
||||
regs.a.w |= c;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
inc_addr(0xee, inc),
|
||||
dec_addr(0xce, dec),
|
||||
asl_addr(0x0e, asl),
|
||||
lsr_addr(0x4e, lsr),
|
||||
rol_addr(0x2e, rol),
|
||||
ror_addr(0x6e, ror),
|
||||
trb_addr(0x1c, trb),
|
||||
tsb_addr(0x0c, tsb) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:rd.l = op_readdbr(aa.w);
|
||||
if(regs.p.m)skip;
|
||||
4:rd.h = op_readdbr(aa.w + 1);
|
||||
5:cpu_io();
|
||||
if(regs.p.m) { op_$1_b(); skip; }
|
||||
else op_$1_w();
|
||||
6:op_writedbr(aa.w + 1, rd.h);
|
||||
7:last_cycle();
|
||||
op_writedbr(aa.w, rd.l);
|
||||
}
|
||||
|
||||
inc_addrx(0xfe, inc),
|
||||
dec_addrx(0xde, dec),
|
||||
asl_addrx(0x1e, asl),
|
||||
lsr_addrx(0x5e, lsr),
|
||||
rol_addrx(0x3e, rol),
|
||||
ror_addrx(0x7e, ror) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:cpu_io();
|
||||
4:rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(regs.p.m)skip;
|
||||
5:rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
6:cpu_io();
|
||||
if(regs.p.m) { op_$1_b(); skip; }
|
||||
else op_$1_w();
|
||||
7:op_writedbr(aa.w + regs.x.w + 1, rd.h);
|
||||
8:last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, rd.l);
|
||||
}
|
||||
|
||||
inc_dp(0xe6, inc),
|
||||
dec_dp(0xc6, dec),
|
||||
asl_dp(0x06, asl),
|
||||
lsr_dp(0x46, lsr),
|
||||
rol_dp(0x26, rol),
|
||||
ror_dp(0x66, ror),
|
||||
trb_dp(0x14, trb),
|
||||
tsb_dp(0x04, tsb) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:rd.l = op_readdp(dp);
|
||||
if(regs.p.m)skip;
|
||||
4:rd.h = op_readdp(dp + 1);
|
||||
5:cpu_io();
|
||||
if(regs.p.m) { op_$1_b(); skip; }
|
||||
else op_$1_w();
|
||||
6:op_writedp(dp + 1, rd.h);
|
||||
7:last_cycle();
|
||||
op_writedp(dp, rd.l);
|
||||
}
|
||||
|
||||
inc_dpx(0xf6, inc),
|
||||
dec_dpx(0xd6, dec),
|
||||
asl_dpx(0x16, asl),
|
||||
lsr_dpx(0x56, lsr),
|
||||
rol_dpx(0x36, rol),
|
||||
ror_dpx(0x76, ror) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:cpu_io();
|
||||
4:rd.l = op_readdp(dp + regs.x.w);
|
||||
if(regs.p.m)skip;
|
||||
5:rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
6:cpu_io();
|
||||
if(regs.p.m) { op_$1_b(); skip; }
|
||||
else op_$1_w();
|
||||
7:op_writedp(dp + regs.x.w + 1, rd.h);
|
||||
8:last_cycle();
|
||||
op_writedp(dp + regs.x.w, rd.l);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,181 +0,0 @@
|
||||
sta_addr(0x8d, regs.p.m, regs.a.w),
|
||||
stx_addr(0x8e, regs.p.x, regs.x.w),
|
||||
sty_addr(0x8c, regs.p.x, regs.y.w),
|
||||
stz_addr(0x9c, regs.p.m, 0x0000) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:if($1)last_cycle();
|
||||
op_writedbr(aa.w, $2);
|
||||
if($1)end;
|
||||
4:last_cycle();
|
||||
op_writedbr(aa.w + 1, $2 >> 8);
|
||||
}
|
||||
|
||||
sta_addrx(0x9d, regs.p.m, regs.a.w),
|
||||
stz_addrx(0x9e, regs.p.m, 0x0000) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:cpu_io();
|
||||
4:if($1)last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, $2);
|
||||
if($1)end;
|
||||
5:last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w + 1, $2 >> 8);
|
||||
}
|
||||
|
||||
sta_addry(0x99) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:cpu_io();
|
||||
4:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
5:last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_long(0x8f) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:aa.b = op_readpc();
|
||||
4:if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
5:last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_longx(0x9f) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:aa.b = op_readpc();
|
||||
4:if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d + regs.x.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
5:last_cycle();
|
||||
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_dp(0x85, regs.p.m, regs.a.w),
|
||||
stx_dp(0x86, regs.p.x, regs.x.w),
|
||||
sty_dp(0x84, regs.p.x, regs.y.w),
|
||||
stz_dp(0x64, regs.p.m, 0x0000) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:if($1)last_cycle();
|
||||
op_writedp(dp, $2);
|
||||
if($1)end;
|
||||
4:last_cycle();
|
||||
op_writedp(dp + 1, $2 >> 8);
|
||||
}
|
||||
|
||||
sta_dpx(0x95, regs.p.m, regs.a.w),
|
||||
sty_dpx(0x94, regs.p.x, regs.y.w),
|
||||
stz_dpx(0x74, regs.p.m, 0x0000) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:cpu_io();
|
||||
4:if($1)last_cycle();
|
||||
op_writedp(dp + regs.x.w, $2);
|
||||
if($1)end;
|
||||
5:last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, $2 >> 8);
|
||||
}
|
||||
|
||||
stx_dpy(0x96) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:cpu_io();
|
||||
4:if(regs.p.x)last_cycle();
|
||||
op_writedp(dp + regs.y.w, regs.x.l);
|
||||
if(regs.p.x)end;
|
||||
5:last_cycle();
|
||||
op_writedp(dp + regs.y.w + 1, regs.x.h);
|
||||
}
|
||||
|
||||
sta_idp(0x92) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
6:last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_ildp(0x87) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:aa.b = op_readdp(dp + 2);
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_idpx(0x81) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:cpu_io();
|
||||
4:aa.l = op_readdp(dp + regs.x.w);
|
||||
5:aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_idpy(0x91) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:cpu_io();
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_ildpy(0x97) {
|
||||
1:dp = op_readpc();
|
||||
2:cpu_c2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:aa.b = op_readdp(dp + 2);
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_sr(0x83) {
|
||||
1:sp = op_readpc();
|
||||
2:cpu_io();
|
||||
3:if(regs.p.m)last_cycle();
|
||||
op_writesp(sp, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
4:last_cycle();
|
||||
op_writesp(sp + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_isry(0x93) {
|
||||
1:sp = op_readpc();
|
||||
2:cpu_io();
|
||||
3:aa.l = op_readsp(sp);
|
||||
4:aa.h = op_readsp(sp + 1);
|
||||
5:cpu_io();
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
@@ -1,582 +0,0 @@
|
||||
void bCPU::op_sta_addr() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.w);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.w >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_stx_addr() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedbr(aa.w, regs.x.w);
|
||||
if(regs.p.x)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.x.w >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sty_addr() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedbr(aa.w, regs.y.w);
|
||||
if(regs.p.x)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.y.w >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_stz_addr() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, 0x0000);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, 0x0000 >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_addrx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
cpu_c4(aa.w, aa.w + regs.x.w);
|
||||
} break;
|
||||
case 4: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, regs.a.w);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w + 1, regs.a.w >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_stz_addrx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
cpu_c4(aa.w, aa.w + regs.x.w);
|
||||
} break;
|
||||
case 4: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, 0x0000);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w + 1, 0x0000 >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_addry() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
cpu_c4(aa.w, aa.w + regs.y.w);
|
||||
} break;
|
||||
case 4: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_long() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
aa.b = op_readpc();
|
||||
} break;
|
||||
case 4: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_longx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
aa.l = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
aa.h = op_readpc();
|
||||
} break;
|
||||
case 3: {
|
||||
aa.b = op_readpc();
|
||||
} break;
|
||||
case 4: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d + regs.x.w, regs.a.l);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_dp() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedp(dp, regs.a.w);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, regs.a.w >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_stx_dp() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedp(dp, regs.x.w);
|
||||
if(regs.p.x)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, regs.x.w >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sty_dp() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedp(dp, regs.y.w);
|
||||
if(regs.p.x)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, regs.y.w >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_stz_dp() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedp(dp, 0x0000);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, 0x0000 >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_dpx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 4: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedp(dp + regs.x.w, regs.a.w);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, regs.a.w >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sty_dpx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 4: {
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedp(dp + regs.x.w, regs.y.w);
|
||||
if(regs.p.x)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, regs.y.w >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_stz_dpx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 4: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedp(dp + regs.x.w, 0x0000);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, 0x0000 >> 8);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_stx_dpy() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 4: {
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedp(dp + regs.y.w, regs.x.l);
|
||||
if(regs.p.x)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 5: {
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.y.w + 1, regs.x.h);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_idp() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
aa.l = op_readdp(dp);
|
||||
} break;
|
||||
case 4: {
|
||||
aa.h = op_readdp(dp + 1);
|
||||
} break;
|
||||
case 5: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 6: {
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_ildp() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
aa.l = op_readdp(dp);
|
||||
} break;
|
||||
case 4: {
|
||||
aa.h = op_readdp(dp + 1);
|
||||
} break;
|
||||
case 5: {
|
||||
aa.b = op_readdp(dp + 2);
|
||||
} break;
|
||||
case 6: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 7: {
|
||||
last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_idpx() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 4: {
|
||||
aa.l = op_readdp(dp + regs.x.w);
|
||||
} break;
|
||||
case 5: {
|
||||
aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
} break;
|
||||
case 6: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 7: {
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_idpy() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
aa.l = op_readdp(dp);
|
||||
} break;
|
||||
case 4: {
|
||||
aa.h = op_readdp(dp + 1);
|
||||
} break;
|
||||
case 5: {
|
||||
cpu_c4(aa.w, aa.w + regs.y.w);
|
||||
} break;
|
||||
case 6: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 7: {
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_ildpy() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
dp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_c2();
|
||||
} break;
|
||||
case 3: {
|
||||
aa.l = op_readdp(dp);
|
||||
} break;
|
||||
case 4: {
|
||||
aa.h = op_readdp(dp + 1);
|
||||
} break;
|
||||
case 5: {
|
||||
aa.b = op_readdp(dp + 2);
|
||||
} break;
|
||||
case 6: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 7: {
|
||||
last_cycle();
|
||||
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_sr() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
sp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 3: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writesp(sp, regs.a.l);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 4: {
|
||||
last_cycle();
|
||||
op_writesp(sp + 1, regs.a.h);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::op_sta_isry() {
|
||||
switch(status.cycle_pos++) {
|
||||
case 1: {
|
||||
sp = op_readpc();
|
||||
} break;
|
||||
case 2: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 3: {
|
||||
aa.l = op_readsp(sp);
|
||||
} break;
|
||||
case 4: {
|
||||
aa.h = op_readsp(sp + 1);
|
||||
} break;
|
||||
case 5: {
|
||||
cpu_io();
|
||||
} break;
|
||||
case 6: {
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.p.m)status.cycle_pos = 0;
|
||||
} break;
|
||||
case 7: {
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
status.cycle_pos = 0;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,377 +0,0 @@
|
||||
//op_read
|
||||
inline void bCPU::op_adc_b() {
|
||||
int32 r = regs.a.l + rd.l + regs.p.c;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.l ) & 15;
|
||||
uint8 n1 = (regs.a.l >> 4) & 15;
|
||||
n0 += ((rd.l) & 15) + regs.p.c;
|
||||
if(n0 > 9) {
|
||||
n0 -= 10;
|
||||
n0 &= 15;
|
||||
n1++;
|
||||
}
|
||||
n1 += ((rd.l >> 4) & 15);
|
||||
if(n1 > 9) {
|
||||
n1 -= 10;
|
||||
n1 &= 15;
|
||||
regs.p.c = 1;
|
||||
} else {
|
||||
regs.p.c = 0;
|
||||
}
|
||||
r = (n1 << 4) | (n0);
|
||||
} else {
|
||||
r = regs.a.l + rd.l + regs.p.c;
|
||||
regs.p.c = (r > 0xff);
|
||||
}
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.v = !!(~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.a.l = r;
|
||||
}
|
||||
|
||||
inline void bCPU::op_adc_w() {
|
||||
int32 r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.w ) & 15;
|
||||
uint8 n1 = (regs.a.w >> 4) & 15;
|
||||
uint8 n2 = (regs.a.w >> 8) & 15;
|
||||
uint8 n3 = (regs.a.w >> 12) & 15;
|
||||
n0 += ((rd.w) & 15) + regs.p.c;
|
||||
if(n0 > 9) {
|
||||
n0 -= 10;
|
||||
n0 &= 15;
|
||||
n1++;
|
||||
}
|
||||
n1 += ((rd.w >> 4) & 15);
|
||||
if(n1 > 9) {
|
||||
n1 -= 10;
|
||||
n1 &= 15;
|
||||
n2++;
|
||||
}
|
||||
n2 += ((rd.w >> 8) & 15);
|
||||
if(n2 > 9) {
|
||||
n2 -= 10;
|
||||
n2 &= 15;
|
||||
n3++;
|
||||
}
|
||||
n3 += ((rd.w >> 12) & 15);
|
||||
if(n3 > 9) {
|
||||
n3 -= 10;
|
||||
n3 &= 15;
|
||||
regs.p.c = 1;
|
||||
} else {
|
||||
regs.p.c = 0;
|
||||
}
|
||||
r = (n3 << 12) | (n2 << 8) | (n1 << 4) | (n0);
|
||||
} else {
|
||||
r = regs.a.w + rd.w + regs.p.c;
|
||||
regs.p.c = (r > 0xffff);
|
||||
}
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.v = !!(~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.a.w = r;
|
||||
}
|
||||
|
||||
inline void bCPU::op_and_b() {
|
||||
regs.a.l &= rd.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_and_w() {
|
||||
regs.a.w &= rd.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_bit_b() {
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.v = !!(rd.l & 0x40);
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_bit_w() {
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.v = !!(rd.w & 0x4000);
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_cmp_b() {
|
||||
int32 r = regs.a.l - rd.l;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_cmp_w() {
|
||||
int32 r = regs.a.w - rd.w;
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_cpx_b() {
|
||||
int32 r = regs.x.l - rd.l;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_cpx_w() {
|
||||
int32 r = regs.x.w - rd.w;
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_cpy_b() {
|
||||
int32 r = regs.y.l - rd.l;
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_cpy_w() {
|
||||
int32 r = regs.y.w - rd.w;
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_eor_b() {
|
||||
regs.a.l ^= rd.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_eor_w() {
|
||||
regs.a.w ^= rd.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_lda_b() {
|
||||
regs.a.l = rd.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_lda_w() {
|
||||
regs.a.w = rd.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_ldx_b() {
|
||||
regs.x.l = rd.l;
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_ldx_w() {
|
||||
regs.x.w = rd.w;
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_ldy_b() {
|
||||
regs.y.l = rd.l;
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_ldy_w() {
|
||||
regs.y.w = rd.w;
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_ora_b() {
|
||||
regs.a.l |= rd.l;
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_ora_w() {
|
||||
regs.a.w |= rd.w;
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_sbc_b() {
|
||||
int32 r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.l ) & 15;
|
||||
uint8 n1 = (regs.a.l >> 4) & 15;
|
||||
n0 -= ((rd.l ) & 15) + !regs.p.c;
|
||||
n1 -= ((rd.l >> 4) & 15);
|
||||
if(n0 > 9) {
|
||||
n0 += 10;
|
||||
n1--;
|
||||
}
|
||||
if(n1 > 9) {
|
||||
n1 += 10;
|
||||
regs.p.c = 0;
|
||||
} else {
|
||||
regs.p.c = 1;
|
||||
}
|
||||
r = (n1 << 4) | (n0);
|
||||
} else {
|
||||
r = regs.a.l - rd.l - !regs.p.c;
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.v = !!((regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.a.l = r;
|
||||
}
|
||||
|
||||
inline void bCPU::op_sbc_w() {
|
||||
int32 r;
|
||||
if(regs.p.d) {
|
||||
uint8 n0 = (regs.a.w ) & 15;
|
||||
uint8 n1 = (regs.a.w >> 4) & 15;
|
||||
uint8 n2 = (regs.a.w >> 8) & 15;
|
||||
uint8 n3 = (regs.a.w >> 12) & 15;
|
||||
n0 -= ((rd.w ) & 15) + !regs.p.c;
|
||||
n1 -= ((rd.w >> 4) & 15);
|
||||
n2 -= ((rd.w >> 8) & 15);
|
||||
n3 -= ((rd.w >> 12) & 15);
|
||||
if(n0 > 9) {
|
||||
n0 += 10;
|
||||
n1--;
|
||||
}
|
||||
if(n1 > 9) {
|
||||
n1 += 10;
|
||||
n2--;
|
||||
}
|
||||
if(n2 > 9) {
|
||||
n2 += 10;
|
||||
n3--;
|
||||
}
|
||||
if(n3 > 9) {
|
||||
n3 += 10;
|
||||
regs.p.c = 0;
|
||||
} else {
|
||||
regs.p.c = 1;
|
||||
}
|
||||
r = (n3 << 12) | (n2 << 8) | (n1 << 4) | (n0);
|
||||
} else {
|
||||
r = regs.a.w - rd.w - !regs.p.c;
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.v = !!((regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.a.w = r;
|
||||
}
|
||||
|
||||
//op_rmw
|
||||
inline void bCPU::op_inc_b() {
|
||||
rd.l++;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_inc_w() {
|
||||
rd.w++;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_dec_b() {
|
||||
rd.l--;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_dec_w() {
|
||||
rd.w--;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_asl_b() {
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_asl_w() {
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_lsr_b() {
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_lsr_w() {
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_rol_b() {
|
||||
uint16 c = regs.p.c;
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
rd.l |= c;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_rol_w() {
|
||||
uint16 c = regs.p.c;
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
rd.w |= c;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_ror_b() {
|
||||
uint16 c = (regs.p.c)?0x80:0;
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
rd.l |= c;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_ror_w() {
|
||||
uint16 c = (regs.p.c)?0x8000:0;
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
rd.w |= c;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void bCPU::op_trb_b() {
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
rd.l &= ~regs.a.l;
|
||||
}
|
||||
|
||||
inline void bCPU::op_trb_w() {
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
rd.w &= ~regs.a.w;
|
||||
}
|
||||
|
||||
inline void bCPU::op_tsb_b() {
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
rd.l |= regs.a.l;
|
||||
}
|
||||
|
||||
inline void bCPU::op_tsb_w() {
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
rd.w |= regs.a.w;
|
||||
}
|
||||
@@ -1,256 +0,0 @@
|
||||
optbl[0x69] = &bCPU::op_adc_const;
|
||||
optbl[0x29] = &bCPU::op_and_const;
|
||||
optbl[0xc9] = &bCPU::op_cmp_const;
|
||||
optbl[0xe0] = &bCPU::op_cpx_const;
|
||||
optbl[0xc0] = &bCPU::op_cpy_const;
|
||||
optbl[0x49] = &bCPU::op_eor_const;
|
||||
optbl[0xa9] = &bCPU::op_lda_const;
|
||||
optbl[0xa2] = &bCPU::op_ldx_const;
|
||||
optbl[0xa0] = &bCPU::op_ldy_const;
|
||||
optbl[0x09] = &bCPU::op_ora_const;
|
||||
optbl[0xe9] = &bCPU::op_sbc_const;
|
||||
optbl[0x6d] = &bCPU::op_adc_addr;
|
||||
optbl[0x2d] = &bCPU::op_and_addr;
|
||||
optbl[0x2c] = &bCPU::op_bit_addr;
|
||||
optbl[0xcd] = &bCPU::op_cmp_addr;
|
||||
optbl[0xec] = &bCPU::op_cpx_addr;
|
||||
optbl[0xcc] = &bCPU::op_cpy_addr;
|
||||
optbl[0x4d] = &bCPU::op_eor_addr;
|
||||
optbl[0xad] = &bCPU::op_lda_addr;
|
||||
optbl[0xae] = &bCPU::op_ldx_addr;
|
||||
optbl[0xac] = &bCPU::op_ldy_addr;
|
||||
optbl[0x0d] = &bCPU::op_ora_addr;
|
||||
optbl[0xed] = &bCPU::op_sbc_addr;
|
||||
optbl[0x7d] = &bCPU::op_adc_addrx;
|
||||
optbl[0x3d] = &bCPU::op_and_addrx;
|
||||
optbl[0x3c] = &bCPU::op_bit_addrx;
|
||||
optbl[0xdd] = &bCPU::op_cmp_addrx;
|
||||
optbl[0x5d] = &bCPU::op_eor_addrx;
|
||||
optbl[0xbd] = &bCPU::op_lda_addrx;
|
||||
optbl[0xbc] = &bCPU::op_ldy_addrx;
|
||||
optbl[0x1d] = &bCPU::op_ora_addrx;
|
||||
optbl[0xfd] = &bCPU::op_sbc_addrx;
|
||||
optbl[0x79] = &bCPU::op_adc_addry;
|
||||
optbl[0x39] = &bCPU::op_and_addry;
|
||||
optbl[0xd9] = &bCPU::op_cmp_addry;
|
||||
optbl[0x59] = &bCPU::op_eor_addry;
|
||||
optbl[0xb9] = &bCPU::op_lda_addry;
|
||||
optbl[0xbe] = &bCPU::op_ldx_addry;
|
||||
optbl[0x19] = &bCPU::op_ora_addry;
|
||||
optbl[0xf9] = &bCPU::op_sbc_addry;
|
||||
optbl[0x6f] = &bCPU::op_adc_long;
|
||||
optbl[0x2f] = &bCPU::op_and_long;
|
||||
optbl[0xcf] = &bCPU::op_cmp_long;
|
||||
optbl[0x4f] = &bCPU::op_eor_long;
|
||||
optbl[0xaf] = &bCPU::op_lda_long;
|
||||
optbl[0x0f] = &bCPU::op_ora_long;
|
||||
optbl[0xef] = &bCPU::op_sbc_long;
|
||||
optbl[0x7f] = &bCPU::op_adc_longx;
|
||||
optbl[0x3f] = &bCPU::op_and_longx;
|
||||
optbl[0xdf] = &bCPU::op_cmp_longx;
|
||||
optbl[0x5f] = &bCPU::op_eor_longx;
|
||||
optbl[0xbf] = &bCPU::op_lda_longx;
|
||||
optbl[0x1f] = &bCPU::op_ora_longx;
|
||||
optbl[0xff] = &bCPU::op_sbc_longx;
|
||||
optbl[0x65] = &bCPU::op_adc_dp;
|
||||
optbl[0x25] = &bCPU::op_and_dp;
|
||||
optbl[0x24] = &bCPU::op_bit_dp;
|
||||
optbl[0xc5] = &bCPU::op_cmp_dp;
|
||||
optbl[0xe4] = &bCPU::op_cpx_dp;
|
||||
optbl[0xc4] = &bCPU::op_cpy_dp;
|
||||
optbl[0x45] = &bCPU::op_eor_dp;
|
||||
optbl[0xa5] = &bCPU::op_lda_dp;
|
||||
optbl[0xa6] = &bCPU::op_ldx_dp;
|
||||
optbl[0xa4] = &bCPU::op_ldy_dp;
|
||||
optbl[0x05] = &bCPU::op_ora_dp;
|
||||
optbl[0xe5] = &bCPU::op_sbc_dp;
|
||||
optbl[0x75] = &bCPU::op_adc_dpx;
|
||||
optbl[0x35] = &bCPU::op_and_dpx;
|
||||
optbl[0x34] = &bCPU::op_bit_dpx;
|
||||
optbl[0xd5] = &bCPU::op_cmp_dpx;
|
||||
optbl[0x55] = &bCPU::op_eor_dpx;
|
||||
optbl[0xb5] = &bCPU::op_lda_dpx;
|
||||
optbl[0xb4] = &bCPU::op_ldy_dpx;
|
||||
optbl[0x15] = &bCPU::op_ora_dpx;
|
||||
optbl[0xf5] = &bCPU::op_sbc_dpx;
|
||||
optbl[0xb6] = &bCPU::op_ldx_dpy;
|
||||
optbl[0x72] = &bCPU::op_adc_idp;
|
||||
optbl[0x32] = &bCPU::op_and_idp;
|
||||
optbl[0xd2] = &bCPU::op_cmp_idp;
|
||||
optbl[0x52] = &bCPU::op_eor_idp;
|
||||
optbl[0xb2] = &bCPU::op_lda_idp;
|
||||
optbl[0x12] = &bCPU::op_ora_idp;
|
||||
optbl[0xf2] = &bCPU::op_sbc_idp;
|
||||
optbl[0x61] = &bCPU::op_adc_idpx;
|
||||
optbl[0x21] = &bCPU::op_and_idpx;
|
||||
optbl[0xc1] = &bCPU::op_cmp_idpx;
|
||||
optbl[0x41] = &bCPU::op_eor_idpx;
|
||||
optbl[0xa1] = &bCPU::op_lda_idpx;
|
||||
optbl[0x01] = &bCPU::op_ora_idpx;
|
||||
optbl[0xe1] = &bCPU::op_sbc_idpx;
|
||||
optbl[0x71] = &bCPU::op_adc_idpy;
|
||||
optbl[0x31] = &bCPU::op_and_idpy;
|
||||
optbl[0xd1] = &bCPU::op_cmp_idpy;
|
||||
optbl[0x51] = &bCPU::op_eor_idpy;
|
||||
optbl[0xb1] = &bCPU::op_lda_idpy;
|
||||
optbl[0x11] = &bCPU::op_ora_idpy;
|
||||
optbl[0xf1] = &bCPU::op_sbc_idpy;
|
||||
optbl[0x67] = &bCPU::op_adc_ildp;
|
||||
optbl[0x27] = &bCPU::op_and_ildp;
|
||||
optbl[0xc7] = &bCPU::op_cmp_ildp;
|
||||
optbl[0x47] = &bCPU::op_eor_ildp;
|
||||
optbl[0xa7] = &bCPU::op_lda_ildp;
|
||||
optbl[0x07] = &bCPU::op_ora_ildp;
|
||||
optbl[0xe7] = &bCPU::op_sbc_ildp;
|
||||
optbl[0x77] = &bCPU::op_adc_ildpy;
|
||||
optbl[0x37] = &bCPU::op_and_ildpy;
|
||||
optbl[0xd7] = &bCPU::op_cmp_ildpy;
|
||||
optbl[0x57] = &bCPU::op_eor_ildpy;
|
||||
optbl[0xb7] = &bCPU::op_lda_ildpy;
|
||||
optbl[0x17] = &bCPU::op_ora_ildpy;
|
||||
optbl[0xf7] = &bCPU::op_sbc_ildpy;
|
||||
optbl[0x63] = &bCPU::op_adc_sr;
|
||||
optbl[0x23] = &bCPU::op_and_sr;
|
||||
optbl[0xc3] = &bCPU::op_cmp_sr;
|
||||
optbl[0x43] = &bCPU::op_eor_sr;
|
||||
optbl[0xa3] = &bCPU::op_lda_sr;
|
||||
optbl[0x03] = &bCPU::op_ora_sr;
|
||||
optbl[0xe3] = &bCPU::op_sbc_sr;
|
||||
optbl[0x73] = &bCPU::op_adc_isry;
|
||||
optbl[0x33] = &bCPU::op_and_isry;
|
||||
optbl[0xd3] = &bCPU::op_cmp_isry;
|
||||
optbl[0x53] = &bCPU::op_eor_isry;
|
||||
optbl[0xb3] = &bCPU::op_lda_isry;
|
||||
optbl[0x13] = &bCPU::op_ora_isry;
|
||||
optbl[0xf3] = &bCPU::op_sbc_isry;
|
||||
optbl[0x89] = &bCPU::op_bit_const;
|
||||
optbl[0x1a] = &bCPU::op_inc;
|
||||
optbl[0xe8] = &bCPU::op_inx;
|
||||
optbl[0xc8] = &bCPU::op_iny;
|
||||
optbl[0x3a] = &bCPU::op_dec;
|
||||
optbl[0xca] = &bCPU::op_dex;
|
||||
optbl[0x88] = &bCPU::op_dey;
|
||||
optbl[0x0a] = &bCPU::op_asl;
|
||||
optbl[0x4a] = &bCPU::op_lsr;
|
||||
optbl[0x2a] = &bCPU::op_rol;
|
||||
optbl[0x6a] = &bCPU::op_ror;
|
||||
optbl[0xee] = &bCPU::op_inc_addr;
|
||||
optbl[0xce] = &bCPU::op_dec_addr;
|
||||
optbl[0x0e] = &bCPU::op_asl_addr;
|
||||
optbl[0x4e] = &bCPU::op_lsr_addr;
|
||||
optbl[0x2e] = &bCPU::op_rol_addr;
|
||||
optbl[0x6e] = &bCPU::op_ror_addr;
|
||||
optbl[0x1c] = &bCPU::op_trb_addr;
|
||||
optbl[0x0c] = &bCPU::op_tsb_addr;
|
||||
optbl[0xfe] = &bCPU::op_inc_addrx;
|
||||
optbl[0xde] = &bCPU::op_dec_addrx;
|
||||
optbl[0x1e] = &bCPU::op_asl_addrx;
|
||||
optbl[0x5e] = &bCPU::op_lsr_addrx;
|
||||
optbl[0x3e] = &bCPU::op_rol_addrx;
|
||||
optbl[0x7e] = &bCPU::op_ror_addrx;
|
||||
optbl[0xe6] = &bCPU::op_inc_dp;
|
||||
optbl[0xc6] = &bCPU::op_dec_dp;
|
||||
optbl[0x06] = &bCPU::op_asl_dp;
|
||||
optbl[0x46] = &bCPU::op_lsr_dp;
|
||||
optbl[0x26] = &bCPU::op_rol_dp;
|
||||
optbl[0x66] = &bCPU::op_ror_dp;
|
||||
optbl[0x14] = &bCPU::op_trb_dp;
|
||||
optbl[0x04] = &bCPU::op_tsb_dp;
|
||||
optbl[0xf6] = &bCPU::op_inc_dpx;
|
||||
optbl[0xd6] = &bCPU::op_dec_dpx;
|
||||
optbl[0x16] = &bCPU::op_asl_dpx;
|
||||
optbl[0x56] = &bCPU::op_lsr_dpx;
|
||||
optbl[0x36] = &bCPU::op_rol_dpx;
|
||||
optbl[0x76] = &bCPU::op_ror_dpx;
|
||||
optbl[0x8d] = &bCPU::op_sta_addr;
|
||||
optbl[0x8e] = &bCPU::op_stx_addr;
|
||||
optbl[0x8c] = &bCPU::op_sty_addr;
|
||||
optbl[0x9c] = &bCPU::op_stz_addr;
|
||||
optbl[0x9d] = &bCPU::op_sta_addrx;
|
||||
optbl[0x9e] = &bCPU::op_stz_addrx;
|
||||
optbl[0x99] = &bCPU::op_sta_addry;
|
||||
optbl[0x8f] = &bCPU::op_sta_long;
|
||||
optbl[0x9f] = &bCPU::op_sta_longx;
|
||||
optbl[0x85] = &bCPU::op_sta_dp;
|
||||
optbl[0x86] = &bCPU::op_stx_dp;
|
||||
optbl[0x84] = &bCPU::op_sty_dp;
|
||||
optbl[0x64] = &bCPU::op_stz_dp;
|
||||
optbl[0x95] = &bCPU::op_sta_dpx;
|
||||
optbl[0x94] = &bCPU::op_sty_dpx;
|
||||
optbl[0x74] = &bCPU::op_stz_dpx;
|
||||
optbl[0x96] = &bCPU::op_stx_dpy;
|
||||
optbl[0x92] = &bCPU::op_sta_idp;
|
||||
optbl[0x87] = &bCPU::op_sta_ildp;
|
||||
optbl[0x81] = &bCPU::op_sta_idpx;
|
||||
optbl[0x91] = &bCPU::op_sta_idpy;
|
||||
optbl[0x97] = &bCPU::op_sta_ildpy;
|
||||
optbl[0x83] = &bCPU::op_sta_sr;
|
||||
optbl[0x93] = &bCPU::op_sta_isry;
|
||||
optbl[0x90] = &bCPU::op_bcc;
|
||||
optbl[0xb0] = &bCPU::op_bcs;
|
||||
optbl[0xd0] = &bCPU::op_bne;
|
||||
optbl[0xf0] = &bCPU::op_beq;
|
||||
optbl[0x10] = &bCPU::op_bpl;
|
||||
optbl[0x30] = &bCPU::op_bmi;
|
||||
optbl[0x50] = &bCPU::op_bvc;
|
||||
optbl[0x70] = &bCPU::op_bvs;
|
||||
optbl[0x80] = &bCPU::op_bra;
|
||||
optbl[0x82] = &bCPU::op_brl;
|
||||
optbl[0x4c] = &bCPU::op_jmp_addr;
|
||||
optbl[0x5c] = &bCPU::op_jmp_long;
|
||||
optbl[0x6c] = &bCPU::op_jmp_iaddr;
|
||||
optbl[0x7c] = &bCPU::op_jmp_iaddrx;
|
||||
optbl[0xdc] = &bCPU::op_jmp_iladdr;
|
||||
optbl[0x20] = &bCPU::op_jsr_addr;
|
||||
optbl[0x22] = &bCPU::op_jsr_long;
|
||||
optbl[0xfc] = &bCPU::op_jsr_iaddrx;
|
||||
optbl[0x40] = &bCPU::op_rti;
|
||||
optbl[0x60] = &bCPU::op_rts;
|
||||
optbl[0x6b] = &bCPU::op_rtl;
|
||||
optbl[0xea] = &bCPU::op_nop;
|
||||
optbl[0x42] = &bCPU::op_wdm;
|
||||
optbl[0xeb] = &bCPU::op_xba;
|
||||
optbl[0x54] = &bCPU::op_mvn;
|
||||
optbl[0x44] = &bCPU::op_mvp;
|
||||
optbl[0x00] = &bCPU::op_brk;
|
||||
optbl[0x02] = &bCPU::op_cop;
|
||||
optbl[0xdb] = &bCPU::op_stp;
|
||||
optbl[0xcb] = &bCPU::op_wai;
|
||||
optbl[0xfb] = &bCPU::op_xce;
|
||||
optbl[0x18] = &bCPU::op_clc;
|
||||
optbl[0xd8] = &bCPU::op_cld;
|
||||
optbl[0x58] = &bCPU::op_cli;
|
||||
optbl[0xb8] = &bCPU::op_clv;
|
||||
optbl[0x38] = &bCPU::op_sec;
|
||||
optbl[0xf8] = &bCPU::op_sed;
|
||||
optbl[0x78] = &bCPU::op_sei;
|
||||
optbl[0xc2] = &bCPU::op_rep;
|
||||
optbl[0xe2] = &bCPU::op_sep;
|
||||
optbl[0xaa] = &bCPU::op_tax;
|
||||
optbl[0xa8] = &bCPU::op_tay;
|
||||
optbl[0x8a] = &bCPU::op_txa;
|
||||
optbl[0x9b] = &bCPU::op_txy;
|
||||
optbl[0x98] = &bCPU::op_tya;
|
||||
optbl[0xbb] = &bCPU::op_tyx;
|
||||
optbl[0x5b] = &bCPU::op_tcd;
|
||||
optbl[0x1b] = &bCPU::op_tcs;
|
||||
optbl[0x7b] = &bCPU::op_tdc;
|
||||
optbl[0x3b] = &bCPU::op_tsc;
|
||||
optbl[0xba] = &bCPU::op_tsx;
|
||||
optbl[0x9a] = &bCPU::op_txs;
|
||||
optbl[0x48] = &bCPU::op_pha;
|
||||
optbl[0xda] = &bCPU::op_phx;
|
||||
optbl[0x5a] = &bCPU::op_phy;
|
||||
optbl[0x0b] = &bCPU::op_phd;
|
||||
optbl[0x8b] = &bCPU::op_phb;
|
||||
optbl[0x4b] = &bCPU::op_phk;
|
||||
optbl[0x08] = &bCPU::op_php;
|
||||
optbl[0x68] = &bCPU::op_pla;
|
||||
optbl[0xfa] = &bCPU::op_plx;
|
||||
optbl[0x7a] = &bCPU::op_ply;
|
||||
optbl[0x2b] = &bCPU::op_pld;
|
||||
optbl[0xab] = &bCPU::op_plb;
|
||||
optbl[0x28] = &bCPU::op_plp;
|
||||
optbl[0xf4] = &bCPU::op_pea;
|
||||
optbl[0xd4] = &bCPU::op_pei;
|
||||
optbl[0x62] = &bCPU::op_per;
|
||||
@@ -1,260 +0,0 @@
|
||||
/* used by both DMA and HDMA
|
||||
* prevents transfer across same bus (a->a or b->b)
|
||||
*/
|
||||
void bCPU::dma_transfer_byte(bool direction, uint8 bbus, uint32 abus) {
|
||||
uint8 r;
|
||||
if(direction == 0) {
|
||||
//read from address bus a, write to address bus b
|
||||
|
||||
//DMA address bus a cannot read from or write to the following addresses:
|
||||
//$[00-3f|80-bf]:21[00-ff] <address bus b>
|
||||
//$[00-3f|80-bf]:43[00-7f] <DMA control registers>
|
||||
//$[00-3f|80-bf]:420b <DMA enable register>
|
||||
//$[00-3f|80-bf]:420c <HDMA enable register>
|
||||
if((abus & 0x40ff00) == 0x2100 || (abus & 0x40ff80) == 0x4300 ||
|
||||
(abus & 0x40ffff) == 0x420b || (abus & 0x40ffff) == 0x420c) {
|
||||
//these invalid reads will return open bus
|
||||
r = r_cpu->regs.mdr;
|
||||
} else {
|
||||
r = r_mem->read(abus);
|
||||
}
|
||||
|
||||
r_mem->write(0x2100 | bbus, r);
|
||||
} else {
|
||||
//read from address bus b, write to address bus a
|
||||
|
||||
//block invalid writes, see comments above
|
||||
r = r_mem->read(0x2100 | bbus);
|
||||
if((abus & 0x40ff00) == 0x2100 || (abus & 0x40ff80) == 0x4300 ||
|
||||
(abus & 0x40ffff) == 0x420b || (abus & 0x40ffff) == 0x420c)return;
|
||||
r_mem->write(abus, r);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 bCPU::dma_bbus(uint8 i, uint8 index) {
|
||||
switch(channel[i].xfermode) {
|
||||
default:
|
||||
case 0: return (channel[i].destaddr); break; //0
|
||||
case 1: return (channel[i].destaddr + (index & 1)); break; //0,1
|
||||
case 2: return (channel[i].destaddr); break; //0,0
|
||||
case 3: return (channel[i].destaddr + ((index >> 1) & 1)); break; //0,0,1,1
|
||||
case 4: return (channel[i].destaddr + (index & 3)); break; //0,1,2,3
|
||||
case 5: return (channel[i].destaddr + (index & 1)); break; //0,1,0,1
|
||||
case 6: return (channel[i].destaddr); break; //0,0 [2]
|
||||
case 7: return (channel[i].destaddr + ((index >> 1) & 1)); break; //0,0,1,1 [3]
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::dma_add_cycles(uint32 cycles) {
|
||||
status.dma_cycle_count += cycles;
|
||||
}
|
||||
|
||||
void bCPU::hdma_add_cycles(uint32 cycles) {
|
||||
if(run_state.dma) {
|
||||
status.dma_cycle_count += cycles;
|
||||
}
|
||||
status.hdma_cycle_count += cycles;
|
||||
}
|
||||
|
||||
uint32 bCPU::dma_addr(uint8 i) {
|
||||
uint32 r;
|
||||
r = (channel[i].srcbank << 16) | (channel[i].srcaddr);
|
||||
|
||||
if(channel[i].fixedxfer == false) {
|
||||
channel[i].srcaddr += channel[i].incmode;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
void bCPU::dma_cputommio(uint8 i, uint8 bbus) {
|
||||
if(cartridge.info.sdd1 == true && sdd1->dma_active() == true) {
|
||||
r_mem->write(0x2100 | bbus, sdd1->dma_read());
|
||||
} else {
|
||||
dma_transfer_byte(0, bbus, dma_addr(i));
|
||||
}
|
||||
|
||||
add_cycles(8);
|
||||
channel[i].xfersize--;
|
||||
}
|
||||
|
||||
void bCPU::dma_mmiotocpu(uint8 i, uint8 bbus) {
|
||||
dma_transfer_byte(1, bbus, dma_addr(i));
|
||||
|
||||
add_cycles(8);
|
||||
channel[i].xfersize--;
|
||||
}
|
||||
|
||||
void bCPU::dma_write(uint8 i, uint8 index) {
|
||||
if(channel[i].direction == 0) {
|
||||
dma_cputommio(i, index);
|
||||
} else {
|
||||
dma_mmiotocpu(i, index);
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::dma_run() {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(channel[i].dma_enabled == false)continue;
|
||||
|
||||
//first byte transferred?
|
||||
if(cartridge.info.sdd1 == true && channel[i].read_index == 0) {
|
||||
sdd1->dma_begin(i, (channel[i].srcbank << 16) | (channel[i].srcaddr),
|
||||
channel[i].xfersize);
|
||||
}
|
||||
|
||||
dma_write(i, dma_bbus(i, channel[i].read_index++));
|
||||
dma_add_cycles(8);
|
||||
|
||||
if(channel[i].xfersize == 0) {
|
||||
channel[i].dma_enabled = false;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
status.dma_state = DMASTATE_CPUSYNC;
|
||||
}
|
||||
|
||||
uint32 bCPU::hdma_addr(uint8 i) {
|
||||
return (channel[i].srcbank << 16) | (channel[i].hdma_addr++);
|
||||
}
|
||||
|
||||
uint32 bCPU::hdma_iaddr(uint8 i) {
|
||||
return (channel[i].hdma_ibank << 16) | (channel[i].hdma_iaddr++);
|
||||
}
|
||||
|
||||
void bCPU::hdma_update(uint8 i) {
|
||||
channel[i].hdma_line_counter = r_mem->read(hdma_addr(i));
|
||||
add_cycles(8);
|
||||
hdma_add_cycles(8);
|
||||
|
||||
if(channel[i].hdma_indirect) {
|
||||
channel[i].hdma_iaddr = r_mem->read(hdma_addr(i)) << 8;
|
||||
add_cycles(8);
|
||||
hdma_add_cycles(8);
|
||||
}
|
||||
|
||||
if(channel[i].hdma_line_counter == 0) {
|
||||
channel[i].hdma_completed = true;
|
||||
channel[i].hdma_do_transfer = false;
|
||||
return;
|
||||
}
|
||||
|
||||
channel[i].hdma_do_transfer = true;
|
||||
|
||||
if(channel[i].hdma_indirect) {
|
||||
channel[i].hdma_iaddr >>= 8;
|
||||
channel[i].hdma_iaddr |= r_mem->read(hdma_addr(i)) << 8;
|
||||
add_cycles(8);
|
||||
hdma_add_cycles(8);
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::hdma_run() {
|
||||
static uint8 hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(!channel[i].hdma_enabled || channel[i].hdma_completed)continue;
|
||||
|
||||
if(channel[i].hdma_do_transfer) {
|
||||
int xferlen = hdma_xferlen[channel[i].xfermode];
|
||||
for(channel[i].read_index = 0; channel[i].read_index < xferlen; channel[i].read_index++) {
|
||||
if(bool(config::cpu.hdma_enable) == true) {
|
||||
dma_transfer_byte(channel[i].direction, dma_bbus(i, channel[i].read_index),
|
||||
channel[i].hdma_indirect ? hdma_iaddr(i) : hdma_addr(i));
|
||||
}
|
||||
add_cycles(8);
|
||||
hdma_add_cycles(8);
|
||||
}
|
||||
}
|
||||
|
||||
channel[i].hdma_line_counter--;
|
||||
channel[i].hdma_do_transfer = bool(channel[i].hdma_line_counter & 0x80);
|
||||
if((channel[i].hdma_line_counter & 0x7f) == 0) {
|
||||
hdma_update(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::hdma_init() {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(!channel[i].hdma_enabled)continue;
|
||||
|
||||
channel[i].hdma_addr = channel[i].srcaddr;
|
||||
hdma_update(i);
|
||||
}
|
||||
}
|
||||
|
||||
uint8 bCPU::hdma_enabled_channels() {
|
||||
int r = 0;
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(channel[i].hdma_enabled)r++;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
uint8 bCPU::hdma_active_channels() {
|
||||
int r = 0;
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(channel[i].hdma_enabled && !channel[i].hdma_completed)r++;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/* hdmainit_activate()
|
||||
* hdma_activate()
|
||||
*
|
||||
* Functions are called by CPU timing routine
|
||||
* when an HDMA event (init or run) occurs.
|
||||
*/
|
||||
|
||||
void bCPU::hdmainit_activate() {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
channel[i].hdma_completed = false;
|
||||
channel[i].hdma_do_transfer = false;
|
||||
}
|
||||
|
||||
if(hdma_enabled_channels() != 0) {
|
||||
status.hdma_state = HDMASTATE_IDMASYNC;
|
||||
run_state.hdma = true;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::hdma_activate() {
|
||||
if(hdma_active_channels() != 0) {
|
||||
status.hdma_state = HDMASTATE_DMASYNC;
|
||||
run_state.hdma = true;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::dma_reset() {
|
||||
status.dma_state = DMASTATE_CPUSYNC;
|
||||
status.hdma_state = HDMASTATE_CPUSYNC;
|
||||
status.dma_cycle_count = 0;
|
||||
status.hdma_cycle_count = 0;
|
||||
|
||||
for(int i = 0; i < 8; i++) {
|
||||
channel[i].read_index = 0;
|
||||
channel[i].dma_enabled = false;
|
||||
channel[i].hdma_enabled = false;
|
||||
channel[i].dmap = 0xff;
|
||||
channel[i].direction = 1;
|
||||
channel[i].hdma_indirect = 1;
|
||||
channel[i].incmode = -1;
|
||||
channel[i].fixedxfer = 1;
|
||||
channel[i].xfermode = 7;
|
||||
channel[i].destaddr = 0xff;
|
||||
channel[i].srcaddr = 0xffff;
|
||||
channel[i].srcbank = 0xff;
|
||||
channel[i].xfersize = 0xffff;
|
||||
//xfersize and hdma_iaddr are of union { uint16 };
|
||||
//channel[i].hdma_iaddr = 0xffff;
|
||||
channel[i].hdma_ibank = 0xff;
|
||||
channel[i].hdma_addr = 0xffff;
|
||||
channel[i].hdma_line_counter = 0xff;
|
||||
channel[i].hdma_unknown = 0xff;
|
||||
|
||||
channel[i].hdma_completed = false;
|
||||
channel[i].hdma_do_transfer = false;
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
struct {
|
||||
uint32 read_index; //set to 0 at beginning of DMA/HDMA
|
||||
|
||||
//$420b
|
||||
bool dma_enabled;
|
||||
//$420c
|
||||
bool hdma_enabled;
|
||||
//$43x0
|
||||
uint8 dmap;
|
||||
bool direction;
|
||||
bool hdma_indirect;
|
||||
int8 incmode;
|
||||
bool fixedxfer;
|
||||
uint8 xfermode;
|
||||
//$43x1
|
||||
uint8 destaddr;
|
||||
//$43x2-$43x3
|
||||
uint16 srcaddr;
|
||||
//$43x4
|
||||
uint8 srcbank;
|
||||
//$43x5-$43x6
|
||||
union {
|
||||
uint16 xfersize;
|
||||
uint16 hdma_iaddr;
|
||||
};
|
||||
//$43x7
|
||||
uint8 hdma_ibank;
|
||||
//$43x8-$43x9
|
||||
uint16 hdma_addr;
|
||||
//$43xa
|
||||
uint8 hdma_line_counter;
|
||||
//$43xb/$43xf
|
||||
uint8 hdma_unknown;
|
||||
|
||||
//hdma-specific
|
||||
bool hdma_completed; //for this frame
|
||||
bool hdma_do_transfer;
|
||||
|
||||
uint8 hdma_current_channel;
|
||||
uint8 hdma_current_pos;
|
||||
} channel[8];
|
||||
|
||||
inline void dma_transfer_byte(bool direction, uint8 bbus, uint32 abus);
|
||||
inline uint8 dma_bbus(uint8 i, uint8 index);
|
||||
inline void dma_add_cycles(uint32 cycles);
|
||||
inline void hdma_add_cycles(uint32 cycles);
|
||||
inline void dma_run();
|
||||
inline void hdma_run();
|
||||
inline void hdma_init();
|
||||
inline void hdma_update(uint8 i);
|
||||
inline uint8 hdma_enabled_channels();
|
||||
inline uint8 hdma_active_channels();
|
||||
inline void hdmainit_activate();
|
||||
inline void hdma_activate();
|
||||
inline void dma_cputommio(uint8 i, uint8 index);
|
||||
inline void dma_mmiotocpu(uint8 i, uint8 index);
|
||||
inline void dma_write(uint8 i, uint8 index);
|
||||
inline uint32 dma_addr(uint8 i);
|
||||
inline uint32 hdma_addr(uint8 i);
|
||||
inline uint32 hdma_iaddr(uint8 i);
|
||||
inline void dma_reset();
|
||||
@@ -1,40 +0,0 @@
|
||||
uint8 bCPU::port_read(uint8 port) {
|
||||
return apu_port[port & 3];
|
||||
}
|
||||
|
||||
void bCPU::port_write(uint8 port, uint8 value) {
|
||||
apu_port[port & 3] = value;
|
||||
}
|
||||
|
||||
/* The next 3 functions control bus timing for the CPU.
|
||||
* cpu_io is an I/O cycle, and always 6 clock cycles long.
|
||||
* mem_read / mem_write indicate memory access bus cycle,
|
||||
* they are either 6, 8, or 12 bus cycles long, depending
|
||||
* both on location and the $420d.d0 FastROM enable bit.
|
||||
*/
|
||||
|
||||
void bCPU::cpu_io() {
|
||||
status.cycle_count = 6;
|
||||
pre_exec_cycle();
|
||||
add_cycles(6);
|
||||
cycle_edge();
|
||||
}
|
||||
|
||||
uint8 bCPU::mem_read(uint32 addr) {
|
||||
status.cycle_count = r_mem->speed(addr);
|
||||
pre_exec_cycle();
|
||||
add_cycles(status.cycle_count - 4);
|
||||
regs.mdr = r_mem->read(addr);
|
||||
add_cycles(4);
|
||||
cycle_edge();
|
||||
return regs.mdr;
|
||||
}
|
||||
|
||||
void bCPU::mem_write(uint32 addr, uint8 value) {
|
||||
status.cycle_count = r_mem->speed(addr);
|
||||
pre_exec_cycle();
|
||||
add_cycles(status.cycle_count);
|
||||
regs.mdr = value;
|
||||
r_mem->write(addr, value);
|
||||
cycle_edge();
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
uint8 apu_port[4];
|
||||
inline uint8 port_read (uint8 port);
|
||||
inline void port_write(uint8 port, uint8 value);
|
||||
|
||||
inline void cpu_io();
|
||||
inline uint8 mem_read(uint32 addr);
|
||||
inline void mem_write(uint32 addr, uint8 value);
|
||||
|
||||
/*****
|
||||
* helper memory addressing functions used by CPU core
|
||||
*****/
|
||||
uint8 op_readpc () { return mem_read((regs.pc.b << 16) + regs.pc.w++); }
|
||||
uint8 op_readstack() { (regs.e) ? regs.s.l++ : regs.s.w++; return mem_read(regs.s.w); }
|
||||
uint8 op_readaddr (uint32 addr) { return mem_read(uclip<16>(addr)); }
|
||||
uint8 op_readlong (uint32 addr) { return mem_read(uclip<24>(addr)); }
|
||||
uint8 op_readdbr (uint32 addr) { return mem_read(uclip<24>((regs.db << 16) + addr)); }
|
||||
uint8 op_readpbr (uint32 addr) { return mem_read((regs.pc.b << 16) + uclip<16>(addr)); }
|
||||
uint8 op_readdp (uint32 addr) { return mem_read(uclip<16>(regs.d + uclip<16>(addr))); }
|
||||
uint8 op_readsp (uint32 addr) { return mem_read(uclip<16>(regs.s + uclip<16>(addr))); }
|
||||
|
||||
void op_writestack(uint8 data) { mem_write(regs.s.w, data); (regs.e) ? regs.s.l-- : regs.s.w--; }
|
||||
void op_writeaddr (uint32 addr, uint8 data) { mem_write(uclip<16>(addr), data); }
|
||||
void op_writelong (uint32 addr, uint8 data) { mem_write(uclip<24>(addr), data); }
|
||||
void op_writedbr (uint32 addr, uint8 data) { mem_write(uclip<24>((regs.db << 16) + addr), data); }
|
||||
void op_writepbr (uint32 addr, uint8 data) { mem_write((regs.pc.b << 16) + uclip<16>(addr), data); }
|
||||
void op_writedp (uint32 addr, uint8 data) { mem_write(uclip<16>(regs.d + uclip<16>(addr)), data); }
|
||||
void op_writesp (uint32 addr, uint8 data) { mem_write(uclip<16>(regs.s + uclip<16>(addr)), data); }
|
||||
@@ -1,338 +0,0 @@
|
||||
/* Notes about PAL timing:
|
||||
* As I do not have PAL hardware to run timing tests on, I've
|
||||
* had to guess on a lot of things. Below is how I've arrived
|
||||
* at various calculations:
|
||||
*
|
||||
* NTSC timing crystal: ~21477272hz
|
||||
* PAL timing crystal: ~21281370hz
|
||||
* NTSC ~60fps, PAL ~50fps
|
||||
* NTSC ~262 lines/frame, PAL ~312 lines/frame
|
||||
* NTSC 21477272 / (262 * 60) = ~1366 cycles/line
|
||||
* PAL 21281370 / (312 * 50) = ~1364 cycles/line
|
||||
*
|
||||
* As the cycles/line are very close between the two systems,
|
||||
* I have left the known NTSC anomalies intact for PAL timing.
|
||||
* In reality, some of these may not exist, and some may be
|
||||
* slightly different.
|
||||
*
|
||||
* [known]
|
||||
* - DRAM refresh occurs at about the same time every
|
||||
* scanline on PAL units (per Overload).
|
||||
* [unknown]
|
||||
* - Are dots 323/327 still 2 cycles longer than the
|
||||
* other dots?
|
||||
* - Is scanline 240 on non-interlace odd frames still
|
||||
* 4 cycles short?
|
||||
*/
|
||||
|
||||
uint16 bCPU::vcounter() { return time.v; }
|
||||
uint16 bCPU::hclock() { return time.hc; }
|
||||
|
||||
bool bCPU::interlace() { return time.interlace; }
|
||||
bool bCPU::interlace_field() { return time.interlace_field; }
|
||||
bool bCPU::overscan() { return time.overscan; }
|
||||
uint16 bCPU::region_scanlines() { return time.region_scanlines; }
|
||||
|
||||
void bCPU::set_interlace(bool r) { time.interlace = r; update_interrupts(); }
|
||||
void bCPU::set_overscan (bool r) { time.overscan = r; update_interrupts(); }
|
||||
|
||||
uint8 bCPU::dma_counter() { return (time.dma_counter + time.hc) & 6; }
|
||||
|
||||
uint16 bCPU::hcounter() {
|
||||
if(time.v == 240 && time.interlace == false && time.interlace_field == 1) {
|
||||
return time.hc >> 2;
|
||||
}
|
||||
return (time.hc - ((time.hc > 1292) << 1) - ((time.hc > 1310) << 1)) >> 2;
|
||||
}
|
||||
|
||||
bool bCPU::nmi_trigger_pos_match(uint32 offset) {
|
||||
uint16 v = overscan() ? 240 : 225;
|
||||
uint16 hc = 2 + offset;
|
||||
return (time.v == v && time.hc == hc);
|
||||
}
|
||||
|
||||
bool bCPU::irq_trigger_pos_match(uint32 offset) {
|
||||
uint16 v = status.virq_pos;
|
||||
uint16 hc = (status.hirq_enabled) ? status.hirq_pos : 0;
|
||||
uint16 vlimit = region_scanlines() >> 1;
|
||||
|
||||
//positions that can never be latched
|
||||
//region_scanlines() = 525/NTSC, 625/PAL
|
||||
//PAL results are unverified on hardware
|
||||
if(v == 240 && hc == 339 && interlace() == false && interlace_field() == 1)return false;
|
||||
if(v == (vlimit - 1) && hc == 339 && interlace() == false)return false;
|
||||
if(v == vlimit && interlace() == false)return false;
|
||||
if(v == vlimit && hc == 339)return false;
|
||||
if(v > vlimit)return false;
|
||||
if(hc > 339)return false;
|
||||
|
||||
hc = (hc != 0) ? ((hc << 2) + 14) : 10;
|
||||
hc += offset;
|
||||
if(hc >= time.line_cycles) {
|
||||
hc -= time.line_cycles;
|
||||
if(++v >= time.frame_lines) {
|
||||
v = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if((status.virq_enabled == true && time.v == v) || status.virq_enabled == false) {
|
||||
return (time.hc == hc);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void bCPU::update_nmi() {
|
||||
if(time.v == (overscan() ? 240 : 225)) {
|
||||
time.nmi_read_trigger_pos = 2;
|
||||
time.nmi_line_trigger_pos = 6;
|
||||
} else {
|
||||
time.nmi_read_trigger_pos = -64;
|
||||
time.nmi_line_trigger_pos = -64;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::update_irq() {
|
||||
int vpos = status.virq_pos;
|
||||
int hpos = (status.hirq_enabled) ? status.hirq_pos : 0;
|
||||
int vlimit = region_scanlines() >> 1;
|
||||
|
||||
//positions that can never be latched
|
||||
//region_scanlines() = 262/NTSC, 312/PAL
|
||||
//PAL results are unverified on hardware
|
||||
if(vpos == 240 && hpos == 339 && interlace() == false && interlace_field() == 1)goto _nolatch;
|
||||
if(vpos == (vlimit - 1) && hpos == 339 && interlace() == false)goto _nolatch;
|
||||
if(vpos == vlimit && interlace() == false)goto _nolatch;
|
||||
if(vpos == vlimit && hpos == 339)goto _nolatch;
|
||||
if(vpos > vlimit)goto _nolatch;
|
||||
if(hpos > 339)goto _nolatch;
|
||||
|
||||
hpos = (hpos != 0) ? ((hpos << 2) + 14) : 10;
|
||||
if(hpos >= time.line_cycles) {
|
||||
hpos -= time.line_cycles;
|
||||
if(++vpos >= time.frame_lines) {
|
||||
vpos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if((status.virq_enabled == true && time.v == vpos) || status.virq_enabled == false) {
|
||||
time.irq_read_trigger_pos = hpos;
|
||||
} else {
|
||||
time.irq_read_trigger_pos = -64;
|
||||
}
|
||||
|
||||
hpos += 4;
|
||||
if(hpos >= time.line_cycles) {
|
||||
hpos -= time.line_cycles;
|
||||
if(++vpos >= time.frame_lines) {
|
||||
vpos = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if((status.virq_enabled == true && time.v == vpos) || status.virq_enabled == false) {
|
||||
time.irq_line_trigger_pos = hpos;
|
||||
} else {
|
||||
time.irq_line_trigger_pos = -64;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
_nolatch:
|
||||
time.irq_read_trigger_pos = -64;
|
||||
time.irq_line_trigger_pos = -64;
|
||||
}
|
||||
|
||||
void bCPU::update_interrupts() {
|
||||
update_nmi();
|
||||
update_irq();
|
||||
}
|
||||
|
||||
void bCPU::poll_interrupts(int cycles) {
|
||||
int16 hc, hc_end;
|
||||
if(time.hc == 0) {
|
||||
hc = -1;
|
||||
hc_end = cycles;
|
||||
} else {
|
||||
hc = time.hc;
|
||||
hc_end = time.hc + cycles;
|
||||
}
|
||||
|
||||
if(hc < time.nmi_read_trigger_pos && time.nmi_read_trigger_pos <= hc_end) {
|
||||
//nmi_read can go low even with NMI interrupts disabled in $4200.d7
|
||||
time.nmi_read = 0;
|
||||
}
|
||||
|
||||
if(hc < time.nmi_line_trigger_pos && time.nmi_line_trigger_pos <= hc_end) {
|
||||
if(status.nmi_enabled == true) {
|
||||
if(time.nmi_line == 1) {
|
||||
time.nmi_transition = 1;
|
||||
}
|
||||
time.nmi_line = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(hc < time.irq_read_trigger_pos && time.irq_read_trigger_pos <= hc_end) {
|
||||
if(status.virq_enabled == true || status.hirq_enabled == true) {
|
||||
time.irq_read = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(hc < time.irq_line_trigger_pos && time.irq_line_trigger_pos <= hc_end) {
|
||||
if(status.virq_enabled == true || status.hirq_enabled == true) {
|
||||
time.irq_line = 0;
|
||||
time.irq_transition = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
uint32 bCPU::clocks_executed() {
|
||||
uint32 r = status.cycles_executed;
|
||||
status.cycles_executed = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
void bCPU::cycle_edge() {
|
||||
if(time.line_rendered == false) {
|
||||
if(time.hc >= 192) {
|
||||
time.line_rendered = true;
|
||||
r_ppu->render_scanline();
|
||||
}
|
||||
}
|
||||
|
||||
if(time.hdmainit_triggered == false) {
|
||||
if(time.hc >= time.hdmainit_trigger_pos || time.v) {
|
||||
time.hdmainit_triggered = true;
|
||||
hdmainit_activate();
|
||||
}
|
||||
}
|
||||
|
||||
if(time.hdma_triggered == false) {
|
||||
//hdma_triggered only set to false for v <= (overscan ? 239 : 224)
|
||||
if(time.hc >= 1106) {
|
||||
time.hdma_triggered = true;
|
||||
hdma_activate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::add_cycles(int cycles) {
|
||||
status.cycles_executed += cycles;
|
||||
poll_interrupts(cycles);
|
||||
|
||||
if(time.hc + cycles >= time.line_cycles) {
|
||||
cycles = (time.hc + cycles) - time.line_cycles;
|
||||
time.hc = 0;
|
||||
scanline();
|
||||
poll_interrupts(cycles);
|
||||
}
|
||||
|
||||
time.hc += cycles;
|
||||
|
||||
if(time.dram_refreshed == false) {
|
||||
if(time.hc >= time.dram_refresh_pos) {
|
||||
time.dram_refreshed = true;
|
||||
add_cycles(40);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::scanline() {
|
||||
if(++time.v >= time.frame_lines) {
|
||||
frame();
|
||||
}
|
||||
|
||||
time.dma_counter += time.line_cycles;
|
||||
if(time.v == 240 && time.interlace == false && time.interlace_field == 1) {
|
||||
time.line_cycles = 1360;
|
||||
} else {
|
||||
time.line_cycles = 1364;
|
||||
}
|
||||
time.dram_refreshed = false;
|
||||
|
||||
time.line_rendered =
|
||||
time.hdma_triggered = (time.v <= (!overscan() ? 224 : 239)) ? false : true;
|
||||
|
||||
r_ppu->scanline();
|
||||
snes->scanline();
|
||||
|
||||
update_interrupts();
|
||||
|
||||
if(vcounter() == (!overscan() ? 227 : 242) && status.auto_joypad_poll == true) {
|
||||
snes->poll_input();
|
||||
//When the SNES auto-polls the joypads, it writes 1, then 0 to
|
||||
//$4016, then reads from each 16 times to get the joypad state
|
||||
//information. As a result, the joypad read positions are set
|
||||
//to 16 after such a poll. Position 16 is the controller
|
||||
//connected status bit.
|
||||
status.joypad1_read_pos = 16;
|
||||
status.joypad2_read_pos = 16;
|
||||
}
|
||||
}
|
||||
|
||||
void bCPU::frame() {
|
||||
time.nmi_read = 1;
|
||||
time.nmi_line = 1;
|
||||
time.nmi_transition = 0;
|
||||
|
||||
time.v = 0;
|
||||
time.interlace_field ^= 1;
|
||||
if(interlace() == true && interlace_field() == 0) {
|
||||
time.frame_lines = (time.region_scanlines >> 1) + 1;
|
||||
} else {
|
||||
time.frame_lines = (time.region_scanlines >> 1);
|
||||
}
|
||||
|
||||
if(cpu_version == 2) {
|
||||
time.hdmainit_trigger_pos = 12 + dma_counter();
|
||||
} else {
|
||||
time.hdmainit_trigger_pos = 12 + 8 - dma_counter();
|
||||
}
|
||||
time.hdmainit_triggered = false;
|
||||
|
||||
r_ppu->frame();
|
||||
snes->frame();
|
||||
}
|
||||
|
||||
void bCPU::time_reset() {
|
||||
time.v = 0;
|
||||
time.hc = 0;
|
||||
|
||||
//upon SNES reset, start at scanline 0 non-interlace
|
||||
time.interlace = 0;
|
||||
time.interlace_field = 0;
|
||||
time.overscan = false;
|
||||
time.line_cycles = 1364;
|
||||
|
||||
time.dram_refreshed = false;
|
||||
time.dram_refresh_pos = (cpu_version == 2) ? 538 : 530;
|
||||
|
||||
time.dma_counter = 0;
|
||||
|
||||
//set at V=0,H=0
|
||||
time.hdmainit_trigger_pos = 0;
|
||||
time.hdmainit_triggered = true;
|
||||
|
||||
time.hdma_triggered = false;
|
||||
|
||||
time.nmi_pending = false;
|
||||
time.irq_pending = false;
|
||||
time.nmi_line = time.nmi_read = 1;
|
||||
time.irq_line = time.irq_read = 1;
|
||||
|
||||
time.nmi_transition = 0;
|
||||
time.irq_transition = 0;
|
||||
|
||||
update_interrupts();
|
||||
|
||||
switch(region) {
|
||||
case NTSC:
|
||||
time.region_scanlines = 525;
|
||||
break;
|
||||
case PAL:
|
||||
time.region_scanlines = 625;
|
||||
break;
|
||||
}
|
||||
|
||||
time.frame_lines = time.region_scanlines >> 1;
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
struct {
|
||||
uint16 v, hc;
|
||||
|
||||
bool interlace, interlace_field, overscan;
|
||||
uint16 line_cycles, frame_lines;
|
||||
|
||||
bool line_rendered;
|
||||
|
||||
bool dram_refreshed;
|
||||
uint16 dram_refresh_pos;
|
||||
|
||||
uint8 dma_counter;
|
||||
|
||||
uint16 hdmainit_trigger_pos;
|
||||
bool hdmainit_triggered;
|
||||
|
||||
bool hdma_triggered;
|
||||
|
||||
uint16 region_scanlines;
|
||||
|
||||
//nmi_pending, irq_pending are used by last_cycle()
|
||||
//nmi_line = /NMI, nmi_read = $4210.7
|
||||
//irq_line = /IRQ, irq_read = $4211.7
|
||||
bool nmi_pending, nmi_line, nmi_read;
|
||||
bool irq_pending, irq_line, irq_read;
|
||||
|
||||
//NMI is edge-sensitive, meaning it triggers when /NMI
|
||||
//transitions from high to low. This value is set to 1
|
||||
//when that happens, and cleared after the nmi_test()
|
||||
//routine acknowledges it and invokes the NMI interrupt
|
||||
bool nmi_transition;
|
||||
|
||||
//IRQ is level-sensitive, so it does not need to keep
|
||||
//track of transitions from high to low. IRQs will
|
||||
//continue to fire as long as /IRQ stays low.
|
||||
//However, if a write to $4200 forces IRQs high at the
|
||||
//exact same clock cycle that /IRQ goes low, the /IRQ
|
||||
//will still occur. Hence the need for this variable.
|
||||
bool irq_transition;
|
||||
|
||||
//position is relative to time.hc, set at start of each scanline
|
||||
//-64 means no trigger point on this scanline
|
||||
//$4210/$4211 status bits get set before /NMI and /IRQ go low,
|
||||
//hence the need for two variables for each.
|
||||
int32 nmi_read_trigger_pos, nmi_line_trigger_pos;
|
||||
int32 irq_read_trigger_pos, irq_line_trigger_pos;
|
||||
} time;
|
||||
|
||||
inline uint16 vcounter();
|
||||
inline uint16 hcounter();
|
||||
inline uint16 hclock();
|
||||
inline bool interlace();
|
||||
inline bool interlace_field();
|
||||
inline bool overscan();
|
||||
inline uint16 region_scanlines();
|
||||
|
||||
inline bool nmi_trigger_pos_match(uint32 offset);
|
||||
inline bool irq_trigger_pos_match(uint32 offset);
|
||||
|
||||
inline void update_nmi();
|
||||
inline void update_irq();
|
||||
inline void update_interrupts();
|
||||
inline void poll_interrupts(int cycles);
|
||||
|
||||
inline void set_interlace(bool r);
|
||||
inline void set_overscan (bool r);
|
||||
|
||||
inline uint8 dma_counter();
|
||||
|
||||
inline void cycle_edge();
|
||||
inline void add_cycles(int cycles);
|
||||
inline void scanline();
|
||||
inline void frame();
|
||||
inline void time_reset();
|
||||
+3
-3
@@ -1,6 +1,9 @@
|
||||
#include "cpuregs.h"
|
||||
|
||||
class CPU : public MMIO {
|
||||
public:
|
||||
virtual void enter() = 0;
|
||||
|
||||
public:
|
||||
//CPU version number
|
||||
//* 1 and 2 are known
|
||||
@@ -30,9 +33,6 @@ CPURegs regs;
|
||||
FLAG_Z = 0x02, FLAG_C = 0x01
|
||||
};
|
||||
virtual uint8 pio_status() = 0;
|
||||
virtual void main() {}
|
||||
virtual void run() = 0;
|
||||
virtual uint32 clocks_executed() = 0;
|
||||
virtual void scanline() = 0;
|
||||
virtual void frame() = 0;
|
||||
virtual void power() = 0;
|
||||
|
||||
+1
-2
@@ -71,6 +71,5 @@ CPURegFlags p;
|
||||
uint8 db;
|
||||
uint8 mdr;
|
||||
bool e;
|
||||
bool acc_8b, idx_8b;
|
||||
CPURegs() : db(0), mdr(0x00), e(false), acc_8b(true), idx_8b(true) {}
|
||||
CPURegs() : db(0), mdr(0x00), e(false) {}
|
||||
};
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "opfn.cpp"
|
||||
|
||||
void sCPU::main() {
|
||||
void sCPU::enter() {
|
||||
for(;;) {
|
||||
if(event.irq) {
|
||||
event.irq = false;
|
||||
@@ -27,10 +27,6 @@ void sCPU::main() {
|
||||
}
|
||||
|
||||
status.in_opcode = false;
|
||||
|
||||
#ifdef FAVOR_SPEED
|
||||
co_return();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
CPUReg24 aa, rd;
|
||||
uint8 dp, sp;
|
||||
|
||||
inline void main();
|
||||
inline void op_irq();
|
||||
void op_irq();
|
||||
|
||||
inline bool in_opcode() { return status.in_opcode; }
|
||||
inline bool in_opcode() { return status.in_opcode; }
|
||||
|
||||
//op_read
|
||||
void op_adc_b();
|
||||
|
||||
+70
-53
@@ -15,7 +15,7 @@ xba(0xeb) {
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.a.h ^= regs.a.l;
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
}
|
||||
|
||||
@@ -27,10 +27,12 @@ mvp(0x44, --) {
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
4:op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
5:op_io();
|
||||
if(regs.idx_8b) {
|
||||
regs.x.l $1; regs.y.l $1;
|
||||
if(regs.p.x) {
|
||||
regs.x.l $1;
|
||||
regs.y.l $1;
|
||||
} else {
|
||||
regs.x.w $1; regs.y.w $1;
|
||||
regs.x.w $1;
|
||||
regs.y.w $1;
|
||||
}
|
||||
6:last_cycle();
|
||||
op_io();
|
||||
@@ -56,10 +58,7 @@ cop(0x02, 0xfff4, 0xfff5, 0xffe4, 0xffe5) {
|
||||
stp(0xdb) {
|
||||
1:op_io();
|
||||
2:last_cycle();
|
||||
while(1) {
|
||||
op_io();
|
||||
co_return();
|
||||
}
|
||||
while(1) { op_io(); }
|
||||
}
|
||||
|
||||
wai(0xcb) {
|
||||
@@ -70,20 +69,20 @@ wai(0xcb) {
|
||||
3:while(event.wai) {
|
||||
last_cycle();
|
||||
op_io();
|
||||
co_return();
|
||||
}
|
||||
}
|
||||
|
||||
xce(0xfb) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
bool c = regs.p.c;
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = regs.e;
|
||||
regs.e = c;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
regs.acc_8b = (regs.e || regs.p.m);
|
||||
regs.idx_8b = (regs.e || regs.p.x);
|
||||
if(regs.idx_8b) {
|
||||
regs.e = carry;
|
||||
if(regs.e) {
|
||||
regs.p |= 0x30;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
@@ -107,29 +106,28 @@ sep(0xe2, |=) {
|
||||
2:last_cycle();
|
||||
op_io();
|
||||
regs.p $1 rd.l;
|
||||
regs.acc_8b = (regs.e || regs.p.m);
|
||||
regs.idx_8b = (regs.e || regs.p.x);
|
||||
if(regs.idx_8b) {
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
tax(0xaa, regs.idx_8b, x, a),
|
||||
tay(0xa8, regs.idx_8b, y, a),
|
||||
txa(0x8a, regs.acc_8b, a, x),
|
||||
txy(0x9b, regs.idx_8b, y, x),
|
||||
tya(0x98, regs.acc_8b, a, y),
|
||||
tyx(0xbb, regs.idx_8b, x, y) {
|
||||
tax(0xaa, regs.p.x, x, a),
|
||||
tay(0xa8, regs.p.x, y, a),
|
||||
txa(0x8a, regs.p.m, a, x),
|
||||
txy(0x9b, regs.p.x, y, x),
|
||||
tya(0x98, regs.p.m, a, y),
|
||||
tyx(0xbb, regs.p.x, x, y) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
if($1) {
|
||||
regs.$2.l = regs.$3.l;
|
||||
regs.p.n = bool(regs.$2.l & 0x80);
|
||||
regs.p.n = !!(regs.$2.l & 0x80);
|
||||
regs.p.z = (regs.$2.l == 0);
|
||||
} else {
|
||||
regs.$2.w = regs.$3.w;
|
||||
regs.p.n = bool(regs.$2.w & 0x8000);
|
||||
regs.p.n = !!(regs.$2.w & 0x8000);
|
||||
regs.p.z = (regs.$2.w == 0);
|
||||
}
|
||||
}
|
||||
@@ -138,7 +136,7 @@ tcd(0x5b) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
regs.d.w = regs.a.w;
|
||||
regs.p.n = bool(regs.d.w & 0x8000);
|
||||
regs.p.n = !!(regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
}
|
||||
|
||||
@@ -153,7 +151,7 @@ tdc(0x7b) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
regs.a.w = regs.d.w;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
@@ -162,10 +160,10 @@ tsc(0x3b) {
|
||||
op_io();
|
||||
regs.a.w = regs.s.w;
|
||||
if(regs.e) {
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
}
|
||||
@@ -173,13 +171,13 @@ tsc(0x3b) {
|
||||
tsx(0xba) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
if(regs.idx_8b) {
|
||||
if(regs.p.x) {
|
||||
regs.x.l = regs.s.l;
|
||||
regs.p.n = bool(regs.x.l & 0x80);
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w = regs.s.w;
|
||||
regs.p.n = bool(regs.x.w & 0x8000);
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
}
|
||||
@@ -194,16 +192,23 @@ txs(0x9a) {
|
||||
}
|
||||
}
|
||||
|
||||
pha(0x48, regs.acc_8b, a),
|
||||
phx(0xda, regs.idx_8b, x),
|
||||
phy(0x5a, regs.idx_8b, y),
|
||||
phd(0x0b, 0, d) {
|
||||
pha(0x48, regs.p.m, a),
|
||||
phx(0xda, regs.p.x, x),
|
||||
phy(0x5a, regs.p.x, y) {
|
||||
1:op_io();
|
||||
2:if(!$1)op_writestack(regs.$2.h);
|
||||
3:last_cycle();
|
||||
op_writestack(regs.$2.l);
|
||||
}
|
||||
|
||||
phd(0x0b) {
|
||||
1:op_io();
|
||||
2:op_writestackn(regs.d.h);
|
||||
3:last_cycle();
|
||||
op_writestackn(regs.d.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
phb(0x8b, regs.db),
|
||||
phk(0x4b, regs.pc.b),
|
||||
php(0x08, regs.p) {
|
||||
@@ -212,31 +217,41 @@ php(0x08, regs.p) {
|
||||
op_writestack($1);
|
||||
}
|
||||
|
||||
pla(0x68, regs.acc_8b, a),
|
||||
plx(0xfa, regs.idx_8b, x),
|
||||
ply(0x7a, regs.idx_8b, y),
|
||||
pld(0x2b, 0, d) {
|
||||
pla(0x68, regs.p.m, a),
|
||||
plx(0xfa, regs.p.x, x),
|
||||
ply(0x7a, regs.p.x, y) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:if($1)last_cycle();
|
||||
regs.$2.l = op_readstack();
|
||||
if($1) {
|
||||
regs.p.n = bool(regs.$2.l & 0x80);
|
||||
regs.p.n = !!(regs.$2.l & 0x80);
|
||||
regs.p.z = (regs.$2.l == 0);
|
||||
end;
|
||||
}
|
||||
4:last_cycle();
|
||||
regs.$2.h = op_readstack();
|
||||
regs.p.n = bool(regs.$2.w & 0x8000);
|
||||
regs.p.n = !!(regs.$2.w & 0x8000);
|
||||
regs.p.z = (regs.$2.w == 0);
|
||||
}
|
||||
|
||||
pld(0x2b) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:regs.d.l = op_readstackn();
|
||||
4:last_cycle();
|
||||
regs.d.h = op_readstackn();
|
||||
regs.p.n = !!(regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
plb(0xab) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:last_cycle();
|
||||
regs.db = op_readstack();
|
||||
regs.p.n = bool(regs.db & 0x80);
|
||||
regs.p.n = !!(regs.db & 0x80);
|
||||
regs.p.z = (regs.db == 0);
|
||||
}
|
||||
|
||||
@@ -245,9 +260,8 @@ plp(0x28) {
|
||||
2:op_io();
|
||||
3:last_cycle();
|
||||
regs.p = op_readstack();
|
||||
regs.acc_8b = (regs.e || regs.p.m);
|
||||
regs.idx_8b = (regs.e || regs.p.x);
|
||||
if(regs.idx_8b) {
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
@@ -256,9 +270,10 @@ plp(0x28) {
|
||||
pea(0xf4) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_writestack(aa.h);
|
||||
3:op_writestackn(aa.h);
|
||||
4:last_cycle();
|
||||
op_writestack(aa.l);
|
||||
op_writestackn(aa.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
pei(0xd4) {
|
||||
@@ -266,9 +281,10 @@ pei(0xd4) {
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:op_writestack(aa.h);
|
||||
5:op_writestackn(aa.h);
|
||||
6:last_cycle();
|
||||
op_writestack(aa.l);
|
||||
op_writestackn(aa.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
per(0x62) {
|
||||
@@ -276,7 +292,8 @@ per(0x62) {
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io();
|
||||
rd.w = regs.pc.d + (int16)aa.w;
|
||||
4:op_writestack(rd.h);
|
||||
4:op_writestackn(rd.h);
|
||||
5:last_cycle();
|
||||
op_writestack(rd.l);
|
||||
op_writestackn(rd.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
@@ -18,7 +18,7 @@ case 0xeb: {
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.a.h ^= regs.a.l;
|
||||
regs.a.l ^= regs.a.h;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} break;
|
||||
|
||||
@@ -30,10 +30,12 @@ case 0x54: {
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
op_io();
|
||||
if(regs.idx_8b) {
|
||||
regs.x.l ++; regs.y.l ++;
|
||||
if(regs.p.x) {
|
||||
regs.x.l ++;
|
||||
regs.y.l ++;
|
||||
} else {
|
||||
regs.x.w ++; regs.y.w ++;
|
||||
regs.x.w ++;
|
||||
regs.y.w ++;
|
||||
}
|
||||
last_cycle();
|
||||
op_io();
|
||||
@@ -48,10 +50,12 @@ case 0x44: {
|
||||
rd.l = op_readlong((sp << 16) | regs.x.w);
|
||||
op_writelong((dp << 16) | regs.y.w, rd.l);
|
||||
op_io();
|
||||
if(regs.idx_8b) {
|
||||
regs.x.l --; regs.y.l --;
|
||||
if(regs.p.x) {
|
||||
regs.x.l --;
|
||||
regs.y.l --;
|
||||
} else {
|
||||
regs.x.w --; regs.y.w --;
|
||||
regs.x.w --;
|
||||
regs.y.w --;
|
||||
}
|
||||
last_cycle();
|
||||
op_io();
|
||||
@@ -94,10 +98,7 @@ case 0x02: {
|
||||
case 0xdb: {
|
||||
op_io();
|
||||
last_cycle();
|
||||
while(1) {
|
||||
op_io();
|
||||
co_return();
|
||||
}
|
||||
while(1) { op_io(); }
|
||||
} break;
|
||||
|
||||
//wai
|
||||
@@ -109,7 +110,6 @@ case 0xcb: {
|
||||
while(event.wai) {
|
||||
last_cycle();
|
||||
op_io();
|
||||
co_return();
|
||||
}
|
||||
} break;
|
||||
|
||||
@@ -117,13 +117,14 @@ case 0xcb: {
|
||||
case 0xfb: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
bool c = regs.p.c;
|
||||
bool carry = regs.p.c;
|
||||
regs.p.c = regs.e;
|
||||
regs.e = c;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
regs.acc_8b = (regs.e || regs.p.m);
|
||||
regs.idx_8b = (regs.e || regs.p.x);
|
||||
if(regs.idx_8b) {
|
||||
regs.e = carry;
|
||||
if(regs.e) {
|
||||
regs.p |= 0x30;
|
||||
regs.s.h = 0x01;
|
||||
}
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
@@ -184,9 +185,8 @@ case 0xc2: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p &=~ rd.l;
|
||||
regs.acc_8b = (regs.e || regs.p.m);
|
||||
regs.idx_8b = (regs.e || regs.p.x);
|
||||
if(regs.idx_8b) {
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
@@ -198,9 +198,8 @@ case 0xe2: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.p |= rd.l;
|
||||
regs.acc_8b = (regs.e || regs.p.m);
|
||||
regs.idx_8b = (regs.e || regs.p.x);
|
||||
if(regs.idx_8b) {
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
@@ -210,13 +209,13 @@ case 0xe2: {
|
||||
case 0xaa: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.idx_8b) {
|
||||
if(regs.p.x) {
|
||||
regs.x.l = regs.a.l;
|
||||
regs.p.n = bool(regs.x.l & 0x80);
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w = regs.a.w;
|
||||
regs.p.n = bool(regs.x.w & 0x8000);
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
} break;
|
||||
@@ -225,13 +224,13 @@ case 0xaa: {
|
||||
case 0xa8: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.idx_8b) {
|
||||
if(regs.p.x) {
|
||||
regs.y.l = regs.a.l;
|
||||
regs.p.n = bool(regs.y.l & 0x80);
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
} else {
|
||||
regs.y.w = regs.a.w;
|
||||
regs.p.n = bool(regs.y.w & 0x8000);
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
} break;
|
||||
@@ -240,13 +239,13 @@ case 0xa8: {
|
||||
case 0x8a: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.acc_8b) {
|
||||
if(regs.p.m) {
|
||||
regs.a.l = regs.x.l;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.a.w = regs.x.w;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
} break;
|
||||
@@ -255,13 +254,13 @@ case 0x8a: {
|
||||
case 0x9b: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.idx_8b) {
|
||||
if(regs.p.x) {
|
||||
regs.y.l = regs.x.l;
|
||||
regs.p.n = bool(regs.y.l & 0x80);
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
} else {
|
||||
regs.y.w = regs.x.w;
|
||||
regs.p.n = bool(regs.y.w & 0x8000);
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
}
|
||||
} break;
|
||||
@@ -270,13 +269,13 @@ case 0x9b: {
|
||||
case 0x98: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.acc_8b) {
|
||||
if(regs.p.m) {
|
||||
regs.a.l = regs.y.l;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.a.w = regs.y.w;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
} break;
|
||||
@@ -285,13 +284,13 @@ case 0x98: {
|
||||
case 0xbb: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.idx_8b) {
|
||||
if(regs.p.x) {
|
||||
regs.x.l = regs.y.l;
|
||||
regs.p.n = bool(regs.x.l & 0x80);
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w = regs.y.w;
|
||||
regs.p.n = bool(regs.x.w & 0x8000);
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
} break;
|
||||
@@ -301,7 +300,7 @@ case 0x5b: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.d.w = regs.a.w;
|
||||
regs.p.n = bool(regs.d.w & 0x8000);
|
||||
regs.p.n = !!(regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
} break;
|
||||
|
||||
@@ -318,7 +317,7 @@ case 0x7b: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
regs.a.w = regs.d.w;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
} break;
|
||||
|
||||
@@ -328,10 +327,10 @@ case 0x3b: {
|
||||
op_io();
|
||||
regs.a.w = regs.s.w;
|
||||
if(regs.e) {
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
} break;
|
||||
@@ -340,13 +339,13 @@ case 0x3b: {
|
||||
case 0xba: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.idx_8b) {
|
||||
if(regs.p.x) {
|
||||
regs.x.l = regs.s.l;
|
||||
regs.p.n = bool(regs.x.l & 0x80);
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w = regs.s.w;
|
||||
regs.p.n = bool(regs.x.w & 0x8000);
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
}
|
||||
} break;
|
||||
@@ -365,7 +364,7 @@ case 0x9a: {
|
||||
//pha
|
||||
case 0x48: {
|
||||
op_io();
|
||||
if(!regs.acc_8b)op_writestack(regs.a.h);
|
||||
if(!regs.p.m)op_writestack(regs.a.h);
|
||||
last_cycle();
|
||||
op_writestack(regs.a.l);
|
||||
} break;
|
||||
@@ -373,7 +372,7 @@ case 0x48: {
|
||||
//phx
|
||||
case 0xda: {
|
||||
op_io();
|
||||
if(!regs.idx_8b)op_writestack(regs.x.h);
|
||||
if(!regs.p.x)op_writestack(regs.x.h);
|
||||
last_cycle();
|
||||
op_writestack(regs.x.l);
|
||||
} break;
|
||||
@@ -381,7 +380,7 @@ case 0xda: {
|
||||
//phy
|
||||
case 0x5a: {
|
||||
op_io();
|
||||
if(!regs.idx_8b)op_writestack(regs.y.h);
|
||||
if(!regs.p.x)op_writestack(regs.y.h);
|
||||
last_cycle();
|
||||
op_writestack(regs.y.l);
|
||||
} break;
|
||||
@@ -389,9 +388,10 @@ case 0x5a: {
|
||||
//phd
|
||||
case 0x0b: {
|
||||
op_io();
|
||||
if(!0)op_writestack(regs. d.h);
|
||||
op_writestackn(regs.d.h);
|
||||
last_cycle();
|
||||
op_writestack(regs. d.l);
|
||||
op_writestackn(regs.d.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
//phb
|
||||
@@ -419,16 +419,16 @@ case 0x08: {
|
||||
case 0x68: {
|
||||
op_io();
|
||||
op_io();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
regs.a.l = op_readstack();
|
||||
if(regs.acc_8b) {
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
if(regs.p.m) {
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
break;
|
||||
}
|
||||
last_cycle();
|
||||
regs.a.h = op_readstack();
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
} break;
|
||||
|
||||
@@ -436,16 +436,16 @@ case 0x68: {
|
||||
case 0xfa: {
|
||||
op_io();
|
||||
op_io();
|
||||
if(regs.idx_8b)last_cycle();
|
||||
if(regs.p.x)last_cycle();
|
||||
regs.x.l = op_readstack();
|
||||
if(regs.idx_8b) {
|
||||
regs.p.n = bool(regs.x.l & 0x80);
|
||||
if(regs.p.x) {
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
break;
|
||||
}
|
||||
last_cycle();
|
||||
regs.x.h = op_readstack();
|
||||
regs.p.n = bool(regs.x.w & 0x8000);
|
||||
regs.p.n = !!(regs.x.w & 0x8000);
|
||||
regs.p.z = (regs.x.w == 0);
|
||||
} break;
|
||||
|
||||
@@ -453,16 +453,16 @@ case 0xfa: {
|
||||
case 0x7a: {
|
||||
op_io();
|
||||
op_io();
|
||||
if(regs.idx_8b)last_cycle();
|
||||
if(regs.p.x)last_cycle();
|
||||
regs.y.l = op_readstack();
|
||||
if(regs.idx_8b) {
|
||||
regs.p.n = bool(regs.y.l & 0x80);
|
||||
if(regs.p.x) {
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
break;
|
||||
}
|
||||
last_cycle();
|
||||
regs.y.h = op_readstack();
|
||||
regs.p.n = bool(regs.y.w & 0x8000);
|
||||
regs.p.n = !!(regs.y.w & 0x8000);
|
||||
regs.p.z = (regs.y.w == 0);
|
||||
} break;
|
||||
|
||||
@@ -470,17 +470,12 @@ case 0x7a: {
|
||||
case 0x2b: {
|
||||
op_io();
|
||||
op_io();
|
||||
if(0)last_cycle();
|
||||
regs. d.l = op_readstack();
|
||||
if(0) {
|
||||
regs.p.n = bool(regs. d.l & 0x80);
|
||||
regs.p.z = (regs. d.l == 0);
|
||||
break;
|
||||
}
|
||||
regs.d.l = op_readstackn();
|
||||
last_cycle();
|
||||
regs. d.h = op_readstack();
|
||||
regs.p.n = bool(regs. d.w & 0x8000);
|
||||
regs.p.z = (regs. d.w == 0);
|
||||
regs.d.h = op_readstackn();
|
||||
regs.p.n = !!(regs.d.w & 0x8000);
|
||||
regs.p.z = (regs.d.w == 0);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
//plb
|
||||
@@ -489,7 +484,7 @@ case 0xab: {
|
||||
op_io();
|
||||
last_cycle();
|
||||
regs.db = op_readstack();
|
||||
regs.p.n = bool(regs.db & 0x80);
|
||||
regs.p.n = !!(regs.db & 0x80);
|
||||
regs.p.z = (regs.db == 0);
|
||||
} break;
|
||||
|
||||
@@ -499,9 +494,8 @@ case 0x28: {
|
||||
op_io();
|
||||
last_cycle();
|
||||
regs.p = op_readstack();
|
||||
regs.acc_8b = (regs.e || regs.p.m);
|
||||
regs.idx_8b = (regs.e || regs.p.x);
|
||||
if(regs.idx_8b) {
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
@@ -511,9 +505,10 @@ case 0x28: {
|
||||
case 0xf4: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_writestack(aa.h);
|
||||
op_writestackn(aa.h);
|
||||
last_cycle();
|
||||
op_writestack(aa.l);
|
||||
op_writestackn(aa.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
//pei
|
||||
@@ -522,9 +517,10 @@ case 0xd4: {
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_writestack(aa.h);
|
||||
op_writestackn(aa.h);
|
||||
last_cycle();
|
||||
op_writestack(aa.l);
|
||||
op_writestackn(aa.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
//per
|
||||
@@ -533,8 +529,9 @@ case 0x62: {
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.w = regs.pc.d + (int16)aa.w;
|
||||
op_writestack(rd.h);
|
||||
op_writestackn(rd.h);
|
||||
last_cycle();
|
||||
op_writestack(rd.l);
|
||||
op_writestackn(rd.l);
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
+18
-16
@@ -48,7 +48,7 @@ jmp_long(0x5c) {
|
||||
2:rd.h = op_readpc();
|
||||
3:last_cycle();
|
||||
rd.b = op_readpc();
|
||||
regs.pc.d = uclip<24>(rd.d);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
jmp_iaddr(0x6c) {
|
||||
@@ -77,7 +77,7 @@ jmp_iladdr(0xdc) {
|
||||
4:rd.h = op_readaddr(aa.w + 1);
|
||||
5:last_cycle();
|
||||
rd.b = op_readaddr(aa.w + 2);
|
||||
regs.pc.d = uclip<24>(rd.d);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
jsr_addr(0x20) {
|
||||
@@ -94,35 +94,36 @@ jsr_addr(0x20) {
|
||||
jsr_long(0x22) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_writestack(regs.pc.b);
|
||||
3:op_writestackn(regs.pc.b);
|
||||
4:op_io();
|
||||
5:aa.b = op_readpc();
|
||||
6:regs.pc.w--;
|
||||
op_writestack(regs.pc.h);
|
||||
op_writestackn(regs.pc.h);
|
||||
7:last_cycle();
|
||||
op_writestack(regs.pc.l);
|
||||
regs.pc.d = uclip<24>(aa.d);
|
||||
op_writestackn(regs.pc.l);
|
||||
regs.pc.d = aa.d & 0xffffff;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
jsr_iaddrx(0xfc) {
|
||||
1:aa.l = op_readpc();
|
||||
2:op_writestack(regs.pc.h);
|
||||
3:op_writestack(regs.pc.l);
|
||||
2:op_writestackn(regs.pc.h);
|
||||
3:op_writestackn(regs.pc.l);
|
||||
4:aa.h = op_readpc();
|
||||
5:op_io();
|
||||
6:rd.l = op_readpbr(aa.w + regs.x.w);
|
||||
7:last_cycle();
|
||||
rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
|
||||
rti(0x40) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:regs.p = op_readstack();
|
||||
regs.acc_8b = (regs.e || regs.p.m);
|
||||
regs.idx_8b = (regs.e || regs.p.x);
|
||||
if(regs.idx_8b) {
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
@@ -135,7 +136,7 @@ rti(0x40) {
|
||||
}
|
||||
6:last_cycle();
|
||||
rd.b = op_readstack();
|
||||
regs.pc.d = uclip<24>(rd.d);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
}
|
||||
|
||||
rts(0x60) {
|
||||
@@ -152,10 +153,11 @@ rts(0x60) {
|
||||
rtl(0x6b) {
|
||||
1:op_io();
|
||||
2:op_io();
|
||||
3:rd.l = op_readstack();
|
||||
4:rd.h = op_readstack();
|
||||
3:rd.l = op_readstackn();
|
||||
4:rd.h = op_readstackn();
|
||||
5:last_cycle();
|
||||
rd.b = op_readstack();
|
||||
regs.pc.d = uclip<24>(rd.d);
|
||||
rd.b = op_readstackn();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
regs.pc.w++;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
}
|
||||
+18
-16
@@ -151,7 +151,7 @@ case 0x5c: {
|
||||
rd.h = op_readpc();
|
||||
last_cycle();
|
||||
rd.b = op_readpc();
|
||||
regs.pc.d = uclip<24>(rd.d);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
} break;
|
||||
|
||||
//jmp_iaddr
|
||||
@@ -183,7 +183,7 @@ case 0xdc: {
|
||||
rd.h = op_readaddr(aa.w + 1);
|
||||
last_cycle();
|
||||
rd.b = op_readaddr(aa.w + 2);
|
||||
regs.pc.d = uclip<24>(rd.d);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
} break;
|
||||
|
||||
//jsr_addr
|
||||
@@ -202,27 +202,29 @@ case 0x20: {
|
||||
case 0x22: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_writestack(regs.pc.b);
|
||||
op_writestackn(regs.pc.b);
|
||||
op_io();
|
||||
aa.b = op_readpc();
|
||||
regs.pc.w--;
|
||||
op_writestack(regs.pc.h);
|
||||
op_writestackn(regs.pc.h);
|
||||
last_cycle();
|
||||
op_writestack(regs.pc.l);
|
||||
regs.pc.d = uclip<24>(aa.d);
|
||||
op_writestackn(regs.pc.l);
|
||||
regs.pc.d = aa.d & 0xffffff;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
//jsr_iaddrx
|
||||
case 0xfc: {
|
||||
aa.l = op_readpc();
|
||||
op_writestack(regs.pc.h);
|
||||
op_writestack(regs.pc.l);
|
||||
op_writestackn(regs.pc.h);
|
||||
op_writestackn(regs.pc.l);
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readpbr(aa.w + regs.x.w);
|
||||
last_cycle();
|
||||
rd.h = op_readpbr(aa.w + regs.x.w + 1);
|
||||
regs.pc.w = rd.w;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
//rti
|
||||
@@ -230,9 +232,8 @@ case 0x40: {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.p = op_readstack();
|
||||
regs.acc_8b = (regs.e || regs.p.m);
|
||||
regs.idx_8b = (regs.e || regs.p.x);
|
||||
if(regs.idx_8b) {
|
||||
if(regs.e)regs.p |= 0x30;
|
||||
if(regs.p.x) {
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
}
|
||||
@@ -245,7 +246,7 @@ case 0x40: {
|
||||
}
|
||||
last_cycle();
|
||||
rd.b = op_readstack();
|
||||
regs.pc.d = uclip<24>(rd.d);
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
} break;
|
||||
|
||||
//rts
|
||||
@@ -264,11 +265,12 @@ case 0x60: {
|
||||
case 0x6b: {
|
||||
op_io();
|
||||
op_io();
|
||||
rd.l = op_readstack();
|
||||
rd.h = op_readstack();
|
||||
rd.l = op_readstackn();
|
||||
rd.h = op_readstackn();
|
||||
last_cycle();
|
||||
rd.b = op_readstack();
|
||||
regs.pc.d = uclip<24>(rd.d);
|
||||
rd.b = op_readstackn();
|
||||
regs.pc.d = rd.d & 0xffffff;
|
||||
regs.pc.w++;
|
||||
if(regs.e)regs.s.h = 0x01;
|
||||
} break;
|
||||
|
||||
+122
-122
@@ -1,14 +1,14 @@
|
||||
adc_const(0x69, adc, regs.acc_8b),
|
||||
and_const(0x29, and, regs.acc_8b),
|
||||
cmp_const(0xc9, cmp, regs.acc_8b),
|
||||
cpx_const(0xe0, cpx, regs.idx_8b),
|
||||
cpy_const(0xc0, cpy, regs.idx_8b),
|
||||
eor_const(0x49, eor, regs.acc_8b),
|
||||
lda_const(0xa9, lda, regs.acc_8b),
|
||||
ldx_const(0xa2, ldx, regs.idx_8b),
|
||||
ldy_const(0xa0, ldy, regs.idx_8b),
|
||||
ora_const(0x09, ora, regs.acc_8b),
|
||||
sbc_const(0xe9, sbc, regs.acc_8b) {
|
||||
adc_const(0x69, adc, regs.p.m),
|
||||
and_const(0x29, and, regs.p.m),
|
||||
cmp_const(0xc9, cmp, regs.p.m),
|
||||
cpx_const(0xe0, cpx, regs.p.x),
|
||||
cpy_const(0xc0, cpy, regs.p.x),
|
||||
eor_const(0x49, eor, regs.p.m),
|
||||
lda_const(0xa9, lda, regs.p.m),
|
||||
ldx_const(0xa2, ldx, regs.p.x),
|
||||
ldy_const(0xa0, ldy, regs.p.x),
|
||||
ora_const(0x09, ora, regs.p.m),
|
||||
sbc_const(0xe9, sbc, regs.p.m) {
|
||||
1:if($2)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if($2) { op_$1_b(); end; }
|
||||
@@ -17,18 +17,18 @@ sbc_const(0xe9, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_addr(0x6d, adc, regs.acc_8b),
|
||||
and_addr(0x2d, and, regs.acc_8b),
|
||||
bit_addr(0x2c, bit, regs.acc_8b),
|
||||
cmp_addr(0xcd, cmp, regs.acc_8b),
|
||||
cpx_addr(0xec, cpx, regs.idx_8b),
|
||||
cpy_addr(0xcc, cpy, regs.idx_8b),
|
||||
eor_addr(0x4d, eor, regs.acc_8b),
|
||||
lda_addr(0xad, lda, regs.acc_8b),
|
||||
ldx_addr(0xae, ldx, regs.idx_8b),
|
||||
ldy_addr(0xac, ldy, regs.idx_8b),
|
||||
ora_addr(0x0d, ora, regs.acc_8b),
|
||||
sbc_addr(0xed, sbc, regs.acc_8b) {
|
||||
adc_addr(0x6d, adc, regs.p.m),
|
||||
and_addr(0x2d, and, regs.p.m),
|
||||
bit_addr(0x2c, bit, regs.p.m),
|
||||
cmp_addr(0xcd, cmp, regs.p.m),
|
||||
cpx_addr(0xec, cpx, regs.p.x),
|
||||
cpy_addr(0xcc, cpy, regs.p.x),
|
||||
eor_addr(0x4d, eor, regs.p.m),
|
||||
lda_addr(0xad, lda, regs.p.m),
|
||||
ldx_addr(0xae, ldx, regs.p.x),
|
||||
ldy_addr(0xac, ldy, regs.p.x),
|
||||
ora_addr(0x0d, ora, regs.p.m),
|
||||
sbc_addr(0xed, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:if($2)last_cycle();
|
||||
@@ -39,15 +39,15 @@ sbc_addr(0xed, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_addrx(0x7d, adc, regs.acc_8b),
|
||||
and_addrx(0x3d, and, regs.acc_8b),
|
||||
bit_addrx(0x3c, bit, regs.acc_8b),
|
||||
cmp_addrx(0xdd, cmp, regs.acc_8b),
|
||||
eor_addrx(0x5d, eor, regs.acc_8b),
|
||||
lda_addrx(0xbd, lda, regs.acc_8b),
|
||||
ldy_addrx(0xbc, ldy, regs.idx_8b),
|
||||
ora_addrx(0x1d, ora, regs.acc_8b),
|
||||
sbc_addrx(0xfd, sbc, regs.acc_8b) {
|
||||
adc_addrx(0x7d, adc, regs.p.m),
|
||||
and_addrx(0x3d, and, regs.p.m),
|
||||
bit_addrx(0x3c, bit, regs.p.m),
|
||||
cmp_addrx(0xdd, cmp, regs.p.m),
|
||||
eor_addrx(0x5d, eor, regs.p.m),
|
||||
lda_addrx(0xbd, lda, regs.p.m),
|
||||
ldy_addrx(0xbc, ldy, regs.p.x),
|
||||
ora_addrx(0x1d, ora, regs.p.m),
|
||||
sbc_addrx(0xfd, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io_cond4(aa.w, aa.w + regs.x.w);
|
||||
@@ -59,14 +59,14 @@ sbc_addrx(0xfd, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_addry(0x79, adc, regs.acc_8b),
|
||||
and_addry(0x39, and, regs.acc_8b),
|
||||
cmp_addry(0xd9, cmp, regs.acc_8b),
|
||||
eor_addry(0x59, eor, regs.acc_8b),
|
||||
lda_addry(0xb9, lda, regs.acc_8b),
|
||||
ldx_addry(0xbe, ldx, regs.idx_8b),
|
||||
ora_addry(0x19, ora, regs.acc_8b),
|
||||
sbc_addry(0xf9, sbc, regs.acc_8b) {
|
||||
adc_addry(0x79, adc, regs.p.m),
|
||||
and_addry(0x39, and, regs.p.m),
|
||||
cmp_addry(0xd9, cmp, regs.p.m),
|
||||
eor_addry(0x59, eor, regs.p.m),
|
||||
lda_addry(0xb9, lda, regs.p.m),
|
||||
ldx_addry(0xbe, ldx, regs.p.x),
|
||||
ora_addry(0x19, ora, regs.p.m),
|
||||
sbc_addry(0xf9, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io_cond4(aa.w, aa.w + regs.y.w);
|
||||
@@ -78,13 +78,13 @@ sbc_addry(0xf9, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_long(0x6f, adc, regs.acc_8b),
|
||||
and_long(0x2f, and, regs.acc_8b),
|
||||
cmp_long(0xcf, cmp, regs.acc_8b),
|
||||
eor_long(0x4f, eor, regs.acc_8b),
|
||||
lda_long(0xaf, lda, regs.acc_8b),
|
||||
ora_long(0x0f, ora, regs.acc_8b),
|
||||
sbc_long(0xef, sbc, regs.acc_8b) {
|
||||
adc_long(0x6f, adc, regs.p.m),
|
||||
and_long(0x2f, and, regs.p.m),
|
||||
cmp_long(0xcf, cmp, regs.p.m),
|
||||
eor_long(0x4f, eor, regs.p.m),
|
||||
lda_long(0xaf, lda, regs.p.m),
|
||||
ora_long(0x0f, ora, regs.p.m),
|
||||
sbc_long(0xef, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:aa.b = op_readpc();
|
||||
@@ -96,13 +96,13 @@ sbc_long(0xef, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_longx(0x7f, adc, regs.acc_8b),
|
||||
and_longx(0x3f, and, regs.acc_8b),
|
||||
cmp_longx(0xdf, cmp, regs.acc_8b),
|
||||
eor_longx(0x5f, eor, regs.acc_8b),
|
||||
lda_longx(0xbf, lda, regs.acc_8b),
|
||||
ora_longx(0x1f, ora, regs.acc_8b),
|
||||
sbc_longx(0xff, sbc, regs.acc_8b) {
|
||||
adc_longx(0x7f, adc, regs.p.m),
|
||||
and_longx(0x3f, and, regs.p.m),
|
||||
cmp_longx(0xdf, cmp, regs.p.m),
|
||||
eor_longx(0x5f, eor, regs.p.m),
|
||||
lda_longx(0xbf, lda, regs.p.m),
|
||||
ora_longx(0x1f, ora, regs.p.m),
|
||||
sbc_longx(0xff, sbc, regs.p.m) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:aa.b = op_readpc();
|
||||
@@ -114,18 +114,18 @@ sbc_longx(0xff, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_dp(0x65, adc, regs.acc_8b),
|
||||
and_dp(0x25, and, regs.acc_8b),
|
||||
bit_dp(0x24, bit, regs.acc_8b),
|
||||
cmp_dp(0xc5, cmp, regs.acc_8b),
|
||||
cpx_dp(0xe4, cpx, regs.idx_8b),
|
||||
cpy_dp(0xc4, cpy, regs.idx_8b),
|
||||
eor_dp(0x45, eor, regs.acc_8b),
|
||||
lda_dp(0xa5, lda, regs.acc_8b),
|
||||
ldx_dp(0xa6, ldx, regs.idx_8b),
|
||||
ldy_dp(0xa4, ldy, regs.idx_8b),
|
||||
ora_dp(0x05, ora, regs.acc_8b),
|
||||
sbc_dp(0xe5, sbc, regs.acc_8b) {
|
||||
adc_dp(0x65, adc, regs.p.m),
|
||||
and_dp(0x25, and, regs.p.m),
|
||||
bit_dp(0x24, bit, regs.p.m),
|
||||
cmp_dp(0xc5, cmp, regs.p.m),
|
||||
cpx_dp(0xe4, cpx, regs.p.x),
|
||||
cpy_dp(0xc4, cpy, regs.p.x),
|
||||
eor_dp(0x45, eor, regs.p.m),
|
||||
lda_dp(0xa5, lda, regs.p.m),
|
||||
ldx_dp(0xa6, ldx, regs.p.x),
|
||||
ldy_dp(0xa4, ldy, regs.p.x),
|
||||
ora_dp(0x05, ora, regs.p.m),
|
||||
sbc_dp(0xe5, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:if($2)last_cycle();
|
||||
@@ -136,15 +136,15 @@ sbc_dp(0xe5, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_dpx(0x75, adc, regs.acc_8b),
|
||||
and_dpx(0x35, and, regs.acc_8b),
|
||||
bit_dpx(0x34, bit, regs.acc_8b),
|
||||
cmp_dpx(0xd5, cmp, regs.acc_8b),
|
||||
eor_dpx(0x55, eor, regs.acc_8b),
|
||||
lda_dpx(0xb5, lda, regs.acc_8b),
|
||||
ldy_dpx(0xb4, ldy, regs.idx_8b),
|
||||
ora_dpx(0x15, ora, regs.acc_8b),
|
||||
sbc_dpx(0xf5, sbc, regs.acc_8b) {
|
||||
adc_dpx(0x75, adc, regs.p.m),
|
||||
and_dpx(0x35, and, regs.p.m),
|
||||
bit_dpx(0x34, bit, regs.p.m),
|
||||
cmp_dpx(0xd5, cmp, regs.p.m),
|
||||
eor_dpx(0x55, eor, regs.p.m),
|
||||
lda_dpx(0xb5, lda, regs.p.m),
|
||||
ldy_dpx(0xb4, ldy, regs.p.x),
|
||||
ora_dpx(0x15, ora, regs.p.m),
|
||||
sbc_dpx(0xf5, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
@@ -156,7 +156,7 @@ sbc_dpx(0xf5, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
ldx_dpy(0xb6, ldx, regs.idx_8b) {
|
||||
ldx_dpy(0xb6, ldx, regs.p.x) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
@@ -168,13 +168,13 @@ ldx_dpy(0xb6, ldx, regs.idx_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_idp(0x72, adc, regs.acc_8b),
|
||||
and_idp(0x32, and, regs.acc_8b),
|
||||
cmp_idp(0xd2, cmp, regs.acc_8b),
|
||||
eor_idp(0x52, eor, regs.acc_8b),
|
||||
lda_idp(0xb2, lda, regs.acc_8b),
|
||||
ora_idp(0x12, ora, regs.acc_8b),
|
||||
sbc_idp(0xf2, sbc, regs.acc_8b) {
|
||||
adc_idp(0x72, adc, regs.p.m),
|
||||
and_idp(0x32, and, regs.p.m),
|
||||
cmp_idp(0xd2, cmp, regs.p.m),
|
||||
eor_idp(0x52, eor, regs.p.m),
|
||||
lda_idp(0xb2, lda, regs.p.m),
|
||||
ora_idp(0x12, ora, regs.p.m),
|
||||
sbc_idp(0xf2, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
@@ -187,13 +187,13 @@ sbc_idp(0xf2, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_idpx(0x61, adc, regs.acc_8b),
|
||||
and_idpx(0x21, and, regs.acc_8b),
|
||||
cmp_idpx(0xc1, cmp, regs.acc_8b),
|
||||
eor_idpx(0x41, eor, regs.acc_8b),
|
||||
lda_idpx(0xa1, lda, regs.acc_8b),
|
||||
ora_idpx(0x01, ora, regs.acc_8b),
|
||||
sbc_idpx(0xe1, sbc, regs.acc_8b) {
|
||||
adc_idpx(0x61, adc, regs.p.m),
|
||||
and_idpx(0x21, and, regs.p.m),
|
||||
cmp_idpx(0xc1, cmp, regs.p.m),
|
||||
eor_idpx(0x41, eor, regs.p.m),
|
||||
lda_idpx(0xa1, lda, regs.p.m),
|
||||
ora_idpx(0x01, ora, regs.p.m),
|
||||
sbc_idpx(0xe1, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
@@ -207,13 +207,13 @@ sbc_idpx(0xe1, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_idpy(0x71, adc, regs.acc_8b),
|
||||
and_idpy(0x31, and, regs.acc_8b),
|
||||
cmp_idpy(0xd1, cmp, regs.acc_8b),
|
||||
eor_idpy(0x51, eor, regs.acc_8b),
|
||||
lda_idpy(0xb1, lda, regs.acc_8b),
|
||||
ora_idpy(0x11, ora, regs.acc_8b),
|
||||
sbc_idpy(0xf1, sbc, regs.acc_8b) {
|
||||
adc_idpy(0x71, adc, regs.p.m),
|
||||
and_idpy(0x31, and, regs.p.m),
|
||||
cmp_idpy(0xd1, cmp, regs.p.m),
|
||||
eor_idpy(0x51, eor, regs.p.m),
|
||||
lda_idpy(0xb1, lda, regs.p.m),
|
||||
ora_idpy(0x11, ora, regs.p.m),
|
||||
sbc_idpy(0xf1, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
@@ -227,13 +227,13 @@ sbc_idpy(0xf1, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_ildp(0x67, adc, regs.acc_8b),
|
||||
and_ildp(0x27, and, regs.acc_8b),
|
||||
cmp_ildp(0xc7, cmp, regs.acc_8b),
|
||||
eor_ildp(0x47, eor, regs.acc_8b),
|
||||
lda_ildp(0xa7, lda, regs.acc_8b),
|
||||
ora_ildp(0x07, ora, regs.acc_8b),
|
||||
sbc_ildp(0xe7, sbc, regs.acc_8b) {
|
||||
adc_ildp(0x67, adc, regs.p.m),
|
||||
and_ildp(0x27, and, regs.p.m),
|
||||
cmp_ildp(0xc7, cmp, regs.p.m),
|
||||
eor_ildp(0x47, eor, regs.p.m),
|
||||
lda_ildp(0xa7, lda, regs.p.m),
|
||||
ora_ildp(0x07, ora, regs.p.m),
|
||||
sbc_ildp(0xe7, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
@@ -247,13 +247,13 @@ sbc_ildp(0xe7, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_ildpy(0x77, adc, regs.acc_8b),
|
||||
and_ildpy(0x37, and, regs.acc_8b),
|
||||
cmp_ildpy(0xd7, cmp, regs.acc_8b),
|
||||
eor_ildpy(0x57, eor, regs.acc_8b),
|
||||
lda_ildpy(0xb7, lda, regs.acc_8b),
|
||||
ora_ildpy(0x17, ora, regs.acc_8b),
|
||||
sbc_ildpy(0xf7, sbc, regs.acc_8b) {
|
||||
adc_ildpy(0x77, adc, regs.p.m),
|
||||
and_ildpy(0x37, and, regs.p.m),
|
||||
cmp_ildpy(0xd7, cmp, regs.p.m),
|
||||
eor_ildpy(0x57, eor, regs.p.m),
|
||||
lda_ildpy(0xb7, lda, regs.p.m),
|
||||
ora_ildpy(0x17, ora, regs.p.m),
|
||||
sbc_ildpy(0xf7, sbc, regs.p.m) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
@@ -267,13 +267,13 @@ sbc_ildpy(0xf7, sbc, regs.acc_8b) {
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
adc_sr(0x63, adc, regs.acc_8b),
|
||||
and_sr(0x23, and, regs.acc_8b),
|
||||
cmp_sr(0xc3, cmp, regs.acc_8b),
|
||||
eor_sr(0x43, eor, regs.acc_8b),
|
||||
lda_sr(0xa3, lda, regs.acc_8b),
|
||||
ora_sr(0x03, ora, regs.acc_8b),
|
||||
sbc_sr(0xe3, sbc, regs.acc_8b) {
|
||||
adc_sr(0x63, adc, regs.p.m),
|
||||
and_sr(0x23, and, regs.p.m),
|
||||
cmp_sr(0xc3, cmp, regs.p.m),
|
||||
eor_sr(0x43, eor, regs.p.m),
|
||||
lda_sr(0xa3, lda, regs.p.m),
|
||||
ora_sr(0x03, ora, regs.p.m),
|
||||
sbc_sr(0xe3, sbc, regs.p.m) {
|
||||
1:sp = op_readpc();
|
||||
2:op_io();
|
||||
3:if($2)last_cycle();
|
||||
@@ -296,18 +296,18 @@ sbc_isry(0xf3, sbc) {
|
||||
3:aa.l = op_readsp(sp);
|
||||
4:aa.h = op_readsp(sp + 1);
|
||||
5:op_io();
|
||||
6:if(regs.acc_8b)last_cycle();
|
||||
6:if(regs.p.m)last_cycle();
|
||||
rd.l = op_readdbr(aa.w + regs.y.w);
|
||||
if(regs.acc_8b) { op_$1_b(); end; }
|
||||
if(regs.p.m) { op_$1_b(); end; }
|
||||
7:last_cycle();
|
||||
rd.h = op_readdbr(aa.w + regs.y.w + 1);
|
||||
op_$1_w();
|
||||
}
|
||||
|
||||
bit_const(0x89) {
|
||||
1:if(regs.acc_8b)last_cycle();
|
||||
1:if(regs.p.m)last_cycle();
|
||||
rd.l = op_readpc();
|
||||
if(regs.acc_8b) {
|
||||
if(regs.p.m) {
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
end;
|
||||
}
|
||||
|
||||
+252
-252
File diff suppressed because it is too large.
Load diff
+34
-34
@@ -1,31 +1,31 @@
|
||||
inc(0x1a, regs.acc_8b, a),
|
||||
inx(0xe8, regs.idx_8b, x),
|
||||
iny(0xc8, regs.idx_8b, y) {
|
||||
inc(0x1a, regs.p.m, a),
|
||||
inx(0xe8, regs.p.x, x),
|
||||
iny(0xc8, regs.p.x, y) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
if($1) {
|
||||
regs.$2.l++;
|
||||
regs.p.n = bool(regs.$2.l & 0x80);
|
||||
regs.p.n = !!(regs.$2.l & 0x80);
|
||||
regs.p.z = (regs.$2.l == 0);
|
||||
} else {
|
||||
regs.$2.w++;
|
||||
regs.p.n = bool(regs.$2.w & 0x8000);
|
||||
regs.p.n = !!(regs.$2.w & 0x8000);
|
||||
regs.p.z = (regs.$2.w == 0);
|
||||
}
|
||||
}
|
||||
|
||||
dec(0x3a, regs.acc_8b, a),
|
||||
dex(0xca, regs.idx_8b, x),
|
||||
dey(0x88, regs.idx_8b, y) {
|
||||
dec(0x3a, regs.p.m, a),
|
||||
dex(0xca, regs.p.x, x),
|
||||
dey(0x88, regs.p.x, y) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
if($1) {
|
||||
regs.$2.l--;
|
||||
regs.p.n = bool(regs.$2.l & 0x80);
|
||||
regs.p.n = !!(regs.$2.l & 0x80);
|
||||
regs.p.z = (regs.$2.l == 0);
|
||||
} else {
|
||||
regs.$2.w--;
|
||||
regs.p.n = bool(regs.$2.w & 0x8000);
|
||||
regs.p.n = !!(regs.$2.w & 0x8000);
|
||||
regs.p.z = (regs.$2.w == 0);
|
||||
}
|
||||
}
|
||||
@@ -33,15 +33,15 @@ dey(0x88, regs.idx_8b, y) {
|
||||
asl(0x0a) {
|
||||
1:last_cycle();
|
||||
op_io();
|
||||
if(regs.acc_8b) {
|
||||
regs.p.c = bool(regs.a.l & 0x80);
|
||||
if(regs.p.m) {
|
||||
regs.p.c = !!(regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = bool(regs.a.w & 0x8000);
|
||||
regs.p.c = !!(regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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.acc_8b) {
|
||||
if(regs.p.m) {
|
||||
regs.p.c = regs.a.l & 1;
|
||||
regs.a.l >>= 1;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = regs.a.w & 1;
|
||||
regs.a.w >>= 1;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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.acc_8b) {
|
||||
regs.p.c = bool(regs.a.l & 0x80);
|
||||
if(regs.p.m) {
|
||||
regs.p.c = !!(regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.a.l |= c;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = bool(regs.a.w & 0x8000);
|
||||
regs.p.c = !!(regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.a.w |= c;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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.acc_8b) {
|
||||
if(regs.p.m) {
|
||||
c = (regs.p.c)?0x80:0;
|
||||
regs.p.c = regs.a.l & 1;
|
||||
regs.a.l >>= 1;
|
||||
regs.a.l |= c;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
c = (regs.p.c)?0x8000:0;
|
||||
regs.p.c = regs.a.w & 1;
|
||||
regs.a.w >>= 1;
|
||||
regs.a.w |= c;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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.acc_8b)rd.h = op_readdbr(aa.w + 1);
|
||||
4:if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
5:op_io();
|
||||
if(regs.acc_8b) { op_$1_b(); }
|
||||
if(regs.p.m) { op_$1_b(); }
|
||||
else { op_$1_w();
|
||||
6:op_writedbr(aa.w + 1, rd.h); }
|
||||
7:last_cycle();
|
||||
@@ -132,9 +132,9 @@ ror_addrx(0x7e, ror) {
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io();
|
||||
4:rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
5:if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
5:if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
6:op_io();
|
||||
if(regs.acc_8b) { op_$1_b(); }
|
||||
if(regs.p.m) { op_$1_b(); }
|
||||
else { op_$1_w();
|
||||
7:op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
8:last_cycle();
|
||||
@@ -152,9 +152,9 @@ tsb_dp(0x04, tsb) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:rd.l = op_readdp(dp);
|
||||
4:if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
|
||||
4:if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
5:op_io();
|
||||
if(regs.acc_8b) { op_$1_b(); }
|
||||
if(regs.p.m) { op_$1_b(); }
|
||||
else { op_$1_w();
|
||||
6:op_writedp(dp + 1, rd.h); }
|
||||
7:last_cycle();
|
||||
@@ -171,9 +171,9 @@ ror_dpx(0x76, ror) {
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
4:rd.l = op_readdp(dp + regs.x.w);
|
||||
5:if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
5:if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
6:op_io();
|
||||
if(regs.acc_8b) { op_$1_b(); }
|
||||
if(regs.p.m) { op_$1_b(); }
|
||||
else { op_$1_w();
|
||||
7:op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
8:last_cycle();
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
case 0x1a: {
|
||||
last_cycle();
|
||||
op_io();
|
||||
if(regs.acc_8b) {
|
||||
if(regs.p.m) {
|
||||
regs.a.l++;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.a.w++;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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.idx_8b) {
|
||||
if(regs.p.x) {
|
||||
regs.x.l++;
|
||||
regs.p.n = bool(regs.x.l & 0x80);
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w++;
|
||||
regs.p.n = bool(regs.x.w & 0x8000);
|
||||
regs.p.n = !!(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.idx_8b) {
|
||||
if(regs.p.x) {
|
||||
regs.y.l++;
|
||||
regs.p.n = bool(regs.y.l & 0x80);
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
} else {
|
||||
regs.y.w++;
|
||||
regs.p.n = bool(regs.y.w & 0x8000);
|
||||
regs.p.n = !!(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.acc_8b) {
|
||||
if(regs.p.m) {
|
||||
regs.a.l--;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.a.w--;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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.idx_8b) {
|
||||
if(regs.p.x) {
|
||||
regs.x.l--;
|
||||
regs.p.n = bool(regs.x.l & 0x80);
|
||||
regs.p.n = !!(regs.x.l & 0x80);
|
||||
regs.p.z = (regs.x.l == 0);
|
||||
} else {
|
||||
regs.x.w--;
|
||||
regs.p.n = bool(regs.x.w & 0x8000);
|
||||
regs.p.n = !!(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.idx_8b) {
|
||||
if(regs.p.x) {
|
||||
regs.y.l--;
|
||||
regs.p.n = bool(regs.y.l & 0x80);
|
||||
regs.p.n = !!(regs.y.l & 0x80);
|
||||
regs.p.z = (regs.y.l == 0);
|
||||
} else {
|
||||
regs.y.w--;
|
||||
regs.p.n = bool(regs.y.w & 0x8000);
|
||||
regs.p.n = !!(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.acc_8b) {
|
||||
regs.p.c = bool(regs.a.l & 0x80);
|
||||
if(regs.p.m) {
|
||||
regs.p.c = !!(regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = bool(regs.a.w & 0x8000);
|
||||
regs.p.c = !!(regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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.acc_8b) {
|
||||
if(regs.p.m) {
|
||||
regs.p.c = regs.a.l & 1;
|
||||
regs.a.l >>= 1;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = regs.a.w & 1;
|
||||
regs.a.w >>= 1;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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.acc_8b) {
|
||||
regs.p.c = bool(regs.a.l & 0x80);
|
||||
if(regs.p.m) {
|
||||
regs.p.c = !!(regs.a.l & 0x80);
|
||||
regs.a.l <<= 1;
|
||||
regs.a.l |= c;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
regs.p.c = bool(regs.a.w & 0x8000);
|
||||
regs.p.c = !!(regs.a.w & 0x8000);
|
||||
regs.a.w <<= 1;
|
||||
regs.a.w |= c;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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.acc_8b) {
|
||||
if(regs.p.m) {
|
||||
c = (regs.p.c)?0x80:0;
|
||||
regs.p.c = regs.a.l & 1;
|
||||
regs.a.l >>= 1;
|
||||
regs.a.l |= c;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(regs.a.l & 0x80);
|
||||
regs.p.z = (regs.a.l == 0);
|
||||
} else {
|
||||
c = (regs.p.c)?0x8000:0;
|
||||
regs.p.c = regs.a.w & 1;
|
||||
regs.a.w >>= 1;
|
||||
regs.a.w |= c;
|
||||
regs.p.n = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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.acc_8b)rd.h = op_readdbr(aa.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_inc_b(); }
|
||||
if(regs.p.m) { op_inc_b(); }
|
||||
else { op_inc_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -183,9 +183,9 @@ case 0xce: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_dec_b(); }
|
||||
if(regs.p.m) { op_dec_b(); }
|
||||
else { op_dec_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -197,9 +197,9 @@ case 0x0e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_asl_b(); }
|
||||
if(regs.p.m) { op_asl_b(); }
|
||||
else { op_asl_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -211,9 +211,9 @@ case 0x4e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_lsr_b(); }
|
||||
if(regs.p.m) { op_lsr_b(); }
|
||||
else { op_lsr_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -225,9 +225,9 @@ case 0x2e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_rol_b(); }
|
||||
if(regs.p.m) { op_rol_b(); }
|
||||
else { op_rol_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -239,9 +239,9 @@ case 0x6e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_ror_b(); }
|
||||
if(regs.p.m) { op_ror_b(); }
|
||||
else { op_ror_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -253,9 +253,9 @@ case 0x1c: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_trb_b(); }
|
||||
if(regs.p.m) { op_trb_b(); }
|
||||
else { op_trb_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -267,9 +267,9 @@ case 0x0c: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
rd.l = op_readdbr(aa.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_tsb_b(); }
|
||||
if(regs.p.m) { op_tsb_b(); }
|
||||
else { op_tsb_w();
|
||||
op_writedbr(aa.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -282,9 +282,9 @@ case 0xfe: {
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_inc_b(); }
|
||||
if(regs.p.m) { op_inc_b(); }
|
||||
else { op_inc_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -297,9 +297,9 @@ case 0xde: {
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_dec_b(); }
|
||||
if(regs.p.m) { op_dec_b(); }
|
||||
else { op_dec_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -312,9 +312,9 @@ case 0x1e: {
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_asl_b(); }
|
||||
if(regs.p.m) { op_asl_b(); }
|
||||
else { op_asl_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -327,9 +327,9 @@ case 0x5e: {
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_lsr_b(); }
|
||||
if(regs.p.m) { op_lsr_b(); }
|
||||
else { op_lsr_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -342,9 +342,9 @@ case 0x3e: {
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_rol_b(); }
|
||||
if(regs.p.m) { op_rol_b(); }
|
||||
else { op_rol_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -357,9 +357,9 @@ case 0x7e: {
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
rd.l = op_readdbr(aa.w + regs.x.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdbr(aa.w + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_ror_b(); }
|
||||
if(regs.p.m) { op_ror_b(); }
|
||||
else { op_ror_w();
|
||||
op_writedbr(aa.w + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -371,9 +371,9 @@ case 0xe6: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_inc_b(); }
|
||||
if(regs.p.m) { op_inc_b(); }
|
||||
else { op_inc_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -385,9 +385,9 @@ case 0xc6: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_dec_b(); }
|
||||
if(regs.p.m) { op_dec_b(); }
|
||||
else { op_dec_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -399,9 +399,9 @@ case 0x06: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_asl_b(); }
|
||||
if(regs.p.m) { op_asl_b(); }
|
||||
else { op_asl_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -413,9 +413,9 @@ case 0x46: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_lsr_b(); }
|
||||
if(regs.p.m) { op_lsr_b(); }
|
||||
else { op_lsr_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -427,9 +427,9 @@ case 0x26: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_rol_b(); }
|
||||
if(regs.p.m) { op_rol_b(); }
|
||||
else { op_rol_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -441,9 +441,9 @@ case 0x66: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_ror_b(); }
|
||||
if(regs.p.m) { op_ror_b(); }
|
||||
else { op_ror_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -455,9 +455,9 @@ case 0x14: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_trb_b(); }
|
||||
if(regs.p.m) { op_trb_b(); }
|
||||
else { op_trb_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -469,9 +469,9 @@ case 0x04: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
rd.l = op_readdp(dp);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_tsb_b(); }
|
||||
if(regs.p.m) { op_tsb_b(); }
|
||||
else { op_tsb_w();
|
||||
op_writedp(dp + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -484,9 +484,9 @@ case 0xf6: {
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_inc_b(); }
|
||||
if(regs.p.m) { op_inc_b(); }
|
||||
else { op_inc_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -499,9 +499,9 @@ case 0xd6: {
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_dec_b(); }
|
||||
if(regs.p.m) { op_dec_b(); }
|
||||
else { op_dec_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -514,9 +514,9 @@ case 0x16: {
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_asl_b(); }
|
||||
if(regs.p.m) { op_asl_b(); }
|
||||
else { op_asl_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -529,9 +529,9 @@ case 0x56: {
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_lsr_b(); }
|
||||
if(regs.p.m) { op_lsr_b(); }
|
||||
else { op_lsr_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -544,9 +544,9 @@ case 0x36: {
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_rol_b(); }
|
||||
if(regs.p.m) { op_rol_b(); }
|
||||
else { op_rol_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
@@ -559,9 +559,9 @@ case 0x76: {
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
rd.l = op_readdp(dp + regs.x.w);
|
||||
if(!regs.acc_8b)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
if(!regs.p.m)rd.h = op_readdp(dp + regs.x.w + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b) { op_ror_b(); }
|
||||
if(regs.p.m) { op_ror_b(); }
|
||||
else { op_ror_w();
|
||||
op_writedp(dp + regs.x.w + 1, rd.h); }
|
||||
last_cycle();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
sta_addr(0x8d, regs.acc_8b, regs.a.w),
|
||||
stx_addr(0x8e, regs.idx_8b, regs.x.w),
|
||||
sty_addr(0x8c, regs.idx_8b, regs.y.w),
|
||||
stz_addr(0x9c, regs.acc_8b, 0x0000) {
|
||||
sta_addr(0x8d, regs.p.m, regs.a.w),
|
||||
stx_addr(0x8e, regs.p.x, regs.x.w),
|
||||
sty_addr(0x8c, regs.p.x, regs.y.w),
|
||||
stz_addr(0x9c, regs.p.m, 0x0000) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:if($1)last_cycle();
|
||||
@@ -11,8 +11,8 @@ stz_addr(0x9c, regs.acc_8b, 0x0000) {
|
||||
op_writedbr(aa.w + 1, $2 >> 8);
|
||||
}
|
||||
|
||||
sta_addrx(0x9d, regs.acc_8b, regs.a.w),
|
||||
stz_addrx(0x9e, regs.acc_8b, 0x0000) {
|
||||
sta_addrx(0x9d, regs.p.m, regs.a.w),
|
||||
stz_addrx(0x9e, regs.p.m, 0x0000) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io();
|
||||
@@ -27,9 +27,9 @@ sta_addry(0x99) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:op_io();
|
||||
4:if(regs.acc_8b)last_cycle();
|
||||
4:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.acc_8b)end;
|
||||
if(regs.p.m)end;
|
||||
5:last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
@@ -38,9 +38,9 @@ sta_long(0x8f) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:aa.b = op_readpc();
|
||||
4:if(regs.acc_8b)last_cycle();
|
||||
4:if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.acc_8b)end;
|
||||
if(regs.p.m)end;
|
||||
5:last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
}
|
||||
@@ -49,17 +49,17 @@ sta_longx(0x9f) {
|
||||
1:aa.l = op_readpc();
|
||||
2:aa.h = op_readpc();
|
||||
3:aa.b = op_readpc();
|
||||
4:if(regs.acc_8b)last_cycle();
|
||||
4:if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d + regs.x.w, regs.a.l);
|
||||
if(regs.acc_8b)end;
|
||||
if(regs.p.m)end;
|
||||
5:last_cycle();
|
||||
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
|
||||
}
|
||||
|
||||
sta_dp(0x85, regs.acc_8b, regs.a.w),
|
||||
stx_dp(0x86, regs.idx_8b, regs.x.w),
|
||||
sty_dp(0x84, regs.idx_8b, regs.y.w),
|
||||
stz_dp(0x64, regs.acc_8b, 0x0000) {
|
||||
sta_dp(0x85, regs.p.m, regs.a.w),
|
||||
stx_dp(0x86, regs.p.x, regs.x.w),
|
||||
sty_dp(0x84, regs.p.x, regs.y.w),
|
||||
stz_dp(0x64, regs.p.m, 0x0000) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:if($1)last_cycle();
|
||||
@@ -69,9 +69,9 @@ stz_dp(0x64, regs.acc_8b, 0x0000) {
|
||||
op_writedp(dp + 1, $2 >> 8);
|
||||
}
|
||||
|
||||
sta_dpx(0x95, regs.acc_8b, regs.a.w),
|
||||
sty_dpx(0x94, regs.idx_8b, regs.y.w),
|
||||
stz_dpx(0x74, regs.acc_8b, 0x0000) {
|
||||
sta_dpx(0x95, regs.p.m, regs.a.w),
|
||||
sty_dpx(0x94, regs.p.x, regs.y.w),
|
||||
stz_dpx(0x74, regs.p.m, 0x0000) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
@@ -86,9 +86,9 @@ stx_dpy(0x96) {
|
||||
1:dp = op_readpc();
|
||||
2:op_io_cond2();
|
||||
3:op_io();
|
||||
4:if(regs.idx_8b)last_cycle();
|
||||
4:if(regs.p.x)last_cycle();
|
||||
op_writedp(dp + regs.y.w, regs.x.l);
|
||||
if(regs.idx_8b)end;
|
||||
if(regs.p.x)end;
|
||||
5:last_cycle();
|
||||
op_writedp(dp + regs.y.w + 1, regs.x.h);
|
||||
}
|
||||
@@ -98,9 +98,9 @@ sta_idp(0x92) {
|
||||
2:op_io_cond2();
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:if(regs.acc_8b)last_cycle();
|
||||
5:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.acc_8b)end;
|
||||
if(regs.p.m)end;
|
||||
6:last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
}
|
||||
@@ -111,9 +111,9 @@ sta_ildp(0x87) {
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:aa.b = op_readdp(dp + 2);
|
||||
6:if(regs.acc_8b)last_cycle();
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.acc_8b)end;
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
}
|
||||
@@ -124,9 +124,9 @@ sta_idpx(0x81) {
|
||||
3:op_io();
|
||||
4:aa.l = op_readdp(dp + regs.x.w);
|
||||
5:aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
6:if(regs.acc_8b)last_cycle();
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.acc_8b)end;
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
}
|
||||
@@ -137,9 +137,9 @@ sta_idpy(0x91) {
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:op_io();
|
||||
6:if(regs.acc_8b)last_cycle();
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.acc_8b)end;
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
@@ -150,9 +150,9 @@ sta_ildpy(0x97) {
|
||||
3:aa.l = op_readdp(dp);
|
||||
4:aa.h = op_readdp(dp + 1);
|
||||
5:aa.b = op_readdp(dp + 2);
|
||||
6:if(regs.acc_8b)last_cycle();
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d + regs.y.w, regs.a.l);
|
||||
if(regs.acc_8b)end;
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
@@ -160,9 +160,9 @@ sta_ildpy(0x97) {
|
||||
sta_sr(0x83) {
|
||||
1:sp = op_readpc();
|
||||
2:op_io();
|
||||
3:if(regs.acc_8b)last_cycle();
|
||||
3:if(regs.p.m)last_cycle();
|
||||
op_writesp(sp, regs.a.l);
|
||||
if(regs.acc_8b)end;
|
||||
if(regs.p.m)end;
|
||||
4:last_cycle();
|
||||
op_writesp(sp + 1, regs.a.h);
|
||||
}
|
||||
@@ -173,9 +173,9 @@ sta_isry(0x93) {
|
||||
3:aa.l = op_readsp(sp);
|
||||
4:aa.h = op_readsp(sp + 1);
|
||||
5:op_io();
|
||||
6:if(regs.acc_8b)last_cycle();
|
||||
6:if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.acc_8b)end;
|
||||
if(regs.p.m)end;
|
||||
7:last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
case 0x8d: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.w);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.w >> 8);
|
||||
} break;
|
||||
@@ -13,9 +13,9 @@ case 0x8d: {
|
||||
case 0x8e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
if(regs.idx_8b)last_cycle();
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedbr(aa.w, regs.x.w);
|
||||
if(regs.idx_8b)break;
|
||||
if(regs.p.x)break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.x.w >> 8);
|
||||
} break;
|
||||
@@ -24,9 +24,9 @@ case 0x8e: {
|
||||
case 0x8c: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
if(regs.idx_8b)last_cycle();
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedbr(aa.w, regs.y.w);
|
||||
if(regs.idx_8b)break;
|
||||
if(regs.p.x)break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.y.w >> 8);
|
||||
} break;
|
||||
@@ -35,9 +35,9 @@ case 0x8c: {
|
||||
case 0x9c: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, 0x0000);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, 0x0000 >> 8);
|
||||
} break;
|
||||
@@ -47,9 +47,9 @@ case 0x9d: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, regs.a.w);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w + 1, regs.a.w >> 8);
|
||||
} break;
|
||||
@@ -59,9 +59,9 @@ case 0x9e: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w, 0x0000);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.x.w + 1, 0x0000 >> 8);
|
||||
} break;
|
||||
@@ -71,9 +71,9 @@ case 0x99: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
op_io();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
} break;
|
||||
@@ -83,9 +83,9 @@ case 0x8f: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
aa.b = op_readpc();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
} break;
|
||||
@@ -95,9 +95,9 @@ case 0x9f: {
|
||||
aa.l = op_readpc();
|
||||
aa.h = op_readpc();
|
||||
aa.b = op_readpc();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d + regs.x.w, regs.a.l);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writelong(aa.d + regs.x.w + 1, regs.a.h);
|
||||
} break;
|
||||
@@ -106,9 +106,9 @@ case 0x9f: {
|
||||
case 0x85: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedp(dp, regs.a.w);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, regs.a.w >> 8);
|
||||
} break;
|
||||
@@ -117,9 +117,9 @@ case 0x85: {
|
||||
case 0x86: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
if(regs.idx_8b)last_cycle();
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedp(dp, regs.x.w);
|
||||
if(regs.idx_8b)break;
|
||||
if(regs.p.x)break;
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, regs.x.w >> 8);
|
||||
} break;
|
||||
@@ -128,9 +128,9 @@ case 0x86: {
|
||||
case 0x84: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
if(regs.idx_8b)last_cycle();
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedp(dp, regs.y.w);
|
||||
if(regs.idx_8b)break;
|
||||
if(regs.p.x)break;
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, regs.y.w >> 8);
|
||||
} break;
|
||||
@@ -139,9 +139,9 @@ case 0x84: {
|
||||
case 0x64: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedp(dp, 0x0000);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedp(dp + 1, 0x0000 >> 8);
|
||||
} break;
|
||||
@@ -151,9 +151,9 @@ case 0x95: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedp(dp + regs.x.w, regs.a.w);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, regs.a.w >> 8);
|
||||
} break;
|
||||
@@ -163,9 +163,9 @@ case 0x94: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
if(regs.idx_8b)last_cycle();
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedp(dp + regs.x.w, regs.y.w);
|
||||
if(regs.idx_8b)break;
|
||||
if(regs.p.x)break;
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, regs.y.w >> 8);
|
||||
} break;
|
||||
@@ -175,9 +175,9 @@ case 0x74: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedp(dp + regs.x.w, 0x0000);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.x.w + 1, 0x0000 >> 8);
|
||||
} break;
|
||||
@@ -187,9 +187,9 @@ case 0x96: {
|
||||
dp = op_readpc();
|
||||
op_io_cond2();
|
||||
op_io();
|
||||
if(regs.idx_8b)last_cycle();
|
||||
if(regs.p.x)last_cycle();
|
||||
op_writedp(dp + regs.y.w, regs.x.l);
|
||||
if(regs.idx_8b)break;
|
||||
if(regs.p.x)break;
|
||||
last_cycle();
|
||||
op_writedp(dp + regs.y.w + 1, regs.x.h);
|
||||
} break;
|
||||
@@ -200,9 +200,9 @@ case 0x92: {
|
||||
op_io_cond2();
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
} break;
|
||||
@@ -214,9 +214,9 @@ case 0x87: {
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d, regs.a.l);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writelong(aa.d + 1, regs.a.h);
|
||||
} break;
|
||||
@@ -228,9 +228,9 @@ case 0x81: {
|
||||
op_io();
|
||||
aa.l = op_readdp(dp + regs.x.w);
|
||||
aa.h = op_readdp(dp + regs.x.w + 1);
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w, regs.a.l);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + 1, regs.a.h);
|
||||
} break;
|
||||
@@ -242,9 +242,9 @@ case 0x91: {
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
} break;
|
||||
@@ -256,9 +256,9 @@ case 0x97: {
|
||||
aa.l = op_readdp(dp);
|
||||
aa.h = op_readdp(dp + 1);
|
||||
aa.b = op_readdp(dp + 2);
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writelong(aa.d + regs.y.w, regs.a.l);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writelong(aa.d + regs.y.w + 1, regs.a.h);
|
||||
} break;
|
||||
@@ -267,9 +267,9 @@ case 0x97: {
|
||||
case 0x83: {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writesp(sp, regs.a.l);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writesp(sp + 1, regs.a.h);
|
||||
} break;
|
||||
@@ -281,9 +281,9 @@ case 0x93: {
|
||||
aa.l = op_readsp(sp);
|
||||
aa.h = op_readsp(sp + 1);
|
||||
op_io();
|
||||
if(regs.acc_8b)last_cycle();
|
||||
if(regs.p.m)last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w, regs.a.l);
|
||||
if(regs.acc_8b)break;
|
||||
if(regs.p.m)break;
|
||||
last_cycle();
|
||||
op_writedbr(aa.w + regs.y.w + 1, regs.a.h);
|
||||
} break;
|
||||
|
||||
+54
-58
@@ -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 = bool(r & 0x80);
|
||||
regs.p.v = bool(~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.v = !!(~(regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.a.l = r;
|
||||
}
|
||||
@@ -67,135 +67,135 @@ int32 r;
|
||||
r = regs.a.w + rd.w + regs.p.c;
|
||||
regs.p.c = (r > 0xffff);
|
||||
}
|
||||
regs.p.n = bool(r & 0x8000);
|
||||
regs.p.v = bool(~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.v = !!(~(regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.a.w = r;
|
||||
}
|
||||
|
||||
inline void sCPU::op_and_b() {
|
||||
regs.a.l &= rd.l;
|
||||
regs.p.n = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(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 = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(regs.a.w & 0x8000);
|
||||
regs.p.z = (regs.a.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_bit_b() {
|
||||
regs.p.n = bool(rd.l & 0x80);
|
||||
regs.p.v = bool(rd.l & 0x40);
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.v = !!(rd.l & 0x40);
|
||||
regs.p.z = ((rd.l & regs.a.l) == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_bit_w() {
|
||||
regs.p.n = bool(rd.w & 0x8000);
|
||||
regs.p.v = bool(rd.w & 0x4000);
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.v = !!(rd.w & 0x4000);
|
||||
regs.p.z = ((rd.w & regs.a.w) == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_cmp_b() {
|
||||
int32 r = regs.a.l - rd.l;
|
||||
regs.p.n = bool(r & 0x80);
|
||||
regs.p.n = !!(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 = bool(r & 0x8000);
|
||||
regs.p.n = !!(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 = bool(r & 0x80);
|
||||
regs.p.n = !!(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 = bool(r & 0x8000);
|
||||
regs.p.n = !!(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 = bool(r & 0x80);
|
||||
regs.p.n = !!(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 = bool(r & 0x8000);
|
||||
regs.p.n = !!(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 = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(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 = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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 = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(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 = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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 = bool(regs.x.l & 0x80);
|
||||
regs.p.n = !!(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 = bool(regs.x.w & 0x8000);
|
||||
regs.p.n = !!(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 = bool(regs.y.l & 0x80);
|
||||
regs.p.n = !!(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 = bool(regs.y.w & 0x8000);
|
||||
regs.p.n = !!(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 = bool(regs.a.l & 0x80);
|
||||
regs.p.n = !!(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 = bool(regs.a.w & 0x8000);
|
||||
regs.p.n = !!(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 = bool(r & 0x80);
|
||||
regs.p.v = bool((regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
|
||||
regs.p.n = !!(r & 0x80);
|
||||
regs.p.v = !!((regs.a.l ^ rd.l) & (regs.a.l ^ r) & 0x80);
|
||||
regs.p.z = ((uint8)r == 0);
|
||||
regs.a.l = r;
|
||||
}
|
||||
@@ -261,8 +261,8 @@ int32 r;
|
||||
r = regs.a.w - rd.w - !regs.p.c;
|
||||
regs.p.c = (r >= 0);
|
||||
}
|
||||
regs.p.n = bool(r & 0x8000);
|
||||
regs.p.v = bool((regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
|
||||
regs.p.n = !!(r & 0x8000);
|
||||
regs.p.v = !!((regs.a.w ^ rd.w) & (regs.a.w ^ r) & 0x8000);
|
||||
regs.p.z = ((uint16)r == 0);
|
||||
regs.a.w = r;
|
||||
}
|
||||
@@ -270,89 +270,85 @@ int32 r;
|
||||
//op_rmw
|
||||
inline void sCPU::op_inc_b() {
|
||||
rd.l++;
|
||||
regs.p.n = bool(rd.l & 0x80);
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_inc_w() {
|
||||
rd.w++;
|
||||
regs.p.n = bool(rd.w & 0x8000);
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_dec_b() {
|
||||
rd.l--;
|
||||
regs.p.n = bool(rd.l & 0x80);
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_dec_w() {
|
||||
rd.w--;
|
||||
regs.p.n = bool(rd.w & 0x8000);
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_asl_b() {
|
||||
regs.p.c = bool(rd.l & 0x80);
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
regs.p.n = bool(rd.l & 0x80);
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_asl_w() {
|
||||
regs.p.c = bool(rd.w & 0x8000);
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
regs.p.n = bool(rd.w & 0x8000);
|
||||
regs.p.n = !!(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 = bool(rd.l & 0x80);
|
||||
regs.p.n = !!(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 = bool(rd.w & 0x8000);
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_rol_b() {
|
||||
uint16 c = regs.p.c;
|
||||
regs.p.c = bool(rd.l & 0x80);
|
||||
rd.l <<= 1;
|
||||
rd.l |= c;
|
||||
regs.p.n = bool(rd.l & 0x80);
|
||||
uint16 carry = (uint16)regs.p.c;
|
||||
regs.p.c = !!(rd.l & 0x80);
|
||||
rd.l = (rd.l << 1) | carry;
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_rol_w() {
|
||||
uint16 c = regs.p.c;
|
||||
regs.p.c = bool(rd.w & 0x8000);
|
||||
rd.w <<= 1;
|
||||
rd.w |= c;
|
||||
regs.p.n = bool(rd.w & 0x8000);
|
||||
uint16 carry = (uint16)regs.p.c;
|
||||
regs.p.c = !!(rd.w & 0x8000);
|
||||
rd.w = (rd.w << 1) | carry;
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_ror_b() {
|
||||
uint16 c = (regs.p.c)?0x80:0;
|
||||
uint16 carry = (uint16)regs.p.c << 7;
|
||||
regs.p.c = rd.l & 1;
|
||||
rd.l >>= 1;
|
||||
rd.l |= c;
|
||||
regs.p.n = bool(rd.l & 0x80);
|
||||
rd.l = carry | (rd.l >> 1);
|
||||
regs.p.n = !!(rd.l & 0x80);
|
||||
regs.p.z = (rd.l == 0);
|
||||
}
|
||||
|
||||
inline void sCPU::op_ror_w() {
|
||||
uint16 c = (regs.p.c)?0x8000:0;
|
||||
uint16 carry = (uint16)regs.p.c << 15;
|
||||
regs.p.c = rd.w & 1;
|
||||
rd.w >>= 1;
|
||||
rd.w |= c;
|
||||
regs.p.n = bool(rd.w & 0x8000);
|
||||
rd.w = carry | (rd.w >> 1);
|
||||
regs.p.n = !!(rd.w & 0x8000);
|
||||
regs.p.z = (rd.w == 0);
|
||||
}
|
||||
|
||||
|
||||
+15
-14
@@ -1,3 +1,8 @@
|
||||
void sCPU::dma_add_clocks(uint clocks) {
|
||||
status.dma_clocks += clocks;
|
||||
add_clocks(clocks);
|
||||
}
|
||||
|
||||
/*****
|
||||
* used by both DMA and HDMA
|
||||
*
|
||||
@@ -29,9 +34,7 @@ uint8 r;
|
||||
r_mem->write(abus, r);
|
||||
}
|
||||
|
||||
status.dma_clocks += 8;
|
||||
add_clocks(8);
|
||||
co_return();
|
||||
dma_add_clocks(8);
|
||||
cycle_edge();
|
||||
}
|
||||
|
||||
@@ -105,8 +108,7 @@ inline void sCPU::dma_write(uint8 i, uint8 index) {
|
||||
void sCPU::dma_run() {
|
||||
for(int i = 0; i < 8; i++) {
|
||||
if(channel[i].dma_enabled == false)continue;
|
||||
status.dma_clocks += 8;
|
||||
add_clocks(8);
|
||||
dma_add_clocks(8);
|
||||
|
||||
if(cartridge.info.sdd1 == true) {
|
||||
sdd1->dma_begin(i, (channel[i].srcbank << 16) | (channel[i].srcaddr),
|
||||
@@ -130,7 +132,7 @@ void sCPU::dma_run() {
|
||||
channel[i].dma_enabled = false;
|
||||
}
|
||||
|
||||
counter_set(counter.irq_delay, 24);
|
||||
counter.set(counter.irq_delay, 2);
|
||||
}
|
||||
|
||||
/*****
|
||||
@@ -167,19 +169,19 @@ uint8 r = 0;
|
||||
|
||||
void sCPU::hdma_update(uint8 i) {
|
||||
channel[i].hdma_line_counter = r_mem->read(hdma_addr(i));
|
||||
add_clocks(8);
|
||||
dma_add_clocks(8);
|
||||
|
||||
channel[i].hdma_completed = (channel[i].hdma_line_counter == 0);
|
||||
channel[i].hdma_do_transfer = !channel[i].hdma_completed;
|
||||
|
||||
if(channel[i].hdma_indirect) {
|
||||
channel[i].hdma_iaddr = r_mem->read(hdma_addr(i)) << 8;
|
||||
add_clocks(8);
|
||||
dma_add_clocks(8);
|
||||
|
||||
if(!channel[i].hdma_completed || hdma_active_after(i)) {
|
||||
channel[i].hdma_iaddr >>= 8;
|
||||
channel[i].hdma_iaddr |= r_mem->read(hdma_addr(i)) << 8;
|
||||
add_clocks(8);
|
||||
dma_add_clocks(8);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -189,7 +191,7 @@ 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);
|
||||
dma_add_clocks(8);
|
||||
|
||||
if(channel[i].hdma_do_transfer) {
|
||||
int xferlen = hdma_xferlen[channel[i].xfermode];
|
||||
@@ -198,8 +200,7 @@ static uint8 hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
|
||||
dma_transfer(channel[i].direction, dma_bbus(i, index),
|
||||
!channel[i].hdma_indirect ? hdma_addr(i) : hdma_iaddr(i));
|
||||
} else {
|
||||
add_clocks(8);
|
||||
co_return();
|
||||
dma_add_clocks(8);
|
||||
cycle_edge();
|
||||
}
|
||||
}
|
||||
@@ -212,7 +213,7 @@ static uint8 hdma_xferlen[8] = { 1, 2, 2, 4, 4, 4, 2, 4 };
|
||||
}
|
||||
}
|
||||
|
||||
counter_set(counter.irq_delay, 24);
|
||||
counter.set(counter.irq_delay, 2);
|
||||
}
|
||||
|
||||
void sCPU::hdma_init_reset() {
|
||||
@@ -231,7 +232,7 @@ void sCPU::hdma_init() {
|
||||
hdma_update(i);
|
||||
}
|
||||
|
||||
counter_set(counter.irq_delay, 24);
|
||||
counter.set(counter.irq_delay, 2);
|
||||
}
|
||||
|
||||
/*****
|
||||
|
||||
@@ -45,6 +45,7 @@ struct {
|
||||
bool hdma_do_transfer;
|
||||
} channel[8];
|
||||
|
||||
void dma_add_clocks(uint clocks);
|
||||
void dma_transfer(bool direction, uint8 bbus, uint32 abus);
|
||||
|
||||
uint8 dma_bbus(uint8 i, uint8 index);
|
||||
|
||||
@@ -10,7 +10,6 @@ void sCPU::op_io() {
|
||||
status.clock_count = 6;
|
||||
precycle_edge();
|
||||
add_clocks(6);
|
||||
//co_return();
|
||||
cycle_edge();
|
||||
}
|
||||
|
||||
@@ -18,9 +17,6 @@ uint8 sCPU::op_read(uint32 addr) {
|
||||
status.clock_count = r_mem->speed(addr);
|
||||
precycle_edge();
|
||||
add_clocks(status.clock_count - 4);
|
||||
#ifdef FAVOR_ACCURACY
|
||||
co_return();
|
||||
#endif
|
||||
regs.mdr = r_mem->read(addr);
|
||||
add_clocks(4);
|
||||
cycle_edge();
|
||||
@@ -31,10 +27,95 @@ void sCPU::op_write(uint32 addr, uint8 data) {
|
||||
status.clock_count = r_mem->speed(addr);
|
||||
precycle_edge();
|
||||
add_clocks(status.clock_count);
|
||||
#ifdef FAVOR_ACCURACY
|
||||
co_return();
|
||||
#endif
|
||||
regs.mdr = data;
|
||||
r_mem->write(addr, regs.mdr);
|
||||
cycle_edge();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
alwaysinline uint8 sCPU::op_readpc() {
|
||||
return op_read((regs.pc.b << 16) + regs.pc.w++);
|
||||
}
|
||||
|
||||
alwaysinline uint8 sCPU::op_readstack() {
|
||||
if(regs.e) {
|
||||
regs.s.l++;
|
||||
} else {
|
||||
regs.s.w++;
|
||||
}
|
||||
return op_read(regs.s.w);
|
||||
}
|
||||
|
||||
alwaysinline uint8 sCPU::op_readstackn() {
|
||||
return op_read(++regs.s.w);
|
||||
}
|
||||
|
||||
alwaysinline uint8 sCPU::op_readaddr(uint32 addr) {
|
||||
return op_read(addr & 0xffff);
|
||||
}
|
||||
|
||||
alwaysinline uint8 sCPU::op_readlong(uint32 addr) {
|
||||
return op_read(addr & 0xffffff);
|
||||
}
|
||||
|
||||
alwaysinline uint8 sCPU::op_readdbr(uint32 addr) {
|
||||
return op_read(((regs.db << 16) + addr) & 0xffffff);
|
||||
}
|
||||
|
||||
alwaysinline uint8 sCPU::op_readpbr(uint32 addr) {
|
||||
return op_read((regs.pc.b << 16) + (addr & 0xffff));
|
||||
}
|
||||
|
||||
alwaysinline uint8 sCPU::op_readdp(uint32 addr) {
|
||||
if(regs.e && regs.d.l == 0x00) {
|
||||
return op_read((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff));
|
||||
} else {
|
||||
return op_read((regs.d + (addr & 0xffff)) & 0xffff);
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline uint8 sCPU::op_readsp(uint32 addr) {
|
||||
return op_read((regs.s + (addr & 0xffff)) & 0xffff);
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_writestack(uint8 data) {
|
||||
op_write(regs.s.w, data);
|
||||
if(regs.e) {
|
||||
regs.s.l--;
|
||||
} else {
|
||||
regs.s.w--;
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_writestackn(uint8 data) {
|
||||
op_write(regs.s.w--, data);
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_writeaddr(uint32 addr, uint8 data) {
|
||||
op_write(addr & 0xffff, data);
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_writelong(uint32 addr, uint8 data) {
|
||||
op_write(addr & 0xffffff, data);
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_writedbr(uint32 addr, uint8 data) {
|
||||
op_write(((regs.db << 16) + addr) & 0xffffff, data);
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_writepbr(uint32 addr, uint8 data) {
|
||||
op_write((regs.pc.b << 16) + (addr & 0xffff), data);
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_writedp(uint32 addr, uint8 data) {
|
||||
if(regs.e && regs.d.l == 0x00) {
|
||||
op_write((regs.d & 0xff00) + ((regs.d + (addr & 0xffff)) & 0xff), data);
|
||||
} else {
|
||||
op_write((regs.d + (addr & 0xffff)) & 0xffff, data);
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::op_writesp(uint32 addr, uint8 data) {
|
||||
op_write((regs.s + (addr & 0xffff)) & 0xffff, data);
|
||||
}
|
||||
@@ -15,19 +15,21 @@ uint8 apu_port[4];
|
||||
/*****
|
||||
* helper memory addressing functions used by CPU core
|
||||
*****/
|
||||
uint8 op_readpc () { return op_read((regs.pc.b << 16) + regs.pc.w++); }
|
||||
uint8 op_readstack() { (regs.e) ? regs.s.l++ : regs.s.w++; return op_read(regs.s.w); }
|
||||
uint8 op_readaddr (uint32 addr) { return op_read(addr & 0xffff); }
|
||||
uint8 op_readlong (uint32 addr) { return op_read(addr & 0xffffff); }
|
||||
uint8 op_readdbr (uint32 addr) { return op_read(((regs.db << 16) + addr) & 0xffffff); }
|
||||
uint8 op_readpbr (uint32 addr) { return op_read((regs.pc.b << 16) + (addr & 0xffff)); }
|
||||
uint8 op_readdp (uint32 addr) { return op_read((regs.d + (addr & 0xffff)) & 0xffff); }
|
||||
uint8 op_readsp (uint32 addr) { return op_read((regs.s + (addr & 0xffff)) & 0xffff); }
|
||||
uint8 op_readpc ();
|
||||
uint8 op_readstack ();
|
||||
uint8 op_readstackn();
|
||||
uint8 op_readaddr (uint32 addr);
|
||||
uint8 op_readlong (uint32 addr);
|
||||
uint8 op_readdbr (uint32 addr);
|
||||
uint8 op_readpbr (uint32 addr);
|
||||
uint8 op_readdp (uint32 addr);
|
||||
uint8 op_readsp (uint32 addr);
|
||||
|
||||
void op_writestack(uint8 data) { op_write(regs.s.w, data); (regs.e) ? regs.s.l-- : regs.s.w--; }
|
||||
void op_writeaddr (uint32 addr, uint8 data) { op_write(addr & 0xffff, data); }
|
||||
void op_writelong (uint32 addr, uint8 data) { op_write(addr & 0xffffff, data); }
|
||||
void op_writedbr (uint32 addr, uint8 data) { op_write(((regs.db << 16) + addr) & 0xffffff, data); }
|
||||
void op_writepbr (uint32 addr, uint8 data) { op_write((regs.pc.b << 16) + (addr & 0xffff), data); }
|
||||
void op_writedp (uint32 addr, uint8 data) { op_write((regs.d + (addr & 0xffff)) & 0xffff, data); }
|
||||
void op_writesp (uint32 addr, uint8 data) { op_write((regs.s + (addr & 0xffff)) & 0xffff, data); }
|
||||
void op_writestack (uint8 data);
|
||||
void op_writestackn(uint8 data);
|
||||
void op_writeaddr (uint32 addr, uint8 data);
|
||||
void op_writelong (uint32 addr, uint8 data);
|
||||
void op_writedbr (uint32 addr, uint8 data);
|
||||
void op_writepbr (uint32 addr, uint8 data);
|
||||
void op_writedp (uint32 addr, uint8 data);
|
||||
void op_writesp (uint32 addr, uint8 data);
|
||||
+14
-75
@@ -41,7 +41,7 @@ void sCPU::mmio_w4016(uint8 data) {
|
||||
status.joypad_strobe_latch = !!(data & 1);
|
||||
|
||||
if(status.joypad_strobe_latch == 1) {
|
||||
snes->poll_input();
|
||||
snes.poll_input();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ void sCPU::mmio_w4016(uint8 data) {
|
||||
//realtime or buffered status of joypadN.b
|
||||
uint8 sCPU::mmio_r4016() {
|
||||
uint8 r = regs.mdr & 0xfc;
|
||||
r |= (uint8)snes->port_read(0);
|
||||
r |= (uint8)snes.port_read(0);
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -63,43 +63,14 @@ uint8 r = regs.mdr & 0xfc;
|
||||
//1-0 = Joypad serial data
|
||||
uint8 sCPU::mmio_r4017() {
|
||||
uint8 r = (regs.mdr & 0xe0) | 0x1c;
|
||||
r |= (uint8)snes->port_read(1);
|
||||
r |= (uint8)snes.port_read(1);
|
||||
return r;
|
||||
}
|
||||
|
||||
//NMITIMEN
|
||||
void sCPU::mmio_w4200(uint8 data) {
|
||||
status.nmi_enabled = !!(data & 0x80);
|
||||
status.virq_enabled = !!(data & 0x20);
|
||||
status.hirq_enabled = !!(data & 0x10);
|
||||
status.auto_joypad_poll = !!(data & 0x01);
|
||||
|
||||
if(status.nmi_read == 0) {
|
||||
if(status.nmi_line == 1 && status.nmi_enabled == 1) {
|
||||
status.nmi_transition = 1;
|
||||
}
|
||||
status.nmi_line = !status.nmi_enabled;
|
||||
}
|
||||
|
||||
if(status.irq_read == 0) {
|
||||
if(status.irq_line == 1 && (status.virq_enabled || status.hirq_enabled)) {
|
||||
status.irq_transition = 1;
|
||||
}
|
||||
status.irq_line = !(status.virq_enabled || status.hirq_enabled);
|
||||
}
|
||||
|
||||
if(status.virq_enabled == true && status.hirq_enabled == false) {
|
||||
status.irq_lock = false;
|
||||
}
|
||||
|
||||
if(status.virq_enabled == false && status.hirq_enabled == false) {
|
||||
status.irq_line = 1;
|
||||
status.irq_read = 1;
|
||||
status.irq_transition = 0;
|
||||
}
|
||||
|
||||
update_interrupts();
|
||||
counter_set(counter.irq_delay, 2);
|
||||
nmitimen_update(data);
|
||||
}
|
||||
|
||||
//WRIO
|
||||
@@ -119,7 +90,7 @@ void sCPU::mmio_w4202(uint8 data) {
|
||||
void sCPU::mmio_w4203(uint8 data) {
|
||||
status.mul_b = data;
|
||||
status.r4216 = status.mul_a * status.mul_b;
|
||||
//counter_set(counter.hw_math, 48);
|
||||
//counter.set(counter.hw_math, 48);
|
||||
}
|
||||
|
||||
//WRDIVL
|
||||
@@ -137,51 +108,35 @@ void sCPU::mmio_w4206(uint8 data) {
|
||||
status.div_b = data;
|
||||
status.r4214 = (status.div_b) ? status.div_a / status.div_b : 0xffff;
|
||||
status.r4216 = (status.div_b) ? status.div_a % status.div_b : status.div_a;
|
||||
//counter_set(counter.hw_math, 96);
|
||||
//counter.set(counter.hw_math, 96);
|
||||
}
|
||||
|
||||
//HTIMEL
|
||||
void sCPU::mmio_w4207(uint8 data) {
|
||||
status.hirq_pos = (status.hirq_pos & ~0xff) | (data);
|
||||
status.hirq_pos &= 0x01ff;
|
||||
update_interrupts();
|
||||
|
||||
uint vpos = status.vcounter, hpos = status.hclock;
|
||||
timeshift_backward(10, vpos, hpos);
|
||||
if(hpos < status.hirq_trigger_pos) { status.irq_lock = false; }
|
||||
hvtime_update(0x4207);
|
||||
}
|
||||
|
||||
//HTIMEH
|
||||
void sCPU::mmio_w4208(uint8 data) {
|
||||
status.hirq_pos = (status.hirq_pos & 0xff) | (data << 8);
|
||||
status.hirq_pos &= 0x01ff;
|
||||
update_interrupts();
|
||||
|
||||
uint vpos = status.vcounter, hpos = status.hclock;
|
||||
timeshift_backward(10, vpos, hpos);
|
||||
if(hpos < status.hirq_trigger_pos) { status.irq_lock = false; }
|
||||
hvtime_update(0x4208);
|
||||
}
|
||||
|
||||
//VTIMEL
|
||||
void sCPU::mmio_w4209(uint8 data) {
|
||||
status.virq_pos = (status.virq_pos & ~0xff) | (data);
|
||||
status.virq_pos &= 0x01ff;
|
||||
update_interrupts();
|
||||
|
||||
uint vpos = status.vcounter, hpos = status.hclock;
|
||||
timeshift_backward(10, vpos, hpos);
|
||||
if(hpos < status.hirq_trigger_pos) { status.irq_lock = false; }
|
||||
hvtime_update(0x4209);
|
||||
}
|
||||
|
||||
//VTIMEH
|
||||
void sCPU::mmio_w420a(uint8 data) {
|
||||
status.virq_pos = (status.virq_pos & 0xff) | (data << 8);
|
||||
status.virq_pos &= 0x01ff;
|
||||
update_interrupts();
|
||||
|
||||
uint vpos = status.vcounter, hpos = status.hclock;
|
||||
timeshift_backward(10, vpos, hpos);
|
||||
if(hpos < status.hirq_trigger_pos) { status.irq_lock = false; }
|
||||
hvtime_update(0x420a);
|
||||
}
|
||||
|
||||
//DMAEN
|
||||
@@ -213,12 +168,7 @@ void sCPU::mmio_w420d(uint8 data) {
|
||||
//3-0 = CPU (5a22) version
|
||||
uint8 sCPU::mmio_r4210() {
|
||||
uint8 r = (regs.mdr & 0x70);
|
||||
r |= (uint8)(!status.nmi_read) << 7;
|
||||
|
||||
if(!counter.nmi_fire) {
|
||||
status.nmi_read = 1;
|
||||
}
|
||||
|
||||
r |= (uint8)(rdnmi()) << 7;
|
||||
r |= (cpu_version & 0x0f);
|
||||
return r;
|
||||
}
|
||||
@@ -228,14 +178,7 @@ uint8 r = (regs.mdr & 0x70);
|
||||
//6-0 = MDR
|
||||
uint8 sCPU::mmio_r4211() {
|
||||
uint8 r = (regs.mdr & 0x7f);
|
||||
r |= (uint8)(!status.irq_read) << 7;
|
||||
|
||||
if(!counter.irq_fire) {
|
||||
status.irq_read = 1;
|
||||
status.irq_line = 1;
|
||||
status.irq_transition = 0;
|
||||
}
|
||||
|
||||
r |= (uint8)(timeup()) << 7;
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -479,9 +422,7 @@ void sCPU::mmio_reset() {
|
||||
uint8 sCPU::mmio_read(uint16 addr) {
|
||||
//APU
|
||||
if((addr & 0xffc0) == 0x2140) { //$2140-$217f
|
||||
#ifdef FAVOR_SPEED
|
||||
co_return();
|
||||
#endif
|
||||
scheduler.sync_cpusmp();
|
||||
return r_smp->port_read(addr & 3);
|
||||
}
|
||||
|
||||
@@ -536,9 +477,7 @@ uint8 sCPU::mmio_read(uint16 addr) {
|
||||
void sCPU::mmio_write(uint16 addr, uint8 data) {
|
||||
//APU
|
||||
if((addr & 0xffc0) == 0x2140) { //$2140-$217f
|
||||
#ifdef FAVOR_SPEED
|
||||
co_return();
|
||||
#endif
|
||||
scheduler.sync_cpusmp();
|
||||
port_write(addr & 3, data);
|
||||
return;
|
||||
}
|
||||
|
||||
+3
-23
@@ -6,16 +6,8 @@
|
||||
#include "mmio/mmio.cpp"
|
||||
#include "timing/timing.cpp"
|
||||
|
||||
void scpu_entry_point() {
|
||||
r_cpu->main();
|
||||
}
|
||||
|
||||
void sCPU::run() {
|
||||
co_call(thread);
|
||||
}
|
||||
|
||||
void sCPU::power() {
|
||||
status.region = bool(snes->region());
|
||||
status.region = (bool)snes.region();
|
||||
|
||||
regs.a = regs.x = regs.y = 0x0000;
|
||||
regs.s = 0x01ff;
|
||||
@@ -28,16 +20,10 @@ void sCPU::power() {
|
||||
}
|
||||
|
||||
void sCPU::reset() {
|
||||
if(thread)co_delete(thread);
|
||||
thread = co_create(scpu_entry_point, 65536);
|
||||
|
||||
regs.pc.d = 0x000000;
|
||||
regs.pc.l = r_mem->read(0xfffc);
|
||||
regs.pc.h = r_mem->read(0xfffd);
|
||||
|
||||
regs.acc_8b = true;
|
||||
regs.idx_8b = true;
|
||||
|
||||
//note: some registers are not fully reset by SNES
|
||||
regs.x.h = 0x00;
|
||||
regs.y.h = 0x00;
|
||||
@@ -62,11 +48,5 @@ void sCPU::reset() {
|
||||
apu_port[3] = 0x00;
|
||||
}
|
||||
|
||||
sCPU::sCPU() {
|
||||
//#include "core/optable.cpp"
|
||||
thread = 0;
|
||||
}
|
||||
|
||||
sCPU::~sCPU() {
|
||||
if(thread)co_delete(thread);
|
||||
}
|
||||
sCPU::sCPU() {}
|
||||
sCPU::~sCPU() {}
|
||||
+29
-11
@@ -1,4 +1,7 @@
|
||||
class sCPU : public CPU {
|
||||
public:
|
||||
void enter();
|
||||
|
||||
public:
|
||||
#include "core/core.h"
|
||||
#include "dma/dma.h"
|
||||
@@ -6,8 +9,6 @@ public:
|
||||
#include "mmio/mmio.h"
|
||||
#include "timing/timing.h"
|
||||
|
||||
thread_t thread;
|
||||
|
||||
struct {
|
||||
bool wai;
|
||||
bool irq;
|
||||
@@ -15,11 +16,25 @@ struct {
|
||||
} event;
|
||||
|
||||
struct {
|
||||
bool enabled;
|
||||
uint irq_delay;
|
||||
uint irq_fire;
|
||||
uint nmi_hold;
|
||||
uint irq_hold;
|
||||
|
||||
uint nmi_fire;
|
||||
uint irq_fire;
|
||||
uint irq_delay;
|
||||
uint hw_math;
|
||||
|
||||
alwaysinline void set(uint &ctr, uint clocks) {
|
||||
if(clocks >= ctr) { ctr = clocks; }
|
||||
}
|
||||
|
||||
alwaysinline void sub(uint &ctr, uint clocks) {
|
||||
if(ctr >= clocks) {
|
||||
ctr -= clocks;
|
||||
} else {
|
||||
ctr = 0;
|
||||
}
|
||||
}
|
||||
} counter;
|
||||
|
||||
enum {
|
||||
@@ -35,7 +50,6 @@ struct {
|
||||
bool in_opcode;
|
||||
|
||||
uint clock_count;
|
||||
uint clocks_executed;
|
||||
|
||||
//timing
|
||||
bool region;
|
||||
@@ -44,6 +58,7 @@ struct {
|
||||
bool interlace, interlace_field;
|
||||
bool overscan;
|
||||
uint16 field_lines, line_clocks;
|
||||
uint16 prev_field_lines, prev_line_clocks;
|
||||
uint16 vblstart;
|
||||
|
||||
bool line_rendered;
|
||||
@@ -59,13 +74,17 @@ struct {
|
||||
|
||||
uint16 irq_delay;
|
||||
|
||||
uint16 nmi_trigger_pos;
|
||||
bool nmi_read, nmi_line, nmi_transition;
|
||||
uint16 vnmi_trigger_pos;
|
||||
bool nmi_valid;
|
||||
bool nmi_line;
|
||||
bool nmi_transition;
|
||||
bool nmi_pending;
|
||||
|
||||
uint16 virq_trigger_pos, hirq_trigger_pos;
|
||||
bool irq_read, irq_line, irq_transition;
|
||||
bool irq_lock, irq_pending;
|
||||
bool irq_valid;
|
||||
bool irq_line;
|
||||
bool irq_transition;
|
||||
bool irq_pending;
|
||||
|
||||
//dma
|
||||
uint dma_counter;
|
||||
@@ -114,7 +133,6 @@ struct {
|
||||
uint8 joy4l, joy4h;
|
||||
} status;
|
||||
|
||||
void run();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
|
||||
+17
-63
@@ -1,61 +1,4 @@
|
||||
void sCPU::update_interrupts() {
|
||||
status.nmi_trigger_pos = (status.vcounter == status.vblstart) ? 2 : IRQ_TRIGGER_NEVER;
|
||||
|
||||
if(irq_pos_valid() == true) {
|
||||
status.virq_trigger_pos = status.virq_pos;
|
||||
status.hirq_trigger_pos = (status.hirq_enabled) ? ((status.hirq_pos + 1) * 4) : 0;
|
||||
} else {
|
||||
status.virq_trigger_pos = IRQ_TRIGGER_NEVER;
|
||||
status.hirq_trigger_pos = IRQ_TRIGGER_NEVER;
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::nmi_tick() {
|
||||
counter.nmi_fire -= 2;
|
||||
if(counter.nmi_fire != 0) { return; }
|
||||
|
||||
if(status.nmi_enabled == true && status.nmi_line == 1) {
|
||||
status.nmi_line = 0;
|
||||
status.nmi_transition = 1;
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::irq_tick() {
|
||||
counter.irq_fire -= 2;
|
||||
if(counter.irq_fire != 0) { return; }
|
||||
|
||||
if(status.virq_enabled == true || status.hirq_enabled == true) {
|
||||
status.irq_line = 0;
|
||||
status.irq_transition = 1;
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::poll_interrupts() {
|
||||
if(status.hclock == status.nmi_trigger_pos) {
|
||||
status.nmi_read = 0;
|
||||
counter.nmi_fire = 4;
|
||||
}
|
||||
|
||||
if(status.hclock == 10) { status.irq_lock = false; }
|
||||
|
||||
if(status.hirq_trigger_pos == IRQ_TRIGGER_NEVER)return;
|
||||
if(status.virq_enabled == false && status.hirq_enabled == false)return;
|
||||
if(status.irq_lock == true)return;
|
||||
|
||||
uint vpos = status.vcounter;
|
||||
uint hpos = status.hclock;
|
||||
timeshift_backward(10, vpos, hpos);
|
||||
|
||||
bool trigger_irq = true;
|
||||
if(status.virq_enabled == true && vpos != status.virq_trigger_pos)trigger_irq = false;
|
||||
if(status.hirq_enabled == true && hpos != status.hirq_trigger_pos)trigger_irq = false;
|
||||
|
||||
if(trigger_irq == true) {
|
||||
status.irq_lock = true;
|
||||
status.irq_read = 0;
|
||||
counter.irq_fire = 4;
|
||||
}
|
||||
}
|
||||
#include "irqtiming.cpp"
|
||||
|
||||
bool sCPU::irq_pos_valid() {
|
||||
uint vpos = status.virq_pos;
|
||||
@@ -74,19 +17,29 @@ uint vlimit = region_scanlines() >> 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
alwaysinline bool sCPU::nmi_test() {
|
||||
if(status.nmi_transition == 0)return false;
|
||||
alwaysinline
|
||||
bool sCPU::nmi_test() {
|
||||
if(status.nmi_transition == false) { return false; }
|
||||
status.nmi_transition = false;
|
||||
|
||||
status.nmi_transition = 0;
|
||||
event.wai = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
alwaysinline bool sCPU::irq_test() {
|
||||
alwaysinline
|
||||
bool sCPU::irq_test() {
|
||||
if(status.irq_transition == false) { return false; }
|
||||
status.irq_transition = false;
|
||||
|
||||
event.wai = false;
|
||||
return (regs.p.i) ? false : true;
|
||||
}
|
||||
|
||||
/*
|
||||
if(status.irq_transition == 1)goto irq_trigger;
|
||||
|
||||
if(status.irq_read == 0) {
|
||||
if(status.irq_line == 1 && counter.irq_fire) {
|
||||
if(status.irq_line == 1 && irq_edge()) {
|
||||
return false;
|
||||
}
|
||||
goto irq_trigger;
|
||||
@@ -104,3 +57,4 @@ irq_trigger:
|
||||
event.wai = false;
|
||||
return (regs.p.i) ? false : true;
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,105 @@
|
||||
void sCPU::update_interrupts() {
|
||||
status.vnmi_trigger_pos = status.vblstart;
|
||||
|
||||
if(irq_pos_valid() == true) {
|
||||
status.virq_trigger_pos = status.virq_pos;
|
||||
status.hirq_trigger_pos = 4 * ((status.hirq_enabled) ? (status.hirq_pos + 1) : 0);
|
||||
} else {
|
||||
status.virq_trigger_pos = IRQ_TRIGGER_NEVER;
|
||||
status.hirq_trigger_pos = IRQ_TRIGGER_NEVER;
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline
|
||||
void sCPU::poll_interrupts() {
|
||||
uint vpos = status.vcounter, hpos = status.hclock;
|
||||
|
||||
//NMI test
|
||||
timeshift_backward(2, vpos, hpos);
|
||||
bool nmi_valid = (vpos >= status.vnmi_trigger_pos);
|
||||
if(status.nmi_valid == false && nmi_valid == true) {
|
||||
//0->1 edge sensitive transition
|
||||
status.nmi_line = true;
|
||||
counter.nmi_hold = 6;
|
||||
} else if(status.nmi_valid == true && nmi_valid == false) {
|
||||
//1->0 edge sensitive transition
|
||||
status.nmi_line = false;
|
||||
}
|
||||
status.nmi_valid = nmi_valid;
|
||||
|
||||
//NMI hold
|
||||
if(counter.nmi_hold) {
|
||||
counter.nmi_hold -= 2;
|
||||
if(counter.nmi_hold == 0) {
|
||||
if(status.nmi_enabled == true) { status.nmi_transition = true; }
|
||||
}
|
||||
}
|
||||
|
||||
//IRQ test
|
||||
timeshift_backward(8, vpos, hpos);
|
||||
bool irq_valid = (status.virq_enabled == true || status.hirq_enabled == true);
|
||||
if(irq_valid == true) {
|
||||
if(status.virq_enabled == true && vpos != status.virq_trigger_pos) { irq_valid = false; }
|
||||
if(status.hirq_enabled == true && hpos != status.hirq_trigger_pos) { irq_valid = false; }
|
||||
}
|
||||
if(status.irq_valid == false && irq_valid == true) {
|
||||
//0->1 edge sensitive transition
|
||||
status.irq_line = true;
|
||||
counter.irq_hold = 6;
|
||||
}
|
||||
status.irq_valid = irq_valid;
|
||||
|
||||
//IRQ hold
|
||||
if(counter.irq_hold) { counter.irq_hold -= 2; }
|
||||
if(status.irq_line == true && counter.irq_hold == 0) {
|
||||
if(status.virq_enabled == true || status.hirq_enabled == true) { status.irq_transition = true; }
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::nmitimen_update(uint8 data) {
|
||||
bool nmi_enabled = status.nmi_enabled;
|
||||
bool virq_enabled = status.virq_enabled;
|
||||
bool hirq_enabled = status.hirq_enabled;
|
||||
status.nmi_enabled = !!(data & 0x80);
|
||||
status.virq_enabled = !!(data & 0x20);
|
||||
status.hirq_enabled = !!(data & 0x10);
|
||||
|
||||
//0->1 edge sensitive transition
|
||||
if(nmi_enabled == false && status.nmi_enabled == true && status.nmi_line == true) {
|
||||
status.nmi_transition = true;
|
||||
}
|
||||
|
||||
//?->1 level sensitive transition
|
||||
if(status.virq_enabled == true && status.hirq_enabled == false && status.irq_line == true) {
|
||||
status.irq_transition = true;
|
||||
}
|
||||
|
||||
if(status.virq_enabled == false && status.hirq_enabled == false) {
|
||||
status.irq_line = false;
|
||||
status.irq_transition = false;
|
||||
}
|
||||
|
||||
update_interrupts();
|
||||
counter.set(counter.irq_delay, 2);
|
||||
}
|
||||
|
||||
void sCPU::hvtime_update(uint16 addr) {
|
||||
update_interrupts();
|
||||
}
|
||||
|
||||
bool sCPU::rdnmi() {
|
||||
bool result = status.nmi_line;
|
||||
if(counter.nmi_hold == 0) {
|
||||
status.nmi_line = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
bool sCPU::timeup() {
|
||||
bool result = status.irq_line;
|
||||
if(counter.irq_hold == 0) {
|
||||
status.irq_line = false;
|
||||
status.irq_transition = false;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
void sCPU::run_auto_joypad_poll() {
|
||||
uint16 joy1 = 0, joy2 = 0;
|
||||
for(int i = 0; i < 16; i++) {
|
||||
joy1 |= (uint16)snes->port_read(0) ? (0x8000 >> i) : 0;
|
||||
joy2 |= (uint16)snes->port_read(1) ? (0x8000 >> i) : 0;
|
||||
joy1 |= (uint16)snes.port_read(0) ? (0x8000 >> i) : 0;
|
||||
joy2 |= (uint16)snes.port_read(1) ? (0x8000 >> i) : 0;
|
||||
}
|
||||
|
||||
status.joy1l = joy1;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
alwaysinline void sCPU::timeshift_forward(uint clocks, uint &vtime, uint &htime) {
|
||||
htime += clocks;
|
||||
|
||||
if(htime >= status.line_clocks) {
|
||||
htime -= status.line_clocks;
|
||||
if(++vtime >= status.field_lines) {
|
||||
@@ -13,14 +12,11 @@ alwaysinline void sCPU::timeshift_backward(uint clocks, uint &vtime, uint &htime
|
||||
if(htime >= clocks) {
|
||||
htime -= clocks;
|
||||
} else {
|
||||
htime += 1364 - clocks;
|
||||
if(status.region == SNES::NTSC && status.vcounter == 241 &&
|
||||
status.interlace == false && status.interlace_field == 1)htime -= 4;
|
||||
htime += status.prev_line_clocks - clocks;
|
||||
if(vtime > 0) {
|
||||
vtime--;
|
||||
} else {
|
||||
vtime = status.region_scanlines;
|
||||
if(status.interlace == true && status.interlace_field == 1)vtime++;
|
||||
vtime = status.prev_field_lines - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -45,35 +45,22 @@ uint16 sCPU::hcounter() {
|
||||
}
|
||||
|
||||
void sCPU::add_clocks(uint clocks) {
|
||||
status.clocks_executed += clocks;
|
||||
|
||||
if(counter.irq_delay) {
|
||||
counter.irq_delay = (counter.irq_delay > clocks) ? (counter.irq_delay - clocks) : 0;
|
||||
if(status.dram_refreshed == false) {
|
||||
if(status.hclock + clocks >= status.dram_refresh_position) {
|
||||
status.dram_refreshed = true;
|
||||
clocks += 40;
|
||||
}
|
||||
}
|
||||
|
||||
if(status.hclock + clocks >= status.line_clocks) {
|
||||
clocks = (status.hclock + clocks) - status.line_clocks;
|
||||
while(status.hclock < status.line_clocks - 2) { tick(); }
|
||||
scanline();
|
||||
}
|
||||
counter.sub(counter.irq_delay, clocks);
|
||||
scheduler.addclocks_cpu(clocks);
|
||||
|
||||
clocks >>= 1;
|
||||
while(clocks--) { tick(); }
|
||||
}
|
||||
|
||||
alwaysinline void sCPU::tick() {
|
||||
status.hclock += 2;
|
||||
|
||||
if(counter.nmi_fire) { nmi_tick(); }
|
||||
if(counter.irq_fire) { irq_tick(); }
|
||||
|
||||
if(status.dram_refreshed == false && status.hclock >= status.dram_refresh_position) {
|
||||
status.dram_refreshed = true;
|
||||
add_clocks(40);
|
||||
return;
|
||||
while(clocks--) {
|
||||
status.hclock += 2;
|
||||
if(status.hclock >= status.line_clocks) { scanline(); }
|
||||
poll_interrupts();
|
||||
}
|
||||
|
||||
poll_interrupts();
|
||||
}
|
||||
|
||||
void sCPU::scanline() {
|
||||
@@ -84,6 +71,7 @@ void sCPU::scanline() {
|
||||
frame();
|
||||
}
|
||||
|
||||
status.prev_line_clocks = status.line_clocks;
|
||||
status.line_clocks = (ntsc_color_burst_phase_shift_scanline() == false) ? 1364 : 1360;
|
||||
|
||||
//dram refresh occurs once every scanline
|
||||
@@ -103,23 +91,20 @@ void sCPU::scanline() {
|
||||
status.hdma_triggered = (status.vcounter <= (!overscan() ? 224 : 239)) ? false : true;
|
||||
|
||||
r_ppu->scanline();
|
||||
snes->scanline();
|
||||
snes.scanline();
|
||||
|
||||
update_interrupts();
|
||||
|
||||
if(status.auto_joypad_poll == true && status.vcounter == (!overscan() ? 227 : 242)) {
|
||||
snes->poll_input();
|
||||
snes.poll_input();
|
||||
run_auto_joypad_poll();
|
||||
}
|
||||
}
|
||||
|
||||
void sCPU::frame() {
|
||||
status.nmi_read = 1;
|
||||
status.nmi_line = 1;
|
||||
status.nmi_transition = 0;
|
||||
|
||||
status.vcounter = 0;
|
||||
status.interlace_field ^= 1;
|
||||
status.prev_field_lines = status.field_lines;
|
||||
status.field_lines = (status.region_scanlines >> 1);
|
||||
//interlaced even fields have one extra scanline
|
||||
//(263+262=525 NTSC, 313+312=625 PAL)
|
||||
@@ -133,7 +118,7 @@ void sCPU::frame() {
|
||||
}
|
||||
|
||||
r_ppu->frame();
|
||||
snes->frame();
|
||||
snes.frame();
|
||||
}
|
||||
|
||||
/*****
|
||||
@@ -185,15 +170,16 @@ void sCPU::cycle_edge() {
|
||||
if(status.hdmainit_triggered == false) {
|
||||
if(status.hclock >= status.hdmainit_trigger_position || status.vcounter) {
|
||||
status.hdmainit_triggered = true;
|
||||
|
||||
hdma_init_reset();
|
||||
if(hdma_enabled_channels()) {
|
||||
if(status.dma_state == DMASTATE_INACTIVE) {
|
||||
status.dma_state = DMASTATE_DMASYNC;
|
||||
status.hdmainit_pending = true;
|
||||
} else {
|
||||
hdma_init();
|
||||
}
|
||||
add_clocks(12);
|
||||
hdma_init();
|
||||
//if(status.dma_state == DMASTATE_INACTIVE) {
|
||||
// status.dma_state = DMASTATE_DMASYNC;
|
||||
// status.hdmainit_pending = true;
|
||||
//} else {
|
||||
// hdma_init();
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,12 +188,14 @@ void sCPU::cycle_edge() {
|
||||
if(status.hclock >= 1106) {
|
||||
status.hdma_triggered = true;
|
||||
if(hdma_active_channels()) {
|
||||
if(status.dma_state == DMASTATE_INACTIVE) {
|
||||
status.dma_state = DMASTATE_DMASYNC;
|
||||
status.hdma_pending = true;
|
||||
} else {
|
||||
hdma_run();
|
||||
}
|
||||
add_clocks(12);
|
||||
hdma_run();
|
||||
//if(status.dma_state == DMASTATE_INACTIVE) {
|
||||
// status.dma_state = DMASTATE_DMASYNC;
|
||||
// status.hdma_pending = true;
|
||||
//} else {
|
||||
// hdma_run();
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -231,30 +219,19 @@ void sCPU::last_cycle() {
|
||||
event.irq = (status.nmi_pending || status.irq_pending);
|
||||
}
|
||||
|
||||
/*****
|
||||
* clocks_executed()
|
||||
*
|
||||
* Return number of clocks executed since last call to this function.
|
||||
* Used by class SNES to control CPU<>APU synchronization.
|
||||
*****/
|
||||
uint32 sCPU::clocks_executed() {
|
||||
uint32 r = status.clocks_executed;
|
||||
status.clocks_executed = 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
void sCPU::timing_power() {
|
||||
}
|
||||
|
||||
void sCPU::timing_reset() {
|
||||
counter.enabled = false;
|
||||
counter.nmi_hold = 0;
|
||||
counter.irq_hold = 0;
|
||||
|
||||
counter.nmi_fire = 0;
|
||||
counter.irq_fire = 0;
|
||||
counter.irq_delay = 0;
|
||||
counter.hw_math = 0;
|
||||
counter.irq_fire = 0;
|
||||
counter.nmi_fire = 0;
|
||||
|
||||
status.clock_count = 0;
|
||||
status.clocks_executed = 0;
|
||||
status.clock_count = 0;
|
||||
|
||||
status.vcounter = 0;
|
||||
status.hcounter = 0;
|
||||
@@ -269,8 +246,11 @@ void sCPU::timing_reset() {
|
||||
status.field_lines = status.region_scanlines >> 1;
|
||||
status.line_clocks = 1364;
|
||||
|
||||
status.prev_field_lines = status.region_scanlines >> 1;
|
||||
status.prev_line_clocks = 1364;
|
||||
|
||||
status.line_rendered = false;
|
||||
status.line_render_position = minmax<0, 1112>((uint16)config::ppu.render_scanline_position);
|
||||
status.line_render_position = minmax<0, 1112>((uint16)config::ppu.hack.render_scanline_position);
|
||||
|
||||
status.dram_refreshed = false;
|
||||
status.dram_refresh_position = (cpu_version == 1) ? 530 : 538;
|
||||
@@ -282,15 +262,14 @@ void sCPU::timing_reset() {
|
||||
|
||||
status.irq_delay = 0;
|
||||
|
||||
status.nmi_read = 1;
|
||||
status.nmi_line = 1;
|
||||
status.nmi_transition = 0;
|
||||
status.nmi_valid = false;
|
||||
status.nmi_line = false;
|
||||
status.nmi_transition = false;
|
||||
status.nmi_pending = false;
|
||||
|
||||
status.irq_read = 1;
|
||||
status.irq_line = 1;
|
||||
status.irq_transition = 0;
|
||||
status.irq_lock = false;
|
||||
status.irq_valid = false;
|
||||
status.irq_line = false;
|
||||
status.irq_transition = false;
|
||||
status.irq_pending = false;
|
||||
|
||||
update_interrupts();
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
uint dma_counter();
|
||||
|
||||
void add_clocks(uint clocks);
|
||||
void tick();
|
||||
void scanline();
|
||||
void frame();
|
||||
|
||||
@@ -25,10 +24,6 @@
|
||||
void timing_power();
|
||||
void timing_reset();
|
||||
|
||||
void counter_set(uint &ctr, uint clocks) {
|
||||
if(clocks >= ctr) { ctr = clocks; }
|
||||
}
|
||||
|
||||
//timeshift.cpp
|
||||
void timeshift_forward (uint clocks, uint &v, uint &h);
|
||||
void timeshift_backward(uint clocks, uint &v, uint &h);
|
||||
@@ -36,9 +31,12 @@
|
||||
//irq.cpp
|
||||
enum { IRQ_TRIGGER_NEVER = 0x3fff };
|
||||
void update_interrupts();
|
||||
void nmi_tick();
|
||||
void irq_tick();
|
||||
void poll_interrupts();
|
||||
void nmitimen_update(uint8 data);
|
||||
void hvtime_update(uint16 addr);
|
||||
bool rdnmi();
|
||||
bool timeup();
|
||||
|
||||
bool irq_pos_valid();
|
||||
bool nmi_test();
|
||||
bool irq_test();
|
||||
|
||||
@@ -558,7 +558,7 @@ int32 fir_samplel, fir_sampler;
|
||||
msampler = sclamp<16>(msampler);
|
||||
}
|
||||
|
||||
return uint32( uint16(msamplel) | (uint16(msampler) << 16) );
|
||||
return (uint32)( (uint16)msamplel | ((uint16)msampler << 16) );
|
||||
}
|
||||
|
||||
bDSP::bDSP() {}
|
||||
|
||||
@@ -20,11 +20,9 @@
|
||||
|
||||
#include "cpu/cpu.h"
|
||||
#include "cpu/scpu/scpu.h"
|
||||
//#include "cpu/bcpu/bcpu.h"
|
||||
|
||||
#include "smp/smp.h"
|
||||
#include "smp/ssmp/ssmp.h"
|
||||
//#include "smp/bsmp/bsmp.h"
|
||||
|
||||
#include "dsp/dsp.h"
|
||||
#include "dsp/bdsp/bdsp.h"
|
||||
|
||||
+132
-4
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
libbase : version 0.08c ~byuu (09/28/06)
|
||||
libbase : version 0.08f ~byuu (2006-11-07)
|
||||
*/
|
||||
|
||||
#ifndef __LIBBASE
|
||||
@@ -9,6 +9,7 @@
|
||||
//disable libc deprecation warnings in MSVC 2k5+
|
||||
#pragma warning(disable:4996)
|
||||
|
||||
#define NOMINMAX
|
||||
#define ftruncate _chsize
|
||||
#define vsnprintf _vsnprintf
|
||||
#endif
|
||||
@@ -28,7 +29,10 @@
|
||||
#define alwaysinline inline
|
||||
#define fastcall __attribute__((fastcall))
|
||||
#else
|
||||
#error "unsupported compiler"
|
||||
#define noinline
|
||||
#define inline inline
|
||||
#define alwaysinline inline
|
||||
#define fastcall
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
@@ -47,6 +51,7 @@
|
||||
#define TRUE !FALSE
|
||||
#endif
|
||||
|
||||
//deprecated
|
||||
#define SafeFree(__n) if(__n) { free(__n); __n = 0; }
|
||||
#define SafeDelete(__n) if(__n) { delete(__n); __n = 0; }
|
||||
#define SafeRelease(__n) if(__n) { __n->Release(); __n = 0; }
|
||||
@@ -78,14 +83,45 @@ typedef signed long long int64;
|
||||
* templates
|
||||
*****/
|
||||
|
||||
template<typename T> inline void safe_free(T &handle) {
|
||||
if(handle) {
|
||||
free(handle);
|
||||
handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> inline void safe_delete(T &handle) {
|
||||
if(handle) {
|
||||
delete handle;
|
||||
handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> inline void safe_release(T &handle) {
|
||||
if(handle) {
|
||||
handle->Release();
|
||||
handle = 0;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> inline void swap(T &x, T &y) {
|
||||
T z = x;
|
||||
x = y;
|
||||
y = z;
|
||||
}
|
||||
|
||||
#ifdef min
|
||||
#undef min
|
||||
#endif
|
||||
#define min(x, y) ((x < y) ? x : y)
|
||||
|
||||
#ifdef max
|
||||
#undef max
|
||||
#endif
|
||||
#define max(x, y) ((x > y) ? x : y)
|
||||
|
||||
template<int min, int max, typename T> inline T minmax(const T x) {
|
||||
return (x < T(min)) ? T(min) : (x > T(max)) ? T(max) : x;
|
||||
return (x < (T)min) ? (T)min : (x > (T)max) ? (T)max : x;
|
||||
}
|
||||
|
||||
template<int bits> inline unsigned uclamp(const unsigned x) {
|
||||
@@ -243,6 +279,90 @@ typedef int_t<48, int64> int48;
|
||||
* libc extensions
|
||||
*****/
|
||||
|
||||
static uint8 fgetb(FILE *fp) { return fgetc(fp); }
|
||||
static uint8 fgetlb(FILE *fp) { return fgetc(fp); }
|
||||
static uint8 fgetmb(FILE *fp) { return fgetc(fp); }
|
||||
|
||||
static uint16 fgetlw(FILE *fp) {
|
||||
return (fgetc(fp)) | (fgetc(fp) << 8);
|
||||
}
|
||||
|
||||
static uint16 fgetmw(FILE *fp) {
|
||||
return (fgetc(fp) << 8) | (fgetc(fp) << 8);
|
||||
}
|
||||
|
||||
static uint32 fgetld(FILE *fp) {
|
||||
return (fgetc(fp)) | (fgetc(fp) << 8) | (fgetc(fp) << 16) | (fgetc(fp) << 24);
|
||||
}
|
||||
|
||||
static uint32 fgetmd(FILE *fp) {
|
||||
return (fgetc(fp) << 24) | (fgetc(fp) << 16) | (fgetc(fp) << 8) | (fgetc(fp));
|
||||
}
|
||||
|
||||
static uint64 fgetlq(FILE *fp) {
|
||||
return ((uint64)fgetc(fp) << 0) | ((uint64)fgetc(fp) << 8) |
|
||||
((uint64)fgetc(fp) << 16) | ((uint64)fgetc(fp) << 24) |
|
||||
((uint64)fgetc(fp) << 32) | ((uint64)fgetc(fp) << 40) |
|
||||
((uint64)fgetc(fp) << 48) | ((uint64)fgetc(fp) << 56);
|
||||
}
|
||||
|
||||
static uint64 fgetmq(FILE *fp) {
|
||||
return ((uint64)fgetc(fp) << 56) | ((uint64)fgetc(fp) << 48) |
|
||||
((uint64)fgetc(fp) << 40) | ((uint64)fgetc(fp) << 32) |
|
||||
((uint64)fgetc(fp) << 24) | ((uint64)fgetc(fp) << 16) |
|
||||
((uint64)fgetc(fp) << 8) | ((uint64)fgetc(fp) << 0);
|
||||
}
|
||||
|
||||
static void fputb(FILE *fp, uint8 data) { fputc(data, fp); }
|
||||
static void fputlb(FILE *fp, uint8 data) { fputc(data, fp); }
|
||||
static void fputmb(FILE *fp, uint8 data) { fputc(data, fp); }
|
||||
|
||||
static void fputlw(FILE *fp, uint16 data) {
|
||||
fputc(data >> 0, fp);
|
||||
fputc(data >> 8, fp);
|
||||
}
|
||||
|
||||
static void fputmw(FILE *fp, uint16 data) {
|
||||
fputc(data >> 8, fp);
|
||||
fputc(data >> 0, fp);
|
||||
}
|
||||
|
||||
static void fputld(FILE *fp, uint32 data) {
|
||||
fputc(data >> 0, fp);
|
||||
fputc(data >> 8, fp);
|
||||
fputc(data >> 16, fp);
|
||||
fputc(data >> 24, fp);
|
||||
}
|
||||
|
||||
static void fputmd(FILE *fp, uint32 data) {
|
||||
fputc(data >> 24, fp);
|
||||
fputc(data >> 16, fp);
|
||||
fputc(data >> 8, fp);
|
||||
fputc(data >> 0, fp);
|
||||
}
|
||||
|
||||
static void fputlq(FILE *fp, uint64 data) {
|
||||
fputc(data >> 0, fp);
|
||||
fputc(data >> 8, fp);
|
||||
fputc(data >> 16, fp);
|
||||
fputc(data >> 24, fp);
|
||||
fputc(data >> 32, fp);
|
||||
fputc(data >> 40, fp);
|
||||
fputc(data >> 48, fp);
|
||||
fputc(data >> 56, fp);
|
||||
}
|
||||
|
||||
static void fputmq(FILE *fp, uint64 data) {
|
||||
fputc(data >> 56, fp);
|
||||
fputc(data >> 48, fp);
|
||||
fputc(data >> 40, fp);
|
||||
fputc(data >> 32, fp);
|
||||
fputc(data >> 24, fp);
|
||||
fputc(data >> 16, fp);
|
||||
fputc(data >> 8, fp);
|
||||
fputc(data >> 0, fp);
|
||||
}
|
||||
|
||||
static bool fexists(const char *fn) {
|
||||
FILE *fp = fopen(fn, "rb");
|
||||
if(!fp)return false;
|
||||
@@ -270,7 +390,7 @@ uint32 size = ftell(fp);
|
||||
return size;
|
||||
}
|
||||
|
||||
inline int ftruncate(FILE *fp, long size) { return ftruncate(fileno(fp), size); }
|
||||
static int ftruncate(FILE *fp, long size) { return ftruncate(fileno(fp), size); }
|
||||
|
||||
/*****
|
||||
* crc32 calculation
|
||||
@@ -327,4 +447,12 @@ inline uint32 crc32_adjust(uint32 crc32, uint8 input) {
|
||||
return ((crc32 >> 8) & 0x00ffffff) ^ crc32_table[(crc32 ^ input) & 0xff];
|
||||
}
|
||||
|
||||
inline uint32 crc32_calculate(uint8 *data, uint length) {
|
||||
uint32 crc32 = ~0;
|
||||
for(uint i = 0; i < length; i++) {
|
||||
crc32 = crc32_adjust(crc32, data[i]);
|
||||
}
|
||||
return ~crc32;
|
||||
}
|
||||
|
||||
#endif
|
||||
+42
-40
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
libco_win32 : version 0.06 ~byuu (05/21/06)
|
||||
libco_win32 : version 0.08 ~byuu (10/21/06)
|
||||
win32-x86 implementation of libco
|
||||
*/
|
||||
|
||||
@@ -9,60 +9,62 @@
|
||||
|
||||
#include "libco_win32.h"
|
||||
|
||||
namespace libco_win32 {
|
||||
bool co_enabled = false;
|
||||
int co_stackptr = 0;
|
||||
thread_t co_stack[4096];
|
||||
|
||||
void __stdcall coentry_proc(void *coentry) {
|
||||
thread_p main = (thread_p)coentry;
|
||||
main();
|
||||
}
|
||||
struct cothread_struct {
|
||||
void *cohandle;
|
||||
cothread_p coentry;
|
||||
cothread_t colink;
|
||||
};
|
||||
|
||||
void co_init() {
|
||||
if(libco_win32::co_enabled == true)return;
|
||||
libco_win32::co_enabled = true;
|
||||
cothread_t __co_active = 0, __co_primary = 0;
|
||||
|
||||
void __stdcall co_entryproc(void *coentry) {
|
||||
cothread_struct *s = static_cast<cothread_struct*>(coentry);
|
||||
s->coentry();
|
||||
co_exit(0);
|
||||
}
|
||||
|
||||
cothread_t co_init() {
|
||||
ConvertThreadToFiber(0);
|
||||
cothread_struct *s = static_cast<cothread_struct*>(malloc(sizeof(cothread_struct)));
|
||||
s->colink = 0;
|
||||
s->coentry = 0;
|
||||
s->cohandle = GetCurrentFiber();
|
||||
__co_active = __co_primary = static_cast<cothread_t>(s);
|
||||
return __co_active;
|
||||
}
|
||||
|
||||
void co_term() {
|
||||
/*****
|
||||
//ConverFiberToThread() only exists on WinXP+
|
||||
|
||||
if(libco_win32::co_enabled == false)return;
|
||||
libco_win32::co_enabled = false;
|
||||
|
||||
ConvertFiberToThread();
|
||||
*****/
|
||||
//primary fiber cannot be deleted; free memory used by handle to fiber only
|
||||
free(__co_primary);
|
||||
//ConvertFiberToThread(); //only exists on WinXP+
|
||||
}
|
||||
|
||||
thread_t co_active() {
|
||||
if(libco_win32::co_enabled == false)co_init();
|
||||
|
||||
return GetCurrentFiber();
|
||||
cothread_t co_active() {
|
||||
return __co_active;
|
||||
}
|
||||
|
||||
thread_t co_create(thread_p coentry, unsigned int heapsize) {
|
||||
if(libco_win32::co_enabled == false)co_init();
|
||||
|
||||
return CreateFiber(heapsize, libco_win32::coentry_proc, (void*)coentry);
|
||||
cothread_t co_create(cothread_p coentry, unsigned int heapsize) {
|
||||
cothread_struct *s = static_cast<cothread_struct*>(malloc(sizeof(cothread_struct)));
|
||||
s->colink = co_active();
|
||||
s->coentry = coentry;
|
||||
s->cohandle = CreateFiber(heapsize + 512, co_entryproc, static_cast<void*>(s));
|
||||
return static_cast<cothread_t>(s);
|
||||
}
|
||||
|
||||
void co_delete(thread_t cothread) {
|
||||
DeleteFiber(cothread);
|
||||
void co_delete(cothread_t cothread) {
|
||||
cothread_struct *s = static_cast<cothread_struct*>(cothread);
|
||||
DeleteFiber(s->cohandle);
|
||||
free(cothread);
|
||||
}
|
||||
|
||||
void co_jump(thread_t cothread) {
|
||||
SwitchToFiber(cothread);
|
||||
void co_switch(cothread_t cothread) {
|
||||
__co_active = cothread;
|
||||
cothread_struct *s = static_cast<cothread_struct*>(cothread);
|
||||
SwitchToFiber(s->cohandle);
|
||||
}
|
||||
|
||||
void co_call(thread_t cothread) {
|
||||
libco_win32::co_stack[libco_win32::co_stackptr++] = co_active();
|
||||
co_jump(cothread);
|
||||
}
|
||||
|
||||
void co_return() {
|
||||
co_jump(libco_win32::co_stack[--libco_win32::co_stackptr]);
|
||||
void co_exit(cothread_t cothread) {
|
||||
if(cothread != 0) { co_switch(cothread); }
|
||||
cothread_struct *s = static_cast<cothread_struct*>(__co_active);
|
||||
co_switch(s->colink);
|
||||
}
|
||||
+16
-11
@@ -1,15 +1,20 @@
|
||||
/*
|
||||
libco_win32 : version 0.06 ~byuu (05/21/2006)
|
||||
libco_win32 : version 0.08 ~byuu (10/21/2006)
|
||||
*/
|
||||
|
||||
typedef void (*thread_t);
|
||||
typedef void (*thread_p)();
|
||||
#define COTHREAD_STACKSIZE_TINY 0x1000
|
||||
#define COTHREAD_STACKSIZE_SMALL 0x4000
|
||||
#define COTHREAD_STACKSIZE_NORMAL 0x10000
|
||||
#define COTHREAD_STACKSIZE_LARGE 0x40000
|
||||
#define COTHREAD_STACKSIZE_HUGE 0x100000
|
||||
|
||||
void co_init();
|
||||
void co_term();
|
||||
thread_t co_active();
|
||||
thread_t co_create(thread_p coentry, unsigned int heapsize);
|
||||
void co_delete(thread_t cothread);
|
||||
void co_jump(thread_t cothread);
|
||||
void co_call(thread_t cothread);
|
||||
void co_return();
|
||||
typedef void (*cothread_t);
|
||||
typedef void (*cothread_p)(void);
|
||||
|
||||
cothread_t co_init();
|
||||
void co_term();
|
||||
cothread_t co_active();
|
||||
cothread_t co_create(cothread_p coentry, unsigned int heapsize);
|
||||
void co_delete(cothread_t cothread);
|
||||
void co_switch(cothread_t cothread);
|
||||
void co_exit(cothread_t cothread);
|
||||
+54
-78
@@ -1,9 +1,9 @@
|
||||
;*****
|
||||
;libco_x86 : version 0.07 ~byuu (08/15/06)
|
||||
;libco_x86 : version 0.08 ~byuu (10/21/06)
|
||||
;cross-platform x86 implementation of libco
|
||||
;
|
||||
;context save/restore adheres to c/c++ ABI
|
||||
;for x86 windows, linux and freebsd
|
||||
;for x86 windows, osx, linux and freebsd
|
||||
;
|
||||
;context saves esp+ebp+esi+edi+ebx
|
||||
;context ignores eax+ecx+edx
|
||||
@@ -14,8 +14,8 @@
|
||||
section .data
|
||||
|
||||
align 4
|
||||
co_initialized dd 0
|
||||
co_active_context dd 0
|
||||
co_primary_context dd 0
|
||||
|
||||
section .code
|
||||
|
||||
@@ -31,9 +31,21 @@ section .code
|
||||
%define co_active @co_active@0
|
||||
%define co_create @co_create@8
|
||||
%define co_delete @co_delete@4
|
||||
%define co_jump @co_jump@4
|
||||
%define co_call @co_call@4
|
||||
%define co_return @co_return@0
|
||||
%define co_switch @co_switch@4
|
||||
%define co_exit @co_exit@4
|
||||
%endif
|
||||
|
||||
%ifdef OSX86
|
||||
%define malloc _malloc
|
||||
%define free _free
|
||||
|
||||
%define co_init _co_init
|
||||
%define co_term _co_term
|
||||
%define co_active _co_active
|
||||
%define co_create _co_create
|
||||
%define co_delete _co_delete
|
||||
%define co_switch _co_switch
|
||||
%define co_exit _co_exit
|
||||
%endif
|
||||
|
||||
extern malloc
|
||||
@@ -44,26 +56,22 @@ global co_term
|
||||
global co_active
|
||||
global co_create
|
||||
global co_delete
|
||||
global co_jump
|
||||
global co_call
|
||||
global co_return
|
||||
global co_switch
|
||||
global co_exit
|
||||
|
||||
;*****
|
||||
;extern "C" void fastcall co_init();
|
||||
;extern "C" cothread_t fastcall co_init();
|
||||
;return = eax
|
||||
;*****
|
||||
|
||||
align 16
|
||||
co_init:
|
||||
cmp dword[co_initialized],0 ;only run co_init once
|
||||
jne .end
|
||||
inc dword[co_initialized]
|
||||
|
||||
;create context for main thread
|
||||
;create context for main cothread
|
||||
mov ecx,0 ;entry point for main thread is not needed
|
||||
mov edx,256 ;main thread uses default program stack
|
||||
mov edx,512 ;main cothread uses default program stack
|
||||
call co_create
|
||||
mov dword[co_active_context],eax
|
||||
.end
|
||||
mov dword[co_primary_context],eax
|
||||
ret
|
||||
|
||||
;*****
|
||||
@@ -72,24 +80,22 @@ co_init:
|
||||
|
||||
align 16
|
||||
co_term:
|
||||
mov ecx,dword[co_primary_context]
|
||||
call co_delete
|
||||
ret
|
||||
|
||||
;*****
|
||||
;extern "C" thread_t fastcall co_active();
|
||||
;extern "C" cothread_t fastcall co_active();
|
||||
;return = eax
|
||||
;*****
|
||||
|
||||
align 16
|
||||
co_active:
|
||||
cmp dword[co_initialized],0 ;make sure co_init has been called
|
||||
jne .next
|
||||
call co_init
|
||||
.next:
|
||||
mov eax,dword[co_active_context]
|
||||
ret
|
||||
|
||||
;*****
|
||||
;extern "C" thread_t fastcall co_create(thread_p coentry, unsigned int heapsize);
|
||||
;extern "C" cothread_t fastcall co_create(cothread_p coentry, unsigned int heapsize);
|
||||
;ecx = coentry
|
||||
;edx = heapsize
|
||||
;return = eax
|
||||
@@ -97,17 +103,8 @@ co_active:
|
||||
|
||||
align 16
|
||||
co_create:
|
||||
cmp dword[co_initialized],0 ;make sure co_init has been called
|
||||
jne .next
|
||||
push ecx
|
||||
push edx
|
||||
call co_init
|
||||
pop edx
|
||||
pop ecx
|
||||
.next:
|
||||
|
||||
;create heap space (stack + register storage)
|
||||
add edx,28 ;+8(esp+prev_call_context)+4(coentry)+16(stack_align)
|
||||
add edx,512 ;+4(esp)+4(coentry)+4(colink)+256(stack_align)
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
@@ -119,10 +116,10 @@ co_create:
|
||||
pop ecx
|
||||
|
||||
add edx,eax ;set edx to point to top of stack heap
|
||||
and edx,0xfffffff0 ;force 16-byte alignment of stack heap
|
||||
and edx,0xffffff00 ;force 256-byte alignment of stack heap
|
||||
|
||||
;store thread entry point + registers so that first call to co_jump will go to coentry
|
||||
mov dword[edx-4],ecx ;edx=*stack,ecx=coentry
|
||||
;store thread entry point + registers so that first call to co_switch will execute coentry
|
||||
mov dword[edx-4],co_entrypoint ;edx=*stack
|
||||
mov dword[edx-8],0
|
||||
mov dword[edx-12],0
|
||||
mov dword[edx-16],0
|
||||
@@ -130,13 +127,15 @@ co_create:
|
||||
sub edx,20
|
||||
|
||||
;initialize context memory heap
|
||||
mov dword[eax],edx ;thread_t[0-3] = stack heap pointer (esp)
|
||||
mov dword[eax+4],0 ;thread_t[4-7] = (null) pointer to prev_call_context
|
||||
mov dword[eax],edx ;cothread_t[ 0- 3] = stack heap pointer (esp)
|
||||
mov dword[eax+4],ecx ;cothread_t[ 4- 7] = entry point
|
||||
mov ecx,dword[co_active_context]
|
||||
mov dword[eax+8],ecx ;cothread_t[ 8-11] = return context
|
||||
|
||||
ret ;return allocated memory block as thread handle
|
||||
|
||||
;*****
|
||||
;extern "C" void fastcall co_delete(thread_t cothread);
|
||||
;extern "C" void fastcall co_delete(cothread_t cothread);
|
||||
;ecx = cothread
|
||||
;*****
|
||||
|
||||
@@ -148,12 +147,12 @@ co_delete:
|
||||
ret
|
||||
|
||||
;*****
|
||||
;extern "C" void fastcall co_jump(thread_t cothread);
|
||||
;extern "C" void fastcall co_switch(cothread_t cothread);
|
||||
;ecx = cothread
|
||||
;*****
|
||||
|
||||
align 16
|
||||
co_jump:
|
||||
co_switch:
|
||||
mov eax,dword[co_active_context] ;backup current context
|
||||
mov dword[co_active_context],ecx ;set new active context
|
||||
|
||||
@@ -172,50 +171,27 @@ co_jump:
|
||||
ret
|
||||
|
||||
;*****
|
||||
;extern "C" void fastcall co_call(thread_t cothread);
|
||||
;extern "C" void fastcall co_exit(cothread_t cothread);
|
||||
;ecx = cothread
|
||||
;*****
|
||||
|
||||
align 16
|
||||
co_call:
|
||||
mov eax,dword[co_active_context] ;backup current context
|
||||
mov dword[co_active_context],ecx ;set new active context
|
||||
mov dword[ecx+4],eax
|
||||
co_exit:
|
||||
cmp ecx,0
|
||||
jne co_switch
|
||||
|
||||
push ebp
|
||||
push esi
|
||||
push edi
|
||||
push ebx
|
||||
mov dword[eax],esp
|
||||
|
||||
mov esp,dword[ecx]
|
||||
pop ebx
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebp
|
||||
|
||||
ret
|
||||
;if cothread is null, switch to context that created current context
|
||||
mov eax,dword[co_active_context]
|
||||
mov ecx,dword[eax+8]
|
||||
jmp co_switch
|
||||
|
||||
;*****
|
||||
;extern "C" void fastcall co_return();
|
||||
;void fastcall co_entrypoint();
|
||||
;*****
|
||||
|
||||
align 16
|
||||
co_return:
|
||||
mov eax,dword[co_active_context] ;backup current context
|
||||
mov ecx,dword[eax+4] ;restore pre-call context
|
||||
mov dword[co_active_context],ecx ;set new active context
|
||||
|
||||
push ebp
|
||||
push esi
|
||||
push edi
|
||||
push ebx
|
||||
mov dword[eax],esp
|
||||
|
||||
mov esp,dword[ecx]
|
||||
pop ebx
|
||||
pop edi
|
||||
pop esi
|
||||
pop ebp
|
||||
|
||||
ret
|
||||
co_entrypoint:
|
||||
mov eax,dword[co_active_context]
|
||||
call dword[eax+4]
|
||||
xor ecx,ecx
|
||||
jmp co_exit
|
||||
+16
-11
@@ -1,15 +1,20 @@
|
||||
/*
|
||||
libco_x86 : version 0.06 ~byuu (05/21/2006)
|
||||
libco_x86 : version 0.08 ~byuu (10/21/2006)
|
||||
*/
|
||||
|
||||
typedef void (*thread_t);
|
||||
typedef void (*thread_p)();
|
||||
#define COTHREAD_STACKSIZE_TINY 0x1000
|
||||
#define COTHREAD_STACKSIZE_SMALL 0x4000
|
||||
#define COTHREAD_STACKSIZE_NORMAL 0x10000
|
||||
#define COTHREAD_STACKSIZE_LARGE 0x40000
|
||||
#define COTHREAD_STACKSIZE_HUGE 0x100000
|
||||
|
||||
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();
|
||||
typedef void (*cothread_t);
|
||||
typedef void (*cothread_p)(void);
|
||||
|
||||
extern "C" cothread_t fastcall co_init();
|
||||
extern "C" void fastcall co_term();
|
||||
extern "C" cothread_t fastcall co_active();
|
||||
extern "C" cothread_t fastcall co_create(cothread_p coentry, unsigned int heapsize);
|
||||
extern "C" void fastcall co_delete(cothread_t cothread);
|
||||
extern "C" void fastcall co_switch(cothread_t cothread);
|
||||
extern "C" void fastcall co_exit(cothread_t cothread);
|
||||
+22
-23
@@ -14,7 +14,7 @@ void Setting::set(uint _data) {
|
||||
data = _data;
|
||||
|
||||
switch(type) {
|
||||
case TRUE_FALSE:
|
||||
case BOOL:
|
||||
case ENABLED_DISABLED:
|
||||
case ON_OFF:
|
||||
case YES_NO:
|
||||
@@ -32,22 +32,20 @@ void Setting::set(uint _data) {
|
||||
}
|
||||
}
|
||||
|
||||
char *Setting::sget() {
|
||||
char *Setting::strget() {
|
||||
return strptr(char_data);
|
||||
}
|
||||
|
||||
void Setting::sset(const char *_data) {
|
||||
void Setting::strset(const char *_data) {
|
||||
strcpy(char_data, _data);
|
||||
strunquote(char_data);
|
||||
}
|
||||
|
||||
Setting::Setting(Config *_parent, char *_name, char *_desc, uint _data, uint _type) {
|
||||
int s;
|
||||
if(_parent) {
|
||||
_parent->add(this);
|
||||
}
|
||||
|
||||
s = strlen(_name);
|
||||
uint s = strlen(_name);
|
||||
name = (char*)malloc(s + 1);
|
||||
strcpy(name, _name);
|
||||
|
||||
@@ -66,12 +64,11 @@ int s;
|
||||
}
|
||||
|
||||
Setting::Setting(Config *_parent, char *_name, char *_desc, char *_data) {
|
||||
int s;
|
||||
if(_parent) {
|
||||
_parent->add(this);
|
||||
}
|
||||
|
||||
s = strlen(_name);
|
||||
uint s = strlen(_name);
|
||||
name = (char*)malloc(s + 1);
|
||||
strcpy(name, _name);
|
||||
|
||||
@@ -87,7 +84,7 @@ int s;
|
||||
strcpy(char_data, _data);
|
||||
strcpy(char_def, _data);
|
||||
|
||||
type = STR;
|
||||
type = STRING;
|
||||
}
|
||||
|
||||
void Config::add(Setting *setting) {
|
||||
@@ -95,18 +92,18 @@ void Config::add(Setting *setting) {
|
||||
}
|
||||
|
||||
uint Config::string_to_uint(uint type, char *input) {
|
||||
if(strmatch(input, "true") ||
|
||||
strmatch(input, "enabled") ||
|
||||
strmatch(input, "on") ||
|
||||
strmatch(input, "yes")
|
||||
if(!strcmp(input, "true") ||
|
||||
!strcmp(input, "enabled") ||
|
||||
!strcmp(input, "on") ||
|
||||
!strcmp(input, "yes")
|
||||
) {
|
||||
return (uint)true;
|
||||
}
|
||||
|
||||
if(strmatch(input, "false") ||
|
||||
strmatch(input, "disabled") ||
|
||||
strmatch(input, "off") ||
|
||||
strmatch(input, "no")
|
||||
if(!strcmp(input, "false") ||
|
||||
!strcmp(input, "disabled") ||
|
||||
!strcmp(input, "off") ||
|
||||
!strcmp(input, "no")
|
||||
) {
|
||||
return (uint)false;
|
||||
}
|
||||
@@ -121,7 +118,7 @@ uint Config::string_to_uint(uint type, char *input) {
|
||||
char *Config::uint_to_string(uint type, uint input) {
|
||||
static char output[512];
|
||||
switch(type) {
|
||||
case Setting::TRUE_FALSE:
|
||||
case Setting::BOOL:
|
||||
sprintf(output, "%s", (input & 1) ? "true" : "false");
|
||||
break;
|
||||
case Setting::ENABLED_DISABLED:
|
||||
@@ -144,7 +141,7 @@ static char output[512];
|
||||
return output;
|
||||
}
|
||||
|
||||
bool Config::load(char *fn) {
|
||||
bool Config::load(const char *fn) {
|
||||
FILE *fp;
|
||||
fp = fopen(fn, "rb");
|
||||
if(!fp)return false;
|
||||
@@ -172,11 +169,12 @@ char *buffer = (char*)malloc(fsize + 1);
|
||||
|
||||
qsplit(part, "=", line[i]);
|
||||
for(int l = 0; l < list_count; l++) {
|
||||
if(strmatch(list[l]->name, part[0])) {
|
||||
if(!strcmp(list[l]->name, part[0])) {
|
||||
if(list[l]->type != Setting::STR) {
|
||||
list[l]->set(string_to_uint(list[l]->type, strptr(part[1])));
|
||||
} else {
|
||||
list[l]->sset(strptr(part[1]));
|
||||
list[l]->strset(strptr(part[1]));
|
||||
strunquote(list[l]->char_data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -186,7 +184,7 @@ char *buffer = (char*)malloc(fsize + 1);
|
||||
}
|
||||
bool Config::load(string &fn) { return load(strptr(fn)); }
|
||||
|
||||
bool Config::save(char *fn) {
|
||||
bool Config::save(const char *fn) {
|
||||
FILE *fp;
|
||||
fp = fopen(fn, "wb");
|
||||
if(!fp)return false;
|
||||
@@ -198,7 +196,7 @@ FILE *fp;
|
||||
for(int l = 0; l < count(line); l++) {
|
||||
fprintf(fp, "# %s\r\n", strptr(line[l]));
|
||||
}
|
||||
if(list[i]->type != Setting::STR) {
|
||||
if(list[i]->type != Setting::STRING) {
|
||||
fprintf(fp, "# (default = %s)\r\n", uint_to_string(list[i]->type, list[i]->def));
|
||||
fprintf(fp, "%s = %s\r\n\r\n", list[i]->name, uint_to_string(list[i]->type, list[i]->data));
|
||||
} else {
|
||||
@@ -207,6 +205,7 @@ FILE *fp;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
return true;
|
||||
}
|
||||
bool Config::save(string &fn) { return save(strptr(fn)); }
|
||||
|
||||
+13
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
libconfig : version 0.10 ~byuu (10/10/06)
|
||||
libconfig : version 0.11 ~byuu (2006/11/12)
|
||||
*/
|
||||
|
||||
#ifndef __LIBCONFIG
|
||||
@@ -30,16 +30,18 @@ enum {
|
||||
HEX16 = 7,
|
||||
HEX24 = 8,
|
||||
HEX32 = 9,
|
||||
STRING = 10,
|
||||
STR = 10,
|
||||
};
|
||||
|
||||
char *name, *desc;
|
||||
string char_data, char_def;
|
||||
virtual void toggle();
|
||||
virtual uint get();
|
||||
virtual void set(uint _data);
|
||||
|
||||
virtual char *sget();
|
||||
virtual void sset(const char *_data);
|
||||
virtual char *strget();
|
||||
virtual void strset(const char *_data);
|
||||
|
||||
Setting(Config *_parent, char *_name, char *_desc, uint _data, uint _type);
|
||||
Setting(Config *_parent, char *_name, char *_desc, char *_data);
|
||||
@@ -52,6 +54,12 @@ string char_data, char_def;
|
||||
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; }
|
||||
|
||||
inline operator char*() { return strget(); }
|
||||
inline Setting &operator=(char *x) { strset(x); return *this; }
|
||||
inline Setting &operator=(const char *x) { strset(x); return *this; }
|
||||
inline bool operator==(const char *x) { return !strcmp(strget(), x); }
|
||||
inline bool operator!=(const char *x) { return strcmp(strget(), x); }
|
||||
};
|
||||
|
||||
class Config {
|
||||
@@ -67,9 +75,9 @@ char *uint_to_string(uint type, uint input);
|
||||
|
||||
public:
|
||||
void add(Setting *setting);
|
||||
bool load(char *fn);
|
||||
bool load(const char *fn);
|
||||
bool load(string &fn);
|
||||
bool save(char *fn);
|
||||
bool save(const char *fn);
|
||||
bool save(string &fn);
|
||||
Config();
|
||||
};
|
||||
|
||||
+34
-32
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
libfile : version 0.05 ~byuu (10/12/06)
|
||||
libfile : version 0.05a ~byuu (10/26/06)
|
||||
*/
|
||||
|
||||
#ifndef __LIBFILE
|
||||
@@ -51,10 +51,12 @@ uint32 crc32 = 0xffffffff;
|
||||
inline void fread(file &s, uint8 *data, uint length) { s.read(data, length); }
|
||||
inline uint8 fread(file &s) { return s.read(); }
|
||||
inline uint8 fgetc(file &s) { return s.read(); }
|
||||
inline uint fgetb(file &s) { return s.read(); }
|
||||
|
||||
inline void fwrite(file &s, uint8 *data, uint length) { s.write(data, length); }
|
||||
inline void fwrite(file &s, uint8 data) { s.write(data); }
|
||||
inline void fputc(file &s, uint8 data) { s.write(data); }
|
||||
inline void fputc(uint8 data, file &s) { s.write(data); }
|
||||
inline void fputb(file &s, uint8 data) { s.write(data); }
|
||||
|
||||
inline uint32 fcrc32(file &s) { return s.crc32(); }
|
||||
|
||||
@@ -107,53 +109,53 @@ inline uint64 fgetmq(file &s) {
|
||||
((uint64)fgetc(s) << 8) | ((uint64)fgetc(s) << 0);
|
||||
}
|
||||
|
||||
inline void fputlb(file &s, uint8 data) { fputc(s, data); }
|
||||
inline void fputmb(file &s, uint8 data) { fputc(s, data); }
|
||||
inline void fputlb(file &s, uint8 data) { fputc(data, s); }
|
||||
inline void fputmb(file &s, uint8 data) { fputc(data, s); }
|
||||
|
||||
inline void fputlw(file &s, uint16 data) {
|
||||
fputc(s, data >> 0);
|
||||
fputc(s, data >> 8);
|
||||
fputc(data >> 0, s);
|
||||
fputc(data >> 8, s);
|
||||
}
|
||||
|
||||
inline void fputmw(file &s, uint16 data) {
|
||||
fputc(s, data >> 8);
|
||||
fputc(s, data >> 0);
|
||||
fputc(data >> 8, s);
|
||||
fputc(data >> 0, s);
|
||||
}
|
||||
|
||||
inline void fputld(file &s, uint32 data) {
|
||||
fputc(s, data >> 0);
|
||||
fputc(s, data >> 8);
|
||||
fputc(s, data >> 16);
|
||||
fputc(s, data >> 24);
|
||||
fputc(data >> 0, s);
|
||||
fputc(data >> 8, s);
|
||||
fputc(data >> 16, s);
|
||||
fputc(data >> 24, s);
|
||||
}
|
||||
|
||||
inline void fputmd(file &s, uint32 data) {
|
||||
fputc(s, data >> 24);
|
||||
fputc(s, data >> 16);
|
||||
fputc(s, data >> 8);
|
||||
fputc(s, data >> 0);
|
||||
fputc(data >> 24, s);
|
||||
fputc(data >> 16, s);
|
||||
fputc(data >> 8, s);
|
||||
fputc(data >> 0, s);
|
||||
}
|
||||
|
||||
inline void fputlq(file &s, uint64 data) {
|
||||
fputc(s, data >> 0);
|
||||
fputc(s, data >> 8);
|
||||
fputc(s, data >> 16);
|
||||
fputc(s, data >> 24);
|
||||
fputc(s, data >> 32);
|
||||
fputc(s, data >> 40);
|
||||
fputc(s, data >> 48);
|
||||
fputc(s, data >> 56);
|
||||
fputc(data >> 0, s);
|
||||
fputc(data >> 8, s);
|
||||
fputc(data >> 16, s);
|
||||
fputc(data >> 24, s);
|
||||
fputc(data >> 32, s);
|
||||
fputc(data >> 40, s);
|
||||
fputc(data >> 48, s);
|
||||
fputc(data >> 56, s);
|
||||
}
|
||||
|
||||
inline void fputmq(file &s, uint64 data) {
|
||||
fputc(s, data >> 56);
|
||||
fputc(s, data >> 48);
|
||||
fputc(s, data >> 40);
|
||||
fputc(s, data >> 32);
|
||||
fputc(s, data >> 24);
|
||||
fputc(s, data >> 16);
|
||||
fputc(s, data >> 8);
|
||||
fputc(s, data >> 0);
|
||||
fputc(data >> 56, s);
|
||||
fputc(data >> 48, s);
|
||||
fputc(data >> 40, s);
|
||||
fputc(data >> 32, s);
|
||||
fputc(data >> 24, s);
|
||||
fputc(data >> 16, s);
|
||||
fputc(data >> 8, s);
|
||||
fputc(data >> 0, s);
|
||||
}
|
||||
|
||||
/*****
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
libsort : version 0.01 ~byuu (2006-11-15)
|
||||
*/
|
||||
|
||||
#ifndef __LIBSORT
|
||||
#define __LIBSORT
|
||||
|
||||
template<typename T>
|
||||
void sort(T list[], uint length) {
|
||||
for(uint d = 0; d < length; d++) {
|
||||
uint min = d;
|
||||
for(uint s = d + 1; s < length; s++) {
|
||||
if(list[s] < list[min]) { min = s; }
|
||||
}
|
||||
if(min != d) {
|
||||
swap(list[d], list[min]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename Tcmp>
|
||||
void sort(T list[], uint length, Tcmp comparator) {
|
||||
for(uint d = 0; d < length; d++) {
|
||||
uint min = d;
|
||||
for(uint s = d + 1; s < length; s++) {
|
||||
if(comparator(list[s], list[min]) == true) { min = s; }
|
||||
}
|
||||
if(min != d) {
|
||||
swap(list[d], list[min]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif __LIBSORT
|
||||
+68
-50
@@ -1,5 +1,6 @@
|
||||
#include "libbase.h"
|
||||
#include "libstring.h"
|
||||
#include "libstring_oo.cpp"
|
||||
|
||||
uint count(stringarray &str) { return str.size(); }
|
||||
|
||||
@@ -13,12 +14,6 @@ char chrupper(char c) {
|
||||
return c;
|
||||
}
|
||||
|
||||
void strresize(string &str, uint size) {
|
||||
str.s = (char*)realloc(str.s, size + 1);
|
||||
str.s[size] = 0;
|
||||
str.size = size;
|
||||
}
|
||||
|
||||
char *strptr(string &str) { return str.s; }
|
||||
|
||||
uint strlen(string &str) { return strlen(strptr(str)); }
|
||||
@@ -39,49 +34,41 @@ int stricmp(string &dest, const char *src) { return __stricmp(strptr(dest), src)
|
||||
int stricmp(const char *dest, string &src) { return __stricmp(dest, strptr(src)); }
|
||||
int stricmp(string &dest, string &src) { return __stricmp(strptr(dest), strptr(src)); }
|
||||
|
||||
bool strmatch(const char *dest, const char *src) { return !strcmp(dest, src); }
|
||||
bool strmatch(string &dest, const char *src) { return strmatch(strptr(dest), src); }
|
||||
bool strmatch(const char *dest, string &src) { return strmatch(dest, strptr(src)); }
|
||||
bool strmatch(string &dest, string &src) { return strmatch(strptr(dest), strptr(src)); }
|
||||
|
||||
bool strimatch(const char *dest, const char *src) { return !stricmp(dest, src); }
|
||||
bool strimatch(string &dest, const char *src) { return strimatch(strptr(dest), src); }
|
||||
bool strimatch(const char *dest, string &src) { return strimatch(dest, strptr(src)); }
|
||||
bool strimatch(string &dest, string &src) { return strimatch(strptr(dest), strptr(src)); }
|
||||
|
||||
void strcpy(string &dest, const char src) {
|
||||
if(1 > dest.size) { strresize(dest, 1); }
|
||||
dest.reserve(2);
|
||||
dest.s[0] = src;
|
||||
dest.s[1] = 0;
|
||||
}
|
||||
|
||||
void strcpy(string &dest, const char *src) {
|
||||
int srclen = strlen(src);
|
||||
if(srclen > dest.size) { strresize(dest, srclen); }
|
||||
dest.reserve(srclen);
|
||||
strcpy(dest.s, src);
|
||||
}
|
||||
void strcpy(string &dest, string &src) { strcpy(dest, strptr(src)); }
|
||||
|
||||
//this differs from libc's strncpy in that it always
|
||||
//appends a null terminator to the end of a copied string
|
||||
void strncpy(string &dest, const char *src, uint32 length) {
|
||||
int srclen = strlen(src);
|
||||
//never copy more text than is in the string
|
||||
if(srclen > length)srclen = length;
|
||||
if(srclen > dest.size) { strresize(dest, srclen); }
|
||||
strncpy(dest.s, src, srclen);
|
||||
dest.s[srclen] = 0;
|
||||
uint strlcpy(char *dest, const char *src, uint length) {
|
||||
uint srclen = strlen(src);
|
||||
length--;
|
||||
if(length > srclen)length = srclen;
|
||||
memcpy(dest, src, length);
|
||||
dest[length] = 0;
|
||||
return srclen;
|
||||
}
|
||||
void strncpy(string &dest, string &src, uint32 length) { strncpy(dest, strptr(src), length); }
|
||||
|
||||
void strset(string &dest, uint pos, uint8 c) {
|
||||
if(pos > dest.size) { strresize(dest, pos); }
|
||||
dest.s[pos] = c;
|
||||
uint strlcpy(string &dest, const char *src, uint length) {
|
||||
dest.reserve(length);
|
||||
return strlcpy(strptr(dest), src, length);
|
||||
}
|
||||
|
||||
uint strlcpy(string &dest, string &src, uint length) {
|
||||
dest.reserve(length);
|
||||
return strlcpy(strptr(dest), strptr(src), length);
|
||||
}
|
||||
|
||||
void strcat(string &dest, const char src) {
|
||||
int length = strlen(dest);
|
||||
if(length + 1 > dest.size) { strresize(dest, length + 1); }
|
||||
dest.reserve(length + 1);
|
||||
dest.s[length] = src;
|
||||
dest.s[length + 1] = 0;
|
||||
}
|
||||
@@ -89,32 +76,62 @@ int length = strlen(dest);
|
||||
void strcat(string &dest, const char *src) {
|
||||
int srclen = strlen(src);
|
||||
int destlen = strlen(dest);
|
||||
if(srclen + destlen > dest.size) { strresize(dest, srclen + destlen); }
|
||||
dest.reserve(srclen + destlen);
|
||||
strcat(dest.s, src);
|
||||
}
|
||||
void strcat(string &dest, string &src) { strcat(dest, strptr(src)); }
|
||||
|
||||
uint strlcat(char *dest, const char *src, uint length) {
|
||||
uint destlen = strlen(dest), srclen = strlen(src);
|
||||
length--;
|
||||
if(length > destlen + srclen)length = destlen + srclen;
|
||||
memcpy(dest + destlen, src, length - destlen);
|
||||
dest[length] = 0;
|
||||
return destlen + srclen;
|
||||
}
|
||||
|
||||
uint strlcat(string &dest, const char *src, uint length) {
|
||||
dest.reserve(length);
|
||||
return strlcat(strptr(dest), src, length);
|
||||
}
|
||||
|
||||
uint strlcat(string &dest, string &src, uint length) {
|
||||
dest.reserve(length);
|
||||
return strlcat(strptr(dest), strptr(src), length);
|
||||
}
|
||||
|
||||
string substr(string &dest, const char *src, uint start, uint length) {
|
||||
string temp;
|
||||
if(length == 0) {
|
||||
//copy entire string
|
||||
strcpy(temp, src + start);
|
||||
} else {
|
||||
//copy partial string
|
||||
strlcpy(temp, src + start, length + 1);
|
||||
}
|
||||
return temp;
|
||||
}
|
||||
|
||||
string substr(string &dest, string &src, uint start, uint length) { return substr(dest, strptr(src), start, length); }
|
||||
|
||||
void strinsert(string &dest, const char *src, uint pos) {
|
||||
static string s;
|
||||
strcpy(s, strptr(dest) + pos);
|
||||
strset(dest, pos, 0);
|
||||
string temp;
|
||||
strcpy(temp, strptr(dest) + pos);
|
||||
dest[pos] = 0;
|
||||
strcat(dest, src);
|
||||
strcat(dest, s);
|
||||
strcat(dest, temp);
|
||||
}
|
||||
void strinsert(string &dest, string &src, uint pos) { strinsert(dest, strptr(src), pos); }
|
||||
|
||||
void strremove(string &dest, uint start, uint length) {
|
||||
int destlen;
|
||||
char *s;
|
||||
int i, sl = strlen(dest.s);
|
||||
if(start > dest.size) { strresize(dest, start); }
|
||||
int i, destlen = strlen(dest);
|
||||
dest.reserve(start);
|
||||
if(!length) {
|
||||
strset(dest, start, 0);
|
||||
dest[start] = 0;
|
||||
return;
|
||||
}
|
||||
s = dest.s;
|
||||
for(i=start;i<sl;i++) { s[i] = s[i+length]; }
|
||||
s[i] = 0;
|
||||
for(i = start; i < destlen; i++) { dest.s[i] = dest.s[i + length]; }
|
||||
dest.s[i] = 0;
|
||||
}
|
||||
|
||||
char *strlower(char *str) {
|
||||
@@ -401,7 +418,7 @@ uint mask = 1000000000;
|
||||
}
|
||||
|
||||
string &utoa(string &str, uint num) {
|
||||
if(str.size < 16) { strresize(str, 16); }
|
||||
str.reserve(16);
|
||||
utoa(strptr(str), num);
|
||||
return str;
|
||||
}
|
||||
@@ -418,7 +435,7 @@ char *pstr = str;
|
||||
}
|
||||
|
||||
string &itoa(string &str, uint num) {
|
||||
if(str.size < 16) { strresize(str, 16); }
|
||||
str.reserve(16);
|
||||
itoa(strptr(str), num);
|
||||
return str;
|
||||
}
|
||||
@@ -441,7 +458,7 @@ uint mask = 28, r;
|
||||
}
|
||||
|
||||
string &htoa(string &str, uint num) {
|
||||
if(str.size < 16) { strresize(str, 16); }
|
||||
str.reserve(16);
|
||||
htoa(strptr(str), num);
|
||||
return str;
|
||||
}
|
||||
@@ -464,7 +481,7 @@ uint mask = 28, r;
|
||||
}
|
||||
|
||||
string &uhtoa(string &str, uint num) {
|
||||
if(str.size < 16) { strresize(str, 16); }
|
||||
str.reserve(16);
|
||||
uhtoa(strptr(str), num);
|
||||
return str;
|
||||
}
|
||||
@@ -485,7 +502,7 @@ uint mask = 0x80000000;
|
||||
}
|
||||
|
||||
string &btoa(string &str, uint num) {
|
||||
if(str.size < 48) { strresize(str, 48); }
|
||||
str.reserve(48);
|
||||
btoa(strptr(str), num);
|
||||
return str;
|
||||
}
|
||||
@@ -507,6 +524,7 @@ char *fdata = (char*)malloc(size + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "libstring_int.cpp"
|
||||
#include "libstring_math.cpp"
|
||||
#include "libstring_split.cpp"
|
||||
#include "libstring_replace.cpp"
|
||||
|
||||
+68
-26
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
libstring : version 0.12 ~byuu (10/05/06)
|
||||
libstring : version 0.14b ~byuu (2006/11/17)
|
||||
*/
|
||||
|
||||
#ifndef __LIBSTRING
|
||||
@@ -15,10 +15,7 @@ char chrupper(char c);
|
||||
|
||||
uint count(stringarray &str);
|
||||
|
||||
void strresize(string &str, uint size);
|
||||
|
||||
char* strptr(string &str);
|
||||
|
||||
char *strptr(string &str);
|
||||
uint strlen(string &str);
|
||||
|
||||
int strcmp(string &dest, const char *src);
|
||||
@@ -34,26 +31,21 @@ int stricmp(string &dest, const char *src);
|
||||
int stricmp(const char *dest, string &src);
|
||||
int stricmp(string &dest, string &src);
|
||||
|
||||
bool strmatch(const char *dest, const char *src);
|
||||
bool strmatch(string &dest, const char *src);
|
||||
bool strmatch(const char *dest, string &src);
|
||||
bool strmatch(string &dest, string &src);
|
||||
|
||||
bool strimatch(const char *dest, const char *src);
|
||||
bool strimatch(string &dest, const char *src);
|
||||
bool strimatch(const char *dest, string &src);
|
||||
bool strimatch(string &dest, string &src);
|
||||
|
||||
void strcpy(string &dest, const char *src);
|
||||
void strcpy(string &dest, string &src);
|
||||
void strncpy(string &dest, const char *src, uint32 length);
|
||||
void strncpy(string &dest, string &src, uint32 length);
|
||||
|
||||
void strset(string &dest, uint pos, uint8 c);
|
||||
uint strlcpy(char *dest, const char *src, uint length);
|
||||
uint strlcpy(string &dest, const char *src, uint length);
|
||||
uint strlcpy(string &dest, string &src, uint length);
|
||||
|
||||
void strcat(string &dest, const char src);
|
||||
void strcat(string &dest, const char *src);
|
||||
void strcat(string &dest, string &src);
|
||||
uint strlcat(char *dest, const char *src, uint length);
|
||||
uint strlcat(string &dest, const char *src, uint length);
|
||||
uint strlcat(string &dest, string &src, uint length);
|
||||
|
||||
string substr(string &dest, const char *src, uint start = 0, uint length = 0);
|
||||
string substr(string &dest, string &src, uint start = 0, uint length = 0);
|
||||
|
||||
void strinsert(string &dest, const char *src, uint pos);
|
||||
void strinsert(string &dest, string &src, uint pos);
|
||||
@@ -143,6 +135,8 @@ string &btoa(string &str, uint num);
|
||||
|
||||
bool strfread(string &str, const char *filename);
|
||||
|
||||
string strfmt(const char *fmt, int num);
|
||||
|
||||
int strmath(const char *in_str);
|
||||
int strmath(string &in_str);
|
||||
|
||||
@@ -165,20 +159,68 @@ class string {
|
||||
public:
|
||||
char *s;
|
||||
uint size;
|
||||
void reserve(uint reqsize) {
|
||||
if(reqsize > size) {
|
||||
size = reqsize;
|
||||
s = (char*)realloc(s, size + 1);
|
||||
s[size] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void swap(string &str) {
|
||||
::swap(s, str.s);
|
||||
::swap(size, str.size);
|
||||
}
|
||||
|
||||
string() {
|
||||
size = 16;
|
||||
s = (char*)malloc(size + 1);
|
||||
*s = 0;
|
||||
s[0] = 0;
|
||||
}
|
||||
|
||||
~string() { SafeFree(s); }
|
||||
|
||||
void operator=(const string &p) {
|
||||
SafeFree(s);
|
||||
size = p.size;
|
||||
string(const char *str) {
|
||||
size = strlen(str);
|
||||
s = (char*)malloc(size + 1);
|
||||
strcpy(s, p.s);
|
||||
strcpy(s, str);
|
||||
}
|
||||
|
||||
string(string &str) {
|
||||
size = strlen(str);
|
||||
s = (char*)malloc(size + 1);
|
||||
strcpy(s, strptr(str));
|
||||
}
|
||||
|
||||
~string() { safe_free(s); }
|
||||
|
||||
const char *operator()();
|
||||
char &operator[](uint);
|
||||
string &operator=(int);
|
||||
string &operator=(const char *);
|
||||
string &operator=(string &);
|
||||
string &operator+=(int);
|
||||
string &operator+=(const char *);
|
||||
string &operator+=(string &);
|
||||
bool operator==(const char *);
|
||||
bool operator==(string &);
|
||||
bool operator!=(const char *);
|
||||
bool operator!=(string &);
|
||||
bool operator<(const char *);
|
||||
bool operator<(string &);
|
||||
bool operator<=(const char *);
|
||||
bool operator<=(string &);
|
||||
bool operator>(const char *);
|
||||
bool operator>(string &);
|
||||
bool operator>=(const char *);
|
||||
bool operator>=(string &);
|
||||
|
||||
string operator+(int);
|
||||
string operator+(const char *);
|
||||
string operator+(string &);
|
||||
};
|
||||
|
||||
string operator+(int, string &);
|
||||
string operator+(const char *, string &);
|
||||
|
||||
inline void swap(string &x, string &y) { x.swap(y); }
|
||||
|
||||
#endif //__LIBSTRING
|
||||
@@ -0,0 +1,5 @@
|
||||
string strfmt(const char *fmt, int num) {
|
||||
string temp;
|
||||
sprintf(temp, fmt, num);
|
||||
return temp;
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
const char *string::operator()() {
|
||||
return s;
|
||||
}
|
||||
|
||||
char &string::operator[](const uint index) {
|
||||
reserve(index);
|
||||
return s[index];
|
||||
}
|
||||
|
||||
string &string::operator=(int num) {
|
||||
strcpy(*this, strfmt("%d", num));
|
||||
return *this;
|
||||
}
|
||||
|
||||
string &string::operator=(const char *str) {
|
||||
strcpy(*this, str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string &string::operator=(string &str) {
|
||||
strcpy(*this, str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string &string::operator+=(int num) {
|
||||
strcat(*this, strfmt("%d", num));
|
||||
return *this;
|
||||
}
|
||||
|
||||
string &string::operator+=(const char *str) {
|
||||
strcat(*this, str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
string &string::operator+=(string &str) {
|
||||
strcat(*this, str);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool string::operator==(const char *str) { return strcmp(strptr(*this), str) == 0; }
|
||||
bool string::operator==(string &str) { return strcmp(strptr(*this), strptr(str)) == 0; }
|
||||
bool string::operator!=(const char *str) { return strcmp(strptr(*this), str) != 0; }
|
||||
bool string::operator!=(string &str) { return strcmp(strptr(*this), strptr(str)) != 0; }
|
||||
bool string::operator<(const char *str) { return strcmp(strptr(*this), str) < 0; }
|
||||
bool string::operator<(string &str) { return strcmp(strptr(*this), strptr(str)) < 0; }
|
||||
bool string::operator<=(const char *str) { return strcmp(strptr(*this), str) <= 0; }
|
||||
bool string::operator<=(string &str) { return strcmp(strptr(*this), strptr(str)) <= 0; }
|
||||
bool string::operator>(const char *str) { return strcmp(strptr(*this), str) > 0; }
|
||||
bool string::operator>(string &str) { return strcmp(strptr(*this), strptr(str)) > 0; }
|
||||
bool string::operator>=(const char *str) { return strcmp(strptr(*this), str) >= 0; }
|
||||
bool string::operator>=(string &str) { return strcmp(strptr(*this), strptr(str)) >= 0; }
|
||||
|
||||
string string::operator+(int num) {
|
||||
string temp(*this);
|
||||
strcat(temp, strfmt("%d", num));
|
||||
return temp;
|
||||
}
|
||||
|
||||
string string::operator+(const char *str) {
|
||||
string temp(*this);
|
||||
strcat(temp, str);
|
||||
return temp;
|
||||
}
|
||||
|
||||
string string::operator+(string &str) {
|
||||
string temp(*this);
|
||||
strcat(temp, str);
|
||||
return temp;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
string operator+(int x, string &y) {
|
||||
string temp(strfmt("%d", x));
|
||||
strcat(temp, y);
|
||||
return temp;
|
||||
}
|
||||
|
||||
string operator+(const char *x, string &y) {
|
||||
string temp(x);
|
||||
strcat(temp, y);
|
||||
return temp;
|
||||
}
|
||||
@@ -4,17 +4,17 @@ uint replace_count = 0, size = ssl;
|
||||
char *data;
|
||||
if(ksl > ssl)return str;
|
||||
if(tsl > ksl) { //the new string may be longer than the old string...
|
||||
for(i=0;i<=ssl-ksl;) { //so let's find out how big of a string we'll need...
|
||||
for(i = 0; i <= ssl - ksl;) { //so let's find out how big of a string we'll need...
|
||||
if(!memcmp(str.s + i, key, ksl)) {
|
||||
replace_count++;
|
||||
i += ksl;
|
||||
} else i++;
|
||||
}
|
||||
size = ssl + ((tsl - ksl) * replace_count);
|
||||
if(size > str.size)strresize(str, size);
|
||||
str.reserve(size);
|
||||
}
|
||||
data = (char*)malloc(size + 1);
|
||||
for(i=z=0;i<ssl;) {
|
||||
for(i = z = 0; i < ssl;) {
|
||||
if(i <= ssl - ksl) {
|
||||
if(!memcmp(str.s + i, key, ksl)) {
|
||||
memcpy(data + z, token, tsl);
|
||||
@@ -37,7 +37,7 @@ uint8 x;
|
||||
char *data;
|
||||
if(ksl > ssl)return str;
|
||||
if(tsl > ksl) {
|
||||
for(i=0;i<=ssl-ksl;) {
|
||||
for(i = 0; i <= ssl - ksl;) {
|
||||
x = str.s[i];
|
||||
if(x == '\"' || x == '\'') {
|
||||
l = i;
|
||||
@@ -55,10 +55,10 @@ char *data;
|
||||
} else i++;
|
||||
}
|
||||
size = ssl + ((tsl - ksl) * replace_count);
|
||||
if(size > str.size)strresize(str, size);
|
||||
str.reserve(size);
|
||||
}
|
||||
data = (char*)malloc(size + 1);
|
||||
for(i=z=0;i<ssl;) {
|
||||
for(i = z = 0; i < ssl;) {
|
||||
x = str.s[i];
|
||||
if(x == '\"' || x == '\'') {
|
||||
l = i++;
|
||||
|
||||
@@ -5,7 +5,7 @@ int ssl = strlen(src), ksl = strlen(key);
|
||||
int lp = 0, split_count = 0;
|
||||
for(int i = 0; i <= ssl - ksl;) {
|
||||
if(!memcmp(src + i, key, ksl)) {
|
||||
strncpy(dest[split_count++], src + lp, i - lp);
|
||||
strlcpy(dest[split_count++], src + lp, i - lp + 1);
|
||||
i += ksl;
|
||||
lp = i;
|
||||
} else i++;
|
||||
@@ -27,7 +27,7 @@ int lp = 0, split_count = 0;
|
||||
if(i >= ssl)i = z;
|
||||
}
|
||||
if(!memcmp(src + i, key, ksl)) {
|
||||
strncpy(dest[split_count++], src + lp, i - lp);
|
||||
strlcpy(dest[split_count++], src + lp, i - lp + 1);
|
||||
i += ksl;
|
||||
lp = i;
|
||||
} else i++;
|
||||
|
||||
@@ -8,7 +8,7 @@ uint length = vsprintf(str, s, args);
|
||||
|
||||
uint vsprintf(string &str, const char *s, va_list args) {
|
||||
uint length = vsnprintf(0, 0, s, args);
|
||||
strresize(str, length + 1);
|
||||
str.reserve(length + 1);
|
||||
return vsprintf(strptr(str), s, args);
|
||||
}
|
||||
|
||||
|
||||
+20
-20
@@ -226,33 +226,33 @@ uint ptr = 0;
|
||||
template<typename FTO, typename FTM, typename FTP>
|
||||
void UPS<FTO, FTM, FTP>::ptr_write(uint ptr) {
|
||||
if(ptr <= 0xf7) {
|
||||
fputc(patch.fp, ptr);
|
||||
fputb(patch.fp, ptr);
|
||||
return;
|
||||
}
|
||||
|
||||
ptr -= 0xf8;
|
||||
if(ptr <= 0xffff) {
|
||||
fputc(patch.fp, 0xf8);
|
||||
fputc(patch.fp, ptr);
|
||||
fputc(patch.fp, ptr >> 8);
|
||||
fputb(patch.fp, 0xf8);
|
||||
fputb(patch.fp, ptr);
|
||||
fputb(patch.fp, ptr >> 8);
|
||||
return;
|
||||
}
|
||||
|
||||
ptr -= 0x10000;
|
||||
if(ptr <= 0xffffff) {
|
||||
fputc(patch.fp, 0xf9);
|
||||
fputc(patch.fp, ptr);
|
||||
fputc(patch.fp, ptr >> 8);
|
||||
fputc(patch.fp, ptr >> 16);
|
||||
fputb(patch.fp, 0xf9);
|
||||
fputb(patch.fp, ptr);
|
||||
fputb(patch.fp, ptr >> 8);
|
||||
fputb(patch.fp, ptr >> 16);
|
||||
return;
|
||||
}
|
||||
|
||||
ptr -= 0x1000000;
|
||||
fputc(patch.fp, 0xfa);
|
||||
fputc(patch.fp, ptr);
|
||||
fputc(patch.fp, ptr >> 8);
|
||||
fputc(patch.fp, ptr >> 16);
|
||||
fputc(patch.fp, ptr >> 24);
|
||||
fputb(patch.fp, 0xfa);
|
||||
fputb(patch.fp, ptr);
|
||||
fputb(patch.fp, ptr >> 8);
|
||||
fputb(patch.fp, ptr >> 16);
|
||||
fputb(patch.fp, ptr >> 24);
|
||||
}
|
||||
|
||||
template<typename FTO, typename FTM, typename FTP>
|
||||
@@ -298,14 +298,14 @@ uint last_ptr = 0, rle_count, last_out, rep_count;
|
||||
ptr_write((i - 1) - last_ptr);
|
||||
|
||||
//data
|
||||
fputc(patch.fp, r);
|
||||
fputb(patch.fp, r);
|
||||
last_out = r;
|
||||
rep_count = 0;
|
||||
|
||||
do {
|
||||
r = fgetc(original) ^ fgetc(modified);
|
||||
i++;
|
||||
fputc(patch.fp, r);
|
||||
fputb(patch.fp, r);
|
||||
|
||||
if(last_out != r) {
|
||||
rep_count = 0;
|
||||
@@ -319,7 +319,7 @@ uint last_ptr = 0, rle_count, last_out, rep_count;
|
||||
} while(i < largest_filesize);
|
||||
|
||||
ptr_write(rle_count);
|
||||
if(i < largest_filesize) { fputc(patch.fp, r); }
|
||||
if(i < largest_filesize) { fputb(patch.fp, r); }
|
||||
rep_count = 0;
|
||||
}
|
||||
}
|
||||
@@ -331,7 +331,7 @@ uint last_ptr = 0, rle_count, last_out, rep_count;
|
||||
last_ptr = i;
|
||||
}
|
||||
|
||||
fputc(patch.fp, 0xff);
|
||||
fputb(patch.fp, 0xff);
|
||||
}
|
||||
|
||||
template<typename FTO, typename FTM, typename FTP>
|
||||
@@ -385,7 +385,7 @@ void UPS<FTO, FTM, FTP>::apply_linear() {
|
||||
fseek(original, 0, file::seek_start);
|
||||
fseek(modified, 0, file::seek_start);
|
||||
for(uint i = 0; i < modified_filesize; i++) {
|
||||
fputc(modified, fgetc(original));
|
||||
fputb(modified, fgetc(original));
|
||||
}
|
||||
|
||||
fseek(original, 0, file::seek_start);
|
||||
@@ -408,14 +408,14 @@ uint rle_count, last_in, rep_count;
|
||||
if(ftell(modified) >= modified_filesize) { break; }
|
||||
|
||||
uint8 r = fgetc(patch.fp);
|
||||
fputc(modified, r ^ fgetc(original));
|
||||
fputb(modified, r ^ fgetc(original));
|
||||
if(r != last_in) {
|
||||
rep_count = 0;
|
||||
} else {
|
||||
if(++rep_count == (3 - 1)) {
|
||||
rle_count = ptr_read();
|
||||
while(rle_count-- && ftell(modified) < modified_filesize) {
|
||||
fputc(modified, r ^ fgetc(original));
|
||||
fputb(modified, r ^ fgetc(original));
|
||||
}
|
||||
rep_count = 0;
|
||||
}
|
||||
|
||||
@@ -14,12 +14,12 @@ bool Button::Create(Window *parent_window, const char *style, int x, int y, int
|
||||
stringarray part;
|
||||
ParseStyleParam(style, part);
|
||||
for(int i = 0; i < count(part); i++) {
|
||||
if(strmatch(part[i], "visible"))state.ws |= WS_VISIBLE;
|
||||
if(strmatch(part[i], "disabled"))state.ws |= WS_DISABLED;
|
||||
if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE;
|
||||
if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED;
|
||||
|
||||
if(strmatch(part[i], "left"))state.ws |= BS_LEFT;
|
||||
if(strmatch(part[i], "center"))state.ws |= BS_CENTER;
|
||||
if(strmatch(part[i], "right"))state.ws |= BS_RIGHT;
|
||||
if(!strcmp(part[i], "left"))state.ws |= BS_LEFT;
|
||||
if(!strcmp(part[i], "center"))state.ws |= BS_CENTER;
|
||||
if(!strcmp(part[i], "right"))state.ws |= BS_RIGHT;
|
||||
}
|
||||
|
||||
hwnd = CreateWindowEx(state.es, "BUTTON", text, state.ws,
|
||||
|
||||
@@ -20,13 +20,13 @@ bool Checkbox::Create(Window *parent_window, const char *style, int x, int y, in
|
||||
stringarray part;
|
||||
ParseStyleParam(style, part);
|
||||
for(int i = 0; i < count(part); i++) {
|
||||
if(strmatch(part[i], "visible"))state.ws |= WS_VISIBLE;
|
||||
if(strmatch(part[i], "disabled"))state.ws |= WS_DISABLED;
|
||||
if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE;
|
||||
if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED;
|
||||
|
||||
if(strmatch(part[i], "left"))state.ws |= BS_LEFT;
|
||||
if(strmatch(part[i], "center"))state.ws |= BS_CENTER;
|
||||
if(strmatch(part[i], "right"))state.ws |= BS_RIGHT;
|
||||
if(strmatch(part[i], "auto"))state.ws |= BS_AUTOCHECKBOX;
|
||||
if(!strcmp(part[i], "left"))state.ws |= BS_LEFT;
|
||||
if(!strcmp(part[i], "center"))state.ws |= BS_CENTER;
|
||||
if(!strcmp(part[i], "right"))state.ws |= BS_RIGHT;
|
||||
if(!strcmp(part[i], "auto"))state.ws |= BS_AUTOCHECKBOX;
|
||||
}
|
||||
if(!(state.ws & BS_AUTOCHECKBOX))state.ws |= BS_CHECKBOX;
|
||||
|
||||
|
||||
@@ -38,13 +38,13 @@ bool Combobox::Create(Window *parent_window, const char *style, int x, int y, in
|
||||
stringarray part;
|
||||
ParseStyleParam(style, part);
|
||||
for(int i = 0; i < count(part); i++) {
|
||||
if(strmatch(part[i], "visible"))state.ws |= WS_VISIBLE;
|
||||
if(strmatch(part[i], "disabled"))state.ws |= WS_DISABLED;
|
||||
if(strmatch(part[i], "border"))state.ws |= WS_BORDER;
|
||||
if(strmatch(part[i], "raised"))state.ws |= WS_DLGFRAME;
|
||||
if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE;
|
||||
if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED;
|
||||
if(!strcmp(part[i], "border"))state.ws |= WS_BORDER;
|
||||
if(!strcmp(part[i], "raised"))state.ws |= WS_DLGFRAME;
|
||||
|
||||
if(strmatch(part[i], "sunken"))state.es |= WS_EX_STATICEDGE;
|
||||
if(strmatch(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE;
|
||||
if(!strcmp(part[i], "sunken"))state.es |= WS_EX_STATICEDGE;
|
||||
if(!strcmp(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE;
|
||||
}
|
||||
|
||||
hwnd = CreateWindowEx(state.es, "COMBOBOX", text, state.ws,
|
||||
@@ -52,7 +52,7 @@ stringarray part;
|
||||
parent->hwnd, (HMENU)id, GetModuleHandle(0), 0);
|
||||
if(!hwnd)return false;
|
||||
|
||||
if(strmatch(text, "") == false) {
|
||||
if(!strcmp(text, "") == false) {
|
||||
stringarray t;
|
||||
split(t, "|", text);
|
||||
for(int i = 0; i < ::count(t); i++) {
|
||||
|
||||
@@ -74,12 +74,12 @@ void Control::GetText(char *text, uint length) {
|
||||
}
|
||||
|
||||
void Control::SetText(const char *text, ...) {
|
||||
char str[4096];
|
||||
string str;
|
||||
va_list args;
|
||||
va_start(args, text);
|
||||
vsprintf(str, text, args);
|
||||
va_end(args);
|
||||
SetWindowText(hwnd, str);
|
||||
SetWindowText(hwnd, strptr(str));
|
||||
}
|
||||
|
||||
Control::Control() {
|
||||
|
||||
@@ -19,18 +19,18 @@ bool Editbox::Create(Window *parent_window, const char *style, int x, int y, int
|
||||
stringarray part;
|
||||
ParseStyleParam(style, part);
|
||||
for(int i = 0; i < count(part); i++) {
|
||||
if(strmatch(part[i], "visible"))state.ws |= WS_VISIBLE;
|
||||
if(strmatch(part[i], "disabled"))state.ws |= WS_DISABLED;
|
||||
if(strmatch(part[i], "border"))state.ws |= WS_BORDER;
|
||||
if(strmatch(part[i], "raised"))state.ws |= WS_DLGFRAME;
|
||||
if(strmatch(part[i], "vscroll"))state.ws |= WS_VSCROLL;
|
||||
if(strmatch(part[i], "hscroll"))state.ws |= WS_HSCROLL;
|
||||
if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE;
|
||||
if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED;
|
||||
if(!strcmp(part[i], "border"))state.ws |= WS_BORDER;
|
||||
if(!strcmp(part[i], "raised"))state.ws |= WS_DLGFRAME;
|
||||
if(!strcmp(part[i], "vscroll"))state.ws |= WS_VSCROLL;
|
||||
if(!strcmp(part[i], "hscroll"))state.ws |= WS_HSCROLL;
|
||||
|
||||
if(strmatch(part[i], "multiline"))state.ws |= ES_MULTILINE;
|
||||
if(strmatch(part[i], "readonly"))state.ws |= ES_READONLY;
|
||||
if(!strcmp(part[i], "multiline"))state.ws |= ES_MULTILINE;
|
||||
if(!strcmp(part[i], "readonly"))state.ws |= ES_READONLY;
|
||||
|
||||
if(strmatch(part[i], "sunken"))state.es |= WS_EX_STATICEDGE;
|
||||
if(strmatch(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE;
|
||||
if(!strcmp(part[i], "sunken"))state.es |= WS_EX_STATICEDGE;
|
||||
if(!strcmp(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE;
|
||||
}
|
||||
|
||||
hwnd = CreateWindowEx(state.es, "EDIT", text, state.ws,
|
||||
|
||||
@@ -14,13 +14,13 @@ bool Groupbox::Create(Window *parent_window, const char *style, int x, int y, in
|
||||
stringarray part;
|
||||
ParseStyleParam(style, part);
|
||||
for(int i = 0; i < count(part); i++) {
|
||||
if(strmatch(part[i], "visible"))state.ws |= WS_VISIBLE;
|
||||
if(strmatch(part[i], "disabled"))state.ws |= WS_DISABLED;
|
||||
if(strmatch(part[i], "border"))state.ws |= WS_BORDER;
|
||||
if(strmatch(part[i], "raised"))state.ws |= WS_DLGFRAME;
|
||||
if(!strcmp(part[i], "visible"))state.ws |= WS_VISIBLE;
|
||||
if(!strcmp(part[i], "disabled"))state.ws |= WS_DISABLED;
|
||||
if(!strcmp(part[i], "border"))state.ws |= WS_BORDER;
|
||||
if(!strcmp(part[i], "raised"))state.ws |= WS_DLGFRAME;
|
||||
|
||||
if(strmatch(part[i], "sunken"))state.es |= WS_EX_STATICEDGE;
|
||||
if(strmatch(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE;
|
||||
if(!strcmp(part[i], "sunken"))state.es |= WS_EX_STATICEDGE;
|
||||
if(!strcmp(part[i], "edge"))state.es |= WS_EX_CLIENTEDGE;
|
||||
}
|
||||
|
||||
hwnd = CreateWindowEx(state.es, "BUTTON", text, state.ws,
|
||||
|
||||
Loaded 100 of 194 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user