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 | |
44 | 0: /*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 | |
52 | 0: /*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 | |
71 | 0: /*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 | |
82 | 0: /*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 | |
90 | recv_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 |
98 | recv_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 |
110 | recv_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 |
126 | send_byte: |
127 | send_one_byte |
128 | rts |
129 | |
f0e06736 |
130 | .macro switch_to_output |
131 | 0: /*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 |
147 | invalidate_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 |
160 | 0: |
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 |
169 | 0: |
170 | move.w (a2)+,(a0) |
171 | dbra d2,0b |
172 | rts |
173 | |
174 | |
8689c962 |
175 | |
176 | do_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) |
195 | jumptab: |
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 |
206 | pcc_transfer_recv: |
8689c962 |
207 | bsr recv_ad |
208 | move.l d0,a0 |
209 | bsr recv_ad |
210 | move.l d0,d3 |
211 | |
212 | tr_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 |
221 | pcc_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 | |
229 | tr_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 |
238 | pcc_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 */ |
246 | pcc_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 |
254 | pcc_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 | |
273 | pcc_io_w8: |
274 | bsr recv_byte |
275 | move.b d0,(a2) |
276 | bra pcc_io_loop |
277 | |
278 | pcc_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 | |
287 | pcc_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 | |
302 | pcc_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 | |
312 | pcc_io_r8: |
313 | move.b (a2),d0 |
314 | bsr send_byte |
315 | bra pcc_io_loop |
316 | |
317 | pcc_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 | |
326 | pcc_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 */ |
344 | pcc_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 |
351 | tr_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 |
359 | tr_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 |
367 | tr_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 |
376 | tr_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 |
383 | tr_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 */ |
393 | 0: |
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 | |
402 | 0: bra 0b |
403 | |
404 | bra return |
405 | |
406 | |
f0e06736 |
407 | pcc_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 | |
416 | tr_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 |
430 | pcc_test_code: |
8689c962 |
431 | bra return |
432 | |
433 | |
93c5aa8a |
434 | |
8689c962 |
435 | return: |
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 |