home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Assembler / DVD!OMA2.DMS / in.adf / Examples / Startup / startup.asm < prev    next >
Encoding:
Assembly Source File  |  1994-10-13  |  9.1 KB  |  479 lines

  1.  
  2. ;****************************************************************************
  3. ; Startup.asm                             Copyright 1990 bei Dietmar Heidrich
  4. ;
  5. ; Startup-Modul für alle Assembler-Programme.  Dieses Modul ist reentrant und
  6. ; arbeitet unter dem CLI und der Workbench.  Compress-Tab 8.
  7. ; Der Code ist dem im Addison-Wesley "ROM Kernel Reference Manual" ähnlich, nur
  8. ; wurden alle Fehler entfernt, und das Parsen der CLI-Parameter berücksichtigt
  9. ; nun die Konventionen des DOS, d.h. der String "a**b" ergibt den Namen "a*b".
  10. ;
  11. ; Das Assembler-Programm muß beim Label "_main" beginnen, welches durch XDEF
  12. ; global deklariert wird, und kann durch den Aufruf von "_exit" mit dem Fehler-
  13. ; code in D0 terminieren.
  14. ; Beim Aufruf von der Workbench aus wird _main ein Zeiger auf die Workbench-
  15. ; Message in A0 übergeben, und D0 enthält Null.
  16. ; Beim Aufruf vom CLI aus wird _main die Anzahl von CLI-Argumenten in D0 und
  17. ; der Zeiger auf das Feld mit den Zeigern auf die Argument-Strings in A0 über-
  18. ; geben.
  19. ; D0 und A0 werden auch auf den Stack geschoben ( 4(SP) für D0, 8(SP) für A0 ).
  20. ; Darüberhinaus können die Zeiger _DOSBase, _stdin, _stdout und _stderr benutzt
  21. ; werden.
  22. ;****************************************************************************
  23.  
  24.  
  25.  
  26.     CODE
  27.  
  28.  
  29.  
  30.     INCLUDE    "exec/types.i"
  31.     INCLUDE    "exec/alerts.i"
  32.     INCLUDE    "exec/tasks.i"
  33.     INCLUDE    "libraries/dos.i"
  34.     INCLUDE    "libraries/dosextens.i"
  35.     INCLUDE    "workbench/startup.i"
  36.     INCLUDE    "lvo/exec.i"
  37.     INCLUDE    "lvo/dos.i"
  38.  
  39.  
  40.  
  41.     XDEF    _exit
  42.     XDEF    _SysBase
  43.     XDEF    _DOSBase
  44.     XDEF    _stdin
  45.     XDEF    _stdout
  46.     XDEF    _stderr
  47.  
  48.  
  49.  
  50.     XREF    _main
  51.  
  52.  
  53.  
  54. BP            EQUR    A5
  55.  
  56. _SysBase        EQU    4
  57.  
  58. MAXIMUM_ARGUMENTE    EQU    40
  59. MAXIMUM_ARGBUFFER    EQU    256
  60. LF            EQU    10
  61. SPACE            EQU    ' '
  62.  
  63.  
  64.  
  65. CALL    MACRO
  66.     IFEQ NARG-2
  67.     move.l    \2,a6
  68.     ENDC
  69.     IFLE NARG-2
  70.     jsr    _LVO\1(a6)
  71.     MEXIT
  72.     ENDC
  73.     FAIL    CALL MACRO ERROR
  74.     ENDM
  75.  
  76.  
  77.  
  78. PSTRING    MACRO
  79.     IFEQ NARG-1
  80.     dc.b    end\@-1-*,'\1',LF
  81. end\@
  82.     MEXIT
  83.     ENDC
  84.     FAIL    PSTRING MACRO ERROR
  85.     ENDM
  86.  
  87.  
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94.  
  95.  
  96. ;****************************************************************************
  97.  
  98. Startup
  99.     ; Wir müssen reentrant sein.
  100.     lea    BA(PC),BP        ; Basiszeiger
  101.     move.l    SP,HauptSP-BA(BP)    ; rette SP
  102.     movem.l    d0/a0,Register-BA(BP)
  103.     clr.l    _WBenchMsg-BA(BP)
  104.     clr.l    WBenchFile-BA(BP)
  105.     moveq    #-1,d0
  106.     lea    _stdin-BA(BP),a0
  107.     move.l    d0,(a0)+
  108.     move.l    d0,(a0)+
  109.     move.l    d0,(a0)+
  110.  
  111.     ; Hole die Adresse unserer Task.
  112.     sub.l    a1,a1
  113.     CALL    FindTask,_SysBase
  114.     move.l    d0,a4            ; Zeiger auf Task-Struktur
  115.  
  116.     ; Wurden wir vom CLI gestartet ?
  117.     tst.l    pr_CLI(a4)
  118.     bne    CLIStartup
  119.  
  120.  
  121.  
  122.  
  123.  
  124.  
  125.  
  126.  
  127.  
  128.  
  129. ;****************************************************************************
  130. ; Workbench-Startup-Code.
  131.  
  132. WorkbenchStartup
  133.     bsr.s    OeffneDOS
  134.  
  135.     ; Hole die Workbench-Message.
  136.     lea    pr_MsgPort(a4),a0
  137.     CALL    WaitPort        ; A6 enthält schon _SysBase
  138.     lea    pr_MsgPort(a4),a0
  139.     CALL    GetMsg
  140.     move.l    d0,_WBenchMsg-BA(BP)
  141.  
  142.     ; Hole das erste Argument.
  143.     move.l    _DOSBase-BA(BP),a6
  144.     move.l    d0,a3            ; Workbench-Message-Zeiger
  145.     move.l    sm_ArgList(a3),d0
  146.     beq.s    1$
  147.  
  148.     ; Setze das aktuelle Directory.
  149.     move.l    d0,a0
  150.     move.l    wa_Lock(a0),d1
  151.     CALL    CurrentDir
  152.  
  153.     ; Hole das Toolwindow-Argument.
  154. 1$    move.l    sm_ToolWindow(a3),d1
  155.     beq.s    2$
  156.  
  157.     ; Öffne das Fenster.
  158.     move.l    #MODE_OLDFILE,d2
  159.     CALL    Open
  160.     move.l    d0,WBenchFile-BA(BP)    ; rette Filezeiger
  161.  
  162.     ; Setze die Input- und Output-Deskriptoren.
  163.     lea    _stdin-BA(BP),a0
  164.     move.l    d0,(a0)+        ; setze _stdin
  165.     move.l    d0,(a0)+        ; setze _stdout
  166.     move.l    d0,(a0)+        ; setze _stderr
  167.     beq.s    2$
  168.  
  169.     ; Setze die Console-Task (damit Open ("*", mode) funktioniert).
  170.     lsl.l    #2,d0            ; BCPL-Zeiger-Konvertierung
  171.     move.l    d0,a0
  172.     move.l    fh_Type(a0),pr_ConsoleTask(a4)
  173.  
  174.     ; Setze die Startwerte.
  175. 2$    move.l    a3,a0            ; Workbench-Message-Zeiger
  176.     moveq    #0,d0            ; d.h. von der Workbench gestartet
  177.     bra    StarteMain
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188. ;****************************************************************************
  189. ; Öffne DOS.
  190. ; Eingabe:  A6 enthält _SysBase.
  191. ; Ausgabe:  A6 enthält _SysBase.
  192. ;           D0 enthält _DOSBase.
  193.  
  194. OeffneDOS
  195.     clr.l    _DOSBase-BA(BP)
  196.     lea    DOSName-BA(BP),a1
  197.     moveq    #LIBRARY_VERSION,d0
  198.     CALL    OpenLibrary
  199.     move.l    d0,_DOSBase-BA(BP)
  200.     beq.s    1$
  201.     rts
  202.  
  203.     ; Fehler: DOS ist nicht offen.
  204. 1$    move.l    #(AG_OpenLib!AO_DOSLib),d7
  205.     lea    AlertValue-BA(BP),a5
  206.     CALL    Alert
  207.     moveq    #100,d0
  208.     bra    _exit
  209.  
  210.  
  211.  
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218.  
  219. ;****************************************************************************
  220. ; CLI-Startup-Code.
  221.  
  222. CLIStartup
  223.     bsr.s    OeffneDOS
  224.  
  225.     ; Hole den Standard-Input/Output-Handle.
  226.     move.l    d0,a6            ; _DOSBase
  227.     CALL    Input
  228.     move.l    d0,_stdin-BA(BP)
  229.     CALL    Output
  230.     move.l    d0,_stdout-BA(BP)
  231.     move.l    d0,_stderr-BA(BP)
  232.  
  233.     ; Finde den Kommandonamen.
  234.     move.l    pr_CLI(a4),a0
  235.     add.l    a0,a0            ; BCPL-Zeiger-Konvertierung
  236.     add.l    a0,a0
  237.     move.l    cli_CommandName(a0),a0
  238.     add.l    a0,a0            ; BCPL-Zeiger-Konvertierung
  239.     add.l    a0,a0
  240.  
  241.     ; Initialisiere Zähler und Zeiger.
  242.     move.l    #MAXIMUM_ARGBUFFER-1,d7
  243.     moveq    #MAXIMUM_ARGUMENTE-2,d6    ; Argumentzähler
  244.     lea    Zeigerfeld,a4
  245.     move.l    a4,a1
  246.     lea    Stringspeicher-Zeigerfeld(a4),a3
  247.  
  248.     ; Hole den Kommandonamen.
  249.     moveq    #0,d0
  250.     move.b    (a0)+,d0        ; Stringlänge
  251.     sub    d0,d7            ; Unterlauf ?
  252.     bcs.s    errorBufferOverflow    ; ja, Fehler
  253.     move.l    a3,(a1)+        ; Zeiger auf Kommandonamen
  254.     bra.s    1$
  255.  
  256. 2$    move.b    (a0)+,(a3)+        ; Kopiere Zeichen
  257. 1$    dbra    d0,2$            ; bis Name zu Ende
  258.  
  259.     clr.b    (a3)+            ; beende Kommandenamen
  260.     movem.l    Register-BA(BP),d0/a0
  261.     cmp.l    d7,d0            ; Kommandozeile zu lang ?
  262.     bhs.s    errorBufferOverflow    ; ja
  263.  
  264.     ; Parse die Argumente.
  265.     moveq    #SPACE,d5        ; verkürzt Code
  266.     moveq    #'"',d3            ; verkürzt Code
  267.     bra    NaechstesArgument
  268.  
  269.  
  270.  
  271. ArgSchleife
  272.     move.b    (a0)+,d4        ; hole Zeichen
  273.     cmp.b    d5,d4            ; legales Zeichen (cmp #' ') ?
  274.     bls.s    NaechstesArgument    ; nein, nächstes Zeichen
  275.  
  276.     move.l    a3,a2            ; Zeiger auf Argumentpuffer-Stelle merken
  277.     cmp.b    d3,d4            ; ist es doppeltes Hochkomma (cmp #'"') ?
  278.     bne.s    1$            ; nein
  279.     bra.s    3$            ; ja
  280.  
  281.  
  282.  
  283.     ; Argument darf mit einem SPACE enden.
  284. 2$    move.b    (a0)+,d4        ; hole Zeichen
  285.     cmp.b    d5,d4            ; Argument beendet (cmp #' ') ?
  286.     bls.s    ArgEnd            ; ja
  287. 1$    cmp.b    #'=',d4            ; ein '=' ist nicht erlaubt
  288.     beq.s    errorEquateUse        ; wenn Fehler
  289.     move.b    d4,(a3)+        ; speichere Zeichen
  290.     dbra    d0,2$            ; Zeichen übrig ?
  291.     bra.s    ArgEnd            ; nein
  292.  
  293.  
  294.  
  295.     ; Argument ist in doppelte Hochkommata eingefaßt.
  296. 4$    move.b    (a0)+,d4        ; hole Zeichen
  297.     cmp.b    d5,d4            ; Argument beendet (cmp #' ') ?
  298.     blo.s    errorIllegalArgEnd    ; ja, Fehler
  299.  
  300.     ; Endet Argument mit doppeltem Hochkomma ?
  301.     cmp.b    d3,d4            ; (cmp #'"')
  302.     bne.s    5$            ; nein
  303.     subq    #1,d0            ; Zeichen übrig ?
  304.     blt.s    ArgEnd            ; nein, alles OK
  305.     move.b    (a0)+,d4        ; ja, nächstes Zeichen
  306.     cmp.b    d5,d4            ; legales Zeichen (cmp #' ') ?
  307.     bls.s    ArgEnd            ; ja, alles OK
  308.     bra.s    errorIllegalArgEnd    ; nein, Fehler
  309.  
  310.     ; Ist es ein Stern ?
  311. 5$    cmp.b    #'*',d4
  312.     bne.s    6$            ; nein, speichere Zeichen
  313.     subq    #1,d0            ; Zeichen übrig ?
  314.     blt.s    errorIllegalArgEnd    ; nein, Fehler
  315.     move.b    (a0)+,d4        ; hole Zeichen
  316.     cmp.b    d5,d4            ; Argument beendet (cmp #' ') ?
  317.     blo.s    errorIllegalArgEnd    ; ja, Fehler
  318.  
  319. 6$    move.b    d4,(a3)+        ; speichere Zeichen
  320.  
  321.     ; Es MUß noch Zeichen geben, oder Fehler.
  322. 3$    dbra    d0,4$            ; Zeichen übrig ?
  323.  
  324.  
  325.  
  326. errorIllegalArgEnd
  327.     lea    TextIllegalArgEnd-BA(BP),a0
  328.     bra.s    errorOut
  329.  
  330. errorBufferOverflow
  331.     lea    TextBufferOverflow-BA(BP),a0
  332.     bra.s    errorOut
  333.  
  334. errorEquateUse
  335.     lea    TextEquateUse-BA(BP),a0
  336.     bra.s    errorOut
  337.  
  338. errorTooManyArguments
  339.     lea    TextTooManyArguments-BA(BP),a0
  340.  
  341. errorOut
  342.     moveq    #0,d3
  343.     move.b    (a0)+,d3        ; Stringlänge
  344.     move.l    a0,d2            ; Stringzeiger
  345.     move.l    _stderr-BA(BP),d1    ; Filezeiger
  346.     CALL    Write            ; Fehler ausgeben, A6 enthält _DOSBase
  347.     moveq    #10,d0            ; Fehlercode
  348.     bra.s    _exit            ; und Ende
  349.  
  350.  
  351.  
  352. ArgEnd 
  353.     clr.b    (a3)+            ; Argumentende
  354.     subq.l    #1,d6            ; noch freie Zeiger übrig ?
  355.     ble.s    errorTooManyArguments    ; nein
  356.     move.l    a2,(a1)+        ; merke Zeiger auf Argumentstring
  357.  
  358. NaechstesArgument
  359.     dbra    d0,ArgSchleife        ; Zeichen übrig ?
  360.  
  361.     ; Setze die Startwerte.
  362.     move.l    a4,a0            ; Zeiger auf Zeigerfeld
  363.     neg    d6
  364.     add    #MAXIMUM_ARGUMENTE-1,d6    ; Zeigeranzahl
  365.     move.l    d6,d0            ; nach D0
  366.  
  367. StarteMain
  368.     ; Starte das Assembler-Programm.
  369.     move.l    a0,-(SP)        ; Startwerte auf den Stack
  370.     move.l    d0,-(SP)
  371.     jsr    _main
  372.  
  373.     ; danach quittiere durch _exit...
  374.  
  375.  
  376.  
  377.  
  378.  
  379.  
  380.  
  381.  
  382.  
  383.  
  384. ;******************************************************************************
  385. ; Die Exit-Funktion.
  386. ; Eingabe:  D0 enthält den Rückgabe-Code.
  387. ; Ausgabe:  Keine Rückkehr.
  388.  
  389. _exit 
  390.     move.l    d0,d7            ; rette Fehlercode
  391.     move.l    HauptSP(PC),SP        ; SP laden
  392.  
  393.     ; Schließe das Workbench-Fenster.
  394.     move.l    _DOSBase(PC),d0
  395.     move.l    d0,a6
  396.     beq.s    1$            ; wenn DOS nicht offen
  397.     move.l    WBenchFile(PC),d1
  398.     beq.s    2$
  399.     CALL    Close            ; schließe das Fenster
  400.  
  401.     ; Schließe das DOS.
  402. 2$    move.l    a6,a1            ; _DOSBase
  403.     CALL    CloseLibrary,_SysBase
  404.  
  405.     ; Workbench-Startup ?
  406. 1$    move.l    _WBenchMsg(PC),d6
  407.     beq.s    3$
  408.     ; Gib die Workbench-Message zurück.  Forbid, damit wir nicht UnLoadSeg
  409.     ; erleiden, bevor wir ins DOS zurückgekehrt sind.
  410.     CALL    Forbid
  411.     move.l    d6,a1
  412.     CALL    ReplyMsg
  413.  
  414.     ; Zurück ins DOS.
  415. 3$    move.l    d7,d0
  416.     rts
  417.  
  418.  
  419.  
  420.  
  421.  
  422.  
  423.  
  424.  
  425.  
  426.  
  427. ;******************************************************************************
  428. ; Variablen.
  429.  
  430.     CNOP    0,4        ; für MC68020
  431.  
  432. BA        ; Basisadresse
  433.  
  434. _DOSBase    ds.l    1
  435.  
  436. _stdin        ds.l    1
  437. _stdout        ds.l    1
  438. _stderr        ds.l    1
  439.  
  440. HauptSP        ds.l    1
  441. _WBenchMsg    ds.l    1
  442. WBenchFile    ds.l    1
  443.  
  444. Register    ds.l    2
  445.  
  446. AlertValue    dc.l    -1
  447.  
  448. DOSName        DOSNAME
  449.  
  450. TextIllegalArgEnd    PSTRING <Illegal argument>
  451. TextBufferOverflow    PSTRING <Argument buffer overflow>
  452. TextEquateUse        PSTRING <Illegally used ''=''>
  453. TextTooManyArguments    PSTRING <Too many arguments>
  454.  
  455.  
  456.  
  457.  
  458.  
  459.     BSS
  460.  
  461.     CNOP    0,4
  462.  
  463. Zeigerfeld    ds.l    MAXIMUM_ARGUMENTE
  464. Stringspeicher    ds.b    MAXIMUM_ARGBUFFER
  465.  
  466.  
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475. ; Ende des Startup-Moduls
  476.  
  477.     END
  478.  
  479.