]> cloudbase.mooo.com Git - z180-stamp.git/commitdiff
New sub dir: avr.
authorLeo C <erbl259-lmu@yahoo.de>
Wed, 2 Jul 2014 13:24:17 +0000 (15:24 +0200)
committerLeo C <erbl259-lmu@yahoo.de>
Wed, 2 Jul 2014 13:24:17 +0000 (15:24 +0200)
avr/debug.h [new file with mode: 0644]
avr/serial.c [new file with mode: 0644]
avr/serial.h [new file with mode: 0644]
avr/z180-stamp-avr.c [new file with mode: 0644]
avr/z80-if.c [new file with mode: 0644]
avr/z80-if.h [new file with mode: 0644]
stm32/z180-stamp-stm32.c
stm32/z80-if.c

diff --git a/avr/debug.h b/avr/debug.h
new file mode 100644 (file)
index 0000000..39ae55c
--- /dev/null
@@ -0,0 +1,11 @@
+
+#ifndef DEBUG_H_
+#define DEBUG_H_
+
+#ifdef DEBUG
+#define DBG_P(lvl, ...) if (DEBUG>=lvl) fprintf_P( stderr,  __VA_ARGS__ )
+#else
+#define DBG_P(lvl, ...)
+#endif
+
+#endif /* DEBUG_H_ */
diff --git a/avr/serial.c b/avr/serial.c
new file mode 100644 (file)
index 0000000..4b3cd42
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ */
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <util/atomic.h>
+#include <errno.h>
+#include <stdio.h>
+
+#include "serial.h"
+
+
+static int _write(char c, FILE *stream);
+static FILE mystdout = FDEV_SETUP_STREAM(_write, 
+               NULL, _FDEV_SETUP_WRITE);
+
+#define CTL_S  ('S'-'@')               /* DC3 (Stop) */
+#define CTL_Q  ('Q'-'@')               /* DC1 (Start) */
+
+typedef enum {
+       IDLE,
+       ACTIVE,
+       REQ_STOP,
+       REQ_CONT,
+       STOPPED
+} xmit_stat_t;
+
+
+static volatile uint8_t stat_tx;
+static volatile uint8_t stat_rx;
+
+
+struct ring {
+       uint8_t *data;
+       uint_fast8_t mask;
+       volatile uint_fast8_t begin;
+       volatile uint_fast8_t end;
+};
+
+
+#define BUFFER_SIZE 256
+
+#if ((BUFFER_SIZE-1) & BUFFER_SIZE)
+# error: BUFFER_SIZE not power of 2
+#endif
+
+#if ((BUFFER_SIZE) > 256)
+# error: BUFFER_SIZE 
+#endif
+
+struct ring rx_ring;
+struct ring tx_ring;
+uint8_t rx_ring_buffer[BUFFER_SIZE];
+uint8_t tx_ring_buffer[BUFFER_SIZE];
+
+
+static void ring_init(struct ring *ring, uint8_t *buf, int size)
+{
+       ring->data = buf;
+       ring->mask = (size-1) & 0xff;
+       ring->begin = 0;
+       ring->end = 0;
+}
+
+static int ring_write_ch(struct ring *ring, uint8_t ch)
+{
+       uint_fast8_t ep = (ring->end + 1) & ring->mask;
+
+       if ((ep) != ring->begin) {
+               ring->data[ring->end] = ch;
+               ring->end = ep;
+               return 1;
+       }
+
+       return -1;
+}
+
+#if 0
+static int ring_write(struct ring *ring, uint8_t *data, int size)
+{
+       int i;
+
+       for (i = 0; i < size; i++) {
+               if (ring_write_ch(ring, data[i]) < 0)
+                       return -i;
+       }
+
+       return i;
+}
+#endif
+
+static int ring_read_ch(struct ring *ring)
+{
+       int ret = -1;
+       uint_fast8_t i = ring->begin;
+
+       if (i != ring->end) {
+               ret = ring->data[i];
+               ring->begin = (i +1) & ring->mask;
+       }
+
+       return ret;
+}
+
+
+static int_fast8_t ring_is_empty(struct ring *ring)
+{
+       return ring->begin == ring->end;
+}
+
+
+/* Initialize UART */
+
+void usart0_setup(void) {
+
+       ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+
+               PRR0 &= ~_BV(PRUSART0);
+               UCSR0B = 0;
+
+               /* Initialize ring buffers. */
+               ring_init(&rx_ring, rx_ring_buffer, BUFFER_SIZE);
+               ring_init(&tx_ring, tx_ring_buffer, BUFFER_SIZE);
+
+               stat_tx = ACTIVE;
+               stat_rx = ACTIVE;
+
+               UCSR0A = _BV(U2X0);
+               UBRR0L = F_CPU / BAUD / 8 - 1;
+               UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
+               UCSR0C = 3 << UCSZ00;
+       };
+}
+
+
+
+/* UART RXC interrupt */
+
+ISR(USART0_RX_vect)
+{
+       uint8_t d;
+
+       d = UDR0;
+
+       switch (d) {
+       case CTL_S:
+               stat_tx = REQ_STOP;
+               break;
+       case CTL_Q:
+               if ((stat_tx == STOPPED) || stat_tx == REQ_STOP) {
+                       UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0) | _BV(UDRIE0);
+                       stat_tx = ACTIVE;
+               }
+               break;
+       default:
+               ring_write_ch(&rx_ring, d);
+               break;
+       }
+}
+
+/* UART UDRE interrupt */
+
+ISR(USART0_UDRE_vect)
+{
+       uint8_t s;
+
+       s = !ring_is_empty(&tx_ring);
+       if ((s == 0) || (stat_tx != ACTIVE)) {
+               UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0);
+               if (s)
+                       stat_tx = STOPPED;
+       } else {
+               UDR0 = ring_read_ch(&tx_ring);
+       }
+}
+
+
+
+/*--------------------------------------------------------------------------*/
+
+void serial_setup(void)
+{
+       stdout = &mystdout;
+       usart0_setup();
+}
+
+/*--------------------------------------------------------------------------*/
+
+int _write(char c, FILE *stream)
+{
+       (void) stream;
+
+       if (c == '\n')
+               serial_putc('\r');
+       serial_putc(c);
+
+       return 0;
+}
+
+int serial_getc(void)
+{
+       return ring_read_ch(&rx_ring);
+}
+
+void serial_putc(uint8_t data)
+{
+       while (ring_write_ch(&tx_ring, data) < 0)
+               ;
+       switch (stat_tx) {
+       case ACTIVE:
+       default:
+               /* Enable the TXE interrupt. */
+               UCSR0B = _BV(RXCIE0) | _BV(RXEN0) | _BV(TXEN0) | _BV(UDRIE0);
+               break;
+       }
+}
+
diff --git a/avr/serial.h b/avr/serial.h
new file mode 100644 (file)
index 0000000..1a0f510
--- /dev/null
@@ -0,0 +1,8 @@
+#ifndef SERIAL_H
+#define SERIAL_H
+
+void serial_setup(void);
+void serial_putc(uint8_t);
+int serial_getc(void);
+
+#endif /* SERIAL_H */
diff --git a/avr/z180-stamp-avr.c b/avr/z180-stamp-avr.c
new file mode 100644 (file)
index 0000000..4ea4d47
--- /dev/null
@@ -0,0 +1,440 @@
+/*
+ */
+
+
+#include <avr/io.h>
+//#include <avr/power.h>
+//#include <avr/pgmspace.h>
+//#include <avr/interrupt.h>
+//#include <util/atomic.h>
+//#include <avr/sleep.h>
+//#include <string.h>
+
+#include <stdio.h>
+
+
+#include "debug.h"
+#include "serial.h"
+#include "z80-if.h"
+
+#define const const __flash
+#include "../z180/hdrom.h"
+#undef const
+
+#define FLASH __flash
+//#define FLASH 
+
+#define ESCCHAR                ('^'-0x40)
+
+#define S_10MS_TO      (1<<0)
+
+
+volatile int_fast8_t timeout_1s;
+volatile uint_least8_t Stat;
+
+
+/****************************************************************/
+
+#define P_ADL          PORTA
+#define P_ADH          PORTC
+#define P_ADB          PORTE
+#define PIN_ADB                PINE
+
+#define ADB_WIDTH      3
+#define ADB_SHIFT      2
+//#define ADB_PORT     GPIOE
+
+#define MASK(n)        ((1<<(n))-1)
+#define SMASK(w,s) (MASK(w) << (s))
+
+typedef union {
+       uint32_t l;
+       uint16_t w[2];
+       uint8_t b[4];
+} addr_t;
+
+
+void z80_setaddress(uint32_t addr)
+{
+       addr_t x;
+
+       x.l = addr;
+       P_ADL = x.b[0];
+       P_ADH = x.b[1];
+       PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ;
+
+}
+
+/****************************************************************/
+
+/*--------------------------------------------------------------------------*/
+
+
+void sys_tick_handler(void)
+{
+       static int_fast8_t tick_10ms = 0;
+       static int_fast16_t count_ms = 0;
+
+       int_fast8_t i;
+
+       ++tick_10ms;
+       if (tick_10ms == 10)
+       {
+               Stat |= S_10MS_TO;
+
+               tick_10ms = 0;
+               
+               
+               /* Drive timer procedure of low level disk I/O module */
+               //disk_timerproc();
+       }
+       
+       count_ms++;
+       if (count_ms == 1000) {
+               count_ms = 0;
+
+               i = timeout_1s;
+               if (i)
+                       timeout_1s = i - 1;
+       }
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+static uint32_t z80_sram_cmp(uint32_t addr, uint32_t length, uint8_t wval, int inc)
+{
+       uint8_t rval;
+       int_fast8_t errors = 0;
+       
+       DBG_P(1, "SRAM: Check %#.5x byte... ", length);
+       while (length--) {
+               if ((rval = z80_read(addr)) != wval) {
+                       if (errors == 0) { 
+                               printf("\nSRAM: Address  W  R\n" \
+                                      "      -------------\n");
+//                                            12345  00 11
+                       }
+                       printf("       %.5lx  %.2x %.2x\n", addr, wval, rval);
+                       
+                       if (++errors > 16 )
+                               break;
+               }
+               addr++;
+               wval += inc;
+       }
+       DBG_P(1, "Done.\n");
+
+       return addr;
+}
+
+#if 0
+static void z80_sram_fill(uint32_t addr, int length, uint8_t startval, int inc)
+{
+       printf("SRAM: Write %#.5x byte... ", length); //fflush(stdout);
+       while (length--) {
+               z80_write(addr, startval);
+               ++addr; 
+               startval += inc;
+       }
+       printf("Done.\n");
+}
+
+
+void z80_sram_fill_string(uint32_t addr, int length, const char *text)
+{
+       char c;
+       const char *p = text;
+
+       while (length--) {
+               z80_write(addr++, c = *p++);
+               if (c == 0)
+                       p = text;
+       }
+}
+
+
+uint32_t z80_sram_cmp_string(uint32_t addr, int length, const char *text)
+{
+       char c;
+       const char *p = text;
+
+       while (length--) {
+               c = *p++;
+               if (z80_read(addr) != c)
+                       break;
+               ++addr;
+               if (c == 0)
+                       p = text;
+       }
+       return addr;
+}
+
+const char * const qbfox = "Zhe quick brown fox jumps over the lazy dog!";
+const char * const qbcat = "Zhe quick brown fox jumps over the lazy cat!";
+
+#endif
+
+uint8_t z80_get_byte(uint32_t adr)
+{
+       uint8_t data;
+       
+       z80_request_bus();
+       data = z80_read(adr),
+       z80_release_bus();
+       
+       return data;
+}
+
+
+/*--------------------------------------------------------------------------*/
+
+static void do_10ms(void) 
+{
+}
+
+/*--------------------------------------------------------------------------*/
+
+struct msg_item {
+       uint8_t fct;
+       uint8_t sub_min, sub_max;
+       void (*func)(uint8_t, int, uint8_t *);
+};
+
+uint32_t msg_to_addr(uint8_t *msg)
+{
+       union {
+               uint32_t as32;
+               uint8_t as8[4];
+       } addr;
+
+       addr.as8[0] = msg[0];
+       addr.as8[1] = msg[1];
+       addr.as8[2] = msg[2];
+       addr.as8[3] = 0;
+
+       return addr.as32;
+}
+
+void do_msg_ini_msgfifo(uint8_t subf, int len, uint8_t * msg)
+{
+       (void)subf; (void)len;
+
+       z80_init_msg_fifo(msg_to_addr(msg));
+}
+
+
+void do_msg_ini_memfifo(uint8_t subf, int len, uint8_t * msg)
+{
+       (void)len;
+
+       z80_memfifo_init(subf - 1, msg_to_addr(msg));
+}
+
+
+void do_msg_char_out(uint8_t subf, int len, uint8_t * msg)
+{
+       (void)subf;
+
+       while (len--)
+               putchar(*msg++);
+}
+
+
+const FLASH struct msg_item z80_messages[] =
+{
+       { 0,                    /* fct nr. */
+         0, 0,                 /* sub fct nr. from, to */
+         &do_msg_ini_msgfifo},
+       { 0,
+         1, 2,
+         &do_msg_ini_memfifo},
+       { 1,
+         1, 1,
+         &do_msg_char_out},
+       { 0xff,                         /* end mark */
+         0, 0,
+         0},
+
+};
+
+
+
+
+void do_message(int len, uint8_t *msg)
+{
+       uint8_t fct, sub_fct;
+       int_fast8_t i = 0;
+
+       if (len >= 2) {
+               fct = *msg++;
+               sub_fct = *msg++;
+               len -= 2;
+
+               while (fct != z80_messages[i].fct)
+                       ++i;
+
+               if (z80_messages[i].fct == 0xff) {
+                       DBG_P(1, "do_message: Unknown function: %i, %i\n",
+                                       fct, sub_fct);
+                       return; /* TODO: unknown message # */
+               }
+
+               while (fct == z80_messages[i].fct) {
+                       if (sub_fct >= z80_messages[i].sub_min && sub_fct <= z80_messages[i].sub_max )
+                               break;
+                       ++i;
+               }
+
+               if (z80_messages[i].fct != fct) {
+                       DBG_P(1, "do_message: Unknown sub function: %i, %i\n",
+                                       fct, sub_fct);
+                       return; /* TODO: unknown message sub# */
+               }
+
+               (z80_messages[i].func)(sub_fct, len, msg);
+
+
+       } else {
+               /* TODO: error */
+               DBG_P(1, "do_message: to few arguments (%i); this shouldn't happen!\n", len);
+       }
+}
+
+
+
+#define CTRBUF_LEN 256
+
+void check_msg_fifo(void)
+{
+       int ch;
+       static int_fast8_t state;
+       static int msglen,idx;
+       static uint8_t buffer[CTRBUF_LEN];
+
+       while (state != 3 && (ch = z80_msg_fifo_getc()) >= 0) {
+               switch (state) {
+               case 0:         /* wait for start of message */
+                       if (ch == 0x81) {
+                               msglen = 0;
+                               idx = 0;
+                               state = 1;
+                       }
+                       break;
+               case 1:         /* get msg len */
+                       if (ch > 0 && ch <= CTRBUF_LEN) {
+                               msglen = ch;
+                               state = 2;
+                       } else
+                               state = 0;
+                       break;
+               case 2:         /* get message */
+                       buffer[idx++] = ch;
+                       if (idx == msglen)
+                               state = 3;
+                       break;
+               }
+       }
+
+       if (state == 3) {
+               do_message(msglen, buffer);
+               state = 0;
+       }
+}
+
+
+void z80_load_mem(void)
+{
+       unsigned sec = 0;
+       uint32_t sec_base = hdrom_start;
+
+       DBG_P(1, "Loading z80 memory... \n");
+
+       while (sec < hdrom_sections) {
+               DBG_P(2, "  From: 0x%.5lX to: 0x%.5lX    (%5li bytes)\n",
+                               hdrom_address[sec],
+                               hdrom_address[sec]+hdrom_length_of_sections[sec] - 1,
+                               hdrom_length_of_sections[sec]);
+
+               z80_write_block((unsigned char *) &hdrom[sec_base],  /* src */
+                               hdrom_address[sec],                  /* dest */
+                               hdrom_length_of_sections[sec]);      /* len */
+               sec_base+=hdrom_length_of_sections[sec];
+               sec++;
+       }
+}
+/*--------------------------------------------------------------------------*/
+
+int main(void)
+{
+       int_fast8_t state = 0;
+       int ch;
+
+//     setvbuf(stdout, NULL, _IONBF, 0);
+       serial_setup();
+//     printf("\n(STM32F100+HD64180)_stamp Tester\n");
+       printf("\n(ATMEGA1281+HD64180)_stamp Tester\n");
+
+       DBG_P(1, "z80_setup_bus... ");
+       z80_setup_msg_fifo();
+       z80_setup_bus();
+       DBG_P(1, "done.\n");
+
+
+       DBG_P(1, "Get bus... ");
+       z80_busreq(LOW);
+       z80_reset(HIGH);
+       z80_request_bus();
+       DBG_P(1, "got it!\n");
+       
+       z80_memset(0, 0x76, 0x80000);
+       //z80_sram_fill(0, 512 * 1024, 0x76, 0);
+       z80_sram_cmp(0, (uint32_t)512 * 1024, 0x76, 0);
+       
+       z80_load_mem();
+       z80_reset(LOW);
+       DBG_P(1, "Bus released!\n");
+       z80_release_bus();
+       z80_reset(HIGH);
+       DBG_P(1, "Reset released!\n");
+       
+       
+       while (1) {
+
+               if (Stat & S_10MS_TO) {
+                       Stat &= ~S_10MS_TO;
+                       do_10ms();
+               }
+
+
+               if ((ch = serial_getc()) >= 0) {
+                       switch (state) {
+                       case 0:
+                               if (ch == ESCCHAR) {
+                                       state = 1;
+                                       /* TODO: Timer starten */
+                               } else
+                                       z80_memfifo_putc(fifo_out, ch);
+                               break;
+                       case 1:
+                               switch (ch) {
+
+                               case 'r':
+                                       z80_reset_pulse();
+                                       break;
+
+                               case ESCCHAR:
+                               default:
+                                       z80_memfifo_putc(fifo_out, ch);
+                               }
+                               state = 0;
+                               break;
+                       }
+               }
+
+               check_msg_fifo();
+       }
+
+       return 0;
+}
diff --git a/avr/z80-if.c b/avr/z80-if.c
new file mode 100644 (file)
index 0000000..955a61a
--- /dev/null
@@ -0,0 +1,563 @@
+/**
+ *
+ * Pin assignments
+ *
+ * | Z180-Sig  |   AVR-Port    | Dir   |   Special Function    |
+ * +------------+---------------+-------+-----------------------+
+ * |   A0      | PA    0       |  O    |                       |
+ * |   A1      | PA    1       |  O    |                       |
+ * |   A2      | PA    2       |  O    |                       |
+ * |   A3      | PA    3       |  O    |                       |
+ * |   A4      | PA    4       |  O    |                       |
+ * |   A5      | PA    5       |  O    |                       |
+ * |   A6      | PA    6       |  O    |                       |
+ * |   A7      | PA    7       |  O    |                       |
+ * |   A8      | PC    0       |  O    |                       |
+ * |   A9      | PC    1       |  O    |                       |
+ * |   A10     | PC    2       |  O    |                       |
+ * |   A11     | PC    3       |  O    |                       |
+ * |   A12     | PC    4       |  O    |                       |
+ * |   A13     | PC    5       |  O    |                       |
+ * |   A14     | PC    6       |  O    |                       |
+ * |   A15     | PC    7       |  O    |                       |
+ * |   A16     | PE    2       |  O    |                       |
+ * |   A17     | PE    3       |  O    |                       |
+ * |   A18     | PE    4       |  O    |                       |
+ * |   D0      | PF    0       |  I/O  |                       |
+ * |   D1      | PF    1       |  I/O  |                       |
+ * |   D2      | PF    2       |  I/O  |                       |
+ * |   D3      | PF    3       |  I/O  |                       |
+ * |   D4      | PF    4       |  I/O  |                       |
+ * |   D5      | PF    5       |  I/O  |                       |
+ * |   D6      | PF    6       |  I/O  |                       |
+ * |   D7      | PF    7       |  I/O  |                       |
+ * |   RD      | PD    3       |  O    |                       |
+ * |   WR      | PD    2       |  O    |                       |
+ * |   MREQ    | PD    4       |  O    |                       |
+ * |   RST     | PD    5       |  O    |                       |
+ * |   BUSREQ  | PD    7       |  O    |                       |
+ * |   BUSACK  | PD    6       |  I    |                       |
+ * |   IOCS1   | PE    5       |  I    |                       |
+ * |*  HALT    | P             |       |                       |
+ * |*  NMI     | P             |       |                       |
+ * |           | P             |       |                       |
+ * |           | P             |       |  af1   USART1_TX      |
+ * |           | P             |       |  af1   USART1_RX      |
+ * |           | P             |JTDI   |  remap SPI1_NSS'      |
+ * |           | P             |JTDO   |  remap SPI1_SCK'      |
+ * |           | P             |JTRST  |  remap SPI1_MISO'     |
+ * |           | P             |       |  remap SPI1_MOSI'     |
+ * |           | P             |       |  af1   OSC32          |
+ * |           | P             |       |  af1   OSC32          |
+
+
+ */
+
+#include <avr/io.h>
+#include <util/delay.h>
+#include <stdio.h>
+#include "debug.h"
+#include "z80-if.h"
+
+
+/* Number of array elements */
+#define NELEMS(x)  (sizeof x/sizeof *x)
+
+
+#define CONCAT(x,y) x ## y
+#define EVALUATOR(x,y)  CONCAT(x,y)
+
+#define GPIO_(X)       CONCAT(GPIO, X)
+
+struct bits {
+  uint8_t b0:1;
+  uint8_t b1:1;
+  uint8_t b2:1;
+  uint8_t b3:1;
+  uint8_t b4:1;
+  uint8_t b5:1;
+  uint8_t b6:1;
+  uint8_t b7:1;
+} __attribute__((__packed__));
+
+#define SBIT(port,pin) ((*(volatile struct bits*)&port).b##pin)
+
+
+
+#define P_MREQ         PORTD
+#define MREQ           4
+#define DDR_MREQ       DDRD
+#define P_RD           PORTD
+#define RD             3
+#define P_WR           PORTD
+#define WR             2
+#define P_BUSREQ       PORTD
+#define BUSREQ         7
+#define DDR_BUSREQ     DDRD
+#define P_BUSACK       PORTD
+#define BUSACK         6
+#define DDR_BUSACK     DDRD
+//#define P_HALT               PORTA
+//#define HALT         12
+#define P_IOCS1                PORTE
+#define IOCS1          5
+#define DDR_IOCS1              DDRE
+//#define P_NMI                PORTB
+//#define NMI          7
+#define P_RST          PORTD
+#define DDR_RST                DDRD
+#define RST            5
+
+
+#define P_DB           PORTF
+#define PIN_DB         PINF
+#define DDR_DB         DDRF
+
+#define P_ADL          PORTA
+#define P_ADH          PORTC
+#define P_ADB          PORTE
+#define PIN_ADB                PINE
+#define DDR_ADL                DDRE
+#define DDR_ADH                DDRE
+#define DDR_ADB                DDRE
+
+#define ADB_WIDTH      3
+#define ADB_SHIFT      2
+//#define ADB_PORT     PORTE
+
+
+
+#define ADp1_OFS       0
+#define ADp1_WIDTH     8
+#define ADp1_SHIFT     1
+#define ADp1_PORT      GPIOA
+
+#define ADp2_OFS       ADp1_WIDTH
+#define ADp2_WIDTH     8
+#define ADp2_SHIFT     0
+#define ADp2_PORT      GPIOC
+
+#define ADp3_OFS       (ADp2_OFS+ADp2_WIDTH)
+#define ADp3_WIDTH     3
+#define ADp3_SHIFT     10
+#define ADp3_PORT      GPIOC
+
+#define ADunbuff1_WIDTH        1
+#define ADunbuff1_SHIFT        8
+#define ADunbuff1_PORT GPIOA
+
+#define ADunbuff2_WIDTH        2
+#define ADunbuff2_SHIFT        6
+#define ADunbuff2_PORT GPIOC
+
+#define ADunbuff3_WIDTH        3
+#define ADunbuff3_SHIFT        10
+#define ADunbuff3_PORT GPIOC
+
+#define DB_OFS         0
+#define DB_WIDTH       8
+#define DB_SHIFT       8
+#define DB_PORT                GPIOB
+
+
+#define        Z80_O_MREQ      SBIT(P_MREQ, 4)
+#define Z80_O_RD       SBIT(P_RD, 3)
+#define Z80_O_WR       SBIT(P_WR, 2)
+#define Z80_O_BUSREQ   SBIT(P_BUSREQ, 7)
+//#define Z80_O_NMI    SBIT(P_NMI, )
+#define Z80_O_RST      SBIT(P_RST, 5)
+#define Z80_I_BUSACK   SBIT(P_BUSACK, 6)
+//#define Z80_I_HALT   SBIT(P_HALT, )
+
+void z80_busreq(level_t level)
+{
+       Z80_O_BUSREQ = level;
+}
+
+void z80_reset(level_t level)
+{
+       Z80_O_RST = level;
+}
+
+
+void z80_reset_pulse(void)
+{
+       Z80_O_RST = 0;
+       _delay_us(10);
+       Z80_O_RST = 1;
+}
+
+#if 0
+int z80_stat_halt(void)
+{
+       return Z80_I_HALT;
+}
+#endif
+
+
+#define MASK(n)        ((1<<(n))-1)
+#define SMASK(w,s) (MASK(w) << (s))
+
+
+
+typedef union {
+       uint32_t l;
+       uint16_t w[2];
+       uint8_t b[4];
+} addr_t;
+
+/*--------------------------------------------------------------------------*/
+
+
+
+/* 
+ * A0..A6, A8..A13 are buffered. No need to disable.
+ * A7, A14..A18: set to input.
+ */
+static void z80_setup_adrbus_tristate(void)
+{
+       P_ADL = 0;
+       DDR_ADL = 0;
+       P_ADH = 0;
+       DDR_ADH = 0;
+       PIN_ADB = P_ADB & MASK(ADB_WIDTH) << ADB_SHIFT;
+       DDR_ADB = DDR_ADB & ~(MASK(ADB_WIDTH) << ADB_SHIFT);
+}
+
+       
+static void z80_setup_adrbus_active(void)
+{
+       DDR_ADL = 0xff;
+       DDR_ADH = 0xff;
+       DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
+}
+
+
+
+static void z80_setup_dbus_in(void)
+{
+       DDR_DB = 0;
+       P_DB = 0;
+}
+
+static void z80_setup_dbus_out(void)
+{
+       DDR_DB = 0xff;
+}
+
+static
+void z80_setaddress(uint32_t addr)
+{
+       addr_t x; x.l = addr;
+
+       P_ADL = x.b[0];
+       P_ADH = x.b[1];
+       PIN_ADB = ((x.b[2] << ADB_SHIFT) ^ P_ADB) & MASK(ADB_WIDTH) << ADB_SHIFT ;
+}
+
+void z80_setup_bus(void)
+{
+       Z80_O_RST = 0;
+       DDR_RST |= _BV(RST);
+
+       Z80_O_BUSREQ = 1;
+       DDR_BUSREQ |= _BV(BUSREQ);
+
+//     Z80_O_NMI = 1;
+//     DDR_NMI |= _BV(NMI);
+
+       Z80_O_MREQ = 1;
+       Z80_O_RD = 1;
+       Z80_O_WR = 1;
+       DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
+
+       DDR_BUSACK &= ~_BV(BUSACK);
+       P_BUSACK &= ~_BV(BUSACK);
+
+       DDR_IOCS1 &= ~_BV(IOCS1);
+       P_IOCS1 &= ~_BV(IOCS1);
+
+       //Z80_O_BUSREQ = 0;
+       //while(Z80_I_BUSACK == 1);
+
+       z80_setup_adrbus_tristate();
+       z80_setup_dbus_in();
+}
+
+void z80_request_bus(void)
+{
+       Z80_O_BUSREQ = 0;
+       while(Z80_I_BUSACK == 1);
+       z80_setup_adrbus_active();
+}
+
+void z80_release_bus(void)
+{
+       z80_setup_dbus_in();
+       z80_setup_adrbus_tristate();
+       Z80_O_BUSREQ = 1;
+       while(Z80_I_BUSACK == 0);
+}
+
+void z80_write(uint32_t addr, uint8_t data)
+{
+       z80_setaddress(addr);
+       Z80_O_MREQ = 0;
+       P_DB = data;
+       z80_setup_dbus_out();
+       Z80_O_WR = 0;
+       Z80_O_WR = 1;
+       Z80_O_MREQ = 1;
+}
+
+uint8_t z80_read(uint32_t addr)
+{
+       uint8_t data;
+
+       z80_setaddress(addr);
+       Z80_O_MREQ = 0;
+       z80_setup_dbus_in();
+       Z80_O_RD = 0;
+       Z80_O_RD = 0;
+       data = PIN_DB;
+       Z80_O_RD = 1;
+       Z80_O_MREQ = 1;
+
+       return data;
+}
+
+
+void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
+{
+       z80_setup_dbus_out();
+       Z80_O_MREQ = 0;
+       while(length--) {
+               z80_setaddress(addr++);
+               P_DB = data;
+               Z80_O_WR = 0;
+               Z80_O_WR = 1;
+       }
+       Z80_O_MREQ = 1;
+}
+
+void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length)
+{
+       uint8_t data;
+       
+       z80_setup_dbus_out();
+       Z80_O_MREQ = 0;
+       while(length--) {
+               z80_setaddress(dest++);
+               data = *src++;
+               P_DB = data;
+               Z80_O_WR = 0;
+               Z80_O_WR = 1;
+       }
+       Z80_O_MREQ = 1;
+}
+
+/*
+  0179'                         rx.bs_mask:    ds      1               ; (buf_len - 1)
+  017A'                         rx.in_idx:     ds      1               ;
+  017B'                         rx.out_idx:    ds      1               ;
+  017C'                         rx.buf:                ds      rx.buf_len      ;
+  018B'                         rx.buf_end     equ     $-1             ; last byte (start+len-1)
+                                
+  018C'                         tx.bs_mask:    ds      1               ; (buf_len - 1)
+  018D'                         tx.in_idx:     ds      1               ;
+  018E'                         tx.out_idx:    ds      1               ;
+  018F'                         tx.buf:                ds      tx.buf_len      ;
+  019E'                         tx.buf_end     equ     $-1             ; last byte
+*/
+
+
+typedef struct __attribute__((packed)) {
+       uint8_t mask;
+       uint8_t in_idx;
+       uint8_t out_idx;
+       uint8_t buf[];
+} zfifo_t;
+
+
+
+#define FIFO_BUFSIZE_MASK      -3
+#define FIFO_INDEX_IN          -2
+#define FIFO_INDEX_OUT         -1
+
+
+static struct {
+       uint32_t base;
+       uint8_t idx_out,
+               idx_in,
+               mask;
+       } fifo_dsc[NUM_FIFOS];
+       
+
+void z80_memfifo_init(const fifo_t f, uint32_t adr)
+{
+
+DBG_P(2, "z80_memfifo_init: %i, %lx\n", f, adr);
+
+       fifo_dsc[f].base = adr;
+
+       z80_request_bus();
+
+       fifo_dsc[f].mask = z80_read(adr + FIFO_BUFSIZE_MASK);
+       fifo_dsc[f].idx_in = z80_read(adr + FIFO_INDEX_IN);
+       fifo_dsc[f].idx_out = z80_read(adr + FIFO_INDEX_OUT);
+
+       z80_release_bus();
+}
+
+
+int z80_memfifo_is_empty(const fifo_t f)
+{
+       int rc = 1;
+
+       if (fifo_dsc[f].base != 0) {
+
+               uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
+               uint8_t idx;
+
+               z80_request_bus();
+               idx = z80_read(adr);
+               z80_release_bus();
+               rc = idx == fifo_dsc[f].idx_out;
+       }
+
+       return rc;
+}
+
+int z80_memfifo_is_full(const fifo_t f)
+{
+       int rc = 1;
+       
+       if (fifo_dsc[f].base != 0) {
+               z80_request_bus();
+               rc = ((fifo_dsc[f].idx_in + 1) & fifo_dsc[f].mask)
+                       == z80_read(fifo_dsc[f].base+FIFO_INDEX_OUT);
+               z80_release_bus();
+       }
+       return rc;
+}
+
+uint8_t z80_memfifo_getc(const fifo_t f)
+{
+       uint8_t rc, idx;
+       
+       while (z80_memfifo_is_empty(f))
+               ;
+
+       z80_request_bus();
+       idx = fifo_dsc[f].idx_out;
+       rc = z80_read(fifo_dsc[f].base+idx);
+       fifo_dsc[f].idx_out = ++idx & fifo_dsc[f].mask;
+       z80_write(fifo_dsc[f].base+FIFO_INDEX_OUT, fifo_dsc[f].idx_out);
+       z80_release_bus();
+       
+       return rc;
+}
+
+
+void z80_memfifo_putc(fifo_t f, uint8_t val)
+{
+       int idx;
+       
+       while (z80_memfifo_is_full(f))
+               ;
+
+       z80_request_bus();
+       idx = fifo_dsc[f].idx_in;
+       z80_write(fifo_dsc[f].base+idx, val);
+       fifo_dsc[f].idx_in = ++idx & fifo_dsc[f].mask;
+       z80_write(fifo_dsc[f].base+FIFO_INDEX_IN, fifo_dsc[f].idx_in);
+       z80_release_bus();
+}
+
+/*--------------------------------------------------------------------------*/
+
+static struct {
+       uint32_t base;
+       //uint8_t  idx_out, idx_in;
+       uint16_t count;
+       uint8_t  buf[256];
+       } msg_fifo;
+
+/*--------------------------------------------------------------------------*/
+
+#if 0
+
+static void tim1_setup(void)
+{
+       RCC_APB2RSTR |= RCC_APB2RSTR_TIM1RST;
+       RCC_APB2RSTR &= ~RCC_APB2RSTR_TIM1RST;
+
+       TIM1_CR1 = 0;
+
+       TIM1_SMCR = 0
+       /*      | TIM_SMCR_ETP                  */
+       /*      | TIM_SMCR_ETF_CK_INT_N_2       */
+               | TIM_SMCR_TS_ETRF
+               | TIM_SMCR_SMS_OFF
+               ;
+
+       TIM1_DIER = TIM_DIER_TDE;
+
+
+       TIM1_CCMR1 = 0
+               | TIM_CCMR1_OC1M_FORCE_LOW
+               | TIM_CCMR1_CC1S_OUT;
+
+       TIM1_SMCR |= TIM_SMCR_SMS_TM;
+}
+
+#endif
+
+/*--------------------------------------------------------------------------*/
+
+void z80_setup_msg_fifo(void)
+{
+//     gpio_set_mode(P_BUSACK, GPIO_MODE_INPUT,
+//             GPIO_CNF_INPUT_FLOAT, GPIO_BUSACK | GPIO_IOCS1);
+
+//...
+
+//     msg_fifo.count = NELEMS(msg_fifo.buf);
+       msg_fifo.count = 0;
+       msg_fifo.base = 0;
+
+}
+
+
+void z80_init_msg_fifo(uint32_t addr)
+{
+
+DBG_P(1, "z80_init_msg_fifo: %lx\n", addr);
+
+       z80_request_bus();
+       z80_write(addr+FIFO_INDEX_OUT, z80_read(addr+FIFO_INDEX_IN));
+       z80_release_bus();
+       msg_fifo.base = addr;
+}
+
+
+int z80_msg_fifo_getc(void)
+{
+       int c = -1;
+       
+       if (msg_fifo.count != (NELEMS(msg_fifo.buf) /*- DMA1_CNDTR4 */ )) {
+               c = msg_fifo.buf[msg_fifo.count];
+               if (++msg_fifo.count == NELEMS(msg_fifo.buf))
+                       msg_fifo.count = 0;
+
+               if (msg_fifo.base != 0) {
+                       z80_request_bus();
+                       z80_write(msg_fifo.base+FIFO_INDEX_OUT, msg_fifo.count);
+                       z80_release_bus();
+               }
+       }
+
+       return c;
+}
diff --git a/avr/z80-if.h b/avr/z80-if.h
new file mode 100644 (file)
index 0000000..1068225
--- /dev/null
@@ -0,0 +1,27 @@
+
+typedef enum {LOW, HIGH} level_t;
+
+void z80_setup_bus(void);
+void z80_write(uint32_t addr, uint8_t data);
+uint8_t z80_read(uint32_t addr);
+void z80_request_bus(void);
+void z80_release_bus(void);
+void z80_memset(uint32_t addr, uint8_t data, uint32_t length);
+void z80_reset(level_t level);
+void z80_reset_pulse(void);
+void z80_busreq(level_t level);
+void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length);
+int z80_stat_halt(void);
+
+
+typedef enum fifo_t {fifo_in, fifo_out, NUM_FIFOS} fifo_t;
+
+void z80_memfifo_init(const fifo_t f, uint32_t adr);
+int z80_memfifo_is_empty(const fifo_t f);
+int z80_memfifo_is_full(const fifo_t f);
+uint8_t z80_memfifo_getc(const fifo_t f);
+void z80_memfifo_putc(fifo_t f, uint8_t val);
+
+void z80_setup_msg_fifo(void);
+void z80_init_msg_fifo(uint32_t addr);
+int z80_msg_fifo_getc(void);
index 284fc8f3076809c9e7a01a4b42d4311b38850867..15d732d26733f75fbdc6875cb2c62f2e43eff700 100644 (file)
@@ -319,10 +319,10 @@ static void key_timerproc() {
 
 void sys_tick_handler(void)
 {
-       static int tick_10ms = 0;
-       static int count_ms = 0;
+       static int_fast8_t tick_10ms = 0;
+       static int_fast16_t count_ms = 0;
 
-       int i;
+       int_fast8_t i;
 
        ++tick_10ms;
        if (tick_10ms == 10)
@@ -389,10 +389,10 @@ void tim3_set(int mode)
 
 /*--------------------------------------------------------------------------*/
 
-static uint32_t z80_sram_cmp(uint32_t addr, int length, uint8_t wval, int inc)
+static uint32_t z80_sram_cmp(uint32_t addr, uint32_t length, uint8_t wval, int inc)
 {
        uint8_t rval;
-       int errors = 0;
+       int_fast8_t errors = 0;
        
        DBG_P(1, "SRAM: Check %#.5x byte... ", length);
        while (length--) {
@@ -510,7 +510,7 @@ struct msg_item {
 
 uint32_t msg_to_addr(uint8_t *msg)
 {
-       uint32_t addr = msg[0] + (msg[1] << 8) + (msg[2] << 16);
+       uint32_t addr = msg[0] | (msg[1] << 8) | ((uint32_t)msg[2] << 16);
 
        return addr;
 
@@ -543,8 +543,8 @@ void do_msg_char_out(uint8_t subf, int len, uint8_t * msg)
 
 const struct msg_item z80_messages[] =
 {
-       { 0,
-         0, 0,
+       { 0,                    /* fct nr. */
+         0, 0,                 /* sub fct nr. from, to */
          &do_msg_ini_msgfifo},
        { 0,
          1, 2,
@@ -564,7 +564,7 @@ const struct msg_item z80_messages[] =
 void do_message(int len, uint8_t *msg)
 {
        uint8_t fct, sub_fct;
-       int i = 0;
+       int_fast8_t i = 0;
 
        if (len >= 2) {
                fct = *msg++;
@@ -608,7 +608,7 @@ void do_message(int len, uint8_t *msg)
 void check_msg_fifo(void)
 {
        int ch;
-       static int state;
+       static int_fast8_t state;
        static int msglen,idx;
        static uint8_t buffer[CTRBUF_LEN];
 
@@ -645,12 +645,11 @@ void check_msg_fifo(void)
 
 void z80_load_mem(void)
 {
-
-DBG_P(1, "Loading z80 memory... \n");
-
        unsigned sec = 0;
        uint32_t sec_base = hdrom_start;
 
+       DBG_P(1, "Loading z80 memory... \n");
+
        while (sec < hdrom_sections) {
                DBG_P(2, "  From: 0x%.5lX to: 0x%.5lX    (%5li bytes)\n",
                                hdrom_address[sec],
@@ -668,11 +667,7 @@ DBG_P(1, "Loading z80 memory... \n");
 
 int main(void)
 {
-       //uint32_t led_state = LED_BLUE_PIN;
-       //uint32_t rc;
-       //uint8_t startval = 0;
-       //int count;
-       int state = 0;
+       int_fast8_t state = 0;
        int ch;
 
        clock_setup();
@@ -704,7 +699,7 @@ int main(void)
        
        z80_memset(0, 0x76, 0x80000);
        //z80_sram_fill(0, 512 * 1024, 0x76, 0);
-       z80_sram_cmp(0, 512 * 1024, 0x76, 0);
+       z80_sram_cmp(0, (uint32_t)512 * 1024, 0x76, 0);
        
        z80_load_mem();
        z80_reset(LOW);
index 409c32a53260010fe90a0824547bc11054dd42d0..171fea9c93dbc6e0f4cb84bb0a6e7204ac0dd1cc 100644 (file)
@@ -1,3 +1,62 @@
+/**
+ *
+ * Pin assignments
+ *
+ * | Z180-Sig  |  STM32-Port   |Buffer |  Dir  |   Special Function    |
+ * +------------+---------------+-------+-------+-----------------------+
+ * |   A0      | A     1       |   P   |  O    |                       |
+ * |   A1      | A     2       |   P   |  O    |                       |
+ * |   A2      | A     3       |   P   |  O    |                       |
+ * |   A3      | A     4       |   P   |  O    |                       |
+ * |   A4      | A     5       |   P   |  O    |                       |
+ * |   A5      | A     6       |   P   |  O    |                       |
+ * |   A6      | A     7       |   P   |  O    |                       |
+ * |   A7      | A     8       |       |  O    |                       |
+ * |   A8      | C     0       |   P   |  O    |                       |
+ * |   A9      | C     1       |   P   |  O    |                       |
+ * |   A10     | C     2       |   P   |  O    |                       |
+ * |   A11     | C     3       |   P   |  O    |                       |
+ * |   A12     | C     4       |   P   |  O    |                       |
+ * |   A13     | C     5       |   P   |  O    |                       |
+ * |   A14     | C     6       |       |  O    |                       |
+ * |   A15     | C     7       |       |  O    |                       |
+ * |   A16     | C     10      |       |  O    |                       |
+ * |   A17     | C     11      |       |  O    |                       |
+ * |   A18     | C     12      |       |  O    |                       |
+ * |   D0      | B     8       |       |  I/O  |                       |
+ * |   D1      | B     9       |       |  I/O  |                       |
+ * |   D2      | B     10      |       |  I/O  |                       |
+ * |   D3      | B     11      |       |  I/O  |                       |
+ * |   D4      | B     12      |       |  I/O  |                       |
+ * |   D5      | B     13      |       |  I/O  |                       |
+ * |   D6      | B     14      |       |  I/O  |                       |
+ * |   D7      | B     15      |       |  I/O  |                       |
+ * |   ME      | C     13      |   P   |  O    |                       |
+ * |   RD      | B     0       |   P   |  O    |                       |
+ * |   WR      | B     1       |   P   |  O    |                       |
+ * |   BUSREQ  | D     2       |       |  O    |                       |
+ * |   IOCS1   | A     11      |       |  I    |  TIM1_CH4             |
+ * |   BUSACK  | A     12      |       |  I    |                       |
+ * |   HALT    | A     12      |       |  I    |                       |
+ * |   NMI     | B     7       |       |  O    |                       |
+ * |   RST     | B     6       |       |  O    |  TIM16_CH1N           |
+ * |           |               |       |       |                       |
+ * |           | A     9       |       |       |  af1   USART1_TX      |
+ * |           | A     10      |       |       |  af1   USART1_RX      |
+ * |           | A     15      |       | JTDI  |  remap SPI1_NSS'      |
+ * |           | B     3       |       | JTDO  |  remap SPI1_SCK'      |
+ * |           | B     4       |       |NJTRST |  remap SPI1_MISO'     |
+ * |           | B     5       |       |       |  remap SPI1_MOSI'     |
+ * |           | C     14      |       |       |  af1   OSC32          |
+ * |           | C     15      |       |       |  af1   OSC32          |
+
+
+AFIO_MAPR2 =
+AFIO_MAPR_SWJ_CFG_JTAG_OFF_SW_ON  (frees
+AFIO_MAPR_SPI1_REMAP
+
+ */
+
 /**
  *
  * Pin assignments