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