Mensaje original de RobsyHola. Aqui os dejo unas rutinas que os pueden ayudar. Estan muy lejos de ser "optimas" pero funcionan bien, que es de lo que se trata. No usan ningun buffer en RAM aparte de la pila, claro. Por eso alguna parte es un poco "oscura". Salud y saludos.
;----------------------------------------------
; SPRITE MIRRORING
; Eduardo A. Robsy Petrus [22/04/2005]
; (c) Karoshi Corporation, 2005
;----------------------------------------------
; Horizontal and vertical mirroring routines
; for 16x16 sized sprites in VRAM.
;----------------------------------------------
; - Does not use temporary RAM, only the stack.
; - Total assembled size: 110 bytes.
; - Requires the .BIOS directive to be used and
; BIOS routines available in page 0.
; - Requires SPRTBL label to point to VRAM
; sprite pattern table (BIOS default: 3800h).
;----------------------------------------------
; PROs: Reliable, does not use a RAM buffer.
; CONs: Not very fast, not very compact.
;----------------------------------------------
;----------------------------------------------
SPRITE_H_MIRROR:
; Horizontal sprite mirroring
;----------------------------------------------
; Input: A=original sprite number
; B=mirrored sprite number
; Output: none
; Modifies: AF,BC,DE,HL,EI
;----------------------------------------------
; Calculate original sprite address
call MULT32
ld a,b
ld bc,SPRTBL
add hl,bc
; Store original address in DE
ex de,hl
; Calculate mirrored sprite address
call MULT32
add hl,bc
; Store in HL and save into the stack
push hl
; Adjust HL to second part
ld bc,16
add hl,bc
; Copy and invert second half
call @@COPY16
; Copy and invert first half
pop hl
call @@COPY16
; Done
ret
; Copy and inverts 16 bytes of VRAM (DE->HL)
@@COPY16:
ld b,16
; Copy loop
@@COPY:
; Read byte
ex de,hl
call RDVRM
; Invert byte
push bc
push hl
ld b,8
@@INVERT:
rla
ld l,a
ld a,c
rra
ld c,a
ld a,l
djnz @@INVERT
ld a,c
pop hl
pop bc
; Write byte
ex de,hl
call WRTVRM
; Increase pointers
inc de
inc hl
djnz @@COPY
; Done
ret
;----------------------------------------------
;----------------------------------------------
SPRITE_V_MIRROR:
; Vertical sprite mirroring
;----------------------------------------------
; Input: A=original sprite number
; B=mirrored sprite number
; Output: none
; Modifies: AF,BC,DE,HL,EI
;----------------------------------------------
; Original address
; (ORIGINAL_NUM*32)+SPRITE_TABLE
call MULT32
ld a,b
ld bc,SPRTBL
add hl,bc
; Store original address in DE
ex de,hl
call MULT32
add hl,bc
; Push into stack
push hl
ld bc,15
add hl,bc
call @@COPY16
pop hl
ld bc,31
add hl,bc
call @@COPY16
ret
; DE->HL 16 bytes, VRAM
@@COPY16:
ld b,16
@@COPY:
ex de,hl
call RDVRM
ex de,hl
call WRTVRM
inc de
dec hl
djnz @@COPY
ret
;----------------------------------------------
;----------------------------------------------
MULT32:
; Support function
;----------------------------------------------
; Input: A=value
; Output: HL=value*32
; Modifies: HL
;----------------------------------------------
ld l,a
ld h,0
add hl,hl
add hl,hl
add hl,hl
add hl,hl
add hl,hl
ret
;----------------------------------------------
Con la mejora de Ricardo Bittencourt
:
MULT32 is very, very slow. Use this instead:
MULT32:
RRCA
RRCA
LD L,A
AND 31
LD H,A
XOR L
LD L,A
RET