mirror of https://github.com/bsnes-emu/bsnes.git
Update to v085r03 release.
byuu says: Changelog: - fixed cursor being visible under Metacity window manager (hopefully doesn't cause regression with other WMs) - show normal cursor when using SDL video driver - added menu accelerators (meh, why not?) - removed debugvirtual, ChipDebugger and chip/debugger functionality entirely - alt/smp disassembler moved up - fixed alt/smp incw/decw instructions (unsigned->uint16 for internal variables) My plan going forward for a debugger is not to hardcode functionality that causes the 10-15% slowdown right into the emulator itself. Instead, I'm going to make a callback class, which will be a specialized version of nall::function: - can call function even if not assigned (results in no-op, return type must have a trivial default constructor) - if compiled without #define DEBUGGER, the entire thing turns into a huge no-op; and will be eliminated entirely when compiled - strategically place the functions: cb_step, cb_read, cb_write, etc. From here, the ui-debugger GUI will bind the callbacks, implement breakpoint checking, usage table generation, etc itself. I'll probably have to add some breakout commands to exit the emulation core prior to a frame event in some cases as well. I didn't initially want any debugger-related stuff in the base cores, but the #if debugger sCPUDebugger #else sCPU #endif stuff was already more of a burden than this will be.
This commit is contained in:
parent
e4e50308d2
commit
892bb3ab01
|
@ -14,7 +14,7 @@ static string iNES(const uint8_t *data, unsigned size) {
|
|||
unsigned prgram = 0;
|
||||
unsigned chrram = chrrom == 0 ? 8192 : 0;
|
||||
|
||||
print("iNES mapper: ", mapper, "\n");
|
||||
//print("iNES mapper: ", mapper, "\n");
|
||||
|
||||
output.append("<?xml version='1.0' encoding='UTF-8'?>\n");
|
||||
output.append("<cartridge>\n");
|
||||
|
@ -151,7 +151,7 @@ static string iNES(const uint8_t *data, unsigned size) {
|
|||
"</cartridge>\n"
|
||||
);
|
||||
|
||||
print(output, "\n");
|
||||
//print(output, "\n");
|
||||
|
||||
return output;
|
||||
}
|
||||
|
|
|
@ -2,10 +2,6 @@ void pAction::setEnabled(bool enabled) {
|
|||
gtk_widget_set_sensitive(widget, enabled);
|
||||
}
|
||||
|
||||
void pAction::setFont(const string &font) {
|
||||
pFont::setFont(widget, font);
|
||||
}
|
||||
|
||||
void pAction::setVisible(bool visible) {
|
||||
gtk_widget_set_visible(widget, visible);
|
||||
}
|
||||
|
@ -15,3 +11,17 @@ void pAction::constructor() {
|
|||
|
||||
void pAction::orphan() {
|
||||
}
|
||||
|
||||
//GTK+ uses _ for mnemonics, __ for _
|
||||
//transform so that & is used for mnemonics, && for &
|
||||
string pAction::mnemonic(string text) {
|
||||
text.transform("&_", "\x01\x02");
|
||||
text.replace("\x01\x01", "&");
|
||||
text.transform("\x01", "_");
|
||||
text.replace("\x02", "__");
|
||||
return text;
|
||||
}
|
||||
|
||||
void pAction::setFont(const string &font) {
|
||||
pFont::setFont(widget, font);
|
||||
}
|
||||
|
|
|
@ -13,12 +13,13 @@ void pCheckItem::setChecked(bool checked) {
|
|||
}
|
||||
|
||||
void pCheckItem::setText(const string &text) {
|
||||
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), text);
|
||||
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), mnemonic(text));
|
||||
}
|
||||
|
||||
void pCheckItem::constructor() {
|
||||
widget = gtk_check_menu_item_new_with_label(checkItem.state.text);
|
||||
widget = gtk_check_menu_item_new_with_mnemonic("");
|
||||
setChecked(checkItem.state.checked);
|
||||
setText(checkItem.state.text);
|
||||
g_signal_connect_swapped(G_OBJECT(widget), "toggled", G_CALLBACK(CheckItem_toggle), (gpointer)&checkItem);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,13 @@ void pItem::setImage(const image &image) {
|
|||
}
|
||||
|
||||
void pItem::setText(const string &text) {
|
||||
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), text);
|
||||
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), mnemonic(text));
|
||||
}
|
||||
|
||||
void pItem::constructor() {
|
||||
widget = gtk_image_menu_item_new_with_label(item.state.text);
|
||||
widget = gtk_image_menu_item_new_with_mnemonic("");
|
||||
g_signal_connect_swapped(G_OBJECT(widget), "activate", G_CALLBACK(Item_activate), (gpointer)&item);
|
||||
setText(item.state.text);
|
||||
}
|
||||
|
||||
void pItem::destructor() {
|
||||
|
|
|
@ -19,13 +19,14 @@ void pMenu::setImage(const image &image) {
|
|||
}
|
||||
|
||||
void pMenu::setText(const string &text) {
|
||||
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), text);
|
||||
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), mnemonic(text));
|
||||
}
|
||||
|
||||
void pMenu::constructor() {
|
||||
gtkMenu = gtk_menu_new();
|
||||
widget = gtk_image_menu_item_new_with_label(menu.state.text);
|
||||
widget = gtk_image_menu_item_new_with_mnemonic("");
|
||||
gtk_menu_item_set_submenu(GTK_MENU_ITEM(widget), gtkMenu);
|
||||
setText(menu.state.text);
|
||||
}
|
||||
|
||||
void pMenu::destructor() {
|
||||
|
|
|
@ -25,12 +25,13 @@ void pRadioItem::setGroup(const array<RadioItem&> &group) {
|
|||
}
|
||||
|
||||
void pRadioItem::setText(const string &text) {
|
||||
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), text);
|
||||
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), mnemonic(text));
|
||||
}
|
||||
|
||||
void pRadioItem::constructor() {
|
||||
widget = gtk_radio_menu_item_new_with_label(0, radioItem.state.text);
|
||||
widget = gtk_radio_menu_item_new_with_mnemonic(0, "");
|
||||
setGroup(radioItem.state.group);
|
||||
setText(radioItem.state.text);
|
||||
for(auto &item : radioItem.state.group) {
|
||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item.p.widget), item.state.checked);
|
||||
}
|
||||
|
|
|
@ -141,6 +141,7 @@ struct pAction : public pObject {
|
|||
pAction(Action &action) : pObject(action), action(action) {}
|
||||
void constructor();
|
||||
virtual void orphan();
|
||||
string mnemonic(string text);
|
||||
virtual void setFont(const string &font);
|
||||
};
|
||||
|
||||
|
|
|
@ -168,13 +168,11 @@ void pWindow::setFullScreen(bool fullScreen) {
|
|||
if(fullScreen == false) {
|
||||
gtk_window_unfullscreen(GTK_WINDOW(widget));
|
||||
gtk_window_set_resizable(GTK_WINDOW(widget), window.state.resizable);
|
||||
gtk_window_set_decorated(GTK_WINDOW(widget), true);
|
||||
gtk_widget_set_size_request(widget, -1, -1);
|
||||
gdk_display_sync(gtk_widget_get_display(widget));
|
||||
setGeometry(window.state.geometry);
|
||||
} else {
|
||||
gtk_window_fullscreen(GTK_WINDOW(widget));
|
||||
gtk_window_set_decorated(GTK_WINDOW(widget), false);
|
||||
gtk_widget_set_size_request(widget, Desktop::size().width, Desktop::size().height);
|
||||
gtk_window_set_resizable(GTK_WINDOW(widget), false);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/****************************************************************************
|
||||
** Meta object code from reading C++ file 'platform.moc.hpp'
|
||||
**
|
||||
** Created: Mon Jan 23 13:07:40 2012
|
||||
** Created: Thu Feb 2 17:56:05 2012
|
||||
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.3)
|
||||
**
|
||||
** WARNING! All changes made in this file will be lost!
|
||||
|
|
|
@ -115,6 +115,7 @@ public:
|
|||
|
||||
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
||||
screen = SDL_SetVideoMode(2560, 1600, 32, SDL_HWSURFACE);
|
||||
XUndefineCursor(display, settings.handle);
|
||||
|
||||
buffer = 0;
|
||||
iwidth = 0;
|
||||
|
|
|
@ -3,12 +3,7 @@
|
|||
#define CPU_CPP
|
||||
namespace SNES {
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.cpp"
|
||||
CPUDebugger cpu;
|
||||
#else
|
||||
CPU cpu;
|
||||
#endif
|
||||
CPU cpu;
|
||||
|
||||
#include "serialization.cpp"
|
||||
#include "dma.cpp"
|
||||
|
|
|
@ -19,8 +19,8 @@ public:
|
|||
void mmio_write(unsigned addr, uint8 data);
|
||||
|
||||
void op_io();
|
||||
debugvirtual uint8 op_read(unsigned addr);
|
||||
debugvirtual void op_write(unsigned addr, uint8 data);
|
||||
uint8 op_read(unsigned addr);
|
||||
void op_write(unsigned addr, uint8 data);
|
||||
|
||||
void enter();
|
||||
void enable();
|
||||
|
@ -34,7 +34,7 @@ public:
|
|||
private:
|
||||
//cpu
|
||||
static void Enter();
|
||||
debugvirtual void op_step();
|
||||
void op_step();
|
||||
|
||||
//timing
|
||||
struct QueueEvent {
|
||||
|
@ -145,13 +145,6 @@ private:
|
|||
uint8 joy3l, joy3h;
|
||||
uint8 joy4l, joy4h;
|
||||
} status;
|
||||
|
||||
friend class CPUDebugger;
|
||||
};
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.hpp"
|
||||
extern CPUDebugger cpu;
|
||||
#else
|
||||
extern CPU cpu;
|
||||
#endif
|
||||
extern CPU cpu;
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
#ifdef CPU_CPP
|
||||
|
||||
void CPUDebugger::op_step() {
|
||||
bool break_event = false;
|
||||
|
||||
usage[regs.pc] &= ~(UsageFlagM | UsageFlagX);
|
||||
usage[regs.pc] |= UsageExec | (regs.p.m << 1) | (regs.p.x << 0);
|
||||
opcode_pc = regs.pc;
|
||||
|
||||
opcode_edge = true;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Exec, regs.pc, 0x00);
|
||||
if(step_event && step_event()) {
|
||||
debugger.break_event = Debugger::BreakEvent::CPUStep;
|
||||
scheduler.exit(Scheduler::ExitReason::DebuggerEvent);
|
||||
}
|
||||
opcode_edge = false;
|
||||
|
||||
CPU::op_step();
|
||||
synchronize_smp();
|
||||
}
|
||||
|
||||
uint8 CPUDebugger::op_read(uint32 addr) {
|
||||
uint8 data = CPU::op_read(addr);
|
||||
usage[addr] |= UsageRead;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Read, addr, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void CPUDebugger::op_write(uint32 addr, uint8 data) {
|
||||
CPU::op_write(addr, data);
|
||||
usage[addr] |= UsageWrite;
|
||||
usage[addr] &= ~UsageExec;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Write, addr, data);
|
||||
}
|
||||
|
||||
CPUDebugger::CPUDebugger() {
|
||||
usage = new uint8[1 << 24]();
|
||||
opcode_pc = 0x8000;
|
||||
opcode_edge = false;
|
||||
}
|
||||
|
||||
CPUDebugger::~CPUDebugger() {
|
||||
delete[] usage;
|
||||
}
|
||||
|
||||
bool CPUDebugger::property(unsigned id, string &name, string &value) {
|
||||
unsigned n = 0;
|
||||
|
||||
#define item(name_, value_) \
|
||||
if(id == n++) { \
|
||||
name = name_; \
|
||||
value = value_; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
//internal
|
||||
item("S-CPU MDR", string("0x", hex<2>(regs.mdr)));
|
||||
|
||||
//$2181-2183
|
||||
item("$2181-$2183", "");
|
||||
item("WRAM Address", string("0x", hex<6>(status.wram_addr)));
|
||||
|
||||
//$4016
|
||||
item("$4016", "");
|
||||
item("Joypad Strobe Latch", status.joypad_strobe_latch);
|
||||
|
||||
//$4200
|
||||
item("$4200", "");
|
||||
item("NMI Enable", status.nmi_enabled);
|
||||
item("H-IRQ Enable", status.hirq_enabled);
|
||||
item("V-IRQ Enable", status.virq_enabled);
|
||||
item("Auto Joypad Poll", status.auto_joypad_poll_enabled);
|
||||
|
||||
//$4201
|
||||
item("$4201", "");
|
||||
item("PIO", string("0x", hex<2>(status.pio)));
|
||||
|
||||
//$4202
|
||||
item("$4202", "");
|
||||
item("Multiplicand", string("0x", hex<2>(status.wrmpya)));
|
||||
|
||||
//$4203
|
||||
item("$4203", "");
|
||||
item("Multiplier", string("0x", hex<2>(status.wrmpyb)));
|
||||
|
||||
//$4204-$4205
|
||||
item("$4204-$4205", "");
|
||||
item("Dividend", string("0x", hex<4>(status.wrdiva)));
|
||||
|
||||
//$4206
|
||||
item("$4206", "");
|
||||
item("Divisor", string("0x", hex<2>(status.wrdivb)));
|
||||
|
||||
//$4207-$4208
|
||||
item("$4207-$4208", "");
|
||||
item("H-Time", string("0x", hex<4>(status.htime)));
|
||||
|
||||
//$4209-$420a
|
||||
item("$4209-$420a", "");
|
||||
item("V-Time", string("0x", hex<4>(status.vtime)));
|
||||
|
||||
//$420b
|
||||
unsigned dma_enable = 0;
|
||||
for(unsigned n = 0; n < 8; n++) dma_enable |= channel[n].dma_enabled << n;
|
||||
|
||||
item("$420b", "");
|
||||
item("DMA Enable", string("0x", hex<2>(dma_enable)));
|
||||
|
||||
//$420c
|
||||
unsigned hdma_enable = 0;
|
||||
for(unsigned n = 0; n < 8; n++) hdma_enable |= channel[n].hdma_enabled << n;
|
||||
|
||||
item("$420c", "");
|
||||
item("HDMA Enable", string("0x", hex<2>(hdma_enable)));
|
||||
|
||||
//$420d
|
||||
item("$420d", "");
|
||||
item("FastROM Enable", status.rom_speed == 6);
|
||||
|
||||
for(unsigned i = 0; i < 8; i++) {
|
||||
item(string("DMA Channel ", i), "");
|
||||
|
||||
//$43x0
|
||||
item("Direction", channel[i].direction);
|
||||
item("Indirect", channel[i].indirect);
|
||||
item("Reverse Transfer", channel[i].reverse_transfer);
|
||||
item("Fixed Transfer", channel[i].fixed_transfer);
|
||||
item("Transfer Mode", (unsigned)channel[i].transfer_mode);
|
||||
|
||||
//$43x1
|
||||
item("B-Bus Address", string("0x", hex<4>(channel[i].dest_addr)));
|
||||
|
||||
//$43x2-$43x3
|
||||
item("A-Bus Address", string("0x", hex<4>(channel[i].source_addr)));
|
||||
|
||||
//$43x4
|
||||
item("A-Bus Bank", string("0x", hex<2>(channel[i].source_bank)));
|
||||
|
||||
//$43x5-$43x6
|
||||
item("Transfer Size / Indirect Address", string("0x", hex<4>(channel[i].transfer_size)));
|
||||
|
||||
//$43x7
|
||||
item("Indirect Bank", string("0x", hex<2>(channel[i].indirect_bank)));
|
||||
|
||||
//$43x8-$43x9
|
||||
item("Table Address", string("0x", hex<4>(channel[i].hdma_addr)));
|
||||
|
||||
//$43xa
|
||||
item("Line Counter", string("0x", hex<2>(channel[i].line_counter)));
|
||||
}
|
||||
|
||||
#undef item
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,24 +0,0 @@
|
|||
class CPUDebugger : public CPU, public ChipDebugger {
|
||||
public:
|
||||
bool property(unsigned id, string &name, string &value);
|
||||
|
||||
function<bool ()> step_event;
|
||||
|
||||
enum Usage {
|
||||
UsageRead = 0x80,
|
||||
UsageWrite = 0x40,
|
||||
UsageExec = 0x20,
|
||||
UsageFlagM = 0x02,
|
||||
UsageFlagX = 0x01,
|
||||
};
|
||||
uint8 *usage;
|
||||
uint32 opcode_pc;
|
||||
bool opcode_edge;
|
||||
|
||||
void op_step();
|
||||
uint8 op_read(uint32 addr);
|
||||
void op_write(uint32 addr, uint8 data);
|
||||
|
||||
CPUDebugger();
|
||||
~CPUDebugger();
|
||||
};
|
|
@ -1,6 +1,6 @@
|
|||
#include "SPC_DSP.h"
|
||||
|
||||
class DSP : public Processor, public ChipDebugger {
|
||||
class DSP : public Processor {
|
||||
public:
|
||||
enum : bool { Threaded = false };
|
||||
alwaysinline void step(unsigned clocks);
|
||||
|
@ -16,7 +16,6 @@ public:
|
|||
void channel_enable(unsigned channel, bool enable);
|
||||
|
||||
void serialize(serializer&);
|
||||
bool property(unsigned id, string &name, string &value) { return false; }
|
||||
DSP();
|
||||
|
||||
private:
|
||||
|
|
|
@ -1,349 +0,0 @@
|
|||
#ifdef PPU_CPP
|
||||
|
||||
uint8 PPUDebugger::vram_mmio_read(uint16 addr) {
|
||||
uint8 data = PPU::vram_mmio_read(addr);
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::VRAM, Debugger::Breakpoint::Mode::Read, addr, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void PPUDebugger::vram_mmio_write(uint16 addr, uint8 data) {
|
||||
PPU::vram_mmio_write(addr, data);
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::VRAM, Debugger::Breakpoint::Mode::Write, addr, data);
|
||||
}
|
||||
|
||||
uint8 PPUDebugger::oam_mmio_read(uint16 addr) {
|
||||
uint8 data = PPU::oam_mmio_read(addr);
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::OAM, Debugger::Breakpoint::Mode::Read, addr, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void PPUDebugger::oam_mmio_write(uint16 addr, uint8 data) {
|
||||
PPU::oam_mmio_write(addr, data);
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::OAM, Debugger::Breakpoint::Mode::Write, addr, data);
|
||||
}
|
||||
|
||||
uint8 PPUDebugger::cgram_mmio_read(uint16 addr) {
|
||||
uint8 data = PPU::cgram_mmio_read(addr);
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::CGRAM, Debugger::Breakpoint::Mode::Read, addr, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void PPUDebugger::cgram_mmio_write(uint16 addr, uint8 data) {
|
||||
PPU::cgram_mmio_write(addr, data);
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::CGRAM, Debugger::Breakpoint::Mode::Write, addr, data);
|
||||
}
|
||||
|
||||
PPUDebugger::PPUDebugger() {
|
||||
}
|
||||
|
||||
bool PPUDebugger::property(unsigned id, string &name, string &value) {
|
||||
unsigned n = 0;
|
||||
|
||||
#define item(name_, value_) \
|
||||
if(id == n++) { \
|
||||
name = name_; \
|
||||
value = value_; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
//internal
|
||||
item("S-PPU1 MDR", string("0x", hex<2>(regs.ppu1_mdr)));
|
||||
item("S-PPU2 MDR", string("0x", hex<2>(regs.ppu2_mdr)));
|
||||
|
||||
//$2100
|
||||
item("$2100", "");
|
||||
item("Display Disable", regs.display_disabled);
|
||||
item("Display Brightness", (unsigned)regs.display_brightness);
|
||||
|
||||
//$2101
|
||||
item("$2101", "");
|
||||
item("OAM Base Size", (unsigned)regs.oam_basesize);
|
||||
item("OAM Name Select", (unsigned)regs.oam_nameselect);
|
||||
item("OAM Name Base Address", string("0x", hex<4>(regs.oam_tdaddr)));
|
||||
|
||||
//$2102-$2103
|
||||
item("$2102-$2103", "");
|
||||
item("OAM Base Address", string("0x", hex<4>(regs.oam_baseaddr)));
|
||||
item("OAM Priority", regs.oam_priority);
|
||||
|
||||
//$2105
|
||||
item("$2105", "");
|
||||
item("BG1 Tile Size", regs.bg_tilesize[BG1] ? "16x16" : "8x8");
|
||||
item("BG2 Tile Size", regs.bg_tilesize[BG2] ? "16x16" : "8x8");
|
||||
item("BG3 Tile Size", regs.bg_tilesize[BG3] ? "16x16" : "8x8");
|
||||
item("BG4 Tile Size", regs.bg_tilesize[BG4] ? "16x16" : "8x8");
|
||||
item("BG3 Priority", regs.bg3_priority);
|
||||
item("BG Mode", (unsigned)regs.bg_mode);
|
||||
|
||||
//$2106
|
||||
item("$2106", "");
|
||||
item("Mosaic Size", (unsigned)regs.mosaic_size);
|
||||
item("BG1 Mosaic Enable", regs.mosaic_enabled[BG1]);
|
||||
item("BG2 Mosaic Enable", regs.mosaic_enabled[BG2]);
|
||||
item("BG3 Mosaic Enable", regs.mosaic_enabled[BG3]);
|
||||
item("BG4 Mosaic Enable", regs.mosaic_enabled[BG4]);
|
||||
|
||||
static char screen_size[4][8] = { "32x32", "32x64", "64x32", "64x64" };
|
||||
|
||||
//$2107
|
||||
item("$2107", "");
|
||||
item("BG1 Screen Address", string("0x", hex<4>(regs.bg_scaddr[BG1])));
|
||||
item("BG1 Screen Size", screen_size[regs.bg_scsize[BG1]]);
|
||||
|
||||
//$2108
|
||||
item("$2108", "");
|
||||
item("BG2 Screen Address", string("0x", hex<4>(regs.bg_scaddr[BG2])));
|
||||
item("BG2 Screen Size", screen_size[regs.bg_scsize[BG2]]);
|
||||
|
||||
//$2109
|
||||
item("$2109", "");
|
||||
item("BG3 Screen Address", string("0x", hex<4>(regs.bg_scaddr[BG3])));
|
||||
item("BG3 Screen Size", screen_size[regs.bg_scsize[BG3]]);
|
||||
|
||||
//$210a
|
||||
item("$210a", "");
|
||||
item("BG4 Screen Address", string("0x", hex<4>(regs.bg_scaddr[BG4])));
|
||||
item("BG4 Screen Size", screen_size[regs.bg_scsize[BG4]]);
|
||||
|
||||
//$210b
|
||||
item("$210b", "");
|
||||
item("BG1 Name Base Address", string("0x", hex<4>(regs.bg_tdaddr[BG1])));
|
||||
item("BG2 Name Base Address", string("0x", hex<4>(regs.bg_tdaddr[BG2])));
|
||||
|
||||
//$210c
|
||||
item("$210c", "");
|
||||
item("BG3 Name Base Address", string("0x", hex<4>(regs.bg_tdaddr[BG3])));
|
||||
item("BG4 Name Base Address", string("0x", hex<4>(regs.bg_tdaddr[BG4])));
|
||||
|
||||
//$210d
|
||||
item("$210d", "");
|
||||
item("Mode 7 Scroll H-offset", (unsigned)(regs.m7_hofs & 0x1fff));
|
||||
item("BG1 Scroll H-offset", (unsigned)(regs.bg_hofs[BG1] & 0x03ff));
|
||||
|
||||
//$210e
|
||||
item("$210e", "");
|
||||
item("Mode 7 Scroll V-offset", (unsigned)(regs.m7_vofs & 0x1fff));
|
||||
item("BG1 Scroll V-offset", (unsigned)(regs.bg_vofs[BG1] & 0x03ff));
|
||||
|
||||
//$210f
|
||||
item("$210f", "");
|
||||
item("BG2 Scroll H-offset", (unsigned)(regs.bg_hofs[BG2] & 0x03ff));
|
||||
|
||||
//$2110
|
||||
item("$2110", "");
|
||||
item("BG2 Scroll V-offset", (unsigned)(regs.bg_vofs[BG2] & 0x03ff));
|
||||
|
||||
//$2111
|
||||
item("$2111", "");
|
||||
item("BG3 Scroll H-offset", (unsigned)(regs.bg_hofs[BG3] & 0x03ff));
|
||||
|
||||
//$2112
|
||||
item("$2112", "");
|
||||
item("BG3 Scroll V-offset", (unsigned)(regs.bg_vofs[BG3] & 0x03ff));
|
||||
|
||||
//$2113
|
||||
item("$2113", "");
|
||||
item("BG4 Scroll H-offset", (unsigned)(regs.bg_hofs[BG4] & 0x03ff));
|
||||
|
||||
//$2114
|
||||
item("$2114", "");
|
||||
item("BG4 Scroll V-offset", (unsigned)(regs.bg_vofs[BG4] & 0x03ff));
|
||||
|
||||
//$2115
|
||||
item("$2115", "");
|
||||
item("VRAM Increment Mode", (unsigned)regs.vram_incmode);
|
||||
item("VRAM Increment Formation", (unsigned)regs.vram_mapping);
|
||||
item("VRAM Increment Size", (unsigned)regs.vram_incsize);
|
||||
|
||||
//$2116-$2117
|
||||
item("$2116-$2117", "");
|
||||
item("VRAM Address", string("0x", hex<4>(regs.vram_addr)));
|
||||
|
||||
//$211a
|
||||
item("$211a", "");
|
||||
item("Mode 7 Repeat", (unsigned)regs.mode7_repeat);
|
||||
item("Mode 7 V-flip", regs.mode7_vflip);
|
||||
item("Mode 7 H-flip", regs.mode7_hflip);
|
||||
|
||||
//$211b
|
||||
item("$211b", "");
|
||||
item("Mode 7 A", (unsigned)regs.m7a);
|
||||
|
||||
//$211c
|
||||
item("$211c", "");
|
||||
item("Mode 7 B", (unsigned)regs.m7b);
|
||||
|
||||
//$211d
|
||||
item("$211d", "");
|
||||
item("Mode 7 C", (unsigned)regs.m7c);
|
||||
|
||||
//$211e
|
||||
item("$211e", "");
|
||||
item("Mode 7 D", (unsigned)regs.m7d);
|
||||
|
||||
//$211f
|
||||
item("$211f", "");
|
||||
item("Mode 7 X", (unsigned)regs.m7x);
|
||||
|
||||
//$2120
|
||||
item("$2120", "");
|
||||
item("Mode 7 Y", (unsigned)regs.m7y);
|
||||
|
||||
//$2121
|
||||
item("$2121", "");
|
||||
item("CGRAM Address", string("0x", hex<4>(regs.cgram_addr)));
|
||||
|
||||
//$2123
|
||||
item("$2123", "");
|
||||
item("BG1 Window 1 Enable", regs.window1_enabled[BG1]);
|
||||
item("BG1 Window 1 Invert", regs.window1_invert [BG1]);
|
||||
item("BG1 Window 2 Enable", regs.window2_enabled[BG1]);
|
||||
item("BG1 Window 2 Invert", regs.window2_invert [BG1]);
|
||||
item("BG2 Window 1 Enable", regs.window1_enabled[BG2]);
|
||||
item("BG2 Window 1 Invert", regs.window1_invert [BG2]);
|
||||
item("BG2 Window 2 Enable", regs.window2_enabled[BG2]);
|
||||
item("BG2 Window 2 Invert", regs.window2_invert [BG2]);
|
||||
|
||||
//$2124
|
||||
item("$2124", "");
|
||||
item("BG3 Window 1 Enable", regs.window1_enabled[BG3]);
|
||||
item("BG3 Window 1 Invert", regs.window1_invert [BG3]);
|
||||
item("BG3 Window 2 Enable", regs.window2_enabled[BG3]);
|
||||
item("BG3 Window 2 Invert", regs.window2_invert [BG3]);
|
||||
item("BG4 Window 1 Enable", regs.window1_enabled[BG4]);
|
||||
item("BG4 Window 1 Invert", regs.window1_invert [BG4]);
|
||||
item("BG4 Window 2 Enable", regs.window2_enabled[BG4]);
|
||||
item("BG4 Window 2 Invert", regs.window2_invert [BG4]);
|
||||
|
||||
//$2125
|
||||
item("$2125", "");
|
||||
item("OAM Window 1 Enable", regs.window1_enabled[OAM]);
|
||||
item("OAM Window 1 Invert", regs.window1_invert [OAM]);
|
||||
item("OAM Window 2 Enable", regs.window2_enabled[OAM]);
|
||||
item("OAM Window 2 Invert", regs.window2_invert [OAM]);
|
||||
item("Color Window 1 Enable", regs.window1_enabled[COL]);
|
||||
item("Color Window 1 Invert", regs.window1_invert [COL]);
|
||||
item("Color Window 2 Enable", regs.window2_enabled[COL]);
|
||||
item("Color Window 2 Invert", regs.window2_enabled[COL]);
|
||||
|
||||
//$2126
|
||||
item("$2126", "");
|
||||
item("Window 1 Left", (unsigned)regs.window1_left);
|
||||
|
||||
//$2127
|
||||
item("$2127", "");
|
||||
item("Window 1 Right", (unsigned)regs.window1_right);
|
||||
|
||||
//$2128
|
||||
item("$2128", "");
|
||||
item("Window 2 Left", (unsigned)regs.window2_left);
|
||||
|
||||
//$2129
|
||||
item("$2129", "");
|
||||
item("Window 2 Right", (unsigned)regs.window2_right);
|
||||
|
||||
static char window_mask_mode[4][8] = { "OR", "AND", "XOR", "XNOR" };
|
||||
|
||||
//$212a
|
||||
item("$212a", "");
|
||||
item("BG1 Window Mask", window_mask_mode[regs.window_mask[BG1]]);
|
||||
item("BG2 Window Mask", window_mask_mode[regs.window_mask[BG2]]);
|
||||
item("BG3 Window Mask", window_mask_mode[regs.window_mask[BG3]]);
|
||||
item("BG4 Window Mask", window_mask_mode[regs.window_mask[BG4]]);
|
||||
|
||||
//$212b
|
||||
item("$212b", "");
|
||||
item("OAM Window Mask", window_mask_mode[regs.window_mask[OAM]]);
|
||||
item("Color Window Mask", window_mask_mode[regs.window_mask[COL]]);
|
||||
|
||||
//$212c
|
||||
item("$212c", "");
|
||||
item("BG1 Mainscreen Enable", regs.bg_enabled[BG1]);
|
||||
item("BG2 Mainscreen Enable", regs.bg_enabled[BG2]);
|
||||
item("BG3 Mainscreen Enable", regs.bg_enabled[BG3]);
|
||||
item("BG4 Mainscreen Enable", regs.bg_enabled[BG4]);
|
||||
item("OAM Mainscreen Enable", regs.bg_enabled[OAM]);
|
||||
|
||||
//$212d
|
||||
item("$212d", "");
|
||||
item("BG1 Subscreen Enable", regs.bgsub_enabled[BG1]);
|
||||
item("BG2 Subscreen Enable", regs.bgsub_enabled[BG2]);
|
||||
item("BG3 Subscreen Enable", regs.bgsub_enabled[BG3]);
|
||||
item("BG4 Subscreen Enable", regs.bgsub_enabled[BG4]);
|
||||
item("OAM Subscreen Enable", regs.bgsub_enabled[OAM]);
|
||||
|
||||
//$212e
|
||||
item("$212e", "");
|
||||
item("BG1 Mainscreen Window Enable", regs.window_enabled[BG1]);
|
||||
item("BG2 Mainscreen Window Enable", regs.window_enabled[BG2]);
|
||||
item("BG3 Mainscreen Window Enable", regs.window_enabled[BG3]);
|
||||
item("BG4 Mainscreen Window Enable", regs.window_enabled[BG4]);
|
||||
item("OAM Mainscreen Window Enable", regs.window_enabled[OAM]);
|
||||
|
||||
//$212f
|
||||
item("$212f", "");
|
||||
item("BG1 Subscreen Window Enable", regs.sub_window_enabled[BG1]);
|
||||
item("BG2 Subscreen Window Enable", regs.sub_window_enabled[BG2]);
|
||||
item("BG3 Subscreen Window Enable", regs.sub_window_enabled[BG3]);
|
||||
item("BG4 Subscreen Window Enable", regs.sub_window_enabled[BG4]);
|
||||
item("OAM Subscreen Window Enable", regs.sub_window_enabled[OAM]);
|
||||
|
||||
static char color_window_mask_mode[4][32] = { "Always", "Never", "Inside Window Only", "Outside Window Only" };
|
||||
|
||||
//$2130
|
||||
item("$2130", "");
|
||||
item("Color Mainscreen Window Mask", color_window_mask_mode[regs.color_mask]);
|
||||
item("Color Subscreen Window Mask", color_window_mask_mode[regs.colorsub_mask]);
|
||||
item("Color Add/Subtract Mode", !regs.addsub_mode ? "Fixed Color" : "Subscreen");
|
||||
item("Direct Color", regs.direct_color);
|
||||
|
||||
//$2131
|
||||
item("$2131", "");
|
||||
item("Color Mode", !regs.color_mode ? "Add" : "Subtract");
|
||||
item("Color Halve", regs.color_halve);
|
||||
item("BG1 Color Enable", regs.color_enabled[BG1]);
|
||||
item("BG2 Color Enable", regs.color_enabled[BG2]);
|
||||
item("BG3 Color Enable", regs.color_enabled[BG3]);
|
||||
item("BG4 Color Enable", regs.color_enabled[BG4]);
|
||||
item("OAM Color Enable", regs.color_enabled[OAM]);
|
||||
item("Back Color Enable", regs.color_enabled[BACK]);
|
||||
|
||||
//$2132
|
||||
item("$2132", "");
|
||||
item("Color Constant - Blue", (unsigned)regs.color_b);
|
||||
item("Color Constant - Green", (unsigned)regs.color_g);
|
||||
item("Color Constant - Red", (unsigned)regs.color_r);
|
||||
|
||||
//$2133
|
||||
item("$2133", "");
|
||||
item("Mode 7 EXTBG", regs.mode7_extbg);
|
||||
item("Pseudo Hires", regs.pseudo_hires);
|
||||
item("Overscan", regs.overscan);
|
||||
item("OAM Interlace", regs.oam_interlace);
|
||||
item("Interlace", regs.interlace);
|
||||
|
||||
//$213c
|
||||
item("$213c", "");
|
||||
item("H-counter", (unsigned)hcounter());
|
||||
|
||||
//$213d
|
||||
item("$213d", "");
|
||||
item("V-counter", (unsigned)vcounter());
|
||||
|
||||
//$213e
|
||||
item("$213e", "");
|
||||
item("Range Over", regs.range_over);
|
||||
item("Time Over", regs.time_over);
|
||||
item("S-PPU1 Version", (unsigned)ppu1_version);
|
||||
|
||||
//$213f
|
||||
item("$213f", "");
|
||||
item("Field", cpu.field());
|
||||
item("Region", !region ? "NTSC" : "PAL");
|
||||
item("S-PPU2 Version", (unsigned)ppu2_version);
|
||||
|
||||
#undef item
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,15 +0,0 @@
|
|||
class PPUDebugger : public PPU, public ChipDebugger {
|
||||
public:
|
||||
bool property(unsigned id, string &name, string &value);
|
||||
|
||||
uint8 vram_mmio_read(uint16 addr);
|
||||
void vram_mmio_write(uint16 addr, uint8 data);
|
||||
|
||||
uint8 oam_mmio_read(uint16 addr);
|
||||
void oam_mmio_write(uint16 addr, uint8 data);
|
||||
|
||||
uint8 cgram_mmio_read(uint16 addr);
|
||||
void cgram_mmio_write(uint16 addr, uint8 data);
|
||||
|
||||
PPUDebugger();
|
||||
};
|
|
@ -3,12 +3,7 @@
|
|||
#define PPU_CPP
|
||||
namespace SNES {
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.cpp"
|
||||
PPUDebugger ppu;
|
||||
#else
|
||||
PPU ppu;
|
||||
#endif
|
||||
PPU ppu;
|
||||
|
||||
#include "memory/memory.cpp"
|
||||
#include "mmio/mmio.cpp"
|
||||
|
|
|
@ -72,13 +72,6 @@ public:
|
|||
void serialize(serializer&);
|
||||
PPU();
|
||||
~PPU();
|
||||
|
||||
friend class PPUDebugger;
|
||||
};
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.hpp"
|
||||
extern PPUDebugger ppu;
|
||||
#else
|
||||
extern PPU ppu;
|
||||
#endif
|
||||
extern PPU ppu;
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
#ifdef PPU_CPP
|
||||
|
||||
bool PPU::display_disable() const { return r[0x00] & 0x80; }
|
||||
unsigned PPU::display_brightness() const { return r[0x00] & 0x0f; }
|
||||
|
||||
uint8 PPU::mmio_read(unsigned addr) {
|
||||
return cpu.regs.mdr;
|
||||
}
|
||||
|
||||
void PPU::mmio_write(unsigned addr, uint8 data) {
|
||||
r[addr & 0x3f] = data;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,81 +0,0 @@
|
|||
#include <snes/snes.hpp>
|
||||
|
||||
#define PPU_CPP
|
||||
namespace SNES {
|
||||
|
||||
#include "mmio.cpp"
|
||||
PPU ppu;
|
||||
|
||||
void PPU::latch_counters() {
|
||||
}
|
||||
|
||||
bool PPU::interlace() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PPU::overscan() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PPU::hires() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void PPU::enter() {
|
||||
scanline();
|
||||
clock += lineclocks();
|
||||
tick(lineclocks());
|
||||
}
|
||||
|
||||
void PPU::scanline() {
|
||||
if(vcounter() == 0) return frame();
|
||||
if(vcounter() > 224) return;
|
||||
}
|
||||
|
||||
void PPU::frame() {
|
||||
}
|
||||
|
||||
void PPU::enable() {
|
||||
bus.map(Bus::MapMode::Direct, 0x00, 0x3f, 0x2100, 0x213f, { &PPU::mmio_read, this }, { &PPU::mmio_write, this });
|
||||
bus.map(Bus::MapMode::Direct, 0x80, 0xbf, 0x2100, 0x213f, { &PPU::mmio_read, this }, { &PPU::mmio_write, this });
|
||||
}
|
||||
|
||||
void PPU::power() {
|
||||
for(unsigned n = 0; n < 512 * 480; n++) output[n] = rand() & ((1 << 19) - 1);
|
||||
|
||||
for(auto &n : vram) n = 0;
|
||||
for(auto &n : oam) n = 0;
|
||||
for(auto &n : cgram) n = 0;
|
||||
for(auto &n : r) n = 0;
|
||||
reset();
|
||||
}
|
||||
|
||||
void PPU::reset() {
|
||||
PPUcounter::reset();
|
||||
}
|
||||
|
||||
void PPUcounter::serialize(serializer &s) {
|
||||
s.integer(status.interlace);
|
||||
s.integer(status.field);
|
||||
s.integer(status.vcounter);
|
||||
s.integer(status.hcounter);
|
||||
|
||||
s.array(history.field);
|
||||
s.array(history.vcounter);
|
||||
s.array(history.hcounter);
|
||||
s.integer(history.index);
|
||||
}
|
||||
|
||||
void PPU::serialize(serializer &s) {
|
||||
}
|
||||
|
||||
PPU::PPU() {
|
||||
surface = new uint32[512 * 512];
|
||||
output = surface + 16 * 512;
|
||||
}
|
||||
|
||||
PPU::~PPU() {
|
||||
delete[] surface;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,40 +0,0 @@
|
|||
struct PPU : public Processor, public PPUcounter {
|
||||
uint8 vram[64 * 1024];
|
||||
uint8 oam[544];
|
||||
uint8 cgram[512];
|
||||
uint8 r[64];
|
||||
|
||||
enum : bool { Threaded = false };
|
||||
|
||||
void latch_counters();
|
||||
bool interlace() const;
|
||||
bool overscan() const;
|
||||
bool hires() const;
|
||||
|
||||
void enter();
|
||||
void enable();
|
||||
void power();
|
||||
void reset();
|
||||
|
||||
void scanline();
|
||||
void frame();
|
||||
|
||||
void serialize(serializer&);
|
||||
PPU();
|
||||
~PPU();
|
||||
|
||||
private:
|
||||
uint32 *surface;
|
||||
uint32 *output;
|
||||
|
||||
//mmio.cpp
|
||||
alwaysinline bool display_disable() const;
|
||||
alwaysinline unsigned display_brightness() const;
|
||||
|
||||
uint8 mmio_read(unsigned addr);
|
||||
void mmio_write(unsigned addr, uint8 data);
|
||||
|
||||
friend class Video;
|
||||
};
|
||||
|
||||
extern PPU ppu;
|
|
@ -1,7 +0,0 @@
|
|||
#ifdef PPU_CPP
|
||||
|
||||
bool PPUDebugger::property(unsigned id, string &name, string &value) {
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,4 +0,0 @@
|
|||
class PPUDebugger : public PPU, public ChipDebugger {
|
||||
public:
|
||||
bool property(unsigned id, string &name, string &value);
|
||||
};
|
|
@ -3,12 +3,7 @@
|
|||
#define PPU_CPP
|
||||
namespace SNES {
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.cpp"
|
||||
PPUDebugger ppu;
|
||||
#else
|
||||
PPU ppu;
|
||||
#endif
|
||||
PPU ppu;
|
||||
|
||||
#include "mmio/mmio.cpp"
|
||||
#include "window/window.cpp"
|
||||
|
|
|
@ -66,9 +66,4 @@ private:
|
|||
friend class Video;
|
||||
};
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.hpp"
|
||||
extern PPUDebugger ppu;
|
||||
#else
|
||||
extern PPU ppu;
|
||||
#endif
|
||||
extern PPU ppu;
|
||||
|
|
|
@ -1,75 +0,0 @@
|
|||
#ifdef SMP_CPP
|
||||
|
||||
void SMPDebugger::op_step() {
|
||||
bool break_event = false;
|
||||
|
||||
usage[regs.pc] |= UsageExec;
|
||||
opcode_pc = regs.pc;
|
||||
|
||||
opcode_edge = true;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Exec, regs.pc, 0x00);
|
||||
if(step_event && step_event() == true) {
|
||||
debugger.break_event = Debugger::BreakEvent::SMPStep;
|
||||
scheduler.exit(Scheduler::ExitReason::DebuggerEvent);
|
||||
}
|
||||
opcode_edge = false;
|
||||
|
||||
SMP::op_step();
|
||||
synchronize_cpu();
|
||||
}
|
||||
|
||||
uint8 SMPDebugger::op_read(uint16 addr) {
|
||||
uint8 data = SMP::op_read(addr);
|
||||
usage[addr] |= UsageRead;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Read, addr, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void SMPDebugger::op_write(uint16 addr, uint8 data) {
|
||||
SMP::op_write(addr, data);
|
||||
usage[addr] |= UsageWrite;
|
||||
usage[addr] &= ~UsageExec;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Write, addr, data);
|
||||
}
|
||||
|
||||
SMPDebugger::SMPDebugger() {
|
||||
usage = new uint8[1 << 16]();
|
||||
opcode_pc = 0xffc0;
|
||||
opcode_edge = false;
|
||||
}
|
||||
|
||||
SMPDebugger::~SMPDebugger() {
|
||||
delete[] usage;
|
||||
}
|
||||
|
||||
bool SMPDebugger::property(unsigned id, string &name, string &value) {
|
||||
unsigned n = 0;
|
||||
|
||||
#define item(name_, value_) \
|
||||
if(id == n++) { \
|
||||
name = name_; \
|
||||
value = value_; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
//$00f0
|
||||
item("$00f0", "");
|
||||
item("Clock Speed", (unsigned)status.clock_speed);
|
||||
item("Timers Enable", status.timers_enable);
|
||||
item("RAM Disable", status.ram_disable);
|
||||
item("RAM Writable", status.ram_writable);
|
||||
item("Timers Disable", status.timers_disable);
|
||||
|
||||
//$00f1
|
||||
item("$00f1", "");
|
||||
item("IPLROM Enable", status.iplrom_enable);
|
||||
|
||||
//$00f2
|
||||
item("$00f2", "");
|
||||
item("DSP Address", string("0x", hex<2>(status.dsp_addr)));
|
||||
|
||||
#undef item
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,27 +0,0 @@
|
|||
class SMPDebugger : public SMP, public ChipDebugger {
|
||||
public:
|
||||
bool property(unsigned id, string &name, string &value);
|
||||
|
||||
function<bool ()> step_event;
|
||||
|
||||
enum Usage {
|
||||
UsageRead = 0x80,
|
||||
UsageWrite = 0x40,
|
||||
UsageExec = 0x20,
|
||||
};
|
||||
uint8 *usage;
|
||||
uint16 opcode_pc;
|
||||
bool opcode_edge;
|
||||
|
||||
void op_step();
|
||||
uint8 op_read(uint16 addr);
|
||||
void op_write(uint16 addr, uint8 data);
|
||||
|
||||
SMPDebugger();
|
||||
~SMPDebugger();
|
||||
|
||||
//disassembler
|
||||
void disassemble_opcode(char *output, uint16 addr);
|
||||
inline uint8 disassemble_read(uint16 addr);
|
||||
inline uint16 relb(int8 offset, int op_len);
|
||||
};
|
|
@ -5,13 +5,8 @@
|
|||
#define SMP_CPP
|
||||
namespace SNES {
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.cpp"
|
||||
#include "debugger/disassembler.cpp"
|
||||
SMPDebugger smp;
|
||||
#else
|
||||
SMP smp;
|
||||
#endif
|
||||
#include "disassembler.cpp"
|
||||
SMP smp;
|
||||
|
||||
#include "algorithms.cpp"
|
||||
#include "core.cpp"
|
||||
|
|
|
@ -21,6 +21,8 @@ public:
|
|||
SMP();
|
||||
~SMP();
|
||||
|
||||
void disassemble_opcode(char *output, uint16 addr);
|
||||
|
||||
//private:
|
||||
struct Flags {
|
||||
bool n, v, p, b, h, i, z, c;
|
||||
|
@ -55,7 +57,7 @@ public:
|
|||
Flags p;
|
||||
} regs;
|
||||
|
||||
unsigned rd, wr, dp, sp, ya, bit;
|
||||
uint16 rd, wr, dp, sp, ya, bit;
|
||||
|
||||
struct Status {
|
||||
//$00f1
|
||||
|
@ -87,9 +89,9 @@ public:
|
|||
|
||||
void tick();
|
||||
alwaysinline void op_io();
|
||||
debugvirtual alwaysinline uint8 op_read(uint16 addr);
|
||||
debugvirtual alwaysinline void op_write(uint16 addr, uint8 data);
|
||||
debugvirtual alwaysinline void op_step();
|
||||
alwaysinline uint8 op_read(uint16 addr);
|
||||
alwaysinline void op_write(uint16 addr, uint8 data);
|
||||
alwaysinline void op_step();
|
||||
static const unsigned cycle_count_table[256];
|
||||
uint64 cycle_table_cpu[256];
|
||||
unsigned cycle_table_dsp[256];
|
||||
|
@ -112,9 +114,4 @@ public:
|
|||
uint8 op_ror (uint8 x);
|
||||
};
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.hpp"
|
||||
extern SMPDebugger smp;
|
||||
#else
|
||||
extern SMP smp;
|
||||
#endif
|
||||
extern SMP smp;
|
||||
|
|
|
@ -3,12 +3,7 @@
|
|||
#define CPU_CPP
|
||||
namespace SNES {
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.cpp"
|
||||
CPUDebugger cpu;
|
||||
#else
|
||||
CPU cpu;
|
||||
#endif
|
||||
CPU cpu;
|
||||
|
||||
#include "serialization.cpp"
|
||||
#include "dma/dma.cpp"
|
||||
|
|
|
@ -132,14 +132,7 @@ private:
|
|||
} alu;
|
||||
|
||||
static void Enter();
|
||||
debugvirtual void op_step();
|
||||
|
||||
friend class CPUDebugger;
|
||||
void op_step();
|
||||
};
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.hpp"
|
||||
extern CPUDebugger cpu;
|
||||
#else
|
||||
extern CPU cpu;
|
||||
#endif
|
||||
extern CPU cpu;
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
#ifdef CPU_CPP
|
||||
|
||||
void CPUDebugger::op_step() {
|
||||
bool break_event = false;
|
||||
|
||||
usage[regs.pc] &= ~(UsageFlagM | UsageFlagX);
|
||||
usage[regs.pc] |= UsageExec | (regs.p.m << 1) | (regs.p.x << 0);
|
||||
opcode_pc = regs.pc;
|
||||
|
||||
opcode_edge = true;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Exec, regs.pc, 0x00);
|
||||
if(step_event && step_event() == true) {
|
||||
debugger.break_event = Debugger::BreakEvent::CPUStep;
|
||||
scheduler.exit(Scheduler::ExitReason::DebuggerEvent);
|
||||
}
|
||||
opcode_edge = false;
|
||||
|
||||
CPU::op_step();
|
||||
synchronize_smp();
|
||||
}
|
||||
|
||||
uint8 CPUDebugger::op_read(uint32 addr) {
|
||||
uint8 data = CPU::op_read(addr);
|
||||
usage[addr] |= UsageRead;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Read, addr, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void CPUDebugger::op_write(uint32 addr, uint8 data) {
|
||||
CPU::op_write(addr, data);
|
||||
usage[addr] |= UsageWrite;
|
||||
usage[addr] &= ~UsageExec;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::CPUBus, Debugger::Breakpoint::Mode::Write, addr, data);
|
||||
}
|
||||
|
||||
CPUDebugger::CPUDebugger() {
|
||||
usage = new uint8[1 << 24]();
|
||||
opcode_pc = 0x8000;
|
||||
opcode_edge = false;
|
||||
}
|
||||
|
||||
CPUDebugger::~CPUDebugger() {
|
||||
delete[] usage;
|
||||
}
|
||||
|
||||
bool CPUDebugger::property(unsigned id, string &name, string &value) {
|
||||
unsigned n = 0;
|
||||
|
||||
#define item(name_, value_) \
|
||||
if(id == n++) { \
|
||||
name = name_; \
|
||||
value = value_; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
//internal
|
||||
item("S-CPU MDR", string("0x", hex<2>(regs.mdr)));
|
||||
|
||||
//$2181-2183
|
||||
item("$2181-$2183", "");
|
||||
item("WRAM Address", string("0x", hex<6>(status.wram_addr)));
|
||||
|
||||
//$4016
|
||||
item("$4016", "");
|
||||
item("Joypad Strobe Latch", status.joypad_strobe_latch);
|
||||
|
||||
//$4200
|
||||
item("$4200", "");
|
||||
item("NMI Enable", status.nmi_enabled);
|
||||
item("H-IRQ Enable", status.hirq_enabled);
|
||||
item("V-IRQ Enable", status.virq_enabled);
|
||||
item("Auto Joypad Poll", status.auto_joypad_poll);
|
||||
|
||||
//$4201
|
||||
item("$4201", "");
|
||||
item("PIO", string("0x", hex<2>(status.pio)));
|
||||
|
||||
//$4202
|
||||
item("$4202", "");
|
||||
item("Multiplicand", string("0x", hex<2>(status.wrmpya)));
|
||||
|
||||
//$4203
|
||||
item("$4203", "");
|
||||
item("Multiplier", string("0x", hex<2>(status.wrmpyb)));
|
||||
|
||||
//$4204-$4205
|
||||
item("$4204-$4205", "");
|
||||
item("Dividend", string("0x", hex<4>(status.wrdiva)));
|
||||
|
||||
//$4206
|
||||
item("$4206", "");
|
||||
item("Divisor", string("0x", hex<2>(status.wrdivb)));
|
||||
|
||||
//$4207-$4208
|
||||
item("$4207-$4208", "");
|
||||
item("H-Time", string("0x", hex<4>(status.hirq_pos)));
|
||||
|
||||
//$4209-$420a
|
||||
item("$4209-$420a", "");
|
||||
item("V-Time", string("0x", hex<4>(status.virq_pos)));
|
||||
|
||||
//$420b
|
||||
unsigned dma_enable = 0;
|
||||
for(unsigned n = 0; n < 8; n++) dma_enable |= channel[n].dma_enabled << n;
|
||||
|
||||
item("$420b", "");
|
||||
item("DMA Enable", string("0x", hex<2>(dma_enable)));
|
||||
|
||||
//$420c
|
||||
unsigned hdma_enable = 0;
|
||||
for(unsigned n = 0; n < 8; n++) hdma_enable |= channel[n].hdma_enabled << n;
|
||||
|
||||
item("$420c", "");
|
||||
item("HDMA Enable", string("0x", hex<2>(hdma_enable)));
|
||||
|
||||
//$420d
|
||||
item("$420d", "");
|
||||
item("FastROM Enable", status.rom_speed == 6);
|
||||
|
||||
for(unsigned i = 0; i < 8; i++) {
|
||||
item(string("DMA Channel ", i), "");
|
||||
|
||||
//$43x0
|
||||
item("Direction", channel[i].direction);
|
||||
item("Indirect", channel[i].indirect);
|
||||
item("Reverse Transfer", channel[i].reverse_transfer);
|
||||
item("Fixed Transfer", channel[i].fixed_transfer);
|
||||
item("Transfer Mode", (unsigned)channel[i].transfer_mode);
|
||||
|
||||
//$43x1
|
||||
item("B-Bus Address", string("0x", hex<4>(channel[i].dest_addr)));
|
||||
|
||||
//$43x2-$43x3
|
||||
item("A-Bus Address", string("0x", hex<4>(channel[i].source_addr)));
|
||||
|
||||
//$43x4
|
||||
item("A-Bus Bank", string("0x", hex<2>(channel[i].source_bank)));
|
||||
|
||||
//$43x5-$43x6
|
||||
item("Transfer Size / Indirect Address", string("0x", hex<4>(channel[i].transfer_size)));
|
||||
|
||||
//$43x7
|
||||
item("Indirect Bank", string("0x", hex<2>(channel[i].indirect_bank)));
|
||||
|
||||
//$43x8-$43x9
|
||||
item("Table Address", string("0x", hex<4>(channel[i].hdma_addr)));
|
||||
|
||||
//$43xa
|
||||
item("Line Counter", string("0x", hex<2>(channel[i].line_counter)));
|
||||
}
|
||||
|
||||
#undef item
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,24 +0,0 @@
|
|||
class CPUDebugger : public CPU, public ChipDebugger {
|
||||
public:
|
||||
bool property(unsigned id, string &name, string &value);
|
||||
|
||||
function<bool ()> step_event;
|
||||
|
||||
enum Usage {
|
||||
UsageRead = 0x80,
|
||||
UsageWrite = 0x40,
|
||||
UsageExec = 0x20,
|
||||
UsageFlagM = 0x02,
|
||||
UsageFlagX = 0x01,
|
||||
};
|
||||
uint8 *usage;
|
||||
uint24 opcode_pc; //points to the current opcode, used to backtrace on read/write breakpoints
|
||||
bool opcode_edge; //true right before an opcode execues, used to skip over opcodes
|
||||
|
||||
void op_step();
|
||||
uint8 op_read(uint32 addr);
|
||||
void op_write(uint32 addr, uint8 data);
|
||||
|
||||
CPUDebugger();
|
||||
~CPUDebugger();
|
||||
};
|
|
@ -1,4 +1,4 @@
|
|||
void op_io();
|
||||
debugvirtual uint8 op_read(uint32 addr);
|
||||
debugvirtual void op_write(uint32 addr, uint8 data);
|
||||
uint8 op_read(uint32 addr);
|
||||
void op_write(uint32 addr, uint8 data);
|
||||
alwaysinline unsigned speed(unsigned addr) const;
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
#ifdef DSP_CPP
|
||||
|
||||
bool DSPDebugger::property(unsigned id, string &name, string &value) {
|
||||
unsigned n = 0;
|
||||
|
||||
#define item(name_, value_) \
|
||||
if(id == n++) { \
|
||||
name = name_; \
|
||||
value = value_; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
item("Main Volume - Left", (unsigned)state.regs[0x0c]);
|
||||
item("Main Volume - Right", (unsigned)state.regs[0x1c]);
|
||||
item("Echo Volume - Left", (unsigned)state.regs[0x2c]);
|
||||
item("Echo Volume - Right", (unsigned)state.regs[0x3c]);
|
||||
item("Key On", string("0x", hex<2>(state.regs[0x4c])));
|
||||
item("Key Off", string("0x", hex<2>(state.regs[0x5c])));
|
||||
item("Flag - Reset", (bool)(state.regs[0x6c] & 0x80));
|
||||
item("Flag - Mute", (bool)(state.regs[0x6c] & 0x40));
|
||||
item("Flag - Echo Disable", (bool)(state.regs[0x6c] & 0x20));
|
||||
item("Flag - Noise Clock", (unsigned)state.regs[0x6c] & 0x1f);
|
||||
item("Source End Block", (unsigned)state.regs[0x7c]);
|
||||
item("Echo Feedback", (unsigned)state.regs[0x0d]);
|
||||
item("Pitch Modulation Enable", string("0x", hex<2>(state.regs[0x2d])));
|
||||
item("Noise Enable", string("0x", hex<2>(state.regs[0x3d])));
|
||||
item("Echo Enable", string("0x", hex<2>(state.regs[0x4d])));
|
||||
item("Source Directory", (unsigned)state.regs[0x5d]);
|
||||
item("Echo Start Address", (unsigned)state.regs[0x6d]);
|
||||
item("Echo Directory", (unsigned)state.regs[0x7d]);
|
||||
|
||||
for(unsigned i = 0; i < 8; i++) {
|
||||
item(string("Coefficient ", i), string("0x", hex<2>(state.regs[(i << 4) + 0x0f])));
|
||||
}
|
||||
|
||||
for(unsigned i = 0; i < 8; i++) {
|
||||
item(string("Voice ", i), "");
|
||||
item("Volume - Left", (unsigned)state.regs[(i << 4) + 0x00]);
|
||||
item("Volume - Right", (unsigned)state.regs[(i << 4) + 0x01]);
|
||||
item("Pitch Height", string("0x", hex<4>(state.regs[(i << 4) + 0x02] + (state.regs[(i << 4) + 0x03] << 8))));
|
||||
item("Source Number", (unsigned)state.regs[(i << 4) + 0x04]);
|
||||
item("ADSR1", (unsigned)state.regs[(i << 4) + 0x05]);
|
||||
item("ADSR2", (unsigned)state.regs[(i << 4) + 0x06]);
|
||||
item("GAIN", (unsigned)state.regs[(i << 4) + 0x07]);
|
||||
item("ENVX", (unsigned)state.regs[(i << 4) + 0x08]);
|
||||
item("OUTX", (unsigned)state.regs[(i << 4) + 0x09]);
|
||||
}
|
||||
|
||||
#undef item
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,4 +0,0 @@
|
|||
class DSPDebugger : public DSP, public ChipDebugger {
|
||||
public:
|
||||
bool property(unsigned id, string &name, string &value);
|
||||
};
|
|
@ -3,18 +3,12 @@
|
|||
#define DSP_CPP
|
||||
namespace SNES {
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.cpp"
|
||||
DSPDebugger dsp;
|
||||
#else
|
||||
DSP dsp;
|
||||
#endif
|
||||
|
||||
#include "serialization.cpp"
|
||||
DSP dsp;
|
||||
|
||||
#define REG(n) state.regs[r_##n]
|
||||
#define VREG(n) state.regs[v.vidx + v_##n]
|
||||
|
||||
#include "serialization.cpp"
|
||||
#include "gaussian.cpp"
|
||||
#include "counter.cpp"
|
||||
#include "envelope.cpp"
|
||||
|
@ -303,4 +297,7 @@ DSP::DSP() {
|
|||
DSP::~DSP() {
|
||||
}
|
||||
|
||||
#undef REG
|
||||
#undef VREG
|
||||
|
||||
}
|
||||
|
|
|
@ -167,13 +167,6 @@ private:
|
|||
//dsp
|
||||
static void Enter();
|
||||
void tick();
|
||||
|
||||
friend class DSPDebugger;
|
||||
};
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.hpp"
|
||||
extern DSPDebugger dsp;
|
||||
#else
|
||||
extern DSP dsp;
|
||||
#endif
|
||||
extern DSP dsp;
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
#ifdef PPU_CPP
|
||||
|
||||
bool PPUDebugger::property(unsigned id, string &name, string &value) {
|
||||
unsigned n = 0;
|
||||
|
||||
#define item(name_, value_) \
|
||||
if(id == n++) { \
|
||||
name = name_; \
|
||||
value = value_; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
#undef item
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,4 +0,0 @@
|
|||
class PPUDebugger : public PPU, public ChipDebugger {
|
||||
public:
|
||||
bool property(unsigned id, string &name, string &value);
|
||||
};
|
|
@ -3,12 +3,7 @@
|
|||
#define PPU_CPP
|
||||
namespace SNES {
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.cpp"
|
||||
PPUDebugger ppu;
|
||||
#else
|
||||
PPU ppu;
|
||||
#endif
|
||||
PPU ppu;
|
||||
|
||||
#include "background/background.cpp"
|
||||
#include "mmio/mmio.cpp"
|
||||
|
|
|
@ -60,9 +60,4 @@ private:
|
|||
friend class Video;
|
||||
};
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.hpp"
|
||||
extern PPUDebugger ppu;
|
||||
#else
|
||||
extern PPU ppu;
|
||||
#endif
|
||||
extern PPU ppu;
|
||||
|
|
|
@ -1,126 +0,0 @@
|
|||
#ifdef SMPCORE_CPP
|
||||
|
||||
uint8 SMPcore::op_adc(uint8 x, uint8 y) {
|
||||
int r = x + y + regs.p.c;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.v = ~(x ^ y) & (x ^ r) & 0x80;
|
||||
regs.p.h = (x ^ y ^ r) & 0x10;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r > 0xff;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint16 SMPcore::op_addw(uint16 x, uint16 y) {
|
||||
uint16 r;
|
||||
regs.p.c = 0;
|
||||
r = op_adc(x, y);
|
||||
r |= op_adc(x >> 8, y >> 8) << 8;
|
||||
regs.p.z = r == 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint8 SMPcore::op_and(uint8 x, uint8 y) {
|
||||
x &= y;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 SMPcore::op_cmp(uint8 x, uint8 y) {
|
||||
int r = x - y;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint16 SMPcore::op_cmpw(uint16 x, uint16 y) {
|
||||
int r = x - y;
|
||||
regs.p.n = r & 0x8000;
|
||||
regs.p.z = (uint16)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 SMPcore::op_eor(uint8 x, uint8 y) {
|
||||
x ^= y;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 SMPcore::op_or(uint8 x, uint8 y) {
|
||||
x |= y;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 SMPcore::op_sbc(uint8 x, uint8 y) {
|
||||
int r = x - y - !regs.p.c;
|
||||
regs.p.n = r & 0x80;
|
||||
regs.p.v = (x ^ y) & (x ^ r) & 0x80;
|
||||
regs.p.h = !((x ^ y ^ r) & 0x10);
|
||||
regs.p.z = (uint8)r == 0;
|
||||
regs.p.c = r >= 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint16 SMPcore::op_subw(uint16 x, uint16 y) {
|
||||
uint16 r;
|
||||
regs.p.c = 1;
|
||||
r = op_sbc(x, y);
|
||||
r |= op_sbc(x >> 8, y >> 8) << 8;
|
||||
regs.p.z = r == 0;
|
||||
return r;
|
||||
}
|
||||
|
||||
uint8 SMPcore::op_inc(uint8 x) {
|
||||
x++;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 SMPcore::op_dec(uint8 x) {
|
||||
x--;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 SMPcore::op_asl(uint8 x) {
|
||||
regs.p.c = x & 0x80;
|
||||
x <<= 1;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 SMPcore::op_lsr(uint8 x) {
|
||||
regs.p.c = x & 0x01;
|
||||
x >>= 1;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 SMPcore::op_rol(uint8 x) {
|
||||
unsigned carry = (unsigned)regs.p.c;
|
||||
regs.p.c = x & 0x80;
|
||||
x = (x << 1) | carry;
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
uint8 SMPcore::op_ror(uint8 x) {
|
||||
unsigned carry = (unsigned)regs.p.c << 7;
|
||||
regs.p.c = x & 0x01;
|
||||
x = carry | (x >> 1);
|
||||
regs.p.n = x & 0x80;
|
||||
regs.p.z = x == 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,35 +0,0 @@
|
|||
#include <snes/snes.hpp>
|
||||
|
||||
#define SMPCORE_CPP
|
||||
namespace SNES {
|
||||
|
||||
#include "serialization.cpp"
|
||||
#include "algorithms.cpp"
|
||||
#include "disassembler/disassembler.cpp"
|
||||
|
||||
#define A 0
|
||||
#define X 1
|
||||
#define Y 2
|
||||
#define SP 3
|
||||
|
||||
#include "opcode_mov.cpp"
|
||||
#include "opcode_pc.cpp"
|
||||
#include "opcode_read.cpp"
|
||||
#include "opcode_rmw.cpp"
|
||||
#include "opcode_misc.cpp"
|
||||
#include "table.cpp"
|
||||
|
||||
#undef A
|
||||
#undef X
|
||||
#undef Y
|
||||
#undef SP
|
||||
|
||||
void SMPcore::op_step() {
|
||||
(this->*opcode_table[op_readpc()])();
|
||||
}
|
||||
|
||||
SMPcore::SMPcore() {
|
||||
initialize_opcode_table();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,118 +0,0 @@
|
|||
struct SMPcore {
|
||||
#include "registers.hpp"
|
||||
#include "memory.hpp"
|
||||
#include "disassembler/disassembler.hpp"
|
||||
|
||||
regs_t regs;
|
||||
uint16 dp, sp, rd, wr, bit, ya;
|
||||
|
||||
virtual void op_io() = 0;
|
||||
virtual uint8 op_read(uint16 addr) = 0;
|
||||
virtual void op_write(uint16 addr, uint8 data) = 0;
|
||||
void op_step();
|
||||
|
||||
uint8 op_adc (uint8 x, uint8 y);
|
||||
uint16 op_addw(uint16 x, uint16 y);
|
||||
uint8 op_and (uint8 x, uint8 y);
|
||||
uint8 op_cmp (uint8 x, uint8 y);
|
||||
uint16 op_cmpw(uint16 x, uint16 y);
|
||||
uint8 op_eor (uint8 x, uint8 y);
|
||||
uint8 op_inc (uint8 x);
|
||||
uint8 op_dec (uint8 x);
|
||||
uint8 op_or (uint8 x, uint8 y);
|
||||
uint8 op_sbc (uint8 x, uint8 y);
|
||||
uint16 op_subw(uint16 x, uint16 y);
|
||||
uint8 op_asl (uint8 x);
|
||||
uint8 op_lsr (uint8 x);
|
||||
uint8 op_rol (uint8 x);
|
||||
uint8 op_ror (uint8 x);
|
||||
|
||||
template<int, int> void op_mov_reg_reg();
|
||||
void op_mov_sp_x();
|
||||
template<int> void op_mov_reg_const();
|
||||
void op_mov_a_ix();
|
||||
void op_mov_a_ixinc();
|
||||
template<int> void op_mov_reg_dp();
|
||||
template<int, int> void op_mov_reg_dpr();
|
||||
template<int> void op_mov_reg_addr();
|
||||
template<int> void op_mov_a_addrr();
|
||||
void op_mov_a_idpx();
|
||||
void op_mov_a_idpy();
|
||||
void op_mov_dp_dp();
|
||||
void op_mov_dp_const();
|
||||
void op_mov_ix_a();
|
||||
void op_mov_ixinc_a();
|
||||
template<int> void op_mov_dp_reg();
|
||||
template<int, int> void op_mov_dpr_reg();
|
||||
template<int> void op_mov_addr_reg();
|
||||
template<int> void op_mov_addrr_a();
|
||||
void op_mov_idpx_a();
|
||||
void op_mov_idpy_a();
|
||||
void op_movw_ya_dp();
|
||||
void op_movw_dp_ya();
|
||||
void op_mov1_c_bit();
|
||||
void op_mov1_bit_c();
|
||||
|
||||
void op_bra();
|
||||
template<int, int> void op_branch();
|
||||
template<int, int> void op_bitbranch();
|
||||
void op_cbne_dp();
|
||||
void op_cbne_dpx();
|
||||
void op_dbnz_dp();
|
||||
void op_dbnz_y();
|
||||
void op_jmp_addr();
|
||||
void op_jmp_iaddrx();
|
||||
void op_call();
|
||||
void op_pcall();
|
||||
template<int> void op_tcall();
|
||||
void op_brk();
|
||||
void op_ret();
|
||||
void op_reti();
|
||||
|
||||
template<uint8 (SMPcore::*)(uint8, uint8), int> void op_read_reg_const();
|
||||
template<uint8 (SMPcore::*)(uint8, uint8)> void op_read_a_ix();
|
||||
template<uint8 (SMPcore::*)(uint8, uint8), int> void op_read_reg_dp();
|
||||
template<uint8 (SMPcore::*)(uint8, uint8)> void op_read_a_dpx();
|
||||
template<uint8 (SMPcore::*)(uint8, uint8), int> void op_read_reg_addr();
|
||||
template<uint8 (SMPcore::*)(uint8, uint8), int> void op_read_a_addrr();
|
||||
template<uint8 (SMPcore::*)(uint8, uint8)> void op_read_a_idpx();
|
||||
template<uint8 (SMPcore::*)(uint8, uint8)> void op_read_a_idpy();
|
||||
template<uint8 (SMPcore::*)(uint8, uint8)> void op_read_ix_iy();
|
||||
template<uint8 (SMPcore::*)(uint8, uint8)> void op_read_dp_dp();
|
||||
template<uint8 (SMPcore::*)(uint8, uint8)> void op_read_dp_const();
|
||||
template<uint16 (SMPcore::*)(uint16, uint16)> void op_read_ya_dp();
|
||||
void op_cmpw_ya_dp();
|
||||
template<int> void op_and1_bit();
|
||||
void op_eor1_bit();
|
||||
void op_not1_bit();
|
||||
template<int> void op_or1_bit();
|
||||
|
||||
template<uint8 (SMPcore::*)(uint8), int> void op_adjust_reg();
|
||||
template<uint8 (SMPcore::*)(uint8)> void op_adjust_dp();
|
||||
template<uint8 (SMPcore::*)(uint8)> void op_adjust_dpx();
|
||||
template<uint8 (SMPcore::*)(uint8)> void op_adjust_addr();
|
||||
template<int> void op_adjust_addr_a();
|
||||
template<int> void op_adjustw_dp();
|
||||
|
||||
void op_nop();
|
||||
void op_wait();
|
||||
void op_xcn();
|
||||
void op_daa();
|
||||
void op_das();
|
||||
template<int, int> void op_setbit();
|
||||
void op_notc();
|
||||
template<int> void op_seti();
|
||||
template<int, int> void op_setbit_dp();
|
||||
template<int> void op_push_reg();
|
||||
void op_push_p();
|
||||
template<int> void op_pop_reg();
|
||||
void op_pop_p();
|
||||
void op_mul_ya();
|
||||
void op_div_ya_x();
|
||||
|
||||
void (SMPcore::*opcode_table[256])();
|
||||
void initialize_opcode_table();
|
||||
|
||||
void core_serialize(serializer&);
|
||||
SMPcore();
|
||||
};
|
|
@ -1,308 +0,0 @@
|
|||
#ifdef SMPCORE_CPP
|
||||
|
||||
uint8 SMPcore::disassemble_read(uint16 addr) {
|
||||
if(addr >= 0xffc0) return smp.iplrom[addr & 0x3f];
|
||||
return smp.apuram[addr];
|
||||
}
|
||||
|
||||
uint16 SMPcore::relb(int8 offset, int op_len) {
|
||||
uint16 pc = regs.pc + op_len;
|
||||
return pc + offset;
|
||||
}
|
||||
|
||||
void SMPcore::disassemble_opcode(char *output, uint16 addr) {
|
||||
char *s, t[512];
|
||||
uint8 op, op0, op1;
|
||||
uint16 opw, opdp0, opdp1;
|
||||
s = output;
|
||||
|
||||
sprintf(s, "..%.4x ", addr);
|
||||
|
||||
op = disassemble_read(addr + 0);
|
||||
op0 = disassemble_read(addr + 1);
|
||||
op1 = disassemble_read(addr + 2);
|
||||
opw = (op0) | (op1 << 8);
|
||||
opdp0 = ((unsigned)regs.p.p << 8) + op0;
|
||||
opdp1 = ((unsigned)regs.p.p << 8) + op1;
|
||||
|
||||
strcpy(t, " ");
|
||||
|
||||
switch(op) {
|
||||
case 0x00: sprintf(t, "nop"); break;
|
||||
case 0x01: sprintf(t, "tcall 0"); break;
|
||||
case 0x02: sprintf(t, "set0 $%.3x", opdp0); break;
|
||||
case 0x03: sprintf(t, "bbs0 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0x04: sprintf(t, "or a,$%.3x", opdp0); break;
|
||||
case 0x05: sprintf(t, "or a,$%.4x", opw); break;
|
||||
case 0x06: sprintf(t, "or a,(x)"); break;
|
||||
case 0x07: sprintf(t, "or a,($%.3x+x)", opdp0); break;
|
||||
case 0x08: sprintf(t, "or a,#$%.2x", op0); break;
|
||||
case 0x09: sprintf(t, "or $%.3x,$%.3x", opdp1, opdp0); break;
|
||||
case 0x0a: sprintf(t, "or1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break;
|
||||
case 0x0b: sprintf(t, "asl $%.3x", opdp0); break;
|
||||
case 0x0c: sprintf(t, "asl $%.4x", opw); break;
|
||||
case 0x0d: sprintf(t, "push p"); break;
|
||||
case 0x0e: sprintf(t, "tset $%.4x,a", opw); break;
|
||||
case 0x0f: sprintf(t, "brk"); break;
|
||||
case 0x10: sprintf(t, "bpl $%.4x", relb(op0, 2)); break;
|
||||
case 0x11: sprintf(t, "tcall 1"); break;
|
||||
case 0x12: sprintf(t, "clr0 $%.3x", opdp0); break;
|
||||
case 0x13: sprintf(t, "bbc0 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0x14: sprintf(t, "or a,$%.3x+x", opdp0); break;
|
||||
case 0x15: sprintf(t, "or a,$%.4x+x", opw); break;
|
||||
case 0x16: sprintf(t, "or a,$%.4x+y", opw); break;
|
||||
case 0x17: sprintf(t, "or a,($%.3x)+y", opdp0); break;
|
||||
case 0x18: sprintf(t, "or $%.3x,#$%.2x", opdp1, op0); break;
|
||||
case 0x19: sprintf(t, "or (x),(y)"); break;
|
||||
case 0x1a: sprintf(t, "decw $%.3x", opdp0); break;
|
||||
case 0x1b: sprintf(t, "asl $%.3x+x", opdp0); break;
|
||||
case 0x1c: sprintf(t, "asl a"); break;
|
||||
case 0x1d: sprintf(t, "dec x"); break;
|
||||
case 0x1e: sprintf(t, "cmp x,$%.4x", opw); break;
|
||||
case 0x1f: sprintf(t, "jmp ($%.4x+x)", opw); break;
|
||||
case 0x20: sprintf(t, "clrp"); break;
|
||||
case 0x21: sprintf(t, "tcall 2"); break;
|
||||
case 0x22: sprintf(t, "set1 $%.3x", opdp0); break;
|
||||
case 0x23: sprintf(t, "bbs1 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0x24: sprintf(t, "and a,$%.3x", opdp0); break;
|
||||
case 0x25: sprintf(t, "and a,$%.4x", opw); break;
|
||||
case 0x26: sprintf(t, "and a,(x)"); break;
|
||||
case 0x27: sprintf(t, "and a,($%.3x+x)", opdp0); break;
|
||||
case 0x28: sprintf(t, "and a,#$%.2x", op0); break;
|
||||
case 0x29: sprintf(t, "and $%.3x,$%.3x", opdp1, opdp0); break;
|
||||
case 0x2a: sprintf(t, "or1 c,!$%.4x:%d", opw & 0x1fff, opw >> 13); break;
|
||||
case 0x2b: sprintf(t, "rol $%.3x", opdp0); break;
|
||||
case 0x2c: sprintf(t, "rol $%.4x", opw); break;
|
||||
case 0x2d: sprintf(t, "push a"); break;
|
||||
case 0x2e: sprintf(t, "cbne $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0x2f: sprintf(t, "bra $%.4x", relb(op0, 2)); break;
|
||||
case 0x30: sprintf(t, "bmi $%.4x", relb(op0, 2)); break;
|
||||
case 0x31: sprintf(t, "tcall 3"); break;
|
||||
case 0x32: sprintf(t, "clr1 $%.3x", opdp0); break;
|
||||
case 0x33: sprintf(t, "bbc1 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0x34: sprintf(t, "and a,$%.3x+x", opdp0); break;
|
||||
case 0x35: sprintf(t, "and a,$%.4x+x", opw); break;
|
||||
case 0x36: sprintf(t, "and a,$%.4x+y", opw); break;
|
||||
case 0x37: sprintf(t, "and a,($%.3x)+y", opdp0); break;
|
||||
case 0x38: sprintf(t, "and $%.3x,#$%.2x", opdp1, op0); break;
|
||||
case 0x39: sprintf(t, "and (x),(y)"); break;
|
||||
case 0x3a: sprintf(t, "incw $%.3x", opdp0); break;
|
||||
case 0x3b: sprintf(t, "rol $%.3x+x", opdp0); break;
|
||||
case 0x3c: sprintf(t, "rol a"); break;
|
||||
case 0x3d: sprintf(t, "inc x"); break;
|
||||
case 0x3e: sprintf(t, "cmp x,$%.3x", opdp0); break;
|
||||
case 0x3f: sprintf(t, "call $%.4x", opw); break;
|
||||
case 0x40: sprintf(t, "setp"); break;
|
||||
case 0x41: sprintf(t, "tcall 4"); break;
|
||||
case 0x42: sprintf(t, "set2 $%.3x", opdp0); break;
|
||||
case 0x43: sprintf(t, "bbs2 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0x44: sprintf(t, "eor a,$%.3x", opdp0); break;
|
||||
case 0x45: sprintf(t, "eor a,$%.4x", opw); break;
|
||||
case 0x46: sprintf(t, "eor a,(x)"); break;
|
||||
case 0x47: sprintf(t, "eor a,($%.3x+x)", opdp0); break;
|
||||
case 0x48: sprintf(t, "eor a,#$%.2x", op0); break;
|
||||
case 0x49: sprintf(t, "eor $%.3x,$%.3x", opdp1, opdp0); break;
|
||||
case 0x4a: sprintf(t, "and1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break;
|
||||
case 0x4b: sprintf(t, "lsr $%.3x", opdp0); break;
|
||||
case 0x4c: sprintf(t, "lsr $%.4x", opw); break;
|
||||
case 0x4d: sprintf(t, "push x"); break;
|
||||
case 0x4e: sprintf(t, "tclr $%.4x,a", opw); break;
|
||||
case 0x4f: sprintf(t, "pcall $ff%.2x", op0); break;
|
||||
case 0x50: sprintf(t, "bvc $%.4x", relb(op0, 2)); break;
|
||||
case 0x51: sprintf(t, "tcall 5"); break;
|
||||
case 0x52: sprintf(t, "clr2 $%.3x", opdp0); break;
|
||||
case 0x53: sprintf(t, "bbc2 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0x54: sprintf(t, "eor a,$%.3x+x", opdp0); break;
|
||||
case 0x55: sprintf(t, "eor a,$%.4x+x", opw); break;
|
||||
case 0x56: sprintf(t, "eor a,$%.4x+y", opw); break;
|
||||
case 0x57: sprintf(t, "eor a,($%.3x)+y", opdp0); break;
|
||||
case 0x58: sprintf(t, "eor $%.3x,#$%.2x", opdp1, op0); break;
|
||||
case 0x59: sprintf(t, "eor (x),(y)"); break;
|
||||
case 0x5a: sprintf(t, "cmpw ya,$%.3x", opdp0); break;
|
||||
case 0x5b: sprintf(t, "lsr $%.3x+x", opdp0); break;
|
||||
case 0x5c: sprintf(t, "lsr a"); break;
|
||||
case 0x5d: sprintf(t, "mov x,a"); break;
|
||||
case 0x5e: sprintf(t, "cmp y,$%.4x", opw); break;
|
||||
case 0x5f: sprintf(t, "jmp $%.4x", opw); break;
|
||||
case 0x60: sprintf(t, "clrc"); break;
|
||||
case 0x61: sprintf(t, "tcall 6"); break;
|
||||
case 0x62: sprintf(t, "set3 $%.3x", opdp0); break;
|
||||
case 0x63: sprintf(t, "bbs3 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0x64: sprintf(t, "cmp a,$%.3x", opdp0); break;
|
||||
case 0x65: sprintf(t, "cmp a,$%.4x", opw); break;
|
||||
case 0x66: sprintf(t, "cmp a,(x)"); break;
|
||||
case 0x67: sprintf(t, "cmp a,($%.3x+x)", opdp0); break;
|
||||
case 0x68: sprintf(t, "cmp a,#$%.2x", op0); break;
|
||||
case 0x69: sprintf(t, "cmp $%.3x,$%.3x", opdp1, opdp0); break;
|
||||
case 0x6a: sprintf(t, "and1 c,!$%.4x:%d", opw & 0x1fff, opw >> 13); break;
|
||||
case 0x6b: sprintf(t, "ror $%.3x", opdp0); break;
|
||||
case 0x6c: sprintf(t, "ror $%.4x", opw); break;
|
||||
case 0x6d: sprintf(t, "push y"); break;
|
||||
case 0x6e: sprintf(t, "dbnz $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0x6f: sprintf(t, "ret"); break;
|
||||
case 0x70: sprintf(t, "bvs $%.4x", relb(op0, 2)); break;
|
||||
case 0x71: sprintf(t, "tcall 7"); break;
|
||||
case 0x72: sprintf(t, "clr3 $%.3x", opdp0); break;
|
||||
case 0x73: sprintf(t, "bbc3 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0x74: sprintf(t, "cmp a,$%.3x+x", opdp0); break;
|
||||
case 0x75: sprintf(t, "cmp a,$%.4x+x", opw); break;
|
||||
case 0x76: sprintf(t, "cmp a,$%.4x+y", opw); break;
|
||||
case 0x77: sprintf(t, "cmp a,($%.3x)+y", opdp0); break;
|
||||
case 0x78: sprintf(t, "cmp $%.3x,#$%.2x", opdp1, op0); break;
|
||||
case 0x79: sprintf(t, "cmp (x),(y)"); break;
|
||||
case 0x7a: sprintf(t, "addw ya,$%.3x", opdp0); break;
|
||||
case 0x7b: sprintf(t, "ror $%.3x+x", opdp0); break;
|
||||
case 0x7c: sprintf(t, "ror a"); break;
|
||||
case 0x7d: sprintf(t, "mov a,x"); break;
|
||||
case 0x7e: sprintf(t, "cmp y,$%.3x", opdp0); break;
|
||||
case 0x7f: sprintf(t, "reti"); break;
|
||||
case 0x80: sprintf(t, "setc"); break;
|
||||
case 0x81: sprintf(t, "tcall 8"); break;
|
||||
case 0x82: sprintf(t, "set4 $%.3x", opdp0); break;
|
||||
case 0x83: sprintf(t, "bbs4 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0x84: sprintf(t, "adc a,$%.3x", opdp0); break;
|
||||
case 0x85: sprintf(t, "adc a,$%.4x", opw); break;
|
||||
case 0x86: sprintf(t, "adc a,(x)"); break;
|
||||
case 0x87: sprintf(t, "adc a,($%.3x+x)", opdp0); break;
|
||||
case 0x88: sprintf(t, "adc a,#$%.2x", op0); break;
|
||||
case 0x89: sprintf(t, "adc $%.3x,$%.3x", opdp1, opdp0); break;
|
||||
case 0x8a: sprintf(t, "eor1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break;
|
||||
case 0x8b: sprintf(t, "dec $%.3x", opdp0); break;
|
||||
case 0x8c: sprintf(t, "dec $%.4x", opw); break;
|
||||
case 0x8d: sprintf(t, "mov y,#$%.2x", op0); break;
|
||||
case 0x8e: sprintf(t, "pop p"); break;
|
||||
case 0x8f: sprintf(t, "mov $%.3x,#$%.2x", opdp1, op0); break;
|
||||
case 0x90: sprintf(t, "bcc $%.4x", relb(op0, 2)); break;
|
||||
case 0x91: sprintf(t, "tcall 9"); break;
|
||||
case 0x92: sprintf(t, "clr4 $%.3x", opdp0); break;
|
||||
case 0x93: sprintf(t, "bbc4 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0x94: sprintf(t, "adc a,$%.3x+x", opdp0); break;
|
||||
case 0x95: sprintf(t, "adc a,$%.4x+x", opw); break;
|
||||
case 0x96: sprintf(t, "adc a,$%.4x+y", opw); break;
|
||||
case 0x97: sprintf(t, "adc a,($%.3x)+y", opdp0); break;
|
||||
case 0x98: sprintf(t, "adc $%.3x,#$%.2x", opdp1, op0); break;
|
||||
case 0x99: sprintf(t, "adc (x),(y)"); break;
|
||||
case 0x9a: sprintf(t, "subw ya,$%.3x", opdp0); break;
|
||||
case 0x9b: sprintf(t, "dec $%.3x+x", opdp0); break;
|
||||
case 0x9c: sprintf(t, "dec a"); break;
|
||||
case 0x9d: sprintf(t, "mov x,sp"); break;
|
||||
case 0x9e: sprintf(t, "div ya,x"); break;
|
||||
case 0x9f: sprintf(t, "xcn a"); break;
|
||||
case 0xa0: sprintf(t, "ei"); break;
|
||||
case 0xa1: sprintf(t, "tcall 10"); break;
|
||||
case 0xa2: sprintf(t, "set5 $%.3x", opdp0); break;
|
||||
case 0xa3: sprintf(t, "bbs5 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0xa4: sprintf(t, "sbc a,$%.3x", opdp0); break;
|
||||
case 0xa5: sprintf(t, "sbc a,$%.4x", opw); break;
|
||||
case 0xa6: sprintf(t, "sbc a,(x)"); break;
|
||||
case 0xa7: sprintf(t, "sbc a,($%.3x+x)", opdp0); break;
|
||||
case 0xa8: sprintf(t, "sbc a,#$%.2x", op0); break;
|
||||
case 0xa9: sprintf(t, "sbc $%.3x,$%.3x", opdp1, opdp0); break;
|
||||
case 0xaa: sprintf(t, "mov1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break;
|
||||
case 0xab: sprintf(t, "inc $%.3x", opdp0); break;
|
||||
case 0xac: sprintf(t, "inc $%.4x", opw); break;
|
||||
case 0xad: sprintf(t, "cmp y,#$%.2x", op0); break;
|
||||
case 0xae: sprintf(t, "pop a"); break;
|
||||
case 0xaf: sprintf(t, "mov (x)+,a"); break;
|
||||
case 0xb0: sprintf(t, "bcs $%.4x", relb(op0, 2)); break;
|
||||
case 0xb1: sprintf(t, "tcall 11"); break;
|
||||
case 0xb2: sprintf(t, "clr5 $%.3x", opdp0); break;
|
||||
case 0xb3: sprintf(t, "bbc5 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0xb4: sprintf(t, "sbc a,$%.3x+x", opdp0); break;
|
||||
case 0xb5: sprintf(t, "sbc a,$%.4x+x", opw); break;
|
||||
case 0xb6: sprintf(t, "sbc a,$%.4x+y", opw); break;
|
||||
case 0xb7: sprintf(t, "sbc a,($%.3x)+y", opdp0); break;
|
||||
case 0xb8: sprintf(t, "sbc $%.3x,#$%.2x", opdp1, op0); break;
|
||||
case 0xb9: sprintf(t, "sbc (x),(y)"); break;
|
||||
case 0xba: sprintf(t, "movw ya,$%.3x", opdp0); break;
|
||||
case 0xbb: sprintf(t, "inc $%.3x+x", opdp0); break;
|
||||
case 0xbc: sprintf(t, "inc a"); break;
|
||||
case 0xbd: sprintf(t, "mov sp,x"); break;
|
||||
case 0xbe: sprintf(t, "das a"); break;
|
||||
case 0xbf: sprintf(t, "mov a,(x)+"); break;
|
||||
case 0xc0: sprintf(t, "di"); break;
|
||||
case 0xc1: sprintf(t, "tcall 12"); break;
|
||||
case 0xc2: sprintf(t, "set6 $%.3x", opdp0); break;
|
||||
case 0xc3: sprintf(t, "bbs6 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0xc4: sprintf(t, "mov $%.3x,a", opdp0); break;
|
||||
case 0xc5: sprintf(t, "mov $%.4x,a", opw); break;
|
||||
case 0xc6: sprintf(t, "mov (x),a"); break;
|
||||
case 0xc7: sprintf(t, "mov ($%.3x+x),a", opdp0); break;
|
||||
case 0xc8: sprintf(t, "cmp x,#$%.2x", op0); break;
|
||||
case 0xc9: sprintf(t, "mov $%.4x,x", opw); break;
|
||||
case 0xca: sprintf(t, "mov1 $%.4x:%d,c", opw & 0x1fff, opw >> 13); break;
|
||||
case 0xcb: sprintf(t, "mov $%.3x,y", opdp0); break;
|
||||
case 0xcc: sprintf(t, "mov $%.4x,y", opw); break;
|
||||
case 0xcd: sprintf(t, "mov x,#$%.2x", op0); break;
|
||||
case 0xce: sprintf(t, "pop x"); break;
|
||||
case 0xcf: sprintf(t, "mul ya"); break;
|
||||
case 0xd0: sprintf(t, "bne $%.4x", relb(op0, 2)); break;
|
||||
case 0xd1: sprintf(t, "tcall 13"); break;
|
||||
case 0xd2: sprintf(t, "clr6 $%.3x", opdp0); break;
|
||||
case 0xd3: sprintf(t, "bbc6 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0xd4: sprintf(t, "mov $%.3x+x,a", opdp0); break;
|
||||
case 0xd5: sprintf(t, "mov $%.4x+x,a", opw); break;
|
||||
case 0xd6: sprintf(t, "mov $%.4x+y,a", opw); break;
|
||||
case 0xd7: sprintf(t, "mov ($%.3x)+y,a", opdp0); break;
|
||||
case 0xd8: sprintf(t, "mov $%.3x,x", opdp0); break;
|
||||
case 0xd9: sprintf(t, "mov $%.3x+y,x", opdp0); break;
|
||||
case 0xda: sprintf(t, "movw $%.3x,ya", opdp0); break;
|
||||
case 0xdb: sprintf(t, "mov $%.3x+x,y", opdp0); break;
|
||||
case 0xdc: sprintf(t, "dec y"); break;
|
||||
case 0xdd: sprintf(t, "mov a,y"); break;
|
||||
case 0xde: sprintf(t, "cbne $%.3x+x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0xdf: sprintf(t, "daa a"); break;
|
||||
case 0xe0: sprintf(t, "clrv"); break;
|
||||
case 0xe1: sprintf(t, "tcall 14"); break;
|
||||
case 0xe2: sprintf(t, "set7 $%.3x", opdp0); break;
|
||||
case 0xe3: sprintf(t, "bbs7 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0xe4: sprintf(t, "mov a,$%.3x", opdp0); break;
|
||||
case 0xe5: sprintf(t, "mov a,$%.4x", opw); break;
|
||||
case 0xe6: sprintf(t, "mov a,(x)"); break;
|
||||
case 0xe7: sprintf(t, "mov a,($%.3x+x)", opdp0); break;
|
||||
case 0xe8: sprintf(t, "mov a,#$%.2x", op0); break;
|
||||
case 0xe9: sprintf(t, "mov x,$%.4x", opw); break;
|
||||
case 0xea: sprintf(t, "not1 c,$%.4x:%d", opw & 0x1fff, opw >> 13); break;
|
||||
case 0xeb: sprintf(t, "mov y,$%.3x", opdp0); break;
|
||||
case 0xec: sprintf(t, "mov y,$%.4x", opw); break;
|
||||
case 0xed: sprintf(t, "notc"); break;
|
||||
case 0xee: sprintf(t, "pop y"); break;
|
||||
case 0xef: sprintf(t, "sleep"); break;
|
||||
case 0xf0: sprintf(t, "beq $%.4x", relb(op0, 2)); break;
|
||||
case 0xf1: sprintf(t, "tcall 15"); break;
|
||||
case 0xf2: sprintf(t, "clr7 $%.3x", opdp0); break;
|
||||
case 0xf3: sprintf(t, "bbc7 $%.3x,$%.4x", opdp0, relb(op1, 3)); break;
|
||||
case 0xf4: sprintf(t, "mov a,$%.3x+x", opdp0); break;
|
||||
case 0xf5: sprintf(t, "mov a,$%.4x+x", opw); break;
|
||||
case 0xf6: sprintf(t, "mov a,$%.4x+y", opw); break;
|
||||
case 0xf7: sprintf(t, "mov a,($%.3x)+y", opdp0); break;
|
||||
case 0xf8: sprintf(t, "mov x,$%.3x", opdp0); break;
|
||||
case 0xf9: sprintf(t, "mov x,$%.3x+y", opdp0); break;
|
||||
case 0xfa: sprintf(t, "mov $%.3x,$%.3x", opdp1, opdp0); break;
|
||||
case 0xfb: sprintf(t, "mov y,$%.3x+x", opdp0); break;
|
||||
case 0xfc: sprintf(t, "inc y"); break;
|
||||
case 0xfd: sprintf(t, "mov y,a"); break;
|
||||
case 0xfe: sprintf(t, "dbnz y,$%.4x", relb(op0, 2)); break;
|
||||
case 0xff: sprintf(t, "stop"); break;
|
||||
}
|
||||
|
||||
t[strlen(t)] = ' ';
|
||||
strcat(s, t);
|
||||
|
||||
sprintf(t, "A:%.2x X:%.2x Y:%.2x SP:01%.2x YA:%.4x ",
|
||||
regs.a, regs.x, regs.y, regs.sp, (uint16)regs.ya);
|
||||
strcat(s, t);
|
||||
|
||||
sprintf(t, "%c%c%c%c%c%c%c%c",
|
||||
regs.p.n ? 'N' : 'n',
|
||||
regs.p.v ? 'V' : 'v',
|
||||
regs.p.p ? 'P' : 'p',
|
||||
regs.p.b ? 'B' : 'b',
|
||||
regs.p.h ? 'H' : 'h',
|
||||
regs.p.i ? 'I' : 'i',
|
||||
regs.p.z ? 'Z' : 'z',
|
||||
regs.p.c ? 'C' : 'c');
|
||||
strcat(s, t);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,3 +0,0 @@
|
|||
void disassemble_opcode(char *output, uint16 addr);
|
||||
inline uint8 disassemble_read(uint16 addr);
|
||||
inline uint16 relb(int8 offset, int op_len);
|
|
@ -1,19 +0,0 @@
|
|||
alwaysinline uint8_t op_readpc() {
|
||||
return op_read(regs.pc++);
|
||||
}
|
||||
|
||||
alwaysinline uint8_t op_readsp() {
|
||||
return op_read(0x0100 | ++regs.sp);
|
||||
}
|
||||
|
||||
alwaysinline void op_writesp(uint8_t data) {
|
||||
op_write(0x0100 | regs.sp--, data);
|
||||
}
|
||||
|
||||
alwaysinline uint8_t op_readdp(uint8_t addr) {
|
||||
return op_read(((unsigned)regs.p.p << 8) + addr);
|
||||
}
|
||||
|
||||
alwaysinline void op_writedp(uint8_t addr, uint8_t data) {
|
||||
op_write(((unsigned)regs.p.p << 8) + addr, data);
|
||||
}
|
|
@ -1,148 +0,0 @@
|
|||
#ifdef SMPCORE_CPP
|
||||
|
||||
void SMPcore::op_nop() {
|
||||
op_io();
|
||||
}
|
||||
|
||||
void SMPcore::op_wait() {
|
||||
while(true) {
|
||||
op_io();
|
||||
op_io();
|
||||
}
|
||||
}
|
||||
|
||||
void SMPcore::op_xcn() {
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
regs.a = (regs.a >> 4) | (regs.a << 4);
|
||||
regs.p.n = (regs.a & 0x80);
|
||||
regs.p.z = (regs.a == 0);
|
||||
}
|
||||
|
||||
void SMPcore::op_daa() {
|
||||
op_io();
|
||||
op_io();
|
||||
if(regs.p.c || (regs.a) > 0x99) {
|
||||
regs.a += 0x60;
|
||||
regs.p.c = 1;
|
||||
}
|
||||
if(regs.p.h || (regs.a & 15) > 0x09) {
|
||||
regs.a += 0x06;
|
||||
}
|
||||
regs.p.n = (regs.a & 0x80);
|
||||
regs.p.z = (regs.a == 0);
|
||||
}
|
||||
|
||||
void SMPcore::op_das() {
|
||||
op_io();
|
||||
op_io();
|
||||
if(!regs.p.c || (regs.a) > 0x99) {
|
||||
regs.a -= 0x60;
|
||||
regs.p.c = 0;
|
||||
}
|
||||
if(!regs.p.h || (regs.a & 15) > 0x09) {
|
||||
regs.a -= 0x06;
|
||||
}
|
||||
regs.p.n = (regs.a & 0x80);
|
||||
regs.p.z = (regs.a == 0);
|
||||
}
|
||||
|
||||
template<int mask, int value> void SMPcore::op_setbit() {
|
||||
op_io();
|
||||
regs.p = (regs.p & ~mask) | value;
|
||||
}
|
||||
|
||||
void SMPcore::op_notc() {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.p.c = !regs.p.c;
|
||||
}
|
||||
|
||||
template<int value> void SMPcore::op_seti() {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.p.i = value;
|
||||
}
|
||||
|
||||
template<int op, int value> void SMPcore::op_setbit_dp() {
|
||||
dp = op_readpc();
|
||||
rd = op_readdp(dp);
|
||||
rd = (op ? rd | value : rd & ~value);
|
||||
op_writedp(dp, rd);
|
||||
}
|
||||
|
||||
template<int n> void SMPcore::op_push_reg() {
|
||||
op_io();
|
||||
op_io();
|
||||
op_writesp(regs.r[n]);
|
||||
}
|
||||
|
||||
void SMPcore::op_push_p() {
|
||||
op_io();
|
||||
op_io();
|
||||
op_writesp(regs.p);
|
||||
}
|
||||
|
||||
template<int n> void SMPcore::op_pop_reg() {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.r[n] = op_readsp();
|
||||
}
|
||||
|
||||
void SMPcore::op_pop_p() {
|
||||
op_io();
|
||||
op_io();
|
||||
regs.p = op_readsp();
|
||||
}
|
||||
|
||||
void SMPcore::op_mul_ya() {
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
ya = regs.y * regs.a;
|
||||
regs.a = ya;
|
||||
regs.y = ya >> 8;
|
||||
//result is set based on y (high-byte) only
|
||||
regs.p.n = (regs.y & 0x80);
|
||||
regs.p.z = (regs.y == 0);
|
||||
}
|
||||
|
||||
void SMPcore::op_div_ya_x() {
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
ya = regs.ya;
|
||||
//overflow set if quotient >= 256
|
||||
regs.p.v = (regs.y >= regs.x);
|
||||
regs.p.h = ((regs.y & 15) >= (regs.x & 15));
|
||||
if(regs.y < (regs.x << 1)) {
|
||||
//if quotient is <= 511 (will fit into 9-bit result)
|
||||
regs.a = ya / regs.x;
|
||||
regs.y = ya % regs.x;
|
||||
} else {
|
||||
//otherwise, the quotient won't fit into regs.p.v + regs.a
|
||||
//this emulates the odd behavior of the S-SMP in this case
|
||||
regs.a = 255 - (ya - (regs.x << 9)) / (256 - regs.x);
|
||||
regs.y = regs.x + (ya - (regs.x << 9)) % (256 - regs.x);
|
||||
}
|
||||
//result is set based on a (quotient) only
|
||||
regs.p.n = (regs.a & 0x80);
|
||||
regs.p.z = (regs.a == 0);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,200 +0,0 @@
|
|||
#ifdef SMPCORE_CPP
|
||||
|
||||
template<int to, int from> void SMPcore::op_mov_reg_reg() {
|
||||
op_io();
|
||||
regs.r[to] = regs.r[from];
|
||||
regs.p.n = (regs.r[to] & 0x80);
|
||||
regs.p.z = (regs.r[to] == 0);
|
||||
}
|
||||
|
||||
void SMPcore::op_mov_sp_x() {
|
||||
op_io();
|
||||
regs.sp = regs.x;
|
||||
}
|
||||
|
||||
template<int n> void SMPcore::op_mov_reg_const() {
|
||||
regs.r[n] = op_readpc();
|
||||
regs.p.n = (regs.r[n] & 0x80);
|
||||
regs.p.z = (regs.r[n] == 0);
|
||||
}
|
||||
|
||||
void SMPcore::op_mov_a_ix() {
|
||||
op_io();
|
||||
regs.a = op_readdp(regs.x);
|
||||
regs.p.n = (regs.a & 0x80);
|
||||
regs.p.z = (regs.a == 0);
|
||||
}
|
||||
|
||||
void SMPcore::op_mov_a_ixinc() {
|
||||
op_io();
|
||||
regs.a = op_readdp(regs.x++);
|
||||
op_io();
|
||||
regs.p.n = (regs.a & 0x80);
|
||||
regs.p.z = (regs.a == 0);
|
||||
}
|
||||
|
||||
template<int n> void SMPcore::op_mov_reg_dp() {
|
||||
sp = op_readpc();
|
||||
regs.r[n] = op_readdp(sp);
|
||||
regs.p.n = (regs.r[n] & 0x80);
|
||||
regs.p.z = (regs.r[n] == 0);
|
||||
}
|
||||
|
||||
template<int n, int i> void SMPcore::op_mov_reg_dpr() {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
regs.r[n] = op_readdp(sp + regs.r[i]);
|
||||
regs.p.n = (regs.r[n] & 0x80);
|
||||
regs.p.z = (regs.r[n] == 0);
|
||||
}
|
||||
|
||||
template<int n> void SMPcore::op_mov_reg_addr() {
|
||||
sp = op_readpc() << 0;
|
||||
sp |= op_readpc() << 8;
|
||||
regs.r[n] = op_read(sp);
|
||||
regs.p.n = (regs.r[n] & 0x80);
|
||||
regs.p.z = (regs.r[n] == 0);
|
||||
}
|
||||
|
||||
template<int i> void SMPcore::op_mov_a_addrr() {
|
||||
sp = op_readpc() << 0;
|
||||
sp |= op_readpc() << 8;
|
||||
op_io();
|
||||
regs.a = op_read(sp + regs.r[i]);
|
||||
regs.p.n = (regs.a & 0x80);
|
||||
regs.p.z = (regs.a == 0);
|
||||
}
|
||||
|
||||
void SMPcore::op_mov_a_idpx() {
|
||||
dp = op_readpc() + regs.x;
|
||||
op_io();
|
||||
sp = op_readdp(dp + 0) << 0;
|
||||
sp |= op_readdp(dp + 1) << 8;
|
||||
regs.a = op_read(sp);
|
||||
regs.p.n = (regs.a & 0x80);
|
||||
regs.p.z = (regs.a == 0);
|
||||
}
|
||||
|
||||
void SMPcore::op_mov_a_idpy() {
|
||||
dp = op_readpc();
|
||||
op_io();
|
||||
sp = op_readdp(dp + 0) << 0;
|
||||
sp |= op_readdp(dp + 1) << 8;
|
||||
regs.a = op_read(sp + regs.y);
|
||||
regs.p.n = (regs.a & 0x80);
|
||||
regs.p.z = (regs.a == 0);
|
||||
}
|
||||
|
||||
void SMPcore::op_mov_dp_dp() {
|
||||
sp = op_readpc();
|
||||
rd = op_readdp(sp);
|
||||
dp = op_readpc();
|
||||
op_writedp(dp, rd);
|
||||
}
|
||||
|
||||
void SMPcore::op_mov_dp_const() {
|
||||
rd = op_readpc();
|
||||
dp = op_readpc();
|
||||
op_readdp(dp);
|
||||
op_writedp(dp, rd);
|
||||
}
|
||||
|
||||
void SMPcore::op_mov_ix_a() {
|
||||
op_io();
|
||||
op_readdp(regs.x);
|
||||
op_writedp(regs.x, regs.a);
|
||||
}
|
||||
|
||||
void SMPcore::op_mov_ixinc_a() {
|
||||
op_io();
|
||||
op_io();
|
||||
op_writedp(regs.x++, regs.a);
|
||||
}
|
||||
|
||||
template<int n> void SMPcore::op_mov_dp_reg() {
|
||||
dp = op_readpc();
|
||||
op_readdp(dp);
|
||||
op_writedp(dp, regs.r[n]);
|
||||
}
|
||||
|
||||
template<int n, int i> void SMPcore::op_mov_dpr_reg() {
|
||||
dp = op_readpc();
|
||||
op_io();
|
||||
dp += regs.r[i];
|
||||
op_readdp(dp);
|
||||
op_writedp(dp, regs.r[n]);
|
||||
}
|
||||
|
||||
template<int n> void SMPcore::op_mov_addr_reg() {
|
||||
dp = op_readpc() << 0;
|
||||
dp |= op_readpc() << 8;
|
||||
op_read(dp);
|
||||
op_write(dp, regs.r[n]);
|
||||
}
|
||||
|
||||
template<int i> void SMPcore::op_mov_addrr_a() {
|
||||
dp = op_readpc() << 0;
|
||||
dp |= op_readpc() << 8;
|
||||
op_io();
|
||||
dp += regs.r[i];
|
||||
op_read(dp);
|
||||
op_write(dp, regs.a);
|
||||
}
|
||||
|
||||
void SMPcore::op_mov_idpx_a() {
|
||||
sp = op_readpc();
|
||||
op_io();
|
||||
sp += regs.x;
|
||||
dp = op_readdp(sp + 0) << 0;
|
||||
dp |= op_readdp(sp + 1) << 8;
|
||||
op_read(dp);
|
||||
op_write(dp, regs.a);
|
||||
}
|
||||
|
||||
void SMPcore::op_mov_idpy_a() {
|
||||
sp = op_readpc();
|
||||
dp = op_readdp(sp + 0) << 0;
|
||||
dp |= op_readdp(sp + 1) << 8;
|
||||
op_io();
|
||||
dp += regs.y;
|
||||
op_read(dp);
|
||||
op_write(dp, regs.a);
|
||||
}
|
||||
|
||||
void SMPcore::op_movw_ya_dp() {
|
||||
sp = op_readpc();
|
||||
regs.a = op_readdp(sp + 0);
|
||||
op_io();
|
||||
regs.y = op_readdp(sp + 1);
|
||||
regs.p.n = (regs.ya & 0x8000);
|
||||
regs.p.z = (regs.ya == 0);
|
||||
}
|
||||
|
||||
void SMPcore::op_movw_dp_ya() {
|
||||
dp = op_readpc();
|
||||
op_readdp(dp);
|
||||
op_writedp(dp + 0, regs.a);
|
||||
op_writedp(dp + 1, regs.y);
|
||||
}
|
||||
|
||||
void SMPcore::op_mov1_c_bit() {
|
||||
sp = op_readpc() << 0;
|
||||
sp |= op_readpc() << 8;
|
||||
bit = sp >> 13;
|
||||
sp &= 0x1fff;
|
||||
rd = op_read(sp);
|
||||
regs.p.c = (rd & (1 << bit));
|
||||
}
|
||||
|
||||
void SMPcore::op_mov1_bit_c() {
|
||||
dp = op_readpc() << 0;
|
||||
dp |= op_readpc() << 8;
|
||||
bit = dp >> 13;
|
||||
dp &= 0x1fff;
|
||||
rd = op_read(dp);
|
||||
(regs.p.c) ? rd |= (1 << bit) : rd &= ~(1 << bit);
|
||||
op_io();
|
||||
op_write(dp, rd);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,152 +0,0 @@
|
|||
#ifdef SMPCORE_CPP
|
||||
|
||||
void SMPcore::op_bra() {
|
||||
rd = op_readpc();
|
||||
op_io();
|
||||
op_io();
|
||||
regs.pc += (int8)rd;
|
||||
}
|
||||
|
||||
template<int flag, int value> void SMPcore::op_branch() {
|
||||
rd = op_readpc();
|
||||
if((bool)(regs.p & flag) != value) return;
|
||||
op_io();
|
||||
op_io();
|
||||
regs.pc += (int8)rd;
|
||||
}
|
||||
|
||||
template<int mask, int value> void SMPcore::op_bitbranch() {
|
||||
dp = op_readpc();
|
||||
sp = op_readdp(dp);
|
||||
rd = op_readpc();
|
||||
op_io();
|
||||
if((bool)(sp & mask) != value) return;
|
||||
op_io();
|
||||
op_io();
|
||||
regs.pc += (int8)rd;
|
||||
}
|
||||
|
||||
void SMPcore::op_cbne_dp() {
|
||||
dp = op_readpc();
|
||||
sp = op_readdp(dp);
|
||||
rd = op_readpc();
|
||||
op_io();
|
||||
if(regs.a == sp) return;
|
||||
op_io();
|
||||
op_io();
|
||||
regs.pc += (int8)rd;
|
||||
}
|
||||
|
||||
void SMPcore::op_cbne_dpx() {
|
||||
dp = op_readpc();
|
||||
op_io();
|
||||
sp = op_readdp(dp + regs.x);
|
||||
rd = op_readpc();
|
||||
op_io();
|
||||
if(regs.a == sp) return;
|
||||
op_io();
|
||||
op_io();
|
||||
regs.pc += (int8)rd;
|
||||
}
|
||||
|
||||
void SMPcore::op_dbnz_dp() {
|
||||
dp = op_readpc();
|
||||
wr = op_readdp(dp);
|
||||
op_writedp(dp, --wr);
|
||||
rd = op_readpc();
|
||||
if(wr == 0) return;
|
||||
op_io();
|
||||
op_io();
|
||||
regs.pc += (int8)rd;
|
||||
}
|
||||
|
||||
void SMPcore::op_dbnz_y() {
|
||||
rd = op_readpc();
|
||||
op_io();
|
||||
regs.y--;
|
||||
op_io();
|
||||
if(regs.y == 0) return;
|
||||
op_io();
|
||||
op_io();
|
||||
regs.pc += (int8)rd;
|
||||
}
|
||||
|
||||
void SMPcore::op_jmp_addr() {
|
||||
rd = op_readpc() << 0;
|
||||
rd |= op_readpc() << 8;
|
||||
regs.pc = rd;
|
||||
}
|
||||
|
||||
void SMPcore::op_jmp_iaddrx() {
|
||||
dp = op_readpc() << 0;
|
||||
dp |= op_readpc() << 8;
|
||||
op_io();
|
||||
dp += regs.x;
|
||||
rd = op_read(dp + 0) << 0;
|
||||
rd |= op_read(dp + 1) << 8;
|
||||
regs.pc = rd;
|
||||
}
|
||||
|
||||
void SMPcore::op_call() {
|
||||
rd = op_readpc() << 0;
|
||||
rd |= op_readpc() << 8;
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_writesp(regs.pc >> 8);
|
||||
op_writesp(regs.pc >> 0);
|
||||
regs.pc = rd;
|
||||
}
|
||||
|
||||
void SMPcore::op_pcall() {
|
||||
rd = op_readpc();
|
||||
op_io();
|
||||
op_io();
|
||||
op_writesp(regs.pc >> 8);
|
||||
op_writesp(regs.pc >> 0);
|
||||
regs.pc = 0xff00 | rd;
|
||||
}
|
||||
|
||||
template<int n> void SMPcore::op_tcall() {
|
||||
dp = 0xffde - (n << 1);
|
||||
rd = op_read(dp + 0) << 0;
|
||||
rd |= op_read(dp + 1) << 8;
|
||||
op_io();
|
||||
op_io();
|
||||
op_io();
|
||||
op_writesp(regs.pc >> 8);
|
||||
op_writesp(regs.pc >> 0);
|
||||
regs.pc = rd;
|
||||
}
|
||||
|
||||
void SMPcore::op_brk() {
|
||||
rd = op_read(0xffde) << 0;
|
||||
rd |= op_read(0xffdf) << 8;
|
||||
op_io();
|
||||
op_io();
|
||||
op_writesp(regs.pc >> 8);
|
||||
op_writesp(regs.pc >> 0);
|
||||
op_writesp(regs.p);
|
||||
regs.pc = rd;
|
||||
regs.p.b = 1;
|
||||
regs.p.i = 0;
|
||||
}
|
||||
|
||||
void SMPcore::op_ret() {
|
||||
rd = op_readsp() << 0;
|
||||
rd |= op_readsp() << 8;
|
||||
op_io();
|
||||
op_io();
|
||||
regs.pc = rd;
|
||||
}
|
||||
|
||||
void SMPcore::op_reti() {
|
||||
regs.p = op_readsp();
|
||||
rd = op_readsp() << 0;
|
||||
rd |= op_readsp() << 8;
|
||||
op_io();
|
||||
op_io();
|
||||
regs.pc = rd;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,154 +0,0 @@
|
|||
#ifdef SMPCORE_CPP
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8, uint8), int n>
|
||||
void SMPcore::op_read_reg_const() {
|
||||
rd = op_readpc();
|
||||
regs.r[n] = (this->*op)(regs.r[n], rd);
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8, uint8)>
|
||||
void SMPcore::op_read_a_ix() {
|
||||
op_io();
|
||||
rd = op_readdp(regs.x);
|
||||
regs.a = (this->*op)(regs.a, rd);
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8, uint8), int n>
|
||||
void SMPcore::op_read_reg_dp() {
|
||||
dp = op_readpc();
|
||||
rd = op_readdp(dp);
|
||||
regs.r[n] = (this->*op)(regs.r[n], rd);
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8, uint8)>
|
||||
void SMPcore::op_read_a_dpx() {
|
||||
dp = op_readpc();
|
||||
op_io();
|
||||
rd = op_readdp(dp + regs.x);
|
||||
regs.a = (this->*op)(regs.a, rd);
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8, uint8), int n>
|
||||
void SMPcore::op_read_reg_addr() {
|
||||
dp = op_readpc() << 0;
|
||||
dp |= op_readpc() << 8;
|
||||
rd = op_read(dp);
|
||||
regs.r[n] = (this->*op)(regs.r[n], rd);
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8, uint8), int i>
|
||||
void SMPcore::op_read_a_addrr() {
|
||||
dp = op_readpc() << 0;
|
||||
dp |= op_readpc() << 8;
|
||||
op_io();
|
||||
rd = op_read(dp + regs.r[i]);
|
||||
regs.a = (this->*op)(regs.a, rd);
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8, uint8)>
|
||||
void SMPcore::op_read_a_idpx() {
|
||||
dp = op_readpc() + regs.x;
|
||||
op_io();
|
||||
sp = op_readdp(dp + 0) << 0;
|
||||
sp |= op_readdp(dp + 1) << 8;
|
||||
rd = op_read(sp);
|
||||
regs.a = (this->*op)(regs.a, rd);
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8, uint8)>
|
||||
void SMPcore::op_read_a_idpy() {
|
||||
dp = op_readpc();
|
||||
op_io();
|
||||
sp = op_readdp(dp + 0) << 0;
|
||||
sp |= op_readdp(dp + 1) << 8;
|
||||
rd = op_read(sp + regs.y);
|
||||
regs.a = (this->*op)(regs.a, rd);
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8, uint8)>
|
||||
void SMPcore::op_read_ix_iy() {
|
||||
op_io();
|
||||
rd = op_readdp(regs.y);
|
||||
wr = op_readdp(regs.x);
|
||||
wr = (this->*op)(wr, rd);
|
||||
static uint8 (SMPcore::*cmp)(uint8, uint8) = &SMPcore::op_cmp;
|
||||
(op != cmp) ? op_writedp(regs.x, wr) : op_io();
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8, uint8)>
|
||||
void SMPcore::op_read_dp_dp() {
|
||||
sp = op_readpc();
|
||||
rd = op_readdp(sp);
|
||||
dp = op_readpc();
|
||||
wr = op_readdp(dp);
|
||||
wr = (this->*op)(wr, rd);
|
||||
static uint8 (SMPcore::*cmp)(uint8, uint8) = &SMPcore::op_cmp;
|
||||
(op != cmp) ? op_writedp(dp, wr) : op_io();
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8, uint8)>
|
||||
void SMPcore::op_read_dp_const() {
|
||||
rd = op_readpc();
|
||||
dp = op_readpc();
|
||||
wr = op_readdp(dp);
|
||||
wr = (this->*op)(wr, rd);
|
||||
static uint8 (SMPcore::*cmp)(uint8, uint8) = &SMPcore::op_cmp;
|
||||
(op != cmp) ? op_writedp(dp, wr) : op_io();
|
||||
}
|
||||
|
||||
template<uint16 (SMPcore::*op)(uint16, uint16)>
|
||||
void SMPcore::op_read_ya_dp() {
|
||||
dp = op_readpc();
|
||||
rd = op_readdp(dp + 0) << 0;
|
||||
op_io();
|
||||
rd |= op_readdp(dp + 1) << 8;
|
||||
regs.ya = (this->*op)(regs.ya, rd);
|
||||
}
|
||||
|
||||
void SMPcore::op_cmpw_ya_dp() {
|
||||
dp = op_readpc();
|
||||
rd = op_readdp(dp + 0) << 0;
|
||||
rd |= op_readdp(dp + 1) << 8;
|
||||
op_cmpw(regs.ya, rd);
|
||||
}
|
||||
|
||||
template<int op> void SMPcore::op_and1_bit() {
|
||||
dp = op_readpc() << 0;
|
||||
dp |= op_readpc() << 8;
|
||||
bit = dp >> 13;
|
||||
dp &= 0x1fff;
|
||||
rd = op_read(dp);
|
||||
regs.p.c = regs.p.c & ((bool)(rd & (1 << bit)) ^ op);
|
||||
}
|
||||
|
||||
void SMPcore::op_eor1_bit() {
|
||||
dp = op_readpc() << 0;
|
||||
dp |= op_readpc() << 8;
|
||||
bit = dp >> 13;
|
||||
dp &= 0x1fff;
|
||||
rd = op_read(dp);
|
||||
op_io();
|
||||
regs.p.c = regs.p.c ^ (bool)(rd & (1 << bit));
|
||||
}
|
||||
|
||||
void SMPcore::op_not1_bit() {
|
||||
dp = op_readpc() << 0;
|
||||
dp |= op_readpc() << 8;
|
||||
bit = dp >> 13;
|
||||
dp &= 0x1fff;
|
||||
rd = op_read(dp);
|
||||
rd ^= 1 << bit;
|
||||
op_write(dp, rd);
|
||||
}
|
||||
|
||||
template<int op> void SMPcore::op_or1_bit() {
|
||||
dp = op_readpc() << 0;
|
||||
dp |= op_readpc() << 8;
|
||||
bit = dp >> 13;
|
||||
dp &= 0x1fff;
|
||||
rd = op_read(dp);
|
||||
op_io();
|
||||
regs.p.c = regs.p.c | ((bool)(rd & (1 << bit)) ^ op);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,58 +0,0 @@
|
|||
#ifdef SMPCORE_CPP
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8), int n>
|
||||
void SMPcore::op_adjust_reg() {
|
||||
op_io();
|
||||
regs.r[n] = (this->*op)(regs.r[n]);
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8)>
|
||||
void SMPcore::op_adjust_dp() {
|
||||
dp = op_readpc();
|
||||
rd = op_readdp(dp);
|
||||
rd = (this->*op)(rd);
|
||||
op_writedp(dp, rd);
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8)>
|
||||
void SMPcore::op_adjust_dpx() {
|
||||
dp = op_readpc();
|
||||
op_io();
|
||||
rd = op_readdp(dp + regs.x);
|
||||
rd = (this->*op)(rd);
|
||||
op_writedp(dp + regs.x, rd);
|
||||
}
|
||||
|
||||
template<uint8 (SMPcore::*op)(uint8)>
|
||||
void SMPcore::op_adjust_addr() {
|
||||
dp = op_readpc() << 0;
|
||||
dp |= op_readpc() << 8;
|
||||
rd = op_read(dp);
|
||||
rd = (this->*op)(rd);
|
||||
op_write(dp, rd);
|
||||
}
|
||||
|
||||
template<int op>
|
||||
void SMPcore::op_adjust_addr_a() {
|
||||
dp = op_readpc() << 0;
|
||||
dp |= op_readpc() << 8;
|
||||
rd = op_read(dp);
|
||||
regs.p.n = ((regs.a - rd) & 0x80);
|
||||
regs.p.z = ((regs.a - rd) == 0);
|
||||
op_read(dp);
|
||||
op_write(dp, (op ? rd | regs.a : rd & ~regs.a));
|
||||
}
|
||||
|
||||
template<int adjust>
|
||||
void SMPcore::op_adjustw_dp() {
|
||||
dp = op_readpc();
|
||||
rd = op_readdp(dp) << 0;
|
||||
rd += adjust;
|
||||
op_writedp(dp++, rd);
|
||||
rd += op_readdp(dp) << 8;
|
||||
op_writedp(dp, rd >> 8);
|
||||
regs.p.n = (rd & 0x8000);
|
||||
regs.p.z = (rd == 0);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,44 +0,0 @@
|
|||
struct regya_t {
|
||||
uint8_t &hi, &lo;
|
||||
|
||||
inline operator uint16_t() const {
|
||||
return (hi << 8) + lo;
|
||||
}
|
||||
|
||||
inline regya_t& operator=(uint16_t data) {
|
||||
hi = data >> 8;
|
||||
lo = data;
|
||||
return *this;
|
||||
}
|
||||
|
||||
regya_t(uint8_t &hi_, uint8_t &lo_) : hi(hi_), lo(lo_) {}
|
||||
};
|
||||
|
||||
struct flag_t {
|
||||
bool n, v, p, b, h, i, z, c;
|
||||
|
||||
inline operator unsigned() const {
|
||||
return (n << 7) + (v << 6) + (p << 5) + (b << 4)
|
||||
+ (h << 3) + (i << 2) + (z << 1) + (c << 0);
|
||||
}
|
||||
|
||||
inline unsigned operator=(uint8_t data) {
|
||||
n = data & 0x80; v = data & 0x40; p = data & 0x20; b = data & 0x10;
|
||||
h = data & 0x08; i = data & 0x04; z = data & 0x02; c = data & 0x01;
|
||||
return data;
|
||||
}
|
||||
|
||||
inline unsigned operator|=(unsigned data) { return operator=(operator unsigned() | data); }
|
||||
inline unsigned operator^=(unsigned data) { return operator=(operator unsigned() ^ data); }
|
||||
inline unsigned operator&=(unsigned data) { return operator=(operator unsigned() & data); }
|
||||
|
||||
flag_t() : n(0), v(0), p(0), b(0), h(0), i(0), z(0), c(0) {}
|
||||
};
|
||||
|
||||
struct regs_t {
|
||||
uint16_t pc;
|
||||
uint8_t r[4], &a, &x, &y, &sp, &s;
|
||||
regya_t ya;
|
||||
flag_t p;
|
||||
regs_t() : a(r[0]), x(r[1]), y(r[2]), s(r[3]), sp(r[3]), ya(r[2], r[0]) {}
|
||||
};
|
|
@ -1,26 +0,0 @@
|
|||
#ifdef SMPCORE_CPP
|
||||
|
||||
void SMPcore::core_serialize(serializer &s) {
|
||||
s.integer(regs.pc);
|
||||
s.integer(regs.a);
|
||||
s.integer(regs.x);
|
||||
s.integer(regs.y);
|
||||
s.integer(regs.sp);
|
||||
s.integer(regs.p.n);
|
||||
s.integer(regs.p.v);
|
||||
s.integer(regs.p.p);
|
||||
s.integer(regs.p.b);
|
||||
s.integer(regs.p.h);
|
||||
s.integer(regs.p.i);
|
||||
s.integer(regs.p.z);
|
||||
s.integer(regs.p.c);
|
||||
|
||||
s.integer(dp);
|
||||
s.integer(sp);
|
||||
s.integer(rd);
|
||||
s.integer(wr);
|
||||
s.integer(bit);
|
||||
s.integer(ya);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,264 +0,0 @@
|
|||
#ifdef SMPCORE_CPP
|
||||
|
||||
void SMPcore::initialize_opcode_table() {
|
||||
#define op opcode_table
|
||||
op[0x00] = &SMPcore::op_nop;
|
||||
op[0x01] = &SMPcore::op_tcall<0>;
|
||||
op[0x02] = &SMPcore::op_setbit_dp<1, 0x01>;
|
||||
op[0x03] = &SMPcore::op_bitbranch<0x01, true>;
|
||||
op[0x04] = &SMPcore::op_read_reg_dp<&SMPcore::op_or, A>;
|
||||
op[0x05] = &SMPcore::op_read_reg_addr<&SMPcore::op_or, A>;
|
||||
op[0x06] = &SMPcore::op_read_a_ix<&SMPcore::op_or>;
|
||||
op[0x07] = &SMPcore::op_read_a_idpx<&SMPcore::op_or>;
|
||||
op[0x08] = &SMPcore::op_read_reg_const<&SMPcore::op_or, A>;
|
||||
op[0x09] = &SMPcore::op_read_dp_dp<&SMPcore::op_or>;
|
||||
op[0x0a] = &SMPcore::op_or1_bit<0>;
|
||||
op[0x0b] = &SMPcore::op_adjust_dp<&SMPcore::op_asl>;
|
||||
op[0x0c] = &SMPcore::op_adjust_addr<&SMPcore::op_asl>;
|
||||
op[0x0d] = &SMPcore::op_push_p;
|
||||
op[0x0e] = &SMPcore::op_adjust_addr_a<1>;
|
||||
op[0x0f] = &SMPcore::op_brk;
|
||||
op[0x10] = &SMPcore::op_branch<0x80, false>;
|
||||
op[0x11] = &SMPcore::op_tcall<1>;
|
||||
op[0x12] = &SMPcore::op_setbit_dp<0, 0x01>;
|
||||
op[0x13] = &SMPcore::op_bitbranch<0x01, false>;
|
||||
op[0x14] = &SMPcore::op_read_a_dpx<&SMPcore::op_or>;
|
||||
op[0x15] = &SMPcore::op_read_a_addrr<&SMPcore::op_or, X>;
|
||||
op[0x16] = &SMPcore::op_read_a_addrr<&SMPcore::op_or, Y>;
|
||||
op[0x17] = &SMPcore::op_read_a_idpy<&SMPcore::op_or>;
|
||||
op[0x18] = &SMPcore::op_read_dp_const<&SMPcore::op_or>;
|
||||
op[0x19] = &SMPcore::op_read_ix_iy<&SMPcore::op_or>;
|
||||
op[0x1a] = &SMPcore::op_adjustw_dp<-1>;
|
||||
op[0x1b] = &SMPcore::op_adjust_dpx<&SMPcore::op_asl>;
|
||||
op[0x1c] = &SMPcore::op_adjust_reg<&SMPcore::op_asl, A>;
|
||||
op[0x1d] = &SMPcore::op_adjust_reg<&SMPcore::op_dec, X>;
|
||||
op[0x1e] = &SMPcore::op_read_reg_addr<&SMPcore::op_cmp, X>;
|
||||
op[0x1f] = &SMPcore::op_jmp_iaddrx;
|
||||
op[0x20] = &SMPcore::op_setbit<0x20, 0x00>;
|
||||
op[0x21] = &SMPcore::op_tcall<2>;
|
||||
op[0x22] = &SMPcore::op_setbit_dp<1, 0x02>;
|
||||
op[0x23] = &SMPcore::op_bitbranch<0x02, true>;
|
||||
op[0x24] = &SMPcore::op_read_reg_dp<&SMPcore::op_and, A>;
|
||||
op[0x25] = &SMPcore::op_read_reg_addr<&SMPcore::op_and, A>;
|
||||
op[0x26] = &SMPcore::op_read_a_ix<&SMPcore::op_and>;
|
||||
op[0x27] = &SMPcore::op_read_a_idpx<&SMPcore::op_and>;
|
||||
op[0x28] = &SMPcore::op_read_reg_const<&SMPcore::op_and, A>;
|
||||
op[0x29] = &SMPcore::op_read_dp_dp<&SMPcore::op_and>;
|
||||
op[0x2a] = &SMPcore::op_or1_bit<1>;
|
||||
op[0x2b] = &SMPcore::op_adjust_dp<&SMPcore::op_rol>;
|
||||
op[0x2c] = &SMPcore::op_adjust_addr<&SMPcore::op_rol>;
|
||||
op[0x2d] = &SMPcore::op_push_reg<A>;
|
||||
op[0x2e] = &SMPcore::op_cbne_dp;
|
||||
op[0x2f] = &SMPcore::op_bra;
|
||||
op[0x30] = &SMPcore::op_branch<0x80, true>;
|
||||
op[0x31] = &SMPcore::op_tcall<3>;
|
||||
op[0x32] = &SMPcore::op_setbit_dp<0, 0x02>;
|
||||
op[0x33] = &SMPcore::op_bitbranch<0x02, false>;
|
||||
op[0x34] = &SMPcore::op_read_a_dpx<&SMPcore::op_and>;
|
||||
op[0x35] = &SMPcore::op_read_a_addrr<&SMPcore::op_and, X>;
|
||||
op[0x36] = &SMPcore::op_read_a_addrr<&SMPcore::op_and, Y>;
|
||||
op[0x37] = &SMPcore::op_read_a_idpy<&SMPcore::op_and>;
|
||||
op[0x38] = &SMPcore::op_read_dp_const<&SMPcore::op_and>;
|
||||
op[0x39] = &SMPcore::op_read_ix_iy<&SMPcore::op_and>;
|
||||
op[0x3a] = &SMPcore::op_adjustw_dp<+1>;
|
||||
op[0x3b] = &SMPcore::op_adjust_dpx<&SMPcore::op_rol>;
|
||||
op[0x3c] = &SMPcore::op_adjust_reg<&SMPcore::op_rol, A>;
|
||||
op[0x3d] = &SMPcore::op_adjust_reg<&SMPcore::op_inc, X>;
|
||||
op[0x3e] = &SMPcore::op_read_reg_dp<&SMPcore::op_cmp, X>;
|
||||
op[0x3f] = &SMPcore::op_call;
|
||||
op[0x40] = &SMPcore::op_setbit<0x20, 0x20>;
|
||||
op[0x41] = &SMPcore::op_tcall<4>;
|
||||
op[0x42] = &SMPcore::op_setbit_dp<1, 0x04>;
|
||||
op[0x43] = &SMPcore::op_bitbranch<0x04, true>;
|
||||
op[0x44] = &SMPcore::op_read_reg_dp<&SMPcore::op_eor, A>;
|
||||
op[0x45] = &SMPcore::op_read_reg_addr<&SMPcore::op_eor, A>;
|
||||
op[0x46] = &SMPcore::op_read_a_ix<&SMPcore::op_eor>;
|
||||
op[0x47] = &SMPcore::op_read_a_idpx<&SMPcore::op_eor>;
|
||||
op[0x48] = &SMPcore::op_read_reg_const<&SMPcore::op_eor, A>;
|
||||
op[0x49] = &SMPcore::op_read_dp_dp<&SMPcore::op_eor>;
|
||||
op[0x4a] = &SMPcore::op_and1_bit<0>;
|
||||
op[0x4b] = &SMPcore::op_adjust_dp<&SMPcore::op_lsr>;
|
||||
op[0x4c] = &SMPcore::op_adjust_addr<&SMPcore::op_lsr>;
|
||||
op[0x4d] = &SMPcore::op_push_reg<X>;
|
||||
op[0x4e] = &SMPcore::op_adjust_addr_a<0>;
|
||||
op[0x4f] = &SMPcore::op_pcall;
|
||||
op[0x50] = &SMPcore::op_branch<0x40, false>;
|
||||
op[0x51] = &SMPcore::op_tcall<5>;
|
||||
op[0x52] = &SMPcore::op_setbit_dp<0, 0x04>;
|
||||
op[0x53] = &SMPcore::op_bitbranch<0x04, false>;
|
||||
op[0x54] = &SMPcore::op_read_a_dpx<&SMPcore::op_eor>;
|
||||
op[0x55] = &SMPcore::op_read_a_addrr<&SMPcore::op_eor, X>;
|
||||
op[0x56] = &SMPcore::op_read_a_addrr<&SMPcore::op_eor, Y>;
|
||||
op[0x57] = &SMPcore::op_read_a_idpy<&SMPcore::op_eor>;
|
||||
op[0x58] = &SMPcore::op_read_dp_const<&SMPcore::op_eor>;
|
||||
op[0x59] = &SMPcore::op_read_ix_iy<&SMPcore::op_eor>;
|
||||
op[0x5a] = &SMPcore::op_cmpw_ya_dp;
|
||||
op[0x5b] = &SMPcore::op_adjust_dpx<&SMPcore::op_lsr>;
|
||||
op[0x5c] = &SMPcore::op_adjust_reg<&SMPcore::op_lsr, A>;
|
||||
op[0x5d] = &SMPcore::op_mov_reg_reg<X, A>;
|
||||
op[0x5e] = &SMPcore::op_read_reg_addr<&SMPcore::op_cmp, Y>;
|
||||
op[0x5f] = &SMPcore::op_jmp_addr;
|
||||
op[0x60] = &SMPcore::op_setbit<0x01, 0x00>;
|
||||
op[0x61] = &SMPcore::op_tcall<6>;
|
||||
op[0x62] = &SMPcore::op_setbit_dp<1, 0x08>;
|
||||
op[0x63] = &SMPcore::op_bitbranch<0x08, true>;
|
||||
op[0x64] = &SMPcore::op_read_reg_dp<&SMPcore::op_cmp, A>;
|
||||
op[0x65] = &SMPcore::op_read_reg_addr<&SMPcore::op_cmp, A>;
|
||||
op[0x66] = &SMPcore::op_read_a_ix<&SMPcore::op_cmp>;
|
||||
op[0x67] = &SMPcore::op_read_a_idpx<&SMPcore::op_cmp>;
|
||||
op[0x68] = &SMPcore::op_read_reg_const<&SMPcore::op_cmp, A>;
|
||||
op[0x69] = &SMPcore::op_read_dp_dp<&SMPcore::op_cmp>;
|
||||
op[0x6a] = &SMPcore::op_and1_bit<1>;
|
||||
op[0x6b] = &SMPcore::op_adjust_dp<&SMPcore::op_ror>;
|
||||
op[0x6c] = &SMPcore::op_adjust_addr<&SMPcore::op_ror>;
|
||||
op[0x6d] = &SMPcore::op_push_reg<Y>;
|
||||
op[0x6e] = &SMPcore::op_dbnz_dp;
|
||||
op[0x6f] = &SMPcore::op_ret;
|
||||
op[0x70] = &SMPcore::op_branch<0x40, true>;
|
||||
op[0x71] = &SMPcore::op_tcall<7>;
|
||||
op[0x72] = &SMPcore::op_setbit_dp<0, 0x08>;
|
||||
op[0x73] = &SMPcore::op_bitbranch<0x08, false>;
|
||||
op[0x74] = &SMPcore::op_read_a_dpx<&SMPcore::op_cmp>;
|
||||
op[0x75] = &SMPcore::op_read_a_addrr<&SMPcore::op_cmp, X>;
|
||||
op[0x76] = &SMPcore::op_read_a_addrr<&SMPcore::op_cmp, Y>;
|
||||
op[0x77] = &SMPcore::op_read_a_idpy<&SMPcore::op_cmp>;
|
||||
op[0x78] = &SMPcore::op_read_dp_const<&SMPcore::op_cmp>;
|
||||
op[0x79] = &SMPcore::op_read_ix_iy<&SMPcore::op_cmp>;
|
||||
op[0x7a] = &SMPcore::op_read_ya_dp<&SMPcore::op_addw>;
|
||||
op[0x7b] = &SMPcore::op_adjust_dpx<&SMPcore::op_ror>;
|
||||
op[0x7c] = &SMPcore::op_adjust_reg<&SMPcore::op_ror, A>;
|
||||
op[0x7d] = &SMPcore::op_mov_reg_reg<A, X>;
|
||||
op[0x7e] = &SMPcore::op_read_reg_dp<&SMPcore::op_cmp, Y>;
|
||||
op[0x7f] = &SMPcore::op_reti;
|
||||
op[0x80] = &SMPcore::op_setbit<0x01, 0x01>;
|
||||
op[0x81] = &SMPcore::op_tcall<8>;
|
||||
op[0x82] = &SMPcore::op_setbit_dp<1, 0x10>;
|
||||
op[0x83] = &SMPcore::op_bitbranch<0x10, true>;
|
||||
op[0x84] = &SMPcore::op_read_reg_dp<&SMPcore::op_adc, A>;
|
||||
op[0x85] = &SMPcore::op_read_reg_addr<&SMPcore::op_adc, A>;
|
||||
op[0x86] = &SMPcore::op_read_a_ix<&SMPcore::op_adc>;
|
||||
op[0x87] = &SMPcore::op_read_a_idpx<&SMPcore::op_adc>;
|
||||
op[0x88] = &SMPcore::op_read_reg_const<&SMPcore::op_adc, A>;
|
||||
op[0x89] = &SMPcore::op_read_dp_dp<&SMPcore::op_adc>;
|
||||
op[0x8a] = &SMPcore::op_eor1_bit;
|
||||
op[0x8b] = &SMPcore::op_adjust_dp<&SMPcore::op_dec>;
|
||||
op[0x8c] = &SMPcore::op_adjust_addr<&SMPcore::op_dec>;
|
||||
op[0x8d] = &SMPcore::op_mov_reg_const<Y>;
|
||||
op[0x8e] = &SMPcore::op_pop_p;
|
||||
op[0x8f] = &SMPcore::op_mov_dp_const;
|
||||
op[0x90] = &SMPcore::op_branch<0x01, false>;
|
||||
op[0x91] = &SMPcore::op_tcall<9>;
|
||||
op[0x92] = &SMPcore::op_setbit_dp<0, 0x10>;
|
||||
op[0x93] = &SMPcore::op_bitbranch<0x10, false>;
|
||||
op[0x94] = &SMPcore::op_read_a_dpx<&SMPcore::op_adc>;
|
||||
op[0x95] = &SMPcore::op_read_a_addrr<&SMPcore::op_adc, X>;
|
||||
op[0x96] = &SMPcore::op_read_a_addrr<&SMPcore::op_adc, Y>;
|
||||
op[0x97] = &SMPcore::op_read_a_idpy<&SMPcore::op_adc>;
|
||||
op[0x98] = &SMPcore::op_read_dp_const<&SMPcore::op_adc>;
|
||||
op[0x99] = &SMPcore::op_read_ix_iy<&SMPcore::op_adc>;
|
||||
op[0x9a] = &SMPcore::op_read_ya_dp<&SMPcore::op_subw>;
|
||||
op[0x9b] = &SMPcore::op_adjust_dpx<&SMPcore::op_dec>;
|
||||
op[0x9c] = &SMPcore::op_adjust_reg<&SMPcore::op_dec, A>;
|
||||
op[0x9d] = &SMPcore::op_mov_reg_reg<X, SP>;
|
||||
op[0x9e] = &SMPcore::op_div_ya_x;
|
||||
op[0x9f] = &SMPcore::op_xcn;
|
||||
op[0xa0] = &SMPcore::op_seti<1>;
|
||||
op[0xa1] = &SMPcore::op_tcall<10>;
|
||||
op[0xa2] = &SMPcore::op_setbit_dp<1, 0x20>;
|
||||
op[0xa3] = &SMPcore::op_bitbranch<0x20, true>;
|
||||
op[0xa4] = &SMPcore::op_read_reg_dp<&SMPcore::op_sbc, A>;
|
||||
op[0xa5] = &SMPcore::op_read_reg_addr<&SMPcore::op_sbc, A>;
|
||||
op[0xa6] = &SMPcore::op_read_a_ix<&SMPcore::op_sbc>;
|
||||
op[0xa7] = &SMPcore::op_read_a_idpx<&SMPcore::op_sbc>;
|
||||
op[0xa8] = &SMPcore::op_read_reg_const<&SMPcore::op_sbc, A>;
|
||||
op[0xa9] = &SMPcore::op_read_dp_dp<&SMPcore::op_sbc>;
|
||||
op[0xaa] = &SMPcore::op_mov1_c_bit;
|
||||
op[0xab] = &SMPcore::op_adjust_dp<&SMPcore::op_inc>;
|
||||
op[0xac] = &SMPcore::op_adjust_addr<&SMPcore::op_inc>;
|
||||
op[0xad] = &SMPcore::op_read_reg_const<&SMPcore::op_cmp, Y>;
|
||||
op[0xae] = &SMPcore::op_pop_reg<A>;
|
||||
op[0xaf] = &SMPcore::op_mov_ixinc_a;
|
||||
op[0xb0] = &SMPcore::op_branch<0x01, true>;
|
||||
op[0xb1] = &SMPcore::op_tcall<11>;
|
||||
op[0xb2] = &SMPcore::op_setbit_dp<0, 0x20>;
|
||||
op[0xb3] = &SMPcore::op_bitbranch<0x20, false>;
|
||||
op[0xb4] = &SMPcore::op_read_a_dpx<&SMPcore::op_sbc>;
|
||||
op[0xb5] = &SMPcore::op_read_a_addrr<&SMPcore::op_sbc, X>;
|
||||
op[0xb6] = &SMPcore::op_read_a_addrr<&SMPcore::op_sbc, Y>;
|
||||
op[0xb7] = &SMPcore::op_read_a_idpy<&SMPcore::op_sbc>;
|
||||
op[0xb8] = &SMPcore::op_read_dp_const<&SMPcore::op_sbc>;
|
||||
op[0xb9] = &SMPcore::op_read_ix_iy<&SMPcore::op_sbc>;
|
||||
op[0xba] = &SMPcore::op_movw_ya_dp;
|
||||
op[0xbb] = &SMPcore::op_adjust_dpx<&SMPcore::op_inc>;
|
||||
op[0xbc] = &SMPcore::op_adjust_reg<&SMPcore::op_inc, A>;
|
||||
op[0xbd] = &SMPcore::op_mov_sp_x;
|
||||
op[0xbe] = &SMPcore::op_das;
|
||||
op[0xbf] = &SMPcore::op_mov_a_ixinc;
|
||||
op[0xc0] = &SMPcore::op_seti<0>;
|
||||
op[0xc1] = &SMPcore::op_tcall<12>;
|
||||
op[0xc2] = &SMPcore::op_setbit_dp<1, 0x40>;
|
||||
op[0xc3] = &SMPcore::op_bitbranch<0x40, true>;
|
||||
op[0xc4] = &SMPcore::op_mov_dp_reg<A>;
|
||||
op[0xc5] = &SMPcore::op_mov_addr_reg<A>;
|
||||
op[0xc6] = &SMPcore::op_mov_ix_a;
|
||||
op[0xc7] = &SMPcore::op_mov_idpx_a;
|
||||
op[0xc8] = &SMPcore::op_read_reg_const<&SMPcore::op_cmp, X>;
|
||||
op[0xc9] = &SMPcore::op_mov_addr_reg<X>;
|
||||
op[0xca] = &SMPcore::op_mov1_bit_c;
|
||||
op[0xcb] = &SMPcore::op_mov_dp_reg<Y>;
|
||||
op[0xcc] = &SMPcore::op_mov_addr_reg<Y>;
|
||||
op[0xcd] = &SMPcore::op_mov_reg_const<X>;
|
||||
op[0xce] = &SMPcore::op_pop_reg<X>;
|
||||
op[0xcf] = &SMPcore::op_mul_ya;
|
||||
op[0xd0] = &SMPcore::op_branch<0x02, false>;
|
||||
op[0xd1] = &SMPcore::op_tcall<13>;
|
||||
op[0xd2] = &SMPcore::op_setbit_dp<0, 0x40>;
|
||||
op[0xd3] = &SMPcore::op_bitbranch<0x40, false>;
|
||||
op[0xd4] = &SMPcore::op_mov_dpr_reg<A, X>;
|
||||
op[0xd5] = &SMPcore::op_mov_addrr_a<X>;
|
||||
op[0xd6] = &SMPcore::op_mov_addrr_a<Y>;
|
||||
op[0xd7] = &SMPcore::op_mov_idpy_a;
|
||||
op[0xd8] = &SMPcore::op_mov_dp_reg<X>;
|
||||
op[0xd9] = &SMPcore::op_mov_dpr_reg<X, Y>;
|
||||
op[0xda] = &SMPcore::op_movw_dp_ya;
|
||||
op[0xdb] = &SMPcore::op_mov_dpr_reg<Y, X>;
|
||||
op[0xdc] = &SMPcore::op_adjust_reg<&SMPcore::op_dec, Y>;
|
||||
op[0xdd] = &SMPcore::op_mov_reg_reg<A, Y>;
|
||||
op[0xde] = &SMPcore::op_cbne_dpx;
|
||||
op[0xdf] = &SMPcore::op_daa;
|
||||
op[0xe0] = &SMPcore::op_setbit<0x48, 0x00>;
|
||||
op[0xe1] = &SMPcore::op_tcall<14>;
|
||||
op[0xe2] = &SMPcore::op_setbit_dp<1, 0x80>;
|
||||
op[0xe3] = &SMPcore::op_bitbranch<0x80, true>;
|
||||
op[0xe4] = &SMPcore::op_mov_reg_dp<A>;
|
||||
op[0xe5] = &SMPcore::op_mov_reg_addr<A>;
|
||||
op[0xe6] = &SMPcore::op_mov_a_ix;
|
||||
op[0xe7] = &SMPcore::op_mov_a_idpx;
|
||||
op[0xe8] = &SMPcore::op_mov_reg_const<A>;
|
||||
op[0xe9] = &SMPcore::op_mov_reg_addr<X>;
|
||||
op[0xea] = &SMPcore::op_not1_bit;
|
||||
op[0xeb] = &SMPcore::op_mov_reg_dp<Y>;
|
||||
op[0xec] = &SMPcore::op_mov_reg_addr<Y>;
|
||||
op[0xed] = &SMPcore::op_notc;
|
||||
op[0xee] = &SMPcore::op_pop_reg<Y>;
|
||||
op[0xef] = &SMPcore::op_wait;
|
||||
op[0xf0] = &SMPcore::op_branch<0x02, true>;
|
||||
op[0xf1] = &SMPcore::op_tcall<15>;
|
||||
op[0xf2] = &SMPcore::op_setbit_dp<0, 0x80>;
|
||||
op[0xf3] = &SMPcore::op_bitbranch<0x80, false>;
|
||||
op[0xf4] = &SMPcore::op_mov_reg_dpr<A, X>;
|
||||
op[0xf5] = &SMPcore::op_mov_a_addrr<X>;
|
||||
op[0xf6] = &SMPcore::op_mov_a_addrr<Y>;
|
||||
op[0xf7] = &SMPcore::op_mov_a_idpy;
|
||||
op[0xf8] = &SMPcore::op_mov_reg_dp<X>;
|
||||
op[0xf9] = &SMPcore::op_mov_reg_dpr<X, Y>;
|
||||
op[0xfa] = &SMPcore::op_mov_dp_dp;
|
||||
op[0xfb] = &SMPcore::op_mov_reg_dpr<Y, X>;
|
||||
op[0xfc] = &SMPcore::op_adjust_reg<&SMPcore::op_inc, Y>;
|
||||
op[0xfd] = &SMPcore::op_mov_reg_reg<Y, A>;
|
||||
op[0xfe] = &SMPcore::op_dbnz_y;
|
||||
op[0xff] = &SMPcore::op_wait;
|
||||
#undef op
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,75 +0,0 @@
|
|||
#ifdef SMP_CPP
|
||||
|
||||
void SMPDebugger::op_step() {
|
||||
bool break_event = false;
|
||||
|
||||
usage[regs.pc] |= UsageExec;
|
||||
opcode_pc = regs.pc;
|
||||
|
||||
opcode_edge = true;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Exec, regs.pc, 0x00);
|
||||
if(step_event && step_event() == true) {
|
||||
debugger.break_event = Debugger::BreakEvent::SMPStep;
|
||||
scheduler.exit(Scheduler::ExitReason::DebuggerEvent);
|
||||
}
|
||||
opcode_edge = false;
|
||||
|
||||
SMP::op_step();
|
||||
synchronize_cpu();
|
||||
}
|
||||
|
||||
uint8 SMPDebugger::op_read(uint16 addr) {
|
||||
uint8 data = SMP::op_read(addr);
|
||||
usage[addr] |= UsageRead;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Read, addr, data);
|
||||
return data;
|
||||
}
|
||||
|
||||
void SMPDebugger::op_write(uint16 addr, uint8 data) {
|
||||
SMP::op_write(addr, data);
|
||||
usage[addr] |= UsageWrite;
|
||||
usage[addr] &= ~UsageExec;
|
||||
debugger.breakpoint_test(Debugger::Breakpoint::Source::APURAM, Debugger::Breakpoint::Mode::Write, addr, data);
|
||||
}
|
||||
|
||||
SMPDebugger::SMPDebugger() {
|
||||
usage = new uint8[1 << 16]();
|
||||
opcode_pc = 0xffc0;
|
||||
opcode_edge = false;
|
||||
}
|
||||
|
||||
SMPDebugger::~SMPDebugger() {
|
||||
delete[] usage;
|
||||
}
|
||||
|
||||
bool SMPDebugger::property(unsigned id, string &name, string &value) {
|
||||
unsigned n = 0;
|
||||
|
||||
#define item(name_, value_) \
|
||||
if(id == n++) { \
|
||||
name = name_; \
|
||||
value = value_; \
|
||||
return true; \
|
||||
}
|
||||
|
||||
//$00f0
|
||||
item("$00f0", "");
|
||||
item("Clock Speed", (unsigned)status.clock_speed);
|
||||
item("Timers Enable", status.timers_enable);
|
||||
item("RAM Disable", status.ram_disable);
|
||||
item("RAM Writable", status.ram_writable);
|
||||
item("Timers Disable", status.timers_disable);
|
||||
|
||||
//$00f1
|
||||
item("$00f1", "");
|
||||
item("IPLROM Enable", status.iplrom_enable);
|
||||
|
||||
//$00f2
|
||||
item("$00f2", "");
|
||||
item("DSP Address", string("0x", hex<2>(status.dsp_addr)));
|
||||
|
||||
#undef item
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,22 +0,0 @@
|
|||
class SMPDebugger : public SMP, public ChipDebugger {
|
||||
public:
|
||||
bool property(unsigned id, string &name, string &value);
|
||||
|
||||
function<bool ()> step_event;
|
||||
|
||||
enum Usage {
|
||||
UsageRead = 0x80,
|
||||
UsageWrite = 0x40,
|
||||
UsageExec = 0x20,
|
||||
};
|
||||
uint8 *usage;
|
||||
uint16 opcode_pc;
|
||||
bool opcode_edge;
|
||||
|
||||
void op_step();
|
||||
uint8 op_read(uint16 addr);
|
||||
void op_write(uint16 addr, uint8 data);
|
||||
|
||||
SMPDebugger();
|
||||
~SMPDebugger();
|
||||
};
|
|
@ -5,5 +5,5 @@ uint8 op_busread(uint16 addr);
|
|||
void op_buswrite(uint16 addr, uint8 data);
|
||||
|
||||
void op_io();
|
||||
debugvirtual uint8 op_read(uint16 addr);
|
||||
debugvirtual void op_write(uint16 addr, uint8 data);
|
||||
uint8 op_read(uint16 addr);
|
||||
void op_write(uint16 addr, uint8 data);
|
||||
|
|
|
@ -3,12 +3,7 @@
|
|||
#define SMP_CPP
|
||||
namespace SNES {
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.cpp"
|
||||
SMPDebugger smp;
|
||||
#else
|
||||
SMP smp;
|
||||
#endif
|
||||
SMP smp;
|
||||
|
||||
#include "serialization.cpp"
|
||||
#include "iplrom.cpp"
|
||||
|
|
|
@ -50,12 +50,6 @@ private:
|
|||
static void Enter();
|
||||
|
||||
friend class SMPcore;
|
||||
friend class SMPDebugger;
|
||||
};
|
||||
|
||||
#if defined(DEBUGGER)
|
||||
#include "debugger/debugger.hpp"
|
||||
extern SMPDebugger smp;
|
||||
#else
|
||||
extern SMP smp;
|
||||
#endif
|
||||
extern SMP smp;
|
||||
|
|
|
@ -40,12 +40,6 @@ using namespace nall;
|
|||
|
||||
#include <gameboy/gameboy.hpp>
|
||||
|
||||
#ifdef DEBUGGER
|
||||
#define debugvirtual virtual
|
||||
#else
|
||||
#define debugvirtual
|
||||
#endif
|
||||
|
||||
namespace SNES {
|
||||
typedef int8_t int8;
|
||||
typedef int16_t int16;
|
||||
|
@ -126,10 +120,6 @@ namespace SNES {
|
|||
}
|
||||
};
|
||||
|
||||
struct ChipDebugger {
|
||||
virtual bool property(unsigned id, string &name, string &value) = 0;
|
||||
};
|
||||
|
||||
#include <snes/memory/memory.hpp>
|
||||
#include <snes/cpu/core/core.hpp>
|
||||
#include <snes/smp/core/core.hpp>
|
||||
|
@ -154,6 +144,4 @@ namespace SNES {
|
|||
#include <snes/ppu/counter/counter-inline.hpp>
|
||||
}
|
||||
|
||||
#undef debugvirtual
|
||||
|
||||
#endif
|
||||
|
|
|
@ -6,42 +6,42 @@ MainWindow::MainWindow() {
|
|||
setBackgroundColor({ 0, 0, 0 });
|
||||
windowManager->append(this, "MainWindow");
|
||||
|
||||
cartridgeMenu.setText("Cartridge");
|
||||
cartridgeLoadSNES.setText("Load SNES Cartridge ...");
|
||||
cartridgeLoadNES.setText("Load NES Cartridge ...");
|
||||
cartridgeLoadGameBoy.setText("Load Game Boy Cartridge ...");
|
||||
cartridgeLoadGameBoyColor.setText("Load Game Boy Color Cartridge ...");
|
||||
cartridgeMenu.setText("&Cartridge");
|
||||
cartridgeLoadSNES.setText("Load &SNES Cartridge ...");
|
||||
cartridgeLoadNES.setText("Load &NES Cartridge ...");
|
||||
cartridgeLoadGameBoy.setText("Load &Game Boy Cartridge ...");
|
||||
cartridgeLoadGameBoyColor.setText("Load Game Boy &Color Cartridge ...");
|
||||
cartridgeLoadSatellaviewSlotted.setText("Load Satellaview-Slotted Cartridge ...");
|
||||
cartridgeLoadSatellaview.setText("Load Satellaview Cartridge ...");
|
||||
cartridgeLoadSufamiTurbo.setText("Load Sufami Turbo Cartridge ...");
|
||||
cartridgeLoadSuperGameBoy.setText("Load Super Game Boy Cartridge ...");
|
||||
|
||||
nesMenu.setText("NES");
|
||||
nesPower.setText("Power Cycle");
|
||||
nesReset.setText("Reset");
|
||||
nesPort1.setText("Controller Port 1");
|
||||
nesMenu.setText("&NES");
|
||||
nesPower.setText("&Power Cycle");
|
||||
nesReset.setText("&Reset");
|
||||
nesPort1.setText("Controller Port &1");
|
||||
nesPort1Device[0].setText("None");
|
||||
nesPort1Device[1].setText("Gamepad");
|
||||
RadioItem::group(nesPort1Device[0], nesPort1Device[1]);
|
||||
nesPort1Device[config->nes.controllerPort1Device].setChecked();
|
||||
nesPort2.setText("Controller Port 2");
|
||||
nesPort2.setText("Controller Port &2");
|
||||
nesPort2Device[0].setText("None");
|
||||
nesPort2Device[1].setText("Gamepad");
|
||||
RadioItem::group(nesPort2Device[0], nesPort2Device[1]);
|
||||
nesPort2Device[config->nes.controllerPort2Device].setChecked();
|
||||
nesCartridgeUnload.setText("Unload Cartridge");
|
||||
nesCartridgeUnload.setText("&Unload Cartridge");
|
||||
|
||||
snesMenu.setText("SNES");
|
||||
snesPower.setText("Power Cycle");
|
||||
snesReset.setText("Reset");
|
||||
snesPort1.setText("Controller Port 1");
|
||||
snesMenu.setText("&SNES");
|
||||
snesPower.setText("&Power Cycle");
|
||||
snesReset.setText("&Reset");
|
||||
snesPort1.setText("Controller Port &1");
|
||||
snesPort1Device[0].setText("None");
|
||||
snesPort1Device[1].setText("Gamepad");
|
||||
snesPort1Device[2].setText("Multitap");
|
||||
snesPort1Device[3].setText("Mouse");
|
||||
RadioItem::group(snesPort1Device[0], snesPort1Device[1], snesPort1Device[2], snesPort1Device[3]);
|
||||
snesPort1Device[config->snes.controllerPort1Device].setChecked();
|
||||
snesPort2.setText("Controller Port 2");
|
||||
snesPort2.setText("Controller Port &2");
|
||||
snesPort2Device[0].setText("None");
|
||||
snesPort2Device[1].setText("Gamepad");
|
||||
snesPort2Device[2].setText("Multitap");
|
||||
|
@ -53,48 +53,48 @@ MainWindow::MainWindow() {
|
|||
RadioItem::group(snesPort2Device[0], snesPort2Device[1], snesPort2Device[2], snesPort2Device[3],
|
||||
snesPort2Device[4], snesPort2Device[5], snesPort2Device[6], snesPort2Device[7]);
|
||||
snesPort2Device[config->snes.controllerPort2Device].setChecked();
|
||||
snesCartridgeUnload.setText("Unload Cartridge");
|
||||
snesCartridgeUnload.setText("&Unload Cartridge");
|
||||
|
||||
gameBoyMenu.setText("Game Boy");
|
||||
gameBoyPower.setText("Power Cycle");
|
||||
gameBoyCartridgeUnload.setText("Unload Cartridge");
|
||||
gameBoyMenu.setText("&Game Boy");
|
||||
gameBoyPower.setText("&Power Cycle");
|
||||
gameBoyCartridgeUnload.setText("&Unload Cartridge");
|
||||
|
||||
settingsMenu.setText("Settings");
|
||||
settingsVideoFilter.setText("Video Filter");
|
||||
settingsMenu.setText("S&ettings");
|
||||
settingsVideoFilter.setText("Video &Filter");
|
||||
settingsVideoFilterNone.setText("None");
|
||||
setupVideoFilters();
|
||||
settingsVideoShader.setText("Video Shader");
|
||||
settingsVideoShader.setText("Video &Shader");
|
||||
settingsVideoShaderNone.setText("None");
|
||||
settingsVideoShaderBlur.setText("Blur");
|
||||
setupVideoShaders();
|
||||
settingsSynchronizeVideo.setText("Synchronize Video");
|
||||
settingsSynchronizeVideo.setText("Synchronize &Video");
|
||||
settingsSynchronizeVideo.setChecked(config->video.synchronize);
|
||||
settingsSynchronizeAudio.setText("Synchronize Audio");
|
||||
settingsSynchronizeAudio.setText("Synchronize &Audio");
|
||||
settingsSynchronizeAudio.setChecked(config->audio.synchronize);
|
||||
settingsCorrectAspectRatio.setText("Correct Aspect Ratio");
|
||||
settingsCorrectAspectRatio.setText("Correct Aspect &Ratio");
|
||||
settingsCorrectAspectRatio.setChecked(config->video.correctAspectRatio);
|
||||
settingsMaskOverscan.setText("Mask Overscan");
|
||||
settingsMaskOverscan.setText("Mask &Overscan");
|
||||
settingsMaskOverscan.setChecked(config->video.maskOverscan);
|
||||
settingsMuteAudio.setText("Mute Audio");
|
||||
settingsMuteAudio.setText("&Mute Audio");
|
||||
settingsMuteAudio.setChecked(config->audio.mute);
|
||||
settingsConfiguration.setText("Configuration ...");
|
||||
settingsConfiguration.setText("&Configuration ...");
|
||||
|
||||
toolsMenu.setText("Tools");
|
||||
toolsStateSave.setText("Save State");
|
||||
toolsStateSave1.setText("Slot 1");
|
||||
toolsStateSave2.setText("Slot 2");
|
||||
toolsStateSave3.setText("Slot 3");
|
||||
toolsStateSave4.setText("Slot 4");
|
||||
toolsStateSave5.setText("Slot 5");
|
||||
toolsStateLoad.setText("Load State");
|
||||
toolsStateLoad1.setText("Slot 1");
|
||||
toolsStateLoad2.setText("Slot 2");
|
||||
toolsStateLoad3.setText("Slot 3");
|
||||
toolsStateLoad4.setText("Slot 4");
|
||||
toolsStateLoad5.setText("Slot 5");
|
||||
toolsShrinkWindow.setText("Shrink Window");
|
||||
toolsCheatEditor.setText("Cheat Editor ...");
|
||||
toolsStateManager.setText("State Manager ...");
|
||||
toolsMenu.setText("&Tools");
|
||||
toolsStateSave.setText("&Save State");
|
||||
toolsStateSave1.setText("Slot &1");
|
||||
toolsStateSave2.setText("Slot &2");
|
||||
toolsStateSave3.setText("Slot &3");
|
||||
toolsStateSave4.setText("Slot &4");
|
||||
toolsStateSave5.setText("Slot &5");
|
||||
toolsStateLoad.setText("&Load State");
|
||||
toolsStateLoad1.setText("Slot &1");
|
||||
toolsStateLoad2.setText("Slot &2");
|
||||
toolsStateLoad3.setText("Slot &3");
|
||||
toolsStateLoad4.setText("Slot &4");
|
||||
toolsStateLoad5.setText("Slot &5");
|
||||
toolsShrinkWindow.setText("Shrink &Window");
|
||||
toolsCheatEditor.setText("&Cheat Editor ...");
|
||||
toolsStateManager.setText("State &Manager ...");
|
||||
|
||||
append(cartridgeMenu);
|
||||
cartridgeMenu.append(cartridgeLoadNES);
|
||||
|
|
|
@ -27,7 +27,7 @@ void Application::run() {
|
|||
}
|
||||
|
||||
Application::Application(int argc, char **argv) {
|
||||
title = "bsnes v085.02";
|
||||
title = "bsnes v085.03";
|
||||
|
||||
application = this;
|
||||
quit = false;
|
||||
|
|
Loading…
Reference in New Issue