English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Language > Coders. Blitz Basic

 
 
Thread Tools
Old 13 April 2019, 18:22   #1
E-Penguin
Banana

 
Join Date: Jul 2016
Location: Darmstadt
Posts: 804
Blitter line-drawing mode?

I will be wanting to draw lots of patterned lines and the blitter can apparently do this with a special mode. I've taken the example from here: http://amigadev.elowar.com/read/ADCD.../node02DF.html

and tried to turn it into a statement. I just get a black screen (with some fiddling I got a white line but not where I expected). I suspect I'm not setting up a register properly but the details are beyond me.

Anyone got any ideas?

Code:
;d0=x1 d1=y1 d2=x2 d3=y2 d4=width
#CUSTOM=$DFF000
#DMACONR=$02+#CUSTOM
#BLTCON0=$40+#CUSTOM
#BLTCON1=$42+#CUSTOM
#BLTAFWM=$44+#CUSTOM
#BLTCPT=$48+#CUSTOM
#BLTAPT=$50+#CUSTOM
#BLTDPT=$54+#CUSTOM
#BLTSIZE=$58+#CUSTOM
#BLTCMOD=$60+#CUSTOM
#BLTBMOD=$62+#CUSTOM
#BLTAMOD=$64+#CUSTOM
#BLTDMOD=$66+#CUSTOM
#BLTCDAT=$70+#CUSTOM
#BLTBDAT=$72+#CUSTOM
#BLTADAT=$74+#CUSTOM
#DMAB_BLTDONE=14
#OCTANT8=24
#OCTANT7=4
#OCTANT6=12
#OCTANT5=28
#OCTANT4=20
#OCTANT3=8
#OCTANT2=0
#OCTANT1=16
#LINEMODE=1
#SIGNFLAG=$40

Statement drawLineBlitter{x1.w, y1.w, x2.w, y2.w, width.w}
simpleline:
        move.l  a1,a0           ; put bitplane addr in a0
        sub.w   d0,d2           ; calculate dx
        bmi     xneg            ; if negative, octant is one of [3,4,5,6]
        sub.w   d1,d3           ; calculate dy   ''   is one of [1,2,7,8]
        bmi     yneg            ; if negative, octant is one of [7,8]
        cmp.w   d3,d2           ; cmp |dx|,|dy|  ''   is one of [1,2]
        bmi     ygtx            ; if y>x, octant is 2
        moveq.l #OCTANT1+LINEMODE,d5    ; otherwise octant is 1
        bra     lineagain       ; go to the common section
ygtx:
        exg     d2,d3           ; X must be greater than Y
        moveq.l #OCTANT2+LINEMODE,d5    ; we are in octant 2
        bra     lineagain       ; and common again.
yneg:
        neg.w   d3              ; calculate abs(dy)
        cmp.w   d3,d2           ; cmp |dx|,|dy|, octant is [7,8]
        bmi     ynygtx          ; if y>x, octant is 7
        moveq.l #OCTANT8+LINEMODE,d5    ; otherwise octant is 8
        bra     lineagain
ynygtx:
        exg     d2,d3           ; X must be greater than Y
        moveq.l #OCTANT7+LINEMODE,d5    ; we are in octant 7
        bra     lineagain
xneg:
        neg.w   d2              ; dx was negative! octant is [3,4,5,6]
        sub.w   d1,d3           ; we calculate dy
        bmi     xyneg           ; if negative, octant is one of [5,6]
        cmp.w   d3,d2           ; otherwise it's one of [3,4]
        bmi     xnygtx          ; if y>x, octant is 3
        moveq.l #OCTANT4+LINEMODE,d5    ; otherwise it's 4
        bra     lineagain
xnygtx:
        exg     d2,d3           ; X must be greater than Y
        moveq.l #OCTANT3+LINEMODE,d5    ; we are in octant 3
        bra     lineagain
xyneg:
        neg.w   d3              ; y was negative, in one of [5,6]
        cmp.w   d3,d2           ; is y>x?
        bmi     xynygtx         ; if so, octant is 6
        moveq.l #OCTANT5+LINEMODE,d5    ; otherwise, octant is 5
        bra     lineagain
xynygtx:
        exg     d2,d3           ; X must be greater than Y
        moveq.l #OCTANT6+LINEMODE,d5    ; we are in octant 6
lineagain:
        mulu.w  d4,d1           ; Calculate y1 * width
        ror.l   #4,d0           ; move upper four bits into hi word
        add.w   d0,d0           ; multiply by 2
        add.l   d1,a0           ; ptr += (x1 >> 3)
        add.w   d0,a0           ; ptr += y1 * width
        swap    d0              ; get the four bits of x1
        or.w    #$BFA,d0        ; or with USEA, USEC, USED, F=A+C
        lsl.w   #2,d3           ; Y = 4 * Y
        add.w   d2,d2           ; X = 2 * X
        move.w  d2,d1           ; set up size word
        lsl.w   #5,d1           ; shift five left
        add.w   #$42,d1         ; and add 1 to height, 2 to width
        btst    #DMAB_BLTDONE-8,DMACONR     ; safety check
waitblit:
        btst    #DMAB_BLTDONE-8,DMACONR     ; wait for blitter
        bne     waitblit
        move.w  d3,BLTBMOD  ; B mod = 4 * Y
        sub.w   d2,d3
        ext.l   d3
        move.l  d3,BLTAPT   ; A ptr = 4 * Y - 2 * X
        bpl     lineover        ; if negative,
        or.w    #SIGNFLAG,d5    ; set sign bit in con1
lineover:
        move.w  d0,BLTCON0  ; write control registers
        move.w  d5,BLTCON1
        move.w  d4,BLTCMOD  ; C mod = bitplane width
        move.w  d4,BLTDMOD  ; D mod = bitplane width
        sub.w   d2,d3
        move.w  d3,BLTAMOD  ; A mod = 4 * Y - 4 * X
        move.w  #$8000,BLTADAT     ; A data = 0x8000
        moveq.l #-1,d5          ; Set masks to all ones
        move.l  d5,BLTAFWM ; we can hit both masks at once
        move.l  a0,BLTCPT   ; Pointer to first pixel to set
        move.l  a0,BLTDPT
        move.w  d1,BLTSIZE  ; Start blit
        AsmExit 				; and return, blit still in progress.
End Statement

;; GO BLITZ MODE
BLITZ
InitPalette 0,32
PalRGB 0,0,0,0,0
PalRGB 0,1,15,15,15
BitMap 0,320,256,1
InitCopList 0, $1
Use BitMap 0
BitMapOutput 0
CreateDisplay 0
DisplayPalette 0,0
DisplayBitmap 0,0

*b.bitmap = Addr BitMap(0)
GetReg d0, *b\_data[0]
move.l d0,a1 ;put the bit plane address into a1 for later
drawLineBlitter{10,10,100,100,1}

doWait.b = True
Repeat
	VWait
	If Joyb(0) > 0 Then doWait = False
Until NOT doWait
End

End
E-Penguin is online now  
Old 13 April 2019, 20:02   #2
mcgeezer
Registered User

 
Join Date: Oct 2017
Location: Sunderland, England
Posts: 1,195
Quote:
Originally Posted by E-Penguin View Post
I will be wanting to draw lots of patterned lines and the blitter can apparently do this with a special mode. I've taken the example from here: http://amigadev.elowar.com/read/ADCD.../node02DF.html

and tried to turn it into a statement. I just get a black screen (with some fiddling I got a white line but not where I expected). I suspect I'm not setting up a register properly but the details are beyond me.

Anyone got any ideas?

Code:
;d0=x1 d1=y1 d2=x2 d3=y2 d4=width
#CUSTOM=$DFF000
#DMACONR=$02+#CUSTOM
#BLTCON0=$40+#CUSTOM
#BLTCON1=$42+#CUSTOM
#BLTAFWM=$44+#CUSTOM
#BLTCPT=$48+#CUSTOM
#BLTAPT=$50+#CUSTOM
#BLTDPT=$54+#CUSTOM
#BLTSIZE=$58+#CUSTOM
#BLTCMOD=$60+#CUSTOM
#BLTBMOD=$62+#CUSTOM
#BLTAMOD=$64+#CUSTOM
#BLTDMOD=$66+#CUSTOM
#BLTCDAT=$70+#CUSTOM
#BLTBDAT=$72+#CUSTOM
#BLTADAT=$74+#CUSTOM
#DMAB_BLTDONE=14
#OCTANT8=24
#OCTANT7=4
#OCTANT6=12
#OCTANT5=28
#OCTANT4=20
#OCTANT3=8
#OCTANT2=0
#OCTANT1=16
#LINEMODE=1
#SIGNFLAG=$40

Statement drawLineBlitter{x1.w, y1.w, x2.w, y2.w, width.w}
simpleline:
        move.l  a1,a0           ; put bitplane addr in a0
        sub.w   d0,d2           ; calculate dx
        bmi     xneg            ; if negative, octant is one of [3,4,5,6]
        sub.w   d1,d3           ; calculate dy   ''   is one of [1,2,7,8]
        bmi     yneg            ; if negative, octant is one of [7,8]
        cmp.w   d3,d2           ; cmp |dx|,|dy|  ''   is one of [1,2]
        bmi     ygtx            ; if y>x, octant is 2
        moveq.l #OCTANT1+LINEMODE,d5    ; otherwise octant is 1
        bra     lineagain       ; go to the common section
ygtx:
        exg     d2,d3           ; X must be greater than Y
        moveq.l #OCTANT2+LINEMODE,d5    ; we are in octant 2
        bra     lineagain       ; and common again.
yneg:
        neg.w   d3              ; calculate abs(dy)
        cmp.w   d3,d2           ; cmp |dx|,|dy|, octant is [7,8]
        bmi     ynygtx          ; if y>x, octant is 7
        moveq.l #OCTANT8+LINEMODE,d5    ; otherwise octant is 8
        bra     lineagain
ynygtx:
        exg     d2,d3           ; X must be greater than Y
        moveq.l #OCTANT7+LINEMODE,d5    ; we are in octant 7
        bra     lineagain
xneg:
        neg.w   d2              ; dx was negative! octant is [3,4,5,6]
        sub.w   d1,d3           ; we calculate dy
        bmi     xyneg           ; if negative, octant is one of [5,6]
        cmp.w   d3,d2           ; otherwise it's one of [3,4]
        bmi     xnygtx          ; if y>x, octant is 3
        moveq.l #OCTANT4+LINEMODE,d5    ; otherwise it's 4
        bra     lineagain
xnygtx:
        exg     d2,d3           ; X must be greater than Y
        moveq.l #OCTANT3+LINEMODE,d5    ; we are in octant 3
        bra     lineagain
xyneg:
        neg.w   d3              ; y was negative, in one of [5,6]
        cmp.w   d3,d2           ; is y>x?
        bmi     xynygtx         ; if so, octant is 6
        moveq.l #OCTANT5+LINEMODE,d5    ; otherwise, octant is 5
        bra     lineagain
xynygtx:
        exg     d2,d3           ; X must be greater than Y
        moveq.l #OCTANT6+LINEMODE,d5    ; we are in octant 6
lineagain:
        mulu.w  d4,d1           ; Calculate y1 * width
        ror.l   #4,d0           ; move upper four bits into hi word
        add.w   d0,d0           ; multiply by 2
        add.l   d1,a0           ; ptr += (x1 >> 3)
        add.w   d0,a0           ; ptr += y1 * width
        swap    d0              ; get the four bits of x1
        or.w    #$BFA,d0        ; or with USEA, USEC, USED, F=A+C
        lsl.w   #2,d3           ; Y = 4 * Y
        add.w   d2,d2           ; X = 2 * X
        move.w  d2,d1           ; set up size word
        lsl.w   #5,d1           ; shift five left
        add.w   #$42,d1         ; and add 1 to height, 2 to width
        btst    #DMAB_BLTDONE-8,DMACONR     ; safety check
waitblit:
        btst    #DMAB_BLTDONE-8,DMACONR     ; wait for blitter
        bne     waitblit
        move.w  d3,BLTBMOD  ; B mod = 4 * Y
        sub.w   d2,d3
        ext.l   d3
        move.l  d3,BLTAPT   ; A ptr = 4 * Y - 2 * X
        bpl     lineover        ; if negative,
        or.w    #SIGNFLAG,d5    ; set sign bit in con1
lineover:
        move.w  d0,BLTCON0  ; write control registers
        move.w  d5,BLTCON1
        move.w  d4,BLTCMOD  ; C mod = bitplane width
        move.w  d4,BLTDMOD  ; D mod = bitplane width
        sub.w   d2,d3
        move.w  d3,BLTAMOD  ; A mod = 4 * Y - 4 * X
        move.w  #$8000,BLTADAT     ; A data = 0x8000
        moveq.l #-1,d5          ; Set masks to all ones
        move.l  d5,BLTAFWM ; we can hit both masks at once
        move.l  a0,BLTCPT   ; Pointer to first pixel to set
        move.l  a0,BLTDPT
        move.w  d1,BLTSIZE  ; Start blit
        AsmExit 				; and return, blit still in progress.
End Statement

;; GO BLITZ MODE
BLITZ
InitPalette 0,32
PalRGB 0,0,0,0,0
PalRGB 0,1,15,15,15
BitMap 0,320,256,1
InitCopList 0, $1
Use BitMap 0
BitMapOutput 0
CreateDisplay 0
DisplayPalette 0,0
DisplayBitmap 0,0

*b.bitmap = Addr BitMap(0)
GetReg d0, *b\_data[0]
move.l d0,a1 ;put the bit plane address into a1 for later
drawLineBlitter{10,10,100,100,1}

doWait.b = True
Repeat
	VWait
	If Joyb(0) > 0 Then doWait = False
Until NOT doWait
End

End

Width isn't the width of the line, it is the width of the screen you have open.

so if you have a 1 bitplane screen with a 320x200 resolution then your width should equal 40. (320/8 = 40).
mcgeezer is offline  
Old 13 April 2019, 21:37   #3
E-Penguin
Banana

 
Join Date: Jul 2016
Location: Darmstadt
Posts: 804
Ha! Thanks for that. It looks like I should RTFM more closely!

Quote:
The C and D pointer registers should be initialized to the word
containing the first pixel of the line; the C and D modulo registers
should be set to the width of the bitplane in bytes.
E-Penguin is online now  
 


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

Similar Threads
Thread Thread Starter Forum Replies Last Post
Blitter: clean-up line drawing and fill mode idle cycles. ross Coders. Asm / Hardware 9 12 May 2018 22:32
Blitter line drawing: nothing happens Crank Coders. General 21 25 April 2018 21:43
Blitter line mode examples? LuigiThirty Coders. Asm / Hardware 4 17 August 2017 08:26
Drawing a line... Lonewolf10 Coders. Tutorials 24 06 September 2011 00:46
Line mode blitter absence Coders. General 4 25 September 2009 20:50

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 22:49.


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