blob: 8a85d413a0cd0e3bf84b1eece7fabfa54a0b3948 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
|
#include <cassert>
#include "isa/isa.h"
instruction_context decode(unsigned int dfifb, unsigned int pc, unsigned int bits)
{
instruction_context inst;
auto df = dfifb >> 3;
auto ifb = dfifb & 00007;
inst.next_pc = (pc & ~07777) | ((pc + 1) & 07777);
switch (bits >> 9) {
case 0: // AND
inst.need_exec_load = true;
inst.need_read_acc = true;
inst.need_write_acc = true;
inst.ef = [](auto &ctx) {
ctx.acc = ctx.acc.value() & ctx.data.value();
};
break;
case 1: // TAD
inst.need_exec_load = true;
inst.need_read_acc = true;
inst.need_read_link = true;
inst.need_write_acc = true;
inst.need_write_link = true;
inst.ef = [](auto &ctx) {
unsigned int sum = (ctx.link.value() << 12) + ctx.acc.value() + ctx.data.value();
ctx.link = (sum >> 12) & 1;
ctx.acc = sum & 07777;
};
break;
case 2: // ISZ
inst.need_exec_load = true;
inst.need_exec_store = true;
inst.possibly_redirects = true;
inst.ef = [](auto &ctx) {
ctx.data = (ctx.data.value() + 1) & 07777;
if (*ctx.data)
ctx.next_pc = (ctx.next_pc & ~07777) | ((ctx.next_pc + 1) & 07777);
};
break;
case 3: // DCA
inst.need_read_acc = true;
inst.need_write_acc = true;
inst.need_exec_store = true;
inst.ef = [](auto &ctx) {
ctx.data = ctx.acc.value();
ctx.acc = 0;
};
break;
case 4: // JMS
inst.need_exec_store = true;
inst.possibly_redirects = true;
inst.ef = [ifb](auto &ctx) {
ctx.data = ctx.next_pc;
ctx.next_pc = (ifb << 12) | ((ctx.final_address.value() + 1) & 07777);
};
break;
case 5: // JMP
inst.possibly_redirects = true;
inst.ef = [ifb](auto &ctx) {
ctx.next_pc = (ifb << 12) | (ctx.final_address.value() & 07777);
};
break;
case 6: // IOT
inst.ef = [bits](auto &ctx) {
assert(false);
};
break;
case 7: // OPR
inst.ef = [bits](auto &ctx) {
assert(false);
};
break;
}
// Instructions with memory operands may be direct or indirect
if (inst.need_exec_load || inst.need_exec_store || inst.possibly_redirects) {
auto addr = (df << 12) | ((bits & 00200) ? (next_pc & 07600) : 0) | (bits & 00177);
if (bits & 00400) {
inst.need_indirect_load = true;
inst.init_address = addr;
} else {
inst.final_address = addr;
}
}
// Non-jump indirect memory operands may be autoincrementing depending on operand bits
if (!inst.possibly_redirects && inst.need_indirect_load && ((bits & 00170) == 00010))
inst.need_autoinc_store = true;
return inst;
}
|