Want more features on Pastebin? Sign Up, it's FREE!

An Optimized Nemesis decompressor for 68k

By: vladikcomper on Nov 4th, 2013  |  syntax: Motorola 68000 HiSoft Dev  |  size: 5.95 KB  |  views: 306  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print  |  QR code  |  clone
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  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
clone this paste RAW Paste Data