
The other day i wrote a small filled rectangle routine, perhaps it's not super fast but it gets the job done (it's currently at 70 bytes).
This is the first version after implementing some optimizations from Xeda. It fills the rectangle vertically:
This is a modified version of the other which i believe is a bit faster (i'd say around 5-15% depending on the dimensions of the rectangle). This one fills vertically:
Note that for the first routine, b = the number of columns in the rectangle and c = the number of rows. In the second, they're switched: b = # rows and c = # columns. de is the same for both, though. Source is in the PD, do (or don't) whatever you want with it!
EDIT: The syntax highlighting is so pretty!
EDIT2: Found a small optimization.
This is the first version after implementing some optimizations from Xeda. It fills the rectangle vertically:
- Code: Select all
#ifdef TI83P
GBUF_LSB = $40
GBUF_MSB = $93
#else
GBUF_LSB = $29
GBUF_MSB = $8E
#endif
;b = # columns
;c = # rows
;d = starting x
;e = starting y
rectangle_filled_xor:
ld a,$AE ;xor (hl)
jr rectangle_filled2
rectangle_filled_solid:
ld a,$B6 ;or (hl)
rectangle_filled2:
push de
push bc
ld (or_xor),a ;use smc for xor/solid fill
ld a,d ;starting x
and $7 ;what bit do we start on?
ex af,af'
ld a,d ;starting x
ld l,e ;ld hl,e
ld h,0 ; ..
ld d,h ;set d = 0
add hl,de ;starting y * 12
add hl,de ;x3
add hl,hl ;x6
add hl,hl ;x12
rra ;a = x coord / 8
rra ;
rra ;
and %00011111 ;starting x/8 (starting byte in gbuf)
add a,GBUF_LSB
ld e,a ;
ld d,GBUF_MSB ;
add hl,de ;hl = offset in gbuf
ex af,af' ;carry should be reset and z affected from and $7
ld e,a
ld a,%10000000
jr z,$+6
rra
dec e
jr nz,$-2
ld d,a ;starting bit to draw
rectangle_loop_y:
push bc
push hl
rectangle_loop_x:
ld e,a ;save a (overwritten with or (hl))
or_xor = $
or (hl) ;smc will modify this to or/xor
ld (hl),a
ld a,e ;recall a
rrca ;rotate a to draw the next bit
jr nc,$+3
inc hl
djnz rectangle_loop_x
pop hl ;hl = first column in gbuf row
ld c,12 ;b = 0, bc = 12
add hl,bc ;move down to next row
pop bc ;restore b (# columns)
ld a,d ;restore a (starting bit to draw)
dec c
jr nz,rectangle_loop_y
rectangle_end:
pop bc
pop de
ret
This is a modified version of the other which i believe is a bit faster (i'd say around 5-15% depending on the dimensions of the rectangle). This one fills vertically:
- Code: Select all
#ifdef TI83P
GBUF_LSB = $40
GBUF_MSB = $93
#else
GBUF_LSB = $29
GBUF_MSB = $8E
#endif
;b = # rows
;c = # columns
;d = starting x
;e = starting y
rectangle_filled_xor:
ld a,$AE ;xor (hl)
jr rectangle_filled2
rectangle_filled_solid:
ld a,$B6 ;or (hl)
rectangle_filled2:
push de
push bc
ld (or_xor),a ;use smc for xor/solid fill
ld a,d ;starting x
and $7 ;what bit do we start on?
ex af,af'
ld a,d ;starting x
ld l,e ;ld hl,e
ld h,0 ; ..
ld d,h ;set d = 0
add hl,de ;starting y * 12
add hl,de ;x3
add hl,hl ;x6
add hl,hl ;x12
rra ;a = x coord / 8
rra ;
rra ;
and %00011111 ;starting x/8 (starting byte in gbuf)
add a,GBUF_LSB
ld e,a ;
ld d,GBUF_MSB ;
add hl,de ;hl = offset in gbuf
ex af,af' ;carry should be reset and z affected from and $7
ld d,a
ld a,%10000000
jr z,$+6
rra
dec d
jr nz,$-2
ld e,12
rectangle_loop_x:
push af
push bc
push hl
ld c,a
rectangle_loop_y:
or_xor = $
or (hl) ;smc will modify this to or/xor
ld (hl),a
ld a,c
add hl,de
djnz rectangle_loop_y
pop hl
pop bc
pop af
rrca
jr nc,$+3
inc hl
dec c
jr nz,rectangle_loop_x
rectangle_end:
pop bc
pop de
ret
Note that for the first routine, b = the number of columns in the rectangle and c = the number of rows. In the second, they're switched: b = # rows and c = # columns. de is the same for both, though. Source is in the PD, do (or don't) whatever you want with it!
EDIT: The syntax highlighting is so pretty!
EDIT2: Found a small optimization.