I'm referencing this Space Invaders code.
Could someone explain why the PrintMessageDel routine checks for a delay value of one instead of zero?
The interrupt service routine decrements the isrDelay variable. So why not start with a value of 6 and exit on zero instead of starting with 7 and exiting on one? There isn't even a need to do a decrement in PrintMessageDel, it's a wasted instruction, right?
PrintMessageDel:
; Print message from DE to screen at HL (length in C) with a
; delay between letters.
0A93: D5 PUSH DE ; Preserve
0A94: 1A LD A,(DE) ; Get character
0A95: CD FF 08 CALL DrawChar ; Draw character on screen
0A98: D1 POP DE ; Preserve
0A99: 3E 07 LD A,$07 ; Delay between letters
0A9B: 32 C0 20 LD (isrDelay),A ; Set counter
0A9E: 3A C0 20 LD A,(isrDelay) ; Get counter
0AA1: 3D DEC A ; Is it 1?
0AA2: C2 9E 0A JP NZ,$0A9E ; No ... wait on it
0AA5: 13 INC DE ; Next in message
0AA6: 0D DEC C ; All done?
0AA7: C2 93 0A JP NZ,PrintMessageDel ; No ... do all
0AAA: C9 RET
Here's the interrupt routine where isrDelay gets decremented. Note that this specific 8080 decrement command actually decrements the isrDelay memory location.
ScanLine224:
; Interrupt brings us here when the beam is at the end of the screen (line 224) when the VBLANK begins.
0010: F5 PUSH AF ; Save ...
0011: C5 PUSH BC ; ...
0012: D5 PUSH DE ; ...
0013: E5 PUSH HL ; ... everything
0014: 3E 80 LD A,$80 ; Flag that tells objects ...
0016: 32 72 20 LD (vblankStatus),A ; ... on the lower half of the screen to draw/move
0019: 21 C0 20 LD HL,isrDelay ; Decrement ...
001C: 35 DEC (HL) ; ... the general countdown (used for pauses)
001D: CD CD 17 CALL CheckHandleTilt ; Check and handle TILT
0020: DB 01 IN A,(INP1) ; Read coin switch
0022: 0F RRCA ; Has a coin been deposited (bit 0)?
0023: DA 67 00 JP C,$0067 ; Yes ... note that switch is closed and continue at 3F with A=1
0026: 3A EA 20 LD A,(coinSwitch) ; Switch is now open. Was it ...
0029: A7 AND A ; ... closed last time?
002A: CA 42 00 JP Z,$0042 ; No ... skip registering the credit
EDIT: I should have said that the posted code is Z80 assembly, not 8080. I was mistaken.
AND A
for isrDelay=0..6 would have done exactly the same asDEC A
for isrDelay=1..7, both update theZ
ero flag forA
. Can only assume it's a programmer's whim, there's no logic for choosing one over the other unless isrDelay is also used elsewhere.AND A
instruction ANDs the accumulatorA
with itself, naturally leavingA
unchanged. What it does do though is update the Zero flag and clear the Carry flag, so it's often used just for those functions: testing ifA
is zero and/or clearing Carry. Same goes for theOR A
instruction. (Just to round off the set, theXOR A
instruction is more useful as it loadsA
with zero. Being a 1-byte instruction, it's very often used instead of the 2-byteLD A,0
.)