Modern memory support for the Progressive Peripherals & Software 2000/040, a 1991 68040 accelerator for the Amiga 2000.
The card's 32-bit RAM doesn't autoconfigure. Its original driver, Init040, adds it from the
startup-sequence, was written for OS 2.x, locks up with newer 68040 libraries and leaves memory
unused. This project replaces it with ppi2000mem, a small resident module burned into the
Kickstart ROM. It adds all the card's RAM at cold start, before DOS and MMULib, so the memory
behaves as if it autoconfigured.
On the reference machine (AmigaOS 3.2.3, MMULib, 32 MB on the card) that meant all 32 MB in use
instead of 30, with the 32-bit RAM preferred over the slow 24-bit RAM, and no startup-sequence
changes other than deleting the old AddMem.
The memory had to be added via the startup-script so you could not test it using tools like xsysinfo. I also wanted to use AI (I use Claude) to help me learn about assembly language. Did I learn much? That is up for debate. The included walkthrough was useful for me in understanding how the code is written but it still leaves a lot of gaps for me. I am hoping to continue to work on this and learn more about assembly for the 68k.
| Path | What |
|---|---|
src/ppi2000mem.asm |
the ROM module (68040 assembly) |
src/ppiprobe.asm |
Shell tool that reports where the card's RAM answers; adds nothing |
src/ppiload.asm |
installs the module until power-off and reboots, to try it without burning a ROM |
tools/mkrom.py |
puts the module into a Kickstart image and fixes the checksum |
tools/mkbootdisk.sh |
builds the bootable test floppy (no AmigaOS files needed) |
tools/disasm.py |
disassembler for AmigaOS executables, used on the PP&S software |
tools/fetch.sh |
downloads the original PP&S driver disks |
tools/mkrelease.sh |
packages a release (zip and ADF) |
tools/onerom-a2000.json |
the One ROM slots for the test setup |
tests/ |
runs the module on an emulated 68040 against simulated cards, and mkrom.py against a synthetic Kickstart |
docs/hardware.md |
the card: jumpers, memory layout, measurements |
docs/reverse-engineering.md |
what the original driver does and how ppi2000mem differs |
docs/rom.md |
testing, building, burning, MMULib setup |
docs/walkthrough.md |
the assembly explained for Python developers |
Each release has a zip with ppi2000mem, ppiload, ppiprobe, mkrom.py and
the docs, and a bootable test floppy (ADF) with the same Amiga files; no AmigaOS or PP&S files.
Boot the floppy to probe the card, and type ppiload to try the module until the next power-off. To patch your own 512K Kickstart image (Python 3.8+, no other
packages):
python3 mkrom.py CDTVA500A600A2000.47.115.rom ppi2000mem kick-ppi2000mem
This writes kick-ppi2000mem.rom (for emulators and MapROM) and the byte-swapped
kick-ppi2000mem.bin for burning. Add --copies 4 for a 2 MB chip such as an MX29F1615 in the
512K socket. Try the module with ppiload before burning; see docs/rom.md.
- Docker. Everything runs in the
toolscontainer (vasm, amitools, xdms, Capstone, Unicorn, pytest);make imagebuilds it. - For
make romonly: your own Kickstart image. It isn't included and can't be. By default the Makefile usesamiga_roms/CDTVA500A600A2000.47.115.rom(the 3.2.3 A500/A600/A2000 ROM); setKICKto use another, inside this directory.
make image # build the tools container
make test # run the module against the simulated cards
make bootdisk # build/pps040-test.adf: probe the card, try the module with ppiload
make rom # build/<kickstart>-ppi2000mem.rom and .bin (COPIES=4 adds -x4.bin)
Then follow docs/rom.md: probe first, try the module with ppiload, and only then burn.
make release packages build/release/pps040-<version>.zip and .adf. GitHub Actions
(.github/workflows/build.yml) does the same on every push and keeps the package as a run
artifact. To publish a release:
- Bump the version in the
idstringline ofsrc/ppi2000mem.asm. - Add a
## X.Y (date)section toCHANGELOG.md; it becomes the release notes. - Tag and push:
git tag vX.Y && git push origin vX.Y. The workflow refuses a tag that doesn't match the module version.
To read the original driver: make disasm downloads the PP&S disks into vendor/ and writes
the listings to build/disasm/.
The reference machine can test ROM builds on a One ROM Fire 40 Rev B in the A2000's Kickstart socket instead of burning a chip. A new build can be running on the real card in a few seconds, from the host and with the case closed. This is optional and nothing else in this repository needs it.
make rom onerom-poke # build the ROM, load it into the One ROM's RAM, reset the Amiga
make onerom-menu # back to the boot menu
make onerom-flash # build the ROM, write all the slots to flash, reset the Amiga
make onerom-poke ONEROM_IMAGE=amiga_roms/onerom/diagrom-2.0-16bit.bin # any other 512K image
These targets run the onerom CLI on the host rather than in the tools
container, because they need the USB connection. They expect the USB cable to be connected.
tools/onerom-a2000.json holds what make onerom-flash writes. The board's 2 MB of flash fits
three 512K images alongside the firmware and plugins, so anything else, such as DiagROM, is loaded
with make onerom-poke.
| Slot | Image |
|---|---|
| 0 | amiga_roms/onerom/amiga_boot_512k_always_menu.bin, the boot menu |
| 1 | build/CDTVA500A600A2000.47.115-ppi2000mem.bin, this project's ROM |
| 2 | amiga_roms/CDTVA500A600A2000.47.115.bin, stock 3.2.3 |
All the images are byte-swapped (.bin), and are git-ignored for the reasons
below. The boot menu is the
RBCP Amiga bootloader
built with make ROM_KB=512 DEV=1, which writes build/amiga_boot_swapped.bin. The stock build
only opens the menu if both mouse buttons read as held at the moment it checks, which never
happened on the reference machine. DEV=1 always opens it. DiagROM's image is 16bit.bin from
the DiagROM release.
A wire from the One ROM's SEL_C pin to the 68000's reset line lets the host reset the Amiga, with
the 040 card fitted. The reference machine connects it at a via on the same net as the 68000's
pin 18. Check the pin with a meter before connecting it, because the holes
are easy to confuse. Reading the labels on the underside of the board, it is the lower hole in the
C column, directly above the CLK label:
SEL_A SEL_B BOOTSEL RUN 5V upper row of holes
A B C D 5V labels
GND GND [SEL_C] SEL_D GND lower row of holes
0=Open CLK DIO GND labels
SEL_C and SEL_D are 5V tolerant. SEL_A and SEL_B are 3.3V only, so never connect them to
the reset line. onerom board header --board fire-40-b draws the header from above.
make onerom-flash always passes --reserve-pin, which stops the firmware reading the wire as an
image select pin. Keep that option if you flash by hand. SEL_C is also the debug probe's clock,
so remove the wire to use a probe.
The menu copies the chosen image over the one in the One ROM's RAM, including the menu itself,
and make onerom-poke does the same with its image. Only a restart of the One ROM brings the menu
back. A reset of the Amiga doesn't restart it, and with USB connected neither does switching the
Amiga off, because USB keeps the One ROM powered.
| Action | The Amiga then boots |
|---|---|
| Ctrl-Amiga-Amiga, or the reset wire | the same image |
| Power cycle with USB connected | the same image |
| Power cycle with USB unplugged | the boot menu |
make onerom-menu |
the boot menu |
So a poked build survives a power cycle while USB is connected, which allows a true cold-start test of the module.
Flashing, restarting or poking the One ROM changes the ROM under a running Amiga, so expect it to crash until the reset that follows.
Burned and in daily use on one A2000 with a 32 MB card, with 0 MB and 2 MB of autoconfig RAM. The Zeus, Mercury and other PP&S cards aren't supported (the module leaves them alone); see the notes at the end of docs/reverse-engineering.md.
Kickstart ROMs, AmigaOS files and anything built from them (patched ROMs) are © Hyperion
Entertainment. The PP&S driver software, its disassembly and its manual are PP&S's.
amiga_roms/, vendor/ and build/ are git-ignored for that reason. The test
floppy contains only this project's files.
- amiga.resource.cx for keeping the PP&S disks, manual and jumper table available.
- The old PP&S 040 FAQ, whose AddMem addresses were the first clue to the memory layout.
- Thomas Richter's MMULib, and the vasm, amitools, Capstone and Unicorn projects.
MIT, see LICENSE. Covers this repository's own code and documentation only.