]> git.mdlowis.com Git - proto/uefi.git/commitdiff
started implementing base system as hybrid of C and assembly. To replace C with assem... forth
authorMichael D. Lowis <mike@mdlowis.com>
Tue, 14 Feb 2023 04:37:04 +0000 (23:37 -0500)
committerMichael D. Lowis <mike@mdlowis.com>
Tue, 14 Feb 2023 04:37:04 +0000 (23:37 -0500)
uefi/crt_x86_64.c
uefi/onward.S

index b61737dded6a2c14a07f8a8c970f7db70ceaafe5..5a733791541684eb6691bdcecd05559b524b54ed 100644 (file)
@@ -1,14 +1,58 @@
 #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)
 {
@@ -17,18 +61,80 @@ 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);
 }
 
 /*
@@ -89,7 +195,7 @@ int uefi_init(uintptr_t ldbase, Elf64_Dyn *dyn, efi_system_table_t *systab, efi_
     /* 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;
@@ -97,23 +203,16 @@ int uefi_init(uintptr_t ldbase, Elf64_Dyn *dyn, efi_system_table_t *systab, efi_
     }
     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;
@@ -122,12 +221,12 @@ int uefi_init(uintptr_t ldbase, Elf64_Dyn *dyn, efi_system_table_t *systab, efi_
     /* 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;
 }
index 0fde90ece8ad75bdb1fa5b6b461b87bd5093dade..6ff8d9e9175b5eff1f26a660b0870e7de7913de7 100644 (file)
@@ -1,8 +1,10 @@
 //---------------------------------------------------------------------
-// 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
@@ -62,12 +65,13 @@ 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
@@ -194,10 +198,31 @@ defcode "over",4,,over
 // 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