hexed: add jump cmd, refactor transfer
[megadrive.git] / hexed / transfer.S
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 #
17 # THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND ANY
18 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 # DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE FOR ANY
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:
91         moveq.l         #0,d0
92         recv_one_byte 1
93         rts
94
95 # receive address/size to d0 (3 bytes BE)
96 #  in: a1 - data port
97 #  trash: d1,d2
98 recv_ad:
99         moveq.l         #0,d2
100         bsr             recv_byte
101         move.b          d0,d2
102         bsr             recv_byte
103         lsl.l           #8,d2
104         move.b          d0,d2
105         bsr             recv_byte
106         lsl.l           #8,d2
107         move.b          d0,d2
108         move.l          d2,d0
109         rts
110
111
112 do_transfer:
113         lea             0xa10005,a1
114         move.b          #0x40,(0xa1000b).l      /* ctrl - all inputs except TH */
115         move.b          #0x00,(a1)
116
117         bsr             recv_byte
118         cmp.b           #CMD_PREFIX,d0
119         bne             return
120
121         bsr             recv_byte
122         cmp.b           #CMD_FIRST,d0
123         bcs             return
124         cmp.b           #CMD_LAST+1,d0
125         bcc             return
126         sub.b           #CMD_FIRST,d0
127
128         lsl.w           #2,d0
129         lea             (jumptab,pc,d0),a0
130         jmp             (a0)
131 jumptab:
132         bra             pcc_transfer_recv       /* sent to us */
133         bra             pcc_transfer_send       /* recv from us */
134         bra             pcc_jump
135         bra             pcc_test_code
136
137
138 pcc_transfer_recv:
139         bsr             recv_ad
140         move.l          d0,a0
141         bsr             recv_ad
142         move.l          d0,d3
143
144 tr_recv_loop:
145         recv_one_byte
146         move.b          d0,(a0)+
147         subq.l          #1,d3
148         bgt             tr_recv_loop
149         bra             return
150
151
152 pcc_transfer_send:
153         bsr             recv_ad
154         move.l          d0,a0
155         bsr             recv_ad
156         move.l          d0,d3
157
158 0: /*Lwait_tl_low:*/
159         move.b          (a1),d0
160         btst.b          #4,d0
161         bne             0b /*Lwait_tl_low*/
162
163         move.b          #0x4f,(0xa1000b).l
164         move.b          #0x40,(a1)
165
166 tr_send_loop:
167         move.b          (a0)+,d0
168         send_one_byte
169         subq.l          #1,d3
170         bgt             tr_send_loop
171         bra             return
172
173
174 pcc_jump:
175         bsr             recv_ad
176         move.l          d0,a0
177         jmp             (a0)
178
179
180 pcc_test_code:
181         bra             return
182
183
184 return:
185         move.b          #0,(0xa1000b).l /* all inputs */
186         move.l          #0xffe000,a1
187         move.l          d0,(a1)+        /* last state for debug */
188         move.l          d1,(a1)+
189         move.l          d2,(a1)+
190         move.l          d3,(a1)+
191         move.l          a0,(a1)+
192         bra             return_to_main
193
194
195 # vim:filetype=asmM68k