📄 llega.asm
字号:
cmp bl,2 ;attributes 0 and 1 map directly
jb PalTrNxt ;go if so
add bl,2 ;attribute 2 maps to 4, 3 to 5
PalTrNxt:
push di
MOV DI,GR_TEXTOFFSET TransF ;translate to color pair
XOR AH,AH
SHL AL,1 ;word index
ADD DI,AX
MOV AX,CS:[DI] ;translate color AX to color pair AX
pop di
clc ;no error
cEnd
;***
; PalTrans_10_64K
;
;Purpose:
; Translate a user supplied attribute for Screen 9/64K to the
; corresponding hardware value after verifying that the attribute
; value and the color value are in the legal ranges.
; Attribute mapping: 0 --> 0
; 1 --> 1
; 2 --> 4
; 3 --> 5
;Entry:
; DX:AX = user supplied color value
; BL = user supplied attribute value
;Exit:
; PSW.C set if illegal value, reset if Ok
; DX:AX = unchanged (user supplied color value)
; BL = actual attribute value
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
DbPub PalTrans_10_64K
cProc PalTrans_10_64K,<NEAR>
cBegin
call B$EgaPalTrans ;check attribute and translate color
jc PalTrErr ;error return
cmp bl,2 ;attributes 0 and 1 map directly
jb PalTrExit ;go if so
add bl,2 ;attribute 2 maps to 4, 3 to 5
PalTrExit:
clc ;no error
ret
PalTrErr:
STC ;indicate error
cEnd
labelB AttrX
DB 0,3,0CH,0FH ;map to 0,3,C,F for odd/even
;***
; SetAttr_F_10_64K
;
;Purpose:
; Map attribute value to the value needed by odd/even mode functions.
; 0 --> 00
; 1 --> 03
; 2 --> 0C
; 3 --> 0F
; If supplied attribute is outside legal range, use maximum legal value.
;Entry:
; AL = attribute
;Exit:
; b$Attr updated
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
DbPub SetAttr_F_10_64K
cProc SetAttr_F_10_64K,<NEAR>,<AX,BX>
cBegin
cmp al,b$MaxAttr ;test against maximum attribute
jbe SetAttrXOk ;Brif legal
mov al,b$MaxAttr ;limit to max
SetAttrXOk:
mov bx,GR_TEXTOFFSET AttrX ;translate for odd/even mode
xlat cs:[bx]
mov b$AttrC,al
clc ;exit no error
cEnd
;***
; SetColor
;
;Purpose:
; Process the color statement for Bios modes 0Dh - 010h (BASIC Screen
; modes 7-10). Syntax for Screen 7-10 color statement is as follows:
;
; COLOR [foreground],[background]
;
; where "foreground" is the attribute to be used for the foreground
; and "background" is the color to be used for the background
;
; Any omitted parameter(s) indicate no change for that parameter.
;Entry:
; parameter list
; WORD 1 = flag 0 if param not present
; WORD 2 = parameter if WORD 1 <> 0, else second param flag
; etc.
;Exit:
; PSW.C set if error, reset if Ok.
; b$ForeColor is set to foreground attribute
; b$ForeMapped is set to foreground attribute mapped to internal value
;
;Uses
; per conv.
;Exceptions:
;*****************************************************************************
cProc SetColor,<NEAR>
cBegin
cCall B$GetParm ;AL=foreground parameter
mov bh,b$ForeColor ;use old values as default
mov bl,b$ForeMapped
jz GotFore ;go if none supplied
cmp b$MaxAttr,al ;check for valid range
jc SetColDun ;go if error
push ax ;save: unmapped attr [14]
push cx ; param count
push b$PenC ; b$AttrC
call [b$SetAttr] ;translate the attribute
mov bl,b$AttrC ;translated attr in BL
pop b$PenC
pop cx
pop ax ;restore unmapped attr
mov bh,al ;unmapped attr to BH
GotFore:
cCall B$GetParm ;AL=background parameter
jz NoBack ;go if none supplied
push bx ;preserve foreground info
xor bx,bx ;attribute 0 is background
cbw ;AX=color
cwd ;DX:AX=color
call [b$PalPut] ;set background
pop bx
jc SetColDun ;go if error
NoBack:
mov b$ForeColor,bh ;save foreground values
mov b$ForeMapped,bl
clc ;indicate no error
jcxz SetColDun ;if we got all params, thats true
stc ;otherwise set error
SetColDun:
cEnd
;***
; PIXLF3
;Purpose:
; Check for non-paint pixels left, odd/even EGA modes.
; Look through entire range of non-border pixels right to left
; to determine whether any will actually change color.
; Use AL as Color Don't Care mask.
;
; If using EGAINT10 interface, this routine must access the CDCReg
; and perform the associated color compare read with ints disabled,
; then reenable them to allow other processes to access the card
; before the next byte is checked. Since another process may have
; modified the graphics chip index reg as well as the data reg, we
; must send both index and data for each odd/even toggle.
;Entry:
; SI = byte address of rightmost byte in range
; BH = bit mask for leftmost byte
; BL = bit mask for rightmost byte
; DI = total number of whole bytes between first and last
; ES = video segment
;Exit:
; CL = 0 if no pixels found to change, non-zero if pixels to change
;Uses:
; per conv.
;Exceptions:
;****
DbPub PIXLF3
cProc PIXLF3,<NEAR>,<DX>
cBegin
MOV DX,GRPADD ;index port for graphics register
MOV AL,LOW CDCREG ;specify Color Don't Care
EGAINT10CLI ;disable ints if using EGAINT10
OUT DX,AL
INC DX
MOV AL,10101010B ;initially assume odd byte address
TEST SI,1
JNZ STMSKL ;if correct, set this mask
ROR AL,1 ;else rotate for other pair of planes
STMSKL:
OUT DX,AL ;set up for initial color compare
; read first byte
MOV CL,ES:[SI] ;bit pattern of first byte with 0's where
;color not paint attribute
AND CL,BL ;AND now produces difference if non-paint
;bit in significant position
XOR CL,BL ;for significant bits in our first byte (bit
;set in BH), then non-paint will be one
JNZ SETBTL ;found a bit to change
OR BH,BH ;see if only one byte
JZ NOSETL ;nothing to paint
OR DI,DI ;see if only a "last byte"
JZ LSBYT3
; Look at whole bytes within viewport range until non-paint color found.
LKPTL3:
DEC SI
ROR AL,1
OUT DX,AL ;set up opposite Don't Care planes each time
MOV CL,ES:[SI]
EGAINT10STI ;read is done, reenable ints if EGAINT10
NOT CL ;check if all bits set (all paint color)
OR CL,CL ;NOT does not affect flags
JNZ SETBTL
DEC DI
EGAINT10CLI ;disable ints for next OUTs (loop
; or fall through)
JNZ LKPTL3 ;keep looking until search of complete
;bytes is exhausted
; On last byte now, mask in BH.
LSBYT3:
DEC SI
ROR AL,1
OUT DX,AL ;last Don't Care
MOV CL,ES:[SI] ;do last compare
AND CL,BH ;significant bit = 0 if not paint color
XOR CL,BH ;if different, non-paint pixel(s) present
JNZ SETBTL
NOSETL:
XOR CL,CL ;no bits to set, so zero pixels-changed flag
SETBTL:
EGAINT10STI ;reenable ints at common exit
cEnd
;***
; PIXRT3
;Purpose:
; Check for non-paint pixels right with odd/even EGA modes.
; Look through entire range of non-border pixels left to right
; to determine whether any will actually change color.
; AL is used for Color Don't Care mask
;
; If using EGAINT10 interface, this routine must access the CDCReg
; and perform the associated color compare read with ints disabled,
; then reenable them to allow other processes to access the card
; before the next byte is checked. Since another process may have
; modified the graphics chip index reg as well as the data reg, we
; must send both index and data for each odd/even toggle.
;Entry:
; SI = byte address of leftmost byte in range
; BH = bit mask for rightmost byte
; BL = bit mask for leftmost byte
; DI = total number of whole bytes -1
; ES = video segment
;Exit:
; CL = 0 if no pixels found to change, non-zero if pixels to change
;Uses:
; per conv.
;Exceptions:
;****
DbPub PIXRT3
cProc PIXRT3,<NEAR>,<DX>
cBegin
MOV DX,GRPADD ;index port for graphics
MOV AL,LOW CDCREG ;set up for Color Don't Care register
EGAINT10CLI ;disable ints if using EGAINT10
OUT DX,AL
INC DX
MOV AL,10101010B ;initially assume odd byte mask
TEST SI,1 ;check whether first byte odd or even
JNZ SETMSK ;if odd, branch to set mask
ROR AL,1 ;else rotate mask 1 right
SETMSK:
OUT DX,AL
; read first byte
MOV CL,ES:[SI] ;bit pattern of first byte with 0's where
;color not paint attribute
AND CL,BL ;AND now produces difference if non-paint
;bit in significant position
XOR CL,BL ;for significant bits in our first byte (bit
;set in BH), then non-paint will be one
JNZ PNTBIT ;found a bit to change
OR DI,DI ;any more bytes?
JZ PIXLAST ;no full bytes, go try last
; Look at whole bytes within viewport range until non-paint color found.
LKPTR3:
INC SI
ROR AL,1 ;shift Don't Care mask
OUT DX,AL
MOV CL,ES:[SI]
EGAINT10STI ;read is done, reenable ints if EGAINT10
NOT CL ;check if all bits set (all paint color)
OR CL,CL ;NOT does not affect flags
JNZ PNTBIT
DEC DI
EGAINT10CLI ;disable ints for next OUTs (loop
; or fall through)
JNZ LKPTR3 ;keep looking until search of complete
;bytes is exhausted
; On last byte now, mask in BH.
PIXLAST:
INC SI
ROR AL,1
OUT DX,AL
MOV CL,ES:[SI] ;do last compare
AND CL,BH ;significant bit = 0 if not paint color
XOR CL,BH ;if different, non-paint color pixels
JNZ PNTBIT ;leave CL non-zero as flag
NOBTR3:
XOR CL,CL ;else zero the flag
PNTBIT:
EGAINT10STI ;reenable ints at common exit
cEnd
;***
; ScanLX
;Purpose:
; Scan left beginning with the pixel to the left of cursor,
; and paint pixels until:
; (1) the viewport edge is encounteered (edge painted)
; (2) a border pixel is encountered (border not painted)
;
; This version supports PAINT for the odd/even EGA modes (bios mode
; 10H with 64K of memory, and monochrome bios mode F). It differs
; from SCANL2 in its use of the Color Don't Care register in
; conjunction with screen reads. This is necessary because if the
; planes representing the even bytes and those representing the odd
; bytes are not disabled during color compares for odd and even bytes,
; respectively, the color compare is made as the sum of the bits set
; for each even byte and its odd successor, all four planes at one
; address.
;Entry:
; b$AddrC, b$MaskC = pixel to right of starting pixel
; b$PaintBorder = attribute of paint region border
; b$AttrC = attribute to paint
; B$LEOFST, B$VLMASK = left viewport edge
;Exit:
; BX = number of pixels scanned
; CL = 0 iff no pixels changed color
; b$OffC, b$MaskC = the last non-border pixel examined/painted
;Uses:
; per conv.
;Exceptions:
;*****************************************************************************
DbPub ScanLX
cProc ScanLX,<NEAR>,<ES>
cBegin
CALL B$EgaScanInit
ROL CH,1 ;see if cursor is left edge of byte
JNB VWBYT1 ;if not, proceed to viewport checks
DEC SI ;if so, start next byte left
JS SCNOUT ;if negative, hit corner of screen
VWBYT1: ;start on-screen viewport checks
CMP SI,B$LEOFST ;see if off edge of viewport to left
JNB VWBYT2
SCNOUT:
JMP BRDEX3 ;else do nothing, exit
VWBYT2:
JNZ NOTBYT ;if not edge byte, skip bit checks
CMP CH,B$VLMASK ;else check for pixel left too far and
JNA NOTBYT
JMP BRDEX3 ;thus off viewport edge -- exit if so
NOTBYT:
MOV DI,SI ;extra copy of first byte address
MOV BL,CH ;extra copy of initial bit mask
MOV BP,-1 ;this will be count of whole bytes
XOR AH,AH ;initialize this byte's viewport mask to 0
; First task is to set up initial Color Don't Care mask depending
; on whether first byte is odd or even.
MOV CL,10101010B ;initially assume odd byte -- 10101010
TEST SI,1
JNZ STCDC3
ROR CL,1 ;if even, set up 01010101
STCDC3:
MOV DX,GRPADD
MOV AL,LOW CDCREG ;index to Color Don't Care register
OUT DX,AL
INC DX
MOV AL,CL
OUT DX,AL
; read first byte off the screen
MOV AL,ES:[DI]
EGAINT10STI ;read is done, reenable ints if EGAINT10
TEST AL,CH ;see whether initial pixel is border
JZ SRCLF3 ;if not, start search left
XOR CL,CL ;else set pixels-changed flag back to 0
MOV BL,CL ;zero out 8-bit register used
JMP BRDEX3 ;and exit gracefully
SRCLF3:
; look for border or viewport in first byte
CMP DI,B$LEOFST ;is this in fact viewport edge byte?
JNZ NTVWL3
MOV AH,B$VLMASK ;if so, set up viewport mask in AH
NTVWL3:
; while not border
TEST AL,CH
JNZ HAVPX3
; and not viewport edge
TEST AH,CH
JNZ HAVPX3
; and not off the edge of the byte
ROL CH,1
JNB NTVWL3
; keep moving left - edge of first byte
DEC DI ;next byte address left
INC BP ;count of intermediate bytes
ROR CL,1 ;rotate Color Don't Care mask
MOV AL,CL
OUT DX,AL
MOV AL,ES:[DI] ;read next byte left
EGAINT10STI ;reenable ints between bytes if EGAINT10
JMP SHORT SRCLF3 ;check next byte
; Here when border or viewport edge found.
; Set up bit mask for first (possibly only) byte
; SI = rightmost byte
; DI = leftmost byte (possibly same byte)
; BL = mask for rightmost bit in rightmost byte
; If viewport edge was found, AH will contain the viewport bit
; mask, and DI is the viewport edge byte. If SI=DI=viewport edge
; byte, we need to retain the viewport mask in AH. Otherwise
; clear AH and fetch the mask again later if needed for DI.
HAVPX3:
CMP SI,B$LEOFST ;see if rightmost byte is LEFT viewport
JZ SINTV2 ;if so, don't clear viewport mask
; register
XOR AH,AH ;else clear AH for CHKBTL on
SINTV2: ; rightmost byte
MOV CH,BL ;initial bit position in CH
MOV CL,10101010B ;need to reset Color Don't Care mask
TEST SI,1 ;see if odd byte
JNZ SISET
ROR CL,1
SISET:
MOV AL,CL
OUT DX,AL ;set up Color Don't Care
MOV AL,ES:[SI] ;get border bits if any
XOR DX,DX ;this will be #pixels painted
CALL B$EgaCHKBTL ;set up bit mask for first byte
MOV BL,BH ;store in BL
XOR BH,BH ;there may be only one byte
; see if more than 1 byte to paint
PUSH SI ;save a copy of rightmost address
INC BP ;see if still -1
JZ ONEALN ;"one alone"
DEC BP ;if not, recover real value
PUSH DX ;store pixel count
MOV DX,GRPADD+1 ;data port for Color Don't Care
MOV CL,10101010B ;assume mask 10101010
TEST DI,1 ;check DI for odd or even address
JNZ DISET
ROR CL,1 ;if even, set up 01010101
DISET:
MOV AL,CL
OUT DX,AL
POP DX ;restore pixel count
MOV AL,ES:[DI] ;get border bits if any
MOV CH,1 ;set up mask for final byte
CMP DI,B$LEOFST ;was this viewport byte?
JNZ DINTV2 ;no -- don't need viewport mask
MOV AH,B$VLMASK ;yes -- get viewport mask for CHKTBL
DINTV2:
CALL B$EgaCHKBTL ;set up leftmost byte bit mask in BH
ONEALN:
MOV b$OffC,DI
MOV b$MaskC,CH ;update cursor
PUSH DI ;save a copy of leftmost address
MOV DI,BP ;store whole byte count for PIXLFT
CMP b$Tiling,0 ;see if tiling is on
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -