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

All times are UTC




Post new topic Reply to topic  [ 264 posts ]  Go to page Previous  1 ... 14, 15, 16, 17, 18
Author Message
PostPosted: Sat Dec 31, 2022 11:06 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
Fantastic! Thanks for making this change, it makes the disassembler much more useful

( I have to say I am really impressed by Forth in general. It's fast and compact.)


Top
 Profile  
Reply with quote  
PostPosted: Sun Jan 01, 2023 4:09 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 247
TLDR Version: I've updated the assembler further with string literal support so it doesn't try to disassemble the string data anymore.

VILR (Very Interesting... Let's Read!) Version: Tali inlines string data by compiling a jump over the string data, then a call to the string literal runtime handler, and then two cells that contain the address and length of the string:
Code:
 Strings are compiled into the dictionary like so:
           jmp a
           <string data bytes>
  a -->    jsr sliteral_runtime
           <string address>
           <string length>
Tali used to try to disassemble the string data after the jump and would sometimes gack on it. To fix this, I needed to recognize the JMP/JSR sliteral_runtime pattern. When the assembler encounters a JMP instruction, it peeks ahead at the jump destination to see if the 3 bytes there are the JSR sliteral_runtime instruction. If it matches, it adjusts the current disassembly location to skip over the string data and continue at the jsr. There is then a special handler for JSR sliteral_runtime that prints the following string address and length and skips over those as well.

I thought about printing the string data, but Tali supports very long strings and they are shown in the memory dump when using SEE, so the address and length should be good enough in the disassembly. Here is an example of the new behavior, including typing in the address and length and TYPEing one of the strings.
Code:
: teststrings s" This is a string literal" 2drop ." This is a printed string" ;  ok
see teststrings
nt: 800  xt: 813
flags (CO AN IM NN UF HC): 0 0 0 1 0 1
size (decimal): 78

0813  4C 2E 08 54 68 69 73 20  69 73 20 61 20 73 74 72  L..This  is a str
0823  69 6E 67 20 6C 69 74 65  72 61 6C 20 8A A0 16 08  ing lite ral ....
0833  18 00 20 D5 D7 E8 E8 E8  E8 4C 57 08 54 68 69 73  .. ..... .LW.This
0843  20 69 73 20 61 20 70 72  69 6E 74 65 64 20 73 74   is a pr inted st
0853  72 69 6E 67 20 8A A0 3F  08 18 00 20 DE A4  ring ..? ... ..

813    82E jmp
82E   A08A jsr     SLITERAL 816 18
835   D7D5 jsr     STACK DEPTH CHECK
838        inx
839        inx
83A        inx
83B        inx
83C    857 jmp
857   A08A jsr     SLITERAL 83F 18
85E   A4DE jsr     type
 ok
$816 $18 type This is a string literal ok
The 2DROP got inlined as the stack depth check and the INX instructions.


Top
 Profile  
Reply with quote  
PostPosted: Tue Jan 03, 2023 3:13 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
SamCoVT wrote:
Note that SEE changes the base to hex


Although I have RB to restore BASE for those words where I need to change it, I've followed advice given by Charles Moore and don't change BASE in my tools. If I want HEX output from SEE , or DUMP , I'll set BASE to HEX first.


Top
 Profile  
Reply with quote  
PostPosted: Wed Mar 15, 2023 3:36 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
Hello all.
I am struggling with some relatively simple math (maths in the UK :-) ).

I have a 16 bit number returned from a thermometer (sht31 if anyone is interested). It has to be converted using this formula
temperature = 175 * (rawtemp / 65535) - 45
I have come up with the following (which works - sort of - see below) Values are in hex.

: convertT ( rT -- T)
445C ( 17500 decimal )
m*
swap drop
1198 - (4500 decimal)
;
This gives results like (in decimal) 1950 for 19.50 degrees C - which is fine. This code is in effect doing the following:

temperature = (rawtemp ** 17500) - 4500 where ** is a 32 bit result with the lower 16 bits thrown away to act as as a division by 65536 (which is not 65535 but close!).

My problem is this:
The thermometer can give raw values of any magnitude ~$0000 to ~$FFFF (corresponding to ~-45C up to ~120C. The forth code above fails at input of $8000 and above, which is obviously to do with the sign of the number throwing the m*.

An unsigned m* - Um* would probably do the trick but Taliforth doesnt have such a thing.

Can anyone (better at Forth than me - which is almost anyone) help me please.


Top
 Profile  
Reply with quote  
PostPosted: Wed Mar 15, 2023 8:46 pm 
Offline
User avatar

Joined: Fri Aug 30, 2002 1:09 am
Posts: 8428
Location: Southern California
Are you sure?  I think that in most Forths, M* is a secondary that uses the UM* primitive in its definition.

BTW, SWAP DROP can be shortened to NIP.

I might write:
Code:
: convertT ( rT -- T)  [ DECIMAL ]
   17500  UM*  NIP
    4500   -           [   HEX   ]       ;

Let us know how it works out.  The only thing I've done for temperature is an LM335 circuit run into my A/D converter.  I've never measured humidity.

_________________
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: Wed Mar 15, 2023 9:18 pm 
Offline

Joined: Sat Apr 30, 2022 7:13 pm
Posts: 159
Location: Devon. UK
oops. You are right, there is a UM* ~blush~

Works perfectly now. Why I decided there was no um* I don't know.

Thanks for the NIP!


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 28, 2023 12:46 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851
Does Tali Forth still inline DO LOOPs?


Top
 Profile  
Reply with quote  
PostPosted: Tue Mar 28, 2023 5:55 pm 
Offline

Joined: Sun May 13, 2018 5:49 pm
Posts: 247
JimBoyd wrote:
Does Tali Forth still inline DO LOOPs?
It does, and those words have special treatment so that they are always native compiled (inlined) when used, even if native compiling has been disabled by the user. It's a bit of a bear at 70 bytes for the two words, and it's not fast either. Druzyek and leepivonka have both done some investigating into the speed (or lack thereof) of Tali's DO LOOPs and I also investigated using an 8-bit index (which results in loops that take about 1/4 of the time or 1/2 the time if using I in them) here. I haven't personally run into an issue with speed, so I haven't spent too much time focusing on the issues involved in making it better. Here is an example of all of the overhead of doing a DO LOOP. Anyone trying to follow the assembly needs to the know that the ending value, and the "index", is subtracted from $8000 (this is sometimes called "fudge-factoring" the index) so that the oVerflow flag can be used to detect when to end the loop.[size=115]
Code:
: test do loop ;  ok
see test
nt: 800  xt: 80C
flags (CO AN IM NN UF HC): 0 0 0 1 0 1
size (decimal): 70

080C  A9 08 48 A9 51 48 38 A9  00 F5 02 95 02 A9 80 F5  ..H.QH8. ........
081C  03 95 03 48 B5 02 48 18  B5 00 75 02 95 00 B5 01  ...H..H. ..u.....
082C  75 03 48 B5 00 48 E8 E8  E8 E8 20 E9 97 18 68 75  u.H..H.. .. ...hu
083C  00 A8 B8 68 75 01 48 98  48 E8 E8 70 03 4C 36 08  ...hu.H. H..p.L6.
084C  68 68 68 68 68 68  hhhhhh

80C      8 lda.#
80E        pha
80F     51 lda.#
811        pha
812        sec
813      0 lda.#
815      2 sbc.zx
817      2 sta.zx
819     80 lda.#
81B      3 sbc.zx
81D      3 sta.zx
81F        pha
820      2 lda.zx
822        pha
823        clc
824      0 lda.zx
826      2 adc.zx
828      0 sta.zx
82A      1 lda.zx
82C      3 adc.zx
82E        pha
82F      0 lda.zx
831        pha
832        inx
833        inx
834        inx
835        inx
836   97E9 jsr     1
839        clc
83A        pla
83B      0 adc.zx
83D        tay
83E        clv
83F        pla
840      1 adc.zx
842        pha
843        tya
844        pha
845        inx
846        inx
847      3 bvs
849    836 jmp
84C        pla
84D        pla
84E        pla
84F        pla
850        pla
851        pla
 ok


Top
 Profile  
Reply with quote  
PostPosted: Thu Apr 06, 2023 1:02 am 
Offline

Joined: Fri May 05, 2017 9:27 pm
Posts: 851

Fleet Forth's DO LOOP's also use the $8000 "fudge factor" so they end when an overflow is detected.
I asked about the inlining because I've been working on some ideas for an STC version of Fleet Forth and have versions of the DO LOOP words which do not get inlined. The added overhead for (DO) and (?DO) would be minimal since they only run once per loop. I also think the added overhead for (LOOP) and (+LOOP) would also be minimal, thanks to a suggestion from leepivonka.
Another benefit, there is a separate (LOOP) primitive compiled by LOOP .
STC versions of Fleet Forth's DO LOOP's.
The use of SUBR (subroutine) was so I could test these words with the current version of Fleet Forth, an ITC Forth.
I realize you may not want to change Tali Forth's DO LOOP's. If it's not broken, don't fix it; however, it might be worth trying if you have a really big application with lots of DO LOOP's and find memory getting a little tight.


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

All times are UTC


Who is online

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