]>
Commit | Line | Data |
---|---|---|
0c5890bb L |
1 | /** |
2 | * | |
3 | * Pin assignments | |
4 | * | |
5 | * | Z180-Sig | STM32-Port |Buffer | Dir | Special Function | | |
6 | * +------------+---------------+-------+-------+-----------------------+ | |
7 | * | A0 | A 1 | P | O | | | |
8 | * | A1 | A 2 | P | O | | | |
9 | * | A2 | A 3 | P | O | | | |
10 | * | A3 | A 4 | P | O | | | |
11 | * | A4 | A 5 | P | O | | | |
12 | * | A5 | A 6 | P | O | | | |
13 | * | A6 | A 7 | P | O | | | |
14 | * | A7 | A 8 | | O | | | |
15 | * | A8 | C 0 | P | O | | | |
16 | * | A9 | C 1 | P | O | | | |
17 | * | A10 | C 2 | P | O | | | |
18 | * | A11 | C 3 | P | O | | | |
19 | * | A12 | C 4 | P | O | | | |
20 | * | A13 | C 5 | P | O | | | |
21 | * | A14 | C 6 | | O | | | |
22 | * | A15 | C 7 | | O | | | |
23 | * | A16 | C 10 | | O | | | |
24 | * | A17 | C 11 | | O | | | |
25 | * | A18 | C 12 | | O | | | |
26 | * | D0 | B 8 | | I/O | | | |
27 | * | D1 | B 9 | | I/O | | | |
28 | * | D2 | B 10 | | I/O | | | |
29 | * | D3 | B 11 | | I/O | | | |
30 | * | D4 | B 12 | | I/O | | | |
31 | * | D5 | B 13 | | I/O | | | |
32 | * | D6 | B 14 | | I/O | | | |
33 | * | D7 | B 15 | | I/O | | | |
34 | * | ME | C 13 | P | O | | | |
35 | * | RD | B 0 | P | O | | | |
36 | * | WR | B 1 | P | O | | | |
37 | * | BUSREQ | D 2 | | O | | | |
38 | * | IOCS1 | A 11 | | I | TIM1_CH4 | | |
39 | * | BUSACK | A 12 | | I | | | |
40 | * | HALT | A 12 | | I | | | |
41 | * | NMI | B 7 | | O | | | |
42 | * | RST | B 6 | | O | TIM16_CH1N | | |
43 | * | | | | | | | |
44 | * | | A 9 | | | af1 USART1_TX | | |
45 | * | | A 10 | | | af1 USART1_RX | | |
46 | * | | A 15 | | JTDI | remap SPI1_NSS' | | |
47 | * | | B 3 | | JTDO | remap SPI1_SCK' | | |
48 | * | | B 4 | |NJTRST | remap SPI1_MISO' | | |
49 | * | | B 5 | | | remap SPI1_MOSI' | | |
50 | * | | C 14 | | | af1 OSC32 | | |
51 | * | | C 15 | | | af1 OSC32 | | |
52 | ||
53 | ||
54 | AFIO_MAPR2 = | |
55 | AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON (frees | |
56 | AFIO_MAPR_SPI1_REMAP | |
57 | ||
58 | */ | |
59 | ||
acd9bdaf L |
60 | /** |
61 | * | |
62 | * Pin assignments | |
63 | * | |
64 | * | Z180-Sig | STM32-Port | Buffer | Dir |Special Function | | |
65 | * | -------- | ---------- | ------ | --- | --------------- | | |
66 | * | A0 |A 1 |P |O | | | |
67 | * | A1 |A 2 |P |O | | | |
68 | * | A2 |A 3 |P |O | | | |
69 | * | A3 |A 4 |P |O | | | |
70 | * | A4 |A 5 |P |O | | | |
71 | * | A5 |A 6 |P |O | | | |
72 | * | A6 |A 7 |P |O | | | |
73 | * | A7 |A 8 | |O | | | |
74 | * | A8 |C 0 |P |O | | | |
75 | * | A9 |C 1 |P |O | | | |
76 | * | A10 |C 2 |P |O | | | |
77 | * | A11 |C 3 |P |O | | | |
78 | * | A12 |C 4 |P |O | | | |
79 | * | A13 |C 5 |P |O | | | |
80 | * | A14 |C 6 | |O | | | |
81 | * | A15 |C 7 | |O | | | |
82 | * | A16 |C 10 | |O | | | |
83 | * | A17 |C 11 | |O | | | |
84 | * | A18 |C 12 | |O | | | |
85 | * | D0 |B 8 | |I/O | | | |
86 | * | D1 |B 9 | |I/O | | | |
87 | * | D2 |B 10 | |I/O | | | |
88 | * | D3 |B 11 | |I/O | | | |
89 | * | D4 |B 12 | |I/O | | | |
90 | * | D5 |B 13 | |I/O | | | |
91 | * | D6 |B 14 | |I/O | | | |
92 | * | D7 |B 15 | |I/O | | | |
93 | * | ME |C 13 |P |O | | | |
94 | * | RD |B 0 |P |O | | | |
95 | * | WR |B 1 |P |O | | | |
96 | * | BUSREQ |D 2 | |O | | | |
97 | * | IOCS1 |A 11 | |I |TIM1_CH4 | | |
98 | * | BUSACK |A 12 | |I | | | |
99 | * | HALT |A 12 | |I | | | |
100 | * | NMI |B 7 | |O | | | |
101 | * | RST |B 6 | |O |TIM16_CH1N | | |
102 | * | | | | | | | |
103 | * | |A 9 | | |af1 USART1_TX | | |
104 | * | |A 10 | | |af1 USART1_RX | | |
105 | * | |A 15 | |JTDI | remap SPI1_NSS' | | |
106 | * | |B 3 | |JTDO |remap SPI1_SCK' | | |
107 | * | |B 4 | |NJTRST |remap SPI1_MISO' | | |
108 | * | |B 5 | | |remap SPI1_MOSI' | | |
109 | * | |C 14 | | |af1 OSC32 | | |
110 | * | |C 15 | | |af1 OSC32 | | |
e64eba00 | 111 | |
e64eba00 L |
112 | |
113 | AFIO_MAPR2 = | |
114 | AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON (frees | |
115 | AFIO_MAPR_SPI1_REMAP | |
116 | ||
acd9bdaf L |
117 | */ |
118 | ||
6b81b39f L |
119 | #include <stdio.h> |
120 | ||
e64eba00 L |
121 | |
122 | #include <libopencm3/stm32/gpio.h> | |
123 | #include <libopencm3/stm32/rcc.h> | |
124 | #include <libopencm3/stm32/timer.h> | |
125 | #include <libopencm3/stm32/dma.h> | |
6b81b39f | 126 | #include "debug.h" |
e64eba00 L |
127 | #include "z80-if.h" |
128 | ||
6b81b39f | 129 | |
e64eba00 L |
130 | /* Number of array elements */ |
131 | #define NELEMS(x) (sizeof x/sizeof *x) | |
132 | ||
133 | #define ODR 0x0c | |
134 | #define IDR 0x08 | |
135 | ||
136 | #define CONCAT(x,y) x ## y | |
137 | #define EVALUATOR(x,y) CONCAT(x,y) | |
138 | ||
139 | #define GPIO_(X) CONCAT(GPIO, X) | |
140 | ||
e64eba00 | 141 | |
e64eba00 | 142 | |
e64eba00 L |
143 | |
144 | #define P_ME GPIOC | |
145 | #define ME 13 | |
146 | #define P_RD GPIOB | |
147 | #define RD 0 | |
148 | #define P_WR GPIOB | |
149 | #define WR 1 | |
150 | #define P_BUSREQ GPIOD | |
151 | #define BUSREQ 2 | |
152 | #define P_BUSACK GPIOA | |
acd9bdaf | 153 | #define BUSACK 12 |
e64eba00 L |
154 | //#define P_HALT GPIOA |
155 | //#define HALT 12 | |
acd9bdaf L |
156 | #define P_IOCS1 GPIOA |
157 | #define IOCS1 11 | |
e64eba00 L |
158 | #define P_NMI GPIOB |
159 | #define NMI 7 | |
160 | #define P_RST GPIOB | |
161 | #define RST 6 | |
162 | ||
163 | #define ADp1_OFS 0 | |
164 | #define ADp1_WIDTH 8 | |
165 | #define ADp1_SHIFT 1 | |
166 | #define ADp1_PORT GPIOA | |
167 | ||
168 | #define ADp2_OFS ADp1_WIDTH | |
169 | #define ADp2_WIDTH 8 | |
170 | #define ADp2_SHIFT 0 | |
171 | #define ADp2_PORT GPIOC | |
172 | ||
173 | #define ADp3_OFS (ADp2_OFS+ADp2_WIDTH) | |
174 | #define ADp3_WIDTH 3 | |
175 | #define ADp3_SHIFT 10 | |
176 | #define ADp3_PORT GPIOC | |
177 | ||
178 | #define ADunbuff1_WIDTH 1 | |
179 | #define ADunbuff1_SHIFT 8 | |
180 | #define ADunbuff1_PORT GPIOA | |
181 | ||
182 | #define ADunbuff2_WIDTH 2 | |
183 | #define ADunbuff2_SHIFT 6 | |
184 | #define ADunbuff2_PORT GPIOC | |
185 | ||
186 | #define ADunbuff3_WIDTH 3 | |
187 | #define ADunbuff3_SHIFT 10 | |
188 | #define ADunbuff3_PORT GPIOC | |
189 | ||
190 | #define DB_OFS 0 | |
191 | #define DB_WIDTH 8 | |
192 | #define DB_SHIFT 8 | |
193 | #define DB_PORT GPIOB | |
194 | ||
195 | #define GPIO_ME GPIO_(ME) | |
196 | #define GPIO_RD GPIO_(RD) | |
197 | #define GPIO_WR GPIO_(WR) | |
198 | #define GPIO_BUSREQ GPIO_(BUSREQ) | |
199 | #define GPIO_BUSACK GPIO_(BUSACK) | |
200 | //#define GPIO_HALT GPIO_(HALT) | |
acd9bdaf | 201 | #define GPIO_IOCS1 GPIO_(IOCS1) |
e64eba00 L |
202 | #define GPIO_NMI GPIO_(NMI) |
203 | #define GPIO_RST GPIO_(RST) | |
204 | ||
205 | #define Z80_O_ME BBIO_PERIPH(P_ME+ODR, ME) | |
206 | #define Z80_O_RD BBIO_PERIPH(P_RD+ODR, RD) | |
207 | #define Z80_O_WR BBIO_PERIPH(P_WR+ODR, WR) | |
208 | #define Z80_O_BUSREQ BBIO_PERIPH(P_BUSREQ+ODR, BUSREQ) | |
209 | #define Z80_O_NMI BBIO_PERIPH(P_NMI+ODR, NMI) | |
210 | #define Z80_O_RST BBIO_PERIPH(P_RST+ODR, RST) | |
211 | ||
212 | #define Z80_I_BUSACK BBIO_PERIPH(P_BUSACK+IDR, BUSACK) | |
213 | //#define Z80_I_HALT BBIO_PERIPH(P_HALT+IDR, HALT) | |
214 | ||
215 | ||
216 | #define MASK(n) ((1<<n)-1) | |
217 | ||
218 | #define IOFIELD_SET(src, ofs, width, shift) \ | |
219 | ((((src>>ofs) & MASK(width)) << shift) | ((((~src>>ofs) & MASK(width)) << shift) << 16)) | |
220 | ||
221 | #define IOFIELD_GET(src, width, shift) \ | |
222 | ((src>>shift) & MASK(width)) | |
223 | ||
224 | #define CNF_MODE_I_F (GPIO_CNF_INPUT_FLOAT<<2 |GPIO_MODE_INPUT) | |
225 | #define CNF_MODE_O_PP (GPIO_CNF_OUTPUT_PUSHPULL<<2 | GPIO_MODE_OUTPUT_10_MHZ) | |
226 | ||
227 | #define DB_MODE_INPUT ( (CNF_MODE_I_F << (4 * 0)) \ | |
228 | | (CNF_MODE_I_F << (4 * 1)) \ | |
229 | | (CNF_MODE_I_F << (4 * 2)) \ | |
230 | | (CNF_MODE_I_F << (4 * 3)) \ | |
231 | | (CNF_MODE_I_F << (4 * 4)) \ | |
232 | | (CNF_MODE_I_F << (4 * 5)) \ | |
233 | | (CNF_MODE_I_F << (4 * 6)) \ | |
234 | | (CNF_MODE_I_F << (4 * 7))) | |
235 | ||
236 | #define DB_MODE_OUTPUT ( (CNF_MODE_O_PP << (4 * 0)) \ | |
237 | | (CNF_MODE_O_PP << (4 * 1)) \ | |
238 | | (CNF_MODE_O_PP << (4 * 2)) \ | |
239 | | (CNF_MODE_O_PP << (4 * 3)) \ | |
240 | | (CNF_MODE_O_PP << (4 * 4)) \ | |
241 | | (CNF_MODE_O_PP << (4 * 5)) \ | |
242 | | (CNF_MODE_O_PP << (4 * 6)) \ | |
243 | | (CNF_MODE_O_PP << (4 * 7))) | |
244 | ||
245 | ||
246 | /*--------------------------------------------------------------------------*/ | |
247 | ||
e64eba00 L |
248 | static void tim16_setup(void) |
249 | { | |
acd9bdaf L |
250 | RCC_APB2RSTR |= RCC_APB2RSTR_TIM16RST; |
251 | RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM16RST; | |
e64eba00 L |
252 | |
253 | TIM16_BDTR = TIM_BDTR_MOE; | |
254 | ||
255 | TIM16_CCMR1 = 0 | |
256 | | TIM_CCMR1_OC1M_FORCE_LOW | |
e64eba00 L |
257 | | TIM_CCMR1_CC1S_OUT; |
258 | ||
259 | TIM16_CCER = TIM_CCER_CC1NE | |
260 | | TIM_CCER_CC1NP; | |
261 | ||
262 | TIM16_ARR = 48; /* default */ | |
263 | TIM16_CCR1 = 1; /* */ | |
264 | } | |
265 | ||
266 | /*--------------------------------------------------------------------------*/ | |
267 | ||
acd9bdaf | 268 | static void tim16_set(int mode) |
e64eba00 L |
269 | { |
270 | uint16_t cc_mode; | |
271 | ||
272 | cc_mode = TIM_CCMR1_CC1S_OUT; | |
273 | ||
274 | TIM16_CR1 = TIM_CR1_OPM; | |
275 | ||
276 | if (mode < 0) | |
277 | cc_mode |= TIM_CCMR1_OC1M_FORCE_LOW; | |
278 | else if (mode == 0) | |
279 | cc_mode |= TIM_CCMR1_OC1M_FORCE_HIGH; | |
280 | else { | |
281 | TIM16_ARR = mode; | |
282 | cc_mode |= TIM_CCMR1_OC1M_PWM2; | |
283 | } | |
284 | ||
285 | TIM16_CCMR1 = cc_mode; | |
286 | ||
287 | if (mode > 0) | |
288 | TIM16_CR1 |= TIM_CR1_CEN; | |
289 | } | |
290 | ||
291 | /*--------------------------------------------------------------------------*/ | |
292 | ||
293 | ||
294 | ||
295 | /* | |
296 | * A0..A6, A8..A13 are buffered. No need to disable. | |
297 | * A7, A14..A18: set to input. | |
298 | */ | |
299 | ||
300 | static void z80_setup_adrbus_tristate(void) | |
301 | { | |
302 | #if 0 | |
303 | gpio_set_mode(ADunbuff1_PORT, GPIO_MODE_INPUT, | |
304 | GPIO_CNF_INPUT_FLOAT, MASK(ADunbuff1_WIDTH) << ADunbuff1_SHIFT); | |
305 | gpio_set_mode(ADunbuff2_PORT, GPIO_MODE_INPUT, GPIO_CNF_INPUT_FLOAT, | |
306 | (MASK(ADunbuff2_WIDTH) << ADunbuff2_SHIFT) | (MASK(ADunbuff3_WIDTH) << ADunbuff3_SHIFT)); | |
307 | #else | |
308 | GPIO_CRH(GPIOA) = (GPIO_CRH(GPIOA) & ~(0x0f << (4 * 0))) | |
309 | | (CNF_MODE_I_F << (4 * 0)); | |
310 | GPIO_CRL(GPIOC) = (GPIO_CRL(GPIOC) & ~((0x0f << (4 * 6)) | (0x0f << (4 * 7)))) | |
311 | | ((CNF_MODE_I_F << (4 * 6)) | (CNF_MODE_I_F << (4 * 7))); | |
312 | GPIO_CRH(GPIOC) = (GPIO_CRH(GPIOC) & ~((0x0f << (4*2)) | (0x0f << (4*3)) | (0x0f << (4*4)))) | |
313 | | ((CNF_MODE_I_F << (4*2)) | (CNF_MODE_I_F << (4*3)) | (CNF_MODE_I_F << (4*4))); | |
314 | #endif | |
315 | } | |
316 | ||
317 | ||
318 | static void z80_setup_adrbus_active(void) | |
319 | { | |
320 | #if 0 | |
321 | gpio_set_mode(ADunbuff1_PORT, GPIO_MODE_OUTPUT_10_MHZ, | |
322 | GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADunbuff1_WIDTH) << ADunbuff1_SHIFT); | |
323 | gpio_set_mode(ADunbuff2_PORT, GPIO_MODE_OUTPUT_10_MHZ, GPIO_CNF_OUTPUT_PUSHPULL, | |
324 | (MASK(ADunbuff2_WIDTH) << ADunbuff2_SHIFT) | (MASK(ADunbuff3_WIDTH) << ADunbuff3_SHIFT)); | |
325 | #else | |
326 | GPIO_CRH(GPIOA) = (GPIO_CRH(GPIOA) & ~(0x0f << (4 * 0))) | |
327 | | (CNF_MODE_O_PP << (4 * 0)); | |
328 | GPIO_CRL(GPIOC) = (GPIO_CRL(GPIOC) & ~((0x0f << (4 * 6)) | (0x0f << (4 * 7)))) | |
329 | | ((CNF_MODE_O_PP << (4 * 6)) | (CNF_MODE_O_PP << (4 * 7))); | |
330 | GPIO_CRH(GPIOC) = (GPIO_CRH(GPIOC) & ~((0x0f << (4*2)) | (0x0f << (4*3)) | (0x0f << (4*4)))) | |
331 | | ((CNF_MODE_O_PP << (4*2)) | (CNF_MODE_O_PP << (4*3)) | (CNF_MODE_O_PP << (4*4))); | |
332 | #endif | |
333 | } | |
334 | ||
335 | ||
336 | static void z80_setup_dbus_in(void) | |
337 | { | |
338 | GPIO_CRH(DB_PORT) = DB_MODE_INPUT; | |
339 | } | |
340 | ||
341 | static void z80_setup_dbus_out(void) | |
342 | { | |
343 | GPIO_CRH(DB_PORT) = DB_MODE_OUTPUT; | |
344 | } | |
345 | ||
346 | ||
347 | static void z80_setaddress(uint32_t addr) | |
348 | { | |
349 | GPIO_BSRR(ADp1_PORT) = IOFIELD_SET(addr, ADp1_OFS, ADp1_WIDTH, ADp1_SHIFT); | |
350 | GPIO_BSRR(ADp2_PORT) = IOFIELD_SET(addr, ADp2_OFS, ADp2_WIDTH, ADp2_SHIFT); | |
351 | GPIO_BSRR(ADp3_PORT) = IOFIELD_SET(addr, ADp3_OFS, ADp3_WIDTH, ADp3_SHIFT); | |
352 | } | |
353 | ||
354 | void z80_setup_bus(void) | |
355 | { | |
356 | tim16_setup(); | |
acd9bdaf | 357 | |
e64eba00 L |
358 | gpio_set_mode(P_RST, GPIO_MODE_OUTPUT_10_MHZ, |
359 | GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO_RST); | |
360 | Z80_O_BUSREQ = 1; | |
361 | gpio_set_mode(P_BUSREQ, GPIO_MODE_OUTPUT_10_MHZ, | |
362 | GPIO_CNF_OUTPUT_PUSHPULL, GPIO_BUSREQ); | |
363 | Z80_O_NMI = 1; | |
364 | gpio_set_mode(P_NMI, GPIO_MODE_OUTPUT_10_MHZ, | |
365 | GPIO_CNF_OUTPUT_PUSHPULL, GPIO_NMI); | |
366 | Z80_O_ME = 1; | |
367 | Z80_O_RD = 1; | |
368 | Z80_O_WR = 1; | |
369 | gpio_set_mode(P_ME, GPIO_MODE_OUTPUT_2_MHZ, | |
370 | GPIO_CNF_OUTPUT_PUSHPULL, GPIO_ME); | |
371 | gpio_set_mode(P_RD, GPIO_MODE_OUTPUT_10_MHZ, | |
372 | GPIO_CNF_OUTPUT_PUSHPULL, GPIO_RD | GPIO_WR); | |
373 | ||
e64eba00 L |
374 | //Z80_O_BUSREQ = 0; |
375 | //while(Z80_I_BUSACK == 1); | |
376 | ||
377 | gpio_set_mode(ADp1_PORT, GPIO_MODE_OUTPUT_10_MHZ, | |
378 | GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADp1_WIDTH) << ADp1_SHIFT); | |
379 | gpio_set_mode(ADp2_PORT, GPIO_MODE_OUTPUT_10_MHZ, | |
380 | GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADp2_WIDTH) << ADp2_SHIFT); | |
381 | gpio_set_mode(ADp3_PORT, GPIO_MODE_OUTPUT_10_MHZ, | |
382 | GPIO_CNF_OUTPUT_PUSHPULL, MASK(ADp3_WIDTH) << ADp3_SHIFT); | |
383 | ||
384 | z80_setup_dbus_in(); | |
385 | } | |
386 | ||
acd9bdaf | 387 | void z80_request_bus(void) |
e64eba00 L |
388 | { |
389 | Z80_O_BUSREQ = 0; | |
390 | while(Z80_I_BUSACK == 1); | |
391 | z80_setup_adrbus_active(); | |
392 | } | |
393 | ||
394 | void z80_release_bus(void) | |
395 | { | |
396 | z80_setup_dbus_in(); | |
397 | z80_setup_adrbus_tristate(); | |
398 | Z80_O_BUSREQ = 1; | |
399 | while(Z80_I_BUSACK == 0); | |
400 | } | |
401 | ||
402 | void z80_reset(level_t level) | |
403 | { | |
404 | int x = level ? -1 : 0; | |
405 | ||
406 | tim16_set(x); | |
407 | ||
408 | // Z80_O_RST = level; | |
409 | } | |
410 | ||
411 | void z80_reset_pulse(void) | |
412 | { | |
413 | tim16_set(48); | |
414 | } | |
415 | ||
416 | void z80_busreq(level_t level) | |
417 | { | |
418 | Z80_O_BUSREQ = level; | |
419 | } | |
420 | ||
421 | #if 0 | |
422 | int z80_stat_halt(void) | |
423 | { | |
424 | return Z80_I_HALT; | |
425 | } | |
426 | #endif | |
427 | ||
428 | void z80_write(uint32_t addr, uint8_t data) | |
429 | { | |
430 | z80_setaddress(addr); | |
431 | Z80_O_ME = 0; | |
432 | GPIO_BSRR(DB_PORT) = IOFIELD_SET(data, DB_OFS, DB_WIDTH, DB_SHIFT); | |
433 | z80_setup_dbus_out(); | |
434 | Z80_O_WR = 0; | |
435 | Z80_O_WR = 1; | |
436 | Z80_O_ME = 1; | |
437 | } | |
438 | ||
439 | uint8_t z80_read(uint32_t addr) | |
440 | { | |
441 | uint8_t data; | |
442 | ||
443 | z80_setaddress(addr); | |
444 | Z80_O_ME = 0; | |
445 | z80_setup_dbus_in(); | |
446 | Z80_O_RD = 0; | |
447 | Z80_O_RD = 0; | |
448 | data = IOFIELD_GET(GPIO_IDR(DB_PORT),DB_WIDTH, DB_SHIFT); | |
449 | Z80_O_RD = 1; | |
450 | Z80_O_ME = 1; | |
451 | ||
452 | return data; | |
453 | } | |
454 | ||
455 | ||
456 | void z80_memset(uint32_t addr, uint8_t data, int length) | |
457 | { | |
458 | z80_setup_dbus_out(); | |
459 | Z80_O_ME = 0; | |
460 | while(length--) { | |
461 | z80_setaddress(addr++); | |
462 | GPIO_BSRR(DB_PORT) = IOFIELD_SET(data, DB_OFS, DB_WIDTH, DB_SHIFT); | |
463 | Z80_O_WR = 0; | |
464 | Z80_O_WR = 1; | |
465 | } | |
466 | Z80_O_ME = 1; | |
467 | } | |
468 | ||
469 | void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length) | |
470 | { | |
471 | uint8_t data; | |
472 | ||
473 | z80_setup_dbus_out(); | |
474 | Z80_O_ME = 0; | |
475 | while(length--) { | |
476 | z80_setaddress(dest++); | |
477 | data = *src++; | |
478 | GPIO_BSRR(DB_PORT) = IOFIELD_SET(data, DB_OFS, DB_WIDTH, DB_SHIFT); | |
479 | Z80_O_WR = 0; | |
480 | Z80_O_WR = 1; | |
481 | } | |
482 | Z80_O_ME = 1; | |
483 | } | |
484 | ||
485 | /* | |
486 | 0179' rx.bs_mask: ds 1 ; (buf_len - 1) | |
487 | 017A' rx.in_idx: ds 1 ; | |
488 | 017B' rx.out_idx: ds 1 ; | |
489 | 017C' rx.buf: ds rx.buf_len ; | |
490 | 018B' rx.buf_end equ $-1 ; last byte (start+len-1) | |
491 | ||
492 | 018C' tx.bs_mask: ds 1 ; (buf_len - 1) | |
493 | 018D' tx.in_idx: ds 1 ; | |
494 | 018E' tx.out_idx: ds 1 ; | |
495 | 018F' tx.buf: ds tx.buf_len ; | |
496 | 019E' tx.buf_end equ $-1 ; last byte | |
497 | */ | |
498 | ||
e64eba00 | 499 | |
6b81b39f L |
500 | typedef struct __attribute__((packed)) { |
501 | uint8_t mask; | |
502 | uint8_t in_idx; | |
503 | uint8_t out_idx; | |
504 | uint8_t buf[]; | |
505 | } zfifo_t; | |
506 | ||
507 | ||
508 | ||
509 | #define FIFO_BUFSIZE_MASK -3 | |
510 | #define FIFO_INDEX_IN -2 | |
511 | #define FIFO_INDEX_OUT -1 | |
512 | ||
e64eba00 L |
513 | |
514 | static struct { | |
515 | uint32_t base; | |
516 | uint8_t idx_out, | |
517 | idx_in, | |
518 | mask; | |
6b81b39f | 519 | } fifo_dsc[NUM_FIFOS]; |
e64eba00 | 520 | |
6b81b39f L |
521 | |
522 | void z80_memfifo_init(const fifo_t f, uint32_t adr) | |
e64eba00 | 523 | { |
6b81b39f L |
524 | |
525 | DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, adr); | |
526 | ||
527 | fifo_dsc[f].base = adr; | |
528 | ||
acd9bdaf | 529 | z80_request_bus(); |
6b81b39f L |
530 | |
531 | fifo_dsc[f].mask = z80_read(adr + FIFO_BUFSIZE_MASK); | |
532 | fifo_dsc[f].idx_in = z80_read(adr + FIFO_INDEX_IN); | |
533 | fifo_dsc[f].idx_out = z80_read(adr + FIFO_INDEX_OUT); | |
534 | ||
e64eba00 L |
535 | z80_release_bus(); |
536 | } | |
e64eba00 | 537 | |
6b81b39f L |
538 | |
539 | int z80_memfifo_is_empty(const fifo_t f) | |
e64eba00 | 540 | { |
6b81b39f L |
541 | int rc = 1; |
542 | ||
543 | if (fifo_dsc[f].base != 0) { | |
544 | ||
545 | uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN; | |
546 | uint8_t idx; | |
547 | ||
548 | z80_request_bus(); | |
549 | idx = z80_read(adr); | |
550 | z80_release_bus(); | |
551 | rc = idx == fifo_dsc[f].idx_out; | |
552 | } | |
e64eba00 | 553 | |
6b81b39f | 554 | return rc; |
e64eba00 L |
555 | } |
556 | ||
6b81b39f | 557 | int z80_memfifo_is_full(const fifo_t f) |
e64eba00 | 558 | { |
6b81b39f | 559 | int rc = 1; |
e64eba00 | 560 | |
6b81b39f L |
561 | if (fifo_dsc[f].base != 0) { |
562 | z80_request_bus(); | |
563 | rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask) | |
564 | == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT); | |
565 | z80_release_bus(); | |
566 | } | |
e64eba00 L |
567 | return rc; |
568 | } | |
569 | ||
6b81b39f | 570 | uint8_t z80_memfifo_getc(const fifo_t f) |
e64eba00 L |
571 | { |
572 | uint8_t rc, idx; | |
573 | ||
acd9bdaf | 574 | while (z80_memfifo_is_empty(f)) |
e64eba00 L |
575 | ; |
576 | ||
acd9bdaf L |
577 | z80_request_bus(); |
578 | idx = fifo_dsc[f].idx_out; | |
579 | rc = z80_read(fifo_dsc[f].base+idx); | |
580 | fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask; | |
6b81b39f | 581 | z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out); |
e64eba00 L |
582 | z80_release_bus(); |
583 | ||
584 | return rc; | |
585 | } | |
586 | ||
587 | ||
acd9bdaf | 588 | void z80_memfifo_putc(fifo_t f, uint8_t val) |
e64eba00 L |
589 | { |
590 | int idx; | |
591 | ||
acd9bdaf | 592 | while (z80_memfifo_is_full(f)) |
e64eba00 L |
593 | ; |
594 | ||
acd9bdaf L |
595 | z80_request_bus(); |
596 | idx = fifo_dsc[f].idx_in; | |
597 | z80_write(fifo_dsc[f].base+idx, val); | |
598 | fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask; | |
6b81b39f | 599 | z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in); |
e64eba00 L |
600 | z80_release_bus(); |
601 | } | |
602 | ||
acd9bdaf L |
603 | /*--------------------------------------------------------------------------*/ |
604 | ||
acd9bdaf | 605 | static struct { |
6b81b39f L |
606 | uint32_t base; |
607 | //uint8_t idx_out, idx_in; | |
acd9bdaf L |
608 | uint16_t count; |
609 | uint8_t buf[256]; | |
6b81b39f | 610 | } msg_fifo; |
acd9bdaf L |
611 | |
612 | /*--------------------------------------------------------------------------*/ | |
613 | ||
6b81b39f L |
614 | #if 0 |
615 | ||
acd9bdaf L |
616 | static void tim1_setup(void) |
617 | { | |
618 | RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST; | |
619 | RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST; | |
620 | ||
621 | TIM1_CR1 = 0; | |
622 | ||
623 | TIM1_SMCR = 0 | |
624 | /* | TIM_SMCR_ETP */ | |
625 | /* | TIM_SMCR_ETF_CK_INT_N_2 */ | |
626 | | TIM_SMCR_TS_ETRF | |
627 | | TIM_SMCR_SMS_OFF | |
628 | ; | |
629 | ||
630 | TIM1_DIER = TIM_DIER_TDE; | |
631 | ||
632 | ||
633 | TIM1_CCMR1 = 0 | |
634 | | TIM_CCMR1_OC1M_FORCE_LOW | |
635 | | TIM_CCMR1_CC1S_OUT; | |
636 | ||
637 | TIM1_SMCR |= TIM_SMCR_SMS_TM; | |
638 | } | |
639 | ||
6b81b39f L |
640 | #endif |
641 | ||
acd9bdaf L |
642 | /*--------------------------------------------------------------------------*/ |
643 | ||
644 | static void tim1_ch4_setup(void) | |
645 | { | |
646 | /* Reset Timer 1 */ | |
647 | RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST; | |
648 | RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST; | |
649 | ||
650 | TIM1_CCMR2 = 0 | |
651 | | TIM_CCMR2_CC4S_IN_TI2 | |
652 | | TIM_CCMR2_IC4F_OFF | |
653 | | TIM_CCMR2_IC4PSC_OFF; | |
654 | ||
655 | TIM1_CCER = 0 | |
656 | /* | TIM_CCER_CC4P */ | |
657 | | TIM_CCER_CC4E; | |
658 | ||
659 | /* Enable DMA for channel 4 */ | |
660 | TIM1_DIER = TIM_DIER_CC4DE; | |
661 | } | |
662 | ||
663 | /*--------------------------------------------------------------------------*/ | |
664 | ||
665 | static void dma1_ch4_setup(void) | |
666 | { | |
667 | DMA1_CCR4 = | |
668 | DMA_CCR_PL_VERY_HIGH | |
669 | | DMA_CCR_MSIZE_8BIT | |
670 | | DMA_CCR_PSIZE_8BIT | |
671 | | DMA_CCR_MINC | |
672 | | DMA_CCR_CIRC; | |
673 | ||
6b81b39f | 674 | DMA1_CMAR4 = (uint32_t) msg_fifo.buf; |
acd9bdaf L |
675 | |
676 | #if (DB_SHIFT == 0) || (DB_SHIFT == 8) | |
677 | DMA1_CPAR4 = DB_PORT + IDR + DB_SHIFT/8; | |
678 | #else | |
679 | #error "Databus not byte aligned!" | |
680 | #endif | |
681 | ||
6b81b39f L |
682 | DMA1_CNDTR4 = NELEMS(msg_fifo.buf); |
683 | // msg_fifo.count = NELEMS(msg_fifo.buf); | |
684 | msg_fifo.count = 0; | |
685 | msg_fifo.base = 0; | |
acd9bdaf L |
686 | |
687 | DMA1_CCR4 |= DMA_CCR_EN; | |
688 | } | |
689 | ||
690 | /*--------------------------------------------------------------------------*/ | |
691 | ||
6b81b39f | 692 | void z80_setup_msg_fifo(void) |
acd9bdaf L |
693 | { |
694 | gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT, | |
695 | GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1); | |
696 | ||
697 | tim1_ch4_setup(); | |
698 | dma1_ch4_setup(); | |
699 | } | |
700 | ||
701 | ||
6b81b39f L |
702 | void z80_init_msg_fifo(uint32_t addr) |
703 | { | |
704 | ||
705 | DBG_P(1, "z80_init_msg_fifo: %lx\n", addr); | |
706 | ||
707 | z80_request_bus(); | |
708 | z80_write(addr+FIFO_INDEX_OUT, z80_read(addr+FIFO_INDEX_IN)); | |
709 | z80_release_bus(); | |
710 | msg_fifo.base = addr; | |
711 | } | |
712 | ||
713 | ||
714 | int z80_msg_fifo_getc(void) | |
e64eba00 L |
715 | { |
716 | int c = -1; | |
717 | ||
6b81b39f L |
718 | if (msg_fifo.count != (NELEMS(msg_fifo.buf) - DMA1_CNDTR4)) { |
719 | c = msg_fifo.buf[msg_fifo.count]; | |
720 | if (++msg_fifo.count == NELEMS(msg_fifo.buf)) | |
721 | msg_fifo.count = 0; | |
722 | ||
723 | if (msg_fifo.base != 0) { | |
724 | z80_request_bus(); | |
725 | z80_write(msg_fifo.base+FIFO_INDEX_OUT, msg_fifo.count); | |
726 | z80_release_bus(); | |
727 | } | |
e64eba00 L |
728 | } |
729 | ||
730 | return c; | |
731 | } |