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.

Binaries

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
PHYWRITE

The PHYREC program is included in the Utilities II package and is used by programs for file copy or backup operations
Download
ONKBD Utilities II,
Terminal Manager
ONKBD REV B 03-27-79

ON KBD GOTO
ON KBD GOSUB
ON KBD CALL
OFF KBD

Allows the use of ON KBD statements in subprograms or functions
Download
GPRINT Utility Library,
2D Graphics Utilities
GPRINT REV. A 4/26/79 GPRINT
GERASE
GCURSOR
Print alpha characters on the graphics display
Download
DGRAPH Utility Library DUMP GRAPHICS # REV.A 4/9/79 DUMP GRAPHICS Dump CRT display to a raster scan device (e.g. 2631G printer)
Download
KGPRIN Utility Library KGPRINT REV. A 8/06/79 KGPRIN
GERASE
GCURSOR
Print katakana alpha characters on the graphics display
Download
LDK45A Utility Library LDK45A LOAD KEY 9845A 9845A to 9845B key file conversion
Download
SHOWBN Utility Library SHOWBIN REV. A SHOWBIN List all currently loaded binary modules which contain header identification
Download
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.
Download
AJECT HPL to BASIC Translator TREAD 781016 TREAD ?
Download
MEMTST 9845B/C Exerciser Tape #1 EXERBIN45B/C REV. A 10/25/79 self starting/ menu driven Memory exerciser
Download
RCKSUM 9845B/C Exerciser Tape #2 (ROMREV) RCKSUM_DIAG REV. A 6/30/80 RCKSUM Checksum calculation for ROM diagnostics
Download
CIARC 2D Graphics Utilities,
3D Graphics Utilities
ARC-CIRCLE REV. B 5/15/79 CURVE Fast circle and arc generator
Download
DMPG 2D Graphics Utilities,
3D Graphics Utilities
DUMP GRAPHICS DUMP GRAPHICS Dump CRT on a dot matrix printer
Download
RUBBND 9845C Graphics Utilities RUBBERBAND REV.A 04/21/80 RB ON
RB OFF
Rubber band software emulation for 9845C
Download
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
Download
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>
Download
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.
Download
WTMEMB 9845B/C Exerciser Tape #1 (ENHGR) WTMEMB

WRITE MEMORY <block>:<address>, <value>

Functions:
OCT(<oct_value>)
MEMORY(<block>, <address>)
DTO$
EXTR
CATN
DTB$
DTH$

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.
Download
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.
Download
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.
Download

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 parameters

Execution: 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.