home *** CD-ROM | disk | FTP | other *** search
/ Computer Club Elmshorn Atari PD / CCE_PD.iso / pc / 0500 / CCE_0544.ZIP / CCE_0544 / MX2 / MX2SRC.ARC / MX2.MOD < prev    next >
Text File  |  1989-01-05  |  39KB  |  1,165 lines

  1. (*$T-,$S-,$A+ *)
  2. MODULE MX2;
  3.  
  4. (*              Copyright 1987,1988 fred brooks LogicTek        *)
  5. (*                                                              *)
  6. (*                                                              *)
  7. (*   First Release                      12/8/87-FGB             *)
  8. (* Corrected code to match changes in lib modules               *)
  9. (*                                      1/9/88-FGB              *)
  10. (* Bug in parser converted all text to UPPER case. Fixed        *)
  11. (*                                      2/27/88-FGB             *)
  12. (* Misc bug fixes.                                              *)
  13. (*                                      4/3/88-FGB              *)
  14. (* Remove NETWORK routines from kernel                          *)
  15. (*                                      4/11/88-FGB             *)
  16. (* Remove SP & XMODEM  routines from kernel                     *)
  17. (*                                      4/11/88-FGB             *)
  18. (* Remove TRAP15 interface routines     6/9/88-FGB              *)
  19. (*                                                              *)
  20.  
  21.   FROM Terminal       IMPORT     ReadString,WriteString,WriteLn;
  22.   FROM TextIO         IMPORT     REadString;
  23.   FROM Conversions    IMPORT     ConvertFromString;
  24.   FROM M2Conversions  IMPORT     ConvertToInteger,ConvertToAddr;
  25.   FROM BitStuff       IMPORT     WAnd,WShr;
  26.   FROM GEMDOS         IMPORT     ExecMode,Exec,Alloc,Free,OldTerm,
  27.                                  GetPath,GetDrv,GetTime,
  28.                                  SetPath,SetDrv;
  29.   FROM XBIOS          IMPORT     SuperExec,IOREC,IORECPTR,SerialDevice,
  30.                                  IORec,ScreenPhysicalBase;
  31.   FROM BIOS           IMPORT     Device,BConStat,BConIn,BConOut,BCosStat,
  32.                                  KBShifts,GetKBShift,KBShiftBits;
  33.   FROM Streams        IMPORT     Stream,OpenStream,CloseStream,EOS,
  34.                                  StreamKinds;
  35.   FROM Storage        IMPORT     CreateHeap;
  36.   FROM SYSTEM         IMPORT     ADR,ADDRESS,CODE,PROCESS,REGISTER,SETREG;
  37.  
  38.   FROM   ATOMIC   IMPORT  Initsked,MultiEnd,MultiBegin,CronActive,
  39.                           InitProcesses,StartProcess,currentprocess,
  40.                           TermProcess,SIGNAL,SwapProcess,request,MAGIC,
  41.                           command,SleepProcess,WakeupProcess,
  42.                           ChangeProcessPriority,CRON,DeviceTable,
  43.                           spintenable,spintmask,spint,bpsave,GEMTYPE,
  44.                           sysvariable,gemsaveGvec,ROMDATE,OLDDATE,NEWDATE,
  45.                           NextPid,VERSION,sysmemsize,devicetype;
  46.  
  47.   FROM   SCANNER  IMPORT  scinit,nxparm,ltext,etext,bkparm,state;
  48.  
  49.   FROM   Strings  IMPORT  Compare,Pos,Length,Concat,CompareResults,String;
  50.  
  51.  
  52. CONST   intnum          =       4;    (* interrupt number on MFP *)
  53. TYPE    ctype   =
  54.                   RECORD
  55.                         stime            :       LONGCARD;
  56.                         freq             :       LONGCARD;
  57.                         btime            :       LONGCARD;
  58.                         command          :       String;
  59.                         active           :       BOOLEAN;
  60.                   END;
  61.           screen  =     ARRAY [0..7999] OF LONGCARD;
  62. VAR
  63.        result,pri,cli1,cli2,clipid,
  64.        spawnpid                                 : INTEGER;
  65.        proc                                     : PROC;
  66.        Oportdevice,Iportdevice                  : devicetype;
  67.        pc,returnadr,kpc,
  68.        oldikbd,par                              : ADDRESS;
  69.        gemsave,param                            : ARRAY [0..15] OF ADDRESS;
  70.        paramstringptr                           : POINTER TO String;
  71.        sizewsp,temphz200,cronslice,currenttime  : LONGCARD;
  72.        cmd,dev,c,a7,SR,tbiosSave                : ADDRESS;
  73.        gem   [88H]                              : ADDRESS;
  74.        hz200  [4baH]                            : LONGCARD;
  75.        termvec [408H]                           : ADDRESS;
  76.        linea [28H]                              : ADDRESS;
  77.        gemdos [84H]                             : ADDRESS;
  78.        gsxgem [88H]                             : ADDRESS;
  79.        tbios  [0b4H]                            : ADDRESS;
  80.        xbios  [0b8H]                            : ADDRESS;
  81.        linef  [2cH]                             : ADDRESS;
  82.        level2 [68H]                             : ADDRESS;
  83.        level4 [70H]                             : ADDRESS;
  84.        shellp [04f6H]                           : ADDRESS;
  85.        ikbdvec [118H]                           : PROC;
  86.        OpenCLI,i,bprunning,function,
  87.        time,defaultdrv,requestdrv,sr,drv,
  88.        ksr                                      : CARDINAL;
  89.        cmdstring,temp,name,tail,envstr,pname,
  90.        defaultpath,requestpath,pstemp,initprg   : String;
  91.        inuse,done,
  92.        swloaded,caps,reservemem,swapcli,inok,
  93.        outok                                    : BOOLEAN;
  94.        periods,drivemap,HotKey,Hotreturn,kjunk,
  95.        NorMouse,CurMouse,RebootKey,memreserve,
  96.        SYSMEM,cin                               : LONGCARD;
  97.        crontable                                : ARRAY [0..15] OF ctype;
  98.        ticktime                                 : LONGINT;
  99.        s0                                       : SIGNAL;
  100.        sysvar                                   : sysvariable;
  101.        sysvector [144H]                         : POINTER TO sysvariable;
  102.        Kshift,Hotset,CapsL                      : KBShifts;
  103.        physcreen                                : POINTER TO screen;
  104.        screensave                               : POINTER TO ARRAY [1..2]
  105.                                                   OF screen;
  106.        kbdiorec                                 : IORECPTR;
  107.        ibuf                                     : POINTER TO ARRAY [0..63]
  108.                                                   OF LONGCARD;
  109.  
  110. CONST
  111.   TDI   = "                Written in TDI MODULA-2 Version 3.01a ";
  112.   TITLE1 = "       ";
  113.   TITLE2 = " Copyright LogicTek 1987,1988 Fred Brooks ";
  114.   CRONFILE = "CRONTAB";
  115.  
  116. (*$P- *)
  117. PROCEDURE       keytrapstart; (* modify IKBD system vector *)
  118. BEGIN
  119.         CODE(48e7H,0fffeH);   (* save regs movem  *)
  120.         CODE(206fH,62); (* move.l 62(a7),a0 get pc *)
  121.         kpc:=REGISTER(8);
  122.         CODE(306fH,60); (* move.w 60(a7),a0 get sr *)
  123.         ksr:=CARDINAL(REGISTER(8));
  124.         SETREG(8,ADDRESS(keytrapend));
  125.         CODE(2f48H,62); (* move new pc to stack *)
  126.         SETREG(8,2700H);
  127.         CODE(3f48H,60); (* move new sr to stack *) 
  128.  
  129.         SETREG(8,oldikbd);  (* move IKBD trap adr *)
  130.         CODE(43faH,10); (* lea 12(pc),a1 *)
  131.         CODE(2288H); (* move.l a0,(a1) *)
  132.         CODE(4cdfH,7fffH); (* restore regs movem *)
  133.         CODE(4ef9H,0,0) (* jmp back to routine *)
  134. END     keytrapstart;
  135. (*$P+ *)
  136.  
  137. (*$P- *)
  138. PROCEDURE       keytrapend; (* check for hotkeys *)
  139. BEGIN
  140.         CODE(5d8fH);    (* subq.l #6,sp *)
  141.         CODE(48e7H,0fffeH);   (* save regs movem  *)
  142.  
  143.         Hotreturn:=ibuf^[kbdiorec^.ibuftl DIV 4];
  144.         CODE(2f39H,0,4a2H); (* save BIOS pointers *)
  145.         CODE(4b9H,0,2eH,0,4a2H);
  146.  
  147.         IF Hotreturn=RebootKey THEN
  148.            CODE(46fcH,0300H); (* set user mode *)
  149.            CODE(42a7H,3f3cH,20H,4e41H,42b9H,0H,420H,2079H,0H,4H,4ed0H);
  150.         END;
  151.         IF Hotreturn=NorMouse THEN
  152.            gkey;
  153.            BConOut(KDB,CHAR(08H)); (* send relative mouse *)
  154.         END;
  155.         IF Hotreturn=CurMouse THEN
  156.            gkey;
  157.            BConOut(KDB,CHAR(0aH)); (* send cursor mouse *)
  158.         END;
  159.         IF Hotreturn=HotKey THEN
  160.            gkey;
  161.            swapcli:=TRUE;
  162.         END;
  163.  
  164.         CODE(23dfH,0,4a2H); (* restore BIOS pointers *)
  165.  
  166.         SETREG(8,ADDRESS(kpc));
  167.         CODE(2f48H,62); (* move new pc to stack *)
  168.         SETREG(8,ADDRESS(ksr));
  169.         CODE(3f48H,60); (* move new sr to stack *) 
  170.         CODE(4cdfH,7fffH); (* restore regs movem *)
  171.         CODE(4e73H); (* rte *)
  172. END     keytrapend;
  173. (*$P- *)
  174.  
  175. (*$P- *)
  176. PROCEDURE       gkey;
  177. BEGIN
  178.         IF BConStat(CON) THEN 
  179.            kjunk:=BConIn(CON);
  180.            ibuf^[kbdiorec^.ibuftl DIV 4]:=0;
  181.         END;
  182.         CODE(4e75H); (* rts *)
  183. END             gkey;
  184. (*$P+ *)
  185.  
  186. PROCEDURE       SetDrvPath(drive: CARDINAL; VAR path: ARRAY OF CHAR);
  187. BEGIN
  188.         SetDrv(drive,drivemap);
  189.         IF path[0]=0c THEN
  190.            path[0]:='\';
  191.            path[1]:=0c;
  192.            path[2]:=0c;
  193.         END;
  194.         done:=SetPath(path);
  195. END             SetDrvPath;
  196.  
  197. (* this is for the BIOS devices *)
  198. (*$P-,$S- *)
  199. PROCEDURE       changedevbios;
  200. BEGIN
  201.         CODE(48e7H,07ffeH);     (* save regs *)
  202.         CODE(306fH,56);         (* move.w 56(a7),a0  get SR *)
  203.         SR:=REGISTER(8);
  204.         IF SR<3ffH THEN        (* called from user mode *)
  205.            CODE(204fH);            (* move.l a7,a0 *)
  206.            a7:=REGISTER(8);        (* save ssp *)
  207.            CODE(4e68H,2e48H);      (* move.l usp,a0  move.l a0,a7 *)
  208.            CODE(306fH,2);  (* move.w 2(a7),a0 *)
  209.            dev:=REGISTER(8);
  210.            CODE(306fH,0);  (* move.w 0(a7),a0 *)
  211.            cmd:=REGISTER(8);
  212.            IF (cmd=1) OR (cmd=2) THEN (* check INPUT *)
  213.               IF dev=2 THEN
  214.                  IF currentprocess^.Iport=null THEN
  215.                     SETREG(8,a7);
  216.                     CODE(2e48H);            (* move.l a0,a7 *)
  217.                     CODE(4cdfH,7ffeH);         (* restore regs movem *)
  218.                     CODE(203CH,0FFFFH,0FFFFH); (* move.l -1,d0 *)
  219.                     CODE(4E73H);  (* RTE return -1 on all calls *)
  220.                  END;
  221.                  IF ORD(currentprocess^.Iport)>ORD(null) THEN (* user *)
  222.                      IF cmd=2 THEN
  223.                  cin:=DeviceTable[ORD(currentprocess^.Oport)].bconin();
  224.                        SETREG(8,a7);
  225.                        CODE(2e48H);            (* move.l a0,a7 *)
  226.                        SETREG(0,ADDRESS(cin));
  227.                        CODE(4cdfH,7ffeH);         (* restore regs movem *)
  228.                        CODE(4E73H);  (* RTE return -1 on all calls *)
  229.                     ELSE
  230.                  inok:=DeviceTable[ORD(currentprocess^.Oport)].bconstat();
  231.                        IF inok THEN
  232.                           SETREG(8,a7);
  233.                           CODE(2e48H);            (* move.l a0,a7 *)
  234.                           CODE(4cdfH,7ffeH);      (* restore regs movem *)
  235.                           CODE(203CH,0FFFFH,0FFFFH); (* move.l -1,d0 *)
  236.                           CODE(4E73H);  (* RTE return -1 *)
  237.                        ELSE
  238.                           SETREG(8,a7);
  239.                           CODE(2e48H);            (* move.l a0,a7 *)
  240.                           CODE(4cdfH,7ffeH);      (* restore regs movem *)
  241.                           CODE(203CH,0H,0H); (* move.l 0,d0 *)
  242.                           CODE(4E73H);  (* RTE return 0 *)
  243.                        END;
  244.                     END;
  245.                 END;
  246.                  dev:=ADDRESS(currentprocess^.Iport); (* change to port *)
  247.                  SETREG(8,dev);
  248.                  CODE(3f48H,2); (* move.w a0,2(a7) set value in stack *)
  249.               END;
  250.            END;
  251.            IF (cmd=3) OR (cmd=8) THEN (* check OUTPUT *)
  252.               IF dev=2 THEN
  253.                  IF currentprocess^.Oport=null THEN
  254.                     SETREG(8,a7);
  255.                     CODE(2e48H);            (* move.l a0,a7 *)
  256.                     CODE(4cdfH,7ffeH);         (* restore regs movem *)
  257.                     CODE(203CH,0FFFFH,0FFFFH); (* move.l -1,d0 *)
  258.                     CODE(4E73H);  (* RTE return -1 on all calls *)
  259.                  END;
  260.                  IF ORD(currentprocess^.Oport)>ORD(null) THEN
  261.                     IF cmd=3 THEN
  262.                        CODE(306fH,4);  (* move.w 4(a7),a0 *)
  263.                        c:=REGISTER(8);
  264.                  DeviceTable[ORD(currentprocess^.Oport)].bconout(CHAR(c));
  265.                        SETREG(8,a7);
  266.                        CODE(2e48H);            (* move.l a0,a7 *)
  267.                        CODE(4cdfH,7ffeH);         (* restore regs movem *)
  268.                        CODE(203CH,0FFFFH,0FFFFH); (* move.l -1,d0 *)
  269.                        CODE(4E73H);  (* RTE return -1 on all calls *)
  270.                     ELSE
  271.                  outok:=DeviceTable[ORD(currentprocess^.Oport)].bcostat();
  272.                        IF outok THEN
  273.                           SETREG(8,a7);
  274.                           CODE(2e48H);            (* move.l a0,a7 *)
  275.                           CODE(4cdfH,7ffeH);      (* restore regs movem *)
  276.                           CODE(203CH,0FFFFH,0FFFFH); (* move.l -1,d0 *)
  277.                           CODE(4E73H);  (* RTE return -1 *)
  278.                        ELSE
  279.                           SETREG(8,a7);
  280.                           CODE(2e48H);            (* move.l a0,a7 *)
  281.                           CODE(4cdfH,7ffeH);      (* restore regs movem *)
  282.                           CODE(203CH,0H,0H); (* move.l 0,d0 *)
  283.                           CODE(4E73H);  (* RTE return 0 *)
  284.                        END;
  285.                     END;
  286.                  END;
  287.                  dev:=ADDRESS(currentprocess^.Oport); (* change to port *)
  288.                  SETREG(8,dev);
  289.                  CODE(3f48H,2); (* move.w a0,2(a7) set value in stack *)
  290.               END;
  291.            END;
  292.            SETREG(8,a7);
  293.            CODE(2e48H);            (* move.l a0,a7 *)
  294.         ELSE                       (* called from super mode *)
  295.            CODE(306fH,64);  (* move.w 64(a7),a0 *)
  296.            dev:=REGISTER(8);
  297.            CODE(306fH,62);  (* move.w 62(a7),a0 *)
  298.            cmd:=REGISTER(8);
  299.            IF (cmd=1) OR (cmd=2) THEN (* check INPUT *)
  300.               IF dev=2 THEN
  301.                  IF currentprocess^.Iport=null THEN
  302.                     CODE(4cdfH,7ffeH);         (* restore regs movem *)
  303.                     CODE(203CH,0FFFFH,0FFFFH); (* move.l -1,d0 *)
  304.                     CODE(4E73H); (* RTE return -1 on all calls *)
  305.                  END;
  306.                  IF ORD(currentprocess^.Iport)>ORD(null) THEN
  307.                      IF cmd=2 THEN
  308.                  cin:=DeviceTable[ORD(currentprocess^.Oport)].bconin();
  309.                        SETREG(0,ADDRESS(cin));
  310.                        CODE(4cdfH,7ffeH);         (* restore regs movem *)
  311.                        CODE(4E73H);  (* RTE return cin *)
  312.                     ELSE
  313.                  inok:=DeviceTable[ORD(currentprocess^.Oport)].bconstat();
  314.                        IF inok THEN
  315.                           CODE(4cdfH,7ffeH);   (* restore regs movem *)
  316.                           CODE(203CH,0FFFFH,0FFFFH); (* move.l -1,d0 *)
  317.                           CODE(4E73H);  (* RTE return -1  *)
  318.                        ELSE
  319.                           CODE(4cdfH,7ffeH);   (* restore regs movem *)
  320.                           CODE(203CH,0H,0H); (* move.l 0,d0 *)
  321.                           CODE(4E73H);  (* RTE return 0 *)
  322.                        END;
  323.                     END;
  324.                 END;
  325.                  dev:=ADDRESS(currentprocess^.Iport); (* change to port *)
  326.                  SETREG(8,dev);
  327.                  CODE(3f48H,64); (* move.w a0,64(a7) set value in stack *)
  328.               END;
  329.            END;
  330.            IF (cmd=3) OR (cmd=8) THEN (* check OUTPUT *)
  331.               IF dev=2 THEN
  332.                  IF currentprocess^.Oport=null THEN
  333.                     CODE(4cdfH,7ffeH);         (* restore regs movem *)
  334.                     CODE(203CH,0FFFFH,0FFFFH); (* move.l -1,d0 *)
  335.                     CODE(4E73H); (* RTE return -1 on all calls *)
  336.                  END;
  337.                  IF ORD(currentprocess^.Oport)>ORD(null) THEN
  338.                     IF cmd=3 THEN
  339.                        CODE(306fH,66);  (* move.w 66(a7),a0 *)
  340.                        c:=REGISTER(8);
  341.                  DeviceTable[ORD(currentprocess^.Oport)].bconout(CHAR(c));
  342.                        CODE(4cdfH,7ffeH);         (* restore regs movem *)
  343.                        CODE(203CH,0FFFFH,0FFFFH); (* move.l -1,d0 *)
  344.                        CODE(4E73H);  (* RTE return -1 on all calls *)
  345.                     ELSE
  346.                  outok:=DeviceTable[ORD(currentprocess^.Oport)].bcostat();
  347.                        IF outok THEN
  348.                           CODE(4cdfH,7ffeH);   (* restore regs movem *)
  349.                           CODE(203CH,0FFFFH,0FFFFH); (* move.l -1,d0 *)
  350.                           CODE(4E73H);  (* RTE return -1  *)
  351.                        ELSE
  352.                           CODE(4cdfH,7ffeH);   (* restore regs movem *)
  353.                           CODE(203CH,0H,0H); (* move.l 0,d0 *)
  354.                           CODE(4E73H);  (* RTE return 0 *)
  355.                        END;
  356.                     END;
  357.                  END;
  358.                  dev:=ADDRESS(currentprocess^.Oport); (* change to port *)
  359.                  SETREG(8,dev);
  360.                  CODE(3f48H,64); (* move.w a0,64(a7) set value in stack *)
  361.               END;
  362.            END;
  363.         END;
  364.         SETREG(8,tbiosSave);  (* move trap adr *)
  365.         CODE(43faH,10); (* lea 12(pc),a1 *)
  366.         CODE(2288H); (* move.l a0,(a1) *)
  367.         CODE(4cdfH,7ffeH); (* restore regs movem *)
  368.         CODE(4ef9H,0,0) (* jmp back to routine *)
  369. END             changedevbios;
  370. (*$P+,$S+ *)
  371.         
  372. (*$P-,$S- *)
  373. PROCEDURE       setup;
  374. BEGIN
  375.         tbios:=ADDRESS(changedevbios);
  376.         CODE(4e75H);    (* RTS *)
  377. END             setup;
  378. (*$P+,$S+ *)
  379.  
  380. (*$P-,$S- *)
  381. PROCEDURE       tbiossetup;
  382. BEGIN
  383.         tbiosSave:=tbios;
  384.         CODE(4e75H);    (* RTS *)
  385. END             tbiossetup;
  386. (*$P+,$S+ *)
  387. (* end device routines *)
  388.  
  389. PROCEDURE       SelectPort;
  390. BEGIN
  391.         currentprocess^.Oport:=Oportdevice;
  392.         currentprocess^.Iport:=Iportdevice;
  393.         IF OpenCLI>0 THEN SuperExec(setup) END;
  394. END             SelectPort;
  395.  
  396. PROCEDURE       RunProgram;
  397. VAR     temp    :       String;
  398.         p       :       CARDINAL;
  399. BEGIN
  400.         IF (bprunning>1) THEN
  401.            gemsaveGvec^:=ADR(currentprocess^.bpsave);
  402.            currentprocess^.bpsave:=bpsave;
  403.            currentprocess^.bpsave[0]:=ADR(currentprocess^.bpsave);
  404.         END;
  405.         SetDrvPath(requestdrv,requestpath);
  406.         IF Pos(currentprocess^.ipname,".",0,p) THEN
  407.                 ExecProgram;
  408.         ELSE
  409.                 temp:=currentprocess^.ipname;
  410.                 Concat(currentprocess^.ipname,".prg",
  411.                        currentprocess^.ipname);
  412.                 ExecProgram;
  413.                 IF currentprocess^.return=(-33) THEN
  414.                         currentprocess^.ipname:=temp;
  415.                         Concat(currentprocess^.ipname,".tos",
  416.                                currentprocess^.ipname);
  417.                         ExecProgram;
  418.                 END;
  419.                 IF currentprocess^.return=(-33) THEN
  420.                         currentprocess^.ipname:=temp;
  421.                         Concat(currentprocess^.ipname,".ttp",
  422.                         currentprocess^.ipname);
  423.                         ExecProgram;
  424.                 END;
  425.         END;
  426. END             RunProgram;
  427.  
  428. (*$P- *)
  429. PROCEDURE       ExecProgram;
  430. BEGIN
  431.           CODE(48e7H,0fffeH); (* save regs *)
  432.           currentprocess^.tmpcor:=PROCESS(REGISTER(15));
  433.           SETREG(8,ADR(currentprocess^.ipenvstr));
  434.           CODE(2f08H);  (* move.l a0,-(sp) *)
  435.           SETREG(8,ADR(currentprocess^.iptail));
  436.           CODE(2f08H);  (* move.l a0,-(sp) *)
  437.           SETREG(8,ADR(currentprocess^.ipname));
  438.           CODE(2f08H);  (* move.l a0,-(sp) *)
  439.           CODE(3f3cH,0);    (* move.w #0,-(sp) LOADEXECUTE *)
  440.           CODE(3f3cH,4bH);  (* move.w #4b,-(sp) gemdos EXEC *)
  441.           CODE(4e41H);      (* trap #1 *)
  442.           SETREG(8,currentprocess^.tmpcor);
  443.           CODE(2e48H);   (* move.l a0,a7 *)
  444.           CODE(4cdfH,7fffH); (* restore regs *)
  445.           currentprocess^.return:=INTEGER(REGISTER(0));
  446.           CODE(4e75H);    (* rts *)
  447. END             ExecProgram;
  448. (*$P+ *)
  449.  
  450. PROCEDURE       IP;
  451. BEGIN
  452.         currentprocess^.ipname:=name;
  453.         currentprocess^.iptail:=tail; 
  454.         currentprocess^.ipenvstr:=envstr;
  455.         SelectPort;
  456.         INC(OpenCLI);
  457.         INC(bprunning);
  458.         LOOP
  459.                 MultiBegin;
  460.                 RunProgram;
  461.         END;
  462. END     IP;
  463.  
  464. PROCEDURE       BP;
  465. BEGIN
  466.         currentprocess^.ipname:=name;
  467.         currentprocess^.iptail:=tail; 
  468.         currentprocess^.ipenvstr:=envstr;
  469.         INC(bprunning);
  470.         SelectPort;
  471.         MultiBegin;
  472.  
  473.         RunProgram;
  474.         MultiEnd;
  475.         DEC(bprunning);
  476.         IF currentprocess^.return#0 THEN
  477.            currentprocess^.errno:=2;
  478.         ELSE
  479.            currentprocess^.errno:=0;
  480.         END;
  481.         TermProcess(currentprocess^.pid);
  482. END     BP;
  483.  
  484. PROCEDURE       Use;
  485. VAR             i        :          CARDINAL;
  486.                 pid      :          INTEGER;
  487.                 s0       :          SIGNAL;
  488.  
  489. PROCEDURE       CheckPort(VAR portdevice: devicetype);
  490. BEGIN
  491.            nxparm;
  492.            ltext(ADR(temp),SIZE(temp));
  493.            IF temp[0]='-' THEN
  494.                 portdevice:=con;
  495.                 IF temp[1]='n' THEN
  496.                         portdevice:=null;
  497.                 END;
  498.                 IF temp[1]='a' THEN
  499.                         portdevice:=aux;
  500.                 END;
  501.                 IF temp[1]='m' THEN
  502.                         portdevice:=midi;
  503.                 END;
  504.                 IF temp[1]='p' THEN
  505.                         portdevice:=printer;
  506.                 END;
  507.                 IF temp[1]='0' THEN
  508.                         portdevice:=dev0;
  509.                 END;
  510.                 IF temp[1]='1' THEN
  511.                         portdevice:=dev1;
  512.                 END;
  513.                 IF temp[1]='2' THEN
  514.                         portdevice:=dev2;
  515.                 END;
  516.                 IF temp[1]='3' THEN
  517.                         portdevice:=dev3;
  518.                 END;
  519.            ELSE
  520.                 portdevice:=con;
  521.                 bkparm;
  522.            END;
  523. END             CheckPort;
  524.  
  525. PROCEDURE       Reset;
  526. BEGIN
  527.            request.req:=FALSE;
  528.            inuse:=FALSE;
  529. END             Reset;
  530.  
  531. PROCEDURE       gettail;
  532. BEGIN
  533.         nxparm;
  534.         etext(ADR(tail[1]),SIZE(tail));
  535.         bkparm;
  536.         etext(ADR(envstr),SIZE(envstr));
  537.         tail[0]:=CHAR(Length(envstr));
  538.         envstr:='';
  539. END             gettail;
  540.  
  541. PROCEDURE       Caps(VAR str: String); (* convert str to CAPS *)
  542. VAR                i               :       INTEGER;
  543. BEGIN
  544.         i:=0;
  545.         WHILE ORD(str[i])#0 DO
  546.               str[i]:=CAP(str[i]);
  547.               INC(i);
  548.         END;
  549. END             Caps;
  550.  
  551. BEGIN
  552.         IF request.magic#MAGIC THEN
  553.            request.magic:=0;
  554.            currentprocess^.errno:=54;
  555.            Reset;
  556.            RETURN;
  557.         END;
  558.         request.magic:=0;
  559.         cmdstring:=command;
  560.         inuse:=TRUE;
  561.         scinit(ADR(cmdstring),SIZE(cmdstring));
  562.         nxparm;
  563.         ltext(ADR(name),SIZE(name));
  564.         Caps(name);
  565.         IF Compare("IP",name)=Equal THEN
  566.            nxparm;
  567.            ltext(ADR(name),SIZE(name));
  568.  
  569.            gettail;
  570.  
  571.            pri:=5;
  572.            FOR i:=0 TO 79 DO
  573.                pname[i]:=name[i];
  574.            END;
  575.            Reset;
  576.            Oportdevice:=con;
  577.            Iportdevice:=con;
  578.            proc:=IP;
  579.            sizewsp:=1000;
  580.            SuperExec(getvector);
  581.            StartProcess(proc,sizewsp,pri,pname,par);
  582.            RETURN;
  583.         END;
  584.         IF Compare("BP",name)=Equal THEN
  585.            CheckPort(Iportdevice);
  586.            CheckPort(Oportdevice);
  587.            nxparm;
  588.            ltext(ADR(temp),SIZE(temp));
  589.            ConvertToInteger(temp,done,pri);
  590.            IF NOT done THEN 
  591.               pri:=4;
  592.               bkparm;
  593.            END;
  594.            nxparm;
  595.            ltext(ADR(name),SIZE(name));
  596.  
  597.            gettail;
  598.  
  599.            FOR i:=0 TO 79 DO
  600.                pname[i]:=name[i];
  601.            END;
  602.            Reset;
  603.            proc:=BP;
  604.            sizewsp:=2000;
  605.            SuperExec(getbiosvector);
  606.            StartProcess(proc,sizewsp,pri,pname,par);
  607.            RETURN;
  608.         END;
  609.         IF Compare("FP",name)=Equal THEN
  610.            CheckPort(Iportdevice);
  611.            CheckPort(Oportdevice);
  612.            nxparm;
  613.            ltext(ADR(temp),SIZE(temp));
  614.            ConvertToInteger(temp,done,pri);
  615.            IF NOT done THEN 
  616.               pri:=5;
  617.               bkparm;
  618.            END;
  619.            nxparm;
  620.            ltext(ADR(name),SIZE(name));
  621.  
  622.            gettail;
  623.  
  624.            FOR i:=0 TO 79 DO
  625.                pname[i]:=name[i];
  626.            END;
  627.            Reset;
  628.            proc:=BP;
  629.            sizewsp:=2000;
  630.            SuperExec(getvector);
  631.            StartProcess(proc,sizewsp,pri,pname,par);
  632.            RETURN;
  633.         END;
  634.         IF Compare("PORT",name)=Equal THEN
  635.            nxparm;
  636.            ltext(ADR(name),SIZE(name));
  637.            ConvertToInteger(name,done,pid);
  638.            IF (NOT done) OR (NOT (pid > clipid)) THEN
  639.               Reset;
  640.               RETURN;
  641.            END;
  642.            s0:=currentprocess;
  643.            LOOP
  644.               s0:=s0^.next;
  645.               IF s0^.pid=1 THEN Reset; RETURN; END;
  646.               IF s0^.pid=pid THEN EXIT END;
  647.            END;
  648.            CheckPort(s0^.Iport);
  649.            CheckPort(s0^.Oport);
  650.            Reset;
  651.            RETURN;
  652.         END;
  653.         IF Compare("CRON",name)=Equal THEN
  654.            nxparm;
  655.            ltext(ADR(name),SIZE(name));
  656.            Caps(name);
  657.            IF Compare("ON",name)=Equal THEN 
  658.               CronActive:=TRUE;
  659.               LoadCRON;
  660.            END;
  661.            IF Compare("OFF",name)=Equal THEN
  662.               CronActive:=FALSE;
  663.            END;
  664.            Reset;
  665.            RETURN;
  666.         END;
  667.         IF Compare("NICE",name)=Equal THEN
  668.            nxparm;
  669.            ltext(ADR(name),SIZE(name));
  670.            ConvertToInteger(name,done,pri);
  671.            IF NOT done THEN
  672.               Reset;
  673.               RETURN;
  674.            END;
  675.            nxparm;
  676.            ltext(ADR(name),SIZE(name));
  677.            IF state.return=0 THEN
  678.               ConvertToInteger(name,done,pid);
  679.               IF NOT done THEN
  680.                  pid:=request.pid;
  681.               END;
  682.            ELSE
  683.               pid:=request.pid;
  684.            END;
  685.            ChangeProcessPriority(pid,pri);
  686.            Reset;
  687.            RETURN;
  688.         END;
  689.         IF Compare("HP",name)=Equal THEN
  690.            nxparm;
  691.            ltext(ADR(name),SIZE(name));
  692.            ConvertToInteger(name,done,pid);
  693.            IF done THEN
  694.               SleepProcess(pid);
  695.            ELSE
  696.               currentprocess^.errno:=3;
  697.            END;
  698.            Reset;
  699.            RETURN;
  700.         END;
  701.         IF Compare("WP",name)=Equal THEN
  702.            nxparm;
  703.            ltext(ADR(name),SIZE(name));
  704.            ConvertToInteger(name,done,pid);
  705.            IF done THEN
  706.               WakeupProcess(pid);
  707.            ELSE
  708.               currentprocess^.errno:=3;
  709.            END;
  710.            Reset;
  711.            RETURN;
  712.         END;
  713.         IF Compare("KILL",name)=Equal THEN
  714.            nxparm;
  715.            ltext(ADR(name),SIZE(name));
  716.            ConvertToInteger(name,done,pid);
  717.            IF done AND (pid>clipid) THEN
  718.               TermProcess(pid);
  719.            ELSE
  720.               currentprocess^.errno:=3;
  721.            END;
  722.            Reset;
  723.            RETURN;
  724.         END;
  725.      Reset;
  726. END     Use;
  727.  
  728. (* return time in seconds *)
  729. PROCEDURE       converttime(time: CARDINAL): LONGCARD;
  730. VAR                h,m,s           :         LONGCARD;
  731. BEGIN
  732.         h:=LONGCARD(WShr(WAnd(time,63488),11));  (* hours *)
  733.         m:=LONGCARD(WShr(WAnd(time,2016),5));    (* minutes *)
  734.         s:=2*LONGCARD(WAnd(time,31));            (* seconds *)
  735.         RETURN s+(m*60)+(h*3600);
  736. END             converttime;
  737.  
  738. (*$P- *)
  739. PROCEDURE       gettick;
  740. BEGIN
  741.         temphz200:=hz200;
  742.         CODE(4e75H); (* rts *)
  743. END     gettick;
  744. (*$P+ *)
  745.  
  746. (*$P- *)
  747. PROCEDURE       setvector;
  748. BEGIN
  749.         linea:=s0^.gemsave[1];
  750.         gemdos:=s0^.gemsave[2];
  751.         gsxgem:=s0^.gemsave[3];
  752.         tbios:=s0^.gemsave[4];
  753.         xbios:=s0^.gemsave[5];
  754.         linef:=s0^.gemsave[6];
  755.         level2:=s0^.gemsave[7];
  756.         level4:=s0^.gemsave[8];
  757.         shellp:=s0^.gemsave[9];
  758.         currentprocess^.Oport:=s0^.Oport;
  759.         currentprocess^.Iport:=s0^.Iport;
  760.         CODE(4e75H); (* rts *)
  761. END     setvector;
  762. (*$P+ *)
  763.  
  764. (*$P- *)
  765. PROCEDURE       getvector;
  766. BEGIN
  767.         SetDrvPath(defaultdrv,defaultpath);
  768.         linea:=gemsave[1];
  769.         gemdos:=gemsave[2];
  770.         gsxgem:=gemsave[3];
  771.         tbios:=gemsave[4];
  772.         xbios:=gemsave[5];
  773.         linef:=gemsave[6];
  774.         level2:=gemsave[7];
  775.         level4:=gemsave[8];
  776.         shellp:=gemsave[9];
  777.         currentprocess^.Oport:=devicetype(gemsave[10]);
  778.         currentprocess^.Iport:=devicetype(gemsave[10]);
  779.         CODE(4e75H); (* rts *)
  780. END     getvector;
  781. (*$P+ *)
  782.  
  783. (*$P- *)
  784. PROCEDURE       getbiosvector;
  785. BEGIN
  786.         tbios:=gemsave[4];
  787.         currentprocess^.Oport:=devicetype(gemsave[10]);
  788.         currentprocess^.Iport:=devicetype(gemsave[10]);
  789.         CODE(4e75H); (* rts *)
  790. END     getbiosvector;
  791. (*$P+ *)
  792.  
  793. (*$P- *)
  794. PROCEDURE       savevector;
  795. BEGIN
  796.         GetPath(defaultpath,0);
  797.         GetDrv(defaultdrv);
  798.         requestdrv:=defaultdrv;
  799.         requestpath:=defaultpath;
  800.         gemsave[1]:=linea;
  801.         gemsave[2]:=gemdos;
  802.         gemsave[3]:=gsxgem;
  803.         gemsave[4]:=tbios;
  804.         gemsave[5]:=xbios;
  805.         gemsave[6]:=linef;
  806.         gemsave[7]:=level2;
  807.         gemsave[8]:=level4;
  808.         gemsave[9]:=shellp;
  809.         gemsave[10]:=ADDRESS(con);
  810.         returnadr:=termvec;
  811.         oldikbd:=ADDRESS(ikbdvec);
  812.         ikbdvec:=keytrapstart;
  813.         CODE(4e75H); (* rts *)
  814. END     savevector;
  815. (*$P+ *)
  816.  
  817. PROCEDURE       readcrontab;
  818. VAR             result,i                          : INTEGER;
  819.                 S                                 : Stream;
  820.                 entry,parm                        : String;
  821. BEGIN
  822.         OpenStream(S,"CRONTAB",READ,result);
  823.         IF result=0 THEN
  824.            WHILE NOT EOS(S) DO
  825.                  REadString(S,entry);
  826.                  scinit(ADR(entry),SIZE(entry));
  827.                  nxparm;
  828.                  ltext(ADR(parm),SIZE(parm));
  829.                  ConvertFromString(parm,10,FALSE,MAX(LONGCARD),
  830.                                    crontable[i].stime,done);
  831.                  crontable[i].stime:=crontable[i].stime*60;
  832.                  nxparm;
  833.                  ltext(ADR(parm),SIZE(parm));
  834.                  ConvertFromString(parm,10,FALSE,MAX(LONGCARD),
  835.                                    crontable[i].freq,done);
  836.                  crontable[i].freq:=crontable[i].freq*60;
  837.                  nxparm;
  838.                  etext(ADR(parm),SIZE(parm));
  839.                  crontable[i].command:=parm;
  840.                  crontable[i].active:=TRUE;
  841.                  INC(i);
  842.            END;
  843.            CloseStream(S,result);
  844.         ELSE
  845.            CronActive:=FALSE;
  846.         END;
  847. END     readcrontab;
  848.  
  849. PROCEDURE       LoadCRON; (* crontable loader *)
  850. BEGIN
  851.   SuperExec(gettick);
  852.   cronslice:=temphz200;
  853.   GetTime(i);
  854.   currenttime:=converttime(i); (* convert time to seconds *)
  855.   ticktime:=LONGINT(temphz200 DIV 200)-LONGINT(currenttime);
  856.        (* ticktime is 200hz clock at 00:00    *)
  857.   FOR i:=0 TO 15 DO               (* clear crontable *)
  858.       crontable[i].active:=FALSE;
  859.   END;
  860.   readcrontab;
  861.   FOR i:=0 TO 15 DO
  862.     IF crontable[i].active THEN
  863.      IF currenttime>crontable[i].stime THEN
  864.         periods:=((currenttime-crontable[i].stime) DIV crontable[i].freq)+1;
  865.         crontable[i].btime:=LONGCARD(ticktime+LONGINT(periods*crontable[i].freq));
  866.         crontable[i].btime:=(crontable[i].stime+crontable[i].btime)*200;
  867.      ELSE
  868.         crontable[i].btime:=LONGCARD(ticktime+LONGINT(crontable[i].stime));
  869.         crontable[i].btime:=crontable[i].btime*200;
  870.      END;
  871.     END;
  872.   END;
  873. END             LoadCRON;
  874.  
  875. PROCEDURE       TIMER;
  876. VAR             i       :       CARDINAL;
  877. BEGIN
  878.      IF NOT request.req THEN
  879.       LOOP;
  880.         FOR i:=0 TO 15 DO
  881.             IF crontable[i].active THEN
  882.                IF currentprocess^.slice>crontable[i].btime THEN
  883.                   REPEAT (* advance to next time slot *)
  884.                         INC(crontable[i].btime,(crontable[i].freq*200));
  885.                   UNTIL crontable[i].btime>currentprocess^.slice;
  886.                   command:=crontable[i].command;
  887.                   request.magic:=MAGIC;
  888.                   request.pid:=currentprocess^.pid;
  889.                   currentprocess^.ipenvstr:=defaultpath;
  890.                   currentprocess^.flags[0]:=LONGCARD(defaultdrv);
  891.                   request.req:=TRUE;
  892.                   EXIT; (* loop *)
  893.                END;
  894.             END;
  895.         END;
  896.         EXIT; (* loop *)
  897.       END; (* loop *)
  898.      END; (* if *)
  899. END     TIMER;
  900.  
  901. PROCEDURE       HOTKEYER;
  902. VAR             i,pid,t         :       INTEGER;
  903. BEGIN
  904.     IF swloaded THEN
  905.        s0:=currentprocess;
  906.        REPEAT
  907.              s0:=s0^.next
  908.        UNTIL s0^.pid=cli1;
  909.        IF s0^.wsp=NIL THEN
  910.           BConOut(CON,33C);
  911.           BConOut(CON,'f');
  912.           screensave^[1]:=physcreen^;
  913.           physcreen^:=screensave^[2];
  914.           screensave^[2]:=screensave^[1];
  915.           BConOut(CON,33C);
  916.           BConOut(CON,'e');
  917.           WakeupProcess(clipid);
  918.           swloaded:=FALSE;
  919.           done:=Free(ADDRESS(screensave));
  920.           RETURN;
  921.        END;
  922.        BConOut(CON,33C);
  923.        BConOut(CON,'f');
  924.        screensave^[1]:=physcreen^;
  925.        physcreen^:=screensave^[2];
  926.        screensave^[2]:=screensave^[1];
  927.        BConOut(CON,33C);
  928.        BConOut(CON,'e');
  929.        SleepProcess(cli1);
  930.        WakeupProcess(cli2);
  931.        t:=cli1;
  932.        cli1:=cli2;
  933.        cli2:=t;
  934.     END;
  935.     IF (NOT swloaded) THEN
  936.        physcreen:=ScreenPhysicalBase();
  937.        Alloc(64000,screensave);
  938.        IF ADDRESS(screensave)=NIL THEN RETURN END;
  939.        BConOut(CON,33C);
  940.        BConOut(CON,'f');
  941.        screensave^[2]:=physcreen^;
  942.        SleepProcess(clipid);
  943.        cli1:=NextPid(); (* get the pid for the new cli *)
  944.        cli2:=clipid;
  945.        BConOut(CON,33C);
  946.        BConOut(CON,'e');
  947.        WriteLn;
  948.        WriteString("Enter name of program to run: ");
  949.        WriteLn;
  950.        WriteString("Press RETURN to run CLI ");
  951.        ReadString(command);
  952.        IF command[0]=0c THEN
  953.           command:="cli";
  954.        END;
  955.        Concat("fp ",command,command);
  956.        tail:="";
  957.        envstr:="";
  958.        request.magic:=MAGIC;
  959.        request.req:=TRUE;
  960.        Use;
  961.        swloaded:=TRUE;
  962.     END;
  963. END             HOTKEYER;
  964.  
  965. PROCEDURE       SysGen;
  966. BEGIN
  967.   initprg:="IP CLI.PRG";
  968.   SYSMEM:=7D00H; (* Allocated memory for MX2 use *)
  969.   HotKey:=320000H; (* ALT m *)
  970.   NorMouse:=310000H; (* ALT n *)
  971.   CurMouse:=2E0000H; (* ALT c *)
  972.   RebootKey:=130000H; (* ALT r *)
  973.   memreserve:=7D00H; (* reserved memory for alt HOTKEY program *)
  974.   ReadMX2INF;
  975. END             SysGen;
  976.  
  977. PROCEDURE       ReadMX2INF;
  978. VAR             result                            : INTEGER;
  979.                 S                                 : Stream;
  980.  
  981. PROCEDURE       getparm(VAR p: LONGCARD); (* read in info file *)
  982. VAR     V       :       ADDRESS;
  983. BEGIN
  984.      REadString(S,temp);
  985.      ConvertToAddr(temp,done,V);
  986.      p:=LONGCARD(V);
  987. END             getparm;
  988.  
  989. BEGIN
  990.         OpenStream(S,"MX2.INF",READ,result);
  991.         IF result=0 THEN
  992.            REadString(S,initprg); (* get command *)
  993.            getparm(SYSMEM);
  994.            getparm(HotKey);
  995.            getparm(NorMouse);
  996.            getparm(CurMouse);
  997.            getparm(RebootKey);
  998.            getparm(memreserve);
  999.            CloseStream(S,result);
  1000.         END;
  1001. END     ReadMX2INF;
  1002.  
  1003. (*$P-,$S- *)
  1004. PROCEDURE       initsetup;
  1005. BEGIN
  1006.         currentprocess^.Oport:=con;
  1007.         currentprocess^.Iport:=con;
  1008.         CODE(4e75H);    (* RTS *)
  1009. END             initsetup;
  1010. (*$P+,$S+ *)
  1011.  
  1012. (* ------------------------------------------------------------------- *)
  1013.  
  1014. PROCEDURE       init;
  1015. BEGIN
  1016.   WriteString(TDI);
  1017.   WriteLn;
  1018.   Initsked;
  1019.  
  1020.   MultiEnd;
  1021.   SuperExec(initsetup);
  1022.   Alloc(memreserve+2,cmd); (* use spare address vars to setup memory block *)
  1023.   Alloc(2,dev);
  1024.   reservemem:=Free(cmd);
  1025.   OpenCLI := 0;
  1026.  
  1027.   MultiEnd;
  1028.   spawnpid:=NextPid();
  1029.   command:="BP 1 spawn";
  1030.   request.pid:=currentprocess^.pid; 
  1031.   request.magic:=MAGIC;
  1032.   request.req:=TRUE;
  1033.   MultiEnd;
  1034.   Use; (* execute command *)
  1035.  
  1036.   MultiEnd;
  1037.   clipid:=NextPid();
  1038.   command:=initprg;
  1039.   request.pid:=currentprocess^.pid; 
  1040.   request.magic:=MAGIC;
  1041.   request.req:=TRUE;
  1042.   MultiEnd;
  1043.   Use; (* execute command *)
  1044.   REPEAT
  1045.         SwapProcess; 
  1046.   UNTIL OpenCLI>0;
  1047.  
  1048.   CRON:=TIMER; 
  1049.   CronActive:=TRUE;
  1050.   LoadCRON; (* read CRONFILE and set up crontable variables *)
  1051.   kbdiorec:=IORec(Keyboard);
  1052.   ibuf:=kbdiorec^.ibuf;
  1053.   SuperExec(tbiossetup);
  1054.  
  1055.  LOOP                   (* main kernel loop runs "forever" *)
  1056.      MultiEnd;
  1057.      Kshift:=GetKBShift();
  1058.      IF Kshift=CapsL THEN
  1059.         IF (NOT caps) THEN
  1060.            caps:=TRUE;
  1061.            BConOut(CON,33C);
  1062.            BConOut(CON,'j');
  1063.            BConOut(CON,33C);
  1064.            BConOut(CON,'Y');
  1065.            BConOut(CON,CHAR(32));
  1066.            BConOut(CON,CHAR(111));
  1067.            BConOut(CON,'*');
  1068.            BConOut(CON,33C);
  1069.            BConOut(CON,'k');
  1070.         END;
  1071.      ELSE
  1072.         IF caps THEN
  1073.            caps:=FALSE;
  1074.            BConOut(CON,33C);
  1075.            BConOut(CON,'j');
  1076.            BConOut(CON,33C);
  1077.            BConOut(CON,'Y');
  1078.            BConOut(CON,CHAR(32));
  1079.            BConOut(CON,CHAR(111));
  1080.            BConOut(CON,' ');
  1081.            BConOut(CON,33C);
  1082.            BConOut(CON,'k');
  1083.         END;
  1084.      END;
  1085.  
  1086.         IF swapcli THEN
  1087.            swapcli:=FALSE;
  1088.            HOTKEYER;
  1089.         END;
  1090.      IF currentprocess^.slice>cronslice+6000 THEN (* every 30 SECONDS *)
  1091.         cronslice:=currentprocess^.slice;
  1092.  
  1093.         IF CronActive THEN
  1094.            SuperExec(getvector);
  1095.            CRON 
  1096.         END;
  1097.      END;
  1098.      IF CARDINAL(spintenable)#0 THEN (* check for spints *)
  1099.         FOR i:=0 TO 15 DO (* check all spints and run if set *)
  1100.             IF (i IN spintenable)
  1101.                AND (i IN spintmask) 
  1102.                AND (ADDRESS(spint[i].proc)#NIL) THEN
  1103.                spint[i].proc;
  1104.             END;
  1105.             EXCL(spintenable,i); (* clear flag after complete *)
  1106.         END;
  1107.      END;
  1108.  
  1109.      IF request.req THEN
  1110.         s0:=currentprocess;
  1111.         REPEAT
  1112.               s0:=s0^.next
  1113.         UNTIL s0^.pid=request.pid;
  1114.         i:=CARDINAL(s0^.flags[0]);
  1115.         SetDrvPath(i,s0^.ipenvstr);
  1116.         requestdrv:=i;
  1117.         requestpath:=s0^.ipenvstr;
  1118.         SuperExec(setvector); 
  1119.         Use;
  1120.         request.req:=FALSE;
  1121.      END;
  1122.      MultiBegin;
  1123.      SwapProcess;
  1124.   END;
  1125. END     init;
  1126.  
  1127. (* ------------------------------------------------------------------- *)
  1128.  
  1129. BEGIN
  1130.         SuperExec(savevector);
  1131.         BConOut(CON,33C);
  1132.         BConOut(CON,'E');
  1133.         Hotset:=KBShifts{AlternateKey};
  1134.         CapsL:=KBShifts{CapsLock};
  1135.         IF (ROMDATE # OLDDATE) AND (ROMDATE # NEWDATE) THEN
  1136.            WriteLn;
  1137.            WriteString("SORRY, MX2 MAY NOT RUN WITH YOUR ROM VERSION.");
  1138.            WriteLn;
  1139.         END;
  1140.         SysGen; (* read in system generation file if any *)
  1141.         IF CreateHeap(SYSMEM,TRUE) THEN
  1142.            sysmemsize:=SYSMEM;
  1143.            Oportdevice:=con;
  1144.            Iportdevice:=con;
  1145.            inuse:=FALSE;
  1146.            done:=TRUE;
  1147.            InitProcesses;
  1148.            request.pid:=currentprocess^.pid;
  1149.            MultiEnd;
  1150.            WriteLn;
  1151.            WriteString(TITLE1);
  1152.            WriteString(VERSION);
  1153.            WriteString(TITLE2);
  1154.            WriteLn;
  1155.            proc:=init;
  1156.            sizewsp:=2000;
  1157.            pri:=1;
  1158.            pname:="init";
  1159.            par:=NIL;
  1160.            StartProcess(proc,sizewsp,pri,pname,par);
  1161.         END;
  1162.         OldTerm;
  1163. END MX2.
  1164.  
  1165.