-
Notifications
You must be signed in to change notification settings - Fork 5
/
MacroSetup.asm
233 lines (209 loc) · 5.29 KB
/
MacroSetup.asm
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
223
224
225
226
227
228
229
230
231
232
233
padding off ; we don't want AS padding out dc.b instructions
listing purecode ; Want listing file, but only the final code in expanded macros
supmode on ; we don't need warnings about privileged instructions
page 0 ; Don't want form feeds
notZ80 function cpu,(cpu<>128)&&(cpu<>32988)
; make org safer (impossible to overwrite previously assembled bytes)
org macro address
if notZ80(MOMCPU)
.diff := address - *
if .diff < 0
error "too much stuff before org $\{address} ($\{(-.diff)} bytes)"
else
while .diff > 1024
; AS can only generate 1 kb of code on a single line
dc.b [1024]$FF
.diff := .diff - 1024
endm
dc.b [.diff]$FF
endif
else
if address < $
error "too much stuff before org 0\{address}h (0\{($-address)}h bytes)"
else
while address > $
db 0
endm
endif
endif
endm
; define an alternate org that fills the extra space with 0s instead of FFs
org0 macro address
.diff := address - *
if .diff < 0
error "too much stuff before org0 $\{address} ($\{(-.diff)} bytes)"
else
while .diff > 1024
; AS can only generate 1 kb of code on a single line
dc.b [1024]0
.diff := .diff - 1024
endm
dc.b [.diff]0
endif
endm
; define the cnop pseudo-instruction
cnop macro offset,alignment
if notZ80(MOMCPU)
org (*-1+(alignment)-((*-1+(-(offset)))#(alignment)))
else
org ($-1+(alignment)-(($-1+(-(offset)))#(alignment)))
endif
endm
; define an alternate cnop that fills the extra space with 0s instead of FFs
cnop0 macro offset,alignment
org0 (*-1+(alignment)-((*-1+(-(offset)))#(alignment)))
endm
; redefine align in terms of cnop, because the built-in align can be stupid sometimes
align macro alignment
cnop 0,alignment
endm
; define an alternate align that fills the extra space with 0s instead of FFs
align0 macro alignment
cnop0 0,alignment
endm
; define the even pseudo-instruction
even macro
align0 2
endm
evenRAM macro
if (*)&1
ds.b 1
endif
endm
; define a trace macro
; lets you easily check what address a location in this disassembly assembles to
trace macro optionalMessageWithoutQuotes
if MOMPASS=1
if ("ALLARGS"<>"")
message "#\{tracenum/1.0}: line=\{MOMLINE/1.0} PC=$\{(*)&$FFFFFFFF} msg=ALLARGS"
else
message "#\{tracenum/1.0}: line=\{MOMLINE/1.0} PC=$\{(*)&$FFFFFFFF}"
endif
tracenum := (tracenum+1)
endif
endm
tracenum := 0
bit function nBits,1<<(nBits-1)
setBit function nBits,1<<(nBits)
signmask function val,nBits,-((-(val&bit(nBits)))&bit(nBits))
signextend function val,nBits,(val+signmask(val,nBits))!signmask(val,nBits)
signextendB function val,signextend(val,8)
roundFloatToInteger function float,INT(float+0.5)
min function a,b,b!((a!b)&(-(a<b)))
max function a,b,a!((a!b)&(-(a<b)))
if ZeroOffsetOptimization=0
; disable a space optimization in AS so we can build a bit-perfect ROM
; (the hard way, but it requires no modification of AS itself)
chkop function op,ref,(substr(lowstring(op),0,strlen(ref))<>ref)
; 1-arg instruction that's self-patching to remove 0-offset optimization
insn1op macro oper,x
if (chkop("x","0(") && chkop("x","objoff_00(") && chkop("x","obid(") && chkop("x","id(") && chkop("x","address(") && chkop("x","smps_queue.v_playsnd1("))
!oper x
else
!oper 1+x
!org *-1
!dc.b 0
endif
endm
; 2-arg instruction that's self-patching to remove 0-offset optimization
insn2op macro oper,x,y
if (chkop("x","0(") && chkop("x","objoff_00(") && chkop("x","obid(") && chkop("x","id(") && chkop("x","address(") && chkop("x","smps_queue.v_playsnd1("))
if (chkop("y","0(") && chkop("y","objoff_00(") && chkop("y","obid(") && chkop("y","id(") && chkop("y","address(") && chkop("y","smps_queue.v_playsnd1("))
!oper x,y
else
!oper x,1+y
!org *-1
!dc.b 0
endif
else
if chkop("y","d")
if (chkop("y","0(") && chkop("y","objoff_00(") && chkop("y","obid(") && chkop("y","id(") && chkop("y","address(") && chkop("y","smps_queue.v_playsnd1("))
.start:
!oper 1+x,y
.end:
!org .start+3
!dc.b 0
!org .end
else
!oper 1+x,1+y
!org *-3
!dc.b 0
!org *+1
!dc.b 0
endif
else
!oper 1+x,y
!org *-1
!dc.b 0
endif
endif
endm
; instructions that were used with 0(a#) syntax
; defined to assemble as they originally did
_move macro
insn2op move.ATTRIBUTE, ALLARGS
endm
_add macro
insn2op add.ATTRIBUTE, ALLARGS
endm
_addq macro
insn2op addq.ATTRIBUTE, ALLARGS
endm
_cmp macro
insn2op cmp.ATTRIBUTE, ALLARGS
endm
_cmpi macro
insn2op cmpi.ATTRIBUTE, ALLARGS
endm
_clr macro
insn1op clr.ATTRIBUTE, ALLARGS
endm
_tst macro
insn1op tst.ATTRIBUTE, ALLARGS
endm
else
; regular meaning to the assembler; better but unlike original
_move macro
!move.ATTRIBUTE ALLARGS
endm
_add macro
!add.ATTRIBUTE ALLARGS
endm
_addq macro
!addq.ATTRIBUTE ALLARGS
endm
_cmp macro
!cmp.ATTRIBUTE ALLARGS
endm
_cmpi macro
!cmpi.ATTRIBUTE ALLARGS
endm
_clr macro
!clr.ATTRIBUTE ALLARGS
endm
_tst macro
!tst.ATTRIBUTE ALLARGS
endm
endif
; nop rept
nops macro fill
if ("fill"="0") || ("fill"="")
nop
else
rept fill
nop
endr
endif
endm
; alias ds as rs from asm68k compiler
rs macro
ds.ATTRIBUTE ALLARGS
endm
; alias binclude as incbin from asm68k compiler
incbin macro
binclude ALLARGS
endm
; dcb from asm68k compiler
dcb macro fill, byte
dc.ATTRIBUTE [fill]byte
endm