diff --git a/mandel.s b/mandel.s index 06d59e7..1a153de 100644 --- a/mandel.s +++ b/mandel.s @@ -13,26 +13,45 @@ zy_2 = $92 ; fixed4.12: z_y^2 zx_zy = $94 ; fixed4.12: z_x * z_y dist = $96 ; fixed4.12: z_x^2 + z_y^2 -frames = $a0 ; u16 -frames_total = $a2 ; float48; total frames -pixels = $a8 ; u16 -pixels_total = $aa ; float48; total pixels +iter = $a0 ; u8: iteration count -iter = $b0 ; u8: iteration count -zoom = $b1 ; u8: zoom shift level -temp = $b2 ; u16 -pixel_ptr = $b4 ; u16 -pixel_color = $b6 ; u8 -pixel_mask = $b7 ; u8 -pixel_shift = $b8 ; u8 -pixel_offset = $b9 ; u8 +zoom = $a1 ; u8: zoom shift level +count_frames = $a2 ; u8 +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 ; FP registers in zero page -FR0 = $d4 -FRE = $da -FR1 = $e0 -FR2 = $e6 +FR0 = $d4 ; float48 +FRE = $da +FR1 = $e0 ; float48 +FR2 = $e6 ; float48 +CIX = $f2 ; u8 - index into INBUFF +INBUFF = $f3 ; u16 - pointer to ascii +FLPTR = $fc ; u16 - pointer to user buffer float48 + +LBUFF = $0580 ; result buffer for FASC routine + +; FP ROM routine vectors +FASC = $D8E6 ; FLOATING POINT TO ASCII (output in INBUFF, last char has high bit set) +IFP = $D9AA ; INTEGER TO FLOATING POINT CONVERSION (FR0:u16 -> FR0:float48) +FADD = $DA66 ; ADDITION (FR0 += FR1) +FSUB = $DA60 ; SUBTRACTION (FR0 -= FR1) +FMUL = $DADB ; MULTIPLICATION (FR0 *= FR1) +FDIV = $DB28 ; DIVISION (FR0 /= FR1) +ZF1 = $DA46 ; CLEAR ZERO PAGE FLOATING POINT NUMBER (XX) +FLD0R = $DD89 ; LOAD FR0 WITH FLOATING POINT NUMBER (YYXX) +FLD1R = $DD98 ; LOAD FR1 WITH FLOATING POINT NUMBER (YYXX) +FST0R = $DDA7 ; STORE FR0 IN USER BUFFER (YYXX) +FMOVE = $DDB6 ; MOVE FR0 TO FR1 ; High data framebuffer_top = $8000 @@ -59,6 +78,11 @@ SDLSTH = $231 XITVBV = $E462 SETVBV = $E45C +.struct float48 + exponent .byte + mantissa .byte 6 +.endstruct + .data strings: @@ -80,6 +104,10 @@ str_speed_len = str_speed_end - str_speed str_run_len = str_run_end - str_run str_done_len = str_done_end - str_done +speed_start = str_self_len + 2 +speed_len = 14 + str_speed_len + + char_map: ; Map ATASCII string values to framebuffer font entries ; Sighhhhh @@ -106,12 +134,19 @@ aspect: ; ; 184h is the equiv of 220.8h at square pixels ; 320 / 220.8 = 1.45 display aspect ratio -aspect_x: +aspect_x: ; fixed4.16 5/4 .word 5 << (12 - 2) -aspect_y: +aspect_y: ; fixed4.16 3/4 .word 3 << (12 - 2) +ms_per_frame: ; float48 16.66666667 + .byte 64 ; exponent/sign + .byte $16 ; BCD digits + .byte $66 + .byte $66 + .byte $66 + .byte $67 display_list_start: ; 24 lines overscan @@ -625,11 +660,8 @@ loop: done: .endmacro -.proc vsync_handler - inc frames - bne no_carry - inc frames + 1 -no_carry: +.proc vblank_handler + inc count_frames jmp XITVBV .endproc @@ -646,11 +678,20 @@ no_carry: .proc start ; ox = 0; oy = 0; zoom = 0 + ; count_frames = 0; count_pixels = 0 lda #0 sta ox sta ox + 1 sta oy sta oy + 1 + sta count_frames + sta count_pixels + + ; total_ms = 0.0; total_pixels = 0.0 + ldx #total_ms + jsr ZF1 + ldx #total_pixels + jsr ZF1 ; zoom = 2x lda #1 @@ -731,6 +772,110 @@ loop_sx: jsr mandelbrot jsr pset + ; check if we should update the counters + ; + ; count_pixels >= width? update! + inc count_pixels + lda count_pixels + cmp #width + bpl update_status + + ; count_frames >= 120? update! + lda count_frames + cmp #120 ; >= 2 seconds + bmi skip_status + +update_status: + ; FR0 = (float)count_pixels & clear count_pixels + lda count_pixels + sta FR0 + lda #0 + sta FR0 + 1 + sta count_pixels + jsr IFP + + ; FR1 = total_pixels + ldx #.lobyte(total_pixels) + ldy #.hibyte(total_pixels) + jsr FLD1R + + ; FR0 += FR1 + jsr FADD + + ; total_pixels = FR0 + ldx #.lobyte(total_pixels) + ldy #.hibyte(total_pixels) + jsr FST0R + + + ; FR0 = (float)count_frames & clear count_frames + ; warning: this should really disable interrupts @TODO + lda count_frames + sta FR0 + lda #0 + sta FR0 + 1 + sta count_frames + jsr IFP + + ; FR0 *= ms_per_frame + ldx #.lobyte(ms_per_frame) + ldy #.hibyte(ms_per_frame) + jsr FMUL + + ; FR1 = total_ms + ldx #total_ms + ldy #0 + jsr FLD1R + + ; FR0 += FR1 + jsr FADD + + ; total_ms = FR0 + ldx #total_ms + ldy #0 + jsr FST0R + + ; FR1 = total_pixels + ldx #total_pixels + ldy #0 + jsr FLD1R + + ; FR0 /= FR1 + jsr FDIV + + ; convert to ASCII in INBUFF + jsr FASC + + ; find the last byte + ldy #0 +number_loop: + lda (INBUFF),y + bmi lastchar + + tax + lda char_map,x + sta textbuffer + speed_start,y + + iny + bpl number_loop +lastchar: + ; Y is last char + ; trim that high bit + and #$7f + tax + lda char_map,x + sta textbuffer + speed_start,y + + ; Fill out any remaining spaces + lda #0 +space_loop: + iny + sta textbuffer + speed_start,y + cpy #(20) + bmi space_loop + +skip_status: + clc lda sx adc #1