home *** CD-ROM | disk | FTP | other *** search
-
- page 64,131
- Title MVOUT -- Pro Audio Spectrum direct I/O
-
- ; /*\
- ;---|*|-------------------------====< MVOUT >====-------------------------
- ;---|*|
- ;---|*| This module contains some code for supporting direct I/O to the PAS
- ;---|*| where the hardware is write only. All calls reference the state
- ;---|*| table to guarrantee proper I/O values.
- ;---|*|
- ;---|*| Media Vision, Inc. Copyright (c) 1991,1992. All Rights Reserved.
- ;---|*|
- ; \*/
-
-
- .xlist
- include model.inc
- include masm.inc
- include state.inc
- include common.inc
- .list
-
- externADDR MVInitStatePtr ; state table pointer stuff
- externADDR mvGetHWVersion ; find the board address...
-
- if MODELSIZE eq 0
- .code
- else
- .data
- endif
-
- ;
- ; The following label allows us to calculate an offset for the tables of
- ; addresses
- ;
- FirstDataByte label byte ; !!!!!! must be the 1st entry in
- ; ; the data segmment!!!
- ;
- ; our first pass flag - set to -1 for first entry, will be zeroed out
- ;
- invmso_first db -1 ; -1 for first pass, to be zeroed out
-
- ;
- ; Hardware Shadowing Table of Registers
- ;
- public shadowregtable
- shadowregtable label word
- dw SYSSPKRTMR ; 00042h ; System Speaker Timer Address
- dw SYSTMRCTLR ; 00043h ; System Timer Control Register
- dw SYSSPKRREG ; 00061h ; System Speaker Register
- dw JOYSTICK ; 00201h ; Joystick Register
- dw LFMADDR ; 00388h ; Left FM Synthesizer Address Register
- dw LFMDATA ; 00389h ; Left FM Synthesizer Data Register
- dw RFMADDR ; 0038Ah ; Right FM Synthesizer Address Register
- dw RFMDATA ; 0038Bh ; Right FM Synthesizer Data Register
- dw DFMADDR ;AUXADDR; 00788h ; Dual FM Synthesizer Address Register
- dw DFMDATA ;AUXDATA; 00789h ; Dual FM Synthesizer Data Register
- dw 0 ; 0078Ah ; reserved for future use
- dw 0 ; 0078Bh ; reserved for future use
- dw AUDIOMIXR ; 00B88h ; Audio Mixer Control Register
- dw INTRCTLRST ; 00B89h ; Interrupt Status Register
- dw AUDIOFILT ; 00B8Ah ; Audio Filter Control Register
- dw INTRCTLR ; 00B8Bh ; Interrupt Control Register
- dw PCMDATA ; 00F88h ; PCM data I/O register
- dw 0 ; 00F89h ; reserved for future use
- dw CROSSCHANNEL ; 00F8Ah ; Cross Channel
- dw 0 ; 00F8Bh ; reserved for future use
- dw SAMPLERATE ; 01388h ; Sample Rate Timer Register
- dw SAMPLECNT ; 01389h ; Sample Count Register
- dw SPKRTMR ; 0138Ah ; Local Speaker Timer Address
- dw TMRCTLR ; 0138Bh ; Local Timer Control Register
- dw MDIRQVECT ; 01788H ; MIDI IRQ Vector Register
- dw MDSYSCTLR ; 01789H ; MIDI System Control Register
- dw MDSYSSTAT ; 0178AH ; MIDI IRQ Status Register
- dw MDIRQCLR ; 0178BH ; MIDI IRQ Clear Register
- dw MDGROUP4 ; 01B88H ; MIDI Group #4 Register
- dw MDGROUP5 ; 01B89H ; MIDI Group #5 Register
- dw MDGROUP6 ; 01B8AH ; MIDI Group #6 Register
- dw MDGROUP7 ; 01B8BH ; MIDI Group #7 Register
-
- SHADOWTABLELEN equ 28 ; 28 entries in the shadow data table
-
- ;
- ; Storage Locations for the data
- ;
- public shadowdatatable
- shadowdatatable label word
- dw offset _sysspkrtmr ; 00042h ; System Speaker Timer Address
- dw offset _systmrctlr ; 00043h ; System Timer Control Register
- dw offset _sysspkrreg ; 00061h ; System Speaker Register
- dw offset _joystick ; 00201h ; Joystick Register
- dw offset _lfmaddr ; 00388h ; Left FM Synthesizer Address Register
- dw offset _lfmdata ; 00389h ; Left FM Synthesizer Data Register
- dw offset _rfmaddr ; 0038Ah ; Right FM Synthesizer Address Register
- dw offset _rfmdata ; 0038Bh ; Right FM Synthesizer Data Register
- dw offset _dfmaddr ; 00788h ; Dual FM Synthesizer Address Register
- dw offset _dfmdata ; 00789h ; Dual FM Synthesizer Data Register
- dw 0 ; 0078Ah ; reserved for future use
- dw 0 ; 0078Bh ; reserved for future use
- dw offset _audiomixr ; 00B88h ; Audio Mixer Control Register
- dw offset _intrctlrst ; 00B89h ; Interrupt Status Register
- dw offset _audiofilt ; 00B8Ah ; Audio Filter Control Register
- dw offset _intrctlr ; 00B8Bh ; Interrupt Control Register
- dw offset _pcmdata ; 00F88h ; PCM data I/O register
- dw 0 ; 00F89h ; reserved for future use
- dw offset _crosschannel ; 00F8Ah ; Cross Channel
- dw 0 ; 00F8Bh ; reserved for future use
- dw offset _samplerate ; 01388h ; Sample Rate Timer Register
- dw offset _samplecnt ; 01389h ; Sample Count Register
- dw offset _spkrtmr ; 0138Ah ; Local Speaker Timer Address
- dw offset _tmrctlr ; 0138Bh ; Local Timer Control Register
- dw offset _mdirqvect ; 01788H ; MIDI IRQ Vector Register
- dw offset _mdsysctlr ; 01789H ; MIDI System Control Register
- dw offset _mdsysstat ; 0178AH ; MIDI IRQ Status Register
- dw offset _mdirqclr ; 0178BH ; MIDI IRQ Clear Register
- dw offset _mdgroup1 ; 01B88H ; MIDI Group #4 Register
- dw offset _mdgroup2 ; 01B89H ; MIDI Group #5 Register
- dw offset _mdgroup3 ; 01B8AH ; MIDI Group #6 Register
- dw offset _mdgroup4 ; 01B8BH ; MIDI Group #7 Register
-
- extrn mvhwShadowPointer :dword
- extrn _MVTranslateCode :word ; hardware I/O offset
- extrn _MVHWVersionBits :word ; hardware bits
-
- ;
- ;---------------------------========================---------------------------
- ;---------------------------====< CODE SECTION >====---------------------------
- ;---------------------------========================---------------------------
- ;
- .code
-
- ;
- ; /*\
- ;---|*|
- ;---|*|---------------====< Prototypes >====---------------
- ;---|*|
- ;---|*| void MVOut( int, int, int )
- ;---|*|
- ;---|*| Output a masked byte directly to the hardware, and return the new value
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| wParm1 is the port address
- ;---|*| wParm2 is the and mask of bits to be written
- ;---|*| wParm3 is the xor data to be written
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| if wParm2 = 0, al = read from hardware, ah = shadowed data
- ;---|*| if wParm2 = !0, value is written to the hardware & shadow table
- ; \*/
- ;
- public MVOut
- MVOut PROC
- push bp
- mov bp,sp
- ;
- ; this code can only be processed once per loading
- ;
- cmp [invmso_first],-1 ; have we been here?
- jnz @F ; yes, don't do this again
- mov [invmso_first],0 ; no, so pass by just once
- call __initmvout
- call MVInitStatePtr ; initialize the state table
- @@:
- ;
- ; perform the read from the state table, or write to the hardware
- ;
- push es
-
- mov dx,wParm1 ; port address
-
- call _getregisterptr ; get the shadow hardware register ptr
- jc mvout_exit ; IO address not found
-
- mov cx,wParm2 ; mask
- mov ax,wParm3 ; data
-
- jcxz mvout_read ; read request, just return the data
-
- and al,cl ; merge new and old bits
- not cl ; get the other bits
- and cl,es:[bx] ; from the shadow state
- or al,cl ; and merge them in
- xor dx,[_MVTranslateCode] ; xlate the board address
- out dx,al ; output to the hardware
- mov es:[bx],al ; save the new state
- ;
- mvout_exit:
- pop es
- pop bp
- ret
- ;
- mvout_read:
- mov al,es:[bx] ; gets the value from the state table
- jmp short mvout_exit
-
- MVOut endp
-
- ;
- ; /*\
- ;---|*|---------------====< __initmvout() >====---------------
- ;---|*|
- ;---|*| Initializes this body of code. It will try to find the int 2F DOS
- ;---|*| interface to the MVPROAS device. Once found, the new state table
- ;---|*| pointer will be loaded.
- ;---|*|
- ;---|*| Entry Conditions:
- ;---|*| None
- ;---|*|
- ;---|*| Exit Conditions:
- ;---|*| DX:AX point to the state table
- ; \*/
-
- __initmvout proc near
- push es
- push di
- mov ax,ds
- mov es,ax
- ;
- ; adjust the shadow data table offsets to the correct linked offset
- ;
- mov cx,SHADOWTABLELEN ; table length...
- lea bx,FirstDataByte ; the compiled offsets must be adjusted
- lea di,shadowdatatable ; DI points to the table
- ;
- @@:
- add es:[di],bx ; move the offsets in the table
- inc di
- inc di
- loop @B
-
- cmp [_MVHWVersionBits],-1 ; already found?
- jnz inmv_done ; yes, continue on..
-
- mov ax,USE_ACTIVE_ADDR ; defaults to the original address
- push ax
- call mvGetHWVersion ; find the board address...
- add sp,2
- ;
- inmv_done:
- pop di
- pop es
- ret
-
- __initmvout endp
-
- ;
- ;---------------------====< _getregisterptr >====---------------
- ;
- ; Get a pointer to the state table
- ;
- ; Entry Conditions:
- ; DX holds the port address
- ;
- ; Exit Conditions:
- ; ES:BX holds the pointer, no other registers modified
- ;
- _getregisterptr proc near
- push di ; no toucha dees...
- push cx
-
- mov cx,ds
- mov es,cx
- lea di,shadowregtable ; look in the register table
- mov cx,SHADOWTABLELEN
-
- xchg ax,dx ; ax holds the port address
- cld
- repne scasw
- xchg ax,dx ; restore 'em...
-
- stc ; just in case we bomb out
- jne @F ; no match, bomb out...
-
- if MODELSIZE eq 0
- assume es:@code ; tiny (.com) model is same as code
- else
- assume es:@data ; all other has a data segment
- endif
-
- sub di,offset shadowregtable+2 ; create an offset into the table
- mov bx,es:[shadowdatatable+di] ; bx = the offset from the 1st ptr
- mov di,es:[shadowdatatable+0] ; grab the first ptr
- sub bx,di ; bx holds a zero based offset
- les di,mvhwShadowPointer ; get the true state table pointer
- add bx,di ; bx now points into the true table
- assume es:nothing
-
- clc ; was found, indicate so...
- ;
- @@:
- pop cx
- pop di
- ret
-
- _getregisterptr endp
-
- ; /*\
- ;---|*| end of MVOut
- ; \*/
-
- end
-
-