textfiles/music/ultra

696 lines
26 KiB
Plaintext

³ ** UltraDox ** v2.0 ³
ÚÄÁÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÁÄ¿
³ Created by: ³
³ CyberStrike of Renaissance ³
³ Tran of Renaissance ³
³(: ...and a few others... :)³
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
OK, everyone, here is the second document describing the Gravis Ultrasound.
Through the ingeniousness of Forte Technologies and Advanced Gravis, this
32-channel CD-quality digital playback card has been created. It can, under
the right mail-order sources, be bought for less than a Soundblaster!
Advanced Gravis: Please, please, make an official document describing the
functions. We've done our best, and through Internet, we have become YOUR
support group for both programming the card and the technical aspects of the
card. There are 4 or 5 of us on Internet that spend our time on comp.sys.
ibm.pc.soundcard responding to questions, requests, etc, about the Ultrasound.
We thought that you did have net access...
We BELIEVE in the Ultrasound! We don't believe it is a dead card! At first,
Usenet was ragging on the Ultrasound badly. We defended it, and now, it
appears that comp.sys.ibm.pc.soundcard has become comp.sys.ibm.pc.soundcard.
gus.
Enough of that. European demo groups and anyone else who can't understand this
document. I only wrote it in a few hours, and while it is better than the
last doc, it still lacks. If you can't understand how something is
implemented, take a look at GUSMOD 1.1 and GUSMOD 1.2 when it finally comes
out.
This document is intended as a more advanced supplement to the previous
UltraSound Programming Docs. As a supplement, it is advisable to pick up
the previous UltraSound Programming Docs, GUSMOD, or any other utilities
that are released with source code in order to determine how this system
works.
If all else fails, contact me at Internet address: cstrike@gompers.gompers.edu
Have fun, all! (And Gravis, let's see some real stuff coming out.)
* CyberStrike from America's BEST
group, Renaissance!
þ All trademarks belong to their respective companies and trademark holders.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Card architecture:
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
The Gravis Ultrasound has onboard capabilities of playing up to 32
digital voices through 2 DACs, one left and one right. Each voice may be
played at sampling rates up to 44.1khz and may be 8 or 16-bit. The voices
are individually pannable through 15 different pan positions.
The Gravis Ultrasound is allowed up to a megabyte of on-board RAM to be
installed on the card. It is highly recommended that Gravis Ultrasound
users upgrade this to a meg of RAM as new products will require this.
By use of the Ultrasound Poke and Peek functions or by DMA
transfers, data can be transferred to and from the card. The data that
is loaded to the card MUST be in two's compliment form. DMA transfers
can adjust this as the data is loaded to or from the card. If the Poke
and Peek methods are used, the data must be manually converted.
Lastly, on the subject of DRAM, the sampled data may be 8- or 16-
bit. If the data is 16-bit, it will take twice the DRAM to store it.
16-bit data is stored as a low-byte and then a high-byte immediately
following it.
Each voice may also have a specific volume setting. This is NOT a
linear volume but rather a logarithmic volume. It is advisable to make a
table to control this. When panning voices, it appears the volume is
adjusted according to the pan position.
Volume ramping is a technique used to control the popping of the card.
If the volume is changed by a large degree, a pop will occur. By ramping the
volume into an inaudible range (usually below 2000), anything can be set on
the voice without hearing it.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Methods:
@DELAY = (in byte 300h)*7
; CX:AX - Number ; Same as 32-bit shr eax,7 or whatever.
RShift proc
mov bx,cx
shr ax,7
shr cx,7
shl bx,9
or ax,bx
ret
RShift endp
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Ports:
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BASE - Mixer Control Port (u_Base)
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
³ 7 ³ 6 ³ 5 ³ 4 ³ 3 ³ 2 ³ 1 ³ 0 ³
ÀÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÙ
³ ³ ³ ³ ³ ³ ³ ³
³ ³ ³ ³ ³ ³ ³ ÀÄÄÄÄ 0 = Line-In On, 1 = Line-In Off
³ ³ ³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄ 0 = Output On, 1 = Output Off
³ ³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄ 0 = MicIn Off, 1 = MicIn On
³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ?
³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ?
³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ?
³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 = u_IRQDMAControl is DMA, 1 is IRQ
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ?
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BASE + 6h - Status Register Port (u_Status)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BASE + 8h - Timer Control Port (u_TimerControl)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BASE + 9h - Timer Data Port (u_TimerData)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BASE + Bh - IRQ-DMA Control Port (u_IRQDMAControl)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BASE + 100h - Midi Control Port (u_MIDI_Control)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BASE + 101h - Midi Data Port (u_MIDI_Data)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BASE + 102h - Active Voice Port (u_Voice)
Output to u_DataHi the voice number to make the active voice. All
commands that pertain to the active voice through the u_Command port will
be routed to this voice until it is changed again.
Example:
mov dx,u_Voice
mov al,1 ; Use voice #1.
out dx,al
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BASE + 103h - Function Select Port (u_Command)
ÄÄÄ 00h - Write Voice Mode (Byte to u_DataHi)
NOTE: This bit layout may be incorrect. If so, I will post a fixed version
of this document later.
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
³ 7 ³ 6 ³ 5 ³ 4 ³ 3 ³ 2 ³ 1 ³ 0 ³
ÀÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÙ
³ ³ ³ ³ ³ ³ ³ ³
³ ³ ³ ³ ³ ³ ³ ÀÄÄÄÄ 1 = Voice is stopped
³ ³ ³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄ 1 = Stop Voice
³ ³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄ 0 = 8-bit data, 1 = 16-bit data
³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 = No loop, 1 = Loop
³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 = Unidirectional, 1 = Bidirectional
³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 1 = IRQ on end of loop
³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 = Go forward, 1 = Go backwards
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ?
Example:
mov dx,u_Voice
mov al,1 ; Use voice #1.
out dx,al
mov dx,u_Command
mov al,0 ; Write Voice Mode.
out dx,al
mov dx,u_DataHi
mov al,00000011b ; Stop voice #1 immediately.
out dx,al
ÄÄÄ 01h - Set Voice Frequency (Word to u_DataLo)
Based on the number of voices set through register 0Eh (Number of
active voices), the divisor changes. The frequency outputted to the
Ultrasound is not a frequency such as 22000hz, but rather the hertz
divided by a modifier (only Gravis and Forte know why).
We've traced the divisors down to 8 active voices. Apparently, there
are a minimum of 14.
# Voices Divisor # Voices Divisor # Voices Divisor
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
24 25
8 74 16 37 25 24
9 66 17 35 26 23
10 60 18 33 27 22
11 54 19 31 28 21
12 50 20 30 29 20
13 46 21 28 30 20
14 43 22 27 31 19
15 40 23 26 32 18
It is recommended that you don't use values below 14 voices (even
though it appears to work).
Example:
mov dx,u_Command
mov al,0Eh ; Set active voices.
out dx,al
mov dx,u_DataHi
mov al,13 or 0C0h ; Set number of active voices to 14.
out dx,al
mov dx,u_Voice
mov al,2 ; Use voice #2.
out dx,al
mov dx,u_Command
mov al,1 ; Set Voice Frequency.
out dx,al
mov dx,u_DataHi
mov ax,511 ; 22000/43
out dx,al
Do yourself a favor and make a table for your notes.
ÄÄÄ 02h - Set Loop Start Location (Word to u_DataLo)
ÄÄÄ 03h - Set Loop Start Location (Word to u_DataLo)
Through the use of these two registers, the starting location for
the active voice can be set. For an unknown reason, any memory
addresses for the BEGIN, START, and END sample locations in DRAM
must be divided by 128 and written to u_DataLo, then multiplied
by 512 and written to u_DataLo.
Set Sample Begin Location (0ah,0bh) and Set Sample End Location
(4,5) will refer to this example. They are both done the same
way with the exception of the u_Command outs. @@Lo should be
replaced with 2, 4, or 0ah (based on what you are doing), and
@@Hi should be replaced with 3, 5, 0bh.
@@AddrLo is the lower word of the 32-bit DRAM location.
@@AddrHi is the upper word of the 32-bit DRAM location.
Example:
mov dx,u_Voice
mov al,3 ; Use voice #3.
out dx,al
mov dx,u_Command
mov al,@@Lo ; Request new position.
out dx,al
mov dx,u_DataLo
mov ax,@@AddrLo
mov cx,@@AddrHi
call RShift
out dx,ax
mov dx,u_Command
mov al,@@Hi
out dx,al
mov dx,u_DataLo
mov ax,@@AddrLo
shl ax,9
out dx,ax
ÄÄÄ 04h - Set Loop End Location (Word to u_DataLo)
ÄÄÄ 05h - Set Loop End Location (Word to u_DataLo)
Through the use of these two registers, the ending location for
the active voice can be set. For an unknown reason, any memory
addresses for the BEGIN, START, and END sample locations in DRAM
must be divided by 128 and written to u_DataLo, then multiplied
by 512 and written to u_DataLo.
ÄÄÄ 06h - Set Volume Ramp Rate (Byte to u_DataHi)
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
³ 7 ³ 6 ³ 5 ³ 4 ³ 3 ³ 2 ³ 1 ³ 0 ³
ÀÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÙ
³ ³ ³ ³ ³ ³ ³ ³
³ ³ ³ ³ ³ ³ ³ ÀÄÄÄÄ¿
³ ³ ³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄÁ¿
³ ³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÁ¿ Increment
³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÙ
³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÂÙ
³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ¿ Scale
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÙ
Scale defines the rate at which the volume will be ramped based on
the increment. The increment will be added or subtracted from the
volume based on the increment.
The scale bits are:
00 - Update every access (fastest)
01 - Update every 8th access
10 - Update every 64th access
11 - Update every 512th access (slowest)
An increment of 63 will be the fastest possible ramp. It may,
depending on the scale, cause a zipper effect. Usually, increments
of 8 or less are suggested.
Also, don't ramp below 63 or above 4032. It creates an interesting
but mostly undesirable effect.
ÄÄÄ 07h - Set Volume Ramp Start (Byte to u_DataHi)
ÄÄÄ 08h - Set Volume Ramp End (Byte to u_DataHi)
These two registers set the start and end volumes for the volume
ramps. Note that only 8 bits per volume are sent, not 12 bits.
The low 4 bits of the volumes should be stripped off. The Volume
Ramp Start volume MUST be less than the Volume Ramp End volume even
if ramping down.
The bytes that will be output have this format:
EEEEMMMM
ÄÄÄ 09h - Set Current Volume (Word to u_DataLo)
This is used to set the current volume for the active voice. Note
that the volumes are not linear, but logarithmic. Volumes can range
from 0-4095 but must be shifted up 4 bits. Bits 3-0 are not used,
but bits 15-4 consist of the volume.
The volume consists of a 4-bit exponent (E) and an 8-bit mantissa (M).
EEEEMMMMMMMM----
As an example:
Current volume value Output level
ÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ
1111111111110000 Max Volume
1110111111110000 Half Volume
1101111111110000 Quarter Volume
1100111111110000 Eighth Volume
The mantissa is used to get a finer breakdown between the exponents.
Example:
mov dx,u_Voice
mov al,4 ; Use voice #4.
out dx,al
mov dx,u_Command
mov al,9 ; Set current volume.
out dx,al
mov dx,u_DataLo
mov ax,0fff0h ; Set max volume.
out dx,ax
Again, it would be wise to create a volume table covering the range
of your volumes.
ÄÄÄ 0ah - Set Loop Begin Location (Word to u_DataLo)
ÄÄÄ 0bh - Set Loop Begin Location (Word to u_DataLo)
Through the use of these two registers, the beginning location for
the active voice can be set. For an unknown reason, any memory
addresses for the BEGIN, START, and END sample locations in DRAM
must be divided by 128 and written to u_DataLo, then multiplied
by 512 and written to u_DataLo.
Note that this command is used to set the position of the pointer
for the current voice also, even while playing. Just make sure that
the voice is within the bounds you set.
ÄÄÄ 0ch - Set Voice Balance (Byte to u_DataHi)
This register will set the voice balance. Apparently there are 15
pan positions. However, this doesn't make sense since all the way
left is 0, all the way right is 15, and the middle is 7. Regardless,
this is how it works.
Example:
mov dx,u_Voice
mov al,5 ; Use voice #5.
out dx,al
mov dx,u_Command
mov al,0Ch ; Set Pan Position for voice 5.
out dx,al
mov dx,u_DataHi
mov al,7 ; Put it in the middle.
out dx,al
ÄÄÄ 0dh - Set Volume Control Register (Byte to u_DataHi)
ÚÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄÂÄÄÄ¿
³ 7 ³ 6 ³ 5 ³ 4 ³ 3 ³ 2 ³ 1 ³ 0 ³
ÀÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÁÄÂÄÙ
³ ³ ³ ³ ³ ³ ³ ³
³ ³ ³ ³ ³ ³ ³ ÀÄÄÄÄ 1 = Ramp is stopped
³ ³ ³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄ 1 = Stop Ramp
³ ³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄ ?
³ ³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 = No loop, 1 = Loop
³ ³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ 0 = Unidirectional, 1 = Bidirectional
³ ³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Enable volume ramp IRQ
³ ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Direction (1 = decreasing)
ÀÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ?
Example:
mov dx,u_Voice
mov al,1 ; Use voice #1.
out dx,al
mov dx,u_Command
mov al,0dh ; Volume Control Register.
out dx,al
mov dx,u_DataHi
mov al,00000011b ; Stop voice #1 ramp immediately.
out dx,al
ÄÄÄ 0eh - Set Highest Active Voices (Byte to u_DataHi)
This will set the maximum number of voices the card will process.
Apparently, the minimum number of voices is 14. Anything lower
is automatically set to 14.
Bear in mind that the more voices your application uses, not as
much oversampling occurs.
This byte MUST be OR'ed with 0C0h before output, and NumVoices must
be one less than those desired! (i.e. 14 Voices is 13 NumVoices)
Example:
mov dx,u_Command
mov al,0eh ; Set Highest Active Voice to:
out dx,al
mov dx,u_DataHi
mov al,NumVoices
or al,0C0h
out dx,al
ÄÄÄ 41h - DMA Control Register (Byte to u_DataHi)
Input : Clear any pending DMA IRQs.
Output: Unknown.
ÄÄÄ 43h - Low Word of DRAM address (Word to u_DataLo)
ÄÄÄ 44h - High Byte of DRAM address (Byte to u_DataHi)
DRAM addresses can range from 00000h to fffffh. By outputting the
DRAM address and then accessing u_DRAMIO, direct peeks and pokes from
the DRAM memory can be accomplished.
Example:
mov dx,u_Command
mov al,43h
out dx,al
mov dx,u_DataLo
mov ax,@@LoDRAMAddress
out dx,ax
mov dx,u_Command
mov al,44h
out dx,al
mov dx,u_DataHi
mov al,@@HiDRAMAddress
out dx,al
mov dx,u_DRAMIO
; At this point, you can either:
in al,u_DRAMIO ; Peek a byte from the address just output
; or:
out dx,al ; Poke a byte to the address just output.
ÄÄÄ 45h - Timer Control Register ??? (Byte to u_DataHi)
Input : Clear any pending timer IRQs.
Output: Something to do with Adlib Control. Hard coded into GUSMOD 1.2.
ÄÄÄ 46h - Timer Speed Register ??? (Byte to u_DataHi)
Used to set the internal 80 microsecond timer. Equation for output:
(256-Desired value)*80 microseconds.
ÄÄÄ 49h - Sample Control Register (Byte to u_DataHi)
Input : Clear any pending Sample Control IRQs.
Output: Unknown.
ÄÄÄ 4Ch - Initialization Register (Byte to u_DataHi)
If bit 1 is off, the Ultrasound is in an init state and cannot be
accessed.
ÄÄÄ 80h - Read Voice Mode (Byte from u_DataHi)
Reads what was output to register 0, Write Voice Mode.
ÄÄÄ 81h - Read Voice Frequency (Word from u_DataLo)
An input from here will read the current voice's frequency. Information
for conversion is contained in 01h - Set Voice Frequency.
ÄÄÄ 82h - Read Loop Start Location (Word from u_DataLo)
ÄÄÄ 83h - Read Loop Start Location (Word from u_DataLo)
Reading these registers will return the loopstart for the active voice.
Information on conversion is contained in register 8ah-8bh - Read Voice
Position.
ÄÄÄ 84h - Read Loop End Location (Word from u_DataLo)
ÄÄÄ 85h - Read Loop End Location (Word from u_DataLo)
Reading these registers will return the end location for the active
voice. Information on conversion is contained in register 8ah-8bh -
Read Voice Position.
ÄÄÄ 86h - Read Volume Ramp Rate (Byte from u_DataHi)
Reading this register will return the Volume Ramp Rate (described
in register 06h - Set Volume Ramp Rate).
ÄÄÄ 87h - Read Volume Ramp Start (Byte from u_DataHi)
ÄÄÄ 88h - Read Volume Ramp End (Byte from u_DataHi)
Reading these registers will return the Volume Ramp Start and End
information set with registers 07h - Set Volume Ramp Start and
08h - Set Volume Ramp End.
ÄÄÄ 89h - Read Volume (Word from u_DataLo)
Reads what was output to register 9, Set Current Volume.
ÄÄÄ 8ah - Read Voice Position (Word from u_DataLo)
ÄÄÄ 8bh - Read Voice Position (Word from u_DataLo)
Returns location of the current voice in DRAM that is the modified
address (i.e. divided by 128, multiplied by 512). The following
equation will convert it.
LOC = ((TEMP0 << 7) | (TEMP1 >> 9))
Example:
; In: AX - Voice
; Out: DX:AX - Linear Position, not shifted position.
U_ReadPos proc
mov dx,u_Voice
out dx,al
mov dx,u_Command
mov al,8ah
out dx,al
mov dx,u_DataLo
in ax,dx ; TEMP0
mov cx,ax
mov dx,u_Command
mov al,8bh
out dx,al
mov dx,u_DataLo
in ax,dx ; TEMP1
xor dx,dx
mov bx,cx
shl cx,7
shl dx,7
shr bx,9
or dx,bx
shr ax,9
and ax,7Fh
or cx,ax
mov ax,cx
ret
U_ReadPos endp
ÄÄÄ 8ch - Read Voice Balance (Byte from u_DataHi)
This register will read the voice balance. More information is
available about the returned result in register 0ch - Set Voice
Balance.
ÄÄÄ 8dh - Read Volume Control Register (Byte from u_DataHi)
Reading this register will return a byte corresponding to the active
voice's Volume Control information as described in register 0dh -
Read Volume Control Register.
ÄÄÄ 8eh - Read Highest Active Voice (Byte from u_DataHi)
Will return a byte corresponding to the number of voices the card
is mixing. Equation for English: Actual_Voices=(in 8eh)&0c0h+1.
ÄÄÄ 8fh - IRQ Status Register (Byte from u_DataHi)
Input : Unknown.
Output: Unknown.
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BASE + 104h - Data Low Port (u_DataLo)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BASE + 105h - Data High Port (u_DataHi)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
BASE + 107h - DRAM IO Port (u_DRAMIO)
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
Techniques:
ÄÄÄ Ultrasound Reset:
mov bx,u_Command
mov cx,u_DataHi
mov dx,bx
mov al,4Ch
out dx,al
mov dx,cx
mov al,0
out dx,al
@DELAY
@DELAY
mov dx,bx
mov al,4Ch
out dx,al
mov dx,cx
mov al,1
out dx,al
@DELAY
@DELAY
mov dx,bx
mov al,41h
out dx,al
mov dx,cx
mov al,0
out dx,al
mov dx,bx
mov al,45h
out dx,al
mov dx,cx
mov al,0
out dx,al
mov dx,bx
mov al,49h
out dx,al
mov dx,cx
mov al,0
out dx,al
mov dx,bx
mov al,0Eh
out dx,al
add dx,2
mov al,MaxVoices
or al,0C0h
out dx,al
mov dx,u_Status
in al,dx
mov dx,bx
mov al,41h
out dx,al
mov dx,cx
in al,dx
mov dx,bx
mov al,49h
out dx,al
mov dx,cx
in al,dx
mov dx,bx
mov al,8Fh
out dx,al
mov dx,cx
in al,dx
push bx cx
mov cx,0
@@VoiceClearLoop:
mov dx,u_Voice
mov al,cl
out dx,al
inc dx
mov al,0
out dx,al
add dx,2
mov al,3 ; Turn voice off
out dx,al
sub dx,2
mov al,0Dh ; Turn ramp off.
out dx,al
add dx,2
mov al,3
out dx,al
inc cx
cmp cx,32
jnz @@VoiceClearLoop
pop cx bx
mov dx,bx
mov al,41h
out dx,al
mov dx,cx
in al,dx
mov dx,bx
mov al,49h
out dx,al
mov dx,cx
in al,dx
mov dx,bx
mov al,8Fh
out dx,al
mov dx,cx
in al,dx
mov dx,bx
mov al,4Ch
out dx,al
mov dx,cx
mov al,7
out dx,al
ret
ÄÄÄ Starting a Volume Ramp:
1) Determine the volume ramp points.
2) Set the current volume register.
3) Set start volume.
4) Set end volume.
5) Set rate.
6) Set control register bits. (bits 0 and 1 off)
7) Wait for bit 0 to turn on.