]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z80-if.c
First real hardware test.
[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 PIN_BUSACK PIND
99 #define BUSACK 6
100 #define DDR_BUSACK DDRD
101 //#define P_HALT PORTA
102 //#define HALT 12
103 #define P_IOCS1 PORTE
104 #define IOCS1 5
105 #define DDR_IOCS1 DDRE
106 //#define P_NMI PORTB
107 //#define NMI 7
108 #define P_RST PORTD
109 #define DDR_RST DDRD
110 #define RST 5
111
112
113 #define P_DB PORTF
114 #define PIN_DB PINF
115 #define DDR_DB DDRF
116
117 #define P_ADL PORTA
118 #define P_ADH PORTC
119 #define P_ADB PORTE
120 #define PIN_ADB PINE
121 #define DDR_ADL DDRA
122 #define DDR_ADH DDRC
123 #define DDR_ADB DDRE
124
125 #define ADB_WIDTH 3
126 #define ADB_SHIFT 2
127 //#define ADB_PORT PORTE
128
129
130 #define Z80_O_MREQ SBIT(P_MREQ, 4)
131 #define Z80_O_RD SBIT(P_RD, 3)
132 #define Z80_O_WR SBIT(P_WR, 2)
133 #define Z80_O_BUSREQ SBIT(P_BUSREQ, 7)
134 //#define Z80_O_NMI SBIT(P_NMI, )
135 #define Z80_O_RST SBIT(P_RST, 5)
136 #define Z80_I_BUSACK SBIT(PIN_BUSACK, 6)
137 //#define Z80_I_HALT SBIT(P_HALT, )
138
139
140 void z80_busreq(level_t level)
141 {
142 Z80_O_BUSREQ = level;
143 }
144
145 void z80_reset(level_t level)
146 {
147 Z80_O_RST = level;
148 }
149
150
151 void z80_reset_pulse(void)
152 {
153 Z80_O_RST = 0;
154 _delay_us(10);
155 Z80_O_RST = 1;
156 }
157
158 #if 0
159 int z80_stat_halt(void)
160 {
161 return Z80_I_HALT;
162 }
163 #endif
164
165
166 #define MASK(n) ((1<<(n))-1)
167 #define SMASK(w,s) (MASK(w) << (s))
168
169
170
171 typedef union {
172 uint32_t l;
173 uint16_t w[2];
174 uint8_t b[4];
175 } addr_t;
176
177
178 /*--------------------------------------------------------------------------*/
179
180
181 static void z80_setup_addrbus_tristate(void)
182 {
183 /* /MREQ, /RD, /WR: Input, no pullup */
184 DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
185 Z80_O_MREQ = 0;
186 Z80_O_RD = 0;
187 Z80_O_WR = 0;
188
189 P_ADL = 0;
190 DDR_ADL = 0;
191 P_ADH = 0;
192 DDR_ADH = 0;
193 PIN_ADB = P_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
194 DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
195 }
196
197
198 static void z80_setup_addrbus_active(void)
199 {
200 /* /MREQ, /RD, /WR: Output and high */
201 Z80_O_MREQ = 1;
202 Z80_O_RD = 1;
203 Z80_O_WR = 1;
204 DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
205
206 DDR_ADL = 0xff;
207 DDR_ADH = 0xff;
208 DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
209 }
210
211
212
213 static void z80_setup_dbus_in(void)
214 {
215 DDR_DB = 0;
216 P_DB = 0;
217 }
218
219 static void z80_setup_dbus_out(void)
220 {
221 DDR_DB = 0xff;
222 }
223
224 void z80_setup_bus(void)
225 {
226 /* /ZRESET: Output and low */
227 Z80_O_RST = 0;
228 DDR_RST |= _BV(RST);
229
230 /* /BUSREQ: Output and high */
231 Z80_O_BUSREQ = 1;
232 DDR_BUSREQ |= _BV(BUSREQ);
233
234 /* /BUSACK: Input, no pullup */
235 DDR_BUSACK &= ~_BV(BUSACK);
236 P_BUSACK &= ~_BV(BUSACK);
237
238 /* /IOCS1: Input, no pullup */
239 DDR_IOCS1 &= ~_BV(IOCS1);
240 P_IOCS1 &= ~_BV(IOCS1);
241
242 z80_setup_addrbus_tristate();
243 z80_setup_dbus_in();
244 }
245
246 /*--------------------------------------------------------------------------*/
247
248 void z80_request_bus(void)
249 {
250 Z80_O_BUSREQ = 0;
251 while(Z80_I_BUSACK == 1);
252 z80_setup_addrbus_active();
253 }
254
255 void z80_release_bus(void)
256 {
257 z80_setup_dbus_in();
258 z80_setup_addrbus_tristate();
259 Z80_O_BUSREQ = 1;
260 //while(Z80_I_BUSACK == 0);
261 }
262
263 /*--------------------------------------------------------------------------*/
264
265 static
266 //inline __attribute__ ((always_inline))
267 void z80_setaddress(uint32_t addr)
268 {
269 addr_t x; x.l = addr;
270
271 P_ADL = x.b[0];
272 P_ADH = x.b[1];
273 PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ;
274 }
275
276 void z80_write(uint32_t addr, uint8_t data)
277 {
278 z80_setaddress(addr);
279 Z80_O_MREQ = 0;
280 z80_setup_dbus_out();
281 P_DB = data;
282 P_DB = data;
283 Z80_O_WR = 0;
284 Z80_O_WR = 0;
285 Z80_O_WR = 1;
286 Z80_O_MREQ = 1;
287 }
288
289 uint8_t z80_read(uint32_t addr)
290 {
291 uint8_t data;
292
293 z80_setaddress(addr);
294 Z80_O_MREQ = 0;
295 z80_setup_dbus_in();
296 Z80_O_RD = 0;
297 Z80_O_RD = 0;
298 Z80_O_RD = 0;
299 data = PIN_DB;
300 Z80_O_RD = 1;
301 Z80_O_MREQ = 1;
302
303 return data;
304 }
305
306
307 void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
308 {
309 z80_setup_dbus_out();
310 Z80_O_MREQ = 0;
311 while(length--) {
312 z80_setaddress(addr++);
313 P_DB = data;
314 P_DB = data;
315 Z80_O_WR = 0;
316 Z80_O_WR = 0;
317 Z80_O_WR = 1;
318 }
319 Z80_O_MREQ = 1;
320 }
321
322 void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
323 {
324 uint8_t data;
325
326 z80_setup_dbus_out();
327 Z80_O_MREQ = 0;
328 while(length--) {
329 z80_setaddress(dest++);
330 data = *src++;
331 P_DB = data;
332 P_DB = data;
333 Z80_O_WR = 0;
334 Z80_O_WR = 0;
335 Z80_O_WR = 1;
336 }
337 Z80_O_MREQ = 1;
338 }
339
340 /*
341 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
342 017A' rx.in_idx: ds 1 ;
343 017B' rx.out_idx: ds 1 ;
344 017C' rx.buf: ds rx.buf_len ;
345 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
346
347 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
348 018D' tx.in_idx: ds 1 ;
349 018E' tx.out_idx: ds 1 ;
350 018F' tx.buf: ds tx.buf_len ;
351 019E' tx.buf_end equ $-1 ; last byte
352 */
353
354
355 typedef struct __attribute__((packed)) {
356 uint8_t mask;
357 uint8_t in_idx;
358 uint8_t out_idx;
359 uint8_t buf[];
360 } zfifo_t;
361
362
363
364 #define FIFO_BUFSIZE_MASK -3
365 #define FIFO_INDEX_IN -2
366 #define FIFO_INDEX_OUT -1
367
368
369 static struct {
370 uint32_t base;
371 uint8_t idx_out,
372 idx_in,
373 mask;
374 } fifo_dsc[NUM_FIFOS];
375
376
377 void z80_memfifo_init(const fifo_t f, uint32_t adr)
378 {
379
380 DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, adr);
381
382 fifo_dsc[f].base = adr;
383
384 z80_request_bus();
385
386 fifo_dsc[f].mask = z80_read(adr + FIFO_BUFSIZE_MASK);
387 fifo_dsc[f].idx_in = z80_read(adr + FIFO_INDEX_IN);
388 fifo_dsc[f].idx_out = z80_read(adr + FIFO_INDEX_OUT);
389
390 z80_release_bus();
391 }
392
393
394 int z80_memfifo_is_empty(const fifo_t f)
395 {
396 int rc = 1;
397
398 if (fifo_dsc[f].base != 0) {
399
400 uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
401 uint8_t idx;
402
403 z80_request_bus();
404 idx = z80_read(adr);
405 z80_release_bus();
406 rc = idx == fifo_dsc[f].idx_out;
407 }
408
409 return rc;
410 }
411
412 int z80_memfifo_is_full(const fifo_t f)
413 {
414 int rc = 1;
415
416 if (fifo_dsc[f].base != 0) {
417 z80_request_bus();
418 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
419 == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
420 z80_release_bus();
421 }
422 return rc;
423 }
424
425 uint8_t z80_memfifo_getc(const fifo_t f)
426 {
427 uint8_t rc, idx;
428
429 while (z80_memfifo_is_empty(f))
430 ;
431
432 z80_request_bus();
433 idx = fifo_dsc[f].idx_out;
434 rc = z80_read(fifo_dsc[f].base+idx);
435 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
436 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
437 z80_release_bus();
438
439 return rc;
440 }
441
442
443 void z80_memfifo_putc(fifo_t f, uint8_t val)
444 {
445 int idx;
446
447 while (z80_memfifo_is_full(f))
448 ;
449
450 z80_request_bus();
451 idx = fifo_dsc[f].idx_in;
452 z80_write(fifo_dsc[f].base+idx, val);
453 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
454 z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
455 z80_release_bus();
456 }
457
458 /*--------------------------------------------------------------------------*/
459
460 static struct {
461 uint32_t base;
462 //uint8_t idx_out, idx_in;
463 uint16_t count;
464 uint8_t buf[256];
465 } msg_fifo;
466
467 /*--------------------------------------------------------------------------*/
468
469 #if 0
470
471 static void tim1_setup(void)
472 {
473 RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
474 RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST;
475
476 TIM1_CR1 = 0;
477
478 TIM1_SMCR = 0
479 /* | TIM_SMCR_ETP */
480 /* | TIM_SMCR_ETF_CK_INT_N_2 */
481 | TIM_SMCR_TS_ETRF
482 | TIM_SMCR_SMS_OFF
483 ;
484
485 TIM1_DIER = TIM_DIER_TDE;
486
487
488 TIM1_CCMR1 = 0
489 | TIM_CCMR1_OC1M_FORCE_LOW
490 | TIM_CCMR1_CC1S_OUT;
491
492 TIM1_SMCR |= TIM_SMCR_SMS_TM;
493 }
494
495 #endif
496
497 /*--------------------------------------------------------------------------*/
498
499 void z80_setup_msg_fifo(void)
500 {
501 // gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
502 // GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1);
503
504 //...
505
506 // msg_fifo.count = NELEMS(msg_fifo.buf);
507 msg_fifo.count = 0;
508 msg_fifo.base = 0;
509
510 }
511
512
513 void z80_init_msg_fifo(uint32_t addr)
514 {
515
516 DBG_P(1, "z80_init_msg_fifo: %lx\n", addr);
517
518 z80_request_bus();
519 z80_write(addr+FIFO_INDEX_OUT, z80_read(addr+FIFO_INDEX_IN));
520 z80_release_bus();
521 msg_fifo.base = addr;
522 }
523
524
525 int z80_msg_fifo_getc(void)
526 {
527 int c = -1;
528
529 #if 0
530 if (msg_fifo.count != (NELEMS(msg_fifo.buf) /*- DMA1_CNDTR4 */ )) {
531 c = msg_fifo.buf[msg_fifo.count];
532 if (++msg_fifo.count == NELEMS(msg_fifo.buf))
533 msg_fifo.count = 0;
534
535 if (msg_fifo.base != 0) {
536 z80_request_bus();
537 z80_write(msg_fifo.base+FIFO_INDEX_OUT, msg_fifo.count);
538 z80_release_bus();
539 }
540 }
541 #endif
542
543 return c;
544 }