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 / BIOSR4.ARC / CXKEY.ASM < prev    next >
Assembly Source File  |  1987-04-26  |  17KB  |  1,061 lines

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