972b9182d7f6a46d95d5495da4b31f4929e75520
[picodrive.git] / memory_arm.s
1 @ vim:filetype=armasm\r
2 \r
3 @ (c) Copyright 2006-2009, Grazvydas "notaz" Ignotas\r
4 @ All Rights Reserved\r
5 \r
6 \r
7 @@ .include "port_config.s"\r
8 \r
9 .equ SRR_MAPPED,    (1 <<  0)\r
10 .equ SRR_READONLY,  (1 <<  1)\r
11 .equ SRF_EEPROM,    (1 <<  1)\r
12 .equ POPT_6BTN_PAD, (1 <<  5)\r
13 .equ POPT_EN_32X,   (1 << 20)\r
14 \r
15 .text\r
16 .align 4\r
17 \r
18 .global PicoRead8_sram\r
19 .global PicoRead8_io\r
20 .global PicoRead16_sram\r
21 .global PicoRead16_io\r
22 .global PicoWrite8_io\r
23 .global PicoWrite16_io\r
24 \r
25 PicoRead8_sram: @ u32 a, u32 d\r
26     ldr     r2, =(SRam)\r
27     ldr     r3, =(Pico+0x22200)\r
28     ldr     r1, [r2, #8]    @ SRam.end\r
29     cmp     r0, r1\r
30     bgt     m_read8_nosram\r
31     ldr     r1, [r2, #4]    @ SRam.start\r
32     cmp     r0, r1\r
33     blt     m_read8_nosram\r
34     ldrb    r1, [r3, #0x11] @ Pico.m.sram_reg\r
35     tst     r1, #SRR_MAPPED\r
36     beq     m_read8_nosram\r
37     ldr     r1, [r2, #0x0c]\r
38     tst     r1, #SRF_EEPROM\r
39     bne     m_read8_eeprom\r
40     ldr     r1, [r2, #4]    @ SRam.start\r
41     ldr     r2, [r2]        @ SRam.data\r
42     sub     r0, r0, r1\r
43     add     r0, r0, r2\r
44     ldrb    r0, [r0]\r
45     bx      lr\r
46 \r
47 m_read8_nosram:\r
48     ldr     r1, [r3, #4]    @ romsize\r
49     cmp     r0, r1\r
50     movgt   r0, #0\r
51     bxgt    lr              @ bad location\r
52     @ XXX: banking unfriendly\r
53     ldr     r1, [r3]\r
54     eor     r0, r0, #1\r
55     ldrb    r0, [r1, r0]\r
56     bx      lr\r
57 \r
58 m_read8_eeprom:\r
59     stmfd   sp!,{r0,lr}\r
60     bl      EEPROM_read\r
61     ldmfd   sp!,{r1,lr}\r
62     tst     r1, #1\r
63     moveq   r0, r0, lsr #8\r
64     bx      lr\r
65 \r
66 \r
67 PicoRead8_io: @ u32 a, u32 d\r
68     bic     r2, r0, #0x001f   @ most commonly we get i/o port read,\r
69     cmp     r2, #0xa10000     @ so check for it first\r
70     bne     m_read8_not_io\r
71 \r
72 m_read8_misc_io:\r
73     ands    r0, r0, #0x1e\r
74     beq     m_read8_misc_hwreg\r
75     cmp     r0, #4\r
76     movlt   r0, #0\r
77     moveq   r0, #1\r
78     ble     PadRead\r
79     ldr     r3, =(Pico+0x22000)\r
80     mov     r0, r0, lsr #1  @ other IO ports (Pico.ioports[a])\r
81     ldrb    r0, [r3, r0]\r
82     bx      lr\r
83 \r
84 m_read8_misc_hwreg:\r
85     ldr     r3, =(Pico+0x22200)\r
86     ldrb    r0, [r3, #0x0f] @ Pico.m.hardware\r
87     bx      lr\r
88 \r
89 m_read8_not_io:\r
90     and     r2, r0, #0xfc00\r
91     cmp     r2, #0x1000\r
92     bne     m_read8_not_brq\r
93 \r
94     ldr     r3, =(Pico+0x22200)\r
95     mov     r1, r0\r
96     ldr     r0, [r3, #8]      @ Pico.m.rotate\r
97     add     r0, r0, #1\r
98     strb    r0, [r3, #8]\r
99     eor     r0, r0, r0, lsl #6\r
100 \r
101     tst     r1, #1\r
102     bxne    lr                @ odd addr -> open bus\r
103     bic     r0, r0, #1        @ bit0 defined in this area\r
104     and     r2, r1, #0xff00\r
105     cmp     r2, #0x1100\r
106     bxne    lr                @ not busreq\r
107 \r
108     ldrb    r1, [r3, #(8+0x01)] @ Pico.m.z80Run\r
109     ldrb    r2, [r3, #(8+0x0f)] @ Pico.m.z80_reset\r
110     orr     r0, r0, r1\r
111     orr     r0, r0, r2\r
112     bx      lr\r
113 \r
114 m_read8_not_brq:\r
115     ldr     r2, =PicoOpt\r
116     ldr     r2, [r2]\r
117     tst     r2, #POPT_EN_32X\r
118     bne     PicoRead8_32x\r
119     mov     r0, #0\r
120     bx      lr\r
121 \r
122 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
123 \r
124 PicoRead16_sram: @ u32 a, u32 d\r
125     ldr     r2, =(SRam)\r
126     ldr     r3, =(Pico+0x22200)\r
127     ldr     r1, [r2, #8]    @ SRam.end\r
128     cmp     r0, r1\r
129     bgt     m_read16_nosram\r
130     ldr     r1, [r2, #4]    @ SRam.start\r
131     cmp     r0, r1\r
132     blt     m_read16_nosram\r
133     ldrb    r1, [r3, #0x11] @ Pico.m.sram_reg\r
134     tst     r1, #SRR_MAPPED\r
135     beq     m_read16_nosram\r
136     ldr     r1, [r2, #0x0c]\r
137     tst     r1, #SRF_EEPROM\r
138     bne     EEPROM_read\r
139     ldr     r1, [r2, #4]    @ SRam.start\r
140     ldr     r2, [r2]        @ SRam.data\r
141     sub     r0, r0, r1\r
142     add     r0, r0, r2\r
143     ldrb    r1, [r0], #1\r
144     ldrb    r0, [r0]\r
145     orr     r0, r0, r1, lsl #8\r
146     bx      lr\r
147 \r
148 m_read16_nosram:\r
149     ldr     r1, [r3, #4]    @ romsize\r
150     cmp     r0, r1\r
151     movgt   r0, #0\r
152     bxgt    lr              @ bad location\r
153     @ XXX: banking unfriendly\r
154     ldr     r1, [r3]\r
155     ldrh    r0, [r1, r0]\r
156     bx      lr\r
157 \r
158 \r
159 PicoRead16_io: @ u32 a, u32 d\r
160     bic     r2, r0, #0x001f   @ most commonly we get i/o port read,\r
161     cmp     r2, #0xa10000     @ so check for it first\r
162     bne     m_read16_not_io\r
163     stmfd   sp!,{lr}\r
164     bl      m_read8_misc_io   @ same as read8\r
165     orr     r0, r0, r0, lsl #8 @ only has bytes mirrored\r
166     ldmfd   sp!,{pc}\r
167 \r
168 m_read16_not_io:\r
169     and     r2, r0, #0xfc00\r
170     cmp     r2, #0x1000\r
171     bne     m_read16_not_brq\r
172 \r
173     ldr     r3, =(Pico+0x22200)\r
174     and     r2, r0, #0xff00\r
175     ldr     r0, [r3, #8]      @ Pico.m.rotate\r
176     add     r0, r0, #1\r
177     strb    r0, [r3, #8]\r
178     eor     r0, r0, r0, lsl #5\r
179     eor     r0, r0, r0, lsl #8\r
180     bic     r0, r0, #0x100    @ bit8 defined in this area\r
181     cmp     r2, #0x1100\r
182     bxne    lr                @ not busreq\r
183 \r
184     ldrb    r1, [r3, #(8+0x01)] @ Pico.m.z80Run\r
185     ldrb    r2, [r3, #(8+0x0f)] @ Pico.m.z80_reset\r
186     orr     r0, r0, r1, lsl #8\r
187     orr     r0, r0, r2, lsl #8\r
188     bx      lr\r
189 \r
190 m_read16_not_brq:\r
191     ldr     r2, =PicoOpt\r
192     ldr     r2, [r2]\r
193     tst     r2, #POPT_EN_32X\r
194     bne     PicoRead16_32x\r
195     mov     r0, #0\r
196     bx      lr\r
197 \r
198 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
199 \r
200 PicoWrite8_io: @ u32 a, u32 d\r
201     bic     r2, r0, #0x1e       @ most commonly we get i/o port write,\r
202     eor     r2, r2, #0xa10000   @ so check for it first\r
203     eors    r2, r2, #1\r
204     bne     m_write8_not_io\r
205 \r
206 m_write8_io:\r
207     ldr     r2, =PicoOpt\r
208     and     r0, r0, #0x1e\r
209     ldr     r2, [r2]\r
210     ldr     r3, =(Pico+0x22000) @ Pico.ioports\r
211     tst     r2, #POPT_6BTN_PAD\r
212     beq     m_write8_io_done\r
213     cmp     r0, #2\r
214     cmpne   r0, #4\r
215     bne     m_write8_io_done @ not likely to happen\r
216     add     r2, r3, #0x200   @ Pico+0x22200\r
217     mov     r12,#0\r
218     cmp     r0, #2\r
219     streqb  r12,[r2,#0x18]\r
220     strneb  r12,[r2,#0x19]   @ Pico.m.padDelay[i] = 0\r
221     tst     r1, #0x40        @ TH\r
222     beq     m_write8_io_done\r
223     ldrb    r12,[r3, r0, lsr #1]\r
224     tst     r12,#0x40\r
225     bne     m_write8_io_done\r
226     cmp     r0, #2\r
227     ldreqb  r12,[r2,#0x0a]\r
228     ldrneb  r12,[r2,#0x0b]   @ Pico.m.padTHPhase\r
229     add     r12,r12,#1\r
230     streqb  r12,[r2,#0x0a]\r
231     strneb  r12,[r2,#0x0b]   @ Pico.m.padTHPhase\r
232 m_write8_io_done:\r
233     strb    r1, [r3, r0, lsr #1]\r
234     bx      lr\r
235 \r
236 m_write8_not_io:\r
237     tst     r0, #1\r
238     bne     m_write8_not_z80ctl @ even addrs only\r
239     and     r2, r0, #0xff00\r
240     cmp     r2, #0x1100\r
241     moveq   r0, r1\r
242     beq     ctl_write_z80busreq\r
243     cmp     r2, #0x1200\r
244     moveq   r0, r1\r
245     beq     ctl_write_z80reset\r
246 \r
247 m_write8_not_z80ctl:\r
248     @ unlikely\r
249     eor     r2, r0, #0xa10000\r
250     eor     r2, r2, #0x003000\r
251     eors    r2, r2, #0x0000f1\r
252     bne     m_write8_not_sreg\r
253     ldr     r3, =(Pico+0x22200)\r
254     ldrb    r2, [r3, #(8+9)] @ Pico.m.sram_reg\r
255     and     r1, r1, #(SRR_MAPPED|SRR_READONLY)\r
256     bic     r2, r2, #(SRR_MAPPED|SRR_READONLY)\r
257     orr     r2, r2, r1\r
258     strb    r2, [r3, #(8+9)]\r
259     bx      lr\r
260 \r
261 m_write8_not_sreg:\r
262     ldr     r2, =PicoOpt\r
263     ldr     r2, [r2]\r
264     tst     r2, #POPT_EN_32X\r
265     bne     PicoWrite8_32x\r
266     bx      lr\r
267 \r
268 @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\r
269 \r
270 PicoWrite16_io: @ u32 a, u32 d\r
271     bic     r2, r0, #0x1f    @ most commonly we get i/o port write,\r
272     cmp     r2, #0xa10000    @ so check for it first\r
273     beq     m_write8_io\r
274 \r
275 m_write16_not_io:\r
276     and     r2, r0, #0xff00\r
277     cmp     r2, #0x1100\r
278     moveq   r0, r1, lsr #8\r
279     beq     ctl_write_z80busreq\r
280     cmp     r2, #0x1200\r
281     moveq   r0, r1, lsr #8\r
282     beq     ctl_write_z80reset\r
283 \r
284 m_write16_not_z80ctl:\r
285     @ unlikely\r
286     eor     r2, r0, #0xa10000\r
287     eor     r2, r2, #0x003000\r
288     eors    r2, r2, #0x0000f0\r
289     bne     m_write16_not_sreg\r
290     ldr     r3, =(Pico+0x22200)\r
291     ldrb    r2, [r3, #(8+9)] @ Pico.m.sram_reg\r
292     and     r1, r1, #(SRR_MAPPED|SRR_READONLY)\r
293     bic     r2, r2, #(SRR_MAPPED|SRR_READONLY)\r
294     orr     r2, r2, r1\r
295     strb    r2, [r3, #(8+9)]\r
296     bx      lr\r
297 \r
298 m_write16_not_sreg:\r
299     ldr     r2, =PicoOpt\r
300     ldr     r2, [r2]\r
301     tst     r2, #POPT_EN_32X\r
302     bne     PicoWrite16_32x\r
303     bx      lr\r
304 \r
305 .pool\r
306 \r