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-12-26 14:59:49

jchristof
Member
Registered: 2019-12-01
Posts: 17

Add and remove interrupts

I'm trying to bookend adding and removing a vbl and lcd isr methods. When these are first added, their behavior performs as expected.
When I try to remove the vbl handler, it crashes the game.
I've tried multiple modifications of the code below, including making sure to guard against double removes but I continue to crash on removing the vbl handler.

I'm using ZGB, and it has already enabled a vbl and timer handler prior to both of these calls.

Can anyone suggest a fix for this?

Code:

void InGameEnableHbl(){
     interrrupts_enabled = 1;
    
    disable_interrupts();
    add_LCD(InGameHbl);
    add_VBL(InGameHblUpdate);
    set_interrupts(VBL_IFLAG | TIM_IFLAG | LCD_IFLAG);
    enable_interrupts();
}

void InGameDisableHbl(){
    if(interrrupts_enabled == 0)
        return;
    
    interrrupts_enabled = 0;
    
    disable_interrupts();
    remove_LCD(InGameHbl);
    
    //remove_VBL(InGameHblUpdate); --- this line will crash the game
    //set_interrupts(VBL_IFLAG | TIM_IFLAG);
    enable_interrupts();
}

Last edited by jchristof (2019-12-26 15:01:20)

Offline

 

#2 2019-12-26 15:07:41

jchristof
Member
Registered: 2019-12-01
Posts: 17

Re: Add and remove interrupts

Oh wait, this seems to work - I must need to turn the display off before removing that isr.

Code:

void InGameDisableHbl(){
    if(interrrupts_emabled == 0)
        return;
    
    interrrupts_emabled = 0;
    
    disable_interrupts();
    remove_LCD(InGameHbl);
    DISPLAY_OFF;
    remove_VBL(InGameHblUpdate);
    set_interrupts(VBL_IFLAG | TIM_IFLAG);
    enable_interrupts();
    DISPLAY_ON;
}

Last edited by jchristof (2019-12-26 15:08:33)

Offline

 

#3 2019-12-26 19:56:31

jchristof
Member
Registered: 2019-12-01
Posts: 17

Re: Add and remove interrupts

Dang - that only appeared to work for a while. After some seemingly unrelated changes, it's crashing on the remove_VBL() again.

Hmm - maybe removing the isr will crash if the isr is not yet returned?

Nope, disabling, waiting and removing doesn't seem to work.

Last edited by jchristof (2019-12-26 21:22:23)

Offline

 

#4 2020-01-17 14:44:00

bbbbbr
Member
Registered: 2019-03-04
Posts: 126

Re: Add and remove interrupts

There's what seems to be a bug in GBDK's interrupt removal function, so I think this might be what you are looking for.

See this thread for both a workaround and a fix:
https://gbdev.gg8.se/forums/viewtopic.php?id=214

TLDR; here's the workaround:

Code:

// 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();

Offline

 

#5 2020-01-20 14:05:53

jchristof
Member
Registered: 2019-12-01
Posts: 17

Re: Add and remove interrupts

Thanks for the response on interrupts - I noticed you mention recompiling libc in gbdk.

I'd like to rebuild it with the fix you mentioned, plus the default interrupt settings don't account for returning in the middle of vram copy functions during mode3 (which is causing corruption in my current project)

I have both the gbdk 2.95 from SF and the ZGB engine's version. I'm looking at the make file in that directory and trying to figure out how to invoke it.
I notice that it refers to Makefile.common but neither of my packages contains this file.

Would you be able to share how you manage to rebuild it? Do I need some other package?

Thanks!

Offline

 

#6 2020-01-20 16:54:43

bbbbbr
Member
Registered: 2019-03-04
Posts: 126

Re: Add and remove interrupts

You should be able to use the tools in gbdk (lcc) to rebuild it. It's straightforward and doesn't (so far as I can tell) require the makefile.

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:

Code:

cd /opt/gbdk/libc/gb
/opt/gbdk/bin/lcc -c crt0.s

Backup and replace the existing crt0.o binary:

Code:

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 16:55:40)

Offline

 

#7 2020-01-22 21:53:09

jchristof
Member
Registered: 2019-12-01
Posts: 17

Re: Add and remove interrupts

Thanks!

I was able to produce a new crt0.s using lcc.
I'm running the ZGB make files to build the project, and the new crt0.s code is not in the final rom (checked the rom with a hex editor)

I wonder, do I also need to build gb.lib?

I need to look at what ZGB's make files are doing to pick up the library code.

*EDIT*
I just noticed that if I remove crt0.o from the small asxxx the build does error with a crt0.o not found.
I'll need to examine the crt0.o again to see where my changes are going...

*EDIT*
Ok got it - it was just a clean issue. The game now won't start, but at least I can see that my changes made it into the rom binary. I just need to figure out the sdcc assembler syntax.

Last edited by jchristof (2020-01-23 00:16:55)

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson