1: MAJOR = 9. / major # from bdevsw[] 2: 3: / CDC 9766 disk on SI 9500 Controller 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: shared = 1 / 9500 shared computer option support 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 $reset,sicnr(r1) 75: 76: mov $bootnm, r1 77: mov $2,r0 / ROOTINO 78: jsr pc,iget 79: clr r2 / offset 80: again: 81: jsr pc,readdir 82: beq restart / error - restart 83: mov 4(r0),r4 / dp->d_namlen 84: cmp r4,$bootlen / if (bootlen == dp->d_namlen) 85: bne again / nope, go try next entry 86: mov r0,r3 87: add $6,r3 / r3 = dp->d_name 88: mov r1,r5 / r5 = filename 89: 9: 90: cmpb (r3)+,(r5)+ 91: bne again / no match - go read next entry 92: sob r4,9b 93: mov (r0),r0 / r0 = dp->d_ino 94: jsr pc,iget / fetch boot's inode 95: br loadfile / 'boot'- go read it 96: 97: / get the inode specified in r0 98: iget: 99: add $INOFF,r0 100: mov r0,r5 101: ash $PBSHFT,r0 102: bic $!7777,r0 103: mov r0,dno 104: clr r0 105: jsr pc,rblk 106: bic $!17,r5 107: mov $INOSIZ,r0 108: mul r0,r5 109: add $buf,r5 110: mov $inod,r4 111: 1: 112: movb (r5)+,(r4)+ 113: sob r0,1b 114: rts pc 115: 116: readdir: 117: bit $BSIZE-1,r2 118: bne 1f 119: jsr pc,rmblk / read mapped block (bno) 120: br err / end of file branch 121: clr r2 / start at beginning of buf 122: 1: 123: mov $buf,r0 124: add r2,r0 / dp = buf+offset 125: add buf+2(r2),r2 / dp += dp->d_reclen 126: tst (r0) / dp->d_ino == 0? 127: beq readdir / yes - go look at next 128: rts pc / return with r0 = &dp->d_ino 129: err: 130: clr r0 / return with 131: rts pc / dp = NULL 132: 133: loadfile: 134: clr bno / start at block 0 of inode in 'inod' 135: / read file into core until 136: / a mapping error, (no disk address) 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: mov ENDCORE-BOOTOPTS, r4 161: mov unit,r3 162: ash $3,r3 / unit # in bits 3-5, partition # is 0 163: bis $MAJOR\<8.,r3 164: mov ENDCORE-CHECKWORD, r2 165: mov csr,r1 166: jsr pc,*$0 167: br restart 168: 169: / read a mapped block 170: / offset in file is in bno. 171: / skip if success, no skip if fail 172: / the algorithm only handles a single 173: / indirect block. that means that 174: / files longer than NDIRIN+256 blocks (260kb) cannot 175: / be loaded. 176: rmblk: 177: add $2,(sp) 178: mov bno,r0 179: cmp r0,$NDIRIN 180: blt 1f 181: mov $NDIRIN,r0 182: 1: 183: ash $2,r0 184: mov addr+2(r0),dno 185: mov addr(r0),r0 186: bne 1f 187: tst dno 188: beq 2f 189: 1: 190: jsr pc,rblk 191: mov bno,r0 192: inc bno 193: sub $NDIRIN,r0 194: blt 1f 195: ash $2,r0 196: mov buf+2(r0),dno 197: mov buf(r0),r0 198: bne rblk 199: tst dno 200: bne rblk 201: 2: 202: sub $2,(sp) 203: 1: 204: rts pc 205: 206: read = 4 207: reset = 0 208: go = 1 209: NSECT = 32. 210: NTRAK = 19. / 9766 211: 212: sicnr = 0 213: siwcr = sicnr+2 214: sipcr = sicnr+4 215: sihsr = sicnr+6 216: simar = sicnr+10 217: sierr = sicnr+12 218: siscr = sicnr+24 219: 220: / si 9500/9766 disk driver. 221: / low order address in dno, 222: / high order in r0. 223: rblk: 224: mov r1,-(sp) 225: mov dno,r1 226: .if CLSIZE-1 227: ashc $CLSHFT,r0 / multiply by CLSIZE 228: .endif 229: div $NSECT*NTRAK,r0 230: mov csr,r3 231: .if shared 232: mov r0,-(sp) / push onto stack 233: mov siscr(r3),r0 / load shared computer register 234: bit $200,r0 / see if grant bit set 235: bne 1f / if so, is dual ported 236: mov sierr(r3),r0 / move error register to r0 237: bic $037777,r0 / clear all but top two bits 238: cmp $140000,r0 / see if contention error 239: bne 2f / if not, not dual ported 240: 1: 241: bit $200,siscr(r3) / test for grant 242: bne 2f / if set, go do command 243: clr sicnr(r3) / issue logic master clear 244: mov $1,siscr(r3) / request grant 245: br 1b / loop until grant 246: 2: 247: mov (sp)+,r0 / pop off stack 248: .endif 249: mov r0,sipcr(r3) / port and cylinder 250: mov unit,r0 251: ash $10.,r0 252: add r0,sipcr(r3) / add in unit number 253: clr r0 254: div $NSECT,r0 255: ash $5.,r0 256: bis r0,r1 257: mov r1,sihsr(r3) / head and sector 258: mov $buf,simar(r3) / buffer address 259: mov $WC,siwcr(r3) / word count 260: mov $read+go,sicnr(r3) / read it 261: 1: 262: tstb sicnr(r3) 263: bge 1b 264: mov (sp)+,r1 265: rts pc 266: 267: bootnm: <boot\0\0> 268: bootlen = 4 / strlen(bootnm) 269: unit: 0 270: csr: 0 271: end: 272: 273: inod = ..-512.-BSIZE / room for inod, buf, stack 274: addr = inod+ADDROFF / first address in inod 275: buf = inod+INOSIZ 276: bno = buf+BSIZE 277: dno = bno+2