fadden / 6502bench Goto Github PK
View Code? Open in Web Editor NEWA workbench for developing 6502 code
Home Page: https://6502bench.com
License: Apache License 2.0
A workbench for developing 6502 code
Home Page: https://6502bench.com
License: Apache License 2.0
A bug introduced in v1.3 causes a crash if you open the Actions menu when no lines are selected in the code list.
Contents of CrashLog.txt look like:
System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Trace:
at System.ThrowHelper.ThrowArgumentOutOfRangeException(ExceptionArgument argument, ExceptionResource resource)
at SourceGen.MainController.CanCreateLocalVariableTable()
at SourceGen.WpfGui.MainWindow.CanCreateLocalVariableTable(Object sender, CanExecuteRoutedEventArgs e)
at System.Windows.Input.CommandBinding.OnCanExecute(Object sender, CanExecuteRoutedEventArgs e)
[...]
Hi Andy,
I'm using 6502bench to disassemble a rom for an educational 6502/816 sbc. Maybe I'm not seeing it but how does one label vectors like for example RESET, IRQBRK or NMI?
Thanks!
Andy
You probably don't know how to debug such so I went on and debugged it.
(f70.1ac8): Stack overflow - code c00000fd (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
eax=19c636ac ebx=0000004e ecx=00babfcc edx=00090040 esi=014db660 edi=80000000
eip=74cde5fb esp=00a02f98 ebp=00a03054 iopl=0 nv up ei pl nz na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00210206
USER32!UserCallWinProcCheckWow+0x2b:
74cde5fb 53 push ebx
So the stack is full and execution cannot continue.
Dumping the call stack shows as attached, which indicates your code is wrong somewhere.
Please review your code and fix it.
Type Name Value
Value will always be 4/6 hex digits max, while Name will change in lenght a lot. So having it
Type Value Name
means you will always be able to keep the value visible while the name can trail off
This:
.setcpu "65816"
.org $80
dp1: bit dp1
bit dp2
dp2: rts
causes:
SymTest.S(5): Warning: Didn't use zeropage addressing for `dp2'
So bit dp2
becomes bit $0085
instead of bit $85
. The problem is that ca65 is a single-pass assembler, so direct-page symbols defined after they're used have to be treated as absolute addresses.
This can be worked around by adding the "z:" width disambiguator in appropriate places.
We don't currently emit direct-page disambiguators because they're generally not necessary -- assemblers will emit the shortest instruction possible based on the value. The problem is actually pretty hard to hit, but if you've got embedded direct page code (like CHRGET) that's referenced before it's .ORGed, you'll hit it. So we have to deal with it.
I don't want to spam "z:" everywhere, but I think I can peek at the symbol definition and see if it's a label associated with a later file offset.
Common practice to begin an abject file with a series of JMP instructions as a sort of API. Recognizing this construct as assumed strong code references would be pretty low risk and greatly reduce hassle of identifying code entry points.
I see a couple places where ReferenceEquals(reference, null) type of statement is made.
This can be simplified to a is null which would be faster since there's no function/method call to make.
This is a pretty low-priority request, but I tend to set up all of my dev tools with dark UI themes because it's easier on my eyes over long periods. A dark UI option (or even full user theming) would be really nice.
From Event Viewer Application log:
Faulting application name: SourceGen.exe, version: 1.0.0.0, time stamp: 0x5bae6108
Faulting module name: comctl32.dll, version: 6.10.17134.285, time stamp: 0xa16245d4
Exception code: 0xc00000fd
Fault offset: 0x00053fd7
Faulting process id: 0xcac4
Faulting application start time: 0x01d45757732bb412
Faulting application path: C:\Users\charl\Downloads\6502bench100a1_debug\SourceGen.exe
Faulting module path: C:\WINDOWS\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.17134.285_none_42efceba44e1907b\comctl32.dll
Report Id: db5c6643-df38-481d-988f-cfe8d548530f
Faulting package full name:
Faulting package-relative application ID:
Not sure if they don't yet exist, or if I just don't know how to use the tool... but I'm not sure how to get common C64 platform symbols to be recognized in the disassembly.
for example something like
does it get branched to
bXXXX
jumped
jXXXX
JSR'd
jsXXXX
JSL'd
jlXXXX
is it used as a pointer lda ($XX,y), jsr (XXXX) for example
pXXXX
only written to
fXXXX
read/write
aXXXX or maybe vXXXX
File, Edit, Tool, and Help menues open as expected with Alt-<letter>
keystroke, but Alt-A
seems to go to the bit-bucket. Also, <alt>, A
fails to open it as well...
I suggest to add hints inside the symbol files about the type of symbol
*ZP
PTR @ $10
*ABS
LPTR @ $12
*CONST8
NL @ 10
*CONST16
CR @ 13
*CODE
PRINTF @ $f000
=> lda #13 will not be disassemble as lda #CR but rather lda #<CR
When opening a .bin file (in c64 mode) the program reads two first bytes and uses them as load address. That might be ok with a .prg file, but if it's just binary data dumped from arbitrary address, let the user choose where to load it. (one more thing you could just do like ida)
I'm getting this when running SourceGen.exe
:
I also had to calm Symantec's nerves about WS.Reputatoin.1, but that's to be expected in this nanny state.
Andy,
I've noticed a few places where a class is instantiated, then following it, there's initialization code.
I'm wondering why there's no overloading with optional parameters being used for some of these.
An example is ProjectLoadIssues. Standard instantiation :
ProjectLoadIssues dlg = new ProjectLoadIssues();
dlg.CanCancel = false;
dlg.Messages = messages;
By adding the overload:
public ProjectLoadIssues(string messages, bool cancel = true, bool cont = true)
{
InitializeComponent();
Messages = messages;
CanCancel = cancel;
CanContinue = cont;
}
the instantiation can be either the original (unless you make Messages, CanCancel and CanContinue private) or the following:
ProjectLoadIssues dlg = new ProjectLoadIssues(messages, false);
or
ProjectLoadIssues dlg = new ProjectLoadIssues(messages, false, false);
Just curious..
Andy
The symbol window allows import but (I cannot find/there is no) description of the format of import file.
Also, exporting the (visible) symbols will help if multiple files might use the same symbols (like jump table, OS entry or HW addresses).
Edit: Reading the source helps to find out about the format, but export would be nice no matter.
If pseudo-ops are changed from the default Merlin/cc65 style, they are shown correctly but the generated code uses either Merlin/cc65 ops and not the changed ones.
On the C64, and I'm sure other plotforms as well, there are some vector address that you can be sure always point to code. Programs can take over certain functions (LOAD, SAVE, ERROR, IRQ) by pointing these vectors to custom routines.
Would be nice if the idsassembler could automatically recognize addresses directly stored in these vector locations as JMP references (code hints), which would then automatically generate labels and generate <routine
and >routine
operands for the immediate values stored in the vectors...
lda #$16
sta VEC_LOAD
lda #$c1
sta VEC_LOAD+1
would then become something like:
lda #<J_C116
sta VEC_LOAD
lda #>J_C116
sta VEC_LOAD+1
Suggested syntax in sym65 file:
vecName ^ address
It's really hard to know what's being undone if it's happening off-screen...
I personally really, really appreciate editors that make sure you are viewing the undo location before performing it, otherwise it's hard to see what's been undone (you just see the after, not the before...) This would follow an algorithm something like:
auto lastEdit = undoStack.pop();
if (lastEdit.isVisible())
lastEdit.undo();
else
{
lastEdit.positionTo();
undoStack.push(lastEdit);
}
Doesn't hurt to ask, right? ;-)
If you have something like:
$1000: mystring .str "hello, world!"
....
$2000: jmp $1005
This should turn into "JMP mystring+5", but it actually turns into "JMP L1005", where L1005 is an auto-label stuck in the middle of the string. This will not assemble.
If the JMP is known at the time the string is created, the data operand editor will split the string in two to keep the label visible. But if you define the string, then uncover the JMP by adding a code entry hint, the code analyzer does the wrong thing (mostly because it runs before the data formatting is applied).
Doing this with a numeric reference, e.g.:
$2003: .dd2 $1005 ;format as 16-bit little-endian / Address
works correctly, because that's resolved in the data analysis pass rather than the code analysis pass.
This can be resolved in a couple of ways:
SetDataTarget()
, which correctly handles things like "LDA $1005".)Update: this is a serious problem, because the code analyzer is outputting code anattribs for regions that are partly covered by the formatted data. If you do this just right, you can end up walking through the file by anattrib and running into the middle of an instruction, which causes the display line generator to crash.
So we can't resolve this just by fixing a hidden label reference. We either need to avoid running the code analyzer on sections that have been formatted as data, or we need to discard data operand formats that overlap with code. The code analyzer is the first thing that runs, and we don't re-run it if we don't have to, so we really don't want the analyzer to depend on data operand formatting. We can strip out data operand formats that overlap code in ApplyFormatDescriptors().
Since the act of hinting as code is essentially a "veto" of that address being interpreted as data, it would be nice if the automatic grouping of such non-data was also considered to be a mistake...
Seems like this would be correct >99% of the time, and if not then a subsequent code hint on the operand could be explicitly given.
Reported by James Davis in c.s.a2
Fiddling with the Win10 system themes (e.g. Light vs. Dark) doesn't do a whole lot to the app. However, enabling a "high contrast" theme causes major changes to the appearance.
This creates one rather prominent difficulty: the highlight colors used in the custom ListView style aren't selecting their colors from whatever source the system is using. So most of the list is changed, but notes and long comments are still using the baked-in style.
I'm not really sure how to make the list look right. The big theme blobs I extracted from Win10 have hard-coded colors that don't match any of the values in SystemColors, so it's not a simple matter of making things use a system color dynamic resource -- switching to SystemColor will make them look funny in Win10.
One approach that I dislike but should work is to fully style the ListView, overriding the system values. This would override High Contrast or other system themes entirely, which seems like a big negative.
Some relevant links:
cc65, 64tass, and SourceGen have very similar mnemonics for the undocumented 6502 opcodes, but all three are slightly different. I'd like to pick one set. This doesn't matter too much -- SourceGen will remap the mnemonics to whatever the target assembler wants -- but it does affect what you see in the code list on screen.
Besides, after 40 years, we really ought to settle on something.
(The Apple II community doesn't do much with these, because the //c, enhanced //e, and IIgs use the 65C02 or 65816, so any code that uses the instructions would be limited to older computers. Consequently I don't really have an opinion. Well, I prefer HLT to JAM, but I'll get over it.)
My current inclination is to use the set defined by 64tass, since their documentation seems pretty thorough. If there's a "standard" set that some notable group of people have agreed on, a pointer to it would be helpful.
There are 3 cases
LabelA .byte LO
LabelB .byte HI,LO,HI,LO,HI,LO
to which you want to be able to get
LabelB = * +1
LabelA .word HILO,HILO,HILO
LabelA .byte lo,lo,lo,lo,lo,lo,lo,lo
LabelB .byte hi,hi,hi,hi,hi,hi,hi,hi
Which then becomes
LabelA .byte <lohi,<lohi,<lohi,<lohi,<lohi,<lohi,<lohi,<lohi
LabelB .byte >lohi,>lohi,>lohi,>lohi,>lohi,>lohi,>lohi,>lohi
And also the other case
LabelA .byte hi,hi,hi,hi,hi,hi,hi,hi
LabelB .byte lo,lo,lo,lo,lo,lo,lo,lo
Which then becomes
LabelA .byte >lohi,>lohi,>lohi,>lohi,>lohi,>lohi,>lohi,>lohi
LabelB .byte <lohi,<lohi,<lohi,<lohi,<lohi,<lohi,<lohi,<lohi
Where the hilo are labels
these also need a STACK modifier so the label becomes the WORD address +1 and then the bytes are -1 of the address, ready for a RTS hack
A line of code that references itself, such as this bit from the ZIPPY example:
BR_2751 lda BR_2751,y
will cause SourceGen to go into an infinite recursion. When the selection changes the code that highlights a reference symbol runs, but (for various obscure reasons) that code causes the selection to change. Easy enough to fix.
Introduced in v1.2.
If I have for example: JMP $FCE2, it would be useful to jump to that label when double clicking the operand. There could be a keyboard command too.
The question is: which one? Nearly all of my experience is in the Apple II world, so I don't have a sense for what's standard on other platforms.
The cc65 assembler can generate code for just about anything, but is light on target-specific constructs.
Merlin 32 is aimed at the Apple II, and has built-in support for things like high ASCII strings and OMF generation.
http://6502.org/tools/asm/ lists 23 assemblers and doesn't mention some of those that I'm familiar with (e.g. 64tass and Merlin 32), so there's a lot out there. The question is, which ones are actively used? Is there a "standard" cross-assembler for C64, Atari 2600, etc.?
In the current application, you can format a value as a 16-bit word by:
That's a lot of steps. This is ameliorated by the ability to select a large number of bytes and apply the format to multiple pairs all at once, but it would be nice to have a keyboard shortcut for this. We need to decide how to activate it, and whether it's a "set", "toggle", or "rotate" operation.
Activation
We'd like this to work in a way that allows 24-bit words (and maybe 32-bit words) as well. There are a couple of ways to do this:
Option (1) is the easiest, but perhaps the least convenient, since if the 2nd or later bytes are part of something larger (like an auto-detected string), you have to break it apart before you can select it.
Option (2) requires looking ahead to see if the next byte or three can be word-ified. We can pull bytes out of auto-generated strings, but if we steal the first byte from a user-specified string we effectively kill the string. The usual data-edit rules apply, e.g. we're not allowed to straddle a user-specified label or multi-line comment. There is some risk of creating a UI that appears to behave inconsistently, because sometimes the word op just won't do anything.
Operation
If you word-ify two unformatted bytes, things are pretty simple. If they already have a format, the existing format will be cleared, potentially affecting multiple bytes if it was a string, dense hex, or multi-byte numeric.
If the two bytes were already formatted as a 16/24/32-bit little-endian hex value, we have some options:
Other Notes
I'm being a little cautious here because this is the sort of thing that quickly becomes part of the workflow, so changing the way it works later is very disruptive (and leads to a proliferation of "Ctrl+W does XYZ" options in the settings). Getting it right the first time would be nice.
Reported by James Davis in c.s.a2.
If the main code list is wider than the window, and you scroll it horizontally, the column reported for double clicks fails to take the scrolling into account.
Bug was introduced in v1.2.
; = add comment
L = add label
P = add param label
D = data
W = word
C = code
Something = Line comment
Given say
lda #$12
sta $0315
lda #$06
sta $0314
This should be
lda #>$1206
sta $0315
lda #<$1206
sta $0314
where $1206 is converted into a label.
In ScriptManager.cs, DomainManager is a class that's also declared as a property.
This is used in member PrepareScripts. While it does work, it's not good practice to use a class name as a property (or variable) as it's rather confusing to anyone looking at the code. Especially if something other than VS is used to look at the code. VS doesn't hilight it when it's not a class name, but it stuck out like a sore thumb here.
(Noted in a crash log from James Davis.)
HTML generation can crash when certain fields are included in the output.
(discovered by frank_o_rama)
Description is in comp.sys.apple2.
Need to:
Support for 65SC02 (a 65C02 without the bit-branch instructions) would be great.
This would help to add Atari Lynx support.
Anyway, great work!
(discovered by frank_o_rama)
A 64K memory dump compiles successfully with 64tass, fails in Merlin 32 due to #37, and blows up in cc65 due to this:
C:\Src\cc65-2.17\bin\cl65.exe --target none "MemDump_cc65.S"
ExitCode=1 -
----- stderr -----
MemDump_cc65.S(169): Warning: Didn't use zeropage addressing for `@L00B7'
ld65: Warning: C:\Src\cc65-2.17\cfg/none.cfg(11): Segment `CODE' overflows memory area `MAIN' by 38914 bytes
ld65: Error: Cannot generate most of the files due to memory area overflow
Is there a way to set data in a block of bytes type format?
I have some font data (or just binary data) and I want to layout it out in chars, eg, 8 bytes on each line like this to save space in the source code and let it be commented nicely.
eg:
.byte $00,$11,$22,$33,$44,$55,$66,$77 ;char1
.byte $00,$11,$22,$33,$44,$55,$66,$77 ;char2
.byte $00,$11,$22,$33,$44,$55,$66,$77
I can reproduce this with SourceGen v1.2 and v1.3, in Windows 10.0.18362 and Windows 7.1. Steps:
The grid splitter will lurch a pixel or two and then freeze. Clicking on the horizontal splitter in the side windows seems to un-lurch it. (Note these still move freely.)
If you close the project, or just reopen it from File > Recent Projects, the side panels un-freeze.
I have listeners on the splitters to tell me when they move, but nothing sets them after the app starts. The launch panel (the thing you see when you first start the app) and the code list panel are both just grids. It works correctly until the ListView gets focus for the first time.
I tried removing the custom Style / ItemContainerStyle from the ListView; no change.
WPF bug?
Update: posted a demo video on youtube and a question on stackoverflow.
Another item that's useful. In DisplayList.cs, there are two members.
public Line(int offset, int span, Type type)
{
FileOffset = offset;
OffsetSpan = span;
LineType = type;
SubLineIndex = 0;
}
public Line(int offset, int span, Type type, int subLineIndex)
{
FileOffset = offset;
OffsetSpan = span;
LineType = type;
SubLineIndex = subLineIndex;
}
These two can be made into a single member as shown below.
public Line(int offset, int span, Type type, int subLineIndex = 0)
{
FileOffset = offset;
OffsetSpan = span;
LineType = type;
SubLineIndex = subLineIndex;
}
Defaults are nice to have. I've avoided c++ except for system level stuff, so don't even know if it supports the default parameters of not.
Crash message is:
wine: Call from 0x7b42c637 to unimplemented function api-ms-win-core-winrt-roparameterizediid-l1-1-0.dll.RoGetParameterizedTypeInstanceIID, aborting
wine: Call from 0x7b42c637 to unimplemented function api-ms-win-core-winrt-roparameterizediid-l1-1-0.dll.RoGetParameterizedTypeInstanceIID, aborting
wine: Call from 0x7b42c637 to unimplemented function api-ms-win-core-winrt-roparameterizediid-l1-1-0.dll.RoGetParameterizedTypeInstanceIID, aborting
wine: Unhandled exception 0xe0434352 in thread 2b7 at address 0x7b42c637 (thread 02b7), starting debugger...
Maybe there's another dependency besides .NET?
Besides the pseudo-ops it would be good to also allow choosing custom label formats in a way like:
Local label: <prefix>label<postfix>
Global lable:<prefix>label<postfix>
Where prefix/postfix can be choosen. For example, lyxass uses "." prefix for locals and "::" postfix for globals
Don't know if Atari or Apple file formats are recognized, but for C64 it's pretty universal and simple... First 2 bytes are a little-endian word, directly followed by code hint. If it's a false assumption, it will probably generate some tell-tale signs...
Some things broke in the WPF conversion (v1.2.0). If we get enough of these we'll want to do a v1.2.1.
See also issue #47.
All filenames passed to cross-assemblers are quoted, but for some reason cl65.exe doesn't work correctly. Merlin 32 and 64tass quote filenames the same way and work fine.
C:\Src\cc65-2.17\bin\cl65.exe --target none "Name WithSpaces.S"
ExitCode=1 -
----- stderr -----
ca65: Don't know what to do with `WithSpaces.S'
I tested cl65 on Linux and had no problems, but running the command manually from the git shell had the same issue.
Issue filed vs. cc65: cc65/cc65#788
Having never worked with Commodore machines -- my background is pretty Apple II-centric -- I didn't know much of anything about PETSCII. Wikipedia was a bit confusing, but I got a bit of an education from the retrocomputing site. There's also a bit of history at the start of https://www.aivosto.com/articles/petscii.pdf, along with charts for VIC-20 and others.
I'm going to focus on C64/C128. There are three relevant character encodings: shifted, unshifted, and screen codes. A capital 'A' could be $41, $61, $C1, or $01 depending on the current mode.
I think a useful level of support can be provided with a few features:
charmap
, 64tass .enc "screen"
) or just output hex if its not something the assembler handles easily.However, I still don't have a good sense for what's actually useful. I need to ask around a bit.
Useful references:
I will need to find a decent set of examples to test with.
I was able to get SourceGen to start up on Linux and successfully run most of the cross-assembler regression tests after making a couple of minor tweaks to some WinForms calls. At that point things started to get weird, so it's going to take some time to figure out.
In my brief time using the program I found other issues, such as a problem with compiling extension scripts (need to figure out how to reference netstandard.dll), and it's difficult to configure cross-assemblers because SourceGen is insisting that the assembler filenames end with ".exe". These should be easy to deal with, but at one point the app apparently locked the input devices, preventing mouse clicks and keyboard actions from working, and I had to kill the app process remotely. On the other hand, a lot of things just worked, giving me hope that, with a few more patches, SourceGen will be usable under Mono.
There are other issues, like the absence of the Consolas font, that will require a bit of fiddling to make things look right. (You can configure the font for the code list, but we'll need to let you pick a mono-space font for the side windows, multi-line comment editor, etc.)
I filed the first couple of crashing bugs against Mono (mono/mono#11070), but will need some time to isolate the non-rendering UI issue and devise a workaround. Hopefully with a workaround for that in place, all parts of the program will be accessible, and a full list of issues can be established.
Andy, I don't know if you noticed VS2017's messages on the error window, but in there it has helpful messages (sometimes helpful anyway).
But it does give info about code that can be simplified, then details when you hover over the item in the code.
For example, simplification of code when you're creating a new instance. As an example, in ProjectView, a SaveDialog box is created, then several items are initialized. The code now is:
SaveFileDialog fileDlg = new SaveFileDialog();
fileDlg.Filter = ProjectFile.FILENAME_FILTER + "|" + Properties.Resources.FILE_FILTER_ALL;
fileDlg.FilterIndex = 1;
fileDlg.ValidateNames = true;
fileDlg.AddExtension = true;
fileDlg.FileName = Path.GetFileName(mDataPathName) + ProjectFile.FILENAME_EXT;
can be simplified to:
SaveFileDialog fileDlg = new SaveFileDialog
{
Filter = ProjectFile.FILENAME_FILTER + "|" + Properties.Resources.FILE_FILTER_ALL,
FilterIndex = 1,
ValidateNames = true,
AddExtension = true,
FileName = Path.GetFileName(mDataPathName) + ProjectFile.FILENAME_EXT
};
There's probably times when you would prefer the first way. Some items can't be done the second way, if they weren't set up to be done that way. If you try it'll tell you it can't, and why. But the second way is cleaner, with less typing!
Andy
Support for decoding SOS system calls would be nice to have.
These are very similar to ProDOS MLI calls that you have included support for. For SOS, it uses a BRK instruction instead of a JMP instruction and the byte following the opcode is the SOS system call number. It then has a word pointing to the parameter block like Prodos.
00962B 1 00 C8 brk OPEN
00962D 1 6C 94 .word L946C ;address to param block
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.