summaryrefslogtreecommitdiff
path: root/isa
diff options
context:
space:
mode:
Diffstat (limited to 'isa')
-rw-r--r--isa/checker.cpp22
-rw-r--r--isa/checker.h6
-rw-r--r--isa/decode.cpp20
-rw-r--r--isa/isa.h12
4 files changed, 39 insertions, 21 deletions
diff --git a/isa/checker.cpp b/isa/checker.cpp
index 1919bd1..7bca5c9 100644
--- a/isa/checker.cpp
+++ b/isa/checker.cpp
@@ -4,16 +4,17 @@
4#include "isa/isa.h" 4#include "isa/isa.h"
5 5
6void checker::execute() { 6void checker::execute() {
7 assert(!halted); 7 bool interrupt = system.interact(ctlregs);
8 auto int_enable_delay = ctlregs[INT_ENABLE] >> 1; 8
9 if (ctlregs[INT_ENABLE] & 1) { 9 if (ctlregs[HALTED])
10 // check for interrupt 10 return;
11 } 11
12 ctlregs[INT_ENABLE] = (int_enable_delay << 1) | int_enable_delay;
13 inst = decode(ctlregs[DATA_INSTRUCTION_FIELD_BUFFER], 12 inst = decode(ctlregs[DATA_INSTRUCTION_FIELD_BUFFER],
14 pc, 13 pc,
15 mem.fetch(pc)); 14 mem.fetch(pc),
15 interrupt);
16 auto next_pc = inst.next_pc; 16 auto next_pc = inst.next_pc;
17
17 if (inst.need_indirect_load) { 18 if (inst.need_indirect_load) {
18 auto addr = mem.fetch(inst.init_address.value()); 19 auto addr = mem.fetch(inst.init_address.value());
19 if (inst.need_autoinc_store) 20 if (inst.need_autoinc_store)
@@ -22,8 +23,10 @@ void checker::execute() {
22 } else { 23 } else {
23 assert(!inst.need_autoinc_store); 24 assert(!inst.need_autoinc_store);
24 } 25 }
26
25 if (inst.need_exec_load) 27 if (inst.need_exec_load)
26 inst.data = mem.fetch(inst.final_address.value()); 28 inst.data = mem.fetch(inst.final_address.value());
29
27 if (inst.need_read_acc) 30 if (inst.need_read_acc)
28 inst.acc = acc; 31 inst.acc = acc;
29 if (inst.need_read_link) 32 if (inst.need_read_link)
@@ -32,7 +35,9 @@ void checker::execute() {
32 inst.mq = mq; 35 inst.mq = mq;
33 if (inst.read_ctlreg.has_value()) 36 if (inst.read_ctlreg.has_value())
34 inst.ctlval = ctlregs[*inst.read_ctlreg]; 37 inst.ctlval = ctlregs[*inst.read_ctlreg];
38
35 inst.execute(); 39 inst.execute();
40
36 if (inst.need_write_acc) 41 if (inst.need_write_acc)
37 acc = inst.acc.value(); 42 acc = inst.acc.value();
38 if (inst.need_write_link) 43 if (inst.need_write_link)
@@ -41,9 +46,10 @@ void checker::execute() {
41 mq = inst.mq.value(); 46 mq = inst.mq.value();
42 if (inst.write_ctlreg.has_value()) 47 if (inst.write_ctlreg.has_value())
43 ctlregs[*inst.write_ctlreg] = inst.ctlval.value(); 48 ctlregs[*inst.write_ctlreg] = inst.ctlval.value();
49
44 if (inst.need_exec_store) 50 if (inst.need_exec_store)
45 mem.store(inst.final_address.value(), inst.data.value()); 51 mem.store(inst.final_address.value(), inst.data.value());
52
46 assert(inst.next_pc == next_pc || inst.possibly_redirects); 53 assert(inst.next_pc == next_pc || inst.possibly_redirects);
47 pc = inst.next_pc; 54 pc = inst.next_pc;
48 halted = inst.halt;
49} 55}
diff --git a/isa/checker.h b/isa/checker.h
index d70997f..332c483 100644
--- a/isa/checker.h
+++ b/isa/checker.h
@@ -3,6 +3,7 @@
3#include <array> 3#include <array>
4#include <map> 4#include <map>
5 5
6#include "io/model.h"
6#include "isa/isa.h" 7#include "isa/isa.h"
7 8
8struct funcmem { 9struct funcmem {
@@ -41,10 +42,11 @@ struct checker {
41 unsigned int mq = 0; 42 unsigned int mq = 0;
42 unsigned int pc = 00200; 43 unsigned int pc = 00200;
43 std::array<unsigned int, NUM_CTLREGS> ctlregs; 44 std::array<unsigned int, NUM_CTLREGS> ctlregs;
45 iomodel &system;
44 instruction_context inst; 46 instruction_context inst;
45 bool halted = false;
46 funcmem mem; 47 funcmem mem;
47 checker() 48 checker(iomodel &system)
49 : system(system)
48 { 50 {
49 ctlregs.fill(0); 51 ctlregs.fill(0);
50 } 52 }
diff --git a/isa/decode.cpp b/isa/decode.cpp
index 1979982..d24632b 100644
--- a/isa/decode.cpp
+++ b/isa/decode.cpp
@@ -2,15 +2,21 @@
2 2
3#include "isa/isa.h" 3#include "isa/isa.h"
4 4
5instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bits) 5instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bits, bool interrupt)
6{ 6{
7 instruction_context inst;
8
9 auto df = dfifb >> 3; 7 auto df = dfifb >> 3;
10 auto ifb = dfifb & 00007; 8 auto ifb = dfifb & 00007;
11 9
10 instruction_context inst;
12 inst.next_pc = (pc & ~07777) | ((pc + 1) & 07777); 11 inst.next_pc = (pc & ~07777) | ((pc + 1) & 07777);
13 12
13 if (interrupt) {
14 bits = 04000;
15 assert(df == 0);
16 assert(ifb == 0);
17 inst.next_pc = pc;
18 }
19
14 switch (bits >> 9) { 20 switch (bits >> 9) {
15 case 0: // AND 21 case 0: // AND
16 inst.need_exec_load = true; 22 inst.need_exec_load = true;
@@ -121,6 +127,8 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit
121 inst.need_read_acc = sma || sza; 127 inst.need_read_acc = sma || sza;
122 inst.need_read_link = snl; 128 inst.need_read_link = snl;
123 inst.need_write_acc = cla; 129 inst.need_write_acc = cla;
130 if (hlt)
131 inst.write_ctlreg = HALTED;
124 inst.possibly_redirects = true; 132 inst.possibly_redirects = true;
125 inst.ef = [cla, sma, sza, snl, osr, hlt](auto &ctx) { 133 inst.ef = [cla, sma, sza, snl, osr, hlt](auto &ctx) {
126 bool skip = false; 134 bool skip = false;
@@ -129,7 +137,7 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit
129 if (snl && ctx.link.value()) skip = true; 137 if (snl && ctx.link.value()) skip = true;
130 if (cla) ctx.acc = 0; 138 if (cla) ctx.acc = 0;
131 assert(!osr); 139 assert(!osr);
132 if (hlt) ctx.halt = true; 140 if (hlt) ctx.ctlval = 1;
133 if (skip) 141 if (skip)
134 ctx.next_pc = (ctx.next_pc & 070000) | ((ctx.next_pc + 1) & 007777); 142 ctx.next_pc = (ctx.next_pc & 070000) | ((ctx.next_pc + 1) & 007777);
135 }; 143 };
@@ -143,6 +151,8 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit
143 inst.need_read_acc = spa || sna; 151 inst.need_read_acc = spa || sna;
144 inst.need_read_link = szl; 152 inst.need_read_link = szl;
145 inst.need_write_acc = cla; 153 inst.need_write_acc = cla;
154 if (hlt)
155 inst.write_ctlreg = HALTED;
146 inst.possibly_redirects = true; 156 inst.possibly_redirects = true;
147 inst.ef = [cla, spa, sna, szl, osr, hlt](auto &ctx) { 157 inst.ef = [cla, spa, sna, szl, osr, hlt](auto &ctx) {
148 bool skip = true; 158 bool skip = true;
@@ -151,7 +161,7 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit
151 if (szl && ctx.link.value()) skip = false; 161 if (szl && ctx.link.value()) skip = false;
152 if (cla) ctx.acc = 0; 162 if (cla) ctx.acc = 0;
153 assert(!osr); 163 assert(!osr);
154 if (hlt) ctx.halt = true; 164 if (hlt) ctx.ctlval = 1;
155 if (skip) 165 if (skip)
156 ctx.next_pc = (ctx.next_pc & 070000) | ((ctx.next_pc + 1) & 007777); 166 ctx.next_pc = (ctx.next_pc & 070000) | ((ctx.next_pc + 1) & 007777);
157 }; 167 };
diff --git a/isa/isa.h b/isa/isa.h
index 11a8db2..bea484e 100644
--- a/isa/isa.h
+++ b/isa/isa.h
@@ -3,19 +3,20 @@
3#include <functional> 3#include <functional>
4#include <optional> 4#include <optional>
5 5
6#include "infra/pipetrace.h"
7
8enum ctlreg { 6enum ctlreg {
9 DATA_INSTRUCTION_FIELD_BUFFER, // (df << 3) | if_buffer 7 DATA_INSTRUCTION_FIELD_BUFFER, // (df << 3) | if_buffer
10 DATA_INSTRUCTION_FIELD_SAVED, // (df_saved << 3) | if_saved 8 DATA_INSTRUCTION_FIELD_SAVED, // (df_saved << 3) | if_saved
9 HALTED,
11 INT_ENABLE, // (int_enable_delay << 1) | int_enable 10 INT_ENABLE, // (int_enable_delay << 1) | int_enable
11 TT_INPUT, // (tti_flag << 8) | tti_buffer
12 TT_INPUT_INT_ENABLE,
13 TT_OUTPUT, // {tto_flag_old, tto_flag, tto_tx, tto_data}
14 TT_OUTPUT_INT_ENABLE,
12 15
13 NUM_CTLREGS, 16 NUM_CTLREGS,
14}; 17};
15 18
16struct instruction_context { 19struct instruction_context {
17 infra::transaction transaction;
18
19 // Known statically at decode time 20 // Known statically at decode time
20 bool need_indirect_load = false; // final_address = mem[init_address] 21 bool need_indirect_load = false; // final_address = mem[init_address]
21 bool need_autoinc_store = false; // mem[init_address] += 1 22 bool need_autoinc_store = false; // mem[init_address] += 1
@@ -43,7 +44,6 @@ struct instruction_context {
43 std::optional<unsigned int> acc; 44 std::optional<unsigned int> acc;
44 std::optional<bool> link; 45 std::optional<bool> link;
45 std::optional<unsigned int> mq; 46 std::optional<unsigned int> mq;
46 bool halt = false;
47}; 47};
48 48
49instruction_context decode(unsigned int df, unsigned int pc, unsigned int bits); 49instruction_context decode(unsigned int df, unsigned int pc, unsigned int bits, bool interrupt);