1: MAJOR = 8 / major # from bdevsw[] 2: 3: / RX02 single-density bootstrap. 4: / 5: / 1995/12/02 - Now we have a boot for RX02! 6: / Based on the RK05 bootstrap. Only 8 bytes 7: / to spare, though. Should prove useful for those 8: / who have only RX02 boot ROM's and use a MSCP 9: / or RP/RM type system disk. 10: / -Tim(shoppa@altair.krl.caltech.edu) 11: / 12: / disk boot program to load and transfer 13: / to a unix entry. 14: / for use with 1 KB byte blocks, CLSIZE is 8. 15: / NDIRIN is the number of direct inode addresses (currently 4) 16: / assembled size must be <= 512; if > 494, the 16-byte a.out header 17: / must be removed 18: 19: / options: none. all options of reading an alternate name or echoing to 20: / the keyboard had to be removed to make room for the 21: / code which understands the new directory structure on disc 22: 23: / constants: 24: BSIZE = 1024. / logical block size 25: DENS = 0. / 1 for double density, 0 for single density 26: / This is the only place you should have 27: / to change to switch this bootstrap for 28: / some other density. 29: WC = 64.*[1.+DENS] / word count per floppy sector 30: BC = 2.*WC / byte count per floppy sector 31: BCSHFT = 7.+DENS / shift to multiply by BC 32: CLSIZE = BSIZE\/BC / physical floppy sectors per logical block 33: CLSHFT = 3.-DENS / shift to multiply by CLSIZE 34: CLMASK = CLSIZE-1. / mask for getting CLSHFT bits 35: 36: INOSIZ = 64. / size of inode in bytes 37: NDIRIN = 4. / number of direct inode addresses 38: ADDROFF = 12. / offset of first address in inode 39: INOPB = BSIZE\/INOSIZ / inodes per logical block 40: INOFF = 31. / inode offset = (INOPB * (SUPERB+1)) - 1 41: PBSHFT = -4 / shift to divide by inodes per block 42: 43: / The boot options and device are placed in the last SZFLAGS bytes 44: / at the end of core by the kernel for autobooting. 45: ENDCORE= 160000 / end of core, mem. management off 46: SZFLAGS= 6 / size of boot flags 47: BOOTOPTS= 2 / location of options, bytes below ENDCORE 48: BOOTDEV= 4 49: CHECKWORD= 6 50: 51: .. = ENDCORE-512.-SZFLAGS / save room for boot flags 52: 53: / entry is made by jsr pc,*$0 54: / so return can be rts pc 55: 56: / establish sp, copy 57: / program up to end of core. 58: 59: nop / These two lines must be present or DEC 60: br start / boot ROMs will refuse to run boot block! 61: start: 62: mov r0,unit 63: mov r1,csr 64: mov $..,sp 65: mov sp,r1 66: clr r0 67: 1: 68: mov (r0)+,(r1)+ 69: cmp r1,$end 70: blo 1b 71: jmp *$2f 72: 73: / On error, restart from here. 74: restart: 75: clr r0 76: / clear core to make things clean 77: 2: 78: clr (r0)+ 79: cmp r0,sp 80: blo 2b 81: 82: mov $bootnm, r1 83: mov $2,r0 / ROOTINO 84: jsr pc,iget 85: clr r2 / offset 86: again: 87: jsr pc,readdir 88: beq restart / error - restart 89: mov 4(r0),r4 / dp->d_namlen 90: cmp r4,$bootlen / if (bootlen == dp->d_namlen) 91: bne again / nope, go try next entry 92: mov r0,r3 93: add $6,r3 / r3 = dp->d_name 94: mov r1,r5 / r5 = filename 95: 9: 96: cmpb (r3)+,(r5)+ 97: bne again / no match - go read next entry 98: sob r4,9b 99: mov (r0),r0 / r0 = dp->d_ino 100: jsr pc,iget / fetch boot's inode 101: br loadfile / 'boot'- go read it 102: 103: / get the inode specified in r0 104: iget: 105: add $INOFF,r0 106: mov r0,r5 107: ash $PBSHFT,r0 108: bic $!7777,r0 109: mov r0,dno 110: clr r0 111: jsr pc,rblk 112: bic $!17,r5 113: mov $INOSIZ,r0 114: mul r0,r5 115: add $buf,r5 116: mov $inod,r4 117: 1: 118: movb (r5)+,(r4)+ 119: sob r0,1b 120: rts pc 121: 122: readdir: 123: bit $BSIZE-1,r2 124: bne 1f 125: jsr pc,rmblk / read mapped block (bno) 126: br err / end of file branch 127: clr r2 / start at beginning of buf 128: 1: 129: mov $buf,r0 130: add r2,r0 / dp = buf+offset 131: add buf+2(r2),r2 / dp += dp->d_reclen 132: tst (r0) / dp->d_ino == 0? 133: beq readdir / yes - go look at next 134: rts pc / return with r0 = &dp->d_ino 135: err: 136: clr r0 / return with 137: rts pc / dp = NULL 138: 139: loadfile: 140: clr bno / start at block 0 of inode in 'inod' 141: / read file into core until 142: / a mapping error, (no disk address) 143: clr r1 144: 1: 145: jsr pc,rmblk 146: br 1f 147: mov $buf,r2 148: 2: 149: mov (r2)+,(r1)+ 150: cmp r2,$buf+BSIZE 151: blo 2b 152: br 1b 153: / relocate core around 154: / assembler header 155: 1: 156: clr r0 157: cmp (r0),$407 158: bne 2f 159: 1: 160: mov 20(r0),(r0)+ 161: cmp r0,sp 162: blo 1b 163: / enter program and 164: / restart if return 165: 2: 166: mov ENDCORE-BOOTOPTS, r4 167: mov unit,r3 168: ash $3,r3 / unit # in bits 3-5, partition # is 0 169: bis $[MAJOR\<8.+DENS],r3 / Density bit is partition #. 170: mov ENDCORE-CHECKWORD, r2 171: mov csr,r1 172: jsr pc,*$0 173: br restart 174: 175: / read a mapped block 176: / offset in file is in bno. 177: / skip if success, no skip if fail 178: / the algorithm only handles a single 179: / indirect block. that means that 180: / files longer than NDIRIN+256 blocks (260kb) cannot 181: / be loaded. 182: rmblk: 183: add $2,(sp) 184: mov bno,r0 185: cmp r0,$NDIRIN 186: blt 1f 187: mov $NDIRIN,r0 188: 1: 189: ash $2,r0 190: mov addr+2(r0),dno 191: mov addr(r0),r0 192: bne 1f 193: tst dno 194: beq 2f 195: 1: 196: jsr pc,rblk 197: mov bno,r0 198: inc bno 199: sub $NDIRIN,r0 200: blt 1f 201: ash $2,r0 202: mov buf+2(r0),dno 203: mov buf(r0),r0 204: bne rblk 205: tst dno 206: bne rblk 207: 2: 208: sub $2,(sp) 209: 1: 210: rts pc 211: 212: dmask = DENS*0400 213: read = dmask + 7 /density, read function, and go 214: empty = dmask + 3 /density, empty function, and go 215: 216: / rx02 single and double density read block routine. 217: / low order address in dno. 218: 219: rblk: 220: mov r1,-(sp) 221: mov r2,-(sp) 222: mov r3,-(sp) 223: mov r4,-(sp) 224: mov r5,-(sp) /we need a lot of registers for interleave 225: / calculations! Can certainly be improved on! 226: mov dno,r5 /count up the CLSIZE physical sectors in here. 227: /will use lowest CLSHFT bits to look for done 228: /and to compute position in buffer 229: .if CLSIZE-1 230: ash $CLSHFT,r5 / multiply by CLSIZE 231: .endif 232: 8: mov r5,r1 233: clr r0 234: div $26.,r0 235: mov r0,r4 236: asl r1 237: cmp $26.,r1 238: bgt 1f 239: inc r1 240: 1: mov r1,r3 241: mov r4,r1 242: mul $6,r1 243: add r3,r1 244: clr r0 245: div $26.,r0 246: inc r1 /physical sector 247: inc r4 248: cmp $77.,r4 249: bgt 3f 250: clr r4 251: 3: /physical track now in r4 252: mov unit,r0 253: ash $4.,r0 254: bis $read,r0 255: mov csr,r3 256: mov r3,r2 257: mov r0,(r2)+ /now r3 is csr, r2 is db 258: 1: tstb (r3) 259: bpl 1b 260: mov r1,(r2) 261: 1: tstb (r3) 262: bpl 1b 263: mov r4,(r2) 264: 1: bit (r3),$040 265: beq 1b 266: mov $empty,(r3) 267: 1: tstb (r3) 268: bpl 1b 269: mov $WC,(r2) 270: 1: tstb (r3) 271: bpl 1b 272: mov r5,r0 273: bic $!CLMASK,r0 /lowest bits of r5 had the section of buffer 274: ash $BCSHFT,r0 275: add $buf,r0 276: mov r0,(r2) 277: 1: bit (r3),$040 278: beq 1b 279: inc r5 280: bit r5,$CLMASK 281: bne 8b 282: mov (sp)+,r5 283: mov (sp)+,r4 284: mov (sp)+,r3 285: mov (sp)+,r2 286: mov (sp)+,r1 287: rts pc 288: 289: bootnm: <boot\0\0> 290: bootlen = 4 / strlen(bootnm) 291: unit: 0 292: csr: 0 293: end: 294: 295: inod = ..-512.-BSIZE / room for inod, buf, stack 296: addr = inod+ADDROFF / first address in inod 297: buf = inod+INOSIZ 298: bno = buf+BSIZE 299: dno = bno+2