home *** CD-ROM | disk | FTP | other *** search
/ ftp.barnyard.co.uk / 2015.02.ftp.barnyard.co.uk.tar / ftp.barnyard.co.uk / cpm / walnut-creek-CDROM / ENTERPRS / CPM / UTILS / A / 28MAY87.ARK / CXKEY.ASM < prev    next >
Assembly Source File  |  1989-09-27  |  15KB  |  956 lines

  1.  
  2.     title    'C128 keyboard handler   18 Feb 86'
  3.  
  4.     maclib    cxequ
  5.  
  6.     maclib    z80
  7.  
  8.     public    ?get$key,?int$cia,?kyscn
  9.     public    Fx$V$tbl
  10.  
  11.     extrn    ?stat,?save,?recov
  12.     extrn    ?dskst
  13.  
  14.     extrn    ?di$int
  15.  
  16.     extrn    cmdsk0,cmdsk1,cmdsk2,cmdsk3,cmdsk4
  17.  
  18.     extrn    @pageM
  19.  
  20.     extrn    adm31
  21.     public    setadm
  22.  
  23.   if    use$VT100
  24.     extrn    vt100
  25.     public    setvt
  26.   endif
  27.  
  28.     page
  29.  
  30.     DSEG
  31. ;
  32. ;
  33. ;
  34. ?int$cia:
  35.     lxi    b,key$row        ; point to CIA 1st register
  36.     mvi    a,0ffh
  37.     outp    a
  38.     inr    c
  39.     inr    c
  40.     outp    a
  41.     inr    c
  42.     xra    a
  43.     sta    commodore$mode        ; clear commodore shift mode
  44.     outp    a
  45.  
  46.  
  47.     lxi    h,key$scan$tbl        ; init key scan tbl pointer
  48.     mov    m,l            ; ..to the begining
  49. ;
  50. ;    initialize keyboard buffer and pointers
  51. ;
  52.     lxi    h,key$buffer
  53.     shld    key$get$ptr
  54.     shld    key$put$ptr
  55.     mvi    m,0ffh
  56.     lxi    d,key$buffer+1
  57.     lxi    b,key$buf$size-1
  58.     ldir
  59.     ret
  60.  
  61.     page
  62. ;==========================================================
  63. ;        KEYBOARD SCANNING FUNCTION
  64. ;==========================================================
  65. ;
  66. ;
  67. ;
  68. ;
  69. ?get$key:
  70.     lhld    msgptr
  71.     mov    a,h
  72.     ora    l
  73.     jrnz    mess$cont
  74.  
  75. ;
  76. ;
  77. ;
  78. re$scan:
  79.     call    scan$keys
  80.     push    psw
  81.  
  82.     mov    a,c
  83.     ani    special
  84.     cpi    special        ; control and rt. shift key
  85.     jrnz    not$special
  86.  
  87.     mov    a,b        ; get the matrix position
  88.     cpi    rt$arrow
  89.     jz    prog$fun
  90.  
  91.     cpi    lf$arrow
  92.     jz    prog$key
  93.  
  94.     cpi    alt$key
  95.     jz    toggle$plain$keys
  96.  
  97. ;
  98. ;
  99. ;
  100. not$special:
  101.     pop     psw
  102.     mov    d,a
  103.     lda    stat$enable
  104.     ani    80h        ; mask off plain keys bit
  105.     mov    a,d        ; recover input character
  106.     rnz            ; return if plain keys bit is set
  107.  
  108.     page
  109. ;
  110. ;
  111. ;
  112. test$function:
  113.     cpi    080h        ; check for MSB set 
  114.     rc            ; return if not
  115.  
  116.     cpi    0A0h        ; 80-9F are function keys
  117.     jrnc    not$8x
  118.  
  119. ;
  120. ;
  121. find$mess:
  122.     ani    1fh        ; 32 messages
  123.     mov    b,a        ; place Function # in B for search
  124.     call    get$fun$adr
  125.  
  126. ;
  127. ;
  128. mess$cont:
  129.     mov    b,m        ; get char to B
  130.     inx    h
  131.     mov    a,m
  132.     ora    a
  133.     jrnz    more$mess
  134.  
  135.     lxi    h,0
  136.  
  137. more$mess:
  138.     shld    msg$ptr
  139.     mov    a,b
  140.     mvi    c,0        ; no control keys
  141.     mvi    b,0f0h        ; tell user this is a function key
  142.     ora    a        ; check character (maybe 1st is 0)
  143.     jrz    re$scan        ; scan keys (no valid function key)
  144.  
  145.     jrnz    test$function    ; test for local function
  146.  
  147.     page
  148. ;
  149. ;
  150. ;
  151. get$fun$adr:
  152.     lhld    fun$tbl            ; get adr of msg table
  153.     dcx    h
  154. ; lxi    h,msgtbl-1            ; point to start of funtions (less one)
  155.     inr    b            ; adjust function # (to test for 0)
  156.     xra    a            ; get a zero in A
  157. check$fun$num:
  158.     inx    h            ; advance pointer to point at text
  159.     shld    msg$ptr            ; save message adr for caller
  160.     dcr    b            ; requested function ?
  161.     rz                ; yes, exit with HL=string adr 
  162.  
  163. find$end$marker:
  164.     cmp    m            ; end of text marker ? (0=EOTM)
  165.     jrz    check$fun$num        ; yes, go see if required fun # 
  166.  
  167.     inx    h            ; advance to next char
  168.     jr    find$end$marker        ; go find EOTM
  169.  
  170.     page
  171. ;
  172. ;    A0-AF    Set char color (80 col)
  173. ;    B0-B1    Set background color (80 col)
  174. ;
  175. not$8x:
  176.     cpi    0C0h        ; 
  177.     jrnc    not$80col$color
  178.  
  179.     sui    0A0h-20h        ; remove key bias
  180.     mov    b,a
  181.     RCALL    FR$color
  182.     jr    ?get$key
  183.  
  184. ;
  185. ;    C0-CF    Set char color (40 col)
  186. ;    D0-DF    Set background color (40 col)
  187. ;    E0-EF    Set border color (40 col)
  188. ;
  189. not$80col$color:
  190.     cpi    0F0h
  191.     jrnc    must$be$Fx
  192. ;
  193. ;
  194. ;
  195.     sui    0C0h-20h        ; remove key bias
  196.     mov    b,a
  197.     RCALL    FR$color+FR$40
  198.     jr    ?get$key
  199.  
  200.     page
  201. ;
  202. ;    F0-FF    special code functions
  203. ;                           
  204. must$be$Fx:
  205.     lxi    h,?get$key
  206.     push    h            ; save as the return adr
  207.     ani    0fh
  208.     add    a            ; double
  209.     lhld    key$FX$function
  210.     mov    e,a
  211.     mvi    d,0
  212.     dad    d            ; HL points to the function
  213.     mov    e,m
  214.     inx    h
  215.     mov    d,m
  216.     xchg
  217.     pchl
  218.  
  219. ;
  220. ;
  221. ;
  222. FX$V$tbl:
  223.     dw    toggle$dsk$stat        ; F0
  224.     dw    display$pause        ; F1
  225.     dw    toggle$track$40        ; F2
  226.     dw    cur$lf            ; F3
  227.     dw    cur$rt            ; F4
  228.     dw    reset$mfm        ; F5
  229.   if    use$VT100
  230.     dw    set$adm            ; F6
  231.     dw    set$VT            ; F7
  232.   else
  233.     dw    empty            ; F6
  234.     dw    empty            ; F7
  235.   endif
  236.     dw    empty            ; F8
  237.     dw    empty            ; F9
  238.     dw    empty            ; FA
  239.     dw    empty            ; FB
  240.     dw    empty            ; FC
  241.     dw    empty            ; FD
  242.     dw    empty            ; FE
  243.  
  244.     dw    0            ; FF    go restart the C128 BASIC
  245.                     ;    mode (or C64)
  246.  
  247.  
  248. ;    dw    screen$print$40        ; would be nice later
  249. ;    dw    screen$print$80
  250.  
  251.     page
  252. ;
  253. ;    Function F0
  254. ;
  255. toggle$dsk$stat:
  256.     lda    stat$enable
  257.     xri    1
  258.     sta    stat$enable
  259.  
  260.     ani    1
  261.     jnz    ?dskst            ; go paint the disk status line
  262.  
  263. ;
  264. ;    erase 80 column window from display
  265. ;
  266.     mvi    e,8
  267.     lxi    b,20h*256+(80-8)    ; get a space start in col 80-8    
  268. erase$loop:
  269.     push    d            ; save count
  270.     push    b            ; save space and position
  271.     xra    a            ; get no attributes
  272.     call    ?stat            ; update screen
  273.     pop    b            ; recover space and position
  274.     inr    c            ; advance position
  275.     pop    d            ; recover count
  276.     dcr    e            ; decrement count
  277.     jrnz    erase$loop        ; loop until done
  278.  
  279. ;
  280. ;    erase 40 column window from display
  281. ;
  282.     RJMP    FR$screen$paint
  283.  
  284.     page
  285. ;
  286. ;    Function F1
  287. ;
  288. display$pause:
  289.     mvi    a,-1
  290.     sta    cur$pos            ; move cursor out of window
  291.  
  292.     lxi    b,buff$small*256+buff$pos    ; B=size C=pos
  293.     call    ?save
  294.     mvi    a,buff$pos+1
  295.     sta    offset
  296.     mvi    b,5
  297.     lxi    h,pause$MSG
  298.  
  299. pause$disp$loop:
  300.     mov    a,m
  301.     push    h
  302.     push    b
  303.     call    disp$status
  304.     pop    b
  305.     pop    h
  306.     inx    h
  307.     djnz    pause$disp$loop
  308.  
  309. pause$loop:
  310.     call    scan$keys
  311.     jrz    pause$loop
  312.     cpi    cr            ; pause key function code
  313.     jrnz    pause$loop
  314.     jmp    recov$small
  315.  
  316.  
  317. pause$MSG:
  318.     db    'Pause'
  319.  
  320.  
  321.     page
  322. ;
  323. ;    Function F2
  324. ;
  325. ;    A Zero in bit 6 of STAT$ENABLE will enable tracking
  326. ;    the cursor on data input with the 40 column display
  327. ;
  328. toggle$track$40:
  329.     lda    stat$enable
  330.     xri    40h
  331.     sta    stat$enable
  332. empty:
  333.     ret
  334.  
  335.  
  336.  
  337.     page
  338. ;
  339. ;    Function F3
  340. ;
  341. ;    Move 40 column window left one positions
  342. ;
  343. cur$lf:
  344.     lda    @off40
  345.     ora    a
  346.     rz
  347.  
  348.     dcr    a
  349.     jr    cur$update$cont
  350.  
  351.  
  352.  
  353.  
  354.  
  355.  
  356.  
  357. ;
  358. ;    Function F4
  359. ;
  360. ;    Move 40 column window right one position
  361. ;
  362. cur$rt:
  363.     lda    @off40
  364.     cpi    40
  365.     rz
  366.     inr    a
  367. cur$update$cont:
  368.     sta    @off40
  369.     RCALL    FR$set$cur$40
  370.     RJMP    FR$screen$paint
  371.  
  372. ;
  373. ;    Function F5
  374. ;
  375. ;    Unlock MFM selection for ALL drives in the system
  376. ;
  377. reset$mfm:
  378.     lda    cmdsk0+42        ; 42 is the offset from drive pointer
  379.     ani    7fh            ; MSB cleared to unlock the drive
  380.     sta    cmdsk0+42        ; unlock drive A
  381.     lda    cmdsk1+42
  382.     ani    7fh
  383.     sta    cmdsk1+42        ; unlock drive B
  384.     lda    cmdsk2+42
  385.     ani    7fh
  386.     sta    cmdsk2+42        ; unlock drive C
  387.     lda    cmdsk3+42
  388.     ani    7fh
  389.     sta    cmdsk3+42        ; unlock drive D
  390.     lda    cmdsk4+42
  391.     ani    7fh
  392.     sta    cmdsk4+42        ; unlock drive E
  393.     ret
  394.  
  395. ;
  396. ;    Function F6
  397. ;
  398. set$adm:
  399.     lxi    h,ADM31
  400.   if    use$vt100
  401.     jr    set$emulation
  402.  
  403. ;
  404. ;    Function F7
  405. ;
  406. set$VT:
  407.     lxi    h,VT100
  408. set$emulation:
  409.   endif
  410.     shld    emulation$adr
  411.     ret
  412.  
  413. ;
  414. ;
  415. ;    THIS CODE IS NOT FUNCTIONAL YET
  416. ;
  417. ;toggle$page$break:
  418. ;    lda    @pageM
  419. ;    xri    0ffh
  420. ;    sta    @pageM
  421. ;    rz
  422. ;    mvi    a,-1
  423. ;    sta    @pageM
  424.  
  425.  
  426.     page
  427. ;
  428. ;    A zero in the MSB of the STAT$ENABLE byte will allow
  429. ;    special keyboard function. (codes above 80h)
  430. ;    A one will force the key value to be returned without
  431. ;    any special functions being executed.
  432. ;
  433. toggle$plain$keys:
  434.     pop    psw            ; remove garbage
  435.  
  436.     lda    stat$enable
  437.     xri    80h
  438.     sta    stat$enable
  439.     jmp    re$scan
  440.  
  441.     page
  442. ;
  443. ;
  444. ;
  445. prog$key:
  446.     pop    psw            ; remove garbage
  447.  
  448.     lxi    b,buff$small*256+buff$pos    ; B=size, C=position
  449.     call    ?save
  450.  
  451.     mvi    a,buff$pos+1
  452.     sta    offset
  453.     call    read$key        ; get key to re-program
  454.     push    h            ; save key's address
  455.     mov    a,m
  456.     call    disp$hex$byte
  457.     mvi    a,buff$pos+4
  458.     sta    offset
  459.     call    get$byte
  460.     pop    h
  461.     jrc    restore$buf$small
  462.     mov    m,a
  463. ;
  464. ;
  465. restore$buf$small:
  466.     call    delay
  467. recov$small:
  468.     lxi    b,buff$small*256+buff$pos    ; B=size, C=position
  469.     jmp    ?recov
  470.  
  471.     page
  472. ;
  473. ;
  474. ;
  475. prog$fun:
  476.     pop    psw            ; remove garbage
  477.  
  478.     lxi    b,buff$large*256+buff$pos    ; b=size, c=pos
  479.     call    ?save
  480.  
  481.     call    read$key        ; get function key to program
  482.     cpi    80h
  483.     jrc    restore$buf$large    ; error, exit
  484.  
  485.     cpi    0A0h
  486.     jrnc    restore$buf$large
  487.  
  488.     ani    1fh            ; 32 keys defined
  489.     mov    b,a
  490.     call    get$fun$adr        ; get pointer to function code
  491.  
  492.     xra    a
  493.     sta    string$index        ; start at start of string
  494.  
  495.     call    edit$fun
  496.  
  497.     lxi    h,0
  498.     shld    msg$ptr            ; clear message pointer
  499.  
  500. restore$buf$large:
  501.     call    delay
  502.     lxi    b,buff$large*256+buff$pos    ; B=size, C=position
  503.     jmp    ?recov
  504.  
  505.     page
  506. ;
  507. ;
  508. ;
  509. delay:
  510.     lxi    h,0
  511. delay$loop:
  512.     dcx    h
  513.     mov    a,h
  514.     ora    l
  515.     jrnz    delay$loop
  516.     ret
  517. ;
  518. ;
  519. ;
  520. edit$fun:
  521.     lxi    h,edit$fun
  522.     push    h            ; set return to here
  523.     call    disp$fun$key
  524.     call    read$key        ; B=matrix position
  525.     mov    d,a            ; save ASCII char in D
  526.     mov    a,c            ; get attr (C=cntr codes)
  527.     ani    special
  528.     cpi    special            ; check for cntr shift
  529.     jnz    not$cntr$shift
  530.  
  531.  
  532. ;
  533. ;
  534. ;
  535. check$exit:
  536.     mov    a,b            ; get matrix position
  537.     cpi    SF$exit
  538.     jrnz    check$delete
  539.  
  540.     pop    h            ; remover return adr
  541.     ret                ; go back to normal keyboard fun
  542.  
  543.     page
  544. ;
  545. ;
  546. ;
  547. check$delete:
  548.     cpi    SF$delete
  549.     jrnz    check$insert
  550. ;
  551. ;    delete the character at current cursor position
  552. ;
  553.     call    compute$adr        ; HL= current position
  554.     rz                ; don't want to delete end markers
  555.  
  556.     xchg                ; save in DE
  557.     lhld    key$tbl            ; get next table adr (keytbl)
  558.     dcx    h
  559. ; lxi    h,msgtbl$end-1        ; end adr
  560.     xra    a            ; clear the carry flag
  561.     dsbc    DE            ; compute number of bytes to move
  562.     mov    b,h
  563.     mov    c,l            ; place count in BC
  564.     mov    h,d
  565.     mov    l,e            ; HL=DE
  566.     inx    h            ;
  567.     ldir
  568.  
  569.     dcx    h            ; point to insert point
  570.     mvi    m,-1            ; fill table end with -1
  571.     ret
  572.  
  573.     page
  574. ;
  575. ;
  576. ;
  577. check$insert:
  578.     cpi    SF$insert
  579.     jrnz    check$right
  580. ;
  581. ;    insert a space into string
  582. ;
  583.     call    compute$adr
  584. ;
  585. ;    HL=address to insert a space at
  586. ;     value of HL is the same on return
  587. ;
  588. insert$space:
  589.     xchg
  590.     lhld    key$tbl            ; get start of next table
  591.     dcx    h            ; point to end of msg table
  592. ; lxi    h,msgtbl$end-1
  593.     xra    a
  594.     cmp    m            ; last char=0 (end of string)
  595.     rz                ; yes, don't insert 
  596.  
  597.     xra    a            ; clear the carry flag
  598.     dsbc    DE            ; compute number of bytes to move
  599.     mov    b,h
  600.     mov    c,l            ; place count in BC
  601.  
  602.     lhld    key$tbl
  603.     dcx    h
  604.     mov    d,h
  605.     mov    e,l
  606. ; lxi    d,msgtbl$end-1            ; dest adr
  607.     dcx    h
  608. ; lxi    h,msgtbl$end-2            ; source adr
  609.     lddr                ; move the data
  610.     inx    h            ; point to insert point
  611.     adi    ' '            ; A was equ to zero, add a space to
  612.     mov    m,a            ; ..clear the zero flag
  613.     ret                ; insert a space at the new location
  614.  
  615.     page
  616. ;
  617. ;
  618. ;
  619. check$right
  620.     cpi    SF$right
  621.     jrnz    check$left
  622. ;
  623. ;    move cursor right
  624. ;     if past right end go back to left end
  625. ;
  626.     call    compute$adr
  627.     lda    string$index
  628.     jrnz    move$rt
  629.  
  630.     mvi    a,-1    
  631. move$rt:
  632.     inr    a
  633.     sta    string$index
  634.     ret
  635.  
  636. ;
  637. ;
  638. ;
  639. check$left:
  640.     cpi    SF$left
  641.     rnz
  642. ;
  643. ;    move cursor left
  644. ;     if past left end go to right end
  645. ;
  646.     lda    string$index
  647.     ora    a
  648.     jrz    at$left$end
  649.  
  650.     dcr    a
  651.     sta    string$index
  652.     ret
  653.  
  654.  
  655.     page
  656. ;
  657. ;
  658. ;
  659. at$left$end:
  660.     call    compute$adr
  661.     rz                ; return if at right end
  662.  
  663.     lda    string$index
  664.     inr    a
  665.     sta    string$index        ; move right one position
  666.     jr    at$left$end        ; 
  667.  
  668.  
  669.  
  670. ;
  671. ;
  672. ;
  673. not$cntr$shift:
  674.     call    compute$adr        ; HL=function adr (A=0 if string end)
  675.     jrnz    no$insert
  676.  
  677.     push    d            ; save char to insert
  678.     call    insert$space
  679.     pop    d            ; recover character
  680.     rz                ; no room if zero flag set
  681.  
  682. no$insert:
  683.     mov    m,d            ; install key's value
  684.     lda    string$index
  685.     inr    a
  686.     sta    string$index
  687.     ret
  688.  
  689.     page
  690. ;
  691. ;
  692. ;
  693. compute$adr:
  694.     lhld    msg$ptr            ; get start of memory pointer
  695.     lda    string$index        ; get current offset
  696.     add    l
  697.     mov    l,a
  698.     mov    a,h
  699.     aci    0
  700.     mov    h,a            ; point to update location
  701.     mov    a,m
  702.     ora    a
  703.     ret
  704.  
  705. ;
  706. ;
  707. ;
  708. disp$fun$key:
  709.     mvi    a,buff$pos
  710.     sta    offset
  711.     mvi    a,'>'            ; display start prompt '>'
  712.     call    disp$status
  713.  
  714.     lhld    msg$ptr
  715.     lda    string$index
  716.  
  717. try$again:
  718.     cpi    buff$large-2
  719.     jrc    parameters$ok
  720.  
  721.     inx    h
  722.     dcr    a
  723.     jr    try$again
  724.  
  725.     page
  726. ;
  727. ;
  728. ;
  729. parameters$ok:
  730.     adi    buff$pos+1
  731.     sta    cur$pos 
  732.  
  733. disp$fun$loop:
  734.     mov    a,m
  735.     ora    a
  736.     inx    h             ; advance function pointer
  737.     jrz    disp$fun$end
  738.  
  739.     push    h
  740.     call    disp$status        ; display on status line
  741.     pop    h
  742.     lda    offset            ; get current cursor position
  743.     cpi    buff$pos+buff$large-1    ; to end of window?
  744.     jrnz    disp$fun$loop        ; no, display next character
  745.  
  746.  
  747. disp$fun$end:
  748.     mvi    a,'<'            ; display end prompt '<'
  749. disp$space$fill:
  750.     call    disp$status
  751.     lda    offset            ; get current cursor position
  752.     cpi    buff$pos+buff$large    ; to end of window?
  753.     rz
  754.  
  755.     mvi    a,' '            ; fill to the end with spaces
  756.     jr    disp$space$fill
  757.  
  758.     page
  759. ;
  760. ;
  761. ;
  762. disp$hex$byte:
  763.     push    psw
  764.     rar
  765.     rar
  766.     rar
  767.     rar
  768.     call    disp$hex$nibble
  769.     pop    psw
  770.  
  771. disp$hex$nibble:
  772.     ani    0fh
  773.     adi    '0'
  774.     cpi    '9'+1
  775.     jrc    disp$status
  776.  
  777.     adi    7
  778.  
  779. disp$status:
  780.     mov    b,a
  781.     lda    offset
  782.     mov    c,a
  783.     inr    a
  784.     sta    offset
  785.     lda    cur$pos
  786.     cmp    c
  787.     mvi    a,01000000b        ; set reverse video attributes
  788.     jrnz    not$cur$pos
  789.  
  790.     mvi    a,00010000b        ; set normal video and blink
  791. not$cur$pos:
  792.     jmp    ?stat
  793.  
  794.  
  795.     page
  796. ;
  797. ;
  798. ;
  799. get$byte:
  800.     mvi    e,0
  801.     call    read$nibble
  802.     rc
  803.  
  804.     add    a
  805.     add    a
  806.     add    a
  807.     add    a
  808.     mov    e,a
  809.  
  810. read$nibble:
  811.     push    d
  812.     call    read$key
  813.     mov    a,b            ; get matrix position
  814.     lxi    h,hex$key$tbl
  815.     lxi    b,16
  816.     ccir
  817.  
  818.     mov    a,c
  819.     pop    d
  820.     stc
  821.     rnz
  822.  
  823.     add    e
  824.     push    d
  825.     push    psw
  826.     call    disp$hex$nibble
  827.     pop    psw
  828.     pop    d
  829.     stc
  830.     cmc
  831.     ret
  832.  
  833. ;
  834. ;
  835. ;
  836. read$key:
  837.     call    scan$keys
  838.     inr    b
  839.     jrz    read$key        ; no, wait for one
  840.     dcr    b
  841.     ret
  842.  
  843.     page
  844. ;
  845. ;
  846. ;
  847. do$alpha$toggle:
  848.     mvi    m,0ffh        ; mark buffer position free    
  849.     lda    commodore$mode
  850.     xri    00100001b
  851.     ani    00100001b
  852.     sta    commodore$mode
  853. ;    
  854. ; output:
  855. ;    B=FF if no key pressed
  856. ;    A=00 if no key code assigned
  857. ;    else     A=ASCII key code 
  858. ;        B=matrix position (0-57)
  859. ;        C=control code (bits 1,0)
  860. ;            00=lower case    (lowest)
  861. ;            01=upper case
  862. ;            10=shift
  863. ;            11=control    (highest)
  864. ;          (bit 2) control key
  865. ;          (bit 4) rt. shift key
  866. ;          (bit 5) commodore key
  867. ;          (bit 7) lf. shift key
  868. ;
  869. ;    HL= address of ASCII key location
  870. ;
  871. ?kyscn:
  872. scan$keys:
  873.     lhld    key$get$ptr
  874.     mov    a,m        ; M=-1 if buffer empty
  875.     mov    b,a        ; B=-1 if no character
  876.     inr    a
  877.     rz            ; return if no key is pressed
  878. ;
  879. ;    there is a character in the buffer,
  880. ;    advance key$get$ptr to next character.
  881. ;
  882.     mov    a,l
  883.     adi    2
  884.     cpi    low(key$buffer+key$buf$size)
  885.     jrnz    not$buf$end
  886.     mvi    a,low(key$buffer)
  887. not$buf$end:
  888.     sta    key$get$ptr    ; update low byte of pointer
  889.  
  890.     page
  891. ;
  892. ;    test for commodore key, if found toggle commodore mode
  893. ;
  894.     mov    a,b        ; get buffered matrix position to A
  895.     cpi    alpha$toggle
  896.     jrz    do$alpha$toggle
  897. ;
  898. ;    if normal mode(00), or in commodore mode bit
  899. ;
  900.     inr    l        ; point to control byte
  901.     lda    commodore$mode
  902.     ani    00100000b    ; save commodore key set bit
  903.     ora    m        ; get rest of control byte
  904.     mov    c,a
  905.     ani    3
  906.     mov    a,c
  907.     jrnz    is$control$or$shift
  908.     lda    commodore$mode
  909.     ora    c
  910.  
  911. is$control$or$shift:
  912.     dcr    l
  913.     mvi    m,0ffh        ; mark buffer position free    
  914.  
  915.     mov    l,b        ; save matrix position in HL
  916.     mvi    h,0
  917.     dad    h
  918.     dad    h        ; mult. matrix position by 4
  919.     mov    c,a        ; save the control code in C for caller
  920.     ani    3
  921.     add    l        ; add the offset 
  922.     mov    l,a        ; update the pointer
  923.     xchg
  924.     lhld    key$tbl        ; get the start of the ASCII table
  925.     dad    d        ; HL now points to the ASCII value
  926.     mov    a,m        ; for the input key.
  927.     ora    a        ; set zero flag if A=0
  928.     ret
  929.  
  930.     page
  931. ;
  932. ;    used to convert a keyboard matrix position into it's HEX
  933. ;    value (keys caps labelled with 0 to 9 and A to F)
  934. ;
  935. hex$key$tbl:
  936.     db    15h        ; F
  937.     db    0eh        ; E
  938.     db    12h        ; D
  939.     db    14h        ; C
  940.     db    1ch        ; B
  941.     db    0ah        ; A
  942.     db    20h        ; 9
  943.     db    1bh        ; 8
  944.     db    18h        ; 7
  945.     db    13h        ; 6
  946.     db    10h        ; 5
  947.     db    0bh        ; 4
  948.     db    08h        ; 3
  949.     db    3bh        ; 2
  950.     db    38h        ; 1
  951.     db    23h        ; 0
  952.  
  953.  
  954.  
  955.  
  956.