mirror of
https://github.com/fadden/6502bench.git
synced 2026-04-27 03:17:45 +00:00
Allow scripts to handle COP and WDM inlines
The code that allows scripts to catch and handle BRK/JSR/JSL followed by inline data now also handles COP and WDM. (issue #177)
This commit is contained in:
1 parent
5a3d288707
commit
037b982d94
11 files changed
+154
-15
No files matched your search
@@ -134,6 +134,34 @@ namespace PluginCommon {
|
|||||||
void CheckBrk(int offset, bool isTwoBytes, out bool noContinue);
|
void CheckBrk(int offset, bool isTwoBytes, out bool noContinue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extension scripts that want to handle inline COPs must implement this interface.
|
||||||
|
/// </summary>
|
||||||
|
public interface IPlugin_InlineCop {
|
||||||
|
/// <summary>
|
||||||
|
/// Checks to see if code/data near a COP instruction should be formatted.
|
||||||
|
///
|
||||||
|
/// The file data is only guaranteed to hold the COP opcode byte.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">Offset of the COP instruction.</param>
|
||||||
|
/// <param name="noContinue">Set to true if the COP doesn't actually return.</param>
|
||||||
|
void CheckCop(int offset, out bool noContinue);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Extension scripts that want to handle inline WDMs must implement this interface.
|
||||||
|
/// </summary>
|
||||||
|
public interface IPlugin_InlineWdm {
|
||||||
|
/// <summary>
|
||||||
|
/// Checks to see if code/data near a WDM instruction should be formatted.
|
||||||
|
///
|
||||||
|
/// The file data is only guaranteed to hold the WDM opcode byte.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="offset">Offset of the WDM instruction.</param>
|
||||||
|
/// <param name="noContinue">Set to true if the WDM doesn't actually return.</param>
|
||||||
|
void CheckWdm(int offset, out bool noContinue);
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Extension scripts that want to generate visualizations must implement this interface.
|
/// Extension scripts that want to generate visualizations must implement this interface.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -126,7 +126,14 @@ namespace SourceGen {
|
|||||||
private IPlugin[] mScriptArray;
|
private IPlugin[] mScriptArray;
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
private enum PluginCap { NONE = 0, JSR = 1 << 0, JSL = 1 << 1, BRK = 1 << 2 };
|
private enum PluginCap {
|
||||||
|
NONE = 0,
|
||||||
|
JSR = 1 << 0,
|
||||||
|
JSL = 1 << 1,
|
||||||
|
BRK = 1 << 2,
|
||||||
|
COP = 1 << 3,
|
||||||
|
WDM = 1 << 4,
|
||||||
|
};
|
||||||
private PluginCap[] mPluginCaps;
|
private PluginCap[] mPluginCaps;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -356,6 +363,12 @@ namespace SourceGen {
|
|||||||
if (mScriptArray[i] is IPlugin_InlineBrk) {
|
if (mScriptArray[i] is IPlugin_InlineBrk) {
|
||||||
cap |= PluginCap.BRK;
|
cap |= PluginCap.BRK;
|
||||||
}
|
}
|
||||||
|
if (mScriptArray[i] is IPlugin_InlineCop) {
|
||||||
|
cap |= PluginCap.COP;
|
||||||
|
}
|
||||||
|
if (mScriptArray[i] is IPlugin_InlineWdm) {
|
||||||
|
cap |= PluginCap.WDM;
|
||||||
|
}
|
||||||
mPluginCaps[i] = cap;
|
mPluginCaps[i] = cap;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,11 +801,17 @@ namespace SourceGen {
|
|||||||
|
|
||||||
// On first visit, check for JSR/JSL inline call. If it's "no-continue",
|
// On first visit, check for JSR/JSL inline call. If it's "no-continue",
|
||||||
// set a flag and halt here.
|
// set a flag and halt here.
|
||||||
|
// Also check COP/WDM, since we assume they continue.
|
||||||
if (firstVisit) {
|
if (firstVisit) {
|
||||||
// Currently ignoring OpDef.OpJSR_AbsIndexXInd
|
// Currently ignoring OpDef.OpJSR_AbsIndexXInd
|
||||||
if (op == OpDef.OpJSR_Abs || op == OpDef.OpJSR_AbsLong) {
|
if (op == OpDef.OpJSR_Abs || op == OpDef.OpJSR_AbsLong ||
|
||||||
|
op == OpDef.OpCOP_StackInt || op == OpDef.OpWDM_WDM) {
|
||||||
bool noContinue = CheckForInlineCall(op, offset, false);
|
bool noContinue = CheckForInlineCall(op, offset, false);
|
||||||
if (noContinue) {
|
if (noContinue) {
|
||||||
|
// The "NoContinue" attribute can be updated if the code gets
|
||||||
|
// revisited, so we use a separate flag to ensure the script's
|
||||||
|
// decision doesn't get lost. See 20180-extension-scripts
|
||||||
|
// for a test case.
|
||||||
LogD(offset, "Script declared inline call no-continue");
|
LogD(offset, "Script declared inline call no-continue");
|
||||||
mAnattribs[offset].NoContinueScript = true;
|
mAnattribs[offset].NoContinueScript = true;
|
||||||
break;
|
break;
|
||||||
@@ -1086,6 +1105,12 @@ namespace SourceGen {
|
|||||||
} else if (op == OpDef.OpJSR_AbsLong && (mPluginCaps[i] & PluginCap.JSL) != 0) {
|
} else if (op == OpDef.OpJSR_AbsLong && (mPluginCaps[i] & PluginCap.JSL) != 0) {
|
||||||
((IPlugin_InlineJsl)script).CheckJsl(offset, operand, out bool noCont);
|
((IPlugin_InlineJsl)script).CheckJsl(offset, operand, out bool noCont);
|
||||||
noContinue |= noCont;
|
noContinue |= noCont;
|
||||||
|
} else if (op == OpDef.OpCOP_StackInt && (mPluginCaps[i] & PluginCap.COP) != 0){
|
||||||
|
((IPlugin_InlineCop)script).CheckCop(offset, out bool noCont);
|
||||||
|
noContinue |= noCont;
|
||||||
|
} else if (op == OpDef.OpWDM_WDM && (mPluginCaps[i] & PluginCap.WDM) != 0) {
|
||||||
|
((IPlugin_InlineWdm)script).CheckWdm(offset, out bool noCont);
|
||||||
|
noContinue |= noCont;
|
||||||
} else if ((op == OpDef.OpBRK_Implied || op == OpDef.OpBRK_StackInt) &&
|
} else if ((op == OpDef.OpBRK_Implied || op == OpDef.OpBRK_StackInt) &&
|
||||||
(mPluginCaps[i] & PluginCap.BRK) != 0) {
|
(mPluginCaps[i] & PluginCap.BRK) != 0) {
|
||||||
((IPlugin_InlineBrk)script).CheckBrk(offset, op == OpDef.OpBRK_StackInt,
|
((IPlugin_InlineBrk)script).CheckBrk(offset, op == OpDef.OpBRK_StackInt,
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
// Copyright 2025 faddenSoft. All Rights Reserved.
|
||||||
|
// See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
using PluginCommon;
|
||||||
|
|
||||||
|
// COP/WDM handler
|
||||||
|
namespace RuntimeData.Test20180 {
|
||||||
|
public class Test20180C : MarshalByRefObject, IPlugin, IPlugin_InlineCop, IPlugin_InlineWdm {
|
||||||
|
private IApplication mAppRef;
|
||||||
|
private byte[] mFileData;
|
||||||
|
private AddressTranslate mAddrTrans;
|
||||||
|
|
||||||
|
public string Identifier {
|
||||||
|
get {
|
||||||
|
return "Test 20180-extension-scripts C";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Prepare(IApplication appRef, byte[] fileData, AddressTranslate addrTrans) {
|
||||||
|
mAppRef = appRef;
|
||||||
|
mFileData = fileData;
|
||||||
|
mAddrTrans = addrTrans;
|
||||||
|
|
||||||
|
mAppRef.DebugLog("Test20180-C(id=" + AppDomain.CurrentDomain.Id + "): prepare()");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Unprepare() {
|
||||||
|
mAppRef = null;
|
||||||
|
mFileData = null;
|
||||||
|
mAddrTrans = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CheckCop(int offset, out bool noContinue) {
|
||||||
|
HandleString(offset, out noContinue);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CheckWdm(int offset, out bool noContinue) {
|
||||||
|
HandleString(offset, out noContinue);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleString(int offset, out bool noContinue) {
|
||||||
|
const int INSTR_LEN = 2; // opcode + byte
|
||||||
|
noContinue = false;
|
||||||
|
|
||||||
|
// Handle as string with 8-bit length prefix.
|
||||||
|
if (offset + INSTR_LEN >= mFileData.Length) {
|
||||||
|
return; // length byte is off end
|
||||||
|
}
|
||||||
|
int len = mFileData[offset + INSTR_LEN];
|
||||||
|
if (offset + INSTR_LEN + 1 + len > mFileData.Length) {
|
||||||
|
// ran off the end
|
||||||
|
mAppRef.DebugLog("L1 string ran off end of file at +" +
|
||||||
|
(offset + INSTR_LEN).ToString("x6"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mAppRef.SetInlineDataFormat(offset + INSTR_LEN, len + 1,
|
||||||
|
DataType.StringL8, DataSubType.Ascii, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"_ContentVersion":7,
|
"_ContentVersion":7,
|
||||||
"FileDataLength":544,
|
"FileDataLength":544,
|
||||||
"FileDataCrc32":1948144462,
|
"FileDataCrc32":371480162,
|
||||||
"ProjectProps":{
|
"ProjectProps":{
|
||||||
"CpuName":"65816",
|
"CpuName":"65816",
|
||||||
"IncludeUndocumentedInstr":false,
|
"IncludeUndocumentedInstr":false,
|
||||||
@@ -20,7 +20,8 @@
|
|||||||
|
|
||||||
"PlatformSymbolFileIdentifiers":["PROJ:20182-extension-scripts.sym65"],
|
"PlatformSymbolFileIdentifiers":["PROJ:20182-extension-scripts.sym65"],
|
||||||
"ExtensionScriptFileIdentifiers":["PROJ:20180-extension-scripts-a.cs",
|
"ExtensionScriptFileIdentifiers":["PROJ:20180-extension-scripts-a.cs",
|
||||||
"PROJ:20180-extension-scripts-b.cs"],
|
"PROJ:20180-extension-scripts-b.cs",
|
||||||
|
"PROJ:20180-extension-scripts-c.cs"],
|
||||||
"ProjectSyms":{
|
"ProjectSyms":{
|
||||||
"PrintInlineDciString":{
|
"PrintInlineDciString":{
|
||||||
"DataDescriptor":{
|
"DataDescriptor":{
|
||||||
|
|||||||
@@ -74,9 +74,14 @@ Next clc
|
|||||||
.byte $00
|
.byte $00
|
||||||
.byte $80
|
.byte $80
|
||||||
|
|
||||||
_L10B8 rts
|
_L10B8 cop #$03
|
||||||
|
.enc "sg_ascii"
|
||||||
|
.ptext "COP!"
|
||||||
|
.byte $42,$04
|
||||||
|
.ptext "WDM!"
|
||||||
|
rts
|
||||||
|
|
||||||
.fill 327,$00
|
.fill 313,$00
|
||||||
|
|
||||||
.logical $1800
|
.logical $1800
|
||||||
L1800 jsr PrintInlineNullString
|
L1800 jsr PrintInlineNullString
|
||||||
@@ -89,7 +94,6 @@ L1800 jsr PrintInlineNullString
|
|||||||
.byte $01
|
.byte $01
|
||||||
.here
|
.here
|
||||||
.logical $1840
|
.logical $1840
|
||||||
.enc "sg_ascii"
|
|
||||||
.text "string"
|
.text "string"
|
||||||
.byte $00
|
.byte $00
|
||||||
.byte $60
|
.byte $60
|
||||||
|
|||||||
@@ -68,9 +68,13 @@ Next clc
|
|||||||
!byte $00
|
!byte $00
|
||||||
!byte $80
|
!byte $80
|
||||||
|
|
||||||
@L10B8 rts
|
@L10B8 cop $03
|
||||||
|
!text $04,"COP!"
|
||||||
|
!byte $42,$04
|
||||||
|
!text $04,"WDM!"
|
||||||
|
rts
|
||||||
|
|
||||||
!fill 327,$00
|
!fill 313,$00
|
||||||
|
|
||||||
!pseudopc $1800 {
|
!pseudopc $1800 {
|
||||||
L1800 jsr PrintInlineNullString
|
L1800 jsr PrintInlineNullString
|
||||||
|
|||||||
@@ -71,9 +71,13 @@ Next: clc
|
|||||||
.byte $00
|
.byte $00
|
||||||
.byte $80
|
.byte $80
|
||||||
|
|
||||||
@L10B8: rts
|
@L10B8: cop $03
|
||||||
|
.byte $04,"COP!"
|
||||||
|
wdm $04
|
||||||
|
.byte $04,"WDM!"
|
||||||
|
rts
|
||||||
|
|
||||||
.res 327,$00
|
.res 313,$00
|
||||||
|
|
||||||
.org $1800
|
.org $1800
|
||||||
L1800: jsr PrintInlineNullString
|
L1800: jsr PrintInlineNullString
|
||||||
|
|||||||
@@ -63,9 +63,13 @@ Next clc
|
|||||||
dfb $00
|
dfb $00
|
||||||
dfb $80
|
dfb $80
|
||||||
|
|
||||||
:L10B8 rts
|
:L10B8 cop $03
|
||||||
|
str 'COP!'
|
||||||
|
wdm $04
|
||||||
|
str 'WDM!'
|
||||||
|
rts
|
||||||
|
|
||||||
ds 327
|
ds 313
|
||||||
|
|
||||||
org $1800
|
org $1800
|
||||||
L1800 jsr PrintInlineNullString
|
L1800 jsr PrintInlineNullString
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
; check basics
|
; check basics
|
||||||
jsr PrintInline8String
|
jsr PrintInline8String
|
||||||
asc '01234567'
|
asc '01234567' ;hard-coded to 8 bytes long
|
||||||
jsr PrintInlineRev8String
|
jsr PrintInlineRev8String
|
||||||
asc '76543210'
|
asc '76543210'
|
||||||
jsr PrintInlineNullString
|
jsr PrintInlineNullString
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ PrintInlineDciString equ $013000 ;EDIT: add to project symbols
|
|||||||
|
|
||||||
; check basics
|
; check basics
|
||||||
jsr PrintInline8String
|
jsr PrintInline8String
|
||||||
asc '01234567'
|
asc '01234567' ;hard-coded to 8 bytes long
|
||||||
jsr PrintInlineRev8String
|
jsr PrintInlineRev8String
|
||||||
asc '76543210'
|
asc '76543210'
|
||||||
jsr PrintInlineNullString
|
jsr PrintInlineNullString
|
||||||
@@ -81,6 +81,12 @@ Next
|
|||||||
brk $80
|
brk $80
|
||||||
:BrkNext
|
:BrkNext
|
||||||
|
|
||||||
|
; test COP and WDM
|
||||||
|
cop $03
|
||||||
|
str 'COP!'
|
||||||
|
wdm $04
|
||||||
|
str 'WDM!'
|
||||||
|
|
||||||
rts
|
rts
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user