home *** CD-ROM | disk | FTP | other *** search
- ;«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
-