mirror of
https://github.com/fadden/6502bench.git
synced 2024-11-29 10:50:28 +00:00
Format ProDOS 8 parameter blocks
If it's a known function, apply basic numeric formatting to the various fields. Primarily of value for the pathname and buffer parameters, which are formatted as addresses. Also, enable horizontal scrolling in the generic show-text dialog.
This commit is contained in:
parent
dc8e49e4d8
commit
57d8514faa
@ -33,9 +33,127 @@ namespace RuntimeData.Apple {
|
|||||||
private const string P8_MLI_TAG = "ProDOS8-MLI-Functions"; // tag used in .sym65 file
|
private const string P8_MLI_TAG = "ProDOS8-MLI-Functions"; // tag used in .sym65 file
|
||||||
private bool VERBOSE = false;
|
private bool VERBOSE = false;
|
||||||
|
|
||||||
|
#region Parameter block defs
|
||||||
|
|
||||||
|
private class Param {
|
||||||
|
public DataType Type { get; private set; }
|
||||||
|
public DataSubType SubType { get; private set; }
|
||||||
|
public int Length { get; private set; }
|
||||||
|
|
||||||
|
public Param(DataType type, DataSubType subType, int length) {
|
||||||
|
Type = type;
|
||||||
|
SubType = subType;
|
||||||
|
Length = length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private static Param PARAM_COUNT = new Param(DataType.NumericLE, DataSubType.Decimal, 1);
|
||||||
|
private static Param PATHNAME = new Param(DataType.NumericLE, DataSubType.Address, 2);
|
||||||
|
private static Param BUFFER = new Param(DataType.NumericLE, DataSubType.Address, 2);
|
||||||
|
private static Param CODEPTR = new Param(DataType.NumericLE, DataSubType.Address, 2);
|
||||||
|
private static Param ACCESS = new Param(DataType.NumericLE, DataSubType.Hex, 1);
|
||||||
|
private static Param FILE_TYPE = new Param(DataType.NumericLE, DataSubType.Hex, 1);
|
||||||
|
private static Param AUX_TYPE = new Param(DataType.NumericLE, DataSubType.Hex, 2);
|
||||||
|
private static Param STORAGE_TYPE = new Param(DataType.NumericLE, DataSubType.Hex, 1);
|
||||||
|
private static Param DATE = new Param(DataType.NumericLE, DataSubType.Hex, 2);
|
||||||
|
private static Param TIME = new Param(DataType.NumericLE, DataSubType.Hex, 2);
|
||||||
|
private static Param BLOCKS_USED = new Param(DataType.NumericLE, DataSubType.Hex, 2);
|
||||||
|
private static Param UNIT_NUM = new Param(DataType.NumericLE, DataSubType.Hex, 1);
|
||||||
|
private static Param REF_NUM = new Param(DataType.NumericLE, DataSubType.Decimal, 1);
|
||||||
|
private static Param COUNT = new Param(DataType.NumericLE, DataSubType.Hex, 2);
|
||||||
|
private static Param BLOCK_NUM = new Param(DataType.NumericLE, DataSubType.Hex, 2);
|
||||||
|
private static Param POSITION = new Param(DataType.NumericLE, DataSubType.Hex, 3);
|
||||||
|
private static Param MISC1 = new Param(DataType.NumericLE, DataSubType.Hex, 1);
|
||||||
|
private static Param MISC2 = new Param(DataType.NumericLE, DataSubType.Hex, 2);
|
||||||
|
private static Param NULL3 = new Param(DataType.NumericLE, DataSubType.Hex, 3);
|
||||||
|
|
||||||
|
private Dictionary<int, Param[]> ParamDescrs = new Dictionary<int, Param[]>() {
|
||||||
|
{ 0x40, // ALLOC_INTERRUPT
|
||||||
|
new Param[] { PARAM_COUNT, MISC1, CODEPTR }
|
||||||
|
},
|
||||||
|
{ 0x41, // DEALLOC_INTERRUPT
|
||||||
|
new Param[] { PARAM_COUNT, MISC1 }
|
||||||
|
},
|
||||||
|
{ 0x65, // QUIT
|
||||||
|
new Param[] { PARAM_COUNT, MISC1, MISC2, MISC1, MISC2 }
|
||||||
|
},
|
||||||
|
{ 0x80, // READ_BLOCK
|
||||||
|
new Param[] { PARAM_COUNT, UNIT_NUM, BUFFER, BLOCK_NUM }
|
||||||
|
},
|
||||||
|
{ 0x81, // WRITE_BLOCK
|
||||||
|
new Param[] { PARAM_COUNT, UNIT_NUM, BUFFER, BLOCK_NUM }
|
||||||
|
},
|
||||||
|
// 0x82 GET_TIME has no parameter list
|
||||||
|
{ 0xc0, // CREATE
|
||||||
|
new Param[] { PARAM_COUNT, PATHNAME, ACCESS, FILE_TYPE, AUX_TYPE, STORAGE_TYPE,
|
||||||
|
DATE, TIME }
|
||||||
|
},
|
||||||
|
{ 0xc1, // DESTROY
|
||||||
|
new Param[] { PARAM_COUNT, PATHNAME }
|
||||||
|
},
|
||||||
|
{ 0xc2, // RENAME
|
||||||
|
new Param[] { PARAM_COUNT, PATHNAME, PATHNAME }
|
||||||
|
},
|
||||||
|
{ 0xc3, // SET_FILE_INFO
|
||||||
|
new Param[] { PARAM_COUNT, PATHNAME, ACCESS, FILE_TYPE, AUX_TYPE, NULL3,
|
||||||
|
DATE, TIME }
|
||||||
|
},
|
||||||
|
{ 0xc4, // GET_FILE_INFO
|
||||||
|
new Param[] { PARAM_COUNT, PATHNAME, ACCESS, FILE_TYPE, AUX_TYPE, STORAGE_TYPE,
|
||||||
|
BLOCKS_USED, DATE, TIME, DATE, TIME }
|
||||||
|
},
|
||||||
|
{ 0xc5, // ON_LINE
|
||||||
|
new Param[] { PARAM_COUNT, UNIT_NUM, BUFFER }
|
||||||
|
},
|
||||||
|
{ 0xc6, // SET_PREFIX
|
||||||
|
new Param[] { PARAM_COUNT, PATHNAME }
|
||||||
|
},
|
||||||
|
{ 0xc7, // GET_PREFIX
|
||||||
|
new Param[] { PARAM_COUNT, PATHNAME }
|
||||||
|
},
|
||||||
|
{ 0xc8, // OPEN
|
||||||
|
new Param[] { PARAM_COUNT, PATHNAME, BUFFER, REF_NUM }
|
||||||
|
},
|
||||||
|
{ 0xc9, // NEWLINE
|
||||||
|
new Param[] { PARAM_COUNT, REF_NUM, MISC1, MISC1 }
|
||||||
|
},
|
||||||
|
{ 0xca, // READ
|
||||||
|
new Param[] { PARAM_COUNT, REF_NUM, BUFFER, COUNT, COUNT }
|
||||||
|
},
|
||||||
|
{ 0xcb, // WRITE
|
||||||
|
new Param[] { PARAM_COUNT, REF_NUM, BUFFER, COUNT, COUNT }
|
||||||
|
},
|
||||||
|
{ 0xcc, // CLOSE
|
||||||
|
new Param[] { PARAM_COUNT, REF_NUM }
|
||||||
|
},
|
||||||
|
{ 0xcd, // FLUSH
|
||||||
|
new Param[] { PARAM_COUNT, REF_NUM }
|
||||||
|
},
|
||||||
|
{ 0xce, // SET_MARK
|
||||||
|
new Param[] { PARAM_COUNT, REF_NUM, POSITION }
|
||||||
|
},
|
||||||
|
{ 0xcf, // GET_MARK
|
||||||
|
new Param[] { PARAM_COUNT, REF_NUM, POSITION }
|
||||||
|
},
|
||||||
|
{ 0xd0, // SET_EOF
|
||||||
|
new Param[] { PARAM_COUNT, REF_NUM, POSITION }
|
||||||
|
},
|
||||||
|
{ 0xd1, // GET_EOF
|
||||||
|
new Param[] { PARAM_COUNT, REF_NUM, POSITION }
|
||||||
|
},
|
||||||
|
{ 0xd2, // SET_BUF
|
||||||
|
new Param[] { PARAM_COUNT, REF_NUM, BUFFER }
|
||||||
|
},
|
||||||
|
{ 0xd3, // GET_BUF
|
||||||
|
new Param[] { PARAM_COUNT, REF_NUM, BUFFER }
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#endregion Parameter block defs
|
||||||
|
|
||||||
private IApplication mAppRef;
|
private IApplication mAppRef;
|
||||||
private byte[] mFileData;
|
private byte[] mFileData;
|
||||||
private Dictionary<int, PlSymbol> mFunctionList;
|
private Dictionary<int, PlSymbol> mFunctionList;
|
||||||
|
private AddressTranslate mAddrTrans;
|
||||||
|
|
||||||
public string Identifier {
|
public string Identifier {
|
||||||
get {
|
get {
|
||||||
@ -47,10 +165,12 @@ namespace RuntimeData.Apple {
|
|||||||
List<PlSymbol> plSyms) {
|
List<PlSymbol> plSyms) {
|
||||||
mAppRef = appRef;
|
mAppRef = appRef;
|
||||||
mFileData = fileData;
|
mFileData = fileData;
|
||||||
|
mAddrTrans = addrTrans;
|
||||||
|
|
||||||
mAppRef.DebugLog("ProDOS(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
mAppRef.DebugLog("ProDOS(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
||||||
//System.Diagnostics.Debugger.Break();
|
//System.Diagnostics.Debugger.Break();
|
||||||
|
|
||||||
|
// Extract the list of function name constants from the platform symbol file.
|
||||||
mFunctionList = PlSymbol.GeneratePlatformValueList(plSyms, P8_MLI_TAG, appRef);
|
mFunctionList = PlSymbol.GeneratePlatformValueList(plSyms, P8_MLI_TAG, appRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,10 +181,10 @@ namespace RuntimeData.Apple {
|
|||||||
// match!
|
// match!
|
||||||
|
|
||||||
byte req = mFileData[offset + 3];
|
byte req = mFileData[offset + 3];
|
||||||
|
int blockAddr = Util.GetWord(mFileData, offset + 4, 2, false);
|
||||||
if (VERBOSE) {
|
if (VERBOSE) {
|
||||||
int addr = Util.GetWord(mFileData, offset + 4, 2, false);
|
|
||||||
mAppRef.DebugLog("P8 MLI call detected at +" + offset.ToString("x6") +
|
mAppRef.DebugLog("P8 MLI call detected at +" + offset.ToString("x6") +
|
||||||
", cmd=$" + req.ToString("x2") + " addr=$" + addr.ToString("x4"));
|
", cmd=$" + req.ToString("x2") + " addr=$" + blockAddr.ToString("x4"));
|
||||||
}
|
}
|
||||||
|
|
||||||
PlSymbol sym;
|
PlSymbol sym;
|
||||||
@ -78,6 +198,34 @@ namespace RuntimeData.Apple {
|
|||||||
mAppRef.SetInlineDataFormat(offset + 4, 2, DataType.NumericLE,
|
mAppRef.SetInlineDataFormat(offset + 4, 2, DataType.NumericLE,
|
||||||
DataSubType.Address, null);
|
DataSubType.Address, null);
|
||||||
|
|
||||||
|
Param[] parms;
|
||||||
|
if (ParamDescrs.TryGetValue(req, out parms)) {
|
||||||
|
// Try to format the parameter block. Start by figuring out how long it is.
|
||||||
|
int blockLen = 0;
|
||||||
|
foreach (Param parm in parms) {
|
||||||
|
blockLen += parm.Length;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Locate it and verify that the entire thing fits in the file.
|
||||||
|
int blockOff = mAddrTrans.AddressToOffset(offset, blockAddr);
|
||||||
|
if (Util.IsInBounds(mFileData, blockOff, blockLen)) {
|
||||||
|
if (VERBOSE) {
|
||||||
|
mAppRef.DebugLog("Formatting P8 block at +" + blockOff.ToString("x6"));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (Param parm in parms) {
|
||||||
|
// We could try to dereference pathname buffers to see if it's a
|
||||||
|
// fixed value and not an empty buffer, but it's hard for us to
|
||||||
|
// reliably tell the difference between a length-limited pathname
|
||||||
|
// and junk. If the length byte is bad, we run the risk of lumping
|
||||||
|
// a bunch of stuff into the pathname buffer.
|
||||||
|
mAppRef.SetInlineDataFormat(blockOff, parm.Length, parm.Type,
|
||||||
|
parm.SubType, null);
|
||||||
|
blockOff += parm.Length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (req == 0x65) { // QUIT call
|
if (req == 0x65) { // QUIT call
|
||||||
noContinue = true;
|
noContinue = true;
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,8 @@ limitations under the License.
|
|||||||
ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
|
ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
|
||||||
PreviewKeyDown="Window_KeyEventHandler">
|
PreviewKeyDown="Window_KeyEventHandler">
|
||||||
<Grid Margin="8">
|
<Grid Margin="8">
|
||||||
<TextBox Name="textBox" VerticalScrollBarVisibility="Visible"
|
<TextBox Name="textBox"
|
||||||
|
VerticalScrollBarVisibility="Visible" HorizontalScrollBarVisibility="Auto"
|
||||||
Text="{Binding DisplayText,
|
Text="{Binding DisplayText,
|
||||||
FallbackValue=0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789}"
|
FallbackValue=0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789}"
|
||||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||||
|
Loading…
Reference in New Issue
Block a user