;*DDK*************************************************************************/
;
; 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.;
;*****************************************************************************/
; 
; Build up the sprite (hardware cursor pattern) data
;
;
.DATA

public    make_sprite_data_rtns
make_sprite_data_rtns   dd      0
                        dd      offset default_make_sprite_rtn
                        dd      offset default_make_sprite_rtn
                        dd      offset default_make_sprite_rtn
                        dd      offset wd_make_sprite_rtn
                        dd      offset default_make_sprite_rtn
                        dd      offset spdway_make_sprite_rtn
                        dd      offset cirrus_make_sprite_rtn
ifdef  INCL_S3        ;IBMJ
                        dd      offset bga_make_sprite_rtn
endif ;INCL_S3        ;IBMJ

public make_sprite_data_rtn
make_sprite_data_rtn    dd      offset default_make_sprite_rtn

.CODE

default_make_sprite_rtn proc near
        ret
default_make_sprite_rtn endp


public    wd_make_sprite_rtn
wd_make_sprite_rtn proc near
;
WD_CURSOR_ADDR_LOW  equ  1000h
WD_CURSOR_ADDR_HI   equ  2000h
; input :  esi ---> CurData.BaseAndMasks
;          edi ---> sprite data
;          ecx is MASK_LENGTH

        push    esi                          ; save source origin
        push    edi                          ; save destination origin
        push    ecx                          ; save byte count

wd_Fill_And_Pattern:
        mov     al,[esi]
        mov     [edi],al
        inc     esi
        inc     edi
        inc     edi
        loop    wd_Fill_And_Pattern
;
        pop     ecx                          ; restore count
        pop     edi                          ; restore destination origin
        pop     esi                          ; restore source origin
;
        add     esi,ecx                      ; ESI --> CurData.BaseXorMasks
        inc     edi                          ; EDI --> sprite data + 1
wd_Fill_Xor_Pattern:
        mov     al,[esi]
        mov     [edi],al
        inc     esi
        inc     edi
        inc     edi
        loop    wd_Fill_Xor_Pattern

; sprite register setting

        mov     dx,23c0h
        mov     al,02h
        out     dx,al                   ; select h/w cursor register

        mov     dx,23c2h
        mov     eax,CurData.sprite_data_origin
        shr     eax,2                   ; eax holds Cursor Pattern Address

        push    eax                     ; save address
        and     ax,0000111111111111b
        or      ax,WD_CURSOR_ADDR_LOW   ; Low 12 bit <b11-b0>
        out     dx,ax
        pop     eax                     ; restore address
        shr     eax,12
        and     ax,0000000111111111b
        or      ax,WD_CURSOR_ADDR_HI    ; High 9 bit <bit20-b12>
        out     dx,ax

        mov     dx,23c0h
        mov     al,0
        out     dx,al                   ; select system control register

        ret

wd_make_sprite_rtn endp


public    spdway_make_sprite_rtn
spdway_make_sprite_rtn proc near
; input :  esi ---> CurData.BaseAndMasks
;          edi ---> sprite data
;          ecx is MASK_LENGTH

        push    ecx                          ; save byte count
smsr_block_loop:
        mov     al,[esi]                     ; get And mask
        mov     bl,[esi+ecx]                 ; get Xor mask

        mov     ah,8
        xor     edx,edx
smsr_word_loop:
        shl     al,1
        jnc     @F
        or      edx,1
@@:     shl     edx,1
        shl     bl,1
        jnc     @F
        or      edx,1
@@:     shl     edx,1
        dec     ah
        jnz     smsr_word_loop
        shr     edx,1

        mov     [edi],dh
        mov     [edi+1],dl
        inc     esi
        inc     edi
        inc     edi
        mov     edx,edi
        mov     al,dl
        and     al,0Fh
        cmp     al,08h
        jl      @F
        and     dl,0f0h
        mov     eax,00000010h
        add     edx,eax
        mov     edi,edx

@@:     pop     edx
        dec     edx
        push    edx
        jnz     smsr_block_loop

        pop     ecx

; fill transparent pattern

        mov     cx,100h
        mov     ax,0aaaah
        rep     stosw

; sprite register setting

        mov     dx,03c4h
        mov     al,80h                       ; sprite color index reg-0
        out     dx,al
        mov     dx,03c5h
        mov     al,0                         ; color-0
        out     dx,al

        mov     dx,03c4h
        mov     al,81h                       ; sprite color index reg-1
        out     dx,al
        mov     dx,03c5h
        mov     al,0ffh                      ; color-1
        out     dx,al

        mov     dx,03c4h
        mov     al,82h                       ; double width sprite
        out     dx,al
        mov     dx,03c5h
        mov     al,0                         ; 0: 32 pel / 1: 64 pel
        out     dx,al

        mov     dx,03c4h
        mov     al,83h                       ; Sprite Data Origin Reg
        out     dx,al
        mov     dx,03c5h

        mov     eax,CurData.sprite_data_origin
        shr     eax,12                       ; 4K boundary

; pochi ??? Airway     ??? <begin>           ;
        mov     ah,al                        ; 
        test    ah,00010000b                 ; Swap the Bit2 and Bit4
        jnz     sms_set_bit2                 ; of the Sprite Data Origin Address
        and     al,11111011b                 ; 
        jmp     sms_test_bit2                ; Is this a     of Airway ??
sms_set_bit2:                                ; 
        or      al,00000100b                 ; 
sms_test_bit2:                               ; 
        test    ah,00000100b                 ; 
        jnz     sms_set_bit4                 ; 
        and     al,11101111b                 ; 
        jmp     sms_done_bit4                ; 
sms_set_bit4:                                ; 
        or      al,00010000b                 ; 
sms_done_bit4:                               ; 
; pochi ??? Airway     ??? <end>             ;

        out     dx,al

;       or      swFlags,SW_SPRITE            ; force h/w cursor ON
;
; move it to spdway_specific_init_rtn at egainit.asm
; 92/02/03  H.Muta
;
        ret

spdway_make_sprite_rtn endp

public    bga_make_sprite_rtn
bga_make_sprite_rtn proc near

HWGC_FGCL equ 04Ah
HWGC_BGCL equ 04Bh
HWGC_STA_H equ 04Ch
HWGC_STA_L equ 04Dh

; input :  esi ---> CurData.BaseAndMasks
;          edi ---> sprite data
;          ecx is MASK_LENGTH

 cmp cx,(32/8)*32
 jne bga_not_32x32_case

        push    esi                          ; save source origin
        push    edi                          ; save destination origin

 cld
 mov eax,0ffffh
 mov ecx,32
@@:
 movsw
 add edi,2
 movsw
 add edi,2
 stosd
 stosd
        loop    @B

 mov ecx,32*4
 rep stosd

        pop     edi                          ; restore destination origin
        pop     esi                          ; restore source origin

        add     esi,(32/8)*32                ; ESI --> CurData.BaseXorMasks
 add edi,2
 mov ecx,32
@@:
 movsw
 add edi,2
 movsw
 add edi,10
        loop    @B
 jmp bga_setup_registers

bga_not_32x32_case:
        push    esi                          ; save source origin
        push    edi                          ; save destination origin
        push    ecx                          ; save byte count

 cld
 shr ecx,1
@@:
 movsw
 add edi,2
        loop    @B

        pop     ecx                          ; restore count
        pop     edi                          ; restore destination origin
        pop     esi                          ; restore source origin

        add     esi,ecx                      ; ESI --> CurData.BaseXorMasks
 add edi,2
 shr ecx,1
@@:
 movsw
 add edi,2
        loop    @B

bga_setup_registers:
        mov     dx,3d4h

 mov al,39h
 out dx,al
 inc dx
 in al,dx
 or al,0a0h
 out dx,al   ; UnLock 40
 dec dx

 mov ax,(0FFh shl 8) or HWGC_FGCL
 out dx,ax   ; set foreground color
 mov ax,(0 shr 8) or HWGC_BGCL
 out dx,ax   ; set background color

        mov     eax,CurData.sprite_data_origin
        shr     eax,10-8                ; AH holds Cursor Pattern Y (low 8bit)
 mov al,HWGC_STA_L
        out     dx,ax
        shr     eax,8
 and ah,0fh                  ; AH holds Cursor Pattern Y (high 4bit)
 mov al,HWGC_STA_H
        out     dx,ax

        ret

bga_make_sprite_rtn endp

public    cirrus_make_sprite_rtn
cirrus_make_sprite_rtn proc near

EXT_REG  equ 03c4h
GC_ATTR  equ 12h
GC_ENABLE equ 1
GC_DAC_EXT equ 2
SIZE_32x32 equ 0

; input :  esi ---> CurData.BaseAndMasks
;          edi ---> sprite data
;          ecx is MASK_LENGTH

 cmp cx,32*4
 je @F
        and     swFlags,not SW_SPRITE
 jmp cms_exit
@@:
        cli
 mov dx,EXT_REG
 mov ax,GC_ATTR or ((GC_DAC_EXT or SIZE_32x32) shl 8)
 out dx,ax

 add esi,32*4
 mov ecx,32    ; Xor mask -> plane 0
 rep movsd

 sub esi,32*4*2
 mov ecx,32    ; And mask -> plane 1
@@:
 lodsd
 not eax
 stosd
 loop @B

 mov ecx,32*2   ; tmp pattern
 xor eax,eax
 rep stosd

        mov     dx,EGA_BASE + DAC_INDEX
 xor al,al    ; cursor BG color
        out     dx,al
        mov     dx,EGA_BASE + DAC_DATA
 xor al,al
        out     dx,al
        out     dx,al
        out     dx,al

        mov     dx,EGA_BASE + DAC_INDEX
 mov al,0fh    ; cursor FG color
        out     dx,al
        mov     dx,EGA_BASE + DAC_DATA
 mov al,255
        out     dx,al
        out     dx,al
        out     dx,al

 mov ax,GC_ATTR or (SIZE_32x32 shl 8)
 out dx,ax
        sti

cms_exit:
        ret
cirrus_make_sprite_rtn endp
