1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-02 19:54:35 +00:00

Attempted to fix interrupt response timing; ensured initial interrupt mode is one that won't jump beyond the interrupt response program table's length, and that the conditionals other than CALL definitely have no alternative program attached.

This commit is contained in:
Thomas Harte 2017-06-21 18:47:00 -04:00
parent 108da64562
commit 10cc94f581

View File

@ -84,9 +84,9 @@ struct MachineCycle {
}; };
// Elemental bus operations // Elemental bus operations
#define ReadOpcodeStart(addr, val) {MachineCycle::ReadOpcode, MachineCycle::Phase::Start, 2, &addr.full, &val, false} #define ReadOpcodeStart() {MachineCycle::ReadOpcode, MachineCycle::Phase::Start, 2, &pc_.full, &operation_, false}
#define ReadOpcodeWait(addr, val, f) {MachineCycle::ReadOpcode, MachineCycle::Phase::Wait, 1, &addr.full, &val, f} #define ReadOpcodeWait(length, f) {MachineCycle::ReadOpcode, MachineCycle::Phase::Wait, length, &pc_.full, &operation_, f}
#define Refresh(len) {MachineCycle::Refresh, MachineCycle::Phase::End, len, &ir_.full, nullptr, false} #define Refresh(len) {MachineCycle::Refresh, MachineCycle::Phase::End, len, &ir_.full, nullptr, false}
#define ReadStart(addr, val) {MachineCycle::Read, MachineCycle::Phase::Start, 2, &addr.full, &val, false} #define ReadStart(addr, val) {MachineCycle::Read, MachineCycle::Phase::Start, 2, &addr.full, &val, false}
#define ReadWait(l, addr, val, f) {MachineCycle::Read, MachineCycle::Phase::Wait, l, &addr.full, &val, f} #define ReadWait(l, addr, val, f) {MachineCycle::Read, MachineCycle::Phase::Wait, l, &addr.full, &val, f}
@ -104,6 +104,8 @@ struct MachineCycle {
#define OutputWait(addr, val, f) {MachineCycle::Output, MachineCycle::Phase::Wait, 1, &addr.full, &val, f} #define OutputWait(addr, val, f) {MachineCycle::Output, MachineCycle::Phase::Wait, 1, &addr.full, &val, f}
#define OutputEnd(addr, val) {MachineCycle::Output, MachineCycle::Phase::End, 1, &addr.full, &val} #define OutputEnd(addr, val) {MachineCycle::Output, MachineCycle::Phase::End, 1, &addr.full, &val}
#define IntAck(length) {MachineCycle::Operation::Interrupt, MachineCycle::Phase::End, length, nullptr, &operation_}
// A wrapper to express a bus operation as a micro-op // A wrapper to express a bus operation as a micro-op
#define BusOp(op) {MicroOp::BusOperation, nullptr, nullptr, op} #define BusOp(op) {MicroOp::BusOperation, nullptr, nullptr, op}
@ -316,10 +318,10 @@ template <class T> class Processor {
/* The following are actual instructions */ /* The following are actual instructions */
#define NOP Sequence(BusOp(Refresh(2))) #define NOP Sequence(BusOp(Refresh(2)))
#define JP(cc) StdInstr(Read16Inc(pc_, temp16_), {MicroOp::cc}, {MicroOp::Move16, &temp16_.full, &pc_.full}) #define JP(cc) StdInstr(Read16Inc(pc_, temp16_), {MicroOp::cc, nullptr}, {MicroOp::Move16, &temp16_.full, &pc_.full})
#define CALL(cc) StdInstr(ReadInc(pc_, temp16_.bytes.low), {MicroOp::cc, conditional_call_untaken_program_.data()}, Read4Inc(pc_, temp16_.bytes.high), Push(pc_), {MicroOp::Move16, &temp16_.full, &pc_.full}) #define CALL(cc) StdInstr(ReadInc(pc_, temp16_.bytes.low), {MicroOp::cc, conditional_call_untaken_program_.data()}, Read4Inc(pc_, temp16_.bytes.high), Push(pc_), {MicroOp::Move16, &temp16_.full, &pc_.full})
#define RET(cc) Instr(3, {MicroOp::cc}, Pop(memptr_), {MicroOp::Move16, &memptr_.full, &pc_.full}) #define RET(cc) Instr(3, {MicroOp::cc, nullptr}, Pop(memptr_), {MicroOp::Move16, &memptr_.full, &pc_.full})
#define JR(cc) StdInstr(ReadInc(pc_, temp8_), {MicroOp::cc}, InternalOperation(5), {MicroOp::CalculateIndexAddress, &pc_.full}, {MicroOp::Move16, &memptr_.full, &pc_.full}) #define JR(cc) StdInstr(ReadInc(pc_, temp8_), {MicroOp::cc, nullptr}, InternalOperation(5), {MicroOp::CalculateIndexAddress, &pc_.full}, {MicroOp::Move16, &memptr_.full, &pc_.full})
#define RST() Instr(3, {MicroOp::CalculateRSTDestination}, Push(pc_), {MicroOp::Move16, &memptr_.full, &pc_.full}) #define RST() Instr(3, {MicroOp::CalculateRSTDestination}, Push(pc_), {MicroOp::Move16, &memptr_.full, &pc_.full})
#define LD(a, b) StdInstr({MicroOp::Move8, &b, &a}) #define LD(a, b) StdInstr({MicroOp::Move8, &b, &a})
@ -712,14 +714,14 @@ template <class T> class Processor {
void assemble_fetch_decode_execute(InstructionPage &target, int length) { void assemble_fetch_decode_execute(InstructionPage &target, int length) {
const MicroOp normal_fetch_decode_execute[] = { const MicroOp normal_fetch_decode_execute[] = {
BusOp(ReadOpcodeStart(pc_, operation_)), BusOp(ReadOpcodeStart()),
BusOp(ReadOpcodeWait(pc_, operation_, true)), BusOp(ReadOpcodeWait(1, true)),
{ MicroOp::DecodeOperation } { MicroOp::DecodeOperation }
}; };
const MicroOp short_fetch_decode_execute[] = { const MicroOp short_fetch_decode_execute[] = {
BusOp(ReadOpcodeStart(pc_, operation_)), BusOp(ReadOpcodeStart()),
BusOp(ReadOpcodeWait(pc_, operation_, false)), BusOp(ReadOpcodeWait(1, false)),
BusOp(ReadOpcodeWait(pc_, operation_, true)), BusOp(ReadOpcodeWait(1, true)),
{ MicroOp::DecodeOperation } { MicroOp::DecodeOperation }
}; };
copy_program((length == 4) ? normal_fetch_decode_execute : short_fetch_decode_execute, target.fetch_decode_execute); copy_program((length == 4) ? normal_fetch_decode_execute : short_fetch_decode_execute, target.fetch_decode_execute);
@ -742,6 +744,7 @@ template <class T> class Processor {
Processor() : Processor() :
halt_mask_(0xff), halt_mask_(0xff),
number_of_cycles_(0), number_of_cycles_(0),
interrupt_mode_(0),
request_status_(Interrupt::PowerOn), request_status_(Interrupt::PowerOn),
last_request_status_(Interrupt::PowerOn), last_request_status_(Interrupt::PowerOn),
irq_line_(false), irq_line_(false),
@ -778,26 +781,28 @@ template <class T> class Processor {
MicroOp reset_program[] = Sequence(InternalOperation(3), {MicroOp::Reset}); MicroOp reset_program[] = Sequence(InternalOperation(3), {MicroOp::Reset});
MicroOp nmi_program[] = { MicroOp nmi_program[] = {
{ MicroOp::BeginNMI }, { MicroOp::BeginNMI },
// { MicroOp::BusOperation, nullptr, nullptr, {MachineCycle::ReadOpcode, 5, &pc_.full, &operation_}}, BusOp(ReadOpcodeStart()),
BusOp(ReadOpcodeWait(1, false)),
BusOp(Refresh(2)),
Push(pc_), Push(pc_),
{ MicroOp::JumpTo66, nullptr, nullptr}, { MicroOp::JumpTo66, nullptr, nullptr},
{ MicroOp::MoveToNextProgram } { MicroOp::MoveToNextProgram }
}; };
MicroOp irq_mode0_program[] = { MicroOp irq_mode0_program[] = {
{ MicroOp::BeginIRQMode0 }, { MicroOp::BeginIRQMode0 },
{ MicroOp::BusOperation, nullptr, nullptr, {MachineCycle::Operation::Interrupt, MachineCycle::Phase::End, 6, nullptr, &operation_}}, BusOp(IntAck(6)),
{ MicroOp::DecodeOperationNoRChange } { MicroOp::DecodeOperationNoRChange }
}; };
MicroOp irq_mode1_program[] = { MicroOp irq_mode1_program[] = {
{ MicroOp::BeginIRQ }, { MicroOp::BeginIRQ },
// { MicroOp::BusOperation, nullptr, nullptr, {MachineCycle::Operation::Interrupt, 7, nullptr, &operation_}}, BusOp(IntAck(7)),
Push(pc_), Push(pc_),
{ MicroOp::Move16, &temp16_.full, &pc_.full }, { MicroOp::Move16, &temp16_.full, &pc_.full },
{ MicroOp::MoveToNextProgram } { MicroOp::MoveToNextProgram }
}; };
MicroOp irq_mode2_program[] = { MicroOp irq_mode2_program[] = {
{ MicroOp::BeginIRQ }, { MicroOp::BeginIRQ },
// { MicroOp::BusOperation, nullptr, nullptr, {MachineCycle::Operation::Interrupt, 7, nullptr, &temp16_.bytes.low}}, BusOp(IntAck(7)),
Push(pc_), Push(pc_),
{ MicroOp::Move8, &ir_.bytes.high, &temp16_.bytes.high }, { MicroOp::Move8, &ir_.bytes.high, &temp16_.bytes.high },
Read16(pc_, temp16_), Read16(pc_, temp16_),