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