GMBLAST Assembler Code Documentation

From SCI Wiki
Jump to navigationJump to search

The GMBLAST.DRV is a third party General MIDI SCI1 driver that adds Sound Blaster digital sound effects. It was written by Michael C. Maggio. The following is his documentation on the assembler code of the driver

; offsets should be relative to CS:0000,
; but debug loads things at 0100 regardless,
; so all code addresses are 100 greater than they ought to be

/* Main */

0B43:0100 E9A705        JMP     06AA

-d 0100 06b5 
0B43:0100  E9 A7 05 00 21 43 65 87-01 04 64 75 64 65 25 47   ....!Ce...dude%G
0B43:0110  65 6E 65 72 61 6C 20 4D-49 44 49 20 66 6F 72 20   eneral MIDI for 
0B43:0120  52 6F 6C 61 6E 64 20 4D-50 55 20 69 6E 74 65 72   Roland MPU inter
0B43:0130  66 61 63 65 98 BA DC FE-00 02 00 00 76 31 2E 30   face........v1.0
0B43:0140  33 FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   3...............
0B43:0150  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:0160  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:0170  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:0180  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:0190  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:01A0  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:01B0  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:01C0  FF 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:01D0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:01E0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:01F0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0200  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0210  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0220  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0230  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0240  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0250  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0260  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0270  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0280  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0290  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:02A0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:02B0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:02C0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:02D0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:02E0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:02F0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0300  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0310  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0320  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0330  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0340  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0350  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0360  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0370  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0380  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0390  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:03A0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:03B0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:03C0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:03D0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:03E0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:03F0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0400  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0410  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0420  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0430  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0440  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0450  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0460  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0470  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0480  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0490  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:04A0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:04B0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:04C0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:04D0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:04E0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:04F0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0500  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0510  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0520  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0530  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0540  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0550  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0560  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0570  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0580  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0590  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:05A0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:05B0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:05C0  00 00 0F 01 FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:05D0  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:05E0  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:05F0  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:0600  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:0610  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:0620  FF FF FF FF FF FF FF FF-FF FF FF FF FF FF FF FF   ................
0B43:0630  FF FF FF FF 01 01 01 01-01 01 01 01 01 01 01 01   ................
0B43:0640  01 01 01 01 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0650  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0660  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0670  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
0B43:0680  00 00 00 00 00 00 08 0A-84 09 2C 08 B6 05 C9 05   ..........,.....
0B43:0690  17 06 B6 05 85 06 18 07-B6 05 DE 07 B7 05 96 08   ................
0B43:06A0  D2 08 B6 05 B6 05 B6 05-18 09 52 D1 E5 2E 8B 96   ..........R.....
0B43:06B0  86 05 FF D2 5A CB                                 ....Z.
-q 
; function address table at cs:0586

0A08 – get_device_info()
0984 – init_device()  (10b4)
082C – shutdown_device()
05B6 – do_nothing()
05C9 – note_off()
0617 – note_on()
05B6 – do_nothing()
0685
0718
05B6 – do_nothing()
07DE
05B7
0896
08D2
05B6 – do_nothing()  (0a5d)
05B6 – do_nothing()  (0b09)
05B6 – do_nothing()  (0b1f)
0918

driver() – 06aa
{
0B43:06AA 52            PUSH    DX
0B43:06AB D1E5          SHL     BP,1

; get near address from table and jump into it
0B43:06AD 2E            CS:
0B43:06AE 8B968605      MOV     DX,[BP+0586]
0B43:06B2 FFD2          CALL    DX

0B43:06B4 5A            POP     DX
0B43:06B5 CB            RETF
}

/* Driver functions */

do_nothing() – 06b6
{
0B43:06B6 C3            RET
}

06b7
{
0B43:06B7 2E            CS:
0B43:06B8 A08505        MOV    AL,[0585]
0B43:06BB 32E4          XOR    AH,AH
0B43:06BD 80F9FF        CMP    CL,FF
0B43:06C0 7501          JNZ    06C3
0B43:06C2 C3            RET

0B43:06C3 2E            CS:
0B43:06C4 880E8505      MOV    [0585],CL
0B43:06C8 C3            RET
}

note_off() – 06c9
{
0B43:06C9 50            PUSH    AX                                 
0B43:06CA 56            PUSH    SI                                 
0B43:06CB 51            PUSH    CX                                 
0B43:06CC 3C09          CMP    AL,09                              
0B43:06CE 7515          JNZ    06E5                               
0B43:06D0 86E9          XCHG    CH,CL                              
0B43:06D2 8BF1          MOV    SI,CX                              
0B43:06D4 86E9          XCHG    CH,CL                              
0B43:06D6 83E67F        AND    SI,+7F                             
0B43:06D9 2E            CS:                                       
0B43:06DA 8AACC101      MOV    CH,[SI+01C1]                       
0B43:06DE 80FDFF        CMP    CH,FF                              
0B43:06E1 7430          JZ    0713                               
0B43:06E3 EB27          JMP    070C                               
0B43:06E5 8BF0          MOV    SI,AX                              
0B43:06E7 83E60F        AND    SI,+0F                             
0B43:06EA 2E            CS:                                       
0B43:06EB 80BC7405FF    CMP    BYTE PTR [SI+0574],FF              
0B43:06F0 7421          JZ    0713                               
0B43:06F2 2E            CS:                                       
0B43:06F3 02AC4405      ADD    CH,[SI+0544]                       
0B43:06F7 B4F4          MOV    AH,F4                              
0B43:06F9 2E            CS:                                       
0B43:06FA 80BC440580    CMP    BYTE PTR [SI+0544],80              
0B43:06FF 7202          JB    0703                               
0B43:0701 B40C          MOV    AH,0C                              
0B43:0703 80FD80        CMP    CH,80                              
0B43:0706 7204          JB    070C                               
0B43:0708 02EC          ADD    CH,AH                              
0B43:070A EBF7          JMP    0703

; call send_message(90, 00)
0B43:070C B490          MOV    AH,90                              
0B43:070E B100          MOV    CL,00                              
0B43:0710 E8F401        CALL    0907

0B43:0713 59            POP    CX                                 
0B43:0714 5E            POP    SI                                 
0B43:0715 58            POP    AX                                 
0B43:0716 C3            RET
}

note_on() – 0717
{
0B43:0717 50            PUSH    AX                                 
0B43:0718 56            PUSH    SI                                 
0B43:0719 51            PUSH    CX                                 
0B43:071A 57            PUSH    DI                                 
0B43:071B 3C09          CMP    AL,09                              
0B43:071D 751A          JNZ    0739                               
0B43:071F 86E9          XCHG    CH,CL                              
0B43:0721 8BF1          MOV    SI,CX                              
0B43:0723 86E9          XCHG    CH,CL                              
0B43:0725 83E67F        AND    SI,+7F                             
0B43:0728 2E            CS:                                       
0B43:0729 8AACC101      MOV    CH,[SI+01C1]                       
0B43:072D 80FDFF        CMP    CH,FF                              
0B43:0730 744E          JZ    0780                               
0B43:0732 8BF0          MOV    SI,AX                              
0B43:0734 83E60F        AND    SI,+0F                             
0B43:0737 EB27          JMP    0760                               
0B43:0739 8BF0          MOV    SI,AX                              
0B43:073B 83E60F        AND    SI,+0F                             
0B43:073E 2E            CS:                                       
0B43:073F 80BC7405FF    CMP    BYTE PTR [SI+0574],FF              
0B43:0744 743A          JZ    0780                               
0B43:0746 2E            CS:                                       
0B43:0747 02AC4405      ADD    CH,[SI+0544]                       
0B43:074B B4F4          MOV    AH,F4                              
0B43:074D 2E            CS:                                       
0B43:074E 80BC440580    CMP    BYTE PTR [SI+0544],80              
0B43:0753 7202          JB    0757                               
0B43:0755 B40C          MOV    AH,0C                              
0B43:0757 80FD80        CMP    CH,80                              
0B43:075A 7204          JB    0760                               
0B43:075C 02EC          ADD    CH,AH                              
0B43:075E EBF7          JMP    0757                               
0B43:0760 50            PUSH    AX                                 
0B43:0761 B080          MOV    AL,80                              
0B43:0763 2E            CS:                                       
0B43:0764 F6A46405      MUL    BYTE PTR [SI+0564]                 
0B43:0768 8BF9          MOV    DI,CX                              
0B43:076A 83E77F        AND    DI,+7F                             
0B43:076D 03F8          ADD    DI,AX                              
0B43:076F 58            POP    AX                                 
0B43:0770 2E            CS:                                       
0B43:0771 8A8DC202      MOV    CL,[DI+02C2]                       
0B43:0775 2E            CS:                                       
0B43:0776 C684340501    MOV    BYTE PTR [SI+0534],01

; call send_message(90,*di+02c2)
0B43:077B B490          MOV    AH,90                              
0B43:077D E88701        CALL    0907

0B43:0780 5F            POP    DI                                 
0B43:0781 59            POP    CX                                 
0B43:0782 5E            POP    SI                                 
0B43:0783 58            POP    AX                                 
0B43:0784 C3            RET
}

0785
{
0B43:0785 50            PUSH    AX                                 
0B43:0786 56            PUSH    SI                                 
0B43:0787 8BF0          MOV    SI,AX                              
0B43:0789 83E60F        AND    SI,+0F                             
0B43:078C 80E17F        AND    CL,7F                              
0B43:078F 80FD07        CMP    CH,07                              
0B43:0792 7543          JNZ    07D7                               
0B43:0794 2E            CS:                                       
0B43:0795 888C0405      MOV    [SI+0504],CL

; if *04c3 = 00, return
0B43:0799 2E            CS:                                       
0B43:079A 803EC30400    CMP    BYTE PTR [04C3],00                 
0B43:079F 7502          JNZ    07A3                               
0B43:07A1 EB72          JMP    0815

0B43:07A3 2E            CS:                                       
0B43:07A4 028C5405      ADD    CL,[SI+0554]                       
0B43:07A8 80F980        CMP    CL,80                              
0B43:07AB 720C          JB    07B9                               
0B43:07AD B17F          MOV    CL,7F                              
0B43:07AF 2E            CS:                                       
0B43:07B0 80BC540580    CMP    BYTE PTR [SI+0554],80              
0B43:07B5 7202          JB    07B9                               
0B43:07B7 B101          MOV    CL,01                              
0B43:07B9 8AE8          MOV    CH,AL

; set al = *04c2
0B43:07BB 2E            CS:                                       
0B43:07BC A0C204        MOV    AL,[04C2]

0B43:07BF F6E1          MUL    CL                                 
0B43:07C1 B10F          MOV    CL,0F                              
0B43:07C3 F6F1          DIV    CL                                 
0B43:07C5 8AC8          MOV    CL,AL                              
0B43:07C7 8AC5          MOV    AL,CH                              
0B43:07C9 B507          MOV    CH,07                              
0B43:07CB 0AC9          OR    CL,CL                              
0B43:07CD 7541          JNZ    0810                               
0B43:07CF 0AE4          OR    AH,AH                              
0B43:07D1 743D          JZ    0810                               
0B43:07D3 FEC1          INC    CL                                 
0B43:07D5 EB39          JMP    0810                               
0B43:07D7 80FD0A        CMP    CH,0A                              
0B43:07DA 750E          JNZ    07EA                               
0B43:07DC 2E            CS:                                       
0B43:07DD 388C1405      CMP    [SI+0514],CL                       
0B43:07E1 7432          JZ    0815                               
0B43:07E3 2E            CS:                                       
0B43:07E4 888C1405      MOV    [SI+0514],CL                       
0B43:07E8 EB26          JMP    0810                               
0B43:07EA 80FD40        CMP    CH,40                              
0B43:07ED 750E          JNZ    07FD                               
0B43:07EF 2E            CS:                                       
0B43:07F0 388C2405      CMP    [SI+0524],CL                       
0B43:07F4 741F          JZ    0815                               
0B43:07F6 2E            CS:                                       
0B43:07F7 888C2405      MOV    [SI+0524],CL                       
0B43:07FB EB13          JMP    0810                               
0B43:07FD 80FD7B        CMP    CH,7B                              
0B43:0800 7513          JNZ    0815                               
0B43:0802 2E            CS:                                       
0B43:0803 80BC340500    CMP    BYTE PTR [SI+0534],00              
0B43:0808 740B          JZ    0815                               
0B43:080A 2E            CS:                                       
0B43:080B C684340500    MOV    BYTE PTR [SI+0534],00              
0B43:0810 B4B0          MOV    AH,B0                              
0B43:0812 E8F200        CALL    0907                               
0B43:0815 5E            POP    SI                                 
0B43:0816 58            POP    AX                                 
0B43:0817 C3            RET
}

0B43:0818 50            PUSH    AX                                 
0B43:0819 56            PUSH    SI                                 
0B43:081A 51            PUSH    CX                                 
0B43:081B 53            PUSH    BX                                 
0B43:081C 3C09          CMP    AL,09                              
0B43:081E 7453          JZ    0873                               
0B43:0820 8BF0          MOV    SI,AX                              
0B43:0822 83E60F        AND    SI,+0F                             
0B43:0825 2E            CS:                                       
0B43:0826 388CC404      CMP    [SI+04C4],CL                       
0B43:082A 7447          JZ    0873                               
0B43:082C 2E            CS:                                       
0B43:082D 888CC404      MOV    [SI+04C4],CL                       
0B43:0831 8BF1          MOV    SI,CX                              
0B43:0833 83E67F        AND    SI,+7F                             
0B43:0836 2E            CS:                                       
0B43:0837 8A8C4100      MOV    CL,[SI+0041]                       
0B43:083B 2E            CS:                                       
0B43:083C 8AACC100      MOV    CH,[SI+00C1]                       
0B43:0840 2E            CS:                                       
0B43:0841 8ABC4101      MOV    BH,[SI+0141]                       
0B43:0845 2E            CS:                                       
0B43:0846 8A9C4202      MOV    BL,[SI+0242]                       
0B43:084A 8BF0          MOV    SI,AX                              
0B43:084C 83E60F        AND    SI,+0F                             
0B43:084F 2E            CS:                                       
0B43:0850 889C6405      MOV    [SI+0564],BL                       
0B43:0854 32DB          XOR    BL,BL                              
0B43:0856 2E            CS:                                       
0B43:0857 80BC7405FF    CMP    BYTE PTR [SI+0574],FF              
0B43:085C 7502          JNZ    0860                               
0B43:085E FEC3          INC    BL                                 
0B43:0860 2E            CS:                                       
0B43:0861 888C7405      MOV    [SI+0574],CL                       
0B43:0865 80F9FF        CMP    CL,FF                              
0B43:0868 750B          JNZ    0875                               
0B43:086A B4B0          MOV    AH,B0                              
0B43:086C B57B          MOV    CH,7B                              
0B43:086E 32C9          XOR    CL,CL                              
0B43:0870 E89400        CALL    0907                               
0B43:0873 EB64          JMP    08D9                               
0B43:0875 2E            CS:                                       
0B43:0876 3AAC4405      CMP    CH,[SI+0544]                       
0B43:087A 7412          JZ    088E                               
0B43:087C 2E            CS:                                       
0B43:087D 88AC4405      MOV    [SI+0544],CH                       
0B43:0881 51            PUSH    CX                                 
0B43:0882 B4B0          MOV    AH,B0                              
0B43:0884 B57B          MOV    CH,7B                              
0B43:0886 32C9          XOR    CL,CL                              
0B43:0888 E87C00        CALL    0907                               
0B43:088B 59            POP    CX                                 
0B43:088C FEC3          INC    BL                                 
0B43:088E 0ADB          OR    BL,BL                              
0B43:0890 7507          JNZ    0899                               
0B43:0892 2E            CS:                                       
0B43:0893 3ABC5405      CMP    BH,[SI+0554]                       
0B43:0897 7411          JZ    08AA                               
0B43:0899 2E            CS:                                       
0B43:089A 88BC5405      MOV    [SI+0554],BH                       
0B43:089E 51            PUSH    CX                                 
0B43:089F 2E            CS:                                       
0B43:08A0 8A8C0405      MOV    CL,[SI+0504]                       
0B43:08A4 B507          MOV    CH,07                              
0B43:08A6 E8DCFE        CALL    0785                               
0B43:08A9 59            POP    CX                                 
0B43:08AA B4C0          MOV    AH,C0                              
0B43:08AC E85800        CALL    0907                               
0B43:08AF 0ADB          OR    BL,BL                              
0B43:08B1 7426          JZ    08D9                               
0B43:08B3 B4B0          MOV    AH,B0                              
0B43:08B5 B50A          MOV    CH,0A                              
0B43:08B7 2E            CS:                                       
0B43:08B8 8A8C1405      MOV    CL,[SI+0514]                       
0B43:08BC 80E17F        AND    CL,7F                              
0B43:08BF E84500        CALL    0907                               
0B43:08C2 D1E6          SHL    SI,1                               
0B43:08C4 2E            CS:                                       
0B43:08C5 8A8CD404      MOV    CL,[SI+04D4]                       
0B43:08C9 80E17F        AND    CL,7F                              
0B43:08CC 2E            CS:                                       
0B43:08CD 8AACD504      MOV    CH,[SI+04D5]                       
0B43:08D1 80E57F        AND    CH,7F                              
0B43:08D4 B4E0          MOV    AH,E0                              
0B43:08D6 E82E00        CALL    0907                               
0B43:08D9 5B            POP    BX                                 
0B43:08DA 59            POP    CX                                 
0B43:08DB 5E            POP    SI                                 
0B43:08DC 58            POP    AX                                 
0B43:08DD C3            RET                                       
0B43:08DE 50            PUSH    AX                                 
0B43:08DF 56            PUSH    SI                                 
0B43:08E0 8BF0          MOV    SI,AX                              
0B43:08E2 83E60F        AND    SI,+0F                             
0B43:08E5 D1E6          SHL    SI,1                               
0B43:08E7 2E            CS:                                       
0B43:08E8 388CD404      CMP    [SI+04D4],CL                       
0B43:08EC 7507          JNZ    08F5                               
0B43:08EE 2E            CS:                                       
0B43:08EF 38ACD504      CMP    [SI+04D5],CH                       
0B43:08F3 740F          JZ    0904                               
0B43:08F5 2E            CS:                                       
0B43:08F6 888CD404      MOV    [SI+04D4],CL                       
0B43:08FA 2E            CS:                                       
0B43:08FB 88ACD504      MOV    [SI+04D5],CH                       
0B43:08FF B4E0          MOV    AH,E0                              
0B43:0901 E80300        CALL    0907                               
0B43:0904 5E            POP    SI                                 
0B43:0905 58            POP    AX                                 
0B43:0906 C3            RET

send_message(ax) - 0907
{
0B43:0907 53            PUSH    BX                                 
0B43:0908 8AD0          MOV    DL,AL                              
0B43:090A 0AD4          OR    DL,AH

; call send_midi_byte(*0584)
0B43:090C 2E            CS:                                       
0B43:090D 88168405      MOV    [0584],DL                          
0B43:0911 8ADA          MOV    BL,DL                              
0B43:0913 E85200        CALL    0968

0B43:0916 80FCC0        CMP    AH,C0                              
0B43:0919 740A          JZ    0925                               
0B43:091B 80FCD0        CMP    AH,D0                              
0B43:091E 7405          JZ    0925

; call send_midi_byte(ch)
0B43:0920 8ADD          MOV    BL,CH                              
0B43:0922 E84300        CALL    0968

; call send_midi_byte(cl)
0B43:0925 8AD9          MOV    BL,CL                              
0B43:0927 E83E00        CALL    0968                               
0B43:092A 5B            POP    BX                                 
0B43:092B C3            RET
}

shutdown_device() - 092c
{
0B43:092C 53            PUSH    BX

; call mpu_reset()
0B43:092D E8E000        CALL    0A10

0B43:0930 5B            POP    BX                                 
0B43:0931 C3            RET
}

mpu_command(bl) - 0932
{
0B43:0932 9C            PUSHF                                       
0B43:0933 FA            CLI                                       
0B43:0934 50            PUSH    AX                                 
0B43:0935 51            PUSH    CX                                 
0B43:0936 52            PUSH    DX

0B43:0937 B9FFFF        MOV    CX,FFFF

; get data ready value from port 0331
0B43:093A BA3103        MOV    DX,0331
0B43:093D EC            IN    AL,DX

; if al == 40, jump to 094a
0B43:093E A840          TEST    AL,40                              
0B43:0940 7408          JZ    094A

0B43:0942 49            DEC    CX                                 
0B43:0943 83F900        CMP    CX,+00                             
0B43:0946 75F5          JNZ    093D                               
0B43:0948 EB19          JMP    0963

; write data to port 0331
0B43:094A 8AC3          MOV    AL,BL                              
0B43:094C EE            OUT    DX,AL

0B43:094D B9FFFF        MOV    CX,FFFF

; read value from port 0331
0B43:0950 EC            IN    AL,DX

0B43:0951 D0C0          ROL    AL,1
0B43:0953 7306          JNB    095B                               
0B43:0955 49            DEC    CX                                 
0B43:0956 83F900        CMP    CX,+00                             
0B43:0959 75F5          JNZ    0950

; get value from port 0330
0B43:095B BA3003        MOV    DX,0330                            
0B43:095E EC            IN    AL,DX

; does nothing
0B43:095F 3CFE          CMP    AL,FE                              
0B43:0961 7400          JZ    0963                               

0B43:0963 5A            POP    DX
0B43:0964 59            POP    CX                                 
0B43:0965 58            POP    AX                                 
0B43:0966 9D            POPF                                       
0B43:0967 C3            RET
}

send_midi_byte(bl) - 0968
{
0B43:0968 9C            PUSHF                                       
0B43:0969 FA            CLI                                       
0B43:096A 50            PUSH    AX                                 
0B43:096B 51            PUSH    CX                                 
0B43:096C 52            PUSH    DX

; set status port number = 331
0B43:096D BA3103        MOV    DX,0331

; initialize timeout counter
0B43:0970 B9FF00        MOV    CX,00FF

; read status from port 331
0B43:0973 EC            IN    AL,DX

; if ready (0x40) jump to 098b to write data                             
0B43:0974 A840          TEST    AL,40                              
0B43:0976 7413          JZ    098B

; cx--
0B43:0978 49            DEC    CX
0B43:0979 D0C0          ROL    AL,1
0B43:097B 7207          JB    0984

; clear any incoming data from data port
0B43:097D BA3003        MOV    DX,0330                            
0B43:0980 EC            IN    AL,DX

; set port back to status (331)
0B43:0981 BA3103        MOV    DX,0331

; loop back
0B43:0984 83F901        CMP    CX,+01                             
0B43:0987 7DEA          JGE    0973

; still not ready, so return
0B43:0989 EB06          JMP    0991

; write data in BL to port 330
0B43:098B BA3003        MOV    DX,0330                            
0B43:098E 8AC3          MOV    AL,BL                              
0B43:0990 EE            OUT    DX,AL

; return
0B43:0991 5A            POP    DX                                 
0B43:0992 59            POP    CX                                 
0B43:0993 58            POP    AX                                 
0B43:0994 9D            POPF                                       
0B43:0995 C3            RET
}

0996(cl)
{
0B43:0996 53            PUSH    BX                                 
0B43:0997 51            PUSH    CX                                 
0B43:0998 56            PUSH    SI

; set al = *04c2
0B43:0999 2E            CS:                                       
0B43:099A A0C204        MOV    AL,[04C2]

; set ah = 00
0B43:099D 32E4          XOR    AH,AH                              

; if cl == ff, return
0B43:099F 80F9FF        CMP    CL,FF                              
0B43:09A2 742A          JZ    09CE

; set *04c2 = cl
0B43:09A4 2E            CS:                                       
0B43:09A5 880EC204      MOV    [04C2],CL

; if *04c3 == 00, return
0B43:09A9 2E            CS:                                       
0B43:09AA 803EC30400    CMP    BYTE PTR [04C3],00                 
0B43:09AF 741D          JZ    09CE

0B43:09B1 50            PUSH    AX

0B43:09B2 B001          MOV    AL,01                              
0B43:09B4 BE0100        MOV    SI,0001                            
0B43:09B7 B507          MOV    CH,07                              
0B43:09B9 2E            CS:                                       
0B43:09BA 8A8C0405      MOV    CL,[SI+0504]                       
0B43:09BE 80F9FF        CMP    CL,FF                              
0B43:09C1 7403          JZ    09C6

; call 0785
0B43:09C3 E8BFFD        CALL    0785

0B43:09C6 FEC0          INC    AL                                 
0B43:09C8 46            INC    SI                                 
0B43:09C9 3C0A          CMP    AL,0A                              
0B43:09CB 75EC          JNZ    09B9

0B43:09CD 58            POP    AX

0B43:09CE 5E            POP    SI                                 
0B43:09CF 59            POP    CX                                 
0B43:09D0 5B            POP    BX                                 
0B43:09D1 C3            RET
}

09d2
{
0B43:09D2 32E4          XOR    AH,AH                              
0B43:09D4 2E            CS:                                       
0B43:09D5 A0C304        MOV    AL,[04C3]                          
0B43:09D8 80F9FF        CMP    CL,FF                              
0B43:09DB 7501          JNZ    09DE                               
0B43:09DD C3            RET

0B43:09DE 50            PUSH    AX                                 
0B43:09DF 51            PUSH    CX                                 
0B43:09E0 80F900        CMP    CL,00                              
0B43:09E3 751A          JNZ    09FF                               
0B43:09E5 2E            CS:                                       
0B43:09E6 C606C30400    MOV    BYTE PTR [04C3],00                 
0B43:09EB B001          MOV    AL,01                              
0B43:09ED B4B0          MOV    AH,B0                              
0B43:09EF B507          MOV    CH,07                              
0B43:09F1 B100          MOV    CL,00

; do
{
; call 0907
0B43:09F3 E811FF        CALL    0907

; a++
0B43:09F6 FEC0          INC    AL

; loop while al == 09
0B43:09F8 3C09          CMP    AL,09                              
0B43:09FA 75F7          JNZ    09F3
}

0B43:09FC 59            POP    CX                                 
0B43:09FD 58            POP    AX                                 
0B43:09FE C3            RET

; set *04c3 = 01
0B43:09FF 2E            CS:                                       
0B43:0A00 C606C30401    MOV    BYTE PTR [04C3],01

; set cl = *04c2
0B43:0A05 2E            CS:                                       
0B43:0A06 8A0EC204      MOV    CL,[04C2]

; call 0996
0B43:0A0A E889FF        CALL    0996                               

0B43:0A0D 59            POP    CX                                 
0B43:0A0E 58            POP    AX                                 
0B43:0A0F C3            RET
}

mpu_reset() - 0a10
{
0B43:0A10 53            PUSH    BX

; call mpu_command(ff)
0B43:0A11 B3FF          MOV    BL,FF
0B43:0A13 E81CFF        CALL    0932

0B43:0A16 5B            POP    BX
0B43:0A17 C3            RET
}

0a18
{
0B43:0A18 56            PUSH    SI                                 
0B43:0A19 8BF0          MOV    SI,AX                              
0B43:0A1B 83E60F        AND    SI,+0F

0B43:0A1E 80FCE0        CMP    AH,E0                              
0B43:0A21 7516          JNZ    0A39

0B43:0A23 D1E6          SHL    SI,1                               
0B43:0A25 2E            CS:                                       
0B43:0A26 8B84D404      MOV    AX,[SI+04D4]                       
0B43:0A2A 3DFFFF        CMP    AX,FFFF                            
0B43:0A2D 7453          JZ    0A82                               
0B43:0A2F 86E0          XCHG    AH,AL                              
0B43:0A31 D0EC          SHR    AH,1                               
0B43:0A33 7302          JNB    0A37                               
0B43:0A35 0C80          OR    AL,80                              
0B43:0A37 EB49          JMP    0A82                               
0B43:0A39 80FCC0        CMP    AH,C0                              
0B43:0A3C 7507          JNZ    0A45                               
0B43:0A3E 2E            CS:                                       
0B43:0A3F 8A84C404      MOV    AL,[SI+04C4]                       
0B43:0A43 EB3D          JMP    0A82                               
0B43:0A45 80FCB0        CMP    AH,B0                              
0B43:0A48 7535          JNZ    0A7F                               
0B43:0A4A 80FD4B        CMP    CH,4B                              
0B43:0A4D 7430          JZ    0A7F                               
0B43:0A4F 80FD01        CMP    CH,01                              
0B43:0A52 7507          JNZ    0A5B                               
0B43:0A54 2E            CS:                                       
0B43:0A55 8A84F404      MOV    AL,[SI+04F4]                       
0B43:0A59 EB27          JMP    0A82                               
0B43:0A5B 80FD07        CMP    CH,07                              
0B43:0A5E 7507          JNZ    0A67                               
0B43:0A60 2E            CS:                                       
0B43:0A61 8A840405      MOV    AL,[SI+0504]                       
0B43:0A65 EB1B          JMP    0A82                               
0B43:0A67 80FD0A        CMP    CH,0A                              
0B43:0A6A 7507          JNZ    0A73                               
0B43:0A6C 2E            CS:                                       
0B43:0A6D 8A841405      MOV    AL,[SI+0514]                       
0B43:0A71 EB0F          JMP    0A82                               
0B43:0A73 80FD40        CMP    CH,40                              
0B43:0A76 7507          JNZ    0A7F                               
0B43:0A78 2E            CS:                                       
0B43:0A79 8A842405      MOV    AL,[SI+0524]                       
0B43:0A7D EB03          JMP    0A82                               
0B43:0A7F B8FFFF        MOV    AX,FFFF                            
0B43:0A82 5E            POP    SI                                 
0B43:0A83 C3            RET
}

init_device() - 0a84
{
0B43:0A84 56            PUSH    SI

; call mpu_reset()
0B43:0A85 E888FF        CALL    0A10

; call mpu_command(3f)
0B43:0A88 BB3F00        MOV    BX,003F
0B43:0A8B E8A4FE        CALL    0932

0B43:0A8E E86300        CALL    0AF4

; call mpu_command(3f)
0B43:0A91 BB3F00        MOV    BX,003F
0B43:0A94 E89BFE        CALL    0932

0B43:0A97 E85A00        CALL    0AF4

; call mpu_command(3f)
0B43:0A9A BB3F00        MOV    BX,003F
0B43:0A9D E892FE        CALL    0932

0B43:0AA0 E85100        CALL    0AF4

0B43:0AA3 E84E00        CALL    0AF4

0B43:0AA6 8BF0          MOV    SI,AX                              
0B43:0AA8 BF0000        MOV    DI,0000                            
0B43:0AAB 26            ES:                                       
0B43:0AAC 8A1C          MOV    BL,[SI]                            
0B43:0AAE 2E            CS:                                       
0B43:0AAF 889D4100      MOV    [DI+0041],BL                       
0B43:0AB3 47            INC    DI                                 
0B43:0AB4 46            INC    SI                                 
0B43:0AB5 81FF8104      CMP    DI,0481                            
0B43:0AB9 75F0          JNZ    0AAB                               
0B43:0ABB 2E            CS:                                       
0B43:0ABC 8A1E4102      MOV    BL,[0241]                          
0B43:0AC0 2E            CS:                                       
0B43:0AC1 881E5D05      MOV    [055D],BL                          
0B43:0AC5 26            ES:                                       
0B43:0AC6 8A0C          MOV    CL,[SI]                            
0B43:0AC8 46            INC    SI                                 
0B43:0AC9 26            ES:                                       
0B43:0ACA 8A2C          MOV    CH,[SI]                            
0B43:0ACC 46            INC    SI                                 
0B43:0ACD 83F900        CMP    CX,+00                             
0B43:0AD0 7414          JZ    0AE6                               
0B43:0AD2 26            ES:                                       
0B43:0AD3 8A1C          MOV    BL,[SI]                            
0B43:0AD5 46            INC    SI

; call send_midi_byte(??)
0B43:0AD6 E88FFE        CALL    0968

0B43:0AD9 80FBF7        CMP    BL,F7                              
0B43:0ADC 7506          JNZ    0AE4                               
0B43:0ADE E81300        CALL    0AF4                               
0B43:0AE1 E81000        CALL    0AF4                               
0B43:0AE4 E2EC          LOOP    0AD2                               

; call 0996(0c)
0B43:0AE6 B10C          MOV    CL,0C
0B43:0AE8 E8ABFE        CALL    0996

; set ax = 0984
0B43:0AEB B88409        MOV    AX,0984

; set cx = 0801
0B43:0AEE B101          MOV    CL,01                              
0B43:0AF0 B508          MOV    CH,08

0B43:0AF2 5E            POP    SI                                 
0B43:0AF3 C3            RET
}

0B43:0AF4 50            PUSH    AX                                 
0B43:0AF5 52            PUSH    DX                                 
0B43:0AF6 57            PUSH    DI                                 
0B43:0AF7 BA3103        MOV    DX,0331                            
0B43:0AFA BF0075        MOV    DI,7500                            
0B43:0AFD EC            IN    AL,DX                              
0B43:0AFE 4F            DEC    DI                                 
0B43:0AFF 83FF00        CMP    DI,+00                             
0B43:0B02 75F9          JNZ    0AFD                               
0B43:0B04 5F            POP    DI                                 
0B43:0B05 5A            POP    DX                                 
0B43:0B06 58            POP    AX                                 
0B43:0B07 C3            RET

get_device_info() - 0b08
{
; don’t use sfx
0B43:0B08 B401          MOV    AH,01

; use sfx
# 0B08 B401   mov ah,11

; load GM map
0B43:0B0A B004          MOV    AL,04

0B43:0B0C B50C          MOV    CH,0C
0B43:0B0E B120          MOV    CL,20
0B43:0B10 C3            RET
}

/* added for GM Blast driver */

; genmidi.drv uses 04c2,04c3 the same way that 
; mtblast.drv uses 015e,0160

; mtblast.drv uses 08c7-0912, difference of 0x024a
; (reflected as 07c7-0812 or 0a11-0a5c in code)

; 0B11-0B5C = 76 bytes of 0’s
0B43:0B11 0000          ADD    [BX+SI],AL                         
0B43:0B13 0000          ADD    [BX+SI],AL                         
0B43:0B15 0000          ADD    [BX+SI],AL                         
0B43:0B17 0000          ADD    [BX+SI],AL                         
0B43:0B19 0000          ADD    [BX+SI],AL                         
0B43:0B1B 0000          ADD    [BX+SI],AL                         
0B43:0B1D 0000          ADD    [BX+SI],AL                         
0B43:0B1F 0000          ADD    [BX+SI],AL                         
0B43:0B21 0000          ADD    [BX+SI],AL                         
0B43:0B23 0000          ADD    [BX+SI],AL                         
0B43:0B25 0000          ADD    [BX+SI],AL                         
0B43:0B27 0000          ADD    [BX+SI],AL                         
0B43:0B29 0000          ADD    [BX+SI],AL                         
0B43:0B2B 0000          ADD    [BX+SI],AL                         
0B43:0B2D 0000          ADD    [BX+SI],AL                         
0B43:0B2F 0000          ADD    [BX+SI],AL                         
0B43:0B31 0000          ADD    [BX+SI],AL                         
0B43:0B33 0000          ADD    [BX+SI],AL                         
0B43:0B35 0000          ADD    [BX+SI],AL                         
0B43:0B37 0000          ADD    [BX+SI],AL                         
0B43:0B39 0000          ADD    [BX+SI],AL                         
0B43:0B3B 0000          ADD    [BX+SI],AL                         
0B43:0B3D 0000          ADD    [BX+SI],AL                         
0B43:0B3F 0000          ADD    [BX+SI],AL                         
0B43:0B41 0000          ADD    [BX+SI],AL                         
0B43:0B43 0000          ADD    [BX+SI],AL                         
0B43:0B45 0000          ADD    [BX+SI],AL                         
0B43:0B47 0000          ADD    [BX+SI],AL                         
0B43:0B49 0000          ADD    [BX+SI],AL                         
0B43:0B4B 0000          ADD    [BX+SI],AL                         
0B43:0B4D 0000          ADD    [BX+SI],AL                         
0B43:0B4F 0000          ADD    [BX+SI],AL                         
0B43:0B51 0000          ADD    [BX+SI],AL                         
0B43:0B53 0000          ADD    [BX+SI],AL                         
0B43:0B55 0000          ADD    [BX+SI],AL                         
0B43:0B57 0000          ADD    [BX+SI],AL                         
0B43:0B59 0000          ADD    [BX+SI],AL                         
0B43:0B5B 0000          ADD    [BX+SI],AL

; 10b2-10b3 (formerly 00ef-00f0) = sb port (220)
; 0a1a (formerly 07d0) = sample loaded (01) or unloaded (00)
; 0a40-0a41 (formerly 07f6-07f7) = size of audio data
; 0a49 (formerly 07ff) = sb irq
; 0a4e (formerly 0804) = timer constant

load_sample(ax,cl,ch) - 0b5d
{
; ax = some address
; cl = must be non-zero to play
; ch = ?


; if cl == 0, return
0B43:0B5D 80F900        CMP    CL,00                              
0B43:0B60 7501          JNZ    0B63                               
0B43:0B62 C3            RET

; if *04c2 == 0, return
0B43:0B63 2E            CS:
0B43:0B64 803E5E0100    CMP    BYTE PTR [04c2],00
0B43:0B69 7501          JNZ    0B6C
0B43:0B6B C3            RET

; if *04c3 == 0, return
0B43:0B6C 2E            CS:
0B43:0B6D 803E600100    CMP    BYTE PTR [04c3],00
0B43:0B72 7501          JNZ    0B75
0B43:0B74 C3            RET

0B43:0B75 53            PUSH    BX                                 
0B43:0B76 51            PUSH    CX                                 
0B43:0B77 52            PUSH    DX

; set *cs:07d1 = ch
0B43:0B78 2E            CS:                                       
0B43:0B79 882ED107      MOV    [07D1],CH

; set *cs:07d2 = 00
0B43:0B7D 2E            CS:                                       
0B43:0B7E C606D20700    MOV    BYTE PTR [07D2],00

; set bx = ax (input address)
0B43:0B83 8BD8          MOV    BX,AX

; loop until we find first address that does not contain 0xFE
; (who knows why?)
{
; bx++
0B43:0B85 43            INC    BX

; if *bx == fe, loop back to 0b85
0B43:0B86 803FFE        CMP    BYTE PTR [BX],FE                   
0B43:0B89 74FA          JZ    0B85
}

; bx++
0B43:0B8B 43            INC    BX

; bx now points to address after last 0xFE
; which I believe is the sampling rate


; set cx = *bx (sampling rate, it would seem)
0B43:0B8C 8B0F          MOV    CX,[BX]

; if cx >= 0f34 (3892 dec), jump to 0b9c
0B43:0B8E 81F9340F      CMP    CX,0F34                            
0B43:0B92 7308          JNB    0B9C


; no timer constant

; set *0804 = 00 (timer constant)
0B43:0B94 2E            CS:                                       
0B43:0B95 C606040800    MOV    BYTE PTR [0804],00

; jump to 0bad                 
0B43:0B9A EB11          JMP    0BAD


; compute timer constant

; set dx,ax = 0f4240 (1000000 dec)
0B43:0B9C BA0F00        MOV    DX,000F
0B43:0B9F B84042        MOV    AX,4240

; ax = 0f4240 / cx
0B43:0BA2 F7F1          DIV    CX

; set ah = ff - al
0B43:0BA4 32E4          XOR    AH,AH
0B43:0BA6 2AE0          SUB    AH,AL

; set *0804 = ah (timer constant)
0B43:0BA8 2E            CS:                                       
0B43:0BA9 88260408      MOV    [0804],AH


; it looks like we’re computing and saving some kind of offsets into the sample...

; set ax = *bx+2 (???)
0B43:0BAD 8B4702        MOV    AX,[BX+02]                         

; set *07d5 = *07db = ds
0B43:0BB0 8CD9          MOV    CX,DS
0B43:0BB2 2E            CS:                                       
0B43:0BB3 890ED507      MOV    [07D5],CX                          
0B43:0BB7 2E            CS:                                       
0B43:0BB8 890EDB07      MOV    [07DB],CX

; set cx = bx + *bx+04 (???)
0B43:0BBC 8BCB          MOV    CX,BX                              
0B43:0BBE 034F04        ADD    CX,[BX+04]

; set dx = cs
0B43:0BC1 8BD1          MOV    DX,CX

; set *07d3 = cx + 8
0B43:0BC3 83C108        ADD    CX,+08                             
0B43:0BC6 2E            CS:                                       
0B43:0BC7 890ED307      MOV    [07D3],CX

; set cx = bx + *bx+6
0B43:0BCB 8BCB          MOV    CX,BX                              
0B43:0BCD 034F06        ADD    CX,[BX+06]

; set *07d9 = cx + 8
0B43:0BD0 83C108        ADD    CX,+08                             
0B43:0BD3 2E            CS:                                       
0B43:0BD4 890ED907      MOV    [07D9],CX

0B43:0BD8 83E908        SUB    CX,+08                             
0B43:0BDB 2BCA          SUB    CX,DX                              
0B43:0BDD 2E            CS:                                       
0B43:0BDE 890ED707      MOV    [07D7],CX                          
0B43:0BE2 8BC8          MOV    CX,AX                              
0B43:0BE4 2B4F06        SUB    CX,[BX+06]                         
0B43:0BE7 2E            CS:                                       
0B43:0BE8 890EDD07      MOV    [07DD],CX                          
0B43:0BEC 2BC1          SUB    AX,CX                              
0B43:0BEE 2E            CS:                                       
0B43:0BEF A30908        MOV    [0809],AX                          
0B43:0BF2 83C308        ADD    BX,+08


; set *0805,*0807 = ds,bx (address of sample ???)
0B43:0BF5 2E            CS:                                       
0B43:0BF6 8C1E0508      MOV    [0805],DS                          
0B43:0BFA 2E            CS:                                       
0B43:0BFB 891E0708      MOV    [0807],BX

; set *07d0 = 01 (sample loaded?)
0B43:0BFF 2E            CS:                                       
0B43:0C00 C606D00701    MOV    BYTE PTR [07D0],01

0B43:0C05 5A            POP    DX                                 
0B43:0C06 59            POP    CX                                 
0B43:0C07 5B            POP    BX                                 
0B43:0C08 C3            RET
}

stop_sample() - 0c09
{
; set *07d1 = 00
0B43:0C09 2E            CS:                                       
0B43:0C0A C606D10700    MOV    BYTE PTR [07D1],00

; set *07d2 = 01
0B43:0C0F 2E            CS:                                       
0B43:0C10 C606D20701    MOV    BYTE PTR [07D2],01

; call 112e
0B43:0C15 E81605        CALL    112E

; set *07d0 = 00 (sample unloaded)
0B43:0C18 2E            CS:                                       
0B43:0C19 C606D00700    MOV    BYTE PTR [07D0],00

0B43:0C1E C3            RET
}

play_sample() - 0c1f
{
; set *07d1 = ch
0B43:0C1F 2E            CS:                                       
0B43:0C20 882ED107      MOV    [07D1],CH

; if 07d0 != 01 (sample not loaded?), jump to 0c2f (skip playing sample)
0B43:0C24 2E            CS:                                       
0B43:0C25 803ED00701    CMP    BYTE PTR [07D0],01                 
0B43:0C2A 7503          JNZ    0C2F                               

; call 108b
0B43:0C2C E85C04        CALL    108B

; clear al (success)
0B43:0C2F 32C0          XOR    AL,AL

; if *0800 != 0000, jump to 0c3b
0B43:0C31 2E            CS:                                       
0B43:0C32 833E000800    CMP    WORD PTR [0800],+00                
0B43:0C37 7502          JNZ    0C3B

; otherwise, set al = 01 (failure)
0B43:0C39 B001          MOV    AL,01

; clear ah
0B43:0C3B 32E4          XOR    AH,AH                              
0B43:0C3D C3            RET
}

write_to_port(al,dx) - 0c3e
{
; al = data
; dx = port number
; carry flag set on error

; set cx = 0x0200 (loop ctr)
0B43:0C3E B90002        MOV    CX,0200

; set ah = al
0B43:0C41 8AE0          MOV    AH,AL

; waits until status bit is clear
{
; get data from port dx
0B43:0C43 EC            IN    AL,DX

; if bit 7 of al is 0, jump to 0c4d
0B43:0C44 0AC0          OR    AL,AL                              
0B43:0C46 7905          JNS    0C4D

; loop back
0B43:0C48 E2F9          LOOP    0C43
}

; sb never ready – set carry flag and return
0B43:0C4A F9            STC                                       
0B43:0C4B EB04          JMP    0C51

; set al = ah
0B43:0C4D 8AC4          MOV    AL,AH                              

; write al to port
0B43:0C4F EE            OUT    DX,AL

; clear carry (successful write)
0B43:0C50 F8            CLC

0B43:0C51 C3            RET
}

read_from_port() - 0c52
{
; carry flag set on error,
; byte value returned in al

0B43:0C52 52            PUSH    DX

; set dx = 0x22e (for read status)
0B43:0C53 2E            CS:                                       
0B43:0C54 8B16EF00      MOV    DX,[00EF]                          
0B43:0C58 80C20E        ADD    DL,0E

; set cx = 0200 (loop ctr)
0B43:0C5B B90002        MOV    CX,0200 

; wait until status bit is set
{
0B43:0C5E EC            IN    AL,DX

; if bit 7 of al is 0, jump to 0c68
0B43:0C5F 0AC0          OR    AL,AL                              
0B43:0C61 7805          JS    0C68

; loop back
0B43:0C63 E2F9          LOOP    0C5E
}

; sb never ready - set carry flag and return
0B43:0C65 F9            STC                                       
0B43:0C66 EB05          JMP    0C6D

; read from port 0x22a
0B43:0C68 80EA04        SUB    DL,04
0B43:0C6B EC            IN    AL,DX

; clear carry (successful read)
0B43:0C6C F8            CLC

0B43:0C6D 5A            POP    DX                                 
0B43:0C6E C3            RET
}

write_to_port(al,dx) – 0c6f
{
; al = data
; dx = port number

0B43:0C6F 51            PUSH    CX

;set cx = 03e8 (loop ctr, dec 1000)
0B43:0C70 B9E803        MOV    CX,03E8

; ah = al
0B43:0C73 8AE0          MOV    AH,AL                              

; waits until status bit is clear
{
; get data from port dx
0B43:0C75 EC            IN    AL,DX

; if bit 7 of al is 0, jump to 0c7c
0B43:0C76 0AC0          OR    AL,AL                              
0B43:0C78 7902          JNS    0C7C

; loop back
0B43:0C7A E2F9          LOOP    0C75
}

; set al = ah
0B43:0C7C 8AC4          MOV    AL,AH

; write al to port dx
0B43:0C7E EE            OUT    DX,AL

; return
0B43:0C7F 59            POP    CX                                 
0B43:0C80 C3            RET
}

read_from_port() - 0c81
{
; byte value returned in al

0B43:0C81 52            PUSH    DX

; set dx = 0x22e (for read status)
0B43:0C82 2E            CS:                                       
0B43:0C83 8B16EF00      MOV    DX,[00EF]                          
0B43:0C87 80C20E        ADD    DL,0E

; clear al
0B43:0C8A 32C0          XOR    AL,AL

{
; read from 0x22e (int ack/read status)
0B43:0C8C EC            IN    AL,DX

; if bit 7 is clear, loop back
0B43:0C8D 0AC0          OR    AL,AL                              
0B43:0C8F 79FB          JNS    0C8C
}

; read byte from 0x22a
0B43:0C91 80EA04        SUB    DL,04
0B43:0C94 EC            IN    AL,DX

0B43:0C95 5A            POP    DX                                 
0B43:0C96 C3            RET
}

reset_dsp() - 0c97
{
; set dx = port 0x226
0B43:0C97 2E            CS:                                       
0B43:0C98 8B16EF00      MOV    DX,[00EF]                          
0B43:0C9C 80C206        ADD    DL,06

; write 01 to port 0x226 (dsp reset)
0B43:0C9F B001          MOV    AL,01                              
0B43:0CA1 EE            OUT    DX,AL

; read from 0x226 8 times
0B43:0CA2 EC            IN    AL,DX                              
0B43:0CA3 EC            IN    AL,DX                              
0B43:0CA4 EC            IN    AL,DX                              
0B43:0CA5 EC            IN    AL,DX                              
0B43:0CA6 EC            IN    AL,DX                              
0B43:0CA7 EC            IN    AL,DX                              
0B43:0CA8 EC            IN    AL,DX                              
0B43:0CA9 EC            IN    AL,DX

; write 00 to port 0x226 (dsp reset)
0B43:0CAA 32C0          XOR    AL,AL
0B43:0CAC EE            OUT    DX,AL

; set cl = 20 (loop ctr)
0B43:0CAD B120          MOV    CL,20

{
; call read_from_port()
0B43:0CAF E8A0FF        CALL    0C52

; if return value = 0xAA (DSP_READY), jump to 0cbf
0B43:0CB2 3CAA          CMP    AL,AA                              
0B43:0CB4 7409          JZ    0CBF

; cl--, and loop back
0B43:0CB6 FEC9          DEC    CL                                 
0B43:0CB8 75F5          JNZ    0CAF
}

; set return code = 0002 (failure) and return
0B43:0CBA B80200        MOV    AX,0002                            
0B43:0CBD EB02          JMP    0CC1

; set return code = 0000 (success)
0B43:0CBF 33C0          XOR    AX,AX

; set flags and return
0B43:0CC1 0BC0          OR    AX,AX                              
0B43:0CC3 C3            RET
}

0cc4
{
;set bx = 02 (failure)
0B43:0CC4 BB0200        MOV    BX,0002

; set al = e0 (dsp identification)
0B43:0CC7 B0E0          MOV    AL,E0

; set dx = 0x22c (dsp write)
0B43:0CC9 2E            CS:
0B43:0CCA 8B16EF00      MOV    DX,[00EF]
0B43:0CCE 83C20C        ADD    DX,+0C

; get dsp identification (cmd e0)

; call write_to_port(e0, 0x22c)
0B43:0CD1 E86AFF        CALL    0C3E

; if error, jump to 0ce8
0B43:0CD4 7212          JB    0CE8

; cmd aa = ??

; call write_to_port(aa, 0x22c)
0B43:0CD6 B0AA          MOV    AL,AA
0B43:0CD8 E863FF        CALL    0C3E

; if error, jump to 0ce8
0B43:0CDB 720B          JB    0CE8

; call read_from_port()
0B43:0CDD E872FF        CALL    0C52

; if error, jump to 0ce8
0B43:0CE0 7206          JB    0CE8

; if returned data != 0x55, return 
0B43:0CE2 3C55          CMP    AL,55
0B43:0CE4 7502          JNZ    0CE8

; clear bx (success)
0B43:0CE6 33DB          XOR    BX,BX

; set ax = bx (return code)
0B43:0CE8 8BC3          MOV    AX,BX

; set flags
0B43:0CEA 0BC0          OR    AX,AX

; return
0B43:0CEC C3            RET
}

determine_sb_irq() - 0ced
{
; set irq’s 2, 5, and 7
; whichever irq actually responds
; when we talk to 0x220 is our sb irq

; call set_interrupt(02, 0a2d, 0d6f)
0B43:0CED B002          MOV    AL,02
0B43:0CEF BA250B        MOV    DX,0D6F
0B43:0CF2 BBE307        MOV    BX,0A2D
0B43:0CF5 E8FC00        CALL    0DF4

; call set_interrupt(05, 0a31, 0d8d)
0B43:0CF8 B005          MOV    AL,05
0B43:0CFA BA430B        MOV    DX,0D8D
0B43:0CFD BBE707        MOV    BX,0A31
0B43:0D00 E8F100        CALL    0DF4

; call set_interrupt(05, 0a35, 0dab)
0B43:0D03 B005          MOV    AL,05
0B43:0D05 BA610B        MOV    DX,0DAB
0B43:0D08 BBEB07        MOV    BX,0A35
0B43:0D0B E8E600        CALL    0DF4

; call set_interrupt(07, 0a39, 0dc9)
0B43:0D0E B007          MOV    AL,07
0B43:0D10 BA7F0B        MOV    DX,0DC9
0B43:0D13 BBEF07        MOV    BX,0A39
0B43:0D16 E8DB00        CALL    0DF4

; cs:0bed is the address of this method

; call compute_absolute_address(cs, 0bed)
0B43:0D19 8CCA          MOV    DX,CS
0B43:0D1B B8A309        MOV    AX,0BED
0B43:0D1E E8BF00        CALL    0DE0

; call program_dma(0000, 49, dl,ax)
0B43:0D21 33C9          XOR    CX,CX                              
0B43:0D23 B649          MOV    DH,49                              
0B43:0D25 E88F00        CALL    0DB7

; set dx = 0x22c
0B43:0D28 2E            CS:                                       
0B43:0D29 8B16EF00      MOV    DX,[00EF]                          
0B43:0D2D 83C20C        ADD    DX,+0C

; set time constant (cmd 40) to 0x64 (100)

; call write_to_port(40, 022c)
0B43:0D30 B040          MOV    AL,40                              
0B43:0D32 E83AFF        CALL    0C6F                               

; call write_to_port(64, 022c)
0B43:0D35 B064          MOV    AL,64                              
0B43:0D37 E835FF        CALL    0C6F                               


; dma mode output, 0 bytes length
; this is a dummy playback just to trigger the irq callback

; call write_to_port(14, 022c)
0B43:0D3A B014          MOV    AL,14                              
0B43:0D3C E830FF        CALL    0C6F                               

; call write_to_port(00, 022c)
0B43:0D3F 32C0          XOR    AL,AL                              
0B43:0D41 E82BFF        CALL    0C6F                               

; call write_to_port(00, 022c)
0B43:0D44 32C0          XOR    AL,AL                              
0B43:0D46 E826FF        CALL    0C6F

; clear ax,cx
0B43:0D49 33C0          XOR    AX,AX                              
0B43:0D4B 31C9          XOR    CX,CX

; loop 64k times or until we get the sb irq
{
; halt (until we get an irq I guess?)
0B43:0D4D F4            HLT

; if irq 2/5/7 actually responded, jump to 0d5b
0B43:0D4E 2E            CS:
0B43:0D4F 803EFF0700    CMP    BYTE PTR [07FF],00
0B43:0D54 7505          JNZ    0D5B

; otherwise, loop back
0B43:0D56 E2F5          LOOP    0D4D
}

; we get here if one of our dummy irq’s responded
0B43:0D58 B80300        MOV    AX,0003

; store ax
0B43:0D5B 50            PUSH    AX

; call restore_interrupt(02, 0a2d)
0B43:0D5C B002          MOV    AL,02                              
0B43:0D5E BBE307        MOV    BX,0A2D                            
0B43:0D61 E8D700        CALL    0E3B

; call restore_interrupt(02, 0a31)
0B43:0D64 B005          MOV    AL,05                              
0B43:0D66 BBE707        MOV    BX,0A31                            
0B43:0D69 E8CF00        CALL    0E3B                               

; call restore_interrupt(02, 0a35)
0B43:0D6C B005          MOV    AL,05                              
0B43:0D6E BBEB07        MOV    BX,0A35                            
0B43:0D71 E8C700        CALL    0E3B                               

; call restore_interrupt(02, 0a39)
0B43:0D74 B007          MOV    AL,07                              
0B43:0D76 BBEF07        MOV    BX,0A39                            
0B43:0D79 E8BF00        CALL    0E3B

; restore ax
0B43:0D7C 58            POP    AX

; set flags and return
0B43:0D7D 0BC0          OR    AX,AX                              
0B43:0D7F C3            RET
}

get_dsp_version() - 0d80
{
; get dsp version (cmd e1)
; returns ax = 0 on success, 1 on failure

; call write_to_port(e1, 0x22c)
0B43:0D80 B0E1          MOV    AL,E1                              
0B43:0D82 2E            CS:                                       
0B43:0D83 8B16EF00      MOV    DX,[00EF]
0B43:0D87 80C20C        ADD    DL,0C
0B43:0D8A E8E2FE        CALL    0C6F

; read major version

; call 0c81
0B43:0D8D E8F1FE        CALL    0C81

; read minor version

; call 0c81
0B43:0D90 8AE0          MOV    AH,AL                              
0B43:0D92 E8ECFE        CALL    0C81

; set bx = 1 (failure)
0B43:0D95 BB0100        MOV    BX,0001

; if version < 1.1, jump to 0d9f
0B43:0D98 3D0101        CMP    AX,0101                            
0B43:0D9B 7202          JB    0D9F

; clear bx (success)
0B43:0D9D 33DB          XOR    BX,BX

; set ax = bx (return code)
0B43:0D9F 8BC3          MOV    AX,BX

; set flags
0B43:0DA1 0BC0          OR    AX,AX

0B43:0DA3 C3            RET
}

pause_dma_output() - 0da4
{
; pause dma output (cmd d0)

; call write_to_port(d0, 0x022c)
0B43:0DA4 2E            CS:                                       
0B43:0DA5 8B16EF00      MOV    DX,[00EF]                          
0B43:0DA9 80C20C        ADD    DL,0C                              
0B43:0DAC B0D0          MOV    AL,D0                              
0B43:0DAE E8BEFE        CALL    0C6F

; loop until write status is clear
{
0B43:0DB1 EC            IN    AL,DX                              
0B43:0DB2 0AC0          OR    AL,AL                              
0B43:0DB4 78FB          JS    0DB1
}

; return
0B43:0DB6 C3            RET
}

program_dma(cx,dh,dl,ax) – 0db7
{
; cx = word count
; dh = ?
; dl,ax = absolute address

0B43:0DB7 53            PUSH    BX

; set bx = ax
0B43:0DB8 8BD8          MOV    BX,AX

; write 05 to port 0x0a (single mask register),
; disables dma channel 1
0B43:0DBA B005          MOV    AL,05                              
0B43:0DBC E60A          OUT    0A,AL

; write 00 to port 0x0c (clear byte flip-flop)
0B43:0DBE 32C0          XOR    AL,AL                              
0B43:0DC0 E60C          OUT    0C,AL

; write dh to port 0x0b (mode: playback on dma 1)
0B43:0DC2 8AC6          MOV    AL,DH                              
0B43:0DC4 E60B          OUT    0B,AL

; write bl,bh to port 0x02 (dma 1 starting address)
0B43:0DC6 8AC3          MOV    AL,BL                              
0B43:0DC8 E602          OUT    02,AL
0B43:0DCA 8AC7          MOV    AL,BH                              
0B43:0DCC E602          OUT    02,AL

; write cl,ch to port 0x03 (dma 1 word count)
0B43:0DCE 8AC1          MOV    AL,CL                              
0B43:0DD0 E603          OUT    03,AL                              
0B43:0DD2 8AC5          MOV    AL,CH                              
0B43:0DD4 E603          OUT    03,AL

; write dl to port 0x83 (high-word starting address ?)
0B43:0DD6 8AC2          MOV    AL,DL                              
0B43:0DD8 E683          OUT    83,AL

; write 01 to port 0x0a (single mask register),
; enables dma channel 1
0B43:0DDA B001          MOV    AL,01                              
0B43:0DDC E60A          OUT    0A,AL

0B43:0DDE 5B            POP    BX                                 
0B43:0DDF C3            RET
}

compute_absolute_address(dx,ax) - 0de0
{
; dx = segment
; ax = offset
; returns absolute address in dx,ax

0B43:0DE0 51            PUSH    CX

; left-rotate segment by 4 bits
0B43:0DE1 B104          MOV    CL,04
0B43:0DE3 D3C2          ROL    DX,CL

; set cx = dx
0B43:0DE5 8BCA          MOV    CX,DX

; get first 4 bits (formerly last 4)
0B43:0DE7 83E20F        AND    DX,+0F

; remove those 4 bits from cx
0B43:0DEA 83E1F0        AND    CX,-10

; ax += cx
0B43:0DED 03C1          ADD    AX,CX

; dx += carry
0B43:0DEF 83D200        ADC    DX,+00

0B43:0DF2 59            POP    CX                                 
0B43:0DF3 C3            RET
}

set_interrupt(al,bx,dx) - 0df4
{
; al = irq number
; bx = address of backup for old interrupt
; dx = address of function to call

0B43:0DF4 53            PUSH    BX                                 
0B43:0DF5 51            PUSH    CX                                 
0B43:0DF6 52            PUSH    DX                                 
0B43:0DF7 9C            PUSHF

; clear interrupt flag
0B43:0DF8 FA            CLI

; set cl = al (interrupt)
0B43:0DF9 8AC8          MOV    CL,AL

; al += 8
0B43:0DFB 0408          ADD    AL,08

0B43:0DFD 98            CBW

0B43:0DFE D0E0          SHL    AL,1
0B43:0E00 D0E0          SHL    AL,1

; set di = ax
0B43:0E02 8BF8          MOV    DI,AX

; store es
0B43:0E04 06            PUSH    ES

; set ax,es to 0
; (es now points to the interrupt vector table)
0B43:0E05 33C0          XOR    AX,AX
0B43:0E07 8EC0          MOV    ES,AX

; save old interrupt vector to cs:bx

; set *cs:bx = *0000:di
0B43:0E09 26            ES:
0B43:0E0A 8B05          MOV    AX,[DI]
0B43:0E0C 2E            CS:
0B43:0E0D 8907          MOV    [BX],AX

; set *0000:di = dx
0B43:0E0F 26            ES:
0B43:0E10 8915          MOV    [DI],DX

; set *cs:bx+2 = *0000:di+2
0B43:0E12 26            ES:
0B43:0E13 8B4502        MOV    AX,[DI+02]
0B43:0E16 2E            CS:
0B43:0E17 894702        MOV    [BX+02],AX

; set *0000:di+2 = cs
0B43:0E1A 26            ES:
0B43:0E1B 8C4D02        MOV    [DI+02],CS

; restore es
0B43:0E1E 07            POP    ES

; set ah = 01
0B43:0E1F B401          MOV    AH,01

; shift by interrupt vector
0B43:0E21 D2E4          SHL    AH,CL

; invert to mask
0B43:0E23 F6D4          NOT    AH

; read from 0x21
0B43:0E25 E421          IN    AL,21

0B43:0E27 53            PUSH    BX
0B43:0E28 8AD9          MOV    BL,CL
0B43:0E2A 32FF          XOR    BH,BH
0B43:0E2C 2E            CS:
0B43:0E2D 88870B08      MOV    [BX+080B],AL
0B43:0E31 5B            POP    BX
0B43:0E32 22C4          AND    AL,AH
0B43:0E34 E621          OUT    21,AL

0B43:0E36 9D            POPF
0B43:0E37 5A            POP    DX
0B43:0E38 59            POP    CX
0B43:0E39 5B            POP    BX
0B43:0E3A C3            RET
}

restore_interrupt() – 0e3b
{
0B43:0E3B 9C            PUSHF                                       
0B43:0E3C FA            CLI                                       
0B43:0E3D 8AC8          MOV    CL,AL                              
0B43:0E3F 0408          ADD    AL,08                              
0B43:0E41 98            CBW                                       
0B43:0E42 D0E0          SHL    AL,1                               
0B43:0E44 D0E0          SHL    AL,1                               
0B43:0E46 8BF8          MOV    DI,AX                              
0B43:0E48 06            PUSH    ES                                 
0B43:0E49 33C0          XOR    AX,AX                              
0B43:0E4B 8EC0          MOV    ES,AX                              
0B43:0E4D 2E            CS:                                       
0B43:0E4E 8B07          MOV    AX,[BX]                            
0B43:0E50 26            ES:                                       
0B43:0E51 8905          MOV    [DI],AX                            
0B43:0E53 2E            CS:                                       
0B43:0E54 8B4702        MOV    AX,[BX+02]                         
0B43:0E57 26            ES:                                       
0B43:0E58 894502        MOV    [DI+02],AX                         
0B43:0E5B 07            POP    ES                                 
0B43:0E5C B401          MOV    AH,01                              
0B43:0E5E D2E4          SHL    AH,CL                              
0B43:0E60 53            PUSH    BX                                 
0B43:0E61 8AD9          MOV    BL,CL                              
0B43:0E63 32FF          XOR    BH,BH                              
0B43:0E65 2E            CS:                                       
0B43:0E66 8A870B08      MOV    AL,[BX+080B]                       
0B43:0E6A 5B            POP    BX                                 
0B43:0E6B E621          OUT    21,AL                              
0B43:0E6D 9D            POPF                                       
0B43:0E6E C3            RET
}

dummy_irq_2() - 0e6f
{
0B43:0E6F 52            PUSH    DX                                 
0B43:0E70 50            PUSH    AX                                 
0B43:0E71 52            PUSH    DX

; set ds = cs
0B43:0E72 8CC8          MOV    AX,CS
0B43:0E74 8ED8          MOV    DS,AX

; set dx = *cs:00ef (sb port 0x220)
0B43:0E76 2E            CS:                                       
0B43:0E77 8B16EF00      MOV    DX,[00EF]

; port offset 0x0e
0B43:0E7B 83C20E        ADD    DX,+0E

; read from 0x22e
0B43:0E7E EC            IN    AL,DX

; set *07ff = 02
0B43:0E7F 2E            CS:                                       
0B43:0E80 C606FF0702    MOV    BYTE PTR [07FF],02

; write 20 to port 20 ?
0B43:0E85 B020          MOV    AL,20                              
0B43:0E87 E620          OUT    20,AL

0B43:0E89 5A            POP    DX                                 
0B43:0E8A 58            POP    AX                                 
0B43:0E8B 5A            POP    DX                                 
0B43:0E8C CF            IRET
}

dummy_irq_5() - 0e8d
{
0B43:0E8D 1E            PUSH    DS                                 
0B43:0E8E 50            PUSH    AX                                 
0B43:0E8F 52            PUSH    DX                                 
0B43:0E90 8CC8          MOV    AX,CS                              
0B43:0E92 8ED8          MOV    DS,AX                              
0B43:0E94 2E            CS:                                       
0B43:0E95 8B16EF00      MOV    DX,[00EF]                          
0B43:0E99 83C20E        ADD    DX,+0E                             
0B43:0E9C EC            IN    AL,DX                              
0B43:0E9D 2E            CS:                                       
0B43:0E9E C606FF0705    MOV    BYTE PTR [07FF],05                 
0B43:0EA3 B020          MOV    AL,20                              
0B43:0EA5 E620          OUT    20,AL                              
0B43:0EA7 5A            POP    DX                                 
0B43:0EA8 58            POP    AX                                 
0B43:0EA9 5A            POP    DX                                 
0B43:0EAA CF            IRET
}

dummy_irq_5() – 0eab
{
0B43:0EAB 1E            PUSH    DS                                 
0B43:0EAC 50            PUSH    AX                                 
0B43:0EAD 52            PUSH    DX                                 
0B43:0EAE 8CC8          MOV    AX,CS                              
0B43:0EB0 8ED8          MOV    DS,AX                              
0B43:0EB2 2E            CS:                                       
0B43:0EB3 8B16EF00      MOV    DX,[00EF]                          
0B43:0EB7 83C20E        ADD    DX,+0E                             
0B43:0EBA EC            IN    AL,DX                              
0B43:0EBB 2E            CS:                                       
0B43:0EBC C606FF0705    MOV    BYTE PTR [07FF],05                 
0B43:0EC1 B020          MOV    AL,20                              
0B43:0EC3 E620          OUT    20,AL                              
0B43:0EC5 5A            POP    DX                                 
0B43:0EC6 58            POP    AX                                 
0B43:0EC7 5A            POP    DX                                 
0B43:0EC8 CF            IRET
}

dummy_irq_7() – 0ec9
{
0B43:0EC9 1E            PUSH    DS                                 
0B43:0ECA 50            PUSH    AX                                 
0B43:0ECB 52            PUSH    DX                                 
0B43:0ECC 8CC8          MOV    AX,CS                              
0B43:0ECE 8ED8          MOV    DS,AX                              
0B43:0ED0 2E            CS:                                       
0B43:0ED1 8B16EF00      MOV    DX,[00EF]                          
0B43:0ED5 83C20E        ADD    DX,+0E                             
0B43:0ED8 EC            IN    AL,DX                              
0B43:0ED9 2E            CS:                                       
0B43:0EDA C606FF0707    MOV    BYTE PTR [07FF],07                 
0B43:0EDF B020          MOV    AL,20                              
0B43:0EE1 E620          OUT    20,AL                              
0B43:0EE3 5A            POP    DX                                 
0B43:0EE4 58            POP    AX                                 
0B43:0EE5 5A            POP    DX                                 
0B43:0EE6 CF            IRET
}

sb_irq_handler() – 0ee7
{
0B43:0EE7 1E            PUSH    DS                                 
0B43:0EE8 06            PUSH    ES                                 
0B43:0EE9 50            PUSH    AX                                 
0B43:0EEA 53            PUSH    BX                                 
0B43:0EEB 51            PUSH    CX                                 
0B43:0EEC 52            PUSH    DX                                 
0B43:0EED 57            PUSH    DI                                 
0B43:0EEE 56            PUSH    SI                                 
0B43:0EEF 55            PUSH    BP                                 
0B43:0EF0 9C            PUSHF

; clear interrupt & d flags
0B43:0EF1 FA            CLI
0B43:0EF2 FC            CLD

; set es = ds = cx
0B43:0EF3 8CC8          MOV    AX,CS                              
0B43:0EF5 8ED8          MOV    DS,AX                              
0B43:0EF7 8EC0          MOV    ES,AX

; write 0x20 to port 0x20
0B43:0EF9 B020          MOV    AL,20                              
0B43:0EFB E620          OUT    20,AL

; if *cs:07d0 != 02, return
0B43:0EFD 2E            CS:                                       
0B43:0EFE 803ED00702    CMP    BYTE PTR [07D0],02                 
0B43:0F03 7519          JNZ    0F1E

; set ax = *cs:07f9
0B43:0F05 2E            CS:                                       
0B43:0F06 A1F907        MOV    AX,[07F9]

; if ax != 0, jump to 0f12
0B43:0F09 0BC0          OR    AX,AX                              
0B43:0F0B 7505          JNZ    0F12

; call 0f9e
0B43:0F0D E88E00        CALL    0F9E                               

; jump to 0f15
0B43:0F10 EB03          JMP    0F15

; call dma_output()
0B43:0F12 E81400        CALL    0F29                               

; read (and return) byte from 0x22e (interrupt ack)
0B43:0F15 2E            CS:
0B43:0F16 8B16EF00      MOV    DX,[00EF]                          
0B43:0F1A 80C20E        ADD    DL,0E                              
0B43:0F1D EC            IN    AL,DX

; return
0B43:0F1E 9D            POPF                                       
0B43:0F1F 5D            POP    BP                                 
0B43:0F20 5E            POP    SI                                 
0B43:0F21 5F            POP    DI                                 
0B43:0F22 5A            POP    DX                                 
0B43:0F23 59            POP    CX                                 
0B43:0F24 5B            POP    BX                                 
0B43:0F25 58            POP    AX                                 
0B43:0F26 07            POP    ES                                 
0B43:0F27 1F            POP    DS                                 
0B43:0F28 CF            IRET
}

dma_output() - 0f29
{
; set cx = ffff
0B43:0F29 B9FFFF        MOV    CX,FFFF

; if *07f8 != 0, jump to 0f3e
0B43:0F2C 2E            CS:                                       
0B43:0F2D 803EF80700    CMP    BYTE PTR [07F8],00                 
0B43:0F32 750A          JNZ    0F3E

; *07f8++
0B43:0F34 2E            CS:                                       
0B43:0F35 FE06F807      INC    BYTE PTR [07F8]                    
0B43:0F39 2E            CS:                                       
0B43:0F3A 8B0EFD07      MOV    CX,[07FD]

; cx -= *07f4
0B43:0F3E 2E            CS:                                       
0B43:0F3F 2B0EF407      SUB    CX,[07F4]

; set *07f6 = cx
0B43:0F43 2E            CS:                                       
0B43:0F44 890EF607      MOV    [07F6],CX

; cx++
0B43:0F48 41            INC    CX

0B43:0F49 740D          JZ    0F58                               
0B43:0F4B 2E            CS:                                       
0B43:0F4C 290EF907      SUB    [07F9],CX                          
0B43:0F50 2E            CS:                                       
0B43:0F51 831EFB0700    SBB    WORD PTR [07FB],+00                
0B43:0F56 EB05          JMP    0F5D                               
0B43:0F58 2E            CS:                                       
0B43:0F59 FF0EFB07      DEC    WORD PTR [07FB]                    
0B43:0F5D B649          MOV    DH,49                              
0B43:0F5F 2E            CS:                                       
0B43:0F60 8A16F307      MOV    DL,[07F3]                          
0B43:0F64 2E            CS:                                       
0B43:0F65 A1F407        MOV    AX,[07F4]                          
0B43:0F68 2E            CS:                                       
0B43:0F69 8B0EF607      MOV    CX,[07F6]

; call 0db7
0B43:0F6D E847FE        CALL    0DB7

0B43:0F70 2E            CS:                                       
0B43:0F71 FE0EF807      DEC    BYTE PTR [07F8]                    
0B43:0F75 2E            CS:                                       
0B43:0F76 FE06F307      INC    BYTE PTR [07F3]                    
0B43:0F7A 2E            CS:                                       
0B43:0F7B C706F4070000  MOV    WORD PTR [07F4],0000

; set cx = cs:*07f6 (size of audio data)
0B43:0F81 2E            CS:                                       
0B43:0F82 8B0EF607      MOV    CX,[07F6]

; set dx = 022c
0B43:0F86 2E            CS:                                       
0B43:0F87 8B16EF00      MOV    DX,[00EF]                          
0B43:0F8B 80C20C        ADD    DL,0C

; dma output (cmd 14)

; call write_to_port(14, 022c)
0B43:0F8E B014          MOV    AL,14                              
0B43:0F90 E8DCFC        CALL    0C6F

; send length (lo-byte)

; call write to port(cl, 022c)
0B43:0F93 8AC1          MOV    AL,CL                              
0B43:0F95 E8D7FC        CALL    0C6F

; send length (hi-byte)

; call write_to_port(ch, 022c)
0B43:0F98 8AC5          MOV    AL,CH                              
0B43:0F9A E8D2FC        CALL    0C6F

; when do we send the actual data ???

; return
0B43:0F9D C3            RET
}

0f9e
{
; if *07d2 != 0, jump to 1016
0B43:0F9E 2E            CS:                                       
0B43:0F9F 803ED20700    CMP    BYTE PTR [07D2],00                 
0B43:0FA4 7402          JZ    0FA8
0B43:0FA6 EB6E          JMP    1016

; if *07d1 != 0, jump to 0feb
0B43:0FA8 2E            CS:                                       
0B43:0FA9 803ED10700    CMP    BYTE PTR [07D1],00                 
0B43:0FAE 753B          JNZ    0FEB

; if *07dd == 0, jump to 1016
0B43:0FB0 2E            CS:                                       
0B43:0FB1 833EDD0700    CMP    WORD PTR [07DD],+00                
0B43:0FB6 7502          JNZ    0FBA
0B43:0FB8 EB5C          JMP    1016

; set *07d2 = 01
0B43:0FBA 2E            CS:                                       
0B43:0FBB C606D20701    MOV    BYTE PTR [07D2],01

0B43:0FC0 1E            PUSH    DS                                 
0B43:0FC1 50            PUSH    AX                                 
0B43:0FC2 53            PUSH    BX

; set *0809 = *07dd
0B43:0FC3 2E            CS:                                       
0B43:0FC4 A1DD07        MOV    AX,[07DD]                          
0B43:0FC7 2E            CS:                                       
0B43:0FC8 A30908        MOV    [0809],AX

; set bx = 07d9
0B43:0FCB 2E            CS:                                       
0B43:0FCC C51ED907      LDS    BX,[07D9]

; set *0805,*0807 = ds,bx
0B43:0FD0 2E            CS:                                       
0B43:0FD1 8C1E0508      MOV    [0805],DS                          
0B43:0FD5 2E            CS:                                       
0B43:0FD6 891E0708      MOV    [0807],BX

; set *0800 = 0000
0B43:0FDA 2E            CS:                                       
0B43:0FDB C70600080000  MOV    WORD PTR [0800],0000

; set *07d0 = 01
0B43:0FE1 2E            CS:                                       
0B43:0FE2 C606D00701    MOV    BYTE PTR [07D0],01

0B43:0FE7 5B            POP    BX                                 
0B43:0FE8 58            POP    AX                                 
0B43:0FE9 1F            POP    DS                                 
0B43:0FEA C3            RET

0B43:0FEB 1E            PUSH    DS                                 
0B43:0FEC 50            PUSH    AX                                 
0B43:0FED 53            PUSH    BX                                 
0B43:0FEE 2E            CS:                                       
0B43:0FEF A1D707        MOV    AX,[07D7]                          
0B43:0FF2 2E            CS:                                       
0B43:0FF3 A30908        MOV    [0809],AX                          
0B43:0FF6 2E            CS:                                       
0B43:0FF7 C51ED307      LDS    BX,[07D3]                          
0B43:0FFB 2E            CS:                                       
0B43:0FFC 8C1E0508      MOV    [0805],DS                          
0B43:1000 2E            CS:                                       
0B43:1001 891E0708      MOV    [0807],BX                          
0B43:1005 2E            CS:                                       
0B43:1006 C70600080000  MOV    WORD PTR [0800],0000               
0B43:100C 2E            CS:                                       
0B43:100D C606D00701    MOV    BYTE PTR [07D0],01                 
0B43:1012 5B            POP    BX                                 
0B43:1013 58            POP    AX                                 
0B43:1014 1F            POP    DS                                 
0B43:1015 C3            RET

0B43:1016 B005          MOV    AL,05                              
0B43:1018 E60A          OUT    0A,AL

; call restore_interrupt(*07ff, 0a29)
0B43:101A 2E            CS:                                       
0B43:101B A0FF07        MOV    AL,[07FF]                          
0B43:101E BBDF07        MOV    BX,07DF                            
0B43:1021 E817FE        CALL    0E3B

0B43:1024 2E            CS:                                       
0B43:1025 C70600080000  MOV    WORD PTR [0800],0000

; read byte from 0x022e (int ack & read status)
0B43:102B 2E            CS:                                       
0B43:102C 8B16EF00      MOV    DX,[00EF]                          
0B43:1030 80C20E        ADD    DL,0E

0B43:1033 EC            IN    AL,DX

0B43:1034 C3            RET
}

init_sb() - 1035
{
0B43:1035 1E            PUSH    DS                                 
0B43:1036 06            PUSH    ES                                 
0B43:1037 57            PUSH    DI                                 
0B43:1038 56            PUSH    SI

; set es = ds = cs
0B43:1039 8CC8          MOV    AX,CS
0B43:103B 8ED8          MOV    DS,AX
0B43:103D 8EC0          MOV    ES,AX

; call reset_dsp()
0B43:103F E855FC        CALL    0C97

; if failure, return
0B43:1042 7516          JNZ    105A

; call 0cc4
0B43:1044 E87DFC        CALL    0CC4

; if failure, return
0B43:1047 7511          JNZ    105A

; call get_dsp_version()
0B43:1049 E834FD        CALL    0D80

; if failure, return
0B43:104C 750C          JNZ    105A

; call determine_sb_irq()
0B43:104E E89CFC        CALL    0CED                               
0B43:1051 7507          JNZ    105A

; turn on speaker

; call toggle_speaker(01)
0B43:1053 B001          MOV    AL,01                              
0B43:1055 E81B00        CALL    1073

; clear ax (to indicate success)
0B43:1058 33C0          XOR    AX,AX

0B43:105A 5E            POP    SI                                 
0B43:105B 5F            POP    DI                                 
0B43:105C 07            POP    ES                                 
0B43:105D 1F            POP    DS                                 
0B43:105E C3            RET
}

toggle_speaker_wrapper(al) - 105f
{
; al = zero to turn off speaker,
;      non-zero to turn on speaker

0B43:105F 1E            PUSH    DS                                 
0B43:1060 06            PUSH    ES                                 
0B43:1061 56            PUSH    SI                                 
0B43:1062 57            PUSH    DI                                 
0B43:1063 50            PUSH    AX                                 
0B43:1064 53            PUSH    BX                                 
0B43:1065 51            PUSH    CX                                 
0B43:1066 52            PUSH    DX

; call toggle_speaker(al)
0B43:1067 E80900        CALL    1073

0B43:106A 5A            POP    DX                                 
0B43:106B 59            POP    CX                                 
0B43:106C 5B            POP    BX                                 
0B43:106D 58            POP    AX                                 
0B43:106E 5F            POP    DI                                 
0B43:106F 5E            POP    SI                                 
0B43:1070 07            POP    ES                                 
0B43:1071 1F            POP    DS                                 
0B43:1072 C3            RET
}

toggle_speaker(al) - 1073
{
; al = zero to turn off speaker,
;      non-zero to turn on speaker

; set dx = 0x022c
0B43:1073 2E            CS:                                       
0B43:1074 8B16EF00      MOV    DX,[00EF]                          
0B43:1078 83C20C        ADD    DX,+0C

; set ah = d1 (turn on speaker cmd)
0B43:107B B4D1          MOV    AH,D1                              

; if al != 0, jump to 1083
0B43:107D 0AC0          OR    AL,AL
0B43:107F 7502          JNZ    1083

; set ah = d3 (turn off speaker cmd)
0B43:1081 B4D3          MOV    AH,D3

; set al = ah
0B43:1083 8AC4          MOV    AL,AH

; call write_to_port(d3, 0x022c)
0B43:1085 E8E7FB        CALL    0C6F

; clear ax
0B43:1088 33C0          XOR    AX,AX

0B43:108A C3            RET
}

108b
{
0B43:108B 53            PUSH    BX                                 
0B43:108C 51            PUSH    CX                                 
0B43:108D 52            PUSH    DX                                 
0B43:108E 1E            PUSH    DS                                 
0B43:108F 06            PUSH    ES                                 
0B43:1090 57            PUSH    DI                                 
0B43:1091 56            PUSH    SI

; set es = ds = cs
0B43:1092 8CC8          MOV    AX,CS                              
0B43:1094 8ED8          MOV    DS,AX                              
0B43:1096 8EC0          MOV    ES,AX

; if *0800 == 00, jump to 10a6
0B43:1098 2E            CS:                                       
0B43:1099 833E000800    CMP    WORD PTR [0800],+00                
0B43:109E 7406          JZ    10A6

; set ax = 1 (failure) and return
0B43:10A0 B80100        MOV    AX,0001                            
0B43:10A3 E98000        JMP    1126


; set *0800 = 01
0B43:10A6 2E            CS:                                       
0B43:10A7 C70600080100  MOV    WORD PTR [0800],0001               

; set dx = 022c
0B43:10AD 2E            CS:                                       
0B43:10AE 8B16EF00      MOV    DX,[00EF]                          
0B43:10B2 80C20C        ADD    DL,0C

; set cl = *cs:0804 (timer constant)
0B43:10B5 2E            CS:                                       
0B43:10B6 8A0E0408      MOV    CL,[0804]

; set dx = 022c
0B43:10BA 2E            CS:                                       
0B43:10BB 8B16EF00      MOV    DX,[00EF]                          
0B43:10BF 80C20C        ADD    DL,0C

; set the timer constant

; call write_to_port(40, 0x022c)
0B43:10C2 B040          MOV    AL,40                              
0B43:10C4 E8A8FB        CALL    0C6F

; call write_to_port(cl, 0x022c)
0B43:10C7 8AC1          MOV    AL,CL                              
0B43:10C9 E8A3FB        CALL    0C6F                               

; 07ff is the sb irq

; call set_interrupt(*cs:07ff, 07df, 0b9d)
0B43:10CC 2E            CS:
0B43:10CD A0FF07        MOV    AL,[0A49]                          
0B43:10D0 BA9D0B        MOV    DX,0DE7
0B43:10D3 BBDF07        MOV    BX,0A29                            
0B43:10D6 E81BFD        CALL    0DF4

; I think 0805,0807 is the address of the sample

; call compute_absolute_address(*0805, *0807,)
0B43:10D9 2E            CS:                                       
0B43:10DA 8B160508      MOV    DX,[0805]                          
0B43:10DE 2E            CS:                                       
0B43:10DF A10708        MOV    AX,[0807]                          
0B43:10E2 E8FBFC        CALL    0DE0

0B43:10E5 2E            CS:                                       
0B43:10E6 8816F307      MOV    [07F3],DL                          
0B43:10EA 2E            CS:                                       
0B43:10EB A3F407        MOV    [07F4],AX                          
0B43:10EE 2E            CS:                                       
0B43:10EF 8B0E0908      MOV    CX,[0809]                          
0B43:10F3 2E            CS:                                       
0B43:10F4 890EF907      MOV    [07F9],CX                          
0B43:10F8 2E            CS:                                       
0B43:10F9 C706FB070000  MOV    WORD PTR [07FB],0000               
0B43:10FF 2E            CS:                                       
0B43:1100 03060908      ADD    AX,[0809]                          
0B43:1104 80D200        ADC    DL,00                              
0B43:1107 2D0100        SUB    AX,0001                            
0B43:110A 80DA00        SBB    DL,00                              
0B43:110D 2E            CS:                                       
0B43:110E A3FD07        MOV    [07FD],AX                          
0B43:1111 2E            CS:                                       
0B43:1112 2A16F307      SUB    DL,[07F3]                          

0B43:1116 2E            CS:                                       
0B43:1117 8816F807      MOV    [07F8],DL                          

; call dma_output()
0B43:111B E80BFE        CALL    0F29

; set *cs:07d0 = 02 (sample played ???)
0B43:111E 2E            CS:                                       
0B43:111F C606D00702    MOV    BYTE PTR [07D0],02

; clear ax
0B43:1124 33C0          XOR    AX,AX

0B43:1126 5E            POP    SI                                 
0B43:1127 5F            POP    DI                                 
0B43:1128 07            POP    ES                                 
0B43:1129 1F            POP    DS                                 
0B43:112A 5A            POP    DX                                 
0B43:112B 59            POP    CX                                 
0B43:112C 5B            POP    BX                                 
0B43:112D C3            RET
}

112e
{
0B43:112E 50            PUSH    AX                                 
0B43:112F 53            PUSH    BX                                 
0B43:1130 51            PUSH    CX                                 
0B43:1131 52            PUSH    DX                                 
0B43:1132 1E            PUSH    DS                                 
0B43:1133 06            PUSH    ES                                 
0B43:1134 57            PUSH    DI                                 
0B43:1135 56            PUSH    SI                                 
0B43:1136 8CC8          MOV    AX,CS                              
0B43:1138 8ED8          MOV    DS,AX                              
0B43:113A 8EC0          MOV    ES,AX                              
0B43:113C B80100        MOV    AX,0001                            
0B43:113F 2E            CS:                                       
0B43:1140 833E000800    CMP    WORD PTR [0800],+00                
0B43:1145 740E          JZ    1155

; call pause_dma_output()
0B43:1147 E85AFC        CALL    0DA4

; call 0f9e
0B43:114A E851FE        CALL    0F9E

0B43:114D 2E            CS:                                       
0B43:114E C606D00700    MOV    BYTE PTR [07D0],00                 
0B43:1153 33C0          XOR    AX,AX                              
0B43:1155 5E            POP    SI                                 
0B43:1156 5F            POP    DI                                 
0B43:1157 07            POP    ES                                 
0B43:1158 1F            POP    DS                                 
0B43:1159 5A            POP    DX                                 
0B43:115A 59            POP    CX                                 
0B43:115B 5B            POP    BX                                 
0B43:115C 58            POP    AX                                 
0B43:115D C3            RET
}

0B43:115E 1E            PUSH    DS                                 
0B43:115F 06            PUSH    ES                                 
0B43:1160 57            PUSH    DI                                 
0B43:1161 56            PUSH    SI                                 
0B43:1162 8CC8          MOV    AX,CS                              
0B43:1164 8ED8          MOV    DS,AX                              
0B43:1166 8EC0          MOV    ES,AX                              
0B43:1168 B80100        MOV    AX,0001                            
0B43:116B 2E            CS:                                       
0B43:116C 833E000801    CMP    WORD PTR [0800],+01                
0B43:1171 750B          JNZ    117E                               
0B43:1173 E82EFC        CALL    0DA4                               
0B43:1176 2E            CS:                                       
0B43:1177 C606D00704    MOV    BYTE PTR [07D0],04                 
0B43:117C 33C0          XOR    AX,AX                              
0B43:117E 5E            POP    SI                                 
0B43:117F 5F            POP    DI                                 
0B43:1180 07            POP    ES                                 
0B43:1181 1F            POP    DS                                 
0B43:1182 C3            RET                                       
0B43:1183 1E            PUSH    DS                                 
0B43:1184 06            PUSH    ES                                 
0B43:1185 57            PUSH    DI                                 
0B43:1186 56            PUSH    SI                                 
0B43:1187 8CC8          MOV    AX,CS                              
0B43:1189 8ED8          MOV    DS,AX                              
0B43:118B 8EC0          MOV    ES,AX                              
0B43:118D B80100        MOV    AX,0001                            
0B43:1190 2E            CS:                                       
0B43:1191 833E000801    CMP    WORD PTR [0800],+01                
0B43:1196 7515          JNZ    11AD                               
0B43:1198 2E            CS:                                       
0B43:1199 8B16EF00      MOV    DX,[00EF]                          
0B43:119D 80C20C        ADD    DL,0C                              
0B43:11A0 B0D4          MOV    AL,D4                              
0B43:11A2 E8CAFA        CALL    0C6F                               
0B43:11A5 2E            CS:                                       
0B43:11A6 C606D00702    MOV    BYTE PTR [07D0],02                 
0B43:11AB 33C0          XOR    AX,AX                              
0B43:11AD 5E            POP    SI                                 
0B43:11AE 5F            POP    DI                                 
0B43:11AF 07            POP    ES                                 
0B43:11B0 1F            POP    DS                                 
0B43:11B1 C3            RET                                       

; port cs:10b2 = 220
0B43:11B2 2002          AND    [BP+SI],AL                         

my_init_device() – 11b4
{
; call init_device()
11b4    call 0a84

; call init_sb()
11b7    call 1035

; if return value success, jump to 11c4
11ba    cmp ax,0000
11bd    jz 11c4

; otherwise, set ax = ffff and jump to 11c7
11bf    mov ax,ffff
11c2    jmp 11c7

; set ax = address of this function
11c4    mov ax,10b4

; set cx = 0801
11c7    mov cx,0801

; return
11ca    ret
}

/* Work Log */

   1 Renamed GENMIDI.DRV to GMBLAST.DRV
   2 Created and ran mkgmblast.c which copies the DSP-handling code from MTBLAST.DRV 
     and appends it to GMBLAST.DRV
   3 Created this document with MS-DOS debug.  Debug loads the program to offset 
     0x0100, so the code segment is 0x0100 greater than it should be.  Need to keep 
     this in mind when synching addresses accessed by absolute address (in brackets) 
     and those by relative address (as in jmp and call).
   4 Changed offset 0x00EF to 0x010B2.  This is the location to store the SB I/O port 
     base address.  (0x0220)
   5 Changed offsets 0x015E and 0x0160 to 0x04C2 and 0x04C3, respectively, based on 
     how they were used in MTBLAST and GENMIDI.  No idea what these do!  In the SB 
     code, they are only used in load_sample().
   6 Manually updated all memory offsets accessed by absolute address (in brackets).  
     The offsets are 0x024A greater in GMBLAST.DRV than they were in MTBLAST.DRV.
   7 Manually updated memory offsets accessed via indirect mode (e.g. stored in a 
     register).  These lines are highlighted in dark red.
   8 (Undocumented) Created some wrappers around load/stop/play sample which write to 
     a logfile, “LOG”.  This will be truncated in the final version and is not 
     documented in the code above.
   9 Found the interrupt handler code and corrected their memory offsets so the 
     correct values go into the interrupt vector table.  These lines are highlighted 
     in light red.
  10 Created my_init_device() at 0x10c7 (0x11c7 in debug) which initializes the sb 
     for output according to MTBLAST.
  11 Found another missed memory offset in determine_sb_irq(), highlighted in green.
  12 Worked properly after logging code was removed.  Apparently, it adversely 
     affected the timing of the sound output.

Status – working & complete