forked from begoon/fcode
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MACROS.INC
222 lines (193 loc) · 6.58 KB
/
MACROS.INC
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
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
; ---------------------------------------------------------------------------
; Call User Subroutine
ofCUS MACRO Addr:REQ
dw Addr
ENDM
NEXT MACRO
jmp NEXT$
ENDM
CALLR MACRO
call CALLR$
ENDM
RETR MACRO Value
ErrIfNb <&Value> "Invalid argument"
dw RETR$
ENDM
OneArg MACRO ID:REQ, isOf
os&ID MACRO Value
ErrIfNB <&Value> "Non-empty argument in &ID"
dw os&ID&$
ENDM
IfIdn <&isOf>, <of>
of&ID MACRO Value:REQ
ofPush Value
os&ID
ENDM
EndIf
ENDM
TwoArg MACRO ID:REQ, isOf
os&ID MACRO Value
ErrIfNB <&Value> "Non-empty argument in &ID"
dw os&ID&$
ENDM
IfIdn <&isOf>, <of>
of&ID MACRO First:REQ, Second:REQ
IfDif <&First>, <*>
ofPush First
ifDif <&Second>, <*>
ofPush Second
Else
osSwap
Endif
Else
IfDif <&Second>, <*>
ofPush Second
EndIf
EndIf
os&ID
ENDM
EndIf
ENDM
ofPush MACRO AWord:REQ
dw osPush$
dw AWord
ENDM
OneArg DP
OneArg RP
OneArg ToAX, of
OneArg ToDX, of
OneArg Pick, of
OneArg Dup
OneArg 2Dup
OneArg Swap
OneArg Over
OneArg Drop
OneArg Adc, of
OneArg Add, of
OneArg Nor, of
OneArg Xor, of
OneArg And, of
OneArg Or, of
OneArg Not
OneArg Neg
OneArg Dos
OneArg Put, of
OneArg Get
OneArg Sub, of
OneArg Inc
OneArg Is0
OneArg Trap
OneArg Peek, of
OneArg Peekb, of
OneArg I
OneArg Char, of
OneArg Str, of
OneArg Int, of
OneArg Shl, of ; Value -> Value*2 isCarry
OneArg Rcl, of ; Value isCarry -> Value*2 isCarry
OneArg Rot
OneArg Exch
OneArg Cmp
TwoArg Do, of
TwoArg Poke, of
TwoArg Pokeb, of
; ---------------------------------------------------------------------------
; osIP$ ( -> IP )
; Push on the data-stack the Instruction Pointer
osIP macro
ofPeek IP$
endm
osJmp MACRO Value ; Addr ->
ErrIfNb <&Value> "Invalid argument"
ofPush 0001h ; Addr Cond=1
osSwap ; Cond=1 Addr
osJnz
ENDM
ofJmp MACRO Addr:REQ
ofPush Addr
osJmp
ENDM
osJnz MACRO Value ; Cond Addr ->
ErrIfNb <&Value> "Invalid argument"
dw osJnz$
ENDM
ofJnz MACRO Addr:REQ ; Cond ->
ofPush Addr
osJnz
ENDM
osJz MACRO Value ; Cond Addr ->
ErrIfNb <&Value> "Invalid argument"
osSwap ; Addr Cond
osIs0 ; Addr Norm
osNot ; Addr !Norm
osSwap ; !Norm Addr
osJnz ; ->
ENDM
ofJz MACRO Addr:REQ ; Cond ->
ofPush Addr ; Cond Addr
osJz ; ->
ENDM
osStep MACRO Value ;
ErrIfNb <&Value> "Invalid argument"
dw osStep$
osSwap
osJnz
osGet
osDrop
osGet
osDrop
ENDM
ofStep MACRO Addr:REQ, Delta:REQ
ofPush Delta
dw osStep$
ofJnz Addr
osGet
osDrop
osGet
osDrop
ENDM
osLoop MACRO Value ;
ErrIfNb <&Value> "Invalid argument"
ofPush 1
osStep
ENDM
ofLoop MACRO Addr:REQ
ofStep Addr, 1
ENDM
; ofJe ( a b -> ) Jump if equal
ofJe MACRO Addr:REQ ; a b ->
osSub ; is0?
ofJz Addr ; ->
ENDM
ofJne MACRO Addr:REQ ; a b ->
osSub ; is0?
ofJnz Addr ; ->
ENDM
ofCond MACRO Addr:REQ ; isZero isCarry ->
osNot ; isZero !isCarry
osAnd ; is0?
ofJnz Addr ; ->
ENDM
ofJge MACRO Addr:REQ ; a b ->
osCmp ; isCarry isZero
osSwap ; isZero isCarry
ofCond Addr ; ->
ENDM
ofJlt MACRO Addr:REQ ; a b ->
osCmp ; isCarry isZero
ofCond Addr ; ->
ENDM
ofJgt MACRO Addr:REQ ; a b ->
osInc ; a b+1 ->
ofJge Addr ; ->
ENDM
ofJle MACRO Addr:REQ ; a b ->
osInc ; a b+1
ofJlt Addr ; ->
ENDM
os MACRO Cmd1, Cmd2, Cmd3, Cmd4
Cmd1
Cmd2
Cmd3
Cmd4
ENDM