On 21.02.2009 13:20 Uhr, Mark Cave-Ayland wrote:
Hi everyone,
I've been spending some time over the past few weeks trying to get a Sparc64/Solaris disk image to boot under qemu, and as far as I can tell, the first reason that the code terminates incorrectly is because b?branch doesn't work.
This can be demonstrated fairly easily using the following couple of Fcode programs. Note that while I'm working on Sparc64, I see the same issue on x86 OpenBIOS too.
Example 1: b?branch with -1 on stack: ignore branch & abort
CC \ offset16 10 \ b(lit) FF FF FF FF \ (-1) 14 00 04 \ b?branch 02 16 \ if false, abort 9D \ if true, display stack 00 \ end
0 > true to ?fcode-verbose ok 0 > here CC10FFFFFFFF1400 /n allot over ! ok 1 > here 0402169D00000000 /n allot over ! drop ok 1 > 1 byte-load byte-load: evaluating fcode at 0xffd9d128 fcode-table at 0xffdb7f90 offset16 [ 0xcc ] b(lit) [ 0x10 ] b?branch [ 0x14 ] abort [ 0x216 ]
byte-load: exception caught! ok
Example 2: b?branch with 0 on stack: skip abort, display stack
CC \ offset16 10 \ b(lit) 00 00 00 00 \ (0) 14 00 04 \ b?branch 02 16 \ if false, abort 9D \ if true, display stack 00 \ end
0 > true to ?fcode-verbose ok 0 > here CC10000000001400 /n allot over ! ok 1 > here 0402169D00000000 /n allot over ! drop ok 1 > 1 byte-load byte-load: evaluating fcode at 0xffd9d128 fcode-table at 0xffdb7f90 offset16 [ 0xcc ] b(lit) [ 0x10 ] b?branch [ 0x14 ] abort [ 0x216 ]
byte-load: exception caught! ok
Okay, so did anyone notice the difference?! This led me to look into the definition of b?branch in forth/device/fcode.fs:
\ b?branch ( continue? -- ) \ Conditional branch FCode. Followed by FCode-offset.
: b?branch ['] do?branch , fcode-offset 0< if \ if we jump backwards, we can forsee where it goes resolve-dest else here 0 , then ; immediate
By adding some extra debugging into b?branch, I can see that for the above Fcode, do?branch is *never* called, although it correct takes the "else" branch listed above.
I'm still reasonably new to Forth, but AIUI, all the code above does is allocate one cell to store the xt of do?branch, and in the case of a forward branch, push the here location onto the stack and then store 0 into another allocated cell. This agrees with my investigation that shows that do?branch is never actually called.
Given that this code is also missing a section that will read and discard Fcode-offset-2 bytes for a forward branch, I'm inclined to think that this code is just wrong. Can anyone else with any experience with this code comment upon this?
I think you indeed hit a bug. b?branch in openbios only works in word definitions, not in interpretion mode. It needs similar handling as setup-tmp-comp/execute-tmp-comp in the definition of "if" in bootstrap.fs.
In addition to that your example contains non-valid code. A b?branch always needs to point behind a b(>resolve) as in the below example.
here cc c, \ offset16 \ a4 c, \ -1 a5 c, \ 0 14 c, 00 c, 05 c, \ b?branch 02 c, 16 c, \ abort b2 c, \ b(>resolve) 9f c, \ .s 00 c, \ end0 1 byte-load
Forth equivalent: \ -1 0 if abort then .s end0
Stefan