http://www.tienza.es/crux/src/www.jwz.org/xscreensaver/xscreensaver-5.05.tar.gz
[xscreensaver] / hacks / images / m6502 / crunch6502.asm
1 ;; Show "6502" on the screen waving up and down.
2 ;; Jeremy English 29-December-2007
3 ;;
4 ;; Each digit is stored as a pattern of vertical bits.
5 ;; For example:
6 ;;
7 ;;   111111     This is the digit six. We think of the digit 
8 ;;   111111     by it's column pattern. The column patterns 
9 ;;   110000     are labeled at the bottom of the example. 
10 ;;   110000     Pattern B is 1100110011. The basic algorithm 
11 ;;   111111     is that we get the pattern, paint the first
12 ;;   111111     bit (1 foreground, 0 background) then dec y 
13 ;;   110011     and get the next bit.
14 ;;   110011     
15 ;;   111111     The pattern for each digit is:
16 ;;   111111     6 = AABBCC
17 ;;   ------     5 = DDBBCC
18 ;;   AABBCC     0 = AAEEAA
19 ;;              2 = CCBBDD
20
21 ;; Addresses $0 and $1 are used by the paint subroutine.
22 ;; Addresses $2 through $6 are used by the display pattern subroutine
23 ;; Address $7 is used in the main loop
24 ;; Address $8 through $1a  are used for the start positions
25 ;; Address $1b is used by the display pattern subroutine
26 ;; Address $1c is used as the color row offset.
27 ;; Addresses $d0 through $ef store the font table
28
29 jmp init_font_table
30 start:
31
32 ;; Initialize the pointers to the start position.
33 lda #<y_start_pos1
34 sta $b
35 lda #>y_start_pos1
36 sta $c
37 lda #<y_start_pos2
38 sta $d
39 lda #>y_start_pos2
40 sta $e
41 lda #<y_start_pos3
42 sta $f
43 lda #>y_start_pos3
44 sta $10
45 lda #<y_start_pos4
46 sta $11
47 lda #>y_start_pos4
48 sta $12
49 lda #<y_start_pos5
50 sta $13
51 lda #>y_start_pos5
52 sta $14
53 lda #<y_start_pos4
54 sta $15
55 lda #>y_start_pos4
56 sta $16
57 lda #<y_start_pos3
58 sta $17
59 lda #>y_start_pos3
60 sta $18
61 lda #<y_start_pos2
62 sta $19
63 lda #>y_start_pos2
64 sta $1a
65
66
67 lda #0        ; start position to use
68 sta $8
69
70 main_loop:
71 inc $1c       ; increment the color offset.
72 inc $1d       ; increment the starting x position
73 ldy $8        ; load the current start position index
74 ldx $b,y      ; get the lsb from the table
75 txa
76 sta $9        ; store the msb of the start position pointer
77 iny           ; move to the next position in the table
78 ldx $b,y      ; get the msb from the table
79 txa
80 sta $a        ; store the lsb of the start position pointer
81 iny           ; move the index up by one
82 tya
83 cmp #$10       ; have we looked at all 16 start positions?
84 bne store_idx ; if not then keep the index and store it
85 lda #0        ; set the index back to zero
86 store_idx:
87 sta $8        ; save the index back in memory
88
89 ldy #0
90 lda #$ff
91 sta $4        ; initialize the column to FF
92 display_loop:
93   inc $4      ; increment the column
94   ldx $d0,y   ; load the lsb from the font table
95   stx $2
96   iny
97   ldx $d0,y   ; load the msb from the font table
98   stx $3
99   sty $7      ; save y in memory
100   jsr dis_pat ; Jump to the display pattern subroutine.
101   inc $4      ; increment the column    
102   jsr dis_pat ; Each pattern gets painted twice so we have a thicker font
103   ldy $7      ; get y out of memory
104   iny         ; increment the index
105   tya
106   cmp #$20    ; Did we display all of the columns?
107   bne display_loop ;if not continue
108 jmp main_loop
109 rts
110
111 init_font_table:
112   ;;Setup a table in the zero page that contains the string "6502"
113   lda #<pattern_a    ;start with digit 6. It's pattern is aabbcc
114   sta $d0
115   lda #>pattern_a
116   sta $d1
117   lda #<pattern_b
118   sta $d2
119   lda #>pattern_b
120   sta $d3
121   lda #<pattern_c
122   sta $d4
123   lda #>pattern_c
124   sta $d5
125   lda #<pattern_null  ;We want to space everything out with blanks
126   sta $d6
127   lda #>pattern_null
128   sta $d7
129   lda #<pattern_d   ;load memory for digit 5 ddbbcc
130   sta $d8
131   lda #>pattern_d
132   sta $d9
133   lda #<pattern_b
134   sta $da
135   lda #>pattern_b
136   sta $db
137   lda #<pattern_c
138   sta $dc
139   lda #>pattern_c
140   sta $dd
141   lda #<pattern_null
142   sta $de
143   lda #>pattern_null
144   sta $df
145   lda #<pattern_a   ;load memory for digit 0 aaeeaa
146   sta $e0
147   lda #>pattern_a
148   sta $e1
149   lda #<pattern_e
150   sta $e2
151   lda #>pattern_e
152   sta $e3
153   lda #<pattern_a
154   sta $e4
155   lda #>pattern_a
156   sta $e5
157   lda #<pattern_null
158   sta $e6
159   lda #>pattern_null
160   sta $e7
161   lda #<pattern_c   ;load memory for digit 2 ccbbdd
162   sta $e8
163   lda #>pattern_c
164   sta $e9
165   lda #<pattern_b
166   sta $ea
167   lda #>pattern_b
168   sta $eb
169   lda #<pattern_d
170   sta $ec
171   lda #>pattern_d
172   sta $ed
173   lda #<pattern_null
174   sta $ee
175   lda #>pattern_null
176   sta $ef
177   jmp start
178
179
180 ;; Display a pattern on the screen. The pattern to use is 
181 ;; stored at $2 and $3. The current column is stored at $4.
182 dis_pat:
183   ldy $4             ; Load the current column into y
184   lda ($9),y         ; Get the start position for y
185   tay
186   sty $5             ; Store the starting position in memory
187   ldy #0             ; We have 12 bits that need to be painted
188 dis_pat_loop:
189   lda ($2),y         ; get a bit from the pattern
190   pha                ; save the color on the stack
191   tya                ; move the index into the accumulator
192   clc                ; clear the carry 
193   adc $5             ; add the starting position to the index
194   sty $6             ; store the index 
195   tay                ; The calculated y position
196   ldx $4             ; The x position is the current column
197   pla                ; pop the color off of the stack
198   beq go_paint       ; black just paint it
199   clc                ; get rid of any carry bit
200   sty $1b            ; save the y coordinate
201   tya
202   clc
203   adc $1c            ; add the color offset
204   and #$7            ; make sure the look up is in range
205   tay                ; move the new index into y so we can look up the color
206   lda color_row,y    ; if not black get the row color
207   ldy $1b            ; restore the y coordinate
208 go_paint:
209   jsr paint          ; paint the pixel on the screen
210   ldy $6             ; get the index out of memory
211   iny                ; increment the index
212   tya
213   cmp #12            ; Have we looked at all of the bits?
214   bne dis_pat_loop   ; if not then continue looking
215   rts                ; else return from the subroutine
216
217 ;; Paint - Put a pixel on the screen by using the x registry for 
218 ;;         the x position, the y registry for the y position and 
219 ;;         the accumulator for the color.
220 paint:
221    pha           ; Save the color
222    lda yl,y      ; Get the LSB of the memory address for y
223    sta $0        ; Store it first
224    lda yh,y      ; Get the MSB of the memory address for y
225    sta $1        ; Store it next
226    txa           ; We want x in the y registry so we transfer it to A
227    tay           ; and then A into y.
228    pla           ; Pop the color off of the stack
229    sta ($0),y    ; Store the color at the correct y + x address.
230    rts           ; return from the subroutine.
231
232 ;; Paint uses the following two tables to look up the 
233 ;; correct address for a y coordinate between 
234 ;; 0 and 31.
235
236 ;; Y cord MSB
237 yh:
238        dcb $02, $02, $02, $02, $02, $02, $02, $02
239        dcb $03, $03, $03, $03, $03, $03, $03, $03
240        dcb $04, $04, $04, $04, $04, $04, $04, $04
241        dcb $05, $05, $05, $05, $05, $05, $05, $05
242 ;; Y cord LSB
243 yl:
244        dcb $00, $20, $40, $60, $80, $a0, $c0, $e0
245        dcb $00, $20, $40, $60, $80, $a0, $c0, $e0
246        dcb $00, $20, $40, $60, $80, $a0, $c0, $e0
247        dcb $00, $20, $40, $60, $80, $a0, $c0, $e0 
248
249 ;; A zero is on the end of each pattern to clean up 
250 ;; residue left by waving.
251 pattern_a:
252   dcb 0,1,1,1,1,1,1,1,1,1,1,0
253
254 pattern_b:
255   dcb 0,1,1,0,0,1,1,0,0,1,1,0
256
257 pattern_c:
258   dcb 0,1,1,0,0,1,1,1,1,1,1,0
259
260 pattern_d:
261   dcb 0,1,1,1,1,1,1,0,0,1,1,0
262
263 pattern_e:
264   dcb 0,1,1,0,0,0,0,0,0,1,1,0
265
266 pattern_null:
267   dcb 0,0,0,0,0,0,0,0,0,0,0,0
268
269 ;; Table that store the current start position 
270 ;; of each y column.
271 y_start_pos1:
272   dcb 10,10,9,9,8,8,7,7,6,6,7,7,8,8,9,9,10,10,9,9,8,8,7,7
273   dcb 6,6,7,7,8,8
274
275 y_start_pos2:
276   dcb 9,9,8,8,8,8,8,8,7,7,8,8,8,8,8,8,9,9,8,8,8,8,8,8
277   dcb 7,7,8,8,8,8
278
279 y_start_pos3:
280   dcb 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8
281   dcb 8,8,8,8,8,8
282
283 y_start_pos4:
284   dcb 7,7,8,8,8,8,8,8,9,9,8,8,8,8,8,8,7,7,8,8,8,8,8,8
285   dcb 9,9,8,8,8,8
286
287 y_start_pos5:
288   dcb  6, 6,7,7,8,8,9,9,10,10,9,9,8,8,7,7, 6, 6,7,7,8,8,9,9
289   dcb 10,10,9,9,8,8
290
291 color_row:
292   dcb $7,$8,$9,$2,$4,$6,$e,$3,$d,$5