Add "Hello world" UEFI application
[rrq/jonasforth.git] / main.asm
index 2e880d9b36871b250057378f14c6b62b1c6c7d87..1a41bb9a2c1dc30f1050200a9e724a56885eff47 100644 (file)
--- a/main.asm
+++ b/main.asm
@@ -198,8 +198,8 @@ forth_asm READ_WORD, 'READ-WORD'
 ;; Takes a string on the stack and replaces it with the decimal number that the
 ;; string represents.
 forth_asm PARSE_NUMBER, 'PARSE-NUMBER'
-  pop [parse_number.length]     ; Length
-  pop [parse_number.buffer]     ; String pointer
+  pop rcx     ; Length
+  pop rdi     ; String pointer
 
   push rsi
   call parse_number
@@ -235,16 +235,6 @@ forth_asm TERMINATE, 'TERMINATE'
   mov rdi, 0
   syscall
 
-forth HELLO, 'HELLO'
-  dq LIT, 'H', EMIT
-  dq LIT, 'e', EMIT
-  dq LIT, 'l', EMIT
-  dq LIT, 'l', EMIT
-  dq LIT, 'o', EMIT
-  dq LIT, '!', EMIT
-  dq NEWLINE
-  dq EXIT
-
 ;; Duplicate a pair of elements.
 forth_asm PAIRDUP, '2DUP'
   pop rbx
@@ -288,18 +278,19 @@ forth INTERPRET, 'INTERPRET'
   ;; Stack is (word length word length).
   dq FIND                       ; Try to find word
   dq DUP_
-  dq ZBRANCH, 8 * 20            ; Check if word is found
+  dq ZBRANCH, 8 * 22            ; Check if word is found
 
   ;; - Word is found -
 
-  dq STATE, GET, ZBRANCH, 8 * 9 ; Check whether we are in compilation or immediate mode
+  dq STATE, GET, ZBRANCH, 8 * 11 ; Check whether we are in compilation or immediate mode
 
   ;; (Word found, compilation mode)
-  dq DUP_, IS_IMMEDIATE, NOT_, ZBRANCH, 8 * 4 ; If the word is immediate, continue as we would in immediate mode
+  dq DUP_, IS_IMMEDIATE, NOT_, ZBRANCH, 8 * 6 ; If the word is immediate, continue as we would in immediate mode
 
   ;; Otherwise, we want to compile this word
   dq TCFA
   dq COMMA
+  dq DROP, DROP
   dq EXIT
 
   ;; (Word found, immediate mode)
@@ -431,6 +422,17 @@ forth_asm MINUS, '-'
   push rbx
   next
 
+;; Given two integers a and b on the stack, pushes the quotient and remainder of
+;; division of a by b.
+forth_asm TIMESMOD, '/MOD'
+  pop rbx                       ; b
+  pop rax                       ; a
+  mov rdx, 0
+  div rbx
+  push rax                      ; a / b
+  push rdx                      ; a % b
+  next
+
 ;; Get the location of the STATE variable. It can be set with '!' and read with
 ;; '@'.
 forth STATE, 'STATE'
@@ -527,7 +529,7 @@ forth IMMEDIATE, 'IMMEDIATE', 1
   dq LIT, 1
   dq LATEST, GET
   dq LIT, 8, PLUS
-  dq PUT
+  dq PUT_BYTE
   dq EXIT
 
 ;; Given the address of a word, return 0 if the given word is not immediate.
@@ -546,8 +548,40 @@ forth OUTOF_IMMEDIATE, ']'
   dq LIT, 1, STATE, PUT_BYTE
   dq EXIT
 
+forth_asm TICK, "'"
+  lodsq
+  push rax
+  next
+
+forth_asm ROT, 'ROT'
+  pop rax
+  pop rbx
+  pop rdx
+  push rax
+  push rdx
+  push rbx
+  next
+
+forth_asm PICK, 'PICK'
+  pop rax
+  lea rax, [rsp + 8 * rax]
+  mov rax, [rax]
+  push rax
+  next
+
+forth_asm EQL, '='
+  pop rax
+  pop rbx
+  cmp rax, rbx
+  je .eq
+.noteq:
+  push 0
+  next
+.eq:
+  push 1
+  next
+
 forth MAIN, 'MAIN'
-  dq HELLO
   dq INTERPRET
   dq BRANCH, -8 * 2
   dq TERMINATE
@@ -580,7 +614,7 @@ DOTU.printed_length dq ?
 
 ;; Reserve space for compiled words, accessed through HERE.
 here dq here_top
-here_top rq $2000
+here_top rq $4000
 
 ;; Return stack
 rq $2000