2023-03-09 21:35:56 -08:00
|
|
|
|
;<3B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
|
|
|
|
|
Proc SetGUSRegisters ; Given DS:SI, CX
|
|
|
|
|
|
|
|
|
|
Mov ES, CS:SongDataArea
|
|
|
|
|
|
|
|
|
|
Push CX
|
|
|
|
|
Push SI
|
|
|
|
|
|
|
|
|
|
Xor AX, AX
|
|
|
|
|
|
|
|
|
|
GetOffsetLoop:
|
|
|
|
|
Push AX
|
|
|
|
|
Push CX
|
|
|
|
|
|
|
|
|
|
Mov DX, GUSVoiceSelect
|
|
|
|
|
Out DX, AL ; OK.. now to play with this
|
|
|
|
|
; voice.
|
|
|
|
|
Call GUSDelay
|
|
|
|
|
|
|
|
|
|
Inc DL ; DX = select rego
|
|
|
|
|
|
|
|
|
|
Mov BX, [SI]
|
|
|
|
|
Test BH, 2
|
|
|
|
|
JZ GetOffsetLoop2
|
|
|
|
|
|
|
|
|
|
Mov BX, 200h
|
|
|
|
|
Mov [SI], BX
|
|
|
|
|
|
|
|
|
|
GetOffsetLoop2:
|
|
|
|
|
Test BL, 1 ; Channel not on!
|
|
|
|
|
JZ GetOffsetLoop1
|
|
|
|
|
Test BH, 1
|
|
|
|
|
JZ GetOffsetLoop3 ; Prev 1.
|
|
|
|
|
|
|
|
|
|
Xor BX, BX
|
|
|
|
|
Call SetGUSVolume
|
|
|
|
|
|
|
|
|
|
Mov AL, 80h
|
|
|
|
|
Out DX, AL
|
|
|
|
|
Add DL, 2
|
|
|
|
|
In AL, DX
|
|
|
|
|
Sub DL, 2
|
|
|
|
|
Mov AH, AL
|
|
|
|
|
And AX, 400h
|
|
|
|
|
Out DX, AL ; AL = 0 (Mode control)
|
|
|
|
|
Mov AL, 3
|
|
|
|
|
Or AL, AH
|
|
|
|
|
Add DL, 2
|
|
|
|
|
Out DX, AL
|
|
|
|
|
Call GUSDelay
|
|
|
|
|
Out DX, AL
|
|
|
|
|
Sub DL, 2
|
|
|
|
|
|
|
|
|
|
Jmp GetOffsetLoop1
|
|
|
|
|
|
|
|
|
|
GetOffsetLoop3:
|
|
|
|
|
Mov EAX, [SI+4Ch]
|
|
|
|
|
Mov [SI+2Ch], EAX
|
|
|
|
|
|
|
|
|
|
Mov AL, 8Ah
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
Inc DX
|
|
|
|
|
In AX, DX
|
|
|
|
|
Dec DX
|
|
|
|
|
|
|
|
|
|
And AH, 31
|
|
|
|
|
ShL EAX, 16 ; Load high part of EAX
|
|
|
|
|
|
|
|
|
|
Mov AL, 8Bh
|
|
|
|
|
Out DX, AL
|
|
|
|
|
Inc DX
|
|
|
|
|
In AX, DX
|
|
|
|
|
; EAX = 000OOOOO OOOOOOOO OOOOOOOF FFFFFFFF
|
|
|
|
|
; Need: 00000000 0000OOOO OOOOOOOO OOOOOOOO
|
|
|
|
|
|
|
|
|
|
ShR EAX, 9
|
|
|
|
|
; EAX contains current loc.
|
|
|
|
|
; Convert to Offset (in sample)
|
|
|
|
|
MovZX EBX, Byte Ptr [SI+36h]
|
|
|
|
|
Sub EAX, [CS:GUSDataTable+EBX*4]
|
|
|
|
|
Push CX
|
|
|
|
|
|
|
|
|
|
Mov CL, CS:Compress
|
|
|
|
|
ShL EAX, CL
|
|
|
|
|
|
|
|
|
|
Pop CX
|
|
|
|
|
Mov [SI+4Ch], EAX
|
|
|
|
|
|
|
|
|
|
GetOffsetLoop1:
|
|
|
|
|
Add SI, SLAVECHANNELSIZE
|
|
|
|
|
|
|
|
|
|
Pop CX
|
|
|
|
|
Pop AX
|
|
|
|
|
|
|
|
|
|
Inc AX
|
|
|
|
|
Loop GetOffsetLoop
|
|
|
|
|
|
|
|
|
|
Pop SI
|
|
|
|
|
Pop CX
|
|
|
|
|
|
|
|
|
|
Xor AX, AX
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters1:
|
|
|
|
|
Push AX
|
|
|
|
|
Push CX
|
|
|
|
|
|
|
|
|
|
Mov DX, GUSVoiceSelect
|
|
|
|
|
Out DX, AL ; OK.. now to play with this
|
|
|
|
|
; voice.
|
|
|
|
|
Call GUSDelay
|
|
|
|
|
|
|
|
|
|
Mov CX, [SI] ; CX = flags.
|
|
|
|
|
Inc DL ; DX = select rego
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters21:
|
|
|
|
|
Test CL, 32 ; Frequency change
|
|
|
|
|
JZ SetGUSRegisters7
|
|
|
|
|
|
|
|
|
|
Push DX
|
|
|
|
|
|
|
|
|
|
Mov EAX, [SI+10h] ; EAX = freq.
|
|
|
|
|
|
|
|
|
|
Push CX
|
|
|
|
|
Mov CL, CS:Compress
|
|
|
|
|
ShR EAX, CL
|
|
|
|
|
Pop CX
|
|
|
|
|
|
|
|
|
|
Xor EDX, EDX
|
|
|
|
|
MovZX EBX, MixSpeed
|
|
|
|
|
|
|
|
|
|
Div EBX ; EAX = I portion.
|
|
|
|
|
|
|
|
|
|
Test EAX, Not 63
|
|
|
|
|
JNZ SetGUSRegisters6
|
|
|
|
|
|
|
|
|
|
Push EAX
|
|
|
|
|
|
|
|
|
|
Xor EAX, EAX
|
|
|
|
|
Div EBX
|
|
|
|
|
|
|
|
|
|
Pop EBX ; EBX:EAX = IIII FFFF etc.
|
|
|
|
|
|
|
|
|
|
SHRD EAX, EBX, 6
|
|
|
|
|
|
|
|
|
|
; Have: IIIIIIII IIIIIIII FFFFFFFF FFFFFFFF
|
|
|
|
|
; Req: IIIIIIFF FFFFFFF0
|
|
|
|
|
|
|
|
|
|
Pop DX
|
|
|
|
|
Mov AL, 1
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
ShR EAX, 16
|
|
|
|
|
Add AX, 1
|
|
|
|
|
SBB AX, 0 ; Just in case!
|
|
|
|
|
And AX, Not 1
|
|
|
|
|
|
|
|
|
|
Inc DX
|
|
|
|
|
Out DX, AX
|
|
|
|
|
Dec DX
|
|
|
|
|
|
|
|
|
|
Jmp SetGUSRegisters7
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters6:
|
|
|
|
|
Mov CH, 2 ; Signify to turn off channel
|
|
|
|
|
Pop DX
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters7:
|
|
|
|
|
MovZX BX, Byte Ptr [SI+36h] ; BX = sample number.
|
|
|
|
|
Cmp BL, 99
|
|
|
|
|
JA SetGUSRegisters20
|
|
|
|
|
|
|
|
|
|
ShL BX, 2 ; GUSDataTable+BX = position
|
|
|
|
|
|
|
|
|
|
Cmp DWord Ptr [CS:GUSDataTable+BX], 0FFFFFFFFh
|
|
|
|
|
JNE SetGUSRegisters10
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters20:
|
|
|
|
|
Mov CH, 2
|
|
|
|
|
Jmp SetGUSRegisters9
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters10:
|
|
|
|
|
Test CH, 5 ; Loop changed?!??!?
|
|
|
|
|
JZ SetGUSRegisters8
|
|
|
|
|
|
|
|
|
|
Mov AL, 3 ; Starting location low.
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
Mov EAX, [SI+40h]
|
|
|
|
|
Call GUSGetAddress
|
|
|
|
|
|
|
|
|
|
; Reqd: ...OOOOO OOOOOOOO OOOOOOOI III.....
|
|
|
|
|
|
|
|
|
|
Inc DX
|
|
|
|
|
Out DX, AX
|
|
|
|
|
Dec DX
|
|
|
|
|
|
|
|
|
|
Mov AL, 2 ; Starting location high
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
ShR EAX, 16
|
|
|
|
|
Inc DX
|
|
|
|
|
Out DX, AX
|
|
|
|
|
Dec DX
|
|
|
|
|
|
|
|
|
|
; Ending location...
|
|
|
|
|
Mov AL, 5 ; Ending location low
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
Mov EAX, [SI+44h]
|
|
|
|
|
Call GUSGetAddress
|
|
|
|
|
|
|
|
|
|
Inc DX
|
|
|
|
|
Out DX, AX
|
|
|
|
|
Dec DX
|
|
|
|
|
|
|
|
|
|
Mov AL, 4 ; Ending location high
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
SHR EAX, 16
|
|
|
|
|
Inc DX
|
|
|
|
|
Out DX, AX
|
|
|
|
|
Dec DX
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters8:
|
|
|
|
|
Test CH, 1 ; Do Current position?
|
|
|
|
|
JZ SetGUSRegisters9
|
|
|
|
|
|
|
|
|
|
Mov AL, 0Bh ; Current location LOW
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
Mov EAX, [SI+4Ch]
|
|
|
|
|
Mov [SI+2Ch], EAX
|
|
|
|
|
|
|
|
|
|
; EAX = OOOOOOOO OOOOOOOO OOOOOOOO OOOOOOOO
|
|
|
|
|
; Req: xxxOOOOO OOOOOOOO OOOOOOOF FFFFFFFF
|
|
|
|
|
Call GUSGetAddress
|
|
|
|
|
|
|
|
|
|
Mov DI, AX
|
|
|
|
|
|
|
|
|
|
Inc DX
|
|
|
|
|
Out DX, AX
|
|
|
|
|
Dec DX
|
|
|
|
|
|
|
|
|
|
Mov AL, 0Ah ; Current location HIGH
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
SHR EAX, 16
|
|
|
|
|
Inc DX
|
|
|
|
|
Out DX, AX
|
|
|
|
|
Call GUSDelay
|
|
|
|
|
Out DX, AX
|
|
|
|
|
Dec DX
|
|
|
|
|
|
|
|
|
|
Mov AL, 0Bh
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
Mov AX, DI
|
|
|
|
|
Inc DX
|
|
|
|
|
Out DX, AX
|
|
|
|
|
Dec DX
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters9:
|
|
|
|
|
Test CL, 64 ; New volume??
|
|
|
|
|
JZ SetGUSPanning
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters23:
|
|
|
|
|
Xor BX, BX
|
|
|
|
|
Test CH, 8
|
|
|
|
|
JNZ SetGUSRegistersMuted
|
|
|
|
|
|
|
|
|
|
Mov BL, Byte Ptr [SI+20h] ; BL = volume, 0->128
|
|
|
|
|
|
|
|
|
|
SetGUSRegistersMuted:
|
|
|
|
|
Call SetGUSVolume
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
SetGUSPanning:
|
|
|
|
|
Test CH, 128 ; New panning?
|
|
|
|
|
JZ SetGUSRegisters5
|
|
|
|
|
|
|
|
|
|
Mov AL, 0Ch ; Set panning.
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
Test CS:Stereo, 1
|
|
|
|
|
JZ SetGUSRegisters3
|
|
|
|
|
|
|
|
|
|
Mov AL, [SI+37h]
|
|
|
|
|
Cmp AL, 100
|
|
|
|
|
JNE SetGUSRegisters4
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters3:
|
|
|
|
|
Mov AL, 32 ; Surround goes to mono :(
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters4: ; AL = 0->64
|
|
|
|
|
ShR AL, 1 ; AL = 0->32
|
|
|
|
|
Sub AL, 1
|
|
|
|
|
AdC AL, 0 ; AL = 0->31
|
|
|
|
|
ShR AL, 1
|
|
|
|
|
|
|
|
|
|
Add DL, 2
|
|
|
|
|
Out DX, AL
|
|
|
|
|
Sub DL, 2
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters5:
|
|
|
|
|
; Now for control register.
|
|
|
|
|
; If CH | 2, then turn rego OFF
|
|
|
|
|
; If CH | 5, then turn rego ON
|
|
|
|
|
; If CL | 1, then check channel
|
|
|
|
|
Test CH, 2
|
|
|
|
|
JNZ SetGUSRegisters11
|
|
|
|
|
|
|
|
|
|
Test CH, 5
|
|
|
|
|
JNZ SetGUSRegisters12
|
|
|
|
|
|
|
|
|
|
Test CL, 1
|
|
|
|
|
JZ SetGUSRegisters13
|
|
|
|
|
|
|
|
|
|
Mov AL, 80h ; Read voice control
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
Add DL, 2
|
|
|
|
|
In AL, DX
|
|
|
|
|
Sub DL, 2
|
|
|
|
|
|
|
|
|
|
Test AL, 1
|
|
|
|
|
JZ SetGUSRegisters13
|
|
|
|
|
|
|
|
|
|
Xor BX, BX
|
|
|
|
|
Call SetGUSVolume
|
|
|
|
|
|
|
|
|
|
Jmp SetGUSRegisters14
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters11:
|
|
|
|
|
; Turn off.
|
|
|
|
|
Xor AL, AL
|
|
|
|
|
Out DX, AL ; AL = 0 (Mode control)
|
|
|
|
|
Mov AL, 2
|
|
|
|
|
Add DL, 2
|
|
|
|
|
|
|
|
|
|
Mov AH, [SI+18h] ; 16 bit?
|
|
|
|
|
Add AH, AH
|
|
|
|
|
Or AL, AH
|
|
|
|
|
|
|
|
|
|
Out DX, AL
|
|
|
|
|
Call GUSDelay
|
|
|
|
|
Out DX, AL
|
|
|
|
|
Sub DL, 2
|
|
|
|
|
|
|
|
|
|
Xor BX, BX
|
|
|
|
|
Call SetGUSVolume
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters14:
|
|
|
|
|
Test CL, 1
|
|
|
|
|
JZ SetGUSRegisters13
|
|
|
|
|
|
|
|
|
|
Xor CX, CX ; Turn off channel
|
|
|
|
|
Test Byte Ptr [SI+3Ah], 80h
|
|
|
|
|
JNZ SetGUSRegisters13
|
|
|
|
|
|
|
|
|
|
Mov BX, [SI+38h]
|
|
|
|
|
And Byte Ptr [BX], Not 4 ; Signify channel off
|
|
|
|
|
|
|
|
|
|
Jmp SetGUSRegisters13
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters12: ; Turn on
|
|
|
|
|
Xor AL, AL
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
Mov AL, [SI+0Ah]
|
|
|
|
|
|
|
|
|
|
Cmp CS:Convert16To8Bit, 0
|
|
|
|
|
JNZ SetGUSRegistersNo16Bit
|
|
|
|
|
|
|
|
|
|
Mov AH, [SI+18h] ; 16 bit?
|
|
|
|
|
Add AH, AH
|
|
|
|
|
Or AL, AH
|
|
|
|
|
|
|
|
|
|
SetGUSRegistersNo16Bit:
|
|
|
|
|
Test CL, 1
|
|
|
|
|
JNZ SetGUSRegisters15
|
|
|
|
|
|
|
|
|
|
Mov AL, 2
|
|
|
|
|
Xor CX, CX
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters15:
|
|
|
|
|
Add DL, 2
|
|
|
|
|
Out DX, AL
|
|
|
|
|
Call GUSDelay
|
|
|
|
|
Out DX, AL
|
|
|
|
|
|
|
|
|
|
SetGUSRegisters13:
|
|
|
|
|
And CX, 0111100010011111b ; Turns off:
|
|
|
|
|
; 1) Freq, pan & vol recalc
|
|
|
|
|
; 2) New note/note stop/loop cha
|
|
|
|
|
|
|
|
|
|
Mov [SI], CX
|
|
|
|
|
|
|
|
|
|
Add SI, SLAVECHANNELSIZE
|
|
|
|
|
|
|
|
|
|
; Call CheckMIDI
|
|
|
|
|
|
|
|
|
|
Pop CX
|
|
|
|
|
Pop AX
|
|
|
|
|
|
|
|
|
|
Inc AX
|
|
|
|
|
Dec CX
|
|
|
|
|
JNZ SetGUSRegisters1
|
|
|
|
|
|
|
|
|
|
Ret
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
EndP SetGUSRegisters
|
|
|
|
|
|