Created
May 13, 2020 08:28
-
-
Save agatti/a1c9b57fa7b4d7129aa1b09f8c62f149 to your computer and use it in GitHub Desktop.
CP1600 BIDECLE data type
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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