]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z80-if.c
Refactor Tupfiles
[z180-stamp.git] / avr / z80-if.c
1 /**
2 *
3 * Pin assignments
4 *
5 * | Z180-Sig | AVR-Port | Dir | Special Function |
6 * +------------+---------------+-------+-----------------------+
7 * | A0 | PA 0 | O | |
8 * | A1 | PA 1 | O | |
9 * | A2 | PA 2 | O | |
10 * | A3 | PA 3 | O | |
11 * | A4 | PA 4 | O | |
12 * | A5 | PA 5 | O | |
13 * | A6 | PA 6 | O | |
14 * | A7 | PA 7 | O | |
15 * | A8 | PC 0 | O | |
16 * | A9 | PC 1 | O | |
17 * | A10 | PC 2 | O | |
18 * | A11 | PC 3 | O | |
19 * | A12 | PC 4 | O | |
20 * | A13 | PC 5 | O | |
21 * | A14 | PC 6 | O | |
22 * | A15 | PC 7 | O | |
23 * | A16 | PE 2 | O | |
24 * | A17 | PE 3 | O | |
25 * | A18 | PE 4 | O | |
26 * | D0 | PF 0 | I/O | |
27 * | D1 | PF 1 | I/O | |
28 * | D2 | PF 2 | I/O | |
29 * | D3 | PF 3 | I/O | |
30 * | D4 | PF 4 | I/O | |
31 * | D5 | PF 5 | I/O | |
32 * | D6 | PF 6 | I/O | |
33 * | D7 | PF 7 | I/O | |
34 * | RD | PD 3 | O | |
35 * | WR | PD 2 | O | |
36 * | MREQ | PD 4 | O | |
37 * | RST | PD 5 | O | |
38 * | BUSREQ | PD 7 | O | |
39 * | BUSACK | PD 6 | I | |
40 * | IOCS1 | PE 5 | I | |
41 * |* HALT | P | | |
42 * |* NMI | P | | |
43 * | | P | | |
44 * | | P | | af1 USART1_TX |
45 * | | P | | af1 USART1_RX |
46 * | | P |JTDI | remap SPI1_NSS' |
47 * | | P |JTDO | remap SPI1_SCK' |
48 * | | P |JTRST | remap SPI1_MISO' |
49 * | | P | | remap SPI1_MOSI' |
50 * | | P | | af1 OSC32 |
51 * | | P | | af1 OSC32 |
52
53
54 */
55
56 #include <avr/io.h>
57 #include <util/delay.h>
58 #include <stdio.h>
59 #include "debug.h"
60 #include "z80-if.h"
61
62
63 /* Number of array elements */
64 #define NELEMS(x) (sizeof x/sizeof *x)
65
66
67 #define CONCAT(x,y) x ## y
68 #define EVALUATOR(x,y) CONCAT(x,y)
69
70 #define GPIO_(X) CONCAT(GPIO, X)
71
72 struct bits {
73 uint8_t b0:1;
74 uint8_t b1:1;
75 uint8_t b2:1;
76 uint8_t b3:1;
77 uint8_t b4:1;
78 uint8_t b5:1;
79 uint8_t b6:1;
80 uint8_t b7:1;
81 } __attribute__((__packed__));
82
83 #define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin)
84
85
86
87 #define P_MREQ PORTD
88 #define MREQ 4
89 #define DDR_MREQ DDRD
90 #define P_RD PORTD
91 #define RD 3
92 #define P_WR PORTD
93 #define WR 2
94 #define P_BUSREQ PORTD
95 #define BUSREQ 7
96 #define DDR_BUSREQ DDRD
97 #define P_BUSACK PORTD
98 #define BUSACK 6
99 #define DDR_BUSACK DDRD
100 //#define P_HALT PORTA
101 //#define HALT 12
102 #define P_IOCS1 PORTE
103 #define IOCS1 5
104 #define DDR_IOCS1 DDRE
105 //#define P_NMI PORTB
106 //#define NMI 7
107 #define P_RST PORTD
108 #define DDR_RST DDRD
109 #define RST 5
110
111
112 #define P_DB PORTF
113 #define PIN_DB PINF
114 #define DDR_DB DDRF
115
116 #define P_ADL PORTA
117 #define P_ADH PORTC
118 #define P_ADB PORTE
119 #define PIN_ADB PINE
120 #define DDR_ADL DDRE
121 #define DDR_ADH DDRE
122 #define DDR_ADB DDRE
123
124 #define ADB_WIDTH 3
125 #define ADB_SHIFT 2
126 //#define ADB_PORT PORTE
127
128
129
130 #define ADp1_OFS 0
131 #define ADp1_WIDTH 8
132 #define ADp1_SHIFT 1
133 #define ADp1_PORT GPIOA
134
135 #define ADp2_OFS ADp1_WIDTH
136 #define ADp2_WIDTH 8
137 #define ADp2_SHIFT 0
138 #define ADp2_PORT GPIOC
139
140 #define ADp3_OFS (ADp2_OFS+ADp2_WIDTH)
141 #define ADp3_WIDTH 3
142 #define ADp3_SHIFT 10
143 #define ADp3_PORT GPIOC
144
145 #define ADunbuff1_WIDTH 1
146 #define ADunbuff1_SHIFT 8
147 #define ADunbuff1_PORT GPIOA
148
149 #define ADunbuff2_WIDTH 2
150 #define ADunbuff2_SHIFT 6
151 #define ADunbuff2_PORT GPIOC
152
153 #define ADunbuff3_WIDTH 3
154 #define ADunbuff3_SHIFT 10
155 #define ADunbuff3_PORT GPIOC
156
157 #define DB_OFS 0
158 #define DB_WIDTH 8
159 #define DB_SHIFT 8
160 #define DB_PORT GPIOB
161
162
163 #define Z80_O_MREQ SBIT(P_MREQ, 4)
164 #define Z80_O_RD SBIT(P_RD, 3)
165 #define Z80_O_WR SBIT(P_WR, 2)
166 #define Z80_O_BUSREQ SBIT(P_BUSREQ, 7)
167 //#define Z80_O_NMI SBIT(P_NMI, )
168 #define Z80_O_RST SBIT(P_RST, 5)
169 #define Z80_I_BUSACK SBIT(P_BUSACK, 6)
170 //#define Z80_I_HALT SBIT(P_HALT, )
171
172 void z80_busreq(level_t level)
173 {
174 Z80_O_BUSREQ = level;
175 }
176
177 void z80_reset(level_t level)
178 {
179 Z80_O_RST = level;
180 }
181
182
183 void z80_reset_pulse(void)
184 {
185 Z80_O_RST = 0;
186 _delay_us(10);
187 Z80_O_RST = 1;
188 }
189
190 #if 0
191 int z80_stat_halt(void)
192 {
193 return Z80_I_HALT;
194 }
195 #endif
196
197
198 #define MASK(n) ((1<<(n))-1)
199 #define SMASK(w,s) (MASK(w) << (s))
200
201
202
203 /*--------------------------------------------------------------------------*/
204
205
206
207 /*
208 * A0..A6, A8..A13 are buffered. No need to disable.
209 * A7, A14..A18: set to input.
210 */
211
212 static void z80_setup_adrbus_tristate(void)
213 {
214 P_ADL = 0;
215 DDR_ADL = 0;
216 P_ADH = 0;
217 DDR_ADH = 0;
218 PIN_ADB = P_ADB & MASK(ADB_WIDTH) << ADB_SHIFT;
219 DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
220 }
221
222
223 static void z80_setup_adrbus_active(void)
224 {
225 DDR_ADL = 0xff;
226 DDR_ADH = 0xff;
227 DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
228 }
229
230
231
232 static void z80_setup_dbus_in(void)
233 {
234 DDR_DB = 0;
235 P_DB = 0;
236 }
237
238 static void z80_setup_dbus_out(void)
239 {
240 DDR_DB = 0xff;
241 }
242
243 static
244 void z80_setaddress(uint32_t addr)
245 {
246 addr_t x; x.l = addr;
247
248 P_ADL = x.b[0];
249 P_ADH = x.b[1];
250 PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ;
251 }
252
253 void z80_setup_bus(void)
254 {
255 Z80_O_RST = 0;
256 DDR_RST |= _BV(RST);
257
258 Z80_O_BUSREQ = 1;
259 DDR_BUSREQ |= _BV(BUSREQ);
260
261 // Z80_O_NMI = 1;
262 // DDR_NMI |= _BV(NMI);
263
264 Z80_O_MREQ = 1;
265 Z80_O_RD = 1;
266 Z80_O_WR = 1;
267 DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
268
269 DDR_BUSACK &= ~_BV(BUSACK);
270 P_BUSACK &= ~_BV(BUSACK);
271
272 DDR_IOCS1 &= ~_BV(IOCS1);
273 P_IOCS1 &= ~_BV(IOCS1);
274
275 //Z80_O_BUSREQ = 0;
276 //while(Z80_I_BUSACK == 1);
277
278 z80_setup_adrbus_tristate();
279 z80_setup_dbus_in();
280 }
281
282 void z80_request_bus(void)
283 {
284 Z80_O_BUSREQ = 0;
285 while(Z80_I_BUSACK == 1);
286 z80_setup_adrbus_active();
287 }
288
289 void z80_release_bus(void)
290 {
291 z80_setup_dbus_in();
292 z80_setup_adrbus_tristate();
293 Z80_O_BUSREQ = 1;
294 while(Z80_I_BUSACK == 0);
295 }
296
297 void z80_write(uint32_t addr, uint8_t data)
298 {
299 z80_setaddress(addr);
300 Z80_O_MREQ = 0;
301 P_DB = data;
302 z80_setup_dbus_out();
303 Z80_O_WR = 0;
304 Z80_O_WR = 1;
305 Z80_O_MREQ = 1;
306 }
307
308 uint8_t z80_read(uint32_t addr)
309 {
310 uint8_t data;
311
312 z80_setaddress(addr);
313 Z80_O_MREQ = 0;
314 z80_setup_dbus_in();
315 Z80_O_RD = 0;
316 Z80_O_RD = 0;
317 data = PIN_DB;
318 Z80_O_RD = 1;
319 Z80_O_MREQ = 1;
320
321 return data;
322 }
323
324
325 void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
326 {
327 z80_setup_dbus_out();
328 Z80_O_MREQ = 0;
329 while(length--) {
330 z80_setaddress(addr++);
331 P_DB = data;
332 Z80_O_WR = 0;
333 Z80_O_WR = 1;
334 }
335 Z80_O_MREQ = 1;
336 }
337
338 void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length)
339 {
340 uint8_t data;
341
342 z80_setup_dbus_out();
343 Z80_O_MREQ = 0;
344 while(length--) {
345 z80_setaddress(dest++);
346 data = *src++;
347 P_DB = data;
348 Z80_O_WR = 0;
349 Z80_O_WR = 1;
350 }
351 Z80_O_MREQ = 1;
352 }
353
354 /*
355 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
356 017A' rx.in_idx: ds 1 ;
357 017B' rx.out_idx: ds 1 ;
358 017C' rx.buf: ds rx.buf_len ;
359 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
360
361 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
362 018D' tx.in_idx: ds 1 ;
363 018E' tx.out_idx: ds 1 ;
364 018F' tx.buf: ds tx.buf_len ;
365 019E' tx.buf_end equ $-1 ; last byte
366 */
367
368
369 typedef struct __attribute__((packed)) {
370 uint8_t mask;
371 uint8_t in_idx;
372 uint8_t out_idx;
373 uint8_t buf[];
374 } zfifo_t;
375
376
377
378 #define FIFO_BUFSIZE_MASK -3
379 #define FIFO_INDEX_IN -2
380 #define FIFO_INDEX_OUT -1
381
382
383 static struct {
384 uint32_t base;
385 uint8_t idx_out,
386 idx_in,
387 mask;
388 } fifo_dsc[NUM_FIFOS];
389
390
391 void z80_memfifo_init(const fifo_t f, uint32_t adr)
392 {
393
394 DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, adr);
395
396 fifo_dsc[f].base = adr;
397
398 z80_request_bus();
399
400 fifo_dsc[f].mask = z80_read(adr + FIFO_BUFSIZE_MASK);
401 fifo_dsc[f].idx_in = z80_read(adr + FIFO_INDEX_IN);
402 fifo_dsc[f].idx_out = z80_read(adr + FIFO_INDEX_OUT);
403
404 z80_release_bus();
405 }
406
407
408 int z80_memfifo_is_empty(const fifo_t f)
409 {
410 int rc = 1;
411
412 if (fifo_dsc[f].base != 0) {
413
414 uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
415 uint8_t idx;
416
417 z80_request_bus();
418 idx = z80_read(adr);
419 z80_release_bus();
420 rc = idx == fifo_dsc[f].idx_out;
421 }
422
423 return rc;
424 }
425
426 int z80_memfifo_is_full(const fifo_t f)
427 {
428 int rc = 1;
429
430 if (fifo_dsc[f].base != 0) {
431 z80_request_bus();
432 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
433 == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
434 z80_release_bus();
435 }
436 return rc;
437 }
438
439 uint8_t z80_memfifo_getc(const fifo_t f)
440 {
441 uint8_t rc, idx;
442
443 while (z80_memfifo_is_empty(f))
444 ;
445
446 z80_request_bus();
447 idx = fifo_dsc[f].idx_out;
448 rc = z80_read(fifo_dsc[f].base+idx);
449 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
450 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
451 z80_release_bus();
452
453 return rc;
454 }
455
456
457 void z80_memfifo_putc(fifo_t f, uint8_t val)
458 {
459 int idx;
460
461 while (z80_memfifo_is_full(f))
462 ;
463
464 z80_request_bus();
465 idx = fifo_dsc[f].idx_in;
466 z80_write(fifo_dsc[f].base+idx, val);
467 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
468 z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
469 z80_release_bus();
470 }
471
472 /*--------------------------------------------------------------------------*/
473
474 static struct {
475 uint32_t base;
476 //uint8_t idx_out, idx_in;
477 uint16_t count;
478 uint8_t buf[256];
479 } msg_fifo;
480
481 /*--------------------------------------------------------------------------*/
482
483 #if 0
484
485 static void tim1_setup(void)
486 {
487 RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
488 RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST;
489
490 TIM1_CR1 = 0;
491
492 TIM1_SMCR = 0
493 /* | TIM_SMCR_ETP */
494 /* | TIM_SMCR_ETF_CK_INT_N_2 */
495 | TIM_SMCR_TS_ETRF
496 | TIM_SMCR_SMS_OFF
497 ;
498
499 TIM1_DIER = TIM_DIER_TDE;
500
501
502 TIM1_CCMR1 = 0
503 | TIM_CCMR1_OC1M_FORCE_LOW
504 | TIM_CCMR1_CC1S_OUT;
505
506 TIM1_SMCR |= TIM_SMCR_SMS_TM;
507 }
508
509 #endif
510
511 /*--------------------------------------------------------------------------*/
512
513 void z80_setup_msg_fifo(void)
514 {
515 // gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
516 // GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1);
517
518 //...
519
520 // msg_fifo.count = NELEMS(msg_fifo.buf);
521 msg_fifo.count = 0;
522 msg_fifo.base = 0;
523
524 }
525
526
527 void z80_init_msg_fifo(uint32_t addr)
528 {
529
530 DBG_P(1, "z80_init_msg_fifo: %lx\n", addr);
531
532 z80_request_bus();
533 z80_write(addr+FIFO_INDEX_OUT, z80_read(addr+FIFO_INDEX_IN));
534 z80_release_bus();
535 msg_fifo.base = addr;
536 }
537
538
539 int z80_msg_fifo_getc(void)
540 {
541 int c = -1;
542
543 if (msg_fifo.count != (NELEMS(msg_fifo.buf) /*- DMA1_CNDTR4 */ )) {
544 c = msg_fifo.buf[msg_fifo.count];
545 if (++msg_fifo.count == NELEMS(msg_fifo.buf))
546 msg_fifo.count = 0;
547
548 if (msg_fifo.base != 0) {
549 z80_request_bus();
550 z80_write(msg_fifo.base+FIFO_INDEX_OUT, msg_fifo.count);
551 z80_release_bus();
552 }
553 }
554
555 return c;
556 }