.segment, CA65/CC65
Moderator: Moderators
.segment, CA65/CC65
I don't remember where I found it, but I'm looking at a .asm file that's essentially a hello world program, and it raises a number of questions for a noob like me, despite consisting mostly of comments and very little code.
1. The beginning of the file has hardly any comments.
.segment "HEADER"
.byte "NES", 26, 2, 1
; CHR ROM data
.segment "CHARS"
.segment "VECTORS"
.word 0, 0, 0, nmi, reset, irq
.segment "STARTUP"
.segment "CODE"
I've been trying to read up on this, and I think CA65 uses these segments keywords to determine where in the resulting .NES file it will put your data upon assembly/compilation (are they the same, by the way?), since e.g. CHR data has to be in a certain address range within the .NES, though if I'm wrong about this, please do correct me. Anyway, is this the full list of possible segments? If not, where can I find such a list, if one exists?
2. [ANSWERED] This particular .asm file has the following labels:
reset
@vblankwait1
@clrmem
@vblankwait2
forever
irq
nmi
What is the purpose of having an @ at the beginning of a label?
3. What is the significance or purpose of the leading 3 zeroes, here?
.segment "VECTORS"
.word 0, 0, 0, nmi, reset, irq
If I got this right, the NMI vector is at $FFFA, so whenever an NMI occurs, the program goes to the NMI label (which is located at the address stored at $FFFA) and starts running the code there. The address to this label is 2 bytes long ($FFFA). Do each of the leading zeroes also represent 2 bytes, i.e. does the vectors segment start at $FFF4? Which interrupts do the first 3 zeroes correspond to? Are they only used by mappers, and is that why they have been set to 0 in this particular program (which doesn't use mappers)?
1. The beginning of the file has hardly any comments.
.segment "HEADER"
.byte "NES", 26, 2, 1
; CHR ROM data
.segment "CHARS"
.segment "VECTORS"
.word 0, 0, 0, nmi, reset, irq
.segment "STARTUP"
.segment "CODE"
I've been trying to read up on this, and I think CA65 uses these segments keywords to determine where in the resulting .NES file it will put your data upon assembly/compilation (are they the same, by the way?), since e.g. CHR data has to be in a certain address range within the .NES, though if I'm wrong about this, please do correct me. Anyway, is this the full list of possible segments? If not, where can I find such a list, if one exists?
2. [ANSWERED] This particular .asm file has the following labels:
reset
@vblankwait1
@clrmem
@vblankwait2
forever
irq
nmi
What is the purpose of having an @ at the beginning of a label?
3. What is the significance or purpose of the leading 3 zeroes, here?
.segment "VECTORS"
.word 0, 0, 0, nmi, reset, irq
If I got this right, the NMI vector is at $FFFA, so whenever an NMI occurs, the program goes to the NMI label (which is located at the address stored at $FFFA) and starts running the code there. The address to this label is 2 bytes long ($FFFA). Do each of the leading zeroes also represent 2 bytes, i.e. does the vectors segment start at $FFF4? Which interrupts do the first 3 zeroes correspond to? Are they only used by mappers, and is that why they have been set to 0 in this particular program (which doesn't use mappers)?
Last edited by Dafydd on Sun Feb 05, 2012 7:28 am, edited 2 times in total.
The zeroes before the vectors are really puzzling me... Then again, I don't use CA65, so this might be related to some peculiarity of that assembler. I can assure you that this has nothing to do with mappers, and that only the last 6 bytes are used by the CPU as vectors. I have no idea what those zeroes are doing there.
Sorry if I can't help with the CA65-specific questions. Having to build scripts before being able to assemble my programs has really put me off (and I don't feel well using scripts other people made unless I completely understand them). The possibility of using segments is hardly worth the trouble IMO. I've been using ASM6, and I have no trouble making sure that everything ends up in the correct places in the NES file myself. From what I heard CA65 is very good though, so I hope you get your answers.
Sorry if I can't help with the CA65-specific questions. Having to build scripts before being able to assemble my programs has really put me off (and I don't feel well using scripts other people made unless I completely understand them). The possibility of using segments is hardly worth the trouble IMO. I've been using ASM6, and I have no trouble making sure that everything ends up in the correct places in the NES file myself. From what I heard CA65 is very good though, so I hope you get your answers.
I seem to remember that the VECTORS segment of the included linker script appears to point to $FFF4 or the like for some reason. I don't use the included linker script, instead choosing to start the vector segment at $FFFA for NROM or anything else with fixed $E000-$FFFF, or $FFF0 for any mapper capable of switching $E000-$FFFF (UNROM 180 or [ABGS]xROM).tokumaru wrote:The zeroes before the vectors are really puzzling me... Then again, I don't use CA65, so this might be related to some peculiarity of that assembler.
If you want me to explain every line in the linker script of my NROM or SGROM/SNROM project template or any other cc65-based project I've released, I'm willing to do so.I don't feel well using scripts other people made unless I completely understand them
Thanks for the offer. When looking at them, everything makes sense, but I imagine this is the kind of thing that can be done in various ways, and depends on the style of the programmer. For example, in your SNROM template I don't see a VECTOR segment, but you obviously got the vectors in somehow. I have to know more than what a given script is doing in order to design my own.tepples wrote:If you want me to explain every line in the linker script of my NROM or SGROM/SNROM project template or any other cc65-based project I've released, I'm willing to do so.
I guess one of the reasons I don't like linking scripts is that they are just one more thing you have to design, and consequently one more thing you might want to redesign in the future when you notice the flaws of the one you're using. Also, due to the fact that I develop on several different computers, I like to keep everything (source, documents, tools, etc.) in a single archive, so it's better that the tools are simple and small. I can't rely on make files or other things that require setting up a complex development environment.
I appreciate your offer though, and I'll be sure to ask you any questions I might have about this in case I decide to give CA65 another shot someday.
I gave my entire cc65 folder a search for fff4 and found nothing. I did find this line in ld65.exe, however:tepples wrote:I seem to remember that the VECTORS segment of the included linker script appears to point to $FFF4 or the like for some reason.
ROMV: start = $fff6, size = $c, file = %O, fill = yes;
Doesn't make much sense to me. First of all, this would mean that these 3 zeroes can't all represent two bytes each. Second, $fff6 + $c is more than $ffff. Any clues?
Anyway, still haven't found an answer for my first question.
-
Karatorian
- Posts: 76
- Joined: Sun Sep 30, 2007 9:54 pm
- Location: Corneria
- Contact:
The default platform linker scripts are built into ld65. You can see the NES script at ftp://ftp.musoftware.de/pub/uz/cc65/sna ... fg/nes.cfg
It's basically designed for use with cc65 and not really what most ca65 users would expect. Which is why most people write their own. (Which are usually much less complex than this.)
So, yes, the vectors section starts at $FFF6 and it's size is $C. No, that doesn't make any sense, but that's how it is. Which means that the code that you've got is buggy. (Or was written for a similar, but differently screwed up linker script.) Each of those zeros is 2 bytes (which is what '.word' means). The end result is this:
Which I doubt would link at all.
It's basically designed for use with cc65 and not really what most ca65 users would expect. Which is why most people write their own. (Which are usually much less complex than this.)
So, yes, the vectors section starts at $FFF6 and it's size is $C. No, that doesn't make any sense, but that's how it is. Which means that the code that you've got is buggy. (Or was written for a similar, but differently screwed up linker script.) Each of those zeros is 2 bytes (which is what '.word' means). The end result is this:
Code: Select all
00FFF6 00 00
00FFF8 00 00
00FFFA 00 00 ; NMI
00FFFC nmi ; reset
00FFFE reset ; IRQ/BRK
010000 irq
MMC1 needs the vectors in each bank because it supports bankswitching of $C000-$FFFF. So there are 16 STUB segments, each with a copy of the vectors and a 10-byte reset redirector, as explained in src/mmc1.s.tokumaru wrote:in your SNROM template I don't see a VECTOR segment, but you obviously got the vectors in somehow.
I too include the Python programs that I use to develop my games, such as a CHR converter, an audio frequency lookup table generator, and any needed compression tools, in the archive with the source code and design documents. But if by "tools" you mean executables, do you also carry around a full copy of Wine if you happen to end up developing on a Linux PC?Also, due to the fact that I develop on several different computers, I like to keep everything (source, documents, tools, etc.) in a single archive, so it's better that the tools are simple and small.
But wouldn't 65816 support mean the vectors need to start around $FFE0 so that the segment can hit the native-mode vectors too?lidnariq wrote:The use of 12 bytes for vectors could be for something like the 65816's 6502-style interrupt table, where there are three extra vectors for COP, BRK, and ABORT. (Or as in the M50734's vectors for TX, HE, Timers, nINT1, nINT2, and nRESET)
Heh, I don't even know how to get Wine to work! XD I don't really have access to any Linux PCs. Now that I think of it, I don't carry ALL the tools around... Emulators for example are not included in my archives... pretty much everything else is though.tepples wrote:I too include the Python programs that I use to develop my games, such as a CHR converter, an audio frequency lookup table generator, and any needed compression tools, in the archive with the source code and design documents. But if by "tools" you mean executables, do you also carry around a full copy of Wine if you happen to end up developing on a Linux PC?
I should probably keep two different archives instead, one with the tools (which don't change often) and the other with code and documents.
-
Karatorian
- Posts: 76
- Joined: Sun Sep 30, 2007 9:54 pm
- Location: Corneria
- Contact:
The NES 'crt0.s' used by cc65 has the following code in the vectors segment. I haven't bothered to figure out what the extra "vectors" are for. From the question marks, the author of the comments doesn't seem to know himself. It clearly expects the vectors section to start at $FFF4, which means the default linker script is broken.lidnariq wrote:The use of 12 bytes for vectors could be for something like the 65816's 6502-style interrupt table, where there are three extra vectors for COP, BRK, and ABORT. (Or as in the M50734's vectors for TX, HE, Timers, nINT1, nINT2, and nRESET)
Code: Select all
; ------------------------------------------------------------------------
; hardware vectors
; ------------------------------------------------------------------------
.segment "VECTORS"
.word irq2 ; $fff4 ?
.word irq1 ; $fff6 ?
.word timerirq ; $fff8 ?
.word nmi ; $fffa vblank nmi
.word start ; $fffc reset
.word irq ; $fffe irq / brk
That's not to say cc65 doesn't work well on the NES. It's just that the out of the box configs are pretty bollixed.