On Sat, Apr 16, 2016 at 08:09:47PM -0400, 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.
Yes. Anything that calls PARSE (or WORD or PARSE-WORD or NAME or whatever similar words you have) depends on this. That is a much longer list than what you found, for example, also ( is in that list.
EVALUATE makes its whole argument string the input buffer, as one string. It does not handle multiple lines. If you want to use it to handle the boot script, you should break things into lines yourself.
I suspect that as Mark was suggesting, the CR vs LF is a red herring. 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.
Between words is the first part of the problem; it's not very hard to make you parser loop play tricks so you can mess with the return stack as well.
But the OS9 boot code also messes with the return stack between _lines_. And allowing that is not feasible.
The usual solution is to implement a separate R stack for use in interpretation mode (just an array in Forth, not some magic system-provided something). The only limitation is that you cannot put something in the R stack in interpret mode and then access it in compile mode (or the other way around). This isn't a problem in practice.
On the other hand, I can't think of much bad that will happen by replacing all CR (0x0D) with LF (0x0A),
Yeah. Many systems use the "parsing 20 means parsing anything <= 20", i.e., parsing a space allows all cosntrol chars as well. I think that is an OF requirement even? Then (on code where the line delimiter is 0d 0a and there are no other 0d or 0a in the file) you just get an extra blank line after every line, which usually is harmless.
One possible solution; take the boot-script code, and rather than interpret it directly, try compiling it.
That does not work. The OS9 bootscript contains many definitions as well. Not just colon definitions.
In summary, the two things you need:
-- Parse the bootscript line by line. -- Have a separate interpretation mode R stack.
Segher