stage0_monitor.s 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  1. ; Copyright (C) 2016 Jeremiah Orians
  2. ; This file is part of stage0.
  3. ;
  4. ; stage0 is free software: you can redistribute it and/or modify
  5. ; it under the terms of the GNU General Public License as published by
  6. ; the Free Software Foundation, either version 3 of the License, or
  7. ; (at your option) any later version.
  8. ;
  9. ; stage0 is distributed in the hope that it will be useful,
  10. ; but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. ; GNU General Public License for more details.
  13. ;
  14. ; You should have received a copy of the GNU General Public License
  15. ; along with stage0. If not, see <http://www.gnu.org/licenses/>.
  16. BITS 16
  17. ;; Steps for building
  18. ;; nasm -o stage0_monitor stage0_monitor.s
  19. ;;
  20. ;; Steps for testing
  21. ;; qemu -fda stage0_monitor
  22. start:
  23. mov sp, 256 ; Allocate 256B for stack
  24. mov ax, 07E00h ; Which is much more than we need
  25. mov ss, ax ; And stopping before this code
  26. mov ax, 01000h ; Select Wide open segment via ES
  27. mov es, ax ; Where we will be shoving things
  28. mov bp, 0 ; Starting at index 0
  29. mov ax, 0
  30. mov di, 1 ; Our toggle
  31. mov si, 0 ; Our holder
  32. loop:
  33. call read_char
  34. ;; Check for C-d
  35. cmp al, 4
  36. jne .L0
  37. call execute_code
  38. jmp loop
  39. .L0:
  40. ;; Check for C-l
  41. cmp al, 12
  42. jne .L1
  43. call clear_screen
  44. jmp loop
  45. .L1:
  46. ;; Check for [Enter]
  47. cmp al, 13
  48. jne .L2
  49. call display_newline
  50. jmp loop
  51. .L2:
  52. ;; Otherwise just print the char
  53. call print_char ; Show the user what they input
  54. call hex ; Convert to what we want
  55. cmp al, 0 ; Check if it is hex
  56. jl loop ; Don't use nonhex chars
  57. cmp di, 0 ; Check if toggled
  58. je .L99 ; Jump if toggled
  59. ;; Process first byte of pair
  60. mov si, 0Fh ; Mask out top
  61. and si, ax ; Store first nibble
  62. mov di, 0 ; Flip the toggle
  63. jmp loop
  64. .L99:
  65. shl si, 4 ; shift our first nibble
  66. and ax, 0Fh ; Mask out top
  67. add ax, si ; Combine nibbles
  68. mov di, 1 ; Flip the toggle
  69. mov bx, bp ; Index registers are weird
  70. mov [es:bx], al ; Write our byte out
  71. add bp, 1 ; Increment our pointer by 1
  72. call insert_spacer
  73. jmp loop
  74. print_char:
  75. ; Routine: output char in al to screen
  76. mov ah, 0Eh ; int 10h 'print char' function
  77. int 10h ; print it
  78. ret
  79. read_char:
  80. ;; Routine: read a char into al
  81. mov ah, 00h
  82. int 16h
  83. ret
  84. clear_screen:
  85. ;; Routine: clears the display
  86. mov al, 0 ; Clear screen
  87. mov ah, 06h ; Scroll up
  88. mov bh, 07h ; Move Color
  89. mov cl, 0 ; UL x coordinate
  90. mov ch, 0 ; UL y coordinate
  91. mov dl, 80 ; LR x coordinate
  92. mov dh, 24 ; LR y coordinate
  93. int 10h
  94. ;; Routine: reset the cursor
  95. mov ah, 02h ; Set cursor position
  96. mov bh, 0 ; Set Page number to 0
  97. mov dh, 0 ; Set Row Number
  98. mov dl, 0 ; Set Column Number
  99. int 10h
  100. ret
  101. display_newline:
  102. ;; Routine for determining if we should scroll or move cursor
  103. call get_cursor_position
  104. cmp ah, 12
  105. jle .L0
  106. call scroll_window
  107. ret
  108. .L0:
  109. ;; Routine: Move the cursor down
  110. mov dh, 1 ; How many rows we want to move
  111. add dh, ah ; Add our current Row Number
  112. mov ah, 02h ; Set cursor position
  113. mov bh, 0 ; Set Page number to 0
  114. mov dl, 0 ; Set Column Number
  115. int 10h
  116. mov al, 13 ; Print a new line
  117. call print_char
  118. ret
  119. get_cursor_position:
  120. ;; Routine for getting cursor position
  121. mov ah, 03h ; Request Cursor position
  122. mov bh, 0 ; For page 0
  123. int 10h
  124. mov ax, dx ; Mov the row and column into ax
  125. ret
  126. scroll_window:
  127. ;; Routine scroll window up
  128. mov al, 1 ; Move the line up one
  129. mov ah, 06h ; Scroll up
  130. mov bh, 07h ; Move Color
  131. mov cl, 0 ; UL x coordinate
  132. mov ch, 0 ; UL y coordinate
  133. mov dl, 80 ; LR x coordinate
  134. mov dh, 24 ; LR y coordinate
  135. int 10h
  136. mov al, 13 ; Print a new line
  137. call print_char
  138. ret
  139. hex:
  140. ; deal with line comments starting with #
  141. cmp al, 35
  142. je ascii_comment
  143. ; deal with line comments starting with ;
  144. cmp al, 59
  145. je ascii_comment
  146. ; deal all ascii less than 0
  147. cmp al, 48
  148. jl ascii_other
  149. ; deal with 0-9
  150. cmp al, 58
  151. jl ascii_num
  152. ; deal with all ascii less than A
  153. cmp al, 65
  154. jl ascii_other
  155. ; deal with A-F
  156. cmp al, 71
  157. jl ascii_high
  158. ; deal with all ascii less than a
  159. cmp al, 97
  160. jl ascii_other
  161. ; deal with a-f
  162. cmp al, 103
  163. jl ascii_low
  164. ; The rest that remains needs to be ignored
  165. jmp ascii_other
  166. ascii_num:
  167. sub al, 48
  168. ret
  169. ascii_low:
  170. sub al, 87
  171. ret
  172. ascii_high:
  173. sub al, 55
  174. ret
  175. ascii_other:
  176. mov al, -1
  177. ret
  178. ascii_comment:
  179. call read_char
  180. call print_char
  181. cmp al, 13
  182. jne ascii_comment
  183. call scroll_window
  184. jmp ascii_other
  185. execute_code:
  186. ;; Clear the screen to be nice
  187. call clear_screen
  188. ;; Zero all registers and segments before jump
  189. mov ax, 0
  190. mov bx, 0
  191. mov cx, 0
  192. mov dx, 0
  193. mov si, 0
  194. mov di, 0
  195. mov bp, 0
  196. mov ds, ax
  197. mov ss, ax
  198. mov es, ax
  199. mov fs, ax
  200. mov gs, ax
  201. ;; Load the code that we input by hand
  202. push 01000h
  203. push 0h
  204. ;; Using intersegment return
  205. iret
  206. insert_spacer:
  207. mov al, 32
  208. call print_char
  209. ret
  210. done:
  211. hlt
  212. times 510-($-$$) db 90h ; Pad remainder of boot sector with NOPs
  213. dw 0xAA55 ; The standard PC boot signature