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 2020-04-27 17:35:38

Ben
Member
Registered: 2015-01-21
Posts: 10

Background modification during V-Blank issue

Hello everyone,
I couldn't find any topic about this kind of issue.

I'm trying to load a complete background during a V-Blank IRQ but I was getting some odd result with bgb emulator.
I reduced my code to the basics and it appears that some bytes of the aren't refreshed during V-Blank. Here the code is loading a grey background and then try to load a black background during V-Blank. Here the code and the result result I'm getting with bgb :

Code:

;///////////////////////////////////////////////////////////////
;////       HEADER DIRECTIVES                               ////
;///////////////////////////////////////////////////////////////

.ROMDMG
.NAME "GB2dB"
.CARTRIDGETYPE 2
.RAMSIZE 2
.COMPUTEGBCHECKSUM
.COMPUTEGBCOMPLEMENTCHECK
.LICENSEECODENEW "17"
.EMPTYFILL $00

.MEMORYMAP
    SLOTSIZE $4000
    DEFAULTSLOT 0
    SLOT 0 $0000
    SLOT 1 $4000
.ENDME

.ROMBANKSIZE $4000
.ROMBANKS 2

.BANK 0 SLOT 0


;///////////////////////////////////////////////////////////////
;////       PROGRAM FIRST BYTES                             ////
;///////////////////////////////////////////////////////////////

.ORG $0040
    call    VBlank
    reti

.ORG $0100
    nop
    jp      start

;//// Mandatory Nintendo logo
.ORG $0104
.DB $CE,$ED,$66,$66,$CC,$0D,$00,$0B,$03,$73,$00,$83,$00,$0C
.DB $00,$0D,$00,$08,$11,$1F,$88,$89,$00,$0E,$DC,$CC,$6E,$E6
.DB $DD,$DD,$D9,$99,$BB,$BB,$67,$63,$6E,$0E,$EC,$CC,$DD,$DC
.DB $99,$9F,$BB,$B9,$33,$3E


;///////////////////////////////////////////////////////////////
;////       INITIALIZATION                                  ////
;///////////////////////////////////////////////////////////////

.org $0150
start:
    di                              ; Deactivate interrupts
    ld      sp,$FFF4                ; Load SP register with $FFF4 as Nintendo advices

    xor     a                       ; A = 0
    ld      ($FF26),a               ; Deactivate GB sound

waitVBlank:
    ld      a,($FF44)               ; Load LCD Y position into A
    cp      144                     ; Compare A to 144
    jr      c,waitVBlank            ; jump back to label if A<144

    xor     a                       ; A=00
    ld      ($FF40),a               ; Shutting down LCD screen


;////       LOADING GRAPHICS GLVL                           ////

    ld      bc,64
    ld      de,graphics_glvl
    ld      hl,$8000
loadTiles
    ld      a,(de)
    ldi     (hl),a
    inc     de
    dec     bc
    ld      a,b
    or      c
    jr      nz,loadTiles


;////       CLEANING BACKGROUND                             ////

    ld      de,32*32
    ld      hl,$9800
clearBG:
    ;xor     a
    ld      a,$01                   ;Use tile 1 as background for test
    ldi     (hl),a
    dec     de
    ld      a,e
    or      d
    jr      nz,clearBG

    xor     a
    ld      ($FF43),a               ; Reset background X position
    ld      ($FF42),a               ; Reset background Y position


;////       CLEANING OAM                                     ///

    ld      hl,$FE00
    ld      b,160
clearOAM:
    ld      (hl),$00
    inc     l
    dec     b
    jr      nz,clearOAM


;////       SCREEN ACTIVATION                               ////

    ld      a,%11100100             ;Background palette setting
    ld      ($FF47),a
    ld      a,%10010001             ;Backrgound display activation
    ld      ($FF40),a
    ld      a,%00010001             ;Mode flag selection
    ld      ($FF41),a
    ld      a,%00000001             ;V-Blank interrupt actvation
    ld      ($FFFF),a

    ei                              ;Enable interrupts


loop:
    nop
    jr      loop


VBlank:
    call    SetFrameTest4

    ret


SetFrameTest4:
    ld      d,18
    ld      hl,$9800
printLine:
    ld      e,20
printChar:
    ld      a,$02
    ldi     (hl),a
    dec     e
    jr      nz,printChar
    inc     hl
    inc     hl
    inc     hl
    inc     hl
    inc     hl
    inc     hl
    inc     hl
    inc     hl
    inc     hl
    inc     hl
    inc     hl
    inc     hl
    dec     d
    jr      nz,printLine
    ret

graphics_glvl:
.DB $00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00,$00
.DB $FF,$00,$FF,$00,$FF,$00,$FF,$00,$FF,$00,$FF,$00,$FF,$00,$FF,$00
.DB $FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF,$FF
.DB $00,$00,$00,$00,$00,$00,$00,$00,$C0,$C0,$20,$E0,$90,$F0,$C8,$78

https://i.ibb.co/R6Y64Lp/GBTest-BGB.png

I tried the same code with Visual Boy Advance and it's seems to run correctly (I'm getting a complete black background).
Does anyone has an idea about what could lead to this behavior ? Is there anything about V-Blank timing I missed here ?

Thanks

Last edited by Ben (2020-04-27 17:36:19)


[Ben]
-----------------------------------------------------

Offline

 

#2 2020-04-27 18:28:23

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

Re: Background modification during V-Blank issue

What assembler is this? I don't recognize it.

The fact that you get different gfx on BGB and VBA strongly hints at VRAM locking problems. Tick every checkbox in BGB's options, tab "Exceptions", except SGB transfers. This will point out a lot of problems when they happen.
I'm pretty sure you're just overflowing VBlank time.


More general comments on your code:

There's no need to fix the location of the init code if you're `jp`-ing to it. It would make more sense if it was a `jr`, but not here.

`sp` is better put outside of HRAM. (See the second half of this post.)

You don't have names for hardware registers? If you were using RGBDS, I'd strongly recommend hardware.inc, but I don't know for this one.

Instead of hardcoding the size of the block copied to VRAM (`graphics_glvl`), you should put a label at the end of that block, and take the difference between the start and end labels as the length.

Clearing the entire tilemap isn't really useful, since you're only going to display a small part. You can just clear 32 (width of a "line") * 18 (height of the screen) bytes, or only clear the first 20 bytes of the first 18 lines.

Clearing OAM isn't necessary, since you wouldn't be displaying it anyways (not setting bit 1 of LCDC).

Writing to STAT isn't useful if you don't use the STAT interrupt. I'm especially not sure why you're writing to the bottom 2 bits, as they are read-only.

Be careful when enabling interrupts again, they may have "accumulated" before. You should clear IF too, though the best way isn't exactly obvious:

Code:

xor a
ei ; Only takes effect *after* the next instruction!
ld ($FF0F), a

You don't really need a `nop` in your loop. `halt` is better because it allows the CPU to go in low power, saving some battery.

Instead of all those `inc hl|, you could add 12 to hl:

Code:

ld a, l
add a, 12 ; This would be better as a constant, though
ld l, a
adc a, h
sub l
ld h, a

(Explanation.)

Instead of hardcoding the gfx in code, you may want to try storing an image instead, and having your build system convert that to a binary file (for example, using RGBGFX). Though I don't know how you would do the equivalent of `INCBIN` in that assembler; worst case, you can have a script generate a stream of `db` and include that.


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

 

#3 2020-04-27 23:49:12

Ben
Member
Registered: 2015-01-21
Posts: 10

Re: Background modification during V-Blank issue

Thank you for your answer!

I'm pretty sure you're just overflowing VBlank time.

That's what I was also thinking of, but V-Blank being this short was bugging me. I mean, not even half of the background can be refreshed at the same time!
I tried running it with all exceptions enabled, as you pointed, and it indeed break on a "inaccessible VRAM". It is strange because none of the background tiles was refreshed before it happens, or maybe it was just BGB not refreshing the map viewer...
Anyway, thanks a lot for your answer, I'll try to work my way around to get the background refreshed in 3 V-Blank instead of one.

Also, thanks for all the advices and tips you gave me. And to answer your question, I'm using WLA-DX assembler (which does come with the .INCBIN directive wink )


[Ben]
-----------------------------------------------------

Offline

 

#4 2020-04-28 09:13:22

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

Re: Background modification during V-Blank issue

Ben wrote:

Thank you for your answer!

I'm pretty sure you're just overflowing VBlank time.

That's what I was also thinking of, but V-Blank being this short was bugging me. I mean, not even half of the background can be refreshed at the same time!
I tried running it with all exceptions enabled, as you pointed, and it indeed break on a "inaccessible VRAM". It is strange because none of the background tiles was refreshed before it happens, or maybe it was just BGB not refreshing the map viewer...
Anyway, thanks a lot for your answer, I'll try to work my way around to get the background refreshed in 3 V-Blank instead of one.

Yes, VBlank is quite short; generally, only a third of a screen's worth of tilemap has time to be refreshed. But, why are you trying to write to it in the VBlank handler, anyways?

BGB's map viewer auto-updates always, so I guess you did some invalid accesses early in the code.

Ben wrote:

Also, thanks for all the advices and tips you gave me. And to answer your question, I'm using WLA-DX assembler (which does come with the .INCBIN directive wink )

Ah, I see. You may want to try RGBDS instead, since it's tailored for the Game Boy, and so should have a bunch of useful features for it.


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 2020-04-28 13:21:25

Ben
Member
Registered: 2015-01-21
Posts: 10

Re: Background modification during V-Blank issue

But, why are you trying to write to it in the VBlank handler, anyways?

For my amount of experience of programming for the GB, it was easier than setting a timer up to load some data repetitively to the background (Guess you're not the only one high on the laziness scale wink ). As the code is not doing a lot and because I wasn't expecting V-Blank to be this short, it seems the best option

You may want to try RGBDS instead

I'll give it a shot, hope it's not too different


[Ben]
-----------------------------------------------------

Offline

 

Board footer

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson