6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Thu Nov 21, 2024 8:33 pm

All times are UTC




Post new topic Reply to topic  [ 266 posts ]  Go to page Previous  1 ... 12, 13, 14, 15, 16, 17, 18  Next
Author Message
PostPosted: Tue Nov 29, 2022 4:53 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
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.
Attachment:
IMG_20221129_164929 (Medium).jpg
IMG_20221129_164929 (Medium).jpg [ 234.62 KiB | Viewed 1046 times ]


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 29, 2022 6:49 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 255
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.


Top
 Profile  
Reply with quote  
PostPosted: Tue Nov 29, 2022 7:34 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
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.)


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 30, 2022 11:05 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
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.


Top
 Profile  
Reply with quote  
PostPosted: Wed Nov 30, 2022 11:19 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
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:
: 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:
   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:
   <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:
   <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?


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 01, 2022 12:12 am 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
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.


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 01, 2022 3:33 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 255
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:
\ 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:
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.


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 01, 2022 3:56 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 255
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:
: 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:
: 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).


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 01, 2022 8:28 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
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?


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 01, 2022 8:50 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
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?


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 01, 2022 8:52 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
Thanks Garth. If that is expected bahaviour then fine.


Top
 Profile  
Reply with quote  
PostPosted: Thu Dec 01, 2022 9:15 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
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


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 02, 2022 7:45 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
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?


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 02, 2022 7:59 pm 
Offline

Joined: Fri Apr 15, 2016 1:03 am
Posts: 140
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


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 02, 2022 9:19 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8543
Location: Southern California
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?


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 266 posts ]  Go to page Previous  1 ... 12, 13, 14, 15, 16, 17, 18  Next

All times are UTC


Who is online

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