31 May 2021, 01:02 | #1 |
Registered User
Join Date: Oct 2015
Location: Landsberg / Germany
Posts: 526
|
Fast way of getting absolute value
Hi guys!
Wonder what you guys think of my code. Its purpose is to convert the value in register d7 to its absolute value: Code:
swap d7 ; fetch x-acceleration tst.w d7 ; test if negative smi d4 ; Yes? Set d4 ext.w d4 ; create polarity converter eor d4,d7 ; convert polarity (if x-acc is negative) |
31 May 2021, 01:04 | #2 |
OCS forever!
Join Date: Mar 2019
Location: Birmingham, UK
Posts: 418
|
I've got a macro I stole from Kalm's on another forum:
Code:
;(Kalms explained the method itself in the other thread.) Now, to use that you'd simply ;enter the macro like any other instruction, specifying a source register, a destination ; register and an available scratch register like so: ; ABS_W d1,d2,d6 ; d2.w <- abs(d1.w-d2.w), trashes d6.w ABS_W MACRO sub.w \1,\2 subx.w \3,\3 eor.w \3,\2 sub.w \3,\2 ENDM Edit: Ah wait, it's the abs of two values, not sure this is applicable, but left here for others |
31 May 2021, 02:31 | #3 | |
Registered User
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,029
|
Quote:
|
|
31 May 2021, 03:17 | #4 |
Registered User
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 56
Posts: 2,029
|
I will use next code, but this is not fastest.
Code:
swap D7 move.w D7,D4 add.w D4,D4 subx.w D4,D4 eor.w D4,D7 sub.w D4,D7 |
31 May 2021, 08:15 | #5 | |
Registered User
Join Date: Oct 2015
Location: Landsberg / Germany
Posts: 526
|
Quote:
You are certainly more eor-expert than I am :-) Yes, the function is not bulletproof as is. Can live with that, as speed is more important than accuracy in this case. But it'd be nice to make it bulletproof and faster :-) |
|
31 May 2021, 09:17 | #6 |
Registered User
Join Date: Jun 2016
Location: europe
Posts: 1,053
|
When you are dealing with short code sequences a lot depends on how they are interfacing with the rest of the code (extreme example: super fast pixel draw but you call it with movem/jsr/movem for each pixel), and this opens up several questions...
Would it be faster to load each word individually to get rid of swap+tst? Is source addressing mode simple enough? Do you need the result as individual words or as a longword (simple partial parallelization: tst.l if ccr not set by move, smi, extb.l, tst.w, smi, ext.w, eor.l, so 1 less eor)? Assuming this is for 020+, so branching should be avoided... |
31 May 2021, 09:41 | #7 | |
Registered User
Join Date: Oct 2015
Location: Landsberg / Germany
Posts: 526
|
Quote:
0.w = x-acceleration (<0 = move left, >0 = move right) 2.w= y-acceleration (< 0 = move up, > 0 = move down) So one longword-read can fetch both values. I tried to avoid absolute value conversion by simply comparing x-acc and y-acc, but cannot get it to work faultlessly. This is the complete code, with absolute conversion: Code:
krakenSmall move.l objectListAcc(a2),d7 ; get x- and y-acceleration move.w d7,d0 ; fetch y-acceleration in world move.w viewPosition+vPyAccConvertWorldToView(pc),d6 sub.w d6,d0 ; convert to y-acceleration in view smi d4 ; y-acc is negative (object goes up) -> set to $ff ext.w d4 ; 0->0, $ff->$ffff eor d4,d0 ; convert polarity if y-acc is negative swap d7 ; fetch x-acceleration tst.w d7 ; test if negative smi d4 ; Yes? Set d4 ext.w d4 ; create polarity converter eor.w d4,d7 ; convert polarity if x-acc is negative cmp.w d0,d7 ; compare x-acceleration and y-acceleration shi d6 ; set d6=0 if object moves up/down - y-acceleration>x-acceleration ; set d6=$ff if object moves left/right y-acceleration<x-acceleration |
|
31 May 2021, 10:57 | #8 | |
Registered User
Join Date: Mar 2012
Location: Norfolk, UK
Posts: 1,157
|
Quote:
Edit: corrected typos - changed "scc" to "scs"! Code:
move.l objectListAcc(a2),d7 ; get x- and y-acceleration move.w d7,d0 ; fetch y-acceleration in world move.w viewPosition+vPyAccConvertWorldToView(pc),d6 sub.w d6,d0 ; convert to y-acceleration in view swap d7 move.w d7,d6 add.w d0,d6 scs d6 sub.w d0,d7 scs d7 or.w d7,d6 ; D6 is set if either the add or sub generated a carry. Last edited by robinsonb5; 31 May 2021 at 12:06. |
|
31 May 2021, 11:15 | #9 | |
Registered User
Join Date: Oct 2015
Location: Landsberg / Germany
Posts: 526
|
Quote:
|
|
31 May 2021, 11:26 | #10 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,488
|
Quote:
Just try it for positive y values greater than positive x values and you will have problems .. --- For a bare 68k I would have no doubts and would simply do: Code:
move.w objectListAcc+2(a2),d7 sub.w viewPosition+vPyAccConvertWorldToView(pc),d7 bpl.b .1 neg.w d7 .1 move.w objectListAcc(a2),d4 bpl.b .2 neg.w d4 .2 cmp.w d7,d4 shi d6 Code:
move.l objectListAcc(a2),d7 move.l d7,d4 swap d4 sub.w viewPosition+vPyAccConvertWorldToView(pc),d7 bpl.b .1 neg.w d7 .1 tst.w d4 bpl.b .2 neg.w d4 .2 cmp.w d7,d4 shi d6 |
|
31 May 2021, 12:03 | #11 | |
Registered User
Join Date: Oct 2015
Location: Landsberg / Germany
Posts: 526
|
Quote:
|
|
31 May 2021, 12:05 | #12 | |
Registered User
Join Date: Mar 2012
Location: Norfolk, UK
Posts: 1,157
|
Quote:
Gah - I said beware of typos - my "scc"s should be "scs"! With that correction made, would it work, or is there still something I'm missing? |
|
31 May 2021, 12:11 | #13 |
son of 68k
Join Date: Nov 2007
Location: Lyon / France
Age: 51
Posts: 5,351
|
If the code does not fit into the cache, it has better be short. The branch solution looks like it is the shortest.
|
31 May 2021, 12:25 | #14 | ||
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,488
|
Quote:
I also prefer to avoid branches (there are many examples of how I feel about it on the forum), but in some cases they are advantageous, especially on slower machines. Quote:
orbrings you back to the wrong result. |
||
31 May 2021, 12:44 | #15 |
Registered User
Join Date: Mar 2012
Location: Norfolk, UK
Posts: 1,157
|
|
31 May 2021, 13:10 | #16 |
Registered User
Join Date: Mar 2012
Location: Norfolk, UK
Posts: 1,157
|
OK this one works, I think:
Code:
move.l objectListAcc(a2),d7 ; get x- and y-acceleration move.w d7,d0 ; fetch y-acceleration in world move.w viewPosition+vPyAccConvertWorldToView(pc),d6 sub.w d6,d0 ; convert to y-acceleration in view swap d7 move.w d7,d6 add.w d0,d6 smi d6 sub.w d0,d7 smi d7 xor.b d7,d6 ; D6 is set if either but not both the add or sub generated a negative result. |
31 May 2021, 14:31 | #17 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,488
|
No, it does not .
EDIT: The problem with your algorithm is that in any case (for both the addition and the subtraction) you are doing it on signed values, while what you are asked to do is to do it for unsigned values. That's why in my algorithm I have to first change it, if needed, for both, and then make a comparison. Last edited by ross; 31 May 2021 at 14:58. |
31 May 2021, 15:07 | #18 |
Registered User
Join Date: Mar 2012
Location: Norfolk, UK
Posts: 1,157
|
LOL - OK, what am I missing?
This testbench tests all eight permutations of +/- Lo/Hi for each operand, and gives the expected result? (0xaa in D1 at the end, or 0x55 if you reverse HI and LO) The inputs do have to be within the range +/- 16383, however. Code:
ORG $1000 HI equ 5 LO equ 4 START: ; first instruction of program moveq #0,d1 move.w #-LO,d7 swap d7 move.w #-HI,d7 bsr abscmp ; set move.b d6,d1 lsl.w #1,d1 move.w #-HI,d7 swap d7 move.w #-LO,d7 bsr abscmp ; clr move.b d6,d1 lsl.w #1,d1 move.w #LO,d7 swap d7 move.w #-HI,d7 bsr abscmp ; set move.b d6,d1 lsl.w #1,d1 move.w #HI,d7 swap d7 move.w #-LO,d7 bsr abscmp ; clr move.b d6,d1 lsl.w #1,d1 move.w #-LO,d7 ; lt swap d7 move.w #HI,d7 bsr abscmp ; set move.b d6,d1 lsl.w #1,d1 move.w #-HI,d7 ; gt swap d7 move.w #LO,d7 bsr abscmp ; clr move.b d6,d1 lsl.w #1,d1 move.w #LO,d7 ; lt swap d7 move.w #HI,d7 bsr abscmp ; set move.b d6,d1 lsl.w #1,d1 move.w #HI,d7 ; lt swap d7 move.w #LO,d7 bsr abscmp ; clr move.b d6,d1 lsr.w #7,d1 SIMHALT abscmp: move.w d7,d0 swap d7 move.w d7,d6 add.w d0,d6 smi d6 sub.w d0,d7 smi d7 eor.b d7,d6 rts END START |
31 May 2021, 15:24 | #19 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 54
Posts: 4,488
|
I grab what Buzzybee wrote and give an example.
0.w = x-acceleration (<0 = move left, >0 = move right) 2.w= y-acceleration (< 0 = move up, > 0 = move down) objectListAcc dc.w a,b ;x-acceleration,y-acceleration Where b>a, generic low values, positive. set d6=0 if object moves up/down - y-acceleration>x-acceleration set d6=$ff if object moves left/right y-acceleration<x-acceleration I'm expecting in this case d6=0 because y-acceleration>x-acceleration (b>a) Now step by step in your algorithm. move.l objectListAcc(a2),d7 ; get x- and y-acceleration d7.h=a; d7.w=b move.w d7,d0 ; fetch y-acceleration in world d0.w=b move.w viewPosition+vPyAccConvertWorldToView(pc),d6 sub.w d6,d0 ; convert to y-acceleration in view we do not care of this swap d7 d7.w=a move.w d7,d6 d6.w=a add.w d0,d6 d6=a+b=positive value smi d6 d6.b=0 sub.w d0,d7 d7=a-b=negative value (as b>a) smi d7 d7.b=$FF eor.b d7,d6 d6=$00^$ff=$ff <- wrong! I don't know how else to describe it to you |
31 May 2021, 16:26 | #20 | |
Registered User
Join Date: Mar 2012
Location: Norfolk, UK
Posts: 1,157
|
Quote:
OK, in that case, switch the operands: Code:
move.l objectListAcc(a2),d7 ; get x- and y-acceleration move.w viewPosition+vPyAccConvertWorldToView(pc),d6 sub.w d6,d7 ; convert to y-acceleration in view move.w d7,d0 move.w d7,d6 swap d7 add.w d7,d6 smi d6 sub.w d7,d0 smi d7 eor.b d7,d6 Code:
move.l objectListAcc(a2),d7 ; get x- and y-acceleration move.w viewPosition+vPyAccConvertWorldToView(pc),d0 sub.w d7,d0 ; convert to y-acceleration in view swap d7 move.w d7,d6 add.w d0,d6 smi d6 sub.w d0,d7 smi d7 eor.b d7,d6 |
|
Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
Thread Tools | |
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Absolute Inebriation | heavy | project.WHDLoad | 3 | 31 January 2021 16:57 |
Absolute addressing | Old_Bob | Coders. Asm / Hardware | 9 | 20 September 2018 10:36 |
Clairvoyance by Absolute | Nibbler | request.Demos | 1 | 19 August 2018 03:41 |
Absolute beginner! | JonniR | New to Emulation or Amiga scene | 8 | 25 February 2012 21:49 |
Absolute Beginner | rick4676 | New to Emulation or Amiga scene | 3 | 11 December 2005 11:06 |
|
|