1: /*
   2:  * Copyright (c) 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)sys.c	2.4 (2.11BSD) 1996/3/8
   7:  */
   8: 
   9: #include "../h/param.h"
  10: #include "../h/dir.h"
  11: #include "../machine/seg.h"
  12: #include "../machine/iopage.h"
  13: #include "../machine/psl.h"
  14: #include "../machine/machparam.h"
  15: #include "saio.h"
  16: 
  17: #undef  KISA0
  18: #define KISA0   ((u_short *) 0172340)
  19: #define KDSA0   ((u_short *) 0172360)
  20: 
  21: extern  struct  devsw   devsw[];
  22: extern  int ssr3copy, bootctlr;
  23: extern  long    atol();
  24: 
  25: /*
  26:  * These buffers are only used in mapping inode blocks to disk sectors,
  27:  * no good reason to make them global.
  28:  *
  29:  * The strange initialization is due to the fact that the 0'th case is
  30:  * not legal since it would be used for quadruple indirect files.  The
  31:  * use of the array 'b' is:
  32:  *
  33:  *	b[0] - not allocated, saving 1kb of space
  34:  *	b[1] - triple indirect block
  35:  *	b[2] - double indirect block
  36:  *	b[3] - single indirect block
  37:  *
  38:  * In the 1kb filesystem double indirect files can be up to ~65 megabytes
  39:  * (the old 512 byte filesystem double indirect files were up to ~8mb).
  40: */
  41: 
  42: static  char    tplind[DEV_BSIZE], dblind[DEV_BSIZE], sngind[DEV_BSIZE];
  43: 
  44: static  char    *b[4] = {
  45:         NULL,       /* j = 0 */
  46:         tplind,     /* j = 1 */
  47:         dblind,     /* j = 2 */
  48:         sngind      /* j = 3 */
  49:         };
  50: 
  51: static  daddr_t blknos[4];
  52: 
  53: #define NFILES  4
  54: struct  iob iob[NFILES];
  55: 
  56: ino_t dlook();
  57: struct direct *readdir();
  58: 
  59: struct dirstuff {
  60:     long loc;
  61:     struct iob *io;
  62:     };
  63: 
  64: /*
  65:  * wfj - mods to trap to explicitly detail why we stopped
  66:  */
  67: 
  68: static
  69: openi(n, io)
  70:     register ino_t n;
  71:     register struct iob *io;
  72: {
  73:     register struct dinode *dp;
  74:     daddr_t tdp;
  75: 
  76:     io->i_offset = 0;
  77:     tdp = itod(n);
  78:     io->i_bn = fsbtodb(tdp) + io->i_boff;
  79:     io->i_cc = DEV_BSIZE;
  80:     io->i_ma = io->i_buf;
  81:     devread(io);
  82: 
  83:     dp = (struct dinode *)io->i_buf;
  84:     dp = &dp[itoo(n)];
  85:     io->i_ino.i_number = n;
  86:     io->i_ino.i_mode = dp->di_mode;
  87:     io->i_ino.i_size = dp->di_size;
  88:     bcopy(dp->di_addr, io->i_ino.i_addr, NADDR * sizeof (daddr_t));
  89: }
  90: 
  91: static
  92: find(path, file)
  93:     register char *path;
  94:     struct iob *file;
  95: {
  96:     register char *q;
  97:     register char c;
  98:     ino_t n;
  99: 
 100:     if (path==NULL || *path=='\0') {
 101:         printf("null path\n");
 102:         return(0);
 103:     }
 104: 
 105:     openi((ino_t) ROOTINO, file);
 106:     while (*path) {
 107:         while (*path == '/')
 108:             path++;
 109:         q = path;
 110:         while (*q != '/' && *q != '\0')
 111:             q++;
 112:         c = *q;
 113:         *q = '\0';
 114:         if (q == path) path = "." ; /* "/" means "/." */
 115: 
 116:         if ((n=dlook(path, file))!=0) {
 117:             if (c=='\0')
 118:                 break;
 119:             openi(n, file);
 120:             *q = c;
 121:             path = q;
 122:             continue;
 123:         } else {
 124:             printf("%s not found\n", path);
 125:             return(0);
 126:         }
 127:         /*NOTREACHED*/
 128:     }
 129:     return(n);
 130: }
 131: 
 132: static daddr_t
 133: sbmap(io, bn)
 134:     register struct iob *io;
 135:     daddr_t bn;
 136: {
 137:     register i;
 138:     register struct inode *ip;
 139:     int j, sh;
 140:     daddr_t nb, *bap;
 141: 
 142:     ip = &io->i_ino;
 143:     if (bn < 0) {
 144:         printf("bn < 0\n");
 145:         return((daddr_t)0);
 146:     }
 147: 
 148:     /*
 149: 	 * blocks 0..NADDR-4 are direct blocks
 150: 	 */
 151:     if (bn < NADDR-3) {
 152:         i = bn;
 153:         nb = ip->i_addr[i];
 154:         return(nb);
 155:     }
 156: 
 157:     /*
 158: 	 * addresses NADDR-3, NADDR-2, and NADDR-1
 159: 	 * have single, double, triple indirect blocks.
 160: 	 * the first step is to determine
 161: 	 * how many levels of indirection.
 162: 	 */
 163:     sh = 0;
 164:     nb = 1;
 165:     bn -= NADDR-3;
 166:     for (j=3; j>0; j--) {
 167:         sh += NSHIFT;
 168:         nb <<= NSHIFT;
 169:         if (bn < nb)
 170:             break;
 171:         bn -= nb;
 172:     }
 173:     if (j == 0) {
 174:         printf("bn ovf %D\n", bn);
 175:         return((daddr_t)0);
 176:     }
 177: /*
 178:  * At this point:
 179:  *
 180:  *  j	  NADDR-j    meaning
 181:  * ---    -------    -------
 182:  *  0       7        illegal - tossed out in the 'if' above
 183:  *  1       6        triple indirect block number
 184:  *  2       5        double indirect block number
 185:  *  3       4        single indirect block number
 186: */
 187: 
 188:     /*
 189: 	 * fetch the address from the inode
 190: 	 */
 191:     nb = ip->i_addr[NADDR-j];
 192:     if (nb == 0)
 193:         goto bnvoid;
 194: 
 195:     /*
 196: 	 * fetch through the indirect blocks
 197: 	 */
 198:     for (; j<=3; j++) {
 199:         if (blknos[j] != nb) {
 200:             io->i_bn = fsbtodb(nb) + io->i_boff;
 201:             io->i_ma = b[j];
 202:             io->i_cc = DEV_BSIZE;
 203:             devread(io);
 204:             blknos[j] = nb;
 205:         }
 206:         bap = (daddr_t *)b[j];
 207:         sh -= NSHIFT;
 208:         i = (bn>>sh) & NMASK;
 209:         nb = bap[i];
 210:         if (nb == 0) {
 211: bnvoid:
 212:             printf("bn void %D\n", bn);
 213:             return((daddr_t)0);
 214:         }
 215:     }
 216: 
 217:     return(nb);
 218: }
 219: 
 220: static ino_t
 221: dlook(s, io)
 222:     char *s;
 223:     register struct iob *io;
 224: {
 225:     register struct direct *dp;
 226:     register struct inode *ip;
 227:     struct dirstuff dirp;
 228:     int len;
 229: 
 230:     if (s==NULL || *s=='\0')
 231:         return(0);
 232:     ip = &io->i_ino;
 233:     if ((ip->i_mode&IFMT) != IFDIR || !ip->i_size) {
 234:         printf("%s: !directory,mode %o size: %D ip %o\n", s,
 235:             ip->i_mode, ip->i_size, ip);
 236:         return(0);
 237:     }
 238: 
 239:     len = strlen(s);
 240:     dirp.loc = 0;
 241:     dirp.io = io;
 242:     for (dp = readdir(&dirp); dp; dp = readdir(&dirp)) {
 243:         if (dp->d_ino == 0)
 244:             continue;
 245:         if (dp->d_namlen == len && !strcmp(s,dp->d_name))
 246:             return(dp->d_ino);
 247:     }
 248:     return(0);
 249: }
 250: 
 251: struct direct *
 252: readdir(dirp)
 253:     register struct dirstuff *dirp;
 254: {
 255:     register struct direct *dp;
 256:     register struct iob *io;
 257:     daddr_t lbn, d, off;
 258: 
 259:     io = dirp->io;
 260:     for (;;) {
 261:         if (dirp->loc >= io->i_ino.i_size)
 262:             return(NULL);
 263:         off = blkoff(dirp->loc);
 264:         if (off == 0) {
 265:             lbn = lblkno(dirp->loc);
 266:             d = sbmap(io, lbn);
 267:             if (d == 0)
 268:                 return(NULL);
 269:             io->i_bn = fsbtodb(d) + io->i_boff;
 270:             io->i_ma = io->i_buf;
 271:             io->i_cc = DEV_BSIZE;
 272:             devread(io);
 273:         }
 274:         dp = (struct direct *)(io->i_buf + off);
 275:         dirp->loc += dp->d_reclen;
 276:         if (dp->d_ino == 0)
 277:             continue;
 278:         return(dp);
 279:     }
 280: }
 281: 
 282: /*
 283:  * Modified to call the tape driver's seek routine.  This only works when
 284:  * the record size is DEV_BSIZE (1kb).
 285: */
 286: lseek(fdesc, addr, ptr)
 287:     register int fdesc;
 288:     off_t addr;
 289:     int ptr;
 290: {
 291:     off_t   new;
 292:     register struct iob *io;
 293: 
 294:     if (ptr != 0) {
 295:         printf("lseek\n");
 296:         return(-1);
 297:     }
 298:     fdesc -= 3;
 299:     if  (fdesc < 0 || fdesc >= NFILES ||
 300:             ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
 301:         return(-1);
 302:     new = addr / DEV_BSIZE;
 303: 
 304:     if  (io->i_flgs & F_TAPE)
 305:         {
 306: #ifdef  debug
 307:         printf("seek: new=%D i_bn=%D\n", new, io->i_bn);
 308: #endif
 309: /*
 310:  * Subtract 1 to acccount for the block currently in the buffer - the
 311:  * tape is currently positioned at the next record.  Need to convert the
 312:  * block number from 512 byte to 1024 byte records (undo the fsbtodb).
 313: */
 314:         devseek(io, (int)(new - dbtofsb(io->i_bn) - 1));
 315:         }
 316:     io->i_offset = addr;
 317:     io->i_bn = fsbtodb(new) + io->i_boff;
 318:     io->i_cc = 0;
 319:     return(0);
 320: }
 321: 
 322: /* if tape mark encountered, set flag  (in driver) */
 323: int tapemark;
 324: 
 325: getc(fdesc)
 326:     int fdesc;
 327: {
 328:     register struct iob *io;
 329:     register unsigned char *p;
 330:     register int c;
 331:     int off;
 332:     daddr_t tbn;
 333: 
 334:     if (fdesc >= 0 && fdesc <= 2)
 335:         return(getchar());
 336:     fdesc -= 3;
 337:     if (fdesc < 0 || fdesc >= NFILES || ((io = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
 338:         return(-1);
 339:     if (io->i_cc <= 0) {
 340:         io->i_bn = fsbtodb(io->i_offset/(off_t)DEV_BSIZE);
 341:         if (io->i_flgs&F_FILE) {
 342:             tbn = sbmap(io, dbtofsb(io->i_bn));
 343:             io->i_bn = fsbtodb(tbn) + io->i_boff;
 344:         }
 345:         io->i_ma = io->i_buf;
 346:         io->i_cc = DEV_BSIZE;
 347: #ifdef DEBUG
 348:         printf("getc: fetch block %D, dev = %d\n", io->i_bn,
 349:                 io->i_ino.i_dev);
 350: #endif
 351:         tapemark = 0;
 352:         devread(io);
 353:         off = io->i_offset % (off_t)DEV_BSIZE;
 354:         if (io->i_flgs&F_FILE) {
 355:             if (io->i_offset+(DEV_BSIZE-off) >= io->i_ino.i_size)
 356:                 io->i_cc = io->i_ino.i_size - io->i_offset + off;
 357:         }
 358:         if  (tapemark)
 359:             return(-1);
 360:         io->i_cc -= off;
 361:         if  (io->i_cc <= 0)
 362:             return(-1);
 363:         io->i_ma = &io->i_buf[off];
 364:     }
 365:     io->i_cc--;
 366:     io->i_offset++;
 367:     c = (int)(*(unsigned char *)io->i_ma++);
 368:     return(c);
 369: }
 370: getw(fdesc)
 371:     int fdesc;
 372: {
 373:     register w, i;
 374:     register unsigned char *cp;
 375:     int val;
 376: 
 377:     for (i = 0, val = 0, cp = (unsigned char *)&val; i < sizeof(val); i++) {
 378:         w = getc(fdesc);
 379:         if (w < 0) {
 380:             if (i == 0)
 381:                 return(-1);
 382:             else
 383:                 return(val);
 384:         }
 385:         *cp++ = w;
 386:     }
 387:     return(val);
 388: }
 389: 
 390: read(fdesc, buf, count)
 391:     register int fdesc;
 392:     char *buf;
 393:     int count;
 394: {
 395:     register i;
 396:     register struct iob *file;
 397: 
 398:     if (fdesc >= 0 & fdesc <= 2) {
 399:         i = count;
 400:         do {
 401:             *buf = getchar();
 402:         } while (--i && *buf++ != '\n');
 403:         return(count - i);
 404:     }
 405:     fdesc -= 3;
 406:     if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
 407:         return(-1);
 408:     if ((file->i_flgs&F_READ) == 0)
 409:         return(-1);
 410:     if ((file->i_flgs&F_FILE) == 0) {
 411:         file->i_cc = count;
 412:         file->i_ma = buf;
 413:         i = devread(file);
 414:         if  (i > 0)
 415:             file->i_bn += (i / NBPG);
 416:         return(i);
 417:     }
 418:     else {
 419:         if (file->i_offset+count > file->i_ino.i_size)
 420:             count = file->i_ino.i_size - file->i_offset;
 421:         if ((i = count) <= 0)
 422:             return(0);
 423:         do {
 424:             *buf++ = getc(fdesc+3);
 425:         } while (--i);
 426:         return(count);
 427:     }
 428: }
 429: 
 430: write(fdesc, buf, count)
 431:     register int fdesc;
 432:     char *buf;
 433:     int count;
 434: {
 435:     register i;
 436:     register struct iob *file;
 437: 
 438:     if (fdesc >= 0 && fdesc <= 2) {
 439:         i = count;
 440:         while (i--)
 441:             putchar(*buf++);
 442:         return(count);
 443:     }
 444:     fdesc -= 3;
 445:     if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
 446:         return(-1);
 447:     if ((file->i_flgs&F_WRITE) == 0)
 448:         return(-1);
 449:     file->i_cc = count;
 450:     file->i_ma = buf;
 451:     i = devwrite(file);
 452:     file->i_bn += (count / NBPG);
 453:     return(i);
 454: }
 455: 
 456: open(str, how)
 457:     char *str;
 458:     int how;
 459: {
 460:     register char *cp;
 461:     int i, i2, i3;
 462:     register struct iob *file;
 463:     register struct devsw *dp;
 464:     int fdesc;
 465: 
 466:     for (fdesc = 0; fdesc < NFILES; fdesc++)
 467:         if (iob[fdesc].i_flgs == 0)
 468:             goto gotfile;
 469:     _stop("No file slots");
 470: gotfile:
 471:     (file = &iob[fdesc])->i_flgs |= F_ALLOC;
 472: 
 473:     for (cp = str; *cp && *cp != '('; cp++)
 474:             ;
 475:     if (*cp != '(') {
 476:         printf("Bad device\n");
 477:         file->i_flgs = 0;
 478:         return(-1);
 479:     }
 480:     *cp = '\0';
 481:     for (dp = devsw; dp->dv_name; dp++) {
 482:         if (strcmp(str, dp->dv_name) == 0)
 483:             goto gotdev;
 484:     }
 485:     printf("Unknown device\n");
 486:     file->i_flgs = 0;
 487:     return(-1);
 488: gotdev:
 489: /*
 490:  * The parse is a bit lengthier and complex now.  The syntax is now:
 491:  *
 492:  *	xx(ctlr, unit, partition)filename
 493:  * or
 494:  *	xx(unit, partition)filename
 495:  *
 496:  *
 497:  * The controller number must be less than 4.  NOTE: many drivers
 498:  * limit the number of controllers to 1 or 2.  If the controller is not
 499:  * specified it defaults to 0.
 500:  *
 501:  * The unit number must be less than 8.
 502:  *
 503:  * The partition number is also used to specify the tapefile to be loaded.
 504:  * When loading a tapefile the 'filename' must not be specified.  The partition
 505:  * number must be less than 8.  This means that the number of standalone
 506:  * programs is limited to 7.
 507: */
 508: 
 509:     *cp++ = '(';
 510:     file->i_ino.i_dev = dp-devsw;
 511:     for (i = 0; *cp >= '0' && *cp <= '9'; cp++) {
 512:         i *= 10;
 513:         i += (*cp - '0');
 514:     }
 515: 
 516:     if (*cp++ != ',') {
 517: badoff:
 518:         printf("Bad offset or ctlr, unit, part out of bounds\n");
 519:         file->i_flgs = 0;
 520:         return(-1);
 521:     }
 522: 
 523:     for (i2 = 0; *cp >= '0' && *cp <= '9'; cp++)
 524:         {
 525:         i2 *= 10;
 526:         i2 += (*cp - '0');
 527:         }
 528: /*
 529:  * If we encounter a ')' now it means we have the two arg form 'ra(x,y)'.  If
 530:  * a ',' is seen then we have the three arg form 'xp(x,y,z)'.  If neither a
 531:  * ',' or ')' it is an error.
 532: */
 533:     if  (*cp == ')')
 534:         {
 535:         file->i_ctlr = bootctlr;
 536:         file->i_unit = i;
 537:         file->i_part = i2;
 538:         cp++;           /* skip ) */
 539:         }
 540:     else if (*cp == ',')
 541:         {
 542:         for (i3 = 0, cp++; *cp >= '0' && *cp <= '9'; cp++)
 543:             {
 544:             i3 *= 10;
 545:             i3 += (*cp - '0');
 546:             }
 547:         file->i_ctlr = i;
 548:         file->i_unit = i2;
 549:         file->i_part = i3;
 550:         if  (*cp++ != ')')
 551:             goto badoff;
 552:         }
 553:     else
 554:         goto badoff;
 555:     if  (file->i_ctlr > 3 || file->i_unit > 7 || file->i_part > 7)
 556:         goto badoff;
 557: 
 558:     if  (devopen(file) < 0)
 559:         {
 560:         file->i_flgs = 0;
 561:         return(-1);
 562:         }
 563:     if (*cp == '\0') {
 564:         file->i_flgs |= how+1;
 565:         goto comret;
 566:     }
 567:     if ((i = find(cp, file)) == 0) {
 568:         file->i_flgs = 0;
 569:         return(-1);
 570:     }
 571:     if (how != 0) {
 572:         printf("Can't write files\n");
 573:         file->i_flgs = 0;
 574:         return(-1);
 575:     }
 576:     openi(i, file);
 577:     file->i_flgs |= F_FILE | (how+1);
 578: comret:
 579:     file->i_offset = 0;
 580:     file->i_cc = 0;
 581:     file->i_bn = 0;
 582:     return(fdesc+3);
 583: }
 584: 
 585: close(fdesc)
 586:     register int fdesc;
 587: {
 588:     register struct iob *file;
 589: 
 590:     fdesc -= 3;
 591:     if (fdesc < 0 || fdesc >= NFILES || ((file = &iob[fdesc])->i_flgs&F_ALLOC) == 0)
 592:         return(-1);
 593:     if ((file->i_flgs&F_FILE) == 0)
 594:         devclose(file);
 595:     file->i_flgs = 0;
 596:     return(0);
 597: }
 598: 
 599: exit()
 600: {
 601:     _stop("Exit called");
 602: }
 603: 
 604: _stop(s)
 605:     char *s;
 606: {
 607:     printf("%s\n", s);
 608:     _rtt();
 609: }
 610: 
 611: extern char module[];
 612: 
 613: trap(r1, r0, nps, pc, ps)
 614:     int nps, r1, r0, pc, ps;
 615: {
 616:     printf("Trap in %s,", module);
 617:     switch (nps&7) {
 618:     case 0:
 619:         printf("bus error");
 620:         break;
 621:     case 1:
 622:         printf("illegal instruction");
 623:         break;
 624:     case 2:
 625:         printf("bpt/trace");
 626:         break;
 627:     case 3:
 628:         printf("iot");
 629:         break;
 630:     case 4:
 631:         printf("power fail");
 632:         break;
 633:     case 5:
 634:         printf("emt");
 635:         break;
 636:     case 6:
 637:         printf("sys/trap");
 638:         break;
 639:     default:
 640:         printf("weird");
 641:     }
 642:     printf(" at loc %o\n", pc);
 643:     printf("registers: r0=%o, r1=%o, ps=%o, nps=%o\n", r0, r1, ps, nps);
 644:     for (;;)
 645:         ;
 646: }
 647: 
 648: genopen(maxctlr, io)
 649:     int maxctlr;
 650:     struct iob *io;
 651:     {
 652:     register struct devsw *dp = &devsw[io->i_ino.i_dev];
 653:     register char *cp;
 654:     register int ctlr = io->i_ctlr;
 655:     int csr;
 656:     char line[64];
 657: 
 658:     if (ctlr >= maxctlr)
 659:         return(-1);
 660:     if (dp->dv_csr[ctlr])
 661:         return(0);
 662:     printf("%s%d csr[0%o]: ", dp->dv_name, ctlr, dp->dv_csr[ctlr]);
 663:     gets(line);
 664:     for (csr = 0, cp = line; *cp >= '0' && *cp <= '7'; cp++)
 665:         csr = csr * 8 + (*cp - '0');
 666:     if (csr == 0)
 667:         return(-1);
 668:     dp->dv_csr[ctlr] = (caddr_t *)csr;
 669: /*
 670:  * Tapes don't need this.  Disk drivers which support labels do not need
 671:  * this either but disk drivers which do not support labels _do_ need this.
 672:  * Doing it here is safe for everyone because label capable drivers will
 673:  * load i_boff from the label _after_ calling this routine.
 674: */
 675:     io->i_boff = 0;
 676:     return(0);
 677:     }
 678: 
 679: delay(i)
 680:     int i;
 681:     {
 682: 
 683:     while   (i)
 684:         i--;
 685:     }
 686: 
 687: char *
 688: ltoa(l)
 689:     u_long l;
 690:     {
 691:     static char x[12];
 692:     register char *cp = x + sizeof (x);
 693: 
 694:     do {
 695:         *--cp = (l % 10) + '0';
 696:         l /= 10;
 697:     } while (l);
 698:     return(cp);
 699:     }
 700: 
 701: char *
 702: itoa(i)
 703:     register int i;
 704:     {
 705:     static char x[8];
 706:     register char *cp = x + sizeof (x);
 707: 
 708:     do {
 709:         *--cp = (i % 10) + '0';
 710:         i /= 10;
 711:     } while (i);
 712:     return(cp);
 713:     }
 714: 
 715: /*
 716:  * Convert a 16 bit (virtual) address into a 18 bit (UNIBUS) address.
 717:  * The address extension bits (bits 16, 17) are placed into 'bae' while
 718:  * the lower order bits (bits 0 - 15) are placed in 'lo16'.
 719:  *
 720:  * This routine was primarily created to handle split I/D kernel mode
 721:  * utilities.  Boot itself must run non split I/D and runs in user mode.
 722:  * A side effect of this routine is that Boot no longer must be loaded at
 723:  * a 64Kb boundary.
 724:  *
 725:  * Everything (Boot and standalone utilities) must still run in the low
 726:  * 248kb of memory which is mapped by the UNIBUS mapping registers.
 727: */
 728: 
 729: iomapadr(buf, bae, lo16)
 730:     memaddr buf;
 731:     u_short *bae, *lo16;
 732:     {
 733:     u_long  uadr;
 734:     int curmode = *PS & PSL_CURMOD, segno;
 735:     u_int   nb, ts;
 736:     extern  char    module[];
 737: 
 738:     if  (curmode == 0)
 739:         {       /* Kernel mode - we're in a utility */
 740: /*
 741:  * For split I/D we need to emulate the kernel's method of looking at
 742:  * the segment registers and calculating the physical address.  Whew, forgot
 743:  * that ;-)
 744: */
 745:         nb = ((int)buf >> 6) & 01777;
 746:         segno = nb >> 7;
 747:         if  (ssr3copy & 4)
 748:             ts = KDSA0[segno];  /* kernel I/D is on */
 749:         else
 750:             ts = KISA0[segno];  /* kernel I/D is off */
 751:         ts += (nb & 0177);
 752:         uadr = ((u_long)ts << 6) + (buf & 077);
 753:         }
 754:     else if (curmode == PSL_CURMOD)
 755:         {       /* User mode - we're in Boot */
 756:         uadr = UISA[0];         /* No I/D for Boot! */
 757:         uadr <<= 6;         /* clicks to bytes */
 758:         uadr += buf;
 759:         }
 760:     else
 761:         _stop("Bad PSL mode");
 762: 
 763:     *bae = (uadr >> 16) & 3;        /* 18 bit mode */
 764:     *lo16 = uadr & 0xffff;
 765:     }

Defined functions

_stop defined in line 604; used 5 times
delay defined in line 679; used 6 times
dlook defined in line 220; used 2 times
find defined in line 91; used 1 times
getc defined in line 325; used 2 times
getw defined in line 370; used 11 times
lseek defined in line 286; used 1 times
ltoa defined in line 687; never used
openi defined in line 68; used 3 times
readdir defined in line 251; used 3 times
sbmap defined in line 132; used 2 times
trap defined in line 613; used 4 times
write defined in line 430; used 2 times

Defined variables

b defined in line 44; used 2 times
blknos defined in line 51; used 2 times
dblind defined in line 42; used 1 times
  • in line 47
iob defined in line 54; used 9 times
sngind defined in line 42; used 1 times
  • in line 48
tplind defined in line 42; used 1 times
  • in line 46

Defined struct's

dirstuff defined in line 59; used 4 times

Defined macros

KDSA0 defined in line 19; used 1 times
KISA0 defined in line 18; used 2 times
NFILES defined in line 53; used 7 times
Last modified: 1996-03-09
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 5869
Valid CSS Valid XHTML 1.0 Strict