====== LC //e Card - Weird Stuff: Opcode $02 ====== ===== Weird Beep ===== The %%//e%% Card is able to replace the standard Apple II beep with a Macintosh sound. The means by which this is accomplished is quite interesting. The routine at $fbdd (BELL1) is .org $fbdd ; this code replaces the .1 second delay .byte $02 ; two byte NOP in 65C02 .byte $01 ; should be ignored by CPU rts nop nop ; remaining code matches the original //e code and calling $fbe2 ; will produce a beep, at the wrong pitch if the card is in fast mode. $02 is a two-byte NOP on the 65C02 (if it was an '802 or '816 it'd be a COP). Interestingly enough, when the processor on the Card executes the sequence $02 $01, it produces the configured beep sound. Try this in the monitor: *300:02 01 02 01 02 01 60 *300G Three beep sounds! So this must be part of the magic that interfaces the card to the host Macintosh. How very very interesting. ===== Other Weird Instructions ===== The preceding find led me to search through the monitor ROM to look for other unusual instruction sequences. Here is what I found: ^ In Routine ^ Address ^ Code ^ Function ^ | PWRUP | $FAB4 | $02 $02 | Loads A reg with $Cn+1 where n = startup slot or $C8 if scan. | | PWRUP | $FAC0 | $02 $03 | Displays "UNABLE TO BOOT FROM STARTUP SLOT" if A reg = $Cn-1 where n = startup slot or $c0 if scan. Disappears if screen scrolls. | | APPLEII | $FB63 | $02 $04 | Display copyright message on screen, disappears if screen scrolls. | | BELL1 | $FBDD | $02 $01 | Play system bell sound. | | GETLN1 | $FD78 | $02 $06 | Key translation called right after rdchar. If A reg has DELETE, converts it to <-. | | | | $02 $05 | Not found in firmware, yet, but presumably this exists. | ==== The Key Translation and the A register ==== Get to the monitor in your %%//%%e Card and try this: *! !300:jsr fd35 ! nop ! nop ! jmp fdda ! *300G FD35 is the RDCHAR routine, FDDA is the print byte routine. This routine reads a keypress and outputs its hex code. Run it a few times to convince yourself there is no funny business. Run it a final time and press DELETE. *300G FF (appears after pressing delete) * FF is exactly what we expect to see with the Apple II delete key. Now want to see something interesting? Change the NOPs to $02 $06 and run it again. Try a few keys, then try it with DELETE. *303:02 06 *300G 88 (appears after pressing delete) * 88 is the code for the left arrow key. That's some serious magic, and in two bytes the Card converts DELETE to <-. ==== The Two-Byte Copyright ==== Try this sequence of instructions: ]HOME ]CALL -151 *300:02 04 60 *300G Hit the left arrow a bunch of times until the display scrolls. **POOF!** ==== Slot Scan Scam ==== The %%//%%e Card lets the user pick the startup slot in the control panel or "Scan" which is the behavior of a standard %%//%%e. This is implemented by the sequences $02 $02 which replaces the LDA #$C8 at the start of the slot scan loop, and $02 $03 which replaces the CMP #$C0 instruction that decides loop termination. The $02 $02 sequence loads the accumulator with $C8 if scan is selected, or $Cn+1 if a specific slot is selected. *300:02 02 4C DA FD *300G C8 (if scan or slot 7 selected, "Cx" if another slot is selected) * The $02 $03 sequence behaves as if CMP #$C0 or CMP #$Cn-1 has been executed and if it has, displays "UNABLE TO BOOT FROM STARTUP SLOT" in the center of the screen in a similar manner to the copyright message. The message is not in Apple II memory. It returns with the flags set as executing the CMP instruction would have. My ''iie.card'' [[https://github.com/mgcaret/davex-mg-utils/blob/master/iie.card.s|utility]] for Davex can exploit this to determine which slot is configured for startup via the [[https://github.com/mgcaret/davex-mg-utils/blob/master/iie.card.s#L118|dispslot routine]].