English Amiga Board


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

 
 
Thread Tools
Old 02 September 2015, 14:24   #1
Fell
Registered User

 
Join Date: Aug 2015
Location: UK
Posts: 15
Question In need of blitter guidance from the pros

Hi all,

I've been trying to write a blitter routine for OCS/ECS that needs to copy a rectangular section from given (x,y) coords in a 1bpl source buffer to given (x,y) coords in another 1bpl destination buffer.

The destination (x,y) pixel coords will always line on word boundaries, and the rectangle width will always be a multiple of 16, but the source coords are arbitrary; I need to be able to pick out my rectangle from the source with pixel precision.

I know I need some cunning masking/shifting but however many times I read the HRM Blitter chapter I'm just not getting it right.

The closest version I've managed is below. If I test it by stepping the source x and y coords I see that the majority of the image scrolls correctly (albeit displaying a block that's one word too far to the right in the source data), but the leftmost word is wrapping from the right. If I use a mask $0000ffff to stop that I get a blank band instead of course...

This all leads me to think I need to use another blitter channel in some way but at this point my head explodes.

Code:
SCREEN_WIDTH       equ 320
BLOCK_WIDTH        equ 64         ; Could change but will always be multiple of 16
BLOCK_HEIGHT       equ 16         ; Could change arbitrarily

; SUBROUTINE: Blit a block with dimensions
; BLOCK_WIDTH x BLOCK_HEIGHT, from pix coords (d4,d3) 
; in a bitplane starting at a1, to pix coords in (d0,d1) 
; in a bitplane starting at a0. Destination coords d0,d1
; will always be on a word boundary; d4,d3 won't!
BlitBlock:
    ; Find source address to nearest preceeding word boundary
    mulu.w #SCREEN_WIDTH/8,d3    ; d3 = sourceY * screenwidth width in bytes
    add.l d3,a1                  ; a1 += d3
    move.w d4,d6                 ; d6 = backup sourceX
    lsr.w #3,d4                  ; d4 = sourceX / 8
    and.w #$fffe,d4              ; clear lsb
    add.w d4,a1                  ; a1 = source address to nearest word, still needs shift tho!
    
    ; Find source shift
    and.w #$f,d6                 ; Just select 4 lowest bits of source x....
    move.w #$f,d5
    sub.w d6,d5
    lsl.w #8,d5                  ; ...and shift em up 12 so they're 4 highest bits
    lsl.w #4,d5
    or.w #$09f0,d5               ; Combine with the A->D minterm shiznaz
    
    ; Find destination address
    mulu.w #SCREEN_WIDTH/8,d1
    add.l d1,a0
    lsr.w #3,d0
    and.w #$fffe,d0
    add.w d0,a0                  ; a0 = dest address (will always be a word boundary)
    
    ; Blit it like Boris!
    WAIT_BLIT
    move.w d5,$40+_CB            ; BLTCON0: A->D copy, with A shift from above, ascending mode
    move.w #0,$42+_CB            ; BLTCON1
    move.l #$ffffffff,$44+_CB    ; BLTAFWM and BLTALWM: No masks
    move.w #SCREEN_WIDTH/8-BLOCK_WIDTH/8,$64+_CB     ; BLTAMOD: Src A mod = effect width in bytes - blit width in bytes
    move.w #SCREEN_WIDTH/8-BLOCK_WIDTH/8,$66+_CB     ; BLTDMOD: Dest D mod = as per A
    move.l a1,$50+_CB            ; BLTAPT: Src A origin (top-left)
    move.l a0,$54+_CB            ; BLTDPT: Dest D origin (top-left)
    move.w #BLOCK_HEIGHT*64+BLOCK_WIDTH/16,$58+_CB    ; BLTSIZE: height*64 + width in words -- Blit it, Boris
    
    rts
Sorry about the non-consecutive register usages in the code, if it's too hard to read I can refactor it.

I can find decent sample code for the kinda inverse situation of bobs, where the source coords are nice and word-aligned but the destination is arbitrary, but haven't seen a clear example of the way round I want to do it.

At head-meets-wall point; any hints / tips / code / spoonfeeding would be massively appreciated!
Fell is offline  
Old 02 September 2015, 16:11   #2
ReadOnlyCat
Code Kitten

 
Join Date: Aug 2015
Location: Montreal/Canadia
Age: 48
Posts: 1,174
Since you are using pixel coordinates for the source you must set a different start and end mask for each blit.

Just picture on paper the different transfers and operations the blitter does on the sources and it will be simpler.

It is almost impossible to solve a problem if you do not have a clear mental model of the system so it's always a good idea to simulate the thing on paper first.
ReadOnlyCat is offline  
Old 02 September 2015, 19:28   #3
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,265
You have to extend the blit by one extra word, use (X-1) as the X source coordinate, calculate the A source shift as (-X) mod 16, and move the destination pointer one word to the left.

A side-effect of this is that you also mess up the 16 pixel wide column just to the left of your rectangle, it becomes a scratch area of sorts, so you have to blit from right to left when drawing your screen, and of course allocate space for a margin outside the left edge of your screen. You can also use descending mode when blitting to move this scratch area to the right hand side.

If you want to avoid the above, then you have to use a third channel when blitting, acting as a mask, resulting in a 50% extra cost for all blitting.
Leffmann is offline  
Old 02 September 2015, 19:55   #4
ReadOnlyCat
Code Kitten

 
Join Date: Aug 2015
Location: Montreal/Canadia
Age: 48
Posts: 1,174
yikes.
No mask needed because the destination is 16 bit aligned.
Was clearly not awake when I wrote that.

So much for my remark about a clear mental model.
ReadOnlyCat is offline  
Old 02 September 2015, 20:24   #5
Fell
Registered User

 
Join Date: Aug 2015
Location: UK
Posts: 15
Leffmann, I think that's exactly what I needed, thanks I think in my use-case I can deal with drawing the screen right-to-left too to avoid needing to bring in another channel.

I'll have a fiddle and see how I get on.

ReadOnlyCat, indeed, much graph paper expended here!
Fell is offline  
Old 02 September 2015, 20:42   #6
Fell
Registered User

 
Join Date: Aug 2015
Location: UK
Posts: 15
Yay, it works great!! Brill, thanks Leffmann

Last edited by Fell; 02 September 2015 at 21:39. Reason: typo
Fell 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
Need some price guidance dirkies MarketPlace 4 03 August 2015 12:41
Blitter busy flag with blitter DMA off? NorthWay Coders. Asm / Hardware 9 23 February 2014 21:05
Upgrading KS/WB on an A500 - pros and cons? AB Positive New to Emulation or Amiga scene 5 14 May 2009 20:33
TinyMeter pros: help! Mojo2000 New to Emulation or Amiga scene 0 02 February 2003 00:37
Need Guidance Now!!! NytroX86 support.Hardware 19 21 December 2002 00:30

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:30.


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