; wander.asm - optimized wandering routine for random fractal far code far data public _wander_asm ; defined here public _setbit public _checkbit public _WritePixel ; needed here public _row public _randoms public _next_random public _hires_rp _wander_asm: ; 4(sp) &x ; x and y hold initial values! ; 8(sp) &y ;wander_asm( retx, rety) ; int *retx, *rety movem.l d2/d3/a2/a3/a4,-(sp) move.l _next_random,a4 ; a4 points to random numbers move.l 20+4(sp),a0 ; d2 = x move.w (a0),d2 move.l 20+8(sp),a0 move.w (a0),d0 ext.l d0 ; get initial row address (from y) asl.l #2,d0 lea _row,a2 adda.l d0,a2 ; a2 = address of row pointer move.l (a2),a3 ; a3 = ptr to row loop move.w d2,d0 ; is this space occupied? asr.w #3,d0 ; calculate byte and bit address btst.b d2,(a3,d0.w) bne loopend ; no ; bsr write_pixel ; to show how it is working ; get random number here move.b (a4)+,d0 ; d0 = next random number bne.s 1$ move.l _randoms,a4 ; wrap around if needed 1$ eor.b d0,d3 ; exclusive or it move.b d3,d0 ; put in 0..14 range (8 posibilities) and.w #$E,d0 ; depending on number, go different directions move.w vectors(pc,d0.w),d0 before_jmp jmp (pc,d0.w) quad0: addq.w #1,d2 ; x++ bra.s loop quad1: addq.w #1,d2 ; x++ move.l -(a2),a3 ; y-- bra.s loop quad2: move.l -(a2),a3 ; y-- bra.s loop quad3: subq.w #1,d2 ; x-- move.l -(a2),a3 ; y-- bra.s loop quad4: subq.w #1,d2 ; x-- bra.s loop quad5: subq.w #1,d2 ; x-- addq.w #4,a2 ; y++ move.l (a2),a3 bra.s loop quad6: addq.w #4,a2 ; y++ move.l (a2),a3 bra.s loop quad7: addq.w #1,d2 ; x++ addq.w #4,a2 ; y++ move.l (a2),a3 bra.s loop vectors: dc.w quad0-before_jmp-2 dc.w quad1-before_jmp-2 dc.w quad2-before_jmp-2 dc.w quad3-before_jmp-2 dc.w quad4-before_jmp-2 dc.w quad5-before_jmp-2 dc.w quad6-before_jmp-2 dc.w quad7-before_jmp-2 loopend: move.l 20+4(sp),a0 ; return x move.w d2,(a0) move.l 20+8(sp),a0 ; return y move.l a2,d0 lea _row,a1 sub.l a1,d0 asr.w #2,d0 move.w d0,(a0) move.l a4,_next_random ; keep track of random number pointer movem.l (sp)+,d2/d3/a2/a3/a4 rts write_pixel: ; a2 = raw index into row ; d2 = x move.l a2,d0 ; get raw row pointer address lea _row,a1 sub.l a1,d0 ; subtract off base to get raw index asr.l #2,d0 ; move.l d0,-(sp) ext.l d2 move.l d2,-(sp) move.l _hires_rp,-(sp) jsr _WritePixel lea 12(sp),sp rts ;========================================================================= _setbit ; setbit( row, x, y ) ; row is the address of an array of pointers to rows ; x and y are 16 bit ; This sets the given bit ; ; 10(sp).w y ; 8(sp).w x ; 4(sp).l address of array of pointers to rows move.l 4(sp),a0 ; a0 = address of base of array move.w 10(sp),d0 ; d0 = y asl.w #2,d0 move.l (a0,d0.w),a0 ; a0 = address of row move.w 8(sp),d0 ; compute bit address move.w d0,d1 ; bit # in d0 (low 3 bits) asr.w #3,d1 ; compute byte offset bset d0,(a0,d1.w) ; set it! rts _checkbit ; checkbit( row, x, y ) ; row is the address of an array of pointers to rows ; x and y are 16 bit ; This checks the given bit, and returns a 16 bit boolean value ; ; 10(sp).w y ; 8(sp).w x ; 4(sp).l address of array of pointers to rows move.l 4(sp),a0 ; a0 = address of base of array move.w 10(sp),d0 ; d0 = y asl.w #2,d0 move.l (a0,d0.w),a0 ; a0 = address of row move.w 8(sp),d0 ; compute bit address move.w d0,d1 ; bit # in d0 (low 3 bits) asr.w #3,d1 ; compute byte offset btst d0,(a0,d1.w) ; check it! sne d0 ext.w d0 ; d0.w = bit set rts end