]> cloudbase.mooo.com Git - z180-stamp.git/blame - avr/z80-if.c
New U-Boot like AVR main program.
[z180-stamp.git] / avr / z80-if.c
CommitLineData
0c5890bb
L
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
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
0c5890bb
L
140void z80_busreq(level_t level)
141{
142 Z80_O_BUSREQ = level;
143}
144
145void z80_reset(level_t level)
146{
147 Z80_O_RST = level;
148}
149
150
151void z80_reset_pulse(void)
152{
153 Z80_O_RST = 0;
154 _delay_us(10);
155 Z80_O_RST = 1;
156}
157
158#if 0
159int 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
eded7ec4
L
171typedef union {
172 uint32_t l;
173 uint16_t w[2];
174 uint8_t b[4];
175} addr_t;
176
177
0c5890bb
L
178/*--------------------------------------------------------------------------*/
179
180
9b6b4b31 181static void z80_setup_addrbus_tristate(void)
0c5890bb 182{
9b6b4b31
L
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
0c5890bb
L
189 P_ADL = 0;
190 DDR_ADL = 0;
191 P_ADH = 0;
192 DDR_ADH = 0;
9b6b4b31 193 PIN_ADB = P_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
0c5890bb
L
194 DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
195}
196
197
9b6b4b31 198static void z80_setup_addrbus_active(void)
0c5890bb 199{
9b6b4b31
L
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
0c5890bb
L
206 DDR_ADL = 0xff;
207 DDR_ADH = 0xff;
208 DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
209}
210
211
212
213static void z80_setup_dbus_in(void)
214{
215 DDR_DB = 0;
216 P_DB = 0;
217}
218
219static void z80_setup_dbus_out(void)
220{
221 DDR_DB = 0xff;
222}
223
0c5890bb
L
224void z80_setup_bus(void)
225{
9b6b4b31 226 /* /ZRESET: Output and low */
0c5890bb
L
227 Z80_O_RST = 0;
228 DDR_RST |= _BV(RST);
229
9b6b4b31 230 /* /BUSREQ: Output and high */
0c5890bb
L
231 Z80_O_BUSREQ = 1;
232 DDR_BUSREQ |= _BV(BUSREQ);
233
9b6b4b31 234 /* /BUSACK: Input, no pullup */
0c5890bb
L
235 DDR_BUSACK &= ~_BV(BUSACK);
236 P_BUSACK &= ~_BV(BUSACK);
237
9b6b4b31 238 /* /IOCS1: Input, no pullup */
0c5890bb
L
239 DDR_IOCS1 &= ~_BV(IOCS1);
240 P_IOCS1 &= ~_BV(IOCS1);
241
9b6b4b31 242 z80_setup_addrbus_tristate();
0c5890bb
L
243 z80_setup_dbus_in();
244}
245
9b6b4b31
L
246/*--------------------------------------------------------------------------*/
247
0c5890bb
L
248void z80_request_bus(void)
249{
250 Z80_O_BUSREQ = 0;
251 while(Z80_I_BUSACK == 1);
9b6b4b31 252 z80_setup_addrbus_active();
0c5890bb
L
253}
254
255void z80_release_bus(void)
256{
257 z80_setup_dbus_in();
9b6b4b31 258 z80_setup_addrbus_tristate();
0c5890bb 259 Z80_O_BUSREQ = 1;
9b6b4b31
L
260 //while(Z80_I_BUSACK == 0);
261}
262
263/*--------------------------------------------------------------------------*/
264
265static
266//inline __attribute__ ((always_inline))
267void 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 ;
0c5890bb
L
274}
275
276void z80_write(uint32_t addr, uint8_t data)
277{
278 z80_setaddress(addr);
279 Z80_O_MREQ = 0;
0c5890bb 280 z80_setup_dbus_out();
9b6b4b31
L
281 P_DB = data;
282 P_DB = data;
283 Z80_O_WR = 0;
0c5890bb
L
284 Z80_O_WR = 0;
285 Z80_O_WR = 1;
286 Z80_O_MREQ = 1;
287}
288
289uint8_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;
9b6b4b31 298 Z80_O_RD = 0;
0c5890bb
L
299 data = PIN_DB;
300 Z80_O_RD = 1;
301 Z80_O_MREQ = 1;
302
303 return data;
304}
305
306
307void 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;
9b6b4b31
L
314 P_DB = data;
315 Z80_O_WR = 0;
0c5890bb
L
316 Z80_O_WR = 0;
317 Z80_O_WR = 1;
318 }
319 Z80_O_MREQ = 1;
320}
321
9b6b4b31 322void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
0c5890bb
L
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;
9b6b4b31
L
332 P_DB = data;
333 Z80_O_WR = 0;
0c5890bb
L
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
355typedef 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
369static struct {
370 uint32_t base;
371 uint8_t idx_out,
372 idx_in,
373 mask;
374 } fifo_dsc[NUM_FIFOS];
375
376
377void z80_memfifo_init(const fifo_t f, uint32_t adr)
378{
379
380DBG_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
394int 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
412int 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
425uint8_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
443void 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
460static 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
471static 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
499void 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
513void z80_init_msg_fifo(uint32_t addr)
514{
515
516DBG_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
525int z80_msg_fifo_getc(void)
526{
527 int c = -1;
528
9b6b4b31 529#if 0
0c5890bb
L
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 }
9b6b4b31 541#endif
0c5890bb
L
542
543 return c;
544}