Source file: /~heha/argon/multimed.zip/ADLIB/ADLIBA.ASM

        page    60, 132
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;   adliba.asm
;
;   Copyright (c) 1991-1992 Microsoft Corporation.  All Rights Reserved.
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        PMODE = 1

        .xlist
        include cmacros.inc                   
        .list

        ?PLM=1                          ; Pascal calling convention
        ?WIN=0                          ; NO! Windows prolog/epilog code


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;   debug support
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ifdef DEBUG
    extrn OutputDebugStr:far          ; mmsystem
    extrn _wDebugLevel:word           ; initc.c
endif

D1 macro text
    DOUT 1, < ",13,10,"ADLIB: &text&>
    endm
D2 macro text
    DOUT 2, < &text&>
    endm
D3 macro text
    DOUT 3, < &text&>
    endm
D4 macro text
    DOUT 4, < &text&>
    endm

DOUT macro level, text
    local   string_buffer
    local   wrong_level

ifdef DEBUG

_DATA segment
string_buffer label byte
    db      "&text&", 0
_DATA ends

    cmp     [_wDebugLevel], level
    jl      wrong_level
    push    ds
    push    DataOFFSET string_buffer
    call    OutputDebugStr
wrong_level:
endif
    endm

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;   assert macros
;
;   AssertF byte        -- fail iff byte==0
;   AssertT byte        -- fail iff byte!=0
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

AssertF     macro exp
    local   assert_ok
ifdef DEBUG
    push    ax
    
    mov     al, exp
    or      al, al
    jnz     assert_ok

    D1      <AssertF fail (&exp&)>
    int     3

assert_ok:
    pop     ax
endif
    endm

AssertT     macro exp
    local   assert_ok
ifdef DEBUG
    push    ax
    
    mov     al, exp
    or      al, al
    jz      assert_ok

    D1      <AssertT fail (&exp&)>
    int     3

assert_ok:
    pop     ax
endif
    endm


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;   data segment
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

sBegin Data

        externW <_wPort>                ; address of sound chip
        externW <_wWriteDelay>          ; delay time for write

sEnd Data

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
;   code segment
;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ifndef SEGNAME
        SEGNAME equ <_TEXT>
endif

createSeg %SEGNAME, CodeSeg, word, public, CODE

sBegin  CodeSeg

        assumes cs, CodeSeg
        assumes ds, Data

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; @doc INTERNAL 
;
; @api BYTE | inport | Read a port.
;
; @parm WORD | port | The port to read.
;
; @rdesc Returns the port value read.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        assumes ds, Data
        assumes es, nothing

cProc inport <FAR, PUBLIC> <>
cBegin nogen

        mov     dx, [_wPort]
        in      al, dx

        D4 <I:#AL>

        retf

cEnd nogen


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; @doc INTERNAL 
;
; @api void | SndOutput | This function writes data to the chip registers.
;
; @parm BYTE | bRegister | The address of the register to write.
;
; @parm BYTE | bData | The data value to write.
;
; @rdesc There is no return value.
;
; @comm Delay is included after each write.  Current implementation is less
;     than ideal - I'm currently investigating methods of calculating the
;     real number of cycles needed (which requires determining machine speed)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        assumes ds, Data
        assumes es, nothing

cProc SndOutput <FAR, PUBLIC> <>
        ParmB   bRegister               ; register address
        ParmB   bData                   ; value to write
cBegin

ifdef DEBUG
        mov     al, bRegister
        mov     ah, bData
        D4 <O:#AL,#AH>
endif

        mov     dx, [_wPort]            ; get register select address of sound chip
        mov     al, bRegister           ; register number to write to
        out     dx, al

;   A a minimum of 3.3 us delay is needed after selecting register:

        mov     cx, [_wWriteDelay]      ; 5/4/1 cycles
@@:     dec     cx                      ; 2/2/1 cycles
        jnz     @B                      ; 9/9/3 cycles (3/3/1 last time)

        inc     dx                      ; data write address of chip (2/2/1 cycles)
        mov     al, bData               ; value to write (5/4/1 cycles)
        out     dx, al

;   A a minimum of 23 us delay is needed after writing a note:

        mov     ax, [_wWriteDelay]      ; 5/4/1 cycles
        mov     bx, 7                   ; 2/2/1 cycles
        mul     bx                      ; 21/9/13 cycles
@@:     dec     ax                      ; 2/2/1 cycles
        jnz     @B                      ; 9/9/3 cycles (3/3/1 last time)

cEnd


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; @doc INTERNAL
;
; @asm WEP | This function is called when the DLL is unloaded.
;
; @parm WORD | UselessParm | This parameter has no meaning.
;
; @comm WARNING: This function is basically useless since you can't call any
;     kernel function that may cause the LoadModule() code to be reentered.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        assumes ds, nothing
        assumes es, nothing

cProc WEP <FAR, PUBLIC, PASCAL>, <>
;       ParmW   wUselessParm
cBegin nogen
        mov     ax, 1
        retf    2
cEnd nogen

sEnd CodeSeg

        end
Detected encoding: ASCII (7 bit)2