mirror of
https://github.com/jscrane/r65emu.git
synced 2026-04-26 22:18:15 +00:00
Improve spiram class (#142)
* spiram::Block * refactor SpiRAM instance * use size_t where appropriate
This commit is contained in:
1 parent
c2673e2cd6
commit
0ae608c39f
10 files changed
+116
-64
No files matched your search
+2
-2
@@ -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);
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
Reference in new issue
Block a user