Introduction
I have just released a serial port based Amiga disk and file transfer tool, amigaXfer.
It is able to read/write/compare floppies, install bootblocks, send/receive files and dump the kickstart rom.
AmigaOS 1.x, 2.x and 3.x are supported.
By disabling interrupts and polling the serial port directly, speeds as high as 512kbps are achieved, even on a basic Amiga 500 with its 7MHz cpu clock. The integrity of data is protected by CRC-32/ISO-HDLC.
Unlike most serial port transfer tools, it does not require installing and running an agent on the Amiga side, as it uses the kickstart rom's debugger to take control of the Amiga.
There's multiple ways to get into this debugger. A simple one is through Workbench's debug menu, present when wb is loaded using loadwb -debug
.
Selecting the Debug, RomWack or SAD menu option in Workbench 1.x/2.x/3.x will then enter the debugger and enable amigaXfer usage.
Another method to enter the debugger is through the execution of a little hardware trick. This method enables the bootstrapping of an Amiga computer without the requirement of having any Amiga-bootable floppies.
This article documents usage of this alternative bootstrapping method, and how it works from a technical perspective.
Requirements
- An Amiga in good condition.
- If the Amiga is an A1000, the kickstart will have to be loaded first.
- AmigaXfer does work with any AmigaOS (1.x/2.x/3.x), and this last-resort alternative bootstrap method has been tested on 1.3(34), 2.0(37), 3.0(39), 3.1(40), 3.1.4(46) and 3.9(45).
- A supported platform running current version of amigaXfer.
- A null-modem serial cable or an USB <-> RS-232 adapter, connecting both computers together. Only three wires will be used: GND<>GND straight and RX<>TX crossed.
- A few blank floppies, verified to be good e.g. by a verified formatting done on another computer. DD is preferable over HD.
- ADF images of any desired floppies to be written. These are suggested:
- Workbench and Extras floppies matching the kickstart version.
- As a free and open source alternative, Nico Bendlin's HelloAmi will boot all the way up to Workbench. He kindly enabled the Workbench's debug menu on my request, which involved some research work on his end. Many thanks for that.
- Keir Fraser's Amiga Test Kit.
- A piece of wire or, if pressed, a paperclip.
- Steady hands that won't connect elsewhere than necessary.
How it is done
These instructions are provided as-is, without express or implied liability. Follow under your own responsibility, and only after understanding them whole.
If bootable Amiga floppies are available, there are far easier methods to enter the debugger and use amigaXfer, such as the trivial loadwb -debug method.
Unplug unnecessary external expansions (such as those attached to the left expansion port on A500).
Open the Amiga and locate a GND and the BERR signal.
BERR, marked in orange, is a pin on 68000's socket, so it is possible to just touch the top of 68000's leg for the purpose.
There's a large GND marked in blue on the left expansion header, useful to hold a wire against.
For paperclip convenience, a GND pin that is close to BERR is also highlighted in blue.
Turn Amiga on, without a floppy inserted. Wait for the video output to show the Workbench prompt. If no floppy is present, the floppy drive should now begin to make clicking noises.
Ensure your version of amigaXfer is current.
Select CrashEntry on amigaXfer, and click connect. LogWindow is recommended to be left on, in order to easily follow what is going on.
Calmly connect BERR into GND for just an instant. If contact lasts for too long, it may require a reboot (Control-Amiga-Amiga) and retry.
Once the brief connection is properly executed, the Amiga will reboot to a white screen and amigaxfer's log window will fill with output. If all goes well, amigaXfer's main menu will pop up after a few seconds.
As the speed of the serial port is locked at 9600 for the bootstrap case, it is recommended to now use the Bootblock Tool to install a debug bootblock into one or more floppies. Tick the Format checkbox, as the floppies aren't necessarily Amiga formatted to begin with. Write protect the floppy and exit. The Amiga will reboot normally.
Amiga should be able to boot this floppy, and normal (non-CrashEntry) usage of amigaXfer should be possible at this point. This means fast transfer speeds are available, as fast as 512kbit/s on a plain A500, therefore writing floppies from images should be fast.
Once a Workbench floppy has been written, the loadwb -debug method can be used to enter amigaXfer thereon, thus this last-resort BERR-based bootstrap method should not be needed again.
How it actually works
BERR is pulled high in the Amiga via 470Ω resistor, so it'll sink about 10.6mA when connected to GND, which is safe. This current comes from the PCB and not a custom chip's output. In A500, it isn't even connected to anything else than the CPU's input, the left expansion header and the pull-up resistor.
From the CPU's point of view, BERR reads low, causing a Bus Error exception to be raised; the CPU reads a pointer from the vectored exception table and branches there.
On AmigaOS, this is set to a routine that will cause a non-recoverable crash, the sort that blinks the led, reboots and shows a guru.
While the led blinks, the kickstart will check the serial port hardware directly (SERDATR) for an incoming DEL (0x7f) character. If found, it will enter the built-in serial debugger (e.g. RomWack), instead of rebooting.
Unfortunately, DEL will crash RomWack if received, due to the debugger using basic serial i/o functions which are programmed to enter RomWack on DEL received. Thus, it is not possible to just flood the serial port with DEL. Instead, DEL is sent on a short timer, after checking there aren't incoming characters sent from the debugger. Once there are, the debugger is running, thus we have control.
At this point, AmigaOS is effectively unusable (exec calls will fail), so we will instead prepare to recover control after a reboot by pointing CoolCapture directly to exec's Debug() function.
If kickstart version is lower than 36, there is a kickstart bug which considers exec's base structure to be corrupted if it states that there is more than 512KB of CHIP RAM available, thus discarding it and building a new one, losing CoolCapture in the process. Unfortunately, many Amiga capable of 1MB CHIP shipped with kickstart 34, thus if this is the case we need to work this bug around by setting the value to 512KB. Fortunately, this much CHIP memory is plenty for bootstrapping.
We don't need to see the GURU display (which would require user intervention to get out of), so we also clear the guru flag, which is the 'HELP' text written at the first four bytes of memory. Then we reboot.
When the system reaches CoolCapture, we recover control. In this boot stage, exec.library is fully functional, but the rest of the modules in the kickstart ROM have not been initialized. Therefore, it is not possible to e.g. use trackdisk.device to access the floppy drive.
We want to use the floppy drive, thus this is less than ideal. But if execution was resumed, AmigaOS would initialize a subset of the modules in the resident table which have a certain flag set, including trackdisk. The last of these modules is strap, which shows the Workbench floppy prompt and whose initialization function doesn't return. This is inconvenient, as it would place us back where we started.
In order to avoid this, we simply remove the lowest priority entry from the residents table i.e. strap. Therefore, the function that handles the initialization of modules will actually reach the end of the table (instead of being taken-over by strap), and will return.
This causes code in the ROM that would normally never be reached to run. What this code does is call WarmCapture() if set, and after or otherwise it calls Debug() on an infinite loop. This is convenient, as it saves us the trouble of setting WarmCapture.
Newer kickstarts (AmigaOS 2.x and 3.x) do instead go into an infinite loop deadend after initializing the residents table. For these, we instead replace the strap entry with our own RomTag structure, which calls Debug() as init function. The strap function is also not the last entry in the list anymore, so we check rt_Name on each entry until found.
At this point, we have control again and AmigaOS is almost fully initialized, with the notable exception of dos.library (not required for doing block level I/O), which is skipped as the LSB of its RomTag structure's rt_Flags field is clear.
This environment is sufficient for amigaXfer to proceed normally.