From http://www.jwz.org/xscreensaver/xscreensaver-5.39.tar.gz
[xscreensaver] / hacks / images / m6502 / lines.asm
1 ; -*- mode: c; tab-width: 4; fill-column: 128 -*-
2 ; vi: set ts=4 tw=128:
3
4 ; Lines, Copyright (c) 2018 Dave Odell <dmo2118@gmail.com>
5 ;
6 ; Permission to use, copy, modify, distribute, and sell this software and its
7 ; documentation for any purpose is hereby granted without fee, provided that
8 ; the above copyright notice appear in all copies and that both that
9 ; copyright notice and this permission notice appear in supporting
10 ; documentation.  No representations are made about the suitability of this
11 ; software for any purpose.  It is provided "as is" without express or 
12 ; implied warranty.
13
14 ; Another port of 20 year old QBasic code.
15
16
17
18 main_loop:
19         lda #$00
20         sta $0
21
22 y_loop:
23         ldx $0
24
25         lda #1
26         bit $1
27         beq left_right
28
29         ; Up-down. Skip all blank columns.
30         lda x_px0,x
31         and #1
32         bne fill
33         jmp next_y ; next_y is too far to conditional-branch from here.
34
35 clear:
36         ldx #1
37         lda $0
38         clc
39         adc #$20
40         tay
41
42         sec
43 clear_loop:
44         lda #0 ; $fe
45         sta $0200,y
46         sta $0240,y
47         sta $0280,y
48         sta $02c0,y
49         sta $0300,y
50         sta $0340,y
51         sta $0380,y
52         sta $03c0,y
53         sta $0400,y
54         sta $0440,y
55         sta $0480,y
56         sta $04c0,y
57         sta $0500,y
58         sta $0540,y
59         sta $0580,y
60         sta $05c0,y
61         tya
62         sbc #$20
63         tay
64         dex
65         bpl clear_loop
66         jmp next_y
67
68 left_right:
69         ; Repaint columns that were previously on.
70         lda x_px0,x
71         bit const_two
72         beq next_y
73         lda x_px0,x
74         and #1
75         beq clear
76         ;jmp fill
77
78 fill:
79         ldx #1
80         lda $0
81         clc
82         adc #$20
83         tay
84
85         sec
86 fill_loop:
87         ; 3 * 2 * 16 = 96 bytes
88         lda y_px0,x
89         sta $0200,y
90         lda y_px1,x
91         sta $0240,y
92         lda y_px2,x
93         sta $0280,y
94         lda y_px3,x
95         sta $02c0,y
96         lda y_px4,x
97         sta $0300,y
98         lda y_px5,x
99         sta $0340,y
100         lda y_px6,x
101         sta $0380,y
102         lda y_px7,x
103         sta $03c0,y
104         lda y_px8,x
105         sta $0400,y
106         lda y_px9,x
107         sta $0440,y
108         lda y_pxa,x
109         sta $0480,y
110         lda y_pxb,x
111         sta $04c0,y
112         lda y_pxc,x
113         sta $0500,y
114         lda y_pxd,x
115         sta $0540,y
116         lda y_pxe,x
117         sta $0580,y
118         lda y_pxf,x
119         sta $05c0,y
120         tya
121         sbc #$20
122         tay
123         dex
124         bpl fill_loop
125         ;jmp next_y
126
127 next_y:
128         inc $0
129         lda #32
130         cmp $0
131         beq shift
132         jmp y_loop
133
134 shift:
135         lda $fe
136         and #$3
137         sta $1 ; Left, down, right, up.
138         beq shift_x1
139
140         cmp #2
141         bmi shift_y1
142         beq shift_x0
143
144 shift_y0:
145         ldx #0
146 shift_y0_loop:
147         lda y_px0,x
148         eor y_px00,x
149         sta y_px0,x
150         inx
151         cpx #31
152         bne shift_y0_loop
153         jmp main_loop
154
155 shift_y1:
156         ldx #30
157 shift_y1_loop:
158         lda y_px00,x
159         eor y_px0,x
160         sta y_px00,x
161         dex
162         bpl shift_y1_loop
163         jmp main_loop
164
165 shift_x0:
166         ldx #0
167 shift_x0_loop:
168         ; px[0] = ((px[0] ^ px[1]) & 1) | (px[1] << 1)
169         lda x_px0,x
170         eor x_px00,x
171         lsr ; Save EOR bit in carry flag.
172         lda x_px00,x
173         rol ; Restore EOR bit.
174         sta x_px0,x
175         inx
176         cpx #31
177         bne shift_x0_loop
178         jmp main_loop
179
180 shift_x1:
181         ldx #30
182 shift_x1_loop:
183         lda x_px00,x
184         eor x_px0,x
185         lsr
186         lda x_px0,x
187         rol
188         sta x_px00,x
189         dex
190         bpl shift_x1_loop
191         jmp main_loop
192
193 y_px0:
194         dcb 0
195 y_px00:
196         dcb 0
197 y_px1:
198         dcb 0, 0
199 y_px2:
200         dcb 0, 0
201 y_px3:
202         dcb 0, 0
203 y_px4:
204         dcb 0, 0
205 y_px5:
206         dcb 0, 0
207 y_px6:
208         dcb 0, 0
209 y_px7:
210         dcb 0, 0
211 y_px8:
212         dcb 1, 0
213 y_px9:
214         dcb 0, 0
215 y_pxa:
216         dcb 0, 0
217 y_pxb:
218         dcb 0, 0
219 y_pxc:
220         dcb 0, 0
221 y_pxd:
222         dcb 0, 0
223 y_pxe:
224         dcb 0, 0
225 y_pxf:
226         dcb 0, 0
227
228         ; Bit 0: black row, bit 1: changed row
229 x_px0:
230         dcb 0
231 x_px00:
232         dcb    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
233         dcb 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
234
235 const_two: ; lolz
236         dcb 2
237
238 ;#include "screenhack.h"
239 ;
240 ;struct _lines
241 ;{
242 ;       unsigned width, height;
243 ;       unsigned long delay;
244 ;       GC gc;
245 ;};
246 ;
247 ;static void *lines_init(Display *display, Window window)
248 ;{
249 ;       struct _lines *self = malloc(sizeof(*self));
250 ;       XGCValues gcv;
251 ;       XWindowAttributes xgwa;
252 ;
253 ;       if(!self)
254 ;               abort();
255 ;
256 ;       XGetWindowAttributes(display, window, &xgwa);
257 ;       self->width = xgwa.width;
258 ;       self->height = xgwa.height;
259 ;
260 ;       self->delay = get_integer_resource(display, "delay", "Integer");
261 ;
262 ;       gcv.function = GXxor;
263 ;       gcv.foreground = get_pixel_resource(display, xgwa.colormap, "foreground", "Foreground");
264 ;       self->gc = XCreateGC(display, window, GCFunction | GCForeground, &gcv);
265 ;
266 ;       XDrawPoint(display, window, self->gc, xgwa.width >> 1, xgwa.height >> 1);
267 ;
268 ;       return self;
269 ;}
270 ;
271 ;static unsigned long lines_draw(Display *display, Window window, void *self_raw)
272 ;{
273 ;       struct _lines *self = self_raw;
274 ;       static const XPoint xy[] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
275 ;       const XPoint *p = xy + NRAND(4);
276 ;
277 ;       XCopyArea(display, window, window, self->gc, 0, 0, self->width, self->height, p->x, p->y);
278 ;       return self->delay;
279 ;}
280 ;
281 ;static void lines_reshape(Display *display, Window window, void *self_raw, unsigned width, unsigned height)
282 ;{
283 ;       struct _lines *self = self_raw;
284 ;       self->width = width;
285 ;       self->height = height;
286 ;}
287 ;
288 ;static Bool lines_event(Display *display, Window window, void *self_raw, XEvent *event)
289 ;{
290 ;       return False;
291 ;}
292 ;
293 ;static void lines_free(Display *display, Window window, void *self_raw)
294 ;{
295 ;       struct _lines *self = self_raw;
296 ;       XFreeGC(display, self->gc);
297 ;       free(self);
298 ;}
299 ;
300 ;static const char *lines_defaults[] =
301 ;{
302 ;       "*fpsSolid:         true",
303 ;       "*delay:            30000",
304 ;       0
305 ;};
306 ;
307 ;static XrmOptionDescRec lines_options [] =
308 ;{
309 ;       {"-delay", ".delay",   XrmoptionSepArg, 0},
310 ;       {0, 0, 0, 0}
311 ;};
312 ;
313 ;XSCREENSAVER_MODULE ("Lines", lines)