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");