Помощь с оптимизацией кода
Буду очень благодарен, если кто-нибудь придумает, как можно ускорить этот код без кардинальных изменений в способе вывода.
Это - вывод монохромного спрайта с маской на произвольную координату экрана. Сам спрайт имеет произвольную высоту/ширину (в байтах, не в пикселях).
Байты не смещаются на ходу, а используется предварительно рассчитанная таблица всех вариантов смещений для всех возможных вариантов байта (4кб).
Код:
SPRXCO DB 4
SPRYCO DB 0
SPRXLEN DB 3
SPRYLEN DB 48
SPRITESRC EQU #9B00
DRAWSPRITE
;check if sprite should be displayed without shifting
LD A,(SPRXCO)
AND 7
JP Z,DRAWNOX
;--------------------------------------------------
;---------------INITIALISATION---------------------
;--------------------------------------------------
ADD A,#B0
LD (RIGHTSIDE1+1),A
LD (RIGHTSIDE2+1),A
LD (RIGHTSIDE3+1),A
LD (RIGHTSIDE4+1),A
ADD A,8
LD (LEFTSIDE1+1),A
LD (LEFTSIDE2+1),A
LD (LEFTSIDE3+1),A
LD (LEFTSIDE4+1),A
LD BC,(SPRADR) ;BC = destination address on screen
LD DE,SPRITESRC ;DE = source address in memory
LD A,(SPRYLEN)
LD IXL,A ;ixl = sprite's height
LD A,(SPRXLEN)
DEC A
LD (DRAWSPRITEITELINE+2), A ;HARDCODED SPRITE'S WIDTH
;----------------------------------------------
;---------------MAIN CYCLE---------------------
;----------------------------------------------
DRAWSPRITEITELINE
LD IXH,0 ;ixh = sprite's width, HERE GOES A HARDCODE FROM INIT
PUSH BC
;-------START DRAWING RIGHT SIDE OF LEFT BYTE--------
LD A,(DE) ;READ COPY BYTE OF MASK FOR NEXT SCREEN BYTE
EX AF,AF'
LD A,(DE) ;READ BYTE OF MASK
RIGHTSIDE1
LD H,00
LD L,A ;HL = BYTE ADDRESS IN RIGHTSIDE PRESHIFTED TABLE
LD A,(BC) ;READ BYTE FROM SCREEN
OR (HL)
XOR (HL) ;APPLY PRESHIFTED MASK FROM TABLE
LD H,A ;SAVE TEMPORARY RESULT IN H
INC DE
LD A,(DE) ;READ BYTE OF SPRITE
LD L,A
LD A,H
RIGHTSIDE2
LD H,00 ;HL = BYTE ADDRESS IN RIGHTSIDE PRESHIFTED TABLE
OR (HL) ;APPLY PRESHIFTED SPRITE FROM TABLE
LD (BC),A ;LEFT HALFBYTE OF LEFT SIDE OF SPRITE IS DONE, PLACE IT BACK ON SCREEN
INC BC
;-------START DRAWING LEFT SIDE OF CENTER BYTE--------
DRAWSPRITEITECENTER
LD A,L ;SAVE LEFT SPRITE BYTE IN A
EX AF,AF' ;A = SAVED LEFT BYTE OF MASK
LEFTSIDE1
LD H,00
LD L,A ;HL = BYTE ADDRESS IN LEFTSIDE PRESHIFTED TABLE
LD A,(BC) ;READ FROM SCREEN
OR (HL)
XOR (HL) ;APPLY LEFT MASK BYTE FROM TABLE
LD H,A ;SAVE TEMPORARY RESULT IN H
EX AF,AF' ;A = SAVED LEFT BYTE OF SPRITE
LD L,A
LD A,H ;RESTORE TEMPORARY RESULT
LEFTSIDE2
LD H,00 ;HL = BYTE ADDRESS IN LEFTSIDE PRESHIFTED TABLE
OR (HL) ;APPLY LEFT SPRITE BYTE FROM TABLE
LD H,A ;SAVE TEMPORARY RESULT (READY LEFT SIDE OF ONSCREEN BYTE) IN H
INC DE
;-------START DRAWING RIGHT SIDE OF CENTER BYTE--------
LD A,(DE) ;READ COPY BYTE OF MASK FOR NEXT SCREEN BYTE
EX AF,AF'
LD A,(DE) ;READ BYTE OF MASK
LD L,A
LD A,H ;RESTORE TEMPORARY RESULT FROM H
RIGHTSIDE3
LD H,00 ;HL = BYTE ADDRESS IN RIGHTSIDE PRESHIFTED TABLE
OR (HL)
XOR (HL) ;APPLY PRESHIFTED MASK FROM TABLE
LD H,A ;SAVE TEMPORARY RESULT IN H
INC DE
LD A,(DE) ;READ BYTE OF SPRITE
LD L,A
LD A,H
RIGHTSIDE4
LD H,00 ;HL = BYTE ADDRESS IN RIGHTSIDE PRESHIFTED TABLE
OR (HL) ;APPLY PRESHIFTED SPRITE FROM TABLE
LD (BC),A ;LEFT HALFBYTE OF LEFT SIDE OF SPRITE IS DONE, PLACE IT BACK ON SCREEN
INC BC
DEC IXH
JR NZ,DRAWSPRITEITECENTER
;-------START DRAWING LEFT SIDE OF RIGHT BYTE--------
LD A,L ;SAVE LEFT SPRITE BYTE IN A
EX AF,AF' ;A = SAVED LEFT BYTE OF MASK
LEFTSIDE3
LD H,00
LD L,A ;HL = BYTE ADDRESS IN LEFTSIDE PRESHIFTED TABLE
LD A,(BC) ;READ FROM SCREEN
OR (HL)
XOR (HL) ;APPLY LEFT MASK BYTE FROM TABLE
LD H,A ;SAVE TEMPORARY RESULT IN H
EX AF,AF' ;A = SAVED LEFT BYTE OF SPRITE
LD L,A
LD A,H ;RESTORE TEMPORARY RESULT
LEFTSIDE4
LD H,00 ;HL = BYTE ADDRESS IN LEFTSIDE PRESHIFTED TABLE
OR (HL) ;APPLY LEFT SPRITE BYTE FROM TABLE
LD (BC),A
INC DE
POP BC
DEC IXL
RET Z
INC B
LD A,B
AND 7
JR NZ,DRAWSPRITEITELINE
LD A,C
ADD A,32
LD C,A
JR C,DRAWSPRITEITELINE
LD A,B
SUB 8
LD B,A
JR DRAWSPRITEITELINE
Добавлено через 7 часов 28 минут
не стану делать новую тему, но вопрос косвенно связан с предыдущим: расскажите пожалуйста в трех словах о выводе спрайтов стеком. параметры те же.
в чем будет выигрыш? всё равно ведь спрайтам надо делать побитовое смещение или пользоваться табличкой, как сверху?
ну, прежде всего, не нужно будет пользоваться downhl, верно? но разве это окупит затраты на переброску результата стеком?
мне кажется, что я чего-то глобально недопонимаю в этом методе, потому что я почти не вижу ему применения при более-менее универсальном использовании.