Advertisement
Guest User

Superfast KosM, v2

a guest
Aug 8th, 2015
365
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  2. ; ---------------------------------------------------------------------------
  3. ; Adds a Kosinski Moduled archive to the module queue
  4. ; Inputs:
  5. ; a1 = address of the archive
  6. ; d2 = destination in VRAM
  7. ; ---------------------------------------------------------------------------
  8. Queue_Kos_Module:
  9.     lea (Kos_module_queue).w,a2
  10.     tst.l   (a2)    ; is the first slot free?
  11.     beq.s   Process_Kos_Module_Queue_Init   ; if it is, branch
  12.  
  13. .findFreeSlot:
  14.     addq.w  #6,a2   ; otherwise, check next slot
  15.     tst.l   (a2)
  16.     bne.s   .findFreeSlot
  17.  
  18.     move.l  a1,(a2)+    ; store source address
  19.     move.w  d2,(a2)+    ; store destination VRAM address
  20.     rts
  21. ; End of function Queue_Kos_Module
  22. ; ===========================================================================
  23.  
  24. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  25. ; ---------------------------------------------------------------------------
  26. ; Initializes processing of the first module on the queue
  27. ; ---------------------------------------------------------------------------
  28. Process_Kos_Module_Queue_Init:
  29.     move.w  (a1)+,d3                ; get uncompressed size
  30.     cmpi.w  #$A000,d3
  31.     bne.s   .gotsize
  32.     move.w  #$8000,d3               ; $A000 means $8000 for some reason
  33.  
  34. .gotsize:
  35.     lsr.w   #1,d3
  36.     move.w  d3,d0
  37.     rol.w   #5,d0
  38.     andi.w  #$1F,d0                 ; get number of complete modules
  39.     move.b  d0,(Kos_modules_left).w
  40.     andi.w  #$7FF,d3                ; get size of last module in words
  41.     bne.s   .gotleftover            ; branch if it's non-zero
  42.     subq.b  #1,(Kos_modules_left).w ; otherwise decrement the number of modules
  43.     move.w  #$800,d3                ; and take the size of the last module to be $800 words
  44.  
  45. .gotleftover:
  46.     move.w  d3,(Kos_last_module_size).w
  47.     move.w  d2,(Kos_module_destination).w
  48.     move.l  a1,(Kos_module_queue).w
  49.     addq.b  #1,(Kos_modules_left).w ; store total number of modules
  50.     rts
  51. ; End of function Process_Kos_Module_Queue_Init
  52. ; ===========================================================================
  53.  
  54. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  55. ; ---------------------------------------------------------------------------
  56. ; Processes the first module on the queue
  57. ; ---------------------------------------------------------------------------
  58. Process_Kos_Module_Queue:
  59.     tst.b   (Kos_modules_left).w
  60.     bne.s   .modulesLeft
  61.  
  62. .done:
  63.     rts
  64. ; ---------------------------------------------------------------------------
  65. .modulesLeft:
  66.     bmi.s   .decompressionStarted
  67.     cmpi.w  #4,(Kos_decomp_queue_count).w
  68.     bcc.s   .done                   ; branch if the Kosinski decompression queue is full
  69.     movea.l (Kos_module_queue).w,a1
  70.     lea (Kos_decomp_buffer).w,a2
  71.     bsr.w   Queue_Kos               ; add current module to decompression queue
  72.     ori.b   #$80,(Kos_modules_left).w   ; and set bit to signify decompression in progress
  73.     rts
  74. ; ---------------------------------------------------------------------------
  75. .decompressionStarted:
  76.     tst.w   (Kos_decomp_queue_count).w
  77.     bne.s   .done                   ; branch if the decompression isn't complete
  78.  
  79.     ; otherwise, DMA the decompressed data to VRAM
  80.     andi.b  #$7F,(Kos_modules_left).w
  81.     move.w  #$800,d3
  82.     subq.b  #1,(Kos_modules_left).w
  83.     bne.s   .skip   ; branch if it isn't the last module
  84.     move.w  (Kos_last_module_size).w,d3
  85.  
  86. .skip:
  87.     move.w  (Kos_module_destination).w,d2
  88.     move.w  d2,d0
  89.     add.w   d3,d0
  90.     add.w   d3,d0
  91.     move.w  d0,(Kos_module_destination).w   ; set new destination
  92.     move.l  (Kos_module_queue).w,d0
  93.     move.l  (Kos_decomp_queue).w,d1
  94.     sub.l   d1,d0
  95.     andi.l  #$F,d0
  96.     add.l   d0,d1                   ; round to the nearest $10 boundary
  97.     move.l  d1,(Kos_module_queue).w ; and set new source
  98.     move.l  #Kos_decomp_buffer,d1
  99.     jsr (QueueDMATransfer).w
  100.     tst.b   (Kos_modules_left).w
  101.     bne.s   .exit                   ; return if this wasn't the last module
  102.     lea (Kos_module_queue).w,a0
  103.     lea (Kos_module_queue+6).w,a1
  104.     move.l  (a1)+,(a0)+ ; otherwise, shift all entries up
  105.     move.w  (a1)+,(a0)+
  106.     move.l  (a1)+,(a0)+
  107.     move.w  (a1)+,(a0)+
  108.     move.l  (a1)+,(a0)+
  109.     move.w  (a1)+,(a0)+
  110.     moveq   #0,d0
  111.     move.l  d0,(a0)+                ; and mark the last slot as free
  112.     move.w  d0,(a0)+
  113.     move.l  (Kos_module_queue).w,d0
  114.     beq.s   .exit                   ; return if the queue is now empty
  115.     movea.l d0,a1
  116.     move.w  (Kos_module_destination).w,d2
  117.     bra.w   Process_Kos_Module_Queue_Init
  118.  
  119. .exit:
  120.     rts
  121. ; End of function Process_Kos_Module_Queue
  122. ; ===========================================================================
  123.  
  124. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  125. ; ---------------------------------------------------------------------------
  126. ; Adds Kosinski-compressed data to the decompression queue
  127. ; Inputs:
  128. ; a1 = compressed data address
  129. ; a2 = decompression destination in RAM
  130. ; ---------------------------------------------------------------------------
  131. Queue_Kos:
  132.     move.w  (Kos_decomp_queue_count).w,d0
  133.     lsl.w   #3,d0
  134.     lea (Kos_decomp_queue).w,a3
  135.     move.l  a1,(a3,d0.w)            ; store source
  136.     move.l  a2,4(a3,d0.w)           ; store destination
  137.     addq.w  #1,(Kos_decomp_queue_count).w
  138.     rts
  139. ; End of function Queue_Kos
  140. ; ===========================================================================
  141.  
  142. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  143. ; ---------------------------------------------------------------------------
  144. ; Checks if V-int occured in the middle of Kosinski queue processing
  145. ; and stores the location from which processing is to resume if it did
  146. ; ---------------------------------------------------------------------------
  147. Set_Kos_Bookmark:
  148.     tst.w   (Kos_decomp_queue_count).w
  149.     bpl.s   .done                   ; branch if a decompression wasn't in progress
  150.     move.l  $42(sp),d0              ; check address V-int is supposed to rte to
  151.     cmpi.l  #Process_Kos_Queue.Main,d0
  152.     bcs.s   .done
  153.     cmpi.l  #Process_Kos_Queue.Done,d0
  154.     bcc.s   .done
  155.     move.l  $42(sp),(Kos_decomp_bookmark).w
  156.     move.l  #Backup_Kos_Registers,$42(sp)   ; force V-int to rte here instead if needed
  157.  
  158. .done:
  159.     rts
  160. ; End of function Set_Kos_Bookmark
  161. ; ===========================================================================
  162.  
  163. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
  164. ; ---------------------------------------------------------------------------
  165. ; Processes the first entry in the Kosinski decompression queue
  166. ; ---------------------------------------------------------------------------
  167. Process_Kos_Queue:
  168.     tst.w   (Kos_decomp_queue_count).w
  169.     beq.w   .Done
  170.     bmi.w   Restore_Kos_Bookmark    ; branch if a decompression was interrupted by V-int
  171.  
  172. .Main:
  173.     ori.w   #$8000,(Kos_decomp_queue_count).w   ; set sign bit to signify decompression in progress
  174.     movea.l (Kos_decomp_queue).w,a0
  175.     movea.l (Kos_decomp_destination).w,a1
  176.  
  177.     ; what follows is identical to the normal Kosinski decompressor
  178.     moveq   #(1<<_Kos_LoopUnroll)-1,d7
  179.     if _Kos_UseLUT==1
  180.     moveq   #0,d0
  181.     moveq   #0,d1
  182.     lea KosDec_ByteMap(pc),a4       ; Load LUT pointer.
  183.     endif
  184.     move.b  (a0)+,d0                ; Get desc field low-byte.
  185.     move.b  (a0)+,d1                ; Get desc field hi-byte.
  186.     if _Kos_UseLUT==1
  187.     move.b  (a4,d0.w),d0            ; Invert bit order...
  188.     move.b  (a4,d1.w),d1            ; ... for both bytes.
  189.     endif
  190.     moveq   #7,d2                   ; Set repeat count to 8.
  191.     moveq   #0,d3                   ; d3 will be desc field switcher.
  192.     bra.s   .FetchNewCode
  193. ; ---------------------------------------------------------------------------
  194. .FetchCodeLoop:
  195.     ; Code 1 (Uncompressed byte).
  196.     _Kos_RunBitStream
  197.     move.b  (a0)+,(a1)+
  198.  
  199. .FetchNewCode:
  200.     _Kos_ReadBit
  201.     bcs.s   .FetchCodeLoop          ; If code = 1, branch.
  202.  
  203.     ; Codes 00 and 01.
  204.     moveq   #-1,d5
  205.     lea (a1),a5
  206.     _Kos_RunBitStream
  207.     if _Kos_ExtremeUnrolling==1
  208.     _Kos_ReadBit
  209.     bcs.w   .Code_01
  210.  
  211.     ; Code 00 (Dictionary ref. short).
  212.     _Kos_RunBitStream
  213.     _Kos_ReadBit
  214.     bcs.s   .Copy45
  215.     _Kos_RunBitStream
  216.     _Kos_ReadBit
  217.     bcs.s   .Copy3
  218.     _Kos_RunBitStream
  219.     move.b  (a0)+,d5                ; d5 = displacement.
  220.     adda.w  d5,a5
  221.     move.b  (a5)+,(a1)+
  222.     move.b  (a5)+,(a1)+
  223.     bra.s   .FetchNewCode
  224. ; ---------------------------------------------------------------------------
  225. .Copy3:
  226.     _Kos_RunBitStream
  227.     move.b  (a0)+,d5                ; d5 = displacement.
  228.     adda.w  d5,a5
  229.     move.b  (a5)+,(a1)+
  230.     move.b  (a5)+,(a1)+
  231.     move.b  (a5)+,(a1)+
  232.     bra.w   .FetchNewCode
  233. ; ---------------------------------------------------------------------------
  234. .Copy45:
  235.     _Kos_RunBitStream
  236.     _Kos_ReadBit
  237.     bcs.s   .Copy5
  238.     _Kos_RunBitStream
  239.     move.b  (a0)+,d5                ; d5 = displacement.
  240.     adda.w  d5,a5
  241.     move.b  (a5)+,(a1)+
  242.     move.b  (a5)+,(a1)+
  243.     move.b  (a5)+,(a1)+
  244.     move.b  (a5)+,(a1)+
  245.     bra.w   .FetchNewCode
  246. ; ---------------------------------------------------------------------------
  247. .Copy5:
  248.     _Kos_RunBitStream
  249.     move.b  (a0)+,d5                ; d5 = displacement.
  250.     adda.w  d5,a5
  251.     move.b  (a5)+,(a1)+
  252.     move.b  (a5)+,(a1)+
  253.     move.b  (a5)+,(a1)+
  254.     move.b  (a5)+,(a1)+
  255.     move.b  (a5)+,(a1)+
  256.     bra.w   .FetchNewCode
  257. ; ---------------------------------------------------------------------------
  258.     else
  259.     moveq   #0,d4                   ; d4 will contain copy count.
  260.     _Kos_ReadBit
  261.     bcs.s   .Code_01
  262.  
  263.     ; Code 00 (Dictionary ref. short).
  264.     _Kos_RunBitStream
  265.     _Kos_ReadBit
  266.     addx.w  d4,d4
  267.     _Kos_RunBitStream
  268.     _Kos_ReadBit
  269.     addx.w  d4,d4
  270.     _Kos_RunBitStream
  271.     move.b  (a0)+,d5                ; d5 = displacement.
  272.  
  273. .StreamCopy:
  274.     adda.w  d5,a5
  275.     move.b  (a5)+,(a1)+             ; Do 1 extra copy (to compensate +1 to copy counter).
  276.  
  277. .copy:
  278.     move.b  (a5)+,(a1)+
  279.     dbra    d4,.copy
  280.     bra.w   .FetchNewCode
  281.     endif
  282. ; ---------------------------------------------------------------------------
  283. .Code_01:
  284.     moveq   #0,d4                   ; d4 will contain copy count.
  285.     ; Code 01 (Dictionary ref. long / special).
  286.     _Kos_RunBitStream
  287.     move.b  (a0)+,d6                ; d6 = %LLLLLLLL.
  288.     move.b  (a0)+,d4                ; d4 = %HHHHHCCC.
  289.     move.b  d4,d5                   ; d5 = %11111111 HHHHHCCC.
  290.     lsl.w   #5,d5                   ; d5 = %111HHHHH CCC00000.
  291.     move.b  d6,d5                   ; d5 = %111HHHHH LLLLLLLL.
  292.     if _Kos_LoopUnroll==3
  293.     and.w   d7,d4                   ; d4 = %00000CCC.
  294.     else
  295.     andi.w  #7,d4
  296.     endif
  297.     bne.s   .StreamCopy             ; if CCC=0, branch.
  298.  
  299.     ; special mode (extended counter)
  300.     move.b  (a0)+,d4                ; Read cnt
  301.     beq.s   .Quit                   ; If cnt=0, quit decompression.
  302.     subq.b  #1,d4
  303.     beq.w   .FetchNewCode           ; If cnt=1, fetch a new code.
  304.  
  305.     adda.w  d5,a5
  306.     move.b  (a5)+,(a1)+             ; Do 1 extra copy (to compensate +1 to copy counter).
  307.     move.w  d4,d6
  308.     not.w   d6
  309.     and.w   d7,d6
  310.     add.w   d6,d6
  311.     lsr.w   #_Kos_LoopUnroll,d4
  312.     jmp .largecopy(pc,d6.w)
  313. ; ---------------------------------------------------------------------------
  314. .largecopy:
  315.     rept (1<<_Kos_LoopUnroll)
  316.     move.b  (a5)+,(a1)+
  317.     endm
  318.     dbra    d4,.largecopy
  319.     bra.w   .FetchNewCode
  320. ; ---------------------------------------------------------------------------
  321.     if _Kos_ExtremeUnrolling==1
  322. .StreamCopy:
  323.     adda.w  d5,a5
  324.     move.b  (a5)+,(a1)+             ; Do 1 extra copy (to compensate +1 to copy counter).
  325.     if _Kos_LoopUnroll==3
  326.     eor.w   d7,d4
  327.     else
  328.     eori.w  #7,d4
  329.     endif
  330.     add.w   d4,d4
  331.     jmp .mediumcopy(pc,d4.w)
  332. ; ---------------------------------------------------------------------------
  333. .mediumcopy:
  334.     rept 8
  335.     move.b  (a5)+,(a1)+
  336.     endm
  337.     bra.w   .FetchNewCode
  338.     endif
  339. ; ---------------------------------------------------------------------------
  340. .Quit:
  341.     move.l  a0,(Kos_decomp_queue).w
  342.     move.l  a1,(Kos_decomp_destination).w
  343.     andi.w  #$7FFF,(Kos_decomp_queue_count).w   ; clear decompression in progress bit
  344.     subq.w  #1,(Kos_decomp_queue_count).w
  345.     beq.s   .Done                               ; branch if there aren't any entries remaining in the queue
  346.     lea (Kos_decomp_queue).w,a0
  347.     lea (Kos_decomp_queue+8).w,a1               ; otherwise, shift all entries up
  348.     move.l  (a1)+,(a0)+
  349.     move.l  (a1)+,(a0)+
  350.     move.l  (a1)+,(a0)+
  351.     move.l  (a1)+,(a0)+
  352.     move.l  (a1)+,(a0)+
  353.     move.l  (a1)+,(a0)+
  354.  
  355. .Done:
  356.     rts
  357. ; ---------------------------------------------------------------------------
  358. Restore_Kos_Bookmark:
  359.     movem.w (Kos_decomp_stored_registers).w,d0-d6
  360.     movem.l (Kos_decomp_stored_registers+2*7).w,a0-a1/a5
  361.     move.l  (Kos_decomp_bookmark).w,-(sp)
  362.     move.w  (Kos_decomp_stored_SR).w,-(sp)
  363.     moveq   #(1<<_Kos_LoopUnroll)-1,d7
  364.     lea KosDec_ByteMap(pc),a4       ; Load LUT pointer.
  365.     rte
  366. ; End of function Process_Kos_Queue
  367. ; ===========================================================================
  368. Backup_Kos_Registers:
  369.     move    sr,(Kos_decomp_stored_SR).w
  370.     movem.w d0-d6,(Kos_decomp_stored_registers).w
  371.     movem.l a0-a1/a5,(Kos_decomp_stored_registers+2*7).w
  372.     rts
  373. ; ===========================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement