home *** CD-ROM | disk | FTP | other *** search
/ The CDPD Public Domain Collection for CDTV 3 / CDPDIII.bin / fish / 801-810 / ff802 / fd2asminc / fd2asminc.asm < prev    next >
Assembly Source File  |  1993-01-24  |  25KB  |  998 lines

  1.  
  2. debugbool    =    0        bei TRUE ist Debug-Modus an
  3.  
  4. ;;    *****************************************************************
  5.     *    Programm:    fdAsmInc                *
  6.     *            (.fd-Files in Assemblerincludes kon-    *
  7.     *             vertieren)                *
  8.     *    Copyright:    Freeware © von Hanns Holger Rutz (Tro-    *
  9.     *            picDesign)                *
  10.     *    History:    10.12.92-1.1.93    erste Version mit klei-    *
  11.     *                    nen Fehlern        *
  12.     *            2-13.1.93    Source neu geschrieben    *
  13.     *    Zukunft:    ALL-Option?                *
  14.     *            [created] -> DestDir, wenn Src=Pattern?    *
  15.     *            FROM/M?                    *
  16.     *****************************************************************
  17.  
  18. ;;-- Includes --
  19.  
  20.         incdir    'sys:asm/inc/'
  21.         include    'dos/dosasl.i'
  22.         include    'dos/dosextens.i'
  23.         include    'exec/execbase.i'
  24.         include    'exec/memory.i'
  25.         include    'private/dos_lib.i'    _LVO-File
  26.         include    'private/exec_lib.i'     "   "
  27.  
  28. ;;-- Macros --
  29.  
  30. exec        macro
  31.         if NARG
  32.             move.l    4.w,\1
  33.         else
  34.             movea.l    4.w,lb
  35.         endc
  36.         endm
  37.  
  38. dos        macro
  39.         if NARG
  40.             move.l    gl_DOSBase(gl),\1
  41.         else
  42.             movea.l    gl_DOSBase(gl),lb
  43.         endc
  44.         endm
  45.  
  46. fjsr        macro
  47.         jsr    _LVO\1(lb)
  48.         endm
  49.  
  50. push        macro
  51.         movem.l    \1,-(sp)
  52.         endm
  53.  
  54. pull        macro
  55.         movem.l    (sp)+,\1
  56.         endm
  57.  
  58. rsword        macro
  59. .addr        rs.b    0
  60.         rs.b    .addr&1        eventuell auf WORD-Länge aufrunden
  61.         endm
  62.  
  63. rslong        macro
  64. .addr        rs.b    0
  65.         rs.b    (-.addr)&3    eventuell auf LONG-Länge aufrunden
  66.         endm
  67.  
  68. version        macro
  69.         dc.b    '1.0a'        Version/Revision des Programms
  70.         endm
  71.  
  72. ;;-- Konstanten --
  73.  
  74. lb        equr    a6        Librarybasis
  75. gl        equr    a5        globale Variablen
  76. lo        equr    a4        lokale Variablen
  77.         rsreset
  78. gl_DOSBase    rs.l    1
  79. gl_Result2    rs.l    1
  80. gl_Process    rs.l    1        eigener Process
  81. gl_Arg        rs.l    1        Array für Printf-Argument
  82. gl_InputBuf    rs.b    512        Puffer für Continue-Abfrage
  83. gl_SourceBuf    rs.l    1        Adresse des QuellMems (Ende: LF+##end)
  84. gl_RDArgs    rs.l    1        Ergebnis von ReadArgs()
  85. gl_Array    rs.b    0        Array für ReadArgs()
  86. gl_aFrom    rs.l    1        ..QuellName
  87. gl_aTo          rs.l    1        ..ZielName
  88. gl_aComments      rs.l    1        ..Kommentare/S
  89. gl_aSpaces      rs.l    1        ..Spaces/S
  90. gl_aTabs      rs.l    1        ..Tab(größe)/N
  91. gl_aDec          rs.l    1        ..Dezimal/S
  92. gl_aHex          rs.l    1        ..Hexdezimal/S
  93. GL_AEND          rs.b    0
  94. gl_aSIZEOF    =    GL_AEND-gl_Array
  95. gl_DestOld    rs.l    1        altes ZielDir-Lock
  96. gl_DestDup    rs.l    1        Sicherheits-Lock des Ziels (wenn Dir)
  97. gl_DestName    rs.l    1        *Name des Ziels (von DirLock aus)
  98. gl_State    rs.b    1        allgemeine Flags
  99.         rslong
  100. gl_AnchorPath    rs.b    ap_SIZEOF    AnchorPath der Quelle
  101.         rsword
  102. gl_SIZEOF    rs.b    0
  103.  
  104. FLB_ANCHOR    =    0        Flag: gesetzt->AnchorPath initialisiert
  105. FLB_ABORT    =    1        Flag: gesetzt->Continue unmöglich
  106.  
  107. ;;-- Startup --
  108.  
  109. _Start        move.w    #(gl_SIZEOF/2)-1,d0
  110. .ClearGlobal    clr.w    -(sp)                globales VarMem anlegen
  111.         dbf    d0,.ClearGlobal
  112.         movea.l    sp,gl
  113.         exec
  114.         move.l    ThisTask(lb),gl_Process(gl)    ProcessPtr sichern
  115.         bsr.w    _OpenDOS            DOS.library öffnen
  116.         beq.w    _Quit                ..Fehler
  117.         if debugbool
  118.             lea.l    gl_Array(gl),a0
  119.             lea.l    debugdata(pc),a1
  120.             moveq.l    #gl_aSIZEOF/4-1,d0
  121. .debugloop        move.l    (a1)+,(a0)+
  122.             dbf    d0,.debugloop
  123.         else
  124.             bsr.w    _ReadArgs        Shellargument holen
  125.             beq.w    _CleanUp        ..Fehler
  126.         endc
  127.  
  128. ;;-- Hauptschleife --
  129.  
  130. _Main        bsr.w    _GetSource            Quelle laden
  131.         beq.b    .Error                ..Fehler
  132.         blt.w    .LoopEnd            ..keine Quelle mehr da
  133.         bsr.w    _WriteDest            Zielfile erzeugen
  134.         beq.b    .Error                ..Fehler
  135. .MainCont    bsr.w    _FreeDest            ZielDir evtl. freigeben
  136.         bsr.w    _FreeSource            QuellSpeicher freigeben
  137.         bra.b    _Main
  138.  
  139. .Error        dos
  140.         move.l    gl_Result2(gl),d1
  141.         moveq.l    #0,d2
  142.         fjsr    PrintFault            Fehler ausgeben
  143.         move.l    gl_DestName(gl),d1
  144.         beq.b    .AskCont            ..Ziel bearbeitet
  145.         fjsr    DeleteFile            ..nicht bearb., löschen
  146.         tst.l    d0
  147.         beq.b    .AskCont            ..Fehler
  148.         move.l    gl_DestName(gl),d1
  149.         fjsr    FilePart
  150.         lea.l    _DeleteText(pc),a0
  151.         lea.l    gl_Arg(gl),a1
  152.         move.l    d0,(a1)
  153.         bsr.w    _Printf                Status-Text ausgeben
  154.  
  155. .AskCont    cmpi.l    #ERROR_BREAK,gl_Result2(gl)    ***Break?
  156.         beq.b    .AskEnd                ..ja
  157.         btst.b    #FLB_ABORT,gl_State(gl)        Continue möglich?
  158.         bne.b    .AskEnd                ..nein
  159.         lea.l    _ContinueText(pc),a0
  160.         suba.l    a1,a1
  161.         bsr.w    _Printf                Prompt ausgeben
  162.         fjsr    Input
  163.         move.l    d0,d1
  164.         lea.l    gl_InputBuf(gl),a2
  165.         move.l    a2,d2
  166.         move.l    #512,d3
  167.         fjsr    Read                STDIN abfragen
  168.         bra.b    .AskLoopEnd
  169. .AskLoop    move.b    (a2)+,d1
  170.         cmpi.b    #'y',d1
  171.         beq.b    .MainCont            ..'y', fortfahren
  172.         cmpi.b    #'Y',d1
  173.         beq.b    .MainCont            ..'Y', fortfahren
  174.         cmpi.b    #' ',d1
  175.         beq.b    .AskLoopEnd            ..' ', weitersuchen
  176.         cmpi.b    #$09,d1
  177.         bne.b    .AskEnd                ..nicht fortfahren
  178. .AskLoopEnd    dbf    d0,.AskLoop
  179. .AskEnd
  180.  
  181. .LoopEnd
  182.  
  183. ;;-- Aufräumen --
  184.  
  185. _CleanUp    bsr.w    _FreeDest            ZielDir etc. freigeben
  186.         bsr.w    _FreeSource            QuellMem freigeben
  187.         bsr.w    _FreeArgs            RDArgs freigeben
  188.         bsr.w    _CloseDOS            DOS.library schließen
  189. _Quit        moveq.l    #RETURN_OK,d0
  190.         move.l    gl_Result2(gl),d1
  191.         movea.l    gl_Process(gl),a0
  192.         move.l    d1,pr_Result2(a0)        Result2 setzen
  193.         beq.b    .Exit                ..kein Fehler
  194.         cmpi.l    #ERROR_BREAK,d1
  195.         bne.b    .Error                ..Fehler
  196.         moveq.l    #RETURN_WARN,d0
  197.         bra.b    .Exit
  198. .Error        moveq.l    #RETURN_ERROR,d0
  199. .Exit        lea.l    gl_SIZEOF(sp),sp        Stack korrigieren
  200.         rts                    Programmende
  201.  
  202. ;;-- Globaler Konstantenspeicher --
  203.  
  204. _Version    dc.b    '$VER: fd2AsmInc '
  205.         version
  206.         dc.b    0
  207. _DeleteText    dc.b    'Destination file "%s" deleted.',$0a,0
  208. _ContinueText    dc.b    'Continue? ',0
  209. _LFEndText    dc.b    $0a        \
  210. _EndCmdText    dc.b    '##end',0    /
  211. _EndEnd        even
  212.  
  213. ;;-- DOS.library öffnen --
  214. ;    Out:    cc=eq bei Fehler
  215.  
  216. _OpenDOS    push    d0/d1/a0/a1/lb
  217.         exec
  218.         lea.l    .DOSName(pc),a1
  219.         moveq.l    #INCLUDE_VERSION,d0
  220.         fjsr    OpenLibrary            DOS.library öffnen
  221.         move.l    d0,gl_DOSBase(gl)        ..und Basis sichern
  222.         beq.b    .Error                ..Fehler
  223. .Exit        pull    d0/d1/a0/a1/lb
  224.         rts
  225. .Error        moveq.l    #ERROR_INVALID_RESIDENT_LIBRARY,d1
  226.         move.l    d1,gl_Result2(gl)            Result2 setzen
  227.         clr.b    d0
  228.         bra.b    .Exit
  229.  
  230. .DOSName    DOSNAME
  231.         even
  232.  
  233. ;;-- DOS.library schließen --
  234.  
  235. _CloseDOS    push    d0/d1/a0/a1/lb
  236.         exec
  237.         dos    a1                DOSBase oder NULL
  238.         fjsr    CloseLibrary            Library schließen
  239. .Exit        pull    d0/d1/a0/a1/lb
  240.         rts
  241.  
  242. ;;-- Shellargumente lesen & prüfen --
  243. ;    Out:    cc=eq bei Fehler
  244.  
  245. _ReadArgs    push    d0/d1/a0/a1/lb
  246.         dos
  247.         lea.l    .Template(pc),a0
  248.         move.l    a0,d1
  249.         lea.l    gl_Array(gl),a0
  250.         move.l    a0,d2
  251.         moveq.l    #0,d3                keine eigene RDArgs
  252.         fjsr    ReadArgs            Argumente besorgen
  253.         move.l    d0,gl_RDArgs(gl)        ..und RDArgs sichern
  254.         beq.b    .UsageError            ..Fehler
  255.  
  256. .CheckTabs    move.l    gl_aTabs(gl),d0
  257.         beq.b    .Ok                ..kein Tabs angegeben
  258.         movea.l    d0,a0
  259.         tst.w    (a0)+                Tabs größer als UWORD?
  260.         bne.b    .TabError            ..ja
  261.         tst.w    (a0)                Tabs = NULL?
  262.         beq.b    .TabError            ..ja
  263. .Ok        moveq.l    #-1,d0                cc setzen
  264. .Exit        pull    d0/d1/a0/a1/lb
  265.         rts
  266.  
  267. .TabError    moveq.l    #ERROR_BAD_NUMBER,d0
  268.         move.l    d0,gl_Result2(gl)        Result2 sichern
  269.         bra.b    .PrintUsage
  270.  
  271. .UsageError    bsr.w    _GetIoErr            Result2 sichern
  272.         ;||
  273. ;-- Usage ausgeben --
  274.  
  275. .PrintUsage    lea.l    -32(sp),sp
  276.         move.l    sp,d1
  277.         moveq.l    #32,d2
  278.         fjsr    GetProgramName            Programmnamen
  279.         move.l    sp,d1
  280.         fjsr    FilePart            ..besorgen
  281.         move.l    d0,-(sp)            ..= Argument
  282.         lea.l    .Usage(pc),a0
  283.         move.l    a0,d1
  284.         move.l    sp,d2
  285.         fjsr    VPrintf                Usage ausgeben
  286.         lea.l    32+4(sp),sp
  287.         clr.b    d0
  288.         bra.b    .Exit
  289.  
  290. .Template    dc.b    'FROM/A,TO,COMMENTS/S,SPACES/S,TABS/N/K,DEC/S,HEX/S',0
  291. .Usage        dc.b    'Usage:  %s <from> [<to>] [comments] [spaces] [tabs <1'
  292.         dc.b    '-65535>] [dec] [hex]',$0a,0
  293.         even
  294.  
  295. ;;-- RDArgs freigeben --
  296.  
  297. _FreeArgs    push    d0/d1/a0/a1/lb
  298.         move.l    gl_RDArgs(gl),d1
  299.         beq.b    .Exit                ..keine RDArgs
  300.         dos
  301.         fjsr    FreeArgs            RDArgs freigeben
  302. .Exit        pull    d0/d1/a0/a1/lb
  303.         rts
  304.  
  305. ;;-- IoErr besorgen und sichern --
  306. ;    Out:    d0.l = IoErr, cc=d0.l
  307.  
  308. _GetIoErr    move.l    a0,-(sp)
  309.         movea.l    gl_Process(gl),a0
  310.         move.l    pr_Result2(a0),d0        IoErr in d0
  311.         move.l    d0,gl_Result2(gl)        ..und sichern
  312.         movea.l    (sp)+,a0
  313.         rts
  314.  
  315. ;;-- Quelle suchen, öffnen und lesen --
  316. ;    Out:    cc=eq bei Fehler, cc=lt, wenn Suche erfolglos
  317. ;        hinterher muß _FreeSource aufgerufen werden!
  318.  
  319.         rsreset
  320. gs_OldLock    rs.l    1        altes Dir
  321. gs_SourceFH    rs.l    1        Filehandle der Quelle
  322. gs_SourceLen    rs.l    1        Größe der Quelle
  323. gs_Arg        rs.l    1        reserviert für Printf-Argument
  324.         rsword
  325. gs_SIZEOF    rs.b    0
  326.  
  327. _GetSource    push    d0-d3/a0-a2/lo/lb
  328.         lea.l    gl_AnchorPath(gl),a2        PERMANENT lokal!
  329.         moveq.l    #(gs_SIZEOF/2)-1,d0
  330. .ClearLocal    clr.w    -(sp)                lokales VarMem anlegen
  331.         dbf    d0,.ClearLocal
  332.         movea.l    sp,lo
  333.         dos
  334.         bset.b    #FLB_ANCHOR,gl_State(gl)    AnchorPath schon init.?
  335.         bne.w    .MatchNext            ..ja
  336.         move.l    gl_aFrom(gl),d1
  337.         bset.b    #SIGBREAKB_CTRL_C-8,ap_BreakBits+3-1(a2)    BrkBit
  338.         move.l    a2,d2
  339.         fjsr    MatchFirst            Suche beginnen
  340.         btst.b    #APB_ITSWILD,ap_Flags(a2)    Wildcards in Quelle ?
  341.         bne.b    .CheckSeek            ..ja
  342.         bset.b    #FLB_ABORT,gl_State(gl)        ..nein, Continue unmög.
  343.  
  344. .CheckSeek    tst.l    d0
  345.         bne.w    .MatchError            ..Fehler
  346.         tst.l    ap_Info+fib_DirEntryType(a2)    Directory?
  347.         bge.w    .MatchNext            ..ja
  348.  
  349. .PrintName    lea.l    ap_Info+fib_FileName(a2),a0
  350.         lea.l    gs_Arg(lo),a1
  351.         move.l    a0,(a1)                FileName = Argument
  352.         lea.l    .NameText(pc),a0
  353.         bsr.w    _Printf                Namen ausgeben
  354.  
  355. .AllocMem    exec
  356.         move.l    ap_Info+fib_Size(a2),d0
  357.         move.l    d0,d2
  358.         move.l    d0,gs_SourceLen(lo)        QuellGröße sichern
  359.         addq.l    #_EndEnd-_LFEndText,d0        (für LF+##end,0)
  360.         moveq.l    #MEMF_PUBLIC,d1
  361.         fjsr    AllocVec            Speicher allokieren
  362.         move.l    d0,gl_SourceBuf(gl)        ..und sichern
  363.         beq.w    .NoMemory            ..Fehler
  364.         add.l    d2,d0                Quellende
  365.         movea.l    d0,a0
  366.         lea.l    _LFEndText(pc),a1
  367. .AllocLoop    move.b    (a1)+,(a0)+            LF+##end,0 ans Ende
  368.         bne.b    .AllocLoop
  369.  
  370. .SourceDir    dos
  371.         movea.l    ap_Current(a2),a0
  372.         move.l    an_Lock(a0),d1
  373.         fjsr    CurrentDir            ins QuellDir wechseln
  374.         move.l    d0,gs_OldLock(lo)        ..& alten Lock sichern
  375.  
  376. .OpenSource    lea.l    ap_Info+fib_FileName(a2),a0
  377.         move.l    a0,d1
  378.         move.l    #MODE_OLDFILE,d2
  379.         fjsr    Open                Quelle öffnen
  380.         move.l    d0,gs_SourceFH(lo)        ..und Handle sichern
  381.         beq.w    .OpenError            ..Fehler
  382.  
  383. .ReadSource    move.l    gs_SourceFH(lo),d1
  384.         move.l    gl_SourceBuf(gl),d2
  385.         move.l    gs_SourceLen(lo),d3
  386.         fjsr    Read                QuellCode einlesen
  387.         addq.l    #1,d0
  388.         beq.b    .ReadError            ..Fehler
  389.  
  390. .CheckBreak    exec
  391.         moveq.l    #0,d0
  392.         moveq.l    #0,d1
  393.         fjsr    SetSignal            Signal auslesen
  394.         btst.l    #SIGBREAKB_CTRL_C,d0        Ctrl+C gedrückt?
  395.         bne.b    .Break                ..ja
  396.         moveq.l    #1,d0                ..nein, cc=gt -> OK
  397.         ;||
  398. ;-- Aufräumen und Routine verlassen --
  399. ;    In:    d0.b = cc, der zurückgegeben wird
  400.  
  401. .CleanUp    move.b    d0,d2
  402.         dos
  403.         move.l    gs_SourceFH(lo),d1
  404.         beq.b    .CleanCont
  405.         fjsr    Close                Quelle schließen
  406. .CleanCont    move.l    gs_OldLock(lo),d1
  407.         beq.b    .CleanCont2
  408.         fjsr    CurrentDir            in altes Dir wechseln
  409. .CleanCont2    tst.b    d2                cc setzen
  410.         lea.l    gs_SIZEOF(sp),sp
  411.         pull    d0-d3/a0-a2/lo/lb
  412.         rts
  413.  
  414. .MatchNext    dos
  415.         move.l    a2,d1
  416.         fjsr    MatchNext            Suche fortsetzen
  417.         bra.w    .CheckSeek
  418.  
  419. ;-- MatchFirst() oder MatchNext() Fehler --
  420. ;    In:    d0.l = Fehlercode ^^
  421.  
  422. .MatchError    cmpi.l    #ERROR_NO_MORE_ENTRIES,d0    Suche beendet?
  423.         bne.b    .SeekError            ..nein, Fehler / Break
  424.         dos
  425.         move.l    a2,d1
  426.         fjsr    MatchEnd            ..und AchorPath freig.
  427.         moveq.l    #-1,d0
  428.         bra.b    .CleanUp
  429.  
  430. .Break        move.l    #ERROR_BREAK,gl_Result2(gl)    Returncodes
  431.         bra.b    .Error
  432.  
  433. .NoMemory    moveq.l    #ERROR_NO_FREE_STORE,d0
  434.         move.l    d0,gl_Result2(gl)        Result2 sichern
  435.         bra.b    .Error
  436.  
  437. .SeekError    bset.b    #FLB_ABORT,gl_State(gl)        Cont. nicht mehr mögl.
  438. .ReadError
  439. .OpenError    bsr.w    _GetIoErr            Result2 sichern
  440.         ;||
  441. ;-- Fehlerstatus setzen und Routine verlassen --
  442.  
  443. .Error        clr.b    d0
  444.         bra.b    .CleanUp
  445.  
  446. .NameText    dc.b    '  %s..',0
  447.         even
  448.  
  449. ;;-- QuellSpeicher freigeben --
  450.  
  451. _FreeSource    push    d0/d1/a0/a1/lb
  452.         exec
  453.         movea.l    gl_SourceBuf(gl),a1
  454.         fjsr    FreeVec                Speicher freigeben
  455.         clr.l    gl_SourceBuf(gl)        ..und Ptr auf NULL
  456.         pull    d0/d1/a0/a1/lb
  457.         rts
  458.  
  459. ;;-- Zielfile erzeugen --
  460. ;    Out:    cc=eq bei Fehler
  461. ;        hinterher muß _FreeDest aufgerufen werden!
  462.  
  463.         rsreset
  464. wd_Lock        rs.l    1        Lock des Ziels
  465. wd_DestFH    rs.l    1        FileHandle des Ziels
  466. wd_NewName    rs.b    106+2        Buffer für evtl. neuen Namen
  467. wd_FileInfo    rs.b    fib_SIZEOF    FileInfo-Block für Ziel
  468. wd_Arg        rs.l    1        reserviert für Printf-Arg
  469.         rsword
  470. wd_SIZEOF    rs.b    0
  471.  
  472. _WriteDest    push    d0-d3/a0-a3/lo/lb
  473.         move.w    #(wd_SIZEOF/2)-1,d0
  474. .ClearLocal    clr.w    -(sp)                lokales VarMem anlegen
  475.         dbf    d0,.ClearLocal
  476.         movea.l    sp,lo
  477.         dos
  478.         move.l    gl_aTo(gl),d1            TO angegeben?
  479.         beq.b    .NewName            ..nein
  480.  
  481. .CheckDest    moveq.l    #ACCESS_READ,d2
  482.         fjsr    Lock                ..ja, Lock holen
  483.         move.l    d0,wd_Lock(lo)            ..und sichern
  484.         beq.b    .OldName            ..Fehler
  485.         move.l    d0,d1
  486.         lea.l    wd_FileInfo(lo),a2
  487.         move.l    a2,d2
  488.         fjsr    Examine                FileInfoBlock ausfüllen
  489.         tst.l    d0
  490.         beq.b    .OldName            ..Fehler
  491.         tst.l    fib_DirEntryType(a2)        File?
  492.         blt.b    .OldName            ..ja
  493.         move.l    wd_Lock(lo),d1
  494.         fjsr    DupLock                ..nein, Lock kopieren
  495.         move.l    d0,gl_DestDup(gl)        ..und sichern
  496.         beq.w    .DupLockError            ..Fehler
  497.         move.l    d0,d1
  498.         fjsr    CurrentDir            in Directory wechseln
  499.         move.l    d0,gl_DestOld(gl)        ..& alten Lock sichern
  500.  
  501. .NewName    lea.l    gl_AnchorPath+ap_Info+fib_FileName(gl),a1
  502.         lea.l    wd_NewName(lo),a0
  503.         movea.l    a0,a2
  504.         suba.l    a3,a3                letzer '.' auf NULL
  505. .NewNameLoop    cmpi.b    #'.',(a1)            '.' gefunden?
  506.         bne.b    .NewNameCont            ..nein
  507.         movea.l    a2,a3                ..ja, Adresse merken
  508. .NewNameCont    move.b    (a1)+,(a2)+            Namen kopieren
  509.         bne.b    .NewNameLoop
  510.         move.l    a3,d0                '.'irgendwo gefunden?
  511.         bne.b    .NewNameCont2            ..ja
  512.         lea.l    -1(a2),a3            ..nein, Adr.=Namensende
  513. .NewNameCont2    move.b    #'.',(a3)+            '.i' dranhängen
  514.         move.b    #'i',(a3)+
  515.         clr.b    (a3)
  516.         bra.b    .OpenDest
  517.  
  518. .OldName    movea.l    gl_aTo(gl),a0            Name in a0
  519.         ;||
  520. ;-- Lock freigeben, File öffnen und beschreiben --
  521. ;    In:    a0 = *Name
  522.  
  523. .OpenDest    movea.l    a0,gl_DestName(gl)
  524.         move.l    wd_Lock(lo),d1            Lock
  525.         beq.b    .OpenCont            ..nicht vorhanden
  526.         fjsr    UnLock                ..freigeben
  527. .OpenCont
  528.         move.l    gl_DestName(gl),d1
  529.         fjsr    FilePart            Filenamen extrahieren
  530.         lea.l    .NameText(pc),a0
  531.         lea.l    wd_Arg(lo),a1
  532.         move.l    d0,(a1)                ..= Argument
  533.         bsr.w    _Printf                Namen ausgeben
  534.  
  535.         movea.l    gl_DestName(gl),d1
  536.         move.l    #MODE_NEWFILE,d2
  537.         fjsr    Open                Datei öffnen
  538.         move.l    d0,wd_DestFH(lo)        ..und Handle sichern
  539.         beq.b    .OpenError            ..Fehler
  540. .WriteDest    bsr.w    _ProcessData            File erzeugen
  541.         beq.b    .Error                ..Fehler
  542.  
  543. .CheckBreak    exec
  544.         moveq.l    #0,d0
  545.         moveq.l    #0,d1
  546.         fjsr    SetSignal            Signal auslesen
  547.         btst.l    #SIGBREAKB_CTRL_C,d0        Ctrl+C gedrückt?
  548.         bne.b    .Break                ..ja
  549.  
  550. .PrintLF    dos
  551.         lea.l    .LineFeedText(pc),a0
  552.         move.l    a0,d1
  553.         fjsr    PutStr                ..ok, LineFeed ausgeben
  554.         moveq.l    #-1,d0                ..und OK-status setzen
  555.         bra.b    .CleanUp
  556.  
  557. ;-- Fehlerstatus setzen und raus --
  558.  
  559. .Error        clr.b    d0
  560.         ;||
  561. ;-- Aufräumen und Routine verlassen --
  562. ;    In:    d0.b = cc, der zurückgegeben wird
  563.  
  564. .CleanUp    move.b    d0,d2
  565.         dos
  566.         move.l    wd_DestFH(lo),d1
  567.         beq.b    .CleanCont
  568.         fjsr    Close
  569. .CleanCont    tst.b    d2
  570.         lea.l    wd_SIZEOF(sp),sp
  571.         pull    d0-d3/a0-a3/lo/lb
  572.         rts
  573.  
  574. .OpenError
  575. .DupLockError    bsr.w    _GetIoErr            Result2 sichern
  576.         bra.b    .Error
  577.  
  578. .Break        move.l    #ERROR_BREAK,gl_Result2(gl)    Returncodes
  579.         bra.b    .Error
  580.  
  581. .NameText    dc.b    $08,$08,'  ',$0a,$9b,'A',$9b,'36C%s..',0
  582. .LineFeedText    dc.b    $08,$08,'  ',$0a,0
  583.  
  584. ;;-- ZielDir etc. freigeben --
  585.  
  586. _FreeDest    push    d0/d2/a0/a1/lb
  587.         dos
  588.         move.l    gl_DestOld(gl),d1
  589.         beq.b    .CleanCont
  590.         fjsr    CurrentDir
  591.         clr.l    gl_DestOld(gl)
  592. .CleanCont    move.l    gl_DestDup(gl),d1
  593.         beq.b    .Exit
  594.         fjsr    UnLock
  595.         clr.l    gl_DestDup(gl)
  596. .Exit        clr.l    gl_DestName(gl)            = Zielaktivtäten beend.
  597.         pull    d0/d2/a0/a1/lb
  598.         rts
  599.  
  600. ;;-- Quelle in Ziel konvertieren --
  601. ;    In:    d0 = *DestFH
  602. ;    Out:    cc=eq bei Fehler
  603.  
  604.         rsreset
  605. pd_DestFH    rs.l    1        FileHandle für's Ziel
  606. pd_SrcLine    rs.l    1        aktuelle QuellZeile (nur Pass2)
  607. pd_Longest    rs.w    1        längster Funktionsname (inkl. _LVO+Spc)
  608. pd_Offset    rs.l    1        aktueller Funktionsoffset
  609. pd_Tab        rs.b    1        \
  610. pd_Space    rs.b    1        /
  611. pd_Buffer    rs.b    3        '=' [+Space|Tab] + '-'
  612. pd_HBuffer    rs.b    10        Puffer für HexOffset [$xxx+LF]
  613. pd_DBuffer    rs.b    11        Puffer für DezOffset [xxx+LF]
  614.         rsword
  615. pd_SIZEOF    rs.b    0
  616.  
  617. _ProcessData    push    d0-d3/a0-a3/lo/lb
  618.         moveq.l    #(pd_SIZEOF/2)-1,d1
  619. .ClearLocal    clr.w    -(sp)                lokales VarMem anlegen
  620.         dbf    d1,.ClearLocal
  621.         movea.l    sp,lo
  622.         move.l    d0,pd_DestFH(lo)        FileHandle sichern
  623.         move.w    #$09<<8!' ',pd_Tab(lo)
  624.         move.b    #'=',pd_Buffer(lo)
  625.         exec
  626.         move.l    LIB_VERSION(lb),d0
  627.         move.w    SoftVer(lb),d0
  628.         cmpi.l    #37<<16!300,d0            A600 vorhanden?
  629.         beq.w    .A600Found            ..ja
  630.  
  631. .CheckSource    dos
  632.         movea.l    gl_SourceBuf(gl),a0        QuellAdresse
  633.         moveq.l    #1,d0
  634.         move.l    d0,pd_SrcLine(lo)        Zeilennummer resetten
  635. .CheckLoop    cmpi.b    #'*',(a0)
  636.         beq.b    .CheckNextLine            ..Kommentar
  637.         cmpi.b    #'#',(a0)
  638.         beq.b    .CheckEndCmd            ..auf ##end testen
  639.         moveq.l    #'(',d0
  640.         move.l    a0,d1
  641.         neg.l    d1
  642.         bsr.w    _Search                nach '(' suchen
  643.         beq.w    .LineTempError            ..Fehler
  644.         add.l    a0,d1                Funktionsnamen-Länge+1
  645.         addq.l    #-1+5,d1            -1+_LVO und Space
  646.         move.l    d1,d0
  647.         clr.w    d0
  648.         tst.l    d0                Zeile zu Lang (>UWORD)?
  649.         bne.w    .LineLongError            ..ja
  650.         cmp.w    pd_Longest(lo),d1        ..längste bisher?
  651.         blt.b    .CheckNextLine            ..nein
  652.         move.w    d1,pd_Longest(lo)        ..ja, sichern
  653. .CheckNextLine    bsr.w    .LineFeed            nächste Zeile
  654.         bra.b    .CheckLoop
  655.  
  656. .CheckEndCmd    lea.l    _EndCmdText(pc),a1
  657.         bsr.w    _Compare            auf ##end testen
  658.         beq.b    .CheckNextLine            ..liegt nicht vor
  659.  
  660. .WriteData    movea.l    gl_SourceBuf(gl),a0        QuellAdresse
  661.         moveq.l    #1,d0
  662.         move.l    d0,pd_SrcLine(lo)        Zeilennummer resetten
  663. .WriteLoop    cmpi.b    #'*',(a0)
  664.         beq.b    .WriteComment            ..Kommentar
  665.         cmpi.b    #'#',(a0)
  666.         bne.b    .WriteFunc            ..Funktion
  667.         movea.l    a0,a2
  668.         lea.l    .BiasText(pc),a1
  669.         bsr.w    _Compare            ##bias?
  670.         exg.l    a0,a2
  671.         beq.b    .WriteEndCmd            ..nein
  672.         moveq.l    #$0a,d0
  673.         bsr.w    _Search
  674.         clr.b    (a0)                ..ja, NULLterminieren
  675.         movea.l    a0,a3
  676.         move.l    a2,d1
  677.         lea.l    pd_Offset(lo),a0
  678.         move.l    a0,d2
  679.         fjsr    StrToLong            Offset sichern
  680.         tst.l    d0
  681.         blt.w    .LineKeyError            ..Fehler
  682.         movea.l    a3,a0
  683.         move.b    #$0a,(a0)            LF wieder herstellen
  684. .WriteNextLine    bsr.w    .LineFeed            nächste Zeile
  685.         bra.b    .WriteLoop
  686.  
  687. .WriteEndCmd    lea.l    _EndCmdText(pc),a1
  688.         bsr.w    _Compare            ##end?
  689.         beq.b    .WriteNextLine            ..nein
  690.  
  691. ;-- Ok-Status setzen und raus --
  692.  
  693. .Ok        moveq.l    #-1,d0                ..ja, cc=ne
  694. .Exit        lea.l    pd_SIZEOF(sp),sp
  695.         pull    d0-d3/a0-a3/lo/lb
  696.         rts
  697.  
  698. .WriteComment    movea.l    a0,a1
  699.         move.l    a0,d0
  700.         neg.l    d0
  701.         bsr.w    .LineFeed            zur nächsten Zeile
  702.         tst.l    gl_aComments(gl)        Kommentare gewünscht?
  703.         beq.b    .WriteLoop            ..nein
  704.         add.l    a0,d0                Kommentarlänge
  705.         exg.l    a1,a0
  706.         bsr.w    .Write                Kommentar schreiben
  707.         exg.l    a1,a0
  708.         beq.w    .WriteError            ..Fehler
  709.         bra.b    .WriteLoop
  710.  
  711. .WriteFunc    movea.l    a0,a1                hier DURCHGEHEND lokal!
  712.         lea.l    .LVOText(pc),a0
  713.         moveq.l    #.LVOEnd-.LVOText,d0
  714.         bsr.w    .Write                _LVO schreiben
  715.         beq.w    .WriteError
  716.         move.l    a1,d1
  717.         neg.l    d1
  718.         movea.l    a1,a0
  719.         moveq.l    #'(',d0
  720.         bsr.w    _Search                nach '(' suchen
  721. ;        beq.b    .LineTempError        evtl. Fehler in Pass1 abgefang.
  722.         subq.l    #1,a0
  723.         add.l    a0,d1                Funktionsnamen-Länge
  724.         move.l    d1,d0
  725.         movea.l    a1,a0
  726.         bsr.w    .Write                FuncName schreiben
  727.         beq.w    .WriteError
  728.         addq.w    #4,d1                +_LVO
  729.         moveq.l    #0,d2                Tabs
  730.         moveq.l    #0,d3                Spaces
  731. .CheckTabs    move.l    gl_aTabs(gl),d0
  732.         beq.b    .CheckSpaces            ..keine Tabs gewünscht
  733.         movea.l    d0,a0
  734.         move.l    d1,d0
  735.         divu.w    2(a0),d0            d0.w=Tabs für FuncName
  736.         move.w    pd_Longest(lo),d2        d2.w=Breite
  737.         tst.l    gl_aSpaces(gl)
  738.         bne.b    .TabCont            ..Spaces gewünscht
  739.         subq.w    #1,d2
  740.         add.l    (a0),d2                d2 wird aufgerundet
  741. .TabCont    divu.w    2(a0),d2            d2.w=Breite in Tabs
  742.         sub.w    d0,d2                d2.w=benötigte Tabs
  743.         beq.b    .Spaces                ..keine vorhanden
  744.         tst.l    gl_aSpaces(gl)
  745.         beq.b    .FuncSpace            ..keine Spcs gewünscht
  746.         move.l    d2,d3
  747.         swap.w    d3                d3=restliche Spaces
  748.         bra.b    .FuncSpace
  749. .CheckSpaces    tst.l    gl_aSpaces(gl)
  750.         beq.b    .FuncSpace            ..gar kein Leerraum
  751. .Spaces        move.w    pd_Longest(lo),d3
  752.         sub.w    d1,d3                d3=Spacs(Width-FuncLen)
  753.  
  754. .FuncSpace    lea.l    pd_Tab(lo),a0
  755.         moveq.l    #1,d0
  756.         bra.b    .TabsEndLoop
  757. .TabsLoop    bsr.w    .Write                Tabulator schreiben
  758.         beq.w    .WriteError            ..Fehler
  759. .TabsEndLoop    dbf    d2,.TabsLoop
  760.         addq.l    #1,a0
  761.         bra.b    .SpacesEndLoop
  762. .SpacesLoop    bsr.w    .Write                Space schreiben
  763.         beq.w    .WriteError            ..Fehler
  764. .SpacesEndLoop    dbf    d3,.SpacesLoop
  765.  
  766. .EquStuff    moveq.l    #2,d0                nur '='
  767.         lea.l    pd_Buffer(lo),a0
  768.         move.b    #' ',1(a0)            auch Space
  769.         tst.l    gl_aSpaces(gl)
  770.         bne.b    .EquNSpace
  771.         tst.l    gl_aTabs(gl)
  772.         beq.b    .WriteEqu
  773.         move.b    #$09,1(a0)            auch Tab
  774. .EquNSpace    addq.b    #1,d0                '=' und Tab/Space
  775. .WriteEqu    move.b    #'-',-1(a0,d0.w)        + Vorzeichen
  776.         bsr.w    .Write                ..schreiben
  777.         beq.b    .WriteError            ..Fehler
  778.  
  779. .OffsetStuff    lea.l    pd_HBuffer(lo),a2
  780.         movea.l    a2,a0
  781.         move.l    pd_Offset(lo),d0
  782.         bsr.w    _ULong2Hex            Offset -> Hex
  783.         move.b    d0,d1
  784.         lea.l    pd_DBuffer(lo),a0
  785.         move.l    pd_Offset(lo),d0
  786.         bsr.w    _ULong2Dec            Offset -> Dez
  787.         tst.l    gl_aDec(gl)
  788.         bne.b    .CheckHex            ..Dec gewünscht
  789.         tst.l    gl_aHex(gl)
  790.         bne.b    .Hex                ..nur Hex
  791. .Shortest    cmp.b    d0,d1                Dec oder Hex nehmen?
  792.         bgt.b    .WriteOffset            ..Dec ist kürzer
  793. .Hex        movea.l    a2,a0                ..Hex ist
  794.         move.b    d1,d0                ..kürzer
  795.         bra.b    .WriteOffset
  796. .CheckHex    tst.l    gl_aHex(gl)
  797.         bne.b    .Shortest            ..Dec oder Hex
  798. .WriteOffset    move.b    #$0a,(a0,d0.w)            Offset + LF
  799.         addq.b    #1,d0
  800.         bsr.b    .Write                ..schreiben
  801.         beq.b    .WriteError            ..Fehler
  802.         addq.l    #6,pd_Offset(lo)        nächster Offset
  803.  
  804.         movea.l    a1,a0                Lokalität beendet!
  805.         bra.w    .WriteNextLine
  806.  
  807. .A600Found    lea.l    .A600Text(pc),a0
  808.         moveq.l    #.A600End-.A600Text,d0
  809.         bsr.b    .Write                Boykott-Text schreiben
  810.         bra.w    .Ok
  811.  
  812. .WriteError    bsr.w    _GetIoErr            Result2 sichern
  813.         bra.b    .Error
  814.  
  815. .LineLongError    moveq.l    #ERROR_LINE_TOO_LONG,d0
  816.         bra.b    .LineError
  817.  
  818. .LineTempError    moveq.l    #ERROR_BAD_TEMPLATE,d0
  819.         bra.b    .LineError
  820.  
  821. .LineKeyError    moveq.l    #ERROR_KEY_NEEDS_ARG,d0
  822.         ;||
  823. ;-- Result2 sichern und Zeilennummer ausgeben --
  824. ;    In:    d0.l = Result2
  825.  
  826. .LineError    move.l    d0,gl_Result2(gl)        Result2 sichern
  827.         lea.l    .LineText(pc),a0
  828.         lea.l    pd_SrcLine(lo),a1
  829.         bsr.w    _Printf                Fehlerzeile ausgeben
  830.         ;||
  831. ;-- Fehlerstatus setzen und raus --
  832.  
  833. .Error        clr.b    d0
  834.         bra.w    .Exit
  835.  
  836. ;-- Nächste (nicht leere) Zeile eines Strings suchen --
  837. ;    In:    a0 = String
  838. ;    Out:    a0 = *NextLine
  839. ;    ACHTUNG: a0 ist nicht NULLterminiert!
  840.  
  841. .LineFeed
  842. .LineFLoop1    cmpi.b    #$0a,(a0)+            Ende der Zeile?
  843.         bne.b    .LineFLoop1            ..nein
  844. .LineFLoop2    addq.l    #1,pd_SrcLine(lo)        Zeilennummer erhöhen
  845.         cmpi.b    #$0a,(a0)+            Leerzeile?
  846.         beq.b    .LineFLoop2            ..ja
  847.         subq.l    #1,a0                ..nein, Adresse korrig.
  848.         rts
  849.  
  850. ;-- String ins Ziel schreiben --
  851. ;    In:    a0 = String, d0.l = Stringlänge
  852. ;    Out:    cc=eq bei Fehler
  853.  
  854. .Write        push    d0-d3/a0/a1/lb
  855.         dos
  856.         move.l    pd_DestFH(lo),d1
  857.         move.l    a0,d2
  858.         move.l    d0,d3
  859.         fjsr    Write                Daten schreiben
  860.         addq.l    #1,d0                cc setzen
  861.         pull    d0-d3/a0/a1/lb
  862.         rts
  863.  
  864. .LineText    dc.b    '(Line %ld:) ',0
  865. .BiasText    dc.b    '##bias',0
  866. .A600Text    dc.b    "Sorry, but u got a fuckin' A600!",$0a
  867. .A600End
  868. .LVOText    dc.b    '_LVO'
  869. .LVOEnd        even
  870.  
  871. ;;-- Zeichen in Stringzeile suchen (LCase <> UCase) --
  872. ;    In:    d0.b = Char, a0 = *String
  873. ;    Out:    cc=eq bei Fehler und a0 = *LineFeed, sonst a0 = *NachChar
  874. ;    ACHTUNG: a0 ist nicht NULLterminiert!
  875.  
  876. _Search        push    d0/d1
  877. .Loop        cmpi.b    #$0a,(a0)            Ende der Zeile?
  878.         beq.b    .Exit                ..ja
  879.         cmp.b    (a0)+,d0            ..nein, Char gefunden?
  880.         bne.b    .Loop                ..nein
  881.         moveq.l    #-1,d0                ..ja, cc=ne
  882. .Exit        pull    d0/d1
  883.         rts
  884.  
  885. ;;-- Teilstring mit Stringzeile vergleichen (LCase = UCase) --
  886. ;    In:    a0 = *String, a1 = *CTeilString
  887. ;    Out:    cc=eq bei Fehler und a0 = *LineFeed, sonst a0 = *NachTeilString
  888. ;    ACHTUNG: a0 ist nicht NULLterminiert und a1 MUSS LCase sein!
  889.  
  890. _Compare    push    d0/d1
  891. .Loop        tst.b    (a1)                Teilstring zu Ende?
  892.         beq.b    .Found                ..ja
  893.         cmpi.b    #$0a,(a0)            Ende der Zeile?
  894.         beq.b    .Exit                ..ja
  895.         move.b    (a0)+,d0
  896.         cmpi.b    #'A',d0
  897.         blt.b    .Cont                ..kein Großbuchstabe
  898.         cmpi.b    #'Z',d0
  899.         bgt.b    .Cont                .."    "
  900.         addi.b    #32,d0                Char > Kleinbuchstabe
  901. .Cont        cmp.b    (a1)+,d0            Chars gleich?
  902.         beq.b    .Loop                ..ja
  903. .NotFound    clr.b    d0                cc=eq
  904. .Exit        pull    d0/d1
  905.         rts
  906. .Found        moveq.l    #-1,d0                cc=ne
  907.         bra.b    .Exit
  908.  
  909. ;;-- String und Argumente formatiert in STDOUT ausgeben --
  910. ;    In:    a0 = *String, a1 = *ArgArray
  911.  
  912. _Printf        push    d0/d1/a0/a1/lb
  913.         dos
  914.         move.l    a0,d1
  915.         move.l    a1,d2
  916.         fjsr    VPrintf                String ausgeben
  917.         fjsr    Output
  918.         move.l    d0,d1
  919.         fjsr    Flush                ..und Buffer flushen
  920.         pull    d0/d1/a0/a1/lb
  921.         rts
  922.  
  923. ;;-- ULong in LCase-Hex-String ($xxx) konvertieren
  924. ;    In:    a0 = *Buffer[9], d0.l = Wert
  925. ;    Out:    d0.l = Größe des benutzten Buffers
  926.  
  927. _ULong2Hex    push    d1/d2/a0-a2
  928.         lea.l    .HexData(pc),a1
  929.         movea.l    sp,a2                temp. Buffer auf Stack
  930.         moveq.l    #0,d2
  931.         moveq.l    #0,d1                Anzahl der Stellen
  932. .Loop        addq.w    #1,d1                ..+1
  933.         move.b    d0,d2
  934.         andi.b    #%1111,d2            4-Bit Wert filtern
  935.         move.b    (a1,d2.w),-(a2)            zugeh. HexChar sichern
  936.         lsr.l    #4,d0                nächste 4 Bits
  937.         bne.b    .Loop                ..Schleife
  938.         move.b    d1,d0                d0.l = Größe-1
  939.         addq.b    #1,d0                ..+1 \/
  940.         move.b    #'$',-(a2)            Kennzeichen
  941. .Loop2        move.b    (a2)+,(a0)+            vom Stack in Buffer
  942.         dbf    d1,.Loop2            ..kopieren
  943.         pull    d1/d2/a0-a2
  944.         rts
  945. .HexData    dc.b    '0123456789abcdef'
  946.         even
  947.  
  948. ;;-- ULong in Dez-String konvertieren
  949. ;    In:    a0 = *Buffer[10], d0.l = Wert
  950. ;    Out:    d0.l = Größe des benutzten Buffers
  951.  
  952. _ULong2Dec    push    d1-d5/a0-a2
  953.         moveq.l    #0,d5                Anzahl der Stellen
  954.         moveq.l    #'0',d4
  955.         move.b    d4,(a0)                schon mal '0' schreiben
  956.         lea.l    .DecData(pc),a1
  957.         moveq.l    #10-1,d3            max. benötigte Stellen
  958. .Loop2        move.l    (a1)+,d1            10er-Faktor
  959.         moveq.l    #-1,d2                aktuelle 10er-Stelle
  960. .Loop        addq.b    #1,d2                ..+1
  961.         sub.l    d1,d0
  962.         bhs.b    .Loop                ..weitere Stelle
  963.         add.l    d1,d0
  964.         tst.b    d2
  965.         beq.b    .Cont                ..keine Stellen
  966.         bset.l    #31,d3                Flag setzen
  967. .Cont        btst.l    #31,d3                Flag gesetzt?
  968.         beq.b    .LoopEnd            ..nein, Wert ist 0
  969.         add.b    d4,d2                Stelle + '0'
  970.         move.b    d2,(a0)+            ..sichern
  971.         addq.b    #1,d5                Anzahl ++
  972. .LoopEnd    dbf    d3,.Loop2
  973.         moveq.l    #1,d0
  974.         tst.b    d5
  975.         beq.b    .Exit                Wert = 0, Anzahl = 1
  976.         move.b    d5,d0                Wert > 0, Anzahl in d0
  977. .Exit        pull    d1-d5/a0-a2
  978.         rts
  979. .DecData    dc.l    1000000000,100000000,10000000,1000000,100000,10000,1000
  980.         dc.l    100,10,1
  981.  
  982. ;;-- Debugstuff --
  983.  
  984.         if debugbool
  985.             even
  986. debugdata        dc.l    .from,.to
  987.             dc.l    .comments,.spaces
  988.             dc.l    .tabs
  989.             dc.l    .dec,.hex
  990. .comments        =    0
  991. .spaces            =    0
  992. .tabs            =    0
  993. .dec            =    0
  994. .hex            =    0
  995. .from            dc.b    'other:fd/#?.fd',0
  996. .to            dc.b    't:',0
  997.         endc
  998.