Aira Force 0.9.0 released
At long last I am proud to present Aira Force 0.9.0. This is a big release for me, because it features a working Amiga 500 emulator. It is available to download now for Windows (64 and 32 bit), Mac, Linux (64-bit), and Raspberry Pi.
I hope it will be useful for disassembling software live. I often code while on a breakpoint, because the debugger provides so much more context to help improve the code. The same should be true for disassembling.
The emulation works, but compatibility is not very good at this point. It plays a good set of the games that I've tried. See the list at the end of this post.
Using the emulator
- Emulator > Options > ROM: Point at your ROM (Kickstart 1.3 is best)
- Check Emulator > Options > Input options
- Add 512 KB Slow (trapdoor) RAM if required
- Open the Emulator > Video window
- Start the debugger using the Debug > Start menu, or press F5
- Hopefully the "strap" hand-holding disk image should appear
- Open the Emulator > Floppy Drives window
- Insert and ADF disk image
- Click in the video window to capture mouse (middle click or F12 or Alt-tab to release)
- Use the debugger windows to breakpoint, inspect CPU, memory and hardware state.
Emulator limitations
The emulator is working but certainly not finished.
- No audio
- No bitter fill mode (enjoy some 3D software in glorious wireframe)
- Emulator vertical sync locked to host display refresh rate
- Middling compatibility (approx 50% of games work, far fewer demos)
- Poor runtime performance sorry
- Copper horizontal timing a bit off
- No interlace and buggy hires sometimes
- No sprite collisions
- Inaccurate CPU timing hardware synchronisation (affects accuracy)
- Only one floppy drive
- No write to disk
- No hard drive
- OCS only
- No niceties such as savestates etc
See the games lists later in this post to see how this affects compatibility.
Implementing the emulator
The CPU emulator was born when I wanted to implement dynamic analysis of the disassembly, which required an 68000 instruction interpreter. Learning from my mistakes on a previous unfinished emulator project (buggy Sega SG-1000 / MSX) I hunted out some excellent SingleStepTests (1 and 2) and made sure my CPU passed them all.
The best advice I had for implementing and Amiga emulator was from r/EmuDev/ where someone said "You should be aiming to execute the system ROM". This gave me a clear purpose. Armed with a 1.3 system ROM binary and an extremely helpful 1.2 Exec disassembly (they're quite similar) from back in the day I set about it. I was surprised how much hardware the system ROM requires - almost all of it: CPU (obviously), CIA, blitter, DMA, copper and eventually the disk controller. This eventually lead to the Strap module, which does two things: 1. draws the Kickstart hand and disk image 2. Loads the bootblock from the inserted disk.
I have a very comprehensive Kickstart1.3.cnf that I would love to include in the package, but I have not yet managed to get permission.
The CIA chips were well documented and straightforward to emulate and write comprehensive tests for to ensure they don't break.
The Blitter was quite a big job, but it was well documented and understood. The Strap module uses blitter line filll and transfer (copy) mode to draw the image. Surprisingly, the trackdisk module uses the blitter to decode MFM buffers. It does not use blitter fill mode - this is why it is still not implemented! I had a lot of fun writing the blitter, but I suspect there may be a bug because there is corruption in some games. The blitter was testable, but more difficult.
The copper was quite fun to implement. It has quite a lot of undocumented behaviour. Lots of thanks to the guys on EAB for helping me out with this. In fact, the 1.3 ROM relies on undocumented blitter stop behaviour when it tries to write to an invalid register. This is a bug in the ROM copperlist, but it worked!
The Denise video out I have found tough. The Amiga's timing is quite complex, with Agnus and Denise loosely coupled, and lots of pipelining and cycle delays to confuse matters. Also, the famous DMA Time Slot Allocation diagram in the Hardware Reference Manual is incorrect! The cycle numbers have been biased to aid comprehensibility - fine for Amiga programmers, but not for emulator writers. Again, many thanks to Toni Willen and Ross of WinUAE fame for explaining this stuff. Denise is fed bitplane and sprite data by DMA and processes it. I've been fixing this until the last minute of this release, and it is still not quite right. In my implementation, performance is poor for this part. It needs work.
The DMA manager is the beating heart of the Amiga. Every cycle, it chooses which single device (sprite, disk, bitplane, audio, blitter, copper, CPU) is allowed access to the chip bus, which is usually to read or write from Chip RAM. This is reasonably straightforward, but there are some little quirks like the blitter needing the bus to be free to tick, even if it doesn't actually need the bus, and there are some strange edge effects I have not even tried to emulate. I think I have some copper timing problems here because both Shadow of the Beast and Lionheart (see image above) copper writes do not line up with the bitplane output. I had some great help and advice from the EmuDev Discord when it came to implementing busses: the bus implements the address map! I have added a WinUAE like DMA debugging overlay to the Video window to help me to debug the emulator, but it should also be handy for debugging software.
Emulating a mechanical floppy drive was great fun. First job was to convert ADF images into Amiga Trackdisk format (which uses MFM encoding), then emulate the motor, heads and signals to and from the CIA chips. I would like to add IPF/SPS support in the future. This part of the emulation is embarassingly slow because mechanical components are stepped at electronic frequencies so not to miss sampling bitcells on the spinning disk. This could be simplifed a lot, and will be. This is why only 1 drive is supported for now!
After I got the ROM working I had to get Workbench loading, then games playing.
Some unplanned features that went in to improve compatibility included:
- The DSKSYNC register, not used by the ROM, but used my most custom trackloaders
- Disk index pulse (Rainbow Islands, Speedball, James Pond loaders)
- Sprite-playfield priority control logic (Apidya, First Samurai, Shadow of the Beast, Uridium 2)
- Extra Half Brite (Pinball Dreams)
- HAM (Menace, Great Giana Sisters, Uridium 2)
- Dual playfield (Katakis, Shadow of the Beast)
Using the ira disassembler with the emulator
This workflow will be improved in a future release, but is possible with a little effort.
You will need an image on disk of the binary data you want to disassemble. This can be saved from Aira by breakpointing and saving memory. For example to disassemble a bootblock, set the "Break when PC in RAM" option (or breakpoint at 5C4C for stock A500!) and save 1024 bytes from 5C40.
When the binary is saved for disk, File > New Project, to configure the disassembly. This will open the interactive ira disassembly view. Now you should be able to use the disassembler and debugger in tandem to step and interactively add comments, labels etc.
This workflow is not well tested sorry, but should work well for single-load games and has been tested on Wicked.
Thanks
Many thanks to everyonewho has helped me with this release, especially PHX for ira support, Toni and Ross on EAB for demystifying this wonderful machine, and everyone who has tested pre-releases and provided valuable feedback to improve the tool.
Changelog
- Add: Amiga CIA 8520 emulation
- Add: Amiga Sprite emulation (no collisions)
- Add: Amiga Hires playfield emulation (buggy)
- Add: Amiga blitter emulation (copy, line but no fill)
- Add: Amiga interrupt emulation
- Add: Amiga bitplane, sprite, copper and disk DMA emulation
- Add: Amiga copper emulation
- Add: Amiga DSKSYNC register emulation (trackloader support)
- Add: Amiga disk controller emulation
- Add: Amiga Mouse, joystick and keyboard emulation
- Add: Amiga ADF disk support
- Add: Amiga Kickstart 1.2/1.3 ROM emulation support
- Add: Many logging options
- Add: USB joystick support
- Add: CIA window
- Add: Amiga Copper (disassembly) window
- Add: Amiga Exec (OS) window
- Add: Dynamic Analysis window (replaces LiveAnalysis window)
- Add: Floppy drives window with ADF, MFM, disk visualisation
- Add: Memory disassembly window
- Add: Memory viewer (visualiser) Window
- Add: TypeInfo window (see included *.json)
- Add: Watch window(s) with type info support
- Add: UI to set breakpoint by address
- Add: Break when PC in RAM option
- Add: Break on vertical blank option
- Add: Break on system call option
- Add: CPU history window
- Add: Watchpoints window
- Add: Disassembler external symbols support and window
- Add: FIXLABELS disassembler option (default: disabled)
- Add: Configurable host input options (pad, keys, mouse)
- Improve: Amiga Window (lots more state)
- Improve: Update to ira V2.11
- Improve: Update vasm to 2.0a
- Improve: Update dear imgui to v1.91.4
- Improve: Video window DMA overlay
- Improve: Add filter to Equates Window
- Improve: Live Analysis is now Dynamic analysis
- Fix: Preserve leading whitespace in comments and banners
- Fix: Pressing E on label causes crash
- Fix: Leading whitespace preserved in banners
- Fix: Filenames containing whitespace support on Linux
- Fix: Store imgui.ini in user folder (guaranteed writable)
- Fix: Bugs in 68000 (CHK, DIVU, DIVS, ASR.x, LINK A7, and MOVE to SR instructions)
- Fix: Include CR when searching for text
"No blitter waits"
Games marked with "no blit waits" in the below list have been written without code to make the CPU wait for the blitter to finish before starting another blit. On a fixed machine like the A500, coders could get away with this because they knew the CPU code would take long enough to run to avoid overlaps.
The Aira emulator uses a hardware "catch-up" model: the CPU executes an instruction, which takes say 4 cycles and then the hardware steps forward by the number of cycles it took to catch back up. The CPU timing model I had in place was very simple: 4 cycles per memory access, and hardware did not block the CPU from the Chip bus. This meant that the CPU was running far too fast and this caused lots of blits to overlap - a serious cause of incompatibility.A
I added some code to catch blits that were kicked off while a previous blit was still in flight and was shocked by how many games it fired on! So, I spent a few hours adding more accurate cycle counts for every emulated instruction's cycle count using the fantastic cbmeeks/Yacht.txt 68000 timing document. Then I updated the hardware emulation "catch-up" to add CPU wait states on bus cycles used by hardware DMA. This made a huge difference to compatibility - suddenly many games started working.
Games confirmed to work
I've tested some of my favourite games, and added some notes on which hardware features were required to run them.
- Addams Family
- Alien Breed - Special Edition 92 (1MB)
- Amegas (No ball vs enemy or enemy vs bat collisions - hardware sprite collisions)
- Another World (wireframe without blitter fill mode!)
- Apidya (Corrupt bitmap HUD. BPLCON2 sprite-playfield priority required for powerup highlight)
- Arkanoid
- Arkanoid - Revenge of Doh (No blit waits)
- ATR - All Terrain Racing (1MB or black screen)
- Barbarian - The Ultimate Warrior (press F1 to start game)
- Battle Squadron (no blit waits)
- Billard Americain
- Biplanes ("bip" 2 player game)
- Blues Brothers
- Bubble Bobble
- Cannon Fodder (some versions)
- Deflektor (fire button sometimes not detected on main menu)
- Dyna Blaster (PAL fixed version)
- Jumping Jack'Son
- Fire and Ice
- First Samurai (BPLCON2 sprite-playfield priority required else moon in foreground)
- Great Giana Sisters (HAM title screen)
- Gods
- IK+
- Hybris (no blit waits)
- Insanity Fight (jerky scroller - host sync issue?)
- James Pond 2 - Codename RoboCod (Jerky scrolling - host sync issue? No blit waits)
- Katakis (Dual playfield title screen)
- Killing Game Show
- Laser Squad
- Lemmings
- Lionheart (white screen? press LMB. Hires interlace title screen. Copper vs bitplane horizontal sync off)
- Lotus Esprit Turbo Challenge
- Lotus Turbo Challenge 2
- Manic Miner (Arrow sprite not shown on main menu: undocumented BPLCON2 PF2P and PF1P values. HAM main menu)
- Marble Madness
- Mega lo Mania (Intro hangs after a few screens; game fine if skipped)
- Moonstone (1 MB)
- Nebulus
- Nitro
- Pac-Mania (no blit waits)
- Pang (no blit waits)
- Pinball Dreams (Ball not detected by flashing gaps at the top - hardware sprite collisions maybe? Uses EHB for intro screens and in-game)
- Pinball Fantasies (corrupt hires intro screens and main menu)
- Project-X
- Rainbow Islands (loader requires disk index pulse (CIA B ICR FLAG bit 4))
- Rick Dangerous (no blit waits)
- RoboCop (no bit waits)
- Rock'n Roll
- Rod-Land (HUD at made entirely of sprites! - see Codetapper article)
- R-Type [TTE]
- Santatron (Nivrig Games) (1 MB or fails to load)
- Secret of Monkey Island (virtual machine inside virtual machine!)
- Sensible Soccer (Fails with 1 MB! Main menu corruption)
- Sensible World of Soccer *Requires 1 MB" Main menu corruption)
- Shadow of the Beast (copper horizontal sync a bit off)
- Shadow of the Beast II
- Shadow of the Beast III (copper horizontal sync a bit off)
- SimCity
- Speedball (loader requires disk index pulse (CIAB ICR FLAG bit 4). No blit waits)
- Speedball 2 - Brutal Deluxe
- Strider
- Stunt Car Racer
- Superfrog
- Switchblade (no blit waits)
- SWIV (Missing blitter waits so requires accurate CPU timings. HUD text requires undocumented BPLCON2 behaviour)
- SWIV AGA fix version (Doesn't require accurate timing because blit waits in place! HUD text requires undocumented BPLCON2 behaviour)
- ThunderCats
- Toki
- Untouchables
- Uridium 2 (1 MB else yellow screen! HAM interlace loading screen. BPLCON2 sprite-playfield priority required for stars)
- Venus - The Flytrap (no blit waits)
- Virus
- Wicked
- Wizball (No blit waits)
- Xenon
- Xenon II [TTE]
- X-Out
- Yolanda
- Zool
- Z-Out
Games with serious problems
I suspect many of these titles fail due to inaccurate timing or missing hardware features - see the nostes. If you figure out why any games are not working please let me know.
- Agony (stuck waiting for audio interrupt)
- B.C. Kid (Freeze after title screen)
- Batman: The Movie (loader fails immediately)
- Bill's Tomato Game (Needs to save to disk (copy protection).
- Blood Money (stuck waiting for audio interrupt)
- Buggy Boy (When crash, stuck waiting for blitter finished interrupt?)
- Chaos Engine (loader fails)
- Defender of the Crown (Couldn't make scene!" when disk 2 inserted)
- Dune II (Requires write enabled save disk to be inserted on DOS screen)
- Flood (Magenta screen of doom on load)
- Iridon (Hardware sprite collisions required)
- James Pond (Hardware sprite collision required for environment collisions? No blit waits. Loader requires disk index pulse (CIAB ICR))
- Menace (Hardware sprite collisions required for pickups? No blit waits. Bullets sometimes left on screen.)
- New Zealand Story (Cutscene hangs waiting for audio interrupts)
- Prince of Persia (1 MB or red screen. Can press fire to start, but can't move - like Turrican 2?)
- Projectyle
- Star Wars - DOS Software Error dialogue
- Supercars (stuck waiting for audio interrupt)
- Supercars II (same?)
- Turrican II (Can fire but can't move. No blit waits)
- Worms (1 MB Chip and ECS only?)
Files
Get Aira Force
Aira Force
Advanced/Amiga Interactive ReAssembler and emulator
Status | In development |
Category | Tool |
Author | howprice |
Tags | Amiga, assembler, assembly-language, debugger, disassembler, Emulator, Graphical User Interface (GUI), Retro, reverse-engineering, User Interface (UI) |
Languages | English |
More posts
- Emulator update39 days ago
- Aira Force 0.8 releasedSep 05, 2024
- Aira Force 0.7.6 now availableJul 12, 2024
- Updated Windows 0.7.5 packagesJul 07, 2024
- Aira Force 0.7.5 now availableJul 05, 2024
Leave a comment
Log in with itch.io to leave a comment.