- Remember to tab after each instruction. In addition to being proper, it'll prevent errors during the compiling process.
- Comments need to be tabbed as well. This can cause serious errors if neglected.
- Always try to use smaller instructions for byte based instructions. moveq, addq, subq, and tst are better than move, add, sub, and cmp.b #$0. In addition to saving a byte of space each in ROM, it'll shave a millisecond off your processing time. It may not seem like much, but every bit of time counts; You want to make the best of each instruction you write.
- Always remember to use registers before using RAM. They're much faster, and good for storing quick reference addresses.
The Official ASM Tips Thread
#1
Posted 14 November 2005 - 03:26 PM
#2
Posted 14 November 2005 - 03:28 PM
#3
Posted 14 November 2005 - 09:22 PM
When using a word or long word index, use the ADD instruction to multiply the index instead of LSL or MUL instructions. This is the fastest way.
#4
Posted 16 November 2005 - 01:42 AM
Always, always, ALWAYS hook your main display code into the Vint if your project is of a substantial size. This will ensure that your output is perfectly smooth. Vint hits at line $E0. If your code is small and only for testing a routine, then feel free to busywait. But know that, if you get too much code running in a frame, then you're bound to hit your display code late sooner or later. If you hook into Vint, then even if your main program loop takes a bit too long, then at least your display code will hit at line $E0 consistently.
Access to VDP RAM during the visible screen is extremely slow, whether you're using DMA or making the 68k do the dirty work - for example, while you can make 205 accesses to VDP RAM during Vblank, you can only make 20 accesses during active scan. Also note that VRAM accesses are byte-wide, while CRAM and VSRAM accesses are word-wide. If the screen is disabled via VDP register $02.6, then you can access VDP RAM like you would be able to during Vblank.
#5
Posted 16 November 2005 - 02:55 AM

I think you mean sine waves. If you're using precalculated sine tables remember that cosine is just sine of whatever you're looking for plus half-pi.
#6
Posted 16 November 2005 - 01:17 PM
#7
Posted 16 November 2005 - 02:50 PM
- Always cut your program in several small parts. Try to make a max use of offset indexes if you can, especially if your code can be executed on several frames.
- Never overwrite anything in RAM without being sure of what you are doing. Beware that some levels use several parts of the RAM that some others don't. A good way to have a large amount of RAM is to use the part where the level mappings are stored. If you are drawing yourself your level, and making the mapping yourself, you can easily keep some 16x16 or 128x128 tiles only for your ASM needs...
- Besides this, always store ALL registers into RAM before your main program (unless you are sure of what you are doing). The MOVEM instruction can be, for once, useful here. This ensures that you aren't erasing an important value that still in a register, and that can be used by the Sonic Engine, even far later your program. This also allow you to use all registers without any unexpected problems. Don't forget to retrieve all registers at the end.
- Limit the use of absolute pointers. Always use relative pointers when you can, so that you can copy and paste fastly your program everywhere in your ROM file, with a single hex editor.
- Be careful of your stack level (a7). The level of the stack should be the same at the start and at the end of your inserted ASM code.
- You can really "play" a bit with the stack, after all, it's only a pointer in RAM. You can for example, calculate "manually" an absolute address with the help of a condition, and write that address on the stack. Then, you can "RTS" your code to jump to different places, depending of the condition (others ways do the same thing)... You can also write that address at (a7) plus one long, by accessing the RAM directly, overwriting the last long pushed on the stack, or simply updating it a bit... It all depends of the effect you want to do.
#8
Posted 16 November 2005 - 04:38 PM
movem.l d0-a6,-(sp) movem.l (sp)+,d0-a6
(I've never used the movem instruction before, so the list syntax may not be accurate...)
EDIT: Oops, fixed destination error.
#9
Posted 16 November 2005 - 06:13 PM
This instruction is invalid: MOVEM.L d0/a6,(a7)+
As well as a similar one: MOVEM.L -(a7),d0/a6
"68k guide" said:
The registers are stored in consecutive memory locations at the specified address. For example, a valid instruction is this one:
MOVEM.L d0/d1/a6,(a2)
#10
Posted 16 November 2005 - 06:37 PM
#11
Posted 17 November 2005 - 02:36 AM
Quote
No... Address register a7 is just like the others address registers. It's only especially used to simulate a stack, nothing more. That's why I prefer speaking about a7 rather than sp, which refers to exactly the same thing.
#12
Posted 21 November 2005 - 03:04 PM
- Copying the current stack pointer to another address register (this will be your base)
- Subtracting the necessary number of bytes from the stack pointer
- Using the base and a negative index to reference your variables
- When you're ready to return or discard your variables, move the base back into the stack pointer
#13
Posted 21 November 2005 - 10:27 PM
Aurochs, on Nov 21 2005, 11:04 PM, said:
- Copying the current stack pointer to another address register (this will be your base)
- Subtracting the necessary number of bytes from the stack pointer
- Using the base and a negative index to reference your variables
- When you're ready to return or discard your variables, move the base back into the stack pointer
This is waht C++ do on Intel processors.
#14
Posted 21 November 2005 - 10:29 PM
LOst, on Nov 21 2005, 11:27 PM, said:
Where do you think I learned it? =P
Actually, Pascal does this too. I can't vouch for other languages, though.
#15
Posted 21 November 2005 - 10:34 PM
Aurochs, on Nov 22 2005, 06:29 AM, said:
LOst, on Nov 21 2005, 11:27 PM, said:
Where do you think I learned it? =P
Actually, Pascal does this too. I can't vouch for other languages, though.
Like you said, 68k processors has a lot of data registers already. The base pointer is a register on the Intel 80x86 processors because there are only 4 16 bit (8 bit bus) registers to work with. Remember that accessing the stack is much slower than having the values in a register. I don't think emulating the base pointer behaivour is a good advice when you have six to seven 32 bit registers to play with.


00