; -*- Midas -*- title SYS:ATSIGN DEVICE ifndef debug, debug==:0 ;;;Accumulators: a=:1 b=:2 c=:3 d=:4 op=:5 ;Initial JOBCAL loads these 5. fn1=:6 fn2=:7 snm=:10 dev=:11 ;.CALL DSKOPN uses this as FN2. Trailing digits ;are removed from here. odev=:12 ;The original value of DEV is kept here. u=:14 v=:15 w=:16 ;;;Channels: dskc==:1 bojc==:2 define syscall name,args .call [setz ? sixbit /name/ ? args(400000)] termin loc 40 0 0 jsr tsint loc 100 ; Semi-builtin devices are loaded from DSK:DEVICE;ATSIGN , where ; is one of the following: devml==:sixbit /MLDEV/ devrip==:sixbit /R.I.P./ devrmt==:sixbit /RMTDEV/ devdir==:sixbit /DIRDEV/ ; Note that you can always override this by placing an explicit link in the ; DEVICE directory. define defdev name,file if2,[ loc devtab+.cnt. sixbit /name/ loc filtab+.cnt. file ] .cnt.==.cnt.+1 termin devtab: .cnt.==0 defdev MC,devml ; We start with the foreign filesystems defdev AI,devml ; Note that these are all two characters defdev MD,devml ; long! defdev ML,devml defdev DM,devrip ; Never again... defdev KL,devrip defdev MX,devrip defdev OZ,devrip nffs==:.cnt. ; # foreign filesystems defdev TPL,devrip ; Unless otherwise defined... defdev DIR,devdir defdev DIRDSK,devdir defdev DIRSYS,devdir defdev DIRCOM,devdir defdev DIRDIR,devdir ; Is this really reasonable? defdev DIRDNR,devdir defdev DIRMC,devml defdev DIRAI,devml defdev DIRMD,devml defdev DIRML,devml defdev DIRDM,devrip ; Never more defdev DIRKL,devrip defdev DIRMX,devrip ndevs==:.cnt. ; # semi-builtin devices loc devtab+ndevs filtab: loc .+ndevs ife debug, stop=:.logout 1, ifn debug,[ $stop: 0 stop=:jsr $stop jfcl .hang ] ;end ifn debug go: .iopush dskc, ;Hack so that a single .IOPDL will close .iopush bojc, ; both channels! ifn debug,[ .suset [.roption,,a] tlnn a,%opddt jrst go1 tlo a,%opojb .suset [.soption,,a] .value [asciz ""] go1: ] ;end ifn debug .open bojc,[.uao,,'boj ? setz ? setz] stop ;He went away? move a,[-5,,op] .call jobcal stop ;He went away? tlne d,60000 stop ;Close? move odev,dev ;Save original device name. retry: came dev,[sixbit />/] camn dev,[sixbit /-20, .err Loader won't fit in accumulators. ; Come here having failed to load the obvious file. Check for possible ; foreign filesystems. ffchek: trnn dev,-1 ; A three character device name jrst pkchek ; is too short for this hack. movsi a,777700 and a,dev ; Check first two characters movsi d,-nffs ; to see if it is a foreign filesystem came a,devtab(d) aobjn d,.-1 jumpge d,pkchek ; We have decided to contact a foreign filesystem. A contains name ; of some machine to contact. RH(D) contains index into FILTAB. move dev,a .call dskopn ; Explicit link? jrst load1 ; No: use index jrst load0 ; Yes: use channel ; Come here having failed to load the obvious file, or decide on a foreign ; filesystem. Check for the names of normally mounted secondary packs. pkchek: syscall sstatu,[repeat 5,[movem a ? ] movem a] ;Get machine name. .lose %lssys movsi b,-nmach came a,machtb(b) ;Find our machine. aobjn b,.-1 move b,dsktab(b) came dev,(b) ;Look for a known disk alias. aobjn b,.-1 jumpge b,strip ;Not one of ours. syscall jobret,[movei bojc ? [%enapk,,0]] ;Pack not mounted. jfcl stop machtb: sixbit /MX/ sixbit /AI/ nmach==:.-machtb dsktab: -3,,[sixbit /second/ ? sixbit /third/ ? sixbit /fourth/] -2,,[sixbit /second/ ? sixbit /third/] nmach==:.-dsktab -1,,[sixbit /second/] ; By default, there is a second. bptab: 000600,,dev 060600,,dev 140600,,dev 220600,,dev 300600,,dev ; Come here having failed to load the obvious file, decide on a foreign ; filesystem, or detect an unmounted pack. ; Try to strip off a trailing digit. strip: movsi a,-5 strip1: ldb b,bptab(a) cail b,'0 caile b,'9 jrst strip2 ;Wasn't a digit. setzi b, ;Erase trailing digit. dpb b,bptab(a) jrst retry ;Take it from the top! strip2: jumpn b,lost ;That was really a character. aobjn a,strip1 ;Was trailing space, try previous? ;;;When we get here, there is no longer a chance that we will find a ;;;handler to load. But we do provide directorys for a couple of odd ;;;things. lost: camn fn1,[sixbit /.file./] ;Directory listing? came fn2,[sixbit /(dir)/] jrst giveup ;Nope. Giveup. setom crock ;??? How could it be otherwise? ;??? tlnn odev,77 ;Three or more character device name? ;??? jrst giveup ;Nope. Giveup. lfunbuf==:100 .vector funbuf(lfunbuf) move a,[-lfunbuf,,funbuf] move b,[sixbit /devs/] .getsys a, jrst giveup ;Whazat? jumpge a,giveup ;Huh? move b,[-lfunbuf,,funbuf] dvlook: camn dev,(b) ;Look for digit stripped name jrst dirwin ; in system's table. aobjn b,.+1 came b,a jrst dvlook giveup: syscall jobret,[movei bojc ? [%ensdv,,0]] ;No such device. jfcl stop funtb: funln==:2 ;A table of two word entries. irp foo,,[lpt,ptr,ptp,plt,cod,dis,nvd,pdp,tab,stk] sixbit /foo/ ;0 squoze 0,foo!usr ;1 termin lfuntb==:.-funtb ;;;We come here when the user has asked for a directory listing of a known ;;;system device. dirwin: move d,[-lfuntb,,funtb] funluk: hllz c,0(d) camn c,dev ;Is this a directory for a one-user device? jrst funwin ;Yup. add d,[funln,,funln] ;Next entry. jumpl d,funluk move a,[440700,,[asciz /Non-Directory Device /]] ;;;Come here with a bp to an asciz string to produce as a directory listing ;;;in A. winwin: setz d, ;Count length of string into D. move b,a ildb c,b skipe c aoja d,.-2 .suset [.smsk2,,[1_bojc]] win1: .call jobwin jrst [ .call jobcal ;??? Why is this done? Won't this trash stop ; A and D and then loop back to win1? tlne d,60000 stop jrst win1] squirt: syscall siot,[movei bojc ? a ? d] ;??? Perhaps the fact that stop ;we only use SIOT, and only use it once, ;makes it OK that we might not have our ;channel open in a matching byte size? aose crock ;IOT's should now return. This is jrst hang ; the wrong way to handle EOF! ;??? How can this AOSE fail to skip? .call jobwin jfcl hang: jfcl .hang crock: -1 tsint: 0 0 skipge u,tsint tdne u,[#] .lose hrroi u,w ;U: -1,,W syscall jobcal,[movei bojc ? u ? movem v] .dismis tsint+1 tlne v,60000 ;Close? stop hrrzs v ;Clear left half of op jumpe v,tsinx ;??? (%joopn=0) how can this happen? cain v,%joiot ;Anything but IOT just returns. skipl crock ;IOT returns if CROCK >= 0 .call jobwin jfcl tsinx: .dismis tsint+1 ;;;Come here to produce a directory listing for a single user device. ;;;D still points to a pair of words: [sixbit /foo/ ? squoze 0,foousr] funwin: move a,1(d) .eval a, ;Get address of the lock for that device. jrst dirwin ;??? Infinite loop? hrli a,1(a) hrri a,b .getloc a, ;Get lock word. jumpl b,funwn0 ;Not locked. sub a,[1,,0] .getloc a, ;Get user index. move a,[squoze 0,uname] .eval a, jrst dirwin ;??? Infinite loop? add b,a funwn0: hrli d,440600 ;BP to sixbit device name. move a,[440700,,funbuf] repeat 6,[ ildb c,d jumpe c,funwn7 addi c,40 idpb c,a ] funwn7: skipl b skipa d,[440700,,[asciz " IN USE BY "]] move d,[440700,,[asciz " NOT IN USE"]] funwn1: ildb c,d jumpe c,funwn2 idpb c,a jrst funwn1 funwn2: jumpl b,fundon ;If it was free. movsi b,(b) ;Else deposit user's name. hrri b,b .getloc b, ;Get UNAME move d,[440600,,b] repeat 6,[ ildb c,d jumpe c,fundon addi c,40 idpb c,a ] fundon: movei c,^M ;Finally a crlf. idpb c,a movei c,^J idpb c,a setzi c, idpb c,a move a,[440700,,funbuf] jrst winwin ;Send it off. ;;;Various common .CALLs ;;;.CALL DSKOPN to try to load a handler for the device name in DEV. dskopn: setz sixbit /open/ move [.uii,,dskc] move [sixbit /dsk/] move [sixbit /jobdev/] move dev setz [sixbit /device/] ;;;.CALL JOBCAL to pick up the user's call. A should have an AOBJN to a ;;;place to deposit the arguments. D will get the "opcode". jobcal: setz sixbit /jobcal/ movei bojc move a setzm d ;;;.CALL JOBWIN to cause a call to return and skip, returning no values. jobwin: setz sixbit /jobret/ movei bojc setzi 1 end go