📄 llcscn.asm
字号:
; Use BIOS/DOS support to scroll a window of any size
MOV DX,BX ;copy bottom right coordinates
MOV BH,b$NullColor ;get scroll attribute
XOR AX,AX ; zero lines default
CMP CH,DH ; only one line to scroll?
JE ScrollSet ; brif so -- just clear screen
INC AX ; Set number of lines to scroll as 1
ScrollSet:
SCNIOS vScrollPageUp ;SCROLL page up
SCROLL_RET: ; All done .. Exit after setting current
cCALL B$SELVPG ; Active Visual Page
cEnd ; End of B$SCROLL
;===================================
;***
; B$ErrorReturn
;
;Purpose:
; Return carry set, indicating error.
;
;Entry:
; None.
;
;Exit:
; PSW.C = set
;
;Uses:
; None.
;
;Exceptions:
; None.
;******************************************************************************
cProc B$ErrorReturn,<PUBLIC,NEAR>
cBegin
stc
cEnd
;***
; B$ScreenN
;
;Purpose:
; Invoke b$ScreenX[AL] to initialize mode data for the screen mode
; specified in AL.
;
;Entry:
; AL = Screen Mode
; AH = Burst (0/1)
; CL = alpha columns
;Exit:
; PSW.C = set indicates an error (mode not supported)
;Uses:
; per convention
;Preserves:
; AX, BX, CX, DX.
;Exceptions:
;******************************************************************************
cProc B$ScreenN,<PUBLIC,NEAR>,<AX,BX,CX,DX>
cBegin
MOV BX,[b$ScreenX] ; BX = DGROUP offset of screen mode table
CMP [BX],AL ; invalid mode?
JB ScrNExit ; brif so -- exit with carry set
MOV DL,AL ; Form screen mode in DX
XOR DH,DH ; [DX] = screen mode
ADD BX,DX
ADD BX,DX ; [DS:BX] = pointer-1 to pointer to routine
CALL word ptr [BX+1] ; set mode-dependent data
ScrNExit:
cEnd
;***
;B$GetParm - get a parameter from the list passed from high levels
;OEM-interface routine
;
;Purpose:
; This routine gets a parameter from the list pointed to by SI.
; The first word of the list is a flag specifying if a parameter
; was specified. If the flag is non-zero the next word in the
; list is the parameter. Otherwise the next word in the list
; is the flag for the next parameter. The list grows from high
; memory down. This routine will not modify the list.
;
; For example, if CX = 11,
;
; ---------------------------------------------------------
; | 51 | ~0| 4 | ~0 | 255| ~0 | 0 | 0 | 23 | ~0 | 0 |
; ---------------------------------------------------------
; ^
; SI
; will return the following on successive calls:
;
; CX AL AH PSW.Z
;
; 10 - 1 reset
; 8 23 0 reset
; 7 - 1 reset
; 6 - 1 reset
; 4 255 0 reset
; 2 4 0 reset
; 0 51 0 reset
; 0 - 1 set
;
; NOTE: Although both the flags and values are WORDs, any value
; that is greater than 255 will cause an Illegal Function
; Call. It is assumed that the list will be in a proper
; format.
;
;Entry:
; [SI] - points to high end of parameter list
; (parameters run from high to low memory)
; [CX] - count of words left in list
;
;Exit:
; [SI] - points to next parameter in list
; [CX] - modified count of words left in parameter list
; [AL] - parameter, if one was specified
; [AH] - 1 if parameter was missing or defaulted, 0 otherwise
; PSW.Z - set means no parameter was found
;
;Uses:
; SI is used as a return value
;
;Preserves:
; BX, DX
;
;Exceptions:
; B$ERR_FC if the value of the parameter > 255.
;******************************************************************************
cProc B$GetParm,<PUBLIC,NEAR>
cBegin
mov ah,1 ;ah=1 means (missing or) defaulted
STD ;from high to low....
OR CX,CX ;unfortunately, JCXZ doesn't set 0 flag
JZ GetParmExit ;brif list empty
LODSW ;get parameter flag
DEC CX ;one less word in list....
OR AX,AX ;was param defaulted?
mov ah,1 ;ah=1 means (missing or) defaulted
JZ GetParmExit ;brif so...
DbAssertRel CX,NZ,0,CN_TEXT,<Parameters out of sync in B$GetParm>
LODSW ;get parameter
OR AH,AH
JNZ BadParm ;Don't allow parms > 255
DEC CX ;one less word in list...
OR SP,SP ;got a parameter...
GetParmExit:
CLD
cEnd
BadParm:
CLD
JMP B$ERR_FC ;illegal function call
;***
;B$SETSCNDATA -- Set mode-dependent data for initialization.
;
;PURPOSE:
; This sets up all the mode-dependent data, both high and low-level.
; The startup screen mode or special mode characteristics (such as
; 43-line mode) may not be supported due to runtime version features
; or mode-dependent module stubbing. Default mode characteristics
; are used if the screen mode is available. Screen 0 is used if the
; startup mode itself is not supported.
; Major rewrite with [22].
;
;ENTRY:
; AL = Screen Mode ... all gleened from the initialization state
; AH = Burst
; CL = Screen Width
; CH = Screen Height
; DL = Active Page
; DH = Visual Page
;
;EXIT:
; Most internal screen variables set.
;
;USES:
;****
cProc B$SETSCNDATA,<NEAR,PUBLIC>
cBegin
call B$ScreenN ;set mode-dependent data
jnc ScrOk ;go if mode supported
cmp al,1 ;trying for screen 1?
jne BurstOk ;go if not
xor ah,al ;invert burst if going from screen 1 to 0
BurstOk:
xor al,al ;default to screen 0
call B$ScreenN ;set up screen 0
ScrOk:
xchg bx,cx ;width/height to BX
push dx ;save pages
call [b$AlphaDim] ;set text dimensions
call B$FixTextPage
mov al,b$ScrWidth
mov cl,b$ScrHeight
cCALL B$SCNSWI ;Inform Hi-Level about dimensions change
pop ax ;AX=act/vis pages for b$SetPages
cmp al,b$MaxPage ;Active Page OK?
ja ResetPage ;go if not
cmp ah,b$MaxPage ;Visual Page OK?
jbe PageOk ;go if not
ResetPage:
xor ax,ax ;clear both pages if either invalid
PageOk:
call [b$SetPages] ;set page values
cEnd
;***
;B$RESETSCN -- Reset the screen startup mode for termination.
;OEM-interface routine
;
;Purpose:
; This routine sets up the mode dependent data and the screen
; to the startup mode for termination. The startup mode was
; saved by B$GWINI in a form that our standard routines would
; be able to use it for termination. If delayed screen initialization
; is being implemented and the physical screen has not yet
; been changed, then this routine should just change internal
; variables. However if the screen has been changed, this
; routine must change the physical screen parameters to their
; entry value.
;
;Entry:
; None.
;
;Exit:
; Most internal screen variables set.
; b$ScreenRestored set properly
;
;Uses:
; Per convention
;
;Exceptions:
; None.
;****
;
;NOTE:
; The startup mode and characteristics were filtered by B$SETSCNDATA
; to values that we can support here.
;
;Our Entry Conditions:
;
; b$OrgScrBst = original startup screen mode and burst
; b$OrgScrDim = original startup screen dimensions
; b$OrgEquip = original startup equipment flags
; b$OrgCsrTyp = original startup cursor type
; b$OrgPages = original startup active/visual pages
;
cProc B$RESETSCN,<NEAR,PUBLIC>
cBegin
mov b$ScreenRestored,0 ;first assume no screen change
; With a VGA, the BIOS actually changes the BiosEquip flags to reflect
; the current mode. If we change it back (or the user POKEs it)
; the BIOS can get awfully confused! So DON'T mess with it!
test b$Adapter,VGA ;using VGA?
jnz ChkMode ;avoid Equipment flag check if so
;carry clear means must check mode
xor ax,ax ;use seg = 0
mov es,ax
mov al,b$OrgEquip ;check the original equipment flags
cmp al,es:[BiosEquip] ;were they changed?
mov es:[BiosEquip],al ;restore original equipment flags
push ds
pop es
je ChkMode ;no change, go check for mode change
;carry clear means must check mode
call B$SetAdapter ;make sure the adapter info is current
stc ;carry set means force SetMode
ChkMode:
mov ax,b$OrgScrBst ;original screen mode and burst
mov cx,b$OrgScrDim ; width and height
jc SetMode ;go if decision already made to SetMode
cmp al,b$ScreenMode;mode changed?
jne ChgMode ;go if so
cmp ah,b$Burst ;burst changed?
jne ChgMode ;go if so
cmp ch,b$ScrHeight ;height changed?
jne ChgMode ;go if so
cmp cl,b$ScrWidth ;width changed?
je SetMode ;go if not
ChgMode:
stc ;carry set means force SetMode
SetMode:
pushf ;save SetMode decision
; Always set screen mode data with B$ScreenN and b$AlphaDim which do
; not change the physical screen.
; B$SCNSWI must be called to reset the text (VIEW PRINT) window.
call B$ScreenN ;set mode-dependent data
xchg bx,cx ;width/height to BX
call [b$AlphaDim] ;set text dimensions
mov al,b$ScrWidth
mov cl,b$ScrHeight
cCALL B$SCNSWI ;Inform Hi-Level about dimensions change
popf ;should we SetMode
jnc NoChgMode ;go if not
mov b$ScreenRestored,1 ;Set flag for QB because screen changed
call B$ChkMonitor ; Set VGA monitor type before setting mode
call [b$SetMode] ;actually set the mode
call B$SCNCLR
jmp short Cleanup
NoChgMode:
call B$VIEWINIT ;reset viewports
Cleanup:
call B$FixTextPage
call [b$PalReset] ; reset the palette to default
mov dx,b$CURSOR ; force positioning of cursor
call B$OFFCSR
mov ax,b$OrgPages ;restore startup page selections
call [b$SetPages]
call B$GETCSRDATA ; DX = cursor positon for this page
mov b$CURSOR,dx ; update cursor position in case pages
; changed (QB can re-start after this
xor cx,cx ; reset b$KEY_SW to 0
xchg [b$KEY_SW],cl ; KEY OFF (equivalent to call B$TKEYOF)
jcxz no_keys ; brif already off
call [b$vKEYDSP] ; turn function key display off if on
no_keys: ; (clears status line). This should be
; done in the final ACTIVE=VISUAL page
cCall B$GRMODE
jz TextMode ; brif so
call B$OFFCSR ; turn off cursor for graphics modes
jmp short ResetExit
TextMode:
mov ax,b$OrgCsrTyp ; get startup cursor type
call B$CSRDSP ; display startup cursor type
ResetExit:
cEnd
;***
;B$SetDOS5Mode - Set screen mode for OS/2
;OEM-interface routine
;
;Purpose:
; Set the screen mode for OS/2.
;
; In order to perform a CHAIN command under OS/2 and pass COMMON
; variables, the normal initialization has to be avoided. What
; happens is that the parent process does not terminate immediately,
; but waits for a signal from the child process. When this occurs,
; the parent process will set some shared variables and signal the
; child, which will start a signal handler. This handler copies all
; the data from the parents data space into its own data space, using
; the shared variables set up by the parent to delimit how much
; data has to be moved. At this point, all the data is set up for
; executing the program, but the machine state has to be updated.
; Everything but the screen is set by the standard calls. This
; routine will update the screen state so that it matches the state
; of the parent, who has now terminated. To do this, it must have
; kept a record of the old state.
;
; In our implementation, we save all the information that needs to
; be passed to GIOSETMODE which is called in this routine and we
; also calculate the Segment descriptor for the video memory.
;
; This is a OS/2 only routine.
;
;Entry:
; b$Dos5Packet set as OS/2 VIO/GIO set mode data packet
;
;Exit:
; None.
;
;Uses:
; Per convention
;
;Exceptions:
; None.
;******************************************************************************
sEnd CN_TEXT
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -