Prev: A071 Up: Map Next: A095
A082: Next scanline up
This, given a screen address, returns the same position on the scanline above.
Spectrum screen memory addresses have the form:
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
0-1-0 Y7-Y6 Y2-Y1-Y0 Y5-Y4-Y3 X4-X3-X2-X1-X0
To calculate the address of the previous scanline (that is the next scanline higher up) we test two of the fields in sequence and subtract accordingly:
Y2-Y1-Y0: If this field is non-zero it's an easy case: we can just decrement the top byte (e.g. using DEC H). Only the bottom three bits of Y will be affected.
Y5-Y4-Y3: If this field is zero we can add $FFE0 (-32) to HL. This is like adding "-1" to the register starting from bit 5 upwards. Since Y2-Y1-Y0 and Y5-Y4-Y3 are both zero here we don't care about bits propagating across boundaries.
Otherwise we add $06E0 (0000 0110 1110 0000) to HL. This will add 111 binary or "-1" to the Y5-Y4-Y3 field, which will carry out into Y0 for all possible values. Simultaneously it adds 110 binary or "-2" to the Y2-Y1-Y0 field (all zeroes) so the complete field becomes 111. Thus the complete field is decremented.
Used by the routine at wave_morale_flag.
Input
HL Original screen address.
Output
HL Updated screen address.
next_scanline_up A082 LD A,H If Y2-Y1-Y0 zero jump to the complicated case
A083 AND $07
A085 JR Z,next_scanline_up_0
Easy case.
A087 DEC H Just decrement the high byte of the address to go back a scanline
A088 RET Return
Complicated case.
next_scanline_up_0 A089 LD DE,$06E0 Load DE with $06E0 by default
A08C LD A,L Is L < 32?
A08D CP $20
A08F JR NC,next_scanline_up_1 Jump if not
A091 LD D,$FF If so bits Y5-Y4-Y3 are clear. Load DE with $FFE0 (-32)
next_scanline_up_1 A093 ADD HL,DE Add
A094 RET Return
Prev: A071 Up: Map Next: A095