home *** CD-ROM | disk | FTP | other *** search
Text File | 1990-02-02 | 110.4 KB | 2,891 lines |
- Volume 1, Number 2 February 2, 1990
-
-
-
-
-
-
-
-
-
-
-
-
- **************************************************
- * *
- * QBNews *
- * *
- * International QuickBASIC Electronic *
- * Newsleter *
- * *
- * Dedicated to promoting QuickBASIC around *
- * the world *
- * *
- **************************************************
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews is an electronic newsletter published by Clearware
- Computing. It can be freely distributed providing NO CHARGE is charged
- for distribution. The QBNews is copyrighted in full by Clearware
- Computing. The authors hold the copyright to their individual
- articles. All program code appearing in QBNews is released into the
- public domain. You may do what you wish with the code except
- copyright it. QBNews must be distributed whole and unmodified.
-
- You can write The QBNews at:
-
- The QBNews
- P.O. Box 507
- Sandy Hook, CT 06482
-
- Copyright (c) 1989 by Clearware Computing.
-
-
-
- The QBNews Page i
- Volume 1, Number 2 February 2, 1990
-
-
- ----------------------------------------------------------------------
-
- T A B L E O F C O N T E N T S
-
-
- 1. From the Editors Desk
- With a future so bright, I got to wear shades ... ............ 1
-
- 2. Mail Bag
- Mail From Our Readers ........................................ 2
-
- 3. Algorithms
- Fast String Searching in QuickBASC by Ethan Winer ............ 4
- Reversing INSTR by Larry Stone ............................... 6
-
- 4. Who ya gonna call? CALL INTERRUPT
- Using the PSP by Hector Plasmic .............................. 9
-
- 5. Product Announcements
- Microsoft Professional BASIC 7.0 ............................. 13
- Index Manager CDP Consultants .............................. 15
- MicroHelp Library Manager .................................... 16
-
- 6. The Tool Shed
- Update on MicroHelp's QB Optimizer Package by Larry Stone ... 19
-
- 7. Ask MR. WIZZARD
- Mr. Wizard tells what "Bytes Free" means ..................... 20
-
- 8. Graphically Speaking
- Getting and Putting Graphics by Frederick Volking ............ 22
-
- 9. And I Heard it Through the Grapevine
- Exerpts from the QUIK_BAS echo ............................... 30
-
- 10. Some Assembly Required
- Retuning Errorlevels to QB by Harold Thomson ................. 34
-
- 11. Swap Shop
- Extended Key Codes ........................................... 39
- Menus ........................................................ 43
-
- 12. Input Past End
- Contacting the QBNews ........................................ 47
-
- The QBNews Page ii
- Volume 1, Number 2 February 2, 1990
-
-
-
- ----------------------------------------------------------------------
- F r o m t h e E d i t o r s D e s k
- ----------------------------------------------------------------------
-
- The Future of the QBNews by David Cleary
-
- With this issue, I can say I am actually proud. The support you
- have shown has been overwhelming. I just feel that this newsletter
- will take off because the better it gets, the more support it will
- receive. The more support it receives, the better it will get. It's a
- viscous circle.
-
- I have received some very nice letters from people. Two of them
- are in our Mailbag section. I would like to here suggestions on what
- you would like to see in this newsletter. With every issue, we will
- continue to evolve to suit the needs of the QuickBASIC programmer. I
- do feel that this issue does not address the needs of the beginner. I
- would like to see a section devoted to beginners so if anybody out
- there has some ideas, please contact me.
-
- I am also thinking of making the QBNews available on disk. If you
- are interested in receiving it on disk, for a nominal charge, let me
- know. If enough would like it this way I may institute it for the next
- issue. Also, if you write me, I would be interested in knowing where
- you got your issue.
-
- One final note. I would like this newsletter distributed
- internationally, specifically England and Australia. If you run a BBS
- in either of these countries, I would be interested in hearing from
- you. I would be willing to upload it to your board. If anybody outside
- of the USA or Canada is reading this, I want to here from you. I'd
- like to know that this is being distributed as widely as possible.
- Until April, goodbye.
-
- David Cleary
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 1
- Volume 1, Number 2 February 2, 1990
-
-
-
- ----------------------------------------------------------------------
- M a i l B a g
- ----------------------------------------------------------------------
-
-
- Dear Mr. Cleary,
-
- Your news letter is a great idea, please continue it. The
- programs were, also, very informative and useful. In the section
- describing the program, SCRNSUBS.BAS, you make this statement.
-
- "The only problem when using internal QB routines is that I
- haven't found a way to use them in the environment."
-
- I have found a way by making a Quick Library with the routine.
- The routine will only work if you include the DECLARE statement in the
- module.
-
- Examples: DECLARE SUB MemCopy ALIAS "B$ASSN" (BYVAL...
-
- DEFINT A-Z
- SUB ScrSave (Buffer(), Page) STATIC
- .
- .
- END SUB
-
- Compile: BC SCRSAVE/O;
- LINK /Q SCRSAVE, SCRSAVE.QLB,, BQLB45.LIB;
-
- Environment: A DECLARE statement is not needed, just make your
- calls.
-
- Call ScrSave(Buffer(), Page)
-
-
- Gaylon Hill
- Louisville, TN
-
- [EDITOR'S NOTE]
-
- It seems that the simplest way is the one that works. I was busy
- trying a bunch of convoluted ways to do it with no luck at all. Thanks
- for sharing this with us. David Cleary
-
-
- Dear Mr. Cleary,
-
- I just read your QBNews Vol 1 No 1 which I picked off the Probas
- BBS. Great idea. I am like most other BASIC programmers, no training,
- ever. However, I am interested in the things that interrupts can do.
- The catch is, I really don't understand what an interrupt is ect. I
- can duplicate Hector's code but that's about it. How about getting
- Hector to write a little about interrupts and what they are and what
- the terminology means.
-
-
- The QBNews Page 2
- Volume 1, Number 2 February 2, 1990
-
- John F. Farrell
- Mesquite, TX
-
- [HECTOR'S RESPONSE]
-
- I'm not gonna go all techie on you here, so relax. But what is
- an interrupt anyway? About what the name implies. When an interrupt
- occurs, the central processing unit (CPU) "interrupts" what it's doing
- and transfers control to an interrupt handler. The handler is
- responsible for determining the cause of the interrupt and taking
- appropriate action, then returning control to the interrupted process.
-
- The CPU knows where the interrupt handlers are located by looking
- up their addresses in special sections of memory known as the
- interrupt vector table. In this way an interrupt can be replaced or
- chained.
-
- Software interrupts, the ones we're using in this column, can be
- triggered by any program by using the INT instruction (QuickBASIC does
- that for you when you use CALL INTERRUPT). Interrupt 21h is the MS-
- DOS function dispatch interrupt, which provides easy access to many
- operating system functions not directly available through QuickBASIC.
- Other interrupts can also be useful, notable 10h (for IBM-compatibles)
- for video, 13h for disk control, 16h for the keyboard, and so forth.
-
- There are several readily available books covering the various
- MS-DOS and BIOS interrupts, and an excellent file (in archive format)
- called INTER489 from Ralf Brown (1:129/46 at last report) if you'd
- like to learn more about them.
-
- Hector Plasmic
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 3
- Volume 1, Number 2 February 2, 1990
-
-
-
- ----------------------------------------------------------------------
- A l g o r i t h m s
- ----------------------------------------------------------------------
-
- FAST STRING SEARCHING IN QUICKBASIC by Ethan Winer
-
- A wise programmer once said, "You can never write a sort routine
- that's fast enough or small enough." No doubt, this same philosophy
- holds true for string searching routines. Therefore, I was quite
- interested to see an article in the July/August Programmers Journal
- which presented an assembly language version of the Boyer-Moore
- searching algorithm. Compared to some of the other implementations I
- had seen, this one appeared to be very tight and well coded. I've
- written a few searching routines myself to use with QuickBASIC string
- arrays, and was very eager to see how much faster this "new" method
- would be.
-
- After carefully modifying the printed routine to work with
- QuickBASIC 4.5, I devised a short test program to time it. My
- benchmark searched a 10,000 character string in a loop, and compared
- two algorithms -- the Boyer-Moore routine published in Programmers
- Journal, and QuickBASIC's built-in INSTR function. However, based on
- the results I obtained, it appears that the Boyer-Moore method is
- little more than a mathematical curiosity. Indeed, it was only half
- as fast as QuickBASIC!
-
- HOW QUICKBASIC DOES IT
-
- So how does QuickBASIC search strings so fast? A quick
- examination under Microsoft CodeView reveals a fundamentally simple,
- yet elegant algorithm. I have adapted QuickBASIC's method (with
- permission from Microsoft), and named it SearchString. This is shown
- in Listing 1. Please understand that this routine is not intended for
- use with QuickBASIC. Rather, it is to provide a foundation for
- achieving BASIC's high performance in other high-level languages. If
- you do intend to try SearchString with QuickBASIC, bear in mind that
- it has been designed as a function, and therefore must be declared.
- Assembler functions were added to QuickBASIC beginning with version
- 4.00, and they are one of the most important features that Microsoft
- has added to the language.
-
- Three passed parameters are required to specify the starting
- character, the string being searched, and the sub-string to locate.
- Even though this version uses the same basic algorithm as QuickBASIC,
- it is slightly faster because it does not check for an illegal Start
- parameter. Also, the start variable is passed "by value", rather than
- by address which is the method used by most high-level languages.
- This eliminates an extra step of locating the variable within the
- assembler routine, thus saving a few bytes and clock cycles.
-
- Rather than relying on a purely "brute force" approach that
- compares every character in both strings, QuickBASIC instead isolates
- the first character. In this case, it is loaded into AL. Then the
- 8088's speedy Scasb instruction is used to find the first occurrence
- where a possible match might begin. The beauty of this approach is
-
- The QBNews Page 4
- Volume 1, Number 2 February 2, 1990
-
- twofold -- Scasb is the fastest way to find a single matching
- character, and subsequent searches then require comparing one less
- character in each string.
-
- SearchString begins by obtaining the starting character offset in
- the string being searched. Even though most situations would require
- searching the entire string, being able to resume a search in the
- middle of the string is often valuable. Next, SI and DI are loaded
- with the address of the first character in each string, and CX is
- assigned the number of characters to search. Unlike C or Pascal,
- BASIC maintains a string descriptor which tells how long a string is,
- and where in near memory its data is located. The final
- initialization steps are to adjust DI to point to the correct portion
- of the string being searched, and to load AL with the first character
- of the string to find.
-
- The main loop begins at the Scan label, and ends at the label
- Found. When Scasb finds a character that matches the one in AL, the
- remaining characters in both strings are compared. If a match is
- found, SearchString returns to the caller with AX holding the offset
- into the source string. Otherwise, Scasb is used again to find the
- next occurrence of the first character. This is repeated until either
- the search string is located, or the source string is exhausted.
-
- ADAPTING THE ROUTINE TO OTHER LANGUAGES
-
- SearchString may be easily modified to work with C, Pascal,
- assembly language, or whatever by simply changing how the various
- registers are initially loaded. For example, the length of a string in
- Pascal is stored in the byte that precedes its first character.
- Conversely, C uses a zero-byte to mark the end of its strings, which
- means that extra steps (and time) will be needed to determine their
- length before beginning the search. SearchString could also be
- modified to accept additional parameters for the string lengths when
- called from C to save that added overhead. Indeed, BASIC's use of
- string descriptors is one of the primary reasons it is so fast at
- string operations.
-
- I believe it is important to point out how fast and well-designed
- BASIC really is. Many programmers unfairly criticize BASIC as a
- language, solely because of the interpreter that comes with DOS.
- Besides being extremely easy to use, current versions of QuickBASIC
- offer a wealth of structured programming features, while offering more
- commands and features than any other high-level language. And as we
- have seen, QuickBASIC is also aptly named.
-
- Ethan Winer is President of Cresent Software and the author of
- QuickPak and PDQ.
-
- [EDITORS NOTE]
- The source code to String Search is in the archive SSEARCH.ZIP.
-
-
-
-
- The QBNews Page 5
- Volume 1, Number 2 February 2, 1990
-
- The Speedy INSTR Function - Programming a Backwards INSTR Routine
- by Larry Stone
-
- One of the easiest traps to fall into is using the FOR...NEXT
- loop to search a string for a sub-string. I call it a trap because it
- seems the obvious choice of functions to use, when, often-time, it is
- neither the fastest, nor the best of available choices.
-
- The choice of the FOR...NEXT loop seems the obvious because when
- we use it, we do so on a variable who's length is known. So why not
- just step through it, character by character, and look for the sub-
- string?
-
- The drawback in using the FOR...NEXT loop is, primarily, speed.
- A typical use (as demonstrated by the correspondence in the Quik_BAS
- echo) is finding the starting point of a sub-string, i.e., looking for
- a file name embedded within a complete path and filename statement.
- Now, let's look what happens when you use a FOR...NEXT loop:
-
- fullName$ = "C:\UTILITY\DISK\PCTOOLS\PCTOOLS.EXE"
- length% = LEN(fullName$)
- FOR A% = 1 TO length%
- IF MID$(fullName$, A%, 1) = "\" THEN B% = A%
- NEXT
-
- In the above example, we are looking for a sub-string composed of
- only one backslash character. The string to search is 35 characters
- long. This means we must loop 35 times in order to find four
- occurrences of the sub-string. Pretty inefficient, isn't it? All we
- wanted was the last occurrence of the backslash character and we had
- to loop 35 times only to discover that the last occurrence was at
- position 24 (In the above example, B% will equal 24).
-
- The INSTR function handles the above solution in a much more
- elegant manner. The example below is a backwards INSTR routine.
- Although it does not, in actuality, step negatively through a string,
- it quickly reports the last occurrence of any sub-string.
-
- fullName$ = "C:\UTILITY\DISK\PCTOOLS\PCTOOLS.EXE"
- searchString$ = fullName$
- subString$ = "\"
- P% = BackInstr%(0, searchString$, subString$)
- PRINT "The last position of the backslash is"; P%
-
- FUNCTION BackInstr% (start%, searchString$, subString$)
- IF start% = 0 THEN start% = 1
- N% = INSTR(start%, searchString$, subString$)
- A% = N%
- DO WHILE N%
- N% = N% + 1
- N% = INSTR(N%, searchString$, subString$)
- IF N% THEN A% = N%
- LOOP
- BackInstr% = A%
- END FUNCTION
-
- The QBNews Page 6
- Volume 1, Number 2 February 2, 1990
-
-
-
- The elegance of this function is that your DO...LOOP executes
- exactly four times - once for each occurrence of the backslash! Speed
- of execution is achieved because there is only four iterations of the
- loop instead of the 35 in the FOR...NEXT loop, and speed of execution
- is further improved because of the way the BASIC's INSTR function
- works.
-
- The INSTR function does not do a "brute-force" evaluation,
- comparing every character in both strings. Instead, it isolates the
- first character and then looks for the first occurrence of a possible
- match. Looking for a single character is much faster than checking
- every character. If a match is found, and if subString$ had more
- characters in it, then the next character is searched. If the next
- character is not matched, INSTR proceeds from the next position in the
- string where the first match was found, requiring that much less
- string to search. The actual asm instruction used is scasb. This
- technique is twice as fast as the Boyer-Moore algorithm, considered by
- many as a bench-mark. For a more exact description of the process,
- read an article called, "QuickBASIC's Fast String Searching
- Algorithm", in the Programmer's Journal, 7.6, authored by Ethan Winer
- of Crescent Software.(See Above)
-
- Would you like your programs, when they search for a sub-string,
- to search for exact matches as well as, embedded matches? Simply swap
- the locations of the search string and the sub-string. Here's how
- INSTR can work for you:
-
- searchString$ = "These"
- subString$ = "The"
- start% = 1
-
- '---- Check one string against the other.
-
- N% = INSTR(start%, searchString$, subString$)
- IF N% THEN
-
- '---- If a match was found, swap locations and search again.
-
- N% = INSTR(subString$, searchString$)
- IF N% THEN
-
- '---- Now, if a match was found then it's an exact match.
-
- PRINT "Sub-String is Exact Match of Search String"
- ELSE
-
- '---- Otherwise, it's an embedded match.
-
- PRINT "Sub-String is Embedded in Search String"
- END IF
- ELSE
-
- '---- The sub-string was not located in the Search String.
-
- The QBNews Page 7
- Volume 1, Number 2 February 2, 1990
-
-
- PRINT "Sub-String is Not Found in Search String"
- END IF
-
-
- The example above will report that N% is equal to one because
- "The" is a subset of "These". To have this code determine whether
- "The" and "These" are exact matches would require the BackInstr
- function. Use it to find the end of the word that was matched (use a
- space, period, and hyphen as sub-strings). When you know where the
- end of the word is, simply state that: word$ = MID$(searchString$, N%,
- P%). Then, use the INSTR function to compare INSTR(subString$,
- word$).
-
- If you wish to move through the searchString$ for the next
- occurrence of a match, place all but the first three lines of code
- within a DO WHILE start%...LOOP. If N% is some positive value, then,
- at the bottom of the loop, LET start% = N% + 1. Otherwise, if N% is
- zero, then LET start% = N% to end the loop. When you are searching
- for more than one occurrence of a match, you should have an escape key
- assigned to get you out of the loop. A$ = INKEY$: IF A$ = CHR$(27)
- THEN EXIT DO works quite well.
-
- One word of caution. The INSTR function returns zero whenever a
- compiled .EXE uses the literals CHR$(1) or CHR$(2) in a string. This
- should not, however, cause any problems in QB's environment.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 8
- Volume 1, Number 2 February 2, 1990
-
-
-
- ----------------------------------------------------------------------
- W h o y a g o n n a c a l l ? C A L L I N T E R R U P T
- ----------------------------------------------------------------------
-
- Using the PSP by Hector Plasmic
-
-
- COMMAND$ lets you see what was entered on the command line (the
- command tail) by the user when your program was started. For
- instance, if the user typed:
-
- C:\> PROGRAM -a -b
-
- PRINT COMMAND$ would display "-A -B". Notice that the command
- tail was uppercased by COMMAND$, though. What if you need to receive
- case sensitive information from the command line?
-
- Well, it just happens that DOS can provide you with the answer.
- DOS keeps an area called the PSP (program segment prefix) which
- contains a lot of potentially useful information in the following
- format:
-
- 0000h Interrupt 20h
- 0002h Segment, end of allocation block
- 0004h Reserved
- 0005h Long call to MS-DOS function handler
- 000Ah Previous contents of termination handler interrupt vector
- (Int 22h)
- 000Eh Previous contents of CTRL-C interrupt vector (Int 23h)
- 0012h Previous contents of critical-error interrupt vector (Int 24h)
- 0016h Reserved
- 002Ch Segment address of environment block
- 002Eh Reserved
- 005Ch Default file control block #1
- 006Ch Default file control block #2 (overlaid if FCB #1 opened)
- 0080h Command tail and default DTA (buffer)
-
- So, to get the command tail in its pre-uppercased format, all we
- have to do is PEEK into the PSP. But how do we find out where the PSP
- is? Interrupt 21h function 62h will get it for you, returning the
- PSP's segment in register .bx. If DEF SEG is set to the returned .bx
- value, PEEK will be looking at the PSP.
-
- What follows is a simple program to get the command tail from the
- PSP, list the environment, and return the name of the program that's
- currently running.
-
-
- DEFINT A-Z
-
- TYPE RegType
- AX AS INTEGER
- BX AS INTEGER
- CX AS INTEGER
- DX AS INTEGER
-
- The QBNews Page 9
- Volume 1, Number 2 February 2, 1990
-
- BP AS INTEGER
- SI AS INTEGER
- DI AS INTEGER
- Flags AS INTEGER
- END TYPE
-
- TYPE RegType2
- AX AS INTEGER
- BX AS INTEGER
- CX AS INTEGER
- DX AS INTEGER
- BP AS INTEGER
- SI AS INTEGER
- DI AS INTEGER
- Flags AS INTEGER
- DS AS INTEGER
- ES AS INTEGER
- END TYPE
-
- 'You must link in QB.LIB (QB.QLB) for Interrupt
-
- DECLARE SUB Interrupt (Intnum%, InReg AS RegType, OutReg AS RegType)
- DECLARE SUB InterruptX (Intnum%, InReg2 AS RegType2, OutReg2 AS
- RegType2)
-
- DIM SHARED InReg AS RegType
- DIM SHARED OutReg AS RegType
-
- InReg.AX = 25088 'Find PSP
- Interrupt &H21, InReg, OutReg
-
- DEF SEG = OutReg.BX 'Segment of PSP
-
- EnvLo = PEEK(&H2C) 'The pointers from the PSP to our copy of the
- EnvHi = PEEK(&H2D) 'environment
-
- ComlineLength = PEEK(&H80) 'Length of command tail in PSP
-
- CLS
- PRINT " Command tail:": PRINT
-
- 'Print command tail
-
- FOR X = &H81 TO &H81 + ComlineLength - 1
- PRINT CHR$(PEEK(X));
- NEXT
-
- PRINT : PRINT
-
- DEF SEG = EnvLo + (EnvHi * 256) 'Segment of environment
-
- X = 0
-
- 'Print environment
-
-
- The QBNews Page 10
- Volume 1, Number 2 February 2, 1990
-
- PRINT " Environment:": PRINT
-
- DO UNTIL PEEK(X) = 0
- DO UNTIL PEEK(X) = 0
- PRINT CHR$(PEEK(X));
- X = X + 1
- LOOP
- PRINT
- X = X + 1
- LOOP
- PRINT
-
- X = X + 3
-
- PRINT " Program drive:\path\name:": PRINT
-
- 'Print program filespec
-
- DO UNTIL PEEK(X) = 0
- PRINT CHR$(PEEK(X));
- X = X + 1
- LOOP
-
- PRINT
-
- END
-
-
- Knowing where the PSP is gives you yet another advantage. When a
- QuickBASIC program RUNs another program outside the environment, the
- RUN program inherits the old PSP, _including_ the old command tail.
- If we change that command tail before RUNning the new program, we can
- pass arguments to it as if they were typed on the command line!
- Here's the Sub to do it:
-
-
- '
- SUB RunIt (Tail$, Prog$) 'Changes command tail and RUN program
-
- InReg.AX = 25088 'Find PSP
- Interrupt &H21, InReg, OutReg
-
- DEF SEG = OutReg.BX 'Point PEEK and POKE at it
-
- Text$ = Text$ + " " + CHR$(13) 'Prep the new command tail
- POKE &H80, LEN(Text$) - 1 'Poke the length
-
- FOR X = &H81 TO &H81 + LEN(Text$) 'Poke the string
- POKE X, ASC(MID$(Text$, X - &H80, 1) + " ")
- NEXT
-
- RUN Prog$ 'Run the program (.EXE or .COM)
-
- END SUB
-
-
- The QBNews Page 11
- Volume 1, Number 2 February 2, 1990
-
-
- To test this Sub, use it to RUN a program that just PRINTs COMMAND$,
- and see if it picks up your new command tail.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 12
- Volume 1, Number 2 February 2, 1990
-
-
-
- ----------------------------------------------------------------------
- P r o d u c t A n n o u n c e m e n t s
- ----------------------------------------------------------------------
-
- Microsoft Professional BASIC 7.0
- REDMOND, Wash. -- November 27, 1989 --
-
- Microsoft Corporation today announced the MicrosoftR BASIC
- Professional Development System, the first BASIC product designed to
- offer serious BASIC programmers the tools they need to develop
- powerful professional applications. The product will be available
- through Microsoft retail outlets in December.
-
- "This product represents a quantum leap for BASIC," said Charles
- Stevens, general manager of Microsoft's Data Access Business Unit.
- "It addresses the needs our BASIC customers said were most important.
- While Microsoft QuickBASIC is still the right choice for beginning
- and occasional programmers, the BASIC Professional Development System
- is truly tailored for serious BASIC programming professionals."
-
- The Microsoft BASIC Professional Development System is the result of
- extensive research that showed BASIC programmers have a strong need
- for high-end tools. It includes the Microsoft Professional ISAM
- (Indexed Sequential Access Method) for data management tasks; new
- language features; increased memory capacity to support large
- application development; and an integrated development environment
- based on Microsoft QuickBASIC. Executables generated with the new
- BASIC product rival those of traditional "high-performance" languages
- in both size and speed.
-
- New Features Expedite Business Programming
-
- Many applications written in BASIC are for business uses, such as
- accounting and data management tasks. To reduce the effort needed to
- develop these applications, Microsoft has added a fully integrated
- ISAM to the new BASIC product. The single-user integrated ISAM
- provides file handling capabilities; but unlike in other ISAMs, such
- as NovellR BTrieveR, the powerful and elegant command syntax is
- integrated directly into the BASIC language.
-
- The Microsoft BASIC Professional Development System also includes a
- new fixed-decimal-point data type for representing currencies; and
- three add-on libraries, derived from Microsoft Excel, for numeric
- formatting, date/time and financial functions.
-
- Microsoft Answers User Requests with New Language Features Microsoft
- added several features requested by BASIC programmers. Static arrays
- in records allow creation of more sophisticated data structures.
- Errors can now be trapped and handled locally in a subprogram. DOS
- file control statements make it easy to write programs to manipulate
- the DOS file system.
-
- Increased Memory Capacity Removes Limitations
-
- The Microsoft BASIC Professional Development System has removed
-
- The QBNews Page 13
- Volume 1, Number 2 February 2, 1990
-
- barriers limiting the size of BASIC programs. To accomplish this,
- Microsoft added EMS (Expanded Memory Specification) support and
- increased total string space in the development environment.
- Compiled executables can also take advantage of more total string
- space, as well as overlays, to create programs as large as 16 MB.
-
- Smaller, Faster Executables Rival Other Languages
-
- BASIC programmers told Microsoft that their top priorities were a
- reduction in .EXE size and an increase in speed. With special
- enhancements in code generation, run- time performance and 80286 code
- generation, BASIC now matches the features and performance offered by
- other professional languages. Developers have increased control over
- the size and content of the BASIC run-time, thus reducing executable
- program size.
-
- Microsoft QuickBASIC Extended Environment, Other Tools
- BoostProductivity
-
- The new product includes a high-performance development environment,
- sample-code toolboxes, and tools for mixed- language and MSR OS/2
- system programming. Professional programmers will appreciate the
- increased capacities and added features of the integrated development
- environment, which is extended from Microsoft QuickBASIC. The
- sample-code toolboxes -- including user-interface, presentation
- graphics and matrix math routines -- illustrate how common
- programming problems can be solved with generalized and reusable
- BASIC code. The Microsoft CodeViewR debugger and Microsoft Editor
- are included for mixed-language and OS/2 systems programming.
-
- System Requirements, Pricing and Availability
-
- The Microsoft BASIC Professional Development System requires a
- personal computer running MS-DOSR or PC-DOSTM operating system 3.0 or
- OS/2 operating system 1.1 or higher; one double-sided disk drive and
- a hard disk; and a minimum of 640K of memory (EMS 4.0 is
- recommended). A Microsoft Mouse is optional. Compiled programs run
- on MS-DOS 2.1 or higher or OS/2 operating system 1.1 or higher.
-
- The Microsoft BASIC Professional Development System will be
- available in December 1989 at Microsoft retail outlets. It has a
- suggested retail price of $495. The upgrade price for registered
- users of Microsoft Basic 6.0 is $150.
- #########
-
- Microsoft BASIC Professional Development System Microsoft, MS, MS-
- DOS, CodeView and the Microsoft logo are registered trademarks of
- Microsoft Corporation.
- Btrieve is a registered trademark of Software, Inc., a Novell
- Company.
- Novell is a registered trademark of Novell, Inc.
- PC-DOS is a trademark of International Business Machines Corporation.
-
-
-
- The QBNews Page 14
- Volume 1, Number 2 February 2, 1990
-
- QUICKBASIC B+ TREE FILE INDEXING
-
- For years there has been a crying need for an easy to use, reasonably
- priced file indexing system for QuickBASIC. This problem has now
- been solved with Index Manager(tm). Programmers can now create B+
- tree file indexes within their QuickBASIC programs. Files can be
- accessed randomly by full key, browsed by partial key, or sorted
- forward or backward. All functions of Index Manager are performed by
- just one external subroutine, making Index Manager very easy to use.
- Only indexes are managed. The programmer still retains full control
- over all data files.
-
- Index Manager creates its indexes using a prefix B+ tree - one of the
- most powerful index structures available today. The program is
- written in assembler language for maximum speed and minimum size. It
- utilizes a large cache buffer to keep the most important index
- records in memory and thereby reduce disk access to a minimum. The
- result is a very fast, exceptionally powerful indexing system.
-
- Two-thirds of the Beta Testers for Index Managers gave it an overall
- rating of 10 out of 10. ProWindows author David Stasinski called
- Index Manager "the absolute best B-tree system I have ever seen."
-
- A demo version of Index Manager is available for downloading on
- Compuserve and GEnie. On Compuserve it is located on the Microsoft
- System Forum (GO MSSYS) on data library 1 or 2, and called
- INDEXM.ARC. On GEnie, it is located in Microsoft (M 505) RoundTable
- data library 10 as file 828.
-
- The Index Manager package includes a high quality perfect bound 64
- page Users Guide, 8 sample programs, and a Quick Reference card.
- Index Manager can be purchased for $59 from
-
- CDP Consultants
- 1700 Circo Del Cielo Drive
- El Cajon, CA 92020
-
- or by phone at 619-440-6482.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 15
- Volume 1, Number 2 February 2, 1990
-
- QB/Pro Volume 8
-
- The MicroHelp Library Manager
-
- A Simple Concept
- We've revolutionized the way that programmers think about libraries.
- Instead of worrying about what object modules go in what libraries,
- our Library Manager (LM.EXE) lets you organize your routines by
- project.
-
- Whenever you want to build a fresh library, whether it's a Quick
- Library, a LINK Library, or an Extended Runtime Library, simply tell
- LM the Project(s) that you want the library for and then tell it to
- build the library!
-
- View Library Contents
- LM lets you view the contents of both Quick and LINK libraries. In
- fact, the program lets you modify LINK libraries without having to
- worry about command line switches. Simply mark the action you want to
- take on each module in the library.
-
- Easy-To-Use Search Capabilities
- You can configure LM so that it automatically searches your disk for
- "unresolved externals". That means you don't have to worry about where
- a routine is located - all you need is the routine name! LM can search
- object modules and LINK libraries in order to resolve all external
- references.
-
- As a matter of fact, LM even lets you look inside object modules, so
- you can tell what routines are included. If you see one you want to
- use, simply tell LM to add it to your standard list of routines.
-
- When you're viewing a LINK library or set of object modules, you can
- tell LM to search for specified public symbols or externals.
-
-
- The Nitty Gritty
- LM is designed to work with two main types of information:
-
- Standard Routines that you use on a regular basis. The product
- comes with a text file containing the names of all the routines in all
- of MicroHelp's products. You can add your own routines, as well as
- routines from other add-on products, and delete the routines you
- don't normally use.
-
- Standard Projects tell LM how you want to group your Standard
- Routines. You can load up to 250 different projects at one time, each
- having a unique code and a description. After designating your
- projects, you can go through your standard routines and tell LM which
- routines are to be included with each product. We even give you a
- "wildcard project" that tells LM to include a routine in all
- libraries.
-
- You can add to your list of Standard Routines automatically whenever
- you View a LINK library or View Object Modules. When you want to build
-
- The QBNews Page 16
- Volume 1, Number 2 February 2, 1990
-
- a library, you simply select one or more Projects and then tell LM to
- go to work. If you prefer, you can tell LM to use the routines that
- you specify instead of or in addition to the Project(s) you selected.
- This allows you to build custom libraries without having to specify a
- new Project.
-
-
- For Your Convenience
- LM is very flexible with its configuration. Not only does it search
- for its configuration file using the same logic described above, it
- also lets you configure the default path for:
-
- Quick Libraries
- LINK Libraries
- Standard Routine and Standard Project files
- Temporary work files
- Object modules
-
- You can also configure the following to suit your preferences:
-
- Quick Library Support Library
- Default LINK library name
- Default Quick library name
- Whether or not to resolve external references when
- building a library.
- Whether or not to search libraries in order to resolve the
- externals.
- Whether or not object module presence should be verified
- before invoking LINK or LIB.
-
-
- Free Utility Program Included
- Included with The MicroHelp Library Manager is a FREE Utility program
- called PREQLB. When you absolutely positively have to have a new
- library for a program right now, just tell PREQLB the name of your
- source file. PREQLB will quickly scan your program, including
- supporting BASIC modules, and will help you create a new Quick Library
- or LINK Library immediately.
-
- PREQLB also tells you if you have DECLAREd a SUBprogram, but it is not
- used in your program, or if you have a SUB or FUNCTION in your program
- that is not invoked by the program.
-
-
- System Requirements
- The minimum system requirements for using The MicroHelp Library
- Manager are:
-
- An IBM PC, XT, AT, PS/2 or close compatible.
- PC/MS DOS version 3.00 or later.
- LIB.EXE (any version) and LIB.EXE 3.61 or later.
- Any Microsoft or IBM BASIC compiler. Quick Libraries
- require Microsoft QuickBASIC 4.0 or later or Microsoft
- BASIC Compiler 6.0 or later, as well as the LINK program
- that comes with the compiler.
-
- The QBNews Page 17
- Volume 1, Number 2 February 2, 1990
-
- A hard disk (fixed disk).
- 1 Diskette drive (5.25"). 3.5" disks are available for a
- nominal charge.
- An 80 column monitor.
-
-
- The Last Word
-
- The MicroHelp Library Manager comes with a three-ring bound manual and
- free full-time technical support. The suggested retail price is $59.00.
-
- To order, or for more information, contact:
-
- MicroHelp, Inc.
- 4636 Huntridge Drive
- Roswell, GA 30075-2012
- (800) 922-3383
- (404) 552-0565
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 18
- Volume 1, Number 2 February 2, 1990
-
-
-
- ----------------------------------------------------------------------
- T h e T o o l S h e d
- ----------------------------------------------------------------------
-
- Update on QB Optimizer by Larry Stone
-
- When "The QBNews" last went to press, I was still awaiting QB
- 4.0b from Microsoft. Without this upgrade, it was not possible to
- give a more extensive review of MicroHelp's QB Optimizer.
-
- Well, the update from Microsoft finally arrived and I immediately
- re-compiled my test program, FULLCUR.BAS, using all of the Xmodules
- supplied by MicroHelp. The stand-alone exe compiled to 3343 bytes, as
- I anticipated.
-
- Because I now have the opportunity to thoroughly test Mark
- Novisoff's utility, I will post my findings in future editions of this
- electronic newsletter.
-
-
- [EDITORS NOTE]
-
- Because of my procrastination, there are no new reviews in this
- issue. In the next issue, (April), look for reviews on Index Manager,
- P-Screen Professional, and Stay-Res Plus.
-
- David Cleary
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 19
- Volume 1, Number 2 February 2, 1990
-
-
-
- ----------------------------------------------------------------------
- A s k M R . W I Z Z A R D
- ----------------------------------------------------------------------
-
- Ask Mr. Wizard Information from the Microsoft Knowledge Base
-
- The Microsoft Knowledge Base is a service available to
- subscribers on Compuserve. It is a database of frequently asked
- questions that Microsoft Tech Support uses to find answers to
- questions asked to them. The QBNews has been given permission to
- reprint some of these answers. You can access the Knowledge Base on
- Compuserve by typing GO MSOFT at any ! prompt.
-
- Question: Gee Mr. Wizard, What do the "Bytes Available" and "Bytes
- Free" mean when I compile?
-
- Well Tudor . . .
-
- Title: Explanation of Compiler "Bytes Available" and "Bytes Free"
- Document Number: Q27347 Publ Date: 16-JAN-1989
- Product Name: Microsoft QuickBASIC Compiler
- Product Version: 4.00 4.00 4.50
- Operating System: MS-DOS
-
- Summary:
-
- At the end of a successful compilation, the BC.EXE compiler displays
- the following message:
-
- nnnnn Bytes Available
- nnnnn Bytes Free
-
- 0 Warning Error(s)
- 0 Severe Error(s)
-
- This message gives the amount of workspace available before (Bytes
- Available) and after (Bytes Free) a program is compiled.
-
- If the Bytes Free is approaching 1024 or less, then you are
- approaching the limits of code generation for this module, and you
- should break your program into smaller, separately compiled
- subprograms or FUNCTION procedures that can be linked together (with
- LINK.EXE).
-
- This information applies to QuickBASIC Compiler Versions 1.00, 1.01,
- 1.02, 2.00, 2.01, 3.00, 4.00, 4.00b, and 4.50 for MS-DOS, the
- Microsoft BASIC Compiler Versions 5.35 and 5.36 for MS-DOS, and
- Versions 6.00 and 6.00b for MS OS/2 and MS-DOS.
-
- More Information:
-
- The 64K memory segmentation architecture of the 8086 chip has
- influenced design limitations of the BASIC Compiler so that it can
- only generate 64K or less for a program's code segment. The 64K
- temporary work space available for the compiler itself can also limit
-
- The QBNews Page 20
- Volume 1, Number 2 February 2, 1990
-
- code generation.
-
- Bytes Available is the initial amount of compiler workspace available
- for storing the symbol table and the line number table, and for
- working storage for code generation and optimization.
-
- Bytes Free is the size of unused compiler workspace after the
- compiler has finished.
-
- Note: If you want to see the number of bytes that were generated for
- a module's code segment, refer to the .MAP file that can be
- optionally output from the LINK.EXE linker. The program must have
- been successfully compiled and linked to get a valid link .MAP file.
-
- COPYRIGHT Microsoft Corporation, 1989.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 21
- Volume 1, Number 2 February 2, 1990
-
-
-
- ----------------------------------------------------------------------
- G r a p h i c a l l y S p e a k i n g
- ----------------------------------------------------------------------
-
- Getting and Putting Graphics by Frederick Volking
-
- Due to the Graphic nature of this article, parental discretion is
- advised.
-
- I am involved in writing several graphics oriented games. Each of
- these games require many different images (called sprites). I was
- evaluating the best method to store these sprites for the games I'm
- writing. I noticed the graphics GET & PUT commands could store
- relatively large images in surprisingly small arrays.
-
- I decided that if I could understand the method used to store the
- images in the arrays, then I could write a few routines which would
- make my games easier to program. Specifically routines which would
- manipulate the images ONCE THEY WERE ALREADY STORED IN THE ARRAY!
- Routines like; (1) "flipping" an image upside down or left to right.
- (2) rotating an image around a fixed point (3) changing all
- occurrences of color-X to a new color-Y [easy way to make a "good guy"
- into a "bad guy"] ... and several other routines.
-
- I thought that if I could write small fast routines to do the
- above actions, then I would need far fewer sprites to accomplish
- the same visual actions, since I could simply "change" the
- sprite, as needed, on-the-fly, while the program was running.
-
- The below article is the result of many hours of research into
- the method used for storage of images into numeric arrays.
- Enjoy ...
- ================================================> Frederick
-
- All versions of Microsoft Basic have several commands which
- provide graphic functions. Two of the most powerful are the graphics
- GET and graphics PUT. These two commands allow the programmer to move
- a copy of a graphic image into a numerical array and then, later,
- redisplay the image whenever needed anyplace on the screen.
-
- Almost every graphics game uses the technique of GET'ing and
- PUT'ing graphics images to create animation. During a game, when our
- eye sees a picture of an object moving across the screen, we are
- actually seeing many separate images. Each image was initially stored
- with a GET command. Then, throughout the game, the image is repeatedly
- redisplayed with subsequent PUT commands. The key concept, is the
- speed at which this redisplay happens. The computer is capable of
- PUT'ing, so rapidly, that the human eye cannot see the individual
- different frames.
-
- The GET and PUT commands use numerical arrays to store images.
- The method used for storage is the main concept to be examined by this
- article.
-
- In Basic, only rectangularly shaped screen areas can be stored
-
- The QBNews Page 22
- Volume 1, Number 2 February 2, 1990
-
- and displayed. The height and width dimensions of such areas are
- determined on a pixel basis. The height and width of a graphic image
- is described as X-pixels-tall and Y-pixels-wide.
-
- GET requires a numeric array which has been pre-dimensioned to
- the proper size to receive the entire graphic image. Depending upon
- several criteria, such as screen mode (CGA, EGA or VGA) or how many
- bytes of graphics memory are available, the exact size and dimension
- of these arrays tend to vary significantly. It is this variation in
- array size, which provides the first clue to unraveling the complexity
- of image storage.
-
- In Screen Two a 16x16 pixel image requires an array of 18
- integers. However, 16x16 pixels in Screen One requires 34 integers and
- in Screen Nine 66 integers are needed. It is immediately obvious the
- screen mode being used has a great impact on the array size needed.
-
- In Screen Two (CGA Monochrome), the color of each pixel may only
- be either white(ON) or black(OFF). In Screen One (CGA color) there are
- only FOUR possible color choices and in Screen Nine, each pixel must
- be one of SIXTEEN possible color choices.
-
- The quantity of colors available, under any specified screen
- mode, is the main factor affecting the size of the array required to
- hold an image.
-
- Included with this article is a SUB which will calculate the
- array size needed, in integers, for most screen modes. GETSIZE.BAS
-
- Numeric arrays dimensioned for image storage include two integers
- in the first and second positions which are not part of the graphics
- image itself. The first and second integers are the height and width
- of the image contained therein. These values are automatically set by
- the GET command.
-
- Examination of array sizes (minus the two extra integers) for a
- variety of screen modes, for storage of a 16x16 pixel image, reveals a
- geometric pattern rise, in step with the quantity of colors available.
-
- SCREEN 2 .... 16 integers needed ... 2 colors available
- SCREEN 1 .... 32 integers needed ... 4 colors available
- SCREEN 9 .... 64 integers needed ... 16 colors available
-
- If we examine the storage needs of a 16x16 pixel image we find
- there are a total of 256 pixels to be stored. (16 pixels tall) times
- (16 pixels wide) equals (256 pixels) to store.
-
- The question that must be answered is, "How do you store 256
- pixels in arrays which are only 16, 32 or 64 integers in size?
-
- CGA - MONOCHROME SCREEN
-
- Let's begin by concentrating on Screen Two where the entire 256
- pixels are stored in only 16 integers and each pixel is either Black
- or White ... ON or OFF ... 0(zero) or 1(one) ...
-
- The QBNews Page 23
- Volume 1, Number 2 February 2, 1990
-
-
- - One array of 16 INTEGERS
- - Each integer is composed of TWO BYTES
- - Each byte is made up of EIGHT BITS
- - Each bit is either a 0(zero) or 1(one) ...
-
- A little mathematics shows us we have (16 integers) times (2
- bytes) times (8 bits) which equals (256 bits).
-
- Since we have 256 PIXELS which are either 0(zero) or 1(one) ... and
- Since we have 256 BITS which are either 0(zero) or 1(one) ...
- We can then THEORIZE that each pixel is "mapped" to the "bit-level".
-
- Included with this article is a program which will validate bit level
- mapping in Screen Two: SCR2BITS.BAS
-
- To prove our THEORY ... let's assume we have an array of 18
- integers (two for height and width and 16 for pixel storage). Each
- integer is composed of two bytes and each byte is composed of 8 bits.
- Set every integer in our array to 0(zero) and examine each bit, of
- each byte, of each integer:
-
- Integer #1 0000 0000 0000 0000 = 0 (tall)
- Integer #2 0000 0000 0000 0000 = 0 (wide)
- Byte #1 Byte #2
- Integer #3 0000 0000 0000 0000
- Integer #4 0000 0000 0000 0000
- Integer #5 0000 0000 0000 0000
- Integer #6 0000 0000 0000 0000
- Integer #7 0000 0000 0000 0000
- Integer #8 0000 0000 0000 0000
- Integer #9 0000 0000 0000 0000
- Integer #10 0000 0000 0000 0000
- Integer #11 0000 0000 0000 0000
- Integer #12 0000 0000 0000 0000
- Integer #13 0000 0000 0000 0000
- Integer #14 0000 0000 0000 0000
- Integer #15 0000 0000 0000 0000
- Integer #16 0000 0000 0000 0000
- Integer #17 0000 0000 0000 0000
- Integer #18 0000 0000 0000 0000
-
- Let's further ...
- 1. turn on Screen 2 > SCREEN 2
- 2. draw a box in the corner > LINE (0,0)-(15,15),1,B
- 3. draw a diagonal line in the box > LINE (0,0)-(15,15),1
- 4. GET the image into our array > GET (0,0)-(15,15),Array
-
- Now let's examine our array again ...
- Integer #1 0001 0000 0000 0000 = 16 (tall)
- Integer #2 0001 0000 0000 0000 = 16 (wide)
- Byte #1 Byte #2
- Integer #3 1111 1111 1111 1111
- Integer #4 1100 0000 0000 0001
- Integer #5 1010 0000 0000 0001
-
- The QBNews Page 24
- Volume 1, Number 2 February 2, 1990
-
- Integer #6 1001 0000 0000 0001
- Integer #7 1000 1000 0000 0001
- Integer #8 1000 0100 0000 0001
- Integer #9 1000 0010 0000 0001
- Integer #10 1000 0001 0000 0001
- Integer #11 1000 0000 1000 0001
- Integer #12 1000 0000 0100 0001
- Integer #13 1000 0000 0010 0001
- Integer #14 1000 0000 0001 0001
- Integer #15 1000 0000 0000 1001
- Integer #16 1000 0000 0000 0101
- Integer #17 1000 0000 0000 0011
- Integer #18 1111 1111 1111 1111
-
- We have proven our theory. Examination of the "bit-pattern"
- proves under Screen Two, each pixel is mapped at the bit level. Given
- the visual pattern above, it's rather obvious how Screen Two (CGA
- Mono) images are stored in the array.
-
- CGA - COLOR SCREEN
-
- In Screen Two (CGA Mono) it is only necessary to store a single
- ON/OFF switch (one bit). Thus, mapping to each integer is rather
- straight forward. However, in Screen One (CGA color), it is necessary
- to store a value which can be one of FOUR possible colors (0,1,2,3).
-
- Using binary mathematics, we can determine it will only require
- TWO BITS to store a value which has a range of 0 thru 3 ....
-
- Bit#1 Bit#2 Value
- OFF OFF . . . . . 0 0 = 0
- OFF on . . . . . 0 1 = 1
- on OFF . . . . . 1 0 = 2
- on on . . . . . 1 1 = 3
-
- We must now determine how those two bits, for each pixel, are mapped
- on the integer array.
-
- Included with this article is a program which will validate bit level
- mapping in Screen One: SCR1BITS.BAS
-
- Let's examine an example ... Since we are now dealing with Screen
- One, we will need an array with 34 integers. Let's set the entire
- array to 0(zero) and examine the "bit-pattern" of the array.
-
- Since we need 2 bits to display each pixel, a single line of 16
- pixels will now span 2 integers (rather than 1 integer as in Screen
- Two). Thus we'll change the way our integers are displayed such that
- we have two integers side by side
-
- Integer #1 0001 0000 0000 0000 = 16 (tall)
- Integer #2 0001 0000 0000 0000 = 16 (wide)
- Byte #1 Byte #2 Byte #1 Byte #2
- Integer # 3 0000 0000 0000 0000 - 0000 0000 0000 0000 # 4 Integer
- Integer # 5 0000 0000 0000 0000 - 0000 0000 0000 0000 # 6 Integer
-
- The QBNews Page 25
- Volume 1, Number 2 February 2, 1990
-
- Integer # 7 0000 0000 0000 0000 - 0000 0000 0000 0000 # 8 Integer
- Integer # 9 0000 0000 0000 0000 - 0000 0000 0000 0000 #10 Integer
- Integer #11 0000 0000 0000 0000 - 0000 0000 0000 0000 #12 Integer
- Integer #13 0000 0000 0000 0000 - 0000 0000 0000 0000 #14 Integer
- Integer #15 0000 0000 0000 0000 - 0000 0000 0000 0000 #16 Integer
- Integer #17 0000 0000 0000 0000 - 0000 0000 0000 0000 #18 Integer
- Integer #19 0000 0000 0000 0000 - 0000 0000 0000 0000 #20 Integer
- Integer #21 0000 0000 0000 0000 - 0000 0000 0000 0000 #22 Integer
- Integer #23 0000 0000 0000 0000 - 0000 0000 0000 0000 #24 Integer
- Integer #25 0000 0000 0000 0000 - 0000 0000 0000 0000 #26 Integer
- Integer #27 0000 0000 0000 0000 - 0000 0000 0000 0000 #28 Integer
- Integer #29 0000 0000 0000 0000 - 0000 0000 0000 0000 #30 Integer
- Integer #31 0000 0000 0000 0000 - 0000 0000 0000 0000 #32 Integer
- Integer #33 0000 0000 0000 0000 - 0000 0000 0000 0000 #34 Integer
-
- Let's ...
- 1. turn on Screen 1 > SCREEN 1
- 2. define the color to use > Clr = 1
- 3. draw a box in the corner > LINE (0,0)-(15,15),Clr,B
- 4. draw a diagonal line in the box > LINE (0,0)-(15,15),Clr
- 5. GET the image into our array > GET (0,0)-(15,15),Array
-
- Now let's examine our array again ...
-
- Integer #1 0001 0000 0000 0000 = 16 (tall)
- Integer #2 0001 0000 0000 0000 = 16 (wide)
- Byte #1 Byte #2 Byte #1 Byte #2
- Integer # 3 0101 0101 0101 0101 - 0101 0101 0101 0101 # 4 Integer
- Integer # 5 0101 0000 0000 0000 - 0000 0000 0000 0001 # 6 Integer
- Integer # 7 0100 0100 0000 0000 - 0000 0000 0000 0001 # 8 Integer
- Integer # 9 0100 0001 0000 0000 - 0000 0000 0000 0001 #10 Integer
- Integer #11 0100 0000 0100 0000 - 0000 0000 0000 0001 #12 Integer
- Integer #13 0100 0000 0001 0000 - 0000 0000 0000 0001 #14 Integer
- Integer #15 0100 0000 0000 0100 - 0000 0000 0000 0001 #16 Integer
- Integer #17 0100 0000 0000 0001 - 0000 0000 0000 0001 #18 Integer
- Integer #19 0100 0000 0000 0000 - 0100 0000 0000 0001 #20 Integer
- Integer #21 0100 0000 0000 0000 - 0001 0000 0000 0001 #22 Integer
- Integer #23 0100 0000 0000 0000 - 0000 0100 0000 0001 #24 Integer
- Integer #25 0100 0000 0000 0000 - 0000 0001 0000 0001 #26 Integer
- Integer #27 0100 0000 0000 0000 - 0000 0000 0100 0001 #28 Integer
- Integer #29 0100 0000 0000 0000 - 0000 0000 0001 0001 #30 Integer
- Integer #31 0100 0000 0000 0000 - 0000 0000 0000 0101 #32 Integer
- Integer #33 0101 0101 0101 0101 - 0101 0101 0101 0101 #34 Integer
-
- Since we drew our box using COLOR 1 ... and ... since the two-bit
- bit-pattern for COLOR 1 is ... 01 ....... It appears each pixel is
- mapped onto two consecutive bits of each integer.
-
- By changing the box to color 2 and 3 and repeating the exercise,
- it's possible to verify the bit mapping suggested by the above bit
- pattern.
-
- The two-bit bit-pattern for COLOR 2 is - 10 - thus ........
-
- Byte #1 Byte #2 Byte #1 Byte #2
-
- The QBNews Page 26
- Volume 1, Number 2 February 2, 1990
-
- Integer # 3 1010 1010 1010 1010 - 1010 1010 1010 1010 # 4 Integer
- Integer # 5 1010 0000 0000 0000 - 0000 0000 0000 0100 # 6 Integer
- Integer # 7 1000 1000 0000 0000 - 0000 0000 0000 0100 # 8 Integer
- Integer # 9 1000 0010 0000 0000 - 0000 0000 0000 0100 #10 Integer
- Integer #11 1000 0000 1000 0000 - 0000 0000 0000 0100 #12 Integer
- Integer #13 1000 0000 0010 0000 - 0000 0000 0000 0100 #14 Integer
- Integer #15 1000 0000 0000 1000 - 0000 0000 0000 0100 #16 Integer
- Integer #17 1000 0000 0000 0010 - 0000 0000 0000 0100 #18 Integer
- Integer #19 1000 0000 0000 0000 - 1000 0000 0000 0100 #20 Integer
- Integer #21 1000 0000 0000 0000 - 0010 0000 0000 0100 #22 Integer
- Integer #23 1000 0000 0000 0000 - 0000 1000 0000 0100 #24 Integer
- Integer #25 1000 0000 0000 0000 - 0000 0010 0000 0100 #26 Integer
- Integer #27 1000 0000 0000 0000 - 0000 0000 1000 0100 #28 Integer
- Integer #29 1000 0000 0000 0000 - 0000 0000 0010 0100 #30 Integer
- Integer #31 1000 0000 0000 0000 - 0000 0000 0000 1010 #32 Integer
- Integer #33 1010 1010 1010 1010 - 1010 1010 1010 1010 #34 Integer
-
- The two-bit bit-pattern for COLOR 3 is - 11 - thus ........
-
- Byte #1 Byte #2 Byte #1 Byte #2
- Integer # 3 1111 1111 1111 1111 - 1111 1111 1111 1111 # 4 Integer
- Integer # 5 1111 0000 0000 0000 - 0000 0000 0000 0011 # 6 Integer
- Integer # 7 1100 1100 0000 0000 - 0000 0000 0000 0011 # 8 Integer
- Integer # 9 1100 0011 0000 0000 - 0000 0000 0000 0011 #10 Integer
- Integer #11 1100 0000 1100 0000 - 0000 0000 0000 0011 #12 Integer
- Integer #13 1100 0000 0011 0000 - 0000 0000 0000 0011 #14 Integer
- Integer #15 1100 0000 0000 1100 - 0000 0000 0000 0011 #16 Integer
- Integer #17 1100 0000 0000 0011 - 0000 0000 0000 0011 #18 Integer
- Integer #19 1100 0000 0000 0000 - 1100 0000 0000 0011 #20 Integer
- Integer #21 1100 0000 0000 0000 - 0011 0000 0000 0011 #22 Integer
- Integer #23 1100 0000 0000 0000 - 0000 1100 0000 0011 #24 Integer
- Integer #25 1100 0000 0000 0000 - 0000 0011 0000 0011 #26 Integer
- Integer #27 1100 0000 0000 0000 - 0000 0000 1100 0011 #28 Integer
- Integer #29 1100 0000 0000 0000 - 0000 0000 0011 0011 #30 Integer
- Integer #31 1100 0000 0000 0000 - 0000 0000 0000 1111 #32 Integer
- Integer #33 1111 1111 1111 1111 - 1111 1111 1111 1111 #34 Integer
-
- EGA - COLOR SCREEN
-
- We will use the same methods we have already employed, to help us
- examine how pixels are stored in Screen Nine.
-
- Included with this article is a program which will validate bit level
- mapping in Screen Nine: SCR9BITS.BAS
-
- First let's examine how many bits will be required to store a
- pixel color in the range of 0 thru 15 (thus 16 colors). Using bit
- mathematics we can determine we'll need 4 bits.
-
- Bits-> (1) (2) (3) (4)
- 1 + 2 + 4 + 8 = 15 + 1 for Zero
-
- Bit
- Value Switches Pattern
- 0 ....... OFF OFF OFF OFF .... 0000
-
- The QBNews Page 27
- Volume 1, Number 2 February 2, 1990
-
- 1 ....... OFF OFF OFF on .... 0001
- 2 ....... OFF OFF on OFF .... 0010
- 3 ....... OFF OFF on on .... 0011
- 4 ....... OFF on OFF OFF .... 0100
- 5 ....... OFF on OFF on .... 0101
- 6 ....... OFF on on OFF .... 0110
- 7 ....... OFF on on on .... 0111
- 8 ....... on OFF OFF OFF .... 1000
- 9 ....... on OFF OFF on .... 1001
- 10 ....... on OFF on OFF .... 1010
- 11 ....... on OFF on on .... 1011
- 12 ....... on on OFF OFF .... 1100
- 13 ....... on on OFF on .... 1101
- 14 ....... on on on OFF .... 1110
- 15 ....... on on on on .... 1111
-
- EGA Screen Nine image storage is much different from Screens One
- & Two. Rather than having one pixel mapped onto 1 or 2 CONSECUTIVE
- bits, Screen Nine takes a substantially different approach. Let's look
- at what appears to happen from a pseudo-code standpoint...
-
- 100 the quantity of pixels WIDE is determined.
-
- 200 that quantity is rounded up to the nearest whole INTEGER
- quantity
-
- 300 the rounded integer quantity is multiplied by the number of
- bits required (four)
-
- 400 the pixel color value, of the first pixel is determined
-
- 500 the bit-pattern of that value is separated into its four
- smallest basic pieces, the individual bits.
-
- 600 the first BIT of the 1ST pixel's color value is mapped onto
- the 1ST BIT position of the FIRST BYTE.
-
- Up until this point, things are happening like they would in Screen
- One or Two. But now things get strange ....
-
- 700 rather than mapping the SECOND pixel color BIT onto the BYTE's
- SECOND BIT (as would happen in CGA), the procedure begins
- again at line 400. However, instead of working with the 1ST
- pixel and the byte's first bit position, the FIRST BIT of the
- SECOND PIXEL is used.
-
- Thus, if you have an image, say 13 pixels wide, then the first 13
- bits of the 2 bytes of the first integer all reflect the FIRST BITS OF
- 13 DIFFERENT PIXELS! and the next 13 bits of the next two bytes of the
- next integer are the SECOND BIT of 13 different pixels, and so on, and
- so on ....
-
- Pixels 1 2 3 4 5 6 7 8 9 10 11 12 13
-
- Their Color 15 1 5 9 1 1 5 9 1 1 5 9 1
-
- The QBNews Page 28
- Volume 1, Number 2 February 2, 1990
-
-
- Their Bit 1 0 0 1 0 0 0 1 0 0 0 1 0 A
- Patterns 1 0 1 0 0 0 1 0 0 0 1 0 0 B
- 1 0 0 0 0 0 0 0 0 0 0 0 0 C
- 1 1 1 1 1 1 1 1 1 1 1 1 1 D
-
- Byte #1 Byte #2
- Integer #1 1001 0001 0001 0000 A
- Integer #1 1010 0010 0010 0000 B
- Integer #1 1000 0000 0000 0000 C
- Integer #1 1111 1111 1111 1000 D
-
- Notice that each integer has been filled to the integer border
- with zero's. When storing images, with a quantity of pixels which are
- not evenly divisible by 8, then substantial wasted space occurs. Run
- the program provided with this article, SCR9BITS and you'll be able to
- see this bit-spread across-bytes in action.
-
- Without going into great detail ... this trait of bit-mapping is
- found in discussions of "planes" in a variety of books. Planes refer
- to a technique taken by the lowest software level to maximize speed
- when addressing hardware requirements of the EGA card.
-
- VGA COLOR & MCGA SCREENS
-
- Sorry ... but I only have EGA and CGA computers at my disposal. I
- have not had the opportunity to examine how bits are stored in VGA
- modes. Possibly someone else will continue my research ... and next
- issue ... we can learn how VGA images are stored ...?
-
- Included is a function which will determine the condition of a
- specified BIT inside an integer, and return TRUE or FALSE if the BIT
- is ON or OFF: BITON.BAS
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 29
- Volume 1, Number 2 February 2, 1990
-
-
-
- ----------------------------------------------------------------------
- A n d I H e a r d i t T h r o u g h t h e G r a p e v i n e
- ----------------------------------------------------------------------
-
- Heard it through the grapevine ... Exerpts from the QUIK_BAS echo
-
- From: Bob Ross
- To: Gregg Pace
- Subject: ENHANCED KEYBOARD
-
- In a message of <02 Nov 89 11:29:13>, Gregg Pace (1:371/8) writes:
-
- >Does anyone know the trick to accessing the cursor keys on an
- enhanced keyboard? I can access the ones on the number pad, but the
- separate cursor pad does nothing. Any info will be GREATLY
- appreciated!!
-
- Some AT type computers boot up with the Num Lock key on which
- disables the cursor keys on the numeric keypad. If this is what it
- happening on your system, try toggling the NumLock key off. There
- are a few programs floating around that you could put in your
- Autoexec.bat file to turn NumLock off on boot-up as well. Hope this
- is helpful...
-
- Bob.
-
- From: Dana Bell
- To: Gregg Pace
- Subject: Re: ENHANCED KEYBOARD
-
- If you can tackle the cursor keys on the pad, then you know about
- scan codes. On the enhanced keyboard, the page and cursor keys scan
- codes are extended, that is, preceded by E0, on both AT and XT mode.
- There's some other characteristics (combos), but it might be best to
- consult a tech manual, or possibly your DOS manual. I've not done it,
- but I assume you add the extended code just as you would CTRL or ALT,
- I.e. KEY 15,CHR$(&HE0)+CHR$(&H48) to 'trap' the new up-arrow key.
-
- Dana
-
-
- From: Keli W'Hazel
- To: Dana Bell
- Subject: Re: Enhanced Keyboard
-
- I was waiting for others to respond to the question on cursor
- keys, but it seems no one has done so yet (properly?).
-
- To the original poster:
-
- "Extended" key-strokes return two characters. A chr$(0)
- followed by aletter. For the method to read these keys from the user,
- try:
-
- i$ = ""
-
- The QBNews Page 30
- Volume 1, Number 2 February 2, 1990
-
- while i$ = ""
- i$ = inkey$
- wend
-
- If an "extended" key is hit, I$ will hold two characters.
-
- Left key: Chr$(0) + "K"
- right key: Chr$(0) + "M"
- Up key: Chr$(0) + "H"
- Down Key: Chr$(0) + "P"
- PgUp Key: Chr$(0) + "I"
- PgDn Key: Chr$(0) + "Q"
-
- There are many more. Such as: F1,F2,F3,F4,F5,F6,F7,F8,F9,F10
- first have chr$(0) followed by:
- ; < = > ? @ A B C D
-
- respectivly.
-
- Home and end, respectivly: G O
-
- Tab is Chr$(9) ONLY, with no preceeding chr$(0).
-
- Shift/TAB is Chr$(0) + chr$(15)
-
- Ins and Del keys, respectivly: R S
-
- Note that the characters following the chr$(0) are case
- sensitive.
-
-
- From: Doug Wilson @ 965/9
- To: Gregg Pace
- Subject: ENHANCED KEYBOARD
-
- Gregg:
-
- (At least I THINK you are the one who posted the question
- about accessing the keys on a separate cursor pad...)
-
- From your message it sounds like you know in general how to
- access the keys, you just need the codes for the keys in
- question. The short program below will display the key codes
- returned by INKEY$ for any key you press - including Ctrl- and
- Alt- combinations. Try it on the cursor pad and see what you
- get. Once you have the codes, if you need help doing what
- you want with them, post another message.
-
- Cheers, Doug
-
-
- CLS
- PRINT "Press a key to see its INKEY$ code(s) - Esc will exit"
- More [Y,n]?
- PRINT
-
- The QBNews Page 31
- Volume 1, Number 2 February 2, 1990
-
- DO UNTIL a$ = CHR$(27)
- a$ = ""
- WHILE a$ = "": a$ = INKEY$: WEND
- LOCATE CSRLIN, 1
- FOR i = 1 TO LEN(a$)
- PRINT ASC(MID$(a$, i, 1)), ;
- NEXT
- PRINT STRING$(4, 32);
- LOOP
- END
-
-
- From: Malcolm Toon @ 914/602
- To: Gregg Pace
- Subject: Enhanced Keyboard
-
- Try this:
- DO: A$=INKEY$:LOOP UNTIL A$<>""
- b% = ASC(RIGHT$(a$, 1))
- 'B%' is now the ASCII char code for the INKEY$...
- Here are the codes:
- 72 - up
- 77 - right
- 80 - down
- 75 - left
- There is only one setback... If you push the Uppercase key on the
- keyboard that is one of the above numbers, it uses the up, down,
- left, or right!
- So this will not be good for a word processor, but here is some code
- to move around a lighted bar to select things in a series...
- This was first written by Dwain Goforth a friend of mine.
-
- x% = 4: y% = 1: z% = 18
- start:
- LOCATE x%, y%: file$ = ""
- FOR yy% = 1 TO 18: file$ = file$ + CHR$(SCREEN(x%, y% + yy% - 1)):
- NEXT yy%
- COLOR clr0%, clr7%: PRINT file$: COLOR clr7%, clr0%
- getkey2:
- DO: a$ = INKEY$: LOOP WHILE a$ = ""
- IF a$ = CHR$(13) THEN GOTO Bye
- IF LEN(a$) <> 2 THEN GOTO getkey2
- LOCATE x%, y%: PRINT file$
- b% = ASC(RIGHT$(a$, 1))
- IF b% = 72 THEN x% = x% - 1 ELSE IF b% = 80 THEN x% = x% + 1
- IF b% = 77 THEN y% = y% + 18 ELSE IF b% = 75 THEN y% = y% - 18
- IF b% = 79 THEN x% = 23: y% = 55
- IF b% = 71 THEN x% = 3: y% = 1
- IF y% > 55 THEN y% = 1 ELSE IF y% < 1 THEN y% = 55
- IF x% < 4 THEN x% = 23 ELSE IF x% > 23 THEN x% = 4
- GOTO start
- Bye: ' Continue your program here....
-
-
- [EDITORS NOTE]
-
- The QBNews Page 32
- Volume 1, Number 2 February 2, 1990
-
- The purpose of this conference is to discuss MicroSoft QuickBASIC
- and related applications and utilities. SysOps looking for a Group
- Mail or EchoMail link into QUIK_BAS should contact the Alliance node
- known as 520/323, the FidoNet node known as 107/323, or the Good
- Egg Net Node known as 9230/323, or simply 1-201-247-8252 for
- information on local feeds.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 33
- Volume 1, Number 2 February 2, 1990
-
-
-
- ----------------------------------------------------------------------
- S o m e A s s e m b l y R e q u i r e d
- ----------------------------------------------------------------------
-
- Using the DOS EXEC function from QB
- by Harold Thomson
-
- ** Caution - the following program will not work in the ENVIRONMENT **
-
- I have been monitoring the messages in the QB message bases for
- the last few months and one of the things that I noticed is that a lot
- of people wish the the BASIC SHELL command would return an ERRORLEVEL
- if the child program returns one. I don't think that this is asking
- too much and I cannot figure out why MS didn't impliment it. Seeing
- this gave me one more routine to add to my growing library of routines
- for QB4 and above that I have written entirly in MS assembler. Right
- now the library is at version 4.5 and contains over 130 routine, but
- enough for the sales pitch (BTW, it's free).
-
- Before we get into the program, a little about the DOS EXEC
- function 4BH along with the related function, 4DH Get return code
- which is used by a parent process, after the successful execution of
- an EXEC call to obtain the return code and termination type of a child
- process.
-
- When I first saw the EXEC function, I realized that this was
- something that I could make use of. But as I started reading the
- documentation, I really started to get confused. It talked about
- different blocks that were needed, the parameter block, the
- environment block, the command tail as well as the ASCIIZ program
- pathname. I was almost tempted to say that it was time to start
- another project. Instead I just picked up my worn copy of ADVANCED
- MSDOS PROGRAMMING by Ray Duncan and worked my way thru his explanation
- and examples and was able to make some sense of it. The results of it
- follows.
-
- As I said above, there are some blocks that are necessary in
- order to get the EXEC function to work. These are commented in the
- followingexample but here is a brief description:
-
- PARAMETER BLOCK Contains the addresses of four data objects
- ! 1. The environment block
- 2. The command tail
- 3. File Control Block 1
- 4. File Control Block 2
-
- ENVIRONMENT BLOCK The documentation stated that if the
- ENVIRONMENT block pointer is zero, then the
- child acquires a copy of the parents
- environment which is the method that I chose.
-
- COMMAND TAIL MSDOS copies the command tail into the childs
- PSP at offset 0080H. This is the normal
- location for any switches or other pieces of
- information that are to be passed to the
-
- The QBNews Page 34
- Volume 1, Number 2 February 2, 1990
-
- child program.
-
- DEFAULT FCS's The default FCBs are seldom used in MSDOS
- versions 2 & 3 because they don't support the
- hierarchical file structure but some programs
- may use them. I point then to the default FCB
- locations in the parent program PSP to
- conserve on space.
-
- The only other thing to do is point at the program name, which
- MUST contain the correct extention, either COM or EXE. I take care of
- making it an ASCIIZ string which just means that it is a string which
- is ended by a HEX 0.
-
- There are a few error codes that the routine will return that may
- need some special attention. First, if a -1 is returned, then QEXEC
- has determined that a null string has been passed to the routine and
- it is not able to continue. The following 5 error codes are returned
- by DOS and the true DOS error code can be found by adding +256 to the
- RC.
- 1. -255 ( 1) Invalid function
- 2. -254 ( 2) File not found
- 3. -248 ( 8) Not enough memory
- 4. -246 (10) Bad environment
- 5. -245 (11) Bad format
-
- Any error code returned that is greater that zero is a valid
- error code and the appropriate action should be taken.
-
- Following the assembler listing is a short QB program that shows
- the necessary DECLARE FUNCTION and some examples of using the QEXEC
- function.
-
- **** WRITTEN FOR MICROSOFT ASSEMBLER VERSION 5.10 ****
-
- Page 60, 130
- EXTRN Pascal B$ShellSetup:Far
- EXTRN Pascal B$ShellRecover:Far
- .MODEL MEDIUM,BASIC
- .CODE
-
- Qexec Proc Far Uses DS ES SI DI, Arg1:Ptr
- Jmp Start
-
- HoldRC DW 0
-
- Pars DW 0 ;Environment segment
- CmdLine DW 0 ;Command line for child - length
- CmdLineS DW 0 ; Command line text
- DW 5CH ;Default FCB 1 offset
- Fcb1 DW 0 ;FCB 1 segment address
- DW 6CH ;Default FCB 2 offset
- Fcb2 DW 0 ;FCB 2 segment address
-
- PgmTxt DB 65 Dup(?) ;Work area to build pgm string
-
- The QBNews Page 35
- Volume 1, Number 2 February 2, 1990
-
-
- CmdBuf DB ? ;This will hold the length
- DB ' ' ;Must allow one space
- CmdTxt DB 80 Dup(?) ;The command line text
-
- Start: Mov CS:HoldRC,-1 ;Set RC to -1
- Mov BX,Arg1 ;Get Program name length
- Mov CX,[BX] ; in CX
- Jcxz GetOut ;Error - Get out
- Mov SI,[BX+2] ;Address of Program string
- Mov DI,Offset PgmTxt ;Program text buffer
- Push ES ;Save ES register
- Mov AX,CS ;Make the ES register
- Mov ES,AX ;the same as the CS register
-
- Pline: Lodsb ;Get a character
- Cmp AL,' ' ;Is it a space?
- Je Pline1 ;Yes - go to next routine
- Stosb ;Move to buffer
- Loop Pline ;Do it again
-
- Pline1: Xor AX,AX ;Zero out AX register
- Stosb ;Make PgmTxt an ASCIIZ string
- Jcxz Pline2 ;No more - continue
- Dec CX ;Adjust for space
-
- Pline2: Mov CS:CmdBuf,CL ;Save command tail length
- Mov DI,Offset CmdTxt ;Command tail buffer
- Jcxz Tline ;No more - continue
- Rep Movsb ;Move command tail to buffer
- Tline: Inc CS:CmdBuf ;Add one to tail length
- Mov AL,13 ;CR value in AL
- Stosb ;Move to buffer
- Pop ES ;Restore ES register
- Mov DI,Offset CmdBuf ;New command tail
- Mov CS:CmdLine,DI ;Move address to parameter block
- Mov DI,CS ;Get CS register address
- Mov CS:CmdLineS,DI ;Move address to parameter block
- Mov AH,62H ;Get current PSP segment
- Int 21H ;DOS interrupt
- Mov CS:Fcb1,BX ;Move PSP address to param block
- Mov CS:Fcb2,BX ;Move PSP address to param block
- Call B$ShellSetup ;QB routine to compress memory
- Mov DX,Offset PgmTxt ;DX points to program name
- ;string
- Mov BX,Offset Pars ;BX points to child environment
- Push DS ;Save DS register
- Mov AX,CS ;Put CS register address
- Mov ES,AX ; into the ES register
- Mov DS,AX ; into the DS register
- Mov AH,4BH ;Function 4B - EXEC function
- Mov AL,00H ;Sub Function 0 - load & exec pgm
- Int 21H ;DOS interrupt
- Pop DS ;Restore DS register
- Jnc Cont ;No Error - Continue
-
- The QBNews Page 36
- Volume 1, Number 2 February 2, 1990
-
- Mov AH,-1 ;Set AH = FFh
- Jmp Cont1 ;Error - Get out
- Cont: Mov AH,4DH ;Function 4D - Get child errorlevel
- Int 21H ;DOS interrupt
- Xor AH,AH ;Zero out AH register
- Cont1: Mov CS:HoldRC,AX ;Set RC to -1
- Call B$ShellRecover ;QB routine to uncompress memory
-
- GetOut: Mov AX,CS:HoldRC ;Set the return code
- Ret ;Go back to caller
-
- Qexec Endp
- End
-
-
-
- A little explanation should be given to the following routine as
- it contains some routines from my QB4BAS.LIB. The first routine,
- QREPLACE changes all occurances of one character to another character.
- This is used to change all occurances of ";" to a space that I can
- then parse to the PATH string using QWORD and QWORDS in a FOR loop,
- concatinating it to the file name and then using QEXIST to see if the
- file exists. If it does, I break out of the FOR loop and then invoke
- QEXEC. The resulting return code will be printed to the screen. If
- the file is not found, then the routine just exits.
-
-
- DEFINT A-Z
- DECLARE SUB QREPLACE (StringName AS STRING, _
- OldStr AS STRING, _
- NewStr AS STRING)
- DECLARE FUNCTION QWORDS% (StringName AS STRING)
- DECLARE FUNCTION QWORD$ (StringName AS STRING, _
- BYVAL Index AS INTEGER)
- DECLARE FUNCTION QEXIST% (FileName AS STRING)
- DECLARE FUNCTION QEXEC% (PgmStr AS STRING)
-
- Tmp$ = "SDIR.COM"
- Work$ = ENVIRON$("PATH")
- QREPLACE Work$, ";", " "
- FOR X = 1 TO QWORDS(Work$)
- Work2$ = QWORD(Work$, X) + "\" + Tmp$
- IF QEXIST(Work2$ + CHR$(0)) = 0 THEN
- EXIT FOR
- ELSE
- Work2$ = ""
- END IF
- NEXT X
-
- IF Work2$ <> "" THEN
- PRINT QEXEC(Work2$)
- END IF
- END
-
- This second example shows the necessary format to execute a BATCH
-
- The QBNews Page 37
- Volume 1, Number 2 February 2, 1990
-
- program. This requires that another copy of COMMAND.COM be first
- loaded using the /C option and then the BAT file name is passed in the
- command tail.
-
- DEFINT A-Z
- DECLARE FUNCTION QEXEC% (PgmStr AS STRING)
- Work1$ = ENVIRON$("COMSPEC")
- Work2$ = " /C THISTEST.BAT"
- Work$ = Work1$ + Work2$
- RC = QEXEC(Work$)
- END
-
- [EDITOR'S NOTE]
-
- QEXEC.ASM is in QEXEC.ZIP in assembled form for thoughs without
- assemblers. Also included is a smmal program called ASK. This was
- written in QuickBASIC and PDQ and it just asks for a number (0-9) and
- returns it as an errorlevel.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 38
- Volume 1, Number 2 February 2, 1990
-
-
-
- ----------------------------------------------------------------------
- S w a p S h o p
- ----------------------------------------------------------------------
-
- Extended Key Codes Made Easy
-
- Detecting various key codes in QuickBasic couldn't be easier, given
- the SELECT CASE construct. In my QB programs I usually INCLUDE a
- file called, FKEYDEFS.BAS, which consists of the following lines:
-
- =====================================================================
- ' Special Key Assignments
-
- UpKey$ = CHR$(0) + CHR$(72)
- DownKey$ = CHR$(0) + CHR$(80)
- LeftKey$ = CHR$(0) + CHR$(75)
- RightKey$ = CHR$(0) + CHR$(77)
- PageUp$ = CHR$(0) + CHR$(73)
- PageDown$ = CHR$(0) + CHR$(81)
- HomeKey$ = CHR$(0) + CHR$(71)
- EndKey$ = CHR$(0) + CHR$(79)
- InsKey$ = CHR$(0) + CHR$(82)
- DelKey$ = CHR$(0) + CHR$(83)
- EnterKey$ = CHR$(13)
- TabKey$ = CHR$(9)
-
- sTabKey$ = CHR$(0) + CHR$(15)
-
- cHomekey$ = CHR$(0) + CHR$(119)
- cEndKey$ = CHR$(0) + CHR$(117)
- cPrtSc$ = CHR$(0) + CHR$(114)
- cLeftKey$ = CHR$(0) + CHR$(115)
- cRightKey$ = CHR$(0) + CHR$(116)
- cPageDown$ = CHR$(0) + CHR$(118)
- cPageUp$ = CHR$(0) + CHR$(132)
-
- ' Function Keys
-
- F1Key$ = CHR$(0) + CHR$(59)
- F2Key$ = CHR$(0) + CHR$(60)
- F3Key$ = CHR$(0) + CHR$(61)
- F4Key$ = CHR$(0) + CHR$(62)
- F5Key$ = CHR$(0) + CHR$(63)
- F6Key$ = CHR$(0) + CHR$(64)
- F7Key$ = CHR$(0) + CHR$(65)
- F8Key$ = CHR$(0) + CHR$(66)
- F9Key$ = CHR$(0) + CHR$(67)
- F10Key$ = CHR$(0) + CHR$(68)
- F11Key$ = CHR$(0) + CHR$(133)
- F12Key$ = CHR$(0) + CHR$(134)
-
- ' Shifted Function Keys
-
- sF1Key$ = CHR$(0) + CHR$(84)
- sF2Key$ = CHR$(0) + CHR$(85)
-
- The QBNews Page 39
- Volume 1, Number 2 February 2, 1990
-
- sF3Key$ = CHR$(0) + CHR$(86)
- sF4Key$ = CHR$(0) + CHR$(87)
- sF5Key$ = CHR$(0) + CHR$(88)
- sF6Key$ = CHR$(0) + CHR$(89)
- sF7Key$ = CHR$(0) + CHR$(90)
- sF8Key$ = CHR$(0) + CHR$(91)
- sF9Key$ = CHR$(0) + CHR$(92)
- sF10Key$ = CHR$(0) + CHR$(93)
- sF11Key$ = CHR$(0) + CHR$(135)
- sF12Key$ = CHR$(0) + CHR$(136)
-
- ' Control Function Keys
-
- cF1Key$ = CHR$(0) + CHR$(94)
- cF2Key$ = CHR$(0) + CHR$(95)
- cF3Key$ = CHR$(0) + CHR$(96)
- cF4Key$ = CHR$(0) + CHR$(97)
- cF5Key$ = CHR$(0) + CHR$(98)
- cF6Key$ = CHR$(0) + CHR$(99)
- cF7Key$ = CHR$(0) + CHR$(100)
- cF8Key$ = CHR$(0) + CHR$(101)
- cF9Key$ = CHR$(0) + CHR$(102)
- cF10Key$ = CHR$(0) + CHR$(103)
- cF11Key$ = CHR$(0) + CHR$(137)
- cF12Key$ = CHR$(0) + CHR$(138)
-
- ' Alt Function Keys
-
- aF1Key$ = CHR$(0) + CHR$(104)
- aF2Key$ = CHR$(0) + CHR$(105)
- aF3Key$ = CHR$(0) + CHR$(106)
- aF4Key$ = CHR$(0) + CHR$(107)
- aF5Key$ = CHR$(0) + CHR$(108)
- aF6Key$ = CHR$(0) + CHR$(109)
- aF7Key$ = CHR$(0) + CHR$(110)
- aF8Key$ = CHR$(0) + CHR$(111)
- aF9Key$ = CHR$(0) + CHR$(112)
- aF10Key$ = CHR$(0) + CHR$(113)
- aF11Key$ = CHR$(0) + CHR$(139)
- aF12Key$ = CHR$(0) + CHR$(140)
-
- ' Alt other keys
-
- alt1$ = CHR$(0) + CHR$(120)
- alt2$ = CHR$(0) + CHR$(121)
- alt3$ = CHR$(0) + CHR$(122)
- alt4$ = CHR$(0) + CHR$(123)
- alt5$ = CHR$(0) + CHR$(124)
- alt6$ = CHR$(0) + CHR$(125)
- alt7$ = CHR$(0) + CHR$(126)
- alt8$ = CHR$(0) + CHR$(127)
- alt9$ = CHR$(0) + CHR$(128)
- alt0$ = CHR$(0) + CHR$(129)
- altHyphen$ = CHR$(0) + CHR$(130)
- altEqual$ = CHR$(0) + CHR$(131)
-
- The QBNews Page 40
- Volume 1, Number 2 February 2, 1990
-
-
- altQ$ = CHR$(0) + CHR$(16)
- altW$ = CHR$(0) + CHR$(17)
- altE$ = CHR$(0) + CHR$(18)
- altR$ = CHR$(0) + CHR$(19)
- altT$ = CHR$(0) + CHR$(20)
- altY$ = CHR$(0) + CHR$(21)
- altU$ = CHR$(0) + CHR$(22)
- altI$ = CHR$(0) + CHR$(23)
- altO$ = CHR$(0) + CHR$(24)
- altP$ = CHR$(0) + CHR$(25)
-
- altA$ = CHR$(0) + CHR$(30)
- altS$ = CHR$(0) + CHR$(31)
- altD$ = CHR$(0) + CHR$(32)
- altF$ = CHR$(0) + CHR$(33)
- altG$ = CHR$(0) + CHR$(34)
- altH$ = CHR$(0) + CHR$(35)
- altJ$ = CHR$(0) + CHR$(36)
- altK$ = CHR$(0) + CHR$(37)
- altL$ = CHR$(0) + CHR$(38)
-
- altZ$ = CHR$(0) + CHR$(44)
- altX$ = CHR$(0) + CHR$(45)
- altC$ = CHR$(0) + CHR$(46)
- altV$ = CHR$(0) + CHR$(47)
- altB$ = CHR$(0) + CHR$(48)
- altN$ = CHR$(0) + CHR$(49)
- altM$ = CHR$(0) + CHR$(50)
-
- All of the variables that start with 'a' (such as 'aF10Key$')
- represent the code for the ALT-Key stroke. Variables with 's' (such
- as 'sF12Key$' are for the shifted-Key stroke, and 'c' (such as
- 'cF1Key$') for the Control-Key stroke.
-
- Now, in your program where you want to detect and act on specific
- keys, use the following:
-
- DO: x$ = INKEY$: LOOP WHILE x$=""
-
- SELECT CASE x$
- CASE F10Key$
- ' Do something when F10 is pressed
- CASE sF10Key$
- ' Do something when Shift-F10 is pressed
- CASE aF10Key$
- ' Do something when Alt-F10 is pressed
- CASE altX$
- ' Do something when Alt-X is pressed
- CASE UpKey$
- ' Do something when the Up arrow key is pressed
- CASE PageDown$
- ' Do something when the Page Down key is pressed
- CASE "P"
- ' Do something when the "P" key is pressed
-
- The QBNews Page 41
- Volume 1, Number 2 February 2, 1990
-
- CASE ELSE
- ' Do something if none of the previous keys were pressed
- END SELECT
-
- This arrangement makes it particularly easy to act on any key stroke,
- and has the added benefit that your program is also MUCH more
- readable.
-
- William R. Hliwa, Jr.
- Clinical Assistant Professor
- Department of Medical Technology
- State University of New York at Buffalo
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 42
- Volume 1, Number 2 February 2, 1990
-
- DECLARE SUB OpenMenu ()
- DECLARE SUB MenuSelection ()
- DECLARE SUB TextMessages ()
- DECLARE SUB RotateSign ()
- DECLARE SUB TimeAMPM ()
-
- COMMON SHARED AMPM$, A$, B, C
-
- '=====
-
- 'This little example is to show how you can have a 'menu' screen with
- 'various selections, and also have rather detailed information also
- 'presented to the user regarding each of his potential selections. If
- 'you use some of the shareware fast screen prints, you can have some
- 'very elaborate instructions on the screen, since the speed of
- 'printing of a lot of details does not become a factor and the
- 'screenful of detailed information snaps into place. The sample below
- 'is partially padded; for the values between #1 and #7. It does not
- 'attempt to restrict a <RETURN> hit with no numeric selection nor some
- 'other combinations. It's purpose is to give you the basics of an on
- 'line additional information' from a menu.
-
- 'This shows how simple the menu programming can be, yet obviously with
- 'just a little work, many of QuickBasic's built-in material can be
- 'used to clean up this listing. The purpose here, was not to show how
- 'well it can be programed, but to show that a programer who knows very
- 'little about BASIC language can still do some pretty sophisticated
- 'programming.
-
- 'SELECT CASE is used in the A.M. / P.M. selection of the TIME so you
- 'would need QB 4.5 or redo it with some IF Statements, and then you
- 'could use this in nearly any BASIC.
-
- 'YUP, there are a few line numbers. Doubt, the world will come to an
- 'end.
-
- CLS
- CALL OpenMenu
- CALL MenuSelection 'selections #1 - #7
- 460 DO
- A$ = INKEY$
- IF LEN(A$) = 0 THEN 'nothing, so on to the screen
- CALL RotateSign 'time / date / scrolling stuff
- GOTO 470 'we want to continue
- END IF
- 470 B = VAL(A$) 'the original A$
- IF LEN(A$) = 0 THEN GOTO 460 'loop
- IF ASC(RIGHT$(A$, 1)) = 13 THEN GOTO 480 'a CR was hit,
- ' call the
- 'routine, or run the module that
- 'is numbered between 1 and 7
- A = B
- IF B < 1 THEN GOTO 460 'heave input values less than 1
- IF B > 7 THEN GOTO 460 'discard values over 7
-
-
- The QBNews Page 43
- Volume 1, Number 2 February 2, 1990
-
- CALL TextMessages
- LOOP
-
- 480 COLOR 14 + 16, 1: LOCATE 22, 16
-
- 'ON C GOTO 101 , 102 , 103 , OneO4 , 105 , 106 , AllDone
- ' 101 RUN "ITEM1.EXE"
- ' 102 RUN "ITEM2.EXE"
- ' 103 ...
- ' OneO4 ...
- ' 105 ...
- ' 106 ...
- ' AllDone
-
- PRINT "You Pushed the RETURN and would also get Item #"; C
- COLOR 15, 4: LOCATE 23, 19
- PRINT "Please push CTL-BREAK to end this program"
- LOCATE 24, 10: COLOR 0, 0
- PRINT SPACE$(70);
-
- DO
- LOOP
-
- SUB MenuSelection
-
- Y = 25
- LOCATE 14, Y: COLOR 15, 1
- PRINT "[ 1 ] -- Item One"
- LOCATE 15, Y
- PRINT "[ 2 ] -- Item Two"
- LOCATE 16, Y
- PRINT "[ 3 ] -- Circles"
- LOCATE 17, Y
- PRINT "[ 4 ] -- No Circles"
- LOCATE 18, Y
- PRINT "[ 5 ] -- Item #5"
- LOCATE 19, Y
- PRINT "[ 6 ] -- Item #6"
- LOCATE 20, Y
- PRINT "[ 7 ] -- Item #7"
- END SUB
-
- SUB OpenMenu
-
- LOCATE 6, 1: COLOR 7, 1
- PRINT " This little program shows how you may place on the screen a_
- short "
- PRINT " instruction or greater information based upon the key_
- selected by "
- PRINT " the user. This information stays on the screen until_
- another possible"
- PRINT " key is selected, or the <RETURN> key is tapped, which takes_
- you to "
- PRINT " the item that is CALLED by the progam associated with the_
- input key. "
-
- The QBNews Page 44
- Volume 1, Number 2 February 2, 1990
-
- COLOR 12 + 16, 1
- PRINT " Tap any key; but preferably #1 - #7_
- "
- END SUB
-
- SUB RotateSign
-
- S1$ = "Select a numeric item and then tap <RETURN>"
- Z1 = LEN(S1$)
- S$ = " Be Sure You Have Made Adequate Backup Disks!! "
- Z = LEN(S$)
- DO UNTIL I = LEN(S$)
- A$ = INKEY$ 'this is WITHIN the first INKEY$
- IF A$ > STR$(0) THEN EXIT SUB
- IF LEN(A$) = 0 THEN GOTO 33
- IF ASC(RIGHT$(A$, 1)) = 104 THEN EXIT SUB
- IF ASC(RIGHT$(A$, 1)) = 13 THEN EXIT SUB 'a CR was hit
- 33 StartTime = TIMER
- IF I = LEN(S$) - 1 THEN I = 0
- LOCATE 12, 16: COLOR 15, 4
-
- DO UNTIL EndTime - StartTime >= .1
- EndTime = TIMER
- LOOP
-
- PRINT LEFT$(S$, LEN(S$) - I) 'scrolling upper message
- LOCATE 12, 16: COLOR 15, 4
- PRINT RIGHT$(S$, Z - (Z - I))
- Y = Y + 1
- IF Y = 15 THEN Y = 8
- COLOR 15, 0
- LOCATE 24, 18
- PRINT RIGHT$(S1$, LEN(S$) - 2 - I);'scrolling bottom message
- I = I + 1
- CALL TimeAMPM
- LOCATE 22, 25: COLOR 15, 0: PRINT AMPM$
- LOCATE 22, 45: PRINT DATE$
- LOOP
- END SUB
-
- SUB TextMessages
- LOCATE 3, 10
- PRINT SPACE$(70)
- LOCATE 4, 10
- PRINT SPACE$(70)
- LOCATE 3, 10
- C = B
- ON B GOTO 1, 2, 3, 4, 5, 6, 7
- 1 COLOR 14, 2
- PRINT " You are considering selecting item #1 "
- EXIT SUB
- 2 COLOR 12, 1
- PRINT " This could be a reminder for item #2 "
- LOCATE 4, 10
- PRINT " This also shows you are NOT restricted to line quantity"
-
- The QBNews Page 45
- Volume 1, Number 2 February 2, 1990
-
- LOCATE 4, 36: COLOR 15 + 16, 1: PRINT "NOT"
- EXIT SUB
- 3 COLOR 15, 9
- PRINT " If you select this item, you will run in circles "
- EXIT SUB
- 4 COLOR 14, 6
- PRINT " Obviously this is not for going in circles "
- EXIT SUB
- 5 COLOR 11, 10
- PRINT " Maybe you have an area that should be called by item #5"
- EXIT SUB
- 6 COLOR 13, 2
- PRINT "The sixth item on the menu might have this informative_
- message "
- LOCATE 4, 10
- PRINT "This could be an entire window, snapped on with a_
- SHAREWARE program"
- EXIT SUB
- 7 COLOR 11, 6
- PRINT " Maybe item #7 could be an instruction to end the program"
- EXIT SUB
- END SUB
-
- SUB TimeAMPM 'a 12 hour clock with either AM or PM at
- the end
- AMPM$ = LEFT$(TIME$, 2)
- SELECT CASE VAL(AMPM$)
- CASE IS >= 12
- AMPM = VAL(AMPM$) - 12
- AMPM$ = STR$(AMPM) + RIGHT$(TIME$, 6) + " PM"
- CASE IS < 12
- AMPM$ = TIME$ + " AM"
- CASE ELSE
- EXIT SUB
- END SELECT
- END SUB
-
-
- by Don Avila
- Compuserve 71525,2041
-
- [EDITOR'S NOTE]
- I may have screwed up the spacing with my word processor. Sorry.
- David Cleary
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 46
- Volume 1, Number 2 February 2, 1990
-
-
-
- ----------------------------------------------------------------------
- I n p u t P a s t E n d
- ----------------------------------------------------------------------
-
- WE NEED AUTHORS!
-
- If you are interested in writing for the QBNews, you can contact
- me at the address below. I can also be reached on Compuserve as
- 76510,1725 or on Prodigy as HSRW18A. If you are submitting articles, I
- ask that they be ASCII text with no more than 70 characters per line.
- As far as reviews go, I am pretty well set so what I really want is
- code.
-
-
- You can write me at:
-
- The QBNews
- P.O. Box 507
- Sandy Hook, CT 06482
-
- David Cleary
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- The QBNews Page 47
-
-