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