Annotation of lucent/sys/src/9/pc/main.c, revision 1.1

1.1     ! root        1: #include       "u.h"
        !             2: #include       "../port/lib.h"
        !             3: #include       "mem.h"
        !             4: #include       "dat.h"
        !             5: #include       "fns.h"
        !             6: #include       "io.h"
        !             7: #include       "ureg.h"
        !             8: #include       "init.h"
        !             9: #include       <ctype.h>
        !            10: 
        !            11: 
        !            12: uchar *sp;     /* stack pointer for /boot */
        !            13: 
        !            14: extern PCArch nsx20, generic, ncr3170;
        !            15: 
        !            16: PCArch *arch;
        !            17: PCArch *knownarch[] =
        !            18: {
        !            19:        &nsx20,
        !            20:        &ncr3170,
        !            21:        &generic,
        !            22: };
        !            23: 
        !            24: /* where b.com leaves configuration info */
        !            25: #define BOOTARGS       ((char*)(KZERO|1024))
        !            26: #define        BOOTARGSLEN     1024
        !            27: #define        MAXCONF         32
        !            28: 
        !            29: char bootdisk[NAMELEN];
        !            30: char *confname[MAXCONF];
        !            31: char *confval[MAXCONF];
        !            32: int nconf;
        !            33: 
        !            34: /* memory map */
        !            35: #define MAXMEG 64
        !            36: char mmap[MAXMEG+2];
        !            37: 
        !            38: void
        !            39: main(void)
        !            40: {
        !            41:        ident();
        !            42:        i8042a20();             /* enable address lines 20 and up */
        !            43:        machinit();
        !            44:        active.exiting = 0;
        !            45:        active.machs = 1;
        !            46:        confinit();
        !            47:        xinit();
        !            48:        dmainit();
        !            49:        screeninit();
        !            50:        printinit();
        !            51:        mmuinit();
        !            52:        pageinit();
        !            53:        trapinit();
        !            54:        mathinit();
        !            55:        clockinit();
        !            56:        printcpufreq();
        !            57:        faultinit();
        !            58:        kbdinit();
        !            59:        procinit0();
        !            60:        initseg();
        !            61:        streaminit();
        !            62:        chandevreset();
        !            63:        swapinit();
        !            64:        userinit();
        !            65:        schedinit();
        !            66: }
        !            67: 
        !            68: /*
        !            69:  *  This tries to capture architecture dependencies since things
        !            70:  *  like power management/reseting/mouse are outside the hardware
        !            71:  *  model.
        !            72:  */
        !            73: void
        !            74: ident(void)
        !            75: {
        !            76:        char *id = (char*)(ROMBIOS + 0xFF40);
        !            77:        PCArch **p;
        !            78: 
        !            79:        for(p = knownarch; *p != &generic; p++)
        !            80:                if(strncmp((*p)->id, id, strlen((*p)->id)) == 0)
        !            81:                        break;
        !            82:        arch = *p;
        !            83: }
        !            84: 
        !            85: void
        !            86: machinit(void)
        !            87: {
        !            88:        int n;
        !            89: 
        !            90:        n = m->machno;
        !            91:        memset(m, 0, sizeof(Mach));
        !            92:        m->machno = n;
        !            93:        m->mmask = 1<<m->machno;
        !            94: }
        !            95: 
        !            96: ulong garbage;
        !            97: 
        !            98: void
        !            99: init0(void)
        !           100: {
        !           101:        int i;
        !           102:        char tstr[32];
        !           103: 
        !           104:        u->nerrlab = 0;
        !           105:        m->proc = u->p;
        !           106:        u->p->state = Running;
        !           107:        u->p->mach = m;
        !           108: 
        !           109:        spllo();
        !           110: 
        !           111:        /*
        !           112:         * These are o.k. because rootinit is null.
        !           113:         * Then early kproc's will have a root and dot.
        !           114:         */
        !           115:        u->slash = (*devtab[0].attach)(0);
        !           116:        u->dot = clone(u->slash, 0);
        !           117: 
        !           118:        kproc("alarm", alarmkproc, 0);
        !           119:        chandevinit();
        !           120: 
        !           121:        if(!waserror()){
        !           122:                strcpy(tstr, arch->id);
        !           123:                strcat(tstr, " %s");
        !           124:                ksetterm(tstr);
        !           125:                ksetenv("cputype", "386");
        !           126:                for(i = 0; i < nconf; i++)
        !           127:                        if(confname[i])
        !           128:                                ksetenv(confname[i], confval[i]);
        !           129:                poperror();
        !           130:        }
        !           131:        touser(sp);
        !           132: }
        !           133: 
        !           134: void
        !           135: userinit(void)
        !           136: {
        !           137:        Proc *p;
        !           138:        Segment *s;
        !           139:        User *up;
        !           140:        KMap *k;
        !           141:        Page *pg;
        !           142: 
        !           143:        p = newproc();
        !           144:        p->pgrp = newpgrp();
        !           145:        p->egrp = smalloc(sizeof(Egrp));
        !           146:        p->egrp->ref = 1;
        !           147:        p->fgrp = smalloc(sizeof(Fgrp));
        !           148:        p->fgrp->ref = 1;
        !           149:        p->procmode = 0640;
        !           150: 
        !           151:        strcpy(p->text, "*init*");
        !           152:        strcpy(p->user, eve);
        !           153:        p->fpstate = FPinit;
        !           154:        fpoff();
        !           155: 
        !           156:        /*
        !           157:         * Kernel Stack
        !           158:         *
        !           159:         * N.B. The -12 for the stack pointer is important.
        !           160:         *      4 bytes for gotolabel's return PC
        !           161:         */
        !           162:        p->sched.pc = (ulong)init0;
        !           163:        p->sched.sp = USERADDR + BY2PG - 4;
        !           164:        p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF));
        !           165: 
        !           166:        /*
        !           167:         * User
        !           168:         */
        !           169:        k = kmap(p->upage);
        !           170:        up = (User*)VA(k);
        !           171:        up->p = p;
        !           172:        kunmap(k);
        !           173: 
        !           174:        /*
        !           175:         * User Stack
        !           176:         */
        !           177:        s = newseg(SG_STACK, USTKTOP-BY2PG, 1);
        !           178:        p->seg[SSEG] = s;
        !           179:        pg = newpage(1, 0, USTKTOP-BY2PG);
        !           180:        segpage(s, pg);
        !           181:        k = kmap(pg);
        !           182:        bootargs(VA(k));
        !           183:        kunmap(k);
        !           184: 
        !           185:        /*
        !           186:         * Text
        !           187:         */
        !           188:        s = newseg(SG_TEXT, UTZERO, 1);
        !           189:        p->seg[TSEG] = s;
        !           190:        segpage(s, newpage(1, 0, UTZERO));
        !           191:        k = kmap(s->map[0]->pages[0]);
        !           192:        memmove((ulong*)VA(k), initcode, sizeof initcode);
        !           193:        kunmap(k);
        !           194: 
        !           195:        ready(p);
        !           196: }
        !           197: 
        !           198: uchar *
        !           199: pusharg(char *p)
        !           200: {
        !           201:        int n;
        !           202: 
        !           203:        n = strlen(p)+1;
        !           204:        sp -= n;
        !           205:        memmove(sp, p, n);
        !           206:        return sp;
        !           207: }
        !           208: 
        !           209: void
        !           210: bootargs(ulong base)
        !           211: {
        !           212:        int i, ac;
        !           213:        uchar *av[32];
        !           214:        uchar **lsp;
        !           215:        char *cp = BOOTLINE;
        !           216:        char buf[64];
        !           217: 
        !           218:        sp = (uchar*)base + BY2PG - MAXSYSARG*BY2WD;
        !           219: 
        !           220:        ac = 0;
        !           221:        av[ac++] = pusharg("/386/9pc");
        !           222:        cp[64] = 0;
        !           223:        buf[0] = 0;
        !           224: 
        !           225:        /*
        !           226:         *  decode the b.com bootline and convert to
        !           227:         *  a disk device name to pass to the boot
        !           228:         */
        !           229:        if(strncmp(cp, "fd!", 3) == 0){
        !           230:                sprint(buf, "local!#f/fd%ddisk", atoi(cp+3));
        !           231:                av[ac++] = pusharg(buf);
        !           232:        } else if(strncmp(cp, "h!", 2) == 0){
        !           233:                sprint(buf, "local!#H/hd%dfs", atoi(cp+2));
        !           234:                av[ac++] = pusharg(buf);
        !           235:        } else if(strncmp(cp, "hd!", 3) == 0){
        !           236:                sprint(buf, "local!#H/hd%ddisk", atoi(cp+3));
        !           237:                av[ac++] = pusharg(buf);
        !           238:        } else if(strncmp(cp, "s!", 2) == 0){
        !           239:                sprint(buf, "local!#w%d/sd%dfs", atoi(cp+2), atoi(cp+2));
        !           240:                av[ac++] = pusharg(buf);
        !           241:        } else if(strncmp(cp, "sd!", 3) == 0){
        !           242:                sprint(buf, "local!#w%d/sd%ddisk", atoi(cp+3), atoi(cp+3));
        !           243:                av[ac++] = pusharg(buf);
        !           244:        } else if(getconf("bootdisk") == 0){
        !           245:                if(conf.nhard){
        !           246:                        sprint(buf, "local!#H/hd0disk");
        !           247:                        av[ac++] = pusharg(buf);
        !           248:                } else{
        !           249:                        sprint(buf, "local!#w/sd0disk");
        !           250:                        av[ac++] = pusharg(buf);
        !           251:                }
        !           252:        }
        !           253:        if(buf[0]){
        !           254:                cp = strchr(buf, '!');
        !           255:                if(cp){
        !           256:                        strcpy(bootdisk, cp+1);
        !           257:                        addconf("bootdisk", bootdisk);
        !           258:                }
        !           259:        }
        !           260: 
        !           261:        /* 4 byte word align stack */
        !           262:        sp = (uchar*)((ulong)sp & ~3);
        !           263: 
        !           264:        /* build argc, argv on stack */
        !           265:        sp -= (ac+1)*sizeof(sp);
        !           266:        lsp = (uchar**)sp;
        !           267:        for(i = 0; i < ac; i++)
        !           268:                *lsp++ = av[i] + ((USTKTOP - BY2PG) - base);
        !           269:        *lsp = 0;
        !           270:        sp += (USTKTOP - BY2PG) - base - sizeof(ulong);
        !           271: }
        !           272: 
        !           273: Conf   conf;
        !           274: 
        !           275: void
        !           276: addconf(char *name, char *val)
        !           277: {
        !           278:        if(nconf >= MAXCONF)
        !           279:                return;
        !           280:        confname[nconf] = name;
        !           281:        confval[nconf] = val;
        !           282:        nconf++;
        !           283: }
        !           284: 
        !           285: char*
        !           286: getconf(char *name)
        !           287: {
        !           288:        int i;
        !           289: 
        !           290:        for(i = 0; i < nconf; i++)
        !           291:                if(strcmp(confname[i], name) == 0)
        !           292:                        return confval[i];
        !           293:        return 0;
        !           294: }
        !           295: 
        !           296: /*
        !           297:  *  look for unused address space in 0xC8000 to 1 meg
        !           298:  */
        !           299: void
        !           300: romscan(void)
        !           301: {
        !           302:        uchar *p;
        !           303: 
        !           304:        p = (uchar*)(KZERO+0xC8000);
        !           305:        while(p < (uchar*)(KZERO+0xE0000)){
        !           306:                p[0] = 0x55;
        !           307:                p[1] = 0xAA;
        !           308:                p[2] = 4;
        !           309:                if(p[0] != 0x55 || p[1] != 0xAA){
        !           310:                        putisa(PADDR(p), 2048);
        !           311:                        p += 2048;
        !           312:                        continue;
        !           313:                }
        !           314:                p += p[2]*512;
        !           315:        }
        !           316: 
        !           317:        p = (uchar*)(KZERO+0xE0000);
        !           318:        if(p[0] != 0x55 || p[1] != 0xAA)
        !           319:                putisa(PADDR(p), 64*1024);
        !           320: }
        !           321: 
        !           322: 
        !           323: void
        !           324: confinit(void)
        !           325: {
        !           326:        long x, i, j, n;
        !           327:        int pcnt;
        !           328:        ulong ktop;
        !           329:        char *cp;
        !           330:        char *line[MAXCONF];
        !           331: 
        !           332:        pcnt = 0;
        !           333: 
        !           334:        /*
        !           335:         *  parse configuration args from dos file p9rc
        !           336:         */
        !           337:        cp = BOOTARGS;  /* where b.com leaves plan9.ini */
        !           338:        cp[BOOTARGSLEN-1] = 0;
        !           339:        n = getfields(cp, line, MAXCONF, "\n");
        !           340:        for(j = 0; j < n; j++){
        !           341:                cp = strchr(line[j], '\r');
        !           342:                if(cp)
        !           343:                        *cp = 0;
        !           344:                cp = strchr(line[j], '=');
        !           345:                if(cp == 0)
        !           346:                        continue;
        !           347:                *cp++ = 0;
        !           348:                if(cp - line[j] >= NAMELEN+1)
        !           349:                        *(line[j]+NAMELEN-1) = 0;
        !           350:                confname[nconf] = line[j];
        !           351:                confval[nconf] = cp;
        !           352:                if(strcmp(confname[nconf], "kernelpercent") == 0)
        !           353:                        pcnt = 100 - atoi(confval[nconf]);
        !           354:                nconf++;
        !           355:        }
        !           356:        /*
        !           357:         *  size memory above 1 meg. Kernel sits at 1 meg.  We
        !           358:         *  only recognize MB size chunks.
        !           359:         */
        !           360:        memset(mmap, ' ', sizeof(mmap));
        !           361:        x = 0x12345678;
        !           362:        for(i = 1; i <= MAXMEG; i++){
        !           363:                /*
        !           364:                 *  write the first & last word in a megabyte of memory
        !           365:                 */
        !           366:                *mapaddr(KZERO|(i*MB)) = x;
        !           367:                *mapaddr(KZERO|((i+1)*MB-BY2WD)) = x;
        !           368: 
        !           369:                /*
        !           370:                 *  write the first and last word in all previous megs to
        !           371:                 *  handle address wrap around
        !           372:                 */
        !           373:                for(j = 1; j < i; j++){
        !           374:                        *mapaddr(KZERO|(j*MB)) = ~x;
        !           375:                        *mapaddr(KZERO|((j+1)*MB-BY2WD)) = ~x;
        !           376:                }
        !           377: 
        !           378:                /*
        !           379:                 *  check for correct value
        !           380:                 */
        !           381:                if(*mapaddr(KZERO|(i*MB)) == x && *mapaddr(KZERO|((i+1)*MB-BY2WD)) == x){
        !           382:                        mmap[i] = 'x';
        !           383:                        /*
        !           384:                         *  zero memory to set ECC but skip over the kernel
        !           385:                         */
        !           386:                        if(i != 1)
        !           387:                                for(j = 0; j < MB/BY2PG; j += BY2PG)
        !           388:                                        memset(mapaddr(KZERO|(i*MB+j)), 0, BY2PG);
        !           389:                }
        !           390:                x += 0x3141526;
        !           391:        }
        !           392:        /*
        !           393:         *  bank0 usually goes from the end of kernel bss to the end of memory
        !           394:         */
        !           395:        ktop = PGROUND((ulong)end);
        !           396:        ktop = PADDR(ktop);
        !           397:        conf.base0 = ktop;
        !           398:        for(i = 1; mmap[i] == 'x'; i++)
        !           399:                ;
        !           400:        conf.npage0 = (i*MB - ktop)/BY2PG;
        !           401:        conf.topofmem = i*MB;
        !           402: 
        !           403:        /*
        !           404:         *  bank1 usually goes from the end of BOOTARGS to 640k
        !           405:         */
        !           406:        conf.base1 = (ulong)(BOOTARGS+BOOTARGSLEN);
        !           407:        conf.base1 = PGROUND(conf.base1);
        !           408:        conf.base1 = PADDR(conf.base1);
        !           409:        conf.npage1 = (640*1024-conf.base1)/BY2PG;
        !           410: 
        !           411:        /*
        !           412:         *  if there is a hole in memory (due to a shadow BIOS) make the
        !           413:         *  memory after the hole be bank 1. The memory from 0 to 640k
        !           414:         *  is lost.
        !           415:         */
        !           416:        for(; i <= MAXMEG; i++)
        !           417:                if(mmap[i] == 'x'){
        !           418:                        conf.base1 = i*MB;
        !           419:                        for(j = i+1; mmap[j] == 'x'; j++)
        !           420:                                ;
        !           421:                        conf.npage1 = (j - i)*MB/BY2PG;
        !           422:                        conf.topofmem = j*MB;
        !           423:                        break;
        !           424:                }
        !           425: 
        !           426:        /*
        !           427:         *  add address space holes holes under 16 meg to available
        !           428:         *  isa space.
        !           429:         */
        !           430:        romscan();
        !           431:        if(conf.topofmem < 16*MB)
        !           432:                putisa(conf.topofmem, 16*MB - conf.topofmem);
        !           433: 
        !           434:        conf.npage = conf.npage0 + conf.npage1;
        !           435:        conf.ldepth = 0;
        !           436:        if(pcnt < 10)
        !           437:                pcnt = 70;
        !           438:        conf.upages = (conf.npage*pcnt)/100;
        !           439: 
        !           440:        conf.nproc = 30 + ((conf.npage*BY2PG)/MB)*8;
        !           441:        conf.monitor = 1;
        !           442:        conf.nswap = conf.nproc*80;
        !           443:        conf.nimage = 50;
        !           444:        switch(x86()){
        !           445:        case 3:
        !           446:                conf.copymode = 1;      /* copy on reference */
        !           447:                break;
        !           448:        default:
        !           449:                conf.copymode = 0;      /* copy on write */
        !           450:                break;
        !           451:        }
        !           452:        conf.nfloppy = 2;
        !           453:        conf.nhard = 2;
        !           454:        conf.nmach = 1;
        !           455: }
        !           456: 
        !           457: char *mathmsg[] =
        !           458: {
        !           459:        "invalid",
        !           460:        "denormalized",
        !           461:        "div-by-zero",
        !           462:        "overflow",
        !           463:        "underflow",
        !           464:        "precision",
        !           465:        "stack",
        !           466:        "error",
        !           467: };
        !           468: 
        !           469: /*
        !           470:  *  math coprocessor error
        !           471:  */
        !           472: void
        !           473: matherror(Ureg *ur, void *a)
        !           474: {
        !           475:        ulong status;
        !           476:        int i;
        !           477:        char *msg;
        !           478:        char note[ERRLEN];
        !           479: 
        !           480:        USED(a);
        !           481: 
        !           482:        /*
        !           483:         *  a write cycle to port 0xF0 clears the interrupt latch attached
        !           484:         *  to the error# line from the 387
        !           485:         */
        !           486:        outb(0xF0, 0xFF);
        !           487: 
        !           488:        /*
        !           489:         *  save floating point state to check out error
        !           490:         */
        !           491:        fpenv(&u->fpsave);
        !           492:        status = u->fpsave.status;
        !           493: 
        !           494:        msg = 0;
        !           495:        for(i = 0; i < 8; i++)
        !           496:                if((1<<i) & status){
        !           497:                        msg = mathmsg[i];
        !           498:                        sprint(note, "sys: fp: %s fppc=0x%lux", msg, u->fpsave.pc);
        !           499:                        postnote(u->p, 1, note, NDebug);
        !           500:                        break;
        !           501:                }
        !           502:        if(msg == 0){
        !           503:                sprint(note, "sys: fp: unknown fppc=0x%lux", u->fpsave.pc);
        !           504:                postnote(u->p, 1, note, NDebug);
        !           505:        }
        !           506:        if(ur->pc & KZERO)
        !           507:                panic("fp: status %lux fppc=0x%lux pc=0x%lux", status,
        !           508:                        u->fpsave.pc, ur->pc);
        !           509: }
        !           510: 
        !           511: /*
        !           512:  *  math coprocessor emulation fault
        !           513:  */
        !           514: void
        !           515: mathemu(Ureg *ur, void *a)
        !           516: {
        !           517:        USED(ur, a);
        !           518: 
        !           519:        switch(u->p->fpstate){
        !           520:        case FPinit:
        !           521:                fpinit();
        !           522:                u->p->fpstate = FPactive;
        !           523:                break;
        !           524:        case FPinactive:
        !           525:                fprestore(&u->fpsave);
        !           526:                u->p->fpstate = FPactive;
        !           527:                break;
        !           528:        case FPactive:
        !           529:                panic("math emu", 0);
        !           530:                break;
        !           531:        }
        !           532: }
        !           533: 
        !           534: /*
        !           535:  *  math coprocessor segment overrun
        !           536:  */
        !           537: void
        !           538: mathover(Ureg *ur, void *a)
        !           539: {
        !           540:        USED(ur, a);
        !           541: 
        !           542: print("sys: fp: math overrun pc 0x%lux pid %d\n", ur->pc, u->p->pid);
        !           543:        pexit("math overrun", 0);
        !           544: }
        !           545: 
        !           546: void
        !           547: mathinit(void)
        !           548: {
        !           549:        setvec(Matherr1vec, matherror, 0);
        !           550:        setvec(Matherr2vec, matherror, 0);
        !           551:        setvec(Mathemuvec, mathemu, 0);
        !           552:        setvec(Mathovervec, mathover, 0);
        !           553: }
        !           554: 
        !           555: /*
        !           556:  *  set up floating point for a new process
        !           557:  */
        !           558: void
        !           559: procsetup(Proc *p)
        !           560: {
        !           561:        p->fpstate = FPinit;
        !           562:        fpoff();
        !           563: }
        !           564: 
        !           565: /*
        !           566:  *  Save the mach dependent part of the process state.
        !           567:  */
        !           568: void
        !           569: procsave(Proc *p)
        !           570: {
        !           571:        if(p->fpstate == FPactive){
        !           572:                if(p->state == Moribund)
        !           573:                        fpoff();
        !           574:                else
        !           575:                        fpsave(&u->fpsave);
        !           576:                p->fpstate = FPinactive;
        !           577:        }
        !           578: }
        !           579: 
        !           580: /*
        !           581:  *  Restore what procsave() saves
        !           582:  */
        !           583: void
        !           584: procrestore(Proc *p)
        !           585: {
        !           586:        USED(p);
        !           587: }
        !           588: 
        !           589: 
        !           590: /*
        !           591:  *  the following functions all are slightly different from
        !           592:  *  PC to PC.
        !           593:  */
        !           594: 
        !           595: /*
        !           596:  *  reset the i387 chip
        !           597:  */
        !           598: void
        !           599: exit(int ispanic)
        !           600: {
        !           601:        u = 0;
        !           602:        wipekeys();
        !           603:        print("exiting\n");
        !           604:        if(ispanic){
        !           605:                if(cpuserver)
        !           606:                        delay(10000);
        !           607:                else
        !           608:                        for(;;);
        !           609:        }
        !           610: 
        !           611:        (*arch->reset)();
        !           612: }
        !           613: 
        !           614: /*
        !           615:  *  set cpu speed
        !           616:  *     0 == low speed
        !           617:  *     1 == high speed
        !           618:  */
        !           619: int
        !           620: cpuspeed(int speed)
        !           621: {
        !           622:        if(arch->cpuspeed)
        !           623:                return (*arch->cpuspeed)(speed);
        !           624:        else
        !           625:                return 0;
        !           626: }
        !           627: 
        !           628: /*
        !           629:  *  f == frequency (Hz)
        !           630:  *  d == duration (ms)
        !           631:  */
        !           632: void
        !           633: buzz(int f, int d)
        !           634: {
        !           635:        if(arch->buzz)
        !           636:                (*arch->buzz)(f, d);
        !           637: }
        !           638: 
        !           639: /*
        !           640:  *  each bit in val stands for a light
        !           641:  */
        !           642: void
        !           643: lights(int val)
        !           644: {
        !           645:        if(arch->lights)
        !           646:                (*arch->lights)(val);
        !           647: }
        !           648: 
        !           649: /*
        !           650:  *  power to serial port
        !           651:  *     onoff == 1 means on
        !           652:  *     onoff == 0 means off
        !           653:  */
        !           654: int
        !           655: serial(int onoff)
        !           656: {
        !           657:        if(arch->serialpower)
        !           658:                return (*arch->serialpower)(onoff);
        !           659:        else
        !           660:                return 0;
        !           661: }
        !           662: 
        !           663: /*
        !           664:  *  power to modem
        !           665:  *     onoff == 1 means on
        !           666:  *     onoff == 0 means off
        !           667:  */
        !           668: int
        !           669: modem(int onoff)
        !           670: {
        !           671:        if(arch->modempower)
        !           672:                return (*arch->modempower)(onoff);
        !           673:        else
        !           674:                return 0;
        !           675: }
        !           676: 
        !           677: int
        !           678: parseether(uchar *to, char *from)
        !           679: {
        !           680:        char nip[4];
        !           681:        char *p;
        !           682:        int i;
        !           683: 
        !           684:        p = from;
        !           685:        while(*p == ' ')
        !           686:                ++p;
        !           687:        for(i = 0; i < 6; i++){
        !           688:                if(*p == 0)
        !           689:                        return -1;
        !           690:                nip[0] = *p++;
        !           691:                if(*p == 0)
        !           692:                        return -1;
        !           693:                nip[1] = *p++;
        !           694:                nip[2] = 0;
        !           695:                to[i] = strtoul(nip, 0, 16);
        !           696:                if(*p == ':')
        !           697:                        p++;
        !           698:        }
        !           699:        return 0;
        !           700: }
        !           701: 
        !           702: int
        !           703: isaconfig(char *class, int ctlrno, ISAConf *isa)
        !           704: {
        !           705:        char cc[NAMELEN], *p, *q;
        !           706:        int n;
        !           707: 
        !           708:        sprint(cc, "%s%d", class, ctlrno);
        !           709:        for(n = 0; n < nconf; n++){
        !           710:                if(strncmp(confname[n], cc, NAMELEN))
        !           711:                        continue;
        !           712:                p = confval[n];
        !           713:                while(*p){
        !           714:                        while(*p == ' ' || *p == '\t')
        !           715:                                p++;
        !           716:                        if(*p == '\0')
        !           717:                                break;
        !           718:                        if(strncmp(p, "type=", 5) == 0){
        !           719:                                p += 5;
        !           720:                                for(q = isa->type; q < &isa->type[NAMELEN-1]; q++){
        !           721:                                        if(*p == '\0' || *p == ' ' || *p == '\t')
        !           722:                                                break;
        !           723:                                        *q = *p++;
        !           724:                                }
        !           725:                                *q = '\0';
        !           726:                        }
        !           727:                        else if(strncmp(p, "port=", 5) == 0)
        !           728:                                isa->port = strtoul(p+5, &p, 0);
        !           729:                        else if(strncmp(p, "irq=", 4) == 0)
        !           730:                                isa->irq = strtoul(p+4, &p, 0);
        !           731:                        else if(strncmp(p, "mem=", 4) == 0)
        !           732:                                isa->mem = strtoul(p+4, &p, 0);
        !           733:                        else if(strncmp(p, "size=", 5) == 0)
        !           734:                                isa->size = strtoul(p+5, &p, 0);
        !           735:                        else if(strncmp(p, "dma=", 4) == 0)
        !           736:                                isa->dma = strtoul(p+4, &p, 0);
        !           737:                        else if(strncmp(p, "ea=", 3) == 0){
        !           738:                                if(parseether(isa->ea, p+3) == -1)
        !           739:                                        memset(isa->ea, 0, 6);
        !           740:                        }
        !           741:                        while(*p && *p != ' ' && *p != '\t')
        !           742:                                p++;
        !           743:                }
        !           744:                return 1;
        !           745:        }
        !           746:        return 0;
        !           747: }
        !           748: 
        !           749: static void
        !           750: pcfloppyintr(Ureg *ur, void *a)
        !           751: {
        !           752:        USED(a);
        !           753: 
        !           754:        floppyintr(ur);
        !           755: }
        !           756: 
        !           757: void
        !           758: floppysetup0(FController *fl)
        !           759: {
        !           760:        USED(fl);
        !           761: }
        !           762: 
        !           763: void
        !           764: floppysetup1(FController *fl)
        !           765: {
        !           766:        uchar equip;
        !           767: 
        !           768:        /*
        !           769:         *  read nvram for types of floppies 0 & 1
        !           770:         */
        !           771:        equip = nvramread(0x10);
        !           772:        if(conf.nfloppy > 0){
        !           773:                fl->d[0].dt = (equip >> 4) & 0xf;
        !           774:                floppysetdef(&fl->d[0]);
        !           775:        }
        !           776:        if(conf.nfloppy > 1){
        !           777:                fl->d[1].dt = equip & 0xf;
        !           778:                floppysetdef(&fl->d[1]);
        !           779:        }
        !           780: 
        !           781:        setvec(Floppyvec, pcfloppyintr, 0);
        !           782: }
        !           783: 
        !           784: /*
        !           785:  *  eject disk ( unknown on safari )
        !           786:  */
        !           787: void
        !           788: floppyeject(FDrive *dp)
        !           789: {
        !           790:        floppyon(dp);
        !           791:        dp->vers++;
        !           792:        floppyoff(dp);
        !           793: }
        !           794: 
        !           795: int 
        !           796: floppyexec(char *a, long b, int c)
        !           797: {
        !           798:        USED(a, b, c);
        !           799:        return b;
        !           800: }
        !           801: 
        !           802: int
        !           803: cistrcmp(char *a, char *b)
        !           804: {
        !           805:        int ac, bc;
        !           806: 
        !           807:        for(;;){
        !           808:                ac = *a++;
        !           809:                bc = *b++;
        !           810:        
        !           811:                if(ac >= 'A' && ac <= 'Z')
        !           812:                        ac = 'a' + (ac - 'A');
        !           813:                if(bc >= 'A' && bc <= 'Z')
        !           814:                        bc = 'a' + (bc - 'A');
        !           815:                ac -= bc;
        !           816:                if(ac)
        !           817:                        return ac;
        !           818:                if(bc == 0)
        !           819:                        break;
        !           820:        }
        !           821:        return 0;
        !           822: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.