diff --git a/pages/e02-all b/pages/e02-all new file mode 100644 index 0000000..b379b09 --- /dev/null +++ b/pages/e02-all @@ -0,0 +1,524 @@ +/ u2 -- unix + +syslink: / name1, name2 + jsr r0,arg2 / u.namep has 1st arg u.off has 2nd + jsr r0,namei / find the i-number associated with the 1st path name + br error9 / cannot be found + jsr r0,iget / get the i-node into core + mov (sp)+,u.namep / u.namep points to 2nd name + mov r1,-(sp) / put i-number of name1 on the stack (a link + / to this file is to be created) + mov cdev,-(sp) / put i-nodes device on the stack + jsr r0,isdir / is it a directory + jsr r0,namei / no, get i-number of name2 + br .+4 / not found so r1-i-number of current directory + / ii = i-number of current directory + br error9 / file already exits., error + cmp (sp)+,cdev / u.dirp now points to end of current directory + bne error9 + mov (sp),u.dirbuf / i-number of name1 into u.dirbuf + jsr r0,mkdir / make directory entry for name2 in current directory + mov (sp)+,r1 / r1 has i-number of name1 + jsr r0,iget / get i-node into core + incb i.nlks / add 1 to its number of links + jsr r0,setimod / set the i-node modified flag + +sysret9: + jmp sysret / see 'sysret' routine +error9: + jmp error / see 'error' routine + +isdir: / if the i-node whose i-number is in r1 is a directory there is an + / error unless super user make the call + tstb u.uid / super user + beq 1f / yes, don't care + mov ii,-(sp) / put current i-number on stack + jsr r0,iget / get i-number into core (i-number in r1) + bit $40000,i.flgs / is it a directory + bne error9 / yes, error + mov (sp)+,r1 / no, put current i-number back in r1 (ii) + jsr r0,iget / get it back in +1: + rts r0 + +sysunlink: / name - remove link name + jsr r0,arg; u.namep / u.namep points to name + jsr r0,namei / find the i-number associated with the path name + br error9 / not found + mov r1,-(sp) / put its i-number on the stack + jsr r0,isdir / is it a directory + clr u.dirbuf / no, clear the location that will get written + / into the i-number portion of the entry + sub $10.,u.off / move u.off back 1 directory entry + jsr r0,wdir / free the directory entry + mov (sp)+,r1 / get i-number back + jsr r0,iget / get i-node + jsr r0,setimod / set momdified flag + decb i.nlks / decrement the number of links + bgt sysret9 / if this was not the last link to the file return + jsr r0,anyi / if it was, see if anyone has it open. Then + / free contents of file and destroy it. + br sysret9 + +mkdir: + jsr r0,copyz; u.dirbuf+2; u.dirbuf+10. / clear this + mov u.namep,r2 / r2 points to name of directory entry + mov $u.dirbuf+2,r3 / r3 oints to u.dirbuf+2 +1: / put characters in the directory name in u.dirbuf+2 - u.dirbuf+10 + movb (r2)+,r1 / move character in name to r1 + beq 1f / if null, done + cmp r1,$'/ / is it a "/"? + beq error9 / yes, error + cmp r3,$u.dirbuf+10. / have we reached the last slot for + / a char? + beq 1b / yes, go back + movb r1,(r3)+ / no, put the char in the u.dirbuf + br 1b / get next char +1: + mov u.dirp,u.off / pointer to empty current directory slot to u.off + +wdir: + mov $u.dirbuf,u.base / u.base points to reated file name + mov $10.,u.count / u.count = 10 + mov ii,r1 / r1 has i-number of current directory + jsr r0,access; 1 / get i-node and set its file up for writing + jsr r0,writei / write into directory + rts r0 + +sysexec: + jsr r0,arg2 / arg0 in u.namep,arg1 on top of stack + jsr r0,namei / namei return i-number of file named in sysexec call in r1 + br error9 + jsr r0,iget / get i-node for file to be executed + bit $20,i.flgs / is file executable + beq error9 + jsr r0,iopen / gets i-node for file with i-number given in r1 (opens file) + bit $40,i.flgs / test user id on execution bit + beq 1f + tstb u.uid / test user id + beq 1f / super user + movb i.uid,u.uid / put user id of owner of file as process user id +1: + mov (sp)+,r5 / r5 now contains address of list of pointers to arguments to be passed + mov $1,u.quit / u.quit determines handling of quits; + / u.quit = 1 take quit + mov $1,u.intr / u.intr determines handling of interrupts; + / u.intr = 1 take interrupt + mov $rtssym,*30 / emt trap vector set to take system routine + mov $fpsym,*10 / reserved instruction trap vector set to take system routine + mov $sstack,sp / stack space used during swapping + mov r5,-(sp) / save arguments pointer on stack + mov $ecore,r5 / r5 has end of core + mov $core,r4 / r4 has start of users core + mov r4,u.base / u.base has start of users ore + mov (sp),r2 / move arguments list ointer into r2 +1: + tst (r2)+ / argument char = "nul" + bne 1b + tst -(r2) / decrement r2 by 2; r2 has addr of end of arguent pointer list +1: / move arguments to bottom of users core + mov -(r2),r3 / (r3) last non zero argument ptr + cmp r2,(sp) / is r2 = beginning of argument ptr list + blo 1f / branch to 1f when all arguments are moved +2: + tstb (r3)+ + bne 2b / scan argument for \0 (nul) +2: + movb -(r3),-(r5) / move argument char by char starting at "ecore" + cmp r3,(r2) / moved all characters in this argument + bhi 2b / branch 2b if not + mov r5,(r4)+ / move r5 into top of users core; r5 has pointer to nth arg + br 1b / string +1: + clrb -(r5) + bic $1,r5 / make r5 even, r5 points to last word of argument strings + mov $core,r2 +1: / move argument ointers into core following argument strings + cmp r2,r4 + bhis 1f / branch to 1f when all pointers are moved + mov (r2)+,-(r5) + br 1b +1: + sub $core,r4 / gives number of arguments *2 + asr r4 / divide by 2 to calculate the number of args stored + mov r4,-(r5) / save number of arguments ahead of the argument pointers + clr -(r5) / popped into ps when rti in sysrele is executed + mov $core,-(r5) / popped into pc when rti is sysrele is executed + mov r5,0f / load second copyz argument + tst -(r5) / decrement r5 + mov r5,u.r0 / + sub $16.,r5 / skip 8 words + mov r5,u.sp / assign user stack ointer value, effectively + / zeros all regs when sysrele is executed + jsr r0,copyz; core; 0:0 / zero user's core + clr u.break + mov r5,sp / point sp to user's stack + mov $14,u.count + mov $u.off,u.fofp + clr u.off / set offset in file to be read to zero + jsr r0,readi / read in first six words of user's file, starting at $core + mov sp,r5 / put users stack address in r5 + sub $core+40.,r5 / subtract $core +40 from r5 (leaves + / number of words less 26 available for + / program in user core + mov r5,u.count / + cmp core,$405 / br .+14 is first instrution if file is + / standard a.out format + bne 1f / branch, if not standard format + mov core+2,r5 / put 2nd word of users program in r5; number of + / bytes in program text + sub $14,r5 / subtract 12 + cmp r5,u.count + bgt 1f / branch if r5 is greater than u.count + mov r5,u.count + jsr r0,readi / read in rest of user's program text + add core+10,u.nread / add size of user data area to u.nread + br 2f +1: + jsr r0,readi / read in rest of file +2: + mov u.nread,u.nbreak / set users program break to end of user code + add $core+14,u.break / plus data area + jsr r0,iclose / does nothing + br sysret3 / return to core image at $core + +sysfstat: / set status of open file + jsr r0,arg; u.off / put buffer address in u.off + mov u.off,-(sp) / put buffer address on stack + mov *u.ro,r1 / put file descriptor in r1 + jsr r0,getf / get the files i-number + tst r1 / is it 0? + beq error3 / yes, error + bgt 1f / if i-number is negative (open for writing) + neg r1 / make it positive, then branch to 1f + br 1f + +sysstat: / ; name of file; buffer - get files status + jsr r0,arg2 / get the 2 arguments + jsr r0,namei / get the i-number for the file + br error3 / no such file, error +1: + jsr r0,iget / get the i-node into core + mov (sp)+,r3 / move u.off to r3 (points to buffer) + mov r1,(r3)+ / put i-number into 1st word of buffer + mov $inode,r2 / r2 points to i-node +1: + mov (r2)+,(r3)+ / move rest of i-node to buffer + cmp r2,$inode+32 / done? + bne 1b / no, go back + br sysret3 / return through sysret + +error3: + jmp error / see 'error' routine +sysret3: + jmp sysret / see 'sysret' routine + +getf: / get the device number into the i-number of an open file + cmp r1,$10. / user limited to 10 open files + bhis error3 / u.fp is table of users open files, index in fsp table + movb u.fp(r1),r1 / r1 contains number of entry in fsp table + beq 1f / if its zero, return + asl r1 + asl r1 / multiply by 8 to get index into fsp table entry + asl r1 + add $fsp-4,r1 / r1 is pointing at the 3rd word in the fsp entry + mov r1,u.fofp / save address of 3rd word in fsp entry in u.fofp + mov -(r1),cdev / remove the device number cdev + mov -(r1),r1 / and the i-number in r1 +1: + rts r0 + +namei: + mov u.cdir,r1 / put the i-number of current directory in r1 + mov u.cdev,cdev / device number for users directory into cdev + cmpb *u.namep,$'/ / is first char in file name a / + bne 1f + inc u.namep / go to next char + mov rootdir,r1 / put i-number of rootdirectory in r1 + clr cdev / clear device number +1: + tstb *u.namep / is the character in file name a nul + beq nig / yes, end of file name reached; branch to "nig" +/ ?? 1: this label was marked out in the listing -bc + jsr r0,access; 2 / get i-node with i-number r1 + bit $40000,i.flgs / directory i-node? + beq error3 / no, got an error + mov i.size,u.dirp / put size of directory in u.dirp + clr u.off / u.fofp u.off is file offset used by user + mov $u.off,u.fofp / u.fofp is a pointer to the offset portion of fsp entry +2: + mov $u.dirbuf,u.base / u.dirbuf holds a file name copied from a directory + mov $10.,u.count / u.count is byte count for reads and writes + jsr r0,readi / read 10. bytes of file with i-number (r1); + / i.e. read a directory entry + tst u.nread + ble nib / gives error return + tst u.dirbuf / + bne 3f / branch when active directory entry (i-node word in entry non zero) + mov u.off,u.dirp + sub $10.,u.dirp + br 2b +3: + mov u.namep,r2 / u.namep points into a file name string + mov $u.dirbuf+2,r3 points to file name of directory entry +3: + movb (r2)+,r4 / move a character from u.namep string into r4 + beq 3f / if char is nul, then the last char in string has been moved + cmp r4,$'/ / is char a + beq 3f + cmp r3,$u.dirbuf+10. / have I checked all 8 bytes of file name + beq 3b + cmpb (r3)+,r4 / compare char in u.namep string to file name char read from + beq 3b / directory; branch if chars match + br 2b / file names do not match go to next directory entry +3: + cmp r3,$u.dirbuf+10. / if equal all 8 bytes were matched + beq 3f + tstb (r3)+ / + bne 2b +3: + mov r2,u.namep / u.namep points to char following a / or nul + mov u.dirbuf,r1 / move i-node number in directory entry to r1 + tst r4 / if r4 = 0 the end of file name reached, if r4 = + / then go to next directory + bne 1b + +nig: + tst (r0)+ / gives non-error return +nib: + rts r0 + +syschdir: / make the directory specified in the argument the current directory + jsr r0,arg; u.namep / u.namep points to path name + jsr r0,namei / find its i-number + br error3 + jsr r0,access; 2 / get i-node into core + bit $40000,i.flgs / is it a directory? + beq error3 / no error + mov r1,u.cdir / move i-number to users current directory + mov cdev,u.cdev / move its device to users current device + br sysret3 + +isown: + jsr r0,arg2 / u.namep points to file name + jsr r0,namei / get its i-number + br error3 + jsr r0,iget / get i-node into core + tstb u.uid / super user? + beq 1f / yes, branch + cmpb i.uid,u.uid / no, is this the owner of the file + beq 1f / yes + jmp error3 / no, error +1: + jsr r0,setimod / indicate i-node has been modified + mov (sp)+,r2 / mode is put into r2 (u.off put on stack with 2nd arg) + rts r0 + +syschmod: / name; mode + jsr r0,isown / get the i-node and check user status + bit $40000,i.flgs / directory? + beq 2f / no + bic $60,r2 / su and ex / yes, clear set user id and executable modes +2: + movb r2,i.flgs / move remaining mode to i.flgs + br 1f + +syschown: / name; owner + jsr r0,isown / get the i-node and check user status + tstb u.uid / super user + beq 2f / yes, 2f + bit $40,i.flgs / no, set userid on execution? + bne 3f / yes error, could create Trojan Horses +2: + movb r2,i.uid / no, put the new owners id in the i-node +1: + jmp sysret4 +3: + jmp error + +arg: + mov u.sp,r1 + mov *18.(r1),*(r0)+ / put argument of system call into argument of arg2 + add $2,18.(r1) / point pc on stack to next system argument + rts r0 + +arg2: + jsr r0,arg; u.namep / u.namep contains value of first art in sys call + jsr r0,arg; u.off / u.off contains value of second arg in sys call + mov r0,r1 / r0 points to callling routine + mov (sp),r0 / put operation code back in r0 + mov u.off,(sp) / put pointer to second argument on stack + jmp (r1) / return to calling routine + +systime: / get time of year + mov s.time,4(sp) + mov s.time+2,2(sp) / put the present time on the stack + br sysret4 + +sysstime: / set time + tstb u.uid / is user the super user + bne error4 / no, error + mov 4(sp),s.time + mov 2(sp),s.time+2 + br sysret4 + +sysbreak: / set the program break + mov u.break,r1 / move users break point to r1 + cmp r1,$core / is it the same or lower than core? + blos 1f / yes, 1f + cmp r1,sp / is it the same or higher than the stack? + bhis 1f / yes, 1f + bit $1,r1 / is it an odd address + beq 2f / no, its even + clrb (r1)+ / yes, make it even +2: / clear area between the break point and the stack + cmp r1,sp / is it higher or same than the stack + bhis 1f / yes, quit + clr (r1)+ / clear word + br 2b / go back +1: + jsr r0,arg; u.break / put the "address" in u.brak (set new break point) + br sysret4 / br sysret + +maknod: / r1 contains the mode + bis $100000,r1 / allocate flag set + mov r1,-(sp) / put mode on stack + mov ii,r1 / move current i-number to r1 + jsr r0,access; 1 / get its i-node into core + mov r1,-(sp) / put i-number on stack + mov $40.,r1 / r1 = 40 +1: / scan for a free i-node (next 4 instructions) + inc r1 / r1 = r1 + 1 + jsr r0,imap / get byte address and bit position in inode map in r2 & m + bitb mq,(r2) / is the i-node active + bne 1b / yes, try the next one + bisb mq,(r2) / no, make it active (put a 1 in the bit map) + jsr r0,iget / get i-node into core + tst i.flgs / is i-node already allocated + blt 1b / yes, look for another one + mov r1,u.dirbuf / no, put i-number in u.dirbuf + mov (sp)+,r1 / get current i-number back + jsr r0,iget / get i-node in core + jsr r0,mkdir / make a directory entry in current directory + mov u.dirbuf,r1 / r1 = new inode number + jsr r0,iget / get it into core + jsr r0,copyz; inode; inode+32. / 0 it out + mov (sp)+,i.flgs / fill flags + movb u.uid,i.uid / user id + movb $1,i.nlks / 1 link + mov s.time,i.ctim / time created + mov s.time+2,i.ctim+2 / time modified + jsr r0,setimod / set modified flag + rts r0 / return + +sysseek: / moves read write pointer in a fsp entry + jsr r0,seektell / get proper value in u.count + add u.base,u.count / add u.base to it + mov u.count,*u.fofp / put result into r/w pointer + br sysret4 + +systell: / get the r/w pointer + jsr r0,seektell + br error4 + +error4: + jmp error / see 'error' routine +sysret4: + jmp sysret / see 'sysret' routine + +seektell: + jsr r0,arg; u.base / puts offset into u.base + jsr r0,arg; u.count / put ptr name in u.count + mov *u.r0,r1 / file descriptor in r1 ( index in u.fp list) + jsr r0,getf / u.fofp points to 3rd word in fsp entry + mov r1,-(sp) / r1 has i-number of file, put it on the stack + beq error4 / if i-number is 0, not active so error + bgt .+4 / if its positive jump + neg r1 / if not make it positive + jsr r0,iget / get its i-node into core + cmp u.count,$1 / is ptr name =1 + blt 2f / no its zero + beq 1f / yes its 1 + mov i.size,u.count / put number of bytes in file in u.count + br 2f +1: / ptr name =1 + mov *u.fofp,u.count / put offset in u.count +2: / ptrname =0 + mov (sp)+,r1 / i-number on stack r1 + rts r0 + +sysintr: / set interrupt handling + jsr r0,arg; u.intr / put the argument in u.intr + br 1f / go into quit routine +sysquit: / hand written on printout -bc + jsr r0,arg; u.quit / put argument in u.quit +1: + mov u.ttyp,r1 / move pointer to control tty buffer to r1 + beq sysret4 / return to user + clrb 6(r1) / clear the interrupt character in the tty buffer + br sysret4 / return to user + +syssetuid: / set process id + movb *u.r0,r1 / move process id (number) to r1 + cmpb r1,u.ruid / is it equal to the real user id number + beq 1f / yst + tstb u.uid / no, is current user the super user? + bne error4 / no, error +1: + movb r1,u.uid / put process id in u.uid + movb r1,u.ruid / put process id in u.ruid + br sysret4 / system return + +sysgetuid: + movb u.ruid,*u.r0 / move the real user id to (u.r0) + br sysret4 / systerm return, sysret + +fclose: + mov r1,-(sp) / put r1 on the stack (it contains the index to u.fp list) + jsr r0,getf / r1 contains i-number, cdev has device #, u.fofp points to 3rd word of fsp entry + tst r1 / is inumber 0? + beq 1f / yes, i-node not active so return + tst (r0)+ / no, jump over error return + mov r1,r2 / move i-number to r2 + mov (sp),r1 / restore value of r1 from the stack which is index to u.fp + clrb u.fp(r1) / clear that entry in the u.fp list + mov u.fofp,r1 / r1 points to 3rd word in fsp entry + decb 2(r1) / decrement the number of processes that have opened the file + bge 1f / if all processes haven't closed the file, return + mov r2,-(sp) / put r2 on the stack (i-number) + clr -4(r1) / clear 1st word of fsp entry + tstb 3(r1) / has this file been deleted + beq 2f / no, branch + mov r2,r1 / yes, put i-number back into r1 + jsr r0,anyi / free all blocks related to i-number + / check if file appears in fsp again +2: + mov (sp)+,r1 / put i-number back into r1 + jsr r0,iclose / check to see if its a special file +1: + mov (sp)+,r1 / put index to u.fp back into r1 + rts r0 + +anyi: / r1 contains an i-number + mov $fsp,r2 / move start of fsp table to r2 +1: + cmp r1,(r2) / do i-numbers match? + beq 1f / yes, 1f + neg r1 / no complement r1 + cmp r1,(r2) / do they match now? + beq 1f / yes, transfer + / i-number do not match + add $8,r2 / no, bump to next entry in fsp table + cmp r2,$fsp+[nfiles*8] / are we at last entry in the table + blt 1b / no, check next entries i-number + tst r1 / yes, no match + bge .+4 + neg r1 / make i-number positive + jsr r0,imap / get address of allocation bit in the i-map in r2 + bicb mq,(r2) / clear bit for i-node in the imap + jsr r0,itrunc / free all blocks related to i-node + clr i.flgs / clear all flags in the i-node + rts r0 / return +1: / i-numbers match + incb 7(r2) / increment upper byte of the 4th word + rts r0 / in that fsp entry (deleted flag of fsp entry) \ No newline at end of file diff --git a/tools/rebuild b/tools/rebuild index 72b45f0..079f213 100755 --- a/tools/rebuild +++ b/tools/rebuild @@ -6,7 +6,7 @@ test -d rebuilt || mkdir rebuilt m u0 e00-* #m u1 e01-* -#m u2 e02-* +m u2 e02-* #m u3 e03-* #m u4 e04-* m u5 e05-*