home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 13 / AACD13.ISO / AACD / Utilities / ACDPlay / src / V1.6 / asmlib / QuickFuncs.s < prev    next >
Text File  |  1997-07-15  |  49KB  |  1,005 lines

  1. *
  2. *    QuickFuncs.s  V0.22 by mak und MC3     passend zu ACDPlay.c V1.49
  3. *
  4. * Ersetzt einige C-Routinen von ACDPlay durch schnellere und kürzere
  5. * Assemblervarianten. QuickFuncs muß als Object-File in ACDPlay eingebunden
  6. * werden (Make), die Protos (Quickfuncs.h) dürfen natürlich auch nicht fehlen.
  7. * Zum assemblieren muß die CATCOMP_NUMBERS Sektion des aktuellen Katalogs für
  8. * Assembler als Datei "locale.i" vorhanden sein.
  9. *
  10. * ACHTUNG! Alle Funktionen hier (und auch C) gehen davon aus daß alle Register
  11. * erhalten bleiben. Darum müssen alle Register die irgendwie verändert
  12. * werden gesichert werden. Auch d0, wenn kein Wert zurückgegeben wird.
  13. *
  14. *  Autor   Version   Datum              Veränderungen
  15. * ------- --------- --------    ------------------------------------------
  16. *   mak     0.01    23.10.96    NewShowMsg() und  NewGetVec() dazu
  17. *                   24.10.96    NewFlushMessages() dazu
  18. *           0.02    26.10.96    Funktionen benutzen jetzt die lokalisierten
  19. *                               Texte von ACDPlay
  20. *           0.03    31.10.96    NewOpenLibs() erstellt
  21. *           0.04     4.11.96    NewCloseLibs() neu
  22. *           0.05     6.11.96    Funktionsnamen von New.. in ..A geändert
  23. *                               OpenARexxPortA() erstellt
  24. *                               QuickFuncs.h erstellt
  25. *                    7.11.96    CloseARexxPortA() hinzu
  26. *                   12.11.96    StrCmpA() geschrieben
  27. *           0.06    14.11.96    HandleARexxMsgA() endlich fertiggestellt
  28. *                   15.11.96    HandleARexxMsgA() optimiert und erweitert
  29. *                               Play, Stop, Eject, JumpForward und JumpBackward eingeführt
  30. *           0.07    17.11.96    FormatA() umgesetzt
  31. *                   18.11.96    alles ausführlich kommentiert
  32. *                               (falls dich die narrensichere Kommentierung nervt, sag das bitte)
  33. *           0.08    20.11.96    HandleARexxMsgA() gibt jetzt BOOL zurück
  34. *                               SHOW, HIDE, QUIT hinzugeführt und JUMPFORWARD in NEXTSONG geändert
  35. *           0.09    22.11.96    FindARexxPort() fertiggestellt und OpenARexxPort() gibt
  36. *                               jetzt nicht mehr PORTALREADYOPEN zurück (jetzt durch FindARexxPort())
  37. *                   23.11.96    'ACDP'-Messagetyp eingeführt (private rexxlike Messages)
  38. *           0.10    25.11.96    FakeRequestA() fertiggestellt
  39. *           0.11    04.01.97    Mindestversion des zu öffnenden Katalogs ist CATALOG_VERSION
  40. *
  41. *   MC3     0.12    29.01.97    Workbench.library wird geöffnet
  42. *
  43. *   mak     0.13    02.02.97    ARexx 'SHOW' schließt jetzt AppIcon
  44. *
  45. *   MC3     0.14    14.02.97    ChangeButtonTextA() erstellt
  46. *                   16.02.97    asl.library wird geöffnet (wenn vorhanden)
  47. *                               Library-Locales dazu
  48. *
  49. *   mak     0.16    23.02.97    ExecuteARexxA() dazu
  50. *                   01.03.97    OPEN, CLOSE und PAUSE hinzu
  51. *                               CloseARexxPortA() und FlushMsgA() testen auf NULL
  52. *           0.17    08.03.97    OpenLibsA() überprüft ob mathieeedoubbas.library vorhanden ist
  53. *           0.18    14.03.97    Rexx-Kommandos extrahiert
  54. *                               ExecuteARexxA() öffnet jetzt ggf. ein Window
  55. *           0.19    23.03.97    Fehlermeldung für RexxSysLib-Fehler stimmt jetzt
  56. *           0.20    06.04.97    ChangeButtonTextA auskommentiert
  57. *                               CON-Fenster von ExecuteArexxA() ist jetzt vom Typ AUTO
  58. *           0.21    27.04.97    HandleARexxMsgA() überarbeitet
  59. *                               rexxcmds.s überarbeitet und ca. 40 ARexx-Kommandos dazu
  60. *           0.22    11.07.97    FindPort´s() mit Forbid abgesichert
  61. *                   15.07.97    MyGT_SetGadgetAttrs() erstellt
  62.  
  63.  include 'exec/ports.i'
  64.  include 'dos/dos.i'
  65.  include 'dos/dosextens.i'
  66.  include 'intuition/intuition.i'
  67.  include 'libraries/gadtools.i'
  68.  include 'libraries/locale.i'
  69.  include 'rexx/rxslib.i'
  70.  include 'rexx/storage.i'
  71.  include 'lvo/dos.i'
  72.  include 'lvo/exec.i'
  73.  include 'lvo/gadtools.i'
  74.  include 'lvo/graphics.i'
  75.  include 'lvo/intuition.i'
  76.  include 'lvo/locale.i'
  77.  
  78.  include "locale.i"
  79.  
  80.  xref _GetString
  81.  
  82.  xref __wbflag
  83.  xref _CDPlayBase
  84.  xref _CxBase
  85.  xref _DOSBase
  86.  xref _GadToolsBase
  87.  xref _GfxBase
  88.  xref _WorkbenchBase
  89.  xref _IconBase
  90.  xref _AslBase
  91.  xref _IntuitionBase
  92.  xref _LocaleBase
  93.  xref _RexxSysBase
  94.  xref _ScreenNotifyBase
  95.  xref _li               ; LocaleInfo Struktur die _GetString übergeben wird
  96.  xref _ls               ; Array mit Zeigern auf lokalisierte Texte
  97.  
  98. FALSE           equ 0
  99. TRUE            equ 1
  100. NULL            equ 0
  101.  
  102.  include "CD-ROM.s"
  103.  
  104. *************************  FakeRequestA   *****************************
  105. *
  106. *  void FakeRequestA(struct Window *win, APTR visualinfo, LONG xoffset, LONG yoffset, LONG height);
  107. *
  108. * Füllt das Fenster 'win' mit einem Muster aus und malt in der Mitte ein
  109. * von einer umgedrehten BevelBox umrahmtes Rechteck mit Farbe 0, so daß es
  110. * wie ein IntuitionRequester aussieht. Die Offsetparameter beziehen sich
  111. * dabei auf den inneren Rand des Fensters.
  112. *
  113.   CNOP 0,2
  114.   xdef _FakeRequestA
  115. _FakeRequestA:  movem.l d0-d5/a0-a6,-(sp)
  116.                 movem.l 52+4(a7),a3-a4          ; a3=win a4=visualinfo
  117.                 lea     wd_RPort(a3),a2
  118.                 movea.l (a2)+,a5                ; a5=RastPort
  119.  
  120. .PrepareRPort   lea     Pattern(pc),a0          ; Daten für Ditherpattern in
  121.                 move.l  a0,rp_AreaPtrn(a5)      ;  RastPort eintragen
  122.                 move.b  #1,rp_AreaPtSz(a5)
  123.                 movea.l _GfxBase,a6             ; GfxBase laden
  124.                 movea.l a5,a1
  125.                 moveq   #2,d0                   ; Vordergrundfarbe auf weiß
  126.                 jsr     _LVOSetAPen(a6)         ;  setzen
  127.  
  128. .DitherWindow   moveq   #0,d0                   ; d0 und d1 müssen vom Typ
  129.                 moveq   #0,d1                   ;  LONG sein
  130.                 move.b  (a2)+,d0                ; =wd_BorderLeft
  131.                 move.b  (a2)+,d1                ; =wd_BorderTop
  132.                 move.b  (a2)+,d4                ; =wd_BorderRight
  133.                 move.b  (a2),d5                 ; =wd_BorderBottom
  134.                 ext.w   d4                      ; d4 und d5 auf WORD
  135.                 ext.w   d5                      ;  erweitern
  136.                 movem.w wd_Width(a3),d2-d3      ; Windowbreite und Höhe laden
  137.                 sub.w   d4,d2                   ; x2 = Width-BorderRight-1
  138.                 sub.w   d5,d3                   ; y2 = Height-BorderBottom-1
  139.                 subq.w  #1,d2
  140.                 subq.w  #1,d3
  141.                 ext.l   d2                      ; RectFill erwartet Parameter
  142.                 ext.l   d3                      ;  vom Typ LONG, darum erweitern
  143.                 movem.l d0-d1,-(a7)             ; wird noch gebraucht
  144.                 movea.l a5,a1                   ; RastPort ist Parameter
  145.                 jsr     _LVORectFill(a6)        ; Window Füllen
  146.  
  147.                 clr.l   rp_AreaPtrn(a5)         ; Dithermuster wieder löschen
  148.                 clr.b   rp_AreaPtSz(a5)
  149.  
  150.                 movea.l a5,a1                   ; RastPort ist Parameter
  151.                 moveq   #0,d0                   ; sollte aus DrawInfo gelesen werden...
  152.                 jsr     _LVOSetAPen(a6)         ; Vordergrundfarbe auf 0 setzen
  153.  
  154. .ClearArea      movem.l (a7)+,d0-d1             ; gesichertes left, top laden
  155.                 lea     52+12(a7),a0            ; Adresse der Parameter ab 'xoffset' laden
  156.                 add.l   (a0),d0                 ; left=left+xoffset
  157.                 sub.l   (a0)+,d2                ; right=right-xoffset
  158.                 add.l   (a0)+,d1                ; top=top+yoffset
  159.                 move.l  d1,d3
  160.                 add.l   (a0),d3                 ; bottom=top+height-1
  161.                 movem.l d0-d1/d3,-(a7)          ; wird nochmal gebraucht
  162.                 subq.l  #1,d3
  163.                 movea.l a5,a1                   ; RastPort
  164.                 jsr     _LVORectFill(a6)        ; Fläche löschen
  165.  
  166. .DrawBevelBox   movea.l _GadToolsBase,a6        ; für DrawBevelBoxA
  167.                 movea.l a5,a0                   ; RastPort ist Parameter
  168.                 movem.l (a7)+,d0-d1/d3
  169.                 sub.l   d0,d2                   ; Absolute Koordinaten in
  170.                 addq.l  #1,d2                   ;  Breite / Höhe wandeln
  171.                 sub.l   d1,d3
  172.                 lea     BevelBoxTags(pc),a1     ; Taglist laden
  173.                 move.l  a4,4(a1)                ; VisualInfo in TagList eintragen
  174.                 jsr     _LVODrawBevelBoxA(a6)   ; inverse BevelBox zeichnen
  175.  
  176. .EXIT           movem.l (sp)+,d0-d5/a0-a6
  177.                 rts
  178.  
  179. Pattern:        dc.w    %1010101010101010
  180.                 dc.w    %0101010101010101
  181.  
  182. BevelBoxTags:   dc.l    GT_VisualInfo, NULL
  183.                 dc.l    GTBB_Recessed, TRUE
  184.                 dc.l    TAG_END
  185.  
  186.  
  187. **************************  ListLengthA  *****************************
  188. *
  189. *  ULONG ListLengthA(register __a0 struct List *list);
  190. *
  191.   CNOP 0,2
  192.   xdef _ListLengthA
  193. _ListLengthA:   movem.l d1/a0,-(sp)                 ; Register sichern
  194.                 moveq   #-2,d0                      ; Zähler auf -2 setzen
  195.  
  196. .Loop           addq.l  #1,d0                       ; Nodezähler erhöhen
  197.                 move.l  (a0),a0                     ; lh_Head/ln_Succ in a0
  198.                 move.l  a0,d1                       ; für Condition-Flags
  199.                 bne.s   .Loop                       ; bis Liste zu Ende ist
  200.  
  201. .EXIT           movem.l (sp)+,d1/a0                 ; Register restaurieren
  202.                 rts
  203.  
  204.  
  205. **************************  ChangeButtonTextA  ***********************
  206. *
  207. *  struct Gadget *ChangeButtonTextA(register __a0 struct Application *app, register __a1 struct Window *win, register __a2 struct Gadget *prevgad, register __a3 char *newtext);
  208. *
  209. *  Vorsicht: Es wird auf die Application-Struktur zugegriffen!
  210. *  Diese darf sich vor app->font nicht mehr ändern!
  211. *
  212. ;  CNOP 0,2
  213. ;  xdef _ChangeButtonTextA
  214. ;_ChangeButtonTextA:
  215. ;                movem.l d1/a0-a6,-(sp)              ; Register sichern
  216. ;                moveq   #0,d0                       ; für die Rückgabe
  217. ;
  218. ;                move.l  (a2),a4                     ; gad = prevgad->NextGadget
  219. ;                move.l  (a4),a5                     ; nextgad = gad->NextGadget
  220. ;
  221. ;                move.l  a2,d1                       ; prüft prevgad
  222. ;                beq.s   .EXIT
  223. ;                move.l  a4,d1                       ; prüft gad
  224. ;                beq.s   .EXIT
  225. ;
  226. ;                lea     NewGadStruct(pc),a6         ; newgad laden
  227. ;
  228. ;                move.l  4(a4),(a6)                  ; LeftEdge, TopEdge kopieren
  229. ;                move.l  8(a4),4(a6)                 ; Width, Height kopieren
  230. ;                move.l  a3,8(a6)                    ; GadgetText kopieren
  231. ;                move.l  16(a0),12(a6)               ; app->font nach TextAttr ***
  232. ;                move.w  38(a4),16(a6)               ; GadgetID kopieren
  233. ;                move.l  12(a0),22(a6)               ; app->visualinfo kopieren ***
  234. ;
  235. ;                move.l  d0,(a4)                     ; NextGadget auf NULL
  236. ;                move.l  a4,a0                       ; gad ist Parameter
  237. ;                move.l  a1,a3                       ; win verlagern, damit
  238. ;                move.l  a6,a1                       ; newgad nach a1 kann
  239. ;                movea.l _GadToolsBase,a6            ; für Funktionsaufruf
  240. ;
  241. ;                movem.l a0-a6,-(sp)                 ; alles retten
  242. ;                jsr     _LVOFreeGadgets(a6)         ; FreeGadgets()
  243. ;                movem.l (sp)+,a0-a6                 ; alles restaurieren
  244. ;
  245. ;                moveq   #BUTTON_KIND,d0             ; Argument 1
  246. ;                move.l  a2,a0                       ; Argument 2
  247. ;                                                    ; Argument 3 ist bereits in a1
  248. ;                suba.l  a2,a2                       ; auf NULL setzen (Argument 4)
  249. ;
  250. ;                movem.l a0-a5,-(sp)                 ; alles retten
  251. ;                jsr     _LVOCreateGadgetA(a6)       ; CreateGadgetsA()
  252. ;                movem.l (sp)+,a0-a5                 ; alles restaurieren
  253. ;
  254. ;                tst.l   d0                          ; Rückgabewert testen
  255. ;                beq.s   .EXIT                       ; ggf. weg
  256. ;
  257. ;                move.l  d0,a0                       ; gad sichern & Argument 1
  258. ;                move.l  a5,(a0)                     ; gad->NextGadget = nextgad
  259. ;                move.l  a3,a1                       ; win ist Argument 2
  260. ;                                                    ; a2 ist noch NULL (Argument 3)
  261. ;                moveq   #1,d0                       ; Argument 4
  262. ;                movea.l _IntuitionBase,a6           ; für Funktionsaufruf
  263. ;
  264. ;                movem.l a1,-(sp)
  265. ;                jsr     _LVORefreshGList(a6)        ; RefreshGList()
  266. ;                movem.l (sp)+,a1
  267. ;
  268. ;                move.l  a1,d0                       ; Rückgabewert (gad)
  269. ;
  270. ;.EXIT           movem.l (sp)+,d1/a0-a6              ; Register restaurieren
  271. ;                rts
  272. ;
  273. ;  CNOP 0,2
  274. ;NewGadStruct:   dc.w 0              ; ng_LeftEdge
  275. ;                dc.w 0              ; ng_TopEdge
  276. ;                dc.w 0              ; ng_Width
  277. ;                dc.w 0              ; ng_Height
  278. ;                dc.l 0              ; ng_GadgetText
  279. ;                dc.l 0              ; ng_TextAttr
  280. ;                dc.w 0              ; ng_GadgetID
  281. ;                dc.l 0              ; ng_Flags
  282. ;                dc.l 0              ; ng_VisualInfo
  283. ;                dc.l 0              ; ng_UserData
  284.  
  285.  
  286. **************************  FormatA   ********************************
  287. *
  288. *  void FormatA(register __a0 char *buffer, register __a1 char *formatstr, ...);
  289. *
  290. * Kopiert den formatierten Text formatstr nach buffer und benutzt dabei
  291. * die Werte bzw. Adressen der Argumente vom Stack.
  292. *
  293.   CNOP 0,2
  294.   xdef _FormatA
  295. _FormatA:       movem.l d0-d1/a0-a3/a6,-(sp)        ; Register sichern
  296.                 movea.l 4.w,a6                      ; SysBase laden
  297.                                                     ; Argumente für RawDoFmt()
  298.                 movea.l a0,a3                       ; PutChData -> a3
  299.                 movea.l a1,a0                       ; FormatString -> a0
  300.                 movea.l a7,a1                       ; DataStream -> a1
  301.                 lea     32(a1),a1                   ; Offset da Register auf dem Stack sind
  302.                 lea     PutChProc(pc),a2            ; Copy-Routine
  303.                 jsr     _LVORawDoFmt(a6)
  304.  
  305. .EXIT           movem.l (sp)+,d0-d1/a0-a3/a6        ; Register restaurieren
  306.                 rts
  307.  
  308. PutChProc:      move.b  d0,(a3)+                    ; wird von RawDoFMt aufgerufen
  309.                 rts                                 ; soll ich einen Overflowtest einbauen?
  310.  
  311.  
  312. *************************  ShowMsgA   ********************************
  313. *
  314. *  void ShowMsgA(char *ReqTitle, char *ReqBody, ...);
  315. *
  316. * Zeigt eine Nachricht Abhängig von __wbflag auf der Workbench als Requester
  317. * oder im CLI an.
  318. *
  319.   CNOP 0,2
  320.   xdef _ShowMsgA
  321. _ShowMsgA:      movem.l d0-d2/a0-a3/a6,-(sp)
  322.  
  323.                 tst.w   __wbflag                    ; von WB gestartet?
  324.                 beq     .CLIMsg                     ; nein: in CLI schreiben
  325.  
  326. .WBMsg          lea     MsgEasyStruct(pc),a1        ; a1=*EasyStruct
  327.                 move.l  36(a7), es_Title(a1)        ; Titel eintragen
  328.                 move.l  40(a7), es_TextFormat(a1)   ; Text eintragen
  329.                 lea     _ls,a0
  330.                 move.l  4*MSG_OK_REQ(a0), es_GadgetFormat(a1) ; Gadget eintragen
  331.                 suba.l  a0,a0                       ; *Window=NULL
  332.                 suba.l  a2,a2                       ; a2=NULL (IDCMP)
  333.                 movea.l a7,a3                       ; * auf restliche
  334.                 adda.l  #44,a3                      ;  Argumente nach a3
  335.                 move.l  _IntuitionBase, a6          ; IBase laden
  336.                 jsr     _LVOEasyRequestArgs(a6)     ; Requester darstellen
  337.                 bra     .EXIT                       ; das wars
  338.  
  339. .CLIMsg         suba.l  #88,a7                      ; 88 bytes auf´m Stack
  340.                 move.l  a7,d1                       ;  freimachen damit 87
  341.                 moveq   #87,d2                      ;  Zeichen da reinpassen
  342.                 move.l  _DOSBase, a6                ; DOSBase laden
  343.                 jsr     _LVOGetProgramName(a6)      ; ProgNamen in Puffer schreiben
  344.                 tst.w   d0                          ; geklappt ?
  345.                 beq     .WriteMsg                   ; nö: Msg ausgeben
  346.                  move.l  a7,d1
  347.                  jsr     _LVOPutStr(a6)             ; Prognamen ausgeben
  348.                  lea     Colon(pc),a1
  349.                  move.l  a1,d1
  350.                  jsr     _LVOPutStr(a6)             ; ": " ausgeben
  351.  
  352. .WriteMsg       adda.l  #88,a7                      ; Stack zurücksetzen
  353.                 move.l  40(a7),d1                   ; ReqBody als Arg für VPrintf
  354.                 move.l  a7,d2
  355.                 addi.b  #44,d2                      ; Rest als Argument
  356.                 jsr     _LVOVPrintf(a6)             ; Msg ausgeben
  357.                 lea     LineFeed(pc),a1             ; erst mit dem LF
  358.                 move.l  a1,d1                       ;  erscheint alles im
  359.                 jsr     _LVOPutStr(a6)              ;  CON-CLI-Window
  360.  
  361. .EXIT           movem.l (sp)+, d0-d2/a0-a3/a6       ; Register wiederherstellen
  362.                 rts
  363.  
  364. MsgEasyStruct:  dc.l 20             ; es_StructSize
  365.                 dc.l 0              ; es_Flags
  366.                 dc.l 0              ; es_Title
  367.                 dc.l 0              ; es_TextFormat
  368.                 dc.l 0              ; es_GadgetFormat
  369.  
  370. Colon:          dc.b ": ",0
  371. LineFeed:       dc.b 10,0
  372.  
  373.  
  374. *************************  GetVecA  *********************************
  375. *
  376. *  APTR GetVecA(register __d0 ULONG bytesize, register __d1 ULONG requirements);
  377. *
  378. * Versucht 'bytesize' Bytes RAM zu erhalten und Zeigt im Fehlerfall eine
  379. * Fehlermeldung an.
  380. *
  381.   CNOP 0,2
  382.   xdef _GetVecA
  383. _GetVecA:       movem.l d1-d2/a0-a1/a6,-(sp)    ; alte Register speichern
  384.                 move.l  d0,d2                   ; bytesize für Fehlerfall sichern
  385.                 move.l  4.w,a6                  ; SysBase laden
  386.                 jsr     _LVOAllocVec(a6)        ; AllocVec bytesize requiements
  387.                 tst.l   d0                      ; erfolgreich?
  388.                 bne     .EXIT                   ; mem <> 0 -->.EXIT
  389.                 move.l  d2,-(a7)                ; Argumente für NewShowMsg
  390.                 lea     _ls,a0                  ;  auf den Stack schieben
  391.                 move.l  4*MSG_NO_MEMORY(a0),-(a7)
  392.                 move.l  4*MSG_ERROR_TITLE(a0),-(a7)
  393.                 bsr     _ShowMsgA               ; Error anzeigen
  394.                 lea     12(a7),a7               ; Stack wieder runtersetzen
  395.  
  396. .EXIT           movem.l (sp)+,d1-d2/a0-a1/a6    ; alte Register restaurieren
  397.                 rts
  398.  
  399.  
  400. *************************  OpenLibsA  ********************************
  401. *
  402. *  BOOL OpenLibsA(void);
  403. *
  404. * Versucht alle benötigten (siehe Tabelle) Libraries zu öffnen und zeigt
  405. * im Fehlerfall, falls die Library unbedingt benötigt wird, einen Requester an.
  406. * Außerdem wird die LocaleInfo-Struktur initialisiert und die Pointer auf
  407. * die lokalisierten Texte werden in das ls-Array kopiert.
  408. *
  409.   CNOP 0,2
  410.   xdef _OpenLibsA
  411. _OpenLibsA:     movem.l d1-d2/d7/a0-a3/a6,-(sp)
  412.                 moveq   #FALSE,d7               ; success = FALSE
  413.                 move.l  4.w,a6                  ; SysBase laden
  414.  
  415. .OpenIntuition  lea     IntuitionLibName(pc),a1
  416.                 moveq   #37,d0
  417.                 jsr     _LVOOpenLibrary(a6)     ; IntuitionLib V37 öffnen
  418.                 move.l  d0,_IntuitionBase
  419.                 beq     .EXIT                   ; if (!IntuitionBase) return success;
  420. .OpenLocale     lea     LocaleLibName(pc),a1
  421.                 moveq   #38,d0
  422.                 jsr     _LVOOpenLibrary(a6)     ; LocaleLib V38 öffnen
  423.                 lea     _li,a3                  ; a3 = LocaleInfo
  424.                 move.l  d0,_LocaleBase
  425.                 beq     .CopyStrings            ; if (LocaleBase)
  426.                                                 ; {
  427. .OpenCatalog    move.l  d0,(a3)                 ;   li.li_LocaleBase = LocaleBase
  428.                 suba.l  a0,a0
  429.                 lea     CatName(pc),a1
  430.                 lea     CatalogVerTags(pc),a2
  431.                 move.l  d0,a6                   ;   LocaleBase laden
  432.                 jsr     _LVOOpenCatalogA(a6)    ;   li.li_Catalog=OpenCatalog()
  433.                 move.l  d0,4(a3)                ; }
  434.  
  435. .CopyStrings    lea     _ls,a2                  ; a2 = ls[]
  436.                 lea     _GetString,a6           ; ein bißchen Speed...
  437.                 moveq   #0,d2
  438.                                                 ; for (i = 0;i < ANZ_MSG;)
  439. .Next           move.l  a3,a0                   ; {
  440.                 move.l  d2,d0
  441.                 jsr     (a6)                    ;   GetString(li, id)
  442.                 move.l  d0,(a2)+                ;   ls[i]=GetString(li, i)
  443.                 addq.w  #1,d2                   ;   i++
  444.                 cmp.w   #ANZ_MSG,d2             ; }
  445.                 blt    .Next                    ;
  446.  
  447. .TstMathDoub    move.l  4.w,a6                  ; SysBase wieder laden
  448.                 lea     MathDoubBasName(pc),a1
  449.                 moveq   #34,d0
  450.                 jsr     _LVOOpenLibrary(a6)     ; mathieeedoubbas.library öffnen
  451.                 tst.l   d0                      ; geklappt?
  452.                 bne     .CloseMathDoub          ; ja: wieder schließen...
  453.                  lea     _ls,a0
  454.                  move.l  4*MSG_NO_MATHIEEEDOUBBASLIB(a0),-(a7)
  455.                  move.l  4*MSG_ERROR_TITLE(a0),-(a7); ErrorTitle auf den Stack
  456.                  bsr     _ShowMsgA                  ; Fehlertext anzeigen
  457.                  addq.l  #8,a7                      ; Stack aufräumen
  458.                  bra     .EXIT
  459. .CloseMathDoub  move.l  d0,a1
  460.                 jsr     _LVOCloseLibrary(a6)
  461.  
  462. .OpenRestLibs   lea     Libs(pc),a2             ; Librarytabelle laden
  463.  
  464. .Loop           tst.l   (a2)                    ; while (Libs.LibName)
  465.                 beq     .AllOpened              ; {
  466.                 move.l  (a2)+,a1                ;   Libs.LibName
  467.                 move.l  (a2)+,d0                ;   Libs.Version
  468.                 jsr     _LVOOpenLibrary(a6)     ;   OpenLibrary()
  469.                 move.l  (a2)+,a0
  470.                 move.l  (a2)+,d1                ;   ...[Libs++]...
  471.                 move.l  d0,(a0)                 ;
  472.                 bne     .Loop                   ;   if (!(Libs.Base = OpenLibrary())
  473.                                                 ;   {
  474. .Error          tst.l   d1                      ;     ErrorText vorgesehen?
  475.                 beq     .Loop                   ;     nein -> kein Fehler, weitermachen
  476.                 movea.l d1,a0                   ;     Adresse des Errortextes auf den Stack
  477.                 move.l  (a0),-(a7)
  478.                 move.l  MSG_ERROR_TITLE*4+_ls,-(a7);  ErrorTitle auf den Stack
  479.                 bsr     _ShowMsgA               ;     Fehlertext anzeigen
  480.                 addq.l  #8,a7                   ;     Stack aufräumen
  481.                 bra     .EXIT                   ;     return success
  482.                                                 ; } }
  483. .AllOpened      moveq   #TRUE,d7                ; success = TRUE
  484.  
  485. .EXIT           move.l  d7,d0
  486.                 movem.l (sp)+,d1-d2/d7/a0-a3/a6
  487.                 rts
  488.  
  489. CatalogVerTags:     dc.l    OC_Version, CATALOG_VERSION
  490.                     dc.l    TAG_END
  491.  
  492. *************************  CloseLibsA  *******************************
  493. *
  494. *  void CloseLibsA(void);
  495. *
  496. * Schließt, ausgehend von der Libstabellealle, alle geöffneten Libraries
  497. * und den geöffnetet Katalog.
  498. *
  499.   CNOP 0,2
  500.   xdef _CloseLibsA
  501. _CloseLibsA:    movem.l d0-d7/a0-a6,-(sp)
  502.                 move.l  4.w,a6                  ; SysBase laden
  503.                 lea     Libs(pc),a2             ; Librarytabelle laden
  504.  
  505. .Loop           tst.l   (a2)                    ; while (Libs.LibName)
  506.                 beq     .CloseLocale            ; {
  507.                 move.l  8(a2),a1                ;   Libs.LibName
  508.                 tst.l   (a1)                    ;   Library geöffnet?
  509.                 beq     .IsClosed
  510.                 move.l  (a1),a1
  511.                 jsr     _LVOCloseLibrary(a6)    ;   Library schließen
  512. .IsClosed       add.l   #16,a2
  513.                 bra     .Loop                   ; }
  514.  
  515. .CloseLocale    lea     _LocaleBase,a0
  516.                 tst.l   (a0)                    ; LocaleLib geöffnet ?
  517.                 beq     .CloseIntui
  518.                 movea.l (a0),a6                 ; LocaleBase laden
  519.                 move.l  _li+4,a0                ; a0 = li.li_Catalog
  520.                 jsr     _LVOCloseCatalog(a6)
  521.                 move.l  a6,a1                   ; LocaleBase wird geschlossen
  522.                 move.l  4.w,a6                  ; SysBase laden
  523.                 jsr     _LVOCloseLibrary(a6)
  524.  
  525. .CloseIntui     lea     _IntuitionBase,a0       ; Prüfen mit (An)
  526.                 tst.l   (a0)                    ;  ist schneller und
  527.                 beq     .EXIT                   ;  kürzer als 2 mal die
  528.                 move.l  (a0),a1                 ;  absolute Adresse zu benutzen
  529.                 jsr     _LVOCloseLibrary(a6)
  530.  
  531. .EXIT           movem.l (sp)+,d0-d7/a0-a6       ; Register & Stack wiederherstellen
  532.                 rts
  533.  
  534. Libs:       *LibName,     Version,  *LibBase,       **ErrorText im Fehlerfall
  535.     dc.l    CxLibName,       37, _CxBase,           MSG_NO_CXLIB*4+_ls
  536.     dc.l    GadToolsLibName, 37, _GadToolsBase,     MSG_NO_GADTOOLSLIB*4+_ls
  537.     dc.l    GfxLibName,      37, _GfxBase,          MSG_NO_GFXLIB*4+_ls
  538.     dc.l    WorkbenchLibName, 37, _WorkbenchBase,   MSG_NO_WORKBENCHLIB*4+_ls
  539.     dc.l    IconLibName,     37, _IconBase,         MSG_NO_ICONLIB*4+_ls
  540.     dc.l    AslLibName,       0, _AslBase,          0
  541.     dc.l    RexxSysName,     36, _RexxSysBase,      MSG_NO_REXXSYSLIB*4+_ls
  542.     dc.l    SNLibName,        0, _ScreenNotifyBase, 0 ; ( 0 bedeutet daß Library nicht unbedingt geöffnet werden muß)
  543.     dc.l    0
  544.  
  545. CatName:            dc.b "ACDPlay.catalog",0
  546. IntuitionLibName:   dc.b 'intuition.library',0
  547. MathDoubBasName:    dc.b 'mathieeedoubbas.library',0
  548. LocaleLibName:      dc.b 'locale.library',0
  549. CxLibName:          dc.b 'commodities.library',0
  550. GadToolsLibName:    dc.b 'gadtools.library',0
  551. GfxLibName:         dc.b 'graphics.library',0
  552. WorkbenchLibName:   dc.b 'workbench.library',0
  553. IconLibName:        dc.b 'icon.library',0
  554. AslLibName:         dc.b 'asl.library',0
  555. RexxSysName:        dc.b 'rexxsyslib.library',0
  556. SNLibName:          dc.b 'screennotify.library',0
  557.  
  558.  
  559. *************************  FindARexxPortA  ***************************
  560. *
  561. *  BOOL FindARexxPortA(void);
  562. *
  563. * Prüft ob schon ein öffentlicher Port 'ACDPLAY' vorhanden ist, sendet
  564. * gegebenenfalls das ARexxkommando 'SHOW' zu diesem Port und gibt TRUE
  565. * zurück, falls der Port nicht ausfindig gemacht werden konnte FALSE.
  566. *
  567.   CNOP 0,2
  568.   xdef _FindARexxPortA
  569. _FindARexxPortA: movem.l d1-d3/d6-d7/a0-a2/a6,-(sp)
  570.                 moveq   #FALSE,d7                   ; Vorgabe: kein Port gefunden
  571.                 move.l  4.w,a6                      ; SysBase laden
  572.  
  573.                 lea     _ARexxPortName(pc),a2       ; a2=ACDPlayPortName
  574.                 jsr     _LVOForbid(a6)              ; damit PatchWork nicht meckert
  575.                 movea.l a2,a1
  576.                 jsr     _LVOFindPort(a6)            ; Port 'ACDPLAY' suchen
  577.                 move.l  d0,d2
  578.                 jsr     _LVOPermit(a6)
  579.                 tst.l   d2                          ; gefunden?
  580.                 beq     .EXIT                       ; nein: Ende
  581.  
  582.                 moveq   #TRUE,d7                    ; Port gefunden
  583.  
  584. .OpenRexxLib    lea     RexxSysName(pc),a1          ; rexxsyslib.library
  585.                 moveq   #36,d0                      ; Version 36
  586.                 jsr     _LVOOpenLibrary(a6)         ; wird für RexxMsg benötigt
  587.                 move.l  d0,d6                       ; RexxSysBase->d6
  588.                 beq     .EXIT
  589.  
  590. .MakeReplyPort  jsr     _LVOCreateMsgPort(a6)       ; ReplyPort erstellen
  591.                 move.l  d0,d3                       ; d3=ReplyMsgPort
  592.                 beq     .CloseRexxLib               ; nicht genug Speicher...
  593.  
  594. .PrepareRexxMsg movea.l d6,a6                       ; RexxSysBase laden
  595.                 movea.l d0,a0                       ; Replymsgport
  596.                 suba.l  a1,a1                       ; Standartextension 'REXX'
  597.                 move.l  a2,d0                       ; Portname
  598.                 jsr     _LVOCreateRexxMsg(a6)
  599.                 move.l  d0,d2                       ; d2 = a0 = RexxMsg
  600.                 beq     .DeleteMsgPort              ; nicht geklappt: Ende
  601.                 lea     name_SHOW(pc),a1
  602.                 move.l  a1,ARG0(a0)                 ; SHOW-Befehl senden
  603.                 lea     PrivateMsg(pc),a1           ; damit ACDPlay die Msg
  604.                 move.l  a1,LN_NAME(a0)              ;  identifizieren kann
  605.                 move.l  #RXCOMM|RXFB_NOIO,rm_Action(a0) ; RexxMsg ist ein RX_Kommando/keine IO-Umleitung
  606.                 moveq   #1,d0                       ; nur ein Argument
  607.                 moveq   #0,d1                       ; alle Argumente sind STRPTRs
  608.                 jsr     _LVOFillRexxMsg(a6)         ; Argumente in ArgStrs konvertieren
  609.                 tst.b   d0                          ; erfolgreich?
  610.                 beq     .DeleteRexxMsg              ; nein: Ende
  611.  
  612. .SendMsg        movea.l 4.w,a6                      ; SysBase laden
  613.                 jsr     _LVOForbid(a6)              ; Taskswitching abschalten
  614.                 movea.l a2,a1                       ;  damit der Port nicht
  615.                 jsr     _LVOFindPort(a6)            ;  plötzlich verschwindet
  616.                 tst.l   d0
  617.                 bne     .SendIt                     ; Port überhaupt noch da?
  618.                  jsr    _LVOPermit(a6)              ; Multitasking wieder an
  619.                  bra    .ClearRexxMsg               ;  und Ende
  620. .SendIt         movea.l d0,a0                       ; gefundener Port
  621.                 movea.l d2,a1                       ; RexxMsg
  622.                 jsr     _LVOPutMsg(a6)              ; ab geht die Post :-)
  623.                 jsr     _LVOPermit(a6)              ; Kermit?
  624.                 movea.l d3,a0                       ; eigener ReplyPort
  625.                 jsr     _LVOWaitPort(a6)            ; auf Reply warten
  626.                 movea.l d3,a0                       ; ReplyPort
  627.                 jsr     _LVOGetMsg(a6)              ; es kommt mit Sicherheit nur
  628.                                                     ;  eine Msg an, darum reicht GetMsg
  629.  
  630. .ClearRexxMsg   movea.l d6,a6                       ; RexxSysBase wieder laden
  631.                 movea.l d2,a0                       ; RexxMsg
  632.                 moveq   #1,d0                       ; einen ArgString freigeben
  633.                 jsr     _LVOClearRexxMsg(a6)
  634.  
  635. .DeleteRexxMsg  movea.l d2,a0                       ; RexxMsg
  636.                 jsr     _LVODeleteRexxMsg(a6)       ;  freigeben
  637.  
  638. .DeleteMsgPort  movea.l 4.w,a6                      ; und SysBase wieder laden
  639.                 movea.l d3,a0                       ; eigener ReplyPort
  640.                 jsr     _LVODeleteMsgPort(a6)       ;  entfernen
  641.  
  642. .CloseRexxLib   movea.l d6,a1                       ; RexxSysBase
  643.                 jsr     _LVOCloseLibrary(a6)        ;  schließen
  644.  
  645. .EXIT           move.l  d7,d0                       ; Returnwert setzen
  646.                 movem.l (sp)+,d1-d3/d6-d7/a0-a2/a6
  647.                 rts
  648.  
  649.  
  650. *************************  OpenARexxPortA  ***************************
  651. *
  652. *  struct MsgPort *OpenARexxPortA(void);
  653. *
  654.   CNOP 0,2
  655.   xdef _OpenARexxPortA
  656. _OpenARexxPortA: movem.l d1/d7/a0-a2/a6,-(sp)
  657.             moveq   #FALSE,d7                   ; Returnwert = FALSE
  658.             move.l  4.w,a6                      ; SysBase laden
  659.  
  660.             lea     _ARexxPortName(pc),a2
  661.             jsr     _LVOForbid(a6)              ; sicherheitshalber...
  662.  
  663.             movea.l a2,a1
  664.             jsr     _LVOFindPort(a6)            ; Port 'ACDPlay' suchen
  665.             tst.l   d0                          ; ACDPlay schon gestartet?
  666.             bne     .EXIT                       ; ja: Ende
  667.  
  668.             jsr     _LVOCreateMsgPort(a6)       ; Port erstellen
  669.             move.l  d0,d7                       ; Returnwert = MsgPort *
  670.             beq     .EXIT                       ;  oder NULL
  671.  
  672.             movea.l d0,a1
  673.             move.l  a2,LN_NAME(a1)              ; Namen und Priorität (die AddPort sowieso ändert)
  674.             move.b  #0,LN_PRI(a1)               ;  des MessagePorts setzen
  675.             jsr     _LVOAddPort(a6)             ;  und öffentlich machen
  676.  
  677. .EXIT       jsr     _LVOPermit(a6)              ; Und die Welt darf sich wieder drehen :-)
  678.             move.l  d7,d0
  679.             movem.l (sp)+,d1/d7/a0-a2/a6
  680.             rts
  681.  
  682.   xdef _ARexxPortName
  683. _ARexxPortName: dc.b "ACDPLAY",0
  684.  
  685.  
  686. *************************  CloseARexxPortA  **************************
  687. *
  688. *  void CloseARexxPortA(register __a1 struct MsgPort *arexxport);
  689. *
  690. * 'arexxport' : öffentlicher Port oder NULL
  691. *
  692.   CNOP 0,2
  693.   xdef _CloseARexxPortA
  694. _CloseARexxPortA: movem.l d0-d2/a0-a1/a6,-(sp)
  695.             move.l  a1,d2                       ; arexxport sichern und testen
  696.             beq     .EXIT
  697.             movea.l 4.w,a6                      ; SysBase
  698.             jsr     _LVORemPort(a6)             ; Port aus der Public-Liste entfernen
  699.             jsr     _LVOForbid(a6)              ; Taskswitching abschalten
  700.             movea.l d2,a0                       ;  damit uns nach FlushMessages
  701.             bsr     _FlushMessagesA             ;  niemand mehr Nachrichten in
  702.             movea.l d2,a0                       ;  den Port legt
  703.             jsr     _LVODeleteMsgPort(a6)       ; MsgPort entfernen
  704.             jsr     _LVOPermit(a6)              ; Multitasking wieder erlauben
  705. .EXIT       movem.l (sp)+,d0-d2/a0-a1/a6
  706.             rts
  707.  
  708.  
  709. *************************  ExecuteARexxA  ***************************
  710. *
  711. *  BOOL ExecuteARexxA(register __a0 char *rexxscript, register __a1 struct MsgPort *rexxport, register __a2 struct Application *app);
  712. *
  713. * Führt das übergebene ARexxmacro "rexxscript" aus. Wurde QUIT empfangen,
  714. * wird QUIT zurückgegeben.
  715. *
  716.   CNOP 0,2
  717.   xdef _ExecuteARexxA
  718. _ExecuteARexxA: movem.l d1-d7/a0-a6,-(sp)
  719.                 moveq   #FALSE,d7
  720.                 moveq   #0,d5
  721.                 move.l  4.w,a6                      ; SysBase laden
  722.                 move.l  a0,a3                       ; a3=Filename
  723.                 move.l  a1,a4                       ; a4=eigener ARexxPort
  724.  
  725. .MakeReplyPort  jsr     _LVOCreateMsgPort(a6)       ; ReplyPort erstellen
  726.                 move.l  d0,d3                       ; d3=ReplyMsgPort für
  727.                 beq     .EXIT                       ;  Antwort von REXX
  728.  
  729. .PrepareRexxMsg movea.l _RexxSysBase,a6             ; RexxSysBase laden
  730.                 movea.l d0,a0                       ; ReplyPort
  731.                 suba.l  a1,a1                       ; Standartextension "REXX"
  732.                 moveq   #0,d0                       ; Standardport "REXX"
  733.                 jsr     _LVOCreateRexxMsg(a6)
  734.                 move.l  d0,d2                       ; d2 = a0 = RexxMsg
  735.                 beq     .KillReplyPort              ; nicht geklappt: Ende
  736.  
  737.                 move.l  a3,ARG0(a0)                 ; Filename ist 1. Argument
  738.                 move.l  #RXFUNC,rm_Action(a0)       ; RexxMsg ist eine RX_Function
  739.                 moveq   #1,d0                       ; nur ein Argument
  740.                 moveq   #0,d1                       ; alle Argumente sind STRPTRs
  741.                 jsr     _LVOFillRexxMsg(a6)         ; Argumente in ArgStrs konvertieren
  742.                 tst.l   d0                          ; erfolgreich?
  743.                 beq     .DeleteRexxMsg              ; nein: Ende
  744.  
  745.                 move.l  4.w,a6                      ; SysBase greifen
  746.                 suba.l  a1,a1
  747.                 jsr     _LVOFindTask(a6)            ; eigenen Task finden
  748.                 move.l  d0,a0                       ; Task wird immer gefunden
  749.                 tst.l   pr_CIS(a0)                  ; ACDPlay ist ein Process
  750.                 beq     .OpenCON                    ; Kein Eingabestrom...
  751.                 tst.l   pr_COS(a0)
  752.                 bne     .SendMsg                    ; Ein- und Ausgabestrom da
  753.  
  754. .OpenCON        move.l  _DOSBase,a6                 ; DOSBase laden
  755.                 lea     CONName(pc),a0
  756.                 move.l  a0,d1                       ; Filename "CON:..."
  757.                 move.l  d2,d4                       ; RexxMsg sichern
  758.                 move.l  #MODE_OLDFILE,d2            ; Zugriffsmodus
  759.                 jsr     _LVOOpen(a6)
  760.                 move.l  d0,d5                       ; d5=filehandle
  761.                 beq     .doserror                   ; Fehler...
  762.                 move.l  d4,d2                       ; RexxMsg zurück
  763.                 move.l  d4,a0
  764.                 move.l  d0,rm_Stdin(a0)             ; Ein- und Ausgabe in
  765.                 move.l  d0,rm_Stdout(a0)            ;  RexxMsg eintragen
  766.  
  767. .doserror       movea.l 4.w,a6                      ; SysBase laden
  768.  
  769. .SendMsg        jsr     _LVOForbid(a6)              ; Multitasking aus
  770.                 lea     RexxName(pc),a1
  771.                 jsr     _LVOFindPort(a6)            ; Port von RexxMast holen
  772.                 tst.l   d0
  773.                 bne     .SendIt                     ; Port überhaupt noch da?
  774.                  jsr    _LVOPermit(a6)              ; Multitasking wieder an
  775.                  bra    .ClearRexxMsg               ;  und Ende
  776.  
  777. .SendIt         movea.l d0,a0                       ; gefundener Port
  778.                 movea.l d2,a1                       ; RexxMsg
  779.                 jsr     _LVOPutMsg(a6)              ; ab geht die Post :-)
  780.                 jsr     _LVOPermit(a6)              ; Tasks laufen wieder und
  781.                                                     ;  das Macro startet jetzt
  782. .Loop           movea.l d3,a0
  783.                 moveq   #0,d1
  784.                 moveq   #1,d0
  785.                 move.b  MP_SIGBIT(a0),d1            ; Signalbit vom ReplyPort
  786.                 lsl.l   d1,d0                       ;  in Bitmaske wandeln
  787.                 moveq   #1,d4
  788.                 move.b  MP_SIGBIT(a4),d1            ; Signalbit vom ARexxPort
  789.                 lsl.l   d1,d4                       ;  in Bitmaske wandeln
  790.                 or.l    d4,d0                       ;  und zusammenodern :-)
  791.  
  792.                 jsr     _LVOWait(a6)                ; auf Message warten
  793.                 cmp.l   d0,d4                       ; Message vom Macro (ARexxkommando)?
  794.                 bne     .IsEnd                      ; nein: warscheinlich vom ReplyPort (Macro zuende)
  795.                 move.l  a4,a0
  796.                 move.l  a2,a1
  797.                 bsr     _HandleARexxMsgA            ; ARexxkommando bearbeiten
  798.                 or.l    d0,d7                       ; QUIT empfangen?
  799.                 bra     .Loop                       ; auf ein neues...
  800.  
  801. .IsEnd          movea.l d3,a0                       ; ReplyPort
  802.                 jsr     _LVOGetMsg(a6)              ; Message holen
  803.                 tst.l   d0                          ; wirklich Reply von Rexx?
  804.                 beq     .Loop
  805.  
  806. .ClearRexxMsg   movea.l _RexxSysBase,a6             ; RexxSysBase wieder laden
  807.                 movea.l d2,a0                       ; RexxMsg
  808.                 moveq   #1,d0                       ; einen ArgString freigeben
  809.                 jsr     _LVOClearRexxMsg(a6)
  810.  
  811.                 move.l  d5,d1                       ; CON-Filehandle
  812.                 beq     .DeleteRexxMsg              ;  falls vorhanden...
  813.                 move.l  _DOSBase,a6
  814.                 jsr     _LVOClose(a6)               ;  ...schließen
  815.                 move.l  _RexxSysBase,a6
  816.  
  817. .DeleteRexxMsg  movea.l d2,a0                       ; RexxMsg
  818.                 jsr     _LVODeleteRexxMsg(a6)       ; freigeben
  819.  
  820. .KillReplyPort  movea.l 4.w,a6                      ; und SysBase wieder laden
  821.                 movea.l d3,a0                       ; eigenen ReplyPort
  822.                 jsr     _LVODeleteMsgPort(a6)       ;  entfernen
  823.  
  824. .EXIT           move.l  d7,d0                       ; returnwert setzen
  825.                 movem.l (sp)+,d1-d7/a0-a6
  826.                 rts
  827.  
  828. RexxName:   dc.b "REXX",0
  829. CONName:    dc.b "CON:0/100/640/140/ACDPlay Output/AUTO/WAIT",0
  830.  
  831.  
  832. ***********************  HandleARexxMsgA  ****************************
  833. *
  834. *  BOOL HandleARexxMsgA(register __a0 struct MsgPort *arexxport, register __a1 struct Application *app);
  835. *
  836. * Gibt TRUE zurück wenn QUIT empfangen wurde
  837. *
  838.   CNOP 0,2
  839.   xdef _HandleARexxMsgA
  840. _HandleARexxMsgA:   movem.l d1-d3/d7/a0-a6,-(sp)
  841.                     moveq   #FALSE,d7               ; success=FALSE
  842.                     move.l  4.w,d3                  ; SysBase speichern um
  843.                     movea.l d3,a6                   ;  CHIPRam-Zugriffe zu vermeiden
  844.                     move.l  a0,d2                   ; MsgPort sichern
  845.                     movea.l a1,a5                   ; Appzeiger sichern
  846.  
  847. .GetNextMsg         movea.l d2,a0
  848.                     jsr     _LVOGetMsg(a6)          ; GetMsg(arexxport)
  849.                     tst.l   d0                      ; Msg da?
  850.                     beq     .EXIT                   ; nein: raus hier
  851.                     movea.l d0,a4                   ; a4=Message
  852.  
  853. .TstMsg             movea.l _RexxSysBase,a6         ; RexxSysBase laden
  854.                     movea.l d0,a0
  855.                     jsr     _LVOIsRexxMsg(a6)       ; kommt Msg von ARexx?
  856.                     tst.b   d0
  857.                     bne     .GetFirstToken          ; ja: weitermachen
  858.                     move.l  LN_NAME(a4),a0
  859.                     lea     PrivateMsg(pc),a1       ; 4 Bytes reichen für 'ACDP'
  860.                     cmp.l   (a0)+,(a1)+             ; kommt Msg von ACDPlay?
  861.                     bne     .ReplyMsg               ; nein: zurückschicken
  862.  
  863. .GetFirstToken      movea.l ARG0(a4),a0             ; ARexxCmd -> a0
  864.                     jsr     _LVOStcToken(a6)        ; a1=FirstToken
  865.                     tst.w   d1                      ; d1=TokenLenght
  866.                     beq     .ReplyMsg               ; leeres Kommando ''
  867.                     move.l  a0,a2                   ; a2=Scan (Rest)
  868.                     lea     Commands(pc),a0         ; a0=Schlüsselwörter
  869.                     lea     JmpTable(pc),a3         ; a3=Sprungtabelle
  870.                     move.l  #10,rm_Result1(a4)      ; sicherheitshalber RETURN_ERROR :-)
  871.                     tst.b   d0                      ; Anführungszeichen vorhanden?
  872.                     beq     .CmpNextCmd             ; nein: weiter
  873.                     subq.w  #1,d1                   ; TokenLength-1
  874.                     addq.l  #1,a1                   ; ' bzw. " übergehen
  875.  
  876. .CmpNextCmd         tst.b   (a0)                    ; weiteres Kommando bekannt?
  877.                     beq     .ReplyMsg               ; nein: zurückschicken
  878.                     move.l  d1,d0                   ; d1 Zeichen vergleichen
  879.                     bsr     _StrCmpA
  880.                     tst.b   d0                      ; Kommando bekannt?
  881.                     bne     .FoundCmd               ; ja: Funktion anspringen
  882. .SkipRest           tst.b   (a0)+                   ; nächstes Kommando
  883.                     bne     .SkipRest               ;  suchen
  884.                     addq.w  #4,a3                   ; JmpTableoffset erhöhen
  885.                     bra     .CmpNextCmd             ; nächstes vergleichen
  886.  
  887. .FoundCmd           movem.l d1-d6/a0-a4,-(a7)       ; Register sichern, damit das Kommando keinen Unsinn macht ;-)
  888.                     move.l  (a3),a3                 ; Adresse des Kommandos laden um ...Buttonaufrufe vorzubereiten
  889.                     move.l  a5,-(a7)                ; AppStruct auf Stack sichern
  890.                     move.l  40(a5),a0
  891.                     move.l  8(a0),a0                ; app->cdstr->cdx nach a0
  892.                     moveq   #0,d0                   ; Errorcode vordefinieren
  893.                     jsr     (a3)                    ; Kommando anspringen
  894.                     move.l  (a7)+,a5
  895.                     movem.l (a7)+,d1-d6/a0-a4       ; Register zurück
  896.                     move.l  d0,rm_Result1(a4)       ; Errorcode in RexxMsg setzen
  897.  
  898. .ReplyMsg           movea.l d3,a6                   ; SysBase wieder laden
  899.                     movea.l a4,a1
  900.                     jsr     _LVOReplyMsg(a6)        ; Message zurück
  901.                     tst.b   d7                      ; QUIT empfangen?
  902.                     bne     .EXIT                   ; ja: gleich beenden
  903.                     bra     .GetNextMsg             ;  und nächste holen
  904.  
  905. .EXIT               move.l  d7,d0                   ; "done" zurückgeben
  906.                     movem.l (sp)+,d1-d3/d7/a0-a6
  907.                     rts
  908.  
  909. PrivateMsg: dc.b 'ACDP',0
  910.  
  911.  
  912. *****************************  StrCmpA  ******************************
  913. *
  914. *  BOOL StrCmpA(register __a0 char *str1, register __a1 char *str2, register __d0 UWORD length);
  915. *
  916. * Vergleicht die Strings str1 und str2 Zeichen für Zeichen bis length oder
  917. * das Ende von str1 erreicht ist oder eine Abweichung erkannt wird. Dabei wird
  918. * nicht zwischen Groß- und Kleinschreibung unterschieden. Die Funktion gibt
  919. * nur dann TRUE zurück, wenn str1 vollständig in str2 enthalten ist.
  920. *
  921.   CNOP 0,2
  922.   xdef _StrCmpA
  923. _StrCmpA:   movem.l d1-d2/d7/a0-a1,-(sp)
  924.             moveq   #FALSE,d7           ; success=FALSE
  925.             subq.w  #1,d0               ; dbra geht bis -1, darum jetzt d0--
  926.  
  927. .GetChar1   move.b  (a0)+,d1            ; Byte aus String1 einlesen
  928.             cmpi.b  #'a',d1             ;  und gegebenenfalls
  929.             bcs     .GetChar2           ;  Kleinbuchstaben in Großbuchstaben
  930.             cmpi.b  #'z',d1             ;  wandeln
  931.             bhi     .GetChar2
  932.             bclr    #5,d1               ; 'a' <= d1 <= 'z'
  933. .GetChar2   move.b  (a1)+,d2            ; s.o.
  934.             cmpi.b  #'a',d2
  935.             bcs     .CmpChars
  936.             cmpi.b  #'z',d2
  937.             bhi     .CmpChars
  938.             bclr    #5,d2               ; 'a' <= d2 <= 'z'
  939. .CmpChars   cmp.b   d1,d2               ; Bytes identisch?
  940.             bne     .EXIT
  941.             dbra    d0,.GetChar1        ; wenn ja: weiter bis d0=-1
  942.             tst.b   (a0)                ; Ende von str1 erreicht?
  943.             bne     .EXIT               ; nein: str1 ist nicht in str2
  944.             moveq   #TRUE,d7            ; sonst: success=TRUE
  945.  
  946. .EXIT       move.l  d7,d0               ; return success
  947.             movem.l (sp)+,d1-d2/d7/a0-a1
  948.             rts
  949.  
  950.  
  951. ***********************  FlushMessagesA  *****************************
  952. *
  953. *  void FlushMessagesA(register __a0 struct MsgPort *port);
  954. *
  955. * Leert den MsgPort 'port', der auch NULL sein kann.
  956. *
  957.   CNOP 0,2
  958.   xdef _FlushMessagesA
  959. _FlushMessagesA:    movem.l d0-d2/a0-a1/a6,-(sp)
  960.                     move.l  a0,d2                   ; MsgPort sichern und testen
  961.                     beq     .EXIT
  962.                     move.l  4.w,a6                  ; SysBase laden
  963.  
  964. .loop               jsr     _LVOGetMsg(a6)          ; Msg holen
  965.                     tst.l   d0                      ; vorhanden?
  966.                     beq     .EXIT                   ; nein: Ende
  967.                     move.l  d0,a1
  968.                     jsr     _LVOReplyMsg(a6)        ; ja: antworten
  969.                     movea.l d2,a0                   ; MsgPort zurückholen
  970.                     bra     .loop                   ; nächste Msg holen
  971.  
  972. .EXIT               movem.l (sp)+,d0-d2/a0-a1/a6
  973.                     rts
  974.  
  975.  
  976. ***********************  MyGT_SetGadgetAttrs  *****************************
  977. *
  978. *  void MyGT_SetGadgetAttrs(struct Gadget *gadget, struct Window *window, struct Requester *req, ...);
  979. *
  980. * Prüft 'gadget' und 'window' auf NULL und ruft ggf. GT_SetGadgetAttrsA()
  981. * aus der gadtools.library auf. Diese Funktion basiert auf GT_SetGadgetAttrs()
  982. * aus der amiga.lib.
  983. *
  984.   CNOP 0,2
  985.   xdef _MyGT_SetGadgetAttrs
  986. _MyGT_SetGadgetAttrs:   link    a5,#0
  987.                         movem.l a2-a3/a6,-(sp)
  988.                         movea.l $0c(a5),d0
  989.                         beq     .EXIT
  990.                         move.l  d0,a1
  991.                         movea.l $08(a5),d0
  992.                         beq     .EXIT
  993.                         move.l  d0,a0
  994.                         lea     $14(a5),a3
  995.                         movea.l $10(a5),a2
  996.                         movea.l _GadToolsBase,a6
  997.                         jsr     _LVOGT_SetGadgetAttrsA(a6)
  998. .EXIT                   movem.l (sp)+,a2-a3/a6
  999.                         unlk    a5
  1000.                         rts
  1001.  
  1002.  
  1003.  include "rexxcmds.s"
  1004.  
  1005.