Tali Forth for the 65c02

Topics relating to various Forth models on the 6502, 65816, and related microprocessors and microcontrollers.
adrianhudson
Posts: 169
Joined: 30 Apr 2022
Location: Devon. UK
Contact:

Re: Tali Forth for the 65c02

Post by adrianhudson »

SamCoVT,
Firstly, thank you so much for yours replies. You have quite obviously spent a long time creating them and I am most grateful.

On the i2c stuff (technical term "stuff"). I'm actually quite familiar with i2c, I have it working - Garth's code, modified to use different pins - which I am sort of coming to regret a little since many people just use what he created. Still, there is an old saying that to truly understand a program you should channge it (or words to that effect) so it was a useful exercise.

So, anyway, lest you should think you have wasted your time making your post, you have not and it is very useful indeed. It is really good to see how you have interfaced Forth to hardware and particularly Tali Forth.

Regarding the Tali Forth code I have used: I used the one from your new repository - I figured that if you have taken over Tali development then it would be daft to use the original. I hope that is okay.

Now, regarding your second post... I have an apology to make. My throwaway comment "I have no handshaking yet. That is my next thing to sort out." should have been qualified. I have all the code ready in another program - I just need to copy and paste it into Tali. What I meant was I don't have the hardware set up to actually use RTS/CTS. So, I am really sorry. You must have spent an age typing all that.

I use a TTL to USB converter - it has RX, TX, DSR and CTS pins. Now, in relation to my SBC, CTS is an input (as far as I understand it - it means "the other end is ready to receive data". What I need is an RTS output, i.e. when the SXB sets RTS false it means stop sending me data. Why then this little converter thing has a pin marked CTS is strange. I perhaps need to buy a different converter.
IMG_20221129_164929 (Medium).jpg
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: Tali Forth for the 65c02

Post by SamCoVT »

Regarding the hardware part of the handshaking, you have everything you need. In the same way you had to connect the R65C51's RX to the PCs TX (and vice versa), you also cross the handshaking lines. The RTS (Request To Send) output from the R65C51 ( pin 8 ) connects to the CTS (Clear To Send) input of the PC. That way, when your single board computer requests data the PC knows it's clear to send it right then - and when your single board stops requesting data (because it's buffer is full) the PC knows it's not clear to be sending data at that moment and it will wait until it's clear to send again.

This kind of handshaking can be bidirectional, but it's often used in just one direction for a faster device to talk to a slower device. The older USB->TTL_RS-232 adapters used to bring RTS out on the last pin, but modern ones swapped it with DTR specifically for Arduino boards so that opening the serial port resets the micro into bootloader mode (you used to have to press the reset button yourself on ancient Arduinos when downloading a new firmware). Regardless, you don't need the handshaking in the other direction because your PC will never need to ask the single board computer to slow down on sending serial data. You just need to add one wire to the CTS pin on your USB adapter over to RTS on your single board computer, change your terminal software to use hardware handshaking, and you should be ready for handshaken (handshook?) serial.

One note about FTDI adapters that bit me. They don't stop transmitting immediately after you deassert RTS and can send up to 3 extra characters - that info is buried on their website in an old FAQ: "If CTS# is logic 1 it is indicating the external device cannot accept more data. the FTxxx will stop transmitting within 0~3 characters, depending on what is in the buffer." Garth's buffered reading helped with that, as it asks the PC to stop when there are about 15 characters left in the buffer.
adrianhudson
Posts: 169
Joined: 30 Apr 2022
Location: Devon. UK
Contact:

Re: Tali Forth for the 65c02

Post by adrianhudson »

Thank you sir! My handshooken SXB is working perfectly! I don't really know how to thank you more. I'd buy you a beer but I suspect you may be a loooooooooooong way from me!

(Darn it, my keyboard is running out of exclamation marks. Need to stock up on them.)
adrianhudson
Posts: 169
Joined: 30 Apr 2022
Location: Devon. UK
Contact:

Re: Tali Forth for the 65c02

Post by adrianhudson »

SamCoVT

With regard to your code for BLOCK-READ and BLOCK-WRITE...

My board has only a 24LC256 (which I know works since I can read/write it in assembler) so I don't have the messing about with the two internal blocks. It also operates with 64 byte write pages, not 128.

To that effect I have modified your Forth routines in the following ways:
. changed the addresses of the 65C22 to match my memory map
. changed the pins to match the pins I use for i2c. I use other pins on the VIA simultaneously so I changed it to only initialize the two pins
. changed it work with 64 byte write blocks
. changed the assembly words to use tsb and trb (no good reason for this I just felt like it)

In doing so I came up with two questions - both probably my ignorance of Forth

First, how does i2c_setup get called? I can't see where/how it is referenced. Or am I misunderstanding something?

Second, i2c-txbit is defined as
: i2c-txbit ( bit -- )
if i2c-sda1 else i2c-sda0 then i2c-clock ;
The IF implies i2c-sda1 returns a value but I can't see / don't know how the assembler routine does that?

Anyway, it doesn't work at the moment but that is another matter! It certainly tries to communicate with the chip - I can see the i2c traffic but it goes into a loop when writing. I suspect the ACK polling at the end of eeprom-pagewrite is looping forever.
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Tali Forth for the 65c02

Post by GARTHWILSON »

adrianhudson wrote:
First, how does i2c_setup get called? I can't see where/how it is referenced. Or am I misunderstanding something?
Just put it in a command line or a program wherever you want it executed.  It does not need or return any parameters.

Quote:
Second, i2c-txbit is defined as
: i2c-txbit ( bit -- )
if i2c-sda1 else i2c-sda0 then i2c-clock ;
The IF implies i2c-sda1 returns a value but I can't see / don't know how the assembler routine does that?

Keep in mind that IF in Forth is saying, "If the above is true," (knowing from a flag left on the stack), "do the following."  It might trip up newcomers to see IF...ELSE...THEN instead of IF...THEN...ELSE.  Instead of IF <condition> THEN <do this>, it's "Is such-and-such condition true?" followed by "IF so,..."  The ELSE part is the same as in other languages.  The THEN is the end of the structure.  Without the ELSE, think of it in the analogy of this example:

Code: Select all

: PUT_ON_SHOES
    Are you lacking socks?
    If so,
        put your socks on first,
    then put on your shoes     ;

Another way to express it is with the example,

Code: Select all

   Is A less than B?            \ The test leaves a flag on the stack.
   IF so, do such-and-such.     \ IF looks at the flag, and branches if the flag was 0.
   ELSE,  do this other stuff.  \ ELSE ends the do-if-true part and branches to THEN.
   THEN, continue with the following, being done with the conditional stuff.

In some cases, it can be visually helpful to write,

Code: Select all

   <condition test>      IF
   <do-if-true stuff>    ELSE
   <otherwise-do-this>   THEN
   <continue>

especially where you have a lot of nested IF structures and you don't want to go indenting all the way across the page; and then you can have a bunch of THENs all in one line at the end:

Code: Select all

   <condition test>      IF
   <do-if-true stuff>    ELSE
   <do stuff>
   <condition test>      IF
   <do-if-true stuff>    ELSE
   <do more stuff>
   <conditon test>       IF
   <more do-if-true>     ELSE
   <yada yada>           THEN  THEN  THEN
   <continue>

Somewhere I have real-life examples of this from my own work.  Hopefully I'll remember where, and show them.

Anyway i2c-sda1 doesn't need to return anything.  It's an action to take if the cell (flag in this case) at the top of the stack was non-zero.
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?
adrianhudson
Posts: 169
Joined: 30 Apr 2022
Location: Devon. UK
Contact:

Re: Tali Forth for the 65c02

Post by adrianhudson »

Thanks Gareth. I forgot the IF syntax. Oops

Regarding the call of i2c-setup. I meant that in SamCoVT's routine, that word needs to be called sometime to do its job of setting up the VIA. It isn't referenced in any of the code he showed and I wondered when it does get called. I can't imagine you have to call it manually before you reference any commands that reference blocks.
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: Tali Forth for the 65c02

Post by SamCoVT »

i2c-setup is indeed never called in my code. The VIA (65C22) is reset (hardware reset) along with all the other chips on my board at powerup and those registers (via.porta (called ORA in the datasheet) and via.ddra) are both zeroed on reset. Unfortunately, WDC's datasheet is not very clear on that so I had originally written this word with the plan of calling it on powerup. Now I only call i2c-setup (manually) if I have messed up the configuration of my via and don't want to reset the board.

I'll also just mention that the . in the names I used for the registers doesn't mean anything to Forth and are just part of the name (eg. they could have also been named via-ddra or via/ddra or viaddra as those are all valid forth word names). I just use the dot syntax because I'm used to that from other languages and it helps me keep all of the names for a particular piece of hardware sorted.

If you need it to be called at startup in your code, then you can just call the i2c-setup word down near where the vectors are loaded, eg:

Code: Select all

\ Connect to Fourth BLOCK words
i2c-setup \ Initialize the VIA hardware
' eeprom-blockread  BLOCK-READ-VECTOR !
' eeprom-blockwrite BLOCK-WRITE-VECTOR !
For debugging your code, the awesome part about Forth is that you can define a word, run it, and then poke around in memory and hardware to see what happened. Want to make sure that the VIA registers are still initialized? You can just type in:

Code: Select all

via.ddra c@ . via.porta c@ .
to see what the current values in the hardware are. If you are having trouble with a word, you can try running it line by line (by pasting a line in, running just that line, and then investigating what happened).

One note about interpreted mode, where you are just typing things in and running them directly, is that the flow-control words are compile-only words (they will tell you that if you forget and try to use them in interpreted mode). This means if you have a loop that need to run 8 times, you can't use DO and LOOP in interpretive mode. If I need to "step" through the code in the loop, I will paste the guts of the loop multiple times. If I is used in a do-loop then I just put the value I want "I" to be.

This is doable for smaller loops but impractical for larger loops, like your 64-byte EEPROM sector writing code). In that case, I might "single-step" (by running individual lines) through the loop code once or twice to make sure the logic inside works properly, and then I will define a word that has only that loop in it. If I was hunting down nACK problems, I would probably make a word that does all but the last byte and then I would do that last byte step by step and use a multimeter or logic probe on the hardware as well as .S to see what was on the stack (without disturbing it). I2C is nice in that you control the clock and there is no minimum speed for most devices, so it's OK to pause in the middle of sending a byte and make sure everything looks good before continuing.

If you keep your debugging code in a text editor while you are working, you can make reproduceable code that will get you from idle to the very last byte of a transfer reliably that you can just copy/paste. I'll often make a test word that I keep adding the "known good" code to - so I can progress right up to the point of interest by running the test word. Forth lets you re-define a word by just defining it again - only the most recent is run (the older ones do still take up dictionary space, but they will be gone on reset). I'll also make a word that prints out all of the values in the important memory and hardware locations. Once you have your logic or hardware figured out and fixed up, then you take what you learned and put it in the final version of the word. I often abandon my debugging code once I have the real-deal working, but you certainly could save it - especially if you made some extra words to test hardware that might be useful later.

Words you will want for debugging: .S DUMP @ C@ . and Tali also has CTRL-P and CTRL-N to recall the previous/next line of the last 8 lines entered.
SamCoVT
Posts: 344
Joined: 13 May 2018

Re: Tali Forth for the 65c02

Post by SamCoVT »

Here are some example debugging words that I still have hanging around from when I was writing some FAT32 code. They print the current info about something without changing it, so they can be run at any time:

Code: Select all

: finfo  ( fileid -- )  ( fileid info for debugging )
   cr ." FILEID: "          dup u.
   cr ." filename: "        dup >filename 0B type
   cr ." access mode: "     dup >attrib c@ u.
   cr ." first cluster: "   dup >firstcluster 2@ ud.
   cr ." current cluster: " dup >currentcluster 2@ ud.
   cr ." current sector: "  dup >currentsector 2@ ud.
   cr ." file position: "   dup >fileposition 2@ ud.
   cr ." file size: "       dup >filesize 2@ ud.
   cr ." linestart: "           >linestart 2@ ud. ;

Code: Select all

: sb ( -- ) ( Show buffer )
  base @ hex
  fatbuffer
  512 0 do
    i 16 mod 0= if 10 emit 13 emit then
    dup c@ 2 .r space 1+
  loop
  drop base !
;
These are both just words that print info on a file handle or print an entire buffer (dump could also have been used for the buffer).
adrianhudson
Posts: 169
Joined: 30 Apr 2022
Location: Devon. UK
Contact:

Re: Tali Forth for the 65c02

Post by adrianhudson »

SamCoVT thank you. All very useful indeed.

I am getting the hang of this - fast. I've done more in Forth in the last few days than I have in 40 years!

However see this:

Tali Forth 2 for the 65c02
Version 1.0 24. Jan 2020
Copyright 2014-2020 Scot W. Stevenson
Tali Forth 2 comes with absolutely NO WARRANTY
Type 'bye' to exit
: aa 99 . ; ok
aa 99 ok
: bb aa ; ok
bb 99 ok
: aa 88 . ; redefined aa ok
aa 88 ok
bb 99 ok

It appears that words (bb in this case) continue to refer to old versions of other words (aa gets changed to print 88 but when called from bb the old version still executes) is this correct?
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Tali Forth for the 65c02

Post by GARTHWILSON »

Yes. FIND will find the latest definition of a word (within a given vocabulary), since the search starts with the most recent and works backward; however, words compiled using an older definition of a particular word will not get modified to use the new one.  There are ways to change that if you want to, as Forth's flexibility is pretty much unlimited and much of its power lies in possibilities that do not initially meet the eye; but these are the basics.
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?
adrianhudson
Posts: 169
Joined: 30 Apr 2022
Location: Devon. UK
Contact:

Re: Tali Forth for the 65c02

Post by adrianhudson »

Thanks Garth. If that is expected bahaviour then fine.
adrianhudson
Posts: 169
Joined: 30 Apr 2022
Location: Devon. UK
Contact:

Re: Tali Forth for the 65c02

Post by adrianhudson »

Block I/O working! Thanks SamCoVT and Garth.

I had to put some delay in the bit read and write words. i suspect my i2c pullup resistors need some tweaking. i am relying on resistors in a clock module to do the pulling up. Probably they are a bit weak.

(Edit: Also, knowing the fact that words use old versions of changed other words really helped! ~chuckle~)

me==enjoying Forth
adrianhudson
Posts: 169
Joined: 30 Apr 2022
Location: Devon. UK
Contact:

Re: Tali Forth for the 65c02

Post by adrianhudson »

Okay, I need numbers bigger than can be held in Tali's 16 bit cells. Am I completely stuck or are there techniques to work with larger numbers than 32767 inTali?
leepivonka
Posts: 167
Joined: 15 Apr 2016

Re: Tali Forth for the 65c02

Post by leepivonka »

Tali has some words that handle double cell (32bit) numbers.
Words like 2@ 2! M* and others
Also see https://forth-standard.org/standard/double
User avatar
GARTHWILSON
Forum Moderator
Posts: 8773
Joined: 30 Aug 2002
Location: Southern California
Contact:

Re: Tali Forth for the 65c02

Post by GARTHWILSON »

And if that's not enough, there are triple- and quad-precision words in the public-domain materials from the Forth Interest Group, or FIG.  The website is http://www.forth.org/ .  Unfortunately it has not been well maintained since FIG dissolved, so it might take some digging.  A web search wasn't really giving me what I hoped for.  You can look for MATHBOX.SCR, and for floating-point, FLOAT4TH.SCR or the later FLOAT4TH.BLK (although the more experience I get with scaled-integer, the more I think floating-point is seldom necessary, which is nice because for a processor like the '02 which doesn't have floating-point hardware, floating-point presents an awful lot of overhead).  I have those here, printed on fanfold paper, from the low-density 5¼" floppy discs I got 25+ years ago from FIG for the price of the disc and shipping.  I have plenty of FDDs but no controllers left that still work.  [Edit: I see I do have some of this stuff on my hard discs.  It might take some conversion to make it readable.  One of them is converted by hand, from a screen file to a text file, by hand, meaning there could be an error here and there.]

You can also get good resources from Taygeta's website.  https://www.taygeta.com/fsl/ is about the Forth Scientific Library Project, and https://www.taygeta.com/fsl/scilib.html has a list of links to lots of algorithms in Forth.

I should at least link to them on my own site (as opposed to 6502.org, since they're not 65-specific).  I'm sure their performance could be vastly improved by re-writing some of the lower-level words as primitives for 6502.
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?
Post Reply