Forums

Sega Master System / Mark III / Game Gear
SG-1000 / SC-3000 / SF-7000 / OMV
Home - Forums - Games - Scans - Maps - Cheats - Credits
Music - Videos - Development - Hacks - Translations - Homebrew

View topic - How to overcome *code* space limits in devkitSMS (code banking in slot 2)

Reply to topic
Author Message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
How to overcome *code* space limits in devkitSMS (code banking in slot 2)
Post Posted: Fri Feb 09, 2018 1:59 pm
While it seems SDCC support for "non-intrinsic named address spaces" is limited to variables (data in RAM) and constants (data in ROM) and it doesn't encompasses functions (yet?), there's still a way to expand the code beyond the -by default- provided 32 KB: thru bank-switching (in slot2, as usual).

Of course this means that the additional code can't be used for assets loading, as this would require that the code and the asset to be mapped at the same time, but nonetheless any function that doesn't call any other function or any function that only calls functions in the same additional code bank or in the 'lower' code area, could be safely allocated in a 'page-able' bank. Thus code space can be quite easily raised to almost 48 KB, and even more (at the cost of a few more caveats).

This, unfortunately as said, doesn't yet come in a transparent manner, given the aforementioned lack of non-intrinsic named address spaces support for functions... but if we treat the (banked) functions the same way we treat (banked) assets, everything would work.

As a proof of concept, I defined a simple function to halve a value, and I have put that in a separate source file: 'add_code.c'

/* code that goes into separate code bank */

#pragma codeseg ADD_CODE

int half(int number) {
  return(number/2);
}


and of course we need an 'add_code.h' header file

/* header */

int half(int number);


then, in our main.c, each time we need to invoke a banked function we have to invoke SMS_mapROMBank(), as you would do when loading a banked assets.

I find convenient in this case to define a macro accessBankedCode() so that I can have the number of the bank of the additional code written just once - less work if you need more banks for your assets (I imagine the banked code will be placed in ROM's last bank)

here's 'main.c'

#include "SMSlib.h"
#include "add_code.h"

#define ADDITIONAL_CODE_BANK     2
#define accessBankedCode() SMS_mapROMBank(ADDITIONAL_CODE_BANK)

void main (void) {

  int a;
  accessBankedCode();
  a = half(42);

}


Finally, of course we need to instruct the linker of the address of ADD_CODE code segment (at 0x8000, just like the assets):
sdcc -o output.ihx -mz80 --data-loc 0xC000 -Wl-b_ADD_CODE=0x8000 -L ..\SMSlib --no-std-crt0 ..\crt0\crt0_sms.rel main.rel SMSlib.lib add_code.rel


I hope this helps... eruiz00 and others too :)
code_banking.rar (9.04 KB)
code banking example source code

  View user's profile Send private message Visit poster's website
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 14682
  • Location: London
Reply with quote
Post Posted: Fri Feb 09, 2018 2:07 pm
In theory the potential call graph can be analysed and any sub trees not including a call to paging could be candidates for this. Selecting those automatically would be amazing...
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Fri Feb 09, 2018 2:13 pm
true, and potentially there would also be automatic placement of code into segments according to the restrictions...
(really, I wouldn't even know where to start building such a tool...)
  View user's profile Send private message Visit poster's website
  • Joined: 17 Nov 2015
  • Posts: 97
  • Location: Canada
Reply with quote
Post Posted: Fri Feb 09, 2018 3:36 pm
Such a thing has to be implemented in the linker which is the only part of the toolchain that has a global view of everything going into the output binary. z88dk/z80asm has a roadmap for implementing this kind of functionality but how far in the future it is is hard to say.

There is one compiler toolset that I know of that can do this for the z180 and that's the (still) commercial softools cross-c compiler.

Quote

Finally, of course we need to instruct the linker of the address of ADD_CODE code segment (at 0x8000, just like the assets):

sdcc -o output.ihx -mz80 --data-loc 0xC000 -Wl-b_ADD_CODE=0x8000 -L ..\SMSlib --no-std-crt0 ..\crt0\crt0_sms.rel main.rel SMSlib.lib add_code.rel



The bank location details are defined in the memory map in z88dk - the equivalent in sdcc would be defining all the banks as new areas in the crt. Then it's a matter of specifying the destination bank on the compile line to place code someplace else. It's a small gain but it makes everything more automatic.

This example (see README at bottom) places data in specific banks but it would be no different if applied to c or asm code. The banks themselves are defined so that the org can be modified via pragmas in a separate pragma file or embedded in c source.

The sms target is a little behind how we're doing things now; in particular banks will be numbered in decimal and that change maybe will break compiles so it should be done very soon.

sdcc is missing the capability to assign all its output to specific memory banks. It can only do code and rodata (constant data)** reassignment but it's missing bss & data (you can't put variables in a different bank) but maybe this doesn't affect the sms unless you have special cartridge hardware that mixes ram and rom. ** Philip recently moved toward adding this to sdcc. For sdcc we currently solve that by recommending those sorts of variables be declared in assembler instead of c, with a header making them accessible to c.

There's another new target in z88dk for the new retro 8-bit zx next which has greater demands on banking in that its paging can put a bank into different places in the memory map. And if I recall correctly, the sms can do that too. We deal with that by making the BANK_N names correspond to physical banks but allow different org inside those banks to allow different code to org to different addresses inside BANK_N. Then you can page BANK_N to slot X, execute code A and at the same time page BANK_N to slot Y, execute code B. But this may be overly complicated for the sms.
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 540
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 11, 2018 12:55 pm
Good.... Good!

There are only a trouble.... I Suppose this banked code Will have trouble using assets from other banks.... If so, i found way more interesting a function to decompress Code in RAM space, allowing to decompress different Code in different parts of a Game. This way the Code Will be bank state independent! (This could be difficult to develop, imho)

Regards
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3757
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Feb 11, 2018 7:24 pm
Alcoholics Anonymous wrote
There's another new target in z88dk for the new retro 8-bit zx next which has greater demands on banking in that its paging can put a bank into different places in the memory map. And if I recall correctly, the sms can do that too. We deal with that by making the BANK_N names correspond to physical banks but allow different org inside those banks to allow different code to org to different addresses inside BANK_N. Then you can page BANK_N to slot X, execute code A and at the same time page BANK_N to slot Y, execute code B. But this may be overly complicated for the sms.


The SEGA mapper supports 3 16 KB slots, slot 0, 1 and 2. Slot 0 has the 1st KB unpageable, thus making that a sort of 15 KB slot in practice. Slot 1 and 2 are plain 16 KB slots, the first at $4000 and the second at $8000. devkitSMS supports only slot 2 paging, but it isn't hard to add support for the other two slots - the problem that arises is that whatever you page in, it will have different addresses if you can page them in into different slots.

One might choose to use slot 2 for assets, the way it is already, and add slot 1 paging for code banking, but this will leave less than 16 KB of space to code that can't be paged. I'm not sure one would really go down this route... but in case, I will try to support that too.
  View user's profile Send private message Visit poster's website
Reply to topic



Back to the top of this page

Back to SMS Power!