megaed-sv: maybe better, sometimes working sync code
[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                                  /* 60Hz         50Hz */
329     move.l      (a0), (a1)+      /* #0xff06ff08* #0xff07ff09- */
330     move.l      (a0), (a1)+      /* #0xff00ff11* #0xff00ff11  */
331     move.l      (a0), (a1)+      /* #0xff18ff1a  #0xff18ff1a  */
332     move.l      (a0), (a1)+      /* #0xff21ff23  #0xff21ff23  */
333     move.l      (a0), (a1)+      /* #0xff2aff28  #0xff2aff28  */
334     move.l      (a0), (a1)+      /* #0xff33ff34  #0xff33ff34  */
335     move.l      (a0), (a1)+      /* #0xff3bff3d  #0xff3cff3e- */
336     move.l      (a0), (a1)+      /* #0xff45ff47* #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     move.l      (a0), (a2)+      /* #0xff4eff4f  #0xff4eff4f  */
341     move.l      (a0), (a2)+      /* #0xff56ff58  #0xff58ff59- */
342     move.l      (a0), (a2)+      /* #0xff60ff62  #0xff60ff62  */
343     move.l      (a0), (a2)+      /* #0xff69ff6b  #0xff69ff6b  */
344     move.l      (a0), (a2)+      /* #0xff72ff74  #0xff72ff74  */
345     move.l      (a0), (a2)+      /* #0xff7bff7c  #0xff7bff7c  */
346     move.l      (a0), (a2)+      /* #0xff83ff85  #0xff83ff85  */
347     move.l      (a0), (a2)+      /* #0xff8cff8e  #0xff8eff8f- */
348
349     moveq.l     #1, d5
350     sub.l       #4*8, a1
351     btst.b      #6, (0xa10001)
352     bne.s       sync_hvc_50hz
353
354     move.l      (0x00,a1), d3
355     cmp.l       #0xff06ff08, d3
356     bne.w       sync_hvc
357
358     moveq.l     #2, d5
359     move.l      (0x04,a1), d3
360     cmp.l       #0xff00ff11, d3  /* mystery value */
361     bne.w       sync_hvc
362
363     moveq.l     #3, d5
364     move.l      (0x1c,a1), d3
365     cmp.l       #0xff45ff47, d3
366     bne.w       sync_hvc
367
368     moveq.l     #4, d5
369     move.l      (-4,a2), d3
370     cmp.l       #0xff8cff8e, d3  /* RAM */
371     bne.w       sync_hvc
372
373     bra.s       0f
374
375 sync_hvc_50hz:
376     move.l      (0x00,a1), d3
377     cmp.l       #0xff07ff09, d3
378     bne.w       sync_hvc
379
380     moveq.l     #2, d5
381     move.l      (0x04,a1), d3
382     cmp.l       #0xff00ff11, d3  /* mystery value */
383     bne.w       sync_hvc
384
385     moveq.l     #3, d5
386     move.l      (0x1c,a1), d3
387     cmp.l       #0xff45ff47, d3
388     bne.w       sync_hvc
389
390     moveq.l     #4, d5
391     move.l      (-4,a2), d3
392     cmp.l       #0xff8eff8f, d3  /* RAM */
393     bne.w       sync_hvc
394
395 0:
396     movea.l     d0, a0
397     movea.l     #0xA13000, a1
398
399     move.b      d0, (0x09,a6) /* CtrlA */
400     move.b      d1, (0x03,a6)
401
402     jmp         0xffff80
403
404 run_game_r:
405     move.w      #0x3210, (0x06,a1) /* 0xA13006 */
406     move.w      d7, (0x10,a1)      /* 0xA13010 */
407     move.w      d0, (a1)           /* 0xA13000 */
408     
409     move.l      (a0)+, a7
410     move.l      (a0),  a0
411
412     jmp         (a0)
413 run_game_r_end:
414
415 hexchars:
416     dc.b        '0','1','2','3','4','5','6','7'
417     dc.b        '8','9','a','b','c','d','e','f'
418
419 # vim:filetype=asmM68k:ts=4:sw=4:expandtab