Heathkit Software Operation
What follows are some general notes about how to use the various Heath-provided programs that are included with HDOS. It's been some years since many of us saw a working H8 and memories fade. It took the author a while to get back on the horse; I thought I'd pass along what I found out!
These notes are not complete and will never be complete, but they should be a good starting point for your own hacking. The author would appreciate any suggestions for additions to this help file.
A note on control characters
In general, you can quit any program by typing Ctl-D.
Also in general, Ctl-C is used as a "cancel current operation" key. Sometimes Ctl-A is used in the same way.
You can use Ctl-S to pause terminal output so you can read what's scrolling by. Use Ctl-Q to resume output.
Command | Init | Xref | Patch |
Pip | Sysgen | Dbug | Boot |
Set | Edit | Basic | |
Flags | Asm | Test17 |
The Asm, Xref and Basic links will take you to another page in this help system.
Back to Table of Contents.
The Command Prompt (command.sys)
Type "help" for a list of commands. However, the list is not complete and is in one case inaccurate:
Reset wants a little more explanation. On a real H8, you could " reset sy0:" then open and close the door and sy0: would immediately remount.
On the emulator, you can issue the 'reset' command, then open the H-17 Management window and click the Reset button associated with the drive. This will simulate opening and closing the door. Or, you can 'reset', open the Manage Diskettes dialog box, and change disks. HDOS will detect the disk swap and mount the new disk.
After entering Pip, type " help". All but two of the command-line switches are included in the help file.
If you are getting a catalog listing, you can add the "/all" switch to see how many disk sectors are allocated to the file, instead of the usual display of how many are used by the file. Remember that sectors are allocated in clusters; your files will be allocated even units of clusters, though they may not fill up the last cluster completely. This option will let you see what's being wasted.
You can also add the "/jgl" switch when displaying a catalog listing. This will activate the "/s" switch (show system files) automatically, and will show the hidden "C" flag that indicates that a file occupies contiguous space on the diskette.
Remember that the order of operation in a copy operation is <to file>=<from file>.
This is used to set options in device drivers. Use " set <dev:> help" to learn what options are available. Use " set hdos help" to learn the options in the HDOS operating system itself.
The "Gen Master" disk has had the following customizations done to the drivers and HDOS. If you sysgen using Gen Master, you won't have to redo these sets. If you make your own disk from the HDOS distribution disks, you should repeat these commands on your disk.
set sy0: step 8
set sy1: step 8
set sy2: step 8
set tt: bks
set tt: tab
set tt: nomli
set tt: nomlo
set tt: bkm
set tt: fill 10 0
set tt: fill
13 0
set hdos stand-alone
The last one is not included in the " help" for HDOS. This sets a flag allowing HDOS to go into stand-alone mode. Without stand-alone mode, you have more memory available to user programs because the drivers and overlays can be swapped in from disk. But it does operate more slowly and you can't dismount sy0: (ref: Address Space Utilization).
With stand-alone mode enabled, you can dismount and remount sy0: to force the overlays into memory. After that, sy0: can be dismounted at will and HDOS will still function. The system is faster, but you do have a little less memory available to user programs.
If you are using stand-alone mode, make sure you load your LP: and AT: drivers first or you won't be able to print or transfer files without rebooting.
This is used to change the directory flags ('s', 'w', or 'l') on your files. The instructions provided by the program are all you should need.
This is used to initialize a new disk. The instructions provided by the program are all that you should need.
I would note, however, that when prompted for bad sectors, you can always simply press return. The possibility of bad sectors is something that I really don't want to have to emulate!
Caution - init.abs is not compatible with speeds in excess of 2 mhz. At the start of a format operation, it will appear to "hang" with interrupts disabled. Simply select 2 mhz on the Speed menu and init will complete the initialization correctly. Best to select 2 mhz before running init.
HUG replacement SY: driver notes:
See the HUG SY: driver documentation for full information on Init when using that driver.
Sysgen is used to take an initialized disk and make it bootable. It transfers the necessary system files to the new disk and sets a 'bootable' flag in the label sector.
There are three formats of the command:
Transfer a standard set of files to the new disk. The standard set of files have to be present on the source disk. Unfortunately, I don't have any documentation showing what this set of files might be.
Transfer only the minimum required files to the new disk. You can then copy over whatever files that you need on this disk.
Transfer all files from the source disk to the new disk.
The author recommends that you use the "Gen Master" disk and the 3rd form of the command to create disks for this emulator. That way you will have the correct driver settings (see set above) and the correct LP: and AT: drivers.
The worst text editor ever devised by man, I swear. The author strongly suggests that you download Pie from the web site or use a Mac editor and transfer the resulting text file to the H8!
That said, here's a quick command reference. Edit uses "command completion" so you only have to type the lower-case letters in the example below; edit fills in the upper-case letters. Expressions [in brackets] are optional. Expressions <in angle brackets> are place-holders for values.
Open a file for input
Open a file for output
Fill the editing buffer from the input file
Write the selected range to the output file
Flush the buffer and unread input to the output file
Flush the buffer to the output file then fill from the input file
Flush the buffer then quit
Clear the buffer after confirmation
Lets you insert new lines at the insertion point; type Ctl-C to stop
Delete the selected range from the buffer
Change text in range, for an optional number of changes (count), but first occurrence per line
Print the range with optional filtering
Quit after prompt, abandoning the buffer
"Range" tells edit what lines to work on. A space means the entire buffer. '=' means the range last used in a previous command. A null range means operate on the current line only. The "current line" is the top line of the previous range. Here are some command examples with range expressions:
Print from the top line (^) to the bottom line ($); This is the same as using a single space for the range
Same as above; note the single space ahead of the print command
Print the first 22 lines of the buffer
Print lines 22 through 44 of the buffer
Print the next 22 lines of the buffer
Print the same range but only lines with the string 'Heathkit' in them
In the same range, for every line that contains the string 'H-19', change the string 'Heathkit' to the string 'H8', but only the first five occurrences
Print the last 22 lines of the buffer
Before doing anything permanent, like deleting a range of lines, I'd recommend that you use the "=print" command to verify that the range of lines is what you want it to be. And use the "print" command, without a range, to verify that the current line is what you think it is.
That should be enough to get you through!
A not bad system debugger. As I recall, there is a bug in dbug that causes it to mess up the terminal settings when you single step. Dbug has command completion but it goes away when this happens. (There are two patches on the project web site.)
With command completion, you only have to type the lower-case letters shown. Dbug responds with the upper-case letters.
Note: You should make sure the console is set to a width of 80 characters (" set tt: width 80") before starting dbug. Dbug uses the console width to know when to insert a New Line character to wrap output. If you have already started dbug, you can change the width in memory using the debugger (you type the underlined characters):
:B:D40331=255/80
A partial list of dbug commands follows. Expressions [in brackets] are optional. Expressions <in angle brackets> are place-holders for values.
Press space to display one or more memory bytes at the optional address or range of addresses; if range is null, only one byte will be displayed at the "current location."
Format is a single character that changes the format of the displayed memory locations:
Modifier | Format | Example |
none | Octal |
:B:40322/2 001 060 :B: |
D | Decimal |
:B:D40322/2 001 048 :B: |
F | Fullword |
:B:F40322 060001 :B:FD40322 12289 :B: |
A | ASCII |
:B:40277/9 061 061 055 016 145 142 055 017 062 :B:A40277/9 1 1 - F e b - 9 2 :B: |
Change memory at the optional address or range of addresses; if the range is null, the change will start at the "current address"; note that the values are separated by spaces. The format character is the same as above. If you use the D modifier, enter values in decimal. If you use the F modifier, enter full word values as in this example:
:B:F40000=000000/40100Display all the registers. This command will accept the 'D' or 'A' format characters before the Ctl-R.
Display one register; <register> is a single character register name (a, b, c, ...) and the command must be followed by a space. This command will accept the 'D' or 'A' format characters.
Change a register; the command must be followed by a space. This command will accept the 'D' or 'A' format characters.
Start execution at <address> if specified, or the current (PC) location if not
Single-step <count> instructions at <address> if given or the current (PC) location if not
Set a breakpoint at <address>; the optional count says to stop on <count> executions of the instruction; you must press return after this command
display the breakpoint table
Range can be a from-to address pair like 40000-42200, or it can be an address/length combination like 24000/255. In the second case, the length is entered in decimal and must be from 1 to 255.
Example dbug session:
>dbug
:B:100000/10=112/000 104/000 115/000 052/000 133/000
100004 112/000 345/000 011/303 172/000 263/100
:B:100000/10 000 000 000 000 000 000
000 303 000 100
:B:BKPT 100004/25
:B:BKPT DSPLY 100004/25
:B:REGP=042200/100000
:B:REGP =100000
:B:GO
-P=100004-
:B:REGP =100004
:B:^D
Are You SURE?
This is the disk test system. The documentation that comes with the package is sufficient to run it with one exception: Unless you are in stand-alone mode with a printer driver already loaded, make sure to load the LP: driver if you want to get a listing during execution.
Caution - Test17 doesn't work at all with the HUG enhanced driver. Use a boot disk with an original HDOS SY: driver to run test17.
As of Release 5 of the emulator, all tests work fine. But the program is, ultimately, pointless. Its use was to test potentially flawed media and to make sure the disk hardware was functioning correctly. In the emulator, both the media and the mechanism are emulated in memory structures. You will have no errors unless something is very, very wrong!
Note to H89 users: Given the lack of audible feedback, these tests won't make sense at all if you don't have the H8 GUI displayed on the screen. Watching the front panel LEDs will give good cues as to what is happening:
Patch is used to make changes to .abs (binary executable) files. The general flow is as follows:
If you want to quit without changing the file, type Ctl-C. You'll be taken back to the file-name prompt; the file you were patching won't be saved.
Heath-provided software has a patch history sector appended to the .abs file. When this sector is present, you must enter additional information, the patch id, prerequisite code and check code, to patch that program. This information is provided with the patch instructions. See the example below.
It's possible to patch Heath-provided software without this extra information. It involves making a copy of the .abs file but not including the patch history sector (e.g., copy all but the last sector of the file). Then patch won't know it's Heath provided and will allow patching.
The three supported physical HDOS disk units are numbered 0, 1, and 2. They are normally assigned logical numbers that are the same as the physical numbers; hence they are referred to as SY0:, SY1: and SY2:. You normally boot from physical drive 0, and the logical and physical unit numbers are the same.
Boot is a small program that allows you to cause the system to boot from a different physical drive than drive 0. The drive you boot from using Boot is now logical sy0: and the remaining drives are renumbered accordingly.
We'll use an example to illustrate how this works. This is a normal boot and mount of two other disks. The disk on SY1: has been sysgened.
Now, leaving the three disks in their current physical drives, we're going to reboot the system from logical and physical drive #1:
As you can see by pairing up the volume numbers and names in the first and second boot, the physical and logical drive numbers now align as follows:
Physical drive #0 is now logical drive SY2:
Physical drive #1 is now logical drive SY0:
Physical drive #2 is now logical
drive SY1:
In other words, the logical numbers start with zero at the physical boot drive and are assigned to the remaining units in a round-robin fashion.
These drive assignments will stay in effect until the system is reset or the boot program is used to reassign the drives. Let's fix it with boot. Note that we have to name logical drive SY2: in the command; this is both the disk we want to boot from, and it's the one in physical drive #0.
Now:
Physical drive #0 is now logical drive SY0:
Physical drive #1 is now logical drive SY1:
Physical drive #2 is now logical
drive SY2:
... which is the normal drive arrangement.
What's going on under the covers...
This behavior is controlled by a System Unit Number (M.SUNI) byte which is at offset 021Q from the start of the System Data Table. The address of the System Data Table is stored in S.DLINK (40.346A). Normally, M.SUNI contains 000Q, which means that physical drive #0 is the system drive, which is given the logical name SY0:.
When you enter " boot sy1:", the disks are dismounted and M.SUNI is changed to 001Q, indicating that physical drive #1 is now the system drive and will be given the logical name SY0:.
HDOS maintains a table of disk-unit information which has three entries stored in physical-unit order. When HDOS needs to access that information starting from a logical drive number, it maps the logical drive to the physical drive number along the lines of the following example, courtesy of S. Webb, which can be found in the Drive Configuration (DC) program on the HUG replacement driver disk, which is available on the project web site.
S.DLINK EQU 40346A(Example simplied slightly for illustration purposes.)
Assume that we enter this code having booted from physical drive #1 and we want to find logical drive SY2:. Register (B) would have the value of 002Q at the top of this routine.
After the first four lines of code, register (L) contains 001Q, the physical boot drive. MNU is the maximum number of units, or 003Q, which ends up in register (L).
Logical drive 002Q + boot physical drive 001Q = 003Q, minus a MNU of 003Q, gives us physical unit 000Q, which is where we would expect to find logical drive SY2:. The code takes the JNC jump and we compute the unit table offset for physical drive #0.