forked from Tronix286/AIL2
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCAKEPORT.ASM
1642 lines (1331 loc) · 49 KB
/
CAKEPORT.ASM
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
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
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ CAKEPORT.ASM ÛÛ
;ÛÛ ÛÛ
;ÛÛ IBM Audio Interface Library ÛÛ
;ÛÛ ÛÛ
;ÛÛ Audio Interface Library driver for Cakewalk Professional version 4.0 ÛÛ
;ÛÛ ÛÛ
;ÛÛ Version 1.0 of 08-Aug-91: Initial version ÛÛ
;ÛÛ 2.0 of 02-Sep-91: MPU-401 MIDI receive capability added ÛÛ
;ÛÛ MIDI.DRV support removed ÛÛ
;ÛÛ Dialog box support added ÛÛ
;ÛÛ Timer subclass code added ÛÛ
;ÛÛ 2.01 of 10-Dec-91: Timer subclass code fixed for .WRK loading ÛÛ
;ÛÛ 2.02 of 20-Apr-92: serve_driver() enabled for all drivers ÛÛ
;ÛÛ 2.03 of 17-Aug-92: Driver-specific volume scaling added ÛÛ
;ÛÛ ÛÛ
;ÛÛ Author: John Miles ÛÛ
;ÛÛ 8086 ASM source compatible with Turbo Assembler v2.0 or later ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
;ÛÛ ÛÛ
;ÛÛ 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 ÛÛ
;ÛÛ ÛÛ
;ÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛÛ
MODEL MEDIUM,C ;Procedures far, data near by default
LOCALS __ ;Enable local labels with __ prefix
JUMPS ;Auto jump sizing
INCLUDE ail.inc
INCLUDE ail.mac
ADDRESS_CRTC MACRO ;Get DX=CRTC address at 3B0h (mono)
push ax ;or 3D0h (color) -- preserves all regs
mov dx,03cch
in al,dx
and al,1
shl al,1
shl al,1
shl al,1
shl al,1
shl al,1
mov dx,03b0h
add dl,al
pop ax
ENDM
.CODE
db 'IPD',10h,00h,82h,00h,00h
jmp startup ;Cakewalk function 0
jmp shutdown ;1
jmp clear_to_send ;2
jmp send_bytes ;3
jmp data_in_queue ;4
jmp read_queue ;5
jmp get_device_data ;6
devname db 'Audio Interface Library CAKEPORT Driver v2.0',0
db ' MPU-401: "1" to enable, "2" to disable',0
MIDI_active dw 1h
db ' Base port address (hex)',0
def_IO dw 330h
db ' IRQ number',0
def_IRQ dw 2h
db 'AIL driver: "1" to enable, "2" to disable',0
AIL_active dw 1h
AIL_IO_text db ' Base port address (hex)',0
def_AIL_IO dw 388h
AIL_IRQ_text db ' IRQ number',0
def_AIL_IRQ dw 7
db 0
intro_box LABEL BYTE
db ' IBM Audio Interface Library '
db '@@'
db ' Cakewalk(TM) Extended MIDI Driver '
db '@@'
db ' Version 2.03 of '
db ??date
db ' '
db '@@@'
db ' Copyright (C) 1991, 1992 Miles Design, Inc. '
db 0
ERR_no_ADV LABEL BYTE
db ' AIL ERROR: XMIDI.ADV driver not found @'
db '@'
db ' To use an Audio Interface Library XMIDI driver from @'
db ' within Cakewalk, you must save the desired .ADV @'
db ' driver file in your Cakewalk driver directory under @'
db ' the special filename XMIDI.ADV. For example, to @'
db ' use the AIL Ad Lib driver with Cakewalk, you should @'
db ' issue a DOS command similar to the following: @'
db '@'
db ' C:\>copy \ail\adlib.adv \cakewalk\xmidi.adv '
db '@'
db 0
ERR_bad_tr LABEL BYTE
db ' AIL WARNING: Patch ~0 not found in bank ~1 of @'
db ' Global Timbre Library file ~A @'
db '@'
db ' Make sure the correct XMIDI Patch Bank Select @'
db ' controller (~2) value appears before each MIDI @'
db ' Patch (Program Change) event. Also, verify that @'
db ' each custom timbre you',39,'re using is specified in @'
db ' the GLIB catfile, and that the ~A file in @'
db ' your Cakewalk driver directory is up to date. '
db 0
ERR_bad_rk LABEL BYTE
db ' AIL WARNING: Patch for rhythm key #~0 not found in @'
db ' bank ~1 of Global Timbre Library file @'
db ' ~A @'
db '@'
db ' The AIL driver currently in use emulates the Roland @'
db ' MT-32 rhythm keys on MIDI channel 10 by playing the @'
db ' timbres in bank 127 of the Global Timbre Library. @'
db ' To hear MIDI key ~0 play a rhythm sound, you must @'
db ' specify a timbre of the form timbre(127,~0) = ... @'
db ' in the selected synthesizer',39,'s GLIB catfile. '
db 0
ERR_no_dev LABEL BYTE
db ' AIL ERROR: Sound hardware not found @'
db '@'
db ' The Audio Interface Library driver could not @'
db ' locate your sound adapter or synthesizer interface. @'
db ' You must restart CAKEPRO with the /S option and @'
db ' choose menu option 3 (MIDI Interface Setup) to @'
db ' specify the I/O location at which the driver @'
db ' should address your hardware. '
db 0
ERR_no_GTL LABEL BYTE
db ' AIL WARNING: Patch ~0, bank ~1 requested but no @'
db ' Global Timbre Library file available @'
db '@'
db ' You should use the GLIB (Global LIBrarian) program @'
db ' to create a Global Timbre Library file which contains @'
db ' this timbre. The Global Timbre Library file for this @'
db ' synthesizer should be saved in the Cakewalk directory @'
db ' under the special filename ~A. '
db 0
ERR_GTL_size LABEL BYTE
db ' AIL WARNING: Patch ~0, bank ~1 not resident in first @'
db ' 32K bytes of Global Timbre Library file @'
db ' ~A @'
db '@'
db ' Only the first 32,768 bytes of a Global Timbre Library @'
db ' file may be loaded by the Cakewalk driver. You will @'
db ' need to use the MIDIECHO program instead if this error @'
db ' occurs. '
db 0
dummy_XMI LABEL BYTE
db 046h,04Fh,052h,04Dh,000h,000h,000h,00Eh,058h,044h,049h
db 052h,049h,04Eh,046h,04Fh
db 000h,000h,000h,002h,001h,000h,043h,041h,054h,020h,000h
db 000h,000h,02Eh,058h,04Dh
db 049h,044h,046h,04Fh,052h,04Dh,000h,000h,000h,022h,058h
db 04Dh,049h,044h,045h,056h
db 04Eh,054h,000h,000h,000h,016h,0FFh,059h,002h,000h,000h
db 0FFh,051h,003h,009h,027h
db 0C0h,0FFh,058h,004h,004h,002h,018h,008h,0FFh,02Fh,000h
db 000h
AIL_fn db 'XMIDI.ADV',0 ;AIL driver for output
GTL_fn db 'XMIDI.' ;AIL Global Timbre Library filename
GTL_suffix_l dw ?
GTL_suffix_h dw ?
GTL_seg dw ?
AIL_vectors dd ?
desc_addr dd ?
drvr_desc STRUC
min_API_version dw ?
drvr_type dw ?
data_suffix db 4 dup (?)
dev_names dd ?
dev_IO dw ?
dev_IRQ dw ?
dev_DMA dw ?
dev_DRQ dw ?
svc_rate dw ?
dsp_size dw ?
ENDS
t_index STRUC
num db ?
bank db ?
ENDS
GTL_hdr STRUC
tag t_index <>
offset_l dw ?
offset_h dw ?
ENDS
AIL_IO dw ?
AIL_IRQ dw ?
AIL_DMA dw ?
AIL_DRQ dw ?
cv_status dw ?
cv_bytecnt dw ?
cv_data db 8 dup (?) ;Channel Voice data stream
timbre_bank db 16 dup (?)
timbre_num db 16 dup (?)
init_prg db -1,68,48,95,78,41,3,110,122,-1,-1,-1,-1,-1,-1,-1
RBS db 0,0,0,0,0,0,0,0,0,127,0,0,0,0,0,0
default_ISR_o dw -1
default_ISR_s dw -1
orig_PIC dw -1
head dw 0
tail dw 0
queue db 256 dup (?) ;incoming message queue
app_ds dw ?
app_sp dw ?
callback LABEL DWORD
callback_o dw ?
callback_s dw ?
IRQ_busy dw ?
old_ss dw ?
old_sp dw ?
AIL_rate dw ? ;AIL driver service rate*10 (120 Hz)
CW_RATE EQU 2913 ;Cakewalk default timer rate (291 Hz)
Cake_INT8 dd ?
timer_trapped dw ?
timer_busy dw ?
timer_accum dw ?
CRTC_port dw ?
dialog_page dw ?
page_size dw ?
page_lines dw ?
page_cols dw ?
text_seg dw ?
text_width db 50 dup (?)
mouse_active dw ?
driver_vol dw ?
accums dw 10 dup (?)
strbuf db 80 dup (?)
;*****************************************************************************
AIL_base db 20480 dup (?) ;reserve 20K for AIL driver
AIL_timbs db 4096 dup (?) ;reserve 4K for AIL timbre cache
GTL_base db 32768 dup (?) ;reserve 32K for Global Timbre Library
;*****************************************************************************
;*****************************************************************************
init_dialog PROC ;Init text dialog box routines
USES ds,si,di
mov dialog_page,1
ADDRESS_CRTC
mov CRTC_port,dx
mov ax,0b800h
cmp dx,03d0h
je __set_scrn_seg
mov ax,0b000h
__set_scrn_seg: mov text_seg,ax
mov ax,40h
mov es,ax
mov bx,es:[4ah] ;get # of text cols
mov page_cols,bx
mov al,es:[84h] ;get # of text rows
mov ah,0
inc ax
mov page_lines,ax
shl bx,1
mul bx
mov page_size,ax
mov ax,24h
mov bx,-1
int 33h
mov ax,0
cmp bh,-1
je __set_mouse
mov ax,1
__set_mouse: mov mouse_active,ax
ret
ENDP
;*****************************************************************************
copy_page PROC Src,Dest ;src|dest=0 for main page, else page #
USES ds,si,di
cld
mov dx,CRTC_port ;wait for vsync leading to
add dx,10 ;avoid flicker
__vsync: in al,dx
test al,8
jnz __vsync
__not_vsync: in al,dx
test al,8
jz __not_vsync
mov ds,text_seg
mov es,text_seg
mov ax,page_size
mul [Src]
mov si,ax
mov ax,page_size
mul [Dest]
mov di,ax
mov cx,page_size
rep movsw
ret
ENDP
;*****************************************************************************
bascalc PROC HTab,VTab,Page
USES ds,si,di
mov ax,page_cols
shl ax,1
mul [VTab]
mov bx,[HTab]
shl bx,1
add bx,ax
mov ax,page_size
mul [Page]
add bx,ax
mov ax,bx
mov dx,text_seg
ret ;AX=offset DX=segment
ENDP
;*****************************************************************************
dialog_escape PROC EscCode:BYTE ;Dialog escape string to buffer
USES ds,si,di
mov al,[EscCode]
cmp al,'A' ;'A': XMIDI GTL filename
je __GTL_fn
sub al,'0' ;'0' - '9': Numeric accumulator
mov ah,0
mov di,ax
shl di,1
call decstr C,OFFSET strbuf,cs,accums[di]
jmp __exit
__GTL_fn: push cs
pop ds
lea si,GTL_fn
jmp __fetch_str
__fetch_str: lea di,strbuf
push cs
pop es
__strcpy: lodsb
stosb
cmp al,0
jne __strcpy
__exit: ret
ENDP
;*****************************************************************************
decstr PROC Buf:FAR PTR,Num ;decimal ASCII to string buffer
LOCAL accum,lzero
USES ds,si,di
cld
les di,[Buf]
mov ax,[Num]
mov accum,ax
mov lzero,0
mov cx,10000
__div_loop: mov ax,accum
mov dx,0
div cx
mov accum,dx
add al,'0'
cmp al,'0'
jne __write_digit
cmp lzero,0
je __next_digit
__write_digit: mov lzero,1
stosb
__next_digit: mov ax,cx
mov dx,0
mov bx,10
div bx
mov cx,ax
cmp ax,0
jne __div_loop
cmp lzero,0
jne __end_string
mov al,'0'
stosb
__end_string: mov BYTE PTR es:[di],0
ret
ENDP
;*****************************************************************************
hide_mouse PROC ;hide mouse if mouse in use
USES ds,si,di
cmp mouse_active,0
je __exit
mov ax,2
int 33h
__exit: ret
ENDP
;*****************************************************************************
show_mouse PROC ;show mouse if mouse in use
USES ds,si,di
cmp mouse_active,0
je __exit
mov ax,1
int 33h
__exit: ret
ENDP
;*****************************************************************************
open_dialog PROC TextStr,BColor:BYTE,FColor:BYTE,CJustify
LOCAL width,height,text_top,text_left
LOCAL box_top,box_left,box_right,box_bottom
USES ds,si,di
cld
call hide_mouse
call copy_page C,0,dialog_page
push cs
pop ds
mov si,[TextStr]
mov width,0
mov bx,0
__scan_line: mov cx,0
__scan_txt: lodsb
mov text_width[bx],cl
cmp al,0
je __end_txt
cmp al,'@'
je __end_line
cmp al,'~'
je __escape
inc cx
__bump_width: cmp cx,width
jb __scan_txt
mov width,cx
jmp __scan_txt
__end_line: inc bx
jmp __scan_line
__escape: lodsb
push cx
push bx
call dialog_escape C,ax
pop bx
pop cx
mov di,-1
__find_strlen: inc di
cmp strbuf[di],0
jne __find_strlen
add cx,di
jmp __bump_width
__end_txt: inc bx
mov height,bx
mov ax,page_lines
sub ax,height
shr ax,1
mov text_top,ax
sub ax,1
mov box_top,ax
add ax,height
add ax,1
mov box_bottom,ax
mov ax,page_cols
sub ax,width
shr ax,1
mov text_left,ax
sub ax,1
mov box_left,ax
add ax,width
add ax,1
mov box_right,ax
mov si,box_left
mov di,box_top
__draw_box: call bascalc C,si,di,0
mov es,dx
mov bx,ax
cmp di,box_top
je __top_char
cmp di,box_bottom
je __btm_char
cmp si,box_left
je __side_char
cmp si,box_right
je __side_char
mov al,' '
jmp __put_char
__side_char: mov al,'º'
jmp __put_char
__top_char: mov al,'É'
cmp si,box_left
je __put_char
mov al,'»'
cmp si,box_right
je __put_char
mov al,'Í'
jmp __put_char
__btm_char: mov al,'È'
cmp si,box_left
je __put_char
mov al,'¼'
cmp si,box_right
je __put_char
mov al,'Í'
__put_char: mov es:[bx],al
mov al,[BColor]
shl al,1
shl al,1
shl al,1
shl al,1
or al,[FColor]
mov es:[bx+1],al
inc si
cmp si,box_right
jbe __draw_box
mov si,box_left
inc di
cmp di,box_bottom
jbe __draw_box
mov di,0
mov si,[TextStr]
__for_line: call bascalc C,text_left,text_top,0
mov bx,ax
mov es,dx
cmp [CJustify],0
je __for_char
mov bx,width
sub bl,text_width[di]
and bx,11111110b
add bx,ax
__for_char: lodsb
cmp al,0
je __text_done
cmp al,'@'
je __newline
cmp al,'~'
je __prt_escape
mov es:[bx],al
add bx,2
jmp __for_char
__newline: inc di
inc text_top
jmp __for_line
__prt_escape: lodsb
push di
push si
push bx
push es
call dialog_escape C,ax
pop es
pop bx
mov si,-1
__dump_str: inc si
mov al,strbuf[si]
cmp al,0
je __end_esc
mov es:[bx],al
add bx,2
jmp __dump_str
__end_esc: pop si
pop di
jmp __for_char
__text_done: call show_mouse
inc dialog_page
ret
ENDP
;*****************************************************************************
close_dialog PROC
USES ds,si,di
dec dialog_page
call hide_mouse
call copy_page C,dialog_page,0
call show_mouse
ret
ENDP
;*****************************************************************************
dialog_prompt PROC Timeout
LOCAL ticks,curval
USES ds,si,di
mov ticks,0
mov curval,0
__wait: cmp [Timeout],-1
je __chk_kbd
mov ax,40h
mov es,ax
mov ax,es:[6ch]
cmp ax,curval
je __chk_kbd
mov curval,ax
inc ticks ;tick cnt +/- 1
mov ax,ticks
cmp ax,[Timeout]
je __exit
__chk_kbd: mov ax,1100h ;key struck?
int 16h
jz __chk_mouse
mov ax,0h ;yes, clear keystroke and return
int 16h
jmp __exit
__chk_mouse: cmp mouse_active,0
je __wait
mov ax,3 ;mouse clicked?
int 33h
and bx,111b
jz __wait
push bx ;yes, wait for release and return
__clear_mouse: mov ax,3
int 33h
and bx,111b
jnz __clear_mouse
pop ax
__exit: ret ;return AX=ASC key, mouse code (0-7),
ENDP ;or # of ticks in [Timeout]
;*****************************************************************************
send_cmd PROC CmdByte
pushf
cli
mov dx,def_IO
inc dx
mov cx,-1
__wait_cts_1: in al,dx
test al,40h
jz __cts_1
loop __wait_cts_1
jmp __exit_bad
__cts_1: mov ax,[CmdByte]
out dx,al
mov cx,-1
__wait_ack: in al,dx
test al,80h
jnz __next_loop
dec dx
in al,dx
inc dx
cmp al,0feh
je __exit_OK
__next_loop: loop __wait_ack
__exit_bad: mov ax,0
jmp __exit
__exit_OK: mov ax,1
__exit: POP_F
ret
ENDP
;*****************************************************************************
report_error PROC ErrTxt
USES ds,si,di
call open_dialog C,[ErrTxt],4,15,0
call dialog_prompt C,-1
call close_dialog
ret
ENDP
;*****************************************************************************
load_file PROC Filename:FAR PTR,Addr,MaxLen
LOCAL file_seg
USES ds,si,di ;Addr: offset of file space in CS
mov ax,cs
mov dx,0
REPT 4
shl ax,1
rcl dx,1
ENDM
add ax,[Addr]
adc dx,0
REPT 4
shr dx,1
rcr ax,1
ENDM
inc ax
mov file_seg,ax
lds dx,[Filename]
mov ax,3d00h
int 21h
jc __error
push ax
mov bx,ax
mov ah,3fh
mov cx,[MaxLen]
mov dx,0
mov ds,file_seg
int 21h
pop bx
mov ah,3eh
int 21h
mov ax,file_seg
ret ;return segment address of file
__error: mov ax,0
ret
ENDP
;*****************************************************************************
find_proc PROC ;Return DX:AX -> function AX
les bx,AIL_vectors ;ES:BX -> driver procedure table
__find_proc: mov cx,es:[bx] ;search for requested function in
cmp cx,ax ;driver procedure table
je __found
add bx,4
cmp cx,-1
jne __find_proc
mov ax,0 ;return 0: function not available
mov dx,0
ret
__found: mov ax,es:[bx+2] ;get offset from start of driver
mov dx,es ;get segment of driver (org = 0)
ret
ENDP
;*****************************************************************************
AIL PROC ;Call function AX in AIL driver
;(Warning: re-entrant procedure!)
call find_proc
cmp ax,0
jne __do_call
cmp dx,0
je __invalid_call
__do_call: push dx ;call driver function via stack
push ax
retf
__invalid_call: ret ;return DX:AX = 0 if call failed
ENDP
;*****************************************************************************
AIL_describe_driver PROC
mov ax,AIL_DESC_DRVR
jmp AIL
ENDP
;*****************************************************************************
AIL_detect_device PROC
mov ax,AIL_DET_DEV
jmp AIL
ENDP
;*****************************************************************************
AIL_init_driver PROC
mov ax,AIL_INIT_DRVR
jmp AIL
ENDP
;*****************************************************************************
AIL_define_timbre_cache PROC
mov ax,AIL_DEFINE_T_CACHE
jmp AIL
ENDP
;*****************************************************************************
AIL_install_timbre PROC
mov ax,AIL_INSTALL_T
jmp AIL
ENDP
;*****************************************************************************
AIL_timbre_status PROC
mov ax,AIL_T_STATUS
jmp AIL
ENDP
;*****************************************************************************
AIL_shutdown_driver PROC
mov ax,AIL_SHUTDOWN_DRVR
jmp AIL
ENDP
;*****************************************************************************
AIL_send_channel_voice_message PROC
mov ax,AIL_SEND_CV_MSG
jmp AIL
ENDP
;*****************************************************************************
AIL_serve_driver PROC
mov ax,AIL_SERVE_DRVR
jmp AIL
ENDP
;*****************************************************************************
AIL_register_sequence PROC
mov ax,AIL_REG_SEQ
jmp AIL
ENDP
;*****************************************************************************
AIL_relative_volume PROC
mov ax,AIL_REL_VOL
jmp AIL
ENDP
;*****************************************************************************
AIL_release_sequence_handle PROC
mov ax,AIL_REL_SEQ_HND
jmp AIL
ENDP
;*****************************************************************************
AIL_INT8 PROC ;Perform serve_driver() calls to AIL
;driver for possible TVFX maintenance
cmp timer_busy,0
je __no_reentry
jmp __serve_Cake
__no_reentry: mov timer_busy,1 ;avoid re-entry or undesirable calls
cld
push ax
push bx
push cx
push dx
push si
push di
push bp
push es
push ds
mov ax,AIL_rate
add timer_accum,ax
cmp timer_accum,CW_RATE
jb __restore_regs
sub timer_accum,CW_RATE
call AIL_serve_driver
__restore_regs: pop ds
pop es
pop bp
pop di
pop si
pop dx
pop cx
pop bx
pop ax
mov timer_busy,0
__serve_Cake: pushf
call [Cake_INT8]
iret
ENDP
;*****************************************************************************
setup_timbre PROC Bank,Num
USES ds,si,di
call AIL_timbre_status C,0,[Bank],[Num]
cmp ax,0
jne __exit ;timbre already installed or not
;needed by synthesizer, exit
mov ax,[Num]
mov accums[0],ax
mov ax,[Bank]
mov accums[2],ax
mov accums[4],PATCH_BANK_SEL
cmp GTL_seg,0
jne __GTL_valid
call report_error C,OFFSET ERR_no_GTL
jmp __exit
__GTL_valid: mov ds,GTL_seg
mov si,0
mov bl,BYTE PTR [Num]
mov bh,BYTE PTR [Bank]
__chk_entry: mov al,[si].tag.num
mov ah,[si].tag.bank
cmp ah,-1
je __not_found ;end of GTL reached, timbre not found
cmp bx,ax
je __timbre_found ;bank and num match, timbre found
add si,SIZE GTL_hdr
jmp __chk_entry
__timbre_found: cmp [si].offset_h,0
jne __GTL_too_big ;timbre not in resident GTL image
mov si,[si].offset_l
mov ax,si ;DS:AX -> timbre