Make a 48kb game using SDCC, great but how ?

Page 1/2
| 2

Par JMeric

Resident (51)

Portrait de JMeric

04-12-2021, 18:45

Hi MSX Coders and lovers Wink

I've seen lot of different sourcecodes (in asm) using different cartridge headers.
As I'm still in learning process during my about 1 year old in this MSX World, I would like to know how create a 48kb game by using slot management, how to organize my code/datas to make my games working on a small msx config (8kb mem). I'm totally lost Sad
48kb or megarom, I don't know even if I've red that the megarom management is easier. But for a 48kb game is it really useful ??

At the moment, my games (DoTheSame & WhereIsIt?) are 32kb full and I would love to add some music(s) and change some things Wink

Hope you could help me, TIA

See you

ps: I'm looking at MSX Inside on Youtube. It could be instructive Wink

!login ou Inscrivez-vous pour poster

Par aoineko

Champion (285)

Portrait de aoineko

04-12-2021, 19:21

I have two headers (crt0) for 48K catridges in my library (https://github.com/aoineko-fr/CMSX/blob/master/cmsx/src/crt0).
Both set the catridges in pages 0 to 2 (address 0x0000 to 0xBFFFF) and start on page 1 (the ROM header is at address 0x4000).
The difference is that for the first one (crt0_rom48.asm), the page 0 remains connected to the Main-ROM slot to keep an access to the Bios, while the second one (crt0_rom48_isr.asm) is made to keep my cartridge slot always on page 0. I created an interrupt handler optimized for game to replace the one in the Main-ROM and this way I don't need to change the slots in code at all (which simplifies the code management a lot).

For the data, it is more complicated. To take advantage of the 48K, you have to be able to put data in the first page, before the beginning of the code (which starts on page 1); which is unfortunately not easy to do with SDCC. Normally there is a direct compile option to place at a given address the read-only data section where all the constant data is located. But the option does not work in z80. I told the SDCC developers but they didn't offer me a solution.
So I use the __at(0x1234) to place my different data in page 0. I made some tools that calculate the addresses so that the data concatenate each other.

This is how my tennis game Final Smash works.

Par aoineko

Champion (285)

Portrait de aoineko

04-12-2021, 19:56

On the other hand, my solution with a 48K cartridge always in page 0 works well only because my library is 100% autonomous from the Bios. If you access the Bios functions this solution will not work.
You still can use the first solution and switch the page 0 between the Main-ROM and your cartridge when reading the data.

The last solution is to use a ROM mapper.
But here I'll let others talk about it because I only know the theory.

Par santiontanon

Paragon (1571)

Portrait de santiontanon

04-12-2021, 20:11

To me, the easiest solution to use page 0 is to use the "CALSLT" BIOS function. With this function you can call code that is located in page 0. CALSLT by itself handles swapping the BIOS out to put your cartridge there, call and run the function, and then put the BIOS back when your function returns. With this functionality, you can have a simple function in page 0 that just copies/decompresses whatever data you want from page 0 to RAM, and then returns. In that way, you forget about the nightmare of swapping pages yourself manually, and it's super easy. The only downside is that while the function in page 0 is being executed, interrupts are disabled, but that's a small price to pay for simplicity Smile

That's how I've been doing it in my last few games.

Par JMeric

Resident (51)

Portrait de JMeric

04-12-2021, 21:08

Thanks my friends Smile

@santiontanon > do you code using SDCC ?? (Menace from Triton is full asm. The management is, maybe, easier using ASM than C?)

thx

Par santiontanon

Paragon (1571)

Portrait de santiontanon

05-12-2021, 02:52

Ah, apologies, I use pure assembler, sorry I did not clarify! I don't know much about SDCC, so, I am not sure if the CALSLT BIOS routine can be used in conjunction with SDCC. So, maybe what I said does not make sense in the context of SDCC, not sure!

Par gdx

Enlighted (5035)

Portrait de gdx

05-12-2021, 08:27

Either disable the interrupts to access the ROM on page 0, or you put a little routine at the address 00038h like the one below in the ROM:

	push	af
	in	(099h),a
	pop	af
	ei
	ret

Obviously, do not call this routine while processing an interrupt and you can not call BIOS routine when your ROM is selected at page 0.

To select the ROM slot and replace the Main-ROM at page 0, see the program at the following link.

https://www.msx.org/wiki/Develop_a_program_in_cartridge_ROM#...

These two routines must be called at an address above 3FFFh.

By using these asm routines in SDCC I think you won't have a big problem creating your ROM.

Par aoineko

Champion (285)

Portrait de aoineko

05-12-2021, 18:23

santiontanon wrote:

Ah, apologies, I use pure assembler, sorry I did not clarify! I don't know much about SDCC, so, I am not sure if the CALSLT BIOS routine can be used in conjunction with SDCC. So, maybe what I said does not make sense in the context of SDCC, not sure!

This makes total sense. Whether in C or in assembler, at some point, he will need to to switch page 0 between the BIOS and the 48K cartridge.
My 1st solution is to switch only once in the starting code and leave page 0 always on the cartridge (with an ISR at the right place).
My 2nd solution is what you suggest: Switch the page manually as needed by disabling the interrupts.
He can do it himself in code, or use the BIOS functions which will handle pages switching automatically for him.
In C, you can use the BIOS functions, you just have to make a "wrapper" in C to put the parameters in the right registers before calling the BIOS routine.
For example, in my game library, these interslot routine wrappers are available here: https://github.com/aoineko-fr/CMSX/blob/master/cmsx/src/bios.c
- RDSLT : Bios_InterSlotRead()
- WRSLT : Bios_InterSlotWrite()
- CALSLT : Bios_InterSlotCall()

Par Grauw

Ascended (10334)

Portrait de Grauw

05-12-2021, 21:25

I really like santiontanon’s approach.

santiontanon wrote:

To me, the easiest solution to use page 0 is to use the "CALSLT" BIOS function. With this function you can call code that is located in page 0. CALSLT by itself handles swapping the BIOS out to put your cartridge there, call and run the function, and then put the BIOS back when your function returns.

The only assembly needed is a tiny routine consisting of LDIR and RET at the start of page 0, and then the remainder can be data that can be copied to RAM easily by just calling CALSLT with the slot and LDIR parameters. Ok you probably also need a wrapper for that call, but that should be standard C-ASM interface code. Certainly much easier and error-proof than coding up custom slot routines and all that.

Par JMeric

Resident (51)

Portrait de JMeric

05-12-2021, 21:25

Thanks for your advices

I'm in 'try to understand mode' and I have to read and test more and more Smile

See you

Par aoineko

Champion (285)

Portrait de aoineko

05-12-2021, 22:56

Grauw wrote:

I really like santiontanon’s approach.

It is not too difficult to place data anywhere in C, but it is much more complicated to do it with code.
That's why I recommend to use the page 0 only for data and to access it by the interslot BIOS reading function.

Page 1/2
| 2