MiDat TSR database
One of my creations I ended using most often was a fast, light-weight, line-oriented micro database. The DOS program was waiting in the background as a memory-resistant program, ready to be activated from every other text mode based DOS program by hitting the Alt+Scroll lock key.
It was TSR program. A concept PowerBASIC called "popup".
I used version numbers like "v1.0", but more as a marketing tool, since that was what version numbers meant to me these days. In addition I kept track of the date whe a source file was changed last.
My files had a license header. I called it "copyright" back then, not "license", but it was a license. Specifically "Public Domain".
I used a documentation header that was the same in many of my projects, as well as a custom set of PowerBASIC compiler directives, mostly for a minimized executable file.
I used German inline comment next to English variable names for a very long time.
You can specify a working directory, including a file name extension pattern, e.g. midat c:\tables\*.tsv. There is quite some code to deal with all the possible combinations, including some inline assembler to not get the current working directory (that would have been a simple
CURDIR$ function) but to get the directory of the MIDAT.EXE executable. The default was to store the text files right there in the program directory. This was quite common when working with DOS.
File selector dialog with quick search.
No save, but also no undo.
Automatic alphabetical order.
ARRAY SORT strings$ COLLATE UCASE.
quick search and continue searching by pressing Ctrl+Enter.
There is a lossy character set conversion function, triggered by pressing Shift+F2, that allows to open Windows text files and convert their charset from Windows-1252/ISO 8859-1 to MS-DOS' codepage 437/850. This conversion was limited to the German umlauts ä, ö, ü, Ä Ö, Ü and ß. Tab moved the MiDat window to the bottom of the screen.
F2 triggered an "export to Windows" function, converting tabulator-separated text to semicolon-separated CSV while also converting the charset to Windows-1252. The file name extension WDB, which stands for "Works database".
There is a print function, triggered by pressing F9, doing
LPRINT in a loop. With a confirmation popup. With error checking and reporting. All unnamed, in the middle of the main keyboard handler loop, which is in the middle of the TSR loop. Awesome. Clearly a "because I can" feature. I can't remember using it. Why should I? You can not choose what to print. It's even bound to a specific printer when it tries to predict the number of pages it's going to print, assuming a page will contain exactly 66 lines. Epson LQ-550, that was the model my family had back then. A programmable (!) printer that deserves it's own whole story.
Tabulator expansion. 8 spaces.
The line editor supports Ctrl+Cursor right and left, which makes the cursor jump to the end of the next or the beginning of the previous word. It's somewhat impressive how much I loved this feature that I came up with my own implementation, including a custimized set of "jump over" characters. And today, 18 years later, I still use word-jumping every single day. I need it so much that I get angry when it's missing in an editor, e.g. in the otherwise totally awesome Nano editor I currently use to write my Git commit message.
Custom cursor, spanning the bottom two rows of the character.
mov ah, 01h; mov ch, 06h; mov cl, 07h; int 10h, or, converted to 16 bit decimal numbers,
reg 1, &H0100: reg 3, 1543: call interrupt &H10.
You can leave the edit mode by pressing Enter or the cursor up/down keys.
Pressing Esc in edit mode usually means "cancel", and changes to the current line are reverted. But there is one exception: When the line was empty, there is nothing that can get lost and the new line is saved.
There is a backup feature you can enable by using /bak as a command line parameter. I remember myself not using this feature, because it did not made much sense, considering how the tool was meant to be used: You open it by pressing Alt+Scroll lock, edit a single line, and close it. This means the backup file was usually only a few minutes older than the original, with very few or even a single line being different.
The structure of the code is quite horrible, judging from todays experience. One instruction per line? Named functions? Code reuse? Nah. Minimal code was much more important, which does make quite some sense considering the screen space was limited to 21 lines with 77 characters each in the PowerBASIC IDE. There are only five procedures and one function. The main part of the code, more than 400 lines, are not structured at all. Even worse. There is a giant, unconditional loop wrapping more than 300 lines. The deepest nesting level is 7 levels.
There are three keyboard handler loops: One in the file selector, one when browsing the lines of a text file, and one in the line editor. I remember being proud when I understood this core concept.
do i$ = "" while len(i$) = 0 i$ = inkey$ wend if ascii(i$) = 27 then print "Esc was pressed" exit loop else print "Character " + $i + "was pressed" end if loop
I was still using
GOTO in a few places. Sometimes to exit nested loops, similar to what we are still allowed to do nowadays. Sometimes to jump back to the file selector when pressing F3.
In total, there are 13 interrupt functions called. One of these calls is even done in an inline assembler section.
There is a lot of
POKE going on for multiple purposes, which is PowerBASIC's way to work with pointers to directly access the memory. I'm using it mostly to access the screen and draw the UI, which is much more powerful and also much faster than using
- Highlight a long line and press End. Parts of the screen are not refreshed and shows a fragment of the long line.
- Switch to edit mode by pressing Enter and continue typing at the end of the line. This kind of works but can not be seen since there is no horizontal scrolling.
- When you open a regular text file, it appears to be empty, because all the empty lines in the file get ordered to the top.