Check for repeated zx/zy values
These will never escape, so saves some time in the lake trick is taken from fractint
This commit is contained in:
parent
839330edb3
commit
0501a364c7
1 changed files with 106 additions and 10 deletions
116
mandel.s
116
mandel.s
|
@ -21,12 +21,16 @@ count_pixels = $a3 ; u8
|
|||
total_ms = $a4 ; float48
|
||||
total_pixels = $aa ; float48
|
||||
|
||||
temp = $b0 ; u16
|
||||
pixel_ptr = $b2 ; u16
|
||||
pixel_color = $b4 ; u8
|
||||
pixel_mask = $b5 ; u8
|
||||
pixel_shift = $b6 ; u8
|
||||
pixel_offset = $b7 ; u8
|
||||
z_buffer_active = $b0 ; boolean: 1 if we triggered the lake, 0 if not
|
||||
z_buffer_start = $b1 ; u8: index into z_buffer
|
||||
z_buffer_end = $b2 ; u8: index into z_buffer
|
||||
temp = $b4 ; u16
|
||||
|
||||
pixel_ptr = $b6 ; u16
|
||||
pixel_color = $b8 ; u8
|
||||
pixel_mask = $b9 ; u8
|
||||
pixel_shift = $ba ; u8
|
||||
pixel_offset = $bb ; u8
|
||||
|
||||
|
||||
; FP registers in zero page
|
||||
|
@ -186,6 +190,15 @@ color_map:
|
|||
|
||||
.code
|
||||
|
||||
z_buffer_len = 16
|
||||
z_buffer_mask = z_buffer_len - 1
|
||||
z_buffer:
|
||||
; the last N zx/zy values
|
||||
.repeat z_buffer_len
|
||||
.word 0
|
||||
.word 0
|
||||
.endrepeat
|
||||
|
||||
.export start
|
||||
|
||||
; 2 + 9 * byte cycles
|
||||
|
@ -462,12 +475,14 @@ initloop:
|
|||
sta zx - 1,x
|
||||
dex
|
||||
bne initloop
|
||||
sta z_buffer_start
|
||||
sta z_buffer_len
|
||||
|
||||
loop:
|
||||
; iter++ & max-iters break
|
||||
inc iter
|
||||
bne keep_going
|
||||
rts
|
||||
jmp exit_path
|
||||
keep_going:
|
||||
|
||||
.macro quick_exit arg, max
|
||||
|
@ -484,7 +499,7 @@ keep_going:
|
|||
positive:
|
||||
cmp #((max) << 4)
|
||||
bmi all_done ; 'less than'
|
||||
rts
|
||||
jmp exit_path
|
||||
|
||||
negative:
|
||||
cmp #(256 - ((max) << 4))
|
||||
|
@ -492,7 +507,7 @@ keep_going:
|
|||
bpl all_done ; 'greater than'
|
||||
|
||||
nope_out:
|
||||
rts
|
||||
jmp exit_path
|
||||
|
||||
first_equal:
|
||||
lda arg
|
||||
|
@ -527,9 +542,90 @@ keep_going:
|
|||
|
||||
; if may be in the lake, look for looping output with a small buffer
|
||||
; as an optimization vs running to max iters
|
||||
lda z_buffer_active
|
||||
beq skip_z_buffer
|
||||
|
||||
ldx z_buffer_start
|
||||
cpx z_buffer_end
|
||||
beq z_nothing_to_read
|
||||
|
||||
z_buffer_loop:
|
||||
.macro z_compare arg
|
||||
.local compare_no_match
|
||||
lda z_buffer,x
|
||||
inx
|
||||
cmp arg
|
||||
bne compare_no_match
|
||||
iny
|
||||
compare_no_match:
|
||||
.endmacro
|
||||
.macro z_advance
|
||||
.local skip_reset_x
|
||||
cpx #(z_buffer_len * 4)
|
||||
bmi skip_reset_x
|
||||
ldx #0
|
||||
skip_reset_x:
|
||||
.endmacro
|
||||
.macro z_store arg
|
||||
lda arg
|
||||
sta z_buffer,x
|
||||
inx
|
||||
.endmacro
|
||||
|
||||
; Compare the previously stored z values
|
||||
ldy #0
|
||||
z_compare zx
|
||||
z_compare zx + 1
|
||||
z_compare zy
|
||||
z_compare zy + 1
|
||||
|
||||
cpy #4
|
||||
bne z_no_matches
|
||||
jmp z_exit
|
||||
|
||||
z_no_matches:
|
||||
z_advance
|
||||
|
||||
cpx z_buffer_end
|
||||
bne z_buffer_loop
|
||||
|
||||
z_nothing_to_read:
|
||||
|
||||
; Store and expand
|
||||
z_store zx
|
||||
z_store zx + 1
|
||||
z_store zy
|
||||
z_store zy + 1
|
||||
z_advance
|
||||
stx z_buffer_end
|
||||
|
||||
; Increment the start roller if necessary (limit size)
|
||||
lda iter
|
||||
cmp #(z_buffer_len * 4)
|
||||
bmi skip_inc_start
|
||||
lda z_buffer_start
|
||||
clc
|
||||
adc #4
|
||||
tax
|
||||
z_advance
|
||||
stx z_buffer_start
|
||||
skip_inc_start:
|
||||
|
||||
skip_z_buffer:
|
||||
|
||||
jmp loop
|
||||
|
||||
peace_out:
|
||||
z_exit:
|
||||
lda #0
|
||||
sta iter
|
||||
|
||||
exit_path:
|
||||
ldx #0
|
||||
lda iter
|
||||
bne next
|
||||
inx
|
||||
next:
|
||||
stx z_buffer_active
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
|
Loading…
Reference in a new issue