From 0ae608c39fcb7326607d4e93420ed969dbab1a52 Mon Sep 17 00:00:00 2001 From: Stephen Crane Date: Sat, 25 Apr 2026 07:36:48 +0100 Subject: [PATCH] Improve spiram class (#142) * spiram::Block * refactor SpiRAM instance * use size_t where appropriate --- src/acia.h | 4 +-- src/arduinomachine.cpp | 8 ++++-- src/memory.h | 38 +++++++++++++------------- src/pia.h | 8 +++--- src/prom.h | 6 ++--- src/ram.h | 16 +++++------ src/riot.h | 6 ++--- src/spiram.cpp | 30 ++++++++++----------- src/spiram.h | 60 ++++++++++++++++++++++++++++++++++++++---- src/via.h | 4 +-- 10 files changed, 116 insertions(+), 64 deletions(-) diff --git a/src/acia.h b/src/acia.h index ab76c49..5fa2913 100644 --- a/src/acia.h +++ b/src/acia.h @@ -8,8 +8,8 @@ class ACIA: public Pollable, public Memory::Device { public: ACIA(): Memory::Device(2) {} - void operator=(uint8_t b) { write(_acc, b); } - operator uint8_t() { return read(_acc); } + void operator=(uint8_t b) override { write(_acc, b); } + operator uint8_t() override { return read(_acc); } void write(Memory::address, uint8_t); uint8_t read(Memory::address); diff --git a/src/arduinomachine.cpp b/src/arduinomachine.cpp index 747cbac..b3b1642 100644 --- a/src/arduinomachine.cpp +++ b/src/arduinomachine.cpp @@ -26,7 +26,12 @@ #if defined(USE_SPIRAM) #include #include "spiram.h" -spiram sram(SPIRAM_SIZE); + +extern SPIClass SPIRAM_DEV; + +static SpiRAM spiRam(SPIRAM_DEV, SPIRAM_CS); + +spiram sram(spiRam, SPIRAM_SIZE); #endif bool Arduino::reset() { @@ -36,7 +41,6 @@ bool Arduino::reset() { bool success = false; #if defined(USE_SPIRAM) - extern SPIClass SPIRAM_DEV; SPIRAM_DEV.begin(); #if defined(SPIRAM_MODULE) SPIRAM_DEV.setModule(SPIRAM_MODULE); diff --git a/src/memory.h b/src/memory.h index 544c84f..91f8316 100644 --- a/src/memory.h +++ b/src/memory.h @@ -4,15 +4,15 @@ class Memory { public: typedef uint16_t address; - static const unsigned address_size = (1 << 16); - static const unsigned page_size = (1 << 8); + static const size_t address_size = (1 << 16); + static const size_t page_size = (1 << 8); class Device: public Checkpointable { public: - Device(unsigned extent): _extent(extent) {} + Device(size_t extent): _extent(extent) {} virtual ~Device() {} - unsigned extent() const { return _extent; } + size_t extent() const { return _extent; } virtual void access(address a) { _acc = a-_base; } void base(address a) { _base = a; } address base() const { return _base; } @@ -20,43 +20,43 @@ public: virtual void operator=(uint8_t) =0; virtual operator uint8_t() =0; - virtual void checkpoint(Checkpoint &) {}; - virtual void restore(Checkpoint &) {}; + virtual void checkpoint(Checkpoint &) override {}; + virtual void restore(Checkpoint &) override {}; protected: address _acc, _base; private: - unsigned _extent; + size_t _extent; }; class Null: public Device { public: - Null(unsigned extent): Device(extent) {} + Null(size_t extent): Device(extent) {} - void operator=(uint8_t) {} - operator uint8_t() { return 0; } + void operator=(uint8_t) override {} + operator uint8_t() override { return 0; } }; class Devices: public Device { public: - static const unsigned device_size = (1 << 4); + static const size_t device_size = (1 << 4); Devices(): Device(page_size), _nd(page_size) { put(_nd, 0); } - void operator=(uint8_t); - operator uint8_t(); + void operator=(uint8_t) override; + operator uint8_t() override; - void checkpoint(Checkpoint &); - void restore(Checkpoint &); + void checkpoint(Checkpoint &) override; + void restore(Checkpoint &) override; void put(Device &d, address at); private: - unsigned slots(Device *dev) const { - unsigned e = dev->extent(); + size_t slots(Device *dev) const { + size_t e = dev->extent(); return e / device_size + (e % device_size? 1: 0); } @@ -64,13 +64,13 @@ public: Null _nd; }; - void put(Device &d, address base, unsigned extent); + void put(Device &d, address base, size_t extent); void put(Device &d, address base) { put(d, base, d.extent()); } virtual Device *get(address a) const { return _pages[a / page_size]; } - unsigned pages(unsigned extent) const { + size_t pages(size_t extent) const { return extent / page_size + (extent % page_size? 1: 0); } diff --git a/src/pia.h b/src/pia.h index 0037d90..bc391f9 100644 --- a/src/pia.h +++ b/src/pia.h @@ -16,14 +16,14 @@ public: irq_a1 = irq_a2 = irqa_state = irq_b1 = irq_b2 = irqb_state = ca1 = ca2 = cb1 = cb2 = false; } - void operator=(uint8_t b) { write(_acc, b); } - operator uint8_t() { return read(_acc); } + void operator=(uint8_t b) override { write(_acc, b); } + operator uint8_t() override { return read(_acc); } void write(Memory::address, uint8_t); uint8_t read(Memory::address); - void checkpoint(Checkpoint &); - void restore(Checkpoint &); + void checkpoint(Checkpoint &) override; + void restore(Checkpoint &) override; // device input (external) interface void write_porta_in(uint8_t b) { ina = b; } diff --git a/src/prom.h b/src/prom.h index 63e88e8..a672eb5 100644 --- a/src/prom.h +++ b/src/prom.h @@ -2,10 +2,10 @@ class prom: public Memory::Device { public: - virtual void operator= (uint8_t) {} - virtual operator uint8_t () { return pgm_read_byte(_mem+_acc); } + prom(const uint8_t *mem, size_t size): Memory::Device(size), _mem(mem) {} - prom(const uint8_t *mem, int uint8_ts): Memory::Device(uint8_ts), _mem(mem) {} + void operator=(uint8_t) override {} + operator uint8_t() override { return pgm_read_byte(_mem+_acc); } private: const uint8_t *_mem; diff --git a/src/ram.h b/src/ram.h index 50d82c7..0a8376f 100644 --- a/src/ram.h +++ b/src/ram.h @@ -1,20 +1,20 @@ #pragma once -template +template class ram: public Memory::Device { public: - static const unsigned page_size = n; + static const size_t page_size = n; + + ram (): Memory::Device(n) {} inline void set(Memory::address a, uint8_t b) { _mem[a] = b; } inline uint8_t get(Memory::address a) { return _mem[a]; } - virtual void operator= (uint8_t c) { set(_acc, c); } - virtual operator uint8_t () { return get(_acc); } + void operator= (uint8_t c) override { set(_acc, c); } + operator uint8_t() override { return get(_acc); } - virtual void checkpoint(Checkpoint &s) { s.write(_mem, sizeof(_mem)); } - virtual void restore(Checkpoint &s) { s.read(_mem, sizeof(_mem)); } - - ram (): Memory::Device(n) {} + void checkpoint(Checkpoint &s) override { s.write(_mem, sizeof(_mem)); } + void restore(Checkpoint &s) override { s.read(_mem, sizeof(_mem)); } private: uint8_t _mem[n]; diff --git a/src/riot.h b/src/riot.h index bd59f7f..f4e079f 100644 --- a/src/riot.h +++ b/src/riot.h @@ -5,13 +5,13 @@ class RIOT: public Memory::Device { public: - RIOT(unsigned extent = 256): Memory::Device(extent), outb(0), inb(0xff), outa(0), ina(0xff), ddrb(0), ddra(0), + RIOT(size_t extent = 256): Memory::Device(extent), outb(0), inb(0xff), outa(0), ina(0xff), ddrb(0), ddra(0), ie_timer(false), irq_timer(false), ie_edge(false), irq_edge(false), pa7(1), pa7_dir(0), timer(-1) { } - void operator=(uint8_t b) { write(_acc, b); } - operator uint8_t() { return read(_acc); } + void operator=(uint8_t b) override { write(_acc, b); } + operator uint8_t() override { return read(_acc); } void reset(); diff --git a/src/spiram.cpp b/src/spiram.cpp index b7bc2f0..75540a5 100644 --- a/src/spiram.cpp +++ b/src/spiram.cpp @@ -8,37 +8,35 @@ #include "memory.h" #include "spiram.h" -extern SPIClass SPIRAM_DEV; - -static SpiRAM spiRam(SPIRAM_DEV, SPIRAM_CS); - -void spiram::operator=(uint8_t b) +void spiram::put(Memory::address a, uint8_t b) { - spiRam.write_byte(_acc, b); + spiRam.write_byte(a, b); } -spiram::operator uint8_t() +uint8_t spiram::get(Memory::address a) { - return spiRam.read_byte(_acc); + return spiRam.read_byte(a); } -void spiram::checkpoint(Checkpoint &s) +void spiram::checkpoint(Checkpoint &c, Memory::address addr, size_t len) { uint8_t buf[256]; - unsigned pages = extent() / 256; + unsigned pages = len / sizeof(buf); for (unsigned i = 0; i < pages; i++) { - spiRam.read_stream(i * 256, buf, sizeof(buf)); - s.write(buf, sizeof(buf)); + spiRam.read_stream(addr, buf, sizeof(buf)); + c.write(buf, sizeof(buf)); + addr += sizeof(buf); } } -void spiram::restore(Checkpoint &s) +void spiram::restore(Checkpoint &c, Memory::address addr, size_t len) { uint8_t buf[256]; - unsigned pages = extent() / 256; + unsigned pages = len / sizeof(buf); for (unsigned i = 0; i < pages; i++) { - s.read(buf, sizeof(buf)); - spiRam.write_stream(i * 256, buf, sizeof(buf)); + c.read(buf, sizeof(buf)); + spiRam.write_stream(addr, buf, sizeof(buf)); + addr += sizeof(buf); } } diff --git a/src/spiram.h b/src/spiram.h index 6644d75..e46a83d 100644 --- a/src/spiram.h +++ b/src/spiram.h @@ -1,15 +1,65 @@ #pragma once +class SpiRAM; + class spiram: public Memory::Device { public: - virtual void operator= (uint8_t c); - virtual operator uint8_t (); + spiram(SpiRAM &sram, size_t bytes): Memory::Device(bytes), spiRam(sram) {} - virtual void checkpoint(Checkpoint &); - virtual void restore(Checkpoint &); + virtual void operator=(uint8_t c) override { put(_acc, c); } + virtual operator uint8_t() override { return get(_acc); } + + virtual void checkpoint(Checkpoint &c) override { checkpoint(c, 0, extent()); } + virtual void restore(Checkpoint &c) override { restore(c, 0, extent()); } - spiram(unsigned bytes): Memory::Device(bytes) {} void begin(uint8_t cs, int module); + + class Block: public Memory::Device { + public: + Block(spiram &sr, size_t size): Memory::Device(size), _sr(sr) { + _block_offset = _sr.allocate(size); + } + + void operator=(uint8_t c) override { + _sr.put(_acc + _block_offset, c); + } + + operator uint8_t() override { + return _sr.get(_acc + _block_offset); + } + + void checkpoint(Checkpoint &c) override { + _sr.checkpoint(c, _block_offset, extent()); + } + + void restore(Checkpoint &c) override { + _sr.restore(c, _block_offset, extent()); + } + + private: + Memory::address _block_offset; + + spiram &_sr; + }; + +private: + void put(Memory::address offset, uint8_t c); + + uint8_t get(Memory::address offset); + + void checkpoint(Checkpoint &, Memory::address, size_t); + + void restore(Checkpoint &, Memory::address, size_t); + + Memory::address _next_block = 0; + + Memory::address allocate(size_t size) { + Memory::address offset = _next_block; + _next_block += size; + return offset; + } + + SpiRAM &spiRam; }; extern class spiram sram; diff --git a/src/via.h b/src/via.h index 9e26050..3245f7b 100644 --- a/src/via.h +++ b/src/via.h @@ -20,8 +20,8 @@ public: _sr = _acr = _pcr = _ier = _ifr = _porta = _portb = _ddra = _ddrb = 0; } - void operator=(uint8_t b) { write(_acc, b); } - operator uint8_t() { return read(_acc); } + void operator=(uint8_t b) override { write(_acc, b); } + operator uint8_t() override { return read(_acc); } void write(Memory::address, uint8_t); uint8_t read(Memory::address);