As Segher had suggested, I executed the boot script one line at a time. This enabled me to see what line failed. The line that is failing is this:
r> here - allot
The message printed after this line is executed is:
"Dictionary space overflow: dicthead=000c3fe4 dictlimit=00080000"
So I decide to find out what value was being allot'ed. Using this code:
r> here - dup ." Calling allot with " . cr allot
The value that is being allocated is 0xa43ef or 672,751. Just for a comparison, I tried my code on Apple's Open Firmware. The value it allocates is 0xffffffd7. So I think the solution might be to increase available memory to OpenBIOS's dictionary. I'm thinking the kernel.c file is where things might need adjusting.
This is the patch I used. It replaces r> and >r with substitute words that don't touch the return stack. This patch also executes one line at a time.
Index: include/libc/string.h =================================================================== --- include/libc/string.h (revision 1395) +++ include/libc/string.h (working copy) @@ -47,7 +47,7 @@ extern char *strdup( const char *str ); extern int strcasecmp( const char *cs, const char *ct ); extern int strncasecmp( const char *cs, const char *ct, size_t count ); - +extern char *strstr(char *buffer, const char *search_string); extern char *strncpy_nopad( char *dest, const char *src, size_t n );
#define _U 0x01 /* upper */ Index: kernel/bootstrap.c =================================================================== --- kernel/bootstrap.c (revision 1395) +++ kernel/bootstrap.c (working copy) @@ -89,7 +89,7 @@ "here", "here!", "dobranch", "do?branch", "unaligned-w@", "unaligned-w!", "unaligned-l@", "unaligned-l!", "ioc@", "iow@", "iol@", "ioc!", "iow!", "iol!", "i", "j", "call", "sys-debug", - "$include", "$encode-file", "(debug", "(debug-off)" + "$include", "$encode-file", "(debug", "(debug-off)", "sub_>r", "sub_r>" };
/* Index: kernel/forth.c =================================================================== --- kernel/forth.c (revision 1395) +++ kernel/forth.c (working copy) @@ -1848,6 +1848,37 @@ PUSH(rstack[rstackcnt - 2]); }
+/* The substitute return stack */ +#define MAX_SUB_RSTACK_SIZE 100 +static int sub_return_stack[MAX_SUB_RSTACK_SIZE]; +static int top = 0; + +/* + * sub_>r ( i -- ) (Substitute R: -- i ) + */ + +static void sub_gt_r(void) +{ + if (top >= MAX_SUB_RSTACK_SIZE) { + printf_console("Stack overflow\n"); + return; + } + sub_return_stack[top++] = POP(); +} + +/* + * sub_r> ( -- i ) (Substitute R: i -- ) + */ + +static void sub_r_gt(void) +{ + if (top < 0 ) { + printf_console("Stack underflow\n"); + return; + } + PUSH(sub_return_stack[top--]); +} + /* words[] is a function array of all native code functions used by * the dictionary, i.e. CFAs and primitives. * Any change here needs a matching change in the primitive word's @@ -1963,4 +1994,6 @@ do_encode_file, /* $encode-file */ do_debug_xt, /* (debug */ do_debug_off, /* (debug-off) */ + sub_gt_r, /* sub_>r */ + sub_r_gt /* sub_r> */ }; Index: libc/string.c =================================================================== --- libc/string.c (revision 1395) +++ libc/string.c (working copy) @@ -385,3 +385,30 @@ return __res; }
+// Search for a string within another string +char *strstr(char *buffer, const char *search_string) +{ + if (!*search_string || (strlen(search_string) == 0)) { + return buffer; + } + + int match_found, index, index2; + for (index = 0; index < strlen(buffer); index++) { + if (buffer[index] == search_string[0]) { + match_found = 1; + // see if we have a match + for (index2 = 0; index2 < strlen(search_string); index2++) { + if (buffer[index + index2] != search_string[index2]) { + match_found = 0; // match not found + break; + } + } + if(match_found == 1) { + return &buffer[index]; + } + } + } + + // Could not find search_string in buffer + return NULL; +} Index: libopenbios/bootinfo_load.c =================================================================== --- libopenbios/bootinfo_load.c (revision 1395) +++ libopenbios/bootinfo_load.c (working copy) @@ -19,6 +19,7 @@ #include "libopenbios/bootinfo_load.h" #include "libopenbios/ofmem.h" #include "libc/vsprintf.h" +#include "libc/string.h"
//#define DEBUG_BOOTINFO
@@ -116,6 +117,85 @@ return LOADER_NOT_SUPPORT; }
+static void erase_memory(char *memory, int size) +{ + int i; + for(i = 0; i < size; i++) { + memory[i] = ' '; + } +} + +// Replace all occurrences of orig_str in buffer with replace_str +static void replace_string(char *buffer, const char *orig_str, const char *replace_str) +{ + char *ptr; + int index, new_buf_index = 0; + const int max_size = 5000; + char *new_buffer = malloc(max_size * sizeof(char)); + erase_memory(new_buffer, max_size); + + for (index = 0; index < strlen(buffer); index++) { + if (buffer[index] == orig_str[0]) { + ptr = strstr(buffer + index, orig_str); + + // if we encountered an orig_str in the buffer + if (index == (ptr - buffer)) { + sprintf(new_buffer + new_buf_index, "%s ", replace_str); + new_buf_index += strlen(replace_str) + 1; + index += strlen(orig_str); + continue; + } + } + new_buffer[new_buf_index++] = buffer[index]; + } + + // Clear the origial buffer + erase_memory(buffer, max_size); + + // copy new_buffer into buffer + for (index = 0; index < strlen(new_buffer); index++) { + buffer[index] = new_buffer[index]; + } + buffer[index+1] = '\0'; +} + +/* Replace >r and r> with sub_>r and sub_r> */ +static void replace_return_stack_words(char *bootscript) +{ + const char *find_str1 = ">r"; + const char *replace_str1 = "sub_>r"; + const char *find_str2 = "r>"; + const char *replace_str2 = "sub_r>"; + + replace_string(bootscript, find_str1, replace_str1); + replace_string(bootscript, find_str2, replace_str2); +} + +void run_script(char *bootscript) +{ + int index = 0, buf_index = 0; + char c; + char *buffer = malloc(1000 * sizeof(char)); + + while (1) { + c = bootscript[index]; + + // fill up buffer + while (c != '\n' && c != '\r' && c != '\0') { + buffer[buf_index++] = c; + c = bootscript[++index]; + } + buffer[buf_index] = '\0'; + buf_index = 0; + index++; + printk("%s\n", buffer); + feval(buffer); + if (c == '\0') { + return; + } + } +} + /* Parse SGML structure like: <chrp-boot> @@ -191,7 +271,7 @@
c = base[current++];
- if (c == '<') { + if (c == '<') { script = 0; tag = 1; taglen = 0; @@ -262,7 +342,8 @@ /* If the payload is bootinfo then we execute it immediately */ if (scriptvalid) { DPRINTF("bootscript: %s\n", bootscript); - feval(bootscript); + replace_return_stack_words(bootscript); + run_script(bootscript); } else DPRINTF("Unable to parse bootinfo bootscript\n");