Re: *.ROM and *.MOD file format documentation? Message #6 Posted by Thomas Okken on 5 Feb 2006, 2:20 p.m., in response to message #5 by Doug Wilder
I stared at a couple of ROM dumps for a couple of hours, and here's what I found. It seems pretty straightforward. I don't care about the "mystery" blocks (Doug mentioned they are for COPY and PRIVATE), and the details of GTO/XEQ offsets and the global chain are not important for what I plan to do either (when Free42 imports HP41/42 user code, it translates it to its own internal format and the specifics of offsets etc. are unceremoniously discarded).
Thanks again for your help -- looks like I'm good to go! :-)
- Thomas
0000: (1 word) ROM number
0001: (1 word) number of functions + 1
0002: (2 words) Offset to pac name. Points to an E0 byte, which is *preceded*
by the pac name, with letters in reverse order. The encoding
looks like ASCII but with the letters of the alphabet moved
to 01-1A. The last character of the name is flagged by bit 7.
0004: function directory, one 2-word entry per function. If the
function is user code, bit 9 of the pointer's first word is
set; for mcode, bit 9 is clear.
The directory is followed by two zero words, presumably a
sentinel.
The remaining words contain the pac's code. User code chunks are always
preceded by a two-word chunk of unknown purpose; both the user code chunks and
the mystery chunks have their final word highlighted by having its bit 9 set.
Inside user code chunks, bit 8 is used to indicate the first word of an
instruction -- to help speed up BST, no doubt.
So, to extract user code from a ROM image, the following algorithm seems like
it might be adequate:
1) Get the ROM number from word 0000 and the instruction count from word 0001.
2) Get the ROM name by dereferencing the offset at word 0002-0003 (minus one)
and moving backward until a word with bit 7 set is found. Add 0x40 to all words
in the range 00-1F.
3) Copy the table of offsets into temporary storage. Discard all mcode entries;
sort the remaining entries by address.
4) Import user code, starting from the instruction pointed to by the first
entry in the sorted offset table. Keep importing until an END instruction is
found. Then remove all offsets before this END from the offset table.
5) Repeat step 4 until the offset table is empty.
6) During the import process, keep track of the locations of global labels in
the imported code. Build a new XROM->label translation table. Mcode entries
should be set to NULL so Free42's instruction despatcher will know that it has
to display an error message rather than perform a subroutine call.
7) Display a warning when mcode entries were found in the ROM image; display an
even sterner warning if the user code from the ROM image calls these mcode
functions.
Edited: 5 Feb 2006, 2:27 p.m.
|