6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Mon May 13, 2024 11:04 pm

All times are UTC




Post new topic Reply to topic  [ 10 posts ] 
Author Message
PostPosted: Sat Apr 18, 2020 9:35 pm 
Offline

Joined: Tue Jun 08, 2004 11:51 pm
Posts: 213
Hi All
I'm working on a project for an old PET computer. It is a Pet Forth adapted for a Commodore Pet. It runs with BASIC 1 ROMs. I told you it was old. It runs at 800 hex. I don't have a Pet so have been working remotely.
There is a thread on the vcf Forum called Petsoft 6502 FORTH.
There is a *.tap file on the first post and a *.prg on post # 7. There is a copy of the Apple manual on post #10. I've created a listing of sorts on post #80. Don't use the one on #78, it is missing significant chunks of code.
It is an early Forth and a lot of the words you may be familiar with are missing.
It looked like it was being meta-compiled from a APPLE to run on the PET ( note ROMs for BASIC 1 ). I has an error in it that several words were duplicated. The dictionary is intact but I suspect while meta-compiling, they used the same screen twice as the code is the same. The only thing is, they left out a few words from the APPLE version :(. One that I think one would want was PRINT ( see the Apple manual for how it works ). I've been trying to write it with the unfamiliar Forth. I don't have a PET, let alone one with ROM BASIC 1 and 16K.
Also, 6502 is not my heaviest language. In the listing I've left out the dictionary headers to remove clutter, I just put the names in, so one couldn't reassemble it without some editing.
I'm hoping to solicit some help here.
One of the words that I would like to use is WHILE but unlike later Forths, there is no REPEAT word. It doesn't have any compiler security so I think I can use THEN to do the back patching but it also needs to patch the loop back. I suspect it was work in progress. Also, if someone can run it, I'd like to know if the word IBP ( In Buffer Pointer ) is a moving pointer or just a pointer to the beginning of the input buffer. I really need a running pointer for the PRINT word.
This Forth does a lot of data stack checking so should be relatively robust, even though relatively small.
My listing could use more comments as well. If someone has something to add, please use only lower case for comments and labels. I have reserved upper case for dictionary names.
It should be a fun project.
Dwight


Top
 Profile  
Reply with quote  
PostPosted: Sun Apr 19, 2020 7:18 pm 
Offline

Joined: Tue Jun 08, 2004 11:51 pm
Posts: 213
I've made 3 bug fixes since first posted.

Here is my PRINT that I think will work. There is no immediate ' and I don't fully understand how to use the assembler so I'm just hacking the code in place. What I want to do is LDA # ( a number from the stack ) but I think the it expects to see a "LDA # nn" where nn is a fixed number. They really should have bitten the bullet and used an rpn assembler. One could use it either way. I could be wrong but I'm just hacking it. It would have been nice to have [ ] and a LITERAL while making a compiler word. Here is what I think is a PRINT.
I can't figure out how to end a WHILE in a BEGIN .. END loop. I think it is BEGIN ... WHILE ... ??? ;.. 0 END
I'd need to play with working code to figure it out, so my BEGIN loops are a little clumsy.
I see a way to do what in fig Forth is [ with ^ but how to do ] ?? figForth is much more friendly to make compiler words.

Code:
BASE @ HEX
: PRINT
4C C, 0 ,  ( JMP n )
HERE IBP 1 - ( mark begining of the string/jump patch, setting up for BEGIN .. END )
BEGIN
    1+ DUP C@ $20 - ( skip leading spaces )
END ( now at delimiter )
DUP C@ <R ( save the delimiter )
BEGIN ( move string to dictionary )
  1+ DUP C@ DUP ( next address and 2 ea character )
   C, ( compile character )
   I = ( no R@ so I use I to see what is on the return stack )
END ( check for delimiter )
R> DROP ( don't need delimiter any more )
1+ IBP !  ( not sure if I need the 1+ but I think it should point to space after string )
( begin of string should still be on stack )
HERE OVER 2 - ! ( Patch the JMP )
HERE 1 - 0 SWAP C! ( replace delimiter with 0 at end of string for $MSG )
( hacked assembly follows making literal )
88 C, ( DEY )
A9 C, DUP C, ( LDA # LSB )
0A96 , ( STA (0A),Y )
88 C, ( DEY )
A9 C, SWAB C, ( LDA # MSB )
0A96  , ( STA (0A),Y )
20 C, ( call ) 0D05 , ( $MSG )
IMMEDIATE ;
BASE !


You should now be able to do:

Code:
: HI  CR PRINT &HELLO WORLD& ;

Dwight


Last edited by dwight on Sun Apr 19, 2020 10:48 pm, edited 4 times in total.

Top
 Profile  
Reply with quote  
PostPosted: Sun Apr 19, 2020 9:07 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
I don't know anything about the PET. Does it have enough memory to add the Forth tools so you don't have to do things in such a juryrig way?

_________________
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 Apr 19, 2020 9:34 pm 
Offline

Joined: Tue Jun 08, 2004 11:51 pm
Posts: 213
By what do you mean?

( note: I had a bug that has been changed in the code )
Dwight


Top
 Profile  
Reply with quote  
PostPosted: Sun Apr 19, 2020 9:59 pm 
Offline

Joined: Tue Jun 08, 2004 11:51 pm
Posts: 213
It doesn't have a lot of memory but it does run in 16K.
It doesn't have a ." ... " but the original instructions used a PRINT instead that wasn't included.
There is no LITERAL and no CMOVE.
It is call threaded so code inline is expected.
PRINT is an IMMEDIATE word that compiles into the dictionary. What would you do differently?
Dwight


Top
 Profile  
Reply with quote  
PostPosted: Sun Apr 19, 2020 11:26 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
I mean to be able to extend it with BEGIN...WHILE...REPEAT, the CASE structure, an assembler, etc.. I used
Code:
   ...  [ <calculate_some_number_here ] LITERAL ...
so often that I finally defined ]LIT so all these occurrences wouldn't take so much space in the source code.

_________________
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 Apr 20, 2020 2:09 am 
Offline

Joined: Tue Jun 08, 2004 11:51 pm
Posts: 213
I thought about that. I've used ]LIT many times, especially when I have some complicated calculation on the side.
I've spent some more time looking at the assembler. The assembler does " operand mnemonic mod " which would have worked fine with the value off the stack. I think it would have worked fine if I'd just compiled using their assembler.
There is a word the puts it into the interactive mode so I can do interactive. I think is is a toggle. ^ has three states.
0 is normal interactive. 1 is compiler mode. I think 2 puts it in an interactive word while in a : compile.
One can use a ; in 1 or 2 but I think ^ toggle back and forth between states 1 and 2. If in state 0 when doing a ; it will error out but seems to be happy in 1 or 2.
What does it take to run vice? I really should be experimenting with a running system. I see others are using it as a simulator. I'd have to play with it some.
I'd still want a LITERAL rather than hand typing several assembly operations. It might even be better to give up on the added speed of inline LIT and just create a call to something like LIT. Technically I should be using their stack checking words. There is $NSO that checks for over flow and $NSU that checks for under flow. I didn't want to clutter things up with too much code but it would make sense with a LIT function. It would be 5 bytes each time it is used instead of 10 or 12 bytes of completely inlined.
I'm still working with my listing to figure out the assembly parts. I've got a few of the things figured out 0A is the data stack pointer. 34 through 37 are used as work space ( not re-entrant ) the is separate space for divide and multiply operations as well.
This was just a proof of concept to see if I could create a PRINT compiler word. Creating compiler words is always a complicated process. ( at least for me ). One has to think of the compile time action and what it is going to do at run time. Not having a form of BUILDS DOES is a pain. It helps to keep the two parts separate but isn't totally necessary, as one can see here. I would have changed things a little with a BUILDS DOES type operation. It would have been cleaner to understand. That is why I had such wordy comments.
Dwight


Top
 Profile  
Reply with quote  
PostPosted: Mon Apr 20, 2020 2:49 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8433
Location: Southern California
Um, yeah... It's hardly Forth if it doesn't have the pearl of Forth, is it? (BUILDS...DOES, or CREATE...DOES>, also ;CODE)

_________________
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 Apr 21, 2020 11:27 pm 
Offline

Joined: Tue Jun 08, 2004 11:51 pm
Posts: 213
I've been looking at my listing and think I've figured out WHILE. I believe it would be used:
BEGIN ... cond IF ... WHILE
cond is the condition for the IF operation. If the IF was true, it would execute the code after the IF to the WHILE and then loop back to the BEGIN. If the IF failed, it would continue after the WHILE.
There is no compiler security so such a mix is fine.
It is interesting that all the conditional test have a way to break out.
Friendlier when a bad loop doesn't end.
Dwight


Top
 Profile  
Reply with quote  
PostPosted: Wed Apr 29, 2020 10:04 pm 
Offline

Joined: Tue Jun 08, 2004 11:51 pm
Posts: 213
This one seems to work. I even had the wrong instruction, not even matching my comment.
There were a number of other bugs as well. Th concept was good but the implementation was not.
The most embarrassing one was that I knew LDA 0E meant to fetch from page 0 address 000E but for some reason LDA 1F really meant LDA #1F in my mind. Only 1F, no other.
Dwight

BASE @ HEX
HERE ?
: PRINT
4C C, 0 , ( JMP n )
HERE IBP @ 4 + ( skip to end of PRINT )
BEGIN
1+ DUP C@ $20 - ( skip leading spaces )
END ( now at delimiter )
DUP C@ <R ( save the delimiter )
BEGIN ( move string to dictionary )
1+ DUP C@ DUP ( next address and 2 ea character )
C, ( compile character )
I = ( no R@ so I use I to see what is on the return stack )
END ( check for delimiter )
R> DROP ( don't need delimiter any more )
1 - IBP ! ( not sure if I need the 1+ but I think it should point to space after string )
( begin of string should still be on stack )
HERE OVER 2 - ! ( Patch the JMP )
0 HERE 1 - C! ( replace delimiter with 0 at end of string for $MSG )
( hacked assembly follows making literal )
88 C, ( DEY )
A9 C, DUP SWAB C, ( LDA # MSB )
0A91 , ( STA (0A,Y )
88 C, ( DEY )
A9 C, C, ( LDA # LSB )
0A91 , ( STA (0A,Y )
20 C, ( call ) 0D05 , ( $MSG )
IMMEDIATE ;
BASE !


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 10 posts ] 

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: