home *** CD-ROM | disk | FTP | other *** search
- ⓪ IMPLEMENTATION MODULE Loader;
- ⓪ (*$Y+,C-,R-,P-*)
- ⓪
- ⓪ (* V#477 *)
- ⓪ (*----------------------------------------------------------------------------
- ⓪"25.10.86 TT Grundversion
- ⓪"27.02.87 TT VarSpc wird beim Start gelöscht.
- ⓪"03.03.87 TT Layout wird endlich überprüft.
- ⓪"22.03.87 TT TermProcs werden nun richtig am Ende des Modlevels aufgerufen.
- ⓪"16.05.87 TT Komplette Umstrukturierung zusammen mit 'ModCtrl'
- ⓪"01.07.87 TT Paths.SearchFile wird verwendet.
- ⓪"18.07.87 TT Proc-Vars Loading/Releasing neu, varRef/Len und code/sourceName
- ⓪0werden aus Codefile geholt; ReadMod führt Directory-Search fort,
- ⓪0wenn beim Importieren der Modulname nicht stimmt.
- ⓪"23.07.87 TT ExecBody rettet/restauriert SR und SSP
- ⓪"11.08.87 TT DeAllocate korrekt, wenn Fehler bei ReadMod
- ⓪"25.08.87 TT SplitName korigiert.
- ⓪"26.08.87 TT CallModule kann auch gelinkte (TOS) Prg. starten
- ⓪"08.09.87 TT Bei neuem Process wird "parent's basepage" gesetzt
- ⓪"17.10.87 TT LoadModule auch für TOS-Prgs.
- ⓪"15.01.88 TT ReadMod: Erkennt illeg. Layout sofort; FClose, wenn RETURN
- ⓪0aus ReadMod wg. 'no memory'.
- ⓪0Seltsam. Ich meine, ich hätte diese Fehler schon mal behoben...
- ⓪"16.01.88 TT Kennung/Bit 4 als Flag f. 'procSym' wird erkannt
- ⓪"22.01.88 TT Kein Search bei Call/Load v. Prgs.; beim Laden v. Prgs. wird
- ⓪0erste Hälfte der Basepage gerettet und bei Exec zurückkopiert
- ⓪"23.01.88 TT Search wieder drin, Current Dirs/Drv werden bei prgExec gesetzt
- ⓪"04.03.88 TT layout zw. 0 und 15 erlaubt (bisher nur 0).
- ⓪"14.05.88 TT Module mit Namen > 8 Zeichen ausführbar.
- ⓪"08.06.88 TT Gecrunchte Module können gelinkt werden. Nur wenn Exportliste
- ⓪0nicht vorhanden ist, gibt's 'ne Fehlermeldung.
- ⓪"10.06.88 TT PRG-Files werden wiedergefunden, wenn geladen.
- ⓪"27.06.88 TT Wenn Modul nicht gefunden, wird wieder richtige Melgung ange-
- ⓪0zeigt.
- ⓪"30.09.88 TT ALLOCATE statt SysAlloc bei InitPrgSpace (da sowieso gleich
- ⓪0wieder freigegeben).
- ⓪"05.11.88 TT Release nun im Loader über Proc-Var implementiert
- ⓪"10.12.88 TT Pexec geändert, damit mit MOSLink lauffähig
- ⓪"20.12.88 TT Pexec korrigiert: Speicher wird wieder freigegeben
- ⓪"01.01.89 TT Infinite loop bei PrepareExec & release0 behoben (zirk. Importe)
- ⓪"17.02.89 TT Nicht geladene, gelinkte Prgs liefern wieder korrekten Exitcode
- ⓪"12.06.89 TT zirkulare Importe werden im Loader automatisch gelöst, Freigabe
- ⓪0nun auch schneller.
- ⓪"04.07.89 TT Release nochmals überarbeitet und korrigiert
- ⓪0>>> Freigabe zusammen mit MODCtrl/MODBase in MAUS M & MS.
- ⓪"04.07.89 TT Bei geladenen Prgs wird DATA-Bereich erst beim Starten kopiert.
- ⓪"06.07.89 TT Importierte Module dürfen Load/CallModule schon aufrufen, bevor
- ⓪0Hauptmodul init. ist (um z.B. Treiber nachzuladen). Es gibt
- ⓪0übrigens *keine* Probleme, wenn beide Programm dasselbe Modul
- ⓪0importieren. Je nach Import-Reihenfolge wird dann das Modul
- ⓪0entweder schon im 1. Prozeß init. und bleibt dann auch für den
- ⓪02. Prozeß aktiv oder es wird erst im 2. Prozeß init., aber dann
- ⓪0wird es dort bei dem Prozeßende auch wieder deinit. und beim
- ⓪01. Prozeß wiederum neu initialisiert.
- ⓪"20.08.89 TT Pexec verwendet nun wieder mode 0 -> Modload wiederum anpassen
- ⓪"08.09.89 TT Kein Hänger mehr bei Removals
- ⓪"05.11.89 TT Removals werden nun in korrekter Reihenfolge aufgerufen
- ⓪"20.12.89 TT hahaha! 5.11. war auch nicht OK: Reihenfolge war genau andersrum
- ⓪"01.01.90 TT Ich kapiert gar nix mehr... nun wieder wie am 5.11.
- ⓪"31.05.90 TT Non-reentry-Behandlung fertig
- ⓪"16.07.90 TT Nun werden ALLE importierten Module mit non-reentry initial.;
- ⓪0ExecMod räumt Speicher auch bei Fehlern korrekt wieder auf,
- ⓪0dadurch geht auch kein Speicher mehr beim Start geladener Prgs
- ⓪0verloren.
- ⓪"02.10.90 TT prgExec übergibt Prgname, damit TEMPUS 2.10 nicht abstürzt
- ⓪"11.10.90 TT Neue Real-Codes im Header ausgewertet
- ⓪"18.11.90 TT CallModule: DriverList- und Stacksize-Parms raus. Die sollen
- ⓪0später im Modulcode enthalten sein oder von CallModule in
- ⓪0einem extra File selbst gesucht werden.
- ⓪"26.11.90 TT ExecMod: "tooManyMods"-Fehler eingeführt (tritt auf, wenn
- ⓪0ExecList überläuft)
- ⓪"06.12.90 TT MaxModExec jetzt dynamisch in MOSConfig bestimmbar; IsModule()
- ⓪0schließt nun Datei nach Zugriff; Module/Prgs werden nicht mehr
- ⓪0anhand von Suffix sondern am Header erkannt.
- ⓪"14.12.90 TT Die Module mit $Y- werden NACH Aufruf aller Envelope-Routinen
- ⓪0für den Vater-Prozeß aufgerufen, damit die Envlp-Handler dann
- ⓪0noch auf die Vars des Vaters zugreifen können (um z.B. Werte
- ⓪0vom Vater an den Sohn zu kopieren - s. GEMEnv).
- ⓪"17.12.90 TT Die Stacksize wird aus dem Modheader übernommen, falls # 0.
- ⓪"05.02.91 TT Pfad wird aus Modulname bei Error-Msgs entfernt (errHandler);
- ⓪0"BadLayout"-Fehler kommt, wenn's kein Prg/Modul ist (check-
- ⓪0ExecRes).
- ⓪"24.02.91 TT Beim Start von geladenen Prgs wird "p_hitpa" nun korrekt
- ⓪0verwaltet, so daß z.B. TEMPUS 2.10 wieder fehlerfrei läuft;
- ⓪0DefaultStackSize kann nun jeden Wert annehmen, auch Null.
- ⓪"28.02.91 TT CallModule: Wenn 'arg[0]=CHR(127)', wird kein Längenbyte
- ⓪0eingefügt; Geladene Module/Prgs werden freigegeben, sobald der
- ⓪0Clienten-Prozeß terminiert und das Modul nicht mit SysAlloc
- ⓪0geladen wurde.
- ⓪"18.04.91 TT gesetztes Bit 7 (68020-Code) erzeugt keine Fehlermeldung wg.
- ⓪0falscher FPU mehr.
- ⓪"15.09.91 MS Relocate zerstört nicht mehr D3/A4
- ⓪"14.02.92 TT CallSuper statt Supexec
- ⓪"23.02.92 TT Stack wird in "CreateBasePage" alloziert.
- ⓪"12.12.93 TT prgFlags werden bei MM2-Modulen ausgewertet (f. TT-RAM usw.),
- ⓪0bei gelinkten, geladenen Prgs vorerst nicht, da hier nicht klar
- ⓪0ist, wie das geht.
- ⓪"16.01.94 TT Um das zu eigene Real-Format zu ermitteln, wird nicht mehr
- ⓪0FPU() aufgerufen, weil das nicht mit den gelinkten Libs über-
- ⓪0einstimmen muß, sondern es wird RealMode abgefragt.
- ⓪ *---------------------------------------------------------------------------*)
- ⓪
- ⓪ (* Beim Relozieren Bus/Addr-Error abfangen ! *)
- ⓪
- ⓪ FROM MOSGlobals IMPORT SfxStr, NameStr, PfxStr, MemArea, Overflow, IllegalState;
- ⓪
- ⓪ FROM PrgCtrl IMPORT EnvlpCarrier, SetEnvelope, RemoveEnvelope, TermProcess;
- ⓪
- ⓪ FROM MOSSupport IMPORT CallSuper;
- ⓪
- ⓪ IMPORT SystemError;
- ⓪
- ⓪ FROM SYSTEM IMPORT ASSEMBLER, CADR, ADR, WORD, ADDRESS, TSIZE, LONGWORD, BYTE;
- ⓪
- ⓪ FROM Strings IMPORT Upper, Concat, Length, Pos, Copy, Append, Insert, PosLen,
- ⓪4Compare, Relation, Empty, String, Assign, Split, Delete,
- ⓪4StrEqual;
- ⓪
- ⓪ FROM Storage IMPORT Inconsistent, SysAlloc, MemAvail, DeAllocate, ALLOCATE;
- ⓪ FROM StorBase IMPORT FullStorBaseAccess;
- ⓪
- ⓪ FROM MOSCtrl IMPORT RemovalRoot, RemovalEntry, CallSub, ProcessID, RealMode;
- ⓪
- ⓪ FROM SysTypes IMPORT PtrBP;
- ⓪
- ⓪ FROM ModBase IMPORT CallEnvelopes, ModLst, ModRef, ModStr, ModEntry,
- ⓪0GetModRef, Release, ModStates, ModState, SearchDesc,
- ⓪0SplitModName, ModLoaded, MarkState, Criterion, PtrBSS,
- ⓪0FreeMod, ExecProcess, CreateBasePage, ModHeader;
- ⓪
- ⓪ FROM Lists IMPORT ResetList, NextEntry, AppendEntry, RemoveEntry,
- ⓪(FindEntry, List, LDir;
- ⓪
- ⓪ FROM Paths IMPORT SearchFile, ListPos;
- ⓪ FROM PathCtrl IMPORT PathList;
- ⓪
- ⓪ FROM MOSConfig IMPORT LoaderMsg, MaxModExec;
- ⓪
- ⓪ FROM Directory IMPORT MakeFullPath;
- ⓪ FROM FileNames IMPORT FileSuffix, SplitName, FilePrefix, SplitPath;
- ⓪ IMPORT FileNames;
- ⓪
- ⓪ FROM SysInfo IMPORT UseStackFrame, CPU;
- ⓪ FROM MOSSupport IMPORT ToSuper, ToUser;
- ⓪ IMPORT XBRA;
- ⓪ IMPORT Block;
- ⓪
- ⓪ (*
- ⓪"FROM Terminal IMPORT WriteLn, WriteString, Read, Write;
- ⓪ *)
- ⓪
- ⓪ CONST Trace = FALSE;
- ⓪&Trace0 = FALSE; (* Prg Start *)
- ⓪&Trace2 = FALSE; (* release *)
- ⓪&Trace3 = FALSE; (* init *)
- ⓪
- ⓪ (*$ ? Trace OR Trace0 OR Trace2 OR Trace3:
- ⓪"VAR inch: CHAR;
- ⓪ *)
- ⓪
- ⓪ CONST
- ⓪#MaxModNest = 15;
- ⓪'anykey = 0L; (* Joker fuer Modul-Key *)
- ⓪
- ⓪&Kennung = "MM2L";
- ⓪
- ⓪ TYPE tCallPtr = [0..MaxModNest];
- ⓪
- ⓪
- ⓪'ExecCondition = (ExecAlways, ExecNever, ExecNew);
- ⓪'
- ⓪'ArgStr = ARRAY [0..127] OF CHAR;
- ⓪&FileStr = ARRAY [0..141] OF CHAR;
- ⓪
- ⓪ VAR
- ⓪&CallPtr: tCallPtr;
- ⓪$ChainName: ARRAY tCallPtr OF FileStr;
- ⓪%ChainArg: ARRAY tCallPtr OF ArgStr;
- ⓪
- ⓪$error, ok: BOOLEAN;
- ⓪
- ⓪&ExecPtr: CARDINAL;
- ⓪%ExecList: POINTER TO ARRAY [0..5000] OF ModRef;
- ⓪
- ⓪ (* das geht nun über msr2:
- ⓪"PROCEDURE willBeInit (ref0:ModRef):BOOLEAN;
- ⓪$(*$L-*)
- ⓪$BEGIN
- ⓪&ASSEMBLER
- ⓪(MOVE.W ExecPtr,D0
- ⓪(MOVE.L ExecList,A0
- ⓪(MOVE.L -(A3),D1
- ⓪(BRA c
- ⓪&l CMP.L (A0)+,D1
- ⓪&c DBEQ D0,l
- ⓪(SEQ D0
- ⓪(ANDI #1,D0
- ⓪(MOVE D0,(A3)+
- ⓪&END
- ⓪$END willBeInit;
- ⓪$(*$L=*)
- ⓪ *)
- ⓪
- ⓪ PROCEDURE markForInit (ref0: ModRef): BOOLEAN;
- ⓪"BEGIN
- ⓪$(*$ ? Trace3: WriteLn; WriteString (ref0^.codeName^); WriteString (' marked for init.'); *)
- ⓪$IF ExecPtr > MaxModExec THEN
- ⓪&RETURN FALSE
- ⓪$ELSE
- ⓪&ExecList^[ExecPtr]:= ref0; inc (ExecPtr);
- ⓪&RETURN TRUE
- ⓪$END
- ⓪"END markForInit;
- ⓪
- ⓪
- ⓪ VAR enterFailed: BOOLEAN;
- ⓪
- ⓪ PROCEDURE enterMods (open, child: BOOLEAN; VAR exitcode: INTEGER);
- ⓪"(* jedes Modul vorbereiten, ggf. VarSpace retten/löschen *)
- ⓪"VAR execThis: CARDINAL; ad: PtrBSS;
- ⓪"BEGIN
- ⓪$IF open & NOT child THEN
- ⓪&(* wir sind der letzte Env-Handler *)
- ⓪&execThis:= 0;
- ⓪&WHILE execThis < ExecPtr DO
- ⓪(WITH ExecList^[execThis]^ DO
- ⓪*IF ~(initialized IN state) THEN
- ⓪,Block.Clear (varRef, varLen)
- ⓪*ELSIF ~(reentrant IN state) & ~(installed IN state) THEN
- ⓪,(* bei nicht-reentrant-fähigen Modulen wird das alte BSS gerettet
- ⓪-* und dann der BSS-Bereich wie üblich gelöscht *)
- ⓪,(*$ ? Trace: WriteLn; WriteString (codename^); WriteString (' gets new BSS'); *)
- ⓪,ALLOCATE (ad, varLen + 4L);
- ⓪,IF ad = NIL THEN
- ⓪.enterfailed:= TRUE;
- ⓪.exitcode:= -39; (* out of mem *)
- ⓪.RETURN
- ⓪,END;
- ⓪,Block.Copy (varRef, varLen, ADDRESS(ad) + 4L);
- ⓪,ad^.prev:= prevBSS;
- ⓪,prevBSS:= ad;
- ⓪,Block.Clear (varRef, varLen)
- ⓪*END;
- ⓪(END;
- ⓪(INC (execThis);
- ⓪&END;
- ⓪&enterfailed:= FALSE;
- ⓪$END
- ⓪"END enterMods;
- ⓪
- ⓪
- ⓪ PROCEDURE Fopen ( REF fname: ARRAY OF CHAR; mode : Cardinal;
- ⓪2VAR handle : Cardinal; VAR ior : Integer ) : Boolean;
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(MOVE mode(A6),-(A7)
- ⓪(MOVE.L fname(A6),-(A7)
- ⓪(MOVE #$3D,-(A7)
- ⓪(TRAP #1
- ⓪(ADDQ.L #8,A7
- ⓪(CLR D1
- ⓪(TST.L D0
- ⓪(BMI err
- ⓪(MOVE D0,D1
- ⓪(CLR D0
- ⓪"err MOVE.L ior(A6),A0
- ⓪(MOVE D0,(A0)
- ⓪(MOVE.L handle(A6),A0
- ⓪(MOVE D1,(A0)
- ⓪$END;
- ⓪$RETURN ior = 0
- ⓪"END Fopen;
- ⓪
- ⓪ PROCEDURE Fseek (handle:Cardinal; n:LongCard; mode:Cardinal; VAR p:Longword);
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(MOVE mode(A6),-(A7)
- ⓪(MOVE handle(A6),-(A7)
- ⓪(MOVE.L n(A6),-(A7)
- ⓪(MOVE #$42,-(A7)
- ⓪(TRAP #1
- ⓪(ADDA.W #10,A7
- ⓪(MOVE.L p(A6),A0
- ⓪(MOVE.L D0,(A0)
- ⓪$END;
- ⓪"END Fseek;
- ⓪
- ⓪ PROCEDURE Fclose (handle:Cardinal);
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(MOVE handle(A6),-(A7)
- ⓪(MOVE #$3E,-(A7)
- ⓪(TRAP #1
- ⓪(ADDQ.L #4,A7
- ⓪$END
- ⓪"END Fclose;
- ⓪
- ⓪ PROCEDURE Fread (handle:Cardinal; p: Address; l:LongInt): LONGINT;
- ⓪"VAR res: LONGINT;
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(MOVE.L p(A6),-(A7)
- ⓪(MOVE.L l(A6),-(A7)
- ⓪(MOVE handle(A6),-(A7)
- ⓪(MOVE #$3F,-(A7)
- ⓪(TRAP #1
- ⓪(ADDA.W #12,A7
- ⓪(MOVE.L D0,res(A6)
- ⓪$END;
- ⓪$RETURN res
- ⓪"END Fread;
- ⓪
- ⓪
- ⓪ PROCEDURE ldHead (handle: CARDINAL;
- ⓪2VAR mlen: LONGCARD;
- ⓪2VAR mid: BYTE;
- ⓪2VAR loadres: LoaderResults);
- ⓪"VAR chead: RECORD
- ⓪/id: ARRAY [0..7] OF CHAR;
- ⓪/layout: BYTE;
- ⓪/modId: BYTE;
- ⓪/res: ARRAY [1..8] OF BYTE;
- ⓪/modlen: LONGCARD;
- ⓪-END;
- ⓪&l: LONGINT; modId2: CARDINAL;
- ⓪"BEGIN
- ⓪$l:= Fread (handle, ADR (chead), SIZE (chead));
- ⓪$IF l < 0L THEN
- ⓪&loadres := badFile;
- ⓪$ELSE
- ⓪&modId2:= ORD (chead.modId) MOD 16;
- ⓪&IF (Compare ("MM2Code", chead.id) # equal)
- ⓪&OR (ORD(chead.layout)>15)
- ⓪&OR ( (modId2#1) & (modId2#2) ) THEN
- ⓪(loadres:= badLayout;
- ⓪&ELSE
- ⓪(loadres:= noError;
- ⓪(mlen:= chead.modlen;
- ⓪(mid:= chead.modId
- ⓪&END
- ⓪$END;
- ⓪"END ldHead;
- ⓪
- ⓪
- ⓪ PROCEDURE IsModule ( REF fileName: ARRAY OF CHAR ): BOOLEAN;
- ⓪"VAR handle: CARDINAL; ior: INTEGER; r: BOOLEAN; res: LoaderResults;
- ⓪&lc: LONGCARD; b: BYTE;
- ⓪"BEGIN
- ⓪$IF Fopen (fileName,0,handle,ior) THEN
- ⓪&ldHead (handle, lc, b, res);
- ⓪&r:= res = noError;
- ⓪&Fclose (handle)
- ⓪$ELSE
- ⓪&r:= FALSE
- ⓪$END;
- ⓪$RETURN r
- ⓪"END IsModule;
- ⓪
- ⓪
- ⓪ PROCEDURE SetChain ( REF ModName, Arg : ARRAY OF Char );
- ⓪"(*
- ⓪#* Modul fuer Chaining vormerken
- ⓪#*)
- ⓪"BEGIN
- ⓪$Assign (ModName, ChainName [CallPtr],ok);
- ⓪$Copy (arg,0,127,ChainArg [CallPtr],ok);
- ⓪"END SetChain;
- ⓪
- ⓪
- ⓪ PROCEDURE prgLoad (REF n:ARRAY OF CHAR): LONGINT;
- ⓪"(*$L-*)
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(CLR.L -(A7) ; Environment
- ⓪(MOVE.L A7,-(A7) ; Cmd-Line: Zeigt auf Leerstring
- ⓪(SUBQ.L #2,A3
- ⓪(MOVE.L -(A3),-(A7) ; Name des Prg.
- ⓪(MOVE #3,-(A7) ; Load-Cmd
- ⓪(MOVE #$4B,-(A7) ; Pexec()
- ⓪(TRAP #1
- ⓪(ADDA.W #16,A7
- ⓪(MOVE.L D0,(A3)+
- ⓪$END
- ⓪"END prgLoad;
- ⓪"(*$L=*)
- ⓪
- ⓪
- ⓪ PROCEDURE SetMsg (n: CARDINAL; VAR s: ARRAY OF CHAR);
- ⓪"BEGIN
- ⓪$IF LoaderMsg # NIL THEN
- ⓪&Assign (LoaderMsg^[n], s, ok);
- ⓪$END
- ⓪"END SetMsg;
- ⓪
- ⓪ PROCEDURE checkExecRes (execRes: INTEGER; VAR myRes: LoaderResults;
- ⓪9REF name: ARRAY OF CHAR; VAR myMsg: ARRAY OF CHAR);
- ⓪"VAR n: CARDINAL;
- ⓪"BEGIN
- ⓪$IF execRes = 0 THEN
- ⓪&myRes:= noError;
- ⓪&myMsg[0]:= ''
- ⓪$ELSE
- ⓪&IF (execRes = -46) OR (execRes = -33) OR (execRes = -34) THEN
- ⓪(myRes:= notFound;
- ⓪(n:= 11
- ⓪&ELSIF (execRes = -39) THEN
- ⓪(myRes:= outOfMemory;
- ⓪(n:= 6
- ⓪&ELSIF (execRes = -66) THEN
- ⓪(myRes:= badLayout;
- ⓪(n:= 4;
- ⓪&ELSE
- ⓪(myRes:= badFile;
- ⓪(n:= 10
- ⓪&END;
- ⓪&SetMsg (n, myMsg);
- ⓪&IF n = 4 THEN
- ⓪(n:= PosLen ('@I',myMsg,0);
- ⓪(Delete (myMsg,n,2,ok);
- ⓪(Insert (FilePrefix(name),n,myMsg,ok);
- ⓪&END
- ⓪$END
- ⓪"END checkExecRes;
- ⓪
- ⓪
- ⓪ PROCEDURE MovStr (VAR s:ARRAY OF CHAR;d:Longword);
- ⓪"(*$L-*)
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪&MOVE.L -10(A3),(A3)+
- ⓪&MOVE.W -10(A3),(A3)+
- ⓪&JSR Length
- ⓪&MOVE.W -(A3),D0
- ⓪&CMPI #127,D0
- ⓪&BLS ok0
- ⓪&MOVEQ #127,D0
- ⓪$ok0
- ⓪&MOVE.L -(A3),A2
- ⓪&SUBQ.L #2,A3
- ⓪&MOVE.L -(A3),A1
- ⓪&MOVE.B D0,(A2)+
- ⓪&BRA cop
- ⓪$clrlp
- ⓪&MOVE.B (A1)+,(A2)+
- ⓪$cop
- ⓪&DBRA D0,clrlp
- ⓪$END
- ⓪"END MovStr;
- ⓪"(*$L=*)
- ⓪
- ⓪
- ⓪ PROCEDURE Mfree (addr: ADDRESS);
- ⓪"(*$L-*)
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(MOVE.L -(A3),-(A7)
- ⓪(MOVE #$49,-(A7)
- ⓪(TRAP #1
- ⓪(ADDQ.L #6,A7
- ⓪$END
- ⓪"END Mfree;
- ⓪"(*$L=*)
- ⓪
- ⓪ PROCEDURE prgUnload (bp:PtrBP);
- ⓪"BEGIN
- ⓪$(* nicht DEALLOCATE verwenden, da sonst u.U. Fehler passieren?! *)
- ⓪$Mfree (bp^.p_env); (* Environment freigeben *)
- ⓪$Mfree (bp) (* TPA / Prg. *)
- ⓪"END prgUnload;
- ⓪
- ⓪ PROCEDURE Mshrink (addr: ADDRESS; newAmount: LONGCARD);
- ⓪"(*$L-*)
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(MOVE.L -(A3),-(A7)
- ⓪(MOVE.L -(A3),-(A7)
- ⓪(CLR.W -(A7)
- ⓪(MOVE #$4A,-(A7)
- ⓪(TRAP #1
- ⓪(ADDA.W #12,A7
- ⓪$END
- ⓪"END Mshrink;
- ⓪"(*$L=*)
- ⓪
- ⓪ PROCEDURE envLength (env: ADDRESS): LONGCARD;
- ⓪"(* Liefert die Länge eines Environment-Strings *)
- ⓪"VAR (*$Reg*) p: POINTER TO CHAR;
- ⓪"BEGIN
- ⓪$p:= env;
- ⓪$WHILE p^ # 0C DO
- ⓪&REPEAT
- ⓪(INC (p)
- ⓪&UNTIL p^ = 0C;
- ⓪&INC (p)
- ⓪$END;
- ⓪$RETURN ADDRESS (p) - env + 2
- ⓪"END envLength;
- ⓪
- ⓪ PROCEDURE CodeSize (bp: PtrBP): LONGCARD;
- ⓪"(* Liefert Länge des statisch belegten Bereichs ohne den Heap-Bonus *)
- ⓪"BEGIN
- ⓪$WITH bp^ DO RETURN 256 + p_tlen + p_dlen + p_blen END
- ⓪"END CodeSize;
- ⓪
- ⓪ PROCEDURE prgPrepare (bp:PtrBP; heap:LONGCARD): BOOLEAN;
- ⓪"VAR newlen:LONGCARD; bpsize: LONGCARD;
- ⓪"BEGIN
- ⓪$(* belegter Speicher (TPA): *)
- ⓪$bpsize:= LONGCARD (bp^.p_hitpa) - LONGCARD (bp);
- ⓪$(* benötigter Speicher: *)
- ⓪$newlen:= CodeSize (bp) + heap;
- ⓪$(* Haben wir genug im TPA erhalten? *)
- ⓪$IF newlen > bpsize THEN
- ⓪&prgUnload (bp);
- ⓪&RETURN FALSE
- ⓪$END;
- ⓪$(* TPA verkleinern *)
- ⓪$Mshrink (bp, newlen);
- ⓪$bp^.p_hitpa:= ADDRESS (bp) + newlen;
- ⓪$RETURN TRUE
- ⓪"END prgPrepare;
- ⓪
- ⓪ VAR CurrentField, CurrentBasePage: ADDRESS;
- ⓪(TPAOffset: LONGCARD;
- ⓪(GemdosEntry: ADDRESS;
- ⓪(StackFrameOffs: SHORTCARD;
- ⓪(Carrier: XBRA.Carrier;
- ⓪
- ⓪ PROCEDURE removeGemdosHdler;
- ⓪"(*
- ⓪#* Trägt den hiesigen GEMDOS-Handler (hdlGemdos) aus.
- ⓪#*)
- ⓪"(*$L-*)
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(LEA Carrier,A2
- ⓪(ADDA.W #12,A2
- ⓪(LEA $84,A0 ; A0: Vektoradr.
- ⓪%l: MOVE.L (A0),A1
- ⓪(CMPA.L A2,A1 ; 'entry' gefunden?
- ⓪(BEQ f
- ⓪(CMPI.L #$58425241,-12(A1) ; Ist dies ein XBRA-Eintrag?
- ⓪(BNE n ; Nein -> Ende
- ⓪(LEA -4(A1),A0 ; Vorige Vektoradr. nach A0
- ⓪(CMPA.L (A0),A1 ; Vektor zeigt auf sich selbst?
- ⓪(BEQ n
- ⓪(BRA l
- ⓪%f: MOVE.L -4(A1),(A0) ; Entry.old eintragen
- ⓪%n:
- ⓪$END;
- ⓪"END removeGemdosHdler;
- ⓪"(*$L=*)
- ⓪
- ⓪ PROCEDURE hdlGemdos;
- ⓪ (*
- ⓪!* Diese Funktion hängt im GEMDOS-TRAP-Handler und wartet darauf, daß
- ⓪!* das über 'CallProgram' gestartete Programm die 'Mshrink'-Funktion
- ⓪!* aufruft. Dann wird daraus die benötigte Heap-Größe ermittelt und
- ⓪!* diese Funktion wieder ausgehängt.
- ⓪!*)
- ⓪"(*$L-*)
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(BTST.B #5,(A7) ; War Supervisormode aktiv ?
- ⓪(BNE.B super ; Ja, dann stehen Arg. auf SSP
- ⓪(MOVE.L USP,A0
- ⓪(CMPI.W #$4A,(A0) ; Mshrink - Funktion ?
- ⓪(BEQ.B hdlMshrinkUser
- ⓪ dos ; normale GEMDOS-Funktion ausführen
- ⓪(MOVE.L GemdosEntry,A0
- ⓪(MOVE.L -4(A0),A0
- ⓪(JMP (A0)
- ⓪ super MOVE.W StackFrameOffs,D0 ; damit es auch mit einer 68010/20/30 geht
- ⓪(CMPI.W #$4A,6(A7,D0.W) ; Mshrink - Funktion ?
- ⓪(BNE.B dos ; Nein -> GEMDOS aufrufen
- ⓪(LEA 6(A7,D0.W),A0 ; Basis d. Argumente nach A0
- ⓪ hdlMshrinkUser
- ⓪(MOVE.L 4(A0),A1 ; Argument 'addr' von Mshrink (addr, newamount)
- ⓪(CMPA.L CurrentBasePage,A1 ; ist es die TPA des gesuchten Programms?
- ⓪(BNE dos
- ⓪(MOVE.L 8(A0),D0 ; 'newamount'-Parm von Mshrink: neue TPA-Größe
- ⓪(MOVE.L D0,D1
- ⓪(ADD.L A1,D0
- ⓪(CMP.L 4(A1),D0 ; newamout > p_hitpa (alte TPA-Größe)?
- ⓪(BHI noNewHi ; dann ist zu wenig Speicher da
- ⓪(MOVE.L D0,4(A1) ; p_hitpa in Base Page neu setzen
- ⓪ noNewHi
- ⓪ (*
- ⓪(TST.L UsedHeapSize
- ⓪(BPL ignore ; Heap-Größe wurde bereits ermittelt
- ⓪(SUB.L TPAOffset,D1 ; Subtr. die Größe des stat. Bereichs ohne Heap
- ⓪(MOVE.L D1,UsedHeapSize ; Das ist die gesuchte Heap-Größe
- ⓪(MOVE.L CurrentField,A0
- ⓪(MOVE.L D1,PrgEntry.neededHeapSize(A0)
- ⓪(CMP.L PrgEntry.currentHeapSize(A0),D1
- ⓪(BCC ignore
- ⓪(MOVE.L D1,PrgEntry.currentHeapSize(A0)
- ⓪ ignore
- ⓪ *)
- ⓪(; Diese Routine kann nun aus dem GEMDOS-TRAP entfernt werden
- ⓪(JSR removeGemdosHdler
- ⓪(BRA dos ; Nun lassen wir endlich Mshrink ausführen
- ⓪$END
- ⓪"END hdlGemdos;
- ⓪"(*$L=*)
- ⓪
- ⓪ PROCEDURE prgExec (bp:PtrBP; name: ADDRESS; REF arg: ArgStr;
- ⓪3env: ADDRESS; VAR res: INTEGER): BOOLEAN;
- ⓪"(*
- ⓪#* geladenes, gelinktes Programm starten
- ⓪#*)
- ⓪
- ⓪"VAR el, dl: LONGCARD; envcopy, hitpa, data: ADDRESS;
- ⓪
- ⓪"BEGIN
- ⓪$dl:= bp^.p_dlen + 128L; (* Länge des zu rettenden Data/Basepage-Bereichs *)
- ⓪$ALLOCATE (data,dl);
- ⓪$IF data = NIL THEN
- ⓪&RETURN FALSE
- ⓪$END;
- ⓪$Block.Copy (bp,128,data);
- ⓪$Block.Copy (bp^.p_dbase,bp^.p_dlen,data+128L);
- ⓪$Block.Clear (bp^.p_bbase, bp^.p_hitpa - bp^.p_bbase);
- ⓪
- ⓪$(* Environment kopieren, da Pexec dies wie so vieles *
- ⓪%* beim Nur-Starten fälschlicherweise nicht tut. *)
- ⓪$
- ⓪$IF env # 0 THEN
- ⓪&el:= envLength (env);
- ⓪&ALLOCATE (envcopy, el);
- ⓪&IF envcopy = NIL THEN
- ⓪(RETURN FALSE
- ⓪&END;
- ⓪&Block.Copy (env, el, envcopy);
- ⓪&bp^.p_env:= envcopy; (* p_env wird am Ende wg. ganzer BP restauriert *)
- ⓪$END;
- ⓪
- ⓪$Block.Copy (CADR(arg),128,ADR(bp^.cmdline));
- ⓪$(*$?Trace0:Write('4');Read(inch);IF Inconsistent() THEN HALT END;*)
- ⓪$ASSEMBLER
- ⓪(MOVE.L bp(A6),A0
- ⓪(
- ⓪(; Pfade v. Parent übernehmen
- ⓪(MOVE.L ProcessID,A2
- ⓪(MOVE.L (A2),A2
- ⓪(MOVE.B $37(A2),$37(A0) ; Default-Drive
- ⓪(MOVEQ #7,D0 ; 16 Pfade (Bytes-Handles)
- ⓪(LEA $40(A0),A1
- ⓪(LEA $40(A2),A2
- ⓪&lll:
- ⓪(MOVE.W (A2)+,(A1)+
- ⓪(DBRA D0,lll
- ⓪(
- ⓪(; DTA auf Cmdline
- ⓪(MOVE.L A0,A1
- ⓪(ADDA.W #128,A1
- ⓪(MOVE.L A1,PtrBP.p_dta(A0)
- ⓪$END;
- ⓪
- ⓪$(* 'hdlGemdos' in TRAP #1 einhängen *)
- ⓪$XBRA.Create (Carrier, Kennung, ADDRESS (hdlGemdos), GemdosEntry);
- ⓪$XBRA.Install (GemdosEntry, $84);
- ⓪
- ⓪$(* Prozeß starten *)
- ⓪$TPAOffset:= CodeSize (bp);
- ⓪$CurrentBasePage:= bp;
- ⓪$ASSEMBLER
- ⓪(; GEMDOS.Pexec (4, filename, bp, env, exitcode);
- ⓪(MOVE.L env(A6),-(A7) ; unused
- ⓪(MOVE.L bp(A6),-(A7) ; ^basepage
- ⓪(MOVE.L name(A6),-(A7) ; unused, f. Kompatibilität: ^path
- ⓪(MOVE #4,-(A7) ; Exec-Cmd
- ⓪(MOVE #$4B,-(A7) ; Pexec()
- ⓪(TRAP #1
- ⓪(ADDA.W #16,A7
- ⓪(MOVE.L res(A6),A0
- ⓪(MOVE.W D0,(A0)
- ⓪$END;
- ⓪$CurrentBasePage:= NIL;
- ⓪
- ⓪$(* 'hdlGemdos' wieder aushängen *)
- ⓪$ASSEMBLER
- ⓪(PEA removeGemdosHdler
- ⓪(JSR CallSuper
- ⓪(ADDQ.L #4,A7
- ⓪$END;
- ⓪$
- ⓪$IF env # 0 THEN
- ⓪&DEALLOCATE (envcopy, 0) (* Kopie vom Environment wieder freigeben *)
- ⓪$END;
- ⓪
- ⓪$(*$?Trace0:Write('5');Read(inch);IF Inconsistent() THEN HALT END;*)
- ⓪$hitpa:= bp^.p_hitpa;
- ⓪$Block.Copy (data,128,bp);
- ⓪$bp^.p_hitpa:= hitpa;
- ⓪$Block.Copy (data+128L,bp^.p_dlen,bp^.p_dbase);
- ⓪$DEALLOCATE (data, 0L);
- ⓪$RETURN TRUE
- ⓪"END prgExec;
- ⓪
- ⓪ (*
- ⓪ PROCEDURE tosPrg (VAR mname:ARRAY OF Char): BOOLEAN;
- ⓪"VAR sfx: SfxStr; i:CARDINAL;
- ⓪"BEGIN
- ⓪$sfx:= FileSuffix (mname);
- ⓪$IF sfx[0] # 0C THEN
- ⓪&Upper (sfx);
- ⓪&FOR i:=1 TO NoOfPrgSfx DO
- ⓪(IF StrEqual (PrgSfx [i], sfx) THEN
- ⓪*RETURN TRUE
- ⓪(END
- ⓪&END
- ⓪$END;
- ⓪$RETURN FALSE
- ⓪"END tosPrg;
- ⓪ *)
- ⓪
- ⓪ MODULE loader0;
- ⓪
- ⓪ IMPORT ASSEMBLER, ExecList, ExecPtr, ModRef, TermProcess, Block,
- ⓪'Monitor, ModState, ADDRESS, ModEntry (*, ModUtil2 *),
- ⓪'CPU, ToSuper, ToUser;
- ⓪
- ⓪ EXPORT initMods;
- ⓪
- ⓪ PROCEDURE execBody (mod0: ModRef; mon: ADDRESS);
- ⓪"(*$L-*)
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪&MOVE.L -(A3),D0
- ⓪&MOVE.L -(A3),A1
- ⓪&MOVEM.L D3-D7/A3-A6,-(A7)
- ⓪
- ⓪&PEA modReturn(PC)
- ⓪
- ⓪&MOVE.L ModEntry.header(A1),A1
- ⓪&ADDA.L 6(A1),A1 ;Adresse des Rumpfes berechnen
- ⓪&PEA (A1)
- ⓪
- ⓪&TST.L D0
- ⓪&BNE moncall
- ⓪&RTS
- ⓪$moncall
- ⓪&MOVE.L D0,A1
- ⓪&JMP (A1)
- ⓪&
- ⓪$modReturn
- ⓪&MOVEM.L (A7)+,D3-D7/A3-A6
- ⓪$END
- ⓪"END execBody;
- ⓪"(*$L=*)
- ⓪
- ⓪ PROCEDURE initMods;
- ⓪"VAR execThis: CARDINAL; mod0: ModRef; mon: ADDRESS;
- ⓪"BEGIN
- ⓪$execThis:= 0;
- ⓪$mon:= NIL;
- ⓪$WHILE execThis < ExecPtr DO
- ⓪&mod0:= ExecList^[execThis];
- ⓪&INC (execThis);
- ⓪&WITH mod0^ DO
- ⓪(IF ~(initialized IN state) THEN
- ⓪*INCL (state,initialized);
- ⓪*INCL (state,firstcall);
- ⓪(END;
- ⓪&END;
- ⓪&IF execThis = ExecPtr THEN
- ⓪(mon:= ADDRESS (Monitor);
- ⓪&END;
- ⓪&(* ModUtil2.CallBody (mod0); *)
- ⓪&execBody (mod0, mon);
- ⓪&(* ModUtil2.LeaveBody (mod0); *)
- ⓪&EXCL (mod0^.state,firstcall)
- ⓪$END;
- ⓪"END initMods;
- ⓪
- ⓪ END loader0;
- ⓪
- ⓪
- ⓪ PROCEDURE outerErrHandler (REF name, clientname: ARRAY OF CHAR;
- ⓪;nowImport: BOOLEAN; errtype: LoaderResults;
- ⓪;VAR errmsg: ARRAY OF CHAR);
- ⓪"PROCEDURE get (idx,n:CARDINAL);
- ⓪$BEGIN
- ⓪&SetMsg (idx, errmsg);
- ⓪&IF n#0 THEN
- ⓪(idx:= PosLen ('@I',errmsg,0);
- ⓪(Delete (errmsg,idx,2,ok);
- ⓪(Insert (FilePrefix(name),idx,errmsg,ok);
- ⓪(IF n=2 THEN
- ⓪*idx:= PosLen ('@C',errmsg,0);
- ⓪*Delete (errmsg,idx,2,ok);
- ⓪*Insert (clientname,idx,errmsg,ok);
- ⓪(END
- ⓪&END
- ⓪$END get;
- ⓪"BEGIN
- ⓪$CASE errtype OF
- ⓪&badversion:
- ⓪(get (5,2)|
- ⓪&BadLayout:
- ⓪(get (4,1)|
- ⓪&NotFound:
- ⓪(IF nowImport THEN
- ⓪*get (1,2)
- ⓪(ELSE
- ⓪*get (0,1)
- ⓪(END|
- ⓪&BadFile:
- ⓪(get (2,1)|
- ⓪&BadData:
- ⓪(get (3,1)|
- ⓪&OutOfMemory:
- ⓪(get (6,0)|
- ⓪&denied:
- ⓪(get (7,1)|
- ⓪&initFault:
- ⓪(get (12,0)|
- ⓪&exitFault:
- ⓪(get (13,0)|
- ⓪¬Linkable:
- ⓪(get (14,1)|
- ⓪&wrongRealForm:
- ⓪(get (15,1)|
- ⓪&wrongFPUType:
- ⓪(get (16,1)|
- ⓪&tooManyMods:
- ⓪(get (17,0)|
- ⓪$ELSE HALT
- ⓪$END
- ⓪"END outerErrHandler;
- ⓪
- ⓪ (*$X+*)
- ⓪ PROCEDURE FlushCPUCache ();
- ⓪"BEGIN
- ⓪$ASSEMBLER
- ⓪(JSR CPU
- ⓪(SUBQ.L #4,A7
- ⓪(JSR ToSuper
- ⓪(MOVE.L -(A3),D0
- ⓪(CMPI.L #68020,D0
- ⓪(BCS ende
- ⓪(CMPI.L #68040,D0
- ⓪(BCS fl30
- ⓪(NOP
- ⓪(DC.W $F4F8 ; CPUSHA BC
- ⓪(BRA ende
- ⓪"fl30: MOVEC CACR,D0
- ⓪(ORI #$0808,D0
- ⓪(MOVEC D0,CACR
- ⓪"ende: JSR ToUser
- ⓪(ADDQ.L #4,A7
- ⓪$END
- ⓪"END FlushCPUCache;
- ⓪ (*$X=*)
- ⓪
- ⓪ PROCEDURE ExecMod (REF mainName: ARRAY OF CHAR; (* Name des gewuenschten Moduls *)
- ⓪4exec: ExecCondition; (* wann ausfuehren? *)
- ⓪3Paths: PathList;
- ⓪1REF Arg: ArgStr;
- ⓪5env: ADDRESS;
- ⓪,VAR ExitCode: Integer;
- ⓪.VAR ErrMsg: ARRAY OF CHAR;
- ⓪-VAR loadres: LoaderResults)
- ⓪8: ModRef; (* vergebener Index *)
- ⓪8
- ⓪#VAR nowimport: Boolean;
- ⓪'clientname: ModStr;
- ⓪
- ⓪"PROCEDURE errHandler (REF name:ARRAY OF CHAR; errtype:loaderresults);
- ⓪$BEGIN
- ⓪&outerErrHandler (name, clientname, nowImport, errtype, errmsg)
- ⓪$END errHandler;
- ⓪
- ⓪"PROCEDURE LinkMod (msname: ARRAY OF Char; (* Name des Moduls *)
- ⓪4reqkey: LONGCARD; (* gewuenschter Key *)
- ⓪6exec: ExecCondition; (* wann ausfuehren? *)
- ⓪4client: ModRef) (* Index des Klienten *)
- ⓪:: ModRef; (* vergebener Index *)
- ⓪"
- ⓪"(* Laedt das Modul "msname" und liefert dessen Index in der "ModLst"
- ⓪#* als Ergebnis.
- ⓪#* Der Modulkey "reqkey" wird erwartet und ueberprueft;
- ⓪#* Falls ein Fehler beim Relozieren oder Laden auftritt,
- ⓪#* wird der benoetigte Speicher freigegeben und als Ergebnis
- ⓪#* "NIL" geliefert
- ⓪#*)
- ⓪$
- ⓪$VAR newname: FileStr;
- ⓪"
- ⓪$PROCEDURE MakeImpList (ref0:ModRef); (* Importliste erstellen *)
- ⓪&
- ⓪&PROCEDURE getImport (VAR p:ADDRESS; VAR name: ARRAY OF CHAR): BOOLEAN;
- ⓪((*$L-*)
- ⓪(BEGIN
- ⓪*ASSEMBLER
- ⓪2MOVE -(A3),D1
- ⓪2MOVE.L -(A3),A0
- ⓪2MOVE.L -(A3),A2
- ⓪2MOVE.L (A2),A1
- ⓪2TST.L (A1)+ ; KEY
- ⓪2BEQ F
- ⓪2; NAMEN HOLEN
- ⓪0L MOVE.B (A1)+,D0
- ⓪2CMPI.B #$FE,D0
- ⓪2BCC E
- ⓪2MOVE.B D0,(A0)+
- ⓪2DBRA D1,L
- ⓪2BRA T
- ⓪0E CLR.B (A0)+
- ⓪2BRA T
- ⓪0M MOVE.B (A1)+,D0
- ⓪0T ADDQ.B #1,D0
- ⓪2BNE M
- ⓪2; ENDE DES NAMENS ERREICHT; LISTENENDE SUCHEN
- ⓪0q TST (A1)+
- ⓪2BEQ O
- ⓪2ADDQ.L #4,A1
- ⓪2BRA q
- ⓪0O MOVE.L A1,(A2)
- ⓪2MOVE #1,(A3)+
- ⓪2RTS
- ⓪0F CLR (A3)+
- ⓪*END
- ⓪(END getImport;
- ⓪((*$L+*)
- ⓪&
- ⓪&VAR implist: ADDRESS;
- ⓪*name: ModStr;
- ⓪*n: CARDINAL;
- ⓪*s: SearchDesc;
- ⓪*
- ⓪&BEGIN (* MakeImpList *)
- ⓪(ASSEMBLER
- ⓪*MOVE.L ref0(A6),A0
- ⓪*MOVE.L modref.header(A0),A1
- ⓪*MOVE.L $E(A1),D0
- ⓪*ADD.L A1,D0
- ⓪*MOVE.L D0,modref.imports(A0)
- ⓪*MOVE.L D0,implist(A6)
- ⓪(END;
- ⓪(n:=0;
- ⓪(WHILE getImport (implist,name) DO
- ⓪*s.mode:= modName;
- ⓪*s.mname:= ADR (name);
- ⓪*GetModRef (s,ref0^.imports^[n]);
- ⓪*INC (n)
- ⓪(END;
- ⓪(ref0^.imports^[n]:= NIL
- ⓪&END MakeImpList;
- ⓪
- ⓪$PROCEDURE ReadMod (REF fname: ARRAY OF CHAR;
- ⓪7VAR mname: ARRAY OF CHAR): ModRef;
- ⓪$(*-----------------------------------------------*)
- ⓪$(* Laedt ein Modul in den Speicher, ueberprueft das Format
- ⓪%* und traegt in die Modul-Liste ein. Reloziert nicht!
- ⓪%* Wenn ein Fehler auftritt, wird der benutzte Speicher
- ⓪%* freigegeben und als Modul-Index NIL geliefert.
- ⓪%* 'fname': Dateiname; 'mname': Modulname, wird ggf. korrgiert.
- ⓪%*)
- ⓪&
- ⓪$
- ⓪$TYPE BSET = SET OF [0..7];
- ⓪$
- ⓪$VAR modad: ADDRESS;
- ⓪'maxlen: LongCard;
- ⓪&loadlen,
- ⓪)cend,
- ⓪&headlen,
- ⓪'modlen: LongCard;
- ⓪'cstart: ADDRESS;
- ⓪(cname: POINTER TO ModStr;
- ⓪'cname0: ModStr;
- ⓪'cname1: ModStr;
- ⓪'dummyl,
- ⓪)flen: LongCard;
- ⓪%foundkey: LONGCARD;
- ⓪(found: boolean;
- ⓪(modId: BYTE;
- ⓪'modId3: BSET;
- ⓪%realCode: CARDINAL;
- ⓪'handle: Cardinal;
- ⓪#searchMode: ListPos;
- ⓪*ior: INTEGER;
- ⓪(modst: ModRef;
- ⓪&reenter: BOOLEAN;
- ⓪
- ⓪$BEGIN (* ReadMod *)
- ⓪&(*$ ? Trace: WriteLn; WriteString ('ReadMod: '); WriteString (fname); *)
- ⓪&searchMode:= fromStart;
- ⓪&IF nowimport THEN
- ⓪(Assign (mname, cname1, ok);
- ⓪(Upper (cname1);
- ⓪&ELSE
- ⓪((* Pfad entfernen für evtl. Fehlermeldung *)
- ⓪(SplitPath (mname, cname1(*dummy*), mname);
- ⓪&END;
- ⓪&REPEAT
- ⓪(SearchFile (fname,Paths,searchMode,found,newname);
- ⓪(IF ~found THEN
- ⓪*(*$ ? Trace: WriteLn; WriteString ('exit: not found'); *)
- ⓪*loadres:= notfound;
- ⓪*RETURN NIL
- ⓪(END;
- ⓪(searchMode:= fromNext;
- ⓪(
- ⓪(MakeFullPath (newname, ior);
- ⓪(IF ~Fopen (newname,0,handle,ior) THEN
- ⓪*IF (ior = -33) OR (ior = -34) OR (ior = -46) THEN
- ⓪,(*$ ? Trace: WriteLn; WriteString ('exit: not found 2'); *)
- ⓪,loadres:= notfound;
- ⓪*ELSE
- ⓪,(*$ ? Trace: WriteLn; WriteString ('exit: bad file'); *)
- ⓪,loadres:= badFile;
- ⓪*END;
- ⓪*RETURN NIL
- ⓪(END;
- ⓪(
- ⓪(ldHead (handle, modLen, modId, loadres);
- ⓪(IF loadres # noError THEN
- ⓪*Fclose (handle);
- ⓪*RETURN NIL
- ⓪(END;
- ⓪(Fseek (handle,0,2,flen); (* Get length of file *)
- ⓪(Fseek (handle,8,0,dummyl); (* Seek hinter "MM2Code" *)
- ⓪(DEC (flen, 8); (* weil erst ab 8. byte geladen wird *)
- ⓪
- ⓪(modId3:= BSET (modId);
- ⓪(ASSEMBLER
- ⓪*MOVE.B modId(A6),D0
- ⓪*LSR.B #5,D0
- ⓪*ANDI.W #3,D0
- ⓪*MOVE.W D0,realCode(A6)
- ⓪(END;
- ⓪
- ⓪(IF flen > modlen THEN (* !!! *)
- ⓪*loadlen := flen
- ⓪(ELSE
- ⓪*loadlen := modlen
- ⓪(END;
- ⓪
- ⓪(loadLen:= loadLen + TSIZE (ModEntry);
- ⓪
- ⓪(SysAlloc (modst, loadlen);
- ⓪(IF modst = NIL THEN
- ⓪*(* ! Eigentlich sollte hier der Fehler noch nicht auftreten, weil
- ⓪+* noch nicht sicher ist, ob dies überhaupt das richtige File ist.*)
- ⓪*(*$ ? Trace:
- ⓪,WriteLn; WriteString ('exit: no memory');
- ⓪**)
- ⓪*Fclose (handle);
- ⓪*loadres:= outofmemory;
- ⓪*RETURN NIL
- ⓪(END;
- ⓪(
- ⓪(modad:= ADDRESS (modst) + TSIZE (ModEntry);
- ⓪(
- ⓪(IF Fread (handle,modad,flen) <= 0L THEN
- ⓪*(*$ ? Trace:
- ⓪,WriteLn; WriteString ('exit: bad file 3');
- ⓪**)
- ⓪*Fclose (handle);
- ⓪*loadres := badFile;
- ⓪*DeAllocate (modst,0L);
- ⓪*RETURN NIL
- ⓪(END;
- ⓪(
- ⓪(Fclose (handle);
- ⓪(
- ⓪(ASSEMBLER
- ⓪*MOVE.L modad(A6),A0
- ⓪*MOVE.L 2(A0),foundkey(A6)
- ⓪*MOVE.L 42(A0),D0
- ⓪*MOVE.L D0,headlen(A6)
- ⓪*ADD.L A0,D0
- ⓪*MOVE.L D0,cstart(A6)
- ⓪*MOVE.L 22(A0),cend(A6)
- ⓪*MOVE.L 46(A0),D0 ; Options laden
- ⓪*BTST #25,D0 ; $Y+? dann ist Modul-Reentry möglich
- ⓪*SNE D0
- ⓪*ANDI #1,D0
- ⓪*MOVE D0,reenter(A6)
- ⓪*MOVE.L 30(A0),D0
- ⓪*ADD.L A0,D0
- ⓪*MOVE.L D0,cname(A6)
- ⓪(END;
- ⓪(cname0:=cname^;
- ⓪(Upper (cname0);
- ⓪&UNTIL ~nowimport OR StrEqual (cname0,cname1);
- ⓪&(*$ ? Trace:
- ⓪(WriteLn; WriteString ('read ok');
- ⓪&*)
- ⓪
- ⓪&IF realCode # 0 THEN
- ⓪((*
- ⓪)* Falls das Modul Reals benutzt, muß geprüft werden, ob
- ⓪)* die vorhandenen Libs das richtige Format und die richtigen
- ⓪)* Runtime-Calls unterstützt. Da wir auf jeden Fall Runtime
- ⓪)* eingelinkt haben, können wir pauschal davon ausgehen, da0
- ⓪)* zumindest einer der 3 mögl. Real-Modi gesetzt ist (theoretisch
- ⓪)* gäbe es ja noch den Fall, daß keine der gelinkten Libs Reals
- ⓪)* benutzt und daher das Format noch undefiniert wäre).
- ⓪)*)
- ⓪(IF RealMode # realCode THEN
- ⓪*IF (realCode > 1) & (RealMode > 1) THEN
- ⓪,loadres:= wrongFPUType; (* beides IEEE, aber falsche FPU *)
- ⓪*ELSE
- ⓪,loadres:= wrongRealForm; (* IEEE <-> MM2Reals *)
- ⓪*END;
- ⓪*Fclose (handle);
- ⓪*DeAllocate (modst,0L);
- ⓪*RETURN NIL
- ⓪(END;
- ⓪&END;
- ⓪&
- ⓪&Assign (cname^, mname, ok);
- ⓪&
- ⓪&IF (reqkey#anykey) & (reqkey#foundkey) THEN
- ⓪((*$ ? Trace:
- ⓪*WriteLn; WriteString ('exit: bad version');
- ⓪(*)
- ⓪(loadres := badversion;
- ⓪(DeAllocate (modst,0L);
- ⓪(RETURN NIL
- ⓪&END;
- ⓪&
- ⓪&(* Modul in ModLst eintragen *)
- ⓪&
- ⓪&AppendEntry(ModLst,modst,error);
- ⓪&IF error THEN
- ⓪((*$ ? Trace:
- ⓪*WriteLn; WriteString ('exit: no memory 2');
- ⓪(*)
- ⓪(DeAllocate (modst,0L);
- ⓪(loadres:= outofmemory;
- ⓪(RETURN NIL
- ⓪&END;
- ⓪&WITH modst^ DO
- ⓪(codeName:= ADDRESS (cname);
- ⓪(Assign (cname0,codeNameUp,ok);
- ⓪((*SplitPath (newname, filePath, fn); SplitName (fn, fileName, sfx);*)
- ⓪(fileName:= FilePrefix (newname);
- ⓪(header:= modad;
- ⓪(codeStart:= cstart;
- ⓪(codeLen:= cend-headlen;
- ⓪(varRef:= cend+modad;
- ⓪(varLen:= modlen-cend;
- ⓪(state:= ModStates {};
- ⓪(IF 4 IN modId3 THEN INCL (state, procSym) END;
- ⓪(IF reenter THEN INCL (state, reentrant) END;
- ⓪(imports:= NIL;
- ⓪(prevBSS:= NIL;
- ⓪(IF FullStorBaseAccess () THEN
- ⓪*owner:= NIL
- ⓪(ELSE
- ⓪*owner:= ProcessID^
- ⓪(END
- ⓪&END;
- ⓪&Assign (cname^,clientname,ok);
- ⓪&loadres:= noError;
- ⓪&RETURN modst
- ⓪$END ReadMod;
- ⓪$
- ⓪$
- ⓪$PROCEDURE Relocate ( header: Address;
- ⓪8myIndex: ModRef;
- ⓪;exec: ExecCondition): BOOLEAN;
- ⓪$
- ⓪$VAR Result: Boolean;
- ⓪$
- ⓪$BEGIN
- ⓪&ASSEMBLER
- ⓪,MOVEM.L D3/A4, -(SP) ; !MS D3/A4 retten
- ⓪,CLR.W Result(A6) ;kann nur noch besser werden
- ⓪,MOVE.L header(A6),A4 ;A4 zeigt auf zu relozierendes Modul
- ⓪,MOVE.L 22(A4),A0
- ⓪,ADDA.L A4,A0
- ⓪&!RE3 MOVE.L (A0)+,D0 ;Var/Proc-Liste abarbeiten
- ⓪,BEQ RE1
- ⓪,MOVE.L (A0)+,D1
- ⓪,ADD.L A4,D1
- ⓪&!RE2 MOVE.L 0(A4,D0.L),D2
- ⓪,MOVE.L D1,0(A4,D0.L)
- ⓪,MOVE.L D2,D0
- ⓪,BNE RE2
- ⓪,BRA RE3
- ⓪,
- ⓪&!RE1 MOVE.L 14(A4),A1 ;A1 zeigt auf Import-Liste
- ⓪,ADDA.L A4,A1
- ⓪&!RE5 MOVE.L (A1)+,D0 ;Key des importierten Moduls
- ⓪,BEQ.L RE4 ;keine IMPORTs mehr
- ⓪,
- ⓪,; wir bereiten den Filenamen vor. Zuerstmal auf den A3 Stack
- ⓪,CLR.W D1
- ⓪&!RE13 MOVE.B (A1)+,D2
- ⓪,CMPI.B #$FE,D2 ;statt BMI, damit auf öäü möglich ist.
- ⓪,BCC RE12
- ⓪,MOVE.B D2,(A3)+
- ⓪,ADDQ.W #1,D1
- ⓪,BRA RE13
- ⓪&!RE12 ADDQ.B #1,D2 ;Sync A1
- ⓪,BEQ RE14
- ⓪,ADDQ.L #1,A1
- ⓪&!RE14 CLR.B (A3)+
- ⓪,MOVE.L A3,D2
- ⓪,BTST #0,D2
- ⓪,BEQ nosync
- ⓪,ADDQ #1,D1
- ⓪,ADDQ.L #1,A3
- ⓪%nosync ; nun den Kram aufn A7 Stack
- ⓪,MOVE D1,D2
- ⓪,ADDQ #1,D2
- ⓪,LSR #1,D2
- ⓪,SUBQ #1,D2
- ⓪$trfname MOVE -(A3),-(A7)
- ⓪,DBRA D2,trfname
- ⓪,MOVE.L A7,(A3)+ ;und die Adresse des Strings aufn A3
- ⓪,MOVE.W D1,(A3)+ ;samt dem High-Wert
- ⓪,
- ⓪,MOVE.L D0,(A3)+ ;Key
- ⓪,MOVE.W exec(A6),(A3)+
- ⓪,MOVE.L myIndex(A6),(A3)+ ;myIndex ist klienten-Index
- ⓪,MOVEM.L D1/A4/A1,-(A7)
- ⓪,MOVE.L (A6),A0 ;Dynamic Link fuer ProcCall
- ⓪,MOVE.L (A0),D2
- ⓪,BSR LinkMod
- ⓪,(*$ ? Trace:
- ⓪.END;
- ⓪0Read (inch);
- ⓪.ASSEMBLER
- ⓪,*)
- ⓪,MOVEM.L (A7)+,D1/A4/A1
- ⓪,ADDQ.W #1,D1
- ⓪,ADDA.W D1,A7 ;mname vom Stack runter
- ⓪,MOVE.L -(A3),D0 ;Index des importierten Moduls
- ⓪,BEQ BAD ;da gab's wohl irgendwo einen Fehler
- ⓪,MOVE.L D0,A2
- ⓪,MOVE.L ModEntry.header(A2),A2
- ⓪&!RE6 MOVE.W (A1)+,D0 ;imp. ItemNr
- ⓪,BEQ RE5
- ⓪,MOVE.L 18(A2),D3 ;Offset zur Exp.liste
- ⓪,BEQ BAD ;keine da
- ⓪,ADD.L A2,D3
- ⓪,MOVE.L (A1)+,D1 ;importiertes Item
- ⓪,BEQ RE6
- ⓪,MOVE.L D3,A0
- ⓪&!RE9 MOVE.W (A0)+,D2 ;Item in Exportliste suchen
- ⓪,BEQ BAD
- ⓪,CMP.W D2,D0
- ⓪,BEQ RE10
- ⓪,ADDQ.L #4,A0
- ⓪,BRA RE9
- ⓪&!RE10 MOVE.L (A0)+,D2 ;abs. ItemAdr ausrechnen
- ⓪,ADD.L A2,D2
- ⓪&!RE11 MOVE.L 0(A4,D1.L),D0 ;ItemAdr im Modul nachtragen
- ⓪,MOVE.L D2,0(A4,D1.L)
- ⓪,MOVE.L D0,D1
- ⓪,BNE RE11
- ⓪,BRA RE6
- ⓪&!RE4 MOVE.W #1,Result(A6) ;alles klar
- ⓪&!BAD MOVEM.L (SP)+, D3/A4 ; !MS Register restaurieren
- ⓪&END;
- ⓪&FlushCPUCache ();
- ⓪&RETURN Result
- ⓪$END Relocate;
- ⓪"
- ⓪"PROCEDURE PrepareExec (ref0:ModRef; mustBeDeInit:BOOLEAN): BOOLEAN;
- ⓪$(*
- ⓪%* Bereitet das geladene Modul und ggf. seine zu initialisierenden
- ⓪%* Importe auf ein Init vor.
- ⓪%* mustBeDeInit: "Modul muß deinit. sein, um gestartet werden zu dürfen"
- ⓪%*)
- ⓪$VAR j: POINTER TO ModRef;
- ⓪$BEGIN
- ⓪&WITH ref0^ DO
- ⓪(INCL (state, msr1);
- ⓪(IF ~(initialized IN state) (* noch nicht init.? *)
- ⓪(OR ~mustBeDeInit & (installed IN state) (* oder installed? *) THEN
- ⓪*(*
- ⓪+* Da das Modul noch nicht init. ist, wird es dafür vorgemerkt.
- ⓪+* Zuvor müssen aber noch seine Importe geprüft werden:
- ⓪+*)
- ⓪*IF imports # NIL THEN
- ⓪,j:= ADDRESS (imports);
- ⓪,LOOP
- ⓪.IF j^=NIL THEN EXIT END;
- ⓪.IF NOT (msr1 IN j^^.state) THEN
- ⓪0IF NOT PrepareExec (j^, TRUE) THEN RETURN FALSE END
- ⓪.END;
- ⓪.INC (j, 4)
- ⓪,END
- ⓪*END;
- ⓪*(*$ ? Trace OR Trace3: WriteLn; WriteString (codename^); WriteString (' will be executed'); *)
- ⓪*IF NOT (msr2 IN ref0^.state) THEN
- ⓪,INCL (ref0^.state, msr2);
- ⓪,IF NOT markForInit (ref0) THEN
- ⓪.loadRes:= tooManyMods;
- ⓪.errHandler (mainName,loadRes);
- ⓪.RETURN FALSE
- ⓪,END;
- ⓪*END
- ⓪(END;
- ⓪&END;
- ⓪&RETURN TRUE
- ⓪$END PrepareExec;
- ⓪"
- ⓪"VAR fname : FileStr;
- ⓪&execRel: ExecCondition;
- ⓪&ref0: ModRef;
- ⓪&basepage: PtrBP;
- ⓪&ior: INTEGER;
- ⓪&ploadres: LONGINT;
- ⓪&found: BOOLEAN;
- ⓪&fn: NameStr;
- ⓪&sfx: ARRAY [0..2] OF CHAR;
- ⓪
- ⓪"PROCEDURE prgInstall (): BOOLEAN;
- ⓪$VAR err: BOOLEAN;
- ⓪$BEGIN
- ⓪&SysAlloc (ref0,TSIZE (ModEntry));
- ⓪&IF ref0 # NIL THEN
- ⓪(Block.Clear (ref0,SIZE(ref0^));
- ⓪(AppendEntry(ModLst,ref0,err);
- ⓪&ELSE
- ⓪(err:= TRUE;
- ⓪&END;
- ⓪&RETURN ~err
- ⓪$END prgInstall;
- ⓪
- ⓪"BEGIN (* of LinkMod *)
- ⓪$FlushCPUCache ();
- ⓪$(*$ ? Trace: WriteLn; WriteString ('LinkMod: '); WriteString (msname); *)
- ⓪$IF client # NIL THEN
- ⓪&clientname := client^.codename^
- ⓪$END;
- ⓪$
- ⓪$IF ModLoaded (msname,nowimport,fname,ref0) THEN
- ⓪&(*$ ? Trace: WriteString (', already in RAM, '); *)
- ⓪&WITH ref0^ DO
- ⓪(IF program IN state THEN
- ⓪*(*$ ? Trace: WriteString (' is program'); *)
- ⓪*RETURN ref0
- ⓪(ELSIF (reqkey#anykey) & (reqkey#header^.key) THEN
- ⓪*(*$ ? Trace: WriteString ('bad version'); *)
- ⓪*loadres := badversion;
- ⓪*errHandler (codeName^,badversion);
- ⓪*RETURN NIL
- ⓪(ELSE (* tatsaechlich: wir haben das richtige Modul im RAM *)
- ⓪*(*$ ? Trace: WriteString ('version ok.'); *)
- ⓪*IF exec = execAlways (* zu startendes Hauptmodul *) THEN
- ⓪,IF (installed IN state) OR ~(initialized IN state) THEN
- ⓪.IF NOT (msr1 IN state) THEN
- ⓪0IF NOT PrepareExec (ref0, FALSE) THEN
- ⓪2RETURN NIL
- ⓪0END
- ⓪.END
- ⓪,ELSE
- ⓪.(*$ ? Trace: WriteLn; WriteString ('error: already initialized !'); *)
- ⓪.loadres := denied;
- ⓪.errHandler (codeName^,denied);
- ⓪.RETURN NIL
- ⓪,END
- ⓪*ELSIF exec = execNew (* importiertes, bereits nachgeladenes Modul *) THEN
- ⓪,IF NOT (msr1 IN state) THEN
- ⓪.IF NOT PrepareExec (ref0, TRUE) THEN
- ⓪0RETURN NIL
- ⓪.END
- ⓪,END
- ⓪*END;
- ⓪*RETURN ref0
- ⓪(END
- ⓪&END
- ⓪$END;
- ⓪$
- ⓪$(*
- ⓪%* Hier kommen wir an, wenn Modul nicht im RAM liegt
- ⓪%*)
- ⓪$
- ⓪$IF Empty (FilePrefix (fname)) THEN
- ⓪&(* ungültiger Modul-/Dateiname *)
- ⓪&loadres:= notfound;
- ⓪&SetMsg (8, errmsg);
- ⓪&RETURN NIL
- ⓪$END;
- ⓪$
- ⓪$ref0 := ReadMod (fname, msname);
- ⓪$(*$ ? Trace: Read (inch); *)
- ⓪$IF ref0 # NIL THEN (* Load war erfolgreich *)
- ⓪&(*$ ? Trace: WriteLn; WriteString (msname); WriteString (': load ok'); *)
- ⓪&nowimport:= True;
- ⓪&IF exec = execNever THEN execRel:= execNever ELSE execRel:= execNew END;
- ⓪&(*
- ⓪'* Wir müssen hier schon das Modul markieren, weil sonst bei
- ⓪'* zirkulären Importen dies Modul zu früh init. würde (z.B. beim
- ⓪'* Compiler)
- ⓪'*)
- ⓪&INCL (ref0^.state, msr2);
- ⓪&IF Relocate (ref0^.header, ref0, execRel) THEN
- ⓪((*$ ? Trace: WriteLn; WriteString (msname); WriteString (': relocate ok, '); *)
- ⓪(MakeImpList (ref0);
- ⓪(IF exec # execNever THEN
- ⓪*(*$ ? Trace: WriteString ('will be executed.'); *)
- ⓪*IF NOT markForInit (ref0) THEN
- ⓪,loadRes:= tooManyMods;
- ⓪,errHandler (mainName,loadRes);
- ⓪,Release (ref0,FALSE,FALSE);
- ⓪,RETURN NIL
- ⓪*END
- ⓪(END;
- ⓪(WITH ref0^ DO
- ⓪*Loading (codeName^,newName,codeStart,codeLen,varRef,varLen);
- ⓪(END;
- ⓪(RETURN ref0
- ⓪&ELSE (* Relocate ist schiefgegangen *)
- ⓪((*$ ? Trace: WriteLn; WriteString (msname); WriteString (': relocate error'); *)
- ⓪(IF loadRes = noError THEN
- ⓪*loadRes:= notLinkable;
- ⓪*errHandler (ref0^.codeName^,loadRes)
- ⓪(END;
- ⓪(MakeImpList (ref0); (* damit alle imp. Module wieder freigegb. werden*)
- ⓪(Release (ref0,FALSE,FALSE);
- ⓪(RETURN NIL
- ⓪&END;
- ⓪$ELSE (* Load ist schiefgegangen *)
- ⓪&IF loadres # badLayout THEN
- ⓪((*$ ? Trace: WriteLn; WriteString (msname); WriteString (': load error'); *)
- ⓪(errHandler (msname,loadres);
- ⓪(RETURN NIL
- ⓪&ELSE
- ⓪((* ...dann müßte es ein TOS-Prg sein *)
- ⓪((*$ ? Trace: WriteString (', loading program.'); *)
- ⓪(ploadres:= prgLoad (newname);
- ⓪(IF ploadres < 0L THEN
- ⓪*checkExecRes (SHORT (ploadres), loadRes, msname, errmsg);
- ⓪*RETURN NIL
- ⓪(ELSE
- ⓪*errMsg[0]:=0C;
- ⓪*basepage:= PtrBP (ploadres);
- ⓪*IF prgPrepare (basepage, DefaultStackSize) & prgInstall() THEN
- ⓪,WITH ref0^ DO
- ⓪.(*SplitPath (newname, filePath, fn); SplitName (fn, fileName, sfx);*)
- ⓪.fileName:= FilePrefix (newname);
- ⓪.Assign (fileName, codeNameUp, ok); (* geht, weil fileName ohne Sfx*)
- ⓪.codeName:= ADR (codeNameUp);
- ⓪.codeStart:= basepage;
- ⓪.header:= codeStart;
- ⓪.codeLen:= basepage^.p_tlen;
- ⓪.state:= ModStates {mainMod,program};
- ⓪.owner:= ProcessID^;
- ⓪.Loading (codeNameUp,newname,codeStart,codeLen,NIL,0L)
- ⓪,END;
- ⓪,loadRes:= NoError;
- ⓪,RETURN ref0
- ⓪*ELSE
- ⓪,DEALLOCATE (ref0,0L);
- ⓪,prgUnload (basepage);
- ⓪,loadRes:= outOfMemory;
- ⓪,errHandler (newname,loadRes);
- ⓪,RETURN NIL
- ⓪*END
- ⓪(END
- ⓪&END
- ⓪$END (* IF tosPrg ... ELSE *)
- ⓪"END LinkMod;
- ⓪
- ⓪"VAR DTA: ARRAY [1..22] OF WORD;
- ⓪&basepage: PtrBP;
- ⓪&stacksize: LONGCARD;
- ⓪
- ⓪"PROCEDURE exitMods;
- ⓪$(* alten VarSpace wiederherstellen *)
- ⓪$VAR execThis: CARDINAL; ad: PtrBSS;
- ⓪$BEGIN
- ⓪&execThis:= 0;
- ⓪&WHILE execThis < ExecPtr DO
- ⓪(WITH ExecList^[execThis]^ DO
- ⓪*IF prevBSS # NIL THEN
- ⓪,(*$ ? Trace: WriteLn; WriteString (codename^); WriteString (' restores BSS'); *)
- ⓪,ad:= prevBSS;
- ⓪,prevBSS:= prevBSS^.prev;
- ⓪,Block.Copy (ADDRESS(ad) + 4L, varLen, varRef);
- ⓪,DEALLOCATE (ad, 0);
- ⓪*END;
- ⓪(END;
- ⓪(INC (execThis);
- ⓪&END;
- ⓪$END exitMods;
- ⓪
- ⓪"PROCEDURE initPrgSpace (prgFlags: LONGWORD) : Boolean;
- ⓪$BEGIN
- ⓪&(*$ ? Trace: WriteLn; WriteString ('CreatePB'); *)
- ⓪&IF ~CreateBasePage (basepage, stacksize, CADR (mainName), prgFlags) THEN
- ⓪(basepage:= NIL;
- ⓪(RETURN FALSE
- ⓪&END;
- ⓪&Block.Copy (CADR(arg),128,ADR(basepage^.cmdline));
- ⓪&basepage^.p_dta:= ADR(DTA);
- ⓪&(*$ ? Trace: WriteString (' ok.'); *)
- ⓪&RETURN true
- ⓪$END initPrgSpace;
- ⓪
- ⓪"PROCEDURE removePrgSpace;
- ⓪$BEGIN
- ⓪&IF basepage # NIL THEN
- ⓪((* nicht DEALLOCATE verwenden, da sonst u.U. Fehler passieren?! *)
- ⓪(Mfree (basepage^.p_env);
- ⓪(Mfree (basepage)
- ⓪&END;
- ⓪$END removePrgSpace;
- ⓪"
- ⓪"PROCEDURE outOfMem;
- ⓪$BEGIN
- ⓪&loadres := outofmemory;
- ⓪&errHandler ('',loadres);
- ⓪$END outOfMem;
- ⓪"
- ⓪"PROCEDURE reset (st: ModStates); (* Flags 'msr1' & 'msr2' löschen *)
- ⓪$VAR i: ModRef;
- ⓪$BEGIN
- ⓪&ResetList (ModLst);
- ⓪&LOOP
- ⓪(i:= NextEntry (ModLst);
- ⓪(IF i=NIL THEN EXIT END;
- ⓪(i^.state:= i^.state - st
- ⓪&END
- ⓪$END reset;
- ⓪
- ⓪"PROCEDURE initNonReentrants (): BOOLEAN;
- ⓪$(*
- ⓪%* Es reicht nicht aus, in PrepareExec() alle Importe zum Init. zu prüfen.
- ⓪%* Denn es kann vorkommen, daß z.B. über Treiber weitere Module abhängig
- ⓪%* sind. Zwar sind diese schon initialisiert, wenn sie jedoch nicht
- ⓪%* reentrant sind, müssen sie erneut init. werden.
- ⓪%* Dies sollte darüber funktionieren, daß die Driver-Liste ausgewertet
- ⓪%* wird. Solange dies noch nicht impl. ist, muß anders vorgegangen
- ⓪%* werden:
- ⓪%* Es werden zur Sicherheit einfach alle Module init., die schon
- ⓪%* initialisiert & non-reentrant $ ~mainMod sind. Damit werden u.U.
- ⓪%* zwar mehr Module als nötig init, das sollte aber nicht schaden.
- ⓪%*)
- ⓪$
- ⓪$PROCEDURE check (i: ModRef): BOOLEAN;
- ⓪&VAR j: POINTER TO ModRef;
- ⓪&BEGIN
- ⓪(WITH i^ DO
- ⓪*INCL (state, msr1);
- ⓪*IF imports # NIL THEN
- ⓪,j:= ADDRESS (imports);
- ⓪,LOOP
- ⓪.IF j^ = NIL THEN EXIT END;
- ⓪.IF NOT (msr1 IN j^^.state) THEN
- ⓪0IF NOT check (j^) THEN RETURN FALSE END
- ⓪.END;
- ⓪.INC (j, 4)
- ⓪,END
- ⓪*END;
- ⓪*IF NOT (reentrant IN state) & (initialized IN state)
- ⓪*& NOT (mainMod IN state)
- ⓪*& NOT (installed IN state) THEN
- ⓪,IF NOT (msr2 IN i^.state) THEN
- ⓪.INCL (i^.state, msr2);
- ⓪.(*$ ? Trace OR Trace3: WriteLn; WriteString (codename^); WriteString (' will be executed'); *)
- ⓪.IF NOT markForInit (i) THEN RETURN FALSE END
- ⓪,END
- ⓪*END
- ⓪(END;
- ⓪(RETURN TRUE
- ⓪&END check;
- ⓪$
- ⓪$VAR i: ModRef;
- ⓪$
- ⓪$BEGIN
- ⓪&ResetList (ModLst);
- ⓪&LOOP
- ⓪(i:= NextEntry (ModLst);
- ⓪(IF i=NIL THEN EXIT END;
- ⓪(IF NOT (msr1 IN i^.state) THEN
- ⓪*IF NOT check (i) THEN
- ⓪,RETURN FALSE
- ⓪*END
- ⓪(END
- ⓪&END;
- ⓪&RETURN TRUE
- ⓪$END initNonReentrants;
- ⓪
- ⓪"VAR usedIndex: ModRef; lastExecPtr, termState: CARDINAL;
- ⓪&ehdl: EnvlpCarrier;
- ⓪&initOK: BOOLEAN; lastExecList: ADDRESS;
- ⓪
- ⓪ BEGIN (* ExecMod *)
- ⓪"(*$?Trace0:Write('1');Read(inch);IF Inconsistent() THEN HALT END;*)
- ⓪"errMsg[0]:=0C;
- ⓪"loadres := noError;
- ⓪"lastExecList:= ExecList;
- ⓪"lastExecPtr:= ExecPtr;
- ⓪"ALLOCATE (ExecList, (MaxModExec+1)*SIZE (ExecList^[0]));
- ⓪"usedIndex:= NIL;
- ⓪"IF ExecList = NIL THEN
- ⓪$outOfMem
- ⓪"ELSE
- ⓪$ExecPtr := 0;
- ⓪$nowimport := False;
- ⓪$clientname:= '';
- ⓪$IF exec # execNever THEN
- ⓪&reset (ModStates{msr1,msr2});
- ⓪&initOK:= initNonReentrants ();
- ⓪&reset (ModStates{msr1})
- ⓪$ELSE
- ⓪&initOK:= TRUE
- ⓪$END;
- ⓪$IF initOK THEN
- ⓪&usedIndex := LinkMod (mainName, anykey, exec, NIL);
- ⓪&IF exec # execNever THEN reset (ModStates{msr1,msr2}) END;
- ⓪&(*$ ? Trace OR Trace3: Read (inch); *)
- ⓪&(*$?Trace0:Write('2');Read(inch);IF Inconsistent() THEN HALT END;*)
- ⓪&IF usedIndex # NIL THEN
- ⓪(INCL (usedIndex^.state, mainMod);
- ⓪(IF program IN usedIndex^.state THEN
- ⓪*(*$?Trace0:Write('3');Read(inch);IF Inconsistent() THEN HALT END;*)
- ⓪*IF exec # ExecNever THEN
- ⓪,IF NOT prgExec (usedIndex^.codeStart, CADR (mainName), arg, env, exitCode) THEN
- ⓪.outOfMem
- ⓪,END;
- ⓪,(*$?Trace0:Write('6');Read(inch);IF Inconsistent() THEN HALT END;*)
- ⓪*END
- ⓪(ELSIF ExecPtr > 0 THEN
- ⓪*stacksize:= usedIndex^.header^.stackSize;
- ⓪*IF stacksize = 0 THEN
- ⓪,stacksize := Defaultstacksize
- ⓪*END;
- ⓪*IF stacksize < 1024L THEN stacksize := 1024 END;
- ⓪*IF odd (stacksize) THEN dec (stacksize) END;
- ⓪*(*$ ? Trace: WriteLn; WriteString ('initPrgSpace'); *)
- ⓪*IF ~initPrgSpace (usedIndex^.header^.prgFlags) THEN
- ⓪,(*$ ? Trace: WriteString (' failed'); *)
- ⓪,outOfMem;
- ⓪,termState:= 2
- ⓪*ELSE
- ⓪,enterMods (TRUE, FALSE, exitCode);
- ⓪,IF enterFailed THEN
- ⓪.exitCode:= 0; outOfMem; termState:= 2
- ⓪,ELSE
- ⓪.(*$ ? Trace: WriteLn; WriteString ('ExecProcess'); *)
- ⓪.INCL (usedIndex^.state, running);
- ⓪.(*
- ⓪0SetEnvelope (ehdl, enterMods, MemArea {NIL,0});
- ⓪.*)
- ⓪.ExecProcess (basepage, initMods, CADR (mainName),
- ⓪;usedIndex^.header^.prgFlags, termState, exitCode);
- ⓪.(*
- ⓪0IF enterFailed THEN exitCode:= 0; outOfMem; termState:= 2 END;
- ⓪0RemoveEnvelope (ehdl);
- ⓪.*)
- ⓪.EXCL (usedIndex^.state, running);
- ⓪,END;
- ⓪*END;
- ⓪*(*$ ? Trace: WriteLn; WriteString ('removePrgSpace'); *)
- ⓪*removePrgSpace;
- ⓪*(*$?Trace0:Write('7');Read(inch);IF Inconsistent() THEN HALT END;*)
- ⓪*exitMods;
- ⓪*(*$?Trace0:Write('8');Read(inch);IF Inconsistent() THEN HALT END;*)
- ⓪*IF termState#2 THEN
- ⓪,IF termState<2 THEN
- ⓪.loadres:= initFault
- ⓪,ELSE
- ⓪.loadres:= exitFault
- ⓪,END;
- ⓪,errHandler ('',loadres)
- ⓪*END
- ⓪(END
- ⓪&END;
- ⓪$ELSE
- ⓪&loadRes:= tooManyMods;
- ⓪&errHandler (mainName,loadRes)
- ⓪$END;
- ⓪$DEALLOCATE (ExecList, 0);
- ⓪"END;
- ⓪"ExecPtr:= lastExecPtr;
- ⓪"ExecList:= lastExecList;
- ⓪"(*$ ? Trace: WriteLn; WriteString ('End ExecMod'); *)
- ⓪"(*$?Trace0:Write('9');Read(inch);IF Inconsistent() THEN HALT END;*)
- ⓪"RETURN usedIndex
- ⓪ END ExecMod;
- ⓪
- ⓪
- ⓪ PROCEDURE Pexec ( VAR name, arg: ARRAY OF CHAR; env: ADDRESS; VAR execRes: INTEGER ): INTEGER;
- ⓪"(*
- ⓪#* Programm von Disk laden und starten
- ⓪#*)
- ⓪"VAR s:FileStr; i:INTEGER;
- ⓪"BEGIN
- ⓪$Assign (name,s,ok);
- ⓪$ASSEMBLER
- ⓪(MOVE.L env(A6),-(A7)
- ⓪(MOVE.L arg(A6),-(A7)
- ⓪(PEA s(A6)
- ⓪(CLR -(A7)
- ⓪(MOVE #$4B,-(A7)
- ⓪(TRAP #1
- ⓪(ADDA.W #16,A7
- ⓪(MOVE.L execRes(A6),A0
- ⓪(TST.L D0
- ⓪(BPL execOK
- ⓪(CLR i(A6)
- ⓪(MOVE.W D0,(A0)
- ⓪(BRA ende
- ⓪ execOK MOVE D0,i(A6)
- ⓪(CLR.W (A0)
- ⓪ ende
- ⓪&END;
- ⓪$RETURN i
- ⓪"END Pexec;
- ⓪
- ⓪
- ⓪ TYPE modList = RECORD p: CARDINAL;
- ⓪6a: POINTER TO ARRAY [0..5000] OF ModRef END;
- ⓪ VAR exitList, removeList: modList;
- ⓪
- ⓪ PROCEDURE freeLists (olda, oldb: ADDRESS);
- ⓪"BEGIN
- ⓪$DEALLOCATE (exitList.a, 0);
- ⓪$DEALLOCATE (removeList.a, 0);
- ⓪$exitList.a:= olda;
- ⓪$removeList.a:= oldb
- ⓪"END freeLists;
- ⓪
- ⓪ PROCEDURE allocLists (VAR olda, oldb: ADDRESS): BOOLEAN;
- ⓪"BEGIN
- ⓪$olda:= exitList.a;
- ⓪$oldb:= removeList.a;
- ⓪$ALLOCATE (exitList.a, (MaxModExec+1)*SIZE(exitList.a^[0]));
- ⓪$ALLOCATE (removeList.a, (MaxModExec+1)*SIZE(removeList.a^[0]));
- ⓪$IF (exitList.a # NIL) & (removeList.a # NIL) THEN
- ⓪&RETURN TRUE
- ⓪$ELSE
- ⓪&freeLists (olda, oldb);
- ⓪&RETURN FALSE
- ⓪$END
- ⓪"END allocLists;
- ⓪
- ⓪
- ⓪ PROCEDURE CallModule ( REF name : ARRAY OF Char;
- ⓪;Paths : PathList;
- ⓪7REF Arg : ARRAY OF Char;
- ⓪;env : ADDRESS;
- ⓪7VAR ExitCode : Integer;
- ⓪7VAR ErrMsg : ARRAY OF CHAR;
- ⓪7VAR Result : LoaderResults);
- ⓪
- ⓪"VAR myindex: ModRef; (* Index wird gebraucht fuer Release *)
- ⓪&mname: FileStr;
- ⓪&fname: FileStr;
- ⓪&arg0: ArgStr;
- ⓪&myres: LoaderResults;
- ⓪&mymsg: String;
- ⓪&execRes: INTEGER;
- ⓪&isPrg, isLoaded, found: BOOLEAN;
- ⓪&save1, save2: ADDRESS;
- ⓪
- ⓪"PROCEDURE search (REF name: ARRAY OF CHAR);
- ⓪$BEGIN
- ⓪&SearchFile (name,Paths,fromStart,found,fname);
- ⓪&isPrg:= found & ~IsModule (fname);
- ⓪$END search;
- ⓪
- ⓪"BEGIN
- ⓪$ExitCode := 0;
- ⓪$errmsg[0]:= 0C;
- ⓪$IF callptr = MaxModNest-1 THEN
- ⓪&SetMsg (9, errmsg);
- ⓪&Result := tooManyCalls
- ⓪$ELSE
- ⓪&inc (callptr);
- ⓪&Assign (name,mname,ok);
- ⓪&Assign (arg,arg0,ok);
- ⓪&REPEAT
- ⓪(IF arg0[0] # CHR(127) THEN
- ⓪*Insert (CHR(Length(arg0)),0,arg0,ok)
- ⓪(END;
- ⓪(myMsg[0]:=0C;
- ⓪(chainname [callptr] := '';
- ⓪(isLoaded:= ModLoaded (mname, FALSE, fname, myindex);
- ⓪(IF isLoaded & ~(loaded IN myindex^.state) & (LENGTH (FileSuffix(mname))>0) THEN
- ⓪*(* Hier soll offenbar ein Prg. gestartet werden, das mit dem
- ⓪+* selben Namen auch schon als residentes Modul vorkommt.
- ⓪+* Prüfen, ob das File existiert und dann doch das File starten. *)
- ⓪*search (mname);
- ⓪*IF isPrg THEN isLoaded:= FALSE END
- ⓪(ELSIF ~isLoaded THEN
- ⓪*search (fname);
- ⓪(END;
- ⓪(IF ~isLoaded & ~found THEN
- ⓪*myres:= notfound;
- ⓪*mname:= '';
- ⓪*outerErrHandler (FileNames.FileName (fname), '', FALSE, notfound, mymsg)
- ⓪(ELSIF ~isLoaded & isPrg THEN
- ⓪*exitCode:= Pexec (fname,arg0,env,execRes);
- ⓪*mname:= '';
- ⓪*checkExecRes (execRes, myRes, fname, myMsg);
- ⓪(ELSE
- ⓪*IF ~allocLists (save1, save2) THEN
- ⓪,mname:= '';
- ⓪,SetMsg (6, mymsg);
- ⓪,myres := outofmemory;
- ⓪*ELSE
- ⓪,myindex:= execmod (mname,execalways,paths,arg0,env,exitcode,mymsg,myres);
- ⓪,IF myindex # NIL THEN
- ⓪.Release (myindex,FALSE,FALSE)
- ⓪,END;
- ⓪,freeLists (save1, save2);
- ⓪,mname := chainname [callptr];
- ⓪,arg0 := chainarg [callptr]
- ⓪*END
- ⓪(END
- ⓪&UNTIL mname[0] = 0C;
- ⓪&Assign (mymsg,ErrMsg,ok);
- ⓪&Result:= myres;
- ⓪&DEC (callptr);
- ⓪$END
- ⓪"END CallModule;
- ⓪
- ⓪
- ⓪ PROCEDURE LoadModule ( REF mname : ARRAY OF CHAR;
- ⓪;paths : PathList;
- ⓪7VAR mname0 : ARRAY OF CHAR;
- ⓪7VAR errMsg : ARRAY OF CHAR;
- ⓪7VAR result : LoaderResults);
- ⓪"
- ⓪"VAR dummy:INTEGER;
- ⓪(sdum: ArgStr;
- ⓪(idx: CARDINAL;
- ⓪(save1, save2: ADDRESS;
- ⓪(ref0:ModRef;
- ⓪
- ⓪"BEGIN
- ⓪$(* darf hier nicht stehen wg. ggf. Alias zu 'mname': mname0[0]:= 0C; *)
- ⓪$errmsg[0]:= 0C;
- ⓪$IF ~allocLists (save1, save2) THEN
- ⓪&SetMsg (6, errmsg);
- ⓪&mname0[0]:= 0C;
- ⓪&Result := outofmemory;
- ⓪$ELSE
- ⓪&ref0 := execmod (mname, execnever, paths, sdum, 0, dummy, errmsg, result);
- ⓪&freeLists (save1, save2);
- ⓪&IF ref0 # NIL THEN
- ⓪(Assign (ref0^.codename^,mname0,ok);
- ⓪(IF linked IN ref0^.state THEN
- ⓪*result := denied;
- ⓪*SetMsg (7, errmsg);
- ⓪*idx:= PosLen ('@I',errmsg,0);
- ⓪*Delete (errmsg,idx,2,ok);
- ⓪*Insert (ref0^.codeName^,idx,errmsg,ok);
- ⓪(ELSE
- ⓪*INCL (ref0^.state,loaded);
- ⓪(END
- ⓪&ELSE
- ⓪(mname0[0]:= 0C;
- ⓪&END
- ⓪$END
- ⓪"END LoadModule;
- ⓪
- ⓪
- ⓪ PROCEDURE freeModule (ref0: ModRef; VAR result: LoaderResults);
- ⓪
- ⓪"VAR save1, save2: ADDRESS;
- ⓪
- ⓪"BEGIN
- ⓪$result := NoError;
- ⓪$IF program IN ref0^.state THEN
- ⓪&prgUnload (ref0^.codeStart);
- ⓪&FindEntry (ModLst, ref0, ok);
- ⓪&IF ok THEN
- ⓪(RemoveEntry (ModLst,ok)
- ⓪&END;
- ⓪&DEALLOCATE (ref0,0L)
- ⓪$ELSE
- ⓪&IF loaded IN ref0^.state THEN
- ⓪(EXCL (ref0^.state, loaded);
- ⓪(IF ~ allocLists (save1, save2) THEN
- ⓪*Result := outofmemory;
- ⓪(ELSE
- ⓪*Release (ref0, FALSE, FALSE);
- ⓪*freeLists (save1, save2);
- ⓪*IF ref0#NIL THEN
- ⓪,result := notRemoved
- ⓪*END
- ⓪(END
- ⓪&ELSE
- ⓪(result:= denied (* Modul ist nicht geladen *)
- ⓪&END;
- ⓪$END
- ⓪"END freeModule;
- ⓪
- ⓪ PROCEDURE UnLoadModule ( REF mname : ARRAY OF Char;
- ⓪9VAR result: LoaderResults);
- ⓪
- ⓪"VAR ref0: ModRef; dummy: FileStr;
- ⓪
- ⓪"BEGIN
- ⓪$IF ModLoaded (mname,FALSE,dummy,ref0) THEN
- ⓪&freeModule (ref0,result)
- ⓪$ELSE
- ⓪&result := notFound
- ⓪$END
- ⓪"END UnLoadModule;
- ⓪
- ⓪
- ⓪
- ⓪ PROCEDURE FullRelease (VAR client: ModRef; dummy1, dummy2: BOOLEAN);
- ⓪"(* 'client' wird auf NIL gesetzt, wenn Modul wirklich freigegeben wird *)
- ⓪
- ⓪"PROCEDURE DoRemoveInfo ( ad: ADDRESS; len: LONGCARD );
- ⓪$BEGIN
- ⓪&ASSEMBLER
- ⓪(; Suche nach Prozeduren, die im angegebenen Code-Bereich liegen:
- ⓪(MOVE.L ad(A6),D1
- ⓪(MOVE.L D1,D2
- ⓪(ADD.L len(A6),D2
- ⓪(LEA RemovalRoot,A0
- ⓪(MOVE.L A0,A1
- ⓪&l MOVE.L RemovalEntry.prev(A0),A0 ; Liste rückwärts durchgehen
- ⓪(CMPA.L A1,A0 ; Listenende ?
- ⓪(BEQ e
- ⓪(MOVE.L RemovalEntry.call(A0),D0
- ⓪(CMP.L D1,D0 ; call < Code-Beginn ?
- ⓪(BCS l ; ja, weitersuchen
- ⓪(CMP.L D2,D0 ; call > Code-Ende ?
- ⓪(BCC l ; ja, weitersuchen
- ⓪(; Proc gefunden -> auslinken und Remove-Info
- ⓪(MOVEM.L D1/D2/A0/A1,-(A7)
- ⓪(MOVE.L RemovalEntry.next(A0),A1
- ⓪(MOVE.L RemovalEntry.prev(A0),A2
- ⓪(MOVE.L A1,RemovalEntry.next(A2)
- ⓪(MOVE.L A2,RemovalEntry.prev(A1)
- ⓪(MOVE.L D0,(A3)+
- ⓪(LEA RemovalEntry.wsp(A0),A0
- ⓪(MOVE.L A0,(A3)+
- ⓪(JSR CallSub
- ⓪(MOVEM.L (A7)+,D1/D2/A0/A1
- ⓪(BRA l ; falls mehrere Removals im Modul
- ⓪&e
- ⓪&END
- ⓪$END DoRemoveInfo;
- ⓪
- ⓪"PROCEDURE markNonFree;
- ⓪
- ⓪$(*
- ⓪%* Die Module werden folgendermaßen markiert:
- ⓪%* - folgende erhalten 'msr1' in 'state':
- ⓪%* - linked
- ⓪%* - program
- ⓪%* - mainMod & running + Importe
- ⓪%* - installed + Importe
- ⓪%* - folgende erhalten 'loadImp' in 'state':
- ⓪%* - loaded + Importe (ohne die, die schon 'msr1' haben)
- ⓪%*
- ⓪%* Alle, die 'msr1' haben, können nicht deinitialisiert werden.
- ⓪%* Alle, die 'msr1' oder 'loadImp' haben, können nicht freigegeben werden.
- ⓪%*)
- ⓪
- ⓪$PROCEDURE presetFlags;
- ⓪&VAR i: ModRef;
- ⓪&BEGIN
- ⓪(ResetList (ModLst);
- ⓪(LOOP
- ⓪*i:= NextEntry (ModLst);
- ⓪*IF i=NIL THEN EXIT END;
- ⓪*EXCL (i^.state, loadImp);
- ⓪*IF (linked IN i^.state) OR (program IN i^.state) THEN
- ⓪,INCL (i^.state, msr1); (* Markiert fertige Module *)
- ⓪*ELSE
- ⓪,EXCL (i^.state, msr1);
- ⓪*END
- ⓪(END
- ⓪&END presetFlags;
- ⓪
- ⓪$PROCEDURE markImported (i: ModRef; s: ModState);
- ⓪&VAR j: POINTER TO ModRef;
- ⓪&BEGIN
- ⓪(INCL (i^.state, s);
- ⓪(IF i^.imports # NIL THEN
- ⓪*j:= ADR (i^.imports^);
- ⓪*WHILE j^ # NIL DO
- ⓪,IF NOT ( (msr1 IN j^^.state) OR (loadImp IN j^^.state) ) THEN
- ⓪.markImported (j^, s);
- ⓪,END;
- ⓪,INC (j, 4)
- ⓪*END
- ⓪(END;
- ⓪&END markImported;
- ⓪
- ⓪$VAR i: ModRef; s: ModStates;
- ⓪
- ⓪$BEGIN (* markNonFree *)
- ⓪&presetFlags;
- ⓪&ResetList (ModLst);
- ⓪&LOOP
- ⓪(i:= NextEntry (ModLst);
- ⓪(IF i=NIL THEN EXIT END;
- ⓪(s:= i^.state;
- ⓪(IF NOT (msr1 IN s) THEN
- ⓪*IF ( (mainMod IN s) AND (running IN s) ) OR (installed IN s) THEN
- ⓪,markImported (i, msr1)
- ⓪*ELSIF loaded IN s THEN
- ⓪,markImported (i, loadImp)
- ⓪*END
- ⓪(END
- ⓪&END;
- ⓪&(*$ ? Trace:
- ⓪(WriteLn;
- ⓪(WriteString ('Freie Module:');
- ⓪(ResetList (ModLst);
- ⓪(LOOP
- ⓪*i:= NextEntry (ModLst);
- ⓪*IF i=NIL THEN EXIT END;
- ⓪*IF NOT (msr1 IN i^.state) THEN
- ⓪,WriteString (i^.codeName^);
- ⓪,WriteString (' ');
- ⓪*END
- ⓪(END;
- ⓪(WriteLn;
- ⓪(Read(inch);
- ⓪&*)
- ⓪$END markNonFree;
- ⓪
- ⓪"PROCEDURE release0 (VAR client: ModRef);
- ⓪
- ⓪$PROCEDURE add (VAR list: modList);
- ⓪&BEGIN
- ⓪(WITH list DO
- ⓪*IF p > MaxModExec THEN
- ⓪,ASSEMBLER
- ⓪0TRAP #6
- ⓪0DC.W Overflow-$8000
- ⓪0ACZ 'Release: Too many modules'
- ⓪,END
- ⓪*END;
- ⓪*a^[p]:= client;
- ⓪*INC (p);
- ⓪(END;
- ⓪&END add;
- ⓪
- ⓪$VAR j, j2: ModRef; pj: POINTER TO ModRef; deInit, removable: BOOLEAN;
- ⓪
- ⓪$BEGIN (* release0 *)
- ⓪&(*$ ? Trace: WriteLn; WriteString ('Release: '); WriteString (client^.codeName^); *)
- ⓪&IF msr1 IN client^.state THEN
- ⓪((*$ ? Trace: WriteString (' / is linked or already removed - no action'); *)
- ⓪&ELSE
- ⓪(INCL (client^.state,msr1);
- ⓪(deInit:= initialized IN client^.state;
- ⓪(removable:= NOT (loadImp IN client^.state);
- ⓪(pj:= ADDRESS (client^.imports);
- ⓪(IF pj # NIL THEN
- ⓪*(*$ ? Trace: WriteLn; WriteString ('< releasing imports of '); WriteString (client^.codeName^); *)
- ⓪*LOOP
- ⓪,j:= pj^;
- ⓪,IF j = NIL THEN EXIT END;
- ⓪,j2:= j;
- ⓪,pj^:= NIL;
- ⓪,release0 (j2); (* 'j2' wird ggf. auf NIL gesetzt *)
- ⓪,pj^:= j;
- ⓪,INC (pj, SIZE (pj^));
- ⓪*END;
- ⓪*(*$ ? Trace: WriteLn; WriteString ('> end of releasing imports of '); WriteString (client^.codeName^); *)
- ⓪(END;
- ⓪(IF deInit THEN add (exitList) END;
- ⓪(IF removable THEN
- ⓪*add (removeList);
- ⓪*client:= NIL
- ⓪(END
- ⓪&END;
- ⓪&(*$ ? Trace: Read(inch) *)
- ⓪$END release0;
- ⓪
- ⓪"VAR listCnt: CARDINAL;
- ⓪
- ⓪"BEGIN (* FullRelease *)
- ⓪$(*$ ? Trace2: WriteLn; WriteString ('Begin Release!'); *)
- ⓪$IF NOT (program IN client^.state) & NOT (linked IN client^.state) THEN
- ⓪&markNonFree;
- ⓪&exitList.p:= 0;
- ⓪&removeList.p:= 0;
- ⓪&release0 (client);
- ⓪&WITH exitList DO
- ⓪(WHILE p > 0 DO
- ⓪*DEC (p);
- ⓪*(*$ ? Trace2 OR Trace: WriteLn; WriteString ('deinit '); WriteString (a^[p]^.codeName^); *)
- ⓪*WITH a^[p]^ DO
- ⓪,DoRemoveInfo (codeStart, codeLen);
- ⓪,EXCL (state, initialized);
- ⓪*END
- ⓪(END
- ⓪&END;
- ⓪&WITH removeList DO
- ⓪(WHILE p > 0 DO
- ⓪*DEC (p);
- ⓪*(*$ ? Trace: WriteLn; WriteString ('dealloc '); WriteString (a^[p]^.codeName^); *)
- ⓪*FindEntry (ModLst, a^[p], ok);
- ⓪*IF ok THEN
- ⓪,RemoveEntry (ModLst,error);
- ⓪,FreeMod (a^[p])
- ⓪*ELSE
- ⓪,ASSEMBLER
- ⓪0TRAP #6
- ⓪0DC.W IllegalState ; interner Fehler!
- ⓪,END
- ⓪*END;
- ⓪(END
- ⓪&END;
- ⓪&(*$ ? Trace2: Read(inch); *)
- ⓪$END;
- ⓪"END FullRelease;
- ⓪
- ⓪
- ⓪ PROCEDURE DummyMonitor;
- ⓪"(*$L-*)
- ⓪"BEGIN
- ⓪"END DummyMonitor;
- ⓪"(*$L+*)
- ⓪
- ⓪ PROCEDURE DummyLoading (REF a,b:ARRAY OF CHAR;c:ADDRESS;d:LONGCARD;e:ADDRESS;f:LONGCARD);
- ⓪"BEGIN
- ⓪"END DummyLoading;
- ⓪
- ⓪ PROCEDURE envelope (open, child: BOOLEAN; VAR exitcode: INTEGER);
- ⓪"(*
- ⓪#* Kontrollieren, ob der Prozeß endet, unter dem ein Modul geladen wurde.
- ⓪#* Dann das Modul freigeben. Da der 'owner' nur dann gesetzt wird, wenn
- ⓪#* kein SysAlloc (FullStorBaseAccess) erfolgen konnte, passiert dies nur
- ⓪#* auf dem TT oder wenn kein erw. Storage-Access erlaubt wird.
- ⓪#*)
- ⓪"VAR i: ModRef; result: LoaderResults;
- ⓪"BEGIN
- ⓪$IF NOT open AND child THEN
- ⓪&ResetList (ModLst);
- ⓪&LOOP
- ⓪(i:= NextEntry (ModLst);
- ⓪(IF i=NIL THEN EXIT END;
- ⓪(IF (loaded IN i^.state) & (i^.owner = ProcessID^) THEN
- ⓪*freeModule (i, result);
- ⓪*ResetList (ModLst); (* wieder von vorn *)
- ⓪(END
- ⓪&END;
- ⓪$END
- ⓪"END envelope;
- ⓪
- ⓪ VAR ehdl: EnvlpCarrier;
- ⓪
- ⓪ BEGIN (* of Loader *)
- ⓪"SetEnvelope (ehdl, envelope, MemArea {NIL,0});
- ⓪"IF UseStackFrame () THEN StackFrameOffs:= 2 ELSE StackFrameOffs:= 0 END;
- ⓪"callptr:= 1;
- ⓪"ExecPtr:= 0;
- ⓪"DefaultStackSize:= 16384;
- ⓪"Loading:= DummyLoading;
- ⓪"Monitor:= DummyMonitor;
- ⓪"Release:= FullRelease;
- ⓪"(*$P+*)
- ⓪ END Loader.
- ⓪ ə
- (* $0000662F$000021CC$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$00005177$FFF09768$0000DC29$FFF09768$0000515F$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$00008304$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768$FFF09768Ç$00001C77T.......T.......T.......T.......T.......T.......T.......T.......T.......T.......$FFAD4838$FFAD4838$00005162$00008834$00008822$FFAD4838$00008822$00005967$FFAD4838$00001CA5$FFAD4838$00005173$0000515F$00001C77$00005949$FFAD4838îÇâ*)
-