aboutsummaryrefslogtreecommitdiff
path: root/dla.s
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2022-11-08 00:42:36 -0500
committerB. Watson <urchlay@slackware.uk>2022-11-08 00:44:46 -0500
commit57587d7d306f5a4ca3597f44b584ce9ad2886866 (patch)
tree4a6ca6c11b71c6b18473a16606a0084d0c394dbd /dla.s
parentd7ae2f127c09229227f91d2309bc044a49dab2b4 (diff)
downloaddla-asm-57587d7d306f5a4ca3597f44b584ce9ad2886866.tar.gz
Store unpacked pixels during generation. Needs more testing.
Diffstat (limited to 'dla.s')
-rw-r--r--dla.s269
1 files changed, 35 insertions, 234 deletions
diff --git a/dla.s b/dla.s
index 3e549f5..9ebf2c1 100644
--- a/dla.s
+++ b/dla.s
@@ -13,8 +13,9 @@
loadaddr = $2000
screen = $4000 ; must be on a x000 (4K) boundary
screen2 = screen + $1000 ; rest of screen RAM after 4K boundary
+ pixarray = screen + $20
linelen = $20 ; aka 32 bytes, antic F (GR.8) in narrow mode.
- maxlines = $C0 ; 192 lines of display
+ maxlines = $aa ; 170 lines of display
screenbytes = maxlines * linelen
dl_len = 202 ; remember to update this if you modify the display list!
dlist = screen - dl_len
@@ -34,6 +35,7 @@ pixmask: .res 1 ; ditto.
cursor_x: .res 1 ; cursor x/y are args to plot/unplot/locate
cursor_y: .res 1
pixptr2: .res 2 ; used by drunkwalk
+screenptr = pixptr2
circlesize: .res 1 ; 0 to 3
@@ -156,6 +158,7 @@ dfltseed:
generate: ;;; start of generate()
jsr initscreen
+
; wait for shadow regs to get updated...
lda RTCLOK+2
wl:
@@ -240,6 +243,7 @@ checkmaxparts:
bne next_particle
main_done:
+ jsr render
lda #0
sta CRITIC
sta COLOR2
@@ -404,7 +408,7 @@ isloop0:
bne isloop0
; next, clear screen memory
- ldx #>screenbytes ; clear this many pages
+ ldx #$72 ; clear this many pages
tay ; 0 again
isloop:
sta (pixptr),y
@@ -432,224 +436,20 @@ isloop:
sta COLCRS+1
rts
-;;; Subroutine: plotsetup
-;;; - set pixptr to point to screen memory at cursor_y.
-;;; - set pixmask to the mask for cursor_x.
-;;; - set Y reg to the byte offset for cursor_x.
-;;; - returns with cursor_x in X reg, pixmask in A reg too.
-;;; Called by plot, unplot, and locate.
-plotsetup:
+ .include "render.s"
+
+plot:
ldx cursor_y
lda lineaddrs_l,x
sta pixptr
lda lineaddrs_h,x
sta pixptr+1
-
- ldx cursor_x
- ldy xoffsets,x
- lda xmasks,x
- sta pixmask
-
- rts
-
-;;; Subroutine: plot
-;;; plots a pixel at (cursor_x, cursor_y)
-plot:
- jsr plotsetup
- lda (pixptr),y
- ora pixmask
+ ldy cursor_x
+ lda #1
sta (pixptr),y
rts
-oob:
- rts
-;;; Subroutine: drunkwalk
-;;; Walk the point around randomly until it either is
-;;; adjacent to a set pixel or goes out of bounds.
-;;; Return with Z=0 if out of bounds, Z=1 if it hit a pixel.
-;;; This is the innermost loop, so it should be as optimized as
-;;; possible (we're not there yet).
-drunkwalk:
- ; X holds the X coord the whole time, only needs to be loaded on entry.
- ; preload pixptr, too.
- ldx part_x ; 3
- ldy part_y ; 3
- lda lineaddrs_l,y ; 5
- sta pixptr ; 3
- lda lineaddrs_h,y ; 5
- sta pixptr+1 ; 3
- ; 4 code paths: TODO: count
- ; note that part_x and part_y are *never* zero; all the bne's here
- ; are "branch always".
- ; all the "cmp #0" here get their operands modified by set_limits.
-dwloop:
- ldy part_y ; 3
- bit RANDOM ; 4 ; use top 2 bits (probably more random, definitely faster)
- bmi lr ; 2/3
- bvc down ; 2/3
- dey ; 2 ; N=1 V=1 up
-selfmod_ymin = * + 1
- cpy #0 ; 2
- beq oob ; 2
- jmp check_lru
-down:
- iny ; 2 ; N=1 V=0 down
-selfmod_ymax = * + 1
- cpy #0 ; 2
- beq oob ; 2
- jmp check_lrd
-lr:
- bvc right ; 2/3
- dex ; 3 ; N=0 V=1 left
-selfmod_xmin = * + 1
- cpx #0 ; 2
- beq oob ; 2
- ldy xoffsets-1,x ; 4 ; moved left, check left X neighbor only.
- lda xmasks-1,x ; 4 ; right X neighbor definitely empty, because
- and (pixptr),y ; 5 ; we just moved out of that cell.
- bne stick ; 2/3
- beq check_ud ; 3 ; still have to check Y (up/down) neighbors.
-right:
- inx ; 3 ; N=0 V=0 right
-selfmod_xmax = * + 1
- cpx #0 ; 2
- beq oob ; 2
- ldy xoffsets+1,x ; 4 ; as above, moved right, check right X neighbor only.
- lda xmasks+1,x ; 4
- and (pixptr),y ; 5
- bne stick ; 2/3
- ; fall through to check_ud
-
-check_ud:
- ; this happens when the pixel moved left or right.
- ; (0,-1)
- ; subtract 32 (one line) from the pointer. one cycle faster
- ; than reloading from lineaddrs_l/h table.
- lda pixptr ; 3
- sec ; 2
- sbc #$20 ; 2
- sta pixptr2 ; 3
- lda pixptr+1 ; 3
- sbc #0 ; 2
- sta pixptr2+1 ; 3
- ;ldx part_x ; X already has this from before
- ldy xoffsets,x ; 4
- lda xmasks,x ; 4
- sta pixmask ; 3
- and (pixptr2),y ; 5
- bne stick ; 2/3
- ; (0,1)
- tya ; 2
- ora #$40 ; 2 ; add 64, AKA 2 screen lines
- tay ; 2
- lda (pixptr2),y ; 5
- and pixmask ; 3
- bne stick ; 2/3
- jmp dwloop ; 3 ; too far for a branch
-
-stick: ; we always get here with Z flag clear
- stx part_x ; only update part_x at exit.
- rts
-
- ; this happens when the pixel moved up.
-check_lru:
- sty part_y ; 3
- lda lineaddrs_l,y ; 5
- sta pixptr ; 3
- lda lineaddrs_h,y ; 5
- sta pixptr+1 ; 3
-
- ; 3/4 of the time, we can use a faster code path, check
- ; (-1,0) and (1,0) at the same time. this happens only when
- ; both pixels lie within the same byte.
- ;ldx part_x ; X already has this from before
- lda fastmasks,x ; 4
- beq slow_x_lru ; 2/3
- ldy xoffsets,x ; 4
- and (pixptr),y ; 5
- bne stick ; 2/3
- beq check_u ; 2/3
-slow_x_lru:
- ; (-1,0)
- ldy xoffsets-1,x ; 4
- lda xmasks-1,x ; 4
- and (pixptr),y ; 5
- bne stick ; 2/3
- ; (1,0)
- ldy xoffsets+1,x ; 4
- lda xmasks+1,x ; 4
- and (pixptr),y ; 5
- bne stick ; 2/3
-
-check_u:
- ; (0,-1)
- ; subtract 32 (one line) from the pointer. one cycle faster
- ; than reloading from lineaddrs_l/h table.
- lda pixptr ; 3
- sec ; 2
- sbc #$20 ; 2
- sta pixptr2 ; 3
- lda pixptr+1 ; 3
- sbc #0 ; 2
- sta pixptr2+1 ; 3
- ;ldx part_x ; X already has this from before
- ldy xoffsets,x ; 4
- lda xmasks,x ; 4
- ;sta pixmask ; 3
- and (pixptr2),y ; 5
- bne stick ; 2/3
- jmp dwloop ; 3 ; too far for a branch
-
-
- ; this happens when the pixel moved down.
-check_lrd:
- sty part_y ; 3
- lda lineaddrs_l,y ; 5
- sta pixptr ; 3
- lda lineaddrs_h,y ; 5
- sta pixptr+1 ; 3
-
- ; 3/4 of the time, we can use a faster code path, check
- ; (-1,0) and (1,0) at the same time. this happens only when
- ; both pixels lie within the same byte.
- ;ldx part_x ; X already has this from before
- lda fastmasks,x ; 4
- beq slow_x_lrd ; 2/3
- ldy xoffsets,x ; 4
- and (pixptr),y ; 5
- bne stick ; 2/3
- beq check_d ; 2/3
-slow_x_lrd:
- ; (-1,0)
- ldy xoffsets-1,x ; 4
- lda xmasks-1,x ; 4
- and (pixptr),y ; 5
- bne stick ; 2/3
- ; (1,0)
- ldy xoffsets+1,x ; 4
- lda xmasks+1,x ; 4
- and (pixptr),y ; 5
- bne stick ; 2/3
-
-check_d:
- ; (0,-1)
- lda pixptr ; 3
- clc ; 2
- adc #$20 ; 2
- sta pixptr2 ; 3
- lda pixptr+1 ; 3
- adc #0 ; 2
- sta pixptr2+1 ; 3
- ;ldx part_x ; X already has this from before
- ldy xoffsets,x ; 4
- lda xmasks,x ; 4
- ;sta pixmask ; 3
- and (pixptr2),y ; 5
- bne stick2 ; 2/3
- jmp dwloop ; 3 ; too far for a branch
-stick2:
- stx part_x ; only update part_x at exit.
- rts
+ .include "drunkwalk.s"
;;; Subroutine: drawseed
;;; dispatch to appropriate seed subroutine
@@ -664,9 +464,9 @@ drawseed:
;;; Subroutine: seed_point
;;; draw initial point in center
seed_point:
- lda #$7f
+ lda #center_x
sta cursor_x
- lda #$5f
+ lda #center_y
sta cursor_y
jmp plot
@@ -675,56 +475,56 @@ seed_point:
seed_long:
lda #$1
sta cursor_x
- lda #$5f
+ lda #center_y
sta cursor_y
slnoop:
jsr plot
inc cursor_x
lda cursor_x
- cmp #$ff
+ cmp #$aa
bne slnoop
rts
;;; Subroutine: seed_plus
;;; plus share, made of two 20px lines intersecting in the center
seed_plus:
- lda #$7f
+ lda #center_x
sta cursor_x
- lda #$55
+ lda #center_y-10
sta cursor_y
sploop:
jsr plot
inc cursor_y
lda cursor_y
- cmp #$69
+ cmp #center_y+10
bne sploop
- lda #$75
+ lda #center_x-10
sta cursor_x
- lda #$5f
+ lda #center_y
sta cursor_y
slloop:
jsr plot
inc cursor_x
lda cursor_x
- cmp #$89
+ cmp #center_x+10
bne slloop
rts
;;; Subroutine: seed_4pt
;;; four points, the corners of a 20px square
seed_4pt:
- lda #$75
+ lda #center_x-10
sta cursor_x
- lda #$55
+ lda #center_y-10
sta cursor_y
jsr plot
- lda #$68
+ lda #center_y+10
sta cursor_y
jsr plot
- lda #$88
+ lda #center_x+10
sta cursor_x
jsr plot
- lda #$55
+ lda #center_y-10
sta cursor_y
jmp plot
@@ -805,7 +605,7 @@ ci_done:
; banner and saveprompt must start with a clear-screen code.
banner:
.byte $7d, "Diffusion Limited Aggregate",$9b
- .byte "Urchlay's ASM version 0.1.3",$9b,$9b
+ .byte "Urchlay's ASM version 0.1.99",$9b,$9b
.byte "Particle count range: 1 to 65535",$9b
.byte "How many particles [",$0
@@ -852,17 +652,17 @@ seeds_h: .byte >(seed_point-1),>(seed_plus-1),>(seed_4pt-1),>(seed_long-1)
; code by 384 bytes, but compared to calculating the address, is
; twice as fast!
lineaddrs_l:
- laddr .set screen
- .repeat 192
+ laddr .set pixarray
+ .repeat 170
.byte <laddr
- laddr .set laddr + $20
+ laddr .set laddr + 170
.endrep
lineaddrs_h:
- laddr .set screen
- .repeat 192
+ laddr .set pixarray
+ .repeat 170
.byte >laddr
- laddr .set laddr + $20
+ laddr .set laddr + 170
.endrep
; tables to replace X coord => mask-and-offset calculations.
@@ -895,6 +695,7 @@ fastmasks:
xex_org dlist
.byte blank8, blank8, blank8
+ .byte blank8
.byte gr8 | lms
.word screen
.repeat 127