/* * SCCS id @(#)mch.s 2.1 (Berkeley) 12/21/83 * * Machine language assist. * Uses the C preprocessor to produce suitable code * for various 11's, mainly dependent on definition * of PDP11, MENLO_KOV and NONSEPARATE. */ #define LOCORE #include "whoami.h" /* for localopts */ #if PDP11==GENERIC /* adapt to any 11 at boot */ # undef NONSEPARATE /* support sep I/D */ # define SPLHIGH bis $HIPRI,PS # define SPL7 bis $340,PS # define SPLLOW bic $HIPRI,PS # ifdef UCB_NET # define SPLNET bis $NETPRI,PS # endif #else # ifdef NONSEPARATE /* 11/40, 34, 23, 24 */ # define SPLHIGH bis $HIPRI,PS # define SPL7 bis $340,PS # define SPLLOW bic $HIPRI,PS # ifdef UCB_NET # define SPLNET bis $NETPRI,PS # endif # define mfpd mfpi # define mtpd mtpi # else /* 11/44, 11/45, 11/70 */ # define SPLHIGH spl HIGH # define SPL7 spl 7 # define SPLLOW spl 0 # ifdef UCB_NET # define SPLNET spl NET # endif # endif #endif #include "ht.h" #include "tm.h" #include "ts.h" #include #include #include #include #include #ifdef MENLO_KOV #include #endif #define INTSTK 500. /* bytes for interrupt stack */ /* * non-UNIX instructions */ mfpi = 6500^tst mtpi = 6600^tst #ifndef NONSEPARATE mfpd = 106500^tst mtpd = 106600^tst #endif stst = 170300^tst spl = 230 ldfps = 170100^tst stfps = 170200^tst mfpt = 000007 / Move from processor - 44s only mfps = 106700^tst / Move from PS - 11/23,24,34's only mtps = 106400^tst / Move to PS - 11/23,24,34's only halt = 0 wait = 1 iot = 4 reset = 5 rtt = 6 #ifdef PROFILE #define HIGH 6 / See also the :splfix files #define HIPRI 300 / Many spl's are done in-line #else #define HIGH 7 #define HIPRI 340 #endif PROFILE #ifdef UCB_NET #define NET 1 #define NETPRI 40 #endif /* * Mag tape dump * Save registers in low core and write core (up to 248K) onto mag tape. * Entry is through 044 (physical) with memory management off. */ .globl dump #ifndef KERN_NONSEP .data #endif dump: #if NHT > 0 || NTM > 0 || NTS > 0 / save regs r0, r1, r2, r3, r4, r5, r6, KIA6 / starting at location 4 (physical) inc $-1 / check for first time bne 1f / if not, don't save registers again mov r0,4 mov $6,r0 mov r1,(r0)+ mov r2,(r0)+ mov r3,(r0)+ mov r4,(r0)+ mov r5,(r0)+ mov sp,(r0)+ mov KDSA6,(r0)+ 1: / dump all of core (i.e. to first mt error) / onto mag tape. (9 track or 7 track 'binary') #if NHT > 0 HT = 0172440 HTCS1 = HT+0 HTWC = HT+2 HTBA = HT+4 HTFC = HT+6 HTCS2 = HT+10 HTTC = HT+32 mov $HTCS1,r0 mov $40,*$HTCS2 mov $2300,*$HTTC clr *$HTBA mov $1,(r0) 1: mov $-512.,*$HTFC mov $-256.,*$HTWC movb $61,(r0) 2: tstb (r0) bge 2b bit $1,(r0) bne 2b bit $40000,(r0) beq 1b mov $27,(r0) #else #if NTM > 0 MTC = 172522 mov $MTC,r0 mov $60004,(r0)+ clr 2(r0) 1: mov $-512.,(r0) inc -(r0) 2: tstb (r0) bge 2b tst (r0)+ bge 1b reset / end of file and loop mov $60007,-(r0) #else #if NTS > 0 TSDB = 0172520 TSSR = 0172522 /register usage is as follows /reg 0 points to UBMAP register 1 low /reg 1 is used to calculate the current memory address / for each 512 byte transfer. /reg 2 is used to contain and calculate memory pointer / for UBMAP register 1 low /reg 3 is used to contain and calculate memory pointer / for UBMAP register 1 high /reg 4 points to the command packet /reg 5 is used as an interation counter when mapping is enabled cmp _cputype,$44. /is a 44 ? beq 1f /yes, skip next cmp _cputype,$70. /is a 70 ? bne 2f /not a 70 either. no UBMAP 1: / tst _ubmaps /unibus map present ? / beq 2f /no, skip map init /this section of code initializes the Unibus map registers /and the memory management registers. /UBMAP reg 0 points to low memory for the TS11 command, /characteristics, and message buffers. /UBMAP reg 1 gets updated to point to the current /memory area. /Kernel I space 0 points to low memory /Kernel I space 7 points to the I/O page. inc setmap /indicate that UB mapping is needed mov $UBMR0,r0 /point to map register 0 clr r2 /init for low map reg clr r3 /init for high map reg clr (r0)+ /load map reg 0 low clr (r0)+ /load map reg 0 high mov $77406,*$KISD0 /set KISDR0 mov $77406,*$KISD7 /set KISDR7 clr *$KISA0 /point KISAR0 to low memory mov $IO,*$KISA7 /point KISAR7 to IO page inc *$SSR0 /turn on memory mngt mov $60,*$SSR3 /enable 22 bit mapping mov r2,(r0) /load map reg 1 low mov r3,2(r0) /load map reg 1 high 2: /this section of code initializes the TS11 tstb *$TSSR /make sure bpl 2b /drive is ready mov $comts,r4 /point to command packet add $2,r4 /set up mod 4 bic $3,r4 /alignment mov $140004,(r4) /write characteristics command mov $chrts,2(r4) /characteristics buffer clr 4(r4) /clear ext mem addr (packet) clr tsxma /clear extended memory save loc mov $10,6(r4) /set byte count for command mov $mests,*$chrts /show where message buffer is clr *$chrts+2 /clear extended memory bits here too mov $16,*$chrts+4 /set message buffer length mov r4,*$TSDB /start command mov $20,r5 /set up SOB counter for UBMAP clr r1 /init r1 beginning memory address 1: tstb *$TSSR /wait for ready bpl 1b /not yet mov *$TSSR,tstcc /error condition (SC) ? bpl 2f /no error bic $!16,tstcc /yes error, get TCC cmp tstcc,$10 /recoverable error ? bne 8f /no mov $101005,(r4) /yes, load write data retry command clr 4(r4) /clear packet ext mem addr mov r4,*$TSDB /start retry br 1b 8: bit $4000,*$TSSR /is error NXM ? beq . /no, hang (not sure of good dump) mov $140013,(r4) /load a TS init command mov r4,*$TSDB /to clear NXM error 6: tstb *$TSSR /wait for ready bpl 6b mov $1,6(r4) /set word count = 1 mov $100011,(r4) /load write EOF command mov r4,*$TSDB /do write EOF 7: tstb *$TSSR /wait for ready bpl 7b halt /halt after good dump 9: br 1b 2: /If mapping is needed this section calculates the / base address to be loaded into map reg 1 / the algorithm is (!(r5 - 21))*1000) | 20000 / the complement is required because an SOB loop / is being used for the counter /This loop causes 20000 bytes to be written /before the UBMAP is updated. tst setmap /UBMAP ? beq 3f /no map mov r2,(r0) /load map reg 1 low mov r3,2(r0) /load map reg 1 high mov r5,r1 /calculate sub $21,r1 /address for this pass com r1 /based on current mul $1000,r1 /interation bis $20000,r1 /select map register 1 clr 4(r4) /clear extended memory bits 3: /This section does the write. / if mapping is needed the sob loop comes in play here / when the sob falls through the UBAMP reg will be / updated by 20000 to point to next loop section. / if mapping not needed then just calculate the / next 512 byte address pointer mov r1,2(r4) /load mem address mov tsxma,4(r4) /load ext mem address mov $512.,6(r4) /set byte count mov $100005,(r4) /set write command mov r4,*$TSDB /initiate xfer tst setmap /mapping? beq 4f /branch if not sob r5,9b /yes continue loop mov $20,r5 /reset loop count add $20000,r2 /bump low map adc r3 /carry to high map br 1b /do some more 4: add $512.,r1 /bump address for no mapping adc tsxma /carry to extended memory bits br 1b /do again / The following TS11 command and message buffers, / must be in initialized data space instead of / bss space. This allows them to be mapped by the / first M/M mapping register, which is the only one / used durring a core dump. tsxma: 0 /ts11 extended memory address bits setmap: 0 /UB map usage indicator tstcc: 0 /ts11 temp location for TCC comts: /ts11 command packet 0 ; 0 ; 0 ; 0 ; 0 chrts: /ts11 characteristics 0 ; 0 ; 0 ; 0 mests: /ts11 message buffer 0 ; 0 ; 0 ; 0 ; 0 ; 0 ; 0 #endif NTS #endif NTM #endif NHT #endif NHT || NTM br . / If no ht and no tm, fall through to here .text #ifdef UCB_AUTOBOOT /* * routine to call panic, take dump and reboot; * entered by manually loading the PC with 040 and continuing */ .globl _panic, _halt, do_panic, _halt do_panic: mov $pmesg, -(sp) jsr pc, _panic /* NOTREACHED */ .data pmesg: .text _halt: halt /* NOTREACHED */ rts pc #endif UCB_AUTOBOOT .globl _etext, _main, start #ifdef MENLO_KOV .globl ovend, ova, ovd #endif start: bit $1,SSR0 / is memory management enabled ? beq . / better be !!! / The following two instructions change the contents of / locations 034-037 to read: / syscall; br0+SYSCALL. mov $syscall, 34 mov $0+SYSCALL., 36 / Turn off write permission on kernel text movb $RO, KISD0 / Get a stack pointer mov $usize-1\<8|RW, KDSD6 mov $_u+[usize*64.],sp / Clear user block mov $_u,r0 1: clr (r0)+ cmp r0,sp blo 1b #ifdef UCB_AUTOBOOT .globl _bootflags, _checkword / Get bootflags; the bootstrap leave them in r4. / R2 should be the complement of bootflags. mov r4,_bootflags mov r2,_checkword #endif / Check out (and if necessary, set up) the hardware. jsr pc, hardprobe / Set up previous mode and call main / on return, enter user mode at 0R mov $30340,PS jsr pc,_main mov $170000,-(sp) clr -(sp) rtt #if defined(MENLO_OVLY) || (defined(NONFP) && !defined(NONSEPARATE)) /* * Emt takes emulator traps, which are normally requests * to change the overlay for the current process. * Emts are also generated by the separate I/D floating * point simulator in fetching instructions from user * I space. In this case, r0 should be -1 and r1 should * contain the pc of the instruction to be fetched. * If an invalid emt is received, _trap is called. */ .globl _choverl, emt emt: mov PS,saveps bit $30000,PS / verify that emt is not kernel mode beq bademt #ifdef MENLO_OVLY tst _u+U_OVBASE / verify that process is overlaid beq fetchi cmp r0,$NOVL / verify valid overlay number bhi fetchi SPLLOW mov r0,-(sp) mov r1,-(sp) mov r0,_u+U_CUROV #ifdef UCB_METER inc _cnt+V_OVLY #endif mov $RO,-(sp) jsr pc,_choverl tst (sp)+ mov (sp)+,r1 mov (sp)+,r0 rtt #endif MENLO_OVLY fetchi: #if defined(NONFP) && !defined(NONSEPARATE) cmp $-1, r0 bne bademt mov $1f,nofault mfpi (r1) / get I-space at (r1) mov (sp)+,r0 / put result in r0 clr nofault rtt 1: clr nofault /* FALL THROUGH */ #endif defined(NONFP) && !defined(NONSEPARATE) bademt: jsr r0, call1; jmp _trap / invalid emt /*NOTREACHED*/ #endif defined(MENLO_OVLY) || (defined(NONFP) && !defined(NONSEPARATE)) .globl syscall, trap, buserr, _syscall, _trap, _panic, _panicstr /* * System call interface to C code. */ syscall: mov r0, -(sp) #ifdef MENLO_KOV cmp -(sp), -(sp) / Dummy arguments. See trap.c for explanation. #else tst -(sp) / Dummy argument. #endif mov r1, -(sp) mfpd sp tst -(sp) / Dummy argument. jsr pc, _syscall tst (sp)+ mtpd sp mov (sp)+, r1 #ifdef MENLO_KOV cmp (sp)+, (sp)+ #else tst (sp)+ #endif mov (sp)+, r0 rtt #ifdef NONFP /* * Fast illegal-instruction trap routine for use with interpreted * floating point. All of the work is done here if SIGILL is caught, * otherwise, trap is called like normal. */ .globl instrap instrap: mov PS, saveps tst nofault bne 1f / branch to trap code bit $30000, PS / verify not from kernel mode beq 3f SPLLOW tst _u+U_SIGILL / check whether SIGILL is being caught beq 3f / is default bit $1, _u+U_SIGILL bne 3f / is ignored (or held or deferred!) mov r0, -(sp) mfpd sp #ifdef UCB_METER inc _cnt+V_TRAP inc _cnt+V_INTR / since other traps also count as intr #endif mov (sp), r0 sub $2, r0 mov $2f, nofault mov 6(sp), -(sp) mtpd (r0) / push old PS sub $2, r0 mov 4(sp), -(sp) mtpd (r0) / push old PC mov _u+U_SIGILL, 4(sp) / new PC bic $TBIT, 6(sp) / new PS mov r0, (sp) mtpd sp / set new user SP mov (sp)+, r0 clr nofault rtt 2: / back out on error clr nofault tst (sp)+ / pop user's sp mov (sp)+, r0 3: jsr r0, call1; jmp _trap / call trap on bad SIGILL /*NOTREACHED*/ #endif buserr: mov PS,saveps bit $30000,PS bne 2f / if previous mode != kernel tst nofault bne 1f tst sp bne 3f / Kernel stack invalid. tst _panicstr beq 4f br . / Already paniced, don't overwrite anything 4: / Find a piece of stack so we can panic. mov $intstk+[INTSTK\/2], sp mov $redstak, -(sp) jsr pc, _panic /*NOTREACHED*/ .data redstak: .text /* * Traps without specialized catchers get vectored here. */ trap: mov PS,saveps 2: tst nofault bne 1f 3: mov SSR0,ssr #ifndef KERN_NONSEP mov SSR1,ssr+2 #endif mov SSR2,ssr+4 mov $1,SSR0 jsr r0, call1; jmp _trap /*NOTREACHED*/ 1: mov $1,SSR0 mov nofault,(sp) rtt .globl call, _runrun call1: mov saveps, -(sp) SPLLOW br 1f call: mov PS, -(sp) 1: #ifdef MENLO_KOV mov __ovno,-(sp) / save overlay number #endif mov r1,-(sp) mfpd sp #ifdef UCB_METER .globl _cnt inc _cnt+V_INTR / count device interrupts #endif UCB_METER #ifdef MENLO_KOV mov 6(sp), -(sp) #else mov 4(sp), -(sp) #endif bic $!37,(sp) bit $30000,PS beq 1f jsr pc,(r0)+ #ifdef UCB_NET jsr pc,checknet #endif tstb _runrun beq 2f mov $SWITCHTRAP.,(sp) / give up cpu jsr pc,_trap 2: tst (sp)+ mtpd sp br 2f 1: bis $30000,PS jsr pc,(r0)+ #ifdef UCB_NET jsr pc,checknet #endif cmp (sp)+,(sp)+ 2: mov (sp)+,r1 #ifdef MENLO_KOV / Restore previous overlay number and mapping. mov (sp)+,r0 / get saved overlay number cmp r0,__ovno beq 1f mov PS,-(sp) / save PS SPL7 mov r0,__ovno asl r0 mov ova(r0), OVLY_PAR mov ovd(r0), OVLY_PDR mov (sp)+,PS / restore PS, unmask interrupts 1: #endif MENLO_KOV tst (sp)+ mov (sp)+,r0 rtt #ifdef UCB_AUTOBOOT /* * Power fail handling. On power down, we just set up for the next trap. */ #define PVECT 24 /* power fail vector */ .globl powrdown, powrup, _panicstr, _rootdev, hardboot .text powrdown: mov $powrup,PVECT SPL7 br . /* * Power back on... wait a bit, then attempt a reboot. * Can't do much since memory management is off * (hence we are in "data" space). */ #ifndef KERN_NONSEP .data #endif powrup: mov $-1,r0 1: dec r0 bne 1b mov $RB_POWRFAIL, r4 mov _rootdev,r3 jsr pc,hardboot /* NOTREACHED */ .text #endif UCB_AUTOBOOT #ifdef UCB_NET .globl _netisr,_netintr checknet: mov PS,-(sp) SPL7 tst _netisr / net requesting soft interrupt beq 3f #ifdef MENLO_KOV bit $340,18.(sp) #else bit $340,16.(sp) #endif bne 3f / if prev spl not 0 SPLNET jsr pc,*$_netintr 3: mov (sp)+,PS rts pc #endif #include "dz.h" #if NDZ > 0 && defined(DZ_PDMA) /* * DZ-11 pseudo-DMA interrupt routine. * Called directly from the interrupt vector; * the device number is in the low bits of the PS. * Calls dzxint when the end of the buffer is reached. * The pdma structure is known to be: * struct pdma { * struct dzdevice *p_addr; * char *p_mem; * char *p_end; * struct tty *p_arg; * }; */ .globl dzdma, _dzpdma, _dzxint dzdma: mov PS, -(sp) mov r0, -(sp) #ifdef MENLO_KOV mov __ovno, -(sp) #endif mov r1, -(sp) mov r2, -(sp) mov r3, -(sp) #ifdef MENLO_KOV mov 12(sp), r3 / new PS #else mov 10(sp), r3 / new PS #endif #ifdef UCB_METER inc _cnt+V_PDMA / count pseudo-DMA interrupts #endif UCB_METER bic $!37, r3 / extract device number ash $3+3, r3 / get offset into dzpdma add $_dzpdma, r3 / for first line mov (r3)+, r2 / dzaddr in r2; r3 points to p_mem #ifdef UCB_CLIST .globl _clststrt, _clstdesc mov KDSA5, -(sp) / save previous mapping mov KDSD5, -(sp) mov _clststrt, KDSA5 / map in clists mov _clstdesc, KDSD5 #endif UCB_CLIST / loop until no line is ready 1: movb 1(r2), r1 / dzcsr high byte bge 3f / test TRDY; branch if none bic $!7, r1 / extract line number ash $3, r1 / convert to pdma offset add r3, r1 / r1 is pointer to pdma.p_mem for line mov (r1)+, r0 / pdma->p_mem cmp r0, (r1)+ / cmp p_mem to p_end bhis 2f / if p_mem >= p_end movb (r0)+, 6(r2) / dztbuf = *p_mem++ mov r0, -4(r1) / update p_mem br 1b / buffer is empty; call dzxint 2: mov (r1), -(sp) / p_arg jsr pc, _dzxint / r0, r1 are modified! tst (sp)+ br 1b / no more lines ready; return 3: #ifdef UCB_CLIST mov (sp)+, KDSD5 mov (sp)+, KDSA5 / restore previous mapping #endif UCB_CLIST mov (sp)+, r3 mov (sp)+, r2 mov (sp)+, r1 #ifdef MENLO_KOV SPL7 mov (sp)+, r0 cmp r0, __ovno beq 1f mov r0, __ovno asl r0 mov ova(r0), OVLY_PAR mov ovd(r0), OVLY_PDR 1: #endif mov (sp)+, r0 tst (sp)+ rtt #endif DZ_PDMA #ifndef NONFP .globl _savfp, _restfp, _stst _savfp: tst fpp beq 9f / No FP hardware mov 2(sp),r1 stfps (r1)+ setd movf fr0,(r1)+ movf fr1,(r1)+ movf fr2,(r1)+ movf fr3,(r1)+ movf fr4,fr0 movf fr0,(r1)+ movf fr5,fr0 movf fr0,(r1)+ 9: rts pc _restfp: tst fpp beq 9f mov 2(sp),r1 mov r1,r0 setd add $8.+2.,r1 movf (r1)+,fr1 movf (r1)+,fr2 movf (r1)+,fr3 movf (r1)+,fr0 movf fr0,fr4 movf (r1)+,fr0 movf fr0,fr5 movf 2(r0),fr0 ldfps (r0) 9: rts pc /* * Save floating poing error registers. * The argument is a pointer to a two word * structure. */ _stst: tst fpp beq 9f stst *2(sp) 9: rts pc #endif NONFP .globl _addupc _addupc: mov r2,-(sp) mov 6(sp),r2 / base of prof with base,leng,off,scale mov 4(sp),r0 / pc sub 4(r2),r0 / offset clc ror r0 mov 6(r2),r1 clc ror r1 mul r1,r0 / scale ashc $-14.,r0 inc r1 bic $1,r1 cmp r1,2(r2) / length bhis 1f add (r2),r1 / base mov nofault,-(sp) mov $2f,nofault mfpd (r1) add 12.(sp),(sp) mtpd (r1) br 3f 2: clr 6(r2) 3: mov (sp)+,nofault 1: mov (sp)+,r2 rts pc #ifdef DISPLAY .globl _display _display: dec dispdly bge 2f clr dispdly mov PS,-(sp) SPLHIGH mov CSW,r1 bit $1,r1 beq 1f bis $30000,PS dec r1 1: jsr pc,fuword mov r0,CSW mov (sp)+,PS cmp r0,$-1 bne 2f mov $120.,dispdly / 2 second delay after CSW fault 2: rts pc #endif .globl _regloc, _backup #ifndef KERN_NONSEP /* * Backup routine for use with machines with ssr2. */ _backup: mov 2(sp),r0 movb ssr+2,r1 jsr pc,1f movb ssr+3,r1 jsr pc,1f movb _regloc+7,r1 asl r1 add r0,r1 mov ssr+4,(r1) clr r0 2: rts pc 1: mov r1,-(sp) asr (sp) asr (sp) asr (sp) bic $!7,r1 movb _regloc(r1),r1 asl r1 add r0,r1 sub (sp)+,(r1) rts pc #else KERN_NONSEP /* * 11/40 version of backup, for use with no SSR2 */ _backup: mov 2(sp),ssr+2 mov r2,-(sp) jsr pc,backup mov r2,ssr+2 mov (sp)+,r2 movb jflg,r0 bne 2f mov 2(sp),r0 movb ssr+2,r1 jsr pc,1f movb ssr+3,r1 jsr pc,1f movb _regloc+7,r1 asl r1 add r0,r1 mov ssr+4,(r1) clr r0 2: rts pc 1: mov r1,-(sp) asr (sp) asr (sp) asr (sp) bic $!7,r1 movb _regloc(r1),r1 asl r1 add r0,r1 sub (sp)+,(r1) rts pc / Hard part: simulate the ssr2 register missing on 11/40. backup: clr r2 / backup register ssr1 mov $1,bflg / clrs jflg clrb fflg mov ssr+4,r0 jsr pc,fetch mov r0,r1 ash $-11.,r0 bic $!36,r0 jmp *0f(r0) 0: t00; t01; t02; t03; t04; t05; t06; t07 t10; t11; t12; t13; t14; t15; t16; t17 t00: clrb bflg t10: mov r1,r0 swab r0 bic $!16,r0 jmp *0f(r0) 0: u0; u1; u2; u3; u4; u5; u6; u7 u6: / single op, m[tf]pi, sxt, illegal bit $400,r1 beq u5 / all but m[tf], sxt bit $200,r1 beq 1f / mfpi bit $100,r1 bne u5 / sxt / Simulate mtpi with double (sp)+,dd. bic $4000,r1 / turn instr into (sp)+ br t01 / Simulate mfpi with double ss,-(sp). 1: ash $6,r1 bis $46,r1 / -(sp) br t01 u4: / jsr mov r1,r0 jsr pc,setreg / assume no fault bis $173000,r2 / -2 from sp rts pc t07: / EIS clrb bflg u0: / jmp, swab u5: / single op #ifndef NONFP f5: / movei, movfi ff1: / ldfps ff2: / stfps ff3: / stst #endif mov r1,r0 br setreg t01: / mov t02: / cmp t03: / bit t04: / bic t05: / bis t06: / add t16: / sub clrb bflg t11: / movb t12: / cmpb t13: / bitb t14: / bicb t15: / bisb mov r1,r0 ash $-6,r0 jsr pc,setreg swab r2 mov r1,r0 jsr pc,setreg / If delta(dest) is zero, no need to fetch source. bit $370,r2 beq 1f / If mode(source) is R, no fault is possible. bit $7000,r1 beq 1f / If reg(source) is reg(dest), too bad. mov r2,-(sp) bic $174370,(sp) cmpb 1(sp),(sp)+ beq u7 / Start source cycle. Pick up value of reg. mov r1,r0 ash $-6,r0 bic $!7,r0 movb _regloc(r0),r0 asl r0 add ssr+2,r0 mov (r0),r0 / If reg has been incremented, must decrement it before fetch. bit $174000,r2 ble 2f dec r0 bit $10000,r2 beq 2f dec r0 2: / If mode is 6,7 fetch and add X(R) to R. bit $4000,r1 beq 2f bit $2000,r1 beq 2f mov r0,-(sp) mov ssr+4,r0 add $2,r0 jsr pc,fetch add (sp)+,r0 2: / Fetch operand. If mode is 3, 5, or 7, fetch *. jsr pc,fetch bit $1000,r1 beq 1f bit $6000,r1 bne fetch 1: rts pc t17: / floating point instructions #ifndef NONFP clrb bflg mov r1,r0 swab r0 bic $!16,r0 jmp *0f(r0) 0: f0; f1; f2; f3; f4; f5; f6; f7 f0: mov r1,r0 ash $-5,r0 bic $!16,r0 jmp *0f(r0) 0: ff0; ff1; ff2; ff3; ff4; ff5; ff6; ff7 f1: / mulf, modf f2: / addf, movf f3: / subf, cmpf f4: / movf, divf ff4: / clrf ff5: / tstf ff6: / absf ff7: / negf inc fflg mov r1,r0 br setreg f6: bit $400,r1 beq f1 / movfo br f5 / movie f7: bit $400,r1 beq f5 / movif br f1 / movof ff0: / cfcc, setf, setd, seti, setl #endif u1: / br u2: / br u3: / br u7: / illegal incb jflg rts pc setreg: mov r0,-(sp) bic $!7,r0 bis r0,r2 mov (sp)+,r0 ash $-3,r0 bic $!7,r0 movb 0f(r0),r0 tstb bflg beq 1f bit $2,r2 beq 2f bit $4,r2 beq 2f 1: cmp r0,$20 beq 2f cmp r0,$-20 beq 2f asl r0 2: #ifndef NONFP tstb fflg beq 3f asl r0 stfps r1 bit $200,r1 beq 3f asl r0 3: #endif bisb r0,r2 rts pc 0: .byte 0,0,10,20,-10,-20,0,0 fetch: bic $1,r0 mov nofault,-(sp) mov $1f,nofault mfpi (r0) mov (sp)+,r0 mov (sp)+,nofault rts pc 1: mov (sp)+,nofault clrb r2 / clear out dest on fault mov $-1,r0 rts pc .bss bflg: .=.+1 jflg: .=.+1 fflg: .=.+1 .text #endif KERN_NONSEP .globl _fuibyte, _fubyte, _suibyte, _subyte _fuibyte: #ifndef NONSEPARATE mov 2(sp),r1 bic $1,r1 jsr pc,giword br 2f #endif _fubyte: mov 2(sp),r1 bic $1,r1 jsr pc,gword 2: cmp r1,2(sp) beq 1f swab r0 1: bic $!377,r0 rts pc _suibyte: #ifndef NONSEPARATE mov 2(sp),r1 bic $1,r1 jsr pc,giword mov r0,-(sp) cmp r1,4(sp) beq 1f movb 6(sp),1(sp) br 2f 1: movb 6(sp),(sp) 2: mov (sp)+,r0 jsr pc,piword clr r0 rts pc #endif _subyte: mov 2(sp),r1 bic $1,r1 jsr pc,gword mov r0,-(sp) cmp r1,4(sp) beq 1f movb 6(sp),1(sp) br 2f 1: movb 6(sp),(sp) 2: mov (sp)+,r0 jsr pc,pword clr r0 rts pc .globl _fuiword, _fuword, _suiword, _suword _fuiword: #ifndef NONSEPARATE mov 2(sp),r1 fuiword: jsr pc,giword rts pc #endif _fuword: mov 2(sp),r1 fuword: jsr pc,gword rts pc gword: #ifndef NONSEPARATE mov PS,-(sp) #ifdef UCB_NET bis $30000,PS / just in case; dgc; %%%% #endif SPLHIGH mov nofault,-(sp) mov $err,nofault mfpd (r1) mov (sp)+,r0 br 1f giword: #endif mov PS,-(sp) #ifdef UCB_NET bis $30000,PS / just in case; dgc; %%%% #endif SPLHIGH mov nofault,-(sp) mov $err,nofault mfpi (r1) mov (sp)+,r0 br 1f _suiword: #ifndef NONSEPARATE mov 2(sp),r1 mov 4(sp),r0 suiword: jsr pc,piword rts pc #endif _suword: mov 2(sp),r1 mov 4(sp),r0 suword: jsr pc,pword rts pc pword: #ifndef NONSEPARATE mov PS,-(sp) #ifdef UCB_NET bis $30000,PS / just in case; dgc; %%%% #endif SPLHIGH mov nofault,-(sp) mov $err,nofault mov r0,-(sp) mtpd (r1) br 1f piword: #endif mov PS,-(sp) #ifdef UCB_NET bis $30000,PS / just in case; dgc; %%%% #endif SPLHIGH mov nofault,-(sp) mov $err,nofault mov r0,-(sp) mtpi (r1) 1: mov (sp)+,nofault mov (sp)+,PS rts pc err: mov (sp)+,nofault mov (sp)+,PS tst (sp)+ mov $-1,r0 rts pc .globl _copyin, _copyiin, _copyout, _copyiout _copyin: #ifndef NONSEPARATE jsr pc,copsu 1: mfpd (r0)+ mov (sp)+,(r1)+ sob r2,1b br 2f #endif _copyiin: jsr pc,copsu 1: mfpi (r0)+ mov (sp)+,(r1)+ sob r2,1b br 2f _copyout: #ifndef NONSEPARATE jsr pc,copsu 1: mov (r0)+,-(sp) mtpd (r1)+ sob r2,1b br 2f #endif _copyiout: jsr pc,copsu 1: mov (r0)+,-(sp) mtpi (r1)+ sob r2,1b 2: mov (sp)+,nofault mov (sp)+,r2 clr r0 rts pc copsu: #ifdef UCB_NET bis $30000,PS / make sure that we copy to/from user space / this is a test - dgc - %%%% #endif mov (sp)+,r0 mov r2,-(sp) mov nofault,-(sp) mov r0,-(sp) mov 10(sp),r0 mov 12(sp),r1 mov 14(sp),r2 asr r2 mov $1f,nofault rts pc 1: mov (sp)+,nofault mov (sp)+,r2 mov $-1,r0 rts pc .globl _idle, _waitloc _idle: mov PS,-(sp) SPLLOW wait waitloc: mov (sp)+,PS rts pc .data _waitloc: waitloc .text #if defined(PROFILE) && !defined(ENABLE34) / These words are to insure that times reported for _save / do not include those spent while in idle mode, when / statistics are gathered for system profiling. / rts pc rts pc rts pc #endif defined(PROFILE) && !defined(ENABLE34) .globl _save, _resume _save: mov (sp)+,r1 mov (sp),r0 mov r2,(r0)+ mov r3,(r0)+ mov r4,(r0)+ mov r5,(r0)+ mov sp,(r0)+ #ifdef MENLO_KOV mov __ovno,(r0)+ #endif mov r1,(r0)+ clr r0 jmp (r1) _resume: mov 2(sp),r0 / new process mov 4(sp),r1 / new stack SPL7 mov r0,KDSA6 / In new process mov (r1)+,r2 mov (r1)+,r3 mov (r1)+,r4 mov (r1)+,r5 mov (r1)+,sp #ifdef MENLO_KOV mov (r1)+,r0 cmp r0,__ovno beq 1f mov r0,__ovno asl r0 mov ova(r0), OVLY_PAR mov ovd(r0), OVLY_PDR 1: #endif MENLO_KOV mov $1,r0 SPLLOW jmp *(r1)+ /* * Note that in the Berkeley system, calls to spl's except splx * are substituted in line in the assembly code on machines * with the spl instruction or mtps/mfps. Splx is done by macros * in param.h. See the makefile, :splfix.spl, :splfix.mtps, * :splfix.movb and param.h. Calls to __spl# (_spl# in C) * are always expanded in-line and do not return the previous priority. */ #if defined(KERN_NONSEP) && PDP11 != 34 && PDP11 != 23 && PDP11 != 24 / Spl's for machines (like 11/40) without spl or m[tf]ps instructions. .globl _spl0, _spl1, _spl4, _spl5, _spl6, _spl7 _spl0: movb PS,r0 clrb PS rts pc _spl1: movb PS,r0 movb $40, PS rts pc _spl4: movb PS,r0 movb $200, PS rts pc _spl5: movb PS,r0 movb $240, PS rts pc _spl6: movb PS,r0 movb $300, PS rts pc _spl7: movb PS,r0 movb $HIPRI, PS rts pc #endif .globl _copy, _clear, _kdsa6 #ifdef CGL_RTP .globl _copyu, _wantrtp, _runrtp #endif /* * Copy count clicks from src to dst. * Uses KDSA5 and 6 to copy with mov instructions. * Interrupt routines must restore segmentation registers if needed; * see seg.h. * Note that if CGL_RTP is defined, it checks whether * the real-time process is runnable once each loop, * and preempts the current process if necessary * (which must not swap before this finishes!). * * copy(src, dst, count) * memaddr src, dst; * int count; */ _copy: jsr r5, csv #ifdef UCB_NET mov PS,-(sp) / have to lock out interrupts... SPL7 mov KDSA5,-(sp) / save seg5 mov KDSD5,-(sp) / save seg5 #endif mov 10(r5),r3 / count beq 3f mov 4(r5),KDSA5 / point KDSA5 at source mov $RO,KDSD5 / 64 bytes, read-only mov sp,r4 mov $eintstk,sp / switch to intstk mov KDSA6,_kdsa6 mov 6(r5),KDSA6 / point KDSA6 at destination mov $RW,KDSD6 / 64 bytes, read-write 1: #ifdef CGL_RTP tst _wantrtp bne preempt 9: #endif mov $5*8192.,r0 mov $6*8192.,r1 #if PDP11==70 mov $4.,r2 / copy one click (4*16) #else mov $8.,r2 / copy one click (8*8) #endif 2: mov (r0)+,(r1)+ mov (r0)+,(r1)+ mov (r0)+,(r1)+ mov (r0)+,(r1)+ #if PDP11==70 mov (r0)+,(r1)+ mov (r0)+,(r1)+ mov (r0)+,(r1)+ mov (r0)+,(r1)+ #endif sob r2,2b inc KDSA5 / next click inc KDSA6 dec r3 bne 1b mov _kdsa6,KDSA6 mov $usize-1\<8|RW, KDSD6 clr _kdsa6 #ifndef NOKA5 .globl _seg5 mov _seg5+SE_DESC, KDSD5 / normalseg5(); mov _seg5+SE_ADDR, KDSA5 / (restore all mapping) #endif NOKA5 mov r4,sp / back to normal stack 3: #ifdef UCB_NET mov (sp)+,KDSD5 / restore seg5 mov (sp)+,KDSA5 / restore seg5 mov (sp)+,PS / back to normal priority #endif jmp cret #ifdef CGL_RTP /* * Save our state and restore enough context for a process switch. */ preempt: mov KDSA6, r0 mov _kdsa6,KDSA6 / back to our u. mov $usize-1\<8|RW, KDSD6 clr _kdsa6 mov r4, sp / back to normal stack mov KDSA5, -(sp) mov r0, -(sp) / KDSA6 #ifndef NOKA5 mov _seg5+SE_DESC, KDSD5 / normalseg5(); mov _seg5+SE_ADDR, KDSA5 / (restore all mapping) #endif NOKA5 jsr pc, _runrtp / switch context and run rtpp / Now continue where we left off. mov (sp)+, r0 / KDSA6 mov (sp)+, KDSA5 mov $RO,KDSD5 / 64 bytes, read-only mov KDSA6,_kdsa6 mov $eintstk, sp mov r0, KDSA6 mov $RW,KDSD6 / 64 bytes, read-write br 9b /* * Copy the u. to dst; not preemptable. * Uses KDSA5 to copy with mov instructions. * Interrupt routines must restore segmentation registers if needed; * see seg.h. * * copyu(dst) * memaddr dst; */ _copyu: jsr r5, csv mov 4(r5),KDSA5 / point KDSA5 at dst. mov $usize-1\<8.|RW,KDSD5 mov $6*8192.,r0 mov $5*8192.,r1 #if PDP11==70 mov $4.*usize,r2 / copy 4*16 bytes per click #else mov $8.*usize,r2 / copy 8*8 bytes per click #endif 2: mov (r0)+,(r1)+ mov (r0)+,(r1)+ mov (r0)+,(r1)+ mov (r0)+,(r1)+ #if PDP11==70 mov (r0)+,(r1)+ mov (r0)+,(r1)+ mov (r0)+,(r1)+ mov (r0)+,(r1)+ #endif sob r2,2b #ifndef NOKA5 mov _seg5+SE_DESC, KDSD5 / normalseg5(); mov _seg5+SE_ADDR, KDSA5 / (restore all mapping) #endif NOKA5 jmp cret #endif CGL_RTP /* * Clear count clicks at dst. * Uses KDSA5. * Interrupt routines must restore segmentation registers if needed; * see seg.h. * * clear(dst, count) * memaddr dst; * int count; */ _clear: jsr r5, csv #ifdef UCB_NET mov KDSA5,-(sp) / save seg5 mov KDSD5,-(sp) / save seg5 #endif mov 4(r5),KDSA5 / point KDSA5 at source mov $RW,KDSD5 / 64 bytes, read-write mov 6(r5),r3 / count beq 3f 1: #ifdef CGL_RTP tst _wantrtp bne clrpreempt 9: #endif mov $5*8192.,r0 mov $8.,r2 / clear one click (8*8) 2: clr (r0)+ clr (r0)+ clr (r0)+ clr (r0)+ sob r2,2b inc KDSA5 / next click dec r3 bne 1b 3: #ifndef NOKA5 mov _seg5+SE_DESC, KDSD5 / normalseg5(); mov _seg5+SE_ADDR, KDSA5 / (restore all mapping) #endif NOKA5 #ifdef UCB_NET mov (sp)+,KDSD5 / restore seg5 mov (sp)+,KDSA5 / restore seg5 #endif jmp cret #ifdef CGL_RTP clrpreempt: mov KDSA5, -(sp) #ifndef NOKA5 mov _seg5+SE_DESC, KDSD5 / normalseg5(); mov _seg5+SE_ADDR, KDSA5 / (restore all mapping) #endif NOKA5 jsr pc, _runrtp / switch context and run rtpp /* * Now continue where we left off. */ mov (sp)+, KDSA5 mov $RW,KDSD5 / 64 bytes, read-write br 9b #endif CGL_RTP #ifdef UCB_NET /* * copyv(fromaddr,toaddr,count) * virtual_addr fromaddr,toaddr; * unsigned count; * * Copy two arbitrary pieces of PDP11 virtual memory from one location * to another. Up to 8K bytes can be copied at one time. * * A PDP11 virtual address is a two word value; a 16 bit "click" that * defines the start in physical memory of an 8KB segment and an offset. */ .globl _copyv .data copyvsave: 0 / saved copy of KDSA6 .text _copyv: jsr r5,csv tst 14(r5) /* if (count == 0) */ jeq copyvexit /* return; */ cmp $20000,14(r5) /* if (count >= 8192) */ jlos copyvexit /* return; */ mov PS,-(sp) /* Lock out interrupts. sigh... */ SPL7 mov KDSA5,-(sp) /* save seg5 */ mov KDSD5,-(sp) mov 4(r5),KDSA5 /* seg5 = fromclick */ mov $128.-1\<8.|RO,KDSD5 mov 10(r5),r1 /* click = toclick */ mov 6(r5),r2 /* foff = fromoffset */ add $5*8192.,r2 /* foff = virtual addr (page 5) */ mov 12(r5),r3 /* toff = tooffset */ add $6*8192.,r3 /* toff = virtual addr (page 6) */ mov 14(r5),r0 /* count = count */ /* Note: the switched stack is only for use of a fatal */ /* kernel trap occurring during the copy; otherwise we */ /* might conflict with the other copy routine */ mov sp,r4 /* switch stacks */ mov $eintstk,sp mov KDSA6,copyvsave mov r1,KDSA6 /* seg6 = click */ mov $128.-1\<8.|RW,KDSD6 /****** Finally do the copy ******/ mov r3,r1 /* Odd addresses or count? */ bis r2,r1 bis r0,r1 bit $1,r1 bne copyvodd /* Branch if odd */ asr r0 /* Copy a word at a time */ 1: mov (r2)+,(r3)+ sob r0,1b br copyvdone copyvodd: movb (r2)+,(r3)+ /* Copy a byte at a time */ sob r0,copyvodd / br copyvdone copyvdone: mov copyvsave,KDSA6 /* remap in the stack */ mov $usize-1\<8.|RW,KDSD6 mov r4,sp mov (sp)+,KDSD5 /* restore seg5 */ mov (sp)+,KDSA5 mov (sp)+,PS /* unlock interrupts */ copyvexit: clr r0 clr r1 jmp cret #endif UCB_NET hardprobe: #ifndef NONFP / Test for floating point capability. fptest: mov $fpdone, nofault setd inc fpp fpdone: #endif NONFP / Test for SSR3 and UNIBUS map capability. If there is no SSR3, / the first test of SSR3 will trap and we skip past septest. ubmaptest: mov $cputest, nofault #ifdef UNIBUS_MAP bit $20, SSR3 beq septest incb _ubmap #endif / Test for separate I/D capability. septest: #ifdef NONSEPARATE / Don't attempt to determine whether we've got separate I/D / (but just in case we do, we must force user unseparated / because boot will have turned on separation if possible). bic $1, SSR3 #else / Test for user I/D separation (not kernel). bit $1, SSR3 beq cputest incb _sep_id #endif NONSEPARATE / Try to find out what kind of cpu this is. / Defaults are 40 for nonseparate and 45 for separate. / Cputype will be one of: 24, 40, 60, 45, 44, 70. cputest: #ifndef NONSEPARATE tstb _sep_id beq nonsepcpu tstb _ubmap beq cpudone mov $1f, nofault mfpt mov $44., _cputype / Disable cache parity interrupts. bis $CCR_DCPI, *$PDP1144_CCR br cpudone 1: mov $70., _cputype / Disable UNIBUS and nonfatal traps. bis $CCR_DUT|CCR_DT, *$PDP1170_CCR br cpudone nonsepcpu: #endif NONSEPARATE tstb _ubmap beq 1f mov $24., _cputype br cpudone 1: mov $cpudone, nofault tst PDP1160_MSR mov $60., _cputype / Disable cache parity error traps. bis $CCR_DT, *$PDP1160_CCR cpudone: / Test for stack limit register; set it if present. mov $1f, nofault mov $intstk-256., STACKLIM 1: #ifdef ENABLE34 / Test for an ENABLE/34. We are very cautious since / the ENABLE's PARs are in the range of the floating / addresses. tstb _ubmap bne 2f mov $2f, nofault mov 32., r0 mov $ENABLE_KISA0, r1 1: tst (r1)+ sob r0, 1b tst *$PDP1170_LEAR tst *$ENABLE_SSR3 tst *$ENABLE_SSR4 incb _enable34 incb _ubmap / Turn on an ENABLE/34. Enableon() is a C routine / which does a PAR shuffle and turns mapping on. .globl _enableon .globl _UISA, _UDSA, _KISA0, _KISA6, _KDSA1, _KDSA2, _KDSA5, _KDSA6 .data _UISA: DEC_UISA _UDSA: DEC_UDSA _KISA0: DEC_KISA0 _KISA6: DEC_KISA6 _KDSA1: DEC_KDSA1 _KDSA2: DEC_KDSA2 _KDSA5: DEC_KDSA5 _KDSA6: DEC_KDSA6 .text mov $ENABLE_UISA, _UISA mov $ENABLE_UDSA, _UDSA mov $ENABLE_KISA0, _KISA0 mov $ENABLE_KISA6, _KISA6 mov $ENABLE_KDSA1, _KDSA1 mov $ENABLE_KDSA2, _KDSA2 mov $ENABLE_KDSA5, _KDSA5 mov $ENABLE_KDSA6, _KDSA6 mov $ENABLE_KDSA6, _ka6 jsr pc, _enableon 2: #endif ENABLE34 clr nofault rts pc /* * Long quotient */ .globl ldiv, lrem ldiv: jsr r5,csv mov 10.(r5),r3 sxt r4 bpl 1f neg r3 1: cmp r4,8.(r5) bne hardldiv mov 6.(r5),r2 mov 4.(r5),r1 bge 1f neg r1 neg r2 sbc r1 com r4 1: mov r4,-(sp) clr r0 div r3,r0 mov r0,r4 /high quotient mov r1,-(sp) / Stash interim result mov r1,r0 mov r2,r1 div r3,r0 bvc 1f mov (sp),r0 / Recover interim result. mov r2,r1 / (Regs may be clobbered by failed div.) sub r3,r0 / this is the clever part div r3,r0 tst r1 sxt r1 add r1,r0 / cannot overflow! 1: tst (sp)+ / Pop temp off stack. mov r0,r1 mov r4,r0 tst (sp)+ bpl 9f neg r0 neg r1 sbc r0 9: jmp cret hardldiv: iot / ``Cannot happen'' /* * Long remainder */ lrem: jsr r5,csv mov 10.(r5),r3 sxt r4 bpl 1f neg r3 1: cmp r4,8.(r5) bne hardlrem mov 6.(r5),r2 mov 4.(r5),r1 mov r1,r4 bge 1f neg r1 neg r2 sbc r1 1: clr r0 div r3,r0 mov r1,-(sp) / Stash interim result. mov r1,r0 mov r2,r1 div r3,r0 bvc 1f mov (sp),r0 / Recover interim result. mov r2,r1 / (Regs may be clobbered by failed div.) sub r3,r0 div r3,r0 tst r1 beq 9f add r3,r1 1: tst (sp)+ / Pop temp off stack. tst r4 bpl 9f neg r1 9: sxt r0 jmp cret hardlrem: iot / ``Cannot happen'' .globl lmul lmul: mov r2,-(sp) mov r3,-(sp) mov 8(sp),r2 sxt r1 sub 6(sp),r1 mov 12.(sp),r0 sxt r3 sub 10.(sp),r3 mul r0,r1 mul r2,r3 add r1,r3 mul r2,r0 sub r3,r0 mov (sp)+,r3 mov (sp)+,r2 rts pc #ifdef UCB_NET .globl _htonl,_htons,_ntohl,_ntohs _htonl: _ntohl: mov 2(sp),r0 mov 4(sp),r1 swab r0 swab r1 rts pc _htons: _ntohs: mov 2(sp),r0 swab r0 rts pc .globl _badaddr _badaddr: mov 2(sp),r0 mov nofault,-(sp) mov $1f,nofault tst (r0) clr r0 br 2f 1: mov $-1,r0 2: mov (sp)+,nofault rts pc .globl _bzero _bzero: mov 2(sp),r0 beq 3f / error checking... dgc mov 4(sp),r1 beq 3f / error checking ... dgc bit $1,r0 bne 1f bit $1,r1 bne 1f asr r1 2: clr (r0)+ sob r1,2b rts pc 1: clrb (r0)+ sob r1,1b 3: rts pc #endif UCB_NET .globl csv, cret #ifndef MENLO_KOV csv: mov r5,r0 mov sp,r5 mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) jsr pc,(r0) cret: mov r5,r2 mov -(r2),r4 mov -(r2),r3 mov -(r2),r2 mov r5,sp mov (sp)+,r5 rts pc #else MENLO_KOV .globl __ovno .data __ovno: 0 .text /* * Inter-overlay calls call thunk which calls ovhndlr to * save registers. Intra-overlay calls may call function * directly which calls csv to save registers. */ csv: mov r5,r1 mov sp,r5 mov __ovno,-(sp) / overlay is extra (first) word in mark mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) jsr pc,(r1) / jsr part is sub $2,sp cret: mov r5,r2 / Get the overlay out of the mark, and if it is non-zero / make sure it is the currently loaded one. mov -(r2),r4 bne 1f / zero is easy 2: mov -(r2),r4 mov -(r2),r3 mov -(r2),r2 mov r5,sp mov (sp)+,r5 rts pc / Not returning to base segment, so check that the right / overlay is mapped in, and if not change the mapping. 1: cmp r4,__ovno beq 2b / lucked out! / If return address is in base segment, then nothing to do. cmp 2(r5),$_etext blos 2b / Returning to wrong overlay --- do something! mov PS,-(sp) / save PS SPL7 mov r4,__ovno asl r4 mov ova(r4), OVLY_PAR mov ovd(r4), OVLY_PDR mov (sp)+,PS / restore PS, unmask interrupts / Could measure switches[ovno][r4]++ here. jmp 2b /* * Ovhndlr1 through ovhndlr7 are called from the thunks, * after the address to return to is put in r1. This address is * that after the call to csv, which will be skipped. */ .globl ovhndlr1, ovhndlr2, ovhndlr3, ovhndlr4 .globl ovhndlr5, ovhndlr6, ovhndlr7 ovhndlr1: mov $1,r0 br ovhndlr ovhndlr2: mov $2,r0 br ovhndlr ovhndlr3: mov $3,r0 br ovhndlr ovhndlr4: mov $4,r0 br ovhndlr ovhndlr5: mov $5,r0 br ovhndlr ovhndlr6: mov $6,r0 br ovhndlr ovhndlr7: mov $7,r0 br ovhndlr /* * Ovhndlr makes the argument (in r0) be the current overlay, * saves the registers ala csv (but saves the previous overlay number), * and then jmp's to the function, skipping the function's initial * call to csv. */ ovhndlr: mov sp,r5 mov __ovno,-(sp) / save previous overlay number cmp r0,__ovno / correct overlay mapped? bne 2f 1: mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) jsr pc,(r1) / skip function's call to csv 2: mov PS,-(sp) / save PS SPL7 mov r0,__ovno / set new overlay number asl r0 mov ova(r0), OVLY_PAR mov ovd(r0), OVLY_PDR mov (sp)+,PS / restore PS, unmask interrupts jbr 1b #endif MENLO_KOV /* * Save regs r0, r1, r2, r3, r4, r5, r6, K[DI]SA6 * starting at data location 0300, in preparation for dumping core. */ .globl _saveregs _saveregs: #ifdef KERN_NONSEP movb $RW, KISD0 / write enable #endif mov r0,300 mov $302,r0 mov r1,(r0)+ mov r2,(r0)+ mov r3,(r0)+ mov r4,(r0)+ mov r5,(r0)+ mov sp,(r0)+ mov KDSA6,(r0)+ mov KDSA5,(r0)+ rts pc .globl _nulldev, _nullsys _nulldev: / placed in insignificant entries in bdevsw and cdevsw _nullsys: / ignored system call rts pc .globl _u _u = 140000 #ifndef UCB_NET usize = 16. #else usize = 32. #endif .data .globl _ka6, _cputype, _sep_id, _ubmap #ifdef ENABLE34 .globl _enable34 _enable34: .byte 0 #endif _ubmap: .byte 0 _sep_id: .byte 0 .even #ifdef KERN_NONSEP #ifdef ENABLE34 _ka6: DEC_KISA6 #else _ka6: KISA6 #endif _cputype:40. #else KERN_NONSEP #ifdef ENABLE34 _ka6: DEC_KDSA6 #else _ka6: KDSA6 #endif _cputype:45. #endif KERN_NONSEP .bss .even intstk: .=.+INTSTK / temporary stack while KDSA6 is repointed eintstk: .=.+2 / initial top of intstk .data nofault:.=.+2 #ifndef NONFP fpp: .=.+2 #endif ssr: .=.+6 #ifdef DISPLAY dispdly:.=.+2 #endif saveps: .=.+2 #if defined(PROFILE) && !defined(ENABLE34) .text /* * System profiler * * Expects to have a KW11-P in addition to the line-frequency * clock, and it should be set to BR7. * Uses supervisor I space register 2 and 3 (040000 - 0100000) * to maintain the profile. */ CCSB = 172542 CCSR = 172540 _probsiz = 37777 .globl _isprof, _sprof, _probsiz, _mode / / Enable clock interrupts for system profiling / _isprof: mov $1f,nofault mov $_sprof,104 / interrupt mov $340,106 / pri mov $100.,CCSB / count set = 100 mov $113,CCSR / count down, 10kHz, repeat 1: clr nofault rts pc / / Process profiling clock interrupts / _sprof: mov r0,-(sp) mov PS,r0 ash $-10.,r0 bic $!14,r0 / mask out all but previous mode add $1,_mode+2(r0) adc _mode(r0) cmp r0,$14 / user beq done mov 2(sp),r0 / pc asr r0 asr r0 bic $140001,r0 cmp r0,$_probsiz blo 1f inc _outside br done 1: mov $10340,PS / Set previous mode to supervisor mfpi 40000(r0) inc (sp) mtpi 40000(r0) done: mov (sp)+,r0 mov $113,CCSR rtt .data _mode: .=.+16. _outside: .=.+2 #endif defined(PROFILE) && !defined(ENABLE34)