]>
cloudbase.mooo.com Git - z180-stamp.git/blob - avr/cmd_loadihex.c
2 * (C) Copyright 2015 Leo C. <erbl259-lmu@yahoo.de>
4 * SPDX-License-Identifier: GPL-2.0
7 #include "cmd_loadihex.h"
10 #include "con-utils.h"
30 static int get_hexdigit(void)
33 c
= toupper(my_getchar(1));
37 c
-= ('A' - '0' - 10);
43 static int get_hexbyte(void)
47 if ((i
= (uint8_t) get_hexdigit()) < 0x10)
48 if ((j
= (uint8_t) get_hexdigit()) < 0x10) {
56 static int ihex_get_record(ihex_t
*rec
)
61 rec
->status
= IHX_BROKEN
;
65 while ((c
= my_getchar(0)) != ':') {
67 return -1; /* Control-C */
70 return 0; /*Control-D, EOF */
74 if ((c
= get_hexbyte()) < 0) /* Start code */
78 if ((c
= get_hexbyte()) < 0) /* Byte Count */
81 rec
->address
= c
* 256;
82 if ((c
= get_hexbyte()) < 0) /* Address */
86 if ((c
= get_hexbyte()) < 0) /* Record type */
91 if (rec
->len
) { /* Record Data */
94 for (n
= 0; n
< rec
->len
; n
++) {
95 if ((c
= get_hexbyte()) < 0)
106 c
= get_hexbyte(); /* Check sum */
111 rec
->status
= IHX_OK
;
113 rec
->status
= IHX_CHKSUMERR
;
120 command_ret_t
do_loadihex(cmd_tbl_t
*cmdtp UNUSED
, uint_fast8_t flag UNUSED
, int argc
, char * const argv
[])
123 uint32_t base_address
= 0;
124 uint32_t address_high
= 0;
125 uint32_t address_max
;
126 uint32_t address_low
;
127 bool firstrec
= true;
131 offset
= strtol(argv
[1], NULL
, 16);
133 int32_t ram
= z80_memsize_detect();
135 cmd_error(CMD_RET_FAILURE
, (ERRNUM
) -ram
, NULL
);
138 address_low
= address_max
;
140 my_puts_P(PSTR("Waiting for Intel Hex Records...\n"));
142 while (ihex_get_record(&rec
) > 0 &&
143 rec
.status
== IHX_OK
&&
147 case 0: /* Data record */
149 my_puts_P(PSTR("Loading: 0x....."));
153 uint32_t addr
= base_address
+ rec
.address
+ offset
;
154 if (addr
< address_low
)
156 if (addr
+rec
.len
> address_high
)
157 address_high
= addr
+ rec
.len
;
159 // debug("low: 0x%.5lX, high: 0x%.5lX, max: 0x%.5lX, addr: 0x%.5lX, len: %d\n",
160 // address_low, address_high, address_max, addr, rec.len);
161 printf_P(PSTR("\b\b\b\b\b%.5lX"), addr
);
162 if (addr
< address_max
) {
163 uint32_t tmplen
= address_max
- addr
;
164 if (rec
.len
> tmplen
)
167 z80_bus_request_or_exit();
168 z80_write_block(rec
.data
, /* src */
171 z80_bus_cmd(Release
);
177 case 1: /* EOF record */
180 case 2: /* Extended Segment Address Record */
181 base_address
= (uint32_t)((rec
.data
[0] << 8) + rec
.data
[1]) << 4;
184 case 4: /* Extended Linear Address Record */
185 base_address
= (uint32_t)((rec
.data
[0] << 8) + rec
.data
[1]) << 16;
188 case 3: /* Start Segment Address Record (ignored)*/
189 case 5: /* Start Linear Address Record (ignored)*/
195 if (rec
.status
!= IHX_OK
)
196 my_puts_P(PSTR("Broken Hex Record or loading interrupted!\n"));
198 for (uint_fast8_t i
=0; i
<100; ++i
) {
199 /* flush input buffer */
200 while (my_getchar(0) > 0)
205 my_puts_P(PSTR("\nData loaded: "));
206 if (address_low
>= MIN(address_high
, address_max
))
207 my_puts_P(PSTR("None.\n"));
209 printf_P(PSTR("low: 0x%.5lX high: 0x%.5lX\n"), address_low
,
210 MIN(address_high
, address_max
) - 1);
212 if (address_high
> address_max
)
213 printf_P(PSTR("Data above highest RAM address "
214 "(in range 0x%.5lX - 0x%.5lX) ignored!\n"), address_max
, address_high
- 1);
216 return rec
.status
== IHX_OK
? CMD_RET_SUCCESS
: CMD_RET_FAILURE
;