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