| 1 | / u7 -- unix |
| 2 | |
| 3 | canon: |
| 4 | mov r5,r1 / move tty buffer address to r1 |
| 5 | add $10.,r1 / add 10 to get start of data |
| 6 | mov r1,4(r5) / canp = 10(r5) / move buffer addr + 10 to 3rd |
| 7 | / word in buffer (char. pointer) |
| 8 | clr 2(r5) / ncan / clear 2nd word in buffer, 0 char. count |
| 9 | 1: |
| 10 | jsr r0,*(r0) / jump to arg get char off Q of characters, sleep |
| 11 | / if none |
| 12 | jsr r0,cesc; 100 / test for @ (kill line) |
| 13 | br canon / character was @ so start over |
| 14 | jsr r0,cesc; 43 / test for # (erase last char. typed) |
| 15 | br 1b / character was #, go back |
| 16 | cmp r1,$4 / is char eot? |
| 17 | beq 1f / yes, reset and return |
| 18 | movb r1,*4(r5) / no, move char to address in 3rd word of buffer |
| 19 | / (char. pointer) |
| 20 | inc 2(r5) / increment 2nd word (char. count) |
| 21 | inc 4(r5) / increment 3rd word (char. pointer) |
| 22 | cmp r1,$'\n / is char = newline |
| 23 | beq 1f / yes, 1f |
| 24 | cmp 2(r5),$120. / is byte count greater than or equal to 120 |
| 25 | bhis 1f / yes, 1f |
| 26 | br 1b / no, get another char off the Q |
| 27 | 1: / get here if line is full, a new line has been received or an eot |
| 28 | / has been received |
| 29 | mov r5,r1 / move buffer address to r1 |
| 30 | add $10.,r1 / add 10 |
| 31 | mov r1,4(r5) / canp = 10(r5) / reset char pointer |
| 32 | tst (r0)+ / skip over argument |
| 33 | rts r0 / return |
| 34 | |
| 35 | cesc: / test for erase or kill char |
| 36 | cmp r1,(r0)+ / char in r1 = erase or kill character? |
| 37 | bne 1f / no, skip return |
| 38 | tst 2(r5) / yes, is char. count = 0 |
| 39 | beq 2f / yes, don't skip return |
| 40 | dec 2(r5) / no, decrement char count |
| 41 | dec 4(r5) / decrement character pointer |
| 42 | cmpb *4(r5),$'\\/ was previous character a "\" |
| 43 | bne 2f / no, don't skip |
| 44 | 1: |
| 45 | tst (r0)+ / yes, skip |
| 46 | 2: |
| 47 | rts r0 / return |
| 48 | |
| 49 | ttych: / get characters from Q of characters inputted to tty |
| 50 | mov $240,*$ps / set processor priority to 5 |
| 51 | jsr r0,getc; 0 / takes char. off clist and puts it in r1 |
| 52 | br 1f / list is empty, go to sleep |
| 53 | clr *$ps / clear process priority |
| 54 | rts r0 / return |
| 55 | 1: / list is empty |
| 56 | mov r5,-(sp) / save r5 |
| 57 | jsr r0,sleep; 0 / put process to sleep in input wait channel |
| 58 | mov (sp)+,r5 / restore r5 |
| 59 | br ttych / try again |
| 60 | |
| 61 | pptic: / paper tape input control |
| 62 | mov $240,*$ps / set processor priority to five |
| 63 | cmpb cc+2,$30. / is character count for paper tape input in |
| 64 | / clist greater than or equal to 30 |
| 65 | bhis 1f / yes, branch |
| 66 | bit *$prs,$104200 / is there either an error, an unread char |
| 67 | / in buffer, or reader busy |
| 68 | bne 1f / yes, don't enable reader |
| 69 | inc *$prs / set reader enable bit |
| 70 | 1: |
| 71 | jsr r0,getc; 2 / get next character in clist for ppt input and |
| 72 | br 1f / place in r1; if no char in clist for ppt input |
| 73 | / branch |
| 74 | tst (r0)+ / pop stack so that return will be four locations past |
| 75 | / subroutine call |
| 76 | 2: |
| 77 | clr *$ps / set process priority equal to zero |
| 78 | rts r0 / return |
| 79 | 1: |
| 80 | cmpb pptiflg,$6 / does pptiflg indicate file "not closed" |
| 81 | beq 2b / yes, return to calling routine at instruction |
| 82 | / immediately following jsr |
| 83 | jsr r0,sleep; 2 / no, all characters to be read in not yet in |
| 84 | / clist, put process to sleep |
| 85 | br pptic |
| 86 | |
| 87 | pptoc: / paper tape output control |
| 88 | mov $240,*$ps / set processor priority to five |
| 89 | cmpb cc+3,$50. / is character count for paper tape output in |
| 90 | / clist greater than or equal to 50 |
| 91 | bhis 1f / yes |
| 92 | jsr r0,putc; 3 / find place in freelist to assign ppt output |
| 93 | / and place |
| 94 | br 1f / character in list; if none available branch to put |
| 95 | / process to sleep |
| 96 | jsr r0,starppt / try to output character |
| 97 | clr *$ps / clear processor priority |
| 98 | rts r0 / return |
| 99 | 1: |
| 100 | mov r1,-(sp) / place character on stack |
| 101 | jsr r0,sleep; 3 / put process to sleep |
| 102 | mov (sp)+,r1 / place character in r1 |
| 103 | br pptoc / try again to place character in clist and output |
| 104 | |
| 105 | /lptoc: / line printer output control |
| 106 | / mov $240,*$ps / set processor priority to five |
| 107 | / cmpb cc+5,$200. / is character count for printer greater than or |
| 108 | / equal to 200 |
| 109 | / bhis 1f / yes |
| 110 | / jsr r0,putc; 5 / find place in freelist to assign to printer |
| 111 | / and place |
| 112 | |
| 113 | br 1f / char in list, if none available branch to put |
| 114 | / process to sleep |
| 115 | / jsr r0,starlpt / try to output character |
| 116 | / clr *$ps / set processor priority = 0 |
| 117 | / rts r0 / return |
| 118 | /1: |
| 119 | / mov r1,-(sp) / place character on stack |
| 120 | / jsr r0,sleep; 5 / put process to sleep |
| 121 | / mov (sp)+,r1 / place character on stack |
| 122 | / br lptoc |
| 123 | |
| 124 | getc: / get a character off character list |
| 125 | mov (r0)+,r1 / put argument in getc call in r1 (char list id) |
| 126 | jsr r0,get |
| 127 | br 1f / empty char list return |
| 128 | decb cc(r1) / decrement number of char in char list |
| 129 | mov $-1,r1 / load minus 1 in r1 |
| 130 | jsr r0,put / put char back on free list |
| 131 | movb clist-2(r2),r1 / put char in r1 |
| 132 | tst (r0)+ / bump r0 for non blank char list return |
| 133 | 1: |
| 134 | rts r0 |
| 135 | |
| 136 | putc: |
| 137 | mov r1,-(sp) / save char on stack |
| 138 | mov $-1,r1 / put free list list id in r1 |
| 139 | jsr r0,get / take char off free list / clist slot taken |
| 140 | / identified by r2 |
| 141 | br 1f / branch when no chars in free list |
| 142 | mov (r0)+,r1 / put putc call arg in r1 (i.e., list identifier) |
| 143 | incb cc(r1) / increment character count for list (r1) |
| 144 | jsr r0,put / put clist entry on list |
| 145 | movb (sp),clist-2(r2) / put character in new entry |
| 146 | 1: |
| 147 | tst (r0)+ |
| 148 | mov (sp)+,r1 |
| 149 | rts r0 |
| 150 | |
| 151 | get: |
| 152 | movb cf+1(r1),r2 / move current first char offset to r2 |
| 153 | beq 2f / no characters in char list |
| 154 | tst (r0)+ / bump r0, second return |
| 155 | cmpb r2,cl+1(r1) / r2 equal to last char offset |
| 156 | beq 1f / yes, (i.e., entire char list scanned), branch to 1f |
| 157 | bic $!377,r2 / clear bits 8-15 in r2 |
| 158 | asl r2 / multiply r2 by 2 to get offset in clist |
| 159 | movb clist-1(r2),cf+1(r1) / move next char in list pointer to |
| 160 | / first char offset ptr |
| 161 | br 2f |
| 162 | 1: |
| 163 | clrb cf+1(r1) / clear first char clist offset |
| 164 | clrb cl+1(r1) / clear last char clist offset |
| 165 | bic $!377,r2 / zero top half of r2 |
| 166 | asl r2 / multiply r2 by 2 |
| 167 | 2: |
| 168 | rts r0 |
| 169 | |
| 170 | put: |
| 171 | asr r2 / divide r2 by 2; r2 is offset in clist |
| 172 | mov r2,-(sp) / save r2 on stack |
| 173 | movb cl+1(r1),r2 / move offset of last char in list (r1) into r2 |
| 174 | beq 1f / offset = 0 then go to 1f (i.e., start a new list) |
| 175 | bic $!377,r2 / zero top half of r2 |
| 176 | asl r2 / multiply offset by 2, r2 now has offset in clist |
| 177 | movb (sp),clist-1(r2) / link new list entry to current last |
| 178 | / entry in list (r1) |
| 179 | br 2f |
| 180 | 1: |
| 181 | movb (sp),cf+1(r1) / put new list entry offset into first char |
| 182 | / offset of list (r1) |
| 183 | 2: |
| 184 | mov (sp)+,r2 / pop stack into r2; offset of new list |
| 185 | / entry in r2 |
| 186 | movb r2,cl+1(r1) / make new list entry the last entry in list |
| 187 | / (r1) |
| 188 | asl r2 / multiply r2 by 2; r2 has clist offset for new |
| 189 | / list entry |
| 190 | rts r0 |
| 191 | |
| 192 | iopen: / open file whose i-number is in r1 |
| 193 | tst r1 / write or read access? |
| 194 | blt 2f / write, go to 2f |
| 195 | jsr r0,access; 2 / get inode into core with read access |
| 196 | cmp r1,$40. / is it a special file |
| 197 | bgt 3f / no. 3f |
| 198 | mov r1,-(sp) / yes, figure out |
| 199 | asl r1 |
| 200 | jmp *1f-2(r1) / which one and transfer to it |
| 201 | 1: |
| 202 | otty / tty |
| 203 | oppt / ppt |
| 204 | sret / mem |
| 205 | sret / rf0 |
| 206 | sret / rk0 |
| 207 | sret / tap0 |
| 208 | sret / tap1 |
| 209 | sret / tap2 |
| 210 | sret / tap3 |
| 211 | sret / tap4 |
| 212 | sret / tap5 |
| 213 | sret / tap6 |
| 214 | sret / tap7 |
| 215 | ocvt / tty0 |
| 216 | ocvt / tty1 |
| 217 | ocvt / tty2 |
| 218 | ocvt / tty3 |
| 219 | ocvt / tty4 |
| 220 | ocvt / tty5 |
| 221 | ocvt / tty6 |
| 222 | ocvt / tty7 |
| 223 | error / crd |
| 224 | |
| 225 | 2: / check open write access |
| 226 | neg r1 / make inode number positive |
| 227 | jsr r0,access; 1 / get inode in 0 core |
| 228 | bit $40000,i.flgs / is it a directory? |
| 229 | bne 2f / yes, transfer (error) |
| 230 | cmp r1,$40. / no, is it a special file? |
| 231 | bgt 3f / no, return |
| 232 | mov r1,-(sp) / yes |
| 233 | asl r1 |
| 234 | jmp *1f-2(r1) / figure out which special file it is |
| 235 | / and transfer |
| 236 | 1: |
| 237 | otty / tty |
| 238 | leadr / ppt |
| 239 | sret / mem |
| 240 | sret / rf0 |
| 241 | sret / rk0 |
| 242 | sret / tap0 |
| 243 | sret / tap1 |
| 244 | sret / tap2 |
| 245 | sret / tap3 |
| 246 | sret / tap4 |
| 247 | sret / tap5 |
| 248 | sret / tap6 |
| 249 | sret / tap7 |
| 250 | ocvt / tty0 |
| 251 | ocvt / tty1 |
| 252 | ocvt / tty2 |
| 253 | ocvt / tty3 |
| 254 | ocvt / tty4 |
| 255 | ocvt / tty5 |
| 256 | ocvt / tty6 |
| 257 | ocvt / tty7 |
| 258 | / ejec / lpr |
| 259 | |
| 260 | otty: / open console tty for reading or writing |
| 261 | mov $100,*$tks / set interrupt enable bit (zero others) in |
| 262 | / reader status reg |
| 263 | mov $100,*$tps / set interrupt enable bit (zero others) in |
| 264 | / punch status reg |
| 265 | mov tty+[ntty*8]-8+6,r5 / r5 points to the header of the |
| 266 | / console tty buffer |
| 267 | incb (r5) / increment the count of processes that opened the |
| 268 | / console tty |
| 269 | tst u.ttyp / is there a process control tty (i.e., has a tty |
| 270 | / buffer header |
| 271 | bne sret / address been loaded into u.ttyp yet)? yes, branch |
| 272 | mov r5,u.ttyp / no, make the console tty the process control |
| 273 | / tty |
| 274 | br sret / ? |
| 275 | |
| 276 | sret: |
| 277 | clr *$ps / set processor priority to zero |
| 278 | mov (sp)+,r1 / pop stack to r1 |
| 279 | 3: |
| 280 | rts r0 |
| 281 | |
| 282 | oppt: / open paper tape for reading or writing |
| 283 | mov $100,*$prs / set reader interrupt enable bit |
| 284 | tstb pptiflg / is file already open |
| 285 | bne 2f / yes, branch |
| 286 | 1: |
| 287 | mov $240,*$ps / no, set processor priority to 5 |
| 288 | jsr r0,getc; 2 / remove all entries in clist |
| 289 | br .+4 / for paper tape input and place in free list |
| 290 | br 1b |
| 291 | movb $2,pptiflg / set pptiflg to indicate file just open |
| 292 | movb $10.,toutt+1 / place 10 in paper tape input tout entry |
| 293 | br sret |
| 294 | 2: |
| 295 | jmp error / file already open |
| 296 | |
| 297 | iclose: / close file whose i-number is in r1 |
| 298 | tst r1 / test i-number |
| 299 | blt 2f / if neg., branch |
| 300 | cmp r1,$40. / is it a special file |
| 301 | bgt 3b / no, return |
| 302 | mov r1,-(sp) / yes, save r1 on stack |
| 303 | asl r1 |
| 304 | jmp *1f-2(r1) / compute jump address and transfer |
| 305 | 1: |
| 306 | ctty / tty |
| 307 | cppt / ppt |
| 308 | sret / mem |
| 309 | sret / rf0 |
| 310 | sret / rk0 |
| 311 | sret / tap0 |
| 312 | sret / tap1 |
| 313 | sret / tap2 |
| 314 | sret / tap3 |
| 315 | sret / tap4 |
| 316 | sret / tap5 |
| 317 | sret / tap6 |
| 318 | sret / tap7 |
| 319 | ccvt / tty0 |
| 320 | ccvt / tty1 |
| 321 | ccvt / tty2 |
| 322 | ccvt / tty3 |
| 323 | ccvt / tty4 |
| 324 | ccvt / tty5 |
| 325 | ccvt / tty6 |
| 326 | ccvt / tty7 |
| 327 | error / crd |
| 328 | |
| 329 | 2: / negative i-number |
| 330 | neg r1 / make it positive |
| 331 | cmp r1,$40. / is it a special file |
| 332 | bgt 3b / no. return |
| 333 | mov r1,-(sp) |
| 334 | asl r1 / yes. compute jump address and transfer |
| 335 | jmp *1f-2(r1) |
| 336 | 1: |
| 337 | ctty / tty |
| 338 | leadr / ppt |
| 339 | sret / mem |
| 340 | sret / rf0 |
| 341 | sret / rk0 |
| 342 | sret / tap0 |
| 343 | sret / tap1 |
| 344 | sret / tap2 |
| 345 | sret / tap3 |
| 346 | sret / tap4 |
| 347 | sret / tap5 |
| 348 | sret / tap6 |
| 349 | sret / tap7 |
| 350 | ccvt / tty0 |
| 351 | ccvt / tty1 |
| 352 | ccvt / tty2 |
| 353 | ccvt / tty3 |
| 354 | ccvt / tty4 |
| 355 | ccvt / tty5 |
| 356 | ccvt / tty6 |
| 357 | ccvt / tty7 |
| 358 | / ejec / lpr |
| 359 | |
| 360 | ctty: / close console tty |
| 361 | mov tty+[ntty*8]-8+6,r5 / point r5 to the console tty buffer |
| 362 | decb (r5) / dec number of processes using console tty |
| 363 | br sret / return via sret |
| 364 | |
| 365 | cppt: / close paper tape |
| 366 | clrb pptiflg / set pptiflg to indicate file not open |
| 367 | 1: |
| 368 | mov $240,*$ps /set process or priority to 5 |
| 369 | jsr r0,getc; 2 / remove all ppt input entries from clist |
| 370 | / and assign to free list |
| 371 | br sret |
| 372 | br 1b |
| 373 | |
| 374 | /ejec: |
| 375 | / mov $100,*$lps / set line printer interrupt enable bit |
| 376 | / mov $14,r1 / 'form feed' character in r1 (new page). |
| 377 | / jsr r0,lptoc / space the printer to a new page |
| 378 | / br sret / return to caller via 'sret' |
| 379 | |
| 380 | leadr: / produce paper tape leader |
| 381 | mov $100,*$pps / set paper tape punch interrupt enable |
| 382 | mov $100.,-(sp) / 101. characters of 'nul' will be output as |
| 383 | / leader |
| 384 | 1: |
| 385 | clr r1 / r1 contains a 'nul' character |
| 386 | jsr r0,pptoc / output the 'nul' character |
| 387 | dec (sp) |
| 388 | bge 1b / last leader character output? no, branch |
| 389 | tst (sp)+ / bump stack pointer |
| 390 | br sret / return to caller via 'sret' |
| 391 | |
| 392 | sysmount: / mount file system; args special; name |
| 393 | |
| 394 | jsr r0,arg2 / get arguments special and name |
| 395 | tst mnti / is the i-number of the cross device file zero? |
| 396 | bne errora / no, error |
| 397 | jsr r0,getspl / get special files device number in r1 |
| 398 | mov (sp)+,u.namep / put the name of file to be placed on the |
| 399 | / device |
| 400 | mov r1,-(sp) / save the device number |
| 401 | jsr r0,namei / get the i-number of the file |
| 402 | br errora |
| 403 | mov r1,mnti / put it in mnti |
| 404 | 1: |
| 405 | tstb sb1+1 / is 15th bit of I/O queue entry for dismountable |
| 406 | / device set? |
| 407 | bne 1b / (inhibit bit) yes, skip writing |
| 408 | mov (sp),mntd / no, put the device number in mntd |
| 409 | movb (sp),sb1 / put the device number in the lower byte of the |
| 410 | / I/O queue entry |
| 411 | mov (sp)+,cdev / put device number in cdev |
| 412 | bis $2000,sb1 / set the read bit |
| 413 | jsr r0,ppoke / read in entire file system |
| 414 | 1: |
| 415 | tstb sb1+1 / done reading? |
| 416 | bne 1b / no, wait |
| 417 | br sysreta / yes |
| 418 | |
| 419 | sysumount: / special dismount file system |
| 420 | jsr r0,arg; u.namep / point u.namep to special |
| 421 | jsr r0,getspl / get the device number in r1 |
| 422 | cmp r1,mntd / is it equal to the last device mounted? |
| 423 | bne errora / no error |
| 424 | 1: |
| 425 | tstb sb1+1 / yes, is the device still doing I/O (inhibit |
| 426 | / bit set)? |
| 427 | bne 1b / yes, wait |
| 428 | clr mntd / no, clear these |
| 429 | clr mnti |
| 430 | br sysreta / return |
| 431 | |
| 432 | getspl: / get device number from a special file name |
| 433 | jsr r0,namei / get the i-number of the special file |
| 434 | br errora / no such file |
| 435 | sub $4,r1 / i-number-4 rk=1,tap=2+n |
| 436 | ble errora / less than 0? yes, error |
| 437 | cmp r1,$9. / greater than 9 tap 7 |
| 438 | bgt errora / yes, error |
| 439 | rts r0 / return with device number in r1 |
| 440 | |
| 441 | errora: |
| 442 | jmp error / see 'error' routine |
| 443 | |
| 444 | sysreta: |
| 445 | jmp sysret / see 'sysret' routine |
| 446 | |