English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 08 October 2019, 08:09   #1
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 453
Blitter line mode problems

I'm trying to follow this guide http://www.winnicki.net/amiga/memmap/LineMode.html to blit a line from (9,9) to (309,117), and while it's blitting something, it's not a straight line (see attached image).

The code is as follows. It fills a structure that gets queued up, but on dequeueing the hardware registers get set in exactly the same order, so I'm confident the problem is in this code here:

Code:
static void drawLine(ScreenBuffer * screenBuffer, UWORD x1, UWORD y1, UWORD x2, UWORD y2, UWORD colour) {
    for (int i = 0; i < screenBuffer->depth; i++) {
        Blit * blit = Blitter_AquireBlit(BLIT_TYPE_LINEDRAW, (Display *) display, screenBuffer);
        if (!blit) {
            // KPrintF("Blitter queue full (3).\n");
            return;
        }

        UWORD dx = ABS((WORD) x1 - (WORD) x2);
        UWORD dy = ABS((WORD) y1 - (WORD) y2);

        UWORD octant = 0;
        if ((dx >= dy && x1 >= x2) || (dx < dy && y1 >= y2))
            octant |= AUL;
        if ((dx >= dy && y1 >= y2) || (dx < dy && x1 >= x2))
            octant |= SUL;
        if (dx >= dy)
            octant |= SUD;
KPrintF("octant = %04lx\n", octant);

        UWORD dmax = MAX(dx,dy);
        UWORD dmin = MIN(dx,dy);
        blit->registers.bltamod = 4 * dmin;
KPrintF("bltamod = %04lx\n", blit->registers.bltamod);
        blit->registers.bltbmod = 4 * (dmax - dmin);
KPrintF("bltbmod = %04lx\n", blit->registers.bltbmod);

        blit->registers.bltapt = (APTR) ((LONG) (4 * dmin - 2 * dmax) & 0x0000ffff);
KPrintF("bltapt = %08lx\n", blit->registers.bltapt);
        blit->registers.bltcon1 = LINEMODE | octant | (blit->registers.bltapt < 0 ? SIGNFLAG : 0); // always set bltcon1 before bltbdat
KPrintF("bltcon1 = %04lx\n", blit->registers.bltcon1);

        blit->registers.bltbdat = 0xffff;

        blit->registers.bltcmod = screenBuffer->width >> 3;
        blit->registers.bltdmod = screenBuffer->width >> 3;

        APTR firstWord = screenBuffer->bitMaps[i] + y1 * (screenBuffer->width >> 3) + (x1 >> 3 & 0xfffe);
        blit->registers.bltcpt = firstWord;
        blit->registers.bltdpt = firstWord;

        UWORD minterm = (colour & 1 << i) ? (ABC | ABNC | NABC | NANBC)
                                          : (ANBNC | ABNC);
KPrintF("minterm = %04lx\n", minterm);
        blit->registers.bltcon0 = x1 << 12 | SRCA | SRCC | DEST | minterm;
KPrintF("bltcon0 = %04lx\n", blit->registers.bltcon0);

        blit->registers.bltadat = 0x8000; // set this only after bltcon0

        blit->registers.bltafwm = 0xffff;
        blit->registers.bltalwm = 0xffff;

        blit->registers.bltsize = dmax * 64 + 66;
        // blit->registers.bltsize = ((dmax + 1 ) << 6) | 2;
KPrintF("bltsize = %04lx\n", blit->registers.bltsize);

        Blitter_EnqueueBlit(blit);
    }
}
The debug output is:

Code:
octant = 0010
bltamod = 01B0
bltbmod = 0300
bltapt = 0000FF58
bltcon1 = 0011
minterm = 00CA
bltcon0 = 9BCA
bltsize = 4B42
octant = 0010
bltamod = 01B0
bltbmod = 0300
bltapt = 0000FF58
bltcon1 = 0011
minterm = 0050
bltcon0 = 9B50
bltsize = 4B42
...
If anyone can spot whatever silly mistake I've made I'd be really grateful, because I've been staring at it for hours.

Ignore the green bit at the bottom, that's unrelated.
Attached Thumbnails
Click image for larger version

Name:	blit.png
Views:	67
Size:	8.1 KB
ID:	64666  

Last edited by deimos; 08 October 2019 at 10:45.
deimos is online now  
Old 08 October 2019, 13:19   #2
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,189
My values for (9,9)-(309,117):
(as usual mine is an asm optimized routine)

Code:
BLTCON0	0x9b4a
BLTCON1	0x0051
BLTAFWM	0xffff
BLTALWM	0xffff
BLTCPTx	BPLxPTx+0x0169*
BLTAPTL	0xffac
BLTDPTx	BPLxPTx+0x0169*
BLTSIZE	0x4b42
BLTCMOD	0x0028
BLTBMOD	0x00d8
BLTAMOD	0xfe80
BLTDMOD	0x0028
*I didn't bother to reset the bit0 since it's ignored and it allows me a faster routine.

Some of your values seem out.
ross is offline  
Old 08 October 2019, 13:37   #3
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 453
Quote:
Originally Posted by ross View Post
Some of your values seem out.
Thank you, having those good values to compare to will help. I think I'm rewriting from scratch.
deimos is online now  
Old 08 October 2019, 13:51   #4
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,189
Quote:
Originally Posted by deimos View Post
Thank you, having those good values to compare to will help. I think I'm rewriting from scratch.
(x1,y1/9,9) fixed, (x2,y2/309--,117--/frame)



Call me if you need other reference values.
Attached Thumbnails
Click image for larger version

Name:	output3.gif
Views:	227
Size:	16.4 KB
ID:	64669  
ross is offline  
Old 08 October 2019, 16:56   #5
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 453
Quote:
Originally Posted by ross View Post
(x1,y1/9,9) fixed, (x2,y2/309--,117--/frame)



Call me if you need other reference values.
I've re-implemented it from scratch, working from the Hardware Reference Manual, just keeping the octant calculations from the original as I'd worked through them and was comfortable they were good.

I now have a straight line.

I don't know where the problems were with the original, but now I don't really care.

[EDIT: There's at least one typo of mine.]

I'm printing out the same debug info, and I have different numbers to you in bltaptl, bltbmod and bltamod. Your values are all exactly half of mine.

Code:
BLTCON0	0x9b4a == 0x9B4A
BLTCON1	0x0051 == 0x0051
BLTAFWM	0xffff == 0xFFFF
BLTALWM	0xffff == 0xFFFF
BLTCPTx	BPLxPTx+0x0169* == 0x0001C9C0
BLTAPTL	0xffac == 0xFF58
BLTDPTx	BPLxPTx+0x0169* == 0x0001C9C0
BLTSIZE	0x4b42 == 0x4B42
BLTCMOD	0x0028 == 0x0028
BLTBMOD	0x00d8 == 0x01B0
BLTAMOD	0xfe80 == 0xFD00
BLTDMOD	0x0028 == 0x0028
I just need to work out the minterms for the bitplanes that need to be cleared instead of set, then I can move onto the next thing.

Last edited by deimos; 09 October 2019 at 13:36.
deimos is online now  
Old 08 October 2019, 17:37   #6
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,189
Quote:
Originally Posted by deimos View Post
I'm printing out the same debug info, and I have different numbers to you in bltaptl, bltbmod and bltamod. Your values are all exactly half of mine.
bltaptl, bltbmod and bltamod are closely linked.
bltamod (4Y-4X) and bltbmod (4Y) define the slope (Y/X).
bltaptl is an accumulator and must be preloaded with the initial (2Y-X).
If the values are consistent, the line is good.

Quote:
I just need to work out the minterms for the bitplanes that need to be cleared instead of set, then I can move onto the next thing.
You can notice I've used 0x4a minterm here (XOR).
If you write in the same position, line is canceled.

Instead, for a line that is always drawn, use 0xca.
ross is offline  
Old 08 October 2019, 17:42   #7
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 453
Quote:
Originally Posted by ross View Post
Instead, for a line that is always drawn, use 0xca.
This is what I'm stuck on at the moment, what should I use for the bitplanes the need the line bits cleared, so that I can do different coloured lines?

EDIT:

I think it's 0x3a, as in:

Code:
        UWORD minterm = (colour & 1 << i) ? NANBC | NABC | ABNC | ABC
                                          : NANBC | NABC | ANBNC | ANBC;

Last edited by deimos; 08 October 2019 at 18:15.
deimos is online now  
Old 08 October 2019, 18:13   #8
hooverphonique
ex. demoscener "Bigmama"

 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 991
to clear the bitplane, you need to 'and' it with the inverse of the source.
hooverphonique is offline  
Old 08 October 2019, 19:55   #9
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,189
Quote:
Originally Posted by deimos View Post
I think it's 0x3a, as in:
Yes, but some explanation is due (and a little trick).

0xca minterm is this operation: D = AB + A'C
There is two constant here: BLTBDAT as a mask for the line and BLTADAT as the 'pixel'.
Usually BLTBDAT=0xffff because you want a full line and BLTADAT(MSB)=1 because one pixel large line.

The blitter operation mean:
- for the AB part: write 1 to destination when (A and B) == 1, so everytime Bresenham's algorithms inside blitter decide is the right time to make an output.
[EDIT:
If you setup a different B mask you expect a dotted line, if you setup a different A 'pixel' you output more than one at the same time (interesting effects ).
This is right but for a different minterm, see successive messages.
Probably the minterm is often (mis-)used because is the classical bob cookie-cut (with mask in A).
But in this case suppose you have A=1,B=0,C=1, you expect D=1, but no.. so works only for mask=0xffff

]
- for the A'C part: when A=0 (no 'pixel' output) write 1 to destination if required (that is with C=1).
Result: you write a line over the background.

What you have done setting a minterm of 0x3a is reversing the mask effect or rather making A the only relevant part.
The operation is now D = AB' + A'C
If you have a B mask of 0xffff then the first operand is alway 0.
So for A'C you usually have C at output excluding when 'pixel', where you output 0 with A=1. Indirectly exactly what you want

Of course a negated 0xffff B mask is no more a mask (it's always 0) so also D = A'C works (minterm 0x0a).
And this give you the possibility to not even setup BLTBDAT because its ignored

If you want you can also use other valid combinations, I happened to use rather strange minterms in the past

Last edited by ross; 09 October 2019 at 00:07. Reason: []
ross is offline  
Old 08 October 2019, 20:59   #10
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 453
Quote:
Originally Posted by ross View Post
Of course a negated 0xffff B mask is no more a mask (it's always 0) so also D = A'C works (minterm 0x0a).
And this give you the possibility to not even setup BLTBDAT because its ignored
Ok...

Is there any advantage to not having to set up BLTBDAT apart from the initial cost of putting ones in it? And is there the equivalent for the set operation / 0xCA minterm?
deimos is online now  
Old 08 October 2019, 21:55   #11
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,189
Quote:
Originally Posted by deimos View Post
Ok...

Is there any advantage to not having to set up BLTBDAT apart from the initial cost of putting ones in it? And is there the equivalent for the set operation / 0xCA minterm?
It's not only the 'initial cost' but a constant cost if you interleave line drawing with other blitter operation that use BLTBDAT (often DMA operations).

--
I am still gathering ideas because all my blabbling on BLTBDAT made me think that many linedrawing routines work only because it's preset to 0xffff.
But they should use a different (and more correct) minterm in case of mask usage.

Please wait next message.
ross is offline  
Old 08 October 2019, 22:06   #12
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,189
Right minterm for a XOR masked linedraw:
0x6a -> D = A'C + B'C + ABC'

Right minterm for a OR masked linedraw:
0xea -> D = C + AB

Right minterm for a CLEAN masked linedraw:
0x2a -> D = A'C + B'C

Obviously it does not hurt to use these minterm also in the 0xffff mask case.

I leave them as a reference also for me and I'll correct it if necessary, actually I didn't think too much about it

Last edited by ross; 08 October 2019 at 22:55. Reason: damn, I've edited something that was right from the start :)
ross is offline  
Old 08 October 2019, 22:23   #13
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,189
Quote:
Originally Posted by deimos View Post
And is there the equivalent for the set operation / 0xCA minterm?
Sorry, I've missed this.

Yes, minterm 0xfa -> D = C + A
ross is offline  
Old 09 October 2019, 09:30   #14
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 453
Thanks,

My initial tests with

Code:
UWORD minterm = (colour & 1 << i) ? 0xfa : 0x2a;
and bltbdat set to a random constant (for testing) appear to work in that I get different coloured lines and no garbage.

I'll also slap some different background colours in as a complete test, just because it's easy.

One last line draw related question... back in '89 or so I was trying to blit lines onto interleaved bitmaps but struggled with the occasional line being wrong, there would be odd pixels of the wrong colour as if Bresenham had decided to go up or down one pixel earlier or later for some bitplanes.

I'm going to try and change my code to use interleaved bitmaps because it makes sense for other things, but can you think of any reason why line blitting won't work on what are essentially very wide bitplanes, which just the modulos changes to reflect this?
deimos is online now  
Old 09 October 2019, 11:37   #15
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,189
This:
Code:
UWORD minterm = (colour & 1 << i) ? 0xfa : 0x2a;
or this?:
Code:
UWORD minterm = (colour & 1 << i) ? 0xfa : 0x0a;
Because with 0x2a B dat value enter the equations..

Quote:
One last line draw related question... back in '89 or so I was trying to blit lines onto interleaved bitmaps but struggled with the occasional line being wrong, there would be odd pixels of the wrong colour as if Bresenham had decided to go up or down one pixel earlier or later for some bitplanes.

I'm going to try and change my code to use interleaved bitmaps because it makes sense for other things, but can you think of any reason why line blitting won't work on what are essentially very wide bitplanes, which just the modulos changes to reflect this?
Later I'll do some tests.
ross is offline  
Old 09 October 2019, 11:39   #16
deimos
Registered User

 
Join Date: Jul 2018
Location: Londonish / UK
Posts: 453
Quote:
Originally Posted by deimos View Post
I'll also slap some different background colours in as a complete test, just because it's easy.
Yeah... not working. A minterm of 0x2a does not seem to be clearing any bits.

EDIT: I think you meant 0x0a?

EDIT 2: Never mind, I think I misunderstood what you meant by "CLEAN masked linedraw".
deimos is online now  
Old 09 October 2019, 11:50   #17
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,189
Quote:
Originally Posted by ross View Post
Of course a negated 0xffff B mask is no more a mask (it's always 0) so also D = A'C works (minterm 0x0a).
And this give you the possibility to not even setup BLTBDAT because its ignored
Quote:
Originally Posted by ross View Post
Right minterm for a CLEAN masked linedraw:
0x2a -> D = A'C + B'C
Quote:
Originally Posted by ross View Post
or this?:
Code:
UWORD minterm = (colour & 1 << i) ? 0xfa : 0x0a;
Because with 0x2a B dat value enter the equations..
Quote:
Originally Posted by deimos View Post
Yeah... not working. A minterm of 0x2a does not seem to be clearing any bits.

EDIT: I think you meant 0x0a?


But I will do more tests because there is a lot of contrast online (even HRM use 0xca or 0x4a minterms and some wiki report strangeness for line draw mode..)
I've also some questions for Toni

I've never had any problems with my routine, but understanding all the cases would be better.
ross is offline  
Old 09 October 2019, 12:54   #18
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,189
Ok, questions for Toni or who can answer me.
All are related to Blitter in LINE mode.

BLTAPT act as an accumulator with initial value (4 * dy) - (2 * dx).
On HRM (and other sources) BLTAPT[H&L] is accessed as an .l register (like as if it were actually a pointer).
But if you setup only BLTAPTL as a signed 16bit value seems that is working anyway.
What's the right way?

Upper bits of BLTCON1 are called TEXTURE(0-3). Why?
From what I understand they do the same thing as the normal mode ie a shift of the content of B (BSH(0-3)).

The last question concerns the use of mask B and the 'famous' minterms 0xca and 0x4a which are used as an example for OR and XOR operations.
(and you can find them in various available blitter examples/sources)
Why talk about masks (how to setup and use) if they don't work the way they should with values <>0xffff?
(well this need some better tests that I've not had time to do )

Last edited by ross; 09 October 2019 at 13:22. Reason: []
ross is offline  
Old 09 October 2019, 17:15   #19
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 44
Posts: 23,285
Quote:
Originally Posted by ross View Post
BLTAPT act as an accumulator with initial value (4 * dy) - (2 * dx).
On HRM (and other sources) BLTAPT[H&L] is accessed as an .l register (like as if it were actually a pointer).
But if you setup only BLTAPTL as a signed 16bit value seems that is working anyway.
What's the right way?
I guess the difference is: officially documented way and how hardware actually works.

Quote:
Upper bits of BLTCON1 are called TEXTURE(0-3). Why?
From what I understand they do the same thing as the normal mode ie a shift of the content of B (BSH(0-3)).
Yes and no.

BDAT gets loaded to internal shift register, pre-shifted by TEXTURE value. Same as block mode.

The rest is different: bit 0 of shifter selects if internal BDAT (BHOLD) is FFFF (1) or 0000 (0). After each processed line pixel, shift register is shifted (rotated) by one bit. (Or shifter is re-loaded after 16 bits, same result anyway)

Line gets "textured" with 16-bit repeating pattern.

Quote:
The last question concerns the use of mask B and the 'famous' minterms 0xca and 0x4a which are used as an example for OR and XOR operations.
(and you can find them in various available blitter examples/sources)
Why talk about masks (how to setup and use) if they don't work the way they should with values <>0xffff?
(well this need some better tests that I've not had time to do )
Not enough information. Probably.
Toni Wilen is online now  
Old 09 October 2019, 18:20   #20
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,189
Quote:
Originally Posted by Toni Wilen View Post
I guess the difference is: officially documented way and how hardware actually works.


Quote:
BDAT gets loaded to internal shift register, pre-shifted by TEXTURE value. Same as block mode.

The rest is different: bit 0 of shifter selects if internal BDAT (BHOLD) is FFFF (1) or 0000 (0). After each processed line pixel, shift register is shifted (rotated) by one bit. (Or shifter is re-loaded after 16 bits, same result anyway)

Line gets "textured" with 16-bit repeating pattern.
Let's see if I really understood it
BHOLD is used because with Bresenham algorithms you could emit single pixel at a time (so you can also have different r/w operations per single word cell).
For this reason you need to 'propagate' the instantaneus BDAT bit 0 for when you apply the minterm operation (to make sure the right B bit is current despite the TEXTURE rotation).
As you said this allows in practice a textured mask along the slope and no longer per word as on bitblock.
In fact I had seen by eye that it worked this way but always interesting to understand how and why.


Quote:
Not enough information. Probably.
Yep


Thanks Toni!

Last edited by ross; 09 October 2019 at 18:28. Reason: punctuation
ross 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
Blitter line-drawing mode? E-Penguin Coders. Blitz Basic 2 13 April 2019 22:37
Blitter: clean-up line drawing and fill mode idle cycles. ross Coders. Asm / Hardware 9 12 May 2018 23:32
Blitter line mode examples? LuigiThirty Coders. Asm / Hardware 4 17 August 2017 09:26
Keep Active control panel "Line Mode" and "Interlaced Line Mode" Zilog request.UAE Wishlist 4 03 August 2014 00:08
Line mode blitter absence Coders. General 4 25 September 2009 21: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 16:58.


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