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 - Source code limit on sdcc

Reply to topic
Author Message
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Source code limit on sdcc
Post Posted: Mon Feb 20, 2017 10:37 pm
Ummmm..... after two weeks developing i am beggining to worry about source code size and limits. This is because two hours ago cannot run the game if sdcc optimize for speed is set. I have regrouped common functions and move to bank some static data like sine wave tables and its working with the optimization set to on now.

Can i check the source code size or the rom space used before the banks ?

Maybe i have a fault or its sdcc... not sure about the overhead of smslib or sdcc runtime or source code generated.

Any comment is welcomed. Dont want to send a two-roms game!!!

Thanks guys.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3828
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Tue Feb 21, 2017 9:24 am
Check the .map file generated, locate where's

l__CODE

that value on the left it's the length of your code. It should be well under 0x7E00 (0x8000-0x0200)
  View user's profile Send private message Visit poster's website
  • Joined: 07 Aug 2007
  • Posts: 220
  • Location: Yach, Germany
Reply with quote
Post Posted: Tue Feb 21, 2017 1:03 pm
Weird; I was sure I wrote a reply to this thread this morning. I guess I only previewed it.

Anyway, besides the recommendation that sverx gave, I also suggested to try --max-allocs-per-node N. Higher values optimize more and slow down compilation. The default is 3000.
You might save quite a few bytes by increasing it. And of course there is --optimize-code-size.

Philipp
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Tue Feb 21, 2017 1:26 pm
This evening i will check lcode but now i have the sense it was not the problem. Maybe far referenced variable pointers (if this is a problem) or that weird error with sdcc when you have large functions with local variables. Afterall i think its a good moment to optimize and clean a bit..
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Tue Feb 21, 2017 6:38 pm
Oh my god!!! Have to do something at respect.

What i dont understand is that half of the memory seems to be used for data. Can someone give me insights about this?
20170221_193738.jpg (3.42 MB)
20170221_193738.jpg

  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Tue Feb 21, 2017 6:53 pm
First though is about banks.... seems they use many space before code. Its like i could not make a 512kb rom...
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Tue Feb 21, 2017 8:04 pm
Ah. No. Sorry. Its the code. Ok. Lets rip the game (snif)
  View user's profile Send private message
  • Joined: 07 Aug 2007
  • Posts: 220
  • Location: Yach, Germany
Reply with quote
Post Posted: Tue Feb 21, 2017 8:15 pm
eruiz00 wrote
Oh my god!!! Have to do something at respect.

What i dont understand is that half of the memory seems to be used for data. Can someone give me insights about this?


Looks like you use about 32 KB of nom-banked ROM and about 1.7 KB of RAM.

Philipp
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Tue Feb 21, 2017 8:43 pm
I also looked at function addresses and with excel doing a rest to see the bigger ones.

The trouble seems to be in lack of data driven scripting( instead of raw code... (many years of java and delphi got me almost stupid developer) as i can upload this data to a bank, so this seems to be my way. Nobody said this was to be easy!
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3828
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Feb 22, 2017 9:00 am
0x78b9 it's a lot of code (well, you've got some left anyway)... but maybe you've got big 'const' arrays there? They will use your CODE segment too...
BTW check you .map file, after the title:

Area                                    Addr        Size        Decimal Bytes (Attributes)
--------------------------------        ----        ----        ------- ----- ------------
_CODE                               00000200


you'll see the list of your functions/const arrays and you can see what is eating up your ROM there...

edit: also, your banks seems mostly empty. are you using assets2banks (that will allocate assets automatically) or the 'old' folder2c (which requires you to manually handle allocation)?
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Wed Feb 22, 2017 1:13 pm
I use folder2c but my plan is to reorder the arrays at end. My workflow is going well this way. Most of arrays are 10kb songs so i think i cannot split them.

Yesterday in one hour did a little scripter from data in arrays and move all the constant arrays to a bank and things went well. Now my code is 39xx and have to move enemy patterns and movement to data so i think is resolved for now. Performance did not went bad so it seems a very good change.

Definitelly have to put a dedication at the end of the game. So quick and good asdistance desserves it. Thanks guys.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3828
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Wed Feb 22, 2017 2:21 pm
eruiz00 wrote
I use folder2c but my plan is to reorder the arrays at end.


As soon as you'll switch to assets2banks you won't ever look back. So true that I'll remove folder2c from devkitSMS 'soon'...

eruiz00 wrote
Most of arrays are 10kb songs so i think i cannot split them.


(You might not know that) PSG files can be compressed (I call them PSGC to remember they're already compressed) and used directly with PSGlib. This might shave 10%-30% of the original size, depending on single tune self-similarity.

eruiz00 wrote
Yesterday in one hour did a little scripter from data in arrays and move all the constant arrays to a bank and things went well.


Yes, large arrays are better moved in banks. I keep small LUTs in the lower 32 KB... well, as long as I've got still plenty of space left.
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Wed Feb 22, 2017 5:33 pm
I know i can split music as i can check if its playing... but i dis not find psgcomp tool.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3828
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Feb 23, 2017 8:54 am
vgm2psg and psgcomp are in the tools folder in the PSGlib repository.
I warn you that psgcomp is VERY slow, so I suggest running it on definitive PSG assets only.
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Thu Feb 23, 2017 7:15 pm
Ok. Ill test right now. Dont want to send a fat rom. Its not elegant :)
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sat Feb 25, 2017 8:57 am
Ummm i think got caugh on other trouble. Lets me explain. I have FOUR bank switchs by frame. Why? Music bank , map bank, script bank, custom stage assets bank. and everything is ok except two things:
1. In some stages i see bank data corruption. Its not src fault. I have revised it 100 times. Maybe cannot switch everytime i want? Some time cycles to wait or between switchs?
2. Lagging is beggining to appear. Maybe bank switch is cheap but not free.

Ill group the three or two latest banks but like to know more about this if possible.

Thanks!
  View user's profile Send private message
  • Joined: 04 Jul 2010
  • Posts: 542
  • Location: Angers, France
Reply with quote
Post Posted: Sat Feb 25, 2017 9:22 am
I switch far more 4 times per frame on my dev and it's not a problem.

switch bank is a tiny asm code :
(that's on my SDCC dev - not the devKit from sverx)

_switch_bank::
       ld      hl,#2
       add     hl,sp
       ld      a,(hl)
       ld     (#0xFFFF),a
ret


Just be careful/be sure to read/point to datas in the good bank each time.

Data corruption = (generally) writing to VDP in active display - too fast.
(too much things in vblank)
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sat Feb 25, 2017 9:39 am
I think i have found an error in code but seems strange to me.

Have this array in bank1.c:

Const unsigned char a[]={...};

The declaration in bank1.h( which of course is not included in bank1.c)

Extern const unsigned char *a;

Does not work!!!

If i change to:

Extern const unsigned char a[];

Does work at all. Maybe there are differences in how sdcc or z80 manage pointers respect how would i386+ c compiler do...
  View user's profile Send private message
  • Joined: 07 Aug 2007
  • Posts: 220
  • Location: Yach, Germany
Reply with quote
Post Posted: Sat Feb 25, 2017 12:00 pm
eruiz00 wrote
I think i have found an error in code but seems strange to me.

Have this array in bank1.c:

Const unsigned char a[]={...};

The declaration in bank1.h( which of course is not included in bank1.c)

Extern const unsigned char *a;

Does not work!!!

If i change to:

Extern const unsigned char a[];

Does work at all. Maybe there are differences in how sdcc or z80 manage pointers respect how would i386+ c compiler do...


An array is not the same as a pointer. In C, arrays decay into pointers in some situations, but that does not mean that they are the same.

Philipp
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sat Feb 25, 2017 1:11 pm
Sorry but i disagree. Obviously there is a difference between a const closed and delimited typed array and a pointer to a typed array ( in worst case void * as untyped) from which we dont know his length...

But the name of the array ( the var) without indexs at computing effects is a pointer to the base of the array (the element 0).

Although i must be mistaken seeing the facts...
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3828
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Feb 25, 2017 1:47 pm
As PkK said, they're not the same thing, even though they might be the same thing "under the hood" (an address, you know). So if you're declaring an const unsigned char array in some C source file, then you must declare an external const unsigned char array in your other source where you want to access that, otherwise the linker probably won't be able to match the two.

Bankswitching is syncronous anyway so when you've done requesting a bank switch, you can consider that done before you perform any read, so there are absolutely no troubles in that, be sure :)

edit: no, bankswitch isn't free, but it is usually performed in just a few cycles. Having 4 bankswitches per frame isn't so uncommon, in many case I have more than 4 (streaming tiles, updating maps, music, SFX, other data...) and they aren't the costly part of the work...
  View user's profile Send private message Visit poster's website
  • Joined: 07 Aug 2007
  • Posts: 220
  • Location: Yach, Germany
Reply with quote
Post Posted: Sat Feb 25, 2017 2:13 pm
Last edited by PkK on Sat Feb 25, 2017 9:11 pm; edited 1 time in total
sverx wrote
As PkK said, they're not the same thing, even though they might be the same thing "under the hood" (an address, you know).


In the OPs case his array and pojnter are also quite different under the hood: The array is placed in ROM by SDCC. No RAM is needed.
But the pointer is a variable in RAM.

Another related programmer-visible difference:

a = 0;


would be legal for the pointer, but not for the array.

Philipp
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sat Feb 25, 2017 3:55 pm
Oh my good. Last example is TRUE. definitely have to left java... anyway the problem was solved :)

Respect performance. I will do optimizations later. For now i am splitting by two frames (even-uneven) all calculations (player. enemies .playershoot .enemyshoot .scroll .map updates. script. effects. collision between all the different classes....) so find it a bit jerky but nothing that cannot be solved.
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 26, 2017 8:44 pm
Ummmm... the progress is good but im having troubles on performance. Have made several optimizations like arrays of structs and pointers instead property arrays, clean code, checking switchs based on sdcc documentation... So, thanks anticipated, my questions:

Performance differences when using ints instead of chars on 8 bit processor.

Optimized collision detection? have up to 16 enemy shoots, 12 enemys, 6 player shoots... and think this is a crucial factor.

Given two quads, one 8x8 and other 16x16... can do 4 if () then... or two abs(rest) and two if thens.

Last but not least. There are some way to profile functions and check bottlenecks??? Maybe have to learn some z80 assembly!!!
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sun Feb 26, 2017 9:57 pm
Ummm... i can see little improvement if replace ints to chars
  View user's profile Send private message
  • Joined: 04 Jul 2010
  • Posts: 542
  • Location: Angers, France
Reply with quote
Post Posted: Sun Feb 26, 2017 10:35 pm
I do not know if sverx put a "set border" function into his lib, but i've got one in my sdcc lib and i'm using it often.

With this you're sure that your code pass in the current active display or vblank.
(With some ifdef, it's very practicle)

Set borders take only colors from the 2nd palette (sprites), you can see them in the overscan. Use emulicious and uncheck "hide borders"

; void set_border_color(unsigned char color)
_set_border_color::
       ld      hl,#2
       add     hl,sp
       ld      a,(hl)
       or      #0xF0
       out     (#0xBF),a
       ld      a,#0x87
       out     (#0xBF),a
ret



For me critical functions must be written in asm.
SDCC is good but sometimes it makes horrible code (even on simple things like memcpy...)
I've rewritten some functions, and now they are 5 times faster than the original one in C.

  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3828
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sun Feb 26, 2017 11:39 pm
some general suggestions:
- use chars instead of ints whenever possible
- use unsigned instead of signed whenever possible
- try not to use arrays of structs, make separate arrays (somebody calls this "structs of arrays", but actually they're just separate arrays...)
- you can profile using Emulicious (it's just wonderful)
once you find out which function(s) are eating your CPU time, check if by chance you're calling modulus and/or divide operations. Also multiplications should be avoided whenever possible.
- for a simple CPU meter on screen you can use a sprite, see this:
http://www.smspower.org/forums/15228-DevkitSMSDevelopYourHomebrewInC?start=250#9...

@ichigobankai: yes, there's this function:
void SMS_setBackdropColor (unsigned char entry);    /* set which sprite palette entry will be used for backdrop */
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Tue Feb 28, 2017 1:07 am
Ummmm have test emulicious profiler and is fantastic!!! Only thing i cannot get to understand is the end field and the value i have to put inside... search the ret of the function and copy his address and things funcs but im not sure of the results

Conclusions were that things which can be calculated each 2/4/8/16 frames must be skipped the rest of frames. Now the things are much fluid and can have up to 16 enemy shoots at once. Anyways the game seems hard to me, although i have played all the shmups in history lol :) soon ill upload a one stage demo to get advices. Thabks guys
  View user's profile Send private message
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Thu Mar 09, 2017 2:06 pm
Sorry guys but have a question.

I have put an interrupt handler for waitvblank and a counter and every two frames im doing one or two ( or zero) waits to ensure the game speed is the same.

This is because cannot balance the functions between each frame on pair. Sometimes i have nothing and other i have just too much enemies and bullets.

This solution works very well but as i am updating psg every frame i am worried because the psgupdate call timing is not regular.


Do i have to call updatepsg and updatepsgfx after waitvblank or can i do this elsewhere? What about timing?

Thanks!
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3828
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Thu Mar 09, 2017 3:40 pm
can you hear the music update being irregular?
I mean, even if it's not perfectly regular it's quite hard to notice, you must really have a good ear... or your call be VERY irregular.

BTW what I usually do is to wait for VBlank, run the UNSAFE VRAM stuff and just after that do the music/SFX update.

If you really REALLY need not to tie your music update to vblank, you could use line IRQ and update music/SFX when the VDP is drawing the 100th line, for instance. But in this case you should keep in mind that after the IRQ you should make sure you restore the ROM bank you were using prior to the interrupt. I don't suggest this way, though.
  View user's profile Send private message Visit poster's website
  • Joined: 28 Jan 2017
  • Posts: 556
  • Location: Málaga, Spain
Reply with quote
Post Posted: Sat Mar 11, 2017 8:57 am
Ummm... the thing which really bug me is that im sure sometimes im calling two times upsatepsg too quickly but doesnt seems to affect the music perception. In other hand the music is really broken in meka while in rest of emulators just plays well. So i thought about how should play in real system.

Last but not least. Yesterday tested it and really liked waimanusms. So pro like game and good balanced playability for such a standard good old idea. Good work dude!!!
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 3828
  • Location: Stockholm, Sweden
Reply with quote
Post Posted: Sat Mar 11, 2017 9:10 am
Of course if you've got the chance nothing beats testing your ROM onto the real thing. But if you haven't got a chance, I suggest you try Emulicious... if it plays/works fine there, chances are it'll plays/works fine on hardware too.

I'm happy you like my little game, thanks. More Waimanu action will come, soon(ish).
  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!