It is currently Fri Oct 20, 2017 2:51 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 32 posts ]  Go to page Previous  1, 2, 3  Next
Author Message
PostPosted: Fri May 02, 2014 11:46 am 
Offline
NESICIDE developer
User avatar

Joined: Mon Oct 13, 2008 7:55 pm
Posts: 1026
Location: Minneapolis, MN
rainwarrior wrote:
So, we can attach .nesproject files now, but then I realized I should probably just add it to the zip. :P

Yeah I suppose I could have added it to your ZIP and re-uploaded the ZIP. But then there'd be two ZIPs floating around one with and one without.


Top
 Profile  
 
PostPosted: Fri May 02, 2014 2:09 pm 
Online
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2962
Location: Tampere, Finland
Off topic:

There's one small feature that I really miss from WinRAR after switching to 7zip: when the Extract button is pressed, it doesn't automatically fill the destination path with the name of the package (with extension stripped), instead it defaults to extracting to the directory where the package is. Usually not a problem since I mostly use the context menu to extract stuff, but sometimes it's more natural to open the archive in the program (e.g. when the file has been downloaded with a browser).

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Mon Oct 06, 2014 5:39 pm 
Offline
User avatar

Joined: Mon Oct 06, 2014 5:09 pm
Posts: 25
Location: Two Bridges, Manhattan (NTSC)
rainwarrior, thanks, this is super useful for someone getting started with ca65 on the NES.

I have a question, though. (Probably dumb, as I'm new to both the cc65 suite and 6502 programming.)

In example.cfg, you have:
Code:
MEMORY {                                                                                                 
    ZP:     start = $00,    size = $0100, type = rw, file = "";                                           
    OAM:    start = $0200,  size = $0100, type = rw, file = "";                                           
    RAM:    start = $0300,  size = $0500, type = rw, file = "";                                           
    HDR:    start = $0000,  size = $0010, type = ro, file = %O, fill = yes, fillval = $00;               
    PRG:    start = $8000,  size = $8000, type = ro, file = %O, fill = yes, fillval = $00;               
    CHR:    start = $0000,  size = $2000, type = ro, file = %O, fill = yes, fillval = $00;               



Because CHR starts at $0000, doesn't this mean that the TILES segment (full of data from `.incbin "background.chr"', etc.) will overlap the zero page and the stack page ($0100 - $01FF), as well as the OAM and RAM areas (not to mention the iNES header)? Doesn't this mean that if I, say, push something onto the stack, I'll be overwriting random parts of the background tiles data? I must not understand how ld65 behaves when you declare overlapping memory areas... why not declare all of the memory areas as strictly disjoint regions? (looks like none of the examples in the ld65 docs have overlapping memory areas)

_________________
Well, kids, you tried and you failed miserably. The lesson is: never try.


Top
 Profile  
 
PostPosted: Mon Oct 06, 2014 5:44 pm 
Online

Joined: Sun Apr 13, 2008 11:12 am
Posts: 6288
Location: Seattle
The NES has two completely unrelated notions of address: one is for the CPU, and has zero page, stack, other RAM, &c.
The other is for the PPU and (almost always) contains just tile data.
They both start at 0. They're just different 0s.


Top
 Profile  
 
PostPosted: Mon Oct 06, 2014 5:59 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5726
Location: Canada
As lidnariq said, in this case these are two different memory regions (CPU vs PPU), but I will also explain the linker.

Each line of the MEMORY section describes a block of memory space that can be used by a SEGMENT, and also may be output to a file. MEMORY regions will be output in the same order as specified.

Each line of the SEGMENTS section describes an allocation of space in one of the previously defined MEMORY blocks. A segment doesn't have to fill up all of any particular MEMORY region, and will be assigned space contiguously in the order listed, sometimes with padding if a start address is specified.

Assembly code may specify which SEGMENT to use with the .segment directive, and the SEGMENT will be filled contiguously in the order the code/data appears.


All that said, blocks in MEMORY can refer to memory regions in different spaces, like in this case, or even the same space. What it really controls is whether and where that region will appear in the output file. A space that represents RAM doesn't normally go in the file. In an iNES file, there is a 16 byte header (HDR), a PRG block (PRG), and a CHR block (CHR), so I have specified 3 MEMORY regions for these three parts of the file.

If you are doing banking, you will typically want to have one MEMORY region per bank. In this case, many of them will overlap the same address space, but what matters is they will go into the file as separate blocks, and you can use SEGMENTS to specify which bank things need to go into.


Top
 Profile  
 
PostPosted: Tue Oct 07, 2014 6:50 pm 
Offline
User avatar

Joined: Mon Oct 06, 2014 5:09 pm
Posts: 25
Location: Two Bridges, Manhattan (NTSC)
Thanks, guys, I think I get it now. What I failed to appreciate is that with the MEMORY areas that are being written to the file (%O), we are actually describing the layout of the iNES file, not the runtime layout of memory -- the iNES format has its own conventions about how its contents will determine the initial state of memory at power-on. And, on the other hand, the MEMORY areas with file = "" (ZP, OAM, RAM) are referring to the runtime address space, but this is for purposes of the symbolic assembler knowing how to interpret what we put in our source code, so it knows, e.g., that ".res 1" means to reserve a byte in one region if it appears under ".segment "ZP"", but in another region if it appears under ".segment "RAM"".

_________________
Well, kids, you tried and you failed miserably. The lesson is: never try.


Top
 Profile  
 
PostPosted: Sat Oct 11, 2014 8:42 pm 
Offline
User avatar

Joined: Mon Oct 06, 2014 5:09 pm
Posts: 25
Location: Two Bridges, Manhattan (NTSC)
One more question: is there a particular reason that you define the gamepad_poll subroutine in the DATA segment, rather than in the CODE segment? Changing it to CODE compiles and works fine. Is it more efficient somehow to have this subroutine located in DATA? (Not sure how that would be, unless you were depending on relative addressing in such a way that you wanted to be close to certain addresses, but I don't see how that's the case here.)

_________________
Well, kids, you tried and you failed miserably. The lesson is: never try.


Top
 Profile  
 
PostPosted: Sun Oct 12, 2014 3:59 am 
Online
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2962
Location: Tampere, Finland
thenendo wrote:
One more question: is there a particular reason that you define the gamepad_poll subroutine in the DATA segment, rather than in the CODE segment? Changing it to CODE compiles and works fine. Is it more efficient somehow to have this subroutine located in DATA? (Not sure how that would be, unless you were depending on relative addressing in such a way that you wanted to be close to certain addresses, but I don't see how that's the case here.)

Looks like a mistake. It's not more efficient.

In this case it doesn't matter which segment the code is placed in, because both the CODE and the DATA segments are ROM and end up in the same memory area. If one wanted to place code at certain addresses, the correct way to do it in cc65/ca65 would be to define a new segment (and possibly a new memory area as well) with the desired starting address.

...

On an unrelated note, it goes somewhat against convention to name the read-only data segment DATA. Typically RDATA or RODATA is used for that, and DATA is used for initialized data in RAM. Not saying that it should be changed, only noting it here since some other source code might be using different conventions.

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Sun Oct 12, 2014 6:44 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5726
Location: Canada
Yeah, just a mistake. I will correct that.

Also, that is a good point. I forgot that RODATA is the cc65 convention for read-only data, though the name might be a little more obscure to new users. Not sure if I want to correct this. The main reason I bother to use separate CODE and DATA segments is that it keeps them nicely separated (good for debugging disassembly if all the code is in one contiguous place) and so the map statistics the linker generates will list them separately.


Top
 Profile  
 
PostPosted: Sun Oct 12, 2014 7:05 am 
Offline
User avatar

Joined: Mon Oct 06, 2014 5:09 pm
Posts: 25
Location: Two Bridges, Manhattan (NTSC)
Awesome, gotcha. While you're at it, I think you could also fix a typo in the comment on line 52 (byte 5 of the iNES header):
Code:
.byte $01 ; 4k CHR bank count


That should say 8k, right?

_________________
Well, kids, you tried and you failed miserably. The lesson is: never try.


Top
 Profile  
 
PostPosted: Sun Oct 12, 2014 8:24 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5726
Location: Canada
Yeah.


Top
 Profile  
 
PostPosted: Sun Oct 12, 2014 8:45 pm 
Offline
User avatar

Joined: Mon Oct 06, 2014 5:09 pm
Posts: 25
Location: Two Bridges, Manhattan (NTSC)
rainwarrior wrote:
Also, that is a good point. I forgot that RODATA is the cc65 convention for read-only data, though the name might be a little more obscure to new users. Not sure if I want to correct this. The main reason I bother to use separate CODE and DATA segments is that it keeps them nicely separated (good for debugging disassembly if all the code is in one contiguous place) and so the map statistics the linker generates will list them separately.

Relatedly, I think you might want to use "ZEROPAGE" instead of "ZP". Using your linker config (with "ZP"), I found that this code makes assembler fail with "Error: Range error":
Code:
.segment "ZP"
addr0: .res 2

.segment "CODE"
; ... in some subroutine
sta addr0+1

But after I renamed "ZP" to "ZEROPAGE" in the linker config and assembly source, it seems to work as expected. I guess without it, ca65 isn't smart enough to figure out that addr0+1 is a constant zero-page address, or something.

Edit: It makes sense that ca65 isn't smart enough, because the assembler runs before the linker, so it has no knowledge of the segment layouts and types; so it's forced to rely on hard-coded conventions for certain things, like "ZEROPAGE".

_________________
Well, kids, you tried and you failed miserably. The lesson is: never try.


Top
 Profile  
 
PostPosted: Mon Oct 13, 2014 2:22 am 
Online
User avatar

Joined: Mon Jan 03, 2005 10:36 am
Posts: 2962
Location: Tampere, Finland
thenendo wrote:
Edit: It makes sense that ca65 isn't smart enough, because the assembler runs before the linker, so it has no knowledge of the segment layouts and types; so it's forced to rely on hard-coded conventions for certain things, like "ZEROPAGE".

Your analysis is correct. However, it's also possible to explicitly specify a segment as a zero page segment:
Code:
.segment "ZP" : zeropage
foo: .res 1
; ...

_________________
Download STREEMERZ for NES from fauxgame.com! — Some other stuff I've done: kkfos.aspekt.fi


Top
 Profile  
 
PostPosted: Mon Oct 13, 2014 8:04 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5726
Location: Canada
thenendo wrote:
rainwarrior wrote:
Relatedly, I think you might want to use "ZEROPAGE" instead of "ZP". Using your linker config (with "ZP")


Ack, yeah I forgot about that special name too. Okay, I've renamed ZP > ZEROPAGE, and DATA > RODATA to keep with ca65 convention.


Top
 Profile  
 
PostPosted: Thu Oct 16, 2014 2:28 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5726
Location: Canada
Fixed a bug with the emphasis bits, accidentally had emphasize-red set on.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 32 posts ]  Go to page Previous  1, 2, 3  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group