/ options. .ht = 0 / tu-16 is dump device .mt = 1 / tu-10 is dump device .rk = 0 / rk-05 is dump device .pdp70 = 0 / 11/70 is target machine .pdp45 = 1 / 11/45 is target machine .fp = 1 / floating point processor present .hpdisk = 0 / enanble ecc error correction code for hp disk .newputc = 1 / set if want new superior getc/putc .display = 1 / enable location 52 as magic pattern !! .idle = 0 / 0=> place idle in l45.s 1=> place idle here / indicate highest priority at which character queues / will be accessed _spl_tty = _spl5 tty_prio = 5 / machine language assist for a pdp-11/70 with fpp / extended and (improved) J. N. Rottman / This code will also work on an 11/45 if the test on the / CPU error register is replaced with a slower direct comparison / on the kernal SP. (pdp70=0) / External definitions for l.s .globl dump, start, call, code00, code01, code02, code03 .globl code04, code05, code06, pirqi / External data references .globl _etext, _edata, _end, _regloc, _cfreelist, _cfreecount .globl _runrun / External text references .globl _main, _trap, _swtch, _wakeup / External data definitions .globl _ka6, _cputype, nofault, ssr, _u / External text definitions .globl _savfp, _incupc, _display, _getc, _putc, _backup .globl _fubyte, _fuword, _subyte, _suword .globl _fuibyte, _suibyte, _fuiword, _suiword, _spl_tty .globl _savu, _retu, _aretu .if .idle .globl _idle .endif .if .display .globl diswflag .endif .globl _spl0, _spl1, _spl4, _spl5, _spl6, _spl7 .globl _copyin, _copyout, _clearseg, _copyseg .globl _dpcmp, _ldiv, _lrem, csv, cret .globl _btoc, _itol / Non-unix instructions mfpi = 6500 ^ tst mtpi = 6600 ^ tst mfpd = 106500 ^ tst mtpd = 106600 ^ tst spl = 230 ldfps = 170100 ^ tst stfps = 170200 ^ tst stst = 170300 ^ tst wait = 1 rti = 2 rtt = 6 halt = 0 reset = 5 / / Mag-tape dump. / Save the registers in low core and write all / of core onto magtape. Entry is from 44 abs. / / Registers r0, r1, r2, r3, r4, r5, r6, KIA6 / are saved in low core starting at location 4. / The blocksize for the type is 512. bytes. / .data dump: 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)+ .if .mt 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 mov $60007,-(r0) br . .endif .if .ht reset mov $1300,*$HTTC mov $HTCS1,r0 mov $60,(r0) 1: mov $177000,*$HTFC mov $177400,*$HTWC inc (r0) 2: tstb (r0) bge 2b tst (r0) bge 1b mov $27,(r0) br . HTCS1 = 172440 HTWC = 172442 HTBA = 172444 HTFC = 172446 HTCS2 = 172450 HTTC = 172472 .endif / Startup code. Since core is shuffled, this code can / be execute but once. start: mov $code15,*$0 / set to catch spurious interrupts / also prevent restart from zero reset clr PS / set KIO to physical 0 mov $77406,r3 mov $KISA0,r0 mov $KISD0,r1 clr (r0)+ mov r3,(r1)+ / set KI1-6 to eventual text resting place mov $_end+63.,r2 ash $-6,r2 bic $!1777,r2 1: mov r2,(r0)+ mov r3,(r1)+ add $200,r2 cmp r0,$KISA7 blos 1b / set KI7 to IO segment for escape mov $IO,-(r0) / set KD0-7 to physical mov $KDSA0,r0 mov $KDSD0,r1 clr r2 1: mov r2,(r0)+ mov r3,(r1)+ add $200,r2 cmp r0,$KDSA7 blos 1b / Initialization : / get a temporary 1-word stack and turn on / segmentation. Then copy text to I space / and clear the bss in data space. mov $stk+2,sp mov $5,SSR3 / K+U sep. inc SSR0 mov $_etext,r0 mov $_edata,r1 add $_etext-8192.,r1 1: mov -(r1),-(sp) mtpi -(r0) cmp r1,$_edata bhi 1b 1: clr (r1)+ cmp r1,$_end blo 1b / Use KI escape to set KD7 to IO segment. Set KD6 to the / first available core to serve as the swap process's / u-table mov $IO,-(sp) mtpi *$KDSA7 mov $_etext-8192.+63.,r2 ash $-6,r2 bic $!1777,r2 add KISA1,r2 mov r2,KDSA6 / Set up the real stack at the top of the u-table, and / clear the rest of it mov $_u+[usize*64.],sp mov $_u,r0 1: clr (r0)+ cmp r0,sp blo 1b / Start system profiling / jsr pc,_isprof / Set up previous mode as user mode and call main. / On return, enter user mode at 0R mov $30000,PS jsr pc,_main mov $170000,-(sp) clr -(sp) rtt .text / Entry to the system from all traps, interrupts, and aborts is / handled in the following code. / / Each device's vector contains a new kernal PS at the device's / bus grant priority, and a pointer to a code segment of the / form: / jsr r0,call; _xxxxxxx / where `xxxxxxx' is the name of the device's interrupt routine. / / Traps and aborts are more complicated. Entry is always in / kernal mode at priority 7, and enters the following routines: / / 1) code00 Floating point asynchronous interrupt. If / the user is active, the interrupt is reported / back immediately. Otherwise, since the interrupt / is asynchronous, it could occur from kernal mode / or supervisor mode. In this case the interrupt is / just posted for the user, and if the interrupted / priority is high, the actual processing is PIRQ'd / at priority 1. Since the FEA and FEC are volitile, / they are saved when the interrupt occurs. They / cannot be restored, but may be retrieved via a system / call. / / 2) code01 IOT. If the request came from the supervisor state, / it is a request for an interrupt exit from a super- / visor interrupt handler. The handler could not do / the rti directly since it could have interrupted a kernal / task. / If the previous mode was user mode, the trap / is posted in the usual way. For efficiency, no check / is made to distinguish supervisor from kernal iot's, / which should never occur. / / 3) code02 BPT/trace trap, illegal instruction, system entry: / If these are from the user they are handled in the / standard manner. / Any of these calls from the supervisor abort / it with an indicative error code. / Any of these calls from the kernal are fatal. / / 4) code03 Power-fail/parity. These are always fatal hardware / errors. / / 5) code04 EMT. If this code is from the supervisor, it is a / request for a kernal function. If the function code / is legal, the function is performed and control returns; / otherwise, the supervisor is aborted. / From user mode this is just a trappable signal. / / 6) code05 Bus error. The cpu error register is interrogated to / see if this a stack overflow (code07) or a bus error. / The following applies just to real bus errors: / nofault_______ is checked; if it is non-zero it is / the address of an error catching routine to which control / should be returned on the rti. Otherwise, bus errors / are handled like class (3). / / 7) code06 Segmentation violation. If nofault is set, the / segmentation error registers are thawed, and control / returns immediately. If the error comes from super- / visor state, the supervisor is aborted. If it comes / from kernal state, the system dies. If it comes from / user state, the error registers are saved for a possible / stack page fault backup. / / 8) code07 Bad PIRQ, stack overfow. (see (6)). These are fatal / software botches. / / / The codes reported to trap are: / 0 User floating point exception / 1 Kernal floating point exception / 2 Illegal instruction / 3 BPT/trace trap / 4 SYS entry / 5 IOT / 6 EMT / 7 Bus error / 10 Segmentation violation / 11 Power fail / 12 Parity / 13 Bad PIRQ / 14 Stack limit overflow / 22 Kernal illegal instruction / 23 Kernal BPT / 24 Kernal SYS / 25 Kernal ... / code00: stst _u+4 / save FEC and FEA in active u bit $340,2(sp) / from high priority ? beq codeff / no - handle immediately bis $PIRQ1,PIRQ / set for later processing rti / and split pirq1: bic $PIRQ1,PIRQ / dispatch from PIRQ request 1 codeff: clr -(sp) / trap code bit $20000,PS / from user mode ? bne callt1 / yes inc (sp) / set to post and leave br callt1 / don't add in displacment pirq2: pirq3: pirq4: pirq5: pirq6: pirq7: clr PIRQ / Illegal PIRQ's - clear register mov $13,-(sp) / set code br callt1 / report fatal error code05: .if .pdp70 / Use CPU error register bit $200,CPUERR / illegal halt ?? beq 3f / --> no mov $2,-(sp) / set illegal instruction br callt1 3: bit $14,CPUERR beq 1f / bus error /*agsm clr SLR / give a decent dump /*agsm .data slrbef: . = . + 2 r0save: . = . + 2 spsave: . = . + 2 .globl spsave .text tst slrbef / prior stack limit trap ?? bne 9f / --> yes bit $4,CPUERR beq 8f / --> YELLOW Violation 9: mov r0,r0save mov sp,spsave mov sp,r0 / save current (offending??) sp mov $142000,sp / reset stack. mov 2(r0),-(sp) / save the troublesome ps mov (r0),-(sp) / save the troublesome pc mov r0save,r0 br 7f 8: sub $400,SLR / let the yellow happen inc slrbef / indicate we already got one !! 7: /*agsm mov $14,-(sp) / report code br callt1 .endif .if .pdp45 STV = 14. / stack trap code tst sp /red violation bne 1f mov $_u+[usize*64.],sp /re-use stack mov *$2,-(sp) /PSW mov *$0,-(sp) /PC 0: mov $STV,-(sp) /stack trap br callt1 1: incb SLR+1 /highest address protected cmp SLR,sp /better than add $400,SLR blo 2f sub $1000,SLR /give an extra 256 bytes br 0b 2: decb SLR+1 /restore stack limit clr -4(sp) /real bus error .endif 1: tst nofault / catchable? beq 1f / no 2: mov nofault,(sp) / adjust return rti / exit 1: mov $7,-(sp) / proper code br callt code06: tst nofault / catchable ? beq 1f / no mov $1,SSR0 / thaw registers br 2b / and take nofault exit 1: bit $20000,PS / user mode ? beq 1f / no - don't overwrite ssr mov SSR0,ssr / save for possible backup mov SSR1,ssr+2 mov SSR2,ssr+4 1: mov $1,SSR0 / thaw error registers mov $10,-(sp) / segmentation code br callt code03: code15: / Hardware-type botches mov PS,-(sp) / previous mode is unimportant br callt1 / so ignore it here code01: code02: code04: mov PS,-(sp) / save emt trap code / br callt callt: bit $20000,PS / see if user fault bne callt1 / yes add $20,(sp) / adjust code for kernal fault callt1: spl 0 / out of critical section mov (sp),-(sp) / save device code mov r0,2(sp) mov r1,-(sp) mfpd sp / get a sp mov 4(sp),-(sp) / device again mov $1f,r0 / point to trap br 2f .data; 1: _trap; .text call: mov PS,-(sp) / Entry from device interrupt vector mov r1,-(sp) mfpd sp mov 4(sp),-(sp) 2: bic $!37,(sp) / extra bits in code mov nofault,6(sp) clr nofault / catch errors bit $20000,PS / from user mode ? beq 1f / no - call routine and split mov $20,_u+8. / set maint. bit jsr pc,*(r0)+ / call routine 2: spl 6 / interlock tstb _runrun beq 2f / see if we should schedule spl 0 / end of interlock jsr pc,_savfp jsr pc,_swtch br 2b 2: mov $_u+8,r1 .if .fp bit $20,(r1) / floating registers saved? bne 2f / no mov (r1),r0 / saved fps bic $4000,(r1) / interrupt on floating undefined ldfps (r1)+ movf (r1)+,fr0 movf (r1)+,fr1 movf fr1,fr4 movf (r1)+,fr1 movf fr1,fr5 movf (r1)+,fr1 movf (r1)+,fr2 movf (r1)+,fr3 ldfps r0 / user's cc's .endif 2: tst (sp)+ / "dev" mtpd sp br 2f 1: jsr pc,*(r0)+ cmp (sp)+,(sp)+ / dump dev and sp 2: mov (sp)+,r1 mov (sp)+,nofault mov (sp)+,r0 / fix015 gregr & chrism / to make t bit tracing work properly bit $3400,2(sp) bne 1f rti 1: bic $3400,2(sp) / end of fix015 rtt / / / PIRQ interrupt / pirqi: mov PIRQ,-(sp) / PIRQ interrupt dispatch movb (sp),PS / set to active PIRQ priority bic $!16,(sp) / prepare word dispatch add $1f-2,(sp) mov *(sp)+,pc / disptach on PIRQ priority .data; 1: pirq1; pirq2; pirq3; pirq4; pirq5; pirq6; pirq7; .text / / Save the user's floating point registers. / Use the maint. bit to indicate if done. / _savfp: mov $_u+8.,r1 .if .fp bit $20,(r1) beq 1f stfps (r1)+ movf fr0,(r1)+ movf fr4,fr0 movf fr0,(r1)+ movf fr5,fr0 movf fr0,(r1)+ movf fr1,(r1)+ movf fr2,(r1)+ movf fr3,(r1)+ .endif 1: rts pc / / Handle counts for user profiles / _incupc: 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 mul 6(r2),r0 / scale ashc $-14.,r0 inc r1 bic $1,r1 cmp r1,2(r2) / length bhis 1f add (r2),r1 / base mov $2f,nofault mfpd (r1) inc (sp) mtpd (r1) br 3f 2: clr 6(r2) 3: clr nofault 1: mov (sp)+,r2 rts pc / / Display the contents of the word whose address is / in the switch registers. If bit 0 is set, the word / refers to supervisor space; otherwise, it refers to / kernal data space / _display: .if .display tst diswflag //// previously waiting ?? bne 0f //// -> yes. mov $5,displw //// slow up the display. br 2f 0: clr diswflag dec displw jge 2f //// -> display not to change mov $2,displw mov dispat+0,r0 mov dispat+2,r1 ashc dishift,r0 //// form next dispat in sequence mov r0,dispat+0 mov r1,dispat+2 ashc $8.,r0 //// extract the dispat for display bit $077776,r0 //// need to start dishifting the other way ?? bne 1f //// -> no. neg dishift 1: mov r0,*$52 //// store for later display 2: .data dispat: 17;0 //// starting pattern (only use middle 22 bits) dishift: 1 //// either 1 or -1 (the dishift direction) displw: 1 //// use to delay the display diswflag: 0 //// set by _idle to indicate wait done .text .endif mov PS,-(sp) mov $30300,PS / previous mode is user mov $3f,nofault 1: mov CSW,r1 bit $1,r1 beq 1f dec r1 mfpi (r1) mov (sp)+,r0 br 4f 1: mov (r1),r0 4: mov r0,CSW 3: clr nofault mov (sp)+,PS rts pc / / Character list get/put / .if .newputc .globl _cblockm, _cblockl / c = getc( cp ) struct clist *cp; _getc: mov r2,-(sp) mov 4(sp),r2 mov PS,-(sp) spl 6 mov 2(r2),r1 / first ptr beq 5f / buffer empty 0: movb (r1)+,r0 bic $!377,r0 dec (r2)+ / update count beq 4f / return last block to free bit _cblockm,r1 beq 2f / return empty block to free mov r1,(r2) 1: mov (sp)+,PS mov (sp)+,r2 rts pc 2: sub _cblockl,r1 mov (r1),(r2) add $2,(r2) / update first pointer 3: mov _cfreelist,(r1) mov r1,_cfreelist br 1b 4: clr (r2)+ clr (r2) dec r1 bic _cblockm,r1 br 3b 5: mov $-1,r0 br 1b / putc( c , cp ) struct clist *cp; _putc: mov 4(sp),r0 mov PS,-(sp) spl 6 mov 4(r0),r1 / last ptr beq 4f / buffer empty bit _cblockm,r1 beq 2f / block full 0: movb 4(sp),(r1)+ mov r1,4(r0) inc (r0) / update count clr r0 1: mov (sp)+,PS rts pc 2: sub _cblockl,r1 mov _cfreelist,-(sp) beq 3f / freelist empty ( r0 != 0 ) mov *(sp),_cfreelist mov (sp),(r1) mov (sp)+,r1 clr (r1)+ br 0b 3: tst (sp)+ br 1b 4: mov _cfreelist,r1 beq 1b / freelist empty ( r0 != 0 ) mov (r1),_cfreelist clr (r1)+ mov r1,2(r0) / set first ptr br 0b .endif .if .newputc - 1 _getc: mov 2(sp),r1 mov PS,-(sp) mov r2,-(sp) spl tty_prio mov 2(r1),r2 / first ptr beq 9f / empty movb (r2)+,r0 / character bic $!377,r0 mov r2,2(r1) dec (r1)+ bne 1f clr (r1)+ clr (r1)+ / last ptr br 2f 1: bit $7,r2 bne 3f mov -10(r2),(r1) / next block add $2,(r1) 2: dec r2 bic $7,r2 mov _cfreelist,(r2) mov r2,_cfreelist inc _cfreecount 3: mov (sp)+,r2 mov (sp)+,PS rts pc 9: clr 4(r1) mov $-1,r0 br 3b _putc: mov 2(sp),r0 mov 4(sp),r1 mov PS,-(sp) mov r2,-(sp) mov r3,-(sp) spl tty_prio mov 4(r1),r2 / last ptr bne 1f mov _cfreelist,r2 beq 9f mov (r2),_cfreelist dec _cfreecount clr (r2)+ mov r2,2(r1) br 2f 1: bit $7,r2 bne 2f mov _cfreelist,r3 beq 9f mov (r3),_cfreelist dec _cfreecount mov r3,-10(r2) mov r3,r2 clr (r2)+ 2: movb r0,(r2)+ mov r2,4(r1) inc (r1) clr r0 3: mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,PS rts pc 9: mov pc,r0 br 3b .endif / / Backup a user's registers after a stack page / fault / _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 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 / / Interspace communitcation routines / _fuibyte: mov 2(sp),r1 bic $1,r1 jsr pc,giword br 2f _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: 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 rts pc _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 rts pc _fuiword: mov 2(sp),r1 jsr pc,giword rts pc _fuword: mov 2(sp),r1 jsr pc,gword rts pc giword: mov $err,nofault mfpi (r1) br 1f gword: mov $err,nofault mfpd (r1) 1: mov (sp)+,r0 br 2f _suiword: mov 2(sp),r1 mov 4(sp),r0 jsr pc,piword rts pc _suword: mov 2(sp),r1 mov 4(sp),r0 jsr pc,pword rts pc piword: mov $err,nofault mov r0,-(sp) mtpi (r1) br 1f pword: mov $err,nofault mov r0,-(sp) mtpd (r1) 1: clr r0 2: clr nofault rts pc err: mov $-1,r0 tst (sp)+ br 2b / / Block/word transfers to/from kernal/user/supervisor space / / / call from C is / copy[in/out](from, to, byte_count, segflag) / on entry previous mode must be user / from and to must be even addresses, / byte_count must also be even / segflag is: / 0: to/from user data / 1: to/form kernal data / 2: to/from user text / 3: to/from supervisor region _copyin: jsr pc,copsu br 4f / transfer from user data br 2f / transfer from kernal data br 1f / transfer from supervisor 1: mfpi (r0)+ mov (sp)+,(r1)+ sob r2,1b br 5f 2: mov (r0)+,(r1)+ / transfer from krnal data sob r2,2b / word count br 5f 4: mfpd (r0)+ / transfer from user data mov (sp)+,(r1)+ sob r2,4b br 5f _copyout: jsr pc,copsu br 4f / transfer to user data br 2b / transfer to system data br 3f / transfer to user text 3: mov (r0)+,-(sp) / transfer to supervisor i/d mtpi (r1)+ sob r2,3b br 5f 4: mov (r0)+,-(sp) mtpd (r1)+ / transfer to user data sob r2,4b 5: clr r0 / successful transfer 6: mov (sp)+,PS / common exit clr nofault mov (sp)+,r2 / count register rts pc / exit copsu: mov (sp)+,r0 / general set-up for copyxx mov r2,-(sp) mov PS,-(sp) mov 14(sp),-(sp) / get segflag cmp (sp),$3 / if its to supervisor mod bne 1f / then set previous mode bic $20000,PS / to supervisor mode 1: asl (sp) / word displacment add r0,(sp) /return address mov 10(sp),r0 / from mov 12(sp),r1 / to mov 14(sp),r2 / byte count asr r2 / to word count mov $1f,nofault / error catcher rts pc / to offset branch 1: mov $-1,r0 / error catcher br 6b / exit with indicator .if .idle / / Just idle while nothing is active to speed up transfers / _idle: .if .display inc diswflag / indicate wait in progress .endif wait rts pc .endif / / Routines to do context switching / _savu: mov (sp)+,r1 mov (sp),r0 mov sp,(r0)+ mov r5,(r0)+ jmp (r1) _aretu: mov (sp)+,r1 mov (sp),r0 spl 7 / critical part where stack is switched br 1f _retu: mov (sp)+,r1 spl 7 / critical region mov (sp),KDSA6 mov $_u,r0 1: mov (r0)+,sp mov (r0)+,r5 spl 0 jmp (r1) / / Routine to set priorities / _spl0: spl 0 rts pc _spl1: spl 1 rts pc _spl4: spl 4 rts pc _spl5: spl 5 rts pc _spl6: spl 6 rts pc _spl7: spl 7 rts pc / / Copy and clear user sements (64 bytes) / Called with previous mode = user mode / _copyseg: mov UISA0,-(sp) / appropriate bottom two user regs. mov UISA1,-(sp) mov UISD0,-(sp) mov UISD1,-(sp) mov 12(sp),UISA0 /from segment mov 14(sp),UISA1 / to segment mov $6,UISD0 mov $6,UISD1 mov r2,-(sp) clr r0 mov $8192.,r1 mov $32.,r2 1: mfpi (r0)+ / get a word mtpi (r1)+ / put a word sob r2,1b / loop 'till done mov (sp)+,r2 mov (sp)+,UISD1 mov (sp)+,UISD0 mov (sp)+,UISA1 mov (sp)+,UISA0 rts pc _clearseg: mov UISA0,-(sp) / get a user register mov UISD0,-(sp) mov 6(sp),UISA0 mov $6,UISD0 mov $32.,r1 clr r0 1: clr -(sp) / clear 32. words mtpi (r0)+ sob r1,1b mov (sp)+,UISD0 mov (sp)+,UISA0 rts pc .if .hpdisk .globl _hpecc / / Error correction for hp disk / _hpecc: mov r3,-(sp) / save some registers mov r2,-(sp) mov UISA0,-(sp) / and some segmentation registers mov UISD0,-(sp) mov PS,-(sp) / for previous mode set mov HPPOS,r3 / bit position of error burst dec r3 / adjust for zero offset clr r2 / into word and bit pair div $16.,r2 / r2 word, r3 bit offset mov r2,-(sp) / save for later end check mov r2,r1 / convert to bytes asl r1 sub $512.,r1 / back up one sector sxt r0 / will be negative always add HPBAE,r0 / high order physical address add HPBA,r1 / low order physical address adc r0 / long arithmetic div $64.,r0 / into KT-11 pages bis $30000,PS / previous is now user mode mov $406,UISD0 / short read/write page (128 bytes) mov r0,UISA0 / into this page mov r1,r2 / word offset in block mov HPPAT,r1 / get correction pattern clr r0 / double precision ashc r3,r0 / fix by bit offset mfpi (r2) / get first word xor r1,(sp) / fix low order mtpi (r2)+ / replace word cmp (sp)+,$255 / don't exceed block beq 1f / only one word correction mfpi (r2) / fetch second word xor r0,(sp) / high order correction mtpi (r2) / and replace word 1: mov (sp)+,PS / now do the mandatory restore mov (sp)+,UISD0 / sequence mov (sp)+,UISA0 mov (sp)+,r2 mov (sp)+,r3 mov HPWC,r0 / see if in mid-transfer beq 1f / no - return 0, we're done inc HPCS1 / complete transfer and return(!=0) 1: rts pc HPCS1 = 176700 / Disk registers used above HPWC = 176702 HPBA = 176704 HPPOS = 176744 HPPAT = 176746 HPBAE = 176750 .endif / General utility routines / _btoc: mov 2(sp),r1 clr r0 add $63.,r1 adc r0 ashc $-6,r0 mov r1,r0 rts pc _dpcmp: mov 2(sp),r0 mov 4(sp),r1 sub 6(sp),r0 sub 8(sp),r1 sbc r0 bge 1f cmp r0,$-1 bne 2f cmp r1,$-512. bhi 3f 2: mov $-512.,r0 rts pc 1: bne 2f cmp r1,$512. blo 3f 2: mov $512.,r1 3: mov r1,r0 rts pc _ldiv: clr r0 mov 2(sp),r1 div 4(sp),r0 rts pc _lrem: clr r0 mov 2(sp),r1 div 4(sp),r0 mov r1,r0 rts pc _itol: mov 4(sp),r1 mov 2(sp),r0 rts pc 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 _u = 140000 usize = 16. CSW = 177570 PS = 177776 SSR0 = 177572 SSR1 = 177574 SSR2 = 177576 SSR3 = 172516 KISA0 = 172340 KISA1 = 172342 KISA7 = 172356 KISD0 = 172300 KDSA0 = 172360 KDSA6 = 172374 KDSA7 = 172376 KDSD0 = 172320 SISD0 = 172200 SISA0 = 172240 SISD7 = 172216 SISD6 = 172214 SISA6 = 172254 MTC = 172522 UISA0 = 177640 / user instruction address 0 UISA1 = 177642 / user instruction address 1 UISD0 = 177600 / user instruction descriptor 0 UISD1 = 177602 / user instruction descriptor 1 PIRQ = 177772 / program interrupt request PIRQ1 = 001000 / request at priority 1 PIRQ2 = 002000 / request at priority 2 PIRQ3 = 004000 / request at priority 3 PIRQ4 = 010000 / request at priority 4 PIRQ5 = 020000 / request at priority 5 PIRQ6 = 040000 / request at priority 6 PIRQ7 = 100000 / request at priority 7 CPUERR = 177766 / cpu error register SLR = 177774 / stack limit register IO = 177600 .data _ka6: KDSA6 / pointer to u-page segment address register _cputype: 45. / pdp-11/45 or pdp-11/70 stk: 0 / one word stack for segmentation set-up .bss nofault: .=.+2 / bus error/segmentation violation bypass ssr: .=.+6 / saved backup registers _cfreecount: .=.+2 / free character count .text / system profiler / /CCSB = 172542 /CCSR = 172540 / /.globl _sprof, _xprobuf, _probuf, _probsiz, _mode /_probsiz = 7500. / /_isprof: / mov $_sprof,104 / interrupt / mov $340,106 / pri / mov $100.,CCSB / count set = 100 / mov $113,CCSR / count down, 10kHz, repeat / rts pc / /_sprof: / mov r0,-(sp) / mov PS,r0 / ash $-10.,r0 / bic $!14,r0 / add $1,_mode+2(r0) / adc _mode(r0) / tst r0 / see if user / bne done / mov 2(sp),r0 / pc / sub $8192.,r0 / low page / asr r0 / asr r0 / bic $140001,r0 / cmp r0,$_probsiz / blo 1f / inc _outside / br done /1: / inc _probuf(r0) / bne done / mov r1,-(sp) / mov $_xprobuf,r1 /2: / cmp (r1)+,r0 / bne 3f / inc (r1) / br 4f /3: / tst (r1)+ / bne 2b / mov $1,-(r1) / mov r0,-(r1) /4: / mov (sp)+,r1 /done: / mov (sp)+,r0 / mov $113,CCSR / rtt / /.bss /_xprobuf: .=.+512. /_probuf:.=.+_probsiz /_mode: .=.+16. /_outside: .=.+2