diff --git a/mandel.s b/mandel.s index 097b700..467245d 100644 --- a/mandel.s +++ b/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