22 October 2019, 17:50 | #81 |
Registered User
Join Date: Feb 2011
Location: Italy/Rome
Posts: 2,281
|
I'll try to expande my demo, and do polygon filling via "copper-blitter"...
|
22 October 2019, 21:35 | #82 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
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. |
23 October 2019, 13:44 | #83 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
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. Last edited by deimos; 21 November 2021 at 12:01. |
23 October 2019, 13:57 | #84 |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
|
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.) |
23 October 2019, 14:48 | #85 | |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
Quote:
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. Last edited by deimos; 21 November 2021 at 11:31. |
|
23 October 2019, 14:49 | #86 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,410
|
The UAE debugger is part of WinUAE, it does not depend on which compiler you use
|
23 October 2019, 14:52 | #87 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
|
23 October 2019, 14:55 | #88 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,410
|
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 |
23 October 2019, 15:12 | #89 | |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
Quote:
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)) Last edited by deimos; 21 November 2021 at 11:31. |
|
23 October 2019, 15:40 | #90 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
BLIT_INSTR(BLTDPTH, LOW_WORD(scratchBufferB))
|
23 October 2019, 15:56 | #91 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
|
24 October 2019, 10:50 | #92 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
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. |
24 October 2019, 20:40 | #93 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
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; } 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; } 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; } |
24 October 2019, 21:48 | #94 | |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,410
|
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:
Last edited by roondar; 24 October 2019 at 22:06. |
|
24 October 2019, 22:04 | #95 |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
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. |
24 October 2019, 22:10 | #96 |
Registered User
Join Date: Jul 2015
Location: The Netherlands
Posts: 3,410
|
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.
|
24 October 2019, 22:34 | #97 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
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. |
25 October 2019, 16:54 | #98 |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
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 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 |
25 October 2019, 17:40 | #99 | |
Defendit numerus
Join Date: Mar 2017
Location: Crossing the Rubicon
Age: 53
Posts: 4,468
|
Quote:
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). |
|
25 October 2019, 18:07 | #100 | |
It's coming back!
Join Date: Jul 2018
Location: comp.sys.amiga
Posts: 762
|
Quote:
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 |
|
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 |
|
|