forked from Tronix286/AIL2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathYAMAHA.INC
2641 lines (2208 loc) · 91.9 KB
/
YAMAHA.INC
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
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ YAMAHA.INC ÛÛ
;ÛÛ ÛÛ
;ÛÛ IBM Audio Interface Library XMIDI interpreter for Ad Lib, etc. ÛÛ
;ÛÛ including YMF262 (aka OPL3) 2-and-4-operator FM support ÛÛ
;ÛÛ ÛÛ
;ÛÛ Version 1.00 of 15-Feb-92: Init version (replaces YM3812.INC v1.04) ÛÛ
;ÛÛ 1.01 of 20-Jun-92: Pro Audio Spectrum Plus/16 support added ÛÛ
;ÛÛ Remove REPTs to circumvent TASM bug ÛÛ
;ÛÛ Reset PAS to Ad Lib mode on shutdown ÛÛ
;ÛÛ 1.02 of 13-Nov-92: Detect OPL3 at 2x8, not 2x0 ÛÛ
;ÛÛ ÛÛ
;ÛÛ 8086 ASM source compatible with Turbo Assembler v2.0 or later ÛÛ
;ÛÛ Author: John Miles ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ Copyright (C) 1991, 1992 Miles Design, Inc. ÛÛ
;ÛÛ ÛÛ
;ÛÛ Miles Design, Inc. ÛÛ
;ÛÛ 10926 Jollyville #308 ÛÛ
;ÛÛ Austin, TX 78759 ÛÛ
;ÛÛ (512) 345-2642 / FAX (512) 338-9630 / BBS (512) 454-9990 ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;
;Driver-specific configuration equates
;
OSI_ALE equ FALSE ;TRUE to assemble OSI TVFX code
MAX_REC_CHAN equ 10 ;Max channel recognized by synths
MAX_TRUE_CHAN equ 9 ;Max channel available for locking
MIN_TRUE_CHAN equ 2 ;Min channel # (1-based)
DEF_SYNTH_VOL equ 100 ;Init vol=100%
MAX_TIMBS equ 192 ;Max # of timbres in local cache
DEF_TC_SIZE equ 3584 ;Room for 256 14-byte .BNK timbres
IFDEF YM3812
NUM_VOICES equ 9 ;# of physical voices available
NUM_SLOTS equ 16 ;# of virtual voices available
ELSEIFDEF YMF262
NUM_VOICES equ 18 ;# of physical voices available
NUM_4OP_VOICES equ 6
NUM_SLOTS equ 20 ;# of virtual voices available
ENDIF
VEL_SENS equ 1 ;Velocity sensitivity disabled if 0
VEL_TRUE equ 0 ;Full velocity sensitivity range if 1
;(set to 0 to reduce playback noise)
DEF_PITCH_RANGE equ 12 ;Default pitch wheel range (semitones)
DEF_AV_DEPTH equ 11000000b ;Default AM/Vibrato depth
;bit 7: AM depth 4.8dB if 1, else 1dB
;bit 6: VIB depth 14c. if 1, else 7c.
IFDEF YMF262 ;Panpot thresholds for OPL3 voices
R_PAN_THRESH equ 27 ;Force right channel if pan <= n
L_PAN_THRESH equ 100 ;Force left channel if pan >= n
IFDEF SBPRO2
LEFT_MASK equ 11011111b
RIGHT_MASK equ 11101111b
ELSEIFDEF PASOPL
LEFT_MASK equ 11011111b
RIGHT_MASK equ 11101111b
ELSE
LEFT_MASK equ 11101111b
RIGHT_MASK equ 11011111b
ENDIF
ENDIF
CIRC_ASSIGN equ TRUE ;FALSE for "old" AIL voice assignment
;
;Internal equates
;
IFDEF SBPRO1
SBPRO equ 1
ENDIF
IFDEF SBPRO2
SBPRO equ 1
ENDIF
IFDEF PAS
PROAUDIO equ 1
ENDIF
IFDEF PASOPL
PROAUDIO equ 1
ENDIF
;
;Driver Description Table (DDT)
;Returned by describe_driver() proc
;
DDT LABEL WORD
min_API_version dw 200 ;Minimum API version required = 2.00
drvr_type dw 3 ;Type 3: XMIDI emulation
data_suffix LABEL BYTE
IFDEF YMF262
db 'OPL',0 ;Supports .OPL Global Timbre file
ELSE ;(backward-compatible w/.AD format)
db 'AD',0,0 ;Needs .AD Global Timbre file
ENDIF
device_name_o dw OFFSET devnames ;Pointer to list of supported devices
device_name_s dw ?
default_IO LABEL WORD ;Factory default I/O parameters
IFDEF ADLIBSTD
dw 388h
ELSEIFDEF SBSTD
dw 220h
ELSEIFDEF PROAUDIO
dw -1
ELSEIFDEF SBPRO1
dw 220h
ELSEIFDEF SBPRO2
dw 220h
ELSEIFDEF ADLIBG
dw 388h
ENDIF
default_IRQ dw -1
default_DMA dw -1
default_DRQ dw -1
service_rate dw QUANT_RATE ;Request 120 calls/second
display_size dw 0 ;No display
devnames LABEL BYTE
IFDEF ADLIBSTD
db 'Ad Lib(R) Music Synthesizer Card',0
ELSEIFDEF SBSTD
db 'Creative Labs Sound Blaster(TM) FM Sound',0
db 'Media Vision Thunderboard(TM) FM Sound',0
ELSEIFDEF PAS
db 'Media Vision Pro Audio Spectrum(TM) 8 FM Sound',0
ELSEIFDEF PASOPL
db 'Media Vision Pro Audio Spectrum(TM) Plus/16 FM Sound',0
ELSEIFDEF SBPRO
db 'Creative Labs Sound Blaster Pro(TM) FM Sound',0
ELSEIFDEF ADLIBG
db 'Ad Lib(R) Gold Music Synthesizer Card',0
ENDIF
db 0 ;0 to end list of device names
IFDEF YM3812
IOWVAL equ 42
IFDEF STEREO
STEREO_3812 equ 1
ENDIF
ELSEIFDEF YMF262
IOWVAL equ 8
ENDIF
IF OSI_ALE
INCLUDE ale.inc
ENDIF
;
;Default setup values & internal constants
;
freq_table dw 02b2h,02b4h,02b7h,02b9h,02bch,02beh,02c1h,02c3h,02c6h,02c9h
dw 02cbh,02ceh,02d0h,02d3h,02d6h,02d8h,02dbh,02ddh,02e0h,02e3h
dw 02e5h,02e8h,02ebh,02edh,02f0h,02f3h,02f6h,02f8h,02fbh,02feh
dw 0301h,0303h,0306h,0309h,030ch,030fh,0311h,0314h,0317h,031ah
dw 031dh,0320h,0323h,0326h,0329h,032bh,032eh,0331h,0334h,0337h
dw 033ah,033dh,0340h,0343h,0346h,0349h,034ch,034fh,0352h,0356h
dw 0359h,035ch,035fh,0362h,0365h,0368h,036bh,036fh,0372h,0375h
dw 0378h,037bh,037fh,0382h,0385h,0388h,038ch,038fh,0392h,0395h
dw 0399h,039ch,039fh,03a3h,03a6h,03a9h,03adh,03b0h,03b4h,03b7h
dw 03bbh,03beh,03c1h,03c5h,03c8h,03cch,03cfh,03d3h,03d7h,03dah
dw 03deh,03e1h,03e5h,03e8h,03ech,03f0h,03f3h,03f7h,03fbh,03feh
dw 0fe01h,0fe03h,0fe05h,0fe07h,0fe08h,0fe0ah,0fe0ch,0fe0eh,0fe10h,0fe12h
dw 0fe14h,0fe16h,0fe18h,0fe1ah,0fe1ch,0fe1eh,0fe20h,0fe21h,0fe23h,0fe25h
dw 0fe27h,0fe29h,0fe2bh,0fe2dh,0fe2fh,0fe31h,0fe34h,0fe36h,0fe38h,0fe3ah
dw 0fe3ch,0fe3eh,0fe40h,0fe42h,0fe44h,0fe46h,0fe48h,0fe4ah,0fe4ch,0fe4fh
dw 0fe51h,0fe53h,0fe55h,0fe57h,0fe59h,0fe5ch,0fe5eh,0fe60h,0fe62h,0fe64h
dw 0fe67h,0fe69h,0fe6bh,0fe6dh,0fe6fh,0fe72h,0fe74h,0fe76h,0fe79h,0fe7bh
dw 0fe7dh,0fe7fh,0fe82h,0fe84h,0fe86h,0fe89h,0fe8bh,0fe8dh,0fe90h,0fe92h
dw 0fe95h,0fe97h,0fe99h,0fe9ch,0fe9eh,0fea1h,0fea3h,0fea5h,0fea8h,0feaah
dw 0feadh,0feafh
note_octave db 0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1
db 1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2
db 2,2,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4
db 4,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5
db 5,5,5,5,6,6,6,6,6,6,6,6,6,6,6,6,7
db 7,7,7,7,7,7,7,7,7,7,7
note_halftone db 0,1,2,3,4,5,6,7,8,9,10,11,0,1,2,3,4
db 5,6,7,8,9,10,11,0,1,2,3,4,5,6,7,8,9
db 10,11,0,1,2,3,4,5,6,7,8,9,10,11,0,1,2
db 3,4,5,6,7,8,9,10,11,0,1,2,3,4,5,6,7
db 8,9,10,11,0,1,2,3,4,5,6,7,8,9,10,11,0
db 1,2,3,4,5,6,7,8,9,10,11
array0_init db 00100000b,0,0,01100000b,0,0,0,0,0,0,0,0,0,0,0 ;01-0f
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;10-1f
db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;20-2f
db 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0 ;30-3f
db 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 ;40-4f
db 63,63,63,63,63,63,0,0,0,0,0,0,0,0,0,0 ;50-5f
db 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
db 255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0 ;70-7f
db 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 ;80-8f
db 15,15,15,15,15,15,0,0,0,0,0,0,0,0,0,0 ;90-9f
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;a0-af
db 0,0,0,0,0,0,0,0,0,0,0,0,0,DEF_AV_DEPTH,0,0 ;b0-bf
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;c0-cf
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;d0-df
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;e0-ef
db 0,0,0,0,0,0 ;f0-f5
array1_init db 0,0,0,0,00000001b,0,0,0,0,0,0,0,0,0,0 ;01-0f
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;10-1f
db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 ;20-2f
db 1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0 ;30-3f
db 63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63 ;40-4f
db 63,63,63,63,63,63,0,0,0,0,0,0,0,0,0,0 ;50-5f
db 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
db 255,255,255,255,255,255,0,0,0,0,0,0,0,0,0,0 ;70-7f
db 15,15,15,15,15,15,15,15,15,15,15,15,15,15,15,15 ;80-8f
db 15,15,15,15,15,15,0,0,0,0,0,0,0,0,0,0 ;90-9f
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;a0-af
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;b0-bf
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;c0-cf
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;d0-df
db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;e0-ef
db 0,0,0,0,0,0 ;f0-f5
vel_graph db 82,85,88,91,94,97,100,103,106,109,112,115,118,121,124,127
IFDEF STEREO_3812
pan_graph db 0,2,4,6,8,10,12,14,16,18,20,22,24,26,28,30
db 32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62
db 64,66,68,70,72,74,76,78,80,82,84,86,88,90,92,94
db 96,98,100,102,104,106,108,110,112,114,116,118,120,122,124,127
db 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127
db 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127
db 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127
db 127,127,127,127,127,127,127,127,127,127,127,127,127,127,127,127
ENDIF
op_0 db 0,1,2,6,7,8,12,13,14,18,19,20,24,25,26,30,31,32
op_1 db 3,4,5,9,10,11,15,16,17,21,22,23,27,28,29,33,34,35
op_index db 0,1,2,3,4,5,8,9,10,11,12,13,16,17,18,19,20,21
db 0,1,2,3,4,5,8,9,10,11,12,13,16,17,18,19,20,21
op_array db 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
db 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
voice_num db 0,1,2,3,4,5,6,7,8,0,1,2,3,4,5,6,7,8
voice_array db 0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1
op4_base db 1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0
alt_voice db 3,4,5,0,1,2,-1,-1,-1,12,13,14,9,10,11,-1,-1,-1
IFDEF YMF262
alt_op_0 db 6,7,8,0,1,2,-1,-1,-1,24,25,26,18,19,20,-1,-1,-1
alt_op_1 db 9,10,11,3,4,5,-1,-1,-1,27,28,29,21,22,23,-1,-1,-1
conn_sel db 1,2,4,1,2,4,0,0,0,8,16,32,8,16,32,0,0,0
op4_voice db 0,1,2,9,10,11
carrier_01 db 00b,01b,10b,01b
carrier_23 db 10b,10b,10b,11b
ENDIF
;
;Misc. data
;
IFDEF STEREO_3812
LFMADDR dw ?
LFMDATA dw ?
RFMADDR dw ?
RFMDATA dw ?
ENDIF
IFDEF SBPRO
MIXADDR dw ?
MIXDATA dw ?
ENDIF
DATA_OUT dw ? ;IO_addr+1
ADDR_STAT dw ? ;IO_addr
IFDEF ADLIBG ;(used during detection)
CTRL_ADDR dw ?
CTRL_DATA dw ?
ENDIF
note_event_l dw ? ;used for LRU counting
note_event_h dw ?
timb_hist_l dw MAX_TIMBS dup (?) ;last note event count for LRU
timb_hist_h dw MAX_TIMBS dup (?)
timb_offsets dw MAX_TIMBS dup (?) ;offsets of resident timbres
timb_bank db MAX_TIMBS dup (?) ;GTR bank
timb_num db MAX_TIMBS dup (?) ;GTR #
timb_attribs db MAX_TIMBS dup (?) ;bit 7=in use 6=protected
cache_base dd ? ;timbre cache base addr
cache_size dw ? ;total cache size in bytes
cache_end dw ? ;offset of first free byte
TV_accum dw ? ;DDA accum for refresh timing
pri_accum dw ? ;DDA accum for priority watch
vol_update db ? ;0 | U_KSLTL
rover_2op dw ? ;circular voice # counters
rover_4op dw ?
conn_shadow db ? ;OPL3 Connection Select copy
BNK STRUC ;.BNK-style timbre definition
B_length dw ?
B_transpose db ?
B_mod_AVEKM db ? ;op_0 = FM modulator
B_mod_KSLTL db ?
B_mod_AD db ?
B_mod_SR db ?
B_mod_WS db ?
B_fb_c db ?
B_car_AVEKM db ? ;op_1 = FM carrier
B_car_KSLTL db ?
B_car_AD db ?
B_car_SR db ?
B_car_WS db ?
ENDS
OPL3BNK STRUC ;.BNK-style OPL3 timbre definition
BNK <>
O_mod_AVEKM db ? ;op_2
O_mod_KSLTL db ?
O_mod_AD db ?
O_mod_SR db ?
O_mod_WS db ?
O_fb_c db ?
O_car_AVEKM db ? ;op_3
O_car_KSLTL db ?
O_car_AD db ?
O_car_SR db ?
O_car_WS db ?
ENDS
S_timbre_off dw NUM_SLOTS dup (?) ;pointer to timbre in local cache
S_timbre_seg dw NUM_SLOTS dup (?) ;""
S_duration dw NUM_SLOTS dup (?) ;# of TV intervals left in keyon
S_status db NUM_SLOTS dup (?) ;2=key off, 1=key on, 0=slot free
S_type db NUM_SLOTS dup (?) ;0=BNK, 1=TV inst, 2=TV effect, 3=OPL3
S_voice db NUM_SLOTS dup (?) ;YM3812 voice 0-8 or -1 assigned to slot
S_channel db NUM_SLOTS dup (?) ;MIDI channel owning slot
S_note db NUM_SLOTS dup (?) ;MIDI note # for slot's voice
S_keynum db NUM_SLOTS dup (?) ;MIDI key # before RBS translation
S_transpose db NUM_SLOTS dup (?) ;MIDI note transposition for slot
S_velocity db NUM_SLOTS dup (?) ;keyon velocity for note
S_sustain db NUM_SLOTS dup (?) ;note sustained if nonzero
S_update db NUM_SLOTS dup (?) ;bit mask for YM3812 register updates
S_KBF_shadow db NUM_SLOTS dup (?) ;shadowed KON-BLOCK-FNUM(H) registers
S_BLOCK db NUM_SLOTS dup (?) ;KON/BLOCK values
S_FBC db NUM_SLOTS dup (?) ;YM3812 multi-purpose registers
S_KSLTL_0 db NUM_SLOTS dup (?)
S_KSLTL_1 db NUM_SLOTS dup (?)
S_AVEKM_0 db NUM_SLOTS dup (?)
S_AVEKM_1 db NUM_SLOTS dup (?)
S_AD_0 db NUM_SLOTS dup (?) ;YM3812 envelope registers
S_AD_1 db NUM_SLOTS dup (?)
S_SR_0 db NUM_SLOTS dup (?)
S_SR_1 db NUM_SLOTS dup (?)
S_scale_01 db NUM_SLOTS dup (?) ;level scaling flags for ops 0-1
IF NOT OSI_ALE
S_ws_val dw NUM_SLOTS dup (?) ;YM3812 registers
S_m1_val dw NUM_SLOTS dup (?) ;(declared in ALE.INC if TVFX enabled)
S_m0_val dw NUM_SLOTS dup (?)
S_fb_val dw NUM_SLOTS dup (?)
S_p_val dw NUM_SLOTS dup (?)
S_v1_val dw NUM_SLOTS dup (?)
S_v0_val dw NUM_SLOTS dup (?)
S_f_val dw NUM_SLOTS dup (?)
ENDIF
IFDEF YMF262
S_KSLTL_2 db NUM_SLOTS dup (?) ;YMF262 registers for operators 3-4
S_KSLTL_3 db NUM_SLOTS dup (?)
S_AVEKM_2 db NUM_SLOTS dup (?)
S_AVEKM_3 db NUM_SLOTS dup (?)
S_AD_2 db NUM_SLOTS dup (?)
S_AD_3 db NUM_SLOTS dup (?)
S_SR_2 db NUM_SLOTS dup (?)
S_SR_3 db NUM_SLOTS dup (?)
S_ws_val_2 dw NUM_SLOTS dup (?)
S_m3_val dw NUM_SLOTS dup (?)
S_m2_val dw NUM_SLOTS dup (?)
S_v3_val dw NUM_SLOTS dup (?)
S_v2_val dw NUM_SLOTS dup (?)
S_scale_23 db NUM_SLOTS dup (?) ;level scaling flags for ops 2-3
ENDIF
FREE equ 0 ;S_status[] phase equates
KEYON equ 1
KEYOFF equ 2
BNK_INST equ 0 ;S_type[] equates
TV_INST equ 1
TV_EFFECT equ 2
OPL3_INST equ 3
U_ALL_REGS equ 11111001b ;Bit mask equates for S_update
U_AVEKM equ 10000000b
U_KSLTL equ 01000000b
U_ADSR equ 00100000b
U_WS equ 00010000b
U_FBC equ 00001000b
U_FREQ equ 00000001b
MIDI_vol db NUM_CHANS dup (?) ;volume
MIDI_pan db NUM_CHANS dup (?) ;panpot
MIDI_pitch_l db NUM_CHANS dup (?) ;pitchwheel LSB
MIDI_pitch_h db NUM_CHANS dup (?) ;pitchwheel MSB
MIDI_express db NUM_CHANS dup (?) ;expression
MIDI_mod db NUM_CHANS dup (?) ;modulation
MIDI_sus db NUM_CHANS dup (?) ;HOLD1 pedal
MIDI_vprot db NUM_CHANS dup (?) ;voice protection
MIDI_timbre db NUM_CHANS dup (?) ;timbre cache index for each channel
MIDI_bank db NUM_CHANS dup (?) ;Patch Bank Select values
MIDI_program db NUM_CHANS dup (?) ;program change # / channel
RBS_timbres db 128 dup (?) ;RBS timbre offset cache
MIDI_voices db NUM_CHANS dup (?) ;# of voices assigned to channel
V_channel db NUM_VOICES dup (?) ;voice assigned to MIDI channel n or -1
S_V_priority dw NUM_SLOTS dup (?) ;adjusted voice priorities
;****************************************************************************
;* *
;* I/O routines *
;* *
;****************************************************************************
set_IO_parms PROC IO_ADDR ;Set I/O address parms for adapter
USES ds,si,di
IFDEF PAS
mov LFMADDR,388h
mov LFMDATA,389h
mov RFMADDR,38ah
mov RFMDATA,38bh
mov ax,LFMADDR
ELSEIFDEF PASOPL
mov ax,388h
ELSE
mov ax,[IO_ADDR]
ENDIF
IFDEF SBSTD
add ax,8
ELSEIFDEF SBPRO1
mov LFMADDR,ax
inc ax
mov LFMDATA,ax
inc ax
mov RFMADDR,ax
inc ax
mov RFMDATA,ax
inc ax
mov MIXADDR,ax
inc ax
mov MIXDATA,ax
add ax,3
ELSEIFDEF SBPRO2
push ax
add ax,4
mov MIXADDR,ax
inc ax
mov MIXDATA,ax
pop ax
ENDIF
mov ADDR_STAT,ax
inc ax
mov DATA_OUT,ax
ret
ENDP
;****************************************************************************
;
;YM3812/YMF262 register access routines must preserve DS, SI, DI!
;
write_register PROC Operator:BYTE,Base:BYTE,Value:BYTE
mov bl,[Operator]
mov bh,0
mov ah,op_array[bx]
mov bl,op_index[bx]
add bl,[Base]
mov bh,ah
mov cl,[Value]
jmp do_update
ENDP
send_byte PROC Voice:WORD,Base:BYTE,Data:BYTE
mov bx,[Voice]
mov ah,voice_array[bx]
mov bl,voice_num[bx]
add bl,[Base]
mov bh,ah
mov cl,[Data]
jmp do_update
ENDP
do_update: pop bp ;discard stack frame
update_reg PROC ;Write value CL to register BX
;(preserves BX)
IFDEF STEREO_3812
mov al,bl ;AL=address, CL=data
mov dx,LFMADDR ;select left register address
out dx,al
mov dx,RFMADDR ;select right register address
out dx,al
mov dx,LFMADDR ;delay 3.3 uS
mov ah,6
__rept_1: in al,dx
dec ah
jne __rept_1
mov al,cl
mov dx,LFMDATA ;write left data
out dx,al
mov dx,RFMDATA ;write right data (same as left)
out dx,al
mov dx,LFMADDR ;delay 23 uS (3.3 for YMF262)
mov ah,IOWVAL
__rept_2: in al,dx
dec ah
jne __rept_2
ELSE
mov dx,ADDR_STAT
IFDEF YMF262 ;index 2nd array if addr > 256
add dl,bh
adc dh,0
add dl,bh
adc dh,0
ENDIF
mov al,bl ;AL=address, CL=data
out dx,al ;select register address
mov ah,6
__rept_3: in al,dx
dec ah
jne __rept_3
mov al,cl
inc dx
out dx,al
dec dx
mov ah,IOWVAL
__rept_4: in al,dx
dec ah
jne __rept_4
ENDIF
ret
ENDP
IFDEF STEREO_3812 ;Access 3812 stereo registers
stereo_register PROC Part:BYTE,Base:BYTE,RLValues:WORD
mov bl,[Part]
mov bh,0
mov al,[Base]
add al,op_index[bx]
mov dx,LFMADDR ;select left register address
out dx,al
mov dx,RFMADDR ;select right register address
out dx,al
mov dx,LFMADDR ;delay 3.3 uS
mov ah,6
__rept_1: in al,dx
dec ah
jne __rept_1
mov dx,LFMDATA ;write left data
mov al,BYTE PTR [RLValues+1]
out dx,al
mov dx,RFMDATA ;write right data
mov al,BYTE PTR [RLValues]
out dx,al
mov dx,LFMADDR ;delay 23 uS
mov ah,42
__rept_2: in al,dx
dec ah
jne __rept_2
ret
ENDP
ENDIF
read_status PROC ;Read YM3812 status register
mov dx,ADDR_STAT
in al,dx
mov ah,0
ret
ENDP
;****************************************************************************
IFDEF ADLIBG
IO_wait PROC ;Wait for clear SB bit (Ad Lib Gold)
mov cx,500
mov dx,CTRL_ADDR
__wait: in al,dx
and al,01000000b
loopnz __wait
ret
ENDP
get_FM_vol PROC RegNum ;Get FM VOLUME register value
call IO_wait
mov dx,CTRL_ADDR
mov ax,[RegNum]
out dx,al
call IO_wait
mov dx,CTRL_DATA
in al,dx
ret
ENDP
set_FM_vol PROC RegNum,Val ;Set FM VOLUME register value
call IO_wait
mov dx,CTRL_ADDR
mov ax,[RegNum]
out dx,al
call IO_wait
mov dx,CTRL_DATA
mov ax,[Val]
out dx,al
ret
ENDP
ENDIF
detect_device PROC H,IO_ADDR,IRQ,DMA,DRQ
USES ds,si,di ;Attempt to detect card
pushf
cli
IFDEF ADLIBG ;if Ad Lib Gold, look for control
;chip
mov dx,IO_ADDR
add dx,2
mov CTRL_ADDR,dx
inc dx
mov CTRL_DATA,dx
mov dx,CTRL_ADDR ;attempt to enable control chip
mov al,0ffh
out dx,al
call get_FM_vol C,9 ;get left volume
mov si,ax
call get_FM_vol C,10 ;get right volume
mov di,ax
xor si,0101b ;tweak a few bits
xor di,1010b
call set_FM_vol C,9,si ;write the tweaked values back
call set_FM_vol C,10,di
call get_FM_vol C,9 ;see if changes took effect
cmp ax,si
mov ax,0 ;(return failure)
jne __return
call get_FM_vol C,10
cmp ax,di
mov ax,0 ;(return failure)
jne __return
xor si,0101b ;control chip found: restore old
xor di,1010b ;values & re-enable FM sound
call set_FM_vol C,9,si
call set_FM_vol C,10,di
call IO_wait
mov dx,CTRL_ADDR
mov al,0feh
out dx,al
mov ax,1 ;return success
jmp __return
ELSE ;(not Ad Lib Gold card...)
push DATA_OUT ;preserve current I/O addresses
push ADDR_STAT
IFDEF STEREO_3812
push LFMADDR
push RFMADDR
push LFMDATA
push RFMDATA
ENDIF
IFDEF SBPRO
push MIXDATA
push MIXADDR
ENDIF
call set_IO_parms C,[IO_ADDR]
IFDEF SBPRO2 ;do Ad Lib detection at 2x8, NOT 2x0
add DATA_OUT,8 ;(avoids hangups on standard SB)
add ADDR_STAT,8
ENDIF
call detect_Adlib ;do Ad Lib compatibility test first
cmp ax,0
je __exit
IFDEF SBPRO ;then look for CT-1345A mixer chip
mov dx,MIXADDR
mov al,0ah ;select Mic Vol control
out dx,ax
jmp $+2
mov dx,MIXDATA
in al,dx ;get original value
jmp $+2
mov ah,al ;save it
xor al,110b ;toggle its bits
out dx,al ;write it back
jmp $+2
in al,dx ;read/verify changed value
xor al,110b
cmp al,ah
mov al,ah ;put the old value back
out dx,al
mov ax,0
jne __exit
mov ax,1 ;signal card found -- it's a SB PRO
ENDIF
IFDEF PROAUDIO ;if Pro Audio Spectrum, look for
mov ax,0bc00h ;MVSOUND.SYS device driver
mov bx,03f3fh
int 2fh ;DOS MPX interrupt
xor bx,cx
xor bx,dx
cmp bx,'MV' ;MediaVision flag
mov ax,0
jne __exit
mov cx,0
mov ax,0bc03h ;get function table address
int 2fh
cmp ax,'MV'
mov ax,0
jne __exit
cmp cx,10 ;bail out if no FM Split routine
jb __exit ;present (MVSOUND version < 1.02)
mov es,dx
mov di,bx
mov bx,100
mov cx,1
call DWORD PTR es:[di+36] ;set FM Split = stereo mode
mov ax,1 ;signal PAS card found
ENDIF
__exit: IFDEF SBPRO
pop MIXADDR
pop MIXDATA
ENDIF
IFDEF STEREO_3812
pop RFMDATA
pop LFMDATA
pop RFMADDR
pop LFMADDR
ENDIF
pop ADDR_STAT
pop DATA_OUT
ENDIF ;IFDEF ADLIBG
__return: POP_F ;return AX=0 if not found
ret
ENDP
IFNDEF ADLIBG
detect_send PROC Addr:BYTE,Data:BYTE ;Write data byte to specified AL reg
mov dx,ADDR_STAT
mov al,[Addr]
out dx,al ;select register address
mov cx,6
__3_3_us: in al,dx ;delay 3.3 uS
loop __3_3_us
mov dx,DATA_OUT
mov al,[Data]
out dx,al
mov dx,ADDR_STAT
mov cx,42
__23_us: in al,dx ;delay 23 uS
loop __23_us
ret
ENDP
detect_Adlib PROC ;Detect standard YM3812 timer regs
USES ds,si,di
call detect_send C,4,60h ;reset T1 and T2
call detect_send C,4,80h ;reset IRQ
call read_status
mov di,ax ;save timer status
call detect_send C,2,0ffh ;set T1 to 0FFh
call detect_send C,4,21h ;unmask and start T1
mov si,200 ;wait 100 uS for timer to count down
__wait_100_uS: call read_status
dec si
jnz __wait_100_uS
mov si,ax ;save timer status
call detect_send C,4,60h ;reset T1 and T2
call detect_send C,4,80h ;reset IRQ
and si,0e0h ;mask off undefined bits
and di,0e0h
mov ax,0 ;assume board not detected
cmp di,0
jne __return ;initial timer value not 0, exit
cmp si,0c0h
jne __return ;timer didn't overflow, exit
mov ax,1 ;else Ad Lib-compatible board exists
__return: ret
ENDP
ENDIF
;****************************************************************************
reset_synth PROC ;Init regs & register map
USES ds,si,di
pushf
cli
IFDEF YMF262
mov bx,105h
mov cl,00000001b ;set OPL3 NEW bit
call update_reg
mov bx,104h ;init OPL3 to 18 2-op voices
mov cl,0
call update_reg
mov conn_shadow,0
ENDIF
mov bx,1h
__init_0: mov cl,array0_init-1[bx]
call update_reg
inc bx
cmp bx,0f5h
jbe __init_0
IFDEF YMF262
mov bx,101h
__init_1: mov cl,array1_init-101h[bx]
call update_reg
inc bx
cmp bx,1f5h
jbe __init_1
ENDIF
POP_F
ret
ENDP
;****************************************************************************
shutdown_synth PROC ;Establish Ad Lib compatibility mode
USES ds,si,di
pushf
cli
IFDEF YMF262
mov bx,105h
mov cl,0 ;clear OPL3 NEW bit
call update_reg
ENDIF
IFDEF PAS ;reset 3812-based card to Ad Lib
mov ax,0bc07h ;function 7: get state table entries
int 2fh
or bl,10000000b ;clear FM split (bit 7)
mov al,bl ;...and write to mixer port
mov dx,0b88h
out dx,al
ENDIF
POP_F
ret
ENDP
;****************************************************************************
;* *
;* Timbre cache management / related API calls *
;* *
;****************************************************************************
index_timbre PROC GNum ;Get global timbre's local index
USES ds,si,di
mov si,0
mov ax,[GNum]
__find_gnum: test timb_attribs[si],10000000b
jz __find_next ;(timbre unused)
cmp timb_bank[si],ah
jne __find_next
cmp timb_num[si],al
je __found
__find_next: inc si
cmp si,MAX_TIMBS
jb __find_gnum
mov si,-1 ;return -1 if timbre not loaded
__found: mov ax,si
ret
ENDP
;****************************************************************************
protect_timbre PROC H,Bank:BYTE,Num:BYTE
USES ds,si,di ;Protect a timbre from replacement
pushf
cli
mov al,[Num]
mov ah,[Bank]
cmp ax,-1
je __prot_all
call index_timbre C,ax
cmp ax,-1
je __exit ;timbre not loaded, can't protect it
mov bx,ax
or timb_attribs[bx],01000000b
jmp __exit
__prot_all: mov bx,0
__prot_timb: or timb_attribs[bx],01000000b
inc bx
cmp bx,MAX_TIMBS
jb __prot_timb
__exit: POP_F
ret
ENDP
;****************************************************************************
unprotect_timbre PROC H,Bank:BYTE,Num:BYTE
USES ds,si,di ;Allow a timbre to be replaced
pushf
cli
mov al,[Num]
mov ah,[Bank]