English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 11 July 2017, 19:55   #1
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Integers vs floats (FFP/Sing/Doub) + printf()

I'm trying to output some samples of a function (a Sine, eg) to the console. Here's the pseudo C# code of what I want to achieve:
Code:
using math;
using console;
int nrSamples = 256;
 
float deltaAngle = 2.0 * math.PI / ((float) nrSamples);
float currAngle, currSine;
 
for(int iSample = 0; iSample < nrSamples; iSample++)
{
 currAngle = deltaAngle * ((float) iSample;
 currSine = math.Sin(currAngle)
 
 console.printf("%f : %f", currAngle, currSine);
}
I might extend and redirect the output of this.

This involves using the math.library, which I'll probably be able to open. I'll hopefully also be able to turn my (integer) variables into the appropriate (floating) format (FFP/Sing/Doub) (using IEEESPFix() and IEEESPFlt()), so that I can call IEEESPSin() on them. I also know how to write a string to the console (using jsr _LVOWrite(_DOSBase)).

So my (first) question is how to format those numbers (integer or float) to a formatted string for display on the console. I think I saw some library on aminet somewhere doing just that (using a C-like format string), but I can't seem to find it now.

TIA!
guy lateur is offline  
Old 11 July 2017, 21:59   #2
thomas
Registered User
 
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 6,985
I would avoid to fiddle around with floating point numbers in assembler. I would rather use a C program (or any other high level language) to print a sine table of integers which can then be used in my asm program.

For example to draw a clock hand at any required angle it is sufficient to have a sine table consisting of 60 integers between -1000 and 1000.
thomas is offline  
Old 12 July 2017, 19:17   #3
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by thomas View Post
I would avoid to fiddle around with floating point numbers in assembler. I would rather use a C program (or any other high level language) to print a sine table of integers which can then be used in my asm program.

For example to draw a clock hand at any required angle it is sufficient to have a sine table consisting of 60 integers between -1000 and 1000.
Really, you don't use floating points at all? I mean, I can understand what you're saying about precalculating sine tables and such, but isn't it a bit constraining to not have floating calculations at all? Eg, I'd hoped to be able to write some custom functions, which I preferably could manipulate and evaluate in real time. I could probably write those all out using integer arithmetic and/or tables, but this feels unintuitive and annoying, to say the least.

Maybe there are some libs around that take the hassle out of it? Remember, I'm a total newbie, trying to make it as easy on myself as humanly possible. Heck, I should probably just leave assembler altogether and start from C..
guy lateur is offline  
Old 12 July 2017, 20:43   #4
thomas
Registered User
 
thomas's Avatar
 
Join Date: Jan 2002
Location: Germany
Posts: 6,985
Quote:
Originally Posted by guy lateur View Post
but this feels unintuitive and annoying
Well, assembler as a whole is unintuitive and annoying. You choose assembler if you need to optimize your code down to a certain number of CPU cycles or so. But it's surely not the language of choice for coding an application.

Quote:
Heck, I should probably just leave assembler altogether and start from C..
Given that you are already using C-like syntax for your pseudo code this would most likely be the easiest exercise.

Your code above can easily be turned into C with very little changes:

Code:
#include <math.h>
#include <stdio.h>

int main (void)
{

	int nrSamples = 256;
 
	float deltaAngle = 2.0 * M_PI / ((float) nrSamples);
	float currAngle, currSine;

	int iSample;
 
	for (iSample = 0; iSample < nrSamples; iSample++)
	{
		currAngle = deltaAngle * ((float) iSample);
		currSine = sin(currAngle);
 
		printf("%3d : %f : %f\n", iSample, currAngle, currSine);
	}


	return (0);
}

Output:

Code:
  0 : 0.000000 : 0.000000
  1 : 0.024544 : 0.024541
  2 : 0.049087 : 0.049068
  3 : 0.073631 : 0.073565
  4 : 0.098175 : 0.098017
  5 : 0.122718 : 0.122411
  6 : 0.147262 : 0.146730
  7 : 0.171806 : 0.170962
  8 : 0.196350 : 0.195090
  9 : 0.220893 : 0.219101
 10 : 0.245437 : 0.242980
 11 : 0.269981 : 0.266713
 12 : 0.294524 : 0.290285
 13 : 0.319068 : 0.313682
 14 : 0.343612 : 0.336890
 15 : 0.368155 : 0.359895
 16 : 0.392699 : 0.382683
 17 : 0.417243 : 0.405241
 18 : 0.441786 : 0.427555
 19 : 0.466330 : 0.449611
 20 : 0.490874 : 0.471397
 21 : 0.515418 : 0.492898
 22 : 0.539961 : 0.514103
 23 : 0.564505 : 0.534998
 24 : 0.589049 : 0.555570
 25 : 0.613592 : 0.575808
 26 : 0.638136 : 0.595699
 27 : 0.662680 : 0.615232
 28 : 0.687223 : 0.634393
 29 : 0.711767 : 0.653173
 30 : 0.736311 : 0.671559
 31 : 0.760854 : 0.689541
 32 : 0.785398 : 0.707107
 33 : 0.809942 : 0.724247
 34 : 0.834486 : 0.740951
 35 : 0.859029 : 0.757209
 36 : 0.883573 : 0.773010
 37 : 0.908117 : 0.788346
 38 : 0.932660 : 0.803207
 39 : 0.957204 : 0.817585
 40 : 0.981748 : 0.831470
 41 : 1.006291 : 0.844854
 42 : 1.030835 : 0.857729
 43 : 1.055379 : 0.870087
 44 : 1.079922 : 0.881921
 45 : 1.104466 : 0.893224
 46 : 1.129010 : 0.903989
 47 : 1.153553 : 0.914210
 48 : 1.178097 : 0.923880
 49 : 1.202641 : 0.932993
 50 : 1.227185 : 0.941544
 51 : 1.251728 : 0.949528
 52 : 1.276272 : 0.956940
 53 : 1.300816 : 0.963776
 54 : 1.325359 : 0.970031
 55 : 1.349903 : 0.975702
 56 : 1.374447 : 0.980785
 57 : 1.398990 : 0.985278
 58 : 1.423534 : 0.989176
 59 : 1.448078 : 0.992480
 60 : 1.472621 : 0.995185
 61 : 1.497165 : 0.997290
 62 : 1.521709 : 0.998795
 63 : 1.546253 : 0.999699
 64 : 1.570796 : 1.000000
 65 : 1.595340 : 0.999699
 66 : 1.619884 : 0.998795
 67 : 1.644427 : 0.997290
 68 : 1.668971 : 0.995185
 69 : 1.693515 : 0.992480
 70 : 1.718058 : 0.989177
 71 : 1.742602 : 0.985278
 72 : 1.767146 : 0.980785
 73 : 1.791690 : 0.975702
 74 : 1.816233 : 0.970031
 75 : 1.840777 : 0.963776
 76 : 1.865321 : 0.956940
 77 : 1.889864 : 0.949528
 78 : 1.914408 : 0.941544
 79 : 1.938952 : 0.932993
 80 : 1.963495 : 0.923880
 81 : 1.988039 : 0.914210
 82 : 2.012583 : 0.903989
 83 : 2.037126 : 0.893224
 84 : 2.061670 : 0.881921
 85 : 2.086214 : 0.870087
 86 : 2.110757 : 0.857729
 87 : 2.135301 : 0.844854
 88 : 2.159845 : 0.831470
 89 : 2.184389 : 0.817585
 90 : 2.208932 : 0.803208
 91 : 2.233476 : 0.788346
 92 : 2.258020 : 0.773010
 93 : 2.282563 : 0.757209
 94 : 2.307107 : 0.740951
 95 : 2.331651 : 0.724247
 96 : 2.356194 : 0.707107
 97 : 2.380738 : 0.689541
 98 : 2.405282 : 0.671559
 99 : 2.429826 : 0.653173
100 : 2.454369 : 0.634393
101 : 2.478913 : 0.615232
102 : 2.503457 : 0.595699
103 : 2.528000 : 0.575808
104 : 2.552544 : 0.555570
105 : 2.577088 : 0.534998
106 : 2.601631 : 0.514103
107 : 2.626175 : 0.492898
108 : 2.650719 : 0.471397
109 : 2.675262 : 0.449611
110 : 2.699806 : 0.427555
111 : 2.724350 : 0.405241
112 : 2.748893 : 0.382683
113 : 2.773437 : 0.359895
114 : 2.797981 : 0.336890
115 : 2.822525 : 0.313682
116 : 2.847068 : 0.290285
117 : 2.871612 : 0.266713
118 : 2.896156 : 0.242980
119 : 2.920699 : 0.219101
120 : 2.945243 : 0.195091
121 : 2.969787 : 0.170962
122 : 2.994330 : 0.146731
123 : 3.018874 : 0.122411
124 : 3.043418 : 0.098017
125 : 3.067961 : 0.073565
126 : 3.092505 : 0.049068
127 : 3.117049 : 0.024541
128 : 3.141593 : 0.000000
129 : 3.166136 : -0.024541
130 : 3.190680 : -0.049067
131 : 3.215224 : -0.073564
132 : 3.239767 : -0.098017
133 : 3.264311 : -0.122411
134 : 3.288855 : -0.146730
135 : 3.313398 : -0.170962
136 : 3.337942 : -0.195090
137 : 3.362486 : -0.219101
138 : 3.387029 : -0.242980
139 : 3.411573 : -0.266713
140 : 3.436117 : -0.290284
141 : 3.460660 : -0.313682
142 : 3.485204 : -0.336890
143 : 3.509748 : -0.359895
144 : 3.534292 : -0.382683
145 : 3.558835 : -0.405241
146 : 3.583379 : -0.427555
147 : 3.607923 : -0.449611
148 : 3.632466 : -0.471397
149 : 3.657010 : -0.492898
150 : 3.681554 : -0.514102
151 : 3.706097 : -0.534997
152 : 3.730641 : -0.555570
153 : 3.755185 : -0.575808
154 : 3.779728 : -0.595699
155 : 3.804272 : -0.615231
156 : 3.828816 : -0.634393
157 : 3.853359 : -0.653173
158 : 3.877903 : -0.671559
159 : 3.902447 : -0.689540
160 : 3.926991 : -0.707107
161 : 3.951534 : -0.724247
162 : 3.976078 : -0.740951
163 : 4.000622 : -0.757209
164 : 4.025166 : -0.773010
165 : 4.049709 : -0.788346
166 : 4.074253 : -0.803207
167 : 4.098796 : -0.817585
168 : 4.123340 : -0.831469
169 : 4.147884 : -0.844853
170 : 4.172428 : -0.857729
171 : 4.196971 : -0.870087
172 : 4.221515 : -0.881921
173 : 4.246058 : -0.893224
174 : 4.270602 : -0.903989
175 : 4.295146 : -0.914210
176 : 4.319690 : -0.923879
177 : 4.344234 : -0.932993
178 : 4.368777 : -0.941544
179 : 4.393321 : -0.949528
180 : 4.417864 : -0.956940
181 : 4.442408 : -0.963776
182 : 4.466952 : -0.970031
183 : 4.491496 : -0.975702
184 : 4.516039 : -0.980785
185 : 4.540583 : -0.985278
186 : 4.565126 : -0.989176
187 : 4.589670 : -0.992479
188 : 4.614214 : -0.995185
189 : 4.638758 : -0.997290
190 : 4.663301 : -0.998795
191 : 4.687845 : -0.999699
192 : 4.712389 : -1.000000
193 : 4.736932 : -0.999699
194 : 4.761476 : -0.998795
195 : 4.786020 : -0.997290
196 : 4.810564 : -0.995185
197 : 4.835107 : -0.992480
198 : 4.859651 : -0.989177
199 : 4.884194 : -0.985278
200 : 4.908738 : -0.980785
201 : 4.933282 : -0.975702
202 : 4.957826 : -0.970031
203 : 4.982369 : -0.963776
204 : 5.006913 : -0.956940
205 : 5.031457 : -0.949528
206 : 5.056000 : -0.941544
207 : 5.080544 : -0.932993
208 : 5.105088 : -0.923880
209 : 5.129632 : -0.914210
210 : 5.154175 : -0.903989
211 : 5.178719 : -0.893224
212 : 5.203263 : -0.881921
213 : 5.227806 : -0.870087
214 : 5.252350 : -0.857729
215 : 5.276894 : -0.844854
216 : 5.301437 : -0.831470
217 : 5.325981 : -0.817585
218 : 5.350525 : -0.803208
219 : 5.375068 : -0.788347
220 : 5.399612 : -0.773011
221 : 5.424156 : -0.757209
222 : 5.448699 : -0.740951
223 : 5.473243 : -0.724247
224 : 5.497787 : -0.707107
225 : 5.522331 : -0.689541
226 : 5.546874 : -0.671559
227 : 5.571418 : -0.653173
228 : 5.595962 : -0.634394
229 : 5.620505 : -0.615232
230 : 5.645049 : -0.595699
231 : 5.669593 : -0.575808
232 : 5.694137 : -0.555570
233 : 5.718680 : -0.534998
234 : 5.743224 : -0.514103
235 : 5.767767 : -0.492898
236 : 5.792311 : -0.471397
237 : 5.816855 : -0.449611
238 : 5.841399 : -0.427555
239 : 5.865942 : -0.405241
240 : 5.890486 : -0.382684
241 : 5.915030 : -0.359895
242 : 5.939573 : -0.336890
243 : 5.964117 : -0.313682
244 : 5.988661 : -0.290285
245 : 6.013205 : -0.266713
246 : 6.037748 : -0.242981
247 : 6.062292 : -0.219102
248 : 6.086835 : -0.195091
249 : 6.111379 : -0.170962
250 : 6.135923 : -0.146731
251 : 6.160467 : -0.122411
252 : 6.185010 : -0.098017
253 : 6.209554 : -0.073565
254 : 6.234097 : -0.049068
255 : 6.258641 : -0.024542

OTOH it's not my intention to put you off from using assembler. You should do whatever is fun for you. Imposing some limits on yourself can be big fun. For example I have much fun in writing applications for Kick/WB 1.3. But then I wouldn't ask for help. The fun lies in the process to work it out yourself.
thomas is offline  
Old 12 July 2017, 20:43   #5
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
What Thomas said was to give your code a 10x speedup. Since you are talking assembly, we take it speed is of importance to you. If you could take the 10x penalty by using floats, then yes you can absolutely use floats. Doubles too, for greater accuracy.
alkis is offline  
Old 12 July 2017, 21:57   #6
matthey
Banned
 
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
C has floating point libraries which can be used in assembler. There is no discrace with borrowing them or learning from them. Compile the modified C program with changes from thomas using vbcc and the math library of your choice.

-lmieee for C= ieee math libraries (not fun to use from assembler)
-lm881 for direct FPU instructions for a 6888x
-lm040 for direct FPU instructions for a 68040
-lm060 for direct FPU instructions for a 68060

The -k option can be used when compiling to get the assembler code or a disassembler like ADis can be used which is formatted for easy reassembly using vasm.

http://eab.abime.net/showthread.php?t=82709

There is often room for optimizing by converting stack based floating point args to register args as the 68k never received a modern ABI which hurts as the extended precision of the 68k FPU is often lost and even double precision floating point args are large to be reading and writing to the stack.

Last edited by matthey; 12 July 2017 at 22:05.
matthey is offline  
Old 12 July 2017, 23:02   #7
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,751
Quote:
Originally Posted by matthey View Post
ieee math libraries (not fun to use from assembler)
Indeed. Macros can make your life ten times easier for that. I have some for a few functions that also switch between math and mathrans library pointers automatically. Much nicer that way.
Thorham is offline  
Old 12 July 2017, 23:06   #8
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
It might help if I summarised where I'm coming from, where I'm at, and where I hope to be 'soon'. I should probably do this in the Introduction forum, but hey, I can always copy this there later.

About 30 years ago, I attempted to write a demo (in assembler -- which, AFAIK, was the only option back then, really) on my A500. Being the young, unexperienced, non-english-speaking and very impatient lad that I was, I never got anywhere with that. That still slightly annoys me to this day -- I was Always very much in awe of those cool demos I saw.

FFW to present day: I'm used to programming in Visual Studio in C#, not having to worry about anything but my own code. Almost everything has already been done, right -- and even way better than I will ever bother to do it. So I try to program at as 'high' a level as I can. This is also a reason why, ATM, I'm trying to program in assembler on the actual hardware, ie pretty low-level/bare-metal -- it's on the opposite side of what I'm used to.

I don't consider myself to be a good programmer, but I've been through various languages (including a little x86 assembler), ide's, libraries and so on -- which makes me think I could make something on the amiga now that I apparently couldn't earlier. Revenge, finally!

Quote:
Originally Posted by thomas View Post
OTOH it's not my intention to put you off from using assembler. You should do whatever is fun for you. Imposing some limits on yourself can be big fun. For example I have much fun in writing applications for Kick/WB 1.3. But then I wouldn't ask for help. The fun lies in the process to work it out yourself.
Oh I'm definitely still having a lot of fun, let there be no doubt about that! My main aim is to make a demo, even if it's a very modest one, that runs on original hardware. I would have preferred to do it in assembler (see above), but maybe I shouldn't start out this way. So even though it wasn't your intention, thanks for putting me off assembler, and shattering my 30 year old dream once again..

The fun I'm having also comes from nostalgia to 'the good old days', surely -- watch out, getting a little philosophical here. I'd like to see it run on original hardware. I'd also have liked to develop it using the tools that were available at the time. But I'd also like to be pragmatic, and just use whatever tools I can -- and this includes asking a lot of meh questions on these forums, for now, I'm afraid. The tension is real!

Quote:
Originally Posted by alkis View Post
What Thomas said was to give your code a 10x speedup. Since you are talking assembly, we take it speed is of importance to you.
Speed may become important, at some point. Wouldn't have thought it'd be a factor of 10, though. Is that FFP, single, or double, btw?
guy lateur is offline  
Old 12 July 2017, 23:10   #9
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,751
Quote:
Originally Posted by guy lateur View Post
Speed may become important, at some point. Wouldn't have thought it'd be a factor of 10, though. Is that FFP, single, or double, btw?
For transcendental functions it's likely 100s of times faster to use a table than software floating point. Perhaps more.
Thorham is offline  
Old 12 July 2017, 23:50   #10
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by Thorham View Post
For transcendental functions it's likely 100s of times faster to use a table than software floating point. Perhaps more.
Well that's what I thought alkis was saying -- quoting thomas, quoting me, talking about the transcendental sine function, and coming to an estimated 10 times speedup. Anyway, here's my understanding:

1. It's 10 times more expensive to do general calculations (add/sub/mul/div) on integers than it is on floats.
2. It's even more expensive (100++ times) to call transcendental functions, like sine, compared to precalculating them into a table. And they require floating arguments, by definition, which makes them even worse.

Is this about right?
guy lateur is offline  
Old 13 July 2017, 00:00   #11
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by matthey View Post
C has floating point libraries which can be used in assembler. There is no discrace with borrowing them or learning from them. Compile the modified C program with changes from thomas using vbcc and the math library of your choice.

The -k option can be used when compiling to get the assembler code or a disassembler like ADis can be used which is formatted for easy reassembly using vasm.

http://eab.abime.net/showthread.php?t=82709
Wow, that's a very interesting point; I totally forgot about the disassembler. Hang on, just give me a minute to get my head around this..

Quote:
Originally Posted by Thorham View Post
Indeed. Macros can make your life ten times easier for that. I have some for a few functions that also switch between math and mathrans library pointers automatically. Much nicer that way.
Could you possibly share a basic example of how that works, please? I'm a little lost again, I'm afraid..
guy lateur is offline  
Old 13 July 2017, 00:04   #12
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,751
Quote:
Originally Posted by guy lateur View Post
And they require floating arguments, by definition, which makes them even worse.
Not in assembly language. A fast float and normal float fit in a single register, a double in two. Not so bad actually. Even if those parameters were passed using the stack (which in asm they aren't), it would be insignificant compared to the actual cost of the floating point calculations.

Even though software float is always slow, it's fine for things that don't need a large amount of speed. For example, I use fast floats in asm to calculate a gamma correction table on the fly. Plenty fast, even though that requires floating point powers (which are REALLY slow).

The annoying thing about those libraries is using them in asm. Something which macros can help out with.

Quote:
Originally Posted by guy lateur View Post
Is this about right?
Yes.
Thorham is offline  
Old 13 July 2017, 01:03   #13
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by Thorham View Post
Not in assembly language. A fast float and normal float fit in a single register, a double in two. Not so bad actually. Even if those parameters were passed using the stack (which in asm they aren't), it would be insignificant compared to the actual cost of the floating point calculations.
Thanks Thorham, you've given me some real food for thought, there! I'll be going to sleep thinking about 1 or all of these possibilities:

1. Testing/timing some calculations using integer-vs-float evaluation-vs-table-lookup and so on. This contradicts the pragmatic approach I mentioned above, obviously, but if only I had a DateTime.Now, and some kind of console printing facility..

2. That darn stack, and how to avoid using it, probably. Btw, are there any conventions about 'side effects' when writing (reusable) subroutines? Is it ok if I use/change d7? How about a7? You know, who's responsible for what?

The above, plus (cross) assembling/linking, plus reading RKM Libraries Manuals, M68k Developers References and pure Hardware Stuff, etc.. It's a lot to go through, you know -- so forgive me if I seem to be confused..
guy lateur is offline  
Old 13 July 2017, 01:25   #14
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,751
Quote:
Originally Posted by guy lateur View Post
Could you possibly share a basic example of how that works, please? I'm a little lost again, I'm afraid..
I can show you the gamma correction table code and macros I was talking about earlier.

Macros:
Code:
;
; Do NOT use d0 and d1 as arguments in these macros.
;
selectMathBase set 0

setMathBase macro
    ifle selectMathBase
selectMathBase set 1
    move.l  mathBase,a6
    endc
 endm

setMathtransBase macro
    ifge selectMathBase
selectMathBase set -1
    move.l  mathtransBase,a6
    endc
 endm

spflt macro
    setMathBase
    move.l  \1,d0
    jsr     _LVOSPFlt(a6)
    move.l  d0,\2
 endm

spfix macro
    setMathBase
    move.l  \1,d0
    jsr     _LVOSPFix(a6)
    move.l  d0,\2
 endm

spdiv macro
    setMathBase
    move.l  \1,d0
    move.l  \2,d1
    jsr     _LVOSPDiv(a6)
    move.l  d0,\3
 endm

spmul macro
    setMathBase
    move.l  \1,d0
    move.l  \2,d1
    jsr     _LVOSPMul(a6)
    move.l  d0,\3
 endm

sppow macro
    setMathtransBase
    move.l  \1,d0
    move.l  \2,d1
    jsr     _LVOSPPow(a6)
    move.l  d0,\3
 endm
Table generator:
Code:
;
; generate gamma correction table
;
; d0 = gamma value times 1000
; a2 = gamma table
;
gamma.genTable
    movem.l d0-a6,-(sp)

;gamma value times 1000

    spflt   d0,d2
    spflt   #1000,d3
    spdiv   d2,d3,d6

    spflt   #255,d5

; table loop

    clr.l   d7
.loop

    spflt   d7,d2
    spdiv   d2,d5,d2
    sppow   d2,d6,d2
    spmul   d2,d5,d2
    spfix   d2,d2

    cmp.w   #256,d2
    blo.s   .l1
    sge     d2
.l1
    move.b  d2,(a2)+

    addq.b  #1,d7
    bne     .loop

    movem.l (sp)+,d0-a6
    rts
Quote:
Originally Posted by guy lateur View Post
This contradicts the pragmatic approach I mentioned above
Welcome to assembly language

Quote:
Originally Posted by guy lateur View Post
if only I had a DateTime.Now
There are two. One in the dos.library and one in timer.device. The one in timer.device includes microseconds, while the dos.library one is slightly easier to use and has a resolution of 1/50 second.

I suggest you start with the one in dos.library: http://amigadev.elowar.com/read/ADCD.../node014F.html

Quote:
Originally Posted by guy lateur View Post
and some kind of console printing facility..
I'm not sure AOS contains anything for floating point values. Writing one yourself shouldn't be too difficult if you know how to convert base 2 exponents to base 10 exponents correctly.

Quote:
Originally Posted by guy lateur View Post
2. That darn stack, and how to avoid using it, probably.
The stack is easy to use in asm, and mostly used for saving and restoring registers. Don't worry about it.

Quote:
Originally Posted by guy lateur View Post
Btw, are there any conventions about 'side effects' when writing (reusable) subroutines? Is it ok if I use/change d7? How about a7? You know, who's responsible for what?
Only a7 doubles as something else, namely the stack pointer. All data registers behave identical, and all address registers except a7 behave identical.

However, when using OS functions, the basic convention is that d0, d1, a0 and a1 are used as scratch registers, and are NOT saved and restored by the function call unless the documentation explicitly specifies that the function saves and restores those registers.

Quote:
Originally Posted by guy lateur View Post
It's a lot to go through, you know
Yeah, it can be a little overwhelming when starting out. Be glad you already know how to program!
Thorham is offline  
Old 13 July 2017, 01:28   #15
matthey
Banned
 
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
Quote:
Originally Posted by guy lateur View Post
Well that's what I thought alkis was saying -- quoting thomas, quoting me, talking about the transcendental sine function, and coming to an estimated 10 times speedup. Anyway, here's my understanding:

1. It's 10 times more expensive to do general calculations (add/sub/mul/div) on integers than it is on floats.
There really is *not* a general rule. It depends on the hardware used. Modern CPUs are usually similar but old CPUs can vary significantly.

Code:
68030 add.l 2 cycle
68882 fadd 56 cycles

68030 muls.l 44 cycles
68882 fmul 76 cycles

68030 divs.l 90 cycles
68882 fdiv 108 cycles
Add and sub are more frequent so maybe there is an overall 10x speedup by using integer instead of the FPU for the 68030+68882.

Code:
68060 add.l 1 cycle
68060 fadd 3 cycles

68060 muls.l 2 cycles
68060 fmul 3 cycles

68060 divs.l 38 cycles
68060 fdiv 37 cycles
The 68060 FPU is not even fully pipelined but we can already see that using integer is not going to be 10x faster than avoiding the FPU, at least with common math.

Quote:
Originally Posted by guy lateur View Post
2. It's even more expensive (100++ times) to call transcendental functions, like sine, compared to precalculating them into a table. And they require floating arguments, by definition, which makes them even worse.
Code:
68882 fsin 394 cycles
68040 no
68060 no
The 68060 should be fewer cycles at finding fsin in software than the 68882 fsin instruction (perhaps half the cycles). I still expect the all integer sin table lookup to be closer to 10x faster than 100x times faster. All of the 68k FPUs can sometimes work in parallel to the integer units reducing the overall cost with mixed code (the 68060 has 2 integer units though too). Floating point args are only a tiny percentage of any difference and can sometimes be avoided by the compiler by using inlined assembler code (default with vbcc).

Last edited by matthey; 13 July 2017 at 01:41.
matthey is offline  
Old 13 July 2017, 01:47   #16
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by Thorham View Post
I can show you the gamma correction table code and macros I was talking about earlier.
<snip>
Yeah, it can be a little overwhelming when starting out. Be glad you already know how to program!
Quote:
Originally Posted by matthey View Post
There really is *not* a general rule. It depends on the hardware used. Modern CPUs are usually similar but old CPUs can vary significantly.
<snip>
I still expect the all integer sin table lookup to be closer to 10x faster than 100x times faster. Floating point args are only a tiny percentage of any difference and can sometimes be avoided by the compiler by using inlined assembler code (default with vbcc).
Please, you guys, stop making me stay up to read and try to understand all this right now! This will never work, can't you see? I'll get back on this soon.

Amazing community this is, that's for sure!
guy lateur is offline  
Old 13 July 2017, 01:54   #17
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,751
Quote:
Originally Posted by guy lateur View Post
Please, you guys, stop making me stay up to read and try to understand all this right now! This will never work, can't you see?
There's always tomorrow.
Thorham is offline  
Old 13 July 2017, 01:58   #18
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by Thorham View Post
There's always tomorrow.
*happily snoring*
guy lateur is offline  
Old 14 July 2017, 11:27   #19
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by Thorham View Post
I can show you the gamma correction table code and macros I was talking about earlier.
Going on a little side track here: I'm very interested in your use of macros. I've often wondered what \1 & \2 were all about.. I'm looking to print things (strings, decimal, floats, ..) to screen/stdout, so I started from a basic hello world example, and I'm trying to separate the printing functionality, using macros. Here's what I have ATM:

main.asm:
Code:
	include "include/dosUtil.i"
	
	XDEF	_main		; ?? is this relevant/special ??
	
_main:
	dosUtilInit
	cmp		#0,d0
	beq 	.fail
	
	dosUtilPrintString #Hello,#HelloLen
	
	; dosUtilPrintNewLine
	dosUtilPrintString #NewLine,#NewLineLength
	
	dosUtilRelease
	
.ok:
	moveq	#RETURN_OK,d0
	rts
	
; ?? can't move this to dosUtil.i ??
.fail:
	moveq	#RETURN_FAIL,d0
	rts

	cnop	0,4

; should probably put this in a data section or something..	
Hello:
	dc.b	'Hello World!!'
HelloLen	equ	*-Hello

NewLine:
	dc.b 	'',10
NewLineLength equ *-NewLine

; ?? can't move this to dosUtil.i ??
DOSName:
	DOSNAME
	
	end
dosUtil.i (put this in an include subfolder next to main):
Code:
	include	"dos/dos.i"
	
	XDEF	_SysBase
	XDEF	_DOSBase
	XDEF	_StdOut
	
	XREF	_AbsExecBase
	
	XREF	_LVOOpenLibrary
	XREF	_LVOCloseLibrary
	
	XREF	_LVOOutput
	XREF	_LVOWrite
	
; dosUtil:
dosUtilInit macro
	;	store	SysBase
	movea.l	_AbsExecBase,a6
	move.l	a6,_SysBase
	
	;	open	dos.library
	lea		DOSName,a1
	moveq	#LIBRARY_MINIMUM,d0
	movea.l	_SysBase,a6
	jsr		_LVOOpenLibrary(a6)
	move.l	d0,_DOSBase
	; beq		.fail		; ?? cannot define .fail in dosUtil.i ??
	; TODO: quit macro here if d0==0
	
	;	fetch	_StdOut
	movea.l	_DOSBase,a6
	jsr		_LVOOutput(a6)
	move.l	d0,_StdOut
endm

dosUtilRelease macro
	;	close	dos.library
	movea.l	_DOSBase,a1
	movea.l	_SysBase,a6
	jsr		_LVOCloseLibrary(a6)
	clr.l	_DOSBase
endm

; dosUtilPrintString	string,stringLength
dosUtilPrintString macro
	move.l	_StdOut,d1
	move.l	\1,d2
	moveq	\2,d3
	movea.l	_DOSBase,a6
	jsr		_LVOWrite(a6)
endm

; dosUtilPrintNewLine macro
	; move.l	_StdOut,d1
	; move.l	#NewLine,d2
	; moveq		#NewLineLength,d3
	; movea.l	_DOSBase,a6
	; jsr		_LVOWrite(a6)
; endm

even
_SysBase:
	dc.l	0
_DOSBase:
	dc.l	0
_StdOut:
	dc.l 	0

; NewLine:
	; dc.b 	'a'
; NewLineLength equ *-NewLine
	
; DOSName:
	; DOSNAME

; how/why local labels? and do they imply _main?
; .fail:
	; moveq	#RETURN_FAIL,d0
	; rts
Everything works fine, but there is some weirdness going on at the end of the files (after the actual code). Eg, it would make sense to put the DOSName label/data into dosUtil.i, but the exe gurues if I do this. Same for the NewLine stuff, which also really belongs in dosUtil.i. It's probably because I'm including the source, which makes main think this is code, rather than data. Maybe I could solve this with sections? Still, I'm beginning to think including these macros isn't really the way to go if I want to make this functionality reusable.

I'll probably need to put this in a separate .o/.lib file, and link to that. There's an excellent explanation by phx on those kind of files here: http://eab.abime.net/showthread.php?...6&goto=newpost However, if I try to link dosUtil.o to amiga.lib (creating dosUtil.lib, preferably), it says things like 'imported symbol <_LVOCloseLibrary> was not referenced', and produces a file that's probably too small to be ok. So I'm assuming you can't link to macros in another object, as they only make sense within the context of that object?

So how can I make this a properly linkable .lib file, like amiga.lib? I should possibly start a separate thread for this..

I've attached the files, including a Python make script, in which you'll obviously want to change some paths to the system/NDK39 includes/linker_libs.
Attached Files
File Type: zip PrintDecimal.zip (1.7 KB, 98 views)
guy lateur is offline  
Old 14 July 2017, 14:35   #20
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
You got to start small!

Ok. You can't link macros in a lib, cause macros don't exist! It's dormant code, that comes into play when you invoke it in your source code.

If you assemble, say 10.000 bytes (worth of) macros and never call any of them, the output will be 0 bytes. It's like defines in C/C++ if you are familiar with those languages.

So, it doesn't make sense to "link" macros. What you link is subroutines. Nice generic subroutines that took you a lot of efford to write/debug/test and now they are perfect.

Try to make your macros as generic as possible. You have one macro that specifically opens dos.library. What if your program needs ten libraries. You are gonna go for ten macros? Could you have one macro?

Say, like that
Code:
; mOpenLibrary "foo.library",version,variableBase
; return library pointer at d0, which SHOULD be checked
mOpenLibrary	macro
	movem.l d1/a0/a1/a6,-(sp)
	ifge execbaseinit
	move.l $4.w,a6
	move.l a6,_SysBase
	bra.s s1\@
_SysBase	dc.l 0
s1\@
execbaseinit set 1
	endc

	lea.l	n1\@,a1
	moveq.l #\2,d0
	move.l  _SysBase,a6
	jsr 	_LVOOpenLibrary(a6)
	bra.s   n2\@
n1\@ dc.b 	\1,0
	cnop 	0,2
	XDEF	\3
	XDEF	_\3
_\3
\3 	dc.l 	0
	cnop	0,2
n2\@
	movem.l (sp)+,d1/a0/a1/a6
	move.l 	d0,\3
	endm
then you can do (in your source code)
mOpenLibrary "dos.library",33,DOSBase
mOpenLibrary "intuition.library",33,IntuitionBase

I skipped error checking (check if d0 is zero), which you should never skip btw.

You could end up with source code like that
Code:
	include mymacros.i

	mOpenLibrary "dos.library",33,DOSBase
	move.l #123,d0
	add.l 	d0,d0
	mprintf "The value of d0 is %ld\n",d0
	mCloseLibrary DOSBase
	rts
See, attached zip for the source code and exe.
Attached Files
File Type: zip asm.zip (2.3 KB, 106 views)
alkis is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
AmiDevCpp and Floats AmigaEd Coders. General 0 18 January 2006 03:16

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 01:58.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.12883 seconds with 16 queries