;; vim: syntax=fasm
+;; At compile-time we load the module given by the environment variable
+;; OS_INCLUDE. This module should define the following macros:
+;;
+;; Each of these functions should preserve the value of RSI and RSP. They may
+;; use other registers as they like.
+;;
+;; os_initialize
+;; Called at initialization.
+;;
+;; os_print_string
+;; Takes a string buffer in RCX and the length in RDX, and prints the string
+;; to the console.
+;;
+;; os_read_char
+;; Wait for the user to type a key, and then put the corresponding ASCII byte
+;; into the buffer pointed to by RCX.
+;;
+;; os_terminate
+;; Shut down the system.
include '%OS_INCLUDE%'
;; Print a string of a given length.
push r9
push r10
- call uefi_print_string
+ call os_print_string
pop r10
pop r9
push r15
mov rcx, rsi
- call uefi_read_char
+ call os_read_char
pop r15
pop r10
macro sys_terminate code {
mov rax, code
- call uefi_terminate
+ call os_terminate
}
;; The code in this macro is placed at the end of each Forth word. When we are
cld ; Clear direction flag so LODSQ does the right thing.
mov rbp, return_stack_top ; Initialize return stack
- call uefi_initialize
+ call os_initialize
mov rax, MAIN
jmp qword [rax]
section '.text' code executable readable
-uefi_initialize:
+os_initialize:
; At program startup, RDX contains an EFI_SYSTEM_TABLE*.
mov [system_table], rdx
ret
-;; Print a string of the given length.
-;;
-;; Inputs:
-;; - RCX = String buffer
-;; - RDX = String length
-uefi_print_string:
+os_print_string:
;; We take an input string of bytes without any terminator. We need to turn
;; this string into a string of words, terminated by a null character.
add rsp, 32
ret
-;; Read a character as an ASCII byte into the given buffer.
-;;
-;; Inputs:
-;; - RCX = Character buffer (1 byte)
-uefi_read_char:
+os_read_char:
mov r15, rcx
.read_key:
mov rcx, [system_table] ; EFI_SYSTEM_TABLE* rcx
;; Print the character
mov rcx, r15
mov rdx, 1
- call uefi_print_string
+ call os_print_string
ret
;;
;; Inputs:
;; - RCX = Error code
-uefi_terminate:
+os_terminate:
mov rcx, terminated_msg
mov rdx, terminated_msg.len
- call uefi_print_string
+ call os_print_string
jmp $
section '.data' readable writable
terminated_msg db 0xD, 0xA, '(The program has terminated.)', 0xD, 0xA
.len = $ - terminated_msg
-uefi_print_string.output_buffer rq 0x400
+os_print_string.output_buffer rq 0x400
char_buffer db ?