How to write a machine-language program for the HP48sx using CLASS ------------------------------------------------------------------ (C)1991 Lutz Vieweg The easiest way to write a machine-program for the HP48sx is to create directly a binary file that can then be transferred to the HP48sx using a common KERMIT program or similar. There are only two problems: The HP48sx works nibble-orientated, but serial transmission is based on bytes. The HP48sx seems to swap the low and the high nibble in every byte it passes through it's UART. Generally it's not the task of an assembler to compensate such nasty things, but I did feel a touch of human sympathy and create an assembler-option to do this (-rn). The second problem is that you have to know a little about the structure of a HP48sx binary file. This is what follows... 1.0 The binary-file header -------------------------- The binary-file header consists of the following 8 byte "H" "P" "H" "P" "4" "8" "-" Version ( "A" to "E" by now) $48 $50 $48 $50 $38 $38 $2d $4x Please set the version-indicator according to the one you use. 1.1 After the header... ----------------------- The nibbles after the header directly represents the memory-image that can be found later in your handheld - but think of the nibble swapping for transmission once again. There's no control information or anything mysterious else. The HP48sx allocates memory for the file that is transmitted, and creates a hash-table entry for it that is "connected" to the name of the variable that was defined in the KERMIT-file-header during transmission. 1.2 Why does the HP48sx not accept any memory-image? ---------------------------------------------------- The HP48sx performs a simple test on any file it receives: Everything, it does not identify, is assumed to be an "external", an unknown 5-nibble RPL-adress. Everything that can be identified by the HP is taken for itself... but when the file ends, there has to be an identifyable instruction the last one. If you transmit an invalid binary to your 48sx, you will either get a string object with the memory image in it (binary-mode) or a "syntax-error" (ASCII-mode). 1.3 What's the correct format of a HP48sx object? ------------------------------------------------- The first five nibbles of an object are always assumed to be a RPL-code. You'll have no trouble if you are setting these first five nibbles to $02d9d (Type_pgm), the last five to $0312b (End) and whithin only valid RPL-commands, for example $02dcc (Type_code) which allows you to include any data-nibbles into the object which are assumed to be an executable machine-program while evaluation of the object. A typical program torso may look like this: main textr "HPHP48-E" dcr.5 $02d9d dcr.5 $02dcc pgmbeg dcr.5 pgmend-pgmbeg ; lenght of machine-pgm jsr $0679b ; save_regs ; here comes the code jsr $067d2 ; restore_regs move.a (d0),a ; jump to next RPL-code add.a #5,d0 jmp (a) pgmend dcr.5 $0312b 1.4 Using absolute adresses... ------------------------------ ... is not that easy on HP48sx. You cannot know where in memory your program is placed when it is executed. There are three possible solutions to this problem: 1. Only write relative code. This one is nice when creating up-to-100-byte programs. But at larger projects this becomes very nasty. 2. Kick-ass the OS and do what you want to do. Seems nice when using the 48sx as arcade-machine (SHAME-BOY), but isn't that funny when you want to do calculations later without having the chance to reload a backup from your stationary computer. 3. Write relocatable code! You do not know, how? Well, this is not a solution that has been offically presented by HP to all the guys who want to get into their machine. This is just an idea I tried successfully (QED was written that way): The CLASS-assembler supports a pseudo-ob to create a simple relocation-table. Please read the instructions there for more information. The needed routines are included in this package. They are both assembler-sources to be "INCLUDE"d into your program. Here comes a simple-sample program using these includes: main include "class.mac" textr "HPHP48-E" dcr.5 Type_pgm include "relocpgm.a" dcr.5 $02dcc pgmbeg dcr.5 pgmend-pgmbeg jsr save_regs move.ao #outvar,d0 move.ao #outvar,c move.a c,(d0) jsr restore_regs move.a (d0),a add.a #5,d0 jmp (a) reloc_tab reltab pgmend include "rerelpgm.a" outvar binint 16,0 dcr.5 $0312b include class.sym 1.5 to be continued... ---------------------- I do not get a penny for the assembler at all - so it depends heavily on my actual motivation whether I improve it or it's manual. This one may be continued later. Lutz Vieweg UseNet: lv@muffel.hotb.sub.org FidoNet: 2:247/30.20