home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / mbug / mbug097.arc / BKBD6545.MAC < prev    next >
Text File  |  1979-12-31  |  8KB  |  430 lines

  1. ;
  2. ;    Keyboard scanner for standard MicroBee keyboard.
  3. ;
  4. ;    Modifications for function keys, window key,
  5. ;    key click, etc. by Peter Broughton.
  6. ;
  7. ;    Last mod. : 1st Jan., 1988
  8. ;
  9.  
  10. ; Function keys:
  11.  
  12. fn_key_1    equ    81h    ; value returned by scn_in
  13.  
  14. fn_str_end    equ    0FFh    ; end function char
  15. fn_str_pause    equ    0FEh    ; pause char
  16.  
  17. window_char    equ    0A0h    ; value returned by scn_in to get window
  18.  
  19. window_key    equ    '9'    ; <CTRL> + this key = window
  20.  
  21. user_char    equ    0A1h    ; value returned by scn_in to get user program
  22.  
  23. user_key_1    equ    ')'    ; <CTRL> + this key = user program call
  24. user_key_2    equ    '?'    ; ditto... due to ghosting
  25.  
  26. rom_port    equ    11
  27. ;
  28. ; language options ..
  29. ENGLISH    equ    1        ;=1 if english version
  30. DANISH    equ    0        ;=1 if danish version
  31. SWEDISH    equ    0        ;=1 if swedish version
  32. ;
  33. ; PIO B bits of interest
  34. BEEP_BIT    equ    6
  35. SER_OUT        equ    5    ;serial comm. lines
  36. SER_IN        equ    4
  37. SER_CTS        equ    3    ;printer busy line= clear to send
  38. SER_DTR        equ    2    ;DTR output
  39. CASS_OUT    equ    1
  40. CASS_IN        equ    0    ;cassette bits
  41. ;
  42. ; the following two are 100Hz multiples (CPU speed independent)
  43. REPT_START    equ    100        ;gives 1 second repeat delay
  44. RP_SPEED    equ    10        ;gives 10 Hz repeat rate
  45. ;
  46. ; 6545 register definitions
  47. H_LPEN    equ    16
  48. L_LPEN    equ    17
  49. H_UPDATE    equ    18
  50. L_UPDATE    equ    19
  51. DUMMY    equ    31
  52. ; status bit definitions
  53. RETRACE    equ    5
  54. LPEN_FULL    equ    6
  55. UPDATE_RDY    equ    7
  56.  
  57.  
  58. ; keyboard row/ column codes
  59. row_val        equ    8        ;keyboard no. elements/ column
  60. shift_code    equ    7*row_val+7    ;shift key
  61. ctrl_code    equ    7*row_val+1    ;control key
  62.  
  63.  
  64. ; scan normal MicroBee keyboard, return
  65. ; Z and char in A
  66. ; or NZ if no chars available
  67. scn_in:    
  68.     push    bc
  69.     push    de
  70.     push    hl
  71.     ld    a,(key_down)
  72.     cp    -1
  73.     jr    z,none_down
  74. ; must wait for previous key to be released (and debounce)
  75.     ld    b,150    ;75    ;more for new keyboards (and at high Mhz)
  76. debounce:
  77.     call    is_closed
  78.     jr    z,try_rept    ;try repeat delay
  79.     djnz    debounce
  80.     ld    a,-1
  81.     ld    (key_down),a    ;it is now up
  82.     jp    none_1        ;--- So ZTREK works !!
  83.  
  84. try_rept:
  85.     ld    hl,rept_flip
  86.     in    a,(crtc)
  87.     and    1 shl retrace
  88.     cp    (hl)
  89.     jp    z,bad_exit    ;hasn't changed yet
  90.     ld    (hl),a        ;note the change
  91.     ld    hl,(rept_count)
  92.     dec    hl
  93.     ld    (rept_count),hl
  94.     ld    a,h
  95.     or    l
  96.     jp    nz,bad_exit
  97. ; 10 Hz repeat delay
  98.     ld    hl,rp_speed
  99.     ld    (rept_count),hl
  100.     ld    a,(last_ascii)
  101.     jp    ascii_ret    ;return last key pressed
  102. ; is there anything pressed at all ?
  103. none_down:
  104.     in    a,(crtc)
  105.     bit    lpen_full,a
  106.     jp    z,bad_exit    ;.. not here wasn't
  107. ; scan all keys to find main key ..
  108. none_1:
  109.     ld    a,1
  110.     out    (rom_port),a    ;disable DISEN address
  111.     ld    a,l_lpen
  112.     out    (crtc),a
  113.     in    a,(crtc+1)    ;reset lpen full
  114.     ld    c,crtc        ;address register
  115.     ld    de,dummy*256+l_update
  116.     ld    hl,0370H    ;address of last key on keyboard
  117. scn_1:
  118.     ld    a,h_update
  119.     out    (crtc),a
  120.     ld    a,h
  121.     out    (crtc+1),a
  122.     ld    a,l
  123.     push    hl
  124.     ld    h,010H        ;value to subtract from a
  125.     call    scan_q        ;very fast 16 key scanner
  126.     pop    hl
  127.     ld    l,a
  128. ; hl=update regs
  129.     jr    nz,scn_2    ;got a new key
  130.     dec    h
  131.     jp    p,scn_1
  132.     ld    b,7
  133.     ld    a,38h
  134. check_c_keys:
  135.     call    is_closed
  136.     jr    z,new_key
  137.     inc    a
  138.     cp    39h        ; avoid the control key
  139.     jr    nz,c_ck1
  140.     inc    a
  141.     dec    b
  142. c_ck1:
  143.     djnz    check_c_keys
  144.     jp    bad_exit
  145. ; convert hl to key_code ...
  146. scn_2:
  147.     add    hl,hl
  148.     add    hl,hl
  149.     add    hl,hl
  150.     add    hl,hl
  151.     ld    a,h
  152.     and    03Fh
  153. new_key:
  154.     cp    39h
  155.     jp    z,bad_exit
  156.     ld    (key_down),a    ;must be released next time
  157. ; ensure that repeat count starts from correct level for 1 second
  158.     ld    hl,rept_start
  159.     ld    (rept_count),hl
  160.  
  161. ; now convert it to good old ascii ..
  162.     cond    1-english
  163.     ld    hl,conv_tab
  164.     ld    b,kbc_length
  165. cmp_kb:
  166.     cp    (hl)
  167.     inc    hl
  168.     ld    a,(hl)
  169.     jr    z,asciify
  170.     inc    hl
  171.     ld    a,(key_down)
  172.     djnz    cmp_kb
  173.     endc
  174.  
  175. ; is it an alphabetical key ?
  176. asciify:
  177.     cp    row_val*4
  178.     jr    c,alpha_key
  179. ; it is a numeric/ punctuation key
  180.     cp    row_val*6
  181.     jr    c,numer_key
  182. ; is it a special key ?
  183.     cp    row_val*7
  184.     jr    c,spec_key
  185.     jp    curs_key
  186.  
  187.  
  188. ; handle alphabetical keys
  189. alpha_key:
  190.     call    is_ctrl
  191.     jp    z,ascii_ret    ;code is correct for control
  192.     add    a,'a'-1
  193.     cp    '`'
  194.     jr    z,strange    ;special case for at @
  195.  
  196.     cond    1-english
  197.     cp    '}'+1        ;include extra 3 letters
  198.     endc
  199.     cond    english
  200.     cp    'z'+1
  201.     endc
  202.     jr    c,letters
  203. strange:
  204.     cp    07FH
  205.     jr    z,no_al_rev    ;delete shifted = underline
  206.     res    5,a        ;for open sq},]},\|,^~
  207.     jr    no_al_rev
  208. ; check alpha reverse byte
  209. letters:
  210.     ld    b,a
  211.     ld    a,(al_rev)
  212.     or    a
  213.     ld    a,b
  214.     jr    z,no_al_rev
  215.     xor    1 shl 5
  216. no_al_rev:
  217.     call    is_shift
  218.     jr    nz,ascii_ret
  219.     xor    1 shl 5
  220.     jr    ascii_ret
  221. ; handle 0-9 and :/* ;/+ and also ,< -= .> /?
  222. numer_key:
  223.     cp    row_val*5+4
  224.     jr    c,num_1
  225.     set    4,a
  226. num_1:
  227.     cp    row_val*4    ;a zero
  228.     jr    z,zero_fix    ;if so, don't shift to space
  229.     call    is_shift
  230.     jr    z,ascii_ret    ;shifted code is correct
  231. zero_fix:
  232.     xor    1 shl 4
  233.     jr    ascii_ret
  234.  
  235. ; handle special keys e.g. cr,lf,brk,lock
  236. spec_key:
  237.     ld    hl,spec_tab-row_val*6
  238.     ld    c,a
  239.     ld    b,0
  240.     add    hl,bc
  241.     ld    a,(hl)
  242.     or    a
  243.     jr    nz,ascii_ret
  244. ; it is the lock key
  245.     ld    hl,0
  246.     ld    (rept_count),hl    ;very slow
  247.     ld    hl,al_rev
  248.     ld    a,1
  249.     xor    (hl)
  250.     ld    (hl),a
  251.     call    do_click
  252.     jr    bad_exit
  253.  
  254. ; handle premium cursor control keys
  255. ; must return value 90h..97h, or 98h..9Fh for shifted key
  256. curs_key:
  257.     add    a,90h-7*8
  258.     ld    b,a
  259.     call    is_shift
  260.     ld    a,b
  261.     jr    nz,ascii_ret
  262.     add    a,8
  263.  
  264. ;
  265. ascii_ret:    
  266. ; now check for fn keys, etc.
  267.     cp    'A'
  268.     jr    nc,a_r_1        ; Alpha key etc. can't be
  269.     ld    c,window_char-window_key    ; conversion value
  270.     cp    window_key            ; window ?
  271.     jr    z,convert_code
  272.     ld    c,user_char-user_key_1
  273.     cp    user_key_1            ; user 1 ?
  274.     jr    z,convert_code
  275.     ld    c,user_char-user_key_2
  276.     cp    user_key_2            ; user 2 ?
  277.     jr    z,convert_code
  278.     ld    c,fn_key_1-'1'
  279.     cp    '8'+1                ; function key ?
  280.     jr    nc,a_r_1
  281.     cp    '1'
  282.     jr    nc,convert_code
  283. a_r_2:
  284.     ld    c,fn_key_1+8-'"'
  285.     cp    '"'
  286.     jr    c,a_r_1
  287.     cp    '&'
  288.     jr    nc,a_r_1
  289. convert_code:
  290.     ld    b,a        ; but only if control is pressed
  291.     call    is_ctrl
  292.     ld    a,b
  293.     jr    nz,a_r_1
  294.     add    a,c
  295. a_r_1:
  296.     call    do_click
  297.     cp    a        ;set z flag -> got a key
  298.     ld    (last_ascii),a    ;for repeating purposes
  299. bad1_ret:    
  300.     push    af
  301.     ld    a,h_lpen    ; reset strobe
  302.     out    (crtc),a
  303.     in    a,(crtc+1)
  304.     xor    a        ;allow scanning LPENS
  305.     out    (rom_port),a
  306.     pop    af
  307.     pop    hl
  308.     pop    de
  309.     pop    bc
  310.     ret
  311.  
  312. bad_exit:    
  313.     or    -1        ;clear z flag (nz exit)
  314.     jr    bad1_ret    ;-> did not get a new key
  315.  
  316.  
  317.  
  318. ; DANISH/SWEDISH
  319. ; keyboard lookup table ...
  320.     cond    danish
  321. conv_tab:
  322.     db    40+3,24+3
  323.     db    0+0,24+4
  324.     db    24+3,24+5
  325.     db    24+4,40+3
  326.     db    24+5,0+0
  327. kbc_length    equ    5
  328.     endc
  329.     cond    swedish
  330. conv_tab:
  331.     db    40+3,24+4
  332.     db    0+0,24+3
  333.     db    24+3,24+5
  334.     db    24+4,40+3
  335.     db    24+5,0+0
  336. kbc_length    equ    5
  337.     endc
  338.  
  339.  
  340. ; very fast keyboard scanner for 16 keys at once
  341. scan_q:    
  342.     out    (c),e
  343.     out    (crtc+1),a
  344.     out    (c),d
  345.     out    (crtc+1),a
  346. scan1_q:    
  347.     in    b,(c)
  348.     jp    p,scan1_q
  349.     in    b,(c)
  350.     bit    lpen_full,b
  351.     ret    nz
  352.     sub    h
  353.     jp    nc,scan_q
  354.     cp    a
  355.     ret
  356.  
  357. is_shift:    
  358.     push    bc
  359.     ld    b,shift_code
  360.     jr    close_1
  361. ; is the control key being held down ?
  362. is_ctrl:    
  363.     push    bc
  364.     ld    b,ctrl_code
  365.     jr    close_1
  366.  
  367. ; return z if key specified in a is closed, else nz
  368. is_closed:    
  369. ; Make sure key is within range
  370.     cp    40h
  371.     jr    nc,key_too_big
  372.     push    bc
  373.     ld    b,a            ;save test key-code
  374.  
  375. close_1:    
  376.     ld    c,a            ;save acc.
  377.  
  378.     ld    a,h_update
  379.     out    (crtc),a        ;select update high byte
  380.     ld    a,b
  381.     rrca
  382.     rrca
  383.     rrca
  384.     rrca
  385.     ld    b,a
  386.     out    (crtc+1),a        ;to update high
  387.     ld    a,l_update
  388.     out    (crtc),a        ;select update lower
  389.     ld    a,b
  390.     out    (crtc+1),a        ;to update lower byte
  391.     ld    a,1            ;disallow scan lpens
  392.     out    (rom_port),a
  393.     ld    a,h_lpen        ;select light pen high byte
  394.     out    (crtc),a        ;reset lpen full strobe
  395.     in    a,(crtc+1)
  396.     ld    a,dummy
  397.     out    (crtc),a        ;select dummy register
  398.     out    (crtc+1),a        ;and write to it
  399. ; now wait for update to be done ..
  400. updte:
  401.     in    a,(crtc)
  402.     bit    update_rdy,a
  403.     jr    z,updte
  404. ; was there a lpen strobe generated ?
  405.     in    a,(crtc)
  406.     cpl
  407.     ld    b,a            ;save 6545 status
  408.     xor    a
  409.     out    (rom_port),a        ;allow refresh scan
  410.     ld    a,h_lpen
  411.     out    (crtc),a
  412.     in    a,(crtc+1)        ;reset lpen strobe
  413.     bit    lpen_full,b
  414.     ld    a,c            ;restore acc.
  415.     pop    bc            ;restore bc
  416.     ret
  417.  
  418. ; Key code not in range so return NZ
  419. key_too_big:
  420.     or    a
  421.     ret
  422.  
  423. spec_tab:    
  424.     db    01Bh,08h,09h    ;esc,bs,tab
  425.     db    0Ah,0Dh,0    ;lf,cr,lock
  426.     db    'X'-40h,020h    ;break -> ctl X,space
  427.  
  428. key_down:    ds    1    ;records key presently down or -1
  429. rept_count:    ds    2    ;counts down to give repeat delay
  430.