Skip to content

Instantly share code, notes, and snippets.

@leiradel
Created February 11, 2021 18:31
Show Gist options
  • Save leiradel/f8a21e553d413c6f6cfeeb6f63420313 to your computer and use it in GitHub Desktop.
Save leiradel/f8a21e553d413c6f6cfeeb6f63420313 to your computer and use it in GitHub Desktop.
#include <inttypes.h>
#include <vector>
class Resumable {
public:
void resume(unsigned const continuationToken) { (void)continuationToken; }
};
template<typename T>
class Bus {
public:
enum {
// Address bus
A0, A1, A2, A3, A4, A5, A6, A7, A8, A9, A10, A11, A12, A13, A14, A15,
// Data bus
D0, D1, D2, D3, D4, D5, D6, D7, D8,
// CPU control bus
nINT, nNMI, nHALT, nMREQ, nIORQ, nRFSH, nM1, nRESET, nBUSRQ, nWAIT, nBUSACK, nWR, nRD,
};
static uint64_t const AddressMask = UINT64_C(0xffff);
static unsigned const AddressShift = 0;
static uint64_t const DataMask = UINT64_C(0xff0000);
static unsigned const DataShift = 16;
Bus() : _pins(0), _floating(UINT64_MAX), _now(0) {}
// Pin handling
void set(unsigned const pin) {
uint64_t const b = bit(pin);
_pins |= b;
_floating &= ~b;
}
void reset(unsigned const pin) {
uint64_t const b = bit(pin);
_pins &= ~b;
_floating &= ~b;
}
void float_(unsigned const pin) {
uint64_t const b = bit(pin);
_floating |= b;
}
bool isSet(unsigned const pin) const {
uint64_t const b = bit(pin);
return (_pins & b & ~_floating) != 0;
}
bool isReset(unsigned const pin) const {
uint64_t const b = bit(pin);
return (~_pins & b & ~_floating) != 0;
}
bool isFloating(unsigned const pin) const {
uint64_t const b = bit(pin);
return (_floating & b) != 0;
}
// Embedded buses
void setAddress(uint16_t const address) {
_pins = (_pins & ~AddressMask) | (address << AddressShift);
_floating &= ~AddressMask;
}
uint16_t getAddress() const {
return (_pins & AddressMask) >> AddressShift;
}
void floatAddress() {
_floating |= AddressMask;
}
void setData(uint8_t const data) {
_pins = (_pins & ~DataMask) | (data << DataShift);
_floating &= ~DataShift;
}
uint8_t getData() const {
return (_pins & DataMask) >> DataShift;
}
void floatData() {
_floating |= DataMask;
}
// Bus events
void post(uint8_t const id, uint64_t const timestamp, unsigned const continuationToken) {}
protected:
struct Event {
uint64_t timestamp;
unsigned continuationToken;
uint8_t id;
};
uint64_t bit(unsigned const pin) const { return UINT64_C(1) << (pin & 63); }
uint64_t _pins;
uint64_t _floating;
uint64_t _now; // nanoseconds
std::vector<Event> _events; // priority queue
};
template<typename T, uint8_t I>
class Z80 : public Resumable {
public:
void init() {
post(I, bus()._now + 40, CheckReset);
}
void resume(unsigned const continuationToken) {
switch (continuationToken) {
}
}
protected:
enum {
CheckReset
};
Bus<T>& bus() { return *static_cast<Bus<T>*>(this); }
};
class System : Bus<System>, public Z80<System, 0> {
public:
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment