]> cloudbase.mooo.com Git - z180-stamp.git/blob - avr/z180-stamp-avr.c
Refactor Tupfiles
[z180-stamp.git] / avr / z180-stamp-avr.c
1 /*
2 */
3
4
5 #include <avr/io.h>
6 //#include <avr/power.h>
7 //#include <avr/pgmspace.h>
8 //#include <avr/interrupt.h>
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
25
26 #define ESCCHAR ('^'-0x40)
27
28 #define S_10MS_TO (1<<0)
29
30
31 static volatile int_fast8_t timeout_1s;
32 static volatile uint_least8_t Stat;
33
34
35 /*--------------------------------------------------------------------------*/
36
37
38 void sys_tick_handler(void)
39 {
40 static int_fast8_t tick_10ms = 0;
41 static int_fast16_t count_ms = 0;
42
43 int_fast8_t i;
44
45 ++tick_10ms;
46 if (tick_10ms == 10)
47 {
48 Stat |= S_10MS_TO;
49 tick_10ms = 0;
50 /* Drive timer procedure of low level disk I/O module */
51 //disk_timerproc();
52 }
53
54 count_ms++;
55 if (count_ms == 1000) {
56 count_ms = 0;
57
58 i = timeout_1s;
59 if (i)
60 timeout_1s = i - 1;
61 }
62 }
63
64
65 static void do_10ms(void)
66 {
67 }
68
69 /*--------------------------------------------------------------------------*/
70
71 static uint32_t z80_sram_cmp(uint32_t addr, uint32_t length, uint8_t wval, int inc)
72 {
73 uint8_t rval;
74 int_fast8_t errors = 0;
75
76 DBG_P(1, "SRAM: Check 0x%.5lX byte... ", length);
77 while (length--) {
78 if ((rval = z80_read(addr)) != wval) {
79 if (errors == 0) {
80 printf("\nSRAM: Address W R\n" \
81 " -------------\n");
82 // 12345 00 11
83 }
84 printf(" %.5lx %.2x %.2x\n", addr, wval, rval);
85
86 if (++errors > 16 )
87 break;
88 }
89 addr++;
90 wval += inc;
91 }
92 DBG_P(1, "Done.\n");
93
94 return addr;
95 }
96
97 #if 0
98 static void z80_sram_fill(uint32_t addr, int length, uint8_t startval, int inc)
99 {
100 printf("SRAM: Write %#.5x byte... ", length); //fflush(stdout);
101 while (length--) {
102 z80_write(addr, startval);
103 ++addr;
104 startval += inc;
105 }
106 printf("Done.\n");
107 }
108
109
110 void z80_sram_fill_string(uint32_t addr, int length, const char *text)
111 {
112 char c;
113 const char *p = text;
114
115 while (length--) {
116 z80_write(addr++, c = *p++);
117 if (c == 0)
118 p = text;
119 }
120 }
121
122
123 uint32_t z80_sram_cmp_string(uint32_t addr, int length, const char *text)
124 {
125 char c;
126 const char *p = text;
127
128 while (length--) {
129 c = *p++;
130 if (z80_read(addr) != c)
131 break;
132 ++addr;
133 if (c == 0)
134 p = text;
135 }
136 return addr;
137 }
138
139 const char * const qbfox = "Zhe quick brown fox jumps over the lazy dog!";
140 const char * const qbcat = "Zhe quick brown fox jumps over the lazy cat!";
141
142 #endif
143
144 /*--------------------------------------------------------------------------*/
145
146 uint8_t z80_get_byte(uint32_t adr)
147 {
148 uint8_t data;
149
150 z80_request_bus();
151 data = z80_read(adr),
152 z80_release_bus();
153
154 return data;
155 }
156
157 /*--------------------------------------------------------------------------*/
158
159 struct msg_item {
160 uint8_t fct;
161 uint8_t sub_min, sub_max;
162 void (*func)(uint8_t, int, uint8_t *);
163 };
164
165 static
166 uint32_t msg_to_addr(uint8_t *msg)
167 {
168 union {
169 uint32_t as32;
170 uint8_t as8[4];
171 } addr;
172
173 addr.as8[0] = msg[0];
174 addr.as8[1] = msg[1];
175 addr.as8[2] = msg[2];
176 addr.as8[3] = 0;
177
178 return addr.as32;
179 }
180
181 static
182 void do_msg_ini_msgfifo(uint8_t subf, int len, uint8_t * msg)
183 {
184 (void)subf; (void)len;
185
186 z80_init_msg_fifo(msg_to_addr(msg));
187 }
188
189
190 static
191 void do_msg_ini_memfifo(uint8_t subf, int len, uint8_t * msg)
192 {
193 (void)len;
194
195 z80_memfifo_init(subf - 1, msg_to_addr(msg));
196 }
197
198
199 static
200 void do_msg_char_out(uint8_t subf, int len, uint8_t * msg)
201 {
202 (void)subf;
203
204 while (len--)
205 putchar(*msg++);
206 }
207
208
209 static
210 const FLASH struct msg_item z80_messages[] =
211 {
212 { 0, /* fct nr. */
213 0, 0, /* sub fct nr. from, to */
214 &do_msg_ini_msgfifo},
215 { 0,
216 1, 2,
217 &do_msg_ini_memfifo},
218 { 1,
219 1, 1,
220 &do_msg_char_out},
221 { 0xff, /* end mark */
222 0, 0,
223 0},
224
225 };
226
227
228 static
229 void do_message(int len, uint8_t *msg)
230 {
231 uint8_t fct, sub_fct;
232 int_fast8_t i = 0;
233
234 if (len >= 2) {
235 fct = *msg++;
236 sub_fct = *msg++;
237 len -= 2;
238
239 while (fct != z80_messages[i].fct)
240 ++i;
241
242 if (z80_messages[i].fct == 0xff) {
243 DBG_P(1, "do_message: Unknown function: %i, %i\n",
244 fct, sub_fct);
245 return; /* TODO: unknown message # */
246 }
247
248 while (fct == z80_messages[i].fct) {
249 if (sub_fct >= z80_messages[i].sub_min && sub_fct <= z80_messages[i].sub_max )
250 break;
251 ++i;
252 }
253
254 if (z80_messages[i].fct != fct) {
255 DBG_P(1, "do_message: Unknown sub function: %i, %i\n",
256 fct, sub_fct);
257 return; /* TODO: unknown message sub# */
258 }
259
260 (z80_messages[i].func)(sub_fct, len, msg);
261
262
263 } else {
264 /* TODO: error */
265 DBG_P(1, "do_message: to few arguments (%i); this shouldn't happen!\n", len);
266 }
267 }
268
269
270 //TODO:
271 #define CTRBUF_LEN 256
272
273 static
274 void check_msg_fifo(void)
275 {
276 int ch;
277 static int_fast8_t state;
278 static int msglen,idx;
279 static uint8_t buffer[CTRBUF_LEN];
280
281 while (state != 3 && (ch = z80_msg_fifo_getc()) >= 0) {
282 switch (state) {
283 case 0: /* wait for start of message */
284 if (ch == 0x81) {
285 msglen = 0;
286 idx = 0;
287 state = 1;
288 }
289 break;
290 case 1: /* get msg len */
291 if (ch > 0 && ch <= CTRBUF_LEN) {
292 msglen = ch;
293 state = 2;
294 } else
295 state = 0;
296 break;
297 case 2: /* get message */
298 buffer[idx++] = ch;
299 if (idx == msglen)
300 state = 3;
301 break;
302 }
303 }
304
305 if (state == 3) {
306 do_message(msglen, buffer);
307 state = 0;
308 }
309 }
310
311
312 static
313 void z80_load_mem(void)
314 {
315 unsigned sec = 0;
316 uint32_t sec_base = hdrom_start;
317
318 DBG_P(1, "Loading z80 memory... \n");
319
320 while (sec < hdrom_sections) {
321 DBG_P(2, " From: 0x%.5lX to: 0x%.5lX (%5li bytes)\n",
322 hdrom_address[sec],
323 hdrom_address[sec]+hdrom_length_of_sections[sec] - 1,
324 hdrom_length_of_sections[sec]);
325
326 z80_write_block((unsigned char *) &hdrom[sec_base], /* src */
327 hdrom_address[sec], /* dest */
328 hdrom_length_of_sections[sec]); /* len */
329 sec_base+=hdrom_length_of_sections[sec];
330 sec++;
331 }
332 }
333
334 /*--------------------------------------------------------------------------*/
335
336 int main(void)
337 {
338 int_fast8_t state = 0;
339 int ch;
340
341 // setvbuf(stdout, NULL, _IONBF, 0);
342 serial_setup();
343 printf("\n(ATMEGA1281+HD64180)_stamp Tester\n");
344
345 DBG_P(1, "z80_setup_bus... ");
346 z80_setup_msg_fifo();
347 z80_setup_bus();
348 DBG_P(1, "done.\n");
349
350 DBG_P(1, "Get bus... ");
351 z80_busreq(LOW);
352 z80_reset(HIGH);
353 z80_request_bus();
354 DBG_P(1, "got it!\n");
355
356 z80_memset(0, 0x76, 0x80000);
357 //z80_sram_fill(0, 512 * 1024, 0x76, 0);
358 z80_sram_cmp(0, (uint32_t)512 * 1024, 0x76, 0);
359
360 z80_load_mem();
361 z80_reset(LOW);
362 DBG_P(1, "Bus released!\n");
363 z80_release_bus();
364 z80_reset(HIGH);
365 DBG_P(1, "Reset released!\n");
366
367
368 while (1) {
369
370 if (Stat & S_10MS_TO) {
371 Stat &= ~S_10MS_TO;
372 do_10ms();
373 }
374
375
376 if ((ch = serial_getc()) >= 0) {
377 switch (state) {
378 case 0:
379 if (ch == ESCCHAR) {
380 state = 1;
381 /* TODO: Timer starten */
382 } else
383 z80_memfifo_putc(fifo_out, ch);
384 break;
385 case 1:
386 switch (ch) {
387
388 case 'r':
389 z80_reset_pulse();
390 break;
391
392 case ESCCHAR:
393 default:
394 z80_memfifo_putc(fifo_out, ch);
395 }
396 state = 0;
397 break;
398 }
399 }
400
401 check_msg_fifo();
402 }
403
404 return 0;
405 }