--- /dev/null
+/* Z80 Mainboard Controller */
+
+#include <stdio.h>
+
+#include <avr/io.h>
+#include <avr/interrupt.h>
+#include <avr/pgmspace.h>
+#include <util/delay.h>
+
+#include "uart.h"
+#include "bus.h"
+#include "i2c.h"
+#include "mem.h"
+#include "io.h"
+
+#include "monitor.h"
+
+uint8_t xorshift(uint8_t new_seed)
+{
+ static uint8_t seed = 0xA5;
+ if(new_seed) seed=new_seed;
+
+ seed ^= (seed << 1);
+ seed ^= (seed >> 1);
+ seed ^= (seed << 2);
+ return(seed);
+}
+
+int main(void)
+{
+ /* initialize serial port and stdin/stdout */
+ uart_init();
+ stdout = &uart_out;
+ stdin = &uart_in;
+ sei();
+
+ /* initialize hardware and monitor */
+ printf_P(PSTR("\nAVR INIT "));
+ printf_P(PSTR("[BUS")); bus_init(); printf_P(PSTR("] "));
+ printf_P(PSTR("[I2C")); i2c_init(); printf_P(PSTR("] "));
+ printf_P(PSTR("[MEM")); mem_init(); printf_P(PSTR("] "));
+ printf_P(PSTR("[I/O")); io_init(); printf_P(PSTR("] "));
+ printf_P(PSTR("[MON] ")); monitor_init();
+ printf_P(PSTR("DONE.\nSend BREAK to enter monitor.\n"));
+
+ /* load initial program into memory */
+ menu_ihex();
+
+#if 0
+ mem_start();
+ for(uint8_t i = 0; i < 8; i++) printf("%02x ", mem_read(i));
+ mem_stop();
+#endif
+
+ /* reset Z80 */
+ printf_P(PSTR("Go!\n"));
+ bus_reset();
+ bus_unlock();
+ bus_wait();
+
+ while(1) {
+ if(!(MEMPIN & (1 << SEL))) { /* got I/O request */
+
+ /* answer the I/O request */
+ if(!(MEMPIN & (1 << RD))) {
+// printf_P(PSTR("<IORD>"));
+ io_read();
+ } else if(!(MEMPIN & (1 << WR))) {
+// printf_P(PSTR("<IOWR>"));
+ io_write();
+ } else {
+ printf_P(PSTR("<IOFAIL>"));
+ while(1);
+ }
+
+ while(!(MEMPIN & (1 << SEL)));
+ }
+
+ if(uart_break) monitor(); /* enter monitor on break */
+ }
+
+ printf_P(PSTR("\nAVR END\n"));
+ while(1);
+}