Hacker News new | past | comments | ask | show | jobs | submit login

6502 FORTHs have to work around a bug on the 6502 processor (which was fixed in later revisions like the 65C02):

The inner interpreter (NEXT) uses the indirect absolute jump instruction and self modifying code that patches the code field address into the jump instruction before executing it:

    JMP ($ABCD)
However if the address is like $xxFF, the code field of the word it's jumping through straddles a 256-byte page boundary, and the 6502 mistakenly wraps around to the beginning of the same page to fetch the second byte of the address, instead of going to the next page.

So the compiler (usually CREATE) has to check before creating a new word, to make sure that its code field address will land at $xxFF, and allocate an extra byte of padding first to prevent that from happening.

I found this out the hard way when developing my own 6502 FORTH. I'd make some tweak to the assembly or FORTH source and recompile, then some essential old reliable word that always used to work would suddenly start failing catastrophically. So I'd enable debugging and recompile, and the problem would go away, or move to some other totally unrelated word! A classic Heisenbug! I finally found the problem and solution by looking at 6502 FIG FORTH.

http://archive.6502.org/publications/6502notes/6502_user_not...

http://forum.6502.org/viewtopic.php?f=2&t=4220&start=60

https://everything2.com/title/6502+indirect+JMP+bug

https://news.ycombinator.com/item?id=11719918

https://web.archive.org/web/20200619194357/http://www.dwheel...

    ;    The following offset adjusts all code fields to avoid an
    ;    address ending $XXFF. This must be checked and altered on
    ;    any alteration , for the indirect jump at W-1 to operate !
    ;
              .ORIGIN *+2
[...]

              .WORD DP       ;)
              .WORD CAT      ;| 6502 only. The code field
              .WORD CLIT     ;| must not straddle page
              .BYTE $FD      ;| boundaries
              .WORD EQUAL    ;|
              .WORD ALLOT    ;)
FIG-FORTH is pre-FORTH-83, so EQUAL returns 1 or 0 instead of -1 or 0. And ahem DP is the Dictionary Pointer, CAT is C@, while CLIT is Character LITeral, of course. :-|



Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: