User:Kmeisthax/Findings/2013/4/23/Tilemap compression

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

A2A and A34 get called to decompress compressed tilemaps from one of two banks into one of two hardware tilemaps.

   ROM:00000A2A ; =============== S U B R O U T I N E =======================================
   ROM:00000A2A
   ROM:00000A2A ; Decompress a tilemap into the hardware's FIRST or SECOND tilemap.
   ROM:00000A2A ;
   ROM:00000A2A ; Params:
   ROM:00000A2A ;
   ROM:00000A2A ;  A = What source bank to read from (bank table is at B18)
   ROM:00000A2A ;
   ROM:00000A2A ; BC = XY coordinates to write to
   ROM:00000A2A ;  E = Index of compressed tilemap to uncompress (map table is at BANKxx:4000)
   ROM:00000A2A
   ROM:00000A2A RunLengthDecompTMap0:                   ; CODE XREF: Banked_RunLengthDecompTMap0+A�p
   ROM:00000A2A                 push    af
   ROM:00000A2B                 ld      hl, $9800
   ROM:00000A2E                 xor     a
   ROM:00000A2F                 ld      [CurrentTilemap], a
   ROM:00000A32                 jr      _RLDecomp_Start
   ROM:00000A34 ; ---------------------------------------------------------------------------
   ROM:00000A34
   ROM:00000A34 RunLengthDecompTMap1:
   ROM:00000A34                 push    af
   ROM:00000A35                 ld      hl, $9C00
   ROM:00000A38                 ld      a, 1
   ROM:00000A3A                 ld      [CurrentTilemap], a
   ROM:00000A3D
   ROM:00000A3D _RLDecomp_Start:                        ; CODE XREF: RunLengthDecompTMap0+8�j
   ROM:00000A3D                 pop     af
   ROM:00000A3E                 push    hl
   ROM:00000A3F                 push    de
   ROM:00000A40                 ld      hl, $B18
   ROM:00000A43                 ld      d, 0
   ROM:00000A45                 ld      e, a
   ROM:00000A46                 add     hl, de
   ROM:00000A47                 ld      a, [hl]
   ROM:00000A48                 rst     $10
   ROM:00000A49                 pop     de
   ROM:00000A4A                 pop     hl
   ROM:00000A4B                 push    de
   ROM:00000A4C                 ld      a, b
   ROM:00000A4D                 and     $1F
   ROM:00000A4F                 ld      b, a
   ROM:00000A50                 ld      a, c
   ROM:00000A51                 and     $1F
   ROM:00000A53                 ld      c, a            ; B &= 0x1F
   ROM:00000A54                 ld      d, 0
   ROM:00000A56                 ld      e, c
   ROM:00000A57                 sla     e
   ROM:00000A59                 rl      d
   ROM:00000A5B                 sla     e
   ROM:00000A5D                 rl      d
   ROM:00000A5F                 sla     e
   ROM:00000A61                 rl      d
   ROM:00000A63                 sla     e
   ROM:00000A65                 rl      d
   ROM:00000A67                 sla     e
   ROM:00000A69                 rl      d               ; DE = (C & 0x1F) * 32
   ROM:00000A6B                 ld      c, b
   ROM:00000A6C                 ld      b, 0            ; BC = (int)B
   ROM:00000A6E                 add     hl, bc
   ROM:00000A6F                 add     hl, de          ; essentially HL = &tilemap[B][C]
   ROM:00000A70                 pop     de              ; restore argument DE
   ROM:00000A71                 push    hl
   ROM:00000A72                 ld      hl, $4000
   ROM:00000A75                 ld      d, 0
   ROM:00000A77                 sla     e
   ROM:00000A79                 rl      d
   ROM:00000A7B                 add     hl, de
   ROM:00000A7C                 ldi     a, [hl]
   ROM:00000A7D                 ld      d, [hl]
   ROM:00000A7E                 ld      e, a            ; DE = ptr_table[E]
   ROM:00000A7F                 pop     hl
   ROM:00000A80                 ld      b, h
   ROM:00000A81                 ld      c, l            ; BC = &tilemap[B][C]
   ROM:00000A82                 ld      a, [de]
   ROM:00000A83                 cp      $FF
   ROM:00000A85                 ret     z               ; FF = return
   ROM:00000A86                 and     3
   ROM:00000A88                 jr      z, _copyLinesMode ; if lower 2 bits are 0
   ROM:00000A8A                 jr      _rllDecompressMode ; if lower 2 bits are not 0
   ROM:00000A8C ; ---------------------------------------------------------------------------
   ROM:00000A8C
   ROM:00000A8C _copyLinesMode:                         ; CODE XREF: RunLengthDecompTMap0+5E�j
   ROM:00000A8C                                         ; RunLengthDecompTMap0+74�j ...
   ROM:00000A8C                 inc     de
   ROM:00000A8D                 ld      a, [de]
   ROM:00000A8E                 cp      $FF
   ROM:00000A90                 ret     z               ; FF = return (again)
   ROM:00000A91                 cp      $FE ; '¦'
   ROM:00000A93                 jr      z, _newLine     ; FE = newline
   ROM:00000A95                 call    vmempoke        ; increment+write A to HL after blanking
   ROM:00000A98                 ld      a, [CurrentTilemap]
   ROM:00000A9B                 call    TileMapLineWrap ; Wrap HL within tilemap A AND within a particular line.
   ROM:00000A9B                                         ; (Assumes you will increment HL between calls)
   ROM:00000A9E                 jr      _copyLinesMode  ; Loop until FF or FE
   ROM:00000AA0 ; ---------------------------------------------------------------------------
   ROM:00000AA0
   ROM:00000AA0 _newLine:                               ; CODE XREF: RunLengthDecompTMap0+69�j
   ROM:00000AA0                 push    de
   ROM:00000AA1                 ld      de, $20 ; ' '
   ROM:00000AA4                 ld      h, b
   ROM:00000AA5                 ld      l, c
   ROM:00000AA6                 add     hl, de
   ROM:00000AA7                 ld      a, [CurrentTilemap]
   ROM:00000AAA                 call    TileMapWrap     ; Wrap HL within tilemap A.
   ROM:00000AAA                                         ;
   ROM:00000AAA                                         ; Clobbers: A (with result H)
   ROM:00000AAD                 ld      b, h
   ROM:00000AAE                 ld      c, l
   ROM:00000AAF                 pop     de
   ROM:00000AB0                 jr      _copyLinesMode
   ROM:00000AB2 ; ---------------------------------------------------------------------------
   ROM:00000AB2
   ROM:00000AB2 _rllDecompressMode:                     ; CODE XREF: RunLengthDecompTMap0+60�j
   ROM:00000AB2                                         ; RunLengthDecompTMap0+AD�j ...
   ROM:00000AB2                 inc     de
   ROM:00000AB3                 ld      a, [de]
   ROM:00000AB4                 cp      $FF
   ROM:00000AB6                 ret     z               ; FF = return
   ROM:00000AB7                 ld      a, [de]         ; useless read
   ROM:00000AB8                 and     $C0 ; '+'
   ROM:00000ABA                 cp      $C0 ; '+'
   ROM:00000ABC                 jp      z, _cmd3        ; Command 3: DecBytes
   ROM:00000ABC                                         ;
   ROM:00000ABC                                         ; Write a sequence of up to 65 decreasing bytes,
   ROM:00000ABC                                         ; starting from the following byte.
   ROM:00000ABC                                         ; (Lower 6 bits of command are count minus 2.)
   ROM:00000ABF                 cp      $80 ; 'Ç'
   ROM:00000AC1                 jp      z, _cmd2        ; Command 2: IncBytes
   ROM:00000AC1                                         ;
   ROM:00000AC1                                         ; Write a sequence of up to 65 increasing bytes,
   ROM:00000AC1                                         ; starting from the following byte.
   ROM:00000AC1                                         ; (Lower 6 bits of command are count minus 2.)
   ROM:00000AC4                 cp      $40 ; '@'
   ROM:00000AC6                 jp      z, _cmd1        ; Command 1: RepeatBytes
   ROM:00000AC6                                         ;
   ROM:00000AC6                                         ; Repeat the following byte upto 65 times.
   ROM:00000AC6                                         ; (Lower 6 bits of command are count minus 2)
   ROM:00000AC9                 push    bc              ; Command 0: CopyBytes
   ROM:00000AC9                                         ;
   ROM:00000AC9                                         ; Copy up to 64 bytes following the command.
   ROM:00000AC9                                         ; (Lower bits of command byte are count minus 1)
   ROM:00000ACA                 ld      a, [de]
   ROM:00000ACB                 inc     a
   ROM:00000ACC                 ld      b, a
   ROM:00000ACD
   ROM:00000ACD _cmd0loop:                              ; CODE XREF: RunLengthDecompTMap0+A9�j
   ROM:00000ACD                 inc     de
   ROM:00000ACE                 ld      a, [de]
   ROM:00000ACF                 call    vmempoke        ; increment+write A to HL after blanking
   ROM:00000AD2                 dec     b
   ROM:00000AD3                 jp      nz, _cmd0loop
   ROM:00000AD6                 pop     bc
   ROM:00000AD7                 jp      _rllDecompressMode
   ROM:00000ADA ; ---------------------------------------------------------------------------
   ROM:00000ADA
   ROM:00000ADA _cmd1:                                  ; CODE XREF: RunLengthDecompTMap0+9C�j
   ROM:00000ADA                 push    bc              ; Command 1: RepeatBytes
   ROM:00000ADA                                         ;
   ROM:00000ADA                                         ; Repeat the following byte upto 65 times.
   ROM:00000ADA                                         ; (Lower 6 bits of command are count minus 2)
   ROM:00000ADB                 ld      a, [de]
   ROM:00000ADC                 and     $3F ; '?'
   ROM:00000ADE                 add     a, 2
   ROM:00000AE0                 ld      b, a
   ROM:00000AE1                 inc     de
   ROM:00000AE2                 ld      a, [de]
   ROM:00000AE3
   ROM:00000AE3 _cmd1Repeat:                            ; CODE XREF: RunLengthDecompTMap0+BD�j
   ROM:00000AE3                 call    vmempoke        ; increment+write A to HL after blanking
   ROM:00000AE6                 dec     b
   ROM:00000AE7                 jp      nz, _cmd1Repeat
   ROM:00000AEA                 pop     bc
   ROM:00000AEB                 jp      _rllDecompressMode
   ROM:00000AEE ; ---------------------------------------------------------------------------
   ROM:00000AEE
   ROM:00000AEE _cmd2:                                  ; CODE XREF: RunLengthDecompTMap0+97�j
   ROM:00000AEE                 push    bc              ; Command 2: IncBytes
   ROM:00000AEE                                         ;
   ROM:00000AEE                                         ; Write a sequence of up to 65 increasing bytes,
   ROM:00000AEE                                         ; starting from the following byte.
   ROM:00000AEE                                         ; (Lower 6 bits of command are count minus 2.)
   ROM:00000AEF                 ld      a, [de]
   ROM:00000AF0                 and     $3F ; '?'
   ROM:00000AF2                 add     a, 2
   ROM:00000AF4                 ld      b, a
   ROM:00000AF5                 inc     de
   ROM:00000AF6                 ld      a, [de]
   ROM:00000AF7
   ROM:00000AF7 _cmd2RepeatAndIncrement:                ; CODE XREF: RunLengthDecompTMap0+D2�j
   ROM:00000AF7                 call    vmempoke        ; increment+write A to HL after blanking
   ROM:00000AFA                 inc     a
   ROM:00000AFB                 dec     b
   ROM:00000AFC                 jp      nz, _cmd2RepeatAndIncrement
   ROM:00000AFF                 pop     bc
   ROM:00000B00                 jp      _rllDecompressMode
   ROM:00000B03 ; ---------------------------------------------------------------------------
   ROM:00000B03
   ROM:00000B03 _cmd3:                                  ; CODE XREF: RunLengthDecompTMap0+92�j
   ROM:00000B03                 push    bc              ; Command 3: DecBytes
   ROM:00000B03                                         ;
   ROM:00000B03                                         ; Write a sequence of up to 65 decreasing bytes,
   ROM:00000B03                                         ; starting from the following byte.
   ROM:00000B03                                         ; (Lower 6 bits of command are count minus 2.)
   ROM:00000B04
   ROM:00000B04 loc_B04:                                ; DATA XREF: ROM:0002E3D0�w
   ROM:00000B04                 ld      a, [de]         ; (ignore the DATA XREF, IDA can't banks)
   ROM:00000B05                 and     $3F ; '?'
   ROM:00000B07                 add     a, 2
   ROM:00000B09                 ld      b, a
   ROM:00000B0A                 inc     de
   ROM:00000B0B                 ld      a, [de]
   ROM:00000B0C
   ROM:00000B0C _cmd3RepeatAndDecrement:                ; CODE XREF: RunLengthDecompTMap0+E7�j
   ROM:00000B0C                 call    vmempoke        ; increment+write A to HL after blanking
   ROM:00000B0F                 dec     a
   ROM:00000B10                 dec     b
   ROM:00000B11                 jp      nz, _cmd3RepeatAndDecrement
   ROM:00000B14                 pop     bc
   ROM:00000B15                 jp      _rllDecompressMode
   ROM:00000B15 ; End of function RunLengthDecompTMap0
   ROM:00000B15
   ROM:00000B15 ; ---------------------------------------------------------------------------
   ROM:00000B18                 db $3E ; >              ; Bank 3E: Compressed tilemaps
   ROM:00000B19                 db $3F ; ?              ; Bank 3F: Compressed tile attributes