keyboard.s 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. /******************************************************************************
  2. * keyboard.s
  3. * by Alex Chadwick
  4. *
  5. * A sample assembly code implementation of the input01 operating system.
  6. * See main.s for details.
  7. *
  8. * keyboard.s contains code to do with the keyboard.
  9. ******************************************************************************/
  10. .section .data
  11. /* NEW
  12. * The address of the keyboard we're reading from.
  13. * C++ Signautre: u32 KeyboardAddress;
  14. */
  15. .align 2
  16. KeyboardAddress:
  17. .int 0
  18. /* NEW
  19. * The scan codes that were down before the current set on the keyboard.
  20. * C++ Signautre: u16* KeyboardOldDown;
  21. */
  22. KeyboardOldDown:
  23. .rept 6
  24. .hword 0
  25. .endr
  26. /* NEW
  27. * KeysNoShift contains the ascii representations of the first 104 scan codes
  28. * when the shift key is up. Special keys are ignored.
  29. * C++ Signature: char* KeysNoShift;
  30. */
  31. .align 3
  32. KeysNormal:
  33. .byte 0x0, 0x0, 0x0, 0x0, 'a', 'b', 'c', 'd'
  34. .byte 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'
  35. .byte 'm', 'n', 'o', 'p', 'q', 'r', 's', 't'
  36. .byte 'u', 'v', 'w', 'x', 'y', 'z', '1', '2'
  37. .byte '3', '4', '5', '6', '7', '8', '9', '0'
  38. .byte '\n', 0x0, '\b', '\t', ' ', '-', '=', '['
  39. .byte ']', '\\', '#', ';', '\'', '`', ',', '.'
  40. .byte '/', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
  41. .byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
  42. .byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
  43. .byte 0x0, 0x0, 0x0, 0x0, '/', '*', '-', '+'
  44. .byte '\n', '1', '2', '3', '4', '5', '6', '7'
  45. .byte '8', '9', '0', '.', '\\', 0x0, 0x0, '='
  46. /* NEW
  47. * KeysShift contains the ascii representations of the first 104 scan codes
  48. * when the shift key is held. Special keys are ignored.
  49. * C++ Signature: char* KeysShift;
  50. */
  51. .align 3
  52. KeysShift:
  53. .byte 0x0, 0x0, 0x0, 0x0, 'A', 'B', 'C', 'D'
  54. .byte 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L'
  55. .byte 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T'
  56. .byte 'U', 'V', 'W', 'X', 'Y', 'Z', '!', '"'
  57. .byte '£', '$', '%', '^', '&', '*', '(', ')'
  58. .byte '\n', 0x0, '\b', '\t', ' ', '_', '+', '{'
  59. .byte '}', '|', '~', ':', '@', '¬', '<', '>'
  60. .byte '?', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
  61. .byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
  62. .byte 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0
  63. .byte 0x0, 0x0, 0x0, 0x0, '/', '*', '-', '+'
  64. .byte '\n', '1', '2', '3', '4', '5', '6', '7'
  65. .byte '8', '9', '0', '.', '|', 0x0, 0x0, '='
  66. .section .text
  67. /* NEW
  68. * Updates the keyboard pressed and released data.
  69. * C++ Signature: void KeyboardUpdate();
  70. */
  71. .globl KeyboardUpdate
  72. KeyboardUpdate:
  73. push {r4,r5,lr}
  74. kbd .req r4
  75. ldr r0,=KeyboardAddress
  76. ldr kbd,[r0]
  77. teq kbd,#0
  78. bne haveKeyboard$
  79. getKeyboard$:
  80. bl UsbCheckForChange
  81. bl KeyboardCount
  82. teq r0,#0
  83. ldreq r1,=KeyboardAddress
  84. streq r0,[r1]
  85. beq return$
  86. mov r0,#0
  87. bl KeyboardGetAddress
  88. ldr r1,=KeyboardAddress
  89. str r0,[r1]
  90. teq r0,#0
  91. beq return$
  92. mov kbd,r0
  93. haveKeyboard$:
  94. mov r5,#0
  95. saveKeys$:
  96. mov r0,kbd
  97. mov r1,r5
  98. bl KeyboardGetKeyDown
  99. ldr r1,=KeyboardOldDown
  100. add r1,r5,lsl #1
  101. strh r0,[r1]
  102. add r5,#1
  103. cmp r5,#6
  104. blt saveKeys$
  105. mov r0,kbd
  106. bl KeyboardPoll
  107. teq r0,#0
  108. bne getKeyboard$
  109. return$:
  110. pop {r4,r5,pc}
  111. .unreq kbd
  112. /* NEW
  113. * Returns r0=0 if a in r1 key was not pressed before the current scan, and r0
  114. * not 0 otherwise.
  115. * C++ Signature bool KeyWasDown(u16 scanCode)
  116. */
  117. .globl KeyWasDown
  118. KeyWasDown:
  119. ldr r1,=KeyboardOldDown
  120. mov r2,#0
  121. keySearch$:
  122. ldrh r3,[r1]
  123. teq r3,r0
  124. moveq r0,#1
  125. moveq pc,lr
  126. add r1,#2
  127. add r2,#1
  128. cmp r2,#6
  129. blt keySearch$
  130. mov r0,#0
  131. mov pc,lr
  132. /* NEW
  133. * Returns the ascii character last typed on the keyboard, with r0=0 if no
  134. * character was typed.
  135. * C++ Signature char KeyboardGetChar()
  136. */
  137. .globl KeyboardGetChar
  138. KeyboardGetChar:
  139. ldr r0,=KeyboardAddress
  140. ldr r1,[r0]
  141. teq r1,#0
  142. moveq r0,#0
  143. moveq pc,lr
  144. push {r4,r5,r6,lr}
  145. kbd .req r4
  146. key .req r6
  147. mov r4,r1
  148. mov r5,#0
  149. keyLoop$:
  150. mov r0,kbd
  151. mov r1,r5
  152. bl KeyboardGetKeyDown
  153. teq r0,#0
  154. beq keyLoopBreak$
  155. mov key,r0
  156. bl KeyWasDown
  157. teq r0,#0
  158. bne keyLoopContinue$
  159. cmp key,#104
  160. bge keyLoopContinue$
  161. mov r0,kbd
  162. bl KeyboardGetModifiers
  163. tst r0,#0b00100010
  164. ldreq r0,=KeysNormal
  165. ldrne r0,=KeysShift
  166. ldrb r0,[r0,key]
  167. teq r0,#0
  168. bne keyboardGetCharReturn$
  169. keyLoopContinue$:
  170. add r5,#1
  171. cmp r5,#6
  172. blt keyLoop$
  173. keyLoopBreak$:
  174. mov r0,#0
  175. keyboardGetCharReturn$:
  176. pop {r4,r5,r6,pc}
  177. .unreq kbd
  178. .unreq key