summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Blake Kongslie2022-10-31 19:55:32 -0700
committerJulian Blake Kongslie2022-10-31 19:55:32 -0700
commit6b45e0f81267be6140f0f178579494ca6d24443b (patch)
treec0ed8beeb65259e3069dd04ddff54b4b16593310
parentLevel-trigger on TTO_FLAG instead of edge-trigger. (diff)
downloadbiggolf-6b45e0f81267be6140f0f178579494ca6d24443b.tar.xz
Restructure a lot of the control registers
-rw-r--r--io/model.cpp19
-rw-r--r--isa/checker.cpp4
-rw-r--r--isa/ctlreg.def10
-rw-r--r--isa/decode.cpp45
-rw-r--r--isa/isa.h20
5 files changed, 62 insertions, 36 deletions
diff --git a/io/model.cpp b/io/model.cpp
index fcabbd2..fb9f62b 100644
--- a/io/model.cpp
+++ b/io/model.cpp
@@ -24,24 +24,25 @@ bool iomodel::interact(std::array<std::uint_fast32_t, NUM_CTLREGS> &ctlregs) {
24 } 24 }
25 25
26 bool interrupt = false; 26 bool interrupt = false;
27 if (ctlregs[TT_INT_ENABLE]) { 27 if (ctlregs[TT_FLAGS] & TTF_INT_ENABLE) {
28 if (ctlregs[TT_BITS] & TTI_FLAG) 28 if (ctlregs[TT_BITS] & TTI_FLAG)
29 interrupt = true; 29 interrupt = true;
30 }
31 if (ctlregs[TT_INT_ENABLE]) {
32 if (ctlregs[TT_BITS] & TTO_FLAG) 30 if (ctlregs[TT_BITS] & TTO_FLAG)
33 interrupt = true; 31 interrupt = true;
34 } 32 }
35 ctlregs[INT_PENDING] = interrupt; 33 if (interrupt)
36 interrupt = interrupt && (ctlregs[INT_ENABLE] & 1); 34 ctlregs[FLAGS] |= FLAG_INT_REQUEST;
35 else
36 ctlregs[FLAGS] &= !FLAG_INT_REQUEST;
37 interrupt = interrupt && (ctlregs[FLAGS] & FLAG_INT_ENABLE);
37 38
38 if (interrupt) { 39 if (interrupt) {
39 ctlregs[DATA_INSTRUCTION_FIELD_SAVED] = ctlregs[DATA_INSTRUCTION_FIELD_BUFFER]; 40 ctlregs[FLAGS_SAVED] = ctlregs[FLAGS];
40 ctlregs[DATA_INSTRUCTION_FIELD_BUFFER] = 0; 41 ctlregs[FLAGS] = 0;
41 ctlregs[HALTED] = 0; 42 ctlregs[HALTED] = 0;
42 ctlregs[INT_ENABLE] = 0;
43 } else { 43 } else {
44 ctlregs[INT_ENABLE] = (ctlregs[INT_ENABLE] >> 1) * 3; 44 if (ctlregs[FLAGS] & FLAG_INT_ENABLE_DELAY)
45 ctlregs[FLAGS] |= FLAG_INT_ENABLE;
45 } 46 }
46 47
47 return interrupt; 48 return interrupt;
diff --git a/isa/checker.cpp b/isa/checker.cpp
index 6eaa15f..c6ab161 100644
--- a/isa/checker.cpp
+++ b/isa/checker.cpp
@@ -9,7 +9,7 @@ void checker::execute() {
9 if (ctlregs[HALTED]) 9 if (ctlregs[HALTED])
10 return; 10 return;
11 11
12 inst = decode(ctlregs[DATA_INSTRUCTION_FIELD_BUFFER], 12 inst = decode(ctlregs[FLAGS],
13 pc, 13 pc,
14 mem.fetch(pc), 14 mem.fetch(pc),
15 interrupt); 15 interrupt);
@@ -21,7 +21,7 @@ void checker::execute() {
21 addr = (addr + 1) & 07777; 21 addr = (addr + 1) & 07777;
22 mem.store(*inst.init_address, addr); 22 mem.store(*inst.init_address, addr);
23 } 23 }
24 auto df = ctlregs[DATA_INSTRUCTION_FIELD_BUFFER] >> 3; 24 auto df = (ctlregs[FLAGS] & FLAG_DF) >> FLAG_DF_SHIFT;
25 inst.final_address = (df << 12) | addr; 25 inst.final_address = (df << 12) | addr;
26 } else { 26 } else {
27 assert(!inst.need_autoinc_store); 27 assert(!inst.need_autoinc_store);
diff --git a/isa/ctlreg.def b/isa/ctlreg.def
index d490073..e379b21 100644
--- a/isa/ctlreg.def
+++ b/isa/ctlreg.def
@@ -1,7 +1,5 @@
1REG(DATA_INSTRUCTION_FIELD_BUFFER) // (df << 3) | if_buffer 1REG(FLAGS) // see FLAG_* consts in isa/isa.h
2REG(DATA_INSTRUCTION_FIELD_SAVED) // (df_saved << 3) | if_saved 2REG(FLAGS_SAVED) // see FLAG_* consts in isa/isa.h
3REG(HALTED) 3REG(HALTED)
4REG(INT_ENABLE) // (int_enable_delay << 1) | int_enable 4REG(TT_BITS) // see TT[IO]_* consts in isa/isa.h
5REG(INT_PENDING) // only meaningful if interrupts disabled 5REG(TT_FLAGS) // see TTF_* consts in isa/isa.h
6REG(TT_BITS) // see TT[IO]_* consts in isa/isa.h
7REG(TT_INT_ENABLE) // (status_enable << 1) | (int_enable)
diff --git a/isa/decode.cpp b/isa/decode.cpp
index 1496364..201a684 100644
--- a/isa/decode.cpp
+++ b/isa/decode.cpp
@@ -1,12 +1,18 @@
1#include <cassert> 1#include <cassert>
2#include <cstdint>
2#include <iostream> 3#include <iostream>
3 4
4#include "isa/isa.h" 5#include "isa/isa.h"
5 6
6instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bits, bool interrupt) 7instruction_context decode(std::uint_fast32_t flags, unsigned int pc, unsigned int bits, bool interrupt)
7{ 8{
8 auto df = dfifb >> 3; 9 //bool gt = (flags >> 10) & 1;
9 auto ifb = dfifb & 00007; 10 //bool ir = (flags >> 9) & 1;
11 //bool ii = (flags >> 8) & 1;
12 //bool ie = (flags >> 7) & 1;
13 //bool u = (flags >> 6) & 1;
14 bool ifb = (flags >> 3) & 7;
15 bool df = flags & 7;
10 16
11 instruction_context inst; 17 instruction_context inst;
12 inst.next_pc = (pc & ~07777) | ((pc + 1) & 07777); 18 inst.next_pc = (pc & ~07777) | ((pc + 1) & 07777);
@@ -16,6 +22,7 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit
16 assert(df == 0); 22 assert(df == 0);
17 assert(ifb == 0); 23 assert(ifb == 0);
18 inst.next_pc = pc; 24 inst.next_pc = pc;
25 pc = 0;
19 } 26 }
20 27
21 switch (bits >> 9) { 28 switch (bits >> 9) {
@@ -79,42 +86,46 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit
79 switch (bits & 07) { 86 switch (bits & 07) {
80 case 0: 87 case 0:
81 // SKON skip if interrupts enabled 88 // SKON skip if interrupts enabled
82 inst.read_ctlreg = INT_ENABLE; 89 inst.read_ctlreg = FLAGS;
83 inst.possibly_redirects = true; 90 inst.possibly_redirects = true;
84 inst.ef = [](auto &ctx) { 91 inst.ef = [](auto &ctx) {
85 if (ctx.ctlval.value() & 1) 92 if (ctx.ctlval.value() & FLAG_INT_ENABLE)
86 ctx.next_pc = (ctx.next_pc & 07777) | ((ctx.next_pc + 1) & 07777); 93 ctx.next_pc = (ctx.next_pc & 07777) | ((ctx.next_pc + 1) & 07777);
87 }; 94 };
88 break; 95 break;
89 case 1: 96 case 1:
90 // ION set int_enable_delay 97 // ION set int_enable_delay
91 inst.read_ctlreg = INT_ENABLE; 98 inst.read_ctlreg = FLAGS;
92 inst.write_ctlreg = INT_ENABLE; 99 inst.write_ctlreg = FLAGS;
93 inst.ef = [](auto &ctx) { 100 inst.ef = [](auto &ctx) {
94 ctx.ctlval.value() |= 2; 101 ctx.ctlval.value() |= FLAG_INT_ENABLE_DELAY;
95 }; 102 };
96 break; 103 break;
97 case 2: 104 case 2:
98 // IOFF clear int_enable and int_enable_delay 105 // IOFF clear int_enable and int_enable_delay
99 inst.write_ctlreg = INT_ENABLE; 106 inst.read_ctlreg = FLAGS;
107 inst.write_ctlreg = FLAGS;
100 inst.ef = [](auto &ctx) { 108 inst.ef = [](auto &ctx) {
101 ctx.ctlval = 0; 109 ctx.ctlval.value() &= ~FLAG_INT_ENABLE_DELAY & ~FLAG_INT_ENABLE;
102 }; 110 };
103 break; 111 break;
104 case 3: 112 case 3:
105 // SRQ skip if pending interrupt 113 // SRQ skip if pending interrupt
106 inst.read_ctlreg = INT_PENDING; 114 inst.read_ctlreg = FLAGS;
107 inst.possibly_redirects = true; 115 inst.possibly_redirects = true;
108 inst.ef = [](auto &ctx) { 116 inst.ef = [](auto &ctx) {
109 if (ctx.ctlval.value()) 117 if (ctx.ctlval.value() & FLAG_INT_REQUEST)
110 ctx.next_pc = (ctx.next_pc & 07777) | ((ctx.next_pc + 1) & 07777); 118 ctx.next_pc = (ctx.next_pc & 07777) | ((ctx.next_pc + 1) & 07777);
111 }; 119 };
112 break; 120 break;
113 case 4: 121 case 4:
114 // GTF get flags 122 // GTF get flags
123 inst.read_ctlreg = FLAGS;
124 inst.need_read_link = true;
115 inst.ef = [](auto &ctx) { 125 inst.ef = [](auto &ctx) {
116 std::cerr << "unimplemented GTF\n"; 126 auto flags = ctx.ctlval.value();
117 assert(false); 127 flags |= (unsigned int)ctx.link.value() << 11;
128 ctx.acc = flags;
118 }; 129 };
119 break; 130 break;
120 case 5: 131 case 5:
@@ -153,11 +164,11 @@ instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bit
153 }; 164 };
154 break; 165 break;
155 case 5: 166 case 5:
156 // KIE set TT_INT_ENABLE to the low bit of the accumulator 167 // KIE set TT_FLAGS from the accumulator
157 inst.need_read_acc = true; 168 inst.need_read_acc = true;
158 inst.write_ctlreg = TT_INT_ENABLE; 169 inst.write_ctlreg = TT_FLAGS;
159 inst.ef = [](auto &ctx) { 170 inst.ef = [](auto &ctx) {
160 ctx.ctlval = ctx.acc.value() & 3; 171 ctx.ctlval = ctx.acc.value();
161 }; 172 };
162 break; 173 break;
163 case 6: 174 case 6:
diff --git a/isa/isa.h b/isa/isa.h
index 69f8b2a..71f852e 100644
--- a/isa/isa.h
+++ b/isa/isa.h
@@ -26,15 +26,31 @@ const std::map<std::string, ctlreg> ctlreg_map = {
26#undef REG 26#undef REG
27}; 27};
28 28
29// FLAGS and FLAGS_SAVED
30static constexpr unsigned int FLAG_DF_SHIFT = 0;
31static constexpr std::uint_fast32_t FLAG_DF = 07 << FLAG_DF_SHIFT;
32static constexpr unsigned int FLAG_IF_SHIFT = 3;
33static constexpr std::uint_fast32_t FLAG_IF = 07 << FLAG_IF_SHIFT; // In FLAGS this is IFB, not IF
34static constexpr std::uint_fast32_t FLAG_USER_MODE = 1 << 6;
35static constexpr std::uint_fast32_t FLAG_INT_ENABLE = 1 << 7;
36static constexpr std::uint_fast32_t FLAG_INT_INHIBIT = 1 << 8;
37static constexpr std::uint_fast32_t FLAG_INT_REQUEST = 1 << 9;
38static constexpr std::uint_fast32_t FLAG_GREATER_THAN = 1 << 10;
39static constexpr std::uint_fast32_t FLAG_INT_ENABLE_DELAY = 1 << 12;
40
29// TT_BITS 41// TT_BITS
30static constexpr std::uint_fast32_t TTI_FLAG = 1 << 0; 42static constexpr std::uint_fast32_t TTI_FLAG = 1 << 0;
31static constexpr std::uint_fast32_t TTO_TX = 1 << 1; 43static constexpr std::uint_fast32_t TTO_TX = 1 << 1;
32static constexpr std::uint_fast32_t TTO_FLAG = 1 << 2; 44static constexpr std::uint_fast32_t TTO_FLAG = 1 << 2;
33static constexpr unsigned int TTI_DATA_SHIFT = 8; 45static constexpr unsigned int TTI_DATA_SHIFT = 8;
34static constexpr unsigned int TTO_DATA_SHIFT = 16;
35static constexpr std::uint_fast32_t TTI_DATA = 0xff << TTI_DATA_SHIFT; 46static constexpr std::uint_fast32_t TTI_DATA = 0xff << TTI_DATA_SHIFT;
47static constexpr unsigned int TTO_DATA_SHIFT = 16;
36static constexpr std::uint_fast32_t TTO_DATA = 0xff << TTO_DATA_SHIFT; 48static constexpr std::uint_fast32_t TTO_DATA = 0xff << TTO_DATA_SHIFT;
37 49
50// TT_FLAGS
51static constexpr std::uint_fast32_t TTF_INT_ENABLE = 1 << 0;
52static constexpr std::uint_fast32_t TTF_STATUS_ENABLE = 1 << 1;
53
38struct instruction_context { 54struct instruction_context {
39 // Known statically at decode time 55 // Known statically at decode time
40 bool need_indirect_load = false; // final_address = mem[init_address] 56 bool need_indirect_load = false; // final_address = mem[init_address]
@@ -65,4 +81,4 @@ struct instruction_context {
65 std::optional<unsigned int> mq; 81 std::optional<unsigned int> mq;
66}; 82};
67 83
68instruction_context decode(unsigned int df, unsigned int pc, unsigned int bits, bool interrupt); 84instruction_context decode(std::uint_fast32_t flags, unsigned int pc, unsigned int bits, bool interrupt);