1
0
mirror of https://github.com/livingcomputermuseum/pdp7-unix.git synced 2026-02-11 02:40:46 +00:00
This commit is contained in:
Warren Toomey
2016-03-04 08:31:45 +10:00
8 changed files with 311 additions and 243 deletions

View File

@@ -64,9 +64,9 @@ sysexit: " common system call exit code
jms dskio; 07000 " save to disk?
1:
dzm .insys " clear "in system call" flag
jms chkint
skp
jmp .save " dump core??
jms chkint " pending interrupt?
skp " no
jmp .save " yes: dump core
jms copy; u.rq+2; 10; 6 " restore auto-index locations 10-15
lac u.rq+1 " restore auto-index location 9
dac 9
@@ -139,12 +139,18 @@ swp: " system call dispatch table
swn:
.-swp-1 i " count of system calls, plus indirect!
" AC/ new value for intflg
" sys intrp
.intrp:
lac u.ac
dac u.intflg
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
and o17777
jms betwen; d1; locn
@@ -155,7 +161,7 @@ swn:
dac u.ac
jmp sysexit
locsw: " table of system data structures for "sysloc" call
locsw: " table of system addresses for sysloc
lac .
iget; inode; userdata; sysdata; copy; copyz; betwen; dskrd
dskwr; dskbuf; dpdata; namei; pbsflgs; alloc; free; dspdata
@@ -163,34 +169,41 @@ locsw: " table of system data structures for "sysloc" call
locn:
.-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
lac .insys
sza
jmp chkint i
lac .int1
sna
jmp 1f
sad u.ofiles+2
jmp 2f
sza " in system?
jmp chkint i " yes: return
lac .int1 " get inumber of interrupt1 source?
sna " zero?
jmp 1f " yes: skip stdin check
sad u.ofiles+2 " non-zero: compare to stdin inumber
jmp 2f " same
1:
lac .int2
sna
jmp chkint i
sad u.ofiles+2
skp
jmp chkint i
dzm .int2
lac .int2 " get inum of interrupt 2 source?
sna " zero?
jmp chkint i " yes: return
sad u.ofiles+2 " non-zero: compare to stdin inumber
skp " match!
jmp chkint i " no match: return
dzm .int2 " clear int2 source
jmp 1f
2:
dzm .int1
dzm .int1 " clear int1 source
1:
"** 01-s1.pdf page 5
lac u.intflg
sza
jmp chkint i
lac u.intflg " get user intflg
sza " zero?
jmp chkint i " no: ignore
-1
dac .insys
ion
isz chkint
dac .insys " set "in system" flag
ion " enable interrupts
isz chkint " give skip return
jmp chkint i

View File

@@ -190,31 +190,34 @@
"** 01-s1.pdf page 10
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:
jms arg
dac 0f
jms arg
sza
lac d1
sna
lac d2 " mode bit 2 (read?)
jms arg " get filename
dac 0f " save for namei
jms arg " get flags
sza " zero (read)
lac d1 " no: get write mode bit
sna " non-zero (write)?
lac d2 " no: get read mode bot
dac mode " save for access call
lac u.cdir
jms namei; 0:0
jms error
lac u.cdir " get current working directory
jms namei; 0:0 " search for file
jms error " error: return -1
jms iget
jms access
lac i.flags
and o20
sna
jmp open1
lac mode
and d1
sna
jmp open1
lac u.uid
sma
jms error
jms access " check access (may return w/ error to user)
lac i.flags " get file flags
and o20 " get directory bit
sna " is directory?
jmp open1 " no
lac mode " get access mode
and d1 " get write bit
sna " write access?
jmp open1 " no, continue
lac u.uid " yes: get uid?
sma " negative (-1 is superuser)
jms error " no: return error
jmp open1
.creat:
@@ -275,63 +278,67 @@ open1:
and d1
sza
jms error
lac i.flags
and o40
sna
jmp 1f
iof
lac ii
tad swr
lac i.flags " get inode flags
and o40 " get special file bit
sna " special?
jmp 1f " no
iof " yes: disable interrupts
lac ii " get i number
tad swr " get read routine table addr
dac .+1
jmp .. i
jmp .. i " dispatch to read routine
1:
lac u.base
dac 1f+1
lac u.count
dac 1f+2
lac f.badd
lac u.base " get user base
dac 1f+1 " save as iread base
lac u.count " get user count
dac 1f+2 " save as iread count
lac f.badd " get file offset
1:
jms iread; ..; ..
jmp exitrw
" write system call:
" AC/ fd
" sys write; buffer; count
" AC/ count or -1 on error
.write:
jms arg
and o17777
dac u.base
jms arg
dac u.count
tad u.base
jms betwen; u.base; o17777
jms error
dac u.limit
jms finac
lac f.flags
and d1
sna
jms error
lac i.flags
and o40
jms arg " pick up buffer
and o17777 " mask to addr
dac u.base " save as I/O base
jms arg " pick up count
dac u.count " save as count
tad u.base " add base (get limit)
jms betwen; u.base; o17777 " check between base and end of memory
jms error " no: error
dac u.limit " yes: save as limit
jms finac " get fnode with fd from user AC
lac f.flags " get file table flags
and d1 " open for write?
sna " yes, skip
jms error " no: error
lac i.flags " get inode flags
and o40 " get special bit?
"** 01-s1.pdf page 12
sna
jmp 1f
iof
lac ii
tad sww
sna " special?
jmp 1f " no
iof " special file (device node)
lac ii " get i number
tad sww " get write routine
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:
lac u.base
dac 1f+1
lac u.count
dac 1f+2
lac f.badd
1:
jms iwrite; ..; ..
jms iwrite; ..; .. " write to file
exitrw:
dac u.ac
exitrw: " common exit for read/write system calls
dac u.ac " save return in user AC
tad f.badd
dac f.badd
jms iput
jms fput
jmp sysexit
dac f.badd " update file offset
jms iput " release inode
jms fput " release fnode
jmp sysexit " return to user

View File

@@ -1,9 +1,12 @@
"** 01-s1.pdf page 14
" s3
" search for user (process)
" call:
" jms searchu; addr
" 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
lac searchu i " fetch argument
dac 9f+t+1 " in t1
@@ -27,7 +30,7 @@ searchu: 0
jmp searchu i
t = t+2
" look for process:
" look for a process with matching status
" jms lookfor; status
" found: ulist ptr in AC
" not found
@@ -45,9 +48,13 @@ lookfor: 0
-3
tad 8 " roll index 8 back to this entry
and o17777
isz lookfor " skip argument
isz lookfor " skip lookfor argument
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:
jms lookfor; 0 " not-used " find an unused process slot
skp
@@ -55,26 +62,26 @@ lookfor: 0
dac 9f+t " save ulist ptr in t0
isz uniqpid " generate new pid
lac uniqpid
dac u.ac " return in AC
dac u.ac " return in child pid in AC
law sysexit
dac u.swapret " return from system call when swapped back in
lac o200000 " change process status to out/ready
lac o200000 " change process status to out/ready (1->3)
tad u.ulistp i
dac u.ulistp i
jms dskswap; 07000 " swap parent out
lac 9f+t " get unused ulist slot back
dac u.ulistp " set ulist pointer
lac o100000 " mark child in/ready
lac o100000 " mark child in/notready? (3->2)
xor u.ulistp i
dac u.ulistp i
lac u.pid
lac u.pid " get old (parent) pid
"** 01-s1.pdf page 15
dac u.ac " return parent pid in AC?
dac u.ac " return parent pid in AC
lac uniqpid
dac u.pid " set child pid
isz 9f+t
isz 9f+t " advance to second word in process table
dac 9f+t i " set pid in process table
isz u.rq+8 " increment return address from sys call
isz u.rq+8 " give skip return
dzm u.intflg " clear int flag
jmp sysexit " return in child process
t= t+1
@@ -82,28 +89,30 @@ t= t+1
badcal: " bad (unimplemented) system call
clon " clear any pending clock interrupt?
-1
dac 7 " set location 7 to -1
.save:
lac d1
dac 7 " set location 7 to -1?!
" fall into "save" system call
" 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
cla
jms iwrite; 4096; 4096
jms iwrite; userdata; 64
jms iwrite; 4096; 4096 " dump core
jms iwrite; userdata; 64 " and user area
jms iput
.exit:
lac u.dspbuf
sna " process using display?
jmp .+3 " no
law dspbuf " yes
jms movdsp
sna " process using display?
jmp .+3 " no
law dspbuf " yes
jms movdsp " move display
jms awake
lac u.ulistp i
and o77777 " mark process table entry free
and o77777 " mark process table entry free
dac u.ulistp i
isz u.ulistp
dzm u.ulistp i " clear pid in process table
jms swap
dzm u.ulistp i " clear pid in process table
jms swap " find a new process to run
.rmes:
jms awake
@@ -131,25 +140,28 @@ badcal: " bad (unimplemented) system call
t = t+1
"** 01-s1.pdf page 16
" smes system call
" AC/ pid
" sys smes
.smes:
lac u.ac
sna spa
jms error
jms searchu; 1f
lac u.ac " get pid from user AC
sna spa " >0?
jms error " no: error
jms searchu; 1f " search for process
law 2
tad u.ulistp
dac 9f+t
dzm 9f+t i
jms error
1: 0
lac lu+1
sad u.ac
skp
jmp 1b i
lac lu+2
sad dm1
jmp 1f
lac o100000
1: 0 " worker for searchu
lac lu+1 " get pid
sad u.ac " match?
skp " yes
jmp 1b i " no
lac lu+2 " get mailbox
sad dm1 " -1?
jmp 1f " yes
lac o100000 " no: increment process status
tad u.ulistp i
dac u.ulistp i
law 2
@@ -184,19 +196,19 @@ t = t+1
awake: 0
jms searchu; 1f
jmp awake i
1: 0
lac u.pid
sad lu+2
skp
jmp 1b i
1: 0 " searchu worker
lac u.pid " get caller pid
sad lu+2 " match process table entry?
skp " yes
jmp 1b i " no, return
-3
tad 8
dac 9f+t
tad 8 " get pointer to pid in process table??
dac 9f+t " save in t0
"** 01-s1.pdf page 17
lac o700000
lac o700000 " set high bits
tad 9f+t i
dac 9f+t i
jmp 1b i
jmp 1b i " return from worker
t = t+1
swr:
@@ -207,15 +219,16 @@ sww:
.halt: jms halt
" read routine for ttyin special file
rttyi:
jms chkint1
lac d1
jms getchar
jmp 1f
and o177
jms betwen; o101; o132
skp
tad o40
jms betwen; o101; o132 " upper case?
skp " no
tad o40 " yes: convert to lower
alss 9
jmp passone
1:
@@ -223,6 +236,7 @@ rttyi:
jms swap
jmp rttyi
" write routine for ttyout special file
wttyo:
jms chkint1
jms forall
@@ -250,6 +264,7 @@ wttyo:
jms swap
jmp wttyo
" read routine for (display) "keyboard" special file
rkbdi:
jms chkint1
lac d3
@@ -289,6 +304,7 @@ rkbdi:
jms swap
jmp rkbdi
" write routine for (graphic) "display" special file
wdspo:
jms chkint1
jms forall
@@ -299,6 +315,7 @@ wdspo:
jmp wdspo
" read routine for paper tape reader special file
rppti:
lac d4
jms getchar
@@ -314,6 +331,7 @@ rppti:
jmp rppti
"** 01-s1.pdf page 19
" write routine for paper tape punch special file
wppto:
jms forall
sna
@@ -338,6 +356,7 @@ wppto:
jms swap
jmp wppto
" common exit for special file
passone:
sad o4000
jmp okexit

View File

@@ -92,11 +92,14 @@ betwen: 0
cma " complement (AC-high)
spa sna " AC-high <= 0?
1:
isz betwen " no: give happy return
isz betwen " no: give happy (skip) return
lacq " restore ~AC
cma " restore AC
jmp betwen i " return w/o skip
" copy memory
" call:
" jms copy; src; dest; count
copy: 0
-1
tad copy i
@@ -118,21 +121,24 @@ copy: 0
jmp 1b
jmp copy i
" copy zeroes (clear memory)
" call:
" jms copyz; pointer; count
copyz: 0
-1
tad copyz i
dac 8
isz copyz
tad copyz i " get call PC
dac 8 " save in index (pre-increments)
isz copyz " skip pointer
-1
tad copyz i
cma
dac 9f+t
isz copyz
tad copyz i " get count-1
cma " get negative count
dac 9f+t " save in t0
isz copyz " skip count
1:
dzm 8 i
isz 9f+t
jmp 1b
jmp copyz i
dzm 8 i " zero word
isz 9f+t " done?
jmp 1b " no: loop
jmp copyz i " return
t = t+1
putchar: 0
@@ -354,11 +360,11 @@ dsktrans: 0
t = t+1
halt: 0
isz 9f+t
isz 9f+t " spin for a while (process interrupts)
jmp .-1
iof
hlt
jms copy; law; 4096; 4096
hlt; jmp .-1
iof " disable interrupts
hlt " halt
jms copy; law; 4096; 4096 " continued: copy system up to user memory?
hlt; jmp .-1 " halt for good
t = t+1

View File

@@ -59,20 +59,28 @@ fassign: 0
jmp fassign i
t = t+1
" get inode fpr an open file
" AC/ user fd
" jms fget
" bad fd
" return with fnode set
fget: 0
jms betwen; d0; d9
jmp fget i
cll; mul; 3
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
dac 9f+t
dac .+2
jms copy; ..; fnode; 3
isz fget
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

View File

@@ -261,28 +261,31 @@ iwrite: 0
"** 01-s1.pdf page 38
dac iread " save as iread return addr
lac cskp
dac iwrite " set our return addr to "cskp"
lac cskp " load skip instruction
dac iwrite " save as iwrite instruction
jmp 1f
" iread from file referenced by loaded inode
" AC/ file offset
" jms iread; addr; count
iread: 0
dac 9f+t
lac cnop " set iwrite return to "cnop"
dac iwrite
dac 9f+t " save offset in t0
lac cnop " get nop
dac iwrite " save as iwrite instruction
1:
-1
tad iread i " get word before return addr
dac 10 " store in index 8 & 9
dac 10 " store in index 10 & 11
dac 11
isz iread " increment return addr
lac iread i " load word
lac iread i " load addr
dac 9f+t+1 " save in t1
isz iread " increment return addr
lac o70000
xct iwrite
lac i.size
xct iwrite " skip if write
lac i.size " read: get file size
cma
tad 9f+t
tad 9f+t " add offset
cma
jms betwen; d0; 9f+t+1
lac 9f+t+1
@@ -336,6 +339,11 @@ cskp:
jmp 1b
t = t+4
" system call helper
" AC/ fd
" jms finac
" return with: fnode and inode loaded
" or makes error return to user
finac: 0
lac u.ac
jms fget
@@ -347,6 +355,7 @@ finac: 0
jms iget
jmp finac i
" update inode file size with value in AC
dacisize: 0
dac i.size
jms iput

View File

@@ -1,8 +1,9 @@
"** 01-s1.pdf page 41
" s7
pibreak: " priority interrupt processing "chain"
dac .ac "** CROSSED OUT....
pibreak: " priority interrupt break processing "chain"
dac .ac " save interrupt AC
"** CROSSED OUT....
dpsf
jmp 1f
@@ -174,14 +175,15 @@ ttyrestart: 0
dac sfiles+1
jmp ttyrestart i "** written arrow up 2 copies
1: sck "** BEGIN CROSSED OUT
jmp 1f
"** BEGIN CROSSED OUT
1: sck " Graphic-2 keyboard flag set?
jmp 1f " no.
cck
lck
cck " yes: clear flag
lck " read character
dac char
sad o33
jmp intrp2
sad o33 " code 33 (ESCAPE?)
jmp intrp2 " yes: mark interrupt
lac d3
jms putchar
nop
@@ -190,8 +192,8 @@ ttyrestart: 0
dac sfiles+2
jmp piret
1: rsf
jmp 1f
1: rsf " paper tape ready?
jmp 1f " no
"** 01-s1.pdf page 44
@@ -237,12 +239,12 @@ ttyrestart: 0
dac sfiles+3
jmp piret
1: psf
jmp 1f
1: psf " paper tape ready?
jmp 1f " no
pcf
pcf " clear ptp flag
lac d5
jms getchar
jms getchar " get next char
jmp .+3
psa
jmp piret
@@ -251,11 +253,12 @@ ttyrestart: 0
dac sfiles+4
jmp piret
1: spb "** BEGIN CROSSED OUT
jmp 1f
"** BEGIN CROSSED OUT
1: spb " graphic 2 push button flag set?
jmp 1f " no
cpb
lpb
cpb " clear push button flag
lpb " load push button value
dac pbsflgs+1
"** 01-s1.pdf page 45
@@ -271,8 +274,8 @@ ttyrestart: 0
wbl
jmp piret "** END CROSSED OUT
1: crsf
jmp 1f
1: crsf " card reader flag set?
jmp 1f " no
crrb
dac crchar
@@ -280,14 +283,14 @@ ttyrestart: 0
dac crread
jmp piret
1: crrb
1: crrb " read card reader buffer??
piret:
lac 0
ral
lac .ac
ion
jmp 0 i
piret: " return from priority interrupt
lac 0 " get LINK/PC
ral " restore LINK
lac .ac " restore AC
ion " reenable interrupts
jmp 0 i " return from interrupt
wakeup: 0
dac 9f+t

View File

@@ -8,14 +8,15 @@ dspbsz = 270
ndskbs = 4
" flags
.insys: 0
.int1: 0
.int2: 0
.ac: 0
.savblk: 0
.dsptm: 0
.dskb: 0
.dske: 0
" interupt flags
.insys: 0 " "in system"
.int1: 0 " inode for interrupt 1
.int2: 0 " inode for interrupt 2
.ac: 0 " saved AC from interrupt
.savblk: 0 " set by system call, cleared by disk i/o
.dsptm: 0 " display restart countdown (10 ticks)
.dskb: 0 " set on disk interrupt
.dske: 0 " status from disk interrupt
" pointers
tadu: tad ulist
@@ -110,25 +111,25 @@ dspbuf:
.=.+30
coldentry:
dzm 0100 " not re-entrant
caf
ion
clon
law 3072
caf " clear all flags
ion " enable interrupts
clon " clear clock flag
law 3072 " initialize display....
wcga
jms dspinit
law dspbuf
jms movdsp
cla
cla " read system block from disk
jms dskio; 06000
jms copy; dskbuf; sysdata; ulist-sysdata
lac d3
jms copy; dskbuf; sysdata; ulist-sysdata " copy to system data
lac d3 " look for "init" in default directory
jms namei; initf
jms halt
"** 01-s1.pdf page 50
jms iget
cla
jms iread; 4096; 4096
jmp 4096
jms iread; 4096; 4096 " read in "init"
jmp 4096 " start process 1
. = dspbuf+dspbsz+3
dskbuf = 07700
dskbs: .=.+65+65+65+65
@@ -144,9 +145,9 @@ name: .=.+4
lnkaddr: .=.+1
char: .=.+1
dskaddr: .=.+1
uniqpid: 1
lu: .=.+4
sfiles: .=.+10
uniqpid: 1 " pid generator
lu: .=.+4 " user (process) table entry copy
sfiles: .=.+10 " wait addresses for special files
dpdata:
dpstat: .=.+1
dpread: .=.+1
@@ -158,12 +159,12 @@ dspdata:
crdata:
crread: .=.+1
crchar: .=.+1
sysdata:
s.nxfblk: .=.+1
s.nfblks: .=.+1 " number of free blocks
s.fblks: .=.+10 " free block numbers
s.uniq: .=.+1 " next unique value
s.tim: .=.+2 " (up)time(?) in 60Hz ticks (low, high)
sysdata: " system data 64 words saved to disk
s.nxfblk: .=.+1 " pointer to next free block??
s.nfblks: .=.+1 " number of free blocks (in fblks?)
s.fblks: .=.+10 " cached free block numbers
s.uniq: .=.+1 " next unique value
s.tim: .=.+2 " (up?)time in 60Hz ticks (low, high)
" process table
" first word
" bits 0:2 -- status
@@ -173,7 +174,9 @@ sysdata:
" 3: out/ready
" 4: out/notready??
" bits 3:17 -- disk swap address/8
" second word: pid
" second word: process pid
" third word: used for smes/rmes
" fourth word: ??
ulist:
0131000;1;0;0
0031040;0;0;0
@@ -185,25 +188,25 @@ ulist:
0031340;0;0;0
0031400;0;0;0
0031440;0;0;0
userdata:
userdata: " "ustruct" (swappable)
u.ac: 0 " user AC
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.pid: 1 " process id
u.cdir: 3 " connected directory (inode number?)
u.ulistp: ulist " pointer to process table entry
u.swapret: 0
u.base: 0
u.count: 0
u.swapret: 0 " kernel routine to resume at after swap in
u.base: 0 " start of user buffer
u.count: 0 " size of user buffer
"** 01-s1.pdf page 51
u.limit: 0
u.ofiles: .=.+30
u.limit: 0 " end of user buffer
u.ofiles: .=.+30 " open files (10 "fnode" entries)
u.dspbuf: 0
u.intflg: 1
.=userdata+64
ii: .=.+1
inode:
ii: .=.+1 " number of i-node in inode:
inode: " disk inode in memory:
i.flags: .=.+1 " inode flags
" 400000 free?? (checked/toggled by icreat)
" 200000 large file
@@ -225,7 +228,7 @@ dnode: " directory entry:
d.name: .=.+4 " name (space padded)
d.uniq: .=.+1 " unique number from directory inode
. = dnode+8
fnode:
fnode: " open file entry
f.flags: .=.+1
f.badd: .=.+1
f.i: 0