Close

20230223a - Special Keys and File Ops

A project log for ROM Disassembly - AlphaSmart Pro

Wherein I disassemble the ROM from a vintage typewriter-thing

ziggurat29ziggurat29 02/25/2023 at 15:031 Comment

While revisiting key handler handleKeyScanCode_EE37 and back annotating scan codes into the code, I wind up with this:

EE37             handleKeyScanCode_EE37:
EE37 13 63 01 04     brclr   bCloverKeyDown_63 1 noclover_EE3F ; true if 'clover key down'
EE3B 12 61 01 C9     brset   bAltKeyDown_61 1 optionclover_EE08 ; true if 'alt/option key down'
EE3F             noclover_EE3F:
EE3F 13 64 01 02     brclr   bShiftKeyDown_64 1 cont_EE45 ; true if 'shift key down'
EE43 8A 80           oraa    #$80            ; set high bit in base scan code to mark as shifted
EE45             cont_EE45:
EE45 97 70           staa    scratch_70      ; save the scan code for later
EE47 81 56           cmpa    #$56            ; 'Clear File' scan code
EE49 27 DD           beq     doDeleteFile_EE28
EE4B 81 2B           cmpa    #$2B            ; 'Delete' scan code
EE4D 27 28           beq     doDeleteChar_EE77 ; delete a char in file?
EE4F 81 35           cmpa    #$35            ; 'arrow Left' scan code
EE51 27 2A           beq     doLeft_EE7D
EE53 81 34           cmpa    #$34            ; 'arrow Right' scan code
EE55 27 36           beq     doRight_EE8D
EE57 81 37           cmpa    #$37            ; 'arrow Up' scan code
EE59 27 40           beq     doUp_EE9B
EE5B 81 15           cmpa    #$15            ; 'arrow Down' scan code
EE5D 27 4A           beq     doDown_EEA9
EE5F 81 66           cmpa    #$66            ; 'Home' scan code
EE61 27 54           beq     doHome_EEB7
EE63 81 75           cmpa    #$75            ; 'End' scan code
EE65 27 55           beq     doEnd_EEBC
EE67 81 2D           cmpa    #$2D            ; 'Caps lock' scan code
EE69 27 56           beq     toggleCapLock_EEC1
EE6B 7E EF 67        jmp     loc_EF67
EE6E             loc_EE6E:
EE6E 7E EE C9        jmp     normalChar_EEC9
EE71 BD F0 13        jsr     sub_F013        ; XXX prepare to send (flags and prompt)
EE74 7E EE E0        jmp     leave_EEE0
...

Now things are much clearer!  The various 'do XXX' locations are usual small, e.g.:

EEB7             doHome_EEB7:
EEB7 BD F1 6B        jsr     sub_F16B
EEBA 20 1E           bra     sub_EEDA

So it is reasonable that sub_F16B does whatever the 'Home' key does (probably move the insert point to the first char position and update the display as appropriate).

Others have modifiers:

EEA9             doDown_EEA9:
EEA9 13 63 01 05     brclr   bCloverKeyDown_63 1 doDownOnce_EEB2 ; true if 'clover key down'
EEAD BD EF 3D        jsr     sub_EF3D        ; XXX clover-down whacks F0DF handler four times
EEB0 20 28           bra     sub_EEDA
EEB2             doDownOnce_EEB2:
EEB2 BD F0 DF        jsr     sub_F0DF        ; XXX down arrow handler
EEB5 20 23           bra     sub_EEDA

So it seems that in this case that the cloverleaf modifier would go down a 'page' (of 4 LCD lines), whereas the unmodified version moves down a line.

In all these mini-handlers, there is a jump to sub_EEDA, which is brief:

EEDA             sub_EEDA:
EEDA BD F3 74        jsr     sub_F374
EEDD BD F2 56        jsr     sub_F256
EEE0             leave_EEE0:
EEE0 39              rts

This routine has a lot (22) references throughout the code.  Taking a quick peek at sub_F374, it starts with a call to clearHomeLCD_F618, fiddles with file related stuff, sends chars to the screen, and then ends with the 'caps lock indicator' mentioned a couple days ago.  So this feels like maybe the 'update screen for file state' function.  One sub-method was interesting:

F62D             sub_F62D:
F62D 81 09           cmpa    #9              ; less than TAB?
F62F 2D 19           blt     bogoChar_F64A
F631 85 80           bita    #$80            ; high ASCII?
F633 26 15           bne     bogoChar_F64A
F635 81 5C           cmpa    #'\'            ; ascii backslash looks like Yen on LCD, so translate
F637 27 15           beq     xlatbackslash_F64E
F639 81 7E           cmpa    #'~'            ; ascii tilde looks like right arrow on LCD, so translate
F63B 27 15           beq     xlattildeswinton_F652
F63D 81 0D           cmpa    #$D
F63F 27 15           beq     xlatcr_F656
F641 81 09           cmpa    #9
F643 27 15           beq     xlattab_F65A
F645 16              tab
F646             loc_F646:
F646 BD F6 74        jsr     sendLCDbyteB_F674 ; send byte in B to LCD (w/ctrl as per 0x5b)
F649 39              rts
F64A             bogoChar_F64A:
F64A C6 3F           ldab    #'?'            ; junk character maps to '?'
F64C 20 F8           bra     loc_F646
F64E             xlatbackslash_F64E:
F64E C6 8F           ldab    #$8F            ; LCD backslash char
F650 20 F4           bra     loc_F646
F652             xlattildeswinton_F652:
F652 C6 F3           ldab    #$F3            ; LCD infinity is an approximation of tilde
F654 20 F0           bra     loc_F646
F656             xlatcr_F656:
F656 C6 7F           ldab    #$7F            ; LCD left arrow indicates hard CR
F658 20 EC           bra     loc_F646
F65A             xlattab_F65A:
F65A C6 7E           ldab    #$7E            ; LCD right arrow indicates TAB
F65C 20 E8           bra     loc_F646

This clearly translates file ASCII into LCD characters.  Most of the LCD follows ASCII, but a few symbol positions have different glyphs, so this fixes those up.  Aside from understanding the code, the context is useful because it seems to suggest that sub_EEDA is in fact 'update display for current file'.  The first routine sub_F374 being 'do the showing file part'.  The second routine sub_F256 is briefer:

F256             sub_F256:
F256 86 28           ldaa    #40             ; (char per line)
F258 D6 6C           ldab    word_6B+1       ; XXX 0x0101 upon file cleared; row, col? 1-relative
F25A 5A              decb
F25B 3D              mul
F25C DB 6B           addb    word_6B         ; XXX 0x0101 upon file cleared; row, col? 1-relative
F25E 5A              decb
F25F 14 5B 01        bset    lcdCtlLineState_5B 1 ; set OC2,OC1 to 11; 'set cursor address'
F262 14 5B 02        bset    lcdCtlLineState_5B 2 ; LCD control lines state in b1 = IOC2, b0 = IOC1
F265 BD F6 74        jsr     sendLCDbyteB_F674 ; send byte in B to LCD (w/ctrl as per 0x5b)
F268 15 5B 01        bclr    lcdCtlLineState_5B 1 ; return OC2,1 to 10; 'data'
F26B 39              rts

It fiddles with the word_6B and does a set cursor address, so this seems to suggest word_6B is in fact two bytes and they are the row/col (1-relative) screen position of the cursor.  This will be useful to back annotate into the various other routines that use/manipulate these locations.

So, some more mysteries solved.  Time to comment and propagate info throughout.

Discussions

Eric Hertz wrote 02/26/2023 at 02:06 point

Whoa, jump after jump after jump!

Seems like a nightmare to backtrace!

Also, yet another character-encoding translation! Hah, four now?

  Are you sure? yes | no