Run-In-Place CO

From Bitchin100 DocGarden
Jump to navigationJump to search

Purpose

Machine language programs on the Model 100 normally contend for space in high RAM. It is often desirable to keep "TSR" (terminate and stay resident) utilities in high RAM. Therefore, "normal" CO programs contend for the high RAM area with TSR utilities.

More importantly, CO programs residing in the RAM filesystem end up taking twice as much precious RAM to run as they need, since during run, two copies exist: the copy in the RAM filesystem, and the running, properly located copy.

Finally, new users often have trouble getting CO programs going. This because upon attempt to execute, if no HIMEM space has been reserved for them using CLEAR, the laptop will beep and leave them back at the menu with no reason. It would be great if we could avoid the CLEAR step.

For these reasons, the goal of this design is to create a CO file which runs "in-place," wherever its file happens to be, with no need to reserve any high RAM to run a CO file.

In order to make this work, we must resolve three issues:

  1. Overcoming the "copy" step
  2. Finding the program
  3. Achieving position independence

I believe this can be done, if a small amount of code can be loaded to a place in high RAM or ALTLCD.

Overcoming the Copy Step

When a CO program is loaded, either from the Menu or from BASIC, it is copied to wherever "TOP" is for the program.

This is problematic for a "run-in-place" program, since the TOP specified with the file is almost certainly not where we we want the program to run from.

The first thought to dealing with this is to set the TOP address to 0. This would cause the a "no-operation" copy since the image would be copied to the ROM area, which is not writeable.

However, this doesn't work... an OM error occurs.

The next best approach does work, however: use address 65535 as the TOP address. The first byte copied overwrites the top byte in RAM, which doesn't seem to cause any problem for me. Due to "rollover," subsequent bytes will be copied to the ROM space, which is a no-op.

Finding the Program Entry Point

With the copy operation nullified, we now need to figure out a way to find the "in-place" entry point for the executable.

Normally the ENTRY for an executable is specified starting at byte #0 in the CO file header. After the copy operation, this is where the program would be entered with a CALL instruction.

But CO programs in the RAM filesystem are moved around all the time, with other files. It is unlikely that the Entry field in the CO header could be kept in sync with these continual changes.

Since we control the payload layout of the CO file, we can just make the Start of the CO file in the filesystem, plus 6 bytes (accounting for the CO header) the Entry point.

So how do we compute this entry point and ensure the launcher will jump to it? We store a pointer in our CO file's ENTRY to a common routine stored in ALTLCD that will:

  1. Lookup the file, by name, in the RAM filesystem
    1. If [SP] == 0x256A, then the program was launched from the Menu. Use the cursor position to locate the filename in the directory.
    2. Otherwise, the program was launched from BASIC. The filename is available in the FILNAM RAM variable.
  2. Determine the start of address of the CO file in RAM
  3. Add 6 bytes to skip the header
  4. Jump to the computed entry point

All of this should work, but consideration must be given to the case that the CO file is present, but the launch logic is not installed.

To avoid an issue, we should use vectored execution of the launch logic. Normally BASIC vectors have a RET installed, and we can make all run-in-place CO files point to the chosen vector. When we install the launch logic, we'll make the chosen BASIC vector point at the launch logic.

So if it occurs that the user forgets to install the launch logic, launching the CO will have no negative effects (other than the CO not executing).

Achieving Position Independence

Fixed-Relative Technique

Fixed-relative is a technique where all jumps are coded to jump to some fixed code elsewhere that calculates relative addresses, places them on the stack, and RETs. Such code does not need to be relocated.

(TBD: link to fixed-relative coding technique)

Relocatable Object Code

With a relocatable object code, either a common relocator subroutine is stored along with the program entry point finder, or the relocator can be packaged with the CO file at the entry point.

(TBD; link to article about relocatable format)