]>
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+
13 #include "con-utils.h"
18 uint32_t detect_ramsize(void)
21 uint8_t save_addr
, save_0
;
22 const uint8_t PATTERN_1
= 0x55;
23 const uint8_t PATTERN_2
= ~PATTERN_1
;
25 if (!(z80_bus_cmd(Request
) & ZST_ACQUIRED
)) {
26 my_puts_P(PSTR("Bus timeout\n"));
31 z80_write(0, PATTERN_1
);
33 for (addr
=1; addr
< CONFIG_SYS_RAMSIZE_MAX
; addr
<<= 1) {
34 save_addr
= z80_read(addr
);
35 z80_write(addr
, PATTERN_2
);
36 if (z80_read(0) != PATTERN_1
|| z80_read(addr
) != PATTERN_2
)
38 z80_write(addr
, save_addr
);
46 static uint32_t min(uint32_t a
, uint32_t b
)
70 int get_hexdigit(void) {
73 c
= toupper(my_getchar(1));
77 c
-= ('A' - '0' - 10);
84 int get_hexbyte(void) {
88 if ((i
= (uint8_t) get_hexdigit()) < 0x10)
89 if ((j
= (uint8_t) get_hexdigit()) < 0x10) {
99 ihex_t
ihex_get_record() {
103 ihex_t rec
= { IHX_BROKEN
, 0, 0, 0, 0 };
106 while ((c
= my_getchar(0)) != ':')
110 if ((i
= get_hexbyte()) < 0) /* Start code */
114 if ((i
= get_hexbyte()) < 0) /* Byte Count */
117 rec
.address
= i
* 256;
118 if ((i
= get_hexbyte()) < 0) /* Address */
122 if ((i
= get_hexbyte()) < 0) /* Record type */
127 if (rec
.len
) { /* Record Data */
129 if ((rec
.data
= malloc(rec
.len
)) == 0)
132 for (p
=rec
.data
, k
=rec
.len
; k
; k
--) {
133 if ((i
= get_hexbyte()) < 0)
140 free(rec
.data
); rec
.data
= 0;
145 i
= get_hexbyte(); /* Check sum */
152 rec
.status
= IHX_CHKSUMERR
;
155 if (rec
.status
!= IHX_OK
) {
166 int ihex_get_record(ihex_t
*rec
) {
171 rec
->status
= IHX_BROKEN
;
174 while ((c
= my_getchar(0)) != ':')
178 if ((c
= get_hexbyte()) < 0) /* Start code */
182 if ((c
= get_hexbyte()) < 0) /* Byte Count */
185 rec
->address
= c
* 256;
186 if ((c
= get_hexbyte()) < 0) /* Address */
190 if ((c
= get_hexbyte()) < 0) /* Record type */
195 if (rec
->len
) { /* Record Data */
198 for (n
= 0; n
< rec
->len
; n
++) {
199 if ((c
= get_hexbyte()) < 0)
210 c
= get_hexbyte(); /* Check sum */
215 rec
->status
= IHX_OK
;
217 rec
->status
= IHX_CHKSUMERR
;
225 command_ret_t
do_loadihex(cmd_tbl_t
*cmdtp
, int flag
, int argc
, char * const argv
[])
228 uint32_t base_address
= 0;
229 uint32_t address_max
= detect_ramsize();
230 uint32_t address_high
= 0;
231 uint32_t address_low
= address_max
;
232 command_ret_t rcode
= CMD_RET_FAILURE
;
235 (void) cmdtp
; (void) flag
;
238 printf_P(PSTR("RAM Size: 0x%.5lX\n"), address_max
);
242 offset
= strtol(argv
[1], NULL
, 16);
244 while (ihex_get_record(&rec
) > 0 &&
245 rec
.status
== IHX_OK
&&
249 case 0: /* Data record */
251 uint32_t addr
= base_address
+ rec
.address
+ offset
;
252 if (addr
< address_low
)
254 if (addr
+rec
.len
> address_high
)
255 address_high
= addr
+ rec
.len
;
258 printf_P(PSTR("low: 0x%.5lX, high: 0x%.5lX, max: 0x%.5lX, addr: 0x%.5lX, len: %d\n"),
259 address_low
, address_high
, address_max
, addr
, rec
.len
);
261 if (addr
< address_max
) {
262 uint32_t tmplen
= address_max
- addr
;
263 if (rec
.len
> tmplen
)
266 if (!(z80_bus_cmd(Request
) & ZST_ACQUIRED
)) {
267 my_puts_P(PSTR("Bus timeout\n"));
268 return CMD_RET_FAILURE
;
270 z80_write_block(rec
.data
, /* src */
273 z80_bus_cmd(Release
);
279 case 1: /* EOF record */
282 case 2: /* Extended Segment Address Record */
283 base_address
= ((rec
.data
[0] << 8) + rec
.data
[1]) << 4;
286 case 4: /* Extended Linear Address Record */
287 base_address
= (uint32_t)((rec
.data
[0] << 8) + rec
.data
[1]) << 16;
290 case 3: /* Start Segment Address Record (ignored)*/
291 case 5: /* Start Linear Address Record (ignored)*/
297 switch (rec
.status
) {
299 rcode
= CMD_RET_SUCCESS
;
304 printf_P(PSTR("Broken Hex Record or loading interrupted!\n"));
308 printf_P(PSTR("Data loaded: "));
309 if (address_low
>= min(address_high
, address_max
))
310 printf_P(PSTR("None.\n"));
312 printf_P(PSTR("low: 0x%.5lX high: 0x%.5lX\n"), address_low
,
313 min(address_high
, address_max
) - 1);
315 if (address_high
> address_max
)
316 printf_P(PSTR("Data above highest RAM address "
317 "(Range 0x%.5lX...0x%.5lX) ignored!\n"), address_max
, address_high
- 1);