English Amiga Board


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

 
 
Thread Tools
Old 20 November 2019, 22:10   #1
geldo79
Registered User
geldo79's Avatar
 
Join Date: Oct 2019
Location: Eydelstedt / Germany
Age: 39
Posts: 32
why does my setPixel method not work correctly?

Hi,

Who can tell me what's wrong with my method? It works, but only for lines < 187. Ok, I think in principle i know whats wrong: each lines consists of 44 Bytes in my case (16 Pixel hidden space on each side), and i use interleaved bitplanes (4 bitplanes). Thus, i have to multiply y by 4x44 = 176 to get the correct offset. At line 186, this gives 176x186 = 32736. At line 187, the value is more than word size. But, i use longwords. So what's wrong?

SetPixel:

* d0 : x
* d1 : y

move.l BITPLANE,a0
add.w #2,a0
divu #8,d0
mulu.w #4*44,d1

add.l d0,d1
Swap d0
Move.b #-1,d2
Sub.b d0,d2
move.w #3,d3

plane_loop:

bset d2,(a0,d1)
add.w #44,d1
dbra d3,plane_loop

rts
geldo79 is offline  
Old 20 November 2019, 22:15   #2
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 489
I don't think you're specifying that you're using longs:

bset d2,(a0,d1)

might need to be:

bset d2,(a0,d1.L)
deimos is offline  
Old 20 November 2019, 22:21   #3
Galahad/FLT
Going nowhere

Galahad/FLT's Avatar
 
Join Date: Oct 2001
Location: United Kingdom
Age: 46
Posts: 7,326
Your error is to do with your division.

You haven't allowed for your DIVU to have a remainder in the high word of D0.

If your number divides equally with no remainder, your add.l d0,d1 will be ok.

If your number has a remainder, your add.l d0,d1 will NOT be ok, because you will be essentially adding a really big longword instead (it will interpret the remainder as a memory address)
Galahad/FLT is offline  
Old 21 November 2019, 10:20   #4
meynaf
son of 68k
meynaf's Avatar
 
Join Date: Nov 2007
Location: Lyon / France
Age: 46
Posts: 3,620
Your routine would be better written this way :
Code:
move.l BITPLANE,a0
addq.w #2,a0
moveq #-1,d2
sub.b d0,d2
lsr.l #3,d0
mulu.w #4*44,d1
add.l d0,d1
add.l d1,a0

moveq #3,d3

plane_loop:

bset d2,(a0)
add.w #44,a0
dbra d3,plane_loop

rts
There were 3 errors in your code :
- as said, (a0,d1) instead of (a0,d1.l)
- as said, remainder of divu
- and a nice time bomb : add.w #44,d1 instead of add.l #44,d1
meynaf is offline  
Old 21 November 2019, 11:06   #5
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,239
Or to be picky
Code:
moveq #3,d3

plane_loop:

bset d2,(a0)
lea 44(a0),a0
dbra d3,plane_loop

rts
16 cycles less on 68k
ross is online now  
Old 21 November 2019, 15:56   #6
Cyprian
Registered User

 
Join Date: Jul 2014
Location: Warsaw/Poland
Posts: 36
Instead of that:
Code:
moveq #3,d3

plane_loop:

bset d2,(a0)
lea 44(a0),a0
dbra d3,plane_loop
faster one:
Code:
bset d2,(a0)
bset d2,44(a0)
bset d2,88(a0)
bset d2,132(a0)
Cyprian is offline  
Old 21 November 2019, 16:51   #7
Exodous
Registered User

 
Join Date: Sep 2019
Location: Leicester / England
Posts: 9
Divides and multiplies are also quite slow. I can't remember the cycle timings off the top of my head, but you would replace:

Code:
	divu #8,d0		; Divide by 8 is shift 3 places right
with

Code:
	moveq.l	#7,d3
	and.l	d0,d3		; d3 = remainder for use later
	asr.l	#3,d0		; d0 = d0 / 8
You need to use the remainder in d3 lower down to calculate the bit to set.


Code:
	mulu.w #4*44,d1
Is probably quicker re-written as shifts and adds like:

Code:
	asl.l	#4,d1		; d1 = 'y' * 16
	add.l	d1,a0		; add *16
	add.l	d1,a0		; add *16
	add.l	d1,a0		; add *16
	asl.l	#3,d1		; d1 = 'y' * 128
	add.l	d1,a0		; add *128
	add.l	d0,a0		; a0 now points to the first memory address
Exodous is offline  
Old 21 November 2019, 23:02   #8
geldo79
Registered User
geldo79's Avatar
 
Join Date: Oct 2019
Location: Eydelstedt / Germany
Age: 39
Posts: 32
Ok.....think i got it. Thanks! But another question: if i want to set a complete Byte to 1 (white), why can't i use

move.b $FF,(a0,d1.l)

instead of

bset d2,(a0,d1.l).

It does not crash, but it's drawing some pixels white, and some pixels black. I don't understand that. And if i use instead

move.w $FFFF,(a0,d1.l)

or

move.l $FFFFFFFF,(a0,d1.l)

my program crashes. Why?
geldo79 is offline  
Old 21 November 2019, 23:21   #9
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,239
This:
Quote:
Originally Posted by geldo79 View Post
move.b $FF,(a0,d1.l)
or in a more compact form:
Quote:
st (a0,d1.l)
set 8 consecutive pixels but only on one plane.
If you have four plane you need to do four of this instructions, a write for every plane (and color 15 is then used).


This:
Quote:
move.w $FFFF,(a0,d1.l)
or
move.l $FFFFFFFF,(a0,d1.l)
EDIT: sure a word/longword read from an odd memory address,
but for the intended immediate form (#$) could also end up to a word/longword write to an odd memory address, depending on d1.l value.
Both crash on bare 68k processor.

Last edited by ross; 22 November 2019 at 00:36.
ross is online now  
Old 22 November 2019, 00:10   #10
geldo79
Registered User
geldo79's Avatar
 
Join Date: Oct 2019
Location: Eydelstedt / Germany
Age: 39
Posts: 32
Ok. But

move.b $FF,(a0,d1.l)

and

st (a0,d1.l)

doesn't do the same Only the second method does what i want.
geldo79 is offline  
Old 22 November 2019, 00:13   #11
Don_Adan
Registered User
 
Join Date: Jan 2008
Location: Warsaw/Poland
Age: 51
Posts: 1,173
Quote:
Originally Posted by geldo79 View Post
Ok. But

move.b $FF,(a0,d1.l)

and

st (a0,d1.l)

doesn't do the same Only the second method does what i want.
No, your code is buggy.
You must use
Move.b #$ff, (a0,d1.l)
Don_Adan is offline  
Old 22 November 2019, 00:17   #12
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,239
Thanks Don.

@geldo79, of course I meant #$ff for the st equivalency
$ff is a memory location.

Last edited by ross; 22 November 2019 at 00:41. Reason: sorry Don, I called you Dan :) I am sleepy ;)
ross is online now  
Old 22 November 2019, 00:40   #13
geldo79
Registered User
geldo79's Avatar
 
Join Date: Oct 2019
Location: Eydelstedt / Germany
Age: 39
Posts: 32
Ooops....yes, of course!
geldo79 is offline  
Old 22 November 2019, 11:49   #14
hooverphonique
ex. demoscener "Bigmama"

 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,001
Quote:
Originally Posted by geldo79 View Post
And if i use instead

move.w $FFFF,(a0,d1.l)

or

move.l $FFFFFFFF,(a0,d1.l)

my program crashes. Why?

$FFFF/$FFFFFFFF are odd addresses - you can only access even addresses with word or longword size.
As mentioned above, you probably meant #$FFFF, but even then it would crash if a0+d1 is odd.

on 68020+ odd addressing for word/long is allowed.
hooverphonique is offline  
Old 22 November 2019, 14:16   #15
geldo79
Registered User
geldo79's Avatar
 
Join Date: Oct 2019
Location: Eydelstedt / Germany
Age: 39
Posts: 32
Ok. So, my next question is : If i would like to set a graphic of 3x3 pixel size, how can I set it properly if it overlaps two bytes? Of course, i could calculate the fraction which is in the first byte and set it, and calculate the fraction for the second byte and set it. But is there an easier way to do it? Would be nice if i could just set a word, and if the shift to e.g. the right side is big enough to show the graphic completely on the next byte, i would set the word on the next byte location. But this is not allowed it it is an odd number.....
geldo79 is offline  
Old 22 November 2019, 14:47   #16
DanScott
Lemon. / Core Design

DanScott's Avatar
 
Join Date: Mar 2016
Location: Sunny Bournemouth, UK
Posts: 480
you could store your 3 pixel wide data in a low word of a data register, shifted to the pixel position

and then:

move.b d0,1(a0)
ror.w #8,d0
move.b d0,0(a0)

a0 can point to an odd address then
DanScott is offline  
Old 22 November 2019, 15:05   #17
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 489
Quote:
Originally Posted by geldo79 View Post
Ok. So, my next question is : If i would like to set a graphic of 3x3 pixel size, how can I set it properly if it overlaps two bytes? Of course, i could calculate the fraction which is in the first byte and set it, and calculate the fraction for the second byte and set it. But is there an easier way to do it? Would be nice if i could just set a word, and if the shift to e.g. the right side is big enough to show the graphic completely on the next byte, i would set the word on the next byte location. But this is not allowed it it is an odd number.....
You can do byte accesses to memory at any address. On a 68000 words accesses always need to be aligned to an even address. On 68020 or higher this restriction is lifted, but comes with a performance penalty (2 memory accesses). Access to memory is always according to the width of the bus. Probably oversimplified, but whatever.

No matter whether you access memory 8, 16, 32 bits at a time, you will have to account for your objects wrapping past the edge of your words. For such small objects I would consider pre-calculating the shifts across a word - there's only 16 of them, and only 2 of them involve overlapping into a second word.

Edit: You'd probably get some savings by making your objects 4x4, even if you never used that last pixel.

Last edited by deimos; 22 November 2019 at 18:09.
deimos is offline  
Old 23 November 2019, 19:24   #18
geldo79
Registered User
geldo79's Avatar
 
Join Date: Oct 2019
Location: Eydelstedt / Germany
Age: 39
Posts: 32
I'll try to precalculate. But at the moment, I wonder if my project is possible on the amiga. I try to code some spacewar like game. My spaceship is a sprite....and it moves very smoothly. But now as i try to implement the shooting mechanism of the ship, it seems to be difficult to keep the game speed at the actual level. Problem is that every laser cannon bob (or at least graphic object...not sure if i will use the blitter or cpu) has to be updated concerning its position for every frame. Up to now, the cpu does not seem to be able to calculate everything in time. I use a bresenham algorithm to calculate the positions. And in order to be able to detect collisions, i do an update pixel by pixel. Otherwise i could increase or decrease x or y of the bob by a larger amount (depending on its speed), but then collision detection will be difficult. Its a bit frustrating at the moment.
geldo79 is offline  
Old 24 November 2019, 08:30   #19
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 489
Quote:
Originally Posted by geldo79 View Post
Up to now, the cpu does not seem to be able to calculate everything in time. I use a bresenham algorithm to calculate the positions. And in order to be able to detect collisions, i do an update pixel by pixel. Otherwise i could increase or decrease x or y of the bob by a larger amount (depending on its speed), but then collision detection will be difficult. Its a bit frustrating at the moment.
I think you should consider changing your approach, calculate positions, physics, collisions, etc. at whatever accuracy is needed and using line intersections, bounding boxes, etc. for efficiency, then convert to screen resolution to draw as a separate step.
deimos 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
Millennium 2.2 doesn't work correctly in WinUAE Nicko support.WinUAE 8 30 January 2011 13:47
ADF to Disk doesn't work correctly Doomman2008 support.Hardware 17 11 October 2010 17:04
New imaging method? Pheonix request.Apps 2 27 August 2009 06:41
Best capture method DJ_OXyGeNe_9 project.Amiga Demo DVD 16 12 May 2009 00:28

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 23:28.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2019, vBulletin Solutions Inc.
Page generated in 0.08860 seconds with 15 queries