Mesen icon indicating copy to clipboard operation
Mesen copied to clipboard

Watches don't work when using an exported CA65 label

Open cacciatc opened this issue 4 years ago • 5 comments

Mesen version 0.9.9

It seems that if I use a label that has been exported (not sure if it also have been imported elsewhere), then I cannot create a watch using the label. For example,

ex

Above you can see that the following label which is not exported can be used no problem. However, the __camera_y label which has been exported cannot be used.

cacciatc avatar Feb 21 '20 19:02 cacciatc

My best guess would be that the .dbg file CA65 produces might not list that particular symbol, or might not give it an address Mesen can make sense of.

If you check the label list, the __camera_y label most likely isn't in it? Hard to say why that might be the case without having the .dbg file you're using, though.

SourMesen avatar Feb 22 '20 02:02 SourMesen

Here is the following and __camera_y with vals in the dbg file:

sym	id=2873,name="following",addrsize=absolute,size=1,scope=121,def=4999,ref=5033+4863+4978+4879,val=0x3A2,seg=6,type=lab
sym	id=2877,name="__camera_y",addrsize=absolute,size=2,scope=121,def=5042,ref=4911+4708+4928+4936+4968+4927+5043+4712+4809+4899+4955+4853+4784+4961+4981+4894+4768+4920,val=0x39B,seg=6,type=lab

Actually, __camera_y appears numerous times (and the other occurrences do not have a val field) maybe InteropEmu.DebugEvaluateExpression is finding one of the other occurrences that don't have a value?

Yep, it looks like InteropEmu.DebugEvaluateExpression may always match against the first occurrence of a name. I just ran some tests:

  1. Inserted another dbg entry for following before the original without a val and I get an invalid expression in Mesen.
  2. Inserted another dbg entry for following after the original without a val and everything works fine.
  3. Inserted another dbg entry for following before the original with a val and everything works fine.

cacciatc avatar Feb 22 '20 04:02 cacciatc

Ah, I think I get what's happening then.

If you look at the label list, you probably have a __camera_y_# label where # is some number? There is some logic to append a number to duplicate labels (since mesen's labels don't have a scope like ca65's do), and I think the labels without a val field might be taking up the __camera_y (without a number) label name even though a (mesen) label is not created for it.

If so, I can probably fix it so only labels that actually get created are counted, which should allow the "correct" __camera_y label to keep its original name.

SourMesen avatar Feb 22 '20 04:02 SourMesen

If you look at the label list, you probably have a _camera_y# label where # is some number?

I exported the label list and did a search for __camera_y, but it doesn't appear anywhere in the file.

cacciatc avatar Feb 22 '20 05:02 cacciatc

Partial Solution

Did some investigation into this issue today and have a partial solution. A patch can be found later on this post (if helpful). The gist is I updated the regex that matches sym entries inside the dbg file so that it only matches against sym entries that are of type=lab. If a sym entry is of that type, then there is guaranteed to be a val attribute that contains the address. Before this patch, all sym entries were loaded even if they didn't contain an address (sym entries of type=imp do not have an address, but rather denote an import).

So doing the above does indeed allow me to create watches for labels that have been imported: tmp1

As a bonus emu.getLabelAddress() also works for __camera_y with Lua scripting (it previously didn't).

Changed Behavior

So that's all well and dandy, but this appears to change some other behavior, but first to get there we have to have a quick look at my assembler source:

So in camera.s file I define and export a label:

; camera.s

.export __camera_y
; y position in world origin top
__camera_y: .res 2

In another file, my "header" file camara.h:

; camera.h

.ifndef _CAMERA_
_CAMERA_ = 1

.proc camera
	.import __camera_y
	ypos = __camera_y
.endproc
.endif

So, now in the remainder of my source when some bit of code wants to access that area of memory it uses the syntax (for example with a simple LDA:

; of course this is equivalent to LDA __camera_y
LDA camera::ypos

Now the current version of Mesen I don't think knows about camera::ypos, but it does know about ypos e.g.: nnd

However, if the patch below is applied, then this stops working: nnd

So I am guessing Mesen does in fact use the type=imp sym entries.

From 06c5ee269cf996e30b33f705b3217e870fa36f94 Mon Sep 17 00:00:00 2001
Date: Wed, 8 Jul 2020 14:44:57 -0700
Subject: [PATCH] Load only type=lab DBG syms.

---
 GUI.NET/Debugger/DbgImporter.cs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/GUI.NET/Debugger/DbgImporter.cs b/GUI.NET/Debugger/DbgImporter.cs
index 52c7248..0271bbe 100644
--- a/GUI.NET/Debugger/DbgImporter.cs
+++ b/GUI.NET/Debugger/DbgImporter.cs
@@ -44,7 +44,7 @@ namespace Mesen.GUI.Debugger
 		private static Regex _fileRegex = new Regex("^file\tid=([0-9]+),.*name=\"([^\"]+)\"", RegexOptions.Compiled);
 		private static Regex _spanRegex = new Regex("^span\tid=([0-9]+),.*seg=([0-9]+),.*start=([0-9]+),.*size=([0-9]+)(,.*type=([0-9]+)){0,1}", RegexOptions.Compiled);
 		private static Regex _scopeRegex = new Regex("^scope\tid=([0-9]+),.*name=\"([0-9a-zA-Z@_-]+)\"(,.*sym=([0-9+]+)){0,1}", RegexOptions.Compiled);
-		private static Regex _symbolRegex = new Regex("^sym\tid=([0-9]+),.*name=\"([0-9a-zA-Z@_-]+)\"(,.*size=([0-9]+)){0,1}(,.*def=([0-9+]+)){0,1}(,.*ref=([0-9+]+)){0,1}(,.*val=0x([0-9a-fA-F]+)){0,1}(,.*seg=([0-9]+)){0,1}(,.*exp=([0-9]+)){0,1}", RegexOptions.Compiled);
+		private static Regex _symbolRegex = new Regex("^sym\tid=([0-9]+),.*name=\"([0-9a-zA-Z@_-]+)\"(,.*size=([0-9]+)){0,1}(,.*def=([0-9+]+)){0,1}(,.*ref=([0-9+]+)){0,1}(,.*val=0x([0-9a-fA-F]+)){0,1}(,.*seg=([0-9]+)){0,1}(,.*exp=([0-9]+)){0,1}(,.*type=lab){1}", RegexOptions.Compiled);
 		private static Regex _cSymbolRegex = new Regex("^csym\tid=([0-9]+),.*name=\"([0-9a-zA-Z@_-]+)\"(,.*sym=([0-9+]+)){0,1}", RegexOptions.Compiled);
 
 		private static Regex _asmFirstLineRegex = new Regex(";(.*)", RegexOptions.Compiled);
@@ -447,7 +447,7 @@ namespace Mesen.GUI.Debugger
 				_symbols.Add(symbol.ID, symbol);
 				return true;
 			} else if(row.StartsWith("sym")) {
-				System.Diagnostics.Debug.Fail("Regex doesn't match sym");
+				//System.Diagnostics.Debug.Fail("Regex doesn't match sym");
 			}
 
 			return false;
-- 
2.10.1.windows.1

cacciatc avatar Jul 08 '20 22:07 cacciatc