6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sun Nov 24, 2024 12:09 am

All times are UTC




Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Mon Oct 26, 2020 5:02 pm 
Offline
User avatar

Joined: Mon Mar 23, 2020 4:02 pm
Posts: 52
Location: Parker, CO
Complete Forth newbie here. I've recently gotten Tali Forth 2 running on my SBC and would like to set some outputs on my 6522 VIA. It is mapped to addresses $8010..$801F.
What is the typical way to write to and read from memory? Are there existing Forth words, or will I need to write my own?

I may have figured it out

It looks like the following works. Is this the correct way to do this?
Code:
hex
FF 8012 !
1 8010 !

Thanks,
Shawn


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 26, 2020 6:17 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
Sure; but you'll want to give the addresses names that are meaningful to humans, typically with CONSTANTs. They take headers space (unless you're compiling headerless code), but if you use them enough, they'll pay for themselves, since reference to a constant takes only one cell versus a literal which takes two cells. The following is from my workbench computer's ROM Forth:

Code:
\ VIA1 is the base address of the first 6522 on the SBC.  Following are
\ the addresses of different registers in the 6522.  VIA1 is the only IC on NMI.

       6000     EQU VIA1        \ Base address of first 6522.
  VIA1 0 + CONSTANT VIA1PB      \ Port B
  VIA1 1 + CONSTANT VIA1PA      \ Port A
  VIA1 2 + CONSTANT VIA1DDRB    \ Data Direction Register for port B
  VIA1 3 + CONSTANT VIA1DDRA    \ Data Direction Register for port A
  VIA1 4 + CONSTANT VIA1T1CL    \ Timer 1 Counter Low byte
  VIA1 5 + CONSTANT VIA1T1CH    \ Timer 1 Counter High byte
  VIA1 6 + CONSTANT VIA1T1LL    \ Timer 1 Latch Low byte
  VIA1 7 + CONSTANT VIA1T1LH    \ Timer 1 Latch High byte
  VIA1 8 + CONSTANT VIA1T2CL    \ Timer 2 Counter Low byte
  VIA1 9 + CONSTANT VIA1T2CH    \ Timer 2 Counter High byte
  VIA1 A + CONSTANT VIA1SR      \ Shift Register
  VIA1 B + CONSTANT VIA1ACR     \ Auxiliary Control Register
  VIA1 C + CONSTANT VIA1PCR     \ Peripheral Control Register
  VIA1 D + CONSTANT VIA1IFR     \ Interrupt Flag Register
  VIA1 E + CONSTANT VIA1IER     \ Interrupt Enable Register
  VIA1 F + CONSTANT VIA1PANOHS  \ (same as VIA1PA, but no handshaking)

(and it continues with VIA2, VIA3, ACIA1, ACIA2, and ACIA3). The abbreviations are taken from the data sheet, so they should be easy to remember. My applications are always for technical I/O for workbench control, not human applications like finance; so it's standard for me to keep it in hex most of the time. Since [ HEX ] and [ BINARY ] and [ DECIMAL ] take so much room in colon definitions in the source code lines, I made the IMMEDIATE words [H] and [B] and [D} to take their place.

_________________
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 Oct 26, 2020 6:23 pm 
Offline

Joined: Fri Apr 15, 2016 1:03 am
Posts: 140
! is store a cell (2 bytes in Tali)
@ is fetch a cell (2 bytes in Tali)
c! is store a character (1 byte in Tali)
c@ is fetch a character (1 byte in Tali)

Look at the definitions of these words in the Tali source for more implementation detail.


Top
 Profile  
Reply with quote  
PostPosted: Mon Oct 26, 2020 8:55 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 255
Hi Shawn,
Congratulations on getting TaliForth running on your SBC!
It looks like you are on the right track and leepivonka's note is important - you'll want to use C@ and C! for accessing byte-wide registers. Here is some code I used to create an I2C bus on two of the pins (heavily influenced by Garth's notes on doing such a thing).
Code:
\ Set up the VIA for I2C.  I'm using the VIA DDR method.

\ PTA7 is data 
\ PTA0 is clock

hex
7F01 constant via.porta
7F03 constant via.ddra
\ Make port A an input so the bus starts idle.
: i2c-setup 0 via.porta c! 0 via.ddra c! ;

\ Data on PORTA7 (note that 0 = 1 on the I2C bus for writing)
\ : i2c-sda0 via.ddra c@ 80  or via.ddra c! ;  allow-native
\ : i2c-sda1 via.ddra c@ 7f and via.ddra c! ;  allow-native

In this code, I make bit 7 of PORTA a zero and then mess with the DDRA (Data Direction Register for port A) bit 7 to change it between an input and an output. This is a neat way to make an open collector signal without having to add a transistor (but you do need a pull-up resistor). The i2c-sda0 and i2c-sda1 words are commented out because I ended up rewriting them in assembly for speed, but you can see where I am reading the current value of the DDRA register (via.ddra c@) and either ANDing it with 0x7F (7f and) or ORing it with 0x80 (80 or) to change just bit 7, and then I write that value back to the DDRA register (via.ddra c!).

I also like Garth's method of declaring the base address and then computing the offsets to the internal registers. I've since started doing my code that way as it makes it much easier to port to a different machine later - you only have to adjust the first line. I don't believe Tali2 has EQU, so you'd just use CONSTANT for that first address as well.

Note that the . in the names of my constants doesn't do anything special - it's just for me to help me organize my constant names around what they go to.


Top
 Profile  
Reply with quote  
PostPosted: Sat Oct 31, 2020 12:23 am 
Offline
User avatar

Joined: Mon Mar 23, 2020 4:02 pm
Posts: 52
Location: Parker, CO
Thanks to everyone for their comments. They are very helpful.
I am reading "Starting FORTH", but haven't gotten too far yet.

Shawn


Top
 Profile  
Reply with quote  
PostPosted: Thu Nov 05, 2020 9:30 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 255
The best way to learn Forth is to use Forth, and Brodie's "Starting Forth" is a good place to start with all of its examples. You can run those examples on Tali Forth 2.

I think the biggest issue I had when starting out was just learning enough words to do useful things. Tali Forth 2's documentation is pretty good once you know a little bit of Forth, so you should work your way through that after you get through Starting Forth. You can go to the Glossary in the Appendix (in manual.pdf found in the TaliForth2/docs folder) to see quick usage information for all of the words that Tali2 supports. Most of Tali2's words are from the ANS 2012 standard, and you can find even more detail on what a word does by referencing https://forth-standard.org and I often use the magnifying glass at the top to search for words.

The good news is that you don't have to learn all the words at once, and once you start using Forth, you'll quickly learn the words most useful to you. My most used words are .S (see what is on the stack) and DUMP (see what is in memory) when I'm testing things out. The word that I always want to use and can never remember the name of is UNUSED (how many bytes of RAM left - and I just had to look it up again to write this), so don't feel bad if you can't remember a word you want to use and have to look it up.

If you get stuck, or just want to know how to approach something, feel free to let us know what you're trying to do and what you've tried so far, and we'll be happy to lend a hand. If you come up with a word you've created and want to know if that's the best way to do it, we can help with that too (although beware that different people might have different "best" answers :D , but they will all be interesting and informative). You are also encouraged to share your "aha!" moments, of which there will be many if you really start digging deep into what Forth can do.


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 06, 2020 1:13 pm 
Offline

Joined: Wed Jan 08, 2014 3:31 pm
Posts: 578
To teach myself Forth (or any computer language) I'll write a bunch of small programs for algorithms I am familiar with. You'll inevitably search for language mechanisms that solve common design problems. For example, building a generalized sort makes you learn about execution tokens which are the equivalent of C's function pointers. Similarly parsing is a common problem to solve.

I then recorded the results in my Forth CS-101 repo:
https://github.com/Martin-H1/Forth-CS-101


Top
 Profile  
Reply with quote  
PostPosted: Fri Nov 06, 2020 7:25 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8546
Location: Southern California
Martin_H wrote:
For example, building a generalized sort makes you learn about execution tokens which are the equivalent of C's function pointers.

One of the many, many things I like about Forth is that pointers of any kind are not any different from any other numbers. The absence of such typing in Forth makes it more flexible, and yet Forthers can always finish bug-free applications much faster than the C crowd can.

_________________
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  [ 8 posts ] 

All times are UTC


Who is online

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