This commit is contained in:
Tom Everett
2016-03-03 19:18:13 -07:00
18 changed files with 731 additions and 447 deletions
+1
View File
@@ -9,6 +9,7 @@ utilities:
$(AS) -o bin/chmod src/cmd/chmod.s $(AS) -o bin/chmod src/cmd/chmod.s
$(AS) -o bin/chown src/cmd/chown.s $(AS) -o bin/chown src/cmd/chown.s
$(AS) -o bin/chrm src/cmd/chrm.s $(AS) -o bin/chrm src/cmd/chrm.s
$(AS) -o bin/ls src/other/wktls.s
clean: clean:
rm -f bin/* rm -f bin/*
+14 -8
View File
@@ -1,15 +1,19 @@
# pdp7-unix # pdp7-unix
This is a project to resurrect Unix on the PDP-7 from a scan of the original This is a project to resurrect Unix on the PDP-7 from scans of the original assembly
assembly code done by Norman Wilson. code done by Norman Wilson. The scans of PDP-7 Unix are in the Unix Archive at
Right now the scans are in the Unix Archive at
http://www.tuhs.org/Archive/PDP-11/Distributions/research/McIlroy_v0/ http://www.tuhs.org/Archive/PDP-11/Distributions/research/McIlroy_v0/
as the files 0*.pdf. We now need to convert these to machine-readable as the files 0*.pdf.
assembly code, write tools such as an assembler, a filesystem creation tool,
and write from scratch missing things like a shell, ls etc. Update early March 2016: We've written an assembler, most of a user-mode
simulator and commented several source files. We now have these utilities
running: cat, cp, chmod, chown, chrm and ls.
Things to do: write a filesystem creation tool, write a shell, write the
missing utilities, try to bring the system up on a PDP-7 system. We have
a real PDP-7 and SimH as target platforms.
The code in the original scans are (c) Novell who own the rights to the Unix The code in the original scans are (c) Novell who own the rights to the Unix
source code. Everything that didn't come from the scanned pages are GPLv3. source code. Everything that didn't come from the scanned files is GPLv3.
scans holds the unmodified OCR versions of the scanned files scans holds the unmodified OCR versions of the scanned files
@@ -17,6 +21,8 @@ src/cmd holds the modified source code of the user-mode programs
src/sys holds the modified source code of the kernel src/sys holds the modified source code of the kernel
src/other holds PDP-7 source code which did not come from the scanned files
tools holds the source for the tools written to assist the project tools holds the source for the tools written to assist the project
misc holds miscellaneous notes and information misc holds miscellaneous notes and information
+2 -2
View File
@@ -247,11 +247,11 @@ call:
isz 8 isz 8
-1 -1
tad sp tad sp
sad B sad 8
skp skp
jmp 1b jmp 1b
lac ap i lac ap i
img lmq
lac dp lac dp
dac ap i dac ap i
lac ap lac ap
+2 -2
View File
@@ -54,7 +54,7 @@ floop1:
tad d4 tad d4
dac name dac name
sys open; name; ..; 0 sys open; name: ..; 0
spa spa
jmp ferror jmp ferror
dac fi dac fi
@@ -189,7 +189,7 @@ ferror:
sys write; 1:..; 4 sys write; 1:..; 4
lac d1 lac d1
sys write; 1f; 1 sys write; 1f; 1
fmp floop1 jmp floop1
1: 077012 1: 077012
hangup: hangup:
+5 -4
View File
@@ -62,7 +62,7 @@ floop1:
tad d4 tad d4
dac name dac name
sys open; name; ..; 0 sys open; name: ..; 0
spa spa
jmp ferror jmp ferror
dac fi dac fi
@@ -72,7 +72,7 @@ ferror:
lac name lac name
dac 1f dac 1f
lac d1 lac d1
sys write; 1;..; 4 sys write; 1:..; 4
lac d1 lac d1
sys write; 1f; 1 sys write; 1f; 1
jmp floop1 jmp floop1
@@ -134,7 +134,7 @@ bksp:
jmp cloop jmp cloop
cret: cret:
czm col dzm col
jmp cloop jmp cloop
pass2: pass2:
@@ -278,6 +278,7 @@ hangup:
abort: abort:
lac d1 lac d1
sys write; m2; m2s sys write; m2; m2s
jmp stop
nofiles: nofiles:
lac d1 lac d1
@@ -342,7 +343,7 @@ gcard: 0
isz gcard isz gcard
sna sna
jmp gcard i jmp gcard i
irss 9 lrss 9
sad o45 sad o45
jmp 1f jmp 1f
jms putc jms putc
+1 -1
View File
@@ -59,7 +59,7 @@ trace: 0
jmp stop jmp stop
jmp trace i jmp trace i
itrace: 0 dtrace: 0
lac pc lac pc
dac 8 dac 8
lac 8 i lac 8 i
+18 -18
View File
@@ -8,7 +8,7 @@ start:
fetch: fetch:
lac pc i lac pc i
imq lmq
and o17777 and o17777
dac addr dac addr
ecla lls 4 ecla lls 4
@@ -79,7 +79,7 @@ bor:
jmp fetch jmp fetch
band: band:
lac t2 i lac t1 i
and t2 i and t2 i
dac t4 i dac t4 i
jmp fetch jmp fetch
@@ -185,7 +185,7 @@ consop:
tad d1 tad d1
dac sp i dac sp i
isz sp isz sp
iac addr lac addr
dac sp i dac sp i
isz sp isz sp
jmp fetch jmp fetch
@@ -206,13 +206,13 @@ mcall:
dac t2 dac t2
-1 -1
tad t2 i tad t2 i
imq lmq
lac dp lac dp
dac t1 i dac t1 i
lac t1 lac t1
dac dp dac dp
isz t1 isz t1
iac pc lac pc
dac t1 i dac t1 i
lacq lacq
dac pc dac pc
@@ -247,11 +247,11 @@ call:
isz 8 isz 8
-1 -1
tad sp tad sp
sad B sad 8
skp skp
jmp 1b jmp 1b
lac ap i lac ap i
img lmq
lac dp lac dp
dac ap i dac ap i
lac ap lac ap
@@ -364,24 +364,24 @@ unaop:
jmp . i jmp . i
uadr; umin; uind; unot uadr; umin; uind; unot
badr: uadr:
lac t1 lac t1
dac t3 i dac t3 i
jmp fetch jmp fetch
bmin: umin:
-1 -1
tad t1 i tad t1 i
cma cma
dac t3 i dac t3 i
jmp fetch jmp fetch
bind: uind:
lac t1 i lac t1 i
dac t2 i dac t2 i
jmp fetch jmp fetch
bnot: unot:
lac t1 i lac t1 i
sna cla sna cla
lac d1 lac d1
@@ -412,22 +412,22 @@ s = n+a
t = s+a t = s+a
u = t+a u = t+a
x = u+a x = u+a
f = x+a y = x+a
d1: 1 d1: 1
dm1: -1 dm1: -1
dm2: -2 dm2: -2
o17777: 017777 o17777: 017777
:1: 0 t1: 0
:2: 0 t2: 0
:3: 0 t3: 0
:4: 0 t4: 0
:ddr: 0 addr: 0
pc = 017 pc = 017
sp: stack sp: stack
dp: stack dp: stack
ip: stack ap: stack
stack: 0 stack: 0
+36 -25
View File
@@ -2,7 +2,7 @@
lac 017777 i lac 017777 i
sad d8 sad d8
skp skp
sys exit sys exit
lac 017777 lac 017777
tad d5 tad d5
@@ -12,13 +12,16 @@
dac fo dac fo
law 017 law 017
sys creat; scrname sys creat; scrname
spa; jms error spa
jms error
dac fso dac fso
sys open; scrname; 0 sys open; scrname; 0
spa; jms error spa
jms error
dac fsi dac fsi
sys chdir; dd sys chdir; dd
spa; jms error spa
jms error
lac d1 lac d1
sys write; pass1; 1 sys write; pass1; 1
law fsobuf law fsobuf
@@ -31,12 +34,14 @@
dac dirp dac dirp
dzm fsloc dzm fsloc
sys open; dotdot; 0 sys open; dotdot; 0
spa; jms error spa
jms error
dac fd dac fd
jms readdir; dotdot jms readdir; dotdot
law statbuf law statbuf
sys status; dotdot; dotdot sys status; dotdot; dotdot
spa; jms error spa
jms error
lac statbuf+12 " i index lac statbuf+12 " i index
dac dirp i dac dirp i
isz dirp isz dirp
@@ -75,13 +80,15 @@ loop:
sys read; scrname; 4 sys read; scrname; 4
law statbuf law statbuf
sys status; dotdot; scrname sys status; dotdot; scrname
spa; jms error spa
jms error
lac statbuf+0 " flags lac statbuf+0 " flags
and o20 and o20
sna sna
jmp 2f jmp 2f
sys open; scrname; 0 sys open; scrname; 0
spa; jms error spa
jms error
dac fd dac fd
jms readdir; scrname jms readdir; scrname
lac ddfilp i lac ddfilp i
@@ -109,7 +116,7 @@ loop:
dzm fflg dzm fflg
law fbuf law fbuf
dac i2 dac i2
r1 -1
tad nfiles tad nfiles
cma cma
dac c2 dac c2
@@ -118,19 +125,19 @@ loop:
lac c1 lac c1
tad d501 tad d501
sad i2 i sad i2 i
skp skp
jmp 3f jmp 3f
-1 -1
tad i1 tad i1
dac i3 dac i3
iac i3 i lac i3 i
dac c3 dac c3
law fbuf law fbuf
dac i3 dac i3
0: 0:
lac i3 i lac i3 i
sad c3 sad c3
jmp 0f jmp 0f
isz i3 isz i3
isz i3 isz i3
jmp 0b jmp 0b
@@ -159,14 +166,15 @@ loop:
lac nlinkt lac nlinkt
sad nlinka sad nlinka
skp skp
jms fishy jms fishy
dzm nlinka dzm nlinka
law 012 law 012
jms putc jms putc
law statbuf law statbuf
sys status; scrname; dd sys status; scrname; dd
spa; jms error spa
jms error
-1 -1
tad statbuf+9 tad statbuf+9
cma cma
@@ -188,7 +196,7 @@ loop:
isz i2 isz i2
lac i2 lac i2
sad i1 i sad i1 i
skp skp
jmp .+3 jmp .+3
isz i1 isz i1
isz i1 isz i1
@@ -199,7 +207,7 @@ loop:
jmp 1b jmp 1b
lac nlinkt lac nlinkt
sad nlinka sad nlinka
skp skp
jms fishy jms fishy
sys chdir; system sys chdir; system
@@ -267,9 +275,10 @@ readdir: 0
jms copyz; buf; 64 jms copyz; buf; 64
lac fd lac fd
sys read; buf; 64 sys read; buf; 64
spa; jms error spa
jms error
sna sna
jmp 4f jmp 4f
-8 -8
dac c1 dac c1
law buf law buf
@@ -277,7 +286,7 @@ readdir: 0
1: 1:
lac i1 i lac i1 i
sna sna
jmp 3f jmp 3f
isz nfiles isz nfiles
dac filp i dac filp i
@@ -292,7 +301,8 @@ readdir: 0
dac .+4 dac .+4
law statbuf law statbuf
sys status; 5:..; .. sys status; 5:..; ..
spa; jms error spa
jms error
jms longout jms longout
lac i1 lac i1
tad d1 tad d1
@@ -316,7 +326,7 @@ readdir: 0
isz fsopt isz fsopt
law fsobuf+64 law fsobuf+64
sad fsopt sad fsopt
skp skp
jmp 3f jmp 3f
lac fso lac fso
sys write; fsobuf; 64 sys write; fsobuf; 64
@@ -365,7 +375,8 @@ octal: 0
lac octal i lac octal i
dac c dac c
1: 1:
ecla llss 3 " ecla llss 3
llss 3
tad o60 tad o60
jms putc jms putc
isz c isz c
@@ -401,10 +412,10 @@ copyz: 0
done: done:
lac noc lac noc
sna sna
sys exit sys exit
and d1 and d1
sna cla sna cla
jmp 1f jmp 1f
jms putc jms putc
jmp done jmp done
1: 1:
+59
View File
@@ -0,0 +1,59 @@
" Warren's version of ls. Simply print out the names in the current directory
main:
sys open; curdir; 0 " Open up the currect directory
spa
sys exit " Unable, so die now
dac fd " Save the fd
fileloop:
" Read 64 words into the buffer from the input file
lac fd
sys read; buf; 64
spa " Skip if result was >= 0
jmp fileend " Result was -ve, so error result
sna " Skip if result was >0
jmp fileend " Result was zero, so nothing left to read
" Save the count of words read in
dac count
lac ibufptr " Point bufptr at the base of the buffer
dac bufptr
" Each directory entry is eight words. We need to print out
" the filename which is in words 2 to 5.
printloop:
isz bufptr " Move up to the filename
lac d1
sys write; bufptr:0; 4 " Write a filename out to stdout
lac d1
sys write; newline; 1 " followed by a newline
lac bufptr " Add 7 to the bufptr
tad d7
dac bufptr
-8
tad count " Decrement the count of words by 8
dac count
sza " Anything left in the buffer to print?
jmp printloop " Yes, stuff left to print
jmp fileloop " Nothing in the buffer, try reading some more
fileend:
" Close the open file descriptor and exit
lac fd
sys close
sys exit
curdir: <. 040; 040040; 040040; 040040 " i.e. "."
newline: 012000
fd: 0
d1: 1 " stdout fd
d7: 7
count: 0
" Input buffer for read
ibufptr: buf " Constant pointer to the buffer
buf: .=.+64
+72 -58
View File
@@ -3,22 +3,22 @@
.. = 0 .. = 0
t = 0 t = 0
orig: orig:
hlt hlt " overwritten with interrupt return addr
jmp pibreak jmp pibreak " dispatch to interrupt processing
. = orig+7 . = orig+7
-1 -1 " only ever set (to -1): never read?!
. = orig+020 . = orig+020 " syscall (CAL) processing
1f 1f " addr for "CAL I": store return here on "CAL"
iof iof " interrupts off
dac u.ac dac u.ac " save user AC
lac 020 lac 020 " save user return addr
dac 1f dac 1f " save as if "CAL I"
lac 1f-1 lac 1f-1
dac 020 dac 020 " restore location 20
lac u.ac lac u.ac " restore user AC
jmp 1f+1 jmp 1f+1 " join "CAL I" processing
1f 1f
1: 0 1: 0
iof " interrupts off iof " interrupts off
@@ -49,7 +49,7 @@ orig:
jmp .. i " dispatch system call jmp .. i " dispatch system call
. = orig+0100 . = orig+0100
jmp coldentry jmp coldentry " here to start kernel
jms halt jms halt
okexit: okexit:
@@ -64,9 +64,9 @@ sysexit: " common system call exit code
jms dskio; 07000 " save to disk? jms dskio; 07000 " save to disk?
1: 1:
dzm .insys " clear "in system call" flag dzm .insys " clear "in system call" flag
jms chkint jms chkint " pending interrupt?
skp skp " no
jmp .save " dump core?? jmp .save " yes: dump core
jms copy; u.rq+2; 10; 6 " restore auto-index locations 10-15 jms copy; u.rq+2; 10; 6 " restore auto-index locations 10-15
lac u.rq+1 " restore auto-index location 9 lac u.rq+1 " restore auto-index location 9
dac 9 dac 9
@@ -77,6 +77,7 @@ sysexit: " common system call exit code
lac u.ac " restore AC register lac u.ac " restore AC register
jmp u.rq+8 i " return to user jmp u.rq+8 i " return to user
" scheduler / idle loop
swap: 0 swap: 0
ion ion
1: 1:
@@ -84,49 +85,49 @@ swap: 0
jmp 1f jmp 1f
jms lookfor; 1 " in/ready jms lookfor; 1 " in/ready
skp skp
jmp 1b jmp 1b " loop until a process becomes ready
dzm maxquant dzm maxquant " here with in/ready (self?)
jmp 3f jmp 3f
1: 1: " here with out/ready process
dac 9f+t dac 9f+t " save process pointer (swapped out) in t0
jms lookfor; 2 " in/notready jms lookfor; 2 " in/notready " find a swapped in process to swap out?
jmp 1f jmp 1f
jms lookfor; 1 " in/ready jms lookfor; 1 " in/ready
jmp 1f jmp 1f
jmp 2f jmp 2f
1: 1:
lac swap lac swap
dac u.swapret dac u.swapret " return to scheduler when swapped back
iof iof
lac o200000 lac o200000 " change status to swapped out
tad u.ulistp i tad u.ulistp i
dac u.ulistp i dac u.ulistp i
ion ion
jms dskswap; 07000 jms dskswap; 07000 " swap process out
lac u.dspbuf lac u.dspbuf
sna sna
jmp 2f jmp 2f
law dspbuf law dspbuf
jms movdsp jms movdsp
2: 2:
iof iof " disable interrupts
lac o600000 lac o600000 " change status (1->7?)
tad 9f+t i tad 9f+t i
dac 9f+t i dac 9f+t i
ion ion " enable interrupts
jms dskswap; 06000 jms dskswap; 06000 " read process in?
lac u.swapret lac u.swapret " set our return addr
dac swap dac swap " to saved return addr
lac o20 lac o20 " reset maxquant to 16 ticks
dac maxquant dac maxquant
lac u.dspbuf lac u.dspbuf
sza sza " using display?
"** 01-s1.pdf page 4 "** 01-s1.pdf page 4
jms movdsp jms movdsp " yes.
3: 3:
dzm uquant dzm uquant " no. reset process tick count
iof iof
jmp swap i jmp swap i " return
t = t+1 t = t+1
swp: " system call dispatch table swp: " system call dispatch table
@@ -138,12 +139,18 @@ swp: " system call dispatch table
swn: swn:
.-swp-1 i " count of system calls, plus indirect! .-swp-1 i " count of system calls, plus indirect!
" AC/ new value for intflg (non-zero to ignore interrupt char)
" sys intrp
.intrp: .intrp:
lac u.ac lac u.ac
dac u.intflg dac u.intflg
jmp okexit jmp okexit
.sysloc: " "sysloc": syscall to return system addresses " syscall to retrieve system addresses (data & routines!!)
" AC/ index (1..17)
" sys sysloc
" AC/ address (or -1 on bad index)
.sysloc:
lac u.ac lac u.ac
and o17777 and o17777
jms betwen; d1; locn jms betwen; d1; locn
@@ -154,7 +161,7 @@ swn:
dac u.ac dac u.ac
jmp sysexit jmp sysexit
locsw: " table of system data structures for "sysloc" call locsw: " table of system addresses for sysloc
lac . lac .
iget; inode; userdata; sysdata; copy; copyz; betwen; dskrd iget; inode; userdata; sysdata; copy; copyz; betwen; dskrd
dskwr; dskbuf; dpdata; namei; pbsflgs; alloc; free; dspdata dskwr; dskbuf; dpdata; namei; pbsflgs; alloc; free; dspdata
@@ -162,34 +169,41 @@ locsw: " table of system data structures for "sysloc" call
locn: locn:
.-locsw-1 .-locsw-1
" check if interrupt for user
" checks .int1 and .int2 (contain i-number of interrupt source)
" call:
" .insys/ 0
" jms chkint
" no: no interrupt, or intflg set (discards interupt)
" yes: PI off, .insys set
chkint: 0 chkint: 0
lac .insys lac .insys
sza sza " in system?
jmp chkint i jmp chkint i " yes: return
lac .int1 lac .int1 " get inumber of interrupt1 source?
sna sna " zero?
jmp 1f jmp 1f " yes: skip stdin check
sad u.ofiles+2 sad u.ofiles+2 " non-zero: compare to stdin inumber
jmp 2f jmp 2f " same
1: 1:
lac .int2 lac .int2 " get inum of interrupt 2 source?
sna sna " zero?
jmp chkint i jmp chkint i " yes: return
sad u.ofiles+2 sad u.ofiles+2 " non-zero: compare to stdin inumber
skp skp " match!
jmp chkint i jmp chkint i " no match: return
dzm .int2 dzm .int2 " clear int2 source
jmp 1f jmp 1f
2: 2:
dzm .int1 dzm .int1 " clear int1 source
1: 1:
"** 01-s1.pdf page 5 "** 01-s1.pdf page 5
lac u.intflg lac u.intflg " get user intflg
sza sza " zero?
jmp chkint i jmp chkint i " no: ignore
-1 -1
dac .insys dac .insys " set "in system" flag
ion ion " enable interrupts
isz chkint isz chkint " give skip return
jmp chkint i jmp chkint i
+86 -79
View File
@@ -190,36 +190,39 @@
"** 01-s1.pdf page 10 "** 01-s1.pdf page 10
jmp okexit jmp okexit
" open system call
" sys open; filename_ptr; flags (0 for read, 1 for write)
" returns w/ "fd" in AC (or -1 if not found)
.open: .open:
jms arg jms arg " get filename
dac 0f dac 0f " save for namei
jms arg jms arg " get flags
sza sza " zero (read)
lac d1 lac d1 " no: get write mode bit
sna sna " non-zero (write)?
lac d2 " mode bit 2 (read?) lac d2 " no: get read mode bot
dac mode " save for access call dac mode " save for access call
lac u.cdir lac u.cdir " get current working directory
jms namei; 0:0 jms namei; 0:0 " search for file
jms error jms error " error: return -1
jms iget jms iget " load inode
jms access jms access " check access (may return w/ error to user)
lac i.flags lac i.flags " get file flags
and o20 and o20 " get directory bit
sna sna " is directory?
jmp open1 jmp open1 " no, join common code
lac mode lac mode " get access mode
and d1 and d1 " get write bit
sna sna " write access?
jmp open1 jmp open1 " no, continue
lac u.uid lac u.uid " yes: get uid?
sma sma " negative? (-1 is superuser)
jms error jms error " no: return error
jmp open1 jmp open1 " yes: join common code
.creat: .creat:
lac d1 " mode bit 1 (write?) lac d1 " mode bit 1 (write)
dac mode " save for access call dac mode " save for access call
jms arg jms arg
dac .+2 dac .+2
jms copy; ..; name; 4 jms copy; ..; name; 4
@@ -241,12 +244,12 @@
jmp open1 jmp open1
1: 1:
jms access jms access
lac u.ac lac u.ac " get access bits from user AC (zero for lock!)
and o17 and o17 " mask to permissions
jms icreat jms icreat
open1: open1: " common exit for open/creat
jms fassign jms fassign " assign fd slot
jms error jms error " none free, return -1
jmp sysexit jmp sysexit
"** 01-s1.pdf page 11 "** 01-s1.pdf page 11
@@ -275,63 +278,67 @@ open1:
and d1 and d1
sza sza
jms error jms error
lac i.flags lac i.flags " get inode flags
and o40 and o40 " get special file bit
sna sna " special?
jmp 1f jmp 1f " no
iof iof " yes: disable interrupts
lac ii lac ii " get i number
tad swr tad swr " get read routine table addr
dac .+1 dac .+1
jmp .. i jmp .. i " dispatch to read routine
1: 1:
lac u.base lac u.base " get user base
dac 1f+1 dac 1f+1 " save as iread base
lac u.count lac u.count " get user count
dac 1f+2 dac 1f+2 " save as iread count
lac f.badd lac f.badd " get file offset
1: 1:
jms iread; ..; .. jms iread; ..; ..
jmp exitrw jmp exitrw
" write system call:
" AC/ fd
" sys write; buffer; count
" AC/ count or -1 on error
.write: .write:
jms arg jms arg " pick up buffer
and o17777 and o17777 " mask to addr
dac u.base dac u.base " save as I/O base
jms arg jms arg " pick up count
dac u.count dac u.count " save as count
tad u.base tad u.base " add base (get limit)
jms betwen; u.base; o17777 jms betwen; u.base; o17777 " check between base and end of memory
jms error jms error " no: error
dac u.limit dac u.limit " yes: save as limit
jms finac jms finac " get fnode with fd from user AC
lac f.flags lac f.flags " get open file table flags
and d1 and d1 " open for write?
sna sna " yes, skip
jms error jms error " no: error
lac i.flags lac i.flags " get inode flags
and o40 and o40 " get special bit?
"** 01-s1.pdf page 12 "** 01-s1.pdf page 12
sna sna " special?
jmp 1f jmp 1f " no
iof iof " special file (device node)
lac ii lac ii " get i number
tad sww tad sww " get write routine
dac .+1 dac .+1
jmp .. i jmp .. i " dispatch to write routine
1: " here with regular file
lac u.base " get base
dac 1f+1 " save as iwrite arg 1
lac u.count " get count
dac 1f+2 " save as iwrite 2
lac f.badd " get fd offset
1: 1:
lac u.base jms iwrite; ..; .. " write to file
dac 1f+1
lac u.count
dac 1f+2
lac f.badd
1:
jms iwrite; ..; ..
exitrw: exitrw: " common exit for read/write system calls
dac u.ac dac u.ac " save return in user AC
tad f.badd tad f.badd
dac f.badd dac f.badd " update file offset
jms iput jms iput " release inode
jms fput jms fput " release fnode
jmp sysexit jmp sysexit " return to user
+105 -79
View File
@@ -1,15 +1,21 @@
"** 01-s1.pdf page 14 "** 01-s1.pdf page 14
" s3 " s3
" search for user (process)
" call:
" jms searchu; worker_routine_addr
" worker called with copy of a process table entry in "lu"
" can return directly (from caller of searchu)
" index location 8 points to next process table entry
searchu: 0 searchu: 0
lac searchu i lac searchu i " fetch argument
dac 9f+t+1 dac 9f+t+1 " in t1
-mnproc -mnproc " loop counter
dac 9f+t dac 9f+t " in t0
law ulist-1 law ulist-1 " ulist ptr
dac 8 dac 8 " in index 8
1: 1:
lac 8 i lac 8 i " copy ulist entry to lu
dac lu dac lu
lac 8 i lac 8 i
dac lu+1 dac lu+1
@@ -17,86 +23,96 @@ searchu: 0
dac lu+2 dac lu+2
lac 8 i lac 8 i
dac lu+3 dac lu+3
jms 9f+t+1 i jms 9f+t+1 i " call argument as subroutine
isz 9f+t isz 9f+t " returned: loop done?
jmp 1b jmp 1b " no, do it again
isz searchu isz searchu " skip argument
jmp searchu i jmp searchu i
t = t+2 t = t+2
" look for a process with matching status
" jms lookfor; status
" found: ulist ptr in AC
" not found
lookfor: 0 lookfor: 0
jms searchu; 1f jms searchu; 1f
isz lookfor isz lookfor " skip argument
isz lookfor isz lookfor " give skip return
jmp lookfor i jmp lookfor i
1: 0 1: 0 " worker called by searchu
lac lu lac lu
rtl; rtl; and o7 rtl; rtl; and o7 " bits 0:2 of lu
sad lookfor i sad lookfor i " match argument?
skp skp " yes
jmp 1b i jmp 1b i " no, return, keep going
-3 -3
tad 8 tad 8 " roll index 8 back to this entry
and o17777 and o17777
isz lookfor isz lookfor " skip lookfor argument
jmp lookfor i jmp lookfor i " non-skip return
" fork system call:
" sys fork
" return at +1 in parent, child pid in AC
" return at +2 in child, parent pid in AC
.fork: .fork:
jms lookfor; 0 " not-used jms lookfor; 0 " not-used " find an unused process slot
skp skp
jms error jms error " none found- return error
dac 9f+t dac 9f+t " save ulist ptr in t0
isz uniqpid isz uniqpid " generate new pid
lac uniqpid lac uniqpid
dac u.ac dac u.ac " return in child pid in AC
law sysexit law sysexit
dac u.swapret dac u.swapret " return from system call when swapped back in
lac o200000 lac o200000 " change process status to out/ready (1->3)
tad u.ulistp i tad u.ulistp i
dac u.ulistp i dac u.ulistp i
jms dskswap; 07000 jms dskswap; 07000 " swap parent out
lac 9f+t lac 9f+t " get unused ulist slot back
dac u.ulistp dac u.ulistp " set ulist pointer
lac o100000 lac o100000 " mark child in/notready? (3->2)
xor u.ulistp i xor u.ulistp i
dac u.ulistp i dac u.ulistp i
lac u.pid lac u.pid " get old (parent) pid
"** 01-s1.pdf page 15 "** 01-s1.pdf page 15
dac u.ac dac u.ac " return parent pid in AC
lac uniqpid lac uniqpid
dac u.pid dac u.pid " set child pid
isz 9f+t isz 9f+t " advance to second word in process table
dac 9f+t i dac 9f+t i " set pid in process table
isz u.rq+8 isz u.rq+8 " give skip return
dzm u.intflg dzm u.intflg " clear int flag
jmp sysexit jmp sysexit " return in child process
t= t+1 t= t+1
badcal: badcal: " bad (unimplemented) system call
clon clon " clear any pending clock interrupt?
-1 -1
dac 7 dac 7 " set location 7 to -1?!
.save: " fall into "save" system call
lac d1 " Ken says save files could be resumed, and used for checkpointing!
.save: " "sys save" system call
lac d1 " get inode 1 (core file?)
jms iget jms iget
cla cla
jms iwrite; 4096; 4096 jms iwrite; 4096; 4096 " dump core
jms iwrite; userdata; 64 jms iwrite; userdata; 64 " and user area
jms iput jms iput
.exit: .exit:
lac u.dspbuf lac u.dspbuf
sna sna " process using display?
jmp .+3 jmp .+3 " no
law dspbuf law dspbuf " yes
jms movdsp jms movdsp " move display
jms awake jms awake
lac u.ulistp i lac u.ulistp i
and o77777 and o77777 " mark process table entry free
dac u.ulistp i dac u.ulistp i
isz u.ulistp isz u.ulistp
dzm u.ulistp i dzm u.ulistp i " clear pid in process table
jms swap jms swap " find a new process to run
.rmes: .rmes:
jms awake jms awake
@@ -124,25 +140,28 @@ badcal:
t = t+1 t = t+1
"** 01-s1.pdf page 16 "** 01-s1.pdf page 16
" smes system call
" AC/ pid
" sys smes
.smes: .smes:
lac u.ac lac u.ac " get pid from user AC
sna spa sna spa " >0?
jms error jms error " no: error
jms searchu; 1f jms searchu; 1f " search for process
law 2 law 2
tad u.ulistp tad u.ulistp
dac 9f+t dac 9f+t
dzm 9f+t i dzm 9f+t i
jms error jms error
1: 0 1: 0 " worker for searchu
lac lu+1 lac lu+1 " get pid
sad u.ac sad u.ac " match?
skp skp " yes
jmp 1b i jmp 1b i " no
lac lu+2 lac lu+2 " get mailbox
sad dm1 sad dm1 " -1?
jmp 1f jmp 1f " yes
lac o100000 lac o100000 " no: increment process status
tad u.ulistp i tad u.ulistp i
dac u.ulistp i dac u.ulistp i
law 2 law 2
@@ -177,19 +196,19 @@ t = t+1
awake: 0 awake: 0
jms searchu; 1f jms searchu; 1f
jmp awake i jmp awake i
1: 0 1: 0 " searchu worker
lac u.pid lac u.pid " get caller pid
sad lu+2 sad lu+2 " match process table entry?
skp skp " yes
jmp 1b i jmp 1b i " no, return
-3 -3
tad 8 tad 8 " get pointer to pid in process table??
dac 9f+t dac 9f+t " save in t0
"** 01-s1.pdf page 17 "** 01-s1.pdf page 17
lac o700000 lac o700000 " set high bits
tad 9f+t i tad 9f+t i
dac 9f+t i dac 9f+t i
jmp 1b i jmp 1b i " return from worker
t = t+1 t = t+1
swr: swr:
@@ -200,15 +219,16 @@ sww:
.halt: jms halt .halt: jms halt
" read routine for ttyin special file
rttyi: rttyi:
jms chkint1 jms chkint1
lac d1 lac d1
jms getchar jms getchar
jmp 1f jmp 1f
and o177 and o177
jms betwen; o101; o132 jms betwen; o101; o132 " upper case?
skp skp " no
tad o40 tad o40 " yes: convert to lower
alss 9 alss 9
jmp passone jmp passone
1: 1:
@@ -216,6 +236,7 @@ rttyi:
jms swap jms swap
jmp rttyi jmp rttyi
" write routine for ttyout special file
wttyo: wttyo:
jms chkint1 jms chkint1
jms forall jms forall
@@ -243,6 +264,7 @@ wttyo:
jms swap jms swap
jmp wttyo jmp wttyo
" read routine for (display) "keyboard" special file
rkbdi: rkbdi:
jms chkint1 jms chkint1
lac d3 lac d3
@@ -282,6 +304,7 @@ rkbdi:
jms swap jms swap
jmp rkbdi jmp rkbdi
" write routine for (graphic) "display" special file
wdspo: wdspo:
jms chkint1 jms chkint1
jms forall jms forall
@@ -292,6 +315,7 @@ wdspo:
jmp wdspo jmp wdspo
" read routine for paper tape reader special file
rppti: rppti:
lac d4 lac d4
jms getchar jms getchar
@@ -307,6 +331,7 @@ rppti:
jmp rppti jmp rppti
"** 01-s1.pdf page 19 "** 01-s1.pdf page 19
" write routine for paper tape punch special file
wppto: wppto:
jms forall jms forall
sna sna
@@ -331,6 +356,7 @@ wppto:
jms swap jms swap
jmp wppto jmp wppto
" common exit for special file
passone: passone:
sad o4000 sad o4000
jmp okexit jmp okexit
+26 -19
View File
@@ -1,7 +1,7 @@
"** 01-s1.pdf page 21 "** 01-s1.pdf page 21
" s4 " s4
" allocate a free disk block " allocate a free disk block for a file (data or indirect)
alloc: 0 alloc: 0
-1 -1
tad s.nfblks tad s.nfblks
@@ -92,11 +92,14 @@ betwen: 0
cma " complement (AC-high) cma " complement (AC-high)
spa sna " AC-high <= 0? spa sna " AC-high <= 0?
1: 1:
isz betwen " no: give happy return isz betwen " no: give happy (skip) return
lacq " restore ~AC lacq " restore ~AC
cma " restore AC cma " restore AC
jmp betwen i " return w/o skip jmp betwen i " return w/o skip
" copy memory
" call:
" jms copy; src; dest; count
copy: 0 copy: 0
-1 -1
tad copy i tad copy i
@@ -118,21 +121,24 @@ copy: 0
jmp 1b jmp 1b
jmp copy i jmp copy i
" copy zeroes (clear memory)
" call:
" jms copyz; pointer; count
copyz: 0 copyz: 0
-1 -1
tad copyz i tad copyz i " get call PC
dac 8 dac 8 " save in index (pre-increments)
isz copyz isz copyz " skip pointer
-1 -1
tad copyz i tad copyz i " get count-1
cma cma " get negative count
dac 9f+t dac 9f+t " save in t0
isz copyz isz copyz " skip count
1: 1:
dzm 8 i dzm 8 i " zero word
isz 9f+t isz 9f+t " done?
jmp 1b jmp 1b " no: loop
jmp copyz i jmp copyz i " return
t = t+1 t = t+1
putchar: 0 putchar: 0
@@ -281,6 +287,8 @@ dskrd: 0
jms collapse jms collapse
jmp dskrd i jmp dskrd i
" write a file block (data, inode or indirect)
" AC/ block
dskwr: 0 dskwr: 0
jms betwen; d2; d7999 jms betwen; d2; d7999
jms halt jms halt
@@ -292,7 +300,6 @@ dskwr: 0
jmp dskwr i jmp dskwr i
t = t+3 t = t+3
" called with:
" AC/ block " AC/ block
" jms dskio; dsld_bits " jms dskio; dsld_bits
dskio: 0 dskio: 0
@@ -354,11 +361,11 @@ dsktrans: 0
t = t+1 t = t+1
halt: 0 halt: 0
isz 9f+t isz 9f+t " spin for a while (process interrupts)
jmp .-1 jmp .-1
iof iof " disable interrupts
hlt hlt " halt
jms copy; law; 4096; 4096 jms copy; law; 4096; 4096 " continued: copy system up to user memory?
hlt; jmp .-1 hlt; jmp .-1 " halt for good
t = t+1 t = t+1
+59 -48
View File
@@ -1,75 +1,86 @@
"** 01-s1.pdf page 28 "** 01-s1.pdf page 28
" s5 " s5
" read/write a process from/to swap space
" call:
" AC/ first word of process table
" jms dskswap; DSLD bits
dskswap: 0 dskswap: 0
cll; als 3 cll; als 3 " get process disk address
dac 9f+t dac 9f+t " save in t0
jms dsktrans; -64; userdata; 9f+t; dskswap jms dsktrans; -64; userdata; 9f+t; dskswap " read/write user area
lac 9f+t lac 9f+t " get swap addr back
tad o20 tad o20 " advance by 16??
dac 9f+t dac 9f+t " save
jms dsktrans; -4096; 4096; 9f+t; dskswap jms dsktrans; -4096; 4096; 9f+t; dskswap " read/write user memory
isz dskswap isz dskswap " skip bits
jmp dskswap i jmp dskswap i " return
t = t+1 t = t+1
access: 0 access: 0
lac i.flags lac i.flags
lmq lmq " save in MQ
lac u.uid lac u.uid " get user id
spa spa " negative?
jmp access i jmp access i " yes: super user, return
sad i.uid sad i.uid " compare to file owner
lrs 2 lrs 2 " same: shift flags down two
lacq lacq " get flags back
and mode " mode from system call and mode " mode from system call
sza sza " access allowed?
jmp access i jmp access i " yes: return
jms error jms error " no: return error from system call
fassign: 0 fassign: 0
-10 -10 " loop count
dac 9f+t dac 9f+t " in t0
1: 1:
lac 9f+t lac 9f+t " get count
tad d10 tad d10 " turn into fd
jms fget jms fget " fetch open file into "fnode"
jms halt " will not happen jms halt " will not happen
lac f.flags lac f.flags " get fnode flags
sma sma " sign bit set (active)?
jmp 1f jmp 1f " no: free
isz 9f+t isz 9f+t " increment loop count & loop until zero
jmp 1b jmp 1b
jmp fassign i jmp fassign i
1: 1:
lac mode lac mode " get mode from system call
xor o400000 xor o400000 " set sign bit
dac f.flags dac f.flags " save in fnode
lac ii lac ii " get i-number
dac f.i dac f.i " save in fnode
lac 9f+t lac 9f+t
tad d10 tad d10 " get fd
dac u.ac dac u.ac " return in user AC
dzm f.badd dzm f.badd " clear file offset in fnode
jms fput jms fput " copy fnode back into u.ofiles
isz fassign isz fassign " give skip return
jmp fassign i jmp fassign i
t = t+1 t = t+1
" load fnode (open file entry) from u.ofiles
" AC/ user fd
" jms fget
" bad fd
" return with fnode set
fget: 0 fget: 0
jms betwen; d0; d9 jms betwen; d0; d9 " fd 0..9?
jmp fget i jmp fget i " no, return
cll; mul; 3 cll; mul; 3 " multiply by three
lacq lacq
"** 01-s1.pdf page 29 "** 01-s1.pdf page 29
tad ofilesp tad ofilesp " get pointer into u.ofiles
dac 9f+t dac 9f+t " save in t0
dac .+2 dac .+2 " save as copy source
jms copy; ..; fnode; 3 jms copy; ..; fnode; 3 " copy to "fnode"
isz fget isz fget " give skip return
jmp fget i jmp fget i
" copy fnode back to u.ofiles
" uses temp value set by "fget"
" (fget and fput calls must be paired)
fput: 0 fput: 0
lac 9f+t lac 9f+t
dac .+3 dac .+3
+26 -17
View File
@@ -255,34 +255,37 @@ pget: 0
t = t+3 t = t+3
iwrite: 0 iwrite: 0
dac 9f+t dac 9f+t " save arg in t0
lac iwrite lac iwrite " load return address
"** 01-s1.pdf page 38 "** 01-s1.pdf page 38
dac iread dac iread " save as iread return addr
lac cskp lac cskp " load skip instruction
dac iwrite dac iwrite " save as iwrite instruction
jmp 1f jmp 1f
" iread from file referenced by loaded inode
" AC/ file offset
" jms iread; addr; count
iread: 0 iread: 0
dac 9f+t dac 9f+t " save offset in t0
lac cnop lac cnop " get nop
dac iwrite dac iwrite " save as iwrite instruction
1: 1:
-1 -1
tad iread i tad iread i " get word before return addr
dac 10 dac 10 " store in index 10 & 11
dac 11 dac 11
isz iread isz iread " increment return addr
lac iread i lac iread i " load addr
dac 9f+t+1 dac 9f+t+1 " save in t1
isz iread isz iread " increment return addr
lac o70000 lac o70000
xct iwrite xct iwrite " skip if write
lac i.size lac i.size " read: get file size
cma cma
tad 9f+t tad 9f+t " add offset
cma cma
jms betwen; d0; 9f+t+1 jms betwen; d0; 9f+t+1
lac 9f+t+1 lac 9f+t+1
@@ -336,6 +339,11 @@ cskp:
jmp 1b jmp 1b
t = t+4 t = t+4
" system call helper
" AC/ fd
" jms finac
" return with: fnode and inode loaded
" or makes error return to user
finac: 0 finac: 0
lac u.ac lac u.ac
jms fget jms fget
@@ -347,6 +355,7 @@ finac: 0
jms iget jms iget
jmp finac i jmp finac i
" update inode file size with value in AC
dacisize: 0 dacisize: 0
dac i.size dac i.size
jms iput jms iput
+43 -38
View File
@@ -1,8 +1,9 @@
"** 01-s1.pdf page 41 "** 01-s1.pdf page 41
" s7 " s7
pibreak: " priority interrupt processing "chain" pibreak: " priority interrupt break processing "chain"
dac .ac "** CROSSED OUT.... dac .ac " save interrupt AC
"** CROSSED OUT....
dpsf dpsf
jmp 1f jmp 1f
@@ -36,11 +37,13 @@ pibreak: " priority interrupt processing "chain"
isz uquant " increment user quantum counter isz uquant " increment user quantum counter
"** written: ttydelay -> ttyd1 "** written: ttydelay -> ttyd1
"** written: ttyrestart -> ttyres1 "** written: ttyrestart -> ttyres1
" referenced in iread:
cnop: cnop:
nop nop
-1 -1
dac 7 dac 7 " set location 7 to -1
clon clon " enable clock interrupts, reset flag
lac ttydelay lac ttydelay
spa spa
isz ttydelay isz ttydelay
@@ -103,16 +106,16 @@ dsprestart:
rlpd rlpd
jmp piret jmp piret
1: ksf 1: ksf " (TTY) keyboard flag set?
jmp 1f jmp 1f " no
lac ttydelay lac ttydelay
sma sma
isz ttydelay isz ttydelay
krb krb " read keyboard buffer
dac char dac char " save in char
sad o375 sad o375 " interrupt char ('}'?)
jmp intrp1 jmp intrp1 " yes
lac d1 lac d1
jms putchar jms putchar
dzm char dzm char
@@ -172,14 +175,15 @@ ttyrestart: 0
dac sfiles+1 dac sfiles+1
jmp ttyrestart i "** written arrow up 2 copies jmp ttyrestart i "** written arrow up 2 copies
1: sck "** BEGIN CROSSED OUT "** BEGIN CROSSED OUT
jmp 1f 1: sck " Graphic-2 keyboard flag set?
jmp 1f " no.
cck cck " yes: clear flag
lck lck " read character
dac char dac char
sad o33 sad o33 " code 33 (ESCAPE?)
jmp intrp2 jmp intrp2 " yes: mark interrupt
lac d3 lac d3
jms putchar jms putchar
nop nop
@@ -188,8 +192,8 @@ ttyrestart: 0
dac sfiles+2 dac sfiles+2
jmp piret jmp piret
1: rsf 1: rsf " paper tape ready?
jmp 1f jmp 1f " no
"** 01-s1.pdf page 44 "** 01-s1.pdf page 44
@@ -235,12 +239,12 @@ ttyrestart: 0
dac sfiles+3 dac sfiles+3
jmp piret jmp piret
1: psf 1: psf " paper tape ready?
jmp 1f jmp 1f " no
pcf pcf " clear ptp flag
lac d5 lac d5
jms getchar jms getchar " get next char
jmp .+3 jmp .+3
psa psa
jmp piret jmp piret
@@ -249,11 +253,12 @@ ttyrestart: 0
dac sfiles+4 dac sfiles+4
jmp piret jmp piret
1: spb "** BEGIN CROSSED OUT "** BEGIN CROSSED OUT
jmp 1f 1: spb " graphic 2 push button flag set?
jmp 1f " no
cpb cpb " clear push button flag
lpb lpb " load push button value
dac pbsflgs+1 dac pbsflgs+1
"** 01-s1.pdf page 45 "** 01-s1.pdf page 45
@@ -269,8 +274,8 @@ ttyrestart: 0
wbl wbl
jmp piret "** END CROSSED OUT jmp piret "** END CROSSED OUT
1: crsf 1: crsf " card reader flag set?
jmp 1f jmp 1f " no
crrb crrb
dac crchar dac crchar
@@ -278,14 +283,14 @@ ttyrestart: 0
dac crread dac crread
jmp piret jmp piret
1: crrb 1: crrb " read card reader buffer??
piret: piret: " return from priority interrupt
lac 0 lac 0 " get LINK/PC
ral ral " restore LINK
lac .ac lac .ac " restore AC
ion ion " reenable interrupts
jmp 0 i jmp 0 i " return from interrupt
wakeup: 0 wakeup: 0
dac 9f+t dac 9f+t
@@ -325,9 +330,9 @@ putcr: 0
cla cla
jmp putcr i jmp putcr i
intrp1: intrp1: " here with keyboard interrupt
lac d6 lac d6 " get keyboard special device number
dac .int1 dac .int1 " save as interrupt source
lac d1 lac d1
jms getchar jms getchar
skp skp
+62 -43
View File
@@ -8,14 +8,15 @@ dspbsz = 270
ndskbs = 4 ndskbs = 4
" flags " flags
.insys: 0 " interupt flags
.int1: 0 .insys: 0 " "in system"
.int2: 0 .int1: 0 " inode for interrupt 1
.ac: 0 .int2: 0 " inode for interrupt 2
.savblk: 0 .ac: 0 " saved AC from interrupt
.dsptm: 0 .savblk: 0 " set by system call, cleared by disk i/o
.dskb: 0 .dsptm: 0 " display restart countdown (10 ticks)
.dske: 0 .dskb: 0 " set on disk interrupt
.dske: 0 " status from disk interrupt
" pointers " pointers
tadu: tad ulist tadu: tad ulist
@@ -110,25 +111,25 @@ dspbuf:
.=.+30 .=.+30
coldentry: coldentry:
dzm 0100 " not re-entrant dzm 0100 " not re-entrant
caf caf " clear all flags
ion ion " enable interrupts
clon clon " clear clock flag
law 3072 law 3072 " initialize display....
wcga wcga
jms dspinit jms dspinit
law dspbuf law dspbuf
jms movdsp jms movdsp
cla cla " read system block from disk
jms dskio; 06000 jms dskio; 06000
jms copy; dskbuf; sysdata; ulist-sysdata jms copy; dskbuf; sysdata; ulist-sysdata " copy to system data
lac d3 lac d3 " look for "init" in default directory
jms namei; initf jms namei; initf
jms halt jms halt
"** 01-s1.pdf page 50 "** 01-s1.pdf page 50
jms iget jms iget
cla cla
jms iread; 4096; 4096 jms iread; 4096; 4096 " read in "init"
jmp 4096 jmp 4096 " start process 1
. = dspbuf+dspbsz+3 . = dspbuf+dspbsz+3
dskbuf = 07700 dskbuf = 07700
dskbs: .=.+65+65+65+65 dskbs: .=.+65+65+65+65
@@ -144,9 +145,9 @@ name: .=.+4
lnkaddr: .=.+1 lnkaddr: .=.+1
char: .=.+1 char: .=.+1
dskaddr: .=.+1 dskaddr: .=.+1
uniqpid: 1 uniqpid: 1 " pid generator
lu: .=.+4 lu: .=.+4 " user (process) table entry copy
sfiles: .=.+10 sfiles: .=.+10 " wait addresses for special files
dpdata: dpdata:
dpstat: .=.+1 dpstat: .=.+1
dpread: .=.+1 dpread: .=.+1
@@ -158,12 +159,24 @@ dspdata:
crdata: crdata:
crread: .=.+1 crread: .=.+1
crchar: .=.+1 crchar: .=.+1
sysdata: sysdata: " system data 64 words saved to disk
s.nxfblk: .=.+1 s.nxfblk: .=.+1 " pointer to next free block??
s.nfblks: .=.+1 " number of free blocks s.nfblks: .=.+1 " number of free blocks (in fblks?)
s.fblks: .=.+10 " free block numbers s.fblks: .=.+10 " cached free block numbers
s.uniq: .=.+1 " next unique value s.uniq: .=.+1 " next unique value
s.tim: .=.+2 " (up)time(?) in 60Hz ticks (low, high) s.tim: .=.+2 " (up?)time in 60Hz ticks (low, high)
" process table
" first word
" bits 0:2 -- status
" 0: free slot
" 1: in/ready
" 2: in/notready
" 3: out/ready
" 4: out/notready??
" bits 3:17 -- disk swap address/8
" second word: process pid
" third word: used for smes/rmes
" fourth word: ??
ulist: ulist:
0131000;1;0;0 0131000;1;0;0
0031040;0;0;0 0031040;0;0;0
@@ -175,31 +188,34 @@ ulist:
0031340;0;0;0 0031340;0;0;0
0031400;0;0;0 0031400;0;0;0
0031440;0;0;0 0031440;0;0;0
userdata: userdata: " "ustruct" (swappable)
u.ac: 0 " user AC u.ac: 0 " user AC
u.mq: 0 " user MQ u.mq: 0 " user MQ
u.rq: .=.+9 " user 010-017 u.rq: .=.+9 " user 010-017, user PC
u.uid: -1 " user id u.uid: -1 " user id
u.pid: 1 " process id u.pid: 1 " process id
u.cdir: 3 " connected directory (inode number?) u.cdir: 3 " connected directory (inode number?)
u.ulistp: ulist u.ulistp: ulist " pointer to process table entry
u.swapret: 0 u.swapret: 0 " kernel routine to resume at after swap in
u.base: 0 u.base: 0 " start of user buffer
u.count: 0 u.count: 0 " size of user buffer
"** 01-s1.pdf page 51 "** 01-s1.pdf page 51
u.limit: 0 u.limit: 0 " end of user buffer
u.ofiles: .=.+30 u.ofiles: .=.+30 " open files (10 "fnode" entries)
u.dspbuf: 0 u.dspbuf: 0
u.intflg: 1 u.intflg: 1
.=userdata+64 .=userdata+64
ii: .=.+1 ii: .=.+1 " number of i-node in inode:
inode: inode: " disk inode in memory:
i.flags: .=.+1 " inode flags i.flags: .=.+1 " inode flags
" 400000 free?? (checked/toggled by icreat) " 400000 free?? (checked/toggled by icreat)
" 200000 large file " 200000 large file
" 000040 special? (checked by read/write) " 000040 special device (indicated by inum)?
" 000020 directory " 000020 directory
" 000017 can be changed by chmod. " 000010 owner read
" 000004 owner write
" 000002 world read
" 000001 world write
i.dskps: .=.+7 " disk block pointers (indirect if "large file") i.dskps: .=.+7 " disk block pointers (indirect if "large file")
i.uid: .=.+1 " owner i.uid: .=.+1 " owner
i.nlks: .=.+1 " link count i.nlks: .=.+1 " link count
@@ -212,8 +228,11 @@ dnode: " directory entry:
d.name: .=.+4 " name (space padded) d.name: .=.+4 " name (space padded)
d.uniq: .=.+1 " unique number from directory inode d.uniq: .=.+1 " unique number from directory inode
. = dnode+8 . = dnode+8
fnode: fnode: " open file entry
f.flags: .=.+1 f.flags: .=.+1 " see below
f.badd: .=.+1 f.badd: .=.+1 " offset
f.i: 0 f.i: 0 " file i-number
" f.flags:
" 400000 in use
" 000002 read
" 000001 write
+114 -6
View File
@@ -485,15 +485,25 @@ sub eae {
$PC++; $PC++;
return; return;
} }
if ( $maskedinstr == 0660700 ) { # alss: long left shift, signed if ( $maskedinstr == 0660700 ) { # alss: AC left shift, signed
# We don't fill the lsb with LINK yet
dprintf( "alss AC %06o step %d\n", $AC, $step ); dprintf( "alss AC %06o step %d\n", $AC, $step );
$AC = ( $AC << $step ) & MAXINT; $AC = ( $AC << $step ) & MAXINT;
$LINK = ( $AC << 1 ) & LINKMASK;
$PC++; $PC++;
return; return;
} }
if ( $maskedinstr == 0640700 ) { # als: long left shift if ( $maskedinstr == 0660600 ) { # llss: long left shift, signed
dprintf( "alss AC %06o step %d\n", $AC, $step ); dprintf( "llss AC %06o step %d\n", $AC, $step );
foreach my $i (1 .. $step) {
my $MQmsb= ($MQ & SIGN) ? 1 : 0;
$AC= (($AC << 1) | $MQmsb) & MAXINT;
$MQ= (($MQ << 1) | (($LINK) ? 1 : 0)) & MAXINT;
}
$PC++;
return;
}
if ( $maskedinstr == 0640700 ) { # als: AC left shift
dprintf( "als AC %06o step %d\n", $AC, $step );
$AC = ( $AC << $step ) & MAXINT; $AC = ( $AC << $step ) & MAXINT;
$PC++; $PC++;
return; return;
@@ -551,7 +561,7 @@ sub cal {
# 22 badcal # 22 badcal
# 23 capt # 23 capt
# 24 rele # 24 rele
# 25 status 25 => \&sys_status,
# 26 badcal # 26 badcal
27 => \&sys_smes, 27 => \&sys_smes,
28 => \&sys_rmes, 28 => \&sys_rmes,
@@ -653,12 +663,55 @@ sub sys_close {
return; return;
} }
# Open something which could be a file or a directory
# Convert directories into files. Return the file handle.
sub opensomething {
my ($readorwrite, $filename )= @_;
my $tempfile= "/tmp/a7out.$$";
my $FH;
# If this is not a directory, simply open and return the FH
if (! -d $filename) {
open( $FH, $readorwrite, $filename ) || return(undef);
return($FH);
}
# It's a directory. The on-disk format for this was:
# d.i: .=.+1 " inode number
# d.name: .=.+4 " name (space padded)
# d.uniq: .=.+1 " unique number from directory inode
# followed by two unused words
# The code creates a temporary file and fills in the i-node numbers
# and space padded filenames from the directory. The file is closed
# opened read-only and unlinked, and the open filehandle is returned.
opendir(my $dh, $filename) || return(undef);
open( $FH, ">", $tempfile) || return(undef);
dprintf("Converting directory $filename\n");
my @list= sort(readdir($dh));
foreach my $name (@list) {
# Get the file's i-node number
my (undef,$inode)= stat($name);
# ARGH! For now we are still read/writing ASCII files, so there's
# no way to represent a proper 18-bit value. For now I'll pad
# with spaces to create the record
printf( $FH " %-8s ", substr( $name, 0, 8 ) );
}
closedir($dh);
close($FH);
open( $FH, "<", $tempfile) || return(undef);
unlink($tempfile);
return($FH);
}
# Common code for creat and open # Common code for creat and open
sub creatopen { sub creatopen {
my ($filename, $readorwrite)= @_; my ($filename, $readorwrite)= @_;
# Open the file # Open the file
if ( open( my $FH, $readorwrite, $filename ) ) { my $FH= opensomething($readorwrite, $filename );
if ( $FH ) {
# Find a place in the @FD array to store this filehandle. # Find a place in the @FD array to store this filehandle.
# 99 is arbitrary # 99 is arbitrary
@@ -914,6 +967,61 @@ sub sys_time {
return; return;
} }
# Status system call
sub sys_status {
# This seems to called as follows:
# law statbuf
# sys status; scrname; dd
# but I can't tell if PC+1 or PC+2 holds the filename pointer.
# For now, I'll use PC+1. $AC seems to hold the pointer to the statbuf
# which, as far as we can tell is:
# word 0: permission bits
# words 1-7: disk block pointers
# word 8: user-id
# word 9: number of links
# word 10: size in words
# word 11: uniq, I have no idea what this is.
# The permission bits are:
# 200000 large file, bigger than 4096 words
# 000020 directory
# 000010 owner read
# 000004 owner write
# 000002 user write
# 000001 user write
# Get the start address of the string
# Convert this to a sensible ASCII filename
my $start = $Mem[ $PC + 1 ];
my $filename = mem2arg($start);
dprintf( "status file %s statbuf %06o\n", $filename, $AC );
# Get the file's details
my (undef,undef,$mode,$nlink,$uid,undef,undef,$size)= stat($filename);
# Set up the statbuf if we got a result
if ($nlink) {
$Mem[ $AC+8 ]= $uid & MAXINT;
$Mem[ $AC+9 ]= $nlink & MAXINT;
$Mem[ $AC+10 ]= $size & MAXINT; # Yes, I know, not words
my $perms=0;
$perms= 01 if ($mode & 02); # World writable
$perms|= 02 if ($mode & 04); # World readable
$perms|= 04 if ($mode & 0200); # Owner writable
$perms|= 010 if ($mode & 0400); # Owner readable
$perms|= 020 if ( -d $filename); # Directory
$perms|= 0200000 if ($size > 4096); # Large file
$Mem[ $AC ] = $perms;
# Set AC to zero as we got something, else return -1
$AC= 0;
} else {
$AC= MAXINT;
}
$PC += 3;
return;
}
# Convert an 18-bit word into two ASCII characters and return them. # Convert an 18-bit word into two ASCII characters and return them.
# Don't return NUL characters # Don't return NUL characters
sub word2ascii { sub word2ascii {