Gameboy Development Forum

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.

Ads

#1 2017-08-08 07:51:44

pikpol
Member
Registered: 2017-08-06
Posts: 12

Bank Switching GBDK Nothing Works!

Hello,

I recently started development for GB/GBC.
Learned a lot so far. Now I want to create a map system for maps bigger than 32x32.
Unfortunately, I can't get bank switching working. Ofcourse this is needed to achieve a lot of things.
Yes, I looked at all those threads on here and all the answers. Tried everything, nothing works...
So I use GBDK for the development and I use C. Also tried to mix C with asm for the map data, but even that didn't work...
I am wondering if I miss something here or if there is something else happening.
The files can be downloaded via these links:
https://mega.nz/#!5lhwRLJC!svtYqIpQx--e … zUnH-nR-FI
https://mega.nz/#!YhRXCQ5J!pEMGSTgsaVs2 … kYgVH06aIM
https://mega.nz/#!UtIgAJIA!e8tkNruVaL6Z … _ZoA6GkcxM

The compiler also throws an error; Multiple definitions of _TestMap/_TestBG/BackgroundPalette/Set_Bkg
Which are all in bank2.c

Help would be greatly appreciated!

Thank you,

Pikpol

Offline

 

#2 2017-08-13 00:27:35

Tauwasser
Member
Registered: 2010-10-23
Posts: 83

Re: Bank Switching GBDK Nothing Works!

Hi, sorry for coming back to you only after a week. Anyway, I think the problem with the double definition is in bank.h, which you haven't uploaded.

I think you already took a look at the older thread, but just in case link to old thread.
I think you should try to get that example working first before continuing.

pikpol's Email wrote:

Though, the weird thing is, it worked when all my code was in 1 file and so in 1 bank.
But it started failing on me when I added a third bank.

In general, it's weird that you include all of your c files in main.c. While not unheard of, this might present its own set of problems. lcc writes the RAM and ROM bank the code is supposed to use inside the object file, so it will have trouble when you compile code that is meant for multiple bank all in the same c file.

The traditional way is to only include header files or character data that is used one time only. Compile each c file into an object file and link them all together in a final step, kind of like in this thread.

Offline

 

#3 2017-08-14 14:52:17

pikpol
Member
Registered: 2017-08-06
Posts: 12

Re: Bank Switching GBDK Nothing Works!

Tauwasser wrote:

Hi, sorry for coming back to you only after a week. Anyway, I think the problem with the double definition is in bank.h, which you haven't uploaded.

I think you already took a look at the older thread, but just in case link to old thread.
I think you should try to get that example working first before continuing.

pikpol's Email wrote:

Though, the weird thing is, it worked when all my code was in 1 file and so in 1 bank.
But it started failing on me when I added a third bank.

In general, it's weird that you include all of your c files in main.c. While not unheard of, this might present its own set of problems. lcc writes the RAM and ROM bank the code is supposed to use inside the object file, so it will have trouble when you compile code that is meant for multiple bank all in the same c file.

The traditional way is to only include header files or character data that is used one time only. Compile each c file into an object file and link them all together in a final step, kind of like in this thread.

Well, I got the example to work already. Therefore I started to look into it and into the other bank example. From there I copied bank.h.

I include all the .c files, otherwise I get an error on the compiler. Something like undefined global ...
I removed the bank.c reference in the main.c file and the compiler at least compiles it without errors. My character also appears on screen again, but the background is nowhere to be seen.
Gonna try some things now with the header files. Thank you so far! Really appreciate the help.

EDIT: So I found out how to include only the .h files and not the .c files. Thank you for that.
Unfortunately, the code in bank2 doesn't seem to work at all. Or better said, it is like bank2 gets skipped. Bank1 works just as intended, it draws the main character, it sets some palettes. And afterwards in main.c the player can 'move' the character with the D-pad. But in between drawing the main character and changing it's direction it is facing, there should be code to display the background.

I know the code for the background works, so it can't be it. I am also not sure if the content is really pushed into bank 1 and 2.

ALso, bank2 seems to be in bank 1 according to the .sym file

; Area: _CODE_1
01:4000 _Set_Sprite
01:418E _spritePalette
01:419E _UpdateSprite
; Area: _CODE_2
01:4000 _Set_Bkg
01:4049 _TestBG
01:4079 _TestMap

Last edited by pikpol (2017-08-14 16:35:33)

Offline

 

#4 2017-08-14 21:24:51

ISSOtm
Member
From: Somewhere in Echo RAM
Registered: 2017-04-18
Posts: 112
Website

Re: Bank Switching GBDK Nothing Works!

Maybe you should upload the whole source, personally I'm a bit confused by the errors you say the compiler throws when you don't include the C files.

My guess is that you declare a variable in one of the C files, and you re-use it in another one. Just add the declaration to a .h file instead, or include an "extern int var;" in the other .c, or something.
(That's how C works, btw.)


The French Lord Of Laziness.
Legend of Zelda and Undertale fan, I also tend to break Pokémon R/B/Y a little too much.

Twitter | Me on GCL | Discord : ISSOtm#9015 | Skype : isso.tm (I don't login anymore)

Offline

 

#5 2017-08-15 07:26:19

pikpol
Member
Registered: 2017-08-06
Posts: 12

Re: Bank Switching GBDK Nothing Works!

ISSOtm wrote:

Maybe you should upload the whole source, personally I'm a bit confused by the errors you say the compiler throws when you don't include the C files.

My guess is that you declare a variable in one of the C files, and you re-use it in another one. Just add the declaration to a .h file instead, or include an "extern int var;" in the other .c, or something.
(That's how C works, btw.)

So here you can download the whole source.
https://mega.nz/#F!d8YhRaiS!ihTkfwO2SWnMYUcZp9NjLw

But I now know how it works with the .h and .c files. At least I think so tongue
As I put everything in the correct bank when I compile it, I don't understand why bank2.c still gets thrown into bank 1 and that no code is being run from bank2.c

Offline

 

#6 2017-08-15 12:54:07

Tauwasser
Member
Registered: 2010-10-23
Posts: 83

Re: Bank Switching GBDK Nothing Works!

I see the problem, which is why I said you should look at the banked example in gbdk's folder. Basically, here's a quote form the gbdk README:

Banked function support
-----------------------
2.95 and above supports banked functions.

[...]

Some notes:
  * Currently only works with rgbds and isas.  asxxxx doesn't support
    resolving the bank of a function at link time

[...]

rgbds support
-------------

[...]

  * lcc does not work with rgbds.  You have to call sdcc directly, setting
    up the include path and making the libraries local as appropriate.

The Makefile in the "examples\gb\banked" directory correctly sets this up. The problem really is that lcc calls asxxx, which does insert banking code, but does not currently resolve the bank correctly at link time.

Just an FYI: the code that is generated for your init() looks like this:

Code:

call $095D   // call DISPLAY_OFF
ld de, $2000 // SWITCH_ROM_MBC1(1);
ld a, $01
ld [de], a
call $0A48   // library function banked_call
dw $4000     // address of Set_Sprite()
db $00       // supposed bank of Set_Sprite()
db $00       // filler
ld de, $2000 // SWITCH_ROM_MBC1(2);
ld a, $02
ld [de], a
call $0A48   // library function banked_call
dw $4000     // address of Set_Bkg()
db $00       // supposed bank of Set_Bkg()
db $00       // filler
call @0225   // call MainGame()
ret

Since you did the bank management by hand (using SWITCH_ROM_MBC1) anyway, you might as well have declared the Set_Sprite() and Set_Bkg() functions NONBANKED.

Offline

 

#7 2017-08-15 13:27:44

pikpol
Member
Registered: 2017-08-06
Posts: 12

Re: Bank Switching GBDK Nothing Works!

Tauwasser wrote:

I see the problem, which is why I said you should look at the banked example in gbdk's folder. Basically, here's a quote form the gbdk README:

Banked function support
-----------------------
2.95 and above supports banked functions.

[...]

Some notes:
  * Currently only works with rgbds and isas.  asxxxx doesn't support
    resolving the bank of a function at link time

[...]

rgbds support
-------------

[...]

  * lcc does not work with rgbds.  You have to call sdcc directly, setting
    up the include path and making the libraries local as appropriate.

The Makefile in the "examples\gb\banked" directory correctly sets this up. The problem really is that lcc calls asxxx, which does insert banking code, but does not currently resolve the bank correctly at link time.

Just an FYI: the code that is generated for your init() looks like this:

Code:

call $095D   // call DISPLAY_OFF
ld de, $2000 // SWITCH_ROM_MBC1(1);
ld a, $01
ld [de], a
call $0A48   // library function banked_call
dw $4000     // address of Set_Sprite()
db $00       // supposed bank of Set_Sprite()
db $00       // filler
ld de, $2000 // SWITCH_ROM_MBC1(2);
ld a, $02
ld [de], a
call $0A48   // library function banked_call
dw $4000     // address of Set_Bkg()
db $00       // supposed bank of Set_Bkg()
db $00       // filler
call @0225   // call MainGame()
ret

Since you did the bank management by hand (using SWITCH_ROM_MBC1) anyway, you might as well have declared the Set_Sprite() and Set_Bkg() functions NONBANKED.

Okay, I misunderstood that part. But now I know that using c I can't implement bank switching?
As I don't know asm at all, I don't understand how I could fix this issue. Would changing to gbdk-n and sdcc help resolve this issue?

Offline

 

#8 2017-08-15 13:56:07

ISSOtm
Member
From: Somewhere in Echo RAM
Registered: 2017-04-18
Posts: 112
Website

Re: Bank Switching GBDK Nothing Works!

Well, you can still write some ASM functions yourself. I'm not sure which MBC you're planning to use, so until I know that I can't really help you...


The French Lord Of Laziness.
Legend of Zelda and Undertale fan, I also tend to break Pokémon R/B/Y a little too much.

Twitter | Me on GCL | Discord : ISSOtm#9015 | Skype : isso.tm (I don't login anymore)

Offline

 

#9 2017-08-15 14:39:13

pikpol
Member
Registered: 2017-08-06
Posts: 12

Re: Bank Switching GBDK Nothing Works!

But the weird thing I don't understand is that at least one tutorial I saw used SWITCH_ROM_MBC1()  and it worked ofcourse.
So why doesn't it work (anymore?) for me?
As you almost always need bank switching, but if you use gbdk, you should also always use asm together with c?

Offline

 

#10 2017-08-15 15:38:01

ISSOtm
Member
From: Somewhere in Echo RAM
Registered: 2017-04-18
Posts: 112
Website

Re: Bank Switching GBDK Nothing Works!

Maybe the tutorial you saw used an older version of GBDK.

No, it's not needed, but GBDK as a whole is, imo, a crappy development environment, partly because it's somewhat unfinished, so in the meantime I'd recommend using some ASM.
Or at least understanding how bank switching works.


The French Lord Of Laziness.
Legend of Zelda and Undertale fan, I also tend to break Pokémon R/B/Y a little too much.

Twitter | Me on GCL | Discord : ISSOtm#9015 | Skype : isso.tm (I don't login anymore)

Offline

 

#11 2017-08-15 19:10:41

Tauwasser
Member
Registered: 2010-10-23
Posts: 83

Re: Bank Switching GBDK Nothing Works!

That's not what I said at all! I said the older gbdk releases come with asxxx, which cannot resolve the banks functions were put in at link time. To improve this, version 2.95 added the rgbds backend, which can resolve banks and can be used with C code. However, you cannot rely on lcc anymore. Instead, you have to call sdcc directly with the appropriate flags. You can use a different makefile that switches to the rgbds libraries. An example of which is given in the readme itself as well as in examples/gb/banked.

Code:

SRC = main.c bank2.c bank3.c
BIN = banked.gb

TOPDIR = ../../..
GBLIB = $(TOPDIR)/lib/medium/rgbds

LIB = $(GBLIB)/gbz80/gbz80.lib $(GBLIB)/gb/gb.lib
CRT0 = $(GBLIB)/gb/crt0.o

OBJ = $(SRC:.c=.o)

CC = $(TOPDIR)/bin/sdcc -mgbz80 --asm=rgbds -I$(TOPDIR)/include

all: $(BIN)

clean:
    rm $(OBJ)

%.o: %.s

$(BIN): $(OBJ)
    $(CC) -v $(CRT0) $(OBJ) $(LIB)
    rgbfix -p 255 -v a.gb

$(LIB): $(LIBOBJ)
    xlib $@ a $(LIBOBJ)

%.o: %.c
    $(CC) -c $<

%.asm: %.s
    astorgb.pl $< > $@

%.o: %.asm
    rgbasm -o$@ $<

%.s: %.ms
    maccer -o $@ $<

If you get the paths right and change the first line to

Code:

SRC = Main.c MainCharacterOverlap.c TestMap.c TestBG.c bank1.c bank2.c

then it will work after you made CharacterOverlap const.

Offline

 

#12 2017-08-19 07:19:42

pikpol
Member
Registered: 2017-08-06
Posts: 12

Re: Bank Switching GBDK Nothing Works!

Sorry guys to bother you again with this, but I don't understand what I am missing and it's the first time I actually use makefiles like this.
So I tried to run the makefile with nmake from the development command prompt from Visual Studio Community 2017.
I copied the makefile from the banked example, made sure that TOPDIR pointed to my gbdk folder and replaced SRC with the one mentioned by @Tauwasser
When I run it, I get

Microsoft (R) Program Maintenance Utility Version 14.11.25506.0
Copyright (C) Microsoft Corporation.  All rights reserved.

NMAKE : fatal error U1073: don't know how to make 'Main.o'
Stop.

I already did some googling, but couldn't find any helpful information for my problem.
I can only imagine that the part where the makefile says how to convert .c to .o isn't correctly setup. But it's hard to believe as the makefile is just a copy of the banked example makefile.
I hope you guys can help me out, so I can finally continue with this project.

Thank you so far.

Offline

 

#13 2017-08-19 07:42:51

ISSOtm
Member
From: Somewhere in Echo RAM
Registered: 2017-04-18
Posts: 112
Website

Re: Bank Switching GBDK Nothing Works!

This error means that the Makefile is requested to "brew" Main.o, but it has no recipe for that.
What does the Makefile look like ?


The French Lord Of Laziness.
Legend of Zelda and Undertale fan, I also tend to break Pokémon R/B/Y a little too much.

Twitter | Me on GCL | Discord : ISSOtm#9015 | Skype : isso.tm (I don't login anymore)

Offline

 

#14 2017-08-19 08:31:41

pikpol
Member
Registered: 2017-08-06
Posts: 12

Re: Bank Switching GBDK Nothing Works!

SRC = Main.c MainCharacterOverlap.c TestMap.c TestBG.c bank1.c bank2.c
BIN = banked.gb

TOPDIR = ../../..
GBLIB = $(TOPDIR)/lib/medium/rgbds

LIB = $(GBLIB)/gbz80/gbz80.lib $(GBLIB)/gb/gb.lib
CRT0 = $(GBLIB)/gb/crt0.o

OBJ = $(SRC:.c=.o)

CC = $(TOPDIR)/bin/sdcc -mgbz80 --asm=rgbds -I$(TOPDIR)/include

all: $(BIN)

clean:
    del $(OBJ)

%.o: %.s

$(BIN): $(OBJ)
    $(CC) -v $(CRT0) $(OBJ) $(LIB)
    rgbfix -p 255 -v a.gb

$(LIB): $(LIBOBJ)
    xlib $@ a $(LIBOBJ)

%.o: %.c
    $(CC) -c $<

%.asm: %.s
    astorgb.pl $< > $@

%.o: %.asm
    rgbasm -o$@ $<

%.s: %.ms
    maccer -o $@ $<

Offline

 

#15 2017-08-19 08:40:37

ISSOtm
Member
From: Somewhere in Echo RAM
Registered: 2017-04-18
Posts: 112
Website

Re: Bank Switching GBDK Nothing Works!

IIRC how Makefiles work, let's break it down a bit.

You ask for "make", thus it is implied "make all" because it's the first target.
To make "all", "banked.gb" is required.
To make "banked.gb", "Main.o MainCharacterOverlap.o TestMap.o TestBG.o bank1.o bank2.o" are required (all items in "SRC" but replacing ".c" with ".o")
Thus, it will start by looking for a recipe for "Main.o".

There are only 3 recipes that can produce a ".o" file : "%.o: %.s", "%.o: %.c" and "%.o: %.asm".
make will try finding a "Main.s" file, then a "Main.c" file, then a "Main.asm" file.
But it finds none, thus it outputs an error "I don't know how I'm supposed to make it ! sad"
So that means you have neither of these 3 files in the same directory as the Makefile (I guess, since I never used GBDK) ; from the "SRC" variable I assert that you have a "Main.c" file.
Before you do anything, where is it located relative to the directory you're using "make" in ?


The French Lord Of Laziness.
Legend of Zelda and Undertale fan, I also tend to break Pokémon R/B/Y a little too much.

Twitter | Me on GCL | Discord : ISSOtm#9015 | Skype : isso.tm (I don't login anymore)

Offline

 

#16 2017-08-19 08:55:37

pikpol
Member
Registered: 2017-08-06
Posts: 12

Re: Bank Switching GBDK Nothing Works!

ISSOtm wrote:

IIRC how Makefiles work, let's break it down a bit.

You ask for "make", thus it is implied "make all" because it's the first target.
To make "all", "banked.gb" is required.
To make "banked.gb", "Main.o MainCharacterOverlap.o TestMap.o TestBG.o bank1.o bank2.o" are required (all items in "SRC" but replacing ".c" with ".o")
Thus, it will start by looking for a recipe for "Main.o".

There are only 3 recipes that can produce a ".o" file : "%.o: %.s", "%.o: %.c" and "%.o: %.asm".
make will try finding a "Main.s" file, then a "Main.c" file, then a "Main.asm" file.
But it finds none, thus it outputs an error "I don't know how I'm supposed to make it ! :("
So that means you have neither of these 3 files in the same directory as the Makefile (I guess, since I never used GBDK) ; from the "SRC" variable I assert that you have a "Main.c" file.
Before you do anything, where is it located relative to the directory you're using "make" in ?

What do you mean by it?
If you mean, where is Main.c located, then I can say that Main.c is in the same folder as the make file. And also the folder I first go into in the command prompt before I use nmake.
But if you mean nmake. Then I can answer with; C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Tools\MSVC\14.11.25503\bin\HostX64\x64.

EDIT: What I forgot to tell you is that I also can't make the banked example. It gives the same error.

Last edited by pikpol (2017-08-19 08:58:25)

Offline

 

#17 2017-08-19 21:00:03

Tauwasser
Member
Registered: 2010-10-23
Posts: 83

Re: Bank Switching GBDK Nothing Works!

nmake cannot handle GNU make files. You will need to run GNU make for Windows, which you can get here.

Offline

 

#18 2017-08-19 21:10:14

ISSOtm
Member
From: Somewhere in Echo RAM
Registered: 2017-04-18
Posts: 112
Website

Re: Bank Switching GBDK Nothing Works!

Personally since I use Windows 10, I installed the Windows Subsystem for Linux (which allows running some Ubuntu things on your NT kernel, yaaay). I know, boo at me how much you want. I like it anyways.
So, since I installed it I can use the Linux bins if RGBDS, GNU make and Git. It's pretty darn cool !


The French Lord Of Laziness.
Legend of Zelda and Undertale fan, I also tend to break Pokémon R/B/Y a little too much.

Twitter | Me on GCL | Discord : ISSOtm#9015 | Skype : isso.tm (I don't login anymore)

Offline

 

#19 2017-08-21 11:32:45

pikpol
Member
Registered: 2017-08-06
Posts: 12

Re: Bank Switching GBDK Nothing Works!

Well I installed gnuwin32. But still, nothing works. I feel like a total noob right now hmm
So basically what happened is, I tried make from within the make directory. That ofcourse didn't work. Then I went into the banked example folder and tried it again. and now i get the error "cannot exec process no such file or directory"v
any ideas?...

Offline

 

#20 2017-08-21 15:56:43

Tauwasser
Member
Registered: 2010-10-23
Posts: 83

Re: Bank Switching GBDK Nothing Works!

Make sure the rgbds bin directory is in your path. sdcc expects to be able to call rgbds directly.

Offline

 

#21 2017-08-21 16:54:18

pikpol
Member
Registered: 2017-08-06
Posts: 12

Re: Bank Switching GBDK Nothing Works!

Tauwasser wrote:

Make sure the rgbds bin directory is in your path. sdcc expects to be able to call rgbds directly.

The documantation is talking about an autoexec.bat. But I don' t have that file anywhere and I never set any environment variables. So I don't understand to which path I should add it to?

Offline

 

#22 2017-08-21 18:06:14

drludos
Member
Registered: 2017-05-11
Posts: 40

Re: Bank Switching GBDK Nothing Works!

I can't help with the "banking" part (way beyond my current skills), but as newbie GB dev, I too struggled to get Make running on windows.

Installing GNUMake alone isn't enough, because makefiles often call other Linux prompt commands. To have it running on windows you'll actually need to install MSYS, which is a port of the whole Linux prompt commands to the Windows environment:
http://www.mingw.org/wiki/MSYS

However, the Make version coming with MSYS has a bug preventing it from reporting compiler errors.

So first, download and install MSYS:
https://sourceforge.net/projects/mingw- … p/download

Then, download Make for windows and copy the "make.exe" you've just downloaded over the "/bin" dir of your fresh MSYS installation.
http://gnuwin32.sourceforge.net/packages/make.htm

Make sure that the "/bin" folder is also added to your PATH environment variable.

Then, you should be able to run makefile on Windows much like on Linux.

Thanks a lot to Zalo's ZGB installation tutorial for helping me out with this "make on windows" issue in the first place.
https://github.com/Zal0/ZGB/wiki/Installation

Last edited by drludos (2017-08-21 18:08:05)

Offline

 

#23 2017-08-22 13:49:50

pikpol
Member
Registered: 2017-08-06
Posts: 12

Re: Bank Switching GBDK Nothing Works!

drludos wrote:

I can't help with the "banking" part (way beyond my current skills), but as newbie GB dev, I too struggled to get Make running on windows.

Installing GNUMake alone isn't enough, because makefiles often call other Linux prompt commands. To have it running on windows you'll actually need to install MSYS, which is a port of the whole Linux prompt commands to the Windows environment:
http://www.mingw.org/wiki/MSYS

However, the Make version coming with MSYS has a bug preventing it from reporting compiler errors.

So first, download and install MSYS:
https://sourceforge.net/projects/mingw- … p/download

Then, download Make for windows and copy the "make.exe" you've just downloaded over the "/bin" dir of your fresh MSYS installation.
http://gnuwin32.sourceforge.net/packages/make.htm

Make sure that the "/bin" folder is also added to your PATH environment variable.

Then, you should be able to run makefile on Windows much like on Linux.

Thanks a lot to Zalo's ZGB installation tutorial for helping me out with this "make on windows" issue in the first place.
https://github.com/Zal0/ZGB/wiki/Installation

Thanks, it is a bit easier now. But I still get the error hmm
So I did exactly as you said. Install msys(in c:\msys\). I downloaded it and just put it in there, so I think I installed it. Then I copied make with the .dll files to the bin folder of msys. And then I ran make again, resulting in the same error as before: make: *** [main.o] Error 1

Offline

 

#24 2017-09-07 09:33:03

pikpol
Member
Registered: 2017-08-06
Posts: 12

Re: Bank Switching GBDK Nothing Works!

Got a sort of new error.
So I added the gbdk\bin folder and the msys\bin folder to PATH.
And than this appeared:

Cannot exec process : No such file or directory
Cannot exec assember: No such file or directory
make: *** [main.o] Error 1

Instead of make saying "Cannot exec preprocessor: No such file or directory"
Make now says, "Cannot exec assember: No such file or directory"
So it has found some stuff and I hope someone knows what I am missing right now.
Thanks again guys, even though this goes very slowly, I still want to make a gameboy game.

Last edited by pikpol (2017-09-07 09:37:05)

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson