Mirror of CollapseOS
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
4.2KB

  1. ; kbd - implement GetC for PS/2 keyboard
  2. ;
  3. ; It reads raw key codes from a FetchKC routine and returns, if appropriate,
  4. ; a proper ASCII char to type. See recipes rc2014/ps2 and sms/kbd.
  5. ;
  6. ; *** Defines ***
  7. ; Pointer to a routine that fetches the last typed keyword in A. Should return
  8. ; 0 when nothing was typed.
  9. ; KBD_FETCHKC
  10. ; *** Consts ***
  11. .equ KBD_KC_BREAK 0xf0
  12. .equ KBD_KC_EXT 0xe0
  13. .equ KBD_KC_LSHIFT 0x12
  14. .equ KBD_KC_RSHIFT 0x59
  15. ; *** Variables ***
  16. ; Set to previously received scan code
  17. .equ KBD_PREV_KC KBD_RAMSTART
  18. ; Whether Shift key is pressed
  19. .equ KBD_SHIFT_ON KBD_PREV_KC+1
  20. .equ KBD_RAMEND KBD_SHIFT_ON+1
  21. kbdInit:
  22. xor a
  23. ld (KBD_PREV_KC), a
  24. ld (KBD_SHIFT_ON), a
  25. ret
  26. kbdGetC:
  27. call KBD_FETCHKC
  28. or a
  29. jr z, .nothing
  30. ; scan code not zero, maybe we have something.
  31. ; Do we need to skip it?
  32. ex af, af' ; save fetched KC
  33. ld a, (KBD_PREV_KC)
  34. ; Whatever the KC, the new A becomes our prev. The easiest way to do
  35. ; this is to do it now.
  36. ex af, af' ; restore KC
  37. ld (KBD_PREV_KC), a
  38. ex af, af' ; restore prev KC
  39. ; If F0 (break code) or E0 (extended code), we skip this code
  40. cp KBD_KC_BREAK
  41. jr z, .break
  42. cp KBD_KC_EXT
  43. jr z, .ignore
  44. ex af, af' ; restore saved KC
  45. cp 0x80
  46. jr nc, .ignore
  47. ; No need to skip, code within bounds, we have something!
  48. call .isShift
  49. jr z, .shiftPressed
  50. ; Let's see if there's a ASCII code associated to it.
  51. push hl ; --> lvl 1
  52. ld hl, KBD_SHIFT_ON
  53. bit 0, (hl)
  54. ld hl, kbdScanCodes ; no flag changed
  55. jr z, .shiftNotPressed
  56. ; Shift is being pressed. Use Shifted table.
  57. ld hl, kbdScanCodesS
  58. .shiftNotPressed:
  59. call addHL
  60. ld a, (hl)
  61. pop hl ; <-- lvl 1
  62. or a
  63. jp z, unsetZ ; no code. Keep A at 0, but unset Z
  64. ; We have something!
  65. cp a ; ensure Z
  66. ret
  67. .shiftPressed:
  68. ld a, 1
  69. ld (KBD_SHIFT_ON), a
  70. jr .ignore ; to actual char to return
  71. .break:
  72. ex af, af' ; restore saved KC
  73. call .isShift
  74. jr nz, .ignore
  75. ; We had a shift break, update status
  76. xor a
  77. ld (KBD_SHIFT_ON), a
  78. ; continue to .ignore
  79. .ignore:
  80. ; A scan code over 0x80 is out of bounds or prev KC tell us we should
  81. ; skip. Ignore.
  82. xor a
  83. jp unsetZ
  84. .nothing:
  85. ; We have nothing. Before we go further, we'll wait a bit to give our
  86. ; device the time to "breathe". When we're in a "nothing" loop, the z80
  87. ; hammers the device really fast and continuously generates interrupts
  88. ; on it and it interferes with its other task of reading the keyboard.
  89. push bc
  90. ld b, 0
  91. .wait:
  92. nop
  93. djnz .wait
  94. pop bc
  95. jp unsetZ
  96. ; Whether KC in A is L or R shift
  97. .isShift:
  98. cp KBD_KC_LSHIFT
  99. ret z
  100. cp KBD_KC_RSHIFT
  101. ret
  102. ; A list of the values associated with the 0x80 possible scan codes of the set
  103. ; 2 of the PS/2 keyboard specs. 0 means no value. That value is a character than
  104. ; can be read in a GetC routine. No make code in the PS/2 set 2 reaches 0x80.
  105. kbdScanCodes:
  106. ; 0x00 1 2 3 4 5 6 7 8 9 a b c d e f
  107. .db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,'`', 0
  108. ; 0x10 9 = TAB
  109. .db 0, 0, 0, 0, 0,'q','1', 0, 0, 0,'z','s','a','w','2', 0
  110. ; 0x20 32 = SPACE
  111. .db 0,'c','x','d','e','4','3', 0, 0, 32,'v','f','t','r','5', 0
  112. ; 0x30
  113. .db 0,'n','b','h','g','y','6', 0, 0, 0,'m','j','u','7','8', 0
  114. ; 0x40 59 = ;
  115. .db 0,',','k','i','o','0','9', 0, 0,'.','/','l', 59,'p','-', 0
  116. ; 0x50 13 = RETURN 39 = '
  117. .db 0, 0, 39, 0,'[','=', 0, 0, 0, 0, 13,']', 0,'\', 0, 0
  118. ; 0x60 8 = BKSP
  119. .db 0, 0, 0, 0, 0, 0, 8, 0, 0,'1', 0,'4','7', 0, 0, 0
  120. ; 0x70 27 = ESC
  121. .db '0','.','2','5','6','8', 27, 0, 0, 0,'3', 0, 0,'9', 0, 0
  122. ; Same values, but shifted
  123. kbdScanCodesS:
  124. ; 0x00 1 2 3 4 5 6 7 8 9 a b c d e f
  125. .db 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,'~', 0
  126. ; 0x10 9 = TAB
  127. .db 0, 0, 0, 0, 0,'Q','!', 0, 0, 0,'Z','S','A','W','@', 0
  128. ; 0x20 32 = SPACE
  129. .db 0,'C','X','D','E','$','#', 0, 0, 32,'V','F','T','R','%', 0
  130. ; 0x30
  131. .db 0,'N','B','H','G','Y','^', 0, 0, 0,'M','J','U','&','*', 0
  132. ; 0x40 59 = ;
  133. .db 0,'<','K','I','O',')','(', 0, 0,'>','?','L',':','P','_', 0
  134. ; 0x50 13 = RETURN
  135. .db 0, 0,'"', 0,'{','+', 0, 0, 0, 0, 13,'}', 0,'|', 0, 0
  136. ; 0x60 8 = BKSP
  137. .db 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0
  138. ; 0x70 27 = ESC
  139. .db 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0