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