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

From Wikifang, a definitive guide to Telefang, Dino Device and Bugsite
Revision as of 15:31, 23 April 2013 by Kmeisthax (talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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