altoslib: Add symbols to .ihx files
authorKeith Packard <keithp@keithp.com>
Mon, 9 Dec 2013 03:46:30 +0000 (19:46 -0800)
committerKeith Packard <keithp@keithp.com>
Mon, 9 Dec 2013 03:46:30 +0000 (19:46 -0800)
Create a new 0xfe record type to hold the symbols, and append them
after the EOF record so that other tools might continue to work.

Signed-off-by: Keith Packard <keithp@keithp.com>
altoslib/AltosHexfile.java
altoslib/AltosHexsym.java [new file with mode: 0644]
altoslib/Makefile.am

index 90352927433f219e1a79c359554c84b2e40009d7..02b083269fd06eb8b76494e90c52405c8a637018 100644 (file)
@@ -116,7 +116,7 @@ class HexRecord implements Comparable<Object> {
                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<Object> {
 
                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<Object> {
 }
 
 public class AltosHexfile {
-       public int      address;
-       public byte[]   data;
+       public int              address;
+       public byte[]           data;
+       LinkedList<AltosHexsym> symlist = new LinkedList<AltosHexsym>();
 
        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<HexRecord>   record_list = new LinkedList<HexRecord>();
                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,14 @@ 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;
+                               if (name.startsWith("ao_romconfig"))
+                                       System.out.printf ("%08x: %s\n", addr, name);
+                               AltosHexsym s = new AltosHexsym(name, addr);
+                               symlist.add(s);
+                               break;
                        default:
                                throw new IOException ("invalid hex record type");
                        }
@@ -292,6 +360,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");
                        }
diff --git a/altoslib/AltosHexsym.java b/altoslib/AltosHexsym.java
new file mode 100644 (file)
index 0000000..810a480
--- /dev/null
@@ -0,0 +1,30 @@
+/*
+ * Copyright © 2013 Keith Packard <keithp@keithp.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ */
+
+package org.altusmetrum.altoslib_2;
+
+public class AltosHexsym {
+       String  name;
+       long    address;
+
+       final static long invalid_addr = 0xffffffff;
+
+       public AltosHexsym(String name, long address) {
+               this.name = name;
+               this.address = address;
+       }
+}
\ No newline at end of file
index 6d3f3fc49862111f877bb000baaf60ae790e3284..b95bd071b0779495f00334a0cd3e708521369634 100644 (file)
@@ -55,6 +55,7 @@ altoslib_JAVA = \
        AltosGPSSat.java \
        AltosGreatCircle.java \
        AltosHexfile.java \
+       AltosHexsym.java \
        AltosIdle.java \
        AltosIdleFetch.java \
        AltosIdleMonitor.java \
@@ -68,6 +69,7 @@ altoslib_JAVA = \
        AltosMag.java \
        AltosMma655x.java \
        AltosMs5607.java \
+       AltosNoSymbol.java \
        AltosParse.java \
        AltosPreferences.java \
        AltosPreferencesBackend.java \