📄 lltext.asm
字号:
;******************************************************************************
cProc AlphaDim0,<NEAR>
cBegin
mov cl,80 ;80 is "other" columns
ADim0_2: ;common entry point from AlphaDim2
xor al,al ;flag request for screen 0
cmp bl,cl ;"other" columns?
je ADim0Exit ;exit if so w/request to reenter screen 0
ADim0_7: ;common entry point from AlphaDim7
cmp bl,b$ScrWidth ;same as current?
stc
jne ADim0Exit ;go if not w/error, only 80 or 40 columns
cmp bh,25 ;25 lines?
je ADim0Ok ;go if so, w/request to reenter screen 0
; to get back to 25 lines
dec al ;flag request satisfied (or error)
test b$Adapter,EGA + VGA ;EGA or VGA?
stc ;set error, just in case
jz ADim0Exit ;go if not w/error, only 25 lines
test b$Monitor,StdColor ;disallow StdColor monitor for 43 lines
stc ;set error, just in case
jnz ADim0Exit ;go if StdColor w/error
cmp bh,43 ;43 lines?
je LinesOk ;43 lines is ok
test b$Adapter,VGA ;VGA?
stc ;set error, just in case
jz ADim0Exit ;exit with error if not VGA
cmp bh,50 ;50 lines?
stc ;set error, just in case
jne ADim0Exit ;exit with error if not 50 lines
mov cx,P40x50 ;larger page size
cmp bl,40 ;40 columns?
je ADim0_50 ;go if so
mov cx,P80x50 ;larger page size
jmp short ADim0_50
LinesOK:
mov cx,P40x43 ;larger page size
cmp bl,40 ;40 columns?
je ADim0_43 ;go if so
mov cx,P80x43 ;larger page size
ADim0_50:
mov b$MaxPage,3 ;only 4 pages in 80x43 or 80x50 or 40x50
ADim0_43:
;64K EGA has half the pages for all text dimensions except
;40x25, which is handled by B$Screen0 and never reaches here
cmp b$VideoMem,64 ;only 64K?
ja PgOk ;go if more, MaxPage is right
shr b$MaxPage,1 ;halve number of pages if 64K mode 7
PgOk:
ADim0Ok:
mov b$ScrHeight,bh ;set alpha rows
clc ;no error
ADim0Exit:
cEnd
;***
; AlphaDim2
;
;Purpose:
; Validate the proposed text dimensions for 80 column Screen mode 0
; and set up several screen-dependent variables if dimensions are OK.
;Entry:
; BH = number of lines
; BL = number of columns
;Exit:
; exits through AlphaDim0
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc AlphaDim2,<NEAR>
cBegin
mov cl,40 ;40 is "other" columns
jmp ADim0_2 ;rest is just like mode 0 case
cEnd <nogen>
;***
; AlphaDim7
;
;Purpose:
; Validate the proposed text dimensions for monochrome Screen mode 0
; and set up several screen-dependent variables if dimensions are OK.
;Entry:
; BH = number of lines
; BL = number of columns
;Exit:
; exits through AlphaDim0
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc AlphaDim7,<NEAR>
cBegin
xor al,al ;setup for request to reenter screen 0
jmp ADim0_7 ;rest is just like mode 0 case
cEnd <nogen>
;***
; B$FixTextPage
;
;Purpose:
; Fix up b$CurrPSize (for 43/50 lines) and initialize b$PageTable.
;
;Entry:
; b$CurrPSize initialized to 25-line default.
; b$ScrHeight must be initialized (call Alphadim).
;
;Exit:
; b$CurrPSize updated.
; b$PageTable initialized.
;
;Uses:
; per conv.
;
;Preserves:
; DI.
;
;******************************************************************************
cProc B$FixTextPage,<PUBLIC,NEAR>,<DI>
cBegin
xor ax,ax ; get a zero
cmp b$ScreenMode,al ; make sure we're in text mode
jnz PSizeExit ; else just return
push es
cmp b$ScrHeight,25 ; 25-line mode?
je PSizeOkay ; brif so--b$CurrPSize already set correctly
mov es,ax
mov ax,es:[CRT_LEN] ; get actual page size from BIOS, in bytes
mov cl,4
shr ax,cl ; convert to paragraphs
mov b$CurrPSize,ax ; and update current page size
PSizeOkay:
mov di,offset DGroup:b$PageTable
mov bx,[b$CurrPSize] ; size of page in paragraphs
mov cl,4
shl bx,cl ; convert to size in bytes
xor ax,ax ; first page always at offset zero
mov cx,8 ; assume 8 pages
push ds
pop es ; es=ds
SetPageTable:
stosw ; set offset for this page
add ax,bx ; compute offset of next page
loop SetPageTable
pop es
PSizeExit:
cEnd
;***
; SetMode
;
;Purpose:
; Set screen mode according to the characteristics established
; by previous call to B$Screenx and b$AlphaDim. Set 8x8 character
; font if new mode is to be 43 or 50 lines.
;Entry:
; b$BiosMode is mode to set
; b$ScrHeight is number of lines
;Exit:
; None
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc SetMode,<NEAR>
cBegin
test b$Adapter,VGA + MCGA ;MCGA or VGA?
jz SkipScanSet ;no, don't set scan lines
mov ax,1202H ;assume we want 400 scan lines
cmp b$ScrHeight,43 ;43 lines mode?
jne SetScans ;no, go set to 400 scan lines
mov ax,1201H ;set 350 scan lines for 43 line mode
SetScans:
mov bl,30H ;subfunction for set scan lines
SCNIO ;set the scan lines
SkipScanSet:
mov al,b$BiosMode ;set BIOS mode
SCNIO vSetMode
cmp b$ScrHeight,43 ;43 lines?
je Set8x8 ;branch if so
cmp b$ScrHeight,50 ;50 lines?
Set8x8:
jne SetMode25 ;go if not
mov ax,1112H ;character generator request
xor bl,bl ; to load 8x8 font
SCNIO ; which gets 43 lines [2]or 50 lines
MOV AX,0707H ; cursor type for 8x8 font
JMP SHORT sm_1
SetMode25:
MOV AX,0707H ; assume 7,7 cursor (all bios modes but 7)
CMP b$BiosMode,AL ; bios mode 7? (AL = 7)
JNE StoreCsr ; no, use normal cursor
MOV AX,0C0CH ; bios mode 7 cursor is 12,12
sm_1:
StoreCsr:
MOV b$UsrCsrTyp,AX ; store cursor type
MOV b$UsrCsrTyp,AX ; store cursor type
MOV b$InsCsrStop,AL ; and make insert cursor match
MOV DX,b$CURSOR ; Get current cursor position
MOV BYTE PTR b$CSRTYP,-1 ; invalidate present cursor type so it
; will get changed
CALL B$USRCSR ; display user cursor
NoStore:
cEnd
;***
; SetPages
;
;Purpose:
; Set the current active and visual pages for text modes.
;Entry:
; AL = active page
; AH = visual page
;Exit:
; None
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc SetPages,<NEAR>
cBegin
mov b$CurPages,ax ;save page numbers
mov al,ah
SCNIO vSelActivePage ;set visual page
cEnd
;***
; PalTrans7
;
;Purpose:
; Translate a user supplied color for monochrome Screen mode 0
; to the corresponding hardware value after verifying that the
; attribute value and the color value are in the legal ranges.
; Color mapping: 0 --> 0
; 1 --> 01000B
; 2 --> 11000B
;Entry:
; DX:AX = user supplied color value
; BL = user supplied attribute value
;Exit:
; PSW.C set if illegal value, reset if Ok
; DX:AX = translated color value
; BL = unchanged
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc PalTrans7,<NEAR>
cBegin
cmp bl,b$MaxAttr ;is legal attribute ?
ja PalTrErr ;error return
or dh,dl ;hi word of color 0?
or dh,ah ;hi byte of lo word of color 0?
jnz PalTrExit ;error if not
cmp al,b$MaxColor ;is legal color ?
ja PalTrErr ;error return
cmp al,1 ;translate color
jb PalTrExit ; 0 -> 0
mov al,01000B ; 1 -> 01000B
je PalTrExit
mov al,11000B ; 2 -> 11000B
PalTrExit:
clc ;no error
ret
PalTrErr:
STC ;indicate error
cEnd
;***
; SetColor
;
;Purpose:
; Process the color statement for text modes (BASIC Screen mode 0).
; Syntax for text mode color statement is as follows:
;
; COLOR [foreground],[background],[border]
;
; where "foreground" is the attribute to be used for the foreground
; (0-15 are normal, 16-31 are 0-15 plus blinking)
; and "background" is the attribute to be used for the background
; and "border" is the color to be used for the overscan border
;
; 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$FBColors is set to foreground/background attributes
; b$CharColor is set to character attribute (fg & bg in one byte)
; b$NullColor is set to null attribute (same as character attribute)
;Uses:
; per conv.
;Exceptions:
;******************************************************************************
cProc SetColor,<NEAR>
cBegin
MOV DX,b$FBColors ;dl=ForeColor dh=BackColor
MOV BH,b$BorderColor
JCXZ SetColErr ;error if no params
jmp short SetCol1
SetColErr:
stc
jmp SetColExit
SetCol1:
cCall B$GetParm ;[AL] = parm if not psw.z
JZ TXTCL1 ;brif no parm given
CMP AL,31 ;is foreground color in range [0-31]?
JA SetColErr ;error if not
XCHG AL,DL ;save new foreground color
TXTCL1:
cCall B$GetParm ;get bkgrnd color if specified
JZ TXTCL2 ;brif no parm given
CMP AL,15 ;range check background color [0-15]
JA SetColErr ;brif out of range
XCHG AL,DH ;save new background color
TXTCL2:
cCall B$GetParm ;get border color if specified
JZ TXTCL3 ;brif no parm given
JCXZ NoError
JMP SHORT SetColErr
NoError:
CMP AL,15 ;range check border color [0-15]
JA SetColErr ;brif out of range
XCHG AL,BH ;save new border color
TXTCL3:
cmp b$BiosMode,7 ;mode 7?
jne SetColOk ;skip if not
test b$Adapter,EGA ;EGA?
jz SetColOk ;skip if not
;this fixes a bug in the EGA card mode 7 ???
;if Fg=0/8/16/24 and Bg=7/15 let it go else force Bg to 0
mov al,dh ;BackColor
not al ;low 3 bits = 0 iff BackColor = 7|15
or al,dl ;low 3 bits = 0 iff ForeColor = 0|8|16|24
and al,7 ;low 3 bits = 0 iff both
jz SetColOk
xor dh,dh ;in all other cases make Bg = 0
SetColOk:
MOV AX,DX ;get fg/bk colors in AX
MOV b$FBColors,AX ;new fore and back
XCHG DH,DL ;swap forground/background colors
AND DH,0FH ;strip off blink
SHL DL,1 ;shift background intensity bit into d4
AND DL,10H ;leave intensity
OR DL,BH ;[DL] = border color + background intensity
AND AH,7 ;strip background intensity from char attribute
MOV CL,4
SHL AH,CL ;move background color bits to d6-d4 for char
;attribute
TEST AL,10H ;is blink enabled?
JZ NOBLNK ;br. if not
OR AH,80H ;add blink
NOBLNK:
OR AH,DH ;add foreground color
MOV CH,AH ;place char attribute in CH
MOV b$NullColor,AH ;char attribute
MOV b$CharColor,AH ;null attribute
TEST b$Monitor,AnalogColor + AnalogMono + EnhColor
;enhanced or analog monitor?
jnz NO_BORDER ;Brif so
MOV b$BorderColor,BH;new border color
MOV BL,DL ;need border color in BL
XOR BH,BH ;zero BH
SCNIO vSetPalette ;set border color
NO_BORDER:
clc ;indicate no error
SetColExit:
cEnd
sEnd GR_TEXT
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -