Z88 Developers' Notes error

Note that there is a serious performance bug in the Eprom programming example
in section 2.20.

The idea of the code fragment is to try programming the EPROM a maximum of 75
times, then overprogram it however many times it took to program.

The initial programming loop uses B as a loop counter ("LD B,75; ...; DJNZ
proloop"). However if the programming succeeds on the very first attempt, the
"JR Z,byteok" jumps past the "DJNZ", and B remains at 75.

Now "LD A,75; SUB B; LD B,A", loads B with 0. Unfortunately this effectively
acts as a loop count of 256 from the point of view of the second loop,
because "DJNZ" decrements (to 255) before testing for zero. This means that:

 * if program took 1 step, the overprogramming was 256 times

 * otherwise if program took n steps, overprogramming was (n - 1) times

The fix is to change the second "75" to "76"; then the second loop is
executed exactly the same number of times as the first.

  LD      B,75    ; Maximum number of attempts
  LD      A,&48   ; For 32K EPROMs
  OUT     (&B3),A ; Set EPROM programming signals
  .proloop
  LD      A,&0E
  OUT     (&B0),A ; Set Vpp and PROGRAM bits
  LD      (HL),C  ; Write byte
  LD      A,&04
  OUT     (&B0),A ; Reset Vpp and PROGRAM bits
  LD      A,(HL)
  CP      C       ; Verify byte
  JR      Z,byteok
  DJNZ    proloop
  < give an error - unable to write byte>
  .byteok
  LD      A,76
  SUB     B
  LD      B,A     ; Same number of times it took to program
  .ovploop
  LD      A,&2E
  OUT     (&B0),A ; Set Vpp, PROGRAM and OVERPROGRAM
  LD      (HL),C  ; Write byte
  LD      A,&04
  OUT     (&B0),A ; Reset Vpp, PROGRAM and OVERPROGRAM
  DJNZ    ovploop ; Repeat
  LD      A,&05
  OUT     (&B0),A ; Turn screen back on.
  RET

We all make mistakes.