Prev: F6C3 Up: Map Next: F7EE
F76F: XOR Blit Sprite
Used by the routines at AnimateIntroSprites and DrawIntroSprites.
Takes the two-byte position entry at HL (byte 00 = Y pixel row, byte 01 = X byte column) and the attribute byte in E (shadow; bit 7 set = erase mode, bit 7 clear = draw mode). Computes each screen pixel address by reading the row base from the screen row LUT at 8C00 (indexed by Y) and adding the X column byte offset stored in shadow D. XORs 04 bytes of the fixed bitmap at 6CFC into consecutive screen pixel memory for each of 20 pixel rows (04 attribute-cell rows of 08 pixel rows each). After the first pixel row of each attribute-cell row, derives the attribute memory high byte from the pixel address high byte and writes the attribute byte to 04 consecutive attribute cells — suppressed in erase mode.
Input
HL Pointer to the two-byte position entry (Y pixel row at +0, X byte column at +1)
Initialise the bitmap source (HL=6CFC via EX DE,HL) and compute IX into the screen row LUT at 8C00 indexed by the Y pixel row. The row is shifted left into the LUT index directly (IX=8C00 + Y × 02). Store the X column byte offset in shadow D and set the outer loop count (C=04 shadow, one iteration per attribute-cell row of 08 pixel rows).
XorBlitSprite F76F LD DE,$6CFC DE=6CFC (bitmap source base address; becomes HL via EX DE,HL).
F772 LD B,$46 B=46 (initial high byte; becomes 8C or 8D after RL B).
F774 LD C,(HL) C=Y pixel row (byte 00 of the position entry).
F775 INC HL Advance HL to byte 01 (X byte column).
F776 SLA C SLA C; carry = bit 7 of Y (selects high byte 8C or 8D).
F778 RL B RL B; B=8C (or 8D if carry set) — high byte of LUT pointer.
F77A PUSH BC Stash BC on the stack.
F77B LD A,(HL) A=X byte column (byte 01 of the position entry).
F77C EXX Switch to the shadow registers.
F77D LD D,A D=X byte column offset (held in shadow across all loop iterations).
F77E EXX Switch back to the normal registers.
F77F POP IX POP IX; IX=8C00 + Y × 02 (pointer into the screen row LUT).
F781 EX DE,HL HL=6CFC (bitmap source pointer); DE=old HL (discarded).
F782 EXX Switch to the shadow registers.
F783 LD C,$04 C=04 (shadow, outer loop count: 04 attribute-cell rows).
F785 EXX Switch back to the normal registers.
Outer loop (04 iterations, one per attribute-cell row of 08 pixel rows). Compute the screen pixel address for the first row of this attribute cell: read shadow D (X column), add the LUT low byte from *(IX) to give E, then read the LUT high byte from *(IX+01) into D. Advance IX by two to the next LUT entry.
XorBlitSprite_OuterLoop F786 EXX Switch to the shadow registers.
F787 LD A,D A=D (X byte column offset).
F788 EXX Switch back to the normal registers.
F789 ADD A,(IX+$00) A += *(IX) (LUT low byte); low byte of screen pixel address.
F78C INC IX Advance IX to the LUT high byte.
F78E LD E,A E=A (low byte of screen pixel address).
F78F LD D,(IX+$00) D=*(IX) (high byte of screen pixel address from LUT).
F792 INC IX Advance IX to the next LUT entry.
XOR 04 consecutive bytes of the bitmap at (HL)–(HL+03) into screen pixel memory at (DE)–(DE+03), advancing both pointers.
F794 LD A,(DE) *(DE) ^= *(HL); advance DE and HL.
F795 XOR (HL)
F796 LD (DE),A
F797 INC DE
F798 INC HL
F799 LD A,(DE) *(DE) ^= *(HL); advance DE and HL.
F79A XOR (HL)
F79B LD (DE),A
F79C INC DE
F79D INC HL
F79E LD A,(DE) *(DE) ^= *(HL); advance DE and HL.
F79F XOR (HL)
F7A0 LD (DE),A
F7A1 INC HL
F7A2 INC DE
F7A3 LD A,(DE) *(DE) ^= *(HL); advance HL.
F7A4 XOR (HL)
F7A5 LD (DE),A
F7A6 INC HL
Derive the attribute memory address high byte from the current pixel address high byte in D. Three right-rotations expose the screen-third index in bits 00–01; OR with 58 gives the attribute area high byte (58–5B).
F7A7 LD A,D D = (RRCA × 03 of D) AND 03 OR 58 (attribute address high byte).
F7A8 RRCA
F7A9 RRCA
F7AA RRCA
F7AB AND $03
F7AD OR $58
F7AF LD D,A
Test the erase-mode flag (bit 7 of shadow E). If set, skip writing the attribute byte so that the background colour is preserved during erase.
F7B0 EXX Switch to shadow; A=E (attribute byte); switch back.
F7B1 LD A,E
F7B2 EXX
F7B3 BIT 7,A Test bit 7 of A (erase-mode flag).
F7B5 JR NZ,XorBlitSprite_InnerSetup If in erase mode, jump to XorBlitSprite_InnerSetup (skip attribute write).
F7B7 LD (DE),A Write attribute byte to (DE), (DE−01), (DE−02) and (DE−03).
F7B8 DEC DE
F7B9 LD (DE),A
F7BA DEC DE
F7BB LD (DE),A
F7BC DEC DE
F7BD LD (DE),A
XorBlitSprite_InnerSetup F7BE EXX Switch to shadow; B=07 (remaining pixel rows in this attribute-cell row); switch back.
F7BF LD B,$07
F7C1 EXX
Inner loop (07 iterations, one per remaining pixel row in this attribute-cell row). Compute the screen address from the LUT and XOR 04 bitmap bytes into pixel memory. No attribute write.
XorBlitSprite_InnerLoop F7C2 EXX Switch to the shadow registers.
F7C3 LD A,D A=D (X byte column offset).
F7C4 EXX Switch back to the normal registers.
F7C5 ADD A,(IX+$00) A += *(IX) (LUT low byte for this pixel row).
F7C8 INC IX Advance IX to the LUT high byte.
F7CA LD E,A E=A (low byte of screen pixel address).
F7CB LD D,(IX+$00) D=*(IX) (high byte of screen pixel address from LUT).
F7CE INC IX Advance IX to the next LUT entry.
F7D0 LD A,(DE) *(DE) ^= *(HL); advance DE and HL.
F7D1 XOR (HL)
F7D2 LD (DE),A
F7D3 INC DE
F7D4 INC HL
F7D5 LD A,(DE) *(DE) ^= *(HL); advance DE and HL.
F7D6 XOR (HL)
F7D7 LD (DE),A
F7D8 INC DE
F7D9 INC HL
F7DA LD A,(DE) *(DE) ^= *(HL); advance DE and HL.
F7DB XOR (HL)
F7DC LD (DE),A
F7DD INC HL
F7DE INC DE
F7DF LD A,(DE) *(DE) ^= *(HL); advance HL.
F7E0 XOR (HL)
F7E1 LD (DE),A
F7E2 INC HL
F7E3 EXX Switch to shadow; decrement B (inner pixel row counter); switch back.
F7E4 DEC B
F7E5 EXX
F7E6 JR NZ,XorBlitSprite_InnerLoop Loop back to XorBlitSprite_InnerLoop until all 07 pixel rows are blitted.
F7E8 EXX Switch to shadow; decrement C (outer attribute-row counter); switch back.
F7E9 DEC C
F7EA EXX
F7EB JR NZ,XorBlitSprite_OuterLoop Loop back to XorBlitSprite_OuterLoop until all 04 attribute-cell rows are blitted.
F7ED RET Return.
Prev: F6C3 Up: Map Next: F7EE