2018-12-20 17:32:22 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2018 Marco Maccaferri and others.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This program and the accompanying materials are made available under
|
|
|
|
* the terms of the Eclipse Public License v1.0 which accompanies this
|
|
|
|
* distribution, and is available at
|
|
|
|
* http://www.eclipse.org/legal/epl-v10.html
|
|
|
|
*/
|
|
|
|
|
|
|
|
package com.maccasoft.tools;
|
|
|
|
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
|
|
|
|
|
import nl.grauw.glass.AssemblyException;
|
|
|
|
import nl.grauw.glass.Line;
|
|
|
|
import nl.grauw.glass.Scope;
|
|
|
|
import nl.grauw.glass.Source;
|
|
|
|
import nl.grauw.glass.directives.If;
|
2019-07-03 09:49:43 +00:00
|
|
|
import nl.grauw.glass.directives.Section;
|
2018-12-20 17:32:22 +00:00
|
|
|
|
|
|
|
public class IntelHexBuilder {
|
|
|
|
|
|
|
|
Source source;
|
|
|
|
|
|
|
|
int addr;
|
|
|
|
int nextAddr;
|
|
|
|
byte[] code;
|
|
|
|
ByteArrayOutputStream os;
|
|
|
|
|
|
|
|
StringBuilder sb;
|
|
|
|
|
|
|
|
public IntelHexBuilder(Source source) {
|
|
|
|
this.source = source;
|
|
|
|
}
|
|
|
|
|
|
|
|
public StringBuilder build() {
|
|
|
|
sb = new StringBuilder();
|
|
|
|
|
|
|
|
addr = -1;
|
|
|
|
nextAddr = -1;
|
|
|
|
os = new ByteArrayOutputStream();
|
|
|
|
|
|
|
|
build(source);
|
|
|
|
|
|
|
|
byte[] data = os.toByteArray();
|
|
|
|
if (data.length != 0) {
|
|
|
|
sb.append(toHexString(addr, data));
|
|
|
|
}
|
|
|
|
|
|
|
|
sb.append(":00000001FF\r\n");
|
|
|
|
|
|
|
|
return sb;
|
|
|
|
}
|
|
|
|
|
|
|
|
void build(Source source) {
|
|
|
|
for (Line line : source.getLines()) {
|
|
|
|
try {
|
|
|
|
Scope scope = line.getScope();
|
|
|
|
if (line.getDirective() instanceof If) {
|
|
|
|
code = new byte[0];
|
|
|
|
}
|
|
|
|
else if (scope.isAddressSet()) {
|
|
|
|
code = line.getBytes();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
code = new byte[0];
|
|
|
|
}
|
|
|
|
|
|
|
|
if (code.length != 0) {
|
|
|
|
if (line.getScope().getAddress() != nextAddr) {
|
|
|
|
byte[] data = os.toByteArray();
|
|
|
|
if (data.length != 0) {
|
|
|
|
sb.append(toHexString(addr, data));
|
|
|
|
}
|
|
|
|
|
|
|
|
nextAddr = addr = line.getScope().getAddress();
|
|
|
|
os = new ByteArrayOutputStream();
|
|
|
|
}
|
|
|
|
|
|
|
|
os.write(code);
|
|
|
|
nextAddr += code.length;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (line.getDirective() instanceof If) {
|
|
|
|
if (line.getInstructionObject() != null) {
|
|
|
|
nl.grauw.glass.instructions.If ins = (nl.grauw.glass.instructions.If) line.getInstruction();
|
|
|
|
build(ins.getThenSource());
|
2018-12-31 08:19:54 +00:00
|
|
|
if (ins.getElseSource() != null) {
|
|
|
|
build(ins.getElseSource());
|
|
|
|
}
|
2018-12-20 17:32:22 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
If ins = (If) line.getDirective();
|
|
|
|
build(ins.getThenSource());
|
2018-12-31 08:19:54 +00:00
|
|
|
if (ins.getElseSource() != null) {
|
|
|
|
build(ins.getElseSource());
|
|
|
|
}
|
2018-12-20 17:32:22 +00:00
|
|
|
}
|
|
|
|
}
|
2019-07-03 09:49:43 +00:00
|
|
|
else if (line.getDirective() instanceof Section) {
|
|
|
|
if (line.getInstructionObject() != null) {
|
|
|
|
nl.grauw.glass.instructions.Section ins = (nl.grauw.glass.instructions.Section) line.getInstruction();
|
|
|
|
build(ins.getSource());
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
Section ins = (Section) line.getDirective();
|
|
|
|
build(ins.getSource());
|
|
|
|
}
|
|
|
|
}
|
2018-12-20 17:32:22 +00:00
|
|
|
} catch (AssemblyException e) {
|
|
|
|
e.addContext(line);
|
|
|
|
throw e;
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String toHexString(int addr, byte[] data) {
|
|
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
while ((data.length - i) > 0) {
|
|
|
|
int l = data.length - i;
|
|
|
|
if (l > 24) {
|
|
|
|
l = 24;
|
|
|
|
}
|
|
|
|
sb.append(String.format(":%02X%04X%02X", l, addr, 0));
|
|
|
|
|
|
|
|
int checksum = l + (addr & 0xFF) + ((addr >> 8) & 0xFF) + 0;
|
|
|
|
for (int n = 0; n < l; n++, i++, addr++) {
|
|
|
|
sb.append(String.format("%02X", data[i]));
|
|
|
|
checksum += data[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
sb.append(String.format("%02X\r\n", (-checksum) & 0xFF));
|
|
|
|
}
|
|
|
|
|
|
|
|
return sb.toString();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|