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