HP 9830 | HP 9830 Machine-Language Programming |
Producing a machine-language program for the 9830 is covered here in two parts:
The assembly source can be assembled using the asm9830 assembler to produce 9830 machine code.
For an example of machine language routines and binary-block formatting at the assembly level, see the Machine Binary-Block source or listing.
Two-argument functions add some complexity, the function code must be forced to an offset beyond ~ 30 to inhibit the default single-arg parsing, and one must do the parsing in your own code. See the MPOKE(a,n) function in the MBB as an example. The MBB includes a routine for two-arg parsing.
Note that functions can be used directly at the user command level, not just within BASIC equations.
A binary-block is a dynamically-linked machine-language extension to the firmware. The block is seen as the addition of commands, functions and statements at the user level.
A binary-block can be implemented as a binary tape file loaded into RAM via the LOAD BIN command, as a ROM card, or as a ROM cartridge.
Binary-blocks can vary in length but in memory the end of the block is always aligned to the end of certain pages. The end-of-page alignment is the key to the dynamic linking. The block pages are the memory pages corresponding to the 4 ROM card slots, the 5 ROM cartridge slots, the last page of RAM, and two pages fixed in the firmware ROM.
The diagram to the right presents the linking organisation, using file 0 of the System Test tape loaded into the RAM block-page as an example. As a binary tape file, file 0 has been loaded at the very top of RAM, the end-of-file aligned to the end-of-page at MAW. The octal addresses are values for a machine with 8K of RAM, the decimal addresses are the address within the page. File 0 is 511 words long and pages are 1024 words, so the file was loaded starting at the 513'th word in the page.
MAW is the maximum RAM word, and is determined by a scan of RAM pages at reset / system initialisation.
LWAM is the last available RAM word for BASIC programs and data, and is set in accordance with the file size when the binary file is loaded.
While there is only one RAM block-page, I have not seen a limitation on the size of that block, so it may be larger than one page.
For ROM block-pages the same organisation applies, with the addresses changed to reflect the page corresponding to the slot the ROM is plugged into, and the size of the block limited to one page.
The two firmware block pages contain the built-in commands, statements and functions of BASIC and the cassette tape operations.
The last word of the block is a Block ID, and is used (in part) to detect the presence of a block in a block page. A Block ID of zero indicates an empty block.
The 3 words preceding the block ID are offsets to symbol tables for the extensions provided by the block.
The symbol table offset is relative to the location of the offset itself.
When looking for a command, statement or arithmetic function symbol, the system scans the last word of block pages looking for present blocks, and then searches the appropriate symbol table in the block for the symbol.
The byte following a symbol contains a symbol-code, the symbol-code value is used as a negative offset from the beginning of the symbol table to obtain an offset to the executable machine code (entry point) for the symbol.
The entry point offset is relative to the location of the offset itself.
The symbol code byte includes two flag bits for End-Of-String and End-Of-Table.
Use | Block ID | Source |
---|---|---|
empty block | 000000 | PM |
- | 002000 | |
String | 004000 | PM |
Matrix | 006000 | PM |
Plotter | 010000 | PM |
BASIC Predefs | 012000 | PM |
Tape Predefs | 014000 | PM |
Terminal | 016000 | P |
Mass Memory | 020000 | M |
Advanced Prog. I | 022000 | M |
- | 024000 | |
Extended I/O | 026000 | PM |
- | 030000 | |
- | 032000 | |
- | 034000 | |
Advanced Prog. II | 036000 | M |
- | 040000 | |
- | 042000 | |
- | 044000 | |
- | 046000 | |
(MBB) | 050000 | S |
- | 052000 | |
- | 054000 | |
- | 056000 | |
- | 060000 | |
- | 062000 | |
- | 064000 | |
- | 066000 | |
- | 070000 | |
System Test Tape | 072000 | T |
- | 074000 | |
- | 076000 | |
P = Patent M = Memory dump T = Tape dump S = Selection |
The BlockScan program provided with the MBB scans and lists the blocks in a system.
Here is an example of an interaction to assemble and load a program into the 9830 via the MPSI Server.
On the host:
host$ asm9830 -a pgm.lst -o pgm.f98 pgm.s host$ tp9830 TP9830> load pgm.f98 TP9830> save pgm.t98 TP9830> quit host$ mpsiServer -t pgm.t98 -- MPSI Server: start, ^C to terminate. -- MPSI Tape: image file loaded, 1234 bytes.On the 9830:
LOADBIN #9,0 NEWCMD
In the above:
The binary-block linking details were derived from reading the patent firmware listing. To test it an absolutely minimal test program - something just enough to give an indication it was running - was written, hand-assembled, written to a cassette via the 9865 drive with I/O adapter, and loaded into the 9830. Sputnik was a 3 instruction program that beeps intermittently.
Sputnik is now included in the MBB.
Sputnik Assembly Program
MPSI | MBB | Machine-Language Programs | HP-9865 Adapter | Mimic66 HP 9830 |
bhilpert 2013 Oct |