;*DDK*************************************************************************/
;
; COPYRIGHT (C) Microsoft Corporation, 1989
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
        PAGE    60,132
        TITLE   IPMIMISC.ASM --
;/*****************************************************************************
;*
;* SOURCE FILE NAME = IPMIMISC.ASM
;*
;* DESCRIPTIVE NAME = 16 bit .286 Clock routines for Diamond Stealth.
;*
;*
;* VERSION      V2.0
;*
;* DATE
;*
;* DESCRIPTION
;*
;* FUNCTIONS
;*
;*
;* NOTES        NONE
;*
;* STRUCTURES   NONE
;*
;* EXTERNAL REFERENCES
;*
;*              NONE
;*
;* EXTERNAL FUNCTIONS
;*
;*              NONE
;*
;* CHANGE ACTIVITY =
;*   DATE      FLAG        APAR   CHANGE DESCRIPTION
;*   --------  ----------  -----  --------------------------------------
;*   mm/dd/yy  @Vr.mpppxx  xxxxx  xxxxxxx
;*   06/02/93             F69306  Hi-color support for Diamond
;*   07/12/93                     Add Diamond clock support for 1280
;*   10/06/93              72687  Add Number Nine clock support for S3
;*   10/21/93              74890  Use hi-color entries in ext clock tbl for 24bpp
;*   10/21/93              75044  Remove YEE04 fix
;*   11/01/93             D75458  Merge r206v, r205, r206, r207 S3 code
;*   02/17/94             D78589  72Hz Refresh Rate for Diamond: Clock Index
;*   04/22/94                     fix #9 VL clock
;*   07/16/94              89439  Build break, _Pascal is not recognized.
;*****************************************************************************/

.386p
;/*
;**  Include files
;*/

        include struc.inc               ; Structured assembly macros
        include svgadefs.inc            ; 

        PUBLIC  SETDIAMONDCLK_S3

CODE32    SEGMENT DWORD USE32 PUBLIC 'CODE'
                ASSUME CS:FLAT, DS:FLAT, ES:NOTHING
                ALIGN   4
R_from_16              LABEL FAR
CODE32  ENDS

CODE2_16  SEGMENT WORD USE16 PUBLIC 'CODE'
                ASSUME CS:CODE2_16, DS:NOTHING, ES:NOTHING
                ALIGN  4
fixup:
        jmp far ptr FLAT:R_from_16
CODE2_16  ENDS
CODE16  SEGMENT WORD USE16 PUBLIC 'CODE'
                ASSUME CS:CODE16, DS:NOTHING, ES:NOTHING
.286p
;;;;;;;;;;begin code for stealth 24
;
eeprom_tab_l            equ     20/2            ;10 words
index_m640              equ     0
index_m640h             equ     1
index_m640t             equ     2
index_m800              equ     3
index_m800h             equ     4
index_m800t             equ     5
index_m1024             equ     6
index_m1024h            equ     7
index_m960              equ     8
index_m1280_16          equ     9
index_m1280_256         equ     10
index_m5455             equ     11

COUNTER                 equ     7fh             ; 2K x 1
mon_port                equ     3c2h
mon_bit                 equ     10h
Read_Miscellaneous      EQU     03CCH           ;Misc output read register

Sequencer               EQU     03C4H           ;Sequencer index register

CRT_3B4                 EQU     03B4H           ;Monochrome CRT index addr
CRT_3D4                 EQU     03D4H           ;Monochrome CRT index addr
BT_FIX                  equ     1
;---------------------------------------------------------------------------
;       EEPROM Data Format (Each entry 20 bytes)
;       db      0       ;bit7=vpol. bit6=hpol. bit5=interlace
;                        bit4,3   = reserved
;                        bit2,1,0 = entry
;       db      0,0,0   ;clock data (3 bytes)
eeprom_reg_index        label   byte
        db      3bh,0,1,2,3,4,5,6,7,10h,11h,16h,17h,5Dh,33h,0ffh

org_5c         label byte
        db      0
;
;---------------------------------------------------------------------------
;       input   (al)=eeprom table entry address
;       output  all registers saved except (ax)

upd_crtc_eeprom:
        push    bx
        push    cx
        push    dx
        push    ax
        call    Find_6845_Address
        mov     ax,0011h                ;unlock crtc
        out     dx,ax
        pop     ax
        mov     bx, offset cs:eeprom_reg_index
        push    ax              ;(al)=address of eeprom +0
        inc     al              ;(al)=address of eeprom +1
;       inc     al              ;(al)=address of eeprom +2
pp_1:   inc     al              ;(al)=address of eeprom +3
        push    ax
        call    read_eeprom
        mov     cx,ax
        mov     al,cs:[bx]
        cmp     al,0ffh
        jz      pp_2
        mov     ah,cl
        out     dx,ax
        inc     bx
        mov     al,cs:[bx]
        cmp     al,0ffh
        jz      pp_2
        mov     ah,ch
        out     dx,ax
        inc     bx
        pop     ax
        jmp     pp_1

pp_2:   pop     ax
        pop     ax
        push    ax
        call    read_eeprom
        mov     cx,ax
        ;--------------------------------------------;
        ;  update vclk params & interlaced bit       ;
        ;--------------------------------------------;
;set interlace & clock select
        mov     ah,cl
        and     ah,28h          ;entry.5 interlace bit of cr42.5
                                ;entry.3 clk3 bit of cr42.3
        or      ah,3            ;clock select 0,1
        mov     al,42h          ;crtc 42 (clock & interlace)
        out     dx,ax
;set polarity
        push    dx
        mov     dx,3cch
        in      al,dx
        and     al,3fh
        and     cl,0c0h         ;polarity
        or      al,cl
        or      al,0ch          ;clock force to extended
        mov     dx,3c2h
        out     dx,al
        pop     dx
;clock program
        mov     bh,ch           ;1st byte
        pop     ax
        inc     al              ;offset +1
        call    read_eeprom
        mov     cl,al           ;2nd byte
        mov     bl,ah           ;3rd byte
;
        call    program_clk_chip_stl24

        pop     dx
        pop     cx
        pop     bx
        jmp     far ptr CODE2_16:fixup
;        ret
;
;---------------------------------------------------------------------------
;       input   (cl)= 2nd byte, (bh)=1st byte, (bl)= 3rd byte
;       output  bx,cx destroed
;
;;      public  program_clk_chip_stl24
program_clk_chip_stl24 :
        push    ax
        push    dx

        mov     dx,3c4h
        mov     al,1
        out     dx,al
        mov     ah,al
        inc     dx
        in      al,dx
        push    ax
        or      al,20h
        out     dx,al           ;screen off

        call    Find_6845_Address
        mov     ax,0a039h       ;unlock sc regs
        out     dx,ax
        mov     ax,04838h       ;unlock s3 regs
        out     dx,ax

        mov     ch,80h          ;25     ;1000   ;25
skip_0_stl24:
        push    bx
        push    cx
        call    p_clock_stl24
        pop     cx
        pop     bx
        mov     dx,3c2h
        in      al,dx
        test    al,10h
        jnz     skip_2_stl24
        dec     ch
        jnz     skip_0_stl24
skip_2_stl24:

        mov     dx,3c4h
        mov     al,1
        out     dx,al
        inc     dx
        pop     ax              ;screen recover
        out     dx,al           ;LIN fix 12/17/92 should be al ; not ax

        call    wait_vertical_retrace_stl24
        call    wait_vertical_retrace_stl24

        pop     dx
        pop     ax
        ret

;
;---------------------------------------------------------------------------
;public p_clock
p_clock_stl24:
        mov     dx,3cch         ;read misc. out reg
        in      al,dx
        push    ax              ;save value
        or      al,0ch
        mov     dx,3c2h
        out     dx,al
        call    Find_6845_Address
        mov     al,42h          ;sc2
        out     dx,al
        xchg    al,ah
        inc     dx
        in      al,dx
        xchg    al,ah
        dec     dx
        push    ax              ;previous vclock selection

;unlock seq
        or      ah,2            ;data high
        mov     ch,6    ;5      ;toggle clk 5 times
        cli
kk_1_stl24:
        and     ah,0feh         ;clock low
        out     dx,ax
        out     dx,ax
        or      ah,1            ;clock high
        out     dx,ax
        out     dx,ax
        dec     ch
        jnz     kk_1_stl24

        and     ah,0feh
        out     dx,ax
        out     dx,ax
        and     ah,0fch         ;clock low data low
        out     dx,ax
        out     dx,ax
        or      ah,1            ;clock high
        out     dx,ax
        out     dx,ax
        and     ah,0fch         ;clock low data low
        out     dx,ax
        out     dx,ax
        or      ah,1            ;clock high
        out     dx,ax
        out     dx,ax
;
        mov     ch,24
Send_Serial_stl24:
        and     ah,0fdh         ;send inverted data first
        shl     bx,1
        rcl     cl,1
        jc      Send_Serial_1_stl24
        or      ah,2
Send_Serial_1_stl24:
        out     dx,ax           ;not data out
        out     dx,ax
        and     ah,0feh         ;clock low
        out     dx,ax
        out     dx,ax
        xor     ah,2            ;now real data out
        out     dx,ax
        out     dx,ax
        or      ah,1            ;clock high
        out     dx,ax
        out     dx,ax
        dec     ch
        jnz     Send_Serial_stl24
;stop bit
        or      ah,2            ;data_high
        out     dx,ax
        out     dx,ax
        and     ah,0feh         ;clock low
        out     dx,ax
        out     dx,ax
        or      ah,1            ;clock high
        out     dx,ax
;
        pop     ax
        out     dx,ax           ;restore prev. clock for vertical retrace
        out     dx,ax
;
        pop     ax              ;save value
        mov     dx,3c2h         ;misc. out reg for vclock recover
        out     dx,al
        sti
        ret
;
;----------------------------------------------------------------------------
;        public  wait_vertical_retrace
;
wait_vertical_retrace_stl24:
        push    ax
        push    cx
        push    dx
        call    Find_6845_Address               ;Get CRTC address
        add     dl,6

        mov     cx,0
wv_0:   in      al,dx
        test    al,8
        jnz     wv_1
        loop    wv_0

        mov     cx,0
wv_1:   in      al,dx
        test    al,8
        jz      wv_2
        loop    wv_1

wv_2:   pop     dx
        pop     cx
        pop     ax
        ret
;
;---------------------------------------------------------------------------
        ;input al=adress, unlocked
        ;output ax=data
        ;all registers reserved
read_eeprom:
        push    bx
        mov     bx,ax
        call    read_conf
        pop     bx
        ret
;
;---------------------------------------------------------------------------
        ;input bl=adress
        ;output ax=data
        ;all registers reserved
read_conf:
        push    bx
        push    cx
        push    dx
        call    init_ports      ;video disabled ,crtc 41 bit1 set
                                ;(dx)=3d5/3b5   crtc index = 5ch selected
                                ;(al)=crtc 5ch data
;
        mov     bh,bl
        push    bx
        mov     cx,4
        mov     bx,0110000000000000b
        call    send_data_stl24 ;send read command
        pop     bx

        mov     cx,9
        call    send_data_stl24 ;send address
        mov     cx,16
        mov     bx,0
rc_1:
        and     al,0efh         ;clock low
        call    del_out
        shl     bx,1

        push    dx
        push    ax
        mov     dx,mon_port
        in      al,dx
        test    al,mon_bit
        pop     ax
        pop     dx

        jz      rc_2
        or      bl,1
rc_2:
        or      al,10h          ;clock high
        call    del_out
        loop    rc_1

        and     al,0efh         ;clock low
        call    del_out
;LIN    and     al,0bfh          ;chip select low
;LIN    call    del_out
        call    recover_ports
        mov     ax,bx
        pop     dx
        pop     cx
        pop     bx
        ret

;
;---------------------------------------------------------------------------
init_ports:
        mov     dx,3c4h
        mov     al,1
        out     dx,al
        inc     dx
        in      al,dx
        or      al,20h          ;screen off
        out     dx,al

        mov     dx,3cch
        in      al,dx
        mov     dx,3d4h
        test    al,1
        jnz     init_1
        mov     dx,3b4h
init_1:
        mov     ax,04838h
        out     dx,ax           ;unlock s3
        mov     ax,0a539h
        out     dx,ax           ;unlock sc

        mov     al,5ch
        out     dx,al
        inc     dx
        in      al,dx

        mov     byte ptr cs:[org_5c] ,al           ; save the original cr.5c

        or      al,40h          ;enable chip
        and     al,0cfh
        out     dx,al
        ret
;
;---------------------------------------------------------------------------
recover_ports:
        mov     al, byte ptr cs:[org_5c]          ; recover the original cr.5c
        and     al,0bfh         ;chip select low
        call    del_out         ;out dx(3d5.5c),al

        dec     dx              ;3d4/3b4
        mov     ax,038h
        out     dx,ax           ;lock s3
        mov     ax,039h
        out     dx,ax           ;lock sc

        mov     dx,3c4h
        mov     al,1
        out     dx,al
        inc     dx
        in      al,dx
        and     al,0dfh         ;screen on
        out     dx,al
        ret

        ;input bl=adress, (ax)=data
        ;output  all registers reserved

chk_ready:
        push    dx
        push    ax
wait_1: mov     dx,mon_port
        in      al,dx
        test    al,mon_bit
        jz      wait_1
        pop     ax
        pop     dx
        ret

a_clock:
        and     al,0dfh         ;data low
        or      al,10h          ;clock high
        call    del_out
        and     al,0efh         ;clock low
        call    del_out
        ret
;
;---------------------------------------------------------------------------
send_data_stl24:
        and     al,0cfh
        shl     bx,1
        jnc     send_data_1_stl24
        or      al,20h
send_data_1_stl24:
        call    del_out         ;data & clock low
        or      al,10h
        call    del_out         ;clock high
        loop    send_data_stl24
        ret

del_out:
        out     dx,al
        out     dx,al
        out     dx,al
        out     dx,al
        out     dx,al
        out     dx,al
        out     dx,al
        out     dx,al
        out     dx,al
        out     dx,al
        ret
;
;---------------------------------------------------------------------------
Find_6845_Address PROC
        PUSH    AX
        MOV     DX,Read_Miscellaneous           ;Get Misc read register
        IN      AL,DX                           ;Read the register
        MOV     DX,CRT_3B4                      ;Set Mono
        TEST    AL,01                           ;0 - MONO 1 - Color
        JE      Set_Mono                        ;Return Mono
        MOV     DX,CRT_3D4                      ;Set Color

Set_Mono:
        POP     AX
        RET
Find_6845_Address ENDP
;
;end code for stealth 24
;/***************************************************************************
;*
;* FUNCTION NAME = VGAWait
;*
;* DESCRIPTION   = wait for video retrace before a write to port
;*                 3C0h, register 10h
;*
;*                 ENTRY POINT: VGAWait
;*                 LINKAGE:   CALL FAR
;*
;* INPUT         = NONE
;*
;* RETURN-NORMAL = NONE
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/

VGAWait PROC    NEAR
        sti
        push    ax
        push    cx
        push    dx
        MOV     DX,Read_Miscellaneous        ;Get Misc read register
        IN      AL,DX                        ;Read the register
        MOV     DX,3bah                      ;Set Mono
        TEST    AL,01                        ;0 - MONO 1 - Color
        JE      _Mono                        ;Return Mono
        MOV     DX,3dah                      ;Set Color

_Mono:
        xor     cx,cx           ; time out in case a card never sets this bit
VGAWait1:
        in      al,dx
        test    al,8            ; look for retrace bit
        loopnz  VGAWait1        ; wait for retrace to end
        xor     cx,cx           ; time out in case a card never sets this bit
VGAWait2:
        sti
        nop
        nop                     ; 486     work around
        cli
        in      al,dx
        test    al,8            ; look for retrace bit
        loopz   VGAWait2        ;wait for retrace to begin again

        pop     dx
        pop     cx
        pop     ax
        ret
VGAWait ENDP


CODE16     ENDS

.386p

CODE32    SEGMENT
          ASSUME CS:FLAT, DS:FLAT, ES:NOTHING
        .errnz ($ - R_from_16)                    ; label defining return jmp location
        jmp return_from_upd
;/***************************************************************************
;*
;* FUNCTION NAME = SETDIAMONDCLK_S3
;*
;* DESCRIPTION   = Set the video clock on diamond stealth /Pro on per
;*                 mode basis.
;*
;*                 ENTRY POINT: SetDiamondClk_S3
;*                 LINKAGE:   CALL NEAR
;*
;* INPUT         = (Passed on stack)
;*                 ULONG HResolution
;*                 ULONG nColor
;*
;* RETURN-NORMAL = Specified clock bits set serially.
;* RETURN-ERROR  = NONE
;*
;**************************************************************************/
;HRes            equ     WORD  PTR [ebp+0ch]         ;                     
;nColor          equ     WORD  PTR [ebp+8]
HRes            equ     WORD  PTR [ebp+08]   ;          
nColor          equ     WORD  PTR [ebp+0ch]  ;          
SETDIAMONDCLK_S3        PROC  NEAR
        push    ebp
        mov     ebp, esp
        push    edi
        push    esi
        push    ebx
        mov     dx, word ptr HRes
        mov     cx, word ptr nColor              ;get #colors                               ;          
        mov     ax,eeprom_tab_l*index_m1024
        cmp     dx, 1024
        jne     short res_800

        cmp     cx, 16                  ;check for hi-color               
        jne     @F
        mov     ax,eeprom_tab_l*index_m1024h
@@:
        jmp     update_eeprom

res_800:
        cmp     dx, 800
        jne     short res_640
        cmp     cx, 16                  ;check for hi-color               
        jne     @F
        mov     ax,eeprom_tab_l*index_m800h
        jmp     short   update_eeprom

@@:
        cmp     cx, 24                  ;check for true-color             
        jne     @F
        mov     ax,eeprom_tab_l*index_m800t                    ;          
        jmp     short   update_eeprom

@@:
        mov     ax,eeprom_tab_l*index_m800
        jmp     short   update_eeprom

res_640:
        cmp     dx, 640
        jne     res_1280                ;check for 1280 res               
        cmp     cx, 16                  ;check for hi-color               
        jne     @F
        mov     ax,eeprom_tab_l*index_m640h
        jmp     short   update_eeprom

@@:
        cmp     cx, 24                  ;check for true-color             
        jne     @F
        mov     ax,eeprom_tab_l*index_m640t                    ;          
        jmp     short   update_eeprom

@@:
        mov     ax,eeprom_tab_l*index_m640
        jmp     short   update_eeprom

res_1280:                               ;          
        cmp     dx, 1280
        jne     @F
;;;;;;; Index_m1280_256 (10 = computed value of 64h) yields a flickering or   ;          
;;;;;;; strobe effect on the OS/2 and WinOS/2 desktop after a save/restore    ;          
;;;;;;; on 1280x1024x256.  Index_m1280_16 (9 = computed value of 5Ah) works   ;          
;;;;;;; for all refresh rates supported by the StlMode Utility (43.5, 60, 72) ;          
;;      mov     ax,eeprom_tab_l*index_m1280_256                               ;          
        mov     ax,eeprom_tab_l*index_m1280_16                                ;          
        jmp     short   update_eeprom

@@:
        cmp     dx, 1056
        jne     @F
        mov     ax,eeprom_tab_l*index_m5455
@@:
update_eeprom:
        jmp     FAR PTR upd_crtc_eeprom

return_from_upd:
        pop     ebx
        pop     esi
        pop     edi
        pop     ebp
;        ret     8            
        ret
SETDIAMONDCLK_S3  ENDP
CODE32  ENDS

END


