Skip to content

Commit 46eefd5

Browse files
adriwebruner112
authored andcommitted
(grosged) slight optimisations (#116)
* slight optimisations * Revert a bad optimization _PixelPtr checks the full 24-bit y value in DE, but the y value is only passed as an 8-bit value to gfx_SetPixel. The upper 16 bits of DE will be undefined and possibly nonzero here, in which case I believe _PixelPtr would erroneously reject it as offscreen even if the 8-bit value is actually on screen. * Optimize gfx_SetPixel -8 cycles, -2 bytes * Make gfx_GetPixel safer +4 cycles, +2 bytes I had these changes sitting around locally for a while. Since this routine was already getting optimized in a very similar fashion, I figured I should just slip my little extra safety changes (and better comments) on top.
1 parent 3b9fc3e commit 46eefd5

File tree

1 file changed

+34
-21
lines changed

1 file changed

+34
-21
lines changed

src/graphx/graphx.asm

Lines changed: 34 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -202,14 +202,16 @@ gfx_AllocSprite:
202202
; arg2 : pointer to malloc routine
203203
; Returns:
204204
; Pointer to allocated sprite, first byte width, second height
205-
ld bc,3
206-
push bc
207-
pop hl
205+
ld hl,3
208206
add hl,sp
209207
ld e,(hl) ; e = width
210-
add hl,bc
208+
inc hl
209+
inc hl
210+
inc hl
211211
ld d,(hl) ; d = height
212-
add hl,bc
212+
inc hl
213+
inc hl
214+
inc hl
213215
ld hl,(hl) ; hl = malloc
214216
push de
215217
mlt de ; de = width * height
@@ -518,18 +520,31 @@ gfx_GetPixel:
518520
; Returns:
519521
; Color index of X,Y coordinate
520522
ld hl,3
521-
add hl,sp
522-
ld bc,(hl) ; bc = x coordinate
523+
add hl,sp ; hl = &x
524+
inc.s bc
525+
ld c,(hl)
523526
inc hl
527+
ld b,(hl) ; bc = (uint16_t)x
524528
inc hl
525-
inc hl ; move to next argument
526-
ld de,0
527-
ld e,(hl) ; e = y coordinate
528-
call _PixelPtr
529-
ret c ; return if out of bounds
530-
ld a,(hl) ; get the actual pixel
529+
inc hl ; hl = &y
530+
ld e,(hl) ; e = y
531+
ld d,LcdWidth/2
532+
mlt de ; de = y * (lcdWidth / 2)
533+
ld hl,(CurrentBuffer) ; hl = buffer
534+
add hl,bc
535+
add hl,de
536+
add hl,de ; hl = buffer + y * (lcdWidth / 2)*2 + (uint16_t)x
537+
; = buffer + y * lcdWidth + (uint16_t)x
538+
; = &buffer[y][x]
539+
; No clipping is necessary, because if the pixel is offscreen, the result is
540+
; undefined. All that is necessary is to ensure that there are no side effects
541+
; of reading outside of the buffer. In this case, the largest possible offset
542+
; into the buffer is 255 * lcdWidth + 65535 = 147135 bytes. Even in the case
543+
; that the current buffer is the second half of VRAM, the largest that this
544+
; pointer can be is $D52C00 + 147135 = $D76ABF. This goes beyond the end of
545+
; mapped RAM, but only into unmapped memory with no read side effects.
546+
ld a,(hl) ; a = buffer[y][x]
531547
ret
532-
533548
;-------------------------------------------------------------------------------
534549
gfx_SetPixel:
535550
; Sets the color pixel to the global color index
@@ -541,10 +556,8 @@ gfx_SetPixel:
541556
ld hl,3
542557
add hl,sp
543558
ld bc,(hl) ; bc = x coordinate
544-
inc hl
545-
inc hl
546-
inc hl ; move to next argument
547-
ld de,0
559+
ld de,3
560+
add hl,de ; move to next argument
548561
ld e,(hl) ; e = y coordinate
549562
_SetPixel:
550563
call _PixelPtr
@@ -803,11 +816,11 @@ _HorizLine_NoClip:
803816
Color_2 := $-1
804817
_MemorySet:
805818
ld (hl),a
806-
push hl
807819
cpi
808-
ex de,hl
809-
pop hl
810820
ret po
821+
ex de,hl
822+
ld hl,-1
823+
add hl,de
811824
ldir
812825
ret
813826

0 commit comments

Comments
 (0)