summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo C2014-07-27 23:23:07 +0200
committerLeo C2014-07-27 23:23:07 +0200
commit9b6b4b31e8cb284ad6a68fe16d458e36bbfb46fa (patch)
tree545e7cd4701667adcd0ecbd9a896fc59e3f4a413
parent762a42ef835d3692bf0d9bea19f5cfd9cb673a33 (diff)
downloadz180-stamp-9b6b4b31e8cb284ad6a68fe16d458e36bbfb46fa.zip
First real hardware test.
-rw-r--r--avr/Tupfile4
-rw-r--r--avr/debug.h2
-rw-r--r--avr/z180-stamp-avr.c241
-rw-r--r--avr/z80-if.c127
-rw-r--r--avr/z80-if.h2
5 files changed, 252 insertions, 124 deletions
diff --git a/avr/Tupfile b/avr/Tupfile
index b43a822..a90b7b5 100644
--- a/avr/Tupfile
+++ b/avr/Tupfile
@@ -6,8 +6,8 @@ SRC_Z = ../z180/hdrom.c
#TARGETS = $(PROG).elf
MCU_TARGET = atmega1281
-F_CPU = 16000000UL
-DEFS = -DF_CPU=$(F_CPU) -DBAUD=115200
+F_CPU = 18432000UL
+DEFS = -DF_CPU=$(F_CPU) -DBAUD=115200UL
INCLUDES += ../z180
diff --git a/avr/debug.h b/avr/debug.h
index c341301..ea67a99 100644
--- a/avr/debug.h
+++ b/avr/debug.h
@@ -6,7 +6,7 @@
#ifdef DEBUG
#define DBG_P(lvl, format, ...) if (DEBUG>=lvl) \
- fprintf_P( stderr, PSTR(format), ##__VA_ARGS__ )
+ fprintf_P( stdout, PSTR(format), ##__VA_ARGS__ )
#else
#define DBG_P(lvl, ...)
#endif
diff --git a/avr/z180-stamp-avr.c b/avr/z180-stamp-avr.c
index 4ea4d47..09f323c 100644
--- a/avr/z180-stamp-avr.c
+++ b/avr/z180-stamp-avr.c
@@ -5,7 +5,7 @@
#include <avr/io.h>
//#include <avr/power.h>
//#include <avr/pgmspace.h>
-//#include <avr/interrupt.h>
+#include <avr/interrupt.h>
//#include <util/atomic.h>
//#include <avr/sleep.h>
//#include <string.h>
@@ -30,8 +30,10 @@
volatile int_fast8_t timeout_1s;
-volatile uint_least8_t Stat;
+//volatile uint_least8_t Stat;
+#define Stat GPIOR0
+unsigned int to_counter;
/****************************************************************/
@@ -55,41 +57,31 @@ typedef union {
-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 ;
-
-}
-
-/****************************************************************/
-
/*--------------------------------------------------------------------------*/
+/*---------------------------------------------------------*/
+/* 1000Hz timer interrupt generated by OC1A */
+/*---------------------------------------------------------*/
-void sys_tick_handler(void)
+ISR(TIMER1_COMPA_vect)
{
- static int_fast8_t tick_10ms = 0;
- static int_fast16_t count_ms = 0;
+ static int_fast8_t tick_10ms;
+// static int_fast16_t count_ms;
int_fast8_t i;
- ++tick_10ms;
- if (tick_10ms == 10)
- {
- Stat |= S_10MS_TO;
- tick_10ms = 0;
-
+ i = tick_10ms + 1;
+ if (i == 10) {
+ i = 0;
+ Stat |= S_10MS_TO;
/* Drive timer procedure of low level disk I/O module */
//disk_timerproc();
}
+ tick_10ms = i;
+#if 0
count_ms++;
if (count_ms == 1000) {
count_ms = 0;
@@ -98,6 +90,7 @@ void sys_tick_handler(void)
if (i)
timeout_1s = i - 1;
}
+#endif
}
@@ -108,18 +101,19 @@ static uint32_t z80_sram_cmp(uint32_t addr, uint32_t length, uint8_t wval, int i
uint8_t rval;
int_fast8_t errors = 0;
- DBG_P(1, "SRAM: Check %#.5x byte... ", length);
+ DBG_P(1, "SRAM: Check 0x%.5lx byte... ", length);
while (length--) {
if ((rval = z80_read(addr)) != wval) {
if (errors == 0) {
- printf("\nSRAM: Address W R\n" \
- " -------------\n");
-// 12345 00 11
+ DBG_P(1, "\nSRAM: Address W R\n" \
+ " ------------------\n");
}
- printf(" %.5lx %.2x %.2x\n", addr, wval, rval);
-
- if (++errors > 16 )
+ errors++;
+ if (errors > 20) {
+ DBG_P(1, " ...\n");
break;
+ }
+ DBG_P(1, " 0x%.5lx 0x%.2x 0x%.2x\n", addr, wval, rval);
}
addr++;
wval += inc;
@@ -129,10 +123,9 @@ static uint32_t z80_sram_cmp(uint32_t addr, uint32_t length, uint8_t wval, int i
return addr;
}
-#if 0
-static void z80_sram_fill(uint32_t addr, int length, uint8_t startval, int inc)
+static void z80_sram_fill(uint32_t addr, uint32_t length, uint8_t startval, int inc)
{
- printf("SRAM: Write %#.5x byte... ", length); //fflush(stdout);
+ printf("SRAM: Write 0x%.5lx byte... ", length);
while (length--) {
z80_write(addr, startval);
++addr;
@@ -142,6 +135,7 @@ static void z80_sram_fill(uint32_t addr, int length, uint8_t startval, int inc)
}
+#if 0
void z80_sram_fill_string(uint32_t addr, int length, const char *text)
{
char c;
@@ -192,6 +186,8 @@ uint8_t z80_get_byte(uint32_t adr)
static void do_10ms(void)
{
+ if (to_counter)
+ to_counter--;
}
/*--------------------------------------------------------------------------*/
@@ -344,6 +340,22 @@ void check_msg_fifo(void)
}
+/*--------------------------------------------------------------------------*/
+
+void dump_mem(const __flash uint8_t *addr, uint32_t len)
+{
+ DBG_P(1, "hdrom dump:");
+ while (len) {
+ DBG_P(1, "\n %.5x:", addr);
+ for (unsigned i = 0; i<16; i++)
+ DBG_P(1, " %.2x", *addr++);
+ len -= len > 16 ? 16 : len;
+ }
+ DBG_P(1, "\n");
+}
+
+/*--------------------------------------------------------------------------*/
+
void z80_load_mem(void)
{
unsigned sec = 0;
@@ -357,56 +369,171 @@ void z80_load_mem(void)
hdrom_address[sec]+hdrom_length_of_sections[sec] - 1,
hdrom_length_of_sections[sec]);
- z80_write_block((unsigned char *) &hdrom[sec_base], /* src */
+ z80_write_block((const __flash unsigned char *) &hdrom[sec_base], /* src */
hdrom_address[sec], /* dest */
hdrom_length_of_sections[sec]); /* len */
sec_base+=hdrom_length_of_sections[sec];
sec++;
}
}
+
+/*--------------------------------------------------------------------------*/
+
+void z80_dump_mem(uint32_t addr, uint32_t len)
+{
+ DBG_P(1, "Memory dump:");
+ while (len) {
+ DBG_P(1, "\n %.5lx:", addr);
+ for (unsigned i = 0; i<16; i++)
+ DBG_P(1, " %.2x", z80_read(addr++));
+ len -= len > 16 ? 16 : len;
+ }
+ DBG_P(1, "\n");
+}
+
/*--------------------------------------------------------------------------*/
+void setup_rtc(void)
+{
+ /* TODO: */
+}
+
+void setup_avr(void)
+{
+ /* WD */
+
+ /* CPU */
+
+ /* Disable JTAG Interface regardless of the JTAGEN fuse setting. */
+ MCUCR = _BV(JTD);
+ MCUCR = _BV(JTD);
+
+ /* disable unused periphels */
+ PRR0 = _BV(PRTIM2) | _BV(PRTIM0) | _BV(PRADC);
+ PRR1 = _BV(PRTIM5) | _BV(PRTIM4) | _BV(PRTIM3) |
+ _BV(PRUSART3) | _BV(PRUSART2) | _BV(PRUSART1);
+
+ /* disable analog comparator */
+ ACSR = _BV(ACD);
+ /* Ports */
+
+ /* Clock */
+ CLKPR = _BV(CLKPCE);
+ CLKPR = 0;
+
+ /* Timer */
+
+ OCR1A = F_CPU / 8 / 1000 - 1; // Timer1: 1000Hz interval (OC1A)
+ TCCR1B = 0b00001010;
+ TIMSK1 = _BV(OCIE1A); // Enable TC1.oca interrupt
+}
+
+const __flash uint8_t iniprog[] = {
+ 0xAF, // xor a
+ 0xED, 0x39, 0x36, // out0 (rcr),a ;disable DRAM refresh
+ 0x3E, 0x30, // ld a,030h
+ 0xED, 0x39, 0x32 //out0 (dcntl),a ;0 mem, max i/0 wait states
+};
+
+const __flash uint8_t sertest[] = {
+ 0xAF, // xor a
+ 0xED, 0x39, 0x36, // out0 (rcr),a ;disable DRAM refresh
+ 0x3E, 0x30, // ld a,030h
+ 0xED, 0x39, 0x32, // out0 (dcntl),a ;0 mem, max i/0 wait states
+ 0x3E, 0x80, // ld a,M_MPBT ;no MP, PS=10, DR=16, SS=0
+ 0xED, 0x39, 0x03, // out0 (cntlb1),a
+ 0x3E, 0x64, // ld a,M_RE + M_TE + M_MOD2 ;
+ 0xED, 0x39, 0x01, // out0 (cntla1),a
+ 0x3E, 0x00, // ld a,0
+ 0xED, 0x39, 0x05, // out0 (stat1),a ;Enable rx interrupts
+ 0xED, 0x38, 0x05, //l0:in0 a,(stat1)
+ 0xE6, 0x80, // and 80h
+ 0x28, 0xF9, // jr z,l0
+ 0xED, 0x00, 0x09, // in0 b,(rdr1)
+ 0xED, 0x38, 0x05, //l1:in0 a,(stat1)
+ 0xE6, 0x02, // and 02h
+ 0x28, 0xF9, // jr z,l1
+ 0xED, 0x01, 0x07, // out0 (tdr1),b
+ 0x18, 0xEA, // jr l0
+};
+
+const __flash uint8_t test1[] = {
+ 0xAF, // xor a
+ 0xED, 0x39, 0x36, // out0 (rcr),a ;disable DRAM refresh
+ 0x3E, 0x30, // ld a,030h
+ 0xED, 0x39, 0x32, // out0 (dcntl),a ;0 mem, max i/0 wait states
+ 0x21, 0x1E, 0x00, // ld hl,dmclrt ;load DMA registers
+ 0x06, 0x08, // ld b,dmct_e-dmclrt
+ 0x0E, 0x20, // ld c,sar0l
+ 0xED, 0x93, // otimr
+ 0x3E, 0xC3, // ld a,0c3h ;dst +1, src +1, burst
+ 0xED, 0x39, 0x31, // out0 (dmode),a ;
+ 0x3E, 0x62, // ld a,062h ;enable dma0,
+ 0xED, 0x39, 0x30, //cl_1: out0 (dstat),a ;copy 64k
+ 0x18, 0xFB, // jr cl_1 ;
+ 0x00, 0x00, //dmclrt: dw 0 ;src (inc)
+ 0x00, // db 0 ;src
+ 0x00, 0x00, // dw 0 ;dst (inc),
+ 0x00, // db 0 ;dst
+ 0x00, 0x00, // dw 0 ;count (64k)
+};
+
+
int main(void)
{
int_fast8_t state = 0;
int ch;
-// setvbuf(stdout, NULL, _IONBF, 0);
+ setup_avr();
serial_setup();
-// printf("\n(STM32F100+HD64180)_stamp Tester\n");
- printf("\n(ATMEGA1281+HD64180)_stamp Tester\n");
+ setup_rtc();
+ sei();
+
+ printf_P(PSTR("\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_sram_fill(0, (uint32_t)512 * 1024, 0x00, 3);
+// z80_sram_cmp(0, (uint32_t)512 * 1024, 0x00, 3);
+// z80_dump_mem(0, 0x400);
+
z80_memset(0, 0x76, 0x80000);
- //z80_sram_fill(0, 512 * 1024, 0x76, 0);
- z80_sram_cmp(0, (uint32_t)512 * 1024, 0x76, 0);
+// z80_memset(0, 0x00, 0x80000);
+// z80_write_block(test1, 0, sizeof(test1));
+
+// z80_dump_mem(0, 0x100);
+
+// z80_sram_cmp(0, (uint32_t)512 * 1024, 0x76, 0);
z80_load_mem();
+// z80_write(0, 0x76);
+// z80_dump_mem(0, 0x200);
+
+
z80_reset(LOW);
DBG_P(1, "Bus released!\n");
z80_release_bus();
z80_reset(HIGH);
DBG_P(1, "Reset released!\n");
-
+ to_counter = 200;
+
while (1) {
if (Stat & S_10MS_TO) {
Stat &= ~S_10MS_TO;
do_10ms();
}
-
+
if ((ch = serial_getc()) >= 0) {
switch (state) {
@@ -414,8 +541,12 @@ int main(void)
if (ch == ESCCHAR) {
state = 1;
/* TODO: Timer starten */
- } else
- z80_memfifo_putc(fifo_out, ch);
+ } else {
+// z80_memfifo_putc(fifo_out, ch);
+ serial_putc(ch);
+ if (ch == '\r')
+ serial_putc('\n');
+ }
break;
case 1:
switch (ch) {
@@ -424,16 +555,32 @@ int main(void)
z80_reset_pulse();
break;
+ case 'b':
+ z80_request_bus();
+ z80_dump_mem(0, 0x2d20);
+ z80_release_bus();
+ break;
+
+ case 'e':
+ z80_request_bus();
+ z80_dump_mem(0x80000-0x4000, 0x800);
+ z80_dump_mem(0x80000-0x200, 0x200);
+ z80_release_bus();
+ break;
+
case ESCCHAR:
default:
- z80_memfifo_putc(fifo_out, ch);
+// z80_memfifo_putc(fifo_out, ch);
+ serial_putc(ch);
+ if (ch == '\r')
+ serial_putc('\n');
}
state = 0;
break;
}
}
- check_msg_fifo();
+// check_msg_fifo();
}
return 0;
diff --git a/avr/z80-if.c b/avr/z80-if.c
index 955a61a..207aed1 100644
--- a/avr/z80-if.c
+++ b/avr/z80-if.c
@@ -95,6 +95,7 @@ struct bits {
#define BUSREQ 7
#define DDR_BUSREQ DDRD
#define P_BUSACK PORTD
+#define PIN_BUSACK PIND
#define BUSACK 6
#define DDR_BUSACK DDRD
//#define P_HALT PORTA
@@ -117,8 +118,8 @@ struct bits {
#define P_ADH PORTC
#define P_ADB PORTE
#define PIN_ADB PINE
-#define DDR_ADL DDRE
-#define DDR_ADH DDRE
+#define DDR_ADL DDRA
+#define DDR_ADH DDRC
#define DDR_ADB DDRE
#define ADB_WIDTH 3
@@ -126,49 +127,16 @@ struct bits {
//#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_BUSACK SBIT(PIN_BUSACK, 6)
//#define Z80_I_HALT SBIT(P_HALT, )
+
void z80_busreq(level_t level)
{
Z80_O_BUSREQ = level;
@@ -210,25 +178,31 @@ typedef union {
/*--------------------------------------------------------------------------*/
-
-/*
- * A0..A6, A8..A13 are buffered. No need to disable.
- * A7, A14..A18: set to input.
- */
-
-static void z80_setup_adrbus_tristate(void)
+static void z80_setup_addrbus_tristate(void)
{
+ /* /MREQ, /RD, /WR: Input, no pullup */
+ DDR_MREQ &= ~(_BV(MREQ) | _BV(RD) | _BV(WR));
+ Z80_O_MREQ = 0;
+ Z80_O_RD = 0;
+ Z80_O_WR = 0;
+
P_ADL = 0;
DDR_ADL = 0;
P_ADH = 0;
DDR_ADH = 0;
- PIN_ADB = P_ADB & MASK(ADB_WIDTH) << ADB_SHIFT;
+ 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)
+static void z80_setup_addrbus_active(void)
{
+ /* /MREQ, /RD, /WR: Output and high */
+ Z80_O_MREQ = 1;
+ Z80_O_RD = 1;
+ Z80_O_WR = 1;
+ DDR_MREQ |= _BV(MREQ) | _BV(RD) | _BV(WR);
+
DDR_ADL = 0xff;
DDR_ADH = 0xff;
DDR_ADB = DDR_ADB | (MASK(ADB_WIDTH) << ADB_SHIFT);
@@ -247,66 +221,66 @@ 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)
{
+ /* /ZRESET: Output and low */
Z80_O_RST = 0;
DDR_RST |= _BV(RST);
+ /* /BUSREQ: Output and high */
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);
-
+ /* /BUSACK: Input, no pullup */
DDR_BUSACK &= ~_BV(BUSACK);
P_BUSACK &= ~_BV(BUSACK);
+ /* /IOCS1: Input, no pullup */
DDR_IOCS1 &= ~_BV(IOCS1);
P_IOCS1 &= ~_BV(IOCS1);
- //Z80_O_BUSREQ = 0;
- //while(Z80_I_BUSACK == 1);
-
- z80_setup_adrbus_tristate();
+ z80_setup_addrbus_tristate();
z80_setup_dbus_in();
}
+/*--------------------------------------------------------------------------*/
+
void z80_request_bus(void)
{
Z80_O_BUSREQ = 0;
while(Z80_I_BUSACK == 1);
- z80_setup_adrbus_active();
+ z80_setup_addrbus_active();
}
void z80_release_bus(void)
{
z80_setup_dbus_in();
- z80_setup_adrbus_tristate();
+ z80_setup_addrbus_tristate();
Z80_O_BUSREQ = 1;
- while(Z80_I_BUSACK == 0);
+ //while(Z80_I_BUSACK == 0);
+}
+
+/*--------------------------------------------------------------------------*/
+
+static
+//inline __attribute__ ((always_inline))
+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_write(uint32_t addr, uint8_t data)
{
z80_setaddress(addr);
Z80_O_MREQ = 0;
- P_DB = data;
z80_setup_dbus_out();
+ P_DB = data;
+ P_DB = data;
+ Z80_O_WR = 0;
Z80_O_WR = 0;
Z80_O_WR = 1;
Z80_O_MREQ = 1;
@@ -321,6 +295,7 @@ uint8_t z80_read(uint32_t addr)
z80_setup_dbus_in();
Z80_O_RD = 0;
Z80_O_RD = 0;
+ Z80_O_RD = 0;
data = PIN_DB;
Z80_O_RD = 1;
Z80_O_MREQ = 1;
@@ -336,13 +311,15 @@ void z80_memset(uint32_t addr, uint8_t data, uint32_t length)
while(length--) {
z80_setaddress(addr++);
P_DB = data;
+ P_DB = data;
+ Z80_O_WR = 0;
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)
+void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length)
{
uint8_t data;
@@ -352,6 +329,8 @@ void z80_write_block(uint8_t *src, uint32_t dest, uint32_t length)
z80_setaddress(dest++);
data = *src++;
P_DB = data;
+ P_DB = data;
+ Z80_O_WR = 0;
Z80_O_WR = 0;
Z80_O_WR = 1;
}
@@ -547,6 +526,7 @@ int z80_msg_fifo_getc(void)
{
int c = -1;
+#if 0
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))
@@ -558,6 +538,7 @@ int z80_msg_fifo_getc(void)
z80_release_bus();
}
}
+#endif
return c;
}
diff --git a/avr/z80-if.h b/avr/z80-if.h
index 1068225..7d08df4 100644
--- a/avr/z80-if.h
+++ b/avr/z80-if.h
@@ -10,7 +10,7 @@ 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);
+void z80_write_block(const __flash uint8_t *src, uint32_t dest, uint32_t length);
int z80_stat_halt(void);