home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-10-10 | 88.9 KB | 2,003 lines |
- The BASIC Wizard's Library page 1
- =------------------------=
- Version 1.4
-
- BASWIZ Copyright (c) 1990 Thomas G. Hanlin III
-
-
-
- This is BASWIZ, a library of assembly language and BASIC routines for use
- with QuickBASIC version 4.5. Support for other recent versions of the BASIC
- compiler is provided with registration. The BASWIZ collection is copyrighted
- and may be distributed only under the following conditions:
-
- 1) No fee of over $10.00 may be charged for distribution. This
- restriction applies only to physical copies and is not meant to
- prevent distribution by telecommunication services.
-
- 2) All BASWIZ files must be distributed together in original, unaltered
- form. This includes BASWIZ.DOC, BASWIZ.LIB, BASWIZ.NEW, BASWIZ.QLB,
- BASWIZ.REF, BIBLIO.TXT, CATALOG.TXT, CREATE.BAT, DEMO.BAS, DEMO.DAT,
- FILES.LST, LIBRARY.TXT, QUESTION.TXT, REGISTER.TXT and TERM.BAS.
-
- You use this library at your own risk. It has been tested by me on my own
- computer, but I will not assume any responsibility for any problems which
- BASWIZ may cause you. If you do encounter a problem, please let me know
- about it, and I will do my best to verify and repair the error.
-
- It is expected that if you find BASWIZ useful, you will register your copy.
- You may not use BASWIZ routines in programs intended for sale unless you have
- registered. Registration entitles you to receive the latest version of
- BASWIZ, complete with full source code in assembly language and BASIC. The
- assembly code is designed for the OPTASM assembler by SLR Systems and will
- require modifications if you wish to use it with MASM or TASM. You will then
- be able to compile the BASIC code with whatever version of the compiler you
- have, allowing you to use BASWIZ with QuickBASIC versions 4.0 - 4.5 and
- BASCOM versions 6.0 - 7.1. Note that Microsoft's "far strings" can't be used
- with BASWIZ at this time, so BASWIZ can't be used with QBX.
-
- Warning: Use of BASWIZ for more than 30 days without registering has been
- determined to cause cancer in laboratory animals! If you use this product,
- please do register.
-
- For an example of how to set up your program to access the BASWIZ library,
- how to LINK the routines, and so forth, take a look at the CREATE.BAT and
- DEMO.BAS files. The LIBRARY.TXT file explains how to use libraries.
-
- So who's the BASIC Wizard? Why, with this library, you will be! Read this
- tome well, for invoking these routines without proper preparation may bring
- unexpected results. Cape and hat (optional) not included. No assembly
- required.
-
- NOTE!!! The Hercules Graphics routines will be expanded and moved into my
- GRAFWIZ library as of the next version! Since GRAFWIZ focuses on graphics,
- it is a more appropriate place for the Hercules routines than BASWIZ. This
- will also help keep the size of BASWIZ manageable in the near future.
-
- Table of Contents page 2
-
-
-
- Expression Evaluator .................................................. 3
-
- Far Strings ........................................................... 4
-
- File Handling ......................................................... 6
-
- Hercules Graphics ..................................................... 14
-
- Memory Management and Pointers ........................................ 16
-
- Telecommunications .................................................... 19
-
- Virtual Windowing System .............................................. 25
-
- Just for Kicks ........................................................ 36
-
- Miscellaneous Notes ................................................... 37
-
- Error Codes ........................................................... 38
-
- Troubleshooting ....................................................... 40
-
- History & Philosophy .................................................. 42
-
- Using BASWIZ with PDQ ................................................. 43
-
- Expression Evaluator page 3
-
-
-
- The expression evaluator allows you to find the result of an expression
- contained in a string. Normal algebraic precedence is used, e.g. 4+3*5
- evaluates to 19. The usual numeric operators (*, /, +, -, ^) are supported
- (multiply, divide, add, subtract, and raise to a power). Use of negative
- numbers is just fine, of course. Parentheses for overriding the default
- order of operations are also supported.
-
- To evaluate an expression, you pass it to the evaluator as a string. You
- will get back either an error code or a single-precision result. Try this
- example to see how the expression evaluator works:
-
- REM $INCLUDE: 'BASWIZ.BI'
- DEFINT A-Z
- DO
- INPUT "Expression? "; Expr$
- IF LEN(Expr$) THEN
- Evaluate Expr$, Result!, ErrCode
- IF ErrCode THEN
- PRINT "Invalid expression. Error code = "; ErrCode
- ELSE
- PRINT "Result: "; Result!
- END IF
- END IF
- LOOP WHILE LEN(Expr$)
- END
-
- An expression evaluator adds convenience to any program that needs to accept
- numbers. Why make someone reach for a calculator when number crunching is
- what a computer does best?
-
- Far Strings page 4
-
-
-
- One of the best things about BASIC is its support for variable-length
- strings. Few other languages support such dynamically-allocated strings and
- they're a terrifically efficient way of using memory. At least, they would
- be, except for one minor limitation... in every version of QuickBASIC and
- BASCOM (except for the new, very expensive BASCOM 7.0 "Professional
- Development System"), string space is limited to a mere 50K-60K bytes. As if
- this weren't trouble enough, this space is also shared with a number of other
- things. Running out of string space is a common and painful problem.
-
- Anyway, it used to be. The BASWIZ library comes with an assortment of
- routines and functions which allow you to keep variable-length strings
- outside of BASIC's tiny string area. Currently, you may have up to 65,535
- far strings of up to 255 characters each, subject to available memory.
- Either normal system memory or expanded memory may be used. Extended memory
- can also be used if you have a driver that converts extended memory to
- expanded memory.
-
- Using far strings works almost the same way as using normal strings. Rather
- than referring to a far string with a string variable name, however, you
- refer to it with an integer variable called a "handle". To create a new far
- string, you use a handle of zero. A new handle will be returned to you which
- will identify that string for future reference.
-
- Before you use any far strings, you must initialize the far string handler.
- When you are done using far strings, you must terminate the far string
- handler. Normally, each of these actions will take place only once in your
- program: you initialize at the beginning and terminate at the end.
-
- On the next page is an example program that reads a file into an array of far
- strings, then displays it. I'll leave out such niceties as error trapping to
- keep the example easy to follow.
-
- Far Strings page 5
-
-
-
- REM $INCLUDE: 'BASWIZ.BI'
- DEFINT A-Z
- REDIM Text(1 TO 5000) ' array for far string handles
- FSInit 0 ' initialize far string handler
- TextLines = 0
- OPEN "ANYFILE.TXT" FOR INPUT AS #1
- DO UNTIL EOF(1)
- LINE INPUT#1, TextRow$
- Handle = 0 ' use zero to create new far string
- FSSet Handle, TextRow$ ' set the far string
- TextLines = TextLines + 1
- Text(TextLines) = Handle ' save the far string handle
- LOOP
- CLOSE
- FOR Row = 1 TO TextLines
- PRINT FSGet$(Text(Row)) ' display a far string
- NEXT
- FSDone ' terminate far string handler
- END
-
- If you wanted to change an existing far string, you would specify its
- existing handle for FSSet. The handle of zero is used only to create new far
- strings, rather in the manner of using a new variable for the first time.
-
- Note the zero after the FSInit call. That specifies that main system memory
- is to be used. If you would prefer to use expanded memory, use a one
- instead. If EMS memory is not available, BASWIZ will ignore the one and use
- main memory instead.
-
- File Handling page 6
-
-
-
- The file handling capabilities of BASIC were improved considerably as of
- QuickBASIC 4.0. A binary mode was added and it became possible to use
- structured (TYPE) variables instead of the awkward FIELD-based random access
- handling. Even today, however, BASIC file handling is inefficient for many
- tasks. It requires error trapping to avoid problems like open floppy drive
- doors and cannot transfer information in large quantities at a time.
-
- The BASWIZ routines provide additional flexibility and power. They allow you
- to access files at as low or high a level as you wish. Here are some of the
- features of BASWIZ file handling:
-
- - File sharing is automatically used if the DOS version is high enough,
- providing convenient network compatibility.
- - Critical errors, like other errors, are detected at any point you find
- convenient via a single function call.
- - Optional input buffers speed up reading from files.
- - Up to 32K of data may be read or written at one time.
- - Files can be flushed to disk to avoid loss due to power outages, etc.
-
- Files are not considered to be strongly moded by BASWIZ, although there are a
- few limitations on how you can deal with text files as opposed to other kinds
- of files. Reads and writes normally take place sequentially, like the INPUT
- and OUTPUT modes allowed by BASIC. However, you can also do random access by
- moving the file pointer to anywhere in the file, just as with the RANDOM and
- BINARY modes allowed by BASIC. These routines place no arbitrary limitations
- on the programmer.
-
- As with BASIC, files are referred to by a number after they are opened for
- access. Unlike BASIC, the number is returned to you when the file is
- successfully opened, rather than being specified by you when you open the
- file. This means that you never have to worry about a file number already
- being in use. We'll refer to the file number as a "file handle" from now on.
-
- File Handling page 7
-
-
-
- Before doing anything else, you must initialize the file handling routines.
- This is typically done only once, at the beginning of your program. The
- FInit routine needs to know the number of files you want to deal with. This
- can be up to 15 files, or possibly up to 50 if you are using DOS 3.3 or
- higher. Support for over 15 files has not been tested, since I don't have
- DOS 3.3 or higher, so you use that feature at your own risk! A future
- version of BASWIZ will support over 15 open files for DOS 3.0 and above.
-
- FInit Files, ErrCode
-
- A file is opened for access like so:
-
- FOpen File$, FMode$, BufferLen, Handle, ErrCode
-
- You pass the File$, FMode$, and BufferLen. The Handle and ErrCode are
- returned to you. The "BufferLen" is the length of the buffer desired for
- input. This must be zero if you want to write to the file. The filename is
- passed in File$, naturally enough. There is a choice of various modes for
- FMode$ and these can be combined to some extent:
-
- A Append to file used to add more information to an existing file
- C Create file creates a new file
- R Read access allows reading (input) from a file
- T Text mode file allows text-mode input from a file
- W Write access allows writing (output) to a file
-
- For the most part, the combinations are self-explanatory. For instance, it
- would be reasonable to open a file for read and write, for create and write,
- for append and write, or for read and text. Text files always require a
- buffer. If you request text access without specifying a buffer, a buffer of
- 512 bytes will be provided for you. If you request create access without
- additional parameters, the file will be opened for write by default.
-
- You may not use a buffer if you want to write to a file. This includes text
- files, which always use a buffer, as well as binary files. This is an
- artificial limitation which will change in a future version of BASWIZ. It
- exists now to reduce the internal complexity of the routines which write to
- the file, so that they do not have to account for any buffering as well as
- the current file pointer. However, writing may be done to a text-type file
- if the file was not opened in text mode. We'll see how that works presently.
-
- When you are done using a particular file, you can close it, just as in
- ordinary BASIC:
-
- FClose Handle
-
- Before your program ends, you should terminate the file handler. This will
- close any open files as well as concluding use of the file routines:
-
- FDone
-
- File Handling page 8
-
-
-
- That covers the basic set-up routines: initialize, open, close, and
- terminate. Of more interest are the routines which actually deal with the
- file itself. These provide assorted read/write services, the ability to get
- or set the file read/write pointer, size, time, and date, and the ability to
- get or set the error code for a specific file, among other things. Let's
- take a look at the error handler first.
-
- The FInit and FOpen routines return an error code directly, since you need to
- know immediately if these have failed. The other file routines do not return
- a direct error code, however. In order to discover whether an error has
- occurred, you use the FGetError% function. This will return an error of zero
- if there was no error, or a specific error code (listed at the end of this
- manual) if some problem occurred. The error code will remain the same until
- you reset it using FError. The FError service also allows you to test your
- error handler by forcing specific error codes even when everything is fine.
-
- PRINT "Error code: "; FGetError(Handle)
- FError Handle, 0 ' clear the error code
-
- It is recommended that you check for errors after any file routine is used if
- there is a chance that your program will be executed on a floppy disk. These
- are particularly prone to user errors (like leaving the drive door open) or
- running out of space. If your program will only run on a hard drive, you may
- not need to check as frequently. It's your choice. Note that the error code
- is not cleared automatically-- use FError to reset the error code to zero if
- you determine that it wasn't a "fatal" error.
-
- Down to the nitty-gritty... we've seen how to open and close a file, how to
- check operations for errors, and so forth. So how do we actually manipulate
- the file? There are assorted alternatives, depending on how you want to deal
- with the file: text reads, text writes, byte-oriented reads and writes, and
- block reads and writes, not to mention handling the time, date, size, and
- read/write pointer. We'll start off with the routines which read from a
- file.
-
- If you opened the file for text access, you must want to read the file a line
- at a time. Each line is assumed to be less than 256 characters and delimited
- by a carriage return and linefeed (<CR><LF>, or ^M^L, in normal notation).
- In that case, you should use the FReadLn$ function:
-
- St$ = FReadLn$(Handle)
-
- A simple program to display a text file directly on the screen might look
- something like this in BASIC:
-
- OPEN COMMAND$ FOR INPUT AS #1
- WHILE NOT EOF(1)
- LINE INPUT#1, St$
- PRINT St$
- WEND
- CLOSE #1
-
- File Handling page 9
-
-
-
- The same program using BASWIZ would look something like this:
-
- REM $INCLUDE: 'BASWIZ.BI'
- DEFINT A-Z
- FInit 15, ErrCode
- FOpen COMMAND$, "RT", 0, Handle, ErrCode
- WHILE NOT FEOF(Handle)
- PRINT FReadLn$(Handle)
- WEND
- FDone
-
- In either case, we're accepting a command-line parameter which specifies the
- name of the file. In the BASWIZ example, note the use of the FEOF% function,
- which tells whether we've gone past the end of the file. This works like the
- EOF function in BASIC.
-
- There are two ways of reading from binary files. You can get the results as
- a string of a specified (maximum) length:
-
- St$ = FRead$(Handle, Bytes)
-
- In plain BASIC, the same thing might be expressed this way:
-
- St$ = INPUT$(Bytes, FileNumber)
-
- The other way of reading from a binary file has no equivalent in BASIC. It
- allows you to read in up to 32K bytes at a time, directly into an array or
- TYPEd variable. You can read the information into anything that doesn't
- contain normal strings (the fixed-length string type can be used, though):
-
- Segm = VARSEG(Array(0))
- Offs = VARPTR(Array(0))
- FBlockRead Handle, Segm, Offs, Bytes
-
- That would read the specified number of bytes into the array "Array",
- starting at array element zero. You can use any data type, whether single
- variable or array, as long as it is not a variable length string. In other
- words, Vbl$ and Vbl$(0) would not work. If you want to use a string with the
- block read, it must be a fixed-length string. For example:
-
- DIM Vbl AS STRING * 1024
- Segm = VARSEG(Vbl)
- Offs = VARPTR(Vbl)
- FBlockRead Handle, Segm, Offs, Bytes
-
- It's a good idea to calculate the Segm and Offs values each time. These tell
- FBlockRead where to store the information it reads. QuickBASIC may move the
- variable around in memory, so VARSEG and VARPTR should be used just before
- FBlockRead, to insure that they return current and correct information.
-
- File Handling page 10
-
-
-
- The file output commands are similar. File output can only be done if there
- is no input buffer. This means that you can't use file output if the file
- was opened in text mode, either, since text mode always requires an input
- buffer. That's a limitation that will be removed in a future version of
- BASWIZ. It is possible to do text output on a file that was opened in binary
- mode, however. The limitation just means that you can't open a file for both
- reading and writing if you use a buffer (or text mode).
-
- To output (write) a string to a file, use this:
-
- FWrite Handle, St$
-
- This is like the plain BASIC statement:
-
- PRINT #FileNumber, St$;
-
- If you would like the string to be terminated by a carriage return and
- linefeed, use this instead:
-
- FWriteLn Handle, St$
-
- This is like the plain BASIC statement:
-
- PRINT #FileNumber, St$
-
- In BASIC, the difference between the two writes is controlled by whether you
- put a semicolon at the end. With BASWIZ, different routines are used
- instead. FWrite is like PRINT with a semicolon and FWriteLn is like PRINT
- without a semicolon.
-
- As well as simple string output, you can also output TYPEd variables and
- even entire arrays. This type of output has no corresponding BASIC
- instruction, although it's somewhat similar to the file PUT statement. Up to
- 32K can be output at a time:
-
- Segm = VARSEG(Array(0))
- Offs = VARPTR(Array(0))
- FBlockWrite Handle, Segm, Offs, Bytes
-
- If you haven't already read the section on FBlockRead, go back a page and
- review it. The same comments apply for FBlockRead: it can handle
- fixed-length strings but not old-style strings, and VARSEG/VARPTR should
- immediately preceed the block I/O, among other things.
-
- File Handling page 11
-
-
-
- Normally, reads and writes take place sequentially. If you want to move to a
- specific spot in the file, though, that's easy. You can do it in text mode
- or binary mode, whether or not you have a buffer, giving you additional
- flexibility over the usual BASIC file handling. Set the location for the
- next read or write like so:
-
- FLocate Handle, Position&
-
- The Position& specified will be where the next read or write takes place. It
- starts at one and (since it's specified as a LONG integer) can go up to
- however many bytes are in the file. If you want a record position rather
- than a byte position, you can do that too. Just convert the record number to
- a byte number, like so:
-
- Position& = (RecordNumber& - 1&) * RecordLength& + 1&
-
- If you do not want to maintain RecordNumber and RecordLength as LONG
- integers, convert them to such by using the CLNG() function on them before
- doing the calculation. Otherwise you may get an overflow error in the
- calculation, since QuickBASIC will assume that the result will be an integer.
-
- You can get the current position of the file read/write pointer too:
-
- Position& = FGetLocate&(Handle)
-
- Let's see... we've examined initialization and termination, opening and
- closing, reading and writing, and manipulating the file read/write pointer.
- What else could there be? Well, how about checking the size of a file and
- getting or setting the file time and date? Why, sure! The "get" routines
- are pretty well self-explanatory:
-
- FileSize& = FGetSize&(Handle)
- FileTime$ = FGetTime$(Handle)
- FileDate$ = FGetDate$(Handle)
-
- Setting the time and date is equally easy. This should be done just before
- you close the file with FClose or FDone. You may use any date and time
- delimiters you choose. If a field is left blank, the appropriate value from
- the current time or date will be used. Years may be specified in four-digit
- or two-digit format. Two-digit years will be assumed to be in the 20th
- century ("90" == "1990"). Careful there! Your program should allow
- four-digit dates to be used or disaster will strike when the year 2000
- rolls around. The 21st century is closer than you think!
-
- FTime Handle, FileTime$
- FDate Handle, FileDate$
-
- File Handling page 12
-
-
-
- There's just one more file routine. It allows you to "flush" a file to disk.
- This insures that the file has been properly updated to the current point, so
- nothing will be lost if there is a power outage or similar problem. If you
- do not use the "flush" routine, data may be lost if the program terminates
- unexpectedly (without going through FClose or FDone). Note that use of
- FFlush requires that a free file handle be available, under most DOS versions.
-
- FFlush Handle
-
- That's it for the BASWIZ file handler. As a quick review, let's run through
- the available routines, then try a couple of example programs. Remember that
- the BASWIZ.REF file contains a brief reference for all of these routines too!
- You might also wish to examine the DEMO.BAS program, which also makes use of
- the file routines.
-
- FInit initialize the file handler
- FDone terminate the file handler and close any open files
-
- FOpen open a file for access (like OPEN)
- FClose close a file (like CLOSE)
-
- FRead$ read a string from a binary file (like INPUT$)
- FReadLn$ read a string from a text file (like LINE INPUT)
- FBlockRead read an item (TYPE, STRING*##, or array) from a binary file
-
- FWrite write a string to a binary file
- FWriteLn write a string with a <CR><LF> to a binary file
- FBlockWrite write an item (TYPE, STRING*##, or array) to a binary file
-
- FLocate set the read/write pointer to a specified position
- FTime set the time stamp
- FDate set the date stamp
- FError set the error code
-
- FGetLocate& get the read/write pointer
- FGetTime$ get the time stamp
- FGetDate$ get the date stamp
- FGetError get the error code
-
- FFlush flush to disk (makes sure file is updated and current)
- FGetSize& get size
- FEOF determine whether the end of the file has been reached
-
- File Handling page 13
-
-
-
- So much for theory. Let's try something practical. A common problem is
- copying one file to another. We'll limit this to text files, so we can do it
- in both plain BASIC and with BASWIZ. Although BASWIZ can handle any type of
- file readily, BASIC has problems in efficiently handling variable-length
- binary files. So, we'll do this first in BASIC, then BASWIZ, for text files.
-
- In BASIC, a text-file copying program might look like this:
-
- INPUT "File to copy"; FromFile$
- INPUT "Copy file to"; ToFile$
- OPEN FromFile$ FOR INPUT AS #1
- OPEN ToFile$ FOR OUTPUT AS #2
- WHILE NOT EOF(1)
- LINE INPUT#1, St$
- PRINT#2, St$
- WEND
- CLOSE
-
- With BASWIZ, the same program would look more like this:
-
- REM $INCLUDE: 'BASWIZ.BI'
- DEFINT A-Z
- INPUT "File to copy"; FromFile$
- INPUT "Copy file to"; ToFile$
- FInit 15, ErrCode
- FOpen FromFile$, "RT", 1024, FromHandle, ErrCode
- FOpen ToFile$, "CW", 0, ToHandle, ErrCode
- FileTime$ = FGetTime$(FromHandle)
- FileDate$ = FGetDate$(FromHandle)
- WHILE NOT FEOF(FromHandle)
- WriteLn ToHandle, ReadLn$(FromHandle)
- WEND
- FTime ToHandle, FileTime$
- FDate ToHandle, FileDate$
- FDone
-
- You might have noticed that the BASWIZ version of the program is a bit longer
- than the plain BASIC version. It has a number of advantages, however. It's
- faster, produces smaller code under ordinary circumstances, and also
- preserves the date and time of the original file in the copied file. Unlike
- BASIC, the BASWIZ routines do not automatically add a ^Z to the end of text
- files, so the BASWIZ example will not alter the original file.
-
- Hercules Graphics page 14
-
-
-
- Even in this age of super VGA displays, there are still many people using
- monochrome systems. After all, they're extremely inexpensive and are
- adequate for many purposes. As an alternative graphics standard, the
- Hercules monochrome adapter is quite popular.
-
- Curiously enough, QuickBASIC provides only indirect support for the Hercules
- through a TSR. The BASWIZ library allows you to dispense with this TSR and
- to take advantage of the full resolution of the Hercules. Rather than
- attempt to emulate 25x80 text mode and get the bottom row truncated, as
- QuickBASIC does, BASWIZ provides a handy 43x90 text mode which makes the best
- use of the Herc's capabilities.
-
- The first thing you need to do in order to use these Hercules routines is to
- put the display into graphics mode. That's done like so:
-
- HGMode 1
-
- When you are done, you do the same thing, but with a zero instead of a one.
- That puts the display back into text mode, which is important. The computer
- does not know how to handle Hercules graphics mode by itself (I'm afraid IBM
- snubbed this poor adapter!) and will display only garbage otherwise. Any
- time you want to display something, use the routines provided here. The
- normal PRINT statement will do you no good in Hercules graphics mode.
-
- Since we can't rely on the usual BASIC display statements, we need to have
- replacements for them. As a matter of fact, the following routines are not
- merely replacements but extensions to BASIC's display capabilities. They are
- for use in Hercules graphics mode only.
-
- To start off with, let's check out the replacements for LOCATE, COLOR, CLS
- and PRINT:
-
- HGCls
- HGColor Fore, Back
- HGLocate Row, Column
- HGWrite St$
- HGWriteLn St$
-
- Pretty straightforward, isn't it? The legal colors are 0 (black) and 1
- (white, or actually green or amber depending on your display). Valid rows
- are 1-43 and valid columns are 1-90. Note that the range of rows is the same
- as an EGA or VGA allows!
-
- Don't forget to put the display back into text mode before your program
- exits! You'll get really funny looking screens otherwise.
-
- HGMode 0
-
- Hercules Display Adapter page 15
-
-
-
- The HGWrite and HGWriteLn routines deserve a bit of additional explanation.
- HGWrite is like PRINT with a semicolon-- the cursor is not moved down a line
- after the string is printed. HGWriteLn is like PRINT without a semicolon.
- Both of these routines use standard ASCII control codes rather than the
- idiosyncratic interpretation offered by QuickBASIC. This means that CHR$(13)
- homes the cursor to the start of the line, CHR$(10) moves the cursor directly
- down one line without homing it, and CHR$(8) does a backspace. Other
- supported control codes include bell (CHR$(7)), tab (CHR$(9)), and formfeed
- (CHR$(12)). The latter is interpreted as meaning "clear screen", which is
- the usual way of handling it on display-based systems.
-
- If you need to print a number rather than a string, you can do that too.
- Just convert the number to a string using the STR$ function provided by
- BASIC.
-
- Suppose you want to get the current colors or cursor position? That's
- handled by these routines:
-
- HGGetColor Fore, Back
- HGGetLocate Fore, Back
-
- Last but not least, there are two graphics routines. Graphics mode wouldn't
- be much fun without graphics, now would it...
-
- HGPlot Column, Row, Colour
- HGLine Column1, Row1, Column2, Row2, Colour
-
- As you might have noticed, the coordinates are in (Column, Row) order as is
- appropriate for graphics mode, rather than the (Row, Column) used by text
- mode. Why does the convention change like this? Well, probably not even
- Microsoft can answer that any more! It's just the way it works.
-
- Graphics mode coordinates may range 0-719 (columns) and 0-347 (rows). The
- color range is the same as for text, i.e., 0-1.
-
- Memory Management and Pointers page 16
-
-
-
- On the whole, BASIC is easily a match for any other language, as far as
- general-purpose programming goes. There is one major lack, however-- a set
- of valuable features that is supported by most other languages, but was
- inexplicably left out of BASIC. Perhaps Microsoft felt it was too advanced
- and dangerous for a so-called "beginner's" language. In truth, using
- pointers and memory management takes a little understanding of what you're
- doing-- the compiler can't protect you from all of your mistakes. However,
- they can be extraordinarily useful for many things, so I have added these
- capabilities to BASWIZ.
-
- A "pointer" is essentially just the address of an item. It is useful in two
- respects: it allows you to pass just the pointer, rather than the whole item
- (be it a TYPEd variable, normal variable, entire array, or whatever) to a
- subprogram. This is faster and more memory-efficient than the alternatives.
- Secondly, a pointer combined with memory management allows you to allocate
- and deallocate memory "on the fly", in just the amount you need. You don't
- have to worry about DIMensioning an array too large or too small, or even
- with how large each element of the array should be, for example. You can
- determine that when your program -runs-, rather than at compile time, and set
- up your data structures accordingly. You can also create a large variety of
- data structures, such as trees and linked lists, which would be difficult and
- cumbersome to emulate using BASIC alone.
-
- The BASWIZ memory/pointer routines allow you to allocate and deallocate
- memory, fill, copy or move a block of memory, get or put a single character
- according to a pointer, and convert back and forth between a segment/offset
- address and a pointer.
-
- Pointers are kept in LONG integers, using an absolute memory addressing
- scheme. This means that you can manipulate pointers just like any ordinary
- LONG integer, e.g. to move to the next memory address, just add one. Since
- you can convert from a segment/offset address to a pointer and you can copy
- information from one pointer to another, you can move information back and
- forth between allocated memory and a TYPEd variable, numeric variable, or
- array. You can even do things like set a pointer to screen memory and
- transfer the screen into a variable or vice versa! Or implement your own
- "far string" routines, heirarchical evaluations, or any number of other
- things. Pointers are incredibly powerful!
-
- Note that there are different ways of representing the same segment/offset
- address, but only one absolute pointer representation. If you need to
- compare two addresses, using pointers is terrific. However, it's good to
- keep in mind that an segment/offset address may -appear- to change if you
- convert it to a pointer and then back to a segment/offset address. When you
- convert from a pointer to a segment/offset, the segment will be maximized and
- the offset minimized.
-
- Although the byte count for these routines is handled through a LONG integer,
- the routines handle a maximum of 65,520 bytes at a time. In other words, a
- pointer can only access a bit less than 64K at a time. If I get enough
- requests to extend this range, I will do so. Meantime, that's the limit!
-
- Memory Management and Pointers page 17
-
-
-
- There are two routines which take care of memory management. These allow you
- to allocate or deallocate memory. Note that if you allocate too much memory,
- QuickBASIC won't have any memory to work with! Use the BASIC function
- "SETMEM" to see how much memory is available before going hog-wild.
-
- You can allocate memory like so:
-
- MAllocate Bytes&, Ptr&, ErrCode%
-
- If there isn't enough memory available, an error code will be returned.
- Otherwise, Ptr& will point to the allocated memory. Memory is allocated in
- chunks of 16 bytes, so there may be some memory wasted if you choose a number
- of bytes that isn't evenly divisible by 16.
-
- When you are finished with that memory, you can free it up by deallocation:
-
- MDeallocate Ptr&, ErrCode%
-
- An error code will be returned if Ptr& doesn't point to previously allocated
- memory.
-
- In the best of all possible worlds, there would be a third routine which
- would allow you to reallocate or resize a block of memory. However, due to
- certain peculiarities of QuickBASIC, I was unable to implement that. You can
- simulate such a thing by allocating a new area of memory of the desired size,
- moving an appropriate amount of information from the old block to the new,
- and finally deallocating the old block.
-
- Once you've allocated memory, you can move any sort of information in or out
- of it except normal strings-- fixed-length strings, TYPEd values, arrays, or
- numeric values. To do that, you use BASIC's VARSEG and VARPTR functions on
- the variable. Convert the resulting segment/offset address to a pointer:
-
- TSeg% = VARSEG(Variable)
- TOfs% = VARPTR(Variable)
- VariablePtr& = MJoinPtr&(TSeg%, TOfs%)
-
- Moving the information from one pointer to another works like so:
-
- MMove FromPtr&, ToPtr&, Bytes&
-
- For STRING or TYPEd values, you can get the number of bytes via the LEN
- function. For numeric values, the following applies:
-
- Type Bytes per value
- ======= ===============
- INTEGER 2
- LONG 4
- SINGLE 4
- DOUBLE 8
-
- Memory Management and Pointers page 18
-
-
-
- The "memory move" (MMove) routine is good for more than just transferring
- information between a variable and allocated memory, of course. Pointers can
- refer to any part of memory. For instance, CGA display memory starts at
- segment &HB800, offset 0, and goes on for 4000 bytes in text mode. That
- gives a pointer of &HB8000. You can transfer from the screen to a variable
- or vice versa. For that matter, you can scroll the screen up, down, left, or
- right by using the appropriate pointers. Add two to the pointer to move it
- to the next character or 160 to move it to the next row. As I said, pointers
- have all kinds of applications! You don't need to worry about overlapping
- memory-- if the two pointers, combined with the bytes to move, overlap at
- some point, why, the MMove routine takes care of that for you. It avoids
- pointer conflicts. MMove is a very efficient memory copying routine.
-
- Suppose you've got a pointer and would like to convert it back to the
- segment/offset address that BASIC understands. That's no problem:
-
- MSplitPtr Ptr&, TSeg%, TOfs%
-
- You might also want to fill an area of memory with a specified byte value,
- perhaps making freshly-allocated memory zeroes, for example:
-
- MFill Ptr&, Value%, Bytes&
-
- Finally, there may be many occasions when you might want to transfer a single
- character. Rather than going through putting the character into a STRING*1,
- getting the VARSEG/VARPTR, and using MJoinPtr&, there is a simpler method:
-
- MPutChr Ptr&, Ch$
- Ch$ = MGetChr$(Ptr&)
-
- Hopefully, this will give you some ideas to start with. I'll expand on the
- uses of pointers and give further examples in future versions of BASWIZ.
- There are many, many possible uses for such capabilities. Pointers and
- memory management used to be the only real way in which BASIC could be
- considered inferior to other popular languages-- that is no more!
-
- NOTE:
- QuickBASIC may move its arrays around in memory! Don't expect the address
- of an array to remain constant while your program is running. Be sure to
- get the VARSEG/VARPTR for arrays any time you're not sure they're in the
- same location. Among the things which can cause arrays to move are use of
- DIM, REDIM, or ERASE, and possibly calls to SUBs or FUNCTIONs. I'm not
- sure if anything else may cause the arrays to move, so be cautious!
-
- Telecommunications page 19
-
-
-
- BASIC is unusual among languages in that it comes complete with built-in
- telecommunications support. Unfortunately, that support is somewhat crude.
- Amongst other problems, it turns off the DTR when the program SHELLs or ends,
- making it difficult to write doors for BBSes or good terminal programs. It
- also requires use of the /E switch for error trapping, since it generates
- errors when line noise is encountered, and doesn't provide much control. It
- doesn't even support COM3 and COM4, which have been available for years.
-
- BASWIZ rectifies these troubles. It allows comprehensive control over
- communications, includes COM3 and COM4, and doesn't require error trapping.
- It won't fiddle with the DTR unless you tell it to do so. The one limitation
- is that you may use only a single comm port at a time.
-
- Before you can use communications, you must initialize the communications
- handler. If you didn't have BASWIZ, you would probably use something like:
-
- OPEN "COM1:2400,N,8,1,RS,CS,DS" AS #1
-
- With BASWIZ, you do not have to set the speed, parity, and so forth.
- Communications will proceed with whatever the current settings are, unless
- you choose to specify your own settings. When you initialize the comm
- handler, you specify only the port number (1-4) and the size of the input and
- output buffers (1-32,767 bytes):
-
- TCInit Port, InSize, OutSize, ErrCode
-
- The size you choose for the buffers should be guided by how your program will
- use communications. Generally, a small output buffer of 128 bytes will be
- quite adequate. You may wish to expand it up to 1,500 bytes or so if you
- expect to write file transfer protocols. For the input buffer, you will want
- perhaps 512 bytes for normal use. For file transfer protocols, perhaps 1,500
- bytes would be better. If a high baud rate is used, or for some other reason
- you might not be emptying the buffer frequently, you may wish to expand the
- input buffer size to 4,000 bytes or more.
-
- When you are done with the telecomm routines, you must terminate them. In
- BASIC, this would be done with something like:
-
- CLOSE #1
-
- With the BASWIZ routines, though, you would use this instead:
-
- TCDone
-
- The BASWIZ "TCDone" does not drop the DTR, unlike BASIC's "CLOSE". This
- means that the modem will not automatically be told to hang up. With BASWIZ,
- you have complete control over the DTR with the TCDTR routine. Use a value
- of zero to drop the DTR or nonzero to raise the DTR:
-
- TCDTR DTRstate
-
- Telecommunications page 20
-
-
-
- You may set the speed of the comm port to any baud rate from 1-65,535. If
- you will be dealing with comm programs that were not written using BASWIZ,
- you may wish to restrict that to the more common rates: 300, 1200, 2400,
- 4800, 9600, 19200, and 38400.
-
- TCSpeed Baud&
-
- The parity, word length, and stop bits can also be specified. You may use
- 1-2 stop bits, 6-8 bit words, and parity settings of None, Even, Odd, Mark,
- or Space. Nearly all BBSes use settings of None, 8 bit words, and 1 stop
- bit, although you will sometimes see Even, 7 bit words, and 1 stop bit. The
- other capabilities are provided for dealing with mainframes and other systems
- which may require unusual communications parameters.
-
- When specifying parity, only the first character in the string is used, and
- uppercase/lowercase distinctions are ignored. Thus, using either "none" or
- "N" would specify that no parity is to be used.
-
- TCParms Parity$, WordLength, StopBits
-
- If your program needs to be aware of when a carrier is present, it can check
- the carrier detect signal from the modem with the TCCarrier function. This
- function returns zero if no carrier is present:
-
- IF TCCarrier THEN
- PRINT "Carrier detected"
- ELSE
- PRINT "No carrier"
- END IF
-
- Suppose, though, that you need to know immediately when someone has dropped
- the carrier? It wouldn't be too convenient to have to spot TCCarrier
- functions all over your program! In that case, use the "ON TIMER" facility
- provided by BASIC for keeping an eye on things. It will enable you to check
- the carrier at specified intervals and act accordingly. Here's a brief
- framework for writing such code:
-
- ON TIMER(30) GOSUB CarrierCheck
- TIMER ON
- ' ...your program goes here...
- CarrierCheck:
- IF TCCarrier THEN ' if the carrier is present...
- RETURN ' ...simply resume where we left off
- ELSE ' otherwise...
- RETURN Restart ' ...return to the "Restart" label
- END IF
-
- Telecommunications page 21
-
-
-
- To get a character from the comm port, use the TCInkey$ function:
-
- ch$ = TCInkey$
-
- To send a string to the comm port, use TCWrite:
-
- TCWrite St$
-
- If you are dealing strictly with text, you may want to have a carriage return
- and a linefeed added to the end of the string. No problem:
-
- TCWriteLn St$
-
- Note that the length of the output buffer affects how the TCWrite and
- TCWriteLn routines work. They don't actually send string directly to the
- comm port. Instead, they put the string into the output buffer, and it gets
- sent to the comm port whenever the comm port is ready. If there is not
- enough room in the output buffer for the whole string, the TCWrite/TCWriteLn
- routines are forced to wait until enough space has been cleared for the
- string. This can delay your program. You can often avoid this delay simply
- by making the output buffer larger.
-
- If you'd like to know how many bytes are waiting in the input buffer or
- output buffer, there are functions which will tell you:
-
- PRINT "Bytes in input buffer:"; TCInStat
- PRINT "Bytes in output buffer:"; TCOutStat
-
- Finally, if you would like to clear the buffers for some reason, you can do
- that too. The following routines clear the buffers, discarding anything
- which was waiting in them:
-
- TCFlushIn
- TCFlushOut
-
- Don't forget to use TCDone to terminate the comm handler before ending your
- program! If you do, the computer will lock up. Worse, it may not lock up
- immediately, so forgetting TCDone can be very unpleasant.
-
- Telecommunications page 22
-
-
-
- Finally, there is a routine which allows you to handle ANSI codes in a
- window. Besides the IBM semi-ANSI display code subset, mock-ANSI music is
- allowed. This routine is designed as a subroutine that you can access via
- GOSUB, since there are a number of variables that the routine needs to
- maintain that would be a nuisance to pass as parameters, and QuickBASIC
- unfortunately can't handle SUBs in $INCLUDE files (so SHARED won't work).
- To use it, either include ANSI.BAS directly in your code, or use:
-
- REM $INCLUDE: 'ANSI.BAS'
-
- Set St$ to the string to process, set Win% to the handle of the window to
- which to display, and set Music% to zero if you don't want sounds or -1 if
- you do want sounds. Then:
-
- GOSUB ANSIprint
-
- Note that the virtual screen tied to the window must be at least an 80 column
- by 25 row screen, since ANSI expects that size. You are also advised to have
- an ON ERROR trap if you use ANSIprint with Music% = -1, just in case a "bad"
- music sequence slips through and makes BASIC unhappy. Check for ERR = 5
- (Illegal Function Call). I'll add a music handler later to avoid this.
-
- To get some idea of how these routines all tie together in practice, see the
- TERM.BAS example program. It provides a simple "dumb terminal" program to
- demonstrate the BASWIZ comm handler. Several command-line switches are
- allowed:
- /43 use 43-line mode (EGA and VGA only)
- /COM2 use COM2
- /COM3 use COM3
- /COM4 use COM4
- /300 use 300 baud
- /1200 use 1200 baud
- /QUIET ignore "ANSI" music
-
- By default, the TERM.BAS program will use COM1 at 2400 baud with no parity, 8
- bit words and 1 stop bit. You can exit the program by pressing Alt-X.
-
- Telecommunications page 23
-
-
-
- The Xmodem file transfer protocol is currently supported for sending files
- only. It automatically handles any of the usual variants on the Xmodem
- protocol: 128-byte or 1024-byte blocks, plus checksum or CRC error detection.
- In other words, it is compatible with Xmodem (checksum), Xmodem CRC, and
- Xmodem-1K (single-file Ymodem-like variant).
-
- There are only two routines which must be used to transfer a file. The first
- is called once to initialize the transfer. The second is called repeatedly
- until the transfer is finished or aborted. Complete status information is
- returned by both routines. You can ignore most of this information or
- display it any way you please.
-
- The initialization routine looks like this:
-
- StartXmodemSend Handle, Protocol$, Baud$, MaxRec, Record, EstTime$, ErrCode
-
- Only the first three parameters are passed to the routine. These are the
- Handle of the file that you wish to send (use FOpen to get the handle) and
- the Protocol$ that you wish to use ("Xmodem" or "Xmodem-1K"), and the current
- Baud$. On return, you will get an ErrCode if the other computer did not
- respond, or MaxRec (the number of blocks to be sent), Record (the current
- block number), and EstTime$ (an estimate of the time required to complete the
- transfer. The Protocol$ will have "CHK" or "CRC" added to it to indicate
- whether checksum or CRC error detection is being used, depending on which the
- receiver requested.
-
- The secondary routine looks like this:
-
- XmodemSend Handle, Protocol$, MaxRec, Record, ErrCount, ErrCode
-
- The ErrCode may be zero (no error), greater than zero (error reading file),
- or less than zero (file transfer error, completion or abort). See the
- appendix on Error Codes for specific details. The TERM.BAS example program
- shows how these routines work together in practice.
-
- The file accessed by the Xmodem routine will remain open. Remember to close
- it when the transfer is done (for whatever reason), using the FClose routine.
-
- Telecommunications page 24
-
-
-
- A few notes on the ins and outs of telecommunications...
-
- The DTR signal is frequently used to control the modem. When the DTR is
- "raised" or "high", the modem knows that we're ready to do something. When
- the DTR is "dropped" or "low", the modem knows that we're not going to do
- anything. In most cases, this tells it to hang up or disconnect the phone
- line. Some modems may be set to ignore the DTR, in which case it will not
- disconnect when the DTR is dropped. Usually this can be fixed by changing a
- switch on the modem. On some modems, a short software command may suffice.
-
- The DTR is generally the best way to disconnect. The Hayes "ATH" command is
- supposed to hang up, but it doesn't work very well.
-
- The BASWIZ comm handler makes sure the DTR is raised when TCInit is used. It
- does not automatically drop the DTR when TCDone is used, so you can keep the
- line connected in case another program wants to use it. If this is not
- suitable, just use TCDTR to drop the DTR. Your program must always use
- TCDone before it exits, but it need only drop the DTR if you want it that
- way.
-
- If you want to execute another program via SHELL, it is ok to leave
- communications running as long as control will return to your program when
- the SHELLed program is done. In that case, the input buffer will continue to
- receive characters from the comm port unless the SHELLed program provides
- its own comm support. The output buffer will likewise continue to transmit
- characters unless overruled.
-
- An assortment of file transfer protocols will be provided in future versions
- of BASWIZ. Among the ones supported will be Xmodem, Xmodem-1K, Ymodem
- (batch), and Modem7 (batch). I do not expect to support Kermit or Zmodem,
- since they are unduly complicated. You can handle any file transfer protocol
- you like by SHELLing to an external protocol program, or of course you can
- write your own support code.
-
- The Virtual Windowing System page 25
-
-
-
- The virtual windowing system offers pop-up and collapsing windows, yes... but
- that is just a small fraction of what it provides. When you create a window,
- the part that you see on the screen may be only a view port on a much larger
- window, called a virtual screen. You can make virtual screens of up to 255
- rows long or 255 columns wide. The only limitation is that any single
- virtual screen must take up less than 65,520 bytes. Each virtual screen is
- treated much like the normal screen display, with simple replacements for the
- standard PRINT, LOCATE, and COLOR commands. Many other commands are provided
- for additional flexibility. The window on the virtual screen may be moved,
- resized, or requested to display a different portion of the virtual screen.
- If you like, you may choose to display a frame and/or title around a window.
- When you open a new window, any windows under it are still there and can
- still be updated-- nothing is ever destroyed unless you want it that way!
- With the virtual windowing system, you get a tremendous amount of control for
- a very little bit of work.
-
- The current version of the virtual windowing system only allows text mode
- screens to be used. All standard text modes are supported, however. This
- includes 25x40 CGA screens, the standard 25x80 screen, and longer screens
- such as the 43x80 EGA screen. The virtual windowing system is designed for
- computers that offer hardware-level compatibility with the IBM PC, which
- includes almost all MS-DOS/PC-DOS computers in use today.
-
- Note that certain old and inexpensive CGAs may flicker noticeably when the
- virtual windowing system updates the display. If the performance penalty is
- acceptable, this will be remedied in a future version.
-
-
-
- Terminology:
- -----------
-
- DISPLAY
- The actual screen.
-
- SHADOW SCREEN
- This is a screen kept in memory which reflects any changes you make to
- windows. Rather than making changes directly on the actual screen, the
- virtual windowing system works with a "shadow screen" for increased speed
- and flexibility. You specify when to update the display from the shadow
- screen. This makes any changes appear very smoothly.
-
- VIRTUAL SCREEN
- This is a screen kept in memory which can be treated much like the actual
- screen. You may choose to make a virtual screen any reasonable size.
- Every virtual screen will have a corresponding window.
-
- WINDOW
- This is the part of a virtual screen which is actually displayed. You
- might think of a window as a "view port" on a virtual screen. A window
- may be smaller than its virtual screen or the same size. It may have a
- frame or a title and can be moved or resized.
-
- The Virtual Windowing System page 26
-
-
-
- Frankly, the virtual windowing system is one of those things that's more
- difficult to explain than to use. It's very easy to use, as a matter of
- fact, but the basic concepts will need a little explanation. Rather than
- launching into a tedious and long-winded description of the system, I'm
- going to take a more tutorial approach, giving examples and explaining as I
- go along. Take a look at the DEMO.BAS program for additional insights.
-
- Let's begin with the simplest possible scenario, where only a background
- window is created. This looks just like a normal screen.
-
- REM $INCLUDE: 'BASWIZ.BI'
- DEFINT A-Z
- Rows = 25: Columns = 80 ' define display size
- WInit Rows, Columns, ErrCode ' initialize window system
- IF ErrCode THEN ' stop if we couldn't...
- PRINT "Insufficient memory"
- END
- END IF
- Handle = 0 ' use background handle
- WWriteLn Handle, "This is going to be displayed on the background window."
- WWriteLn Handle, "Right now, that's the full screen."
- WUpdate ' update the display
- WDone ' terminate window system
-
- What we just did was to display two lines on the screen-- nothing at all
- fancy, but it gives you the general idea of how things work. Let's take a
- closer look at what the program does:
-
- - We INCLUDE the BASWIZ.BI definition file to let QuickBASIC know that
- we'll be using the BASWIZ routines.
-
- - We define the size of the display using the integer variables Rows and
- Columns (you can use any variable names you want). If you have an EGA
- display and had previously used WIDTH ,43 to go into 43x80 mode, you'd
- use "Rows = 43" here, for example.
-
- - We initialize the windowing system with WInit, telling it how large the
- display is. It returns an error code if it is unable to initialize.
-
- - We define the Handle of the window that we want to use. The "background
- window" is always available as handle zero, so we choose "Handle = 0".
-
- - We print two strings to the background window with WWriteLn, which is
- like a PRINT without a semicolon on the end (it moves to the next line).
-
- - At this point, only the shadow screen has been updated. We're ready to
- display the information, so we use WUpdate to update the actual screen.
-
- - We're all done with the program, so we finish up with WDone.
-
- The Virtual Windowing System page 27
-
-
-
- See, there's nothing to it! We initialize the screen, print to it or
- whatever else we need to do, tell the windowing system to update the display,
- and when the program is done, we close up shop.
-
- The background screen is always available. It might help to think of it as a
- virtual screen that's the size of the display. The window on this virtual
- screen is exactly the same size, so the entire virtual screen is displayed.
- As with other virtual screens, you can print to it without disturbing
- anything else. That means you can treat the background screen the same way
- regardless of whether it has other windows on top of it-- the other windows
- just "cover" the background information, which will still be there.
-
- This leads us to the topic of creating windows. Both a virtual screen and a
- window are created simultaneously-- remember, a window is just a view port on
- a virtual screen. The window can be the same size as the virtual screen, in
- which case the entire virtual screen is visible (as with the background
- window) or it can be smaller than the virtual screen, in which case just a
- portion of the virtual screen will be visible.
-
- A window is created like so:
-
- ' This is a partial program and can be inserted in the original example
- ' after the second WWriteLn statement...
- VRows = 43: VColumns = 80 ' define virtual screen size
- WOpen VRows, VColumns, 1, 1, Rows, Columns, Handle, ErrCode ' create window
- IF ErrCode THEN ' error if we couldn't...
- PRINT "Insufficient memory available"
- WDone ' (or use an error handler)
- END
- END IF
-
- What we have done here is to create a virtual screen of 43 rows by 80
- columns. The window will be the size of the display, so if you are in the
- normal 25x80 mode, only the first 25 rows of the virtual screen will be
- visible. If you have an EGA or VGA in 43x80 mode, though, the entire virtual
- screen will be visible! So, this window lets you treat a screen the same way
- regardless of the display size.
-
- The Handle returned is used any time you want to print to this new window or
- otherwise deal with it. If you are using many windows, you might want to
- keep an array of handles, to make it easier to keep track of which is which.
-
- By default, a virtual screen is created with the following attributes:
-
- - The cursor is at (1,1), the upper left corner of the virtual screen.
- - The cursor size is 0 (invisible).
- - The text color is 7,0 (white foreground on a black background).
- - There is no title or frame.
- - The window starts at (1,1) in the virtual screen, which displays the
- area starting at the upper left corner of the virtual screen.
-
- The Virtual Windowing System page 28
-
-
-
- When you create a new window, it becomes the "top" window, and will be
- displayed on top of any other windows that are in the same part of the
- screen. Remember, you can print to a window or otherwise deal with it, even
- if it's only partially visible or entirely covered by other windows.
-
- Don't forget WUpdate! None of your changes are actually displayed until
- WUpdate is used. You can make as many changes as you like before calling
- WUpdate, which will display the results smoothly and at lightning speed.
-
- We've created a window which is exactly the size of the display, but which
- might well be smaller than its virtual screen. Let's assume that the normal
- 25x80 display is being used, in which case our virtual screen (43x80) is
- larger than the window. We can still print to the virtual screen normally,
- but if we print below line 25, the results won't be displayed. What a
- predicament! How do we fix this?
-
- The window is allowed to start at any given location in the virtual screen,
- so if we want to see a different portion of the virtual screen, all we have
- to do is tell the window to start somewhere else. When the window is
- created, it starts at the beginning of the virtual screen, coordinate (1,1).
- The WView routine allows us to change this.
-
- In our example, we're displaying a 43x80 virtual screen in a 25x80 window.
- To begin with, then, rows 1-25 of the virtual screen are visible. To make
- rows 2-26 of the virtual screen visible, we simply do this:
-
- WView Handle, 2, 1
-
- That tells the window to start at row 2, column 1 in the virtual screen.
- Sounds easy enough, doesn't it? Well, if not, don't despair. Play with it
- in the QuickBASIC environment a little until you get the hang of it.
-
- You've noticed that the window doesn't need to be the same size as the
- virtual screen. Suppose we don't want it the same size as the display,
- either... suppose we want it in a nice box, sitting out of the way in a
- corner of the display? Well, we could have created it that way to begin with
- when we used WOpen. Since we've already created it, though, let's take a
- look at the routines to change the size of a window and to move it elsewhere.
- The window can be made as small as 1x1 or as large as its virtual screen, and
- it can be moved anywhere on the display you want it.
-
- Let's make the window a convenient 10 rows by 20 columns:
-
- WSize Handle, 10, 20
-
- And move it into the lower right corner of the display:
-
- WPlace Handle, 12, 55
-
- The Virtual Windowing System page 29
-
-
-
- Don't forget to call WUpdate or the changes won't be visible! Note also that
- we didn't really lose any text. The virtual screen, which holds all the
- text, is still there. We've just changed the size and position of the
- window, which is the part of the virtual screen that we see, so less of the
- text (if there is any!) is visible. If we made the window larger again, the
- text in the window would expand accordingly.
-
- If you were paying close attention, you noticed that we didn't place the
- resized window flush against the corner of the display. We left a little bit
- of room so we can add a frame and a title. Let's proceed to do just that.
-
- Window frames are displayed around the outside of a window and will not be
- displayed unless there is room to do so. We have four different types of
- standard frames available:
-
- 0 (no frame)
- 1 single lines
- 2 double lines
- 3 single horizontal lines, double vertical lines
- 4 single vertical lines, double horizontal lines
-
- We must also choose the colors for the frame. It usually looks best if the
- background color is the same background color as used by the virtual screen.
- Let's go ahead and create a double-line frame in bright white on black:
-
- FType = 2: Fore = 15: Back = 0
- WFrame Handle, FType, Fore, Back
-
- If you'd rather not use the default frame types, there's ample room to get
- creative! Frames 5-9 can be defined any way you please. They are null by
- default. To create a new frame type, you must specify the eight characters
- needed to make the frame: upper left corner, upper middle columns, upper
- right corner, left middle rows, right middle rows, lower left corner, lower
- middle columns, and lower right corner.
-
- +----------------------------------------+
- | Want a plain text frame like this? |
- | Use the definition string "+-+||+-+" |
- +----------------------------------------+
-
- The above window frame would be defined something like this:
-
- Frame = 5
- FrameInfo$ = "+-+||+-+"
- WUserFrame Frame, FrameInfo$
-
- Of course, you can choose any values you like. As always, the names of the
- variables can be anything, as long as you name them consistently within your
- program. You can even use constants if you prefer:
-
- WUserFrame 5, "+-+||+_+"
-
- The Virtual Windowing System page 30
-
-
-
- We can have a title regardless of whether a frame is present or not. Like
- the frame, the title is displayed only if there is enough room for it. If
- the window is too small to accommodate the full title, only the part of the
- title that fits will be displayed. The maximum length of a title is 70
- characters. Titles have their own colors.
-
- Title$ = "Wonderful Window!"
- Fore = 0: Back = 7
- WTitle Handle, Title$, Fore, Back
-
- To get rid of a title, just use a null title string (Title$ = "").
-
- There are only a few more ways of dealing with windows themselves. After
- that, I'll explain the different things you can do with text in windows and
- how to get information about a specific window or virtual screen.
-
- If you have a lot of windows, one window may be on top of another, obscuring
- part or all of the window(s) below. In order to make sure a window is
- visible, all you need to do is to put it on top, right? Hey, is this easy or
- what?!
-
- WTop Handle
-
- Note that the background window will always be the background window. You
- can't put handle zero, the background window, on top. What? You say you
- need to do that?! Well, that's one of the ways you can use the WCopy
- routine. WCopy copies one virtual screen to another one of the same size:
-
- WCopy FromHandle, ToHandle
-
- You can copy the background window (or any other window) to another window.
- The new window can be put on top, resized, moved, or otherwise spindled and
- mutilated. The demo program uses this trick.
-
- We've been through how to open windows, print to them, resize them and move
- them around, among other things. We've seen how to put a frame and a title
- on a window and pop it onto the display. If you're a fan of flashy displays,
- though, you'd probably like to be able to make a window "explode" onto the
- screen or "collapse" off. It's the little details like that which make a
- program visually exciting and professional-looking. I wouldn't disappoint
- you by leaving something fun like that out!
-
- Since we're using a virtual windowing system rather than just a plain ol'
- ordinary window handler, there's an extra benefit. When a window explodes or
- collapses, it does so complete with its frame, title, and even its text.
- This adds rather nicely to the effect.
-
- The Virtual Windowing System page 31
-
-
-
- To "explode" a window, we just set up all its parameters the way we normally
- would-- open the window, add a title or frame if we like, print any text that
- we want displayed, and set the screen position. Then we use WExplode to zoom
- the window from a tiny box up to its full size:
-
- WExplode Handle
-
- The "collapse" routine works similarly. It should be used only when you are
- through with a window, because it closes the window when it's done. The
- window is collapsed from its full size down to a tiny box, then eliminated
- entirely:
-
- WCollapse Handle
-
- Note that WExplode and WCollapse automatically use WUpdate to update the
- display. You do not need to use WUpdate yourself and you should make sure
- that the screen is the way you want it displayed before you call either
- routine.
-
- The WCollapse and WExplode routines were written in BASIC, so they'll be easy
- to customize just the way you want them if you register BASWIZ and get the
- source code. They're not particularly difficult routines, however, so you
- might want to design a set of your own similar routines just for the
- exercise. All it takes is moving and resizing the windows.
-
- The great thing about being a programmer is that you can do it your way.
- Hold the pickles, hold the lettuce! Might be fun to add some sound effects
- to those exploding windows, hmmm? I'll do that in a later version, but don't
- feel obliged to wait for me!
-
- That's it for the windows. We've been through all the "tricky stuff". There
- are a number of useful things you can do with a virtual screen, though,
- besides printing to it with WWriteLn. Let's take a look at what we can do.
-
- WWriteLn is fine if you want to use a "PRINT St$" sort of operation. Suppose
- you don't want to move to a new line afterward, though? In BASIC, you'd use
- something like "PRINT St$;" (with a semicolon). With the virtual windowing
- system, you use WWrite, which is called just like WWriteLn:
-
- WWrite Handle, St$
-
- There are also routines that work like CLS, COLOR and LOCATE:
-
- WClear Handle
- WColor Handle, Fore, Back
- WLocate Handle, Row, Column
-
- The WClear routine is not quite like CLS in that it does not affect the
- cursor position. If you want the cursor "homed", use WLocate.
-
- The Virtual Windowing System page 32
-
-
-
- Note that the coordinates for WLocate are based on the virtual screen, not
- the window. If you move the cursor to a location outside the view port
- provided by the window, it will disappear. Speaking of disappearing cursors,
- you might have noticed that our WLocate doesn't mimic LOCATE exactly: it
- doesn't provide for controlling the cursor size. Don't panic! There's
- another routine available for that:
-
- WCursor Handle, CSize
-
- The CSize value may range from zero (in which case the cursor will be
- invisible) to the maximum size allowed by your display adapter. This will
- always be at least eight.
-
- Now, since each virtual screen is treated much like the full display, you may
- be wondering what happens if the cursor is "on" in more than one window.
- Does that mean multiple cursors are displayed? Well, no. That would get a
- little confusing! Only the cursor for the top window is displayed. If you
- put a different window on top, the cursor for that window will be activated
- and the cursor for the old top window will disappear. The virtual windowing
- system remembers the cursor information for each window, but it only actually
- displays the cursor for the window that's on top.
-
- In addition to the usual screen handling, the windowing system provides four
- new capabilities which you may find very handy. These are routines to insert
- and delete both characters and rows. This is done at the current cursor
- position within a selected virtual screen:
-
- WDelChr Handle
- WDelLine Handle
- WInsChr Handle
- WInsLine Handle
-
- These routines can also be used for scrolling. Remember, the display isn't
- updated until you use WUpdate, and then it's updated all at once. You can
- use any of the routines multiple times and the display will still be updated
- perfectly smoothly-- all the real work goes on behind the scene!
-
- When you are done with a virtual screen and no longer need it, you can
- dispose of it like so:
-
- WClose Handle
-
- All of the information that can be "set" can also be retrieved. That's
- useful in general, of course, but it's also a great feature for writing
- portable subprograms. You can create subprograms that will work with any
- virtual screen, since it can retrieve any information it needs to know about
- the virtual screen or its window. That's power!
-
- The Virtual Windowing System page 33
-
-
-
- Here is a list of the available window data retrieval routines:
-
- WGetColor Handle, Fore, Back
- ' gets the current foreground and background colors
-
- WGetCursor Handle, CSize
- ' gets the cursor size
-
- WGetFrame Handle, Frame, Fore, Back
- ' gets the frame type and frame colors
-
- WGetLocate Handle, Row, Column
- ' gets the cursor position
-
- WGetPlace Handle, Row, Column
- ' gets the starting position of a window on the display
-
- WGetSize Handle, Rows, Columns
- ' gets the size of a window
-
- Title$ = SPACE$(70)
- WGetTitle Handle, Title$, TLen, Fore, Back
- Title$ = LEFT$(Title$, TLen)
- ' gets the title string (null if there's no title) and title colors
-
- WGetTop Handle
- ' gets the handle of the top window
-
- FrameInfo$ = SPACE$(8)
- WGetUFrame$ Frame, FrameInfo$
- ' gets the specification for a given user-defined frame type
-
- WGetView Handle, Row, Column
- ' gets the starting position of a window within a virtual screen
-
- WGetVSize Handle, Rows, Columns
- ' gets the size of a virtual screen
-
- The Virtual Windowing System page 34
-
-
-
- As well as displaying information in a window, you will frequently want to
- allow for getting input from the user. Of course, INKEY$ will still work
- fine, but that's not an effective way of handling more than single
- characters. The virtual windowing system includes a flexible string input
- routine which is a lot more powerful:
-
- WInput Handle, Valid$, ExitCode$, ExtExitCode$, MaxLength, St$, ExitKey$
-
- The Valid$ variable allows you to specify a list of characters which may be
- entered. If you use a null string (""), any character will be accepted.
-
- ExitCode$ specifies the normal keys that can be used to exit input. You'll
- probably want to use a carriage return, CHR$(13), for this most of the time.
- You can also specify exit on extended key codes like arrow keys and function
- keys via ExtExitCode$.
-
- MaxLength is the maximum length of the string you want. Use zero to get the
- longest possible string. The length may go up to the width of the virtual
- screen, minus one character. The window will be scrolled sideways as needed
- to accomodate the full length of the string.
-
- The St$ variable is used to return the entered string, but you can also use
- it to pass a default string to the routine.
-
- ExitKey$ returns the key that was used to exit input.
-
- A fairly strong set of editing capabilities is available through WInput.
- The editing keys can be overridden by ExitCode$ or ExtExitCode$, but by
- default they include support for both the cursor keypad and WordStar:
-
- Control-S LeftArrow move left once
- Control-D RightArrow move right once
- Control-V Ins switch between insert and overstrike modes
- Control-G Del delete current character
- Control-H Backspace destructive backspace
- Home move to the start of input
- End move to the end of input
-
- The Virtual Windowing System page 35
-
-
-
- There are two more routines which allow the virtual windowing system to work
- on a wide variety of displays: WFixColor and WSnow.
-
- Chances are, as a software developer you have a color display. However,
- there are many people out there who have monochrome displays, whether due to
- preference, a low budget, or use of notebook-style computers with LCD or
- plasma screens. WFixColor allows you to develop your programs in color while
- still supporting monochrome systems. It tells the VWS whether to keep the
- colors as specified or to translate them to their monochrome equivalents:
-
- WFixColor Convert%
-
- Set Convert% to zero if you want true color (default), or to any other value
- if you want the colors to be translated to monochrome. In the latter case,
- the translation will be done based on the relative brightness of the
- foreground and background colors. The result is guaranteed to be readable on
- a monochrome system if it's readable on a color system. You should check the
- results on your system to make sure that such things as highlight bars are
- still appear highlighted, however.
-
- In the case of some of the older or less carefully designed CGA cards, the
- high-speed displays of the virtual windowing system can cause the display to
- flicker annoyingly. You can get rid of the flicker at the expense of slowing
- the display:
-
- WSnow Remove%
-
- Set Remove% to zero if there is no problem with "snow" or flickering
- (default), or to any other value if you need "snow removal". Using snow
- removal will slow down the display substantially, which may be a problem if
- you update (WUpdate) it frequently.
-
- Note that you can't detect either of these cases automatically with perfect
- reliability. Not all CGA cards have flicker problems. Monochrome displays
- may be attached to CGA displays and the computer won't know the difference.
- A VGA with a paper-white monitor may well think it has color, and will mostly
- act like it, but some "color" combinations can be very difficult to read.
- While you can self-configure the program to some extent using the GetDisplay
- routine (see Just for Kicks), you should also provide command-line switches
- so that the user can override your settings. Microsoft generally uses "/B"
- to denote a monochrome ("black and white") display, so you may want to follow
- that as a standard. I would suggest "/F" to turn on flicker suppression.
-
- And that, folks, is all there is to it. See DEMO.BAS and TERM.BAS for
- working examples. Also see "Telecommunications" for information about a
- routine which handles ANSI display and music codes; it displays to the window
- of your choice.
-
- Just for Kicks page 36
-
-
-
- There are two more routines that may be of some use to you. One of 'em lets
- you find out about the active display adapter. The other tells how much
- expanded (EMS) memory is available.
-
- To see how much expanded memory is available, use the GetEMS function. It'll
- return zero if there is no expanded memory installed:
-
- PRINT "Kbytes of expanded memory:"; GetEMS
-
- The GetDisplay routine tells what kind of display adapter is active and
- whether it's hooked up to a color monitor. The only time it can't detect the
- monitor type is on CGA setups (it assumes "color"). It's a good idea to
- allow a "/B" switch for your program so the user can specify if a monochrome
- monitor is attached to a CGA.
-
- GetDisplay Adapter, Mono
- IF Mono THEN
- PRINT "Monochrome monitor"
- ELSE
- PRINT "Color monitor"
- END IF
- SELECT CASE Adapter
- CASE 1: PRINT "MDA"
- CASE 2: PRINT "Hercules"
- CASE 3: PRINT "CGA"
- CASE 4: PRINT "EGA"
- CASE 5: PRINT "MCGA"
- CASE 6: PRINT "VGA"
- END SELECT
-
- Miscellaneous Notes page 37
-
-
-
- Limitations:
-
- The virtual windowing system allows up to 16 windows to be open at a time,
- including the background window, which is opened automatically. This is
- subject to available memory, of course.
-
- The far string handler allows up to 65,535 strings of up to 255 characters
- each, subject to available memory. When the handler needs additional
- memory for string storage, it allocates more in blocks of 16 Kbytes. If
- that much memory is not available, an "out of memory" error will be
- generated (BASIC error number 7). You can check the size of the available
- memory pool using the SETMEM function provided by QuickBASIC.
-
- The communications handler only allows one comm port to be used at a time.
- This will change in a future version of BASWIZ.
-
- The file handler does not allow you to combine Write mode with Text mode
- or input buffering. This will change in a future version of BASWIZ.
-
- Errors:
-
- All routines are designed to be as bomb-proof as possible. If you pass an
- invalid value to a routine which does not return an error code, it will
- simply ignore the value.
-
- It's always possible that a problem has escaped notice. If you run into
- something that you believe to be a bug or incompatibility, please tell me
- about it, whether you've registered BASWIZ or not.
-
- Feedback:
-
- Do you like what you see? Tell me what you like, what you don't like, and
- what you'd be interested in seeing in future versions! Chances are good
- that I'll use your suggestions. If you don't speak up, though, I won't
- know what you're looking for. You can reach me through U.S. Mail or
- through several of the international BASIC conferences on BBSes.
-
- Error Codes page 38
-
-
-
- The expression evaluator returns the following error codes:
-
- 0 No error, everything went fine
- 2 A number was expected but not found
- 4 Unbalanced parentheses
- 8 The expression string had a length of zero
- 9 The expression included an attempt to divide by zero
-
-
-
- The far string handler does not return error codes. If an invalid string
- handle is specified for FSSet, it will be ignored; if for FSGet, a null
- string will be returned. If you run out of memory for far strings, an "out
- of memory" error will be generated (BASIC error #7). You can prevent this by
- checking available memory beforehand with the SETMEM function provided by
- QuickBASIC. Far string space is allocated as needed in blocks of just over
- 16 Kbytes, or 16,400 bytes to be exact.
-
-
-
- The telecommunications handler returns the following error codes for TCInit:
-
- 0 No error, everything A-Ok
- 1 The comm handler is already installed (you tried to install it twice)
- 2 Invalid comm port specified
- 3 Not enough memory available for input and output buffers
-
-
-
- The telecommunications handler returns these error codes for XmodemSend:
-
- -12 FATAL : Abort due to excessive errors
- -11 FATAL : Abort (by keyboard <ESC> or receiver CANcel request)
- -10 DONE : No error, transfer completed ok
- -5 WARNING : Checksum or CRC error
- -1 WARNING : Time-out error (the receiver didn't respond)
- 0 WORKING : No error, everything A-Ok
- >0 ERROR : Problem reading from the file (see file error codes)
-
- Error Codes page 39
-
-
-
- The file services return the following error codes:
- (The asterisk "*" is used to identify so-called "critical errors")
-
- 0 No error
- 1 Invalid function number (usually means "invalid parameter(s)")
- 2 File not found
- 3 Path not found
- 4 Too many open files
- 5 Access denied (probably "write to read-only file")
- 6 Invalid file handle
- 7 Memory control blocks destroyed
- 8 Insufficient memory (usually RAM, sometimes disk)
- 9 Incorrect memory pointer specified
- 15 Invalid drive specified
- * 19 Tried to write on a write-protected disk
- * 21 Drive not ready
- * 23 Disk data error
- * 25 Disk seek error
- * 26 Unknown media type
- * 27 Sector not found
- * 28 Printer out of paper
- * 29 Write fault
- * 30 Read fault
- * 31 General failure
- 32 Sharing violation
- 33 Lock violation
- * 34 Invalid disk change
- 36 Sharing buffer overflow
-
-
-
- A "critical error" is one that would normally give you the dreaded prompt:
-
- A>bort, R>etry, I>gnore, F>ail?
-
- Such errors generally require some action on the part of the user. For
- instance, they may need to close a floppy drive door or replace the paper in
- a printer. If a critical error occurs on a hard drive, it may indicate a
- problem in the drive hardware or software setup. In that case, the problem
- may possibly be cleared up by "CHKDSK /F", which should be executed directly
- from the DOS command line (do not execute this by SHELL).
-
- Troubleshooting page 40
-
-
-
- Problem:
- QB says "subprogram not defined".
-
- Solution:
- The definition file was not included. Your program must contain the line
- REM $INCLUDE: 'BASWIZ.BI'
- before any executable code in your program. You should also start
- QuickBASIC with
- QB /L BASWIZ
- so it knows to use the BASWIZ library.
-
-
- Problem:
- LINK says "unresolved external reference".
-
- Solution:
- Did you specify BASWIZ as the library when you used LINK? You should!
- The BASWIZ.LIB file must be in the current directory or along a path
- specified by the LIB environment variable (like PATH, but for LIB files).
-
-
- Problem:
- The virtual windowing system doesn't display anything.
-
- Solution:
- Perhaps you left out the WUpdate routine? If so, the shadow screen is not
- reflected to the actual screen and nothing will appear. The screen also
- needs to be in text mode (either no SCREEN statement or SCREEN 0).
- Finally, only the default "page zero" is supported on color monitors.
-
-
- Problem:
- The virtual windowing system causes the display to flicker.
-
- Solution:
- This is a problem with some old CGA setups. You can cure the problem
- permanently and speed up your display into the bargain simply by buying a
- new CGA card (about $35 by mail order). I'll add an optional anti-flicker
- switch to a later version of BASWIZ if the performance penalty is not too
- severe.
-
-
- Problem:
- QuickBASIC doesn't get along with the Hercules display routines.
-
- Solution:
- Are you using an adapter which includes Hercules mode along with EGA or
- VGA mode? QuickBASIC doesn't like that, since it thinks you'll be using
- EGA or VGA mode. Use the stand-alone compiler (BC.EXE) instead of the
- environment (QB.EXE) and you should be fine. You might also consider
- getting a separate Herc adapter and monochrome monitor. It's possible to
- combine a Hercules monochrome adapter with a CGA, EGA or VGA.
-
- Troubleshooting page 41
-
-
-
- Problem:
- QB says "out of memory" (or "range out of bounds" on a DIM or REDIM).
-
- Solution:
- If you're using the memory management/pointer routines, you've probably
- allocated too much memory! You need to leave some for QuickBASIC. Use
- the SETMEM function provided by BASIC to determine how much memory is
- available before allocating memory. The amount needed by QuickBASIC will
- depend on your program. The primary memory-eaters are arrays and
- recursive subprograms or functions.
-
- Many of the BASWIZ routines need to allocate memory, including the virtual
- window manager, telecommunications handler, and memory management system.
- Besides checking with SETMEM to make sure there's memory to spare, don't
- forget to check the error codes returned by these routines to make sure
- they're working properly!
-
- History and Philosophy page 42
-
-
-
- "History," you say. "Philosophy. What the heck does that have to do with a
- BASIC library? Yuck! Go away and leave me alone!"
-
- Ok. This section is not strictly necessary for using BASWIZ. If you're not
- interested, you can certainly avoid reading this without ill effects. "Suit
- yourself," he said with a bow and a flourish.
-
- Still here? Thank you! I'll keep it short.
-
- Back in 'bout 1984 or so, I created ADVBAS, one of the very first assembly
- language libraries for BASIC. That was for IBM BASCOM 1.0, well before
- QuickBASIC came out. I created the library for my own use and ended up making
- a moderately successful shareware project out of it.
-
- ADVBAS was designed in bits and pieces that came along whenever I felt like
- adding to the library or needed a new capability. The routines were designed
- at a low level, with most of the actual work needed to accomplish anything
- useful left to BASIC. All this resulted in a decent amount of flexibility
- but also a good deal of chaos as new routines provided capabilities that
- overlapped with old routines. Although I tried to keep the calling sequence
- reasonably standardized, it didn't always work out that way. Then too, the
- library was designed well before the neat capabilities of QuickBASIC 4.0 came
- into being and couldn't take good advantage of them.
-
- Second came ProBas, a commercial version of ADVBAS. ProBas is a vastly more
- powerful superset of the ADVBAS library. Unfortunately, it suffers from the
- same flaws. No old routines can be discarded or even modified if at all
- possible, to provide compatibility from one version to the next. The lack of
- thought inherent in the original design caused a mad proliferation of
- routines, many overlapping, most still low-level and hard to use. At version
- 4.0, there are over 500 (or is it 600?!) different routines-- something for
- everyone, to be sure, but tending towards complete pandemonium.
-
- The BASWIZ project is a third-generation library. It is designed to overcome
- the liabilities I've encountered with ADVBAS and every other library I've
- seen for BASIC. Rather than being put together haphazardly, one routine at a
- time, I have designed BASWIZ as a coordinated collection. The virtual
- windowing system is an excellent example of this. Rather than having
- separate print routines, window routines, screen saving routines, virtual
- screen routines and all the rest, it is all combined into one single
- package. The routines are designed at a high level, providing a maximum of
- functionality with a minimum of programming effort. The gritty details are
- kept hidden inside the library where you need never deal with them. Consider
- the apparent simplicity of the far string handler! Many more capabilities
- will be added in future versions, but... very carefully.
-
- This library represents the culmination of many years of experience in the
- fields of BASIC and assembly language programming. I have spared no effort.
- It's the best I can offer and I hope you'll forgive me for taking some pride
- in my work! If you find this library powerful and easy to use, I'll count my
- efforts a great success.
-
- As you might have guessed, I'm not exactly in it "just for the money."
- Nonetheless, money is always nice! If you like BASWIZ, please do register.
- That will enable me to upgrade my equipment and design more advanced BASWIZ
- routines. Currently I have a 386SX with an EGA display. I would like to be
- able to support the VGA, scanners, sound boards and other hardware as well.
-
- Using BASWIZ with PDQ page 43
-
-
-
- Crescent's PDQ library does not currently support the SETMEM function, which
- is required by many of the BASWIZ routines. Fortunately, the use of PDQ
- precludes the need for SETMEM, so all we need to do is to include a "dummy"
- SETMEM routine to satisfy LINK:
-
- LINK program+PDQSTUB/NOE,,NUL,PDQ+BASWIZ;
-
- If you use LINK differently, that's fine. The only thing necessary is to
- make sure "+PDQSTUB" is listed just after the name of your program as the
- first LINK argument. Use of /EX and other LINK parameters is no problem.
- Use of other libraries, if any, is also supported.
-
- Crescent thoughtfully provided me with a free copy of PDQ in order that I
- might resolve any incompatibilities between it and BASWIZ. If you are not
- familiar with PDQ, it is a replacement library for BASIC's own runtime
- libraries. While not providing every capability of plain QuickBASIC, it
- allows you to create substantially smaller EXE files for those programs that
- qualify. Support is currently lacking for floating point (single/double
- precision) numbers, music, and graphics, among other things. Communications
- support is available as an add-on. Check with Crescent for more recent
- details.
-
-