home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 26 / AACD 26.iso / AACD / System / XFD / Developer / Sources / ASM / Crunch.a < prev    next >
Encoding:
Text File  |  2001-09-16  |  11.6 KB  |  594 lines

  1. * Programmheader
  2. *
  3. *    Name:        Crunch
  4. *    Author:        SDI
  5. *    Distribution:    PD
  6. *    Description:    XFD external decruncher for recognising Crunch1.x
  7. *    Compileropts:    -
  8. *    Linkeropts:    -
  9. *
  10. * 1.0   22.11.98 : first version
  11. * 1.1   09.12.98 : added normal reloc version
  12. * 1.2   11.12.98 : added SEG version
  13. * 1.3   29.12.98 : added BSS hunk support
  14. * 1.4   19.01.99 : added Data scan
  15. * 1.5   09.03.99 : enforcer hit fixed
  16. * 1.6   01.05.00 : fixed Enforcer hit
  17. * 1.8   18.08.00 : fixed little bug with BSS hunks
  18.  
  19.         INCLUDE    "AINCLUDE:IncDirs.i"
  20.         INCLUDE    "lvo/exec_lib.i"
  21.  
  22.         INCLUDE    "libraries/xfdmaster.i"
  23.         INCLUDE    "exec/memory.i"
  24.         INCLUDE "dos/doshunks.i"
  25.  
  26.         * head function for tests
  27. *        INCLUDE    "xfdExeHead.a"
  28.  
  29. ForeMan        MOVEQ    #-1,D0        ;security
  30.         RTS
  31.  
  32.         DC.L    XFDF_ID
  33.         DC.W    1,0
  34.         DC.L    0,0,S_Crunch
  35.  
  36.         DC.B    "$VER: Crunch 1.7 (18.08.2000) by SDI",0
  37. N_Crunch    DC.B    "Crunch 1.3",0
  38. N_CrunchSeg    DC.B    "Crunch 1.3 Seg",0
  39. N_CrunchData    DC.B    "Crunch 1.3 Data",0
  40.         EVEN
  41.  
  42. S_Crunch    DC.L    S_CrunchSeg    ;next slave
  43.         DC.W    2        ;version
  44.         DC.W    36        ;master version
  45.         DC.L    N_Crunch    ;name
  46.         DC.W    XFDPFF_RELOC
  47.         DC.W    0
  48.         DC.L    RB_Crunch    ;recog buffer
  49.         DC.L    DB_Crunch    ;decrunch buffer
  50.         DC.L    0        ;recog segment
  51.         DC.L    0        ;decrunch segment
  52.         DC.W    0,0
  53.         DC.L    140        ;MinBufSize
  54.  
  55. S_CrunchSeg    DC.L    S_CrunchData    ;next slave
  56.         DC.W    2        ;version
  57.         DC.W    36        ;master version
  58.         DC.L    N_CrunchSeg    ;name
  59.         DC.W    XFDPFF_RELOC
  60.         DC.W    0
  61.         DC.L    RB_CrunchSeg    ;recog buffer
  62.         DC.L    DB_CrunchSeg    ;decrunch buffer
  63.         DC.L    0        ;recog segment
  64.         DC.L    0        ;decrunch segment
  65.         DC.W    0,0
  66.         DC.L    140        ;MinBufSize
  67.  
  68. S_CrunchData    DC.L    0        ;next slaves
  69.         DC.W    2        ;version
  70.         DC.W    38        ;master version
  71.         DC.L    N_CrunchData    ;name
  72.         DC.W    XFDPFF_DATA|XFDPFF_USERTARGET|XFDPFF_RECOGLEN
  73.         DC.W    0
  74.         DC.L    RB_CrunchData    ;recog buffer
  75.         DC.L    DB_CrunchData    ;decrunch buffer
  76.         DC.L    SD_CrunchData    ;recog segment
  77.         DC.L    VD_CrunchData    ;decrunch segment
  78.         DC.W    0,0
  79.         DC.L    12        ;MinBufSize
  80.  
  81. RB_Crunch    CMP.L    #$000003F3,(A0)
  82.         BNE.B    .Exit
  83.         TST.L    4(A0)
  84.         BNE.B    .Exit
  85.         MOVE.L    8(A0),D1
  86.         LSL.L    #2,D1
  87.         CMP.L    D1,D0
  88.         BLO.B    .Exit
  89.         ADD.L    D1,A0
  90.         CMP.L    #$48E7FFFF,7*4(A0)
  91.         BNE.B    .Exit
  92.         CMP.L    #$70004E96,10*4(A0)
  93.         BNE.B    .Exit
  94.         CMP.L    #$584C4E75,20*4(A0)
  95.         BNE.B    .Exit
  96.         CMP.L    #$000003EB,21*4(A0)
  97.         BNE.B    .Exit
  98.         MOVEQ    #1,D0
  99.         RTS
  100. .Exit        MOVEQ    #0,D0
  101.         RTS
  102.  
  103. RB_CrunchSeg    CMP.L    #$000003F3,(A0)
  104.         BNE.B    .Exit
  105.         TST.L    4(A0)
  106.         BNE.B    .Exit
  107.         MOVE.L    8(A0),D1
  108.         LSL.L    #2,D1
  109.         CMP.L    D1,D0
  110.         BLO.B    .Exit
  111.         ADD.L    D1,A0
  112.         CMP.L    #$48E7FFFF,7*4(A0)
  113.         BNE.B    .Exit
  114.         CMP.L    #$70006146,10*4(A0)
  115.         BNE.B    .Exit
  116.         CMP.L    #$202800AC,20*4(A0)
  117.         BNE.B    .Exit
  118.         CMP.L    #$6712E588,21*4(A0)
  119.         BNE.B    .Exit
  120.         MOVEQ    #1,D0
  121.         RTS
  122. .Exit        MOVEQ    #0,D0
  123.         RTS
  124.  
  125. RB_CrunchData    MOVEQ    #0,D0
  126.         CMPI.L    #$43525561,(A0)
  127.         BNE.B    .Exit
  128.         MOVE.L    4(A0),xfdrr_FinalTargetLen(A1)
  129.         MOVE.L    4(A0),xfdrr_MinTargetLen(A1)
  130.         MOVEQ    #1,D0
  131. .Exit        RTS
  132.  
  133. SD_CrunchData    MOVEQ    #0,D0
  134.         CMPI.L    #$43525561,(A0)
  135.         BNE.B    .Exit
  136.         MOVEQ    #1,D0
  137. .Exit        RTS
  138.  
  139. VD_CrunchData    MOVEQ    #12,D1
  140.         ADD.L    8(a0),D1    ;crlen
  141.         CMP.L    D0,D1        ;crlen > buflen ??
  142.         BGT.B    .Exit
  143.         MOVE.L    4(A0),D0
  144.         SUB.L    8(A0),D0    ;cr > uncr ??
  145.         BMI.B    .Exit
  146.         MOVE.L    D1,D0
  147.         RTS
  148. .Exit        MOVEQ    #0,D0
  149.         RTS
  150.  
  151. DB_CrunchSeg    MOVEM.L    D7/A4-A6,-(A7)
  152.         MOVE.L    A0,A5
  153.         MOVE.W    #XFDERR_NOMEMORY,xfdbi_Error(A5)
  154.         MOVE.L    xfdm_ExecBase(A6),A6
  155.         MOVE.L    xfdbi_SourceBuffer(A5),A4
  156.  
  157.         MOVE.L    8(A4),D7
  158.         SUBQ.L    #1,D7        * destination hunk numbers
  159.  
  160.         MOVE.L    A4,A0
  161.         BSR.B    GetCruSegSize
  162.         MOVE.L    D0,xfdbi_TargetBufLen(A5)
  163.         MOVE.L    D0,xfdbi_TargetBufSaveLen(A5)
  164.         MOVE.L    xfdbi_TargetBufMemType(A5),D1
  165.         JSR    _LVOAllocMem(A6)
  166.         MOVE.L    D0,xfdbi_TargetBuffer(A5)
  167.         BEQ.B    .NoMem
  168.  
  169.         MOVE.L    D0,A1
  170.         MOVE.L    A4,A0
  171.         BSR.W    DecrunchCruSeg
  172.  
  173.         CLR.W    xfdbi_Error(A5)
  174.         MOVEQ    #1,D0
  175. .NoMem        MOVEM.L    (A7)+,D7/A4-A6
  176.         RTS
  177.  
  178.         * A0 is buffer
  179.         * D7 is num of hunks
  180. GetCruSegSize    MOVE.L    D6,-(A7)
  181.         MOVE.L    D7,D1
  182.         LSL.L    #2,D1
  183.         MOVE.L    D1,D0
  184.         ADD.L    #$1D0,D1
  185.         LEA    (A0,D1.L),A0    * get first hunk pointer
  186.         ADD.L    #20,D0        * header size
  187.         MOVEQ    #0,D6
  188. .MainLoop    ADD.L    #12,D0        * hunk, size, HUNK_END
  189.         CMP.W    #HUNK_BSS,2(A0)
  190.         BEQ.B    .BSS
  191.         CMP.L    #'CRUa',8(A0)
  192.         BEQ.B    .crunched
  193.         MOVE.L    4(A0),D1
  194.         LSL.L    #2,D1
  195.         ADD.L    D1,D0
  196.         LEA    8(A0,D1.L),A0
  197.         BRA.B    .loopend
  198. .BSS        ADDQ.L    #8,A0
  199.         BRA.B    .loopend
  200. .crunched    ADD.L    12(A0),D0
  201.         MOVE.L    16(A0),D1
  202.         ADDQ.L    #3,D1
  203.         AND.L    #-4,D1
  204.         LEA    20(A0,D1.L),A0
  205. .loopend    BSR.B    .ParseReloc
  206.         ADDQ.L    #1,D6
  207.         CMP.B    D6,D7
  208.         BNE.B    .MainLoop
  209.         MOVE.L    (A7)+,D6
  210.         RTS
  211.  
  212. .ParseReloc    CMP.L    #HUNK_RELOC32,(A0)
  213.         BNE.B    .end
  214.         ADDQ.L    #4,A0
  215.         ADDQ.L    #4,D0        * HUNK_RELOC
  216. .PRLoop        ADDQ.L    #4,D0
  217.         MOVE.L    (A0)+,D1
  218.         BEQ.B    .end
  219.         LSL.L    #2,D1
  220.         ADDQ.L    #4,D1        * related hunk
  221.         LEA    (A0,D1.L),A0
  222.         ADD.L    D1,D0
  223.         BRA.B    .PRLoop
  224. .end        RTS
  225.  
  226.         * A0 is buffer
  227.         * A1 is destination
  228.         * A4 is source buffer
  229.         * D7 is num of hunks
  230. DecrunchCruSeg    MOVEM.L    D2-D6/A2,-(A7)    * hunk size == def size - 512
  231.         MOVE.L    D7,D0        * - reloc space
  232.         LSL.L    #2,D0
  233.         ADD.L    #$1D0,D0
  234.         LEA    (A0,D0.L),A0    * get first hunk pointer
  235.         MOVEQ    #0,D6
  236.         MOVE.L    #HUNK_HEADER,(A1)+
  237.         CLR.L    (A1)+
  238.         MOVE.L    D7,(A1)+    * numhunks
  239.         CLR.L    (A1)+        * starthunk
  240.         MOVE.L    D7,D0
  241.         SUBQ.L    #1,D0
  242.         MOVE.L    D0,(A1)+    * endhunk
  243.         MOVE.L    A1,A2        * start of hunk sizes
  244.         MOVE.L    D7,D0
  245.         LSL.L    #2,D0
  246.         LEA    (A1,D0.L),A1    * skip space
  247. .MainLoop    MOVE.L    (A0)+,(A1)+    * hunk type
  248.         MOVE.L    D6,D0
  249.         LSL.L    #2,D0
  250.         MOVE.L    24(A4,D0.L),D5
  251.         MOVE.L    D5,D4
  252.         AND.L    #$E0000000,D4    * only bits
  253.         AND.L    #$1FFFFFFF,D5    * strip bits
  254.         MOVEQ    #1,D3        * uncrunched
  255.         CMP.W    #HUNK_BSS,-2(A0)
  256.         BEQ.B    .BSS
  257.         CMP.L    #'CRUa',4(A0)
  258.         BEQ.B    .crunched
  259.         MOVE.L    (A0)+,D0
  260.         MOVE.L    D0,(A1)+
  261. .copyhunk    TST.L    D0
  262.         BEQ.B    .loopend
  263.         MOVE.L    (A0)+,(A1)+
  264.         SUBQ.L    #1,D0
  265.         BRA.B    .copyhunk
  266. .BSS        MOVE.L    (A0)+,(A1)+
  267.         BRA.B    .loopend
  268. .crunched    MOVEQ    #0,D3        * crunched
  269.         ADDQ.L    #4,A0
  270.         MOVE.L    4(A0),D0
  271.         LSR.L    #2,D0
  272.         MOVE.L    D0,(A1)+    * store size
  273.         MOVEM.L    A0-A1,-(A7)
  274.         BSR.W    DecrunchCru
  275.         MOVEM.L    (A7)+,A0-A1
  276.         ADD.L    4(A0),A1
  277.         MOVE.L    8(A0),D1
  278.         ADDQ.L    #3,D1
  279.         AND.L    #-4,D1
  280.         LEA    12(A0,D1.L),A0
  281.         SUB.L    #128,D5
  282. .loopend    BSR.B    .CopyReloc
  283.         OR.L    D4,D5        * copy bits
  284.         MOVE.L    D5,(A2)+    * store size
  285.         MOVE.L    #HUNK_END,(A1)+
  286.         ADDQ.L    #1,D6
  287.         CMP.B    D6,D7
  288.         BNE.W    .MainLoop
  289.         MOVEM.L    (A7)+,D2-D6/A2
  290.         RTS
  291.  
  292. .CopyReloc    MOVE.L    A1,D0        * store pointer
  293.         CMP.L    #HUNK_RELOC32,(A0)
  294.         BNE.B    .end
  295.         MOVE.L    (A0)+,(A1)+
  296. .CRLoop        MOVE.L    (A0)+,D1
  297.         MOVE.L    D1,(A1)+
  298.         BEQ.B    .end
  299.         MOVE.L    (A0)+,D2
  300.         SUB.L    D3,D2        * subtract 1, when uncrunched
  301.         MOVE.L    D2,(A1)+    * copy hunkID
  302. .RCLoop        MOVE.L    (A0)+,(A1)+    * copy reloc
  303.         SUBQ.L    #1,D1
  304.         BNE.B    .RCLoop
  305.         BRA.B    .CRLoop
  306. .end        TST.L    D3
  307.         BNE.B    .endR
  308.         MOVE.L    A1,D1    * subtract
  309.         SUB.L    D0,D1    * reloc space
  310.         LSR.L    #2,D1    * from filesize
  311.         SUB.L    D1,D5
  312. .endR        RTS
  313.  
  314. DB_Crunch    MOVEM.L    D5-D7/A2-A6,-(A7)
  315.         MOVE.L    A0,A5
  316.         MOVEQ    #0,D6                * return value
  317.         MOVE.W    #XFDERR_NOMEMORY,xfdbi_Error(A5)
  318.         MOVE.L    xfdm_ExecBase(A6),A6
  319.         MOVE.L    xfdbi_SourceBuffer(A5),A4
  320.  
  321.         MOVE.L    8(A4),D7
  322.         SUBQ.L    #3,D7        * destination hunk numbers
  323.  
  324.         MOVE.L    D7,D1
  325.         LSL.L    #2,D1
  326.         MOVE.L    D1,D0
  327.         LSL.L    #1,D0
  328.         ADD.L    D1,D0    * multiply with 12
  329.         ADD.L    #$1E4,D0
  330.  
  331.         LEA.L    (A4,D0.L),A2
  332.         MOVE.L    4(A2),D5
  333.         MOVE.L    D5,D0
  334.         MOVEQ    #0,D1
  335.         JSR    _LVOAllocMem(A6)
  336.         TST.L    D0
  337.         BEQ.B    .NoMem
  338.         MOVE.L    D0,A3
  339.         
  340.         MOVE.L    D0,A1
  341.         MOVE.L    A2,A0
  342.         BSR.W    DecrunchCru
  343.  
  344.         MOVE.L    A3,A0
  345.         BSR.W    CountCruSize
  346.  
  347.         MOVE.L    D0,xfdbi_TargetBufLen(A5)
  348.         MOVE.L    D0,xfdbi_TargetBufSaveLen(A5)
  349.         MOVE.L    xfdbi_TargetBufMemType(A5),D1
  350.         JSR    _LVOAllocMem(A6)
  351.         MOVE.L    D0,xfdbi_TargetBuffer(A5)
  352.         BEQ.B    .NoMem2
  353.  
  354.         MOVEA.L    A3,A0
  355.         MOVEA.L    D0,A1
  356.         BSR.W    MakeCruFile
  357.  
  358.         CLR.W    xfdbi_Error(A5)
  359.         MOVEQ    #1,D6                * set true
  360. .NoMem2        MOVE.L    D5,D0
  361.         MOVE.L    A3,A1
  362.         JSR    _LVOFreeMem(A6)
  363. .NoMem        MOVE.L    D6,D0
  364.         MOVEM.L    (A7)+,D5-D7/A2-A6
  365.         RTS
  366.  
  367. DB_CrunchData    MOVEM.L    A4-A6,-(A7)
  368.         MOVE.L    A0,A5
  369.         MOVE.L    xfdm_ExecBase(A6),A6
  370.         MOVE.L    xfdbi_SourceBuffer(A5),A4
  371.  
  372.         MOVE.W    #XFDERR_NOMEMORY,xfdbi_Error(A5)
  373.         MOVE.L    4(A4),D0
  374.         MOVE.L    xfdbi_UserTargetBuf(A5),A1
  375.         MOVE.L    D0,xfdbi_TargetBufSaveLen(A5)
  376.  
  377.         BTST.B    #XFDFB_USERTARGET,1+xfdbi_Flags(A5)
  378.         BNE.B    .Decrunch
  379.  
  380.         MOVE.L    D0,xfdbi_TargetBufLen(A5)
  381.         MOVE.L    xfdbi_TargetBufMemType(A5),D1
  382.         JSR    _LVOAllocMem(A6)
  383.         MOVE.L    D0,xfdbi_TargetBuffer(A5)
  384.         BEQ.B    .End
  385.         MOVE.L    D0,A1
  386. .Decrunch    MOVEA.L    A4,A0
  387.         BSR.B    DecrunchCru
  388.         CLR.W    xfdbi_Error(A5)
  389.         MOVEQ    #1,D0
  390. .End        MOVEM.L    (A7)+,A4-A6
  391.         RTS
  392.  
  393. DecrunchCru    MOVEM.L    D2-D6/A2-A4,-(A7)
  394.         MOVEA.L    A1,A2
  395.         ADDA.L    4(A0),A1
  396.         ADDQ.W    #8,A0
  397.         ADDA.L    (A0)+,A0
  398.         LEA    Sub1(PC),A3
  399.         MOVEQ    #8,D5
  400.         MOVE.W    #$00FF,D6
  401.         MOVE.B    -(A0),D4
  402. .Dec1        CMPA.L    A1,A2
  403.         BCS.B    .Dec2
  404.         MOVEM.L    (A7)+,D2-D6/A2-A4
  405.         RTS
  406.  
  407. .Dec2        JSR    (A3)
  408.         BCS.B    .Dec3
  409.         MOVE.B    -(A0),-(A1)
  410.         BRA.B    .Dec1
  411. .Dec3        MOVEQ    #0,D0
  412.         MOVEQ    #0,D1
  413.         MOVEQ    #0,D2
  414.         JSR    (A3)
  415.         BCC.B    .Dec4
  416.         MOVEQ    #0,D1
  417.         MOVEQ    #2,D2
  418.         JSR    (A3)
  419.         BCC.B    .Dec4
  420.         MOVEQ    #1,D1
  421.         MOVEQ    #4,D2
  422.         JSR    (A3)
  423.         BCC.B    .Dec4
  424.         MOVEQ    #1,D1
  425.         MOVEQ    #8,D2
  426.         JSR    (A3)
  427.         BCC.B    .Dec4
  428.         MOVEQ    #2,D1
  429.         MOVEQ    #$000C,D2
  430.         JSR    (A3)
  431.         BCC.B    .Dec4
  432.         MOVEQ    #$0014,D2
  433.         MOVE.B    -(A0),D0
  434.         CMP.B    D6,D0
  435.         BNE.B    .Dec5
  436.         ADD.W    D0,D2
  437.         MOVE.B    -(A0),D0
  438.         ROR.W    #8,D0
  439.         MOVE.B    -(A0),D0
  440.         BRA.B    .Dec5
  441. .Dec4        JSR    (A3)
  442.         ADDX.B    D0,D0
  443.         DBRA    D1,.Dec4
  444. .Dec5        ADD.W    D0,D2
  445.         BNE.B    .Dec6
  446.         MOVEQ    #$0010,D1
  447.         JSR    (A3)
  448.         BCC.B    .Dec7
  449.         MOVEQ    #$0014,D1
  450.         JSR    (A3)
  451.         BCC.B    .Dec7
  452.         MOVEQ    #$0018,D1
  453.         JSR    (A3)
  454.         BCC.B    .Dec7
  455.         MOVEQ    #$001C,D1
  456.         BRA.B    .Dec7
  457. .Dec6        MOVEQ    #0,D1
  458.         JSR    (A3)
  459.         ADDX.B    D1,D1
  460.         JSR    (A3)
  461.         ADDX.B    D1,D1
  462.         LSL.B    #2,D1
  463. .Dec7        MOVEM.W    $A(A3,D1.W),D0/A4    * access data field, A3 points
  464.         MOVEQ    #0,D3            * to Sub1, which is $A bytes
  465.         CMP.W    D5,D0
  466.         BCS.B    .Dec8
  467.         MOVE.B    -(A0),D3
  468.         SUBQ.W    #8,D0
  469. .Dec8        JSR    (A3)
  470.         ADDX.W    D3,D3
  471.         DBRA    D0,.Dec8
  472.         ADDA.L    D3,A4
  473.         ADDA.L    A1,A4
  474.         MOVE.B    (A4),-(A1)
  475. .Dec9        MOVE.B    -(A4),-(A1)
  476.         DBRA    D2,.Dec9
  477.         BRA.W    .Dec1
  478.  
  479. Sub1        ADD.B    D4,D4
  480.         BNE.B    .SubEnd
  481.         MOVE.B    -(A0),D4
  482.         ADDX.B    D4,D4
  483. .SubEnd        RTS
  484.         DC.W    06,$0000,09,$0080,12,$0480,13,$2480,05,$0000
  485.         DC.W    06,$0040,06,$00C0,06,$0140
  486.  
  487.  
  488.         * A0 is buffer
  489.         * D7 is num of hunks
  490. CountCruSize    MOVEM.L    D2/D6,-(A7)
  491.         MOVE.L    D7,D0
  492.         LSL.L    #4,D0        * size, HUNK_CODE, size, HUNK_END --> 4*4 bytes
  493.         ADD.L    #20,D0        * header hunk
  494.         MOVEQ    #0,D6        * hunk counter
  495. .MainLoop    MOVE.L    (A0)+,D1
  496.         MOVE.L    D1,D2
  497.         ANDI.L    #-4,D1        * last bits are CHIP/RELOC markers
  498.         ADD.L    D1,D0        * add that size
  499.         LEA    (A0,D1.L),A0    * skip that part
  500.         BTST    #1,D2        * no reloc hunks
  501.         BEQ.B    .LoopEnd
  502.         ADDQ.L    #4,D0        * place for HUNK_RELOC32
  503. .Reloc        MOVE.W    (A0)+,D1
  504.         ADDQ.L    #4,D0    * add size or empty place for last marker
  505.         TST.W    D1
  506.         BEQ.B    .LoopEnd
  507.         ADDQ.L    #8,D0        * add related hunk and first reloc
  508.         ADDQ.L    #6,A0
  509.         SUBQ.W    #2,D1
  510.         BMI.B    .Reloc
  511. .RelLoop    ADDQ.L    #4,D0
  512.         MOVE.W    (A0)+,D2    * normally we have word offsets
  513.         BNE.B    .Skip
  514.         MOVE.L    (A0)+,D2    * skip LONG offset
  515. .Skip        DBRA.B    D1,.RelLoop
  516.         BRA.B    .Reloc
  517. .LoopEnd    ADDQ.L    #1,D6        * next hunk
  518.         CMP.L    D6,D7
  519.         BNE.B    .MainLoop
  520.         MOVEM.L    (A7)+,D2/D6
  521.         RTS
  522.  
  523.         * A0 is buffer
  524.         * A1 is destination
  525.         * A4 is source file (crunched)
  526.         * D7 is num of hunks
  527. MakeCruFile    MOVEM.L    D2/D6/A4,-(A7)
  528.         MOVE.L    #HUNK_HEADER,(A1)+
  529.         CLR.L    (A1)+
  530.         MOVE.L    D7,(A1)+    * numhunks
  531.         CLR.L    (A1)+        * starthunk
  532.         MOVE.L    D7,D0
  533.         SUBQ.L    #1,D0
  534.         MOVE.L    D0,(A1)+    * endhunk
  535.         LEA    24(A4),A4    * start of sizes
  536. .HeadLoop    MOVE.L    (A4)+,(A1)+    * copy sizes
  537.         DBRA    D0,.HeadLoop
  538.  
  539.         MOVEQ    #0,D6
  540. .MainLoop    MOVE.L    (A0)+,D1
  541.         MOVE.L    D1,D2
  542.         LSR.L    #2,D1
  543.         BEQ.B    .BSS
  544.         MOVE.L    #HUNK_CODE,D0
  545.         BTST    #0,D2
  546.         BEQ.B    .Next
  547.         MOVE.L    #HUNK_DATA,D0
  548. .Next        MOVE.L    D0,(A1)+
  549.         MOVE.L    D1,(A1)+
  550.         BEQ.B    .DoRel
  551.         BRA.B    .CopyHunk
  552. .BSS        MOVE.L    #HUNK_BSS,(A1)+
  553.         MOVE.L    D6,D0
  554.         SUB.L    D7,D0
  555.         LSL.L    #2,D0
  556.         MOVE.L    (A4,D0.L),D0
  557.         AND.L    #$3FFFFFFF,D0
  558.         MOVE.L    D0,(A1)+
  559.         BRA.B    .DoRel
  560. .CopyHunk    MOVE.L    (A0)+,(A1)+
  561.         SUBQ.L    #1,D1
  562.         BNE.B    .CopyHunk
  563. .DoRel        BTST    #1,D2
  564.         BEQ.B    .LoopEnd
  565.         MOVE.L    #HUNK_RELOC32,(A1)+
  566. .Reloc        MOVEQ    #0,D1
  567.         MOVE.W    (A0)+,D1    * copy size
  568.         MOVE.L    D1,(A1)+
  569.         BEQ.B    .LoopEnd
  570.         MOVEQ    #0,D0
  571.         MOVE.W    (A0)+,D0
  572.         MOVE.L    D0,(A1)+    * move hunknum
  573.         MOVEQ    #0,D3
  574.         MOVE.L    (A0)+,D3
  575.         MOVE.L    D3,(A1)+
  576.         SUBQ.W    #2,D1
  577.         BMI.B    .Reloc
  578. .RelLoop    MOVEQ    #0,D0
  579.         MOVE.W    (A0)+,D0
  580.         BNE.B    .Skip
  581.         MOVE.L    (A0)+,D0
  582. .Skip        ADD.L    D0,D3
  583.         MOVE.L    D3,(A1)+
  584.         DBRA    D1,.RelLoop
  585.         BRA.B    .Reloc
  586.  
  587. .LoopEnd    MOVE.L    #HUNK_END,(A1)+
  588.         ADDQ.W    #1,D6
  589.         CMP.W    D6,D7
  590.         BNE.B    .MainLoop
  591.         MOVEM.L    (A7)+,D2/D6/A4
  592.         RTS
  593.         END
  594.