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 ; Our zero-page vars
sx = $80 ; 8 bits: screen pixel x sx = $80 ; i16: screen pixel x
sy = $81 ; 8 bits: screen pixel y sy = $82 ; i16: screen pixel y
cx = $82 ; 16 bits fixed point ox = $84 ; fixed3.13: center point x
cy = $84 ; 16 bits fixed point oy = $86 ; fixed3.13: center point y
zx = $86 ; 16 bits fixed point cx = $84 ; fixed3.13: c_x
zy = $88 ; 16 bits fixed point cy = $86 ; fixed3.13: c_y
zx_2 = $8a ; 32 bits fixed point zx = $88 ; fixed3.13: z_x
zy_2 = $8e ; 32 bits fixed point zy = $8a ; fixed3.13: z_y
zx_zy = $92 ; 32 bits fixed point
dist = $96 ; 32 bits fixed point
iter = $9a ; 8 bits iteration count
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 ; FP registers in zero page
FR0 = $d4 FR0 = $d4
@ -19,6 +23,77 @@ FRE = $da
FR1 = $e0 FR1 = $e0
FR2 = $e6 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 .code
.export start .export start
@ -181,10 +256,18 @@ positive:
.macro imul16 dest, arg1, arg2 .macro imul16 dest, arg1, arg2
copy16 FR0, arg1 ; 12 cyc copy16 FR0, arg1 ; 12 cyc
copy16 FR1, arg2 ; 12 cyc copy16 FR1, arg2 ; 12 cyc
jsr imul16_func ; 470-780 jsr imul16_func ; 470-780 cyc
copy32 dest, FR2 ; 24 cyc copy32 dest, FR2 ; 24 cyc
.endmacro .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 ; min 470 cycles
; max 780 cycles ; max 780 cycles
.proc imul16_func .proc imul16_func
@ -269,8 +352,6 @@ next:
.endmacro .endmacro
.proc mandelbrot .proc mandelbrot
; input: ; input:
; cx: position scaled to 4.12 fixed point - -8..+7.9 ; cx: position scaled to 4.12 fixed point - -8..+7.9
@ -355,29 +436,128 @@ still_in:
.endproc .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 .proc start
looplong: ; ox = 0; oy = 0; zoom = 0
; cx = -0.5 lda #0
lda #$f7 sta ox
sta cx sta ox + 1
lda #$ff sta oy
sta cx + 1 sta oy + 1
sta zoom
; cy = 1 ; Disable display DMA
lda #$10
sta cy
lda #$00 lda #$00
sta cy + 1 sta DMACTL
jsr mandelbrot ; Set up the display list
; should have 32-bit -15 in FR2 lda #.lobyte(display_list)
sta DLISTL
lda #.hibyte(display_list)
sta DLISTH
; save the completed iter count for debugging ; zero the range from framebuffer_top to framebuffer_end
lda iter lda #.lobyte(framebuffer_top)
sta temp 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: loop:
; keep looping over so we can work in the debugger ; finished
jmp looplong jmp loop
.endproc .endproc