1: MAJOR = 10. / major # from bdevsw[] 2: 3: / RM02/03/05 bootstrap 4: / 5: / 1995/05/31 - The unit number needs to go in bits 3-5 of bootdev 6: / because the partition number now goes into bits 0-2. 7: / 8: / disk boot program to load and transfer 9: / to a unix entry. 10: / for use with 1 KB byte blocks, CLSIZE is 2. 11: / NDIRIN is the number of direct inode addresses (currently 4) 12: / assembled size must be <= 512; if > 494, the 16-byte a.out header 13: / must be removed 14: 15: RM05 = 1 / 0-> RM02/03, 1-> RM05 16: 17: / options: none. all options of reading an alternate name or echoing to 18: / the keyboard had to be removed to make room for the 19: / code which understands the new directory structure on disc 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: PBSHFT = -4 / shift to divide by inodes per block 31: WC = -256.*CLSIZE / word count 32: 33: / The boot options and device are placed in the last SZFLAGS bytes 34: / at the end of core by the kernel for autobooting. 35: ENDCORE= 160000 / end of core, mem. management off 36: SZFLAGS= 6 / size of boot flags 37: BOOTOPTS= 2 / location of options, bytes below ENDCORE 38: BOOTDEV= 4 39: CHECKWORD= 6 40: 41: .. = ENDCORE-512.-SZFLAGS / save room for boot flags 42: 43: / entry is made by jsr pc,*$0 44: / so return can be rts pc 45: 46: / establish sp, copy 47: / program up to end of core. 48: 49: nop / These two lines must be present or DEC 50: br start / boot ROMs will refuse to run boot block! 51: start: 52: mov r0,unit 53: mov r1,csr 54: mov $..,sp 55: mov sp,r1 56: clr r0 57: 1: 58: mov (r0)+,(r1)+ 59: cmp r1,$end 60: blo 1b 61: jmp *$2f 62: 63: / On error, restart from here. 64: restart: 65: clr r0 66: / clear core to make things clean 67: 2: 68: clr (r0)+ 69: cmp r0,sp 70: blo 2b 71: 72: / initialize disk 73: mov csr,r1 74: mov unit,rmcs2(r1) 75: mov $preset+go,rmcs1(r1) 76: mov $fmt22,rmof(r1) 77: 78: mov $bootnm, r1 79: mov $2,r0 / ROOTINO 80: jsr pc,iget 81: clr r2 / offset 82: again: 83: jsr pc,readdir 84: beq restart / error - restart 85: mov 4(r0),r4 / dp->d_namlen 86: cmp r4,$bootlen / if (bootlen == dp->d_namlen) 87: bne again / nope, go try next entry 88: mov r0,r3 89: add $6,r3 / r3 = dp->d_name 90: mov r1,r5 / r5 = filename 91: 9: 92: cmpb (r3)+,(r5)+ 93: bne again / no match - go read next entry 94: sob r4,9b 95: mov (r0),r0 / r0 = dp->d_ino 96: jsr pc,iget / fetch boot's inode 97: br loadfile / 'boot'- go read it 98: 99: / get the inode specified in r0 100: iget: 101: add $INOFF,r0 102: mov r0,r5 103: ash $PBSHFT,r0 104: bic $!7777,r0 105: mov r0,dno 106: clr r0 107: jsr pc,rblk 108: bic $!17,r5 109: mov $INOSIZ,r0 110: mul r0,r5 111: add $buf,r5 112: mov $inod,r4 113: 1: 114: movb (r5)+,(r4)+ 115: sob r0,1b 116: rts pc 117: 118: readdir: 119: bit $BSIZE-1,r2 120: bne 1f 121: jsr pc,rmblk / read mapped block (bno) 122: br err / end of file branch 123: clr r2 / start at beginning of buf 124: 1: 125: mov $buf,r0 126: add r2,r0 / dp = buf+offset 127: add buf+2(r2),r2 / dp += dp->d_reclen 128: tst (r0) / dp->d_ino == 0? 129: beq readdir / yes - go look at next 130: rts pc / return with r0 = &dp->d_ino 131: err: 132: clr r0 / return with 133: rts pc / dp = NULL 134: 135: loadfile: 136: clr bno / start at block 0 of inode in 'inod' 137: / read file into core until 138: / a mapping error, (no disk address) 139: clr r1 140: 1: 141: jsr pc,rmblk 142: br 1f 143: mov $buf,r2 144: 2: 145: mov (r2)+,(r1)+ 146: cmp r2,$buf+BSIZE 147: blo 2b 148: br 1b 149: / relocate core around 150: / assembler header 151: 1: 152: clr r0 153: cmp (r0),$407 154: bne 2f 155: 1: 156: mov 20(r0),(r0)+ 157: cmp r0,sp 158: blo 1b 159: / enter program and 160: / restart if return 161: 2: 162: mov ENDCORE-BOOTOPTS, r4 163: mov unit,r3 164: ash $3,r3 / unit # in bits 3-5, partition # is 0 165: bis $MAJOR\<8.,r3 166: mov ENDCORE-CHECKWORD, r2 167: mov csr,r1 168: jsr pc,*$0 169: br restart 170: 171: / read a mapped block 172: / offset in file is in bno. 173: / skip if success, no skip if fail 174: / the algorithm only handles a single 175: / indirect block. that means that 176: / files longer than NDIRIN+256 blocks (260kb) cannot 177: / be loaded. 178: rmblk: 179: add $2,(sp) 180: mov bno,r0 181: cmp r0,$NDIRIN 182: blt 1f 183: mov $NDIRIN,r0 184: 1: 185: ash $2,r0 186: mov addr+2(r0),dno 187: mov addr(r0),r0 188: bne 1f 189: tst dno 190: beq 2f 191: 1: 192: jsr pc,rblk 193: mov bno,r0 194: inc bno 195: sub $NDIRIN,r0 196: blt 1f 197: ash $2,r0 198: mov buf+2(r0),dno 199: mov buf(r0),r0 200: bne rblk 201: tst dno 202: bne rblk 203: 2: 204: sub $2,(sp) 205: 1: 206: rts pc 207: 208: read = 70 209: preset = 20 210: go = 1 211: fmt22 = 10000 212: NSECT = 32. 213: .if RM05 214: NTRAK = 19. / RM05 215: .endif 216: .if RM05-1 217: NTRAK = 5. / RM02/03 218: .endif 219: 220: rmcs1 = 0 221: rmda = rmcs1+6 222: rmcs2 = rmcs1+10 223: rmds = rmcs1+12 224: rmof = rmcs1+32 225: rmca = rmcs1+34 226: 227: / rm02/3/5 disk driver. 228: / low order address in dno, 229: / high order in r0. 230: rblk: 231: mov r1,-(sp) 232: mov dno,r1 233: .if CLSIZE-1 234: ashc $CLSHFT,r0 / multiply by CLSIZE 235: .endif 236: div $NSECT*NTRAK,r0 237: mov csr,r3 238: mov r0,rmca(r3) 239: clr r0 240: div $NSECT,r0 241: swab r0 242: bis r1,r0 243: add $rmcs2,r3 244: mov unit,(r3) 245: mov r0,-(r3) 246: mov $buf,-(r3) 247: mov $WC,-(r3) 248: mov $read+go,-(r3) 249: 1: 250: tstb (r3) 251: bge 1b 252: mov (sp)+,r1 253: rts pc 254: 255: bootnm: <boot\0\0> 256: bootlen = 4 / strlen(bootnm) 257: unit: 0 258: csr: 0 259: end: 260: 261: inod = ..-512.-BSIZE / room for inod, buf, stack 262: addr = inod+ADDROFF / first address in inod 263: buf = inod+INOSIZ 264: bno = buf+BSIZE 265: dno = bno+2