Building a HP-IPL/OS system using real hardware

The procedure for building a HP-IPL/OS system on real hardware is similar to using the simulator, but sometimes the challenges can be great, both hardware and PC software. First thing that's needed is a way to load streams attached to specified files, often many packages are needed so it should be easy to select which file to send. The simple PTR emulator design included here is a possibility, this is a PIC-based circuit with pins connected to 10 lines of a parallel interface in the HP (8 data lines plus control and flag), with 2 more lines connected to a serial port. When the HP asserts the control line the firmware sends a "!" character to which the PC responds by sending the next byte of the file, which the firmware copies to the data bits and sets the flag line and waits for the next control pulse, thus providing handshaking for the transfer. PC software such as HpLoader (Windows) or the HPSEND (pure dos) program is used to transfer the file, and therein lies some of the biggest problems when trying to use real hardware - PC's!

Problem #1 - modern OS's seem to be anti-hobby-programming, forcing one to use mindnumbingly complicated programming techniques to accomplish trivial things and they seem to make sure that things that were once simple are no longer supported. HpLoader is fairly easy to get running but Windows will probably compain at first about a library not being "registered" as the program has to use an alternate comm driver to get around a stupid licensing limitation. The much simpler HPSEND program can't be run under Windows at all, has to either be run from a dos boot disk or from Linux using DosEmu/FreeDos, which must be set up to be able to access the serial port and can only access files within its file tree. Need a native Linux version - done - wrote it in IPL running under simulation, easier than fighting modern languages, fortunately SimH has no problem attaching PTR and PTP to /dev/ttyS0, the hardest part was figuring out the right stty command to tell the TTY driver it's binary and to stay out of the way, but once that was done it booted right up. Problem solved here.

Problem #2 - having to use a single serial port. This one is a bit easier to solve, just need something to provide time to swap the cable before starting the load. Simple solution - make a time-delay word such as...

? OCTAL DEFINE CSDELAY
> #0 7 +DO #0 77777 +DO +LOOP +LOOP END

...then enter CSDELAY <PTR, close the serial terminal emulator, swap cables, start the transfer using the sender app (whatever that might be), when the lights stop blinking disconnect the sender, swap cables, start the terminal emulator, press enter for the prompt. Of course this solution makes you have to play beat-the-clock.

A better solution would be a HLT word so I can take my time. Normally when CREATE is loaded this is trivial to make, but when starting from the bare kernel it's a bit trickier. Need a word that executes HLT 7 (102007) then JMP 321,I (124321). Have to use low-level facilities to make it (using information from summary.txt), under simulation to test it looks like...

? "HLT" ADDHEADER$ ;THIS CREATES A WORD HEADER
? @DIPTR GET PNUM ;DISPLAY DICTIONARY POINTER
011545
? 11546 ADDCODE ;ADD *+1 ADDRESS TO INDICATE CODE TO RUN
? 102007 ADDCODE ;ADD HLT 7 INSTRUCTION
? 124321 ADDCODE ;ADD JMP 321,I INSTRUCTION
? FIXLINKS ;FIX DICTIONARY TO COMPLETE THE WORD
? WORDS
DO +DO INDEx +LOOx >STEx IFNZ IFZ IF<0 ENDIx ELSE UNTIx WHILx CASE = < > <=
>= <> DEFAxxx ENDCxxx EXECxxx WBOOx AND OR XOR ADD SUB INC DEC NOT 2CPL DUP
DROP OVER ROT SWAP GET PUT PNUM CRLF DECIxxx OCTAx BINAxx RADIx SP>S SB>S
XP>S XB>S YP>S YB>S ZP>S ZB>S END EOD DEFIxx DMPS S>SR SR>S PCHR PWRD CHRIx
S>X X>S S>Y Y>S S>Z Z>S MUL ASL ASR ROL ROR DIV RUN X>>Y X>>Z Y>>X Z>>X
$PRIxx $SWAx $CPY $DUP $DROx $LEN $ADR $XTExx $PUT $GET $CRExxx $STR $HEAx
$APPxxx $TAIx $IN $CAT $VAL <>COx >PTP <PTR MSPAxxx MSBOxx MSBIx MSWOxx
MSWIx MS$Oxx MS$Ix MSCRxx >MS <MS MS_Sxxx MS_Rxxxxxx CONSxxx #0 #1 @TL @TB1
@TB2 @ANVxx @ENSxx @CLH @LITxxxx @STRxxx @RTSxx @DIC @USR @BLK @END @DIPxx
RND TOKEx SDIC +IRQ -IRQ +AUTx -AUTx INBLxxx OUTBxxxx GETIx SETIx GETOx
SETOx $DEFxxx HEADxxx WORDx ADDCxxx ADDHxxxxx ADDHxxxxxx FIXLxxxx ADDMxxxx
VARIxxxx CONSxxxx ALLOxxxx ZEROxxxxx BPUT BGET HLT
EOD=011550 FREE=002227
? HLT "OK" $PRINT

HALT instruction 102007, P: 11547 (JMP 321,I)
sim>c
OK
?

...that'll work. Can be reduced to the following sequence...

? "HLT" ADDHEADER$ @DIPTR GET INC ADDCODE
? 102007 ADDCODE 124321 ADDCODE FIXLINKS

Not much harder to type than the delay word but lots easier to use, to load a package enter HLT <PTR, exit the terminal, swap cables, start the transfer program and ready the file, press the run switch, when the lights stop blinking exit the transfer program, swap cables, start the terminal then press enter to restore the prompt.

Problem #3 - I have no PTP emulator. Once the build is made the usual way of punching (SYSALL etc) isn't available, instead the build will have to be dumped as text using CONGEN from the congen.ipl package, the text can be captured by the terminal emulator into a file. At 2400 baud it's slow process but it works. The simulator is still needed though to turn the dump file into an ABS binary, run the hposutil.abs build which contains L2ABS (from log2abs.ipl), halt, attach ptr to the dump file, attach ptp to the build.abs file, continue, and enter L2ABS to translate the encoded text into a binary. This problem isn't much of a problem, it only takes a few minutes to dump and save the system, then very little time to convert the text to an ABS file using the hposutil.abs build running under simulation (I use the scripts in the scripts directory so that I can click on .abs and .sim files and they run). It is not a problem at all for someone who has a punch emulator, however in my case I also need to easily transfer the output to my PC so it can be filed, documented, reloaded, etc.

Another option for my use is to use VDOS to save the system to a USB thumbdrive, the core VDOS package (without the extra utilities) only needs about 1/2 KW memory and can be used on systems with as little as 16KW (possibly less but requires CREATE which is fairly large), but this approach requires custom hardware and carries the VDOS words as dead weight if targeting a more general application, so it is not a universal solution. One approach to using the USB interface without having to include extra words in the dictionary might be to construct an "attacher/detacher" utility that sits up high, it could be manually run from HP-IPL/OS and used to attach the MS vectors to specific file(s), then upon returning to HP-IPL/OS the usual SYSALL etc used to save the system. Care would have to be taken with such a system since with my present hardware setup the file must be closed afterwards or the last part of the write will be lost, unless targeting general systems it's easier just to load vdos.ipl and be done with it. For my own purposes, CONGEN is a suitable solution for saving builds I make on my machine that don't contain a dos, otherwise I just use the dos. As far as making builds for other purposes I almost always use the simulation anyway (the builds included with HP-IPL/OS are all built using simulator scripts that attach the packages one by one and tell me what to type, greatly speeding up the process and practically eliminating errors) - solutions like CONGEN and VDOS are for when I'm running my real machine and I make something I want to save.

With the lack-of-hardware problems adequately solved, I can make HP-IPL/OS builds from scratch on my machine.


HP-IPL/OS From Scratch

The procedure documented here was performed on May 18, 2010 using the following hardware...

HP2113 E-series CPU with slots assigned TTY=11, PTR=12
PC with a terminal emulator, a HP transfer program, and a single serial port
pass-through papertape reader emulator on slot 12
VDRIVE interface on slot 23 (optional, part of my existing IDE/USB interface)

This example shows the making of a simple 32KW build with notes describing the changes to make a 16KW build for non-extended machines. The DMS and VDOS additions require at least 64KW. Note... this was performed using version 1.54 packages, the WORDS listing and amount of free memory will vary somewhat with newer versions but the procedure remains the same. The load order has been tested using the version 1.60 packages, comments edited to account for new features, in particular no more crash effects if the dictionary overflows, and the new ERASE word which can remove a failed load.

The package list for the build is...

hpiplos1.abs - the kernel
a manually created HLT word
extra2.ipl - smaller version of the extra words
create.ipl - the assembler (use smallcre.ipl for 16KW or non-extended)
version.ipl - to change the signon string
double.ipl - double-word math package (use double2.ipl for 16KW or non-extended)
congen.ipl - used to dump a build to the console to save
a custom replacement for the CONGEN word
a custom SYSGEN or SYSALL word
screen.ipl - ANSI terminal words
mkword.ipl - used to create packaged words

This provides a fairly complete IPL environment with over 7000 octal words (3.5KW) free in the dictionary for a 16KW configuration with 1KW high memory for custom machine code. When configured for 32KW+ machines using the usual 4KW high mem there's over 35000 octal words free (14.5W), ready for adding dms altutil altenc and other packages for using bank-switched memory. Even with a 16KW non-extended configuration there's plenty of room for VDOS to make a simple USB-based disk system, with a 64KW DMS system VDOS can load binaries and return to the system, still with more than 10KW free (figures like this could only impress an old computer fan used to free memory often being less than a few kilobytes...). What the system doesn't have... no interrupts or TBG, no BACI or HP drivers, no CONFIG (can change zero-page to configure), and several words including MARKCON ERASE HIDEDUPS DELETE and UNDELETE were removed. HP-IPL/OS on a diet.

For a 64KW DMS VDOS build add...
dms.ipl - alternate memory access words
altutil.ipl - alternate memory utility words
vdos.ipl - core VDRIVE words
vdosext.ipl - extra VDRIVE words including VLOAD for loading and running binaries

First step... fire up the machine and load the kernel.
Power up, connect serial cable to the PTR emulator, select hpiplos1.abs in the sending app, select S register, set to 001200 and store, press Preset, IBL, Preset, Run... sending app responds and starts printing its progress bar, when loaded bits 0-5 light up. Exit sending app, swap serial cable to the console, run terminal emulator set to 2400 baud 7n2, select P register, Clear display, set bit 1 for address 2, Store, Preset, Run. HP-IPL/OS is running.

Type in the HLT word for cable-swapping...

HP-IPL/OS  8K   V1.5
? "HLT" ADDHEADER$ @DIPTR GET INC ADDCODE
? 102007 ADDCODE 124321 ADDCODE FIXLINKS
?

Enter HLT <PTR, exit the terminal emulator, swap the cable to the PTR emu, select extra2.ipl in the sending app, press Run. When the progress bar stops, exit sending app, swap cable to console, run terminal emu, press enter for prompt.

Configure for 32KW with 3 blocks and 4KW high memory, enter: @END 67777 PUT 3 ALLOCATE

If making a 16KW build with 2 blocks and 1KW high memory, enter: @END 35777 PUT 2 ALLOCATE
For a 16KW build with 2KW high mem to use Octapus from oct34.ipl, enter: @END 33777 PUT 2 ALLOCATE

Repeat loading for create.ipl, version.ipl, double.ipl and congen.ipl (LOAD is loaded now so HLT LOAD can be used). For non-DMS 32KW or 16KW systems use the non-extended versions, smallcre.ipl instead of create.ipl, and double2.ipl instead of double.ipl. Make sure plenty of time is given for CREATE to process which causes pauses in the loads. If after returning to the terminal and finding it unresponsive, press halt, set P to 2, store, preset, run, enter WORDS to check it out. Error messages are not visible when loading with a single port but WORDS appears to show only part of a package (check the IPL file to know what it's supposed to load) then some kind of error occured such as a dependency issue or a page error. Remove the partial load (version 1.6's extra package has a ERASE for this), sort it out and try again. Needless to say operation with only a single serial port and no way to see error messages isn't an ideal situation.

CONGEN assumes Octapus is present, but this particular build has no Octapus so to make it more efficient need to replace the CONGEN word that checks to see if there is anything in hi mem to save. The Octapus package normally provides SYSALL for punching builds, so need a custom SYSALL word too. Entering...

? FORGET CONGEN
Forget CONGxx and everything after it? Y
Done
? DEFINE CONGEN
> "----START----" $PRINT CRLF
> 2 EOD CONOUT
> 70000 GET IFNZ 70000 73777 CONOUT ENDIF
> 74000 GET IFNZ 74000 77677 CONOUT ENDIF
> CRLF "----END----" $PRINT CRLF END
? DEFINE SYSALL
> "SAVING..." $PRINT PTZERO
> 2000 DO DUP DUP 1777 ADD DUP EOD SUB IF<0 ABSOUT 2000 ADD #0 ELSE
> DROP EOD ABSOUT DROP #1 ENDIF 56 PCHR UNTIL 2 1777 ABSOUT 56 PCHR
> 70000 GET IFNZ 70000 71777 ABSOUT 53 PCHR 72000 73777 ABSOUT 53 PCHR ENDIF
> 74000 GET IFNZ 74000 75777 ABSOUT 53 PCHR 76000 77767 ABSOUT 53 PCHR ENDIF
> PTZERO " DONE " $PRINT END
?

For 16KW builds these need to be customized to match where high memory was placed. Instead of fixed locations, perhaps use something like these that detect where highmem starts at by looking at the @END variable...

OCTAL DEFINE CONGEN ;for 16KW build
"----START----" $PRINT CRLF
2 EOD CONOUT
@END GET INC DUP GET IFZ DROP ELSE 37677 CONOUT ENDIF
CRLF "----END----" $PRINT CRLF END

OCTAL DEFINE SYSALL ;for 16KW build (not needed if oct34.ipl loaded)
"SAVING..." $PRINT PTZERO
2000 DO DUP DUP 1777 ADD DUP EOD SUB IF<0 ABSOUT 2000 ADD #0 ELSE
DROP EOD ABSOUT DROP #1 ENDIF 56 PCHR UNTIL 2 1777 ABSOUT 56 PCHR
@END GET INC DUP GET IFZ DROP ELSE 37677 ABSOUT 53 PCHR ENDIF
PTZERO " DONE " $PRINT END

Next to load screen.ipl and mkword.ipl, this completes the base build...

? WORDS
DO +DO INDEx +LOOx >STEx IFNZ IFZ IF<0 ENDIx ELSE UNTIx WHILx CASE = < > <=
>= <> DEFAxxx ENDCxxx EXECxxx WBOOx AND OR XOR ADD SUB INC DEC NOT 2CPL DUP
DROP OVER ROT SWAP GET PUT PNUM CRLF DECIxxx OCTAx BINAxx RADIx SP>S SB>S
XP>S XB>S YP>S YB>S ZP>S ZB>S END EOD DEFIxx DMPS S>SR SR>S PCHR PWRD CHRIx
S>X X>S S>Y Y>S S>Z Z>S MUL ASL ASR ROL ROR DIV RUN X>>Y X>>Z Y>>X Z>>X
$PRIxx $SWAx $CPY $DUP $DROx $LEN $ADR $XTExx $PUT $GET $CRExxx $STR $HEAx
$APPxxx $TAIx $IN $CAT $VAL <>COx >PTP <PTR MSPAxxx MSBOxx MSBIx MSWOxx
MSWIx MS$Oxx MS$Ix MSCRxx >MS <MS MS_Sxxx MS_Rxxxxxx CONSxxx #0 #1 @TL @TB1
@TB2 @ANVxx @ENSxx @CLH @LITxxxx @STRxxx @RTSxx @DIC @USR @BLK @END @DIPxx
RND TOKEx SDIC +IRQ -IRQ +AUTx -AUTx INBLxxx OUTBxxxx GETIx SETIx GETOx
SETOx $DEFxxx HEADxxx WORDx ADDCxxx ADDHxxxxx ADDHxxxxxx FIXLxxxx ADDMxxxx
VARIxxxx CONSxxxx ALLOxxxx ZEROxxxxx BPUT BGET HLT $EQUxx $SLIxx $TRIx
ABSOxx PTZExx DUMP PDEF EXPLxxx FORGxx FETCx STASx RENAxx WHERxxx LOAD
CREAxx PRESxx VERSxxx DADD D2CPx EMUL EDIV DSWAx $DVAx $DSTx CONOxx CONGxx
SYSAxx ESC POS CLS COLOx -COLxx MKWOxx ENDWxxx
EOD=024106 FREE=035671

Enter VERSION and give it a name (in this case I called it HP-IPL/OS 32K 1.54), enter CONGEN to save to the console as encoded text which is then dumped to a file. I'm using dterm in a konsole terminal with a very big buffer, so just have to save the session, copy the encoded output to a file making sure it has CRLF line ends (using the scite editor), and use the hposutil.abs build under simulation to make an ABS binary...

HP-IPL/OS UTIL 1.54
? ;USE L2ABS TO CONVERT LOG INTO ABS FILE
?
Simulation stopped, P: 02225 (SFS 11)
sim>attach -e ptr 32klog.txt
sim>attach ptp hpos32k.abs
PTP: creating new file
sim>c
L2ABS
Processing 000002 to 024106
....................

?
Simulation stopped, P: 02225 (SFS 11)
sim>detach ptp

Then launch the new build and test SYSALL to make sure it works...

HP-IPL/OS 32K 1.54
? ;REPUNCH BINARY USING SELF
?
Simulation stopped, P: 02226 (JMP 2225)
sim>! rm hpos32k.abs
sim>attach ptp hpos32k.abs
PTP: creating new file
sim>c
SYSALL
SAVING.............. DONE
?
Simulation stopped, P: 02226 (JMP 2225)
sim>detach ptp

Resulting binary works OK. The way this SYSALL (and CONGEN) works is it saves 70000-73777 if location 70000 is non-zero, and 74000-77677 if location 74000 is non-zero. After loading Octapus from oct70.ipl and FORGET SYSALL to remove the version that comes in Octapus, SYSALL then saves Octapus too but in that case a custom SYSALL is not needed unless putting more code at 74000 that also needs saving.

Moving on to make a DMS/VDOS build... add dms.ipl, altutil.ipl, vdos.ipl and vdosext.ipl (the NOT FOUND error is normal, no disk words so the usb/disk copy stuff isn't defined), enter 23 SLOT to patch it to my interface in slot 23 - of course this is for my machine, with the VDRIVE interface implemented as part of the IDE disk interface but entirely different interface implementations are possible, including using the PTR interface and doubling as a PTR emulator - VDOS firmware commands all have high bits set so should be no conflict with 8 bit data.

Enter VERSION, press Y to confirm, enter HPOS DMS/VDOS 1.54 [or whatever the present version is], enter CONGEN to save it before testing. Here's the dictionary...

? WORDS
DO +DO INDEx +LOOx >STEx IFNZ IFZ IF<0 ENDIx ELSE UNTIx WHILx CASE = < > <=
>= <> DEFAxxx ENDCxxx EXECxxx WBOOx AND OR XOR ADD SUB INC DEC NOT 2CPL DUP
DROP OVER ROT SWAP GET PUT PNUM CRLF DECIxxx OCTAx BINAxx RADIx SP>S SB>S
XP>S XB>S YP>S YB>S ZP>S ZB>S END EOD DEFIxx DMPS S>SR SR>S PCHR PWRD CHRIx
S>X X>S S>Y Y>S S>Z Z>S MUL ASL ASR ROL ROR DIV RUN X>>Y X>>Z Y>>X Z>>X
$PRIxx $SWAx $CPY $DUP $DROx $LEN $ADR $XTExx $PUT $GET $CRExxx $STR $HEAx
$APPxxx $TAIx $IN $CAT $VAL <>COx >PTP <PTR MSPAxxx MSBOxx MSBIx MSWOxx
MSWIx MS$Oxx MS$Ix MSCRxx >MS <MS MS_Sxxx MS_Rxxxxxx CONSxxx #0 #1 @TL @TB1
@TB2 @ANVxx @ENSxx @CLH @LITxxxx @STRxxx @RTSxx @DIC @USR @BLK @END @DIPxx
RND TOKEx SDIC +IRQ -IRQ +AUTx -AUTx INBLxxx OUTBxxxx GETIx SETIx GETOx
SETOx $DEFxxx HEADxxx WORDx ADDCxxx ADDHxxxxx ADDHxxxxxx FIXLxxxx ADDMxxxx
VARIxxxx CONSxxxx ALLOxxxx ZEROxxxxx BPUT BGET HLT $EQUxx $SLIxx $TRIx
ABSOxx PTZExx DUMP PDEF EXPLxxx FORGxx FETCx STASx RENAxx WHERxxx LOAD
CREAxx PRESxx VERSxxx DADD D2CPx EMUL EDIV DSWAx $DVAx $DSTx CONOxx CONGxx
SYSAxx ESC POS CLS COLOx -COLxx MKWOxx ENDWxxx !DMS -DMS SDMA UDMA UJUMx
SJUMx SPAGx C>ACxxx A>CCxxx USPAxx DMSTxxxx UPTR MSUSxx ABSLxxx GOUSxx
GOSYxxxx ALTSxxx ?DMS ZAM ALTRxx RUNAxx PTHExxxx AAOUx ALTAxx ALTDxxx
CLRHxxx ALTHxxx VDOS VSYNx VCLExx <VDR >VDR &SIW &ORF &OWF &WFVxx @GSB @SSB
&UCLxxx USBSxxx @PVLx PVDR $>VDx $>VCxx VECS VPROxxx VDIR VCD VSHOx VDEL
USBRxxx USBAxxxxx USBWxxxx USBCxxxx VOWCxxxx VLOAx VSAVx VCOPx VREAx VWRIxx
VCLOxx UFSIxx
EOD=032464 FREE=027313

From this point on I shouldn't have to swap cables to use the PTR emulator, but load files directly from a USB thumbdrive. Took a bit of coaxing, can't remember how my own firmware switches work (there are docs somewhere:-) but it works... VDIR displays a directory, "VDOSDMS1.ABS" VSAVE saved the build, "HPIPLOS" VCD then "IPL" VCD then "MAZE.IPL" VLOAD loaded in the maze game...

? "MAZE" VLOAD
USB Error = 000002
? "MAZE.IPL" VLOAD
(loading from sub 030434)
Loading MAZE...
Defining RND
Declaring Variables
Defining XY_TO_ROOM
Defining CONNECT_ROOM
Defining RANDOMIZE_ROOMS
Defining ROOM_TO_XY
Defining GO_IF_VALID
Defining M_RADAR
Defining TAKE_HITS
Defining MOVE_MONSTER
Defining LOOK_AROUND
Defining INIT_MAZE
Defining MAZE_HELP
Defining MAZE_BODY
Done
? MAZE

*** MAZE *** 11/07/02
Select 1)Easy 2)Medium 3)Difficult: 1
Creating World...
Welcome to the maze. Commands...
N S E W move north, south, east or west
F P T take food or protection, use transport
L B Q M R ? look, battle, quit, map, reset, help
You are at X: 1 Y: 1
Passages lead: South East
Strength: 50 Protection: 0
There is a transporter here
Command: M
*--F--T--. .--P-- M
`--' `--P--T--:-----:
M .--P--F--.--: M--M
:--'--: :--F : T--
M--F--: F-- M--:--.
:-----: : .--'--: :
:--P--M--P--F-----F--F
`-----'--'--'-----'--M
Command:

The VDRIVE is a fairly primitive device, kind of old-comp-style itself. To go back up the directory tree have to change back to the root, from HP-IPL/OS to change to the ABS dir in the tree have to do "/" VCD "HPIPLOS" VCD "ABS" VCD then I'm there...

? "/" VCD "HPIPLOS" VCD "ABS" VCD
? VDIR

. DIR
.. DIR
HPOSMT.ABS
OCT-D.ABS
HPOSDMS.ABS
HPOS7906.ABS
HPOSDEMO.ABS
HPIPLOS1.ABS
HPOS16K.ABS
7906BEXT.ABS
MSUBASIC.ABS
7900BEXT.ABS
BUILDI~1.TXT
HPOSUTIL.ABS
HPOS8K.ABS
D:\>

? "MSUBASIC.ABS" VLOAD
LOADING.....................................
Run from 77000 to return
31KW MSU BASIC

READY
10 PRINT "OH YEA!"
20 END
RUN
OH YEA!

READY
BYE

HPOS DMS/VDOS 1.54
?

That program is still in memory but there aren't any words in place to save. Regular HP-IPL/OS disk files are always allocated 32KW regardless of size and files are saved as straight binary, that would be very inefficient for ABS files so need the fcam.ipl package (fcam = Find Code in Alt Mem). Also unlike XDOS etc, VDOS can load IPL files without disturbing alt mem so FORGET MAZE (still in mem), back to root and change to the IPL dir and "FCAM.IPL" VLOAD (error is normal for disk transfer words, no XDOS), also need MSUPATCH.IPL for patching the startup text and backspace (stock MSU BASIC uses "_" to make corrections). Need to make a new dir for my stuff... what no MKDIR? that's an oversight... bet it's available from the raw prompt...

? VPROMPT
VDRIVE prompt - EXIT to quit
:CD /
D:\>
:MKDIR MYSTUFF
Bad Command
:MKD MYSTUFF
D:\>
:CD MYSTUFF
D:\>
:DIR

. DIR
.. DIR
D:\>
:EXIT

?

Called MKD. First to save the program in alt mem manually...

? "MYBASIC.ABS" VWRITE AM2ABS VCLOSE
Writing USB file MYBASIC.ABS

Scanning alt mem...
Detected extents:
From 000002 to 013562
From 067100 to 067677
From 072500 to 075777
Save as ABS? Y
Halt for attaching/detaching files? N
Saving...
Done.
Closing output buffer
? VDIR

. DIR
.. DIR
MYBASIC.ABS
D:\>

?

VREAD VWRITE and VCLOSE are wrappers for USBREAD USBWRITE and USBCLOSE that print messages, prompt to overwrite etc. FCAM/AM2ABS is a bit too clunky, really need a save that's specific to MSU BASIC that peeks inside to know what to save without having to scan all of alt mem, could do without the prompts too. But that's a project for another day. A make directory command can be made like...

? DEFINE VMKD
> VECS "MKD " $>VDR $>VCMD &WFVDR DROP VCLEAR END

This uses some of the lower-level VDOS words... VECS switches to the extended (human-usable) command set, $>VDR and $>VCMD send strings to the VDRIVE, the latter with a CR, &WFVDR waits for a response and pushes the first byte received, VCLEAR discards the rest of the response. The command to delete a directory is DLD so same idea for a VDLD command. Care must be taken when using the VDRIVE2 module, it's strictly short filenames and doesn't even touch long filename entries, so if used to rename a file written by a PC the filename might not appear to change at all, or worse can end up with multiple files with the same apparent name. More info about this cool gadget is on the Vinculum web site. Also check out my HP Minicomputer Project pages with pictures, games binaries and other stuff that's too big to include here.

Adding other packages

Once familiar with the process, the build procedure can be customized to include BACI, HPIB, TBG or whatever else is needed but you might need to play with the loading order to avoid page errors. If EOD is not too far past a 1KW boundary (within about 600 octal) then all three of these will load without error. With the above build example, baci.ipl, hpib.ipl and tbg.ipl can be loaded after altutil.ipl or vdos.ipl/vdosext.ipl, but can't be immediately loaded after dms.ipl unless a small word is defined to push EOD past the 1KW boundary. If not familiar, 1KW boundaries are at addresses like 24000 32000 34000 36000 etc, if EOD is say 25650 then you need a high-level word that takes up about 150 octal memory - if you don't care about wasted memory do something like VARIABLE ~PAD 150 or however much is needed to push past the boundary.

If a page error does occur, you need to know the name of the first word (or variable/constant) in the package then FORGET that word to remove the entire package. The first word can be determined by doing WORDS before loading a new package (which should always be done anyway unless sure there's enough memory), the next new word in the dictionary is the one to FORGET should an error occur. The new v1.6 kernel automatically records EOD when loading, so in 1.6x builds should an error occur just enter ERASE and confirm to remove the last package loaded. Also, always do WORDS after loading a package to make sure there is still sufficient memory. The 1.6 kernel has protection against dictionary overflow and will halt the load if it exceeds available memory, previous kernels will display a negative EOD value if the load overflowed into block memory.

Packages often require words from other packages, if the dependencies are not already in the dictionary then HP-IPL/OS will stop with a "NOT FOUND" error. FORGET the first word of the errant package (or use ERASE), look at the .ipl file to see what it requires, load the package(s) and try again.

HP-IPL/OS does demand that the builder perform proper ordering and at least some manual memory allocation when building new systems, but in return you get more memory for applications and a faster system that isn't bloated by extra error-checking that can just as easily be done by the builder. It's fairly easy to predict if a machine-coded package will load by doing WORDS, noting the EOD number, and looking at the .ipl file to see how much machine code it contains. It takes a bit of practice but is nowhere near as complex as trying to say resolve dependencies using LOADR in RTE... other vintage HP operating systems also demand that things be loaded in precisely the right order, they might solve page errors by using a relocatable format but this does not help if it can't find a subroutine it needs, quite often the same .rel file has to be loaded multiple times until all the dependencies are met. This kind of stuff makes HP-IPL/OS seem easy by comparison... at least it either works or doesn't instead of waiting until the very end to indicate an error. Not to mention HP-IPL/OS can be made to run on almost any HP21xx mini whereas other vintage OS's often require very specific configurations and cannot be easily adapted if compatible hardware isn't available.

However, this doesn't mean applications should be lax on error checking - to the contrary - trimming things down by not having extra error checking in the kernel permits more room in memory for programming. User applications can be more robust and (as opposed to building) not require special knowledge on the part of the user. It is also possible to write IPL "application" packages that automatically check EOD and define dummy words to avoid page errors, see the fed.ipl package for an example. These kinds of packages are nice when using "run and forget" loading methods from a disk menu or a library file. Run-and-forget apps are packages where the first word name is the same as the package name and also the word that runs the app, so a menu or library command can load it, run it, then remove it from the dictionary after it exits. Typically these apps use MKWORD and ENDWORD (or manual memory manipulation) to make the entire app, subroutines, variables and all, appear as a single word in the dictionary. It is also possible to use $DEFADR to execute words that exist further down in the dictionary to accomplish the same thing. Perhaps the most reliable way to make an application is to build it so that it is a self-contained binary system that doesn't care about dependencies etc, all that is taken care of by the builder so that the user can just run it.


6/4/10 - Original version
7/6/11 - Edited failed load info for v1.6 kernel