Looking for the Floppy Controller
After the splash screen, the firmware kept running — but reaching the floppy disk controller turned out to be a detective story involving delay loops, keyboard scanners, and SCSI detection.
The Delay Wall
After the "ENSONIQ ASR-10" splash screen appeared on the virtual LCD, the firmware continued executing. We expected it to move quickly toward the floppy disk controller — after all, the next logical step in the boot sequence is loading the OS from disk. Instead, the CPU landed at FFFB8D6C and stayed there. For a long time.
Initially, we thought this was the keyboard scanner — the routine that polls the front panel buttons for user input. The address was right in the neighborhood of the keyboard handling code. But the disassembly told a different story:
[FFFB8D6C] MOVE.L #$1000, D3 ; D3 = 4096 iterations[FFFB8D72] CMP.L D0, D0 ; NOP (sets Z flag)[FFFB8D74] PUSH D0 ; waste cycles[FFFB8D76] POP D0 ; waste more cycles[FFFB8D78] SUBQ.L #1, D3 ; decrement counter[FFFB8D7A]BNE FFFB8D72; loop until D3 = 0[FFFB8D7C] RTS ; Not a keyboard scanner -- just a massive delay loop.; CMP/PUSH/POP/SUBQ/BNE x 4096 = millions of wasted cycles.D3 loaded with 0x1000 = 4,096 iterations. Each iteration burns thousands of cycles with pointless CMP/PUSH/POP instructions before decrementing and looping. This wasn't a keyboard scanner at all — it was a hardware timing delay, the kind you insert when you need to wait for analog circuits to settle or external chips to initialize. On real hardware, these delays are essential. In an emulator, they're a brick wall.
We let the emulator run for 100 million emulated cycles. The firmware was still inside this loop. And this subroutine was being called from multiple places throughout the boot sequence — the firmware uses it as a general-purpose "wait a while" function.
NOP Surgery
The solution was surgical. We searched the entire ROM for every JSR FFFB8D6C call — the 68000 opcode sequence 4EB9 FFFB 8D6C. The search found 8 call sites scattered throughout the boot code:
$ python3 find_calls.py --pattern "4EB9 FFFB 8D6C" rom.bin
Found 8 occurrences: [1] offset 0x39B82 (PC: FFF9BB82) [2] offset 0x39B9A (PC: FFF9BB9A) [3] offset 0x39C04 (PC: FFF9BC04) [4] offset 0x39C1E (PC: FFF9BC1E) [5] offset 0x3A210 (PC: FFFA2210) [6] offset 0x3A244 (PC: FFFA2244) [7] offset 0x3B36C (PC: FFFB336C) [8] offset 0x3B398 (PC: FFFB3398) Each JSR is a 6-byte instruction (4EB9 + 4-byte absolute address). We replaced all 8 with three NOP instructions (4E71 4E71 4E71) — same size, no side effects. The firmware would execute the NOPs in a few cycles instead of burning millions in the delay loop.
We hit run again. The firmware moved. Past the delay wall, into new code we hadn't seen before.
SCSI Discovery
With the delays eliminated, the firmware reached its SCSI detection routine. New messages appeared on the virtual LCD:
[LCD line 1]ENSONIQ ASR-10[LCD line 2]SCSI INSTALLED[LCD line 2]SEARCHING FOR SCSI DEV The firmware was probing the SCSI bus at 0x410000. Our mock SCSI controller was returning values from its status registers — enough to make the firmware believe a SCSI interface was present. It detected the controller, displayed "SCSI INSTALLED", then began scanning for devices on the bus.
On a real ASR-10, this is where the machine checks for an external SCSI hard drive — a popular expansion that gave musicians fast access to large sample libraries without swapping floppy disks. The "SEARCHING FOR SCSI DEV" message would display briefly while the bus scan completed, then the firmware would move on to the floppy controller regardless of whether SCSI devices were found.
The Keyboard Wait
After the SCSI scan, the firmware hit another blocking point. This time at FFFBB26C:
[FFFBB26C]BTST #7, (A4); test bit 7 of register[FFFBB270]BEQ FFFBB26C; if zero: loop forever; A4 = $FC4001 = keyboard SCC register; Bit 7 = RxRDY (receive data ready); Firmware is waiting for user to press a button.BTST #7, (A4) with A4 pointing to FC4001 — the keyboard SCC (Serial Communication Controller). Bit 7 is the RxRDY flag: "data has been received." The firmware was waiting for the user to press a button on the front panel. On the real ASR-10, this is the moment where the machine displays a message and waits for acknowledgment — perhaps "PRESS ENTER TO CONTINUE" or similar.
The BEQ * pattern (branch-to-self when equal) is the tightest possible polling loop: test the bit, if it's not set, test it again. Forever. There's no timeout, no fallback. The firmware will wait here until the heat death of the universe or until someone presses a button.
We patched it. The BEQ FFFBB26C instruction (opcode 67FA) was replaced with a NOP (4E71). The firmware fell through the loop and continued.
ROM Surgery
At this point, the accumulated ROM patches formed a clear picture of what we'd bypassed to get the firmware moving. Here's the complete surgical record:
; ASR-10 ROM Patches -- cumulative list; All patches preserve instruction alignment (same byte count)PATCH 1 BSR $FFF8A0AE -> NOP NOP ; Skip DOC/DSP init verification loop; Original: 6100 04D8 -> 4E71 4E71PATCH 2 JSR $FFFB8D6C -> NOP NOP NOP (8 locations); Skip delay loops throughout boot sequence; Original: 4EB9 FFFB 8D6C -> 4E71 4E71 4E71PATCH 3 BEQ * -> NOP ; Skip keyboard wait at FFFBB26C; Original: 67FA -> 4E71 Every patch follows the same principle: replace a blocking instruction with NOPs of the same byte length. No code is shifted, no addresses change, no branch targets break. The firmware continues executing as if the operation completed instantly. It's the reverse engineering equivalent of telling the machine "yes, the hardware responded, trust me."
The Floppy Vocabulary
With the firmware now running past all the blocking points, we turned to the ROM's string table to understand what lay ahead. Searching for disk-related ASCII strings revealed the complete vocabulary of the floppy disk subsystem:
$ strings -n 8 rom.bin | grep -i disk
PLEASE INSERT DISKLOADING SYSTEMDISK NOT FORMATTEDBAD DISK/NOT EPS DISKDISK OPERATION SUCCESSDISK DRIVE NOT READYDISK DATA CORRUPTEDO.S. DISKSAVING TO DISKFORMATTING DISKEvery message the ASR-10 could ever display about its floppy drive was sitting right there in ROM, waiting to be triggered. "PLEASE INSERT DISK" — the message every ASR-10 owner knows. It's what the machine displays at power-on when there's no OS disk in the drive. "LOADING SYSTEM" appears while reading the OS. "BAD DISK/NOT EPS DISK" fires when the disk format isn't recognized — note the reference to "EPS", the ASR-10's predecessor (Ensoniq Performance Sampler), confirming that the ASR-10 can read EPS-format disks.
"DISK DATA CORRUPTED" is the message no musician ever wants to see — it means the OS loaded but failed a checksum or validation check. And "O.S. DISK" is the label the firmware looks for in the disk directory to identify a bootable operating system disk.
The strings tell us the firmware has a complete, robust disk subsystem with error handling for every failure mode: missing disk, unformatted disk, wrong format, corrupted data, drive not responding. Ensoniq's engineers built this for musicians who would be using floppy disks on stage and in studios — every error needed a clear, human-readable message.
What's Next
The firmware was now running through the boot sequence at full speed, past the DSP init, past the delays, past the SCSI scan, past the keyboard wait. The floppy controller vocabulary was mapped. The question was: would the firmware actually reach the "PLEASE INSERT DISK" prompt, or would there be more walls to climb?
There was only one way to find out. We let the emulator run.
Next: the firmware reaches the floppy disk prompt, and we discover why no FDC registers are being polled. Read the conclusion in Please Insert Disk.
