/ machine language assist / for 11/45 with ENABLE mapping box / unusual instructions halt = 0 wait = 1 reset = 5 rtt = 6 spl = 230 mfpi = 6500^tst mtpi = 6600^tst mfpd = 106500^tst mtpd = 106600^tst .data / start and dump code must go in low mem and page zero / so put it in data / RK disk dump / save registers in low core and / write all core onto disk. / entry is thru 44 abs .globl dump, dmper, dmpdn dump: bit $segenb,SSR0 beq 1f spl high br . / save regs r0,r1,r2,r3,r4,r5,r6,KIA6 / starting at abs location 4 1: 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)+ / dump all of core onto disk bis $segenb,*$SSR5 / enable ENABLE box bis $ubme,*$SSR4 / enable UNIBUS map mov $droz,RKDA / set up initial disk address clr UBMAP / and memory address clr UBMAP+2 / starting at physical 0 bit $rdy,RKCS / disk ready to be used? bne 2f / yep dmper: mov $-1,CSW halt 2: clr RKBA / make it point to prepared map page mov $-[blksiz\/2],RKWC bis $wtgo,RKCS / and start transfer 1: bit $rdy,RKCS / done? beq 1b bit $error,RKCS / error during this xfer? bne 3f / yep, make sure done add $blksiz,UBMAP / no, set up for next adc UBMAP+2 / move UNIBUS map up br 2b / and do next transfer 3: bit $nxm,RKER / off end of memory? beq dmper / nope, some other error mov $52525,CSW / yep, done dmpdn: halt .globl start, _end, _edata, _etext, _main / 11/45 with ABLE ENABLE mapping box startup / entry is thru 0 abs, indirect through 40 abs / since core is shuffled, / this code can be executed but once start: inc $-1 beq 1f spl high br . / Set loc. 0 to trap to system, in case of / hardware glitch 1: reset mov $trap,0 / in case of bad trap through 0 mov $br7+15.,2 / at level 7 with trap type 15 mov $pmu+hipri,PS / set up to copy and no disturb / set up DEC mapping registers to point to ENABLE ones mov $DKISA0,r0 / do kernel I and D clr r1 1: mov r1,(r0)+ add $pgsize,r1 cmp r0,$DKDSA6 blos 1b mov $io,(r0)+ / I/O page is special mov $DUISA0,r0 / and now user 1: mov r1,(r0)+ add $pgsize,r1 cmp r0,$DUDSA7 blos 1b / get ready to copy code / / you can't use kernel maps with the ENABLE to copy text because there / is no way to reset KISD7 without stepping on something somewhere, / since a reference to the register that holds it in the Able / box will also use the map to go through and poke at memory / note that since you must make user previous mode for D fetches / you have to use it for I as well, even though the kernel I map / is there; / / set KI0 to physical 0 mov $fkrw,r3 mov $KISA0,r0 mov $KISD0,r1 clr (r0)+ mov r3,(r1)+ / set KI1-7 to eventual text resting place / set UI1-7 as well for text copy / the K pages are made read only now since we never need / to write into them, but the U pages will be written into / in the text copy mov $_end+[clksiz-1],r2 ash $-clklen,r2 / round up to next click bic $![assize-1],r2 mov $UISA1,r4 mov $UISD1,r5 1: mov r2,(r0)+ / set A regs, K and U mov r2,(r4)+ mov r3,(r1)+ / and D mov r3,(r5)+ add $pgsize,r2 cmp r0,$KISA7 blos 1b / set UD0-6 to current text resting place mov $UDSA0,r0 mov $UDSD0,r1 mov $_edata,r2 / code comes after data mov r2,r4 / stick in safe place bic $![clksiz-1],r4 / save low bits for later ash $-clklen,r2 / stick high bits in page register bic $![assize-1],r2 1: mov r2,(r0)+ mov r3,(r1)+ add $pgsize,r2 cmp r0,$UDSA6 blos 1b / set KD0-6 to physical low memory (actually, KD6 never gets used, / but it's easiest this way) and KD7 to the I/O page mov $KDSA0,r0 mov $KDSD0,r1 clr r2 1: mov r2,(r0)+ mov r3,(r1)+ add $pgsize,r2 cmp r0,$KDSA6 blos 1b mov $io,KDSA7 mov r3,(r1)+ / initialization / get a temp (1-word) stack / turn on segmentation / / this code works while turning on the mapping non-atomically / because while the KT is not on and the ENABLE is we are running / through the KISA0 page which points to this code and the / references to the I/O page are internal and thus non mapped / or go through KDSA7 (page 31) which points to the I/O page mov $stk+2,sp mov $kud,SSR3 / enable K+U sep mov $ttbubme,SSR4 / enable 22 bit and UNIBUS map inc SSR5 / turn on ENABLE inc SSR0 / and KT / copy text to I space / clear bss in D space mov $_etext,r2 / start at end and work backward mov r2,r1 / same for source, but offset since add r4,r1 / doesn't start on click boundary in memory sub $[pgsize*clksiz],r1 1: mfpd -(r1) / read text in from D space and put out in mtpi -(r2) / I space cmp r2,$[pgsize*clksiz] bhi 1b / no first page mov $_edata,r1 1: clr (r1)+ / now work forwards clearing BSS cmp r1,$_end blo 1b / take stuff above data out of address space mov $_end+[clksiz-1],r0 ash $-clklen,r0 / get size of data in clicks bic $![assize-1],r0 mov $KDSD0,r1 1: cmp r0,$pgsize / more than one page left? bge 2f / yes, make a full sized page dec r0 / no, get partial length bge 4f / some there? clr (r1) / no, no data in this page br 3f 4: movb r0,1(r1) / set into plf field br 3f 2: movb $[pgsize-1],1(r1) 3: tst (r1)+ / next page sub $pgsize,r0 cmp r1,$KDSD6 / max data page is 5 blo 1b / set KD6 to first available core / set page 6 to USIZE length mov $_etext-[pgsize*clksiz]+[clksiz-1],r2 ash $-clklen,r2 / get number of clicks of text bic $![assize-1],r2 add KISA1,r2 / add to address of first click of text mov r2,KDSA6 / and set to usize long movb $[usize-1],KDSD6+1 / set up real sp / turn on SLR / clear user block for process zero mov $_u+[usize*clksiz],sp mov $_u+[usize*clksiz\/2]-slinc,r0 mov r0,SLR / allow half u area for stack mov $_u,r0 1: clr (r0)+ cmp r0,sp blo 1b / set up previous mode and call main / on return, enter user mode at 0R mov $pmu,PS jsr pc,_main mov $cmu+pmu,-(sp) clr -(sp) rtt halt / should never be here / all traps and interrupts are / vectored thru this routine. / must stay in D space since it contains / a jump address pointed to by the PC .globl trap, call, call1 .globl _trap, _runrun, _swtch trap: mov PS,-4(sp) tst nofault bne 1f mov SSR0,ssr mov SSR1,ssr+2 mov SSR2,ssr+4 mov $segenb,SSR0 jsr r0,call1; _trap / no return 1: mov $segenb,SSR0 mov nofault,(sp) rtt .text call1: tst -(sp) spl low br 1f call: mov PS,-(sp) 1: mov r1,-(sp) mfpd sp mov 4(sp),-(sp) bic $!37,(sp) / get minor dev. numb. - pass to subr bit $pmu,PS beq 1f / previous context kernel mode jsr pc,*(r0)+ / previous context user mode 2: spl high tstb _runrun beq 2f spl low jsr pc,_savfp jsr pc,_swtch br 2b 2: tst (sp)+ mtpd sp br 2f 1: bis $pmu,PS jsr pc,*(r0)+ cmp (sp)+,(sp)+ 2: mov (sp)+,r1 tst (sp)+ mov (sp)+,r0 rtt .globl _savfp _savfp: rts pc .globl _incupc _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 nofault,-(sp) mov $2f,nofault mfpd (r1) inc (sp) mtpd (r1) br 3f 2: clr 6(r2) 3: mov (sp)+,nofault 1: mov (sp)+,r2 rts pc .globl _display _display: dec dispdly bge 2f clr dispdly mov PS,-(sp) mov $hipri,PS mov CSW,r1 bit $1,r1 beq 1f bis $pmu,PS dec r1 1: cmp r1,$magic bne 1f mov $bounce,r1 1: mov $dsperr,-(sp) / error return will go there jsr pc,guword tst (sp)+ / pop unused return point 1: mov r0,CSW mov (sp)+,PS 2: rts pc dsperr: mov $dserdl,dispdly / 2 sec delay after CSW fault br 1b / Character list get/put .globl _getc, _putc, _unputc .globl _cfreelist _getc: mov 2(sp),r1 mov PS,-(sp) mov r2,-(sp) spl 6 mov 2(r1),r2 / first ptr beq 9f / empty movb (r2)+,r0 / character bic $!377,r0 mov r2,2(r1) dec (r1)+ / count bne 1f clr (r1)+ clr (r1)+ / last block 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 3: mov (sp)+,r2 mov (sp)+,PS rts pc 9: clr 4(r1) mov $-1,r0 mov (sp)+,r2 mov (sp)+,PS rts pc _putc: mov 2(sp),r0 mov 4(sp),r1 mov PS,-(sp) mov r2,-(sp) mov r3,-(sp) spl 6 mov 4(r1),r2 / last ptr bne 1f mov _cfreelist,r2 beq 9f mov (r2),_cfreelist clr (r2)+ mov r2,2(r1) / first ptr br 2f 1: bit $7,r2 bne 2f mov _cfreelist,r3 beq 9f mov (r3),_cfreelist mov r3,-10(r2) mov r3,r2 clr (r2)+ 2: movb r0,(r2)+ mov r2,4(r1) inc (r1) / count clr r0 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,PS rts pc 9: mov pc,r0 mov (sp)+,r3 mov (sp)+,r2 mov (sp)+,PS rts pc _unputc: / Mike Patrick, June 76 / (used in tty.c) mov 2(sp),r1 / ptr to c_cc into r1 mov PS,-(sp) / state onto stack mov r2,-(sp) / also r2 mov r3,-(sp) spl 5 mov 4(r1),r2 / c_cl into r2 beq 5f / if 0, empty queue dec r2 / Last char put in movb (r2),r0 / char into r0 dec (r1)+ / decrement count, advance r1 beq 4f / if zilch, empty queue now bit $5,r2 / check if emptied block bne 3f / if not 010b, return. (can't be 000b) bic $7,r2 / point to c_next mov _cfreelist,(r2) / put empty block on freelist mov r2,_cfreelist mov (r1),r3 / c_cf into r3 bic $7,r3 / ptr to next block down the line 1: cmp (r3),r2 / block preceding c_cl's ? beq 2f mov (r3),r3 / nope, move down the line br 1b 2: / yep clr (r3) / end of list mov r3,r2 add $10,r2 / r2 now points past last char put in 3: mov r2,2(r1) / New c_cl br 9f / return 4: clr (r1)+ / c_cf zeroed clr (r1)+ / c_cl " bic $7,r2 mov _cfreelist,(r2) / put block on freelist mov r2,_cfreelist br 9f / return 5: mov $-1,r0 / error condition 9: mov (sp)+,r3 / restore state mov (sp)+,r2 mov (sp)+,PS rts pc / bye! .globl _backup .globl _regloc _backup: mov 2(sp),r0 movb ssr+2,r1 jsr pc,fixreg movb ssr+3,r1 jsr pc,fixreg movb _regloc+7,r1 asl r1 add r0,r1 mov ssr+4,(r1) clr r0 rts pc fixreg: 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 .globl _fubyte, _subyte .globl _fuibyte, _suibyte .globl _fuword, _suword .globl _fuiword, _suiword _fuibyte: mov 2(sp),r1 bic $1,r1 jsr pc,guiword br 2f _fubyte: mov 2(sp),r1 bic $1,r1 jsr pc,guword 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,guiword 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,puiword clr r0 rts pc _subyte: mov 2(sp),r1 bic $1,r1 jsr pc,guword 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,puword clr r0 rts pc _fuiword: mov 2(sp),r1 jsr pc,guiword rts pc _fuword: mov 2(sp),r1 jsr pc,guword rts pc _suiword: mov 2(sp),r1 mov 4(sp),r0 jsr pc,puiword clr r0 rts pc _suword: mov 2(sp),r1 mov 4(sp),r0 jsr pc,puword clr r0 rts pc guiword: mov PS,-(sp) spl high mov nofault,-(sp) mov $err,nofault mfpi (r1) mov (sp)+,r0 br gpret guword: mov PS,-(sp) spl high mov nofault,-(sp) mov $err,nofault mfpd (r1) mov (sp)+,r0 br gpret puiword: mov PS,-(sp) spl high mov nofault,-(sp) mov $err,nofault mov r0,-(sp) mtpi (r1) br gpret puword: mov PS,-(sp) spl high mov nofault,-(sp) mov $err,nofault mov r0,-(sp) mtpd (r1) gpret: mov (sp)+,nofault mov (sp)+,PS rts pc err: mov (sp)+,nofault mov (sp)+,PS tst (sp)+ / throw away first return point mov $-1,r0 rts pc / these routines are used to access /dev/kmem and look at possible / NXM locations in the system. The reason it uses this mechanism / is that some locations to be examined are on the bus before the / ABLE map, and thus cannot be examined by playing with the ABLE / map regs, e.g. using the standard u access routines .globl _fkbyte, _skbyte .globl _fkword, _skword _fkword: mov 2(sp),r1 jsr pc,gkword rts pc _fkbyte: mov 2(sp),r1 bic $1,r1 jsr pc,gkword 2: cmp r1,2(sp) beq 1f swab r0 1: bic $!377,r0 rts pc _skword: mov 2(sp),r1 mov 4(sp),r0 jsr pc,pkword clr r0 rts pc _skbyte: mov 2(sp),r1 bic $1,r1 jsr pc,gkword 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,pkword clr r0 rts pc gkword: mov PS,-(sp) spl high mov nofault,-(sp) mov $err,nofault mov *r1,r0 br gpret pkword: mov PS,-(sp) spl high mov nofault,-(sp) mov $err,nofault mov r0,*r1 br gpret .globl _copyin, _copyout .globl _copyiin, _copyiout _copyiin: jsr pc,copsu 1: mfpi (r0)+ mov (sp)+,(r1)+ sob r2,1b br 2f _copyin: jsr pc,copsu 1: mfpd (r0)+ mov (sp)+,(r1)+ sob r2,1b br 2f _copyiout: jsr pc,copsu 1: mov (r0)+,-(sp) mtpi (r1)+ sob r2,1b br 2f _copyout: jsr pc,copsu 1: mov (r0)+,-(sp) mtpd (r1)+ sob r2,1b 2: mov (sp)+,nofault mov (sp)+,r2 clr r0 rts pc copsu: 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) spl low dec dispcnt / display hack bge 7f / every so often mov $15.,dispcnt / frob the pattern mov r2,-(sp) mov lpat,r1 mov rpat,r2 mov r1,r0 / make the pattern bis r2,r0 mov r0,*$bounce / zap it out tstb r2 / bouncing? bpl 1f com pinout / yes, reverse direction 1: tst r1 / back at the start bpl 5f tst pinout beq 5f clr pinout / yes, reverse again and hack mask tst binout / mask getting shorter? beq 4f / no, longer rol lbit tst lbit / ran off end? bpl 1f / yes, reverse ror lbit / undo damage com binout / use these bits br 3f / in the other mode 1: ror rbit 2: bic lbit,r1 bic rbit,r2 br 6f 4: rol rbit / same idea here, cept other way tstb rbit bpl 1f ror rbit com binout br 2b / let him do it 1: ror lbit 3: bis lbit,r1 bis rbit,r2 br 6f 5: tst pinout / going in? bne 1f / no, out ror r1 / the tst cleared C rol r2 br 6f 1: rol r1 ror r2 6: mov r1,lpat mov r2,rpat mov (sp)+,r2 7: wait _waitloc: mov (sp)+,PS rts pc .globl _boot / Reboot system from hdw bootstrap _boot: mov $io,DKISA7 / point map page at ROM bootstrap jmp *$BOOT / No return .globl _savu, _retu, _aretu _savu: spl high mov (sp)+,r1 mov (sp),r0 mov sp,(r0)+ mov r5,(r0)+ spl low jmp (r1) _aretu: spl 7 mov (sp)+,r1 mov (sp),r0 br 1f _retu: spl 7 mov (sp)+,r1 mov (sp),KDSA6 mov $_u,r0 1: mov (r0)+,sp mov (r0)+,r5 spl low jmp (r1) .globl _spl0, _spl1, _spl4, _spl5, _spl6, _spl7 _spl0: spl low rts pc _spl1: spl 1 rts pc _spl4: spl 4 rts pc _spl5: spl 5 rts pc _spl6: spl 6 rts pc _spl7: spl high rts pc .globl _copyseg _copyseg: mov PS,-(sp) mov UISA0,-(sp) mov UISA1,-(sp) mov $pmu+hipri,PS mov 10(sp),UISA0 mov 12(sp),UISA1 mov UISD0,-(sp) mov UISD1,-(sp) mov $ocrw,UISD0 mov $ocrw,UISD1 mov r2,-(sp) clr r0 mov $[pgsize*clksiz],r1 mov $[clksiz\/2],r2 1: mfpi (r0)+ mtpi (r1)+ sob r2,1b mov (sp)+,r2 mov (sp)+,UISD1 mov (sp)+,UISD0 mov (sp)+,UISA1 mov (sp)+,UISA0 mov (sp)+,PS rts pc .globl _clearseg _clearseg: mov PS,-(sp) mov UISA0,-(sp) mov $pmu+hipri,PS mov 6(sp),UISA0 mov UISD0,-(sp) mov $ocrw,UISD0 clr r0 mov $[clksiz\/2],r1 1: clr -(sp) mtpi (r0)+ sob r1,1b mov (sp)+,UISD0 mov (sp)+,UISA0 mov (sp)+,PS rts pc .globl _dpadd _dpadd: mov 2(sp),r0 add 4(sp),2(r0) adc (r0) rts pc .globl _dpcmp _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 .globl _ldiv _ldiv: clr r0 mov 2(sp),r1 div 4(sp),r0 rts pc .globl _lrem _lrem: clr r0 mov 2(sp),r1 div 4(sp),r0 mov r1,r0 rts pc .globl _lshift _lshift: mov 2(sp),r1 mov (r1)+,r0 mov (r1),r1 ashc 4(sp),r0 mov r1,r0 rts pc .globl csv csv: mov r5,r0 mov sp,r5 mov r4,-(sp) mov r3,-(sp) mov r2,-(sp) jsr pc,(r0) .globl cret cret: mov r5,r2 mov -(r2),r4 mov -(r2),r3 mov -(r2),r2 mov r5,sp mov (sp)+,r5 rts pc / Constants CSW = 177570 / various registers PS = 177776 SLR = 177774 / stack limit register BOOT = 173220 / bootstrap address UBMAP = 170200 / UNIBUS map registers SSR0 = 177572 SSR1 = 177574 SSR2 = 177576 SSR3 = 172516 SSR4 = 163676 / ENABLE SSR5 = 163674 / EN KISA0 = 163700 / EN KISA1 = 163702 / EN KISA7 = 163716 / EN DKISA0 = 172340 / KT DKISA7 = 172356 / KT KISD0 = 172300 KISD7 = 172316 KDSA0 = 163720 / EN KDSA6 = 163734 / EN KDSA7 = 163776 / EN DKDSA6 = 172374 / KT KDSD0 = 172320 KDSD6 = 172334 UISA0 = 163736 / EN UISA1 = 163740 / EN DUISA0 = 177640 / KT UISD0 = 177600 UISD1 = 177602 UDSA0 = 163756 / EN UDSA6 = 163772 / EN UDSD0 = 177620 DUDSA7 = 177676 / KT / random constants low = 0 / priorities and PS stuff high = 6 hipri = 300 br7 = 340 cmu = 140000 / current mode user pmu = 30000 / previous mode user ocrw = 6 / one click read write fkrw = 77406 / 4K read/write fkro = 77402 / 4K read only segenb = 1 / segmentation enable (D and E) kud = 5 / enable kernel and user D space ttb = 20 / 22 bit adressing (E) ubme = 40 / UNIBUS map enable (E) io = 177600 / I/O page location clksiz = 100 / size of click in bytes clklen = 6 / log(clicksize) pgsize = 200 / page size in clicks assize = 2000 / address space size in clicks slinc = 400 / stack limit increment usize = 20 / user area size in clicks .globl _u _u = 140000 / fixed address of u area in KD space magic = 173030 / magic word for CSW in boot bounce = 50 / place to keep bouncing bits RKDS = 177400 / RK controller registers RKER = 177402 / status, errors, control RKCS = 177404 RKWC = 177406 / word count, bus addr and disk addr RKBA = 177410 RKDA = 177412 nxm = 2000 / nxm err bit in err reg error = 100000 / general err in csr rdy = 200 / done wtgo = 3 / write and start blksiz = 20000 / UNIBUS map page size droz = 020000 / starting address; drive 1, cyl/surf/sect 0 .data .globl _ka6, _cputype _ka6: KDSA6 / address of system stack PAR _cputype: 70. lbit: 100000 / display cruft rbit: 000001 lpat: 100000 rpat: 000001 stk: 0 / temp stack for init, must be in static area .bss .globl nofault, ssr nofault:.=.+2 ssr: .=.+6 dispdly:.=.+2 dispcnt:.=.+2 pinout: .=.+2 binout: .=.+2 .text