http://www.tienza.es/crux/src/www.jwz.org/xscreensaver/xscreensaver-5.05.tar.gz
[xscreensaver] / hacks / images / m6502 / sierpinsky.asm
1 ; 6502 assembler Sierpinsky Triangle ver.2
2 ; by Magnus Wedmark 2007-05-02
3 ; This program is especially written for
4 ; the 6502asm.com competition and 
5 ; uses the 32*32 pixel display used in that
6 ; virtual platform. The sierpinsky 
7 ; fractal is one of the simplest to
8 ; implement. Here is a walk-through:
9 ; 1) Specify 3 points that form a triangle
10 ; 2) Choose one of them as a starting point
11 ; 3) Choose one of them as targetpoint randomly
12 ; 4) Set the new current position half-way 
13 ;    between the current point and the target 
14 ;    point.
15 ; 5) Goto 3
16         
17         LDX #0
18         LDY #0
19 new_rnd:
20         LDA $FE       ; random 0-255
21         AND #3        ; only 0-3 left
22         CMP #3
23         BNE good_rnd
24         JMP new_rnd
25 good_rnd:     
26 ; random = 0-2
27         PHA
28 ; transform X and Y values according to: 
29 ; X=X/2+(P*8) and Y=Y/2+(P*16)
30         ASL
31         ASL
32         ASL
33         STA $F3 ; P*8
34         PLA
35         AND #1
36         ASL
37         ASL
38         ASL
39         ASL
40         STA $F4 ; (P AND 1)*16
41         TXA
42         LSR
43         ADC $F3
44         TAX
45         TYA
46         LSR
47         ADC $F4
48         TAY
49         JSR set_point   ; use and restore regs
50         JMP new_rnd
51
52 set_point: ; uses both X,Y,A and restores them
53         PHA ; backup all reg-value (X,Y,A)
54         TXA
55         PHA
56         TYA
57         PHA 
58         PHA 
59         PHA ; triple Y push, two for int. use
60         STX $F2  ; transfer X to Y using $F2
61         LDY $F2
62         LDA #0
63         STA $F0
64         LDA #$2
65         STA $F1 ; set base vector to $200
66         LDA #0
67         PLA  ; transfer the pushed Y-coord to A
68         AND #$07 ; the value %0000'0111
69         ASL
70         ASL
71         ASL
72         ASL
73         ASL
74         CLC
75         ADC $F0
76         STA $F0
77         BCC no_carry
78         INC $F1
79 no_carry:
80         CLC
81         PLA ; transfer the pushed Y-coord to A
82         AND #$18
83         LSR
84         LSR
85         LSR
86         ADC $F1
87         STA $F1         
88
89         CLC
90         TYA
91         ADC $F0
92         ADC $F1
93
94         LDA #1 ;1 = white for trouble-shooting
95         JSR set_toning_point ; use for shading
96         STA ($F0),Y  ; set pixel
97         PLA  ; restore all reg-value (X,Y,A)
98         TAY
99         PLA
100         TAX
101         PLA
102         RTS
103
104 ; sub routine to shade the current pixel ($F0),Y
105 ; lighter on a scale: $0, $B, $C, $F, $1 
106 ; Black, DarkGrey, Grey, LightGrey, White
107 set_toning_point:
108         LDA ($F0),Y
109         CMP #$00
110         BNE not_black
111         LDA #$0B
112         RTS
113 not_black:
114         CMP #$0B
115         BNE not_dgrey
116         LDA #$0C
117         RTS
118 not_dgrey:
119         CMP #$0C
120         BNE not_grey
121         LDA #$0F
122         RTS
123 not_grey:
124         CMP #$0F
125         BNE not_lgrey
126         LDA #$01
127         RTS
128 not_lgrey:
129 ; white stays white
130         RTS
131