Z80 Routines:Graphic:put8x8sprite
From WikiTI
		
		
		
The put8xBsprite routine is used to plot a 8xB sized sprite.
Contents
Code
Basic Version
putSprite8xb: ld h,$00 ld d,h #ifdef faster sla e ;*2 sla e ;*4 #endif ld l,e add hl,de ;*2 faster:*8 add hl,de ;*3 faster:*12 #ifndef faster add hl,hl ;*6 add hl,hl ;*12 #endif ld e,a srl e srl e srl e add hl,de ld de,gbuf add hl,de and 7 ld c,a putSpriteLoop1: ld d,(ix) ld e,$00 ld a,c or a jr z,putSpriteSkip1 putSpriteLoop2: srl d rr e dec a jr nz,putSpriteLoop2 putSpriteSkip1: ld a,(hl) xor d ld (hl),a inc hl ld a,(hl) xor e ld (hl),a ld de,$0B add hl,de inc ix djnz putSpriteLoop1 ret
Masked Version
PutSpriteMask:
; Displays an 8x8 masked sprite
; A = x coordinate
; E = y coordinate
; IX = address of sprite
; IX + 8 = address of mask
    LD     H, 0
    LD     D, H
    LD     E, L
    ADD    HL, HL
    ADD    HL, DE
    ADD    HL, HL
    ADD    HL, HL
    LD     E, A
    SRL    E
    SRL    E
    SRL    E
    ADD    HL, DE
    LD     DE, PlotSScreen
    ADD    HL, DE
    AND    7
    JR     Z, _Aligned
    LD     C, A
    LD     B,8
_RowLoop:
    PUSH   BC
    LD     B, C
    LD     D, (IX)
    LD     A, (IX + 8)
    LD     C, 0
    LD     E, C
_ShiftLoop:
    SRL    A
    RR     C
    SRL    D
    RR     E
    DJNZ   _ShiftLoop
    CPL
    AND    (HL)
    XOR    D
    LD     (HL), A
    INC    HL
    LD     A, C
    CPL
    AND    (HL)
    XOR    E
    LD     (HL), A
    LD     DE, 12
    ADD    HL, DE
    INC    IX
    POP    BC
    DJNZ   _RowLoop
    RET
_Aligned:
    LD     DE, 12
_PutLoop
    LD     A, (IX + 8)
    AND    (HL)
    XOR    (IX)
    LD     (HL), A
    INC    IX
    ADD    HL, DE
    DJNZ   _PutLoop
    RET
 
Full Clipping (vertical and horizontal) Version
ClipSprXOR:
; D = xpos
; E = ypos
; B = height
; IX = image address
; Start by doing vertical clipping
    LD     A, %11111111         ; Reset clipping mask
    LD     (clip_mask), A
    LD     A, E                 ; If ypos is negative
    OR     A                    ; try clipping the top
    JP     M, ClipTop           ;
 
    SUB    64                   ; If ypos is >= 64
    RET    NC                   ; sprite is off-screen
    NEG                         ; If (64 - ypos) > height
    CP     B                    ; don't need to clip
    JR     NC, VertClipDone     ; 
    LD     B, A                 ; Do bottom clipping by
    JR     VertClipDone         ; setting height to (64 - ypos)
ClipTop:
    LD     A, B                 ; If ypos <= -height
    NEG                         ; sprite is off-screen
    SUB    E                    ;
    RET    NC                   ;
    PUSH   AF
    ADD    A, B                 ; Get the number of clipped rows
    LD     E, 0                 ; Set ypos to 0 (top of screen)
    LD     B, E                 ; Advance image data pointer
    LD     C, A                 ;
    ADD    IX, BC               ;
    POP    AF
    NEG                         ; Get the number of visible rows
    LD     B, A                 ; and set as height
VertClipDone:
; Now we're doing horizontal clipping
    LD     C, 0                 ; Reset correction factor
    LD     A, D
    CP     -7                   ; If 0 > xpos >= -7
    JR     NC, ClipLeft         ; clip the left side
    CP     96                   ; If xpos >= 96
    RET    NC                   ; sprite is off-screen
    CP     89                   ; If 0 <= xpos < 89
    JR     C, HorizClipDone     ; don't need to clip
ClipRight:
    AND    7                    ; Determine the clipping mask
    LD     C, A
    LD     A, %11111111
FindRightMask:
    ADD    A, A
    DEC    C
    JR     NZ, FindRightMask
    LD     (clip_mask), A
    LD     A, D
    JR     HorizClipDone
ClipLeft:
    AND    7                    ; Determine the clipping mask
    LD     C, A
    LD     A, %11111111
FindLeftMask:
    ADD    A, A
    DEC    C
    JR     NZ, FindLeftMask
    CPL
    LD     (clip_mask), A
    LD     A, D
    ADD    A, 96                ; Set xpos so sprite will "spill over"
    LD     C, 12                ; Set correction
HorizClipDone:
; A = xpos
; E = ypos
; B = height
; IX = image address
; Now we can finally display the sprite.
    LD     H, 0
    LD     D, H
    LD     L, E
    ADD    HL, HL
    ADD    HL, DE
    ADD    HL, HL
    ADD    HL, HL
    LD     E, A
    SRL    E
    SRL    E
    SRL    E
    ADD    HL, DE
    LD     DE, PlotSScreen
    ADD    HL, DE
    LD     D, 0                 ; Correct graph buffer address
    LD     E, C                 ; if clipping the left side
    SBC    HL, DE               ;
    AND    7
    JR     Z, _Aligned
    LD     C, A
    LD     DE, 11
_RowLoop:
    PUSH   BC
    LD     B, C
    LD     A, (clip_mask)       ; Mask out the part of the sprite
    AND    (IX)                 ; to be horizontally clipped
    LD     C, 0
_ShiftLoop:
    SRL    A
    RR     C
    DJNZ   _ShiftLoop
    XOR    (HL)
    LD     (HL), A
    INC    HL
    LD     A, C
    XOR    (HL)
    LD     (HL), A
    ADD    HL, DE
    INC    IX
    POP    BC
    DJNZ   _RowLoop
    RET
_Aligned:
    LD     DE, 12
_PutLoop:
    LD     A, (IX)
    XOR    (HL)
    LD     (HL), A
    INC    IX
    ADD    HL, DE
    DJNZ   _PutLoop
    RET
clip_mask:      .DB     0
 
Example
A example using the basic version of PutSprite.
;... ld e,8 ;y ld a,16 ;x ld b,8 ;height ld ix,sprite call putsprite call fastcopy ;... sprite: .db %11111111 .db %10000001 .db %10000001 .db %10000001 .db %10000001 .db %10000001 .db %10000001 .db %11111111