+ public long address;
+ public long max_address;
+ public byte[] data;
+ LinkedList<AltosHexsym> symlist = new LinkedList<AltosHexsym>();
+
+ public byte get_byte(long a) {
+ return data[(int) (a - address)];
+ }
+
+ public int get_u8(long a) {
+ return ((int) get_byte(a)) & 0xff;
+ }
+
+ public int get_u16(long a) {
+ return get_u8(a) | (get_u8(a+1) << 8);
+ }
+
+ /* 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)
+ };
+
+ static final int AO_USB_DESC_DEVICE = 1;
+ static final int AO_USB_DESC_STRING = 3;
+
+ static final int AO_ROMCONFIG_VERSION_INDEX = 0;
+ static final int AO_ROMCONFIG_CHECK_INDEX = 1;
+ static final int AO_SERIAL_NUMBER_INDEX = 2;
+ static final int AO_RADIO_CAL_INDEX = 3;
+ static final int AO_USB_DESCRIPTORS_INDEX = 4;
+
+ 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 static final int look_around[] = { 0, -2, 2, -4, 4 };
+
+ private long find_usb_descriptors() {
+ AltosHexsym usb_descriptors = lookup_symbol("ao_usb_descriptors");
+ long a;
+
+ if (usb_descriptors == null)
+ return -1;
+
+ /* The address of this has moved depending on padding
+ * in the linker script and romconfig symbols. Look
+ * forward and backwards two and four bytes to see if
+ * we can find it
+ */
+ a = usb_descriptors.address;
+
+ for (int look : look_around) {
+ try {
+ if (get_u8(a + look) == 0x12 && get_u8(a + look + 1) == AO_USB_DESC_DEVICE)
+ return a;
+ } catch (ArrayIndexOutOfBoundsException ae) {
+ continue;
+ }
+ }
+ return -1;
+ }