313 lines
7.9 KiB
ArmAsm
313 lines
7.9 KiB
ArmAsm
"** 01-s1.pdf page 28
|
|
" s5
|
|
" read/write a process from/to swap space
|
|
" call:
|
|
" AC/ first word of process table
|
|
" jms dskswap; DSLD bits
|
|
dskswap: 0
|
|
cll; als 3 " get process disk address
|
|
dac 9f+t " save in t0
|
|
jms dsktrans; -64; userdata; 9f+t; dskswap " read/write user area
|
|
lac 9f+t " get swap addr back
|
|
tad o20 " advance by 16??
|
|
dac 9f+t " save
|
|
jms dsktrans; -4096; 4096; 9f+t; dskswap " read/write user memory
|
|
isz dskswap " skip bits
|
|
jmp dskswap i " return
|
|
t = t+1
|
|
|
|
access: 0
|
|
lac i.flags " get inode flags
|
|
lmq " save in MQ
|
|
lac u.uid " get user id
|
|
spa " negative?
|
|
jmp access i " yes: super user, return
|
|
sad i.uid " compare to file owner
|
|
lrs 2 " same: shift flags down two
|
|
lacq " get inode flags back
|
|
and mode " AND with mode from system call
|
|
sza " access allowed?
|
|
jmp access i " yes: return
|
|
jms error " no: return error from system call
|
|
|
|
fassign: 0
|
|
-10 " loop count
|
|
dac 9f+t " in t0
|
|
1:
|
|
lac 9f+t " get count
|
|
tad d10 " turn into fd
|
|
jms fget " fetch open file into "fnode"
|
|
jms halt " will not happen
|
|
lac f.flags " get fnode flags
|
|
sma " sign bit set (active)?
|
|
jmp 1f " no: free
|
|
isz 9f+t " increment loop count & loop until zero
|
|
jmp 1b
|
|
jmp fassign i
|
|
1:
|
|
lac mode " get mode from system call
|
|
xor o400000 " set sign bit
|
|
dac f.flags " save in fnode
|
|
lac ii " get i-number
|
|
dac f.i " save in fnode
|
|
lac 9f+t
|
|
tad d10 " get fd
|
|
dac u.ac " return in user AC
|
|
dzm f.badd " clear file offset in fnode
|
|
jms fput " copy fnode back into u.ofiles
|
|
isz fassign " give skip return
|
|
jmp fassign i
|
|
t = t+1
|
|
|
|
" load fnode (open file entry) from u.ofiles
|
|
" AC/ user fd
|
|
" jms fget
|
|
" bad fd
|
|
" return with fnode set
|
|
fget: 0
|
|
jms betwen; d0; d9 " fd 0..9?
|
|
jmp fget i " no, return
|
|
cll; mul; 3 " multiply by three
|
|
lacq
|
|
"** 01-s1.pdf page 29
|
|
|
|
tad ofilesp " get pointer into u.ofiles
|
|
dac 9f+t " save in t0
|
|
dac .+2 " save as copy source
|
|
jms copy; ..; fnode; 3 " copy to "fnode"
|
|
isz fget " give skip return
|
|
jmp fget i
|
|
|
|
" copy fnode back to u.ofiles
|
|
" uses temp value set by "fget"
|
|
" (fget and fput calls must be paired)
|
|
fput: 0
|
|
lac 9f+t
|
|
dac .+3
|
|
jms copy; fnode; ..; 3
|
|
jmp fput i
|
|
t = t+1
|
|
|
|
" helper for special device write routines
|
|
" return to caller with next character to write:
|
|
" when done return character count to user.
|
|
forall: 0
|
|
lac u.base
|
|
sad u.limit
|
|
jmp 1f " done
|
|
lac u.base " get base pointer (again?)
|
|
ral " rotate MSB into LINK
|
|
lac u.base i " fetch word via base pointer
|
|
snl " link set?
|
|
lrs 9 " no: get low 9 bits
|
|
and o777 " mask to 9 bits
|
|
jmp forall i " return char
|
|
fallr: " jump here for subsequent characters
|
|
lac u.base " get base
|
|
add o400000 " advance pointer
|
|
dac u.base " start from top
|
|
jmp forall+1
|
|
1:
|
|
lac u.count
|
|
dac u.ac
|
|
jmp sysexit
|
|
|
|
" wait for a condition variable
|
|
" call:
|
|
" jmr sleep; sfiles+N
|
|
sleep: 0
|
|
law ulist-1 " pointer to process table
|
|
dac 8 " in index register
|
|
lac o200000
|
|
lmq " get 200000 in MQ
|
|
1:
|
|
lac u.ulistp i " get current process status word
|
|
sad 8 i " compare to next process table entry
|
|
jmp 1f " match
|
|
isz 8 " no match: skip other 3 words of process table
|
|
isz 8
|
|
isz 8
|
|
cla; lrs 1 " shift MQ down one
|
|
jmp 1b " loop
|
|
1:
|
|
tad o100000 " mark process not ready
|
|
dac u.ulistp i
|
|
lac sleep i " get sleep variable pointer
|
|
dac 9f+t
|
|
lac 9f+t i " get sleep variable contents
|
|
omq " or in MQ (bit vector of processes waiting)
|
|
dac 9f+t i " save
|
|
isz sleep " skip sleep variable pointer
|
|
jmp sleep i
|
|
t = t+1
|
|
|
|
"** 01-s1.pdf page 30
|
|
|
|
" look for a free directory entry??
|
|
dslot: 0
|
|
dzm di
|
|
skp
|
|
1:
|
|
isz di
|
|
lac di
|
|
jms dget " get directory entry
|
|
lac d.i " get i number
|
|
sza " zero (free)?
|
|
jmp 1b " no keep looking
|
|
jmp dslot i " yes: return index
|
|
|
|
" called with:
|
|
" AC/ mode
|
|
" name/ file name
|
|
icreat: 0
|
|
dac 9f+t " save mode in t0
|
|
jms dslot
|
|
lac o20 " look for a free inode starting at 17
|
|
dac ii
|
|
1:
|
|
isz ii
|
|
lac ii
|
|
jms iget
|
|
lac i.flags
|
|
spa " "in use" bit bit clear?
|
|
jmp 1b " no, guess again
|
|
lac ii
|
|
dac d.i
|
|
jms copy; name; d.name; 4
|
|
isz s.uniq " get a new unique number
|
|
lac s.uniq
|
|
dac d.uniq " save in directory entry
|
|
dac i.uniq " and inode
|
|
lac 9f+t " get mode
|
|
xor o400000 " set "in use"
|
|
dac i.flags
|
|
lac u.uid " get user
|
|
dac i.uid " set owner
|
|
-1
|
|
dac i.nlks " -1 links?!
|
|
dzm i.size " empty
|
|
jms copyz; i.dskps; 7 " clear disk block numbers
|
|
jms iput " write inode
|
|
jms dput " write directory entry
|
|
jmp icreat i
|
|
t = t+1
|
|
|
|
" output character to display
|
|
dspput: 0
|
|
and o177 " mask to 7 bits
|
|
sna
|
|
jmp i dspput " discard NUL
|
|
sad o14 " Form Feed?
|
|
jmp 1f " yes
|
|
lmq " save char in MQ
|
|
sad o12 " newline?
|
|
jms dspnl " yes
|
|
lac dsploc i " get display word
|
|
sad o400000 " TRAP?
|
|
jmp dspleft " yes (first character)
|
|
omq " no: or in second character
|
|
dac dsploc i " save both characters
|
|
isz dsploc " advance display pointer
|
|
jmp i dspput
|
|
|
|
"** 01-s1.pdf page 31
|
|
|
|
1: " here on form feed
|
|
jms dspinit " clear display
|
|
jmp dspput i
|
|
|
|
dspleft:
|
|
lac dsploc " get display pointer
|
|
sad edspbuf " end of the buffer?
|
|
jmp 1f " yes: light up a button!?
|
|
dac 8 " no: store in index
|
|
lac o400000 " get TRAP instruction
|
|
dac 8 i " store as next
|
|
cla; llss 18+7 " shift MQ upto "char1" position
|
|
dac dsploc i " store word with char1
|
|
jmp dspput i
|
|
|
|
dspnl: 0 " only called once!
|
|
lac dsplno " get display line number
|
|
sad d33 " 33?
|
|
jmp 1f " yes: light a button!
|
|
isz dsplno " no: increment line number
|
|
jmp dspnl i
|
|
1:
|
|
lac o2000 " get bit for push button 7
|
|
wbl " write button lights
|
|
isz dspput
|
|
jmp dspput i
|
|
|
|
dspinit: 0
|
|
lac dspbufp3 " get pointer to dspbuf+3
|
|
dac dsploc " store location
|
|
lac o400000 " display "TRAP" instruction (end of list)
|
|
dac dspbuf+3 " save in buffer
|
|
dzm dsplno " clear display line number
|
|
jmp dspinit i
|
|
|
|
" "move display" (change display buffer pointer)
|
|
" called with new buffer pointer in AC??
|
|
movdsp: 0
|
|
iof
|
|
cdf
|
|
dac dspbufp
|
|
-1
|
|
dac .dspb
|
|
ion
|
|
jmp movdsp i
|
|
|
|
" fetch user argument from word after "sys" call, return in AC
|
|
arg: 0
|
|
lac u.rq+8 i " fetch word after return PC
|
|
isz u.rq+8 " bump PC
|
|
jmp arg i
|
|
|
|
" fetch user pathname argument from pointer word after "sys" call
|
|
" into "name" and look it up (in current working directory)
|
|
" if lookup fails: returns error to user (not caller)
|
|
" if lookup OK: returns with file i-inode read (into "inode")
|
|
" and i-number in AC
|
|
argname: 0
|
|
jms arg " fetch name pointer
|
|
dac .+2 " save as copy source
|
|
jms copy; ..; name; 4 " copy to "name"
|
|
lac u.cdir " get CWD
|
|
jms namei; name " look up file
|
|
jms error " failed: return error directly to user
|
|
jmp argname i
|
|
|
|
" common code for seek/tell system calls
|
|
seektell: 0
|
|
jms arg " fetch 1st arg after sys
|
|
dac u.base " save in u.base
|
|
|
|
"** 01-s1.pdf page 32
|
|
jms arg " fetch 2nd arg (whence??)
|
|
dac u.limit " save in u.limit
|
|
jms finac " fetch fnode & inode for fd in AC
|
|
lac u.limit " get whence arg back
|
|
sna " zero?
|
|
jmp seektell i " yes, return zero (relative to start)
|
|
sad d1 " one?
|
|
jmp .+3 " yes: return pos (relative to current)
|
|
lac i.size " no: return file size (relative to end)
|
|
jmp seektell i
|
|
lac f.badd
|
|
jmp seektell i
|
|
|
|
" system call helper
|
|
" fetch system call argument name pointer from after "sys" call
|
|
" read inode; if current user is not owner, return error to user
|
|
isown: 0
|
|
jms argname
|
|
jms iget
|
|
lac u.uid " get user id
|
|
sma " super user?
|
|
sad i.uid " no: does user own file?
|
|
skp " yes, or super user
|
|
jms error " not super user, not owner: return error
|
|
jmp isown i
|
|
|