568be822da09bc948b86e4c0a5eb5c834113c488
[picodrive.git] / pico / memory_arm.S
1 /*\r
2  * PicoDrive\r
3  * (C) notaz, 2006-2009\r
4  * (C) irixxxx, 2019,2020\r
5  *\r
6  * This work is licensed under the terms of MAME license.\r
7  * See COPYING file in the top-level directory.\r
8  */\r
9 \r
10 #include "arm_features.h"\r
11 #include "pico_int_offs.h"\r
12 \r
13 .equ SRR_MAPPED,    (1 <<  0)\r
14 .equ SRR_READONLY,  (1 <<  1)\r
15 .equ SRF_EEPROM,    (1 <<  1)\r
16 .equ POPT_EN_32X,   (1 << 20)\r
17 \r
18 .text\r
19 .align 4\r
20 \r
21 .global PicoRead8_sram\r
22 .global PicoRead8_io\r
23 .global PicoRead16_sram\r
24 .global PicoRead16_io\r
25 .global PicoWrite8_io\r
26 .global PicoWrite16_io\r
27 \r
28     PIC_LDR_INIT()\r
29 \r
30 PicoRead8_sram: @ u32 a\r
31     PIC_LDR(r3, r1, Pico)\r
32     ldr     r1, [r3, #OFS_Pico_sv_end]\r
33     cmp     r0, r1\r
34     bgt     m_read8_nosram\r
35     ldr     r2, [r3, #OFS_Pico_sv_start]\r
36     cmp     r0, r2\r
37     blt     m_read8_nosram\r
38     ldrb    r1, [r3, #OFS_Pico_m_sram_reg]\r
39     tst     r1, #SRR_MAPPED\r
40     beq     m_read8_nosram\r
41     ldr     r1, [r3, #OFS_Pico_sv_flags]\r
42     tst     r1, #SRF_EEPROM\r
43     bne     m_read8_eeprom\r
44     ldr     r1, [r3, #OFS_Pico_sv_data]\r
45     sub     r0, r0, r2\r
46     ldrb    r0, [r0, r1]\r
47     bx      lr\r
48 \r
49 m_read8_nosram:\r
50     ldr     r1, [r3, #OFS_Pico_romsize]\r
51     cmp     r0, r1\r
52     movgt   r0, #0\r
53     bxgt    lr              @ bad location\r
54     @ XXX: banking unfriendly\r
55     ldr     r1, [r3, #OFS_Pico_rom]\r
56     eor     r0, r0, #1\r
57     ldrb    r0, [r1, r0]\r
58     bx      lr\r
59 \r
60 m_read8_eeprom:\r
61     stmfd   sp!,{r0,lr}\r
62     bl      EEPROM_read\r
63     ldmfd   sp!,{r1,lr}\r
64     tst     r1, #1\r
65     moveq   r0, r0, lsr #8\r
66     and     r0, r0, #0xff\r
67     bx      lr\r
68 \r
69 \r
70 PicoRead8_io: @ u32 a\r
71     bic     r2, r0, #0x001f   @ most commonly we get i/o port read,\r
72     cmp     r2, #0xa10000     @ so check for it first\r
73     beq     io_ports_read\r
74 \r
75 m_read8_not_io:\r
76     and     r2, r0, #0xfc00\r
77     cmp     r2, #0x1000\r
78     bne     PicoRead8_32x\r
79 \r
80     PIC_LDR(r3, r1, Pico)\r
81     mov     r1, r0\r
82     ldr     r0, [r3, #OFS_Pico_m_rotate]\r
83     add     r0, r0, #1\r
84     strb    r0, [r3, #OFS_Pico_m_rotate]\r
85     eor     r0, r0, r0, lsl #6\r
86 \r
87     tst     r1, #1\r
88     bxne    lr                @ odd addr -> open bus\r
89     bic     r0, r0, #1        @ bit0 defined in this area\r
90     and     r2, r1, #0xff00\r
91     cmp     r2, #0x1100\r
92     bxne    lr                @ not busreq\r
93 \r
94     ldrb    r1, [r3, #OFS_Pico_m_z80Run]\r
95     ldrb    r2, [r3, #OFS_Pico_m_z80_reset]\r
96     orr     r0, r0, r1\r
97     orr     r0, r0, r2\r
98     bx      lr\r
99 \r
100 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
101 \r
102 PicoRead16_sram: @ u32 a, u32 d\r
103     PIC_LDR(r3, r1, Pico)\r
104     ldr     r1, [r3, #OFS_Pico_sv_end]\r
105     cmp     r0, r1\r
106     bgt     m_read16_nosram\r
107     ldr     r2, [r3, #OFS_Pico_sv_start]\r
108     cmp     r0, r2\r
109     blt     m_read16_nosram\r
110     ldrb    r1, [r3, #OFS_Pico_m_sram_reg]\r
111     tst     r1, #SRR_MAPPED\r
112     beq     m_read16_nosram\r
113     ldr     r1, [r3, #OFS_Pico_sv_flags]\r
114     tst     r1, #SRF_EEPROM\r
115     bne     EEPROM_read\r
116     ldr     r1, [r3, #OFS_Pico_sv_data]\r
117     sub     r0, r0, r2\r
118     ldrb    r1, [r0, r1]!\r
119     ldrb    r0, [r0, #1]\r
120     orr     r0, r0, r1, lsl #8\r
121     bx      lr\r
122 \r
123 m_read16_nosram:\r
124     ldr     r1, [r3, #OFS_Pico_romsize]\r
125     cmp     r0, r1\r
126     movgt   r0, #0\r
127     bxgt    lr              @ bad location\r
128     @ XXX: banking unfriendly\r
129     ldr     r1, [r3, #OFS_Pico_rom]\r
130     ldrh    r0, [r1, r0]\r
131     bx      lr\r
132 \r
133 \r
134 PicoRead16_io: @ u32 a, u32 d\r
135     bic     r2, r0, #0x001f   @ most commonly we get i/o port read,\r
136     cmp     r2, #0xa10000     @ so check for it first\r
137     bne     m_read16_not_io\r
138     stmfd   sp!,{lr}\r
139     bl      io_ports_read     @ same as read8\r
140     orr     r0, r0, r0, lsl #8 @ only has bytes mirrored\r
141     ldmfd   sp!,{pc}\r
142 \r
143 m_read16_not_io:\r
144     and     r2, r0, #0xfc00\r
145     cmp     r2, #0x1000\r
146     bne     PicoRead16_32x\r
147 \r
148     PIC_LDR(r3, r2, Pico)\r
149     and     r2, r0, #0xff00\r
150     ldr     r0, [r3, #OFS_Pico_m_rotate]\r
151     add     r0, r0, #1\r
152     strb    r0, [r3, #OFS_Pico_m_rotate]\r
153     eor     r0, r0, r0, lsl #5\r
154     eor     r0, r0, r0, lsl #8\r
155     bic     r0, r0, #0x100    @ bit8 defined in this area\r
156     cmp     r2, #0x1100\r
157     bxne    lr                @ not busreq\r
158 \r
159     ldrb    r1, [r3, #OFS_Pico_m_z80Run]\r
160     ldrb    r2, [r3, #OFS_Pico_m_z80_reset]\r
161     orr     r0, r0, r1, lsl #8\r
162     orr     r0, r0, r2, lsl #8\r
163     bx      lr\r
164 \r
165 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
166 \r
167 PicoWrite8_io: @ u32 a, u32 d\r
168     bic     r2, r0, #0x1e       @ most commonly we get i/o port write,\r
169     eor     r2, r2, #0xa10000   @ so check for it first\r
170     eors    r2, r2, #1\r
171     beq     io_ports_write\r
172 \r
173 m_write8_not_io:\r
174     tst     r0, #1\r
175     bne     m_write8_not_z80ctl @ even addrs only\r
176     and     r2, r0, #0xff00\r
177     cmp     r2, #0x1100\r
178     moveq   r0, r1\r
179     beq     ctl_write_z80busreq\r
180     cmp     r2, #0x1200\r
181     moveq   r0, r1\r
182     beq     ctl_write_z80reset\r
183 \r
184 m_write8_not_z80ctl:\r
185     @ unlikely\r
186     eor     r2, r0, #0xa10000\r
187     eor     r2, r2, #0x003000\r
188     eors    r2, r2, #0x0000f1\r
189     bne     PicoWrite8_32x\r
190     PIC_LDR(r3, r2, Pico)\r
191     ldrb    r2, [r3, #OFS_Pico_m_sram_reg]\r
192     and     r1, r1, #(SRR_MAPPED|SRR_READONLY)\r
193     bic     r2, r2, #(SRR_MAPPED|SRR_READONLY)\r
194     orr     r2, r2, r1\r
195     strb    r2, [r3, #OFS_Pico_m_sram_reg]\r
196     bx      lr\r
197 \r
198 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
199 \r
200 PicoWrite16_io: @ u32 a, u32 d\r
201     bic     r2, r0, #0x1f    @ most commonly we get i/o port write,\r
202     cmp     r2, #0xa10000    @ so check for it first\r
203     beq     io_ports_write\r
204 \r
205 m_write16_not_io:\r
206     and     r2, r0, #0xff00\r
207     cmp     r2, #0x1100\r
208     moveq   r0, r1, lsr #8\r
209     beq     ctl_write_z80busreq\r
210     cmp     r2, #0x1200\r
211     moveq   r0, r1, lsr #8\r
212     beq     ctl_write_z80reset\r
213 \r
214 m_write16_not_z80ctl:\r
215     @ unlikely\r
216     eor     r2, r0, #0xa10000\r
217     eor     r2, r2, #0x003000\r
218     eors    r2, r2, #0x0000f0\r
219     bne     PicoWrite16_32x\r
220     PIC_LDR(r3, r2, Pico)\r
221     ldrb    r2, [r3, #OFS_Pico_m_sram_reg]\r
222     and     r1, r1, #(SRR_MAPPED|SRR_READONLY)\r
223     bic     r2, r2, #(SRR_MAPPED|SRR_READONLY)\r
224     orr     r2, r2, r1\r
225     strb    r2, [r3, #OFS_Pico_m_sram_reg]\r
226     bx      lr\r
227 \r
228 .global m68k_read8\r
229 .global m68k_read16\r
230 .global m68k_read32\r
231 .global m68k_write8\r
232 .global m68k_write16\r
233 .global m68k_write32\r
234 \r
235 m68k_read8:\r
236     PIC_LDR(r3, r2, m68k_read8_map)\r
237     bic     r0, r0, #0xff000000\r
238     mov     r2, r0, lsr #16\r
239     ldr     r3, [r3, r2, lsl #2]\r
240     eor     r2, r0, #1\r
241     movs    r3, r3, lsl #1\r
242     ldrccb  r0, [r3, r2]\r
243     bxcc    lr\r
244     bx      r3\r
245 \r
246 m68k_read16:\r
247     PIC_LDR(r3, r2, m68k_read16_map)\r
248     bic     r0, r0, #0xff000000\r
249     mov     r2, r0, lsr #16\r
250     ldr     r3, [r3, r2, lsl #2]\r
251     bic     r0, r0, #1\r
252     movs    r3, r3, lsl #1\r
253     ldrcch  r0, [r3, r0]\r
254     bxcc    lr\r
255     bx      r3\r
256 \r
257 m68k_read32:\r
258     PIC_LDR(r3, r2, m68k_read16_map)\r
259     bic     r0, r0, #0xff000000\r
260     mov     r2, r0, lsr #16\r
261     ldr     r3, [r3, r2, lsl #2]\r
262     bic     r0, r0, #1\r
263     movs    r3, r3, lsl #1\r
264     ldrcch  r1, [r3, r0]!\r
265     ldrcch  r0, [r3, #2]\r
266     orrcc   r0, r0, r1, lsl #16\r
267     bxcc    lr\r
268 \r
269     stmfd   sp!, {r0, r3, r4, lr}\r
270     mov     lr, pc\r
271     bx      r3\r
272     ldmfd   sp!, {r1, r3}\r
273     str     r0, [sp]\r
274     add     r0, r1, #2\r
275     mov     lr, pc\r
276     bx      r3\r
277     ldmfd   sp!, {r1, lr}\r
278     mov     r0, r0, lsl #16\r
279     mov     r1, r1, lsl #16\r
280     orr     r0, r1, r0, lsr #16\r
281     bx      lr\r
282 \r
283 m68k_write8:\r
284     PIC_LDR(r3, r2, m68k_write8_map)\r
285     bic     r0, r0, #0xff000000\r
286     mov     r2, r0, lsr #16\r
287     ldr     r3, [r3, r2, lsl #2]\r
288     eor     r2, r0, #1\r
289     movs    r3, r3, lsl #1\r
290     strccb  r1, [r3, r2]\r
291     bxcc    lr\r
292     bx      r3\r
293 \r
294 m68k_write16:\r
295     PIC_LDR(r3, r2, m68k_write16_map)\r
296     bic     r0, r0, #0xff000000\r
297     mov     r2, r0, lsr #16\r
298     ldr     r3, [r3, r2, lsl #2]\r
299     bic     r0, r0, #1\r
300     movs    r3, r3, lsl #1\r
301     strcch  r1, [r3, r0]\r
302     bxcc    lr\r
303     bx      r3\r
304 \r
305 m68k_write32:\r
306     PIC_LDR(r3, r2, m68k_write16_map)\r
307     bic     r0, r0, #0xff000000\r
308     mov     r2, r0, lsr #16\r
309     ldr     r3, [r3, r2, lsl #2]\r
310     bic     r0, r0, #1\r
311     movs    r3, r3, lsl #1\r
312     movcc   r2, r1, lsr #16\r
313     strcch  r2, [r3, r0]!\r
314     strcch  r1, [r3, #2]\r
315     bxcc    lr\r
316 \r
317     stmfd   sp!, {r0, r1, r3, lr}\r
318     mov     r1, r1, lsr #16\r
319     mov     lr, pc\r
320     bx      r3\r
321     ldmfd   sp!, {r0, r1, r3, lr}\r
322     add     r0, r0, #2\r
323     bx      r3\r
324 \r
325 .pool\r
326 \r
327 @ vim:filetype=armasm\r