megaed-sv: allow to input raw mapper code
[megadrive.git] / megaed-sv / asmtools.s
... / ...
CommitLineData
1# Assemble with gas
2# --register-prefix-optional --bitwise-or
3
4.macro ldarg arg, stacksz, reg
5 move.l (4 + \arg * 4 + \stacksz)(%sp), \reg
6.endm
7
8
9.global read_joy_responses /* u8 *rbuf */
10read_joy_responses:
11 ldarg 0, 0, a1
12 movem.l d2-d7, -(sp)
13 movea.l #0xa10003, a0
14 move.b #0x40, (6,a0)
15 move.b #0x40, (a0)
16
17.macro one_test val
18 move.l #100/12-1, d0
190:
20 dbra d0, 0b
21 move.b \val, d0
22 move.b d0, (a0)
23 move.b (a0), d0
24 move.b (a0), d1
25 move.b (a0), d2
26 move.b (a0), d3
27 move.b (a0), d4
28 move.b (a0), d5
29 move.b (a0), d6
30 move.b (a0), d7
31 move.b d0, (a1)+
32 move.b d1, (a1)+
33 move.b d2, (a1)+
34 move.b d3, (a1)+
35 move.b d4, (a1)+
36 move.b d5, (a1)+
37 move.b d6, (a1)+
38 move.b d7, (a1)+
39.endm
40
41 move.w #0x2700, sr
42 one_test #0x00
43 one_test #0x40
44 one_test #0x00
45 one_test #0x40
46 one_test #0x00
47 move.w #0x2000, sr
48 movem.l (sp)+, d2-d7
49 rts
50
51
52/* expects:
53 * a0 = #0xa10003
54 * d0 = #0
55 * d1 = #0x40
56 * trashes d2, d3
57 */
58sync_with_teensy:
590: /* wait for special code */
60 move.b d1, (a0)
61 move.b (a0), d2
62 move.b d0, (a0)
63 move.b (a0), d3
64 and.b #0x3f, d2
65 cmp.b d2, d3
66 bne 0b
67 cmp.b #0x25, d2
68 bne 0b
69
700: /* wait for special code to end */
71 cmp.b (a0), d2
72 beq 0b
73
74 move.b d1, (a0)
75 move.l #8000000/50/18, d2
76
770: /* wait enough for teensy to setup it's stuff */
78 subq.l #1, d2 /* 8 */
79 bgt.s 0b /* 10 */
80
81 rts
82
83
84.macro t_nop
85 /*
86 * when communicating with 3.3V teensy:
87 * - no nops: see old value on multiple pins randomly
88 * - 1 nop: only TR often shows old value
89 * - 2 nops: ?
90 */
91 nop
92 nop
93.endm
94
95
96.global test_joy_read_log /* u8 *dest, int size, int do_sync */
97test_joy_read_log:
98 ldarg 0, 0, a1
99 ldarg 1, 0, d0
100 ldarg 2, 0, d1
101 movem.l d2-d7, -(sp)
102 movea.l #0xa10003, a0
103 move.l d0, d7
104 move.l d1, d6
105
106 moveq.l #0, d0
107 move.l #0x40, d1
108 move.b d1, (6,a0)
109 move.b d1, (a0)
110
111 tst.l d6
112 beq.s 2f
113 bsr sync_with_teensy
114
1152: /* save data */
116 move.b d0, (a0)
117 t_nop
118 move.b (a0), d2
119 move.b d1, (a0)
120 t_nop
121 move.b (a0), d3
122 move.b d0, (a0)
123 t_nop
124 move.b (a0), d4
125 move.b d1, (a0)
126 t_nop
127 move.b (a0), d5
128.if 0
129 /* broken on Mega-ED v9?? */
130 move.b d2, (a1)+
131 move.b d3, (a1)+
132 move.b d4, (a1)+
133 move.b d5, (a1)+
134.else
135 lsl.w #8, d2
136 move.b d3, d2
137 move.w d2, (a1)+
138 lsl.w #8, d4
139 move.b d5, d4
140 move.w d4, (a1)+
141.endif
142
143 /* delay for teensy, 128 not enough.. */
144 move.l #256, d2
1450:
146 dbra d2, 0b
147
148 subq.l #4, d7
149 bgt.s 2b
150
151 movem.l (sp)+, d2-d7
152 rts
153
154
155.global test_joy_read_log_vsync /* u8 *dest, int size */
156test_joy_read_log_vsync:
157 ldarg 0, 0, a1
158 ldarg 1, 0, d0
159 movem.l d2-d7/a2, -(sp)
160 movea.l #0xa10003, a0
161 movea.l #0xc00005, a2
162 move.l d0, d7
163
164 move.l #0x40, d1
165 moveq.l #0, d0
166 move.b d1, (6,a0)
167 move.b d1, (a0)
168
169 bsr sync_with_teensy
170
1712: /* save data */
172 move.b d0, (a0)
173 move.b (a0), d2
174 move.b d1, (a0)
175 move.b (a0), d3
176 move.b d2, (a1)+
177 move.b d3, (a1)+
178
179 /* wait for next vsync */
180 moveq.l #3, d2
1810:
182 btst d2, (a2)
183 bne.s 0b
1840:
185 btst d2, (a2)
186 beq.s 0b
187
188 subq.l #2, d7
189 bgt.s 2b
190
191 movem.l (sp)+, d2-d7/a2
192 rts
193
194
195.global test_byte_write /* u8 *dest, int size, int seed */
196test_byte_write:
197 ldarg 0, 0, a0
198 ldarg 1, 0, d0
199 ldarg 2, 0, d1
200 movem.l d2-d7, -(sp)
201
202 move.l a0, a1
203 add.l d0, a1
204 move.l d1, d7
2050:
206 move.b d7, d0
207 addq.b #1, d7
208 move.b d7, d1
209 addq.b #1, d7
210 move.b d7, d2
211 addq.b #1, d7
212 move.b d7, d3
213 addq.b #1, d7
214 move.b d7, d4
215 addq.b #1, d7
216 move.b d7, d5
217 addq.b #1, d7
218 move.b d7, d6
219 addq.b #1, d7
220
221 move.b d0, (a0)+
222 move.b d1, (a0)+
223 move.b d2, (a0)+
224 move.b d3, (a0)+
225 move.b d4, (a0)+
226 move.b d5, (a0)+
227 move.b d6, (a0)+
228 move.b d7, (a0)+
229 addq.b #1, d7
230 cmp.l a1, a0
231 blt.s 0b
232
233 movem.l (sp)+, d2-d7
234 rts
235
236
237.global run_game /* u16 mapper, int tas_sync */
238run_game:
239 move.w #0x2700, sr
240 ldarg 0, 0, d7
241 ldarg 1, 0, d6
242 movea.l #0xa10000, a6
243 movea.l #0xc00000, a5
244 movea.l #0xc00005, a4
245 movea.l #0xc00004, a3
246 moveq.l #0x00, d0
247 move.b #0x40, d1 /* d2 is tmp */
248 move.b #0xff, d3 /* d4 is temp */
249 moveq.l #0x00, d5 /* progress cnt */
250 movea.l d0, a7
251 move.b d1, (0x09,a6) /* CtrlA */
252 move.b d0, (0x0b,a6) /* CtrlB */
253 move.b d0, (0x0d,a6) /* CtrlC */
254 move.b d0, (0x13,a6) /* S-CtrlA */
255 move.b d3, (0x0f,a6) /* TxDataA */
256 move.b d0, (0x19,a6) /* S-CtrlB */
257 move.b d3, (0x15,a6) /* TxDataB */
258 move.b d0, (0x1f,a6) /* S-CtrlC */
259 move.b d3, (0x1b,a6) /* TxDataC */
260
261 move.w #0xcbaf, (0xA13006) /* some scratch area */
262
263 move.l #0xff0000, a1
264 move.l #0x10000/4/4-1, d2
2650:
266 move.l d0, (a1)+
267 move.l d0, (a1)+
268 move.l d0, (a1)+
269 move.l d0, (a1)+
270 dbra d2, 0b
271
272 lea (run_game_r,pc), a0
273 move.l #0xffff80, a1
274 move.l #(run_game_r_end - run_game_r)/2-1, d2
2750:
276 move.w (a0)+, (a1)+
277 dbra d2, 0b
278
279 tst.l d6
280 beq.s sync_hvc
281
282 movea.l #0xa10003, a0
283 bsr sync_with_teensy /* trashes d3 */
284 move.l d0, (-4,a7)
285
286sync_hvc:
287 addq.l #1, d6 /* attempt counter */
288
289 /* set up for progress vram write (x,y - tile #) */
290 /* GFX_WRITE_VRAM_ADDR(0xc000 + (x + 64 * y) * 2) */
291 /* d = d5 + '0' - 32 + 0xB000/32 - 128 = d5 + 0x510 */
292 move.l #(0x40000003 | ((36 + 64*1) << 17)), (a3)
293 add.w #0x510, d5
294 move.w d5, (a5)
295 move.w #('/'+0x4e0), (a5)
296 move.w #('4'+0x4e0), (a5)
297
298 lea hexchars, a1
299 move.l #(0x40000003 | ((31 + 64*2) << 17)), (a3)
300 moveq.l #8-1, d5
3010:
302 rol.l #4, d3
303 move.b d3, d4
304 and.l #0x0f, d4
305 move.b (d4,a1), d4
306 add.w #0x4e0, d4
307 move.w d4, (a5)
308 dbra d5, 0b
309
310 movea.l #0xc00008, a0
311 movea.l #0x3ff000, a1
312 movea.l #0xffffe0, a2
313
314 /* wait for active display */
315 moveq.l #3, d2
3160:
317 btst d2, (a4) /* 8 */
318 beq.s 0b /* 10 */
3190:
320 btst d2, (a4)
321 bne.s 0b
322
323 /* flood the VDP FIFO */
324.rept 5
325 move.w d0, (a5)
326.endr
327
328 /* these seem stable for both 50Hz/60Hz */
329 move.l (a0), (a1)+ /* #0xff07ff09 */
330 move.l (a0), (a1)+ /* #0xff00ff11 */
331 move.l (a0), (a1)+ /* #0xff18ff1a */
332 move.l (a0), (a1)+ /* #0xff21ff23 */
333 move.l (a0), (a1)+ /* #0xff2aff28 */
334 move.l (a0), (a1)+ /* #0xff33ff34 */
335 move.l (a0), (a1)+ /* #0xff3cff3e */
336 move.l (a0), (a1)+ /* #0xff45ff47 */
337
338 /* as long as exactly 8 or more RAM writes are performed here, */
339 /* after multiple tries RAM refresh somehow eventually syncs */
340 /* after cold boot, only 50Hz syncs to always same values though, */
341 /* so values below are 50Hz */
342 move.l (a0), (a2)+ /* #0xff4eff4f */
343 move.l (a0), (a2)+ /* #0xff58ff59 */
344 move.l (a0), (a2)+ /* #0xff60ff62 */
345 move.l (a0), (a2)+ /* #0xff69ff6b */
346 move.l (a0), (a2)+ /* #0xff72ff74 */
347 move.l (a0), (a2)+ /* #0xff7bff7c */
348 move.l (a0), (a2)+ /* #0xff83ff85 */
349 move.l (a0), (a2)+ /* #0xff8eff8f */
350
351 sub.l #4*8, a1
352 sub.l #4*8, a2
353
354 moveq.l #1, d5
355 move.l (0x00,a1), d3
356 cmp.l #0xff07ff09, d3
357 bne.w sync_hvc
358
359 moveq.l #2, d5
360 move.l (0x04,a1), d3
361 cmp.l #0xff00ff11, d3 /* mystery value */
362 bne.w sync_hvc
363
364 moveq.l #3, d5
365 move.l (0x1c,a1), d3
366 cmp.l #0xff45ff47, d3
367 bne.w sync_hvc
368
369 btst.b #6, (0xa10001)
370 bne.s sync_hvc_50hz
371
372sync_hvc_60hz:
373 /* unable to get stable RAM between cold boots :( */
374 moveq.l #4, d5
375 move.l (0x1c,a2), d3
376 cmp.l #0xff8dff8f, d3 /* unstable */
377 beq.s sync_hvc_end
378 cmp.l #0xff8cff8e, d3 /* stable? */
379 beq.s sync_hvc_end
380 cmp.l #0xff8eff90, d3
381 beq.s sync_hvc_end
382 bra.w sync_hvc
383
384sync_hvc_50hz:
385 moveq.l #4, d5
386 move.l (0x1c,a2), d3
387 cmp.l #0xff8eff8f, d3 /* RAM */
388 bne.w sync_hvc
389
390sync_hvc_end:
391 movea.l d0, a0
392 movea.l #0xA13000, a1
393
394 move.b d0, (0x09,a6) /* CtrlA */
395 move.b d1, (0x03,a6)
396
397 jmp 0xffff80
398
399run_game_r:
400 move.w #0x3210, (0x06,a1) /* 0xA13006 */
401 move.w d7, (0x10,a1) /* 0xA13010 */
402 move.w d0, (a1) /* 0xA13000 */
403
404 move.l (a0)+, a7
405 move.l (a0), a0
406
407 jmp (a0)
408run_game_r_end:
409
410hexchars:
411 dc.b '0','1','2','3','4','5','6','7'
412 dc.b '8','9','a','b','c','d','e','f'
413
414# vim:filetype=asmM68k:ts=4:sw=4:expandtab