Page 1 of 1

No EQU Variable Substitution Data In List file / Label file. Advice? (ASM6F)

Posted: Wed Jul 01, 2020 2:42 am
by Controllerhead
Hey guys, i'm running into a slightly annoying issue, and i wonder if anyone here has a good solution for it.

I am using EQU string substitutions as static constant variables, which is great because they are substituted in at compile assemble time, take up no extra ROM space and load in immediate mode. The issue is, neither the List file nor the Mesen Label .mlb file generate any notation about this.

Code: Select all

; Constant Variables
X_MAP_SIZE	EQU #$0F
Y_MAP_SIZE 	EQU #$0F
Which looks like this in the source code:

Code: Select all

BPL nameTableSwitchR	;	Check map size bounds
LDA X_MAP_SIZE
STA xMap
And looks like so in the List file:

Code: Select all

083C9 10 04	BPL nameTableSwitchR	;	Check map size bounds
083CB A9 0F	LDA #$0F
083CD 85 A0	STA xMap
As you can see, it simply puts #$0F in there with no mention of X_MAP_SIZE anywhere. The .mlb label file is the same. The EQU string substitution works as advertised i guess, heh... I also tried putting a comment after the EQU, but ASM6F didn't substitute that in. I can't assign a label to it, as far as i know, as it doesn't technically "exist" and is just an immediate #$0F in the ROM wherever it lands after being assembled... Can i do that somehow? Anyway, i wish there was a way to simply read what the string substitution "variable" was when stepping through the debugger. I mean i could just put a comment with the variable name after every time i use an EQU variable; but that would be very messy and all but defeat the point of using EQU in the first place...

Anyway, Is there a better / different way to substitute in static variables or a different compiler i could try that handles this better? I really like ASM6F and this is a really nitpicky thing, but i was wondering if anyone has dealt with this before and has a good solution. Thanks!

Re: No EQU Variable Substitution Data In List file / Label file. Advice? (ASM6F)

Posted: Wed Jul 01, 2020 6:35 am
by tokumaru
I'm of the opinion that including the immediate sign ("#") in constants is a poor practice, because it makes the code that uses them less readable. When you look at LDA X_MAP_SIZE, it looks like absolute or zero page addressing, but it's actually immediate addressing with a hidden "#". It's misleading, I really don't like it.

I don't know if ASM6f will export all symbols or just labels, but I think that instead of using EQU, it makes more sense to do this:

Code: Select all

X_MAP_SIZE = $0F

Code: Select all

LDA #X_MAP_SIZE

Re: No EQU Variable Substitution Data In List file / Label file. Advice? (ASM6F)

Posted: Wed Jul 01, 2020 8:29 am
by Controllerhead
tokumaru wrote: Wed Jul 01, 2020 6:35 am I'm of the opinion that including the immediate sign ("#") in constants is a poor practice
I suppose you're right, it might be a bit confusing to read by not including the immediate pound sign for an immediate operation. In my defense, ALL_CAPS are used to represent static variables in many languages, and i am using camelCase for memory vaues, so there is some distinction there, but ...i think you're right. Thanks.

Anyway, i tried your advice it still doesn't solve my original problem. It is still displaying #$0F....
Image
It would be nice to find a way to have X_MAP_SIZE appear in that spot, or at the very least, as a comment next to it. Maybe ill go through the ASM6F .C source file and try to cook something up.

EDIT: Ok, X_MAP_SIZE now appears in the .lst List file with your advice, which it should i guess, but still not in the Mesen Label .mlb; so i am definitly going to play with that .mlb generating ASM6F source code and see what i can do. I'll post it here if i can get it to work.

Re: No EQU Variable Substitution Data In List file / Label file. Advice? (ASM6F)

Posted: Wed Jul 01, 2020 10:02 am
by tokumaru
The thing is, this value doesn't represent a memory address, so it will never show up in a disassembly. Memory addresses are unique, so when you're acessing a specific memory address, the disassembler can easily tell that this address corresponds to one of your labels. But when you're loading an immediate value, there's nothing unique about the number $0F, so it can't simply go around replacing all instances of an immediate $0F by X_MAP_SIZE, you'd probably get a lot of conflicts and false positives.

I know that Mesen is able to trace execution using the original source files, meaning you'll see exactly what you typed, comments and all, but I'm not sure if this is possible with programs assembled in ASM6f. It may be exclusive to ca65 programs, since that assembler outputs very comprehensive debug files.

Re: No EQU Variable Substitution Data In List file / Label file. Advice? (ASM6F)

Posted: Wed Jul 01, 2020 10:43 am
by Sour
Mesen doesn't support this - it can only add labels to memory addresses, but cannot replace constants with labels. e.g it will always display AND #$0F in your case. Supporting this properly would require having a separate type of labels for constants, which would also need to have a concept of scope, which quickly turns into a pretty large undertaking.

Like tokumaru said, Mesen has the ability to debug/display the original source files directly (see: http://mesen.ca/docs/debugging/debugger ... ource-view), but this is only supported with ca65 because it's the only (popular) assembler that outputs debug symbols that contain enough information to allow this.

Re: No EQU Variable Substitution Data In List file / Label file. Advice? (ASM6F)

Posted: Wed Jul 01, 2020 5:51 pm
by Controllerhead
...Ok, so, there really isn't an elegant solution for switching in immediate values and having them display in the Mesen debugger with ASM6F. Oh well. Figured i'd ask. Thanks anyway!
Sour wrote: Wed Jul 01, 2020 10:43 am Mesen has the ability to debug/display the original source files directly ... this is only supported with ca65 because it's the only (popular) assembler that outputs debug symbols that contain enough information to allow this.
A few months ago, CA65 seemed a bit overwhelming and ASM6 was something i could wrap my head around after switching over from NESASM3 after Nerdy Nights (no zero page instructions by default? really?! typing a bunch of Z's everywhere me switch realll fast); but im getting to be a big boy now with a much bigger project, and more comfortable with 6502 ASM in general, so perhaps it's time to switch over to CA65, or at least seriously consider it.

Re: No EQU Variable Substitution Data In List file / Label file. Advice? (ASM6F)

Posted: Wed Jul 01, 2020 7:54 pm
by aa-dav
Controllerhead wrote: Wed Jul 01, 2020 5:51 pm ...
I see nothing special in CA65 syntax, but the main difficulty with it is cfg-files.
It insist on avoiding .org directive and use segment's layout configuration file.
In some cases it looks like serious limitation (fixed address tables), but there are several tricks to do it: manual segment definition or using .align directive.
As a result CA65 allows to intermix .asm modules with .c modules in linkage stage without problems. And this is main idea behind it: linkability. By default segments are movable and linkable entities and if you want fixed addresses - define them in cfg file to allow linker work correctly.
.org directive destroys etherything in this approach and should be avoided.
Example of bank-switching layout:

Code: Select all

MEMORY 
{
	HEADER:		start = $0000,	size = $0010, type = ro, file = %O, fill=yes;
	ZPAGE:		start = $0000,	size = $0100, type = rw;
	RAM:		start = $0300,	size = $0500, type = rw;
	ROM_0:		start = $8000,	size = $2000, type = ro, file = %O, fill=yes, fillval = $D0;
	ROM_1:		start = $8000,	size = $2000, type = ro, file = %O, fill=yes, fillval = $D1;
	ROM_2:		start = $8000,	size = $2000, type = ro, file = %O, fill=yes, fillval = $D2;
	ROM_3:		start = $8000,	size = $2000, type = ro, file = %O, fill=yes, fillval = $D3;
	ROM_4:		start = $A000,	size = $2000, type = ro, file = %O, fill=yes, fillval = $D4;
	ROM_5:		start = $A000,	size = $2000, type = ro, file = %O, fill=yes, fillval = $D5;
	ROM_H:		start = $C000,	size = $4000, type = ro, file = %O, fill=yes, fillval = $CC;
}

SEGMENTS 
{
	HEADER:		load = HEADER,	type = ro;
	ZPAGE:		load = ZPAGE,	type = zp;
	RAM:		load = RAM,	type = bss,	define = yes;
	ROM_0:		load = ROM_0,	type = ro,	align = $0100;
	ROM_1:		load = ROM_1,	type = ro,	align = $0100;
	ROM_2:		load = ROM_2,	type = ro,	align = $0100;
	ROM_3:		load = ROM_3,	type = ro,	align = $0100;
	ROM_4:		load = ROM_4,	type = ro,	align = $0100;
	ROM_5:		load = ROM_5,	type = ro,	align = $0100;
	ROM_H:		load = ROM_H,	type = ro,	align = $0100;
	VECTORS:	load = ROM_H,	type = ro,	start = $FFFA;
}

FILES 
{
	%O:		format = bin;
}
It instruct linker to produce binary file filling it with memory fragments defined in MEMORY section (including NES header) in order of definition where file=%O property is defined. And SEGMENTS section defines names for .segment directive binding them to memory fragments. Later another tool will add CHR data to that file and .NES image will be done.
This configuration is for MMC3 64KbROM (+64Kb CHR, but it's outside of here). 8-Kb sized banked segments ROM_0-ROM_3 are binded to low page, ROM_4-ROM-5 (banked too) are binded to high page and 16Kb-sized (unbanked) are binded to end of ROM address space.
And so on.