reformat to 80 columns
[rrq/jonasforth.git] / src / main.asm
index d1d89fb159a71c3a928867094aa499ee9213c4dc..3af5713ba81790adf989d42a777bf744c59f0409 100644 (file)
@@ -1,5 +1,6 @@
-;; The UEFI module defines the following functions. Each of these functions
-;; preserve the value of RSI and RSP. They may use other registers as they like.
+;; The UEFI module defines the following functions. Each of these
+;; functions preserve the value of RSI and RSP. They may use other
+;; registers as they like.
 ;;
 ;; os_initialize
 ;;   Called at initialization.
@@ -14,6 +15,7 @@
 ;;
 ;; os_terminate
 ;;   Shut down the system, returning the error code given in RAX.
+
 include 'src/uefi.asm'
 
 ;; The code in this macro is placed at the end of each Forth word. When we are
@@ -66,7 +68,8 @@ label:
 initial_latest_entry = label#_entry
 }
 
-;; Define a Forth word that is implemented in assembly. See 'header' for details.
+;; Define a Forth word that is implemented in assembly. See 'header'
+;; for details.
 macro forth_asm label, name, immediate {
   header label, name, immediate
   dq .start
@@ -79,7 +82,7 @@ include "impl.asm"      ; Misc. subroutines
 include "bootstrap.asm" ; Forth words encoded in Assembly
 
 main:
-  cld                        ; Clear direction flag so LODSQ does the right thing.
+  cld                     ; Clear direction flag so LODSQ does the right thing.
   mov rbp, return_stack_top  ; Initialize return stack
 
   call os_initialize
@@ -89,12 +92,15 @@ main:
 
 program: dq MAIN
 
-;; The codeword is the code that will be executed at the beginning of a forth
-;; word. It needs to save the old RSI and update it to point to the next word to
-;; execute.
+;; The codeword is the code that will be executed at the beginning of
+;; a forth word. It needs to save the old RSI and update it to point
+;; to the next word to execute.
 header DOCOL, 'DOCOL'
-  pushr rsi            ; Save old value of RSI on return stack; we will continue execution there after we are done executing this word
-  lea rsi, [rax + 8]   ; RAX currently points to the address of the codeword, so we want to continue at RAX+8
+  pushr rsi            ; Save old value of RSI on return stack; we
+                      ; will continue execution there after we are
+                      ; done executing this word
+  lea rsi, [rax + 8]   ; RAX currently points to the address of the
+                      ; codeword, so we want to continue at RAX+8
   next                 ; Execute word pointed to by RSI
 
 ;; This word is called at the end of a Forth definition. It just needs to
@@ -103,16 +109,16 @@ forth_asm EXIT, 'EXIT'
   popr rsi
   next
 
-;; LIT is a special word that reads the next "word pointer" and causes it to be
-;; placed on the stack rather than executed.
+;; LIT is a special word that reads the next "word pointer" and causes
+;; it to be placed on the stack rather than executed.
 forth_asm LIT, 'LIT'
   lodsq
   push rax
   next
 
-;; When LITSTRING is encountered while executing a word, it instead reads a
-;; string from the definition of that word, and places that string on the stack
-;; as (buffer, length).
+;; When LITSTRING is encountered while executing a word, it instead
+;; reads a string from the definition of that word, and places that
+;; string on the stack as (buffer, length).
 forth_asm LITSTRING, 'LITSTRING'
   lodsb
   push rsi ; Buffer
@@ -121,8 +127,9 @@ forth_asm LITSTRING, 'LITSTRING'
   add rsi, rax ; Skip over string before resuming execution
   next
 
-;; Given a string (a pointer following by a size), return the location of the
-;; dictionary entry for that word. If no such word exists, return 0.
+;; Given a string (a pointer following by a size), return the location
+;; of the dictionary entry for that word. If no such word exists,
+;; return 0.
 forth_asm FIND, 'FIND'
   mov [.rsi], rsi
 
@@ -139,8 +146,8 @@ forth_asm FIND, 'FIND'
   mov rsi, [.rsi]
   next
 
-;; Given an entry in the dictionary, return a pointer to the codeword of that
-;; entry.
+;; Given an entry in the dictionary, return a pointer to the codeword
+;; of that entry.
 forth_asm TCFA, '>CFA'
   pop rax
   add rax, 8 + 1                ; [rax] = length of name
@@ -150,22 +157,25 @@ forth_asm TCFA, '>CFA'
   push rax
   next
 
-;; BRANCH is the fundamental mechanism for branching. BRANCH reads the next word
-;; as a signed integer literal and jumps by that offset.
+;; BRANCH is the fundamental mechanism for branching. BRANCH reads the
+;; next word as a signed integer literal and jumps by that offset.
+
 forth_asm BRANCH, 'BRANCH'
-  add rsi, [rsi] ; [RSI], which is the next word, contains the offset; we add this to the instruction pointer.
+  add rsi, [rsi] ; [RSI], which is the next word, contains the offset
+                ; we add this to the instruction pointer.
   next           ; Then, we can just continue execution as normal
 
-;; 0BRANCH is like BRANCH, but it jumps only if the top of the stack is zero.
+;; 0BRANCH is like BRANCH, but it jumps only if the top of the stack
+;; is zero.
 forth_asm ZBRANCH, '0BRANCH'
-  ;; Compare top of stack to see if we should branch
   pop rax
-  cmp rax, 0
+  cmp rax, 0    ; Compare top of stack to see if we should branch
   jnz .dont_branch
 .do_branch:
   jmp BRANCH.start
 .dont_branch:
-  add rsi, 8     ; We need to skip over the next word, which contains the offset.
+  add rsi, 8     ; We need to skip over the next word, which contains
+                ; the offset.
   next
 
 ;; Duplicate the top of the stack.
@@ -192,10 +202,10 @@ forth_asm EMIT, 'EMIT'
   popr rsi
   next
 
-;; Read a single character from the current input stream. Usually, this will wait
-;; for the user to press a key, and then return the corresponding character. When
-;; reading from a special buffer, it will instead return the next characater from
-;; that buffer.
+;; Read a single character from the current input stream. Usually,
+;; this will wait for the user to press a key, and then return the
+;; corresponding character. When reading from a special buffer, it
+;; will instead return the next characater from that buffer.
 ;;
 ;; The ASCII character code is placed on the stack.
 forth_asm KEY, 'KEY'
@@ -222,8 +232,8 @@ forth_asm KEY, 'KEY'
   dec [input_buffer_length]
   ret
 
-;; Read a word and push it onto the stack as a pointer and a size. The pointer
-;; is valid until the next call to READ_WORD.
+;; Read a word and push it onto the stack as a pointer and a size. The
+;; pointer is valid until the next call to READ_WORD.
 forth_asm READ_WORD, 'READ-WORD'
   push rsi
 .skip_whitespace:
@@ -260,8 +270,8 @@ forth_asm READ_WORD, 'READ-WORD'
 
   next
 
-;; Takes a string on the stack and replaces it with the decimal number that the
-;; string represents.
+;; Takes a string on the stack and replaces it with the decimal number
+;; that the string represents.
 forth_asm PARSE_NUMBER, 'PARSE-NUMBER'
   pop rcx     ; Length
   pop rdi     ; String pointer
@@ -419,8 +429,8 @@ forth_asm PLUS, '+'
   push rax
   next
 
-;; Calculate difference between two integers on the stack. The second number is
-;; subtracted from the first.
+;; Calculate difference between two integers on the stack. The second
+;; number is subtracted from the first.
 forth_asm MINUS, '-'
   pop rax
   pop rbx
@@ -439,9 +449,10 @@ forth_asm TIMESMOD, '/MOD'
   push rdx                      ; a % b
   next
 
-;; Read input until next " character is found. Push a string containing the
-;; input on the stack as (buffer length). Note that the buffer is only valid
-;; until the next call to S" and that no more than 255 characters can be read.
+;; Read input until next " character is found. Push a string
+;; containing the input on the stack as (buffer length). Note that the
+;; buffer is only valid until the next call to S" and that no more
+;; than 255 characters can be read.
 forth_asm READ_STRING, 'S"'
   ;; If the input buffer is set, we should read from there instead.
   cmp [input_buffer], 0
@@ -504,11 +515,12 @@ read_string_buffer:
 
   next
 
-;; CREATE inserts a new header in the dictionary, and updates LATEST so that it
-;; points to the header. To compile a word, the user can then call ',' to
-;; continue to append data after the header.
+;; CREATE inserts a new header in the dictionary, and updates LATEST
+;; so that it points to the header. To compile a word, the user can
+;; then call ',' to continue to append data after the header.
 ;;
-;; It takes the name of the word as a string (address length) on the stack.
+;; It takes the name of the word as a string (address length) on the
+;; stack.
 forth_asm CREATE, 'CREATE'
   pop rcx                       ; Word string length
   pop rdx                       ; Word string pointer
@@ -583,6 +595,16 @@ forth EFI_SYSTEM_TABLE_CONSTANT, 'SystemTable'
   dq LIT, system_table, GET
   dq EXIT
 
+forth_asm EFICALL1, 'EFICALL1'
+  pop rax ; function pointer
+  pop rcx ; 1st argument
+
+  sub rsp, 32
+  call rax
+  add rsp, 32
+
+  next
+
 forth_asm EFICALL2, 'EFICALL2'
   pop rax ; function pointer
   pop rdx ; 2nd argument
@@ -669,18 +691,18 @@ forth INPUT_LENGTH, 'INPUT-LENGTH'
 
 section '.data' readable writable
 
-;; The LATEST variable holds a pointer to the word that was last added to the
-;; dictionary. This pointer is updated as new words are added, and its value is
-;; used by FIND to look up words.
+;; The LATEST variable holds a pointer to the word that was last added
+;; to the dictionary. This pointer is updated as new words are added,
+;; and its value is used by FIND to look up words.
 latest_entry dq initial_latest_entry
 
-;; The STATE variable is 0 when the interpreter is executing, and non-zero when
-;; it is compiling.
+;; The STATE variable is 0 when the interpreter is executing, and
+;; non-zero when it is compiling.
 var_STATE dq 0
 
-;; The interpreter can read either from standard input or from a buffer. When
-;; input-buffer is set (non-null), words like READ-WORD and S" will use this
-;; buffer instead of reading user input.
+;; The interpreter can read either from standard input or from a
+;; buffer. When input-buffer is set (non-null), words like READ-WORD
+;; and S" will use this buffer instead of reading user input.
 input_buffer dq 0
 input_buffer_length dq 0
 
@@ -694,7 +716,7 @@ READ_STRING.buffer rb $FF
 READ_STRING.length dq ?
 
 DOTU.chars db '0123456789ABCDEF'
-DOTU.buffer rq 16               ; 64-bit number has no more than 16 digits in hex
+DOTU.buffer rq 16     ; 64-bit number has no more than 16 digits in hex
 DOTU.rbuffer rq 16
 DOTU.length dq ?
 DOTU.printed_length dq ?
@@ -712,9 +734,10 @@ here_top rq $4000
 rq $2000
 return_stack_top:
 
-;; We store some Forth code in sys.f that defined common words that the user
-;; would expect to have available at startup. To execute these words, we just
-;; include the file directly in the binary, and then interpret it at startup.
+;; We store some Forth code in sys.f that defined common words that
+;; the user would expect to have available at startup. To execute
+;; these words, we just include the file directly in the binary, and
+;; then interpret it at startup.
 sysf:
 file '../init/sys.f'
 file '../init/uefi.f'