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 {
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 License = "GPLv3";
static const string Website = "http://byuu.org/";

View File

@ -94,10 +94,10 @@ Board::Board(Markup::Node& document) {
auto crom = cartridge["chr/rom"];
auto cram = cartridge["chr/ram"];
prgrom.size = prom["size"].decimal();
prgram.size = pram["size"].decimal();
chrrom.size = crom["size"].decimal();
chrram.size = cram["size"].decimal();
prgrom.size = prom["size"].natural();
prgram.size = pram["size"].natural();
chrrom.size = crom["size"].natural();
chrram.size = cram["size"].natural();
if(prgrom.size) prgrom.data = new uint8[prgrom.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) {
settings.pinout.a0 = 1 << document["cartridge/chip/pinout/a0"].decimal();
settings.pinout.a1 = 1 << document["cartridge/chip/pinout/a1"].decimal();
settings.pinout.a0 = 1 << document["cartridge/chip/pinout/a0"].natural();
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) {
settings.pinout.a0 = 1 << document["cartridge/chip/pinout/a0"].decimal();
settings.pinout.a1 = 1 << document["cartridge/chip/pinout/a1"].decimal();
settings.pinout.a0 = 1 << document["cartridge/chip/pinout/a0"].natural();
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 ram = document["cartridge/ram"];
romsize = rom["size"].decimal();
romsize = rom["size"].natural();
romdata = allocate<uint8>(romsize, 0xff);
ramsize = ram["size"].decimal();
ramsize = ram["size"].natural();
ramdata = allocate<uint8>(ramsize, 0xff);
//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});
}
information.romsize = rom["size"].decimal();
information.ramsize = ram["size"].decimal();
information.romsize = rom["size"].natural();
information.ramsize = ram["size"].natural();
information.battery = (bool)ram["name"];
switch(information.mapper) { default:

View File

@ -32,10 +32,10 @@ void APU::Noise::clockenvelope() {
uint8 APU::Noise::read(unsigned addr) const {
switch(addr) {
case 1: return (length << 0);
case 1: return 0;
case 2: return (envelope.frequency << 0) | (envelope.direction << 3) | (envelope.volume << 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[3] << 7)
);
case 2: return (
(enable[0] << 0)
| (enable[1] << 1)
| (enable[2] << 2)
| (enable[3] << 3)
| (masterenable << 7)
);
case 2: return (masterenable << 7);
}
}

View File

@ -25,10 +25,10 @@ void APU::Square1::clocksweep() {
uint8 APU::Square1::read(unsigned addr) const {
switch(addr) {
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 3: return (frequency << 0);
case 4: return (frequency >> 8) | (counter << 6) | (initialize << 7);
case 3: return 0;
case 4: return (counter << 6);
}
}

View File

@ -1,9 +1,9 @@
uint8 APU::Square2::read(unsigned addr) const {
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 3: return (frequency >> 0);
case 4: return (frequency >> 8) | (counter << 6) | (initialize << 7);
case 3: return 0;
case 4: return (counter << 6);
}
}

View File

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

View File

@ -46,14 +46,14 @@ auto Cartridge::load() -> void {
hasFLASH = false;
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);
}
if(auto info = document["cartridge/sram"]) {
hasSRAM = true;
sram.size = min(32 * 1024, info["size"].decimal());
sram.size = min(32 * 1024, info["size"].natural());
sram.mask = sram.size - 1;
for(auto n : range(sram.size)) sram.data[n] = 0xff;
@ -63,7 +63,7 @@ auto Cartridge::load() -> void {
if(auto info = document["cartridge/eeprom"]) {
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;
if(eeprom.size == 0) eeprom.size = 8192, eeprom.bits = 0; //auto-detect size
eeprom.mask = mrom.size > 16 * 1024 * 1024 ? 0x0fffff00 : 0x0f000000;
@ -76,8 +76,8 @@ auto Cartridge::load() -> void {
if(auto info = document["cartridge/flash"]) {
hasFLASH = true;
flash.id = info["id"].decimal();
flash.size = min(128 * 1024, info["size"].decimal());
flash.id = info["id"].natural();
flash.size = min(128 * 1024, info["size"].natural());
for(auto n : range(flash.size)) flash.data[n] = 0xff;
//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 0x040000d2: case 0x040000d3:
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];
unsigned shift = (addr & 1) * 8;
bool enable = dma.control.enable;

View File

@ -41,6 +41,8 @@ uint8 PPU::read(uint32 addr) {
case 0x04000052: return regs.blend.eva;
case 0x04000053: return regs.blend.evb;
//BLDY is write-only
}
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;
//BLDALPHA
case 0x04000052: regs.blend.eva = std::min(16, byte & 0x1f); return;
case 0x04000053: regs.blend.evb = std::min(16, byte & 0x1f); return;
case 0x04000052: regs.blend.eva = byte & 0x1f; return;
case 0x04000053: regs.blend.evb = byte & 0x1f; return;
//BLDY
case 0x04000054: regs.blend.evy = std::min(16, byte & 0x1f); return;
case 0x04000054: regs.blend.evy = byte & 0x1f; return;
case 0x04000055: return;
}

View File

@ -62,6 +62,7 @@ PPU::Registers::BackgroundControl::operator uint16() const {
return (
(priority << 0)
| (characterbaseblock << 2)
| (unused << 4)
| (mosaic << 6)
| (colormode << 7)
| (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) {
eva = min(16, eva);
evb = min(16, evb);
uint5 ar = above >> 0, ag = above >> 5, ab = above >> 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;
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("italic")) traits |= NSItalicFontMask;
if(part(2).ifind("narrow")) traits |= NSNarrowFontMask;

View File

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

View File

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

View File

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

View File

@ -256,6 +256,13 @@ auto mObject::parentWindow(bool recursive) const -> mWindow* {
}
#endif
auto mObject::property(const string& name) const -> string {
if(auto property = state.properties.find({name})) {
return property->value();
}
return {};
}
auto mObject::remove() -> type& {
signal(remove);
return *this;
@ -295,6 +302,16 @@ auto mObject::setParent(mObject* parent, signed offset) -> type& {
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& {
state.visible = visible;
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(); \
} \
auto property(const string& name) const { return self().property(name); } \
auto remove() { return self().remove(), *this; } \
auto setEnabled(bool enabled = true) { return self().setEnabled(enabled), *this; } \
auto setFocused() { return self().setFocused(), *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 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 {
if(path.empty()) return {};
auto paths = path.split("/");
unsigned position = decimal(paths.takeFirst());
unsigned position = paths.takeFirst().natural();
if(position >= itemCount()) return {};
if(paths.empty()) return state.items[position];
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 {
if(path.empty()) return {};
auto paths = path.split("/");
unsigned position = decimal(paths.takeFirst());
unsigned position = paths.takeFirst().natural();
if(position >= itemCount()) return {};
if(paths.empty()) return state.items[position];
return state.items[position]->item(paths.merge("/"));

View File

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

View File

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

View File

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

View File

@ -2,10 +2,11 @@
#define NALL_ATOI_HPP
#include <nall/stdint.hpp>
#include <nall/varint.hpp>
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 (
*s == '0' || *s == '1' ? binary_(s + 1, (sum << 1) | *s - '0') :
*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 (
*s >= '0' && *s <= '7' ? octal_(s + 1, (sum << 3) | *s - '0') :
*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 (
*s >= '0' && *s <= '9' ? decimal_(s + 1, (sum * 10) + *s - '0') :
*s == '\'' ? decimal_(s + 1, sum) :
*s >= '0' && *s <= '9' ? natural_(s + 1, (sum * 10) + *s - '0') :
*s == '\'' ? natural_(s + 1, 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 (
*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 (
*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 (
*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 (
*s == '+' ? +decimal_(s + 1) :
*s == '-' ? -decimal_(s + 1) :
decimal_(s)
*s == '+' ? +natural_(s + 1) :
*s == '-' ? -natural_(s + 1) :
natural_(s)
);
}
constexpr inline auto decimal(const char* s) -> uintmax_t {
constexpr inline auto natural(const char* s) -> uintmax {
return (
decimal_(s)
natural_(s)
);
}
constexpr inline auto hex(const char* s) -> uintmax_t {
constexpr inline auto hex(const char* s) -> uintmax {
return (
*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 {
string name;
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;
vector<Node> children;
@ -21,9 +21,9 @@ struct Node {
auto get() const -> string {
switch(type) {
case Type::Bool: return {*(bool*)data};
case Type::Signed: return {*(signed*)data};
case Type::Unsigned: return {*(unsigned*)data};
case Type::Boolean: return {*(bool*)data};
case Type::Integer: return {*(int*)data};
case Type::Natural: return {*(uint*)data};
case Type::Double: return {*(double*)data};
case Type::String: return {*(string*)data};
}
@ -32,18 +32,18 @@ struct Node {
auto set(const string& value) -> void {
switch(type) {
case Type::Bool: *(bool*)data = (value != "false"); break;
case Type::Signed: *(signed*)data = integer(value); break;
case Type::Unsigned: *(unsigned*)data = decimal(value); break;
case Type::Boolean: *(bool*)data = (value != "false"); break;
case Type::Integer: *(int*)data = integer(value); break;
case Type::Natural: *(uint*)data = natural(value); break;
case Type::Double: *(double*)data = real(value); break;
case Type::String: *(string*)data = value; break;
}
}
auto assign() { type = Type::Null; data = nullptr; }
auto assign(bool& bind) { type = Type::Bool; data = (void*)&bind; }
auto assign(signed& bind) { type = Type::Signed; data = (void*)&bind; }
auto assign(unsigned& bind) { type = Type::Unsigned; data = (void*)&bind; }
auto assign(bool& bind) { type = Type::Boolean; data = (void*)&bind; }
auto assign(int& bind) { type = Type::Integer; 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(string& bind) { type = Type::String; data = (void*)&bind; }
auto assign(const Node& node) { operator=(node); }
@ -80,10 +80,10 @@ struct Node {
auto save(file& fp, unsigned depth = 0) -> void {
for(auto& child : children) {
if(child.desc) {
for(unsigned n = 0; n < depth; n++) fp.print(" ");
for(auto n : range(depth)) fp.print(" ");
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);
if(!child.empty()) fp.print(": ", child.get());
fp.print("\n");

View File

@ -40,7 +40,7 @@ struct ODBC {
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);
uint64_t value = 0;
SQLGetData(statement(), 1 + column, SQL_C_UBIGINT, &value, 0, nullptr);
@ -79,7 +79,7 @@ struct ODBC {
}
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 text() -> string { return text(_output++); }
auto data() -> vector<uint8_t> { return data(_output++); }

View File

@ -43,7 +43,7 @@ struct SQLite3 {
return sqlite3_column_int64(statement(), column);
}
auto decimal(unsigned column) -> uint64_t {
auto natural(unsigned column) -> uint64_t {
return sqlite3_column_int64(statement(), column);
}
@ -70,7 +70,7 @@ struct SQLite3 {
}
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 text() -> string { return text(_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 return false;
setResponseType(decimal(response));
setResponseType(natural(response));
for(auto& header : headers) {
if(header.beginsWith(" ") || header.beginsWith("\t")) continue;
@ -156,7 +156,7 @@ auto Response::hasBody() const -> bool {
}
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(hasData()) return data().size();
if(hasFile()) return file::size(file());

View File

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

View File

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

View File

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

View File

@ -150,8 +150,8 @@ public:
auto end() const -> const char* { return &data()[size()]; }
//atoi.hpp
inline auto integer() const -> intmax_t;
inline auto decimal() const -> uintmax_t;
inline auto integer() const -> intmax;
inline auto natural() const -> uintmax;
inline auto real() const -> double;
//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; }
unsigned index = nall::decimal(&data[x + 1]);
unsigned index = nall::natural(&data[x + 1]);
if(index >= params.size()) { x++; continue; }
unsigned sourceSize = y - x;

View File

@ -41,10 +41,10 @@ auto ManagedNode::_evaluate(string query) const -> bool {
switch(comparator) {
case Comparator::EQ: if(data.match(side(1)) == true) 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::LE: if(data.decimal() <= side(1).decimal()) continue; break;
case Comparator::GT: if(data.decimal() > side(1).decimal()) continue; break;
case Comparator::GE: if(data.decimal() >= side(1).decimal()) continue; break;
case Comparator::LT: if(data.natural() < side(1).natural()) continue; break;
case Comparator::LE: if(data.natural() <= side(1).natural()) continue; break;
case Comparator::GT: if(data.natural() > side(1).natural()) continue; break;
case Comparator::GE: if(data.natural() >= side(1).natural()) continue; break;
}
return false;
@ -65,10 +65,10 @@ auto ManagedNode::_find(const string& query) const -> vector<Node> {
name = p(0);
if(p(1).find("-")) {
p = p(1).split("-", 1L);
lo = p(0).empty() ? 0u : p(0).decimal();
hi = p(1).empty() ? ~0u : p(1).decimal();
lo = p(0).empty() ? 0u : p(0).natural();
hi = p(1).empty() ? ~0u : p(1).natural();
} 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 boolean() const -> bool { return text() == "true"; }
auto integer() const -> intmax_t { return text().integer(); }
auto decimal() const -> uintmax_t { return text().decimal(); }
auto integer() const -> intmax { return text().integer(); }
auto natural() const -> uintmax { return text().natural(); }
auto setName(const string& name = "") -> Node& { shared->_name = name; 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/serializer.hpp>
#include <nall/stdint.hpp>
#include <nall/traits.hpp>
namespace nall {
@ -209,6 +208,8 @@ using int61 = nall::int_t<61>;
using int62 = nall::int_t<62>;
using int63 = nall::int_t<63>;
using int64 = int64_t;
using intmax = intmax_t;
using intptr = intptr_t;
using uint1 = nall::uint_t<1>;
using uint2 = nall::uint_t<2>;
@ -274,6 +275,8 @@ using uint61 = nall::uint_t<61>;
using uint62 = nall::uint_t<62>;
using uint63 = nall::uint_t<63>;
using uint64 = uint64_t;
using uintmax = uintmax_t;
using uintptr = uintptr_t;
#if defined(__SIZEOF_INT128__)
using int128 = int128_t;

View File

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

View File

@ -19,7 +19,7 @@ auto OpenGL::shader(const string& pathname) -> void {
}
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() == "filter") filter = glrFilter(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();
if(node.name() == "width") {
if(text.endsWith("%")) relativeWidth = real(text.rtrim("%", 1L)) / 100.0;
else absoluteWidth = text.decimal();
else absoluteWidth = text.natural();
}
if(node.name() == "height") {
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();
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;
else absoluteHeight = h.decimal();
else absoluteHeight = h.natural();
format = glrFormat(node["format"].text());

View File

@ -137,7 +137,7 @@ auto Cartridge::loadSatellaview() -> void {
auto rom = document["cartridge/rom"];
if(rom["name"]) {
unsigned size = rom["size"].decimal();
unsigned size = rom["size"].natural();
satellaviewcartridge.memory.map(allocate<uint8>(size, 0xff), size);
interface->loadRequest(ID::SatellaviewROM, rom["name"].text(), true);
@ -154,13 +154,13 @@ auto Cartridge::loadSufamiTurboA() -> void {
auto ram = document["cartridge/ram"];
if(rom["name"]) {
unsigned size = rom["size"].decimal();
unsigned size = rom["size"].natural();
sufamiturboA.rom.map(allocate<uint8>(size, 0xff), size);
interface->loadRequest(ID::SufamiTurboSlotAROM, rom["name"].text(), true);
}
if(ram["name"]) {
unsigned size = ram["size"].decimal();
unsigned size = ram["size"].natural();
sufamiturboA.ram.map(allocate<uint8>(size, 0xff), size);
interface->loadRequest(ID::SufamiTurboSlotARAM, ram["name"].text(), false);
memory.append({ID::SufamiTurboSlotARAM, ram["name"].text()});
@ -180,13 +180,13 @@ auto Cartridge::loadSufamiTurboB() -> void {
auto ram = document["cartridge/ram"];
if(rom["name"]) {
unsigned size = rom["size"].decimal();
unsigned size = rom["size"].natural();
sufamiturboB.rom.map(allocate<uint8>(size, 0xff), size);
interface->loadRequest(ID::SufamiTurboSlotBROM, rom["name"].text(), true);
}
if(ram["name"]) {
unsigned size = ram["size"].decimal();
unsigned size = ram["size"].natural();
sufamiturboB.ram.map(allocate<uint8>(size, 0xff), size);
interface->loadRequest(ID::SufamiTurboSlotBRAM, ram["name"].text(), false);
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 {
m.addr = map["address"].text();
m.size = map["size"].decimal();
m.base = map["base"].decimal();
m.mask = map["mask"].decimal();
m.size = map["size"].natural();
m.base = map["base"].natural();
m.mask = map["mask"].natural();
}
auto Cartridge::parseMarkupMemory(MappedRAM& ram, Markup::Node node, unsigned id, bool writable) -> void {
string name = node["name"].text();
unsigned size = node["size"].decimal();
unsigned size = node["size"].natural();
ram.map(allocate<uint8>(size, 0xff), size);
if(name) {
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 {
hasSuperGameBoySlot = 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);
interface->loadRequest(ID::SuperGameBoy, "Game Boy", "gb", false);
@ -188,7 +188,7 @@ auto Cartridge::parseMarkupEvent(Markup::Node root) -> void {
hasEvent = true;
for(auto node : root.find("rom")) {
unsigned id = node["id"].decimal();
unsigned id = node["id"].natural();
if(id > 3) continue;
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;
lstring part = root["timer"].text().split(":", 1L);
if(part.size() == 1) event.timer = decimal(part(0));
if(part.size() == 2) event.timer = decimal(part(0)) * 60 + decimal(part(1));
if(part.size() == 1) event.timer = part(0).natural();
if(part.size() == 2) event.timer = part(0).natural() * 60 + part(1).natural();
for(auto node : root.find("map")) {
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.dataRAM) word = 0x00;
hitachidsp.Frequency = root["frequency"].decimal();
hitachidsp.Frequency = root["frequency"].natural();
if(hitachidsp.Frequency == 0) hitachidsp.frequency = 20000000;
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.dataRAM) word = 0x0000;
necdsp.frequency = root["frequency"].decimal();
necdsp.frequency = root["frequency"].natural();
if(necdsp.frequency == 0) necdsp.frequency = 8000000;
necdsp.revision
= 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});
parseMarkupMap(m, node);
mapping.append(m);
necdsp.Select = node["select"].decimal();
necdsp.Select = node["select"].natural();
}
if(node["id"].text() == "ram") {

View File

@ -6,9 +6,21 @@ namespace SuperFamicom {
#include "serialization.cpp"
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
while(bridge.reset) {
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);
Coprocessor::step(clocks);
synchronize_cpu();
@ -47,7 +59,7 @@ void ArmDSP::step(unsigned clocks) {
//3800-3807 mirrored throughout
//a0 ignored
uint8 ArmDSP::mmio_read(unsigned addr) {
auto ArmDSP::mmio_read(uint addr) -> uint8 {
cpu.synchronizeCoprocessors();
uint8 data = 0x00;
@ -71,7 +83,7 @@ uint8 ArmDSP::mmio_read(unsigned addr) {
return data;
}
void ArmDSP::mmio_write(unsigned addr, uint8 data) {
auto ArmDSP::mmio_write(uint addr, uint8 data) -> void {
cpu.synchronizeCoprocessors();
addr &= 0xff06;
@ -83,30 +95,30 @@ void ArmDSP::mmio_write(unsigned addr, uint8 data) {
if(addr == 0x3804) {
data &= 1;
if(!bridge.reset && data) arm_reset();
if(!bridge.reset && data) resetARM();
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() {
for(unsigned n = 0; n < 16 * 1024; n++) programRAM[n] = random(0x00);
auto ArmDSP::power() -> void {
for(auto n : range(16 * 1024)) programRAM[n] = random(0x00);
}
void ArmDSP::reset() {
auto ArmDSP::reset() -> void {
bridge.reset = false;
arm_reset();
resetARM();
}
void ArmDSP::arm_reset() {
auto ArmDSP::resetARM() -> void {
create(ArmDSP::Enter, 21477272);
ARM::power();
@ -118,16 +130,4 @@ void ArmDSP::arm_reset() {
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)
struct ArmDSP : Processor::ARM, Coprocessor {
uint8* programROM;
uint8* dataROM;
uint8* programRAM;
#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();
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;

View File

@ -1,14 +1,14 @@
//note: timings are completely unverified
//due to the ST018 chip design (on-die ROM), testing is nearly impossible
void ArmDSP::bus_idle() {
auto ArmDSP::bus_idle() -> void {
step(1);
}
uint32 ArmDSP::bus_read(unsigned mode, uint32 addr) {
auto ArmDSP::bus_read(unsigned mode, uint32 addr) -> uint32 {
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) {
memory += addr & ~3;
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;
}
void ArmDSP::bus_write(unsigned mode, uint32 addr, uint32 word) {
auto ArmDSP::bus_write(uint mode, uint32 addr, uint32 word) -> void {
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) {
memory += addr & ~3;
*memory++ = word >> 0;

View File

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

View File

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

View File

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

View File

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

View File

@ -1,4 +1,4 @@
void EpsonRTC::rtc_reset() {
auto EpsonRTC::rtc_reset() -> void {
state = State::Mode;
offset = 0;
@ -7,7 +7,7 @@ void EpsonRTC::rtc_reset() {
test = 0;
}
uint4 EpsonRTC::rtc_read(uint4 addr) {
auto EpsonRTC::rtc_read(uint4 addr) -> uint4 {
switch(addr) { default:
case 0: return secondlo;
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) {
case 0:
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;
secondhi = data[0] >> 4;
batteryfailure = data[0] >> 7;
@ -151,7 +151,7 @@ void EpsonRTC::load(const uint8* data) {
test = data[7] >> 7;
uint64 timestamp = 0;
for(unsigned byte = 0; byte < 8; byte++) {
for(auto byte : range(8)) {
timestamp |= data[8 + byte] << (byte * 8);
}
@ -162,7 +162,7 @@ void EpsonRTC::load(const uint8* data) {
while(diff--) tick_second();
}
void EpsonRTC::save(uint8* data) {
auto EpsonRTC::save(uint8* data) -> void {
data[0] = secondlo << 0 | secondhi << 4 | batteryfailure << 7;
data[1] = minutelo << 0 | minutehi << 4 | 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;
uint64 timestamp = (uint64)time(0);
for(unsigned byte = 0; byte < 8; byte++) {
for(auto byte : range(8)) {
data[8 + byte] = timestamp;
timestamp >>= 8;
}

View File

@ -1,11 +1,11 @@
void EpsonRTC::serialize(serializer& s) {
auto EpsonRTC::serialize(serializer& s) -> void {
Thread::serialize(s);
s.integer(clocks);
s.integer(seconds);
s.integer(chipselect);
s.integer((unsigned&)state);
s.integer((uint&)state);
s.integer(mdr);
s.integer(offset);
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(period == irqperiod) irqflag = 1;
}
void EpsonRTC::duty() {
auto EpsonRTC::duty() -> void {
if(irqduty) irqflag = 0;
}
void EpsonRTC::round_seconds() {
auto EpsonRTC::round_seconds() -> void {
if(roundseconds == 0) return;
roundseconds = 0;
@ -17,7 +17,7 @@ void EpsonRTC::round_seconds() {
secondhi = 0;
}
void EpsonRTC::tick() {
auto EpsonRTC::tick() -> void {
if(stop || pause) return;
if(hold) {
@ -32,7 +32,7 @@ void EpsonRTC::tick() {
//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)
void EpsonRTC::tick_second() {
auto EpsonRTC::tick_second() -> void {
if(secondlo <= 8 || secondlo == 12) {
secondlo++;
} else {
@ -46,7 +46,7 @@ void EpsonRTC::tick_second() {
}
}
void EpsonRTC::tick_minute() {
auto EpsonRTC::tick_minute() -> void {
if(minutelo <= 8 || minutelo == 12) {
minutelo++;
} else {
@ -60,7 +60,7 @@ void EpsonRTC::tick_minute() {
}
}
void EpsonRTC::tick_hour() {
auto EpsonRTC::tick_hour() -> void {
if(atime) {
if(hourhi < 2) {
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;
weekday = (weekday + 1) + (weekday == 6);
//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,
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) {
//add one day for leap years
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(monthlo <= 8 || monthlo == 12) {
monthlo++;
@ -168,7 +168,7 @@ void EpsonRTC::tick_month() {
}
}
void EpsonRTC::tick_year() {
auto EpsonRTC::tick_year() -> void {
if(yearlo <= 8 || yearlo == 12) {
yearlo++;
} else {

View File

@ -4,9 +4,9 @@ namespace SuperFamicom {
Event event;
void Event::Enter() { event.enter(); }
auto Event::Enter() -> void { event.enter(); }
void Event::enter() {
auto Event::enter() -> void {
while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
@ -15,7 +15,6 @@ void Event::enter() {
if(scoreActive && scoreSecondsRemaining) {
if(--scoreSecondsRemaining == 0) {
scoreActive = false;
submitScore();
}
}
@ -33,40 +32,13 @@ void Event::enter() {
}
}
void Event::submitScore() {
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");
}
auto Event::init() -> void {
}
void Event::init() {
auto Event::load() -> void {
}
void Event::load() {
}
void Event::unload() {
auto Event::unload() -> void {
rom[0].reset();
rom[1].reset();
rom[2].reset();
@ -74,27 +46,25 @@ void Event::unload() {
ram.reset();
}
void Event::power() {
usedSaveState = false;
auto Event::power() -> void {
}
void Event::reset() {
auto Event::reset() -> void {
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;
select = 0x00;
timerActive = false;
scoreActive = false;
timerSecondsRemaining = 0;
scoreSecondsRemaining = 0;
usedSaveState = false;
}
uint8 Event::sr(unsigned) {
auto Event::sr(uint) -> uint8 {
return status;
}
void Event::dr(unsigned, uint8 data) {
auto Event::dr(uint, uint8 data) -> void {
select = data;
if(timer && data == 0x09) {
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) {
unsigned id = 0;
uint id = 0;
if(select == 0x09) id = 1;
if(select == 0x05) id = 2;
if(select == 0x03) id = 3;
@ -117,7 +87,7 @@ uint8 Event::rom_read(unsigned addr) {
}
if(board == Board::Powerfest94) {
unsigned id = 0;
uint id = 0;
if(select == 0x09) id = 1;
if(select == 0x0c) id = 2;
if(select == 0x0a) id = 3;
@ -138,15 +108,15 @@ uint8 Event::rom_read(unsigned addr) {
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()));
}
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);
}
void Event::serialize(serializer& s) {
auto Event::serialize(serializer& s) -> void {
Thread::serialize(s);
s.array(ram.data(), ram.size());
s.integer(status);
@ -155,8 +125,6 @@ void Event::serialize(serializer& s) {
s.integer(scoreActive);
s.integer(timerSecondsRemaining);
s.integer(scoreSecondsRemaining);
usedSaveState = true;
}
}

View File

@ -3,42 +3,40 @@
//* Powerfest '94
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 ram;
static void Enter();
void enter();
void init();
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;
enum class Board : uint { CampusChallenge92, Powerfest94 } board;
uint revision;
uint timer;
privileged:
uint8 status;
uint8 select;
bool timerActive;
bool scoreActive;
unsigned timerSecondsRemaining;
unsigned scoreSecondsRemaining;
bool usedSaveState;
uint timerSecondsRemaining;
uint scoreSecondsRemaining;
};
extern Event event;

View File

@ -6,16 +6,16 @@ namespace SuperFamicom {
#include "serialization.cpp"
HitachiDSP hitachidsp;
void HitachiDSP::Enter() { hitachidsp.enter(); }
auto HitachiDSP::Enter() -> void { hitachidsp.enter(); }
void HitachiDSP::enter() {
auto HitachiDSP::enter() -> void {
while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
scheduler.exit(Scheduler::ExitReason::SynchronizeEvent);
}
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));
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();
ram.reset();
}
void HitachiDSP::power() {
auto HitachiDSP::power() -> void {
mmio.dma = false;
mmio.dma_source = 0x000000;
@ -56,7 +56,7 @@ void HitachiDSP::power() {
mmio.r1f52 = 0x01;
}
void HitachiDSP::reset() {
auto HitachiDSP::reset() -> void {
create(HitachiDSP::Enter, Frequency);
HG51B::power();
}

View File

@ -1,39 +1,39 @@
struct HitachiDSP : Processor::HG51B, Coprocessor {
unsigned Frequency;
unsigned Roms;
MappedRAM rom;
MappedRAM ram;
#include "mmio.hpp"
static void Enter();
void enter();
static auto Enter() -> void;
auto enter() -> void;
void init();
void load();
void unload();
void power();
void reset();
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;
auto reset() -> void;
//HG51B read/write
uint8 bus_read(uint24 addr);
void bus_write(uint24 addr, uint8 data);
auto bus_read(uint24 addr) -> uint8;
auto bus_write(uint24 addr, uint8 data) -> void;
//CPU ROM read/write
uint8 rom_read(unsigned addr);
void rom_write(unsigned addr, uint8 data);
auto rom_read(uint addr) -> uint8;
auto rom_write(uint addr, uint8 data) -> void;
//CPU RAM read/write
uint8 ram_read(unsigned addr);
void ram_write(unsigned addr, uint8 data);
auto ram_read(uint addr) -> uint8;
auto ram_write(uint addr, uint8 data) -> void;
//CPU MMIO read/write
uint8 dsp_read(unsigned addr);
void dsp_write(unsigned addr, uint8 data);
auto dsp_read(uint addr) -> uint8;
auto dsp_write(uint addr, uint8 data) -> void;
vector<uint8> firmware();
void serialize(serializer&);
auto firmware() const -> vector<uint8>;
auto serialize(serializer&) -> void;
uint Frequency;
uint Roms;
};
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 & 0xf88000) == 0x700000) return bus.read(addr); //$70-77:0000-7fff
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 & 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) {
addr = bus.mirror(addr, rom.size());
//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;
}
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
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;
return ram.write(bus.mirror(addr, ram.size()), data);
}
uint8 HitachiDSP::dsp_read(unsigned addr) {
auto HitachiDSP::dsp_read(uint addr) -> uint8 {
addr &= 0x1fff;
//Data RAM
@ -74,15 +74,15 @@ uint8 HitachiDSP::dsp_read(unsigned addr) {
//GPRs
if((addr >= 0x1f80 && addr <= 0x1faf) || (addr >= 0x1fc0 && addr <= 0x1fef)) {
unsigned index = (addr & 0x3f) / 3; //0..15
unsigned shift = ((addr & 0x3f) % 3) * 8; //0, 8, 16
uint index = (addr & 0x3f) / 3; //0..15
uint shift = ((addr & 0x3f) % 3) * 8; //0, 8, 16
return regs.gpr[index] >> shift;
}
return 0x00;
}
void HitachiDSP::dsp_write(unsigned addr, uint8 data) {
auto HitachiDSP::dsp_write(uint addr, uint8 data) -> void {
addr &= 0x1fff;
//Data RAM
@ -129,7 +129,7 @@ void HitachiDSP::dsp_write(unsigned addr, uint8 data) {
//GPRs
if((addr >= 0x1f80 && addr <= 0x1faf) || (addr >= 0x1fc0 && addr <= 0x1fef)) {
unsigned index = (addr & 0x3f) / 3;
uint index = (addr & 0x3f) / 3;
switch((addr & 0x3f) % 3) {
case 0: regs.gpr[index] = (regs.gpr[index] & 0xffff00) | (data << 0); 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;
if(!cartridge.hasHitachiDSP()) return buffer;
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] >> 8);
buffer.append(dataROM[n] >> 16);
@ -10,7 +10,7 @@ vector<uint8> HitachiDSP::firmware() {
return buffer;
}
void HitachiDSP::serialize(serializer& s) {
auto HitachiDSP::serialize(serializer& s) -> void {
HG51B::serialize(s);
Thread::serialize(s);

View File

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

View File

@ -1,19 +1,19 @@
struct ICD2 : Emulator::Interface::Bind, GameBoy::Interface::Hook, Coprocessor {
unsigned revision;
static auto Enter() -> void;
auto enter() -> void;
static void Enter();
void enter();
auto init() -> void;
auto load() -> void;
auto unload() -> void;
auto power() -> void;
auto reset() -> void;
void init();
void load();
void unload();
void power();
void reset();
auto read(uint addr) -> uint8;
auto write(uint addr, uint8 data) -> void;
uint8 read(unsigned addr);
void write(unsigned addr, uint8 data);
auto serialize(serializer&) -> void;
void serialize(serializer&);
uint revision;
private:
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 & 7) == 0) {
write_bank = (write_bank + 1) & 3;
@ -6,16 +6,16 @@ void ICD2::lcdScanline() {
}
}
void ICD2::lcdOutput(uint2 color) {
unsigned y = write_addr / 160;
unsigned x = write_addr % 160;
unsigned addr = write_bank * 512 + y * 2 + x / 8 * 16;
auto ICD2::lcdOutput(uint2 color) -> void {
uint y = write_addr / 160;
uint x = write_addr % 160;
uint addr = write_bank * 512 + y * 2 + x / 8 * 16;
output[addr + 0] = (output[addr + 0] << 1) | (bool)(color & 1);
output[addr + 1] = (output[addr + 1] << 1) | (bool)(color & 2);
write_addr = (write_addr + 1) % 1280;
}
void ICD2::joypWrite(bool p15, bool p14) {
auto ICD2::joypWrite(bool p15, bool p14) -> void {
//joypad handling
if(p15 == 1 && p14 == 1) {
if(joyp15lock == 0 && joyp14lock == 0) {
@ -85,21 +85,21 @@ void ICD2::joypWrite(bool p15, bool p14) {
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;
}
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);
}
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;
unsigned data = 0x00;
uint data = 0x00;
switch(joyp_id & mlt_req) {
case 0: data = ~r6004; break;
case 1: data = ~r6005; break;

View File

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

View File

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

View File

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

View File

@ -1,8 +1,8 @@
void ICD2::serialize(serializer& s) {
auto ICD2::serialize(serializer& s) -> void {
Thread::serialize(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(joyp_id);

View File

@ -21,29 +21,29 @@ auto MCC::power() -> 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[0x08] = 0x80;
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);
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());
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());
return memory.write(addr, data);
}
//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(r07 == 1) {
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;
}
auto MCC::mcu_read(unsigned addr) -> uint8 {
auto MCC::mcu_read(uint addr) -> uint8 {
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);
}
auto MCC::mmio_read(unsigned addr) -> uint8 {
auto MCC::mmio_read(uint addr) -> uint8 {
if((addr & 0xf0ffff) == 0x005000) { //$00-0f:5000
uint8 n = (addr >> 16) & 15;
return r[n];
@ -110,7 +110,7 @@ auto MCC::mmio_read(unsigned addr) -> uint8 {
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
uint8 n = (addr >> 16) & 15;
r[n] = data;

View File

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

View File

@ -35,8 +35,8 @@ auto MSU1::enter() -> void {
}
}
signed lchannel = (double)left * (double)mmio.audioVolume / 255.0;
signed rchannel = (double)right * (double)mmio.audioVolume / 255.0;
int lchannel = (double)left * (double)mmio.audioVolume / 255.0;
int rchannel = (double)right * (double)mmio.audioVolume / 255.0;
left = sclamp<16>(lchannel);
right = sclamp<16>(rchannel);
if(dsp.mute()) left = 0, right = 0;
@ -103,7 +103,7 @@ auto MSU1::audioOpen() -> void {
auto document = BML::unserialize(cartridge.information.markup.cartridge);
string name = {"track-", mmio.audioTrack, ".pcm"};
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();
break;
}
@ -123,7 +123,7 @@ auto MSU1::audioOpen() -> void {
mmio.audioError = true;
}
auto MSU1::mmioRead(unsigned addr) -> uint8 {
auto MSU1::mmioRead(uint addr) -> uint8 {
cpu.synchronizeCoprocessors();
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();
addr = 0x2000 | (addr & 7);

View File

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

View File

@ -5,9 +5,9 @@ namespace SuperFamicom {
#include "serialization.cpp"
NECDSP necdsp;
void NECDSP::Enter() { necdsp.enter(); }
auto NECDSP::Enter() -> void { necdsp.enter(); }
void NECDSP::enter() {
auto NECDSP::enter() -> void {
while(true) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
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();
if(addr & Select) {
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();
if(addr & Select) {
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();
return uPD96050::dp_read(addr);
}
void NECDSP::ram_write(unsigned addr, uint8 data) {
auto NECDSP::ram_write(uint addr, uint8 data) -> void {
cpu.synchronizeCoprocessors();
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);
uPD96050::power();
}

View File

@ -1,23 +1,23 @@
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;
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;

View File

@ -1,17 +1,17 @@
vector<uint8> NECDSP::firmware() {
auto NECDSP::firmware() const -> vector<uint8> {
vector<uint8> buffer;
if(!cartridge.hasNECDSP()) return buffer;
unsigned plength = 2048, dlength = 1024;
uint plength = 2048, dlength = 1024;
if(revision == Revision::uPD96050) plength = 16384, dlength = 2048;
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] >> 8);
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] >> 8);
}
@ -19,7 +19,7 @@ vector<uint8> NECDSP::firmware() {
return buffer;
}
void NECDSP::serialize(serializer& s) {
auto NECDSP::serialize(serializer& s) -> void {
uPD96050::serialize(s);
Thread::serialize(s);
}

View File

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

View File

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

View File

@ -1,20 +1,20 @@
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;
void init();
void load();
void unload();
void power();
void reset();
uint8 read(unsigned addr);
void write(unsigned addr, uint8 data);
void serialize(serializer&);
private:
uint8 ram_read(unsigned addr);
void ram_write(unsigned addr, uint8 data);
auto ramRead(uint addr) -> uint8;
auto ramWrite(uint addr, uint8 data) -> void;
struct {
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.integer(status.address);

View File

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

View File

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

View File

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

View File

@ -1,11 +1,11 @@
struct DMA {
enum CDEN { DmaNormal = 0, DmaCharConversion = 1 };
enum SD { SourceROM = 0, SourceBWRAM = 1, SourceIRAM = 2 };
enum DD { DestIRAM = 0, DestBWRAM = 1 };
unsigned line;
enum CDEN : uint { DmaNormal = 0, DmaCharConversion = 1 };
enum SD : uint { SourceROM = 0, SourceBWRAM = 1, SourceIRAM = 2 };
enum DD : uint { DestIRAM = 0, DestBWRAM = 1 };
uint line;
} dma;
void dma_normal();
void dma_cc1();
uint8 dma_cc1_read(unsigned addr);
void dma_cc2();
auto dma_normal() -> void;
auto dma_cc1() -> void;
auto dma_cc1_read(uint addr) -> uint8;
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
return mmio_read(addr);
}
@ -39,7 +39,7 @@ uint8 SA1::bus_read(unsigned addr) {
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
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
//to avoid syncing the S-CPU and SA-1*; as both chips are able to access
//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
return mmcrom_read(addr);
}
@ -97,6 +97,8 @@ uint8 SA1::vbr_read(unsigned addr) {
if((addr & 0x40f800) == 0x003000) { //$00-3f|80-bf:3000-37ff
return iram.read(addr & 2047);
}
return 0x00;
}
//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
//note: bus conflict delays are not emulated at this time
void SA1::op_io() {
auto SA1::op_io() -> void {
tick();
}
uint8 SA1::op_read(unsigned addr) {
auto SA1::op_read(uint addr) -> uint8 {
tick();
if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick();
return bus_read(addr);
}
void SA1::op_write(unsigned addr, uint8 data) {
auto SA1::op_write(uint addr, uint8 data) -> void {
tick();
if(((addr & 0x40e000) == 0x006000) || ((addr & 0xd00000) == 0x400000)) tick();
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 == 0xffea && sa1.mmio.cpu_nvsw) return sa1.mmio.snv >> 0;
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;
}
static auto read = [](unsigned addr) {
static auto read = [](uint addr) {
return sa1.rom.read(bus.mirror(addr, sa1.rom.size()));
};
@ -175,10 +177,10 @@ uint8 SA1::mmcrom_read(unsigned addr) {
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
cpu.synchronizeCoprocessors();
addr = bus.mirror(mmio.sbm * 0x2000 + (addr & 0x1fff), cpubwram.size());
@ -192,7 +194,7 @@ uint8 SA1::mmcbwram_read(unsigned addr) {
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
cpu.synchronizeCoprocessors();
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();
if(mmio.sw46 == 0) {
//$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();
if(mmio.sw46 == 0) {
//$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) {
//4bpp
unsigned shift = addr & 1;
uint shift = addr & 1;
addr = (addr >> 1) & (bwram.size() - 1);
switch(shift) {
case 0: return (bwram.read(addr) >> 0) & 15;
@ -241,7 +243,7 @@ uint8 SA1::bitmap_read(unsigned addr) {
}
} else {
//2bpp
unsigned shift = addr & 3;
uint shift = addr & 3;
addr = (addr >> 2) & (bwram.size() - 1);
switch(shift) {
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) {
//4bpp
unsigned shift = addr & 1;
uint shift = addr & 1;
addr = (addr >> 1) & (bwram.size() - 1);
switch(shift) {
case 0: data = (bwram.read(addr) & 0xf0) | ((data & 15) << 0); break;
@ -263,7 +265,7 @@ void SA1::bitmap_write(unsigned addr, uint8 data) {
}
} else {
//2bpp
unsigned shift = addr & 3;
uint shift = addr & 3;
addr = (addr >> 2) & (bwram.size() - 1);
switch(shift) {
case 0: data = (bwram.read(addr) & 0xfc) | ((data & 3) << 0); break;

View File

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

View File

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

View File

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

View File

@ -10,9 +10,9 @@ SA1 sa1;
#include "memory/memory.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) {
if(scheduler.sync == Scheduler::SynchronizeMode::All) {
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_io();
if(!regs.e) op_writestack(regs.pc.b);
@ -48,7 +48,7 @@ void SA1::op_irq() {
regs.p.d = 0;
}
void SA1::last_cycle() {
auto SA1::last_cycle() -> void {
if(mmio.sa1_nmi && !mmio.sa1_nmicl) {
status.interrupt_pending = true;
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;
}
void SA1::tick() {
auto SA1::tick() -> void {
step(2);
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;
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();
iram.reset();
bwram.reset();
}
void SA1::power() {
auto SA1::power() -> void {
regs.a = regs.x = regs.y = 0x0000;
regs.s = 0x01ff;
}
void SA1::reset() {
auto SA1::reset() -> void {
create(SA1::Enter, system.cpuFrequency());
cpubwram.dma = false;
for(unsigned addr = 0; addr < iram.size(); addr++) {
for(auto addr : range(iram.size())) {
iram.write(addr, 0x00);
}

View File

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

View File

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

View File

@ -8,12 +8,12 @@
//input manager
void SDD1::Decomp::IM::init(unsigned offset_) {
auto SDD1::Decomp::IM::init(uint offset_) -> void {
offset = offset_;
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 comp_count;
@ -70,7 +70,7 @@ const uint8 SDD1::Decomp::GCD::run_count[] = {
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);
if(codeword & 0x80) {
@ -83,12 +83,12 @@ void SDD1::Decomp::GCD::get_run_count(uint8 code_number, uint8& mps_count, bool&
//bits generator
void SDD1::Decomp::BG::init() {
auto SDD1::Decomp::BG::init() -> void {
mps_count = 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);
uint8 bit;
@ -142,14 +142,14 @@ const SDD1::Decomp::PEM::State SDD1::Decomp::PEM::evolution_table[33] = {
{7, 24, 22},
};
void SDD1::Decomp::PEM::init() {
for(unsigned i = 0; i < 32; i++) {
context_info[i].status = 0;
context_info[i].mps = 0;
auto SDD1::Decomp::PEM::init() -> void {
for(auto n : range(32)) {
context_info[n].status = 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];
uint8 current_status = info.status;
uint8 current_mps = info.mps;
@ -182,11 +182,11 @@ uint8 SDD1::Decomp::PEM::get_bit(uint8 context) {
//context model
void SDD1::Decomp::CM::init(unsigned offset) {
auto SDD1::Decomp::CM::init(uint offset) -> void {
bitplanes_info = sdd1.mmc_read(offset) & 0xc0;
context_bits_info = sdd1.mmc_read(offset) & 0x30;
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) {
case 0x00: current_bitplane = 1; 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) {
case 0x00:
current_bitplane ^= 0x01;
@ -230,12 +230,12 @@ uint8 SDD1::Decomp::CM::get_bit() {
//output logic
void SDD1::Decomp::OL::init(unsigned offset) {
auto SDD1::Decomp::OL::init(uint offset) -> void {
bitplanes_info = sdd1.mmc_read(offset) & 0xc0;
r0 = 0x01;
}
uint8 SDD1::Decomp::OL::decompress() {
auto SDD1::Decomp::OL::decompress() -> uint8 {
switch(bitplanes_info) {
case 0x00: case 0x40: case 0x80:
if(r0 == 0) {
@ -257,7 +257,14 @@ uint8 SDD1::Decomp::OL::decompress() {
//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);
bg0.init();
bg1.init();
@ -272,13 +279,6 @@ void SDD1::Decomp::init(unsigned offset) {
ol.init(offset);
}
uint8 SDD1::Decomp::read() {
auto SDD1::Decomp::read() -> uint8 {
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 IM { //input manager
Decomp& self;
void init(unsigned offset);
uint8 get_codeword(uint8 code_length);
IM(SDD1::Decomp& self) : self(self) {}
auto init(uint offset) -> void;
auto get_codeword(uint8 code_length) -> uint8;
private:
unsigned offset;
unsigned bit_count;
Decomp& self;
uint offset;
uint bit_count;
};
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;
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
Decomp& self;
void init();
uint8 get_bit(bool& end_of_run);
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:
Decomp& self;
const uint8 code_number;
uint8 mps_count;
bool lps_index;
};
struct PEM { //probability estimation module
Decomp& self;
void init();
uint8 get_bit(uint8 context);
PEM(SDD1::Decomp& self) : self(self) {}
auto init() -> void;
auto get_bit(uint8 context) -> uint8;
private:
Decomp& self;
struct State {
uint8 code_number;
uint8 next_if_mps;
@ -46,11 +51,12 @@ struct Decomp {
};
struct CM { //context model
Decomp& self;
void init(unsigned offset);
uint8 get_bit();
CM(SDD1::Decomp& self) : self(self) {}
auto init(uint offset) -> void;
uint8 get_bit();
private:
Decomp& self;
uint8 bitplanes_info;
uint8 context_bits_info;
uint8 bit_number;
@ -59,18 +65,19 @@ struct Decomp {
};
struct OL { //output logic
Decomp& self;
void init(unsigned offset);
uint8 decompress();
OL(SDD1::Decomp& self) : self(self) {}
auto init(uint offset) -> void;
auto decompress() -> uint8;
private:
Decomp& self;
uint8 bitplanes_info;
uint8 r0, r1, r2;
};
void init(unsigned offset);
uint8 read();
Decomp();
auto init(uint offset) -> void;
auto read() -> uint8;
IM im;
GCD gcd;

View File

@ -7,7 +7,7 @@ SDD1 sdd1;
#include "decomp.cpp"
#include "serialization.cpp"
void SDD1::init() {
auto SDD1::init() -> void {
}
void SDD1::load() {
@ -17,15 +17,15 @@ void SDD1::load() {
bus.map({&SDD1::read, &sdd1}, {&SDD1::write, &sdd1}, 0x80, 0xbf, 0x4300, 0x437f);
}
void SDD1::unload() {
auto SDD1::unload() -> void {
rom.reset();
ram.reset();
}
void SDD1::power() {
auto SDD1::power() -> void {
}
void SDD1::reset() {
auto SDD1::reset() -> void {
sdd1_enable = 0x00;
xfer_enable = 0x00;
dma_ready = false;
@ -35,13 +35,13 @@ void SDD1::reset() {
mmc[2] = 2 << 20;
mmc[3] = 3 << 20;
for(unsigned i = 0; i < 8; i++) {
dma[i].addr = 0;
dma[i].size = 0;
for(auto n : range(8)) {
dma[n].addr = 0;
dma[n].size = 0;
}
}
uint8 SDD1::read(unsigned addr) {
auto SDD1::read(uint addr) -> uint8 {
addr &= 0xffff;
if((addr & 0x4380) == 0x4300) {
@ -58,11 +58,11 @@ uint8 SDD1::read(unsigned addr) {
return cpu.regs.mdr;
}
void SDD1::write(unsigned addr, uint8 data) {
auto SDD1::write(uint addr, uint8 data) -> void {
addr &= 0xffff;
if((addr & 0x4380) == 0x4300) {
unsigned channel = (addr >> 4) & 7;
uint channel = (addr >> 4) & 7;
switch(addr & 15) {
case 2: dma[channel].addr = (dma[channel].addr & 0xffff00) + (data << 0); 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));
}
@ -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
//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
return rom.read(addr);
//addr = ((addr & 0x7f0000) >> 1) | (addr & 0x7fff);
@ -117,10 +117,10 @@ uint8 SDD1::mcurom_read(unsigned addr) {
//$40-7f|c0-ff:0000-ffff (MMC)
if(sdd1_enable & xfer_enable) {
//at least one channel has S-DD1 decompression enabled ...
for(unsigned i = 0; i < 8; i++) {
if(sdd1_enable & xfer_enable & (1 << i)) {
for(auto n : range(8)) {
if(sdd1_enable & xfer_enable & (1 << n)) {
//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) {
//prepare streaming decompression
decomp.init(addr);
@ -129,9 +129,9 @@ uint8 SDD1::mcurom_read(unsigned addr) {
//fetch a decompressed byte; once finished, disable channel and invalidate buffer
uint8 data = decomp.read();
if(--dma[i].size == 0) {
if(--dma[n].size == 0) {
dma_ready = false;
xfer_enable &= ~(1 << i);
xfer_enable &= ~(1 << n);
}
return data;
@ -144,10 +144,10 @@ uint8 SDD1::mcurom_read(unsigned 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
return ram.read(addr & 0x1fff);
}
@ -159,7 +159,7 @@ uint8 SDD1::mcuram_read(unsigned addr) {
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
return ram.write(addr & 0x1fff, data);
}

View File

@ -1,34 +1,34 @@
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 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:
uint8 sdd1_enable; //channel bit-mask
uint8 xfer_enable; //channel bit-mask
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 {
unsigned addr; //$43x2-$43x4 -- DMA transfer address
uint addr; //$43x2-$43x4 -- DMA transfer address
uint16 size; //$43x5-$43x6 -- DMA transfer size
} 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.integer(sdd1_enable);
@ -6,7 +6,7 @@ void SDD1::serialize(serializer& s) {
s.integer(dma_ready);
s.array(mmc);
for(unsigned n = 0; n < 8; n++) {
for(auto n : range(8)) {
s.integer(dma[n].addr);
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) {
case 0: 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) {
case 0: second = second / 10 * 10 + data; 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) {
for(unsigned byte = 0; byte < 8; byte++) {
auto SharpRTC::load(const uint8* data) -> void {
for(auto byte : range(8)) {
rtc_write(byte * 2 + 0, data[byte] >> 0);
rtc_write(byte * 2 + 1, data[byte] >> 4);
}
uint64 timestamp = 0;
for(unsigned byte = 0; byte < 8; byte++) {
for(auto byte : range(8)) {
timestamp |= data[8 + byte] << (byte * 8);
}
@ -53,14 +53,14 @@ void SharpRTC::load(const uint8* data) {
while(diff--) tick_second();
}
void SharpRTC::save(uint8* data) {
for(unsigned byte = 0; byte < 8; byte++) {
auto SharpRTC::save(uint8* data) -> void {
for(auto byte : range(8)) {
data[byte] = rtc_read(byte * 2 + 0) << 0;
data[byte] |= rtc_read(byte * 2 + 1) << 4;
}
uint64 timestamp = (uint64)time(0);
for(unsigned byte = 0; byte < 8; byte++) {
uint64 timestamp = (uint64)time(nullptr);
for(auto byte : range(8)) {
data[8 + byte] = timestamp;
timestamp >>= 8;
}

View File

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

View File

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

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

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