Created
February 11, 2021 18:31
-
-
Save leiradel/f8a21e553d413c6f6cfeeb6f63420313 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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