Annotation of lucent/sys/src/9/pc/main.c, revision 1.1.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.