== Skip tip ==
Bug #127 was fixed this week, this is a near-perfect opportunity to remind you the usefulness of the SKIP directive. Make sure to install FF beta F.
`SKIP n` advances $ and $$ without emitting code. Importantly, it doesn't update low-high addresses which are used for binary save.
What is it good for?
1. Memory maps
When you have tables and structures with some custom sizes, replace
table1 = &1000
table2 = table1 + MAX_Y*MAX_CHAR*2
table3 = table2 + MAX_ENTRIES*SIZE_ENTRY
table4 = &2000 ; Must be at &2000
table1 SKIP MAX_Y * MAX_CHAR * 2
table2 SKIP MAX_ENTRIES * SIZE_ENTRY
ALIGN(&2000) ; Make sure no overlap occurs.
* Each size is associated with its table.
* It's more legible, and make it easier to insert another table or to re-order them.
* We ensure tables aren't overlapping each other by mistake.
We often deals with contiguous fields whose offset we want to know. Exemple:
dot_x = 0 ; It's a word
dot_y = 2 ; It's a byte
dot_rgb = 3 ; It's 3 bytes
dot_size = 6
Instead, we can use the fact that no code is emitted to write:
ORG 0 ; Won't assemble anything at 0...
dot_x WORD ; (equivalent to SKIP 2)
dot_y BYTE ; (equivalent to SKIP 1)
dot_rgb SKIP 3
Since we are fiddling with ORG, it should be done before the main ORG, or the last thing in the source.
You could also store/restore like that:
savepc = $
saveobj = $$
; define all your structs and tables.
ORG savepc, saveobj
Admittedly, it's a bit more hackish than a dedicated "STRUCT" directive. On the other hand, I appreciate the ability to achieve functionalities with basic building blocks. By the way SKIP could (should?) have been a MACRO.
MACRO DO_SKIP n
What is it not good for?
For alignement, you'd rather use FILL, so that the padding is... filled, hence more crunchable (*), in a dedicated MACRO to show intent. See ALIGN.
Also, it does nothing for your gut issues.
(*) Note that filling with a uniform byte like 0 doesn't always give the best compression, but that's another matter.