Mirror of CollapseOS
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

222 行
3.5KB

  1. ; shell
  2. ;
  3. ; Runs a shell over an asynchronous communication interface adapter (ACIA).
  4. ; for now, this unit is tightly coupled to acia.asm, but it will eventually be
  5. ; more general than that.
  6. ; Status: incomplete. As it is now, it spits a welcome prompt, wait for input
  7. ; and compare the first 4 chars of the input with a command table and call the
  8. ; appropriate routine if it's found, an error if it's not.
  9. ;
  10. ; Commands, for now, are dummy.
  11. ;
  12. ; See constants below for error codes.
  13. ; *** CONSTS ***
  14. CR .equ 0x0d
  15. LF .equ 0x0a
  16. ; number of entries in shellCmdTbl
  17. SHELL_CMD_COUNT .equ 2
  18. ; The command that was type isn't known to the shell
  19. SHELL_ERR_UNKNOWN_CMD .equ 0x01
  20. ; Arguments for the command weren't properly formatted
  21. SHELL_ERR_BAD_ARGS .equ 0x02
  22. ; *** CODE ***
  23. shellInit:
  24. ; print prompt
  25. ld hl, .prompt
  26. call printstr
  27. call printcrlf
  28. ret
  29. .prompt:
  30. .db "Collapse OS", 0
  31. shellLoop:
  32. call chkbuf
  33. jr shellLoop
  34. ; print null-terminated string pointed to by HL
  35. printstr:
  36. push af
  37. push hl
  38. .loop:
  39. ld a, (hl) ; load character to send
  40. or a ; is it zero?
  41. jr z, .end ; if yes, we're finished
  42. call aciaPutC
  43. inc hl
  44. jr .loop
  45. .end:
  46. pop hl
  47. pop af
  48. ret
  49. printcrlf:
  50. ld a, CR
  51. call aciaPutC
  52. ld a, LF
  53. call aciaPutC
  54. ret
  55. ; check if the input buffer is full or ends in CR or LF. If it does, prints it
  56. ; back and empty it.
  57. chkbuf:
  58. call aciaBufPtr
  59. cp 0
  60. ret z ; BUFIDX is zero? nothing to check.
  61. cp ACIA_BUFSIZE
  62. jr z, .do ; if BUFIDX == BUFSIZE? do!
  63. ; our previous char is in BUFIDX - 1. Fetch this
  64. dec hl
  65. ld a, (hl) ; now, that's our char we have in A
  66. inc hl ; put HL back where it was
  67. cp CR
  68. jr z, .do ; char is CR? do!
  69. cp LF
  70. jr z, .do ; char is LF? do!
  71. ; nothing matched? don't do anything
  72. ret
  73. .do:
  74. ; terminate our string with 0
  75. xor a
  76. ld (hl), a
  77. ; reset buffer index
  78. ld (ACIA_BUFIDX), a
  79. ; alright, let's go!
  80. ld hl, ACIA_BUF
  81. call shellParse
  82. ret
  83. ; Compares strings pointed to by HL and DE up to A count of characters. If
  84. ; equal, Z is set. If not equal, Z is reset.
  85. strncmp:
  86. push bc
  87. push hl
  88. push de
  89. ld b, a
  90. .loop:
  91. ld a, (de)
  92. cp (hl)
  93. jr nz, .end ; not equal? break early
  94. inc hl
  95. inc de
  96. djnz .loop
  97. .end:
  98. pop de
  99. pop hl
  100. pop bc
  101. ; Because we don't call anything else than CP that modify the Z flag,
  102. ; our Z value will be that of the last cp (reset if we broke the loop
  103. ; early, set otherwise)
  104. ret
  105. ; add the value of A into DE
  106. addDE:
  107. add a, e
  108. jr nc, .end ; no carry? skip inc
  109. inc d
  110. .end:
  111. ld e, a
  112. ret
  113. ; jump to the location pointed to by HL. This allows us to call HL instead of
  114. ; just jumping it.
  115. jumpHL:
  116. jp hl
  117. ret
  118. ; Parse command (null terminated) at HL and calls it
  119. shellParse:
  120. push af
  121. push bc
  122. push de
  123. ld de, shellCmdTbl
  124. ld a, SHELL_CMD_COUNT
  125. ld b, a
  126. .loop:
  127. ld a, 4 ; 4 chars to compare
  128. call strncmp
  129. jr z, .found
  130. ld a, 6
  131. call addDE
  132. djnz .loop
  133. ; exhausted loop? not found
  134. ld a, SHELL_ERR_UNKNOWN_CMD
  135. call shellPrintErr
  136. jr .end
  137. .found:
  138. ld a, 4
  139. call addDE
  140. ex hl, de
  141. call jumpHL
  142. ex hl, de
  143. .end:
  144. pop de
  145. pop bc
  146. pop af
  147. ret
  148. ; Print the error code set in A (doesn't work for codes > 9 yet...)
  149. shellPrintErr:
  150. push af
  151. push hl
  152. ld hl, .str
  153. call printstr
  154. ; ascii for '0' is 0x30
  155. add a, 0x30
  156. call aciaPutC
  157. call printcrlf
  158. pop hl
  159. pop af
  160. ret
  161. .str:
  162. .db "ERR ", 0
  163. ; *** COMMANDS ***
  164. shellSeek:
  165. ld hl, .str
  166. call printstr
  167. ret
  168. .str:
  169. .db "seek called", CR, LF, 0
  170. shellPeek:
  171. ld hl, .str
  172. call printstr
  173. ret
  174. .str:
  175. .db "peek called", CR, LF, 0
  176. ; Format: 4 bytes name followed by 2 bytes jump. fill names with zeroes
  177. shellCmdTbl:
  178. .db "seek"
  179. jr shellSeek
  180. .db "peek"
  181. jr shellPeek