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