Creating a MSX ROM in C with SDCC

Page 1/2
| 2

By albs_br

Champion (499)

albs_br's picture

24-08-2021, 05:16

Hi guys,
what is a quick and dirty way to create a ROM file (32Kb, start at 0x4000) for a C program using SDCC ?

I was using 8bitworkshop IDE, but it breaks after a certain complexity level is hit.

Thanks for any help.

Login or register to post comments

By ToriHino

Paladin (927)

ToriHino's picture

24-08-2021, 06:34

You can use the MSX Template Pack to get a quick start.

By geijoenr

Champion (392)

geijoenr's picture

24-08-2021, 07:34

If you are using Linux or Mac you can also take a look at

By MattyT

Rookie (26)

MattyT's picture

02-10-2021, 04:18

I have followed the same path of starting a project in the 8bit workshop IDE using msxbios, and then running out of space, and then I have used the MSX Template Pack (MSX.ROM.Application in particular) and transferred my code across to it, and can make 16K ROMs that work in OpenMSX and on my real MSX1 Panasonic CF-2700.
But I have now again run out of space and have been trying to make a 32K ROM. I have made them with both with the msxromcrt0.rel of the MSX,ROM.Application and have also substituted in crt0_MSX32kROM4000 (from and hex2bin duly makes 32k ROMs, but then they do not work in openMSX or on my real machine. (They go to the MSX BASIC version 1.0 screen, instead of my cool looking Mode 2 intro screen for my game).
My game is called Blastoid. Hopefuily it will be an entry in MSXDEV22.
The make file runs these:

sdcc --code-loc 0x0000403E --data-loc 0xC000 -mz80 --no-std-crt0 --opt-code-size --disable-warning 196 ".\RELEASE\\objs\msxromcrt0.rel" ".\RELEASE\\objs\msxbios.rel" ".\RELEASE\\objs\Blastoid.rel" -I"." -o ".\RELEASE\\objs\BLASTOID.IHX"

hex2bin -e ROM -l 8000 ".\RELEASE\\objs\BLASTOID.IHX"

In the Application_Settings.txt file:
; crt0 features
; ROM settings
FILESTART 0x4000 ; Typically, 0x4000 for 32kb ROM or 0x8000 for 16kb ROM

What am I missing or not understanding about 32K ROMs? Anything I should try?

By DamnedAngel

Champion (286)

DamnedAngel's picture

02-10-2021, 12:44

Hi MattyT,

I'm the author of the MSX Template Pack. I just tested a 32k build here and it worked fine with me.

Will it be okay with you to share a snapshot of your project with me so I can try to diagnose what's happening in your case?


By MattyT

Rookie (26)

MattyT's picture

02-10-2021, 21:54

Thanks. That will be great.
I've zipped it up here.
There is one source file, levels.h with 2 versions of it. One has some static char arrays commented out to bring it under the 16K boundary. The other makes it go over. levels.h presently makes it go over. So make\make RELEASES builds it.
I'll delete it once you've got it from dropbox, so let me know when you have.

By DamnedAngel

Champion (286)

DamnedAngel's picture

02-10-2021, 23:16

MattyT wrote:

I'll delete it once you've got it from dropbox, so let me know when you have.

You may delete it.
I'll try to take a look at it tomorrow.

By DamnedAngel

Champion (286)

DamnedAngel's picture

03-10-2021, 00:01

Hi again MattyT,

I just made a Quick test and the game seems to work fine with both levels.h files, under DEBUG and under RELEASE modes. I tested under several MSX configurations in OpenMSX and they all worked. There is a good chance of me doing something wrong though... Big smile

Do you want to contact me directly? You may find my email on the cover page of the MSX Template Pack Manual. From there we can find a more efficient way to communicate (WhatsApp/Telegram).

By MattyT

Rookie (26)

MattyT's picture

03-10-2021, 18:26

Problem solved - I was using an older version of hex2bin. I needed v2.5

By CodeIndigo

Supporter (16)

CodeIndigo's picture

08-10-2021, 15:34

So I'm running into an interesting issue here with SDCC ROM creation using the Fr3el project methods (which work flawlessly otherwise). I think I may have an understanding of it but I want to check that I get it and ask for a workaround.

For my testing and experimentation I'm using an 8k ROM that starts at 0x4000. In theory that means that RAM from 0x6000 straight through to the end (minus the stack) is available for use. Everything I've done bears that out, and I can read and write to those without a problem.

Where things get interesting is if I want to write to addresses BELOW my ROM. Let's say I want to put 64 bytes of data at 0x1000, which to my understanding is outside of the trampolines to the BIOS code. If I try writing to that address, it doesn't stick. Between yesterday and today I've determined that my understanding of how the BIOS works is flawed, but I just want to make sure.

What I think is happening is that the BIOS ROM is, just like my own ROM, overlaid on top of 0x0000-0x3FFF. So without paging out the BIOS, that low RAM is inaccessible. Am I right so far?

Let's say then that I *do* want to have access to that low RAM through straight assembly. I get that it might not be advisable due to the fact that I'm going to be using interrupts, but is it possible? And if it is, what assembly would I use to do it (with the appropriate DI and EI commands around it, of course)?

By aoineko

Paragon (1144)

aoineko's picture

08-10-2021, 21:02

The Z80 can see only 64K of address.
On MSX, this address space is split in 4 pages :

  • Page 0: 0x0000 - 0x3FFF
  • Page 1: 0x4000 - 0x7FFF
  • Page 2: 0x8000 - 0xBFFF
  • Page 3: 0xC000 - 0xFFFF

Each page can be pointed to any slot or sub-slot that contain ROM or RAM (mainly).
If the MSX detect a ROM at 0x4000 it will switch the page 1 to the cartridge slot/sub-slot and start the program inside the cartridge.
If you want to access the RAM between 0x6000 and 0x7FFF you have no other choice that switch the page 1 to a slot/subslot that contain RAM. It's really tricky because doing that you loose access to your program in ROM.

If you can, the easiest way is just to use a 16K ROM in page 1 and to use 32K of RAM in pages 2 and 3 so you don't have to bother with page switch.

An other solution is to have a small code at the beginning of your program that copy your 8K ROM somewhere in RAM then to switch page 1 to RAM. Be careful in this case that all your jump address have to match the final position of your program.

For example:
- Compile your C program to start at 0x8000
- Create a ROM starting in 0x4000 that include your C compiled as data and have a code to copy the C program to 0x8000 and jump to 0x8000 (or to your _main)
- In your main() start to switch the page 1 back to RAM (to the same slot/subslot than the one in page 2 or 3)

Et voila, you can access RAM from 0x4000 to 0x7FFF and from 0xA000 to 0xFFFF (minus the BIOS working area).

Page 1/2
| 2