English Amiga Board


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

 
 
Thread Tools
Old 15 January 2021, 18:09   #1
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
Blitter Restore Artefacts

Hello Amiga Coders!

Long time no see, hope you're all well!

So I've been getting back to my ASM after a good 4 or 5 months off to rest my brain, and I've jumped straight into where I left off: the blitter.

The last time I looked at it, I had some nifty code from roondar to get my minterms setup correctly so I could cookie cut and move my bob around in 1 pixel increments:

Code:
*******************************************************************************
* BlitterControl
*   -
*
*   - trashes: a1
*   - input: d0 - x position
*   - return: d0 - shifted x position, d6 - calculated BLTCON0/1
*

BlitterControl:
  movem.l a1,-(sp)

  lea.l	BlitterMinTerms,a1
  moveq	#15,d6            ; calculate shift for x position
  and.w	d0,d6             ; calculate shift for x position
  add.w	d6,d6
  add.w	d6,d6			        ; d6 = offset into bltcon table
  move.l 0(a1,d6),d6		  ; d6 = BLTCON0/1

  asr.w	#3,d0             ; shifted x position

  movem.l (sp)+,a1
  rts

*******************************************************************************
* BLTCON table for bob minterms/shifts (base tables)
*******************************************************************************

BlitterMinTerms:
  dc.l	$0fca0000,$1fca1000,$2fca2000,$3fca3000
  dc.l	$4fca4000,$5fca5000,$6fca6000,$7fca7000
  dc.l	$8fca8000,$9fca9000,$afcaa000,$bfcab000
  dc.l	$cfcac000,$dfcad000,$efcae000,$ffcaf000
The actual bob movement code looked something like this (this is my dodgy code by the way, just incase you spot anything wrong):

Code:
UpdatePlayer:
  movem.l d0-d7/a0-a4,-(sp)

  lea Player,a0                                                                 ; graphic
  lea PlayerMask,a1                                                             ; mask
  move.l DrawBuffer,a2                                                          ; destination

  move.l #80,d0                                                                 ; x position
  move.l #84,d1                                                                 ; y position

  lea scrollData,a3
  sub.b scrollCounterX(a3),d0

  bsr BlitterControl                                                            ; d6 = BLTCON0/1

  mulu #BytesAllBitplaneLines,d1                                                ; buffer offset
  add.l d0,d1                                                                   ;
  add.l d1,a2                                                                   ;

  bsr WaitBlitter

  move.l d6,BLTCON0(a6)
  move.l #$ffffffff,BLTAFWM(a6)
  move.w #BobSourceModulo,BLTAMOD(a6)
  move.w #BobSourceModulo,BLTBMOD(a6)
  move.w #BobDestinationModulo,BLTCMOD(a6)
  move.w #BobDestinationModulo,BLTDMOD(a6)
  move.l a1,BLTAPTH(a6)                         ; mask
  move.l a0,BLTBPTH(a6)	                        ; graphic
  move.l a2,BLTCPTH(a6)                         ; destination buffer
  move.l a2,BLTDPTH(a6)                         ; destination buffer
  move.w #BobVerticalSize,BLTSIZV(a6)
  move.w #BobHorizontalSize,BLTSIZH(a6)

  movem.l (sp)+,d0-d7/a0-a4
  rts
The result looks like this left hand picture below (ignore the sprite mess at the bottom, that's for another day). I expected this result though, no restore.



So today I tried some different approaches and changed the BLTCPTH to point to my ViewBuffer from the double buffering setup. The result looks like the right picture above.

It looks like I'm getting somewhere, and I'm assuming that the blitter is automatically handling all of the copy/restore etc. That's how it works right? Or have I just lucked out here?

Anyway, the problem I'm asking about here is that there are small artefacts being left behind when I move. I've highlighted them with red circles here.

Would that be a result of my fluke restore solution, or is it because it's being shifted with the BlitterControl function?

As always, thanks for any help you can throw my way
DanielAllsopp is offline  
Old 15 January 2021, 21:53   #2
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,410
Quote:
Originally Posted by DanielAllsopp View Post
It looks like I'm getting somewhere, and I'm assuming that the blitter is automatically handling all of the copy/restore etc. That's how it works right? Or have I just lucked out here?
You have lucked out
The Blitter does nothing automatically, you'll have to deal with restoring the background yourself.
roondar is offline  
Old 15 January 2021, 23:11   #3
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
Quote:
Originally Posted by roondar View Post
You have lucked out
The Blitter does nothing automatically, you'll have to deal with restoring the background yourself.
Yeah, I feared as much. Any quick pointers for me to have a look at so I can figure it out?
DanielAllsopp is offline  
Old 16 January 2021, 15:12   #4
pink^abyss
Registered User
 
Join Date: Aug 2018
Location: Untergrund/Germany
Posts: 408
Quote:
Originally Posted by DanielAllsopp View Post
Yeah, I feared as much. Any quick pointers for me to have a look at so I can figure it out?

The two common approaches are

1. save the background behind your BOB before drawing into it, and then restore it after it has been displayed and before drawing again into it
2. have another copy of your background (additional to your double buffers) and restore from there. This is faster because you don't need to save the background in the first place.

hope this helps
pink^abyss is offline  
Old 16 January 2021, 16:09   #5
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
Quote:
Originally Posted by pink^abyss View Post
The two common approaches are

1. save the background behind your BOB before drawing into it, and then restore it after it has been displayed and before drawing again into it
2. have another copy of your background (additional to your double buffers) and restore from there. This is faster because you don't need to save the background in the first place.

hope this helps
So multiple blitter uses then. A -> D restore from previous frame, A -> D copy of background, blit bob. And repeat?

There’s nothing behind my current bob, it’s a copper rainbow of colour 0 and multiplexed sprites so in essence, the background is blank.
DanielAllsopp is offline  
Old 16 January 2021, 16:13   #6
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,410
If your background is guaranteed to be blank at all times, you can get by with just clearing the rectangle the object occupies before blitting instead of using a 'true' restore.
roondar is offline  
Old 16 January 2021, 16:28   #7
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
Quote:
Originally Posted by roondar View Post
If your background is guaranteed to be blank at all times, you can get by with just clearing the rectangle the object occupies before blitting instead of using a 'true' restore.
Ok I’ll give that a go. Can I just ask what the different BLTCPTH and BLTDPTH are for then? Should they always just point to the same destination buffer?

I think I get most of the theory, I just need to wrap my head around how and why the Amiga does it.
DanielAllsopp is offline  
Old 16 January 2021, 16:36   #8
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,410
The different Blitter pointers are what defines where in memory the sources and the destination are. The Blitter has three sources and one destination. The sources are channels A,B & C. The destination is channel D.

Depending on the type of blit, you can need any combination of these 4 channels to make it work.
  • A standard copy blit will use two channels: one of the sources (usually A is used) and the destination (D).
  • A standard cookie-cut blit will use all of the channels (A,B,C & D)
  • A clear bit will only use the D channel (set BLTADAT to a 16 bit pattern you want to use - usually this will be $0000)
There's a bunch of details regarding performance (some channel combinations are less efficient than others), but in general using the 'lowest' channels will be best for performance (meaning a AD copy blit is faster than a BD copy blit).

Edit: the reason that in a cookie-cut blit C & D point to the same address is that the blit needs to use the destination area as part of it's source (this is where it'll cut out the background and insert the shape you're blitting).
roondar is offline  
Old 16 January 2021, 16:45   #9
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
Perfect, that’s explained it. I’ll post some results soon. Thanks roondar.
DanielAllsopp is offline  
Old 22 January 2021, 21:53   #10
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
So I finally figured some stuff out with everyone's help, a lot of searches and a lot of trial and error:



I do find it satisfying when things start working, instead of just having someone do the work for me, so much appreciated for the hints

Off the back of that work, I do have some questions though:

1. My clear blitter routine uses #$01000000 for BLTCON0 and nothing else, but is BLTCON0/1 also used for the x position shift to allow 1 pixel accurate movement?

2. Are bsr calls efficient? When I'm detecting joystick movement, I'm calling a sub-routine to update the player position within the player.s source file. Would it be more efficient to update the data structure directly rather than have a modular approach?

Thanks for any help as usual!

Daniel
DanielAllsopp is offline  
Old 22 January 2021, 22:00   #11
jotd
This cat is no more
 
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,170
bsr is only useful if you call your routine from more than one location.

It's also good for readability... the bigger your routine is, the lower the overhead (using stack to store return address and jump back isn't a big overhead, compared to traps for instance)

your animation is looking good already
jotd is offline  
Old 22 January 2021, 22:27   #12
DanielAllsopp
Registered User
 
DanielAllsopp's Avatar
 
Join Date: Feb 2018
Location: Northumberland, UK
Posts: 272
Quote:
Originally Posted by jotd View Post
bsr is only useful if you call your routine from more than one location.

It's also good for readability... the bigger your routine is, the lower the overhead (using stack to store return address and jump back isn't a big overhead, compared to traps for instance)

your animation is looking good already
Thanks for the info. I do call it only once, but I guess I try to keep everything modular due to working with OOP all day.

I'm sure I'll be able to optimise things better when I'm finished with what I'm doing.
DanielAllsopp is offline  
Old 22 January 2021, 22:37   #13
DanScott
Lemon. / Core Design
 
DanScott's Avatar
 
Join Date: Mar 2016
Location: Tier 5
Posts: 1,212
Quote:
Originally Posted by DanielAllsopp View Post
Thanks for the info. I do call it only once, but I guess I try to keep everything modular due to working with OOP all day.

I'm sure I'll be able to optimise things better when I'm finished with what I'm doing.
you might want to search for "68000 instruction timings" to get a better idea of what various things will incur in cycle costs
DanScott is offline  
Old 22 January 2021, 22:39   #14
DanScott
Lemon. / Core Design
 
DanScott's Avatar
 
Join Date: Mar 2016
Location: Tier 5
Posts: 1,212
Quote:
Originally Posted by DanielAllsopp View Post
1. My clear blitter routine uses #$01000000 for BLTCON0 and nothing else, but is BLTCON0/1 also used for the x position shift to allow 1 pixel accurate movement?

#$01000000 for BLTCON0 is only enabling the D channel, so you have no data in A or B to shift
DanScott is offline  
Old 22 January 2021, 22:41   #15
roondar
Registered User
 
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,410
Quote:
Originally Posted by DanScott View Post
you might want to search for "68000 instruction timings" to get a better idea of what various things will incur in cycle costs
http://oldwww.nvg.ntnu.no/amiga/MC68...000timing.HTML


roondar 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
[Restore]Amiga 1200 Kwizoke restore (if possible) blog... Mr. Trog support.Hardware 9 02 September 2020 21:44
Indivision ECS issues (artefacts, flickering & flashing) Xanthe support.Hardware 2 20 April 2017 20:25
Grapical artefacts on the left-hand side only Foebane support.WinUAE 2 11 August 2016 17:09
Indivision MK2cr; corrupt picture/artefacts at higher resolutions Tommelom support.Hardware 22 30 October 2015 20:59
Odd artefacts when turning on A1200 manic23 support.Hardware 11 11 November 2014 21:19

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 17:51.

Top

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