View Full Version : Random Amiga programming trivia
Toni Wilen
16 May 2006, 20:20
What does following instruction do and why? (68000 CPU)
CLR.L $DFF088
More "stupid/weird code" questions later..
OOh is this a programming quiz Kewl ;)
Not that I know the answer.. i'm gonna dig some books out to see what happens at $DFF088 :)
musashi5150
16 May 2006, 20:40
It 'should' cause the copper to reload it's PC from both 1st and then 2nd COPJMP locations within a few cycles of each other (because of 68K 16bit bus) and continue running with the 2nd one...
Why on earth you'd want to do that is beyond me :D
Or maybe I'm wrong... because the CLR does a read before hand doesn't it ? That's why Commodore advise against using it for custom regs.... If it did read first that would case all kinds of craziness :D
It 'should' cause the copper to reload it's PC from both 1st and then 2nd COPJMP locations within a few cycles of each other (because of 68K 16bit bus) and continue running with the 2nd one...
Why on earth you'd want to do that is beyond me :D
Or maybe I'm wrong... because the CLR does a read before hand doesn't it ? That's why Commodore advise against using it for custom regs.... If it did read first that would case all kinds of craziness :D
The behaviour you describe about CLR only happens on a 68000, not on 68020 and higher AFAIR.
Toni Wilen
17 May 2006, 07:26
continue running with the 2nd one...
Incorrect :)
Why on earth you'd want to do that is beyond me :D
Not me but others have used it in demos and games...
Or maybe I'm wrong... because the CLR does a read before hand doesn't it ? That's why Commodore advise against using it for custom regs.... If it did read first that would case all kinds of craziness :D
68000 CLR.L to memory has 2 unexpected features (ok, read before write is documented in programming manuals but there is another undocumented feature..)
musashi5150
17 May 2006, 10:19
Ok.... I managed to dig this out. The author states this only applies to MOVE.L, but he didn't test it on CLR. I would play with this myself, but I'm not near an Amiga right now...
Is this what happens ? Seems weird this behaviour....
------------------------------------------
Long-Word Writes and 16-Bit Data Buses
------------------------------------------
The 68000 has a 16-bit data bus and consequently, 32-bit accesses are broken down into 2 consecutive 16-bit accesses.
When writing a long-word (with MOVE.L) with a pre-decrementing destination address mode, the following occurs:
- Destination address register is decremented by 2
- Low word of data is written to the address
- Destination address register is decremented by 2
- High word of data is written to the address
( Thanks to Steve Snake for figuring this out. The Sega Genesis game "Jim Power" relies on this behavior. )
Consider the following code as an example:
lea 0xc00004, a0
move.l #0x12345678, -(a0)
The address, 0xC00004, is loaded into A0. The MOVE.L instruction then does this:
- Subtract 2 from the destination address (0xC00004 - 2 = 0xC00002)
- Write 0x5678 to 0xC00002
- Subtract 2 from the destination address (0xC00002 - 2 = 0xC00000)
- Write 0x1234 to 0xC00000
Note that this backwards writing behavior only seems to happen with the MOVE.L instruction when the destination address mode is pre-decremented. It does not happen when the source address is pre-decremented. Also, the few arithmetic instructions that were tested did not exhibit this behavior, either. CLR was not tested, but I assume it does not behave like MOVE.L because of the dummy read it performs.
The other long word addressing modes work as expected:
- High word of data is written to address
- Low word of data is written to (address + 2)
For those interested I found the details here: http://www.trzy.org/files/68knotes.txt
Toni Wilen
17 May 2006, 10:35
"Interesting" memory fetch cycles are due to microcode. 68000's microcode is clearly optimized for best possible memory access cycle utilization.
Fortunately there is ECS blitter trick that can be used to detect memory cycle order without any extra hardware. (Only checked some most interesting opcodes because it is really slow and boring task..)
Some even do this: write first word, fetch next instruction opcode (prefetch), write second word. (I think it was some variant of JSR) Makes self-modfying copy protection code most interesting..
blade2565
17 May 2006, 13:32
It just writes the value 0 to $dff088, you can do the same by doing this move.l #0,$dff088....
musashi5150
17 May 2006, 13:34
It just writes the value 0 to $dff088, you can do the same by doing this move.l #0,$dff088....
Thanks for the insight ;)
blade2565
17 May 2006, 13:35
or do it like this:
move.l #$0,d0 (can also be #0,d0, if I remember right)
move.l d0,$dff088
LOL it does in a way the same...
Toni Wilen
17 May 2006, 13:42
or do it like this:
move.l #$0,d0 (can also be #0,d0, if I remember right)
move.l d0,$dff088
LOL it does in a way the same...
Nope, it isn't same.. CLR.L <> MOVE.L in this case.. (I did say "68000", not any 68K CPU)
blade2565
17 May 2006, 13:48
d0 to d7 are data registers, a0 to a7 are used for starting addresses
example:
move.l #$FFFFFFFF,d0 (write value #$FFFFFFFF in register d0)
clr.l d0 (clear register d0 to 0)
only clr.l should work faster than for example this
move.l #$0,d0
since than it the CPU first needs to read out the value, 0 and than write it register.
clr.l d0 just clears register d0
if you for example do this:
move.l #$ffffffff,d0
move.b #$0,d0
than the result should of D0, should be $FFFFFF00 it only clears the last byte.... I think you can guess what happens if you do move.w #$0,do to d0, or move.l #$0,d0
well if I remember right clr.l isn't support by 68000 CPU but 68020+ supports it...
68000 wasn't 16bit yet, and should do move.w #0,$dff088 but hey it is a long time a go I did program will start soon again.... didn't program anymore for +/- 12 years I think...
Toni Wilen
17 May 2006, 13:56
:nuts :confused :banghead
What does this have to do with the original question? (and btw, there is "edit"-post button too)'
It was already said 68000 CLR.x does read memory access and then write memory access instead of single write access but the question has not yet been answered, one important detail is still missing..
musashi5150
17 May 2006, 14:02
You could always share this 2nd undocumented feature with us :cool
blade2565
17 May 2006, 14:06
I know about the edit post button, and sorry did not want to upset you...
Galahad/FLT
17 May 2006, 14:24
off topic but... never use move.l #$0,d0 or clr.l d0. Moveq #$0,d0 is a far better and economic way of doing the same thing.
Toni Wilen
17 May 2006, 14:32
I was not upset, only annoyed :)
Answer:
CLR.L $DFF088 does following (on 68000):
1: READ $DFF088
2: READ $DFF08A
3: WRITE $DFF08A
4: WRITE $DFF088
-> COPJMP1 is last address triggered.
musashi5150
17 May 2006, 14:47
That's just plain weird - proper microcode stuff :) I guess it's more efficient as the 68K doesn't have to reconfig it's address pins more than necessary.
Good stuff Toni, do you have any more? :D
In English what does all this writing to registers do (I really should whip out the RKM and Hardware ref manual)
musashi5150
17 May 2006, 16:53
In English what does all this writing to registers do (I really should whip out the RKM and Hardware ref manual)
In this case it just forces the copper chip to reload a new copperlist to be executed. Don't worry too much about our discussion of which memory address are accessed first - this is for us hardcore nerds only :D
:lol i'd be hardcore if I could keep my attention focused on asm programming long enough!
I've spent enough cash on bloody manuals and books this past year..
It has nothing to do with asm programming... it is a hw feature ;)
Yes but it is presented with asm instuction in this thread ;)
Show me the C, Amos or Blitz equivilent :D
off topic but... never use move.l #$0,d0 or clr.l d0. Moveq #$0,d0 is a far better and economic way of doing the same thing.
:agree
moveq need only 4 clock periods,
clr.l d0 need 6 clock periods.
Yes but it is presented with asm instuction in this thread ;)
Show me the C, Amos or Blitz equivilent :D
I don't think you could do this in C, AMOS or Blitz, because you rely on the behaviour of a specific asm instruction and a specific memory address. You can access the memory address using C, but you can't guarantee that the compiler will choose that specific instruction. As has already been mentioned, there's at least one other way to achieve what the CLR command is intended to (use MOVE to put 0 into the memory address).
In C it'd look like this:
long *p;
p = 0xDFF088;
*p = 0;
Think that's right, haven't done any C in ages (and don't really know asm yet either!). It just sets the long value at memory address 0xDFF088 to 0.
Have I got this right? :help
musashi5150
17 May 2006, 20:25
Have I got this right? :help
Looks good enough to me :) But as you said, best to steer well clear of high-level languages for this kind of stuff.
:agree
moveq need only 4 clock periods,
clr.l d0 need 6 clock periods.
Aargh, it has always irritated me that I have never been able to understand ASM. :banghead
Can you tell me; How do you know this? (4/6 clock periods). Is it something you have read, or is it able to measure it?
musashi5150
18 May 2006, 09:41
I suppose you 'could' measure it... but the easier way is to just read it out of a 68000 handbook :)
Galahad/FLT
18 May 2006, 13:07
Aargh, it has always irritated me that I have never been able to understand ASM. :banghead
Can you tell me; How do you know this? (4/6 clock periods). Is it something you have read, or is it able to measure it?
As you get more proficient at programming, so you learn more.
Examples
moveq #$0,d0 better than clr.l d0
lea $200(a0),a0 better than add.l #$200,a0
lsl.l #1,d0 better than mulu #2,d0
and so on and on........
even better if the data is already in a Data register to add or subtract.
Yes, good example.
mulu #2,d0 needs 70 clock periods.
lsl #1,d0 needs only 8 clock periods.
It is nearly ten times faster for
doing the "same".
Toni Wilen
18 May 2006, 17:52
add.l d0,d0 is even faster, only 6 cycles :)
hehe, yup we have forgotten the add instruction.:agree
Galahad/FLT
19 May 2006, 14:50
add.l d0,d0 is even faster, only 6 cycles :)
for that one example of multiplying by 2 its quicker, but if I was multiplying by 4 add.l d0,d0, add.l d0,d0 would be slower than the equivalent lsl.l ;)
:banghead
I..........feel.............s....t....u.....p.....i......d....... :bowdown
And it is most interesting if it is multiplyed by 5 ,6 ,7...:D
StingRay
31 July 2006, 20:37
And it is most interesting if it is multiplyed by 5 ,6 ,7...:D
Not very hard to do actually.
You can multiply by 5 like this:
move.l d0,d1
lsl.l #2,d1
add.l d1,d0
if you would like to multiply by 6 you just need to add add.l d0,d0:
move.l d0,d1
lsl.l #2,d1
add.l d0,d0
add.l d1,d0
and multiply by 7 could be done like this:
move.l d0,d1
lsl.l #2,d1
move.l d0,d2
add.l d0,d0
add.l d2,d0
add.l d1,d0
I didn't comment the code since I think it's easy enough to understand. It is also untested since I couldn't be bothered to fire up an assembler. But it should work. ;)
t0ne
01 August 2006, 11:19
... or how about for 7 ?
move.l d0,d1
lsl.l #3,d1
sub.l d0,d1
This is the first 68k code I've written in over 12 years :crazy:laughing
edit: whoops I think I had the src/dst the wrong way (no reference manual)
StingRay
01 August 2006, 12:30
nice one. :) but if you would like it to behave like a "real" mulu instruction, it would have to be like this:
move.l d0,d1
lsl.l #3,d0
sub.l d1,d0
Anyway, much cooler solution than the one I posted. :)
t0ne
01 August 2006, 12:38
Ta. I'd love to get back into some 68k (one of the reasons I joined here) ... it's been a long time but I've got fond memories (or rose tinted specs) ;)
Ray Norrish
03 August 2006, 01:05
nice one. :) but if you would like it to behave like a "real" mulu instruction, it would have to be like this:
move.l d0,d1
lsl.l #3,d0
sub.l d1,d0
Anyway, much cooler solution than the one I posted. :)
how about doing it in 1989 demo stylee?
moveq #5,d0
add d0,d0
lea 7timestable(pc),a0
move (a0,d0.w),d1
7timestable: dc.w 7,14,21,28,35,42,49
or my personal favourite :)
REPT 7
add d0,d1
ENDR
Galahad/FLT
03 August 2006, 17:06
how about doing it in 1989 demo stylee?
moveq #5,d0
add d0,d0
lea 7timestable(pc),a0
move (a0,d0.w),d1
7timestable: dc.w 7,14,21,28,35,42,49
or my personal favourite :)
REPT 7
add d0,d1
ENDR
ahem.... moveq? more like move.l #5,d0 if its 1989 demo stylee! :)
cdoty
30 August 2006, 21:25
... or how about for 7 ?
move.l d0,d1
lsl.l #3,d1
sub.l d0,d1
Heh! I've never thought of the sub option.
I was not upset, only annoyed :)
Answer:
CLR.L $DFF088 does following (on 68000):
1: READ $DFF088
2: READ $DFF08A
3: WRITE $DFF08A
4: WRITE $DFF088
-> COPJMP1 is last address triggered.
Hi,
I have question. How many cycles eat CLR.L $DFF088 on 68000 ? And the second one. How check that the answer is correct ?
Regards
add.l d0,d0 is even faster, only 6 cycles :)
On the 68000, 8 cycles if operand is register direct or immediate, as in this case.
There's always a "break even" point between successive adds and rotate instructions. For longs, a rotate instruction should be used if the shift is greater than 1, I think.
One of these nice solutions is the fastest. If there is a tie, the one with the fewest instructions will cause less competition with DMA, if the code is in chipmem (ie. works on unexpanded A500). I haven't calculated, but I suspect t0ne's will be the one. Might even be faster than the table one (don't have my timing sheet here but ... 14+4 for the table, 4+14+8... so could break even if the extra longword memory access would have to wait for two blitter cycles...)
But in this case, a table would be crap. Because in order to do it correctly, it would have to be 64K longs = 256K!
For those who like weird things : what happens when opcode $FF10 is executed by a 68020 or 68030 (EC or not) in user mode ?
StingRay
24 May 2009, 14:31
Should simply trigger a line-f exception.
frank_b
24 May 2009, 15:47
I don't think you could do this in C, AMOS or Blitz, because you rely on the behaviour of a specific asm instruction and a specific memory address. You can access the memory address using C, but you can't guarantee that the compiler will choose that specific instruction. As has already been mentioned, there's at least one other way to achieve what the CLR command is intended to (use MOVE to put 0 into the memory address).
In C it'd look like this:
long *p;
p = 0xDFF088;
*p = 0;
Think that's right, haven't done any C in ages (and don't really know asm yet either!). It just sets the long value at memory address 0xDFF088 to 0.
Have I got this right? :help
I'd add volatile to it if you're banging the hardware. :)
Should simply trigger a line-f exception.
But will not. Instead you'll get a privilege violation exception (try it if you don't believe me).
A note about poking to DFF088 : there's no reason to do that anyway, apart if you want your freshly initialized copperlist to start right in the middle of actual screen and make you see garbage during one frame :D
Toni Wilen
24 May 2009, 18:22
For those who like weird things : what happens when opcode $FF10 is executed by a 68020 or 68030 (EC or not) in user mode ?
0xFF10 is FPU instruction (FSAVE) which is privileged instruction. CPU will decode them even if FPU is not installed.
A note about poking to DFF088 : there's no reason to do that anyway, apart if you want your freshly initialized copperlist to start right in the middle of actual screen and make you see garbage during one frame :D
There is if you want to have 100% robust code. Previous copper list may poke some registers which you may not want to happen :)
0xFF10 is FPU instruction (FSAVE) which is privileged instruction. CPU will decode them even if FPU is not installed.
No my friend it's not FPU instruction. ALL fpu opcodes are in the range F200-F3FF. FSAVE is F310, not FF10.
There is if you want to have 100% robust code. Previous copper list may poke some registers which you may not want to happen :)
Like what ? If you initialize everything you have nothing to fear about previous coplist.
And if you want 100% robust code then it's better to waitvbl() after setting up your coplist.
Toni Wilen
24 May 2009, 18:40
No my friend it's not FPU instruction. ALL fpu opcodes are in the range F200-F3FF. FSAVE is F310, not FF10.
It is. Check your CPU manual again :)
Bits 9-11 is FPU ID number = ignored when decoding the instruction type. (EDIT: not 12-10. Never used in Amiga but there it is in official Motorola manuals)
Like what ? If you initialize everything you have nothing to fear about previous coplist.
And if you want 100% robust code then it's better to waitvbl() after setting up your coplist.
Yeah but if you let the old copper list run while initializing custom registers = you can get quite random results..
It is. Check your CPU manual again :)
Bits 9-11 is FPU ID number = ignored when decoding the instruction type. (EDIT: not 12-10. Never used in Amiga but there it is in official Motorola manuals)
It's certainly not. Bits 11,10,9 are COPROCESSOR id, not FPU id. See the difference ?
COPROCESSOR ID=1 -> FPU. Perhaps YOU need to look in your CPU manual again :p
0 is MMU (which means F800 isn't MMU even in weird EC030, but I already told this to you someday), 2 is 040 cache control (cinvl, cinvp, cpusha, etc.), 3 is move16 block (040), 4 is power control (lpstop, 060), 5 is debug block ( wddata, wdebug), 6 and 7 are unused.
Yeah but if you let the old copper list run while initializing custom registers = you can get quite random results..
If you initialize custom registers by hand, just turn the copper dma off.
Toni Wilen
25 May 2009, 08:31
It's certainly not. Bits 11,10,9 are COPROCESSOR id, not FPU id. See the difference ?
COPROCESSOR ID=1 -> FPU. Perhaps YOU need to look in your CPU manual again :p
0 is MMU (which means F800 isn't MMU even in weird EC030, but I already told this to you someday), 2 is 040 cache control (cinvl, cinvp, cpusha, etc.), 3 is move16 block (040), 4 is power control (lpstop, 060), 5 is debug block ( wddata, wdebug), 6 and 7 are unused.
Oops, it is coprocessor :)
You are partially right but 020 and 030 still considers bits 9-11 as "no care" when decoding, afaik it is meant for other external support chips just like 68851 MMU or 68881 FPU. CPU don't know (or care) if they exist or not :)
(btw, there is no 030 MMU emulation so it isn't something important)
If you initialize custom registers by hand, just turn the copper dma off.
Thats one way to do it properly but there has been few games that fail if run at wrong time or previous (system) copperlist does something "unexpected" due to crappy setup routine.
Just complaining because this isn't rare error at all, just check recent post in this forum :D
Toni Wilen
25 May 2009, 10:20
Hi,
I have question. How many cycles eat CLR.L $DFF088 on 68000 ? And the second one. How check that the answer is correct ?
I'll check this when I bother with boring logic analyzer stuff again.
On the 68000, 8 cycles if operand is register direct or immediate, as in this case.
Same here :)
clr.l $dff088 takes 32 cycles according to my docs. The fastest way to accomplish the exact same thing is a move.l Dn,(An) (12 cycles), or to make it a part of a movem.l, in which case it takes 8 cycles+one or two for the shared start of the movem, depending on how many registers share the movem startup cycles.
Oops, it is coprocessor :)
You are partially right but 020 and 030 still considers bits 9-11 as "no care" when decoding, afaik it is meant for other external support chips just like 68851 MMU or 68881 FPU. CPU don't know (or care) if they exist or not :)
The 030 seems to care about those bits, because MMU opcodes are really with ID=0 (I checked all opcodes on my 030 so I know about this).
For me they decode the cpsave before they check about the coprocessor being present or not. 68000 and 040/060 don't do this and we'll get line-F as expected.
This could be another way to detect emulators ;)
(btw, there is no 030 MMU emulation so it isn't something important)
I know, but you can't fool a program which uses that. Perhaps one day we'll see a demo checking it and refusing to run on emulators...
Thats one way to do it properly but there has been few games that fail if run at wrong time or previous (system) copperlist does something "unexpected" due to crappy setup routine.
Just complaining because this isn't rare error at all, just check recent post in this forum :D
I complained probably because I've seen just too many games having graphical glitches at startup, and writing to DFF088 is a nice way of making them :D
Toni Wilen
30 May 2009, 09:32
The 030 seems to care about those bits, because MMU opcodes are really with ID=0 (I checked all opcodes on my 030 so I know about this).
For me they decode the cpsave before they check about the coprocessor being present or not. 68000 and 040/060 don't do this and we'll get line-F as expected.
This could be another way to detect emulators ;)
I know, but you can't fool a program which uses that. Perhaps one day we'll see a demo checking it and refusing to run on emulators...
There are many MUCH easier ways to do that (that are much harder to "fix")
I still won't care :)
I complained probably because I've seen just too many games having graphical glitches at startup, and writing to DFF088 is a nice way of making them :D
Ok, we agree. Lets say it this way: you can write dff088 if you know what are you doing :)
There are many MUCH easier ways to do that (that are much harder to "fix")
I still won't care :)
If you don't care... no problem here :D
Ok, we agree. Lets say it this way: you can write dff088 if you know what are you doing :)
Just like any other hardware address ;)
gimbal
03 June 2009, 13:10
Man, threads like this really make me wish I was born 5-10 years sooner :(
There is still a strong homebrew scene today on consoles and phones if you wanted to "prove" yourself.
TheDarkCoder
06 June 2009, 13:13
I have a question about proper copperlist startup. If one:
1) stops copper dma
2) init hardware registers
3) change COP1LC to its own copperlist but do not poke $dff088
4) starts copper dma
what happens whrn copper dma restarts? Isn't it possible that the old copperlist is executed because COP1LC is copied in the hidden copper instruction pointer only at the next VBLANK ?
Photon
06 June 2009, 16:06
IIRC I had a startup code like that way back. Ie. stop all dma, init stuff, set new copperptr, start dma. When DMA is started it will start fetching copper instruction as usual, and the address counter will be reset next Vsync or next time copjmp is poked.
@ Photon - you do remember correctly. Just tested as follows:
Turned off DMA.
Waited for vblank.
Pointer to my copperlist --> cop1lch.
Turned on DMA again.
My copperlist executed normally with no move to copjmp1
Photon
06 June 2009, 19:07
Well, waiting for vsync kinda spoils it tho ;) But just make a loop in your favorite NonSystemStartup.S and set the normal copper as usual at vblank, then change the frame loop to wait (with cpu) for scanline $50 or so, and switch copper off, set copper address to a second copperlist which changes bg-color to neon pink, and copper dma on again.
If you see pink starting on rasterline $50, "dma-on" triggers copper start without copjmp, mid-frame.
If not, turning copper dma off mid-frame kills the copper until copjmp trigger or autotrigger(=vblank) OR continues reading instructions on dma-on from the normal copper (test by having a bgcolor-change on rasterline $60 or so in the normal cop)
Poking copjmp mid-frame should probably give the famous "force vblank hiccup" on CRTs.
OK, I setup two identical copperlists and did this:
.wait_line: move.l vposr(a6),d0
and.l #$1ff00,d0
cmp.l #$5000,d0
bne.s .wait_line
move.w #%0111111111111111,dmacon(a6)
move.l #my_cop_listtwo,cop1lch(a6)
move.w #%1000011111000000,dmacon(a6)
bsr .wait_vbl
move.w #%0111111111111111,dmacon(a6)
move.l #my_cop_listone,cop1lch(a6)
move.w #%1000011111000000,dmacon(a6)
btst #6,$bfe001
beq.s .exit
bra.s .wait_line
With a red colour change in my_cop_listtwo and a blue color change in my_cop_listone. With the above loop executing I get a blue colour change on screen ie. I see the colour change from listone that's getting triggered to be read at vblank and not the colour change from listtwo that's getting triggered not at vblank.
If I insert a move to copjmp1 after moving listtwo to cop1lch I see a red colour change on screen again indicating that a move to copjmp1 is needed to force the copper instructions to be read from the new list.
So, *if* I understood your explanation right, and *if* I coded something that tests it right (big ifs, after all it's me we're talking about ;)) then dma on by itself doesn't trigger copper start - a move to copjmp or a vblank is needed for that.
If I'm being a complete denzil with my 'testing' then tell me so and also please tell my why I'm being so stupid - my ego can take it and it'll help me learn! :great
Photon
09 June 2009, 00:18
Yeah, it's not triggered by just writing a value, like the sound registers. It's quite logical, or there wouldn't be a separate trigger register, really :)
What I was curious for was if it would continue reading words from the original copper, even though the address had changed. It should, and it did.
Also, copper is auto-triggered each vblank without any write to copjmp. No surprise there, it wouldn't work otherwise. But would a write while copper dma was off be recognized? I tested, and yes. Again, no surprise, no reason why it should not, but it's tested.
Also, by adding a copjmp trigger mid-frame, it switches to cop2 as expected, WITHOUT any display hiccup. Wonder where those hiccups came from, maybe you need to trigger them at a certain scanline and copper must contain a wait that causes it to miss, ie. copper waits across vblanks somehow and no vsync comes to the CRT. Dunno.
I used the same colors as you, with a wait for scanline $60+green to test if it continued reading on after dmaon.
See attached source, I only added a few lines in loop: and inter:
Cool. More things learned. Cheers Photon. :)
TheDarkCoder
20 June 2009, 18:48
Hi, if I have understood it right, your test do confirm that to have a correct statup either you poke copjmp1 or you sync the dma copper restart to the vblank.
The display hiccup are probably generated when copperlists do change display windows settings
hooverphonique
01 August 2012, 22:44
that sounds strange.. i'm sure I never waited for vbl or poked any trigger register in my startup code, and I never saw display corruption (when there weren't any other bugs that could cause corruption, of course ;-)
TheDarkCoder
02 August 2012, 16:41
that sounds strange.. i'm sure I never waited for vbl or poked any trigger register in my startup code, and I never saw display corruption (when there weren't any other bugs that could cause corruption, of course ;-)
of course it's not automatic, it depends on what your code does. If, for instance, all bitplaes and sprite register are set by the copper list, you have no problem. Only be aware that the copperlist will start at next blank.
Problems occur if you need the copperlist to start executing immediatley after the end of the startup code. If you need such a behavior, then either trig COPJMP1 or wait for blank before leaving the startup code
vBulletin® v3.7.0, Copyright ©2000-2013, Jelsoft Enterprises Ltd.