#include <stdint.h>
#include <uefi.h>
+#include <ctype.h>
void StartOnward(void);
+//typedef struct word_t {
+// struct word_t* link;
+// char* name;
+// void* code;
+//} word_t;
+//
+//word_t* find(word_t* w, char* s)
+//{
+// if (!w)
+// {
+// return w;
+// }
+// else
+// {
+// char* ws = w->name;
+// while (1)
+// {
+// if (!*ws || !*s || *ws != *s)
+// {
+// return find(w->link, s);
+// }
+// }
+// }
+// return w;
+//}
+
+
+
+
+char WordBuf[0x1F];
+long WordLen = 0;
+long WordVal;
+
struct {
efi_handle_t IM;
efi_system_table_t* ST;
efi_boot_services_t* BS;
} EFI = {0};
+void PutChar(long c)
+{
+ wchar_t data[3] = {c,0,0};
+ if (c == '\n' || c == '\r')
+ {
+ data[0] = '\r';
+ data[1] = '\n';
+ }
+ EFI.ST->ConOut->OutputString(EFI.ST->ConOut, data);
+}
long GetChar(void)
{
do {
status = EFI.ST->ConIn->ReadKeyStroke(EFI.ST->ConIn, &key);
} while(status != EFI_SUCCESS);
+ PutChar(key.UnicodeChar);
+
return key.UnicodeChar;
}
-void PutChar(long c)
+static inline long whitespace(long c)
{
- wchar_t data[3] = {c,0,0};
- if (c == '\n' || c == '\r')
+ return ((c == ' ') || (c == '\t') || (c == '\n') || (c == '\r'));
+}
+
+void GetWord(void)
+{
+ long c = 0;
+ long len = 0;
+ do
{
- data[0] = '\r';
- data[1] = '\n';
+ c = GetChar();
+ } while (whitespace(c));
+ do
+ {
+ WordBuf[len++] = c;
+ c = GetChar();
+ } while (!whitespace(c) && len < 0x1F);
+ WordLen = len;
+}
+
+long ParseNumber(void)
+{
+ WordVal = 0;
+ long base = 10;
+ long sign = 1;
+ long i = 0;
+ if (WordBuf[i] == '0')
+ {
+ i++;
+ char bc = WordBuf[i++];
+ if (bc == 'b') base = 2;
+ else if (bc == 'o') base = 8;
+ else if (bc == 'd') base = 10;
+ else if (bc == 'x') base = 16;
+ else return 0;
}
- EFI.ST->ConOut->OutputString(EFI.ST->ConOut, data);
+ else if (WordBuf[i] == '-')
+ {
+ sign = -1;
+ i++;
+ }
+
+ while (i < WordLen)
+ {
+ long c = WordBuf[i];
+ if (c >= '0' && c <= '9')
+ {
+ c -= '0';
+ }
+ else if (c >= 'a' && c <= 'f')
+ {
+ c = (c - ('a' - 'A')) - ('A' - 10);
+ }
+ else if (c >= 'A' && c <= 'F')
+ {
+ c = c - ('A' - 10);
+ }
+ else
+ {
+ break;
+ }
+ // TODO: check limits here...
+ WordVal *= base;
+ WordVal += c;
+ i++;
+ }
+ WordVal *= sign;
+ return (i == WordLen);
}
/*
/* handle relocations */
for (int i = 0; dyn[i].tag != DT_NULL; ++i) {
switch (dyn[i].tag) {
- case DT_RELA: rel = (Elf64_Rel*)((unsigned long)dyn[i].value + ldbase); break;
+ case DT_RELA: rel = (Elf64_Rel*)(dyn[i].value + ldbase); break;
case DT_RELASZ: relsz = dyn[i].value; break;
case DT_RELAENT: relent = dyn[i].value; break;
default: break;
}
if (rel && relent) {
while (relsz > 0) {
- if(ELF64_R_TYPE (rel->r_info) == R_X86_64_RELATIVE)
- { addr = (uintptr_t*)(ldbase + rel->r_offset); *addr += ldbase; break; }
+ if(ELF64_R_TYPE (rel->r_info) == R_X86_64_RELATIVE) {
+ addr = (uintptr_t*)(ldbase + rel->r_offset);
+ *addr += ldbase;
+ break;
+ }
rel = (Elf64_Rel*) ((char *) rel + relent);
relsz -= relent;
}
}
- /* make sure SSE is enabled, because some say there are buggy firmware in the wild not doing that */
- __asm__ __volatile__ (
- " movq %cr0, %rax\n"
- " andb $0xF1, %al\n"
- " movq %rax, %cr0\n"
- " movq %cr4, %rax\n"
- " orw $3 << 9, %ax\n"
- " mov %rax, %cr4\n"
- );
-
/* save EFI pointers and loaded image into globals */
EFI.IM = image;
EFI.ST = systab;
/* start the REPL */
EFI.ST->ConOut->ClearScreen(EFI.ST->ConOut);
EFI.ST->ConOut->EnableCursor(EFI.ST->ConOut, 1);
- StartOnward();
-
-// while(1)
-// {
-// PutChar(GetChar());
-// }
+ while (1){
+ GetWord();
+ long is_num = ParseNumber();
+ PutChar(is_num ? 'N' : 'W');
+ PutChar('\n');
+ }
return 0;
}
//---------------------------------------------------------------------
-// TODO
+// System API
//---------------------------------------------------------------------
-/*
-*/
+.global PutChar
+.global GetChar
+.global GetWord
+.global ParseNumber
//---------------------------------------------------------------------
// Register Usage
.macro defcode name, namelen, flags=0, label
.data
.p2align 4
+name_\string :
+ .byte \flags+\namelen
+ .ascii "\name"
.global name_\label
name_\label :
.quad link
+ .quad name_\string
.set link, name_\label
- .byte \flags+\namelen
- .ascii "\name"
- .p2align 4
.global \label
\label :
.quad code_\label
.data
.p2align 4
.global name_\label
+name_\string:
+ .byte \flags+\namelen
+ .ascii "\name"
name_\label :
.quad link
+ .quad name_\string
.set link,name_\label
- .byte \flags+\namelen
- .ascii "\name"
- .p2align 4
.globl \label
\label :
.int DOCOL
// defcode asp@
// defcode asp!
-// defcode getc
+// ( - v) Get the next typed character
+defcode "getc",4,,getc
+ call GetChar
+ push %rax
+ NEXT
+
// defcode putc
-// defcode word
+// (v - ) Put a character to the console
+defcode "putc",4,,putc
+ pop %rcx
+ call PutChar
+ NEXT
+
+// ( - s) Get the next word from input
+defcode "word",4,,word
+ call GetWord
+ NEXT
+
// defcode number
+// (s - s i) Parse the word as a number
+defcode "num",3,,num
+ call ParseNumber
+ push %rax
+ NEXT
+
// defcode find
// defcode >cfa
// defcode >dfa