Advertisement
vladikcomper

An Optimized Nemesis decompressor for 68k

Nov 4th, 2013
2,249
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; ==============================================================================
  2. ; ------------------------------------------------------------------------------
  3. ; Nemesis decompression routine
  4. ; ------------------------------------------------------------------------------
  5. ; Optimized by vladikcomper
  6. ; ------------------------------------------------------------------------------
  7.  
  8. NemDec_RAM:
  9.     movem.l d0-a1/a3-a6,-(sp)
  10.     lea NemDec_WriteRowToRAM(pc),a3
  11.     bra.s   NemDec_Main
  12.  
  13. ; ------------------------------------------------------------------------------
  14. NemDec:
  15.     movem.l d0-a1/a3-a6,-(sp)
  16.     lea $C00000,a4      ; load VDP Data Port    
  17.     lea NemDec_WriteRowToVDP(pc),a3
  18.  
  19. NemDec_Main:
  20.     lea $FFFFAA00,a1        ; load Nemesis decompression buffer
  21.     move.w  (a0)+,d2        ; get number of patterns
  22.     bpl.s   @0          ; are we in Mode 0?
  23.     lea $A(a3),a3       ; if not, use Mode 1
  24. @0  lsl.w   #3,d2
  25.     movea.w d2,a5
  26.     moveq   #7,d3
  27.     moveq   #0,d2
  28.     moveq   #0,d4
  29.     bsr.w   NemDec4
  30.     move.b  (a0)+,d5        ; get first byte of compressed data
  31.     asl.w   #8,d5           ; shift up by a byte
  32.     move.b  (a0)+,d5        ; get second byte of compressed data
  33.     move.w  #$10,d6         ; set initial shift value
  34.     bsr.s   NemDec2
  35.     movem.l (sp)+,d0-a1/a3-a6
  36.     rts
  37.  
  38. ; ---------------------------------------------------------------------------
  39. ; Part of the Nemesis decompressor, processes the actual compressed data
  40. ; ---------------------------------------------------------------------------
  41.  
  42. NemDec2:
  43.     move.w  d6,d7
  44.     subq.w  #8,d7           ; get shift value
  45.     move.w  d5,d1
  46.     lsr.w   d7,d1           ; shift so that high bit of the code is in bit position 7
  47.     cmpi.b  #%11111100,d1       ; are the high 6 bits set?
  48.     bcc.s   NemDec_InlineData   ; if they are, it signifies inline data
  49.     andi.w  #$FF,d1
  50.     add.w   d1,d1
  51.     sub.b   (a1,d1.w),d6        ; ~~ subtract from shift value so that the next code is read next time around
  52.     cmpi.w  #9,d6           ; does a new byte need to be read?
  53.     bcc.s   @0          ; if not, branch
  54.     addq.w  #8,d6
  55.     asl.w   #8,d5
  56.     move.b  (a0)+,d5        ; read next byte
  57. @0  move.b  1(a1,d1.w),d1
  58.     move.w  d1,d0
  59.     andi.w  #$F,d1          ; get palette index for pixel
  60.     andi.w  #$F0,d0
  61.  
  62. NemDec_GetRepeatCount:
  63.     lsr.w   #4,d0           ; get repeat count
  64.  
  65. NemDec_WritePixel:
  66.     lsl.l   #4,d4           ; shift up by a nybble
  67.     or.b    d1,d4           ; write pixel
  68.     dbf d3,NemDec_WritePixelLoop; ~~
  69.     jmp (a3)            ; otherwise, write the row to its destination
  70. ; ---------------------------------------------------------------------------
  71.  
  72. NemDec3:
  73.     moveq   #0,d4           ; reset row
  74.     moveq   #7,d3           ; reset nybble counter
  75.  
  76. NemDec_WritePixelLoop:
  77.     dbf d0,NemDec_WritePixel
  78.     bra.s   NemDec2
  79. ; ---------------------------------------------------------------------------
  80.  
  81. NemDec_InlineData:
  82.     subq.w  #6,d6           ; 6 bits needed to signal inline data
  83.     cmpi.w  #9,d6
  84.     bcc.s   @0
  85.     addq.w  #8,d6
  86.     asl.w   #8,d5
  87.     move.b  (a0)+,d5
  88. @0  subq.w  #7,d6           ; and 7 bits needed for the inline data itself
  89.     move.w  d5,d1
  90.     lsr.w   d6,d1           ; shift so that low bit of the code is in bit position 0
  91.     move.w  d1,d0
  92.     andi.w  #$F,d1          ; get palette index for pixel
  93.     andi.w  #$70,d0         ; high nybble is repeat count for pixel
  94.     cmpi.w  #9,d6
  95.     bcc.s   NemDec_GetRepeatCount
  96.     addq.w  #8,d6
  97.     asl.w   #8,d5
  98.     move.b  (a0)+,d5
  99.     bra.s   NemDec_GetRepeatCount
  100.  
  101. ; ---------------------------------------------------------------------------
  102. ; Subroutines to output decompressed entry
  103. ; Selected depending on current decompression mode
  104. ; ---------------------------------------------------------------------------
  105.  
  106. NemDec_WriteRowToVDP:
  107. loc_1502:
  108.     move.l  d4,(a4)         ; write 8-pixel row
  109.     subq.w  #1,a5
  110.     move.w  a5,d4           ; have all the 8-pixel rows been written?
  111.     bne.s   NemDec3         ; if not, branch
  112.     rts
  113. ; ---------------------------------------------------------------------------
  114.  
  115. NemDec_WriteRowToVDP_XOR:
  116.     eor.l   d4,d2           ; XOR the previous row by the current row
  117.     move.l  d2,(a4)         ; and write the result
  118.     subq.w  #1,a5
  119.     move.w  a5,d4
  120.     bne.s   NemDec3
  121.     rts
  122. ; ---------------------------------------------------------------------------
  123.  
  124. NemDec_WriteRowToRAM:
  125.     move.l  d4,(a4)+        ; write 8-pixel row
  126.     subq.w  #1,a5
  127.     move.w  a5,d4           ; have all the 8-pixel rows been written?
  128.     bne.s   NemDec3         ; if not, branch
  129.     rts
  130. ; ---------------------------------------------------------------------------
  131.  
  132. NemDec_WriteRowToRAM_XOR:
  133.     eor.l   d4,d2           ; XOR the previous row by the current row
  134.     move.l  d2,(a4)+        ; and write the result
  135.     subq.w  #1,a5
  136.     move.w  a5,d4
  137.     bne.s   NemDec3
  138.     rts
  139.  
  140. ; ---------------------------------------------------------------------------
  141. ; Part of the Nemesis decompressor, builds the code table (in RAM)
  142. ; ---------------------------------------------------------------------------
  143.  
  144. NemDec4:
  145.     move.b  (a0)+,d0        ; read first byte
  146.  
  147. @ChkEnd:
  148.     cmpi.b  #$FF,d0         ; has the end of the code table description been reached?
  149.     bne.s   @NewPalIndex        ; if not, branch
  150.     rts
  151. ; ---------------------------------------------------------------------------
  152.  
  153. @NewPalIndex:
  154.     move.w  d0,d7
  155.  
  156. @ItemLoop:
  157.     move.b  (a0)+,d0        ; read next byte
  158.     bmi.s   @ChkEnd         ; ~~
  159.     move.b  d0,d1
  160.     andi.w  #$F,d7          ; get palette index
  161.     andi.w  #$70,d1         ; get repeat count for palette index
  162.     or.w    d1,d7           ; combine the two
  163.     andi.w  #$F,d0          ; get the length of the code in bits
  164.     move.b  d0,d1
  165.     lsl.w   #8,d1
  166.     or.w    d1,d7           ; combine with palette index and repeat count to form code table entry
  167.     moveq   #8,d1
  168.     sub.w   d0,d1           ; is the code 8 bits long?
  169.     bne.s   @ItemShortCode      ; if not, a bit of extra processing is needed
  170.     move.b  (a0)+,d0        ; get code
  171.     add.w   d0,d0           ; each code gets a word-sized entry in the table
  172.     move.w  d7,(a1,d0.w)        ; store the entry for the code
  173.     bra.s   @ItemLoop       ; repeat
  174. ; ---------------------------------------------------------------------------
  175.  
  176. @ItemShortCode:
  177.     move.b  (a0)+,d0        ; get code
  178.     lsl.w   d1,d0           ; shift so that high bit is in bit position 7
  179.     add.w   d0,d0           ; get index into code table
  180.     moveq   #1,d5
  181.     lsl.w   d1,d5
  182.     subq.w  #1,d5           ; d5 = 2^d1 - 1
  183.     lea (a1,d0.w),a6        ; ~~
  184.  
  185. @ItemShortCodeLoop:
  186.     move.w  d7,(a6)+        ; ~~ store entry
  187.     dbf d5,@ItemShortCodeLoop   ; repeat for required number of entries
  188.     bra.s   @ItemLoop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement