1: / RL01/02 bootstrap. 2: / 3: / disk boot program to load and transfer 4: / to a unix entry. 5: / for use with 1 KB byte blocks, CLSIZE is 2. 6: / NDIRIN is the number of direct inode addresses (currently 4) 7: / assembled size must be <= 512; if > 494, the 16-byte a.out header 8: / must be removed 9: 10: / options: 11: nohead = 1 / 0->normal, 1->this boot must have a.out 12: / header removed. Saves 10 bytes. 13: readname= 0 / 1->normal, if default not found, read name 14: / from console. 0->loop on failure, saves 36 bytes 15: prompt = 0 / 1->prompt (':') before reading from console 16: / 0-> no prompt, saves 8 bytes 17: autoboot= 1 / 1->code for autoboot. 0->no autoboot, saves 12 bytes 18: 19: / constants: 20: CLSIZE = 2. / physical disk blocks per logical block 21: CLSHFT = 1. / shift to multiply by CLSIZE 22: BSIZE = 512.*CLSIZE / logical block size 23: INOSIZ = 64. / size of inode in bytes 24: NDIRIN = 4. / number of direct inode addresses 25: ADDROFF = 12. / offset of first address in inode 26: INOPB = BSIZE\/INOSIZ / inodes per logical block 27: INOFF = 31. / inode offset = (INOPB * (SUPERB+1)) - 1 28: WC = -256.*CLSIZE / word count 29: 30: / The boot options and device are placed in the last SZFLAGS bytes 31: / at the end of core by the kernel if this is an autoboot. 32: ENDCORE= 160000 / end of core, mem. management off 33: SZFLAGS= 6 / size of boot flags 34: BOOTOPTS= 2 / location of options, bytes below ENDCORE 35: BOOTDEV= 4 36: CHECKWORD= 6 37: 38: .. = ENDCORE-512.-SZFLAGS / save room for boot flags 39: 40: / entry is made by jsr pc,*$0 41: / so return can be rts pc 42: 43: / establish sp, copy 44: / program up to end of core. 45: start: 46: mov $..,sp 47: mov sp,r1 48: clr r0 49: .if nohead-1 / if nohead == 1 50: cmp (r0),$407 51: bne 1f 52: mov $20,r0 53: .endif 54: 1: 55: mov (r0)+,(r1)+ 56: cmp r1,$end 57: blo 1b 58: jmp *$2f 59: 60: / On error, restart from here. 61: restart: 62: 63: / clear core to make things clean 64: clr r0 65: 2: 66: clr (r0)+ 67: cmp r0,sp 68: blo 2b 69: 70: / initialize rl 71: 72: / mov $13,*$rlda /get status 73: / mov $4,*$rlcs 74: / 75: / jsr pc,rdy 76: / mov *$rlda,r5 /superstision 77: / 78: 79: / at origin, read pathname 80: .if prompt 81: mov $':, r0 82: jsr pc, putc 83: .endif 84: 85: / spread out in array 'names', one 86: / component every 14 bytes. 87: mov $names,r1 88: 1: 89: mov r1,r2 90: 2: 91: jsr pc,getc 92: cmp r0,$'\n 93: beq 1f 94: cmp r0,$'/ 95: beq 3f 96: movb r0,(r2)+ 97: br 2b 98: 3: 99: cmp r1,r2 100: beq 2b 101: add $14.,r1 102: br 1b 103: 104: / now start reading the inodes 105: / starting at the root and 106: / going through directories 107: 1: 108: mov $names,r1 109: mov $2,r0 110: 1: 111: clr bno 112: jsr pc,iget 113: tst (r1) 114: beq 1f 115: 2: 116: jsr pc,rmblk 117: br restart 118: mov $buf,r2 119: 3: 120: mov r1,r3 121: mov r2,r4 122: add $16.,r2 123: tst (r4)+ 124: beq 5f 125: 4: 126: cmpb (r3)+,(r4)+ 127: bne 5f 128: cmp r4,r2 129: blo 4b 130: mov -16.(r2),r0 131: add $14.,r1 132: br 1b 133: 5: 134: cmp r2,$buf+BSIZE 135: blo 3b 136: br 2b 137: 138: / read file into core until 139: / a mapping error, (no disk address) 140: 1: 141: clr r1 142: 1: 143: jsr pc,rmblk 144: br 1f 145: mov $buf,r2 146: 2: 147: mov (r2)+,(r1)+ 148: cmp r2,$buf+BSIZE 149: blo 2b 150: br 1b 151: / relocate core around 152: / assembler header 153: 1: 154: clr r0 155: cmp (r0),$407 156: bne 2f 157: 1: 158: mov 20(r0),(r0)+ 159: cmp r0,sp 160: blo 1b 161: / enter program and 162: / restart if return 163: 2: 164: .if autoboot 165: mov ENDCORE-BOOTOPTS, r4 166: mov ENDCORE-BOOTDEV, r3 167: mov ENDCORE-CHECKWORD, r2 168: .endif 169: jsr pc,*$0 170: br restart 171: 172: / get the inode specified in r0 173: iget: 174: add $INOFF,r0 175: mov r0,r5 176: ash $-4.,r0 177: bic $!7777,r0 178: mov r0,dno 179: clr r0 180: jsr pc,rblk 181: bic $!17,r5 182: mul $INOSIZ,r5 183: add $buf,r5 184: mov $inod,r4 185: 1: 186: mov (r5)+,(r4)+ 187: cmp r4,$inod+INOSIZ 188: blo 1b 189: rts pc 190: 191: / read a mapped block 192: / offset in file is in bno. 193: / skip if success, no skip if fail 194: / the algorithm only handles a single 195: / indirect block. that means that 196: / files longer than NDIRIN+128 blocks cannot 197: / be loaded. 198: rmblk: 199: add $2,(sp) 200: mov bno,r0 201: cmp r0,$NDIRIN 202: blt 1f 203: mov $NDIRIN,r0 204: 1: 205: mov r0,-(sp) 206: asl r0 207: add (sp)+,r0 208: add $addr+1,r0 209: movb (r0)+,dno 210: movb (r0)+,dno+1 211: movb -3(r0),r0 212: bne 1f 213: tst dno 214: beq 2f 215: 1: 216: jsr pc,rblk 217: mov bno,r0 218: inc bno 219: sub $NDIRIN,r0 220: blt 1f 221: ash $2,r0 222: mov buf+2(r0),dno 223: mov buf(r0),r0 224: bne rblk 225: tst dno 226: bne rblk 227: 2: 228: sub $2,(sp) 229: 1: 230: rts pc 231: 232: / 233: / RL02 read only non-interrupt driven driver 234: / Dave Clemans, TEK, 4/8/82 235: / 236: / NOTE: 237: / errors are NOT checked 238: / spiral reads are NOT implemented 239: / it MUST run in the lower 64K address space 240: / 241: / Parameters: 242: / r0: high part of disk block number 243: / dno: low part of disk block number 244: / WC: amount of data to read 245: / buf: buffer to read data into 246: / 247: / Register usage: 248: / r1,r2,r3: used, but saved 249: / r0,r4 used and clobbered 250: rlcs = 174400 251: rlba = 174402 252: rlda = 174404 253: rlmp = 174406 254: 255: READ = 14 256: SEEK = 6 257: RDHDR = 10 258: SEEKHI = 5 259: SEEKLO = 1 260: CRDY = 200 261: RLSECT = 20. 262: 263: rblk: 264: mov r1,-(sp) 265: mov r2,-(sp) 266: mov r3,-(sp) 267: mov $rlcs,r4 / point to controller 268: mov dno,r1 269: .if CLSIZE-1 270: ashc $CLSHFT,r0 / multiply by CLSIZE 271: .endif 272: div $RLSECT,r0 / cylinder number - surface 273: asl r1 / sector number 274: mov $RDHDR,(r4) / find where the heads are now 275: 7: bit $CRDY,(r4) / wait for the STUPID!!! controller 276: beq 7b 277: mov *$rlmp,r2 278: ash $-7,r2 279: bic $!777,r2 / we are at this cylinder now 280: mov r0,r3 281: asr r3 / desired cylinder number 282: sub r3,r2 / compute relative seek distance 283: bge 1f / up or down? 284: neg r2 285: ash $7,r2 286: bis $SEEKHI,r2 / up 287: br 2f 288: 1: ash $7,r2 289: bis $SEEKLO,r2 / down 290: 2: mov r0,r3 / compute desired disk surface 291: bic $!1,r3 292: ash $4,r3 293: bis r3,r2 294: mov r2,*$rlda / disk address for seek 295: mov $SEEK,(r4) / do the seek 296: 7: bit $CRDY,(r4) / wait for the STUPID!!! controller 297: beq 7b 298: ash $6,r0 / compute disk address for read 299: bis r1,r0 300: add $6,r4 / point to rlmp 301: mov $WC,(r4) / word count for read 302: mov r0,-(r4) / disk address for read 303: mov $buf,-(r4) / buffer address for read 304: mov $READ,-(r4) / do the read 305: 7: bit $CRDY,(r4) / wait for the STUPID!!! controller 306: beq 7b 307: mov (sp)+,r3 308: mov (sp)+,r2 309: mov (sp)+,r1 310: rts pc 311: 312: tks = 177560 313: tkb = 177562 314: / read and echo a teletype character 315: / if *cp is nonzero, it is the next char to simulate typing 316: / after the defnm is tried once, read a name from the console 317: getc: 318: movb *cp, r0 319: beq 2f 320: inc cp 321: .if readname 322: br putc 323: 2: 324: mov $tks,r0 325: inc (r0) 326: 1: 327: tstb (r0) 328: bge 1b 329: mov tkb,r0 330: bic $!177,r0 331: cmp r0,$'A 332: blo 2f 333: cmp r0,$'Z 334: bhi 2f 335: add $'a-'A,r0 336: .endif 337: 2: 338: 339: tps = 177564 340: tpb = 177566 341: / print a teletype character 342: putc: 343: tstb *$tps 344: bge putc 345: mov r0,*$tpb 346: cmp r0,$'\r 347: bne 1f 348: mov $'\n,r0 349: br putc 350: 1: 351: rts pc 352: 353: cp: defnm 354: defnm: <boot\r\0> 355: end: 356: 357: inod = ..-512.-BSIZE / room for inod, buf, stack 358: addr = inod+ADDROFF / first address in inod 359: buf = inod+INOSIZ 360: bno = buf+BSIZE 361: dno = bno+2 362: names = dno+2