|
|
1.1 root 1: /*
2:
1.1.1.3 ! root 3: Copyright 1990,1991,1992 Eric R. Smith.
! 4:
! 5: Copyright 1992,1993 Atari Corporation.
! 6:
! 7: All rights reserved.
1.1 root 8:
9: */
10:
11:
12:
13: #include "mint.h"
14:
15: #include "version.h"
16:
17: #include "cookie.h"
18:
19: #include "xbra.h"
20:
21:
22:
23: /* the kernel's stack size */
24:
25: #define STACK 8*1024L
26:
27:
28:
29: /* if the user is holding down the magic shift key, we ask before booting */
30:
1.1.1.3 ! root 31: #define MAGIC_SHIFT 0x2 /* left shift */
1.1 root 32:
33:
34:
1.1.1.2 root 35: /* magic number to show that we have captured the reset vector */
36:
37: #define RES_MAGIC 0x31415926L
38:
39:
40:
1.1.1.3 ! root 41: static void xbra_install P_((xbra_vec *, long, long ARGS_ON_STACK (*)()));
1.1 root 42:
43: static void init_intr P_((void));
44:
1.1.1.3 ! root 45: static long getmch P_((void));
1.1 root 46:
47: static void do_line P_((char *));
48:
49: static void shutmedown P_((PROC *));
50:
51: void shutdown P_((void));
52:
53: static void doset P_((char *,char *));
54:
1.1.1.2 root 55: static long ARGS_ON_STACK mint_criticerr P_((long));
1.1 root 56:
1.1.1.3 ! root 57: static void ARGS_ON_STACK do_exec_os P_((register long basepage));
! 58:
1.1 root 59:
60:
1.1.1.3 ! root 61: static int gem_active; /* 0 if AES has not started, nonzero otherwise */
1.1 root 62:
63:
64:
1.1.1.3 ! root 65: #define EXEC_OS 0x4feL
! 66:
1.1 root 67: static int check_for_gem P_((void));
68:
69: static void run_auto_prgs P_((void));
70:
71:
72:
73: #ifdef LATTICE
74:
75: /*
76:
77: * AGK: this is witchcraft to completely replace the startup code for
78:
79: * Lattice; doing so saves around 10K on the final binary and pulls only
80:
81: * long division & multitplication from the library (and not even those
82:
83: * if you compile for native '030). The drawback of this code is it
84:
85: * passes no environment or command line whatsoever. Since I always
86:
87: * set MiNT options & environment in 'mint.cnf' this is not a personal
88:
89: * downer, however at some point in the future we ought to have a kernel
90:
91: * parseargs() like call which sets these things up.
92:
93: */
94:
95: BASEPAGE *_base;
96:
97:
98:
99: static void
100:
101: start(BASEPAGE *bp)
102:
103: {
104:
105: long shrinklen;
106:
107:
108:
109: _base = bp;
110:
111: shrinklen = bp->p_tlen + bp->p_dlen + bp->p_blen + STACK + 0x100;
112:
113: if (bp->p_lowtpa + shrinklen <= bp->p_hitpa) {
114:
115: static char null[1] = {""};
116:
117: static char *argv[2] = {null, NULL};
118:
119: extern __builtin_putreg P_((int, long)); /* totally bogus */
120:
121:
122:
123: __builtin_putreg(15, bp->p_lowtpa + shrinklen);
124:
125: Mshrink((void *)bp->p_lowtpa, shrinklen);
126:
1.1.1.2 root 127: main(1, argv);
1.1 root 128:
129: }
130:
131: Pterm(ENSMEM);
132:
133: }
134:
135: #endif
136:
137:
138:
139: #ifdef __GNUC__
140:
141: long _stksize = STACK;
142:
1.1.1.2 root 143: #ifndef PROFILING
144:
1.1 root 145: #include <minimal.h>
146:
147: #endif
148:
1.1.1.2 root 149: #endif
150:
1.1 root 151:
152:
153: int curs_off = 0; /* set if we should turn the cursor off when exiting */
154:
155: int mint_errno = 0; /* error return from open and creat filesystem calls */
156:
157:
158:
159: /*
160:
161: * AGK: for proper co-processors we must consider saving their context.
162:
163: * This variable when non-zero indicates that the BIOS considers a true
164:
165: * coprocessor to be present. We use this variable in the context switch
166:
167: * code to decide whether to attempt an FPU context save.
168:
169: */
170:
171: short fpu = 0;
172:
173:
174:
175: /*
176:
177: * "mch" holds what kind of machine we are running on
178:
179: */
180:
181: long mch = 0;
182:
183:
184:
185: /*
186:
1.1.1.3 ! root 187: * "screen_boundary+1" tells us how screens must be positioned
! 188:
! 189: * (to a 256 byte boundary on STs, a 16 byte boundary on other
! 190:
! 191: * machines; actually, 16 bytes is conservative, 4 is probably
! 192:
! 193: * OK, but it doesn't hurt to be cautious). The +1 is because
! 194:
! 195: * we're using this as a mask in the ROUND() macro in mem.h.
! 196:
! 197: */
! 198:
! 199: int screen_boundary = 255;
! 200:
! 201:
! 202:
! 203: /*
! 204:
1.1 root 205: * variable holds processor type
206:
207: */
208:
209: long mcpu = 0;
210:
211:
212:
213: /*
214:
1.1.1.3 ! root 215: * variable holds language preference
! 216:
! 217: */
! 218:
! 219: int gl_lang = -1;
! 220:
! 221:
! 222:
! 223: /*
! 224:
1.1 root 225: * variable set if someone has already installed an flk cookie
226:
227: */
228:
229: int flk = 0;
230:
231:
232:
1.1.1.3 ! root 233: /*
! 234:
! 235: * variable set to 1 if the _VDO cookie indicates Falcon style video
! 236:
! 237: */
! 238:
! 239: int FalconVideo;
! 240:
! 241:
! 242:
1.1 root 243: /* program to run at startup */
244:
1.1.1.3 ! root 245: #ifdef MULTITOS
! 246:
! 247: static int init_is_gemsys = 1; /* set to 1 if init is gem.sys */
1.1 root 248:
1.1.1.3 ! root 249: #else
! 250:
! 251: static int init_is_gemsys = 0; /* set to 1 if init is gem.sys */
1.1 root 252:
1.1.1.3 ! root 253: #endif
! 254:
! 255: static const char *init_prg = 0;
! 256:
! 257:
! 258:
! 259: /* note: init_tail is also used as a temporary stack for resets in
! 260:
! 261: * intr.spp
! 262:
! 263: */
! 264:
! 265: char init_tail[256];
1.1 root 266:
267:
268:
269: /* initial environment for that program */
270:
1.1.1.3 ! root 271: static char *init_env = 0;
1.1 root 272:
273: /* temporary pointer into that environment for setenv */
274:
1.1.1.3 ! root 275: static char *env_ptr;
1.1 root 276:
277: /* length of the environment */
278:
1.1.1.3 ! root 279: static long env_len;
1.1 root 280:
281:
282:
283: /* GEMDOS pointer to current basepage */
284:
285: BASEPAGE **tosbp;
286:
287:
288:
289: /* pointer to the BIOS keyboard shift variable */
290:
291: extern char *kbshft; /* see bios.c */
292:
293:
294:
295: /* version of TOS we're running over */
296:
297: int tosvers;
298:
299:
300:
301: /* structures for keyboard/MIDI interrupt vectors */
302:
303: KBDVEC *syskey, oldkey;
304:
305: xbra_vec old_ikbd; /* old ikbd vector */
306:
307:
308:
309: /* values the user sees for the DOS, BIOS, and XBIOS vectors */
310:
311: long save_dos, save_bios, save_xbios;
312:
313:
314:
315: /* values for original system vectors */
316:
317: xbra_vec old_dos, old_bios, old_xbios, old_timer, old_vbl, old_5ms;
318:
319: xbra_vec old_criticerr;
320:
1.1.1.3 ! root 321: xbra_vec old_execos;
! 322:
1.1 root 323:
324:
325: long old_term;
326:
327:
328:
329: xbra_vec old_resvec; /* old reset vector */
330:
331: long old_resval; /* old reset validation */
332:
333:
334:
335: #ifdef EXCEPTION_SIGS
336:
337: /* bus error, address error, illegal instruction, etc. vectors */
338:
339: xbra_vec old_bus, old_addr, old_ill, old_divzero, old_trace, old_priv;
340:
1.1.1.2 root 341: xbra_vec old_linef, old_chk, old_trapv, old_mmuconf, old_format, old_cpv;
342:
343: xbra_vec old_uninit, old_spurious, old_fpcp[7], old_pmmuill, old_pmmuacc;
344:
1.1 root 345: #endif
346:
347:
348:
349: /* BIOS disk vectors */
350:
351: xbra_vec old_mediach, old_getbpb, old_rwabs;
352:
353:
354:
355: /* BIOS drive map */
356:
357: long olddrvs;
358:
359:
360:
361: extern Func bios_tab[], dos_tab[];
362:
363:
364:
365: /* kernel info that is passed to loaded file systems and device drivers */
366:
367:
368:
369: struct kerinfo kernelinfo = {
370:
371: MAJ_VERSION, MIN_VERSION,
372:
373: DEFAULT_MODE, 0,
374:
375: bios_tab, dos_tab,
376:
377: changedrv,
378:
1.1.1.2 root 379: Trace, Debug, ALERT, FATAL,
1.1 root 380:
381: kmalloc, kfree, umalloc, ufree,
382:
383: strnicmp, stricmp, strlwr, strupr, ksprintf,
384:
385: ms_time, unixtim, dostim,
386:
387: nap, sleep, wake, wakeselect,
388:
389: denyshare, denylock
390:
391: };
392:
393:
394:
1.1.1.2 root 395: /* table of processor frame sizes in _words_ (not used on MC68000) */
396:
397: unsigned char framesizes[16] = {
398:
399: /*0*/ 0, /* MC68010/M68020/M68030/M68040 short */
400:
401: /*1*/ 0, /* M68020/M68030/M68040 throwaway */
402:
403: /*2*/ 2, /* M68020/M68030/M68040 instruction error */
404:
405: /*3*/ 2, /* M68040 floating point post instruction */
406:
407: /*4*/ 3, /* MC68LC040/MC68EC040 unimplemented floating point instruction */
408:
409: /*5*/ 0, /* NOTUSED */
410:
411: /*6*/ 0, /* NOTUSED */
412:
413: /*7*/ 26, /* M68040 access error */
414:
415: /*8*/ 25, /* MC68010 long */
416:
417: /*9*/ 6, /* M68020/M68030 mid instruction */
418:
419: /*A*/ 12, /* M68020/M68030 short bus cycle */
420:
421: /*B*/ 42, /* M68020/M68030 long bus cycle */
422:
1.1.1.3 ! root 423: /*C*/ 8, /* CPU32 bus error */
1.1.1.2 root 424:
425: /*D*/ 0, /* NOTUSED */
426:
427: /*E*/ 0, /* NOTUSED */
428:
429: /*F*/ 0 /* NOTUSED */
430:
431: };
432:
433:
434:
1.1 root 435: /* TOS and MiNT cookie jars, respectively. See the comments and code
436:
437: * after main() for further details
438:
439: */
440:
441:
442:
443: COOKIE *oldcookie, *newcookie;
444:
445:
446:
447: /*
448:
449: * install a new vector for address "addr", using the XBRA protocol.
450:
451: * must run in supervisor mode!
452:
453: */
454:
455:
456:
457: static void
458:
459: xbra_install(xv, addr, func)
460:
461: xbra_vec *xv;
462:
463: long addr;
464:
1.1.1.3 ! root 465: long ARGS_ON_STACK (*func)();
1.1 root 466:
467: {
468:
469: xv->xbra_magic = XBRA_MAGIC;
470:
471: xv->xbra_id = MINT_MAGIC;
472:
473: xv->jump = JMP_OPCODE;
474:
475: xv->this = func;
476:
477: xv->next = *((struct xbra **)addr);
478:
479: *((short **)addr) = &xv->jump;
480:
481: }
482:
483:
484:
485: /*
486:
487: * MiNT critical error handler; all it does is to jump through
488:
489: * the vector for the current process
490:
491: */
492:
493:
494:
1.1.1.2 root 495: static long ARGS_ON_STACK
1.1 root 496:
497: mint_criticerr(error)
498:
499: long error; /* high word is error, low is drive */
500:
501: {
502:
503: return (*curproc->criticerr)(error);
504:
505: }
506:
507:
508:
1.1.1.3 ! root 509: /*
! 510:
! 511: * if we are MultiTOS, and if we are running from the AUTO folder,
! 512:
! 513: * then we grab the exec_os vector and use that to start GEM; that
! 514:
! 515: * way programs that expect exec_os to act a certain way will still
! 516:
! 517: * work.
! 518:
! 519: * NOTE: we must use Pexec instead of p_exec here, because we will
! 520:
! 521: * be running in a user context (that of process 1, not process 0)
! 522:
! 523: */
! 524:
! 525:
! 526:
! 527: static void ARGS_ON_STACK
! 528:
! 529: do_exec_os(basepage)
! 530:
! 531: register long basepage;
! 532:
! 533: {
! 534:
! 535: register int r;
! 536:
! 537:
! 538:
! 539: if (!init_prg)
! 540:
! 541: init_prg = "\\multitos\\gem.sys";
! 542:
! 543:
! 544:
! 545: /* we have to set a7 to point to lower in our TPA; otherwise we would
! 546:
! 547: * bus error right after the Mshrink call!
! 548:
! 549: */
! 550:
! 551: setstack(basepage+500L);
! 552:
! 553: #ifdef __TURBOC__
! 554:
! 555: Mshrink(0, (void *)basepage, 512L);
! 556:
! 557: #else
! 558:
! 559: Mshrink((void *)basepage, 512L);
! 560:
! 561: #endif
! 562:
! 563: r = Pexec(200, init_prg, init_tail, init_env);
! 564:
! 565: Pterm(r);
! 566:
! 567: }
! 568:
! 569:
! 570:
! 571:
! 572:
1.1 root 573: /* initialize all interrupt vectors and new trap routines
574:
575: * we also get here any TOS variables that we're going to change
576:
577: * (e.g. the pointer to the cookie jar) so that rest_intr can
578:
579: * restore them.
580:
581: */
582:
583:
584:
585: static void
586:
587: init_intr()
588:
589: {
590:
1.1.1.3 ! root 591: extern long ARGS_ON_STACK mint_bios();
! 592:
! 593: extern long ARGS_ON_STACK mint_dos();
! 594:
! 595: extern long ARGS_ON_STACK mint_timer();
! 596:
! 597: extern long ARGS_ON_STACK mint_vbl();
! 598:
! 599: extern long ARGS_ON_STACK mint_5ms();
! 600:
! 601: extern long ARGS_ON_STACK mint_xbios();
! 602:
! 603: extern long ARGS_ON_STACK reset();
! 604:
! 605: extern long ARGS_ON_STACK new_ikbd();
! 606:
! 607: extern long ARGS_ON_STACK new_bus();
! 608:
! 609: extern long ARGS_ON_STACK new_addr();
! 610:
! 611: extern long ARGS_ON_STACK new_ill();
! 612:
! 613: extern long ARGS_ON_STACK new_divzero();
1.1 root 614:
1.1.1.3 ! root 615: extern long ARGS_ON_STACK new_trace();
1.1 root 616:
1.1.1.3 ! root 617: extern long ARGS_ON_STACK new_priv();
1.1 root 618:
1.1.1.3 ! root 619: extern long ARGS_ON_STACK new_linef();
1.1 root 620:
1.1.1.3 ! root 621: extern long ARGS_ON_STACK new_chk();
1.1 root 622:
1.1.1.3 ! root 623: extern long ARGS_ON_STACK new_trapv();
1.1.1.2 root 624:
1.1.1.3 ! root 625: extern long ARGS_ON_STACK new_fpcp();
1.1.1.2 root 626:
1.1.1.3 ! root 627: extern long ARGS_ON_STACK new_mmu();
! 628:
! 629: extern long ARGS_ON_STACK new_format();
! 630:
! 631: extern long ARGS_ON_STACK new_cpv();
! 632:
! 633: extern long ARGS_ON_STACK new_uninit();
! 634:
! 635: extern long ARGS_ON_STACK new_spurious();
! 636:
! 637: extern long ARGS_ON_STACK new_pmmuacc();
1.1 root 638:
639: short savesr;
640:
1.1.1.2 root 641: int i;
642:
1.1 root 643:
644:
645: syskey = (KBDVEC *)Kbdvbase();
646:
647: oldkey = *syskey;
648:
649:
650:
651: xbra_install(&old_ikbd, (long)(&syskey->ikbdsys), new_ikbd);
652:
653:
654:
655: /* gratuitous (void *) for Lattice */
656:
1.1.1.2 root 657: old_term = (long)Setexc(0x102, (void *)-1UL);
1.1 root 658:
659:
660:
661: savesr = spl7();
662:
663:
664:
665: xbra_install(&old_dos, 0x84L, mint_dos);
666:
667: save_dos = (long)old_dos.next;
668:
669:
670:
671: xbra_install(&old_bios, 0xb4L, mint_bios);
672:
673: save_bios = (long)old_bios.next;
674:
675:
676:
677: xbra_install(&old_xbios, 0xb8L, mint_xbios);
678:
679: save_xbios = (long)old_xbios.next;
680:
681:
682:
683: xbra_install(&old_timer, 0x400L, mint_timer);
684:
1.1.1.3 ! root 685: xbra_install(&old_criticerr, 0x404L, mint_criticerr);
1.1 root 686:
687: xbra_install(&old_5ms, 0x114L, mint_5ms);
688:
689: xbra_install(&old_vbl, 4*0x1cL, mint_vbl);
690:
691: xbra_install(&old_resvec, 0x42aL, reset);
692:
693: old_resval = *((long *)0x426L);
694:
1.1.1.2 root 695: *((long *)0x426L) = RES_MAGIC;
696:
1.1 root 697:
698:
699: spl(savesr);
700:
701:
702:
703: #ifdef EXCEPTION_SIGS
704:
705: /* set up signal handlers */
706:
707: xbra_install(&old_bus, 8L, new_bus);
708:
709: xbra_install(&old_addr, 12L, new_addr);
710:
711: xbra_install(&old_ill, 16L, new_ill);
712:
713: xbra_install(&old_divzero, 20L, new_divzero);
714:
715: xbra_install(&old_trace, 36L, new_trace);
716:
1.1.1.2 root 717: xbra_install(&old_priv, 32L, new_priv);
1.1 root 718:
1.1.1.2 root 719: if (tosvers >= 0x106)
1.1 root 720:
1.1.1.2 root 721: xbra_install(&old_linef, 44L, new_linef);
722:
723: xbra_install(&old_chk, 24L, new_chk);
724:
725: xbra_install(&old_trapv, 28L, new_trapv);
726:
727: for (i = (int)(sizeof(old_fpcp) / sizeof(old_fpcp[0])); i--; ) {
728:
729: xbra_install(&old_fpcp[i], 192L + i * 4, new_fpcp);
730:
731: }
1.1 root 732:
1.1.1.2 root 733: xbra_install(&old_mmuconf, 224L, new_mmu);
734:
735: xbra_install(&old_pmmuill, 228L, new_mmu);
736:
737: xbra_install(&old_pmmuacc, 232L, new_pmmuacc);
738:
739: xbra_install(&old_format, 56L, new_format);
740:
741: xbra_install(&old_cpv, 52L, new_cpv);
742:
743: xbra_install(&old_uninit, 60L, new_uninit);
744:
745: xbra_install(&old_spurious, 96L, new_spurious);
1.1 root 746:
747: #endif
748:
749:
750:
751: /* set up disk vectors */
752:
1.1.1.3 ! root 753: xbra_install(&old_mediach, 0x47eL, new_mediach);
1.1 root 754:
1.1.1.3 ! root 755: xbra_install(&old_rwabs, 0x476L, new_rwabs);
1.1 root 756:
1.1.1.3 ! root 757: xbra_install(&old_getbpb, 0x472L, new_getbpb);
1.1 root 758:
759: olddrvs = *((long *)0x4c2L);
760:
761:
762:
763: /* set up cookie jar */
764:
765: oldcookie = *CJAR; /* CJAR defined in cookie.h */
766:
767: install_cookies();
768:
769: }
770:
771:
772:
773: /* restore all interrupt vectors and trap routines */
774:
775: /*
776:
777: * NOTE: This is *not* the approved way of unlinking XBRA trap handlers.
778:
779: * Normally, one should trace through the XBRA chain. However, this is
780:
781: * a very unusual situation: when MiNT exits, any TSRs or programs running
782:
783: * under MiNT will no longer exist, and so any vectors that they have
784:
785: * caught will be pointing to never-never land! So we do something that
786:
787: * would normally be considered rude, and restore the vectors to
788:
789: * what they were before we ran.
790:
791: * BUG: we should restore *all* vectors, not just the ones that MiNT caught.
792:
793: */
794:
795:
796:
797: void
798:
799: restr_intr()
800:
801: {
802:
803: short savesr;
804:
1.1.1.2 root 805: int i;
806:
1.1 root 807:
808:
809: savesr = spl7();
810:
811: *syskey = oldkey; /* restore keyboard vectors */
812:
813: *tosbp = _base; /* restore GEMDOS basepage pointer */
814:
815: *CJAR = oldcookie; /* restore old cookie jar */
816:
817:
818:
819: #ifdef EXCEPTION_SIGS
820:
821: *((long *)0x08L) = (long) old_bus.next;
822:
823: *((long *)0x0cL) = (long) old_addr.next;
824:
825: *((long *)0x10L) = (long) old_ill.next;
826:
827: *((long *)0x14L) = (long) old_divzero.next;
828:
829: *((long *)0x20L) = (long) old_priv.next;
830:
831: *((long *)0x24L) = (long) old_trace.next;
832:
1.1.1.2 root 833: if (old_linef.next)
834:
835: *((long *)0x2cL) = (long) old_linef.next;
836:
837: *((long *)0x18L) = (long) old_chk.next;
838:
839: *((long *)0x1cL) = (long) old_trapv.next;
840:
841: for (i = (int)(sizeof(old_fpcp) / sizeof(old_fpcp[0])); i--; ) {
842:
843: ((long *)0xc0L)[i] = (long) old_fpcp[i].next;
844:
845: }
846:
847: *((long *)0xe0L) = (long) old_mmuconf.next;
848:
849: *((long *)0xe4L) = (long) old_pmmuill.next;
850:
851: *((long *)0xe8L) = (long) old_pmmuacc.next;
852:
853: *((long *)0x38L) = (long) old_format.next;
854:
855: *((long *)0x34L) = (long) old_cpv.next;
856:
857: *((long *)0x3cL) = (long) old_uninit.next;
858:
859: *((long *)0x60L) = (long) old_spurious.next;
860:
1.1 root 861: #endif
862:
863: *((long *)0x84L) = (long) old_dos.next;
864:
865: *((long *)0xb4L) = (long) old_bios.next;
866:
867: *((long *)0xb8L) = (long) old_xbios.next;
868:
869: *((long *)0x408L) = old_term;
870:
871: *((long *)0x404L) = (long) old_criticerr.next;
872:
873: *((long *)0x114L) = (long) old_5ms.next;
874:
875: *((long *)0x400L) = (long) old_timer.next;
876:
877: *((long *)0x70L) = (long) old_vbl.next;
878:
879: *((long *)0x426L) = old_resval;
880:
881: *((long *)0x42aL) = (long) old_resvec.next;
882:
883: *((long *)0x476L) = (long) old_rwabs.next;
884:
885: *((long *)0x47eL) = (long) old_mediach.next;
886:
887: *((long *)0x472L) = (long) old_getbpb.next;
888:
889: *((long *)0x4c2L) = olddrvs;
890:
891:
892:
893: spl(savesr);
894:
895: }
896:
897:
898:
899:
900:
901: /* we save the TOS supervisor stack pointer so that we can reset it when
902:
903: calling Pterm() (not that anyone will ever want to leave MiNT :-)).
904:
905: */
906:
907:
908:
909: long tosssp; /* TOS supervisor stack pointer */
910:
911:
912:
913:
914:
915: /*
916:
917: * enter_kernel: called every time we enter the MiNT kernel via a trap
918:
919: * call. Sets up the GEMDOS and BIOS vectors to point to TOS, and
920:
921: * sets up other vectors and system variables appropriately. Note that
922:
1.1.1.2 root 923: * calling enter_kernel multiple times is probably NOT a good idea,
924:
925: * but the code will allow it.
1.1 root 926:
927: */
928:
929:
930:
931: short in_kernel = 0;
932:
933:
934:
1.1.1.2 root 935: void ARGS_ON_STACK
1.1 root 936:
937: enter_kernel()
938:
939: {
940:
941: short save_sr;
942:
943:
944:
945: if (in_kernel) return;
946:
947:
948:
949: save_sr = spl7();
950:
951: save_dos = *((long *) 0x84L);
952:
953: save_bios = *((long *) 0xb4L);
954:
955: save_xbios = *((long *) 0xb8L);
956:
957: *((long *) 0x84L) = (long)old_dos.next;
958:
959: *((long *) 0xb4L) = (long)old_bios.next;
960:
961: *((long *) 0xb8L) = (long)old_xbios.next;
962:
1.1.1.2 root 963: *tosbp = _base;
1.1 root 964:
965:
966:
967: in_kernel = 1;
968:
969: spl(save_sr);
970:
971: }
972:
973:
974:
975: /*
976:
977: * leave_kernel: called before leaving the kernel, either back to
978:
979: * user mode or when calling a signal handler or the GEMDOS
980:
981: * terminate vector. Note that interrupts should be disabled before
982:
983: * this routine is called.
984:
985: */
986:
987:
988:
1.1.1.2 root 989: void ARGS_ON_STACK
1.1 root 990:
991: leave_kernel()
992:
993: {
994:
995: *((long *) 0x84L) = save_dos;
996:
997: *((long *) 0xb4L) = save_bios;
998:
999: *((long *) 0xb8L) = save_xbios;
1000:
1001: *tosbp = curproc->base;
1002:
1003: in_kernel = 0;
1004:
1005: }
1006:
1007:
1008:
1009: /*
1010:
1011: * shut down processes; this involves waking them all up, and sending
1012:
1013: * them SIGTERM to give them a chance to clean up after themselves
1014:
1015: */
1016:
1017:
1018:
1019: static void
1020:
1021: shutmedown(p)
1022:
1023: PROC *p;
1024:
1025: {
1026:
1.1.1.2 root 1027: UNUSED(p);
1028:
1.1 root 1029: curproc->wait_cond = 0;
1030:
1031: }
1032:
1033:
1034:
1035: void
1036:
1037: shutdown()
1038:
1039: {
1040:
1041: PROC *p;
1042:
1043: int proc_left = 0;
1044:
1045:
1046:
1047: curproc->sighandle[SIGCHLD] = SIG_IGN;
1048:
1049:
1050:
1051: for (p = proclist; p; p = p->gl_next) {
1052:
1053: if (p->pid == 0) continue;
1054:
1055: if (p->wait_q != ZOMBIE_Q && p->wait_q != TSR_Q) {
1056:
1057: if (p->wait_q != READY_Q) {
1058:
1.1.1.3 ! root 1059: short sr = spl7();
! 1060:
1.1 root 1061: rm_q(p->wait_q, p);
1062:
1063: add_q(READY_Q, p);
1064:
1.1.1.3 ! root 1065: spl(sr);
! 1066:
1.1 root 1067: }
1068:
1069: post_sig(p, SIGTERM);
1070:
1071: proc_left++;
1072:
1073: }
1074:
1075: }
1076:
1077:
1078:
1079: if (proc_left) {
1080:
1081: /* sleep a little while, to give the other processes a chance to
1082:
1083: shut down
1084:
1085: */
1086:
1087:
1088:
1089: addtimeout(1000, shutmedown);
1090:
1091: do {
1092:
1.1.1.2 root 1093: sleep(WAIT_Q, (long)shutdown);
1.1 root 1094:
1.1.1.2 root 1095: } while (curproc->wait_cond == (long)shutdown);
1.1 root 1096:
1097: }
1098:
1099: }
1100:
1101:
1102:
1.1.1.2 root 1103: #ifdef __GNUC__
1.1 root 1104:
1.1.1.2 root 1105: int
1.1 root 1106:
1.1.1.2 root 1107: main(argc, argv, envp)
1.1 root 1108:
1.1.1.2 root 1109: int argc;
1.1 root 1110:
1.1.1.2 root 1111: char **argv, **envp;
1.1 root 1112:
1.1.1.2 root 1113: #else
1.1 root 1114:
1115: int
1116:
1.1.1.2 root 1117: main(argc, argv)
1.1 root 1118:
1119: int argc;
1120:
1121: char **argv;
1122:
1.1.1.2 root 1123: #endif
1.1 root 1124:
1125: {
1126:
1127: long *sysbase;
1128:
1129: long r;
1130:
1.1.1.3 ! root 1131: extern int debug_level, debug_logging; /* in debug.c */
! 1132:
! 1133: extern int no_mem_prot; /* memprot.c */
! 1134:
! 1135: extern const char *greet1, *greet2;
! 1136:
! 1137: /* welcome.c */
1.1 root 1138:
1139: static char buf[SPRINTF_MAX];
1140:
1141: static char curpath[128];
1142:
1.1.1.2 root 1143: long yn;
1.1 root 1144:
1145: FILEPTR *f;
1146:
1147:
1148:
1.1.1.3 ! root 1149: /* figure out what kind of machine we're running on */
! 1150:
! 1151: /* biosfs wants to know this; also sets no_mem_prot */
! 1152:
! 1153: /* 920625 kbad put it here so memprot_warning can be intelligent */
! 1154:
! 1155: (void)Supexec(getmch);
! 1156:
! 1157: #ifdef ONLY030
! 1158:
! 1159: if (mcpu != 30) {
! 1160:
! 1161: Cconws("\r\nThis version of MiNT requires a 68030.\r\n");
! 1162:
! 1163: Cconws("Hit any key to continue.\r\n");
! 1164:
! 1165: (void)Cconin();
! 1166:
! 1167: Pterm0();
! 1168:
! 1169: }
! 1170:
! 1171: #endif
! 1172:
! 1173:
! 1174:
! 1175: #ifdef MULTITOS
! 1176:
! 1177: /* Ask the user if s/he wants to boot MultiTOS or regular TOS */
! 1178:
! 1179: if ((Kbshift(-1) & MAGIC_SHIFT) == MAGIC_SHIFT) {
! 1180:
! 1181: yn = boot_kernel_p();
! 1182:
! 1183: Cconws("\r\n");
! 1184:
! 1185: if (!yn)
! 1186:
! 1187: Pterm0();
! 1188:
! 1189: }
! 1190:
! 1191: #else
! 1192:
1.1 root 1193: /* Allow the user to abort the boot if the magic combination of shift keys
1194:
1195: * is held down (see MAGIC_SHIFT above)
1196:
1197: */
1198:
1199: if ((Kbshift(-1) & MAGIC_SHIFT) == MAGIC_SHIFT) {
1200:
1201: Cconws("Boot MiNT? (y/n) ");
1202:
1203: yn = Cconin() & 0x7f;
1204:
1205: if (yn != 'y' && yn != 'Y') {
1206:
1207: Cconws("\r\n\r\nMiNT not booted, at user's request.\r\n");
1208:
1209: Pterm0();
1210:
1211: }
1212:
1213: }
1214:
1.1.1.3 ! root 1215: #endif
! 1216:
1.1 root 1217:
1218:
1219: if (argv[0][0] == 0) { /* maybe started from the desktop */
1220:
1221: curs_off = 1;
1222:
1223: }
1224:
1225:
1226:
1.1.1.3 ! root 1227: yn = 0; /* by default, don't print basepage */
1.1 root 1228:
1.1.1.3 ! root 1229: --argc, ++argv;
1.1 root 1230:
1.1.1.3 ! root 1231: while (argc && **argv == '-') {
1.1 root 1232:
1.1.1.3 ! root 1233: if (argv[0][1] >= '0' && argv[0][1] <= '9') {
1.1 root 1234:
1.1.1.3 ! root 1235: /* a number sets out_device to that device */
1.1 root 1236:
1.1.1.3 ! root 1237: extern int out_device;
1.1 root 1238:
1.1.1.3 ! root 1239: out_device = (int)atol(&argv[0][1]);
1.1 root 1240:
1.1.1.3 ! root 1241: }
1.1 root 1242:
1.1.1.3 ! root 1243: else if (argv[0][1] == 'b') {
1.1 root 1244:
1.1.1.3 ! root 1245: /* print MiNT basepage */
1.1.1.2 root 1246:
1.1.1.3 ! root 1247: yn++;
1.1.1.2 root 1248:
1.1.1.3 ! root 1249: }
1.1.1.2 root 1250:
1.1.1.3 ! root 1251: else if (argv[0][1] == 'd') {
1.1 root 1252:
1.1.1.3 ! root 1253: /* -d increases debugging level */
1.1.1.2 root 1254:
1.1.1.3 ! root 1255: debug_level++;
1.1.1.2 root 1256:
1.1.1.3 ! root 1257: }
1.1.1.2 root 1258:
1.1.1.3 ! root 1259: else if (argv[0][1] == 'm' || argv[0][1] == 'p') {
1.1 root 1260:
1.1.1.3 ! root 1261: int givenotice = (argv[0][2] != 'w');
1.1 root 1262:
1.1.1.3 ! root 1263: /* -m and -p turn off memory protection */
1.1 root 1264:
1.1.1.3 ! root 1265: extern const char *memprot_notice, *memprot_warning;
1.1 root 1266:
1.1.1.3 ! root 1267: if (no_mem_prot) {
! 1268:
! 1269: if (givenotice)
! 1270:
! 1271: Cconws(memprot_notice);
! 1272:
! 1273: }
! 1274:
! 1275: else {
! 1276:
! 1277: no_mem_prot = 1;
! 1278:
! 1279: if (givenotice)
! 1280:
! 1281: Cconws(memprot_warning);
! 1282:
! 1283: }
! 1284:
! 1285: }
! 1286:
! 1287: else if (argv[0][1] == 'l') {
! 1288:
! 1289: /* -l turns on debug logging */
! 1290:
! 1291: debug_logging = 1;
! 1292:
! 1293: }
! 1294:
! 1295: else {
! 1296:
! 1297: Cconws("Unknown argument (ignored): ");
! 1298:
! 1299: Cconws(*argv);
! 1300:
! 1301: Cconws("\r\n");
! 1302:
! 1303: }
! 1304:
! 1305: ++argv, --argc;
! 1306:
! 1307: }
! 1308:
! 1309: if (argc) {
! 1310:
! 1311: Cconws("Unknown argument ignored: ");
! 1312:
! 1313: Cconws(*argv);
! 1314:
! 1315: Cconws(" (and all the rest)\r\n");
! 1316:
! 1317: }
! 1318:
! 1319:
! 1320:
! 1321: /* greetings */
! 1322:
! 1323: Cconws(greet1);
! 1324:
! 1325: ksprintf(buf, VERS_STRING, MAJ_VERSION, MIN_VERSION);
1.1 root 1326:
1327: Cconws(buf);
1328:
1.1.1.3 ! root 1329: Cconws(greet2);
1.1 root 1330:
1.1.1.2 root 1331:
1332:
1333: #ifdef __TURBOC__
1334:
1335: Cconws("PRELIMINARY PureC compiled version!\r\n");
1336:
1337: #endif
1338:
1339:
1340:
1.1.1.3 ! root 1341: if (yn)
1.1 root 1342:
1.1.1.3 ! root 1343: {
1.1 root 1344:
1.1.1.3 ! root 1345: ksprintf(buf,"MiNT@%lx\r\nhit a key...",_base);
1.1 root 1346:
1.1.1.3 ! root 1347: Cconws(buf);
1.1 root 1348:
1.1.1.3 ! root 1349: (void)Crawcin();
1.1 root 1350:
1.1.1.3 ! root 1351: Cconws("\r\033K");
1.1 root 1352:
1.1.1.3 ! root 1353: }
1.1 root 1354:
1355:
1356:
1.1.1.3 ! root 1357: #ifdef notdef
! 1358:
! 1359: /* if less than 1 megabyte free, turn off memory protection */
! 1360:
! 1361: if (Mxalloc(-1L, 3) < ONE_MEG && !no_mem_prot) {
! 1362:
! 1363: extern const char *insuff_mem_warning;
! 1364:
! 1365: Cconws(insuff_mem_warning);
! 1366:
! 1367: no_mem_prot = 1;
! 1368:
! 1369: }
! 1370:
! 1371: #endif
! 1372:
! 1373:
! 1374:
! 1375: /* look for ourselves as \AUTO\MINTNP.PRG; if so, we turn memory
! 1376:
! 1377: * protection off
1.1 root 1378:
1379: */
1380:
1.1.1.3 ! root 1381: if (!no_mem_prot && Fsfirst("\\AUTO\\MINTNP.PRG",0) == 0)
1.1 root 1382:
1.1.1.3 ! root 1383: no_mem_prot = 1;
1.1 root 1384:
1385:
1386:
1.1.1.3 ! root 1387: /* check for GEM -- this must be done from user mode */
1.1 root 1388:
1.1.1.3 ! root 1389: gem_active = check_for_gem();
1.1 root 1390:
1391:
1392:
1.1.1.3 ! root 1393: /*
! 1394:
! 1395: * get the current directory, so that we can switch back to it after
1.1 root 1396:
1.1.1.3 ! root 1397: * the file systems are properly initialized
1.1 root 1398:
1399: */
1400:
1.1.1.3 ! root 1401: /* set the current directory for the current process */
! 1402:
! 1403: (void)Dgetpath(curpath, 0);
! 1404:
! 1405:
! 1406:
! 1407: tosssp = (long)Super(0L); /* enter supervisor mode */
1.1 root 1408:
1409:
1410:
1411: /* get GEMDOS pointer to current basepage */
1412:
1413: /* 0x4f2 points to the base of the OS; here we can find the OS compilation
1414:
1415: date, and (in newer versions of TOS) where the current basepage pointer
1416:
1417: is kept; in older versions of TOS, it's at 0x602c
1418:
1419: */
1420:
1421: sysbase = *((long **)(0x4f2L)); /* gets the RAM OS header */
1422:
1423: sysbase = (long *)sysbase[2]; /* gets the ROM one */
1424:
1425:
1426:
1.1.1.2 root 1427: tosvers = (int)(sysbase[0] & 0x0000ffff);
1.1 root 1428:
1429: if (tosvers == 0x100) {
1430:
1.1.1.2 root 1431: if ((sysbase[7] & 0xfffe0000L) == 0x00080000L)
1.1 root 1432:
1433: tosbp = (BASEPAGE **)0x873cL; /* SPANISH ROM */
1434:
1435: else
1436:
1437: tosbp = (BASEPAGE **) 0x602cL;
1438:
1439: kbshft = (char *) 0x0e1bL;
1440:
1441: } else {
1442:
1443: tosbp = (BASEPAGE **) sysbase[10];
1444:
1445: kbshft = (char *) sysbase[9];
1446:
1447: }
1448:
1449:
1450:
1451: /* The TT TOS release notes are wrong... this is the real way to test
1452:
1453: * for Bconmap ability
1454:
1455: */
1456:
1457: has_bconmap = (Bconmap(0) == 0);
1458:
1459:
1460:
1461: /* initialize memory */
1462:
1463: init_mem();
1464:
1465:
1466:
1467: /* initialize the basic file systems */
1468:
1469: init_filesys();
1470:
1471:
1472:
1473: /* initialize processes */
1474:
1475: init_proc();
1476:
1477:
1478:
1479: /* initialize system calls */
1480:
1481: init_dos();
1482:
1483: init_bios();
1484:
1485: init_xbios();
1486:
1487:
1488:
1489: /* NOTE: there's a call to kmalloc embedded in install_cookies, which
1490:
1491: * is called by init_intr; so make sure this is the last of the
1492:
1493: * init_* things called!
1494:
1495: */
1496:
1497: init_intr();
1498:
1499: enter_kernel();
1500:
1501:
1502:
1.1.1.2 root 1503: if (!gem_active) {
1504:
1505: /* make MiNT invisible in the basepage chain, so that
1506:
1507: * programs that rely on a certain basepage chain
1508:
1509: * structure to determine whether or not they were run
1510:
1511: * from the desktop will have a better chance of working.
1512:
1513: * NOTE THAT THIS IS ONLY DONE TO HELP OUT BRAIN-DAMAGED
1514:
1515: * SOFTWARE: do *not* try counting basepages to figure
1516:
1517: * out whether or not you were run from the desktop!!!
1518:
1519: */
1520:
1521: rootproc->base = _base->p_parent;
1522:
1523: }
1524:
1525:
1526:
1.1 root 1527: /* set up standard file handles for the current process
1528:
1529: * do this here, *after* init_intr has set the Rwabs vector,
1530:
1531: * so that AHDI doesn't get upset by references to drive U:
1532:
1533: */
1534:
1535: f = do_open("U:\\DEV\\CONSOLE", O_RDWR, 0, (XATTR *)0);
1536:
1537: if (!f) {
1538:
1539: FATAL("unable to open CONSOLE device");
1540:
1541: }
1542:
1543: curproc->control = f;
1544:
1545: curproc->handle[0] = f;
1546:
1547: curproc->handle[1] = f;
1548:
1549: f->links = 3;
1550:
1551:
1552:
1553: f = do_open("U:\\DEV\\MODEM1", O_RDWR, 0, (XATTR *)0);
1554:
1555: curproc->aux = f;
1556:
1557: if (has_bconmap) {
1558:
1559: /* If someone has already done a Bconmap call, then
1560:
1561: * MODEM1 may no longer be the default
1562:
1563: */
1564:
1565: bconmap(curbconmap);
1566:
1567: f = curproc->aux; /* bconmap can change curproc->aux */
1568:
1569: }
1570:
1571: if (f) {
1572:
1573: curproc->handle[2] = f;
1574:
1575: f->links++;
1576:
1577: }
1578:
1579: f = do_open("U:\\DEV\\CENTR", O_RDWR, 0, (XATTR *)0);
1580:
1581: if (f) {
1582:
1583: curproc->handle[3] = curproc->prn = f;
1584:
1585: f->links = 2;
1586:
1587: }
1588:
1589: if (f) {
1590:
1591: f = do_open("U:\\DEV\\MIDI", O_RDWR, 0, (XATTR *)0);
1592:
1593: curproc->midiin = curproc->midiout = f;
1594:
1595: f->links = 2;
1596:
1597: }
1598:
1599:
1600:
1601: /* load external file systems */
1602:
1603: if (*curpath) {
1604:
1605: (void)d_setpath(curpath);
1606:
1607: }
1608:
1609:
1610:
1.1.1.2 root 1611: #ifndef PROFILING
1612:
1613: /* load_filesys causes media changes :-( */
1614:
1.1 root 1615: load_filesys();
1616:
1.1.1.2 root 1617: #endif
1618:
1.1 root 1619:
1620:
1621: /* note that load_filesys changed the
1622:
1623: * directory on us!!
1624:
1625: */
1626:
1627: if (*curpath) {
1628:
1629: (void)d_setpath(curpath);
1630:
1631: }
1632:
1633:
1634:
1635: /* load the configuration file */
1636:
1637: load_config();
1638:
1639:
1640:
1.1.1.2 root 1641: *((long *)0x4c2L) |= PSEUDODRVS;
1.1 root 1642:
1643:
1644:
1645: if (init_env == 0)
1646:
1647: init_env = (char *)_base->p_env;
1648:
1649:
1650:
1651: /* empty environment? Set the PATH variable to the root of the current drive */
1652:
1653: if (init_env[0] == 0) {
1654:
1655: static char path_env[] = "PATH=\0C:\0";
1656:
1657: path_env[6] = curproc->curdrv + 'A';
1658:
1659: init_env = path_env;
1660:
1661: }
1662:
1663:
1664:
1.1.1.3 ! root 1665: /* if we are MultiTOS, we're running in the AUTO folder, and our INIT is
! 1666:
! 1667: * called GEM.SYS, take the exec_os() vector
! 1668:
! 1669: */
! 1670:
! 1671: if (!gem_active && init_is_gemsys) {
! 1672:
! 1673: xbra_install(&old_execos, EXEC_OS, (long ARGS_ON_STACK (*)())do_exec_os);
! 1674:
! 1675: }
! 1676:
! 1677:
! 1678:
1.1 root 1679: /* run any programs appearing after us in the AUTO folder */
1680:
1681: run_auto_prgs();
1682:
1683:
1684:
1685: /* run the initial program */
1686:
1.1.1.3 ! root 1687: /* if that program is in fact GEM, we start it via exec_os, otherwise
! 1688:
! 1689: * we do it with Pexec.
! 1690:
! 1691: * the logic is: if the user specified init_prg, and it is not
1.1 root 1692:
1.1.1.3 ! root 1693: * a gem.sys file, then we try to execute it; if it *is* a gem.sys
1.1 root 1694:
1.1.1.3 ! root 1695: * file, we try to execute it if gem is already active, otherwise
1.1 root 1696:
1.1.1.3 ! root 1697: * we jump through the exec_os vector (which we grabbed above) in
1.1 root 1698:
1.1.1.3 ! root 1699: * order to start it. We *never* go through exec_os if we're not in
! 1700:
! 1701: * the AUTO folder.
! 1702:
! 1703: */
1.1 root 1704:
1.1.1.3 ! root 1705: if (init_prg && (!init_is_gemsys || gem_active)) {
1.1 root 1706:
1.1.1.3 ! root 1707: r = p_exec(0, (char *)init_prg, init_tail, init_env);
1.1 root 1708:
1.1.1.3 ! root 1709: } else if (!gem_active) {
1.1 root 1710:
1.1.1.3 ! root 1711: BASEPAGE *bp; int pid;
1.1 root 1712:
1.1.1.3 ! root 1713: bp = (BASEPAGE *)p_exec(7, (char *)7L, (char *)"\0", init_env);
1.1 root 1714:
1.1.1.3 ! root 1715: bp->p_tbase = *((long *) EXEC_OS );
1.1 root 1716:
1.1.1.3 ! root 1717: r = p_exec(106, (char *)"GEM", bp, 0L);
1.1 root 1718:
1.1.1.3 ! root 1719: pid = (int)r;
! 1720:
! 1721: if (pid > 0) {
1.1 root 1722:
1723: do {
1724:
1725: r = p_wait3(0, (long *)0);
1726:
1.1.1.2 root 1727: } while(pid != ((r & 0xffff0000L) >> 16));
1.1 root 1728:
1729: r &= 0x0000ffff;
1730:
1.1.1.3 ! root 1731: }
1.1 root 1732:
1.1.1.3 ! root 1733: } else {
1.1 root 1734:
1735: Cconws("If MiNT is run after GEM starts, you must specify a program\r\n");
1736:
1737: Cconws("to run initially in MINT.CNF, with an INIT= line\r\n");
1738:
1739: r = 0;
1740:
1741: }
1742:
1743:
1744:
1.1.1.3 ! root 1745: if (r < 0 && init_prg) {
1.1 root 1746:
1747: ksprintf(buf, "FATAL: couldn't run %s\r\n", init_prg);
1748:
1749: Cconws(buf);
1750:
1751: }
1752:
1753:
1754:
1755: if (r) {
1756:
1757: ksprintf(buf, "exit code: %ld\r\n", r);
1758:
1759: Cconws(buf);
1760:
1761: }
1762:
1763:
1764:
1.1.1.2 root 1765: rootproc->base = _base;
1766:
1767:
1768:
1.1 root 1769: /* shut down all processes gracefully */
1770:
1771: shutdown();
1772:
1773:
1774:
1775: /* put everything back and exit */
1776:
1.1.1.3 ! root 1777: if (!gem_active && init_is_gemsys) {
! 1778:
! 1779: /* we stole exec_os above */
! 1780:
! 1781: *((long *)EXEC_OS) = (long)old_execos.next;
! 1782:
! 1783: }
! 1784:
1.1 root 1785: restr_intr();
1786:
1787: close_filesys();
1788:
1789:
1790:
1791: (void)Super((void *)tosssp); /* gratuitous (void *) for Lattice */
1792:
1793: Cconws("leaving MiNT\r\n");
1794:
1795:
1796:
1797: if (curs_off)
1798:
1799: Cconws("\033f"); /* disable cursor */
1800:
1801:
1802:
1.1.1.2 root 1803: return 0;
1.1 root 1804:
1805: }
1806:
1807:
1808:
1809:
1810:
1811: /*
1812:
1813: * cookie jar handling routines. The "cookie jar" is an area of memory
1814:
1815: * reserved by TOS for TSR's and utility programs; the idea is that
1816:
1817: * you put a cookie in the jar to notify people of available services.
1818:
1819: * The BIOS uses the cookie jar in TOS 1.6 and higher; for earlier versions
1820:
1821: * of TOS, the jar is always empty (unless someone added a cookie before
1822:
1823: * us; POOLFIX does, for example).
1824:
1825: * MiNT establishes an entirely new cookie jar (with the old cookies copied
1826:
1827: * over) and frees it on exit. That's because TSR's run under MiNT
1828:
1829: * will no longer be accessible after MiNT exits.
1830:
1831: * MiNT also puts a cookie in the jar, with tag field 'MiNT' (of course)
1832:
1833: * and with the major version of MiNT in the high byte of the low word,
1834:
1835: * and the minor version in the low byte.
1836:
1837: */
1838:
1839:
1840:
1841: void
1842:
1843: install_cookies()
1844:
1845: {
1846:
1847: COOKIE *cookie;
1848:
1849: int i, ncookies;
1850:
1.1.1.3 ! root 1851: long ncsize;
! 1852:
1.1 root 1853:
1854:
1855: /* note that init_intr sets oldcookie to the old cookie jar */
1856:
1857:
1858:
1859: ncookies = 0;
1860:
1861: cookie = oldcookie;
1862:
1863: if (cookie) {
1864:
1865: while (cookie->tag.aslong != 0) {
1866:
1867: /* check for true FPU co-processor */
1868:
1869: if (!strncmp(cookie->tag.aschar, "_FPU",4) &&
1870:
1871: (cookie->value >> 16) >= 2)
1872:
1873: fpu = 1;
1874:
1875: /* check for _FLK cookie */
1876:
1877: else if (!strncmp(cookie->tag.aschar, "_FLK",4))
1878:
1879: flk = 1;
1880:
1881: cookie++; ncookies++;
1882:
1883: }
1884:
1885: }
1886:
1887:
1888:
1.1.1.3 ! root 1889: /*
1.1 root 1890:
1.1.1.3 ! root 1891: * We allocate the cookie jar in global memory so anybody can read
1.1 root 1892:
1.1.1.3 ! root 1893: * it or write it. This code allocates at least 8 more cookies, and
! 1894:
! 1895: * then rounds up to a QUANTUM boundary (that's what ROUND does).
! 1896:
! 1897: * Probably, nobody will have to allocate another cookie jar :-)
! 1898:
! 1899: */
! 1900:
! 1901:
! 1902:
! 1903: /* NOTE: obviously, we can do this only if init_intr is called
! 1904:
! 1905: * _after_ memory, processes, etc. have been initialized
! 1906:
! 1907: */
1.1 root 1908:
1.1.1.3 ! root 1909: ncsize = (ncookies+8)*sizeof(COOKIE);
1.1 root 1910:
1.1.1.3 ! root 1911: ncsize = ROUND(ncsize);
! 1912:
! 1913: newcookie = (COOKIE *)alloc_region(core, ncsize, PROT_G);
1.1 root 1914:
1915:
1916:
1917: /* copy the old cookies to the new jar */
1918:
1919:
1920:
1921: for (i = 0; i < ncookies; i++) {
1922:
1923: newcookie[i] = oldcookie[i];
1924:
1925: }
1926:
1927:
1928:
1929: /* install MiNT cookie */
1930:
1931: strncpy(newcookie[i].tag.aschar, "MiNT", 4);
1932:
1933: newcookie[i].value = (MAJ_VERSION << 8) | MIN_VERSION;
1934:
1935: i++;
1936:
1937:
1938:
1939: /* install _FLK cookie to indicate that file locking works */
1940:
1941: if (!flk) {
1942:
1943: strncpy(newcookie[i].tag.aschar, "_FLK", 4);
1944:
1945: newcookie[i].value = 0;
1946:
1947: i++;
1948:
1949: }
1950:
1951:
1952:
1953: /* the last cookie should have a 0 tag, and a value indicating the number
1954:
1955: * of slots, total
1956:
1957: */
1958:
1959:
1960:
1961: newcookie[i].tag.aslong = 0;
1962:
1.1.1.3 ! root 1963: newcookie[i].value = ncsize/sizeof(COOKIE);
1.1 root 1964:
1965:
1966:
1967: *CJAR = newcookie;
1968:
1969:
1970:
1971: }
1972:
1973:
1974:
1975: /*
1976:
1.1.1.3 ! root 1977: * Get the value of the _MCH cookie, if one exists; also set no_mem_prot if
! 1978:
! 1979: * there's a _CPU cookie and you're not on an '030, or if there is none.
1.1 root 1980:
1.1.1.3 ! root 1981: * This must be done in a separate routine because the machine type and CPU
1.1 root 1982:
1.1.1.3 ! root 1983: * type are needed when initializing the system, whereas install_cookies is
1.1 root 1984:
1.1.1.3 ! root 1985: * not called until everything is practically up.
1.1 root 1986:
1987: * In fact, getmch() should be called before *anything* else is
1988:
1989: * initialized, so that if we find a MiNT cookie already in the
1990:
1.1.1.3 ! root 1991: * jar we can bail out early and painlessly.
1.1 root 1992:
1993: */
1994:
1995:
1996:
1.1.1.3 ! root 1997: static long
1.1 root 1998:
1999: getmch()
2000:
2001: {
2002:
2003: COOKIE *jar;
2004:
1.1.1.3 ! root 2005: int foundcpu = 0;
1.1 root 2006:
1.1.1.3 ! root 2007: int i;
! 2008:
! 2009: long *sysbase;
! 2010:
! 2011: extern int no_mem_prot;
! 2012:
! 2013:
! 2014:
! 2015: mcpu = 0;
1.1 root 2016:
2017: jar = *CJAR; /* CJAR defined in cookie.h */
2018:
2019: if (jar) {
2020:
2021: while (jar->tag.aslong != 0) {
2022:
2023: /* check for machine type */
2024:
2025: if (!strncmp(jar->tag.aschar, "_MCH",4)) {
2026:
2027: mch = jar->value;
2028:
1.1.1.3 ! root 2029: } else if (!strncmp(jar->tag.aschar, "_CPU",4)) {
! 2030:
! 2031: /* if not '030 then no memory protection */
1.1 root 2032:
2033: mcpu = jar->value;
2034:
1.1.1.3 ! root 2035: if (jar->value != 30) no_mem_prot = 1;
! 2036:
! 2037: foundcpu = 1;
! 2038:
! 2039: } else if (!strncmp(jar->tag.aschar, "_VDO",4)) {
! 2040:
! 2041: FalconVideo = (jar->value == 0x00000300L);
! 2042:
! 2043: if (jar->value & 0xffff0000L)
! 2044:
! 2045: screen_boundary = 15;
! 2046:
1.1 root 2047: } else if (!strncmp(jar->tag.aschar, "MiNT",4)) {
2048:
2049: Cconws("MiNT is already installed!!\r\n");
2050:
2051: Pterm(2);
2052:
1.1.1.3 ! root 2053: } else if (!strncmp(jar->tag.aschar, "_AKP",4)) {
! 2054:
! 2055: gl_lang = (int) ((jar->value >> 8) & 0x00ff);
! 2056:
1.1 root 2057: }
2058:
2059: jar++;
2060:
2061: }
2062:
2063: }
2064:
1.1.1.3 ! root 2065: if (!foundcpu) no_mem_prot = 1;
! 2066:
! 2067: /*
! 2068:
! 2069: * if no preference found, look at the country code to decide
! 2070:
! 2071: */
! 2072:
! 2073: if (gl_lang < 0) {
! 2074:
! 2075: sysbase = *((long **)(0x4f2L)); /* gets the RAM OS header */
! 2076:
! 2077: sysbase = (long *)sysbase[2]; /* gets the ROM one */
! 2078:
! 2079: i = (int) ((sysbase[7] & 0x7ffe0000L) >> 17L);
! 2080:
! 2081: switch(i) {
! 2082:
! 2083: case 1: /* Germany */
! 2084:
! 2085: case 8: /* Swiss German */
! 2086:
! 2087: gl_lang = 1;
! 2088:
! 2089: break;
! 2090:
! 2091: case 2: /* France */
! 2092:
! 2093: case 7: /* Swiss French */
! 2094:
! 2095: gl_lang = 2;
! 2096:
! 2097: break;
! 2098:
! 2099: case 4: /* Spain */
! 2100:
! 2101: gl_lang = 4;
! 2102:
! 2103: break;
! 2104:
! 2105: case 5: /* Italy */
! 2106:
! 2107: gl_lang = 5;
! 2108:
! 2109: break;
! 2110:
! 2111: default:
! 2112:
! 2113: gl_lang = 0;
! 2114:
! 2115: break;
! 2116:
! 2117: }
! 2118:
! 2119: }
! 2120:
! 2121:
! 2122:
! 2123: return 0L;
! 2124:
1.1 root 2125: }
2126:
2127:
2128:
2129: /*
2130:
2131: * routines for reading the configuration file
2132:
2133: * we allow the following commands in the file:
2134:
2135: * # anything -- comment
2136:
2137: * INIT=file -- specify boot program
2138:
1.1.1.3 ! root 2139: * CON=file -- specify initial file/device for handles -1, 0, 1
1.1 root 2140:
1.1.1.3 ! root 2141: * PRN=file -- specify initial file for handle 2
1.1 root 2142:
1.1.1.3 ! root 2143: * BIOSBUF=[yn] -- if 'n' or 'N' then turn off BIOSBUF feature
! 2144:
! 2145: * DEBUG_LEVEL=n -- set debug level to (decimal number) n
! 2146:
! 2147: * DEBUG_DEVNO=n -- set debug device number to (decimal number) n
! 2148:
! 2149: * HARDSCROLL=n -- set hard-scroll size to n, range 0-99.
! 2150:
! 2151: * SLICES=nnn -- set multitasking granularity
1.1 root 2152:
2153: * echo message -- print a message on the screen
2154:
1.1.1.3 ! root 2155: * alias drive path -- make a fake drive pointing at a path
! 2156:
! 2157: * cd dir -- change directory/drive
! 2158:
! 2159: * exec cmd args -- execute a program
! 2160:
! 2161: * setenv name val -- set up environment
! 2162:
! 2163: * sln file1 file2 -- create a symbolic link
! 2164:
! 2165: * ren file1 file2 -- rename a file
1.1 root 2166:
2167: *
2168:
2169: * BUG: if you use setenv in mint.cnf, *none* of the original environment
2170:
2171: * gets passed to children. This is rarely a problem if mint.prg is
2172:
2173: * in the auto folder.
2174:
2175: */
2176:
2177:
2178:
2179: extern short bconbdev, bconbsiz; /* from bios.c */
2180:
2181:
2182:
2183: static void
2184:
2185: doset(name, val)
2186:
2187: char *name, *val;
2188:
2189: {
2190:
2191: char *t;
2192:
2193:
2194:
1.1.1.3 ! root 2195: if (!strcmp(name, "GEM")) {
! 2196:
! 2197: init_is_gemsys = 1;
! 2198:
! 2199: goto setup_init;
! 2200:
! 2201: }
! 2202:
1.1 root 2203: if (!strcmp(name, "INIT")) {
2204:
1.1.1.3 ! root 2205: init_is_gemsys = 0;
! 2206:
! 2207: setup_init:
! 2208:
1.1 root 2209: t = kmalloc(strlen(val)+1);
2210:
2211: if (!t) return;
2212:
2213: strcpy(t, val);
2214:
2215: init_prg = t;
2216:
2217: while (*t && !isspace(*t)) t++;
2218:
2219: /* get the command tail, too */
2220:
2221: if (*t) {
2222:
2223: *t++ = 0;
2224:
2225: strncpy(init_tail+1, t, 125);
2226:
1.1.1.3 ! root 2227: init_tail[126] = 0;
! 2228:
1.1 root 2229: init_tail[0] = strlen(init_tail+1);
2230:
2231: }
2232:
2233: return;
2234:
2235: }
2236:
2237: if (!strcmp(name, "CON")) {
2238:
2239: FILEPTR *f;
2240:
2241: int i;
2242:
2243:
2244:
2245: f = do_open(val, O_RDWR, 0, (XATTR *)0);
2246:
2247: if (f) {
2248:
2249: for (i = -1; i < 2; i++) {
2250:
2251: do_close(curproc->handle[i]);
2252:
2253: curproc->handle[i] = f;
2254:
2255: f->links++;
2256:
2257: }
2258:
2259: f->links--; /* correct for overdoing it */
2260:
2261: }
2262:
2263: return;
2264:
2265: }
2266:
2267: if (!strcmp(name, "PRN")) {
2268:
2269: FILEPTR *f;
2270:
2271:
2272:
2273: f = do_open(val, O_RDWR|O_CREAT|O_TRUNC, 0, (XATTR *)0);
2274:
2275: if (f) {
2276:
2277: do_close(curproc->handle[2]);
2278:
2279: do_close(curproc->prn);
2280:
2281: curproc->prn = curproc->handle[2] = f;
2282:
2283: f->links = 2;
2284:
2285: }
2286:
2287: return;
2288:
2289: }
2290:
2291: if (!strcmp(name, "BIOSBUF")) {
2292:
2293: if (*val == 'n' || *val == 'N') {
2294:
2295: if (bconbsiz) bflush();
2296:
2297: bconbdev = -1;
2298:
2299: }
2300:
2301: return;
2302:
2303: }
2304:
2305: if (!strcmp(name, "DEBUG_LEVEL")) {
2306:
2307: extern int debug_level;
2308:
1.1.1.2 root 2309: if (*val >= '0' && *val <= '9')
2310:
2311: debug_level = (int)atol(val);
1.1 root 2312:
2313: else ALERT("Bad arg to \"DEBUG_LEVEL\" in cnf file");
2314:
2315: return;
2316:
2317: }
2318:
2319: if (!strcmp(name, "DEBUG_DEVNO")) {
2320:
2321: extern int out_device;
2322:
1.1.1.2 root 2323: if (*val >= '0' && *val <= '9')
2324:
2325: out_device= (int)atol(val);
1.1 root 2326:
2327: else ALERT("Bad arg to \"DEBUG_DEVNO\" in cnf file");
2328:
2329: return;
2330:
2331: }
2332:
2333:
2334:
2335: #ifdef FASTTEXT
2336:
2337: if (!strcmp(name, "HARDSCROLL")) {
2338:
1.1.1.2 root 2339: int i;
1.1 root 2340:
2341: extern int hardscroll;
2342:
2343:
2344:
1.1.1.2 root 2345: if (!strcmp(val, "AUTO")) {
2346:
2347: hardscroll = -1;
2348:
2349: return;
2350:
2351: }
2352:
1.1 root 2353: i = *val++;
2354:
2355: if (i < '0' || i > '9') return;
2356:
2357: hardscroll = i-'0';
2358:
2359: i = *val;
2360:
2361: if (i < '0' || i > '9') return;
2362:
2363: hardscroll = 10*hardscroll + i - '0';
2364:
2365: return;
2366:
2367: }
2368:
2369: #endif
2370:
1.1.1.2 root 2371: if (!strcmp(name, "MAXMEM")) {
2372:
2373: long r;
2374:
2375:
2376:
2377: r = atol(val) * 1024L;
2378:
2379: if (r > 0)
2380:
1.1.1.3 ! root 2381: p_setlimit(2, r);
! 2382:
! 2383: return;
! 2384:
! 2385: }
! 2386:
! 2387: if (!strcmp(name, "SLICES")) {
! 2388:
! 2389: extern short time_slice;
! 2390:
! 2391:
! 2392:
! 2393: time_slice = atol(val);
! 2394:
! 2395: return;
1.1.1.2 root 2396:
2397: }
2398:
1.1.1.3 ! root 2399:
! 2400:
1.1.1.2 root 2401: if (!strcmp(name, "PSEUDODRIVES")) {
2402:
1.1.1.3 ! root 2403: FORCE("PSEUDODRIVES= no longer supported");
1.1.1.2 root 2404:
2405: return;
2406:
2407: }
2408:
1.1.1.3 ! root 2409: FORCE("Unknown variable `%s'", name);
1.1 root 2410:
2411: }
2412:
2413:
2414:
2415: /* Execute a line from the config file */
2416:
2417: static void
2418:
2419: do_line(line)
2420:
2421: char *line;
2422:
2423: {
2424:
2425: char *cmd, *arg1, *arg2;
2426:
2427: char *newenv;
2428:
2429: char *t;
2430:
2431: int i;
2432:
2433:
2434:
2435: while (*line == ' ') line++;
2436:
2437: if (*line == '#') return; /* ignore comments */
2438:
2439: if (!*line) return; /* and also blank lines */
2440:
2441:
2442:
2443: cmd = line;
2444:
2445: /* check for variable assignments (e.g. INIT=, etc.) */
2446:
2447: /*
2448:
2449: * AGK: note we check for spaces whilst scanning so that an environment
2450:
2451: * variable may include an =, this has the unfortunate side effect that
2452:
2453: * the '=' _has_ to be concatenated to the variable name (INIT etc.)
2454:
2455: */
2456:
2457: for (t = cmd; *t && *t != ' '; t++) {
2458:
2459: if (*t == '=') {
2460:
2461: *t++ = 0;
2462:
2463: doset(cmd, t);
2464:
2465: return;
2466:
2467: }
2468:
2469: }
2470:
2471:
2472:
2473: /* OK, assume a regular command; break it up into 'cmd', 'arg1', arg2' */
2474:
2475:
2476:
2477: while (*line && *line != ' ') line++;
2478:
2479: if (*line == ' ') {
2480:
2481: *line++ = 0;
2482:
2483: while (*line == ' ') line++;
2484:
2485: }
2486:
2487:
2488:
2489: if (!strcmp(cmd, "echo")) {
2490:
2491: c_conws(line); c_conws("\r\n");
2492:
2493: return;
2494:
2495: }
2496:
2497: arg1 = line;
2498:
2499: while (*line && *line != ' ') line++;
2500:
2501: if (*line) {
2502:
2503: *line++ = 0;
2504:
2505: while (*line == ' ') line++;
2506:
2507: }
2508:
2509: if (!strcmp(cmd, "cd")) {
2510:
2511: int drv;
2512:
2513: (void)d_setpath(arg1);
2514:
2515: drv = toupper(*arg1) - 'A';
2516:
2517: if (arg1[1] == ':') (void)d_setdrv(drv);
2518:
2519: return;
2520:
2521: }
2522:
2523: if (!strcmp(cmd, "exec")) {
2524:
1.1.1.3 ! root 2525: char cmdline[128];
1.1 root 2526:
2527: int i;
2528:
2529:
2530:
2531: i = strlen(line);
2532:
2533: if (i > 126) i = 126;
2534:
2535: cmdline[0] = i;
2536:
2537: strncpy(cmdline+1, line, i);
2538:
2539: cmdline[i+1] = 0;
2540:
1.1.1.2 root 2541: i = (int)p_exec(0, arg1, cmdline, init_env);
1.1 root 2542:
2543: if (i == -33) {
2544:
1.1.1.3 ! root 2545: FORCE("%s: file not found", arg1);
1.1 root 2546:
2547: } else if (i < 0) {
2548:
1.1.1.3 ! root 2549: FORCE("%s: error while attempting to execute", arg1);
1.1 root 2550:
2551: }
2552:
2553: return;
2554:
2555: }
2556:
2557: if (!strcmp(cmd, "setenv")) {
2558:
2559: if (strlen(arg1) + strlen(line) + 4 + (env_ptr - init_env) >
2560:
2561: env_len) {
2562:
1.1.1.2 root 2563: long j;
1.1 root 2564:
2565:
2566:
1.1.1.2 root 2567: env_len += 1024;
1.1 root 2568:
1.1.1.3 ! root 2569: newenv = (char *)m_xalloc(env_len, 0x13);
1.1 root 2570:
1.1.1.2 root 2571: if (init_env) {
2572:
2573: t = init_env;
2574:
2575: j = env_ptr - init_env;
2576:
2577: env_ptr = newenv;
2578:
2579: for (i = 0; i < j; i++)
2580:
2581: *env_ptr++ = *t++;
1.1 root 2582:
1.1.1.2 root 2583: if (init_env)
1.1 root 2584:
1.1.1.3 ! root 2585: m_free((virtaddr)init_env);
1.1.1.2 root 2586:
2587: } else {
2588:
2589: env_ptr = newenv;
2590:
2591: }
1.1 root 2592:
2593: init_env = newenv;
2594:
2595: }
2596:
2597: while (*arg1) {
2598:
1.1.1.2 root 2599: *env_ptr++ = *arg1++;
1.1 root 2600:
2601: }
2602:
2603: *env_ptr++ = '=';
2604:
2605: while (*line) {
2606:
1.1.1.2 root 2607: *env_ptr++ = *line++;
1.1 root 2608:
2609: }
2610:
2611: *env_ptr++ = 0;
2612:
2613: *env_ptr = 0;
2614:
2615: return;
2616:
2617: }
2618:
2619:
2620:
2621: arg2 = line;
2622:
2623: while (*line && *line != ' ') line++;
2624:
2625: if (*line) {
2626:
1.1.1.2 root 2627: *line = 0;
2628:
2629: }
2630:
2631: if (!strcmp(cmd, "alias")) {
2632:
2633: int drv;
2634:
2635: long r;
2636:
2637: fcookie root_dir;
2638:
2639: extern int aliasdrv[];
2640:
2641:
2642:
2643: drv = toupper(*arg1) - 'A';
2644:
2645: if (drv < 0 || drv >= NUM_DRIVES) {
2646:
2647: ALERT("Bad drive (%c:) in alias", drv+'A');
2648:
2649: return;
2650:
2651: }
2652:
2653: r = path2cookie(arg2, NULL, &root_dir);
2654:
2655: if (r) {
2656:
2657: ALERT("alias: TOS error %ld while looking for %s",
2658:
2659: r, arg2);
2660:
2661: return;
2662:
2663: }
2664:
2665: aliasdrv[drv] = root_dir.dev + 1;
2666:
2667: *((long *)0x4c2L) |= (1L << drv);
2668:
1.1.1.3 ! root 2669: release_cookie(&curproc->curdir[drv]);
! 2670:
! 2671: dup_cookie(&curproc->curdir[drv], &root_dir);
! 2672:
! 2673: release_cookie(&curproc->root[drv]);
! 2674:
! 2675: curproc->root[drv] = root_dir;
1.1.1.2 root 2676:
2677: return;
1.1 root 2678:
2679: }
2680:
2681: if (!strcmp(cmd, "sln")) {
2682:
2683: (void)f_symlink(arg1, arg2);
2684:
2685: return;
2686:
2687: }
2688:
2689: if (!strcmp(cmd, "ren")) {
2690:
2691: (void)f_rename(0, arg1, arg2);
2692:
2693: return;
2694:
2695: }
2696:
1.1.1.3 ! root 2697: FORCE("syntax error in mint.cnf near: %s", cmd);
1.1 root 2698:
2699: }
2700:
2701:
2702:
2703: #define BUF 512
2704:
2705: #define LINE 256
2706:
2707:
2708:
2709: void
2710:
2711: load_config()
2712:
2713: {
2714:
2715: int fd;
2716:
2717: long r;
2718:
2719: char buf[BUF+1], c;
2720:
2721: char line[LINE+1];
2722:
2723: char *from;
2724:
2725: int count = 0;
2726:
2727:
2728:
1.1.1.2 root 2729: fd = (int) f_open("mint.cnf", 0);
1.1 root 2730:
2731: if (fd < 0)
2732:
1.1.1.2 root 2733: fd = (int) f_open("\\mint\\mint.cnf", 0);
1.1 root 2734:
1.1.1.3 ! root 2735: if (fd < 0)
! 2736:
! 2737: fd = (int) f_open("\\multitos\\mint.cnf", 0);
! 2738:
1.1 root 2739: if (fd < 0) return;
2740:
2741: buf[BUF] = 0;
2742:
2743: from = &buf[BUF];
2744:
2745: line[LINE] = 0;
2746:
2747:
2748:
2749: for(;;) {
2750:
2751: c = *from++;
2752:
2753: if (!c) {
2754:
2755: r = f_read(fd, (long)BUF, buf);
2756:
2757: if (r <= 0) break;
2758:
2759: buf[r] = 0;
2760:
2761: from = buf;
2762:
2763: } else if (c == '\r') {
2764:
2765: continue;
2766:
2767: } else if (c == '\n') {
2768:
2769: line[count] = 0;
2770:
2771: do_line(line);
2772:
2773: count = 0;
2774:
2775: } else {
2776:
2777: if (count < LINE) {
2778:
2779: line[count++] = c;
2780:
2781: }
2782:
2783: }
2784:
2785: }
2786:
1.1.1.3 ! root 2787: if (count) {
! 2788:
! 2789: line[count] = 0;
! 2790:
! 2791: do_line(line);
! 2792:
! 2793: }
! 2794:
1.1 root 2795: f_close(fd);
2796:
2797: }
2798:
2799:
2800:
2801: /*
2802:
2803: * run programs in the AUTO folder that appear after MINT.PRG
2804:
2805: * some things to watch out for:
2806:
2807: * (1) make sure GEM isn't active
2808:
2809: * (2) make sure there really is a MINT.PRG in the auto folder
2810:
2811: */
2812:
2813:
2814:
2815: /*
2816:
2817: * some global variables used to see if GEM is active
2818:
2819: */
2820:
2821: static short aes_intout[64];
2822:
2823: static short aes_dummy[64];
2824:
2825: static short aes_globl[15];
2826:
2827: static short aes_cntrl[6] = { 10, 0, 1, 0, 0 };
2828:
2829:
2830:
2831: short *aes_pb[6] = { aes_cntrl, aes_globl, aes_dummy, aes_intout,
2832:
2833: aes_dummy, aes_dummy };
2834:
2835:
2836:
2837: /* check for whether GEM is active; remember, this *must* be done in
2838:
2839: * user mode
2840:
2841: */
2842:
2843:
2844:
2845: static int
2846:
2847: check_for_gem()
2848:
2849: {
2850:
2851: call_aes(aes_pb); /* does an appl_init */
2852:
2853: return aes_globl[0];
2854:
2855: }
2856:
2857:
2858:
2859: static void
2860:
2861: run_auto_prgs()
2862:
2863: {
2864:
2865: DTABUF *dta;
2866:
2867: long r;
2868:
2869: static char pathspec[32] = "\\AUTO\\";
2870:
2871: short runthem = 0; /* set to 1 after we find MINT.PRG */
2872:
2873:
2874:
2875: /* if the AES is running, don't check AUTO */
2876:
2877:
2878:
2879: if (gem_active) {
2880:
2881: return;
2882:
2883: }
2884:
2885:
2886:
2887: /* OK, now let's run through \\AUTO looking for
2888:
2889: * programs...
2890:
2891: */
2892:
2893: dta = (DTABUF *)f_getdta();
2894:
2895: r = f_sfirst("\\AUTO\\*.PRG", 0);
2896:
2897: while (r >= 0) {
2898:
1.1.1.3 ! root 2899: if (!strcmp(dta->dta_name, "MINT.PRG") ||
! 2900:
! 2901: !strcmp(dta->dta_name, "MINTNP.PRG"))
1.1 root 2902:
2903: runthem = 1;
2904:
2905: else if (runthem) {
2906:
2907: strcpy(pathspec+6, dta->dta_name);
2908:
2909: (void)p_exec(0, pathspec, (char *)"", init_env);
2910:
2911: }
2912:
2913: r = f_snext();
2914:
2915: }
2916:
2917: }
2918:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.