Subversion Repositories NedoOS

Rev

Rev 984 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download

  1. ;; MASK-INT
  2. L0038   PUSH    AF              ; save the registers.
  3.         PUSH    HL              ; but not IY unfortunately.
  4.         LD      HL,(0x5C78)      ; fetch two bytes at FRAMES1.
  5.         INC     HL              ; increment lowest two bytes of counter.
  6.         LD      (0x5C78),HL      ; place back in FRAMES1.
  7.         LD      A,H             ; test if the result
  8.         OR      L               ; was zero.
  9.         JR      NZ,L0048        ; forward to KEY-INT if not.
  10.  
  11.         INC     (IY+0x40)        ; otherwise increment FRAMES3 the third byte.
  12.  
  13. ; now save the rest of the main registers and read and decode the keyboard.
  14.  
  15. ;; KEY-INT
  16. L0048   PUSH    BC              ; save the other
  17.         PUSH    DE              ; main registers.
  18.         CALL    L02BF           ; routine KEYBOARD executes a stage
  19.                                 ; in the process of reading a key-press.
  20.         POP     DE              ;
  21.         POP     BC              ; restore registers.
  22.         POP     HL              ;
  23.         POP     AF              ;
  24.         EI                      ; enable interrupts.
  25.         RET                     ; return.
  26.  
  27. ;-----------
  28. ; Key tables
  29. ;-----------
  30. ; These six look-up tables are used by the keyboard reading routine
  31. ; to decode the key values.
  32.  
  33. ; The first table contains the maps for the 39 keys of the standard
  34. ; 40-key Spectrum keyboard. The remaining key [SHIFT $27] is read directly.
  35. ; The key values 0-38 map to their ascii upper-case characters except for
  36. ; symbol-shift $0E.
  37.  
  38. ;; MAIN-KEYS
  39. L0205   DEFB    $42             ; B
  40.         DEFB    $48             ; H
  41.         DEFB    $59             ; Y
  42.         DEFB    $36             ; 6
  43.         DEFB    $35             ; 5
  44.         DEFB    $54             ; T
  45.         DEFB    $47             ; G
  46.         DEFB    $56             ; V
  47.         DEFB    $4E             ; N
  48.         DEFB    $4A             ; J
  49.         DEFB    $55             ; U
  50.         DEFB    $37             ; 7
  51.         DEFB    $34             ; 4
  52.         DEFB    $52             ; R
  53.         DEFB    $46             ; F
  54.         DEFB    $43             ; C
  55.         DEFB    $4D             ; M
  56.         DEFB    $4B             ; K
  57.         DEFB    $49             ; I
  58.         DEFB    $38             ; 8
  59.         DEFB    $33             ; 3
  60.         DEFB    $45             ; E
  61.         DEFB    $44             ; D
  62.         DEFB    $58             ; X
  63.         DEFB    $0E             ; SYMBOL SHIFT
  64.         DEFB    $4C             ; L
  65.         DEFB    $4F             ; O
  66.         DEFB    $39             ; 9
  67.         DEFB    $32             ; 2
  68.         DEFB    $57             ; W
  69.         DEFB    $53             ; S
  70.         DEFB    $5A             ; Z
  71.         DEFB    $20             ; SPACE
  72.         DEFB    $0D             ; ENTER
  73.         DEFB    $50             ; P
  74.         DEFB    $30             ; 0
  75.         DEFB    $31             ; 1
  76.         DEFB    $51             ; Q
  77.         DEFB    $41             ; A
  78.  
  79.  
  80. ;; E-UNSHIFT
  81. L022C   DEFB    $E3             ; READ
  82.         DEFB    $C4             ; BIN
  83.         DEFB    $E0             ; LPRINT
  84.         DEFB    $E4             ; DATA
  85.         DEFB    $B4             ; TAN
  86.         DEFB    $BC             ; SGN
  87.         DEFB    $BD             ; ABS
  88.         DEFB    $BB             ; SQR
  89.         DEFB    $AF             ; CODE
  90.         DEFB    $B0             ; VAL
  91.         DEFB    $B1             ; LEN
  92.         DEFB    $C0             ; USR
  93.         DEFB    $A7             ; PI
  94.         DEFB    $A6             ; INKEY$
  95.         DEFB    $BE             ; PEEK
  96.         DEFB    $AD             ; TAB
  97.         DEFB    $B2             ; SIN
  98.         DEFB    $BA             ; INT
  99.         DEFB    $E5             ; RESTORE
  100.         DEFB    $A5             ; RND
  101.         DEFB    $C2             ; CHR$
  102.         DEFB    $E1             ; LLIST
  103.         DEFB    $B3             ; COS
  104.         DEFB    $B9             ; EXP
  105.         DEFB    $C1             ; STR$
  106.         DEFB    $B8             ; LN
  107.  
  108.  
  109. ;; EXT-SHIFT
  110. L0246   DEFB    $7E             ; ~
  111.         DEFB    $DC             ; BRIGHT
  112.         DEFB    $DA             ; PAPER
  113.         DEFB    $5C             ; \
  114.         DEFB    $B7             ; ATN
  115.         DEFB    $7B             ; {
  116.         DEFB    $7D             ; }
  117.         DEFB    $D8             ; CIRCLE
  118.         DEFB    $BF             ; IN
  119.         DEFB    $AE             ; VAL$
  120.         DEFB    $AA             ; SCREEN$
  121.         DEFB    $AB             ; ATTR
  122.         DEFB    $DD             ; INVERSE
  123.         DEFB    $DE             ; OVER
  124.         DEFB    $DF             ; OUT
  125.         DEFB    $7F             ; (Copyright character)
  126.         DEFB    $B5             ; ASN
  127.         DEFB    $D6             ; VERIFY
  128.         DEFB    $7C             ; |
  129.         DEFB    $D5             ; MERGE
  130.         DEFB    $5D             ; ]
  131.         DEFB    $DB             ; FLASH
  132.         DEFB    $B6             ; ACS
  133.         DEFB    $D9             ; INK
  134.         DEFB    $5B             ; [
  135.         DEFB    $D7             ; BEEP
  136.  
  137.  
  138. ;; CTL-CODES
  139. L0260   DEFB    $0C             ; DELETE
  140.         DEFB    $07             ; EDIT
  141.         DEFB    $06             ; CAPS LOCK
  142.         DEFB    $04             ; TRUE VIDEO
  143.         DEFB    $05             ; INVERSE VIDEO
  144.         DEFB    $08             ; CURSOR LEFT
  145.         DEFB    $0A             ; CURSOR DOWN
  146.         DEFB    $0B             ; CURSOR UP
  147.         DEFB    $09             ; CURSOR RIGHT
  148.         DEFB    $0F             ; GRAPHICS
  149.  
  150.  
  151. ;; SYM-CODES
  152. L026A   DEFB    $E2             ; STOP
  153.         DEFB    $2A             ; *
  154.         DEFB    $3F             ; ?
  155.         DEFB    $CD             ; STEP
  156.         DEFB    $C8             ; >=
  157.         DEFB    $CC             ; TO
  158.         DEFB    $CB             ; THEN
  159.         DEFB    $5E             ; ^
  160.         DEFB    $AC             ; AT
  161.         DEFB    $2D             ; -
  162.         DEFB    $2B             ; +
  163.         DEFB    $3D             ; =
  164.         DEFB    $2E             ; .
  165.         DEFB    $2C             ; ,
  166.         DEFB    $3B             ; ;
  167.         DEFB    $22             ; "
  168.         DEFB    $C7             ; <=
  169.         DEFB    $3C             ; <
  170.         DEFB    $C3             ; NOT
  171.         DEFB    $3E             ; >
  172.         DEFB    $C5             ; OR
  173.         DEFB    $2F             ; /
  174.         DEFB    $C9             ; <>
  175.         DEFB    $60             ; pound
  176.         DEFB    $C6             ; AND
  177.         DEFB    $3A             ; :
  178.  
  179. ;; E-DIGITS
  180. L0284   DEFB    $D0             ; FORMAT
  181.         DEFB    $CE             ; DEF FN
  182.         DEFB    $A8             ; FN
  183.         DEFB    $CA             ; LINE
  184.         DEFB    $D3             ; OPEN#
  185.         DEFB    $D4             ; CLOSE#
  186.         DEFB    $D1             ; MOVE
  187.         DEFB    $D2             ; ERASE
  188.         DEFB    $A9             ; POINT
  189.         DEFB    $CF             ; CAT
  190.  
  191.  
  192. ;*******************************
  193. ;** Part 2. KEYBOARD ROUTINES **
  194. ;*******************************
  195.  
  196. ; Using shift keys and a combination of modes the Spectrum 40-key keyboard
  197. ; can be mapped to 256 input characters
  198.  
  199. ;----------------------------------------------------------------------------
  200. ;
  201. ;         0     1     2     3     4 -Bits-  4     3     2     1     0
  202. ; PORT                                                                    PORT
  203. ;
  204. ; F7FE  [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ]  |  [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 0 ]   EFFE
  205. ;  ^                                   |                                   v
  206. ; FBFE  [ Q ] [ W ] [ E ] [ R ] [ T ]  |  [ Y ] [ U ] [ I ] [ O ] [ P ]   DFFE
  207. ;  ^                                   |                                   v
  208. ; FDFE  [ A ] [ S ] [ D ] [ F ] [ G ]  |  [ H ] [ J ] [ K ] [ L ] [ ENT ] BFFE
  209. ;  ^                                   |                                   v
  210. ; FEFE  [SHI] [ Z ] [ X ] [ C ] [ V ]  |  [ B ] [ N ] [ M ] [sym] [ SPC ] 7FFE
  211. ;  ^     $27                                                 $18           v
  212. ; Start                                                                   End
  213. ;        00100111                                            00011000
  214. ;
  215. ;----------------------------------------------------------------------------
  216. ; The above map may help in reading.
  217. ; The neat arrangement of ports means that the B register need only be
  218. ; rotated left to work up the left hand side and then down the right
  219. ; hand side of the keyboard. When the reset bit drops into the carry
  220. ; then all 8 half-rows have been read. Shift is the first key to be
  221. ; read. The lower six bits of the shifts are unambiguous.
  222.  
  223. ;------------------
  224. ; Keyboard scanning
  225. ;------------------
  226. ; from keyboard and s-inkey$
  227. ; returns 1 or 2 keys in DE, most significant shift first if any
  228. ; key values 0-39 else 255
  229.  
  230. ;; KEY-SCAN
  231. L028E   LD      L,$2F           ; initial key value
  232.                                 ; valid values are obtained by subtracting
  233.                                 ; eight five times.
  234.         LD      DE,$FFFF        ; a buffer for 2 keys.
  235.        ld ix,keymatrix+7
  236.         LD      BC,$FEFE        ; the commencing port address
  237.                                 ; B holds 11111110 initially and is also
  238.                                 ; used to count the 8 half-rows
  239. ;; KEY-LINE
  240. L0296   ;IN      A,(C)           ; read the port to A - bits will be reset
  241.                                 ; if a key is pressed else set.
  242.        ld a,(ix)
  243.        dec ix
  244.         CPL                     ; complement - pressed key-bits are now set
  245.         AND     $1F             ; apply 00011111 mask to pick up the
  246.                                 ; relevant set bits.
  247.  
  248.         JR      Z,L02AB         ; forward to KEY-DONE if zero and therefore
  249.                                 ; no keys pressed in row at all.
  250.  
  251.         LD      H,A             ; transfer row bits to H
  252.         LD      A,L             ; load the initial key value to A
  253.  
  254. ;; KEY-3KEYS
  255. L029F   INC     D               ; now test the key buffer
  256.         RET     NZ              ; if we have collected 2 keys already
  257.                                 ; then too many so quit.
  258.  
  259. ;; KEY-BITS
  260. L02A1   SUB     $08             ; subtract 8 from the key value
  261.                                 ; cycling through key values (top = $27)
  262.                                 ; e.g. 2F>   27>1F>17>0F>07
  263.                                 ;      2E>   26>1E>16>0E>06
  264.         SRL     H               ; shift key bits right into carry.
  265.         JR      NC,L02A1        ; back to KEY-BITS if not pressed
  266.                                 ; but if pressed we have a value (0-39d)
  267.  
  268.         LD      D,E             ; transfer a possible previous key to D
  269.         LD      E,A             ; transfer the new key to E
  270.         JR      NZ,L029F        ; back to KEY-3KEYS if there were more
  271.                                 ; set bits - H was not yet zero.
  272.  
  273. ;; KEY-DONE
  274. L02AB   DEC     L               ; cycles 2F>2E>2D>2C>2B>2A>29>28 for
  275.                                 ; each half-row.
  276.         RLC     B               ; form next port address e.g. FEFE > FDFE
  277.         JR      C,L0296         ; back to KEY-LINE if still more rows to do.
  278.  
  279.         LD      A,D             ; now test if D is still FF ?
  280.         INC     A               ; if it is zero we have at most 1 key
  281.                                 ; range now $01-$28  (1-40d)
  282.         RET     Z               ; return if one key or no key.
  283.  
  284.         CP      $28             ; is it capsshift (was $27) ?
  285.         RET     Z               ; return if so.
  286.  
  287.         CP      $19             ; is it symbol shift (was $18) ?
  288.         RET     Z               ; return also
  289.  
  290.         LD      A,E             ; now test E
  291.         LD      E,D             ; but first switch
  292.         LD      D,A             ; the two keys.
  293.         CP      $18             ; is it symbol shift ?
  294.         RET                     ; return (with zero set if it was).
  295.                                 ; but with symbol shift now in D
  296.  
  297. ;-------------------------------
  298. ; Scan keyboard and decode value
  299. ;-------------------------------
  300. ; from interrupt 50 times a second
  301. ;
  302.  
  303. ;; KEYBOARD
  304. L02BF   CALL    L028E           ; routine KEY-SCAN
  305.         RET     NZ              ; return if invalid combinations
  306.  
  307. ; then decrease the counters within the two key-state maps
  308. ; as this could cause one to become free.
  309. ; if the keyboard has not been pressed during the last five interrupts
  310. ; then both sets will be free.
  311.  
  312.  
  313.         LD      HL,$5C00        ; point to KSTATE-0
  314.  
  315. ;; K-ST-LOOP
  316. L02C6   BIT     7,(HL)          ; is it free ?  ($FF)
  317.         JR      NZ,L02D1        ; forward to K-CH-SET if so
  318.  
  319.         INC     HL              ; address 5-counter
  320.         DEC     (HL)            ; decrease counter
  321.         DEC     HL              ; step back
  322.         JR      NZ,L02D1        ; forward to K-CH-SET if not at end of count
  323.  
  324.         LD      (HL),$FF        ; else mark it free.
  325.  
  326. ;; K-CH-SET
  327. L02D1   LD      A,L             ; store low address byte.
  328.         LD      HL,$5C04        ; point to KSTATE-4
  329.                                 ; (ld l, $04)
  330.         CP      L               ; have 2 been done ?
  331.         JR      NZ,L02C6        ; back to K-ST-LOOP to consider this 2nd set
  332.  
  333. ; now the raw key (0-38) is converted to a main key (uppercase).
  334.  
  335.         CALL    L031E           ; routine K-TEST to get main key in A
  336.         RET     NC              ; return if single shift
  337.  
  338.         LD      HL,$5C00        ; point to KSTATE-0
  339.         CP      (HL)            ; does it match ?
  340.         JR      Z,L0310         ; forward to K-REPEAT if so
  341.  
  342. ; if not consider the second key map.
  343.  
  344.         EX      DE,HL           ; save kstate-0 in de
  345.         LD      HL,$5C04        ; point to KSTATE-4
  346.         CP      (HL)            ; does it match ?
  347.         JR      Z,L0310         ; forward to K-REPEAT if so
  348.  
  349. ; having excluded a repeating key we can now consider a new key.
  350. ; the second set is always examined before the first.
  351.  
  352.         BIT     7,(HL)          ; is it free ?
  353.         JR      NZ,L02F1        ; forward to K-NEW if so.
  354.  
  355.         EX      DE,HL           ; bring back kstate-0
  356.         BIT     7,(HL)          ; is it free ?
  357.         RET     Z               ; return if not.
  358.                                 ; as we have a key but nowhere to put it yet.
  359.  
  360. ; continue or jump to here if one of the buffers was free.
  361.  
  362. ;; K-NEW
  363. L02F1   LD      E,A             ; store key in E
  364.         LD      (HL),A          ; place in free location
  365.         INC     HL              ; advance to interrupt counter
  366.         LD      (HL),$05        ; and initialize to 5
  367.         INC     HL              ; advance to delay
  368.         LD      A,($5C09)       ; pick up system variable REPDEL
  369.         LD      (HL),A          ; and insert that for first repeat delay.
  370.         INC     HL              ; advance to last location of state map.
  371.  
  372.         LD      C,(IY+$07)      ; pick up MODE  (3 bytes)
  373.         LD      D,(IY+$01)      ; pick up FLAGS (3 bytes)
  374.         PUSH    HL              ; save state map location
  375.                                 ; Note. could now have used.
  376.                                 ; ld l,$41; ld c,(hl); ld l,$3B; ld d,(hl).
  377.                                 ; six and two threes of course.
  378.         CALL    L0333           ; routine K-DECODE
  379.         POP     HL              ; restore map pointer
  380.         LD      (HL),A          ; put decoded key in last location of map.
  381.  
  382. ;; K-END
  383. L0308   LD      ($5C08),A       ; update LASTK system variable.
  384.         SET     5,(IY+$01)      ; FLAGS  - signal new key.
  385.         RET                     ; done
  386.  
  387. ;-------------------
  388. ; Repeat key routine
  389. ;-------------------
  390. ; A possible repeat has been identified. HL addresses the raw (main) key.
  391. ; The last location holds the decoded key (from the first context).
  392.  
  393. ;; K-REPEAT
  394. L0310   INC     HL              ; advance
  395.         LD      (HL),$05        ; maintain interrupt counter at 5
  396.         INC     HL              ; advance
  397.         DEC     (HL)            ; decrease REPDEL value.
  398.         RET     NZ              ; return if not yet zero.
  399.  
  400.         LD      A,($5C0A)       ; REPPER
  401.         LD      (HL),A          ; but for subsequent repeats REPPER will be used.
  402.         INC     HL              ; advance
  403.                                 ;
  404.         LD      A,(HL)          ; pick up the key decoded possibly in another
  405.                                 ; context.
  406.         JR      L0308           ; back to K-END
  407.  
  408. ;---------------
  409. ; Test key value
  410. ;---------------
  411. ; also called from s-inkey$
  412. ; begin by testing for a shift with no other.
  413.  
  414. ;; K-TEST
  415. L031E   LD      B,D             ; load most significant key to B
  416.                                 ; will be $FF if not shift.
  417.         LD      D,$00           ; and reset D to index into main table
  418.         LD      A,E             ; load least significant key from E
  419.         CP      $27             ; is it higher than 39d   i.e. FF
  420.         RET     NC              ; return with just a shift (in B now)
  421.  
  422.         CP      $18             ; is it symbol shift ?
  423.         JR      NZ,L032C        ; forward to K-MAIN if not
  424.  
  425. ; but we could have just symbol shift and no other
  426.  
  427.         BIT     7,B             ; is other key $FF (ie not shift)
  428.         RET     NZ              ; return with solitary symbol shift
  429.  
  430.  
  431. ;; K-MAIN
  432. L032C   LD      HL,L0205        ; address: MAIN-KEYS
  433.         ADD     HL,DE           ; add offset 0-38
  434.         LD      A,(HL)          ; pick up main key value
  435.         SCF                     ; set carry flag
  436.         RET                     ; return    (B has other key still)
  437.  
  438. ;------------------
  439. ; Keyboard decoding
  440. ;------------------
  441. ; also called from s-inkey$
  442.  
  443. ;; K-DECODE
  444. L0333   LD      A,E             ; pick up the stored main key
  445.         CP      $3A             ; an arbitrary point between digits and letters
  446.         JR      C,L0367         ; forward to K-DIGIT with digits,space,enter
  447.  
  448.         DEC     C               ; decrease MODE ( 0='KLC', 1='E', 2='G')
  449.  
  450.         JP      M,L034F         ; to K-KLC-LET if was zero
  451.  
  452.         JR      Z,L0341         ; to K-E-LET if was 1 for extended letters.
  453.  
  454. ; proceed with graphic codes.
  455. ; Note. should selectively drop return address if code > 'U' ($55).
  456. ; i.e. abort the KEYBOARD call.
  457. ; e.g. cp 'V'; jr c addit; pop af; ;;addit etc. (5 bytes of instruction).
  458. ; (s-inkey$ never gets into graphics mode.)
  459.  
  460. ;; addit
  461.         ADD     A,$4F           ; add offset to augment 'A' to graphics A say.
  462.         RET                     ; return.
  463.                                 ; Note. ( but [GRAPH] V gives RND, etc ).
  464.  
  465. ; the jump was to here with extended mode with uppercase A-Z.
  466.  
  467. ;; K-E-LET
  468. L0341   LD      HL,L022C-$41    ; base address of E-UNSHIFT L022c
  469.                                 ; ( $01EB in standard ROM )
  470.         INC     B               ; test B is it empty i.e. not a shift
  471.         JR      Z,L034A         ; forward to K-LOOK-UP if neither shift
  472.  
  473.         LD      HL,L0246-$41    ; Address: $0205 L0246-$41 EXT-SHIFT base
  474.  
  475. ;; K-LOOK-UP
  476. L034A   LD      D,$00           ; prepare to index
  477.         ADD     HL,DE           ; add the main key value
  478.         LD      A,(HL)          ; pick up other mode value
  479.         RET                     ; return
  480.  
  481. ; the jump was here with mode = 0
  482.  
  483. ;; K-KLC-LET
  484. L034F   LD      HL,L026A-$41    ; base of sym-codes
  485.         BIT     0,B             ; shift=$27 sym-shift=$18
  486.         JR      Z,L034A         ; back to K-LOOK-UP with symbol-shift
  487.  
  488.         BIT     3,D             ; test FLAGS is it 'K' mode (from OUT-CURS)
  489.         JR      Z,L0364         ; skip to K-TOKENS if so
  490.  
  491.         BIT     3,(IY+$30)      ; test FLAGS2 - consider CAPS LOCK ?
  492.         RET     NZ              ; return if so with main code.
  493.  
  494.         INC     B               ; is shift being pressed ?
  495.                                 ; result zero if not
  496.         RET     NZ              ; return if shift pressed.
  497.  
  498.         ADD     A,$20           ; else convert the code to lower case.
  499.         RET                     ; return.
  500.  
  501. ; the jump was here for tokens
  502.  
  503. ;; K-TOKENS
  504. L0364   ADD     A,$A5           ; add offset to main code so that 'A'
  505.                                 ; becomes 'NEW' etc.
  506.         RET                     ; return
  507.  
  508. ; the jump was here with digits, space, enter and symbol shift (< $xx)
  509.  
  510. ;; K-DIGIT
  511. L0367   CP      $30             ; is it '0' or higher ?
  512.         RET     C               ; return with space, enter and symbol-shift
  513.  
  514.         DEC     C               ; test MODE (was 0='KLC', 1='E', 2='G')
  515.         JP      M,L039D         ; jump to K-KLC-DGT if was 0.
  516.  
  517.         JR      NZ,L0389        ; forward to K-GRA-DGT if mode was 2.
  518.  
  519. ; continue with extended digits 0-9.
  520.  
  521.         LD      HL,L0284-$30    ; $0254 - base of E-DIGITS
  522.         BIT     5,B             ; test - shift=$27 sym-shift=$18
  523.         JR      Z,L034A         ; to K-LOOK-UP if sym-shift
  524.  
  525.         CP      $38             ; is character '8' ?
  526.         JR      NC,L0382        ; to K-8-&-9 if greater than '7'
  527.  
  528.         SUB     $20             ; reduce to ink range $10-$17
  529.         INC     B               ; shift ?
  530.         RET     Z               ; return if not.
  531.  
  532.         ADD     A,$08           ; add 8 to give paper range $18 - $1F
  533.         RET                     ; return
  534.  
  535. ; 89
  536.  
  537. ;; K-8-&-9
  538. L0382   SUB     $36             ; reduce to 02 and 03  bright codes
  539.         INC     B               ; test if shift pressed.
  540.         RET     Z               ; return if not.
  541.  
  542.         ADD     A,$FE           ; subtract 2 setting carry
  543.         RET                     ; to give 0 and 1    flash codes.
  544.  
  545. ;  graphics mode with digits
  546.  
  547. ;; K-GRA-DGT
  548. L0389   LD      HL,L0260-$30    ; $0230 base address of CTL-CODES
  549.         CP      $39             ; '9' ?
  550.         JR      Z,L034A         ; to K-LOOK-UP changed to $0F
  551.  
  552.         CP      $30             ; '0' ?
  553.         JR      Z,L034A         ; to K-LOOK-UP changed to $0C
  554.  
  555. ; for keys '0' - '7' we assign a mosaic character depending on shift.
  556.  
  557.         AND     $07             ; convert character to number. 0 - 7.
  558.         ADD     A,$80           ; add offset - they start at $80
  559.  
  560.         INC     B               ; destructively test for shift
  561.         RET     Z               ; and return if not pressed.
  562.  
  563.         XOR     $0F             ; toggle bits becomes range $88-$8F
  564.         RET                     ; return.
  565.  
  566. ; now digits in 'KLC' mode
  567.  
  568. ;; K-KLC-DGT
  569. L039D   INC     B               ; return with digit codes if neither
  570.         RET     Z               ; shift pressed.
  571.  
  572.         BIT     5,B             ; test for caps shift
  573.         LD      HL,L0260-$30    ; base of table CTL-CODES
  574.         JR      NZ,L034A        ; back to K-LOOK-UP
  575.  
  576. ; must have been symbol shift
  577.  
  578.         SUB     $10             ; for ascii most will now be correct
  579.                                 ; on a standard typewriter.
  580.         CP      $22             ; but '@' is not - see below.
  581.         JR      Z,L03B2         ; forward to to K-@-CHAR if so
  582.  
  583.         CP      $20             ; '_' is the other one that fails
  584.         RET     NZ              ; return if not.
  585.  
  586.         LD      A,$5F           ; substitute ascii '_'
  587.         RET                     ; return.
  588.  
  589. ;; K-@-CHAR
  590. L03B2   LD      A,$40           ; substitute ascii '@'
  591.         RET                     ; return.
  592.  
  593.