home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
QBAS
/
VIDBASIC.ZIP
/
VPRINTL.ASM
< prev
next >
Wrap
Assembly Source File
|
1990-11-29
|
13KB
|
340 lines
;«RM82»«TS8,16,24,32,40,48,56,64»
; Updated 11/20/90
;============================================================================
; Copyright (C) Copr. 1990 by Sidney J. Kelly
; All Rights Reserved.
; Sidney J. Kelly
; 150 Woodhaven Drive
; Pittsburgh, PA 15228
; home phone 412-561-0950 (7pm to 9:30pm EST)
;============================================================================
DOSSEG
.model medium, Basic
.data
;external data so all video routines can access
EVEN
EXTRN B$DVIDEOSEG:WORD
EXTRN B$DVIDEOPORT:WORD
EXTRN B$DVIDEODI:WORD
EXTRN B$DVIDEOINSTL:BYTE
.code
INCLUDE NOWAIT.INC
EXTRN Get_Adapter:FAR
EXTRN SET_DI:FAR
.code
EVEN
VPageSize dw 3998 ; default page size of 80 x 25
VDI_Reset dw 3840 ; default offset of Row 25, col 1
VAttrib db 7 ; default color of white on black
VRow db 24 ; default number of rows (0 bias)
VColumn db 79 ; default number of columns (0 bias)
;===========================================================================
; DECLARE SUB SETQP (BYVAL ROW%, BYVAL COLL%, BYVAL Attribute%)
; CALL SETQP(ROW%, COLL%, Attribute%)
; Purpose:
; Initializes varibles, and sets DI to target address. This is the
; initialization routine for QPRINTL. Selects the attribute used to
; scroll the display upward.
; Assumes that user wants to set page size to full size of current dsp
; such as 80 x 25, 80 x 43, or 80 x 50
;===========================================================================
EVEN
SETQP PROC FAR BASIC USES SI DI, ROW:WORD, COLL:WORD, ATTRIB:WORD
Assume DS:@data
Cmp B$DVIDEOINSTL,1 ;See if we have done this before
JE Didit ; yep, so skip ahead
Call Get_Adapter ; call routine to find display type
Didit:
Mov BX,ATTRIB ; read attribute from stack
Or BL,BL ; make sure that BL <> 0
JNZ @f ; if BL <> 0 then skip ahead
Mov BX,7 ; else give normal attribute
@@:
Mov VAttrib,BL ; store attribute
Mov BX,ROW ; read value of Row
Dec BX ; convert to BIOS format
Cmp BX,24 ; check if within range 1 to 25
JBE @f ; if w/in bounds o.k.
Xor BL,BL ; else make it Row 1
@@:
Mov DH,BL ; store ROW (BL) in DH
Mov BX,COLL
Dec BX ; convert to BIOS format
Cmp BX,79 ; check if within range 1 to 80
JBE @f ; if w/in bounds o.k.
Xor BL,BL ; else make it Column 1
@@:
Mov DL,BL ; store COLL (BL) in DL
CALL SET_DI ; call routine to find video seg offset in DI
Mov B$DVIDEODI,DI ; store DI
Xor AX,AX ; read current bios values
Mov ES,AX ; set ES to BIOS ram area
Xor BH,BH ; clear high byte
Mov BL,Byte Ptr ES:[0484h] ; read ROW from BIOS ram
Or BL,BL ; is ROW 0? (i.e. is this CGA, HERC or MONO?)
JNZ @f ; nope, it is a EGA, MCGA or VGA
Mov BL,24 ; set default ROW to 24
@@:
Mov VRow,BL ; store number of ROW
Inc BL ; remove 0 bias of ROW
Mov AX,ES:[044Ah]; read COLUMN from BIOS ram
Dec AL ; make it zero biased
Mov VColumn,AL ; store number of columns with 0 bias
Inc AL ; remove zero bias
Mul BX ; multiply ROW times COLUMN
Add AX,AX ; multiply AX by 2 (3 clocks on 8088)
Sub AX,2 ; reduce by 2 (3 clocks on 8088)
Mov VPageSize,AX ; store Page_Size in memory
Xor AH,AH ; clear AH
Mov BH,AH ; also clear BH
Mov AL,VRow ; get row in AL (it is 0 biased)
; the following shows the work necessary
; if you allow display widths other than 80
Mov BL,VColumn ; load number of columns into BL
Inc BL ; remove zero bias
Add BX,BX ; multipy Column times 2
Mul BX ; multiply Rows * (Columns * 2)
Mov VDI_Reset,AX ; store result from AX in VDI_Reset
; this is offset of Last line, Column 1
Ret
SETQP ENDP
;===========================================================================
; DECLARE SUB QPRINTL (Text$)
; CALL QPRINTL(Text$)
; Usage: CALL SETQP(ROW%, COLL%, Attribute%) the first time to set
; the defaults to current display size. Then QPRINTL on down the display.
; You should use SETQP to start, since scroll routine needs the proper
; attribute to scroll the screen up.
;
; Purpose:
; To work similarly to PRINT Text$;
;
; Major differences are:
; a) Assumes that a VIEW PRINT has been executed
; b) will not parse the Text$ and start a new line if length of
; Text$ is longer than remaining space on current line. PRINT
; is designed for formatted column printing, while this
; routine is not.
; c) if at Last Row, Column 80, QPRINTL will scroll the display
; can't stop it.
;
; Speed:
; Varies with length of Text$ and length of display
; for a color EGA on a 10 Mhz AT, the speed varies from 3% faster
; (if LEN(Text$) = 80) to 48% faster.
; Typical speed increase is 12%
;===========================================================================
EVEN
QPRINTL PROC FAR BASIC USES SI DI, TEXTSTRG:WORD
Mov ES,B$DVIDEOSEG ; restore the initialized values
Mov DX,B$DVIDEOPORT ; puts 0 in DX if not CGA
Mov BL,VAttrib ; get attribute
Mov AH,BL ; store attribute in AH
Mov BH,BL ; store attribute in BH too for use in _Rollup
Mov SI,TEXTSTRG ; put descriptor to TEXT$ into SI
Mov CX,[SI] ; put Len(TEXT$) into CX for loop counter
JCXZ Exit1 ; if CX is zero it's a null string, exit now
Mov SI,[SI+02] ; put address of first character in X$ into SI
Cld ; clear the direction flag to move data forward
Mov DI,B$DVIDEODI ; set DI to reflect last call
Main_Loop:
Or DX,DX ; are we on a mono or EGA system (is DX = 0)?
JZ Mono ; yes, skip over the retrace stuff
EVEN
CGA:
CLI ; prevent interrupts to speed routine
Wait_CGA_Retrace ; wait for CGA retrace MACRO
Lodsb ; get character from TEXT$ and increment SI
Stosw ; store both the character and attribute
STI ; allow interrupts again
Cmp DI,3998 ; are we at last character? (80 * 25) display
JBE @f ; nope
Call _Rollup ; scroll up & reset to left column
@@:
Loop CGA ; loop until CX is zero
Jmp Short Exit1
EVEN
Mono:
Lodsb ; get character from TEXT$ and increment SI
Stosw ; store both the character and attribute
Cmp DI,VPageSize ; are we at last character?
JBE @f ; nope
Call _Rollup ; scroll up & reset to left column
@@:
Loop Mono ; loop until CX is zero
Exit1:
Mov B$DVIDEODI,DI ; store DI for the future
Ret
QPRINTL ENDP
;===========================================================================
; DECLARE SUB VADDR (Row%, Column%)
; CALL VADDR(Row%, Column%)
; returns the current end of string address for the qprint routines
;===========================================================================
EVEN
VADDR PROC FAR BASIC, ROW:WORD, COLL:WORD
Xor DX,DX ;clear DX
Mov AX,B$DVIDEODI ;get current DI
Mov BX,160 ;set divisor at 160 for 80 column display
Div BX ;divide AX by BX. Row in AX, remainder in DX
Inc AX ;remove zero bias
SHR DX,1 ;divide remainder by 2 then increment
Inc DX ;to remove zero bias
Mov BX,ROW ;store values
Mov [BX],AX
Mov BX,COLL
Mov [BX],DX
Ret
VADDR ENDP
;=======================================================================
; _Rollup: a local routine that scrolls up the last line of a display
; using the attribute stored in BH. If SETQP is run, then
; is sensitive to current display length.
; Input:
; Attribute in BH
; Preserves:
; AX,BX,CX,DX
; Returns:
; Screen scrolled up one line, DI reset to Last Line, Col 1
; About as fast as dedicated version below, and neatly handles snowy CGA's.
;
;=======================================================================
EVEN
_Rollup Label Near ;Label used so routine name will not
Push AX ;be public.
Push BX
Push CX
Push DX
Mov AX,0601h ;scroll up one row
Xor CX,CX ;window at 1,1
Mov DH,VRow ;put row in DH
Mov DL,VColumn ;put column in DL
Int 10h ; doit
Mov DI,VDI_Reset ; reset DI to Last Row, Col 1
Pop DX
Pop CX
Pop BX
Pop AX
Retn ; routine is near!!
;end of routine
comment |*
;=======================================================================
; _Rollup: a local routine that scrolls up the last line of a
; 80 x 25 display, using the attribute stored in BH
; not yet corrected for snow on a CGA
;
; Input:
; Attribute in BH, Video Segment in ES, Direction flag cleared
; Preserves:
; AX,BX,CX,DX,DS,SI
; Returns:
; Screen scrolled up one line, DI reset to Row 25, Col 1
;=======================================================================
_Rollup Label Near ;Label used so routine name will not
Push AX ;be public.
Push CX ; save all registers used
Push SI
Push DS ; save DS
Mov AX,ES
Mov DS,AX ; set DS == ES
Mov SI,160 ; copy block of 2,1 to 25,80
; to 1,1 to 24,80
Mov CX,2000-80 ; page size in words
Xor DI,DI ; destination of 1,1 (0 based)
Rep Movsw ; do scroll
Mov CX,80 ; number of characters on bottom line
Mov AH,BH ; get attribute from BH
Mov AL,32 ; put space character in AL
Rep Stosw ; clear bottom line
Mov DI,3840 ; reset DI to Row 25, Col 1
Pop DS ; get back DS
Pop SI
Pop CX ; restore all registers used
Pop AX
Retn ; routine is near!!
;end of routine
|*
;===========================================================================
; DECLARE SUB CLREOL ()
; CLREOL
; Purpose:
; Clears to end of current display line w/o changing attribute
; Assumes:
; 80 Column mode, assumes that DI has been set by SETQP; QPRINT;
; QPRINTL; or QPRNT
;===========================================================================
EVEN
CLREOL PROC FAR BASIC
Cmp B$DVIDEOINSTL,1 ; See if we have done this before
JE Didit3 ; yep, so skip ahead
Call Get_Adapter ; call routine to find display type
Didit3:
Cld ; clear the direction flag to move data forward
Mov AX,B$DVIDEODI ; get DI from last call
Mov DI,AX ; set DI to reflect last call
Xor DX,DX ; clear DX
Mov BX,160 ; set divisor at 160 for 80 column display
Div BX ; divide AX by BX. COL*2 (remainder) in DX
SHR DX,1 ; divide remainder by 2
Or DX,DX ; if column is 1
Jz Exit2 ; exit as there is nothing to do
Mov CX,80 ; Assume in 80 column Mode
Sub CX,DX ; this gives number of spaces to print
Mov ES,B$DVIDEOSEG ; restore the initialized values
Mov DX,B$DVIDEOPORT ; puts 0 in DX if not CGA, else CGA retrace
Mov AL,20h ; character to erase with (a space)
Main:
Or DX,DX ; are we on a mono or EGA system (is DX = 0)?
JZ Mono1 ; yes, skip over the retrace stuff
Mov BL,AL ; store in BL for rapid loading
EVEN
CGA1:
CLI ; prevent interrupts to speed routine
Wait_CGA_Retrace ; wait for CGA retrace MACRO
Mov AL,BL ; get character back again (MACRO destroys it)
Stosb ; store the character only
STI ; allow interrupts again
Inc DI ; skip to next cell
Loop CGA1 ; loop until CX is zero
Jmp Short Exit2
EVEN
Mono1:
Stosb ; store the character w/o changing attribute
Inc DI ; skip to next cell
Loop Mono1 ; loop until CX is zero
Exit2:
Mov B$DVIDEODI,DI ; store DI for the future
Ret
CLREOL ENDP
END