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