home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / QBASIC / VIDBASIC.ZIP / HELP.DOC < prev    next >
Encoding:
Text File  |  1990-11-29  |  48.6 KB  |  977 lines

  1.  
  2. ;Video routine short instruction list
  3.  
  4. ========================================================================
  5.     Copyright (C) Copr. 1990 by Sidney J. Kelly
  6.             All Rights Reserved.
  7.             Sidney J. Kelly
  8.             150 Woodhaven Drive
  9.             Pittsburgh, PA 15228
  10.             home phone 412-561-0950 (7pm to 9:30pm EST)
  11.  
  12.      CompuServ   70043,1656
  13.      Genie       S.KELLY8
  14.  
  15. ========================================================================
  16.  
  17.           The following routines are designed to do something
  18. useful to text without regard to the type of monitor actually
  19. installed.  These routines are text mode primitives.  In most
  20. cases that give you direct control over the hardware in a fashion
  21. that cannot be done except in assembly language.  You can save
  22. the display, write characters or attributes at high speed to the
  23. display, or write to the display using DOS compatible modes to
  24. allow you to use multi-taskers or ANSI.SYS.  You can change text
  25. or attributes on the display.  You can adjust cursor size, turn
  26. off blinking, BLOAD help files, etc.
  27.           These routines are part of a larger freeware library of
  28. QBASIC routines that is currently under construction.  The full
  29. version will be released two days AFTER an OOPS version of QBASIC
  30. is released by MICROSOFT-- at which time few will want to use
  31. these routines.
  32.           Why these were written:
  33.           I originally wrote these routines to parrot Dick Evers
  34. window routines written exclusively in BASIC (You can see his
  35. influence in the demo program).  Then an old issue of PC Magazine
  36. showed how to call MASM video routines from QBASIC, which I think
  37. is based on an earlier BYTE magazine article.  Other PC Magazine
  38. routines, and the discussions about IBM Technical reference video
  39. adapter recognition routines, showed how to identify display
  40. types using just BIOS calls.  Then the quest began: I began my
  41. search of back issues of PC Magazine for programming tidbits, I
  42. bought old assembly language guide books back with the earth was
  43. fresh and the IBM PC with 64kb of memory and two floppies was a
  44. wonder to behold, searched the standard databases for public
  45. domain routines; read more programming books, etc.  The
  46. bibliography at the end of this document should answer your
  47. requests for additional information.
  48.           The video display was selected for improvement because
  49. that is one area a user can really notice the difference between
  50. fast code and slow code.  Some of these routines allow you to do
  51. things that are impossible otherwise.  Other routines allow you
  52. to do something much faster and in an attractive fashion.  All
  53. the routines avoid the agony of using ON ERROR GOTO traps.
  54.           Programmers Assumptions:
  55.           These routines are designed to work with MONO, CGA,
  56. HERC, MCGA (mostly color, though generally untested), EGA (mono
  57. or color, 25 or 43 line mode), and VGA (mono or color, 25 or 50
  58. line mode).  In a very limited way, the routines support dual
  59. displays.  These routines assume that the display width is 80
  60. columns wide, mostly because there is no known way to determine
  61. in advance if a particular user's display will support 132 column
  62. mode.  Anyway that is QBASIC's assumption too.  More importantly
  63. I don't own a multi sync display, and I do not access to 10 types
  64. of EGA and 50 types of VGA displays that are necessary to test
  65. everything out on.  Finally, there are several shareware
  66. libraries that already have some of the ATI, Paradise, VESA and
  67. Video Seven EGA/VGA routines built in.  Unfortunately, after
  68. looking at the freeware version of FRACINT (a nifty graphics time
  69. waster that draws fractals), it appears that there are about five
  70. or six different ways to switch displays into high resolution
  71. mode.  Even FRACINT requires the user to select the display type.
  72. (How can I convince my wife that I need a register compatible
  73. 8514/A display and adapter for the ultimate in text mode
  74. displays??????????).
  75.           It is possible to devote many hours to routines for
  76. hardware 95% of the users wont have or need in text mode.  Most
  77. of the direct screen routines use macros that are hard coded for
  78. an 80 column width display. (Lengths of 25, 43, and 50 are
  79. allowed).  This is done for speed in case the poor user only has
  80. a CGA on a PC clone (he needs all the speed he can get).  To show
  81. how it is done, I have included a few routines that actually do
  82. use the BIOS ram data areas to determine the current display
  83. width.
  84.           QBASIC Theory.
  85.           Aside from the current DEF SEG setting, most of QBASIC
  86. video information storage registers are not available inside the
  87. QB.EXE environment, though it is available inside the .EXE
  88. program (which makes testing the routines way too time
  89. consuming).  My routines had to come up with such information
  90. independently.  My solution is store the key variables in the
  91. default data segment in QBASIC (its name in MASM is DGROUP).  To
  92. save space in DGROUP, only 7 bytes of information is kept by the
  93. video routines.  This allows transparent sharing of the
  94. information.  The reason for such "stupid" names (B$V...) for the
  95. DGROUP variables is to only give the MASM routines access to such
  96. information, and prevent normal QBASIC routines (or someone
  97. else's library routines) from messing them up.
  98.           Generally QBASIC only keeps simple variables, (INT,
  99. LONGINT, SINGLE and DOUBLE, and STRINGS) in DGROUP.  Arrays and
  100. TYPE records are usually kept outside DGROUP, with only the
  101. STRING Descriptor or the undocumented Array descriptor kept in
  102. DGROUP.  Thus, the library routines assume that all information
  103. passed from simple variables is information about a near (DGROUP)
  104. address.  If we pass simple integers to MASM routines, and don't
  105. care to have MASM change those variables, we use BYVAL to send
  106. the information to MASM.  If we want to have MASM send
  107. information back about multiple variables, we pass the address
  108. information for the variables without using BYVAL.  If we use
  109. arrays, we must use a combination of BYVAL and VARSEG and VARPTR
  110. to get the information we need to manipulate the information
  111. inside the arrays.  VARSEG and VARPTR are necessary because there
  112. is a very great chance that the arrays will be stored as far data
  113. (i.e. not stored in DGROUP).
  114.           Text strings are sent by QBASIC as near address
  115. (relative to DS and DGROUP).  The fist value in the descriptor is
  116. the length of the string.  The second value is the offset address
  117. inside DGROUP.  Fixed length strings are not referenced with
  118. string descriptors.  For that reason, I don't allow such strings
  119. as variables in my routines.
  120.           QBASIC requires that MASM preserve BP, SI, DI, DS, and
  121. keep the direction flag clear (CLD).  All these routines do this.
  122. You will note that MICROSOFT'S CALL INTERRUPT routines do not
  123. save BP (apparently to give you access to some EGA VGA palette
  124. and character font selection routines in the BIOS), and thus will
  125. crash if a critical error occurs.  MICROSOFT offers a replacement
  126. routine, that overcomes this error by preventing any change to
  127. BP.  You should get it if you don't already have it.
  128.           The choice of defining MASM routines as SUB's or
  129. FUNCTION's depends on whether you want to get information from
  130. MASM in DX:AX (the format for FUNCTIONs), or if the MASM routine
  131. either sends back no information or more than one variable (the
  132. format for SUBs).  For simple one variable routines when MASM is
  133. just returning a value, use FUNCTIONs.  To use such functions
  134. inside QBASIC you must either assign the value of the function to
  135. a QBASIC variable or use IF ... THEN statements (C style).  For
  136. everything else use SUBS.
  137.           Note due to an error in the QBASIC parser, always use
  138. the CALL keyword to call the library routines if there is any
  139. chance that you will use a colon as a separator on a line.
  140. Without the CALL keyword, the QBASIC parser assumes that the
  141. routine name followed by a colon is intended as a line label, and
  142. not as a SUB name.  You must use CALL if you will use a SUB that
  143. does not need any parameters and will follow that SUB name by a
  144. colon.
  145.           CGA Theory:
  146.           The CGA is a slow, and sometimes snowy display.  These
  147. routines deal with snow in four ways.  If the CGA is good display
  148. (e.g. COMPAQ, AT&T, or ZENITH) then snow checking can be turned
  149. off automatically.  If a user has a CGA display that does not
  150. display snow (one of many clones, none of which I have access to
  151. or have tested), he can use TOGGLESNOW to turn snow checking off.
  152. The routine can assume the that CGA is snowy and turn off the CGA
  153. for a instant, then turn it back on.  This causes flicker, but I
  154. use when I am changing the entire display.  See BLOADHELP.  The
  155. last alternative is to delay writing words or bytes to the
  156. display until the display is in either vertical or horizontal
  157. retrace mode.  This can be fast (1.5 times as fast as QBASIC's
  158. PRINT routine, while if snow checking is turned off these
  159. routines are 5 to six times faster than QBASIC library routines).
  160. Hardware interrupts are temporarily turned off, so a timer tick
  161. or a keystroke will not upset the counting and writing routines.
  162. The routines generally only allow enough time to read and write
  163. one word.  If any further manipulation is required, the wait-for-
  164. retrace loop has to be re-entered a second time.  For speedier
  165. displays (MONO, HERC, EGA, VGA and MCGA), a jump is made to a
  166. faster routine that does not have to wait for retrace.
  167.           There is a fifth way to avoid snow on a CGA, and that
  168. is send one word while the video display is in horizontal retrace
  169. and 400 words while in vertical retrace mode.  However, that was
  170. considered too complicated.  See, Wilton, "Programmer's Guide to
  171. PC & PS/2 Video Systems" (Microsoft 1987).
  172.           Video Theory:
  173.           Video memory in text mode starts at segment &HB000 for
  174. mono displays, and &HB800 for color displays.  The offset of the
  175. first page is 0, then &H1000 (80 x 25) for as many pages as are
  176. allowed.  The screen has no internal divisions representing ROWS
  177. and COLUMNS (except in HERC and CGA graphics modes), it simply is
  178. a logical concept.  At the BIOS/hardware level, for purposes of
  179. displaying a character, the upper left is 0,0 and lower right of
  180. the display in SCREEN 0: WIDTH 80,25  is 24,79.  Thus the
  181. location of a particular word on the display is (Row (0 biased)
  182. times 160 plus Column) times 2.  The 160 is merely 80 columns
  183. times two bytes (character and attribute).  That figure is
  184. hardcoded in my routines so I can use shifts rather than MUL's on
  185. old PC's and speed up the video location MACROS.  On an 8088,
  186. shifts are faster then MUL's (some of the macros show the clocks
  187. for shifts versus MUL's on an 8088 and on an 80286).  When
  188. writing to the display, the attribute is stored (and read into)
  189. in AH, and the character is stored (and read into) in AL.  To
  190. only write characters or attributes, the routines increment DI
  191. (usually) after every write.  This allows certain routines to
  192. write to the display sending only characters or only attributes.
  193.           MASM Theory:
  194.           The MASM routines were designed to be compiled with MS
  195. QUICK ASSEMBLER, using simplified segment names.  They should
  196. compile with MS MASM 5.1 and above.  The DOSSEG keyword might not
  197. be supported in MASM, so use the MASM keyword that arranges the
  198. segments in DOS order, rather than ALPHA order.  If you use TASM
  199. with QUIRKS (IDEAL too?) you should be able to compile these
  200. programs with TASM.  Because A86 does not make MS .OBJ files, you
  201. probably cannot use it.  The same may be true with OPTASM.
  202.           The simplified directives really save time when you
  203. have to identify variables on the stack, and push and pop
  204. variables.  I use the full PROC function and the regular PROC
  205. keywords interchangeably.  Full PROC format is not necessary when
  206. there is no need to address variables on the stack (i.e. no need
  207. to change BP to address the stack) and the QBASIC routine is
  208. described as a FUNCTION.
  209.           The EVEN directive is used to word align loops for
  210. 80286 and 80386 machines.  EVEN inserts NOPS as necessary to word
  211. align loops.  The QBASIC BYVAL directive is used to get
  212. information directly from QBASIC without having to use [BX] or
  213. [SI] to fish out the correct information.  You will note that DS
  214. and OFFSET are used in an unusual way in these routines.  The
  215. string move MASM opcodes use DS:SI (source) to move video bytes
  216. to ES:DI (destination).  We have to wait to set DS to the proper
  217. address until we have removed information from the stack, as DS
  218. must point to DGROUP to properly use the stack.  In addition,
  219. OFFSET is faster than LEA to address information in .CODE
  220. segment.  However, for OFFSET to work, MASM must be told that
  221. ASSUME DS:NOTHING, ES:NOTHING.  This makes the offset relative to
  222. beginning of code segment, and not relative to DGROUP (which is
  223. the default if simplified segments are used).  Should anyone have
  224. problems with this, please let me know.   To allow for
  225. compatibility with the 8088 chip, shifts rather than MULs are
  226. used for speed.  I use .code to store most of my variables to
  227. save space in DGROUP, which is comparatively tiny and easily
  228. filed with string data.
  229.           To program in OS/2 .code segment variables are
  230. verbotten, and you must use local variables on the stack.  I
  231. don't have access to the OS/2 DOS compatibility box, so I don't
  232. know how these routines would work under OS/2.  I am certain that
  233. none of these routines would work smoothly under protected mode.
  234.  
  235.  Video routine short instruction list
  236.  ===========================================================================
  237.   DECLARE SUB BACKFILL _
  238.  (BYVAL ULR%, BYVAL ULC%, BYVAL LRR%, BYVAL LRC%, BYVAL ATTRIB%, BYVAL TEXTCHAR%)
  239.   CALL BACKFILL(ULR%, ULC%, LRR%, LRC%, ATTRIB%, TEXT$)
  240.   Description of parameters:
  241.      Because a rectangle can be described by two points, we us the following
  242.      data points:
  243.         ULR Upper left row
  244.         UCL Upper left column
  245.         LRR Lower right row
  246.         LRC Lower right column
  247.         Attribute% = Background color (range 0 to 15) x 16 + Foreground color
  248.             (Range 0 - 15).  The color can be easily described in Hex as &H47
  249.         which yields a red background and white foreground.
  250.         TextChar% = is simply the character code that you want to fill display
  251.         with.  Common characters are 32 or space, 176 - 178 which makes for an
  252.         attractive background character for windowing.
  253.   Fills the display area with a character and a fixed text attribute
  254.  
  255.  ============================================================================
  256.   DECLARE SUB BLOADHELP (FileName$)
  257.   CALL BLOADHELP(FileName$)
  258.  
  259.   Purpose:
  260.           to BLOAD help files without defining size of help file or type of
  261.           display, DEFSEG location, or anything else
  262.  
  263.   Assumes:
  264.           Both BSAVED file and CRT is setup for SCREEN 0, 80 x 25
  265.           Routine does not provide any critical error support.
  266.           Minor file errors will cause abort unless ON ERROR GOTO support
  267.           is provided to handle common errors.
  268.  
  269.           FileName$ must be a near string in DGROUP, cannot be FIXED Length
  270.           or TYPE'd.
  271.  
  272.  ===========================================================================
  273.   DECLARE SUB CHANGEPAGE ()
  274.   CALL CHANGEPAGE
  275.  Purpose:
  276.          Adjust the current VIDEOSEG to reflect current active page that is set
  277.          by QBASIC.  This routine does not change the page that is currently
  278.          written to, you must use QBASIC to do it.
  279.  
  280.          Also reinitializes Video Data Area
  281.  
  282.  Limit:
  283.          This will permit 25, 43, & 50 line displays
  284.          Note on many HERC's the page size is fixed at 16kb even though
  285.          it really is 4kb in Text Mode.  Because QBASIC does not believe that
  286.          a HERC display has video pages in text mode, this routine ignores
  287.          ignores the possibility of video pages for HERC display.
  288.   Typical page limits in 80 x 25 text mode:
  289.   Mono, HERC    = 0 pages
  290.   CGA           = 4 pages
  291.   EGA (w/128kb) = 8 pages
  292.   VGA           = 8 pages
  293.   With careful tinkering of CODE you could get 32 pages for 256kb EGA/VGA's
  294.   and 8 pages for HERC.  However, QBASIC and PRINT would become all confused.
  295.   That is why this is left to reader to implement.
  296.   Returns:
  297.          Nothing, Video Data Area Filed
  298.  
  299.  ===========================================================================
  300.   DECLARE SUB _
  301.   CLEARAREA (BYVAL ULR%, BYVAL ULC%, BYVAL LRR%, BYVAL LRC%, BYVAL ATTRIB%)
  302.   CALL CLEARAREA (ULR%, ULC%, LRR%, LRC%, ATTRIB%)
  303.   Description of parameters:
  304.      Because a rectangle can be described by two points, we us the following
  305.      data points:
  306.         ULR Upper left row
  307.         UCL Upper left column
  308.         LRR Lower right row
  309.         LRC Lower right column
  310.         Attribute% = Background color (range 0 to 15) x 16 + Foreground color
  311.             (Range 0 - 15).  The color can be easily described in Hex as &H47
  312.         which yields a red background and white foreground.
  313.   Changes the attribute of an area on the screen in text mode
  314.  
  315.  =========================================================================
  316.  DECLARE SUB CLEARSCR (BYVAL ULR%, BYVAL ULC%, BYVAL LRR%, BYVAL LRC%,
  317.  _BYVAL ATTRIB%)
  318.  CALL CLEARSCR(ULR%,  ULC%,  LRR%,  LRC%, ATTRIB%)
  319.        range:   1-50  1-80  1-50   1-80   0-255
  320.   Uses the video bios to scroll a window.
  321.  
  322.  ===========================================================================
  323.   DECLARE SUB CLREOL ()
  324.      CLREOL
  325.   Purpose:
  326.         Clears to end of current display line w/o changing attribute
  327.   Assumes:
  328.         80 Column mode, assumes that DI has been set by SETQP; QPRINT;
  329.         QPRINTL; or  QPRNT
  330.  
  331.  ============================================================================
  332.   DECLARE SUB CURSET (Mode%)
  333.   Input:
  334.         Mode = 0  turn off cursor
  335.              NOTE on a VGA with ANSI.SYS installed it might not be possible
  336.              to turn off all attributes of the cursor.
  337.         Mode = 1  turn on normal cursor
  338.         Mode = 2  turn on half block
  339.         Mode = 3  turn on full block
  340.   Returns:
  341.         Nothing
  342.   Purpose:
  343.         Selects attractive cursor sizes over the default QBASIC format.
  344.         Complicated because of need to overcome cursor emulation on VGA/EGA
  345.         With an EGA/VGA if want a full block cursor, cannot rely on cursor
  346.         emulation, must adjust for actual display box (assume 80 x 25).
  347.  
  348.  ============================================================================
  349.   DECLARE FUNCTION DOSPRINT% (BYVAL Row%, BYVAL Col%, Text$)
  350.   IF DOSPRINT% (Row%, Col%, Text$) THEN
  351.       PRINT "Error in text$: null or invalid character"
  352.   END IF
  353.   If you don't need a return code, simply DECLARE as a SUB
  354.  
  355.   Print Text$ at Row%, Column
  356.   Uses DOS Write services to print to STDERR.  STDERR always == CON.
  357.   Does not change the current background attribute, uses whatever was there.
  358.   Only prints to page 0, but no range checks on ROW and COL.  Most useful when
  359.   operating in a multitasking environment or if want to use ANSI.SYS control
  360.   strings.
  361.  
  362.   Returns:
  363.          Error code:
  364.           0 if no error
  365.          -1 if ASCII CHR$(26) found in input stream
  366.  
  367.   Warning:
  368.          Assumes Text$ only contains ASCII text or Carriage return
  369.          control characters.  Any other control characters, e.g. CTRL-C
  370.          will cause Program to terminate, probably destroying file.
  371.          Routine checks for C/R, CTRL-C, CTRL-S, CTRL-P after each character
  372.          If don't want this character checking, use DMPRINT
  373.  
  374.   Notes:
  375.   Moves the cursor to the beginning of the string.  However does not tell
  376.   QBASIC the current cursor location.  Should be a well managed function
  377.   under WINDOWS or other multitasker.
  378.  
  379.  ============================================================================
  380.   DECLARE FUNCTION DMPRINT% (BYVAL Row%, BYVAL Col%, Text$)
  381.   IF DMPRINT% (Row%, Col%, Text$) THEN
  382.       PRINT "Error in text$: null or invalid character"
  383.   END IF
  384.  
  385.   If you don't need a return code, simply DECLARE as a SUB
  386.  
  387.   Uses DOS Write services to print to STDERR.  STDERR always == CON.
  388.   Does not change the current background attribute, uses whatever was there.
  389.   Only prints to page 0, but no range checks on ROW and COL.
  390.   Returns:
  391.          Error code:
  392.           0 if no error
  393.          -1 if CON error.
  394.   If you don't need a return code, simply DECLARE as a SUB
  395.  
  396.   Warning:
  397.          Ignores any control characters, merely prints string.
  398.  
  399.   Notes:
  400.   Moves the cursor to the beginning of the string.  However does not tell
  401.   QBASIC the current cursor location.  Should be a well managed function
  402.   under WINDOWS or other multitasker.
  403.  
  404.   Routine is about 1.23 times faster than DOSPRINT on an EGA
  405.  
  406.  =======================================================================
  407.  DECLARE FUNCTION DSPATTRIB% (BYVAL Foreground%, BYVAL Background%)
  408.  Takes Background color x 16 plus Foreground color
  409.  to make an attribute used by the system routines
  410.  allows Background% > 15, so can blink
  411.  This routine is not necessary, it just makes life easier for the programmer
  412.  who remembers the format for COLOR.
  413.  
  414.  ============================================================================
  415.   DECLARE FUNCTION DUALDISPLAY% ()
  416.   Returns:
  417.         True  (<> 0)  if two displays found
  418.         False (0)     if only one CRT found
  419.  
  420.  ============================================================================
  421.   DECLARE EGAMONO (BYVAL Mode%)
  422.   CALL EGAMONO (Mode%)
  423.   Purpose:
  424.         Forces VGA/EGA mono display to normal MONO attributes
  425.         This allows programmer to have the same attributes appear on a
  426.         HERC, MONO, or EGA Mono Display
  427.   Input:
  428.         Mode%  = 0 if want default mono attributes
  429.         Mode% <> 0 if want Herc type attributes
  430.   Returns: Nothing
  431.  
  432.   Limitations:
  433.          For contrast, colors can only be used against White or Intense.
  434.          Primary colors appear as Black.
  435.          Only White or Intense can be contrasted against Black.
  436.          Blue and Intense Blue attributes are not underlined, unlike HERC/MONO
  437.          All intense colors appear as white.
  438.   Full control over VGA is not possible because of GRAY scaling and large
  439.   number of DAC/palette registers.  To get control over those two features would
  440.   make the program much larger.
  441.   Tinkering required for mono MCGA, but who has one of those?
  442.  
  443.  ============================================================================
  444.   DECLARE SUB FADE ()
  445.   CALL FADE
  446.   Purpose: Clever visual effect, fades out display to white on black.
  447.   Changes all characters to spaces.
  448.   Works in TextMode only.  Sensitive to all video modes (i.e. no snow on CGA's)
  449.   Assumes: Display width is 80 x 25, 80 x 43 or 80 x 50
  450.  
  451.  ============================================================================
  452.   DECLARE FUNCTION FINDCOLOR% ()
  453.   Returns:
  454.         True  (<> 0)  if color CRT found, even if not active
  455.         False (0)     if color CRT not found
  456.  
  457.  ============================================================================
  458.   DECLARE FUNCTION FINDMONO% ()
  459.   Returns:
  460.         True  (<> 0)  if mono CRT found, even if not active
  461.         False (0)     if mono CRT not found
  462.  
  463.  ============================================================================
  464.   DECLARE SUB HERCMODE (BYVAL Mode%)
  465.   CALL HERCMODE (Mode%)
  466.   Purpose is a to control dual displays with color and HERC
  467.  
  468.   Input:
  469.         Mode =  0, Sets a Herc display to half-mode, so it can use a CGA
  470.         Mode <> 0, Sets a Herc display to full-mode, can not use a CGA
  471.   Does not test for existence of Herc display.
  472.  
  473.  =======================================================================
  474.   DECLARE FUNCTION INCOLOR%()
  475.         IF INCOLOR% THEN
  476.             ... etc.
  477.   Tests if have a color or mono display attached.  Test primary display only.
  478.   returns          -1 if color display (may be a single color display)
  479.                     0 if BW mono display
  480.   Note will not be fooled by Herc CGA emulation routines.  Doesn't test
  481.   for single color displays like COMPAQ, AT&T
  482.  
  483.  =======================================================================
  484.   DECLARE SUB LSCROLL (BYVAL Attribute%)
  485.   CALL LSCROLL(Attribute%)
  486.   Scrolls screen left
  487.   Mostly for fun.  To be really useful would have to set it up for windows
  488.   and would have to print using VPRINT.
  489.   Designed to handle an 80 x 25 text display
  490.  
  491.  ============================================================================
  492.  DECLARE SUB MAKEBOXES _
  493.  (BYVAL ULR%, BYVAL ULC%, BYVAL LRR%, BYVAL LRC%, BYVAL HASNO%, BYVAL BORDER%,_
  494.   BYVAL ATTRIB%)
  495.  CALL MAKEBOXES(ULR,ULC,LRR,LRC,HASHNO,BORDER,ATTRIB)
  496.  
  497.   Description of parameters:
  498.      Because a rectangle can be described by two points, we us the following
  499.      data points:
  500.         ULR = Upper left row
  501.         UCL = Upper left column
  502.         LRR = Lower right row
  503.         LRC = Lower right column
  504.  
  505.         HashNo% = is simply the character code that you want to fill display
  506.         with.  Common characters are 32 or space, 176 - 178 which makes for an
  507.         attractive background character for windowing.
  508.  
  509.         Border = Select border type:
  510.            0 = no border
  511.            2 = single sided
  512.            3 = single vertical, double horizontal
  513.            4 = double vertical, single horizontal
  514.            5 = solid box
  515.            Default or 1 = double vertical, double horizontal
  516.  
  517.         Add 256 to BORDER if want shadows.  Shadow designed for 80 x 25 windows,
  518.         to prevent page overlap.  Shadow color is White on blue background for
  519.         a mono display, is white on black background
  520.  
  521.         Attribute% = Background color (range 0 to 15) x 16 + Foreground color
  522.             (Range 0 - 15).  The color can be easily described in Hex as &H47
  523.         which yields a red background and white foreground.
  524.  
  525.   Somewhat shorter and 1.0076 times faster than using the primitives
  526.   in this .OBJ file to do the same thing
  527.  
  528.  ============================================================================
  529.   DECLARE SUB QATTRIB (BYVAL ROW%, BYVAL COL%, BYVAL NUMCHAR%, BYVAL ATTRIB%)
  530.   Row, Column is the starting location. attribute is the color
  531.   and Numchar is the number of characters to change.
  532.   Changes the attribute of characters on the screen in text mode
  533.   Assumes: Display width is 80 columns, Rows are 25, 43, or 50
  534.  
  535.  ============================================================================
  536.   QPRINT.ASM - performs Quick Printing in the QuickBASIC
  537.   DECLARE SUB QPRINT (BYVAL ROW%, BYVAL COL%, Text$, BYVAL ATTRIBUTE%)
  538.   Works in TextMode only, ignores all special characters
  539.   Sensitive to all video modes (i.e. no snow on CGA's)
  540.   If no attribute is selected, the default attribute is &H07 (normal)
  541.   Assumes: Display width is 80 columns, Rows are 25, 43, or 50
  542.  
  543.  ===========================================================================
  544.   DECLARE SUB QPRINTL (Text$)
  545.           CALL QPRINTL(Text$)
  546.   Usage: CALL SETQP(ROW%, COLL%, Attribute%) the first time to set
  547.   the defaults to current display size.  Then QPRINTL on down the display.
  548.   You should use SETQP to start, since scroll routine needs the proper
  549.   attribute to scroll the screen up.
  550.  
  551.   Purpose:
  552.           To work similarly to PRINT Text$
  553.  
  554.           Major differences are:
  555.           a)  Assumes that a VIEW PRINT has been executed
  556.           b)  will not parse the Text$ and start a new line if length of
  557.             Text$ is longer than remaining space on current line.  PRINT
  558.             is designed for formatted column printing, while this
  559.             routine is not.
  560.           c) if at Last Row, Column 80, QPRINTL will scroll the display
  561.              can't stop it.
  562.  
  563.   Speed:
  564.         Varies with length of Text$ and length of display
  565.           for a color EGA on a 10 Mhz AT, the speed varies from 3% faster
  566.           (if LEN(Text$) = 80) to 48% faster.
  567.           Typical speed increase is 12%
  568.  
  569.  ============================================================================
  570.   QPRT.ASM - performs Quick Printing in the QuickBASIC
  571.   DECLARE SUB QPRT (BYVAL ROW%, BYVAL COL%, TEXT$)
  572.   Works in TextMode only, ignores all special characters
  573.   Sensitive to all video modes (i.e. no snow on CGA's)
  574.   Does not change the attribute, uses whatever was there.
  575.   Much faster than LOCATE X,Y : PRINT T$
  576.   Routine is about 6   times faster than PRINT on a color EGA on an AT
  577.              about 4.5 times faster than PRINT on a color VGA on a 386SX
  578.              about 7   times faster than PRINT on a mono EGA on an AT
  579.              about 1.5 to 2 times faster than PRINT on a CGA on an IBM PC
  580.              about 5   times faster than PRINT on a HERC on an AT
  581.              about 6   times faster than PRINT on a COMPAQ Portable
  582.  
  583.   Assumes: Display width is 80 columns, Max Rows are 25, 43, or 50
  584.  
  585.  ============================================================================
  586.   DECLARE SUB RECOLOR (BYVAL OrigColor%, BYVAL NewColor%)
  587.   CALL RECOLOR( OrigColor%, NewColor%)
  588.   Purposes: Change one specific color to another without upsetting the display
  589.   or using palette registers (which couldn't be restored easily using an EGA)
  590.  
  591.   Color is written as BackGround x 16 + ForeGround color
  592.  
  593.   Sensitive to all video modes (i.e. no snow on CGA's)
  594.   Assumes: Display width is 80 x 25, 80 x 43 or 80 x 50
  595.  
  596.  ========================================================================
  597.  RESTSCRN.ASM - restores 80 x 25 page text screen in QuickBASIC array
  598.  Parameters:
  599.   DECLARE SUB RESTSCRN (BYVAL Segment%, BYVAL Offset%)
  600.   DIM ARRAY%(2000)
  601.   CALL RESTSCRN(VARSEG(ARRAY%(0)), VARPTR(ARRAY%(0)))
  602.   To save display call SAVESCRN
  603.  
  604.  =======================================================================
  605.   DECLARE SUB RSCROLL (BYVAL Attribute%)
  606.   CALL RSCROLL(Attribute%)
  607.   Scrolls screen right
  608.   Mostly for fun.  To be really useful would have to set it up for windows
  609.   and would have to print using VPRINT.
  610.   Designed to handle an 80 x 25 text display
  611.  
  612.  ========================================================================
  613.  SAVESCRN.ASM - saves 80 x 25 text screen page in QuickBASIC array
  614.  Parameters:
  615.   DECLARE SUB SAVESCRN (BYVAL Segment%, BYVAL Offset%)
  616.   DIM ARRAY%(2000)
  617.   CALL SAVESCRN( VARSEG(ARRAY%(0)), VARPTR(ARRAY%(0)))
  618.   To restore call RESTSCRN
  619.  
  620.  ===========================================================================
  621.  DECLARE FUNCTION S2BUFF  ;put text screen in buffer
  622.  DECLARE FUNCTION BUFF2S  ;get text screen from buffer
  623.  
  624.  Allows movement of text screens, page 0 to and from a buffer.
  625.  Modified to handle a CGA display so will NOT cause SNOW on a CGA
  626.  
  627.  Handles  80 x 25, 80 x 43, and 80 x 50 displays.  Checks current status each
  628.  time it makes a shift.
  629.  
  630.  Storage in Code Segment used to save space in DGROUP, makes DATA near
  631.  without using up the limited amount of DGROUP space.  However prevents
  632.  use of program in OS/2 which prohibits any change to CodeSeg values.
  633.  
  634.  ===========================================================================
  635.  DECLARE SUB SCN2BUFF ()  ;put text screen in buffer
  636.  DECLARE SUB BUFF2SCN () ;get text screen from buffer
  637.  
  638.   Allows movement of text screens, page 0 to and from a buffer.
  639.   Modified to handle a CGA display so will NOT cause SNOW on a CGA
  640.  
  641.   Handles only 80 x 25 displays. Will not crash on 80 x 43 or 80 x 50 just wont
  642.         save the entire display.  See S2BUFF if want larger displays.
  643.  
  644.   Storage in Code Segment used to save space in DGROUP, makes DATA near
  645.   without using up the limited amount of DGROUP space.  However prevents
  646.   use of program in OS/2 which prohibits any change to CodeSeg values.
  647.  
  648.  =========================================================================
  649.  DECLARE SUB SCROLLDOWN (BYVAL ULR%, BYVAL ULC%, BYVAL LRR%, BYVAL LRC%, BYVAL
  650.  _ ROWS%, BYVAL ATTRIB%)
  651.  CALL SCROLLDOWN(ULR%, ULC%, LRR%, LRC%, ROWS%, ATTRIB%)
  652.   If ROWS%=0 then entire window cleared
  653.   Description of parameters:
  654.      Because a rectangle can be described by two points, we us the following
  655.      data points:
  656.         ULR = Upper left row
  657.         UCL = Upper left column
  658.         LRR = Lower right row
  659.         LRC = Lower right column
  660.         Rows = number of rows to scroll
  661.   Uses the video bios to scroll a window.
  662.  
  663.  =========================================================================
  664.  DECLARE SUB SCROLLUP (BYVAL ULR%, BYVAL ULC%, BYVAL LRR%, BYVAL LRC%, BYVAL
  665.  _ ROWS%, BYVAL ATTRIB%)
  666.  CALL SCROLLUP(ULR%, ULC%, LRR%, LRC%, ROWS%, ATTRIB%)
  667.   If ROWS%=0 then entire window cleared
  668.   Description of parameters:
  669.      Because a rectangle can be described by two points, we us the following
  670.      data points:
  671.         ULR = Upper left row
  672.         UCL = Upper left column
  673.         LRR = Lower right row
  674.         LRC = Lower right column
  675.         Rows = number of rows to scroll
  676.   Uses the video bios to scroll a window.
  677.  
  678.  ===========================================================================
  679.   DECLARE SUB SETQP (BYVAL ROW%, BYVAL COLL%, BYVAL Attribute%)
  680.           CALL SETQP(ROW%, COLL%, Attribute%)
  681.   Purpose:
  682.           Initializes varibles, and sets DI to target address.  This is the
  683.   initialization routine for QPRINTL.  Selects the attribute used to scroll
  684.   the display upward.
  685.   Assumes that user wants to set page size to full size of current dsplay
  686.   such as 80 x 25, 80 x 43, or 80 x 50
  687.  
  688.  ===========================================================================
  689.   DECLARE SUB SETBLINK (BYVAL Status%)
  690.   CALL SETBLICK (Status%)
  691.   Purpose:
  692.         Toggles background blinking/intensity for MONO, CGA, EGA, VGA
  693.         allows use of background colors that would otherwise flash
  694.   Parameters:
  695.         =  0 turn off blinking, enable intensity
  696.         <> 0 to turn it on again
  697.   Returns:
  698.         nothing
  699.  
  700.  ===========================================================================
  701.   DECLARE SUB SNOWCHECK ()
  702.   CALL SNOWCHECK
  703.   Purpose:
  704.          Clears the snowcheck variable (B$DVIDEOPORT) if it finds a CGA
  705.          display by OLIVETTI (AT&T), COMPAQ, or ZENITH
  706.  
  707.   Returns:
  708.          Nothing DGROUP Data Area Filed
  709.  
  710.  ============================================================================
  711.   DECLARE SUB SWAPCOLOR ()
  712.   CALL SWAPCOLOR
  713.   Purpose:
  714.           If have a CGA and a MONO display, this makes the CGA active
  715.   Note:
  716.           Does not test if have either CGA or MONO installed
  717.   See the FIND routines
  718.   Side Effect: Display Cleared
  719.  
  720.  ============================================================================
  721.   DECLARE SUB SWAPMONO ()
  722.   CALL SWAPMONO
  723.   Purpose:
  724.           If have a CGA and a MONO display, this makes the MONO active
  725.   Note:
  726.           Does not test if have either CGA or MONO installed
  727.   See the FIND routines
  728.   Side Effect: Display Cleared.  If have dual displays, the mono display is put
  729.         in HERC half mode for CGA compatibility purposes.   Feedback please!
  730.  
  731.  ===========================================================================
  732.   DECLARE SUB TOGGLESNOW (Mode%)
  733.   CALL TOGGLESNOW(Mode%)
  734.  Input: If Mode% =  0, clears SNOWCHECK
  735.         If Mode% <> 0, leaves SNOWCHECK set
  736.  Purpose:
  737.          Clears the snowcheck variable (B$DVIDEOPORT) if find a CGA display
  738.          Also reinitializes Video Data Area
  739.  
  740.  Returns:  Nothing
  741.            Video Data Area Filed
  742.  
  743.  ===========================================================================
  744.   DECLARE SUB VADDR (Row%, Column%)
  745.    CALL VADDR(Row%, Column%)
  746.    returns the current end of string address for the qprint routines
  747.  
  748.  ============================================================================
  749.   DECLARE SUB VIDINFO (MODE%, ROW%, COLUMN%, CURPAGE%, PAGESIZE%)
  750.   CALL VIDINFO(MODE%, ROW%, COLUMN%, CURPAGE%, PAGESIZE%)
  751.   Purpose:
  752.         Returns information about current video display status.
  753.         Mode%     = current video mode using BIOS format
  754.         Row%      = number of rows currently being displayed
  755.         Cols%     = width of display in columns
  756.         Curpage%  = currently active page
  757.         Pagesize% = size of current page in bytes, default is 4kb
  758.                     for an 80 x 25 display.
  759.   Note:
  760.         PAGESIZE% on many HERC clones will be incorrect and reflect the
  761.   information of the HERC display in HALF mode or 16kb size.
  762.   Routine will store correct Row% length in BIOS ram for CGA, HERC & MONO
  763.  
  764.  ===========================================================================
  765.   DECLARE FUNCTION VIDEOSTAT% ()
  766.  
  767.   VideoStatus Analyzer
  768.   Program returns video information for use by QBASIC
  769.   returns highest level of SCREEN mode supported by the Hardware.
  770.   Returns information about the PRIMARY display only
  771.   This routine with a SELECT CASE, can tell you how many display pages
  772.   are available in text mode, SCREEN 0: WIDTH 80,25
  773.   VGA has 8 pages (0 to 7)
  774.   EGA with > 64kb has 8 pages (0 to 7)
  775.   EGA with 64kb has 4 pages (0 to 3)
  776.   CGA has 4 pages (0 to 3)
  777.   MONO has 1 pages (0)
  778.   HERC has 1 page in SCREEN 0 (0), 2 pages in SCREEN 3 (0 to 1)
  779.  
  780.   Exceptions:
  781.   MCGA color returns a mode 11, so can contrast w/ VGA
  782.   HERC w/o MSHERC.COM reports a -3 so you can tell user to correct matters
  783.   COMPAQ with CGA reports -2 so can force use of monchrome attributes.
  784.   EGA's with CGA displays report -8 if have only 64kb of memory
  785.   EGA's with ECD display report  8 if have only 64kb of memory
  786.  
  787.   Returns:
  788.   Mono         =   0
  789.   CGA          =   2
  790.   PGA          =   2   (Untested, assume PGA would be treated as CGA)
  791.   COMPAQ - CGA =  -2   to tell that user may have a single color display
  792.   HERC         =   3   if have HERC and MSHERC.COM
  793.   HERC         =  -3   if have HERC but w/o MSHERC.COM
  794.   AT&T         =   4,  but only if have just CGA display, not EGA or VGA
  795.       Microsoft QuickC/C makes Olivetti EGA and VGA return a separate code.
  796.       I don't know why anyone would care if the EGA/VGA emulation were
  797.       good.
  798.   EGA64        =   8   Because resolution limited for 64k EGA
  799.   EGA64 w/CGA  =  -8   Because resolution limited to CGA modes
  800.   EGA          =   9   Have minimum of 128kb of video ram
  801.   EGA w/CGA    =  -9   Since resolution limited to CGA modes
  802.   MCGA         =  11   If have an analog color display
  803.   MCGA         = -11   If have an EGA ECD digital color display, since
  804.                        resolution of this display is limited to EGA modes
  805.   VGA          =  13
  806.   EGA/VGA mono =  10   I guess will catch MCGA mono too
  807.  
  808.   The above numbering routine was selected so if the programmer put ABS in
  809. front of the returned value, a SCREEN command could be entered.  The other
  810. advantage was that the routines are much faster thant the ON ERROR GOTO
  811. traps using ERR 5 to determine what is allowed and what is not.
  812.  
  813.   Version 0.92
  814.  
  815.   Tested:     CGA clone, HERC clone, EGA mono, EGA color, VGA color, COMPAQ CGA,
  816.               VGA clone, EGA clone (Paradise clone, ATI EGA Wonder), AT&T 6300
  817.   Not tested: PGA, VGA monochrome, MCGA (color or monochrome)
  818.  
  819.  ===========================================================================
  820.   VPRINT.ASM - performs Vertical Printing in the QuickBASIC
  821.   DECLARE SUB VPRINT (BYVAL ROW%, BYVAL COL%, Text$, BYVAL ATTRIBUTE%)
  822.   Works in TextMode only, ignores all special characters
  823.   Sensitive to all video modes (i.e. no snow on CGA's)
  824.   If no attribute is selected, the default attribute is &H07 (normal)
  825.   Assumes: Display width is 80 columns
  826.  
  827.  ============================================================================
  828.   VPRT.ASM - performs Vertical Printing in the QuickBASIC
  829.   DECLARE SUB VPRT (BYVAL ROW%, BYVAL COL%, TEXT$)
  830.   Works in TextMode only, ignores all special characters
  831.   Sensitive to all video modes (i.e. no snow on CGA's)
  832.   Does not change the attribute, uses whatever was there.
  833.   Assumes: Display width is 80 columns
  834.  
  835.  ==============================================================================
  836.      WINDREST.ASM - restores a portion of the text screen in QuickBASIC;
  837.  
  838.   DECLARE SUB WINDREST(BYVAL ULR%,BYVAL ULC%,BYVAL LRR%,BYVAL LRC%,
  839.  _BYVAL SEGADD%, BYVAL OFFADR% )
  840.   CALL  WINDREST(ULR%,ULC%,LRR%,LRC%,VARSEG(STORAGE(0)),VARPTR(STORAGE(0)))
  841.   Description of parameters:
  842.      Because a rectangle can be described by two points, we us the following
  843.      data points:
  844.         ULR = Upper left row
  845.         UCL = Upper left column
  846.         LRR = Lower right row
  847.         LRC = Lower right column
  848.      Dimension storage array to handle size of display in bytes
  849.     E.g. 80 x 20 display would require an integer array of 1600
  850.  
  851.  ===============================================================================
  852.      WINDSAVE.ASM - saves a portion of the text screen in QuickBASIC
  853.   call from Quickbasic:
  854.   DECLARE SUB WINDSAVE(BYVAL ULR%,BYVAL ULC%,BYVAL LRR%,BYVAL LRC%,
  855.  _BYVAL SEGADD%, BYVAL OFFADR% )
  856.   DIM STORAGE(2000)
  857.   CALL  WINDSAVE(ULR%,ULC%,LRR%,LRC%,VARSEG(STORAGE(0)),VARPTR(STORAGE(0)))
  858.  
  859.   Description of parameters:
  860.      Because a rectangle can be described by two points, we us the following
  861.      data points:
  862.         ULR = Upper left row
  863.         UCL = Upper left column
  864.         LRR = Lower right row
  865.         LRC = Lower right column
  866.      Dimension storage array to handle size of display in bytes
  867.     E.g. 80 x 20 display would require an integer array of 1600
  868.  
  869.  ===============================================================================
  870.  
  871. Acknowledgments:
  872.         Most of my deeper insight into video programming came from a set of
  873. public domain TASM video routines by Dave Bennett, (with the Toad Halls
  874. tweaks), from 1988.  He is the source of the routine for using both the
  875. horizontal and vertical retrace to write to a CGA.  In addition, his code
  876. showed the simple techniques used to write just characters and just attributes
  877. to the display.
  878.  
  879. Author  : Dave Bennett
  880. Version : 1.0
  881. Date    : 11/9/88
  882. CIS PPN : 74635,1671
  883.  
  884. Bibliography:
  885.         General DOS/BIOS routines:  Ray Duncan and Peter Norton's programming
  886. books.  If you can only afford one book, get Duncan's.  Duncan, "Advanced MS-
  887. DOS Programming" (2d Ed. Microsoft 1988).  Very easy to read and to refer to
  888. specific routines.  The text is very well formatted for easy reference.
  889.         Norton, "The New Peter Norton Programmer's Guide to the IBM PC and
  890. PS/2" (Harper & Row 1988).  A book designed to help you visualize what is
  891. going on.  Having been "burned" by writing a book on the PC Junior, and
  892. experienced the agony of hardware incompatibilities in writing the Norton
  893. Utilities, Peter wants everybody to use the bios and documented DOS routines.
  894.         EGA/VGA Programming:
  895.         Michael Abrash, "Power Graphics Programming" (Que 1990).  Excellent
  896. reprint of Programmer's Journal (Buy this magazine!) columns.  Does not cover
  897. Super VGA and beyond (that is being done now in the Programmer's Journal).
  898. Mostly useful for graphics routines.  The best book on the subject, and the
  899. only technical book that one could actually enjoy reading as a book rather
  900. than as a reference.  See also various issues of PC Magazine for programming
  901. tidbits.
  902.         Ferro, "Programmer's Guide to the EGA and VGA Cards," (Addison-Wesley
  903. 1988).   Good, but slightly disorganized.  The only book that discusses the
  904. registers (unfortunately more in the nature of a dictionary rather than in
  905. examples of how to manipulate the registers).  A good list of typical bios
  906. defaults, which are important for the EGA since you can't read the registers.
  907.         Herc:
  908.         Doty, "Programmer's Guide to Hercules Graphics Cards" (Addison-Wesley
  909. 1988).  Good book on the subject.  Describes the high end Herc systems.  Many
  910. programming examples and port descriptions.
  911.         Herc, CGA, EGA, VGA:
  912.         Wilton, "Programmer's Guide to PC & PS/2 Video Systems" (Microsoft
  913. 1987).  Excellent general purpose book.  Said to have some errors, though I
  914. have found nothing more than a few typos.  Does not cover Super VGA and
  915. beyond.  Partial information is set forth in Phoenix's "System Bios for
  916. PC/XT/AT Computers and Compatibles" (Addison-Wesley 1989).
  917.         MONO and CGA:
  918.         Bradley, "Assembly Language Programming for the IBM Personal
  919. Computers" (Prentice Hall 1984).  Good technical descriptions of the original
  920. PC.  Only book I have seen that has really shown how to switch displays,
  921. manipulate DMA, make sound, and manipulate floppy disk drives at the PORT
  922. level (teaches you why we have BIOS and DOS routines).  Good book on the 8087.
  923. Probably now out of print.  I bought my copy at a book store that sells
  924. remainders.
  925.         DOS Programming:
  926.         Detteman, "DOS Programmer's Reference (2d Ed. Que 1989).  Excellent
  927. book with a very helpful look at undocumented DOS.  Doesn't preach about not
  928. using undocumented DOS as does Peter Norton.
  929.         Waite Group "Dos Developer's Guide" (2d Ed Sams 1989).  Good book on
  930. Expanded memory and math chips.  Several good discussions of the undocumented
  931. DOS functions.  Such a big book, that you feel you got your money's worth
  932. based just on weight.
  933.         General Programming:
  934.         Holzner, "PS/2-PC Assembly Language"  (Brady 1989)  Good introduction
  935. to assembly language programming.  In many respects better than Holzner,
  936. "Advanced Assembly Language on the IBM PC" (Brady 1987).
  937.         Tischer, "PC System Programming for Developers" (ABACUS 1989).  Good
  938. technical survey of PC/AT systems.  Comes with a lot of programs showing how
  939. to do useful things in MASM, QBASIC, PASCAL and C.  The only shortcoming is
  940. that the book is printed on very cheap paper.  One of the few books to show
  941. register usage of DOS and BIOS routines (important so you can save variables
  942. in registers rather than in memory or pushed on the stack.)  Doesn't discuss
  943. DOS Version 4 in an integrated fashion.  Such a big book, that you feel you
  944. got your money's worth based just on weight.
  945.         Young, "Inside DOS: A Programmer's Guide", (Sybex 1990).  Good source
  946. of MASM code, with a primary emphasis on C (The MASM code is similar for both
  947. C and QBASIC).  A reprint of "MS DOS Advanced Programming" (Sybex 1988).  (I
  948. didn't discover this until I purchased both).
  949.         Wyatt, "Using Assembly Language" (2d Ed. QUE 1989).  Some decent video
  950. routines.  No useful description of VGA.  EGA routines are primitive.  Good
  951. insight into programming for high level languages.  Complete listing of all
  952. the Intel keywords, but reads too much like an Intel-English disctionary.
  953. Most of the examples in the keyword section are not really helpful and the
  954. ASCII math routines are not well described.  One major programming feature
  955. dropped from the 1st edition was the AT keyboard programming routines.  Does
  956. this mean AT keyboards are only marginally compatible on the hardware level?
  957. Feedback please.
  958.         QBASIC Programming:
  959.         Goodwin, "QuickBASIC Advanced Programming Tools" (MIS 1989).  A much
  960. better book for QBASIC code (sorting, popup windows, dropdown windows and
  961. menubar programs) than for MASM code.  The MASM code relies on video bios to
  962. do things (which is slow, though always compatible).  Moreover, screens are
  963. stored in STRINGs rather than arrays, which greatly limits the usefulness of
  964. his MASM routines.  (I agree storing screens in arrays takes more work).  A
  965. programmer can have access to several hundred KB of far data in arrays, while
  966. he can only have access to 30 to 40kb of precious string space in DGROUP.
  967.         Lesser,  "Advanced Quickbasic 4.0 Language Extensions with Modular
  968. Tools" (Bantam 1988).  This is how I learned about MASM/QBASIC programming.
  969. Talks more about ideas that were important for QBASIC Version 3.0/MASM pre-
  970. version 5.1  (before simplified directives) than for QBASIC Version 4.x.
  971. BELIEVES in structured programming.  Not too many hardware insights.  Offers
  972. generally sound advice.
  973.         Shammas, "QuickBASIC- Programming Techniques and Library Development"
  974. (M&T Publishing 1988).  Good QBASIC code.  Some of the string routines are
  975. fast.  He has some BTREE and high level math routines.
  976.         Books Not Recommended (How daring!):
  977.         Murray & Pappas, "80386/80286 Assembly Language Programming"
  978. (Osborne/McGraw Hill 1986).  Only feature of the book is a list of clock
  979. cycles for 80286/80386 opcodes.  Reads like an Intel-English dictionary.
  980.         Duntemann, "Assembly Language from Square One" (Scott, Foresman 1990)
  981. Designed for the beginning programmer.  Suffers from a serious case of
  982. excessive cuteness.  See game of "Big Bux", page 8.  PC Techniques (a good
  983. programming magazine, like those HAX) shows he is capable of much, much more.
  984.  
  985. What's next:
  986.         Two more freeware QBASIC libraries will be released: a) Mouse and
  987. Keyboard routines; and b) DOS and Equipment ID routines.  All will include
  988. MASM source and .OBJ code.  If I get any significant feedback, I might even
  989. release revised libraries.
  990.         I think once you are finished using these libraries you will discover
  991. that programming is much like fishing.  At first, you just go fishing, then
  992. you want to catch big fish.  After a while, you become content to merely catch
  993. fish with whatever is fast, cheap and handy.
  994.         Oh yes, I almost forgot, in case you are wondering, I am a tax lawyer
  995. trying to "catch big fish"
  996.