Exactly - anyplace that data may be accessed as a word (code fetches fall under this category) or a long, the address must be at least word aligned. Putting an even right before code starts, or before dc.w/dc.l/ds.w/ds.l variables assures that they will meet that alignment. More difficult are blocks of data where the code that deals with said blocks use a mix of byte, word, and long accesses. In such a case, you would need to make sure the block of data is built to meet the alignment rules as well.
So why put an even after it if it only evens data after the word? For example, how do you know that an even doesn't need to go before "File1Location:"? I've gone through my whole ASM putting evens after the BINCLUDES and after the dc.b's and etc. An example: Code (Text): return_2D42E: rts ; =========================================================================== ; animation script off_2D430: dc.w byte_2D436-off_2D430 dc.w byte_2D43A-off_2D430; 1 dc.w byte_2D43E-off_2D430; 2 byte_2D436: dc.b 7, 0, 1,$FF byte_2D43A: dc.b 3, 0, 1,$FF byte_2D43E: dc.b 7, 0,$FF even ; ---------------------------------------------------------------------------- ; sprite mappings ; ---------------------------------------------------------------------------- Obj5C_MapUnc_2D442: BINCLUDE "mappings/sprite/obj5C.bin" even ; =========================================================================== JmpTo34_MarkObjGone jmp MarkObjGone Should I put an even before the "off_2D430" and "Obj5C_MapUnc_2D442" and not after it?
If you see code or dc.w/dc.l/ds.w/ds.l, those MUST be on an even address. How do you know they are on an even address? Some cases are simple: Code (Text): rts some_var: dc.b 5 another_function: movem.l d0-d1,-(sp) See how you have a single byte stuck between pieces of code? Unless that second bit of code at another_function is aligned, calling it will cause an address errror. Code (Text): rts some_var: dc.b 5 even another_function: movem.l d0-d1,-(sp) That now works. However, some cases are harder... Code (Text): rts some_var: incbin "some_data_file.bin" another_function: movem.l d0-d1,-(sp) Is another_function aligned or not? It depends on how long some_data_file.bin is. If it's an odd length, the code is unaligned again and will fail. But if the block is an even length, you don't need to worry, right? Maybe, but maybe not. Will the block ever change length? Will you remember that this block affects code later on when you change the contents of the block? Will you do something like this? Code (Text): rts another_var: dc.b 11 some_var: incbin "some_data_file.bin" another_function: movem.l d0-d1,-(sp) Even if the file is an even length, you've changed where it starts to an odd address by adding the byte variable before it. That means since it's an even length, it will end on an odd address and the code is again unaligned. In the case of variables stuck between code segments, use alignment directives no matter what to guarantee the following code segment is aligned. Like this Code (Text): rts another_var: dc.b 11 some_var: incbin "some_data_file.bin" even another_function: movem.l d0-d1,-(sp) Another case people forget occurs when code is split over several files. Say file 3 ends like this Code (Text): dc.b 0,0,0 and say file 4 starts like this Code (Text): enemy_code: movem.l d0-d7/a0-a6,-(sp) You've created an odd alignment without even realizing it. You need to keep in mind how the overall code and data sections are being populated when assembling/compiling to avoid this. For code that starts a file, ALWAYS align it no matter what. Code (Text): even enemy_code: movem.l d0-d7/a0-a6,-(sp) Now it doesn't matter how file 3 ends, file 4 will start with aligned code. This can also get you when you switch back and forth among sections... Code (Text): rts local_var_used_by_last_routine_above: dc.b 1 .data level_data: incbin "level1.bin" .text another_function: tst.l d0 ... rts .data global_var: dc.l 53 I've created TWO potential address errors in the above code! First the code section ends with a byte variable, but when the section resumes later, starts straight in with code. Second, I have an unknown length block of data in the data section that when the data section resumes has a long variable. Both may cause address errors. When you resume a section, you cannot really be certain how that section ended... so align it! Code (Text): rts local_var_used_by_last_routine_above: dc.b 1 .data level_data: incbin "level1.bin" .text even another_function: tst.l d0 ... rts .data even global_var: dc.l 53
There's only one thing I do not understand. With this code above, you say when I make edits, it can become unaligned at anytime. So, you've put an "even" in front of "another_function". So you're saying that now, no matter what, "another_function" will be aligned, right? Well, why not put an "even" in front of "another_var" and "some_var"? So, that way, "another_var" and "some_var" will also always be aligned?
If they aren't read as words, then alignment doesn't matter for them; if they are used as words, then yeah, they should be aligned too.
I'm not sure if half of them are words or not, so I will put an "even" in front anyway. There's no harm in doing it and I won't have to worry it ever being unaligned.
You have to be very aware of how the code uses bytes... for example, here's a case where two byte variables MUST be aligned... Code (Text): move.w var1,d0 ; get both var1 and var2 at the same time ... var1: dc.b 10 var2: dc.b 10 If var1 isn't evenly aligned, the above with blow up. Code (Text): move.w var1,d0 ; get both var1 and var2 at the same time ... even var1: dc.b 10 var2: dc.b 10 But now let's say I get crazy with the evens and do this Code (Text): move.w var1,d0 ; get both var1 and var2 at the same time ... even var1: dc.b 10 even var2: dc.b 10 Oopsi! I just made the code fail in a hard to trace manner because the code is trying to load both vars at once, but that second even pushes var2 off a byte so that it won't load with that move.w. So you just can't stick evens EVERYWHERE or you may break the code. Such is the joy and fun of assembly! :v:
So I found out earlier. The HUD screwed up and etc when I put an even before it. So if anything ever goes wrong, I will mess around with evens there.
Okay, HUGE bump here, but it looks like flamewing's question never got answered. Does his error report work on real hardware? Yes. A while ago, I asked ChillyWilly to try my Sonic 2 Recreation out on real hardware. Right at the beginning of the ROM, an error occurred, reported by flamewing's report (which the error never happens on emulators). I've fixed it now and my hack works 100% on real hardware. But in conclusion, yes, flamewing's report works on real hardware. Thanks to ChillyWilly for testing.