A.D.A. Amiga Demoscene Archive

        Welcome guest!

  

  

  

log in with SceneID

  

Demos Amiga Demoscene Archive Forum / Coding / Memory structure - am I just too thick?

 

Author Message
rudee
Member
#1 - Posted: 6 Jan 2008 12:57 - Edited
Reply Quote
Hi, I am learning to code 68k assembly and I'm now stuck on a small problem that I can't seem to overcome.

I have the following code:

...

lea.l screenbuffer,a1
lea.l bitplanepointers,a2
move.l a1,d1
move.w d1,6(a2)
swap d1
move.w d1,2(a2)

....

bitplanepointers:
dc.w $00e0,$0000
dc.w $00e2,$0000
...

screenbuffer:
blk.b 10240,0

Now, here there is a logical hole for me.. As I see this, the bytes where a2 now points looks like this:
________ ________ _________ ________
|-----------|-----------|------------|-----------|
|0e0 (a2) |0e1 1(a2)|0e2 2(a2)|0e3 3(a2)|
|________|________|________|________|

Clearly it doesn't, because then the code would look like this IMO:

move.l a1,d1
move.w d1,2(a2)
swap d1
move.w d1,(a2)

I'm sure someone can shed some light on this :)

Thanks,
Eirik
Blueberry
Member
#2 - Posted: 6 Jan 2008 17:26
Reply Quote
Your code is correct for writing into the copperlist. I think you are confusing the copperlist with the actual hardware registers.

The bitplane pointers must be written into the hardware bitplane pointer registers in every vblank. The bitplane pointer for bitplane 1 is at 0e0 as you have indicated (bitplane 2 is at 0e4 and so on). And the memory layout is as you have shown (big endian byte order).

The bitplane pointer registers can be written by the cpu or by the copper. To write them with the cpu, you can simply have

lea.l screenbuffer,a1
lea.l $dff0e0,a2
move.l a1,(a2)

And execute this code in the vblank interrupt.

Note that the last instruction is equivalent to the four instructions you write at the bottom of your post (except for the contents of d1 afterwards, of course).

However, a more common way is to write the values using the copper, since the copper automatically executes the copper list in every vblank. The copper can write to any hardware register, but it can only write one word at a time, so when you want to write a longword (such as a pointer) you have to split it up into two copper commands. Your copper list snippet

bitplanepointers:
dc.w $00e0,$0000
dc.w $00e2,$0000

is the correct sequence of copper commands for writing to the bitplane pointer for plane 1. The instruction sequence you have at the top puts in the two halves of the bitplane pointer into the copper list, so that the copper will automatically write the pointer to the hardware register in every vblank (provided that the snippet is part of your copperlist of course).

Beware of writing to copperlists, by the way. If the code that writes to the copperlist is not strictly synchronized with the execution of the copperlist (that is, if you don't know at which time during a refresh the code will execute), the code will sometimes write to the copperlist while it is being executed. This results in the copper using one half of an old pointer with the other half of a new pointer, or old pointers for some bitplanes and new pointers for others. This results in visual glitches. It is a very common mistake, which can be seen in many demos.
rudee
Member
#3 - Posted: 6 Jan 2008 18:02 - Edited
Reply Quote
Aha!

That may very well be the case, that I am confusing the copperlist with the actual hardware registers. I think it makes a little more sense now.

So, what you are saying is that what a2 points to is, something like this?
________ ________ ________ _________
|-----------|-----------|-----------|------------|
|00 (a2)---|e0 1(a2)-|00 2(a2)-|00 3(a2)--|
|________|________|________|________|
________ ________ ________ _________
|-----------|-----------|-----------|------------|
|00 4(a2)-|e2 5(a2)--|00 6(a2)-|00 7(a2)--|
|________|________|________|________|
This is more or less what the copperlist looks like in the code too :)

If my figure above is true, then the machine writes from left to right. Is this true?

Thank you for clearing this up! :)
Blueberry
Member
#4 - Posted: 7 Jan 2008 21:56
Reply Quote
Yes, that is exactly what a2 is pointing to.

What you call "left to right" is commonly known as "big endian" - that is, when 16-bit and 32-bit values are stored to memory, the more significant bytes precede the less significant ones. Another way of looking at it is that the byte values always end up in the order you write them, no matter how you group them into byts, words and longwords. So, for instance, each of the three lines

dc.b $12,$34,$56,$78
dc.w $1234,$5678
dc.l $12345678

will result in the same memory contents.

The opposite, little endian, is what x86 machines use. Here, if you store the word $1234, the $34 byte will end up before the $12 byte.
rudee
Member
#5 - Posted: 10 Jan 2008 23:17
Reply Quote
Ah! Thank you very much! :)

 

  Please log in to comment

  

  

  

 

A.D.A. Amiga Demoscene Archive, Version 3.0