📄 llcgasup.asm
字号:
TITLE LLCGASUP - LowLevel CGA support (shared routines)
;***
; LLCGASUP - LowLevel CGA support
;
; Copyright <C> 1987, 1988, Microsoft Corporation
;
;Purpose:
; This module contains support routines extracted from LLCGA.ASM
; which are shared by CGA and VGA functions.
;
;******************************************************************************
INCLUDE switch.inc ;feature switches
INCLUDE rmacros.inc
USESEG _DATA
USESEG _BSS
USESEG GR_TEXT
INCLUDE seg.inc
INCLUDE ibmunv.inc
INCLUDE llgrp.inc
INCLUDE idmac.inc
sBegin _BSS
;
;
; ***************************************************************************
; External variables
; ***************************************************************************
;
externW B$LEOFST
externW B$REOFST
externB B$VLMASK
externB B$VRMASK
externD b$AddrC
externB b$AttrC
externB b$BitsPerPixel
externB b$DivShift
externB b$MaskC
externB b$MaskLeft
externB b$MaskRight
externW b$ModMask
externW b$OffC
externB b$PaintBorder
externW b$PenC
externW b$PixelsPerByte
externW b$SegC
;
; ***************************************************************************
; Global variables
; ***************************************************************************
;
globalW b$UpSub,,1 ;subtract to try to move up
globalW b$DnSub,,1 ;subtract to try to move down
globalW b$UpDnAdd,,1 ;add if wrong quadrant/half for subtractor
;
; ***************************************************************************
; External function vectors
; ***************************************************************************
;
externW b$PutVector
externW b$Incr1
externW b$Incr2
;
; ***************************************************************************
; Local variables
; ***************************************************************************
;
staticW SaveCa,,1
staticB SaveCm,,1
staticW PutVectorM,,1
sEnd _BSS
assumes CS,GR_TEXT
sBegin GR_TEXT
externNP B$BumpDS
externNP B$BumpES
externNP B$DecDS
;***
; B$CgaSetAttr
;
;Purpose:
; Replicate the 1 bit attribute for 1-bit-per-pixel modes throughout
; the attribute byte used by the graphics functions. If the supplied
; attribute is greater than 1, use 1.
;Entry:
; AL = attribute
;Exit:
; _bAttrC = 00 if AL was 0, else FF
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$CgaSetAttr,<PUBLIC,NEAR>,<AX>
cBegin
NEG AL ;set carry iff non-0
SBB AL,AL ;AL = (AL==0) ? 0 : -1
MOV b$AttrC,al
CLC ;exit no error
cEnd
;***
; B$CgaReadC
;
;Purpose:
; Return the attribute of the current pixel as specified by
; b$MaskC and b$OffC for CGA screen modes.
;Entry:
; b$MaskC, b$OffC specify pixel to read
;Exit:
; AL = attribute of specified pixel
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$CgaReadC,<PUBLIC,NEAR>,<ES>
cBegin
mov al,b$MaskC ;get cursor mask
les bx,b$AddrC ;get memory address of cursor
mov cl,b$BitsPerPixel
mov ah,es:[bx] ;current cell value
and ah,al ;mask out other pixels (using b$MaskC)
RdLoop: shr ax,cl ;shift right 1 pixel
jnc RdLoop ;loop till mask is right justified
shl ax,cl ;went once too far
mov al,ah ;return with attribute in [al]
cEnd
;***
; B$CgaSetC
;
;Purpose:
; Set the pixel defined by the current graphics cursor to
; the current attribute for CGA modes.
;Entry:
; b$PenC = cursor mask and attribute
; b$AddrC = address of pixel
;Exit:
; None
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$CgaSetC,<PUBLIC,NEAR>,<DS>
cBegin
mov cx,b$PenC ;[cl] = cursor mask, [ch] = attribute
lds bx,b$AddrC ;[BX] = cursor offset, [ES] = segment
xor ch,[bx] ;change masked bits of video byte
and ch,cl ; to color in attribute byte
xor [bx],ch
cEnd
;***
; B$CgaSetPixC
;
;Purpose:
; Set the pixel defined by the current graphics cursor to
; the current attribute for CGA modes. This is identical to
; B$CgaSetC except that this routine assumes ES is set to
; video segment.
;Entry:
; ES = video segment (set up by B$CgaSetPixFirstC)
; b$PenC = cursor mask and attribute
; b$OffC = address of pixel
;Exit:
; None
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$CgaSetPixC,<PUBLIC,NEAR>
cBegin
mov cx,b$PenC ;[cl] = cursor mask, [ch] = attribute
mov bx,b$OffC ;[BX] = cursor offset
;[ES] = setup by SetPixFirstC
xor ch,es:[bx] ;change masked bits of video byte
and ch,cl ; to color in attribute byte
xor es:[bx],ch
cEnd
;***
; B$CgaSetPixFirstC/B$CgaSetPixLastC
;
;Purpose:
; Set up ES to the video segment for CGA modes (FirstC).
; LastC just returns as nothing needs to be done here for CGA modes.
;Entry:
; b$SegC = video segment
;Exit:
; ES set to video segment
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$CgaSetPixFirstC,<PUBLIC,NEAR>
cBegin
mov es,b$SegC ;ES = video segment for b$SetPixC
labelNP <PUBLIC,B$CgaSetPixLastC>
cEnd
labelW PutTable ;Put Vectors according to put action value
DW PutOr, PutAnd, PutPreset, PutPset, PutXor
labelW PutTableM ;Put Vectors for "Middle" (full mask) PUTs
DW PutOrM, PutAndM, PutPresetM, PutPsetM, PutXorM
;***
; B$CgaPutAction
;
;Purpose:
; Set b$PutVector to appropriate PUT action routine for CGA modes.
; Requested action is used to index into a table of entry points.
;Entry:
; AL = PUT action [0..4] representing (OR, AND, PRESET, PSET, XOR)
;Exit:
; b$PutVector set to entry point of appropriate PUT action routine
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$CgaPutAction,<PUBLIC,NEAR>
cBegin
xor ah,ah ;make word index
shl ax,1
mov bx,ax
mov ax,cs:PutTable[BX] ;get our vector
mov b$PutVector,ax ;save it
mov ax,cs:PutTableM[BX] ;get our Middle vector
mov PutVectorM,ax ;save it
cEnd
;***
; PutAnd
;
;Purpose:
; Support routine for CGA PUT. Write to the specified screen byte
; the result of ANDing the given attribute with what was already
; in the screen byte.
;Entry:
; ES:DI = address of screen byte
; AH = attribute to AND, then write
; DH = pixel mask
;Exit:
; ES:DI = address of next screen byte
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc PutAnd,<NEAR>
cBegin
not dh ;NEGATE [DH] AND USE NEGATIVE LOGIC
or ah,dh ;MAKE NON-SIG BITS ONES
not dh ;RESTORE [DH]
and es:[di],ah ;AND WITH SCREEN
inc di
cEnd
;***
; PutOr
;
;Purpose:
; Support routine for CGA PUT. Write to the specified screen byte
; the result of ORing the given attribute with what was already
; in the screen byte.
;Entry:
; ES:DI = address of screen byte
; AH = attribute to OR, then write
; DH = pixel mask
;Exit:
; ES:DI = address of next screen byte
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc PutOr,<NEAR>
cBegin
and ah,dh ;ISOLATE SIG BITS
or es:[di],ah ;OR WITH SCREEN
inc di
cEnd
;***
; PutPreset/PutPset/PutXor
;
;Purpose:
; Support routine for CGA PUT. Write to the specified screen byte
; either the specified attribute unchanged (Pset), the one's complement
; of the specified attribute (Preset), or the result of XORing the
; specified attribute with what was already in the screen byte,
; depending on the entry point.
;Entry:
; ES:DI = address of screen byte
; AH = attribute to apply
; DH = pixel mask
;Exit:
; ES:DI = address of next screen byte
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc PutPreset,<NEAR>
cBegin
not ah ;NEGATE DATA FOR PRESET
labelNP PutPset
xor ah,es:[di] ;XOR DATA WITH EXISTING SCREEN BYTE
labelNP PutXor
and ah,dh ;ISOLATE SIG BITS
xor es:[di],ah ;XOR WITH SCREEN
inc di
cEnd
ASSUME DS:NOTHING
;***
; B$CgaNReadL
;
;Purpose:
; Read a line of pixels from the screen to an array for CGA modes.
;Entry:
; DS:SI = screen address
; ES:DI = array address
; CL = array align shift count
; CH = mask for last partial byte
; BP = count of bits (not pixels) to read
;Exit:
; ES:DI = updated to array byte past point filled
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$CgaNReadL,<PUBLIC,NEAR>
cBegin
mov ah,[si] ;preload hi byte
inc si
NRdLoop:
lodsb ;fill ax word with video bytes
mov bh,al ;this lo byte will become next hi byte
rol ax,cl ;align to array
sub bp,8 ;8 bits done
jbe NRdLast ;go if bit count exhausted
mov es:[di],ah ;save full byte
inc di
mov ah,bh ;move lo byte (BH) to hi byte (AH)
jnz NRdLoop ;loop if no offset overflow
call B$BumpES ;move array pointer over segment boundary
jmp short NRdLoop ;go do another
NRdLast:
and ah,ch ;strip unused bits from last byte
mov es:[di],ah ;save last byte
inc di
jnz NRdDone
call B$BumpES ;move array pointer over segment boundary
NRdDone:
cEnd
;***
; B$CgaNWriteL
;
;Purpose:
; Write a line of pixels from an array to the screen for CGA modes.
;Entry:
; ES:DI = screen address
; DS:SI = array address
; CL = array align shift count
; BP = count of bits (not pixels) to write
; DL = last partial byte mask
; DH = first partial byte mask
;Exit:
; DS:SI = updated to array byte past point used
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$CgaNWriteL,<PUBLIC,NEAR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -