fix: user config writeable, memory init out of bounds for 4K, unstrapped memory, remove one instance of tinyfd

This commit is contained in:
Christopher A. Mosher 2022-12-10 11:26:39 -05:00
parent 5ff50c9c0c
commit 5c3d14b795
9 changed files with 55 additions and 41 deletions

View File

@ -151,8 +151,10 @@ void PreferencesDialog::Save(const std::filesystem::path& to) {
CTRL(wxTextCtrl, txtConfig);
const wxString sConfig = txtConfig->GetValue();
if (sConfig != this->sOrigConfig) {
BOOST_LOG_TRIVIAL(info) << "saving config file: " << to.c_str();
std::ofstream out(to);
out << sConfig;
out.flush();
this->sOrigConfig = sConfig;
}
}
@ -252,6 +254,7 @@ void PreferencesDialog::OnDuplicate(wxCommandEvent& evt) {
BOOST_LOG_TRIVIAL(info) << "copy from: " << data->path().c_str();
if (!std::filesystem::exists(f)) {
std::filesystem::copy_file(data->path(), f, std::filesystem::copy_options::skip_existing);
std::filesystem::permissions(f, std::filesystem::perms::owner_write, std::filesystem::perm_options::add);
BuildItemTree();
PreSelectUserConfigItemName(f);
} else {

View File

@ -14,7 +14,7 @@
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
*/
#include "apple2.h"
#include "slots.h"
#include "videomode.h"
@ -38,20 +38,20 @@
#include <istream>
#include <fstream>
Apple2::Apple2(KeypressQueue& keypresses, PaddleButtonStates& paddleButtonStates, AnalogTV& tv, HyperMode& fhyper, KeyboardBufferMode& buffered, ScreenImage& gui):
slts(gui),
kbd(keypresses,fhyper,buffered),
rom(AddressBus::MOTHERBOARD_ROM_SIZ),
ram(revision),
cassetteIn(gui),
cassetteOut(gui),
addressBus(gui,revision,ram,rom,kbd,videoMode,paddles,paddleButtonStates,speaker,cassetteIn,cassetteOut,slts),
picgen(tv,videoMode,revision),
video(videoMode,addressBus,picgen,textRows),
transistors("transistors"), // TODO load file from resources
cpu(NULL),
powerUpReset(*this),
revision(1) {
Apple2::Apple2(KeypressQueue& keypresses, PaddleButtonStates& paddleButtonStates, AnalogTV& tv, HyperMode& fhyper, KeyboardBufferMode& buffered, ScreenImage& gui) :
slts(gui),
kbd(keypresses, fhyper, buffered),
rom(AddressBus::MOTHERBOARD_ROM_SIZ),
ram(revision),
cassetteIn(gui),
cassetteOut(gui),
addressBus(gui, revision, ram, rom, kbd, videoMode, paddles, paddleButtonStates, speaker, cassetteIn, cassetteOut, slts),
picgen(tv, videoMode, revision),
video(videoMode, addressBus, picgen, textRows),
transistors("transistors"), // TODO load file from resources
cpu(NULL),
powerUpReset(*this),
revision(1) {
}
Apple2::~Apple2() {
@ -72,6 +72,7 @@ void Apple2::useVisual6502Cpu() {
}
void Apple2::tick() {
useEpple2Cpu(); // default, if not already set
this->cpu->tick();
this->slts.tick();
this->video.tick();
@ -85,8 +86,7 @@ void Apple2::tick() {
}
}
void Apple2::powerOn()
{
void Apple2::powerOn() {
useEpple2Cpu(); // default, if not already set
this->ram.powerOn();
this->cpu->powerOn();
@ -96,13 +96,12 @@ void Apple2::powerOn()
this->powerUpReset.powerOn();
}
void Apple2::powerOff()
{
void Apple2::powerOff() {
this->ram.powerOff();
}
void Apple2::reset()
{
void Apple2::reset() {
useEpple2Cpu(); // default, if not already set
this->cpu->reset();
this->slts.reset();
}

View File

@ -33,6 +33,7 @@
#include "cassetteout.h"
#include "tinyfiledialogs.h"
#include <wx/filedlg.h>
#include <wx/config.h>
#include <wx/string.h>
@ -456,14 +457,12 @@ void Config::tryParseLine(const std::string& line, MemoryRandomAccess& ram, Memo
trim(fn_optional);
if (fn_optional.length() == 0) {
gui.exitFullScreen();
char const *ft[1] = {"*.woz"};
char const *fn = tinyfd_openFileDialog("Load floppy", "", 1, ft, "WOZ 2.0 disk images", 0);
if (fn) {
fn_optional = std::string(fn);
wxFileDialog dlg{nullptr, "Load floppy", "", "", "WOZ 2.0 disk images (*.woz)|*.woz", wxFD_OPEN|wxFD_FILE_MUST_EXIST};
if (dlg.ShowModal() == wxID_OK) {
fn_optional = dlg.GetPath().c_str();
}
}
if (fn_optional.length() > 0) {
// TODO check if file exists, if not then check resources
loadDisk(slts, slot, drive, fn_optional);
}
} else if (cmd == "unload") {

View File

@ -24,7 +24,7 @@
*/
GUI::GUI() {
const int result = SDL_Init(SDL_INIT_TIMER | SDL_INIT_AUDIO | SDL_INIT_VIDEO);
const int result = SDL_Init(SDL_INIT_AUDIO | SDL_INIT_VIDEO);
if (result != 0) {
std::cerr << "Failed to initialize SDL: " << SDL_GetError() << std::endl;
throw GUI::NotInitException();

View File

@ -36,7 +36,7 @@ void Memory::clear() {
}
void Memory::load(const std::uint16_t base, std::istream& in) {
in.read(reinterpret_cast<char*>(&this->bytes[base]), static_cast<ptrdiff_t>(this->bytes.size()-base));
in.read(reinterpret_cast<char*>(&this->bytes.at(base)), static_cast<ptrdiff_t>(this->bytes.size()-base));
}
void Memory::powerOn() {
@ -52,9 +52,9 @@ size_t Memory::size() const {
}
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);
return (this->bytes.at(address) & ~this->missing_bits) | (data & this->missing_bits);
}
void Memory::write(const std::uint16_t address, const std::uint8_t data) {
this->bytes[address] = data;
this->bytes.at(address) = data;
}

View File

@ -78,7 +78,7 @@ void MemoryChip::rand_init(const std::uint8_t mask, std::vector<std::uint8_t> &b
std::uint_fast32_t c_chaos16 = 65u;
std::uint_fast32_t c_chaos16sub = 15u;
bool on = false;
for (std::uint_fast16_t i = 0u; i < 16*K; ++i) {
for (std::uint_fast16_t i = 0u; i < size; ++i) {
double r = static_cast<double>(std::rand())/RAND_MAX;
bool is_rand = false;
if (r < GLITCH && c_chaos16 == 65u) {
@ -94,7 +94,7 @@ void MemoryChip::rand_init(const std::uint8_t mask, std::vector<std::uint8_t> &b
}
}
is_rand |= (r < CHAOS);
bitflag(is_rand?!on:on, mask, bytes[i]);
bitflag(is_rand?!on:on, mask, bytes.at(i));
if (c_cycle++ == cycle-1) {
on = !on;
c_cycle = 0u;

View File

@ -16,7 +16,7 @@ void MemoryRow::insert_chip(MemoryChip *chip, const std::uint_fast8_t socket) {
if (socket < 8u) {
remove_chip(socket);
if (chip->exists()) {
this->chips[socket] = chip;
this->chips.at(socket) = chip;
this->missing_bits &= ~(1u << socket);
this->values_stored.resize(calculate_size());
}
@ -27,7 +27,7 @@ void MemoryRow::insert_chip(MemoryChip *chip, const std::uint_fast8_t socket) {
void MemoryRow::remove_chip(const std::uint_fast8_t socket) {
if (socket < 8u) {
this->chips[socket] = MemoryChip::instance("-");
this->chips.at(socket) = MemoryChip::instance("-");
this->missing_bits |= (1u << socket);
this->values_stored.resize(calculate_size());
} else {
@ -43,7 +43,7 @@ std::uint16_t MemoryRow::calculate_size() const {
std::uint16_t size_new = 0u;
for (std::uint_fast8_t i_chip = 0; i_chip < 8; ++i_chip) {
const MemoryChip *chip = this->chips[i_chip];
const MemoryChip *chip = this->chips.at(i_chip);
if (chip->exists()) {
const std::uint16_t s = chip->size();
if (size_new == 0u || s < size_new) {
@ -68,7 +68,7 @@ void MemoryRow::powerOn() {
std::uint8_t mask_bit = 1u;
for (std::uint_fast8_t i_bit = 0; i_bit < 8; ++i_bit) {
const MemoryChip *chip = this->chips[i_bit];
const MemoryChip *chip = this->chips.at(i_bit);
if (chip->exists()) {
chip->init(mask_bit, this->values_stored, size());
}
@ -95,7 +95,7 @@ std::uint8_t MemoryRow::read(const std::uint16_t address_offset, std::uint8_t da
* --------
* 00011101 (stored & ~missing) | (data & missing)
*/
data = (this->values_stored[address_offset] & ~this->missing_bits) | (data & this->missing_bits);
data = (this->values_stored.at(address_offset) & ~this->missing_bits) | (data & this->missing_bits);
}
return data;
} else {
@ -107,12 +107,12 @@ 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;
this->values_stored.at(address) = data;
} else {
throw std::logic_error("cannot write memory when power is off");
}
}
std::string MemoryRow::chip_id(std::uint_fast8_t socket) const {
return this->chips[socket]->id();
return this->chips.at(socket)->id();
}

View File

@ -1,27 +1,39 @@
#include "memorystrapping.h"
#include <algorithm>
MemoryStrapping::MemoryStrapping(MemoryRow &row):
row(row) {
MemoryStrapping::MemoryStrapping(MemoryRow &row): row{row}, strapped{false} {
}
void MemoryStrapping::strap_to(std::uint16_t addr_base, std::uint16_t addr_size) {
this->addr_base = addr_base;
this->addr_size = addr_size;
this->strapped = true;
}
bool MemoryStrapping::contains(std::uint16_t address) const {
if (!this->strapped) {
return false;
}
return this->addr_base <= address && address < this->addr_base + size();
}
std::uint8_t MemoryStrapping::read(const std::uint16_t address, const std::uint8_t data) const {
if (!this->strapped) {
return 0xFFu;
}
return this->row.read(address - this->addr_base, data);
}
void MemoryStrapping::write(const std::uint16_t address, const std::uint8_t data) {
if (!this->strapped) {
return;
}
this->row.write(address - this->addr_base, data);
}
std::uint16_t MemoryStrapping::size() const {
if (!this->strapped) {
return 0;
}
return std::min(this->row.size(), this->addr_size);
}

View File

@ -6,6 +6,7 @@
class MemoryStrapping {
private:
bool strapped;
MemoryRow &row;
std::uint16_t addr_base;
std::uint16_t addr_size;