English Amiga Board Maths question, divisions, remainders etc.
 Register Amiga FAQ Rules & Help Members List  /  Moderators List Today's Posts Mark Forums Read

 26 May 2011, 14:54 #1 h0ffman Registered User   Join Date: Aug 2008 Location: Salisbury Posts: 470 Maths question, divisions, remainders etc. Hi guys Bit of a maths question today. Funnily enough relating to scope code again. It's to do with sample rates (or periods! as they are called on the amiga) and time calculations. This is a section of code from the original protracker scope code.. Code: ``` MOVEQ.L #0,D1 MOVE.W ns_period(A2),D1 LSR.W #1,D1 BEQ.S ScoNextChan MOVE.L #35469,D2 DIVU D1,D2 EXT.L D2 ADD.L D2,D0``` The above section calculates where the sample pointer needs to draw from in the next frame. The 35469 is the magic number which does this. So, at present all the scopes I've seen or worked on simply draw the samples byte by byte to the screen and uses this calculation to simply move the pointer each frame to where the sample should be. This is not an accurate representation of the wave form, however it does suffice most requirements. What I want to do is draw the wave at the frequency it is being played at. My idea was to simply divide the 35469 by the pixel width of the scope, then use this value to increment the sample pointer for each pixel. However, I very quickly realised that you cannot get away with this as the remainder from the division needs to be taken into consideration for each pixel iteration. Code: ``` moveq #0,d1 MOVE.W #172,D1 ; period LSR.W #1,D1 MOVE.L #35469/160,D2 ; magic number div by 160 pixels DIVU D1,D2``` So the result of this in D2 is \$00310002, so I can assume that I can move forward two bytes to get the next pixel from the sample data, however if I just do that for all 160 pixels, it wont finish at the end because the remainder \$0031 is not being taken into consideration. So... how do you go about performing this type of calculation in 68k? On a side note, it doesn't need to be fast, just accurate as it will all get pre-calced into look up tables anyhow.
26 May 2011, 15:40   #2
Ed Cruse
Registered User

Join Date: Sep 2007
Location: Las Cruces, USA
Age: 66
Posts: 351
Quote:
 Originally Posted by h0ffman Hi guys Bit of a maths question today. Funnily enough relating to scope code again. It's to do with sample rates (or periods! as they are called on the amiga) and time calculations. This is a section of code from the original protracker scope code.. Code: ``` MOVEQ.L #0,D1 MOVE.W ns_period(A2),D1 LSR.W #1,D1 BEQ.S ScoNextChan MOVE.L #35469,D2 DIVU D1,D2 EXT.L D2 ADD.L D2,D0``` The above section calculates where the sample pointer needs to draw from in the next frame. The 35469 is the magic number which does this. So, at present all the scopes I've seen or worked on simply draw the samples byte by byte to the screen and uses this calculation to simply move the pointer each frame to where the sample should be. This is not an accurate representation of the wave form, however it does suffice most requirements. What I want to do is draw the wave at the frequency it is being played at. My idea was to simply divide the 35469 by the pixel width of the scope, then use this value to increment the sample pointer for each pixel. However, I very quickly realised that you cannot get away with this as the remainder from the division needs to be taken into consideration for each pixel iteration. Code: ``` moveq #0,d1 MOVE.W #172,D1 ; period LSR.W #1,D1 MOVE.L #35469/160,D2 ; magic number div by 160 pixels DIVU D1,D2``` So the result of this in D2 is \$00310002, so I can assume that I can move forward two bytes to get the next pixel from the sample data, however if I just do that for all 160 pixels, it wont finish at the end because the remainder \$0031 is not being taken into consideration. So... how do you go about performing this type of calculation in 68k? On a side note, it doesn't need to be fast, just accurate as it will all get pre-calced into look up tables anyhow.

One possible way is to convert to double float, do the calculations, round to an integer, and then convert back to integers. It's slow but it works. You may still be off at the end, it just depends on how well the rounding averages out. I've used this method for scaling the data for plotting purposes.

 26 May 2011, 16:14 #3 h0ffman Registered User   Join Date: Aug 2008 Location: Salisbury Posts: 470 How do you do a double float in assembly?
 26 May 2011, 17:42 #4 dalton tulou   Join Date: Jun 2006 Location: Gothenburg / Sweden Posts: 71 If you're on 020, you can use divu.l with 35469<<16 to get a 16.16 bit fixed point representation. That should be sufficient for 160 pixels. If you're not on 020, perhaps Bresenham interpolation could be a solution.
26 May 2011, 23:19   #5
Ed Cruse
Registered User

Join Date: Sep 2007
Location: Las Cruces, USA
Age: 66
Posts: 351
Quote:
 Originally Posted by h0ffman How do you do a double float in assembly?

Use the Amiga math libs to do the converting and calculations. The easiest way would be to use the math libs to convert all your integers like 35469 and integers in the data registers, to single or double float. Calculate and then use the math libs to convert back to integers. It's basically a pain. It's a lot easier to do it in C.

When I was doing a lot of assembly I had macros to make it a lot easier, I also came up with my own double float constants and wrote a program that would search through my source codes and convert double float constants like 35469.0 into two dc.l. Eventually I got an assembler that new about double float constants. After 20 years of assembly programing I finally wised up and learned C, now I do assembly only when it's necessary.

I can already feel the hate from the pure assembly programers, like I used to be.

 27 May 2011, 14:22 #6 h0ffman Registered User   Join Date: Aug 2008 Location: Salisbury Posts: 470 Thanks for the response Ed, however, i'm more interested in how to solve this problem with assembly. I know that maths lib might be the easiest, but I'd love to know how these kind of problems are resolved when working directly with the CPU.
27 May 2011, 15:44   #7
Ed Cruse
Registered User

Join Date: Sep 2007
Location: Las Cruces, USA
Age: 66
Posts: 351
Quote:
 Originally Posted by h0ffman Thanks for the response Ed, however, i'm more interested in how to solve this problem with assembly. I know that maths lib might be the easiest, but I'd love to know how these kind of problems are resolved when working directly with the CPU.

I know what you mean, I've tried to complish the same thing dealing with the remainder but it's always been very difficult. Seems like there's always some odd combination of things that causes problems, so I end up using double floating point. Recently I did manage to use the remainder method and it was working, but in the normal use of what I was doing I would frequently end up with numbers after the divide that were larger then a long could handle and it messed up my whole plan. In this case speed was important and using double floating point was slow but I ended up using it anyway, I had no choice. My math isn't good enough to figure out how to use remainders reliably to do what I needed. Especially rounding.

I use WinUAE so the emulated fpu is really fast, so when I really need my float points to be fast I compile to use inline FPU code. But that also requires using at least a 68020, but you want 68000. If you could use a 68020 you can also use an assembler that knows fpu commands and use the fpu to convert, calculate, and convert back to integers. From a assembly programmers point of view the fpu is a dream to use and very fast.

 30 May 2011, 15:15 #8 MSL Registered User   Join Date: Feb 2009 Location: Copenhagen / Denmark Posts: 11 I'm not experienced with asm, so I might not understand your code correctly, but from what it looks like to me is, that you divide D1 with D2, where D2 is a division of 35469/160, which have a remainder. The math can be rewritten: A / (B / C) = (A * C) / B -> ( D1 * 160 ) / 35469 Assuming that A * C does not overflow you have removed the imprecision of one division. Last edited by MSL; 30 May 2011 at 15:21. Reason: Spelling mistake
 07 June 2011, 14:35 #9 h0ffman Registered User   Join Date: Aug 2008 Location: Salisbury Posts: 470 Just thought I'd put a quick update here, managed to crack it in the end... Code: ```ScopeInitFreq lea FreqTable+(scopebytewd*8*2),a0 moveq #1,d0 ; current period .nextperiod move.l #35469/(scopebytewd*8),d6 ; the magic number! moveq #0,d5 move.w #scopebytewd*8-1,d7 moveq #0,d2 moveq #0,d3 .test add.l d6,d5 move.l d5,d1 divu d0,d1 move.w d1,d2 sub.w d3,d1 move.w d1,(a0)+ ; store byte move size move.w d2,d3 dbra d7,.test add.w #1,d0 cmp.w #scopemaxperiod,d0 blo.b .nextperiod RTS``` Simply re-do the calculation incrementing the seed each time. Also managed to get this plugged into the scope drawing routine. You can see it re-sizing the wave depending on the frequency of the sample !
 24 June 2011, 00:03 #10 Photon Moderator   Join Date: Nov 2004 Location: Eksjö / Sweden Posts: 4,685 If you're using The Player to optimize modules, there's a scope routine accurate to 1/262144th of a sample in the latest P61 playroutine by me, P6108, if you enable it it will give you pointer and length for a 50Hz frame for each playing channel. It wraps loops correctly and gives a bunch of zeroes if the channel is quiet or ending.
 24 June 2011, 08:40 #11 pmc gone   Join Date: Apr 2007 Location: completely gone Posts: 1,596 @ Photon: going slightly off topic I suppose but not too far I hope - I integrated ThePlayer into my demo shell recently but I didn't manage to get your "super optimised, all singing, all dancing" version to assemble and had to use the latest "old" release of ThePlayer instead. With your version I got 200+ errors on assembly using Devpac3.18 - was I doing something obviously and stupidly wrong...?
 24 June 2011, 18:35 #12 Photon Moderator   Join Date: Nov 2004 Location: Eksjö / Sweden Posts: 4,685 Differences between assemblers will give errors, basically for all sources "not made for your assembler flavor". The Player source is special in that it uses loads of conditionals and a few macros, and these features might not be supported or need to be written in another way to be used in your assembler. Same thing if someone releases a Devpac source and uses features not found in say, AsmOne or PhxAss. The most common complaint about The Player sources is the structures macros. Have you set ASMONE=0, to start with? This attempts to replace AsmOne macros with other flavors. If there are remaining differences you'll have to reconcile them, or you could rip out the Scope routine+a few vars added for it at the end of the source and see if it talks to P6106. Or check what it does and modify it to talk to Protracker, that would be ace
 24 June 2011, 23:58 #13 h0ffman Registered User   Join Date: Aug 2008 Location: Salisbury Posts: 470 Hey photn, thanks for the offer, however I've got my scope routine already integrated into the player. Fixed all the original bugs that came with the original source, such as sample offset, loops sample endings. I've recently done a version which draws the sample at the sample rate its playing at. Next up is it see if I can combine all four channels into one massive scope
25 June 2011, 00:00   #14
Lonewolf10
AMOS Extensions Developer

Join Date: Jun 2007
Location: near Cambridge, UK
Age: 39
Posts: 1,920
Quote:
 Originally Posted by pmc With your version I got 200+ errors on assembly using Devpac3.18 - was I doing something obviously and stupidly wrong...?
I agree with Photon's reply, but just wish to check that you are not using case-sensitive mode when assembling - that gave me loads of errors when compiling with (an old version of) The Player when I first started using it.
Now I always compile assemble with case-sensitive mode off.

Regards,
Lonewolf10

Last edited by Lonewolf10; 25 June 2011 at 00:05. Reason: typo (assembling not compiling)

 25 June 2011, 09:06 #15 pmc gone   Join Date: Apr 2007 Location: completely gone Posts: 1,596 Errrm, no - not using case sensitive and had already done all the other obvious stuff. While Photon was around I thought I'd ask out of curiosity but now I know (rather than just suspecting...) the answer is basically to go though those errors and remedy each one I'm gonna take the approach I'd already decided on: stick with the latest un-Photon'd version of ThePlayer that works for me.
 25 June 2011, 21:44 #16 Photon Moderator   Join Date: Nov 2004 Location: Eksjö / Sweden Posts: 4,685 pmc, I'd be interested in differences in error log between P6106 and P6108, so email me them if you want ! h0ffman, hm, read pmc's reply as one of yours, sorry for the confusion. The scope routine would then only be of abstract use for your playroutine, anyway good to hear you fixed it up! And yes, 4 fullres scopes running separately consume a not negligible amount of raster time on OCS, visualizing 4 added together to reduce the amount of plots or similar you use to visualize it is a very good idea

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

 Similar Threads Thread Thread Starter Forum Replies Last Post dlfrsilver request.Old Rare Games 2 12 February 2013 18:23 Nipedley Looking for a game name ? 8 29 April 2011 21:56 alexh Retrogaming General Discussion 5 18 November 2007 23:47 ElectroBlaster HOL contributions 0 19 September 2006 01:11 icewizard2k5 request.Old Rare Games 2 21 February 2005 12:14

 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 Rules
 Forum Jump User Control Panel Private Messages Subscriptions Who's Online Search Forums Forums Home News Main     Amiga scene     Retrogaming General Discussion     Nostalgia & memories Support     New to Emulation or Amiga scene         Member Introductions     support.WinUAE     support.WinFellow     support.OtherUAE     support.FS-UAE         project.AmigaLive     support.Hardware         Hardware mods         Hardware pics     support.Games     support.Demos     support.Apps     support.Amiga Forever     support.Amix     support.Other Requests     request.UAE Wishlist     request.Old Rare Games     request.Demos     request.Apps     request.Modules     request.Music     request.Other     Looking for a game name ?     Games images which need to be WHDified abime.net - Hall Of Light     HOL news     HOL suggestions and feedback     HOL data problems     HOL contributions abime.net - Amiga Magazine Rack     AMR news     AMR suggestions and feedback     AMR data problems     AMR contributions abime.net - Home Projects     project.Amiga Lore     project.EAB     project.IRC     project.Mods Jukebox     project.Wiki abime.net - Hosted Projects     project.aGTW     project.APoV     project.ClassicWB     project.Jambo!     project.Green Amiga Alien GUIDES     project.Maptapper     project.Sprites     project.WinUAE - Kaillera Other Projects     project.Amiga Demo DVD     project.Amiga Game Factory     project.CARE     project.EAB File Server     project.CD32 Conversion     project.Game Cover Art         GCA.Feedback and Suggestions         GCA.Work in Progress         GCA.Cover Requests         GCA.Usefull Programs         GCA.Helpdesk     project.KGLoad     project.MAGE     project.Missing Full Shareware Games     project.SPS (was CAPS)     project.TOSEC (amiga only)     project.WHDLoad         project.Killergorilla's WHD packs Misc     Amiga websites reviews     MarketPlace         Swapshop     Kinky Amiga Stuff     Collections     EAB's competition Coders     Coders. General         Coders. Releases         Coders. Tutorials     Coders. Asm / Hardware     Coders. System         Coders. Scripting         Coders. Nextgen     Coders. Language         Coders. C/C++         Coders. AMOS         Coders. Blitz Basic     Coders. Contest         Coders. Entries Off Topic     OT - General     OT - Entertainment     OT - Sports     OT - Technical     OT - Gaming

All times are GMT +2. The time now is 22:05.

 -- EAB3 skin ---- EAB2 skin ---- Mobile skin Archive - Top