A piece of criticism on "to go fast, do less"
-
My Z-80 is a little rusty (last program I wrote in Z-80 code was the Bally Astrocade Biorhythm cartridge back in '80). But I had a friend look over your example and he came back with this comment/suggestion...
Odd code. Z80 has bit tests and yes they only take a constant for the bit number. Plus a second value which is the register or address pointed to by the HL or pointed to by one of the 2 index registers + d (same as set & reset {res}). The Z (zero) flag indicates the state (1=zero else 0 - backwards I always thought.) An easier way to test any bit dynamically would be;
LD b, value // Value with bit to be tested
LD a, mask // b-value of bit(s) to be tested.
CALL TEST
:
:
TEST
AND b // a will be zero if the mask bit was not set and 1 if the bit was set,
// z=1 if a=0 else 0 p=1 if parity even else 0
//c=0, h=1, n=0, s=0
RETPsychosis at 10 Film at 11
Sure, except that inlining the AND is actually shorter (and faster). Of course this doesn't always quite work out, since you're destroying A. Or, if you're testing a bit on A, you're destroying some other register to hold the bitmask. There aren't that many registers.. Doing it the "easy" way could especially hurt in a loop, where
ld a,mask and b
is actually slower than abit {self-modified-stuff}
- justand b
would be 1 cc faster but being able to miss A is not very common and extra loads and/or pops and pushes would ruin the performance even more. As for the oddness of the code, I can't disagree. It is decidedly odd, and doesn't work on any new processors. I know of no other way to atomically take a lock in the presence of NMI's though (if there are only normal interrupts, di/ei would work - and maybe some extra logic to only ei if interrupts were enabled)