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.
Hi there,
Just trying to remove an interrupt handler using remove_VBL with GBDK 2.95, but whenever I try the game crashes, any idea what I might be doing wrong? just doing this:
remove_VBL(myHandler);
Thanks,
Andrea
Offline
Did you ever solve this? Even on ultra stripped down projects, where all it does is add then remove the interrupt, it crashes.
Offline
Disclaimer: I haven't dug much into GBDK for this so the following may not be entirely accurate.
A couple things I noticed
* Do not call wait_vbl_done() if the VBL interrupt is not enabled / running (I believe it will get stuck waiting)
* It's probably best to turn off interrupts before removing a handler
* It looks like GBDK may install it's own VBL interrupt (in crt0.s see: .vbl: ) to service the OAM. For example, even if you don't install your own VBL handler, calling "disable_interrupts()" will cause sprites to no longer refresh, then calling "enable_interrupts()" will cause them to resume. (likewise: set_interrupts(0x00) and then set_interrupts(VBL_IFLAG)
* calling add_VBL() repeatedly with the same entry will append more duplicate entries, it will not replace the existing entry that matches. So avoid calling add_VBL() without first removing the same entry
* add_VBL() appends entries to the end of the VBL interrupt list (at 0xCEDD), but remove_VBL removes the first matching entry from the front of the list. I'm not entirely sure, but it looks like it may also remove (copy over) the preceding entry. This could be part of the problem and also points to a workaround.
Here is a potential (ugly) workaround:
// If this gets optimized out, then add something to the body void vbl_shim() { } . . . // Call in this sequence to remove a *different* handler previously added with add_VBL() // DO NOT call if you haven't previously added a handler, otherwise it will crash // This adds an entry after the most recent entry, and then deletes itself (and via a bug(?), the preceding/most recent entry as well) disable_interrupts(); add_VBL(vbl_shim); remove_VBL(vbl_shim); enable_interrupts();
Last edited by bbbbbr (2019-11-22 17:13:04)
Offline
Update- if you want a fix instead of a workaround, I think it would be as follows (seems to work when I patch and rebuild crt0.s). My ASM isn't very good, so there might be a more optimal way to do this.
gbdk/libc/gb/crt0.s
FROM this: ;; Now do a memcpy from here until the end of the list LD D,H LD E,L DEC DE INC HL TO this: ;; Now do a memcpy from here until the end of the list ; Fix for _remove_VBL() erasing previous VBL entry ; Copy next entry -> current entry, instead of copying current -> previous LD D,H LD E,L INC HL INC HL
Once built, back up and repalce the crt0.o found under the gbdk/lib/... folder
Edit: Add rebuild instructions below
You should be able to use the tools in gbdk (lcc) to rebuild it.
I'm using gbdk 2.96 on Linux, so location of file paths and command line may vary for you.
Go to where ctr0.s is located and rebuild it:
cd /opt/gbdk/libc/gb /opt/gbdk/bin/lcc -c crt0.s
Backup and replace the existing crt0.o binary:
cp ../../lib/small/asxxxx/gb/crt0.o ../../lib/small/asxxxx/gb/crt0.o.dist mv crt0.o ../../lib/small/asxxxx/gb
Last edited by bbbbbr (2020-01-20 17:00:36)
Offline
Zalo wrote:
Hi
I am planning to add this to gbdk 3.1. Has it been properly tested already?
I tested while investigating the fix, but it would be good to have the fix confirmed by another person. Particularly if one of the posters above could confirm that it resolved their issue.
The process for testing is fairly straightforward if I recall: calling remove_VBL() on your previously installed handler should produce a crash in an unpatched build. In the patched version the crash should go away and the desired VBL handler should get removed.
Last edited by bbbbbr (2020-04-21 15:58:20)
Offline