]> cloudbase.mooo.com Git - z180-stamp.git/blame - avr/z180-stamp-avr.c
New U-Boot like AVR main program.
[z180-stamp.git] / avr / z180-stamp-avr.c
CommitLineData
0c5890bb
L
1/*
2 */
3
4
5#include <avr/io.h>
6//#include <avr/power.h>
7//#include <avr/pgmspace.h>
9b6b4b31 8#include <avr/interrupt.h>
0c5890bb
L
9//#include <util/atomic.h>
10//#include <avr/sleep.h>
11//#include <string.h>
12
13#include <stdio.h>
14
15
16#include "debug.h"
17#include "serial.h"
18#include "z80-if.h"
19
20#define const const __flash
21#include "../z180/hdrom.h"
22#undef const
23
24#define FLASH __flash
eded7ec4 25//#define FLASH
0c5890bb
L
26
27#define ESCCHAR ('^'-0x40)
28
29#define S_10MS_TO (1<<0)
30
31
eded7ec4 32volatile int_fast8_t timeout_1s;
9b6b4b31
L
33//volatile uint_least8_t Stat;
34#define Stat GPIOR0
0c5890bb 35
9b6b4b31 36unsigned int to_counter;
0c5890bb 37
eded7ec4
L
38/****************************************************************/
39
40#define P_ADL PORTA
41#define P_ADH PORTC
42#define P_ADB PORTE
43#define PIN_ADB PINE
44
45#define ADB_WIDTH 3
46#define ADB_SHIFT 2
47//#define ADB_PORT GPIOE
48
49#define MASK(n) ((1<<(n))-1)
50#define SMASK(w,s) (MASK(w) << (s))
51
52typedef union {
53 uint32_t l;
54 uint16_t w[2];
55 uint8_t b[4];
56} addr_t;
57
58
59
0c5890bb
L
60/*--------------------------------------------------------------------------*/
61
9b6b4b31
L
62/*---------------------------------------------------------*/
63/* 1000Hz timer interrupt generated by OC1A */
64/*---------------------------------------------------------*/
0c5890bb 65
9b6b4b31 66ISR(TIMER1_COMPA_vect)
0c5890bb 67{
9b6b4b31
L
68 static int_fast8_t tick_10ms;
69// static int_fast16_t count_ms;
0c5890bb
L
70
71 int_fast8_t i;
72
eded7ec4 73
9b6b4b31
L
74 i = tick_10ms + 1;
75 if (i == 10) {
76 i = 0;
77 Stat |= S_10MS_TO;
eded7ec4 78
0c5890bb
L
79 /* Drive timer procedure of low level disk I/O module */
80 //disk_timerproc();
81 }
9b6b4b31 82 tick_10ms = i;
0c5890bb 83
9b6b4b31 84#if 0
0c5890bb
L
85 count_ms++;
86 if (count_ms == 1000) {
87 count_ms = 0;
88
89 i = timeout_1s;
90 if (i)
91 timeout_1s = i - 1;
92 }
9b6b4b31 93#endif
0c5890bb
L
94}
95
96
97/*--------------------------------------------------------------------------*/
98
99static uint32_t z80_sram_cmp(uint32_t addr, uint32_t length, uint8_t wval, int inc)
100{
101 uint8_t rval;
102 int_fast8_t errors = 0;
103
9b6b4b31 104 DBG_P(1, "SRAM: Check 0x%.5lx byte... ", length);
0c5890bb
L
105 while (length--) {
106 if ((rval = z80_read(addr)) != wval) {
107 if (errors == 0) {
9b6b4b31
L
108 DBG_P(1, "\nSRAM: Address W R\n" \
109 " ------------------\n");
0c5890bb 110 }
9b6b4b31
L
111 errors++;
112 if (errors > 20) {
113 DBG_P(1, " ...\n");
0c5890bb 114 break;
9b6b4b31
L
115 }
116 DBG_P(1, " 0x%.5lx 0x%.2x 0x%.2x\n", addr, wval, rval);
0c5890bb
L
117 }
118 addr++;
119 wval += inc;
120 }
121 DBG_P(1, "Done.\n");
122
123 return addr;
124}
125
9b6b4b31 126static void z80_sram_fill(uint32_t addr, uint32_t length, uint8_t startval, int inc)
0c5890bb 127{
9b6b4b31 128 printf("SRAM: Write 0x%.5lx byte... ", length);
0c5890bb
L
129 while (length--) {
130 z80_write(addr, startval);
131 ++addr;
132 startval += inc;
133 }
134 printf("Done.\n");
135}
136
137
9b6b4b31 138#if 0
0c5890bb
L
139void z80_sram_fill_string(uint32_t addr, int length, const char *text)
140{
141 char c;
142 const char *p = text;
143
144 while (length--) {
145 z80_write(addr++, c = *p++);
146 if (c == 0)
147 p = text;
148 }
149}
150
151
152uint32_t z80_sram_cmp_string(uint32_t addr, int length, const char *text)
153{
154 char c;
155 const char *p = text;
156
157 while (length--) {
158 c = *p++;
159 if (z80_read(addr) != c)
160 break;
161 ++addr;
162 if (c == 0)
163 p = text;
164 }
165 return addr;
166}
167
168const char * const qbfox = "Zhe quick brown fox jumps over the lazy dog!";
169const char * const qbcat = "Zhe quick brown fox jumps over the lazy cat!";
170
171#endif
172
173uint8_t z80_get_byte(uint32_t adr)
174{
175 uint8_t data;
176
177 z80_request_bus();
178 data = z80_read(adr),
179 z80_release_bus();
180
181 return data;
182}
183
eded7ec4
L
184
185/*--------------------------------------------------------------------------*/
186
187static void do_10ms(void)
188{
9b6b4b31
L
189 if (to_counter)
190 to_counter--;
eded7ec4
L
191}
192
0c5890bb
L
193/*--------------------------------------------------------------------------*/
194
195struct msg_item {
196 uint8_t fct;
197 uint8_t sub_min, sub_max;
198 void (*func)(uint8_t, int, uint8_t *);
199};
200
201uint32_t msg_to_addr(uint8_t *msg)
202{
203 union {
204 uint32_t as32;
205 uint8_t as8[4];
206 } addr;
207
208 addr.as8[0] = msg[0];
209 addr.as8[1] = msg[1];
210 addr.as8[2] = msg[2];
211 addr.as8[3] = 0;
212
213 return addr.as32;
214}
215
216void do_msg_ini_msgfifo(uint8_t subf, int len, uint8_t * msg)
217{
218 (void)subf; (void)len;
219
220 z80_init_msg_fifo(msg_to_addr(msg));
221}
222
223
224void do_msg_ini_memfifo(uint8_t subf, int len, uint8_t * msg)
225{
226 (void)len;
227
228 z80_memfifo_init(subf - 1, msg_to_addr(msg));
229}
230
231
232void do_msg_char_out(uint8_t subf, int len, uint8_t * msg)
233{
234 (void)subf;
235
236 while (len--)
237 putchar(*msg++);
238}
239
240
241const FLASH struct msg_item z80_messages[] =
242{
243 { 0, /* fct nr. */
244 0, 0, /* sub fct nr. from, to */
d684c216 245 do_msg_ini_msgfifo},
0c5890bb
L
246 { 0,
247 1, 2,
d684c216 248 do_msg_ini_memfifo},
0c5890bb
L
249 { 1,
250 1, 1,
d684c216 251 do_msg_char_out},
0c5890bb
L
252 { 0xff, /* end mark */
253 0, 0,
254 0},
255
256};
257
258
eded7ec4
L
259
260
0c5890bb
L
261void do_message(int len, uint8_t *msg)
262{
263 uint8_t fct, sub_fct;
264 int_fast8_t i = 0;
265
266 if (len >= 2) {
267 fct = *msg++;
268 sub_fct = *msg++;
269 len -= 2;
270
271 while (fct != z80_messages[i].fct)
272 ++i;
273
274 if (z80_messages[i].fct == 0xff) {
275 DBG_P(1, "do_message: Unknown function: %i, %i\n",
276 fct, sub_fct);
277 return; /* TODO: unknown message # */
278 }
279
280 while (fct == z80_messages[i].fct) {
281 if (sub_fct >= z80_messages[i].sub_min && sub_fct <= z80_messages[i].sub_max )
282 break;
283 ++i;
284 }
285
286 if (z80_messages[i].fct != fct) {
287 DBG_P(1, "do_message: Unknown sub function: %i, %i\n",
288 fct, sub_fct);
289 return; /* TODO: unknown message sub# */
290 }
291
292 (z80_messages[i].func)(sub_fct, len, msg);
293
294
295 } else {
296 /* TODO: error */
297 DBG_P(1, "do_message: to few arguments (%i); this shouldn't happen!\n", len);
298 }
299}
300
301
eded7ec4 302
0c5890bb
L
303#define CTRBUF_LEN 256
304
305void check_msg_fifo(void)
306{
307 int ch;
308 static int_fast8_t state;
309 static int msglen,idx;
310 static uint8_t buffer[CTRBUF_LEN];
311
312 while (state != 3 && (ch = z80_msg_fifo_getc()) >= 0) {
313 switch (state) {
314 case 0: /* wait for start of message */
315 if (ch == 0x81) {
316 msglen = 0;
317 idx = 0;
318 state = 1;
319 }
320 break;
321 case 1: /* get msg len */
322 if (ch > 0 && ch <= CTRBUF_LEN) {
323 msglen = ch;
324 state = 2;
325 } else
326 state = 0;
327 break;
328 case 2: /* get message */
329 buffer[idx++] = ch;
330 if (idx == msglen)
331 state = 3;
332 break;
333 }
334 }
335
336 if (state == 3) {
337 do_message(msglen, buffer);
338 state = 0;
339 }
340}
341
342
9b6b4b31
L
343/*--------------------------------------------------------------------------*/
344
345void dump_mem(const __flash uint8_t *addr, uint32_t len)
346{
347 DBG_P(1, "hdrom dump:");
348 while (len) {
349 DBG_P(1, "\n %.5x:", addr);
350 for (unsigned i = 0; i<16; i++)
351 DBG_P(1, " %.2x", *addr++);
352 len -= len > 16 ? 16 : len;
353 }
354 DBG_P(1, "\n");
355}
356
357/*--------------------------------------------------------------------------*/
358
0c5890bb
L
359void z80_load_mem(void)
360{
361 unsigned sec = 0;
362 uint32_t sec_base = hdrom_start;
363
364 DBG_P(1, "Loading z80 memory... \n");
365
366 while (sec < hdrom_sections) {
367 DBG_P(2, " From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n",
368 hdrom_address[sec],
369 hdrom_address[sec]+hdrom_length_of_sections[sec] - 1,
370 hdrom_length_of_sections[sec]);
371
9b6b4b31 372 z80_write_block((const __flash unsigned char *) &hdrom[sec_base], /* src */
0c5890bb
L
373 hdrom_address[sec], /* dest */
374 hdrom_length_of_sections[sec]); /* len */
375 sec_base+=hdrom_length_of_sections[sec];
376 sec++;
377 }
378}
9b6b4b31
L
379
380/*--------------------------------------------------------------------------*/
381
382void z80_dump_mem(uint32_t addr, uint32_t len)
383{
384 DBG_P(1, "Memory dump:");
385 while (len) {
386 DBG_P(1, "\n %.5lx:", addr);
387 for (unsigned i = 0; i<16; i++)
388 DBG_P(1, " %.2x", z80_read(addr++));
389 len -= len > 16 ? 16 : len;
390 }
391 DBG_P(1, "\n");
392}
393
0c5890bb
L
394/*--------------------------------------------------------------------------*/
395
9b6b4b31
L
396void setup_rtc(void)
397{
398 /* TODO: */
399}
400
401void setup_avr(void)
402{
403 /* WD */
404
405 /* CPU */
406
407 /* Disable JTAG Interface regardless of the JTAGEN fuse setting. */
408 MCUCR = _BV(JTD);
409 MCUCR = _BV(JTD);
410
411 /* disable unused periphels */
412 PRR0 = _BV(PRTIM2) | _BV(PRTIM0) | _BV(PRADC);
413 PRR1 = _BV(PRTIM5) | _BV(PRTIM4) | _BV(PRTIM3) |
414 _BV(PRUSART3) | _BV(PRUSART2) | _BV(PRUSART1);
415
416 /* disable analog comparator */
417 ACSR = _BV(ACD);
418 /* Ports */
419
420 /* Clock */
421 CLKPR = _BV(CLKPCE);
422 CLKPR = 0;
423
424 /* Timer */
425
426 OCR1A = F_CPU / 8 / 1000 - 1; // Timer1: 1000Hz interval (OC1A)
427 TCCR1B = 0b00001010;
428 TIMSK1 = _BV(OCIE1A); // Enable TC1.oca interrupt
429}
430
431const __flash uint8_t iniprog[] = {
432 0xAF, // xor a
433 0xED, 0x39, 0x36, // out0 (rcr),a ;disable DRAM refresh
434 0x3E, 0x30, // ld a,030h
435 0xED, 0x39, 0x32 //out0 (dcntl),a ;0 mem, max i/0 wait states
436};
437
438const __flash uint8_t sertest[] = {
439 0xAF, // xor a
440 0xED, 0x39, 0x36, // out0 (rcr),a ;disable DRAM refresh
441 0x3E, 0x30, // ld a,030h
442 0xED, 0x39, 0x32, // out0 (dcntl),a ;0 mem, max i/0 wait states
443 0x3E, 0x80, // ld a,M_MPBT ;no MP, PS=10, DR=16, SS=0
444 0xED, 0x39, 0x03, // out0 (cntlb1),a
445 0x3E, 0x64, // ld a,M_RE + M_TE + M_MOD2 ;
446 0xED, 0x39, 0x01, // out0 (cntla1),a
447 0x3E, 0x00, // ld a,0
448 0xED, 0x39, 0x05, // out0 (stat1),a ;Enable rx interrupts
449 0xED, 0x38, 0x05, //l0:in0 a,(stat1)
450 0xE6, 0x80, // and 80h
451 0x28, 0xF9, // jr z,l0
452 0xED, 0x00, 0x09, // in0 b,(rdr1)
453 0xED, 0x38, 0x05, //l1:in0 a,(stat1)
454 0xE6, 0x02, // and 02h
455 0x28, 0xF9, // jr z,l1
456 0xED, 0x01, 0x07, // out0 (tdr1),b
457 0x18, 0xEA, // jr l0
458};
459
460const __flash uint8_t test1[] = {
461 0xAF, // xor a
462 0xED, 0x39, 0x36, // out0 (rcr),a ;disable DRAM refresh
463 0x3E, 0x30, // ld a,030h
464 0xED, 0x39, 0x32, // out0 (dcntl),a ;0 mem, max i/0 wait states
465 0x21, 0x1E, 0x00, // ld hl,dmclrt ;load DMA registers
466 0x06, 0x08, // ld b,dmct_e-dmclrt
467 0x0E, 0x20, // ld c,sar0l
468 0xED, 0x93, // otimr
469 0x3E, 0xC3, // ld a,0c3h ;dst +1, src +1, burst
470 0xED, 0x39, 0x31, // out0 (dmode),a ;
471 0x3E, 0x62, // ld a,062h ;enable dma0,
472 0xED, 0x39, 0x30, //cl_1: out0 (dstat),a ;copy 64k
473 0x18, 0xFB, // jr cl_1 ;
474 0x00, 0x00, //dmclrt: dw 0 ;src (inc)
475 0x00, // db 0 ;src
476 0x00, 0x00, // dw 0 ;dst (inc),
477 0x00, // db 0 ;dst
478 0x00, 0x00, // dw 0 ;count (64k)
479};
480
481
0c5890bb
L
482int main(void)
483{
484 int_fast8_t state = 0;
485 int ch;
486
9b6b4b31 487 setup_avr();
0c5890bb 488 serial_setup();
9b6b4b31
L
489 setup_rtc();
490 sei();
491
492 printf_P(PSTR("\n(ATMEGA1281+HD64180)_stamp Tester\n"));
0c5890bb
L
493
494 DBG_P(1, "z80_setup_bus... ");
495 z80_setup_msg_fifo();
496 z80_setup_bus();
497 DBG_P(1, "done.\n");
498
0c5890bb
L
499 DBG_P(1, "Get bus... ");
500 z80_busreq(LOW);
501 z80_reset(HIGH);
502 z80_request_bus();
503 DBG_P(1, "got it!\n");
504
9b6b4b31
L
505// z80_sram_fill(0, (uint32_t)512 * 1024, 0x00, 3);
506// z80_sram_cmp(0, (uint32_t)512 * 1024, 0x00, 3);
507// z80_dump_mem(0, 0x400);
508
0c5890bb 509 z80_memset(0, 0x76, 0x80000);
9b6b4b31
L
510// z80_memset(0, 0x00, 0x80000);
511// z80_write_block(test1, 0, sizeof(test1));
512
513// z80_dump_mem(0, 0x100);
514
515// z80_sram_cmp(0, (uint32_t)512 * 1024, 0x76, 0);
0c5890bb
L
516
517 z80_load_mem();
9b6b4b31
L
518// z80_write(0, 0x76);
519// z80_dump_mem(0, 0x200);
520
521
0c5890bb
L
522 z80_reset(LOW);
523 DBG_P(1, "Bus released!\n");
524 z80_release_bus();
525 z80_reset(HIGH);
526 DBG_P(1, "Reset released!\n");
527
9b6b4b31
L
528 to_counter = 200;
529
0c5890bb
L
530 while (1) {
531
532 if (Stat & S_10MS_TO) {
533 Stat &= ~S_10MS_TO;
534 do_10ms();
535 }
9b6b4b31 536
0c5890bb
L
537
538 if ((ch = serial_getc()) >= 0) {
539 switch (state) {
540 case 0:
541 if (ch == ESCCHAR) {
542 state = 1;
543 /* TODO: Timer starten */
9b6b4b31
L
544 } else {
545// z80_memfifo_putc(fifo_out, ch);
546 serial_putc(ch);
547 if (ch == '\r')
548 serial_putc('\n');
549 }
0c5890bb
L
550 break;
551 case 1:
552 switch (ch) {
553
554 case 'r':
555 z80_reset_pulse();
556 break;
557
9b6b4b31
L
558 case 'b':
559 z80_request_bus();
560 z80_dump_mem(0, 0x2d20);
561 z80_release_bus();
562 break;
563
564 case 'e':
565 z80_request_bus();
566 z80_dump_mem(0x80000-0x4000, 0x800);
567 z80_dump_mem(0x80000-0x200, 0x200);
568 z80_release_bus();
569 break;
570
0c5890bb
L
571 case ESCCHAR:
572 default:
9b6b4b31
L
573// z80_memfifo_putc(fifo_out, ch);
574 serial_putc(ch);
575 if (ch == '\r')
576 serial_putc('\n');
0c5890bb
L
577 }
578 state = 0;
579 break;
580 }
581 }
582
9b6b4b31 583// check_msg_fifo();
0c5890bb
L
584 }
585
586 return 0;
587}