|
|
(10 intermediate revisions by 4 users not shown) |
Line 1: |
Line 1: |
− | [[Category:Z80 Routines:Graphic|largesprite]][[Category:Z80 Routines|largesprite]] | + | #REDIRECT [[Z80_Routines:Graphic:putLargeSprite]] |
− | | + | |
− | The '''Largesprite''' routine is used to copy the content of a sprite to the Graph Buffer.
| + | |
− | | + | |
− | Here is Joe Wingbermuehle's version, which is the one used in ION.
| + | |
− | | + | |
− | <nowiki>
| + | |
− | ;=======================
| + | |
− | ;LargeSprite
| + | |
− | ;by Joe Wingbermuehle
| + | |
− | ;=======================
| + | |
− | ;Does: Copy a sprite to the gbuf
| + | |
− | ;Input: ix=sprite address, a='x', l='y', b='height' (in pixels), c='width' (in bytes, e.g. 2 would be 16)
| + | |
− | ;Output: The sprite is copied to the gbuf
| + | |
− | ;-----------------------
| + | |
− | largeSprite:
| + | |
− | di ;turn interrupts off (we want to use shadow registers)
| + | |
− | ex af,af'
| + | |
− | ;exchange af with af' \
| + | |
− | ld a,c ;ld c in a (a = 'width') | for not destroying a ('x')
| + | |
− | push af ;push a |
| + | |
− | ex af,af'
| + | |
− | ;exchange back | and 'width' is now in a' (saved)
| + | |
− | ld e,l ;e = 'y'
| + | |
− | ld h,$00 ;h = 0
| + | |
− | ld d,h ;d = 0
| + | |
− | add hl,de ;'y' *2 \
| + | |
− | add hl,de ; *3 | calculate 'y' *12 because 'y' is 'in rows'
| + | |
− | add hl,hl ; *6 | (screen is 12 bytes in length)
| + | |
− | add hl,hl ; *12 /
| + | |
− | ld e,a ;e = 'x'
| + | |
− | and $07 ;and %00000111
| + | |
− | ld c,a ;last 3 bits in c (amount of bits to shift all bytes)
| + | |
− | srl e ;e/2 | shifting e ('x') 3 bits to the right
| + | |
− | srl e ; /4 | %11111111 becomes %00011111 for example
| + | |
− | srl e ; /8 /
| + | |
− | add hl,de ;hl = 'y'; de = 'x' (rounded) | add them
| + | |
− | ld de, gbuf ;de = the adress of graph buffer
| + | |
− | add hl,de ;add hl to the adress of the gbuf
| + | |
− | largeSpriteLoop1:
| + | |
− | push hl ;save adress
| + | |
− | largeSpriteLoop2:
| + | |
− | ld d,(ix) ;first sprite data in d
| + | |
− | ld e,$00 ;e = 0
| + | |
− | ld a,c ;a = c (to not destroy c)
| + | |
− | or a ;is a = 0? (same as cp 0)
| + | |
− | jr z,largeSpriteSkip1 ;if theres nothing to shift (a = 0) loop it
| + | |
− | largeSpriteLoop3:
| + | |
− | srl d ;shift one bit to the right; put the destroyed bit in the carry flag
| + | |
− | rr e ;put the carry flag in e (%00000000 becomes %10000000 if carry flag = 1)
| + | |
− | dec a ;decrease counter (with was 'the amount of bits to shift')
| + | |
− | jr nz,largeSpriteLoop3 ;if the counter is not 0 loop back
| + | |
− | largeSpriteSkip1:
| + | |
− | ld a,(hl) ;graphbyte in a
| + | |
− | xor d ;xor first byte of sprite (that can be changed to 'or d' if you want a OR-routine)
| + | |
− | ld (hl),a ;back to buffer
| + | |
− | inc hl ;increase pointer
| + | |
− | ld a,(hl) ;graphbyte in a
| + | |
− | xor e ;xor with shifted sprite byte (change to 'or e' for OR-routine)
| + | |
− | ld (hl),a ;back to buffer
| + | |
− | inc ix ;increase sprite adress
| + | |
− | ex af,af'
| + | |
− | ;exchange af with af' ( a is now the 'width' from the first line)
| + | |
− | dec a ;decrease 'width'
| + | |
− | push af ;push the 'width'
| + | |
− | ex af,af'
| + | |
− | ;exchange back
| + | |
− | pop af ;pop the 'width'
| + | |
− | jr nz,largeSpriteLoop2 ;if a is not 0 (if a = 0 then we would be done) loop it
| + | |
− | pop hl ;pop gbuf adress (search the last push hl!)
| + | |
− | pop af ;pop | to restore the real 'width'
| + | |
− | push af ;push /
| + | |
− | ex af,af'
| + | |
− | ;af' must be the original 'width' when loop 'largeSpriteLoop1'
| + | |
− | ld de,$0C ;ld de,12
| + | |
− | add hl,de ;next line
| + | |
− | djnz largeSpriteLoop1 ;if not b = 0 loop (b = height of sprite)
| + | |
− | pop af ;pop because we dont want a stack problem :)
| + | |
− | ret ;return</nowiki>
| + | |
− | | + | |
− | ===Differences between the 83+ and the 83 in Largesprite===
| + | |
− | You need to define 'gbuf' which is [[83Plus:RAM:9340|$9340]] on the Ti83+ and [[83:RAM:8E29|$8E29]] on the Ti83 before you include the largesprite routine.
| + | |
− | <nowiki>
| + | |
− | #ifdef TI83P
| + | |
− | #define gbuf $9340
| + | |
− | #else
| + | |
− | #define gbuf $8E29
| + | |
− | #endif</nowiki>
| + | |