📄 llegasup.asm
字号:
TITLE LLEGASUP - LowLevel EGA support (shared routines)
;***
; LLEGASUP - LowLevel EGA support
;
; Copyright <C> 1987, Microsoft Corporation
;
;Purpose:
; This module contains support routines extracted from LLEGA.ASM
; which are shared by EGA and VGA functions.
;
;******************************************************************************
INCLUDE switch.inc ;feature switches
INCLUDE rmacros.inc
USESEG _BSS
USESEG GR_TEXT
INCLUDE seg.inc
INCLUDE ibmunv.inc
INCLUDE baslibma.inc
INCLUDE llgrp.inc
sBegin _BSS
;
;
; ***************************************************************************
; External variables
; ***************************************************************************
;
externB b$EgaPalSup
externD b$InitPalette
externB b$MaxColor
externB b$Monitor
externW B$LEOFST
externW B$REOFST
externW B$VTOFST
externW B$VBOFST
externW B$VLOFST
externW B$VROFST
externB B$VLMASK
externB B$VRMASK
externD b$AddrC
externB b$AttrC
externW b$BytesPerRow
externB b$DivShift
externB b$EgaWrMd
externW b$Incr1
externW b$Incr2
externW b$IncrY
externB b$MaskC
externB b$MaxAttr
externW b$ModMask
externW b$OffC
externB b$PaintBorder
externW b$PenC
externB b$Planes
externW b$SegC
externB b$Tiling
externW b$SaveCa
externB b$SaveCm
externB b$PlaneMask
;
; ***************************************************************************
; External function vectors
; ***************************************************************************
;
externW b$PutVector
externW b$ReadC
externW b$PalTrans
externW b$PalPut
;
; ***************************************************************************
; Local variables
; ***************************************************************************
staticB AttrTile,,4 ;tile attribute pattern table
staticB ColorBits,,8 ;table of rotated tiling patterns
staticW ByteCount,,1
staticB EgaPalette,,17
;
sEnd _BSS
assumes CS,GR_TEXT
sBegin GR_TEXT
externNP B$BumpDS
externNP B$BumpES
externNP B$DecDS
externNP B$OutWord
externNP B$ResetEGA
;***
; B$EgaMapXYC_D
;
;Purpose:
; Map given X and Y coordinates to the graphics cursor for Screen 7.
;Entry:
; CX = X coordinate
; DX = Y coordinate
;Exit:
; b$OffC, b$MaskC updated
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaMapXYC_D,<PUBLIC,NEAR>
cBegin
mov bx,dx ;multiply y by 40 to compute row displacement
shl dx,1 ;dx=2*Y
shl dx,1 ;dx=4*Y
add dx,bx ;dx=5*Y
jmp short MapCommon
cEnd <nogen>
;***
; B$EgaMapXYC
;
;Purpose:
; Map given X and Y coordinates to the graphics cursor for EGA modes
;Entry:
; CX = X coordinate
; DX = Y coordinate
;Exit:
; b$OffC, b$MaskC updated
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaMapXYC,<PUBLIC,NEAR>
cBegin
mov bx,dx ;multiply y by 80 to compute row displacement
shl dx,1 ;dx=2*Y
shl dx,1 ;dx=4*Y
add dx,bx ;dx=5*Y
shl dx,1 ;dx=10*Y
MapCommon:
shl dx,1 ;dx=20*Y
shl dx,1 ;dx=40*Y
shl dx,1 ;dx=80*Y (40*Y for mode 0DH)
mov ax,cx ;save x
shr ax,1 ;div by PixelsPerByte (8)
shr ax,1 ; to get byte index
shr ax,1
add dx,ax ;add x byte offset to y row address
mov b$OffC,dx ;save byte offset
and cl,7 ;mask in x bit addr
mov ch,10000000B ;leftmost pixel on in shift mask
shr ch,cl ;move over to get mask
mov b$MaskC,ch ;store cursor mask
cEnd
;***
; B$EgaLeftC/B$EgaLeftC_13
;
;Purpose:
; Move graphics cursor left 1 pixel for EGA modes or Screen 13,
; depending on entry point. No test is made for screen boundaries.
;Entry:
; None
;Exit:
; b$MaskC, b$OffC updated
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaLeftC,<PUBLIC,NEAR>
cBegin
rol b$MaskC,1
jc LeftCnext ;go if not in same byte
ret
labelNP <PUBLIC,B$EgaLeftC_13>
LeftCnext:
dec b$OffC ;move byte pointer
cEnd
;***
; B$EgaChkUpC
;
;Purpose:
; Move graphics cursor up 1 pixel for EGA modes. A test is made for
; boundaries. If it is a boundary then PSW.C is set upon return and
; no move is made.
;
;Entry:
; None
;Exit:
; b$MaskC, b$OffC updated
; PSW.C = set if original graphics cursor was on screen top edge.
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaChkUpC,<PUBLIC,NEAR>
cBegin
MOV AX,b$OffC ;[AX] = cursor offset
CMP AX,B$VTOFST ;already on top of viewport ?
JAE B$EgaUpC ;less than VTOFST means on top of
;viewport
STC ;STC to indicate that cursor already
cEnd ;on top of viewport
;***
; B$EgaUpC
;
;Purpose:
; Move graphics cursor up 1 pixel for EGA modes. No test is made for
; screen boundaries.
;Entry:
; None
;Exit:
; b$MaskC, b$OffC updated
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaUpC,<PUBLIC,NEAR>
cBegin
mov ax,b$BytesPerRow
sub b$OffC,ax ;up one row
clc ;(no error for ChkUpC)
cEnd
;***
; B$EgaChkDownC
;
;Purpose:
; Move graphics cursor down 1 pixel for EGA modes. If beyond the
; bottom edge, PSW.C is set upon return and no move is made.
;Entry:
; None
;Exit:
; PSW.C = set if original cursor was on screen edge.
; b$MaskC, b$OffC Updated otherwise
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaChkDownC,<PUBLIC,NEAR>
cBegin
MOV AX,b$OffC ;[AX] = cursor offset
CMP AX,B$VBOFST ;already at the bottom of viewport?
JB B$EgaDownC ;Brif not
STC ;STC to indicate that cursor is
cEnd ;on bottom of viewport
;***
; B$EgaDownC
;
;Purpose:
; Move graphics cursor down 1 pixel for EGA modes. No test is made for
; screen boundaries.
;Entry:
; None
;Exit:
; b$MaskC, b$OffC Updated
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaDownC,<PUBLIC,NEAR>
cBegin
mov ax,b$BytesPerRow
add b$OffC,ax ;down one row
clc ;(no error for ChkDownC)
cEnd
;***
; B$EgaSetAttr
;
;Purpose:
; Set b$AttrC to user-supplied attribute for EGA modes. If
; user-supplied attribute is outside legal range, use maximum legal
; attribute.
;Entry:
; AL = attribute
;Exit:
; b$AttrC set to new attribute
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaSetAttr,<PUBLIC,NEAR>,<AX>
cBegin
cmp al,b$MaxAttr ;test against maximum attribute
jbe SetAttrOk ;Brif legal
mov al,b$MaxAttr ;limit to max
SetAttrOk:
mov b$AttrC,al
clc ;exit no error
cEnd
;***
; B$EgaReadC
;
;Purpose:
; For EGA modes, return the attribute of the current pixel as
; specified by b$MaskC and b$OffC.
;
;Entry:
; b$MaskC and b$OffC specify pixel to read
;Exit:
; AL = attribute of pixel
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaReadC,<PUBLIC,NEAR>,<SI,ES>
cBegin
les si,b$AddrC
mov bx,0103H ;start at plane 3 and dec by 1 for 4 planes
ReadCX1:
EGAINT10CLI ; disable interrupts if using EGAINT10
MOV DX,GRPADD ;address of graphics index register
MOV AX,RWMREG ;r/w mode index in AL, 0 in AH
OutWord ;set read mode to 0 so that we read byte
;specified as 0/1 for one plane at a time
MOV AL,RMPREG ;AL=index to read map reg
OUT DX,AL ;indicate next data for read map register
INC DX ;data port address
MOV al,bl ;al = plane number
xor ah,ah ;ah = color accumulator
MOV cl,b$MaskC ;bit position
ReadC1:
OUT DX,AL ;indicate plane to read
MOV ch,ES:[si] ;get 8 bits for plane
AND ch,cl ;isolate bit to read
neg ch ;carry = (ch==0)?0:1
rcl ah,1 ;shift bit into color accumulator
sub al,bh ;reference next color plane to read
jae ReadC1 ;do next plane
XCHG AH,AL ;color attribute returned in AL
CALL B$ResetEGA ;set up EGA for next BIOS write
cEnd
;***
; B$EgaReadC_F
;
;Purpose:
; For Screen 10, return the attribute of the current pixel as
; specified by b$MaskC and b$OffC.
;
;Entry:
; b$MaskC and b$OffC specify pixel to read
;Exit:
; AL = attribute of pixel
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaReadC_F,<PUBLIC,NEAR>,<SI,ES>
cBegin
les si,b$AddrC
mov bx,0202H ;start at plane 2 and dec by 2 for 2 planes
; (0&2)
jmp short ReadCX1 ;continue in common code
cEnd <nogen>
;***
; B$EgaReadC_64K
;
;Purpose:
; For Screen 9/64K, return the attribute of the current pixel as
; specified by b$MaskC and b$OffC.
;
;Entry:
; b$MaskC and b$OffC specify pixel to read
;Exit:
; AL = attribute of pixel
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaReadC_64K,<PUBLIC,NEAR>,<SI,ES>
cBegin
les si,b$AddrC
mov bx,si ;copy video address
mov bh,2 ;bh = dec by 2 between planes
and bl,1 ;1 if odd, 0 if even
add bl,bh ;bl = plane (use maps 3 and 1 if odd address)
; ( or maps 2 and 0 if even address)
jmp short ReadCX1 ;continue in common code
cEnd <nogen>
;***
; B$EgaSetC
;
;Purpose:
; Set the pixel defined by the current graphics cursor to
; the current attribute for EGA modes.
;Entry:
; b$PenC = cursor mask and attribute
; b$AddrC = address of pixel byte
;Exit:
; None
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaSetC,<PUBLIC,NEAR>,<ES>
cBegin
EGAINT10CLI ; disable interrupts if using EGAINT10
MOV DX,GRPADD ;address of graphics index port
MOV AL,RWMREG ;index to the graphics controller mode reg
OUT DX,AL
MOV AL,b$EgaWrMd ;write mode 2; odd/even or sequential addr.
INC DX ;address data port
OUT DX,AL
MOV AL,BMKREG ;index to the bit mask register
DEC DX
OUT DX,AL
mov ax,b$PenC ;[al] = cursor mask, [ah] = attribute
INC DX
OUT DX,AL ;set bit mask
les bx,b$AddrC ;[BX] = cursor offset, [DS] = segment
XCHG ah,es:[BX] ;latch screen contents and do a color write
;reset EGA regs to those expected by the BIOS
MOV AL,0FFH ;set all mask bits
OUT DX,AL
MOV AL,RWMREG ;index to the graphics controller mode reg
DEC DX
OUT DX,AL
MOV AL,b$EgaWrMd ;odd/even or sequential addr.
and al,10H ;set write mode 0 for bios
INC DX
OUT DX,AL
EGAINT10STI ; reenable interrupts if using EGAINT10
cEnd
;***
; B$EgaSetPixC
;
;Purpose:
; Set the pixel defined by the current graphics cursor to
; the current attribute for EGA modes. This is identical
; to B$EgaSetC with the initialization and termination code
; extracted to make it faster when multiple pixels are being
; set in a graphics functin (ie: CIRCLE). A call to
; B$EgaSetPixFirstC should preceed the first call to
; B$EgaSetPixC. A call to B$ResetEGA should follow
; the last. B$EgaSetPixFirstC sets up ES which should be
; preserved for all B$SetPixC calls.
;Entry:
; ES = video segment (set up by B$EgaSetPix)
; b$PenC = cursor mask and attribute
; b$OffC = address of pixel
;Exit:
; None
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc B$EgaSetPixC,<PUBLIC,NEAR>
cBegin
MOV DX,GRPADD+1 ;address graphics data port
mov ax,b$PenC ;[al] = cursor mask, [ah] = attribute
OUT DX,AL
mov bx,b$OffC ;[BX] = cursor offset
;[ES] = setup by SetPixFirstC
XCHG ah,ES:[BX] ;latch screen contents and do a color write
cEnd
;***
; B$EgaSetPixFirstC
;
;Purpose:
; Set up ES to the video segment and set up EGA write mode so
; repeated calls can be made to B$EgaSetPixC without having
; to reinitialize.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -