Advertisement
Guest User

Superfast KosM, v2

a guest
Aug 8th, 2015
10
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   #-1,d3                  ; d3 will be desc field switcher.
  192.     clr.w   d3                      ; Low word is zero.
  193.     bra.s   .FetchNewCode
  194. ; ---------------------------------------------------------------------------
  195. .FetchCodeLoop:
  196.     ; Code 1 (Uncompressed byte).
  197.     _Kos_RunBitStream
  198.     move.b  (a0)+,(a1)+
  199.  
  200. .FetchNewCode:
  201.     _Kos_ReadBit
  202.     bcs.s   .FetchCodeLoop          ; If code = 1, branch.
  203.  
  204.     ; Codes 00 and 01.
  205.     moveq   #-1,d5
  206.     lea (a1),a5
  207.     _Kos_RunBitStream
  208.     if _Kos_ExtremeUnrolling==1
  209.     _Kos_ReadBit
  210.     bcs.w   .Code_01
  211.  
  212.     ; Code 00 (Dictionary ref. short).
  213.     _Kos_RunBitStream
  214.     _Kos_ReadBit
  215.     bcs.s   .Copy45
  216.     _Kos_RunBitStream
  217.     _Kos_ReadBit
  218.     bcs.s   .Copy3
  219.     _Kos_RunBitStream
  220.     move.b  (a0)+,d5                ; d5 = displacement.
  221.     adda.w  d5,a5
  222.     move.b  (a5)+,(a1)+
  223.     move.b  (a5)+,(a1)+
  224.     bra.s   .FetchNewCode
  225. ; ---------------------------------------------------------------------------
  226. .Copy3:
  227.     _Kos_RunBitStream
  228.     move.b  (a0)+,d5                ; d5 = displacement.
  229.     adda.w  d5,a5
  230.     move.b  (a5)+,(a1)+
  231.     move.b  (a5)+,(a1)+
  232.     move.b  (a5)+,(a1)+
  233.     bra.w   .FetchNewCode
  234. ; ---------------------------------------------------------------------------
  235. .Copy45:
  236.     _Kos_RunBitStream
  237.     _Kos_ReadBit
  238.     bcs.s   .Copy5
  239.     _Kos_RunBitStream
  240.     move.b  (a0)+,d5                ; d5 = displacement.
  241.     adda.w  d5,a5
  242.     move.b  (a5)+,(a1)+
  243.     move.b  (a5)+,(a1)+
  244.     move.b  (a5)+,(a1)+
  245.     move.b  (a5)+,(a1)+
  246.     bra.w   .FetchNewCode
  247. ; ---------------------------------------------------------------------------
  248. .Copy5:
  249.     _Kos_RunBitStream
  250.     move.b  (a0)+,d5                ; d5 = displacement.
  251.     adda.w  d5,a5
  252.     move.b  (a5)+,(a1)+
  253.     move.b  (a5)+,(a1)+
  254.     move.b  (a5)+,(a1)+
  255.     move.b  (a5)+,(a1)+
  256.     move.b  (a5)+,(a1)+
  257.     bra.w   .FetchNewCode
  258. ; ---------------------------------------------------------------------------
  259.     else
  260.     moveq   #0,d4                   ; d4 will contain copy count.
  261.     _Kos_ReadBit
  262.     bcs.s   .Code_01
  263.  
  264.     ; Code 00 (Dictionary ref. short).
  265.     _Kos_RunBitStream
  266.     _Kos_ReadBit
  267.     addx.w  d4,d4
  268.     _Kos_RunBitStream
  269.     _Kos_ReadBit
  270.     addx.w  d4,d4
  271.     _Kos_RunBitStream
  272.     move.b  (a0)+,d5                ; d5 = displacement.
  273.  
  274. .StreamCopy:
  275.     adda.w  d5,a5
  276.     move.b  (a5)+,(a1)+             ; Do 1 extra copy (to compensate +1 to copy counter).
  277.  
  278. .copy:
  279.     move.b  (a5)+,(a1)+
  280.     dbra    d4,.copy
  281.     bra.w   .FetchNewCode
  282.     endif
  283. ; ---------------------------------------------------------------------------
  284. .Code_01:
  285.     moveq   #0,d4                   ; d4 will contain copy count.
  286.     ; Code 01 (Dictionary ref. long / special).
  287.     _Kos_RunBitStream
  288.     move.b  (a0)+,d6                ; d6 = %LLLLLLLL.
  289.     move.b  (a0)+,d4                ; d4 = %HHHHHCCC.
  290.     move.b  d4,d5                   ; d5 = %11111111 HHHHHCCC.
  291.     lsl.w   #5,d5                   ; d5 = %111HHHHH CCC00000.
  292.     move.b  d6,d5                   ; d5 = %111HHHHH LLLLLLLL.
  293.     if _Kos_LoopUnroll==3
  294.     and.w   d7,d4                   ; d4 = %00000CCC.
  295.     else
  296.     andi.w  #7,d4
  297.     endif
  298.     bne.s   .StreamCopy             ; if CCC=0, branch.
  299.  
  300.     ; special mode (extended counter)
  301.     move.b  (a0)+,d4                ; Read cnt
  302.     beq.s   .Quit                   ; If cnt=0, quit decompression.
  303.     subq.b  #1,d4
  304.     beq.w   .FetchNewCode           ; If cnt=1, fetch a new code.
  305.  
  306.     adda.w  d5,a5
  307.     move.b  (a5)+,(a1)+             ; Do 1 extra copy (to compensate +1 to copy counter).
  308.     move.w  d4,d6
  309.     not.w   d6
  310.     and.w   d7,d6
  311.     add.w   d6,d6
  312.     lsr.w   #_Kos_LoopUnroll,d4
  313.     jmp .largecopy(pc,d6.w)
  314. ; ---------------------------------------------------------------------------
  315. .largecopy:
  316.     rept (1<<_Kos_LoopUnroll)
  317.     move.b  (a5)+,(a1)+
  318.     endm
  319.     dbra    d4,.largecopy
  320.     bra.w   .FetchNewCode
  321. ; ---------------------------------------------------------------------------
  322.     if _Kos_ExtremeUnrolling==1
  323. .StreamCopy:
  324.     adda.w  d5,a5
  325.     move.b  (a5)+,(a1)+             ; Do 1 extra copy (to compensate +1 to copy counter).
  326.     if _Kos_LoopUnroll==3
  327.     eor.w   d7,d4
  328.     else
  329.     eori.w  #7,d4
  330.     endif
  331.     add.w   d4,d4
  332.     jmp .mediumcopy(pc,d4.w)
  333. ; ---------------------------------------------------------------------------
  334. .mediumcopy:
  335.     rept 8
  336.     move.b  (a5)+,(a1)+
  337.     endm
  338.     bra.w   .FetchNewCode
  339.     endif
  340. ; ---------------------------------------------------------------------------
  341. .Quit:
  342.     move.l  a0,(Kos_decomp_queue).w
  343.     move.l  a1,(Kos_decomp_destination).w
  344.     andi.w  #$7FFF,(Kos_decomp_queue_count).w   ; clear decompression in progress bit
  345.     subq.w  #1,(Kos_decomp_queue_count).w
  346.     beq.s   .Done                               ; branch if there aren't any entries remaining in the queue
  347.     lea (Kos_decomp_queue).w,a0
  348.     lea (Kos_decomp_queue+8).w,a1               ; otherwise, shift all entries up
  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.     move.l  (a1)+,(a0)+
  355.  
  356. .Done:
  357.     rts
  358. ; ---------------------------------------------------------------------------
  359. Restore_Kos_Bookmark:
  360.     movem.w (Kos_decomp_stored_registers).w,d0-d6
  361.     movem.l (Kos_decomp_stored_registers+2*7).w,a0-a1/a5
  362.     move.l  (Kos_decomp_bookmark).w,-(sp)
  363.     move.w  (Kos_decomp_stored_SR).w,-(sp)
  364.     moveq   #(1<<_Kos_LoopUnroll)-1,d7
  365.     lea KosDec_ByteMap(pc),a4       ; Load LUT pointer.
  366.     rte
  367. ; End of function Process_Kos_Queue
  368. ; ===========================================================================
  369. Backup_Kos_Registers:
  370.     move    sr,(Kos_decomp_stored_SR).w
  371.     movem.w d0-d6,(Kos_decomp_stored_registers).w
  372.     movem.l a0-a1/a5,(Kos_decomp_stored_registers+2*7).w
  373.     rts
  374. ; ===========================================================================
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement