Difference between revisions of "Z80 Good Programming Practices"
(added alternative to LUTs for if few options and sequential values of a) |
(Ix thing was painfully wrong, lut code wasn't the best still isn't.) |
||
Line 1: | Line 1: | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
== Lookup table == | == Lookup table == | ||
Line 78: | Line 27: | ||
<nowiki> | <nowiki> | ||
ld a,(SpriteNumber) | ld a,(SpriteNumber) | ||
+ | cp 0 | ||
+ | jp z,ChooseSprite0 | ||
cp 1 | cp 1 | ||
jp z,ChooseSprite1 | jp z,ChooseSprite1 | ||
Line 86: | Line 37: | ||
cp 4 | cp 4 | ||
jp z,ChooseSprite4 | jp z,ChooseSprite4 | ||
+ | cp 5 | ||
+ | jp z,ChooseSprite5 | ||
... | ... | ||
+ | ChooseSprite0 | ||
+ | ld hl,Sprite0 | ||
+ | jp DisplaySprite | ||
ChooseSprite1 | ChooseSprite1 | ||
ld hl,Sprite1 | ld hl,Sprite1 | ||
Line 98: | Line 54: | ||
ChooseSprite4 | ChooseSprite4 | ||
ld hl,Sprite4 | ld hl,Sprite4 | ||
+ | jp DisplaySprite | ||
+ | ChooseSprite5 | ||
+ | ld hl,Sprite5 | ||
jp DisplaySprite | jp DisplaySprite | ||
... | ... | ||
Line 108: | Line 67: | ||
<nowiki> | <nowiki> | ||
ld a,(SpriteNumber) | ld a,(SpriteNumber) | ||
− | add a,a ; a*2 | + | add a,a ; a*2 (limits SpriteNumber to 128) |
ld h,0 | ld h,0 | ||
ld l,a | ld l,a | ||
Line 118: | Line 77: | ||
ld l,a | ld l,a | ||
ld bc,(coordinates) | ld bc,(coordinates) | ||
− | + | jp SpriteRoutine | |
... | ... | ||
SpriteAddressLUT | SpriteAddressLUT | ||
+ | .dw Sprite0 | ||
.dw Sprite1 | .dw Sprite1 | ||
.dw Sprite2 | .dw Sprite2 | ||
.dw Sprite3 | .dw Sprite3 | ||
.dw Sprite4 | .dw Sprite4 | ||
+ | .dw Sprite5 | ||
</nowiki> | </nowiki> | ||
</td> | </td> | ||
Line 137: | Line 98: | ||
<nowiki> | <nowiki> | ||
ld a,(MenuChoice) | ld a,(MenuChoice) | ||
+ | cp 0 | ||
+ | jp z,Choice0 | ||
cp 1 | cp 1 | ||
jp z,Choice1 | jp z,Choice1 | ||
Line 145: | Line 108: | ||
cp 4 | cp 4 | ||
jp z,Choice4 | jp z,Choice4 | ||
+ | cp 5 | ||
+ | jp z,Choice5 | ||
+ | cp 6 | ||
+ | jp z,Choice6 | ||
+ | cp 7 | ||
+ | jp z,Choice7 | ||
... | ... | ||
</nowiki> | </nowiki> | ||
Line 163: | Line 132: | ||
jp (hl) | jp (hl) | ||
... | ... | ||
− | CodeBranchLUT | + | CodeBranchLUT: |
+ | .dw Choice0 | ||
.dw Choice1 | .dw Choice1 | ||
.dw Choice2 | .dw Choice2 | ||
.dw Choice3 | .dw Choice3 | ||
.dw Choice4 | .dw Choice4 | ||
+ | .dw Choice5 | ||
+ | .dw Choice6 | ||
+ | .dw Choice7 | ||
</nowiki> | </nowiki> | ||
</td> | </td> |
Revision as of 00:26, 27 December 2006
Lookup table
If you have a place in your code where a value is tested to choose between a lot of things, like subroutines or data, it can be a good idea to use lookup tables instead of a series of tests. It makes the code more readable, concise and extensible.
In terms optimisation though it should be used when the data is not sequentially ordered or when the objects being pointed to are not the same size. For example, using LUTs (Look Up Tables) to find a tile in a block of memory that is only tiles would both slower and cost more memory. Using LUTs to find a particular string would be quicker but would waste more memory than a linear search. Using LUTs as a jump table to different code blocks located through out a program would be faster and smaller compared to the alternative.
However, if there aren't many jumps and many of the values of a are sequential, it would be more efficient to do something like:
ld a,(Number) or a jp z,A_is_0 dec a jp z,A_is_1 dec a jp z,A_is_2 sub 2 jp z,A_is_4 dec a jp z,A_is_5
Examples:
Without | With |
---|---|
ld a,(SpriteNumber) cp 0 jp z,ChooseSprite0 cp 1 jp z,ChooseSprite1 cp 2 jp z,ChooseSprite2 cp 3 jp z,ChooseSprite3 cp 4 jp z,ChooseSprite4 cp 5 jp z,ChooseSprite5 ... ChooseSprite0 ld hl,Sprite0 jp DisplaySprite ChooseSprite1 ld hl,Sprite1 jp DisplaySprite ChooseSprite2 ld hl,Sprite2 jp DisplaySprite ChooseSprite3 ld hl,Sprite3 jp DisplaySprite ChooseSprite4 ld hl,Sprite4 jp DisplaySprite ChooseSprite5 ld hl,Sprite5 jp DisplaySprite ... DisplaySprite ld bc,(coordinates) call SpriteRoutine |
ld a,(SpriteNumber) add a,a ; a*2 (limits SpriteNumber to 128) ld h,0 ld l,a ld de,SpriteAddressLUT add hl,de ld a,(hl) inc hl ld h,(hl) ld l,a ld bc,(coordinates) jp SpriteRoutine ... SpriteAddressLUT .dw Sprite0 .dw Sprite1 .dw Sprite2 .dw Sprite3 .dw Sprite4 .dw Sprite5 |
And this one :
Without | With |
---|---|
ld a,(MenuChoice) cp 0 jp z,Choice0 cp 1 jp z,Choice1 cp 2 jp z,Choice2 cp 3 jp z,Choice3 cp 4 jp z,Choice4 cp 5 jp z,Choice5 cp 6 jp z,Choice6 cp 7 jp z,Choice7 ... |
ld a,(MenuChoice) add a,a ; a*2 ld h,0 ld l,a ld de,CodeBranchLUT add hl,de ld a,(hl) inc hl ld h,(hl) ld l,a jp (hl) ... CodeBranchLUT: .dw Choice0 .dw Choice1 .dw Choice2 .dw Choice3 .dw Choice4 .dw Choice5 .dw Choice6 .dw Choice7 |