[PicForth] bug+workaround: code page switching
David McNab
david at rebirthing.co.nz
Sun Nov 7 08:39:12 CET 2004
Hi,
While PicForth's heuristics make a noble effort to keep PCLATH set
correctly at all times, there are some areas where it's getting it wrong.
After a few hours of chasing weird phenomena, I've found a bug with
PicForth's handling of code page switching around loops.
Consider the code (from a simple test serial echo prog):
main : main
tty.init
begin
tty.getc
tty.putc
again
;
With tty.init, tty.getc and tty.putc in codepage0, and this main word in
codepage1, we would expect PicForth to clear PCLATH before the tty.init,
then to set PCLATH bit 3 before the 'again' (so the generated GOTO will
actually end up at the 'begin'. But also, we need another clrf PCLATH
just inside the begin.
Instead, what we see in the assembler is:
; name: main
; max return-stack depth: 1
0x0802 1683 bsf 0x03,5
0x0803 0186 clrf 0x06
0x0804 1283 bcf 0x03,5
0x0805 018A clrf 0x0A
0x0806 2055 call 0x055 ; tty.init
0x0807 2072 call 0x072 ; tty.getc
0x0808 206C call 0x06C ; tty.putc
0x0809 20E3 call 0x0E3 ; getc-dummy
0x080A 20E4 call 0x0E4 ; putc-dummy
0x080B 158A bsf 0x0A,3
0x080C 2807 goto 0x007 ; main + 0x005 (0x807)
What happens here is that after one round of the loop, we hit the 'goto
0007', which takes us back to the top. However, when we hit the 'call
tty.getc', PCLATH is still set for codepage1, so the 'call' goes off to
Disneyland instead.
As a workaround, I seem to be getting away with 'no-cbank', which
appears to tell PicForth to forget its PCLATH caching status.
Amending the above example:
main : main
0 trisb !
tty.init
begin
forth> no-cbank
tty.getc ( ch )
tty.putc ( ch+20 )
again
;
This forces an additional 'clrf PCLATH' to go inside the begin, which
keeps things on track.
Another possible attack is to hack the control-flow words, to add
'no-cbank' statements. For example, a modified 'begin':
: begin ( -- 0 baddr ) 0 backref no-cbank ;
This also forces an explicit PCLATH setting at the top of the loop, but
could cause some unnecessary PCLATH setting code to be generated.
Anyone got any thoughts on all this?
--
Cheers
David
More information about the PicForth
mailing list