hexed: support PicoDrive savestate loading (only VDP+VRAM for now)
[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
93c5aa8a 123send_byte:
124 send_one_byte
125 rts
126
4e6ba16d 127.equ sat_maxsize, (80*8+0x200) /* sprites+max_align */
128
129# make sure cache is invalidated
130# note: VRAM copy doesn't seem to help here
131# note2: cache is updated as data is written
132# in: d0 - vdp reg5, a0 = 0xc00000
133# trash: d1,d2,a2
134invalidate_sprite_cache:
135 move.w #0x8f02,4(a0) /* auto increment 2 */
136 lsl.b #1,d0 /* upper byte of sat address */
137 move.b d0,d1
138 lsr.b #6,d1 /* 15:14 dst addr */
139 and.b #0x3f,d0 /* assemble cmd */
140 lsl.w #8,d0
141 swap d0
142 move.b d1,d0
143 move.l d0,4(a0)
144
145 move.l #0xffe000,a2
146 move.l #sat_maxsize/2-1,d2
1470:
148 move.w (a0),(a2)+
149 dbra d2,0b
150
151 bset #30,d0 /* VRAM write */
152 move.l d0,4(a0)
153
154 move.l #0xffe000,a2
155 move.l #sat_maxsize/2-1,d2
1560:
157 move.w (a2)+,(a0)
158 dbra d2,0b
159 rts
160
161
8689c962 162
163do_transfer:
164 lea 0xa10005,a1
165 move.b #0x40,(0xa1000b).l /* ctrl - all inputs except TH */
166 move.b #0x00,(a1)
167
168 bsr recv_byte
169 cmp.b #CMD_PREFIX,d0
170 bne return
171
172 bsr recv_byte
272bd2ec 173 cmp.b #CMD_FIRST,d0
174 bcs return
175 cmp.b #CMD_LAST+1,d0
176 bcc return
177 sub.b #CMD_FIRST,d0
178
179 lsl.w #2,d0
180 lea (jumptab,pc,d0),a0
181 jmp (a0)
182jumptab:
183 bra pcc_transfer_recv /* sent to us */
184 bra pcc_transfer_send /* recv from us */
185 bra pcc_jump
93c5aa8a 186 bra pcc_io
4e6ba16d 187 bra pcc_loadstate
272bd2ec 188 bra pcc_test_code
189
190
93c5aa8a 191/* receive data from PC */
272bd2ec 192pcc_transfer_recv:
8689c962 193 bsr recv_ad
194 move.l d0,a0
195 bsr recv_ad
196 move.l d0,d3
197
198tr_recv_loop:
199 recv_one_byte
200 move.b d0,(a0)+
201 subq.l #1,d3
272bd2ec 202 bgt tr_recv_loop
8689c962 203 bra return
204
272bd2ec 205
93c5aa8a 206/* send data to PC */
272bd2ec 207pcc_transfer_send:
8689c962 208 bsr recv_ad
209 move.l d0,a0
210 bsr recv_ad
211 move.l d0,d3
212
93c5aa8a 2130: /*Lwait_tl_low: it should switch to rx mode before lowering tl */
8689c962 214 move.b (a1),d0
215 btst.b #4,d0
216 bne 0b /*Lwait_tl_low*/
217
218 move.b #0x4f,(0xa1000b).l
219 move.b #0x40,(a1)
220
221tr_send_loop:
222 move.b (a0)+,d0
223 send_one_byte
224 subq.l #1,d3
272bd2ec 225 bgt tr_send_loop
226 bra return
227
228
93c5aa8a 229/* call specified location */
272bd2ec 230pcc_jump:
231 bsr recv_ad
232 move.l d0,a0
93c5aa8a 233 jsr (a0)
234 bra return
235
236
237/* do simple i/o commands */
238pcc_io:
239 moveq.l #0,d4
240 bsr recv_byte
241 move.b d0,d4
242 bsr recv_byte
243 lsl.l #8,d4
244 move.b d0,d4
272bd2ec 245
93c5aa8a 246pcc_io_loop:
247 move.b #0x40,(0xa1000b).l /* input mode */
272bd2ec 248
93c5aa8a 249 sub.w #1,d4
250 bmi return
251
252 bsr recv_byte
253 move.b d0,d3 /* cmd */
254
255 bsr recv_ad
256 move.l d0,a2 /* addr */
257
258 cmp.b #IOSEQ_W32, d3
259 beq pcc_io_w32
260 cmp.b #IOSEQ_W16, d3
261 beq pcc_io_w16
262 cmp.b #IOSEQ_W8, d3
263 bne pcc_io_rx
264
265pcc_io_w8:
266 bsr recv_byte
267 move.b d0,(a2)
268 bra pcc_io_loop
269
270pcc_io_w16:
271 bsr recv_byte
272 move.b d0,d3
273 bsr recv_byte
274 lsl.w #8,d3
275 move.b d0,d3
276 move.w d3,(a2)
277 bra pcc_io_loop
278
279pcc_io_w32:
280 bsr recv_byte
281 move.b d0,d3
282 bsr recv_byte
283 lsl.w #8,d3
284 move.b d0,d3
285 bsr recv_byte
286 lsl.l #8,d3
287 move.b d0,d3
288 bsr recv_byte
289 lsl.l #8,d3
290 move.b d0,d3
291 move.l d3,(a2)
292 bra pcc_io_loop
293
294pcc_io_rx:
2950: /*Lwait_tl_low:*/
296 move.b (a1),d0
297 btst.b #4,d0
298 bne 0b /*Lwait_tl_low*/
299
300 move.b #0x4f,(0xa1000b).l
301 move.b #0x40,(a1)
302
303 cmp.b #IOSEQ_R32, d3
304 beq pcc_io_r32
305 cmp.b #IOSEQ_R16, d3
306 beq pcc_io_r16
307 cmp.b #IOSEQ_R8, d3
308 bne return
309
310pcc_io_r8:
311 move.b (a2),d0
312 bsr send_byte
313 bra pcc_io_loop
314
315pcc_io_r16:
316 move.w (a2),d3
317 move.w d3,d0
318 lsr.w #8,d0
319 bsr send_byte
320 move.b d3,d0
321 bsr send_byte
322 bra pcc_io_loop
323
324pcc_io_r32:
325 move.l (a2),d3
326 move.l d3,d0
327 swap d0
328 lsr.l #8,d0
329 bsr send_byte
330 move.l d3,d0
331 swap d0
332 bsr send_byte
333 move.w d3,d0
334 lsr.w #8,d0
335 bsr send_byte
336 move.b d3,d0
337 bsr send_byte
338 bra pcc_io_loop
339
340
4e6ba16d 341/* PicoDrive savestate load */
342pcc_loadstate:
343 /* write VRAM */
344 move.l #0xc00000,a0
345 move.w #0x8f02,4(a0) /* auto increment 2 */
346
347 move.l #0x40000000,4(a0)
348 move.l #0x10000/2-1,d3
349tr_do_vram_loop:
350 bsr recv_word
351 move.w d0,(a0)
352 dbra d3, tr_do_vram_loop
353
354 /* write cram */
355 move.l #0xc0000000,4(a0)
356 move.l #0x80/2-1,d3
357tr_do_cram_loop:
358 bsr recv_word
359 move.w d0,(a0)
360 dbra d3, tr_do_cram_loop
361
362 /* write vsram */
363 move.l #0x40000010,4(a0)
364 move.l #0x80/2-1,d3
365tr_do_vsram_loop:
366 bsr recv_word
367 move.w d0,(a0)
368 dbra d3, tr_do_vsram_loop
369
370 /* recv and write regs */
371 lea 0xffe000,a3
372 move.l a3,a2
373 moveq.l #0x20-1,d3
374tr_do_vdpreg_recv_loop:
375 bsr recv_byte
376 move.b d0,(a2)+
377 dbra d3, tr_do_vdpreg_recv_loop
378
379 move.l a3,a2
380 moveq.l #0,d3
381tr_do_vdpreg_loop:
382 move.b d3,d1
383 or.b #0x80,d1
384 lsl.w #8,d1
385 move.b (d3,a2),d1
386 move.w d1,4(a0)
387 addq.l #1,d3
388 cmp.b #0x17,d3 /* FIXME: r23 might cause DMA or.. */
389 bne 0f /* ..something and hang VDP.. */
390 add.b #1,d3 /* ..so we skip it */
3910:
392 cmp.b #0x20,d3
393 blt tr_do_vdpreg_loop
394
395 moveq.l #0,d0
396 move.b 5(a3),d0
397 bsr invalidate_sprite_cache
398
399
4000: bra 0b
401
402 bra return
403
404
405
406
93c5aa8a 407/* some random code */
272bd2ec 408pcc_test_code:
8689c962 409 bra return
410
411
93c5aa8a 412
8689c962 413return:
414 move.b #0,(0xa1000b).l /* all inputs */
415 move.l #0xffe000,a1
416 move.l d0,(a1)+ /* last state for debug */
417 move.l d1,(a1)+
418 move.l d2,(a1)+
419 move.l d3,(a1)+
420 move.l a0,(a1)+
421 bra return_to_main
422
423
424# vim:filetype=asmM68k