summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2013-03-24 15:35:15 -0700
committerKeith Packard <keithp@keithp.com>2013-05-07 20:16:52 -0700
commit9acd488c5f945511f813d84c3c6f69846d4601e8 (patch)
tree6c9f67f3b7c8d3287c8c75981569be6b399b544f
parentc9ba2d17b979410acfa41f9954674757f7f321fc (diff)
altosui: Support 32-bit ihx files
This just borrows the same 32-bit ihx parsing changes from ao-tools. Signed-off-by: Keith Packard <keithp@keithp.com>
-rw-r--r--altosui/AltosHexfile.java79
1 files changed, 64 insertions, 15 deletions
diff --git a/altosui/AltosHexfile.java b/altosui/AltosHexfile.java
index 56875f53..625c5ba1 100644
--- a/altosui/AltosHexfile.java
+++ b/altosui/AltosHexfile.java
@@ -228,21 +228,70 @@ public class AltosHexfile {
else
record_list.add(record);
}
- HexRecord[] records = record_list.toArray(new HexRecord[0]);
- Arrays.sort(records);
- if (records.length > 0) {
- int base = records[0].address;
- int bound = records[records.length-1].address +
- records[records.length-1].data.length;
-
- data = new byte[bound - base];
- address = base;
- Arrays.fill(data, (byte) 0xff);
-
- /* Paint the records into the new array */
- for (int i = 0; i < records.length; i++) {
- for (int j = 0; j < records[i].data.length; j++)
- data[records[i].address - base + j] = records[i].data[j];
+
+ long extended_addr = 0;
+ long base = 0xffffffff;
+ long bound = 0x00000000;
+ for (HexRecord record : record_list) {
+ switch (record.type) {
+ case 0:
+ long addr = extended_addr + record.address;
+ long r_bound = addr + record.data.length;
+ if (addr < base)
+ base = addr;
+ if (r_bound > bound)
+ bound = r_bound;
+ break;
+ case 1:
+ break;
+ case 2:
+ if (record.data.length != 2)
+ throw new IOException("invalid extended segment address record");
+ extended_addr = ((record.data[0] << 8) + (record.data[1])) << 4;
+ break;
+ case 4:
+ if (record.data.length != 2)
+ throw new IOException("invalid extended segment address record");
+ extended_addr = ((record.data[0] << 8) + (record.data[1])) << 16;
+ break;
+ default:
+ throw new IOException ("invalid hex record type");
+ }
+ }
+
+ if (base >= bound)
+ throw new IOException("invalid hex file");
+
+ if (bound - base > 4 * 1024 * 1024)
+ throw new IOException("hex file too large");
+
+ data = new byte[(int) (bound - base)];
+ address = (int) base;
+ Arrays.fill(data, (byte) 0xff);
+
+ /* Paint the records into the new array */
+ for (HexRecord record : record_list) {
+ switch (record.type) {
+ case 0:
+ long addr = extended_addr + record.address;
+ long r_bound = addr + record.data.length;
+ for (int j = 0; j < record.data.length; j++)
+ data[(int) (addr - base) + j] = record.data[j];
+ break;
+ case 1:
+ break;
+ case 2:
+ if (record.data.length != 2)
+ throw new IOException("invalid extended segment address record");
+ extended_addr = ((record.data[0] << 8) + (record.data[1])) << 4;
+ break;
+ case 4:
+ if (record.data.length != 2)
+ throw new IOException("invalid extended segment address record");
+ extended_addr = ((record.data[0] << 8) + (record.data[1])) << 16;
+ break;
+ default:
+ throw new IOException ("invalid hex record type");
}
}
}