Friday, January 5, 2007

Multiple Entry Point Instructions

In compiler theory we have the concept of a "basic block." This is a unit of code which is only entered at the beginning and has a single exit at the end of the block. All code is made up of basic blocks.

My disassembler attempts to discover all basic blocks by reverse engineering the call graph. Normally a instruction is an atomic unit... it has only one entry point and one exit. Steve Adolph brought up some BASIC ROM code in which a given multi-byte instruction can be entered at more than one address, and so the code will execute in different ways.

I think my disassembler would do OK but it would pick one path and not the other depending on which call it reached first. As I disassemble I mark a table of addresses that hold the opcodes and postbytes as "visited." Once an address has been disassembled I don't attempt to disassemble it again.

The reason I have the "visited" flags is to prevent the disassembler code from looping forever disassembling the same code. However, since the actual entry point is different it might make more sense to disassemble both paths. Instead of deciding whether to follow a code path by the visited flag, I would instead decide based on whether the specific entry point has been visited as an entry point rather than as an intermediate byte. Since the goal is to produce code which is ready to be assembled, the alternative code would have to appear as a comment. ideally the longer code string would be the dominant one... otherwise the extra bytes would be disassembled as 'db' raw data.

The really difficult things to disassemble, at least automatically, are computed gotos, vector tables and self-modifying code. At least in the ROM there is no self-modifying code. I noticed some areas where RAM100.CO (which runs from RAM) modifies postbytes. The actual instructions themselves are never modified but the postbytes after the opcode are. In this case, the immediate byte indicating the i/o port is calculated and modified directly in the object code at runtime.

Wednesday, January 3, 2007

Minimal binary file transfer (concept)

From a recent email:

I've been thinking about how to make an absolutely minimal Model 100 file transfer application which requires no client but can transfer a binary file. Basically the idea would be that on the laptop you type

RUN"COM:98N1E"

which accepts and runs a very small program BASIC program that pokes in ML. Real short, fast... just enough code to read in and append raw binary blocks to a RAM file from the COM port and calculate a checksum as it goes. No flow control, the PC side is tuned to send packets at a fixed
rate that the laptop can sustain. No retransmissions supported... at the end of the transfer the decision is made to either keep the saved file or delete it depending on the checksum match. By and large there should be no errors on a local link.

This sidesteps the whole issue of not having a client on the laptop. Since there is no user interface there would be very few dependencies on the ROM so it could be made cross-platform.

On the PC side I would have a really short (probably 20 lines of Perl) command line program that computes the checksums, sends the canned BASIC code and the file. There is a cross-platform serial API for Perl that would work on both Linux and Windows.

The upload to PC would work similarly... RUN"COM:98N1E" on the laptop, and launch the desktop program... it downloads a short BASIC/ML program that can upload one (or all) files from the RAM file system to the desktop.

Comments?