Created
May 13, 2020 08:29
-
-
Save agatti/150f1db354c2503280ffe25462e5f6f7 to your computer and use it in GitHub Desktop.
CP1600 SBIDECLE data type Raw
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 SignedBiDecleDataType extends AbstractIntegerDataType { | |
public final static SignedBiDecleDataType dataType = new SignedBiDecleDataType(); | |
public SignedBiDecleDataType() { | |
this(null); | |
} | |
public SignedBiDecleDataType(DataTypeManager dtm) { | |
super("sbidecle", true, dtm); | |
} | |
@Override | |
public int getLength() { | |
return getDataOrganization().getIntegerSize(); | |
} | |
@Override | |
public boolean isDynamicallySized() { | |
return true; | |
} | |
@Override | |
public String getDescription() { | |
return "Signed 16-bit data type spread over two words"; | |
} | |
@Override | |
public String getCDeclaration() { | |
return C_SIGNED_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); | |
} | |
long abs = Math.abs(truncated) & 0x7FFF; | |
return new Scalar(getLength() * 8, ((truncated & 0x8000) == 0x8000) ? -abs : abs, | |
(truncated & 0x8000) == 0x8000); | |
} | |
@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[2]; | |
if (ENDIAN.isBigEndian(settings, buf)) { | |
buffer[0] = (byte) ((scalar.getUnsignedValue() & 0xFF00) >> 8); | |
buffer[1] = (byte) (scalar.getUnsignedValue() & 0x00FF); | |
} else { | |
buffer[0] = (byte) (scalar.getUnsignedValue() & 0x00FF); | |
buffer[1] = (byte) ((scalar.getUnsignedValue() & 0xFF00) >> 8); | |
} | |
if (getFormatSettingsDefinition().getFormat(settings) == FormatSettingsDefinition.CHAR) { | |
return StringDataInstance.getCharRepresentation(this, buffer, settings); | |
} | |
// Truncate to two bytes as it is still a word underneath... | |
return super.getRepresentation(new BigInteger(buffer), settings, 16); | |
} | |
return super.getRepresentation(buf, settings, length); | |
} | |
@Override | |
public AbstractIntegerDataType getOppositeSignednessDataType() { | |
return BiDecleDataType.dataType.clone(getDataTypeManager()); | |
} | |
@Override | |
public SignedBiDecleDataType clone(DataTypeManager dtm) { | |
if (dtm == getDataTypeManager()) { | |
return this; | |
} | |
return new SignedBiDecleDataType(dtm); | |
} | |
@Override | |
public String getCTypeDeclaration(DataOrganization dataOrganization) { | |
return "short"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment