Discussion about software development for the old-school Gameboys, ranging from the "Gray brick" to Gameboy Color
(Launched in 2008)
You are not logged in.
Hello there,
I'm actually finding how to bankswitch to 0x4000 with GBDK.
I actually know there is a known cmd : SWITCH_ROM_MBC1(1);
but I can't figure it out how to fully switch to 0x4000 to execute something else like a 16kb game.
Thanks by advance
Regards
Offline
My advice is to not use GBDK for projects larger than 32k.
Also, don't use MBC1. It just adds extra complexity for no reason, use MBC3 or MBC5.
Offline
ISSOtm wrote:
My advice is to not use GBDK for projects larger than 32k.
Also, don't use MBC1. It just adds extra complexity for no reason, use MBC3 or MBC5.
Why? GBDK has lots of issues but I never had any problems with bank switching or the MBC1.
JS7777 wrote:
Hello there,
I'm actually finding how to bankswitch to 0x4000 with GBDK.
I actually know there is a known cmd : SWITCH_ROM_MBC1(1);
but I can't figure it out how to fully switch to 0x4000 to execute something else like a 16kb game.
Thanks by advance
Regards
That's not enough information to really help you. Maybe you should first read through the documents I provided in post #7 of this thread: http://gbdev.gg8.se/forums/viewtopic.php?id=453
Offline
Hello, thanks for your response.
Well actually i'm using a 32ko cartridge ROM Only.
I already found those links you gave me Jonas (That's my name too actually )
Let me explain to A to Z.
I'm actually finding a logic signal like 0v - 5v from my 32kb flash gameboy cartridge(AM29F010) when a specific button is pressed so I could control something external like an led or anything with the gameboy buttons, that signal would be wired to a microcontroller. The best way to do it is with banks.
in a ROM Only 32kb cartridge there is 2 banks, bank 1 and 2 : 0x0000 and 0x4000
Switching to 0x4000 would change the state of the A14 pin but that doesn't work in gbdk with the SWITCH_ROM_MBC1 cmd, It looks like that that command is only used to retreive data from those banks and not to fully switch to it.
Reiner Zeigler made a tool called ReadPlus and with it there is a .gb file, it's a menu that Reiner Zeigler made for some 16kb tools, I've checked the menu with the integreated tool with an hex editor and that 16kb rom is located in 0x4000 so I've tried it on a 32kb cartridge and when starting one of the tool A14 goes high, that's what I want.
But the menu was coded in assembly (RGBDS) and not with GBDK.
(That's the menu at startup)
(On this picture you can actually see that the tool called GB-BASIC is at 0x4000 and when launching it A14 goes high)
Thanks by advance
Regards
Last edited by JS7777 (2018-07-26 23:16:57)
Offline
In summary: You want to use the bank switching instruction for something it isn't indended for. For such purposes, you should know exactly what you're doing which unfortunately is never the case with GBDK. The best option would in fact be to switch to assembly. If you don't want to do that, here are some suggestions:
First thing to know is that switching a bank with an MBC1 means nothing else but to write the desired bank number to memory address $2000. Therefore, in theory
SWITCH_ROM_MBC1(7);
should translate to
ld a, 7 ld ($2000), a
in assembly.
To trace the problem, you could inspect the assembly output of GBDK and see whether GBDK translates your code that way. If it doesn't, that is probably the cause for the unexpected behaviour.
A solution to solve this in C could be to write to memory address $2000 manually (use a pointer to that address). This may or may not work with GBDK, but it's at least worth a try.
Offline
Thanks for your response
So that simple code is correct ? :
#include <gb/gb.h> #include <stdio.h> void main() { puts("test"); waitpad(J_START); // other keys are J_A, J_UP, J_SELECT, etc. SWITCH_ROM_MBC1(7); }
Offline
A solution to solve this in C could be to write to memory address $2000 manually (use a pointer to that address). This may or may not work with GBDK, but it's at least worth a try.
How could I do that ? I've haven't find any info on internet about pointers.
Thanks by advance
Offline
JS7777 wrote:
So that simple code is correct ? :
Code:
#include <gb/gb.h> #include <stdio.h> void main() { puts("test"); waitpad(J_START); // other keys are J_A, J_UP, J_SELECT, etc. SWITCH_ROM_MBC1(7); }
Yes, I think so. But it could make sense to add an infinite loop at the very end. Because Game Boy games are not expected to ever reach the end of the program, I don't know what happens when they do.
JS7777 wrote:
A solution to solve this in C could be to write to memory address $2000 manually (use a pointer to that address). This may or may not work with GBDK, but it's at least worth a try.
How could I do that ? I've haven't find any info on internet about pointers.
Thanks by advance
I don't remember the exact syntax but something like this should work (for ROM bank 7):
*(UINT8 *)0x2000U = 0x07;
Offline
Great thanks and what would be the code to compile it ?
That's the current code :
..\bin\lcc -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -c -o banks.o banks.c ..\bin\lcc -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -Wf-bo1 -Wf-ba1 -c -o bank_1.o bank_1.c ..\bin\lcc -Wa-l -Wl-m -Wl-j -DUSE_SFR_FOR_REG -Wl-yt0 -Wl-yo4 -Wl-ya1 -o banks.gb banks.o bank_1.o pause
Offline
Well, with what you want to do, you're in uncharted territory... But anyway, I'd try it with this:
..\bin\lcc -Wa-l -Wl-m -Wl-j -c -o banks.o banks.c ..\bin\lcc -Wa-l -Wl-m -Wl-j -Wf-bo1 -c -o bank_1.o bank_1.c ..\bin\lcc -Wa-l -Wl-m -Wl-j -Wl-yt0x01 -Wl-yo4 -o banks.gb banks.o bank_1.o pause
Here's why:
- I removed the -DUSE_SFR_FOR_REG statement simply because I don't know what it's good for.
- I removed the -Wf-ba1 statement in line 2 because that's for RAM bank switching and you don't want to switch RAM banks.
- I changed -Wl-yt0 in line 3 to -Wl-yt0x01 because you want to use an MBC1. -Wl-yt0 is for a cartridge with no MBC.
- I removed the -Wl-ya1 statement in line 3 because that's once more for RAM bank switching.
Don't put any relevant code in bank_1.c since that goes to the ROM section you are going to switch out.
Offline
Thanks, i get an error :
bank_1.c(1):error *** parse error at end of of input
I didn't put anything in bank_1.c
Here is the folder if you want to check an eye : https://www.dropbox.com/s/n4m2vfg6vkb6njl/bank.zip?dl=0
Thanks alot for your help
Offline
You're going to wrong way. A14 is one of the address pins; what the program does is simply switch to a bank, which changes the address read from. This modifies A14's state, but the MBC doesn't interpret it any differently.
You should go the ASM route anyways, especially if you want to use a custom mapper. GBDK is just a source of headaches.
Offline
You should go the ASM route anyways, especially if you want to use a custom mapper. GBDK is just a source of headaches.
I know nothing about asm and I didn't find any documentations to start with.
Well here what happens :
In BGB debugger rom=1 becomes rom=3 when pressing start but no switching to an adress.
Oh, I had to add a loop at the end of bank.c otherwise it wouldn't work
#include <gb/gb.h> #include <stdio.h> void main() { puts("test"); waitpad(J_START); // other keys are J_A, J_UP, J_SELECT, etc. SWITCH_ROM_MBC1(7); while(1) { } }
Last edited by JS7777 (2018-07-28 14:15:15)
Offline
JS7777 wrote:
You should go the ASM route anyways, especially if you want to use a custom mapper. GBDK is just a source of headaches.
I know nothing about asm and I didn't find any documentations to start with.
In my opinion it's a bit unfair to call GBDK a headache. It has its issues and the code it generates runs slowly, but for a beginner it's much more accessible than a cryptic programming language that will take you a day or so just to put "Hello World" on the screen... In the case at hand, however, assembly would be the better solution beacuse you always know what exactly it does with the hardware. It might turn out that what you want to do cannot be achieved with GBDK.
JS7777 wrote:
Well here what happens :
In BGB debugger rom=1 becomes rom=3 when pressing start but no switching to an adress.
Maybe I got you wrong but isn't that what you wanted? You switched to another bank which means that the content of that bank can now be accessed in the address space from $4000 to $8000.
It's probably not bank 7 (as in your code) because you compiled a ROM with only 4 banks.
Offline
Not the content of that bank but lunching the content of that bank from $4000 to $8000. If I put a 16kb game between those adresses nothing happens. (even changing the bank number)
Last edited by JS7777 (2018-07-28 16:12:36)
Offline
JS7777 wrote:
Not the content of that bank but lunching the content of that bank from $4000 to $8000. If I put a 16kb game between those adresses nothing happens. (even changing the bank number)
I'm not sure whether we're talking about the same thing...
Generally bank switching works as follows: In your ROM file you have the banks lined up in a row (0-1-2-3-4-5- etc.). When you start up the Game Boy you have banks 0 and 1 accessible. Bank 0 will be in the address space from $0000 to $3FFF and bank 1 will be in the address space from $4000 to $7FFF. The bank switching instruction will exchange what you can access in the address space from $4000 to $7FFF. For example,
SWITCH_ROM_MBC1(3);
will make the content of bank 3 appear in the address space from $4000 to $7FFF while the content of bank 1 will be switched out and cannot be accessed anymore.
Bank 0 is not switchable, so what is in the first 16 kb of the ROM file will always be accessible in the address space from $0000 to $3FFF.
Offline
You shouldn't trust which bank is loaded by default. Also, you should use SWITCH_ROM_MBC3 if that exists.
And, GBDK doesn't make it easy to understand what banking actually is.
Offline
Oh, I understand, thanks.
But how could I launch a game from 0x4000 to 0x8000 like the menu from Reiner Zeigler ?
Thanks
Last edited by JS7777 (2018-07-29 15:25:05)
Offline
Well, I don't know what exactly this menu does or what it's good for, but I assume the following: You have the menu located in ROM bank 0 and then the five programs to select in ROM banks 1 to 5. If you select one of the programs, this will be started. Correct?
If that is correct, the first restriction is that neither the code for the menu nor the code of any of the programs must be larger than 16 kb. If the user selects a program, you switch in the respective bank with the SWITCH_ROM_MBC1() instruction and then call the function that starts the program. That's all.
Offline
Correct but the tools aren't programmed in the rom, they are programmed apart like a game. A 16KB .gb file. To add them you just need to paste it in 4000 to 8000 or 8000 to etc..
I got an issue, it doesn't seems to work. A14 is always high, then goes low when pressing START. It should be the other way round.
So I tried that rom from reinerzeigler and A14 is low at startup then it goes high when I start one of his tools, that's correct.
Last edited by JS7777 (2018-07-29 16:21:43)
Offline
OK, I understand it but I'm afraid to say I don't know how you could do that with GBDK.
Anyway, one more remark: Since your real goal is controlling external devices, why don't you use the link cable (which is made for that purpose)?
Offline
Anyway, one more remark: Since your real goal is controlling external devices, why don't you use the link cable (which is made for that purpose)?
Oh, didn't think about that. How can I control it ?
Last edited by JS7777 (2018-07-29 16:54:27)
Offline
To get started, here are articles in the Wiki on this website:
http://gbdev.gg8.se/wiki/articles/Seria … )_Tutorial
gbdev.gg8.se/wiki/articles/Serial_Data_ … ink_Cable)
Last edited by Jonas (2018-07-30 07:42:47)
Offline
Thanks.
Well, I can control A14 state but on a MBC1 flash cartridge, not a ROM Only flash cartridge, maybe because of the SWITCH_ROM_MBC1 command wouldn't work on a ROM only cartridge. What about your idea with pointers, what do you think ?
Thanks alot for your help.
Offline