It is currently Sat Dec 15, 2018 3:29 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 20 posts ]  Go to page 1, 2  Next
Author Message
PostPosted: Fri Aug 24, 2018 4:20 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2129
Location: Fukuoka, Japan
If I'm using a mapper that uses multiples banks and I write the code in assembler, I know how to define the segments and put them at the right place in the cfg file. My issue is if I write the code in C or define some data in C structure, how can I say that this code or this data should be in a specific bank?

For now I didn't find much yet. There seems to be something new (2017) about trampoline or something but I cannot visualize how to organize my code around that. Then I saw an old post (2016) by dougeff that seems to compile the code separately and put the vector in each file but that seems to be for a very specific mapper.

I guess I should the mapper that I would like to target, and that would be the mmc3. So what approach can be used with that mapper? Since I'm getting to like to write some part in C that would be a shame to have to go back to asm and rewrite the code.


Top
 Profile  
 
PostPosted: Fri Aug 24, 2018 4:37 pm 
Offline
User avatar

Joined: Fri Nov 24, 2017 2:40 pm
Posts: 95
Check out #pragma code-name and wrapped-call:
https://cc65.github.io/doc/cc65.html


Top
 Profile  
 
PostPosted: Fri Aug 24, 2018 5:06 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7017
Location: Canada
That particular extension was written by calima. There's some more info here:
https://forums.nesdev.com/viewtopic.php?f=2&t=15959


Top
 Profile  
 
PostPosted: Fri Aug 24, 2018 9:17 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2129
Location: Fukuoka, Japan
@slembcke

This is the first thing I looked at. It is very ambiguous unless you already know this coding pattern. This is why I searched more on the subject and ended back on nesdev :lol:

@rainwarrior
I saw that post. This is actually the first one I found when searching on the subject (actually there was a post from 2016 when it was not possible yet but that post is not relevant anymore).

Maybe it's because it was 2h in the morning when I checked the content but I cannot visualize how I would use it in a C project to put C code in specific segment/bank. This example seems to explain the "how" to call the code in that bank. My current problem is I don't even know how to put the code in a specific bank in the first place. There is ".segment" in assembler but no such thing in C. I think it just ends up in the "code" segment by default. If I have to compile file per file and put in specific bank then this requires a complete rethinking of my makeFile that just compile everything and let the linker do the job.

Is there an example that shows how C code is put in a specific bank then called later? If I can see with my eyes and experiment with it then I will be able to figure out how to reproduce in my own code.


Top
 Profile  
 
PostPosted: Fri Aug 24, 2018 9:29 pm 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 7017
Location: Canada
CC65's C has pragmas that can be used to set segments. Use #pragma code-name to put code into a specific segment, and #pragma rodata-name to put read-only (const) data in a specific segment.


Top
 Profile  
 
PostPosted: Fri Aug 24, 2018 9:46 pm 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2129
Location: Fukuoka, Japan
I knew about those pragma but I completely misunderstood their usage! I was sure it was to change the name of the current "code/data" segment to something else inside my code instead of through the command line, not to add extra segments. Must be an English as a second language misunderstanding kind of thing.

Thank you for pointing that out. Now I need to migrate back my project to my target mapper and see how it goes.


Top
 Profile  
 
PostPosted: Sun Aug 26, 2018 1:13 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 500
You can also check my UNROM-ready template using neslib and famitone.

viewtopic.php?p=169438#p169438

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Sun Aug 26, 2018 5:41 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2129
Location: Fukuoka, Japan
I will start to experiment soon but there is one thing that I would like to confirm before trying it.

What is the use of the trampoline code? I'm not sure yet. I'm my current project, what I expect to do is to switch the bank first by calling a method made in ASM then call the code expected in that bank. I would think with that way that it would work right away. So if this work then what is the use of the trampoline code? My guess would be go to a function by changing the bank before then calling the method then going back to previous bank?


Top
 Profile  
 
PostPosted: Sun Aug 26, 2018 6:18 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20878
Location: NE Indiana, USA (NTSC)
The answer relates to what bank is active immediately after a function returns (using the rts instruction in assembly, or return or reaching the end of a void function in C). To help us understand what you expect to do, please answer these questions with respect to that:

To which bank does the subroutine made in assembly language to change the bank return?
To which bank does the function in the new bank return?


Top
 Profile  
 
PostPosted: Sun Aug 26, 2018 7:03 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 500
I think it's a good idea, for starters, to begin with a project that has all relevant code (i.e. main loop) in the fixed bank, which calls to subroutines (i.e. functions) in different pages. That's the simplest scenario. You just bank switch to make the relevant bank visible, then call the function. Once you get the hang of it you can start complicating things.

My game Cheril the Goddess does exactly that. All the main stuff is in the fixed bank, and subroutines in different banks.

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Sun Aug 26, 2018 7:33 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2129
Location: Fukuoka, Japan
@Tepples

What I expect to do is like na_th_an said. In my fixed bank I will have code that contains the main flow of the game. When I change a phase (for example title screen, menu, game play), the fixed bank prepare the state, change the bank then call the code inside that bank.

Inside that code, it will loop until that state is over. Once over, it return to the fixed bank code to decide what to do next. So I think in that kind of scenario, the "trampoline" code ins not necessary unless I'm mistaken?


Top
 Profile  
 
PostPosted: Sun Aug 26, 2018 9:10 am 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20878
Location: NE Indiana, USA (NTSC)
The "multicart full of 16K games" organization might work until a single phase needs to access more than 16K of total code and data.


Top
 Profile  
 
PostPosted: Sun Aug 26, 2018 10:00 am 
Offline
User avatar

Joined: Tue Jun 24, 2008 8:38 pm
Posts: 2129
Location: Fukuoka, Japan
You indirectly answered my question. What you means is, yes, it will be fine except if you data/code becomes more than 16k you will have issues.

So I have to be careful regarding size of data and code.


Top
 Profile  
 
PostPosted: Sun Aug 26, 2018 1:15 pm 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1765
I think you should try to keep all of the code in the fixed bank and only use the several banks for data. This way, the control of the program is always in the fixed bank. Otherwise you might run into an issue when your code from a variable bank needs data from yet another bank.

For example, in my game I cannot put the functions to build a new screen into a variable bank. Because I will probably need more than one bank for all the screen data anyway, so the code has to be in the fixed bank, so that it's able to switch between all the banks to read all those constant arrays.

I have one exception:
The code for the text screens (title screen, credits etc.) is in a separate bank.
Text screen logic is separated enough from the actual main game logic, so that there's no interaction between the text screens and any read-only data from the game logic.
And one bank is more than enough to store all the text screen code and its display data, so in this particular case I can be sure that there won't be any conflicts.

But stuff like the music library or rendering the sprites: That always goes into the fixed bank while the songs themselves and the meta sprite definitions are in their own banks.

(If you use a mapper with extended cartridge RAM, you can use this RAM for yet some more KB of always available code: Just store some code into a variable bank. And at the start of the program, you copy this code from the bank into RAM.
cc65 config files have a feature that let you store data into one place, but execute it as if it was located in another place. You can define a segment for your code and tell the compiler that it's stored in one memory location, but executed in another.)

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Sun Aug 26, 2018 5:46 pm 
Offline

Joined: Sun Sep 19, 2004 11:12 pm
Posts: 20878
Location: NE Indiana, USA (NTSC)
More generally: If one code module needs to refer to no more than about 12K of data, it and its data go in a bank. Otherwise, it can go in the fixed bank and refer to multiple banks of data.

Putting all code in the fixed bank may limit how many distinct player, enemy, and projectile behaviors you can add. It did in The Curse of Possum Hollow, requiring several refactors over the course of its development to move things out as the fixed bank at $C000-$FFFF filled up.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 3 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