This commit is contained in:
Brooke Vibber 2023-01-21 19:17:30 -08:00
parent 8044dbfc21
commit f22653bd87

242
mandel.s
View file

@ -1,17 +1,21 @@
; Our zero-page vars
sx = $80 ; 8 bits: screen pixel x
sy = $81 ; 8 bits: screen pixel y
cx = $82 ; 16 bits fixed point
cy = $84 ; 16 bits fixed point
zx = $86 ; 16 bits fixed point
zy = $88 ; 16 bits fixed point
zx_2 = $8a ; 32 bits fixed point
zy_2 = $8e ; 32 bits fixed point
zx_zy = $92 ; 32 bits fixed point
dist = $96 ; 32 bits fixed point
iter = $9a ; 8 bits iteration count
sx = $80 ; i16: screen pixel x
sy = $82 ; i16: screen pixel y
ox = $84 ; fixed3.13: center point x
oy = $86 ; fixed3.13: center point y
cx = $84 ; fixed3.13: c_x
cy = $86 ; fixed3.13: c_y
zx = $88 ; fixed3.13: z_x
zy = $8a ; fixed3.13: z_y
temp = $a0 ; debug temp area
zx_2 = $90 ; fixed6.26: z_x^2
zy_2 = $94 ; fixed6.26: z_y^2
zx_zy = $98 ; fixed6.26: z_x * z_y
dist = $9c ; fixed6.26: z_x^2 + z_y^2
iter = $a0 ; u8: iteration count
zoom = $a1 ; u8: zoom shift level
temp = $a2 ; u16
; FP registers in zero page
FR0 = $d4
@ -19,6 +23,77 @@ FRE = $da
FR1 = $e0
FR2 = $e6
; High data
framebuffer_top = $8000
framebuffer_bottom = $9000
textbuffer = $9f00
framebuffer_end = $a000
height = 184
half_height = height >> 1
width = 160
half_width = 160 >> 1
width_ratio_3_13 = (5 << 11) ; 5/4
height_ratio_3_13 = (3 << 11) ; 5/4
DMACTL = $D400
DLISTL = $D402
DLISTH = $D403
.data
aspect:
; aspect ratio!
; pixels at 320w are 5:6 (narrow)
; pixels at 160w are 5:3 (wide)
;
; cy = (sy << (8 - zoom)) * (96 / 128 = 3 / 4)
; cx = (sx << (8 - zoom)) * ((3 / 4) * (5 / 3) = 5 / 4)
;
; so vertical range -92 .. 91.9 is -2.15625 .. 2.15624
; &horizontal range -80 .. 79.9 is -3.125 .. 3.124
;
; 184h is the equiv of 220.8h at square pixels
; 320 / 220.8 = 1.45 display aspect ratio
aspect_x:
.word 5 << (13 - 2)
aspect_y:
.word 3 << (13 - 2)
bit_masks:
.byte 3
.byte 3 << 2
.byte 3 << 4
.byte 3 << 6
display_list:
; 48 lines overscan
.repeat 5
.byte $70 ; 8 blank lines
.endrep
; 184 lines graphics
; ANTIC mode e (160px 2bpp, 1 scan line per line)
.byte $4e
.addr framebuffer_top
.repeat half_height - 1
.byte $0e
.endrep
.byte $4e
.addr framebuffer_bottom
.repeat half_height - 1
.byte $0e
.endrep
; 1 line 40-column text
.byte $42
.addr textbuffer
.byte $41 ; jump and blank
.addr display_list
.code
.export start
@ -181,10 +256,18 @@ positive:
.macro imul16 dest, arg1, arg2
copy16 FR0, arg1 ; 12 cyc
copy16 FR1, arg2 ; 12 cyc
jsr imul16_func ; 470-780
jsr imul16_func ; 470-780 cyc
copy32 dest, FR2 ; 24 cyc
.endmacro
.macro imul16_round dest, arg1, arg2
copy16 FR0, arg1 ; 12 cyc
copy16 FR1, arg2 ; 12 cyc
jsr imul16_func ; 470-780 cyc
round16 FR2 ; 5-28 cyc
copy16 dest, FR2 + 2 ; 12 cyc
.endmacro
; min 470 cycles
; max 780 cycles
.proc imul16_func
@ -269,8 +352,6 @@ next:
.endmacro
.proc mandelbrot
; input:
; cx: position scaled to 4.12 fixed point - -8..+7.9
@ -355,29 +436,128 @@ still_in:
.endproc
.macro zoom_factor dest, src, zoom, aspect
.local cont
.local enough
; cx = (sx << (8 - zoom))
copy16 dest, src
ldx zoom
cont:
cpx #8
beq enough
shl16 dest
inx
jmp cont
enough:
; cy = cy * (3 / 4)
; cx = cx * (5 / 4)
imul16_round dest, dest, aspect
.endmacro
.proc pset
; screen coords in signed sx,sy
; iter holds the target to use
; @todo implement
rts
.endproc
.proc start
looplong:
; cx = -0.5
lda #$f7
sta cx
lda #$ff
sta cx + 1
; ox = 0; oy = 0; zoom = 0
lda #0
sta ox
sta ox + 1
sta oy
sta oy + 1
sta zoom
; cy = 1
lda #$10
sta cy
; Disable display DMA
lda #$00
sta cy + 1
sta DMACTL
jsr mandelbrot
; should have 32-bit -15 in FR2
; Set up the display list
lda #.lobyte(display_list)
sta DLISTL
lda #.hibyte(display_list)
sta DLISTH
; save the completed iter count for debugging
lda iter
; zero the range from framebuffer_top to framebuffer_end
lda #.lobyte(framebuffer_top)
sta temp
lda #.hibyte(framebuffer_top)
sta temp + 1
zero_page_loop:
lda #0
ldy #0
zero_byte_loop:
sta (temp),y
iny
bne zero_byte_loop
inc temp + 1
lda temp + 1
cmp #.hibyte(framebuffer_end)
bne zero_page_loop
; Re-enable display DMA
lda #$22
sta DMACTL
main_loop:
; sy = -92 .. 91
lda #(256-half_height)
sta sy
lda #(256-1)
sta sy + 1
loop_sy:
; sx = -80 .. 79
lda #(256-half_width)
sta sx
lda #(256-1)
sta sx + 1
loop_sx:
zoom_factor cx, sx, zoom, aspect_x
zoom_factor cy, sy, zoom, aspect_y
jsr mandelbrot
jsr pset
lda sx
clc
adc #1
sta sx
cmp #half_width
beq loop_sx_done
lda sx + 1
adc #0
sta sx + 1
jmp loop_sx
loop_sx_done:
lda sy
clc
adc #1
sta sy
cmp #half_height
beq loop_sy_done
lda sy + 1
adc #0
sta sy + 1
jmp loop_sy
loop_sy_done:
loop:
; keep looping over so we can work in the debugger
jmp looplong
; finished
jmp loop
.endproc