forked from utz82/HoustonTracker2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
util.asm
339 lines (277 loc) · 8.07 KB
/
util.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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
;*******************************************************************************
;MISC UTILITIES
;*******************************************************************************
calcPtnOffset ;calculate offsets in note data
dec de
ld a,(de)
add a,a
ld l,a
ld h,0
add hl,hl
add hl,hl
add hl,hl
add hl,bc
ret
;************************************************************************************
confirmAction ;wait for confirmation/abortion of user action
;IN: nothing | OUT: carry reset if confirmed, else abort
setXYat #29, #b8 ;print CONF message
printTwoChars CHAR_C, CHAR_O ;CO
setXYat #2a, #b8
printTwoChars CHAR_N, CHAR_F ;NF
_rdkeys
ld a,KBD_GROUP_ZERO ;read key 0
out (kbd),a
key_delay
in a,(kbd)
rra
jp nc,_cancel ;if pressed, cancel user action
ld a,KBD_GROUP_DOT ;read key .
out (kbd),a
key_delay
in a,(kbd)
rra
jp nc,_confirm ;if pressed, confirm user action
jr _rdkeys ;if no key pressed, try again
_cancel
scf ;set carry
_confirm ;if user action confirmed, carry is already reset
_exitc
clrMsgArea ;clear message area
push af ;preserve flags
setXYat #29, #b2 ;delete CONF message and rest of msg area
call clearPrintBuf
call printBuf
call printBuf
setXYat #2a, #b8
call printBuf
setXYat #2b, #b2
call printBuf
pop af
ret
;************************************************************************************
calculateCopyParams ;calculate block start, length and target line #
;IN: nothing | OUT: block start in DE, block length in BC and HL, current line # in A
exx
ld a,d ;D' holds old block start
exx
;ld a,(CPS) ;calculate block start in memory
ld l,a
ld h,0
add hl,hl
add hl,hl
ex de,hl ;block start - base offset now in DE
;ld a,(CPE) ;calculate block length in memory
exx
ld a,e ;E' holds old block end
exx
ld l,a
ld h,0
add hl,hl
add hl,hl
;xor a ;TODO: optimzed 15-08-19 - carry should never be set at this point, so we don't need to reset it
sbc hl,de
inc hl
inc hl
inc hl
inc hl ;block length now in HL
call getCurrLineNo ;current line # now in A
ld b,h ;block length now in BC
ld c,l
ret
;************************************************************************************
getCurrLineNo ;calculate the current line number
;IN: nothing | OUT: current line number in A | DESTROYED: C
ld a,(CsrPos)
and %11111000
rra
rra
rra
ld c,a
ld a,(FirstLineMS)
add a,c
ret
;************************************************************************************
findCurrLine ;find the current line in the sequence
;IN: nothing | OUT: pointer to start of line in HL
xor a
ld h,a
ld d,a
ld a,(CsrPos)
ld (OldCsrPos),a
findCurrLineNoSeq ;entry point for finding the current row when not on seq.scr
and %11111000 ;clear lower 3 bits of cursor pos value to get to the start of the line and clear carry
rra ;divide by two
ld e,a ;store in DE
ld a,(FirstLineMS) ;read current first line
ld l,a ;store in HL
add hl,hl ;HL*4 to get offset of first line
add hl,hl
add hl,de ;add DE to get offset of current line
ld de,ptns ;add base pointer
add hl,de ;sequence pointer now in HL
ret
;************************************************************************************
findNextUnused ;find next unused ptn in sequence
;IN: first # to check in A | OUT: next unused in A, Z if no unsed patterns found
ld hl,ptns
ld bc,256*4
_chklp
cpi ;iterate through the pattern sequence
jr z,_used ;exit loop if match found (pattern used)
cpi
jr z,_used
cpi
jr z,_used
cpi ;every 4th pattern is an fx pattern, so it's ignored
ret po ;return if pattern was unused
jr _chklp
_used
inc a ;if pattern was used
cp #80 ;check if all patterns have been checked
ret z ;and return if that's the case
jr findNextUnused ;else, check next pattern
isPtnFree ;check if a pattern is free
;IN: ptn # in A | OUT: Z if free, NZ if not free
add a,a ;calculate offset
; ld l,a ;pattern # *2 to HL
; ld h,0
; add hl,hl
; add hl,hl
; add hl,hl
; ld de,ptn00 ;add base pointer
; add hl,de
ld h,HIGH(ptntab) ;look up pattern address
ld l,a
ld a,(hl)
inc hl
ld h,(hl)
ld l,a
ld b,#10
xor a
chklp
cp (hl) ;check value
jr nz,_notfree ;exit loop if != 0
inc hl ;else, increment pointer and check next val
djnz chklp
_notfree
ret ;return with Z set if all values have been checked
findNextUnusedFX ;find the next free fx pattern
;IN: first # to check in A | OUT: next unused in A, Z if no unsed patterns found
ld hl,ptns
ld bc,256*4
_chklp
cpi
cpi
cpi
cpi
jr z,_used
ret po
jr _chklp
_used
inc a ;if pattern was used
cp #40 ;check if all patterns have been checked
ret z ;and return if that's the case
jr findNextUnusedFX ;else, check next pattern
isFxPtnFree ;check if a pattern is free
;IN: ptn # in A | OUT: Z if free, NZ if not free
ld de,fxptntab ;10
add a,a ;4
ld h,0 ;7
ld l,a ;4
add hl,de ;11
ld a,(hl) ;7
inc hl ;6
ld h,(hl) ;7
ld l,a ;4
;60t
ld b,#20
jr chklp-1
;*******************************************************************************
divNoteVal ;split note value into octave and val w/in the octave
;IN: note val in A | OUT: octave in B, note val in C
ld b,#ff
dec a ;0=silence, so lowest actual note val is 1 -> decrement by 1
_divlp ;effectively dividing A by 12
inc b ;increment octave
ld c,a ;preserve remainder
sub 12 ;subtract 12
jr nc,_divlp ;loop until result was <0
ret
;************************************************************************************
;************************************************************************************
findCurrPtn ;locate the currently selected pattern in memory
;IN: nothing | OUT: pattern pointer in DE
ld a,(CPtn) ;read current ptn# TODO: optimize by moving this to after the findCurrFxPtn label
findPtn ;find ptn in memory
ld hl,ptntab ;10 ;point to pattern position LUT
findCurrFxPtn ;entry point for finding fx pattern. A and HL need to be preset
add a,a ;4 ;A=A*2
add a,l ;4
ld l,a ;4
jr nc,_skip1 ;12/7
inc h ;4
_skip1 ;ptn pointer now at (HL)
ld e,(hl)
inc hl
ld d,(hl) ;ptn pointer now in DE
ret
;************************************************************************************
getSeqOffset ;get offset in ptn sequence based on current cursor pos on seq.screen
;IN: nothing | OUT: sequence pointer in HL, [current] ptn# in A,(CPtn) | destroyed: DE
xor a ;clear carry
ld h,a ;ld h,0
ld d,a
ld a,(CsrPos) ;read old cursor position (from seq.scr)
rra ;divide by 2
ld e,a
ld a,(FirstLineMS) ;check first line on seq scr
ld l,a
add hl,hl ;offset*4
add hl,hl
add hl,de ;+ position offset = total offset in ptn sequence
ld de,ptns ;add ptn sequence base
add hl,de ;seq.pointer now in HL
ld a,(hl) ;load ptn# into A
ld (CPtn),a ;store it in (CPtn)
ret
;************************************************************************************
;************************************************************************************
hex2char ;convert hex value to character string (using custom font)
;input: A=hex byte | output: string in (charstring), A destroyed
cp #ff ;check if we have an #ff byte
jr z,hex2charFF
hex2charNoFF
push af ;preserve input byte
and %00001111 ;extract lower nibble
ld (CharString),a ;save it
pop af ;retrieve input byte
rra ;shift right x4 and clear bit 4-7 to extract upper nibble
rra
rra
rra
and %00001111
ld (CharString+1),a
ret
hex2charFF
ld a,#16 ;replace #ff with --
ld (CharString),a
ld (CharString+1),a
ret
hex2charU ;convert upper nibble of hex value to right-aligned char and return it in A
cp #ff
jr z,hex2FF
rra ;shift right x4 and clear bit 4-7 to extract upper nibble
rra
rra
rra
and %00001111
ret
hex2charL ;convert lower nibble of hex value to left-aligned char and return it in A
cp #ff
jr z,hex2FF
and %00001111
ret
hex2FF ;replace hex digit with - (dash)
ld a,#16
ret