]> cloudbase.mooo.com Git - z180-stamp.git/blame - avr/z80-if.c
Merge tag 'fatfs-0.10b'
[z180-stamp.git] / avr / z80-if.c
CommitLineData
0c5890bb
L
1/**
2 *
3 * Pin assignments
4 *
72f58822 5 * | Z180-Sig | AVR-Port | Dir | Special Function |
0c5890bb
L
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>
f338df2a 58#include <util/atomic.h>
0c5890bb
L
59#include <stdio.h>
60#include "debug.h"
61#include "z80-if.h"
62
63
64/* Number of array elements */
65#define NELEMS(x) (sizeof x/sizeof *x)
66
67
68#define CONCAT(x,y) x ## y
69#define EVALUATOR(x,y) CONCAT(x,y)
70
71#define GPIO_(X) CONCAT(GPIO, X)
72
73struct bits {
74 uint8_t b0:1;
75 uint8_t b1:1;
76 uint8_t b2:1;
77 uint8_t b3:1;
78 uint8_t b4:1;
79 uint8_t b5:1;
80 uint8_t b6:1;
81 uint8_t b7:1;
82} __attribute__((__packed__));
83
84#define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin)
85
86
87
88#define P_MREQ PORTD
89#define MREQ 4
90#define DDR_MREQ DDRD
91#define P_RD PORTD
92#define RD 3
93#define P_WR PORTD
94#define WR 2
95#define P_BUSREQ PORTD
96#define BUSREQ 7
97#define DDR_BUSREQ DDRD
98#define P_BUSACK PORTD
9b6b4b31 99#define PIN_BUSACK PIND
0c5890bb
L
100#define BUSACK 6
101#define DDR_BUSACK DDRD
102//#define P_HALT PORTA
103//#define HALT 12
104#define P_IOCS1 PORTE
105#define IOCS1 5
106#define DDR_IOCS1 DDRE
107//#define P_NMI PORTB
108//#define NMI 7
109#define P_RST PORTD
110#define DDR_RST DDRD
111#define RST 5
112
113
114#define P_DB PORTF
115#define PIN_DB PINF
116#define DDR_DB DDRF
117
118#define P_ADL PORTA
119#define P_ADH PORTC
120#define P_ADB PORTE
121#define PIN_ADB PINE
9b6b4b31
L
122#define DDR_ADL DDRA
123#define DDR_ADH DDRC
0c5890bb
L
124#define DDR_ADB DDRE
125
126#define ADB_WIDTH 3
127#define ADB_SHIFT 2
128//#define ADB_PORT PORTE
129
130
0c5890bb
L
131#define Z80_O_MREQ SBIT(P_MREQ, 4)
132#define Z80_O_RD SBIT(P_RD, 3)
133#define Z80_O_WR SBIT(P_WR, 2)
134#define Z80_O_BUSREQ SBIT(P_BUSREQ, 7)
135//#define Z80_O_NMI SBIT(P_NMI, )
136#define Z80_O_RST SBIT(P_RST, 5)
9b6b4b31 137#define Z80_I_BUSACK SBIT(PIN_BUSACK, 6)
0c5890bb
L
138//#define Z80_I_HALT SBIT(P_HALT, )
139
9b6b4b31 140
0c5890bb
L
141#define MASK(n) ((1<<(n))-1)
142#define SMASK(w,s) (MASK(w) << (s))
143
144
145
eded7ec4
L
146typedef union {
147 uint32_t l;
148 uint16_t w[2];
149 uint8_t b[4];
150} addr_t;
f338df2a
L
151
152
153static zstate_t zstate;
eded7ec4 154
0c5890bb
L
155/*--------------------------------------------------------------------------*/
156
157
9b6b4b31 158static void z80_setup_addrbus_tristate(void)
0c5890bb 159{
9b6b4b31
L
160 /* /MREQ, /RD, /WR: Input, no pullup */
161 DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
162 Z80_O_MREQ = 0;
163 Z80_O_RD = 0;
164 Z80_O_WR = 0;
165
0c5890bb
L
166 P_ADL = 0;
167 DDR_ADL = 0;
168 P_ADH = 0;
169 DDR_ADH = 0;
9b6b4b31 170 PIN_ADB = P_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
0c5890bb
L
171 DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
172}
173
174
9b6b4b31 175static void z80_setup_addrbus_active(void)
0c5890bb 176{
9b6b4b31
L
177 /* /MREQ, /RD, /WR: Output and high */
178 Z80_O_MREQ = 1;
179 Z80_O_RD = 1;
180 Z80_O_WR = 1;
181 DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
182
0c5890bb
L
183 DDR_ADL = 0xff;
184 DDR_ADH = 0xff;
185 DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
186}
187
188
0c5890bb
L
189static void z80_setup_dbus_in(void)
190{
191 DDR_DB = 0;
192 P_DB = 0;
193}
194
62f624d3 195
0c5890bb
L
196static void z80_setup_dbus_out(void)
197{
198 DDR_DB = 0xff;
199}
200
62f624d3
L
201
202static void z80_reset_pulse(void)
203{
204 Z80_O_RST = 0;
205 _delay_us(10);
206 Z80_O_RST = 1;
207}
208
209
0c5890bb
L
210void z80_setup_bus(void)
211{
9b6b4b31 212 /* /ZRESET: Output and low */
0c5890bb
L
213 Z80_O_RST = 0;
214 DDR_RST |= _BV(RST);
215
9b6b4b31 216 /* /BUSREQ: Output and high */
0c5890bb
L
217 Z80_O_BUSREQ = 1;
218 DDR_BUSREQ |= _BV(BUSREQ);
219
9b6b4b31 220 /* /BUSACK: Input, no pullup */
0c5890bb
L
221 DDR_BUSACK &= ~_BV(BUSACK);
222 P_BUSACK &= ~_BV(BUSACK);
223
9b6b4b31 224 /* /IOCS1: Input, no pullup */
0c5890bb
L
225 DDR_IOCS1 &= ~_BV(IOCS1);
226 P_IOCS1 &= ~_BV(IOCS1);
227
9b6b4b31 228 z80_setup_addrbus_tristate();
0c5890bb 229 z80_setup_dbus_in();
72f58822 230
f338df2a 231 zstate = RESET;
0c5890bb
L
232}
233
f338df2a 234
62f624d3 235zstate_t z80_bus_state(void)
f338df2a
L
236{
237 return zstate;
238}
239
62f624d3
L
240
241static void z80_busreq_hpulse(void)
0c5890bb
L
242{
243 z80_setup_dbus_in();
9b6b4b31 244 z80_setup_addrbus_tristate();
72f58822 245
62f624d3
L
246 ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
247 Z80_O_BUSREQ = 1;
248 Z80_O_BUSREQ = 1; /* 2 AVR clock cycles */
249 Z80_O_BUSREQ = 0; /* 2 AVR clock cycles */
f338df2a 250 }
72f58822 251
62f624d3 252 if (zstate & ZST_ACQUIRED) {
f338df2a
L
253 while(Z80_I_BUSACK == 1)
254 ;
255 z80_setup_addrbus_active();
f338df2a 256 }
f338df2a
L
257}
258
f338df2a
L
259
260/*
f338df2a 261
62f624d3
L
262 + | | | | |
263 + State | RESET | RESET_AQRD | RUNNING | RUNNING_AQRD |
264 + | | | | |
265 + | 0 | 1 | 2 | 3 |
266Event + | | | | |
267----------------+---------------+---------------+---------------+---------------+
268 | | | | |
269Reset | 0 | 0 | 0 | 0 |
270 | | | | |
271 | | | | |
272Request | 1 | | 3 | |
273 | | | | |
274 | | | | |
275Release | | 0 | | 2 |
276 | | | | |
277 | | | | |
278Run | 2 | 3 | | |
279 | | | | |
280 | | | | |
281Restart | | | 2 | 3 |
282 | | | | |
283 | | | | |
284M_Cycle | | | | 3 |
285 | | | | |
286 | | | | |
287*/
f338df2a 288
62f624d3 289zstate_t z80_bus_cmd(bus_cmd_t cmd)
f338df2a 290{
62f624d3 291 switch (cmd) {
f338df2a 292
62f624d3 293 case Reset:
f338df2a
L
294 z80_setup_dbus_in();
295 z80_setup_addrbus_tristate();
296 Z80_O_RST = 0;
62f624d3
L
297 Z80_O_BUSREQ = 1;
298 zstate = RESET;
f338df2a
L
299 break;
300
62f624d3
L
301 case Request:
302 switch (zstate) {
303 case RESET:
304 Z80_O_BUSREQ = 0;
305 Z80_O_RST = 1;
306 while(Z80_I_BUSACK == 1)
307 ;
308 z80_setup_addrbus_active();
309 zstate = RESET_AQRD;
310 break;
311
312 case RUNNING:
313 Z80_O_BUSREQ = 0;
314 while(Z80_I_BUSACK == 1)
315 ;
316 z80_setup_addrbus_active();
317 zstate = RUNNING_AQRD;
318 break;
319
320 default:
321 break;
322 }
f338df2a 323 break;
f338df2a 324
62f624d3
L
325 case Release:
326 switch (zstate) {
327 case RESET_AQRD:
328 z80_setup_dbus_in();
329 z80_setup_addrbus_tristate();
330 Z80_O_RST = 0;
331 Z80_O_BUSREQ = 1;
332 zstate = RESET;
333 break;
334 case RUNNING_AQRD:
335 z80_setup_dbus_in();
336 z80_setup_addrbus_tristate();
337 Z80_O_BUSREQ = 1;
338 zstate = RUNNING;
339 break;
340 default:
341 break;
342 }
343 break;
f338df2a 344
62f624d3
L
345 case Run:
346 switch (zstate) {
347 case RESET:
348 Z80_O_RST = 1;
349 zstate = RUNNING;
350 break;
351
352 case RESET_AQRD:
353 z80_setup_dbus_in();
354 z80_setup_addrbus_tristate();
355 z80_reset_pulse();
356 z80_setup_addrbus_active();
357 zstate = RUNNING_AQRD;
358 break;
359 default:
360 break;
361 }
362 break;
f338df2a 363
62f624d3
L
364 case Restart:
365 switch (zstate) {
366 case RUNNING:
367 case RUNNING_AQRD:
368 z80_reset_pulse();
369 break;
370 default:
371 break;
372 }
373 break;
f338df2a 374
62f624d3
L
375 case M_Cycle:
376 switch (zstate) {
377 case RUNNING_AQRD:
378 z80_busreq_hpulse();
379 break;
380 default:
381 break;
382 }
f338df2a 383 }
62f624d3 384 return zstate;
9b6b4b31
L
385}
386
62f624d3 387
9b6b4b31
L
388/*--------------------------------------------------------------------------*/
389
390static
391//inline __attribute__ ((always_inline))
392void z80_setaddress(uint32_t addr)
393{
394 addr_t x; x.l = addr;
395
396 P_ADL = x.b[0];
397 P_ADH = x.b[1];
398 PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ;
0c5890bb
L
399}
400
401void z80_write(uint32_t addr, uint8_t data)
402{
403 z80_setaddress(addr);
404 Z80_O_MREQ = 0;
0c5890bb 405 z80_setup_dbus_out();
9b6b4b31
L
406 P_DB = data;
407 P_DB = data;
408 Z80_O_WR = 0;
0c5890bb
L
409 Z80_O_WR = 0;
410 Z80_O_WR = 1;
411 Z80_O_MREQ = 1;
412}
413
414uint8_t z80_read(uint32_t addr)
415{
416 uint8_t data;
417
418 z80_setaddress(addr);
419 Z80_O_MREQ = 0;
420 z80_setup_dbus_in();
421 Z80_O_RD = 0;
422 Z80_O_RD = 0;
9b6b4b31 423 Z80_O_RD = 0;
0c5890bb
L
424 data = PIN_DB;
425 Z80_O_RD = 1;
426 Z80_O_MREQ = 1;
427
428 return data;
429}
430
431
432void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
433{
434 z80_setup_dbus_out();
435 Z80_O_MREQ = 0;
436 while(length--) {
437 z80_setaddress(addr++);
438 P_DB = data;
9b6b4b31
L
439 P_DB = data;
440 Z80_O_WR = 0;
0c5890bb
L
441 Z80_O_WR = 0;
442 Z80_O_WR = 1;
443 }
444 Z80_O_MREQ = 1;
445}
446
9b6b4b31 447void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
0c5890bb
L
448{
449 uint8_t data;
450
451 z80_setup_dbus_out();
452 Z80_O_MREQ = 0;
453 while(length--) {
454 z80_setaddress(dest++);
455 data = *src++;
456 P_DB = data;
9b6b4b31
L
457 P_DB = data;
458 Z80_O_WR = 0;
0c5890bb
L
459 Z80_O_WR = 0;
460 Z80_O_WR = 1;
461 }
462 Z80_O_MREQ = 1;
463}
464
465/*
466 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
467 017A' rx.in_idx: ds 1 ;
468 017B' rx.out_idx: ds 1 ;
469 017C' rx.buf: ds rx.buf_len ;
470 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
471
472 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
473 018D' tx.in_idx: ds 1 ;
474 018E' tx.out_idx: ds 1 ;
475 018F' tx.buf: ds tx.buf_len ;
476 019E' tx.buf_end equ $-1 ; last byte
477*/
478
479
480typedef struct __attribute__((packed)) {
481 uint8_t mask;
482 uint8_t in_idx;
483 uint8_t out_idx;
484 uint8_t buf[];
485} zfifo_t;
486
487
488
489#define FIFO_BUFSIZE_MASK -3
490#define FIFO_INDEX_IN -2
491#define FIFO_INDEX_OUT -1
492
493
494static struct {
495 uint32_t base;
496 uint8_t idx_out,
497 idx_in,
498 mask;
499 } fifo_dsc[NUM_FIFOS];
500
501
502void z80_memfifo_init(const fifo_t f, uint32_t adr)
503{
504
505DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, adr);
506
507 fifo_dsc[f].base = adr;
508
62f624d3 509 z80_bus_cmd(Request);
0c5890bb
L
510
511 fifo_dsc[f].mask = z80_read(adr + FIFO_BUFSIZE_MASK);
512 fifo_dsc[f].idx_in = z80_read(adr + FIFO_INDEX_IN);
513 fifo_dsc[f].idx_out = z80_read(adr + FIFO_INDEX_OUT);
514
62f624d3 515 z80_bus_cmd(Release);
0c5890bb
L
516}
517
518
519int z80_memfifo_is_empty(const fifo_t f)
520{
521 int rc = 1;
522
523 if (fifo_dsc[f].base != 0) {
524
525 uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
526 uint8_t idx;
527
62f624d3 528 z80_bus_cmd(Request);
0c5890bb 529 idx = z80_read(adr);
62f624d3 530 z80_bus_cmd(Release);
0c5890bb
L
531 rc = idx == fifo_dsc[f].idx_out;
532 }
533
534 return rc;
535}
536
537int z80_memfifo_is_full(const fifo_t f)
538{
539 int rc = 1;
540
541 if (fifo_dsc[f].base != 0) {
62f624d3 542 z80_bus_cmd(Request);
0c5890bb
L
543 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
544 == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
62f624d3 545 z80_bus_cmd(Release);
0c5890bb
L
546 }
547 return rc;
548}
549
550uint8_t z80_memfifo_getc(const fifo_t f)
551{
552 uint8_t rc, idx;
553
554 while (z80_memfifo_is_empty(f))
555 ;
556
62f624d3 557 z80_bus_cmd(Request);
0c5890bb
L
558 idx = fifo_dsc[f].idx_out;
559 rc = z80_read(fifo_dsc[f].base+idx);
560 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
561 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
62f624d3 562 z80_bus_cmd(Release);
0c5890bb
L
563
564 return rc;
565}
566
567
568void z80_memfifo_putc(fifo_t f, uint8_t val)
569{
570 int idx;
571
572 while (z80_memfifo_is_full(f))
573 ;
574
62f624d3 575 z80_bus_cmd(Request);
0c5890bb
L
576 idx = fifo_dsc[f].idx_in;
577 z80_write(fifo_dsc[f].base+idx, val);
578 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
579 z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
62f624d3 580 z80_bus_cmd(Release);
0c5890bb
L
581}
582
583/*--------------------------------------------------------------------------*/
72f58822
L
584/*
585 TODO: Rewrite msg_fifo routines for AVR
586*/
0c5890bb
L
587
588static struct {
589 uint32_t base;
590 //uint8_t idx_out, idx_in;
591 uint16_t count;
592 uint8_t buf[256];
593 } msg_fifo;
594
595/*--------------------------------------------------------------------------*/
596
597#if 0
598
599static void tim1_setup(void)
600{
601 RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
602 RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST;
603
604 TIM1_CR1 = 0;
605
606 TIM1_SMCR = 0
607 /* | TIM_SMCR_ETP */
608 /* | TIM_SMCR_ETF_CK_INT_N_2 */
609 | TIM_SMCR_TS_ETRF
610 | TIM_SMCR_SMS_OFF
611 ;
612
613 TIM1_DIER = TIM_DIER_TDE;
614
615
616 TIM1_CCMR1 = 0
617 | TIM_CCMR1_OC1M_FORCE_LOW
618 | TIM_CCMR1_CC1S_OUT;
619
620 TIM1_SMCR |= TIM_SMCR_SMS_TM;
621}
622
623#endif
624
625/*--------------------------------------------------------------------------*/
626
627void z80_setup_msg_fifo(void)
628{
629// gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
630// GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1);
631
632//...
633
634// msg_fifo.count = NELEMS(msg_fifo.buf);
635 msg_fifo.count = 0;
636 msg_fifo.base = 0;
637
638}
639
640
641void z80_init_msg_fifo(uint32_t addr)
642{
643
644DBG_P(1, "z80_init_msg_fifo: %lx\n", addr);
645
62f624d3 646 z80_bus_cmd(Request);
0c5890bb 647 z80_write(addr+FIFO_INDEX_OUT, z80_read(addr+FIFO_INDEX_IN));
62f624d3 648 z80_bus_cmd(Release);
0c5890bb
L
649 msg_fifo.base = addr;
650}
651
652
653int z80_msg_fifo_getc(void)
654{
655 int c = -1;
656
9b6b4b31 657#if 0
0c5890bb
L
658 if (msg_fifo.count != (NELEMS(msg_fifo.buf) /*- DMA1_CNDTR4 */ )) {
659 c = msg_fifo.buf[msg_fifo.count];
660 if (++msg_fifo.count == NELEMS(msg_fifo.buf))
661 msg_fifo.count = 0;
662
663 if (msg_fifo.base != 0) {
62f624d3 664 z80_bus_cmd(Request);
0c5890bb 665 z80_write(msg_fifo.base+FIFO_INDEX_OUT, msg_fifo.count);
62f624d3 666 z80_bus_cmd(Release);
0c5890bb
L
667 }
668 }
9b6b4b31 669#endif
0c5890bb
L
670
671 return c;
672}