home *** CD-ROM | disk | FTP | other *** search
- ;
- ;DOS, Equipment and File Utilities
-
- =======================================================================
- Copyright (C) Copr. 1990 by Sidney J. Kelly
- All Rights Reserved.
- Sidney J. Kelly
- 150 Woodhaven Drive
- Pittsburgh, PA 15228
- home phone 412-561-0950 (7pm to 9:30pm EST)
-
- CompuServe 70043,1656
- Genie S.KELLY8
-
- =======================================================================
-
- These routines provide information concerning the hardware/software
- environment. A few routines are duplicated in PDS 7.1/QBX, though not with
- the same parameters. Some routines provide information about the DOS
- status of a drive or file names. Some routines even return information
- without needing ON ERROR GOSUB. A fair number of hardware routines are
- provided.
- Because I do not have access to PDS 7.x/QBX and its far string
- library, I believe that any of the routines that obtain input or make output
- to strings will not work correctly. Some MASM code is shown below to
- demonstrate how to fix the routines so that they will do the same thing inside
- PDS 7.x/QBS. Jim Mack has released some routines for PDS on COMPUSERVE MSSYS
- TRIMS.ASM. It shows how to pass far strings inside PDS.
-
- =================================================================
- DECLARE FUNCTION ACTUALEXTND% ()
- Returns:
- Actual amount of extended memory installed on 80286, 80386 or 80486
- machine as stored in CMOS RAM
- If clock battery is bad, will return a -1
-
- =================================================================
- DECLARE FUNCTION ANSICHECK%()
- IF ANSICHECK% THEN
- PRINT "ANSI.SYS is installed."
-
- Source: Disassembled COMMAND.COM Version 3.3 of CLS command
- xxxx:2B62h is the beginning of the routine
-
- VERY FAST and NOT MESSY!!!!
-
- This is the same method that COMMAND.COM uses to test for ANSI.SYS
- so every utility had better allow for this testing method.
-
- NOTE: PC Magazine's ANSI.COM even if turned off will still report ANSI.SYS
- present, (it was planned that way so it would handle CLS).
-
- =================================================================
- DECLARE SUB BEEPER
- BEEPER
- Primarily used to show you how to make sound in a somewhat machine
- independent basis
-
- =================================================================
- DECLARE FUNCTION CHECK87%()
- Returns:
- 0 if no 80x87, or system equipment word not set.
- 87 if an 8087
- -87 if 8087 emulation in use on an 80286 or 80386. Because the
- 80287 has almost exactly the same instruction set as the
- 8087, few have felt a need to emulate the 80287. I have not
- seen an 80387 emulator in software. The 80827 just includes
- one new instruction (protected mode), nothing for use in
- real mode. 80387 has transcendental math routines.*
-
- 287 if an 80827
- 387 if an 80387 or 80487
- More accurate than checking the equipment word. QBX, Version 7
- merely checks the equipment word to determine if an 80x87 is installed.
- I guess that can be used as a software toggle.
-
- * Intel recently released an 80287 that has 80387 transcendental math
- routines in it. If someone sends me a new chip, I will write code
- to test for it.
-
- Because of complaints about the traditional test with inexpensive clones
- (See Jon Waterhouse letter in Byte, Nov. 1990, page 40)
- routine first tests the equipment word in RAM bios.
-
- =================================================================
- DECLARE FUNCTION DOSVER% ()
- CALL DOSVER%
- Returns DOS VERSION value as an integer, to get display value \ 100
- E.g. DOS Version 3.3 is returned as 330
-
- =================================================================
- DECLARE SUB DRVSPACE (DRIVE$,SPACE&)
- checks if DRIVE$ <"A" or >"z", or if >"Z" & less <"a"
- Drive of "@" gives the current drive
- Invalid DRIVE$ gives a free space of 0
- Note: DOS does not correctly adjust this if use JOIN or SUBST and
- try to determine the size of a non-default drive.
-
- =================================================================
- DECLARE SUB DRIVEALIAS ( ASSIGN%, DAPPEND%, NETWORK%, SHARE%)
- CALL DRIVEALIAS( ASSIGN%, DAPPEND%, NETWORK%, SHARE%)
- Purpose: To warn programmer that the logical drives may not be as they
- seem, so if programmer desires to do some technical manipulation
- he will be aware that it may not work.
-
- =================================================================
- DECLARE SUB EQUIPMENT(ConvMem%,PrinterPorts%,ComPorts%)
- Returns amount of Conventional Memory in KB
- number of Parallel Ports
- number of COM ports
-
- =================================================================
- DECLARE SUB EXIST (FILNAME$, ErrCode%, Mode%)
- CALL EXIST(FILENAME$+CHR$(0), ErrCode%, Mode%)
- Filename$ must be an ASCII Null string (end in CHR$(0)).
- Filename$ can not be a TYPEd string or a variable in a string array
- because there is a chance that string will be outside DGROUP. String
- cocentenation is used to make sure it is in DGROUP.
-
- Mode%:
- = 0 if just want to see if file exits
- <> 0 if want to see if can read and write to file
-
- Returns ErrCode% = 0 (False) if no error
- = True if an error,
- Codes:
- -1 = string wrong length
- 2 = file not found
- 3 = path not found
- 4 = no free handles
- 5 = access denied (tried to read a subdirectory)
- 12 = invalid access code (wont see this unless Mode% <> 0)
- 20 = Write protect error (wont see this)
- 21 = Invalid drive
- 22 = Drive not ready (floppy drive door open)
- 23 = unknown command
- 24 = CRC error
- 25 = Bad request structure
- 26 = Seek error
- 27 = Unknown disk format
- 28 = Sector not found
- 29 = Printer out of paper (shouldn't see this)
- 30 = Write fault (shouldn't see this)
- 31 = Read fault
- 32 = General, non-specific error (usually a network drive error)
- 35 = Invalid Disk Change (shouldn't see this)
-
- =================================================================
- DECLARE FUNCTION FINDDRIVES% ()
- Returns number of current logical drives w/o any errors
-
- Because LASTDRIVE default value = 5, it is likely that
- number of logical drives will be less than LASTDRIVE in CONFIG.SYS
- This routine will miss a drive if there are gaps between logical drives
- as can occur if SUBST is used.
-
- =================================================================
- DECLARE SUB FLOPPYREADY (DRIVE$, ErrCode%)
- Tests if floppy drive is ready, on a one floppy system
- treats drive B: as equivalent to drive A:
- ErrCode
- 128 = Time Out Error
- 80 = Track error
- -1 = Drive$ is not valid
- 0 = All a.o.k.
- Note : A critical error routine is not necessary for this routine to work
-
- =================================================================
- DECLARE SUB FLOPPYDRIVES(NumDrives%)
- Returns number of physical floppy drives in system
-
- =================================================================
- DECLARE FUNCTION GETCPU% ()
- Checks for CPU type
- Returns:
- 88 for 8088
- 86 for 8086
- 20 for NEC V20
- 30 for NEC V30
- 186 for 80186 or 80188 (I have never seen an 80188 so no special test)
- 286 for 80286
- 386 for 80386DX or 80386SX
- 386 for 80486. I offer no special test for 80486.
-
- =================================================================
- DECLARE SUB GETCURRENTNAME (FName as STRING * 64, FileLength%)
- Returns current filename for dos version 3.xx and above
- if LEN(FName$) <> 64 then returns a FileLength% of -1
-
- FName$ can not be a TYPEd string or a variable in a string array
- because there is a chance that string will be outside DGROUP.
- This routine assumes that FName$ is a near string.
- Function returns an error if DOS version < 3.xx since function is not
- supported for that version.
-
- =================================================================
- DECLARE SUB GETDOSVER (VERSION$)
- VERSION$=SPACE$(4)
- CALL GETDOSVER(VERSION$)
- Returns DOS Version as a string
-
- =================================================================
- DECLARE SUB GETDRIVE(DRIVE$)
- CALL GETDRIVE(DRIVE$)
- Returns current drive name
- If LEN(DRIVE$)=0 then nothing happens
-
- Assumes that DRIVE$ is a near string, not TYPEd or part of a far string
- array. In other words, assumes DRIVE$ is in DGROUP
-
- =================================================================
- DECLARE SUB GETFULLPATH (PATH$, PATHLEN%)
- Returns current subdirectory path, with Drive:\, e.g. "A:\"
- if LEN(Path$) <> 67 then returns a pathlen% of -1
-
- PATH$ can not be a TYPEd string or a variable in a string array
- because there is a chance that string will be outside DGROUP.
- This routine assumes that Path$ is a near string.
-
- =================================================================
- DECLARE SUB GETSUB (PATH AS STRING * 64, PATHLEN%)
- Returns current subdirectory path, without Drive:\, (i.e. no "A:\")
- if LEN(Path$) not = to 64 then returns a pathlen% of -1
-
- PATH$ can not be a TYPEd string or a variable in a string array
- because there is a chance that string will be outside DGROUP.
- This routine assumes that Path$ is a near string.
-
- =================================================================
- DECLARE SUB HARDDRIVES(NoDrives%)
- Returns number of physical hard disks in system
-
- =================================================================
- DECLARE SUB KILLPRINT (LptNum%)
- CALL KILLPRINT(LptNum%)
-
- Halts LptNum%, by resetting and purging buffer. Printer reset to defaults
- all non-default formats lost. Will do nothing if errors noted, printer
- is not busy.
-
- =================================================================
- DECLARE FUNCTION MEM2INT% (SegAddress%,OffAddress%)
- Reads word from memory and returns an integer value
- Faster than PEEK(High_byte) * 256 + PEEK(Low_byte)
-
- =================================================================
- DECLARE SUB MEM2STRING (TEXT$,SegAddress%,OffAddress%)
- Reads bytes from memory and stores them into a string
- number of bytes transferred is = LEN(Text$)
- Assumes string is in near data (DGROUP) & not a fixed length string
- or a user defined TYPE.
-
- =================================================================
- DECLARE SUB OTHERMEMORY(EXTENDED%,EXPANDED%,XMS%)
- Returns size of extended, expanded, and XMS memory.
- Extended = only size that BIOS reports is free
- Expanded = total installed.
- XMS = total installed.
- Uses the rom ID byte approach to determine if extended memory supported.
-
- =================================================================
- DECLARE SUB OTHEROPER (DPMI%, WINDOWS%, DESQ%)
- CALL OTHEROPER(DPMI%, WINDOWS%, DESQ%)
- Purpose: Checks if DPMI, or MS Windows or Quarterdeck DESQVIEW is active
- Returns:
- For each variable that exists -1
- Else if multitasking environment does not exist then returns 0
- Returns 0 if used with DOS versions < 3.x
-
- =================================================================
- DECLARE FUNCTION PRINTRDY%(Lpt%)
- Input:
- Lpt% gives portnumber to test
- Lpt%=1 for LPT1:, 2 for LPT2:, etc
-
- Returns:
- 0 if not ready
- -1 (True) if ready
-
- =================================================================
- DECLARE SUB PRINTSCREEN%(Mode%, Error%)
- IF Error% THEN
- printer error
- else
- all o.k.
- end if
-
- Input: 0 = turn off printscreen key
- 1 = printscreen, then shut down key again
- Prints to LPT1
-
- =======================================================================
- DECLARE SUB REVERSESTRING (A$)
- will reverse A$
-
- DECLARE SUB LEFTROTATE (A$)
- will rotate a string one character to the left
-
- DECLARE SUB RIGHTROTATE (A$)
- will rotate a string one character to the right
-
- =================================================================
- DECLARE SUB SETDRIVE (DRIVE$,ErrCode%)
- no change occurs if DRIVE$ <"A" or >"z", or if >"Z" & less <"a"
- Returns ErrCode% = 0 (False) if no errors
- = -1 (True) if errors
- error checking includes range check and real test if a change occurred
-
- =================================================================
- DECLARE SUB SUBEXIST (PATH$+CHR$(0),ErrCode%)
- Returns ErrCode% = 0 (False) if no errors,
- = -1 (True) if errors
- If a drive change is required, subdirectory on other drive will be made
- the "current" subdirectory on that other drive.
-
- PATH$ cannot be a TYPEd string or a variable in a string array
- because there is a chance that string will be outside DGROUP. String
- cocentenation is used to make sure it is in DGROUP.
-
- =================================================================
- DECLARE SUB SUBSTDRIVE (Drive$,ErrCode%)
- CALL SUBSTDRIVE(Drive$,ErrCode%)
-
- Input:
- Drive$ = letter between A to Z
- If Drive$ ="" or is outside range, assume it is a request for
- default drive information.
-
- Purpose: To warn programmer that the logical drives may not be as they
- seem, so if programmer desires to do some technical manipulation
- he will be aware that it may not work.
-
- Returns:
- 0 = o.k.
- 1 = invalid drive
- 2 = SUBST active on drive
-
- =================================================================
- DECLARE SUB TRUENAME (OrigFile$+CHR$(0), TrueFName$, FileLength%)
- Purpose:
- Allows user to test for SUBST, ASSIGN, and JOIN using an
- undocumented call for DOS Version 3.xx and above
- The returned name will contain technically correct Drive: and Path
- information. However, the OrigFile$ is not checked so ? and * may be
- used, the OrigFile$ may even be nonexistent.
-
- Shortcuts:
- OrigFile$ = "." to obtain current drive & subdirectory name
- OrigFile$ = ".." to obtain immediate parent drive & subdirectory name
-
- Usage:
- TrueFName$ = STR$(67,0)
- CALL TRUENAME(OrigFile$ + CHR$(0), TrueFName$, FileLength%)
- IF FileLength% = -1 THEN
- Error
- ELSE
- TrueFName$=LEFT$(TrueFName$, FileLength%)
- END IF
-
- =================================================================
-
- QBASIC-MASM Interface Theory:
- Generally QBASIC only keeps simple variables, (INT,
- LONGINT, SINGLE and DOUBLE, and STRINGS) in DGROUP. Arrays and
- TYPE records are usually kept outside DGROUP, with only the
- STRING Descriptor or the undocumented Array descriptor kept in
- DGROUP. Thus, the library routines assume that all information
- passed from simple variables is information about a near (DGROUP)
- address. If we pass simple integers to MASM routines, and don't
- care to have MASM change those variables, we use BYVAL to send
- the information to MASM. BYVAL speeds up variable access by a
- factor of two. If we want to have MASM send information back
- about multiple variables, we must pass the address information
- for the variables without using BYVAL. If we use arrays, we must
- use a combination of BYVAL & VARSEG and BYVAL & VARPTR to get the
- information we need to manipulate the information inside the
- arrays. VARSEG and VARPTR are necessary because there is a very
- great chance that the arrays will be stored as far data (i.e. not
- stored in DGROUP). If you must get an array in DGROUP, put the
- array in COMMON.
- Text strings are sent by QBASIC as near address
- (relative to DS and DGROUP). The fist value in the descriptor is
- the length of the string. The second value is the offset address
- inside DGROUP. Fixed length strings and TYPE record strings are
- not referenced with string descriptors. For that reason, I don't
- allow such strings as variables in my routines.
- PDS/QBX Version 7.x stores strings in FAR DATA, outside
- DGROUP. Special routines are offered in the programmer's package
- to find address and length of far strings. Not having access to
- that program (insufficient liquid assets), I can't suggest work
- arounds (I am sure that there are some library routines that will
- give you access). My guess is that string input will work if the
- following format is used
- Inside QBX:
- DECLARE SUB xx(BYVAL SEGADD%, BYVAL OFFADD%, BYVAL
- LENGTH%, ...)
- CALL xx(SSEG(A$), SADD(A$), LEN(A$), ...
-
- Inside MASM:
- .code
-
- STRING SEGMENT AT 0h ;used only for MASM assumptions
- STRING ENDS ;no code is generated.
-
- xx PROC FAR BASIC USES ...,SEGADD:WORD, OFFADD:WORD, LENGTH:WORD
- Push DS
- ...
-
- Mov SI,OFFADD ;offset of string
- Mov CX,LENGTH ;length of string
- Mov AX,SEGADD ;segment address of far string
- ;segment
- Mov DS,AX
-
- Assume DS:STRING ;note lose access to stack
- when change DS
- ...
- Pop DS
- Assume DS:@data
- ...
- Ret
- xx ENDP
- END
- Another approach, which I have not tested is to rely on
- the library routines included inside the QBX environment.
-
- Use the following library calls:
- EXTRN StringAddress:FAR
- EXTRN StringLength:FAR
-
- How to use StringLength (must clear direction flag CLD):
- Basic program must pass address of string descriptor on stack
-
- Push StringDescriptor ; push it back on stack
- call StringLength ; call routine
- length returned in AX
-
- How to use StringAddress (must clear direction flag CLD):
- Basic program must pass address of string descriptor on stack
-
- Push StringDescriptor ; push it back on stack
- call StringAddress ; call routine
- address returned in DX:AX ; DX has segment address, AX has
- ; offset
-
- QBASIC requires that MASM preserve BP, SI, DI, DS, and
- keep the direction flag clear (CLD). All these routines do this.
- You will note that MICROSOFT'S CALL INTERRUPT routines do not
- save BP (apparently to give you access to some EGA VGA palette
- and character font selection routines in the BIOS), and thus will
- crash if a critical error occurs. MICROSOFT offers a replacement
- routine that overcomes this error by preventing any change to BP.
- You should get it if you don't already have it.
- The choice of defining MASM routines as SUB's or
- FUNCTION's depends on whether you want to get information from
- MASM in DX:AX (the format for FUNCTIONs), or if the MASM routine
- either sends back no information or more than one variable (the
- format for SUBs). For simple one variable routines when MASM is
- just returning a value, use FUNCTIONs. To use such functions
- inside QBASIC you must either assign the value of the function to
- a QBASIC variable or use 1) IF ... THEN statements (C style), or
- 2) PRINT statements. For everything else use SUBS.
- Note due to an error in the QBASIC text parser, always
- use the CALL keyword to call the library routines if there is any
- chance that you will use a colon as a separator on a line AND the
- library routine does not take any parameters. Without the CALL
- keyword, the QBASIC parser assumes that the routine name followed
- by a colon is intended as a line label, and not as a SUB name.
- You must use CALL if you will use a SUB that does not need any
- parameters and will follow that SUB name by a colon.
- MASM Theory:
- The MASM routines were designed to be compiled with MS
- QUICK ASSEMBLER, using simplified segment names. They should
- compile with MS MASM 5.1 and above. The DOSSEG keyword might not
- be supported by your version of MASM, so use the MASM keyword
- that arranges the segments in DOS order, rather than ALPHA order.
- If you use TASM with QUIRKS (IDEAL too?) you should be able to
- compile these programs with TASM. Because A86 does not make MS
- .OBJ files, you probably cannot use it. The same may be true
- with OPTASM. The @@, @f, @b are local labels used so I can skip
- ahead without having to think up unique names. Don't use @@, @f,
- @b inside MASM Macros, use LOCAL alphanumeric names instead.
- MASM too easily can lose track of which local label you mean.
- The simplified directives really save time when you
- have to identify variables on the stack, and push and pop
- variables. I use the full PROC function and the regular PROC
- keywords interchangeably. Full PROC format is not necessary when
- there is no need to address variables on the stack (i.e. no need
- to change BP to address the stack) and the QBASIC routine is
- described as a FUNCTION or a SUB that does not take or return
- parameters..
- The EVEN directive is used to word align loops for
- 80286 and 80386 machines. EVEN inserts NOPS as necessary to word
- align loops. The QBASIC BYVAL directive is used to get
- information directly from QBASIC without having to use [BX] or
- [SI] to fish out the correct information. To allow for
- compatibility with the 8088 chip, shifts rather than MULs are
- used for speed. I use .code to store most of my variables to
- save space in DGROUP, which is comparatively tiny and easily
- filed with string data.
- To program in OS/2 .code segment variables are
- "verbotten", and you must use local variables on the stack. I
- don't have access to the OS/2 DOS compatibility box, so I don't
- know how these routines would work under OS/2. I am certain that
- none of these routines would work smoothly under protected mode
- because they often access the BIOS or the hardware.
-
-
- Bibliography:
- General DOS/BIOS routines: Ray Duncan and Peter Norton's
- programming books. If you can only afford one book, get Duncan's.
- Duncan, "Advanced MS-DOS Programming" (2d Ed. Microsoft 1988). Very
- easy to read and to refer to specific routines. The text is very well
- formatted for easy reference.
- Norton, "The New Peter Norton Programmer's Guide to the IBM PC
- and PS/2" (Harper & Row 1988). A book designed to help you visualize
- what is going on. Having been "burned" by writing a book on the PC
- Junior, and experienced the agony of hardware incompatibilities in
- writing the Norton Utilities, Peter wants everybody to use the bios and
- documented DOS routines.
- Bradley, "Assembly Language Programming for the IBM Personal
- Computers" (Prentice Hall 1984). Good technical descriptions of the
- original PC. Only book I have seen that has really shown how to switch
- displays, manipulate DMA, make sound, and manipulate floppy disk drives
- at the PORT level (teaches you why we have BIOS and DOS routines). Good
- book on the 8087. Probably now out of print. I bought my copy at a
- book store that sells remainders.
- DOS Programming:
- Detteman, "DOS Programmer's Reference (2d Ed. Que 1989).
- Excellent book with a very helpful look at undocumented DOS. Doesn't
- preach about not using undocumented DOS as does Peter Norton. Goes
- "mano a mano" with DOS. You should read that material for a complete
- discussion of the undocumented calls contained in my routines.
- Waite Group "Dos Developer's Guide" (2d Ed Howard Sams 1989).
- Good book on Expanded memory and math chips. Several good discussions
- of the undocumented DOS functions. Such a big book, that you feel you
- got your money's worth based just on weight.
- General Programming:
- Holzner, "PS/2-PC Assembly Language" (Brady 1989) Good
- introduction to assembly language programming. In many respects much
- better than Holzner, "Advanced Assembly Language on the IBM PC" (Brady
- 1987).
- Tischer, "PC System Programming for Developers" (ABACUS 1989).
- Good technical survey of PC/AT systems. Comes with a lot of programs
- showing how to do useful things in MASM, GWBASIC, PASCAL and C. The
- only shortcoming is that the book is printed on very cheap paper. One
- of the few books to show register usage of DOS and BIOS routines
- (important so you can save variables in registers rather than in memory
- or pushed on the stack.) Doesn't discuss DOS Version 4 in an integrated
- fashion. Such a big book, that you feel you got your money's worth
- based just on weight.
- Young, "Inside DOS: A Programmer's Guide", (Sybex 1990). Good
- source of MASM code, with a primary emphasis on C (The MASM code is
- similar for both C and QBASIC). A reprint of "MS DOS Advanced
- Programming" (Sybex 1988). (I didn't discover this until I purchased
- both).
- Wyatt, "Using Assembly Language" (2d Ed. QUE 1989). Some decent
- video routines. No useful description of VGA. EGA routines are
- primitive. Good insight into programming for high level languages.
- Complete listing of all the Intel keywords, but reads too much like an
- Intel-English dictionary. Most of the examples in the keyword section
- are not really helpful and the ASCII math routines are not well
- described. One major programming feature dropped from the 1st edition
- was the AT keyboard programming routines. Does this mean AT keyboards
- are only marginally compatible on the hardware level? Feedback please.
- QBASIC Programming:
- Goodwin, "QuickBASIC Advanced Programming Tools" (MIS 1989). A
- much better book for QBASIC code (sorting, popup windows, dropdown
- windows and menubar programs) than for MASM code. The MASM code relies
- on video bios to do things (which is slow, though always compatible).
- Moreover, screens are stored in STRINGs rather than arrays, which
- greatly limits the usefulness of his MASM routines. (I agree storing
- screens in arrays takes more work). A programmer can have access to
- several hundred KB of far data in arrays, while he can only have access
- to 30 to 40kb of precious string space in DGROUP. PDS 7.1 gives access
- to about 190(?) kb of string space using far strings. Goodwin's book
- was written before PDS was released.
- Lesser, "Advanced Quickbasic 4.0 Language Extensions with
- Modular Tools" (Bantam 1988). This is how I learned about MASM/QBASIC
- programming. Talks more about ideas that were important for QBASIC
- Version 3.0 -- MASM pre-version 5.1 (before simplified directives) than
- for QBASIC Version 4.x. BELIEVES in structured programming. Not too
- many hardware insights even though hardware insights are necessary for
- fast video programming. Offers generally sound advice.
- Microsoft, "QuickBasic Toolbox" Generally, useful collection of
- routines. Very speedy string routines, some good formatting and a good
- set of long int days between dates routines. Some little insight into
- Quick C - Basic interfacting using Quick C library routines. The DOS
- InterruptX routines are generally useful, however, they do not warn of a
- problem inside QBASIC that can cause QBASIC to lock up. The error
- occurs if a critical error (typically disk error) occurs inside a Call
- Interrupt/InterruptX routine.
- Reason for error: Because the Microsoft supplied version of that
- routine allows the programmer to change BP, any critical error causes
- QBASIC to get lost. All smart programmers should obtain, from
- Microsoft's on-line knowledgebase on GENIE and COMPUSERVE, a copy of the
- revised routine and NOCOM.OBJ (makes some programs smaller by turning
- off all of QBASIC overhead associated with the COM ports) from
- Microsoft. The revised Interrupt/InterruptX routines prevents any
- change to BP at the cost of a minor loss of funtionality in EGA/VGA font
- routines.
- Shammas, "QuickBASIC- Programming Techniques and Library
- Development" (M&T Publishing 1988). Good QBASIC code. Some of the
- string routines are fast. He has some BTREE and high level math
-
- What's available:
- VIDBASIC - A selection of text mode video routines. Freeware.
- The library allows the user to select, move, switch, change, save,
- restore, draw boxes, and write with lightening speed. MASM .ASM code,
- .OBJ, and a demo routine with source is included. Uploaded by author on
- GENIE and COMPUSERVE.
- KEYBASIC - A selection of Microsoft Compatible Mouse and
- Keyboard utilities. Text mode mouse utilities. Fast mouse utilities.
- Turn off CONTROL-BREAK so you can use LINE INPUT$ without error if user
- pushes the Control-Break key. Freeware. MASM .ASM code, .OBJ, and a
- demo routine with source is included. Uploaded by author on GENIE and
- COMPUSERVE.
-
- I don't anticipate I will do much more with any of these three
- libraries. My next effort is to make menu environment similar to the
- environment inside QuickBasic, using the building blocks I have created.
- After that, I will probably try to figure out Quick C and convert much
- of the library to Quick C format. I figure by the time I begin to
- understand Quick C, an OOPS form of Quick Basic will come out and much
- of my work will be for naught.
- As always, constructive criticism is desired. These libraries
- were released as Freeware to encourage a sharing of ideas. If you have
- something to say, I welcome your comments. With application programs
- there appears to be a significant and speedy exchange of ideas,
- programmers, on the other hand, seem to move at a much slower pace, with
- Jim Mack being the notable exception.