Source code for MindBender, a small program that generates some visual illusion, presented at Sommarhack 2020's 256 bytes demo competition.
Includes the source code (HiSoft Devpac format), TOS executable and screenshot.
@@ -0,0 +1,312 @@ | ||
1 | +; | |
2 | +; Dbug's 256 bytes intro for Sommarhack 2020 | |
3 | +; 2020, 28th of May | |
4 | +; | |
5 | +; Inspired by Patapom Facebook post with this brainteaser picture | |
6 | +; | |
7 | +; https://www.facebook.com/Patapom/posts/10158451888604846 | |
8 | +; | |
9 | +; Size evolution over time: | |
10 | +; -- 2020-05-28: | |
11 | +; 1207 bytes - first working version of the effect with the visible distortion | |
12 | +; 1051 bytes - removed setup and debug infos | |
13 | +; 930 bytes - can't quit anymore, no restore, no keypress | |
14 | +; 482 bytes - not sure what I changed... | |
15 | +; 478 bytes - replaced supexec by super | |
16 | +; 463 bytes - not clearing IMRA and IMRB anymore | |
17 | +; 331 bytes - Replaced the nops by a dbra | |
18 | +; 325 bytes - Removed one useless color change | |
19 | +; 296 bytes - Replaced the color mapping table by a rotated bitfield | |
20 | +; | |
21 | +; -- 2020-05-29: | |
22 | +; 284 bytes - Replaced the blocks 2 and 5 nops by single instructions taking the same time | |
23 | +; 282 bytes - Replaced a move.b #0 by a sf | |
24 | +; 265 bytes - Changed the generation of the bitmap pattern | |
25 | +; 260 bytes - Replaced a few move.w #0, by clr.w | |
26 | +; 258 bytes - Accessed $ff8240 through an address register | |
27 | +; 256 bytes - Played with the initial temporisation code | |
28 | +; | |
29 | +; -- 2020-05-30: | |
30 | +; 244 bytes - Used the default screen instead of setting up mine | |
31 | +; 240 bytes - Changed the pattern generation to use bitplans offsets | |
32 | +; 238 bytes - Optimize the color setting for the bitmaps | |
33 | +; 254 bytes - Added a text and some fancy colors on the top | |
34 | +; 252 bytes - Reduced a constant value from .l to .w | |
35 | +; 250 bytes - Removed a sf $ffff8209.w which I did not need anymore | |
36 | +; 240 bytes - Reorganized the post video sync delay loop | |
37 | +; | |
38 | + | |
39 | + | |
40 | +enable_proper_setup equ 0 ; Enables the tabbed out code | |
41 | + | |
42 | + opt o+,w+ | |
43 | + | |
44 | + | |
45 | + | |
46 | +;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
47 | +;% Macro qui fait une attente soit avec une succession de NOPs % | |
48 | +;% (FAST=1), soit en optimisant avec des instructions neutres % | |
49 | +;% prenant plus de temps machine avec la mˆme taille % | |
50 | +;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | |
51 | + | |
52 | +pause macro | |
53 | +t6 set (\1)/6 | |
54 | +t5 set (\1-t6*6)/5 | |
55 | +t4 set (\1-t6*6-t5*5)/4 | |
56 | +t3 set (\1-t6*6-t5*5-t4*4)/3 | |
57 | +t2 set (\1-t6*6-t5*5-t4*4-t3*3)/2 | |
58 | +t1 set (\1-t6*6-t5*5-t4*4-t3*3-t2*2) | |
59 | + dcb.w t6,$e188 ; lsl.l #8,d0 6 | |
60 | + dcb.w t5,$ed88 ; lsl.l #6,d0 5 | |
61 | + dcb.w t4,$e988 ; lsl.l #4,d0 4 | |
62 | + dcb.w t3,$1090 ; move.b (a0),(a0) 3 | |
63 | + dcb.w t2,$8080 ; or.l d0,d0 2 | |
64 | + dcb.w t1,$4e71 ; nop 1 | |
65 | + endm | |
66 | + | |
67 | + SECTION TEXT | |
68 | + | |
69 | +; ------------------ | |
70 | +; Program start | |
71 | +; ------------------ | |
72 | +ProgStart | |
73 | + ifne enable_proper_setup | |
74 | + | |
75 | + ; We call the main routine in supervisor mode | |
76 | + ; and when we come back, we return to the caller | |
77 | + move.l #super_main,-(sp) | |
78 | + move.w #$26,-(sp) ; XBIOS: SUPEXEC | |
79 | + trap #14 | |
80 | + addq.w #6,sp | |
81 | + | |
82 | + clr.w -(sp) ; GEMDOS: PTERM(0) | |
83 | + trap #1 | |
84 | + | |
85 | + else | |
86 | + | |
87 | + ; We switch to supervisor, but never come back | |
88 | + ; so no need to correct the stack pointer | |
89 | + clr.l -(sp) | |
90 | + move.w #$20,-(sp) ; GEMDOS: SUPER | |
91 | + trap #1 | |
92 | + | |
93 | + endc | |
94 | + | |
95 | +super_main | |
96 | + lea $ffff8240.w,a6 | |
97 | + move.l #$07770727,$ffff8242.w ; The White and Purple crosses [Could be 2(a6) but same size] | |
98 | + | |
99 | + ifne enable_proper_setup | |
100 | + ; | |
101 | + ; Save context | |
102 | + ; | |
103 | + move.b $fffffa07.w,save_iera | |
104 | + move.b $fffffa09.w,save_ierb | |
105 | + move.b $ffff8260.w,save_resol | |
106 | + | |
107 | + clr.w -(sp) | |
108 | + pea -1.w | |
109 | + pea -1.w | |
110 | + move.w #5,-(sp) | |
111 | + trap #14 | |
112 | + lea 12(sp),sp | |
113 | + endc | |
114 | + | |
115 | + ; | |
116 | + ; Print the Dbug title | |
117 | + ; | |
118 | + pea Message(pc) | |
119 | + move.w #9,-(sp) | |
120 | + trap #1 | |
121 | + ifne enable_proper_setup | |
122 | + addq.l #6,sp | |
123 | + endc | |
124 | + | |
125 | + ; | |
126 | + ; Draw the cross patterns | |
127 | + ; | |
128 | + move.l $44e.w,a0 ; screenpt | |
129 | + lea 160*5(a0),a0 | |
130 | + | |
131 | + move.w #%0110100101101001,d3 | |
132 | + | |
133 | + moveq #7-1,d1 | |
134 | +loop_y | |
135 | + move.l a0,a1 | |
136 | + | |
137 | + move.l d3,d4 | |
138 | + lsr.l #1,d3 | |
139 | + | |
140 | + moveq #10-1,d0 | |
141 | +loop_x | |
142 | + ;moveq #0,d2 | |
143 | + ;addx d2,d2 | |
144 | + ;add d2,d2 | |
145 | + move.w d4,d2 | |
146 | + lsr.l #1,d4 | |
147 | + and #2,d2 | |
148 | + | |
149 | + lea 0(a1,d2.w),a2 | |
150 | + | |
151 | + lea Patterns(pc),a3 | |
152 | + moveq #10-1,d5 | |
153 | +loop_pattern | |
154 | + move.w (a3)+,(a2) | |
155 | + lea 160(a2),a2 | |
156 | + dbra d5,loop_pattern | |
157 | + | |
158 | + lea 16(a1),a1 | |
159 | + | |
160 | + dbra d0,loop_x | |
161 | + lea 160*30(a0),a0 | |
162 | + dbra d1,loop_y | |
163 | + | |
164 | + ; | |
165 | + ; VSync and disable interrupts | |
166 | + ; | |
167 | + move.w #37,-(sp) ; VSYNC | |
168 | + trap #14 | |
169 | + ifne enable_proper_setup | |
170 | + addq.l #2,sp | |
171 | + endc | |
172 | + | |
173 | + ; | |
174 | + ; Main loop | |
175 | + ; | |
176 | + move.w #$2700,sr | |
177 | +loop | |
178 | + move.w #$345,(a6) ; Light blue-gray background | |
179 | + | |
180 | + ; We do the key check before the synchronisation to avoid wobbly rasters | |
181 | + ifne enable_proper_setup | |
182 | + cmp.b #$39,$fffffc02.w | |
183 | + beq.s exit | |
184 | + endc | |
185 | + | |
186 | + move.w #$370,d6 ; Color of first tile | |
187 | + move.w #$263,d7 ; Color of second tile | |
188 | + move.w #$fff,8(a6) | |
189 | + | |
190 | + | |
191 | + ; Line zero synchronisation | |
192 | + moveq #14,d2 | |
193 | +.wait_sync | |
194 | + move.b $ffff8209.w,d0 | |
195 | + beq.s .wait_sync | |
196 | + sub.b d0,d2 | |
197 | + lsl.b d2,d0 | |
198 | + | |
199 | + ; 366*3=1098 | |
200 | + ; 274*4=1098 | |
201 | + | |
202 | + ; To leave room for the "Dbug" line | |
203 | + ; 64 nops*8 = | |
204 | + ;move.w #138-1,d0 | |
205 | + move.w #157-1,d0 | |
206 | +delay | |
207 | + subq.w #1,8(a6) | |
208 | + dbra d0,delay ; 3 | |
209 | + | |
210 | + ; The alternated color grid | |
211 | + moveq #10-1,d1 | |
212 | +loop_lines | |
213 | + | |
214 | + ; 247 | |
215 | + move.w #242-1,d0 | |
216 | +loop_squares | |
217 | + move.w d6,(a6) ; 8/2 background color change | |
218 | + | |
219 | + lsl.l #8,d3 ; 24/6 (DELAY) | |
220 | + | |
221 | + move.w d7,(a6) ; 8/2 background color change | |
222 | + | |
223 | + move.w (a6),(a6) ;pause 3 ; (DELAY) | |
224 | + | |
225 | + dbra d0,loop_squares ; 12/3 if branches / 16/4 if not taken | |
226 | + | |
227 | + ;pause 2 ; (DELAY) | |
228 | + addq #1,d6 | |
229 | + ;addq #1,d7 | |
230 | + nop | |
231 | + | |
232 | + dbra d1,loop_lines | |
233 | + bra.s loop | |
234 | +exit | |
235 | + | |
236 | + ; | |
237 | + ; Restore system | |
238 | + ; | |
239 | + ifne enable_proper_setup | |
240 | + move.w #$2700,sr | |
241 | + | |
242 | + moveq #0,d0 | |
243 | + move.b save_resol,d0 | |
244 | + move.w d0,-(sp) | |
245 | + pea -1.w | |
246 | + pea -1.w | |
247 | + move.w #5,-(sp) | |
248 | + trap #14 | |
249 | + lea 12(sp),sp | |
250 | + | |
251 | + move.b save_iera,$fffffa07.w | |
252 | + move.b save_ierb,$fffffa09.w | |
253 | + move.b save_resol,$ffff8260.w | |
254 | + | |
255 | + move.w #$700,$ffff8242.w | |
256 | + move.w #$000,$ffff8244.w | |
257 | + move.w #$000,$ffff8246.w | |
258 | + | |
259 | + move.w #$777,$ffff8240.w | |
260 | + | |
261 | + move.w #$2300,sr | |
262 | + rts | |
263 | + endc | |
264 | + | |
265 | + | |
266 | +Patterns | |
267 | + dc.w %0000000001100000 | |
268 | + dc.w %0000000001100000 | |
269 | + dc.w %0000000011110000 | |
270 | + dc.w %0000001111111100 | |
271 | + dc.w %0000111111111111 | |
272 | + dc.w %0000111111111111 | |
273 | + dc.w %0000001111111100 | |
274 | + dc.w %0000000011110000 | |
275 | + dc.w %0000000001100000 | |
276 | + dc.w %0000000001100000 | |
277 | + | |
278 | +Message | |
279 | + dc.b 27,"b",4 ; Set 1 as Ink color | |
280 | + dc.b 27,"E" ; Erase Screen | |
281 | + ;dc.b "Dbug's ",174,"OverBender",175," at Sommarhack",191," 2020 " | |
282 | + ;dc.b "Dbug's ",174,"OverBender",175 | |
283 | + ;dc.b "Dbug's ",240,240,27,"p"," MindBender ",27,"q",240,240 | |
284 | + ;dc.b "Dbug ",27,"p",242,"MindBender",243,27,"q" | |
285 | + ;dc.b "Dbug ",27,"p",248,"MindBender",248,27,"q" | |
286 | + ;dc.b "Dbug ",247,32,"MindBender",191 | |
287 | + dc.b "Dbug @ Sommarhack 2020" | |
288 | + dc.b 0 | |
289 | + | |
290 | + ifne enable_proper_setup | |
291 | + SECTION BSS | |
292 | + | |
293 | +save_iera ds.b 1 ; Interrupt enable register A | |
294 | +save_ierb ds.b 1 ; Interrupt enable register B | |
295 | +save_resol ds.b 1 ; Screen resolution | |
296 | + endc | |
297 | + | |
298 | + end | |
299 | + | |
300 | +<_Dbug_> I don't remember the PRG format, is it normal there are 4 bytes at zero at the end ? | |
301 | +<ggn> yes | |
302 | +<ggn> relocation table | |
303 | +<_Dbug_> So I guess that means I successfully manage to be all pcrelative? | |
304 | +<ggn> ABSFLAG | |
305 | +<ggn> 0x1A | |
306 | +<ggn> This WORD flag should be non-zero to indicate that the program has no fixups or 0 to indicate it does.Since some versions of TOS handle files with this value being non-zero incorrectly, it is better to represent a program having no fixups with 0 here and placing a 0 longword as the fixup offset. | |
307 | +<ggn> so in in theory you can remove that 0.l and fix ABSFLAG to non-zero | |
308 | +<ggn> in practice however.... go and read the pack-fire page on pouet | |
309 | +<_Dbug_> I'll keep that in mind for if I need these 4 more bytes | |
310 | +<ggn> yeah also if you want your thing to crash on startup randomly | |
311 | +<_Dbug_> Ha, yeah no, that stinks :p | |
312 | + |