Binary Programs
Binary Programs are special programs consisting of pure object code. Binary programs are generally used as extensions to the BASIC interpreter, i.e. they implement one or more new BASIC statements. Actually, binary programs are simply machine language programs which were normally written in assembler and which can be used for any purpose, either as complete, self-contained program or as extension to the BASIC command set.

The approach how binary programs are used with BASIC program was different to the standard way how it was normally done in other BASIC dialects. One of the differences was, that HP9845 BASIC was quite well protected against any kind of machine address reference, including direct jumps to arbitrary machine addresses. Instead, HP provided means to load object code modules into memory and to add those routines together with the associated keywords to the BASIC instructions set which was already provided by the 9845 LPU firmware.
For a calling BASIC program, there was no difference whether the routine belonging to a special keyword was implemented permanently in ROM or temporarily loaded into R/W memory. Probably, the HP way was a bit more sophisticated and secure than the standard approach with the SYS and USR statements, since the ROM BASIC could be extended with real new instructions and it was'nt too easy to freeze the system accidentally through a jump to the wrong address. On the other side, through the complete abandonment of standard BASIC direct access statements like PEEK, POKE, ADR, SYS and USR, any access from within BASIC to the system resources was completely blocked.
Binary programs can also be used to implement complete applications. The TBIN system test binary is such an example, it works just like any other program, with the difference that it is completely in machine code. The functions provided by this program are driven my menus and keyboard short-cuts.
Binary programs had to meet some rules. The first rule was that it was not possible to specify a certain memory location where the object code should be installed. As a consequence, the object code module had to be designed with fully relocatable code. Another speciality was that each binary module had to have a defined header which holds information about the keyword(s) with which each module routine was invoked, the version information of the module, and the way how the statements can be syntaxed, listed and executed inside a BASIC program.
Binary modules could be saved and loaded in different ways, either alone (with the LOAD BIN command) or in combination with a BASIC program (see the Software Architecture section for more information about the the usage and structure of binary routines). All binary programs could include a special routine which was automatically executed after loading.
Since binary programs could be used to extend the set of statements which was implemented in firmware, it was the ideal way to implement some special functionality which couldn't be performed in BASIC. This includes even low level functionality, which is intentionally not provided by the normal BASIC implementation. One of the most useful example is the PHYREC binary program, which added the PHYREAD and the PHYWRITE statements, through which a direct sector access for any mass storage device was available. Other binary programs provided means to read standard SIF tapes or to access, test and diagnose selected memory areas. Because they - for certain applications - added very useful functionality to the standard BASIC, they are generally still of high interest. The funny side is, that usage in BASIC programs was intentionally protected in many cases, in order to hide both purpose and usage for the normal user.
Special importance is due to the TBIN test binary program. This program was generally used by the service personnel in combination with the 09845-65520 Test ROM cartridge. It provides a number of highly useful diagnostics for exercising the different functional areas of a 9845 system and for the identification and isolation of defects.
Below are the binary programs which are known to me. Most accept parameters.
| Binary Program | Package | ID String | Keywords | Short Description | D/L |
| PHYREC | Utilities II | PHYREC REV B | PHYREAD |
The PHYREC program is included in the Utilities II package and is used by programs for file copy or backup operations | |
| ONKBD | Utilities II, Terminal Manager |
ONKBD REV B 03-27-79 | ON KBD GOTO |
Allows the use of ON KBD statements in subprograms or functions | |
| GPRINT | Utility Library, 2D Graphics Utilities |
GPRINT REV. A 4/26/79 | GPRINT GERASE GCURSOR |
Print alpha characters on the graphics display | |
| DGRAPH | Utility Library | DUMP GRAPHICS # REV.A 4/9/79 | DUMP GRAPHICS | Dump CRT display to a raster scan device (e.g. 2631G printer) | |
| KGPRIN | Utility Library | KGPRINT REV. A 8/06/79 | KGPRIN GERASE GCURSOR |
Print katakana alpha characters on the graphics display | |
| LDK45A | Utility Library | LDK45A | LOAD KEY 9845A | 9845A to 9845B key file conversion | |
| SHOWBN | Utility Library | SHOWBIN REV. A | SHOWBIN | List all currently loaded binary modules which contain header identification | |
| SIF | Utility Library, HP 85 Data Utilities |
SIF REV. A 11/26/79 | INTERCHANGE IS FINDFILE MARK SPRINT SPRINTFILE PDELIMITER IS CHECKREAD CHECKREADOFF SREAD SREADFILE RDELIMITER IS IDENTIFY |
Provides full access to SIF tapes. See Utility Libraray Manual for usage. | |
| AJECT | HPL to BASIC Translator | TREAD 781016 | TREAD | ? | |
| MEMTST | 9845B/C Exerciser Tape #1 | EXERBIN45B/C REV. A 10/25/79 | self starting/ menu driven | Memory exerciser | |
| RCKSUM | 9845B/C Exerciser Tape #2 (ROMREV) | RCKSUM_DIAG REV. A 6/30/80 | RCKSUM | Checksum calculation for ROM diagnostics | |
| CIARC | 2D Graphics Utilities, 3D Graphics Utilities |
ARC-CIRCLE REV. B 5/15/79 | CURVE | Fast circle and arc generator | |
| DMPG | 2D Graphics Utilities, 3D Graphics Utilities |
DUMP GRAPHICS | DUMP GRAPHICS | Dump CRT on a dot matrix printer | |
| RUBBND | 9845C Graphics Utilities | RUBBERBAND REV.A 04/21/80 | RB ON RB OFF |
Rubber band software emulation for 9845C | |
| 79XX | 9845B/C Exerciser Tape #1 (7906A) | 79xx_DIAG REV. C 10/23/79 | SD, STS, POP, HCLR, SK, AR, RC, CL, VF, SM, RDA, WRTD, WFS, INITD, REDD, RFS, RWO, IDY, DSJ, FYSPD, WRTLP, REDLP, DWPL, DRPL, PWPL, PRPL | 790x Diagnostics | |
| DEVSTA | 9845B/C Exerciser Tape #1 (AUTOST, 9134A) | DEVICE_STATUS REV. A 9/26/79 | DSTS <sc>, <ret_status> | Return device status for device <sc> | |
| ODESSY | 9845B/C Exerciser Tape #1 (CLRGR) | ODESSY_GRAPHICS REV. A 9/26/79 | OTEST <ret_memoryplane>, <ret_resultpattern>, <ret_expectpattern> | 98770A color graphics memory exerciser. Returns <ret_memoryplane> = 0 if no error, or faulty memory plane plus both expected and returned pattern. | |
| WTMEMB | 9845B/C Exerciser Tape #1 (ENHGR) | WTMEMB | WRITE MEMORY <block>:<address>, <value> Functions: |
Memory read/write and base conversion utility. WRITE MEMORY and MEMORY can be used on any <block>:<address> combination, or, if 4 ≤ address ≤ 7, as <select_code>:<register> combination. DTO$, DTB$ and DTH$ return a number in octal, binary or hexadecimal notation. OCT converts an octal number into a decimal number. | |
| FTBIN | 9845B/C Exerciser Tape #1 (ENHGR) | FAST TRANSFER BINARY | TRANSFER [<from_block>:]<from_address> TO [<to_block>:]<to_address>, <size> COMPARE <from> TO <to>, <size>, <ret_errorflag> FAST SUM [<block>:]<address>, <size>, <checksum> CHECK SUM [<block>:]<address>, <size>, <checksum> |
Memory block utility. TRANSFER moves between memory locations and/or arbitrary objects such as integer arrays. COMPARE returns -1 in case both blocks compare in ret_errorflag. FAST SUM does a simple sum on the selected memory area modulo 32768, and CHECK SUM calculates a validation sum like it is used to validate (not identify) 9845 ROMs. | |
| TBIN | 9845B/C Test Binary | n/a | self starting/ menu driven | Service test binary for in-depth 9845 diagnostics. Lock the AUTOST key to run the rack test automatically after loading. |
The above binary programs can be downloaded here as complete archive, including a disc image with all binaries: 9845-Binaries-081230.zip
Handling Binary Programs
All binary program files follow a certain structure with file header, file trailer, a linked list of keywords plus some extra code & data for tables and execution. Binary programs can be either stored in special files of type BPRG or packed together with BASIC program files of type PROG. So if a BASIC program requires certain binary programs to be present, it is good practice to pack these binary programs together with the BASIC code into one single file of type PROG. This is automatically done with each STORE command (i.e. the binaries which are currently loaded into RAM are automatically stored together the the current BASIC program into one single file). Note that storing binary programs together with BASIC code is possible with the STORE command only, not with the SAVE command.
The way back, i.e. separating binary programs from the BASIC code, requires three steps. First the PROG file containing both binary programs and BASIC code has to be loaded with LOAD. Then, the binary programs can be stored separately with the STORE BIN command, and the BASIC program can be stored without binaries using SAVE.
For handling programs of type PROG and BPRG on a PC I wrote a special utility named 'Progalyze'. It can be used to detect binary programs included in PROG files, to extract those binary modules, to get detailed internal information on the PROG files, and even to perform operations on the PROG file like removing line protection. See the 9845 Utilities Section for more information on how to use this utility.
Creating Binary Programs
Writing your own binary programs is a bit tricky, especially when passing parameters from and back to BASIC. Below is a basic understanding of the header structure. The object code part can be produced with the asm45 assembler program. Note that the object code has to be fully relocatable and that each BPRG file starts with an additional size word over all binary routines which are stored in the file. All pointers will be updated automatically when the binary program is installed (i.e. with the LOAD BIN command).
Here is the structure of a binary program (all offsets in words):
Size: Size of all modules in words (file only)
Start: Pointer to Id_info (revision ID)
Start+1: Module size in words (reserved memory space)
Start+2: Pointer to 1st keyword
Start+3: Pointer to next binary module (normally pointer to -1 for last module)
Start+4: On load execution address (normally RET 1 (=$F081))
Start+5: RET 1 (=$F081)
Start+6: RET 1 (=$F081)
Start+7: =$0
Start+8: * (reference to this address in memory, used to re-calculate all other pointers)
Start+9: flags (?)
Start+10: # of aux pointers (?)
Start+11: Aux pointer #1
Start+12: Aux pointer #2
...Id_info: Revision ID string (max. 32 characters, terminated with $80, word align padding with $0)
Keyword: Pointer to next Keyword or to -1 for last keyword
Keyword+1: Keyword string (n*2 characters, word align padding with $20)
Keyword+n: Instruction flags with MSB set (upper byte) & offset from Keyword to Execution (lower byte)
Keyword+n+1: JMP to Syntax (syntax routine)
Keyword+n+2: JMP to List (list routine) or RET 1 for no parametersExecution: Execution code, terminates with RET 2 in case of success or with RET 1 for error
Syntax: Syntax routine
List: List routine (or RET 1 for no parameters)
Binary program files are terminated a trailing word holding the size of the whole binary, plus some record boundary fillers. Since binary programs can only be installed via the LOAD BIN command, first the object code is to be produced (e.g. with the asm45 utility), then the header/trailer structure and all pointers have to be added. Finally the module can be saved to disc as a file of type BPRG.
For parameter syntax checking, parameter listing and parameter data reference the OS provides a couple of utility routines, however I've not yet figured out how it works in detail. Of course, all utility routines used by the BASIC interpreter (e.g. for CRT output or keyboard input) can be used from within a binary program, too.