-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmog.decoded.def.txt
20665 lines (19095 loc) · 617 KB
/
mog.decoded.def.txt
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
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
; vim: set foldmethod=marker :
;File: mog-d-f.rom ; {{{ 1a000-20000 -> 6000-c000
;DASM As: Memory Mirror File (Non executable file)
;Initial Address: 6000h
;. MSX DASM v0.9 for Linux i386 - CopyRight Fudeba Software, 2004
;Addr Hexa ASCII Z80 Mnemonic Comments
; We can only get here from:
; T6045h (jump)
setAto0x0A_jump6049:
T6000h 3E0A.... >... LD A,00Ah ; A = 0x0A (10 in decimal)
T6002h 1845.... .E.. JR 045h ; Jump to 06049H
SoundHandling:
; !! The interrupt hook calls this function !!
;
; Input:
; 0xE1B1: the value to write to register 7 of the PSG.
; 0xE1B2: ?
; 0xE1C0: ?
# {{{ Select which tone channels to mute and which noise channels to mute.
T6004h 3AB1E1.. :... LD A,(TE1B1H) ; Load value to write to PSG register 7.
T6007h 5F...... _... LD E,A ;
T6008h 3E07.... >... LD A,007h ; PSG register 7: enable/disable noise and/or tone
T600Ah CD9300.. .... CALL T0093H ; WRTPSG
# }}}
T600Dh 3AB2E1.. :... LD A,(TE1B2H)
T6010h CB47.... .G.. BIT 0,A
T6012h C29960.. ..`. JP NZ,T6099H ; if (A&1) jump to jump_to_pointer_in_E10A()
T6015h CB4F.... .O.. BIT 1,A
T6017h C29D60.. ..`. JP NZ,T609DH ; if (A&2) jump to A=0_B=4_load_0xE108_jump_to_0x6063()
T601Ah 3AC0E1.. :... LD A,(TE1C0H)
T601Dh 3D...... .... DEC A
T601Eh FA4C60.. .L`. JP M,T604CH ; Jump if A < 0 (signed) A >= 128 (unsigned) ?End of something?
T6021h C24960.. .I`. JP NZ,T6049H ; Jump if A != 0
; Post: A == 0, and thus *(0xE1C0) == -1
# {{{ *(0xE1C1) -= 1
T6024h 3AC1E1.. :... LD A,(TE1C1H) ; Load volume?
T6027h 3D...... .... DEC A ;
T6028h 32C1E1.. 2... LD (TE1C1H),A ; Store new volume?
# }}}
T602Bh FEF0.... .... CP 0F0h ; Compute A - 0xF0 and set flags.
T602Dh C24060.. .@`. JP NZ,T6040H ; if (A != 0xF0) jump
; Post: A == 0xF0
T6030h 217560.. !u`. LD HL,06075h ; 0x6075 == mute_channel code
T6033h 2200E1.. "... LD (TE100H),HL ; *(0xe100) = 0x6075 (code ref)
T6036h 2202E1.. "... LD (TE102H),HL ; *(0xe102) = 0x6075 (code ref)
T6039h 2204E1.. "... LD (TE104H),HL ; *(0xe104) = 0x6075 (code ref)
T603Ch AF...... .... XOR A ; Clear A and F
T603Dh C34960.. .I`. JP T6049H ; Unconditional jump.
; We can only get here from:
; T602Dh (jump) A != 0xF0
T6040h 3AC4E1.. :... LD A,(TE1C4H)
T6043h FEFA.... .... CP 0FAh
T6045h 28B9.... (... JR Z,0B9h ; if (*(0xe1c4) == 0xFA) jump to 06000H: setAto0x0A_jump6049
T6047h 3E30.... >0.. LD A,030h ; A = 0x30
; We can get here from:
; T6002h (jump) A = 0x0A (10)
; T6021h (jump) A >= 0 and A = *(0xE1C0) - 1
; T603Dh (jump) A = 0x00 ( 0)
; T6047h (fall) A = 0x30 (48)
T6049h 32C0E1.. 2... LD (TE1C0H),A
; We can get here from:
; 0x601E (jump)
; 0x6049 (fall)
T604Ch AF...... .... XOR A ; A = 0 (select channel A)
T604Dh 47...... G... LD B,A ; B = 0
T604Eh 2A00E1.. *... LD HL,(TE100H) ; Will jump to value of HL in next call.
T6051h CD6D60.. .m`. CALL T606DH ; TE1AEH=A,TE1AFH=B,jump2HL
T6054h 3E01.... >... LD A,001h ; A = 1 (select channel B)
T6056h 47...... G... LD B,A ; B = 1
T6057h 2A02E1.. *... LD HL,(TE102H) ; Will jump to HL.
T605Ah CD6D60.. .m`. CALL T606DH ; TE1AEH=A,TE1AFH=B,jump2HL
T605Dh 3E02.... >... LD A,002h ; A = 2 (select channel C)
T605Fh 47...... G... LD B,A ; B = 2
T6060h 2A04E1.. *... LD HL,(TE104H) ; Will jump to HL.
; We can get here from:
; T6060h (fall) A == 2, B == 2)
; T60A3h (jump) A == 0, B == 4)
T6063h CD6D60.. .m`. CALL T606DH ; TE1AEH=A,TE1AFH=B,jump2HL
T6066h 3E02.... >... LD A,002h ; A = 2 (select channel C)
T6068h 0603.... .... LD B,003h ; B = 3
T606Ah 2A06E1.. *... LD HL,(TE106H) ; Will jump to HL.
:TE1AEH=A,TE1AFH=B,jump2HL
; We can get here from:
; T6051h (channel A (A==0), B==0, HL=0xE100)
; T605Ah (channel B (A==1), B==1, HL=0xE102)
; T6063h option 1 (channel C (A==2), B==2, HL=0xE104)
; T606Ah (channel C (A==2), B==3, HL=0xE106)
; T6063h option 2 (channel A (A==0), B==4, HL=0xE108)
T606Dh 32AEE1.. 2... LD (TE1AEH),A
T6070h 78...... x... LD A,B
T6071h 32AFE1.. 2... LD (TE1AFH),A
T6074h E9...... .... JP (HL)
mute_channel:
; Mute channel.
;
; Input:
; *(0xE1AE): channel to mute (set to volume 0).
; *(0xE1AF): channel to set RET code for.
; 0: Channel A (E100,E101)
; 1: Channel B (E102,E103)
; 2: Channel C (E104,E105)
; 3: Channel A' (E106,E107)
;
; Output:
; Channel *(0xE1AE) is set to volume 0.
;
; HL[*(0xE1AF) * 2 + 0] = 0x98, code at 0x6098: "RET"
; HL[*(0xE1AF) * 2 + 1] = 0x60
;
; *(0xE1B0) = 0 (but only if *(0xE1AF) == 3)
;
; Note: quite a lot of references to this piece of code.
T6075h 3AAFE1.. :... LD A,(TE1AFH)
T6078h FE03.... .... CP 003h
T607Ah C28460.. ..`. JP NZ,T6084H ; if (*(0xe1af) != 3) jump to 0x6084
# {{{ *(0xe1b0) = 0
T607Dh AF...... .... XOR A ; Clear A and F
T607Eh 32B0E1.. 2... LD (TE1B0H),A ; *(0xe1b0) = 0
T6081h 3AAFE1.. :... LD A,(TE1AFH) ;
# }}}
T6084h 07...... .... RLCA ; A *= 2
# {{{ HL = 0xE100 + A
T6085h 2100E1.. !... LD HL,0E100h
T6088h 85...... .... ADD A,L
T6089h 6F...... o... LD L,A
T608Ah 3001.... 0... JR NC,001h ; Jump to 0608DH (no carry adjustment needed)
T608Ch 24...... $... INC H ; Manually add carry.
# }}}
T608Dh 119860.. ..`. LD DE,06098h ; Code at 6098 is "RET" (return).
T6090h 73...... s... LD (HL),E
T6091h 23...... #... INC HL ;
T6092h 72...... r... LD (HL),D
T6093h 1E00.... .... LD E,000h ; E = 0 (volume)
T6095h C3B260.. ..`. JP T60B2H ; jump to change_psg_volume(). Set volume to 0.
; The easiest sound code: do nothing.
;
; Since volume for the channel is supposed to be set to 0 already, the
; code means also: SILENCE!
T6098h C9...... .... RET
jump_to_pointer_in_E10A:
T6099h 2A0AE1.. *... LD HL,(TE10AH) ; Channel "C'"?
T609Ch E9...... .... JP (HL) ; Unconditional.
A=0_B=4_load_0xE108_jump_to_0x6063:
; We can only get here from:
; 0x6017
T609Dh AF...... .... XOR A ; Clear A and F
T609Eh 0604.... .... LD B,004h ; B = 4
T60A0h 2A08E1.. *... LD HL,(TE108H) ; Channel "B'"?
T60A3h C36360.. .c`. JP T6063H ; Unconditional jump.
write_PSG_frequency_divider_from_registerE_and_D:
; Set PSG frequency divider registers.
;
; INPUT:
; 0xE1AE: contains which PSG channel to operate on:
; 0: Channel A
; 1: Channel B
; 2: Channel C
; E: Least significant bits of frequency divider
; D: Most significant bits of frequency divider
;
; DESTROYS:
; A, E
; We can get here from:
; T6255h (call)
; T6496h (call)
; T652Dh (jump)
;
; switch(*0xe1ae)
; case 0: set PSG frequency divider register 0+1 (channel A)
; case 1: set PSG frequency divider register 2+3 (channel B)
; case 2: set PSG frequency divider register 4+5 (channel C)
T60A6h 3AAEE1.. :... LD A,(TE1AEH) ; A contains PSG register to write to.
T60A9h 07...... .... RLCA ; A *= 2 (since bit 7 of 0xE1AE is never set).
T60AAh CD9300.. .... CALL T0093H ; Write PSG: least significant bits, from register E.
T60ADh 3C...... <... INC A ; ++A
T60AEh 5A...... Z... LD E,D ; E = D
; Note: unconditional jump
T60AFh C39300.. .... JP T0093H ; Write PSG: most significant bits, from register E.
change_psg_volume:
; The volume is set to register E.
;
; The channel is governed by 0xE1AE:
; 0xE1AE == 0: Change volume of channel A
; 0xE1AE == 1: Change volume of channel B
; 0xE1AE == 2: Change volume of channel C
;
; Input:
; E: the volume to set (00..0x0F)
; Trashes:
; A
;
; We can get here from:
; 0x6095 (jump, unconditionally)
; 0x616C (jump, unconditionally)
; 0x618E (jump, unconditionally)
; 0x6274 (call)
; 0x6345 (jump, unconditionally)
; 0x651E (call)
; 0x657C (call)
T60B2h 3AAEE1.. :... LD A,(TE1AEH)
T60B5h C608.... .... ADD A,008h ; reg 8 == volA, reg 9 == volB, reg 10 == volC
T60B7h C39300.. .... JP T0093H ; Write PSG. Change volume of channel A/B/C. Issues RET (return).
; We can get here from:
; 0x655A (call) ToneNo_NoiseNo, via SetOrDisableNoise_SetOrDisableTone, via sample opcode 0x20 (and 0x24, 0x28, 0x2c).
T60BAh E5...... .... PUSH HL
T60BBh 21FE60.. !.`. LD HL,060FEh ; Tone=no, noise=no.
T60BEh C3D360.. ..`. JP T60D3H ; change_psg_mixer_setting()
; We can get here from:
; 0x6571 (call) NoiseYes_ToneYes, via SetOrDisableNoise_SetOrDisableTone, via sample opcode 0x23 (and 0x27, 0x2b, 0x2f).
T60C1h E5...... .... PUSH HL
T60C2h 21F860.. !.`. LD HL,060F8h ; Tone=yes, noise=yes.
T60C5h C3D360.. ..`. JP T60D3H ; change_psg_mixer_setting()
; We can get here from:
; 0x656B (call) NoiseYes_ToneNo, via SetOrDisableNoise_SetOrDisableTone, via sample opcode 0x21 (and 0x25, 0x29, 0x2d).
T60C8h E5...... .... PUSH HL
T60C9h 21F260.. !.`. LD HL,060F2h ; Tone=no, noise=yes.
T60CCh C3D360.. ..`. JP T60D3H ; change_psg_mixer_setting()
; We can get here from:
; 0x6277 (jump)
; 0x6560 (call) NoiseNo_ToneYes, via SetOrDisableNoise_SetOrDisableTone, via sample opcode 0x22 (and 0x26, 0x2a, 0x2e).
T60CFh E5...... .... PUSH HL
T60D0h 21EC60.. !.`. LD HL,060ECh ; Tone=yes, noise=no.
:change_psg_mixer_setting
;
; Input:
; A: PSG channel (0, 1, 2)
; *(0xE1B1): Base mixer setting (base input for PSG register 7.
; HL[0]: Channel A: bitmask of bits to keep from base mixer setting.
; HL[1]: Channel A: bitmask of bits to set in base mixer setting.
; HL[2]: Channel B: bitmask of bits to keep from base mixer setting.
; HL[3]: Channel B: bitmask of bits to set in base mixer setting.
; HL[4]: Channel C: bitmask of bits to keep from base mixer setting.
; HL[5]: Channel C: bitmask of bits to set in base mixer setting.
;
; HL == 0x60EC (from T60D0h): Tone=yes, noise=no
; HL == 0x60F2 (from T60CCh): Tone=no, noise=yes
; HL == 0x60F8 (from T60C5h): Tone=yes, noise=yes
; HL == 0x60FE (from T60BEh): Tone=no, noise=no
T60D3h 3AAEE1.. :... LD A,(TE1AEH) ; A = channel (0,1,2)
T60D6h 07...... .... RLCA ; A = channel * 2 (0, 2, 4) (is carry cleared btw?)
T60D7h 85...... .... ADD A,L
T60D8h 6F...... o... LD L,A
T60D9h 3001.... 0... JR NC,001h ; Jump to 060DCH
T60DBh 24...... $... INC H ; Manual carry adjust.
T60DCh 3AB1E1.. :... LD A,(TE1B1H) ; A = previous mixer setting.
T60DFh A6...... .... AND (HL) ; Remove unwanted bits: enable selected tone/noise features.
T60E0h 23...... #... INC HL ;
T60E1h B6...... .... OR (HL) ; Add wanted bits. Disable selected tone/noise features.
T60E2h 32B1E1.. 2... LD (TE1B1H),A ; Save/store mixer setting.
T60E5h E1...... .... POP HL
T60E6h 5F...... _... LD E,A
T60E7h 3E07.... >... LD A,007h ; PSG register 7 is "change mixer setting".
T60E9h C39300.. .... JP T0093H ; 0093=WRTPSG. Jump, not a call!
; Data, referenced by T60D0h.
;
; !! Remember: PSG register 7 uses inverse logic:
; !! 0 == Enable
; !! 1 == Disable
;
; bit 0 (mask=0x01): Channel A Tone
; bit 1 (mask=0x02): Channel B Tone
; bit 2 (mask=0x04): Channel C Tone
; bit 3 (mask=0x08): Channel A Noise
; bit 4 (mask=0x10): Channel B Noise
; bit 5 (mask=0x20): Channel C Noise
; bit 6 (mask=0x40): Port A direction - MUST BE 0 (input)
; bit 7 (mask=0x80); Port B direction - MUST BE 1 (output)
;
; Formula:
; Setting = (*(0xE1B1) & first_byte) | second_byte
defb 0xFE ; T60ECh. Clear bit 0 == Channel A: Enable tone generator.
defb 0x08 ; T60EDh. Set bit 3 == Channel A: Detach noise generator from channel.
defb 0xFD ; T60EEh. Clear bit 1 == Channel B: Enable tone generator.
defb 0x10 ; T60EFh. Set bit 4 == Channel B: Detach noise generator from channel.
defb 0xFB ; T60F0h. Clear bit 2 == Channel C: Enable tone generator.
defb 0x20 ; T60F1h. Set bit 5 == Channel C: Detach noise generator from channel.
; Data, referenced by T60C9h.
defb 0xF7 ; T60F2h. Clear bit 3 == Channel A: Attach noise generator to channel.
defb 0x01 ; T60F3h. Set bit 0 == Channel A: Disable tone generator.
defb 0xEF ; T60F4h. Clear bit 4 == Channel B: Attach noise generator to channel.
defb 0x02 ; T60F5h. Set bit 1 == Channel B: Disable tone generator.
defb 0xDF ; T60F6h. Clear bit 5 == Channel C: Attach noise genereator to channel.
defb 0x04 ; T60F7h. Set bit 2 == Channel C: Disable tone generator.
; Data, referenced by T60C2h.
defb 0xF6 ; T60F8h. Clear bit 0 and bit 3 == Channel A: Enable tone generator, attach noise generator to channel.
defb 0x00 ; T60F9h. Don't disable anything.
defb 0xED ; T60FAh. Clear bit 1 and bit 4 == Channel B: Enable tone generator, attach noise generator to channel.
defb 0x00 ; T60FBh. Don't disable anything.
defb 0xDB ; T60FCh. Clear bit 2 and bit 5 == Channel C: Enable tone generator, attach noise generator to channel.
defb 0x00 ; T60FDh. Don't disable anything.
; Data, referenced by T60BBh.
defb 0xFF ; T60FEh. Don't clear any bits.
defb 0x09 ; T60FFh. Set bit 0 and bit 3 == Channel A: Disable tone generator, detach noise generator from channel.
defb 0xFF ; T6100h. Don't clear any bits.
defb 0x12 ; T6101h. Set bit 1 and bit 4 == Channel B: Disable tone generator, detach noise generator from channel.
defb 0xFF ; T6102h. Don't clear any bits.
defb 0x24 ; T6103h. Set bit 2 and bit 5 == Channel C: Disable tone generator, detach noise generator from channel.
# {{{ Set IX to start of memory for sound for channel F.
; We can get here from:
; 0x4FFA-0x4FFD (indirectly) *(0xE10A) is set to 0x6104
T6104h DD2193E1 .!.. LD IX,0E193h
T6108h C31D61.. ..a. JP T611DH ; Jump to code that only depends on IX.
# }}}
# {{{ Set IX to start of memory for sound for channel A.
; We can get here from:
; 0x4ECD-0x4ED0 (indirectly) *(0xE100) is set to 0x610B
T610Bh DD210CE1 .!.. LD IX,0E10Ch ; 0xe10c-0xe126 is memory for sound for channel A.
T610Fh C31D61.. ..a. JP T611DH ; Jump to code that only depends on IX.
# }}}
# {{{ Set IX to start of memory for sound for channel B.
; We can get here from:
; 0x4ED3-0x4ED6 (indirectly) *(0xE102) is set to 0x6112
T6112h DD2127E1 .!'. LD IX,0E127h ; 0xe127-0xe141 is memory for sound for channel B.
T6116h C31D61.. ..a. JP T611DH ; Jump to code that only depends on IX.
# }}}
# {{{ Set IX to start of memory for sound for channel C.
; We can get here from:
; 0x4ED9-0x4EDC (indirectly) *(0xE104) is set to 0x6119
T6119h DD2142E1 .!B. LD IX,0E142h ; 0xe142-0xe15c is memory for sound for channel C.
# }}}
; Channel independent code, since it uses IX only.
;
; We can get here from:
; 0x6108 (jump) IX == 0xE193 (channel F)
; 0x610F (jump) IX == 0xE10C (channel A)
; 0x6116 (jump) IX == 0xE127 (channel B)
; 0x6119 (fall) IX == 0xE142 (channel C)
T611Dh 3AAFE1.. :... LD A,(TE1AFH)
T6120h FE02.... .... CP 002h
T6122h C23061.. .0a. JP NZ,T6130H ; if (*(0xE1AF) != 0x02) jump
; Post: *(0xE1AF) == 0x02
T6125h 3AB0E1.. :... LD A,(TE1B0H)
T6128h B7...... .... OR A
T6129h CA3061.. .0a. JP Z,T6130H ; if (*(0xE1B0) == 0) jump
T612Ch DDCB02EE .... SET 5,(IX+002h)
; We can get here from:
; 0x6122 (jump) *(0xE1AF) != 0x02
; 0x6129 (jump) *(0xE1AF) == 0x02 and *(0xE1B0) == 0
; 0x612C (fall) *(0xE1AF) == 0x02 and *(0xE1B0) != 0 and bit 5 is set in IX[2]
T6130h DD3509.. .5.. DEC (IX+009h) ; Decrement number of VDP ticks left for current sound.
T6133h CA9161.. ..a. JP Z,T6191H ; if(zero ticks left) jump
T6136h DDCB0246 ...F BIT 0,(IX+002h)
T613Ah CA6F61.. .oa. JP Z,T616FH
; IX[2] & 0x01 == 0x01, caused by sound_opcode 0xE9 or ldir initialisation.
T613Dh DD7E16.. .~.. LD A,(IX+016h)
T6140h B7...... .... OR A
T6141h C44964.. .Id. CALL NZ,T6449H ; if (IX[16] != 0) jump to 0x6449
; IX[16] == 0
T6144h DD7E09.. .~.. LD A,(IX+009h) ; Number of VDP ticks left for current sound.
T6147h DDBE0B.. .... CP (IX+00Bh) ; Compute A - IX[0xB] and set flags.
T614Ah D25161.. .Qa. JP NC,T6151H ; If remaining duration >= duration at 0xFx yz - y, jump.
T614Dh DDBE06.. .... CP (IX+006h) ; Compute A - IX[0x6] and set flags.
T6150h D0...... .... RET NC ; If remaining duration >= z of 0xFx yz, return.
; Decrement volume.
T6151h DD5E0A.. .^.. LD E,(IX+00Ah) ; Load volume.
T6154h 1D...... .... DEC E ; Decrease volume.
T6155h F8...... .... RET M ; if (volume < 0) return
T6156h DD730A.. .s.. LD (IX+00Ah),E ; Save decremented volume.
T6159h DDCB026E ...n BIT 5,(IX+002h) ; Test bit 5 in IX[2].
T615Dh C0...... .... RET NZ ; if (IX[2] & 0x20) return
T615Eh 3AC6E1.. :... LD A,(TE1C6H)
T6161h B7...... .... OR A
T6162h 2808.... (... JR Z,008h ; if (*(0xe1c6) == 0) jump to 0x616C
T6164h 3AC9E1.. :... LD A,(TE1C9H)
T6167h B7...... .... OR A
T6168h 2002.... .... JR NZ,002h ; if (*(0xe1c9) != 0) jump to 0x616C
T616Ah 1E00.... .... LD E,000h ; E = 0 (volume)
; We can get here from:
; 0x6162 (jump) *(0xE1C6) == 0
; 0x6168 (jump) *(0xE1C6) != 0 and *(0xE1C9) != 0
; 0x616A (fallthrough) E == 0 (volume)
T616Ch C3B260.. ..`. JP T60B2H ; jump to change_psg_volume(). Unconditional jump!
; We can get here from:
; 0x613A (jump) BIT 0,(IX+002h) is zero/unset.
T616Fh DDCB026E ...n BIT 5,(IX+002h) ; Test bit 5 in IX[2].
T6173h C0...... .... RET NZ ; if (IX[2] & 0x20) return
T6174h DDCB027E ...~ BIT 7,(IX+002h) ; Test bit 7 in IX[2].
T6178h C0...... .... RET NZ ; if (IX[2] & 0x80) return
; IX[2]: bit 5 isn't set, bit 7 isn't set.
T6179h 3AC6E1.. :... LD A,(TE1C6H)
T617Ch B7...... .... OR A
T617Dh 2805.... (... JR Z,005h ; if (*(0xe1c6) == 0) jump to 0x6184
T617Fh 3E01.... >... LD A,001h ; A = 1
T6181h DD771A.. .w.. LD (IX+01Ah),A ; IX[0x1A] = 1
; We can get here from:
; 0x617D (jump) *(0xe1c6) == 0
; 0x6181 (fallthrough)
T6184h CDB064.. ..d. CALL T64B0H ; Carry set means "end of sound definition" (seen 0xFF)
T6187h D0...... .... RET NC ; Return if sound definition not at end.
# {{{ End of sound definition. Mark it and set volume to 0.
T6188h DDCB02FE .... SET 7,(IX+002h)
T618Ch 1E00.... .... LD E,000h ; E = 0 (volume)
T618Eh C3B260.. ..`. JP T60B2H ; jump to change_psg_volume(). Unconditional jump!
#}}}
# {{{ Parse and execute sound definition.
ParseAndExecuteSoundDefinition:
; We can get here by a jump from:
; T6133h
T6191h DD6E00.. .n.. LD L,(IX+000h) ;
T6194h DD6601.. .f.. LD H,(IX+001h) ;
ParseAndExecuteSampleDefinitionWithoutRestoringHLFirst:
T6197h 7E...... ~... LD A,(HL) ;
T6198h 23...... #... INC HL ;
T6199h 4F...... O... LD C,A ;
T619Ah FED0.... .... CP 0D0h ;
T619Ch D24863.. .Hc. JP NC,T6348H ; if (A >= 0xd0) jump to 0x6348
T619Fh DD7500.. .u.. LD (IX+000h),L ; Store increased HL.
T61A2h DD7401.. .t.. LD (IX+001h),H ; Store increased HL.
T61A5h FEC0.... .... CP 0C0h ;
T61A7h D21863.. ..c. JP NC,T6318H ; if (A >= 0xc0) jump to 0x6318
; Post: A < 0xc0. ?"Normal" opcode?
T61AAh E60F.... .... AND 00Fh ; A &= 0x0F (low nybble, reset high nybble)
T61ACh 3C...... <... INC A ; ++A
T61ADh 47...... G... LD B,A ; Set number of loops for DJNZ at T61C8h.
T61AEh DD5E03.. .^.. LD E,(IX+003h) ; E = duration factor
T61B1h 3AC5E1.. :... LD A,(TE1C5H) ;
T61B4h B7...... .... OR A ;
T61B5h 280F.... (... JR Z,00Fh ; if (*(0xE1C5) == 0) Jump to 061C6H
T61B7h 3AC9E1.. :... LD A,(TE1C9H) ;
T61BAh B7...... .... OR A ;
T61BBh 2009.... .... JR NZ,009h ; if (*(0xE1C9) != 0) Jump to 061C6H
T61BDh 3AC5E1.. :... LD A,(TE1C5H) ;
T61C0h FE02.... .... CP 002h ;
T61C2h 2001.... .... JR NZ,001h ; if (*(0xE1C5) != 2) Jump to 061C5H
T61C4h 1D...... .... DEC E ;
; We can get here from:
; 0x61C2 (jump) E == IX[3]
; 0x61C4 (fall) E == IX[3] - 1
T61C5h 1D...... .... DEC E ;
; We can get here from:
; 0x61B5 (jump) E == IX[3]
; 0x61BB (jump) E == IX[3]
; 0x61C5 (fall) E == IX[3] - 1 or E == IX[3] - 2
T61C6h AF...... .... XOR A ; Clear A and F
; We can get here from:
; 0x61C6 (fall) Start of loop
; 0x61C8 (djnz) Next loop
T61C7h 83...... .... ADD A,E ; A += E (loop)
T61C8h 10FD.... .... DJNZ 0FDh ; if (--B != 0) Jump to 061C7H
# }}}
T61CAh DD7709.. .w.. LD (IX+009h),A ; Store number of VDP ticks left for this note/sound.
T61CDh 3AAFE1.. :... LD A,(TE1AFH)
T61D0h FE02.... .... CP 002h
T61D2h C2E061.. ..a. JP NZ,T61E0H ; if (*(0xE1AF) != 2) jump to T61E0H.
; Post: *(0xE1AF) == 2
T61D5h 3AB0E1.. :... LD A,(TE1B0H)
T61D8h B7...... .... OR A
T61D9h C2E061.. ..a. JP NZ,T61E0H ; if (*(0xE1B0) != 0) jump to T61E0H.
T61DCh DDCB02AE .... RES 5,(IX+002h) ; Clear bit 5 in IX[2].
; We can get here from:
; 0x61D2 (jump) *(0xE1AF) != 2
; 0x61D9 (jump) *(0xE1B0) != 0
; 0x61DC (fall) *(0xE1AF) == 2 or *(0xE1B0) == 0
T61E0h DDCB0246 ...F BIT 0,(IX+002h) ; Test bit 0 in IX[2].
T61E4h CA7A62.. .zb. JP Z,T627AH ; if (IX[2] & 1 == 0) jump to select_sample_and_return (T627Ah).
; Post: IX[2] & 1 == 1 (bit 0 is set)
T61E7h DD7E09.. .~.. LD A,(IX+009h) ; A = IX[9]
T61EAh DD9605.. .... SUB A,(IX+005h) ; A = IX[9] - IX[5]
T61EDh DD770B.. .w.. LD (IX+00Bh),A ; IX[0xB] = IX[9] - IX[5]
T61F0h DDCB026E ...n BIT 5,(IX+002h) ; Test bit 5 in IX[2].
T61F4h C0...... .... RET NZ ; if (IX[2] & 0x20 != 0) return
T61F5h 3AC5E1.. :... LD A,(TE1C5H) ;
T61F8h B7...... .... OR A ;
T61F9h 2823.... (#.. JR Z,023h ; if (*(0xE1C5) == 0) jump to T621Eh.
T61FBh 3AC9E1.. :... LD A,(TE1C9H) ;
T61FEh B7...... .... OR A ;
T61FFh 201D.... .... JR NZ,01Dh ; if (*(0xE1C9) != 0) jump to T621Eh.
T6201h 3AC5E1.. :... LD A,(TE1C5H) ;
T6204h FE02.... .... CP 002h ;
T6206h 200B.... .... JR NZ,00Bh ; if (*(0xE1C5) != 2) jump to T6213h.
T6208h 79...... y... LD A,C ; A = current sound opcode.
T6209h E6F0.... .... AND 0F0h ; A = C & 0xF0. Clears low nybble.
T620Bh 0F...... .... RRCA ;
T620Ch 0F...... .... RRCA ;
T620Dh 0F...... .... RRCA ;
; Post: A is now the note index into the/a frequency divider table.
T620Eh 210063.. !.c. LD HL,06300h ; HL = FrequencyDividerTableForOctave0ButStartAtFis
T6211h 1814.... .... JR 014h ; Jump to 06227H, unconditionally!
; We can get here via:
; 0x6206 (jump) C = current_opcode and C < 0xC0 and *(0xE1C5) != 0x23 and *(0xE1C9) == 0 and *(0xE1C5) != 2
T6213h 79...... y... LD A,C ; A = C
T6214h E6F0.... .... AND 0F0h ; Zero the low nybble.
T6216h 0F...... .... RRCA ;
T6217h 0F...... .... RRCA ;
T6218h 0F...... .... RRCA ;
; Post: A is now the note index into the/a frequency divider table.
T6219h 21E862.. !.b. LD HL,062E8h ; HL = FrequencyDividerTableForOctave0ButStartAtDis
; Dis: HL[0] + HL[1] << 8
; E : HL[2] + HL[3] << 8
; etc...
T621Ch 1809.... .... JR 009h ; Jump to 06227H
; We can get here via:
; 0x61F9 (jump) *(0xE1C5) == 0
; 0x61FF (jump) *(0xE1C9) != 0
T621Eh 79...... y... LD A,C ; A = C
T621Fh E6F0.... .... AND 0F0h ;
T6221h 0F...... .... RRCA ; rotate_right(A), carry is only assigned, not shifted in.
T6222h 0F...... .... RRCA ; rotate_right(A), carry is only assigned, not shifted in.
T6223h 0F...... .... RRCA ; rotate_right(A), carry is only assigned, not shifted in.
; Post: A is now the note index into the/a frequency divider table.
T6224h 21D062.. !.b. LD HL,062D0h ; HL = 0x62D0, HL=FrequencyDividerTableForOctave0
; We can get here via:
; 0x6224 (fall) HL == 0x62D0 (FrequencyDividerTableForOctave0)
; 0x6211 (jump) HL == 0x6300 (FrequencyDividerTableForOctave0ButStartAtFis)
; 0x621C (jump) HL == 0x62E8 (FrequencyDividerTableForOctave0ButStartAtDis)
;
; A is the offset to HL, to select the right frequency divider.
;
; Compute HL += A
T6227h 85...... .... ADD A,L ; A += L, assign carry flag.
T6228h 6F...... o... LD L,A ; L = A
T6229h 3001.... 0... JR NC,001h ; if (no overflow) Jump to 0622CH.
T622Bh 24...... $... INC H ; ++H, manually add carry.
; Post: HL points to the correct frequency divider (but in wrong octave).
;
; DE = *HL
T622Ch 5E...... ^... LD E,(HL) ; E = *(HL)
T622Dh 23...... #... INC HL ; ++HL
T622Eh 56...... V... LD D,(HL) ; D = *(HL)
; Octave up means divide frequency by 2 (implemented via bitshifting to the right).
T622Fh DD4607.. .F.. LD B,(IX+007h) ; B = IX[7] (octave), the number of repeats in DJNZ.
T6232h CB3A.... .:.. SRL D ; Part 1 of 16 bit shift right.
T6234h CB1B.... .... RR E ; Part 2 of 16 bit shift right.
T6236h 10FA.... .... DJNZ 0FAh ; if(--B == 0) Jump to 06232H
; Post: DE is the correct frequency divider for the correct octave.
T6238h AF...... .... XOR A ; Clear A and F
T6239h DD7718.. .w.. LD (IX+018h),A ; IX[18] = 0
T623Ch DD7E16.. .~.. LD A,(IX+016h) ; A = IX[16]
T623Fh B7...... .... OR A ;
T6240h 2805.... (... JR Z,005h ; if (IX[16] == 0) jump to T6247h.
T6242h 3EEC.... >... LD A,0ECh ; A = 0xEC
T6244h DD7716.. .w.. LD (IX+016h),A ; IX[16] = 0xEC
; We can get here from:
; 0x6240 (jump) A == 0x00
; 0x6244 (fall) A == 0xEC
T6247h DDCB0276 ...v BIT 6,(IX+002h) ; Test bit 6 of IX[2].
T624Bh CA4F62.. .Ob. JP Z,T624FH ; if (IX[2] & 0x40 == 0) jump to T624Fh.
T624Eh 13...... .... INC DE ; Increase frequency divider (decrease frequency)
T624Fh DD7214.. .r.. LD (IX+014h),D ; Store current frequency divider.
T6252h DD7315.. .s.. LD (IX+015h),E ; Store current frequency divider.
T6255h CDA660.. ..`. CALL T60A6H ; write_PSG_frequency_divider_from_registerE_and_D
T6258h 3AC1E1.. :... LD A,(TE1C1H) ; A = *(0xe1c1)
T625Bh DD8604.. .... ADD A,(IX+004h) ; A += IX[0x4]
T625Eh F26262.. .bb. JP P,T6262H ; if (*(0xe1c1) + IX[0x4] <= 127) jump
T6261h AF...... .... XOR A ; Clear A and F
; We can get here from:
; 0x625E (jump) A <= 127 (i.e. bit 7 is not set)
; 0x6261 (fall) A == 0
T6262h DD770A.. .w.. LD (IX+00Ah),A ; A = IX[0xA]
T6265h 5F...... _... LD E,A ; E = IX[0xA] (volume)
T6266h 3AC6E1.. :... LD A,(TE1C6H) ; A = *(0xE1C6)
T6269h B7...... .... OR A
T626Ah 2808.... (... JR Z,008h ; if (*(0xE1C6) == 0) jump to 06274H
; Post: *(0xE1C6) != 0
T626Ch 3AC9E1.. :... LD A,(TE1C9H)
T626Fh B7...... .... OR A
T6270h 2002.... .... JR NZ,002h ; if (*(0xE1C9) != 0) jump to 06274H
; Post: *(0xE1C9) == 0
T6272h 1E00.... .... LD E,000h ; E = 0 (volume)
; We can get here from:
; 0x626A (jump) E == IX[0xA] and *(0xE1C6) == 0
; 0x6270 (jump) E == IX[0xA] and *(0xE1C6) != 0 and *(0xE1C9) != 0
; 0x6272 (fall) E == 0 and *(0xE1C6) != 0 and *(0xE1C9) == 0
T6274h CDB260.. ..`. CALL T60B2H ; call change_psg_volume()
T6277h C3CF60.. ..`. JP T60CFH ; Unconditional jump! Tone=yes, noise=no
:select_sample_and_return
; Set HL to point to the beginning of the sample.
;
; INPUT:
; IX[8]: The sample table number to use
; reg C: The index into the sample table (i.e. sample number)
;
; CHANGES:
; IX[0x2]: Bit 7 is cleared.
; IX[0xC] + IX[0xD]: Set to HL (beginning of the sample)
; IX[0xE]: Set to 1.
;
; DESTROYS:
; A, HL
;
; We can get here from:
; 0x61E4 (jump) "BIT 0,(IX+002h)" == False, i.e. IX[2] & 1 == 0
T627Ah DD7E08.. .~.. LD A,(IX+008h)
T627Dh FE01.... .... CP 001h
T627Fh 2831.... (1.. JR Z,031h ; Jump to 062B2H
T6281h FE02.... .... CP 002h
T6283h 2833.... (3.. JR Z,033h ; Jump to 062B8H
T6285h FE03.... .... CP 003h
T6287h 2835.... (5.. JR Z,035h ; Jump to 062BEH
T6289h FE04.... .... CP 004h
T628Bh 2837.... (7.. JR Z,037h ; Jump to 062C4H
T628Dh FE05.... .... CP 005h
T628Fh 2839.... (9.. JR Z,039h ; Jump to 062CAH
; Post: IX[8] >= 6 (or IX[8] == 0)
T6291h 211F66.. !.f. LD HL,0661Fh
;; We can get here from:
;; 0x6291 (fall) HL == 0x661F, IX[8] == 0 or IX[8] >= 6
;; 0x62B5 (jump) HL == 0x65A7, IX[8] == 1
;; 0x62BB (jump) HL == 0x65BF, IX[8] == 2
;; 0x62C1 (jump) HL == 0x65D7, IX[8] == 3
;; 0x62C7 (jump) HL == 0x65EF, IX[8] == 4
;; 0x62CD (jump) HL == 0x6607, IX[8] == 5
;;
## {{{ HL += C / 8 (which is 2 times the high nybble)
## This computes the pointer to the next note struct.
T6294h 79...... y... LD A,C
T6295h E6F0.... .... AND 0F0h
T6297h 0F...... .... RRCA
T6298h 0F...... .... RRCA
T6299h 0F...... .... RRCA
T629Ah 85...... .... ADD A,L
T629Bh 6F...... o... LD L,A
T629Ch 3001.... 0... JR NC,001h ; Jump to 0629FH
T629Eh 24...... $... INC H ; Add carry manually.
## }}}
## {{{ Save HL
T629Fh 7E...... ~... LD A,(HL)
T62A0h DD770C.. .w.. LD (IX+00Ch),A ; IX[0xC] = *(HL)
T62A3h 23...... #... INC HL ;
T62A4h 7E...... ~... LD A,(HL) ;
T62A5h DD770D.. .w.. LD (IX+00Dh),A ; IX[0xD] = *(HL)
## }}}
T62A8h DDCB02BE .... RES 7,(IX+002h)
T62ACh 3E01.... >... LD A,001h
T62AEh DD770E.. .w.. LD (IX+00Eh),A ; IX[0xE] = 1
T62B1h C9...... .... RET
; We can get here from:
; 0x627F (jump) IX[8] == 1
T62B2h 21A765.. !.e. LD HL,065A7h ; Load address of sound pointer table.
T62B5h C39462.. ..b. JP T6294H
; We can get here from:
; 0x6283 (jump) IX[8] == 2
T62B8h 21BF65.. !.e. LD HL,065BFh ; Load address of sound pointer table.
T62BBh C39462.. ..b. JP T6294H
; We can get here from:
; 0x6287 (jump) IX[8] == 3
T62BEh 21D765.. !.e. LD HL,065D7h ; Load address of sound pointer table.
T62C1h C39462.. ..b. JP T6294H
; We can get here from:
; 0x628B (jump) IX[8] == 4
T62C4h 21EF65.. !.e. LD HL,065EFh ; Load address of sound pointer table.
T62C7h C39462.. ..b. JP T6294H
; We can get here from:
; 0x628F (jump) IX[8] == 5
T62CAh 210766.. !.f. LD HL,06607h ; Load address of sound pointer table.
T62CDh C39462.. ..b. JP T6294H
;; Frequency divider table for octave 0, loaded at T6224h.
;;
;; One octave up means dividing by 2, hence why bitshifting is used via
;; IX[7].
;;
;; Note 0x0: C
;; Note 0x1: C#
;; Note 0x2: D
;; Note 0x3: D#
;; Note 0x4: E
;; Note 0x5: F
;; Note 0x6: F#
;; Note 0x7: G
;; Note 0x8: G#
;; Note 0x9: A
;; Note 0xA: A#
;; Note 0xB: B
;; Note Octave 0 Octave 1 Octave 2 Octave 3 Octave 4 Octave 5 Octave 6 Octave 7 Octave 8
defb 0xB8 ; T62D0h,+00 C 0x1AB8 0xD5C 0x6AE 0x357 0x1AB 0x0D5 0x06A 0x035 0x01A
defb 0x1A ; T62D1h
defb 0x38 ; T62D2h,+02 C# 0x1938 0xC9C 0x64E 0x327 0x193 0x0C9 0x064 0x032 0x019
defb 0x19 ; T62D3h
defb 0xD0 ; T62D4h,+04 D 0x17D0 0xBE8 0x5F4 0x2FA 0x17D 0x0BE 0x05F 0x02F 0x017
defb 0x17 ; T62D5h
defb 0x78 ; T62D6h,+06 D# 0x1678 0xB3C 0x59E 0x2CF 0x167 0x0B3 0x059 0x02C 0x016
defb 0x16 ; T62D7h
defb 0x34 ; T62D8h,+08 E 0x1534 0xA9A 0x54D 0x2A6 0x153 0x0A9 0x054 0x02A 0x015
defb 0x15 ; T62D9h
defb 0x04 ; T62DAh,+0A F 0x1404 0xA02 0x501 0x280 0x140 0x0A0 0x050 0x028 0x014
defb 0x14 ; T62DBh
defb 0xE4 ; T62DCh,+0C F# 0x12E4 0x972 0x4B9 0x25C 0x12E 0x097 0x04B 0x025 0x012
defb 0x12 ; T62DDh
defb 0xD4 ; T62DEh,+0E G 0x11D4 0x8EA 0x475 0x23A 0x11D 0x08E 0x047 0x023 0x011
defb 0x11 ; T62DFh
defb 0xD4 ; T62E0h,+10 G# 0x10D4 0x86A 0x435 0x21A 0x10D 0x086 0x043 0x021 0x010
defb 0x10 ; T62E1h
defb 0xE4 ; T62E2h,+12 A 0x0FE4 0x7F2 0x3F9 0x1FC 0x0FE 0x07F 0x03F 0x01F 0x00F
defb 0x0F ; T62E3h
defb 0x00 ; T62E4h,+14 A# 0x0F00 0x780 0x3C0 0x1E0 0x0F0 0x078 0x03C 0x01E 0x00F
defb 0x0F ; T62E5h
defb 0x28 ; T62E6h,+16 B 0x0E28 0x714 0x38A 0x1C5 0x0E2 0x071 0x038 0x01C 0x00E
defb 0x0E ; T62E7h
:FrequencyDividerTableForOctave0ButStartAtDis
;; Frequency divider table for octave 0 + 3 halve notes. So, it
;; basically the same as T62D0h, just modulated/transposed upwards with
;; 3 halve notes.
;;
;; Referenced by T6219h.
;;
;; This table is used during a boss fight, when the boss has sustained a
;; fair amount of damage. Tempo of the music goes up (but not due to
;; this table) and the music is modulated/transposed by 3 halve notes.
;; Index Note Octave
defw 0x1678 ; T62E8h+T62E9h 0 D# 0
defw 0x1534 ; T62EAh+T62EBh 1 E 0
defw 0x1404 ; T62ECh+T62EDh 2 F 0
defw 0x12E4 ; T62EEh+T62EFh 3 F# 0
defw 0x11D4 ; T62F0h+T62F1h 4 G 0
defw 0x10D4 ; T62F2h+T62F3h 5 G# 0
defw 0x0FE4 ; T62F4h+T62F5h 6 A 0
defw 0x0F00 ; T62F6h+T62F7h 7 A# 0
defw 0x0E28 ; T62F8h+T62F9h 8 B 0
defw 0x0D5C ; T62FAh+T62FBh 9 C 1
defw 0x0C9C ; T62FCh+T62FDh 0xA C# 1
defw 0x0BE8 ; T62FEh+T62FFh 0xB D 1
:FrequencyDividerTableForOctave0ButStartAtFis
;; Frequency divider table for octave 0 + half an octave. So, it basically
;; the same as T62D0h, just transposed upwards with a half octave.
;;
;; Referenced by T620Eh.
;;
;; This table is used during a boss fight, when the boss has sustained
;; near fatal damage. Tempo of the music goes up (but not due to this
;; table) and the music is modulated/transposed by a further 3 halve
;; notes. (6 halve notes since the start of the boss fight.)
;; Index Note Octave
defw 0x12E4 ; T6300h+T6301h 0 F# 0
defw 0x11D4 ; T6302h+T6303h 1 G 0
defw 0x10D4 ; T6304h+T6305h 2 G# 0
defw 0x0FE4 ; T6306h+T6307h 3 A 0
defw 0x0F00 ; T6308h+T6309h 4 A# 0
defw 0x0E28 ; T630Ah+T630Bh 5 B 0
defw 0x0D5C ; T630Ch+T630Dh 6 C 1
defw 0x0C9C ; T630Eh+T630Fh 7 C# 1
defw 0x0BE8 ; T6310h+T6311h 8 D 1
defw 0x0B3C ; T6312h+T6313h 9 D# 1
defw 0x0A9C ; T6314h+T6315h 0xA E 1
defw 0x0A04 ; T6316h+T6317h 0xB F 1
; We can get here from:
; T61A7h (jump) A >= 0xc0 and A < 0xd0, so high nybble is 0xC.
T6318h E60F.... .... AND 00Fh
T631Ah 3C...... <... INC A ;
T631Bh 47...... G... LD B,A
T631Ch DD5E03.. .^.. LD E,(IX+003h) ; E = IX[3], load duration factor.
T631Fh 3AC5E1.. :... LD A,(TE1C5H)
T6322h B7...... .... OR A
T6323h 280F.... (... JR Z,00Fh ; Jump to 06334H
T6325h 3AC9E1.. :... LD A,(TE1C9H)
T6328h B7...... .... OR A
T6329h 2009.... .... JR NZ,009h ; Jump to 06334H
T632Bh 3AC5E1.. :... LD A,(TE1C5H)
T632Eh FE02.... .... CP 002h
T6330h 2001.... .... JR NZ,001h ; Jump to 06333H
T6332h 1D...... .... DEC E
; We can get here from:
; 0x6330 (jump)
; 0x6332 (fall)
T6333h 1D...... .... DEC E
; We can get here from:
; 0x6323 (jump) E == IX[3], *(0xE1C5) == 0
; 0x6329 (jump) E == IX[3], *(0xE1C9) != 0
; 0x6333 (fall) E == IX[3] - 1 or E == IX[3] - 2
T6334h AF...... .... XOR A ; Clear A and F
; We can get here from:
; 0x6334 (fall) Start of loop
; 0x6336 (djnz) Next loop
T6335h 83...... .... ADD A,E ; A += E
T6336h 10FD.... .... DJNZ 0FDh ; Jump to 06335H
T6338h DD7709.. .w.. LD (IX+009h),A
T633Bh DDCB026E ...n BIT 5,(IX+002h)
T633Fh C0...... .... RET NZ
T6340h 1E00.... .... LD E,000h ; E = 0 (volume)
T6342h DD730A.. .s.. LD (IX+00Ah),E ; Store volume.
T6345h C3B260.. ..`. JP T60B2H ; jump to change_psg_volume(). Unconditional jump!
; We can only get here from:
; 0x619C (jump) Happens when A >= 0xd0, where A is the current sample_opcode.
T6348h E6F0.... .... AND 0F0h ; Select high nybble.
T634Ah FED0.... .... CP 0D0h ;
T634Ch CA9A63.. ..c. JP Z,T639AH ; if (high nybble == 0xD) jump to SetDurationFactor.
T634Fh FEE0.... .... CP 0E0h ;
T6351h CAA363.. ..c. JP Z,T63A3H ; if (high nybble == 0xE) jump to 0x63A3
; Post: A >= 0xf0
T6354h 79...... y... LD A,C ; A = IX[0]
T6355h E60F.... .... AND 00Fh ; Select low nybble.
T6357h FE0F.... .... CP 00Fh ;
T6359h CA3464.. .4d. JP Z,T6434H ; if (low nybble == 0xF) jump to 0x6434: enable PSG channel defined by 0xe1af.
T635Ch FE0E.... .... CP 00Eh ;
T635Eh C28163.. ..c. JP NZ,T6381H ; if (low nybble != 0xE) jump to 0x6381
;; Post: low nybble of *(IX + 0) is 0xE.
T6361h DD7E10.. .~.. LD A,(IX+010h)
T6364h 3D...... .... DEC A
T6365h CA7863.. .xc. JP Z,T6378H ; if (*(IX + 0x10) == 1) jump to 0x6378
T6368h F26D63.. .mc. JP P,T636DH ; if (*(IX + 0x10) != 0) jump to 0x636D
T636Bh 7E...... ~... LD A,(HL) ; A = *(HL), with HL = *(IX) + 1
T636Ch 3D...... .... DEC A
; We can also get here by a jump from 0x6368.
# {{{ HL = *(HL + 1), which is basically: HL = *(*(IX + 0) + 2)
T636Dh 23...... #... INC HL ;
T636Eh DD7710.. .w.. LD (IX+010h),A ; Save A
T6371h 7E...... ~... LD A,(HL)
T6372h 23...... #... INC HL ;
T6373h 66...... f... LD H,(HL)
T6374h 6F...... o... LD L,A
# }}}
T6375h C39761.. ..a. JP T6197H ; ParseAndExecuteSampleDefinitionWithoutRestoringHLFirst
T6378h DD7710.. .w.. LD (IX+010h),A ; Save A.
T637Bh 23...... #... INC HL ; Skip?
T637Ch 23...... #... INC HL ; Skip?
T637Dh 23...... #... INC HL ; Skip?
T637Eh C39761.. ..a. JP T6197H ; ParseAndExecuteSampleDefinitionWithoutRestoringHLFirst
; We can only get here from:
; 0x635E (jump) current opcode is 0xF?, but not 0xFE and not 0xFF.
T6381h 3C...... <... INC A ;
T6382h DD7704.. .w.. LD (IX+004h),A ; Store low nybble + 1 of sound opcode.
T6385h 7E...... ~... LD A,(HL) ; Read next sound opcode
T6386h 0F...... .... RRCA
T6387h 0F...... .... RRCA
T6388h 0F...... .... RRCA
T6389h 0F...... .... RRCA
T638Ah E60F.... .... AND 00Fh ; A >>= 4 (carries are removed)
T638Ch 3D...... .... DEC A
T638Dh DD7705.. .w.. LD (IX+005h),A ; *(IX + 5) = (*(HL) >> 4) - 1
T6390h 7E...... ~... LD A,(HL)
T6391h 23...... #... INC HL ;
T6392h E60F.... .... AND 00Fh
T6394h DD7706.. .w.. LD (IX+006h),A ; *(IX + 6) = (*(HL_old) & 0x0F)
T6397h C39761.. ..a. JP T6197H ; ParseAndExecuteSampleDefinitionWithoutRestoringHLFirst
:SetDurationFactor
; We can only get here from
; 0x634C (jump) (A & 0xF0) == 0xD0)
T639Ah 79...... y... LD A,C ;
T639Bh E60F.... .... AND 00Fh
T639Dh DD7703.. .w.. LD (IX+003h),A ; Set duration factor to C & 0x0F.
T63A0h C39761.. ..a. JP T6197H ; ParseAndExecuteSampleDefinitionWithoutRestoringHLFirst
; We can only get here from
; 0x6351 (jump) (A & 0xF0) == 0xE0, i.e. high nybble is 0xE)
;
T63A3h 79...... y... LD A,C ; A and C now contain the current sample opcode (0xE?).
T63A4h E60F.... .... AND 00Fh
T63A6h FE0C.... .... CP 00Ch ;
T63A8h 285F.... (_.. JR Z,05Fh ; if (C & 0x0F == 0x0C) Jump to SetIX16To0xECSetIX17ToNextOpcode (T6409h).
T63AAh FE06.... .... CP 006h
T63ACh DAE963.. ..c. JP C,T63E9H ; if (C & 0x0F < 0x06) jump to SetOctave.
T63AFh CAF363.. ..c. JP Z,T63F3H ; if (C & 0x0F == 0x06) jump to Set0xE1C3to1.
T63B2h FE07.... .... CP 007h
T63B4h CA0264.. ..d. JP Z,T6402H ; if (C & 0x0F == 0x07) jump to SetBit6inIX2.
T63B7h FE0A.... .... CP 00Ah
T63B9h CA1664.. ..d. JP Z,T6416H ; if (C & 0x0F == 0x0A) jump to SampleDefinitionContinuesAtValueOfHL.
T63BCh FE0B.... .... CP 00Bh
T63BEh CAFB63.. ..c. JP Z,T63FBH ; if (C & 0x0F == 0x0B) jump
T63C1h FE0D.... .... CP 00Dh
T63C3h CA1D64.. ..d. JP Z,T641DH ; if (C & 0x0F == 0x0D) jump to save_HL_in_IX12_and_IX13_continue_sound_at_argument (T641Dh)
T63C6h FE0E.... .... CP 00Eh
T63C8h CA2B64.. .+d. JP Z,T642BH ; if (C & 0x0F == 0x0E) jump to restore_HL_from_IX12_and_IX13 (T642Bh)
; Register A can still be any of: 0x08 0x09 0x0f
:ChangeLower3bitsInIX2
T63CBh E607.... .... AND 007h ; Get least significant 3 bits of the current opcode.
T63CDh 47...... G... LD B,A ; B = current_opcode & 7
; Post:
; if current_opcode == 0x08 then B == 0
; if current_opcode == 0x09 then B == 1
; if current_opcode == 0x0F then B == 7
T63CEh DD7E02.. .~.. LD A,(IX+002h) ; A = IX[2]
T63D1h E6F8.... .... AND 0F8h ; Get most significant 5 bits.
T63D3h B0...... .... OR B ; A = (IX[2] & 0xF8) | (current_opcode & 7)
T63D4h DD7702.. .w.. LD (IX+002h),A ; IX[2] = A
T63D7h 79...... y... LD A,C ; A = C
T63D8h E60F.... .... AND 00Fh ; A &= 0xf
T63DAh FE08.... .... CP 008h ; Compute A - 8 and set flags. Tests bit 3 of new IX[2].
T63DCh 2803.... (... JR Z,003h ; if (A == 8) Jump to 063E1H
T63DEh C39761.. ..a. JP T6197H ; ParseAndExecuteSampleDefinitionWithoutRestoringHLFirst
; We can only get here from:
; 0x63DC (jump) current_opcode == 0xE8 (switch to sample mode)
T63E1h 7E...... ~... LD A,(HL) ; A = *HL
T63E2h 23...... #... INC HL ; ++HL
T63E3h DD7708.. .w.. LD (IX+008h),A ; IX[8] = A
T63E6h C39761.. ..a. JP T6197H ; ParseAndExecuteSampleDefinitionWithoutRestoringHLFirst
:SetOctave
; We can only get here from:
; 0x63AC (jump)
T63E9h ED44.... .D.. NEG ; A = -A
T63EBh C606.... .... ADD A,006h ; A += 6
T63EDh DD7707.. .w.. LD (IX+007h),A ; IX[7] = A, set the octave
T63F0h C39761.. ..a. JP T6197H ; ParseAndExecuteSampleDefinitionWithoutRestoringHLFirst
:Set0xE1C3to1
; We can only get here from: