1: MAJOR = 7 / major # from bdevsw[] 2: 3: / RL01/02 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: / options: none. all options of reading an alternate name or echoing to 16: / the keyboard had to be removed to make room for the 17: / code which understands the new directory structure on disc 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: PBSHFT = -4 / shift to divide by inodes per block 29: WC = -256.*CLSIZE / word count 30: 31: / The boot options and device are placed in the last SZFLAGS bytes 32: / at the end of core by the kernel for autobooting. 33: ENDCORE= 160000 / end of core, mem. management off 34: SZFLAGS= 6 / size of boot flags 35: BOOTOPTS= 2 / location of options, bytes below ENDCORE 36: BOOTDEV= 4 37: CHECKWORD= 6 38: 39: .. = ENDCORE-512.-SZFLAGS / save room for boot flags 40: 41: / entry is made by jsr pc,*$0 42: / so return can be rts pc 43: 44: nop / These two lines must be present or DEC MXV-11 45: br start / boot ROMs will refuse to run boot block! 46: 47: / establish sp, copy 48: / program up to end of core. 49: start: 50: movb r0,unit+1 / unit # in high byte 51: mov r1,csr 52: mov $..,sp 53: mov sp,r1 54: clr r0 55: 1: 56: mov (r0)+,(r1)+ 57: cmp r1,$end 58: blo 1b 59: jmp *$2f 60: 61: / On error, restart from here. 62: restart: 63: clr r0 64: / clear core to make things clean 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: mov $bootnm, r1 80: mov $2,r0 / ROOTINO 81: jsr pc,iget 82: clr r2 / offset 83: again: 84: jsr pc,readdir 85: beq restart / error - restart 86: mov 4(r0),r4 / dp->d_namlen 87: cmp r4,$bootlen / if (bootlen == dp->d_namlen) 88: bne again / nope, go try next entry 89: mov r0,r3 90: add $6,r3 / r3 = dp->d_name 91: mov r1,r5 / r5 = filename 92: 9: 93: cmpb (r3)+,(r5)+ 94: bne again / no match - go read next entry 95: sob r4,9b 96: mov (r0),r0 / r0 = dp->d_ino 97: jsr pc,iget / fetch boot's inode 98: br loadfile / 'boot'- go read it 99: 100: / get the inode specified in r0 101: iget: 102: add $INOFF,r0 103: mov r0,r5 104: ash $PBSHFT,r0 105: bic $!7777,r0 106: mov r0,dno 107: clr r0 108: jsr pc,rblk 109: bic $!17,r5 110: mov $INOSIZ,r0 111: mul r0,r5 112: add $buf,r5 113: mov $inod,r4 114: 1: 115: movb (r5)+,(r4)+ 116: sob r0,1b 117: rts pc 118: 119: readdir: 120: bit $BSIZE-1,r2 121: bne 1f 122: jsr pc,rmblk / read mapped block (bno) 123: br err / end of file branch 124: clr r2 / start at beginning of buf 125: 1: 126: mov $buf,r0 127: add r2,r0 / dp = buf+offset 128: add buf+2(r2),r2 / dp += dp->d_reclen 129: tst (r0) / dp->d_ino == 0? 130: beq readdir / yes - go look at next 131: rts pc / return with r0 = &dp->d_ino 132: err: 133: clr r0 / return with 134: rts pc / dp = NULL 135: 136: loadfile: 137: clr bno / start at block 0 of inode in 'inod' 138: / read file into core until 139: / a mapping error, (no disk address) 140: clr r1 141: 1: 142: jsr pc,rmblk 143: br 1f 144: mov $buf,r2 145: 2: 146: mov (r2)+,(r1)+ 147: cmp r2,$buf+BSIZE 148: blo 2b 149: br 1b 150: / relocate core around 151: / assembler header 152: 1: 153: clr r0 154: cmp (r0),$407 155: bne 2f 156: 1: 157: mov 20(r0),(r0)+ 158: cmp r0,sp 159: blo 1b 160: / enter program and 161: / restart if return 162: 2: 163: mov ENDCORE-BOOTOPTS, r4 164: movb unit+1,r3 165: ash $3,r3 / unit # in bits 3-5, partition # is 0 166: bis $MAJOR\<8.,r3 167: mov ENDCORE-CHECKWORD, r2 168: mov csr,r1 169: jsr pc,*$0 170: br restart 171: 172: / read a mapped block 173: / offset in file is in bno. 174: / skip if success, no skip if fail 175: / the algorithm only handles a single 176: / indirect block. that means that 177: / files longer than NDIRIN+256 blocks (260kb) cannot 178: / be loaded. 179: rmblk: 180: add $2,(sp) 181: mov bno,r0 182: cmp r0,$NDIRIN 183: blt 1f 184: mov $NDIRIN,r0 185: 1: 186: ash $2,r0 187: mov addr+2(r0),dno 188: mov addr(r0),r0 189: bne 1f 190: tst dno 191: beq 2f 192: 1: 193: jsr pc,rblk 194: mov bno,r0 195: inc bno 196: sub $NDIRIN,r0 197: blt 1f 198: ash $2,r0 199: mov buf+2(r0),dno 200: mov buf(r0),r0 201: bne rblk 202: tst dno 203: bne rblk 204: 2: 205: sub $2,(sp) 206: 1: 207: rts pc 208: 209: / 210: / RL02 read only non-interrupt driven driver 211: / Dave Clemans, TEK, 4/8/82 212: / 213: / NOTE: 214: / errors are NOT checked 215: / spiral reads are NOT implemented 216: / it MUST run in the lower 64K address space 217: / 218: / Parameters: 219: / r0: high part of disk block number 220: / dno: low part of disk block number 221: / WC: amount of data to read 222: / buf: buffer to read data into 223: / 224: / Register usage: 225: / r1,r2: used, but saved 226: / r0,r3,r4 used and clobbered 227: rlcs = 0 / offset from base csr 228: rlba = 2 229: rlda = 4 230: rlmp = 6 231: 232: READ = 14 233: SEEK = 6 234: RDHDR = 10 235: SEEKHI = 5 236: SEEKLO = 1 237: CRDY = 200 238: RLSECT = 20. 239: 240: rblk: 241: mov r1,-(sp) 242: mov r2,-(sp) 243: mov csr,r4 244: mov dno,r1 245: .if CLSIZE-1 246: ashc $CLSHFT,r0 / multiply by CLSIZE 247: .endif 248: div $RLSECT,r0 / cylinder number - surface 249: asl r1 / sector number 250: mov unit,-(sp) 251: bis $RDHDR,(sp) 252: mov (sp)+,(r4) / find where the heads are now 253: 7: tstb (r4) / wait for the STUPID!!! controller (CRDY=200) 254: bpl 7b 255: mov rlmp(r4),r2 256: ash $-7,r2 257: bic $!777,r2 / we are at this cylinder now 258: mov r0,r3 259: asr r3 / desired cylinder number 260: sub r3,r2 / compute relative seek distance 261: bge 1f / up or down? 262: neg r2 263: ash $7,r2 264: bis $SEEKHI,r2 / up 265: br 2f 266: 1: ash $7,r2 267: inc r2 / down (SEEKLO = 1, so just do 'inc') 268: 2: mov r0,r3 / compute desired disk surface 269: bic $!1,r3 270: ash $4,r3 271: bis r3,r2 272: mov r2,rlda(r4) / disk address for seek 273: mov unit,-(sp) 274: bis $SEEK,(sp) 275: mov (sp)+,(r4) / do the seek 276: 7: tstb (r4) / wait for the STUPID!!! controller 277: bpl 7b 278: ash $6,r0 / compute disk address for read 279: bis r1,r0 280: add $rlmp,r4 / point to rlmp 281: mov $WC,(r4) / word count for read 282: mov r0,-(r4) / disk address for read 283: mov $buf,-(r4) / buffer address for read 284: mov unit,-(sp) 285: bis $READ,(sp) 286: mov (sp)+,-(r4) / do the read 287: 7: tstb (r4) / wait for the STUPID!!! controller 288: bpl 7b 289: mov (sp)+,r2 290: mov (sp)+,r1 291: rts pc 292: 293: bootnm: <boot\0\0> 294: bootlen = 4 / strlen(bootnm) 295: unit: 0 296: csr: 0 297: end: 298: 299: inod = ..-512.-BSIZE / room for inod, buf, stack 300: addr = inod+ADDROFF / first address in inod 301: buf = inod+INOSIZ 302: bno = buf+BSIZE 303: dno = bno+2