diff --git a/CommonWPF/AnimatedGifEncoder.cs b/CommonWPF/AnimatedGifEncoder.cs
index 2ce9bd9..4618dfa 100644
--- a/CommonWPF/AnimatedGifEncoder.cs
+++ b/CommonWPF/AnimatedGifEncoder.cs
@@ -125,7 +125,7 @@ namespace CommonWPF {
// Step 2: determine the size of the largest image. This will become the logical
// size of the animated GIF.
//
- // TODO: We have an opportunity to replace all of the local color tables with a
+ // TODO(maybe): We have an opportunity to replace all of the local color tables with a
// single global color table. This is only possible if all of the local tables are
// identical and the transparency values in the GCE also match up. (Well, it's
// otherwise *possible*, but we'd need to decode, update palettes and pixels, and
diff --git a/SourceGen/DisplayList.cs b/SourceGen/DisplayList.cs
index 06eb3da..0d7e26f 100644
--- a/SourceGen/DisplayList.cs
+++ b/SourceGen/DisplayList.cs
@@ -314,7 +314,8 @@ namespace SourceGen {
for (int i = 0; i < newCount; i++) {
mList.Insert(startIndex, null);
}
- // TODO: can we null out existing entries, and just insert/remove when counts differ?
+ // TODO(someday): can we null out existing entries, and just insert/remove when
+ // counts differ?
if (oldCount != newCount) {
SelectedIndices = new DisplayListSelection(mList.Count);
@@ -323,9 +324,9 @@ namespace SourceGen {
OnPropertyChanged(CountString);
OnPropertyChanged(IndexerName);
- // TODO(performance): this causes the ListView to format the entire listing, despite
+ // TODO: this causes the ListView to format the entire listing, despite
// being virtual. So we're regenerating the entire list after something trivial,
- // like renaming a label. Need to figure this out.
+ // like renaming a label, which hampers performance. Need to figure this out.
OnCollectionReset();
}
diff --git a/SourceGen/Examples/Tutorial/Source/Tutorial5.S b/SourceGen/Examples/Tutorial/Source/Tutorial5.S
new file mode 100644
index 0000000..46939b6
--- /dev/null
+++ b/SourceGen/Examples/Tutorial/Source/Tutorial5.S
@@ -0,0 +1,80 @@
+; Copyright 2019 faddenSoft. All Rights Reserved.
+; See the LICENSE.txt file for distribution terms (Apache 2.0).
+;
+; Assembler: Merlin 32
+
+ org $1000
+
+ENTRY
+ lda bitmapX
+ lda bitmapO
+ lda bitmapBoard
+ rts
+
+; Each pixel is represented by a single bit. Leftmost pixel is in high bit.
+
+bitmapX ;1x8
+ dfb %10000010 ; X.....X.
+ dfb %01000100 ; .X...X..
+ dfb %00101000 ; ..X.X...
+ dfb %00010000 ; ...X....
+ dfb %00101000 ; ..X.X...
+ dfb %01000100 ; .X...X..
+ dfb %10000010 ; X.....X.
+ dfb %00000000 ; ........
+
+bitmapO ;1x8
+ dfb %00111000 ; ..OOO...
+ dfb %01000100 ; .O...O..
+ dfb %10000010 ; O.....O.
+ dfb %10000010 ; O.....O.
+ dfb %10000010 ; O.....O.
+ dfb %01000100 ; .O...O..
+ dfb %00111000 ; ..OOO...
+ dfb %00000000 ; ........
+
+bitmapBoard ;5x40, stride=8
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex fffffffffeCCCCCC ; ######## ######## ######## ######## #######.
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 00fe00fe00CCCCCC ; ........ #######. ........ #######. ........
+ hex 0000000000CCCCCC ; ........ ........ ........ ........ ........
diff --git a/SourceGen/Examples/Tutorial/Tutorial5 b/SourceGen/Examples/Tutorial/Tutorial5
new file mode 100644
index 0000000..9fa06e0
Binary files /dev/null and b/SourceGen/Examples/Tutorial/Tutorial5 differ
diff --git a/SourceGen/Examples/Tutorial/VisTutorial5.cs b/SourceGen/Examples/Tutorial/VisTutorial5.cs
new file mode 100644
index 0000000..745be14
--- /dev/null
+++ b/SourceGen/Examples/Tutorial/VisTutorial5.cs
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2019 faddenSoft
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+using System;
+using System.Collections.ObjectModel;
+
+using PluginCommon;
+
+namespace Tutorial {
+ public class VisTutorial5 : MarshalByRefObject, IPlugin, IPlugin_Visualizer {
+ // IPlugin
+ public string Identifier {
+ get { return "Tutorial Visualizer"; }
+ }
+ private IApplication mAppRef;
+ private byte[] mFileData;
+
+ // Visualization identifiers; DO NOT change or projects that use them will break.
+ private const string VIS_GEN_BITMAP = "tutorial-bitmap";
+
+ private const string P_OFFSET = "offset";
+ private const string P_BYTE_WIDTH = "byteWidth";
+ private const string P_HEIGHT = "height";
+ private const string P_ROW_STRIDE = "rowStride";
+
+ private const int MAX_DIM = 4096;
+
+ // Visualization descriptors.
+ private VisDescr[] mDescriptors = new VisDescr[] {
+ new VisDescr(VIS_GEN_BITMAP, "Tutorial Bitmap", VisDescr.VisType.Bitmap,
+ new VisParamDescr[] {
+ new VisParamDescr("File offset (hex)",
+ P_OFFSET, typeof(int), 0, 0x00ffffff, VisParamDescr.SpecialMode.Offset, 0),
+ new VisParamDescr("Width (in bytes)",
+ P_BYTE_WIDTH, typeof(int), 1, 64, 0, 1),
+ new VisParamDescr("Height",
+ P_HEIGHT, typeof(int), 1, 512, 0, 1),
+ new VisParamDescr("Row stride (bytes)",
+ P_ROW_STRIDE, typeof(int), 0, 256, 0, 0),
+ })
+ };
+
+
+ // IPlugin
+ public void Prepare(IApplication appRef, byte[] fileData, AddressTranslate addrTrans) {
+ mAppRef = appRef;
+ mFileData = fileData;
+ }
+
+ // IPlugin
+ public void Unprepare() {
+ mAppRef = null;
+ mFileData = null;
+ }
+
+ // IPlugin_Visualizer
+ public VisDescr[] GetVisGenDescrs() {
+ if (mFileData == null) {
+ return null;
+ }
+ return mDescriptors;
+ }
+
+ // IPlugin_Visualizer
+ public IVisualization2d Generate2d(VisDescr descr,
+ ReadOnlyDictionary
Select the line with address $2003 ("CMP #$04"), then Actions > Edit Operand. This allows you to pick how you want the -operand to look. It's currently set to Default, which for an 8-bit +operand to look. It's currently set to "Default", which for an 8-bit immediate argument means it's shown as a hexadecimal value. Click -Binary, then OK. It now appears as a binary value.
+"Binary", then "OK". It now appears as a binary value.The operand in the LDA instruction at line $2000 refers to an address ($3000) that isn't part of the file. We want to create an equate directive to @@ -375,6 +376,8 @@ it should always match exactly.)
At this point you know enough to work with a SourceGen project. Continue on to the next tutorial to learn more.
+We don't want to save this project, so select File > Close. When SourceGen asks for confirmation, click Discard & Continue.
+Double-click the JSR operand ("L1026"), click "Create Label", and enter "PrintInlineL1String". Remember that labels are case-sensitive; -you must enter it exactly as shown. Hit OK to accept the label, and OK +you must enter it exactly as shown. Hit "OK" to accept the label, and "OK" to close the operand editor. If all went well, address $1003 should now be an L1 string "How long?", and adress $100D should be another JSR.
@@ -692,7 +699,7 @@ and add the script "InlineNullTermString.cs". that starts with "PrintInlineNullString". So let's give it a couple of those.Double-click the operand on line $100D ("L1027"), click Create Label, -and set the label to "PrintInlineNullStringOne". Hit OK twice. That +and set the label to "PrintInlineNullStringOne". Hit "OK" twice. That formatted the first one and got us to the next JSR. Repeat the process on line $1019 ("L1028"), setting the label to "PrintInlineNullStringTwo".
@@ -706,6 +713,127 @@ strings and clean up the disassembly automatically. some programming experience. See the manual for more details. +This tutorial covers one specific feature.
+ +Many programs contain a significant amount of graphical data. This is +especially true for games, where the space used for bitmaps is often +larger than the space required for the code. When disassembling a program +it can be very helpful to be able to see the contents of the data +regions in graphical form.
+ +Start a new project with "Generic 6502", and in the SourceGen Tutorial +directory select "Tutorial5". We'll need to load an extension script from +the project directory, so immediately save the project, using the +default name ("Tutorial5.dis65").
+Normally a project will give you some sort of hint as to the data +format, e.g. the graphics might be a platform-specific sprite. For +non-standard formats you can glean dimensions from the drawing code. For +the purposes of this tutorial we're just using a simple monochrome bitmap +format, with 8 pixels per byte, and we'll know that our images are for +a Tic-Tac-Toe game. The 'X' and the 'O' are 8x8, the game board is 40x40. +The bitmaps are sprites with transparency, so pixels are either solid +or transparent.
+The first thing we need to do is load an extension script that can +decode this format. The RuntimeData directory has a few, but for this +tutorial we're using a custom one. Select Edit > Project Properties, +select the Extension Scripts tab, and click "Add Scripts from Project". +Double-click on "VisTutorial5.cs", then click "OK".
+ +The address of the three bitmaps are helpfully identified by the +load instructions at the top of the file. Select the first one at +address $100A, then Actions > Create/Edit Visualization Set. In +the window that opens, click "New Bitmap".
+We're going to ignore most of what's going on and just focus on the +list of parameters at the bottom. The file offset indicates where in +the file the bitmap starts; note this is an offset, not an address +(that way, if you change the address, your visualizations don't break). +This is followed by the bitmap's width in bytes, and the bitmap's height. +Because we have 8 pixels per byte, we're currently showing a 1x1 image. +We'll come back to row stride.
+We happen to know (by playing the game and/or reading the fictitious +drawing code) that the image is 8x8, so change the value in the height +field to 8. As soon as you do, the preview window shows a big blue 'X'. +(The 'X' is 7x7; the last row/column of pixels are transparent so adjacent +images don't blend into each other.)
+Let's try doing it wrong. Add a 0 to make the height 80. You can see +some additional bitmap data. Add another 0 to make it 800. Now you get +a big red X, and the "Height" parameter is shown in red. That's because +the maximum value for the height is 512, as shown by "[1,512]" on the +right.
+Change it back to 8, and hit "OK". Hit "OK" in the Edit Visualization +Set window as well. You should now see the blue 'X' in the code listing +above line $100A.
+ +Repeat the process at line $1012: select the line, create a visualization +set, create a new bitmap, set the height to 8, click "OK" twice.
+ +Repeat the process at line $101A, but this time the image is 40x40 +rather than 8x8. Set the width to 5, and the height to 40. This makes +a mess.
+In this case, the bitmap data is 5 bytes wide, but the data is stored +as 8 bytes per row. This is known as the "stride" or "pitch" of the row. +To tell the visualizer to skip the last 3 bytes on each row, set the +"Row stride (bytes)" field to 8. Now we have a proper Tic-Tac-Toe grid. +Note that it fills the preview window just as the 'X' and 'O' did, even +though it's 5x as large. The preview window scales everything up.
+Let's format the bitmap data. Select line $101A, then shift-click the +last line in the file ($1159). Actions > Edit Operand. Select +"densely-packed bytes", and click "OK". This is perhaps a little too +dense. Open the operand editor again, but this time select the +densely-packed bytes sub-option "...with a limit", and set the limit +to 8 bytes per line. Instead of one very dense statement spread across +a few lines, you get one line of code per row of bitmap. If you prefer +to see individual bytes, you can use Edit > Settings, select the +Display Format tab, and check "use comma-separated format for bulk data". +This can make it a bit easier to read.
+ +Some graphics represent individual frames in an animated sequence. +You can convert those as well. Double-click on the blue 'X' to open +the visualization set editor, then click "New Bitmap Animation". This +opens the Bitmap Animation Editor.
+Let's try it with our Tic-Tac-Toe board pieces. From the list on the +left, select the blue 'X' and click "Add", then click the 'O' and click +"Add". Below the list, set the frame delay to 500. Near the bottom, +click "Start / Stop. This causes the animation to play in a loop. You +can use the controls to add and remove items, change their order, and change +the animation speed. You can add the grid to the animation set, but the +preview scales the bitmaps up to full size, so it may not look the way +you expect.
+Hit "OK" to save the animation, then "OK" to update the visualization set. +The code list now shows two entries, one of which has a blue triangle +superimposed. You can have as many bitmaps an animations on a line +as you want.
+If you have a lot of bitmaps it can be helpful to give them meaningful +names, so that they're easy to identify and sort together in the list. +The "tag" field at the top of the editor windows lets you give things +names. Tags must be unique.
+ +The visualization editor is intended to be very dynamic, showing the +results of parameter changes immediately. This can be helpful if you're +not exactly sure what the size or format of a bitmap is. Just keep +tweaking values until it looks right.
+ +Visualization generators are defined by extension scripts. If you're +disassembling a program with a totally custom way of storing graphics, +you can write a totally custom visualizer and distribute it with the +project. Because the file offset is a parameter, you're not limited to +placing visualizations at the start of the graphic data -- you can put +them on any code or data line.
+ +Visualizations have no effect on assembly source code generation, +but they do appear in code exported to HTML. Bitmaps are converted to GIF +images, and animations become animated GIFs.
+ +