Advertisement
Guest User

Slightly faster Kosinski decompression M68K

a guest
Dec 30th, 2017
386
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.     ; ===========================================================================
  2. ; ---------------------------------------------------------------------------
  3. ; Kosinski decompression routine
  4. ;
  5. ; Created by vladikcomper
  6. ; Further optimizations and comments by carljr
  7. ; Special thanks to flamewing and MarkeyJester
  8. ; ---------------------------------------------------------------------------
  9.  
  10. _Kos_RunBitStream macro
  11.  
  12.         dbra    d2,@skip\@
  13.  
  14.         moveq   #16-1,d2                        ;  4 set bit counter back to 16, minus 1
  15.  
  16.         move.b  (a0)+,d1                        ;  8 -.
  17.         move.b  (a4,d1.w),d0                    ; 14  :
  18.         lsl.w   #8,d0                           ; 22 -' d0.8-15  <- [a0++] (x-mirror, process left to right)
  19.         move.b  (a0)+,d1                        ;  8 -.
  20.         move.b  (a4,d1.w),d0                    ; 14 -' d0.0-7   <- [a0++] (x-mirror, process left to right)
  21. @skip\@
  22.  
  23.         endm
  24.  
  25. ; ---------------------------------------------------------------------------
  26.  
  27. KosDec:
  28.  
  29.         ; INPUT:
  30.         ;   a0 -> source (compressed data)
  31.         ;   a1 -> destination
  32.  
  33.         ; TRASHES: a3, d0-d2, d4-d7
  34.  
  35.         moveq   #7,d7                           ; used to mask bits 0-2 twice below
  36.         moveq   #0,d1                           ; clear bits 8-15 (index into x-mirror table)
  37.         moveq   #-1,d4                          ; used in "dictionary reference long" for displacement
  38.         moveq   #-1,d6                          ; used in "dictionary reference short" for displacement
  39.  
  40.         lea     KosDec_ByteMap(pc),a4           ;  8 x-mirror table (left to right faster to traverse)
  41.  
  42.         moveq   #16-1,d2                        ;  4 set bit count to 16, minus 1
  43.  
  44.         move.b  (a0)+,d1                        ;  8 -.
  45.         move.b  (a4,d1.w),d0                    ; 14  :
  46.         lsl.w   #8,d0                           ; 22 -' d0.8-15  <- [a0++] (x-mirror, process left to right)
  47.         move.b  (a0)+,d1                        ;  8 -.
  48.         move.b  (a4,d1.w),d0                    ; 14 -' d0.0-7   <- [a0++] (x-mirror, process left to right)
  49.  
  50.         bra.s   KosDec_FetchNewCode             ; 10
  51.  
  52. KosDec_FetchCodeLoop:
  53.  
  54.     ; code 1 (uncompressed byte)
  55.  
  56.         _Kos_RunBitStream
  57.  
  58.         move.b  (a0)+,(a1)+                     ; move 1 uncompressed byte to destination
  59. KosDec_FetchNewCode:
  60.         add.w   d0,d0                           ;  4 get a bit from the bitstream
  61.         bcs.s   KosDec_FetchCodeLoop            ; 10/8 if code == 1, branch
  62.  
  63.     ; codes %00 and %01
  64.  
  65.         _Kos_RunBitStream
  66.  
  67.         add.w   d0,d0                           ; get a bit from the bitstream
  68.         bcs.s   KosDec_Code_01                  ; if code == %01, "dictionary reference long" / special
  69.  
  70.         ; if code == %00, "dictionary reference short"; next 2 bits are count, minus 2 (0-3 -> 2-5)
  71.  
  72.         _Kos_RunBitStream
  73.  
  74.         moveq   #0,d4                           ; d4 will contain copy count
  75.  
  76.         add.w   d0,d0                           ;  4 get a bit from the bitstream
  77.         addx.b  d4,d4                           ;  4
  78.  
  79.         _Kos_RunBitStream
  80.  
  81.         add.w   d0,d0                           ;  4 get a bit from the bitstream
  82.         addx.b  d4,d4                           ;  4
  83.  
  84.         _Kos_RunBitStream
  85.  
  86.         move.b  (a0)+,d6                        ; d6.w = !!!!!!!! DDDDDDDD
  87.  
  88.         lea     (a1,d6),a3                      ; 12 a3 -> [a1.l + d6.w]
  89. KosDec_StreamCopy:
  90.         move.b  (a3)+,(a1)+                     ; do 1 extra copy (to compensate for +1 to copy counter)
  91. KosDec_copy:
  92.         move.b  (a3)+,(a1)+
  93.         dbr     d4,KosDec_copy
  94.  
  95.         bra.s   KosDec_FetchNewCode
  96.  
  97. ; ---------------------------------------------------------------------------
  98.  
  99. KosDec_Code_01:
  100.  
  101.         ; code %01 (dictionary reference long / special)
  102.  
  103.         _Kos_RunBitStream
  104.  
  105.         move.b  (a0)+,d1                        ;  8 d1.w = ........ LLLLLLLL
  106.         move.b  (a0)+,d4                        ;  8 d4.w = !!!!!!!! HHHHHCCC
  107.  
  108.         move.w  d4,d5                           ;  4 d5.w = !!!!!!!! HHHHHCCC
  109.         lsl.w   #5,d5                           ; 16      = !!!HHHHH CCC.....
  110.         move.b  d1,d5                           ;  4      = !!!HHHHH LLLLLLLL
  111.  
  112.         lea     (a1,d5),a3                      ; 12 a3 -> [a1.l + d5.w]
  113.  
  114.         and.w   d7,d4                           ; d4.w = ........ .....CCC
  115.         bne.s   KosDec_StreamCopy       ; if CCC != 0 (1-7 -> 3-9), branch
  116.  
  117.         ; if CCC == 0, special mode (extended counter)
  118.  
  119.         move.b  (a0)+,d4                        ; d4.w <- count_m1 (#/bytes to move, minus 1)
  120.  
  121.         subq.b  #1,d4                           ;  4   count_m1 <= 1 ?
  122.         bls.s   KosDec_Quit                     ; 10/8 yes, so 0 = quit, 1 = fetch a new code (!)
  123.  
  124.         move.w  d4,d1                           ;  4 d1.w =      count_m1 - 1
  125.         not.w   d1                              ;  4      =      -1 * count_m1
  126.         and.w   d7,d1                           ;  4      =     (-1 * count_m1) % 8 (isolate lower 3 bits)
  127.         add.w   d1,d1                           ;  4      = 2 * (-1 * count_m1) % 8 (each instruction = 2 bytes)
  128.  
  129.         lsr.b   #3,d4                           ; 12 d4.w = (count_m1 - 1) / 8
  130.  
  131.         move.b  (a3)+,(a1)+                     ; 12 do 1 extra copy (to compensate for +1 to copy counter)
  132.  
  133.         jmp     KosDec_largecopy(pc,d1.w)       ; 12
  134.  
  135. KosDec_largecopy:
  136.  
  137.         rept 8
  138.         move.b  (a3)+,(a1)+                     ; 12
  139.         endr
  140.         dbf     d4,KosDec_largecopy
  141. KosDec_Quit:
  142.         bcc.w   KosDec_FetchNewCode             ; 10/12 if count_m1 == 1 fetch a new code (!)
  143.  
  144.         rts
  145.  
  146. ; ---------------------------------------------------------------------------
  147. ; A look-up table to invert bits order in desc. field bytes
  148. ; ---------------------------------------------------------------------------
  149.  
  150. KosDec_ByteMap:
  151.  
  152.         dc.b    $00,$80,$40,$C0,$20,$A0,$60,$E0,$10,$90,$50,$D0,$30,$B0,$70,$F0
  153.         dc.b    $08,$88,$48,$C8,$28,$A8,$68,$E8,$18,$98,$58,$D8,$38,$B8,$78,$F8
  154.         dc.b    $04,$84,$44,$C4,$24,$A4,$64,$E4,$14,$94,$54,$D4,$34,$B4,$74,$F4
  155.         dc.b    $0C,$8C,$4C,$CC,$2C,$AC,$6C,$EC,$1C,$9C,$5C,$DC,$3C,$BC,$7C,$FC
  156.         dc.b    $02,$82,$42,$C2,$22,$A2,$62,$E2,$12,$92,$52,$D2,$32,$B2,$72,$F2
  157.         dc.b    $0A,$8A,$4A,$CA,$2A,$AA,$6A,$EA,$1A,$9A,$5A,$DA,$3A,$BA,$7A,$FA
  158.         dc.b    $06,$86,$46,$C6,$26,$A6,$66,$E6,$16,$96,$56,$D6,$36,$B6,$76,$F6
  159.         dc.b    $0E,$8E,$4E,$CE,$2E,$AE,$6E,$EE,$1E,$9E,$5E,$DE,$3E,$BE,$7E,$FE
  160.         dc.b    $01,$81,$41,$C1,$21,$A1,$61,$E1,$11,$91,$51,$D1,$31,$B1,$71,$F1
  161.         dc.b    $09,$89,$49,$C9,$29,$A9,$69,$E9,$19,$99,$59,$D9,$39,$B9,$79,$F9
  162.         dc.b    $05,$85,$45,$C5,$25,$A5,$65,$E5,$15,$95,$55,$D5,$35,$B5,$75,$F5
  163.         dc.b    $0D,$8D,$4D,$CD,$2D,$AD,$6D,$ED,$1D,$9D,$5D,$DD,$3D,$BD,$7D,$FD
  164.         dc.b    $03,$83,$43,$C3,$23,$A3,$63,$E3,$13,$93,$53,$D3,$33,$B3,$73,$F3
  165.         dc.b    $0B,$8B,$4B,$CB,$2B,$AB,$6B,$EB,$1B,$9B,$5B,$DB,$3B,$BB,$7B,$FB
  166.         dc.b    $07,$87,$47,$C7,$27,$A7,$67,$E7,$17,$97,$57,$D7,$37,$B7,$77,$F7
  167.         dc.b    $0F,$8F,$4F,$CF,$2F,$AF,$6F,$EF,$1F,$9F,$5F,$DF,$3F,$BF,$7F,$FF
  168.  
  169. ; ===========================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement