Files
pdp7-unix/src/sys/s6.s
T
phil 4b284c6bbe Improve sys annotations
Finally understand location 7 (incremented at 60Hz)
	setting it to -1 causes clock interrupt every jiffy
Improve comments in dsktrans
Clarify cnop/cskp usage in iread/iwrite code
	iwrite and iread have common code
	entry at iwrite save return address at iread
		and overwrites return address to "skp" inst
	entry at iread puts "nop" inst at iwrite
	"xct iwrite" skips on write entry
2019-10-21 22:24:09 -04:00

378 lines
9.9 KiB
ArmAsm

"** 01-s1.pdf page 34
" s6
itrunc: 0
-7 " loop 7 times
dac 9f+t " in t0
lac idskpp " pointer to inode block numbers
dac 9f+t+1 " save in t1
1: " top of loop for inode blocks
lac 9f+t+1 i " fetch next block number
sna " allocated?
jmp 4f " no
lac i.flags " check flags
and o200000
sna " large file?
jmp 3f " no
-64 " loop 64 times
dac 9f+t+2 " save count in t2
lac dskbufp " get pointer to dskbuf
dac 9f+t+3 " in t3
2: " inner loop for indirect blocks
lac 9f+t+1 i " get indirect block number
jms dskrd " read it
lac 9f+t+3 i " read block number from indirect
sza " free?
jms free " no: free it
isz 9f+t+3 " increment pointer into indirect block
isz 9f+t+2 " increment loop counter, skip if done
jmp 2b " not done: loop
3: " here with small file
lac 9f+t+1 i " load block number
jms free " free it
dzm 9f+t+1 i " clear block number
4: " bottom of loop for inode block ptrs
isz 9f+t+1 " increment block pointer
isz 9f+t " increment count, skip if done
jmp 1b " not done
lac i.flags
and o577777 " clear large file flag
dac i.flags
jmp itrunc i
t = t+4
" Given a pointer to a 4-word filename after
" the jms to namei, and with AC holding the
" i-num of the directory it is in, return the
" i-number of the filename (and skip)
" return zero in AC if not found (no skip)
namei: 0
jms iget " Get the inode from the i-num in the AC
-1
tad namei i " get argptr-1
dac 9f+t+1 " save in t1
isz namei " skip over argument
lac i.flags
and o20 " get directory bit
sna " Is this a directory?
jmp namei i " no: return without skip
-8
tad i.size " Subtract 8 from the file's size
cma
lrss 3
dac 9f+t " negative count of directory entries in t0
sna " any?
jmp namei i " no: return without skip
dzm di " Store zero in di
1:
lac di
"** 01-s1.pdf page 35
jms dget " Get a directory entry from the dirblock
lac d.i " get i-num
sna " in use?
jmp 2f " no
lac 9f+t+1 " get argptr-1
dac 8
lac d.name " Compare the four words of the filename in the
sad 8 i " directory entry with the argument to namei
skp
jmp 2f " No match
lac d.name+1
sad 8 i
skp
jmp 2f " No match
lac d.name+2
sad 8 i
skp
jmp 2f " No match
lac d.name+3
sad 8 i
skp
jmp 2f " No match
lac d.i " A match. Get the i-number into AC
isz namei " give skip return
jmp namei i
2:
isz di " No match, move up to the next direntry
isz 9f+t " any left?
jmp 1b " yes: keep going
jmp namei i " Didn't find it, return zero in AC (without skip)
t = t+2
" NOTE: iget/iput share "temp" vars!!!
" Given an i-number in AC, fetch that i-node
" from disk and store it in the inode buffer
iget: 0
dac ii " Store the i-number in ii
cll; idiv; 5 " Divide by 5: 5 inodes in a block
dac 9f+t " Store the remainder in 9f+t: the i-node
lacq " number within the block
tad d2 " Add 2 to the quotient to get the block number
dac 9f+t+1 " and store in 9f+t+1
jms dskrd " Get the block
lac 9f+t
cll; mul; 12 " Multiply the i-num within the block by 12
lacq " to get the offset into the block
tad dskbufp " Add on the base of the disk buffer
dac 9f+t " save pointer into dskbuf in "t0"
dac .+2
jms copy; ..; inode; 12 " Copy 12 words from buffer to inode
jmp iget i " and return
iput: 0
lac 9f+t+1 " get block number saved by iget
jms dskrd " read the block
law inode-1 " pointer to "in core" inode
dac 8 " in index 8
-1
tad 9f+t " get saved pointer into buffer
dac 9 " in index 9
-12 " 12 word loop count
dac 9f+t+2 " in t2
1:
lac 8 i " fetch source word
"** 01-s1.pdf page 36
sad 9 i " differs from disk?
skp " no:
jmp 2f " yes:
isz 9f+t+2 " no difference: done?
jmp 1b " no: keep going
jmp iput i " yes: return w/o writing to disk
2: " here with in-core inode changed
-1 " back up both pointers
tad 8
dac 8
-1
tad 9
dac 9
1:
lac 8 i " fetch word
dac 9 i " copy to dskbuf
isz 9f+t+2 " done?
jmp 1b " no: keep going
lac 9f+t+1 " get block number
jms dskwr " write back to disk
jmp iput i " return
t = t+3
" NOTE! dget/dput share "temp" vars
" allocate directory entry
" AC/ entry number
dget: 0
dac di " save entry number
alss 3 " get word number
dac 9f+t " save in t0
jms pget " get free disk block
dac 9f+t+1 " save in t1
jms dskrd " read block
lac 9f+t " get word number
and o77 " get word within block
tad dskbufp " make pointer into dskbuf
dac 9f+t+2 " save in t2
dac .+2 " save as copy source
jms copy; ..; dnode; 8 " copy entry into dnode
lac 9f+t " get word number
tad d8 " of end of new node
jms betwen; d0; i.size " already allocated?
skp " no
jmp dget i " yes: return
jms dacisize " store new file size
dzm d.i " mark new entry as free
jmp dget i " return
" write directory entry (back) to disk
dput: 0
lac 9f+t+1 " get disk block number back
jms dskrd " read into dskbuf
lac 9f+t+2 " get pointer into dskbuf
dac .+3 " save as copy dest
jms copy; dnode; ..; 8 " copy into dskbuf
lac 9f+t+1 " get disk block number
jms dskwr " write back to disk
jmp dput i
t = t+3
" get a block number for a file, returns disk block number
" allocates block if not allocated
" AC/ file offset
" jms pget
" AC/ disk block number
pget: 0
lrss 6 " convert offset to block
dac 9f+t " save as t0
lac i.flags
"** 01-s1.pdf page 37
and o200000
sza " large file bit set?
jmp 2f " yes
lac 9f+t " no: small file
jms betwen; d0; d6 " block 0..6?
jmp 1f " no
tad idskpp " make into block number pointer
dac 9f+t " save in t0
lac 9f+t i " get disk block number
sna " allocated?
jms alloc " no: allocate now
dac 9f+t i " save (new) disk block number
jmp pget i " return disk block number
1: " here when file block>=7, not "large"
jms alloc " allocate indirect block
dac 9f+t+1 " save as t1
jms copy; i.dskps; dskbuf; 7 " copy all the disk block numbers
jms copyz; dskbuf+7; 64-7 " zero rest of indirect block
lac 9f+t+1 " get indirect block number back
jms dskwr " write indirect block to disk
lac 9f+t+1
dac i.dskps " save indirect as new first block
jms copyz; i.dskps+1; 6 " zero rest of block pointers
lac i.flags
xor o200000 " set "large file"
dac i.flags
2: " here with "large file"
lac 9f+t " get file block number
lrss 6 " divide by 64 (indirects/block)
jms betwen; d0; d6 " ok now?
jms halt " file too big " no, you lose!
tad idskpp " yes: get indirect block pointer
dac 9f+t+1 " save in t1
lac 9f+t+1 i " get indirect block number
sna " allocated?
jms alloc " no, get it now
dac 9f+t+1 i " save (new) indirect block
dac 9f+t+2 " save as t2
jms dskrd " read indirect block
lac 9f+t " get original block number
and o77 " mod by 64
tad dskbufp " get pointer to disk block number
dac 9f+t+1 " save as t1
lac 9f+t+1 i " fetch disk block number
sza " allocated?
jmp pget i " yes: return
jms alloc " no: allocate data block
dac 9f+t " save as t0
lac 9f+t+2 " get indirect block number
jms dskrd " read it in
lac 9f+t " get data block number
dac 9f+t+1 i " save data block number
lac 9f+t+2
jms dskwr " write indirect block back
lac 9f+t " get data block back
jmp pget i " return it
t = t+3
" write to file referenced by loaded inode
" AC/ file offset
" jms iwrite; addr; count
iwrite: 0 " set to skp (or nop by iread)
dac 9f+t " save arg in t0
lac iwrite " load return address
"** 01-s1.pdf page 38
dac iread " save as iread return addr
lac cskp " load skip instruction
dac iwrite " save as iwrite instruction
jmp 1f
" read from file referenced by loaded inode
" AC/ file offset
" jms iread; addr; count
iread: 0
dac 9f+t " save offset in t0
lac cnop " get nop
dac iwrite " save in iwrite return location
1: " common code for iread/iwrite
-1
tad iread i " get word before return addr
dac 10 " store in index 10 & 11
dac 11
isz iread " increment return addr
lac iread i " load addr
dac 9f+t+1 " save in t1
isz iread " increment return addr
lac o70000 " get max file size
xct iwrite " skip if write
lac i.size " read: get file size
cma
tad 9f+t " add offset
cma
jms betwen; d0; 9f+t+1
lac 9f+t+1
dac 9f+t+2
cma
tad d1 " subtract offset
sna " offset == size?
jmp iread i " yes, return
dac 9f+t+1 " save size-offset in t1
1:
lac 9f+t
jms pget
dac 9f+t+3
jms dskrd
lac 9f+t
and o77
tad dskbufp
tad dm1
xct iwrite " skip if write
jmp .+3
dac 10 " here on read
cskp: " literal for store to iwrite
skp
dac 11 " here on write
2:
lac 11 i
dac 10 i
isz 9f+t
isz 9f+t+1
jmp 3f
xct iwrite " skip if write
jmp 4f
lac 9f+t
jms betwen; d0; i.size
dac i.size
lac 9f+t+3
jms dskwr
4:
"** 01-s1.pdf page 38
lac 9f+t+2
jmp iread i
3:
lac 9f+t
and o77
sza
jmp 2b
xct iwrite " skip if write
jmp 1b
lac 9f+t+3
jms dskwr
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
jms error
lac f.flags
sma
jms error
lac f.i
jms iget
jmp finac i
" update inode file size with value in AC
dacisize: 0
dac i.size
jms iput
lac i.size
jmp dacisize i