1: /* 2: * SCCS id @(#)mch.s 2.1 (Berkeley) 12/21/83 3: * 4: * Machine language assist. 5: * Uses the C preprocessor to produce suitable code 6: * for various 11's, mainly dependent on definition 7: * of PDP11, MENLO_KOV and NONSEPARATE. 8: */ 9: 10: #define LOCORE 11: #include "whoami.h" /* for localopts */ 12: 13: #if PDP11==GENERIC /* adapt to any 11 at boot */ 14: # undef NONSEPARATE /* support sep I/D */ 15: # define SPLHIGH bis $HIPRI,PS 16: # define SPL7 bis $340,PS 17: # define SPLLOW bic $HIPRI,PS 18: # ifdef UCB_NET 19: # define SPLNET bis $NETPRI,PS 20: # endif 21: #else 22: # ifdef NONSEPARATE /* 11/40, 34, 23, 24 */ 23: # define SPLHIGH bis $HIPRI,PS 24: # define SPL7 bis $340,PS 25: # define SPLLOW bic $HIPRI,PS 26: # ifdef UCB_NET 27: # define SPLNET bis $NETPRI,PS 28: # endif 29: # define mfpd mfpi 30: # define mtpd mtpi 31: # else /* 11/44, 11/45, 11/70 */ 32: # define SPLHIGH spl HIGH 33: # define SPL7 spl 7 34: # define SPLLOW spl 0 35: # ifdef UCB_NET 36: # define SPLNET spl NET 37: # endif 38: # endif 39: #endif 40: 41: #include "ht.h" 42: #include "tm.h" 43: #include "ts.h" 44: #include <a.out.h> 45: #include <sys/cpu.m> 46: #include <sys/trap.h> 47: #include <sys/reboot.h> 48: #include <sys/iopage.m> 49: #ifdef MENLO_KOV 50: #include <sys/koverlay.h> 51: #endif 52: 53: #define INTSTK 500. /* bytes for interrupt stack */ 54: 55: /* 56: * non-UNIX instructions 57: */ 58: mfpi = 6500^tst 59: mtpi = 6600^tst 60: #ifndef NONSEPARATE 61: mfpd = 106500^tst 62: mtpd = 106600^tst 63: #endif 64: stst = 170300^tst 65: spl = 230 66: ldfps = 170100^tst 67: stfps = 170200^tst 68: mfpt = 000007 / Move from processor - 44s only 69: mfps = 106700^tst / Move from PS - 11/23,24,34's only 70: mtps = 106400^tst / Move to PS - 11/23,24,34's only 71: halt = 0 72: wait = 1 73: iot = 4 74: reset = 5 75: rtt = 6 76: 77: #ifdef PROFILE 78: #define HIGH 6 / See also the :splfix files 79: #define HIPRI 300 / Many spl's are done in-line 80: #else 81: #define HIGH 7 82: #define HIPRI 340 83: #endif PROFILE 84: #ifdef UCB_NET 85: #define NET 1 86: #define NETPRI 40 87: #endif 88: 89: /* 90: * Mag tape dump 91: * Save registers in low core and write core (up to 248K) onto mag tape. 92: * Entry is through 044 (physical) with memory management off. 93: */ 94: .globl dump 95: 96: #ifndef KERN_NONSEP 97: .data 98: #endif 99: 100: dump: 101: #if NHT > 0 || NTM > 0 || NTS > 0 102: / save regs r0, r1, r2, r3, r4, r5, r6, KIA6 103: / starting at location 4 (physical) 104: inc $-1 / check for first time 105: bne 1f / if not, don't save registers again 106: mov r0,4 107: mov $6,r0 108: mov r1,(r0)+ 109: mov r2,(r0)+ 110: mov r3,(r0)+ 111: mov r4,(r0)+ 112: mov r5,(r0)+ 113: mov sp,(r0)+ 114: mov KDSA6,(r0)+ 115: 1: 116: 117: / dump all of core (i.e. to first mt error) 118: / onto mag tape. (9 track or 7 track 'binary') 119: #if NHT > 0 120: HT = 0172440 121: HTCS1 = HT+0 122: HTWC = HT+2 123: HTBA = HT+4 124: HTFC = HT+6 125: HTCS2 = HT+10 126: HTTC = HT+32 127: mov $HTCS1,r0 128: mov $40,*$HTCS2 129: mov $2300,*$HTTC 130: clr *$HTBA 131: mov $1,(r0) 132: 1: 133: mov $-512.,*$HTFC 134: mov $-256.,*$HTWC 135: movb $61,(r0) 136: 2: 137: tstb (r0) 138: bge 2b 139: bit $1,(r0) 140: bne 2b 141: bit $40000,(r0) 142: beq 1b 143: mov $27,(r0) 144: #else 145: 146: #if NTM > 0 147: MTC = 172522 148: mov $MTC,r0 149: mov $60004,(r0)+ 150: clr 2(r0) 151: 1: 152: mov $-512.,(r0) 153: inc -(r0) 154: 2: 155: tstb (r0) 156: bge 2b 157: tst (r0)+ 158: bge 1b 159: reset 160: 161: / end of file and loop 162: mov $60007,-(r0) 163: #else 164: #if NTS > 0 165: TSDB = 0172520 166: TSSR = 0172522 167: 168: /register usage is as follows 169: 170: /reg 0 points to UBMAP register 1 low 171: /reg 1 is used to calculate the current memory address 172: / for each 512 byte transfer. 173: /reg 2 is used to contain and calculate memory pointer 174: / for UBMAP register 1 low 175: /reg 3 is used to contain and calculate memory pointer 176: / for UBMAP register 1 high 177: /reg 4 points to the command packet 178: /reg 5 is used as an interation counter when mapping is enabled 179: 180: 181: cmp _cputype,$44. /is a 44 ? 182: beq 1f /yes, skip next 183: cmp _cputype,$70. /is a 70 ? 184: bne 2f /not a 70 either. no UBMAP 185: 1: 186: / tst _ubmaps /unibus map present ? 187: / beq 2f /no, skip map init 188: /this section of code initializes the Unibus map registers 189: /and the memory management registers. 190: /UBMAP reg 0 points to low memory for the TS11 command, 191: /characteristics, and message buffers. 192: /UBMAP reg 1 gets updated to point to the current 193: /memory area. 194: /Kernel I space 0 points to low memory 195: /Kernel I space 7 points to the I/O page. 196: 197: inc setmap /indicate that UB mapping is needed 198: mov $UBMR0,r0 /point to map register 0 199: clr r2 /init for low map reg 200: clr r3 /init for high map reg 201: clr (r0)+ /load map reg 0 low 202: clr (r0)+ /load map reg 0 high 203: mov $77406,*$KISD0 /set KISDR0 204: mov $77406,*$KISD7 /set KISDR7 205: clr *$KISA0 /point KISAR0 to low memory 206: mov $IO,*$KISA7 /point KISAR7 to IO page 207: inc *$SSR0 /turn on memory mngt 208: mov $60,*$SSR3 /enable 22 bit mapping 209: mov r2,(r0) /load map reg 1 low 210: mov r3,2(r0) /load map reg 1 high 211: 2: 212: /this section of code initializes the TS11 213: 214: tstb *$TSSR /make sure 215: bpl 2b /drive is ready 216: mov $comts,r4 /point to command packet 217: add $2,r4 /set up mod 4 218: bic $3,r4 /alignment 219: mov $140004,(r4) /write characteristics command 220: mov $chrts,2(r4) /characteristics buffer 221: clr 4(r4) /clear ext mem addr (packet) 222: clr tsxma /clear extended memory save loc 223: mov $10,6(r4) /set byte count for command 224: mov $mests,*$chrts /show where message buffer is 225: clr *$chrts+2 /clear extended memory bits here too 226: mov $16,*$chrts+4 /set message buffer length 227: mov r4,*$TSDB /start command 228: mov $20,r5 /set up SOB counter for UBMAP 229: clr r1 /init r1 beginning memory address 230: 1: 231: tstb *$TSSR /wait for ready 232: bpl 1b /not yet 233: mov *$TSSR,tstcc /error condition (SC) ? 234: bpl 2f /no error 235: bic $!16,tstcc /yes error, get TCC 236: cmp tstcc,$10 /recoverable error ? 237: bne 8f /no 238: mov $101005,(r4) /yes, load write data retry command 239: clr 4(r4) /clear packet ext mem addr 240: mov r4,*$TSDB /start retry 241: br 1b 242: 8: 243: bit $4000,*$TSSR /is error NXM ? 244: beq . /no, hang (not sure of good dump) 245: mov $140013,(r4) /load a TS init command 246: mov r4,*$TSDB /to clear NXM error 247: 6: 248: tstb *$TSSR /wait for ready 249: bpl 6b 250: mov $1,6(r4) /set word count = 1 251: mov $100011,(r4) /load write EOF command 252: mov r4,*$TSDB /do write EOF 253: 7: 254: tstb *$TSSR /wait for ready 255: bpl 7b 256: halt /halt after good dump 257: 9: 258: br 1b 259: 2: 260: /If mapping is needed this section calculates the 261: / base address to be loaded into map reg 1 262: / the algorithm is (!(r5 - 21))*1000) | 20000 263: / the complement is required because an SOB loop 264: / is being used for the counter 265: /This loop causes 20000 bytes to be written 266: /before the UBMAP is updated. 267: 268: tst setmap /UBMAP ? 269: beq 3f /no map 270: mov r2,(r0) /load map reg 1 low 271: mov r3,2(r0) /load map reg 1 high 272: mov r5,r1 /calculate 273: sub $21,r1 /address for this pass 274: com r1 /based on current 275: mul $1000,r1 /interation 276: bis $20000,r1 /select map register 1 277: clr 4(r4) /clear extended memory bits 278: 3: 279: /This section does the write. 280: / if mapping is needed the sob loop comes in play here 281: / when the sob falls through the UBAMP reg will be 282: / updated by 20000 to point to next loop section. 283: 284: / if mapping not needed then just calculate the 285: / next 512 byte address pointer 286: 287: mov r1,2(r4) /load mem address 288: mov tsxma,4(r4) /load ext mem address 289: mov $512.,6(r4) /set byte count 290: mov $100005,(r4) /set write command 291: mov r4,*$TSDB /initiate xfer 292: tst setmap /mapping? 293: beq 4f /branch if not 294: sob r5,9b /yes continue loop 295: mov $20,r5 /reset loop count 296: add $20000,r2 /bump low map 297: adc r3 /carry to high map 298: br 1b /do some more 299: 4: 300: add $512.,r1 /bump address for no mapping 301: adc tsxma /carry to extended memory bits 302: br 1b /do again 303: 304: / The following TS11 command and message buffers, 305: / must be in initialized data space instead of 306: / bss space. This allows them to be mapped by the 307: / first M/M mapping register, which is the only one 308: / used durring a core dump. 309: 310: tsxma: 0 /ts11 extended memory address bits 311: setmap: 0 /UB map usage indicator 312: tstcc: 0 /ts11 temp location for TCC 313: comts: /ts11 command packet 314: 0 ; 0 ; 0 ; 0 ; 0 315: chrts: /ts11 characteristics 316: 0 ; 0 ; 0 ; 0 317: mests: /ts11 message buffer 318: 0 ; 0 ; 0 ; 0 ; 0 ; 0 ; 0 319: #endif NTS 320: #endif NTM 321: #endif NHT 322: #endif NHT || NTM 323: br . / If no ht and no tm, fall through to here 324: 325: .text 326: 327: #ifdef UCB_AUTOBOOT 328: /* 329: * routine to call panic, take dump and reboot; 330: * entered by manually loading the PC with 040 and continuing 331: */ 332: .globl _panic, _halt, do_panic, _halt 333: do_panic: 334: mov $pmesg, -(sp) 335: jsr pc, _panic 336: /* NOTREACHED */ 337: 338: .data 339: pmesg: <forced from console\0> 340: .text 341: 342: _halt: 343: halt 344: /* NOTREACHED */ 345: rts pc 346: #endif UCB_AUTOBOOT 347: 348: .globl _etext, _main, start 349: #ifdef MENLO_KOV 350: .globl ovend, ova, ovd 351: #endif 352: 353: start: 354: bit $1,SSR0 / is memory management enabled ? 355: beq . / better be !!! 356: 357: / The following two instructions change the contents of 358: / locations 034-037 to read: 359: / syscall; br0+SYSCALL. 360: mov $syscall, 34 361: mov $0+SYSCALL., 36 362: 363: / Turn off write permission on kernel text 364: movb $RO, KISD0 365: 366: / Get a stack pointer 367: mov $usize-1\<8|RW, KDSD6 368: mov $_u+[usize*64.],sp 369: 370: / Clear user block 371: mov $_u,r0 372: 1: 373: clr (r0)+ 374: cmp r0,sp 375: blo 1b 376: 377: #ifdef UCB_AUTOBOOT 378: .globl _bootflags, _checkword 379: 380: / Get bootflags; the bootstrap leave them in r4. 381: / R2 should be the complement of bootflags. 382: mov r4,_bootflags 383: mov r2,_checkword 384: #endif 385: 386: / Check out (and if necessary, set up) the hardware. 387: jsr pc, hardprobe 388: 389: / Set up previous mode and call main 390: / on return, enter user mode at 0R 391: mov $30340,PS 392: jsr pc,_main 393: mov $170000,-(sp) 394: clr -(sp) 395: rtt 396: 397: #if defined(MENLO_OVLY) || (defined(NONFP) && !defined(NONSEPARATE)) 398: /* 399: * Emt takes emulator traps, which are normally requests 400: * to change the overlay for the current process. 401: * Emts are also generated by the separate I/D floating 402: * point simulator in fetching instructions from user 403: * I space. In this case, r0 should be -1 and r1 should 404: * contain the pc of the instruction to be fetched. 405: * If an invalid emt is received, _trap is called. 406: */ 407: .globl _choverl, emt 408: emt: 409: mov PS,saveps 410: bit $30000,PS / verify that emt is not kernel mode 411: beq bademt 412: #ifdef MENLO_OVLY 413: tst _u+U_OVBASE / verify that process is overlaid 414: beq fetchi 415: cmp r0,$NOVL / verify valid overlay number 416: bhi fetchi 417: SPLLOW 418: mov r0,-(sp) 419: mov r1,-(sp) 420: mov r0,_u+U_CUROV 421: #ifdef UCB_METER 422: inc _cnt+V_OVLY 423: #endif 424: mov $RO,-(sp) 425: jsr pc,_choverl 426: tst (sp)+ 427: mov (sp)+,r1 428: mov (sp)+,r0 429: rtt 430: #endif MENLO_OVLY 431: 432: fetchi: 433: #if defined(NONFP) && !defined(NONSEPARATE) 434: cmp $-1, r0 435: bne bademt 436: mov $1f,nofault 437: mfpi (r1) / get I-space at (r1) 438: mov (sp)+,r0 / put result in r0 439: clr nofault 440: rtt 441: 442: 1: 443: clr nofault 444: /* FALL THROUGH */ 445: #endif defined(NONFP) && !defined(NONSEPARATE) 446: bademt: 447: jsr r0, call1; jmp _trap / invalid emt 448: /*NOTREACHED*/ 449: #endif defined(MENLO_OVLY) || (defined(NONFP) && !defined(NONSEPARATE)) 450: 451: .globl syscall, trap, buserr, _syscall, _trap, _panic, _panicstr 452: /* 453: * System call interface to C code. 454: */ 455: syscall: 456: mov r0, -(sp) 457: #ifdef MENLO_KOV 458: cmp -(sp), -(sp) / Dummy arguments. See trap.c for explanation. 459: #else 460: tst -(sp) / Dummy argument. 461: #endif 462: mov r1, -(sp) 463: mfpd sp 464: tst -(sp) / Dummy argument. 465: jsr pc, _syscall 466: tst (sp)+ 467: mtpd sp 468: mov (sp)+, r1 469: #ifdef MENLO_KOV 470: cmp (sp)+, (sp)+ 471: #else 472: tst (sp)+ 473: #endif 474: mov (sp)+, r0 475: rtt 476: 477: #ifdef NONFP 478: /* 479: * Fast illegal-instruction trap routine for use with interpreted 480: * floating point. All of the work is done here if SIGILL is caught, 481: * otherwise, trap is called like normal. 482: */ 483: .globl instrap 484: instrap: 485: mov PS, saveps 486: tst nofault 487: bne 1f / branch to trap code 488: bit $30000, PS / verify not from kernel mode 489: beq 3f 490: SPLLOW 491: tst _u+U_SIGILL / check whether SIGILL is being caught 492: beq 3f / is default 493: bit $1, _u+U_SIGILL 494: bne 3f / is ignored (or held or deferred!) 495: mov r0, -(sp) 496: mfpd sp 497: #ifdef UCB_METER 498: inc _cnt+V_TRAP 499: inc _cnt+V_INTR / since other traps also count as intr 500: #endif 501: mov (sp), r0 502: sub $2, r0 503: mov $2f, nofault 504: mov 6(sp), -(sp) 505: mtpd (r0) / push old PS 506: sub $2, r0 507: mov 4(sp), -(sp) 508: mtpd (r0) / push old PC 509: mov _u+U_SIGILL, 4(sp) / new PC 510: bic $TBIT, 6(sp) / new PS 511: mov r0, (sp) 512: mtpd sp / set new user SP 513: mov (sp)+, r0 514: clr nofault 515: rtt 516: 2: / back out on error 517: clr nofault 518: tst (sp)+ / pop user's sp 519: mov (sp)+, r0 520: 3: 521: jsr r0, call1; jmp _trap / call trap on bad SIGILL 522: /*NOTREACHED*/ 523: #endif 524: buserr: 525: mov PS,saveps 526: bit $30000,PS 527: bne 2f / if previous mode != kernel 528: tst nofault 529: bne 1f 530: tst sp 531: bne 3f 532: / Kernel stack invalid. 533: tst _panicstr 534: beq 4f 535: br . / Already paniced, don't overwrite anything 536: 4: 537: / Find a piece of stack so we can panic. 538: mov $intstk+[INTSTK\/2], sp 539: mov $redstak, -(sp) 540: jsr pc, _panic 541: /*NOTREACHED*/ 542: .data 543: redstak: <kernel red stack violation\0> 544: .text 545: 546: /* 547: * Traps without specialized catchers get vectored here. 548: */ 549: trap: 550: mov PS,saveps 551: 2: 552: tst nofault 553: bne 1f 554: 3: 555: mov SSR0,ssr 556: #ifndef KERN_NONSEP 557: mov SSR1,ssr+2 558: #endif 559: mov SSR2,ssr+4 560: mov $1,SSR0 561: jsr r0, call1; jmp _trap 562: /*NOTREACHED*/ 563: 1: 564: mov $1,SSR0 565: mov nofault,(sp) 566: rtt 567: 568: .globl call, _runrun 569: call1: 570: mov saveps, -(sp) 571: SPLLOW 572: br 1f 573: 574: call: 575: mov PS, -(sp) 576: 1: 577: #ifdef MENLO_KOV 578: mov __ovno,-(sp) / save overlay number 579: #endif 580: mov r1,-(sp) 581: mfpd sp 582: #ifdef UCB_METER 583: .globl _cnt 584: inc _cnt+V_INTR / count device interrupts 585: #endif UCB_METER 586: #ifdef MENLO_KOV 587: mov 6(sp), -(sp) 588: #else 589: mov 4(sp), -(sp) 590: #endif 591: bic $!37,(sp) 592: bit $30000,PS 593: beq 1f 594: jsr pc,(r0)+ 595: #ifdef UCB_NET 596: jsr pc,checknet 597: #endif 598: tstb _runrun 599: beq 2f 600: mov $SWITCHTRAP.,(sp) / give up cpu 601: jsr pc,_trap 602: 2: 603: tst (sp)+ 604: mtpd sp 605: br 2f 606: 1: 607: bis $30000,PS 608: jsr pc,(r0)+ 609: #ifdef UCB_NET 610: jsr pc,checknet 611: #endif 612: cmp (sp)+,(sp)+ 613: 2: 614: mov (sp)+,r1 615: #ifdef MENLO_KOV 616: / Restore previous overlay number and mapping. 617: mov (sp)+,r0 / get saved overlay number 618: cmp r0,__ovno 619: beq 1f 620: mov PS,-(sp) / save PS 621: SPL7 622: mov r0,__ovno 623: asl r0 624: mov ova(r0), OVLY_PAR 625: mov ovd(r0), OVLY_PDR 626: mov (sp)+,PS / restore PS, unmask interrupts 627: 1: 628: #endif MENLO_KOV 629: tst (sp)+ 630: mov (sp)+,r0 631: rtt 632: 633: #ifdef UCB_AUTOBOOT 634: /* 635: * Power fail handling. On power down, we just set up for the next trap. 636: */ 637: #define PVECT 24 /* power fail vector */ 638: .globl powrdown, powrup, _panicstr, _rootdev, hardboot 639: .text 640: powrdown: 641: mov $powrup,PVECT 642: SPL7 643: br . 644: 645: /* 646: * Power back on... wait a bit, then attempt a reboot. 647: * Can't do much since memory management is off 648: * (hence we are in "data" space). 649: */ 650: #ifndef KERN_NONSEP 651: .data 652: #endif 653: powrup: 654: mov $-1,r0 655: 1: 656: dec r0 657: bne 1b 658: 659: mov $RB_POWRFAIL, r4 660: mov _rootdev,r3 661: jsr pc,hardboot 662: /* NOTREACHED */ 663: .text 664: #endif UCB_AUTOBOOT 665: 666: #ifdef UCB_NET 667: .globl _netisr,_netintr 668: checknet: 669: mov PS,-(sp) 670: SPL7 671: tst _netisr / net requesting soft interrupt 672: beq 3f 673: #ifdef MENLO_KOV 674: bit $340,18.(sp) 675: #else 676: bit $340,16.(sp) 677: #endif 678: bne 3f / if prev spl not 0 679: SPLNET 680: jsr pc,*$_netintr 681: 3: 682: mov (sp)+,PS 683: rts pc 684: #endif 685: 686: #include "dz.h" 687: #if NDZ > 0 && defined(DZ_PDMA) 688: /* 689: * DZ-11 pseudo-DMA interrupt routine. 690: * Called directly from the interrupt vector; 691: * the device number is in the low bits of the PS. 692: * Calls dzxint when the end of the buffer is reached. 693: * The pdma structure is known to be: 694: * struct pdma { 695: * struct dzdevice *p_addr; 696: * char *p_mem; 697: * char *p_end; 698: * struct tty *p_arg; 699: * }; 700: */ 701: .globl dzdma, _dzpdma, _dzxint 702: dzdma: 703: mov PS, -(sp) 704: mov r0, -(sp) 705: #ifdef MENLO_KOV 706: mov __ovno, -(sp) 707: #endif 708: mov r1, -(sp) 709: mov r2, -(sp) 710: mov r3, -(sp) 711: #ifdef MENLO_KOV 712: mov 12(sp), r3 / new PS 713: #else 714: mov 10(sp), r3 / new PS 715: #endif 716: #ifdef UCB_METER 717: inc _cnt+V_PDMA / count pseudo-DMA interrupts 718: #endif UCB_METER 719: bic $!37, r3 / extract device number 720: ash $3+3, r3 / get offset into dzpdma 721: add $_dzpdma, r3 / for first line 722: mov (r3)+, r2 / dzaddr in r2; r3 points to p_mem 723: 724: #ifdef UCB_CLIST 725: .globl _clststrt, _clstdesc 726: mov KDSA5, -(sp) / save previous mapping 727: mov KDSD5, -(sp) 728: mov _clststrt, KDSA5 / map in clists 729: mov _clstdesc, KDSD5 730: #endif UCB_CLIST 731: 732: / loop until no line is ready 733: 1: 734: movb 1(r2), r1 / dzcsr high byte 735: bge 3f / test TRDY; branch if none 736: bic $!7, r1 / extract line number 737: ash $3, r1 / convert to pdma offset 738: add r3, r1 / r1 is pointer to pdma.p_mem for line 739: mov (r1)+, r0 / pdma->p_mem 740: cmp r0, (r1)+ / cmp p_mem to p_end 741: bhis 2f / if p_mem >= p_end 742: movb (r0)+, 6(r2) / dztbuf = *p_mem++ 743: mov r0, -4(r1) / update p_mem 744: br 1b 745: 746: / buffer is empty; call dzxint 747: 2: 748: mov (r1), -(sp) / p_arg 749: jsr pc, _dzxint / r0, r1 are modified! 750: tst (sp)+ 751: br 1b 752: 753: / no more lines ready; return 754: 3: 755: #ifdef UCB_CLIST 756: mov (sp)+, KDSD5 757: mov (sp)+, KDSA5 / restore previous mapping 758: #endif UCB_CLIST 759: mov (sp)+, r3 760: mov (sp)+, r2 761: mov (sp)+, r1 762: #ifdef MENLO_KOV 763: SPL7 764: mov (sp)+, r0 765: cmp r0, __ovno 766: beq 1f 767: mov r0, __ovno 768: asl r0 769: mov ova(r0), OVLY_PAR 770: mov ovd(r0), OVLY_PDR 771: 1: 772: #endif 773: mov (sp)+, r0 774: tst (sp)+ 775: rtt 776: #endif DZ_PDMA 777: 778: #ifndef NONFP 779: .globl _savfp, _restfp, _stst 780: _savfp: 781: tst fpp 782: beq 9f / No FP hardware 783: mov 2(sp),r1 784: stfps (r1)+ 785: setd 786: movf fr0,(r1)+ 787: movf fr1,(r1)+ 788: movf fr2,(r1)+ 789: movf fr3,(r1)+ 790: movf fr4,fr0 791: movf fr0,(r1)+ 792: movf fr5,fr0 793: movf fr0,(r1)+ 794: 9: 795: rts pc 796: 797: _restfp: 798: tst fpp 799: beq 9f 800: mov 2(sp),r1 801: mov r1,r0 802: setd 803: add $8.+2.,r1 804: movf (r1)+,fr1 805: movf (r1)+,fr2 806: movf (r1)+,fr3 807: movf (r1)+,fr0 808: movf fr0,fr4 809: movf (r1)+,fr0 810: movf fr0,fr5 811: movf 2(r0),fr0 812: ldfps (r0) 813: 9: 814: rts pc 815: 816: /* 817: * Save floating poing error registers. 818: * The argument is a pointer to a two word 819: * structure. 820: */ 821: _stst: 822: tst fpp 823: beq 9f 824: stst *2(sp) 825: 9: 826: rts pc 827: 828: #endif NONFP 829: 830: .globl _addupc 831: _addupc: 832: mov r2,-(sp) 833: mov 6(sp),r2 / base of prof with base,leng,off,scale 834: mov 4(sp),r0 / pc 835: sub 4(r2),r0 / offset 836: clc 837: ror r0 838: mov 6(r2),r1 839: clc 840: ror r1 841: mul r1,r0 / scale 842: ashc $-14.,r0 843: inc r1 844: bic $1,r1 845: cmp r1,2(r2) / length 846: bhis 1f 847: add (r2),r1 / base 848: mov nofault,-(sp) 849: mov $2f,nofault 850: mfpd (r1) 851: add 12.(sp),(sp) 852: mtpd (r1) 853: br 3f 854: 2: 855: clr 6(r2) 856: 3: 857: mov (sp)+,nofault 858: 1: 859: mov (sp)+,r2 860: rts pc 861: 862: #ifdef DISPLAY 863: .globl _display 864: _display: 865: dec dispdly 866: bge 2f 867: clr dispdly 868: mov PS,-(sp) 869: SPLHIGH 870: mov CSW,r1 871: bit $1,r1 872: beq 1f 873: bis $30000,PS 874: dec r1 875: 1: 876: jsr pc,fuword 877: mov r0,CSW 878: mov (sp)+,PS 879: cmp r0,$-1 880: bne 2f 881: mov $120.,dispdly / 2 second delay after CSW fault 882: 2: 883: rts pc 884: #endif 885: 886: .globl _regloc, _backup 887: #ifndef KERN_NONSEP 888: /* 889: * Backup routine for use with machines with ssr2. 890: */ 891: _backup: 892: mov 2(sp),r0 893: movb ssr+2,r1 894: jsr pc,1f 895: movb ssr+3,r1 896: jsr pc,1f 897: movb _regloc+7,r1 898: asl r1 899: add r0,r1 900: mov ssr+4,(r1) 901: clr r0 902: 2: 903: rts pc 904: 1: 905: mov r1,-(sp) 906: asr (sp) 907: asr (sp) 908: asr (sp) 909: bic $!7,r1 910: movb _regloc(r1),r1 911: asl r1 912: add r0,r1 913: sub (sp)+,(r1) 914: rts pc 915: 916: #else KERN_NONSEP 917: /* 918: * 11/40 version of backup, for use with no SSR2 919: */ 920: _backup: 921: mov 2(sp),ssr+2 922: mov r2,-(sp) 923: jsr pc,backup 924: mov r2,ssr+2 925: mov (sp)+,r2 926: movb jflg,r0 927: bne 2f 928: mov 2(sp),r0 929: movb ssr+2,r1 930: jsr pc,1f 931: movb ssr+3,r1 932: jsr pc,1f 933: movb _regloc+7,r1 934: asl r1 935: add r0,r1 936: mov ssr+4,(r1) 937: clr r0 938: 2: 939: rts pc 940: 1: 941: mov r1,-(sp) 942: asr (sp) 943: asr (sp) 944: asr (sp) 945: bic $!7,r1 946: movb _regloc(r1),r1 947: asl r1 948: add r0,r1 949: sub (sp)+,(r1) 950: rts pc 951: 952: / Hard part: simulate the ssr2 register missing on 11/40. 953: backup: 954: clr r2 / backup register ssr1 955: mov $1,bflg / clrs jflg 956: clrb fflg 957: mov ssr+4,r0 958: jsr pc,fetch 959: mov r0,r1 960: ash $-11.,r0 961: bic $!36,r0 962: jmp *0f(r0) 963: 0: t00; t01; t02; t03; t04; t05; t06; t07 964: t10; t11; t12; t13; t14; t15; t16; t17 965: 966: t00: 967: clrb bflg 968: 969: t10: 970: mov r1,r0 971: swab r0 972: bic $!16,r0 973: jmp *0f(r0) 974: 0: u0; u1; u2; u3; u4; u5; u6; u7 975: 976: u6: / single op, m[tf]pi, sxt, illegal 977: bit $400,r1 978: beq u5 / all but m[tf], sxt 979: bit $200,r1 980: beq 1f / mfpi 981: bit $100,r1 982: bne u5 / sxt 983: 984: / Simulate mtpi with double (sp)+,dd. 985: bic $4000,r1 / turn instr into (sp)+ 986: br t01 987: 988: / Simulate mfpi with double ss,-(sp). 989: 1: 990: ash $6,r1 991: bis $46,r1 / -(sp) 992: br t01 993: 994: u4: / jsr 995: mov r1,r0 996: jsr pc,setreg / assume no fault 997: bis $173000,r2 / -2 from sp 998: rts pc 999: 1000: t07: / EIS 1001: clrb bflg 1002: 1003: u0: / jmp, swab 1004: u5: / single op 1005: #ifndef NONFP 1006: f5: / movei, movfi 1007: ff1: / ldfps 1008: ff2: / stfps 1009: ff3: / stst 1010: #endif 1011: mov r1,r0 1012: br setreg 1013: 1014: t01: / mov 1015: t02: / cmp 1016: t03: / bit 1017: t04: / bic 1018: t05: / bis 1019: t06: / add 1020: t16: / sub 1021: clrb bflg 1022: 1023: t11: / movb 1024: t12: / cmpb 1025: t13: / bitb 1026: t14: / bicb 1027: t15: / bisb 1028: mov r1,r0 1029: ash $-6,r0 1030: jsr pc,setreg 1031: swab r2 1032: mov r1,r0 1033: jsr pc,setreg 1034: 1035: / If delta(dest) is zero, no need to fetch source. 1036: bit $370,r2 1037: beq 1f 1038: 1039: / If mode(source) is R, no fault is possible. 1040: bit $7000,r1 1041: beq 1f 1042: 1043: / If reg(source) is reg(dest), too bad. 1044: mov r2,-(sp) 1045: bic $174370,(sp) 1046: cmpb 1(sp),(sp)+ 1047: beq u7 1048: 1049: / Start source cycle. Pick up value of reg. 1050: mov r1,r0 1051: ash $-6,r0 1052: bic $!7,r0 1053: movb _regloc(r0),r0 1054: asl r0 1055: add ssr+2,r0 1056: mov (r0),r0 1057: 1058: / If reg has been incremented, must decrement it before fetch. 1059: bit $174000,r2 1060: ble 2f 1061: dec r0 1062: bit $10000,r2 1063: beq 2f 1064: dec r0 1065: 2: 1066: 1067: / If mode is 6,7 fetch and add X(R) to R. 1068: bit $4000,r1 1069: beq 2f 1070: bit $2000,r1 1071: beq 2f 1072: mov r0,-(sp) 1073: mov ssr+4,r0 1074: add $2,r0 1075: jsr pc,fetch 1076: add (sp)+,r0 1077: 2: 1078: 1079: / Fetch operand. If mode is 3, 5, or 7, fetch *. 1080: jsr pc,fetch 1081: bit $1000,r1 1082: beq 1f 1083: bit $6000,r1 1084: bne fetch 1085: 1: 1086: rts pc 1087: 1088: t17: / floating point instructions 1089: #ifndef NONFP 1090: clrb bflg 1091: mov r1,r0 1092: swab r0 1093: bic $!16,r0 1094: jmp *0f(r0) 1095: 0: f0; f1; f2; f3; f4; f5; f6; f7 1096: 1097: f0: 1098: mov r1,r0 1099: ash $-5,r0 1100: bic $!16,r0 1101: jmp *0f(r0) 1102: 0: ff0; ff1; ff2; ff3; ff4; ff5; ff6; ff7 1103: 1104: f1: / mulf, modf 1105: f2: / addf, movf 1106: f3: / subf, cmpf 1107: f4: / movf, divf 1108: ff4: / clrf 1109: ff5: / tstf 1110: ff6: / absf 1111: ff7: / negf 1112: inc fflg 1113: mov r1,r0 1114: br setreg 1115: 1116: f6: 1117: bit $400,r1 1118: beq f1 / movfo 1119: br f5 / movie 1120: 1121: f7: 1122: bit $400,r1 1123: beq f5 / movif 1124: br f1 / movof 1125: 1126: ff0: / cfcc, setf, setd, seti, setl 1127: #endif 1128: u1: / br 1129: u2: / br 1130: u3: / br 1131: u7: / illegal 1132: incb jflg 1133: rts pc 1134: 1135: setreg: 1136: mov r0,-(sp) 1137: bic $!7,r0 1138: bis r0,r2 1139: mov (sp)+,r0 1140: ash $-3,r0 1141: bic $!7,r0 1142: movb 0f(r0),r0 1143: tstb bflg 1144: beq 1f 1145: bit $2,r2 1146: beq 2f 1147: bit $4,r2 1148: beq 2f 1149: 1: 1150: cmp r0,$20 1151: beq 2f 1152: cmp r0,$-20 1153: beq 2f 1154: asl r0 1155: 2: 1156: #ifndef NONFP 1157: tstb fflg 1158: beq 3f 1159: asl r0 1160: stfps r1 1161: bit $200,r1 1162: beq 3f 1163: asl r0 1164: 3: 1165: #endif 1166: bisb r0,r2 1167: rts pc 1168: 1169: 0: .byte 0,0,10,20,-10,-20,0,0 1170: 1171: fetch: 1172: bic $1,r0 1173: mov nofault,-(sp) 1174: mov $1f,nofault 1175: mfpi (r0) 1176: mov (sp)+,r0 1177: mov (sp)+,nofault 1178: rts pc 1179: 1180: 1: 1181: mov (sp)+,nofault 1182: clrb r2 / clear out dest on fault 1183: mov $-1,r0 1184: rts pc 1185: 1186: .bss 1187: bflg: .=.+1 1188: jflg: .=.+1 1189: fflg: .=.+1 1190: .text 1191: #endif KERN_NONSEP 1192: 1193: .globl _fuibyte, _fubyte, _suibyte, _subyte 1194: _fuibyte: 1195: #ifndef NONSEPARATE 1196: mov 2(sp),r1 1197: bic $1,r1 1198: jsr pc,giword 1199: br 2f 1200: #endif 1201: 1202: _fubyte: 1203: mov 2(sp),r1 1204: bic $1,r1 1205: jsr pc,gword 1206: 1207: 2: 1208: cmp r1,2(sp) 1209: beq 1f 1210: swab r0 1211: 1: 1212: bic $!377,r0 1213: rts pc 1214: 1215: _suibyte: 1216: #ifndef NONSEPARATE 1217: mov 2(sp),r1 1218: bic $1,r1 1219: jsr pc,giword 1220: mov r0,-(sp) 1221: cmp r1,4(sp) 1222: beq 1f 1223: movb 6(sp),1(sp) 1224: br 2f 1225: 1: 1226: movb 6(sp),(sp) 1227: 2: 1228: mov (sp)+,r0 1229: jsr pc,piword 1230: clr r0 1231: rts pc 1232: #endif 1233: 1234: _subyte: 1235: mov 2(sp),r1 1236: bic $1,r1 1237: jsr pc,gword 1238: mov r0,-(sp) 1239: cmp r1,4(sp) 1240: beq 1f 1241: movb 6(sp),1(sp) 1242: br 2f 1243: 1: 1244: movb 6(sp),(sp) 1245: 2: 1246: mov (sp)+,r0 1247: jsr pc,pword 1248: clr r0 1249: rts pc 1250: 1251: .globl _fuiword, _fuword, _suiword, _suword 1252: _fuiword: 1253: #ifndef NONSEPARATE 1254: mov 2(sp),r1 1255: fuiword: 1256: jsr pc,giword 1257: rts pc 1258: #endif 1259: 1260: _fuword: 1261: mov 2(sp),r1 1262: fuword: 1263: jsr pc,gword 1264: rts pc 1265: 1266: gword: 1267: #ifndef NONSEPARATE 1268: mov PS,-(sp) 1269: #ifdef UCB_NET 1270: bis $30000,PS / just in case; dgc; %%%% 1271: #endif 1272: SPLHIGH 1273: mov nofault,-(sp) 1274: mov $err,nofault 1275: mfpd (r1) 1276: mov (sp)+,r0 1277: br 1f 1278: 1279: giword: 1280: #endif 1281: mov PS,-(sp) 1282: #ifdef UCB_NET 1283: bis $30000,PS / just in case; dgc; %%%% 1284: #endif 1285: SPLHIGH 1286: mov nofault,-(sp) 1287: mov $err,nofault 1288: mfpi (r1) 1289: mov (sp)+,r0 1290: br 1f 1291: 1292: _suiword: 1293: #ifndef NONSEPARATE 1294: mov 2(sp),r1 1295: mov 4(sp),r0 1296: suiword: 1297: jsr pc,piword 1298: rts pc 1299: #endif 1300: 1301: _suword: 1302: mov 2(sp),r1 1303: mov 4(sp),r0 1304: suword: 1305: jsr pc,pword 1306: rts pc 1307: 1308: pword: 1309: #ifndef NONSEPARATE 1310: mov PS,-(sp) 1311: #ifdef UCB_NET 1312: bis $30000,PS / just in case; dgc; %%%% 1313: #endif 1314: SPLHIGH 1315: mov nofault,-(sp) 1316: mov $err,nofault 1317: mov r0,-(sp) 1318: mtpd (r1) 1319: br 1f 1320: 1321: piword: 1322: #endif 1323: mov PS,-(sp) 1324: #ifdef UCB_NET 1325: bis $30000,PS / just in case; dgc; %%%% 1326: #endif 1327: SPLHIGH 1328: mov nofault,-(sp) 1329: mov $err,nofault 1330: mov r0,-(sp) 1331: mtpi (r1) 1332: 1: 1333: mov (sp)+,nofault 1334: mov (sp)+,PS 1335: rts pc 1336: 1337: err: 1338: mov (sp)+,nofault 1339: mov (sp)+,PS 1340: tst (sp)+ 1341: mov $-1,r0 1342: rts pc 1343: 1344: .globl _copyin, _copyiin, _copyout, _copyiout 1345: _copyin: 1346: #ifndef NONSEPARATE 1347: jsr pc,copsu 1348: 1: 1349: mfpd (r0)+ 1350: mov (sp)+,(r1)+ 1351: sob r2,1b 1352: br 2f 1353: #endif 1354: 1355: _copyiin: 1356: jsr pc,copsu 1357: 1: 1358: mfpi (r0)+ 1359: mov (sp)+,(r1)+ 1360: sob r2,1b 1361: br 2f 1362: 1363: _copyout: 1364: #ifndef NONSEPARATE 1365: jsr pc,copsu 1366: 1: 1367: mov (r0)+,-(sp) 1368: mtpd (r1)+ 1369: sob r2,1b 1370: br 2f 1371: #endif 1372: 1373: _copyiout: 1374: jsr pc,copsu 1375: 1: 1376: mov (r0)+,-(sp) 1377: mtpi (r1)+ 1378: sob r2,1b 1379: 2: 1380: mov (sp)+,nofault 1381: mov (sp)+,r2 1382: clr r0 1383: rts pc 1384: 1385: copsu: 1386: #ifdef UCB_NET 1387: bis $30000,PS / make sure that we copy to/from user space 1388: / this is a test - dgc - %%%% 1389: #endif 1390: mov (sp)+,r0 1391: mov r2,-(sp) 1392: mov nofault,-(sp) 1393: mov r0,-(sp) 1394: mov 10(sp),r0 1395: mov 12(sp),r1 1396: mov 14(sp),r2 1397: asr r2 1398: mov $1f,nofault 1399: rts pc 1400: 1401: 1: 1402: mov (sp)+,nofault 1403: mov (sp)+,r2 1404: mov $-1,r0 1405: rts pc 1406: 1407: .globl _idle, _waitloc 1408: _idle: 1409: mov PS,-(sp) 1410: SPLLOW 1411: wait 1412: waitloc: 1413: mov (sp)+,PS 1414: rts pc 1415: 1416: .data 1417: _waitloc: 1418: waitloc 1419: .text 1420: #if defined(PROFILE) && !defined(ENABLE34) 1421: / These words are to insure that times reported for _save 1422: / do not include those spent while in idle mode, when 1423: / statistics are gathered for system profiling. 1424: / 1425: rts pc 1426: rts pc 1427: rts pc 1428: #endif defined(PROFILE) && !defined(ENABLE34) 1429: 1430: .globl _save, _resume 1431: _save: 1432: mov (sp)+,r1 1433: mov (sp),r0 1434: mov r2,(r0)+ 1435: mov r3,(r0)+ 1436: mov r4,(r0)+ 1437: mov r5,(r0)+ 1438: mov sp,(r0)+ 1439: #ifdef MENLO_KOV 1440: mov __ovno,(r0)+ 1441: #endif 1442: mov r1,(r0)+ 1443: clr r0 1444: jmp (r1) 1445: 1446: _resume: 1447: mov 2(sp),r0 / new process 1448: mov 4(sp),r1 / new stack 1449: SPL7 1450: mov r0,KDSA6 / In new process 1451: mov (r1)+,r2 1452: mov (r1)+,r3 1453: mov (r1)+,r4 1454: mov (r1)+,r5 1455: mov (r1)+,sp 1456: #ifdef MENLO_KOV 1457: mov (r1)+,r0 1458: cmp r0,__ovno 1459: beq 1f 1460: mov r0,__ovno 1461: asl r0 1462: mov ova(r0), OVLY_PAR 1463: mov ovd(r0), OVLY_PDR 1464: 1: 1465: #endif MENLO_KOV 1466: mov $1,r0 1467: SPLLOW 1468: jmp *(r1)+ 1469: 1470: /* 1471: * Note that in the Berkeley system, calls to spl's except splx 1472: * are substituted in line in the assembly code on machines 1473: * with the spl instruction or mtps/mfps. Splx is done by macros 1474: * in param.h. See the makefile, :splfix.spl, :splfix.mtps, 1475: * :splfix.movb and param.h. Calls to __spl# (_spl# in C) 1476: * are always expanded in-line and do not return the previous priority. 1477: */ 1478: 1479: #if defined(KERN_NONSEP) && PDP11 != 34 && PDP11 != 23 && PDP11 != 24 1480: / Spl's for machines (like 11/40) without spl or m[tf]ps instructions. 1481: .globl _spl0, _spl1, _spl4, _spl5, _spl6, _spl7 1482: _spl0: 1483: movb PS,r0 1484: clrb PS 1485: rts pc 1486: _spl1: 1487: movb PS,r0 1488: movb $40, PS 1489: rts pc 1490: _spl4: 1491: movb PS,r0 1492: movb $200, PS 1493: rts pc 1494: _spl5: 1495: movb PS,r0 1496: movb $240, PS 1497: rts pc 1498: _spl6: 1499: movb PS,r0 1500: movb $300, PS 1501: rts pc 1502: _spl7: 1503: movb PS,r0 1504: movb $HIPRI, PS 1505: rts pc 1506: #endif 1507: 1508: .globl _copy, _clear, _kdsa6 1509: #ifdef CGL_RTP 1510: .globl _copyu, _wantrtp, _runrtp 1511: #endif 1512: 1513: /* 1514: * Copy count clicks from src to dst. 1515: * Uses KDSA5 and 6 to copy with mov instructions. 1516: * Interrupt routines must restore segmentation registers if needed; 1517: * see seg.h. 1518: * Note that if CGL_RTP is defined, it checks whether 1519: * the real-time process is runnable once each loop, 1520: * and preempts the current process if necessary 1521: * (which must not swap before this finishes!). 1522: * 1523: * copy(src, dst, count) 1524: * memaddr src, dst; 1525: * int count; 1526: */ 1527: _copy: 1528: jsr r5, csv 1529: #ifdef UCB_NET 1530: mov PS,-(sp) / have to lock out interrupts... 1531: SPL7 1532: mov KDSA5,-(sp) / save seg5 1533: mov KDSD5,-(sp) / save seg5 1534: #endif 1535: mov 10(r5),r3 / count 1536: beq 3f 1537: mov 4(r5),KDSA5 / point KDSA5 at source 1538: mov $RO,KDSD5 / 64 bytes, read-only 1539: mov sp,r4 1540: mov $eintstk,sp / switch to intstk 1541: mov KDSA6,_kdsa6 1542: mov 6(r5),KDSA6 / point KDSA6 at destination 1543: mov $RW,KDSD6 / 64 bytes, read-write 1544: 1: 1545: #ifdef CGL_RTP 1546: tst _wantrtp 1547: bne preempt 1548: 9: 1549: #endif 1550: mov $5*8192.,r0 1551: mov $6*8192.,r1 1552: #if PDP11==70 1553: mov $4.,r2 / copy one click (4*16) 1554: #else 1555: mov $8.,r2 / copy one click (8*8) 1556: #endif 1557: 2: 1558: mov (r0)+,(r1)+ 1559: mov (r0)+,(r1)+ 1560: mov (r0)+,(r1)+ 1561: mov (r0)+,(r1)+ 1562: #if PDP11==70 1563: mov (r0)+,(r1)+ 1564: mov (r0)+,(r1)+ 1565: mov (r0)+,(r1)+ 1566: mov (r0)+,(r1)+ 1567: #endif 1568: sob r2,2b 1569: 1570: inc KDSA5 / next click 1571: inc KDSA6 1572: dec r3 1573: bne 1b 1574: mov _kdsa6,KDSA6 1575: mov $usize-1\<8|RW, KDSD6 1576: clr _kdsa6 1577: #ifndef NOKA5 1578: .globl _seg5 1579: mov _seg5+SE_DESC, KDSD5 / normalseg5(); 1580: mov _seg5+SE_ADDR, KDSA5 / (restore all mapping) 1581: #endif NOKA5 1582: mov r4,sp / back to normal stack 1583: 3: 1584: #ifdef UCB_NET 1585: mov (sp)+,KDSD5 / restore seg5 1586: mov (sp)+,KDSA5 / restore seg5 1587: mov (sp)+,PS / back to normal priority 1588: #endif 1589: jmp cret 1590: 1591: #ifdef CGL_RTP 1592: /* 1593: * Save our state and restore enough context for a process switch. 1594: */ 1595: preempt: 1596: mov KDSA6, r0 1597: mov _kdsa6,KDSA6 / back to our u. 1598: mov $usize-1\<8|RW, KDSD6 1599: clr _kdsa6 1600: mov r4, sp / back to normal stack 1601: mov KDSA5, -(sp) 1602: mov r0, -(sp) / KDSA6 1603: #ifndef NOKA5 1604: mov _seg5+SE_DESC, KDSD5 / normalseg5(); 1605: mov _seg5+SE_ADDR, KDSA5 / (restore all mapping) 1606: #endif NOKA5 1607: jsr pc, _runrtp / switch context and run rtpp 1608: 1609: / Now continue where we left off. 1610: mov (sp)+, r0 / KDSA6 1611: mov (sp)+, KDSA5 1612: mov $RO,KDSD5 / 64 bytes, read-only 1613: mov KDSA6,_kdsa6 1614: mov $eintstk, sp 1615: mov r0, KDSA6 1616: mov $RW,KDSD6 / 64 bytes, read-write 1617: br 9b 1618: 1619: /* 1620: * Copy the u. to dst; not preemptable. 1621: * Uses KDSA5 to copy with mov instructions. 1622: * Interrupt routines must restore segmentation registers if needed; 1623: * see seg.h. 1624: * 1625: * copyu(dst) 1626: * memaddr dst; 1627: */ 1628: _copyu: 1629: jsr r5, csv 1630: mov 4(r5),KDSA5 / point KDSA5 at dst. 1631: mov $usize-1\<8.|RW,KDSD5 1632: mov $6*8192.,r0 1633: mov $5*8192.,r1 1634: #if PDP11==70 1635: mov $4.*usize,r2 / copy 4*16 bytes per click 1636: #else 1637: mov $8.*usize,r2 / copy 8*8 bytes per click 1638: #endif 1639: 2: 1640: mov (r0)+,(r1)+ 1641: mov (r0)+,(r1)+ 1642: mov (r0)+,(r1)+ 1643: mov (r0)+,(r1)+ 1644: #if PDP11==70 1645: mov (r0)+,(r1)+ 1646: mov (r0)+,(r1)+ 1647: mov (r0)+,(r1)+ 1648: mov (r0)+,(r1)+ 1649: #endif 1650: sob r2,2b 1651: 1652: #ifndef NOKA5 1653: mov _seg5+SE_DESC, KDSD5 / normalseg5(); 1654: mov _seg5+SE_ADDR, KDSA5 / (restore all mapping) 1655: #endif NOKA5 1656: jmp cret 1657: #endif CGL_RTP 1658: 1659: /* 1660: * Clear count clicks at dst. 1661: * Uses KDSA5. 1662: * Interrupt routines must restore segmentation registers if needed; 1663: * see seg.h. 1664: * 1665: * clear(dst, count) 1666: * memaddr dst; 1667: * int count; 1668: */ 1669: _clear: 1670: jsr r5, csv 1671: #ifdef UCB_NET 1672: mov KDSA5,-(sp) / save seg5 1673: mov KDSD5,-(sp) / save seg5 1674: #endif 1675: mov 4(r5),KDSA5 / point KDSA5 at source 1676: mov $RW,KDSD5 / 64 bytes, read-write 1677: mov 6(r5),r3 / count 1678: beq 3f 1679: 1: 1680: #ifdef CGL_RTP 1681: tst _wantrtp 1682: bne clrpreempt 1683: 9: 1684: #endif 1685: mov $5*8192.,r0 1686: mov $8.,r2 / clear one click (8*8) 1687: 2: 1688: clr (r0)+ 1689: clr (r0)+ 1690: clr (r0)+ 1691: clr (r0)+ 1692: sob r2,2b 1693: 1694: inc KDSA5 / next click 1695: dec r3 1696: bne 1b 1697: 3: 1698: #ifndef NOKA5 1699: mov _seg5+SE_DESC, KDSD5 / normalseg5(); 1700: mov _seg5+SE_ADDR, KDSA5 / (restore all mapping) 1701: #endif NOKA5 1702: #ifdef UCB_NET 1703: mov (sp)+,KDSD5 / restore seg5 1704: mov (sp)+,KDSA5 / restore seg5 1705: #endif 1706: jmp cret 1707: 1708: #ifdef CGL_RTP 1709: clrpreempt: 1710: mov KDSA5, -(sp) 1711: #ifndef NOKA5 1712: mov _seg5+SE_DESC, KDSD5 / normalseg5(); 1713: mov _seg5+SE_ADDR, KDSA5 / (restore all mapping) 1714: #endif NOKA5 1715: jsr pc, _runrtp / switch context and run rtpp 1716: /* 1717: * Now continue where we left off. 1718: */ 1719: mov (sp)+, KDSA5 1720: mov $RW,KDSD5 / 64 bytes, read-write 1721: br 9b 1722: #endif CGL_RTP 1723: 1724: #ifdef UCB_NET 1725: /* 1726: * copyv(fromaddr,toaddr,count) 1727: * virtual_addr fromaddr,toaddr; 1728: * unsigned count; 1729: * 1730: * Copy two arbitrary pieces of PDP11 virtual memory from one location 1731: * to another. Up to 8K bytes can be copied at one time. 1732: * 1733: * A PDP11 virtual address is a two word value; a 16 bit "click" that 1734: * defines the start in physical memory of an 8KB segment and an offset. 1735: */ 1736: 1737: .globl _copyv 1738: 1739: .data 1740: copyvsave: 0 / saved copy of KDSA6 1741: .text 1742: 1743: _copyv: jsr r5,csv 1744: 1745: tst 14(r5) /* if (count == 0) */ 1746: jeq copyvexit /* return; */ 1747: cmp $20000,14(r5) /* if (count >= 8192) */ 1748: jlos copyvexit /* return; */ 1749: 1750: mov PS,-(sp) /* Lock out interrupts. sigh... */ 1751: SPL7 1752: 1753: mov KDSA5,-(sp) /* save seg5 */ 1754: mov KDSD5,-(sp) 1755: 1756: mov 4(r5),KDSA5 /* seg5 = fromclick */ 1757: mov $128.-1\<8.|RO,KDSD5 1758: mov 10(r5),r1 /* click = toclick */ 1759: mov 6(r5),r2 /* foff = fromoffset */ 1760: add $5*8192.,r2 /* foff = virtual addr (page 5) */ 1761: mov 12(r5),r3 /* toff = tooffset */ 1762: add $6*8192.,r3 /* toff = virtual addr (page 6) */ 1763: mov 14(r5),r0 /* count = count */ 1764: 1765: /* Note: the switched stack is only for use of a fatal */ 1766: /* kernel trap occurring during the copy; otherwise we */ 1767: /* might conflict with the other copy routine */ 1768: mov sp,r4 /* switch stacks */ 1769: mov $eintstk,sp 1770: mov KDSA6,copyvsave 1771: 1772: mov r1,KDSA6 /* seg6 = click */ 1773: mov $128.-1\<8.|RW,KDSD6 1774: 1775: /****** Finally do the copy ******/ 1776: mov r3,r1 /* Odd addresses or count? */ 1777: bis r2,r1 1778: bis r0,r1 1779: bit $1,r1 1780: bne copyvodd /* Branch if odd */ 1781: 1782: asr r0 /* Copy a word at a time */ 1783: 1: mov (r2)+,(r3)+ 1784: sob r0,1b 1785: br copyvdone 1786: 1787: copyvodd: movb (r2)+,(r3)+ /* Copy a byte at a time */ 1788: sob r0,copyvodd 1789: / br copyvdone 1790: 1791: copyvdone: 1792: mov copyvsave,KDSA6 /* remap in the stack */ 1793: mov $usize-1\<8.|RW,KDSD6 1794: mov r4,sp 1795: mov (sp)+,KDSD5 /* restore seg5 */ 1796: mov (sp)+,KDSA5 1797: mov (sp)+,PS /* unlock interrupts */ 1798: 1799: copyvexit: 1800: clr r0 1801: clr r1 1802: jmp cret 1803: #endif UCB_NET 1804: 1805: hardprobe: 1806: #ifndef NONFP 1807: / Test for floating point capability. 1808: fptest: 1809: mov $fpdone, nofault 1810: setd 1811: inc fpp 1812: fpdone: 1813: #endif NONFP 1814: 1815: / Test for SSR3 and UNIBUS map capability. If there is no SSR3, 1816: / the first test of SSR3 will trap and we skip past septest. 1817: ubmaptest: 1818: mov $cputest, nofault 1819: #ifdef UNIBUS_MAP 1820: bit $20, SSR3 1821: beq septest 1822: incb _ubmap 1823: #endif 1824: 1825: / Test for separate I/D capability. 1826: septest: 1827: #ifdef NONSEPARATE 1828: / Don't attempt to determine whether we've got separate I/D 1829: / (but just in case we do, we must force user unseparated 1830: / because boot will have turned on separation if possible). 1831: bic $1, SSR3 1832: #else 1833: / Test for user I/D separation (not kernel). 1834: bit $1, SSR3 1835: beq cputest 1836: incb _sep_id 1837: #endif NONSEPARATE 1838: 1839: / Try to find out what kind of cpu this is. 1840: / Defaults are 40 for nonseparate and 45 for separate. 1841: / Cputype will be one of: 24, 40, 60, 45, 44, 70. 1842: cputest: 1843: #ifndef NONSEPARATE 1844: tstb _sep_id 1845: beq nonsepcpu 1846: 1847: tstb _ubmap 1848: beq cpudone 1849: 1850: mov $1f, nofault 1851: mfpt 1852: mov $44., _cputype 1853: / Disable cache parity interrupts. 1854: bis $CCR_DCPI, *$PDP1144_CCR 1855: br cpudone 1856: 1: 1857: mov $70., _cputype 1858: / Disable UNIBUS and nonfatal traps. 1859: bis $CCR_DUT|CCR_DT, *$PDP1170_CCR 1860: br cpudone 1861: 1862: nonsepcpu: 1863: #endif NONSEPARATE 1864: tstb _ubmap 1865: beq 1f 1866: mov $24., _cputype 1867: br cpudone 1868: 1: 1869: mov $cpudone, nofault 1870: tst PDP1160_MSR 1871: mov $60., _cputype 1872: / Disable cache parity error traps. 1873: bis $CCR_DT, *$PDP1160_CCR 1874: 1875: cpudone: 1876: / Test for stack limit register; set it if present. 1877: mov $1f, nofault 1878: mov $intstk-256., STACKLIM 1879: 1: 1880: 1881: #ifdef ENABLE34 1882: / Test for an ENABLE/34. We are very cautious since 1883: / the ENABLE's PARs are in the range of the floating 1884: / addresses. 1885: tstb _ubmap 1886: bne 2f 1887: mov $2f, nofault 1888: mov 32., r0 1889: mov $ENABLE_KISA0, r1 1890: 1: 1891: tst (r1)+ 1892: sob r0, 1b 1893: 1894: tst *$PDP1170_LEAR 1895: tst *$ENABLE_SSR3 1896: tst *$ENABLE_SSR4 1897: incb _enable34 1898: incb _ubmap 1899: 1900: / Turn on an ENABLE/34. Enableon() is a C routine 1901: / which does a PAR shuffle and turns mapping on. 1902: .globl _enableon 1903: .globl _UISA, _UDSA, _KISA0, _KISA6, _KDSA1, _KDSA2, _KDSA5, _KDSA6 1904: 1905: .data 1906: _UISA: DEC_UISA 1907: _UDSA: DEC_UDSA 1908: _KISA0: DEC_KISA0 1909: _KISA6: DEC_KISA6 1910: _KDSA1: DEC_KDSA1 1911: _KDSA2: DEC_KDSA2 1912: _KDSA5: DEC_KDSA5 1913: _KDSA6: DEC_KDSA6 1914: .text 1915: 1916: mov $ENABLE_UISA, _UISA 1917: mov $ENABLE_UDSA, _UDSA 1918: mov $ENABLE_KISA0, _KISA0 1919: mov $ENABLE_KISA6, _KISA6 1920: mov $ENABLE_KDSA1, _KDSA1 1921: mov $ENABLE_KDSA2, _KDSA2 1922: mov $ENABLE_KDSA5, _KDSA5 1923: mov $ENABLE_KDSA6, _KDSA6 1924: mov $ENABLE_KDSA6, _ka6 1925: jsr pc, _enableon 1926: 1927: 2: 1928: #endif ENABLE34 1929: 1930: clr nofault 1931: rts pc 1932: 1933: /* 1934: * Long quotient 1935: */ 1936: .globl ldiv, lrem 1937: ldiv: 1938: jsr r5,csv 1939: mov 10.(r5),r3 1940: sxt r4 1941: bpl 1f 1942: neg r3 1943: 1: 1944: cmp r4,8.(r5) 1945: bne hardldiv 1946: mov 6.(r5),r2 1947: mov 4.(r5),r1 1948: bge 1f 1949: neg r1 1950: neg r2 1951: sbc r1 1952: com r4 1953: 1: 1954: mov r4,-(sp) 1955: clr r0 1956: div r3,r0 1957: mov r0,r4 /high quotient 1958: mov r1,-(sp) / Stash interim result 1959: mov r1,r0 1960: mov r2,r1 1961: div r3,r0 1962: bvc 1f 1963: mov (sp),r0 / Recover interim result. 1964: mov r2,r1 / (Regs may be clobbered by failed div.) 1965: sub r3,r0 / this is the clever part 1966: div r3,r0 1967: tst r1 1968: sxt r1 1969: add r1,r0 / cannot overflow! 1970: 1: 1971: tst (sp)+ / Pop temp off stack. 1972: mov r0,r1 1973: mov r4,r0 1974: tst (sp)+ 1975: bpl 9f 1976: neg r0 1977: neg r1 1978: sbc r0 1979: 9: 1980: jmp cret 1981: 1982: hardldiv: 1983: iot / ``Cannot happen'' 1984: 1985: /* 1986: * Long remainder 1987: */ 1988: lrem: 1989: jsr r5,csv 1990: mov 10.(r5),r3 1991: sxt r4 1992: bpl 1f 1993: neg r3 1994: 1: 1995: cmp r4,8.(r5) 1996: bne hardlrem 1997: mov 6.(r5),r2 1998: mov 4.(r5),r1 1999: mov r1,r4 2000: bge 1f 2001: neg r1 2002: neg r2 2003: sbc r1 2004: 1: 2005: clr r0 2006: div r3,r0 2007: mov r1,-(sp) / Stash interim result. 2008: mov r1,r0 2009: mov r2,r1 2010: div r3,r0 2011: bvc 1f 2012: mov (sp),r0 / Recover interim result. 2013: mov r2,r1 / (Regs may be clobbered by failed div.) 2014: sub r3,r0 2015: div r3,r0 2016: tst r1 2017: beq 9f 2018: add r3,r1 2019: 1: 2020: tst (sp)+ / Pop temp off stack. 2021: tst r4 2022: bpl 9f 2023: neg r1 2024: 9: 2025: sxt r0 2026: jmp cret 2027: 2028: hardlrem: 2029: iot / ``Cannot happen'' 2030: 2031: .globl lmul 2032: lmul: 2033: mov r2,-(sp) 2034: mov r3,-(sp) 2035: mov 8(sp),r2 2036: sxt r1 2037: sub 6(sp),r1 2038: mov 12.(sp),r0 2039: sxt r3 2040: sub 10.(sp),r3 2041: mul r0,r1 2042: mul r2,r3 2043: add r1,r3 2044: mul r2,r0 2045: sub r3,r0 2046: mov (sp)+,r3 2047: mov (sp)+,r2 2048: rts pc 2049: 2050: #ifdef UCB_NET 2051: .globl _htonl,_htons,_ntohl,_ntohs 2052: _htonl: 2053: _ntohl: 2054: mov 2(sp),r0 2055: mov 4(sp),r1 2056: swab r0 2057: swab r1 2058: rts pc 2059: 2060: _htons: 2061: _ntohs: 2062: mov 2(sp),r0 2063: swab r0 2064: rts pc 2065: 2066: .globl _badaddr 2067: _badaddr: 2068: mov 2(sp),r0 2069: mov nofault,-(sp) 2070: mov $1f,nofault 2071: tst (r0) 2072: clr r0 2073: br 2f 2074: 1: 2075: mov $-1,r0 2076: 2: 2077: mov (sp)+,nofault 2078: rts pc 2079: 2080: .globl _bzero 2081: _bzero: 2082: mov 2(sp),r0 2083: beq 3f / error checking... dgc 2084: mov 4(sp),r1 2085: beq 3f / error checking ... dgc 2086: bit $1,r0 2087: bne 1f 2088: bit $1,r1 2089: bne 1f 2090: asr r1 2091: 2: clr (r0)+ 2092: sob r1,2b 2093: rts pc 2094: 2095: 1: clrb (r0)+ 2096: sob r1,1b 2097: 3: 2098: rts pc 2099: #endif UCB_NET 2100: 2101: .globl csv, cret 2102: #ifndef MENLO_KOV 2103: csv: 2104: mov r5,r0 2105: mov sp,r5 2106: mov r4,-(sp) 2107: mov r3,-(sp) 2108: mov r2,-(sp) 2109: jsr pc,(r0) 2110: 2111: cret: 2112: mov r5,r2 2113: mov -(r2),r4 2114: mov -(r2),r3 2115: mov -(r2),r2 2116: mov r5,sp 2117: mov (sp)+,r5 2118: rts pc 2119: 2120: #else MENLO_KOV 2121: .globl __ovno 2122: .data 2123: __ovno: 0 2124: .text 2125: /* 2126: * Inter-overlay calls call thunk which calls ovhndlr to 2127: * save registers. Intra-overlay calls may call function 2128: * directly which calls csv to save registers. 2129: */ 2130: csv: 2131: mov r5,r1 2132: mov sp,r5 2133: mov __ovno,-(sp) / overlay is extra (first) word in mark 2134: mov r4,-(sp) 2135: mov r3,-(sp) 2136: mov r2,-(sp) 2137: jsr pc,(r1) / jsr part is sub $2,sp 2138: 2139: cret: 2140: mov r5,r2 2141: / Get the overlay out of the mark, and if it is non-zero 2142: / make sure it is the currently loaded one. 2143: mov -(r2),r4 2144: bne 1f / zero is easy 2145: 2: 2146: mov -(r2),r4 2147: mov -(r2),r3 2148: mov -(r2),r2 2149: mov r5,sp 2150: mov (sp)+,r5 2151: rts pc 2152: 2153: / Not returning to base segment, so check that the right 2154: / overlay is mapped in, and if not change the mapping. 2155: 1: 2156: cmp r4,__ovno 2157: beq 2b / lucked out! 2158: 2159: / If return address is in base segment, then nothing to do. 2160: cmp 2(r5),$_etext 2161: blos 2b 2162: 2163: / Returning to wrong overlay --- do something! 2164: mov PS,-(sp) / save PS 2165: SPL7 2166: mov r4,__ovno 2167: asl r4 2168: mov ova(r4), OVLY_PAR 2169: mov ovd(r4), OVLY_PDR 2170: mov (sp)+,PS / restore PS, unmask interrupts 2171: / Could measure switches[ovno][r4]++ here. 2172: jmp 2b 2173: 2174: /* 2175: * Ovhndlr1 through ovhndlr7 are called from the thunks, 2176: * after the address to return to is put in r1. This address is 2177: * that after the call to csv, which will be skipped. 2178: */ 2179: .globl ovhndlr1, ovhndlr2, ovhndlr3, ovhndlr4 2180: .globl ovhndlr5, ovhndlr6, ovhndlr7 2181: ovhndlr1: 2182: mov $1,r0 2183: br ovhndlr 2184: ovhndlr2: 2185: mov $2,r0 2186: br ovhndlr 2187: ovhndlr3: 2188: mov $3,r0 2189: br ovhndlr 2190: ovhndlr4: 2191: mov $4,r0 2192: br ovhndlr 2193: ovhndlr5: 2194: mov $5,r0 2195: br ovhndlr 2196: ovhndlr6: 2197: mov $6,r0 2198: br ovhndlr 2199: ovhndlr7: 2200: mov $7,r0 2201: br ovhndlr 2202: /* 2203: * Ovhndlr makes the argument (in r0) be the current overlay, 2204: * saves the registers ala csv (but saves the previous overlay number), 2205: * and then jmp's to the function, skipping the function's initial 2206: * call to csv. 2207: */ 2208: ovhndlr: 2209: mov sp,r5 2210: mov __ovno,-(sp) / save previous overlay number 2211: cmp r0,__ovno / correct overlay mapped? 2212: bne 2f 2213: 1: mov r4,-(sp) 2214: mov r3,-(sp) 2215: mov r2,-(sp) 2216: jsr pc,(r1) / skip function's call to csv 2217: 2218: 2: mov PS,-(sp) / save PS 2219: SPL7 2220: mov r0,__ovno / set new overlay number 2221: asl r0 2222: mov ova(r0), OVLY_PAR 2223: mov ovd(r0), OVLY_PDR 2224: mov (sp)+,PS / restore PS, unmask interrupts 2225: jbr 1b 2226: #endif MENLO_KOV 2227: 2228: /* 2229: * Save regs r0, r1, r2, r3, r4, r5, r6, K[DI]SA6 2230: * starting at data location 0300, in preparation for dumping core. 2231: */ 2232: .globl _saveregs 2233: _saveregs: 2234: #ifdef KERN_NONSEP 2235: movb $RW, KISD0 / write enable 2236: #endif 2237: mov r0,300 2238: mov $302,r0 2239: mov r1,(r0)+ 2240: mov r2,(r0)+ 2241: mov r3,(r0)+ 2242: mov r4,(r0)+ 2243: mov r5,(r0)+ 2244: mov sp,(r0)+ 2245: mov KDSA6,(r0)+ 2246: mov KDSA5,(r0)+ 2247: rts pc 2248: 2249: .globl _nulldev, _nullsys 2250: 2251: _nulldev: / placed in insignificant entries in bdevsw and cdevsw 2252: _nullsys: / ignored system call 2253: rts pc 2254: 2255: .globl _u 2256: _u = 140000 2257: #ifndef UCB_NET 2258: usize = 16. 2259: #else 2260: usize = 32. 2261: #endif 2262: 2263: .data 2264: .globl _ka6, _cputype, _sep_id, _ubmap 2265: #ifdef ENABLE34 2266: .globl _enable34 2267: _enable34: .byte 0 2268: #endif 2269: _ubmap: .byte 0 2270: _sep_id: .byte 0 2271: .even 2272: 2273: #ifdef KERN_NONSEP 2274: #ifdef ENABLE34 2275: _ka6: DEC_KISA6 2276: #else 2277: _ka6: KISA6 2278: #endif 2279: _cputype:40. 2280: 2281: #else KERN_NONSEP 2282: #ifdef ENABLE34 2283: _ka6: DEC_KDSA6 2284: #else 2285: _ka6: KDSA6 2286: #endif 2287: _cputype:45. 2288: #endif KERN_NONSEP 2289: 2290: .bss 2291: .even 2292: intstk: .=.+INTSTK / temporary stack while KDSA6 is repointed 2293: eintstk: .=.+2 / initial top of intstk 2294: 2295: .data 2296: nofault:.=.+2 2297: #ifndef NONFP 2298: fpp: .=.+2 2299: #endif 2300: ssr: .=.+6 2301: #ifdef DISPLAY 2302: dispdly:.=.+2 2303: #endif 2304: saveps: .=.+2 2305: 2306: #if defined(PROFILE) && !defined(ENABLE34) 2307: .text 2308: /* 2309: * System profiler 2310: * 2311: * Expects to have a KW11-P in addition to the line-frequency 2312: * clock, and it should be set to BR7. 2313: * Uses supervisor I space register 2 and 3 (040000 - 0100000) 2314: * to maintain the profile. 2315: */ 2316: 2317: CCSB = 172542 2318: CCSR = 172540 2319: _probsiz = 37777 2320: 2321: .globl _isprof, _sprof, _probsiz, _mode 2322: / 2323: / Enable clock interrupts for system profiling 2324: / 2325: _isprof: 2326: mov $1f,nofault 2327: mov $_sprof,104 / interrupt 2328: mov $340,106 / pri 2329: mov $100.,CCSB / count set = 100 2330: mov $113,CCSR / count down, 10kHz, repeat 2331: 1: 2332: clr nofault 2333: rts pc 2334: 2335: / 2336: / Process profiling clock interrupts 2337: / 2338: _sprof: 2339: mov r0,-(sp) 2340: mov PS,r0 2341: ash $-10.,r0 2342: bic $!14,r0 / mask out all but previous mode 2343: add $1,_mode+2(r0) 2344: adc _mode(r0) 2345: cmp r0,$14 / user 2346: beq done 2347: mov 2(sp),r0 / pc 2348: asr r0 2349: asr r0 2350: bic $140001,r0 2351: cmp r0,$_probsiz 2352: blo 1f 2353: inc _outside 2354: br done 2355: 1: 2356: mov $10340,PS / Set previous mode to supervisor 2357: mfpi 40000(r0) 2358: inc (sp) 2359: mtpi 40000(r0) 2360: done: 2361: mov (sp)+,r0 2362: mov $113,CCSR 2363: rtt 2364: 2365: .data 2366: _mode: .=.+16. 2367: _outside: .=.+2 2368: #endif defined(PROFILE) && !defined(ENABLE34)