diff options
author | B. Watson <urchlay@slackware.uk> | 2022-11-08 00:42:36 -0500 |
---|---|---|
committer | B. Watson <urchlay@slackware.uk> | 2022-11-08 00:44:46 -0500 |
commit | 57587d7d306f5a4ca3597f44b584ce9ad2886866 (patch) | |
tree | 4a6ca6c11b71c6b18473a16606a0084d0c394dbd /dla.s | |
parent | d7ae2f127c09229227f91d2309bc044a49dab2b4 (diff) | |
download | dla-asm-57587d7d306f5a4ca3597f44b584ce9ad2886866.tar.gz |
Store unpacked pixels during generation. Needs more testing.
Diffstat (limited to 'dla.s')
-rw-r--r-- | dla.s | 269 |
1 files changed, 35 insertions, 234 deletions
@@ -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 |