1: / RP03 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: cyl = 0. / cylinder offset of filesys to read from 11: 12: / options: 13: nohead = 0 / 0->normal, 1->this boot must have a.out 14: / header removed. Saves 10 bytes. 15: readname= 1 / 1->normal, if default not found, read name 16: / from console. 0->loop on failure, saves 36 bytes 17: prompt = 1 / 1->prompt ('>') before reading from console 18: / 0-> no prompt, saves 8 bytes 19: autoboot= 1 / 1->code for autoboot. 0->no autoboot, saves 12 bytes 20: 21: / constants: 22: CLSIZE = 2. / physical disk blocks per logical block 23: CLSHFT = 1. / shift to multiply by CLSIZE 24: BSIZE = 512.*CLSIZE / logical block size 25: INOSIZ = 64. / size of inode in bytes 26: NDIRIN = 4. / number of direct inode addresses 27: ADDROFF = 12. / offset of first address in inode 28: INOPB = BSIZE\/INOSIZ / inodes per logical block 29: INOFF = 31. / inode offset = (INOPB * (SUPERB+1)) - 1 30: WC = -256.*CLSIZE / word count 31: 32: / The boot options and device are placed in the last SZFLAGS bytes 33: / at the end of core by the kernel if this is an autoboot. 34: ENDCORE= 160000 / end of core, mem. management off 35: SZFLAGS= 6 / size of boot flags 36: BOOTOPTS= 2 / location of options, bytes below ENDCORE 37: BOOTDEV= 4 38: CHECKWORD= 6 39: 40: .. = ENDCORE-512.-SZFLAGS / save room for boot flags 41: 42: / entry is made by jsr pc,*$0 43: / so return can be rts pc 44: 45: / establish sp, copy 46: / program up to end of core. 47: start: 48: mov $..,sp 49: mov sp,r1 50: clr r0 51: .if nohead-1 / if nohead == 1 52: cmp (r0),$407 53: bne 1f 54: mov $20,r0 55: .endif 56: 1: 57: mov (r0)+,(r1)+ 58: cmp r1,$end 59: blo 1b 60: jmp *$2f 61: 62: / On error, restart from here. 63: restart: 64: 65: / clear core to make things clean 66: clr r0 67: 2: 68: clr (r0)+ 69: cmp r0,sp 70: blo 2b 71: 72: / initialize rp 73: clr *$rpcs / selects drive zero 74: 75: / at origin, read pathname 76: .if prompt 77: mov $'>, r0 78: jsr pc, putc 79: .endif 80: 81: / spread out in array 'names', one 82: / component every 14 bytes. 83: mov $names,r1 84: 1: 85: mov r1,r2 86: 2: 87: jsr pc,getc 88: cmp r0,$'\n 89: beq 1f 90: cmp r0,$'/ 91: beq 3f 92: movb r0,(r2)+ 93: br 2b 94: 3: 95: cmp r1,r2 96: beq 2b 97: add $14.,r1 98: br 1b 99: 100: / now start reading the inodes 101: / starting at the root and 102: / going through directories 103: 1: 104: mov $names,r1 105: mov $2,r0 106: 1: 107: clr bno 108: jsr pc,iget 109: tst (r1) 110: beq 1f 111: 2: 112: jsr pc,rmblk 113: br restart 114: mov $buf,r2 115: 3: 116: mov r1,r3 117: mov r2,r4 118: add $16.,r2 119: tst (r4)+ 120: beq 5f 121: 4: 122: cmpb (r3)+,(r4)+ 123: bne 5f 124: cmp r4,r2 125: blo 4b 126: mov -16.(r2),r0 127: add $14.,r1 128: br 1b 129: 5: 130: cmp r2,$buf+BSIZE 131: blo 3b 132: br 2b 133: 134: / read file into core until 135: / a mapping error, (no disk address) 136: 1: 137: clr r1 138: 1: 139: jsr pc,rmblk 140: br 1f 141: mov $buf,r2 142: 2: 143: mov (r2)+,(r1)+ 144: cmp r2,$buf+BSIZE 145: blo 2b 146: br 1b 147: / relocate core around 148: / assembler header 149: 1: 150: clr r0 151: cmp (r0),$407 152: bne 2f 153: 1: 154: mov 20(r0),(r0)+ 155: cmp r0,sp 156: blo 1b 157: / enter program and 158: / restart if return 159: 2: 160: .if autoboot 161: mov ENDCORE-BOOTOPTS, r4 162: mov ENDCORE-BOOTDEV, r3 163: mov ENDCORE-CHECKWORD, r2 164: .endif 165: jsr pc,*$0 166: br restart 167: 168: / get the inode specified in r0 169: iget: 170: add $INOFF,r0 171: mov r0,r5 172: ash $-4.,r0 173: bic $!7777,r0 174: mov r0,dno 175: clr r0 176: jsr pc,rblk 177: bic $!17,r5 178: mul $INOSIZ,r5 179: add $buf,r5 180: mov $inod,r4 181: 1: 182: mov (r5)+,(r4)+ 183: cmp r4,$inod+INOSIZ 184: blo 1b 185: rts pc 186: 187: / read a mapped block 188: / offset in file is in bno. 189: / skip if success, no skip if fail 190: / the algorithm only handles a single 191: / indirect block. that means that 192: / files longer than NDIRIN+128 blocks cannot 193: / be loaded. 194: rmblk: 195: add $2,(sp) 196: mov bno,r0 197: cmp r0,$NDIRIN 198: blt 1f 199: mov $NDIRIN,r0 200: 1: 201: mov r0,-(sp) 202: asl r0 203: add (sp)+,r0 204: add $addr+1,r0 205: movb (r0)+,dno 206: movb (r0)+,dno+1 207: movb -3(r0),r0 208: bne 1f 209: tst dno 210: beq 2f 211: 1: 212: jsr pc,rblk 213: mov bno,r0 214: inc bno 215: sub $NDIRIN,r0 216: blt 1f 217: ash $2,r0 218: mov buf+2(r0),dno 219: mov buf(r0),r0 220: bne rblk 221: tst dno 222: bne rblk 223: 2: 224: sub $2,(sp) 225: 1: 226: rts pc 227: 228: read = 4 229: go = 1 230: 231: rpcs = 176710 232: rpda = 176724 233: rpca = 176722 234: rpba = 176720 235: / rp03 disk driver. 236: / low order address in dno, 237: / high order in r0. 238: rblk: 239: mov r1,-(sp) 240: mov dno,r1 241: .if CLSIZE-1 242: ashc $CLSHFT,r0 / multiply by CLSIZE 243: .endif 244: div $20.*10.,r0 245: .if cyl 246: add $cyl,r0 247: .endif 248: mov r0,*$rpca 249: clr r0 250: div $10.,r0 251: swab r0 252: bis r1,r0 253: mov r0,*$rpda 254: mov $rpba,r1 255: mov $buf,(r1) 256: mov $WC,-(r1) 257: mov $read+go,-(r1) 258: 1: 259: tstb (r1) 260: bge 1b 261: mov (sp)+,r1 262: rts pc 263: 264: tks = 177560 265: tkb = 177562 266: / read and echo a teletype character 267: / if *cp is nonzero, it is the next char to simulate typing 268: / after the defnm is tried once, read a name from the console 269: getc: 270: movb *cp, r0 271: beq 2f 272: inc cp 273: .if readname 274: br putc 275: 2: 276: mov $tks,r0 277: inc (r0) 278: 1: 279: tstb (r0) 280: bge 1b 281: mov tkb,r0 282: bic $!177,r0 283: cmp r0,$'A 284: blo 2f 285: cmp r0,$'Z 286: bhi 2f 287: add $'a-'A,r0 288: .endif 289: 2: 290: 291: tps = 177564 292: tpb = 177566 293: / print a teletype character 294: putc: 295: tstb *$tps 296: bge putc 297: mov r0,*$tpb 298: cmp r0,$'\r 299: bne 1f 300: mov $'\n,r0 301: br putc 302: 1: 303: rts pc 304: 305: cp: defnm 306: defnm: <boot\r\0> 307: end: 308: 309: inod = ..-512.-BSIZE / room for inod, buf, stack 310: addr = inod+ADDROFF / first address in inod 311: buf = inod+INOSIZ 312: bno = buf+BSIZE 313: dno = bno+2 314: names = dno+2