Jump to content
  • entries
    45
  • comments
    10
  • views
    10,346

Dealer Demo, part 5: More Forth for you


Atari_Ace

489 views

In the last post I explained how the NEXT routine uses IP and W to JMP from word to word, but otherwise neglected to explain the Forth environment. Let's remedy that.

Forth contains two stacks, a data stack and a return stack.

The 6502 stack pointer indexes the return stack in page one. Saving and restoring the interpreter pointer is done here when Forth 'subroutines' are entered and exited, in a fashion analogous to JSR and RTS for the 6502. The routine SEMIS which we'll disassemble shortly is similar to RTS.

The 6502 X register indexes the data stack in page zero. The stack grow downwards, so 0,X and 1,X is the entry at the top of the stack, 2,X and 3,X is the next entry in the stack, et cetera. To add a word to the stack, decrement the X register twice (e.g. PUSH in the listing). To remove a word from the stack, increment the X register twice (e.g. ZBRAN and POP in the listing).

The 6502 Y register is always zero when a word is entered as a side effect of the implementation of the NEXT routine. Some routines take advantage of this, using TYA instead of LDA #0 (e.g. DIGIT).

The N label references 9 bytes of scratch space for the interpreter, from N-1 to N+7. Forth routines can use this space on page zero as needed. The SETUP routine for instance uses this space to transfer up to four words from the data stack for routines to work with.

The UP label is a pointer to the user area. It is set to $480 on startup and hold $80 bytes of interpreter state (this area was also used for the boot loader code). For instance, at offset 8 is RP0, the initial return stack value. Before the interpreter starts the stack pointer is set to that value by calling RPSTO, a routine we'll be disassembling shortly.

The XSAVE label provide a byte for saving and restoring the X register. The Forth environment requires that the X register always hold the data stack index, so routines that need to use the X register for other purposes have to save and restore it before returning to the Forth NEXT routine. For instance, PLOOP transfers the return stack pointer to the X register (TSX) so it can manipulate the return stack directly, so it needs to use XSAVE to save and restore the data stack pointer.

And that for now completes our discussion of the Forth interpreter environment. On to our regularly scheduled disassembly.

The next four words in the listing match what we find in the fig-Forth listing:

-def  WORD     NFA   PFA    same as fig-Forth?
0e52  I        L207  I      Yes
0e58  DIGIT    L214  DIGIT  Yes
0e88  (FIND)   L243  PFIND  Yes
0eed  ENCLOSE  L301  ENCL   Yes

After that the fig-Forth listing has words for EMIT, KEY, ?TERMINAL, and CR, which are all implemented as forward refences (the actual code appears much later in the listing). In the Dealer Demo, these words don't appear here, they appear later with their implementation.

The next words are all identical to the fig-Forth listings.

0f2f  CMOVE    L365  CMOVE  Yes
0f57  U*       L386  USTAR  Yes
0f8f  U/       L418  USLAS  Yes
0fcb  AND      L453  ANDD   Yes
0fe1  OR       L469  OR     Yes
0ff6  XOR      L484  XOR    Yes
100c  SP@      L499  SPAT   Yes
101b  SP!      L511  SPSTO  Yes
102b  RP!      L522  RPSTO  Yes
1040  ;S       L536  SEMIS  Yes
1050  LEAVE    L548  LEAVE  Yes
106E  >R       L563  TOR    Yes
1080  R>       L577  RFROM  Yes
1092  R        L591  R      Yes

U* and U/ are unsigned multiply and divide. It's peculiar they appear so early in the listing, as they aren't really needed to implement anything right away. Of note is that both are incorrectly implemented in almost every 6502 Forth, so that some inputs generate the wrong values. The U* bug is simply a missed overflow condition on adding the carry. It can be fixed by replacing:

     LDA #0
     ADC 0,X
     STA 0,X
L411 DEY

with:

     BCC L411
     INC 0,X
     BNE L411
     INC 1,X
L411 DEY

 

The USLAS bug I don't think can be fixed as simply. See the discussion as http://6502.org/source/integers/ummodfix/ummodfix.htm

 

OK, I think that's enough progress for today. I'm attaching WIP dealerdemo.lst, which is more than twice the length of the last update. Although we have a long way to go, progress will be faster once we're done with the 'primitive' words.

dealerdemo.lst

0 Comments


Recommended Comments

There are no comments to display.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...