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