]> cloudbase.mooo.com Git - z180-stamp.git/blame - avr/z80-if.c
Remove flow control, factor out ring buffer
[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
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
172void z80_busreq(level_t level)
173{
174 Z80_O_BUSREQ = level;
175}
176
177void z80_reset(level_t level)
178{
179 Z80_O_RST = level;
180}
181
182
183void z80_reset_pulse(void)
184{
185 Z80_O_RST = 0;
186 _delay_us(10);
187 Z80_O_RST = 1;
188}
189
190#if 0
191int 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
eded7ec4
L
203typedef union {
204 uint32_t l;
205 uint16_t w[2];
206 uint8_t b[4];
207} addr_t;
208
209
0c5890bb
L
210/*--------------------------------------------------------------------------*/
211
212
213
214/*
215 * A0..A6, A8..A13 are buffered. No need to disable.
216 * A7, A14..A18: set to input.
217 */
218
219static void z80_setup_adrbus_tristate(void)
220{
221 P_ADL = 0;
222 DDR_ADL = 0;
223 P_ADH = 0;
224 DDR_ADH = 0;
225 PIN_ADB = P_ADB & MASK(ADB_WIDTH) << ADB_SHIFT;
226 DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
227}
228
229
230static void z80_setup_adrbus_active(void)
231{
232 DDR_ADL = 0xff;
233 DDR_ADH = 0xff;
234 DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
235}
236
237
238
239static void z80_setup_dbus_in(void)
240{
241 DDR_DB = 0;
242 P_DB = 0;
243}
244
245static void z80_setup_dbus_out(void)
246{
247 DDR_DB = 0xff;
248}
249
250static
251void z80_setaddress(uint32_t addr)
252{
253 addr_t x; x.l = addr;
254
255 P_ADL = x.b[0];
256 P_ADH = x.b[1];
257 PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ;
258}
259
260void z80_setup_bus(void)
261{
262 Z80_O_RST = 0;
263 DDR_RST |= _BV(RST);
264
265 Z80_O_BUSREQ = 1;
266 DDR_BUSREQ |= _BV(BUSREQ);
267
268// Z80_O_NMI = 1;
269// DDR_NMI |= _BV(NMI);
270
271 Z80_O_MREQ = 1;
272 Z80_O_RD = 1;
273 Z80_O_WR = 1;
274 DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
275
276 DDR_BUSACK &= ~_BV(BUSACK);
277 P_BUSACK &= ~_BV(BUSACK);
278
279 DDR_IOCS1 &= ~_BV(IOCS1);
280 P_IOCS1 &= ~_BV(IOCS1);
281
282 //Z80_O_BUSREQ = 0;
283 //while(Z80_I_BUSACK == 1);
284
285 z80_setup_adrbus_tristate();
286 z80_setup_dbus_in();
287}
288
289void z80_request_bus(void)
290{
291 Z80_O_BUSREQ = 0;
292 while(Z80_I_BUSACK == 1);
293 z80_setup_adrbus_active();
294}
295
296void z80_release_bus(void)
297{
298 z80_setup_dbus_in();
299 z80_setup_adrbus_tristate();
300 Z80_O_BUSREQ = 1;
301 while(Z80_I_BUSACK == 0);
302}
303
304void z80_write(uint32_t addr, uint8_t data)
305{
306 z80_setaddress(addr);
307 Z80_O_MREQ = 0;
308 P_DB = data;
309 z80_setup_dbus_out();
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;
324 data = PIN_DB;
325 Z80_O_RD = 1;
326 Z80_O_MREQ = 1;
327
328 return data;
329}
330
331
332void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
333{
334 z80_setup_dbus_out();
335 Z80_O_MREQ = 0;
336 while(length--) {
337 z80_setaddress(addr++);
338 P_DB = data;
339 Z80_O_WR = 0;
340 Z80_O_WR = 1;
341 }
342 Z80_O_MREQ = 1;
343}
344
345void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length)
346{
347 uint8_t data;
348
349 z80_setup_dbus_out();
350 Z80_O_MREQ = 0;
351 while(length--) {
352 z80_setaddress(dest++);
353 data = *src++;
354 P_DB = data;
355 Z80_O_WR = 0;
356 Z80_O_WR = 1;
357 }
358 Z80_O_MREQ = 1;
359}
360
361/*
362 0179' rx.bs_mask: ds 1 ; (buf_len - 1)
363 017A' rx.in_idx: ds 1 ;
364 017B' rx.out_idx: ds 1 ;
365 017C' rx.buf: ds rx.buf_len ;
366 018B' rx.buf_end equ $-1 ; last byte (start+len-1)
367
368 018C' tx.bs_mask: ds 1 ; (buf_len - 1)
369 018D' tx.in_idx: ds 1 ;
370 018E' tx.out_idx: ds 1 ;
371 018F' tx.buf: ds tx.buf_len ;
372 019E' tx.buf_end equ $-1 ; last byte
373*/
374
375
376typedef struct __attribute__((packed)) {
377 uint8_t mask;
378 uint8_t in_idx;
379 uint8_t out_idx;
380 uint8_t buf[];
381} zfifo_t;
382
383
384
385#define FIFO_BUFSIZE_MASK -3
386#define FIFO_INDEX_IN -2
387#define FIFO_INDEX_OUT -1
388
389
390static struct {
391 uint32_t base;
392 uint8_t idx_out,
393 idx_in,
394 mask;
395 } fifo_dsc[NUM_FIFOS];
396
397
398void z80_memfifo_init(const fifo_t f, uint32_t adr)
399{
400
401DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, adr);
402
403 fifo_dsc[f].base = adr;
404
405 z80_request_bus();
406
407 fifo_dsc[f].mask = z80_read(adr + FIFO_BUFSIZE_MASK);
408 fifo_dsc[f].idx_in = z80_read(adr + FIFO_INDEX_IN);
409 fifo_dsc[f].idx_out = z80_read(adr + FIFO_INDEX_OUT);
410
411 z80_release_bus();
412}
413
414
415int z80_memfifo_is_empty(const fifo_t f)
416{
417 int rc = 1;
418
419 if (fifo_dsc[f].base != 0) {
420
421 uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
422 uint8_t idx;
423
424 z80_request_bus();
425 idx = z80_read(adr);
426 z80_release_bus();
427 rc = idx == fifo_dsc[f].idx_out;
428 }
429
430 return rc;
431}
432
433int z80_memfifo_is_full(const fifo_t f)
434{
435 int rc = 1;
436
437 if (fifo_dsc[f].base != 0) {
438 z80_request_bus();
439 rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
440 == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
441 z80_release_bus();
442 }
443 return rc;
444}
445
446uint8_t z80_memfifo_getc(const fifo_t f)
447{
448 uint8_t rc, idx;
449
450 while (z80_memfifo_is_empty(f))
451 ;
452
453 z80_request_bus();
454 idx = fifo_dsc[f].idx_out;
455 rc = z80_read(fifo_dsc[f].base+idx);
456 fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
457 z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
458 z80_release_bus();
459
460 return rc;
461}
462
463
464void z80_memfifo_putc(fifo_t f, uint8_t val)
465{
466 int idx;
467
468 while (z80_memfifo_is_full(f))
469 ;
470
471 z80_request_bus();
472 idx = fifo_dsc[f].idx_in;
473 z80_write(fifo_dsc[f].base+idx, val);
474 fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
475 z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
476 z80_release_bus();
477}
478
479/*--------------------------------------------------------------------------*/
480
481static struct {
482 uint32_t base;
483 //uint8_t idx_out, idx_in;
484 uint16_t count;
485 uint8_t buf[256];
486 } msg_fifo;
487
488/*--------------------------------------------------------------------------*/
489
490#if 0
491
492static void tim1_setup(void)
493{
494 RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
495 RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST;
496
497 TIM1_CR1 = 0;
498
499 TIM1_SMCR = 0
500 /* | TIM_SMCR_ETP */
501 /* | TIM_SMCR_ETF_CK_INT_N_2 */
502 | TIM_SMCR_TS_ETRF
503 | TIM_SMCR_SMS_OFF
504 ;
505
506 TIM1_DIER = TIM_DIER_TDE;
507
508
509 TIM1_CCMR1 = 0
510 | TIM_CCMR1_OC1M_FORCE_LOW
511 | TIM_CCMR1_CC1S_OUT;
512
513 TIM1_SMCR |= TIM_SMCR_SMS_TM;
514}
515
516#endif
517
518/*--------------------------------------------------------------------------*/
519
520void z80_setup_msg_fifo(void)
521{
522// gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
523// GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1);
524
525//...
526
527// msg_fifo.count = NELEMS(msg_fifo.buf);
528 msg_fifo.count = 0;
529 msg_fifo.base = 0;
530
531}
532
533
534void z80_init_msg_fifo(uint32_t addr)
535{
536
537DBG_P(1, "z80_init_msg_fifo: %lx\n", addr);
538
539 z80_request_bus();
540 z80_write(addr+FIFO_INDEX_OUT, z80_read(addr+FIFO_INDEX_IN));
541 z80_release_bus();
542 msg_fifo.base = addr;
543}
544
545
546int z80_msg_fifo_getc(void)
547{
548 int c = -1;
549
550 if (msg_fifo.count != (NELEMS(msg_fifo.buf) /*- DMA1_CNDTR4 */ )) {
551 c = msg_fifo.buf[msg_fifo.count];
552 if (++msg_fifo.count == NELEMS(msg_fifo.buf))
553 msg_fifo.count = 0;
554
555 if (msg_fifo.base != 0) {
556 z80_request_bus();
557 z80_write(msg_fifo.base+FIFO_INDEX_OUT, msg_fifo.count);
558 z80_release_bus();
559 }
560 }
561
562 return c;
563}