Autostart...

Hardware Hacking, Programming and Game Solutions/Cheats
Post Reply
Rink
Posts: 236
Joined: Mon Sep 05, 2011 7:01 pm

Autostart...

Post by Rink »

'lo :)

I'm just getting into a bit of Dragon programming (mainly 6809 assembly, but some BASIC too) and I was wondering if someone could tell me, maybe with a bit of a code snippet, how the autostart/autorun and "loading screens" on commercial titles work? A response to a letter in Dragon User indicated that it might be done by overriding the launch vectors but didn't give any clue as to how to do that.

Any points would be much appreciated.

Cheers.
Sarah
Posts: 177
Joined: Wed Apr 13, 2011 3:36 pm
Contact:

Re: Autostart...

Post by Sarah »

This is actually really easy to do. The most common method, as referenced in the DU response you mention, simply involves overwriting the launch vectors (or "ram hooks") between $15E-$1A8 in the system variable area of memory.

These hooks are a table of 3 byte addresses to which the Dragon's built-in BASIC interpreter makes frequent direct calls in order to support the expansion and customisation of ROM routines. They have lots of potential and actual uses but initially simply contain RTS instructions so that they return without doing anything; the typical way to make use of a hook is to replace this with a JMP instruction, causing an additional machine code routine to be executed each time the hook is called by BASIC.

For the purposes of performing an autorun, the hook at $167 is typically used, which is called by BASIC before any text mode characters are output, therefore once a CLOADM operation has completed the hook is called (causing the loaded software to execute) before BASIC displays "OK" and this gives a tidy outcome. Occasionally the hook at $16A has been used instead, which is called by BASIC before character input from the keyboard, so in this case "OK" will be seen first, but the effect is much the same. Few, if any, of the other hooks would cause the software to execute immediately after loading, without the user having an opportunity to type another command.

A simple and common (but somewhat lazy) way for an autorun to be implemented has the software and all data contained in a single file, with a load/start address of $167 (or less; but not $0 since some system variables such as those used by the cassette routines must not be touched). The file continues, overwriting the text screen area $400-$5FF to display a loading screen and then onwards and upwards in memory for the software code and its data, not ending until the last address it uses has been included. Unfortunately, commercial titles using this approach have often included lots of unused memory between $600 and the start of real code and data (needlessly extending the file size and loading time) even though it would be very easy for the code and data to be loaded lower in memory and relocated when executed. If loading results in an ?IO ERROR then a crash is likely since the JMP in the hook will still activate even if loading is incomplete. This style of loading is also defeated very easily, e.g. CLOADM:POKE359,57 often works.

The disadvantages of using a single file can be avoided by loading the software in multiple parts, which can easily be headerless since headers have no purpose when loading is already under the control of a custom loader. The loader can also switch the display to a hires graphics mode, of course, when a hires loading screen is to be displayed.

There are lots of variations of the RAM hooks approach. A method I used to enjoy using involved deploying the autorun loader directly into an extra-long initial header block, so that it's already in memory before the "F" is displayed and the main program can then be as short as 3 bytes, to hook BASIC into executing it. Another smart but virtually unknown approach is to use the gapped machine code format, which can load arbitrary code to different addresses, without even needing a loader. Unlike the single file approach, these formats also need custom code to create them, since CSAVEM doesn't support doing so.

If the loader or software wishes to exit when it has finished then it needs to restore any hooks used before doing so, e.g. by restoring the RTS at $167. If the software is BASIC then it can be RUN by the loader setting up the system variables correctly and using the appropriate ROM calls.

There are also other autorun methods which don't use the RAM hooks but are much less common, for example by overwriting the system stack at the top of 32K memory. They can all be defeated; with varying amounts of effort!
Rink
Posts: 236
Joined: Mon Sep 05, 2011 7:01 pm

Re: Autostart...

Post by Rink »

Great googly moogly - you're amazing! Really excellent info, thank you so much.

Am I right in thinking that you can specify the load address (e.g. $167) in one of the header blocks used by the .cas format?
Sarah
Posts: 177
Joined: Wed Apr 13, 2011 3:36 pm
Contact:

Re: Autostart...

Post by Sarah »

You're welcome!

Yes the load address is encapsulated within the header block. A standard format file will have only 1 header block. For example, you could create a simple autorun file like this - suppose you have a short machine language routine installed at $200-$27F (which could itself be a custom loader, or anything else):

Code: Select all

POKE359,126:POKE360,2:POKE361,0:CSAVEM"AUTORUN",359,&H27F,0:POKE359,57
The routine being executed at $200 should also ensure that it restores the hook (e.g. LDA #57 followed by STA 359) if it terminates or wishes to output text using the BASIC routine.
Alastair
Posts: 669
Joined: Fri Jul 18, 2008 11:33 pm

Re: Autostart...

Post by Alastair »

Sarah, it's no wonder that in a previous life you were able to find so many pokes for all those arcade games!
Rink
Posts: 236
Joined: Mon Sep 05, 2011 7:01 pm

Re: Autostart...

Post by Rink »

Sarah, just wanted to say an extra thank you since I actually got this working recently.

Cheers again.
Sarah
Posts: 177
Joined: Wed Apr 13, 2011 3:36 pm
Contact:

Re: Autostart...

Post by Sarah »

That's good to hear; glad I could help!
Post Reply