On Apr 16, 2016, at 8:09 PM, Tarl Neustaedter wrote:
On 2016-Apr-16 19:17 , Programmingkid wrote:
I added some code to the bootinfo_init_program() function in bootinfo_load.c file that changes all control characters to '\n'. This made Mac OS 9 boot. But when I changed the control characters to a single space, Mac OS 9 failed to boot. This seems strange to me. The space character is the ultimate whitespace character, so why would it fail when '\n' succeeds? My only guess right now is a bug with one of the words in Forth.
Well, changing end-of-line to space will probably fail for the following standard words (doing a search through IEEE 1275 for EOL):
\ dev " parse load help setenv devalias boot set-default printenv
The last seven are supposed to be interactive commands, so no surprise they need an EOL. "dev" is supposed to be as well, but it's too-widely used in code (they should be using '" /" find-device' instead of 'dev /', but poor programming isn't limited to C language). It's rare to see a quoted string ended by end-of-line, but I have run into it.
I suspect that as Mark was suggesting, the CR vs LF is a red herring.
You think so? This looks like the solution Mark and I have been wanting. An explanation as to why EOL a.k.a. '\n' substitution works. I can finally tell him it is because the standard requires it.
Thank you very much for solving this problem.
The issue is likely to be what happens to the return stack between commands - the forth interpreter might trash the return stack between commands - it could well be that in the process of parsing strings from the boot code, it's resetting the return stack, and that's where we're getting tripped up. Maybe some parsing code goes through a different path for CR vs LF, for example. Apple's Forth code is known to take advantage of Apple's interpreter's quirks, to the degree that plug-in card manufacturers had to produce different code for Sun, IBM and Apple systems.
I do have Apple's Forth implementation available to test. All I need is a test program that does something to the return stack.
After looking at the bootscript, I think return stack trashing is not a problem. There are three calls to >r and then three calls the r>. They balance each other out. To show that this is ok, just run this program:
: main 1 2 3 \ place these numbers on the stack
r r r
." doing something" cr r> r> r> ." You should see 3 2 1: " . . . cr ;
You will see at the end 3 2 1.
It could also be that the parsing code is getting tangled up with this code's use of "here", where it is allocating from the heap in the middle of parsing. Perhaps the Forth parser is using the heap itself and things are tripping over each other.
On the other hand, I can't think of much bad that will happen by replacing all CR (0x0D) with LF (0x0A), other than some formatting problems if you have code which is trying to be fancy with a spinning wheel (sequence of / - \ |). The main problem with that approach is that we know something is wrong and we may be just hiding the problem.
When all operating systems boot properly, we can say there is no problem.
One possible solution; take the boot-script code, and rather than interpret it directly, try compiling it. E.g., before starting the boot code, add:
: boot-script-container
<add boot code here> ; boot-script-container
That way we could separate the parsing of the forth source from the execution of the forth. You'd have to watch out for the cases where there are colon definitions already in the boot code, because the openbios interpreter probably doesn't allow nested colon definitions. So you might end up with something like
: boot-script-container1 <code from "here" to "release-load-area"> ; boot-script-container1
: do-translate ... through : release-virt ...
: boot-script-container2 <code from "1000 constant" to "go"> ; boot-script-container2
I really like this idea.