Compare commits
No commits in common. "main" and "main" have entirely different histories.
3 changed files with 182 additions and 448 deletions
612
mandel.s
612
mandel.s
|
@ -1,16 +1,16 @@
|
|||
; Our zero-page vars
|
||||
ox = $80 ; fixed6.26: center point x
|
||||
oy = $84 ; fixed6.26: center point y
|
||||
cx = $88 ; fixed6.26: c_x
|
||||
cy = $8c ; fixed6.26: c_y
|
||||
ox = $80 ; fixed8.24: center point x
|
||||
oy = $84 ; fixed8.24: center point y
|
||||
cx = $88 ; fixed8.24: c_x
|
||||
cy = $8c ; fixed8.24: c_y
|
||||
|
||||
zx = $90 ; fixed6.26: z_x
|
||||
zy = $94 ; fixed6.26: z_y
|
||||
zx_2 = $98 ; fixed6.26: z_x^2
|
||||
zy_2 = $9c ; fixed6.26: z_y^2
|
||||
zx = $90 ; fixed8.24: z_x
|
||||
zy = $94 ; fixed8.24: z_y
|
||||
zx_2 = $98 ; fixed8.24: z_x^2
|
||||
zy_2 = $9c ; fixed8.24: z_y^2
|
||||
|
||||
zx_zy = $a0 ; fixed6.26: z_x * z_y
|
||||
dist = $a4 ; fixed6.26: z_x^2 + z_y^2
|
||||
zx_zy = $a0 ; fixed8.24: z_x * z_y
|
||||
dist = $a4 ; fixed8.24: z_x^2 + z_y^2
|
||||
sx = $a8 ; i16: screen pixel x
|
||||
sy = $aa ; i16: screen pixel y
|
||||
z_buffer_active = $ac ; boolean: 1 if we triggered the lake, 0 if not
|
||||
|
@ -31,12 +31,10 @@ chroma_offset = $bb ; u8
|
|||
palette_ticks = $bc ; u8
|
||||
chroma_ticks = $bd ; u8
|
||||
count_frames = $be ; u8
|
||||
; free space $bf
|
||||
count_pixels = $bf ; u8
|
||||
|
||||
count_iters = $c0 ; u16
|
||||
text_col = $c2 ; u8
|
||||
text_row = $c3 ; u8
|
||||
; free space c4-cb
|
||||
total_pixels = $c0 ; float48
|
||||
total_ms = $c6 ; float48
|
||||
temp = $cc ; u16
|
||||
temp2 = $ce ; u16
|
||||
|
||||
|
@ -61,12 +59,10 @@ 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)
|
||||
FPI = $D9D2 ; floating point to integer
|
||||
FADD = $DA66 ; ADDITION (FR0 += FR1)
|
||||
FSUB = $DA60 ; SUBTRACTION (FR0 -= FR1)
|
||||
FMUL = $DADB ; MULTIPLICATION (FR0 *= FR1)
|
||||
FDIV = $DB28 ; DIVISION (FR0 /= FR1)
|
||||
ZFR0 = $DA44 ; clear FR0
|
||||
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)
|
||||
|
@ -80,7 +76,7 @@ framebuffer_bottom = $b000
|
|||
display_list = $bf00
|
||||
framebuffer_end = $c000
|
||||
|
||||
height = 176
|
||||
height = 184
|
||||
half_height = height >> 1
|
||||
width = 160
|
||||
half_width = width >> 1
|
||||
|
@ -144,52 +140,25 @@ strings:
|
|||
str_self:
|
||||
.byte "MANDEL-6502"
|
||||
str_self_end:
|
||||
.byte 0
|
||||
str_speed:
|
||||
.byte "us/iter: "
|
||||
.byte " ms/px"
|
||||
str_speed_end:
|
||||
.byte 0
|
||||
str_run:
|
||||
.byte " RUN"
|
||||
str_run_end:
|
||||
.byte 0
|
||||
str_done:
|
||||
.byte "DONE"
|
||||
str_done_end:
|
||||
.byte 0
|
||||
str_padding:
|
||||
.byte " "
|
||||
str_padding_end:
|
||||
.byte 0
|
||||
|
||||
str_self_len = str_self_end - str_self
|
||||
str_speed_len = str_speed_end - str_speed
|
||||
str_run_len = str_run_end - str_run
|
||||
str_done_len = str_done_end - str_done
|
||||
str_padding_len = str_padding_end - str_padding
|
||||
speed_precision = 6
|
||||
|
||||
speed_start = 40 - str_done_len - str_speed_len - str_padding_len - 1
|
||||
speed_start = 40 - str_done_len - str_speed_len - speed_precision - 1
|
||||
speed_len = 14 + str_speed_len
|
||||
|
||||
col_x = 1
|
||||
str_x:
|
||||
.byte "X:"
|
||||
.byte 0
|
||||
str_x_len = 2
|
||||
str_x_space = 12
|
||||
str_x_padding = 2
|
||||
|
||||
col_y = col_x + str_x_len + str_x_space + str_x_padding
|
||||
str_y:
|
||||
.byte "Y:"
|
||||
.byte 0
|
||||
str_y_len = 2
|
||||
str_y_space = 12
|
||||
str_y_padding = 2
|
||||
|
||||
col_zoom = col_y + str_y_len + str_y_space + str_y_padding
|
||||
str_zoom:
|
||||
.byte "ZOOM:"
|
||||
.byte 0
|
||||
str_zoom_len = 5
|
||||
|
||||
char_map:
|
||||
; Map ATASCII string values to framebuffer font entries
|
||||
|
@ -220,49 +189,20 @@ aspect:
|
|||
;
|
||||
; 184h is the equiv of 220.8h at square pixels
|
||||
; 320 / 220.8 = 1.45 display aspect ratio
|
||||
aspect_x: ; fixed3.13 5/4
|
||||
.word 5 << (13 - 2)
|
||||
aspect_x: ; fixed4.16 5/4
|
||||
.word 5 << (12 - 2)
|
||||
|
||||
aspect_y: ; fixed3.13 3/4
|
||||
.word 3 << (13 - 2)
|
||||
aspect_y: ; fixed4.16 3/4
|
||||
.word 3 << (12 - 2)
|
||||
|
||||
fixed3_13_as_float: ; float48
|
||||
; 1 << 13
|
||||
; 8192
|
||||
; 81 92 . 00 00 00
|
||||
.byte 65 ; exponent/sign - +1 byte
|
||||
.byte $81
|
||||
.byte $92
|
||||
.byte $00
|
||||
.byte $00
|
||||
.byte $00
|
||||
|
||||
sec_per_frame: ; float48 00 . 01 66 66 66 67
|
||||
.byte 63 ; exponent/sign - -1 bytes
|
||||
.byte $01 ; BCD digits
|
||||
ms_per_frame: ; float48 16.66666667
|
||||
.byte 64 ; exponent/sign
|
||||
.byte $16 ; BCD digits
|
||||
.byte $66
|
||||
.byte $66
|
||||
.byte $66
|
||||
.byte $67
|
||||
|
||||
us_per_sec: ; float48 1e9 01 00 0,0 00 . 00
|
||||
.byte 67 ; exponent/sign +3 bytes
|
||||
.byte $01 ; BCD digits
|
||||
.byte $00
|
||||
.byte $00
|
||||
.byte $00
|
||||
.byte $00
|
||||
|
||||
total_iters: ; float48
|
||||
.repeat 6
|
||||
.byte 0
|
||||
.endrepeat
|
||||
|
||||
total_sec: ; float48
|
||||
.repeat 6
|
||||
.byte 0
|
||||
.endrepeat
|
||||
|
||||
display_list_start:
|
||||
; 24 lines overscan
|
||||
.repeat 3
|
||||
|
@ -286,10 +226,6 @@ display_list_start:
|
|||
.byte $0e
|
||||
.endrep
|
||||
|
||||
; 8 scan lines, 1 row of 40-column text
|
||||
.byte $42
|
||||
.addr textbuffer + 40
|
||||
|
||||
.byte $41 ; jump and blank
|
||||
.addr display_list
|
||||
display_list_end:
|
||||
|
@ -298,9 +234,9 @@ display_list_len = display_list_end - display_list_start
|
|||
color_map:
|
||||
.byte 0
|
||||
.repeat 85
|
||||
.byte %01010101
|
||||
.byte %10101010
|
||||
.byte %11111111
|
||||
.byte 1
|
||||
.byte 2
|
||||
.byte 3
|
||||
.endrepeat
|
||||
|
||||
|
||||
|
@ -349,34 +285,23 @@ fill_masks:
|
|||
.byte %00000001
|
||||
.byte %00000000
|
||||
|
||||
pixel_masks:
|
||||
.byte %11111111
|
||||
.byte %11110000
|
||||
.byte %11000000
|
||||
|
||||
viewport_zoom:
|
||||
.byte 0
|
||||
.byte 5
|
||||
.byte 7
|
||||
.byte 5
|
||||
.byte 7
|
||||
.byte 7
|
||||
.byte 1
|
||||
.byte 6
|
||||
.byte 8
|
||||
.byte 6
|
||||
|
||||
viewport_ox:
|
||||
.dword ($00000000 & $3fffffff) << 2
|
||||
.dword ($ff110000 & $3fffffff) << 2
|
||||
.dword ($ff110000 & $3fffffff) << 2
|
||||
.dword ($fe400000 & $3fffffff) << 2
|
||||
.dword ($fe3b0000 & $3fffffff) << 2
|
||||
.dword $fd220000
|
||||
.dword $00000000
|
||||
.dword $ff110000
|
||||
.dword $ff110000
|
||||
.dword $fe400000
|
||||
|
||||
viewport_oy:
|
||||
.dword ($00000000 & $3fffffff) << 2
|
||||
.dword ($ffb60000 & $3fffffff) << 2
|
||||
.dword ($ffbe0000 & $3fffffff) << 2
|
||||
.dword ($00000000 & $3fffffff) << 2
|
||||
.dword ($fffe0000 & $3fffffff) << 2
|
||||
.dword $ff000000
|
||||
.dword $00000000
|
||||
.dword $ffb60000
|
||||
.dword $ffbe0000
|
||||
.dword $00000000
|
||||
|
||||
; 2 + 9 * byte cycles
|
||||
.macro add bytes, dest, arg1, arg2
|
||||
|
@ -528,6 +453,20 @@ viewport_oy:
|
|||
sta dest + 1
|
||||
.endmacro
|
||||
|
||||
; input: arg as u8
|
||||
; input/output: dest as u16
|
||||
; clobbers a, x
|
||||
.macro sqr8_add16 dest, arg
|
||||
ldx arg
|
||||
clc
|
||||
lda sqr_lobyte,x
|
||||
adc dest
|
||||
sta dest
|
||||
lda sqr_hibyte,x
|
||||
adc dest + 1
|
||||
sta dest + 1
|
||||
.endmacro
|
||||
|
||||
.segment "TABLES"
|
||||
; lookup table for top byte -> PORTB value for bank-switch
|
||||
.align 256
|
||||
|
@ -810,8 +749,9 @@ inner_loop:
|
|||
; h1*h2*256*256 + h1*l2*256 + h2*l1*256 + l1*l2
|
||||
|
||||
imul8 result, arg1, arg2, xe
|
||||
|
||||
imul8 result + 2, arg1 + 1, arg2 + 1, xe
|
||||
lda #0
|
||||
sta result + 2
|
||||
sta result + 3
|
||||
|
||||
imul8 inter, arg1 + 1, arg2, xe
|
||||
add16 result + 1, result + 1, inter
|
||||
|
@ -821,6 +761,9 @@ inner_loop:
|
|||
add16 result + 1, result + 1, inter
|
||||
add_carry result + 3
|
||||
|
||||
imul8 inter, arg1 + 1, arg2 + 1, xe
|
||||
add16 result + 2, result + 2, inter
|
||||
|
||||
; In case of negative inputs, adjust high word
|
||||
; https://stackoverflow.com/a/28827013
|
||||
lda arg1 + 1
|
||||
|
@ -853,8 +796,9 @@ arg2_pos:
|
|||
; h*h*256*256 + h*l*256 + h*l*256 + l*l
|
||||
|
||||
sqr8 result, arg
|
||||
|
||||
sqr8 result + 2, arg + 1
|
||||
lda #0
|
||||
sta result + 2
|
||||
sta result + 3
|
||||
|
||||
imul8 inter, arg + 1, arg, xe
|
||||
add16 result + 1, result + 1, inter
|
||||
|
@ -862,6 +806,8 @@ arg2_pos:
|
|||
add16 result + 1, result + 1, inter
|
||||
add_carry result + 3
|
||||
|
||||
sqr8_add16 result + 2, arg + 1
|
||||
|
||||
rts ; 6 cyc
|
||||
.endscope
|
||||
.endmacro
|
||||
|
@ -927,72 +873,10 @@ next:
|
|||
|
||||
.endmacro
|
||||
|
||||
; input in FR0, 16 bits signed 3.13 fixed
|
||||
; output in FR0, Atari float
|
||||
; clobbers a, x, y, FR0, FR1
|
||||
.proc fixed3_13_to_float
|
||||
ldx #.lobyte(fixed3_13_as_float)
|
||||
ldy #.hibyte(fixed3_13_as_float)
|
||||
jsr FLD1R
|
||||
|
||||
; check sign bit! conversion routine is for unsigned
|
||||
lda FR0 + 1
|
||||
bpl positive
|
||||
|
||||
negative:
|
||||
neg16 FR0
|
||||
jsr IFP
|
||||
|
||||
; set float sign bit
|
||||
lda FR0
|
||||
ora #$80
|
||||
sta FR0
|
||||
jmp common
|
||||
|
||||
positive:
|
||||
jsr IFP
|
||||
|
||||
common:
|
||||
jsr FDIV
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
; input in FR0, Atari float
|
||||
; output in FR0, 16 bits signed 3.13 fixed
|
||||
; clobbers a, x, y, FR0, FR1
|
||||
.proc float_to_fixed3_13
|
||||
ldx #.lobyte(fixed3_13_as_float)
|
||||
ldy #.hibyte(fixed3_13_as_float)
|
||||
jsr FLD1R
|
||||
jsr FMUL
|
||||
|
||||
; check sign bit! conversion routine is for unsigned
|
||||
lda FR0
|
||||
bcc positive
|
||||
|
||||
negative:
|
||||
; clearfloat sign bit
|
||||
lda FR0
|
||||
eor #$80
|
||||
sta FR0
|
||||
|
||||
jsr FPI
|
||||
neg16 FR0
|
||||
jmp common
|
||||
|
||||
positive:
|
||||
jsr FPI
|
||||
|
||||
common:
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
.proc mandelbrot
|
||||
; input:
|
||||
; cx: position scaled to 6.26 fixed point - -32..+31.9
|
||||
; cy: position scaled to 6.26
|
||||
; cx: position scaled to 8.24 fixed point - -128..+127.9
|
||||
; cy: position scaled to 8.24
|
||||
;
|
||||
; output:
|
||||
; iter: iteration count at escape or 0
|
||||
|
@ -1043,11 +927,6 @@ common:
|
|||
sta z_buffer_end
|
||||
|
||||
loop:
|
||||
inc count_iters
|
||||
bne low_iters
|
||||
inc count_iters + 1
|
||||
low_iters:
|
||||
|
||||
; iter++ & max-iters break
|
||||
inc iter
|
||||
bne keep_going
|
||||
|
@ -1055,7 +934,7 @@ low_iters:
|
|||
keep_going:
|
||||
|
||||
.macro quick_exit arg, max
|
||||
; arg: fixed6.26
|
||||
; arg: fixed8.24
|
||||
; max: integer
|
||||
.local positive
|
||||
.local negative
|
||||
|
@ -1068,12 +947,12 @@ keep_going:
|
|||
bmi negative
|
||||
|
||||
positive:
|
||||
cmp #(max << 2)
|
||||
cmp #max
|
||||
bmi all_done ; 'less than'
|
||||
jmp exit_path
|
||||
|
||||
negative:
|
||||
cmp #(256 - (max << 2))
|
||||
cmp #(256 - max)
|
||||
beq first_equal ; 'equal' on first byte
|
||||
bpl all_done ; 'greater than'
|
||||
|
||||
|
@ -1093,7 +972,7 @@ keep_going:
|
|||
all_done:
|
||||
.endmacro
|
||||
|
||||
; 6.26: (-32 .. 31.9)
|
||||
; 8.24: (-128 .. 127.9)
|
||||
; zx = zx_2 - zy_2 + cx
|
||||
sub32 zx, zx_2, zy_2
|
||||
add32 zx, zx, cx
|
||||
|
@ -1104,9 +983,9 @@ keep_going:
|
|||
add32 zy, zy, cy
|
||||
quick_exit zy, 2
|
||||
|
||||
; convert 6.26 -> 3.13: (-4 .. +3.9)
|
||||
shift_round_16 zx, 3
|
||||
shift_round_16 zy, 3
|
||||
; convert 8.24 -> 4.12: (-8 .. +7.9)
|
||||
shift_round_16 zx, 4
|
||||
shift_round_16 zy, 4
|
||||
|
||||
; zx_2 = zx * zx
|
||||
sqr16 zx_2, zx + 2
|
||||
|
@ -1228,9 +1107,9 @@ enough:
|
|||
.endmacro
|
||||
|
||||
.macro zoom_factor dest, src, aspect
|
||||
; output: dest: fixed6.26
|
||||
; input: src: fixed3.13
|
||||
; aspect: fixed3.13
|
||||
; output: dest: fixed8.24
|
||||
; input: src: fixed4.12
|
||||
; aspect: fixed4.12
|
||||
; clobbers A, X, flags, etc
|
||||
copy16 dest, src
|
||||
scale_zoom dest
|
||||
|
@ -1248,11 +1127,8 @@ enough:
|
|||
; iter -> color
|
||||
ldx iter
|
||||
lda color_map,x
|
||||
ldx fill_level
|
||||
and pixel_masks,x
|
||||
sta pixel_color
|
||||
lda pixel_masks,x
|
||||
eor #$ff
|
||||
lda #(255 - 3)
|
||||
sta pixel_mask
|
||||
|
||||
; sy -> line base address in temp
|
||||
|
@ -1301,23 +1177,22 @@ point:
|
|||
; pixel_mask <<= pixel_shift (shifting in ones)
|
||||
and #3
|
||||
sta pixel_shift
|
||||
lda #3
|
||||
sec
|
||||
sbc pixel_shift
|
||||
tax
|
||||
shift_loop:
|
||||
beq shift_done
|
||||
lsr pixel_color
|
||||
lsr pixel_color
|
||||
asl pixel_color
|
||||
asl pixel_color
|
||||
sec
|
||||
ror pixel_mask
|
||||
rol pixel_mask
|
||||
sec
|
||||
ror pixel_mask
|
||||
rol pixel_mask
|
||||
dex
|
||||
jmp shift_loop
|
||||
shift_done:
|
||||
|
||||
ldy fill_level
|
||||
ldx fill_masks,y
|
||||
inx
|
||||
|
||||
; pixel_offset = temp >> 2
|
||||
lda temp
|
||||
lsr a
|
||||
|
@ -1325,94 +1200,48 @@ shift_done:
|
|||
sta pixel_offset
|
||||
tay
|
||||
|
||||
draw_pixel:
|
||||
; read, mask, or, write
|
||||
lda (pixel_ptr),y
|
||||
and pixel_mask
|
||||
ora pixel_color
|
||||
sta (pixel_ptr),y
|
||||
|
||||
dex
|
||||
beq done
|
||||
clc
|
||||
lda #40
|
||||
adc pixel_ptr
|
||||
sta pixel_ptr
|
||||
lda #0
|
||||
adc pixel_ptr + 1
|
||||
sta pixel_ptr + 1
|
||||
jmp draw_pixel
|
||||
|
||||
done:
|
||||
rts
|
||||
.endproc
|
||||
|
||||
; in/out: column in text_col
|
||||
; in: row in text_row
|
||||
; in: pointer to string in INBUFF
|
||||
; clobbers x/y/a/temp
|
||||
.proc draw_string
|
||||
drawptr = temp
|
||||
strptr = INBUFF
|
||||
|
||||
clc
|
||||
lda #.lobyte(textbuffer)
|
||||
adc text_col
|
||||
sta temp
|
||||
lda #.hibyte(textbuffer)
|
||||
adc #0
|
||||
sta temp + 1
|
||||
|
||||
ldx text_row
|
||||
beq done_rows
|
||||
continue_rows:
|
||||
clc
|
||||
lda temp
|
||||
adc #40
|
||||
sta temp
|
||||
lda temp + 1
|
||||
adc #0
|
||||
sta temp + 1
|
||||
dex
|
||||
bne continue_rows
|
||||
|
||||
done_rows:
|
||||
|
||||
ldy #0
|
||||
.macro draw_text_indirect col, len, strptr
|
||||
; clobbers A, X
|
||||
.local loop
|
||||
.local done
|
||||
ldx #0
|
||||
loop:
|
||||
lda (strptr),y
|
||||
; if char's null, terminate c-style
|
||||
cpx #len
|
||||
beq done
|
||||
; save the char for terminator check
|
||||
pha
|
||||
; strip the high bit (terminator)
|
||||
and #$7f
|
||||
tax
|
||||
lda char_map,x
|
||||
sta (drawptr),y
|
||||
iny
|
||||
|
||||
pla
|
||||
; _last_ char has high bit set in atari rom routines
|
||||
bmi done
|
||||
txa
|
||||
tay
|
||||
lda (strptr),y
|
||||
tay
|
||||
lda char_map,y
|
||||
sta textbuffer + col,x
|
||||
inx
|
||||
jmp loop
|
||||
|
||||
done:
|
||||
; move the text column pointer
|
||||
tya
|
||||
clc
|
||||
adc text_col
|
||||
sta text_col
|
||||
.endmacro
|
||||
|
||||
rts
|
||||
.endproc
|
||||
|
||||
.macro draw_string_const str
|
||||
lda #.lobyte(str)
|
||||
sta INBUFF
|
||||
lda #.hibyte(str)
|
||||
sta INBUFF + 1
|
||||
jsr draw_string
|
||||
.macro draw_text col, len, cstr
|
||||
; clobbers A, X
|
||||
.local loop
|
||||
.local done
|
||||
ldx #0
|
||||
loop:
|
||||
cpx #len
|
||||
beq done
|
||||
ldy cstr,x
|
||||
lda char_map,y
|
||||
sta textbuffer + col,x
|
||||
inx
|
||||
jmp loop
|
||||
done:
|
||||
.endmacro
|
||||
|
||||
.proc vblank_handler
|
||||
|
@ -1538,7 +1367,7 @@ skip_char:
|
|||
|
||||
plus:
|
||||
lda zoom
|
||||
cmp #7
|
||||
cmp #8
|
||||
bpl skip_char
|
||||
inc zoom
|
||||
jmp done
|
||||
|
@ -1549,20 +1378,16 @@ minus:
|
|||
dec zoom
|
||||
jmp done
|
||||
up:
|
||||
add32 oy, oy, temp
|
||||
jsr display_coords
|
||||
sub32 oy, oy, temp
|
||||
jmp done
|
||||
down:
|
||||
sub32 oy, oy, temp
|
||||
jsr display_coords
|
||||
add32 oy, oy, temp
|
||||
jmp done
|
||||
left:
|
||||
sub32 ox, ox, temp
|
||||
jsr display_coords
|
||||
jmp done
|
||||
right:
|
||||
add32 ox, ox, temp
|
||||
jsr display_coords
|
||||
jmp done
|
||||
|
||||
number_keys:
|
||||
|
@ -1574,10 +1399,6 @@ number_keys:
|
|||
beq three
|
||||
cpy #KEY_4
|
||||
beq four
|
||||
cpy #KEY_5
|
||||
beq five
|
||||
cpy #KEY_6
|
||||
beq six
|
||||
jmp skip_char
|
||||
|
||||
one:
|
||||
|
@ -1591,12 +1412,6 @@ three:
|
|||
jmp load_key_viewport
|
||||
four:
|
||||
ldx #3
|
||||
jmp load_key_viewport
|
||||
five:
|
||||
ldx #4
|
||||
jmp load_key_viewport
|
||||
six:
|
||||
ldx #5
|
||||
; fall through
|
||||
load_key_viewport:
|
||||
jsr load_viewport
|
||||
|
@ -1632,63 +1447,12 @@ zero_byte_loop:
|
|||
|
||||
.proc status_bar
|
||||
; Status bar
|
||||
|
||||
lda #0
|
||||
sta text_col
|
||||
lda #0
|
||||
sta text_row
|
||||
draw_string_const str_self
|
||||
|
||||
lda #(40 - str_run_len)
|
||||
sta text_col
|
||||
draw_string_const str_run
|
||||
draw_text 0, str_self_len, str_self
|
||||
draw_text 40 - str_run_len, str_run_len, str_run
|
||||
|
||||
rts
|
||||
.endproc
|
||||
|
||||
.proc display_coords
|
||||
lda #1
|
||||
sta text_row
|
||||
lda #col_x
|
||||
sta text_col
|
||||
draw_string_const str_x
|
||||
|
||||
copy32 FR0, ox
|
||||
shift_round_16 FR0, 3
|
||||
copy16 FR0, FR0 + 2
|
||||
jsr fixed3_13_to_float
|
||||
jsr FASC
|
||||
jsr draw_string
|
||||
|
||||
lda #col_y
|
||||
sta text_col
|
||||
draw_string_const str_y
|
||||
|
||||
copy32 FR0, oy
|
||||
shift_round_16 FR0, 3
|
||||
copy16 FR0, FR0 + 2
|
||||
jsr fixed3_13_to_float
|
||||
jsr FASC
|
||||
jsr draw_string
|
||||
|
||||
lda #col_zoom
|
||||
sta text_col
|
||||
draw_string_const str_zoom
|
||||
|
||||
lda zoom
|
||||
clc
|
||||
adc #0
|
||||
sta FR0
|
||||
lda #0
|
||||
sta FR0 + 1
|
||||
jsr IFP
|
||||
jsr FASC
|
||||
jsr draw_string
|
||||
|
||||
rts
|
||||
|
||||
.endproc
|
||||
|
||||
; input: viewport selector in x
|
||||
; clobbers: a, x
|
||||
.proc load_viewport
|
||||
|
@ -1740,7 +1504,6 @@ zero_byte_loop:
|
|||
sta DMACTL
|
||||
|
||||
jsr clear_screen
|
||||
jsr display_coords
|
||||
|
||||
; Copy the display list into properly aligned memory
|
||||
; Can't cross 1024-byte boundaries :D
|
||||
|
@ -1779,24 +1542,19 @@ copy_byte_loop:
|
|||
jsr SETVBV
|
||||
|
||||
main_loop:
|
||||
; count_frames = 0; count_iters = 0
|
||||
; count_frames = 0; count_pixels = 0
|
||||
lda #0
|
||||
sta count_frames
|
||||
sta count_iters
|
||||
sta count_iters + 1
|
||||
sta count_pixels
|
||||
|
||||
; total_sec = 0.0; total_iters = 0.0
|
||||
jsr ZFR0
|
||||
ldx #.lobyte(total_sec)
|
||||
ldy #.hibyte(total_sec)
|
||||
jsr FST0R
|
||||
ldx #.lobyte(total_iters)
|
||||
ldy #.hibyte(total_iters)
|
||||
jsr FST0R
|
||||
; total_ms = 0.0; total_pixels = 0.0
|
||||
ldx #total_ms
|
||||
jsr ZF1
|
||||
ldx #total_pixels
|
||||
jsr ZF1
|
||||
|
||||
jsr clear_screen
|
||||
jsr status_bar
|
||||
jsr display_coords
|
||||
|
||||
lda #0
|
||||
sta fill_level
|
||||
|
@ -1854,7 +1612,6 @@ not_skipped_mask:
|
|||
zoom_factor cx, sx, aspect_x
|
||||
add32 cx, cx, ox
|
||||
zoom_factor cy, sy, aspect_y
|
||||
neg32 cy
|
||||
add32 cy, cy, oy
|
||||
jsr mandelbrot
|
||||
jsr pset
|
||||
|
@ -1866,32 +1623,38 @@ not_skipped_mask:
|
|||
|
||||
no_key:
|
||||
; check if we should update the counters
|
||||
;
|
||||
; count_pixels >= width? update!
|
||||
inc count_pixels
|
||||
lda count_pixels
|
||||
cmp #width
|
||||
bmi update_status
|
||||
|
||||
; count_frames >= 120? update!
|
||||
lda count_frames
|
||||
cmp #120 ; >= 2 seconds
|
||||
bpl update_status
|
||||
jmp skipped
|
||||
bmi skipped
|
||||
|
||||
update_status:
|
||||
; FR0 = (float)count_iters & clear count_iters
|
||||
copy16 FR0, count_iters
|
||||
jsr IFP
|
||||
; FR0 = (float)count_pixels & clear count_pixels
|
||||
lda count_pixels
|
||||
sta FR0
|
||||
lda #0
|
||||
sta count_iters
|
||||
sta count_iters + 1
|
||||
sta FR0 + 1
|
||||
sta count_pixels
|
||||
jsr IFP
|
||||
|
||||
; FR1 = total_iters
|
||||
ldx #.lobyte(total_iters)
|
||||
ldy #.hibyte(total_iters)
|
||||
; FR1 = total_pixels
|
||||
ldx #.lobyte(total_pixels)
|
||||
ldy #.hibyte(total_pixels)
|
||||
jsr FLD1R
|
||||
|
||||
; FR0 += FR1
|
||||
jsr FADD
|
||||
|
||||
; total_iters = FR0
|
||||
ldx #.lobyte(total_iters)
|
||||
ldy #.hibyte(total_iters)
|
||||
; total_pixels = FR0
|
||||
ldx #.lobyte(total_pixels)
|
||||
ldy #.hibyte(total_pixels)
|
||||
jsr FST0R
|
||||
|
||||
|
||||
|
@ -1904,66 +1667,44 @@ update_status:
|
|||
sta count_frames
|
||||
jsr IFP
|
||||
|
||||
; FR0 *= sec_per_frame
|
||||
ldx #.lobyte(sec_per_frame)
|
||||
ldy #.hibyte(sec_per_frame)
|
||||
; FR0 *= ms_per_frame
|
||||
ldx #.lobyte(ms_per_frame)
|
||||
ldy #.hibyte(ms_per_frame)
|
||||
jsr FLD1R
|
||||
jsr FMUL
|
||||
|
||||
; FR0 += total_sec
|
||||
ldx #.lobyte(total_sec)
|
||||
ldy #.hibyte(total_sec)
|
||||
; FR0 += total_ms
|
||||
ldx #total_ms
|
||||
ldy #0
|
||||
jsr FLD1R
|
||||
jsr FADD
|
||||
|
||||
; total_sec = FR0
|
||||
ldx #.lobyte(total_sec)
|
||||
ldy #.hibyte(total_sec)
|
||||
; total_ms = FR0
|
||||
ldx #total_ms
|
||||
ldy #0
|
||||
jsr FST0R
|
||||
|
||||
; FR0 /= total_iters
|
||||
ldx #.lobyte(total_iters)
|
||||
ldy #.hibyte(total_iters)
|
||||
; FR0 /= total_pixels
|
||||
ldx #total_pixels
|
||||
ldy #0
|
||||
jsr FLD1R
|
||||
jsr FDIV
|
||||
|
||||
; FR0 *= us_per_sec
|
||||
ldx #.lobyte(us_per_sec)
|
||||
ldy #.hibyte(us_per_sec)
|
||||
jsr FLD1R
|
||||
jsr FMUL
|
||||
|
||||
; round (down) to integer
|
||||
jsr FPI
|
||||
clc
|
||||
jsr IFP
|
||||
|
||||
lda #speed_start
|
||||
sta text_col
|
||||
lda #0
|
||||
sta text_row
|
||||
draw_string_const str_speed
|
||||
|
||||
lda text_col
|
||||
pha
|
||||
draw_string_const str_padding
|
||||
pla
|
||||
sta text_col
|
||||
|
||||
; convert to ASCII in INBUFF and print
|
||||
; convert to ASCII in INBUFF
|
||||
jsr FASC
|
||||
jsr draw_string
|
||||
|
||||
; print the first 6 digits
|
||||
draw_text_indirect speed_start, speed_precision, INBUFF
|
||||
draw_text speed_start + speed_precision, str_speed_len, str_speed
|
||||
|
||||
skipped:
|
||||
|
||||
; sx += fill_level[fill_masks] + 1
|
||||
ldx fill_level
|
||||
lda fill_masks,x
|
||||
clc
|
||||
adc #1 ; will never carry
|
||||
adc sx
|
||||
lda sx
|
||||
adc #1
|
||||
sta sx
|
||||
lda #0
|
||||
adc sx + 1
|
||||
lda sx + 1
|
||||
adc #0
|
||||
sta sx + 1
|
||||
|
||||
lda sx
|
||||
|
@ -1973,15 +1714,12 @@ skipped:
|
|||
|
||||
loop_sx_done:
|
||||
|
||||
; sy += fill_level[fill_masks] + 1
|
||||
ldx fill_level
|
||||
lda fill_masks,x
|
||||
clc
|
||||
adc #1 ; will never carry
|
||||
adc sy
|
||||
lda sy
|
||||
adc #1
|
||||
sta sy
|
||||
lda #0
|
||||
adc sy + 1
|
||||
lda sy + 1
|
||||
adc #0
|
||||
sta sy + 1
|
||||
|
||||
lda sy
|
||||
|
@ -2000,13 +1738,7 @@ fill_loop_done:
|
|||
|
||||
loop:
|
||||
; finished
|
||||
|
||||
lda #(40 - str_done_len)
|
||||
sta text_col
|
||||
lda #0
|
||||
sta text_row
|
||||
draw_string_const str_done
|
||||
|
||||
draw_text 40 - str_done_len, str_done_len, str_done
|
||||
jsr keycheck
|
||||
beq loop
|
||||
jmp main_loop
|
||||
|
|
|
@ -18,7 +18,7 @@ Enjoy! I'll probably work on this off and on for the next few weeks until I've g
|
|||
|
||||
## Current state
|
||||
|
||||
Basic rendering is functional, with interactive zoom/pan (+/-/arrows) and 6 preset viewports via the number keys.
|
||||
Basic rendering is functional, with interactive zoom/pan (+/-/arrows) and 4 preset viewports via the number keys.
|
||||
|
||||
The 16-bit signed integer multiplication takes two 16-bit inputs and emits one 32-bit output in the zero page, using the Atari OS ROM's floating point registers as workspaces. Inputs are clobbered.
|
||||
|
||||
|
@ -27,7 +27,7 @@ The 16-bit signed integer multiplication takes two 16-bit inputs and emits one 3
|
|||
* when expanded RAM is available as on 130XE, a 64KB 8-bit multiplication table accelerates the remaining multiplications
|
||||
* without expanded RAM, a table of half-squares is used to implement the algorithm from https://everything2.com/title/Fast+6502+multiplication
|
||||
|
||||
The mandelbrot calculations are done using 3.13-precision fixed point numbers with 6.26-precision intermediates.
|
||||
The mandelbrot calculations are done using 4.12-precision fixed point numbers with 8.24-precision intermediates. It may be possible to squish this down to 3.13/6.26.
|
||||
|
||||
Iterations are capped at 255.
|
||||
|
||||
|
|
14
todo.md
14
todo.md
|
@ -1,17 +1,19 @@
|
|||
things to try:
|
||||
|
||||
* fix status bar to show elapsed time, per-iter time, per-pixel iter count
|
||||
|
||||
* 'turbo' mode disabling graphics in full or part
|
||||
* skip add on the top-byte multiply in sqr8/mul8
|
||||
* should save a few cycles, suggestion by jamey
|
||||
|
||||
* patch the entire expanded-ram imul8xe on top of imul8 to avoid the 3-cycle thunk penalty :D
|
||||
|
||||
* maybe clean up the load/layout of the big mul table
|
||||
|
||||
* consider alternate lookup tables in the top 16KB under ROM
|
||||
* try 3.13 fixed point instead of 4.12 for more precision
|
||||
* can we get away without the extra bit?
|
||||
* since exit compare space would be 6.26 i think so
|
||||
|
||||
* y-axis mirror optimization
|
||||
|
||||
* 'wide pixels' 2x and 4x for a fuller initial image in the tiered rendering
|
||||
* maybe redo tiering to just 4x4, 2x2, 1x1?
|
||||
|
||||
* extract viewport for display & re-input via keyboard
|
||||
|
||||
* fujinet screenshot/viewport uploader
|
||||
|
|
Loading…
Reference in a new issue