DMA Play WAV

DOS specific questions.
angros47
Posts: 1445
Joined: Jun 21, 2005 19:04

DMA Play WAV

Postby angros47 » Oct 22, 2013 17:57

This is a barebone DMA play (it needs the file "tada.wav" in the same directory)

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

Return to “DOS”

Who is online

Users browsing this forum: No registered users and 1 guest