avr: initial commit
[z80.git] / avr / monitor / ihex.c
1 /* IHEX loader */
2
3 #include <avr/pgmspace.h>
4
5 #include <stdio.h>
6
7 #include "../mem.h"
8 #include "../uart.h"
9 #include "../monitor.h"
10
11 static uint8_t get_hex(char c)
12 {
13         switch(c) {
14         case '0': return 0;
15         case '1': return 1;
16         case '2': return 2;
17         case '3': return 3;
18         case '4': return 4;
19         case '5': return 5;
20         case '6': return 6;
21         case '7': return 7;
22         case '8': return 8;
23         case '9': return 9;
24         case 'A': case 'a': return 10;
25         case 'B': case 'b': return 11;
26         case 'C': case 'c': return 12;
27         case 'D': case 'd': return 13;
28         case 'E': case 'e': return 14;
29         case 'F': case 'f': return 15;
30         }
31 }
32
33 void menu_ihex(void)
34 {
35         char c;
36
37         uint8_t  state = 0;
38         uint8_t  len, count, sum, type = 0;
39         uint16_t addr;
40         uint8_t  byte;
41         uint8_t  echo = uart_echo;
42
43         mem_start();
44         uart_echo = 0;
45         printf_P(PSTR("Please send IHEX file now.\n"));
46
47         while(type != 0x01) {
48                 /* wait for RECORD START */
49                 sum = 0;
50                 while(c != ':') c = uart_getc(NULL);
51
52                 /* read RECORD LENGTH */
53                 c=uart_getc(NULL); len  = get_hex(c) << 4;
54                 c=uart_getc(NULL); len |= get_hex(c);
55                 sum += len;
56
57                 /* read LOAD OFFSET */
58                 c=uart_getc(NULL); addr  = get_hex(c) << 12;
59                 c=uart_getc(NULL); addr |= get_hex(c) <<  8;
60                 c=uart_getc(NULL); addr |= get_hex(c) <<  4;
61                 c=uart_getc(NULL); addr |= get_hex(c);
62                 sum += (addr >> 8);
63                 sum += (addr & 0xFF);
64
65                 /* read RECORD TYPE */
66                 c=uart_getc(NULL); type  = get_hex(c) << 4;
67                 c=uart_getc(NULL); type |= get_hex(c);
68                 sum += type;
69
70                 /* read DATA */
71                 for(uint8_t i = 0; i < len; i++) {
72                         c = uart_getc(NULL); byte  = get_hex(c) << 4;
73                         c = uart_getc(NULL); byte |= get_hex(c);
74                         sum += byte;
75
76                         mem_write(addr + i, byte);
77                 }
78
79                 /* read CHKSUM */
80                 c = uart_getc(NULL); byte  = get_hex(c) << 4;
81                 c = uart_getc(NULL); byte |= get_hex(c);
82                 sum += byte;
83
84                 if(sum) printf_P(PSTR("\nFAIL:0x%02x"), sum);
85                 else    printf_P(PSTR("\r0x%04x"), addr);
86         }
87
88         /* read last CRLF */
89         if((char)(uart_getc(NULL)) == '\r') uart_getc(NULL);
90
91         printf_P(PSTR("\nReading IHEX file finished.\n"));
92         uart_echo = echo;
93         mem_stop();
94 }
95