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:
Tim Allen 2012-02-04 20:23:53 +11:00
parent e4e50308d2
commit 892bb3ab01
66 changed files with 113 additions and 2999 deletions

View File

@ -14,7 +14,7 @@ static string iNES(const uint8_t *data, unsigned size) {
unsigned prgram = 0;
unsigned chrram = chrrom == 0 ? 8192 : 0;
print("iNES mapper: ", mapper, "\n");
//print("iNES mapper: ", mapper, "\n");
output.append("<?xml version='1.0' encoding='UTF-8'?>\n");
output.append("<cartridge>\n");
@ -151,7 +151,7 @@ static string iNES(const uint8_t *data, unsigned size) {
"</cartridge>\n"
);
print(output, "\n");
//print(output, "\n");
return output;
}

View File

@ -2,10 +2,6 @@ void pAction::setEnabled(bool enabled) {
gtk_widget_set_sensitive(widget, enabled);
}
void pAction::setFont(const string &font) {
pFont::setFont(widget, font);
}
void pAction::setVisible(bool visible) {
gtk_widget_set_visible(widget, visible);
}
@ -15,3 +11,17 @@ void pAction::constructor() {
void pAction::orphan() {
}
//GTK+ uses _ for mnemonics, __ for _
//transform so that & is used for mnemonics, && for &
string pAction::mnemonic(string text) {
text.transform("&_", "\x01\x02");
text.replace("\x01\x01", "&");
text.transform("\x01", "_");
text.replace("\x02", "__");
return text;
}
void pAction::setFont(const string &font) {
pFont::setFont(widget, font);
}

View File

@ -13,12 +13,13 @@ void pCheckItem::setChecked(bool checked) {
}
void pCheckItem::setText(const string &text) {
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), text);
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), mnemonic(text));
}
void pCheckItem::constructor() {
widget = gtk_check_menu_item_new_with_label(checkItem.state.text);
widget = gtk_check_menu_item_new_with_mnemonic("");
setChecked(checkItem.state.checked);
setText(checkItem.state.text);
g_signal_connect_swapped(G_OBJECT(widget), "toggled", G_CALLBACK(CheckItem_toggle), (gpointer)&checkItem);
}

View File

@ -8,12 +8,13 @@ void pItem::setImage(const image &image) {
}
void pItem::setText(const string &text) {
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), text);
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), mnemonic(text));
}
void pItem::constructor() {
widget = gtk_image_menu_item_new_with_label(item.state.text);
widget = gtk_image_menu_item_new_with_mnemonic("");
g_signal_connect_swapped(G_OBJECT(widget), "activate", G_CALLBACK(Item_activate), (gpointer)&item);
setText(item.state.text);
}
void pItem::destructor() {

View File

@ -19,13 +19,14 @@ void pMenu::setImage(const image &image) {
}
void pMenu::setText(const string &text) {
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), text);
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), mnemonic(text));
}
void pMenu::constructor() {
gtkMenu = gtk_menu_new();
widget = gtk_image_menu_item_new_with_label(menu.state.text);
widget = gtk_image_menu_item_new_with_mnemonic("");
gtk_menu_item_set_submenu(GTK_MENU_ITEM(widget), gtkMenu);
setText(menu.state.text);
}
void pMenu::destructor() {

View File

@ -25,12 +25,13 @@ void pRadioItem::setGroup(const array<RadioItem&> &group) {
}
void pRadioItem::setText(const string &text) {
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), text);
gtk_menu_item_set_label(GTK_MENU_ITEM(widget), mnemonic(text));
}
void pRadioItem::constructor() {
widget = gtk_radio_menu_item_new_with_label(0, radioItem.state.text);
widget = gtk_radio_menu_item_new_with_mnemonic(0, "");
setGroup(radioItem.state.group);
setText(radioItem.state.text);
for(auto &item : radioItem.state.group) {
gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(item.p.widget), item.state.checked);
}

View File

@ -141,6 +141,7 @@ struct pAction : public pObject {
pAction(Action &action) : pObject(action), action(action) {}
void constructor();
virtual void orphan();
string mnemonic(string text);
virtual void setFont(const string &font);
};

View File

@ -168,13 +168,11 @@ void pWindow::setFullScreen(bool fullScreen) {
if(fullScreen == false) {
gtk_window_unfullscreen(GTK_WINDOW(widget));
gtk_window_set_resizable(GTK_WINDOW(widget), window.state.resizable);
gtk_window_set_decorated(GTK_WINDOW(widget), true);
gtk_widget_set_size_request(widget, -1, -1);
gdk_display_sync(gtk_widget_get_display(widget));
setGeometry(window.state.geometry);
} else {
gtk_window_fullscreen(GTK_WINDOW(widget));
gtk_window_set_decorated(GTK_WINDOW(widget), false);
gtk_widget_set_size_request(widget, Desktop::size().width, Desktop::size().height);
gtk_window_set_resizable(GTK_WINDOW(widget), false);
}

View File

@ -1,7 +1,7 @@
/****************************************************************************
** Meta object code from reading C++ file 'platform.moc.hpp'
**
** Created: Mon Jan 23 13:07:40 2012
** Created: Thu Feb 2 17:56:05 2012
** by: The Qt Meta Object Compiler version 62 (Qt 4.6.3)
**
** WARNING! All changes made in this file will be lost!

View File

@ -115,6 +115,7 @@ public:
SDL_InitSubSystem(SDL_INIT_VIDEO);
screen = SDL_SetVideoMode(2560, 1600, 32, SDL_HWSURFACE);
XUndefineCursor(display, settings.handle);
buffer = 0;
iwidth = 0;

View File

@ -3,12 +3,7 @@
#define CPU_CPP
namespace SNES {
#if defined(DEBUGGER)
#include "debugger/debugger.cpp"
CPUDebugger cpu;
#else
CPU cpu;
#endif
CPU cpu;
#include "serialization.cpp"
#include "dma.cpp"

View File

@ -19,8 +19,8 @@ public:
void mmio_write(unsigned addr, uint8 data);
void op_io();
debugvirtual uint8 op_read(unsigned addr);
debugvirtual void op_write(unsigned addr, uint8 data);
uint8 op_read(unsigned addr);
void op_write(unsigned addr, uint8 data);
void enter();
void enable();
@ -34,7 +34,7 @@ public:
private:
//cpu
static void Enter();
debugvirtual void op_step();
void op_step();
//timing
struct QueueEvent {
@ -145,13 +145,6 @@ private:
uint8 joy3l, joy3h;
uint8 joy4l, joy4h;
} status;
friend class CPUDebugger;
};
#if defined(DEBUGGER)
#include "debugger/debugger.hpp"
extern CPUDebugger cpu;
#else
extern CPU cpu;
#endif
extern CPU cpu;

View File

@ -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

View File

@ -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();
};

View File

@ -1,6 +1,6 @@
#include "SPC_DSP.h"
class DSP : public Processor, public ChipDebugger {
class DSP : public Processor {
public:
enum : bool { Threaded = false };
alwaysinline void step(unsigned clocks);
@ -16,7 +16,6 @@ public:
void channel_enable(unsigned channel, bool enable);
void serialize(serializer&);
bool property(unsigned id, string &name, string &value) { return false; }
DSP();
private:

View File

@ -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

View File

@ -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();
};

View File

@ -3,12 +3,7 @@
#define PPU_CPP
namespace SNES {
#if defined(DEBUGGER)
#include "debugger/debugger.cpp"
PPUDebugger ppu;
#else
PPU ppu;
#endif
PPU ppu;
#include "memory/memory.cpp"
#include "mmio/mmio.cpp"

View File

@ -72,13 +72,6 @@ public:
void serialize(serializer&);
PPU();
~PPU();
friend class PPUDebugger;
};
#if defined(DEBUGGER)
#include "debugger/debugger.hpp"
extern PPUDebugger ppu;
#else
extern PPU ppu;
#endif
extern PPU ppu;

View File

@ -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

View File

@ -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;
}
}

View File

@ -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;

View File

@ -1,7 +0,0 @@
#ifdef PPU_CPP
bool PPUDebugger::property(unsigned id, string &name, string &value) {
return false;
}
#endif

View File

@ -1,4 +0,0 @@
class PPUDebugger : public PPU, public ChipDebugger {
public:
bool property(unsigned id, string &name, string &value);
};

View File

@ -3,12 +3,7 @@
#define PPU_CPP
namespace SNES {
#if defined(DEBUGGER)
#include "debugger/debugger.cpp"
PPUDebugger ppu;
#else
PPU ppu;
#endif
PPU ppu;
#include "mmio/mmio.cpp"
#include "window/window.cpp"

View File

@ -66,9 +66,4 @@ private:
friend class Video;
};
#if defined(DEBUGGER)
#include "debugger/debugger.hpp"
extern PPUDebugger ppu;
#else
extern PPU ppu;
#endif
extern PPU ppu;

View File

@ -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

View File

@ -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);
};

View File

@ -5,13 +5,8 @@
#define SMP_CPP
namespace SNES {
#if defined(DEBUGGER)
#include "debugger/debugger.cpp"
#include "debugger/disassembler.cpp"
SMPDebugger smp;
#else
SMP smp;
#endif
#include "disassembler.cpp"
SMP smp;
#include "algorithms.cpp"
#include "core.cpp"

View File

@ -21,6 +21,8 @@ public:
SMP();
~SMP();
void disassemble_opcode(char *output, uint16 addr);
//private:
struct Flags {
bool n, v, p, b, h, i, z, c;
@ -55,7 +57,7 @@ public:
Flags p;
} regs;
unsigned rd, wr, dp, sp, ya, bit;
uint16 rd, wr, dp, sp, ya, bit;
struct Status {
//$00f1
@ -87,9 +89,9 @@ public:
void tick();
alwaysinline void op_io();
debugvirtual alwaysinline uint8 op_read(uint16 addr);
debugvirtual alwaysinline void op_write(uint16 addr, uint8 data);
debugvirtual alwaysinline void op_step();
alwaysinline uint8 op_read(uint16 addr);
alwaysinline void op_write(uint16 addr, uint8 data);
alwaysinline void op_step();
static const unsigned cycle_count_table[256];
uint64 cycle_table_cpu[256];
unsigned cycle_table_dsp[256];
@ -112,9 +114,4 @@ public:
uint8 op_ror (uint8 x);
};
#if defined(DEBUGGER)
#include "debugger/debugger.hpp"
extern SMPDebugger smp;
#else
extern SMP smp;
#endif
extern SMP smp;

View File

@ -3,12 +3,7 @@
#define CPU_CPP
namespace SNES {
#if defined(DEBUGGER)
#include "debugger/debugger.cpp"
CPUDebugger cpu;
#else
CPU cpu;
#endif
CPU cpu;
#include "serialization.cpp"
#include "dma/dma.cpp"

View File

@ -132,14 +132,7 @@ private:
} alu;
static void Enter();
debugvirtual void op_step();
friend class CPUDebugger;
void op_step();
};
#if defined(DEBUGGER)
#include "debugger/debugger.hpp"
extern CPUDebugger cpu;
#else
extern CPU cpu;
#endif
extern CPU cpu;

View File

@ -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

View File

@ -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();
};

View File

@ -1,4 +1,4 @@
void op_io();
debugvirtual uint8 op_read(uint32 addr);
debugvirtual void op_write(uint32 addr, uint8 data);
uint8 op_read(uint32 addr);
void op_write(uint32 addr, uint8 data);
alwaysinline unsigned speed(unsigned addr) const;

View File

@ -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

View File

@ -1,4 +0,0 @@
class DSPDebugger : public DSP, public ChipDebugger {
public:
bool property(unsigned id, string &name, string &value);
};

View File

@ -3,18 +3,12 @@
#define DSP_CPP
namespace SNES {
#if defined(DEBUGGER)
#include "debugger/debugger.cpp"
DSPDebugger dsp;
#else
DSP dsp;
#endif
#include "serialization.cpp"
DSP dsp;
#define REG(n) state.regs[r_##n]
#define VREG(n) state.regs[v.vidx + v_##n]
#include "serialization.cpp"
#include "gaussian.cpp"
#include "counter.cpp"
#include "envelope.cpp"
@ -303,4 +297,7 @@ DSP::DSP() {
DSP::~DSP() {
}
#undef REG
#undef VREG
}

View File

@ -167,13 +167,6 @@ private:
//dsp
static void Enter();
void tick();
friend class DSPDebugger;
};
#if defined(DEBUGGER)
#include "debugger/debugger.hpp"
extern DSPDebugger dsp;
#else
extern DSP dsp;
#endif
extern DSP dsp;

View File

@ -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

View File

@ -1,4 +0,0 @@
class PPUDebugger : public PPU, public ChipDebugger {
public:
bool property(unsigned id, string &name, string &value);
};

View File

@ -3,12 +3,7 @@
#define PPU_CPP
namespace SNES {
#if defined(DEBUGGER)
#include "debugger/debugger.cpp"
PPUDebugger ppu;
#else
PPU ppu;
#endif
PPU ppu;
#include "background/background.cpp"
#include "mmio/mmio.cpp"

View File

@ -60,9 +60,4 @@ private:
friend class Video;
};
#if defined(DEBUGGER)
#include "debugger/debugger.hpp"
extern PPUDebugger ppu;
#else
extern PPU ppu;
#endif
extern PPU ppu;

View File

@ -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

View File

@ -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();
}
}

View File

@ -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();
};

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]) {}
};

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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();
};

View File

@ -5,5 +5,5 @@ uint8 op_busread(uint16 addr);
void op_buswrite(uint16 addr, uint8 data);
void op_io();
debugvirtual uint8 op_read(uint16 addr);
debugvirtual void op_write(uint16 addr, uint8 data);
uint8 op_read(uint16 addr);
void op_write(uint16 addr, uint8 data);

View File

@ -3,12 +3,7 @@
#define SMP_CPP
namespace SNES {
#if defined(DEBUGGER)
#include "debugger/debugger.cpp"
SMPDebugger smp;
#else
SMP smp;
#endif
SMP smp;
#include "serialization.cpp"
#include "iplrom.cpp"

View File

@ -50,12 +50,6 @@ private:
static void Enter();
friend class SMPcore;
friend class SMPDebugger;
};
#if defined(DEBUGGER)
#include "debugger/debugger.hpp"
extern SMPDebugger smp;
#else
extern SMP smp;
#endif
extern SMP smp;

View File

@ -40,12 +40,6 @@ using namespace nall;
#include <gameboy/gameboy.hpp>
#ifdef DEBUGGER
#define debugvirtual virtual
#else
#define debugvirtual
#endif
namespace SNES {
typedef int8_t int8;
typedef int16_t int16;
@ -126,10 +120,6 @@ namespace SNES {
}
};
struct ChipDebugger {
virtual bool property(unsigned id, string &name, string &value) = 0;
};
#include <snes/memory/memory.hpp>
#include <snes/cpu/core/core.hpp>
#include <snes/smp/core/core.hpp>
@ -154,6 +144,4 @@ namespace SNES {
#include <snes/ppu/counter/counter-inline.hpp>
}
#undef debugvirtual
#endif

View File

@ -6,42 +6,42 @@ MainWindow::MainWindow() {
setBackgroundColor({ 0, 0, 0 });
windowManager->append(this, "MainWindow");
cartridgeMenu.setText("Cartridge");
cartridgeLoadSNES.setText("Load SNES Cartridge ...");
cartridgeLoadNES.setText("Load NES Cartridge ...");
cartridgeLoadGameBoy.setText("Load Game Boy Cartridge ...");
cartridgeLoadGameBoyColor.setText("Load Game Boy Color Cartridge ...");
cartridgeMenu.setText("&Cartridge");
cartridgeLoadSNES.setText("Load &SNES Cartridge ...");
cartridgeLoadNES.setText("Load &NES Cartridge ...");
cartridgeLoadGameBoy.setText("Load &Game Boy Cartridge ...");
cartridgeLoadGameBoyColor.setText("Load Game Boy &Color Cartridge ...");
cartridgeLoadSatellaviewSlotted.setText("Load Satellaview-Slotted Cartridge ...");
cartridgeLoadSatellaview.setText("Load Satellaview Cartridge ...");
cartridgeLoadSufamiTurbo.setText("Load Sufami Turbo Cartridge ...");
cartridgeLoadSuperGameBoy.setText("Load Super Game Boy Cartridge ...");
nesMenu.setText("NES");
nesPower.setText("Power Cycle");
nesReset.setText("Reset");
nesPort1.setText("Controller Port 1");
nesMenu.setText("&NES");
nesPower.setText("&Power Cycle");
nesReset.setText("&Reset");
nesPort1.setText("Controller Port &1");
nesPort1Device[0].setText("None");
nesPort1Device[1].setText("Gamepad");
RadioItem::group(nesPort1Device[0], nesPort1Device[1]);
nesPort1Device[config->nes.controllerPort1Device].setChecked();
nesPort2.setText("Controller Port 2");
nesPort2.setText("Controller Port &2");
nesPort2Device[0].setText("None");
nesPort2Device[1].setText("Gamepad");
RadioItem::group(nesPort2Device[0], nesPort2Device[1]);
nesPort2Device[config->nes.controllerPort2Device].setChecked();
nesCartridgeUnload.setText("Unload Cartridge");
nesCartridgeUnload.setText("&Unload Cartridge");
snesMenu.setText("SNES");
snesPower.setText("Power Cycle");
snesReset.setText("Reset");
snesPort1.setText("Controller Port 1");
snesMenu.setText("&SNES");
snesPower.setText("&Power Cycle");
snesReset.setText("&Reset");
snesPort1.setText("Controller Port &1");
snesPort1Device[0].setText("None");
snesPort1Device[1].setText("Gamepad");
snesPort1Device[2].setText("Multitap");
snesPort1Device[3].setText("Mouse");
RadioItem::group(snesPort1Device[0], snesPort1Device[1], snesPort1Device[2], snesPort1Device[3]);
snesPort1Device[config->snes.controllerPort1Device].setChecked();
snesPort2.setText("Controller Port 2");
snesPort2.setText("Controller Port &2");
snesPort2Device[0].setText("None");
snesPort2Device[1].setText("Gamepad");
snesPort2Device[2].setText("Multitap");
@ -53,48 +53,48 @@ MainWindow::MainWindow() {
RadioItem::group(snesPort2Device[0], snesPort2Device[1], snesPort2Device[2], snesPort2Device[3],
snesPort2Device[4], snesPort2Device[5], snesPort2Device[6], snesPort2Device[7]);
snesPort2Device[config->snes.controllerPort2Device].setChecked();
snesCartridgeUnload.setText("Unload Cartridge");
snesCartridgeUnload.setText("&Unload Cartridge");
gameBoyMenu.setText("Game Boy");
gameBoyPower.setText("Power Cycle");
gameBoyCartridgeUnload.setText("Unload Cartridge");
gameBoyMenu.setText("&Game Boy");
gameBoyPower.setText("&Power Cycle");
gameBoyCartridgeUnload.setText("&Unload Cartridge");
settingsMenu.setText("Settings");
settingsVideoFilter.setText("Video Filter");
settingsMenu.setText("S&ettings");
settingsVideoFilter.setText("Video &Filter");
settingsVideoFilterNone.setText("None");
setupVideoFilters();
settingsVideoShader.setText("Video Shader");
settingsVideoShader.setText("Video &Shader");
settingsVideoShaderNone.setText("None");
settingsVideoShaderBlur.setText("Blur");
setupVideoShaders();
settingsSynchronizeVideo.setText("Synchronize Video");
settingsSynchronizeVideo.setText("Synchronize &Video");
settingsSynchronizeVideo.setChecked(config->video.synchronize);
settingsSynchronizeAudio.setText("Synchronize Audio");
settingsSynchronizeAudio.setText("Synchronize &Audio");
settingsSynchronizeAudio.setChecked(config->audio.synchronize);
settingsCorrectAspectRatio.setText("Correct Aspect Ratio");
settingsCorrectAspectRatio.setText("Correct Aspect &Ratio");
settingsCorrectAspectRatio.setChecked(config->video.correctAspectRatio);
settingsMaskOverscan.setText("Mask Overscan");
settingsMaskOverscan.setText("Mask &Overscan");
settingsMaskOverscan.setChecked(config->video.maskOverscan);
settingsMuteAudio.setText("Mute Audio");
settingsMuteAudio.setText("&Mute Audio");
settingsMuteAudio.setChecked(config->audio.mute);
settingsConfiguration.setText("Configuration ...");
settingsConfiguration.setText("&Configuration ...");
toolsMenu.setText("Tools");
toolsStateSave.setText("Save State");
toolsStateSave1.setText("Slot 1");
toolsStateSave2.setText("Slot 2");
toolsStateSave3.setText("Slot 3");
toolsStateSave4.setText("Slot 4");
toolsStateSave5.setText("Slot 5");
toolsStateLoad.setText("Load State");
toolsStateLoad1.setText("Slot 1");
toolsStateLoad2.setText("Slot 2");
toolsStateLoad3.setText("Slot 3");
toolsStateLoad4.setText("Slot 4");
toolsStateLoad5.setText("Slot 5");
toolsShrinkWindow.setText("Shrink Window");
toolsCheatEditor.setText("Cheat Editor ...");
toolsStateManager.setText("State Manager ...");
toolsMenu.setText("&Tools");
toolsStateSave.setText("&Save State");
toolsStateSave1.setText("Slot &1");
toolsStateSave2.setText("Slot &2");
toolsStateSave3.setText("Slot &3");
toolsStateSave4.setText("Slot &4");
toolsStateSave5.setText("Slot &5");
toolsStateLoad.setText("&Load State");
toolsStateLoad1.setText("Slot &1");
toolsStateLoad2.setText("Slot &2");
toolsStateLoad3.setText("Slot &3");
toolsStateLoad4.setText("Slot &4");
toolsStateLoad5.setText("Slot &5");
toolsShrinkWindow.setText("Shrink &Window");
toolsCheatEditor.setText("&Cheat Editor ...");
toolsStateManager.setText("State &Manager ...");
append(cartridgeMenu);
cartridgeMenu.append(cartridgeLoadNES);

View File

@ -27,7 +27,7 @@ void Application::run() {
}
Application::Application(int argc, char **argv) {
title = "bsnes v085.02";
title = "bsnes v085.03";
application = this;
quit = false;