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");
On Thu, Apr 21, 2016 at 12:26:06PM -0400, Programmingkid wrote:
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.
[ L O O O O N G L I N E S ]
No, the solution is to make R> work in interpret mode. Properly. And you'll need structure words to work as well. Piling workarounds on top of workarounds won't get you far.
Segher
On Apr 21, 2016, at 1:17 PM, Segher Boessenkool wrote:
On Thu, Apr 21, 2016 at 12:26:06PM -0400, Programmingkid wrote:
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.
[ L O O O O N G L I N E S ]
No, the solution is to make R> work in interpret mode. Properly.
Wouldn't we be better off avoiding using R> and >R? Apple's code looks like it only cares about using the return stack as a placeholder for data (correct me if I am wrong on this point). Tarl said if the parsing code uses the return stack, then this boot script would mess it up. So it seems avoiding using the return stack is a logical course of action.
I did try your version of r> and >r. The end result was pretty much the same as my patch. The "Dictionary Space overflow" error message is still printed. This doesn't mean you are wrong, it just means maybe there is more that needs fixing.
And you'll need structure words to work as well. Piling workarounds on top of workarounds won't get you far.
I remember your list of words that you thought had problems:
AHEAD IF THEN BEGIN AGAIN UNTIL CASE ENDCASE DO ?DO LOOP +LOOP
What makes you so sure it is these words that are the problem?
My test for BEGIN AGAIN in interpret mode: begin ." hello world" again
The result was "hello world" being printed over and over again. It seems to work in interpret mode.
The IF tests:
0 if ." false" else ." true" then
1 if ." true" else ." false" then
Both these tests print "true" like they are suppose to.
The do loop test:
decimal 100 0 do ." number: " i . cr loop
The output is the expected list of numbers. number 0 number 1 number 2 ... number 99
BEGIN ... UNTIL tests:
begin ." hello world " 0 until
The output is the expected "hello world" text repeated over and over.
5 begin cr ." hello world " 1 - dup 0= until cr ." end of loop" cr
The output is the expected "hello world repeated five times with the "end of loop" text at the end.
I ran these tests with just this command line: qemu-system-ppc -nographic
It allows me to copy and paste my code into QEMU.
On Thu, Apr 21, 2016 at 03:39:47PM -0400, Programmingkid wrote:
No, the solution is to make R> work in interpret mode. Properly.
Wouldn't we be better off avoiding using R> and >R?
If you don't want to run the OS9 bootscript, then don't run the OS9 bootscript.
I did try your version of r> and >r. The end result was pretty much the same as my patch. The "Dictionary Space overflow" error message is still printed.
There are many problems, you'll need to solve all to have things work.
And you'll need structure words to work as well. Piling workarounds on top of workarounds won't get you far.
I remember your list of words that you thought had problems:
AHEAD IF THEN BEGIN AGAIN UNTIL CASE ENDCASE DO ?DO LOOP +LOOP
What makes you so sure it is these words that are the problem?
Because they are implemented incorrectly. They use the data space.
Try
2a IF CREATE uh-oh THEN
or
10 0 DO i , LOOP
and watch the sparks.
Segher
On Thu, Apr 21, 2016 at 11:17:44PM -0500, Segher Boessenkool wrote:
Because they are implemented incorrectly. They use the data space.
Or maybe I read it wrong? I dunno, it's weird code. Either way, check it, and check everything else the script does.
Segher
On Apr 22, 2016, at 12:17 AM, Segher Boessenkool wrote:
On Thu, Apr 21, 2016 at 03:39:47PM -0400, Programmingkid wrote:
No, the solution is to make R> work in interpret mode. Properly.
Wouldn't we be better off avoiding using R> and >R?
If you don't want to run the OS9 bootscript, then don't run the OS9 bootscript.
I do wish to run Mac OS 9. We can still run it and avoid the return stack.
I did try your version of r> and >r. The end result was pretty much the same as my patch. The "Dictionary Space overflow" error message is still printed.
There are many problems, you'll need to solve all to have things work.
And you'll need structure words to work as well. Piling workarounds on top of workarounds won't get you far.
I remember your list of words that you thought had problems:
AHEAD IF THEN BEGIN AGAIN UNTIL CASE ENDCASE DO ?DO LOOP +LOOP
What makes you so sure it is these words that are the problem?
Because they are implemented incorrectly. They use the data space.
Data space? What's that?
Try
2a IF CREATE uh-oh THEN
or
10 0 DO i , LOOP
and watch the sparks.
Did. On OpenBIOS the first one just says "uh-oh: undefined word.". On Apple's Open Firmware it says "uh-oh, unknown word".
For the second example, OpenBIOS will say compiled and keep saying compiled until the semicolon is typed. The loop does not run. On Apple's Open Firmware, it just says "ok" and does nothing also. I think you should test your ideas before stating them.