fix: user config writeable, memory init out of bounds for 4K, unstrapped memory, remove one instance of tinyfd
This commit is contained in:
parent
5ff50c9c0c
commit
5c3d14b795
|
@ -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 {
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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") {
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
class MemoryStrapping {
|
||||
private:
|
||||
bool strapped;
|
||||
MemoryRow &row;
|
||||
std::uint16_t addr_base;
|
||||
std::uint16_t addr_size;
|
||||
|
|
Loading…
Reference in New Issue