📄 llcga.asm
字号:
;
;Purpose:
; Validate the proposed text dimensions for Screen 1.
; If 40x25 is requested, this mode satisfies the request
; elseif 80x25 is requested, suggest screen mode 2
; else suggest screen mode 0.
;Entry:
; BH = number of lines
; BL = number of columns
;Exit:
; AL = -1 if this mode satisfies the request, otherwise
; AL is suggested screen mode to invoke for desired dimensions
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
DbPub AlphaDim1
cProc AlphaDim1,<NEAR>
cBegin
mov al,-1 ;flag request satisfied (maybe)
cmp bx,40+25*256 ;40x25?
je ADim1Exit ;exit if so, standard stuff
xor al,al ;flag request for screen 0
cmp bx,80+25*256 ;80x25?
jne ADim1Exit ;if not, let text mode try
mov al,2 ;otherwise use screen 2
ADim1Exit:
clc ;no error
cEnd
;***
; AlphaDim2
;
;Purpose:
; Validate the proposed text dimensions for Screen 2.
; If 80x25 is requested, this mode satisfies the request
; elseif 40x25 is requested, suggest screen mode 1
; else suggest screen mode 0.
;Entry:
; BH = number of lines
; BL = number of columns
;Exit:
; AL = -1 if this mode satisfies the request, otherwise
; AL is suggested screen mode to invoke for desired dimensions
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
DbPub AlphaDim2
cProc AlphaDim2,<NEAR>
cBegin
mov al,-1 ;flag request satisfied (maybe)
cmp bx,80+25*256 ;80x25?
je ADim1Exit ;exit if so, standard stuff
xor al,al ;flag request for screen 0
cmp bx,40+25*256 ;40x25?
jne ADim2Exit ;if not, let text mode try
inc al ;otherwise use screen 1
ADim2Exit:
clc ;no error
cEnd
;***
; SetMode
;
;Purpose:
; Set the screen mode according to the characteristics established
; by previous call to B$Screenx and b$AlphaDim.
;Entry:
;
;Exit:
;
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
DbPub SetMode
cProc SetMode,<NEAR>
cBegin
mov al,b$BiosMode ;set BIOS mode
SCNIOS vSetMode
cmp b$ScreenMode,1 ;remainder for SCREEN 1 only
jne SetModeExit ;exit if not
test b$Adapter,EGA+VGA ;EGA or VGA?
jz SetModeExit ;go if not
;
; The following is provided only to overcome a bug in the EGA BIOS
; routines which support the graphics "compatibility mode" (BIOS 4)
; so that the two calls related to PALETTE (INT10 AH = 0BH and
; INT10H AH = 10H) work correctly. If we use the first call once
; when user invokes SCREEN 1 to set the background color, then the
; BIOS will subsequently reference the correct (low-intensity)
; color values for the 4 palette attributes whenever the call using
; INT10H, AH = 0BH is used to toggle the palette, and whenever the
; call INT10H, AH = 10H is used to set an individual palette regis-
; ter. In the absence of this initialization, the high-intensity
; color values for both palettes are referenced.
;
xor bx,bx ;set background to 0
SCNIOS vSetPalette ;INT10H, AH=0BH "set color palette"
SetModeExit:
cEnd
;***
; B$CgaSetPages
;
;Purpose:
; Set the current active and visual pages and calculate page size
; and video segment offset.
;Entry:
; AL = active page (will always be 0 for these modes)
; AH = visual page (will always be 0 for these modes)
;Exit:
; b$CurPages set to new active and visual pages
; b$SegC set to video segment
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
PUBLIC B$CgaSetPages
cProc B$CgaSetPages,<NEAR>
cBegin
DbAssertRel AX,E,0,GR_TEXT,<Non-zero page requested in B$CgaSetPages (LLCGA)>
mov [b$CurPages],ax ; save page numbers
mov ax,[b$VideoBase] ;set video segment
mov [b$SegC],ax
cEnd
;***
; PalPut1
;
;Purpose:
; Change palette entry for Screen 1 with translation/verification.
; A color value of -1 indicates that the associated palette
; entry is not to be modified.
;Entry:
; [DX:AX] = color
; BL = attribute
;Exit:
; PSW.C reset indicates successful operation
; set indicates PALETTE function call error
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
DbPub PalPut1
cProc PalPut1,<NEAR>
cBegin
cmp ax,-1 ;lo word of color == -1?
jne PutPalA ;go if not, can't ignore
cmp dx,ax ;hi word too?
je PutPalX ;exit if color == -1
PutPalA:
push ax
push dx
push bx
call B$EgaPalPut ;put palette value
pop bx
pop dx
pop ax
jc PutPalX ;go if error
or bl,bl ;is for background?
jnz PutPalX ;exit if not
call B$EgaPalTrans ;translate color value again!!
cmp b$EgaPalSup,0 ;have we an EGA palette?
je PutPalX ;exit if not
mov bh,al ;overscan color
mov al,1 ;subfunction "Set Overscan (Border) Register"
SCNIO vSetEgaPalette ;set the border color identically
PutPalX:
cEnd
;***
; MapXYC1
;
;Purpose:
; May given X and Y coordinates to the graphics cursor for Screen 1.
;Entry:
; CX = X coordinate
; DX = Y coordinate
;Exit:
; b$OffC, b$MaskC updated
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
DbPub MapXYC1
cProc MapXYC1,<NEAR>
cBegin
xor ax,ax
shr dx,1 ;dx=row within odd or even half, carry=1 if odd
rcr ax,1 ;ax=8K if dx was odd, 0 if was even
shr ax,1 ; computing offset to proper buffer half
shr ax,1
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
shl dx,1 ;dx=20*Y
shl dx,1 ;dx=40*Y
shl dx,1 ;dx=80*Y
add dx,ax ;odd rasters are displaced 8k
mov ax,cx ;save x
shr ax,1 ;div by PixelsPerByte (4)
shr ax,1 ; to get byte index
add dx,ax ;add x byte offset to y row address
mov b$OffC,dx ;save byte offset
and cl,3 ;mask in x bit addr
shl cl,1 ; *2 for pixel addr in byte
mov ch,11000000B ;leftmost pixel on in shift mask
shr ch,cl ;move over to get mask
mov b$MaskC,ch ;store cursor mask
cEnd
;***
; MapXYC2
;
;Purpose:
; May given X and Y coordinates to the graphics cursor for Screen 2.
;Entry:
; CX = X coordinate
; DX = Y coordinate
;Exit:
; b$OffC, b$MaskC updated
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
DbPub MapXYC2
cProc MapXYC2,<NEAR>
cBegin
xor ax,ax
shr dx,1 ;dx=row within odd or even half, carry=1 if odd
rcr ax,1 ;ax=8K if dx was odd, 0 if was even
shr ax,1 ; computing offset to proper buffer half
shr ax,1
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
shl dx,1 ;dx=20*Y
labelNP <PUBLIC,B$MapXYC2_4> ; common to MAPXYC4 routine (lloga.asm)
shl dx,1 ;dx=40*Y
shl dx,1 ;dx=80*Y
add dx,ax ;odd rasters are displaced 8k
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
;***
; SetAttr1
;
;Purpose:
; Replicate supplied attribute throughout the attribute byte for
; use by Screen 1 functions. If supplied attribute is beyond
; legal range the maximum legal attribute is used.
;Entry:
; AL = attribute
;Exit:
; b$Attr updated
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
DbPub SetAttr1
cProc SetAttr1,<NEAR>,<AX>
cBegin
cmp al,b$MaxAttr ;test against maximum attribute
jbe SetAttr1Ok ;Brif legal
mov al,b$MaxAttr ;limit to max
SetAttr1Ok:
MOV CL,2 ;2 bits per pixel
MOV AH,AL ;attr mask in ??????xx
SHL AH,CL
OR AL,AH ;attr mask in ????xxxx
SHL AH,CL
OR AL,AH ;attr mask in ??xxxxxx
SHL AH,CL
OR AL,AH ;attr mask in xxxxxxxx
MOV b$AttrC,al ;exit no error
cEnd
;***
; SetColor1
;
;Purpose:
; Process the color statement for Screen 1. Syntax for Screen 1
; color statement is as follows:
;
; COLOR [background],[fg palette],[fg override]
;
; where "background" is a color number 0-255 which gets mapped to 0-15,
; "fg palette" is a number which selects CGA palette 0 if even,
; or CGA palette 1 if odd,
; and "fg override" (if present) replaces and functions identically
; to "fg palette".
;
; 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 too many parameters, reset if Ok
; b$NullColor set to background attribute value (always 0 for screen 1)
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
DbPub SetColor1
cProc SetColor1,<NEAR>
cBegin
cCall B$GetParm ;AL=background parameter
push ax ;save background and flag
cCall B$GetParm ;AL=1st palette parameter
xchg ax,bx ;save 1st palette and flag
cCall B$GetParm ;AL=2nd palette parameter
jnz SetCol1 ;jump if param found
; which overrides the 1st one
xchg ax,bx ;restore 1st palette param
or ah,ah ;is it defaulted too?
jnz SetCol2 ;go if so
SetCol1:
; If palette parameter, then user gets bogus palette reset to
; 0 or 1.
push ax ;save palette select value
test b$Adapter,EGA + VGA ;EGA or VGA?
jnz IsEga ;go if so
xor bx,bx ;set background subfunction (0)
mov bl,BackColor ;get chosen background color
SCNIOS vSetPalette ;set background
IsEga:
pop bx ;restore palette select value
mov bh,1 ;subfunction - set bogus palette
and bl,bh ;force palette number to 0 or 1
SCNIOS vSetPalette
SetCol2:
pop bx ;the background parameter is on the stack
or bh,bh ;was there background parameter?
jnz SetColExit ;no, only palette
and bl,0FH ;Allow 0-255, mask to 0-15.
test bl,8 ;If Bgnd to be intensified
jz SetCol3 ;Brif not
or bl,10H ;Set Intensity Bit
SetCol3:
mov BackColor,bl ;save it
test b$Adapter,EGA + VGA ; EGA card present? [10] or VGA?
jz NoEga ; No, use CGA BIOS call to set background
mov al,bl ;AL=color
and al,0FH ;strip intensity (PalPut will translate)
cbw ;AX=color
cwd ;DX:AX=color
mov bl,bh ;BL=attribute(0)
call [b$PalPut] ;make the EGA do what WE want
jmp short SetColExit
NoEga:
SCNIOS vSetPalette ;set background color
SetColExit:
mov b$NullColor,0 ;use background for null color
clc ;indicate no error
jcxz SetColDun ;if we got all params, thats true
stc ;otherwise set error
SetColDun:
cEnd
;***
; B$xINITCGA - initialize CGA modes
;
;Purpose:
; Added with revision [14].
; Put the addresses of CGA screen mode support routines into the
; dispatch table used by the screen statement.
;
;Entry:
; None
;Exit:
; ScreenTab updated
;Uses:
; None
;Exceptions:
;******************************************************************************
cProc B$xINITCGA,<FAR,PUBLIC>
cBegin
MOV WORD PTR [b$ScreenTab + (1*2) + 1],OFFSET B$Screen1
MOV WORD PTR [b$ScreenTab + (2*2) + 1],OFFSET B$Screen2
cEnd
sEnd GR_TEXT
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -