mirror of https://github.com/lianthony/NT4.0
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
3376 lines
102 KiB
3376 lines
102 KiB
PAGE 60, 132
|
|
TITLE Setting 1/4 bits per pel bitmap or 3 planes-1BPP bitmap
|
|
|
|
|
|
COMMENT `
|
|
|
|
Copyright (c) 1990-1991 Microsoft Corporation
|
|
|
|
|
|
Module Name:
|
|
|
|
htwbmp.asm
|
|
|
|
Abstract:
|
|
|
|
This module is used to provide set of functions to set the bits into the
|
|
final destination bitmap, the input to these function are data structures
|
|
(PRIMMONO_COUNT, PRIMCOLOR_COUNT and other pre-calculated data values).
|
|
|
|
This function is the equivelant codes in the htsetbmp.c
|
|
|
|
Author:
|
|
|
|
03-Apr-1991 Wed 10:28:50 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
[Environment:]
|
|
|
|
Printer Driver.
|
|
|
|
|
|
[Notes:]
|
|
|
|
|
|
Revision History:
|
|
06-Nov-1992 Fri 16:04:18 updated -by- Daniel Chou (danielc)
|
|
Fixed bug in VarCountOutputToVGA256 which clear 'ah' (xor _AX, _AX)
|
|
while we still need to use it.
|
|
|
|
|
|
28-Mar-1992 Sat 21:09:42 updated -by- Daniel Chou (danielc)
|
|
Rewrite all output functions, add in VGA16 support.
|
|
|
|
|
|
`
|
|
|
|
|
|
.XLIST
|
|
INCLUDE i386\i80x86.inc
|
|
.LIST
|
|
|
|
|
|
IF HT_ASM_80x86
|
|
|
|
|
|
;------------------------------------------------------------------------------
|
|
.XLIST
|
|
INCLUDE i386\htp.inc
|
|
.LIST
|
|
;------------------------------------------------------------------------------
|
|
|
|
DBG_FILENAME i386\htwbmp
|
|
|
|
|
|
.CODE
|
|
|
|
VGA16ColorIndex db 000h, 077h, 077h, 088h, 088h, 0ffh ; MONO
|
|
|
|
db 000h, 000h, 000h, 011h, 033h, 077h ; RY 0
|
|
db 000h, 000h, 011h, 033h, 077h, 088h ; RY 6
|
|
db 000h, 000h, 011h, 033h, 088h, 0ffh ; RY 18
|
|
|
|
db 000h, 011h, 033h, 099h, 0bbh, 077h ; RY 24
|
|
db 011h, 033h, 099h, 0bbh, 077h, 088h ; RY 30
|
|
db 011h, 033h, 099h, 0bbh, 088h, 0ffh ; RY 36
|
|
|
|
db 000h, 000h, 000h, 011h, 055h, 077h ; RM 42
|
|
db 000h, 000h, 011h, 055h, 077h, 088h ; RM 48
|
|
db 000h, 000h, 011h, 055h, 088h, 0ffh ; RM 54
|
|
|
|
db 000h, 011h, 055h, 099h, 0ddh, 077h ; RM 60
|
|
db 011h, 055h, 099h, 0ddh, 077h, 088h ; RM 66
|
|
db 011h, 055h, 099h, 0ddh, 088h, 0ffh ; RM 72
|
|
|
|
db 000h, 000h, 000h, 022h, 033h, 077h ; GY 78
|
|
db 000h, 000h, 022h, 033h, 077h, 088h ; GY 84
|
|
db 000h, 000h, 022h, 033h, 088h, 0ffh ; GY 90
|
|
|
|
db 000h, 022h, 033h, 0aah, 0bbh, 077h ; GY 96
|
|
db 022h, 033h, 0aah, 0bbh, 077h, 088h ; GY 102
|
|
db 022h, 033h, 0aah, 0bbh, 088h, 0ffh ; GY 108
|
|
|
|
db 000h, 000h, 000h, 022h, 066h, 077h ; GC 114
|
|
db 000h, 000h, 022h, 066h, 077h, 088h ; GC 120
|
|
db 000h, 000h, 022h, 066h, 088h, 0ffh ; GC 126
|
|
|
|
db 000h, 022h, 066h, 0aah, 0eeh, 077h ; GC 132
|
|
db 022h, 066h, 0aah, 0eeh, 077h, 088h ; GC 138
|
|
db 022h, 066h, 0aah, 0eeh, 088h, 0ffh ; GC 144
|
|
|
|
db 000h, 000h, 000h, 044h, 055h, 077h ; BM 150
|
|
db 000h, 000h, 044h, 055h, 077h, 088h ; BM 156
|
|
db 000h, 000h, 044h, 055h, 088h, 0ffh ; BM
|
|
|
|
db 000h, 044h, 055h, 0cch, 0ddh, 077h ; BM 162
|
|
db 044h, 055h, 0cch, 0ddh, 077h, 088h ; BM 168
|
|
db 044h, 055h, 0cch, 0ddh, 088h, 0ffh ; BM 174
|
|
|
|
db 000h, 000h, 000h, 044h, 066h, 077h ; BC 180
|
|
db 000h, 000h, 044h, 066h, 077h, 088h ; BC 186
|
|
db 000h, 000h, 044h, 066h, 088h, 0ffh ; BC 192
|
|
|
|
db 000h, 044h, 066h, 0cch, 0eeh, 077h ; BC 198
|
|
db 044h, 066h, 0cch, 0eeh, 077h, 088h ; BC 204
|
|
db 044h, 066h, 0cch, 0eeh, 088h, 0ffh ; BC 210
|
|
|
|
|
|
|
|
;******************************************************************************
|
|
; Following EQUATES and MACROS only used in this file
|
|
;******************************************************************************
|
|
|
|
|
|
VGA256_SSSP_XLAT_TABLE equ 0
|
|
VGA256_XLATE_TABLE_SIZE equ 256
|
|
|
|
|
|
; 87654321
|
|
;------------------------------------------
|
|
HTPAT_STK_MASK equ (01111111b)
|
|
HTPAT_NOT_STK_MASK equ (NOT HTPAT_STK_MASK)
|
|
HTPAT_STK_MASK_SIZE equ (HTPAT_STK_MASK + 1)
|
|
|
|
HTPAT_BP_SIZE equ (REG_MAX_SIZE * 1)
|
|
HTPAT_BP_OLDSTK equ (REG_MAX_SIZE * 2)
|
|
HTPAT_BP_DATA1 equ (REG_MAX_SIZE * 3)
|
|
|
|
HTPAT_STK_SIZE_EXTRA equ (REG_MAX_SIZE * 3)
|
|
|
|
HTPAT_SP_SIZE equ (HTPAT_STK_SIZE_EXTRA - HTPAT_BP_SIZE)
|
|
HTPAT_SP_OLDSTK equ (HTPAT_STK_SIZE_EXTRA - HTPAT_BP_OLDSTK)
|
|
HTPAT_SP_DATA1 equ (HTPAT_STK_SIZE_EXTRA - HTPAT_BP_DATA1)
|
|
|
|
|
|
.XLIST
|
|
|
|
|
|
@ENTER_PAT_TO_STK MACRO Format
|
|
LOCAL StkSizeOk, DoneSetUp
|
|
|
|
__@@VALID_PARAM? <PAT_TO_STK>, 1, Format, <1BPP, 3PLANES, 4BPP, VGA16, VGA256, 16BPP>
|
|
|
|
|
|
@ENTER _DS _SI _DI _BP ;; Save environment/registers
|
|
|
|
__@@EMIT <xor > _CX, _CX
|
|
__@@EMIT <mov > cx, <OutFuncInfo.OFI_PatWidthBytes>
|
|
|
|
__@@EMIT <mov > _AX, _SP ;; get stack location
|
|
__@@EMIT <mov > _DX, _AX ;; save it
|
|
__@@EMIT <and > _AX, <HTPAT_STK_MASK> ;; how many bytes avai
|
|
__@@EMIT <inc > _AX ;; this many bytes
|
|
__@@EMIT <cmp > _AX, _CX ;; enough for pattern?
|
|
__@@EMIT <jae > <SHORT StkSizeOk>
|
|
__@@EMIT <add > _AX, <HTPAT_STK_MASK_SIZE> ;; add this more
|
|
StkSizeOk:
|
|
__@@EMIT <dec > _AX ;; back one
|
|
__@@EMIT <sub > _SP, _AX ;; reduced it
|
|
__@@EMIT <mov > _DI, _SP ;; _DI point to the pPattern
|
|
__@@EMIT <sub > _SP, <HTPAT_STK_SIZE_EXTRA> ;; reduced again
|
|
__@@EMIT <mov > <[_DI-HTPAT_BP_SIZE]>, _CX ;; save the pattern size
|
|
__@@EMIT <mov > <[_DI-HTPAT_BP_OLDSTK]>, _DX ;; save old stk pointer
|
|
|
|
IFIDNI <Format>,<3PLANES>
|
|
IFE ExtRegSet
|
|
__@@EMIT <mov > _AX, <WPTR OutFuncInfo.OFI_BytesPerPlane>
|
|
ELSE
|
|
__@@EMIT <mov > _AX, OutFuncInfo.OFI_BytesPerPlane
|
|
ENDIF
|
|
|
|
__@@EMIT <mov > <[_DI-HTPAT_BP_DATA1]>, _AX
|
|
ENDIF
|
|
|
|
;
|
|
; now staring coping the pattern to stack
|
|
;
|
|
|
|
MOV_SEG es, ss, ax
|
|
LDS_SI pPattern
|
|
MOVS_CB _CX, dl ;; copy the pattern
|
|
|
|
__@@EMIT <mov > _BX, _DI ;; _BX point to the pattern start
|
|
|
|
IFIDNI <Format>, <VGA256>
|
|
IFE ExtRegSet
|
|
__@@EMIT <mov > _AX, <WPTR OutFuncInfo.OFI_BytesPerPlane + 2>
|
|
or _AX, _AX
|
|
jz SHORT DoneXlateTable
|
|
mov _CX, VGA256_XLATE_TABLE_SIZE
|
|
sub _SP, _CX
|
|
mov _DI, _SP
|
|
LDS_SI OutFuncInfo.OFI_BytesPerPlane
|
|
MOVS_CB _CX, dl
|
|
ELSE
|
|
__@@EMIT <mov > _AX, OutFuncInfo.OFI_BytesPerPlane
|
|
ENDIF
|
|
ENDIF
|
|
|
|
DoneXlateTable:
|
|
|
|
IFIDNI <Format>, <1BPP>
|
|
LDS_SI pPrimMonoCount
|
|
ELSE
|
|
LDS_SI pPrimColorCount ;; _SI=pPrimColorCount
|
|
ENDIF
|
|
|
|
LES_DI pDest
|
|
|
|
__@@EMIT <mov > _BP, _BX ;; _BP=Pattern Start
|
|
|
|
|
|
ENDM
|
|
|
|
|
|
@EXIT_PAT_STK_RESTORE MACRO
|
|
|
|
__@@EMIT <mov > _BP, _SP
|
|
__@@EMIT <mov > _SP, <[_BP + HTPAT_SP_OLDSTK]>
|
|
@EXIT
|
|
|
|
ENDM
|
|
|
|
|
|
WRAP_BP_PAT?? MACRO EndWrapLoc
|
|
Local DoneWrap
|
|
|
|
IFB <EndWrapLoc>
|
|
__@@EMIT <test > bp, <HTPAT_STK_MASK>
|
|
__@@EMIT <jnz > <SHORT DoneWrap>
|
|
__@@EMIT <add > _BP, <[_BP-HTPAT_BP_SIZE]> ;; add in pattern size
|
|
ELSE
|
|
__@@EMIT <test > bp, <HTPAT_STK_MASK>
|
|
__@@EMIT <jnz > <SHORT EndWrapLoc>
|
|
__@@EMIT <add > _BP, <[_BP-HTPAT_BP_SIZE]> ;; add in pattern size
|
|
__@@EMIT <jmp > <SHORT EndWrapLoc>
|
|
ENDIF
|
|
|
|
DoneWrap:
|
|
|
|
ENDM
|
|
|
|
|
|
SAVE_1BPP_DEST MACRO
|
|
|
|
;
|
|
; Save Prim1 (DL) to Plane
|
|
;
|
|
|
|
__@@EMIT <not > dl ; invert bit
|
|
__@@EMIT <mov > <BPTR_ES[_DI]>, dl ; Save Dest
|
|
|
|
ENDM
|
|
|
|
|
|
SAVE_1BPP_MASKDEST MACRO
|
|
|
|
;
|
|
; Save Prim1 (DL) with Mask (DH, 1=Preserved, 0=Overwrite) to Dest
|
|
;
|
|
|
|
__@@EMIT <and > <BPTR_ES[_DI]>, dh ; Mask overwrite bits
|
|
__@@EMIT <not > dx ; invert bit/mask
|
|
__@@EMIT <and > dl, dh
|
|
__@@EMIT <or > <BPTR_ES[_DI]>, dl ; Save Plane1=Prim3
|
|
|
|
ENDM
|
|
|
|
|
|
SAVE_VGA16_DEST MACRO
|
|
|
|
;
|
|
; Save Prim1/2/3 (DL) to Plane
|
|
;
|
|
|
|
__@@EMIT <mov > dh, dl
|
|
__@@EMIT <add > dh, 11h
|
|
__@@EMIT <and > dh, 88h
|
|
__@@EMIT <or > dl, dh
|
|
__@@EMIT <not > dl
|
|
__@@EMIT <mov > <BPTR_ES[_DI]>, dl ; Save Dest
|
|
|
|
ENDM
|
|
|
|
|
|
SAVE_VGA16_DEST_HIGH MACRO
|
|
|
|
;
|
|
; Save Prim1 (DL) high nibble only, preserved low nibble
|
|
;
|
|
|
|
|
|
__@@EMIT <and > <BPTR_ES[_DI]>, 0fh ; Mask overwrite bits
|
|
__@@EMIT <mov > dh, dl
|
|
__@@EMIT <inc > dh
|
|
__@@EMIT <and > dh, 08h
|
|
__@@EMIT <or > dl, dh
|
|
__@@EMIT <not > dl ; invert bit/mask
|
|
__@@EMIT <shl > dl, 4
|
|
__@@EMIT <or > <BPTR_ES[_DI]>, dl ; Save Plane1=Prim3
|
|
|
|
ENDM
|
|
|
|
|
|
SAVE_VGA16_DEST_LOW MACRO
|
|
|
|
;
|
|
; Save Prim1 (DL) low nibble only, preserved high nibble
|
|
;
|
|
|
|
|
|
__@@EMIT <and > <BPTR_ES[_DI]>, 0f0h ; Mask overwrite bits
|
|
__@@EMIT <mov > dh, dl
|
|
__@@EMIT <inc > dh
|
|
__@@EMIT <and > dh, 08h
|
|
__@@EMIT <or > dl, dh
|
|
__@@EMIT <xor > dl, 0fh ; invert bit/mask
|
|
__@@EMIT <or > <BPTR_ES[_DI]>, dl ; Save Plane1=Prim3
|
|
|
|
ENDM
|
|
|
|
|
|
SAVE_4BPP_DEST MACRO
|
|
|
|
;
|
|
; Save Prim1/2/3 (DL) to Plane
|
|
;
|
|
|
|
__@@EMIT <xor > dl, 77h
|
|
__@@EMIT <mov > <BPTR_ES[_DI]>, dl ; Save Dest
|
|
|
|
ENDM
|
|
|
|
|
|
SAVE_4BPP_DEST_HIGH MACRO
|
|
LOCAL DoneVGA
|
|
|
|
;
|
|
; Save Prim1 (DL) high nibble only, preserved low nibble
|
|
;
|
|
|
|
|
|
__@@EMIT <and > <BPTR_ES[_DI]>, 0fh ; Mask overwrite bits
|
|
__@@EMIT <xor > dl, 07h ; Invert bits
|
|
__@@EMIT <shl > dl, 4 ; move to high nibble
|
|
__@@EMIT <or > <BPTR_ES[_DI]>, dl ; Save Plane1=Prim3
|
|
|
|
ENDM
|
|
|
|
|
|
SAVE_4BPP_DEST_LOW MACRO
|
|
LOCAL DoneVGA
|
|
;
|
|
; Save Prim1 (DL) low nibble only, preserved high nibble
|
|
;
|
|
|
|
|
|
__@@EMIT <and > <BPTR_ES[_DI]>, 0f0h ; Mask overwrite bits
|
|
__@@EMIT <xor > dl, 07h ; invert bit/mask
|
|
__@@EMIT <or > <BPTR_ES[_DI]>, dl ; Save Plane1=Prim3
|
|
|
|
ENDM
|
|
|
|
|
|
|
|
SAVE_3PLANES_DEST MACRO UseAX
|
|
|
|
;
|
|
; Save Prim1/2/3 (CL:CH:DL) to Plane3/2/1
|
|
;
|
|
|
|
IFB <UseAX>
|
|
__@@EMIT <push > _BP ; save Prim1/2
|
|
ELSE
|
|
__@@EMIT <mov > _AX, _BP ; save _BP
|
|
ENDIF
|
|
|
|
__@@EMIT <and > _BP, <HTPAT_NOT_STK_MASK> ; to HTPAT_BP_xxx
|
|
__@@EMIT <mov > _BP, <[_BP - HTPAT_BP_DATA1]> ; size of plane
|
|
|
|
__@@EMIT <not > cx ; invert the bits
|
|
__@@EMIT <not > dl ; invert bit
|
|
|
|
__@@EMIT <mov > <BPTR_ES[ _DI]>, dl ; Save Plane1=Prim3
|
|
__@@EMIT <mov > <BPTR_ES[_BP + _DI]>, ch ; save Plane2=Prim2
|
|
|
|
IFE ExtRegSet
|
|
__@@EMIT <add > _BP, _BP ; goto plane3
|
|
__@@EMIT <mov > <BPTR_ES[_BP+_DI]>, cl ; save Plane3=Prim1
|
|
ELSE
|
|
__@@EMIT <mov > <BPTR_ES[(_BP*2)+_DI]>, cl ; save Plane3=Prim1
|
|
ENDIF
|
|
|
|
IFB <UseAX>
|
|
__@@EMIT <pop > _BP ; restore _BP
|
|
ELSE
|
|
__@@EMIT <mov > _BP, _AX ; restore _BP
|
|
ENDIF
|
|
|
|
ENDM
|
|
|
|
|
|
|
|
SAVE_3PLANES_MASKDEST MACRO UseAX
|
|
;
|
|
; Save Prim1/2/3 (CL:CH:DL) with Mask (DH, 1=Preserved, 0=Overwrite) to
|
|
; Plane3/2/1
|
|
;
|
|
|
|
IFB <UseAX>
|
|
__@@EMIT <push > _BP ; save Prim1/2
|
|
ELSE
|
|
__@@EMIT <mov > _AX, _BP ; save _BP
|
|
ENDIF
|
|
|
|
__@@EMIT <and > _BP, <HTPAT_NOT_STK_MASK> ; to HTPAT_BP_xxx
|
|
__@@EMIT <mov > _BP, <[_BP - HTPAT_BP_DATA1]> ; size of plane
|
|
|
|
__@@EMIT <not > cx ; invert the bits
|
|
__@@EMIT <not > dx ; invert bit/mask
|
|
__@@EMIT <and > cl, dh ; mask preserved bits
|
|
__@@EMIT <and > ch, dh
|
|
__@@EMIT <and > dl, dh
|
|
__@@EMIT <not > dh ; for dest mask
|
|
|
|
__@@EMIT <and > <BPTR_ES[ _DI]>, dh ; Mask overwrite bits
|
|
__@@EMIT <or > <BPTR_ES[ _DI]>, dl ; Save Plane1=Prim3
|
|
|
|
__@@EMIT <and > <BPTR_ES[_BP + _DI]>, dh ; Mask overwrite bits
|
|
__@@EMIT <or > <BPTR_ES[_BP + _DI]>, ch ; save Plane2=Prim2
|
|
|
|
IFE ExtRegSet
|
|
__@@EMIT <add > _BP, _BP ; goto plane3
|
|
__@@EMIT <and > <BPTR_ES[_BP + _DI]>, dh ; Mask overwrite bits
|
|
__@@EMIT <or > <BPTR_ES[_BP + _DI]>, cl ; save Plane3=Prim1
|
|
ELSE
|
|
__@@EMIT <and > <BPTR_ES[(_BP*2) + _DI]>, dh ; Mask overwrite bits
|
|
__@@EMIT <or > <BPTR_ES[(_BP*2) + _DI]>, cl ; save Plane3=Prim1
|
|
ENDIF
|
|
|
|
IFB <UseAX>
|
|
__@@EMIT <pop > _BP ; restore _BP
|
|
ELSE
|
|
__@@EMIT <mov > _BP, _AX ; restore _BP
|
|
ENDIF
|
|
ENDM
|
|
|
|
|
|
.LIST
|
|
|
|
|
|
|
|
SUBTTL SingleCountOutputTo1BPP
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_1BPP destination surface from
|
|
PRIMMONO_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimMonoCount - Pointer to the PRIMMONO_COUNT data structure array.
|
|
|
|
pDest - Pointer to first modified destination byte
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
`
|
|
|
|
|
|
@BEG_PROC SingleCountOutputTo1BPP <pPrimMonoCount:DWORD, \
|
|
pDest:DWORD, \
|
|
pPattern:DWORD, \
|
|
OutFuncInfo:QWORD>
|
|
|
|
|
|
;
|
|
; Register Usage:
|
|
;
|
|
; _SI = pPrimMonoCount
|
|
; _DI = pDestination
|
|
; _BP = Self host pPattern
|
|
; al:ah = Prim1/2
|
|
; dl = DestByte
|
|
; dh = DestMask
|
|
|
|
|
|
@ENTER_PAT_TO_STK <1BPP> ; _BP=Pat location, fall throug to load
|
|
|
|
;=============================================================================
|
|
; the DH has two uses, it contains the mask bits (1 bit=Mask), and it also
|
|
; contains an extra bit to do a byte boundary test, every time we shift the
|
|
; mask left by one, the boundary bit get shift to left, when first time a
|
|
; carry is produced then we know we finished one byte. at here we set up the
|
|
; dh=FirstMask + Aligned boundary bit
|
|
;=============================================================================
|
|
|
|
mov _DX, 1ffh ; dh=Mask (1=Mask, 0=Not Mask)
|
|
MOVZX_W _CX, <WPTR [_SI]> ; load extended
|
|
sub _BP, _CX ; back the _BP
|
|
shl _DX, cl ; set first mask
|
|
xor dl, dl ; clear Prim1
|
|
jmp short LoadByte
|
|
|
|
|
|
;============================================================================
|
|
; EOF encountered, if Mask (DH) is equal to 0x01 then we just starting the new
|
|
; byte, which we just have exactly end at last byte boundary (no last byte
|
|
; mask), otherwise, shift all destination byte to left by count, then mask it
|
|
;============================================================================
|
|
; EOF encountered, if count is 0, then there is no last byte mask, so just
|
|
; exit, otherwise, shift all destination byte to left by count, then mask it
|
|
;============================================================================
|
|
|
|
EOFDest:
|
|
cmp dh, 1
|
|
jz short AllDone ; finished
|
|
|
|
EOFDestMask:
|
|
mov cx, WPTR [_SI] ; get LastByteSkips
|
|
|
|
xor ah, ah ; ax=0xffff now, clear ah
|
|
shl ax, cl ; ah=LastByteMask
|
|
shl dx, cl ; shift Mask+Prim1
|
|
or dh, ah ; add in dh=mask
|
|
cmp dh, 0ffh ; if dh=0xff then all masked
|
|
jz short AllDone
|
|
|
|
SAVE_1BPP_MASKDEST ; save last byte
|
|
|
|
AllDone:
|
|
@EXIT_PAT_STK_RESTORE
|
|
|
|
|
|
;==========================================================================
|
|
; An invalid density is encountered, (0xff to indicate the stretch must not
|
|
; update to the destination), if this is the last stretch then do 'EOFDest'
|
|
; otherwise set mask bits until the byte boundary is encountered then fall
|
|
; through to load next byte, if a byte boundary is before count are exausted
|
|
; then save that mask byte and it will automatically skip rest of the pels.
|
|
;==========================================================================
|
|
|
|
InvDensity:
|
|
cmp al, ah
|
|
jz short EOFDest ; EOF
|
|
add dx, dx
|
|
inc dh ; add in mask, 'C' not changed
|
|
jc short DoneOneByte ; finished? if not fall through
|
|
|
|
LoadByte:
|
|
add _SI, SIZE_PMC ; sizeof(PRIMMONO_COUNT)
|
|
mov ax, WPTR [_SI+2] ; al:ah=Prim 1/2
|
|
dec _BP ; ready to access pattern
|
|
cmp al, PRIM_INVALID_DENSITY
|
|
jz short InvDensity
|
|
cmp al, BPTR[_BP] ; check with pattern
|
|
adc dx, dx
|
|
jnc short LoadByte
|
|
|
|
DoneOneByte:
|
|
or dh, dh ; any mask?
|
|
jnz short HasDestMask
|
|
|
|
SAVE_1BPP_DEST ; save it, no jmp
|
|
|
|
ReadyNextByte:
|
|
inc _DI
|
|
mov _DX, 0100h ; dh=0x01=Boundary test bit
|
|
|
|
WRAP_BP_PAT?? <LoadByte>
|
|
|
|
HasDestMask:
|
|
cmp dh, 0ffh
|
|
jz short ReadyNextByte ;
|
|
|
|
SAVE_1BPP_MASKDEST ; save it with DH=mask
|
|
|
|
jmp short ReadyNextByte
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
|
|
SUBTTL VarCountOutputTo1BPP
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_1BPP destination surface from
|
|
PRIMMONO_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimMonoCount - Pointer to the PRIMMONO_COUNT data structure array.
|
|
|
|
pDest - Pointer to first modified destination byte
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
`
|
|
|
|
|
|
@BEG_PROC VarCountOutputTo1BPP <pPrimMonoCount:DWORD, \
|
|
pDest:DWORD, \
|
|
pPattern:DWORD, \
|
|
OutFuncInfo:QWORD>
|
|
|
|
|
|
;
|
|
; Register Usage:
|
|
;
|
|
; _SI = pPrimMonoCount
|
|
; _DI = pDestination
|
|
; _BP = Self host pPattern
|
|
; cx = PrimMonoCount.Count
|
|
; al:ah = Prim1/2
|
|
; dl = DestByte
|
|
; dh = DestMask
|
|
;
|
|
|
|
|
|
@ENTER_PAT_TO_STK <1BPP> ; _BP=Pat location
|
|
|
|
;=============================================================================
|
|
; the DH has two uses, it contains the mask bits (1 bit=Mask), and it also
|
|
; contains an extra bit to do a byte boundary test, every time we shift the
|
|
; mask left by one, the boundary bit get shift to left, when first time a
|
|
; carry is produced then we know we finished one byte. at here we set up the
|
|
; dh=FirstMask + Aligned boundary bit
|
|
;=============================================================================
|
|
|
|
mov _DX, 1ffh ; dh=Mask (1=Mask, 0=Not Mask)
|
|
MOVZX_W _CX, <WPTR [_SI]> ; load extended
|
|
sub _BP, _CX ; back the _BP
|
|
shl _DX, cl ; set first mask
|
|
xor dl, dl ; clear Prim1
|
|
jmp short LoadByte
|
|
|
|
;============================================================================
|
|
; EOF encountered, if Mask (DH) is equal to 0x01 then we just starting the new
|
|
; byte, which we just have exactly end at last byte boundary (no last byte
|
|
; mask), otherwise, shift all destination byte to left by count, then mask it
|
|
;============================================================================
|
|
; EOF encountered, if count is 0, then there is no last byte mask, so just
|
|
; exit, otherwise, shift all destination byte to left by count, then mask it
|
|
;============================================================================
|
|
|
|
EOFDest:
|
|
jcxz short AllDone ; if cx=0 then done
|
|
|
|
EOFDestMask:
|
|
xor ah, ah ; ax=0xffff now, clear ah
|
|
shl ax, cl ; ah=LastByteMask
|
|
shl dx, cl ; shift Mask+Prim1
|
|
or dh, ah ; add in dh=mask
|
|
cmp dh, 0ffh ; if dh=0xff then all masked
|
|
jz short AllDone
|
|
|
|
SAVE_1BPP_MASKDEST ; save it with DH=mask
|
|
|
|
AllDone:
|
|
@EXIT_PAT_STK_RESTORE ; restore original SP
|
|
|
|
;==========================================================================
|
|
; An invalid density is encountered, (0xff to indicate the stretch must not
|
|
; update to the destination), if this is the last stretch then do 'EOFDest'
|
|
; otherwise set mask bits until the byte boundary is encountered then fall
|
|
; through to load next byte, if a byte boundary is before count are exausted
|
|
; then save that mask byte and it will automatically skip rest of the pels.
|
|
;==========================================================================
|
|
|
|
InvDensity:
|
|
cmp al, ah
|
|
jz short EOFDest ; done
|
|
InvDensityLoop:
|
|
dec _BP
|
|
add dx, dx
|
|
inc dh ; add in mask, 'C' not changed
|
|
jc short DoneOneByte
|
|
dec cx
|
|
jnz short InvDensityLoop ; !!! FALL THROUGH
|
|
|
|
LoadByte:
|
|
add _SI, SIZE_PMC ; sizeof(PRIMMONO_COUNT)
|
|
mov cx, WPTR [_SI] ; cx=Count
|
|
mov ax, WPTR [_SI+2] ; al:ah=Prim1/2
|
|
cmp al, PRIM_INVALID_DENSITY ; a skip?, if yes go do it
|
|
jz short InvDensity
|
|
inc cx ; make it no jump
|
|
MakeByte:
|
|
dec cx
|
|
jz short LoadByte
|
|
dec _BP ; ready to access pattern
|
|
mov ah, BPTR[_BP] ; get pattern
|
|
cmp al, ah
|
|
adc dx, dx
|
|
jnc short MakeByte ; if carry then byte boundary
|
|
|
|
DoneOneByte:
|
|
or dh, dh ; any mask?
|
|
jnz short HasDestMask ; yes
|
|
|
|
SAVE_1BPP_DEST ; save it
|
|
|
|
ReadyNextByte:
|
|
inc _DI ; ++pDest
|
|
mov _DX, 0100h ; dh=0x01, dl=0x00
|
|
|
|
WRAP_BP_PAT?? <MakeByte>
|
|
|
|
;=============================================================================
|
|
; Mask the destination by DH mask, (1 bit=Mask), if whole destiantion byte is
|
|
; masked then just increment the pDest
|
|
;=============================================================================
|
|
|
|
HasDestMask:
|
|
cmp dh, 0ffh
|
|
jz short DoneDestMask
|
|
|
|
SAVE_1BPP_MASKDEST ; save it with DH=mask
|
|
|
|
DoneDestMask:
|
|
cmp al, PRIM_INVALID_DENSITY ; is last one a skip stretch?
|
|
jnz short ReadyNextByte
|
|
cmp cx, 1 ; more than 0 count?
|
|
jbe short ReadyNextByte ; no, continue
|
|
|
|
;
|
|
;*** FALL THROUGH
|
|
;
|
|
|
|
;============================================================================
|
|
; skip the 'cx-1' count of pels on the destination (SI is post decrement so
|
|
; we must only skip 'cxi-1' count), it will skip the 'pDest', set up next
|
|
; pDest mask, also it will aligned the destination pattern pointer (_BP)
|
|
;===========================================================================
|
|
|
|
SkipDestPels:
|
|
inc _DI ; update to current pDest
|
|
|
|
dec cx ; back one
|
|
WZXE cx ; zero extended
|
|
mov _AX, _CX ; _AX=_CX=Count
|
|
and cl, 7
|
|
;===============================================================
|
|
mov _DX, 1ffh ; ready to shift
|
|
shl _DX, cl ; Boundary Bit + MASK
|
|
xor dl, dl ; clear Prim1
|
|
;================================================================
|
|
mov _CX, _AX ; get count again
|
|
shr _CX, 3
|
|
add _DI, _CX ; pDest += (Count >> 3)
|
|
mov _CX, _BP ; align pattern now
|
|
and _CX, HTPAT_STK_MASK ; how many pat avai.?
|
|
xor _BP, _CX ; clear _BP mask=pPattern
|
|
sub _CX, _AX ; see if > 0? (_AX=Count)
|
|
jg short DoneSkipDestPels ; still not used up yet!
|
|
mov _AX, [_BP - HTPAT_BP_SIZE] ; get pattern size
|
|
SkipDestPelsLoop:
|
|
add _CX, _AX
|
|
jle short SkipDestPelsLoop ; do until > 0
|
|
DoneSkipDestPels:
|
|
add _BP, _CX ; _BP=pCurPat
|
|
jmp LoadByte
|
|
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
|
|
SUBTTL SingleCountOutputTo3Planes
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_1BPP_3PLANES destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
18-Jun-1991 Tue 12:00:35 updated -by- Daniel Chou (danielc)
|
|
Fixed destination masking bugs, it should be 0xff/0x00 rather 0x77
|
|
|
|
`
|
|
|
|
|
|
@BEG_PROC SingleCountOutputTo3Planes <pPrimColorCount:DWORD, \
|
|
pDest:DWORD, \
|
|
pPattern:DWORD, \
|
|
OutFuncInfo:QWORD>
|
|
|
|
|
|
;
|
|
; Register Usage:
|
|
;
|
|
; _SI = pPrimMonoCount
|
|
; _BP = Self host pPattern
|
|
; _SP = Some saved environment (Old BP to get to the local variable)
|
|
; bl:bh:al = Prim 1/2/3
|
|
; cl:ch:dl = Current Destination Byte, 0x88 is the mask bit indicator
|
|
; dh = Dest Mask
|
|
;
|
|
; Prim1 -> pPlane3 <---- Highest bit
|
|
; Prim2 -> pPlane2
|
|
; Prim3 -> pPlane1 <---- Lowest bit
|
|
;
|
|
; Local Variable access from Old BP, BytesPerPlane
|
|
;
|
|
|
|
|
|
@ENTER_PAT_TO_STK <3PLANES> ; _BP=Pat location, fall throug to load
|
|
|
|
;=============================================================================
|
|
; the DH has two uses, it contains the mask bits (1 bit=Mask), and it also
|
|
; contains an extra bit to do a byte boundary test, every time we shift the
|
|
; mask left by one, the boundary bit get shift to left, when first time a
|
|
; carry is produced then we know we finished one byte. at here we set up the
|
|
; dh=FirstMask + Aligned boundary bit
|
|
;=============================================================================
|
|
|
|
mov _DX, 1ffh ; dh=Mask (1=Mask, 0=Not Mask)
|
|
MOVZX_W _CX, <WPTR [_SI]> ; load extended
|
|
sub _BP, _CX ; back the _BP
|
|
shl _DX, cl ; set first mask
|
|
xor dl, dl
|
|
xor _CX, _CX ; clear cx now
|
|
jmp short LoadByte
|
|
|
|
|
|
;============================================================================
|
|
; EOF encountered, if Mask (DH) is equal to 0x01 then we just starting the new
|
|
; byte, which we just have exactly end at last byte boundary (no last byte
|
|
; mask), otherwise, shift all destination byte to left by count, then mask it
|
|
;============================================================================
|
|
; EOF encountered, if count is 0, then there is no last byte mask, so just
|
|
; exit, otherwise, shift all destination byte to left by count, then mask it
|
|
;============================================================================
|
|
|
|
EOFDest:
|
|
cmp dh, 1
|
|
jz short AllDone ; finished
|
|
|
|
EOFDestMask:
|
|
mov ax, cx ; save Prim1/2=al:ah
|
|
mov cx, WPTR [_SI] ; get LastByteSkips
|
|
|
|
xor bh, bh ; bx=0xffff now, clear bh
|
|
shl bx, cl ; bh=LastByteMask
|
|
shl dx, cl ; shift Mask+Prim3
|
|
or dh, bh ; add in dh=mask
|
|
cmp dh, 0ffh ; if dh=0xff then all masked
|
|
jz short AllDone
|
|
|
|
shl ax, cl ; shift Prim1/2
|
|
mov cx, ax ; restore cl:ch=Prim1/2
|
|
|
|
SAVE_3PLANES_MASKDEST <UseAX> ; save last byte
|
|
|
|
AllDone:
|
|
@EXIT_PAT_STK_RESTORE ; exit/restore env/stack
|
|
|
|
|
|
;==========================================================================
|
|
; An invalid density is encountered, (0xff to indicate the stretch must not
|
|
; update to the destination), if this is the last stretch then do 'EOFDest'
|
|
; otherwise set mask bits until the byte boundary is encountered then fall
|
|
; through to load next byte, if a byte boundary is before count are exausted
|
|
; then save that mask byte and it will automatically skip rest of the pels.
|
|
;==========================================================================
|
|
|
|
InvDensity:
|
|
cmp bl, bh
|
|
jz short EOFDest ; EOF
|
|
add cx, cx
|
|
add dx, dx
|
|
inc dh ; add in mask, 'C' not changed
|
|
jc short DoneOneByte ; finished? if not fall through
|
|
|
|
LoadByte:
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov bx, WPTR [_SI+2] ; bl:bh:al:ah=Prim 1/2/3/4
|
|
mov ax, WPTR [_SI+4]
|
|
dec _BP ; ready to access pattern
|
|
cmp bl, PRIM_INVALID_DENSITY
|
|
jz short InvDensity
|
|
mov ah, BPTR[_BP] ; get pattern
|
|
cmp bl, ah
|
|
adc cl, cl
|
|
cmp bh, ah
|
|
adc ch, ch
|
|
cmp al, ah
|
|
adc dx, dx
|
|
jnc short LoadByte
|
|
|
|
DoneOneByte:
|
|
or dh, dh ; any mask?
|
|
jnz short HasDestMask
|
|
|
|
SAVE_3PLANES_DEST <UseAX> ; save it, no jmp
|
|
|
|
ReadyNextByte:
|
|
inc _DI
|
|
xor _CX, _CX ; clear destination
|
|
mov _DX, 0100h ; dh=0x01=Boundary test bit
|
|
|
|
WRAP_BP_PAT?? <LoadByte>
|
|
|
|
HasDestMask:
|
|
cmp dh, 0ffh
|
|
jz short ReadyNextByte ;
|
|
|
|
SAVE_3PLANES_MASKDEST <UseAX> ; save it with DH=mask
|
|
|
|
jmp short ReadyNextByte
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
|
|
SUBTTL VarCountOutputTo3Planes
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_1BPP_3PLANES destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
18-Jun-1991 Tue 12:00:35 updated -by- Daniel Chou (danielc)
|
|
Fixed destination masking bugs, it should be 0xff/0x00 rather 0x77
|
|
|
|
|
|
`
|
|
|
|
|
|
|
|
@BEG_PROC VarCountOutputTo3Planes <pPrimColorCount:DWORD, \
|
|
pDest:DWORD, \
|
|
pPattern:DWORD, \
|
|
OutFuncInfo:QWORD>
|
|
|
|
|
|
;
|
|
; Register Usage:
|
|
;
|
|
; _SI = pPrimColorCount
|
|
; _BP = Self host pPattern
|
|
; _SP = Some saved environment (Old BP to get to the local variable)
|
|
; di = pPlane1
|
|
; bl:bh:al = Prim 1/2/3
|
|
; cl:ch:dl = Current Destination Byte, 0x88 is the mask bit indicator
|
|
; dh = Dest Mask
|
|
;
|
|
; Prim1 -> pPlane3 <---- Highest bit
|
|
; Prim2 -> pPlane2
|
|
; Prim3 -> pPlane1 <---- Lowest bit
|
|
;
|
|
; Local Variable access from Old BP, BytesPerPlane
|
|
;
|
|
|
|
|
|
@ENTER_PAT_TO_STK <3PLANES> ; _BP=Pat location
|
|
|
|
;=============================================================================
|
|
; the DH has two uses, it contains the mask bits (1 bit=Mask), and it also
|
|
; contains an extra bit to do a byte boundary test, every time we shift the
|
|
; mask left by one, the boundary bit get shift to left, when first time a
|
|
; carry is produced then we know we finished one byte. at here we set up the
|
|
; dh=FirstMask + Aligned boundary bit
|
|
;=============================================================================
|
|
|
|
mov _DX, 1ffh ; dh=Mask (1=Mask, 0=Not Mask)
|
|
MOVZX_W _CX, <WPTR [_SI]> ; load extended
|
|
sub _BP, _CX ; back the _BP
|
|
shl _DX, cl ; set first mask
|
|
xor dl, dl
|
|
xor _CX, _CX ; clear cx now
|
|
jmp short FirstLoadByte
|
|
|
|
;============================================================================
|
|
; EOF encountered, if Mask (DH) is equal to 0x01 then we just starting the new
|
|
; byte, which we just have exactly end at last byte boundary (no last byte
|
|
; mask), otherwise, shift all destination byte to left by count, then mask it
|
|
;============================================================================
|
|
; EOF encountered, if count is 0, then there is no last byte mask, so just
|
|
; exit, otherwise, shift all destination byte to left by count, then mask it
|
|
;============================================================================
|
|
|
|
EOFDest:
|
|
or si, si
|
|
jz short AllDone
|
|
|
|
EOFDestMask:
|
|
xchg si, cx ; si=Prim1/2, cx=Last Skips
|
|
|
|
xor bh, bh ; bx=0xffff now, clear bh
|
|
shl bx, cl ; bh=LastByteMask
|
|
shl dx, cl ; shift Mask+Prim3
|
|
or dh, bh ; add in dh=mask
|
|
cmp dh, 0ffh ; if dh=0xff then all masked
|
|
jz short AllDone
|
|
|
|
shl si, cl ; shift Prim1/2
|
|
mov cx, si ; restore cl:ch=Prim1/2
|
|
|
|
SAVE_3PLANES_MASKDEST ; save it with DH=mask
|
|
|
|
AllDone:
|
|
pop _SI ; pop the source pointer push
|
|
@EXIT_PAT_STK_RESTORE ; restore original SP
|
|
|
|
;==========================================================================
|
|
; An invalid density is encountered, (0xff to indicate the stretch must not
|
|
; update to the destination), if this is the last stretch then do 'EOFDest'
|
|
; otherwise set mask bits until the byte boundary is encountered then fall
|
|
; through to load next byte, if a byte boundary is before count are exausted
|
|
; then save that mask byte and it will automatically skip rest of the pels.
|
|
;==========================================================================
|
|
|
|
InvDensity:
|
|
cmp bl, bh
|
|
jz short EOFDest ; done
|
|
InvDensityLoop:
|
|
dec _BP
|
|
add cx, cx
|
|
add dx, dx
|
|
inc dh ; add in mask, 'C' not changed
|
|
jc short DoneOneByte
|
|
dec si
|
|
jnz short InvDensityLoop ; !!! FALL THROUGH
|
|
|
|
LoadByte:
|
|
pop _SI ; restore _SI
|
|
FirstLoadByte:
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
push _SI ; save _SI
|
|
mov bx, WPTR [_SI+2] ; bl:bh=Prim1/2
|
|
mov ax, WPTR [_SI+4] ; al:ah=Prim3/4
|
|
mov si, WPTR [_SI] ; si=Count
|
|
cmp bl, PRIM_INVALID_DENSITY ; a skip?, if yes go do it
|
|
jz short InvDensity
|
|
inc si ; make it no jump
|
|
MakeByte:
|
|
dec si
|
|
jz short LoadByte
|
|
dec _BP ; ready to access pattern
|
|
mov ah, BPTR[_BP] ; get pattern
|
|
cmp bl, ah
|
|
adc cl, cl
|
|
cmp bh, ah
|
|
adc ch, ch
|
|
cmp al, ah
|
|
adc dx, dx
|
|
jnc short MakeByte ; if carry then byte boundary
|
|
|
|
DoneOneByte:
|
|
or dh, dh ; any mask?
|
|
jnz short HasDestMask ; yes
|
|
|
|
SAVE_3PLANES_DEST ; save it
|
|
|
|
ReadyNextByte:
|
|
inc _DI ; ++pDest
|
|
xor _CX, _CX ; clear destination
|
|
mov _DX, 0100h ; dh=0x01, dl=0x00
|
|
|
|
WRAP_BP_PAT?? <MakeByte>
|
|
|
|
;=============================================================================
|
|
; Mask the destination by DH mask, (1 bit=Mask), if whole destiantion byte is
|
|
; masked then just increment the pDest
|
|
;=============================================================================
|
|
|
|
HasDestMask:
|
|
cmp dh, 0ffh
|
|
jz short DoneDestMask
|
|
|
|
SAVE_3PLANES_MASKDEST ; save it with DH=mask
|
|
|
|
DoneDestMask:
|
|
cmp bl, PRIM_INVALID_DENSITY ; is last one a skip stretch?
|
|
jnz short ReadyNextByte
|
|
cmp si, 1 ; more than 0 count?
|
|
jbe short ReadyNextByte ; no, continue
|
|
|
|
;
|
|
;*** FALL THROUGH
|
|
;
|
|
|
|
;============================================================================
|
|
; skip the 'si-1' count of pels on the destination (SI is post decrement so
|
|
; we must only skip 'si-1' count), it will skip the 'pDest', set up next
|
|
; pDest mask, also it will aligned the destination pattern pointer (_BP)
|
|
;===========================================================================
|
|
|
|
SkipDestPels:
|
|
inc _DI ; update to current pDest
|
|
|
|
dec si ; back one
|
|
WZXE si ; zero extended
|
|
mov cx, si
|
|
and cl, 7
|
|
;===============================================================
|
|
mov _DX, 1ffh ; ready to shift
|
|
shl _DX, cl
|
|
xor dl, dl ; clear Prim3
|
|
xor _CX, _CX ; clear Prim1/2
|
|
;================================================================
|
|
mov _BX, _SI
|
|
shr _BX, 3
|
|
add _DI, _BX
|
|
mov _BX, _BP
|
|
and _BX, HTPAT_STK_MASK ; how many pat avai.?
|
|
xor _BP, _BX ; clear _BP mask=pPattern
|
|
sub _BX, _SI ; see if > 0?
|
|
jg short DoneSkipDestPels
|
|
mov _SI, [_BP - HTPAT_BP_SIZE] ; get pattern size
|
|
SkipDestPelsLoop:
|
|
add _BX, _SI
|
|
jle short SkipDestPelsLoop ; do until > 0
|
|
DoneSkipDestPels:
|
|
add _BP, _BX ; _BP=pCurPat
|
|
jmp LoadByte
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
|
|
|
|
SUBTTL SingleCountOutputTo4BPP
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
`
|
|
|
|
@BEG_PROC SingleCountOutputTo4BPP <pPrimColorCount:DWORD, \
|
|
pDest:DWORD, \
|
|
pPattern:DWORD, \
|
|
OutFuncInfo:QWORD>
|
|
|
|
|
|
;==========================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pPrimColorCount
|
|
; _DI : pDest
|
|
; _BP : Current pPattern, self wrappable
|
|
; bl:bh:al:ah : Prim 1/2/3/4 =====> Bit 2:1:0
|
|
; dl : DestByte
|
|
; dh : scratch register
|
|
; ch : PRIM_INVALID_DENSITY
|
|
; cl : PRIM_INVALID_DENSITY --> CX = PRIMCOUNT_EOF
|
|
;==========================================
|
|
|
|
|
|
@ENTER_PAT_TO_STK <4BPP> ; _BP=Pat location
|
|
|
|
;=============================================================================
|
|
; the DH has two uses, it contains the mask bits (1 bit=Mask), and it also
|
|
; contains an extra bit to do a byte boundary test, every time we shift the
|
|
; mask left by one, the boundary bit get shift to left, when first time a
|
|
; carry is produced then we know we finished one byte. at here we set up the
|
|
; dh=FirstMask + Aligned boundary bit
|
|
;=============================================================================
|
|
|
|
mov _CX, PRIMCOUNT_EOF
|
|
xor _DX, _DX ; clear mask/dest
|
|
cmp WPTR [_SI], dx ; check if begin with skip
|
|
jnz short InvDensityHStart ; has first skip
|
|
|
|
LoadByteH:
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov bx, WPTR [_SI+2] ; bl:bh=Prim 1/2
|
|
cmp bl, ch ; invalid?
|
|
jz short InvDensityH
|
|
mov ax, WPTR [_SI+4] ; al:ah=Prim 3/4
|
|
|
|
MakeByteH:
|
|
dec _BP
|
|
mov dh, BPTR [_BP]
|
|
cmp bl, dh
|
|
adc dl, dl
|
|
cmp bh, dh
|
|
adc dl, dl
|
|
cmp al, dh
|
|
adc dl, dl
|
|
|
|
LoadByteL:
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov bx, WPTR [_SI+2] ; bl:bh=Prim 1/2
|
|
cmp bl, ch ; invalid?
|
|
jz short InvDensityL
|
|
mov ax, WPTR [_SI+4] ; al:ah=Prim 3/4
|
|
|
|
MakeByteL:
|
|
add dl, dl
|
|
dec _BP
|
|
mov dh, BPTR [_BP]
|
|
cmp bl, dh
|
|
adc dl, dl
|
|
cmp bh, dh
|
|
adc dl, dl
|
|
cmp al, dh
|
|
adc dl, dl
|
|
|
|
SAVE_4BPP_DEST
|
|
|
|
ReadyNextByte:
|
|
inc _DI
|
|
xor _DX, _DX
|
|
|
|
WRAP_BP_PAT?? <LoadByteH>
|
|
|
|
;=============================================================================
|
|
; The high nibble need to be skipped, (byte boundary now), if bl=bh=INVALID
|
|
; then we are done else set the mask=0xf0 (high nibble) and if count > 1 then
|
|
; continune load LOW nibble
|
|
;=============================================================================
|
|
|
|
InvDensityH:
|
|
cmp bl, bh ; end?
|
|
jz short AllDone ; exactly byte boundary
|
|
InvDensityHStart:
|
|
dec _BP ; update pCurPat
|
|
LoadByteL2:
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov bx, WPTR [_SI+2] ; bl:bh=Prim 1/2
|
|
cmp bl, ch ; invalid?
|
|
jz short DoneDestMask
|
|
mov ax, WPTR [_SI+4] ; al:ah=Prim 3/4
|
|
|
|
MakeByteL2:
|
|
add dl, dl ; skip high bit
|
|
mov dh, BPTR [_BP-1] ; load next pattern
|
|
cmp bl, dh
|
|
adc dl, dl
|
|
cmp bh, dh
|
|
adc dl, dl
|
|
cmp al, dh
|
|
adc dl, dl
|
|
|
|
SAVE_4BPP_DEST_LOW ; fall through
|
|
|
|
DoneDestMask:
|
|
dec _BP
|
|
cmp bx, cx ; done?
|
|
jnz short ReadyNextByte
|
|
jmp short AllDone
|
|
|
|
InvDensityL:
|
|
SAVE_4BPP_DEST_HIGH
|
|
dec _BP
|
|
cmp bx, cx
|
|
jnz short ReadyNextByte
|
|
|
|
AllDone:
|
|
@EXIT_PAT_STK_RESTORE
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
|
|
|
|
SUBTTL VarCountOutputTo4BPP
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination plane.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
`
|
|
|
|
@BEG_PROC VarCountOutputTo4BPP <pPrimColorCount:DWORD, \
|
|
pDest:DWORD, \
|
|
pPattern:DWORD, \
|
|
OutFuncInfo:QWORD>
|
|
|
|
;==========================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pPrimColorCount
|
|
; _DI : pDest
|
|
; _BP : Current pPattern, self wrappable
|
|
; cx : PrimColorCount.Count
|
|
; bl:bh:al:ah : Prim 1/2/3/4 =====> Bit 2:1:0
|
|
; dl : DestByte
|
|
; dh : Scratch Register
|
|
;==========================================
|
|
|
|
|
|
@ENTER_PAT_TO_STK <4BPP> ; _BP=Pat location
|
|
|
|
;=============================================================================
|
|
; the DH has two uses, it contains the mask bits (1 bit=Mask), and it also
|
|
; contains an extra bit to do a byte boundary test, every time we shift the
|
|
; mask left by one, the boundary bit get shift to left, when first time a
|
|
; carry is produced then we know we finished one byte. at here we set up the
|
|
; dh=FirstMask + Aligned boundary bit
|
|
;=============================================================================
|
|
|
|
xor _DX, _DX ; clear mask/dest
|
|
mov cx, WPTR [_SI]
|
|
or cx, cx
|
|
jnz short InvDensityHStart ; has first skip
|
|
|
|
LoadByteH:
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov cx, WPTR [_SI] ; cx=count
|
|
mov bx, WPTR [_SI+2] ; bl:bh=Prim 1/2
|
|
cmp bl, PRIM_INVALID_DENSITY ; invalid?
|
|
jz short InvDensityH
|
|
mov ax, WPTR [_SI+4] ; al:ah=Prim 3/4
|
|
inc cx
|
|
|
|
LoadByteH1:
|
|
dec cx
|
|
jz short LoadByteH
|
|
|
|
MakeByteH:
|
|
dec _BP
|
|
mov dh, BPTR [_BP]
|
|
cmp bl, dh
|
|
adc dl, dl
|
|
cmp bh, dh
|
|
adc dl, dl
|
|
cmp al, dh
|
|
adc dl, dl
|
|
|
|
dec cx ;
|
|
jz short LoadByteL
|
|
|
|
MakeByteL:
|
|
add dl, dl ; skip high bit
|
|
dec _BP
|
|
mov dh, BPTR [_BP]
|
|
cmp bl, dh
|
|
adc dl, dl
|
|
cmp bh, dh
|
|
adc dl, dl
|
|
cmp al, dh
|
|
adc dl, dl
|
|
|
|
SAVE_4BPP_DEST
|
|
|
|
ReadyNextByte:
|
|
inc _DI
|
|
xor _DX, _DX
|
|
|
|
WRAP_BP_PAT?? <LoadByteH1>
|
|
|
|
|
|
;=============================================================================
|
|
; The high nibble need to be skipped, (byte boundary now), if bl=bh=INVALID
|
|
; then we are done else set the mask=0xf0 (high nibble) and if count > 1 then
|
|
; continune load LOW nibble
|
|
;=============================================================================
|
|
|
|
LoadByteL:
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov cx, WPTR [_SI] ; cx=count
|
|
mov bx, WPTR [_SI+2] ; bl:bh=Prim 1/2
|
|
mov ax, WPTR [_SI+4] ; al:ah=Prim 3/4
|
|
cmp bl, PRIM_INVALID_DENSITY ; invalid?
|
|
jnz short MakeByteL
|
|
|
|
SAVE_4BPP_DEST_HIGH ; save only high nibble
|
|
|
|
jmp short DoneDestMask
|
|
|
|
InvDensityH:
|
|
cmp bl, bh ; end?
|
|
jz short AllDone ; exactly byte boundary
|
|
|
|
InvDensityHStart:
|
|
dec _BP ; update pCurPat
|
|
dec cx
|
|
jnz short DoneDestMask
|
|
|
|
LoadByteL2:
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov cx, WPTR [_SI] ; cx=count
|
|
mov bx, WPTR [_SI+2] ; bl:bh=Prim 1/2
|
|
cmp bl, PRIM_INVALID_DENSITY ; invalid?
|
|
jz short DoneDestMask
|
|
mov ax, WPTR [_SI+4] ; al:ah=Prim 3/4
|
|
|
|
MakeByteL2:
|
|
add dl, dl ; skip high bit
|
|
mov dh, BPTR [_BP-1] ; load next pattern
|
|
cmp bl, dh
|
|
adc dl, dl
|
|
cmp bh, dh
|
|
adc dl, dl
|
|
cmp al, dh
|
|
adc dl, dl
|
|
|
|
SAVE_4BPP_DEST_LOW ; fall through
|
|
|
|
DoneDestMask:
|
|
dec _BP
|
|
cmp bl, PRIM_INVALID_DENSITY ; is last one a skip stretch?
|
|
jnz short ReadyNextByte
|
|
cmp bl, bh ; end?
|
|
jz short AllDone
|
|
cmp cx, 1
|
|
jbe short ReadyNextByte
|
|
|
|
;============================================================================
|
|
; skip the 'cx-1' count of pels on the destination (SI is post decrement so
|
|
; we must only skip 'cx-1' count), it will skip the 'pDest', set up next
|
|
; pDest mask, also it will aligned the destination pattern pointer (_BP)
|
|
;===========================================================================
|
|
|
|
SkipDestPels:
|
|
inc _DI ; update to current pDest
|
|
xor _DX, _DX ;
|
|
|
|
dec cx
|
|
WZXE cx ; zero extended
|
|
mov _AX, _CX
|
|
shr _CX, 1 ; see if carry
|
|
sbb dh, dh ; -1=skip high nibble
|
|
add _DI, _CX ; 2 pels per byte
|
|
mov _CX, _BP ; align pattern now
|
|
and _CX, HTPAT_STK_MASK ; how many pat avai.?
|
|
xor _BP, _CX ; clear _BP mask=pPattern
|
|
sub _CX, _AX ; see if > 0? (_AX=Count)
|
|
jg short DoneSkipDestPels ; still not used up yet!
|
|
mov _AX, [_BP - HTPAT_BP_SIZE] ; get pattern size
|
|
SkipDestPelsLoop:
|
|
add _CX, _AX
|
|
jle short SkipDestPelsLoop ; do until > 0
|
|
DoneSkipDestPels:
|
|
add _BP, _CX ; _BP=pCurPat
|
|
or dh, dh
|
|
jnz short LoadByteL2
|
|
jmp LoadByteH
|
|
|
|
AllDone:
|
|
@EXIT_PAT_STK_RESTORE
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
|
|
|
|
SUBTTL SingleCountOutputToVGA16
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_VGA16 destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
|
|
`
|
|
|
|
@BEG_PROC SingleCountOutputToVGA16 <pPrimColorCount:DWORD, \
|
|
pDest:DWORD, \
|
|
pPattern:DWORD, \
|
|
OutFuncInfo:QWORD>
|
|
|
|
;
|
|
; VGA 16 Standard table
|
|
;
|
|
; 0, 0, 0, 0000 0 Black
|
|
; 0, ,0, 0x80 0001 1 Dark Red
|
|
; 0, 0x80,0, 0010 2 Dark Green
|
|
; 0, ,0x80,0x80 0011 3 Dark Yellow
|
|
; 0x80 0, 0, 0100 4 Dark Blue
|
|
; 0x80,0, 0x80 0101 5 Dark Magenta
|
|
; 0x80 0x80,0, 0110 6 Dark Cyan
|
|
; 0x80,0x80,0x80 0111 7 Gray 50%
|
|
;
|
|
; 0xC0,0xC0,0xC0 1000 8 Gray 75%
|
|
; 0, ,0, 0xFF 1001 9 Red
|
|
; 0, 0xFF,0, 1010 10 Green
|
|
; 0, ,0xFF,0xFF 1011 11 Yellow
|
|
; 0xFF 0, 0, 1100 12 Blue
|
|
; 0xFF,0, 0xFF 1101 13 Magenta
|
|
; 0xFF 0xFF,0, 1110 14 Cyan
|
|
; 0xFF,0xFF,0xFF 1111 15 White
|
|
;
|
|
;==========================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pPrimColorCount
|
|
; _DI : pDest
|
|
; _BP : Current pPattern, self wrappable
|
|
; bl:bh:dl:dh : Prim 1/2/5/6 Prim6 is Index for VGA16ColorIndex[]
|
|
; cl : PRIM_INVALID_DENSITY
|
|
; ch : ZERO (0)
|
|
; al : Pattern/Low Nibble
|
|
; ah : High nibble
|
|
;
|
|
; Prim1 = Initial VGA16ColorIndex[]
|
|
; Prim2 = Color Thresholds for VGA16ColorIndex[Prim1]
|
|
; Prim3 = Color Thresholds for VGA16ColorIndex[Prim1-1]
|
|
; Prim4 = Color Thresholds for VGA16ColorIndex[Prim1-2]
|
|
; Prim5 = Color Thresholds for VGA16ColorIndex[Prim1-3]
|
|
; Prim6 = Color Thresholds for VGA16ColorIndex[Prim1-4]
|
|
; ELSE VGA16ColorIndex[Prim1-5]
|
|
;=========================================================================
|
|
;
|
|
|
|
|
|
@ENTER_PAT_TO_STK <VGA16> ; _BP=Pat location
|
|
|
|
;=============================================================================
|
|
; the DH has two uses, it contains the mask bits (1 bit=Mask), and it also
|
|
; contains an extra bit to do a byte boundary test, every time we shift the
|
|
; mask left by one, the boundary bit get shift to left, when first time a
|
|
; carry is produced then we know we finished one byte. at here we set up the
|
|
; dh=FirstMask + Aligned boundary bit
|
|
;=============================================================================
|
|
|
|
xor _BX, _BX ; clear high word
|
|
sub _SI, SIZE_PCC
|
|
cmp WPTR [_SI + SIZE_PCC], bx ; check if begin with skip
|
|
mov cl, PRIM_INVALID_DENSITY
|
|
jz SHORT DoHNibble
|
|
add _SI, SIZE_PCC
|
|
jmp SHORT SkipPelsH_2 ; skip from the first pel
|
|
|
|
AllDone:
|
|
@EXIT_PAT_STK_RESTORE
|
|
|
|
|
|
SkipPelsH:
|
|
add _SI, (SIZE_PCC * 2)
|
|
mov bx, WPTR [_SI+2]
|
|
cmp bl, PRIM_INVALID_DENSITY
|
|
jnz SHORT LoadHNibble
|
|
|
|
SkipPelsH_1:
|
|
cmp bl, bh
|
|
jz SHORT AllDone
|
|
|
|
SkipPelsH_2:
|
|
sub _BP, 2
|
|
|
|
SkipPelsL:
|
|
mov bx, WPTR [_SI+SIZE_PCC+2]
|
|
cmp bl, PRIM_INVALID_DENSITY
|
|
jz SHORT SkipPelsL_1
|
|
|
|
mov ah, BPTR_ES[_DI] ; start from Low nibble so
|
|
mov cl, BPTR [_BP] ; get pattern
|
|
jmp SHORT LoadLNibble ; we must load current dest
|
|
|
|
SaveLNibbleAndSkip:
|
|
and BPTR_ES[_DI], 0fh ; clear high nibble
|
|
and ah, 0f0h ; clear low nibble
|
|
or BPTR_ES[_DI], ah ; save it in
|
|
|
|
SkipPelsL_1:
|
|
cmp bl, bh
|
|
jz SHORT AllDone
|
|
inc _DI ; skip the destination
|
|
|
|
WRAP_BP_PAT?? <SkipPelsH> ; repeat until no more skips
|
|
|
|
|
|
|
|
DoHNibble:
|
|
add _SI, (SIZE_PCC * 2)
|
|
mov bx, WPTR [_SI+2] ; bl:bh=Prim 1/2
|
|
cmp bl, PRIM_INVALID_DENSITY
|
|
jz SHORT SkipPelsH_1
|
|
|
|
LoadHNibble:
|
|
sub _BP, 2
|
|
mov cx, WPTR [_BP]
|
|
|
|
;
|
|
;===================================================================
|
|
; 2 4 6
|
|
; +-+ +--+ +--+
|
|
; 1 2 3 4 5
|
|
; bh:cl:ch:dl:dh
|
|
;--------------------------
|
|
|
|
IFE ExtRegSet
|
|
mov dx, WPTR [_SI+4] ; Color 2/3
|
|
cmp dh, ch ; first split in the middle
|
|
jae SHORT GetH1 ; [ie. binary search/compare]
|
|
mov dx, WPTR [_SI+6] ; now check if Prim4/5
|
|
ELSE
|
|
mov _DX, DPTR [_SI+4]
|
|
cmp dh, ch ; first split in the middle
|
|
jae SHORT GetH1 ; [ie. binary search/compare]
|
|
shr _DX, 16
|
|
ENDIF
|
|
|
|
cmp dl, ch
|
|
sbb bl, 3 ; one of -3/-4/-5
|
|
cmp dh, ch
|
|
jmp SHORT GetH2
|
|
|
|
GetH1: cmp bh, ch ; it is white
|
|
jae SHORT GetHNibble
|
|
dec bl
|
|
cmp dl, ch
|
|
|
|
GetH2: sbb bl, 0
|
|
|
|
;
|
|
;===================================================================
|
|
;
|
|
|
|
GetHNibble:
|
|
xor bh, bh
|
|
mov ah, BPTR cs:VGA16ColorIndex[_BX]
|
|
|
|
|
|
DoLNibble:
|
|
mov bx, WPTR [_SI+SIZE_PCC+2] ; bl:bh=Prim 1/2
|
|
cmp bl, PRIM_INVALID_DENSITY
|
|
jz SHORT SaveLNibbleAndSkip
|
|
|
|
LoadLNibble:
|
|
|
|
;
|
|
;===================================================================
|
|
; 2 4 6
|
|
; +-+ +--+ +--+
|
|
; 1 2 3 4 5
|
|
; bh:cl:ch:dl:dh
|
|
;--------------------------
|
|
|
|
IFE ExtRegSet
|
|
mov dx, WPTR [_SI+SIZE+PCC+4] ; Color 2/3
|
|
cmp dh, cl ; first split in the middle
|
|
jae SHORT GetL1 ; [ie. binary search/compare]
|
|
mov dx, WPTR [_SI+SIZE+PCC+6] ; now check if Prim4/5
|
|
ELSE
|
|
mov _DX, DPTR [_SI+SIZE_PCC+4]
|
|
cmp dh, cl ; first split in the middle
|
|
jae SHORT GetL1 ; [ie. binary search/compare]
|
|
shr _DX, 16
|
|
ENDIF
|
|
|
|
cmp dl, cl
|
|
sbb bl, 3 ; one of -3/-4/-5
|
|
cmp dh, cl
|
|
jmp SHORT GetL2
|
|
|
|
GetL1: cmp bh, cl ; it is white
|
|
jae SHORT GetLNibble
|
|
dec bl
|
|
cmp dl, cl
|
|
|
|
GetL2: sbb bl, 0
|
|
|
|
;
|
|
;===================================================================
|
|
;
|
|
|
|
GetLNibble:
|
|
|
|
xor bh, bh
|
|
mov al, BPTR cs:VGA16ColorIndex[_BX]
|
|
and ax, 0f00fh
|
|
or al, ah
|
|
stosb
|
|
|
|
WRAP_BP_PAT?? <DoHNibble>
|
|
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
|
|
|
|
|
|
SUBTTL VarCountOutputToVGA16
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination plane.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
`
|
|
|
|
@BEG_PROC VarCountOutputToVGA16 <pPrimColorCount:DWORD, \
|
|
pDest:DWORD, \
|
|
pPattern:DWORD, \
|
|
OutFuncInfo:QWORD>
|
|
|
|
|
|
;
|
|
; VGA 16 Standard table
|
|
;
|
|
; 0, 0, 0, 0000 0 Black
|
|
; 0, ,0, 0x80 0001 1 Dark Red
|
|
; 0, 0x80,0, 0010 2 Dark Green
|
|
; 0, ,0x80,0x80 0011 3 Dark Yellow
|
|
; 0x80 0, 0, 0100 4 Dark Blue
|
|
; 0x80,0, 0x80 0101 5 Dark Magenta
|
|
; 0x80 0x80,0, 0110 6 Dark Cyan
|
|
; 0x80,0x80,0x80 0111 7 Gray 50%
|
|
;
|
|
; 0xC0,0xC0,0xC0 1000 8 Gray 75%
|
|
; 0, ,0, 0xFF 1001 9 Red
|
|
; 0, 0xFF,0, 1010 10 Green
|
|
; 0, ,0xFF,0xFF 1011 11 Yellow
|
|
; 0xFF 0, 0, 1100 12 Blue
|
|
; 0xFF,0, 0xFF 1101 13 Magenta
|
|
; 0xFF 0xFF,0, 1110 14 Cyan
|
|
; 0xFF,0xFF,0xFF 1111 15 White
|
|
;
|
|
;==========================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pPrimColorCount
|
|
; _DI : pDest
|
|
; _BP : Current pPattern, self wrappable
|
|
; ax : PrimColorCount.Count
|
|
; bl:bh:cl:ch:dl:dh : Prim 1/2/3/4/5/6
|
|
;==========================================
|
|
; Prim1 = Initial VGA16ColorIndex[]
|
|
; Prim2 = Color Thresholds for VGA16ColorIndex[Prim1]
|
|
; Prim3 = Color Thresholds for VGA16ColorIndex[Prim1-1]
|
|
; Prim4 = Color Thresholds for VGA16ColorIndex[Prim1-2]
|
|
; Prim5 = Color Thresholds for VGA16ColorIndex[Prim1-3]
|
|
; Prim6 = Color Thresholds for VGA16ColorIndex[Prim1-4]
|
|
; ELSE VGA16ColorIndex[Prim1-5]
|
|
;=========================================================================
|
|
;
|
|
|
|
|
|
@ENTER_PAT_TO_STK <VGA16> ; _BP=Pat location
|
|
|
|
;=============================================================================
|
|
; the DH has two uses, it contains the mask bits (1 bit=Mask), and it also
|
|
; contains an extra bit to do a byte boundary test, every time we shift the
|
|
; mask left by one, the boundary bit get shift to left, when first time a
|
|
; carry is produced then we know we finished one byte. at here we set up the
|
|
; dh=FirstMask + Aligned boundary bit
|
|
;=============================================================================
|
|
|
|
xor _BX, _BX
|
|
cmp WPTR [_SI], 0
|
|
jnz SHORT SkipPelsH_2
|
|
|
|
JMP LoadPrimH ; start the process
|
|
|
|
SkipPelsContinue:
|
|
or dh, dh
|
|
jz SHORT SkipPelsH
|
|
|
|
SkipPelsL:
|
|
cmp bl, bh
|
|
jz SHORT AllDone
|
|
|
|
xor dh, dh ; clear indicator
|
|
|
|
dec _BP
|
|
WRAP_BP_PAT??
|
|
|
|
inc _DI
|
|
MOVZX_W _BX, <WPTR [_SI]> ; get skip count
|
|
dec _BX ; only one
|
|
jz SHORT TrySkipNext
|
|
jmp SHORT SkipBXPels
|
|
|
|
AllDone:
|
|
@EXIT_PAT_STK_RESTORE
|
|
|
|
SkipPelsH:
|
|
cmp bl, bh ; end?
|
|
jz SHORT AllDone
|
|
|
|
SkipPelsH_2:
|
|
MOVZX_W _BX, <WPTR [_SI]> ; get skip count
|
|
|
|
SkipBXPels:
|
|
mov _CX, _BX
|
|
shr _CX, 1 ; see if carry
|
|
sbb dh, dh ; -1=skip high nibble
|
|
add _DI, _CX ; 2 pels per byte
|
|
mov _CX, _BP ; align pattern now
|
|
and _CX, HTPAT_STK_MASK ; how many pat avai.?
|
|
xor _BP, _CX ; clear _BP mask=pPattern
|
|
sub _CX, _BX ; see if > 0? (_BX=Count)
|
|
jg short DoneSkipDestPels ; still not used up yet!
|
|
mov _BX, [_BP - HTPAT_BP_SIZE] ; get pattern size
|
|
SkipDestPelsLoop:
|
|
add _CX, _BX
|
|
jle short SkipDestPelsLoop ; do until > 0
|
|
DoneSkipDestPels:
|
|
add _BP, _CX ; _BP=pCurPat
|
|
|
|
TrySkipNext:
|
|
add _SI, SIZE_PCC
|
|
mov bx, WPTR [_SI+2]
|
|
cmp bl, PRIM_INVALID_DENSITY ; still invalid ?
|
|
jz SHORT SkipPelsContinue
|
|
|
|
or dh, dh ; skip high nibble?
|
|
jz SHORT LoadPrimHStart ; no
|
|
|
|
mov cx, WPTR [_SI+4] ; cl:ch=Prim 3/4
|
|
mov dx, WPTR [_SI+6] ; dl:dh=Prim 5/6
|
|
push _SI
|
|
mov si, WPTR [_SI] ; si=count
|
|
and BPTR_ES[_DI], 0f0h ; clear low nibble first!!!
|
|
jmp SHORT DoLNibble
|
|
|
|
|
|
PopSI_LoadPrimH:
|
|
pop _SI
|
|
|
|
LoadPrimH:
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov bx, WPTR [_SI+2] ; bl:bh=Prim 1/2
|
|
cmp bl, PRIM_INVALID_DENSITY ; invalid?
|
|
jz SHORT SkipPelsH
|
|
|
|
LoadPrimHStart:
|
|
mov cx, WPTR [_SI+4] ; dl:dh=Prim 3/4
|
|
mov dx, WPTR [_SI+6] ; al:ah=Prim 5/6
|
|
|
|
push _SI
|
|
mov si, WPTR [_SI] ; si=count
|
|
inc si
|
|
|
|
DoHNibble:
|
|
dec si
|
|
jz SHORT PopSI_LoadPrimH
|
|
|
|
dec _BP
|
|
mov ah, BPTR [_BP]
|
|
mov al, bl ; initial condition
|
|
|
|
;
|
|
; 1 2 3 4 5
|
|
; bh:cl:ch:dl:dh
|
|
;----------------------
|
|
|
|
cmp ch, ah
|
|
jae SHORT GetH1
|
|
cmp dl, ah
|
|
sbb al, 3
|
|
cmp dh, ah
|
|
jmp SHORT GetH2
|
|
|
|
GetH1: cmp bh, ah
|
|
jae SHORT GetHNibble
|
|
dec al
|
|
cmp cl, ah
|
|
|
|
GetH2: sbb al, 0
|
|
|
|
GetHNibble:
|
|
BZXEAX al
|
|
mov al, BPTR cs:VGA16ColorIndex[_AX]
|
|
and al, 0f0h
|
|
|
|
dec si
|
|
jz SHORT PopSI_LoadPrimL
|
|
|
|
SaveHNibbleL0:
|
|
mov BPTR_ES[_DI], al ; save high nibble
|
|
|
|
DoLNibble:
|
|
dec _BP
|
|
mov ah, BPTR [_BP]
|
|
mov al, bl ; initial condition
|
|
|
|
;
|
|
; 1 2 3 4 5
|
|
; bh:cl:ch:dl:dh
|
|
;----------------------
|
|
|
|
cmp ch, ah
|
|
jae SHORT GetL1
|
|
cmp dl, ah
|
|
sbb al, 3
|
|
cmp dh, ah
|
|
jmp SHORT GetL2
|
|
|
|
GetL1: cmp bh, ah
|
|
jae SHORT GetLNibble
|
|
dec al
|
|
cmp cl, ah
|
|
|
|
GetL2: sbb al, 0
|
|
|
|
GetLNibble:
|
|
BZXEAX al
|
|
mov al, BPTR cs:VGA16ColorIndex[_AX]
|
|
and al, 0fh
|
|
or BPTR_ES[_DI], al ; or in the low nibble
|
|
inc _DI
|
|
|
|
WRAP_BP_PAT?? <DoHNibble>
|
|
|
|
PopSI_LoadPrimL:
|
|
pop _SI
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov bx, WPTR [_SI+2] ; bl:bh=Prim 1/2
|
|
cmp bl, PRIM_INVALID_DENSITY
|
|
jz SHORT SaveAH_SkipPelsL
|
|
|
|
mov cx, WPTR [_SI+4] ; dl:dh=Prim 3/4
|
|
mov dx, WPTR [_SI+6] ; al:ah=Prim 5/6
|
|
push _SI
|
|
mov si, WPTR [_SI] ; si=count
|
|
jmp SHORT SaveHNibbleL0
|
|
|
|
SaveAH_SkipPelsL: ; need to save current AL
|
|
and BPTR_ES[_DI], 0fh ; clear high nibble
|
|
or BPTR_ES[_DI], al ; move high nibble in
|
|
jmp SkipPelsL
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
|
|
|
|
SUBTTL SingleCountOutputToVGA256
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_VGA256 destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
01-Jun-1992 Mon 15:32:00 updated -by- Daniel Chou (danielc)
|
|
1. Fixed so that Prims match the device's BGR color table format rather
|
|
than RGB format
|
|
|
|
|
|
`
|
|
|
|
@BEG_PROC SingleCountOutputToVGA256 <pPrimColorCount:DWORD, \
|
|
pDest:DWORD, \
|
|
pPattern:DWORD, \
|
|
OutFuncInfo:QWORD>
|
|
|
|
|
|
;==========================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pPrimColorCount
|
|
; _DI : pDest
|
|
; _BP : Current pPattern, self wrappable
|
|
; cl:ch:dl:dh : Prim 1/2/3/4 ====> R/G/B/IDX
|
|
; _BX : Scratch register
|
|
; _AX : Scratch register
|
|
;==========================================
|
|
;
|
|
@ENTER_PAT_TO_STK <VGA256> ; _BP=Pat location
|
|
|
|
;============================================================================
|
|
; Since we are in byte boundary, we should never have an invalid density to
|
|
; start with
|
|
;
|
|
; The VGA256's color table is constructed as BGR and 6 steps for each primary
|
|
; color.
|
|
;
|
|
; The BGR Mask = 0x24:0x06:0x01
|
|
;============================================================================
|
|
|
|
cld ; clear direction
|
|
or _AX, _AX
|
|
jz SHORT V256_NoXlate
|
|
|
|
V256_HasXlate:
|
|
|
|
IFE ExtRegSet
|
|
mov _BX, _SP ; the table on the stack
|
|
ELSE
|
|
mov _BX, _AX ; _AX point to xlate table
|
|
ENDIF
|
|
|
|
V256_XlateByteLoop:
|
|
dec _BP ; do this one first
|
|
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov cx, WPTR [_SI+2] ; bl:bh=Prim 1/2 B/G
|
|
cmp cl, PRIM_INVALID_DENSITY ; invalid?
|
|
jz short V256_XlateInvDensity
|
|
|
|
mov dh, BPTR [_BP] ; al=pattern
|
|
dec dh ; make it cmp al, cl work
|
|
|
|
cmp dh, cl
|
|
sbb ah, ah ; al=0xff or 0
|
|
cmp dh, ch
|
|
sbb al, al
|
|
and ax, ((VGA256_B_CUBE_INC shl 8) or VGA256_G_CUBE_INC) ; dh:dl=36:6
|
|
|
|
mov cx, WPTR [_SI+4] ; cl:ch=Prim 3/4 R/I
|
|
|
|
cmp dh, cl
|
|
adc al, ah
|
|
add al, ch
|
|
|
|
;
|
|
; for extended register set _BX point to the translation table
|
|
; otherwise ss:bx point to the translation table
|
|
;
|
|
|
|
IFE ExtRegSet
|
|
xlat _SS:VGA256_SSSP_XLAT_TABLE
|
|
ELSE
|
|
xlatb
|
|
ENDIF
|
|
stosb
|
|
|
|
WRAP_BP_PAT?? <V256_XlateByteLoop>
|
|
|
|
V256_XlateInvDensity:
|
|
cmp cl, ch
|
|
jz short V256_XlateAllDone
|
|
|
|
inc _DI
|
|
WRAP_BP_PAT?? <V256_XlateByteLoop>
|
|
|
|
V256_XlateAllDone:
|
|
|
|
IFE ExtRegSet
|
|
add _SP, VGA256_XLATE_TABLE_SIZE
|
|
ENDIF
|
|
|
|
;===================================================================
|
|
|
|
AllDone:
|
|
@EXIT_PAT_STK_RESTORE
|
|
|
|
;===================================================================
|
|
|
|
|
|
V256_NoXlate:
|
|
|
|
mov bx, ((VGA256_B_CUBE_INC shl 8) or VGA256_G_CUBE_INC)
|
|
|
|
V256_ByteLoop:
|
|
dec _BP ; do this one first
|
|
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov cx, WPTR [_SI+2] ; cl:ch=Prim 1/2 B/G
|
|
cmp cl, PRIM_INVALID_DENSITY ; invalid?
|
|
jz short V256_InvDensity
|
|
|
|
mov dh, BPTR [_BP] ; dh=pattern
|
|
dec dh ; make it cmp dh, T work
|
|
|
|
cmp dh, cl
|
|
sbb ah, ah ; ah=0xff or 0
|
|
cmp dh, ch
|
|
sbb al, al ; al=0xff or 0x00
|
|
and ax, bx ; bh:bl=36:6
|
|
|
|
mov cx, WPTR [_SI+4] ; cl:ch=Prim 3/4 R/I
|
|
|
|
cmp dh, cl
|
|
adc al, ah
|
|
add al, ch
|
|
stosb
|
|
|
|
WRAP_BP_PAT?? <V256_ByteLoop>
|
|
|
|
V256_InvDensity:
|
|
cmp cl, ch
|
|
jz short AllDone
|
|
|
|
inc _DI
|
|
WRAP_BP_PAT?? <V256_ByteLoop>
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
|
|
|
|
SUBTTL VarCountOutputToVGA256
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination plane.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
01-Jun-1992 Mon 15:32:00 updated -by- Daniel Chou (danielc)
|
|
1. Fixed so that Prims match the device's BGR color table format rather
|
|
than RGB format
|
|
|
|
19-Mar-1993 Fri 18:53:56 updated -by- Daniel Chou (danielc)
|
|
1. When we push _SI and jmp to VGA256_InvDensity we fogot to that
|
|
si now is run as count rather than _CX
|
|
|
|
`
|
|
|
|
@BEG_PROC VarCountOutputToVGA256 <pPrimColorCount:DWORD, \
|
|
pDest:DWORD, \
|
|
pPattern:DWORD, \
|
|
OutFuncInfo:QWORD>
|
|
|
|
|
|
;==========================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pPrimColorCount
|
|
; _DI : pDest
|
|
; _BP : Current pPattern, self wrappable
|
|
; cx : PrimColorCount.Count
|
|
; bl:bh:dl:dh : Prim 1/2/3/4 ====> R/G/B/IDX
|
|
; al : DestByte
|
|
; ah : Scratch Register
|
|
;==========================================
|
|
;
|
|
|
|
@ENTER_PAT_TO_STK <VGA256> ; _BP=Pat location
|
|
|
|
;============================================================================
|
|
; Since we are in byte boundary, we should never have an invalid density to
|
|
; start with
|
|
;
|
|
; The VGA256's color table is constructed as BGR and 6 steps for each primary
|
|
; color.
|
|
;============================================================================
|
|
|
|
cld ; clear direction
|
|
|
|
IFE ExtRegSet
|
|
mov _BX, _SP ; the table on the stack
|
|
ELSE
|
|
mov _BX, _AX ; _AX point to xlate table
|
|
ENDIF
|
|
or _AX, _AX
|
|
jnz SHORT V256_XlateStart
|
|
jmp V256_NoXlate
|
|
|
|
|
|
;======== THIS PORTION is for xlate table
|
|
|
|
V256_XlateByteLoop:
|
|
pop _SI ; restore SI
|
|
|
|
V256_XlateStart:
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
push _SI ; save again
|
|
|
|
mov cx, WPTR [_SI+2] ; cl:ch=Prim 1/2 B/G
|
|
cmp cl, PRIM_INVALID_DENSITY ; invalid?
|
|
jz short V256_XlateInvDensity
|
|
|
|
mov dx, WPTR [_SI+4] ; dl:dh=Prim 3/4 R/I
|
|
mov si, WPTR [_SI] ; count
|
|
inc si
|
|
|
|
V256_XlateCountLoop:
|
|
|
|
dec si
|
|
jz short V256_XlateByteLoop
|
|
|
|
dec _BP
|
|
mov ah, BPTR [_BP] ; ah=Pattern
|
|
dec ah ; make cmp ah, bl works
|
|
|
|
cmp ah, cl
|
|
sbb al, al
|
|
and al, VGA256_B_CUBE_INC ; AL=0 or 36 Prim1
|
|
|
|
cmp ah, dl ; Do Prim 3 first
|
|
adc al, dh ; al=InitValue+Prim1+Prim3
|
|
|
|
cmp ah, ch ; do Prim 2 now
|
|
sbb ah, ah
|
|
and ah, VGA256_G_CUBE_INC
|
|
add al, ah
|
|
|
|
;
|
|
; for extended register set _BX point to the translation table
|
|
; otherwise ss:bx point to the translation table
|
|
;
|
|
|
|
IFE ExtRegSet
|
|
xlat _SS:VGA256_SSSP_XLAT_TABLE
|
|
ELSE
|
|
xlatb
|
|
ENDIF
|
|
|
|
stosb
|
|
|
|
V256_XlateReadyNextByte:
|
|
|
|
WRAP_BP_PAT?? <V256_XlateCountLoop>
|
|
|
|
|
|
V256_XlateInvDensity:
|
|
cmp cl, ch ; all done?
|
|
jz SHORT V256_XlateAllDone
|
|
dec _BP
|
|
inc _DI
|
|
|
|
MOVZX_W _CX, <WPTR [_SI]>
|
|
mov _SI, _CX ; we expect count in si
|
|
cmp _CX, 1
|
|
jbe short V256_XlateReadyNextByte
|
|
|
|
;=========
|
|
|
|
dec _CX
|
|
mov _AX, _CX
|
|
add _DI, _CX ; 1 pel per byte
|
|
mov _CX, _BP ; align pattern now
|
|
and _CX, HTPAT_STK_MASK ; how many pat avai.?
|
|
xor _BP, _CX ; clear _BP mask=pPattern
|
|
sub _CX, _AX ; see if > 0? (_AX=Count)
|
|
jg short V256_XlateDoneSkipPels ; still not used up yet!
|
|
mov _AX, [_BP - HTPAT_BP_SIZE] ; get pattern size
|
|
V256_XlateSkipLoop:
|
|
add _CX, _AX
|
|
jle short V256_XlateSkipLoop ; do until > 0
|
|
V256_XlateDoneSkipPels:
|
|
add _BP, _CX ; _BP=pCurPat
|
|
jmp V256_XlateByteLoop ; repeat the process
|
|
|
|
V256_XlateAllDone:
|
|
pop _SI ; restore last _SI
|
|
|
|
IFE ExtRegSet
|
|
add _SP, VGA256_XLATE_TABLE_SIZE
|
|
ENDIF
|
|
|
|
;======================================================================
|
|
|
|
AllDone:
|
|
@EXIT_PAT_STK_RESTORE
|
|
|
|
;======================================================================
|
|
|
|
|
|
V256_NoXlate:
|
|
|
|
V256_ByteLoop:
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov cx, WPTR [_SI] ; cx=count
|
|
mov bx, WPTR [_SI+2] ; bl:bh=Prim 1/2 B/G
|
|
cmp bl, PRIM_INVALID_DENSITY ; invalid?
|
|
jz short V256_InvDensity
|
|
|
|
mov dx, WPTR [_SI+4] ; dl:dh=Prim 3/4 R/I
|
|
|
|
inc cx
|
|
|
|
V256_CountLoop:
|
|
|
|
dec cx
|
|
jz short V256_ByteLoop
|
|
|
|
dec _BP
|
|
mov ah, BPTR [_BP] ; ah=Pattern
|
|
dec ah ; make cmp ah, bl works
|
|
|
|
cmp ah, bl
|
|
sbb al, al
|
|
and al, VGA256_B_CUBE_INC ; AL=0 or 36 Prim1
|
|
|
|
cmp ah, dl ; Do Prim 3 first
|
|
adc al, dh ; al=InitValue+Prim1+Prim3
|
|
|
|
cmp ah, bh ; do Prim 2 now
|
|
sbb ah, ah
|
|
and ah, VGA256_G_CUBE_INC
|
|
add al, ah
|
|
stosb
|
|
|
|
ReadyNextByte:
|
|
|
|
WRAP_BP_PAT?? <V256_CountLoop>
|
|
|
|
|
|
V256_InvDensity:
|
|
cmp bl, bh ; all done?
|
|
jz short AllDone
|
|
dec _BP
|
|
inc _DI
|
|
cmp cx, 1
|
|
jbe short ReadyNextByte
|
|
|
|
SkipDestPels:
|
|
dec cx
|
|
WZXE cx ; zero extended
|
|
mov _AX, _CX
|
|
add _DI, _CX ; 1 pel per byte
|
|
mov _CX, _BP ; align pattern now
|
|
and _CX, HTPAT_STK_MASK ; how many pat avai.?
|
|
xor _BP, _CX ; clear _BP mask=pPattern
|
|
sub _CX, _AX ; see if > 0? (_AX=Count)
|
|
jg short DoneSkipDestPels ; still not used up yet!
|
|
mov _AX, [_BP - HTPAT_BP_SIZE] ; get pattern size
|
|
SkipDestPelsLoop:
|
|
add _CX, _AX
|
|
jle short SkipDestPelsLoop ; do until > 0
|
|
DoneSkipDestPels:
|
|
add _BP, _CX ; _BP=pCurPat
|
|
jmp V256_ByteLoop ; repeat the process
|
|
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
|
|
SUBTTL SingleCountOutputTo16BPP_555
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_16BPP_555 destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination planes pointers.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
01-Jun-1992 Mon 15:32:00 updated -by- Daniel Chou (danielc)
|
|
1. Fixed so that Prims match the device's BGR color table format rather
|
|
than RGB format
|
|
|
|
|
|
`
|
|
|
|
@BEG_PROC SingleCountOutputTo16BPP_555 <pPrimColorCount:DWORD, \
|
|
pDest:DWORD, \
|
|
pPattern:DWORD, \
|
|
OutFuncInfo:QWORD>
|
|
|
|
|
|
;==========================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pPrimColorCount
|
|
; _DI : pDest
|
|
; _BP : Current pPattern, self wrappable
|
|
; ax : Initial RGB color range from 0-32k (15 bits as 5:5:5)
|
|
; dh : pattern
|
|
; bl:bh:dl : Prim1/2/3
|
|
; ch : PRIM_INVALID_DENSITY
|
|
; cl : PRIM_INVALID_DENSITY --> CX = PRIMCOUNT_EOF
|
|
;--------------------------------------------------------------------
|
|
;
|
|
|
|
@ENTER_PAT_TO_STK <16BPP> ; _BP=Pat location
|
|
|
|
;============================================================================
|
|
; Since we are in WORD boundary, we should never have an invalid density to
|
|
; start with
|
|
;
|
|
; The 16BPP_555's color table is constructed as 32 steps for each primary color
|
|
;============================================================================
|
|
|
|
cld ; clear direction
|
|
mov cx, (RGB555_R_CUBE_INC or RGB555_G_CUBE_INC)
|
|
|
|
WordLoop:
|
|
dec _BP ; do this one first
|
|
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
mov bx, WPTR [_SI+2] ; bl:bh=Prim 1/2
|
|
cmp bl, PRIM_INVALID_DENSITY ; invalid?
|
|
jz short InvalidDensity
|
|
|
|
mov dh, BPTR [_BP] ; dh=pattern
|
|
dec dh ; make 'cmp dh, bl' works
|
|
|
|
cmp dh, bl
|
|
sbb ah, ah ; ah=0x00 or 0x04
|
|
cmp dh, bh
|
|
sbb al, al ; al=0x00 or 0x20 ax=0x420
|
|
and ax, cx ; mask with cx= 0x0420
|
|
|
|
cmp dh, BPTR [_SI+4]
|
|
adc ax, WPTR [_SI+6] ; ax+carry+initial index
|
|
|
|
stosw
|
|
|
|
WRAP_BP_PAT?? <WordLoop>
|
|
|
|
InvalidDensity:
|
|
cmp bl, bh
|
|
jz short AllDone
|
|
|
|
inc _DI
|
|
WRAP_BP_PAT?? <WordLoop>
|
|
|
|
AllDone:
|
|
@EXIT_PAT_STK_RESTORE
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
|
|
|
|
SUBTTL VarCountOutputTo16BPP_555
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
Routine Description:
|
|
|
|
This function output to the BMF_4BPP destination surface from
|
|
PRIMCOLOR_COUNT data structure array.
|
|
|
|
Arguments:
|
|
|
|
pPrimColorCount - Pointer to the PRIMCOLOR_COUNT data structure array.
|
|
|
|
pDest - Pointer to the destination plane.
|
|
|
|
pPattern - Pointer to the starting pattern byte for the current
|
|
destination scan line.
|
|
|
|
OutFuncInfo - OUTFUNCINFO data structure.
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
01-Jun-1992 Mon 15:32:00 updated -by- Daniel Chou (danielc)
|
|
1. Fixed so that Prims match the device's BGR color table format rather
|
|
than RGB format
|
|
|
|
|
|
`
|
|
|
|
@BEG_PROC VarCountOutputTo16BPP_555 <pPrimColorCount:DWORD, \
|
|
pDest:DWORD, \
|
|
pPattern:DWORD, \
|
|
OutFuncInfo:QWORD>
|
|
|
|
|
|
;==========================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pPrimColorCount, si=Temp Init Index
|
|
; _DI : pDest
|
|
; _BP : Current pPattern, self wrappable
|
|
; ax : Initial RGB color range from 0-32k (15 bits as 5:5:5)
|
|
; dh : pattern
|
|
; bl:bh:dl : Prim1/2/3
|
|
; cx : PrimColorCount.Count
|
|
;==========================================
|
|
;
|
|
|
|
@ENTER_PAT_TO_STK <16BPP> ; _BP=Pat location
|
|
|
|
;============================================================================
|
|
; Since we are in byte boundary, we should never have an invalid density to
|
|
; start with
|
|
;
|
|
; The 16BPP_555's color table is constructed as BGR and 6 steps for each
|
|
; primary color.
|
|
;============================================================================
|
|
|
|
cld ; clear direction
|
|
jmp short InitStart
|
|
|
|
WordLoop:
|
|
pop _SI ; restore _SI
|
|
InitStart:
|
|
add _SI, SIZE_PCC ; sizeof(PRIMCOLOR_COUNT)
|
|
push _SI ; save _SI
|
|
|
|
mov cx, WPTR [_SI] ; cx=count
|
|
mov bx, WPTR [_SI+2] ; bx=Prim 1/2/3
|
|
|
|
cmp bl, PRIM_INVALID_DENSITY ; invalid?
|
|
jz short InvalidDensity
|
|
|
|
mov dx, WPTR [_SI+4] ; dl:dh=Prim 3/4
|
|
mov si, WPTR [_SI+6] ; si=initial index
|
|
|
|
inc cx ; pre-enter
|
|
|
|
CountLoop:
|
|
dec cx
|
|
jz SHORT WordLoop
|
|
|
|
dec _BP
|
|
mov dh, BPTR [_BP] ; bl=pattern
|
|
dec dh ; make cmp bl, dh works
|
|
|
|
cmp dh, bl
|
|
sbb ah, ah ; ah=0/0x40
|
|
cmp dh, bh
|
|
sbb al, al
|
|
and ax, (RGB555_R_CUBE_INC or RGB555_G_CUBE_INC) ; mask=0x420
|
|
cmp dh, dl
|
|
adc ax, si ; carry+ax+initial index
|
|
|
|
stosw
|
|
|
|
ReadyNextByte:
|
|
|
|
WRAP_BP_PAT?? <CountLoop>
|
|
|
|
InvalidDensity:
|
|
cmp bl, bh ; all done?
|
|
jz short AllDone
|
|
dec _BP
|
|
add _DI, 2 ; 16-bit per pel
|
|
cmp cx, 1
|
|
jbe SHORT ReadyNextByte
|
|
|
|
SkipDestPels:
|
|
dec cx
|
|
WZXE cx ; zero extended
|
|
mov _AX, _CX
|
|
add _DI, _CX ; 16-bit per pel
|
|
add _DI, _CX ;
|
|
mov _CX, _BP ; align pattern now
|
|
and _CX, HTPAT_STK_MASK ; how many pat avai.?
|
|
xor _BP, _CX ; clear _BP mask=pPattern
|
|
sub _CX, _AX ; see if > 0? (_AX=Count)
|
|
jg short DoneSkipDestPels ; still not used up yet!
|
|
mov _AX, [_BP - HTPAT_BP_SIZE] ; get pattern size
|
|
SkipDestPelsLoop:
|
|
add _CX, _AX
|
|
jle short SkipDestPelsLoop ; do until > 0
|
|
DoneSkipDestPels:
|
|
add _BP, _CX ; _BP=pCurPat
|
|
jmp WordLoop ; repeat the process,
|
|
|
|
AllDone:
|
|
pop _SI ; restore _SI
|
|
@EXIT_PAT_STK_RESTORE
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
SUBTTL MakeHalftoneBrush
|
|
PAGE
|
|
|
|
COMMENT `
|
|
|
|
Routine Description:
|
|
|
|
This function generate a halftone brush on the output buffer
|
|
|
|
Arguments:
|
|
|
|
pThresholds - Pointer to a byte array for the halftone thresholds array
|
|
|
|
pOutputBuffer - Pointer to the output buffer
|
|
|
|
PrimColor - a PRIMCOLOR data structure
|
|
|
|
HTBrushData - a HTBRUSHDATA data structure.
|
|
|
|
|
|
Return Value:
|
|
|
|
No return value.
|
|
|
|
Author:
|
|
|
|
30-Aug-1992 Sun 14:19:45 updated -by- Daniel Chou (danielc)
|
|
1. Fixes 'rol' to 'ror' in 16bpp555 format
|
|
2. fixes trash 'cl' cxHTCell in 1/4/8 bpp format
|
|
|
|
24-Jan-1991 Thu 11:47:08 created -by- Daniel Chou (danielc)
|
|
|
|
|
|
Revision History:
|
|
|
|
`
|
|
|
|
|
|
@BEG_PROC MakeHalftoneBrush <pThresholds:DWORD, \
|
|
pOutputBuffer:DWORD, \
|
|
PCC:QWORD, \
|
|
HTBrushData:QWORD>
|
|
|
|
;----------------------
|
|
; Register Usage:
|
|
;
|
|
; _SI : Thresholds
|
|
; _DI : Output Buffer
|
|
; _BP ; Bytes to next scan line
|
|
; cl : cx cell count
|
|
; ch : cy cell count
|
|
; bl:bh:dl:dh:al:ah ; Prim1/2/3/4/5/6
|
|
|
|
|
|
|
|
@ENTER _DS _SI _DI _BP
|
|
|
|
mov cl, HTBrushData.cxHTCell
|
|
mov ch, HTBrushData.cyHTCell
|
|
MOVZX_W _BX, <WPTR PCC.PCC_Prim1>
|
|
MOVZX_W _DX, <WPTR PCC.PCC_Prim3>
|
|
MOVZX_W _AX, <WPTR PCC.PCC_Prim5>
|
|
LDS_SI pThresholds
|
|
LES_DI pOutputBuffer
|
|
cld ; clear the forward DIR
|
|
|
|
push _AX ; Save PCC_Prim5/6
|
|
mov al, HTBrushData.SurfaceFormat ; al=SurfaceFormat
|
|
|
|
JmpFunc3Planes:
|
|
cmp al, BMF_1BPP_3PLANES
|
|
jnz SHORT JmpFunc1BPP
|
|
pop _AX
|
|
jmp BrushFunc3Planes
|
|
|
|
JmpFunc1BPP:
|
|
MOVSX_W _BP, <WPTR HTBrushData.ScanLinePadBytes> ; BP=ScanPadByte
|
|
|
|
cmp al, BMF_1BPP
|
|
jnz SHORT JmpFunc4BPP
|
|
pop _AX ; Restore Prim5/6
|
|
jmp BrushFunc1BPP
|
|
|
|
JmpFunc4BPP:
|
|
cmp al, BMF_4BPP
|
|
jnz SHORT JmpFuncVGA16
|
|
pop _AX ; Restore Prim5/6
|
|
jmp BrushFunc4BPP
|
|
|
|
JmpFuncVGA16:
|
|
cmp al, BMF_4BPP_VGA16
|
|
jnz SHORT JmpFuncVGA256
|
|
pop _AX ; Restore Prim5/6
|
|
jmp BrushFuncVGA16
|
|
|
|
JmpFuncVGA256:
|
|
cmp al, BMF_8BPP_VGA256
|
|
pop _AX ; Restore Prim5/6
|
|
jz SHORT BrushFuncVGA256
|
|
jmp SHORT BrushFunc16BPP_555
|
|
|
|
;=================================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pThresholds
|
|
; _DI : pOutputBuffer
|
|
; _BP ; ScanLinePadBytes
|
|
; cl : cx cell count
|
|
; ch : cy cell count
|
|
; bl:bh:dl:dh:al:ah ; Prim1/2/3/4/5/6 Initial Index
|
|
;============================================================================
|
|
;============================================================================
|
|
; VGA256 colors
|
|
;
|
|
; _SI : pThreshold
|
|
; _DI : pOutputBuffer
|
|
; _BP : Bytes To next scan line
|
|
; cl : cx cell count
|
|
; ch : cy cell count
|
|
; bl:bh:dl:dh ; Prim1/2/3 ---> B:G:R:InitValue
|
|
; al ; current Byte
|
|
; ah : Working register
|
|
;
|
|
;============================================================================
|
|
|
|
BrushFuncVGA256:
|
|
|
|
B8_yLoop:
|
|
cld
|
|
push _CX ; save cx/cy count
|
|
B8_xLoop:
|
|
mov ch, BPTR[_SI]
|
|
dec ch
|
|
inc _SI
|
|
; ah=0xff if need to increment
|
|
cmp ch, bl ; and will be mask by 36
|
|
sbb ah, ah
|
|
cmp ch, bh ; al=0xff if need to increment
|
|
sbb al, al ; and will be mask by 6
|
|
and ax, ((VGA256_B_CUBE_INC shl 8) or VGA256_G_CUBE_INC)
|
|
cmp ch, dl
|
|
adc al, ah
|
|
add al, dh ; add in the initial value
|
|
stosb ; save it
|
|
|
|
dec cl
|
|
jnz SHORT B8_xLoop
|
|
|
|
B8_xLoppEnd:
|
|
pop _CX
|
|
add _DI, _BP
|
|
dec ch
|
|
jnz SHORT B8_yLoop
|
|
|
|
;============================================================================
|
|
; EXIT HERE
|
|
;============================================================================
|
|
|
|
AllDone: @EXIT
|
|
|
|
|
|
;=================================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pThresholds
|
|
; _DI : pOutputBuffer
|
|
; _BP ; ScanLinePadBytes
|
|
; cl : cx cell count
|
|
; ch : cy cell count
|
|
; bl:bh:dl:dh:al:ah ; Prim1/2/3/3/4/5/6 Initial Index
|
|
;============================================================================
|
|
; 16BPP_555 colors
|
|
;
|
|
; _SI : pThreshold
|
|
; _DI : pOutputBuffer
|
|
; bp : Initial color Index number
|
|
; cl : cx cell count
|
|
; ch : cy cell count
|
|
; bl:bh:dl ; Prim1/2/3/4/5/6
|
|
; dh : BytesToNextScanLine (0/1)
|
|
; ax : Working register
|
|
;
|
|
;============================================================================
|
|
|
|
BrushFunc16BPP_555:
|
|
|
|
|
|
B16_yLoop:
|
|
xchg _AX, _BP ; bp=Init index, al=ScanLinePad
|
|
mov dh, al ; dh=PadBytes
|
|
|
|
push _CX
|
|
|
|
B16_xLoop:
|
|
mov ch, BPTR[_SI] ; ch=pattern
|
|
dec ch ; make Prim >= Threshold works
|
|
inc _SI
|
|
|
|
cmp ch, bl
|
|
sbb ah, ah ; ah=RIndex 0/1024 = 0x00:0x04
|
|
cmp ch, bh ; al=GIndex 0/32 = 0x00:0x20
|
|
sbb al, al
|
|
and ax, (RGB555_R_CUBE_INC or RGB555_G_CUBE_INC) ; mask=0x420
|
|
|
|
cmp ch, dl
|
|
adc ax, bp ; BIndex carry+initial index
|
|
|
|
stosw
|
|
|
|
dec cl
|
|
jnz SHORT B16_xLoop
|
|
|
|
B16_xLoppEnd:
|
|
pop _CX
|
|
|
|
BZXEAX dh ; dh=BytesToNextScan
|
|
add _DI, _AX
|
|
dec ch
|
|
jnz SHORT B16_yLoop
|
|
jmp AllDone
|
|
|
|
|
|
;=================================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : Thresholds
|
|
; _DI : Output Buffer
|
|
; _BP ; Stack Frame
|
|
; cl : cx cell count
|
|
; ch : cy cell count
|
|
; bl:bh:dl:dh:al:ah ; Prim1/2/3/4/5/6
|
|
;----------------------
|
|
; 3 Planes registers usage
|
|
;
|
|
; dh : cx Cell Count
|
|
; bl:bh:dl : Prim1/2/3/4
|
|
; cl:ch:al : current byte
|
|
; ah : Threshold
|
|
;
|
|
|
|
BrushFunc3Planes:
|
|
|
|
B3P_yLoop:
|
|
mov dh, HTBrushData.cxHTCell
|
|
|
|
B3P_xLoop:
|
|
xor cx, cx
|
|
mov al, 1 ; this is the BYTE indicator
|
|
B3P_DoByte:
|
|
mov ah, BPTR[_SI]
|
|
dec ah ; if (Prim >= T) Dest |= 0x01
|
|
inc _SI
|
|
cmp ah, bl
|
|
adc cl, cl
|
|
|
|
cmp ah, bh
|
|
adc ch, ch
|
|
|
|
cmp ah, dl
|
|
adc al, al
|
|
|
|
jc short B3P_DoneOneByte
|
|
dec dh
|
|
jnz short B3P_DoByte
|
|
|
|
B3P_ShiftByte:
|
|
add cx, cx
|
|
add al, al
|
|
jnc short B3P_ShiftByte ; shift until byte aligned
|
|
|
|
B3P_DoneOneByte:
|
|
mov BPTR_ES[_DI], cl
|
|
mov ah, ch
|
|
MOVZX_W _CX, HTBrushData.SizePerPlane
|
|
add _DI, _CX
|
|
mov BPTR_ES[_DI], ah
|
|
add _DI, _CX
|
|
stosb
|
|
sub _DI, _CX
|
|
sub _DI, _CX
|
|
|
|
dec dh
|
|
jnz short B3P_xLoop
|
|
|
|
MOVSX_W _CX, HTBrushData.ScanLinePadBytes
|
|
add _DI, _CX
|
|
dec BPTR HTBrushData.cyHTCell
|
|
jnz short B3P_yLoop
|
|
jmp AllDone
|
|
|
|
|
|
;=================================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pThresholds
|
|
; _DI : pOutputBuffer
|
|
; _BP ; ScanLinePadBytes
|
|
; cl : cx cell count
|
|
; ch : cy cell count
|
|
; bl:bh:dl:dh:al:ah ; Prim1/2/3/4/5/6 Index
|
|
;============================================================================
|
|
; 1BPP register usage
|
|
;
|
|
; _SI - pThresholds
|
|
; _DI - pOutputBuffer
|
|
; _BP - Bytes to next scan line
|
|
; al - Dest byte
|
|
; bl - Prim1
|
|
; bh - xLoop
|
|
; ch - cy
|
|
; cl - Total bits not finished in one byte
|
|
; dh - NOT USED
|
|
; dl - cx
|
|
|
|
BrushFunc1BPP:
|
|
mov dl, cl ; dl=cx
|
|
|
|
B1_yLoop:
|
|
mov bh, dl ; bh=xLoop
|
|
|
|
B1_xLoop0:
|
|
xor al, al ; bDest = 0
|
|
mov cl, 8 ; LeftShift = 8
|
|
|
|
B1_xLoop1:
|
|
cmp bl, BPTR[_SI] ; Prim1 >= *pThresholds
|
|
adc al, al ; Dest = (Dest << 1) | Bit
|
|
inc _SI ; ++pThresholds
|
|
|
|
dec bh ; done xLoop yet?
|
|
jz SHORT B1_xLoopEnd ; yes
|
|
|
|
dec cl ; done 1 bit
|
|
jnz SHORT B1_xLoop1 ; repeat xLoop
|
|
|
|
B1_xLoopByte:
|
|
not al ; save one byte
|
|
stosb
|
|
jmp SHORT B1_xLoop0 ; repeat for unfinished xLoop
|
|
|
|
B1_xLoopEnd:
|
|
dec cl ; reduced one at end
|
|
not al ; carry when (prim1 < *pThresholds)
|
|
shl al, cl ; bDest <<= LeftShift
|
|
stosb ; *pbDest++ = bDest
|
|
|
|
B1_yLoopEnd:
|
|
add _DI, _BP ; next Destination
|
|
dec ch ; --yLoop == 0 ?
|
|
jnz SHORT B1_yLoop
|
|
jmp AllDone
|
|
|
|
|
|
;=================================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pThresholds
|
|
; _DI : pOutputBuffer
|
|
; _BP ; ScanLinePadBytes
|
|
; cl : cx cell count
|
|
; ch : cy cell count
|
|
; bl:bh:dl:dh:al:ah ; Prim1/2/3/4/5/6
|
|
;============================================================================
|
|
; 4BPP registers usage:
|
|
;
|
|
; _SI : Thresholds
|
|
; _DI : Output Buffer
|
|
; _BP ; Bytes to next scan line
|
|
; cl : cx cell count
|
|
; ch : cy cell count
|
|
; bl:bh:dl:dh ; Prim1/2/3/4
|
|
; al : current byte
|
|
; ah : 0x77 bits fliper
|
|
|
|
BrushFunc4BPP:
|
|
mov ah, 77h ; flip these bits later
|
|
|
|
B4_yLoop:
|
|
push _CX ; save cx/cy
|
|
|
|
B4_xLoop:
|
|
xor al, al ; clear destination byte
|
|
|
|
mov ch, BPTR[_SI]
|
|
inc _SI
|
|
|
|
cmp bl, ch
|
|
adc al, al
|
|
|
|
cmp bh, ch
|
|
adc al, al
|
|
|
|
cmp dl, ch
|
|
adc al, al
|
|
|
|
dec cl
|
|
jz SHORT B4_DoLowNibble ; shift it left 4 bits
|
|
|
|
mov ch, BPTR[_SI]
|
|
inc _SI
|
|
dec cl
|
|
|
|
B4_DoLowNibble:
|
|
add al, al ; shift bit 3
|
|
|
|
cmp bl, ch
|
|
adc al, al
|
|
|
|
cmp bh, ch
|
|
adc al, al
|
|
|
|
cmp dl, ch
|
|
adc al, al
|
|
|
|
B4_Done1Byte: ; flip the bits because
|
|
xor al, ah ; bit=1 if (Prim < *pThresholds)
|
|
stosb
|
|
or cl, cl
|
|
jnz SHORT B4_xLoop
|
|
|
|
B4_xLoopEnd:
|
|
pop _CX ; restore cx/cy
|
|
add _DI, _BP ; next destination
|
|
|
|
dec ch
|
|
jnz short B4_yLoop
|
|
jmp AllDone
|
|
|
|
|
|
|
|
;=================================================
|
|
; Register Usage:
|
|
;
|
|
; _SI : pThresholds
|
|
; _DI : Output Buffer
|
|
; _BP ; Bytes to next scan line
|
|
; cl : cx cell count
|
|
; ch : cy cell count
|
|
; bl:bh:dl:dh:al:ah ; Prim1/2/3/4/5/6
|
|
;----------------------
|
|
; VGA16
|
|
;
|
|
; _SI : pThresholds
|
|
; _DI : pDest
|
|
; _BP : Bytes to Next scan line
|
|
; cl : cx cell
|
|
; ch : cy cell
|
|
; bl:bh:dl:dh:al:ah : Prim 1/2/3/4/5/6
|
|
;==================================================================
|
|
; NOTE:
|
|
;
|
|
; Because when we making the brushes, we did not invert the thresholds
|
|
; for the pattern, but just invert the Prim colors, so we must making
|
|
; the color comparsion in other way around, from (PrimColor < Pattern) to
|
|
; (PrimColor >= Pattern) [ie. PrimColor > (Pattern - 1)] to set the carry
|
|
; bit
|
|
;
|
|
; Prim1 = Initial VGA16ColorIndex[]
|
|
; Prim2 = Color Thresholds for VGA16ColorIndex[Prim1]
|
|
; Prim3 = Color Thresholds for VGA16ColorIndex[Prim1-1]
|
|
; Prim4 = Color Thresholds for VGA16ColorIndex[Prim1-2]
|
|
; Prim5 = Color Thresholds for VGA16ColorIndex[Prim1-3]
|
|
; Prim6 = Color Thresholds for VGA16ColorIndex[Prim1-4]
|
|
; ELSE VGA16ColorIndex[Prim1-5]
|
|
;=========================================================================
|
|
|
|
BrushFuncVGA16:
|
|
|
|
VGA16_yLoop:
|
|
push _CX ; save cx/cy
|
|
push _BP ; save BP
|
|
mov _BP, _BX ; save bx here
|
|
|
|
VGA16_xLoopH:
|
|
mov _BX, _BP ; get bx again
|
|
|
|
mov ch, BPTR[_SI]
|
|
inc _SI
|
|
|
|
;
|
|
; 1 2 3 4 5
|
|
; bh:dl:dh:al:ah
|
|
;----------------------
|
|
|
|
cmp dh, ch
|
|
jae SHORT GetH1
|
|
cmp al, ch
|
|
sbb bl, 3
|
|
cmp ah, ch
|
|
jmp SHORT GetH2
|
|
|
|
GetH1: cmp bh, ch
|
|
jae SHORT GetHNibble
|
|
dec bl
|
|
cmp dl, ch
|
|
|
|
GetH2: sbb bl, 0
|
|
|
|
GetHNibble:
|
|
BZXE bl
|
|
mov bl, BPTR cs:VGA16ColorIndex[_BX]
|
|
and bl, 0f0h
|
|
mov BPTR_ES[_DI], bl
|
|
|
|
dec cl
|
|
jz SHORT VGA16_Done1Byte ; done
|
|
|
|
VGA16_xLoopL:
|
|
mov _BX, _BP ; get the bx again
|
|
|
|
mov ch, BPTR[_SI]
|
|
inc _SI
|
|
|
|
;
|
|
; 1 2 3 4 5
|
|
; bh:dl:dh:al:ah
|
|
;----------------------
|
|
|
|
cmp dh, ch
|
|
jae SHORT GetL1
|
|
cmp al, ch
|
|
sbb bl, 3
|
|
cmp ah, ch
|
|
jmp SHORT GetL2
|
|
|
|
GetL1: cmp bh, ch
|
|
jae SHORT GetLNibble
|
|
dec bl
|
|
cmp dl, ch
|
|
|
|
GetL2: sbb bl, 0
|
|
|
|
GetLNibble:
|
|
BZXE bl
|
|
mov bl, BPTR cs:VGA16ColorIndex[_BX]
|
|
and bl, 0fh
|
|
or BPTR_ES[_DI], bl
|
|
dec cl
|
|
|
|
VGA16_Done1Byte:
|
|
inc _DI
|
|
or cl, cl
|
|
jnz SHORT VGA16_xLoopH
|
|
|
|
VGA16_xLoopEnd:
|
|
mov _BX, _BP ; restore BX
|
|
pop _BP ; restore BP
|
|
pop _CX ; restore cx/cy
|
|
add _DI, _BP ; next destination
|
|
|
|
dec ch
|
|
jnz short VGA16_yLoop
|
|
jmp AllDone
|
|
|
|
|
|
@END_PROC
|
|
|
|
|
|
ENDIF ; HT_ASM_80x86
|
|
|
|
|
|
END
|