home *** CD-ROM | disk | FTP | other *** search
- ----------------------------------------------------------------------
- ----------------------------------------------------------------------
- DOCUMENT:
- PROGRAMMING DMA I/O WITH VMDMA
- Version 1.0
- March 8, 1991
-
- Programming and Documentation by Ryan Hanlon
- Copyright (c) 1991, Covox, Inc. All Rights Reserved
- ----------------------------------------------------------------------
- GENERAL DESCRIPTION
-
- The recording and playback of non-compressed 8 bit PCM sound
- data via DMA (memory to port, port to memory), can be achieved
- by setting the Voice Master card and mother board DMA controller
- properly. This document will supply all of the raw information
- you will need to write recording and playback software for the
- Voice Master and the Sound Master II boards.
-
- The Voice Master is only capable of being set to use IRQ 3 or IRQ 7
- while the Sound Master II board can use any one of IRQ's 3 through 7.
- Both the Voice Master and the Sound Master II were designed to use
- DMA channel 1 or channel 3 and one of the port ranges starting at
- 0x0220, 0x0240, 0x0280, or 0x02C0.
-
- NOTE : Except for the IRQ changes on the Sound Master II the
- functionality of the Voice Master is replicated on the Sound
- Master II board. For the duration of this document all references
- to the Voice Master (VMDMA), apply equally to the Sound Master II
- board.
-
- This document should be used in conjunction with the document and
- source code supplied with the program sm2detec.exe.
-
- ----------------------------------------------------------------------
- VOICE MASTER PORTS
-
- BASE PORTS
- Jumper setting positions 1 through 4 determine the BASE PORT of
- the Voice Master.
-
- 0x0220 to 0x022F,
- 0x0240 to 0x024F,
- 0x0280 to 0x028F,
- 0x02C0 to 0x02CF
-
- BASE PORT OFFSETS
- The BASE PORT plus (+) the BASE PORT OFFSET can be used to access the
- ports on the Voice Master. As can be seen below only port offsets
- from 0x08 and 0x0F are used on the Voice Master.
-
- 8254 TIMER 0 OFFSET = 0x08 Timer/Clock
- 8254 TIMER 1 OFFSET = 0x09 Timer/Clock
- 8254 TIMER 2 OFFSET = 0x0A Timer/Clock
- 8254 CONTROL OFFSET = 0x0B Timer/Clock control register
-
- CLEAR IRQ OFFSET = 0x0C \
- DISABLE VMDMA OFFSET = 0x0D > VMDMA Control ports
- ENABLE VMDMA OFFSET = 0x0E /
-
- DAC OFFSET = 0x0F The DAC OFFSET port should
- not be written to during DMA
- i/o.
- ----------------------------------------------------------------------
- VMDMA CONTROL PORT OFFSETS
-
- DISABLE DMA OFFSET = 0x0D
- Writing to this port will disable DREQ (DMA Request), channel 1
- or DREQ channel 3 thus preventing all VMDMA i/o.
-
-
- ENABLE DMA OFFSET = 0x0E
- Writing to this port should be done last and only after all clock and
- DMA setup has been completed. A write to this port will fire off
- a DREQ (cause the DREQ line to go low), thus allowing the VMDMA i/o
- to begin.
-
-
- CLEAR IRQ OFFSET = 0x0C
- This BASE PORT offset is to be utilized after every DMA
- terminal count is reached. It is common to find this port
- being written to inside an interrupt handler. Any value
- may be output to the port.
-
- ----------------------------------------------------------------------
- INTEL 8254 COUNTER/TIMER ONBOARD THE VOICE MASTER
-
- The Voice Master is equipped with the Intel 8254 programmable interval
- counter/timer. COUNTER 2 is used for DMA i/o control. COUNTER 1 and 3
- are not used by the Voice Master and are available for general purpose
- use within software.
-
- TIMER 0 OFFSET = 0x08 TIMER 1 OFFSET = 0x09 TIMER 2 OFFSET = 0x0A
-
- 8254 CONTROL OFFSET = 0x0B
-
- COUNTER 2 is setup to fire off DREQ's at given intervals by
- latching to the 8254 CONTROL OFFSET port in LSB/MSB order.
- The formula you will need to properly program this DREQ
- frequency is shown below.
-
- 7.1MHz
- i/o rate = ------------ where N is a 16 bit divisor that
- N is written, 8 bits at a time,
- to one of the TIMER OFFSETs.
-
- Each DREQ sent by the Voice Master is received by the 8237 DMA
- controller on the mother board. After one 8 bit DMA read or write is
- performed the 8237 sends a DACK (DMA Acknowledged), signal to the Voice
- Master board. This DACK signal effectively disables the Voice Master
- from sending another DREQ to the 8237 until CLOCK 2 reaches zero again.
-
- Bit settings for the CONTROL port of the 8254.
-
- bits 7,6 = 00 timer 0 bits 5,4 = 00 latch preset
- 01 timer 1 01 read/write only MSB
- 10 timer 2 10 read/write only LSB
- 01 read/write LSB, then MSB
-
- bits 3,1 = 000 mode 0 bit 0 = 0 binary
- 001 mode 1 1 BCD decrementing
- 010 mode 2
- 011 mode 3
- 100 mode 4
- 101 mode 5
-
- ----------------------------------------------------------------------
- 8237 DMA CONTROLLER ON THE MOTHERBOARD
-
- The DMA on the mother board should be completely setup for i/o
- only after the Voice Master board has had the DREQ lines
- disabled. (See DISABLE VMDMA OFFSET for more information).
-
- The recommended settings for performing recording or playback
- are as follows :
- 1. single mode
- 2. address increment
- 3. no automatic reinitialize
- 4. read or write (depending on desired results)
- 5. channel 1 or 3 (depending on jumper setting on Voice Master)
-
- Bit settings for the control byte of the 8237.
- bits 7,6 = 00 demand mode
- 01 single mode
- 10 block mode
- 11 cascade mode
-
- bit 5 = 0 address increment
- 1 address decrement
-
- bit 4 = 0 no automatic reinitialize
- 1 automatic reinitialize
-
- bits 3,2 = 00 verify
- 01 write
- 10 read
-
- bits 1,0 = 00 channel 0
- 01 channel 1
- 10 channel 2
- 11 channel 3
-
-
- ----------------------------------------------------------------------
-
- DMA BUFFER - 20-BIT SEGMENT ADDRESS
-
- Bits 2 and 3 of the byte written to the 8237 DMA CONTROLLER determine
- whether DMA recording or playback will be performed. Both DMA i/o
- directions require that the start address of a data buffer be output
- to the DMA ADDRESS REGISTER and the physical page be outp to the
- DMA PAGE REGISTER.
-
-
- EXAMPLE :
-
- This example uses a long named temp_address to store the 20 bit
- address of a Test_Buffer of char. First the page address of Test_Buffer
- is outp to the DMA PAGE REGISTER. The remaining 16 bit address
- is outp to the DMA ADDR REGISTER. Channel 1 is the active settings
- of the Voice Master for this example.
-
- /* Get 20 bit address of test buffer
- */
- temp_address = ((long)FP_SEG(Test_Buffer))<<4) + (long)FP_OFF(Test_Buffer);
-
-
- /* Output segment page address of test buffer to the DMA PAGE REGISTER
- // for channel 1.
- */
- outp( DMA_CH1_PAGE_REGISTER, (unsigned char)(temp_address >> 16) );
-
-
- /* Set the address of the test buffer. outp LSB then MSB.
- */
- outp( DMA_CLEAR_LSB_MSB, 0x00 );
- outp( DMA_CH1_ADDR_REGISTER, (unsigned char)(temp_address) );
- outp( DMA_CH1_ADDR_REGISTER, (unsigned char)(temp_address >> 8) );
-
- ----------------------------------------------------------------------
-
- DMA BUFFER - CURRENT BUFFER SIZE
-
- The size of the current buffer being used with DMA i/o should be
- output to the DMA COUNT REGISTER. Special considerations need to be
- made for buffers that cross page boundaries.
-
-
- EXAMPLE :
-
- This example assumes that the length of Test_Buffer is stored in a
- variable named Test_Buffer_Count. Since the DMA predecrements this
- count before a byte is processed we add 1 to the count before it
- is outp to the DMA COUNT REGISTER. Channel 1 is the active settings
- of the Voice Master for this example.
- This example does not check to see if the length of the buffer exceeds
- the available length left before the page boundary.
-
- /* Set word count on DMA channel 1.
- */
- outp( DMA_CLEAR_LSB_MSB, 0x00 );
- outp( DMA_CH1_COUNT_REGISTER, Test_Buffer_Count + 1 );
- outp( DMA_CH1_COUNT_REGISTER, 0x00 );
-
- /* Enable 8237 DMA on the mother board
- */
- outp( DMA_MASK_REGISTER , DMA_CH1);
-
-
- ----------------------------------------------------------------------
-
- IMPORTANT PROGRAMMING CONSIDERATIONS
-
- 1. Disabling and enabling of the DMA subsystem can cause an IRQ to fire
- off.
-
- 2. When the terminal count is reached on the 8237 DMA controller the
- DACK line on the Voice Master goes high. To set this line to
- low and thus allow the next interrupt to occur you must
- outp( (vmdma_base_port + VMDMA_CLEAR_IRQ_OFFSET), 0) directly before
- issuing an outp(0x20,0x20) in your interrupt handler.
-
-
-