From 17a714e5501ebc9c250959a1a843b07cccd77a49 Mon Sep 17 00:00:00 2001 From: Christopher Mosher Date: Sun, 23 Jun 2019 23:25:09 -0400 Subject: [PATCH] incorporate floating data bus in RAM (instead of just ROM) reads; some more refactoring and cleanup --- src/Makefile.am | 4 +- src/addressbus.cpp | 272 +++++++++++++++---------------------- src/addressbus.h | 27 ++-- src/card.cpp | 4 +- src/diskcontroller.cpp | 16 +-- src/firmwarecard.cpp | 4 +- src/languagecard.cpp | 4 +- src/memory.cpp | 42 +----- src/memory.h | 4 +- src/memoryrandomaccess.cpp | 28 ++-- src/memoryrandomaccess.h | 4 +- src/memoryrow.cpp | 50 +++---- src/memoryrow.h | 4 +- src/memorystrapping.cpp | 4 +- src/memorystrapping.h | 2 +- src/raminitializer.cpp | 137 ------------------- src/raminitializer.h | 41 ------ 17 files changed, 177 insertions(+), 470 deletions(-) delete mode 100644 src/raminitializer.cpp delete mode 100644 src/raminitializer.h diff --git a/src/Makefile.am b/src/Makefile.am index 2896016..3a9473f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -21,7 +21,7 @@ keyboard.cpp keyboardbuffermode.cpp languagecard.cpp filterchroma.cpp \ filterluma.cpp lss.cpp main.cpp memory.cpp \ memorychip.cpp memoryrow.cpp memorystrapping.cpp memoryrandomaccess.cpp \ paddlebuttonstates.cpp \ -paddles.cpp picturegenerator.cpp powerupreset.cpp raminitializer.cpp \ +paddles.cpp picturegenerator.cpp powerupreset.cpp \ screenimage.cpp slots.cpp speakerclicker.cpp standardin.cpp \ standardinproducer.cpp standardout.cpp textcharacters.cpp \ timable.cpp video.cpp videoaddressing.cpp videomode.cpp \ @@ -40,7 +40,7 @@ hypermode.h keyboardbuffermode.h keyboard.h languagecard.h filterchroma.h \ filterluma.h lss.h memory.h \ memorychip.h memoryrow.h memorystrapping.h memoryrandomaccess.h \ paddlebuttonstates.h paddles.h picturegenerator.h \ -powerupreset.h raminitializer.h screenimage.h slots.h speakerclicker.h \ +powerupreset.h screenimage.h slots.h speakerclicker.h \ standardin.h standardinproducer.h standardout.h \ textcharacterimages.h textcharacters.h timable.h util.h \ videoaddressing.h video.h videomode.h videostaticgenerator.h wozfile.h \ diff --git a/src/addressbus.cpp b/src/addressbus.cpp index 153f054..e8e6d4f 100644 --- a/src/addressbus.cpp +++ b/src/addressbus.cpp @@ -28,14 +28,11 @@ #include "slots.h" AddressBus::AddressBus(ScreenImage& gui, int& revision, MemoryRandomAccess& ram, Memory& rom, Keyboard& kbd, VideoMode& vid, Paddles& paddles, PaddleButtonStates& paddleButtonStates, SpeakerClicker& speaker, CassetteIn& cassetteIn, CassetteOut& cassetteOut, Slots& slts): - gui(gui), revision(revision), ram(ram), rom(rom), kbd(kbd), vid(vid), paddles(paddles), paddleButtonStates(paddleButtonStates), speaker(speaker), cassetteIn(cassetteIn), cassetteOut(cassetteOut), slts(slts) -{ + gui(gui), revision(revision), ram(ram), rom(rom), kbd(kbd), vid(vid), paddles(paddles), paddleButtonStates(paddleButtonStates), speaker(speaker), cassetteIn(cassetteIn), cassetteOut(cassetteOut), slts(slts) { } -AddressBus::~AddressBus() -{ -} +AddressBus::~AddressBus() = default; @@ -45,70 +42,51 @@ AddressBus::~AddressBus() -unsigned char AddressBus::read(const unsigned short address) -{ - if ((address >> 14 == 3)) // >= $C000 - { - if ((address >> 12) == 0xC) - { +unsigned char AddressBus::read(const unsigned short address) { + if ((address >> 14) == 3) { // >= $C000 + if ((address >> 12) == 0xC) { // 11007sss,xxxxxxxx - const bool seventh = address & 0x0800; - const int slot = (address >> 8) & 7; - if (seventh) - { - this->data = this->slts.readSeventhRom(address & 0x07FF, this->data); - } - else if (slot == 0) - { - this->data = readSwitch(address & 0x00FF); - } - else - { - this->data = this->slts.readRom(slot,address & 0x00FF, this->data); - } - } - else - { - this->data = this->slts.ioBankRom(address - 0xD000,this->data,false); - if (!this->slts.inhibitMotherboardRom()) - { - this->data = this->rom.read(address - 0xD000); - } - } - } - else // < $C000 - { - this->data = this->ram.read(address); - } + const bool seventh = address & 0x0800; + const int slot = (address >> 8) & 7; + if (seventh) { + this->data = this->slts.readSeventhRom(address & 0x07FF, this->data); + } else if (slot == 0) { + readSwitch(address & 0x00FF); + } else { + this->data = this->slts.readRom(slot, address & 0x00FF, this->data); + } + } else { + this->data = this->slts.ioBankRom(address - 0xD000, this->data, false); + if (!this->slts.inhibitMotherboardRom()) { + this->data = this->rom.read(address - 0xD000, this->data); + } + } + } else { // < $C000 + this->data = this->ram.read(address, this->data); + } - return this->data; + return this->data; } -void AddressBus::write(const unsigned short address, const unsigned char d) -{ - this->data = d; +void AddressBus::write(const unsigned short address, const unsigned char d) { + this->data = d; - if ((address >> 14 == 3)) // >= $C000 - { - if ((address >> 12) == 0xC) - { + if ((address >> 14 == 3)) { // >= $C000 + if ((address >> 12) == 0xC) { // 11007sss,xxxxxxxx - const bool seventh = address & 0x0800; - const int slot = (address >> 8) & 7; - if (!seventh && slot == 0) - { - writeSwitch(address & 0x00FF); - } - } - else - { - this->slts.ioBankRom(address - 0xD000,this->data,true); - } - } - else // < $C000 - { - this->ram.write(address,this->data); - } + const bool seventh = address & 0x0800; + const int slot = (address >> 8) & 7; + if (!seventh && slot == 0) { + writeSwitch(address & 0x00FF); + } + } + else { + this->data = this->slts.ioBankRom(address - 0xD000, this->data, true); + } + } + else { // < $C000 + this->ram.write(address, this->data); + } } @@ -118,122 +96,84 @@ void AddressBus::write(const unsigned short address, const unsigned char d) -unsigned char AddressBus::readSwitch(unsigned short address) -{ - if (address < 0x80) - { - const int islot = (address >> 4) & 0xF; - const int iswch = (address & 0xF); - if (islot == 0x0) - { - this->data = this->kbd.get(); - } - else if (islot == 0x1) - { - this->kbd.clear(); - } - else if (islot == 0x2) - { + +void AddressBus::setD7(const bool set) { + if (set) { + this->data |= 0x80; + } else { + this->data &= 0x7F; + } +} + +void AddressBus::readSwitch(unsigned short address) { + if (address < 0x80) { + const int islot = (address >> 4) & 0xF; + const int iswch = (address & 0xF); + if (islot == 0x0) { + this->data = this->kbd.get(); + } else if (islot == 0x1) { + this->kbd.clear(); + } else if (islot == 0x2) { this->cassetteOut.output(); - } - else if (islot == 0x3) - { + } else if (islot == 0x3) { if (this->revision == 0) { this->cassetteOut.output(); } - this->speaker.click(); - } - else if (islot == 0x4) - { + this->speaker.click(); + } else if (islot == 0x4) { // TODO ? utility strobe - } - else if (islot == 0x5) - { - if (iswch < 0x8) - { - this->data = this->vid.io(address,this->data); - } - else - { + } else if (islot == 0x5) { + if (iswch < 0x8) { + this->data = this->vid.io(address, this->data); + } else { // 11000000,01011aaf // aa = annunciator, 0-3 // f == on/off const bool on = iswch & 1; const int ann = (iswch >> 1) & 3; this->gui.setAnnunciator(ann, on); - } - } - else if (islot == 0x6) - { - int sw2 = iswch & 0x7; - if (sw2 == 0) - { + } + } else if (islot == 0x6) { + int sw2 = iswch & 0x7; + if (sw2 == 0) { setD7(this->cassetteIn.input()); - } - else if (sw2 < 4) - { - setD7(this->paddleButtonStates.isDown(sw2-1)); - } - else - { - sw2 &= 3; - setD7(!this->paddles.isTimedOut(sw2)); - } - } - else if (islot == 0x7) - { - this->paddles.startTimers(); - setD7(true); - } - } - else - { - // slot I/O switches - address &= 0x7F; - const int islot = (address >> 4) & 0xF; - const int iswch = (address & 0xF); - this->data = this->slts.io(islot,iswch,this->data,false); - } - - return this->data; + } else if (sw2 < 4) { + setD7(this->paddleButtonStates.isDown(sw2-1)); + } else { + sw2 &= 3; + setD7(!this->paddles.isTimedOut(sw2)); + } + } else if (islot == 0x7) { + this->paddles.startTimers(); + setD7(true); + } + } else { + // slot I/O switches + address &= 0x7F; + const int islot = (address >> 4) & 0xF; + const int iswch = (address & 0xF); + this->data = this->slts.io(islot, iswch, this->data, false); + } } -void AddressBus::setD7(const bool set) -{ - if (set) - { - this->data |= 0x80; - } - else - { - this->data &= 0x7F; - } -} +void AddressBus::writeSwitch(unsigned short address){ + if (address < 0x80) { + const int islot = (address >> 4) & 0xF; + const int iswch = (address & 0xF); -void AddressBus::writeSwitch(unsigned short address) -{ - if (address < 0x80) - { - const int islot = (address >> 4) & 0xF; - const int iswch = (address & 0xF); - - if (islot == 0x1) - { - this->kbd.clear(); - } - else if (islot == 0x5) - { - if (iswch < 0x8) - this->vid.io(address,this->data); - } - // ignore all other switch writes - } - else - { - // slot I/O switches - address &= 0x7F; - const int islot = (address >> 4) & 0xF; - const int iswch = (address & 0xF); - this->slts.io(islot,iswch,this->data,true); - } + if (islot == 0x1) { + this->kbd.clear(); + } else if (islot == 0x5) { + if (iswch < 0x8) { + this->vid.io(address, this->data); + } + } + // ignore all other switch writes + } else { + // slot I/O switches + address &= 0x7F; + const int islot = (address >> 4) & 0xF; + const int iswch = (address & 0xF); + this->slts.io(islot, iswch, this->data, true); + } } diff --git a/src/addressbus.h b/src/addressbus.h index 1f757d0..08d2c50 100644 --- a/src/addressbus.h +++ b/src/addressbus.h @@ -33,9 +33,9 @@ class Slots; class AddressBus { private: ScreenImage& gui; - int& revision; + const int& revision; MemoryRandomAccess& ram; - Memory& rom; + Memory& rom; // TODO fix ROM so it doesn't use deprecated Memory class Keyboard& kbd; VideoMode& vid; Paddles& paddles; @@ -47,21 +47,24 @@ class AddressBus { unsigned char data; // this emulates the (floating) data bus - public: + void setD7(const bool set); + void readSwitch(unsigned short address); + void writeSwitch(unsigned short address); + +public: AddressBus(ScreenImage& gui, int& revision, MemoryRandomAccess& ram, Memory& rom, Keyboard& kbd, VideoMode& vid, Paddles& paddles, PaddleButtonStates& paddleButtonStates, SpeakerClicker& speaker, CassetteIn& cassetteIn, CassetteOut& cassetteOut, Slots& slts); ~AddressBus(); unsigned char read(const unsigned short address); void write(const unsigned short address, const unsigned char d); - unsigned char readSwitch(unsigned short address); - void setD7(const bool set); - void writeSwitch(unsigned short address); - enum { MOTHERBOARD_RAM_BAS = 0x00000 } ; - enum { MOTHERBOARD_RAM_LIM = 0x0C000 } ; - enum { MOTHERBOARD_RAM_SIZ = MOTHERBOARD_RAM_LIM-MOTHERBOARD_RAM_BAS }; - enum { MOTHERBOARD_ROM_BAS = 0x0D000 } ; - enum { MOTHERBOARD_ROM_LIM = 0x10000 } ; - enum { MOTHERBOARD_ROM_SIZ = MOTHERBOARD_ROM_LIM-MOTHERBOARD_ROM_BAS } ; + + static const int MOTHERBOARD_RAM_BAS = 0x00000; + static const int MOTHERBOARD_RAM_LIM = 0x0C000; + static const int MOTHERBOARD_RAM_SIZ = MOTHERBOARD_RAM_LIM-MOTHERBOARD_RAM_BAS; + + static const int MOTHERBOARD_ROM_BAS = 0x0D000; + static const int MOTHERBOARD_ROM_LIM = 0x10000; + static const int MOTHERBOARD_ROM_SIZ = MOTHERBOARD_ROM_LIM-MOTHERBOARD_ROM_BAS; }; #endif diff --git a/src/card.cpp b/src/card.cpp index 541da73..1f5f70f 100644 --- a/src/card.cpp +++ b/src/card.cpp @@ -49,7 +49,7 @@ unsigned char Card::io(const unsigned short /*address*/, const unsigned char dat unsigned char Card::readRom(const unsigned short address, const unsigned char data) { this->activeSeventhRom = true; - return this->rom.read(address); + return this->rom.read(address, data); } void Card::readSeventhRom(const unsigned short address, unsigned char* const pb) @@ -60,7 +60,7 @@ void Card::readSeventhRom(const unsigned short address, unsigned char* const pb) } else if (this->activeSeventhRom && hasSeventhRom()) { - *pb = this->seventhRom.read(address); + *pb = this->seventhRom.read(address, *pb); } } diff --git a/src/diskcontroller.cpp b/src/diskcontroller.cpp index 9e765ba..8fac749 100644 --- a/src/diskcontroller.cpp +++ b/src/diskcontroller.cpp @@ -96,14 +96,12 @@ void DiskController::tick() { this->ioStepped = false; return; } + + + this->motor.tick(); // only need to send tick when motor is powered on - /* - * TODO - * Every CPU clock, add 8 to your bit timing clock. If your bit timing clock is >= optimal bit timing, - * then inject the next bit and subtract the optimal bit timing from your bit timing clock. - * That will give you 125ns resolution on your bits being fed to the sequencer. - */ + // run two LSS cycles = 2MHz @@ -118,10 +116,10 @@ void DiskController::tick() { } void DiskController::rotateCurrentDisk() { - this->t += 1.0f; - if (this->currentDrive->optimal_timing()/4.0f <= this->t) { // 4us interval between bits + this->t += 1.0; + if (this->currentDrive->optimal_timing()/4.0 <= this->t) { // wait for optimal interval between bits this->currentDrive->rotateDiskOneBit(); // (will also generate a read-pulse when it reads a 1-bit) - this->t -= this->currentDrive->optimal_timing()/4.0f; + this->t -= this->currentDrive->optimal_timing()/4.0; } } diff --git a/src/firmwarecard.cpp b/src/firmwarecard.cpp index 78053e6..2b0af00 100644 --- a/src/firmwarecard.cpp +++ b/src/firmwarecard.cpp @@ -45,7 +45,7 @@ void FirmwareCard::ioBankRom(const unsigned short addr, unsigned char* const pb, { if (this->inhibitBankRom) { - *pb = this->bankRom.read(addr); + *pb = this->bankRom.read(addr, *pb); this->inhibit = true; } } @@ -53,7 +53,7 @@ void FirmwareCard::ioBankRom(const unsigned short addr, unsigned char* const pb, { if (this->inhibitF8Rom) { - *pb = this->bankRom.read(addr); + *pb = this->bankRom.read(addr, *pb); this->inhibit = true; } } diff --git a/src/languagecard.cpp b/src/languagecard.cpp index ab1ad02..22cb3b0 100644 --- a/src/languagecard.cpp +++ b/src/languagecard.cpp @@ -73,11 +73,11 @@ void LanguageCard::ioBankRom(const unsigned short addr, unsigned char* const pb, { if (addr < 0x1000) { - *pb = this->ramBank[this->bank]->read(addr); + *pb = this->ramBank[this->bank]->read(addr, *pb); } else { - *pb = this->ramTop.read(addr-0x1000); + *pb = this->ramTop.read(addr-0x1000, *pb); } this->inhibit = true; } diff --git a/src/memory.cpp b/src/memory.cpp index f33e383..5bded7e 100644 --- a/src/memory.cpp +++ b/src/memory.cpp @@ -22,29 +22,6 @@ #include #include #include -#include "raminitializer.h" - - - -/* - * If any RAM IC sockets are empty, set the corresponding bits to 1 most of the time. - * But set to 0 instead, with probability 1 in 137 (a rough estimate obtained empirically) - */ -static std::uint8_t randomize_missing_bits(std::uint8_t v, const std::uint8_t bits) { - std::uint8_t bit = 1u; - for (std::uint_fast8_t i = 0; i < 8; ++i) { - if (bits & bit) { - double r = static_cast(std::rand())/RAND_MAX; - if (r < 1.0/137.0) { - v &= ~bit; - } else { - v |= bit; - } - } - bit <<= 1; - } - return v; -} @@ -54,25 +31,16 @@ Memory::Memory(const size_t n): missing_bits(0u) { } - - void Memory::clear() { std::fill(this->bytes.begin(), this->bytes.end(), this->clear_value); } -void Memory::init() { - RAMInitializer initRam(*this); - initRam.init(); -} - void Memory::load(const std::uint16_t base, std::istream& in) { in.read(reinterpret_cast(&this->bytes[base]), static_cast(this->bytes.size()-base)); } - - void Memory::powerOn() { - init(); + clear(); } void Memory::powerOff() { @@ -83,12 +51,8 @@ size_t Memory::size() const { return this->bytes.size(); } -std::uint8_t Memory::read(const std::uint16_t address) const { - std::uint8_t v = this->bytes[address]; - if (this->missing_bits) { - v = randomize_missing_bits(v, this->missing_bits); - } - return v; +std::uint8_t Memory::read(const std::uint16_t address, const std::uint8_t data) const { + return (this->bytes[address] & ~this->missing_bits) | (data & this->missing_bits); } void Memory::write(const std::uint16_t address, const std::uint8_t data) { diff --git a/src/memory.h b/src/memory.h index 85ba8d3..9dcfb61 100644 --- a/src/memory.h +++ b/src/memory.h @@ -30,10 +30,10 @@ class Memory { public: Memory(const size_t n); - virtual ~Memory() { } + virtual ~Memory() = default; size_t size() const; - std::uint8_t read(const std::uint16_t address) const; + std::uint8_t read(const std::uint16_t address, const std::uint8_t data) const; void write(const std::uint16_t address, const std::uint8_t data); void powerOn(); void powerOff(); diff --git a/src/memoryrandomaccess.cpp b/src/memoryrandomaccess.cpp index eb73a27..d6eaa14 100644 --- a/src/memoryrandomaccess.cpp +++ b/src/memoryrandomaccess.cpp @@ -59,44 +59,44 @@ bool MemoryRandomAccess::k20or24() const { } /* for 20K or 24K on rev. 0: pages 40-5F are dup w/ 60-7F */ -std::uint8_t MemoryRandomAccess::buggyRamRead(const std::uint16_t address) const { +std::uint8_t MemoryRandomAccess::buggyRamRead(const std::uint16_t address, std::uint8_t data) const { std::uint16_t ax = address & ~0x2000u; if (this->strapE.contains(ax)) { - return this->strapE.read(ax); + return this->strapE.read(ax, data); } if (this->strapD.contains(ax)) { - return this->strapD.read(ax); + return this->strapD.read(ax, data); } if (this->strapC.contains(ax)) { - return this->strapC.read(ax); + return this->strapC.read(ax, data); } ax = address | 0x2000u; if (this->strapE.contains(ax)) { - return this->strapE.read(ax); + return this->strapE.read(ax, data); } if (this->strapD.contains(ax)) { - return this->strapD.read(ax); + return this->strapD.read(ax, data); } if (this->strapC.contains(ax)) { - return this->strapC.read(ax); + return this->strapC.read(ax, data); } - return MemoryRow::missing_memory_byte_value(); + return data; } -std::uint8_t MemoryRandomAccess::read(const std::uint16_t address) const { +std::uint8_t MemoryRandomAccess::read(const std::uint16_t address, std::uint8_t data) const { if (this->revision == 0 && k20or24() && ((address & 0xC000u) == 0x4000u)) { - return buggyRamRead(address); + return buggyRamRead(address, data); } if (this->strapE.contains(address)) { - return this->strapE.read(address); + return this->strapE.read(address, data); } if (this->strapD.contains(address)) { - return this->strapD.read(address); + return this->strapD.read(address, data); } if (this->strapC.contains(address)) { - return this->strapC.read(address); + return this->strapC.read(address, data); } - return MemoryRow::missing_memory_byte_value(); + return data; } void MemoryRandomAccess::buggyRamWrite(std::uint16_t address, const std::uint8_t data) { diff --git a/src/memoryrandomaccess.h b/src/memoryrandomaccess.h index 5ea721e..940a5c1 100644 --- a/src/memoryrandomaccess.h +++ b/src/memoryrandomaccess.h @@ -18,7 +18,7 @@ class MemoryRandomAccess { MemoryRow &row_of(const std::string &row); MemoryStrapping &strapping_of(const std::string &row); - std::uint8_t buggyRamRead(std::uint16_t address) const; + std::uint8_t buggyRamRead(std::uint16_t address, std::uint8_t data) const; void buggyRamWrite(std::uint16_t address, const std::uint8_t data); bool k20or24() const; @@ -31,7 +31,7 @@ public: void remove_chip(const std::string &row, const std::uint_fast8_t socket); void strap_to(const std::string &row, std::uint16_t addr_base, std::uint16_t addr_size); - std::uint8_t read(std::uint16_t address) const; + std::uint8_t read(std::uint16_t address, const std::uint8_t data) const; void write(std::uint16_t address, const std::uint8_t data); void powerOn(); void powerOff(); diff --git a/src/memoryrow.cpp b/src/memoryrow.cpp index a0dfb5c..221a688 100644 --- a/src/memoryrow.cpp +++ b/src/memoryrow.cpp @@ -2,27 +2,6 @@ #include #include -/* - * If any RAM IC sockets are empty, set the corresponding bits to 1 most of the time. - * For some addresses it seems they are always 1, but for other addresses they can return - * 0 sometimes, empirically about 4% of the time. - */ -static std::uint8_t randomize_missing_bits(std::uint8_t v, const std::uint8_t bits) { - std::uint8_t bit = 1u; - for (std::uint_fast8_t i = 0; i < 8; ++i) { - if (bits & bit) { - double r = static_cast(std::rand())/RAND_MAX; - if (r < 0.04) { - v &= ~bit; - } else { - v |= bit; - } - } - bit <<= 1; - } - return v; -} - MemoryRow::MemoryRow(const char label): @@ -102,22 +81,23 @@ std::uint16_t MemoryRow::size() const { return static_cast(this->values_stored.size()); } -std::uint8_t MemoryRow::missing_memory_byte_value() { - return randomize_missing_bits(0xFFu, 0xFFu); -} - -std::uint8_t MemoryRow::read(const std::uint16_t address_offset) const { +std::uint8_t MemoryRow::read(const std::uint16_t address_offset, std::uint8_t data) const { if (this->power) { - std::uint8_t v; if (address_offset < this->values_stored.size()) { - v = this->values_stored[address_offset]; - if (this->missing_bits) { - v = randomize_missing_bits(v, this->missing_bits); - } - } else { - v = missing_memory_byte_value(); + /* We need to float the data bits corresponding to missing chips: + * 01010101 data bits (previously places on data bus from elsewhere) + * 00110011 mask of memory chips (1=missing, 0=present) + * 00001111 bits stored in chips + * -------- + * 00010001 data & missing + * 11001100 ~missing + * 00001100 stored & ~missing + * -------- + * 00011101 (stored & ~missing) | (data & missing) + */ + data = (this->values_stored[address_offset] & ~this->missing_bits) | (data & this->missing_bits); } - return v; + return data; } else { throw std::logic_error("cannot read memory when power is off"); } @@ -125,6 +105,8 @@ std::uint8_t MemoryRow::read(const std::uint16_t address_offset) const { void MemoryRow::write(const std::uint16_t address, const std::uint8_t data) { if (this->power) { + // if there are missing bits, they do get stored, so we need to + // be careful to mask them out when giving them back (in read method) this->values_stored[address] = data; } else { throw std::logic_error("cannot write memory when power is off"); diff --git a/src/memoryrow.h b/src/memoryrow.h index ed18fd5..5906bc0 100644 --- a/src/memoryrow.h +++ b/src/memoryrow.h @@ -40,11 +40,9 @@ class MemoryRow { /* 4K or 16K, size of each chip (or minimum in corner case of mixed sizes) */ std::uint16_t size() const; - std::uint8_t read(const std::uint16_t address) const; + std::uint8_t read(const std::uint16_t address, const std::uint8_t data) const; void write(const std::uint16_t address, const std::uint8_t data); - static std::uint8_t missing_memory_byte_value(); - std::string chip_id(std::uint_fast8_t socket) const; }; diff --git a/src/memorystrapping.cpp b/src/memorystrapping.cpp index 3bae794..91e2509 100644 --- a/src/memorystrapping.cpp +++ b/src/memorystrapping.cpp @@ -14,8 +14,8 @@ bool MemoryStrapping::contains(std::uint16_t address) const { return this->addr_base <= address && address < this->addr_base + size(); } -std::uint8_t MemoryStrapping::read(const std::uint16_t address) const { - return this->row.read(address - this->addr_base); +std::uint8_t MemoryStrapping::read(const std::uint16_t address, const std::uint8_t data) const { + return this->row.read(address - this->addr_base, data); } void MemoryStrapping::write(const std::uint16_t address, const std::uint8_t data) { diff --git a/src/memorystrapping.h b/src/memorystrapping.h index 5354774..47a92f1 100644 --- a/src/memorystrapping.h +++ b/src/memorystrapping.h @@ -13,7 +13,7 @@ class MemoryStrapping { MemoryStrapping(MemoryRow &row); void strap_to(std::uint16_t addr_base, std::uint16_t addr_size); bool contains(std::uint16_t address) const; - std::uint8_t read(const std::uint16_t address) const; + std::uint8_t read(const std::uint16_t address, const std::uint8_t data) const; void write(const std::uint16_t address, const std::uint8_t data); std::uint16_t size() const; }; diff --git a/src/raminitializer.cpp b/src/raminitializer.cpp deleted file mode 100644 index d660ed3..0000000 --- a/src/raminitializer.cpp +++ /dev/null @@ -1,137 +0,0 @@ -/* - epple2 - Copyright (C) 2008 by Christopher A. Mosher - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY, without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -#include "raminitializer.h" -#include "memory.h" -#include -#include - -RAMInitializer::RAMInitializer(Memory& mem): - ram(mem) -{ - srand(time(0)); -} - -void RAMInitializer::init() -{ - this->ram.clear(); - - int b(0); - // TODO make the types of RAM chips configurable - putBytesUntilFull(b++,1); - putBytesUntilFull(b++,2); - putBytesUntilFull(b++,1); - putBytesUntilFull(b++,2); - putBytesUntilFull(b++,1); - putBytesUntilFull(b++,2); - putBytesUntilFull(b++,2); - putBytesUntilFull(b++,1); -} - - -void RAMInitializer::putBytesUntilFull(int bit, int pat) -{ - this->nextinit = 0; - try - { - while (true) - { - if (pat==1) - ramPattern1(bit); - else - ramPattern2(bit); - } - } - catch (const done&) - { - // done filling this bit in RAM - } -} - -void RAMInitializer::ramPattern1(const int bit) -{ - for (int k = 0; k < 2; ++k) - { - for (int j = 0; j < 8; ++j) - { - int i; - for (i = 0; i < 0x10; ++i) - { - putn(4,false,bit); - putn(2,true,bit); - putn(2,false,bit); - } - for (i = 0; i < 0x40; ++i) - { - putn(2,true,bit); - putn(2,false,bit); - } - for (i = 0; i < 0x08; ++i) - { - putn(2,true,bit); - putn(1,false,bit); - putn(3,true,bit); - putn(2,false,bit); - putn(2,true,bit); - putn(2,false,bit); - putn(2,true,bit); - putn(2,false,bit); - } - } - for (int i = 0; i < 0x400; ++i) - { - putn(2,true,bit); - putn(2,false,bit); - } - } -} - -void RAMInitializer::ramPattern2(const int bit) -{ - for (int i = 0; i < 0x40; ++i) - { - putn(0x80,true,bit); - putn(0x80,false,bit); - } -} - - - -void RAMInitializer::putn(const int c, bool on, const int bit) -{ - if (((rand() >> 9) & 0x1F) == 5) - on = !on; - const unsigned char mask(1 << bit); - for (int i = 0; i < c; ++i) - { - if (this->nextinit >= this->ram.size()) - { - throw done(); - } - unsigned char b = this->ram.read(this->nextinit); - if (on) - { - b |= mask; - } - else - { - b &= ~mask; - } - this->ram.write(this->nextinit,b); - ++this->nextinit; - } -} diff --git a/src/raminitializer.h b/src/raminitializer.h deleted file mode 100644 index 0efc5b4..0000000 --- a/src/raminitializer.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - epple2 - Copyright (C) 2008 by Christopher A. Mosher - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY, without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ -#ifndef RAMINITIALIZER_H -#define RAMINITIALIZER_H - -class Memory; - -class RAMInitializer -{ -private: - class done {}; - - Memory& ram; - unsigned short nextinit; - - void putBytesUntilFull(int bit, int pat); - void ramPattern1(const int bit); - void ramPattern2(const int bit); - void putn(const int c, bool on, const int bit); - -public: - RAMInitializer(Memory& mem); - void init(); -}; - -#endif