English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 22 October 2019, 17:50   #81
sandruzzo
Registered User
 
Join Date: Feb 2011
Location: Italy/Rome
Posts: 1,779
I'll try to expande my demo, and do polygon filling via "copper-blitter"...
sandruzzo is offline  
Old 22 October 2019, 21:35   #82
deimos
Registered User

 
Join Date: Jul 2018
Location: France
Posts: 545
Copper Blitter Queue Lists - Update

An update - just so that no one thinks I've given up.

I have written a copper blitter queue system and reworked all my graphics primitive functions to generate copper instructions. I now have to rework my triple buffer code so that everything stays in sync and I'm never overwriting a copper blitter queue list that's currently being processed. Once I've done that I should be able to give another update with frame rates for comparison.

I still don't know how I'm going to work in a copper based split screen with the blitter queue stuff, but I don't think it's impossible.
deimos is offline  
Old 23 October 2019, 13:44   #83
deimos
Registered User

 
Join Date: Jul 2018
Location: France
Posts: 545
For anyone who stayed up all night hoping for an update - see attached screenshots.

I have the copper blitter queue list working to the point where it will draw a few frames before glitched start appearing, then a few frames later it bombs completely.
Attached Thumbnails
Click image for larger version

Name:	copper-glitch.png
Views:	111
Size:	9.0 KB
ID:	64889   Click image for larger version

Name:	copper-crash.png
Views:	96
Size:	12.2 KB
ID:	64890  
deimos is offline  
Old 23 October 2019, 13:57   #84
phx
Natteravn

phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 1,599
You overwrote your copper list with a bad blitter operation? Does the copper list reside near the bitplanes in memory? Are you sure clipping works well?

When debugging with UAE:
1. Use the o (o1?) command to view the active copper list and look what has changed.
2. Maybe set a watchpoint (w) for your copper list to detect the moment it is destroyed. (Do UAE-watchpoints work for DMA as well? Not sure.)
phx is offline  
Old 23 October 2019, 14:48   #85
deimos
Registered User

 
Join Date: Jul 2018
Location: France
Posts: 545
Quote:
Originally Posted by phx View Post
You overwrote your copper list with a bad blitter operation? Does the copper list reside near the bitplanes in memory? Are you sure clipping works well?

When debugging with UAE:
1. Use the o (o1?) command to view the active copper list and look what has changed.
2. Maybe set a watchpoint (w) for your copper list to detect the moment it is destroyed. (Do UAE-watchpoints work for DMA as well? Not sure.)
Not certain, but it looks like I needed more space for the copper lists I'm creating, apparently I wrote past the end of the buffer.

I'm running in the bartman gcc 8.3 environment at the moment, so I don't think I have the UAE debugger available, and I can't get much from the debugger I have, so I'll have to do it the old fashioned way, with printf.

Anyway, right now I still have glitches, but the code runs through my 100 frame test, so hopefully it will come together. I have some interesting art over my shell window when the program exits.
Attached Thumbnails
Click image for larger version

Name:	dots.png
Views:	70
Size:	10.2 KB
ID:	64891  
deimos is offline  
Old 23 October 2019, 14:49   #86
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,719
The UAE debugger is part of WinUAE, it does not depend on which compiler you use
roondar is offline  
Old 23 October 2019, 14:52   #87
deimos
Registered User

 
Join Date: Jul 2018
Location: France
Posts: 545
Quote:
Originally Posted by roondar View Post
The UAE debugger is part of WinUAE, it does not depend on which compiler you use
Maybe, but shift-F12 now brings up the debugger in VS Code.

Is there another way to get to it?
deimos is offline  
Old 23 October 2019, 14:55   #88
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,719
Ahh, I'm sorry. I didn't understand that was the way it worked.
Well, I do think there's a WinUAE command line option to start the debugger. But I don't know what it is
roondar is offline  
Old 23 October 2019, 15:12   #89
deimos
Registered User

 
Join Date: Jul 2018
Location: France
Posts: 545
Quote:
Originally Posted by deimos View Post
I have some interesting art over my shell window when the program exits.
Is it possible that the trick of setting BLTDPT to a scratch buffer in order to not draw the first dot of a line could not work when starting the blitter from a copper list?

Code:
    BLIT_INSTR(BLTCPTH, HIGH_WORD(firstWord))
    BLIT_INSTR(BLTCPTL, LOW_WORD(firstWord))
    BLIT_INSTR(BLTDPTH, HIGH_WORD(scratchBufferB))
    BLIT_INSTR(BLTDPTH, LOW_WORD(scratchBufferB))
I'm 90% certain that those are the dots, but I've checked that the value of scratchBufferB above is correct and hasn't been changed.
Attached Thumbnails
Click image for larger version

Name:	dots.png
Views:	45
Size:	10.2 KB
ID:	64893  
deimos is offline  
Old 23 October 2019, 15:40   #90
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,456
BLIT_INSTR(BLTDPTH, LOW_WORD(scratchBufferB))
ross is online now  
Old 23 October 2019, 15:56   #91
deimos
Registered User

 
Join Date: Jul 2018
Location: France
Posts: 545
Quote:
Originally Posted by ross View Post
BLIT_INSTR(BLTDPTH, LOW_WORD(scratchBufferB))
Gosh, that's embarrassing.

Anyhoo, that's fixed the dots, but I'm still getting weirdness, as if blits were being missed, that gets worse the longer the code runs for, so I'm still bug hunting.
deimos is offline  
Old 24 October 2019, 10:50   #92
deimos
Registered User

 
Join Date: Jul 2018
Location: France
Posts: 545
Copper Blitter Queue Lists - Working

My copper blitter queue list now works, at least for the simple, non split-screen, case, and I've been able to get some timings to compare with my two other blitter queue systems.

I'm going to continue to work on the split-screen case, and to fix a couple of bodges I've put in.
deimos is offline  
Old 24 October 2019, 20:40   #93
deimos
Registered User

 
Join Date: Jul 2018
Location: France
Posts: 545
Quote:
Originally Posted by deimos View Post
...and to fix a couple of bodges I've put in.
I've been trying to fix this for 8 hours now, time to beg for help.

My copper list sets cop1lc to point to the start of a loop, then jumps to a blitter subroutine pointed to by cop2lc. This subroutine sets cop2lc to point to the next blitter subroutine to execute, starts the blitter, and returns to the start of the loop by jumping to cop1lc.

This much I've basically copied from an example given by ross (http://eab.abime.net/showpost.php?p=...5&postcount=19).

The last blitter subroutine sets cop2lc to point to a subroutine that just "0xffff, 0xfffe" sleeps forever / never returns, then triggers a COPER interrupt before itself going to sleep and not returning.

The COPER interrupt sets a status to PROCESSED to signal that the queue has been processed.

The VBLANK interrupt, if this status is set to PROCESSED, switches front and back buffers (If the status is BUILT it will set cop2lc to the first blit routine). Regardless of the status, the interrupt will then set cop1lc to the copper list for the front buffer and will strobe copjmp1.

This doesn't work unless I also set cop1lc at the end of my copper list.

In fact, if I remove any of

- setting cop1lc in the VBLANK interrupt
- strobing copjmp1 in the VBLANK interrup
- setting cop1lc at the end of the copper list

then things start to fail. Blits get skipped, including the clear screen blit, and garbage starts to accumulate, etc.

I have no idea what could be wrong.

Here's my main copper list (generation):

Code:
CopperInstruction * GenerateSplitScreenCopperList(APTR buffer, APTR secondaryBuffer) {
    COP_INIT

    COP_START

    COP_LABEL("start")

        COP_INSTR(0x01fc, 0x0000)

        COP_INSTR(DIWSTRT, 0x2c81)
        COP_INSTR(DIWSTOP, 0x2cc1)
        COP_INSTR(DDFSTRT, 0x0038)
        COP_INSTR(DDFSTOP, 0x00d0)

        COP_INSTR(0x2b07, 0xfffe)

        COP_INSTR(BPLCON0, 0x4200)
        COP_INSTR(BPLCON1, 0x0000)

        COP_INSTR(BPL1MOD, (SCREEN_WIDTH_IN_BYTES) * (PRIMARY_DISPLAY_DEPTH - 1))
        COP_INSTR(BPL2MOD, (SCREEN_WIDTH_IN_BYTES) * (PRIMARY_DISPLAY_DEPTH - 1))

        COP_INSTR(BPL1PTH, HIGH_WORD(buffer))
        COP_INSTR(BPL1PTL, LOW_WORD(buffer))
        COP_INSTR(BPL2PTH, HIGH_WORD(buffer + SCREEN_WIDTH_IN_BYTES))
        COP_INSTR(BPL2PTL, LOW_WORD(buffer + SCREEN_WIDTH_IN_BYTES))
        COP_INSTR(BPL3PTH, HIGH_WORD(buffer + 2 * SCREEN_WIDTH_IN_BYTES))
        COP_INSTR(BPL3PTL, LOW_WORD(buffer + 2 * SCREEN_WIDTH_IN_BYTES))
        COP_INSTR(BPL4PTH, HIGH_WORD(buffer + 3 * SCREEN_WIDTH_IN_BYTES))
        COP_INSTR(BPL4PTL, LOW_WORD(buffer + 3 * SCREEN_WIDTH_IN_BYTES))

        // COP_INSTR(COLOR00, 0x000) // Black
        COP_INSTR(COLOR01, 0x8ce) // Sky Blue
        COP_INSTR(COLOR02, 0xdb8) // Tan
        COP_INSTR(COLOR03, 0x282) // Forest Green
        COP_INSTR(COLOR04, 0xfff) // White
        COP_INSTR(COLOR05, 0xaaa) // Lightest Grey
        COP_INSTR(COLOR06, 0x999) // Light Grey
        COP_INSTR(COLOR07, 0x777) // Medium Grey
        COP_INSTR(COLOR08, 0x555) // Dark Grey
        COP_INSTR(COLOR09, 0x444) // Darkest Grey
        COP_INSTR(COLOR10, 0xf00) // Red
        COP_INSTR(COLOR11, 0x800) // Dark Red
        COP_INSTR(COLOR12, 0xf80) // Dark Orange
        COP_INSTR(COLOR13, 0xfdb) // Wheat
        COP_INSTR(COLOR14, 0x682) // Olive Drab
        COP_INSTR(COLOR15, 0x59a) // Cadet Blue

        COP_LOC_HIGH(COP1LCH, "upper_loop")
        COP_LOC_LOW(COP1LCL, "upper_loop")

    COP_LABEL("upper_loop")

        COP_INSTR(COLOR01, 0xFF0) // YELLOW
        COP_INSTR(0x0001, 0x0000) // wait for blitter
        COP_INSTR(COLOR01, 0xF70) // ORANGE

        COP_INSTR(0xf0d7, 0xffff) // skip if >= ?
        COP_INSTR(COPJMP2, 0x0000)

        COP_INSTR(COLOR01, 0x8ce) // BACK TO SKY_BLUE

        // WHY do I need these?
        COP_LOC_HIGH(COP1LCH, "start")
        COP_LOC_LOW(COP1LCL, "start")

        COP_INSTR(0xffff, 0xfffe)
        COP_INSTR(0xffff, 0xfffe)
    
    COP_FINISH

    CopperInstruction * instructions = COP_LIST;

    COP_DESTROY

    return instructions;
}
Here are my interrupt handlers:
Code:
void _GameDisplay_interrupt_copper(Display * display) {
    GameDisplay * gameDisplay = (GameDisplay *) display;
    gameDisplay->queueState = BLITTER_QUEUE_PROCESSED;
}

void _GameDisplay_interrupt_verticalBlank(Display * display) {
    extern volatile struct Custom * custom;

    volatile GameDisplay * gameDisplay = (GameDisplay *) display;

    if (gameDisplay->queueState == BLITTER_QUEUE_PROCESSED) {
        ScreenBuffer * temp = gameDisplay->_frontScreenBuffer;
        gameDisplay->_frontScreenBuffer = gameDisplay->_backScreenBuffer;
        gameDisplay->_backScreenBuffer = temp;

backBuffer = gameDisplay->_backScreenBuffer->buffer;
blitterQueueCopperList = ((GameScreenBuffer *) gameDisplay->_backScreenBuffer)->blitterQueueCopperList;

        gameDisplay->queueState = BLITTER_QUEUE_NEW;
    } else if (gameDisplay->queueState == BLITTER_QUEUE_BUILT) {
        gameDisplay->queueState = BLITTER_QUEUE_PROCESSING;

        custom->cop2lc = (ULONG) BlitterQueue_previousBlit;
    }

    custom->cop1lc = (ULONG) ((GameScreenBuffer *) gameDisplay->_frontScreenBuffer)->splitScreenCopperList;
    custom->copjmp1 = 0;
}
And my "terminating" blitter subs
Code:
static CopperInstruction * BlitterQueue_InitNullBlit(void) {
    COP_INIT

    COP_START

        COP_INSTR(COLOR01, 0x0f0f) // VIOLET

        COP_INSTR(0xffff, 0xfffe);
        COP_INSTR(0xffff, 0xfffe);
    
    COP_FINISH

    CopperInstruction * instructions = COP_LIST;

    COP_DESTROY

    return instructions;
}

static CopperInstruction * BlitterQueue_InitEndBlit(void) {
    COP_INIT

    COP_START

        COP_INSTR(COLOR01, 0x00f0) // GREEN

        COP_INSTR(COP2LCH, HIGH_WORD(BlitterQueue_nullBlit))
        COP_INSTR(COP2LCL, LOW_WORD(BlitterQueue_nullBlit))

        COP_INSTR(INTREQ, INTF_SETCLR | INTF_COPER);

        COP_INSTR(0xffff, 0xfffe);
        COP_INSTR(0xffff, 0xfffe);
    
    COP_FINISH

    CopperInstruction * instructions = COP_LIST;

    COP_DESTROY

    return instructions;
}
Sorry about the macros.
deimos is offline  
Old 24 October 2019, 21:48   #94
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,719
Ok, if I understood your copper list, it's luckily not that difficult to explain.

At the start of each frame, the Copper will always start running the list pointed to by COPLC1. So, COPLC1 must point to the start of the list at the end of the frame, or the copper list won't do what you think it'll do. If you remove the resetting at the end of the frame, it'll start wherever it pointed last.

See HRM here http://amigadev.elowar.com/read/ADCD.../node0050.html

Quote:
Originally Posted by HRM
About Copper restart.

At the start of each vertical blanking interval, COP1LC is automatically used to start the program counter. That is, no matter what the Copper is doing, when the end of vertical blanking occurs, the Copper is automatically forced to restart its operations at the address contained in COP1LC.
Edit: to be more clear, what happens here is a race condition - you set COP1LC during the VBlank, which is technically too late as the CPU will take some cycles to respond to the interrupt, while the Copper will start running the code at COP1LC immediately when VBlank occurs. As such, your code will have executed part of the copper list pointed to by the old value of COP1LC already before you reset the pointer to the start of the copper list.

Last edited by roondar; 24 October 2019 at 22:06.
roondar is offline  
Old 24 October 2019, 22:04   #95
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,456
With only code snippets, flow is a bit hard to follow, much better with some binary example..

Generic tips.
There is a reason why I do not use BFD bit on WAIT and only on SKIP.
The split screen or copper effect cannot work if not done this way.
If I'm stuck waiting, I can loss some fundamental registers initialization and going to video glitches.
(ok, you may have put it to debug but remember not to have blitter wait in the final version)

There is a reason for
$138 dc.w $0082,copper
.
I need to reset COP1LC or I lose copper control.
At VBL copperlist restart from the value buffered in it.
[EDIT: ops.. roondar first ]

Your STROBE on VBI is really dangerous.
If for some reason you are waiting with copper, and the blitter is running, your copper pointer could be used as a destination for the blitter and the memory be corrupted (HW bug).

I'm not sure you have understood what SKIP do.. this 0xf0d7, 0xffff is a non-sense..
My code is created for specific needs: use the copper code without hindering the video effects normally used in demos/games (read all the thread )
You need to be sure to execute Copper subroutine only if the blitter has finished his operations!
This is why I ignore any video position and continue with my normal flow otherwise (and all my tight copper effects are guaranteed).
Logically this implies that the blitter control code must be carried out often, at least as much as you think is your minimum blitting time.

And at the same time it's not 'disturbed' by a VBL wrap or a frame skip situation due to a long blitter queue.
ross is online now  
Old 24 October 2019, 22:10   #96
roondar
Registered User

 
Join Date: Jul 2015
Location: The Netherlands
Posts: 1,719
Ah yes, the hardware bug. I forgot about that. Ross is 100% correct here, never use the CPU to strobe COPJMP while the Blitter is running. This can cause all sorts of mayhem.
roondar is offline  
Old 24 October 2019, 22:34   #97
deimos
Registered User

 
Join Date: Jul 2018
Location: France
Posts: 545
Thank you roondar and ross, I think I understand now how to fix my cop1lc issue. And with the VBLANK code removed there will be no strobing of copjmp1.

Regarding the comments from ross about the skip, that was intended to prevent calling a blit subroutine too close to the bottom of the screen and having the copper reset half way through setting up the blit. I've probably done that wrong because I still find the copper tricky, but I think the intent was right.

Regarding BFD with skip instead of wait, that's the next step, particularly as I want a split screen, but I want to fix other bits first.

Thanks again.
deimos is offline  
Old 25 October 2019, 16:54   #98
deimos
Registered User

 
Join Date: Jul 2018
Location: France
Posts: 545
I now have my copper list blitter queue working (apparently), and am starting to look at rewriting it to not use waits.

But before I do that, there's one thing I still don't understand.

My main loop looks like this:

Code:
start:
        ...

        dc.w    COP1LCH, <top half of upper_loop>
        dc.w    COP1LCL, <bottom half of upper_loop>

upper_loop:

        dc.w    $0001, $0000 ; wait for blitter

        dc.w    $bb01, $ffff ; skip if >= line 186
        dc.w    COPJMP2, $0000

        dc.w    COP1LCH, <top half of start>
        dc.w    COP1LCL, <bottom half of start>

        dc.w    $ffff, $fffe
The skip instruction is there to prevent the subroutine being called when there isn't enough time for it to run before the list gets automatically restarted.

But why does no value higher than 0xbb work? My subroutines should take no time at all, the largest is only around 20 copper move instructions.

Last edited by deimos; 25 October 2019 at 18:00. Reason: Rewriting macros to look like assembly
deimos is offline  
Old 25 October 2019, 17:40   #99
ross
Per aspera ad astra

ross's Avatar
 
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 49
Posts: 2,456
Quote:
Originally Posted by deimos View Post
But why does no value higher than 0xbb work? My subroutines should take no time at all, the largest is only around 20 copper move instructions.
My crystal ball tells me that your copper code does not return correctly from the subroutine.

First case (skip <= $bb01):
- your copper blitter-wait finish after start of vline=$bb, so in any case you reset COP1LC (you never jump) and at next VB your copper list works.

Second case (skip > $bb):
- your copper blitter-wait finish before beam have reached skip position, copper jmp and you lose control (because you do not have a proper return).
ross is online now  
Old 25 October 2019, 18:07   #100
deimos
Registered User

 
Join Date: Jul 2018
Location: France
Posts: 545
Quote:
Originally Posted by ross View Post
My crystal ball tells me that your copper code does not return correctly from the subroutine.

First case (skip <= $bb01):
- your copper blitter-wait finish after start of vline=$bb, so in any case you reset COP1LC (you never jump) and at next VB your copper list works.

Second case (skip > $bb):
- your copper blitter-wait finish before beam have reached skip position, copper jmp and you lose control (because you do not have a proper return).
I don't think it's that, COP1LC is set to point to the start of the loop before we enter it.

I've rewritten the code in my post to get rid of my macros.

Could it be that my blits are so big that the beam hpos counter rolls over? i.e. 256 - 186 = 70 lines? Do I need to learn how to calculate how long blits take?

Edit: Yes, I think that might be it. If I change the code to only paint the background on the top half of the screen, i.e. halve the size of my largest blits, I can increase the 0xbb all the way to 0xfb.

Last edited by deimos; 25 October 2019 at 18:21. Reason: Tried something new
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
So, I'd like to write a new Amiga game - what do you want to see? Graham Humphrey Amiga scene 88 26 February 2012 21:50
My sales over next couple of weeks emdxxxx MarketPlace 4 31 October 2007 10:17
AmigaSYS 1.7 Released ETA : 1-2 Weeks. Dary News 34 22 March 2005 19:51
HOL mentioned in this weeks Micro Mart fiath Amiga scene 8 06 June 2004 23:56

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


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