Code: Select all
Defint A-Z
'$Dynamic
Dim Storage(1999)
FirstLine = 1
LastLine = 5
Cls
For X = 1 To 15
Color X
Print String$(80, X + 64);
Next
Locate 20
Print "Press a key to save the screen";
While Inkey$ = "" : Wend
'Call Ptr86(Segment, Address, Varptr(Storage(0))) ' For QB 3.00.
Segment=VARSEG(Storage(0)) ' For QB 4.00
Address=VARPTR(Storage(0)) ' For QB 4.00
Call ScrnSave(FirstLine, LastLine, Segment, Address)
Cls
Print "Press a key to restore the top";
While Inkey$ = "" : Wend
'Call Ptr86(Segment, Address, Varptr(Storage(0))) ' For QB 3.00.
Segment=VARSEG(Storage(0)) ' For QB 4.00
Address=VARPTR(Storage(0)) ' For QB 4.00
Call ScrnRest(FirstLine, LastLine, Segment, Address)
The following is SCRNSAVE.ASM, an assembly language routine. SCRNSAVE.ASM saves a portion of the text screen in QuickBasic:
Code Segment Byte Public 'Code'
Assume CS:Code
Public ScrnSave
ScrnSave Proc Far
Begin: Push BP ;save registers for Basic
;* Push DS DELETE THIS LINE
Mov BP,SP ;locate stack to get variable
;addresses later
PUSH DS ;* SAVE THE DATA SEGMENT
PUSH ES ;* SAVE THE EXTRA SEGMENT
Mov DX,0 ;look at low memory using ES
Mov ES,DX
Mov BX,0B000h ;assume monochrome screen segment for
;now
Mov AL,ES:[410h] ;get the equipment list
And AL,48 ;just look at the monitor type
Cmp AL,48 ;is it monochrome?
JZ Get_Params ;if yes, skip over adding 800h
Add BX,800h ;if no, adjust for color-screen memory
Mov AL,ES:[487h] ;if an EGA is present, AL will not be
;zero
Cmp AL,0 ;is it an EGA?
JNZ Get_Params ;if yes, leave DX set to zero as a
;flag for later
Mov DX,3DAh ;if no, specify the port to check for
;retrace
Get_Params: Push BX ;save the screen segment for later
;* Mov SI,[BP+08] ;get the starting address of the
;storage array
;* change to BP+6
Mov SI,[BP+06] ;get the starting address of the
;storage array
Mov DI,[SI] ;and put it into DI
;* Mov SI,[BP+10] ;get the segment for the array
;* change to BP+8
Mov SI,[BP+8] ;get the segment for the array
Mov ES,[SI] ;and assign it to ES
;* Mov SI,[BP+12] ;get the address for LastLine
;* change to BP+10
Mov SI,[BP+10] ;get the address for LastLine
Mov AL,[SI] ;and put it into AL
Mov CL,160 ;prepare to multiply times 160
Mul CL ;now AX holds the last screen address to
;save
Mov BX,AX ;save it in BX for later
;* Mov SI,[BP+14] ;get the address for FirstLine
;* change to BP+12
Mov SI,[BP+12] ;get the address for FirstLine
Mov AL,[SI] ;put it into AL
Dec AL ;adjust 1-25 to 0-24
Mul CL ;calculate actual starting address on
;screen
Mov SI,AX ;now SI points to the source address
Sub BX,AX ;calculate the number of bytes to copy
Mov CX,BX ;put it into CX for Rep or Loop below
Shr CX,1 ;divide CX by 2 to obtain the number of
;words
Pop DS ;retrieve the screen segment saved
;earlier
Cld ;all data moves below will be forward
Cmp DL,0 ;are we doing monochrome or EGA?
JZ Mono ;if monochrome, skip over the retrace
No_Retrace: In AL,DX ;get the video-status byte
Test AL,1 ;test just the horizontal retrace part
JNZ No_Retrace ;if doing a retrace, wait until it is
;not
Retrace: In AL,DX ;get the status byte again
Test AL,1 ;are we currently doing a retrace?
JZ Retrace ;if no, wait until we are
Lodsw ;now get the word from the screen
Stosw ;and put it into the array
Loop No_Retrace ;loop until done
Jmp Exit ;skip over the monochrome routine and
;exit
Mono: Rep Movsw ;move the data in one operation
Exit: POP ES ;* ADD THIS LINE
Pop DS ;restore registers for Basic
Pop BP
Ret 8 ;return skipping the passed parameters
ScrnSave Endp
Code Ends
End ;* REMOVE THE LABEL Begin
The following is SCRNREST.ASM, which restores a portion of the text screen in the QuickBasic program:
Code Segment Byte Public 'Code'
Assume CS:Code
Public ScrnRest
ScrnRest Proc Far
Begin: Push BP ;save registers for Basic
;* Push DS DELETE THIS LINE
Mov BP,SP ;locate stack to get variable addresses
;later
PUSH DS ;* ADD THIS LINE
PUSH ES ;* ADD THIS LINE
Mov DX,0 ;look at low memory using ES
Mov ES,DX
Mov BX,0B000h ;assume monochrome screen segment for
;now
Mov AL,ES:[410h];get the equipment list
And AL,48 ;just look at the monitor type
Cmp AL,48 ;is it monochrome?
JZ Get_Params ;if yes, skip over adding 800h
Add BX,800h ;if no, adjust for color-screen memory
Mov AL,ES:[487h];if an EGA is present, AL will not be
;zero
Cmp AL,0 ;is it an EGA?
JNZ Get_Params ;yes, leave DX set to zero as flag for
;later
Mov DX,3DAh ;no, specify the port to check for
;retrace
Get_Params: Mov ES,BX ;set ES to the appropriate screen
;segment
;* Mov DI,[BP+12] ;get the address for LastLine
;* change to BP+10
Mov DI,[BP+10] ;get the address for LastLine
Mov AL,[DI] ;and put it into AL
Mov CL,160 ;prepare to multiply times 160
Mul CL ;now AX holds last screen address to
;restore
Mov BX,AX ;save it in BX for later
;* Mov DI,[BP+14] ;get the address for FirstLine
;* change to BP+12
Mov DI,[BP+12] ;get the address for FirstLine
Mov AL,[DI] ;put it into AL
Dec AL ;adjust 1-25 to 0-24
Mul CL ;calculate actual starting address on
;screen
Mov DI,AX ;now DI points to the destination
;address
Sub BX,AX ;calculate the number of bytes to copy
Mov CX,BX ;put it into CX for Rep or Loop below
Shr CX,1 ;divide CX by 2 to obtain the number of
;words
;* Mov SI,[BP+10] ;get the segment of the storage
array
;* change BP + 8
Mov SI,[BP+8] ;get the segment of the storage array
Mov AX,[SI] ;and save it in AX for a moment
;* Mov SI,[BP+08] ;get the address of the first array
;element
;* change to BP+6
Mov SI,[BP+06] ;get the address of the first array
;element
Mov SI,[SI] ;and put it into SI
Mov DS,AX ;okay to change DS after getting all
;variables
Cld ;all data moves below will be forward
Cmp DL,0 ;are we doing monochrome or EGA?
JZ Mono ;if monochrome, skip over the retrace
No_Retrace: In AL,DX ;get the video status byte
Test AL,1 ;test just the horizontal retrace part
JNZ No_Retrace ;if doing a retrace, wait until it is
;not
Retrace: In AL,DX ;get the status byte again
Test AL,1 ;are we currently doing a retrace?
JZ Retrace ;if no, wait until we are
Lodsw ;now get the word from the screen
Stosw ;and put it into the array
Loop No_Retrace ;loop until done
Jmp Exit ;skip over the monochrome routine and
;exit
Mono: Rep Movsw ;move the data in one operation
Exit: POP ES ;* ADD THIS LINE
Pop DS ;restore registers for Basic
Pop BP
Ret 8 ;return skipping the passed parameters
ScrnRest Endp
Code Ends
End ;* REMOVE THE LABEL Begin