How about this?
It now has an inner loop and an outer loop, and the saving/restoring of SP is only done by the outer loop.
So the DI/EI and SP operations are done 20 times instead of 160.
This saves 1400 NOPs per call.
Also, I added EXX before the RET, as we need to switch back to standard registers before returning from the function.
PLEASE BE CAREFUL with this code if you are sensitive to brightly flashing colours on-screen.
#include <cpctelera.h>
void fillView(u8*);
u8 counter;
void main(void) {
cpct_disableFirmware();
cpct_clearScreen_f64(0x00);
cpct_setBorder(1);
cpct_setDrawCharM1(2,0);
counter=0;
while (1){
fillView((u8*)CPCT_VMEM_START+160);
counter++;
}
}
void fillView(u8* backBuffer){
__asm
;; Parameter *memory* is directly given in HL register, using __z88dk_fastcall convention
;; Not fill Border Right 8-bytes
ld bc, #0x0008 ;; [3] BC = 8-bytes Border Width
sbc hl, bc ;; [4] HL = HL - BC
ld de, #0x01C0 ;; [3] DE = 0x640 + Next PixelLine End (0x01C0) = 0x800
ld c, #0x50 ;; [2] BC = 80-bytes ScanLine (0x0050)
ld a, #08 ;; [2] A = Number of Character per line
exx
ld de,(_counter) ;; set fill colour to counter variable, in both D and E
ld d,e
ld c,#20
ld b,c
;; Fill 80-bytes ScanLine
fillLoop_raster:
;; Save SP to restore it later, as this function makes use of it
di ;; [1] Disable interrupts first
ld (fv_restore_sp + 1), sp ;; [5] Save SP to recover it later on
fillLoop_character:
exx ;; [1] Switch to Standard Registers
;; Move SP to the end of the array
add hl, bc ;; [3] HL += BC (0x50) Start CharacterLine (HL points to the end of the array)
ld sp, hl ;; [2] SP = HL (SP points to the end of the array)
exx ;; [1] Switch to Alternate Registers
;; Fill Center View 64-bytes
push de ;; [4] Push 8-bytes
push de ;; [4]
push de ;; [4]
push de ;; [4]
push de ;; [4] Push 8-bytes
push de ;; [4]
push de ;; [4]
push de ;; [4]
push de ;; [4] Push 8-bytes
push de ;; [4]
push de ;; [4]
push de ;; [4]
push de ;; [4] Push 8-bytes
push de ;; [4]
push de ;; [4]
push de ;; [4]
push de ;; [4] Push 8-bytes
push de ;; [4]
push de ;; [4]
push de ;; [4]
push de ;; [4] Push 8-bytes
push de ;; [4]
push de ;; [4]
push de ;; [4]
push de ;; [4] Push 8-bytes
push de ;; [4]
push de ;; [4]
push de ;; [4]
push de ;; [4] Push 8-bytes
push de ;; [4]
push de ;; [4]
push de ;; [4]
djnz fillLoop_character
ld b, c ;; [1] B' = C' Character Lines to fill (20)
exx ;; [1] Switch to Default Registers
add hl, de ;; [3] HL += DE (Next PixelLine End)
exx ;; [1] Switch to Alternate Registers
fv_restore_sp:
ld sp, #0000 ;; [3] Placeholder for restoring SP value before returning
ei ;; [1] Reenable interrupts
dec a ;; [1] A-- Number of Character per line
jr nz, fillLoop_raster ;; [2/3]
exx
ret ;; [3] Return
__endasm;
}