mirror of
https://github.com/fadden/6502bench.git
synced 2024-09-10 13:54:52 +00:00
We were failing to update properly when a label changed if the label was one that a plugin cared about. The problem is that a label add/remove operation skips the code analysis, and a label edit skips everything but the display update. Plugins only run during the code analysis pass, so changes weren't being reflected in the display list until something caused it to refresh. The solution is to ask the plugin if the label being changed is one that it cares about. This allows the plugin to use the same wildcard-match logic that it uses elsewhere. For efficiency, and to reduce clutter in plugins that don't care about symbols, a new interface class has been created to handle the "here are the symbols" call and the "do you care about this label" call. The program in Examples/Scripts has been updated to show a very simple single-call plugin and a slightly more complex multi-call plugin.
160 lines
6.7 KiB
C#
160 lines
6.7 KiB
C#
// Copyright 2019 faddenSoft. All Rights Reserved.
|
|
// See the LICENSE.txt file for distribution terms (Apache 2.0).
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
|
|
using PluginCommon;
|
|
|
|
namespace RuntimeData.Test2022 {
|
|
public class Test2022A : MarshalByRefObject, IPlugin, IPlugin_SymbolList,
|
|
IPlugin_InlineJsr, IPlugin_InlineJsl {
|
|
private IApplication mAppRef;
|
|
private byte[] mFileData;
|
|
|
|
private int mInline8StringAddr; // jsr
|
|
private int mInlineRev8StringAddr; // jsr
|
|
private int mInlineNullStringAddr; // jsr
|
|
private int mInlineL1StringAddr; // jsl
|
|
private int mInlineL2StringAddr; // jsl
|
|
private int mInlineDciStringAddr; // jsl
|
|
|
|
public string Identifier {
|
|
get {
|
|
return "Test 2022-extension-scripts A";
|
|
}
|
|
}
|
|
|
|
public void Prepare(IApplication appRef, byte[] fileData, AddressTranslate addrTrans) {
|
|
mAppRef = appRef;
|
|
mFileData = fileData;
|
|
|
|
mAppRef.DebugLog("Test2022-A(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
|
}
|
|
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
|
foreach (PlSymbol sym in plSyms) {
|
|
switch (sym.Label) {
|
|
case "PrintInline8String":
|
|
mInline8StringAddr = sym.Value;
|
|
break;
|
|
case "PrintInlineRev8String":
|
|
mInlineRev8StringAddr = sym.Value;
|
|
break;
|
|
case "PrintInlineNullString":
|
|
mInlineNullStringAddr = sym.Value;
|
|
break;
|
|
case "PrintInlineL1String":
|
|
mInlineL1StringAddr = sym.Value;
|
|
break;
|
|
case "PrintInlineL2String":
|
|
mInlineL2StringAddr = sym.Value;
|
|
break;
|
|
case "PrintInlineDciString":
|
|
mInlineDciStringAddr = sym.Value;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
public bool IsLabelSignificant(string beforeLabel, string afterLabel) {
|
|
const string PREFIX = "PrintInline"; // all interesting labels start with this
|
|
return (beforeLabel.StartsWith(PREFIX) || afterLabel.StartsWith(PREFIX));
|
|
}
|
|
|
|
public void CheckJsr(int offset, out bool noContinue) {
|
|
noContinue = false;
|
|
int target = Util.GetWord(mFileData, offset + 1, 2, false);
|
|
if (target == mInline8StringAddr) {
|
|
if (offset + 3 + 8 > mFileData.Length) {
|
|
mAppRef.DebugLog("8string ran off end at +" +
|
|
(offset + 3).ToString("x6"));
|
|
return;
|
|
}
|
|
mAppRef.SetInlineDataFormat(offset + 3, 8,
|
|
DataType.StringGeneric, DataSubType.Ascii, null);
|
|
} else if (target == mInlineRev8StringAddr) {
|
|
if (offset + 3 + 8 > mFileData.Length) {
|
|
mAppRef.DebugLog("rev8string ran off end at +" +
|
|
(offset + 3).ToString("x6"));
|
|
return;
|
|
}
|
|
mAppRef.SetInlineDataFormat(offset + 3, 8,
|
|
DataType.StringReverse, DataSubType.Ascii, null);
|
|
} else if (target == mInlineNullStringAddr) {
|
|
// look for the terminating null byte
|
|
int nullOff = offset + 3;
|
|
while (nullOff < mFileData.Length) {
|
|
if (mFileData[nullOff] == 0) {
|
|
break;
|
|
}
|
|
nullOff++;
|
|
}
|
|
if (nullOff == mFileData.Length) {
|
|
mAppRef.DebugLog("Unable to find end of null-terminated string at +" +
|
|
(offset+3).ToString("x6"));
|
|
return;
|
|
}
|
|
mAppRef.SetInlineDataFormat(offset + 3, nullOff - (offset + 3) + 1,
|
|
DataType.StringNullTerm, DataSubType.Ascii, null);
|
|
}
|
|
}
|
|
|
|
public void CheckJsl(int offset, out bool noContinue) {
|
|
noContinue = false;
|
|
int target = Util.GetWord(mFileData, offset + 1, 3, false);
|
|
if (target == mInlineL1StringAddr) {
|
|
// 0 1 2 3 4 5
|
|
// 22 00 10 01 01 66
|
|
if (offset + 4 >= mFileData.Length) {
|
|
return; // length byte is off end
|
|
}
|
|
int len = mFileData[offset + 4]; // 1-byte len in first byte past 4-byte JSL
|
|
if (offset + 5 + len > mFileData.Length) {
|
|
// ran off the end
|
|
mAppRef.DebugLog("L1 string ran off end of file at +" +
|
|
(offset + 4).ToString("x6"));
|
|
return;
|
|
}
|
|
mAppRef.SetInlineDataFormat(offset + 4, len + 1,
|
|
DataType.StringL8, DataSubType.Ascii, null);
|
|
} else if (target == mInlineL2StringAddr) {
|
|
if (offset + 5 >= mFileData.Length) {
|
|
return; // length word is off end
|
|
}
|
|
int len = Util.GetWord(mFileData, offset + 4, 2, false);
|
|
if (offset + 6 + len > mFileData.Length) {
|
|
// ran off the end
|
|
mAppRef.DebugLog("L2 string ran off end of file at +" +
|
|
(offset+4).ToString("x6"));
|
|
return;
|
|
}
|
|
mAppRef.SetInlineDataFormat(offset + 4, len + 2,
|
|
DataType.StringL16, DataSubType.Ascii, null);
|
|
} else if (target == mInlineDciStringAddr) {
|
|
// look for the first byte whose high bit doesn't match the first byte's bit
|
|
// 0 1 2 3 4 5
|
|
// 22 00 30 01 66 c1
|
|
if (offset + 3 + 2 >= mFileData.Length) {
|
|
// need at least two bytes
|
|
return;
|
|
}
|
|
byte firstBit = (byte) (mFileData[offset + 4] & 0x80);
|
|
int endOff = offset + 5;
|
|
while (endOff < mFileData.Length) {
|
|
if ((mFileData[endOff] & 0x80) != firstBit) {
|
|
break;
|
|
}
|
|
endOff++;
|
|
}
|
|
if (endOff == mFileData.Length) {
|
|
mAppRef.DebugLog("Unable to find end of DCI string at +" +
|
|
(offset+4).ToString("x6"));
|
|
return;
|
|
}
|
|
mAppRef.SetInlineDataFormat(offset + 4, endOff - (offset + 4) + 1,
|
|
DataType.StringDci, DataSubType.Ascii, null);
|
|
}
|
|
}
|
|
}
|
|
}
|