Update to v095r06 release.

byuu says:

Changelog:
- fixed I/O register reads; perfect score on endrift's I/O tests now
- fixed mouse capture clipping on Windows [Cydrak]
- several hours of code maintenance work done on the SFC core

All higan/sfc files should now use the auto fn() -> ret; syntax. Haven't
converted all unsigned->uint yet. Also, probably won't do sfc/alt as
that's mostly just speed hack stuff.

Errata:
- forgot auto& instead of just auto on SuperFamicom::Video::draw_cursor,
  which makes Super Scope / Justifier crash. Will be fixed in the next
  WIP.
This commit is contained in:
Tim Allen 2015-11-14 11:52:51 +11:00
parent 6d9f43a37b
commit 40f4b91000
114 changed files with 1250 additions and 1199 deletions

View File

@ -7,7 +7,7 @@ using namespace nall;
namespace Emulator { namespace Emulator {
static const string Name = "higan"; static const string Name = "higan";
static const string Version = "095.05"; static const string Version = "095.06";
static const string Author = "byuu"; static const string Author = "byuu";
static const string License = "GPLv3"; static const string License = "GPLv3";
static const string Website = "http://byuu.org/"; static const string Website = "http://byuu.org/";

View File

@ -94,10 +94,10 @@ Board::Board(Markup::Node& document) {
auto crom = cartridge["chr/rom"]; auto crom = cartridge["chr/rom"];
auto cram = cartridge["chr/ram"]; auto cram = cartridge["chr/ram"];
prgrom.size = prom["size"].decimal(); prgrom.size = prom["size"].natural();
prgram.size = pram["size"].decimal(); prgram.size = pram["size"].natural();
chrrom.size = crom["size"].decimal(); chrrom.size = crom["size"].natural();
chrram.size = cram["size"].decimal(); chrram.size = cram["size"].natural();
if(prgrom.size) prgrom.data = new uint8[prgrom.size](); if(prgrom.size) prgrom.data = new uint8[prgrom.size]();
if(prgram.size) prgram.data = new uint8[prgram.size](); if(prgram.size) prgram.data = new uint8[prgram.size]();

View File

@ -50,8 +50,8 @@ void serialize(serializer& s) {
} }
KonamiVRC2(Markup::Node& document) : Board(document), vrc2(*this) { KonamiVRC2(Markup::Node& document) : Board(document), vrc2(*this) {
settings.pinout.a0 = 1 << document["cartridge/chip/pinout/a0"].decimal(); settings.pinout.a0 = 1 << document["cartridge/chip/pinout/a0"].natural();
settings.pinout.a1 = 1 << document["cartridge/chip/pinout/a1"].decimal(); settings.pinout.a1 = 1 << document["cartridge/chip/pinout/a1"].natural();
} }
}; };

View File

@ -54,8 +54,8 @@ void serialize(serializer& s) {
} }
KonamiVRC4(Markup::Node& document) : Board(document), vrc4(*this) { KonamiVRC4(Markup::Node& document) : Board(document), vrc4(*this) {
settings.pinout.a0 = 1 << document["cartridge/chip/pinout/a0"].decimal(); settings.pinout.a0 = 1 << document["cartridge/chip/pinout/a0"].natural();
settings.pinout.a1 = 1 << document["cartridge/chip/pinout/a1"].decimal(); settings.pinout.a1 = 1 << document["cartridge/chip/pinout/a1"].natural();
} }
}; };

View File

@ -66,10 +66,10 @@ void Cartridge::load(System::Revision revision) {
auto rom = document["cartridge/rom"]; auto rom = document["cartridge/rom"];
auto ram = document["cartridge/ram"]; auto ram = document["cartridge/ram"];
romsize = rom["size"].decimal(); romsize = rom["size"].natural();
romdata = allocate<uint8>(romsize, 0xff); romdata = allocate<uint8>(romsize, 0xff);
ramsize = ram["size"].decimal(); ramsize = ram["size"].natural();
ramdata = allocate<uint8>(ramsize, 0xff); ramdata = allocate<uint8>(ramsize, 0xff);
//Super Game Boy core loads memory from Super Famicom core //Super Game Boy core loads memory from Super Famicom core
@ -79,8 +79,8 @@ void Cartridge::load(System::Revision revision) {
if(auto name = ram["name"].text()) memory.append({ID::RAM, name}); if(auto name = ram["name"].text()) memory.append({ID::RAM, name});
} }
information.romsize = rom["size"].decimal(); information.romsize = rom["size"].natural();
information.ramsize = ram["size"].decimal(); information.ramsize = ram["size"].natural();
information.battery = (bool)ram["name"]; information.battery = (bool)ram["name"];
switch(information.mapper) { default: switch(information.mapper) { default:

View File

@ -32,10 +32,10 @@ void APU::Noise::clockenvelope() {
uint8 APU::Noise::read(unsigned addr) const { uint8 APU::Noise::read(unsigned addr) const {
switch(addr) { switch(addr) {
case 1: return (length << 0); case 1: return 0;
case 2: return (envelope.frequency << 0) | (envelope.direction << 3) | (envelope.volume << 4); case 2: return (envelope.frequency << 0) | (envelope.direction << 3) | (envelope.volume << 4);
case 3: return (divisor << 0) | (narrowlfsr << 3) | (frequency << 4); case 3: return (divisor << 0) | (narrowlfsr << 3) | (frequency << 4);
case 4: return (counter << 6) | (initialize << 7); case 4: return (counter << 6);
} }
} }

View File

@ -39,13 +39,7 @@ uint8 APU::Sequencer::read(unsigned addr) const {
| (lenable[2] << 6) | (lenable[2] << 6)
| (lenable[3] << 7) | (lenable[3] << 7)
); );
case 2: return ( case 2: return (masterenable << 7);
(enable[0] << 0)
| (enable[1] << 1)
| (enable[2] << 2)
| (enable[3] << 3)
| (masterenable << 7)
);
} }
} }

View File

@ -25,10 +25,10 @@ void APU::Square1::clocksweep() {
uint8 APU::Square1::read(unsigned addr) const { uint8 APU::Square1::read(unsigned addr) const {
switch(addr) { switch(addr) {
case 0: return (sweep.shift << 0) | (sweep.direction << 3) | (sweep.frequency << 4); case 0: return (sweep.shift << 0) | (sweep.direction << 3) | (sweep.frequency << 4);
case 1: return (length << 0) | (duty << 6); case 1: return (duty << 6);
case 2: return (envelope.frequency << 0) | (envelope.direction << 3) | (envelope.volume << 4); case 2: return (envelope.frequency << 0) | (envelope.direction << 3) | (envelope.volume << 4);
case 3: return (frequency << 0); case 3: return 0;
case 4: return (frequency >> 8) | (counter << 6) | (initialize << 7); case 4: return (counter << 6);
} }
} }

View File

@ -1,9 +1,9 @@
uint8 APU::Square2::read(unsigned addr) const { uint8 APU::Square2::read(unsigned addr) const {
switch(addr) { switch(addr) {
case 1: return (length << 0) | (duty << 6); case 1: return (duty << 6);
case 2: return (envelope.frequency << 0) | (envelope.direction << 3) | (envelope.volume << 4); case 2: return (envelope.frequency << 0) | (envelope.direction << 3) | (envelope.volume << 4);
case 3: return (frequency >> 0); case 3: return 0;
case 4: return (frequency >> 8) | (counter << 6) | (initialize << 7); case 4: return (counter << 6);
} }
} }

View File

@ -20,10 +20,10 @@ void APU::Wave::clocklength() {
uint8 APU::Wave::read(unsigned addr) const { uint8 APU::Wave::read(unsigned addr) const {
switch(addr) { switch(addr) {
case 0: return (mode << 5) | (bank << 6) | (dacenable << 7); case 0: return (mode << 5) | (bank << 6) | (dacenable << 7);
case 1: return (length << 0); case 1: return 0;
case 2: return (volume << 5); case 2: return (volume << 5);
case 3: return (frequency >> 0); case 3: return 0;
case 4: return (frequency >> 8) | (counter << 6) | (initialize << 7); case 4: return (counter << 6);
} }
} }

View File

@ -46,14 +46,14 @@ auto Cartridge::load() -> void {
hasFLASH = false; hasFLASH = false;
if(auto info = document["cartridge/mrom"]) { if(auto info = document["cartridge/mrom"]) {
mrom.size = min(32 * 1024 * 1024, info["size"].decimal()); mrom.size = min(32 * 1024 * 1024, info["size"].natural());
interface->loadRequest(ID::MROM, info["name"].text(), true); interface->loadRequest(ID::MROM, info["name"].text(), true);
} }
if(auto info = document["cartridge/sram"]) { if(auto info = document["cartridge/sram"]) {
hasSRAM = true; hasSRAM = true;
sram.size = min(32 * 1024, info["size"].decimal()); sram.size = min(32 * 1024, info["size"].natural());
sram.mask = sram.size - 1; sram.mask = sram.size - 1;
for(auto n : range(sram.size)) sram.data[n] = 0xff; for(auto n : range(sram.size)) sram.data[n] = 0xff;
@ -63,7 +63,7 @@ auto Cartridge::load() -> void {
if(auto info = document["cartridge/eeprom"]) { if(auto info = document["cartridge/eeprom"]) {
hasEEPROM = true; hasEEPROM = true;
eeprom.size = min(8 * 1024, info["size"].decimal()); eeprom.size = min(8 * 1024, info["size"].natural());
eeprom.bits = eeprom.size <= 512 ? 6 : 14; eeprom.bits = eeprom.size <= 512 ? 6 : 14;
if(eeprom.size == 0) eeprom.size = 8192, eeprom.bits = 0; //auto-detect size if(eeprom.size == 0) eeprom.size = 8192, eeprom.bits = 0; //auto-detect size
eeprom.mask = mrom.size > 16 * 1024 * 1024 ? 0x0fffff00 : 0x0f000000; eeprom.mask = mrom.size > 16 * 1024 * 1024 ? 0x0fffff00 : 0x0f000000;
@ -76,8 +76,8 @@ auto Cartridge::load() -> void {
if(auto info = document["cartridge/flash"]) { if(auto info = document["cartridge/flash"]) {
hasFLASH = true; hasFLASH = true;
flash.id = info["id"].decimal(); flash.id = info["id"].natural();
flash.size = min(128 * 1024, info["size"].decimal()); flash.size = min(128 * 1024, info["size"].natural());
for(auto n : range(flash.size)) flash.data[n] = 0xff; for(auto n : range(flash.size)) flash.data[n] = 0xff;
//if flash ID not provided; guess that it's a Macronix chip //if flash ID not provided; guess that it's a Macronix chip

View File

@ -190,6 +190,7 @@ auto CPU::write(uint32 addr, uint8 byte) -> void {
case 0x040000c6: case 0x040000c7: case 0x040000c6: case 0x040000c7:
case 0x040000d2: case 0x040000d3: case 0x040000d2: case 0x040000d3:
case 0x040000de: case 0x040000df: { case 0x040000de: case 0x040000df: {
if(addr == 0x040000bb || addr == 0x040000c7 || addr == 0x040000d3) byte &= 0xf7; //gamepak DRQ valid for DMA3 only
auto& dma = regs.dma[(addr - 0x040000ba) / 12]; auto& dma = regs.dma[(addr - 0x040000ba) / 12];
unsigned shift = (addr & 1) * 8; unsigned shift = (addr & 1) * 8;
bool enable = dma.control.enable; bool enable = dma.control.enable;

View File

@ -41,6 +41,8 @@ uint8 PPU::read(uint32 addr) {
case 0x04000052: return regs.blend.eva; case 0x04000052: return regs.blend.eva;
case 0x04000053: return regs.blend.evb; case 0x04000053: return regs.blend.evb;
//BLDY is write-only
} }
return 0u; return 0u;
@ -194,11 +196,11 @@ void PPU::write(uint32 addr, uint8 byte) {
case 0x04000051: regs.blend.control = (regs.blend.control & 0x00ff) | (byte << 8); return; case 0x04000051: regs.blend.control = (regs.blend.control & 0x00ff) | (byte << 8); return;
//BLDALPHA //BLDALPHA
case 0x04000052: regs.blend.eva = std::min(16, byte & 0x1f); return; case 0x04000052: regs.blend.eva = byte & 0x1f; return;
case 0x04000053: regs.blend.evb = std::min(16, byte & 0x1f); return; case 0x04000053: regs.blend.evb = byte & 0x1f; return;
//BLDY //BLDY
case 0x04000054: regs.blend.evy = std::min(16, byte & 0x1f); return; case 0x04000054: regs.blend.evy = byte & 0x1f; return;
case 0x04000055: return; case 0x04000055: return;
} }

View File

@ -62,6 +62,7 @@ PPU::Registers::BackgroundControl::operator uint16() const {
return ( return (
(priority << 0) (priority << 0)
| (characterbaseblock << 2) | (characterbaseblock << 2)
| (unused << 4)
| (mosaic << 6) | (mosaic << 6)
| (colormode << 7) | (colormode << 7)
| (screenbaseblock << 8) | (screenbaseblock << 8)

View File

@ -77,6 +77,9 @@ void PPU::render_window(unsigned w) {
} }
unsigned PPU::blend(unsigned above, unsigned eva, unsigned below, unsigned evb) { unsigned PPU::blend(unsigned above, unsigned eva, unsigned below, unsigned evb) {
eva = min(16, eva);
evb = min(16, evb);
uint5 ar = above >> 0, ag = above >> 5, ab = above >> 10; uint5 ar = above >> 0, ag = above >> 5, ab = above >> 10;
uint5 br = below >> 0, bg = below >> 5, bb = below >> 10; uint5 br = below >> 0, bg = below >> 5, bb = below >> 10;

View File

@ -35,7 +35,7 @@ NSFont* pFont::cocoaFont(string description) {
CGFloat size = 8.0; CGFloat size = 8.0;
if(!part(0).empty()) family = [NSString stringWithUTF8String:part(0)]; if(!part(0).empty()) family = [NSString stringWithUTF8String:part(0)];
if(!part(1).empty()) size = decimal(part(1)); if(!part(1).empty()) size = part(1).natural();
if(part(2).ifind("bold")) traits |= NSBoldFontMask; if(part(2).ifind("bold")) traits |= NSBoldFontMask;
if(part(2).ifind("italic")) traits |= NSItalicFontMask; if(part(2).ifind("italic")) traits |= NSItalicFontMask;
if(part(2).ifind("narrow")) traits |= NSNarrowFontMask; if(part(2).ifind("narrow")) traits |= NSNarrowFontMask;

View File

@ -27,6 +27,8 @@
#define Hiro_BrowserWindow #define Hiro_BrowserWindow
#define Hiro_MessageWindow #define Hiro_MessageWindow
#define Hiro_Property
#define Hiro_Object #define Hiro_Object
#define Hiro_Group #define Hiro_Group

View File

@ -49,6 +49,8 @@ namespace hiro {
#include "browser-window.cpp" #include "browser-window.cpp"
#include "message-window.cpp" #include "message-window.cpp"
#include "property.cpp"
#include "object.cpp" #include "object.cpp"
#include "group.cpp" #include "group.cpp"

View File

@ -5,6 +5,7 @@
#include <nall/image.hpp> #include <nall/image.hpp>
#include <nall/maybe.hpp> #include <nall/maybe.hpp>
#include <nall/range.hpp> #include <nall/range.hpp>
#include <nall/set.hpp>
#include <nall/shared-pointer.hpp> #include <nall/shared-pointer.hpp>
#include <nall/stdint.hpp> #include <nall/stdint.hpp>
#include <nall/string.hpp> #include <nall/string.hpp>
@ -15,6 +16,8 @@
using nall::function; using nall::function;
using nall::lstring; using nall::lstring;
using nall::maybe; using nall::maybe;
using nall::nothing;
using nall::set;
using nall::shared_pointer; using nall::shared_pointer;
using nall::shared_pointer_weak; using nall::shared_pointer_weak;
using nall::string; using nall::string;
@ -542,6 +545,25 @@ struct MessageWindow {
}; };
#endif #endif
struct Property {
using type = Property;
Property(const string& name, const string& value = "");
auto operator==(const Property& source) const -> bool;
auto operator< (const Property& source) const -> bool;
auto name() const -> string;
auto setValue(const string& value = "") -> type&;
auto value() const -> string;
private:
struct State {
string name;
string value;
} state;
};
#define Declare(Name) \ #define Declare(Name) \
using type = m##Name; \ using type = m##Name; \
operator s##Name() const { return instance; } \ operator s##Name() const { return instance; } \
@ -595,6 +617,7 @@ struct mObject {
auto parentTreeViewItem(bool recursive = false) const -> mTreeViewItem*; auto parentTreeViewItem(bool recursive = false) const -> mTreeViewItem*;
auto parentWidget(bool recursive = false) const -> mWidget*; auto parentWidget(bool recursive = false) const -> mWidget*;
auto parentWindow(bool recursive = false) const -> mWindow*; auto parentWindow(bool recursive = false) const -> mWindow*;
auto property(const string& name) const -> string;
virtual auto remove() -> type&; virtual auto remove() -> type&;
virtual auto reset() -> type&; virtual auto reset() -> type&;
virtual auto setEnabled(bool enabled = true) -> type&; virtual auto setEnabled(bool enabled = true) -> type&;
@ -602,6 +625,7 @@ struct mObject {
virtual auto setFont(const Font& font = {}) -> type&; virtual auto setFont(const Font& font = {}) -> type&;
virtual auto setGroup(sGroup group = {}) -> type&; virtual auto setGroup(sGroup group = {}) -> type&;
virtual auto setParent(mObject* parent = nullptr, signed offset = -1) -> type&; virtual auto setParent(mObject* parent = nullptr, signed offset = -1) -> type&;
virtual auto setProperty(const string& name, const string& value = "") -> type&;
virtual auto setVisible(bool visible = true) -> type&; virtual auto setVisible(bool visible = true) -> type&;
auto visible(bool recursive = false) const -> bool; auto visible(bool recursive = false) const -> bool;
@ -611,6 +635,7 @@ struct mObject {
Font font; Font font;
signed offset = -1; signed offset = -1;
mObject* parent = nullptr; mObject* parent = nullptr;
set<Property> properties;
bool visible = true; bool visible = true;
} state; } state;

View File

@ -256,6 +256,13 @@ auto mObject::parentWindow(bool recursive) const -> mWindow* {
} }
#endif #endif
auto mObject::property(const string& name) const -> string {
if(auto property = state.properties.find({name})) {
return property->value();
}
return {};
}
auto mObject::remove() -> type& { auto mObject::remove() -> type& {
signal(remove); signal(remove);
return *this; return *this;
@ -295,6 +302,16 @@ auto mObject::setParent(mObject* parent, signed offset) -> type& {
return *this; return *this;
} }
auto mObject::setProperty(const string& name, const string& value) -> type& {
if(auto property = state.properties.find(name)) {
if(value) property->setValue(value);
else state.properties.remove(*property);
} else {
if(value) state.properties.insert({name, value});
}
return *this;
}
auto mObject::setVisible(bool visible) -> type& { auto mObject::setVisible(bool visible) -> type& {
state.visible = visible; state.visible = visible;
signal(setVisible, this->visible(true)); signal(setVisible, this->visible(true));

29
hiro/core/property.cpp Normal file
View File

@ -0,0 +1,29 @@
#if defined(Hiro_Property)
Property::Property(const string& name, const string& value) {
state.name = name;
state.value = value;
}
auto Property::operator==(const Property& source) const -> bool {
return state.name == source.state.name;
}
auto Property::operator<(const Property& source) const -> bool {
return state.name < source.state.name;
}
auto Property::name() const -> string {
return state.name;
}
auto Property::setValue(const string& value) -> type& {
state.value = value;
return *this;
}
auto Property::value() const -> string {
return state.value;
}
#endif

View File

@ -25,10 +25,12 @@
} \ } \
return Object(); \ return Object(); \
} \ } \
auto property(const string& name) const { return self().property(name); } \
auto remove() { return self().remove(), *this; } \ auto remove() { return self().remove(), *this; } \
auto setEnabled(bool enabled = true) { return self().setEnabled(enabled), *this; } \ auto setEnabled(bool enabled = true) { return self().setEnabled(enabled), *this; } \
auto setFocused() { return self().setFocused(), *this; } \ auto setFocused() { return self().setFocused(), *this; } \
auto setFont(const Font& font = {}) { return self().setFont(font), *this; } \ auto setFont(const Font& font = {}) { return self().setFont(font), *this; } \
auto setProperty(const string& name, const string& value = "") { return self().setProperty(name, value), *this; } \
auto setVisible(bool visible = true) { return self().setVisible(visible), *this; } \ auto setVisible(bool visible = true) { return self().setVisible(visible), *this; } \
auto visible(bool recursive = false) const { return self().visible(recursive); } \ auto visible(bool recursive = false) const { return self().visible(recursive); } \

View File

@ -59,7 +59,7 @@ auto mTreeViewItem::image() const -> Image {
auto mTreeViewItem::item(const string& path) const -> TreeViewItem { auto mTreeViewItem::item(const string& path) const -> TreeViewItem {
if(path.empty()) return {}; if(path.empty()) return {};
auto paths = path.split("/"); auto paths = path.split("/");
unsigned position = decimal(paths.takeFirst()); unsigned position = paths.takeFirst().natural();
if(position >= itemCount()) return {}; if(position >= itemCount()) return {};
if(paths.empty()) return state.items[position]; if(paths.empty()) return state.items[position];
return state.items[position]->item(paths.merge("/")); return state.items[position]->item(paths.merge("/"));

View File

@ -45,7 +45,7 @@ auto mTreeView::foregroundColor() const -> Color {
auto mTreeView::item(const string& path) const -> TreeViewItem { auto mTreeView::item(const string& path) const -> TreeViewItem {
if(path.empty()) return {}; if(path.empty()) return {};
auto paths = path.split("/"); auto paths = path.split("/");
unsigned position = decimal(paths.takeFirst()); unsigned position = paths.takeFirst().natural();
if(position >= itemCount()) return {}; if(position >= itemCount()) return {};
if(paths.empty()) return state.items[position]; if(paths.empty()) return state.items[position];
return state.items[position]->item(paths.merge("/")); return state.items[position]->item(paths.merge("/"));

View File

@ -193,7 +193,7 @@ auto pIconView::_updateSelected() -> void {
while(p) { while(p) {
auto path = (GtkTreePath*)p->data; auto path = (GtkTreePath*)p->data;
char* pathString = gtk_tree_path_to_string(path); char* pathString = gtk_tree_path_to_string(path);
unsigned position = decimal(pathString); unsigned position = natural(pathString);
g_free(pathString); g_free(pathString);
selected.append(position); selected.append(position);
p = p->next; p = p->next;

View File

@ -212,7 +212,7 @@ auto pListView::_doContext() -> void {
auto pListView::_doDataFunc(GtkTreeViewColumn* gtkColumn, GtkCellRenderer* renderer, GtkTreeIter* iter) -> void { auto pListView::_doDataFunc(GtkTreeViewColumn* gtkColumn, GtkCellRenderer* renderer, GtkTreeIter* iter) -> void {
auto path = gtk_tree_model_get_string_from_iter(gtkTreeModel, iter); auto path = gtk_tree_model_get_string_from_iter(gtkTreeModel, iter);
auto row = decimal(path); auto row = natural(path);
g_free(path); g_free(path);
if(auto& header = state().header) { if(auto& header = state().header) {
@ -265,7 +265,7 @@ auto pListView::_doEdit(GtkCellRendererText* gtkCellRendererText, const char* pa
for(auto& column : header->state.columns) { for(auto& column : header->state.columns) {
if(auto delegate = column->self()) { if(auto delegate = column->self()) {
if(gtkCellRendererText == GTK_CELL_RENDERER_TEXT(delegate->gtkCellText)) { if(gtkCellRendererText == GTK_CELL_RENDERER_TEXT(delegate->gtkCellText)) {
auto row = decimal(path); auto row = natural(path);
if(auto item = self().item(row)) { if(auto item = self().item(row)) {
if(auto cell = item->cell(column->offset())) { if(auto cell = item->cell(column->offset())) {
if(string{text} != cell->state.text) { if(string{text} != cell->state.text) {
@ -337,7 +337,7 @@ auto pListView::_doToggle(GtkCellRendererToggle* gtkCellRendererToggle, const ch
for(auto& column : header->state.columns) { for(auto& column : header->state.columns) {
if(auto delegate = column->self()) { if(auto delegate = column->self()) {
if(gtkCellRendererToggle == GTK_CELL_RENDERER_TOGGLE(delegate->gtkCellToggle)) { if(gtkCellRendererToggle == GTK_CELL_RENDERER_TOGGLE(delegate->gtkCellToggle)) {
auto row = decimal(path); auto row = natural(path);
if(auto item = self().item(row)) { if(auto item = self().item(row)) {
if(auto cell = item->cell(column->offset())) { if(auto cell = item->cell(column->offset())) {
cell->setChecked(!cell->checked()); cell->setChecked(!cell->checked());
@ -365,7 +365,7 @@ auto pListView::_updateSelected() -> void {
GtkTreeIter iter; GtkTreeIter iter;
if(gtk_tree_model_get_iter(gtkTreeModel, &iter, (GtkTreePath*)p->data)) { if(gtk_tree_model_get_iter(gtkTreeModel, &iter, (GtkTreePath*)p->data)) {
char* pathname = gtk_tree_model_get_string_from_iter(gtkTreeModel, &iter); char* pathname = gtk_tree_model_get_string_from_iter(gtkTreeModel, &iter);
unsigned selection = decimal(pathname); unsigned selection = natural(pathname);
g_free(pathname); g_free(pathname);
selected.append(selection); selected.append(selection);
} }

View File

@ -123,10 +123,10 @@ auto pTreeView::_doDataFunc(GtkTreeViewColumn* column, GtkCellRenderer* renderer
auto parts = string{path}.split(":"); auto parts = string{path}.split(":");
g_free(path); g_free(path);
auto item = self().item(decimal(parts.takeFirst())); auto item = self().item(parts.takeFirst().natural());
if(!item) return; if(!item) return;
while(parts) { while(parts) {
item = item.item(decimal(parts.takeFirst())); item = item.item(parts.takeFirst().natural());
if(!item) return; if(!item) return;
} }

View File

@ -2,10 +2,11 @@
#define NALL_ATOI_HPP #define NALL_ATOI_HPP
#include <nall/stdint.hpp> #include <nall/stdint.hpp>
#include <nall/varint.hpp>
namespace nall { namespace nall {
constexpr inline auto binary_(const char* s, uintmax_t sum = 0) -> uintmax_t { constexpr inline auto binary_(const char* s, uintmax sum = 0) -> uintmax {
return ( return (
*s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | *s - '0') : *s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | *s - '0') :
*s == '\'' ? binary_(s + 1, sum) : *s == '\'' ? binary_(s + 1, sum) :
@ -13,7 +14,7 @@ constexpr inline auto binary_(const char* s, uintmax_t sum = 0) -> uintmax_t {
); );
} }
constexpr inline auto octal_(const char* s, uintmax_t sum = 0) -> uintmax_t { constexpr inline auto octal_(const char* s, uintmax sum = 0) -> uintmax {
return ( return (
*s >= '0' && *s <= '7' ? octal_(s + 1, (sum << 3) | *s - '0') : *s >= '0' && *s <= '7' ? octal_(s + 1, (sum << 3) | *s - '0') :
*s == '\'' ? octal_(s + 1, sum) : *s == '\'' ? octal_(s + 1, sum) :
@ -21,15 +22,15 @@ constexpr inline auto octal_(const char* s, uintmax_t sum = 0) -> uintmax_t {
); );
} }
constexpr inline auto decimal_(const char* s, uintmax_t sum = 0) -> uintmax_t { constexpr inline auto natural_(const char* s, uintmax sum = 0) -> uintmax {
return ( return (
*s >= '0' && *s <= '9' ? decimal_(s + 1, (sum * 10) + *s - '0') : *s >= '0' && *s <= '9' ? natural_(s + 1, (sum * 10) + *s - '0') :
*s == '\'' ? decimal_(s + 1, sum) : *s == '\'' ? natural_(s + 1, sum) :
sum sum
); );
} }
constexpr inline auto hex_(const char* s, uintmax_t sum = 0) -> uintmax_t { constexpr inline auto hex_(const char* s, uintmax sum = 0) -> uintmax {
return ( return (
*s >= 'A' && *s <= 'F' ? hex_(s + 1, (sum << 4) | *s - 'A' + 10) : *s >= 'A' && *s <= 'F' ? hex_(s + 1, (sum << 4) | *s - 'A' + 10) :
*s >= 'a' && *s <= 'f' ? hex_(s + 1, (sum << 4) | *s - 'a' + 10) : *s >= 'a' && *s <= 'f' ? hex_(s + 1, (sum << 4) | *s - 'a' + 10) :
@ -41,7 +42,7 @@ constexpr inline auto hex_(const char* s, uintmax_t sum = 0) -> uintmax_t {
// //
constexpr inline auto binary(const char* s) -> uintmax_t { constexpr inline auto binary(const char* s) -> uintmax {
return ( return (
*s == '0' && *(s + 1) == 'B' ? binary_(s + 2) : *s == '0' && *(s + 1) == 'B' ? binary_(s + 2) :
*s == '0' && *(s + 1) == 'b' ? binary_(s + 2) : *s == '0' && *(s + 1) == 'b' ? binary_(s + 2) :
@ -50,7 +51,7 @@ constexpr inline auto binary(const char* s) -> uintmax_t {
); );
} }
constexpr inline auto octal(const char* s) -> uintmax_t { constexpr inline auto octal(const char* s) -> uintmax {
return ( return (
*s == '0' && *(s + 1) == 'O' ? octal_(s + 2) : *s == '0' && *(s + 1) == 'O' ? octal_(s + 2) :
*s == '0' && *(s + 1) == 'o' ? octal_(s + 2) : *s == '0' && *(s + 1) == 'o' ? octal_(s + 2) :
@ -58,21 +59,21 @@ constexpr inline auto octal(const char* s) -> uintmax_t {
); );
} }
constexpr inline auto integer(const char* s) -> intmax_t { constexpr inline auto integer(const char* s) -> intmax {
return ( return (
*s == '+' ? +decimal_(s + 1) : *s == '+' ? +natural_(s + 1) :
*s == '-' ? -decimal_(s + 1) : *s == '-' ? -natural_(s + 1) :
decimal_(s) natural_(s)
); );
} }
constexpr inline auto decimal(const char* s) -> uintmax_t { constexpr inline auto natural(const char* s) -> uintmax {
return ( return (
decimal_(s) natural_(s)
); );
} }
constexpr inline auto hex(const char* s) -> uintmax_t { constexpr inline auto hex(const char* s) -> uintmax {
return ( return (
*s == '0' && *(s + 1) == 'X' ? hex_(s + 2) : *s == '0' && *(s + 1) == 'X' ? hex_(s + 2) :
*s == '0' && *(s + 1) == 'x' ? hex_(s + 2) : *s == '0' && *(s + 1) == 'x' ? hex_(s + 2) :

View File

@ -11,7 +11,7 @@ namespace Configuration {
struct Node { struct Node {
string name; string name;
string desc; string desc;
enum class Type : unsigned { Null, Bool, Signed, Unsigned, Double, String } type = Type::Null; enum class Type : unsigned { Null, Boolean, Integer, Natural, Double, String } type = Type::Null;
void* data = nullptr; void* data = nullptr;
vector<Node> children; vector<Node> children;
@ -21,9 +21,9 @@ struct Node {
auto get() const -> string { auto get() const -> string {
switch(type) { switch(type) {
case Type::Bool: return {*(bool*)data}; case Type::Boolean: return {*(bool*)data};
case Type::Signed: return {*(signed*)data}; case Type::Integer: return {*(int*)data};
case Type::Unsigned: return {*(unsigned*)data}; case Type::Natural: return {*(uint*)data};
case Type::Double: return {*(double*)data}; case Type::Double: return {*(double*)data};
case Type::String: return {*(string*)data}; case Type::String: return {*(string*)data};
} }
@ -32,18 +32,18 @@ struct Node {
auto set(const string& value) -> void { auto set(const string& value) -> void {
switch(type) { switch(type) {
case Type::Bool: *(bool*)data = (value != "false"); break; case Type::Boolean: *(bool*)data = (value != "false"); break;
case Type::Signed: *(signed*)data = integer(value); break; case Type::Integer: *(int*)data = integer(value); break;
case Type::Unsigned: *(unsigned*)data = decimal(value); break; case Type::Natural: *(uint*)data = natural(value); break;
case Type::Double: *(double*)data = real(value); break; case Type::Double: *(double*)data = real(value); break;
case Type::String: *(string*)data = value; break; case Type::String: *(string*)data = value; break;
} }
} }
auto assign() { type = Type::Null; data = nullptr; } auto assign() { type = Type::Null; data = nullptr; }
auto assign(bool& bind) { type = Type::Bool; data = (void*)&bind; } auto assign(bool& bind) { type = Type::Boolean; data = (void*)&bind; }
auto assign(signed& bind) { type = Type::Signed; data = (void*)&bind; } auto assign(int& bind) { type = Type::Integer; data = (void*)&bind; }
auto assign(unsigned& bind) { type = Type::Unsigned; data = (void*)&bind; } auto assign(uint& bind) { type = Type::Natural; data = (void*)&bind; }
auto assign(double& bind) { type = Type::Double; data = (void*)&bind; } auto assign(double& bind) { type = Type::Double; data = (void*)&bind; }
auto assign(string& bind) { type = Type::String; data = (void*)&bind; } auto assign(string& bind) { type = Type::String; data = (void*)&bind; }
auto assign(const Node& node) { operator=(node); } auto assign(const Node& node) { operator=(node); }
@ -80,10 +80,10 @@ struct Node {
auto save(file& fp, unsigned depth = 0) -> void { auto save(file& fp, unsigned depth = 0) -> void {
for(auto& child : children) { for(auto& child : children) {
if(child.desc) { if(child.desc) {
for(unsigned n = 0; n < depth; n++) fp.print(" "); for(auto n : range(depth)) fp.print(" ");
fp.print("//", child.desc, "\n"); fp.print("//", child.desc, "\n");
} }
for(unsigned n = 0; n < depth; n++) fp.print(" "); for(auto n : range(depth)) fp.print(" ");
fp.print(child.name); fp.print(child.name);
if(!child.empty()) fp.print(": ", child.get()); if(!child.empty()) fp.print(": ", child.get());
fp.print("\n"); fp.print("\n");

View File

@ -40,7 +40,7 @@ struct ODBC {
return value; return value;
} }
auto decimal(unsigned column) -> uint64_t { auto natural(unsigned column) -> uint64_t {
if(auto value = _values(column)) return value.get<uint64_t>(0); if(auto value = _values(column)) return value.get<uint64_t>(0);
uint64_t value = 0; uint64_t value = 0;
SQLGetData(statement(), 1 + column, SQL_C_UBIGINT, &value, 0, nullptr); SQLGetData(statement(), 1 + column, SQL_C_UBIGINT, &value, 0, nullptr);
@ -79,7 +79,7 @@ struct ODBC {
} }
auto integer() -> int64_t { return integer(_output++); } auto integer() -> int64_t { return integer(_output++); }
auto decimal() -> uint64_t { return decimal(_output++); } auto natural() -> uint64_t { return natural(_output++); }
auto real() -> double { return real(_output++); } auto real() -> double { return real(_output++); }
auto text() -> string { return text(_output++); } auto text() -> string { return text(_output++); }
auto data() -> vector<uint8_t> { return data(_output++); } auto data() -> vector<uint8_t> { return data(_output++); }

View File

@ -43,7 +43,7 @@ struct SQLite3 {
return sqlite3_column_int64(statement(), column); return sqlite3_column_int64(statement(), column);
} }
auto decimal(unsigned column) -> uint64_t { auto natural(unsigned column) -> uint64_t {
return sqlite3_column_int64(statement(), column); return sqlite3_column_int64(statement(), column);
} }
@ -70,7 +70,7 @@ struct SQLite3 {
} }
auto integer() -> int64_t { return integer(_output++); } auto integer() -> int64_t { return integer(_output++); }
auto decimal() -> uint64_t { return decimal(_output++); } auto natural() -> uint64_t { return natural(_output++); }
auto real() -> double { return real(_output++); } auto real() -> double { return real(_output++); }
auto text() -> string { return text(_output++); } auto text() -> string { return text(_output++); }
auto data() -> vector<uint8_t> { return data(_output++); } auto data() -> vector<uint8_t> { return data(_output++); }

View File

@ -95,7 +95,7 @@ auto Response::setHead() -> bool {
else if(response.ibeginsWith("HTTP/1.1 ")) response.iltrim("HTTP/1.1 ", 1L); else if(response.ibeginsWith("HTTP/1.1 ")) response.iltrim("HTTP/1.1 ", 1L);
else return false; else return false;
setResponseType(decimal(response)); setResponseType(natural(response));
for(auto& header : headers) { for(auto& header : headers) {
if(header.beginsWith(" ") || header.beginsWith("\t")) continue; if(header.beginsWith(" ") || header.beginsWith("\t")) continue;
@ -156,7 +156,7 @@ auto Response::hasBody() const -> bool {
} }
auto Response::findContentLength() const -> unsigned { auto Response::findContentLength() const -> unsigned {
if(auto contentLength = header["Content-Length"]) return contentLength.value().decimal(); if(auto contentLength = header["Content-Length"]) return contentLength.value().natural();
if(_body) return _body.size(); if(_body) return _body.size();
if(hasData()) return data().size(); if(hasData()) return data().size();
if(hasFile()) return file::size(file()); if(hasFile()) return file::size(file());

View File

@ -83,7 +83,7 @@ auto Role::download(signed fd, Message& message) -> bool {
headReceived = true; headReceived = true;
if(!message.setHead()) return false; if(!message.setHead()) return false;
chunked = message.header["Transfer-Encoding"].value().iequals("chunked"); chunked = message.header["Transfer-Encoding"].value().iequals("chunked");
contentLength = message.header["Content-Length"].value().decimal(); contentLength = message.header["Content-Length"].value().natural();
} }
continue; continue;

View File

@ -12,9 +12,8 @@
//- only plain-old-data can be stored. complex classes must provide serialize(serializer&); //- only plain-old-data can be stored. complex classes must provide serialize(serializer&);
//- floating-point usage is not portable across different implementations //- floating-point usage is not portable across different implementations
#include <type_traits>
#include <utility>
#include <nall/stdint.hpp> #include <nall/stdint.hpp>
#include <nall/traits.hpp>
#include <nall/utility.hpp> #include <nall/utility.hpp>
namespace nall { namespace nall {

View File

@ -2,18 +2,18 @@
namespace nall { namespace nall {
auto string::integer() const -> intmax_t { auto string::integer() const -> intmax {
if(beginsWith("0b") || beginsWith("0B")) return nall::binary(data()); if(beginsWith("0b") || beginsWith("0B")) return nall::binary(data());
if(beginsWith("0o") || beginsWith("0O")) return nall::octal(data()); if(beginsWith("0o") || beginsWith("0O")) return nall::octal(data());
if(beginsWith("0x") || beginsWith("0X")) return nall::hex(data()); if(beginsWith("0x") || beginsWith("0X")) return nall::hex(data());
return nall::integer(data()); return nall::integer(data());
} }
auto string::decimal() const -> uintmax_t { auto string::natural() const -> uintmax {
if(beginsWith("0b") || beginsWith("0B")) return nall::binary(data()); if(beginsWith("0b") || beginsWith("0B")) return nall::binary(data());
if(beginsWith("0o") || beginsWith("0O")) return nall::octal(data()); if(beginsWith("0o") || beginsWith("0O")) return nall::octal(data());
if(beginsWith("0x") || beginsWith("0X")) return nall::hex(data()); if(beginsWith("0x") || beginsWith("0X")) return nall::hex(data());
return nall::decimal(data()); return nall::natural(data());
} }
auto string::real() const -> double { auto string::real() const -> double {

View File

@ -150,8 +150,8 @@ public:
auto end() const -> const char* { return &data()[size()]; } auto end() const -> const char* { return &data()[size()]; }
//atoi.hpp //atoi.hpp
inline auto integer() const -> intmax_t; inline auto integer() const -> intmax;
inline auto decimal() const -> uintmax_t; inline auto natural() const -> uintmax;
inline auto real() const -> double; inline auto real() const -> double;
//core.hpp //core.hpp

View File

@ -32,7 +32,7 @@ auto string::format(const nall::format& params) -> type& {
}; };
if(!isNumeric(&data[x + 1], &data[y - 1])) { x++; continue; } if(!isNumeric(&data[x + 1], &data[y - 1])) { x++; continue; }
unsigned index = nall::decimal(&data[x + 1]); unsigned index = nall::natural(&data[x + 1]);
if(index >= params.size()) { x++; continue; } if(index >= params.size()) { x++; continue; }
unsigned sourceSize = y - x; unsigned sourceSize = y - x;

View File

@ -41,10 +41,10 @@ auto ManagedNode::_evaluate(string query) const -> bool {
switch(comparator) { switch(comparator) {
case Comparator::EQ: if(data.match(side(1)) == true) continue; break; case Comparator::EQ: if(data.match(side(1)) == true) continue; break;
case Comparator::NE: if(data.match(side(1)) == false) continue; break; case Comparator::NE: if(data.match(side(1)) == false) continue; break;
case Comparator::LT: if(data.decimal() < side(1).decimal()) continue; break; case Comparator::LT: if(data.natural() < side(1).natural()) continue; break;
case Comparator::LE: if(data.decimal() <= side(1).decimal()) continue; break; case Comparator::LE: if(data.natural() <= side(1).natural()) continue; break;
case Comparator::GT: if(data.decimal() > side(1).decimal()) continue; break; case Comparator::GT: if(data.natural() > side(1).natural()) continue; break;
case Comparator::GE: if(data.decimal() >= side(1).decimal()) continue; break; case Comparator::GE: if(data.natural() >= side(1).natural()) continue; break;
} }
return false; return false;
@ -65,10 +65,10 @@ auto ManagedNode::_find(const string& query) const -> vector<Node> {
name = p(0); name = p(0);
if(p(1).find("-")) { if(p(1).find("-")) {
p = p(1).split("-", 1L); p = p(1).split("-", 1L);
lo = p(0).empty() ? 0u : p(0).decimal(); lo = p(0).empty() ? 0u : p(0).natural();
hi = p(1).empty() ? ~0u : p(1).decimal(); hi = p(1).empty() ? ~0u : p(1).natural();
} else { } else {
lo = hi = p(1).decimal(); lo = hi = p(1).natural();
} }
} }

View File

@ -60,8 +60,8 @@ struct Node {
auto text() const -> string { return value().strip(); } auto text() const -> string { return value().strip(); }
auto boolean() const -> bool { return text() == "true"; } auto boolean() const -> bool { return text() == "true"; }
auto integer() const -> intmax_t { return text().integer(); } auto integer() const -> intmax { return text().integer(); }
auto decimal() const -> uintmax_t { return text().decimal(); } auto natural() const -> uintmax { return text().natural(); }
auto setName(const string& name = "") -> Node& { shared->_name = name; return *this; } auto setName(const string& name = "") -> Node& { shared->_name = name; return *this; }
auto setValue(const string& value = "") -> Node& { shared->_value = value; return *this; } auto setValue(const string& value = "") -> Node& { shared->_value = value; return *this; }

View File

@ -4,7 +4,6 @@
#include <nall/bit.hpp> #include <nall/bit.hpp>
#include <nall/serializer.hpp> #include <nall/serializer.hpp>
#include <nall/stdint.hpp> #include <nall/stdint.hpp>
#include <nall/traits.hpp>
namespace nall { namespace nall {
@ -209,6 +208,8 @@ using int61 = nall::int_t<61>;
using int62 = nall::int_t<62>; using int62 = nall::int_t<62>;
using int63 = nall::int_t<63>; using int63 = nall::int_t<63>;
using int64 = int64_t; using int64 = int64_t;
using intmax = intmax_t;
using intptr = intptr_t;
using uint1 = nall::uint_t<1>; using uint1 = nall::uint_t<1>;
using uint2 = nall::uint_t<2>; using uint2 = nall::uint_t<2>;
@ -274,6 +275,8 @@ using uint61 = nall::uint_t<61>;
using uint62 = nall::uint_t<62>; using uint62 = nall::uint_t<62>;
using uint63 = nall::uint_t<63>; using uint63 = nall::uint_t<63>;
using uint64 = uint64_t; using uint64 = uint64_t;
using uintmax = uintmax_t;
using uintptr = uintptr_t;
#if defined(__SIZEOF_INT128__) #if defined(__SIZEOF_INT128__)
using int128 = int128_t; using int128 = int128_t;

View File

@ -18,15 +18,15 @@ struct InputMouseRawInput {
} ms; } ms;
auto acquire() -> bool { auto acquire() -> bool {
if(mouseAcquired == false) { if(!mouseAcquired) {
mouseAcquired = true; mouseAcquired = true;
ShowCursor(false); ShowCursor(false);
} }
return true; return acquired();
} }
auto release() -> bool { auto release() -> bool {
if(mouseAcquired == true) { if(mouseAcquired) {
mouseAcquired = false; mouseAcquired = false;
ReleaseCapture(); ReleaseCapture();
ClipCursor(nullptr); ClipCursor(nullptr);
@ -36,7 +36,7 @@ struct InputMouseRawInput {
} }
auto acquired() -> bool { auto acquired() -> bool {
if(mouseAcquired == true) { if(mouseAcquired) {
SetFocus((HWND)handle); SetFocus((HWND)handle);
SetCapture((HWND)handle); SetCapture((HWND)handle);
RECT rc; RECT rc;

View File

@ -19,7 +19,7 @@ auto OpenGL::shader(const string& pathname) -> void {
} }
for(auto node : document["input"]) { for(auto node : document["input"]) {
if(node.name() == "history") historySize = node.decimal(); if(node.name() == "history") historySize = node.natural();
if(node.name() == "format") format = glrFormat(node.text()); if(node.name() == "format") format = glrFormat(node.text());
if(node.name() == "filter") filter = glrFilter(node.text()); if(node.name() == "filter") filter = glrFilter(node.text());
if(node.name() == "wrap") wrap = glrWrap(node.text()); if(node.name() == "wrap") wrap = glrWrap(node.text());
@ -29,11 +29,11 @@ auto OpenGL::shader(const string& pathname) -> void {
string text = node.text(); string text = node.text();
if(node.name() == "width") { if(node.name() == "width") {
if(text.endsWith("%")) relativeWidth = real(text.rtrim("%", 1L)) / 100.0; if(text.endsWith("%")) relativeWidth = real(text.rtrim("%", 1L)) / 100.0;
else absoluteWidth = text.decimal(); else absoluteWidth = text.natural();
} }
if(node.name() == "height") { if(node.name() == "height") {
if(text.endsWith("%")) relativeHeight = real(text.rtrim("%", 1L)) / 100.0; if(text.endsWith("%")) relativeHeight = real(text.rtrim("%", 1L)) / 100.0;
else absoluteHeight = text.decimal(); else absoluteHeight = text.natural();
} }
} }

View File

@ -5,9 +5,9 @@ auto OpenGLProgram::bind(OpenGL* instance, const Markup::Node& node, const strin
string w = node["width"].text(), h = node["height"].text(); string w = node["width"].text(), h = node["height"].text();
if(w.endsWith("%")) relativeWidth = real(w.rtrim("%", 1L)) / 100.0; if(w.endsWith("%")) relativeWidth = real(w.rtrim("%", 1L)) / 100.0;
else absoluteWidth = w.decimal(); else absoluteWidth = w.natural();
if(h.endsWith("%")) relativeHeight = real(h.rtrim("%", 1L)) / 100.0; if(h.endsWith("%")) relativeHeight = real(h.rtrim("%", 1L)) / 100.0;
else absoluteHeight = h.decimal(); else absoluteHeight = h.natural();
format = glrFormat(node["format"].text()); format = glrFormat(node["format"].text());

View File

@ -137,7 +137,7 @@ auto Cartridge::loadSatellaview() -> void {
auto rom = document["cartridge/rom"]; auto rom = document["cartridge/rom"];
if(rom["name"]) { if(rom["name"]) {
unsigned size = rom["size"].decimal(); unsigned size = rom["size"].natural();
satellaviewcartridge.memory.map(allocate<uint8>(size, 0xff), size); satellaviewcartridge.memory.map(allocate<uint8>(size, 0xff), size);
interface->loadRequest(ID::SatellaviewROM, rom["name"].text(), true); interface->loadRequest(ID::SatellaviewROM, rom["name"].text(), true);
@ -154,13 +154,13 @@ auto Cartridge::loadSufamiTurboA() -> void {
auto ram = document["cartridge/ram"]; auto ram = document["cartridge/ram"];
if(rom["name"]) { if(rom["name"]) {
unsigned size = rom["size"].decimal(); unsigned size = rom["size"].natural();
sufamiturboA.rom.map(allocate<uint8>(size, 0xff), size); sufamiturboA.rom.map(allocate<uint8>(size, 0xff), size);
interface->loadRequest(ID::SufamiTurboSlotAROM, rom["name"].text(), true); interface->loadRequest(ID::SufamiTurboSlotAROM, rom["name"].text(), true);
} }
if(ram["name"]) { if(ram["name"]) {
unsigned size = ram["size"].decimal(); unsigned size = ram["size"].natural();
sufamiturboA.ram.map(allocate<uint8>(size, 0xff), size); sufamiturboA.ram.map(allocate<uint8>(size, 0xff), size);
interface->loadRequest(ID::SufamiTurboSlotARAM, ram["name"].text(), false); interface->loadRequest(ID::SufamiTurboSlotARAM, ram["name"].text(), false);
memory.append({ID::SufamiTurboSlotARAM, ram["name"].text()}); memory.append({ID::SufamiTurboSlotARAM, ram["name"].text()});
@ -180,13 +180,13 @@ auto Cartridge::loadSufamiTurboB() -> void {
auto ram = document["cartridge/ram"]; auto ram = document["cartridge/ram"];
if(rom["name"]) { if(rom["name"]) {
unsigned size = rom["size"].decimal(); unsigned size = rom["size"].natural();
sufamiturboB.rom.map(allocate<uint8>(size, 0xff), size); sufamiturboB.rom.map(allocate<uint8>(size, 0xff), size);
interface->loadRequest(ID::SufamiTurboSlotBROM, rom["name"].text(), true); interface->loadRequest(ID::SufamiTurboSlotBROM, rom["name"].text(), true);
} }
if(ram["name"]) { if(ram["name"]) {
unsigned size = ram["size"].decimal(); unsigned size = ram["size"].natural();
sufamiturboB.ram.map(allocate<uint8>(size, 0xff), size); sufamiturboB.ram.map(allocate<uint8>(size, 0xff), size);
interface->loadRequest(ID::SufamiTurboSlotBRAM, ram["name"].text(), false); interface->loadRequest(ID::SufamiTurboSlotBRAM, ram["name"].text(), false);
memory.append({ID::SufamiTurboSlotBRAM, ram["name"].text()}); memory.append({ID::SufamiTurboSlotBRAM, ram["name"].text()});

View File

@ -39,14 +39,14 @@ auto Cartridge::parseMarkup(const string& markup) -> void {
auto Cartridge::parseMarkupMap(Mapping& m, Markup::Node map) -> void { auto Cartridge::parseMarkupMap(Mapping& m, Markup::Node map) -> void {
m.addr = map["address"].text(); m.addr = map["address"].text();
m.size = map["size"].decimal(); m.size = map["size"].natural();
m.base = map["base"].decimal(); m.base = map["base"].natural();
m.mask = map["mask"].decimal(); m.mask = map["mask"].natural();
} }
auto Cartridge::parseMarkupMemory(MappedRAM& ram, Markup::Node node, unsigned id, bool writable) -> void { auto Cartridge::parseMarkupMemory(MappedRAM& ram, Markup::Node node, unsigned id, bool writable) -> void {
string name = node["name"].text(); string name = node["name"].text();
unsigned size = node["size"].decimal(); unsigned size = node["size"].natural();
ram.map(allocate<uint8>(size, 0xff), size); ram.map(allocate<uint8>(size, 0xff), size);
if(name) { if(name) {
interface->loadRequest(id, name, !writable); //treat ROM as required; RAM as optional interface->loadRequest(id, name, !writable); //treat ROM as required; RAM as optional
@ -78,7 +78,7 @@ auto Cartridge::parseMarkupCartridge(Markup::Node root) -> void {
auto Cartridge::parseMarkupICD2(Markup::Node root) -> void { auto Cartridge::parseMarkupICD2(Markup::Node root) -> void {
hasSuperGameBoySlot = true; hasSuperGameBoySlot = true;
hasICD2 = true; hasICD2 = true;
icd2.revision = max(1, root["revision"].decimal()); icd2.revision = max(1, root["revision"].natural());
GameBoy::cartridge.load_empty(GameBoy::System::Revision::SuperGameBoy); GameBoy::cartridge.load_empty(GameBoy::System::Revision::SuperGameBoy);
interface->loadRequest(ID::SuperGameBoy, "Game Boy", "gb", false); interface->loadRequest(ID::SuperGameBoy, "Game Boy", "gb", false);
@ -188,7 +188,7 @@ auto Cartridge::parseMarkupEvent(Markup::Node root) -> void {
hasEvent = true; hasEvent = true;
for(auto node : root.find("rom")) { for(auto node : root.find("rom")) {
unsigned id = node["id"].decimal(); unsigned id = node["id"].natural();
if(id > 3) continue; if(id > 3) continue;
parseMarkupMemory(event.rom[id], node, ID::EventROM0 + id, false); parseMarkupMemory(event.rom[id], node, ID::EventROM0 + id, false);
} }
@ -200,8 +200,8 @@ auto Cartridge::parseMarkupEvent(Markup::Node root) -> void {
event.revision = root["revision"].text() == "B" ? 2 : 1; event.revision = root["revision"].text() == "B" ? 2 : 1;
lstring part = root["timer"].text().split(":", 1L); lstring part = root["timer"].text().split(":", 1L);
if(part.size() == 1) event.timer = decimal(part(0)); if(part.size() == 1) event.timer = part(0).natural();
if(part.size() == 2) event.timer = decimal(part(0)) * 60 + decimal(part(1)); if(part.size() == 2) event.timer = part(0).natural() * 60 + part(1).natural();
for(auto node : root.find("map")) { for(auto node : root.find("map")) {
if(node["id"].text() == "rom") { if(node["id"].text() == "rom") {
@ -338,7 +338,7 @@ auto Cartridge::parseMarkupHitachiDSP(Markup::Node root, unsigned roms) -> void
for(auto& word : hitachidsp.dataROM) word = 0x000000; for(auto& word : hitachidsp.dataROM) word = 0x000000;
for(auto& word : hitachidsp.dataRAM) word = 0x00; for(auto& word : hitachidsp.dataRAM) word = 0x00;
hitachidsp.Frequency = root["frequency"].decimal(); hitachidsp.Frequency = root["frequency"].natural();
if(hitachidsp.Frequency == 0) hitachidsp.frequency = 20000000; if(hitachidsp.Frequency == 0) hitachidsp.frequency = 20000000;
hitachidsp.Roms = roms; hitachidsp.Roms = roms;
@ -380,7 +380,7 @@ auto Cartridge::parseMarkupNECDSP(Markup::Node root) -> void {
for(auto& word : necdsp.dataROM) word = 0x0000; for(auto& word : necdsp.dataROM) word = 0x0000;
for(auto& word : necdsp.dataRAM) word = 0x0000; for(auto& word : necdsp.dataRAM) word = 0x0000;
necdsp.frequency = root["frequency"].decimal(); necdsp.frequency = root["frequency"].natural();
if(necdsp.frequency == 0) necdsp.frequency = 8000000; if(necdsp.frequency == 0) necdsp.frequency = 8000000;
necdsp.revision necdsp.revision
= root["model"].text() == "uPD7725" ? NECDSP::Revision::uPD7725 = root["model"].text() == "uPD7725" ? NECDSP::Revision::uPD7725
@ -417,7 +417,7 @@ auto Cartridge::parseMarkupNECDSP(Markup::Node root) -> void {
Mapping m({&NECDSP::read, &necdsp}, {&NECDSP::write, &necdsp}); Mapping m({&NECDSP::read, &necdsp}, {&NECDSP::write, &necdsp});
parseMarkupMap(m, node); parseMarkupMap(m, node);
mapping.append(m); mapping.append(m);
necdsp.Select = node["select"].decimal(); necdsp.Select = node["select"].natural();
} }
if(node["id"].text() == "ram") { if(node["id"].text() == "ram") {

View File

@ -6,9 +6,21 @@ namespace SuperFamicom {
#include "serialization.cpp" #include "serialization.cpp"
ArmDSP armdsp; ArmDSP armdsp;
void ArmDSP::Enter() { armdsp.enter(); } ArmDSP::ArmDSP() {
programROM = new uint8[128 * 1024];
dataROM = new uint8[32 * 1024];
programRAM = new uint8[16 * 1024];
}
void ArmDSP::enter() { ArmDSP::~ArmDSP() {
delete[] programROM;
delete[] dataROM;
delete[] programRAM;
}
auto ArmDSP::Enter() -> void { armdsp.enter(); }
auto ArmDSP::enter() -> void {
//reset hold delay //reset hold delay
while(bridge.reset) { while(bridge.reset) {
step(1); step(1);
@ -37,7 +49,7 @@ void ArmDSP::enter() {
} }
} }
void ArmDSP::step(unsigned clocks) { auto ArmDSP::step(uint clocks) -> void {
if(bridge.timer && --bridge.timer == 0); if(bridge.timer && --bridge.timer == 0);
Coprocessor::step(clocks); Coprocessor::step(clocks);
synchronize_cpu(); synchronize_cpu();
@ -47,7 +59,7 @@ void ArmDSP::step(unsigned clocks) {
//3800-3807 mirrored throughout //3800-3807 mirrored throughout
//a0 ignored //a0 ignored
uint8 ArmDSP::mmio_read(unsigned addr) { auto ArmDSP::mmio_read(uint addr) -> uint8 {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
uint8 data = 0x00; uint8 data = 0x00;
@ -71,7 +83,7 @@ uint8 ArmDSP::mmio_read(unsigned addr) {
return data; return data;
} }
void ArmDSP::mmio_write(unsigned addr, uint8 data) { auto ArmDSP::mmio_write(uint addr, uint8 data) -> void {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
addr &= 0xff06; addr &= 0xff06;
@ -83,30 +95,30 @@ void ArmDSP::mmio_write(unsigned addr, uint8 data) {
if(addr == 0x3804) { if(addr == 0x3804) {
data &= 1; data &= 1;
if(!bridge.reset && data) arm_reset(); if(!bridge.reset && data) resetARM();
bridge.reset = data; bridge.reset = data;
} }
} }
void ArmDSP::init() { auto ArmDSP::init() -> void {
} }
void ArmDSP::load() { auto ArmDSP::load() -> void {
} }
void ArmDSP::unload() { auto ArmDSP::unload() -> void {
} }
void ArmDSP::power() { auto ArmDSP::power() -> void {
for(unsigned n = 0; n < 16 * 1024; n++) programRAM[n] = random(0x00); for(auto n : range(16 * 1024)) programRAM[n] = random(0x00);
} }
void ArmDSP::reset() { auto ArmDSP::reset() -> void {
bridge.reset = false; bridge.reset = false;
arm_reset(); resetARM();
} }
void ArmDSP::arm_reset() { auto ArmDSP::resetARM() -> void {
create(ArmDSP::Enter, 21477272); create(ArmDSP::Enter, 21477272);
ARM::power(); ARM::power();
@ -118,16 +130,4 @@ void ArmDSP::arm_reset() {
bridge.armtocpu.ready = false; bridge.armtocpu.ready = false;
} }
ArmDSP::ArmDSP() {
programROM = new uint8[128 * 1024];
dataROM = new uint8[32 * 1024];
programRAM = new uint8[16 * 1024];
}
ArmDSP::~ArmDSP() {
delete[] programROM;
delete[] dataROM;
delete[] programRAM;
}
} }

View File

@ -1,35 +1,35 @@
//ARMv3 (ARM60) //ARMv3 (ARM60)
struct ArmDSP : Processor::ARM, Coprocessor { struct ArmDSP : Processor::ARM, Coprocessor {
uint8* programROM;
uint8* dataROM;
uint8* programRAM;
#include "registers.hpp" #include "registers.hpp"
static void Enter();
void enter();
void step(unsigned clocks) override;
void bus_idle() override;
uint32 bus_read(unsigned mode, uint32 addr) override;
void bus_write(unsigned mode, uint32 addr, uint32 word) override;
uint8 mmio_read(unsigned addr);
void mmio_write(unsigned addr, uint8 data);
void init();
void load();
void unload();
void power();
void reset();
void arm_reset();
nall::vector<uint8> firmware();
void serialize(serializer&);
ArmDSP(); ArmDSP();
~ArmDSP(); ~ArmDSP();
static auto Enter() -> void;
auto enter() -> void;
auto step(uint clocks) -> void override;
auto bus_idle() -> void override;
auto bus_read(uint mode, uint32 addr) -> uint32 override;
auto bus_write(uint mode, uint32 addr, uint32 word) -> void override;
auto mmio_read(uint addr) -> uint8;
auto mmio_write(uint addr, uint8 data) -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;
auto reset() -> void;
auto resetARM() -> void;
auto firmware() const -> nall::vector<uint8>;
auto serialize(serializer&) -> void;
uint8* programROM;
uint8* dataROM;
uint8* programRAM;
}; };
extern ArmDSP armdsp; extern ArmDSP armdsp;

View File

@ -1,14 +1,14 @@
//note: timings are completely unverified //note: timings are completely unverified
//due to the ST018 chip design (on-die ROM), testing is nearly impossible //due to the ST018 chip design (on-die ROM), testing is nearly impossible
void ArmDSP::bus_idle() { auto ArmDSP::bus_idle() -> void {
step(1); step(1);
} }
uint32 ArmDSP::bus_read(unsigned mode, uint32 addr) { auto ArmDSP::bus_read(unsigned mode, uint32 addr) -> uint32 {
step(1); step(1);
static auto memory = [&](const uint8 *memory, unsigned mode, uint32 addr) -> uint32 { static auto memory = [&](const uint8* memory, uint mode, uint32 addr) -> uint32 {
if(mode & Word) { if(mode & Word) {
memory += addr & ~3; memory += addr & ~3;
return memory[0] << 0 | memory[1] << 8 | memory[2] << 16 | memory[3] << 24; return memory[0] << 0 | memory[1] << 8 | memory[2] << 16 | memory[3] << 24;
@ -46,10 +46,10 @@ uint32 ArmDSP::bus_read(unsigned mode, uint32 addr) {
return 0; return 0;
} }
void ArmDSP::bus_write(unsigned mode, uint32 addr, uint32 word) { auto ArmDSP::bus_write(uint mode, uint32 addr, uint32 word) -> void {
step(1); step(1);
static auto memory = [](uint8 *memory, unsigned mode, uint32 addr, uint32 word) { static auto memory = [](uint8* memory, uint mode, uint32 addr, uint32 word) {
if(mode & Word) { if(mode & Word) {
memory += addr & ~3; memory += addr & ~3;
*memory++ = word >> 0; *memory++ = word >> 0;

View File

@ -11,7 +11,7 @@ struct Bridge {
bool ready; bool ready;
bool signal; bool signal;
uint8 status() const { auto status() const -> uint8 {
return (ready << 7) | (cputoarm.ready << 3) | (signal << 2) | (armtocpu.ready << 0); return (ready << 7) | (cputoarm.ready << 3) | (signal << 2) | (armtocpu.ready << 0);
} }
} bridge; } bridge;

View File

@ -1,13 +1,13 @@
nall::vector<uint8> ArmDSP::firmware() { auto ArmDSP::firmware() const -> nall::vector<uint8> {
nall::vector<uint8> buffer; nall::vector<uint8> buffer;
if(!cartridge.hasARMDSP()) return buffer; if(!cartridge.hasARMDSP()) return buffer;
buffer.reserve(128 * 1024 + 32 * 1024); buffer.reserve(128 * 1024 + 32 * 1024);
for(unsigned n = 0; n < 128 * 1024; n++) buffer.append(programROM[n]); for(auto n : range(128 * 1024)) buffer.append(programROM[n]);
for(unsigned n = 0; n < 32 * 1024; n++) buffer.append(dataROM[n]); for(auto n : range( 32 * 1024)) buffer.append(dataROM[n]);
return buffer; return buffer;
} }
void ArmDSP::serialize(serializer& s) { auto ArmDSP::serialize(serializer& s) -> void {
ARM::serialize(s); ARM::serialize(s);
Thread::serialize(s); Thread::serialize(s);

View File

@ -7,11 +7,11 @@ namespace SuperFamicom {
#include "serialization.cpp" #include "serialization.cpp"
EpsonRTC epsonrtc; EpsonRTC epsonrtc;
void EpsonRTC::Enter() { auto EpsonRTC::Enter() -> void {
epsonrtc.enter(); epsonrtc.enter();
} }
void EpsonRTC::enter() { auto EpsonRTC::enter() -> void {
while(true) { while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) { if(scheduler.sync == Scheduler::SynchronizeMode::All) {
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
@ -36,12 +36,10 @@ void EpsonRTC::enter() {
} }
} }
void EpsonRTC::init() { auto EpsonRTC::init() -> void {
} }
void EpsonRTC::load() { auto EpsonRTC::load() -> void {
return;
secondlo = 0; secondlo = 0;
secondhi = 0; secondhi = 0;
batteryfailure = 1; batteryfailure = 1;
@ -82,13 +80,13 @@ void EpsonRTC::load() {
test = 0; test = 0;
} }
void EpsonRTC::unload() { auto EpsonRTC::unload() -> void {
} }
void EpsonRTC::power() { auto EpsonRTC::power() -> void {
} }
void EpsonRTC::reset() { auto EpsonRTC::reset() -> void {
create(EpsonRTC::Enter, 32768 * 64); create(EpsonRTC::Enter, 32768 * 64);
clocks = 0; clocks = 0;
@ -102,19 +100,19 @@ void EpsonRTC::reset() {
holdtick = 0; holdtick = 0;
} }
void EpsonRTC::sync() { auto EpsonRTC::sync() -> void {
time_t systime = time(0); time_t systime = time(0);
tm* timeinfo = localtime(&systime); tm* timeinfo = localtime(&systime);
unsigned second = min(59, timeinfo->tm_sec); uint second = min(59, timeinfo->tm_sec);
secondlo = second % 10; secondlo = second % 10;
secondhi = second / 10; secondhi = second / 10;
unsigned minute = timeinfo->tm_min; uint minute = timeinfo->tm_min;
minutelo = minute % 10; minutelo = minute % 10;
minutehi = minute / 10; minutehi = minute / 10;
unsigned hour = timeinfo->tm_hour; uint hour = timeinfo->tm_hour;
if(atime) { if(atime) {
hourlo = hour % 10; hourlo = hour % 10;
hourhi = hour / 10; hourhi = hour / 10;
@ -126,15 +124,15 @@ void EpsonRTC::sync() {
hourhi = hour / 10; hourhi = hour / 10;
} }
unsigned day = timeinfo->tm_mday; uint day = timeinfo->tm_mday;
daylo = day % 10; daylo = day % 10;
dayhi = day / 10; dayhi = day / 10;
unsigned month = 1 + timeinfo->tm_mon; uint month = 1 + timeinfo->tm_mon;
monthlo = month % 10; monthlo = month % 10;
monthhi = month / 10; monthhi = month / 10;
unsigned year = timeinfo->tm_year % 100; uint year = timeinfo->tm_year % 100;
yearlo = year % 10; yearlo = year % 10;
yearhi = year / 10; yearhi = year / 10;
@ -143,7 +141,7 @@ void EpsonRTC::sync() {
resync = true; //alert program that time has changed resync = true; //alert program that time has changed
} }
uint8 EpsonRTC::read(unsigned addr) { auto EpsonRTC::read(uint addr) -> uint8 {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
addr &= 3; addr &= 3;
@ -166,7 +164,7 @@ uint8 EpsonRTC::read(unsigned addr) {
} }
} }
void EpsonRTC::write(unsigned addr, uint8 data) { auto EpsonRTC::write(uint addr, uint8 data) -> void {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
addr &= 3, data &= 15; addr &= 3, data &= 15;

View File

@ -1,29 +1,29 @@
//Epson RTC-4513 Real-Time Clock //Epson RTC-4513 Real-Time Clock
struct EpsonRTC : Coprocessor { struct EpsonRTC : Coprocessor {
static void Enter(); static auto Enter() -> void;
void enter(); auto enter() -> void;
void init(); auto init() -> void;
void load(); auto load() -> void;
void unload(); auto unload() -> void;
void power(); auto power() -> void;
void reset(); auto reset() -> void;
void sync(); auto sync() -> void;
uint8 read(unsigned addr); auto read(uint addr) -> uint8;
void write(unsigned addr, uint8 data); auto write(uint addr, uint8 data) -> void;
void serialize(serializer&); auto serialize(serializer&) -> void;
uint21 clocks; uint21 clocks;
unsigned seconds; uint seconds;
uint2 chipselect; uint2 chipselect;
enum class State : unsigned { Mode, Seek, Read, Write } state; enum class State : uint { Mode, Seek, Read, Write } state;
uint4 mdr; uint4 mdr;
uint4 offset; uint4 offset;
unsigned wait; uint wait;
uint1 ready; uint1 ready;
uint1 holdtick; uint1 holdtick;
@ -67,25 +67,25 @@ struct EpsonRTC : Coprocessor {
uint1 test; uint1 test;
//memory.cpp //memory.cpp
void rtc_reset(); auto rtc_reset() -> void;
uint4 rtc_read(uint4 addr); auto rtc_read(uint4 addr) -> uint4;
void rtc_write(uint4 addr, uint4 data); auto rtc_write(uint4 addr, uint4 data) -> void;
void load(const uint8* data); auto load(const uint8* data) -> void;
void save(uint8* data); auto save(uint8* data) -> void;
//time.cpp //time.cpp
void irq(uint2 period); auto irq(uint2 period) -> void;
void duty(); auto duty() -> void;
void round_seconds(); auto round_seconds() -> void;
void tick(); auto tick() -> void;
void tick_second(); auto tick_second() -> void;
void tick_minute(); auto tick_minute() -> void;
void tick_hour(); auto tick_hour() -> void;
void tick_day(); auto tick_day() -> void;
void tick_month(); auto tick_month() -> void;
void tick_year(); auto tick_year() -> void;
}; };
extern EpsonRTC epsonrtc; extern EpsonRTC epsonrtc;

View File

@ -1,4 +1,4 @@
void EpsonRTC::rtc_reset() { auto EpsonRTC::rtc_reset() -> void {
state = State::Mode; state = State::Mode;
offset = 0; offset = 0;
@ -7,7 +7,7 @@ void EpsonRTC::rtc_reset() {
test = 0; test = 0;
} }
uint4 EpsonRTC::rtc_read(uint4 addr) { auto EpsonRTC::rtc_read(uint4 addr) -> uint4 {
switch(addr) { default: switch(addr) { default:
case 0: return secondlo; case 0: return secondlo;
case 1: return secondhi | batteryfailure << 3; case 1: return secondhi | batteryfailure << 3;
@ -32,7 +32,7 @@ uint4 EpsonRTC::rtc_read(uint4 addr) {
} }
} }
void EpsonRTC::rtc_write(uint4 addr, uint4 data) { auto EpsonRTC::rtc_write(uint4 addr, uint4 data) -> void {
switch(addr) { switch(addr) {
case 0: case 0:
secondlo = data; secondlo = data;
@ -110,7 +110,7 @@ void EpsonRTC::rtc_write(uint4 addr, uint4 data) {
} }
} }
void EpsonRTC::load(const uint8* data) { auto EpsonRTC::load(const uint8* data) -> void {
secondlo = data[0] >> 0; secondlo = data[0] >> 0;
secondhi = data[0] >> 4; secondhi = data[0] >> 4;
batteryfailure = data[0] >> 7; batteryfailure = data[0] >> 7;
@ -151,7 +151,7 @@ void EpsonRTC::load(const uint8* data) {
test = data[7] >> 7; test = data[7] >> 7;
uint64 timestamp = 0; uint64 timestamp = 0;
for(unsigned byte = 0; byte < 8; byte++) { for(auto byte : range(8)) {
timestamp |= data[8 + byte] << (byte * 8); timestamp |= data[8 + byte] << (byte * 8);
} }
@ -162,7 +162,7 @@ void EpsonRTC::load(const uint8* data) {
while(diff--) tick_second(); while(diff--) tick_second();
} }
void EpsonRTC::save(uint8* data) { auto EpsonRTC::save(uint8* data) -> void {
data[0] = secondlo << 0 | secondhi << 4 | batteryfailure << 7; data[0] = secondlo << 0 | secondhi << 4 | batteryfailure << 7;
data[1] = minutelo << 0 | minutehi << 4 | resync << 7; data[1] = minutelo << 0 | minutehi << 4 | resync << 7;
data[2] = hourlo << 0 | hourhi << 4 | meridian << 6 | resync << 7; data[2] = hourlo << 0 | hourhi << 4 | meridian << 6 | resync << 7;
@ -173,7 +173,7 @@ void EpsonRTC::save(uint8* data) {
data[7] = irqmask << 0 | irqduty << 1 | irqperiod << 2 | pause << 4 | stop << 5 | atime << 6 | test << 7; data[7] = irqmask << 0 | irqduty << 1 | irqperiod << 2 | pause << 4 | stop << 5 | atime << 6 | test << 7;
uint64 timestamp = (uint64)time(0); uint64 timestamp = (uint64)time(0);
for(unsigned byte = 0; byte < 8; byte++) { for(auto byte : range(8)) {
data[8 + byte] = timestamp; data[8 + byte] = timestamp;
timestamp >>= 8; timestamp >>= 8;
} }

View File

@ -1,11 +1,11 @@
void EpsonRTC::serialize(serializer& s) { auto EpsonRTC::serialize(serializer& s) -> void {
Thread::serialize(s); Thread::serialize(s);
s.integer(clocks); s.integer(clocks);
s.integer(seconds); s.integer(seconds);
s.integer(chipselect); s.integer(chipselect);
s.integer((unsigned&)state); s.integer((uint&)state);
s.integer(mdr); s.integer(mdr);
s.integer(offset); s.integer(offset);
s.integer(wait); s.integer(wait);

View File

@ -1,14 +1,14 @@
void EpsonRTC::irq(uint2 period) { auto EpsonRTC::irq(uint2 period) -> void {
if(stop || pause) return; if(stop || pause) return;
if(period == irqperiod) irqflag = 1; if(period == irqperiod) irqflag = 1;
} }
void EpsonRTC::duty() { auto EpsonRTC::duty() -> void {
if(irqduty) irqflag = 0; if(irqduty) irqflag = 0;
} }
void EpsonRTC::round_seconds() { auto EpsonRTC::round_seconds() -> void {
if(roundseconds == 0) return; if(roundseconds == 0) return;
roundseconds = 0; roundseconds = 0;
@ -17,7 +17,7 @@ void EpsonRTC::round_seconds() {
secondhi = 0; secondhi = 0;
} }
void EpsonRTC::tick() { auto EpsonRTC::tick() -> void {
if(stop || pause) return; if(stop || pause) return;
if(hold) { if(hold) {
@ -32,7 +32,7 @@ void EpsonRTC::tick() {
//below code provides bit-perfect emulation of invalid BCD values on the RTC-4513 //below code provides bit-perfect emulation of invalid BCD values on the RTC-4513
//code makes extensive use of variable-length integers (see epsonrtc.hpp for sizes) //code makes extensive use of variable-length integers (see epsonrtc.hpp for sizes)
void EpsonRTC::tick_second() { auto EpsonRTC::tick_second() -> void {
if(secondlo <= 8 || secondlo == 12) { if(secondlo <= 8 || secondlo == 12) {
secondlo++; secondlo++;
} else { } else {
@ -46,7 +46,7 @@ void EpsonRTC::tick_second() {
} }
} }
void EpsonRTC::tick_minute() { auto EpsonRTC::tick_minute() -> void {
if(minutelo <= 8 || minutelo == 12) { if(minutelo <= 8 || minutelo == 12) {
minutelo++; minutelo++;
} else { } else {
@ -60,7 +60,7 @@ void EpsonRTC::tick_minute() {
} }
} }
void EpsonRTC::tick_hour() { auto EpsonRTC::tick_hour() -> void {
if(atime) { if(atime) {
if(hourhi < 2) { if(hourhi < 2) {
if(hourlo <= 8 || hourlo == 12) { if(hourlo <= 8 || hourlo == 12) {
@ -104,17 +104,17 @@ void EpsonRTC::tick_hour() {
} }
} }
void EpsonRTC::tick_day() { auto EpsonRTC::tick_day() -> void {
if(calendar == 0) return; if(calendar == 0) return;
weekday = (weekday + 1) + (weekday == 6); weekday = (weekday + 1) + (weekday == 6);
//January - December = 0x01 - 0x09; 0x10 - 0x12 //January - December = 0x01 - 0x09; 0x10 - 0x12
static const unsigned daysinmonth[32] = { static const uint daysinmonth[32] = {
30, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 30, 31, 30, 30, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31, 30, 31, 30,
31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30, 31, 30,
}; };
unsigned days = daysinmonth[monthhi << 4 | monthlo]; uint days = daysinmonth[monthhi << 4 | monthlo];
if(days == 28) { if(days == 28) {
//add one day for leap years //add one day for leap years
if((yearhi & 1) == 0 && ((yearlo - 0) & 3) == 0) days++; if((yearhi & 1) == 0 && ((yearlo - 0) & 3) == 0) days++;
@ -153,7 +153,7 @@ void EpsonRTC::tick_day() {
} }
} }
void EpsonRTC::tick_month() { auto EpsonRTC::tick_month() -> void {
if(monthhi == 0 || !(monthlo & 2)) { if(monthhi == 0 || !(monthlo & 2)) {
if(monthlo <= 8 || monthlo == 12) { if(monthlo <= 8 || monthlo == 12) {
monthlo++; monthlo++;
@ -168,7 +168,7 @@ void EpsonRTC::tick_month() {
} }
} }
void EpsonRTC::tick_year() { auto EpsonRTC::tick_year() -> void {
if(yearlo <= 8 || yearlo == 12) { if(yearlo <= 8 || yearlo == 12) {
yearlo++; yearlo++;
} else { } else {

View File

@ -4,9 +4,9 @@ namespace SuperFamicom {
Event event; Event event;
void Event::Enter() { event.enter(); } auto Event::Enter() -> void { event.enter(); }
void Event::enter() { auto Event::enter() -> void {
while(true) { while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) { if(scheduler.sync == Scheduler::SynchronizeMode::All) {
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
@ -15,7 +15,6 @@ void Event::enter() {
if(scoreActive && scoreSecondsRemaining) { if(scoreActive && scoreSecondsRemaining) {
if(--scoreSecondsRemaining == 0) { if(--scoreSecondsRemaining == 0) {
scoreActive = false; scoreActive = false;
submitScore();
} }
} }
@ -33,40 +32,13 @@ void Event::enter() {
} }
} }
void Event::submitScore() { auto Event::init() -> void {
if(usedSaveState) return;
string data;
data.append("timer:", timer, "\n");
if(board == Board::CampusChallenge92) {
unsigned mw = 0, fz = 0, pw = 0;
for(unsigned n = 0x0408; n <= 0x040e; n++) mw = mw * 10 + ram.read(n);
for(unsigned n = 0x0413; n >= 0x0410; n--) fz = fz * 10 + ram.read(n);
for(unsigned n = 0x0418; n >= 0x0415; n--) pw = pw * 10 + ram.read(n);
data.append("mw:", mw, "\n");
data.append("fz:", fz, "\n");
data.append("pw:", pw, "\n");
}
if(board == Board::Powerfest94) {
unsigned ml = 0, mk[2] = {0}, ba[2] = {0};
for(unsigned n = 0x0408; n <= 0x040e; n++) ml = ml * 10 + ram.read(n);
for(unsigned n = 0x0413; n >= 0x0412; n--) mk[0] = mk[0] * 10 + ram.read(n);
for(unsigned n = 0x0411; n >= 0x0410; n--) mk[1] = mk[1] * 10 + ram.read(n);
for(unsigned n = 0x0418; n >= 0x0415; n--) ba[0] = ba[0] * 10 + ram.read(n);
for(unsigned n = 0x041a; n >= 0x0419; n--) ba[1] = ba[1] * 10 + ram.read(n);
data.append("ml:", ml, "\n");
data.append("mk:", mk[0], ",", mk[1], "\n");
data.append("ba:", ba[0], ",", ba[1], "\n");
}
} }
void Event::init() { auto Event::load() -> void {
} }
void Event::load() { auto Event::unload() -> void {
}
void Event::unload() {
rom[0].reset(); rom[0].reset();
rom[1].reset(); rom[1].reset();
rom[2].reset(); rom[2].reset();
@ -74,27 +46,25 @@ void Event::unload() {
ram.reset(); ram.reset();
} }
void Event::power() { auto Event::power() -> void {
usedSaveState = false;
} }
void Event::reset() { auto Event::reset() -> void {
create(Event::Enter, 1); create(Event::Enter, 1);
for(unsigned n = 0; n < ram.size(); n++) ram.write(n, 0x00); for(auto n : range(ram.size())) ram.write(n, 0x00);
status = 0x00; status = 0x00;
select = 0x00; select = 0x00;
timerActive = false; timerActive = false;
scoreActive = false; scoreActive = false;
timerSecondsRemaining = 0; timerSecondsRemaining = 0;
scoreSecondsRemaining = 0; scoreSecondsRemaining = 0;
usedSaveState = false;
} }
uint8 Event::sr(unsigned) { auto Event::sr(uint) -> uint8 {
return status; return status;
} }
void Event::dr(unsigned, uint8 data) { auto Event::dr(uint, uint8 data) -> void {
select = data; select = data;
if(timer && data == 0x09) { if(timer && data == 0x09) {
timerActive = true; timerActive = true;
@ -102,9 +72,9 @@ void Event::dr(unsigned, uint8 data) {
} }
} }
uint8 Event::rom_read(unsigned addr) { auto Event::rom_read(uint addr) -> uint8 {
if(board == Board::CampusChallenge92) { if(board == Board::CampusChallenge92) {
unsigned id = 0; uint id = 0;
if(select == 0x09) id = 1; if(select == 0x09) id = 1;
if(select == 0x05) id = 2; if(select == 0x05) id = 2;
if(select == 0x03) id = 3; if(select == 0x03) id = 3;
@ -117,7 +87,7 @@ uint8 Event::rom_read(unsigned addr) {
} }
if(board == Board::Powerfest94) { if(board == Board::Powerfest94) {
unsigned id = 0; uint id = 0;
if(select == 0x09) id = 1; if(select == 0x09) id = 1;
if(select == 0x0c) id = 2; if(select == 0x0c) id = 2;
if(select == 0x0a) id = 3; if(select == 0x0a) id = 3;
@ -138,15 +108,15 @@ uint8 Event::rom_read(unsigned addr) {
return cpu.regs.mdr; return cpu.regs.mdr;
} }
uint8 Event::ram_read(unsigned addr) { auto Event::ram_read(uint addr) -> uint8 {
return ram.read(bus.mirror(addr, ram.size())); return ram.read(bus.mirror(addr, ram.size()));
} }
void Event::ram_write(unsigned addr, uint8 data) { auto Event::ram_write(uint addr, uint8 data) -> void {
return ram.write(bus.mirror(addr, ram.size()), data); return ram.write(bus.mirror(addr, ram.size()), data);
} }
void Event::serialize(serializer& s) { auto Event::serialize(serializer& s) -> void {
Thread::serialize(s); Thread::serialize(s);
s.array(ram.data(), ram.size()); s.array(ram.data(), ram.size());
s.integer(status); s.integer(status);
@ -155,8 +125,6 @@ void Event::serialize(serializer& s) {
s.integer(scoreActive); s.integer(scoreActive);
s.integer(timerSecondsRemaining); s.integer(timerSecondsRemaining);
s.integer(scoreSecondsRemaining); s.integer(scoreSecondsRemaining);
usedSaveState = true;
} }
} }

View File

@ -3,42 +3,40 @@
//* Powerfest '94 //* Powerfest '94
struct Event : Coprocessor { struct Event : Coprocessor {
static auto Enter() -> void;
auto enter() -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;
auto reset() -> void;
auto submitScore() -> void;
auto sr(uint) -> uint8;
auto dr(uint, uint8 data) -> void;
auto rom_read(uint addr) -> uint8;
auto ram_read(uint addr) -> uint8;
auto ram_write(uint addr, uint8 data) -> void;
auto serialize(serializer&) -> void;
MappedRAM rom[4]; MappedRAM rom[4];
MappedRAM ram; MappedRAM ram;
static void Enter(); enum class Board : uint { CampusChallenge92, Powerfest94 } board;
void enter(); uint revision;
void init(); uint timer;
void load();
void unload();
void power();
void reset();
void submitScore();
uint8 sr(unsigned);
void dr(unsigned, uint8 data);
uint8 rom_read(unsigned addr);
uint8 ram_read(unsigned addr);
void ram_write(unsigned addr, uint8 data);
void serialize(serializer&);
//private:
enum class Board : unsigned { CampusChallenge92, Powerfest94 } board;
unsigned revision;
unsigned timer;
privileged:
uint8 status; uint8 status;
uint8 select; uint8 select;
bool timerActive; bool timerActive;
bool scoreActive; bool scoreActive;
unsigned timerSecondsRemaining; uint timerSecondsRemaining;
unsigned scoreSecondsRemaining; uint scoreSecondsRemaining;
bool usedSaveState;
}; };
extern Event event; extern Event event;

View File

@ -6,16 +6,16 @@ namespace SuperFamicom {
#include "serialization.cpp" #include "serialization.cpp"
HitachiDSP hitachidsp; HitachiDSP hitachidsp;
void HitachiDSP::Enter() { hitachidsp.enter(); } auto HitachiDSP::Enter() -> void { hitachidsp.enter(); }
void HitachiDSP::enter() { auto HitachiDSP::enter() -> void {
while(true) { while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) { if(scheduler.sync == Scheduler::SynchronizeMode::All) {
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
} }
if(mmio.dma) { if(mmio.dma) {
for(unsigned n = 0; n < mmio.dma_length; n++) { for(auto n : range(mmio.dma_length)) {
bus.write(mmio.dma_target + n, bus.read(mmio.dma_source + n)); bus.write(mmio.dma_target + n, bus.read(mmio.dma_source + n));
step(2); step(2);
} }
@ -29,18 +29,18 @@ void HitachiDSP::enter() {
} }
} }
void HitachiDSP::init() { auto HitachiDSP::init() -> void {
} }
void HitachiDSP::load() { auto HitachiDSP::load() -> void {
} }
void HitachiDSP::unload() { auto HitachiDSP::unload() -> void {
rom.reset(); rom.reset();
ram.reset(); ram.reset();
} }
void HitachiDSP::power() { auto HitachiDSP::power() -> void {
mmio.dma = false; mmio.dma = false;
mmio.dma_source = 0x000000; mmio.dma_source = 0x000000;
@ -56,7 +56,7 @@ void HitachiDSP::power() {
mmio.r1f52 = 0x01; mmio.r1f52 = 0x01;
} }
void HitachiDSP::reset() { auto HitachiDSP::reset() -> void {
create(HitachiDSP::Enter, Frequency); create(HitachiDSP::Enter, Frequency);
HG51B::power(); HG51B::power();
} }

View File

@ -1,39 +1,39 @@
struct HitachiDSP : Processor::HG51B, Coprocessor { struct HitachiDSP : Processor::HG51B, Coprocessor {
unsigned Frequency;
unsigned Roms;
MappedRAM rom; MappedRAM rom;
MappedRAM ram; MappedRAM ram;
#include "mmio.hpp" #include "mmio.hpp"
static void Enter(); static auto Enter() -> void;
void enter(); auto enter() -> void;
void init(); auto init() -> void;
void load(); auto load() -> void;
void unload(); auto unload() -> void;
void power(); auto power() -> void;
void reset(); auto reset() -> void;
//HG51B read/write //HG51B read/write
uint8 bus_read(uint24 addr); auto bus_read(uint24 addr) -> uint8;
void bus_write(uint24 addr, uint8 data); auto bus_write(uint24 addr, uint8 data) -> void;
//CPU ROM read/write //CPU ROM read/write
uint8 rom_read(unsigned addr); auto rom_read(uint addr) -> uint8;
void rom_write(unsigned addr, uint8 data); auto rom_write(uint addr, uint8 data) -> void;
//CPU RAM read/write //CPU RAM read/write
uint8 ram_read(unsigned addr); auto ram_read(uint addr) -> uint8;
void ram_write(unsigned addr, uint8 data); auto ram_write(uint addr, uint8 data) -> void;
//CPU MMIO read/write //CPU MMIO read/write
uint8 dsp_read(unsigned addr); auto dsp_read(uint addr) -> uint8;
void dsp_write(unsigned addr, uint8 data); auto dsp_write(uint addr, uint8 data) -> void;
vector<uint8> firmware(); auto firmware() const -> vector<uint8>;
void serialize(serializer&); auto serialize(serializer&) -> void;
uint Frequency;
uint Roms;
}; };
extern HitachiDSP hitachidsp; extern HitachiDSP hitachidsp;

View File

@ -1,15 +1,15 @@
uint8 HitachiDSP::bus_read(uint24 addr) { auto HitachiDSP::bus_read(uint24 addr) -> uint8 {
if((addr & 0x408000) == 0x008000) return bus.read(addr); //$00-3f,80-bf:6000-7fff if((addr & 0x408000) == 0x008000) return bus.read(addr); //$00-3f,80-bf:6000-7fff
if((addr & 0xf88000) == 0x700000) return bus.read(addr); //$70-77:0000-7fff if((addr & 0xf88000) == 0x700000) return bus.read(addr); //$70-77:0000-7fff
return 0x00; return 0x00;
} }
void HitachiDSP::bus_write(uint24 addr, uint8 data) { auto HitachiDSP::bus_write(uint24 addr, uint8 data) -> void {
if((addr & 0x40e000) == 0x006000) return bus.write(addr, data); //$00-3f,80-bf:6000-7fff if((addr & 0x40e000) == 0x006000) return bus.write(addr, data); //$00-3f,80-bf:6000-7fff
if((addr & 0xf88000) == 0x700000) return bus.write(addr, data); //$70-77:0000-7fff if((addr & 0xf88000) == 0x700000) return bus.write(addr, data); //$70-77:0000-7fff
} }
uint8 HitachiDSP::rom_read(unsigned addr) { auto HitachiDSP::rom_read(uint addr) -> uint8 {
if(co_active() == hitachidsp.thread || regs.halt) { if(co_active() == hitachidsp.thread || regs.halt) {
addr = bus.mirror(addr, rom.size()); addr = bus.mirror(addr, rom.size());
//if(Roms == 2 && mmio.r1f52 == 1 && addr >= (bit::round(rom.size()) >> 1)) return 0x00; //if(Roms == 2 && mmio.r1f52 == 1 && addr >= (bit::round(rom.size()) >> 1)) return 0x00;
@ -19,20 +19,20 @@ uint8 HitachiDSP::rom_read(unsigned addr) {
return cpu.regs.mdr; return cpu.regs.mdr;
} }
void HitachiDSP::rom_write(unsigned addr, uint8 data) { auto HitachiDSP::rom_write(uint addr, uint8 data) -> void {
} }
uint8 HitachiDSP::ram_read(unsigned addr) { auto HitachiDSP::ram_read(uint addr) -> uint8 {
if(ram.size() == 0) return 0x00; //not open bus if(ram.size() == 0) return 0x00; //not open bus
return ram.read(bus.mirror(addr, ram.size())); return ram.read(bus.mirror(addr, ram.size()));
} }
void HitachiDSP::ram_write(unsigned addr, uint8 data) { auto HitachiDSP::ram_write(uint addr, uint8 data) -> void {
if(ram.size() == 0) return; if(ram.size() == 0) return;
return ram.write(bus.mirror(addr, ram.size()), data); return ram.write(bus.mirror(addr, ram.size()), data);
} }
uint8 HitachiDSP::dsp_read(unsigned addr) { auto HitachiDSP::dsp_read(uint addr) -> uint8 {
addr &= 0x1fff; addr &= 0x1fff;
//Data RAM //Data RAM
@ -74,15 +74,15 @@ uint8 HitachiDSP::dsp_read(unsigned addr) {
//GPRs //GPRs
if((addr >= 0x1f80 && addr <= 0x1faf) || (addr >= 0x1fc0 && addr <= 0x1fef)) { if((addr >= 0x1f80 && addr <= 0x1faf) || (addr >= 0x1fc0 && addr <= 0x1fef)) {
unsigned index = (addr & 0x3f) / 3; //0..15 uint index = (addr & 0x3f) / 3; //0..15
unsigned shift = ((addr & 0x3f) % 3) * 8; //0, 8, 16 uint shift = ((addr & 0x3f) % 3) * 8; //0, 8, 16
return regs.gpr[index] >> shift; return regs.gpr[index] >> shift;
} }
return 0x00; return 0x00;
} }
void HitachiDSP::dsp_write(unsigned addr, uint8 data) { auto HitachiDSP::dsp_write(uint addr, uint8 data) -> void {
addr &= 0x1fff; addr &= 0x1fff;
//Data RAM //Data RAM
@ -129,7 +129,7 @@ void HitachiDSP::dsp_write(unsigned addr, uint8 data) {
//GPRs //GPRs
if((addr >= 0x1f80 && addr <= 0x1faf) || (addr >= 0x1fc0 && addr <= 0x1fef)) { if((addr >= 0x1f80 && addr <= 0x1faf) || (addr >= 0x1fc0 && addr <= 0x1fef)) {
unsigned index = (addr & 0x3f) / 3; uint index = (addr & 0x3f) / 3;
switch((addr & 0x3f) % 3) { switch((addr & 0x3f) % 3) {
case 0: regs.gpr[index] = (regs.gpr[index] & 0xffff00) | (data << 0); return; case 0: regs.gpr[index] = (regs.gpr[index] & 0xffff00) | (data << 0); return;
case 1: regs.gpr[index] = (regs.gpr[index] & 0xff00ff) | (data << 8); return; case 1: regs.gpr[index] = (regs.gpr[index] & 0xff00ff) | (data << 8); return;

View File

@ -1,8 +1,8 @@
vector<uint8> HitachiDSP::firmware() { auto HitachiDSP::firmware() const -> vector<uint8> {
vector<uint8> buffer; vector<uint8> buffer;
if(!cartridge.hasHitachiDSP()) return buffer; if(!cartridge.hasHitachiDSP()) return buffer;
buffer.reserve(1024 * 3); buffer.reserve(1024 * 3);
for(unsigned n = 0; n < 1024; n++) { for(auto n : range(1024)) {
buffer.append(dataROM[n] >> 0); buffer.append(dataROM[n] >> 0);
buffer.append(dataROM[n] >> 8); buffer.append(dataROM[n] >> 8);
buffer.append(dataROM[n] >> 16); buffer.append(dataROM[n] >> 16);
@ -10,7 +10,7 @@ vector<uint8> HitachiDSP::firmware() {
return buffer; return buffer;
} }
void HitachiDSP::serialize(serializer& s) { auto HitachiDSP::serialize(serializer& s) -> void {
HG51B::serialize(s); HG51B::serialize(s);
Thread::serialize(s); Thread::serialize(s);

View File

@ -7,9 +7,9 @@ namespace SuperFamicom {
#include "serialization.cpp" #include "serialization.cpp"
ICD2 icd2; ICD2 icd2;
void ICD2::Enter() { icd2.enter(); } auto ICD2::Enter() -> void { icd2.enter(); }
void ICD2::enter() { auto ICD2::enter() -> void {
while(true) { while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) { if(scheduler.sync == Scheduler::SynchronizeMode::All) {
GameBoy::system.runtosave(); GameBoy::system.runtosave();
@ -28,27 +28,27 @@ void ICD2::enter() {
} }
} }
void ICD2::init() { auto ICD2::init() -> void {
} }
void ICD2::load() { auto ICD2::load() -> void {
bind = GameBoy::interface->bind; bind = GameBoy::interface->bind;
hook = GameBoy::interface->hook; hook = GameBoy::interface->hook;
GameBoy::interface->bind = this; GameBoy::interface->bind = this;
GameBoy::interface->hook = this; GameBoy::interface->hook = this;
} }
void ICD2::unload() { auto ICD2::unload() -> void {
GameBoy::interface->bind = bind; GameBoy::interface->bind = bind;
GameBoy::interface->hook = hook; GameBoy::interface->hook = hook;
} }
void ICD2::power() { auto ICD2::power() -> void {
audio.coprocessor_enable(true); audio.coprocessor_enable(true);
audio.coprocessor_frequency(2 * 1024 * 1024); audio.coprocessor_frequency(2 * 1024 * 1024);
} }
void ICD2::reset() { auto ICD2::reset() -> void {
create(ICD2::Enter, cpu.frequency / 5); create(ICD2::Enter, cpu.frequency / 5);
r6003 = 0x00; r6003 = 0x00;

View File

@ -1,19 +1,19 @@
struct ICD2 : Emulator::Interface::Bind, GameBoy::Interface::Hook, Coprocessor { struct ICD2 : Emulator::Interface::Bind, GameBoy::Interface::Hook, Coprocessor {
unsigned revision; static auto Enter() -> void;
auto enter() -> void;
static void Enter(); auto init() -> void;
void enter(); auto load() -> void;
auto unload() -> void;
auto power() -> void;
auto reset() -> void;
void init(); auto read(uint addr) -> uint8;
void load(); auto write(uint addr, uint8 data) -> void;
void unload();
void power();
void reset();
uint8 read(unsigned addr); auto serialize(serializer&) -> void;
void write(unsigned addr, uint8 data);
void serialize(serializer&); uint revision;
private: private:
Emulator::Interface::Bind* bind = nullptr; Emulator::Interface::Bind* bind = nullptr;

View File

@ -1,4 +1,4 @@
void ICD2::lcdScanline() { auto ICD2::lcdScanline() -> void {
if(GameBoy::ppu.status.ly > 143) return; //Vblank if(GameBoy::ppu.status.ly > 143) return; //Vblank
if((GameBoy::ppu.status.ly & 7) == 0) { if((GameBoy::ppu.status.ly & 7) == 0) {
write_bank = (write_bank + 1) & 3; write_bank = (write_bank + 1) & 3;
@ -6,16 +6,16 @@ void ICD2::lcdScanline() {
} }
} }
void ICD2::lcdOutput(uint2 color) { auto ICD2::lcdOutput(uint2 color) -> void {
unsigned y = write_addr / 160; uint y = write_addr / 160;
unsigned x = write_addr % 160; uint x = write_addr % 160;
unsigned addr = write_bank * 512 + y * 2 + x / 8 * 16; uint addr = write_bank * 512 + y * 2 + x / 8 * 16;
output[addr + 0] = (output[addr + 0] << 1) | (bool)(color & 1); output[addr + 0] = (output[addr + 0] << 1) | (bool)(color & 1);
output[addr + 1] = (output[addr + 1] << 1) | (bool)(color & 2); output[addr + 1] = (output[addr + 1] << 1) | (bool)(color & 2);
write_addr = (write_addr + 1) % 1280; write_addr = (write_addr + 1) % 1280;
} }
void ICD2::joypWrite(bool p15, bool p14) { auto ICD2::joypWrite(bool p15, bool p14) -> void {
//joypad handling //joypad handling
if(p15 == 1 && p14 == 1) { if(p15 == 1 && p14 == 1) {
if(joyp15lock == 0 && joyp14lock == 0) { if(joyp15lock == 0 && joyp14lock == 0) {
@ -85,21 +85,21 @@ void ICD2::joypWrite(bool p15, bool p14) {
packetlock = true; packetlock = true;
} }
uint32_t ICD2::videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue) { auto ICD2::videoColor(uint source, uint16 red, uint16 green, uint16 blue) -> uint32 {
return source; return source;
} }
void ICD2::videoRefresh(const uint32_t* data, unsigned pitch, unsigned width, unsigned height) { auto ICD2::videoRefresh(const uint32* data, uint pitch, uint width, uint height) -> void {
} }
void ICD2::audioSample(int16_t left, int16_t right) { auto ICD2::audioSample(int16 left, int16 right) -> void {
audio.coprocessor_sample(left, right); audio.coprocessor_sample(left, right);
} }
int16_t ICD2::inputPoll(unsigned port, unsigned device, unsigned id) { auto ICD2::inputPoll(uint port, uint device, uint id) -> int16 {
GameBoy::cpu.status.mlt_req = joyp_id & mlt_req; GameBoy::cpu.status.mlt_req = joyp_id & mlt_req;
unsigned data = 0x00; uint data = 0x00;
switch(joyp_id & mlt_req) { switch(joyp_id & mlt_req) {
case 0: data = ~r6004; break; case 0: data = ~r6004; break;
case 1: data = ~r6005; break; case 1: data = ~r6005; break;

View File

@ -1,20 +1,20 @@
void lcdScanline(); auto lcdScanline() -> void;
void lcdOutput(uint2 color); auto lcdOutput(uint2 color) -> void;
void joypWrite(bool p15, bool p14); auto joypWrite(bool p15, bool p14) -> void;
uint32_t videoColor(unsigned source, uint16_t red, uint16_t green, uint16_t blue); auto videoColor(uint source, uint16 red, uint16 green, uint16 blue) -> uint32;
void videoRefresh(const uint32_t* data, unsigned pitch, unsigned width, unsigned height); auto videoRefresh(const uint32* data, uint pitch, uint width, uint height) -> void;
void audioSample(int16_t lsample, int16_t rsample); auto audioSample(int16 lsample, int16 rsample) -> void;
int16_t inputPoll(unsigned port, unsigned device, unsigned id); auto inputPoll(uint port, uint device, uint id) -> int16;
struct Packet { struct Packet {
auto operator[](uint addr) -> uint8& { return data[addr & 15]; }
uint8 data[16]; uint8 data[16];
uint8& operator[](unsigned addr) { return data[addr & 15]; }
}; };
Packet packet[64]; Packet packet[64];
unsigned packetsize; uint packetsize;
unsigned joyp_id; uint joyp_id;
bool joyp15lock; bool joyp15lock;
bool joyp14lock; bool joyp14lock;
bool pulselock; bool pulselock;

View File

@ -1,9 +1,9 @@
uint8 ICD2::read(unsigned addr) { auto ICD2::read(uint addr) -> uint8 {
addr &= 0xffff; addr &= 0xffff;
//LY counter //LY counter
if(addr == 0x6000) { if(addr == 0x6000) {
unsigned y = min(143u, GameBoy::ppu.status.ly); uint y = min(143u, GameBoy::ppu.status.ly);
return (y & ~7) | write_bank; return (y & ~7) | write_bank;
} }
@ -11,9 +11,9 @@ uint8 ICD2::read(unsigned addr) {
if(addr == 0x6002) { if(addr == 0x6002) {
bool data = packetsize > 0; bool data = packetsize > 0;
if(data) { if(data) {
for(unsigned i = 0; i < 16; i++) r7000[i] = packet[0][i]; for(auto n : range(16)) r7000[n] = packet[0][n];
packetsize--; packetsize--;
for(unsigned i = 0; i < packetsize; i++) packet[i] = packet[i + 1]; for(auto n : range(packetsize)) packet[n] = packet[n + 1];
} }
return data; return data;
} }
@ -38,7 +38,7 @@ uint8 ICD2::read(unsigned addr) {
return 0x00; return 0x00;
} }
void ICD2::write(unsigned addr, uint8 data) { auto ICD2::write(uint addr, uint8 data) -> void {
addr &= 0xffff; addr &= 0xffff;
//VRAM port //VRAM port

View File

@ -7,7 +7,7 @@ uint8 r7000[16]; //JOYP packet data
uint8 mlt_req; //number of active joypads uint8 mlt_req; //number of active joypads
uint8 output[4 * 512]; uint8 output[4 * 512];
unsigned read_bank; uint read_bank;
unsigned read_addr; uint read_addr;
unsigned write_bank; uint write_bank;
unsigned write_addr; uint write_addr;

View File

@ -1,8 +1,8 @@
void ICD2::serialize(serializer& s) { auto ICD2::serialize(serializer& s) -> void {
Thread::serialize(s); Thread::serialize(s);
GameBoy::system.serialize_all(s); GameBoy::system.serialize_all(s);
for(unsigned n = 0; n < 64; n++) s.array(packet[n].data); for(auto n : range(64)) s.array(packet[n].data);
s.integer(packetsize); s.integer(packetsize);
s.integer(joyp_id); s.integer(joyp_id);

View File

@ -21,29 +21,29 @@ auto MCC::power() -> void {
} }
auto MCC::reset() -> void { auto MCC::reset() -> void {
for(unsigned i = 0; i < 16; i++) r[i] = 0x00; for(auto n : range(16)) r[n] = 0x00;
r[0x07] = 0x80; r[0x07] = 0x80;
r[0x08] = 0x80; r[0x08] = 0x80;
mmio_commit(); mmio_commit();
} }
auto MCC::memory_access(bool write, Memory& memory, unsigned addr, uint8 data) -> uint8 { auto MCC::memory_access(bool write, Memory& memory, uint addr, uint8 data) -> uint8 {
if(write == 0) return memory_read(memory, addr); if(write == 0) return memory_read(memory, addr);
memory_write(memory, addr, data); memory_write(memory, addr, data);
} }
auto MCC::memory_read(Memory& memory, unsigned addr) -> uint8 { auto MCC::memory_read(Memory& memory, uint addr) -> uint8 {
addr = bus.mirror(addr, memory.size()); addr = bus.mirror(addr, memory.size());
return memory.read(addr); return memory.read(addr);
} }
auto MCC::memory_write(Memory& memory, unsigned addr, uint8 data) -> void { auto MCC::memory_write(Memory& memory, uint addr, uint8 data) -> void {
addr = bus.mirror(addr, memory.size()); addr = bus.mirror(addr, memory.size());
return memory.write(addr, data); return memory.write(addr, data);
} }
//mcu_access() allows mcu_read() and mcu_write() to share decoding logic //mcu_access() allows mcu_read() and mcu_write() to share decoding logic
auto MCC::mcu_access(bool write, unsigned addr, uint8 data) -> uint8 { auto MCC::mcu_access(bool write, uint addr, uint8 data) -> uint8 {
if((addr & 0xe08000) == 0x008000) { //$00-1f:8000-ffff if((addr & 0xe08000) == 0x008000) { //$00-1f:8000-ffff
if(r07 == 1) { if(r07 == 1) {
addr = ((addr & 0x1f0000) >> 1) | (addr & 0x7fff); addr = ((addr & 0x1f0000) >> 1) | (addr & 0x7fff);
@ -89,15 +89,15 @@ auto MCC::mcu_access(bool write, unsigned addr, uint8 data) -> uint8 {
return cpu.regs.mdr; return cpu.regs.mdr;
} }
auto MCC::mcu_read(unsigned addr) -> uint8 { auto MCC::mcu_read(uint addr) -> uint8 {
return mcu_access(0, addr); return mcu_access(0, addr);
} }
auto MCC::mcu_write(unsigned addr, uint8 data) -> void { auto MCC::mcu_write(uint addr, uint8 data) -> void {
mcu_access(1, addr, data); mcu_access(1, addr, data);
} }
auto MCC::mmio_read(unsigned addr) -> uint8 { auto MCC::mmio_read(uint addr) -> uint8 {
if((addr & 0xf0ffff) == 0x005000) { //$00-0f:5000 if((addr & 0xf0ffff) == 0x005000) { //$00-0f:5000
uint8 n = (addr >> 16) & 15; uint8 n = (addr >> 16) & 15;
return r[n]; return r[n];
@ -110,7 +110,7 @@ auto MCC::mmio_read(unsigned addr) -> uint8 {
return 0x00; return 0x00;
} }
auto MCC::mmio_write(unsigned addr, uint8 data) -> void { auto MCC::mmio_write(uint addr, uint8 data) -> void {
if((addr & 0xf0ffff) == 0x005000) { //$00-0f:5000 if((addr & 0xf0ffff) == 0x005000) { //$00-0f:5000
uint8 n = (addr >> 16) & 15; uint8 n = (addr >> 16) & 15;
r[n] = data; r[n] = data;

View File

@ -11,16 +11,16 @@ struct MCC {
auto power() -> void; auto power() -> void;
auto reset() -> void; auto reset() -> void;
auto memory_access(bool write, Memory& memory, unsigned addr, uint8 data) -> uint8; auto memory_access(bool write, Memory& memory, uint addr, uint8 data) -> uint8;
auto memory_read(Memory& memory, unsigned addr) -> uint8; auto memory_read(Memory& memory, uint addr) -> uint8;
auto memory_write(Memory& memory, unsigned addr, uint8 data) -> void; auto memory_write(Memory& memory, uint addr, uint8 data) -> void;
auto mcu_access(bool write, unsigned addr, uint8 data = 0x00) -> uint8; auto mcu_access(bool write, uint addr, uint8 data = 0x00) -> uint8;
auto mcu_read(unsigned addr) -> uint8; auto mcu_read(uint addr) -> uint8;
auto mcu_write(unsigned addr, uint8 data) -> void; auto mcu_write(uint addr, uint8 data) -> void;
auto mmio_read(unsigned addr) -> uint8; auto mmio_read(uint addr) -> uint8;
auto mmio_write(unsigned addr, uint8 data) -> void; auto mmio_write(uint addr, uint8 data) -> void;
auto mmio_commit() -> void; auto mmio_commit() -> void;
auto serialize(serializer&) -> void; auto serialize(serializer&) -> void;

View File

@ -35,8 +35,8 @@ auto MSU1::enter() -> void {
} }
} }
signed lchannel = (double)left * (double)mmio.audioVolume / 255.0; int lchannel = (double)left * (double)mmio.audioVolume / 255.0;
signed rchannel = (double)right * (double)mmio.audioVolume / 255.0; int rchannel = (double)right * (double)mmio.audioVolume / 255.0;
left = sclamp<16>(lchannel); left = sclamp<16>(lchannel);
right = sclamp<16>(rchannel); right = sclamp<16>(rchannel);
if(dsp.mute()) left = 0, right = 0; if(dsp.mute()) left = 0, right = 0;
@ -103,7 +103,7 @@ auto MSU1::audioOpen() -> void {
auto document = BML::unserialize(cartridge.information.markup.cartridge); auto document = BML::unserialize(cartridge.information.markup.cartridge);
string name = {"track-", mmio.audioTrack, ".pcm"}; string name = {"track-", mmio.audioTrack, ".pcm"};
for(auto track : document.find("cartridge/msu1/track")) { for(auto track : document.find("cartridge/msu1/track")) {
if(track["number"].decimal() != mmio.audioTrack) continue; if(track["number"].natural() != mmio.audioTrack) continue;
name = track["name"].text(); name = track["name"].text();
break; break;
} }
@ -123,7 +123,7 @@ auto MSU1::audioOpen() -> void {
mmio.audioError = true; mmio.audioError = true;
} }
auto MSU1::mmioRead(unsigned addr) -> uint8 { auto MSU1::mmioRead(uint addr) -> uint8 {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
addr = 0x2000 | (addr & 7); addr = 0x2000 | (addr & 7);
@ -149,7 +149,7 @@ auto MSU1::mmioRead(unsigned addr) -> uint8 {
} }
} }
auto MSU1::mmioWrite(unsigned addr, uint8 data) -> void { auto MSU1::mmioWrite(uint addr, uint8 data) -> void {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
addr = 0x2000 | (addr & 7); addr = 0x2000 | (addr & 7);

View File

@ -11,8 +11,8 @@ struct MSU1 : Coprocessor {
auto dataOpen() -> void; auto dataOpen() -> void;
auto audioOpen() -> void; auto audioOpen() -> void;
auto mmioRead(unsigned addr) -> uint8; auto mmioRead(uint addr) -> uint8;
auto mmioWrite(unsigned addr, uint8 data) -> void; auto mmioWrite(uint addr, uint8 data) -> void;
auto serialize(serializer&) -> void; auto serialize(serializer&) -> void;
@ -20,7 +20,7 @@ private:
file dataFile; file dataFile;
file audioFile; file audioFile;
enum Flag : unsigned { enum Flag : uint {
DataBusy = 0x80, DataBusy = 0x80,
AudioBusy = 0x40, AudioBusy = 0x40,
AudioRepeating = 0x20, AudioRepeating = 0x20,

View File

@ -5,9 +5,9 @@ namespace SuperFamicom {
#include "serialization.cpp" #include "serialization.cpp"
NECDSP necdsp; NECDSP necdsp;
void NECDSP::Enter() { necdsp.enter(); } auto NECDSP::Enter() -> void { necdsp.enter(); }
void NECDSP::enter() { auto NECDSP::enter() -> void {
while(true) { while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) { if(scheduler.sync == Scheduler::SynchronizeMode::All) {
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
@ -19,7 +19,7 @@ void NECDSP::enter() {
} }
} }
uint8 NECDSP::read(unsigned addr) { auto NECDSP::read(uint addr) -> uint8 {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
if(addr & Select) { if(addr & Select) {
return uPD96050::sr_read(); return uPD96050::sr_read();
@ -28,7 +28,7 @@ uint8 NECDSP::read(unsigned addr) {
} }
} }
void NECDSP::write(unsigned addr, uint8 data) { auto NECDSP::write(uint addr, uint8 data) -> void {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
if(addr & Select) { if(addr & Select) {
return uPD96050::sr_write(data); return uPD96050::sr_write(data);
@ -37,29 +37,29 @@ void NECDSP::write(unsigned addr, uint8 data) {
} }
} }
uint8 NECDSP::ram_read(unsigned addr) { auto NECDSP::ram_read(uint addr) -> uint8 {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
return uPD96050::dp_read(addr); return uPD96050::dp_read(addr);
} }
void NECDSP::ram_write(unsigned addr, uint8 data) { auto NECDSP::ram_write(uint addr, uint8 data) -> void {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
return uPD96050::dp_write(addr, data); return uPD96050::dp_write(addr, data);
} }
void NECDSP::init() { auto NECDSP::init() -> void {
} }
void NECDSP::load() { auto NECDSP::load() -> void {
} }
void NECDSP::unload() { auto NECDSP::unload() -> void {
} }
void NECDSP::power() { auto NECDSP::power() -> void {
} }
void NECDSP::reset() { auto NECDSP::reset() -> void {
create(NECDSP::Enter, frequency); create(NECDSP::Enter, frequency);
uPD96050::power(); uPD96050::power();
} }

View File

@ -1,23 +1,23 @@
struct NECDSP : Processor::uPD96050, Coprocessor { struct NECDSP : Processor::uPD96050, Coprocessor {
static auto Enter() -> void;
auto enter() -> void;
auto read(uint addr) -> uint8;
auto write(uint addr, uint8 data) -> void;
auto ram_read(uint addr) -> uint8;
auto ram_write(uint addr, uint8 data) -> void;
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;
auto reset() -> void;
auto firmware() const -> vector<uint8>;
auto serialize(serializer&) -> void;
unsigned Select; unsigned Select;
static void Enter();
void enter();
uint8 read(unsigned addr);
void write(unsigned addr, uint8 data);
uint8 ram_read(unsigned addr);
void ram_write(unsigned addr, uint8 data);
void init();
void load();
void unload();
void power();
void reset();
vector<uint8> firmware();
void serialize(serializer&);
}; };
extern NECDSP necdsp; extern NECDSP necdsp;

View File

@ -1,17 +1,17 @@
vector<uint8> NECDSP::firmware() { auto NECDSP::firmware() const -> vector<uint8> {
vector<uint8> buffer; vector<uint8> buffer;
if(!cartridge.hasNECDSP()) return buffer; if(!cartridge.hasNECDSP()) return buffer;
unsigned plength = 2048, dlength = 1024; uint plength = 2048, dlength = 1024;
if(revision == Revision::uPD96050) plength = 16384, dlength = 2048; if(revision == Revision::uPD96050) plength = 16384, dlength = 2048;
buffer.reserve(plength * 3 + dlength * 2); buffer.reserve(plength * 3 + dlength * 2);
for(unsigned n = 0; n < plength; n++) { for(auto n : range(plength)) {
buffer.append(programROM[n] >> 0); buffer.append(programROM[n] >> 0);
buffer.append(programROM[n] >> 8); buffer.append(programROM[n] >> 8);
buffer.append(programROM[n] >> 16); buffer.append(programROM[n] >> 16);
} }
for(unsigned n = 0; n < dlength; n++) { for(auto n : range(dlength)) {
buffer.append(dataROM[n] >> 0); buffer.append(dataROM[n] >> 0);
buffer.append(dataROM[n] >> 8); buffer.append(dataROM[n] >> 8);
} }
@ -19,7 +19,7 @@ vector<uint8> NECDSP::firmware() {
return buffer; return buffer;
} }
void NECDSP::serialize(serializer& s) { auto NECDSP::serialize(serializer& s) -> void {
uPD96050::serialize(s); uPD96050::serialize(s);
Thread::serialize(s); Thread::serialize(s);
} }

View File

@ -4,31 +4,30 @@ namespace SuperFamicom {
NSS nss; NSS nss;
void NSS::init() { auto NSS::init() -> void {
dip = 0x00;
} }
void NSS::load() { auto NSS::load() -> void {
} }
void NSS::unload() { auto NSS::unload() -> void {
} }
void NSS::power() { auto NSS::power() -> void {
} }
void NSS::reset() { auto NSS::reset() -> void {
} }
void NSS::set_dip(uint16 dip) { auto NSS::set_dip(uint16 dip) -> void {
this->dip = dip; this->dip = dip;
} }
uint8 NSS::read(unsigned addr) { auto NSS::read(uint addr) -> uint8 {
return dip; return dip;
} }
void NSS::write(unsigned addr, uint8 data) { auto NSS::write(uint addr, uint8 data) -> void {
} }
} }

View File

@ -1,15 +1,15 @@
struct NSS { struct NSS {
uint8 dip; auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;
auto reset() -> void;
void init(); auto set_dip(uint16 dip) -> void;
void load(); auto read(uint addr) -> uint8;
void unload(); auto write(uint addr, uint8 data) -> void;
void power();
void reset();
void set_dip(uint16 dip); uint8 dip = 0x00;
uint8 read(unsigned addr);
void write(unsigned addr, uint8 data);
}; };
extern NSS nss; extern NSS nss;

View File

@ -5,74 +5,74 @@ namespace SuperFamicom {
#include "serialization.cpp" #include "serialization.cpp"
OBC1 obc1; OBC1 obc1;
void OBC1::init() { auto OBC1::init() -> void {
} }
void OBC1::load() { auto OBC1::load() -> void {
} }
void OBC1::unload() { auto OBC1::unload() -> void {
ram.reset(); ram.reset();
} }
void OBC1::power() { auto OBC1::power() -> void {
} }
void OBC1::reset() { auto OBC1::reset() -> void {
status.baseptr = (ram_read(0x1ff5) & 1) ? 0x1800 : 0x1c00; status.baseptr = (ramRead(0x1ff5) & 1) ? 0x1800 : 0x1c00;
status.address = (ram_read(0x1ff6) & 0x7f); status.address = (ramRead(0x1ff6) & 0x7f);
status.shift = (ram_read(0x1ff6) & 3) << 1; status.shift = (ramRead(0x1ff6) & 3) << 1;
} }
uint8 OBC1::read(unsigned addr) { auto OBC1::read(uint addr) -> uint8 {
addr &= 0x1fff; addr &= 0x1fff;
switch(addr) { switch(addr) {
case 0x1ff0: return ram_read(status.baseptr + (status.address << 2) + 0); case 0x1ff0: return ramRead(status.baseptr + (status.address << 2) + 0);
case 0x1ff1: return ram_read(status.baseptr + (status.address << 2) + 1); case 0x1ff1: return ramRead(status.baseptr + (status.address << 2) + 1);
case 0x1ff2: return ram_read(status.baseptr + (status.address << 2) + 2); case 0x1ff2: return ramRead(status.baseptr + (status.address << 2) + 2);
case 0x1ff3: return ram_read(status.baseptr + (status.address << 2) + 3); case 0x1ff3: return ramRead(status.baseptr + (status.address << 2) + 3);
case 0x1ff4: return ram_read(status.baseptr + (status.address >> 2) + 0x200); case 0x1ff4: return ramRead(status.baseptr + (status.address >> 2) + 0x200);
} }
return ram_read(addr); return ramRead(addr);
} }
void OBC1::write(unsigned addr, uint8 data) { auto OBC1::write(uint addr, uint8 data) -> void {
addr &= 0x1fff; addr &= 0x1fff;
switch(addr) { switch(addr) {
case 0x1ff0: ram_write(status.baseptr + (status.address << 2) + 0, data); return; case 0x1ff0: ramWrite(status.baseptr + (status.address << 2) + 0, data); return;
case 0x1ff1: ram_write(status.baseptr + (status.address << 2) + 1, data); return; case 0x1ff1: ramWrite(status.baseptr + (status.address << 2) + 1, data); return;
case 0x1ff2: ram_write(status.baseptr + (status.address << 2) + 2, data); return; case 0x1ff2: ramWrite(status.baseptr + (status.address << 2) + 2, data); return;
case 0x1ff3: ram_write(status.baseptr + (status.address << 2) + 3, data); return; case 0x1ff3: ramWrite(status.baseptr + (status.address << 2) + 3, data); return;
case 0x1ff4: { case 0x1ff4: {
uint8 temp = ram_read(status.baseptr + (status.address >> 2) + 0x200); uint8 temp = ramRead(status.baseptr + (status.address >> 2) + 0x200);
temp = (temp & ~(3 << status.shift)) | ((data & 3) << status.shift); temp = (temp & ~(3 << status.shift)) | ((data & 3) << status.shift);
ram_write(status.baseptr + (status.address >> 2) + 0x200, temp); ramWrite(status.baseptr + (status.address >> 2) + 0x200, temp);
} return; } return;
case 0x1ff5: case 0x1ff5:
status.baseptr = (data & 1) ? 0x1800 : 0x1c00; status.baseptr = (data & 1) ? 0x1800 : 0x1c00;
ram_write(addr, data); ramWrite(addr, data);
return; return;
case 0x1ff6: case 0x1ff6:
status.address = (data & 0x7f); status.address = (data & 0x7f);
status.shift = (data & 3) << 1; status.shift = (data & 3) << 1;
ram_write(addr, data); ramWrite(addr, data);
return; return;
case 0x1ff7: case 0x1ff7:
ram_write(addr, data); ramWrite(addr, data);
return; return;
} }
return ram_write(addr, data); return ramWrite(addr, data);
} }
uint8 OBC1::ram_read(unsigned addr) { auto OBC1::ramRead(uint addr) -> uint8 {
return ram.read(addr & 0x1fff); return ram.read(addr & 0x1fff);
} }
void OBC1::ram_write(unsigned addr, uint8 data) { auto OBC1::ramWrite(uint addr, uint8 data) -> void {
ram.write(addr & 0x1fff, data); ram.write(addr & 0x1fff, data);
} }

View File

@ -1,20 +1,20 @@
struct OBC1 { struct OBC1 {
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;
auto reset() -> void;
auto read(uint addr) -> uint8;
auto write(uint addr, uint8 data) -> void;
auto serialize(serializer&) -> void;
MappedRAM ram; MappedRAM ram;
void init();
void load();
void unload();
void power();
void reset();
uint8 read(unsigned addr);
void write(unsigned addr, uint8 data);
void serialize(serializer&);
private: private:
uint8 ram_read(unsigned addr); auto ramRead(uint addr) -> uint8;
void ram_write(unsigned addr, uint8 data); auto ramWrite(uint addr, uint8 data) -> void;
struct { struct {
uint16 address; uint16 address;

View File

@ -1,4 +1,4 @@
void OBC1::serialize(serializer& s) { auto OBC1::serialize(serializer& s) -> void {
s.array(ram.data(), ram.size()); s.array(ram.data(), ram.size());
s.integer(status.address); s.integer(status.address);

View File

@ -1,30 +1,30 @@
//ROM / RAM access from the S-CPU //ROM / RAM access from the S-CPU
unsigned SA1::CPUIRAM::size() const { auto SA1::CPUIRAM::size() const -> uint {
return sa1.iram.size(); return sa1.iram.size();
} }
uint8 SA1::CPUIRAM::read(unsigned addr) { auto SA1::CPUIRAM::read(uint addr) -> uint8 {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
return sa1.iram.read(addr & 0x07ff); return sa1.iram.read(addr & 0x07ff);
} }
void SA1::CPUIRAM::write(unsigned addr, uint8 data) { auto SA1::CPUIRAM::write(uint addr, uint8 data) -> void {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
sa1.iram.write(addr & 0x07ff, data); sa1.iram.write(addr & 0x07ff, data);
} }
unsigned SA1::CPUBWRAM::size() const { auto SA1::CPUBWRAM::size() const -> uint {
return sa1.bwram.size(); return sa1.bwram.size();
} }
uint8 SA1::CPUBWRAM::read(unsigned addr) { auto SA1::CPUBWRAM::read(uint addr) -> uint8 {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
if(dma) return sa1.dma_cc1_read(addr); if(dma) return sa1.dma_cc1_read(addr);
return sa1.bwram.read(addr); return sa1.bwram.read(addr);
} }
void SA1::CPUBWRAM::write(unsigned addr, uint8 data) { auto SA1::CPUBWRAM::write(uint addr, uint8 data) -> void {
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
sa1.bwram.write(addr, data); sa1.bwram.write(addr, data);
} }

View File

@ -1,12 +1,12 @@
struct CPUIRAM : Memory { struct CPUIRAM : Memory {
unsigned size() const; auto size() const -> uint;
alwaysinline uint8 read(unsigned); alwaysinline auto read(uint) -> uint8;
alwaysinline void write(unsigned, uint8); alwaysinline auto write(uint, uint8) -> void;
} cpuiram; } cpuiram;
struct CPUBWRAM : Memory { struct CPUBWRAM : Memory {
unsigned size() const; auto size() const -> uint;
alwaysinline uint8 read(unsigned); alwaysinline auto read(uint) -> uint8;
alwaysinline void write(unsigned, uint8); alwaysinline auto write(uint, uint8) -> void;
bool dma; bool dma;
} cpubwram; } cpubwram;

View File

@ -2,7 +2,7 @@
//direct data transfer //direct data transfer
//==================== //====================
void SA1::dma_normal() { auto SA1::dma_normal() -> void {
while(mmio.dtc--) { while(mmio.dtc--) {
uint8 data = regs.mdr; uint8 data = regs.mdr;
uint32 dsa = mmio.dsa++; uint32 dsa = mmio.dsa++;
@ -56,7 +56,7 @@ void SA1::dma_normal() {
//type-1 character conversion //type-1 character conversion
//=========================== //===========================
void SA1::dma_cc1() { auto SA1::dma_cc1() -> void {
cpubwram.dma = true; cpubwram.dma = true;
mmio.chdma_irqfl = true; mmio.chdma_irqfl = true;
if(mmio.chdma_irqen) { if(mmio.chdma_irqen) {
@ -65,29 +65,29 @@ void SA1::dma_cc1() {
} }
} }
uint8 SA1::dma_cc1_read(unsigned addr) { auto SA1::dma_cc1_read(uint addr) -> uint8 {
//16 bytes/char (2bpp); 32 bytes/char (4bpp); 64 bytes/char (8bpp) //16 bytes/char (2bpp); 32 bytes/char (4bpp); 64 bytes/char (8bpp)
unsigned charmask = (1 << (6 - mmio.dmacb)) - 1; uint charmask = (1 << (6 - mmio.dmacb)) - 1;
if((addr & charmask) == 0) { if((addr & charmask) == 0) {
//buffer next character to I-RAM //buffer next character to I-RAM
unsigned bpp = 2 << (2 - mmio.dmacb); uint bpp = 2 << (2 - mmio.dmacb);
unsigned bpl = (8 << mmio.dmasize) >> mmio.dmacb; uint bpl = (8 << mmio.dmasize) >> mmio.dmacb;
unsigned bwmask = bwram.size() - 1; uint bwmask = bwram.size() - 1;
unsigned tile = ((addr - mmio.dsa) & bwmask) >> (6 - mmio.dmacb); uint tile = ((addr - mmio.dsa) & bwmask) >> (6 - mmio.dmacb);
unsigned ty = (tile >> mmio.dmasize); uint ty = (tile >> mmio.dmasize);
unsigned tx = tile & ((1 << mmio.dmasize) - 1); uint tx = tile & ((1 << mmio.dmasize) - 1);
unsigned bwaddr = mmio.dsa + ty * 8 * bpl + tx * bpp; uint bwaddr = mmio.dsa + ty * 8 * bpl + tx * bpp;
for(unsigned y = 0; y < 8; y++) { for(auto y : range(8)) {
uint64 data = 0; uint64 data = 0;
for(unsigned byte = 0; byte < bpp; byte++) { for(auto byte : range(bpp)) {
data |= (uint64)bwram.read((bwaddr + byte) & bwmask) << (byte << 3); data |= (uint64)bwram.read((bwaddr + byte) & bwmask) << (byte << 3);
} }
bwaddr += bpl; bwaddr += bpl;
uint8 out[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; uint8 out[] = {0, 0, 0, 0, 0, 0, 0, 0};
for(unsigned x = 0; x < 8; x++) { for(auto x : range(8)) {
out[0] |= (data & 1) << (7 - x); data >>= 1; out[0] |= (data & 1) << (7 - x); data >>= 1;
out[1] |= (data & 1) << (7 - x); data >>= 1; out[1] |= (data & 1) << (7 - x); data >>= 1;
if(mmio.dmacb == 2) continue; if(mmio.dmacb == 2) continue;
@ -100,8 +100,8 @@ uint8 SA1::dma_cc1_read(unsigned addr) {
out[7] |= (data & 1) << (7 - x); data >>= 1; out[7] |= (data & 1) << (7 - x); data >>= 1;
} }
for(unsigned byte = 0; byte < bpp; byte++) { for(auto byte : range(bpp)) {
unsigned p = mmio.dda + (y << 1) + ((byte & 6) << 3) + (byte & 1); uint p = mmio.dda + (y << 1) + ((byte & 6) << 3) + (byte & 1);
iram.write(p & 0x07ff, out[byte]); iram.write(p & 0x07ff, out[byte]);
} }
} }
@ -114,18 +114,18 @@ uint8 SA1::dma_cc1_read(unsigned addr) {
//type-2 character conversion //type-2 character conversion
//=========================== //===========================
void SA1::dma_cc2() { auto SA1::dma_cc2() -> void {
//select register file index (0-7 or 8-15) //select register file index (0-7 or 8-15)
const uint8 *brf = &mmio.brf[(dma.line & 1) << 3]; const uint8* brf = &mmio.brf[(dma.line & 1) << 3];
unsigned bpp = 2 << (2 - mmio.dmacb); uint bpp = 2 << (2 - mmio.dmacb);
unsigned addr = mmio.dda & 0x07ff; uint addr = mmio.dda & 0x07ff;
addr &= ~((1 << (7 - mmio.dmacb)) - 1); addr &= ~((1 << (7 - mmio.dmacb)) - 1);
addr += (dma.line & 8) * bpp; addr += (dma.line & 8) * bpp;
addr += (dma.line & 7) * 2; addr += (dma.line & 7) * 2;
for(unsigned byte = 0; byte < bpp; byte++) { for(auto byte : range(bpp)) {
uint8 output = 0; uint8 output = 0;
for(unsigned bit = 0; bit < 8; bit++) { for(auto bit : range(8)) {
output |= ((brf[bit] >> byte) & 1) << (7 - bit); output |= ((brf[bit] >> byte) & 1) << (7 - bit);
} }
iram.write(addr + ((byte & 6) << 3) + (byte & 1), output); iram.write(addr + ((byte & 6) << 3) + (byte & 1), output);

View File

@ -1,11 +1,11 @@
struct DMA { struct DMA {
enum CDEN { DmaNormal = 0, DmaCharConversion = 1 }; enum CDEN : uint { DmaNormal = 0, DmaCharConversion = 1 };
enum SD { SourceROM = 0, SourceBWRAM = 1, SourceIRAM = 2 }; enum SD : uint { SourceROM = 0, SourceBWRAM = 1, SourceIRAM = 2 };
enum DD { DestIRAM = 0, DestBWRAM = 1 }; enum DD : uint { DestIRAM = 0, DestBWRAM = 1 };
unsigned line; uint line;
} dma; } dma;
void dma_normal(); auto dma_normal() -> void;
void dma_cc1(); auto dma_cc1() -> void;
uint8 dma_cc1_read(unsigned addr); auto dma_cc1_read(uint addr) -> uint8;
void dma_cc2(); auto dma_cc2() -> void;

View File

@ -1,4 +1,4 @@
uint8 SA1::bus_read(unsigned addr) { auto SA1::bus_read(uint addr) -> uint8 {
if((addr & 0x40fe00) == 0x002200) { //$00-3f|80-bf:2200-23ff if((addr & 0x40fe00) == 0x002200) { //$00-3f|80-bf:2200-23ff
return mmio_read(addr); return mmio_read(addr);
} }
@ -39,7 +39,7 @@ uint8 SA1::bus_read(unsigned addr) {
return regs.mdr; return regs.mdr;
} }
void SA1::bus_write(unsigned addr, uint8 data) { auto SA1::bus_write(uint addr, uint8 data) -> void {
if((addr & 0x40fe00) == 0x002200) { //$00-3f|80-bf:2200-23ff if((addr & 0x40fe00) == 0x002200) { //$00-3f|80-bf:2200-23ff
return mmio_write(addr, data); return mmio_write(addr, data);
} }
@ -73,7 +73,7 @@ void SA1::bus_write(unsigned addr, uint8 data) {
//this is used both to keep VBR-reads from accessing MMIO registers, and //this is used both to keep VBR-reads from accessing MMIO registers, and
//to avoid syncing the S-CPU and SA-1*; as both chips are able to access //to avoid syncing the S-CPU and SA-1*; as both chips are able to access
//these ports. //these ports.
uint8 SA1::vbr_read(unsigned addr) { auto SA1::vbr_read(uint addr) -> uint8 {
if((addr & 0x408000) == 0x008000) { //$00-3f|80-bf:8000-ffff if((addr & 0x408000) == 0x008000) { //$00-3f|80-bf:8000-ffff
return mmcrom_read(addr); return mmcrom_read(addr);
} }
@ -97,6 +97,8 @@ uint8 SA1::vbr_read(unsigned addr) {
if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff
return iram.read(addr & 2047); return iram.read(addr & 2047);
} }
return 0x00;
} }
//ROM, I-RAM and MMIO registers are accessed at ~10.74MHz (2 clock ticks) //ROM, I-RAM and MMIO registers are accessed at ~10.74MHz (2 clock ticks)
@ -104,23 +106,23 @@ uint8 SA1::vbr_read(unsigned addr) {
//tick() == 2 clock ticks //tick() == 2 clock ticks
//note: bus conflict delays are not emulated at this time //note: bus conflict delays are not emulated at this time
void SA1::op_io() { auto SA1::op_io() -> void {
tick(); tick();
} }
uint8 SA1::op_read(unsigned addr) { auto SA1::op_read(uint addr) -> uint8 {
tick(); tick();
if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick(); if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick();
return bus_read(addr); return bus_read(addr);
} }
void SA1::op_write(unsigned addr, uint8 data) { auto SA1::op_write(uint addr, uint8 data) -> void {
tick(); tick();
if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick(); if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick();
bus_write(addr, regs.mdr = data); bus_write(addr, regs.mdr = data);
} }
uint8 SA1::mmcrom_read(unsigned addr) { auto SA1::mmcrom_read(uint addr) -> uint8 {
if((addr & 0xffffe0) == 0x00ffe0) { if((addr & 0xffffe0) == 0x00ffe0) {
if(addr == 0xffea && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 0; if(addr == 0xffea && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 0;
if(addr == 0xffeb && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 8; if(addr == 0xffeb && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 8;
@ -128,7 +130,7 @@ uint8 SA1::mmcrom_read(unsigned addr) {
if(addr == 0xffef && sa1.mmio.cpu_ivsw) return sa1.mmio.siv >> 8; if(addr == 0xffef && sa1.mmio.cpu_ivsw) return sa1.mmio.siv >> 8;
} }
static auto read = [](unsigned addr) { static auto read = [](uint addr) {
return sa1.rom.read(bus.mirror(addr, sa1.rom.size())); return sa1.rom.read(bus.mirror(addr, sa1.rom.size()));
}; };
@ -175,10 +177,10 @@ uint8 SA1::mmcrom_read(unsigned addr) {
return 0x00; return 0x00;
} }
void SA1::mmcrom_write(unsigned addr, uint8 data) { auto SA1::mmcrom_write(uint addr, uint8 data) -> void {
} }
uint8 SA1::mmcbwram_read(unsigned addr) { auto SA1::mmcbwram_read(uint addr) -> uint8 {
if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size()); addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size());
@ -192,7 +194,7 @@ uint8 SA1::mmcbwram_read(unsigned addr) {
return cpu.regs.mdr; return cpu.regs.mdr;
} }
void SA1::mmcbwram_write(unsigned addr, uint8 data) { auto SA1::mmcbwram_write(uint addr, uint8 data) -> void {
if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff if((addr & 0x40e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
cpu.synchronizeCoprocessors(); cpu.synchronizeCoprocessors();
addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size()); addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size());
@ -204,7 +206,7 @@ void SA1::mmcbwram_write(unsigned addr, uint8 data) {
} }
} }
uint8 SA1::mmc_sa1_read(unsigned addr) { auto SA1::mmc_sa1_read(uint addr) -> uint8 {
synchronize_cpu(); synchronize_cpu();
if(mmio.sw46 == 0) { if(mmio.sw46 == 0) {
//$40-43:0000-ffff x 32 projection //$40-43:0000-ffff x 32 projection
@ -217,7 +219,7 @@ uint8 SA1::mmc_sa1_read(unsigned addr) {
} }
} }
void SA1::mmc_sa1_write(unsigned addr, uint8 data) { auto SA1::mmc_sa1_write(uint addr, uint8 data) -> void {
synchronize_cpu(); synchronize_cpu();
if(mmio.sw46 == 0) { if(mmio.sw46 == 0) {
//$40-43:0000-ffff x 32 projection //$40-43:0000-ffff x 32 projection
@ -230,10 +232,10 @@ void SA1::mmc_sa1_write(unsigned addr, uint8 data) {
} }
} }
uint8 SA1::bitmap_read(unsigned addr) { auto SA1::bitmap_read(uint addr) -> uint8 {
if(mmio.bbf == 0) { if(mmio.bbf == 0) {
//4bpp //4bpp
unsigned shift = addr & 1; uint shift = addr & 1;
addr = (addr >> 1) & (bwram.size() - 1); addr = (addr >> 1) & (bwram.size() - 1);
switch(shift) { switch(shift) {
case 0: return (bwram.read(addr) >> 0) & 15; case 0: return (bwram.read(addr) >> 0) & 15;
@ -241,7 +243,7 @@ uint8 SA1::bitmap_read(unsigned addr) {
} }
} else { } else {
//2bpp //2bpp
unsigned shift = addr & 3; uint shift = addr & 3;
addr = (addr >> 2) & (bwram.size() - 1); addr = (addr >> 2) & (bwram.size() - 1);
switch(shift) { switch(shift) {
case 0: return (bwram.read(addr) >> 0) & 3; case 0: return (bwram.read(addr) >> 0) & 3;
@ -252,10 +254,10 @@ uint8 SA1::bitmap_read(unsigned addr) {
} }
} }
void SA1::bitmap_write(unsigned addr, uint8 data) { auto SA1::bitmap_write(uint addr, uint8 data) -> void {
if(mmio.bbf == 0) { if(mmio.bbf == 0) {
//4bpp //4bpp
unsigned shift = addr & 1; uint shift = addr & 1;
addr = (addr >> 1) & (bwram.size() - 1); addr = (addr >> 1) & (bwram.size() - 1);
switch(shift) { switch(shift) {
case 0: data = (bwram.read(addr) & 0xf0) | ((data & 15) << 0); break; case 0: data = (bwram.read(addr) & 0xf0) | ((data & 15) << 0); break;
@ -263,7 +265,7 @@ void SA1::bitmap_write(unsigned addr, uint8 data) {
} }
} else { } else {
//2bpp //2bpp
unsigned shift = addr & 3; uint shift = addr & 3;
addr = (addr >> 2) & (bwram.size() - 1); addr = (addr >> 2) & (bwram.size() - 1);
switch(shift) { switch(shift) {
case 0: data = (bwram.read(addr) & 0xfc) | ((data & 3) << 0); break; case 0: data = (bwram.read(addr) & 0xfc) | ((data & 3) << 0); break;

View File

@ -1,19 +1,19 @@
uint8 bus_read(unsigned addr); auto bus_read(uint addr) -> uint8;
void bus_write(unsigned addr, uint8 data); auto bus_write(uint addr, uint8 data) -> void;
uint8 vbr_read(unsigned addr); auto vbr_read(uint addr) -> uint8;
alwaysinline void op_io(); alwaysinline auto op_io() -> void;
alwaysinline uint8 op_read(unsigned addr); alwaysinline auto op_read(uint addr) -> uint8;
alwaysinline void op_write(unsigned addr, uint8 data); alwaysinline auto op_write(uint addr, uint8 data) -> void;
uint8 mmcrom_read(unsigned addr); auto mmcrom_read(uint addr) -> uint8;
void mmcrom_write(unsigned addr, uint8 data); auto mmcrom_write(uint addr, uint8 data) -> void;
uint8 mmcbwram_read(unsigned addr); auto mmcbwram_read(uint addr) -> uint8;
void mmcbwram_write(unsigned addr, uint8 data); auto mmcbwram_write(uint addr, uint8 data) -> void;
uint8 mmc_sa1_read(unsigned addr); auto mmc_sa1_read(uint addr) -> uint8;
void mmc_sa1_write(unsigned addr, uint8 data); auto mmc_sa1_write(uint addr, uint8 data) -> void;
uint8 bitmap_read(unsigned addr); auto bitmap_read(uint addr) -> uint8;
void bitmap_write(unsigned addr, uint8 data); auto bitmap_write(uint addr, uint8 data) -> void;

View File

@ -1,5 +1,5 @@
//(CCNT) SA-1 control //(CCNT) SA-1 control
void SA1::mmio_w2200(uint8 data) { auto SA1::mmio_w2200(uint8 data) -> void {
if(mmio.sa1_resb && !(data & 0x80)) { if(mmio.sa1_resb && !(data & 0x80)) {
//reset SA-1 CPU //reset SA-1 CPU
regs.pc.w = mmio.crv; regs.pc.w = mmio.crv;
@ -24,7 +24,7 @@ void SA1::mmio_w2200(uint8 data) {
} }
//(SIE) S-CPU interrupt enable //(SIE) S-CPU interrupt enable
void SA1::mmio_w2201(uint8 data) { auto SA1::mmio_w2201(uint8 data) -> void {
if(!mmio.cpu_irqen && (data & 0x80)) { if(!mmio.cpu_irqen && (data & 0x80)) {
if(mmio.cpu_irqfl) { if(mmio.cpu_irqfl) {
mmio.cpu_irqcl = 0; mmio.cpu_irqcl = 0;
@ -44,7 +44,7 @@ void SA1::mmio_w2201(uint8 data) {
} }
//(SIC) S-CPU interrupt clear //(SIC) S-CPU interrupt clear
void SA1::mmio_w2202(uint8 data) { auto SA1::mmio_w2202(uint8 data) -> void {
mmio.cpu_irqcl = (data & 0x80); mmio.cpu_irqcl = (data & 0x80);
mmio.chdma_irqcl = (data & 0x20); mmio.chdma_irqcl = (data & 0x20);
@ -55,19 +55,19 @@ void SA1::mmio_w2202(uint8 data) {
} }
//(CRV) SA-1 reset vector //(CRV) SA-1 reset vector
void SA1::mmio_w2203(uint8 data) { mmio.crv = (mmio.crv & 0xff00) | data; } auto SA1::mmio_w2203(uint8 data) -> void { mmio.crv = (mmio.crv & 0xff00) | data; }
void SA1::mmio_w2204(uint8 data) { mmio.crv = (data << 8) | (mmio.crv & 0xff); } auto SA1::mmio_w2204(uint8 data) -> void { mmio.crv = (data << 8) | (mmio.crv & 0xff); }
//(CNV) SA-1 NMI vector //(CNV) SA-1 NMI vector
void SA1::mmio_w2205(uint8 data) { mmio.cnv = (mmio.cnv & 0xff00) | data; } auto SA1::mmio_w2205(uint8 data) -> void { mmio.cnv = (mmio.cnv & 0xff00) | data; }
void SA1::mmio_w2206(uint8 data) { mmio.cnv = (data << 8) | (mmio.cnv & 0xff); } auto SA1::mmio_w2206(uint8 data) -> void { mmio.cnv = (data << 8) | (mmio.cnv & 0xff); }
//(CIV) SA-1 IRQ vector //(CIV) SA-1 IRQ vector
void SA1::mmio_w2207(uint8 data) { mmio.civ = (mmio.civ & 0xff00) | data; } auto SA1::mmio_w2207(uint8 data) -> void { mmio.civ = (mmio.civ & 0xff00) | data; }
void SA1::mmio_w2208(uint8 data) { mmio.civ = (data << 8) | (mmio.civ & 0xff); } auto SA1::mmio_w2208(uint8 data) -> void { mmio.civ = (data << 8) | (mmio.civ & 0xff); }
//(SCNT) S-CPU control //(SCNT) S-CPU control
void SA1::mmio_w2209(uint8 data) { auto SA1::mmio_w2209(uint8 data) -> void {
mmio.cpu_irq = (data & 0x80); mmio.cpu_irq = (data & 0x80);
mmio.cpu_ivsw = (data & 0x40); mmio.cpu_ivsw = (data & 0x40);
mmio.cpu_nvsw = (data & 0x10); mmio.cpu_nvsw = (data & 0x10);
@ -83,7 +83,7 @@ void SA1::mmio_w2209(uint8 data) {
} }
//(CIE) SA-1 interrupt enable //(CIE) SA-1 interrupt enable
void SA1::mmio_w220a(uint8 data) { auto SA1::mmio_w220a(uint8 data) -> void {
if(!mmio.sa1_irqen && (data & 0x80) && mmio.sa1_irqfl ) mmio.sa1_irqcl = 0; if(!mmio.sa1_irqen && (data & 0x80) && mmio.sa1_irqfl ) mmio.sa1_irqcl = 0;
if(!mmio.timer_irqen && (data & 0x40) && mmio.timer_irqfl) mmio.timer_irqcl = 0; if(!mmio.timer_irqen && (data & 0x40) && mmio.timer_irqfl) mmio.timer_irqcl = 0;
if(!mmio.dma_irqen && (data & 0x20) && mmio.dma_irqfl ) mmio.dma_irqcl = 0; if(!mmio.dma_irqen && (data & 0x20) && mmio.dma_irqfl ) mmio.dma_irqcl = 0;
@ -96,7 +96,7 @@ void SA1::mmio_w220a(uint8 data) {
} }
//(CIC) SA-1 interrupt clear //(CIC) SA-1 interrupt clear
void SA1::mmio_w220b(uint8 data) { auto SA1::mmio_w220b(uint8 data) -> void {
mmio.sa1_irqcl = (data & 0x80); mmio.sa1_irqcl = (data & 0x80);
mmio.timer_irqcl = (data & 0x40); mmio.timer_irqcl = (data & 0x40);
mmio.dma_irqcl = (data & 0x20); mmio.dma_irqcl = (data & 0x20);
@ -109,96 +109,96 @@ void SA1::mmio_w220b(uint8 data) {
} }
//(SNV) S-CPU NMI vector //(SNV) S-CPU NMI vector
void SA1::mmio_w220c(uint8 data) { mmio.snv = (mmio.snv & 0xff00) | data; } auto SA1::mmio_w220c(uint8 data) -> void { mmio.snv = (mmio.snv & 0xff00) | data; }
void SA1::mmio_w220d(uint8 data) { mmio.snv = (data << 8) | (mmio.snv & 0xff); } auto SA1::mmio_w220d(uint8 data) -> void { mmio.snv = (data << 8) | (mmio.snv & 0xff); }
//(SIV) S-CPU IRQ vector //(SIV) S-CPU IRQ vector
void SA1::mmio_w220e(uint8 data) { mmio.siv = (mmio.siv & 0xff00) | data; } auto SA1::mmio_w220e(uint8 data) -> void { mmio.siv = (mmio.siv & 0xff00) | data; }
void SA1::mmio_w220f(uint8 data) { mmio.siv = (data << 8) | (mmio.siv & 0xff); } auto SA1::mmio_w220f(uint8 data) -> void { mmio.siv = (data << 8) | (mmio.siv & 0xff); }
//(TMC) H/V timer control //(TMC) H/V timer control
void SA1::mmio_w2210(uint8 data) { auto SA1::mmio_w2210(uint8 data) -> void {
mmio.hvselb = (data & 0x80); mmio.hvselb = (data & 0x80);
mmio.ven = (data & 0x02); mmio.ven = (data & 0x02);
mmio.hen = (data & 0x01); mmio.hen = (data & 0x01);
} }
//(CTR) SA-1 timer restart //(CTR) SA-1 timer restart
void SA1::mmio_w2211(uint8 data) { auto SA1::mmio_w2211(uint8 data) -> void {
status.vcounter = 0; status.vcounter = 0;
status.hcounter = 0; status.hcounter = 0;
} }
//(HCNT) H-count //(HCNT) H-count
void SA1::mmio_w2212(uint8 data) { mmio.hcnt = (mmio.hcnt & 0xff00) | (data << 0); } auto SA1::mmio_w2212(uint8 data) -> void { mmio.hcnt = (mmio.hcnt & 0xff00) | (data << 0); }
void SA1::mmio_w2213(uint8 data) { mmio.hcnt = (mmio.hcnt & 0x00ff) | (data << 8); } auto SA1::mmio_w2213(uint8 data) -> void { mmio.hcnt = (mmio.hcnt & 0x00ff) | (data << 8); }
//(VCNT) V-count //(VCNT) V-count
void SA1::mmio_w2214(uint8 data) { mmio.vcnt = (mmio.vcnt & 0xff00) | (data << 0); } auto SA1::mmio_w2214(uint8 data) -> void { mmio.vcnt = (mmio.vcnt & 0xff00) | (data << 0); }
void SA1::mmio_w2215(uint8 data) { mmio.vcnt = (mmio.vcnt & 0x00ff) | (data << 8); } auto SA1::mmio_w2215(uint8 data) -> void { mmio.vcnt = (mmio.vcnt & 0x00ff) | (data << 8); }
//(CXB) Super MMC bank C //(CXB) Super MMC bank C
void SA1::mmio_w2220(uint8 data) { auto SA1::mmio_w2220(uint8 data) -> void {
mmio.cbmode = (data & 0x80); mmio.cbmode = (data & 0x80);
mmio.cb = (data & 0x07); mmio.cb = (data & 0x07);
} }
//(DXB) Super MMC bank D //(DXB) Super MMC bank D
void SA1::mmio_w2221(uint8 data) { auto SA1::mmio_w2221(uint8 data) -> void {
mmio.dbmode = (data & 0x80); mmio.dbmode = (data & 0x80);
mmio.db = (data & 0x07); mmio.db = (data & 0x07);
} }
//(EXB) Super MMC bank E //(EXB) Super MMC bank E
void SA1::mmio_w2222(uint8 data) { auto SA1::mmio_w2222(uint8 data) -> void {
mmio.ebmode = (data & 0x80); mmio.ebmode = (data & 0x80);
mmio.eb = (data & 0x07); mmio.eb = (data & 0x07);
} }
//(FXB) Super MMC bank F //(FXB) Super MMC bank F
void SA1::mmio_w2223(uint8 data) { auto SA1::mmio_w2223(uint8 data) -> void {
mmio.fbmode = (data & 0x80); mmio.fbmode = (data & 0x80);
mmio.fb = (data & 0x07); mmio.fb = (data & 0x07);
} }
//(BMAPS) S-CPU BW-RAM address mapping //(BMAPS) S-CPU BW-RAM address mapping
void SA1::mmio_w2224(uint8 data) { auto SA1::mmio_w2224(uint8 data) -> void {
mmio.sbm = (data & 0x1f); mmio.sbm = (data & 0x1f);
} }
//(BMAP) SA-1 BW-RAM address mapping //(BMAP) SA-1 BW-RAM address mapping
void SA1::mmio_w2225(uint8 data) { auto SA1::mmio_w2225(uint8 data) -> void {
mmio.sw46 = (data & 0x80); mmio.sw46 = (data & 0x80);
mmio.cbm = (data & 0x7f); mmio.cbm = (data & 0x7f);
} }
//(SWBE) S-CPU BW-RAM write enable //(SWBE) S-CPU BW-RAM write enable
void SA1::mmio_w2226(uint8 data) { auto SA1::mmio_w2226(uint8 data) -> void {
mmio.swen = (data & 0x80); mmio.swen = (data & 0x80);
} }
//(CWBE) SA-1 BW-RAM write enable //(CWBE) SA-1 BW-RAM write enable
void SA1::mmio_w2227(uint8 data) { auto SA1::mmio_w2227(uint8 data) -> void {
mmio.cwen = (data & 0x80); mmio.cwen = (data & 0x80);
} }
//(BWPA) BW-RAM write-protected area //(BWPA) BW-RAM write-protected area
void SA1::mmio_w2228(uint8 data) { auto SA1::mmio_w2228(uint8 data) -> void {
mmio.bwp = (data & 0x0f); mmio.bwp = (data & 0x0f);
} }
//(SIWP) S-CPU I-RAM write protection //(SIWP) S-CPU I-RAM write protection
void SA1::mmio_w2229(uint8 data) { auto SA1::mmio_w2229(uint8 data) -> void {
mmio.siwp = data; mmio.siwp = data;
} }
//(CIWP) SA-1 I-RAM write protection //(CIWP) SA-1 I-RAM write protection
void SA1::mmio_w222a(uint8 data) { auto SA1::mmio_w222a(uint8 data) -> void {
mmio.ciwp = data; mmio.ciwp = data;
} }
//(DCNT) DMA control //(DCNT) DMA control
void SA1::mmio_w2230(uint8 data) { auto SA1::mmio_w2230(uint8 data) -> void {
mmio.dmaen = (data & 0x80); mmio.dmaen = (data & 0x80);
mmio.dprio = (data & 0x40); mmio.dprio = (data & 0x40);
mmio.cden = (data & 0x20); mmio.cden = (data & 0x20);
@ -210,7 +210,7 @@ void SA1::mmio_w2230(uint8 data) {
} }
//(CDMA) character conversion DMA parameters //(CDMA) character conversion DMA parameters
void SA1::mmio_w2231(uint8 data) { auto SA1::mmio_w2231(uint8 data) -> void {
mmio.chdend = (data & 0x80); mmio.chdend = (data & 0x80);
mmio.dmasize = (data >> 2) & 7; mmio.dmasize = (data >> 2) & 7;
mmio.dmacb = (data & 0x03); mmio.dmacb = (data & 0x03);
@ -221,16 +221,16 @@ void SA1::mmio_w2231(uint8 data) {
} }
//(SDA) DMA source device start address //(SDA) DMA source device start address
void SA1::mmio_w2232(uint8 data) { mmio.dsa = (mmio.dsa & 0xffff00) | (data << 0); } auto SA1::mmio_w2232(uint8 data) -> void { mmio.dsa = (mmio.dsa & 0xffff00) | (data << 0); }
void SA1::mmio_w2233(uint8 data) { mmio.dsa = (mmio.dsa & 0xff00ff) | (data << 8); } auto SA1::mmio_w2233(uint8 data) -> void { mmio.dsa = (mmio.dsa & 0xff00ff) | (data << 8); }
void SA1::mmio_w2234(uint8 data) { mmio.dsa = (mmio.dsa & 0x00ffff) | (data << 16); } auto SA1::mmio_w2234(uint8 data) -> void { mmio.dsa = (mmio.dsa & 0x00ffff) | (data << 16); }
//(DDA) DMA destination start address //(DDA) DMA destination start address
void SA1::mmio_w2235(uint8 data) { auto SA1::mmio_w2235(uint8 data) -> void {
mmio.dda = (mmio.dda & 0xffff00) | (data << 0); mmio.dda = (mmio.dda & 0xffff00) | (data << 0);
} }
void SA1::mmio_w2236(uint8 data) { auto SA1::mmio_w2236(uint8 data) -> void {
mmio.dda = (mmio.dda & 0xff00ff) | (data << 8); mmio.dda = (mmio.dda & 0xff00ff) | (data << 8);
if(mmio.dmaen == true) { if(mmio.dmaen == true) {
@ -242,7 +242,7 @@ void SA1::mmio_w2236(uint8 data) {
} }
} }
void SA1::mmio_w2237(uint8 data) { auto SA1::mmio_w2237(uint8 data) -> void {
mmio.dda = (mmio.dda & 0x00ffff) | (data << 16); mmio.dda = (mmio.dda & 0x00ffff) | (data << 16);
if(mmio.dmaen == true) { if(mmio.dmaen == true) {
@ -253,23 +253,23 @@ void SA1::mmio_w2237(uint8 data) {
} }
//(DTC) DMA terminal counter //(DTC) DMA terminal counter
void SA1::mmio_w2238(uint8 data) { mmio.dtc = (mmio.dtc & 0xff00) | (data << 0); } auto SA1::mmio_w2238(uint8 data) -> void { mmio.dtc = (mmio.dtc & 0xff00) | (data << 0); }
void SA1::mmio_w2239(uint8 data) { mmio.dtc = (mmio.dtc & 0x00ff) | (data << 8); } auto SA1::mmio_w2239(uint8 data) -> void { mmio.dtc = (mmio.dtc & 0x00ff) | (data << 8); }
//(BBF) BW-RAM bitmap format //(BBF) BW-RAM bitmap format
void SA1::mmio_w223f(uint8 data) { auto SA1::mmio_w223f(uint8 data) -> void {
mmio.bbf = (data & 0x80); mmio.bbf = (data & 0x80);
} }
//(BRF) bitmap register files //(BRF) bitmap register files
void SA1::mmio_w2240(uint8 data) { mmio.brf[ 0] = data; } auto SA1::mmio_w2240(uint8 data) -> void { mmio.brf[ 0] = data; }
void SA1::mmio_w2241(uint8 data) { mmio.brf[ 1] = data; } auto SA1::mmio_w2241(uint8 data) -> void { mmio.brf[ 1] = data; }
void SA1::mmio_w2242(uint8 data) { mmio.brf[ 2] = data; } auto SA1::mmio_w2242(uint8 data) -> void { mmio.brf[ 2] = data; }
void SA1::mmio_w2243(uint8 data) { mmio.brf[ 3] = data; } auto SA1::mmio_w2243(uint8 data) -> void { mmio.brf[ 3] = data; }
void SA1::mmio_w2244(uint8 data) { mmio.brf[ 4] = data; } auto SA1::mmio_w2244(uint8 data) -> void { mmio.brf[ 4] = data; }
void SA1::mmio_w2245(uint8 data) { mmio.brf[ 5] = data; } auto SA1::mmio_w2245(uint8 data) -> void { mmio.brf[ 5] = data; }
void SA1::mmio_w2246(uint8 data) { mmio.brf[ 6] = data; } auto SA1::mmio_w2246(uint8 data) -> void { mmio.brf[ 6] = data; }
void SA1::mmio_w2247(uint8 data) { mmio.brf[ 7] = data; auto SA1::mmio_w2247(uint8 data) -> void { mmio.brf[ 7] = data;
if(mmio.dmaen == true) { if(mmio.dmaen == true) {
if(mmio.cden == 1 && mmio.cdsel == 0) { if(mmio.cden == 1 && mmio.cdsel == 0) {
dma_cc2(); dma_cc2();
@ -277,14 +277,14 @@ void SA1::mmio_w2247(uint8 data) { mmio.brf[ 7] = data;
} }
} }
void SA1::mmio_w2248(uint8 data) { mmio.brf[ 8] = data; } auto SA1::mmio_w2248(uint8 data) -> void { mmio.brf[ 8] = data; }
void SA1::mmio_w2249(uint8 data) { mmio.brf[ 9] = data; } auto SA1::mmio_w2249(uint8 data) -> void { mmio.brf[ 9] = data; }
void SA1::mmio_w224a(uint8 data) { mmio.brf[10] = data; } auto SA1::mmio_w224a(uint8 data) -> void { mmio.brf[10] = data; }
void SA1::mmio_w224b(uint8 data) { mmio.brf[11] = data; } auto SA1::mmio_w224b(uint8 data) -> void { mmio.brf[11] = data; }
void SA1::mmio_w224c(uint8 data) { mmio.brf[12] = data; } auto SA1::mmio_w224c(uint8 data) -> void { mmio.brf[12] = data; }
void SA1::mmio_w224d(uint8 data) { mmio.brf[13] = data; } auto SA1::mmio_w224d(uint8 data) -> void { mmio.brf[13] = data; }
void SA1::mmio_w224e(uint8 data) { mmio.brf[14] = data; } auto SA1::mmio_w224e(uint8 data) -> void { mmio.brf[14] = data; }
void SA1::mmio_w224f(uint8 data) { mmio.brf[15] = data; auto SA1::mmio_w224f(uint8 data) -> void { mmio.brf[15] = data;
if(mmio.dmaen == true) { if(mmio.dmaen == true) {
if(mmio.cden == 1 && mmio.cdsel == 0) { if(mmio.cden == 1 && mmio.cdsel == 0) {
dma_cc2(); dma_cc2();
@ -293,7 +293,7 @@ void SA1::mmio_w224f(uint8 data) { mmio.brf[15] = data;
} }
//(MCNT) arithmetic control //(MCNT) arithmetic control
void SA1::mmio_w2250(uint8 data) { auto SA1::mmio_w2250(uint8 data) -> void {
mmio.acm = (data & 0x02); mmio.acm = (data & 0x02);
mmio.md = (data & 0x01); mmio.md = (data & 0x01);
@ -301,24 +301,24 @@ void SA1::mmio_w2250(uint8 data) {
} }
//(MAL) multiplicand / dividend low //(MAL) multiplicand / dividend low
void SA1::mmio_w2251(uint8 data) { auto SA1::mmio_w2251(uint8 data) -> void {
mmio.ma = (mmio.ma & 0xff00) | data; mmio.ma = (mmio.ma & 0xff00) | data;
} }
//(MAH) multiplicand / dividend high //(MAH) multiplicand / dividend high
void SA1::mmio_w2252(uint8 data) { auto SA1::mmio_w2252(uint8 data) -> void {
mmio.ma = (data << 8) | (mmio.ma & 0x00ff); mmio.ma = (data << 8) | (mmio.ma & 0x00ff);
} }
//(MBL) multiplier / divisor low //(MBL) multiplier / divisor low
void SA1::mmio_w2253(uint8 data) { auto SA1::mmio_w2253(uint8 data) -> void {
mmio.mb = (mmio.mb & 0xff00) | data; mmio.mb = (mmio.mb & 0xff00) | data;
} }
//(MBH) multiplier / divisor high //(MBH) multiplier / divisor high
//multiplication / cumulative sum only resets MB //multiplication / cumulative sum only resets MB
//division resets both MA and MB //division resets both MA and MB
void SA1::mmio_w2254(uint8 data) { auto SA1::mmio_w2254(uint8 data) -> void {
mmio.mb = (data << 8) | (mmio.mb & 0x00ff); mmio.mb = (data << 8) | (mmio.mb & 0x00ff);
if(mmio.acm == 0) { if(mmio.acm == 0) {
@ -348,7 +348,7 @@ void SA1::mmio_w2254(uint8 data) {
} }
//(VBD) variable-length bit processing //(VBD) variable-length bit processing
void SA1::mmio_w2258(uint8 data) { auto SA1::mmio_w2258(uint8 data) -> void {
mmio.hl = (data & 0x80); mmio.hl = (data & 0x80);
mmio.vb = (data & 0x0f); mmio.vb = (data & 0x0f);
if(mmio.vb == 0) mmio.vb = 16; if(mmio.vb == 0) mmio.vb = 16;
@ -362,12 +362,12 @@ void SA1::mmio_w2258(uint8 data) {
} }
//(VDA) variable-length bit game pak ROM start address //(VDA) variable-length bit game pak ROM start address
void SA1::mmio_w2259(uint8 data) { mmio.va = (mmio.va & 0xffff00) | (data << 0); } auto SA1::mmio_w2259(uint8 data) -> void { mmio.va = (mmio.va & 0xffff00) | (data << 0); }
void SA1::mmio_w225a(uint8 data) { mmio.va = (mmio.va & 0xff00ff) | (data << 8); } auto SA1::mmio_w225a(uint8 data) -> void { mmio.va = (mmio.va & 0xff00ff) | (data << 8); }
void SA1::mmio_w225b(uint8 data) { mmio.va = (mmio.va & 0x00ffff) | (data << 16); mmio.vbit = 0; } auto SA1::mmio_w225b(uint8 data) -> void { mmio.va = (mmio.va & 0x00ffff) | (data << 16); mmio.vbit = 0; }
//(SFR) S-CPU flag read //(SFR) S-CPU flag read
uint8 SA1::mmio_r2300() { auto SA1::mmio_r2300() -> uint8 {
uint8 data; uint8 data;
data = mmio.cpu_irqfl << 7; data = mmio.cpu_irqfl << 7;
data |= mmio.cpu_ivsw << 6; data |= mmio.cpu_ivsw << 6;
@ -378,7 +378,7 @@ uint8 SA1::mmio_r2300() {
} }
//(CFR) SA-1 flag read //(CFR) SA-1 flag read
uint8 SA1::mmio_r2301() { auto SA1::mmio_r2301() -> uint8 {
uint8 data; uint8 data;
data = mmio.sa1_irqfl << 7; data = mmio.sa1_irqfl << 7;
data |= mmio.timer_irqfl << 6; data |= mmio.timer_irqfl << 6;
@ -389,29 +389,33 @@ uint8 SA1::mmio_r2301() {
} }
//(HCR) hcounter read //(HCR) hcounter read
uint8 SA1::mmio_r2302() { auto SA1::mmio_r2302() -> uint8 {
//latch counters //latch counters
mmio.hcr = status.hcounter >> 2; mmio.hcr = status.hcounter >> 2;
mmio.vcr = status.vcounter; mmio.vcr = status.vcounter;
return mmio.hcr >> 0; } return mmio.hcr >> 0;
uint8 SA1::mmio_r2303() { return mmio.hcr >> 8; } }
auto SA1::mmio_r2303() -> uint8 {
return mmio.hcr >> 8;
}
//(VCR) vcounter read //(VCR) vcounter read
uint8 SA1::mmio_r2304() { return mmio.vcr >> 0; } auto SA1::mmio_r2304() -> uint8 { return mmio.vcr >> 0; }
uint8 SA1::mmio_r2305() { return mmio.vcr >> 8; } auto SA1::mmio_r2305() -> uint8 { return mmio.vcr >> 8; }
//(MR) arithmetic result //(MR) arithmetic result
uint8 SA1::mmio_r2306() { return mmio.mr >> 0; } auto SA1::mmio_r2306() -> uint8 { return mmio.mr >> 0; }
uint8 SA1::mmio_r2307() { return mmio.mr >> 8; } auto SA1::mmio_r2307() -> uint8 { return mmio.mr >> 8; }
uint8 SA1::mmio_r2308() { return mmio.mr >> 16; } auto SA1::mmio_r2308() -> uint8 { return mmio.mr >> 16; }
uint8 SA1::mmio_r2309() { return mmio.mr >> 24; } auto SA1::mmio_r2309() -> uint8 { return mmio.mr >> 24; }
uint8 SA1::mmio_r230a() { return mmio.mr >> 32; } auto SA1::mmio_r230a() -> uint8 { return mmio.mr >> 32; }
//(OF) arithmetic overflow flag //(OF) arithmetic overflow flag
uint8 SA1::mmio_r230b() { return mmio.overflow << 7; } auto SA1::mmio_r230b() -> uint8 { return mmio.overflow << 7; }
//(VDPL) variable-length data read port low //(VDPL) variable-length data read port low
uint8 SA1::mmio_r230c() { auto SA1::mmio_r230c() -> uint8 {
uint32 data = (vbr_read(mmio.va + 0) << 0) uint32 data = (vbr_read(mmio.va + 0) << 0)
| (vbr_read(mmio.va + 1) << 8) | (vbr_read(mmio.va + 1) << 8)
| (vbr_read(mmio.va + 2) << 16); | (vbr_read(mmio.va + 2) << 16);
@ -420,7 +424,7 @@ uint8 SA1::mmio_r230c() {
} }
//(VDPH) variable-length data read port high //(VDPH) variable-length data read port high
uint8 SA1::mmio_r230d() { auto SA1::mmio_r230d() -> uint8 {
uint32 data = (vbr_read(mmio.va + 0) << 0) uint32 data = (vbr_read(mmio.va + 0) << 0)
| (vbr_read(mmio.va + 1) << 8) | (vbr_read(mmio.va + 1) << 8)
| (vbr_read(mmio.va + 2) << 16); | (vbr_read(mmio.va + 2) << 16);
@ -437,11 +441,11 @@ uint8 SA1::mmio_r230d() {
} }
//(VC) version code register //(VC) version code register
uint8 SA1::mmio_r230e() { auto SA1::mmio_r230e() -> uint8 {
return 0x01; //true value unknown return 0x01; //true value unknown
} }
uint8 SA1::mmio_read(unsigned addr) { auto SA1::mmio_read(uint addr) -> uint8 {
(co_active() == cpu.thread ? cpu.synchronizeCoprocessors() : synchronize_cpu()); (co_active() == cpu.thread ? cpu.synchronizeCoprocessors() : synchronize_cpu());
addr &= 0xffff; addr &= 0xffff;
@ -466,7 +470,7 @@ uint8 SA1::mmio_read(unsigned addr) {
return 0x00; return 0x00;
} }
void SA1::mmio_write(unsigned addr, uint8 data) { auto SA1::mmio_write(uint addr, uint8 data) -> void {
(co_active() == cpu.thread ? cpu.synchronizeCoprocessors() : synchronize_cpu()); (co_active() == cpu.thread ? cpu.synchronizeCoprocessors() : synchronize_cpu());
addr &= 0xffff; addr &= 0xffff;

View File

@ -1,5 +1,5 @@
uint8 mmio_read(unsigned addr); auto mmio_read(uint addr) -> uint8;
void mmio_write(unsigned addr, uint8 data); auto mmio_write(uint addr, uint8 data) -> void;
struct MMIO { struct MMIO {
//$2200 CCNT //$2200 CCNT
@ -63,19 +63,19 @@ struct MMIO {
//$2220 CXB //$2220 CXB
bool cbmode; bool cbmode;
unsigned cb; uint cb;
//$2221 DXB //$2221 DXB
bool dbmode; bool dbmode;
unsigned db; uint db;
//$2222 EXB //$2222 EXB
bool ebmode; bool ebmode;
unsigned eb; uint eb;
//$2223 FXB //$2223 FXB
bool fbmode; bool fbmode;
unsigned fb; uint fb;
//$2224 BMAPS //$2224 BMAPS
uint8 sbm; uint8 sbm;
@ -168,88 +168,88 @@ struct MMIO {
bool overflow; bool overflow;
} mmio; } mmio;
void mmio_w2200(uint8); //CCNT auto mmio_w2200(uint8) -> void; //CCNT
void mmio_w2201(uint8); //SIE auto mmio_w2201(uint8) -> void; //SIE
void mmio_w2202(uint8); //SIC auto mmio_w2202(uint8) -> void; //SIC
void mmio_w2203(uint8); //CRVL auto mmio_w2203(uint8) -> void; //CRVL
void mmio_w2204(uint8); //CRVH auto mmio_w2204(uint8) -> void; //CRVH
void mmio_w2205(uint8); //CNVL auto mmio_w2205(uint8) -> void; //CNVL
void mmio_w2206(uint8); //CNVH auto mmio_w2206(uint8) -> void; //CNVH
void mmio_w2207(uint8); //CIVL auto mmio_w2207(uint8) -> void; //CIVL
void mmio_w2208(uint8); //CIVH auto mmio_w2208(uint8) -> void; //CIVH
void mmio_w2209(uint8); //SCNT auto mmio_w2209(uint8) -> void; //SCNT
void mmio_w220a(uint8); //CIE auto mmio_w220a(uint8) -> void; //CIE
void mmio_w220b(uint8); //CIC auto mmio_w220b(uint8) -> void; //CIC
void mmio_w220c(uint8); //SNVL auto mmio_w220c(uint8) -> void; //SNVL
void mmio_w220d(uint8); //SNVH auto mmio_w220d(uint8) -> void; //SNVH
void mmio_w220e(uint8); //SIVL auto mmio_w220e(uint8) -> void; //SIVL
void mmio_w220f(uint8); //SIVH auto mmio_w220f(uint8) -> void; //SIVH
void mmio_w2210(uint8); //TMC auto mmio_w2210(uint8) -> void; //TMC
void mmio_w2211(uint8); //CTR auto mmio_w2211(uint8) -> void; //CTR
void mmio_w2212(uint8); //HCNTL auto mmio_w2212(uint8) -> void; //HCNTL
void mmio_w2213(uint8); //HCNTH auto mmio_w2213(uint8) -> void; //HCNTH
void mmio_w2214(uint8); //VCNTL auto mmio_w2214(uint8) -> void; //VCNTL
void mmio_w2215(uint8); //VCNTH auto mmio_w2215(uint8) -> void; //VCNTH
void mmio_w2220(uint8); //CXB auto mmio_w2220(uint8) -> void; //CXB
void mmio_w2221(uint8); //DXB auto mmio_w2221(uint8) -> void; //DXB
void mmio_w2222(uint8); //EXB auto mmio_w2222(uint8) -> void; //EXB
void mmio_w2223(uint8); //FXB auto mmio_w2223(uint8) -> void; //FXB
void mmio_w2224(uint8); //BMAPS auto mmio_w2224(uint8) -> void; //BMAPS
void mmio_w2225(uint8); //BMAP auto mmio_w2225(uint8) -> void; //BMAP
void mmio_w2226(uint8); //SBWE auto mmio_w2226(uint8) -> void; //SBWE
void mmio_w2227(uint8); //CBWE auto mmio_w2227(uint8) -> void; //CBWE
void mmio_w2228(uint8); //BWPA auto mmio_w2228(uint8) -> void; //BWPA
void mmio_w2229(uint8); //SIWP auto mmio_w2229(uint8) -> void; //SIWP
void mmio_w222a(uint8); //CIWP auto mmio_w222a(uint8) -> void; //CIWP
void mmio_w2230(uint8); //DCNT auto mmio_w2230(uint8) -> void; //DCNT
void mmio_w2231(uint8); //CDMA auto mmio_w2231(uint8) -> void; //CDMA
void mmio_w2232(uint8); //SDAL auto mmio_w2232(uint8) -> void; //SDAL
void mmio_w2233(uint8); //SDAH auto mmio_w2233(uint8) -> void; //SDAH
void mmio_w2234(uint8); //SDAB auto mmio_w2234(uint8) -> void; //SDAB
void mmio_w2235(uint8); //DDAL auto mmio_w2235(uint8) -> void; //DDAL
void mmio_w2236(uint8); //DDAH auto mmio_w2236(uint8) -> void; //DDAH
void mmio_w2237(uint8); //DDAB auto mmio_w2237(uint8) -> void; //DDAB
void mmio_w2238(uint8); //DTCL auto mmio_w2238(uint8) -> void; //DTCL
void mmio_w2239(uint8); //DTCH auto mmio_w2239(uint8) -> void; //DTCH
void mmio_w223f(uint8); //BBF auto mmio_w223f(uint8) -> void; //BBF
void mmio_w2240(uint8); //BRF0 auto mmio_w2240(uint8) -> void; //BRF0
void mmio_w2241(uint8); //BRF1 auto mmio_w2241(uint8) -> void; //BRF1
void mmio_w2242(uint8); //BRF2 auto mmio_w2242(uint8) -> void; //BRF2
void mmio_w2243(uint8); //BRF3 auto mmio_w2243(uint8) -> void; //BRF3
void mmio_w2244(uint8); //BRF4 auto mmio_w2244(uint8) -> void; //BRF4
void mmio_w2245(uint8); //BRF5 auto mmio_w2245(uint8) -> void; //BRF5
void mmio_w2246(uint8); //BRF6 auto mmio_w2246(uint8) -> void; //BRF6
void mmio_w2247(uint8); //BRF7 auto mmio_w2247(uint8) -> void; //BRF7
void mmio_w2248(uint8); //BRF8 auto mmio_w2248(uint8) -> void; //BRF8
void mmio_w2249(uint8); //BRF9 auto mmio_w2249(uint8) -> void; //BRF9
void mmio_w224a(uint8); //BRFA auto mmio_w224a(uint8) -> void; //BRFA
void mmio_w224b(uint8); //BRFB auto mmio_w224b(uint8) -> void; //BRFB
void mmio_w224c(uint8); //BRFC auto mmio_w224c(uint8) -> void; //BRFC
void mmio_w224d(uint8); //BRFD auto mmio_w224d(uint8) -> void; //BRFD
void mmio_w224e(uint8); //BRFE auto mmio_w224e(uint8) -> void; //BRFE
void mmio_w224f(uint8); //BRFF auto mmio_w224f(uint8) -> void; //BRFF
void mmio_w2250(uint8); //MCNT auto mmio_w2250(uint8) -> void; //MCNT
void mmio_w2251(uint8); //MAL auto mmio_w2251(uint8) -> void; //MAL
void mmio_w2252(uint8); //MAH auto mmio_w2252(uint8) -> void; //MAH
void mmio_w2253(uint8); //MBL auto mmio_w2253(uint8) -> void; //MBL
void mmio_w2254(uint8); //MBH auto mmio_w2254(uint8) -> void; //MBH
void mmio_w2258(uint8); //VBD auto mmio_w2258(uint8) -> void; //VBD
void mmio_w2259(uint8); //VDAL auto mmio_w2259(uint8) -> void; //VDAL
void mmio_w225a(uint8); //VDAH auto mmio_w225a(uint8) -> void; //VDAH
void mmio_w225b(uint8); //VDAB auto mmio_w225b(uint8) -> void; //VDAB
uint8 mmio_r2300(); //SFR auto mmio_r2300() -> uint8; //SFR
uint8 mmio_r2301(); //CFR auto mmio_r2301() -> uint8; //CFR
uint8 mmio_r2302(); //HCRL auto mmio_r2302() -> uint8; //HCRL
uint8 mmio_r2303(); //HCRH auto mmio_r2303() -> uint8; //HCRH
uint8 mmio_r2304(); //VCRL auto mmio_r2304() -> uint8; //VCRL
uint8 mmio_r2305(); //VCRH auto mmio_r2305() -> uint8; //VCRH
uint8 mmio_r2306(); //MR [00-07] auto mmio_r2306() -> uint8; //MR [00-07]
uint8 mmio_r2307(); //MR [08-15] auto mmio_r2307() -> uint8; //MR [08-15]
uint8 mmio_r2308(); //MR [16-23] auto mmio_r2308() -> uint8; //MR [16-23]
uint8 mmio_r2309(); //MR [24-31] auto mmio_r2309() -> uint8; //MR [24-31]
uint8 mmio_r230a(); //MR [32-40] auto mmio_r230a() -> uint8; //MR [32-40]
uint8 mmio_r230b(); //OF auto mmio_r230b() -> uint8; //OF
uint8 mmio_r230c(); //VDPL auto mmio_r230c() -> uint8; //VDPL
uint8 mmio_r230d(); //VDPH auto mmio_r230d() -> uint8; //VDPH
uint8 mmio_r230e(); //VC auto mmio_r230e() -> uint8; //VC

View File

@ -10,9 +10,9 @@ SA1 sa1;
#include "memory/memory.cpp" #include "memory/memory.cpp"
#include "mmio/mmio.cpp" #include "mmio/mmio.cpp"
void SA1::Enter() { sa1.enter(); } auto SA1::Enter() -> void { sa1.enter(); }
void SA1::enter() { auto SA1::enter() -> void {
while(true) { while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) { if(scheduler.sync == Scheduler::SynchronizeMode::All) {
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent); scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
@ -35,7 +35,7 @@ void SA1::enter() {
} }
} }
void SA1::op_irq() { auto SA1::op_irq() -> void {
op_read(regs.pc.d); op_read(regs.pc.d);
op_io(); op_io();
if(!regs.e) op_writestack(regs.pc.b); if(!regs.e) op_writestack(regs.pc.b);
@ -48,7 +48,7 @@ void SA1::op_irq() {
regs.p.d = 0; regs.p.d = 0;
} }
void SA1::last_cycle() { auto SA1::last_cycle() -> void {
if(mmio.sa1_nmi && !mmio.sa1_nmicl) { if(mmio.sa1_nmi && !mmio.sa1_nmicl) {
status.interrupt_pending = true; status.interrupt_pending = true;
regs.vector = mmio.cnv; regs.vector = mmio.cnv;
@ -75,11 +75,11 @@ void SA1::last_cycle() {
} }
} }
bool SA1::interrupt_pending() { auto SA1::interrupt_pending() -> bool {
return status.interrupt_pending; return status.interrupt_pending;
} }
void SA1::tick() { auto SA1::tick() -> void {
step(2); step(2);
if(++status.tick_counter == 0) synchronize_cpu(); if(++status.tick_counter == 0) synchronize_cpu();
@ -110,33 +110,33 @@ void SA1::tick() {
} }
} }
void SA1::trigger_irq() { auto SA1::trigger_irq() -> void {
mmio.timer_irqfl = true; mmio.timer_irqfl = true;
if(mmio.timer_irqen) mmio.timer_irqcl = 0; if(mmio.timer_irqen) mmio.timer_irqcl = 0;
} }
void SA1::init() { auto SA1::init() -> void {
} }
void SA1::load() { auto SA1::load() -> void {
} }
void SA1::unload() { auto SA1::unload() -> void {
rom.reset(); rom.reset();
iram.reset(); iram.reset();
bwram.reset(); bwram.reset();
} }
void SA1::power() { auto SA1::power() -> void {
regs.a = regs.x = regs.y = 0x0000; regs.a = regs.x = regs.y = 0x0000;
regs.s = 0x01ff; regs.s = 0x01ff;
} }
void SA1::reset() { auto SA1::reset() -> void {
create(SA1::Enter, system.cpuFrequency()); create(SA1::Enter, system.cpuFrequency());
cpubwram.dma = false; cpubwram.dma = false;
for(unsigned addr = 0; addr < iram.size(); addr++) { for(auto addr : range(iram.size())) {
iram.write(addr, 0x00); iram.write(addr, 0x00);
} }

View File

@ -1,8 +1,4 @@
struct SA1 : Processor::R65816, public Coprocessor { struct SA1 : Processor::R65816, public Coprocessor {
MappedRAM rom;
MappedRAM iram;
MappedRAM bwram;
#include "bus/bus.hpp" #include "bus/bus.hpp"
#include "dma/dma.hpp" #include "dma/dma.hpp"
#include "memory/memory.hpp" #include "memory/memory.hpp"
@ -18,22 +14,26 @@ struct SA1 : Processor::R65816, public Coprocessor {
uint16 hcounter; uint16 hcounter;
} status; } status;
static void Enter(); static auto Enter() -> void;
void enter(); auto enter() -> void;
void tick(); auto tick() -> void;
void op_irq(); auto op_irq() -> void;
alwaysinline void trigger_irq(); alwaysinline auto trigger_irq() -> void;
alwaysinline void last_cycle(); alwaysinline auto last_cycle() -> void;
alwaysinline bool interrupt_pending(); alwaysinline auto interrupt_pending() -> bool;
void init(); auto init() -> void;
void load(); auto load() -> void;
void unload(); auto unload() -> void;
void power(); auto power() -> void;
void reset(); auto reset() -> void;
void serialize(serializer&); auto serialize(serializer&) -> void;
MappedRAM rom;
MappedRAM iram;
MappedRAM bwram;
}; };
extern SA1 sa1; extern SA1 sa1;

View File

@ -1,4 +1,4 @@
void SA1::serialize(serializer& s) { auto SA1::serialize(serializer& s) -> void {
R65816::serialize(s); R65816::serialize(s);
Thread::serialize(s); Thread::serialize(s);

View File

@ -8,12 +8,12 @@
//input manager //input manager
void SDD1::Decomp::IM::init(unsigned offset_) { auto SDD1::Decomp::IM::init(uint offset_) -> void {
offset = offset_; offset = offset_;
bit_count = 4; bit_count = 4;
} }
uint8 SDD1::Decomp::IM::get_codeword(uint8 code_length) { auto SDD1::Decomp::IM::get_codeword(uint8 code_length) -> uint8 {
uint8 codeword; uint8 codeword;
uint8 comp_count; uint8 comp_count;
@ -70,7 +70,7 @@ const uint8 SDD1::Decomp::GCD::run_count[] = {
0x70, 0x30, 0x50, 0x10, 0x60, 0x20, 0x40, 0x00, 0x70, 0x30, 0x50, 0x10, 0x60, 0x20, 0x40, 0x00,
}; };
void SDD1::Decomp::GCD::get_run_count(uint8 code_number, uint8& mps_count, bool& lps_index) { auto SDD1::Decomp::GCD::get_run_count(uint8 code_number, uint8& mps_count, bool& lps_index) -> void {
uint8 codeword = self.im.get_codeword(code_number); uint8 codeword = self.im.get_codeword(code_number);
if(codeword & 0x80) { if(codeword & 0x80) {
@ -83,12 +83,12 @@ void SDD1::Decomp::GCD::get_run_count(uint8 code_number, uint8& mps_count, bool&
//bits generator //bits generator
void SDD1::Decomp::BG::init() { auto SDD1::Decomp::BG::init() -> void {
mps_count = 0; mps_count = 0;
lps_index = 0; lps_index = 0;
} }
uint8 SDD1::Decomp::BG::get_bit(bool& end_of_run) { auto SDD1::Decomp::BG::get_bit(bool& end_of_run) -> uint8 {
if(!(mps_count || lps_index)) self.gcd.get_run_count(code_number, mps_count, lps_index); if(!(mps_count || lps_index)) self.gcd.get_run_count(code_number, mps_count, lps_index);
uint8 bit; uint8 bit;
@ -142,14 +142,14 @@ const SDD1::Decomp::PEM::State SDD1::Decomp::PEM::evolution_table[33] = {
{7, 24, 22}, {7, 24, 22},
}; };
void SDD1::Decomp::PEM::init() { auto SDD1::Decomp::PEM::init() -> void {
for(unsigned i = 0; i < 32; i++) { for(auto n : range(32)) {
context_info[i].status = 0; context_info[n].status = 0;
context_info[i].mps = 0; context_info[n].mps = 0;
} }
} }
uint8 SDD1::Decomp::PEM::get_bit(uint8 context) { auto SDD1::Decomp::PEM::get_bit(uint8 context) -> uint8 {
ContextInfo& info = context_info[context]; ContextInfo& info = context_info[context];
uint8 current_status = info.status; uint8 current_status = info.status;
uint8 current_mps = info.mps; uint8 current_mps = info.mps;
@ -182,11 +182,11 @@ uint8 SDD1::Decomp::PEM::get_bit(uint8 context) {
//context model //context model
void SDD1::Decomp::CM::init(unsigned offset) { auto SDD1::Decomp::CM::init(uint offset) -> void {
bitplanes_info = sdd1.mmc_read(offset) & 0xc0; bitplanes_info = sdd1.mmc_read(offset) & 0xc0;
context_bits_info = sdd1.mmc_read(offset) & 0x30; context_bits_info = sdd1.mmc_read(offset) & 0x30;
bit_number = 0; bit_number = 0;
for(unsigned i = 0; i < 8; i++) previous_bitplane_bits[i] = 0; for(auto n : range(8)) previous_bitplane_bits[n] = 0;
switch(bitplanes_info) { switch(bitplanes_info) {
case 0x00: current_bitplane = 1; break; case 0x00: current_bitplane = 1; break;
case 0x40: current_bitplane = 7; break; case 0x40: current_bitplane = 7; break;
@ -194,7 +194,7 @@ void SDD1::Decomp::CM::init(unsigned offset) {
} }
} }
uint8 SDD1::Decomp::CM::get_bit() { auto SDD1::Decomp::CM::get_bit() -> uint8 {
switch(bitplanes_info) { switch(bitplanes_info) {
case 0x00: case 0x00:
current_bitplane ^= 0x01; current_bitplane ^= 0x01;
@ -230,12 +230,12 @@ uint8 SDD1::Decomp::CM::get_bit() {
//output logic //output logic
void SDD1::Decomp::OL::init(unsigned offset) { auto SDD1::Decomp::OL::init(uint offset) -> void {
bitplanes_info = sdd1.mmc_read(offset) & 0xc0; bitplanes_info = sdd1.mmc_read(offset) & 0xc0;
r0 = 0x01; r0 = 0x01;
} }
uint8 SDD1::Decomp::OL::decompress() { auto SDD1::Decomp::OL::decompress() -> uint8 {
switch(bitplanes_info) { switch(bitplanes_info) {
case 0x00: case 0x40: case 0x80: case 0x00: case 0x40: case 0x80:
if(r0 == 0) { if(r0 == 0) {
@ -257,7 +257,14 @@ uint8 SDD1::Decomp::OL::decompress() {
//core //core
void SDD1::Decomp::init(unsigned offset) { SDD1::Decomp::Decomp():
im(*this), gcd(*this),
bg0(*this, 0), bg1(*this, 1), bg2(*this, 2), bg3(*this, 3),
bg4(*this, 4), bg5(*this, 5), bg6(*this, 6), bg7(*this, 7),
pem(*this), cm(*this), ol(*this) {
}
auto SDD1::Decomp::init(uint offset) -> void {
im.init(offset); im.init(offset);
bg0.init(); bg0.init();
bg1.init(); bg1.init();
@ -272,13 +279,6 @@ void SDD1::Decomp::init(unsigned offset) {
ol.init(offset); ol.init(offset);
} }
uint8 SDD1::Decomp::read() { auto SDD1::Decomp::read() -> uint8 {
return ol.decompress(); return ol.decompress();
} }
SDD1::Decomp::Decomp():
im(*this), gcd(*this),
bg0(*this, 0), bg1(*this, 1), bg2(*this, 2), bg3(*this, 3),
bg4(*this, 4), bg5(*this, 5), bg6(*this, 6), bg7(*this, 7),
pem(*this), cm(*this), ol(*this) {
}

View File

@ -1,38 +1,43 @@
struct Decomp { struct Decomp {
struct IM { //input manager struct IM { //input manager
Decomp& self;
void init(unsigned offset);
uint8 get_codeword(uint8 code_length);
IM(SDD1::Decomp& self) : self(self) {} IM(SDD1::Decomp& self) : self(self) {}
auto init(uint offset) -> void;
auto get_codeword(uint8 code_length) -> uint8;
private: private:
unsigned offset; Decomp& self;
unsigned bit_count; uint offset;
uint bit_count;
}; };
struct GCD { //golomb-code decoder struct GCD { //golomb-code decoder
GCD(SDD1::Decomp& self) : self(self) {}
auto get_run_count(uint8 code_number, uint8& mps_count, bool& lps_index) -> void;
private:
Decomp& self; Decomp& self;
static const uint8 run_count[256]; static const uint8 run_count[256];
void get_run_count(uint8 code_number, uint8& mps_count, bool& lps_index);
GCD(SDD1::Decomp& self) : self(self) {}
}; };
struct BG { //bits generator struct BG { //bits generator
Decomp& self;
void init();
uint8 get_bit(bool& end_of_run);
BG(SDD1::Decomp& self, uint8 code_number) : self(self), code_number(code_number) {} BG(SDD1::Decomp& self, uint8 code_number) : self(self), code_number(code_number) {}
auto init() -> void;
auto get_bit(bool& end_of_run) -> uint8;
private: private:
Decomp& self;
const uint8 code_number; const uint8 code_number;
uint8 mps_count; uint8 mps_count;
bool lps_index; bool lps_index;
}; };
struct PEM { //probability estimation module struct PEM { //probability estimation module
Decomp& self;
void init();
uint8 get_bit(uint8 context);
PEM(SDD1::Decomp& self) : self(self) {} PEM(SDD1::Decomp& self) : self(self) {}
auto init() -> void;
auto get_bit(uint8 context) -> uint8;
private: private:
Decomp& self;
struct State { struct State {
uint8 code_number; uint8 code_number;
uint8 next_if_mps; uint8 next_if_mps;
@ -46,11 +51,12 @@ struct Decomp {
}; };
struct CM { //context model struct CM { //context model
Decomp& self;
void init(unsigned offset);
uint8 get_bit();
CM(SDD1::Decomp& self) : self(self) {} CM(SDD1::Decomp& self) : self(self) {}
auto init(uint offset) -> void;
uint8 get_bit();
private: private:
Decomp& self;
uint8 bitplanes_info; uint8 bitplanes_info;
uint8 context_bits_info; uint8 context_bits_info;
uint8 bit_number; uint8 bit_number;
@ -59,18 +65,19 @@ struct Decomp {
}; };
struct OL { //output logic struct OL { //output logic
Decomp& self;
void init(unsigned offset);
uint8 decompress();
OL(SDD1::Decomp& self) : self(self) {} OL(SDD1::Decomp& self) : self(self) {}
auto init(uint offset) -> void;
auto decompress() -> uint8;
private: private:
Decomp& self;
uint8 bitplanes_info; uint8 bitplanes_info;
uint8 r0, r1, r2; uint8 r0, r1, r2;
}; };
void init(unsigned offset);
uint8 read();
Decomp(); Decomp();
auto init(uint offset) -> void;
auto read() -> uint8;
IM im; IM im;
GCD gcd; GCD gcd;

View File

@ -7,7 +7,7 @@ SDD1 sdd1;
#include "decomp.cpp" #include "decomp.cpp"
#include "serialization.cpp" #include "serialization.cpp"
void SDD1::init() { auto SDD1::init() -> void {
} }
void SDD1::load() { void SDD1::load() {
@ -17,15 +17,15 @@ void SDD1::load() {
bus.map({&SDD1::read, &sdd1}, {&SDD1::write, &sdd1}, 0x80, 0xbf, 0x4300, 0x437f); bus.map({&SDD1::read, &sdd1}, {&SDD1::write, &sdd1}, 0x80, 0xbf, 0x4300, 0x437f);
} }
void SDD1::unload() { auto SDD1::unload() -> void {
rom.reset(); rom.reset();
ram.reset(); ram.reset();
} }
void SDD1::power() { auto SDD1::power() -> void {
} }
void SDD1::reset() { auto SDD1::reset() -> void {
sdd1_enable = 0x00; sdd1_enable = 0x00;
xfer_enable = 0x00; xfer_enable = 0x00;
dma_ready = false; dma_ready = false;
@ -35,13 +35,13 @@ void SDD1::reset() {
mmc[2] = 2 << 20; mmc[2] = 2 << 20;
mmc[3] = 3 << 20; mmc[3] = 3 << 20;
for(unsigned i = 0; i < 8; i++) { for(auto n : range(8)) {
dma[i].addr = 0; dma[n].addr = 0;
dma[i].size = 0; dma[n].size = 0;
} }
} }
uint8 SDD1::read(unsigned addr) { auto SDD1::read(uint addr) -> uint8 {
addr &= 0xffff; addr &= 0xffff;
if((addr & 0x4380) == 0x4300) { if((addr & 0x4380) == 0x4300) {
@ -58,11 +58,11 @@ uint8 SDD1::read(unsigned addr) {
return cpu.regs.mdr; return cpu.regs.mdr;
} }
void SDD1::write(unsigned addr, uint8 data) { auto SDD1::write(uint addr, uint8 data) -> void {
addr &= 0xffff; addr &= 0xffff;
if((addr & 0x4380) == 0x4300) { if((addr & 0x4380) == 0x4300) {
unsigned channel = (addr >> 4) & 7; uint channel = (addr >> 4) & 7;
switch(addr & 15) { switch(addr & 15) {
case 2: dma[channel].addr = (dma[channel].addr & 0xffff00) + (data << 0); break; case 2: dma[channel].addr = (dma[channel].addr & 0xffff00) + (data << 0); break;
case 3: dma[channel].addr = (dma[channel].addr & 0xff00ff) + (data << 8); break; case 3: dma[channel].addr = (dma[channel].addr & 0xff00ff) + (data << 8); break;
@ -85,7 +85,7 @@ void SDD1::write(unsigned addr, uint8 data) {
} }
} }
uint8 SDD1::mmc_read(unsigned addr) { auto SDD1::mmc_read(uint addr) -> uint8 {
return rom.read(mmc[(addr >> 20) & 3] + (addr & 0x0fffff)); return rom.read(mmc[(addr >> 20) & 3] + (addr & 0x0fffff));
} }
@ -107,7 +107,7 @@ uint8 SDD1::mmc_read(unsigned addr) {
// //
//the actual S-DD1 transfer can occur on any channel, but it is most likely limited to //the actual S-DD1 transfer can occur on any channel, but it is most likely limited to
//one transfer per $420b write (for spooling purposes). however, this is not known for certain. //one transfer per $420b write (for spooling purposes). however, this is not known for certain.
uint8 SDD1::mcurom_read(unsigned addr) { auto SDD1::mcurom_read(uint addr) -> uint8 {
if(addr < 0x400000) { //(addr & 0x408000) == 0x008000) { //$00-3f|80-bf:8000-ffff if(addr < 0x400000) { //(addr & 0x408000) == 0x008000) { //$00-3f|80-bf:8000-ffff
return rom.read(addr); return rom.read(addr);
//addr = ((addr & 0x7f0000) >> 1) | (addr & 0x7fff); //addr = ((addr & 0x7f0000) >> 1) | (addr & 0x7fff);
@ -117,10 +117,10 @@ uint8 SDD1::mcurom_read(unsigned addr) {
//$40-7f|c0-ff:0000-ffff (MMC) //$40-7f|c0-ff:0000-ffff (MMC)
if(sdd1_enable & xfer_enable) { if(sdd1_enable & xfer_enable) {
//at least one channel has S-DD1 decompression enabled ... //at least one channel has S-DD1 decompression enabled ...
for(unsigned i = 0; i < 8; i++) { for(auto n : range(8)) {
if(sdd1_enable & xfer_enable & (1 << i)) { if(sdd1_enable & xfer_enable & (1 << n)) {
//S-DD1 always uses fixed transfer mode, so address will not change during transfer //S-DD1 always uses fixed transfer mode, so address will not change during transfer
if(addr == dma[i].addr) { if(addr == dma[n].addr) {
if(!dma_ready) { if(!dma_ready) {
//prepare streaming decompression //prepare streaming decompression
decomp.init(addr); decomp.init(addr);
@ -129,9 +129,9 @@ uint8 SDD1::mcurom_read(unsigned addr) {
//fetch a decompressed byte; once finished, disable channel and invalidate buffer //fetch a decompressed byte; once finished, disable channel and invalidate buffer
uint8 data = decomp.read(); uint8 data = decomp.read();
if(--dma[i].size == 0) { if(--dma[n].size == 0) {
dma_ready = false; dma_ready = false;
xfer_enable &= ~(1 << i); xfer_enable &= ~(1 << n);
} }
return data; return data;
@ -144,10 +144,10 @@ uint8 SDD1::mcurom_read(unsigned addr) {
return mmc_read(addr); return mmc_read(addr);
} }
void SDD1::mcurom_write(unsigned addr, uint8 data) { auto SDD1::mcurom_write(uint addr, uint8 data) -> void {
} }
uint8 SDD1::mcuram_read(unsigned addr) { auto SDD1::mcuram_read(uint addr) -> uint8 {
if((addr & 0x60e000) == 0x006000) { //$00-3f|80-bf:6000-7fff if((addr & 0x60e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
return ram.read(addr & 0x1fff); return ram.read(addr & 0x1fff);
} }
@ -159,7 +159,7 @@ uint8 SDD1::mcuram_read(unsigned addr) {
return cpu.regs.mdr; return cpu.regs.mdr;
} }
void SDD1::mcuram_write(unsigned addr, uint8 data) { auto SDD1::mcuram_write(uint addr, uint8 data) -> void {
if((addr & 0x60e000) == 0x006000) { //$00-3f|80-bf:6000-7fff if((addr & 0x60e000) == 0x006000) { //$00-3f|80-bf:6000-7fff
return ram.write(addr & 0x1fff, data); return ram.write(addr & 0x1fff, data);
} }

View File

@ -1,34 +1,34 @@
struct SDD1 { struct SDD1 {
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;
auto reset() -> void;
auto read(uint addr) -> uint8;
auto write(uint addr, uint8 data) -> void;
auto mmc_read(uint addr) -> uint8;
auto mcurom_read(uint addr) -> uint8;
auto mcurom_write(uint addr, uint8 data) -> void;
auto mcuram_read(uint addr) -> uint8;
auto mcuram_write(uint addr, uint8 data) -> void;
auto serialize(serializer&) -> void;
MappedRAM rom; MappedRAM rom;
MappedRAM ram; MappedRAM ram;
void init();
void load();
void unload();
void power();
void reset();
uint8 read(unsigned addr);
void write(unsigned addr, uint8 data);
uint8 mmc_read(unsigned addr);
uint8 mcurom_read(unsigned addr);
void mcurom_write(unsigned addr, uint8 data);
uint8 mcuram_read(unsigned addr);
void mcuram_write(unsigned addr, uint8 data);
void serialize(serializer&);
private: private:
uint8 sdd1_enable; //channel bit-mask uint8 sdd1_enable; //channel bit-mask
uint8 xfer_enable; //channel bit-mask uint8 xfer_enable; //channel bit-mask
bool dma_ready; //used to initialize decompression module bool dma_ready; //used to initialize decompression module
unsigned mmc[4]; //memory map controller ROM indices uint mmc[4]; //memory map controller ROM indices
struct { struct {
unsigned addr; //$43x2-$43x4 -- DMA transfer address uint addr; //$43x2-$43x4 -- DMA transfer address
uint16 size; //$43x5-$43x6 -- DMA transfer size uint16 size; //$43x5-$43x6 -- DMA transfer size
} dma[8]; } dma[8];

View File

@ -1,4 +1,4 @@
void SDD1::serialize(serializer& s) { auto SDD1::serialize(serializer& s) -> void {
s.array(ram.data(), ram.size()); s.array(ram.data(), ram.size());
s.integer(sdd1_enable); s.integer(sdd1_enable);
@ -6,7 +6,7 @@ void SDD1::serialize(serializer& s) {
s.integer(dma_ready); s.integer(dma_ready);
s.array(mmc); s.array(mmc);
for(unsigned n = 0; n < 8; n++) { for(auto n : range(8)) {
s.integer(dma[n].addr); s.integer(dma[n].addr);
s.integer(dma[n].size); s.integer(dma[n].size);
} }

View File

@ -1,4 +1,4 @@
uint4 SharpRTC::rtc_read(uint4 addr) { auto SharpRTC::rtc_read(uint4 addr) -> uint4 {
switch(addr) { switch(addr) {
case 0: return second % 10; case 0: return second % 10;
case 1: return second / 10; case 1: return second / 10;
@ -17,7 +17,7 @@ uint4 SharpRTC::rtc_read(uint4 addr) {
} }
} }
void SharpRTC::rtc_write(uint4 addr, uint4 data) { auto SharpRTC::rtc_write(uint4 addr, uint4 data) -> void {
switch(addr) { switch(addr) {
case 0: second = second / 10 * 10 + data; break; case 0: second = second / 10 * 10 + data; break;
case 1: second = data * 10 + second % 10; break; case 1: second = data * 10 + second % 10; break;
@ -35,14 +35,14 @@ void SharpRTC::rtc_write(uint4 addr, uint4 data) {
} }
} }
void SharpRTC::load(const uint8* data) { auto SharpRTC::load(const uint8* data) -> void {
for(unsigned byte = 0; byte < 8; byte++) { for(auto byte : range(8)) {
rtc_write(byte * 2 + 0, data[byte] >> 0); rtc_write(byte * 2 + 0, data[byte] >> 0);
rtc_write(byte * 2 + 1, data[byte] >> 4); rtc_write(byte * 2 + 1, data[byte] >> 4);
} }
uint64 timestamp = 0; uint64 timestamp = 0;
for(unsigned byte = 0; byte < 8; byte++) { for(auto byte : range(8)) {
timestamp |= data[8 + byte] << (byte * 8); timestamp |= data[8 + byte] << (byte * 8);
} }
@ -53,14 +53,14 @@ void SharpRTC::load(const uint8* data) {
while(diff--) tick_second(); while(diff--) tick_second();
} }
void SharpRTC::save(uint8* data) { auto SharpRTC::save(uint8* data) -> void {
for(unsigned byte = 0; byte < 8; byte++) { for(auto byte : range(8)) {
data[byte] = rtc_read(byte * 2 + 0) << 0; data[byte] = rtc_read(byte * 2 + 0) << 0;
data[byte] |= rtc_read(byte * 2 + 1) << 4; data[byte] |= rtc_read(byte * 2 + 1) << 4;
} }
uint64 timestamp = (uint64)time(0); uint64 timestamp = (uint64)time(nullptr);
for(unsigned byte = 0; byte < 8; byte++) { for(auto byte : range(8)) {
data[8 + byte] = timestamp; data[8 + byte] = timestamp;
timestamp >>= 8; timestamp >>= 8;
} }

View File

@ -1,7 +1,7 @@
void SharpRTC::serialize(serializer& s) { auto SharpRTC::serialize(serializer& s) -> void {
Thread::serialize(s); Thread::serialize(s);
s.integer((unsigned&)rtc_state); s.integer((uint&)rtc_state);
s.integer(rtc_index); s.integer(rtc_index);
s.integer(second); s.integer(second);

View File

@ -1,47 +1,47 @@
struct SharpRTC : Coprocessor { struct SharpRTC : Coprocessor {
static void Enter(); static auto Enter() -> void;
void enter(); auto enter() -> void;
void init(); auto init() -> void;
void load(); auto load() -> void;
void unload(); auto unload() -> void;
void power(); auto power() -> void;
void reset(); auto reset() -> void;
void sync(); auto sync() -> void;
uint8 read(unsigned addr); auto read(uint addr) -> uint8;
void write(unsigned addr, uint8 data); auto write(uint addr, uint8 data) -> void;
void serialize(serializer&); auto serialize(serializer&) -> void;
enum class State : unsigned { Ready, Command, Read, Write } rtc_state; enum class State : uint { Ready, Command, Read, Write } rtc_state;
signed rtc_index; int rtc_index;
unsigned second; uint second;
unsigned minute; uint minute;
unsigned hour; uint hour;
unsigned day; uint day;
unsigned month; uint month;
unsigned year; uint year;
unsigned weekday; uint weekday;
//memory.cpp //memory.cpp
uint4 rtc_read(uint4 addr); auto rtc_read(uint4 addr) -> uint4;
void rtc_write(uint4 addr, uint4 data); auto rtc_write(uint4 addr, uint4 data) -> void;
void load(const uint8* data); auto load(const uint8* data) -> void;
void save(uint8* data); auto save(uint8* data) -> void;
//time.cpp //time.cpp
static const unsigned daysinmonth[12]; static const uint daysinmonth[12];
void tick_second(); auto tick_second() -> void;
void tick_minute(); auto tick_minute() -> void;
void tick_hour(); auto tick_hour() -> void;
void tick_day(); auto tick_day() -> void;
void tick_month(); auto tick_month() -> void;
void tick_year(); auto tick_year() -> void;
unsigned calculate_weekday(unsigned year, unsigned month, unsigned day); auto calculate_weekday(uint year, uint month, uint day) -> uint;
}; };
extern SharpRTC sharprtc; extern SharpRTC sharprtc;

View File

@ -1,25 +1,25 @@
const unsigned SharpRTC::daysinmonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; const uint SharpRTC::daysinmonth[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
void SharpRTC::tick_second() { auto SharpRTC::tick_second() -> void {
if(++second < 60) return; if(++second < 60) return;
second = 0; second = 0;
tick_minute(); tick_minute();
} }
void SharpRTC::tick_minute() { auto SharpRTC::tick_minute() -> void {
if(++minute < 60) return; if(++minute < 60) return;
minute = 0; minute = 0;
tick_hour(); tick_hour();
} }
void SharpRTC::tick_hour() { auto SharpRTC::tick_hour() -> void {
if(++hour < 24) return; if(++hour < 24) return;
hour = 0; hour = 0;
tick_day(); tick_day();
} }
void SharpRTC::tick_day() { auto SharpRTC::tick_day() -> void {
unsigned days = daysinmonth[month % 12]; uint days = daysinmonth[month % 12];
//add one day for leap years //add one day for leap years
if(year % 400 == 0) days++; if(year % 400 == 0) days++;
@ -31,13 +31,13 @@ void SharpRTC::tick_day() {
tick_month(); tick_month();
} }
void SharpRTC::tick_month() { auto SharpRTC::tick_month() -> void {
if(month++ < 12) return; if(month++ < 12) return;
month = 1; month = 1;
tick_year(); tick_year();
} }
void SharpRTC::tick_year() { auto SharpRTC::tick_year() -> void {
year++; year++;
year = (uint12)year; year = (uint12)year;
} }
@ -45,9 +45,9 @@ void SharpRTC::tick_year() {
//returns day of week for specified date //returns day of week for specified date
//eg 0 = Sunday, 1 = Monday, ... 6 = Saturday //eg 0 = Sunday, 1 = Monday, ... 6 = Saturday
//usage: calculate_weekday(2008, 1, 1) returns weekday of January 1st, 2008 //usage: calculate_weekday(2008, 1, 1) returns weekday of January 1st, 2008
unsigned SharpRTC::calculate_weekday(unsigned year, unsigned month, unsigned day) { auto SharpRTC::calculate_weekday(uint year, uint month, uint day) -> uint {
unsigned y = 1000, m = 1; //SharpRTC epoch is 1000-01-01 uint y = 1000, m = 1; //SharpRTC epoch is 1000-01-01
unsigned sum = 0; //number of days passed since epoch uint sum = 0; //number of days passed since epoch
year = max(1000, year); year = max(1000, year);
month = max(1, min(12, month)); month = max(1, min(12, month));
@ -64,7 +64,7 @@ unsigned SharpRTC::calculate_weekday(unsigned year, unsigned month, unsigned day
} }
while(m < month) { while(m < month) {
unsigned days = daysinmonth[m - 1]; uint days = daysinmonth[m - 1];
bool leapyearmonth = false; bool leapyearmonth = false;
if(days == 28) { if(days == 28) {
if(y % 4 == 0) { if(y % 4 == 0) {

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