1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-01 13:58:20 +00:00

Reformulated the machine cycle slightly to support posting operation plus phase, thereby exposing the segue points at which waits might be inserted. So: to stick to the rule that CPUs expose the minimum amount of information sufficient completely to reconstruct bus activity. This breaks the Z80 for now.

This commit is contained in:
Thomas Harte 2017-06-18 12:21:27 -04:00
parent e1a2580b2a
commit ebc7356db5

View File

@ -65,17 +65,55 @@ enum Flag: uint8_t {
struct MachineCycle {
enum Operation {
ReadOpcode = 0,
Refresh,
Read, Write,
Input, Output,
Interrupt,
BusAcknowledge,
Internal
} operation;
enum Phase {
Start,
Wait,
End
} phase;
int length;
uint16_t *address;
uint8_t *value;
};
#define ReadOpcodeStart(addr, val) {MachineCycle::ReadOpcode, Phase::Start, 2, addr, val)
#define ReadOpcodeWait(addr, val) {MachineCycle::ReadOpcode, Phase::Wait, 1, addr, val)
#define Refresh(len) {MachineCycle::Refresh, Phase::Start, 2, &ir_.full, nullptr)
#define ReadStart(addr, val) {MachineCycle::Read, Phase::Start, 2, addr, val)
#define ReadWait(addr, val) {MachineCycle::Read, Phase::Wait, 1, addr, val)
#define ReadEnd(addr, val) {MachineCycle::Read, Phase::End, 1, addr, val)
#define WriteStart(addr, val) {MachineCycle::Write, Phase::Start, 2, addr, val)
#define WriteWait(addr, val) {MachineCycle::Write, Phase::Wait, 1, addr, val)
#define WriteEnd(addr, val) {MachineCycle::Write, Phase::End, 1, addr, val)
#define InputStart(addr, val) {MachineCycle::Input, Phase::Start, 3, addr, val)
#define InputWait(addr, val) {MachineCycle::Input, Phase::Wait, 1, addr, val)
#define InputEnd(addr, val) {MachineCycle::Input, Phase::End, 1, addr, val)
#define OutpuStart(addr, val) {MachineCycle::Output, Phase::Start, 3, addr, val)
#define OutpuWait(addr, val) {MachineCycle::Output, Phase::Wait, 1, addr, val)
#define OutpuEnd(addr, val) {MachineCycle::Output, Phase::End, 1, addr, val)
#define BusOp(c) {MicroOp::BusOperation, nullptr, nullptr, c}
#define Read(addr, val) BusOp(ReadStart(addr, val)), BusOp(ReadWait(addr, val)), BusOp(ReadEnd(addr, val))
#define Write(addr, val) BusOp(WriteStart(addr, val)), BusOp(WriteWait(addr, val)), BusOp(WriteEnd(addr, val))
#define Input(addr, val) BusOp(InputStart(addr, val)), BusOp(InputWait(addr, val)), BusOp(InputEnd(addr, val))
#define Output(addr, val) BusOp(OutputStart(addr, val)), BusOp(OutputWait(addr, val)), BusOp(OutputEnd(addr, val))
#define InternalOperation(n) BusOp({MachineCycle::Internal, n})
#define Sequence(...) { __VA_ARGS__, {MicroOp::MoveToNextProgram} }
#define Instr(r, ...) Sequence(BusOp(Refresh(r)), __VA_ARGS__)
#define StdInstr(...) Instr(2, __VA_ARGS_)
/*!
@abstact An abstract base class for emulation of a Z80 processor via the curiously recurring template pattern/f-bounded polymorphism.
@ -325,9 +363,6 @@ template <class T> class Processor {
#define ADC16(d, s) Program(WAIT(4), WAIT(3), {MicroOp::ADC16, &s.full, &d.full})
#define SBC16(d, s) Program(WAIT(4), WAIT(3), {MicroOp::SBC16, &s.full, &d.full})
#define WAIT(n) {MicroOp::BusOperation, nullptr, nullptr, {MachineCycle::Internal, n} }
#define Program(...) { __VA_ARGS__, {MicroOp::MoveToNextProgram} }
#define isTerminal(n) (n == MicroOp::MoveToNextProgram || n == MicroOp::DecodeOperation || n == MicroOp::DecodeOperationNoRChange)
typedef MicroOp InstructionTable[256][20];