home *** CD-ROM | disk | FTP | other *** search
- December 09, 1986
-
- Q SCREEN UTILITIES
- Version 2.1
-
- PURPOSE:
-
- Q screen utilities permit fast screen writes on IBM compatibles
- with MDA, CGA, and/or EGA adapters without "snow" or flicker
- effects and is compatible with ANY column format (e.g. 40/80 or
- variable). Written in Turbo Pascal inline assembler, these
- procedures are lightning fast. The code has also been condensed
- as much as possible without sacrificing speed - only 1.4k bytes
- of compiled code for all 17 procedures!
-
-
- TEST DRIVE:
-
- Compile and run QDEMO.PAS to get a feel for features and speed.
-
-
- IMPROVEMENTS:
-
- In this version, I have tried to compile the efforts of Bela
- Lubkin and Brian Foley with some concepts of my own for making
- these procedures fast, easy to use, and compatible with current
- and future products. The inline code has been revised to allow
- column formats of ANY size (e.g. 40,80, or variable) and allow
- global access to addresses and wait-for-retrace. This gives you
- the power to have multiple pages (4 on CGA and 8 on EGA) in memory
- that you already have. The filling and transfer procedures now
- work in block mode rather than line mode which is faster and much
- simpler with the use of Rows-by-Columns parameters.
-
-
- UTILITIES:
-
- In this version, QWIK21.ARC contains:
-
- Qinit .inc: Initializing procedure required to be compiled
- before all Q utilities. Also has a function to
- check for EGA cards.
- Qwrites.inc: Five Quick direct screen writing procedures:
- QwriteLV - referenced (VAR) strings, specified
- length and index.
- QwriteV - referenced (VAR) strings
- Qwrite - value strings
- QwriteC - value strings, self-centering
- QwriteCV - referenced (VAR) strings, self-
- centering
- Qfills .inc: Four Quick direct screen filling procedures
- in Rows-by-Cols block parameters:
- QfillC - repetitive filling with the same
- character and self-centering
- Qfill - repetitive filling with the same
- character
- Qattr - repetitive filling with the same
- attribute only
- QattrC - repetitive filling with the same
- attribute and self-centering
- Qstores.inc: Two Quick storing procedures:
- QstoreToMem - Saves a Rows-by-Cols block
- to memory.
- QstoreToScr - Restores a Rows-by-Cols block
- to any screen page.
- Qpage .inc: Two Quick direct screen changing procedures:
- QviewPage - Changes the page to be
- displayed - up to 8!
- QwritePage - Sets the page on which the
- Q utilities are writing. You
- don't have to write just on
- the displayed page!
- Cursor .inc: Two Quick cursor procedures:
- GotoRC - inverse of Turbo's GotoXY
- ChangeCursor - changes shape and visibility
- of the cursor; saves old, too!
- Qwik21 .inc: Has all of the above routines but compiles much
- faster because there are few comments.
- Qwik21 .doc: This document.
- Qdemo .pas: A demonstration program showing the features and
- speed of all procedures and is written for all
- cards and column modes. It also has some appli-
- cation procedures like Qbox for making windows.
- Qbench .pas: A timing program that shows "screens/second" for
- the Q utilities.
-
- Qwrites.inc and Qfills.inc work with or without attributes changes.
- (Do not run QwritesDisp and QfillsDisp alone as they are just dummy
- names for compiling.)
-
-
- PROGRAMMING:
-
- To use the procedures, just simply pick out the ones you need and
- include them in your programs. QINIT.INC must be included first.
- Be sure to read the MODIFICATIONS section below before editing
- the modules. Only one initializing statement is necessary before
- Q utilities are used (not required for cursor.inc):
-
- Qinit;
-
- This procedure automatically configures the procedures to your
- machine and also makes it portable to others.
-
-
- MODULES:
-
- The coding has been reduced by making the display loops into a
- subroutine and programming the procedures to access it. These
- were combined to make modules - two in this package. It is
- important that the procedures within the module remain in their
- present order because the CALL addresses were compiled in
- assembler and not with Turbo. But you can easily delete the
- procedures you don't need. Refer to MODIFICATIONS below.
-
-
- PARAMETERS:
-
- Row/Col - The procedures do not check for bounds on the screen,
- so be sure to stay in range. The procedures were designed for
- the upper left column on the screen to be 1,1. If you want 0,0,
- refer to MODIFICATIONS below. They also wrap to the next line;
- they do not truncate at EOL. You of course can have something
- like Row:=1 and Col:=255 which is equivalent to Row:=3 and
- Col:=15 on a screen with 80 columns.
-
- ColL/ColR - In QwriteC, QwriteCV, QfillC, and QattrC, the left
- and right columns are simply averaged. To center on the full
- width of an 80 column display, set ColL:=1 and ColR:=80. To
- center on a certain column number, set both values equal to that
- column number.
-
- Rows/Cols - They can be any positive integer to define the block
- - Rows-by-Columns starting at Row, Col. Values <=0 will simply
- abort the procedure. Please keep Cols limited to one row.
-
- Attr - The attributes range from 0 to 255. Values greater than
- 255 will be operated by modulo 256 to stay useful. Negative
- values suppress any changes to the screen attributes and use
- what's currently on the screen. For help with attribute values,
- use Brian Foley's FWATTR.INC on Borland's Programming Forum on
- CompuServe in Turbo Pascal Data Library for MSDOS. You can also
- use Turbo's TextColor and TextBackground procedures, and then
- use an absolute variable assigned at Dseg:8 (see Qdemo.pas for
- an example).
-
- Length - In QwriteLV, you can write partial strings by specifying
- the Length and starting index (St[i]). All other Qwrite procedures
- assume length is the value at St[0] and the starting index is St[1].
- Length can be any positive integer.
-
- St - The original type was set for string length of 80 characters
- which my be changed to any value between 1 and 255. Be sure to
- change all type statements to reflect it though!
-
- Source/Dest - For Qstores.inc, this can be a pointer for the heap
- or an array variable. Be sure there is sufficient room. Storage
- requirements are: (Rows * Cols shl 1) which is two bytes for
- every column. For pointers use a format such as:
-
- Type BytePtr = ^byte;
- Var MemPtr: BytePtr;
- GetMem (MemPtr,Rows*Cols shl 1);
- QstoreToMem (Row,Col,Rows,Cols,MemPtr^);
-
- Page - The page range depends upon your adapter as follows:
- MDA - On Monochrome cards, there is only page 0.
- CGA - Page 0 to 3 in modes 2 and 3 (80 column),
- page 0 to 7 in modes 0 and 1 (40 column).
- EGA - Page 0 to 7 in any mode (as I understand it).
-
- Order - You may rearrange the parameters in any order you prefer.
- The arrangement was made to facilitate readability and keeping
- the coordinates on the left side of the display.
-
-
- PAGING:
-
- If you have a CGA or better, you already have memory on your card
- for more than the 80x25 display you normally see. The two page
- procedures allow you to use Q screen utilities on these other pages
- and display which ever you choose. However, Turbo's procedures
- such as Write, Window, and GotoXY are dedicated to page 0 only.
- I have included GotoRC as one utility that works on all pages. If
- you want more procedures for this, refer to Neil Rubenking's
- VIDPAG.PAS on Borland's Programming Forum. Be sure to end your
- programs with "QviewPage (0);".
-
-
- SPEED:
-
- How fast is fast? Well, I thought it would be good idea to have
- some criteria to get a feeling for speed. The units I decided
- to use for comparison are "screens/second". To make one screen,
- a utility is repeated with a FOR loop to fill several 80x25
- pages and timed. QwriteXX use 80 character strings, and Qattr
- and Qfill use Rows:=25 and Cols:=80. At the moment, all I have
- are ratings on my own computer (AT&T 6300+) which uses Intel
- 80286. Other processors will be proportional. Monochrome (MDA)
- speeds are identical to EGA speeds.
-
- ------------------ S C R E E N S / S E C O N D ------------------
- Chng -- 80286 -- -- 8086 --- -- 8088 ---
- Procedure Attr EGA CGA EGA CGA EGA CGA
- --------- ---- ----------- ----------- ------------
- QwriteLV Yes 111.3 16.8
- No 119.5 16.8
- QwriteV Yes 112.1 16.7
- No 119.5 16.8
- Qwrite Yes 87.3 14.4
- No 92.0 14.4
- QwriteC Yes 86.8 14.3
- No 90.9 14.4
- QwriteCV Yes 111.0 16.8
- No 119.0 16.8
- QfillC Yes 244.3 21.5
- No 176.9 14.0
- Qfill Yes 246.1 21.5
- No 177.9 14.0
- Qattr Yes 177.9 14.0
- QattrC Yes 177.9 14.0
- QstoreToMem n/a 181.9 13.8
- QstoreToScr n/a 183.9 13.7
-
-
- HOW IT WAS ASSEMBLED:
-
- Turbo compiles some code before and after procedures:
-
- 1. 7 bytes before.
- 2. 7 bytes after without parameters.
- 3. 9 bytes after with parameters.
-
- So, when the modules were assembled, some dummy bytes were placed
- between the procedures to represent Turbo's compiled code which
- allowed Dave Baldwin's Inline to correctly address the calls.
- The dummy bytes were:
-
- Qwrites Module: Qfills Module:
- QwriteLV QfillC
- { 16 dummy bytes } { 16 dummy bytes }
- QwriteV Qfill
- { 16 dummy bytes } { 16 dummy bytes }
- Qwrite QfillsDisp
- { 16 dummy bytes } { 14 dummy bytes }
- QwritesDisp Qattr
- { 14 dummy bytes } { 16 dummy bytes }
- QwriteC QattrC
- { 16 dummy bytes }
- QwriteCV
-
-
- MODIFICATIONS:
-
- Deleting Procedures - If you want to delete some procedures
- within a module, just follow this simple rule:
-
- Delete from the outside in.
-
- You can delete the procedures surrounding QwriteDisp and
- QfillsDisp, but you cannot for example delete QwriteC without
- also deleting QwriteCV. You of course can delete a whole module.
- Do not attempt to rearrange the procedures within a module unless
- you feel confident with modifying the CALL addresses.
-
- Base Coordinates - If you want to change the upper left corner to
- be 0,0 instead of 1,1, you need to do the following on the inline
- codes described with "Convert to 0-?? range":
-
- 1. In QwriteLV, QwriteV, Qwrite, Qfill, and Qattr replace
- DEC DI with NOP which has an inline code of $90.
- 2. In QwritesDisp and QfillsDisp, replace DEC DX and DEC AX
- with NOP.
- 3. In QwriteC, QwriteCV, QfillC, and QattrC change DEC DI to
- INC DI which has a inline code of $40.
- 4. In QstoreToMem and QstoreToScr, replace DEC AX, DEC SI
- and DEC DI with NOP.
-
-
- Qinit.inc - This include file sets up the global variables for the
- Q utilities and was designed for full compatibility with MDA, CGA
- and EGA cards. You can still modify it to fit your needs. It is
- not required for the cursor procedures.
-
-
- CREDITS:
-
- Without the assistance and original ideas from Brian Foley
- [76317,3247], these routines would not have been written. In
- addition, Dave Baldwin's InLine Assembler was essential in its
- development.
-
- Copyright (c) 1986 by Jim LeMay
- These procedures may be used and distributed without profit in
- private contexts. I must be contacted for any other use.
-
- If there are any problems such as snow, please let me know.
- Jim LeMay [76011,217] (1-817-735-4833 after 1800 CST )
- 6341 Klamath Rd., Ft. Worth, TX, 76116.
-
- APPENDIX:
-
- Quick Reference List of all procedures and parameters:
-
- Qinit;
-
- QwriteLV (Row, Col: byte; Attr, Length: integer; VAR St);
- QwriteV (Row, Col: byte; Attr: integer; VAR St);
- Qwrite (Row, Col: byte; Attr: integer; St: Str80);
- QwriteC (Row, ColL, ColR: byte; Attr: integer; St: Str80);
- QwriteCV (Row, ColL, ColR: byte; Attr: integer; VAR St);
-
- QfillC (Row, ColL, ColR, Rows, Cols: byte; Attr: integer; Ch: char);
- Qfill (Row, Col, Rows, Cols: byte; Attr: integer; Ch: char);
- Qattr (Row, Col, Rows, Cols: byte; Attr: integer);
- QattrC (Row, ColL, ColR, Rows, Cols: byte; Attr: integer);
-
- QstoreToMem (Row, Col, Rows, Cols: byte; VAR Dest);
- QstoreToScr (Row, Col, Rows, Cols: byte; VAR Source);
-
- QviewPage (Page: byte);
- QwritePage (Page: byte);
-
- GotoRC (Row, Col: Byte);
- CursorChange (New: integer; VAR Old: integer);
-
-
- REVISIONS:
-
- Version 1.1 (10-31-86):
- Improved speed about 15%.
- Corrected segment error for Mono mode.
-
- Version 1.2 (11-04-86):
- Added self-centering routines.
- Added document and complete demo.
-
- Version 1.3 (11-10-86):
- Reduced assembly code 60% by using modules.
- Added CursorChange utility.
- Improved speed on Qfill and Qattr about 5%.
- Corrected Qfill bug. (Extra characters were added when
- attr<0 and Cols=even.)
- Changed EGA detection to use Mono rather than CGA loops.
- Added page capability to GotoRC.
-
- Version 2.0 (11-24-86):
- Complete revision for global access to paging, retrace, and
- segment address. Permits formats in any column mode (40
- 80,120, or whatever).
- Changed Qfill and Qattr for easier Row-by-Column blocks.
- Added QfillC and QattrC for self-centering.
- Added two page utilities.
- Added two screen memory transfer utilities for Row-by-Column
- blocks.
- Increased speed of Qfill with attribute on CGA by 65%.
-
- Version 2.1 (12-09-86):
- Added QwriteLV for partial string writing.
- Added interrupt enable in QwritesDisp and QfillsDisp at
- the end of writing in the vertical band for color.
- Fixed bug in QstoresToScr to access other segments.
- Modified Qdemo.pas for MDA and any column mode.
- Added Qbench.pas to check speed on your own system.
-