megaed-sv: relax sync as it often fails, unify
[megadrive.git] / megaed-sv / asmtools.s
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 */
10 read_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
19 0:
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  */
58 sync_with_teensy:
59 0:  /* 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
70 0:  /* 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
77 0:  /* 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 */
97 test_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
115 2:  /* 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
145 0:
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 */
156 test_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
171 2:  /* 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
181 0:
182     btst        d2, (a2)
183     bne.s       0b
184 0:
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 */
196 test_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
205 0:
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 */
238 run_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
265 0:
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
275 0:
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
286 sync_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
301 0:
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
316 0:
317     btst        d2, (a4)      /* 8 */
318     beq.s       0b            /* 10 */
319 0:
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
372 sync_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
384 sync_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
390 sync_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
399 run_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)
408 run_game_r_end:
409
410 hexchars:
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