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 - Beginners question [C and SMSDevKit]

Reply to topic Goto page Previous  1, 2, 3  Next
Author Message
  • Joined: 29 Mar 2012
  • Posts: 504
  • Location: Spain
Reply with quote
Post Posted: Sat Jun 29, 2019 4:02 pm
I would say most "normal" games can be done using plain C. Asm probably is needed on some parts if you have intensive computing.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Sat Jun 29, 2019 5:36 pm
SDCC creates pretty good code but yes, it's hard to beat handwritten asm (if written by an experienced developer).

I wouldn't worry if I were you, as you can do cool stuff with devkitSMS too, check this list here: a few suggestions are surely eruiz's Astro Force, Galactic Revenge and Silver Valley, or even my own Weka Invaders or MARKanoIIId (unfinished) - but please do check all the other creations in the list too, they're surely worth your attention :)

In the while SMS_decompressZX7() (to decompress to RAM) has been added.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Sat Jun 29, 2019 5:55 pm
Awesome :D I will go with the SDCC then x3
I'm not much into inline assembly actually - I spend half a year removing inline assembly from our code base at work xD

I want to download some of those games and stream then :3
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Tue Jul 02, 2019 5:47 pm
It's me again °-°

I'm happy and a bit proud, I finally managed to scroll my map into 8 directions ^o^
Took my long enough though...

Anyway, I'm still concernd if my code is fast enough - currently I render the part of the screen every VBlank and allow the screen to move with 1pixel each direction.
It feels very slow - now I wonder if I render to slow or if it is normal and stuff like that... Any ideas how to validate my concerns?

Edit:
Well... I compared the scroll speed between no rendering of map and a rendering of my map - there are huge differences in the time x.x"
So my code is very slow...

Edit2:
So yesterday in bed I realized that it is over the top to copy the map every frame. Today I want to focus on copying only the parts that really needs to be updated. I hope this will make things better, I'm still frustrated that it is so slow... Am I that bad? >o<
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 504
  • Location: Spain
Reply with quote
Post Posted: Wed Jul 03, 2019 6:00 am
You're not that bad at all, siply the time is tight on the z80
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Wed Jul 03, 2019 9:29 am
Jaberwocky wrote
So yesterday in bed I realized that it is over the top to copy the map every frame. Today I want to focus on copying only the parts that really needs to be updated.


Yes, that's the way. As VRAM access is particularly slow, and as we have hardware scroll anyway, you're going to update one row of data AND one column of data in the same frame worst case. This can be done without perceivable slowdown.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Thu Jul 04, 2019 8:41 pm
Thanks guys x3 I finally have my map scrolling in all directions :D The frame rate is better now - I guess it could be even faster, but for a beginning I'm really happy :3

Next thing to tackle will be sprites on the map, in dependency of the current 'camera' position.

Also... In an assembly code I looked into, I read something about a "General purpose RAM" - it had a fixed address, which I can't remember anymore... What is that about? And what do I do if I want more then 64 sprites on my screen?
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 12883
  • Location: London
Reply with quote
Post Posted: Thu Jul 04, 2019 9:56 pm
Most games limit scroll speed to 8 pixels per frame (which is a lot), in order to avoid needing to draw more than one column of tiles.

RAM is what the compiler will be using for all your globals and suchlike.

You probably don't want to use more than 64 sprites. Consider the 8 sprite limit per row limit also applies.
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Fri Jul 05, 2019 8:26 am
Jaberwocky wrote
And what do I do if I want more then 64 sprites on my screen?


The hardware supports no more than 64 sprites so if you really need more than that (hardly, I would say!) you should multiplex, or use 'software sprites', which is an expression to indicate that you're drawing your characters in the background (slow, cumbersome) instead of using the system hardware features.

Note that even multiplexing the sprites you won't ever get more than 8 sprites appear on every single screen line.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Sun Jul 14, 2019 12:34 pm
Thanks again for the help :3
Had a busy week but I managed to get some basic stuff running - I improved my screen scrolling and played a bit with sprites.

What does multiplexing of sprites mean?

Also... from the old pokemon games I remember an effect where you had a black screen and could only see the map through a circle - is such an effect possibel with the SMS as well? And how would you do that?
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 12883
  • Location: London
Reply with quote
Post Posted: Sun Jul 14, 2019 1:31 pm
Multiplexing means you update the sprite table at some point in the screen. I don't know any game which does that because it's really hard.

To get a spotlight effect you'd need to draw the whole screen using black tiles, except for near the centre where you draw a blocky circle. Then use sprites to mask the edges to be pixel perfect. This costs a lot of sprites though. I think Ys does it?
  View user's profile Send private message Visit poster's website
  • Joined: 14 Oct 2008
  • Posts: 310
Reply with quote
Post Posted: Sun Jul 14, 2019 5:03 pm
Jaberwocky wrote

Also... from the old pokemon games I remember an effect where you had a black screen and could only see the map through a circle - is such an effect possibel with the SMS as well? And how would you do that?


That would be the GBA and DS generation games (gen 1 only darkened the palette and gen 2 made it completely black), which possibly had some hardware support for it. (I have only heard from some people who said GBA could do "Mode 7" effects like the SNES, but wanted to make a technical argument about the name, I wonder if GBA had other hardware visual features of the SNES.)

But yes, as said to do it on a console without built-in hardware functionality it would require tile and sprite trickery.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Sun Jul 14, 2019 5:21 pm
GBA's HDMA effect coupled with the windowing feature - basically you can define a (rectangular) window and make everything outside the window not be shown. With HDMA you'll then redefine the window left and right position at each scanline thus making a circle/ellipse.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Sun Jul 14, 2019 5:48 pm
Woah... Is there anything you guys don't know? :'D

I thank you all so much for all those answers :3 I might try such a tile sprite trickery - but all in all I want to do a simple game now. I'm done with experimenting :D
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Mon Jul 15, 2019 7:56 pm
Well... Here I go again...

I have not used the Bank mapping yet... but... If I understand it correctly... Pretending I have data stored in Bank2 and Bank3...

Bank2 seems to be automaticly mapped, because I used it already but never used the mapping function. So... If bank 2 is mapped, but in code I use an address from bank3 - I will read the data from bank 2 right? Like an offset... So to get the real data, I would have to map bank 3, correct? Kind of overriding the bank 2 content with the one from bank 3.

Urgs... I'm bad in explaining, but is that the basic concept?
  View user's profile Send private message
  • Site Admin
  • Joined: 19 Oct 1999
  • Posts: 12883
  • Location: London
Reply with quote
Post Posted: Tue Jul 16, 2019 6:02 am
Yes. The easiest way to manage it is to put all your data in the higher banks and code in the lower 32KB, and always select the bank before reading the data.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Tue Jul 16, 2019 7:54 am
I guess the lines "-Wl-b_BANK2=0x8000 -Wl-b_BANK3=0x8000" for the SDCC means, that the mapped bank will be at address 0x8000 - is that correct?

And the lower 32KB you reference are "--data-loc 0xC000"? >-<
So bascily everything I don't stuff into a bank?

So I wonder... Can I please the compiler to place certain values at specific addresses? Pretending I'm right with that the bank starts at 0x8000.

Could I tell the compiler to place char x at for example 0x8002? Or an offset like 0x2?
I ask because then I could use the address hard coded in my programm and use the bank maping to replace the value. I take, that this is already done by ordering the data in the banks in a certain way - like starting with palettes because they have a fixed size and so on.

I just wonder if I can relay on it or if I can enforce those things... Does that make sense? °-°
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Tue Jul 16, 2019 8:41 am
Jaberwocky wrote
I guess the lines "-Wl-b_BANK2=0x8000 -Wl-b_BANK3=0x8000" for the SDCC means, that the mapped bank will be at address 0x8000 - is that correct?


correct! (you're setting BANK2 and BANK3 address in ROM at value 0x8000)

Jaberwocky wrote
And the lower 32KB you reference are "--data-loc 0xC000"? >-<
So bascily everything I don't stuff into a bank?


no, that part tells the linker that we've got RAM at 0xC000

Jaberwocky wrote
So I wonder... Can I please the compiler to place certain values at specific addresses? Pretending I'm right with that the bank starts at 0x8000.

Could I tell the compiler to place char x at for example 0x8002? Or an offset like 0x2?
I ask because then I could use the address hard coded in my programm and use the bank maping to replace the value. I take, that this is already done by ordering the data in the banks in a certain way - like starting with palettes because they have a fixed size and so on.

I just wonder if I can relay on it or if I can enforce those things... Does that make sense? °-°


There's absolute placement, but you hardly need that. If you're using assets2banks you'll get an header file (or many of them if you don't use --singleheader) with all the pointers, sizes and bank placement you need.

edit: in detail, for each asset you'll find three definitions. This is for asset 'palette.bin' for instance:
extern const unsigned char   palette_bin[16];
#define            palette_bin_size 16
#define            palette_bin_bank 2


you can see that it's 16 bytes in size and it's been placed in bank 2. So to load that to BG palette, you need to

SMS_mapROMBank (palette_bin_bank);
SMS_loadBGPalette (palette_bin);
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Tue Jul 16, 2019 9:01 am
I see... Why bank 2 though? What is about bank 1 and bank 2?

I already noticed that a bank seems to be 16K in size, which multiplied by 2 (bank 0 and 1) will be 32K - exactly the size of the "lower 32KB" you mentioned.
I guess that is no coincidence xD

Another question about the timing again...
I want to do a thing like meassure the play time in minutes. I already learned, that I have no timer for this, so all I could do is count the frames, depending on the VBlank-Time correct?

But that means, that my timer must also distinguish between PAL and NTSC. But when my code is terrible slow, like my first map scrolling, then I will manipulate the timer as well...
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Tue Jul 16, 2019 10:15 am
you'll count the passing time in frames, then it's up to you to decide if you want to support both frame rates (50 and 60 frames per second) or just set your 'one second' equivalence to either one or the other (or 55 to be slightly off both).

Many games just don't care. Their timer either run faster on NTSC/60Hz or slower on PAL/50Hz. Note that your game anyway will run at the fps speed, so it'll run faster on NTSC and slower on PAL, unless you create an engine that supports both and adapt itself (not easy at all to do).
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Tue Jul 16, 2019 5:24 pm
But when I do a lot of slow operations in the VBlank time, this would effect the timer, counting the frames as well - right?

I played around with banks and now I'm confused...
I declared an array in a header file
extern const int miau[1024*5];

and put into the c file:
const int miau[1024*5] = {0};


When compiling I get the following output:
Info: 11500 bytes used/49152 total [23.40%] - 1260 bytes used in banks 0,1 [3.85%] - size of output ROM is 48 KB

Weeeeell... my miau array was obviously not stored in the bank oO Why? And how can I force it to be fully there?

Also I noticed, when I declare non-const values or functions, that they seem to be not placed in the bank either...
  View user's profile Send private message
  • Joined: 08 Sep 2018
  • Posts: 178
Reply with quote
Post Posted: Tue Jul 16, 2019 6:23 pm
Jaberwocky wrote
But when I do a lot of slow operations in the VBlank time, this would effect the timer, counting the frames as well - right?

I played around with banks and now I'm confused...
I declared an array in a header file
extern const int miau[1024*5];

and put into the c file:
const int miau[1024*5] = {0};


When compiling I get the following output:
Info: 11500 bytes used/49152 total [23.40%] - 1260 bytes used in banks 0,1 [3.85%] - size of output ROM is 48 KB

Weeeeell... my miau array was obviously not stored in the bank oO Why? And how can I force it to be fully there?

Also I noticed, when I declare non-const values or functions, that they seem to be not placed in the bank either...


Consts for starters are not stored in memory, the compiler should find any calls of a const's name in script and replace it with its value on compilation. consts are used specifically for saving memory(both rom and ram) and assigning easy to remember names to values you might reuse over and over again. If your value is not being placed, it may be improper or out of range. idk why you would want a variable array thats 5.13K in size anyways...

Further more some compilers remove consts and variables that are not called during the program (also a memory saving feature)
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Tue Jul 16, 2019 6:38 pm
IllusionOfMana wrote
idk why you would want a variable array thats 5.13K in size anyways...


Well... because I'm a beginner and try to understand mapping - so I needed to fill my bank with something :'D

Without my big array the cartridge is way smaller - so it does not get optimized away I assume.
  View user's profile Send private message
  • Joined: 08 Sep 2018
  • Posts: 178
Reply with quote
Post Posted: Tue Jul 16, 2019 7:12 pm
Things should not get optimized away as long as you use them. You can try calling your array and just writing it to vram or performing a simple operation on it if you want the compiler to include it else itll just optimize it and remove it from the final compilation.
Typically all unused functions and variables are removed during the optimization process.
As for banking and mapping...
IDK how SMS C works with banks but im guessing there are 4 slots that you can assign banks to, you dont want to touch slot 1 as it contains boot code and interrupt handler code and without that your program could crash. slot 4 will contain ram which you also dont want to touch except for reading from or writing to. You typically want to use slots 2 and 3 for your program and swap those out for new banks whenever you need to load in new data.
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 504
  • Location: Spain
Reply with quote
Post Posted: Wed Jul 17, 2019 6:53 am
In the usual flow using devKitSMS:
-Slot 0 and 1 are fixed on the first ROM 32kb and are used by code and any data you have not compiled to be a bank.
- Any const variable is put on ROM (so either in the first 32kb or in a bank). A non const variable is to be stored in RAM.
- Slot 2 is the one that can be banked, the only one using devkitSMS.
- You can compile your data (LUTS, graphics, music) to be on a bank. For that, you tell it has a number of bank, and the bank starts at memory location 0x8000 (the begining of Slot 2). You do that using Wl-b_BANKN=0x8000 where N is the bank number.
- You have to manually switch to the right bank when accessing the data, using SMS_mapROMBank(N)
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Wed Jul 17, 2019 7:52 am
I tried that kusfo - but I'm not sure if it worked correctly... Because my output became:

Quote
Info: 11500 bytes used/49152 total [23.40%] - 1260 bytes used in banks 0,1 [3.85%] - size of output ROM is 48 KB


Which I really don't understand.... I expected the first percentege value to be something around 7% and the second one to be high. Why?
When I compile the code without my large bank, then I get a ROM size of ~7% so with the bank I expected that the first value will be ~7% and the rest will be kinda... 18% or whatever. So... do I missunderstand the output of the program or did I set it up incorrectly?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Wed Jul 17, 2019 8:11 am
IllusionOfMana wrote
Jaberwocky wrote

const int miau[1024*5] = {0};


Consts for starters are not stored in memory, the compiler should find any calls of a const's name in script and replace it with its value on compilation. [...] Further more some compilers remove consts and variables that are not called during the program (also a memory saving feature)


SDCC doesn't remove any const variables you declare as they need to be there (they could be referenced from another module) and doesn't remove any unused (global) variable or functions - but it can remove part of your code if you put some code where it's unreachable.

In short if you put const data, such an array, in your main.c file, that will use your 'lower' ROM, that is bank 0 and bank 1. If you need your const data to be placed into an 'upper' bank, you should create a separate c file, compile that with some
sdcc -c -mz80 --constseg OTHER_DATA other_data.c

and link that likely as last bank
sdcc -o your_program.ihx -mz80 --no-std-crt0 --data-loc 0xC000 -Wl-b_BANK2=0x8000 -Wl-b_BANK3=0x8000 -Wl-b_OTHER_DATA=0x8000 crt0_sms.rel your_program.rel SMSlib.lib bank2.rel bank3.rel other_data.rel

of course you need to define some value to access that bank as in
#define other_data_bank 4
  View user's profile Send private message Visit poster's website
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Wed Jul 17, 2019 8:16 am
Jaberwocky wrote
I tried that kusfo - but I'm not sure if it worked correctly... Because my output became:

Quote
Info: 11500 bytes used/49152 total [23.40%] - 1260 bytes used in banks 0,1 [3.85%] - size of output ROM is 48 KB


Which I really don't understand.... I expected the first percentege value to be something around 7% and the second one to be high. Why?


It seems you're placing your 10KB array (an int requires two bytes so 5K ints require 10KB) in the upper bank. So you've got 1260 bytes used in the lower banks, 11.5KB used total. Sounds correct...

edit: oh wait, it's probably the order you're linking the .rel files. Can you share your command line?
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Wed Jul 17, 2019 8:54 am
I share my comandlines when I'm home again :3
I think I make something wrong...
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Wed Jul 17, 2019 9:03 am
the reason behind that is a long story about how IHX format isn't really suitable for bank switching (or better, how you seemingly can't create a proper IHX file with absolute ROM addresses)... but the point is that the order you specify your RELs in the linking phase DO counts.

The rules are:
- crt0_sms.rel needs to be first, always.
- all the code and data that goes into 'lower' banks is next (so for instance your own main.rel, SMSlib.lib, PSGlib.rel (if you use PSGlib) and any other REL you've compiled yourself that doesn't contain banked data.
- the banked data, strictly in ascending order (bank2.rel, bank3.rel ... bankN.rel)
- (and eventually) any other REL you want to add with custom banked data (or even code!)
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Wed Jul 17, 2019 12:32 pm
I think I'm doing it right... but maybe I just looked to often at it.

Soo here is my compile command for everything that I don't want in a bank. I'm using visual studio so I don't have a big batch file.
sdcc -c -mz80 --peep-file crt0/peep-rules.txt --vc -I "../../../devkitSMS-master/SMSlib/src" --opt-code-speed --max-allocs-per-node 100000 -o x64\Release\Scenes.rel Scene/Scenes.c


For things I want in bank I use:
sdcc -c -mz80 --peep-file crt0/peep-rules.txt --vc -I "../../../devkitSMS-master/SMSlib/src" --opt-code-speed --max-allocs-per-node 100000 --constseg BANK2 -o x64\Release\bank2.rel Bank/Bank2/bank2.c


My final linking is like that:
@echo off
if not exist "x64\Release\IHX\" mkdir "x64\Release\IHX\"

@echo Link
sdcc -o x64\Release\IHX\DarkForest.ihx --opt-code-speed --max-allocs-per-node 100000 -mz80 --data-loc 0xC000 --no-std-crt0 crt0/crt0_sms.rel -Wl-b_BANK2=0x8000 x64\Release\DarkForest.rel x64\Release\SceneControlling.rel x64\Release\Scenes.rel SMSlib.lib x64\Release\bank2.rel
if errorlevel 1 goto linkerror

@echo Finalize
ihx2sms.exe x64\Release\IHX\DarkForest.ihx I:\SMS\Projects\DarkForest\x64\Release\DarkForest.sms
if errorlevel 1 goto finalizerror
exit

:linkerror
@echo --------------
@echo Linking failed!
@echo --------------
exit

:finalizeerror
@echo --------------
@echo Finalize failed!
@echo --------------
exit
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Wed Jul 17, 2019 1:28 pm
seems good. You can check the generated .map file, you'll see where things end up. It's organized in sections.

For instance CODE is where your code and non banked constant data ends up:

Area                                    Addr        Size        Decimal Bytes (Attributes)
--------------------------------        ----        ----        ------- ----- ------------
_CODE                               00000200    00005B53 =       23379. bytes (REL,CON)

      Value  Global                              Global Defined In Module
      -----  --------------------------------   ------------------------
     00000200  _initialize_data_bank              main
     00000243  _LUT_sqrd_half                     main
     00000443  _LUT_log2_32                       main
[...]
     00001419  _the_line_handler                  main
     00001429  _background_queue_update_column    main
     00001447  _background_update_column          main
     000014A5  _initialize_background             main
     000014FB  _background_scroll                 main
[...]


and DATA is things in RAM:

Area                                    Addr        Size        Decimal Bytes (Attributes)
--------------------------------        ----        ----        ------- ----- ------------
_DATA                               0000C000    0000036F =         879. bytes (REL,CON)

      Value  Global                              Global Defined In Module
      -----  --------------------------------   ------------------------
     0000C000  _fake_rand_index                   main
     0000C001  _handling_player                   main
     0000C002  _desired_h_scroll                  main
     0000C006  _hit_hard                          main
     0000C008  _players                           main
     0000C038  _current_player                    main
     0000C050  _ks                                main
     0000C052  _kp                                main
     0000C054  _kr                                main
     0000C056  _h_scroll                          main
     0000C057  _new_h_scroll                      main
[...]


and BANK2 is what's in your BANK2 of course:
Area                                    Addr        Size        Decimal Bytes (Attributes)
--------------------------------        ----        ----        ------- ----- ------------
_BANK2                              00008000    00003F4D =       16205. bytes (REL,CON)

      Value  Global                              Global Defined In Module
      -----  --------------------------------   ------------------------
     00008000  _WIB_psgc                          bank2
     0000BAF0  _hud__tiles__psgcompr              bank2
     0000BF10  _SFX1_psg                          bank2
     0000BF2D  _sprite__palette__bin              bank2
     0000BF3D  _palette_bin                       bank2


so you can check if everything's OK.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Wed Jul 17, 2019 1:40 pm
sverx wrote
seems good. You can check the generated .map file, you'll see where things end up. It's organized in sections.
[...]
so you can check if everything's OK.


But why does the tool reply with:
Quote
Info: 11500 bytes used/49152 total [23.40%] - 1260 bytes used in banks 0,1 [3.85%] - size of output ROM is 48 KB

Then? :O

Will check my map file later anyways... but that message confuses me so much... Because from it it sounds like it was all stored in my lower 32KB memory...

Edit:
I checked the map file:
Area                                    Addr        Size        Decimal Bytes (Attributes)
--------------------------------        ----        ----        ------- ----- ------------
_BANK2                              00008000    00002800 =       10240. bytes (REL,CON)

      Value  Global                              Global Defined In Module
      -----  --------------------------------   ------------------------
     00008000  _miau                              bank2

Looks right to me :D But why is the message of the ihx tool so different then?
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 504
  • Location: Spain
Reply with quote
Post Posted: Wed Jul 17, 2019 1:57 pm
What's the problem with the IHX message?

It's saying that 11500 bytes are used in the ROM, and 1260 are in the first 32kb, so 10240 are in the other banks, so everything is fine.
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Wed Jul 17, 2019 2:31 pm
kusfo wrote
What's the problem with the IHX message?

That I really don't understand it D:

kusfo wrote
It's saying that 11500 bytes are used in the ROM, and 1260 are in the first 32kb, so 10240 are in the other banks, so everything is fine.


Seems like I understand it the exact wrong way... So the message tells me first the entire size of my rom, but the [3.85%] are actually my lower 32KB? Ahhh! Now it makes sense... I kinda feel stupid now ~o~

Thank you guys :D
  View user's profile Send private message
  • Joined: 29 Mar 2012
  • Posts: 504
  • Location: Spain
Reply with quote
Post Posted: Wed Jul 17, 2019 2:32 pm
Yes, the Slots 0 and 1 refer to the first 32kb (they're not bankable)
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Wed Jul 17, 2019 2:39 pm
I see your point now! Sorry, yes, it's giving three info on the same line:

1) 11500 bytes used/49152 total [23.40%]
2) 1260 bytes used in banks 0,1 [3.85%]
3) size of output ROM is 48 KB

I should probably make that more clear? How?

Something like

Output ROM is 48 KB (11500 bytes used/49152 total [23.40%], 1260 bytes used in banks 0,1 [3.85%])


would be better?
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Wed Jul 17, 2019 5:20 pm
I think this would be a better output :D

But now that I understand the 'old' version, I have less problems with it now xD

Silly question but... why can't I store program code like functions in a bank? Like a const value, it can't be modified and will only be read accessed :O
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Wed Jul 17, 2019 5:30 pm
Jaberwocky wrote
why can't I store program code like functions in a bank?


you actually can - but you need to map that ROM bank before calling any code that's in there AND you won't be able to access any data that's in banks as that would require you to map some other ROM bank, and you'll end up mapping out your code while it's running: sure crash.

So the common approach is to keep your code in the lower 32 KB only.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Wed Jul 17, 2019 5:50 pm
But I don't get it to work :0
I tried the following:

bank2.h
extern const int wau[1024*5];

bank2.c
const int wau[1024*5] ={0};

Creates:
Info: 11519 bytes used/49152 total [23.44%] - 1279 bytes used in banks 0,1 [3.90%] - size of output ROM is 48 KB
_BANK2                              00008000    00002800 =       10240. bytes (REL,CON)

      Value  Global                              Global Defined In Module
      -----  --------------------------------   ------------------------
     00008000  _wau                               bank2


--- But if I do:
bank2.h

extern const int wau[1024*5];
int schwimmflugel();

bank2.c

const int wau[1024*5] ={0};
int schwimmflugel()
{
   return 0;
}

Creates:
Info: 11523 bytes used/16384 total [70.33%] - size of output ROM is 16 KB
Area                                    Addr        Size        Decimal Bytes (Attributes)
--------------------------------        ----        ----        ------- ----- ------------
_CODE                               00000200    00002AE9 =       10985. bytes (REL,CON)

      Value  Global                              Global Defined In Module
      -----  --------------------------------   ------------------------
     00000200  _main                              DarkForest
     00000215  _switchToScene                     Scenes
     00000266  _scenes                            Scenes
     0000026B  _titleScreenScene_setup            TitleScreenScene
     00000276  _titleScreenScene_update           TitleScreenScene
     0000027E  _schwimmflugel                     bank2
     00000282  _wau                               bank2


Now it is not stored in the bank anymore, not even my "wau" array...
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Thu Jul 18, 2019 7:31 am
if you put code in bank2, when compiling you should use

--codeseg BANK2


instead of

--constseg BANK2


as you need to place CODE in BANK2.

Never tried using them together, TBH.
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Thu Jul 18, 2019 7:48 am
Well that makes sense :O
But... why didn't ended my array in the bank? :x It was still const...

I planed on placing the images, but also the code for a titlescreen in a bank, because it will only used once in the game.

The global variables used by that state, I wanted to place in the lower 32KB with an union to not waste memory.
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Thu Jul 18, 2019 10:09 am
Frankly I think you don't need to. Title screen code will probably be mainly calls to SMSlib functions so it shouldn't require too much space, and even the few variables you'll need there won't likely eat too much.

Of course unless you've done your math and you already know you do really need this kind of savings.

And global variables are in RAM, so they won't use the lower 32 KB (that's ROM), they'll go into the console's 8 KB of RAM, which is also holding the program stack (less than 100 bytes usually are sufficient).
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Thu Jul 18, 2019 11:16 am
Stupid question :O

But when I write
char x = 12;


Does that not effect the size of my ROM as well? The 12 as a number or the instruction how to generate the number must be stored somewhere as well - right? :o

Also... If I use an union I would save some RAM right? >_<
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Thu Jul 18, 2019 12:06 pm
if you're declaring initialized global variables such as

unsigned char x = 12;
unsigned int count = 1000;


you're using both space in RAM (the variable) and in ROM as the value will end up in the INITIALIZER section, where values needed for start up are held and copied by the crt0 module before your main() starts.

So you should for instance avoid any zero initialization such as

unsigned char x = 0;
unsigned int count = 0;
bool flag = false;


as that would be surely a waste (RAM is initialized to zero by the crt0 module at start-up, before global variables initialization)

If you're initializing a local variable instead, your code will contain your value as an 'immediate' so, in that sense, it will take ROM again (your code will be 'bigger')

void some_func (void) {
unsigned char local_x = 12
[...]


will likely become some ASM like this (with hl pointing some location on stack)

ld a,#12
ld (hl),a
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Thu Jul 18, 2019 1:45 pm
That was interessting ^o^
Thank you a lot x3

Seems like I will not place functions in the banks xD
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Thu Jul 18, 2019 6:11 pm
sverx wrote
if you put code in bank2, when compiling you should use

--codeseg BANK2


instead of

--constseg BANK2


as you need to place CODE in BANK2.

Never tried using them together, TBH.


I tried it now and it is actually working :O Here is the part of the map file:
_BANK2                              00008000    00002804 =       10244. bytes (REL,CON)

      Value  Global                              Global Defined In Module
      -----  --------------------------------   ------------------------
     00008000  _schwimmflugel                     bank2
     00008004  _wau                               bank2


Thank you a lot x3 But defining a global editable variable was of no use correct?
  View user's profile Send private message
  • Joined: 05 Sep 2013
  • Posts: 2496
Reply with quote
Post Posted: Fri Jul 19, 2019 2:13 pm
Jaberwocky wrote
defining a global editable variable was of no use correct?


I don't think I understand your question :|
  View user's profile Send private message Visit poster's website
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Sun Jul 21, 2019 2:57 pm
sverx wrote
I don't think I understand your question :|

I'm not suprised - I had to remember myself what I meant with that >_>

If I define a global variabel in the bank, so without the const specifier, then it will land right into RAM, correctly?

Like when I say
extern int c;

and in the bank I do:
int c = 123;


That variabel c will not be effected by the bank mapping, correct? So if I would mal a different bank, variabel c would still be uneffected - right?

Also - are there ways to earse the current map I have disapled, to set it back to all zero? Like when you start up the SMS.

I would do a loop with SMS_setTile - but that feels rather slow for that purpose.

Edit:
Also I wondered right now...
When I call 'SMS_setTile' like.... 8 times in a row, wouldn't it be faster, to load the tiledata first into an array and then call 'SMS_loadTileMap'? 8 is just a value I picked at random to indicate I want to change more then one tile in a row.
  View user's profile Send private message
  • Joined: 24 Jun 2019
  • Posts: 45
Reply with quote
Post Posted: Thu Jul 25, 2019 8:18 am
Not sure if I should had edit my post for those questions... But...

To my questions from above:
I hope I can explain what I mean... I know my questions can be difficult to understand >~<

I read the following sentence about the VDP:
Quote
The VDP is programmed by sending a two-byte sequence to the control port


I'm pretty sure this 'task' is hidden behind the SMSDevKit - correct? But is this the reason why accessing the VRAM is a slow operation? Because it is running over the control port?

If that is the case, it sounds to me, that I can only write/read a limited amount of values in one command.

From that I assumed, that there might be no difference in using 'SMS_setTile' over using a small local buffer and 'SMS_loadTileMap'. Is that correct?

I'm really not used to old hardware and without some kind of time measurement it is hard to find that stuff out...
  View user's profile Send private message
Reply to topic Goto page Previous  1, 2, 3  Next



Back to the top of this page

Back to SMS Power!