6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Wed May 22, 2024 2:14 pm

All times are UTC




Post new topic Reply to topic  [ 343 posts ]  Go to page Previous  1 ... 16, 17, 18, 19, 20, 21, 22, 23  Next
Author Message
PostPosted: Tue Jan 17, 2023 1:24 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 862

After a discussion on another thread I was wondering what percent of Fleet Forth's words are colon definitions. Less than fifty percent of the words in the system are high level.
Code:
557 words
272 : words          48.8330
157 code words       28.1867
 59 no body words    10.5925
 19 variables         3.4111
 11 constants         1.9749
 11 deferred words    1.9749
 10 values            1.7953
  7 user variables    1.2567
  4 among             0.7181
  3 vocabularies      0.5386
  3 xttable           0.5386
  1 string array      0.1795

Code words and code words without bodies together make up a almost thirty nine percent.
This data does not include the multitasker lexicon, nor does it include the metacompiler lexicon since neither one was loaded. It also does not include the sixteen headerless words in the kernel. Nor does it include the thirteen high level words used to obtain this data.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 17, 2023 2:15 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 862

Another caveat, this list doesn't include the words defined with :NONAME and it is only for the FORTH vocabulary. If the ASSEMBLER and EDITOR vocabularies were included, the percentage of high level words would be higher.


Top
 Profile  
Reply with quote  
PostPosted: Mon Jan 30, 2023 11:54 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 862

I originally released Fleet Forth under the General Public Licence. Now that the latest version gets closer to completion I'm not sure if that was the best choice. scotws mentioned the Forth tradition of putting the code in the public domain and I wonder if that is what I should have done, what I should do with the latest version of Fleet Forth?


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 31, 2023 12:48 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8442
Location: Southern California
JimBoyd wrote:

I originally released Fleet Forth under the General Public Licence. Now that the latest version gets closer to completion I'm not sure if that was the best choice. scotws mentioned the Forth tradition of putting the code in the public domain and I wonder if that is what I should have done, what I should do with the latest version of Fleet Forth?

Some relevant topics here are:
Copyright considerations.
Preferred License?
Another 65816 STC Forth

_________________
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 31, 2023 3:31 pm 
Offline

Joined: Mon Jan 09, 2023 9:33 pm
Posts: 23
JimBoyd wrote:
agsb wrote:
Please, take a look at https://github.com/agsb/immu/

It uses a minimal ITC, no keep IP and W, all references at return stack.

feel free to comment :)


Have you considered starting a new thread to discuss your Forth and your design goals?


No need, just point an alternative of ITC. I'm learn a lot in this topic, and could also use some codes ?


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 31, 2023 4:58 pm 
Offline
User avatar

Joined: Thu Dec 11, 2008 1:28 pm
Posts: 10802
Location: England
(It does seem like a good idea, if wanting to discuss ideas which are not Fleet Forth, to use a new thread instead of this Fleet Forth thread. Don't worry about the possibility of not reaching your audience - this place is not so busy. Your new thread will be seen, and if you ask good questions, you will get good answers.)


Top
 Profile  
Reply with quote  
PostPosted: Fri Feb 03, 2023 11:45 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 862
agsb wrote:
JimBoyd wrote:
agsb wrote:
Please, take a look at https://github.com/agsb/immu/

It uses a minimal ITC, no keep IP and W, all references at return stack.

feel free to comment :)


Have you considered starting a new thread to discuss your Forth and your design goals?


No need, just point an alternative of ITC. I'm learn a lot in this topic, and could also use some codes ?


Although I am currently experimenting with a subroutine threaded version of Fleet Forth, the version I discuss here is ITC Fleet Forth. I designed and wrote the initial version of Fleet Forth as an indirect threaded Forth because I like the simplicity and elegance of the ITC model. All words have a two byte code field. >BODY and BODY> work for all words. I am not going to change the way NEXT works for the ITC version of Fleet Forth.

As for the idea of keeping IP on the return stack, I keep IP in a dedicated pair of zero page locations. This keeps it out of the way and, I believe, simplifies skipping over inline strings.

As I recall, eForth had a minimal number of primitives so it could be easily ported to different systems. I understand it was dismally slow as a result. Fleet Forth has a large number of primitives. Making it easy to port Fleet Forth was not one of my design goals. I wanted to make Fleet Forth the best ITC Forth for the Commodore 64 that I could.

These were the three main ideas I gleaned from my perusal of IMMU. If you have any other ideas you believe could benefit Fleet Forth, it would be a good idea to present them one at a time here on this forum rather than post a link to a project somewhere else. This gives all interested parties a chance to discuss the pros and cons of any given idea and whether it is a good fit for Fleet Forth without the need to sift though external material just to find it.


Top
 Profile  
Reply with quote  
PostPosted: Sun Feb 19, 2023 10:35 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 862

I noticed the conversion algorithms here and here and thought routines using the decimal mode might be useful. Then I realized that could be a problem on the Commodore 64. It has the 6510 processor which is basically an NMOS 6502 with a slight modification. What if a nonmaskable interrupt hits while the CPU is in decimal mode?
I tested this scenario. The C64's RESTORE key generates a non-maskable interrupt. If the RUN/STOP key is pressed at that time, the NMI ISR will indirectly jump to Fleet Forth's warm start routine through address $300.
This short code word will run in a loop forever.
Code:
CODE FOREVER
   BEGIN  AGAIN
   END-CODE

If the RUN/STOP RESTORE key combination is used, Fleet Forth's warm start routine runs and everything is fine.
If SED is added before the loop:
Code:
CODE FOREVER
   SED
   BEGIN  AGAIN
   END-CODE

the RUN/STOP RESTORE key combination still breaks out of the loop, but after the "WARM START" message the cursor is blinking rapidly and it is virtually impossible to type any characters. Clearly the C64's NMI service routine is adversely affected by the decimal mode.
This is the solution I came up with. The C64's NMI service routine starts out like this:
Code:
FFFA @ DIS
 FE43         SEI
 FE44  318  ) JMP
4
 OK

The address at $318 is normally $FE47.
Replace that address with the address for a small piece of code to compensate for the C64 engineers not putting a CLD instruction in place of the useless SEI instruction:
Code:
   CLD
   $FE47 JMP

I was concerned about a non-maskable interrupt hitting while that address is being altered so I conducted a little experiment. I fetched the address from the reset vector at $FFFC and stored it at $318. Any NMI would cause a system reset back to BASIC. Everything worked fine. About a half hour later I wrapped up this experiment by hitting the RUN/STOP RESTORE key combination to reset the C64 back to BASIC.
The only other considerations are that the NMI service routine resets the vector at $318 and the possibility this vector could hold a different address on different models of the C64.
Here are the modifications I made to Fleet Forth's kernel.
Add the short code fragment to clear the decimal mode and resume the NMI service routine.
Code:
HSUBR  NMI2
   CLD  0 JMP  END-CODE

This will be a four byte code fragment without a header and without a code field. The jump address will be patched by the header-less routine (WARM) called by both the warm start routine and the cold start routine.
Here is the previous version of (WARM)
Code:
HSUBR (WARM)
   SEI  CLD
   2F # LDA  0 STA
   36 # LDA  1 STA
   USER.DATA    LDA  UP    STA
   USER.DATA 1+ LDA  UP 1+ STA
   6C # LDA  W 1- STA
   'THERE USER.DATA - 1- # LDY
   BEGIN
      USER.DATA ,Y LDA  UP )Y STA
      DEY
   0< UNTIL
   CLI
   >FORTH
   SP! AP! [COMPILE] [
   IORESET SINGLE DECIMAL
   PAGE BOOTCOLORS
   >ASSEM
   RTS
END-CODE

The new version of (WARM)
Code:
HSUBR (WARM)
   SEI
   $2F # LDA  0 STA
   $36 # LDA  1 STA  1 # LDY
   BEGIN
      USER.DATA ,Y LDA  UP ,Y STA
      $318 ,Y LDA  NMI2 2+ ,Y STA
      DEY
   0< UNTIL
   $6C # LDA  W 1- STA
   'THERE USER.DATA - 1- # LDY
   BEGIN
      USER.DATA ,Y LDA  UP )Y STA
      DEY
   0< UNTIL
   CLI
   NMI2  SPLIT SWAP
   # LDA  # LDY  $318 STA  $319 STY
   >FORTH
      SP! AP! [COMPILE] [
      IORESET SINGLE DECIMAL
      PAGE BOOTCOLORS
   >ASSEM
      RTS  END-CODE

When this routine is initially called by the cold start routine and when it is called by WARM by way of the NMI, address $318 will hold the default address. The jump address of NMI2 is patched to this address in the first BEGIN loop.
Code:
      $318 ,Y LDA  NMI2 2+ ,Y STA

NMI2 is installed as the new vector for address $318 by this section of code.
Code:
   NMI2  SPLIT SWAP
   # LDA  # LDY  $318 STA  $319 STY

This latest version of Fleet Forth works fine. The RUN/STOP RESTORE key combination breaks out of the loop in the code word FOREVER and warm starts without a problem.
Code:
CODE FOREVER
   SED
   BEGIN  AGAIN
   END-CODE

I also wrote a code word to test the normal interrupt service routine. It sets the decimal mode and runs in a loop until a key-press is detected, saving and restoring the x-register as needed. Once out of the loop, it pushes the processor status and pulls it to the accumulator before clearing the decimal mode. The accumulator is then pushed onto the data stack to confirm that decimal mode was not cleared by the C64 kernal routine to check the keyboard buffer for a key.
The C64 ISR occurs about sixty times a second and I let this word run for about ten seconds before pressing a key. There were no ill effects that I am aware of. It seems as though the normal ISR is immune to decimal mode.
The new Fleet Forth kernel is twenty bytes bigger and still smaller than Blazin' Forth's kernel. Not too bad.


Top
 Profile  
Reply with quote  
PostPosted: Sun Feb 19, 2023 11:03 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 862

I should mention that I'm not running Fleet Forth on a real Commodore 64, I'm running it on VICE.
Based on my experiences with a real Commodore 64, VICE has been a very accurate simulation so I'm inclined to believe the decimal mode problem with the C64's NMI service routine occurs on the actual hardware as well.


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 13, 2023 10:50 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 862
JimBoyd wrote:
I noticed the conversion algorithms here and here and thought routines using the decimal mode might be useful. Then I realized that could be a problem on the Commodore 64. It has the 6510 processor which is basically an NMOS 6502 with a slight modification. What if a nonmaskable interrupt hits while the CPU is in decimal mode?
...
I've had a few weeks to think about this and decided to go back to the original warm start routine. If another source of non-maskable interrupts is enabled then this 'fix' will not work anyway and there will be a chance of a non-maskable interrupt occurring while the new vector for address $318 is being changed. It's just not worth the hassle, restrictions on sources of non-maskable interrupts or the increased size to safely support decimal mode in Fleet Forth.


Top
 Profile  
Reply with quote  
PostPosted: Mon Mar 13, 2023 11:07 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8442
Location: Southern California
Without my reviewing 19 pages of this topic... Is it really a problem?  The D flag is part of the status register that gets pushed in the interrupt sequence and pulled in the RTI sequence, and the first instruction in the ISR can be CLD (which is standard procedure on the NMOS 6502, but not necessary on the CMOS 65c02 since CLD is an automatic, implied part of its interrupt sequence).  The background program and the ISR code can have their own D status without affecting the other.

_________________
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: Mon Mar 13, 2023 11:59 pm 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 862

It's not a problem. I'll just avoid using decimal mode. As for the ISR code having its own D status, it's a Commodore 64 and the ISRs are a part of the kernel in the C64's ROM and the 6510 NMOS cpu does not clear decimal mode when servicing an interrupt.
I wasn't seeking help in this post. It was more along the lines of 'I'm not doing that now, and here is why.'
Basically, it's a heads up for anyone following along. I may have, on some future date, occasion to mention the source for the warm start routine or mention something else which would conflict with what I said about that change. On that day I may forget to mention that I changed the warm start routine back.


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 14, 2023 3:00 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 862

I mentioned another way to define THRU . Here are the block loading words in Fleet Forth.
These are in the kernel.
Code:
2VARIABLE HISTORY
: LINELOAD  ( LINE# BLK# -- )
   DUP 0=
   ABORT" CAN'T LOAD 0"
   RB DECIMAL
   BLK 2@ 2>R
   BLK !  C/L * >IN !
   INTERPRET  2R>
   BRANCH [ BLK.2! , ] -;
: LOAD  ( U -- )
   0 SWAP BRANCH
   [ ' LINELOAD >BODY , ] -;
: RAM  ( BLK#1 -- BLK#2 )
   RAM.OFFSET + ;
: FH  ( N1 -- N2 )
   BLK @ DUP UNDER+ ?EXIT
   SCR @ + ;
: DR+  ( BLK#1 #DR -- BLK#2 )
   7 AND  DR.OFS.PWR LSHIFT  + ;

HISTORY is set by WORD . HISTORY was originally added to Fleet Forth so WHERE could accurately display where an error originated.
LINELOAD takes a line number and a block number. It will load a screen starting at the specified line number.
LOAD loads the entire block. It branches to the beginning of LINELOAD .
Fleet Forth sets aside a range of block numbers for each disk as well as a range for the Ram Expansion Unit.
In the current version of Fleet Forth, RAM adds an offset of 16384 ($4000) to the number on the stack. Fleet Forth's BLOCK and BUFFER will access blocks higher than 16383 ($3FFF) from the Ram Expansion Unit
DR+ masks off the higher bits of a number and treats drive numbers 0 and 8 as the same device, 1 and 9 as the same device on up to treating 7 and 15 as the same device. DR+ adds the offset for the desired drive.
Code:
0 DR+   \
8 DR+   \ adds 0 to the number on the stack

1 DR+   \
9 DR+   \ adds 2048 to the number on the stack

2 DR+   \
10 DR+  \ adds 4096 to the number on the stack
...
7 DR+   \
15 DR+  \ adds 14336 to the number on the stack

RAM     \ adds 16384 to the number on the stack

Each drive, and the Ram Expansion Unit, sees its block range starting at 0.
Assume there is a disk with Forth blocks in drive 8 and drive 9 and both drives are open for block access.
Code:
1 LOAD \ loads block 1 from drive 8
1 8 DR+ LOAD \ also loads block 1 from drive 8
1 9 DR+ LOAD \ loads block 1 from drive 9
1 RAM LOAD \ loads block 1 from the Ram Expansion Unit

FH , from here, is a nice utility word from Leo Brodie's "Thinking Forth". When loading a screen, it adds the current block number to the number on the stack. This allows loading blocks (with LOAD or THRU ) relative from the currently loading block. When not loading a block, FH adds the current screen number to the number on the stack to assist editing.
THRU is defined in the system loader. This is its source in Fleet Forth.
Code:
: THRU  ( U1 U2 -- )
   >R
   BEGIN
      5 ?CR
      DUP U.  LOAD
      R@ HISTORY @ 1+ DUP>R U<
      DONE? OR
   ?LEAVE
      R>
   AGAIN -;

Yes, that is ?LEAVE used without a DO LOOP . Fleet Forth's ?LEAVE will, if the flag on the data stack is TRUE , drop two items from the return stack and pull a third item from the return stack and store it in IP .?LEAVE is used in Fleet Forth's definition of THRU to make it 2 bytes smaller than this:
Code:
: THRU  ( U1 U2 -- )
   >R
   BEGIN
      5 ?CR
      DUP U.  LOAD
      R@ HISTORY @ 1+ TUCK U<
      DONE? OR
   UNTIL
   R> 2DROP ;

Fleet Forth's source for THRU is not portable to other Forth systems with ?LEAVE in there and it doesn't matter. THRU is in the Controlled Reference Words of the Forth-83 Standard and it is in the ANSI Forth Standard. Any Forth system which uses blocks will likely have THRU .
I have not yet added --> except as a temporary definition. Should I choose to define it in the system, it will be defined in the system loader along with THRU .


Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 18, 2023 12:45 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 862

Leo Brodie introduced the word \S in his book Thinking Forth. \S stops the rest of a screen from loading. Here is his source for \S
Code:
: \S   1024 >IN ! ;

In Fleet Forth it can be defined as this
Code:
: \S   B/BUF >IN ! ;

However, since the value of >IN is used in an unsigned comparison and WORD does not increment >IN beyond the size of the text stream, \S can be shortened further.
Code:
: \S   >IN OFF ;

This will also work with Fleet Forth.
Code:
: \S   2R> 2DROP ;

It can be made even smaller. I once mentioned that Fleet Forth's LEAVE is equivalent to using this phrase.
Code:
   2R> 2DROP EXIT

anywhere that phrase is used LEAVE can be used and vice versa.
For example
Code:
: TESTWORD
   10 0
   DO
      <DO SOME STUFF>
      <TEST> IF  LEAVE  THEN
   LOOP ;

can be rewritten as this
Code:
: TESTWORD
   10 0
   DO
      <DO SOME STUFF>
      <TEST> IF  2R> 2DROP EXIT  THEN
   LOOP ;

That phrase does the same thing as Fleet Forth's LEAVE , pull the top two loop parameters from the return stack and discard then exit to the address of the third parameter. The new TESTWORD is larger and slower, but it is functionally equivalent.

This
Code:
: \S   2R> 2DROP EXIT -;

compiles the same thing as this
Code:
: \S   2R> 2DROP ;

so Fleet Forth's source for \S can be changed to this
Code:
: \S   LEAVE -;



Top
 Profile  
Reply with quote  
PostPosted: Sat Mar 18, 2023 1:16 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8442
Location: Southern California
Quote:
Code:
IF  LEAVE  THEN

I use that enough that I've made it part of my kernel, as ?LEAVE.  It pays for itself in memory, and also runs a lot faster because the ?leave (the internal compiled by the immediate compile-only word ?LEAVE) is a primitive.

_________________
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  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 343 posts ]  Go to page Previous  1 ... 16, 17, 18, 19, 20, 21, 22, 23  Next

All times are UTC


Who is online

Users browsing this forum: No registered users and 3 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: