Skip to content

Instantly share code, notes, and snippets.

@agatti
Created May 13, 2020 08:28
Show Gist options
  • Save agatti/a1c9b57fa7b4d7129aa1b09f8c62f149 to your computer and use it in GitHub Desktop.
Save agatti/a1c9b57fa7b4d7129aa1b09f8c62f149 to your computer and use it in GitHub Desktop.
CP1600 BIDECLE data type
package ghidra.program.model.data;
import java.math.BigInteger;
import ghidra.docking.settings.FormatSettingsDefinition;
import ghidra.docking.settings.Settings;
import ghidra.program.model.mem.MemBuffer;
import ghidra.program.model.scalar.Scalar;
public class BiDecleDataType extends AbstractIntegerDataType {
public final static BiDecleDataType dataType = new BiDecleDataType();
public BiDecleDataType() {
this(null);
}
public BiDecleDataType(DataTypeManager dtm) {
super("bidecle", false, dtm);
}
@Override
public int getLength() {
return getDataOrganization().getIntegerSize();
}
@Override
public boolean isDynamicallySized() {
return true;
}
@Override
public String getDescription() {
return "16-bit data type spread over two words";
}
@Override
public String getCDeclaration() {
return C_UNSIGNED_SHORT;
}
private Object getScalar(MemBuffer buf, Settings settings, int length) {
Object value = super.getValue(buf, settings, length);
long truncated;
if (value instanceof BigInteger) {
truncated = ((BigInteger) value).intValue() & 0x00FF00FF;
} else if (value instanceof Scalar) {
truncated = (int) ((Scalar) value).getValue() & 0x00FF00FF;
} else {
return value;
}
if (ENDIAN.isBigEndian(settings, buf)) {
truncated = ((truncated & 0x00FF0000) >> 16) | ((truncated & 0x000000FF) << 8);
} else {
truncated = ((truncated & 0x00FF0000) >> 8) | (truncated & 0x000000FF);
}
return new Scalar(getLength() * 8, truncated, false);
}
@Override
public Object getValue(MemBuffer buf, Settings settings, int length) {
return getScalar(buf, settings, length);
}
@Override
public String getRepresentation(MemBuffer buf, Settings settings, int length) {
Object possibleScalar = getScalar(buf, settings, length);
if (possibleScalar instanceof Scalar) {
Scalar scalar = (Scalar) possibleScalar;
byte[] buffer = new byte[4];
if (ENDIAN.isBigEndian(settings, buf)) {
buffer[2] = (byte) ((scalar.getUnsignedValue() & 0xFF00) >> 8);
buffer[3] = (byte) (scalar.getUnsignedValue() & 0x00FF);
} else {
buffer[2] = (byte) (scalar.getUnsignedValue() & 0x00FF);
buffer[3] = (byte) ((scalar.getUnsignedValue() & 0xFF00) >> 8);
}
if (getFormatSettingsDefinition().getFormat(settings) == FormatSettingsDefinition.CHAR) {
return StringDataInstance.getCharRepresentation(this, buffer, settings);
}
return super.getRepresentation(new BigInteger(buffer), settings, 8 * length);
}
return super.getRepresentation(buf, settings, length);
}
@Override
public AbstractIntegerDataType getOppositeSignednessDataType() {
return SignedBiDecleDataType.dataType.clone(getDataTypeManager());
}
@Override
public BiDecleDataType clone(DataTypeManager dtm) {
if (dtm == getDataTypeManager()) {
return this;
}
return new BiDecleDataType(dtm);
}
@Override
public String getCTypeDeclaration(DataOrganization dataOrganization) {
return "unsigned short";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment