megaed-sv: input latency test
[megadrive.git] / hexed / transfer.S
CommitLineData
8689c962 1###############################################################################
2#
3# Copyright (c) 2011, GraÅžvydas Ignotas
4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions are met:
8# * Redistributions of source code must retain the above copyright
9# notice, this list of conditions and the following disclaimer.
10# * Redistributions in binary form must reproduce the above copyright
11# notice, this list of conditions and the following disclaimer in the
12# documentation and/or other materials provided with the distribution.
13# * Neither the name of the organization nor the
14# names of its contributors may be used to endorse or promote products
15# derived from this software without specific prior written permission.
16#
f28eaaad 17# THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND ANY
8689c962 18# EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
f28eaaad 20# DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
8689c962 21# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
23# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
24# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
26# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27#
28# Assemble with gas
29# --register-prefix-optional --bitwise-or
30#
31
32#include "transfer.h"
33
34.text
35.globl do_transfer
36
37
38# receive 1 byte to d0
39# in: a1 - data port
40# trash: d1
41.macro recv_one_byte is_last=0
42 move.b #0,(a1) /* clear TH */
43
440: /*L_wait_tl_low*/
45 move.b (a1),d1
46 btst.b #4,d1
47 bne 0b /*L_wait_tl_low*/
48
49 move.b #0x40,(a1) /* set TH */
50 and.b #0x0f,d1
51
520: /*L_wait_tl_hi*/
53 move.b (a1),d0
54 btst.b #4,d0
55 beq 0b /*L_wait_tl_hi*/
56
57.if !\is_last
58 move.b #0,(a1) /* clear TH - ready for next */
59.endif
60 lsl.b #4,d0
61 or.b d1,d0
62.endm
63
64# send 1 byte in d0
65# in: a1 - data port
66# trash: d1,d2
67.macro send_one_byte
68 move.b d0,d2
69 and.b #0x0f,d2
70
710: /*Lwait_tl_low:*/
72 move.b (a1),d1
73 btst.b #4,d1
74 bne 0b /*Lwait_tl_low*/
75
76 move.b d2,(a1) /* clears TH and writes data */
77
78 move.b d0,d2
79 lsr.b #4,d2
80 bset.b #6,d2 /* prepare TH */
81
820: /*wait_tl_hi*/
83 move.b (a1),d1
84 btst.b #4,d1
85 beq 0b /*wait_tl_hi1*/
86
87 move.b d2,(a1)
88.endm
89
90recv_byte:
272bd2ec 91 moveq.l #0,d0
8689c962 92 recv_one_byte 1
93 rts
94
4e6ba16d 95# receive 1 16bit word to d0
96# in: a1 - data port
97# trash: d1,d2
98recv_word:
99 recv_one_byte
100 move.b d0,d2
101 recv_one_byte
102 lsl.w #8,d2
103 move.b d0,d2
104 move.w d2,d0
105 rts
106
8689c962 107# receive address/size to d0 (3 bytes BE)
108# in: a1 - data port
109# trash: d1,d2
110recv_ad:
111 moveq.l #0,d2
112 bsr recv_byte
113 move.b d0,d2
114 bsr recv_byte
115 lsl.l #8,d2
116 move.b d0,d2
117 bsr recv_byte
118 lsl.l #8,d2
119 move.b d0,d2
120 move.l d2,d0
121 rts
122
f0e06736 123# send 1 byte in d0
124# in: a1 - data port
125# trash: d1,d2
93c5aa8a 126send_byte:
127 send_one_byte
128 rts
129
f0e06736 130.macro switch_to_output
1310: /*Lwait_tl_low: PC should switch to rx mode before lowering tl */
132 move.b (a1),d0
133 btst.b #4,d0
134 bne 0b /*Lwait_tl_low*/
135
136 move.b #0x4f,(0xa1000b).l
137 move.b #0x40,(a1)
138.endm
139
4e6ba16d 140.equ sat_maxsize, (80*8+0x200) /* sprites+max_align */
141
142# make sure cache is invalidated
143# note: VRAM copy doesn't seem to help here
144# note2: cache is updated as data is written
145# in: d0 - vdp reg5, a0 = 0xc00000
146# trash: d1,d2,a2
147invalidate_sprite_cache:
148 move.w #0x8f02,4(a0) /* auto increment 2 */
149 lsl.b #1,d0 /* upper byte of sat address */
150 move.b d0,d1
151 lsr.b #6,d1 /* 15:14 dst addr */
152 and.b #0x3f,d0 /* assemble cmd */
153 lsl.w #8,d0
154 swap d0
155 move.b d1,d0
156 move.l d0,4(a0)
157
158 move.l #0xffe000,a2
159 move.l #sat_maxsize/2-1,d2
1600:
161 move.w (a0),(a2)+
162 dbra d2,0b
163
164 bset #30,d0 /* VRAM write */
165 move.l d0,4(a0)
166
167 move.l #0xffe000,a2
168 move.l #sat_maxsize/2-1,d2
1690:
170 move.w (a2)+,(a0)
171 dbra d2,0b
172 rts
173
174
8689c962 175
176do_transfer:
177 lea 0xa10005,a1
178 move.b #0x40,(0xa1000b).l /* ctrl - all inputs except TH */
179 move.b #0x00,(a1)
180
181 bsr recv_byte
182 cmp.b #CMD_PREFIX,d0
183 bne return
184
185 bsr recv_byte
272bd2ec 186 cmp.b #CMD_FIRST,d0
187 bcs return
188 cmp.b #CMD_LAST+1,d0
189 bcc return
190 sub.b #CMD_FIRST,d0
191
192 lsl.w #2,d0
193 lea (jumptab,pc,d0),a0
194 jmp (a0)
195jumptab:
196 bra pcc_transfer_recv /* sent to us */
197 bra pcc_transfer_send /* recv from us */
198 bra pcc_jump
93c5aa8a 199 bra pcc_io
4e6ba16d 200 bra pcc_loadstate
f0e06736 201 bra pcc_vram_send
272bd2ec 202 bra pcc_test_code
203
204
93c5aa8a 205/* receive data from PC */
272bd2ec 206pcc_transfer_recv:
8689c962 207 bsr recv_ad
208 move.l d0,a0
209 bsr recv_ad
210 move.l d0,d3
211
212tr_recv_loop:
213 recv_one_byte
214 move.b d0,(a0)+
215 subq.l #1,d3
272bd2ec 216 bgt tr_recv_loop
8689c962 217 bra return
218
272bd2ec 219
93c5aa8a 220/* send data to PC */
272bd2ec 221pcc_transfer_send:
8689c962 222 bsr recv_ad
223 move.l d0,a0
224 bsr recv_ad
225 move.l d0,d3
226
f0e06736 227 switch_to_output
8689c962 228
229tr_send_loop:
230 move.b (a0)+,d0
231 send_one_byte
232 subq.l #1,d3
272bd2ec 233 bgt tr_send_loop
234 bra return
235
236
93c5aa8a 237/* call specified location */
272bd2ec 238pcc_jump:
239 bsr recv_ad
240 move.l d0,a0
93c5aa8a 241 jsr (a0)
242 bra return
243
244
245/* do simple i/o commands */
246pcc_io:
247 moveq.l #0,d4
248 bsr recv_byte
249 move.b d0,d4
250 bsr recv_byte
251 lsl.l #8,d4
252 move.b d0,d4
272bd2ec 253
93c5aa8a 254pcc_io_loop:
255 move.b #0x40,(0xa1000b).l /* input mode */
272bd2ec 256
93c5aa8a 257 sub.w #1,d4
258 bmi return
259
260 bsr recv_byte
261 move.b d0,d3 /* cmd */
262
263 bsr recv_ad
264 move.l d0,a2 /* addr */
265
266 cmp.b #IOSEQ_W32, d3
267 beq pcc_io_w32
268 cmp.b #IOSEQ_W16, d3
269 beq pcc_io_w16
270 cmp.b #IOSEQ_W8, d3
271 bne pcc_io_rx
272
273pcc_io_w8:
274 bsr recv_byte
275 move.b d0,(a2)
276 bra pcc_io_loop
277
278pcc_io_w16:
279 bsr recv_byte
280 move.b d0,d3
281 bsr recv_byte
282 lsl.w #8,d3
283 move.b d0,d3
284 move.w d3,(a2)
285 bra pcc_io_loop
286
287pcc_io_w32:
288 bsr recv_byte
289 move.b d0,d3
290 bsr recv_byte
291 lsl.w #8,d3
292 move.b d0,d3
293 bsr recv_byte
294 lsl.l #8,d3
295 move.b d0,d3
296 bsr recv_byte
297 lsl.l #8,d3
298 move.b d0,d3
299 move.l d3,(a2)
300 bra pcc_io_loop
301
302pcc_io_rx:
f0e06736 303 switch_to_output
93c5aa8a 304
305 cmp.b #IOSEQ_R32, d3
306 beq pcc_io_r32
307 cmp.b #IOSEQ_R16, d3
308 beq pcc_io_r16
309 cmp.b #IOSEQ_R8, d3
310 bne return
311
312pcc_io_r8:
313 move.b (a2),d0
314 bsr send_byte
315 bra pcc_io_loop
316
317pcc_io_r16:
318 move.w (a2),d3
319 move.w d3,d0
320 lsr.w #8,d0
321 bsr send_byte
322 move.b d3,d0
323 bsr send_byte
324 bra pcc_io_loop
325
326pcc_io_r32:
327 move.l (a2),d3
328 move.l d3,d0
329 swap d0
330 lsr.l #8,d0
331 bsr send_byte
332 move.l d3,d0
333 swap d0
334 bsr send_byte
335 move.w d3,d0
336 lsr.w #8,d0
337 bsr send_byte
338 move.b d3,d0
339 bsr send_byte
340 bra pcc_io_loop
341
342
4e6ba16d 343/* PicoDrive savestate load */
344pcc_loadstate:
345 /* write VRAM */
346 move.l #0xc00000,a0
347 move.w #0x8f02,4(a0) /* auto increment 2 */
348
349 move.l #0x40000000,4(a0)
350 move.l #0x10000/2-1,d3
351tr_do_vram_loop:
352 bsr recv_word
353 move.w d0,(a0)
354 dbra d3, tr_do_vram_loop
355
356 /* write cram */
357 move.l #0xc0000000,4(a0)
358 move.l #0x80/2-1,d3
359tr_do_cram_loop:
360 bsr recv_word
361 move.w d0,(a0)
362 dbra d3, tr_do_cram_loop
363
364 /* write vsram */
365 move.l #0x40000010,4(a0)
366 move.l #0x80/2-1,d3
367tr_do_vsram_loop:
368 bsr recv_word
369 move.w d0,(a0)
370 dbra d3, tr_do_vsram_loop
371
372 /* recv and write regs */
373 lea 0xffe000,a3
374 move.l a3,a2
375 moveq.l #0x20-1,d3
376tr_do_vdpreg_recv_loop:
377 bsr recv_byte
378 move.b d0,(a2)+
379 dbra d3, tr_do_vdpreg_recv_loop
380
381 move.l a3,a2
382 moveq.l #0,d3
383tr_do_vdpreg_loop:
384 move.b d3,d1
385 or.b #0x80,d1
386 lsl.w #8,d1
387 move.b (d3,a2),d1
388 move.w d1,4(a0)
389 addq.l #1,d3
390 cmp.b #0x17,d3 /* FIXME: r23 might cause DMA or.. */
391 bne 0f /* ..something and hang VDP.. */
392 add.b #1,d3 /* ..so we skip it */
3930:
394 cmp.b #0x20,d3
395 blt tr_do_vdpreg_loop
396
397 moveq.l #0,d0
398 move.b 5(a3),d0
399 bsr invalidate_sprite_cache
400
401
4020: bra 0b
403
404 bra return
405
406
f0e06736 407pcc_vram_send:
408 /* write VRAM */
409 move.l #0xc00000,a0
410 move.w #0x8f02,4(a0) /* auto increment 2 */
411 move.l #0,4(a0) /* VRAM read, addr 0 */
412 move.l #0x10000/2-1,d4
413
414 switch_to_output
415
416tr_vram_send_loop:
417 move.w (a0),d3
418 move.w d3,d0
419 lsr.w #8,d0
420 bsr send_byte
421 move.b d3,d0
422 bsr send_byte
423 dbra d4,tr_vram_send_loop
424
425 bra return
426
4e6ba16d 427
428
93c5aa8a 429/* some random code */
272bd2ec 430pcc_test_code:
8689c962 431 bra return
432
433
93c5aa8a 434
8689c962 435return:
436 move.b #0,(0xa1000b).l /* all inputs */
437 move.l #0xffe000,a1
438 move.l d0,(a1)+ /* last state for debug */
439 move.l d1,(a1)+
440 move.l d2,(a1)+
441 move.l d3,(a1)+
442 move.l a0,(a1)+
f0e06736 443 rts
444# bra return_to_main
8689c962 445
446
447# vim:filetype=asmM68k