impulsetracker/SoundDrivers/SAM9407.ASM

1009 lines
25 KiB
NASM
Executable File

.386P
Segment DriverHeader PARA Public 'Code' Use16
Assume CS:Driver, DS:Nothing
;***** Driver Header *******
include drhead.inc
EndS
Segment Driver PARA Public 'Code' Use16
Assume CS:Driver, DS:Nothing
ORG 0
StartDriver:
include vtable.inc
;******** Required ProcedureTable *************
include reqproc.inc
;***********************************************
NUMMEMORYBLOCKS EQU 64
PNPSERIALID EQU 0FFFFFFFFh
PNPVENDORID EQU 80719304h
MMT_MAXENTRIES EQU 64
MMT_MAXSIZE EQU 3*MMT_MAXENTRIES
SAM_RD_MEM EQU 2h
SAM_GET_MMT EQU 3h
SAM_GEN_INT EQU 48h
SAM_GET_VOI EQU 51h
SAM_VOI_OPEN EQU 52h
SAM_VOI_CLOSE EQU 53h
SAM_VOI_START EQU 54h
SAM_VOI_STOP EQU 55h
SAM_VOI_VOL EQU 56h
SAM_VOI_MAIN EQU 57h
SAM_VOI_PITCH EQU 58h
SAM_VOI_AUX EQU 59h
SAM_VOI_FILT EQU 5Ah
SAM_VOI_MEM EQU 5Bh
SAM_GET_POS EQU 5Ch
SAM_ADD_POS EQU 5Dh
SAM9407Message DB "Dream SAM9407 Detected", 13
DB "Port ", 0FDh, "Xh, ", 0FDh, "Dk RAM", 0
StatusLine DB "FreeSAM ", 0FDh, "Dk", 0
SAMUpdateFlag DB 0
ALIGN 4
OldIRQHandler DD 0
SAMUpdateTimer DW 0
SAMUpdateCount DW 0
MMTData DW MMT_MAXSIZE Dup (0)
MemoryBlocks DD NUMMEMORYBLOCKS*2 Dup (0)
; Memory blocks are offset/size pairs.
SampleInformation DD 100*4 Dup (0)
; Sample data is a struct
; Offset 0: Starting address
; Offset 4: Loop start
; Offset 8: Loop end
; Offset 0Ch: ??
SlaveChannelOffset DW 0
; ÄÄ EmptyFunction ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc EmptyFunction Far
Xor AX, AX
StC
Ret
EndP EmptyFunction
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAM9407ReceiveByte ; Returns AL = data
; BL = status
Push DX
Mov DX, CS:BasePort
Inc DX
SAM9407ReceiveByte1:
In AL, DX
Test AL, AL
JS SAM9407ReceiveByte1
Mov BL, AL
Dec DX
And BL, 30h
In AL, DX
Pop DX
Ret
EndP SAM9407ReceiveByte
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAM9407ReceiveWord ; Returns AX
Call SAM9407ReceiveByte
Mov AL, AH
Call SAM9407ReceiveByte
XChg AL, AH
Ret
EndP SAM9407ReceiveWord
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAM9407ReceiveDWord ; Returns EAX
Call SAM9407ReceiveByte
RoR EAX, 8
Call SAM9407ReceiveByte
RoR EAX, 8
Call SAM9407ReceiveByte
RoR EAX, 8
Call SAM9407ReceiveByte
RoR EAX, 8
Ret
EndP SAM9407ReceiveDWord
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAM9407SendControlByte ; BL = data
Push AX
Push DX
Mov DX, CS:BasePort
Inc DX
SAM9407SendControlByte1:
In AL, DX
Test AL, 40h
JNZ SAM9407SendControlByte1
Mov AL, BL
Out DX, AL
Pop DX
Pop AX
Ret
EndP SAM9407SendControlByte
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAM9407SendDataByte ; AL = data
Push DX
Push AX
Mov DX, CS:BasePort
Inc DX
SAM9407SendDataByte1:
In AL, DX
Test AL, 40h
JNZ SAM9407SendDataByte1
Pop AX
Dec DX
Out DX, AL
Pop DX
Ret
EndP SAM9407SendDataByte
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAM9407SendDataWord ; AX = data
Call SAM9407SendDataByte
Mov AL, AH
Call SAM9407SendDataByte
Ret
EndP SAM9407SendDataWord
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAM9407SendDataDWord ; EAX = data
Call SAM9407SendDataByte
ShR EAX, 8
Call SAM9407SendDataByte
ShR EAX, 8
Call SAM9407SendDataByte
ShR AX, 8
Call SAM9407SendDataByte
Ret
EndP SAM9407SendDataDWord
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAM9407ReceiveString ; ES:DI points to deposit point.
; EAX = memory address
; CX = count
Mov BL, SAM_RD_MEM
Call SAM9407SendControlByte
Call SAM9407SendDataDWord
Mov AX, CX
Call SAM9407SendDataWord
SAM9407InString1:
Call SAM9407ReceiveByte
Cmp AL, 0ABh
JE SAM9407InStringError
Cmp AL, 0ACh
JNE SAM9407InString1
SAM9407InString2:
Mov DX, CS:BasePort
Add DX, 2
Rep InsW
DB 85h
SAM9407InStringError:
StC
Ret
EndP SAM9407ReceiveString
; ÄÄ DetectCard ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Returns carry set if error, else carry clear. Has to setup internal vars
; (eg. appropriate IRQ/DMA whatever).
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc ResetWaitforSend ; Given DX = control port
Xor CX, CX
ResetWaitforSend1:
In AL, DX
Test AL, 40h
LoopNZ ResetWaitforSend
Ret
EndP ResetWaitforSend
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc ResetWaitforReceive
Xor CX, CX
ResetWaitforReceive1:
In AL, DX
Test AL, 80h
JNZ ResetWaitforReceive2
Dec DX
In AL, DX
Inc DX
Cmp AL, 0FEh
JE ResetWaitforReceive3
ResetWaitforReceive2:
Loop ResetWaitforReceive1
StC
Ret
ResetWaitforReceive3:
ClC
Ret
EndP ResetWaitforReceive
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAMSendChannelNumber
Mov AX, SI
Sub AX, CS:SlaveChannelOffset
ShR AX, 7
Call SAM9407SendDataByte
Ret
EndP SAMSendChannelNumber
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAMOpenVoice
Cmp Byte Ptr [SI+2], 1
JE SAMOpenVoice1 ; Already opened!
Mov Byte Ptr [SI+2], 1
Mov BL, [SI+36h] ; Sample number
Xor DH, DH
And BX, 0FFh
ShL BX, 4
Mov DL, [Byte Ptr CS:SampleInformation+BX+3]
Sub DL, [Byte Ptr CS:SampleInformation+BX+7]
; Carry 0 if inbank
; Carry 1 if crossbank
SBB DL, DL ; DL = 0 inbank
; DL = 0FFh crossbank
ShL DL, 7 ; DL = 0 inbank
; DL = 80h crossbank
Mov BL, SAM_VOI_OPEN
Call SAM9407SendControlByte
Mov AX, SI
Sub AX, CS:SlaveChannelOffset
ShR AX, 7
Or AL, DL
Call SAM9407SendDataByte
SAMOpenVoice1:
Ret
EndP SAMOpenVoice
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAMStopNote ; Closes the voice.
Cmp Byte Ptr [SI+2], 1
JNE SAMStopNote1
Mov Byte Ptr [SI+2], 0
Mov BL, SAM_VOI_CLOSE
Call SAM9407SendControlByte
Call SAMSendChannelNumber
SAMStopNote1:
Ret
EndP SAMStopNote
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAMSetVolume
Cmp Byte Ptr [SI+2], 1
JNE SAMSetVolume1
Mov BL, SAM_VOI_VOL
Call SAM9407SendControlByte
Call SAMSendChannelNumber
Mov AL, [SI+20h]
Call SAM9407SendDataByte
SAMSetVolume1:
Ret
EndP SAMSetVolume
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAMSetPan
Cmp Byte Ptr [SI+2], 1
JNE SAMSetPan1
Comment ~
Mov BL, SAM_VOI_PAN
Call SAM9407SendControlByte
Call SAMSendChannelNumber
Mov AL, [SI+37h]
Call SAM9407SendDataByte
~
SAMSetPan1:
Ret
EndP SAMSetPan
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAMSetPitch
; Pitch value sent is 400h for nominal frequency of 37.5khz, linear scale
; -> Value sent = Frequency*400h / 37500
; = Frequency * 0.02730666
; = Frequency * 117281240 / 2^32
Cmp Byte Ptr [SI+2], 1
JNE SAMSetPitch3
Mov EAX, 117281240
Mul DWord Ptr [SI+10h]
Cmp EDX, 0FFFFh
JA SAMSetPitch1
Mov BL, SAM_VOI_PITCH
Call SAM9407SendControlByte
Call SAMSendChannelNumber
Mov AX, DX
Call SAM9407SendDataWord
SAMSetPitch3:
Ret
SAMSetPitch1:
Call SAMStopNote
Mov Word Ptr [SI], 200h
Test Byte Ptr [SI+3Ah], 80h
JNZ SAMSetPitch2
Mov BX, [SI+38h]
And Byte Ptr [BX], Not 4 ; Signify channel off
SAMSetPitch2:
Ret
EndP SAMSetPitch
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAMSetRegisters
; First get offset of currently playing notes
; Update Registers to play notes
; Flow is as follows:
; If new note, open voice
;
; If pitch change, set pitch
; If volume change, set volume + filters
;
PlayNote:
Ret
EndP SAMSetRegisters
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SAMIRQHandler ; IRQ Handler has to
; 1) Update GUS registers
; 2) Update song position
Push AX
Push DS
Push CS
Pop DS
Assume DS:Driver
Mov AX, SAMUpdateTimer
Add SAMUpdateCount, AX
JC SAMIRQHandler1
Mov AL, 20h
Out 20h, AL
Jmp SAMIRQHandler2
SAMIRQHandler1:
PushF
Call [OldIRQHandler]
SAMIRQHandler2:
Xor SAMUpdateFlag, 1
JZ SAMIRQHandlerEnd
PushAD
Push ES
ClD
Call SaveEMSPageFrame
Call Update ; Returns DS:SI, CX
Assume DS:Nothing
Mov SlaveChannelOffset, SI
Call SAMSetRegisters
Call RestoreEMSPageFrame
Pop ES
PopAD
SAMIRQHandlerEnd:
Pop DS
Pop AX
IRet
EndP SAMIRQHandler
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc ResetUART ; Given DX = Port
Inc DX
Mov AL, 0FFh ; Reset!
Out DX, AL
Out DX, AL ; Two resets required to ensure it'll work
Call ResetWaitforReceive
JNC ResetUART1
ResetUARTError:
StC
Ret
ResetUART1: ; Now to shove it into 'intelligent' mode.
Call ResetWaitforSend
JNZ ResetUARTError
Mov AL, 3Fh ; Intelligent mode!
Out DX, AL
Call ResetWaitforReceive
JC ResetUARTError
Call ResetWaitforSend
JNZ ResetUARTError
Mov AL, SAM_GEN_INT
Out DX, AL
Call ResetWaitforSend
JNZ ResetUARTError
Dec DX
Xor AL, AL
Out DX, AL
Inc DX
Xor CX, CX
ResetUART2:
In AL, DX
Test AL, 80h
JNZ ResetUART3
Mov AH, AL
Dec DX
In AL, DX
Inc DX
And AH, 30h
Cmp AX, 3088h
JE ResetUART4
ResetUART3:
Loop ResetUART2
Jmp ResetUARTError
ResetUART4:
Call ResetWaitforReceive
JC ResetUARTError
Dec DX
ClC
Ret
EndP ResetUART
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc DetectCard Far ; returns carry clear if succesful
Push CS
Pop DS
; Check whether the MPU can be reset
Mov DX, BasePort
Cmp DX, 0FFFFh
JE DetectCard1
Call ResetUART
JNC DetectCardFound
DetectCardExit:
Ret
DetectCard1:
Mov DX, 330h
Call ResetUART
JNC DetectCard2
Mov DX, 300h
Call ResetUART
JC DetectCardExit
DetectCard2:
Mov BasePort, DX
DetectCardFound:
; Find memory mapping table,
Mov BL, SAM_GET_MMT
Xor AL, AL
Call SAM9407SendControlByte
Call SAM9407SendDataByte
Call SAM9407ReceiveDWord
Push CS
Pop ES
Mov CX, MMT_MAXSIZE
Mov DI, Offset MMTData
Call SAM9407ReceiveString
Mov EAX, 'Jeff'
Ret
EndP DetectCard
Assume DS:Nothing
;ÄÄ InitSound ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Sets up any memory required for output
; Initiates output
;
; Parameters: AX = Number of Channels
;
; If sucessful, returns:
; Carry flag clear
; DS:SI = pointer to text to display
; AX = parameter 1 in text
; BX = parameter 2 in text
; CX = parameter 3 in text
; DX = parameter 4 in text
; DI = parameter 5 in text
;
; If unsucessful, returns:
; Carry flag set
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc InitSound Far
Push CS
Pop DS
Assume DS:Driver
Mov AL, 34h ; Program IRQ 0. LSB&MSB, Rate gen
Out 43h, AL
Call GetTempo
Call SetTempo
Call ResetMemory
Xor AX, AX
Mov ES, AX ; ES = 0
Mov AX, CS
ShL EAX, 16
Mov AX, Offset SAMIRQHandler
ClI
XChg DWord Ptr [ES:20h], EAX ; Clock tick
Mov OldIRQHandler, EAX
StI
Mov SI, Offset SAM9407Message
Xor BX, BX
Comment ~
Mov BL, SAM_GET_VOI
Xor AL, AL
Call SAM9407SendControlByte
Call SAM9407SendDataByte
Call SAM9407ReceiveByte
Mov BL, AL
~
Mov AX, BasePort
Mov EBX, DWord Ptr [MMTData+2]
ShR EBX, 9
ClC
Ret
EndP InitSound
Assume DS:Nothing
;ÄÄ ReInitSound ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Reinitialises sound output
; Initiates sound output
;
; Parameters: AX = number of channels.
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc ReInitSound Far
Ret
EndP ReInitSound
;ÄÄ UnInitSound ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Stops sound output, releases any memory used by driver
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc UnInitSound Far
Mov BL, 0FFh
Call SAM9407SendControlByte
Mov AL, 34h
Out 43h, AL
Xor AX, AX
Out 40h, AL
Out 40h, AL
Mov ES, AX
Mov EAX, OldIRQHandler
Mov [ES:20h], EAX
Ret
EndP UnInitSound
;ÄÄ Poll ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; This procedure is called as often as possible by IT.EXE
; AX = Playmode (0 for nothing in particular, 1 = pattern, 2 = song)
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc Poll Far
Ret
EndP Poll
;ÄÄ SetTempo ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Parameters: BX = tempo
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SetTempo Far ; BX = tempo...
Push AX
Push BX
Push DX
; Frames per second = 2 * (0.4*Tempo)
Mov AX, 0C214h
Mov DX, 16h ; Ticks = (1193181/(2*0.4))/Tempo
Div BX
; AX contains counter.
Mov CS:SAMUpdateTimer, AX
Out 40h, AL ; Timer IRQ.
Mov AL, AH
Out 40h, AL
Pop DX
Pop BX
Pop AX
Ret
EndP SetTempo
;ÄÄ SetMixVolume ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Parameters: AX = MixVolume
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SetMixVolume Far
Ret
EndP SetMixVolume
;ÄÄ SetStereo ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Parameters: AL = Stereo on/off, 0 = off.
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SetStereo Far
Ret
EndP SetStereo
;ÄÄ LoadSample ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Parameters: AX = sample to load (0 based)
; DS:SI points to sample header
; ES:0 points to first sample
;
; Returns: **Carry set if NO error**
; **Carry clear if error**
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc LoadSample Far
StC
Ret
EndP LoadSample
;ÄÄ ReleaseSample ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Parameters: AX = sample to release (1 based)
; DS:SI points to sample header
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc ReleaseSample Far
Ret
EndP ReleaseSample
;ÄÄ ResetMemory ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Frees all on-board memory
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc ResetMemory Far
PushA
Push DS
Push ES
Push CS
Pop DS
Push CS
Pop ES
Mov SI, Offset MMTData+6
Mov DI, Offset MemoryBlocks
ResetMemory1:
Mov AX, [SI]
Add SI, 6
Cmp AX, -1
JE ResetMemory2
Cmp AX, 1
JNE ResetMemory1
Mov EAX, [SI-4]
StosD
Neg EAX
Add EAX, [SI+2]
StosD
Jmp ResetMemory1
ResetMemory2:
Mov CX, Offset MemoryBlocks+NUMMEMORYBLOCKS*2*4
Sub CX, DI
Xor AX, AX
ShR CX, 1
Rep StosW
Pop ES
Pop DS
PopA
Ret
EndP ResetMemory
;ÄÄ GetStatus ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Returns text to show on status line, AX = display parameter
; Carry set if not to show anything.
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc GetStatus Far
Push CS
Pop DS
Assume DS:Driver
Mov SI, Offset MemoryBlocks+4
Mov CX, NUMMEMORYBLOCKS
Xor EAX, EAX
GetStatus1:
Add EAX, [SI]
Add SI, 8
Loop GetStatus1
Mov SI, Offset StatusLine
ShR EAX, 9
ClC
Ret
EndP GetStatus
Assume DS:Nothing
;ÄÄ SoundCardScreen ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
;
; Function to have driver interactive part of program
;
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SoundCardScreen Far
Xor AX, AX
StC
Ret
EndP SoundCardScreen
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc GetVariable Far
Ret
EndP GetVariable
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Proc SetVariable Far
Ret
EndP SetVariable
;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
EndDriver:
;******** Provided Variable Table *************
MaxNumberOfChannels DW 64 ; Maximum number of channels the
; driver can handle.
StopAfterPlay DW 0
DefaultChannels DW 64
DW 5 Dup (0)
;******** Provided Procedure Table *************
ProvidedTableStart:
DW Offset DetectCard
DW Offset InitSound ; Playing related
DW Offset ReinitSound
DW Offset UninitSound
DW Offset Poll
DW Offset SetTempo ; Sound variable related
DW Offset SetMixVolume
DW Offset SetStereo
DW Offset LoadSample ; Sample related
DW Offset ReleaseSample
DW Offset ResetMemory
DW Offset GetStatus ; Returns string to show on status line
DW Offset SoundCardScreen ; Sound card 'screen'
DW Offset GetVariable ; For interface
DW Offset SetVariable
ProvidedTableEnd:
DW 32-(ProvidedTableEnd-ProvidedTableStart)/2 Dup (0)
EndS
End