-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathMacroReference
More file actions
146 lines (116 loc) · 5.69 KB
/
MacroReference
File metadata and controls
146 lines (116 loc) · 5.69 KB
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
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
Accumulator Macros
NOT - bitwise complement
NEG - 2's complement negation
LOGNOT - boolean negation (nonzero becomes zero, zero becomes nonzero)
GETCARR - isolates the carry bit from the status register
GETCMP - isolates the 2'c complement comparison bit from status register
CLRCARR - clears the carry bit (sets it to 0)
SETCARR - sets the carry bit (sets to 1)
INC - adds 1
DEC - subtracts 1 (by adding F)
UCLC - unsafe clear carry (sets carry to 0, ACC value not preserved)
USTC - unsafe set carry (sets carry to 1, ACC value not preserved)
LSHIFT - left shift by 1, filling LSB with 0.
LROT - left rotate by 1, filling LSB with old MSB
SIGNEX - if MSB is 1, puts F into ACC. Otherwise, puts 0 into ACC.
BEEP - Tells the audio peripheral, if present (and enabled by 0xD)
- to make a sound corresponding to the accumulator contents.
- Beep with acc value 0 tells it to be quiet.
Normal Unary Macros (OPCODE mem1 INTO mem2)
MOV - copies memory, without altering it
NOT - bitwise complement
NEG - 2's complement negation
INC - Increment (add 1).
LSHIFT - left shift by 1
LROT - left rotate by 1
Normal Binary Macros (OPCODE mem1 mem2 INTO mem3)
ADD - basic addition with carry
SUB - subtraction, with carry (mem3 = mem1 - mem2)
NAND - bitwise NAND
AND - bitwise AND
OR - bitwise OR
NOR - bitwise NOR
XOR - bitwise XOR
XNOR - bitwise XNOR
Jump Macros (OPCODE mem1 mem2 TO code1)
JMPEQ - jump if memory locations hold equal contents
JMPNE - jump if memory locations hold different contents
JMPG - jump if op1 holds strictly greater value than op2
JMPL - jump if op1 holds strictly lesser value than op2
JMPGE - jump if op1 holds greater or equal value than op2
JMPLE - jump if op1 hold lesser or equal value than op2
Syntactic Requirements
To simplify the core of the macro expander, certain constraints
have been placed on syntax. In general, only one statement can
be on each line. User-defined jump labels shown in code
must be on a line with nothing else, and must end with a colon
("myLabel:", for instance). Labels can, however, share a line
with a data field declaration. Line comments are marked with a
leading hash ('#') or semicolon (';'), and cannot be on the
same line as anything else.
In unary and binary macros, the "INTO" and final label can be
omitted. If this is done, it will assume you meant "INTO mem1",
and put the result of the operation into the first memory location
given. For example, "NEG8 number" is equivalent to "NEG8 number
INTO number".
Blank lines and line comments are both unaltered by this program,
meaning that the output code will be slightly easier to read and
debug. This was done not only for your benefit, but also for mine.
Allowing comments to pass through means that I will have a much
easier time testing and debugging this program!
Macro Variations
All normal unary and binary macros have size variants, for
8, 16, 32, and 64 bit operand sizes. They are used by appending
the size to the opcode. For example, ADD32 or LSHIFT8 are also
valid opcodes. Assumes less significant bits have higher memory
addresses.
Labels can be offset by a hexadecimal value (no need for the
0x prefix, though it doesn't break anything), which signifies
a memory position that many nibbles "further" (greater address
value) in memory. For instance, if place[0] has previously been
used to MOV16 the value 0xC0DE, then place [2] now holds the
value "D".
Non-hexadecimal offsets are valid, using appropriate prefixes:
- 0d for decimal
- 0b for binary
- 0o for octal
The &(label[A])[B] syntax is supported by this program, but with
the requirement that both offsets be present at all times, even if
their values are 0. If the second offset has a value greater than 3,
this will cause a syntax error, as this indicates the fifth (or greater)
bit of an address, which is meaningless.
Special Macros
These were designed for use by other macros, but are available
to use in your programs if you want.
ADDC - binary macro. Propagates addition. Mostly just there
to make the macro definitions cleaner.
SUBC - binary macro. Propagates subtractions. As above, just
there to make definitions prettier.
CMPC - binary macro. Propagates dummy subtraction. Like SUBC,
but without storing the result. Used for comparisons.
PROPCARR- unary macro. Adds the carry bit from STAT to the first
operand, and stores the result in the destination.
PROPNEG - unary macro. NOTs the first operand, adds carry from
STAT, and stores in destination.
MOVADDR - puts address of mem1 into mem2 (as C '&' operator). No
variants available, but very useful for subroutine calls.
File Inclusion
We can now handle file inclusion. Files are opened and expanded
in a breadth-first recursive manner, automatically ignoring any
repeated files. Files can be included by using an INCL opcode
followed by a valid filepath to the new file. Files will be
concatenated in a way that keeps each code section intact, as
well as keeping each data section intact. It will, however, cause
other code and/or data to be inserted between the last instruction
in the file and the first data declaration in the file. Comments
are generated in a way that allows easy traceability of which file
a particular line of code originated from.
The Carry Bit
Due to the latest architectural changes (start of Feb 2016), we now
have an extra bit of state - the carry bit. Since it alters the behavior
of ADD instructions, we need to be aware of it. The macros here have
been coded to work the same regardless of carry bit state, but to
leave the carry bit in unknown state. You should probably follow this
philosophy in your code too. Never assume that the carry bit is known,
unless you're absolutely sure it is, and use the CLRCARR, SETCARR,
UCLC, and USTC macros to put it in known state.