summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--avr/background.c35
-rw-r--r--avr/cmd_boot.c74
-rw-r--r--avr/command_tbl.c10
-rw-r--r--avr/main.c18
-rw-r--r--avr/z180-serv.c122
-rw-r--r--avr/z80-if.c24
-rw-r--r--include/background.h4
-rw-r--r--include/common.h1
-rw-r--r--include/config.h1
-rw-r--r--include/z180-serv.h7
-rw-r--r--include/z80-if.h9
11 files changed, 257 insertions, 48 deletions
diff --git a/avr/background.c b/avr/background.c
index 37e4b02..0e1ca40 100644
--- a/avr/background.c
+++ b/avr/background.c
@@ -4,15 +4,39 @@
#define BG_FUNC_MAX 5
-static bg_func func_tab[BG_FUNC_MAX];
+static struct {
+ bg_func fct;
+ int param;
+} func_tab[BG_FUNC_MAX];
+
static int_fast8_t fcount;
-int bg_register(bg_func f)
+int bg_register(bg_func f, int initval)
{
if (fcount < BG_FUNC_MAX) {
- func_tab[fcount++] = f;
+ func_tab[fcount].fct = f;
+ func_tab[fcount].param = initval;
+ return ++fcount - 1;
+ }
+ return -1;
+}
+
+int bg_setstat(int handle, int val)
+{
+ if (handle < fcount) {
+ func_tab[handle].param = val;
return 1;
}
+
+ return 0;
+}
+
+
+int bg_getstat(int handle)
+{
+ if (handle < fcount) {
+ return func_tab[handle].param;
+ }
return 0;
}
@@ -21,8 +45,9 @@ void bg_shed(void)
{
static int_fast8_t current;
- if (func_tab[current]) {
- func_tab[current](0);
+ if (func_tab[current].fct) {
+ int v = func_tab[current].fct(func_tab[current].param);
+ func_tab[current].param = v;
}
if (++current >= fcount)
current = 0;
diff --git a/avr/cmd_boot.c b/avr/cmd_boot.c
index 17ed746..c2f0351 100644
--- a/avr/cmd_boot.c
+++ b/avr/cmd_boot.c
@@ -5,9 +5,12 @@
#include "common.h"
#include <stdlib.h>
#include <avr/pgmspace.h>
+#include <util/atomic.h>
#include "command.h"
+#include "con-utils.h"
#include "z80-if.h"
+#include "z180-serv.h"
//#include "debug.h"
/* ugly hack to get Z180 loadfile into flash memory */
@@ -130,6 +133,7 @@ command_ret_t do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
printf_P(PSTR("## CPU now in reset state.\n"));
+ restart_z180_serv();
z80_bus_cmd(Reset);
return CMD_RET_SUCCESS;
}
@@ -138,8 +142,78 @@ command_ret_t do_restart(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
{
(void) cmdtp; (void) flag; (void) argc; (void) argv;
+ restart_z180_serv();
z80_bus_cmd(Restart);
return CMD_RET_SUCCESS;
}
+
+command_ret_t do_console(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ int ch;
+ uint8_t pending, state = 0;
+
+ (void) cmdtp; (void) flag; (void) argc; (void) argv;
+
+
+ while (1) {
+
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ pending = (Stat & S_CON_PENDING) != 0;
+ Stat &= ~S_CON_PENDING;
+ }
+ if (pending)
+ while ((ch = z80_memfifo_getc(fifo_conout)) >= 0)
+ putchar(ch);
+
+ if ((ch = my_getchar(0)) >= 0) {
+ switch (state) {
+ case 0:
+ if (ch == CONFIG_ESC_CHAR) {
+ state = 1;
+ /* TODO: Timer starten */
+ } else {
+ z80_memfifo_putc(fifo_conin, ch);
+// serial_putc(ch);
+// if (ch == '\r')
+// serial_putc('\n');
+ }
+ break;
+ case 1:
+ switch (ch) {
+
+ case 'r':
+// z80_reset_pulse();
+ break;
+
+ case 'b':
+ break;
+
+ case 'e':
+ break;
+
+ case 'q':
+ case 'Q':
+ goto quit;
+ break;
+
+ case CONFIG_ESC_CHAR:
+ default:
+ z80_memfifo_putc(fifo_conin, ch);
+// serial_putc(ch);
+// if (ch == '\r')
+// serial_putc('\n');
+ }
+ state = 0;
+ break;
+ }
+ }
+
+ }
+quit:
+
+ return CMD_RET_SUCCESS;
+}
+
+
diff --git a/avr/command_tbl.c b/avr/command_tbl.c
index e8af931..336e6ea 100644
--- a/avr/command_tbl.c
+++ b/avr/command_tbl.c
@@ -14,12 +14,11 @@ extern command_ret_t do_env_save(cmd_tbl_t *, int, int, char * const []);
extern command_ret_t do_loadf(cmd_tbl_t *, int, int, char * const []);
extern command_ret_t do_go(cmd_tbl_t *, int, int, char * const []);
extern command_ret_t do_restart(cmd_tbl_t *, int, int, char * const []);
+extern command_ret_t do_console(cmd_tbl_t *, int, int, char * const []);
extern command_ret_t do_dump_mem(cmd_tbl_t *, int, int, char * const []);
extern command_ret_t do_eep_cp(cmd_tbl_t *, int, int, char * const []);
extern command_ret_t do_busreq_pulse(cmd_tbl_t *, int, int, char * const []);
extern command_ret_t do_date(cmd_tbl_t *, int, int, char * const []);
-//extern command_ret_t do_clock(cmd_tbl_t *, int, int, char * const []);
-//extern command_ret_t do_clock2(cmd_tbl_t *, int, int, char * const []);
extern command_ret_t do_pin(cmd_tbl_t *, int, int, char * const []);
@@ -118,10 +117,15 @@ CMD_TBL_ITEM(
""
),
CMD_TBL_ITEM(
- restart, 1, 0, do_restart,
+ restart, 1, 1, do_restart,
"Perform RESET of the CPU",
""
),
+CMD_TBL_ITEM(
+ connect, 1, 1, do_console,
+ "Connect to CPU console i/o",
+ ""
+),
#if 0
CMD_TBL_ITEM(
diff --git a/avr/main.c b/avr/main.c
index 2a1ecd3..34db6ef 100644
--- a/avr/main.c
+++ b/avr/main.c
@@ -18,6 +18,7 @@
#include "timer.h"
#include "cli.h"
#include "env.h"
+#include "z180-serv.h"
#define udelay(n) _delay_us(n)
@@ -66,6 +67,11 @@ ISR(INT5_vect)
Stat |= S_MSG_PENDING;
}
+ISR(INT6_vect)
+{
+ Stat |= S_CON_PENDING;
+}
+
static
void setup_avr(void)
{
@@ -105,10 +111,13 @@ void setup_avr(void)
TCCR3B = (0b01<<WGM32)|(0b001<<CS30); /* CTC Mode, Prescaler 1 */
TIMSK3 = _BV(OCIE3A); /* Enable TC2.oca interrupt */
- /* INT5 falling edge */
- EICRB = (EICRB & ~(0b11 << ISC50)) | 0b10 << ISC50;
- /* Enable INT5 */
- EIMSK |= _BV(INT5);
+ /* INT5, INT6: falling edge */
+ EICRB = (EICRB & ~((0b11 << ISC50) | (0b11 << ISC60))) |
+ (0b10 << ISC50) | (0b10 << ISC60);
+ /* Reset pending ints */
+ EIFR |= _BV(INTF5) | _BV(INTF6);
+ /* Enable INT5, and INT6 */
+ EIMSK |= _BV(INT5) | _BV(INT6);
}
static
@@ -240,6 +249,7 @@ int main(void)
printf_P(PSTR("\nATMEGA1281+Z8S180 Stamp Monitor\n\n"));
+ setup_z180_serv();
main_loop();
}
diff --git a/avr/z180-serv.c b/avr/z180-serv.c
index c920326..2dbac65 100644
--- a/avr/z180-serv.c
+++ b/avr/z180-serv.c
@@ -4,14 +4,15 @@
#include "common.h"
//#include <avr/power.h>
//#include <avr/pgmspace.h>
-//#include <util/atomic.h>
+#include <util/atomic.h>
//#include <avr/sleep.h>
//#include <string.h>
-
+#include "background.h"
#include "debug.h"
#include "serial.h"
#include "z80-if.h"
+#include "z180-serv.h"
@@ -23,7 +24,7 @@ uint8_t z80_get_byte(uint32_t adr)
uint8_t data;
z80_bus_cmd(Request);
- data = z80_read(adr),
+ data = z80_read(adr);
z80_bus_cmd(Release);
return data;
@@ -53,19 +54,12 @@ uint32_t msg_to_addr(uint8_t *msg)
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));
+ z80_memfifo_init(subf, msg_to_addr(msg));
}
@@ -81,10 +75,7 @@ void do_msg_char_out(uint8_t subf, int len, uint8_t * 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,
+ 1, 3, /* sub fct nr. from, to */
do_msg_ini_memfifo},
{ 1,
1, 1,
@@ -108,17 +99,19 @@ void do_message(int len, uint8_t *msg)
sub_fct = *msg++;
len -= 2;
- while (fct != z80_messages[i].fct)
+ while (fct != z80_messages[i].fct) {
+ if (z80_messages[i].fct == 0xff) {
+ DBG_P(1, "do_message: Unknown function: %i, %i\n",
+ fct, sub_fct);
+ return; /* TODO: unknown message # */
+ }
+
++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 )
+ if (sub_fct >= z80_messages[i].sub_min &&
+ sub_fct <= z80_messages[i].sub_max )
break;
++i;
}
@@ -149,7 +142,7 @@ void check_msg_fifo(void)
static int msglen,idx;
static uint8_t buffer[CTRBUF_LEN];
- while (state != 3 && (ch = z80_msg_fifo_getc()) >= 0) {
+ while ((ch = z80_memfifo_getc(fifo_msgin)) >= 0) {
switch (state) {
case 0: /* wait for start of message */
if (ch == 0x81) {
@@ -167,18 +160,89 @@ void check_msg_fifo(void)
break;
case 2: /* get message */
buffer[idx++] = ch;
- if (idx == msglen)
- state = 3;
+ if (idx == msglen) {
+ do_message(msglen, buffer);
+ state = 0;
+ }
+ break;
+ }
+ }
+}
+
+
+int msg_handling(int state)
+{
+ uint8_t pending;
+
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ pending = (Stat & S_MSG_PENDING) != 0;
+ Stat &= ~S_MSG_PENDING;
+ }
+
+ if (pending) {
+ switch (state) {
+ case 0:
+ z80_bus_cmd(Request);
+ uint32_t addr = z80_read(0x40) +
+ ((uint16_t) z80_read(0x41) << 8) +
+ ((uint32_t) z80_read(0x42) << 16);
+ z80_bus_cmd(Release);
+ if (addr != 0) {
+ z80_memfifo_init(fifo_msgin, addr);
+ state = 1;
+ }
+ break;
+ case 1:
+ check_msg_fifo();
break;
}
}
- if (state == 3) {
- do_message(msglen, buffer);
- state = 0;
+ return state;
+}
+
+
+int console_handling(int state)
+{
+ int ch;
+ uint8_t pending;
+
+ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) {
+ pending = (Stat & S_CON_PENDING) != 0;
+ Stat &= ~S_CON_PENDING;
+ }
+
+ if (pending) {
+ while ((ch = z80_memfifo_getc(fifo_conout)) >= 0) {
+ putchar(ch);
+ }
}
+
+ return state;
+}
+
+
+
+
+static int handle_msg_handling;
+
+void setup_z180_serv(void)
+{
+
+ handle_msg_handling = bg_register(msg_handling, 0);
+// bg_register(console_handling, 0);
}
+void restart_z180_serv(void)
+{
+ z80_bus_cmd(Request);
+ z80_write(0x40, 0);
+ z80_write(0x41, 0);
+ z80_write(0x42, 0);
+ z80_bus_cmd(Release);
+
+ bg_setstat(handle_msg_handling, 0);
+}
/*--------------------------------------------------------------------------*/
@@ -250,5 +314,3 @@ const FLASH uint8_t test1[] = {
-// check_msg_fifo();
-
diff --git a/avr/z80-if.c b/avr/z80-if.c
index d14d9d7..414582e 100644
--- a/avr/z80-if.c
+++ b/avr/z80-if.c
@@ -518,8 +518,7 @@ int z80_memfifo_is_empty(const fifo_t f)
{
int rc = 1;
- if (((Stat & S_MSG_PENDING) || f != fifo_in) && fifo_dsc[f].base != 0)
- {
+ if (fifo_dsc[f].base != 0) {
uint32_t adr = fifo_dsc[f].base + FIFO_INDEX_IN;
uint8_t idx;
@@ -546,7 +545,8 @@ int z80_memfifo_is_full(const fifo_t f)
return rc;
}
-uint8_t z80_memfifo_getc(const fifo_t f)
+
+uint8_t z80_memfifo_getc_wait(const fifo_t f)
{
uint8_t rc, idx;
@@ -563,6 +563,24 @@ uint8_t z80_memfifo_getc(const fifo_t f)
return rc;
}
+int z80_memfifo_getc(const fifo_t f)
+{
+ int rc = -1;
+
+ if (fifo_dsc[f].base != 0) {
+ uint8_t idx = fifo_dsc[f].idx_out;
+ z80_bus_cmd(Request);
+ if (idx != z80_read(fifo_dsc[f].base + FIFO_INDEX_IN)) {
+ 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_bus_cmd(Release);
+ }
+
+ return rc;
+}
+
void z80_memfifo_putc(fifo_t f, uint8_t val)
{
diff --git a/include/background.h b/include/background.h
index a624dbb..8a430b3 100644
--- a/include/background.h
+++ b/include/background.h
@@ -3,7 +3,9 @@
typedef int (*bg_func)(int);
-int bg_register(bg_func f);
+int bg_register(bg_func f, int initval);
+int bg_setstat(int handle, int val);
+int bg_getstat(int handle);
void bg_shed(void);
#endif /* BACKGROUND_H */
diff --git a/include/common.h b/include/common.h
index d054ad1..ef5af12 100644
--- a/include/common.h
+++ b/include/common.h
@@ -38,6 +38,7 @@ extern volatile uint_least8_t Stat;
#define S_10MS_TO (1<<0)
#define S_MSG_PENDING (2<<0)
+#define S_CON_PENDING (3<<0)
static inline
void my_puts(const char *s)
diff --git a/include/config.h b/include/config.h
index c0777a8..82dbf81 100644
--- a/include/config.h
+++ b/include/config.h
@@ -32,6 +32,7 @@
#define CONFIG_SYS_ENV_NAMELEN 16
#define CONFIG_SYS_PROMPT "=> "
+#define CONFIG_ESC_CHAR ('^'-0x40)
/* TODO: */
diff --git a/include/z180-serv.h b/include/z180-serv.h
new file mode 100644
index 0000000..af4b1c0
--- /dev/null
+++ b/include/z180-serv.h
@@ -0,0 +1,7 @@
+#ifndef Z180_SERV_H
+#define Z180_SERV_H
+
+void setup_z180_serv(void);
+void restart_z180_serv(void);
+
+#endif /* Z180_SERV_H */
diff --git a/include/z80-if.h b/include/z80-if.h
index b4a4e6f..24fda5d 100644
--- a/include/z80-if.h
+++ b/include/z80-if.h
@@ -34,11 +34,16 @@ void z80_memset(uint32_t addr, uint8_t data, uint32_t length);
void z80_write_block(const FLASH uint8_t *src, uint32_t dest, uint32_t length);
-typedef enum fifo_t {fifo_in, fifo_out, NUM_FIFOS} fifo_t;
+typedef enum fifo_t {
+ fifo_msgin, fifo_msgout,
+ fifo_conout, fifo_conin,
+ 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);
+int z80_memfifo_getc(const fifo_t f);
+uint8_t z80_memfifo_getc_wait(const fifo_t f);
void z80_memfifo_putc(fifo_t f, uint8_t val);