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.


#1 2019-04-21 15:42:04

New member
Registered: 2019-04-21
Posts: 4

MBC1 unkown address, possibly caused by banking issues

Hello all!
I am very excited to get going on my game. I have been working on a demo. I am trying to add some new tile data to my build and when i add the file containing the data array the screen goes blue. There is also an error in the logs "MBC1 unknown address". I believe the issue has to do with banking. It seems that my banks are not setup correctly. Below is a link to the code. you can run make to build a working rom. If you look in the make file you can comment out lines 34,35 and uncomment 38,39 to make the build break.

Link: … sp=sharing




#2 2019-04-22 17:08:03

New member
Registered: 2019-04-21
Posts: 4

Re: MBC1 unkown address, possibly caused by banking issues

I think i found out how to fix it, but i am a little confused. I changed the  " unsigned char" to "static const unsigned char" in hud-font.c This seemed to force the compiler to store the code under _CODE_4 instead of _DATA. Can anyone shed some light on this?



#3 2019-04-27 18:53:42

Registered: 2010-10-23
Posts: 85

Re: MBC1 unkown address, possibly caused by banking issues

Which version of gbdk are you using? I'm using gbdk3-2.93 and get a better error message:


lcc -Wl-yt3 -Wl-yo8 -Wl-ya0 -o build/ ./src2/bank-1/my-world-map.o ./src2/bank-1/my-world-tiles.o ./src2/bank-2/astroid-tiles.o ./src2/bank-2/ShipTiles.o ./src2/bank-3/hud-border.o ./src2/bank-3/hud-window.o obj/main.o
ERROR: address overflow (addr cbd6 >= 8000)

This error message is trying to tell you that you ran out of space in one of the rom banks, as it calculated that address 0xCBD6 is still within one of the ROM banks, which usually are from 0x4000--0x7FFF resp. 0x0000--0x3FFF for Rom Bank 0.

The reason is that you data is much too big, as you never tell the compiler that the data is constant. Thus, it correctly assumes that you could change the data at one point in time and it needs to reside in RAM.

Constant data is put into the ROM directly, whereas pre-initialized non-constant data needs to be copied to RAM when the program is initially booted up. Thus, each ROM bank must hold a copy of the data and RAM needs to be big enough to hold it, too. Because the initialization happens in ROM bank 0, the compiler tries to copy all the initialization data to ROM bank 0 first and ran out of space there as well. I actually noticed that the compiler doesn't care if it runs from ROM bank 0 into ROM bank 1 as it assumes to be able to do that. The initialization code for RAM is very bad as it produces code copy single bytes to target locations instead of doing a memcpy, at least for me.

That's why changing data to const works in your case. The static keyword does something else: It changes linkage from default external linkage to internal linkage. Internal symbols are only visible within one compilation unit (one C file), whereas external symbols are visible globally. You cannot define a variable to have internal linkage and external linkage at the same time. Doing so will result in a linker error if the variable is used anywhere:


?ASlink-Warning-Undefined Global _WorldTiles referenced by module lcc70320

You can find and debug these errors using the map and listing files. See the GBDK docs for help how to activate them. This way you can know the RAM usage and the ROM usage of your data.

You should also know that your Makefile does not actually work, as the default compilation rule is used for all your sources:


lcc    -c -o src2/bank-1/my-world-map.o src2/bank-1/my-world-map.c

The default rule is $(CC) -c -o $@ $<. As you see, the flags specifying RAM and ROM banks are missing. Use make -r to run make without default rules. Let's check the rules:


./src2/bank-1/%.c.o: %.c

This rule expects to find a my-world-map.c file at the root of your tree next to the Makefile. It also expects a dependency to file ./src2/bank-1/my-world-map.c.o, which isn't there either.
There are many ways to solve this. I chose a somewhat generic way where you specify each file by hand and each attribute for each file by hand but provide a generic rule for all files:


CC = lcc
TARGET ?= build/
BUILD_DIR ?= ./build
MKDIR_P ?= mkdir -p

SRC = \
    main.c \
    bank-1/my-world-map.c \
    bank-1/my-world-tiles.c \
    bank-2/astroid-tiles.c \
    bank-2/ShipTiles.c \
    bank-3/hud-border.c \
    bank-3/hud-window.c \

OBJS = $(addprefix obj/, $(SRC:.c=.o))

rebuild: clean $(TARGET) cleanafter

# # Link banks
# #      ROM+MBC1+RAM : -Wl-yt2
# #      4 ROM banks  : -Wl-yo4
# #      1 RAM banks  : -Wl-ya0
# # Make Byte 0x0143 in Header 0xC0 for CGB exclusive title.
    $(CC) -Wl-m -Wl-yt3 -Wl-yo8 -Wl-ya0 -Wl-yp0x143=0xC0 -o $@ $(OBJS)

# --------------------------

# enable secondexpansion used to depend on directories
# keep listing and map files
.PRECIOUS: *.lst *.map

# Compilation-unit-specific flags
obj/main.o: BANKS :=
obj/bank-1/%.o: BANKS := -Wf-bo1 -Wf-ba0
obj/bank-2/%.o: BANKS := -Wf-bo2 -Wf-ba0
obj/bank-3/%.o: BANKS := -Wf-bo3 -Wf-ba0
obj/bank-4/%.o: BANKS := -Wf-bo4 -Wf-ba0

# Generic compilation rule
# depend on directory being created first using second expansion
obj/%.o: src2/%.c | $$(dir $$@)
    $(CC) -Wa-l $(BANKS) -c -o $@ $<

# Rule to create directories
    mkdir -p $@

# --- cleans ---
    rm -rf $(OBJS) $(OBJS:.o:.lst)

    rm -rf $(OBJS)

Btw, it's kind of bad style to include c files in other c files. You might want to rethink that.
Also, there's an error in hud.c where you switch to the wrong ROM bank and the palette data references palette 0x00 instead of 0x02.





Last edited by Tauwasser (2019-04-27 19:00:42)



#4 2019-05-08 17:20:59

New member
Registered: 2019-04-21
Posts: 4

Re: MBC1 unkown address, possibly caused by banking issues

Thanks for the reply. I am using GBDK  2.96a



Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson