6502.org Forum  Projects  Code  Documents  Tools  Forum
It is currently Sat Apr 27, 2024 5:06 pm

All times are UTC




Post new topic Reply to topic  [ 264 posts ]  Go to page Previous  1 ... 13, 14, 15, 16, 17, 18  Next
Author Message
PostPosted: Fri Dec 02, 2022 9:28 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 247
Standard numbers in Tali are 16-bit so -32768 to +32767. If you use words like U. (u is for unsigned) to print the numbers, those same 16-bits can represent 0-65535 instead. There are other "unsigned" words like U< and U> to operate on unsigned values.

"Double" numbers in Tali use two 16-bit cells on the stack to make up a 32-bit number. This allows numbers from around -2.1 billion to +2.1 billion. You can deal with the halves as separate 16-bit values (most significant half is on top of stack) or use words like D. to print them and D+ to add them. To enter a double number, put a period after the last digit, eg: 1234567890.

Tali doesn't have the full double word set, but it has enough that all the "missing" words can be created if you need them. Here are some that I made while playing with FAT32 - some are ANS 2012 standard and some are just words I needed. In the stack comments, d = double, ud = unsigned double, n is a normal (signed 16-bit) number, u is an unsigned (16-bit) value, and f is a flag (true/false).
Code:
\ Tali2 needs some extra double words.
: d=  ( d1 d2 -- f )
   rot = -rot = and ;
: d0=   ( d -- f ) 0= swap 0= and ;
: d0<>  ( d -- f ) or ;
: d2*   ( d -- f ) 2dup d+ ;
: d<    ( d -- f ) rot 2dup = if ( use LSBs ) 2drop <
   else ( use MSBs ) 2swap 2drop > then ;

: d0!  ( addr -- )  ( store double 0 at address )
   0. rot 2! ; allow-native
: d+!  ( d1 addr -- )  ( Add d1 to double at addr )
   dup >r 2@ d+ r> 2! ;
: d1+!  ( addr -- )  ( Add 1 to double at addr )
   1. rot d+! ;
There's also unsigned double words, like UD. that would print an unsigned double (values 0 to about +4.2 billion). Note that Forth expects the programmer to keep track of whether single or double values are on the stack and to use the appropriate words for them.

There are also 2CONSTANT and 2VARIABLE for constants and variables, 2DUP and 2DROP etc to manipulate them on the stack, etc. Most words that start with 2 (except 2* and 2/) work with double values. It's a bit unfortunate that some of the words start with 2 and others start with D, but that's how it is. You'll sometimes see the words used even with non-double values on the stack because (for example) 2DROP drops two items off the stack - it doesn't care if that was both halves of a double or two unrelated values.

Words that start with M are usually for "mixed" calculations, where one side is double and the other is not, eg M* (single value times a single value with a double result) and I bet you can figure out what UM* does now.

https://forth-standard.org, if you haven't found it already, will be very handy for reference as it covers the ANS 2012 Forth standard and I use the search function at the top all the time. The gotcha is that you kinda need to know the name of the word you want to know more about.


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

Joined: Sun May 13, 2018 5:49 pm
Posts: 247
Snippets of example code using doubles:
Code:
2variable sector# \ The disk sector currently in the buffer

\ Read sector (given as double) into sectorbuff.
: sector>buffer  ( sector#.d -- )
   ( See if we already have it in the buffer )
   2dup sector# 2@ d= if
      2drop exit ( already have this sector ) then
   2dup sector# 2! ( Remember this sector )
   sectorbuff -rot 1 -rot cf.read ( Read the sector ) ;

: 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. ;


Top
 Profile  
Reply with quote  
PostPosted: Fri Dec 02, 2022 9:51 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
Thank you both (leepivonka & Garth). I know about the scalar operators. but not about the floating point routines Garth, though they would be interesting to play with. I'm not convinced one would ever NEED floating point since scaled integer, as you say, can do pretty well anything floating point can do but it just needs more thinking about. I guess I need to think a little more about my current problem. I got an M24M02 eeprom today and replaced my smaller 24 chip. It works but the calculation of the addresses into it is overflowing and I need to rework the routines. I guess my question was more with thought for the future - whether there is a generalised way to deal with multi-cell arithmetic in Tali - ie. can an integer be held in 2 or more cells (obviously it can) and I was wondering out loud (without being too specific [I must stop doing that]) whether there are any boilerplate routines out there to work on these hypothetical multi-cell integers.
.
.
I notice while typing this that SamCoVT has also replied... (twice!)
...and has completely resolved my problem.

Thank you once again Sam.


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

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
adrianhudson wrote:
whether there is a generalised way to deal with multi-cell arithmetic in Tali - ie. can an integer be held in 2 or more cells (obviously it can) and I was wondering out loud (without being too specific [I must stop doing that]) whether there are any boilerplate routines out there to work on these hypothetical multi-cell integers.
.
.
I notice while typing this that SamCoVT has also replied... (twice!)
...and has completely resolved my problem.

I feel a bit out of place here since I'm not familiar with Tali specifically; but the double-precision material Sam presents has been standard Forth stuff for many decades, meaning it will be portable to other Forths as well.  I don't know how standard the triple- and quad-precision words I mentioned earlier might be.  There are UT*, UT/MOD, M*/MOD, Q/, D*/, Q+, Q!, Q@, Q2/, Q<, and others.

Quote:
To enter a double number, put a period after the last digit, eg: 1234567890.

The period can be anywhere, and variable DPL keeps track of how many digits were found to the right of the right-most decimal point in NUMBER? .  ANS might not use DPL.  I've had a little trouble figuring out how ANS handles the entry of double literals.  Sometimes I use the decimal point just for readability when I want for example 3.45 volts, where I don't really even need doubles, and I just reduce it to a single (just use DROP to do that) before using it.

Sam, please remind me of what "SamCoVT" stands for.  In my mind, I always say "Sam Covington;" but I know that's not right.

_________________
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: Fri Dec 02, 2022 11:33 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
GARTHWILSON wrote:
I feel a bit out of place here since I'm not familiar with Tali specifically;

Thanks Garth.
What Forth do you use Garth? I've often wondered but much as I keep an eye out for you mentioning it as I read your primers and posts I have never spotted it.


Top
 Profile  
Reply with quote  
PostPosted: Sat Dec 03, 2022 12:10 am 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
adrianhudson wrote:
GARTHWILSON wrote:
I feel a bit out of place here since I'm not familiar with Tali specifically;

Thanks Garth.
What Forth do you use Garth? I've often wondered but much as I keep an eye out for you mentioning it as I read your primers and posts I have never spotted it.

See viewtopic.php?p=96847#p96847 .

_________________
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 Dec 04, 2022 11:09 am 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
SamCoVT, I'm getting on famously with Forth. Have implemented access of LCD and access if i2c devices. One thing that irritates is if you get it in a loop or other crash. The only way out is a reset button press. Is there any way Tali can be made to return to its internal main loop using NMI without reinitialising all its memory?
Edit: I guess what I am asking is, is there a warm restart point in the code?


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 04, 2022 5:22 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 247
GARTHWILSON wrote:
Quote:
To enter a double number, put a period after the last digit, eg: 1234567890.

The period can be anywhere, and variable DPL keeps track of how many digits were found to the right of the right-most decimal point in NUMBER? . ANS might not use DPL.

Since at least ANS94, the standard says the period goes on the end of the number, and I believe that's all Tali supports for entering double numbers (a quick test shows that Tali can only handle the . at the end). This may be to make it so it is distinct from floating point numbers, which some Forths support (but Tali does not - unless you add it yourself, of course). I did see DPL when playing with FIG-Forth, but apparently that was lost in the ANS standardization. I don't see it mentioned in the FORTH-83 standard at all, but I also don't see the . in numbers mentioned either.

Tali also supports base prefixes, which showed up in the 2012 ANS standard, so you can say (regardless of the current BASE):
Code:
#123 \ 123 in decimal
$-123 \ -123 in hex
%101 \ 101 in binary
$12345678. \ a double in hex

GARTHWILSON wrote:
Sam, please remind me of what "SamCoVT" stands for. In my mind, I always say "Sam Covington;" but I know that's not right.[/color]
SamCo is a nickname I picked up in college because I was always building things. VT is because there are other SamCo's out there and I live in Vermont.


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 04, 2022 5:25 pm 
Offline

Joined: Fri Apr 15, 2016 1:03 am
Posts: 135
Your NMI handler could re-enable interrupts then jmp to ABORT .


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 04, 2022 5:36 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 247
adrianhudson wrote:
One thing that irritates is if you get it in a loop or other crash. The only way out is a reset button press. Is there any way Tali can be made to return to its internal main loop using NMI without reinitialising all its memory?
Edit: I guess what I am asking is, is there a warm restart point in the code?
(leepivonka beat me to it but has an important extra piece of info - you need to re-enable interrupts) You could put the address for xt_abort in the NMI handler vector, I think. the ABORT word clears the data stack, clears the return stack, sets the input to the keyboard (serial port in your case), clears the input buffer, and goes into interpret mode so it will accept a new line and interpret it. The stacks will be gone, but any variables will be left alone, new words will still be in the dictionary, and your hardware should be where you left it because it won't have been reset (if it accepts the RESB signal).

At the end of your platform file, you will find the interrupt vectors. v_nmi is currently another name for kernel_init. You can change it to your own handler that re-enables interrupts and jumps to xt_abort. I haven't done this myself, so I'm not 100% sure this is a good solution, but I think it should work. NMI is falling edge triggered. Note that you won't get a new prompt (eg. cursor will be left wherever it is), but if you hit ENTER should should get the standard "ok".


Top
 Profile  
Reply with quote  
PostPosted: Sun Dec 04, 2022 6:04 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
Thank you both. I changed the platform file from
Code:
v_nmi:
v_reset:
;v_irq: ; IRQ redirected to SERVICE_ACIA
kernel_init:

to
Code:
v_nmi:
      pla
      pla
      pla
      cli
      jmp xt_abort
v_reset:
;v_irq: ; IRQ redirected to SERVICE_ACIA
kernel_init:

...which seems to work. Fantastic! Even if it doen't work under all conditions (which I have yet to determine), it is better than nothing.


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 05, 2022 4:45 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 247
adrianhudson wrote:
Code:
v_nmi:
      pla
      pla
      pla
      cli
      jmp xt_abort
v_reset:
;v_irq: ; IRQ redirected to SERVICE_ACIA
kernel_init:
Just FYI, you don't need to bother with the pla instructions, as xt_abort resets the return stack (along with the data stack). It's designed so that you can abort from the middle of a loop in a loop in a loop or deeply nested words and it will reset everything to base levels and go back to interpreting.


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 05, 2022 5:02 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
Oh, thanks for that, will change it...
It works very reliably. It's useful as I am messing with a permanently running app (just a clock reading from as ds3231). (What I really want is a background Forth task. I read somewhere that some Forths have that).


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 05, 2022 8:06 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 247
Some Forths support tasking. Tasking was on Scot's wishlist for Tali Forth 2. Some of the work has been started to support it (moving things to user variables accessed via a base "user pointer") but it's likely that more would have to be moved around to be ready for full tasking support. You can read about our musings on it here: https://github.com/scotws/TaliForth2/issues/234

If you wanted to do an interrupt based background task (based on one of your 65C22 timers, for example), you should be able to do that, but would need to take extra care. You would need to save/restore A and Y (X is used for the data stack and you could use it if you made sure it was at the same value when done), and you'd likely also need to save/restore tmp1, tmp2, and tmp3, which are locations in zero page (two bytes each) used to hold data temporarily; they are used by many words who expect they are the only one using them. You can find their definitions in definitions.asm. To find their exact locations, you'll need to know where user0 is (they are defined as offsets from that address) and that's in your platform file. user0 is usually address 0 in zero page, but Tali lets you move the entire block of variables in zero page by changing user0 in your platform file.

If that's the kind of rabbit hole you'd like to go down, I'd be interested in what you find. You're welcome to start a new thread to chronicle your adventures/progress and report what does (and doesn't) work.


Top
 Profile  
Reply with quote  
PostPosted: Mon Dec 05, 2022 10:46 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
SamCoVT wrote:
If you wanted to do an interrupt based background task (based on one of your 65C22 timers, for example)
Umm, forth or assembler? I doubt I am up to coding an interrupt routing in forth yet!

While I am here, can I ask: I have been coding away in Forth and pasting the code into my terminal program. Eventually Tali crashes. On investigation I suspect the dictionary grows with old versions of words as I edit/test/edit/test until Tali crashes. Is this your expectation or is there something else going on do you think? Do all Forths just grow or do some have housekeeping? I guess that would be non-trivial.


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

All times are UTC


Who is online

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