6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 27, 2024 1:16 pm

All times are UTC




Post new topic Reply to topic  [ 72 posts ]  Go to page Previous  1, 2, 3, 4, 5
Author Message
PostPosted: Sat Jan 14, 2023 3:07 am 
Offline

Joined: Mon Jan 09, 2023 9:33 pm
Posts: 23
Also >R R> R@ must look for 2nd cell at stack while runs, because 1st is the real return reference


Top
 Profile  
Reply with quote  
PostPosted: Sat Jan 14, 2023 5:24 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
agsb wrote:
Also >R R> R@ must look for 2nd cell at stack while runs, because 1st is the real return reference

In 6502 fig-Forth, release 1.1 from September 1980, >R (not including the header) is:
Code:
TOR:    .WORD *+2
        LDA  1,X
        PHA
        LDA  0,X
        PHA
        INX
        INX
        JMP  NEXT

R> is:
Code:
RFROM:  .WORD *+2
        DEX
        DEX
        PLA
        STA  0,X
        PLA
        STA  1,X
        JMP  NEXT

R@ is:
Code:
R:      .WORD  *+2
        STX  XSAVE
        TSX
        LDA  $101,X
        PHA
        LDA  $102,X
        LDX  XSAVE
        JMP  PUSH

There's no return address to step over, because they're primitives.

In my 65816 ITC Forth, I have for these:
Code:
        HEADER ">R", NOT_IMMEDIATE      ; ( n -- )  ; Should be compile-only.
TO_R:   PRIMITIVE                                   ; Will crash in command line.
        LDA     0,X
        PHA
        POP1
 ;-------------------
        HEADER "DUP>R", NOT_IMMEDIATE   ; ( n -- n )
DUP2R:  PRIMITIVE
        LDA     0,X
        PHA
        GO_NEXT
 ;-------------------
        HEADER "R>", NOT_IMMEDIATE      ; ( -- n )
R_FR:   PRIMITIVE
        PLA
        DEX2                            ; These 2 lines are like JMP PUSH but
        PUT_TOS                         ; 2 bytes longer to save 3 clocks.
 ;-------------------
        HEADER "R@", NOT_IMMEDIATE      ; ( -- n )
Rfetch: PRIMITIVE                       ; I uses this code too.
        LDA     1,S                     ; Stack-relative addressing.
        DEX2                            ; These 2 lines are like JMP PUSH but
        PUT_TOS                         ; 2 bytes longer to save 3 clocks.
 ;-------------------

(with a little use of short macros to improve the source-code clarity and length, for example PUT_TOS is just STA 0,X followed by a jump to NEXT).

Quote:
Code:
next:
; as is, classic ITC from fig-forth 6502
        sty  y_save
        <snip>

The fig-Forth NEXT is this:
Code:
NEXT:   LDY  #1
        LDA  (IP),Y
        STA  W+1
        DEY
        LDA  (IP),Y
        STA  W
        CLC
        LDA  IP
        ADC  #2
        STA  IP
        BCC  L54
        INC  IP+1
L54:    JMP  W-1

Note that there's no saving and restoring of Y.  Many primitives need Y to start as 0 anyway; and this starts with LDY #1, not 0, then DEY's to 0; so it's already initialized for them.  My '816 Forth shortens NEXT quite a bit by using the 816's ability to handle 16 bits at a time, and also putting NEXT in direct page to take advantage of self-modifying code to avoid a couple of indirects, having IP and W be operands of the instructions themselves, rather than separate variables.

I kind of like your idea though of using 0000 in the CFA to indicate a primitive, and anything else to indicate a secondary (also called "colon definition"—we do not call these Forth words "compound words" in English), to save some memory.  It would take some experimentation to evaluate the tradeoffs.  On the '816, it becomes much more worthwhile to make a lot more words primitives, and in my '816 Forth, I have several hundred, which is partly why my 65816 Forth runs two to three times as fast as my '02 Forth at a given clock rate.

As for TOS (top of stack, the top data-stack cell) in register (basically in the 16-bit accumulator for the 65816), I went through some exercises to see if it would be beneficial, and although there are places where it would be, there are others where it actually adds overhead.  So I'd have to actually write an entire kernel and run programs on both kernels to find out if it was a wash or not.

Quote:
sorry long post.

There's no need to apologize.  A post should be as long as necessary to make the point, and there are many, many posts on this forum that are much, much longer.  A few are like presenting a paper at a conference, which is fine.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sat Jan 14, 2023 3:49 pm 
Offline

Joined: Mon Jan 09, 2023 9:33 pm
Posts: 23
MITC also eliminates JSR/RTS, all goes to be: unnest->next-->leaf? jump : nest

Push all references until a primitive then execute and pull a reference

"There's no return address to step over, because they're primitives." and the return reference is at IP in Fig-Forth, but in MITC it will be at top of return stack


Top
 Profile  
Reply with quote  
PostPosted: Sat Jan 14, 2023 9:05 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
GARTHWILSON wrote:

I kind of like your idea though of using 0000 in the CFA to indicate a primitive, and anything else to indicate a secondary (also called "colon definition"—we do not call these Forth words "compound words" in English), to save some memory.  It would take some experimentation to evaluate the tradeoffs. 


It's not as simple as "if the first cell is 0000 jump to the body of this word otherwise nest". A variable has a code field which does not point to its body, yet it is not a secondary. The same for constants and other child words of CREATE DOES> and CREATE ;CODE . These type of words do not have a code field which points to nest (or docolon) nor do they have a code field which points two bytes forward.


Top
 Profile  
Reply with quote  
PostPosted: Sat Jan 14, 2023 9:26 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
Good point.  For example, fig-Forth's R@ which I listed above is also used for I (getting a copy of the loop counter), and I's CFA points to R@'s code.  There are lots of those.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 15, 2023 1:27 am 
Offline

Joined: Mon Jan 09, 2023 9:33 pm
Posts: 23
Quote:
It's not as simple as "if the first cell is 0000 jump to the body of this word otherwise nest". A variable has a code field which does not point to its body, yet it is not a secondary. The same for constants and other child words of CREATE DOES> and CREATE ;CODE . These type of words do not have a code field which points to nest (or docolon) nor do they have a code field which points two bytes forward.
[/color]


No problem the reference for those is processed as any compound list of references, same for DOCON, DOVAR, DODOES, etc

anyway that's what happen in any Forth: push references, till a primitive, execute it, then pull a reference, repeat

;CODE is a primitive that does a direct jump for a reference (address) wich code ends with jmp unnest.

Any value at top of return stack could be moved without warn, just will be momentarily at 2nd cell while >R R> R@ is running, nothing change


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 15, 2023 9:25 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
agsb wrote:
No problem the reference for those is processed as any compound list of references, same for DOCON, DOVAR, DODOES, etc

anyway that's what happen in any Forth: push references, till a primitive, execute it, then pull a reference, repeat


A quick perusal of your pdf file leads me to suspect this is actually a modification of direct threaded code (DTC), not ITC.

agsb wrote:
;CODE is a primitive that does a direct jump for a reference (address) wich code ends with jmp unnest.


;CODE is not a primitive, it compiles another word which is also not a primitive.
From the fig-forth installation manual:
Code:
; CODE
Used in the form:
   : cccc   ....  ;CODE
         assembly mnemonics

Stop compilation and terminate a new defining word cccc by compiling (;CODE). Set the CONTEXT vocabulary to ASSEMBLER, assembling to machine code the following mnemonics.

Concerning your use of EXIT . Although the fig-Forth name for unnest is ;S (semicolon S), EXIT has been the name for unnest since the Forth-79 Standard, possibly earlier. It is what semicolon compiles.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 15, 2023 9:32 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
GARTHWILSON wrote:
Good point.  For example, fig-Forth's R@ which I listed above is also used for I (getting a copy of the loop counter), and I's CFA points to R@'s code.  There are lots of those.


My Forth's I works differently because its DO LOOP's use the overflow flag to determine when the limit has been crossed in either direction.
There are several words in the kernel which have a code field pointing into another word.
Code:
2NIP      FORTH-83  >SLF#     VFIND     L>NAME    N>LINK    BODY>
>BODY     C!        HOLD      BUFFER    2SWAP     NIP       UNDER+
OVER      OFF       SWAP      DUP       D+        +         1-
1+        DUP>R     DNEGATE   NEGATE    CMOVE     ROFF      NOOP
[         1         0         FALSE     TRUE      BRANCH    DROP
EXIT      LEAVE     



Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 15, 2023 9:55 pm 
Offline

Joined: Mon Jan 09, 2023 9:33 pm
Posts: 23
Quote:
Concerning your use of EXIT . Although the fig-Forth name for unnest is ;S (semicolon S), EXIT has been the name for unnest since the Forth-79 Standard, possibly earlier. It is what semicolon compiles.


Yes, I'm using Dr. Ting eForth names, also called by other names, etc.

Quote:
;CODE is not a primitive, it compiles another word which is also not a primitive.



Yes, in fig-Forth, and what it does is a jump for a assembler reference, could easy be a fast primitive. In IMMU it is.

Quote:
A quick perusal of your pdf file leads me to suspect this is actually a modification of direct threaded code (DTC), not ITC.


Please, tell me which part. The example is with DOCOL ... EXIT, not using any JSR/RTS.

Also in IMMU there is no JSR/RTS, all forth words are a uniq thread linked with JMPs.


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 15, 2023 10:06 pm 
Offline

Joined: Mon Jan 09, 2023 9:33 pm
Posts: 23
Quote:
There are several words in the kernel which have a code field pointing into another word.


The concept of "code field" is unnecessary in MITC, all references in compound words are treated the same way. So, the code field is just the first reference of a list as in (car cdr) :)

Really, as in any Forth, only primitives are executed and any compound is a list of address references.

Sure, some words have a "assembler code" in definition, and that part should be defined as primitive, previously.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 16, 2023 2:18 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
agsb wrote:
Quote:
A quick perusal of your pdf file leads me to suspect this is actually a modification of direct threaded code (DTC), not ITC.

Please, tell me which part. The example is with DOCOL ... EXIT, not using any JSR/RTS.

Our own Dr. Brad Rodriguez (forum name BradR), a big man in the world of Forth, has an article on the different threading methods at http://www.bradrodriguez.com/papers/moving1.htm .  The explanation for DTC starts about 30% of the way down the page.  JSR/RTS is used a lot in STC; but while DTC uses JSR to the ENTER routine (also called nest or DOCOL) in a colon definition's code field just to keep a record of the address (minus 1) of the subsequent list of addresses, it does not use a matching RTS, if I understand it correctly.  DTC is the least clear in my mind.

Quote:
Quote:
Concerning your use of EXIT . Although the fig-Forth name for unnest is ;S (semicolon S), EXIT has been the name for unnest since the Forth-79 Standard, possibly earlier. It is what semicolon compiles.

Yes, I'm using Dr. Ting eForth names, also called by other names, etc.

I spent about 45 minutes searching his materials online.  I cannot find any reference to "compound words" in his materials.  He calls them "colon words" in a recent video.  Again, we do not call them "compound words" in English.  Please call them "colon definitions" or "secondaries."  These are the standard terms.  It was sad to read that he died last June.  He did appear to be quite old though.  I have separate words for unnest versus EXIT (although their CFAs point to the same code), so if I use the ANS word SEE to de-compile a word, it doesn't stop at an EXIT that's not at the end of the word.  As an aside, I see Dr. Ting did not like DO...LOOP, preferring instead FOR...NEXT.  The primitive laid down by NEXT (obviously different from the inner loop NEXT which is neither a primitive nor a secondary) is simpler than loop, but more limited in what it can do.  I see that Elizabeth Rather, in her book "Forth Application Techniques," ©2010, which is regarding Forth, Inc.'s ANS-compliant SwiftForth, only uses DO...LOOP, not FOR...NEXT.  I'll stick with DO...LOOP.

I know we're getting partially off the topic of optimal 6502 NEXTs; but we're 11 years and five pages into into it, and it has more or less run its course; so it's not necessary that everything be so tightly related.

_________________
http://WilsonMinesCo.com/ lots of 6502 resources
The "second front page" is http://wilsonminesco.com/links.html .
What's an additional VIA among friends, anyhow?


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 17, 2023 11:29 am 
Offline

Joined: Mon Jan 09, 2023 9:33 pm
Posts: 23
Quote:
"I spent about 45 minutes searching his materials online. I cannot find any reference to "compound words" in his materials. "

I'm talking about nest, next, unnest. Primitives as leafs and Compound as twigs, https://muforth.nimblemachines.com/threaded-code/

I'm not saying that DTC, SDC must ever use JSR/RST, sorry, I try said that IMMU does not use.

And IMMU does not have ~~ call them "colon definitions" or "secondaries." ~~ because nest and unnest are incorporated to inner address interpreter, there is only primitives and "list of references", and any word could be at CFA, including (do), dovar, docon, dodoes etc

Also DO LOOP +LOOP LEAVE FOR NEXT IF ELSE THEN etc


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 72 posts ]  Go to page Previous  1, 2, 3, 4, 5

All times are UTC


Who is online

Users browsing this forum: No registered users and 7 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to: