mirror of
https://github.com/PDP-10/its.git
synced 2026-01-17 00:33:22 +00:00
397 lines
9.2 KiB
Plaintext
Executable File
397 lines
9.2 KiB
Plaintext
Executable File
; -*- 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 <foo>, where <foo>
|
||
; 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 /</]
|
||
jrst giveup
|
||
.call dskopn
|
||
caia
|
||
jrst load0
|
||
; No explicit file in directory, check for a semi-builtin device.
|
||
movsi d,-ndevs
|
||
came dev,devtab(d)
|
||
aobjn d,.-1
|
||
jumpge d,ffchek ; nope
|
||
; Come here with semi-builtin device index in RH(D).
|
||
load1: syscall open,[[.uii,,dskc] ? [sixbit /DSK/] ? [sixbit /ATSIGN/]
|
||
filtab(d) ? [sixbit /DEVICE/]]
|
||
jrst [ ; it -should- be there, so say device not available
|
||
syscall jobret,[movei bojc ? [%enadv,,0]]
|
||
jfcl
|
||
stop ]
|
||
; Come here when DSKC has been successfully opened.
|
||
load0: movsi 17,loader
|
||
blt 17,17
|
||
jrst loadit
|
||
|
||
zero==:0
|
||
|
||
;;;If this thing gives the %ENACR error, it does a bunch of wierd things
|
||
;;;after the JOBRET, but none of them seem to be harmfull...
|
||
loader: offset -.
|
||
zero:: %enacr,,0 ;No core available. (must be in zero!)
|
||
crapit:: .call crap
|
||
.logout
|
||
loadit:: .core 0 ;Start here.
|
||
.logout
|
||
.call load
|
||
jrst crapit
|
||
.iot a,crap ;This better get an instruction!
|
||
.iopdl
|
||
crap:: setz
|
||
sixbit /jobret/
|
||
movei bojc
|
||
load:: setz zero ;Dual purpose!
|
||
sixbit /load/
|
||
movei %jself
|
||
setzi dskc
|
||
offset 0
|
||
|
||
ifg <.-loader>-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,[#<setz 1_bojc>]
|
||
.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
|