Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
I guess the BASIC for hobbyists notion stems from the fact those languages were kind of looked down upon. Not entirely unjustified either, GW-BASIC for example, while decent back then for writing some simple programs on your home computer was a sluggish overly verbose piece of crap compared to C for example. The later BASICs have come quite far after that though.
PS:
Imho Visual BASIC for MS-DOS was one of the best basics back for DOS.
Last edited by Peter Swinkels; Jan 30th, 2024 at 08:40 AM.
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
GW-BASIC for example, while decent back then for writing some simple programs on your home computer was a sluggish overly verbose piece of crap compared to C for example
All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Here is the content of a text file that came with PowerBASIC 3.5 about PB vs QB:
Code:
100 ways PowerBASIC 3.2 beats QuickBasic
========================================
1- PB 3.2 supports true pointer variables. Traditionally, a Basic
programmer had to use a combination of DEF SEG and PEEK and POKE to
access memory. Pointers are not only more flexible, they also make
data access much faster.
2- Code pointers allow a programmer to call a routine or jump to a label
without having to know their name. The CALL DWORD extension allows
programmers to call subs by address and pass up to 16 arguments.
3- Calling procedures that accept a variable number of arguments.
4- Underscores "_" in variable names, allowing for more flexibility in
naming variables and procedures.
5- Enhanced communications support. Support for COM1 through COM4 at up
to 115200 bps. Even support for non-standard addresses and IRQs as
well as 16550 FIFO support.
6- PB3 directly creates TSR (terminate/stay-resident) programs which can
"pop-down" to a memory image of 4K! Memory resident programs can be
activated by practically any stimulus: a hot key, timer, inactivity,
a hardware or software interrupt, even a message from a foreground
program. In fact, it's possible for multiple TSRs to activate each
other repeatedly, with two-way communication throughout. No other
language offers this capability as an integral part of the compiler.
7- PB3 uses all real mode memory for dynamic strings. It's the first
and only Basic with a no-limit, handle-based string memory manager;
QB is limited to substantially less than 64k, and PDS has "inside"
segmentation limits (<64k per module, per sub-program, etc.)
8- The PB3 String Memory Manager is a resource available to any user
code. Both Basic and Assembler code can allocate, release, and alter
memory blocks as required by the programmer. While other compilers
may allow you to calcluate string location or assignment, none allow
the full memory management functionality of PowerBASIC.
9- PB3 compiles to true machine code in the integrated environment; the
identical code as an .EXE file. You never need to deal with a slow,
p-code interpreter as in QB and PDS. That means faster development,
and the elimination of subtle differences between interpreted and
compiled results.
10- PB3 offers unsigned integer variable types: BYTE, WORD, DOUBLE WORD.
(byte: 0-255 word: 0-65,535 dword: 0-4,294,967,295). Unsigned
integers are not available in other Basic compilers.
11- Optionally, PB3 can require that all variables be declared before use;
this option greatly enhances the probability of catching "typos"
automatically during compilation.
12- Dual Monitor Support is offered in both the PowerBASIC Integrated
Environment and the PBD Standalone debugger. This allows the
programmer to simultaneously view a full screen of source code and
debug information alongside a second full screen generated by the
target program. Annoying screen flashes and pauses are eliminated.
13- PowerBASIC is DesqView aware.
14- As an enhancement to user-defined TYPES, PowerBASIC is the first Basic
compiler to offer user-defined UNIONS as well.
15- PB3 offers 64-bit signed integer variables types. Quad-word integers
are not available in other Basic compilers.
16- With PowerBASIC, there is no need to maintain numerous sets of
libraries. Other compilers require one set of run time libraries for
near strings, another for far strings, and still another for each of
the floating point options. Then you need Quick Libraries for work
in the IDE, but Link Libraries to create an .EXE. With PowerBASIC,
there's no more confusion: All run time libraries are built into
the compiler, and PB3 selects them automatically! Furthermore, the
built-in PowerBASIC linker recognizes the same object modules, units,
and libraries, whether you're running in the IDE or creating an .EXE.
17- PB3 offers a USING$ function, which may be referenced in any string
expression. It duplicates the numeric and text formatting capability
of PRINT USING, but allows the result to be saved or modified, rather
than require immediate printing.
18- PB3 offers extended precision (80-bit) floating point variable types.
19- The PRINT USING and USING$ functions in PB3 may be dynamically altered
to format numeric values with leading zeros, or other special
characters. Further, currency characters ("$,.") may be easily
adapted to non-USA standards when needed.
20- PB3 offers conditional compilation directives ($IF/$ELSE/$ENDIF) to
allow easy version control, as well as large comment blocks in your
source code.
21- PB3 supports HUGE arrays (total data size > 64k) on a selective basis.
Unlike other Basic compilers, the extra overhead of huge array
calculation is only applied to those arrays which require it.
22- PB3 supports fixed-point BCD variable type with variable precision
from 0-18 digits, not a forced 4 digits which introduces additional
round-off errors.
23- PB3 supports floating point BCD variable type.
24- PB3 offers built-in array manipulation functions: ARRAY SORT,
ARRAY SCAN, ARRAY INSERT, and ARRAY DELETE.
25- PB3 offers a full-functioned, built-in assembler. Critical sections
of a program can easily be hand-optimized to provide the utmost
performance, as Assembler and Basic can be intermixed line-by-line.
26- PB3 won't run out of memory compiling the largest programs. It
automatically uses EMS, XMS, and VMS virtual disk memory.
27- User-defined TYPE arrays need not be a power of two in element
size in order to exceed 128k of data space.
28- The PB3 program editor offers the capability to read and write
blocks of text to external disk files.
29- PB3 supports source-level metastatements for all compilation
switches.
30- VIEW TEXT supports scrollable rectangular text view ports.
31- PEEK and POKE extensions support byte, integer, and long integer.
32- PEEK$ and POKE$ extensions support memory block moves or assignment.
33- FLUSH will force all buffered data to be written to a disk file,
while minimizing the overhead of a file close and re-open.
34- PowerBASIC offers MIN and MAX functions which allow a variable
number of arguments: PRINT MIN(a%,b%,c%,d%)
35- BIT operations include shift, rotate, set, reset, toggle, test.
36- BIT arrays up to 512k bits are implicitly supported.
37- CHR$ allows a variable number of arguments. CRLF$ = chr$(13,10)
38- Optional procedural math package offers faster calculation
(improvement of 40% to 500%) when no numeric co-processor is
installed. Procedural math package uses the 8087 if it is
available, and can toggle between the emulator/procedural option
on a statement-by-statement basis for the highest optimization.
Procedural package adheres to IEEE floating-point standard.
39- Flex string variable type offers fixed-length strings which may
be sized dynamically at run-time.
40- MAP statement allows flex scalar and array variables to be
linked together into dynamic data structures, with nesting
capabilities limited only by available memory. These data
structures are created and sized dynamically at the time of
program execution to offer dynamic data base capabilities.
41- Many string and numeric functions offer the ANY option, such
as INSTR("abcde", ANY "cq") returns 3.
42- EXTRACT$ captures that portion of a string up to a sub-string.
43- REPEAT$ creates a string from a repetition of another string.
44- REPLACE substitutes one sub-string for all occurrences of another.
REMOVE$ removes all occurrences of a sub-string.
45- VERIFY ascertains that all characters in one string also occur
in a second string.
46- TALLY counts the occurrences of a sub-string.
47- LTRIM$/RTRIM$ strip leading/trailing spaces or other characters.
48- STR$(x,y) function specifies y significant decimal digits.
49- ROUND(x,y) rounds off x to y digits past the decimal point.
50- STRPTR/STRSEG return the address of any string variable data.
Dynamic, Flex, and Fixed-length strings are supported as both
scalars and arrays.
51- END statement may return an optional error level.
52- ASCII functions avoids error conditions of ASC function, by
returning -1 if the argument is a zero-length string.
53- Integer divide, MOD, AND, OR, XOR, EQV, and IMP are valid
on all numeric values in the range of a quad-word (64-bit)
integer (+/- 2^63-1).
54- PB3 optionally generates 80286/80386 specific code.
55- Library stripping for ambiguous library functions is controlled
directly by meta-statements or menu choices, rather than the
necessity of complex linker commands.
56- Separate compilation via unit modules is simpler, faster, and offers
standard PUBLIC/EXTERNAL statements. Assembler object modules may be
linked via $LINK meta-statements.
57- Executable files are generated directly rather than complex
shells to a compiler and linker, resulting in faster compilation.
58- A full complement of error checks can easily enabled or
disabled, including STACK, NUMERIC, OVERFLOW, and BOUNDS.
59- The PowerBasic editor doesn't alter capitalization or spacing,
and doesn't insert or remove code from the source program.
60- Line continuation characters are supported inside and outside of
the IDE.
61- Identical code, just as efficient, is generated when error
trapping is enabled. Other compilers generate larger, slower
code whenever a program includes an ON ERROR GOTO clause. This
is a serious factor often overlooked in published benchmarks.
62- PowerBasic supports a single-line if/then/else statement which
is 100% compatible with BASICA/GW-BASIC. Other Basics force this
code to be re-written.
63- PowerBasic performs short-circuit expression evaluation in
boolean expressions.
64- Interpreted print: the user chooses graphic character or
interpreted actions for special ascii characters.
65- MTIMER function provides microtimer accuracy.
66- INSTAT function tests for a keypress without removing it from
the keyboard buffer.
67- INCR and DECR statements are offered for all numeric data types.
68- Forward references to DEF FN, SUB, and FUNCTION are allowed.
69- $SEGMENT allows multiple segments of module level code within
the same source file. There is no requirement to split your
program into multiple modules as your program size increases.
70- EXP2, EXP10, LOG2 and LOG10 are supported.
71- CEIL function returns the smallest integer greater or equal to n.
72- CALL INTERRUPT is built right into the PowerBASIC language. There's
no need to load a special library in order to access this capability.
73- FRAC function returns the fractional part of n.
74- FIX function returns the whole number part of n.
75- ISTRUE and ISFALSE Boolean operators force true and false values
to -1 and 0 respectively.
76- ITERATE forces a new iteration of a loop.
77- PB3 offers absolute arrays at any specific memory location.
78- EXIT FAR provides a controlled, multi-level SUB/FUNCTION
exit - a safe, yet powerful enhancement to the SETJMP and
LONGJMP functions found in C compilers. This allows you to
exit a SUB/FUNCTION, and immediately branch to the label most
recently specified as an EXIT FAR destination in any "parent"
procedure with any number of intervening procedure calls. All
temporaries and local variables are released as necessary, so
this is readily usable for special exception-processing. EXIT
FAR constructs may be nested to any level.
79- CODEPTR and CODESEG functions allow you to obtain the offset
and Segment of any SUB, FUNCTION, or LABEL in the program.
This capability, unavailable in other Basics, is essential
for interrupt handlers and certain other assembler code.
80- A standalone debugger (PBD.EXE) is included with PowerBASIC 3.0.
81- The PB3 Librarian (PBLIB.EXE) constructs libraries which may
include both industry-standard object modules (.obj), as well as
highly efficient binary unit modules (.pbu) constructed by the
PowerBASIC compiler.
82- Internal assembler code can access all PowerBASIC variables (even
local and static variables), as well as subs, functions, and labels.
83- $ALIAS metastatement allows the name of the main data segment to be
redefined for external object modules.
84- BITS function allows fast, one-step conversion between signed and
unsigned representations of a numeric value.
85- Internal procedures ARRAYCALC and ARRAYINFO are provided so that
assembler code can manipulate all aspects of PowerBASIC arrays.
86- PowerBASIC offers the option to preserve or discard the GOSUB stack
at the current SUB/FUNCTION level in case of a trapped error. If
the choice is to discard it, substantially more efficient code can
be generated.
87- PowerBASIC functions can be called just as if they were a SUB, and
the returned result is discarded.
88- CLS statement offers options to clear the text viewport, the graphics
viewport, the key line, or the entire screen.
89- ERRTEST function returns the current error number, while resetting it
to zero for future calls. This provides an efficient means of error
polling when using ON ERROR RESUME NEXT to mask system errors.
90- FILEATTR function can optionally return the open/closed status of a
particular file number, as well as the record length of a random file.
91- KEY statement now offers an optional third parameter which allows the
programmer to define any shift keys which should be ignored in
determining if ON KEY GOSUB should be called. With other Basics,
it's necessary to declare numerous key statements to cover every
possible combination of shift keys., or else an errant "caps lock"
or "num lock" key can cause a defined hot-key to be ignored.
92- NAME statement allows renaming of directories as well as files.
93- DIR$ function allows you to read directory items with any attribute,
not just normal files: sub-directories, volumes, hidden/system files.
94- OPEN COM supports the DT option which causes DTR to be asserted after
the communications file is closed. PowerBASIC supports direct access
to COM3 and COM4.
95- OPTION BINARY BASE allows the programmer to choose binary file access
based at zero or one, depending upon the program logic.
96- PowerBASIC provides documented Basic and Assembler access to numerous
internal system variables. This provides easy access to the cpu type,
co-processor type, cursor shape and visibility, PB revision, screen
page and attributes, video card, print using format characters,
screen/viewport size, and much more.
97- BIN$ function returns the binary representation of a number.
98- GET$ statement reads a binary file, assigning a specified number of
bytes to a string variable. PUT$ statement writes a string expression
to a binary file.
99- DELAY statement pauses program execution for n seconds without the
possibility of interrupt by a keystroke.
100- While PowerBASIC offers a large superset of the functionality found
in other compilers, moving up to PowerBASIC 3.0 couldn't be easier!
PB3 is 99+% compatible with QuickBasic syntax, and our Programmer's
Guide devotes a chapter to the minor differences which remain.
PowerBASIC . . . it's not your basic BASIC!
Check List
==========
Feature PB 3.0 QB 4.5 PDS 7.1 VBDOS
======= ====== ====== ======= =====
TSR programming support built-in X
Internal Assembler in the language X
Option to require variable declaration X X
Unsigned byte, word, dword integer variables X
User-Defined TYPES X X X X
User-Defined UNIONS X
User-Defined Dynamic Data Structures (MAPS) X
Array sort, scan, insert, delete statement X
Pointers to a sub, function, or label X
EXIT FAR multi-level sub/function exit X
Unlimited dynamic string space <1> X
ON LOCAL ERROR X X X
Standalone debugger included X X X
Editor never changes your source programs X
Conditional compilation ($IF/$ELSE/$ENDIF) X
Viewport for screen text display X X
Alternate procedural math package X X X
Procedural math package utilizes 8087 X
Extended 80-bit floats & 64-bit integers X
Floating point BCD variables X
Fixed point BCD variables <2> X X X
Block memory moves with PEEK$/POKE$ X
<1> PowerBASIC can allocate all real mode memory for any and all dynamic
strings. There are no "inside limits" (such as 64k limit per module
or sub-program) as are found in far string implementations.
<2> PowerBASIC Fixed-Point BCD variables are implemented as 64-bit scaled
integers for computational efficiency. The decimal digits (to the right
of the decimal point) may be user-defined from 0 to 18. Some Microsoft
products offer a currency data type, which is fixed at 4 decimal places.
Even though the internal format is identical to that of PowerBASIC,
additional round-off code is typically required in financial calculations
to correct the precision to standard dollars/cents levels. Since this
binary-coded-decimal format differs from traditional "natural bcd",
Microsoft contends that their products do not support BCD variables.
That's all very impressive, however here's what QB can do and PB can't:
1. Low-resolution 320x200 256 color VGA.
2. 60 rows of text in default VGA (640x480 16 color)
3. Constants of a datatype other than integer.
4. QB's IDE and help are more user friendly imho.
Last edited by Peter Swinkels; Jan 30th, 2024 at 11:18 AM.
Reason: additional info
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Originally Posted by fafalone
I think it's really interesting QB had predeclared functions... I had been contemplating posting a request for these in tB so we could provide prototypes of callback functions like the SDK headers, but it seemed like pushing it too far into C/C++ territory. But looks like it would just be getting back to it's roots.
I'd strongly advise against such a suggestion. This existed in C/C++ out of necessity. Ancient compilers were single pass compilers which means if you call a function, that function must be compiled before any call to the function is compiled. Modern compilers are multi-pass compilers which means you can call a function in the first compilation unit and implement that function in the 1000th compilation unit and your program will still work because the compiler will resolve the all the functions on in all compilation units on the first pass.
Single pass compilers do not make sense anymore considering the excess of computing power we have today so I doubt TwinBASIC uses a single pass compiler.
Note: When I say single pass, it's not single pass in the strictest sense. I'm sure there is some backtracking but due to the constraints on computing power back in the day, it was avoided as much as possible.
C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter
There's just no reason to use garbage like InputBox. - jmcilhinney
The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Lately I have been thinking about writing a vbdos vs qb list, anyway I remembered explaining to someone why qb is vastly superior to GWBasic:
Q(uick) Basic:
1. Is faster.
2. Supports long integers.
3. Supports 64k strings.
4. Supports binary file access.
5. Supports VGA.
6. Supports structures.
7. Supports procedures and functions with their own separate scope.
8. No mandatory line numbers.
9. Supports labels.
10. Offers a way to exit loops without resorting to using to the GOTO statement.
11. Supports unconditional loops.
12. Conditional expressions can be placed at the end of the loop.
13. Supports SELECT CASE.
14. Supports multiline blocks in IF statements.
15. Supports multiple branches for IF statements.
16. Supports constants.
17. Offers functions for converting the letter case in strings.
18. Comes with a much better editor.
19. Supports arrays with a variable base.
20. Has a way to check array boundaries.
Also, if I remember correctly GWBasis has a buggy INSTR function which is likely to return a value of one instead of zero when it could not find the specified substring.
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
If I were to sum up what makes QuickBasic superior to GWBasic in a single statement, I'd say QB is vastly superior because it introduced structured programming constructs to the language. GWBasic was like assembly. Every line of assembly operates in isolation, performing a discrete, self-contained action without any relation to the surrounding lines. There was no concept of aggregating related statements into cohesive blocks, such as Do...While loops, If...Else...Then conditional blocks, or subroutines/functions etc.
C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter
There's just no reason to use garbage like InputBox. - jmcilhinney
The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Not quite, GWBasic did support blocks inside loops, however QB vastly did expand on that concept.
btw:
I keep seeing something about ISAM databases in qb 7.1 and vbdos’s online help. They seemingly throw a lot of keywords at you without really explaining the fundamentals and the sample code I did find confused me. I thought I had a pretty good grasp on programming in BASIC and figuring out code but this concept has me stumped.
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Is it ISAM you don't understand or using ISAM within QB? If it's ISAM there's plenty of info on the Internet.
All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
I don’t really know about either, however given that there is enough info about ISAM in general, I’d probably benefit the most from an example in either vbdos or qb.
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Duh, I overlooked the Booklook example that came with VBDOS. Its entire bookgen.bas module appears to contain ISAM related code. The only question now is whether I can figure it out. :-)
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
vbdos vs qb:
1. Object oriented and event driven interface controls.
2. Better interface.
3. More efficient with memory thanks to EMS support.
4. Database support (ISAM).
5. Mandatory variable declaration with OPTION EXPLICIT.
6. COMMON SHARED variables can be grouped into memory blocks.
7. Error traps can be local to procedures.
8. More flexible syntax: underscores in names, empty braces for function calls, AS clauses for functions.
9. REDIM PRESERVE.
10. DIR$
11. CURDIR$
12. CHDRIVE
13. Currency datatype.
14. Has a clipboard for text.
15. Has the ability to extract specific sub values from the date and time.
16. Finance related functions.
16. Has a printer object which could replace the LPRINT statement.
17. A string formatting function. (FORMAT$)
18. The NOW, TIMESERIAL and DATESERIAL functions.
19. ERROR$ returns descriptions that go with error codes.
20. More flexible way to manage the stack size with STACK statement and function of the same name. Also less drastic than CLEAR in resetting data.
This is all I think of atm. :-)
PS:
It seems that even if you don't use the ability to create forms there would still be many subtle advantages over qb! :-)
Last edited by Peter Swinkels; Mar 5th, 2024 at 01:52 PM.
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Does anyone here know whether there is any real advantage to using PRINTER.PRINT instead of LPRINT? Both appear to behave the same way. The only reason I think of for the PRINTER object is compatibility with Visual BASIC for Windows.
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Don't take this as gospel but when I see LPRINT it evokes memories of writing directly to a parallel port like LPT1. It's been far too long since I touched a classic BASIC variant like QuickBasic. I barely remember how anything works there anymore so I could be wrong here.
C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter
There's just no reason to use garbage like InputBox. - jmcilhinney
The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Now that you mention it, VBDOS's PRINTER object does have a PrintTarget property which allows you to specify an LPT port (1-3), but wouldn't that still mean that internally it basically still writes directly to the port except for the fact you get to select which port? Now, I know Windows has drivers mediating between devices and software, from the very first version if I am not mistaken, but I don't think VBDOS applications use drivers, correct? In fact, does an MS-DOS application writing to LPT1 write directly to the parallel port? Wouldn't you need to use the OUT statement for that? I am not sure, but I believe IO.SYS was meant to serve has a rudimentary hardware abstraction layer which would mean it probably had a "driver" embedded for writing to parallel ports among other things. But, like you said, this is all very long ago, I never to knew every detail about MS-DOS and probably forgot a few things too. :-)
Last edited by Peter Swinkels; Feb 19th, 2024 at 12:22 AM.
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
DOS had drivers but it was also a real mode operating system. Drivers in DOS were in the form of something called a TSR which is most closely equivalent to a modern Windows service or a Linux/Unix daemon. When it came to hardware access like Printers and such, real mode allows your applications to directly access to the hardware so I'd expect the Printer object to also use LPT ports. Perhaps they changed it when Visual Basic was ported to Windows because Windows is a protected mode operating system so you can only access the hardware through a user mode intermediary.
C++ programmers will dismiss you as a cretinous simpleton for your inability to keep track of pointers chained 6 levels deep and Java programmers will pillory you for buying into the evils of Microsoft. Meanwhile C# programmers will get paid just a little bit more than you for writing exactly the same code and VB6 programmers will continue to whitter on about "footprints". - FunkyDexter
There's just no reason to use garbage like InputBox. - jmcilhinney
The threads I start are Niya and Olaf free zones. No arguing about the benefits of VB6 over .NET here please. Happiness must reign. - yereverluvinuncleber
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Yes, but until this was mostly blocked when NT versions of Windows were released MS-DOS programs could still mostly directly access the hardware while running in Windows. Something about v86 mode from what I understood. I never really quite understood how exactly early versions of Windows managed to run DOS programs. Once I really started thinking about it I was really confused about how exactly Windows captured a DOS program's graphical output (which except for text mode stuff) was mostly directly written to video memory and (usually) neatly displayed in a Window. And while I have stated before that I felt that many early versions of Windows were unstable bug ridled pieces of *** it was kind of impressive how Windows juggled executing all those different processes. As long as no process interfered too much with the rest that is. I was especially impressed when I first used Windows 2000 that it wasn't so easy to crash as earlier Windows versions I'd worked with.
And yes, I've told this story several times before, but I can't resist bringing it up again: the fact Windows 2000 ran on my old piece of *** a 80586 at all was perhaps the most impressive thing about it. :-) According to the sysytem requirements it needed a 80686 with twice (128 mb) the amount of memory mine had. (64 mb.) It slow as heck, *but* it was surprisingly stable! :-)
Last edited by Peter Swinkels; Feb 20th, 2024 at 01:33 PM.
Reason: grammar and punctiation
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Well, I decided to have some fun and make a rudimentary Notepad clone in VBDOS. On one hand it is wonderful to be able to implement fully functioning forms, messageboxes, and dialogs with relative ease in a BASIC dialect for MS-DOS, on the other VBDOS's form designer is definitely a bit more laborious than the one found the Windows versions, but that's kind of to be expected. ;-)
EDIT:
And before I forget, this project isn't finished yet. ;-)
Last edited by Peter Swinkels; Feb 24th, 2024 at 05:22 PM.
Reason: added missing info
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Attached is a much more complete version of DOSPad, and also for who might have tried to download my previous file, I forgot that VBDos saves certain files in a binary format by default. Personally I don't like that because I prefer to be able to open a source file in an external editor if need be. (It is rare, but sometimes necessary.) Also, binary format files can set-off false virus warnings, so that is one more reason I dislike them, especially when sharing my projects online such as on this forum.
Since my project is meant to be fun little exploration of building a form-based app in VBDos I am probably not going to add much more features to my program other than some rudimentary error-handling capabilities. Don't expect much more than the most basic of basic Notepad clones. It should work as intended, but isn't meant to be truly practical.
I am considering attaching a compiled program, but I need to check whether such file-types are allowed, also virus scanners don't like binaries, so there's that. :-)
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Okay, after putting it off for a while I got around to having a look at that Bookgen example in order to figure out what exactly ISAM is.
I attached a copy of the example to this post. I did strip out most comments because I feel they make the code inreadable in this case and I can always refer to the original example and online help in the IDE in this case.
A quick look at the code gives me the strong impression that the example provided by Microsoft is a bit overdeveloped, I really don't like it when bells and whistles are crammed into an example that aren't really related to what the example is supposed to demonstrate. The Bookgen example, is meant to demonstrate ISAM but has an entire IDE attached to it as well and well, comments are all nice and dandy but every little bit of code had been documented. You'd think someone who wants to learn about ISAM would know the essentials of BASIC programming and how to use the online help. *sigh*. Any way back on topic, here are some code snippets:
Code:
OPEN "BOOKS.MDB" FOR ISAM Books "BookStock" AS cBookStockTableNum
Which looks a lot like a slightly more advanced version of the "OPEN ... FOR RANDOM " and "GET/PUT" record based features of earlier BASIC dialects. The next snippet:
Code:
TYPE Books
IDnum AS DOUBLE
Price AS CURRENCY
Edition AS INTEGER
Title AS STRING * 50
Publisher AS STRING * 50
Author AS STRING * 36
END TYPE
It looks like any data is defined by the structure above. And this is what an operation on said data looks like:
Code:
INSERT cBookStockTableNum, BigRec.Inventory
Not really all that complicated, but it will take me some time to really figure this out. I will probably build a small ISAM based app myself in VBDOS and call it a day.
PS:
And speaking of overwritten, VBDOS's online help is wonderful but does tend to throw a lot of info at the user all at once too, imho. :-)
PS PS:
The Bookgen example uses the *.mdb extension for its "database" file, don't read too much into that, it doesn't appear to be even remotely compatible with Microsoft Access. :-)
PS PS PS:
Qbx 7.1 (or whatever you want to call it) also supports ISAM. It's online help appears to be less cluttered than VBDOS's but its demo's state I have to first build a new library from other libraries first. Probably not worth the effort given that I suspect those demo's will demonstrate essentially the same as those in VBDOS.
Last edited by Peter Swinkels; Feb 26th, 2024 at 11:45 AM.
Reason: additional info
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
I see a few people downloaded the example I posted! :-)
According to this thread: http://www.petesqbsite.com/phpBB3/viewtopic.php?t=1098 - qbx's 7.1's ISAM (and therefore VBDOS) isn't truly a database system but more some kind of file access method. One that produces files that are hardly compatible with any database software at that. Still I am curious to learn more about it. It might provide some clues as to how other old DOS software managed their data, which could be fun to investigate.
Anyway, it gives me an excuse to indulge in playing with VBDOS. :-)
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Okay, I briefly glanced over the command line utilities provided with VBDOS and does seem there are utilities for conversions between other databases and its ISAM (pseudo?-) database files.
Attached to this post are three pages from VBDOS's online help printed to a text file which seem most relevant atm. They're best viewed with a fixed-width font that supports box drawing ASCII characters such as Terminal and word-wrapping disabled in Notepad or similar editor.
Also, I found some interesting debugging utiltiies which distracted me, but those could be useful to investigate how VBDOS programs work internally. I know a bit about assembly language, it's probably going to be tedious even with a good debugger. :-)
Last edited by Peter Swinkels; Feb 26th, 2024 at 11:42 AM.
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Success!
Code:
OPTION EXPLICIT
DEFINT A-Z
TYPE NumberStr
Number AS STRING * 10
END TYPE
DECLARE SUB CreateDataBase (Numbers() AS NumberStr)
DECLARE SUB DeleteNumberTable ()
DECLARE SUB DisplayDatabase ()
DECLARE SUB ReadNumberList (Numbers() AS NumberStr)
DIM Numbers() AS NumberStr
CLS
DeleteNumberTable
ReadNumberList Numbers()
CreateDataBase Numbers()
DisplayDatabase
END
NumberList:
DATA "zero"
DATA "one"
DATA "two"
DATA "three"
DATA "four"
DATA "five"
DATA "six"
DATA "seven"
DATA "eight"
DATA "nine"
DATA "ten"
DATA "*"
SUB CreateDataBase (Numbers() AS NumberStr)
DIM FileH AS INTEGER
DIM Index AS INTEGER
FileH = FREEFILE
OPEN "Numbers.mdb" FOR ISAM NumberStr "NumberTable" AS FileH
FOR Index = LBOUND(Numbers) TO UBOUND(Numbers)
INSERT #FileH, Numbers(Index)
NEXT Index
CLOSE FileH
END SUB
SUB DeleteNumberTable ()
ON LOCAL ERROR RESUME NEXT
IF NOT DIR$("Numbers.mdb") = "" THEN
DELETETABLE "Numbers.mdb", "NumberTable"
END IF
END SUB
SUB DisplayDatabase ()
DIM FileH AS INTEGER
DIM Index AS INTEGER
DIM NumbersInDatabase(0 TO 0) AS NumberStr
FileH = FREEFILE
OPEN "Numbers.mdb" FOR ISAM NumberStr "NumberTable" AS FileH
DO
RETRIEVE #FileH, NumbersInDatabase(UBOUND(NumbersInDatabase))
MOVENEXT FileH
IF EOF(FileH) THEN
EXIT DO
END IF
REDIM PRESERVE NumbersInDatabase(LBOUND(NumbersInDatabase) TO UBOUND(NumbersInDatabase) + 1) AS NumberStr
LOOP
CLOSE FileH
FOR Index = LBOUND(NumbersInDatabase) TO UBOUND(NumbersInDatabase)
PRINT NumbersInDatabase(Index).Number
NEXT Index
END SUB
SUB ReadNumberList (Numbers() AS NumberStr)
RESTORE NumberList
REDIM Numbers(0 TO 0) AS NumberStr
DO
READ Numbers(UBOUND(Numbers)).Number
IF RTRIM$(Numbers(UBOUND(Numbers)).Number) = "*" THEN
REDIM PRESERVE Numbers(LBOUND(Numbers) TO UBOUND(Numbers) - 1) AS NumberStr
EXIT DO
END IF
REDIM PRESERVE Numbers(LBOUND(Numbers) TO UBOUND(Numbers) + 1) AS NumberStr
LOOP
END SUB
It creates and displays a simple database with a single table! No extras, just the basics. :-) Of course this program is rather rough around the edges and a true data management program would be far more complex with more safeguards and what not.
Run PROISAMD.EXE before trying to run it first.
Last edited by Peter Swinkels; Feb 26th, 2024 at 02:15 PM.
Reason: added info
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Up next, something else I never really got, those financial functions. To be honest I never really got much deeper into that than adding income and subtracting expenses and how your interest increases as you accumulates as long as your balance does.
I never really got why BASIC would provide fancy financial calculation functions in later BASIC dialects. While Visual Basic for DOS is pretty close to being a really good programming language imho, would anyone in their right mind do any serious financial calculations with it? It is still BASIC, no matter how many fancy features you stuff it with. :-)
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Re ISAM. The beauty of ISAM is that you can create a file with multiple indexes and use these indexes to quickly locate required record(s). So from the TYPE in post #61 you might have an ISAM file with indexes for Publisher, Author etc so that extracting all books for specific author(s) or publisher(s) would be quick as it would not require a full database search. Once established the maintenance of these indexes would be automatic without specific user code being needed. You won't see the benefit of this method for a file with just a few records, but when you have tens of thousands of records you can easily see the time difference between accessing an indexed field to one which isn't indexed.
All advice is offered in good faith only. You are ultimately responsible for the effects of your programs and the integrity of the machines they run on. Anything I post, code snippets, advice, etc is licensed as Public Domain https://creativecommons.org/publicdomain/zero/1.0/
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
@2kaud: I suspect that this ISAM if used properly is indeed a pretty solid way of managing large amounts of data. The BookGen example which I complained about as being overly complex probably demonstrates that better than the tiny program I uploaded. However, I believe my code better gets the basics of how to use ISAM across. Also, I believe the user complaining on PetesQb site (link is somewhere in this thread) got a bit overwhelmed by the online-help, like me, and in his rush to get something done overlooked the conversion command line utility which does seem to support actual database systems that were popular. ISAMIO appears to support BTrieve for example and dumping to a text file also is possible. In fact you could do that manually with some code if you really wanted/needed to. Anyway, I just really wanted to know what this whole thing about ISAM in BASIC was all about. Now I know and unless I feel like building some kind of database manager for fun, which I don't I am not going to investigate it further.
I briefly considered the possiblity there might be some older programs using a format compatible with BASIC's ISAM, but I doubt there'd be that many. Also, if there were any, I'd still need to guess how they structured their data, or would I? In fact, while I feel I now know enough about what ISAM is, I am still curious as to what exactly is stored in the files created with it and what isn't.
Anyway, I feel like leaving it at that and looking at the finance related functions because I never really got what those were for either.
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Alright, I had a first real look at those financial functions... They all return double precision floating numberic values! Isn't that asking for the last thing you would want while doing financial calculations? Rounding errors when large numbers are involved? Why did they even add the currency datatype to begin with in that case? Worst of all, vb6 happily uses double precision values too for supposedly financial calculations too.
And before anyone points this out, yes before I knew better I tried developing a few programs for keeping track of finances and used the double datatype which means those programs are worthless in the practical sense except for trivial calculations. Heck, you'd be better off using Microsoft Excel. :-)
Anyway, I still am curious what those functions do. :-)
Re: Feeling nostalgic I fired up QuickBASIC and wrote a Brain***** interpreter!
Okay, I have looked at those financial functions, nothing more than highly specialized bookkeeping stuff imho. Not really worth looking at any further.