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 prgram = 0;
|
||||||
unsigned chrram = chrrom == 0 ? 8192 : 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("<?xml version='1.0' encoding='UTF-8'?>\n");
|
||||||
output.append("<cartridge>\n");
|
output.append("<cartridge>\n");
|
||||||
|
@ -151,7 +151,7 @@ static string iNES(const uint8_t *data, unsigned size) {
|
||||||
"</cartridge>\n"
|
"</cartridge>\n"
|
||||||
);
|
);
|
||||||
|
|
||||||
print(output, "\n");
|
//print(output, "\n");
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,10 +2,6 @@ void pAction::setEnabled(bool enabled) {
|
||||||
gtk_widget_set_sensitive(widget, enabled);
|
gtk_widget_set_sensitive(widget, enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pAction::setFont(const string &font) {
|
|
||||||
pFont::setFont(widget, font);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pAction::setVisible(bool visible) {
|
void pAction::setVisible(bool visible) {
|
||||||
gtk_widget_set_visible(widget, visible);
|
gtk_widget_set_visible(widget, visible);
|
||||||
}
|
}
|
||||||
|
@ -15,3 +11,17 @@ void pAction::constructor() {
|
||||||
|
|
||||||
void pAction::orphan() {
|
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) {
|
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() {
|
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);
|
setChecked(checkItem.state.checked);
|
||||||
|
setText(checkItem.state.text);
|
||||||
g_signal_connect_swapped(G_OBJECT(widget), "toggled", G_CALLBACK(CheckItem_toggle), (gpointer)&checkItem);
|
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) {
|
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() {
|
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);
|
g_signal_connect_swapped(G_OBJECT(widget), "activate", G_CALLBACK(Item_activate), (gpointer)&item);
|
||||||
|
setText(item.state.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pItem::destructor() {
|
void pItem::destructor() {
|
||||||
|
|
|
@ -19,13 +19,14 @@ void pMenu::setImage(const image &image) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pMenu::setText(const string &text) {
|
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() {
|
void pMenu::constructor() {
|
||||||
gtkMenu = gtk_menu_new();
|
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);
|
gtk_menu_item_set_submenu(GTK_MENU_ITEM(widget), gtkMenu);
|
||||||
|
setText(menu.state.text);
|
||||||
}
|
}
|
||||||
|
|
||||||
void pMenu::destructor() {
|
void pMenu::destructor() {
|
||||||
|
|
|
@ -25,12 +25,13 @@ void pRadioItem::setGroup(const array<RadioItem&> &group) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void pRadioItem::setText(const string &text) {
|
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() {
|
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);
|
setGroup(radioItem.state.group);
|
||||||
|
setText(radioItem.state.text);
|
||||||
for(auto &item : radioItem.state.group) {
|
for(auto &item : radioItem.state.group) {
|
||||||
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item.p.widget), item.state.checked);
|
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) {}
|
pAction(Action &action) : pObject(action), action(action) {}
|
||||||
void constructor();
|
void constructor();
|
||||||
virtual void orphan();
|
virtual void orphan();
|
||||||
|
string mnemonic(string text);
|
||||||
virtual void setFont(const string &font);
|
virtual void setFont(const string &font);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -168,13 +168,11 @@ void pWindow::setFullScreen(bool fullScreen) {
|
||||||
if(fullScreen == false) {
|
if(fullScreen == false) {
|
||||||
gtk_window_unfullscreen(GTK_WINDOW(widget));
|
gtk_window_unfullscreen(GTK_WINDOW(widget));
|
||||||
gtk_window_set_resizable(GTK_WINDOW(widget), window.state.resizable);
|
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);
|
gtk_widget_set_size_request(widget, -1, -1);
|
||||||
gdk_display_sync(gtk_widget_get_display(widget));
|
gdk_display_sync(gtk_widget_get_display(widget));
|
||||||
setGeometry(window.state.geometry);
|
setGeometry(window.state.geometry);
|
||||||
} else {
|
} else {
|
||||||
gtk_window_fullscreen(GTK_WINDOW(widget));
|
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_widget_set_size_request(widget, Desktop::size().width, Desktop::size().height);
|
||||||
gtk_window_set_resizable(GTK_WINDOW(widget), false);
|
gtk_window_set_resizable(GTK_WINDOW(widget), false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
** Meta object code from reading C++ file 'platform.moc.hpp'
|
** 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)
|
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.3)
|
||||||
**
|
**
|
||||||
** WARNING! All changes made in this file will be lost!
|
** WARNING! All changes made in this file will be lost!
|
||||||
|
|
|
@ -115,6 +115,7 @@ public:
|
||||||
|
|
||||||
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
SDL_InitSubSystem(SDL_INIT_VIDEO);
|
||||||
screen = SDL_SetVideoMode(2560, 1600, 32, SDL_HWSURFACE);
|
screen = SDL_SetVideoMode(2560, 1600, 32, SDL_HWSURFACE);
|
||||||
|
XUndefineCursor(display, settings.handle);
|
||||||
|
|
||||||
buffer = 0;
|
buffer = 0;
|
||||||
iwidth = 0;
|
iwidth = 0;
|
||||||
|
|
|
@ -3,12 +3,7 @@
|
||||||
#define CPU_CPP
|
#define CPU_CPP
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
CPU cpu;
|
||||||
#include "debugger/debugger.cpp"
|
|
||||||
CPUDebugger cpu;
|
|
||||||
#else
|
|
||||||
CPU cpu;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "serialization.cpp"
|
#include "serialization.cpp"
|
||||||
#include "dma.cpp"
|
#include "dma.cpp"
|
||||||
|
|
|
@ -19,8 +19,8 @@ public:
|
||||||
void mmio_write(unsigned addr, uint8 data);
|
void mmio_write(unsigned addr, uint8 data);
|
||||||
|
|
||||||
void op_io();
|
void op_io();
|
||||||
debugvirtual uint8 op_read(unsigned addr);
|
uint8 op_read(unsigned addr);
|
||||||
debugvirtual void op_write(unsigned addr, uint8 data);
|
void op_write(unsigned addr, uint8 data);
|
||||||
|
|
||||||
void enter();
|
void enter();
|
||||||
void enable();
|
void enable();
|
||||||
|
@ -34,7 +34,7 @@ public:
|
||||||
private:
|
private:
|
||||||
//cpu
|
//cpu
|
||||||
static void Enter();
|
static void Enter();
|
||||||
debugvirtual void op_step();
|
void op_step();
|
||||||
|
|
||||||
//timing
|
//timing
|
||||||
struct QueueEvent {
|
struct QueueEvent {
|
||||||
|
@ -145,13 +145,6 @@ private:
|
||||||
uint8 joy3l, joy3h;
|
uint8 joy3l, joy3h;
|
||||||
uint8 joy4l, joy4h;
|
uint8 joy4l, joy4h;
|
||||||
} status;
|
} status;
|
||||||
|
|
||||||
friend class CPUDebugger;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
extern CPU cpu;
|
||||||
#include "debugger/debugger.hpp"
|
|
||||||
extern CPUDebugger cpu;
|
|
||||||
#else
|
|
||||||
extern CPU cpu;
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -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"
|
#include "SPC_DSP.h"
|
||||||
|
|
||||||
class DSP : public Processor, public ChipDebugger {
|
class DSP : public Processor {
|
||||||
public:
|
public:
|
||||||
enum : bool { Threaded = false };
|
enum : bool { Threaded = false };
|
||||||
alwaysinline void step(unsigned clocks);
|
alwaysinline void step(unsigned clocks);
|
||||||
|
@ -16,7 +16,6 @@ public:
|
||||||
void channel_enable(unsigned channel, bool enable);
|
void channel_enable(unsigned channel, bool enable);
|
||||||
|
|
||||||
void serialize(serializer&);
|
void serialize(serializer&);
|
||||||
bool property(unsigned id, string &name, string &value) { return false; }
|
|
||||||
DSP();
|
DSP();
|
||||||
|
|
||||||
private:
|
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
|
#define PPU_CPP
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
PPU ppu;
|
||||||
#include "debugger/debugger.cpp"
|
|
||||||
PPUDebugger ppu;
|
|
||||||
#else
|
|
||||||
PPU ppu;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "memory/memory.cpp"
|
#include "memory/memory.cpp"
|
||||||
#include "mmio/mmio.cpp"
|
#include "mmio/mmio.cpp"
|
||||||
|
|
|
@ -72,13 +72,6 @@ public:
|
||||||
void serialize(serializer&);
|
void serialize(serializer&);
|
||||||
PPU();
|
PPU();
|
||||||
~PPU();
|
~PPU();
|
||||||
|
|
||||||
friend class PPUDebugger;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
extern PPU ppu;
|
||||||
#include "debugger/debugger.hpp"
|
|
||||||
extern PPUDebugger ppu;
|
|
||||||
#else
|
|
||||||
extern PPU ppu;
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -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
|
#define PPU_CPP
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
PPU ppu;
|
||||||
#include "debugger/debugger.cpp"
|
|
||||||
PPUDebugger ppu;
|
|
||||||
#else
|
|
||||||
PPU ppu;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "mmio/mmio.cpp"
|
#include "mmio/mmio.cpp"
|
||||||
#include "window/window.cpp"
|
#include "window/window.cpp"
|
||||||
|
|
|
@ -66,9 +66,4 @@ private:
|
||||||
friend class Video;
|
friend class Video;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
extern PPU ppu;
|
||||||
#include "debugger/debugger.hpp"
|
|
||||||
extern PPUDebugger ppu;
|
|
||||||
#else
|
|
||||||
extern PPU ppu;
|
|
||||||
#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,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
|
#define SMP_CPP
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
#include "disassembler.cpp"
|
||||||
#include "debugger/debugger.cpp"
|
SMP smp;
|
||||||
#include "debugger/disassembler.cpp"
|
|
||||||
SMPDebugger smp;
|
|
||||||
#else
|
|
||||||
SMP smp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "algorithms.cpp"
|
#include "algorithms.cpp"
|
||||||
#include "core.cpp"
|
#include "core.cpp"
|
||||||
|
|
|
@ -21,6 +21,8 @@ public:
|
||||||
SMP();
|
SMP();
|
||||||
~SMP();
|
~SMP();
|
||||||
|
|
||||||
|
void disassemble_opcode(char *output, uint16 addr);
|
||||||
|
|
||||||
//private:
|
//private:
|
||||||
struct Flags {
|
struct Flags {
|
||||||
bool n, v, p, b, h, i, z, c;
|
bool n, v, p, b, h, i, z, c;
|
||||||
|
@ -55,7 +57,7 @@ public:
|
||||||
Flags p;
|
Flags p;
|
||||||
} regs;
|
} regs;
|
||||||
|
|
||||||
unsigned rd, wr, dp, sp, ya, bit;
|
uint16 rd, wr, dp, sp, ya, bit;
|
||||||
|
|
||||||
struct Status {
|
struct Status {
|
||||||
//$00f1
|
//$00f1
|
||||||
|
@ -87,9 +89,9 @@ public:
|
||||||
|
|
||||||
void tick();
|
void tick();
|
||||||
alwaysinline void op_io();
|
alwaysinline void op_io();
|
||||||
debugvirtual alwaysinline uint8 op_read(uint16 addr);
|
alwaysinline uint8 op_read(uint16 addr);
|
||||||
debugvirtual alwaysinline void op_write(uint16 addr, uint8 data);
|
alwaysinline void op_write(uint16 addr, uint8 data);
|
||||||
debugvirtual alwaysinline void op_step();
|
alwaysinline void op_step();
|
||||||
static const unsigned cycle_count_table[256];
|
static const unsigned cycle_count_table[256];
|
||||||
uint64 cycle_table_cpu[256];
|
uint64 cycle_table_cpu[256];
|
||||||
unsigned cycle_table_dsp[256];
|
unsigned cycle_table_dsp[256];
|
||||||
|
@ -112,9 +114,4 @@ public:
|
||||||
uint8 op_ror (uint8 x);
|
uint8 op_ror (uint8 x);
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
extern SMP smp;
|
||||||
#include "debugger/debugger.hpp"
|
|
||||||
extern SMPDebugger smp;
|
|
||||||
#else
|
|
||||||
extern SMP smp;
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -3,12 +3,7 @@
|
||||||
#define CPU_CPP
|
#define CPU_CPP
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
CPU cpu;
|
||||||
#include "debugger/debugger.cpp"
|
|
||||||
CPUDebugger cpu;
|
|
||||||
#else
|
|
||||||
CPU cpu;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "serialization.cpp"
|
#include "serialization.cpp"
|
||||||
#include "dma/dma.cpp"
|
#include "dma/dma.cpp"
|
||||||
|
|
|
@ -132,14 +132,7 @@ private:
|
||||||
} alu;
|
} alu;
|
||||||
|
|
||||||
static void Enter();
|
static void Enter();
|
||||||
debugvirtual void op_step();
|
void op_step();
|
||||||
|
|
||||||
friend class CPUDebugger;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
extern CPU cpu;
|
||||||
#include "debugger/debugger.hpp"
|
|
||||||
extern CPUDebugger cpu;
|
|
||||||
#else
|
|
||||||
extern CPU cpu;
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -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();
|
void op_io();
|
||||||
debugvirtual uint8 op_read(uint32 addr);
|
uint8 op_read(uint32 addr);
|
||||||
debugvirtual void op_write(uint32 addr, uint8 data);
|
void op_write(uint32 addr, uint8 data);
|
||||||
alwaysinline unsigned speed(unsigned addr) const;
|
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
|
#define DSP_CPP
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
DSP dsp;
|
||||||
#include "debugger/debugger.cpp"
|
|
||||||
DSPDebugger dsp;
|
|
||||||
#else
|
|
||||||
DSP dsp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "serialization.cpp"
|
|
||||||
|
|
||||||
#define REG(n) state.regs[r_##n]
|
#define REG(n) state.regs[r_##n]
|
||||||
#define VREG(n) state.regs[v.vidx + v_##n]
|
#define VREG(n) state.regs[v.vidx + v_##n]
|
||||||
|
|
||||||
|
#include "serialization.cpp"
|
||||||
#include "gaussian.cpp"
|
#include "gaussian.cpp"
|
||||||
#include "counter.cpp"
|
#include "counter.cpp"
|
||||||
#include "envelope.cpp"
|
#include "envelope.cpp"
|
||||||
|
@ -303,4 +297,7 @@ DSP::DSP() {
|
||||||
DSP::~DSP() {
|
DSP::~DSP() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef REG
|
||||||
|
#undef VREG
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -167,13 +167,6 @@ private:
|
||||||
//dsp
|
//dsp
|
||||||
static void Enter();
|
static void Enter();
|
||||||
void tick();
|
void tick();
|
||||||
|
|
||||||
friend class DSPDebugger;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
extern DSP dsp;
|
||||||
#include "debugger/debugger.hpp"
|
|
||||||
extern DSPDebugger dsp;
|
|
||||||
#else
|
|
||||||
extern DSP dsp;
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -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
|
#define PPU_CPP
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
PPU ppu;
|
||||||
#include "debugger/debugger.cpp"
|
|
||||||
PPUDebugger ppu;
|
|
||||||
#else
|
|
||||||
PPU ppu;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "background/background.cpp"
|
#include "background/background.cpp"
|
||||||
#include "mmio/mmio.cpp"
|
#include "mmio/mmio.cpp"
|
||||||
|
|
|
@ -60,9 +60,4 @@ private:
|
||||||
friend class Video;
|
friend class Video;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
extern PPU ppu;
|
||||||
#include "debugger/debugger.hpp"
|
|
||||||
extern PPUDebugger ppu;
|
|
||||||
#else
|
|
||||||
extern PPU ppu;
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -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_buswrite(uint16 addr, uint8 data);
|
||||||
|
|
||||||
void op_io();
|
void op_io();
|
||||||
debugvirtual uint8 op_read(uint16 addr);
|
uint8 op_read(uint16 addr);
|
||||||
debugvirtual void op_write(uint16 addr, uint8 data);
|
void op_write(uint16 addr, uint8 data);
|
||||||
|
|
|
@ -3,12 +3,7 @@
|
||||||
#define SMP_CPP
|
#define SMP_CPP
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
SMP smp;
|
||||||
#include "debugger/debugger.cpp"
|
|
||||||
SMPDebugger smp;
|
|
||||||
#else
|
|
||||||
SMP smp;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "serialization.cpp"
|
#include "serialization.cpp"
|
||||||
#include "iplrom.cpp"
|
#include "iplrom.cpp"
|
||||||
|
|
|
@ -50,12 +50,6 @@ private:
|
||||||
static void Enter();
|
static void Enter();
|
||||||
|
|
||||||
friend class SMPcore;
|
friend class SMPcore;
|
||||||
friend class SMPDebugger;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#if defined(DEBUGGER)
|
extern SMP smp;
|
||||||
#include "debugger/debugger.hpp"
|
|
||||||
extern SMPDebugger smp;
|
|
||||||
#else
|
|
||||||
extern SMP smp;
|
|
||||||
#endif
|
|
||||||
|
|
|
@ -40,12 +40,6 @@ using namespace nall;
|
||||||
|
|
||||||
#include <gameboy/gameboy.hpp>
|
#include <gameboy/gameboy.hpp>
|
||||||
|
|
||||||
#ifdef DEBUGGER
|
|
||||||
#define debugvirtual virtual
|
|
||||||
#else
|
|
||||||
#define debugvirtual
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace SNES {
|
namespace SNES {
|
||||||
typedef int8_t int8;
|
typedef int8_t int8;
|
||||||
typedef int16_t int16;
|
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/memory/memory.hpp>
|
||||||
#include <snes/cpu/core/core.hpp>
|
#include <snes/cpu/core/core.hpp>
|
||||||
#include <snes/smp/core/core.hpp>
|
#include <snes/smp/core/core.hpp>
|
||||||
|
@ -154,6 +144,4 @@ namespace SNES {
|
||||||
#include <snes/ppu/counter/counter-inline.hpp>
|
#include <snes/ppu/counter/counter-inline.hpp>
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef debugvirtual
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,42 +6,42 @@ MainWindow::MainWindow() {
|
||||||
setBackgroundColor({ 0, 0, 0 });
|
setBackgroundColor({ 0, 0, 0 });
|
||||||
windowManager->append(this, "MainWindow");
|
windowManager->append(this, "MainWindow");
|
||||||
|
|
||||||
cartridgeMenu.setText("Cartridge");
|
cartridgeMenu.setText("&Cartridge");
|
||||||
cartridgeLoadSNES.setText("Load SNES Cartridge ...");
|
cartridgeLoadSNES.setText("Load &SNES Cartridge ...");
|
||||||
cartridgeLoadNES.setText("Load NES Cartridge ...");
|
cartridgeLoadNES.setText("Load &NES Cartridge ...");
|
||||||
cartridgeLoadGameBoy.setText("Load Game Boy Cartridge ...");
|
cartridgeLoadGameBoy.setText("Load &Game Boy Cartridge ...");
|
||||||
cartridgeLoadGameBoyColor.setText("Load Game Boy Color Cartridge ...");
|
cartridgeLoadGameBoyColor.setText("Load Game Boy &Color Cartridge ...");
|
||||||
cartridgeLoadSatellaviewSlotted.setText("Load Satellaview-Slotted Cartridge ...");
|
cartridgeLoadSatellaviewSlotted.setText("Load Satellaview-Slotted Cartridge ...");
|
||||||
cartridgeLoadSatellaview.setText("Load Satellaview Cartridge ...");
|
cartridgeLoadSatellaview.setText("Load Satellaview Cartridge ...");
|
||||||
cartridgeLoadSufamiTurbo.setText("Load Sufami Turbo Cartridge ...");
|
cartridgeLoadSufamiTurbo.setText("Load Sufami Turbo Cartridge ...");
|
||||||
cartridgeLoadSuperGameBoy.setText("Load Super Game Boy Cartridge ...");
|
cartridgeLoadSuperGameBoy.setText("Load Super Game Boy Cartridge ...");
|
||||||
|
|
||||||
nesMenu.setText("NES");
|
nesMenu.setText("&NES");
|
||||||
nesPower.setText("Power Cycle");
|
nesPower.setText("&Power Cycle");
|
||||||
nesReset.setText("Reset");
|
nesReset.setText("&Reset");
|
||||||
nesPort1.setText("Controller Port 1");
|
nesPort1.setText("Controller Port &1");
|
||||||
nesPort1Device[0].setText("None");
|
nesPort1Device[0].setText("None");
|
||||||
nesPort1Device[1].setText("Gamepad");
|
nesPort1Device[1].setText("Gamepad");
|
||||||
RadioItem::group(nesPort1Device[0], nesPort1Device[1]);
|
RadioItem::group(nesPort1Device[0], nesPort1Device[1]);
|
||||||
nesPort1Device[config->nes.controllerPort1Device].setChecked();
|
nesPort1Device[config->nes.controllerPort1Device].setChecked();
|
||||||
nesPort2.setText("Controller Port 2");
|
nesPort2.setText("Controller Port &2");
|
||||||
nesPort2Device[0].setText("None");
|
nesPort2Device[0].setText("None");
|
||||||
nesPort2Device[1].setText("Gamepad");
|
nesPort2Device[1].setText("Gamepad");
|
||||||
RadioItem::group(nesPort2Device[0], nesPort2Device[1]);
|
RadioItem::group(nesPort2Device[0], nesPort2Device[1]);
|
||||||
nesPort2Device[config->nes.controllerPort2Device].setChecked();
|
nesPort2Device[config->nes.controllerPort2Device].setChecked();
|
||||||
nesCartridgeUnload.setText("Unload Cartridge");
|
nesCartridgeUnload.setText("&Unload Cartridge");
|
||||||
|
|
||||||
snesMenu.setText("SNES");
|
snesMenu.setText("&SNES");
|
||||||
snesPower.setText("Power Cycle");
|
snesPower.setText("&Power Cycle");
|
||||||
snesReset.setText("Reset");
|
snesReset.setText("&Reset");
|
||||||
snesPort1.setText("Controller Port 1");
|
snesPort1.setText("Controller Port &1");
|
||||||
snesPort1Device[0].setText("None");
|
snesPort1Device[0].setText("None");
|
||||||
snesPort1Device[1].setText("Gamepad");
|
snesPort1Device[1].setText("Gamepad");
|
||||||
snesPort1Device[2].setText("Multitap");
|
snesPort1Device[2].setText("Multitap");
|
||||||
snesPort1Device[3].setText("Mouse");
|
snesPort1Device[3].setText("Mouse");
|
||||||
RadioItem::group(snesPort1Device[0], snesPort1Device[1], snesPort1Device[2], snesPort1Device[3]);
|
RadioItem::group(snesPort1Device[0], snesPort1Device[1], snesPort1Device[2], snesPort1Device[3]);
|
||||||
snesPort1Device[config->snes.controllerPort1Device].setChecked();
|
snesPort1Device[config->snes.controllerPort1Device].setChecked();
|
||||||
snesPort2.setText("Controller Port 2");
|
snesPort2.setText("Controller Port &2");
|
||||||
snesPort2Device[0].setText("None");
|
snesPort2Device[0].setText("None");
|
||||||
snesPort2Device[1].setText("Gamepad");
|
snesPort2Device[1].setText("Gamepad");
|
||||||
snesPort2Device[2].setText("Multitap");
|
snesPort2Device[2].setText("Multitap");
|
||||||
|
@ -53,48 +53,48 @@ MainWindow::MainWindow() {
|
||||||
RadioItem::group(snesPort2Device[0], snesPort2Device[1], snesPort2Device[2], snesPort2Device[3],
|
RadioItem::group(snesPort2Device[0], snesPort2Device[1], snesPort2Device[2], snesPort2Device[3],
|
||||||
snesPort2Device[4], snesPort2Device[5], snesPort2Device[6], snesPort2Device[7]);
|
snesPort2Device[4], snesPort2Device[5], snesPort2Device[6], snesPort2Device[7]);
|
||||||
snesPort2Device[config->snes.controllerPort2Device].setChecked();
|
snesPort2Device[config->snes.controllerPort2Device].setChecked();
|
||||||
snesCartridgeUnload.setText("Unload Cartridge");
|
snesCartridgeUnload.setText("&Unload Cartridge");
|
||||||
|
|
||||||
gameBoyMenu.setText("Game Boy");
|
gameBoyMenu.setText("&Game Boy");
|
||||||
gameBoyPower.setText("Power Cycle");
|
gameBoyPower.setText("&Power Cycle");
|
||||||
gameBoyCartridgeUnload.setText("Unload Cartridge");
|
gameBoyCartridgeUnload.setText("&Unload Cartridge");
|
||||||
|
|
||||||
settingsMenu.setText("Settings");
|
settingsMenu.setText("S&ettings");
|
||||||
settingsVideoFilter.setText("Video Filter");
|
settingsVideoFilter.setText("Video &Filter");
|
||||||
settingsVideoFilterNone.setText("None");
|
settingsVideoFilterNone.setText("None");
|
||||||
setupVideoFilters();
|
setupVideoFilters();
|
||||||
settingsVideoShader.setText("Video Shader");
|
settingsVideoShader.setText("Video &Shader");
|
||||||
settingsVideoShaderNone.setText("None");
|
settingsVideoShaderNone.setText("None");
|
||||||
settingsVideoShaderBlur.setText("Blur");
|
settingsVideoShaderBlur.setText("Blur");
|
||||||
setupVideoShaders();
|
setupVideoShaders();
|
||||||
settingsSynchronizeVideo.setText("Synchronize Video");
|
settingsSynchronizeVideo.setText("Synchronize &Video");
|
||||||
settingsSynchronizeVideo.setChecked(config->video.synchronize);
|
settingsSynchronizeVideo.setChecked(config->video.synchronize);
|
||||||
settingsSynchronizeAudio.setText("Synchronize Audio");
|
settingsSynchronizeAudio.setText("Synchronize &Audio");
|
||||||
settingsSynchronizeAudio.setChecked(config->audio.synchronize);
|
settingsSynchronizeAudio.setChecked(config->audio.synchronize);
|
||||||
settingsCorrectAspectRatio.setText("Correct Aspect Ratio");
|
settingsCorrectAspectRatio.setText("Correct Aspect &Ratio");
|
||||||
settingsCorrectAspectRatio.setChecked(config->video.correctAspectRatio);
|
settingsCorrectAspectRatio.setChecked(config->video.correctAspectRatio);
|
||||||
settingsMaskOverscan.setText("Mask Overscan");
|
settingsMaskOverscan.setText("Mask &Overscan");
|
||||||
settingsMaskOverscan.setChecked(config->video.maskOverscan);
|
settingsMaskOverscan.setChecked(config->video.maskOverscan);
|
||||||
settingsMuteAudio.setText("Mute Audio");
|
settingsMuteAudio.setText("&Mute Audio");
|
||||||
settingsMuteAudio.setChecked(config->audio.mute);
|
settingsMuteAudio.setChecked(config->audio.mute);
|
||||||
settingsConfiguration.setText("Configuration ...");
|
settingsConfiguration.setText("&Configuration ...");
|
||||||
|
|
||||||
toolsMenu.setText("Tools");
|
toolsMenu.setText("&Tools");
|
||||||
toolsStateSave.setText("Save State");
|
toolsStateSave.setText("&Save State");
|
||||||
toolsStateSave1.setText("Slot 1");
|
toolsStateSave1.setText("Slot &1");
|
||||||
toolsStateSave2.setText("Slot 2");
|
toolsStateSave2.setText("Slot &2");
|
||||||
toolsStateSave3.setText("Slot 3");
|
toolsStateSave3.setText("Slot &3");
|
||||||
toolsStateSave4.setText("Slot 4");
|
toolsStateSave4.setText("Slot &4");
|
||||||
toolsStateSave5.setText("Slot 5");
|
toolsStateSave5.setText("Slot &5");
|
||||||
toolsStateLoad.setText("Load State");
|
toolsStateLoad.setText("&Load State");
|
||||||
toolsStateLoad1.setText("Slot 1");
|
toolsStateLoad1.setText("Slot &1");
|
||||||
toolsStateLoad2.setText("Slot 2");
|
toolsStateLoad2.setText("Slot &2");
|
||||||
toolsStateLoad3.setText("Slot 3");
|
toolsStateLoad3.setText("Slot &3");
|
||||||
toolsStateLoad4.setText("Slot 4");
|
toolsStateLoad4.setText("Slot &4");
|
||||||
toolsStateLoad5.setText("Slot 5");
|
toolsStateLoad5.setText("Slot &5");
|
||||||
toolsShrinkWindow.setText("Shrink Window");
|
toolsShrinkWindow.setText("Shrink &Window");
|
||||||
toolsCheatEditor.setText("Cheat Editor ...");
|
toolsCheatEditor.setText("&Cheat Editor ...");
|
||||||
toolsStateManager.setText("State Manager ...");
|
toolsStateManager.setText("State &Manager ...");
|
||||||
|
|
||||||
append(cartridgeMenu);
|
append(cartridgeMenu);
|
||||||
cartridgeMenu.append(cartridgeLoadNES);
|
cartridgeMenu.append(cartridgeLoadNES);
|
||||||
|
|
|
@ -27,7 +27,7 @@ void Application::run() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::Application(int argc, char **argv) {
|
Application::Application(int argc, char **argv) {
|
||||||
title = "bsnes v085.02";
|
title = "bsnes v085.03";
|
||||||
|
|
||||||
application = this;
|
application = this;
|
||||||
quit = false;
|
quit = false;
|
||||||
|
|
Loading…
Reference in New Issue