@evanh said:
Good stuff Wuerfel_21. And quick. I'm sure Eric is happy there is someone else with the skills to help.
Very happy. Ada has contributed so much, not just in the obvious things she's added to flexspin, but also behind the scenes with bug reports, suggestions, and testing. She's really a great programmer!
@Rayman said:
Great to see floating point in Spin2!
Does Spin2 use up more of the cog memory now?
The Spin2 interpreter is now 4,784 bytes long, occupying $00000..$012AF. The floating-point instructions added a total of 554 bytes of code and data to the interpreter, increasing its size by 13%.
Wait, that must be HUB space, right? Is cog usage still the same?
@Rayman said:
Great to see floating point in Spin2!
Does Spin2 use up more of the cog memory now?
The Spin2 interpreter is now 4,784 bytes long, occupying $00000..$012AF. The floating-point instructions added a total of 554 bytes of code and data to the interpreter, increasing its size by 13%.
Wait, that must be HUB space, right? Is cog usage still the same?
Sorry, I didn't answer your actual question.
Cog RAM usage is exactly the same. No change there.
Hmm, just investigated converting the clock frequency calculations back into floats. But it doesn't really look any better unless all variables are converted back. Otherwise the code looks just as untidy with lots of float() and round() sprinkled around.
Really, muldiv65() does what is needed there. After all, the objective is to find the best set of integer components of clock-mode for a HUBSET instruction.
Ah, yeah, I'm not using the website. Using the "git pull" and "make" commands from shell instead. Eric has updated the master dev branch in the Git repository. One advantage of having a Linux box. These tools are just there, even if they're a mystery to work sometimes.
@evanh said:
Ah, yeah, I'm not using the website. Using the "git pull" and "make" commands from shell instead. Eric has updated the master dev branch in the Git repository. One advantage of having a Linux box. These tools are just there, even if they're a mystery to work sometimes.
I have several raspberries to try this.
Edit: fresh build on rpi400 doesn't understand new operators. "Unexpected ."
@cgracey : I've found a few bugs in the Spin2 floating point routines. There are a few general categories:
(1) Rounding errors: IEEE 32 says results should be rounded to the nearest even bit pattern. I think Spin2 may always be rounding up.
(2) Overflow errors: Many operations which should give infinite results give NaN patterns (but not always the "official" NaN)
(3) Negative zero: there are a few cases where $8000_0000 needs to be treated specially.
I've attached a .zip file with the test program I used to generate these.
Rounding errors: IEEE 32 says results should be rounded to the nearest even bit pattern
Gee, never tried to consider that level of specificity myself. I'm guessing there is some particular method that produces that as a natural outcome ...
And another oddity: NaN ==. NaN is returning FALSE (as it should), but NaN <>. NaN is also returning FALSE. I'm not sure if this is a bug, exactly, but in most other languages I've seen NaN <>. NaN would return TRUE, just like !(NaN ==. NaN).
~~EDITED: Whoops! It turns out that NaN <>. NaN should be false, according to the spec, so this is a case where Spin2 is doing the right thing, and gcc is not.~~
EDITED further: I should have gone back to the actual standard rather than relying on web pages. The IEEE spec is very careful in specifying that any comparison involving NaN should return unordered, which is distinct from equal (and hence x "not equal" x should be TRUE if x is NaN).
Rounding errors: IEEE 32 says results should be rounded to the nearest even bit pattern
Gee, never tried to consider that level of specificity myself. I'm guessing there is some particular method that produces that as a natural outcome ...
No, it's just that if you have a value like say 1.5 that's exactly half way between integers, then there's no unique "nearest" value to round to. Always rounding up results in a small bias away from 0. This can matter a lot in scientific and financial applications. For an integer example, if you have inputs that are exactly 1.5 and 2.5 and you round up then you get 2 and 3 (the sum is 5), whereas if you round to nearest even you get 2 and 2 ( the sum is 4, the same as the sum of the original inputs). This special rounding only needs to happen if the input is exactly half way between possible outputs of the rounding; otherwise, of course, you round to the nearest number.
What I've been doing previously is adding 50% of the divisor to the dividend before division. But the means by which I get 50% is simple truncation (SHR #1) ...
I think SHR #2 then SHL #1 would work. In other words clear the lsb of the 50% divisor. Nope failed. Best I got is: ((dividend + (divisor>>1) - 1) | 1) / divisor grr, that fails too. Maybe this time: First copy dividend bit1 to bit0, then (dividend + divisor>>1) / divisor damn it! Way past bed time.
I figure Chip's original muldiv64(), including two IRQ shields, should take 124 sysclock ticks. In reality it takes more because of skipping and other overheads. But, for comparison, I'll use 124 ticks.
I've got the mouse feedback working in DEBUG. This should be pretty self-explanatory if you look at the code.
I had to slow the screen capture way down to make a sufficiently-small gif file, but this is reading almost 250 mouse positions per second, since I set the USB serial driver latency to 4ms.
For some reason, my screen-capture program is dragging a huge inverse box around with the cursor. Try to ignore that.
The way this works is you pass GETMOUSE a pointer to a 4-long record (either in Spin2 or PASM regs). It puts the mouse's x position, y position, left button, and right button into the four longs. If the cursor is outside of the PLOT window, then x = -1, y = -1, left = 0, right = 0. If the mouse cursor is in the window, it will return properly scaled and oriented coordinates and each button will read -1 if pressed or 0 if not pressed.
I've got the mouse feedback working in DEBUG. This should be pretty self-explanatory if you look at the code.
I had to slow the screen capture way down to make a sufficiently-small gif file, but this is reading almost 250 mouse positions per second, since I set the USB serial driver latency to 4ms.
For some reason, my screen-capture program is dragging a huge inverse box around with the cursor. Try to ignore that.
The way this works is you pass GETMOUSE a pointer to a 4-long record (either in Spin2 or PASM regs). It puts the mouse's x position, y position, left button, and right button into the four longs. If the cursor is outside of the PLOT window, then x = -1, y = -1, left = 0, right = 0. If the mouse cursor is in the window, it will return properly scaled and oriented coordinates and each button will read -1 if pressed or 0 if not pressed.
@cgracey Mouse feedback in debug is fantastic!!! This allows for a user interface... buttons and sliders and... You should start a new thread so people know about this... When will you release a new pnut with this feature? I imagine it will be a while before it makes it to propeller tool...
Comments
Very happy. Ada has contributed so much, not just in the obvious things she's added to flexspin, but also behind the scenes with bug reports, suggestions, and testing. She's really a great programmer!
Wait, that must be HUB space, right? Is cog usage still the same?
Sorry, I didn't answer your actual question.
Cog RAM usage is exactly the same. No change there.
They're in github now.
Cool! floating_point_demo.spin2 now works with flexspin.
Hmm, just investigated converting the clock frequency calculations back into floats. But it doesn't really look any better unless all variables are converted back. Otherwise the code looks just as untidy with lots of float() and round() sprinkled around.
Really, muldiv65() does what is needed there. After all, the objective is to find the best set of integer components of clock-mode for a HUBSET instruction.
What I can see now on Github is the commit from 10 days ago (2021.09.15) without any floating point debug/operators
Ah, yeah, I'm not using the website. Using the "git pull" and "make" commands from shell instead. Eric has updated the master dev branch in the Git repository. One advantage of having a Linux box. These tools are just there, even if they're a mystery to work sometimes.
I have several raspberries to try this.
Edit: fresh build on rpi400 doesn't understand new operators. "Unexpected ."
Is that the make? Or is that a flexspin error?
Do a
make clean
and make it again. And make sure you're actually using the fresh build of flexspin.I did git pull, make, all went ok and I have a working flexprop on my RPi400. It says it is 5.9.2
However if I tried
c:= a /. b
it told me "unexpected ." while trying to compile this for a P2
It may not be part of flexprop. Did you build flexspin alone?
git clone https://github.com/totalspectrum/spin2cpp
Or you can download the zip from the website and unzip then
git pull
andmake
from that.Yeah, that'll be it. My flexspin version string is
Version 5.9.3-beta-v5.9.2-21-gd463d1ea Compiled on: Sep 25 2021
Sorry, I had only updated spin2cpp, not flexprop. Try again now (and if you're still having trouble do a "make clean" before "make install").
Now it is 5.9.3 and it compiled /.
@cgracey : I've found a few bugs in the Spin2 floating point routines. There are a few general categories:
(1) Rounding errors: IEEE 32 says results should be rounded to the nearest even bit pattern. I think Spin2 may always be rounding up.
(2) Overflow errors: Many operations which should give infinite results give NaN patterns (but not always the "official" NaN)
(3) Negative zero: there are a few cases where $8000_0000 needs to be treated specially.
I've attached a .zip file with the test program I used to generate these.
Gee, never tried to consider that level of specificity myself. I'm guessing there is some particular method that produces that as a natural outcome ...
Oh, and another (minor) bug: DEBUG(fdec(x)) is printing "3.402824e+38" instead of "Inf" for $7f80_0000.
And another oddity: NaN ==. NaN is returning FALSE (as it should), but NaN <>. NaN is also returning FALSE. I'm not sure if this is a bug, exactly, but in most other languages I've seen NaN <>. NaN would return TRUE, just like !(NaN ==. NaN).
~~EDITED: Whoops! It turns out that NaN <>. NaN should be false, according to the spec, so this is a case where Spin2 is doing the right thing, and gcc is not.~~
EDITED further: I should have gone back to the actual standard rather than relying on web pages. The IEEE spec is very careful in specifying that any comparison involving NaN should return unordered, which is distinct from equal (and hence x "not equal" x should be TRUE if x is NaN).
No, it's just that if you have a value like say 1.5 that's exactly half way between integers, then there's no unique "nearest" value to round to. Always rounding up results in a small bias away from 0. This can matter a lot in scientific and financial applications. For an integer example, if you have inputs that are exactly 1.5 and 2.5 and you round up then you get 2 and 3 (the sum is 5), whereas if you round to nearest even you get 2 and 2 ( the sum is 4, the same as the sum of the original inputs). This special rounding only needs to happen if the input is exactly half way between possible outputs of the rounding; otherwise, of course, you round to the nearest number.
(deleted)
Okay, got it.
What I've been doing previously is adding 50% of the divisor to the dividend before division. But the means by which I get 50% is simple truncation (SHR #1) ...
I think SHR #2 then SHL #1 would work. In other words clear the lsb of the 50% divisor. Nope failed.
Best I got is: ((dividend + (divisor>>1) - 1) | 1) / divisor grr, that fails too.
Maybe this time: First copy dividend bit1 to bit0, then (dividend + divisor>>1) / divisor damn it! Way past bed time.
Right, I've cheated and used the Cordic's pipeline to give me both results at once.
EDIT: Belatedly attached some rounding test results.
Here's the muldiv65() version:
I figure Chip's original muldiv64(), including two IRQ shields, should take 124 sysclock ticks. In reality it takes more because of skipping and other overheads. But, for comparison, I'll use 124 ticks.
My extended muldiv65() comes to 132 ticks. An extra 8 ticks between the QMUL and QDIV.
And finally, muldiv65ieee() comes to 142 ticks.
All versions additionally have variability of up to +7 more for hub-op alignment.
I just posted a new version 35q at the top of this thread.
The main symbol table was increased from 64KB to 256KB. Others went from 4KB to 32KB.
https://drive.google.com/file/d/1Op4YOyFIul-7-UhRq7Cdv-OfGx5afb5M/view?usp=sharing
I've got the mouse feedback working in DEBUG. This should be pretty self-explanatory if you look at the code.
I had to slow the screen capture way down to make a sufficiently-small gif file, but this is reading almost 250 mouse positions per second, since I set the USB serial driver latency to 4ms.
For some reason, my screen-capture program is dragging a huge inverse box around with the cursor. Try to ignore that.
The way this works is you pass GETMOUSE a pointer to a 4-long record (either in Spin2 or PASM regs). It puts the mouse's x position, y position, left button, and right button into the four longs. If the cursor is outside of the PLOT window, then x = -1, y = -1, left = 0, right = 0. If the mouse cursor is in the window, it will return properly scaled and oriented coordinates and each button will read -1 if pressed or 0 if not pressed.
Great work Chip. This looks promising...
@cgracey Mouse feedback in debug is fantastic!!! This allows for a user interface... buttons and sliders and... You should start a new thread so people know about this... When will you release a new pnut with this feature? I imagine it will be a while before it makes it to propeller tool...