![]() |
DevelopmentSega Master System / Mark III / Game Gear |
Home - Forums - Games - Scans - Maps - Cheats |
Sega8bit & SMS Power! 2013 Event - 10th August 11 weeks and 5 days from now
The repeating block instructions like otir and ldir are used to copy or transfer large strings of data. Internally the Z80 handles these like individual outi and ldi instructions, after executing one it will move the program counter back to re-execute the instruction until the value in register pair bc becomes zero.
It is actually faster to use multiple outi and ldi instructions in sequence to mimic the behavior of otir or ldir. For example:
This defines 1024 outi instructions with a ret at the end, making it into a subroutine. You can then call it like so:
To keep your code readable, it might be a good idea to put a call to the block of outi instructions in a macro.
Using this technique with ldi can be useful for filling memory too. Just replace the source address with a table that contains the fill value.
add a,a is faster than a sla a for single bit left shifts.
axor a is faster and smaller than ld a,0.
ret == retiei; ret instead of ei; reti to spare a byte and 4 clock cycles.
ixl/ixh/iyl/iyh and even the i register for loop counters instead of maintaining a counter in memory or pushing/popping an already used register to the stack inside a loop.
rstrst $38, use jr cc, -1. This will cause a conditional jump to the displacement byte ($FF) which is the rst $38 opcode.
l and the table address in h. This is faster than loading the full unaligned 16-bit address and adding a 16-bit index to it, and makes accessing tables with a size of 256 bytes or less very convenient:
Instead of:
sub hl,deInstead of:
Two's complement takes care of the rest.
call and then retcan be optimised to
negChanges hl to -hl in 6 bytes and 24 cycles.
Rather than
...you can save a bit of space and execution time with:
...which changes the "or a" into a (relatively) harmless ld a,$b7, at the cost of being quite obtuse to read. It saves you 1 byte and 8 cycles (or 2 bytes and 6 cycles if you used a jp instead of a jr in the first case).
b register to hold 8-bit loop counters. This allows the djnz instruction to be used, which efficiently decrements the counter and performs a conditional jump back to the top of the loop.
b is not available and the counter is placed in a different register, the loop will require separate decrement and jump instructions. If the loop body is likely to execute 3 or more times, it is faster to use dec & jp nz rather than the slightly smaller dec & jr nz.