-
Notifications
You must be signed in to change notification settings - Fork 0
/
macros.asm
220 lines (187 loc) · 5.15 KB
/
macros.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
;-------------------------------------------------------------------------------
; Banks
;-------------------------------------------------------------------------------
; PRG Bankswitching
; A function to be used with BankSwitch subroutine
CBJ_Helper .function bank, label
.cerror label&$3E=0, "Illegal label (Label & $3E == 0)"
.cerror ((label&$FF00)>>8)!=$80, "Illegal label (higher byte is not $80)"
.endf ((((label&$FF)-4)/1.5)<<2)+bank
CrossBankJump .macro bank, label, jump=false
lda #CBJ_Helper(\bank,\label)
.if !\jump
.if *<$C000
jsr Goto_CrossBankJump
.else
jsr Sub_CrossBankJump
.endif
.else
.if *<$C000
jmp Goto_CrossBankJump
.else
jmp Sub_CrossBankJump
.endif
.endif
.endm
BankStartAddress .var 0
BankEndAddress .var 0
LastBank .var 0
BankHeader .segment
BankStartAddress .var * & $F000
.if LastBank!=(PRGBankCount-1) ; last PRG bank
.byte LastBank
.endif
.byte $62, $6b, $30+LastBank
.endsegment
BankEnd .segment
.if LastBank != (PRGBankCount-1)
.text "GODZILLA "
.byte $00, $00, $00, $00 ; $bff0: 00 00 00 00 Data
.byte $33, $04, $01, $10 ; $bff4: 33 04 01 10 Data
.byte $00, $00
.addr Main_ffd8
.addr Main_ffd8
.addr Main_ffd8
.endif
BankEndAddress .var (BankStartAddress + PRGBankSize) & $FFFF
.if (BankStartAddress < BankEndAddress && * > BankEndAddress) || (BankStartAddress > BankEndAddress && * > BankEndAddress && * < BankStartAddress)
.error "Bank ", repr(LastBank), " is too big (", *, ")"
.endif
.if Debug && ( (BankStartAddress < BankEndAddress && * < BankEndAddress) || (BankStartAddress > BankEndAddress && * > BankStartAddress) )
.warn "Bank ", repr(LastBank), " is small (", *, ")"
.endif
LastBank += 1
.align PRGBankSize
.endsegment
; CHR Bankswitching
; (Note that Sub_CHRBankSwitch1 and Sub_CHRBankSwitch2 (mainbank.asm)
; limit the bank ID to available number of banks)
CHR_BankSwitch1 .macro
; A = requested bank ID
sta $bfff
lsr
sta $bFFF
lsr
sta $bfff
lsr
sta $bfff
lsr
sta $bfff
.endm
CHR_BankSwitch2 .macro
; A = requested bank ID
sta $dfff
lsr
sta $dfff
lsr
sta $dfff
lsr
sta $dfff
lsr
sta $dfff
.endm
;-------------------------------------------------------------------------------
; Text
;-------------------------------------------------------------------------------
GameText .macro x, y, txt
_pos = $2020 + \y*$20 + \x
; Position in Big Endian
.byte >_pos, <_pos
.byte len(_text)
.encode Enc_Default
_text: .text \txt
.endencode
.endm
GameTextEnd .macro
.byte 0
.endm
;-------------------------------------------------------------------------------
; Sound
;-------------------------------------------------------------------------------
MusicFadeOut .macro
CrossBankJump Sound_Bank, Sound_Goto_MusicFadeOut
.endm
;-------------------------------------------------------------------------------
; Tables
;-------------------------------------------------------------------------------
; I use segment because I need to create a global variable
; or to use a global variable
TableOffset .var 0
; Start a new table
TableStart .segment offset=0
CurrentTable .var []
TableOffset .var \offset
.endsegment
; Insert a label into the table and return its id
TableInsert .segment
_CurrentID .var len(CurrentTable)+TableOffset
CurrentTable ..= [\@]
.endsegment _CurrentID
;-------------------------------------------------------------------------------
; Other
;-------------------------------------------------------------------------------
; Check if the size of data matches the planet count
PlanetCheck .macro start, size
.cwarn (*-\start)!=(PlanetCount*\size), "Size of the planet data does not match the needed size: expected " .. repr(PlanetCount) .. " elements, got " .. repr((*-\start)/\size)
.endm
; Load an address into $a5, $a6
LoadAddress .macro address, swap=false
.if \swap
lda #>\address
sta LoadAddress_High
lda #<\address
sta LoadAddress_Low
.else
lda #<\address
sta LoadAddress_Low
lda #>\address
sta LoadAddress_High
.endif
.endm
; Load address from table '(higher, lower)' by index 'register' (either X or Y)
LoadAddressFromTable .macro lower, higher, register
lda \lower,\register
sta LoadAddress_Low
lda \higher,\register
sta LoadAddress_High
.endm
; A lot of types because I want the disassembly to be
; both readable and bit-perfect
LoadAddressOffset .macro offlow, offhigh, type=0
.switch \type
.case 0
lda #\offlow
adc LoadAddress_Low
sta LoadAddress_Low
lda #\offhigh
adc LoadAddress_High
sta LoadAddress_High
.case 1
lda LoadAddress_Low
adc #\offlow
sta LoadAddress_Low
lda LoadAddress_High
adc #\offhigh
sta LoadAddress_High
.case 2
lda #\offlow
adc $a3
sta LoadAddress_Low
lda #\offhigh
adc $a4
sta LoadAddress_High
.default
.error "Unknown LoadAddressOffset type: " .. repr(type)
.endswitch
.endm
LoadAddressTransfer .macro address
lda \address
sta LoadAddress_Low
lda \address+1
sta LoadAddress_High
.endm
; Check if a values is a power of two
CheckPowerOfTwo .macro value
; len(bits) is number of bits
.cerror \value!=(1<<len(bits(\value-1))), "The value above must be a power of two"
.endm