1: /*
   2:  * Copyright (c) 1987 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:  *	@(#)mch_xxx.s	1.5 (2.11BSD GTE) 12/15/94
   7:  */
   8: #include "DEFS.h"
   9: #include "../machine/mch_iopage.h"
  10: #include "../machine/koverlay.h"
  11: 
  12: /*
  13:  * noop()
  14:  *
  15:  * Do nothing.  Typically used to provide enough time for interrupts to
  16:  * happen between a pair of spl's in C.  We use noop rather than inserting
  17:  * meaningless instructions between the spl's to prevent any future C
  18:  * optimizer `improvements' from causing problems.
  19:  *
  20:  * delay(usec)
  21:  *	long	usec;
  22:  *
  23:  * Delay (approximately) usec micro-seconds.  It really isn't very acurrate
  24:  * since we can be interrupted and take much longer than we intended, but
  25:  * that's alright - we just don't want to come home early ...
  26:  */
  27: ENTRY(delay)
  28:         mov     2(sp),r0                / r0 = hiint(usec)
  29:         mov     4(sp),r1                / r1 = loint(usec)
  30:         ashc    $1,r0                   / sob's ~= 1/2 micro second,
  31:         beq     2f                      / oops, got passed a delay of 0L-leave
  32:         tst     r1
  33:         /*
  34: 	 * If the low int of the loop counter is zero, the double sob loop
  35: 	 * below will perform correctly, otherwise the high byte must be
  36: 	 * increment.
  37: 	 */
  38:         beq     1f
  39:         inc     r0                      / correct for looping
  40: 1:
  41:         sob     r1,1b                   / sit on our hands for a while ...
  42:         sob     r0,1b
  43: 2:
  44: ENTRY(noop)
  45:         rts     pc
  46: 
  47: /*
  48:  * idle()
  49:  *
  50:  * Sit and wait for something to happen ...
  51:  */
  52: 
  53: /*
  54:  * If you have a console display it's amusing to see a slowly rotating
  55:  * sequence of lights in the display.  If the system is very active the display
  56:  * will appear blurred.
  57:  */
  58: INT(LOCAL, rdisply, 0377)               / idle pattern
  59: INT(LOCAL, wcount, 2)                   / rotate rdisply every wcount calls
  60: 
  61: ENTRY(idle)
  62:         mov     PS,-(sp)                / save current SPL, indicate that no
  63:         mov     $1,_noproc              /   process is running
  64:         dec     wcount                  / if (--wcount <= 0) {
  65:         bgt     1f
  66:         mov     $2,wcount               /   wcount = 2
  67:         clc                             /   rdisply <<= 1
  68:         rol     rdisply
  69:         bpl     1f                      /   if (``one shifted out'')
  70:         bis     $1,rdisply              /     rdisply |= 1
  71: 1:                                      / }
  72:         mov     rdisply,r0              / wait displays contents of r0
  73:         SPLLOW                          / set SPL low so we can be interrupted
  74:         wait                            / wait for something to happen
  75:         mov     (sp)+,PS                / restore previous SPL
  76:         rts     pc                      /   and return
  77: 
  78: #ifdef PROF
  79: /*
  80:  * These words are to insure that times reported for any following routine do
  81:  * not include those spent while in idle mode when statistics are gathered
  82:  * for system profiling.
  83:  */
  84:         rts     pc
  85:         rts     pc
  86:         rts     pc
  87: #endif
  88: 
  89: 
  90: /*
  91:  * setjmp(env)
  92:  *	label_t	*env;
  93:  *
  94:  * longjmp(u, env)
  95:  * resume(u, env)
  96:  *	memaddr	u;
  97:  *	label_t	*env;
  98:  *
  99:  * Setjmp(env) will save the process' current register variable, stack,
 100:  * overlay and program counter context and return a zero.
 101:  *
 102:  * Longjmp(u, env) (and resume) will will generate a "return(1)" from the last
 103:  * call to setjmp(env) by mapping in the user structure pointed to by u,
 104:  * restoring the context saved by setjmp in env and returning a one.  Note that
 105:  * registers are recovered statically from the env buffer rather than
 106:  * dynamically from the stack ...
 107:  *
 108:  * This longjmp differs from the longjmp found in the standard library and the
 109:  * VAX 4.3 kernel - it's actually closer to the resume routine of the 4.3
 110:  * kernel and, indeed, even used to be called resume in the 2.9 kernel.
 111:  * We've given it both names to promote some degree of compatibility between
 112:  * the 4.3 and 2.10 C kernel source ...
 113:  */
 114: ENTRY(setjmp)
 115:         mov     (sp)+,r1                / save return address
 116:         mov     (sp),r0                 / r0 = env
 117:         mov     r2,(r0)+                / save register variables r2 - r4
 118:         mov     r3,(r0)+                /   in env ...
 119:         mov     r4,(r0)+
 120:         mov     r5,(r0)+                /   frame pointer,
 121:         mov     sp,(r0)+                /   stack pointer,
 122: #ifdef INET
 123:         mov     PS,-(sp)                /   network stack pointer,
 124:         mov     $010340,PS
 125:         mfpd    sp
 126: #ifdef CHECKSTACK
 127:         cmp     (sp),$NET_STOP          /   (check network stack pointer to
 128:         bhi     1f                      /     make sure it's in the network
 129:         cmp     (sp),$NET_SBASE         /     stack ...)
 130:         bhi     2f
 131: 1:
 132:         halt
 133: 2:
 134: #endif
 135:         mov     (sp)+,(r0)+
 136:         mov     (sp)+,PS
 137: #endif
 138:         mov     __ovno,(r0)+            /   overlay number,
 139:         mov     r1,(r0)+                /   and return address
 140:         clr     r0                      / return a zero for the setjmp call
 141:         jmp     (r1)
 142: 
 143: ENTRY(longjmp)
 144: ENTRY(resume)
 145:         mov     2(sp),r0                / r0 = u
 146:         mov     4(sp),r1                / r1 = env
 147:         SPL7                            / can't let anything in till we
 148:                                         /   (at least) get a valid stack ...
 149:         mov     r0,KDSA6                / map new process' u structure in
 150: #ifdef INET
 151:         mov     r0,SDSA6                / map supervisor stack area to same
 152: #endif
 153:         mov     (r1)+,r2                / restore register variables
 154:         mov     (r1)+,r3                /   from env ...
 155:         mov     (r1)+,r4
 156:         mov     (r1)+,r5                /   frame pointer,
 157:         mov     (r1)+,sp                /   stack pointer,
 158: #ifdef INET
 159:         mov     PS,-(sp)                /   network stack pointer,
 160:         mov     $010340,PS
 161:         mov     (r1)+,-(sp)
 162:         mtpd    sp
 163:         mov     (sp)+,PS
 164: #endif
 165:         mov     (r1)+,r0                / grab return overlay number ...
 166:         cmp     r0,__ovno               / old overlay currently mapped in?
 167:         beq     1f
 168:         mov     r0,__ovno               / nope, set new overlay number
 169:         asl     r0                      / compute descriptor index and map
 170:         mov     ova(r0),OVLY_PAR        /   the old overlay back in ...
 171:         mov     ovd(r0),OVLY_PDR
 172: 1:
 173:         mov     $1001,SSR0              / J-11 bug, force MMU registers to start
 174:                                         /   tracking again between processes
 175:         SPLLOW                          / release interrupts and transfer back
 176:         mov     $1,r0                   /   to setjmp return with a return
 177:         jmp     *(r1)+                  /   value of 1
 178: 
 179: /*
 180:  * struct uprof {			/ profile arguments
 181:  *	short	*pr_base;		/ buffer base
 182:  *	unsigned pr_size;		/ buffer size
 183:  *	unsigned pr_off;		/ pc offset
 184:  *	unsigned pr_scale;		/ pc scaling
 185:  * } u_prof;
 186:  *
 187:  * addupc(pc, pbuf, ticks)
 188:  *	caddr_t		pc;
 189:  *	struct uprof	*pbuf;
 190:  *	int		ticks;
 191:  *
 192:  * Addupc implements the profil(2) facility:
 193:  *
 194:  *	b = (pc - pbuf->pr_off)>>1;
 195:  *	b *= pbuf->pr_scale>>1;
 196:  *	b >>= 14; { 2^14 = 2^16/2/2 - because of the two `>>'s above }
 197:  *	if (b < pbuf->pr_size) {
 198:  *		b += pbuf->pr_base;
 199:  *		if (fuword(b, &w) < 0  ||  suword(b, w) < 0)
 200:  *			pbuf->pr_scale = 0;	{ turn off profiling }
 201:  *	}
 202:  */
 203: ENTRY(addupc)
 204:         mov     r2,-(sp)                / save register so we can use it
 205:         mov     6(sp),r2                / r2 = pbuf
 206:         mov     4(sp),r0                / r0 = pc
 207:         sub     4(r2),r0                / r0 -= pbuf->pr_off
 208:         clc                             / r0 >>= 1 { ensure high bit 0 }
 209:         ror     r0
 210:         mov     6(r2),r1                / r1 = pbuf->pr_scale
 211:         clc                             / r1 >>= 1 { ensure high bit 0 }
 212:         ror     r1
 213:         mul     r1,r0                   / r0:r1 = r0 * (pbuf->pr_scale>>1)
 214:         ashc    $-14.,r0                / r0:r1 >>= 14
 215:         inc     r1                      / *round* r1 to a word offset
 216:         bic     $1,r1
 217:         cmp     r1,2(r2)                / if r1 > pbuf->pr_size
 218:         bhis    3f                      /   bug out ...
 219:         add     (r2),r1                 / r1 += pbuf->pr_base
 220:         mov     nofault,-(sp)           / set up for possible memory fault when
 221:         mov     $1f,nofault             /   access pbuf->pr_base[r1] : branch
 222:                                         /   to 1f on fault
 223:         mfpd    (r1)                    / pbuf->pr_base[r1] += ticks
 224:         add     12.(sp),(sp)
 225:         mtpd    (r1)
 226:         br      2f                      / (branch around fault code)
 227: 1:                                      / on fault: disable profiling
 228:         clr     6(r2)                   /   (pbuf->pr_scale = 0)
 229: 2:
 230:         mov     (sp)+,nofault           / reset fault branch
 231: 3:
 232:         mov     (sp)+,r2                / restore saved registers
 233:         rts     pc                      /   and return
 234: 
 235: #ifndef ENABLE34
 236: /*
 237:  * fioword(addr)
 238:  *	caddr_t addr;
 239:  *
 240:  * Fetch a word from an address on the I/O page,
 241:  * returning -1 if address does not exist.
 242:  */
 243: ENTRY(fioword)
 244:         mov     nofault,-(sp)
 245:         mov     $2f,nofault
 246:         mov     *4(sp),r0
 247: 1:
 248:         mov     (sp)+,nofault
 249:         rts     pc
 250: 2:
 251:         mov     $-1,r0
 252:         br      1b
 253: #endif
 254: 
 255: /*
 256:  * error = copystr(fromaddr, toaddr, maxlength, lencopied)
 257:  *	int	error;
 258:  *	caddr_t	fromaddr, toaddr;
 259:  *	u_int	maxlength, *lencopied;
 260:  *
 261:  * Copy a null terminated string from one point to another in the kernel
 262:  * address space.  Returns zero on success, ENOENT if maxlength exceeded.  If
 263:  * lencopied is non-zero, *lencopied gets the length of the copy (including
 264:  * the null terminating byte).
 265:  */
 266: ENTRY(copystr)
 267:         mov     r2,-(sp)                / need an extra register
 268:         mov     4.(sp),r0               / r0 = fromaddr
 269:         mov     6.(sp),r1               / r1 = toaddr
 270:         mov     8.(sp),r2               / r2 = maxlength (remaining space)
 271:         beq     2f                      / (exit early with ENOENT if 0)
 272: 1:
 273:         movb    (r0)+,(r1)+             / move a byte
 274:         beq     3f                      / (done when we cross the null)
 275:         sob     r2,1b                   / and loop as long as there's room
 276: 2:
 277:         mov     $ENOENT,r0              / ran out of room - indicate failure
 278:         br      4f                      /   and exit ...
 279: 3:
 280:         clr     r0                      / success!
 281: 4:
 282:         tst     10.(sp)                 / does the caller want the copy length?
 283:         beq     5f
 284:         sub     6.(sp),r1               / yes, figure out how much we copied:
 285:         mov     r1,*10.(sp)             / *lencopied = r1 {toaddr'} - toaddr
 286: 5:
 287:         mov     (sp)+,r2                / restore registers
 288:         rts     pc                      /   and return
 289: 
 290: 
 291: /*
 292:  * Zero the core associated with a buffer.  Since this routine calls mapin
 293:  * without saving the current map, it cannot be called from interrupt routines.
 294:  */
 295: ENTRY(clrbuf)
 296:         mov     2(sp),-(sp)             / pass bp to mapin
 297:         jsr     pc,_mapin               / r0 = buffer pointer
 298:         tst     (sp)+
 299: 
 300:         tst     _fpp                    / do we have floating point hardware?
 301:         beq     2f                      / nope, use regular clr instructions
 302: 
 303:         stfps   -(sp)                   / save old floating point status
 304:         setd                            / use double precision
 305:         mov     $MAXBSIZE\/32.,r1       / clear 32 bytes per loop
 306: 1:
 307:         clrf    (r0)+
 308:         clrf    (r0)+
 309:         clrf    (r0)+
 310:         clrf    (r0)+
 311:         sob     r1,1b
 312: 
 313:         ldfps   (sp)+                   / restore floating point status
 314:         br      4f
 315: 2:
 316:         mov     $MAXBSIZE\/8.,r1        / clear 8 bytes per loop
 317: 3:
 318:         clr     (r0)+
 319:         clr     (r0)+
 320:         clr     (r0)+
 321:         clr     (r0)+
 322:         sob     r1,1b
 323: 4:
 324: #ifdef DIAGNOSTIC
 325:         jmp     _mapout                 / map out buffer
 326: 
 327: #else
 328: 
 329:         mov     _seg5+SE_DESC,KDSD5     / normalseg5();
 330:         mov     _seg5+SE_ADDR,KDSA5
 331:         rts     pc
 332: #endif
 333: 
 334: 
 335: #ifdef DIAGNOSTIC
 336: SPACE(GLOBAL, _hasmap, 2)               / (struct bp *): SEG5 mapped
 337: #endif
 338: 
 339: /*
 340:  * caddr_t
 341:  * mapin(bp)
 342:  *	struct buf *bp;
 343:  *
 344:  * Map in an out-of-address space buffer.  If this is done
 345:  * from interrupt level, the previous map must be saved before
 346:  * mapin, and restored after mapout; e.g.
 347:  *	segm save;
 348:  *	saveseg5(save);
 349:  *	mapin(bp);
 350:  *	...
 351:  *	mapout(bp);
 352:  *	restorseg5(save);
 353:  *
 354:  *	caddr_t
 355:  *	mapin(bp)
 356:  *		register struct buf *bp;
 357:  *	{
 358:  *		register u_int paddr;
 359:  *		register u_int offset;
 360:  *
 361:  *	#ifdef DIAGNOSTIC
 362:  *		if (hasmap) {
 363:  *			printf("mapping %o over %o\n", bp, hasmap);
 364:  *			panic("mapin");
 365:  *		}
 366:  *		hasmap = bp;
 367:  *	#endif
 368:  *		offset = (u_int)bp->b_un.b_addr & 077;
 369:  *		paddr = bftopaddr(bp);
 370:  *		mapseg5((u_short)paddr,
 371:  *		    (u_short)(((u_int)DEV_BSIZE << 2) | (u_int)RW));
 372:  *		return(SEG5 + offset);
 373:  *	}
 374:  */
 375: ENTRY(mapin)
 376:         mov     2(sp),r0                / r0 = bp
 377: #ifdef DIAGNOSTIC
 378:         tst     _hasmap                 / is buffer already mapped in??
 379:         beq     9f
 380:         mov     _hasmap,-(sp)           / oops ... print out a message and die
 381:         mov     r0,-(sp)                /   with a panic
 382:         mov     $1f,-(sp)
 383:         STRING(LOCAL, 1, <mapping %o over %o\n\0>)
 384:         jsr     pc,_printf
 385:         cmp     (sp)+,(sp)+
 386:         mov     $1f,(sp)
 387:         STRING(LOCAL, 1, <mapin\0>)
 388:         jsr     pc,_panic
 389:         /*NOTREACHED*/
 390: 9:
 391:         mov     r0,_hasmap              / save mapin buffer address
 392: #endif
 393:         mov     B_ADDR(r0),r1           / r1 = bp->b_addr
 394:         movb    B_XMEM(r0),r0           / r0 = bp->b_xmem
 395:         mov     r1,-(sp)                / for later...
 396:         ashc    $-6,r0                  / r0:r1 = bftopaddr(bp)
 397:         mov     r1,KDSA5                / mapseg5((u_short)r0:r1,
 398:         mov     $DEV_BSIZE\<2|RW,KDSD5  /   (DEV_BSIZE << 2) | RW)
 399:         mov     (sp)+,r0
 400:         bic     $!077,r0                / return(SEG5 + (bp->b_un.b_addr&077))
 401:         add     $0120000,r0
 402:         rts     pc
 403: 
 404: 
 405: #ifdef DIAGNOSTIC
 406: /*
 407:  * Map out buffer pointed to by bp and restore previous mapping.
 408:  * Mapout is handled by a macro in seg.h if DIAGNOSTIC isn't defined.
 409:  *
 410:  *	#ifdef DIAGNOSTIC
 411:  *	void
 412:  *	mapout(bp)
 413:  *		struct buf *bp;
 414:  *	{
 415:  *		if (bp != hasmap) {
 416:  *			printf("unmapping %o, not %o\n", bp, hasmap);
 417:  *			panic("mapout");
 418:  *		}
 419:  *		hasmap = NULL;
 420:  *
 421:  *	normalseg5();
 422:  *	}
 423:  *	#endif
 424:  */
 425: ENTRY(mapout)
 426:         cmp     2(sp),_hasmap           / mapping out same buffer that was
 427:         beq     9f                      /   mapped in?
 428:         mov     _hasmap,-(sp)           / not good ... print out a message
 429:         mov     4(sp),-(sp)             /   and die
 430:         mov     $1f,-(sp)
 431:         STRING(LOCAL, 1, <unmapping %o; not %o\n\0>)
 432:         jsr     pc,_printf
 433:         cmp     (sp)+,(sp)+
 434:         mov     $1f,(sp)
 435:         STRING(LOCAL, 1, <mapout\0>)
 436:         jsr     pc,_panic
 437:         /*NOTREACHED*/
 438: 9:
 439:         clr     _hasmap                 / indicate mapping clear
 440:         mov     _seg5+SE_DESC,KDSD5     / normalseg5();
 441:         mov     _seg5+SE_ADDR,KDSA5
 442:         rts     pc
 443: #endif
 444: 
 445: 
 446: /*
 447:  * Save current SEG5 and SEG6 mapping in map and setup normal mapping.
 448:  *
 449:  * 	#define	KD6	(((USIZE-1)<<8) | RW)	/ proto descriptor for u.
 450:  *	savemap(map)
 451:  *		register mapinfo map;
 452:  *	{
 453:  *		map[0].se_desc = *KDSD5;
 454:  *		map[0].se_addr = *KDSA5;
 455:  *		map[1].se_desc = *KDSD6;
 456:  *		map[1].se_addr = *KDSA6;
 457:  *		if (kdsa6) {
 458:  *			*KDSD6 = KD6;
 459:  *			*KDSA6 = kdsa6;
 460:  *		}
 461:  *		normalseg5(seg5);
 462:  *	}
 463:  */
 464: ENTRY(savemap)
 465:         mov     2(sp),r0                / r0 = map
 466:         mov     KDSD5,(r0)+             / map[0].se_desc = *KDSD5
 467:         mov     KDSA5,(r0)+             / map[0].se_addr = *KDSA5
 468:         mov     KDSD6,(r0)+             / map[1].se_desc = *KDSD6
 469:         mov     KDSA6,(r0)              / map[1].se_addr = *KDSA6
 470:         tst     _kdsa6                  / SEG mapped out??
 471:         beq     9f
 472:         mov     $USIZE-1\<8|RW,KDSD6    / yep, map it in, *KDSD6 = (USIZE, RW)
 473:         mov     _kdsa6,KDSA6            /   *KDSA6 = kdsa6
 474: 9:
 475:         mov     _seg5+SE_DESC,KDSD5     / normalseg5();
 476:         mov     _seg5+SE_ADDR,KDSA5
 477:         rts     pc
 478: 
 479: /*
 480:  * Restore SEG5 and SEG6 mapping from map.
 481:  *
 482:  *	restormap(map)
 483:  *		register mapinfo map;
 484:  *	{
 485:  *		*KDSD5 = map[0].se_desc;
 486:  *		*KDSA5 = map[0].se_addr;
 487:  *		*KDSD6 = map[1].se_desc;
 488:  *		*KDSA6 = map[1].se_addr;
 489:  *	}
 490:  */
 491: ENTRY(restormap)
 492:         mov     2(sp),r0                / r0 = map
 493:         mov     (r0)+,KDSD5             / *KDSD5 = map[0].se_desc
 494:         mov     (r0)+,KDSA5             / *KDSA5 = map[0].se_addr
 495:         mov     (r0)+,KDSD6             / *KDSD6 = map[1].se_desc
 496:         mov     (r0),KDSA6              / *KDSA6 = map[1].se_addr
 497:         rts     pc
 498: 
 499: /*
 500:  * savfp(fps)
 501:  *	struct fps	*fps;
 502:  *
 503:  * Save current floating point processor state: floating point status register,
 504:  * and all six floating point registers.
 505:  */
 506: ENTRY(savfp)
 507:         tst     _fpp                    / do we really have floating point
 508:         beq     1f                      /   hardware??
 509: 
 510:         mov     2(sp),r1                / r1 = fps
 511:         stfps   (r1)+                   / save floating point status register
 512:         setd                            / (always save registers as double)
 513:         movf    fr0,(r1)+               / and save floating point registers
 514:         movf    fr1,(r1)+
 515:         movf    fr2,(r1)+
 516:         movf    fr3,(r1)+
 517:         movf    fr4,fr0
 518:         movf    fr0,(r1)+
 519:         movf    fr5,fr0
 520:         movf    fr0,(r1)+
 521: 1:
 522:         rts     pc
 523: 
 524: /*
 525:  * restfp(fps)
 526:  *	struct fps	*fps;
 527:  *
 528:  * Restore floating point processor state.
 529:  */
 530: ENTRY(restfp)
 531:         tst     _fpp                    / do we really have floating point
 532:         beq     1f                      /   hardware??
 533: 
 534:         mov     2(sp),r1                / r0 = r1 = fps
 535:         mov     r1,r0
 536:         setd                            / (we saved the registers as double)
 537:         add     $8.+2.,r1               / skip fpsr and fr0 for now
 538:         movf    (r1)+,fr1               / restore fr1 thru fr3
 539:         movf    (r1)+,fr2
 540:         movf    (r1)+,fr3
 541:         movf    (r1)+,fr0               / grab and restore saved fr4 and fr5
 542:         movf    fr0,fr4
 543:         movf    (r1)+,fr0
 544:         movf    fr0,fr5
 545:         movf    2(r0),fr0               / restore fr0
 546:         ldfps   (r0)                    /   and floating point status register
 547: 1:
 548:         rts     pc
 549: 
 550: /*
 551:  * stst(fperr)
 552:  *	struct fperr	*fperr;
 553:  *
 554:  * Save floating point error registers.  The argument is a pointer to a two
 555:  * word structure as defined in <pdp/fperr>.
 556:  */
 557: ENTRY(stst)
 558:         tst     _fpp                    / do we really have floating point
 559:         beq     1f                      /   hardware??
 560:         stst    *2(sp)                  / simple, no?
 561: 1:
 562:         rts     pc
 563: 
 564: /*
 565:  * scanc(size, str, table, mask)
 566:  * 	u_int size;
 567:  * 	u_char *str, table[];
 568:  * 	u_char mask;
 569:  *
 570:  * Scan through str up to (but not including str[size]) stopping when a
 571:  * character who's entry in table has mask bits set.  Return number of
 572:  * characters left in str.
 573:  */
 574: ENTRY(scanc)
 575:         mov     2(sp),r0                / r0 = size
 576:         beq     3f                      /   exit early if zero
 577:         mov     4(sp),r1                / r1 = str
 578:         mov     r2,-(sp)                / r2 = table
 579:         mov     6+2(sp),r2
 580:         mov     r3,-(sp)                / r3 = mask
 581:         mov     10+4(sp),r3
 582:         mov     r4,-(sp)                / r4 is temporary
 583: 1:                                      / do
 584:         clr     r4                      /   if (table[*str++] & mask)
 585:         bisb    (r1)+,r4
 586:         add     r2,r4
 587:         bitb    r3,(r4)
 588:         bne     2f                      /     break;
 589:         sob     r0,1b                   / while (--size != 0)
 590: 2:
 591:         mov     (sp)+,r4                / restore registers
 592:         mov     (sp)+,r3
 593:         mov     (sp)+,r2
 594: 3:
 595:         rts     pc                      / and return size
 596: 
 597: 
 598: /*
 599:  * locc(mask, size, str)
 600:  * 	u_char mask;
 601:  * 	u_int size;
 602:  * 	u_char *str;
 603:  *
 604:  * Scan through str up to (but not including str[size]) stopping when a
 605:  * character equals mask.  Return number of characters left in str.
 606:  */
 607: ENTRY(locc)
 608:         mov     4(sp),r0                / r0 = size
 609:         beq     3f                      /   exit early if zero
 610:         mov     6(sp),r1                / r1 = str
 611:         mov     r2,-(sp)                / r2 = mask
 612:         mov     2+2(sp),r2
 613: 1:                                      / do
 614:         cmpb    (r1)+,r2                /   if (*str++ == mask)
 615:         beq     2f
 616:         sob     r0,1b                   / while (--size != 0)
 617: 2:
 618:         mov     (sp)+,r2                / restore registers
 619: 3:
 620:         rts     pc                      / and return size
 621: 
 622: /*
 623:  * nextiv()
 624:  *
 625:  * Decrement _lastiv by size of a vector (4) and return the new value.
 626:  * Placed here for centralized access and easy calling from the networking
 627:  * (via SKcall) and 'autoconfig' (via ucall).
 628: */
 629: ENTRY(nextiv)
 630:         sub     $4,_lastiv              / adjust last interrupt vector
 631:         mov     _lastiv,r0              / put in right place for return value
 632:         rts     pc                      / return assigned vector
 633: 
 634: /*
 635:  * vattr_null()
 636:  *
 637:  * Initialize a inode attribute structure.  See the comments in h/inode.h
 638:  * for more details.  If the vnode/inode attribute structure (which is a
 639:  * subset of 4.4's) changes then this routine must change also.  The 'sxt'
 640:  * sequences below are shorter/faster than "mov $VNOVAL,..." since VNOVAL
 641:  * is -1.
 642: */
 643: ENTRY(vattr_null)
 644:         mov     2(sp),r0                / get address of vattr structure
 645:         mov     $-1,(r0)+               / va_mode = VNOVAL
 646:         sxt     (r0)+                   / va_uid = VNOVAL
 647:         sxt     (r0)+                   / va_gid = VNOVAL
 648:         sxt     (r0)+                   / va_size - hi = VNOVAL
 649:         sxt     (r0)+                   / va_size - lo = VNOVAL
 650:         sxt     (r0)+                   / va_atime - hi = VNOVAL
 651:         sxt     (r0)+                   / va_atime - lo = VNOVAL
 652:         sxt     (r0)+                   / va_mtime - hi = VNOVAL
 653:         sxt     (r0)+                   / va_mtime - lo = VNOVAL
 654:         sxt     (r0)+                   / va_flags = VNOVAL
 655:         clr     (r0)+                   / va_vaflags = 0
 656:         rts     pc

Defined functions

_addupc defined in line 203; used 3 times
_clrbuf defined in line 295; used 3 times
_copystr defined in line 266; used 2 times
_delay defined in line 27; never used
_idle defined in line 61; used 1 times
_locc defined in line 607; never used
_longjmp defined in line 143; used 3 times
_mapout defined in line 425; used 1 times
_nextiv defined in line 629; used 4 times
_noop defined in line 44; used 2 times
_restfp defined in line 530; used 2 times
_resume defined in line 144; never used
_savemap defined in line 464; never used
_scanc defined in line 574; used 1 times
_stst defined in line 557; used 1 times
_vattr_null defined in line 643; used 1 times

Defined variables

_hasmap defined in line 336; used 9 times
rdisply defined in line 58; used 3 times
wcount defined in line 59; used 2 times
Last modified: 1994-12-16
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3992
Valid CSS Valid XHTML 1.0 Strict