Tested in DosBox.
Code: Select all
#include "dos/dpmi.bi"
#include "dos/dos.bi"
#include "dos/sys/movedata.bi"
DECLARE FUNCTION ResetDSP () as integer
DECLARE SUB WriteDSP (byt as ubyte)
DECLARE SUB DMAPlay (Offset as long, Length as long)
CONST PgPort = &H83, AddPort = &H2, LenPort = &H3, ModeReg = &H49
CONST Channel = 1, BasePort = &H220, Freq = 22000
CONST buffersize= 32767
PRINT
PRINT "PlayWav A utility for Playing WAV files Version 1.03"
PRINT "Forever Young Software(r) (C)opyright 1984-2007"
PRINT
IF ResetDSP THEN 'resets DSP (returns true if sucessful)
PRINT "DSP reset successfully!"
ELSE
PRINT "DSP failed to reset, try another port."
END IF
WriteDSP &HD1 'turn the speaker on
OUT BasePort + 4, &H22 ' set volume
OUT BasePort + 5, &HDD ' Left = HI Nibble, Right = LO nibble (0FF is max)
DIM SHARED WavBuffer(1 TO 1) AS STRING * 32767 'Make a 32k buffer for file.
var File = "tada.wav"
OPEN File FOR BINARY AS #1
GET #1, 44, WavBuffer(1) 'Get 32k from file (skip header on WAV)
Dim s2 As String
Dim shared dos_seg As Integer, dos_sel As Integer, f as integer
Dim regs As __dpmi_regs
dos_seg = __dpmi_allocate_dos_memory((buffersize*2+15)shr 4, @dos_sel)
If dos_seg = 0 Then end ' out of memory
var Length = LOF(1) - 44
var Offset=dos_seg shl 4
if (Offset shr 16) <> ((Offset + buffersize) shr 16) then Offset = ((Offset + buffersize) and &Hffffff00)
IF Length > buffersize THEN Length = buffersize 'Adjust length if needed to 32k
dosmemput(Strptr(WavBuffer(1)), Length, Offset)
DMAPlay Offset , Length
sleep
CLOSE 1
END
SUB DMAPlay (Offset as long, Length as long)
Length = Length - 1
var Page = 0
var MemLoc = Offset
OUT &HA, &H4 + Channel
OUT &HC, &H0
OUT &HB, ModeReg
OUT AddPort%, MemLoc AND &HFF
OUT AddPort%, (MemLoc AND &HFFFF&) \ &H100
IF (MemLoc AND 65536) THEN Page = Page + 1
IF (MemLoc AND 131072) THEN Page = Page + 2
IF (MemLoc AND 262144) THEN Page = Page + 4
IF (MemLoc AND 524288) THEN Page = Page + 8
OUT PgPort, Page
OUT LenPort, Length AND &HFF
OUT LenPort, (Length AND &HFFFF&) \ &H100
OUT &HA, Channel
WriteDSP &H40
WriteDSP (256 - 1000000 \ Freq)
WriteDSP &H14
WriteDSP (Length AND &HFF)
WriteDSP ((Length AND &HFFFF&) \ &H100)
END SUB
FUNCTION ResetDSP as integer
' Resets the DSP
OUT BasePort + 6, 1
dim Junk as integer
FOR Count as integer = 1 TO 10
Junk = INP(BasePort% + 6)
NEXT
OUT BasePort + 6, 0
FOR Count as integer = 1 TO 10
Junk = INP(BasePort% + 6)
NEXT
IF (INP(BasePort + 14) AND &H80 = &H80) AND (INP(BasePort + 10) = &HAA) THEN
ResetDSP = -1
ELSE
ResetDSP = 0
END IF
END FUNCTION
SUB WriteDSP (byt as ubyte)
' Writes a byte to the DSP
DO
LOOP WHILE INP(BasePort + 12) AND &H80
OUT BasePort + 12, byt
END SUB