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