User:Kmeisthax/Findings/2011/6/10/v67 Patch Notes

From Wikifang, a definitive guide to Telefang, Dino Device and Bugsite
Jump to navigation Jump to search

Cleared Tile Fix

The Cleared Tile Glitch happens when the VWF core draws tiles. It will always draw one extra tile most of the time. In normal operation (i.e. drawing to successive tiles) this is fine, but if things are drawn in reverse order then some tiles may be cleared. Let's fix that.

If you're wondering, here's the current state of the VWF:

   ROM:0002F9C1 ; ---------------------------------------------------------------------------
   ROM:0002F9C1                 nop
   ROM:0002F9C2                 nop
   ROM:0002F9C3                 nop
   ROM:0002F9C4                 nop
   ROM:0002F9C5                 nop
   ROM:0002F9C6                 nop
   ROM:0002F9C7                 nop
   ROM:0002F9C8                 nop
   ROM:0002F9C9                 nop
   ROM:0002F9CA                 nop
   ROM:0002F9CB                 nop
   ROM:0002F9CC                 nop
   ROM:0002F9CD                 nop
   ROM:0002F9CE                 nop
   ROM:0002F9CF                 nop
   ROM:0002F9D0                 nop
   ROM:0002F9D1                 nop
   ROM:0002F9D2                 nop
   ROM:0002F9D3                 ld      b, 8
   ROM:0002F9D5                 ld      a, $CF ; '-'
   ROM:0002F9D7                 ld      [WRAM_VWF_CompositingArea0], a
   ROM:0002F9DA                 ld      a, $D0 ; '-'
   ROM:0002F9DC                 ld      [WRAM_VWF_CompositingArea1], a
   ROM:0002F9DF                 push    bc
   ROM:0002F9E0                 push    de
   ROM:0002F9E1                 push    hl
   ROM:0002F9E2                 di
   ROM:0002F9E3                 ld      a, [WRAM_VWF_CompositingArea0]
   ROM:0002F9E6                 ld      h, a
   ROM:0002F9E7                 ld      a, [WRAM_VWF_CompositingArea1]
   ROM:0002F9EA                 ld      l, a
   ROM:0002F9EB                 ld      b, [hl]
   ROM:0002F9EC                 inc     hl
   ROM:0002F9ED                 ld      c, [hl]
   ROM:0002F9EE                 dec     hl
   ROM:0002F9EF                 ld      a, [de]
   ROM:0002F9F0                 ld      d, a
   ROM:0002F9F1                 ld      e, 0
   ROM:0002F9F3                 ld      a, [WRAM_VWF_OldTileMode]
   ROM:0002F9F6                 cp      2
   ROM:0002F9F8                 jr      z, loc_FA00
   ROM:0002F9FA                 cp      1
   ROM:0002F9FC                 jr      z, loc_FA01+1
   ROM:0002F9FE                 jr      loc_FA01+2
   ROM:0002FA00 ; ---------------------------------------------------------------------------
   ROM:0002FA00                 ld      c, 0
   ROM:0002FA02                 ld      b, c
   ROM:0002FA03                 ld      a, [WRAM_VWF_LetterShift]
   ROM:0002FA06                 or      a
   ROM:0002FA07                 jr      z, loc_FA10
   ROM:0002FA09                 srl     d
   ROM:0002FA0B                 rr      e
   ROM:0002FA0D                 dec     a
   ROM:0002FA0E                 jr      nz, loc_FA07+2
   ROM:0002FA10                 ld      a, d
   ROM:0002FA11                 or      b
   ROM:0002FA12                 ld      b, a
   ROM:0002FA13                 ld      c, e
   ROM:0002FA14                 ld      [hl], b
   ROM:0002FA15                 inc     hl
   ROM:0002FA16                 ld      [hl], c
   ROM:0002FA17                 inc     hl
   ROM:0002FA18                 ld      a, h
   ROM:0002FA19                 ld      [WRAM_VWF_CompositingArea0], a
   ROM:0002FA1C                 ld      a, l
   ROM:0002FA1D                 ld      [WRAM_VWF_CompositingArea1], a
   ROM:0002FA20                 pop     hl
   ROM:0002FA21                 ld      d, h
   ROM:0002FA22                 ld      e, l
   ROM:0002FA23                 ld      a, [byte_FF41]
   ROM:0002FA25                 and     2
   ROM:0002FA27                 jr      nz, loc_FA21+2
   ROM:0002FA29                 ld      a, b
   ROM:0002FA2A                 ldi     [hl], a
   ROM:0002FA2B                 ldi     [hl], a
   ROM:0002FA2C                 push    hl
   ROM:0002FA2D                 ld      hl, $10
   ROM:0002FA30                 add     hl, de
   ROM:0002FA31                 ld      a, [byte_FF41]
   ROM:0002FA33                 and     2
   ROM:0002FA35                 jr      nz, loc_FA30+1
   ROM:0002FA37                 ld      a, c
   ROM:0002FA38                 ldi     [hl], a
   ROM:0002FA39                 ldi     [hl], a
   ROM:0002FA3A                 ei
   ROM:0002FA3B                 pop     hl
   ROM:0002FA3C                 pop     de
   ROM:0002FA3D                 pop     bc
   ROM:0002FA3E                 inc     de
   ROM:0002FA3F                 dec     b
   ROM:0002FA40                 jr      nz, loc_F9DF
   ROM:0002FA42                 ld      a, 0
   ROM:0002FA44                 ld      [WRAM_VWF_OldTileMode], a
   ROM:0002FA47                 ld      b, $7B ; '{'
   ROM:0002FA49                 ld      a, [WRAM_VWF_CurrentLetter]
   ROM:0002FA4C                 ld      c, a
   ROM:0002FA4D                 ld      a, [bc]
   ROM:0002FA4E                 inc     a
   ROM:0002FA4F                 ld      b, a
   ROM:0002FA50                 ld      a, [WRAM_VWF_LetterShift]
   ROM:0002FA53                 add     a, b
   ROM:0002FA54                 bit     3, a
   ROM:0002FA56                 jr      z, loc_FA6D
   ROM:0002FA58                 sub     8
   ROM:0002FA5A                 push    af
   ROM:0002FA5B                 ld      a, 1
   ROM:0002FA5D                 ld      [WRAM_VWF_OldTileMode], a
   ROM:0002FA60                 ld      a, [WRAM_VWF_MainScriptHack]
   ROM:0002FA63                 cp      1
   ROM:0002FA65                 jr      nz, unk_FA6C
   ROM:0002FA67                 ld      a, 0
   ROM:0002FA69                 ld      [WRAM_VWF_MainScriptHack], a
   ROM:0002FA6C                 pop     af
   ROM:0002FA6D                 ld      [WRAM_VWF_LetterShift], a
   ROM:0002FA70                 ret
   ROM:0002FA70 ; ---------------------------------------------------------------------------
   ROM:0002FA71                 db   0
   ROM:0002FA72                 db   0
   ROM:0002FA73                 db   0
   ROM:0002FA74                 db   0
   ROM:0002FA75                 db   0
   ROM:0002FA76                 db   0
   ROM:0002FA77                 db   0
   ROM:0002FA78                 db   0
   ROM:0002FA79                 db   0
   ROM:0002FA7A                 db   0
   ROM:0002FA7B                 db   0
   ROM:0002FA7C                 db   0
   ROM:0002FA7D                 db   0
   ROM:0002FA7E                 db   0
   ROM:0002FA7F                 db   0
   ROM:0002FA80                 db   0
   ROM:0002FA81                 db   0
   ROM:0002FA82                 db   0
   ROM:0002FA83                 db   0
   ROM:0002FA84                 db   0
   ROM:0002FA85                 db   0
   ROM:0002FA86                 db   0
   ROM:0002FA87                 db   0

Yowza! That's a lotta NOPs. We need to insert some advice such that we can determine if the second tile needs to be written to or not. It's simple enough...

   ROM:0002F9D3                 ld      b, 8                               06 08
   ROM:0002F9D5                 ld      a, $CF ; '-'                       3E CF
   ROM:0002F9D7                 ld      [WRAM_VWF_CompositingArea0], a     EA C3 C7
   ROM:0002F9DA                 ld      a, $D0 ; '-'                       3E D0
   ROM:0002F9DC                 ld      [WRAM_VWF_CompositingArea1], a     EA C4 C7
       ;that should be a hint as to where this code goes
       push hl                                                             E5
       push bc                                                             C5
       ld      a, [WRAM_VWF_CurrentLetter]                                 FA C1 C7
       ld      h, $7B                                                      26 7B
       ld      l, a                                                        6F
       xor     a                                                           AF
       ld      b, [hl]                                                     46
       ld      a, [WRAM_VWF_LetterShift]                                   FA C2 C7
       add     a, b                                                        80
       bit     3, a                                                        CB 5F
       jr      nz, ClearTile2                                              20 03
       xor     a                                                           AF
       jr      nextSec                                                     18 02
       .ClearTile2: ld     a, 1                                            3E 01
       .nextSec: pop bc                                                    C1
       pop hl                                                              E1
   ROM:0002F9DF                 push    bc                                 C5
   ROM:0002F9E0                 push    de                                 D5
   ROM:0002F9E1                 push    hl                                 E5
       push af                                                             F5
   ROM:0002F9E2                 di                                         F3

Now, by moving back the start of the function we should be able to insert our advice without having to increase any relative jumps. Okay, just one, but only by one byte to fit our new push af... well at least so far. We will have to move back the entry point by 41(dec) bytes from 2F9E2, so it now starts at 2F9B9. That's not enough space. So our second solution is to move the whole routine forward 8 bytes, which we can do because we have 8 bytes to spare. This is a safe operation because the whole routine is composed of relative jumps, and thus position-independant.

Of course, remember to alter the VWF advice routine to call the VWF code. The VWF advice routine is at 2CE2C and the particular call is at 2CE53...

   ROM:0002CE2C                 add     a, a
   ROM:0002CE2D                 jr      nc, 2CE30
   ROM:0002CE2F                 inc     b
   ROM:0002CE30                 sla     a
   ROM:0002CE32                 rl      b
   ROM:0002CE34                 sla     a
   ROM:0002CE36                 rl      b
   ROM:0002CE38                 ld      c, a
   ROM:0002CE39                 ld      hl, $5229
   ROM:0002CE3C                 add     hl, bc
   ROM:0002CE3D                 ld      d, h
   ROM:0002CE3E                 ld      e, l
   ROM:0002CE3F                 pop     hl
   ROM:0002CE40                 ld      a, [WRAM_TextStyle]
   ROM:0002CE43                 cp      0
   ROM:0002CE45                 jr      z, loc_CE53
   ROM:0002CE47                 cp      1
   ROM:0002CE49                 jr      z, loc_CE65
   ROM:0002CE4B                 cp      2
   ROM:0002CE4D                 jr      z, loc_CE79
   ROM:0002CE4F                 cp      3
   ROM:0002CE51                 jr      z, loc_CE8C
   ROM:0002CE53                 call    2F9C1           ; ALTER OPERAND TO BE THIS
   ROM:0002CE56                 jr      2CE64

(This is, partially, a reverting of a change done in the previous patch, since now I know what to do with all that space..)

We now need to gate the second tile drawing code so that it won't touch the second tile if A=0. This is what the tile drawing code currently looks like in v65...

   ROM:0002FA20                 pop     hl
   ROM:0002FA21                 ld      d, h
   ROM:0002FA22                 ld      e, l
   ROM:0002FA23                 ld      a, [byte_FF41]
   ROM:0002FA25                 and     2
   ROM:0002FA27                 jr      nz, loc_FA21+2
   ROM:0002FA29                 ld      a, b
   ROM:0002FA2A                 ldi     [hl], a
   ROM:0002FA2B                 ldi     [hl], a
   ROM:0002FA2C                 push    hl
   ROM:0002FA2D                 ld      hl, $10
   ROM:0002FA30                 add     hl, de
   ROM:0002FA31                 ld      a, [byte_FF41]
   ROM:0002FA33                 and     2
   ROM:0002FA35                 jr      nz, loc_FA30+1
   ROM:0002FA37                 ld      a, c
   ROM:0002FA38                 ldi     [hl], a
   ROM:0002FA39                 ldi     [hl], a
   ROM:0002FA3A                 ei
   ROM:0002FA3B                 pop     hl
   ROM:0002FA3C                 pop     de
   ROM:0002FA3D                 pop     bc
   ROM:0002FA3E                 inc     de
   ROM:0002FA3F                 dec     b
   ROM:0002FA40                 jr      nz, loc_F9DF

(A word of warning: These rom addresses should be summed with 8 if you're looking through the post-patch code because of my routine moving.)

Extra code needs to be inserted. Keep in mind however that we have a limit of 17 bytes before we need to pointcut a jump into some advice.

                                pop     af                 F1
   ROM:0002FA20                 pop     hl                 E1
   ROM:0002FA21                 ld      d, h               54
   ROM:0002FA22                 ld      e, l               5D
                                push    af                 F5
   ROM:0002FA23                 ld      a, [byte_FF41]     F0 41
   ROM:0002FA25                 and     2                  E6 02
   ROM:0002FA27                 jr      nz, loc_FA21+2     20 ??
   ROM:0002FA29                 ld      a, b               78
   ROM:0002FA2A                 ldi     [hl], a            22
   ROM:0002FA2B                 ldi     [hl], a            22
                                pop     af                 F1
   ROM:0002FA2C                 push    hl                 E5
                                push    af                 F5
                                or      a                  B7
                                jr      z, .NoSecondTile   28 ??
   ROM:0002FA2D                 ld      hl, $10            21 10 00
   ROM:0002FA30                 add     hl, de             19
   ROM:0002FA31                 ld      a, [byte_FF41]     F0 41
   ROM:0002FA33                 and     2                  E6 02
   ROM:0002FA35                 jr      nz, loc_FA30+1     20 ??
   ROM:0002FA37                 ld      a, c               79
   ROM:0002FA38                 ldi     [hl], a            22
   ROM:0002FA39                 ldi     [hl], a            22
                            .NoSecondTile:
   ROM:0002FA3A                 ei                         FB
                                pop     af                 F1
   ROM:0002FA3B                 pop     hl
   ROM:0002FA3C                 pop     de
   ROM:0002FA3D                 pop     bc
   ROM:0002FA3E                 inc     de
   ROM:0002FA3F                 dec     b
   ROM:0002FA40                 jr      nz, loc_F9DF       20 94

Oh wow! Only 8 bytes... Let's insert the code and see what happens. It works! Easy patch... NOT! Inserting all those bytes and keeping everything sane was a pain, and really I did it in stages to catch errors before they accumulated.