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.

234 lines
4.2KB

  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. ;
  14. ; All numerical values in the Collapse OS shell are represented and parsed in
  15. ; hexadecimal form, without prefix or suffix.
  16. ; *** CONSTS ***
  17. ; number of entries in shellCmdTbl
  18. SHELL_CMD_COUNT .equ 2
  19. ; The command that was type isn't known to the shell
  20. SHELL_ERR_UNKNOWN_CMD .equ 0x01
  21. ; Arguments for the command weren't properly formatted
  22. SHELL_ERR_BAD_ARGS .equ 0x02
  23. ; *** VARIABLES ***
  24. ; Memory address that the shell is currently "pointing at" for peek and deek
  25. ; operations. Set with seek.
  26. SHELL_MEM_PTR .equ SHELL_RAMSTART
  27. ; Used to store formatted hex values just before printing it.
  28. SHELL_HEX_FMT .equ SHELL_MEM_PTR+2
  29. SHELL_RAMEND .equ SHELL_HEX_FMT+2
  30. ; *** CODE ***
  31. shellInit:
  32. xor a
  33. ld (SHELL_MEM_PTR), a
  34. ; print prompt
  35. ld hl, .prompt
  36. call printstr
  37. call printcrlf
  38. ret
  39. .prompt:
  40. .db "Collapse OS", 0
  41. shellLoop:
  42. ; check if the input buffer is full or ends in CR or LF. If it does,
  43. ; prints it back and empty it.
  44. call aciaBufPtr
  45. cp 0
  46. jr z, shellLoop ; BUFIDX is zero? nothing to check.
  47. cp ACIA_BUFSIZE
  48. jr z, .do ; if BUFIDX == BUFSIZE? do!
  49. ; our previous char is in BUFIDX - 1. Fetch this
  50. dec hl
  51. ld a, (hl) ; now, that's our char we have in A
  52. inc hl ; put HL back where it was
  53. cp ASCII_CR
  54. jr z, .do ; char is CR? do!
  55. cp ASCII_LF
  56. jr z, .do ; char is LF? do!
  57. ; nothing matched? don't do anything
  58. jr shellLoop
  59. .do:
  60. ; terminate our string with 0
  61. xor a
  62. ld (hl), a
  63. ; reset buffer index
  64. ld (ACIA_BUFIDX), a
  65. ; alright, let's go!
  66. ld hl, ACIA_BUF
  67. call shellParse
  68. jr shellLoop
  69. printcrlf:
  70. ld a, ASCII_CR
  71. call aciaPutC
  72. ld a, ASCII_LF
  73. call aciaPutC
  74. ret
  75. ; Parse command (null terminated) at HL and calls it
  76. shellParse:
  77. push af
  78. push bc
  79. push de
  80. push hl
  81. ld de, shellCmdTbl
  82. ld a, SHELL_CMD_COUNT
  83. ld b, a
  84. .loop:
  85. ld a, 4 ; 4 chars to compare
  86. call strncmp
  87. jr z, .found
  88. ld a, 6
  89. call addDE
  90. djnz .loop
  91. ; exhausted loop? not found
  92. ld a, SHELL_ERR_UNKNOWN_CMD
  93. call shellPrintErr
  94. jr .end
  95. .found:
  96. ; all right, we're almost ready to call the cmd. Let's just have DE
  97. ; point to the cmd jump line.
  98. ld a, 4
  99. call addDE
  100. ; Now, let's swap HL and DE because, welll because that's how we're set.
  101. ex hl, de ; HL = jump line, DE = cmd str pointer
  102. ; Before we call our command, we want to set up the pointer to the arg
  103. ; list. Normally, it's DE+5 (DE+4 is the space) unless DE+4 is null,
  104. ; which means no arg.
  105. ld a, 4
  106. call addDE
  107. ld a, (DE)
  108. cp 0
  109. jr z, .noarg ; char is null? we have no arg
  110. inc de
  111. .noarg:
  112. ; DE points to args, HL points to jump line. Ready to roll!
  113. call jumpHL
  114. .end:
  115. pop hl
  116. pop de
  117. pop bc
  118. pop af
  119. ret
  120. ; Print the error code set in A (in hex)
  121. shellPrintErr:
  122. push af
  123. push hl
  124. ld hl, .str
  125. call printstr
  126. ld hl, SHELL_HEX_FMT
  127. call fmtHexPair
  128. ld a, 2
  129. call printnstr
  130. call printcrlf
  131. pop hl
  132. pop af
  133. ret
  134. .str:
  135. .db "ERR ", 0
  136. ; *** COMMANDS ***
  137. ; When these commands are called, DE points to the first character of the
  138. ; command args.
  139. ; Set memory pointer to the specified address.
  140. ; Example: seek 01fe
  141. shellSeek:
  142. push de
  143. push hl
  144. ex de, hl
  145. call parseHexPair
  146. jr c, .error
  147. ld (SHELL_MEM_PTR), a
  148. inc hl
  149. inc hl
  150. call parseHexPair
  151. jr c, .error
  152. ld (SHELL_MEM_PTR+1), a
  153. jr .success
  154. .error:
  155. ld a, SHELL_ERR_BAD_ARGS
  156. call shellPrintErr
  157. jr .end
  158. .success:
  159. ld a, (SHELL_MEM_PTR)
  160. ld hl, SHELL_HEX_FMT
  161. call fmtHexPair
  162. ld a, 2
  163. call printnstr
  164. ld a, (SHELL_MEM_PTR+1)
  165. call fmtHexPair
  166. ld a, 2
  167. call printnstr
  168. call printcrlf
  169. .end:
  170. pop hl
  171. pop de
  172. ret
  173. ; peek byte where memory pointer points to aby display its value
  174. shellPeek:
  175. push af
  176. push hl
  177. ld hl, (SHELL_MEM_PTR)
  178. ld a, (hl)
  179. ld hl, SHELL_HEX_FMT
  180. call fmtHexPair
  181. ld a, 2
  182. call printnstr
  183. call printcrlf
  184. pop hl
  185. pop af
  186. ret
  187. ; Format: 4 bytes name followed by 2 bytes jump. fill names with zeroes
  188. shellCmdTbl:
  189. .db "seek"
  190. jr shellSeek
  191. .db "peek"
  192. jr shellPeek