vitoco Posted March 7, 2023 Share Posted March 7, 2023 A couple of years ago I wrote a demo for a 12 colors text mode (GRAPHICS 2) in a pseudo ANTIC 7 text mode without flickering: It was written in Fastbasic which builds a custom display list using two ANTIC 6 lines sharing the same data for a single text line, but displaying half of the char each (top & bottom), and a DLI to swap the PF palette on every scanline and the charset every eight scan lines. I want to use this trick in a game, and a plain background using just PF4 looks like this: The problem started when I enabled P/M graphics, because a glitch appeared: I'm not sure what is going on. it looks like WSYNC is taking more CPU cycles when P/M graphics are enabled, and it is also missing the last line of each interrupt. Also, the first scan line of the first interrupt also takes more time than the next interrupts. It could be seen even in the no-glitch example, where the first pixel still has the color from the score line (original palette), and that is because the timming is so tight. Any idea? Am I missing something? A setting? Why P/M changes the timmings? Is it an ANTIC chip issue? It looks like I'll have to use only 10 colors (6 plain + 3 mixed + 1 original/unmodified) for the playfield to hide the glitch. 1 Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted March 7, 2023 Share Posted March 7, 2023 Without seeing the code, it's a bit difficult to help, I've used PM and heavy DLI's and not seen anything like this. Usually this sort of thing is down to the DLI using too many cycles. WSYNC just pauses until the end of the current scanline, it won't take any more cycles. Quote Link to comment Share on other sites More sharing options...
TracMan Posted March 7, 2023 Share Posted March 7, 2023 (edited) Don't forget if you have turned on PMG with DMA, that will certainly use more cycles at the START of EVERY line. You can use double line resolution rather than single line to reduce it because there is no refetch per line. But like the poster above says, normally there is plenty of time to do what you want. However, perhaps you could simply try turning off PMG DMA via SMDCTL (memory location 559) with bits 2+3 to confirm with no other changes to your code if it is any better. Note: missile DMA is always fetched when player DMA is on for consistent timing. Here's the definite bit values: https://www.atariarchives.org/mapping/memorymap.php As an extra thing to explain DMA affecting timing is that you could in a game turn on and off Player + Missile DMA before the scan lines where the PMG is used, for examples turning it on after the top border and off in the bottom border, you just have to set GRAFPx or GRAFPM registers to 0 in the Vblank and in the last interrupt as they will contain noise. This can be used to speed up the game logic in a game a small amount, if the sprites are limited to an area of the screen, the DMA can be turned on much later. Edited March 7, 2023 by TracMan Quote Link to comment Share on other sites More sharing options...
phaeron Posted March 7, 2023 Share Posted March 7, 2023 2 hours ago, TracMan said: You can use double line resolution rather than single line to reduce it because there is no refetch per line. Unfortunately, two-line resolution does not save any DMA cycles. It simply changes the addressing used by ANTIC for the P/M fetch. ANTIC still has to fetch P/M graphics every scanline to support vertical scrolling via GTIA's VDELAY register. 1 Quote Link to comment Share on other sites More sharing options...
vitoco Posted March 7, 2023 Author Share Posted March 7, 2023 1 hour ago, TGB1718 said: Without seeing the code, it's a bit difficult to help The DLI statement in Fastbasic is: dli set col = $80 into $D409, $0E into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $0E wsync into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $0E wsync into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $0E wsync into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $82 wsync into $D409, $0E into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $0E wsync into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $0E wsync into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $0E wsync into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019 The parser translates it into the following (extracted using Altirra): 4C87: 48 PHA 4C88: 8A TXA 4C89: 48 PHA 4C8A: A6 4F LDX COLRSH 4C8C: A9 80 LDA #$80 4C8E: 8D 0A D4 STA WSYNC 4C91: 8D 09 D4 STA CHBASE 4C94: A9 0E LDA #$0E 4C96: 8D 16 D0 STA COLPF0 4C99: A9 18 LDA #$18 4C9B: 8D 17 D0 STA COLPF1 4C9E: A9 CA LDA #$CA 4CA0: 8D 18 D0 STA COLPF2 4CA3: A9 58 LDA #$58 4CA5: 8D 19 D0 STA COLPF3 4CA8: A9 86 LDA #$86 4CAA: 8D 0A D4 STA WSYNC 4CAD: 8D 16 D0 STA COLPF0 4CB0: A9 A4 LDA #$A4 4CB2: 8D 17 D0 STA COLPF1 4CB5: A9 36 LDA #$36 4CB7: 8D 18 D0 STA COLPF2 4CBA: A9 EC LDA #$EC 4CBC: 8D 19 D0 STA COLPF3 4CBF: A9 0E LDA #$0E 4CC1: 8D 0A D4 STA WSYNC 4CC4: 8D 16 D0 STA COLPF0 4CC7: A9 18 LDA #$18 4CC9: 8D 17 D0 STA COLPF1 4CCC: A9 CA LDA #$CA 4CCE: 8D 18 D0 STA COLPF2 4CD1: A9 58 LDA #$58 4CD3: 8D 19 D0 STA COLPF3 4CD6: A9 86 LDA #$86 4CD8: 8D 0A D4 STA WSYNC 4CDB: 8D 16 D0 STA COLPF0 4CDE: A9 A4 LDA #$A4 4CE0: 8D 17 D0 STA COLPF1 4CE3: A9 36 LDA #$36 4CE5: 8D 18 D0 STA COLPF2 4CE8: A9 EC LDA #$EC 4CEA: 8D 19 D0 STA COLPF3 4CED: A9 0E LDA #$0E 4CEF: 8D 0A D4 STA WSYNC 4CF2: 8D 16 D0 STA COLPF0 4CF5: A9 18 LDA #$18 4CF7: 8D 17 D0 STA COLPF1 4CFA: A9 CA LDA #$CA 4CFC: 8D 18 D0 STA COLPF2 4CFF: A9 58 LDA #$58 4D01: 8D 19 D0 STA COLPF3 4D04: A9 86 LDA #$86 4D06: 8D 0A D4 STA WSYNC 4D09: 8D 16 D0 STA COLPF0 4D0C: A9 A4 LDA #$A4 4D0E: 8D 17 D0 STA COLPF1 4D11: A9 36 LDA #$36 4D13: 8D 18 D0 STA COLPF2 4D16: A9 EC LDA #$EC 4D18: 8D 19 D0 STA COLPF3 4D1B: A9 0E LDA #$0E 4D1D: 8D 0A D4 STA WSYNC 4D20: 8D 16 D0 STA COLPF0 4D23: A9 18 LDA #$18 4D25: 8D 17 D0 STA COLPF1 4D28: A9 CA LDA #$CA 4D2A: 8D 18 D0 STA COLPF2 4D2D: A9 58 LDA #$58 4D2F: 8D 19 D0 STA COLPF3 4D32: A9 86 LDA #$86 4D34: 8D 0A D4 STA WSYNC 4D37: 8D 16 D0 STA COLPF0 4D3A: A9 A4 LDA #$A4 4D3C: 8D 17 D0 STA COLPF1 4D3F: A9 36 LDA #$36 4D41: 8D 18 D0 STA COLPF2 4D44: A9 EC LDA #$EC 4D46: 8D 19 D0 STA COLPF3 4D49: A9 82 LDA #$82 4D4B: 8D 0A D4 STA WSYNC 4D4E: 8D 09 D4 STA CHBASE 4D51: A9 0E LDA #$0E 4D53: 8D 16 D0 STA COLPF0 4D56: A9 18 LDA #$18 4D58: 8D 17 D0 STA COLPF1 4D5B: A9 CA LDA #$CA 4D5D: 8D 18 D0 STA COLPF2 4D60: A9 58 LDA #$58 4D62: 8D 19 D0 STA COLPF3 4D65: A9 86 LDA #$86 4D67: 8D 0A D4 STA WSYNC 4D6A: 8D 16 D0 STA COLPF0 4D6D: A9 A4 LDA #$A4 4D6F: 8D 17 D0 STA COLPF1 4D72: A9 36 LDA #$36 4D74: 8D 18 D0 STA COLPF2 4D77: A9 EC LDA #$EC 4D79: 8D 19 D0 STA COLPF3 4D7C: A9 0E LDA #$0E 4D7E: 8D 0A D4 STA WSYNC 4D81: 8D 16 D0 STA COLPF0 4D84: A9 18 LDA #$18 4D86: 8D 17 D0 STA COLPF1 4D89: A9 CA LDA #$CA 4D8B: 8D 18 D0 STA COLPF2 4D8E: A9 58 LDA #$58 4D90: 8D 19 D0 STA COLPF3 4D93: A9 86 LDA #$86 4D95: 8D 0A D4 STA WSYNC 4D98: 8D 16 D0 STA COLPF0 4D9B: A9 A4 LDA #$A4 4D9D: 8D 17 D0 STA COLPF1 4DA0: A9 36 LDA #$36 4DA2: 8D 18 D0 STA COLPF2 4DA5: A9 EC LDA #$EC 4DA7: 8D 19 D0 STA COLPF3 4DAA: A9 0E LDA #$0E 4DAC: 8D 0A D4 STA WSYNC 4DAF: 8D 16 D0 STA COLPF0 4DB2: A9 18 LDA #$18 4DB4: 8D 17 D0 STA COLPF1 4DB7: A9 CA LDA #$CA 4DB9: 8D 18 D0 STA COLPF2 4DBC: A9 58 LDA #$58 4DBE: 8D 19 D0 STA COLPF3 4DC1: A9 86 LDA #$86 4DC3: 8D 0A D4 STA WSYNC 4DC6: 8D 16 D0 STA COLPF0 4DC9: A9 A4 LDA #$A4 4DCB: 8D 17 D0 STA COLPF1 4DCE: A9 36 LDA #$36 4DD0: 8D 18 D0 STA COLPF2 4DD3: A9 EC LDA #$EC 4DD5: 8D 19 D0 STA COLPF3 4DD8: A9 0E LDA #$0E 4DDA: 8D 0A D4 STA WSYNC 4DDD: 8D 16 D0 STA COLPF0 4DE0: A9 18 LDA #$18 4DE2: 8D 17 D0 STA COLPF1 4DE5: A9 CA LDA #$CA 4DE7: 8D 18 D0 STA COLPF2 4DEA: A9 58 LDA #$58 4DEC: 8D 19 D0 STA COLPF3 4DEF: A9 86 LDA #$86 4DF1: 8D 0A D4 STA WSYNC 4DF4: 8D 16 D0 STA COLPF0 4DF7: A9 A4 LDA #$A4 4DF9: 8D 17 D0 STA COLPF1 4DFC: A9 36 LDA #$36 4DFE: 8D 18 D0 STA COLPF2 4E01: A9 EC LDA #$EC 4E03: 8D 19 D0 STA COLPF3 4E06: E6 4F INC COLRSH 4E08: 68 PLA 4E09: AA TAX 4E0A: 68 PLA 4E0B: 40 RTI As it could be seen, on every scan line, 4 color registers are touched, and a 5th every 8 scan lines. For a moment I thought that Fastbasic could insert some extra opcodes when PMGRAPHICS mode is used, but it didn't, it's the same. What it is added by Fastbasic is the first WSYNC and the load of the X register (previously saving it with the accumulator) for array index purposes (unused in this case). I also thought that crossing page boundaries would be relevant with extra cycles, but I moved the DLI code and there was no visual difference in the glitches. 1 hour ago, TracMan said: Don't forget if you have turned on PMG with DMA, that will certainly use more cycles at the START of EVERY line. That makes sense. The glitch (delay) appears at the start of every ANTIC line, not at every scanline. But something also happens at the end of that ANTIC line. It seems that the DLI is aborted by the next DLI. 2 hours ago, TracMan said: As an extra thing to explain DMA affecting timing is that you could in a game turn on and off Player + Missile DMA before the scan lines where the PMG is used, for examples turning it on after the top border and off in the bottom border, you just have to set GRAFPx or GRAFPM registers to 0 in the Vblank and in the last interrupt as they will contain noise. Unfortunately, I need P0 to be displayed and moved over the playfield colorized by the DLI. This is not a DLI that happend once in a frame, but a DLI that repeats on every other playfield line (except at the end of the last one) and it spans over two ANTIC 6 lines. I did lots of experiments and it seems that I'll have to remove one of the color registers to reduce the number of cycles of the DLI. 7 minutes ago, phaeron said: Unfortunately, two-line resolution does not save any DMA cycles. It simply changes the addressing used by ANTIC for the P/M fetch. ANTIC still has to fetch P/M graphics every scanline to support vertical scrolling via GTIA's VDELAY register. My display list has the load memory scan bit set (LMS) on every line, in order to reuse the same data in pairs. Could that LMS introduce more delays to ANTIC? Quote Link to comment Share on other sites More sharing options...
phaeron Posted March 7, 2023 Share Posted March 7, 2023 Yeeaah, you're gonna need a more optimized DLI than that. Back of the envelope calculations: Every register loaded this way takes 6 cycles (2 for LDA #imm, 4 for STA abs). With IR mode 4, you get 27-28 cycles in horizontal blank before the wall of DMA on the first scanline of the mode line (the +/-1 is due to the 'free' cycle you may or may not get with STA WSYNC). Thus, you're already pushing it pretty close loading 4 registers in HBLANK. However, every byte ANTIC needs to load costs you one DMA cycle. The display list IR fetch takes one, LMS takes two more, missile takes one, players take 4. So if you have DL + LMS + P/M, you're down 8 cycles, so not enough time to load four registers with straight LDA/STA pairs. The way you get around this is to load up all A/X/Y registers prior to STA WSYNC and burst write them after WSYNC. You should be able to just barely squeeze in the LDA #imm for the fourth register, but five is a bit much. 1 Quote Link to comment Share on other sites More sharing options...
TGB1718 Posted March 7, 2023 Share Posted March 7, 2023 @phaeron beat me to it, that's a lot of cycles needed to do the job before the screen starts to draw, agreed with the A,X and Y to speed things up a bit. @vitoco have a look at De Re Atari, there's a good description in there about how many cycles you have to play with. Quote Link to comment Share on other sites More sharing options...
vitoco Posted March 7, 2023 Author Share Posted March 7, 2023 1 minute ago, TGB1718 said: agreed with the A,X and Y to speed things up a bit. I also agree. I got used to count cycles during 2600 programming and use some techniques like that to save cycles, but this time I'm using Fastbasic's general purpose DLI statement, and I know I'm abusing of it while programming a BASIC tenliner. What was news to me is the fact that P/M graphics are stealing some precious cycles during the HBLANK in the A8. Thanks @phaeron for the confirmation. 8 minutes ago, TGB1718 said: have a look at De Re Atari, there's a good description in there about how many cycles you have to play with. Thanks for the hint. For now, I'll measure how far can I go with this, and I'll probably modify the charsets in order to hide the last glitches. Quote Link to comment Share on other sites More sharing options...
Rybags Posted March 7, 2023 Share Posted March 7, 2023 (edited) DLI timing in itself shouldn't be affected. The DLI is triggered a few cycles after PM DMA has occurred. The problem will be after WSYNC. Write to that will stop the CPU until just after a normal width PF. Generally you'd have loaded a register or more in preparation to store new colours or whatever. Having PM graphics active means 1 or 5 less cycles available until the next playfield start. Also a DList DMA fetch will cost another 1 or 3 cycles each mode line start so you have to cater for such things when calculating the available time. Then of course character graphics modes will cost a whole lot more on the first mode line. Edited March 7, 2023 by Rybags Quote Link to comment Share on other sites More sharing options...
drpeter Posted March 8, 2023 Share Posted March 8, 2023 (edited) 3 hours ago, vitoco said: What was news to me is the fact that P/M graphics are stealing some precious cycles during the HBLANK in the A8. Also, have a look at the Altirra Hardware Reference Manual (Google it) which has the best description and illustration of how, where and why 6502 cycles are 'stolen' under various circumstances. It's also more accurate than De Re Atari in a number of places. Edited March 8, 2023 by drpeter Quote Link to comment Share on other sites More sharing options...
thorfdbg Posted March 8, 2023 Share Posted March 8, 2023 If timing is as tight as this, it may be worth to check whether you can squeeze the data in without the STA WSYNC. If you time the DLI right, the color change will hit GTIA just after the active playfield. 1 Quote Link to comment Share on other sites More sharing options...
Rybags Posted March 8, 2023 Share Posted March 8, 2023 For this psuedo mode, possibly VSCROL tricks could help by reusing the fetched characters. You'd still get that badline where you have less cycles but it might become tolerable since the stock alphanums usually have a blank line top and bottom. Quote Link to comment Share on other sites More sharing options...
TracMan Posted March 8, 2023 Share Posted March 8, 2023 On 3/7/2023 at 8:29 PM, vitoco said: The DLI statement in Fastbasic is: dli set col = $80 into $D409, $0E into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $0E wsync into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $0E wsync into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $0E wsync into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $82 wsync into $D409, $0E into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $0E wsync into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $0E wsync into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019, dli = $0E wsync into $D016, $18 into $D017, $CA into $D018, $58 into $D019, dli = $86 wsync into $D016, $A4 into $D017, $36 into $D018, $EC into $D019 The parser translates it into the following (extracted using Altirra): 4C87: 48 PHA 4C88: 8A TXA 4C89: 48 PHA 4C8A: A6 4F LDX COLRSH 4C8C: A9 80 LDA #$80 4C8E: 8D 0A D4 STA WSYNC 4C91: 8D 09 D4 STA CHBASE 4C94: A9 0E LDA #$0E 4C96: 8D 16 D0 STA COLPF0 4C99: A9 18 LDA #$18 4C9B: 8D 17 D0 STA COLPF1 4C9E: A9 CA LDA #$CA 4CA0: 8D 18 D0 STA COLPF2 4CA3: A9 58 LDA #$58 4CA5: 8D 19 D0 STA COLPF3 4CA8: A9 86 LDA #$86 4CAA: 8D 0A D4 STA WSYNC 4CAD: 8D 16 D0 STA COLPF0 4CB0: A9 A4 LDA #$A4 4CB2: 8D 17 D0 STA COLPF1 4CB5: A9 36 LDA #$36 4CB7: 8D 18 D0 STA COLPF2 4CBA: A9 EC LDA #$EC 4CBC: 8D 19 D0 STA COLPF3 4CBF: A9 0E LDA #$0E 4CC1: 8D 0A D4 STA WSYNC 4CC4: 8D 16 D0 STA COLPF0 4CC7: A9 18 LDA #$18 4CC9: 8D 17 D0 STA COLPF1 4CCC: A9 CA LDA #$CA 4CCE: 8D 18 D0 STA COLPF2 4CD1: A9 58 LDA #$58 4CD3: 8D 19 D0 STA COLPF3 4CD6: A9 86 LDA #$86 4CD8: 8D 0A D4 STA WSYNC 4CDB: 8D 16 D0 STA COLPF0 4CDE: A9 A4 LDA #$A4 4CE0: 8D 17 D0 STA COLPF1 4CE3: A9 36 LDA #$36 4CE5: 8D 18 D0 STA COLPF2 4CE8: A9 EC LDA #$EC 4CEA: 8D 19 D0 STA COLPF3 4CED: A9 0E LDA #$0E 4CEF: 8D 0A D4 STA WSYNC 4CF2: 8D 16 D0 STA COLPF0 4CF5: A9 18 LDA #$18 4CF7: 8D 17 D0 STA COLPF1 4CFA: A9 CA LDA #$CA 4CFC: 8D 18 D0 STA COLPF2 4CFF: A9 58 LDA #$58 4D01: 8D 19 D0 STA COLPF3 4D04: A9 86 LDA #$86 4D06: 8D 0A D4 STA WSYNC 4D09: 8D 16 D0 STA COLPF0 4D0C: A9 A4 LDA #$A4 4D0E: 8D 17 D0 STA COLPF1 4D11: A9 36 LDA #$36 4D13: 8D 18 D0 STA COLPF2 4D16: A9 EC LDA #$EC 4D18: 8D 19 D0 STA COLPF3 4D1B: A9 0E LDA #$0E 4D1D: 8D 0A D4 STA WSYNC 4D20: 8D 16 D0 STA COLPF0 4D23: A9 18 LDA #$18 4D25: 8D 17 D0 STA COLPF1 4D28: A9 CA LDA #$CA 4D2A: 8D 18 D0 STA COLPF2 4D2D: A9 58 LDA #$58 4D2F: 8D 19 D0 STA COLPF3 4D32: A9 86 LDA #$86 4D34: 8D 0A D4 STA WSYNC 4D37: 8D 16 D0 STA COLPF0 4D3A: A9 A4 LDA #$A4 4D3C: 8D 17 D0 STA COLPF1 4D3F: A9 36 LDA #$36 4D41: 8D 18 D0 STA COLPF2 4D44: A9 EC LDA #$EC 4D46: 8D 19 D0 STA COLPF3 4D49: A9 82 LDA #$82 4D4B: 8D 0A D4 STA WSYNC 4D4E: 8D 09 D4 STA CHBASE 4D51: A9 0E LDA #$0E 4D53: 8D 16 D0 STA COLPF0 4D56: A9 18 LDA #$18 4D58: 8D 17 D0 STA COLPF1 4D5B: A9 CA LDA #$CA 4D5D: 8D 18 D0 STA COLPF2 4D60: A9 58 LDA #$58 4D62: 8D 19 D0 STA COLPF3 4D65: A9 86 LDA #$86 4D67: 8D 0A D4 STA WSYNC 4D6A: 8D 16 D0 STA COLPF0 4D6D: A9 A4 LDA #$A4 4D6F: 8D 17 D0 STA COLPF1 4D72: A9 36 LDA #$36 4D74: 8D 18 D0 STA COLPF2 4D77: A9 EC LDA #$EC 4D79: 8D 19 D0 STA COLPF3 4D7C: A9 0E LDA #$0E 4D7E: 8D 0A D4 STA WSYNC 4D81: 8D 16 D0 STA COLPF0 4D84: A9 18 LDA #$18 4D86: 8D 17 D0 STA COLPF1 4D89: A9 CA LDA #$CA 4D8B: 8D 18 D0 STA COLPF2 4D8E: A9 58 LDA #$58 4D90: 8D 19 D0 STA COLPF3 4D93: A9 86 LDA #$86 4D95: 8D 0A D4 STA WSYNC 4D98: 8D 16 D0 STA COLPF0 4D9B: A9 A4 LDA #$A4 4D9D: 8D 17 D0 STA COLPF1 4DA0: A9 36 LDA #$36 4DA2: 8D 18 D0 STA COLPF2 4DA5: A9 EC LDA #$EC 4DA7: 8D 19 D0 STA COLPF3 4DAA: A9 0E LDA #$0E 4DAC: 8D 0A D4 STA WSYNC 4DAF: 8D 16 D0 STA COLPF0 4DB2: A9 18 LDA #$18 4DB4: 8D 17 D0 STA COLPF1 4DB7: A9 CA LDA #$CA 4DB9: 8D 18 D0 STA COLPF2 4DBC: A9 58 LDA #$58 4DBE: 8D 19 D0 STA COLPF3 4DC1: A9 86 LDA #$86 4DC3: 8D 0A D4 STA WSYNC 4DC6: 8D 16 D0 STA COLPF0 4DC9: A9 A4 LDA #$A4 4DCB: 8D 17 D0 STA COLPF1 4DCE: A9 36 LDA #$36 4DD0: 8D 18 D0 STA COLPF2 4DD3: A9 EC LDA #$EC 4DD5: 8D 19 D0 STA COLPF3 4DD8: A9 0E LDA #$0E 4DDA: 8D 0A D4 STA WSYNC 4DDD: 8D 16 D0 STA COLPF0 4DE0: A9 18 LDA #$18 4DE2: 8D 17 D0 STA COLPF1 4DE5: A9 CA LDA #$CA 4DE7: 8D 18 D0 STA COLPF2 4DEA: A9 58 LDA #$58 4DEC: 8D 19 D0 STA COLPF3 4DEF: A9 86 LDA #$86 4DF1: 8D 0A D4 STA WSYNC 4DF4: 8D 16 D0 STA COLPF0 4DF7: A9 A4 LDA #$A4 4DF9: 8D 17 D0 STA COLPF1 4DFC: A9 36 LDA #$36 4DFE: 8D 18 D0 STA COLPF2 4E01: A9 EC LDA #$EC 4E03: 8D 19 D0 STA COLPF3 4E06: E6 4F INC COLRSH 4E08: 68 PLA 4E09: AA TAX 4E0A: 68 PLA 4E0B: 40 RTI As it could be seen, on every scan line, 4 color registers are touched, and a 5th every 8 scan lines. For a moment I thought that Fastbasic could insert some extra opcodes when PMGRAPHICS mode is used, but it didn't, it's the same. What it is added by Fastbasic is the first WSYNC and the load of the X register (previously saving it with the accumulator) for array index purposes (unused in this case). I also thought that crossing page boundaries would be relevant with extra cycles, but I moved the DLI code and there was no visual difference in the glitches. That makes sense. The glitch (delay) appears at the start of every ANTIC line, not at every scanline. But something also happens at the end of that ANTIC line. It seems that the DLI is aborted by the next DLI. Unfortunately, I need P0 to be displayed and moved over the playfield colorized by the DLI. This is not a DLI that happend once in a frame, but a DLI that repeats on every other playfield line (except at the end of the last one) and it spans over two ANTIC 6 lines. I did lots of experiments and it seems that I'll have to remove one of the color registers to reduce the number of cycles of the DLI. My display list has the load memory scan bit set (LMS) on every line, in order to reuse the same data in pairs. Could that LMS introduce more delays to ANTIC? It looked like there were a couple of optimisations or advice for the future: 1) LDA #$0E , STA COLPF2 seems to appear several times. LDY #$0E at the beginning of your DLI and then STY COLPF2 each time will save you a few cycles. 2) LDX COLRSH - is this necessary? Again, might not have much cycles left if you are changing a lot but just load it with *anything* you have that you load into A several times and STX away without the LDA. Looks like #$86 or #$0E are used several times? 3) Avoid STA WSYNC, if you think about it, the cycles required for STA WSYNC are completely unnecessary if you already near enough the edge of the screen and running late, so you just miss it out on those lines and save the cycles BTW although it won't help the crazy timing critical stuff but does work if you have lots of DLI's with colour changes near to each other, a pro tip I learned off these forums - you can avoid PLA/PHA in your DLI altogether just STX <some zero page location reserved for X> and at the end of the DLI, LDX <zero page location location reserved for X>. Can do this for A, X and Y, eg. 3 locations, I have these save/ restore pairs as macros M_SAVEX, M_RESTOREX etc. Makes it less error prone if you are quickly writing a lot of DLIs in case you type TAX and mean TAY etc. Quote Link to comment Share on other sites More sharing options...
TracMan Posted March 8, 2023 Share Posted March 8, 2023 On 3/7/2023 at 8:18 PM, phaeron said: Unfortunately, two-line resolution does not save any DMA cycles. It simply changes the addressing used by ANTIC for the P/M fetch. ANTIC still has to fetch P/M graphics every scanline to support vertical scrolling via GTIA's VDELAY register. My bad, I assumed the GRAFP/M registers being loaded already was enough to reduce the DMA. Is that VDELAY the one that moves the graphics down one scanline down to odd or even lines - I only learned about this recently, don't remember it being mentioned in any the COMPUTE GRAPHICS textbooks I had. Wonder if anyone uses it. Thanks for the correction Quote Link to comment Share on other sites More sharing options...
Rybags Posted March 9, 2023 Share Posted March 9, 2023 VDELAY is a GTIA function and just indicates whether to load GRAFx on even or odd scanlines. Regardless of resolution or VDELAY, Antic will always do the DMA for the each scanline of the visible display area. You can have missile only DMA but player DMA will also enable missile DMA if I recall properly. VDELAY is commonly used in games that just have the 2-line resolution though I would guess such occurrences aren't very common (maybe some early games where memory was tight) 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.