Improve spiram class (#142)

* spiram::Block
* refactor SpiRAM instance
* use size_t where appropriate
This commit is contained in:
Stephen Crane authored and GitHub committed 2026-04-25 07:36:48 +01:00
1 parent c2673e2cd6
commit 0ae608c39f
10 files changed
+116 -64

No files matched your search

+2 -2
View File
@@ -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);
+6 -2
View File
@@ -26,7 +26,12 @@
#if defined(USE_SPIRAM)
#include <SpiRAM.h>
#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);
+19 -19
View File
@@ -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);
}
+4 -4
View File
@@ -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; }
+3 -3
View File
@@ -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;
+8 -8
View File
@@ -1,20 +1,20 @@
#pragma once
template<unsigned n = 1024>
template<size_t n = 1024>
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];
+3 -3
View File
@@ -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();
+14 -16
View File
@@ -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);
}
}
+55 -5
View File
@@ -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;
+2 -2
View File
@@ -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);