@@ -36,7 +36,7 @@ STACK_SIZE EQU 20 |
| 36 |
;; Stack starts at $FFFE |
36 |
;; Stack starts at $FFFE |
| 37 |
|
37 |
|
| 38 |
PATTERN_LENGTH EQU 64 |
38 |
PATTERN_LENGTH EQU 64 |
| 39 |
TICKS EQU 7 |
39 |
TICKS EQU 4 |
| 40 |
|
40 |
|
| 41 |
; $0000 - $003F: RST handlers. |
41 |
; $0000 - $003F: RST handlers. |
| 42 |
|
42 |
|
@@ -122,8 +122,8 @@ DB "NF" |
| 122 |
SECTION "Song Data", ROM0 |
122 |
SECTION "Song Data", ROM0 |
| 123 |
;; order_cnt is the number of orders times 2 |
123 |
;; order_cnt is the number of orders times 2 |
| 124 |
order_cnt: db 2 |
124 |
order_cnt: db 2 |
| 125 |
order1: dw unreal ;; unreal ;; unreal;, lunawaves, lunawaves, unreal |
125 |
order1: dw updown ;; unreal ;; unreal;, lunawaves, lunawaves, unreal |
| 126 |
order2: dw unreal_arps ;; empty, unreal, unreal, lunawaves |
126 |
order2: dw empty ;; empty, unreal, unreal, lunawaves |
| 127 |
order3: dw empty |
127 |
order3: dw empty |
| 128 |
order4: dw empty |
128 |
order4: dw empty |
| 129 |
|
129 |
|
@@ -141,46 +141,46 @@ empty: |
| 141 |
rept 64 |
141 |
rept 64 |
| 142 |
db 90, 0, 0 |
142 |
db 90, 0, 0 |
| 143 |
endr |
143 |
endr |
| 144 |
; drums: |
144 |
drums: |
| 145 |
; rept 16 |
145 |
rept 16 |
| 146 |
; db 44, 0, 0 |
146 |
db 44, 0, 0 |
| 147 |
; db 90, 0, 0 |
147 |
db 90, 0, 0 |
| 148 |
; db 90, 0, 0 |
148 |
db 90, 0, 0 |
| 149 |
; db 90, 0, 0 |
149 |
db 90, 0, 0 |
| 150 |
; endr |
150 |
endr |
| 151 |
; slideup: |
151 |
slideup: |
| 152 |
; dn C4, 00, $000 |
152 |
dn C4, 00, $000 |
| 153 |
; rept 63 |
153 |
rept 63 |
| 154 |
; dn 90, 00, $101 |
154 |
dn 90, 00, $101 |
| 155 |
; endr |
155 |
endr |
| 156 |
; arps: |
156 |
arps: |
| 157 |
; rept 64 |
157 |
rept 64 |
| 158 |
; dn C5, 00, $047 |
158 |
dn C5, 00, $047 |
| 159 |
; endr |
159 |
endr |
| 160 |
vib: |
160 |
vib: |
| 161 |
dn C5, 00, $000 |
161 |
dn C5, 00, $000 |
| 162 |
rept 63 |
162 |
rept 63 |
| 163 |
dn 90, 00, $443 |
163 |
dn 90, 00, $443 |
| 164 |
endr |
164 |
endr |
| 165 |
; updown: |
165 |
updown: |
| 166 |
; dn C4, 00, $105 |
166 |
dn C4, 00, $105 |
| 167 |
; rept 31 |
167 |
rept 31 |
| 168 |
; dn 90, 00, $105 |
168 |
dn 90, 00, $105 |
| 169 |
; endr |
169 |
endr |
| 170 |
; rept 32 |
170 |
rept 32 |
| 171 |
; dn 90, 00, $205 |
171 |
dn 90, 00, $205 |
| 172 |
; endr |
172 |
endr |
| 173 |
; volset: |
173 |
volset: |
| 174 |
; dn C5, 00, $000 |
174 |
dn C5, 00, $000 |
| 175 |
; rept 32 |
175 |
rept 32 |
| 176 |
; dn 90, 00, $C90 |
176 |
dn 90, 00, $C90 |
| 177 |
; dn 90, 00, $CF0 |
177 |
dn 90, 00, $CF0 |
| 178 |
; endr |
178 |
endr |
| 179 |
; notecut: |
179 |
notecut: |
| 180 |
; rept 32 |
180 |
rept 32 |
| 181 |
; dn C5, 00, $E04 |
181 |
dn C5, 00, $E04 |
| 182 |
; dn 90, 00, $000 |
182 |
dn 90, 00, $000 |
| 183 |
; endr |
183 |
endr |
| 184 |
|
184 |
|
| 185 |
SECTION "Playback variables", WRAM0 |
185 |
SECTION "Playback variables", WRAM0 |
| 186 |
pattern1: dw |
186 |
pattern1: dw |
@@ -190,6 +190,9 @@ pattern4: dw |
| 190 |
|
190 |
|
| 191 |
current_order: dw |
191 |
current_order: dw |
| 192 |
|
192 |
|
|
|
193 |
;; TODO: Find some way to get rid of this thing. |
|
|
194 |
temp_note_value: dw |
|
|
195 |
|
| 193 |
;; Size of a channel in bytes |
196 |
;; Size of a channel in bytes |
| 194 |
CHANNEL_SIZE EQU 8 |
197 |
CHANNEL_SIZE EQU 8 |
| 195 |
;; Amount to be shifted in order to skip a channel. |
198 |
;; Amount to be shifted in order to skip a channel. |
@@ -296,6 +299,11 @@ _addr = _addr + 1 |
| 296 |
; ld a, $20 |
299 |
; ld a, $20 |
| 297 |
; ldh [rAUD3LEVEL], a |
300 |
; ldh [rAUD3LEVEL], a |
| 298 |
|
301 |
|
|
|
302 |
ld a, %11110000 |
|
|
303 |
ld [envelope1], a |
|
|
304 |
ld a, %11110000 |
|
|
305 |
ld [envelope2], a |
|
|
306 |
|
| 299 |
; Enable sound globally |
307 |
; Enable sound globally |
| 300 |
ld a, $80 |
308 |
ld a, $80 |
| 301 |
ldh [rAUDENA], a |
309 |
ldh [rAUDENA], a |
@@ -350,11 +358,13 @@ ENDM |
| 350 |
|
358 |
|
| 351 |
_lookup_note: |
359 |
_lookup_note: |
| 352 |
;; Call with: |
360 |
;; Call with: |
| 353 |
;; Pattern pointer in DE |
361 |
;; Pattern pointer in BC |
|
|
362 |
;; channel_noteX pointer in DE |
| 354 |
|
363 |
|
| 355 |
;; Stores note period value in HL |
364 |
;; Stores note period value in HL |
| 356 |
;; Stores instrument/effect code in B |
365 |
;; Stores instrument/effect code in B |
| 357 |
;; Stores effect params in C |
366 |
;; Stores effect params in C |
|
|
367 |
;; Stores note number in the memory pointed to by DE |
| 358 |
|
368 |
|
| 359 |
ld a, [row] |
369 |
ld a, [row] |
| 360 |
ld h, a |
370 |
ld h, a |
@@ -362,11 +372,10 @@ _lookup_note: |
| 362 |
add h |
372 |
add h |
| 363 |
add h |
373 |
add h |
| 364 |
|
374 |
|
|
|
375 |
add 2 |
| 365 |
ld h, 0 |
376 |
ld h, 0 |
| 366 |
ld l, a |
377 |
ld l, a |
| 367 |
inc l |
378 |
add hl, bc ; HL now points at the 3rd byte of the note |
| 368 |
inc l |
|
|
| 369 |
add hl, de ; HL now points at the 3rd byte of the note |
|
|
| 370 |
ld a, [hl-] |
379 |
ld a, [hl-] |
| 371 |
ld c, a |
380 |
ld c, a |
| 372 |
ld a, [hl-] |
381 |
ld a, [hl-] |
@@ -374,17 +383,22 @@ _lookup_note: |
| 374 |
|
383 |
|
| 375 |
ld a, [hl] |
384 |
ld a, [hl] |
| 376 |
|
385 |
|
|
|
386 |
;; If the note we found is greater than LAST_NOTE, then it's not a valid note |
|
|
387 |
;; and nothing needs to be updated. |
| 377 |
cp LAST_NOTE |
388 |
cp LAST_NOTE |
| 378 |
ret nc |
389 |
ret nc |
| 379 |
|
390 |
|
| 380 |
ld [channel_note2], a |
391 |
;; Store the loaded note value in channel_noteX |
|
|
392 |
ld h, d |
|
|
393 |
ld l, e |
|
|
394 |
ld [hl], a |
| 381 |
|
395 |
|
| 382 |
_convert_note: |
396 |
_convert_note: |
| 383 |
;; Call with: |
397 |
;; Call with: |
| 384 |
;; Note number in A |
398 |
;; Note number in A |
| 385 |
;; Stores note period value in HL |
399 |
;; Stores note period value in HL |
| 386 |
|
400 |
|
| 387 |
add a, a ;; double it to get index into hi/lo table |
401 |
add a ;; double it to get index into hi/lo table |
| 388 |
|
402 |
|
| 389 |
ld hl, note_table |
403 |
ld hl, note_table |
| 390 |
add_a_to_hl |
404 |
add_a_to_hl |
@@ -392,7 +406,9 @@ _convert_note: |
| 392 |
ld h, [hl] |
406 |
ld h, [hl] |
| 393 |
ld l, a |
407 |
ld l, a |
| 394 |
|
408 |
|
| 395 |
ccf ;; uh....? |
409 |
;; Need to clear the carry flag-- this complements it, but since the last |
|
|
410 |
;; thing that modified the flag always sets it, this will clear it. |
|
|
411 |
ccf |
| 396 |
ret |
412 |
ret |
| 397 |
|
413 |
|
| 398 |
_update_channel: |
414 |
_update_channel: |
@@ -444,42 +460,23 @@ ENDM |
| 444 |
_playnote1: |
460 |
_playnote1: |
| 445 |
;; Call with: |
461 |
;; Call with: |
| 446 |
;; Note value in H and L |
462 |
;; Note value in H and L |
| 447 |
;; Instrument + effect code in B |
|
|
| 448 |
;; Effect params in C |
|
|
| 449 |
|
463 |
|
| 450 |
;; Free: A, D, E |
464 |
;; Free: A, D, E, B, C |
| 451 |
|
465 |
|
| 452 |
;; Play a note on channel 1 (square wave) |
466 |
;; Play a note on channel 1 (square wave) |
| 453 |
strip_instrument |
467 |
; ld a, %11110000 |
| 454 |
|
468 |
; ld [rAUD1ENV], a |
| 455 |
cp $3 |
|
|
| 456 |
jr nz, .no_toneporta |
|
|
| 457 |
ld a, h |
|
|
| 458 |
ld [toneporta_target1+1], a |
|
|
| 459 |
ld a, l |
|
|
| 460 |
ld [toneporta_target1], a |
|
|
| 461 |
ret |
|
|
| 462 |
|
469 |
|
| 463 |
.no_toneporta: |
|
|
| 464 |
cp $C |
|
|
| 465 |
jr nz, .no_volume |
|
|
| 466 |
ld e, c |
|
|
| 467 |
jr .set_regs |
|
|
| 468 |
.no_volume: |
|
|
| 469 |
ld e, %11110000 ; TODO: Get from instrument |
|
|
| 470 |
.set_regs: |
|
|
| 471 |
ld a, %01111111 |
470 |
ld a, %01111111 |
| 472 |
ld [rAUD1LEN], a |
471 |
ld [rAUD1LEN], a |
| 473 |
|
472 |
|
| 474 |
ld a, e |
473 |
ld a, l ; [temp_note_value+1] |
| 475 |
ld [rAUD1ENV], a |
|
|
| 476 |
|
|
|
| 477 |
ld a, l |
|
|
| 478 |
ld [channel_period1], a |
474 |
ld [channel_period1], a |
| 479 |
ld [rAUD1LOW], a |
475 |
ld [rAUD1LOW], a |
| 480 |
|
476 |
|
| 481 |
ld a, h |
477 |
ld a, h ; [temp_note_value] |
| 482 |
ld [channel_period1+1], a |
478 |
ld [channel_period1+1], a |
|
|
479 |
|
| 483 |
or %10000000 |
480 |
or %10000000 |
| 484 |
ld [rAUD1HIGH], a |
481 |
ld [rAUD1HIGH], a |
| 485 |
|
482 |
|
@@ -491,38 +488,22 @@ _playnote2: |
| 491 |
;; instrument + effect code in B |
488 |
;; instrument + effect code in B |
| 492 |
|
489 |
|
| 493 |
;; Play a note on channel 2 (square wave) |
490 |
;; Play a note on channel 2 (square wave) |
| 494 |
strip_instrument |
491 |
; ld a, %11110000 |
| 495 |
|
492 |
; ld [rAUD2ENV], a |
| 496 |
cp $3 |
|
|
| 497 |
jr nz, .no_toneporta |
|
|
| 498 |
ld a, h |
|
|
| 499 |
ld [toneporta_target2+1], a |
|
|
| 500 |
ld a, l |
|
|
| 501 |
ld [toneporta_target2], a |
|
|
| 502 |
ret |
|
|
| 503 |
|
493 |
|
| 504 |
.no_toneporta: |
|
|
| 505 |
cp $C |
|
|
| 506 |
jr nz, .no_volume |
|
|
| 507 |
ld e, c |
|
|
| 508 |
jr .set_regs |
|
|
| 509 |
.no_volume: |
|
|
| 510 |
ld e, %11110000 ; TODO: Get from instrument |
|
|
| 511 |
.set_regs: |
|
|
| 512 |
ld a, %01111111 ; $10 |
494 |
ld a, %01111111 ; $10 |
| 513 |
ld [rAUD2LEN], a |
495 |
ld [rAUD2LEN], a |
| 514 |
|
496 |
|
| 515 |
ld a, e |
497 |
ld a, l ; [temp_note_value+1] |
| 516 |
ld [rAUD2ENV], a |
|
|
| 517 |
|
|
|
| 518 |
ld a, l |
|
|
| 519 |
ld [channel_period2], a |
498 |
ld [channel_period2], a |
| 520 |
ld [rAUD2LOW], a |
499 |
ld [rAUD2LOW], a |
| 521 |
|
500 |
|
| 522 |
ld a, h |
501 |
ld a, h ; [temp_note_value] |
| 523 |
ld [channel_period2+1], a |
502 |
ld [channel_period2+1], a |
|
|
503 |
|
| 524 |
or %10000000 |
504 |
or %10000000 |
| 525 |
ld [rAUD2HIGH], a |
505 |
ld [rAUD2HIGH], a |
|
|
506 |
|
| 526 |
ret |
507 |
ret |
| 527 |
|
508 |
|
| 528 |
_playnote3: |
509 |
_playnote3: |
@@ -531,24 +512,16 @@ _playnote3: |
| 531 |
;; instrument + effect code in B |
512 |
;; instrument + effect code in B |
| 532 |
|
513 |
|
| 533 |
;; Play a note on channel 3 (waveform) |
514 |
;; Play a note on channel 3 (waveform) |
| 534 |
strip_instrument |
515 |
ld a, l ; [temp_note_value+1] |
| 535 |
|
|
|
| 536 |
cp $3 |
|
|
| 537 |
jr nz, .no_toneporta |
|
|
| 538 |
ld a, h |
|
|
| 539 |
ld [toneporta_target2+1], a |
|
|
| 540 |
ld a, l |
|
|
| 541 |
ld [toneporta_target2], a |
|
|
| 542 |
ret |
|
|
| 543 |
|
|
|
| 544 |
.no_toneporta: |
|
|
| 545 |
ld a, l |
|
|
| 546 |
ld [channel_period3], a |
516 |
ld [channel_period3], a |
| 547 |
ld [rAUD3LOW], a |
517 |
ld [rAUD3LOW], a |
| 548 |
ld a, h |
518 |
|
|
|
519 |
ld a, h ; [temp_note_value] |
| 549 |
ld [channel_period3+1], a |
520 |
ld [channel_period3+1], a |
|
|
521 |
|
| 550 |
or %10000000 |
522 |
or %10000000 |
| 551 |
ld [rAUD3HIGH], a |
523 |
ld [rAUD3HIGH], a |
|
|
524 |
|
| 552 |
ret |
525 |
ret |
| 553 |
|
526 |
|
| 554 |
_playnote4: |
527 |
_playnote4: |
@@ -569,24 +542,15 @@ _playnote4: |
| 569 |
|
542 |
|
| 570 |
ret |
543 |
ret |
| 571 |
|
544 |
|
| 572 |
loadShort: MACRO |
|
|
| 573 |
ld a, [\1] |
|
|
| 574 |
ld \3, a |
|
|
| 575 |
ld a, [\1 + 1] |
|
|
| 576 |
ld \2, a |
|
|
| 577 |
ENDM |
|
|
| 578 |
|
|
|
| 579 |
|
|
|
| 580 |
|
|
|
| 581 |
_doeffect: |
545 |
_doeffect: |
| 582 |
;; Call with: |
546 |
;; Call with: |
| 583 |
;; B: instrument nibble + effect type nibble |
547 |
;; B: instrument nibble + effect type nibble |
| 584 |
;; C: effect parameters |
548 |
;; C: effect parameters |
| 585 |
;; E: channel |
549 |
;; E: channel |
| 586 |
|
550 |
|
| 587 |
;; free: A, D, H, L |
551 |
;; free: A, D, H, L |
| 588 |
|
552 |
|
| 589 |
;; Strip the instrument bits off leaving only effect code |
553 |
;; Strip the instrument bits off leaving only effect code |
| 590 |
ld a, b |
554 |
ld a, b |
| 591 |
and %00001111 |
555 |
and %00001111 |
| 592 |
ld b, a |
556 |
ld b, a |
@@ -605,7 +569,9 @@ _doeffect: |
| 605 |
ld h, a |
569 |
ld h, a |
| 606 |
|
570 |
|
| 607 |
ld b, e |
571 |
ld b, e |
| 608 |
|
572 |
ld a, [tick] |
|
|
573 |
cp 0 |
|
|
574 |
; or a ; We can return right off the bat if it's tick zero |
| 609 |
jp hl |
575 |
jp hl |
| 610 |
|
576 |
|
| 611 |
.jump: |
577 |
.jump: |
@@ -622,11 +588,7 @@ _doeffect: |
| 622 |
jp fx_no_op ;fx_set_duty ;9xy |
588 |
jp fx_no_op ;fx_set_duty ;9xy |
| 623 |
jp fx_no_op ;fx_vol_slide ;Axy |
589 |
jp fx_no_op ;fx_vol_slide ;Axy |
| 624 |
jp fx_no_op ;fx_pos_jump ;Bxy |
590 |
jp fx_no_op ;fx_pos_jump ;Bxy |
| 625 |
jp fx_set_volume |
591 |
jp fx_set_volume ;Cxy |
| 626 |
; ret ;Cxy Volume always runs on first tick |
|
|
| 627 |
; nop |
|
|
| 628 |
; nop |
|
|
| 629 |
jp fx_no_op |
|
|
| 630 |
jp fx_no_op ;fx_pattern_break ;Dxy |
592 |
jp fx_no_op ;fx_pattern_break ;Dxy |
| 631 |
jp fx_note_cut ;Exy |
593 |
jp fx_note_cut ;Exy |
| 632 |
jp fx_no_op ;fx_set_speed ;Fxy |
594 |
jp fx_no_op ;fx_set_speed ;Fxy |
@@ -646,15 +608,20 @@ setup_channel_pointer: |
| 646 |
add_a_to_hl |
608 |
add_a_to_hl |
| 647 |
ret |
609 |
ret |
| 648 |
|
610 |
|
|
|
611 |
return_if_tick_zero: MACRO |
|
|
612 |
ret z |
|
|
613 |
ENDM |
|
|
614 |
|
| 649 |
fx_no_op: |
615 |
fx_no_op: |
| 650 |
ret |
616 |
ret |
| 651 |
|
617 |
|
|
|
618 |
;; TODO: Fix this |
| 652 |
fx_note_cut: |
619 |
fx_note_cut: |
| 653 |
;; B: channel |
620 |
;; B: channel |
| 654 |
;; C: effect parameters |
621 |
;; C: effect parameters |
| 655 |
|
622 |
|
| 656 |
;; free registers: A, D, E, H, L |
623 |
;; free registers: A, D, E, H, L |
| 657 |
ld a, [tick] |
624 |
;; ld a, [tick] |
| 658 |
cp c |
625 |
cp c |
| 659 |
ret nz |
626 |
ret nz |
| 660 |
|
627 |
|
@@ -662,6 +629,9 @@ fx_note_cut: |
| 662 |
jp set_channel_volume |
629 |
jp set_channel_volume |
| 663 |
|
630 |
|
| 664 |
fx_set_volume: |
631 |
fx_set_volume: |
|
|
632 |
ret |
|
|
633 |
ret nz ;; Return if we're not on tick zero. |
|
|
634 |
|
| 665 |
;; B: channel |
635 |
;; B: channel |
| 666 |
;; C: effect parameters |
636 |
;; C: effect parameters |
| 667 |
|
637 |
|
@@ -673,8 +643,6 @@ fx_set_volume: |
| 673 |
ld d, 6 |
643 |
ld d, 6 |
| 674 |
call setup_channel_pointer |
644 |
call setup_channel_pointer |
| 675 |
|
645 |
|
| 676 |
ld d, [hl] |
|
|
| 677 |
|
|
|
| 678 |
set_channel_volume: |
646 |
set_channel_volume: |
| 679 |
;; Call with: |
647 |
;; Call with: |
| 680 |
;; Correct volume value in D |
648 |
;; Correct volume value in D |
@@ -687,21 +655,48 @@ set_channel_volume: |
| 687 |
set_chn_3_vol: |
655 |
set_chn_3_vol: |
| 688 |
ld a, d |
656 |
ld a, d |
| 689 |
ld [rAUD3LEVEL], a |
657 |
ld [rAUD3LEVEL], a |
|
|
658 |
|
|
|
659 |
; ld a, [temp_note_value] |
|
|
660 |
; ld h, a |
|
|
661 |
; ld a, [temp_note_value+1] |
|
|
662 |
; ld l, a |
|
|
663 |
; call playnote3 |
|
|
664 |
|
| 690 |
ret |
665 |
ret |
| 691 |
set_chn_2_vol: |
666 |
set_chn_2_vol: |
| 692 |
ld a, d |
667 |
ld a, d |
| 693 |
and %00001111 |
668 |
and %00001111 |
| 694 |
or c |
669 |
or c |
| 695 |
ld [rAUD2ENV], a |
670 |
ld [rAUD2ENV], a |
|
|
671 |
|
|
|
672 |
ld a, [temp_note_value] |
|
|
673 |
ld h, a |
|
|
674 |
ld a, [temp_note_value+1] |
|
|
675 |
ld l, a |
|
|
676 |
call _playnote2 |
|
|
677 |
|
| 696 |
ret |
678 |
ret |
| 697 |
set_chn_1_vol: |
679 |
set_chn_1_vol: |
| 698 |
ld a, d |
680 |
ld a, d |
| 699 |
and %00001111 |
681 |
and %00001111 |
| 700 |
or c |
682 |
or c |
| 701 |
ld [rAUD1ENV], a |
683 |
ld [rAUD1ENV], a |
| 702 |
ret |
684 |
|
|
|
685 |
ld a, [temp_note_value] |
|
|
686 |
ld h, a |
|
|
687 |
ld a, [temp_note_value+1] |
|
|
688 |
ld l, a |
|
|
689 |
call _playnote1 |
|
|
690 |
|
|
|
691 |
;; Don't call _playnote. This is done by grabbing the return |
|
|
692 |
;; address and manually skipping the next call instruction. |
|
|
693 |
pop hl |
|
|
694 |
ld a, 3 |
|
|
695 |
add_a_to_hl |
|
|
696 |
jp hl |
| 703 |
|
697 |
|
| 704 |
fx_vibrato: |
698 |
fx_vibrato: |
|
|
699 |
return_if_tick_zero |
| 705 |
;; B: channel |
700 |
;; B: channel |
| 706 |
;; C: effect parameters |
701 |
;; C: effect parameters |
| 707 |
|
702 |
|
@@ -743,64 +738,8 @@ fx_vibrato: |
| 743 |
ld e, l |
738 |
ld e, l |
| 744 |
jp _update_channel |
739 |
jp _update_channel |
| 745 |
|
740 |
|
| 746 |
;; TODO: Come back and make this work later. |
|
|
| 747 |
|
|
|
| 748 |
; fx_vibrato2: |
|
|
| 749 |
; ld b, e ;; so we have access to DE |
|
|
| 750 |
; ;; B: channel |
|
|
| 751 |
; ;; C: effect parameters |
|
|
| 752 |
|
|
|
| 753 |
; ;; free registers: A, D, E, H, L |
|
|
| 754 |
|
|
|
| 755 |
; ;; This isn't really a sine vibrato, it's the same thing as ProTracker's |
|
|
| 756 |
; ;; "ramp down" setting, basically a sawtooth wave. Fortunately in most cases, |
|
|
| 757 |
; ;; this sounds exactly the same, and we don't need to store a sine table. |
|
|
| 758 |
|
|
|
| 759 |
; ;; Point at the vibrato phase |
|
|
| 760 |
; ld d, 5 |
|
|
| 761 |
; call setup_channel_pointer |
|
|
| 762 |
|
|
|
| 763 |
; ld e, [hl] |
|
|
| 764 |
; inc [hl] |
|
|
| 765 |
; dec hl |
|
|
| 766 |
|
|
|
| 767 |
; ld a, [hl] |
|
|
| 768 |
; call _convert_note |
|
|
| 769 |
|
|
|
| 770 |
; ;; load D with speed |
|
|
| 771 |
; ld a, c |
|
|
| 772 |
; and %11110000 |
|
|
| 773 |
; ld d, a |
|
|
| 774 |
; swap d |
|
|
| 775 |
|
|
|
| 776 |
; xor a ; ld a, 0 |
|
|
| 777 |
|
|
|
| 778 |
; ;; Multiply E ("time") by D (speed) (at most 16 cycles...) |
|
|
| 779 |
; ;; TODO: Find faster multiplication? |
|
|
| 780 |
; .mult1: |
|
|
| 781 |
; add e |
|
|
| 782 |
; dec d |
|
|
| 783 |
; jr nz, .mult1 |
|
|
| 784 |
|
|
|
| 785 |
; ;; Multiply by depth into a 16 bit value |
|
|
| 786 |
; ld e, a ; D is already empty |
|
|
| 787 |
; ; ld hl, 0 |
|
|
| 788 |
|
|
|
| 789 |
; ;; Load E with depth |
|
|
| 790 |
; ld a, c |
|
|
| 791 |
; and %00001111 |
|
|
| 792 |
; .mult2: |
|
|
| 793 |
; add hl, de |
|
|
| 794 |
; dec a |
|
|
| 795 |
; jr nz, .mult2 |
|
|
| 796 |
|
|
|
| 797 |
; ld d, h |
|
|
| 798 |
; ld e, l |
|
|
| 799 |
|
|
|
| 800 |
; jp _update_channel |
|
|
| 801 |
|
|
|
| 802 |
|
|
|
| 803 |
fx_arpeggio: |
741 |
fx_arpeggio: |
|
|
742 |
return_if_tick_zero |
| 804 |
;; B: channel |
743 |
;; B: channel |
| 805 |
;; C: effect parameters |
744 |
;; C: effect parameters |
| 806 |
|
745 |
|
@@ -847,6 +786,7 @@ fx_arpeggio: |
| 847 |
jp _update_channel |
786 |
jp _update_channel |
| 848 |
|
787 |
|
| 849 |
fx_porta_up: |
788 |
fx_porta_up: |
|
|
789 |
return_if_tick_zero |
| 850 |
;; B: channel |
790 |
;; B: channel |
| 851 |
;; C: effect parameters |
791 |
;; C: effect parameters |
| 852 |
|
792 |
|
@@ -871,6 +811,7 @@ fx_porta_up: |
| 871 |
;; TODO: Maybe merge with fx_porta_up, since they're so similar? Would need |
811 |
;; TODO: Maybe merge with fx_porta_up, since they're so similar? Would need |
| 872 |
;; to find a way to compare against effect code. |
812 |
;; to find a way to compare against effect code. |
| 873 |
fx_porta_down: |
813 |
fx_porta_down: |
|
|
814 |
return_if_tick_zero |
| 874 |
;; B: channel |
815 |
;; B: channel |
| 875 |
;; C: effect parameters |
816 |
;; C: effect parameters |
| 876 |
|
817 |
|
@@ -892,8 +833,28 @@ fx_porta_down: |
| 892 |
|
833 |
|
| 893 |
jp _update_channel |
834 |
jp _update_channel |
| 894 |
|
835 |
|
| 895 |
|
|
|
| 896 |
fx_toneporta: |
836 |
fx_toneporta: |
|
|
837 |
jp nz, .do_toneporta |
|
|
838 |
;; We're on tick zero, so just move the temp note value into the toneporta target. |
|
|
839 |
ld d, 2 |
|
|
840 |
call setup_channel_pointer |
|
|
841 |
|
|
|
842 |
ld a, [temp_note_value] |
|
|
843 |
ld c, a |
|
|
844 |
ld a, [temp_note_value+1] |
|
|
845 |
ld e, a |
|
|
846 |
|
|
|
847 |
ld [hl+], a |
|
|
848 |
ld [hl], c |
|
|
849 |
|
|
|
850 |
;; Don't call _playnote. This is done by grabbing the return |
|
|
851 |
;; address and manually skipping the next call instruction. |
|
|
852 |
pop hl |
|
|
853 |
ld a, 3 |
|
|
854 |
add_a_to_hl |
|
|
855 |
jp hl |
|
|
856 |
|
|
|
857 |
.do_toneporta: |
| 897 |
;; B: channel |
858 |
;; B: channel |
| 898 |
;; C: effect parameters |
859 |
;; C: effect parameters |
| 899 |
|
860 |
|
@@ -902,7 +863,6 @@ fx_toneporta: |
| 902 |
;; TOOD: Optimize. This usage of the stack isn't great but IMO it's |
863 |
;; TOOD: Optimize. This usage of the stack isn't great but IMO it's |
| 903 |
;; better than using the stack hack which forces all effects to screw with |
864 |
;; better than using the stack hack which forces all effects to screw with |
| 904 |
;; pushing and popping. Most effects won't need to do this. |
865 |
;; pushing and popping. Most effects won't need to do this. |
| 905 |
|
|
|
| 906 |
ld d, 0 |
866 |
ld d, 0 |
| 907 |
call setup_channel_pointer |
867 |
call setup_channel_pointer |
| 908 |
push hl |
868 |
push hl |
@@ -977,35 +937,84 @@ fx_toneporta: |
| 977 |
|
937 |
|
| 978 |
jp _update_channel |
938 |
jp _update_channel |
| 979 |
|
939 |
|
|
|
940 |
loadShort: MACRO |
|
|
941 |
ld a, [\1] |
|
|
942 |
ld \3, a |
|
|
943 |
ld a, [\1 + 1] |
|
|
944 |
ld \2, a |
|
|
945 |
ENDM |
|
|
946 |
|
| 980 |
_dosound: |
947 |
_dosound: |
| 981 |
ld a, [tick] |
948 |
ld a, [tick] |
| 982 |
cp 0 |
949 |
or a |
| 983 |
jr nz, .process_effects |
950 |
jp nz, .process_effects |
| 984 |
|
951 |
|
| 985 |
;; We're on tick zero, so lookup and play the notes, |
952 |
;; remove this |
| 986 |
;; then return |
953 |
ld a, %11110000 |
|
|
954 |
ld [rAUD1ENV], a |
| 987 |
|
955 |
|
| 988 |
loadShort pattern1, d, e |
956 |
loadShort pattern1, b, c |
| 989 |
call _lookup_note |
957 |
call _lookup_note |
|
|
958 |
|
|
|
959 |
ld a, h |
|
|
960 |
ld [temp_note_value], a |
|
|
961 |
ld a, l |
|
|
962 |
ld [temp_note_value+1], a |
|
|
963 |
|
| 990 |
jr nc, .after_note1 |
964 |
jr nc, .after_note1 |
| 991 |
call _playnote1 |
965 |
|
|
|
966 |
ld e, 0 |
|
|
967 |
call _doeffect |
|
|
968 |
|
|
|
969 |
ld a, [temp_note_value] |
|
|
970 |
ld h, a |
|
|
971 |
ld a, [temp_note_value+1] |
|
|
972 |
ld l, a |
|
|
973 |
call _playnote1 ; 3 bytes |
| 992 |
|
974 |
|
| 993 |
.after_note1: |
975 |
.after_note1: |
| 994 |
loadShort pattern2, d, e |
976 |
loadShort pattern2, b, c |
| 995 |
call _lookup_note |
977 |
call _lookup_note |
| 996 |
jr nc, .after_note2 |
978 |
jr nc, .after_note2 |
|
|
979 |
|
|
|
980 |
ld a, h |
|
|
981 |
ld [temp_note_value], a |
|
|
982 |
ld a, l |
|
|
983 |
ld [temp_note_value+1], a |
|
|
984 |
|
|
|
985 |
ld e, 1 |
|
|
986 |
call _doeffect |
|
|
987 |
|
| 997 |
call _playnote2 |
988 |
call _playnote2 |
| 998 |
|
989 |
|
| 999 |
.after_note2: |
990 |
.after_note2: |
| 1000 |
loadShort pattern3, d, e |
991 |
loadShort pattern3, b, c |
| 1001 |
call _lookup_note |
992 |
call _lookup_note |
| 1002 |
jr nc, .after_note3 |
993 |
jr nc, .after_note3 |
|
|
994 |
|
|
|
995 |
ld a, h |
|
|
996 |
ld [temp_note_value], a |
|
|
997 |
ld a, l |
|
|
998 |
ld [temp_note_value+1], a |
|
|
999 |
|
|
|
1000 |
ld e, 2 |
|
|
1001 |
call _doeffect |
|
|
1002 |
|
| 1003 |
call _playnote3 |
1003 |
call _playnote3 |
| 1004 |
|
1004 |
|
| 1005 |
.after_note3: |
1005 |
.after_note3: |
| 1006 |
loadShort pattern4, d, e |
1006 |
loadShort pattern4, b, c |
| 1007 |
call _lookup_note |
1007 |
call _lookup_note |
| 1008 |
jp nc, process_tick |
1008 |
jr nc, process_tick |
|
|
1009 |
|
|
|
1010 |
ld a, h |
|
|
1011 |
ld [temp_note_value], a |
|
|
1012 |
ld a, l |
|
|
1013 |
ld [temp_note_value+1], a |
|
|
1014 |
|
|
|
1015 |
ld e, 3 |
|
|
1016 |
call _doeffect |
|
|
1017 |
|
| 1009 |
call _playnote4 |
1018 |
call _playnote4 |
| 1010 |
|
1019 |
|
| 1011 |
jp process_tick |
1020 |
jp process_tick |
@@ -1013,7 +1022,7 @@ _dosound: |
| 1013 |
.process_effects: |
1022 |
.process_effects: |
| 1014 |
;; Only do effects if not on tick zero |
1023 |
;; Only do effects if not on tick zero |
| 1015 |
|
1024 |
|
| 1016 |
loadShort pattern1, d, e |
1025 |
loadShort pattern1, b, c |
| 1017 |
call _lookup_note |
1026 |
call _lookup_note |
| 1018 |
|
1027 |
|
| 1019 |
ld a, c |
1028 |
ld a, c |
@@ -1024,7 +1033,7 @@ _dosound: |
| 1024 |
call _doeffect |
1033 |
call _doeffect |
| 1025 |
|
1034 |
|
| 1026 |
.after_effect1: |
1035 |
.after_effect1: |
| 1027 |
loadShort pattern2, d, e |
1036 |
loadShort pattern2, b, c |
| 1028 |
call _lookup_note |
1037 |
call _lookup_note |
| 1029 |
|
1038 |
|
| 1030 |
ld a, c |
1039 |
ld a, c |
@@ -1035,13 +1044,13 @@ _dosound: |
| 1035 |
call _doeffect |
1044 |
call _doeffect |
| 1036 |
|
1045 |
|
| 1037 |
.after_effect2: |
1046 |
.after_effect2: |
| 1038 |
; loadShort pattern3, d, e |
1047 |
; loadShort pattern3, b, c |
| 1039 |
; call _lookup_note |
1048 |
; call _lookup_note |
| 1040 |
; ld e, 2 |
1049 |
; ld e, 2 |
| 1041 |
; call _doeffect |
1050 |
; call _doeffect |
| 1042 |
|
1051 |
|
| 1043 |
.after_effect3: |
1052 |
.after_effect3: |
| 1044 |
; loadShort pattern4, d, e |
1053 |
; loadShort pattern4, b, c |
| 1045 |
; call _lookup_note |
1054 |
; call _lookup_note |
| 1046 |
; ld e, 3 |
1055 |
; ld e, 3 |
| 1047 |
; call _doeffect |
1056 |
; call _doeffect |