Manic Miner: Routine at 8FF4

| Routines

8FF4: Draw a sprite

Used by the routines at 85CC (to draw Willy on the title screen), 870E (to draw the remaining lives), 8944 (to draw Willy, the boot and the plinth during the game over sequence), 8DAA (to draw horizontal guardians), 8DF8 (to draw Eugene in Eugene's Lair), 8E75 (to draw the Skylabs in Skylab Landing Bay), 8EF1 (to draw vertical guardians), 8FC5 (to draw the portal in the current cavern), 9028 (to draw Willy above ground and the swordfish graphic over the portal in The Final Barrier) and 9135 (to draw the Kong Beast in Miner Willy meets the Kong Beast and Return of the Alien Kong Beast). If C=1 on entry, this routine returns with the zero flag reset if any of the set bits in the sprite being drawn collides with a set bit in the background.
Input
C | Drawing mode: 0 (overwrite) or 1 (blend)
DE | Address of sprite graphic data
HL | Address to draw at
8FF4 | LD B,$10 | There are 16 rows of pixels to draw
8FF6 | BIT 0,C | Set the zero flag if we're in overwrite mode
8FF8 | LD A,(DE) | Pick up a sprite graphic byte
8FF9 | JR Z,$8FFF | Jump if we're in overwrite mode
8FFB | AND (HL) | Return with the zero flag reset if any of the set bits in the sprite graphic byte collide with a set bit in the background (e.g. in Willy's sprite)
8FFC | RET NZ
8FFD | LD A,(DE) | Pick up the sprite graphic byte again
8FFE | OR (HL) | Blend it with the background byte
8FFF | LD (HL),A | Copy the graphic byte to its destination cell
9000 | INC L | Move HL along to the next cell on the right
9001 | INC DE | Point DE at the next sprite graphic byte
9002 | BIT 0,C | Set the zero flag if we're in overwrite mode
9004 | LD A,(DE) | Pick up a sprite graphic byte
9005 | JR Z,$900B | Jump if we're in overwrite mode
9007 | AND (HL) | Return with the zero flag reset if any of the set bits in the sprite graphic byte collide with a set bit in the background (e.g. in Willy's sprite)
9008 | RET NZ
9009 | LD A,(DE) | Pick up the sprite graphic byte again
900A | OR (HL) | Blend it with the background byte
900B | LD (HL),A | Copy the graphic byte to its destination cell
900C | DEC L | Move HL to the next pixel row down in the cell on the left
900D | INC H
900E | INC DE | Point DE at the next sprite graphic byte
900F | LD A,H | Have we drawn the bottom pixel row in this pair of cells yet?
9010 | AND $07
9012 | JR NZ,$9024 | Jump if not
9014 | LD A,H | Otherwise move HL to the top pixel row in the cell below
9015 | SUB $08
9017 | LD H,A
9018 | LD A,L
9019 | ADD A,$20
901B | LD L,A
901C | AND $E0 | Was the last pair of cells at y-coordinate 7 or 15?
901E | JR NZ,$9024 | Jump if not
9020 | LD A,H | Otherwise adjust HL to account for the movement from the top or middle third of the screen to the next one down
9021 | ADD A,$08
9023 | LD H,A
9024 | DJNZ $8FF6 | Jump back until all 16 rows of pixels have been drawn
9026 | XOR A | Set the zero flag (to indicate no collision)
9027 | RET |