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.

171 lines
3.6KB

  1. ; stdio
  2. ;
  3. ; Allows other modules to print to "standard out", and get data from "standard
  4. ; in", that is, the console through which the user is connected in a decoupled
  5. ; manner.
  6. ;
  7. ; Those GetC/PutC routines are hooked through defines and have this API:
  8. ;
  9. ; GetC: Blocks until a character is read from the device and return that
  10. ; character in A.
  11. ;
  12. ; PutC: Write character specified in A onto the device.
  13. ;
  14. ; *** Accepted characters ***
  15. ;
  16. ; For now, we're in muddy waters in this regard. We try to stay close to ASCII.
  17. ; Anything over 0x7f is undefined. Both CR and LF are interpreted as "line end".
  18. ; Both BS and DEL mean "delete previous character".
  19. ;
  20. ; When outputting, newlines are marked by CR and LF. Outputting a character
  21. ; deletion is made through BS then space then BS.
  22. ;
  23. ; *** Defines ***
  24. ; STDIO_GETC: address of a GetC routine
  25. ; STDIO_PUTC: address of a PutC routine
  26. ;
  27. ; *** Consts ***
  28. ; Size of the readline buffer. If a typed line reaches this size, the line is
  29. ; flushed immediately (same as pressing return).
  30. .equ STDIO_BUFSIZE 0x20
  31. ; *** Variables ***
  32. ; Used to store formatted hex values just before printing it.
  33. .equ STDIO_HEX_FMT STDIO_RAMSTART
  34. ; Line buffer. We read types chars into this buffer until return is pressed
  35. ; This buffer is null-terminated.
  36. .equ STDIO_BUF @+2
  37. ; Index where the next char will go in stdioGetC.
  38. .equ STDIO_RAMEND @+STDIO_BUFSIZE
  39. stdioGetC:
  40. jp STDIO_GETC
  41. stdioPutC:
  42. jp STDIO_PUTC
  43. ; print null-terminated string pointed to by HL
  44. printstr:
  45. push af
  46. push hl
  47. .loop:
  48. ld a, (hl) ; load character to send
  49. or a ; is it zero?
  50. jr z, .end ; if yes, we're finished
  51. call STDIO_PUTC
  52. inc hl
  53. jr .loop
  54. .end:
  55. pop hl
  56. pop af
  57. ret
  58. ; print B characters from string that HL points to
  59. printnstr:
  60. push bc
  61. push hl
  62. .loop:
  63. ld a, (hl) ; load character to send
  64. call STDIO_PUTC
  65. inc hl
  66. djnz .loop
  67. .end:
  68. pop hl
  69. pop bc
  70. ret
  71. printcrlf:
  72. push af
  73. ld a, ASCII_CR
  74. call STDIO_PUTC
  75. ld a, ASCII_LF
  76. call STDIO_PUTC
  77. pop af
  78. ret
  79. ; Print the hex char in A
  80. printHex:
  81. push bc
  82. push hl
  83. ld hl, STDIO_HEX_FMT
  84. call fmtHexPair
  85. ld b, 2
  86. call printnstr
  87. pop hl
  88. pop bc
  89. ret
  90. ; Print the hex pair in HL
  91. printHexPair:
  92. push af
  93. ld a, h
  94. call printHex
  95. ld a, l
  96. call printHex
  97. pop af
  98. ret
  99. ; Repeatedly calls stdioGetC until a whole line was read, that is, when CR or
  100. ; LF is read or if the buffer is full. Sets HL to the beginning of the read
  101. ; line, which is null-terminated.
  102. ;
  103. ; This routine also takes care of echoing received characters back to the TTY.
  104. ; It also manages backspaces properly.
  105. stdioReadLine:
  106. push bc
  107. ld hl, STDIO_BUF
  108. ld b, STDIO_BUFSIZE-1
  109. .loop:
  110. ; Let's wait until something is typed.
  111. call STDIO_GETC
  112. ; got it. Now, is it a CR or LF?
  113. cp ASCII_CR
  114. jr z, .complete ; char is CR? buffer complete!
  115. cp ASCII_LF
  116. jr z, .complete
  117. cp ASCII_DEL
  118. jr z, .delchr
  119. cp ASCII_BS
  120. jr z, .delchr
  121. ; Echo the received character right away so that we see what we type
  122. call STDIO_PUTC
  123. ; Ok, gotta add it do the buffer
  124. ld (hl), a
  125. inc hl
  126. djnz .loop
  127. ; buffer overflow, complete line
  128. .complete:
  129. ; The line in our buffer is complete.
  130. ; Let's null-terminate it and return.
  131. xor a
  132. ld (hl), a
  133. ld hl, STDIO_BUF
  134. pop bc
  135. ret
  136. .delchr:
  137. ; Deleting is a tricky business. We have to decrease HL and increase B
  138. ; so that everything stays consistent. We also have to make sure that
  139. ; We don't do buffer underflows.
  140. ld a, b
  141. cp STDIO_BUFSIZE-1
  142. jr z, .loop ; beginning of line, nothing to delete
  143. dec hl
  144. inc b
  145. ; Char deleted in buffer, now send BS + space + BS for the terminal
  146. ; to clear its previous char
  147. ld a, ASCII_BS
  148. call STDIO_PUTC
  149. ld a, ' '
  150. call STDIO_PUTC
  151. ld a, ASCII_BS
  152. call STDIO_PUTC
  153. jr .loop