mirror of
https://github.com/fadden/6502bench.git
synced 2025-01-16 04:32:34 +00:00
Rearrange the tutorial files
Copied the extension script tutorial files out of the Scripts directory and into the Tutorial directory. This makes more sense, and makes it possible to expand the script sample without altering the tutorial. Reverted the Scripts sample to be an actual sample, rather than a tutorial. Renumbered the last two tutorials and added them to the ToC. This gives them actual numbers rather than treating them as add-ons to the advanced tutorial. Moved the source files for the tutorial binaries into a subdirectory to reduce clutter. This does mean we have two separate copies of the inline string sample plugins, but that's an artifact of our attempts at security.
This commit is contained in:
parent
51081c5db0
commit
4b46b78e34
@ -1,3 +1,8 @@
|
||||
; Copyright 2019 faddenSoft. All Rights Reserved.
|
||||
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||
;
|
||||
; Assembler: Merlin 32
|
||||
|
||||
org $1000
|
||||
|
||||
jsr PrintInlineL1String
|
||||
|
@ -10,7 +10,7 @@
|
||||
"Low":0,"High":0,"Hint":"Code"}],"StatusFlagOverrides":{
|
||||
},
|
||||
"Comments":{
|
||||
},
|
||||
"0":"requires exact name match","13":"requires name prefix match"},
|
||||
"LongComments":{
|
||||
},
|
||||
"Notes":{
|
73
SourceGen/Examples/Tutorial/InlineL1String.cs
Normal file
73
SourceGen/Examples/Tutorial/InlineL1String.cs
Normal file
@ -0,0 +1,73 @@
|
||||
// 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 ExtensionScriptSample {
|
||||
/// <summary>
|
||||
/// Sample class for handling a JSR followed by a string prefixed with a 1-byte length.
|
||||
/// </summary>
|
||||
public class InlineL1String: MarshalByRefObject, IPlugin, IPlugin_SymbolList,
|
||||
IPlugin_InlineJsr {
|
||||
private IApplication mAppRef;
|
||||
private byte[] mFileData;
|
||||
|
||||
// Only one call.
|
||||
private const string CALL_LABEL = "PrintInlineL1String";
|
||||
private int mInlineL1StringAddr; // jsr
|
||||
|
||||
public string Identifier {
|
||||
get {
|
||||
return "Inline L1 ASCII string handler";
|
||||
}
|
||||
}
|
||||
|
||||
public void Prepare(IApplication appRef, byte[] fileData, AddressTranslate addrTrans) {
|
||||
mAppRef = appRef;
|
||||
mFileData = fileData;
|
||||
|
||||
mAppRef.DebugLog("InlineL1String(id=" +
|
||||
AppDomain.CurrentDomain.Id + "): prepare()");
|
||||
}
|
||||
|
||||
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
||||
// reset this every time, in case they remove the symbol
|
||||
mInlineL1StringAddr = -1;
|
||||
|
||||
foreach (PlSymbol sym in plSyms) {
|
||||
if (sym.Label == CALL_LABEL) {
|
||||
mInlineL1StringAddr = sym.Value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
mAppRef.DebugLog(CALL_LABEL + " @ $" + mInlineL1StringAddr.ToString("x6"));
|
||||
}
|
||||
public bool IsLabelSignificant(string beforeLabel, string afterLabel) {
|
||||
return beforeLabel == CALL_LABEL || afterLabel == CALL_LABEL;
|
||||
}
|
||||
|
||||
public void CheckJsr(int offset, int operand, out bool noContinue) {
|
||||
noContinue = false;
|
||||
if (operand != mInlineL1StringAddr) {
|
||||
return;
|
||||
}
|
||||
if (offset + 3 >= mFileData.Length) {
|
||||
return; // length byte is off end
|
||||
}
|
||||
int len = mFileData[3]; // first byte past JSR
|
||||
if (offset + 4 + len > mFileData.Length) {
|
||||
mAppRef.DebugLog("L1 string ran off end of file at +" +
|
||||
(offset + 4).ToString("x6"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Assuming ASCII. This can be hard-coded, use auto-detection, or look
|
||||
// up a value in a project constant.
|
||||
mAppRef.SetInlineDataFormat(offset + 3, len + 1,
|
||||
DataType.StringL8, DataSubType.Ascii, null);
|
||||
}
|
||||
}
|
||||
}
|
76
SourceGen/Examples/Tutorial/InlineNullTermString.cs
Normal file
76
SourceGen/Examples/Tutorial/InlineNullTermString.cs
Normal file
@ -0,0 +1,76 @@
|
||||
// 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 ExtensionScriptSample {
|
||||
/// <summary>
|
||||
/// Sample class for handling a JSR followed by an inline null-terminated string. Any
|
||||
/// label that starts with "PrintLineNullString" is matched.
|
||||
/// </summary>
|
||||
public class InlineNullTermString : MarshalByRefObject, IPlugin, IPlugin_SymbolList,
|
||||
IPlugin_InlineJsr {
|
||||
private IApplication mAppRef;
|
||||
private byte[] mFileData;
|
||||
|
||||
private const string LABEL_PREFIX = "PrintInlineNullString";
|
||||
private Dictionary<int, PlSymbol> mNullStringAddrs = new Dictionary<int, PlSymbol>();
|
||||
|
||||
public string Identifier {
|
||||
get {
|
||||
return "Inline null-terminated ASCII string handler";
|
||||
}
|
||||
}
|
||||
|
||||
public void Prepare(IApplication appRef, byte[] fileData, AddressTranslate addrTrans) {
|
||||
mAppRef = appRef;
|
||||
mFileData = fileData;
|
||||
|
||||
mAppRef.DebugLog("InlineNullStringHandler(id=" +
|
||||
AppDomain.CurrentDomain.Id + "): prepare()");
|
||||
}
|
||||
|
||||
public void UpdateSymbolList(List<PlSymbol> plSyms) {
|
||||
mNullStringAddrs.Clear();
|
||||
|
||||
foreach (PlSymbol sym in plSyms) {
|
||||
if (sym.Label.StartsWith(LABEL_PREFIX)) {
|
||||
mNullStringAddrs.Add(sym.Value, sym);
|
||||
}
|
||||
}
|
||||
mAppRef.DebugLog(LABEL_PREFIX + " matched " + mNullStringAddrs.Count + " labels");
|
||||
}
|
||||
public bool IsLabelSignificant(string beforeLabel, string afterLabel) {
|
||||
return beforeLabel.StartsWith(LABEL_PREFIX) || afterLabel.StartsWith(LABEL_PREFIX);
|
||||
}
|
||||
|
||||
public void CheckJsr(int offset, int operand, out bool noContinue) {
|
||||
noContinue = false;
|
||||
if (!mNullStringAddrs.ContainsKey(operand)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// search 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;
|
||||
}
|
||||
|
||||
// Assuming ASCII. This can be hard-coded, use auto-detection, or look
|
||||
// up a value in a project constant.
|
||||
mAppRef.SetInlineDataFormat(offset + 3, nullOff - (offset + 3) + 1,
|
||||
DataType.StringNullTerm, DataSubType.Ascii, null);
|
||||
}
|
||||
}
|
||||
}
|
23
SourceGen/Examples/Tutorial/Source/Tutorial4.S
Normal file
23
SourceGen/Examples/Tutorial/Source/Tutorial4.S
Normal file
@ -0,0 +1,23 @@
|
||||
; Copyright 2019 faddenSoft. All Rights Reserved.
|
||||
; See the LICENSE.txt file for distribution terms (Apache 2.0).
|
||||
;
|
||||
; Assembler: Merlin 32
|
||||
|
||||
org $1000
|
||||
|
||||
jsr PrintInlineL1String
|
||||
str 'How long?'
|
||||
|
||||
jsr PrintInlineZString1
|
||||
asc 'Test one',00
|
||||
|
||||
jsr PrintInlineZString2
|
||||
asc 'Test two',00
|
||||
rts
|
||||
|
||||
PrintInlineL1String
|
||||
rts
|
||||
PrintInlineZString1
|
||||
rts
|
||||
PrintInlineZString2
|
||||
rts
|
BIN
SourceGen/Examples/Tutorial/Tutorial4
Normal file
BIN
SourceGen/Examples/Tutorial/Tutorial4
Normal file
Binary file not shown.
@ -164,6 +164,8 @@ and 65816 code. The official web site is
|
||||
<ul>
|
||||
<li><a href="tutorials.html#basic-features">Tutorial #1: Basic Features</a></li>
|
||||
<li><a href="tutorials.html#advanced-features">Tutorial #2: Advanced Features</a></li>
|
||||
<li><a href="tutorials.html#address-tables">Tutorial #3: Address Table Formatting</a></li>
|
||||
<li><a href="tutorials.html#extension-scripts">Tutorial #4: Extension Scripts</a></li>
|
||||
</ul></li>
|
||||
|
||||
</ul>
|
||||
|
@ -21,8 +21,8 @@ manual is recommended.</p>
|
||||
<ul>
|
||||
<li><a href="#basic-features">#1: Basic Features</a></li>
|
||||
<li><a href="#advanced-features">#2: Advanced Features</a></li>
|
||||
<li><a href="#address-table">#2a: Address Table Formatting</a></li>
|
||||
<li><a href="#extension-scripts">#2b: Extension Scripts</a></li>
|
||||
<li><a href="#address-tables">#3: Address Table Formatting</a></li>
|
||||
<li><a href="#extension-scripts">#4: Extension Scripts</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@ -539,7 +539,7 @@ extra symbol in the opcode field, you need to look closely at what's going
|
||||
on.</p>
|
||||
|
||||
|
||||
<h2><a name="address-table">Tutorial #2a: Address Table Formatting</a></h2>
|
||||
<h2><a name="address-tables">Tutorial #3: Address Table Formatting</a></h2>
|
||||
|
||||
<p><i>This tutorial covers one specific feature.</i></p>
|
||||
|
||||
@ -591,6 +591,11 @@ You could repeat these steps for the remaining items, but there's a faster
|
||||
way. Click on the line at address $1d97, then shift-click the line at
|
||||
address $1da9 (which should be <code>.FILL 12,$1e</code>). Select
|
||||
Actions > Format Address Table.</p>
|
||||
<p>Contrary to first impressions, this imposing dialog does not allow you
|
||||
to launch objects into orbit. There are a variety of common ways to
|
||||
structure an address table, all of which are handled here. You can
|
||||
configure the various parameters and see the effects as you make
|
||||
each change.</p>
|
||||
<p>The message at the top should indicate that there are 30 bytes
|
||||
selected. In Address Characteristics, click the "Parts are split across
|
||||
sub-tables" checkbox and the "adjusted for RTS/RTL"
|
||||
@ -614,7 +619,7 @@ code entry point hint -- but did several of them at once.</p>
|
||||
SourceGen asks for confirmation, click Discard & Continue.</p>
|
||||
|
||||
|
||||
<h2><a name="extension-scripts">Tutorial #2b: Extension Scripts</a></h2>
|
||||
<h2><a name="extension-scripts">Tutorial #4: Extension Scripts</a></h2>
|
||||
|
||||
<p><i>This tutorial covers one specific feature.</i></p>
|
||||
|
||||
@ -624,10 +629,9 @@ because code is expected.</p>
|
||||
<p>An earlier tutorial demonstrated how to manually mark bytes as
|
||||
inline data. We're going to do it a faster way. For this tutorial,
|
||||
start a new project with "Generic 6502", and in the SourceGen
|
||||
installation directory find the Examples directory, open the Scripts
|
||||
subdirectory, and select "Sample".</p>
|
||||
Tutorial directory select "Tutorial4".</p>
|
||||
<p>We'll need to load scripts from the project directory, so we have to
|
||||
save the project. File > Save, call it the default name (Sample.dis65).</p>
|
||||
save the project. File > Save, use the default name ("Tutorial4.dis65").</p>
|
||||
|
||||
<p>Take a look at the disassembly listing. The file starts with a JSR
|
||||
followed by a string that begins with a small number. This appears to be
|
||||
@ -657,9 +661,9 @@ on line $1019 ("L1028"), setting the label to "PrintInlineNullStringTwo".</p>
|
||||
|
||||
<p>The entire project is now nicely formatted. In a real project the
|
||||
"Print Inline" locations would be actual print functions, not just RTS
|
||||
instructions, and there would be multiple JSRs to a single function.
|
||||
So labeling a single print function could format dozens of inline strings
|
||||
and clean up the disassembly automatically.</p>
|
||||
instructions. There would likely be multiple JSRs to the print function,
|
||||
so labeling a single function entry point could format dozens of inline
|
||||
strings and clean up the disassembly automatically.</p>
|
||||
|
||||
<p>Extension scripts can make your life much easier, but they do require
|
||||
some programming experience. See the
|
||||
|
Loading…
x
Reference in New Issue
Block a user