X-Git-Url: https://git.gag.com/?p=fw%2Faltos;a=blobdiff_plain;f=altoslib%2FAltosHexfile.java;h=9ee64bdc72e585871bbeabc63e63c0a5e96229f6;hp=90352927433f219e1a79c359554c84b2e40009d7;hb=c8078d352a7f54a4a97d25af080155d3f875536a;hpb=488a527267decece48e6682e0e0c7fc29cbed329 diff --git a/altoslib/AltosHexfile.java b/altoslib/AltosHexfile.java index 90352927..9ee64bdc 100644 --- a/altoslib/AltosHexfile.java +++ b/altoslib/AltosHexfile.java @@ -15,7 +15,7 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -package org.altusmetrum.altoslib_2; +package org.altusmetrum.altoslib_5; import java.io.*; import java.util.LinkedList; @@ -116,7 +116,7 @@ class HexRecord implements Comparable { return String.format("%04x: %02x (%d)", address, type, data.length); } - public HexRecord(HexFileInputStream input) throws IOException { + public HexRecord(HexFileInputStream input) throws IOException, EOFException { read_state state = read_state.marker; int nhexbytes = 0; int hex = 0; @@ -125,14 +125,16 @@ class HexRecord implements Comparable { while (state != read_state.done) { int c = input.read(); - if (c < 0 && state != read_state.white) + if (c < 0 && state != read_state.white && state != read_state.marker) throw new IOException(String.format("%d: Unexpected EOF", input.line)); if (c == ' ') continue; switch (state) { case marker: + if (c == EOF || c == -1) + throw new EOFException(); if (c != ':') - throw new IOException("Missing ':'"); + throw new IOException(String.format ("Missing ':' (got %x)", c)); state = read_state.length; nhexbytes = 2; hex = 0; @@ -208,25 +210,82 @@ class HexRecord implements Comparable { } public class AltosHexfile { - public int address; - public byte[] data; + public int address; + public byte[] data; + LinkedList symlist = new LinkedList(); public byte get_byte(int a) { return data[a - address]; } + /* CC1111-based products have the romconfig stuff located + * at a fixed address; when the file we load has no symbols, + * assume it is one of those and set the symbols appropriately + */ + final static int ao_romconfig_version_addr = 0xa0; + final static int ao_romconfig_check_addr = 0xa2; + final static int ao_serial_number_addr = 0xa4; + final static int ao_radio_cal_addr = 0xa6; + final static int ao_usb_descriptors_addr = 0xaa; + + static AltosHexsym[] cc_symbols = { + new AltosHexsym("ao_romconfig_version", ao_romconfig_version_addr), + new AltosHexsym("ao_romconfig_check", ao_romconfig_check_addr), + new AltosHexsym("ao_serial_number", ao_serial_number_addr), + new AltosHexsym("ao_radio_cal", ao_radio_cal_addr), + new AltosHexsym("ao_usb_descriptors", ao_usb_descriptors_addr) + }; + + private void add_cc_symbols() { + for (int i = 0; i < cc_symbols.length; i++) + symlist.add(cc_symbols[i]); + } + + public void add_symbol(AltosHexsym symbol) { + symlist.add(symbol); + } + + /* Take symbols from another hexfile and duplicate them here */ + public void add_symbols(AltosHexfile other) { + for (AltosHexsym symbol : other.symlist) + symlist.add(symbol); + } + + public AltosHexsym lookup_symbol(String name) { + if (symlist.isEmpty()) + add_cc_symbols(); + + for (AltosHexsym symbol : symlist) + if (name.equals(symbol.name)) + return symbol; + return null; + } + + private String make_string(byte[] data, int start, int length) { + String s = ""; + for (int i = 0; i < length; i++) + s += (char) data[start + i]; + return s; + } + + public AltosHexfile(byte[] bytes, int offset) { + data = bytes; + address = offset; + } + public AltosHexfile(FileInputStream file) throws IOException { HexFileInputStream input = new HexFileInputStream(file); LinkedList record_list = new LinkedList(); boolean done = false; while (!done) { - HexRecord record = new HexRecord(input); + try { + HexRecord record = new HexRecord(input); - if (record.type == HexRecord.EOF) - done = true; - else record_list.add(record); + } catch (EOFException eof) { + done = true; + } } long extended_addr = 0; @@ -234,9 +293,10 @@ public class AltosHexfile { long bound = 0; boolean set = false; for (HexRecord record : record_list) { + long addr; switch (record.type) { case 0: - long addr = extended_addr + record.address; + addr = extended_addr + record.address; long r_bound = addr + record.data.length; if (!set || addr < base) base = addr; @@ -256,6 +316,12 @@ public class AltosHexfile { throw new IOException("invalid extended segment address record"); extended_addr = ((record.data[0] << 8) + (record.data[1])) << 16; break; + case 0xfe: + String name = make_string(record.data, 0, record.data.length); + addr = extended_addr + record.address; + AltosHexsym s = new AltosHexsym(name, addr); + symlist.add(s); + break; default: throw new IOException ("invalid hex record type"); } @@ -292,6 +358,8 @@ public class AltosHexfile { throw new IOException("invalid extended segment address record"); extended_addr = ((record.data[0] << 8) + (record.data[1])) << 16; break; + case 0xfe: + break; default: throw new IOException ("invalid hex record type"); }