|
|
1.1 ! root 1: # ! 2: # fake boot ROM for MicroVAX, UQSSP/MSCP disk ! 3: # read boot block into memory, ! 4: # and call it with parameters pointing to and used by ! 5: # a device driver ! 6: # ! 7: # the MicroVAX ROM actually has horrible VMB in it. ! 8: # this code is stuck in block 0, ! 9: # with a header VMB will recognize. ! 10: # the boot block is put in block 1. ! 11: # VMB reads block 0; ! 12: # the header tells it to read block 0 (sic); ! 13: # code packaged in uvhdr.s relocates us to the ! 14: # standard ROM address, moves VMB's parameters into ! 15: # our standard places, and calls us. ! 16: # ! 17: ! 18: # ! 19: # KDA50 defs ! 20: # ! 21: .set IP,0x0 # ip register ! 22: .set SA,0x2 # sa register ! 23: ! 24: .set STEP0,10 # STEP1 == bit 11 ! 25: ! 26: .set BPOWN,31 # bit 31 == port owns descriptor ! 27: .set RTOC,4 ! 28: ! 29: # ! 30: # mscp defs ! 31: # packet offsets have 4 added to account for UQSSP header (mostly length) ! 32: # ! 33: ! 34: .set m_crf,4 # command ref number ! 35: .set m_unit,8 # disk unit number ! 36: .set m_opcd,12 # opcode ! 37: .set m_sts,14 # status (word) ! 38: .set RPKSIZE,16 # as much as we want on rcv ! 39: .set m_bcnt,16 # byte count ! 40: .set SOSIZE,20 # as much as we send for ONLINE ! 41: .set m_buff,20 # buffer address ! 42: .set m_lbn,32 # block number ! 43: .set SRSIZE,36 # as much as we send to read ! 44: .set SOSIZE,36 # as much as we send for ONLINE ! 45: ! 46: .set OPONL,011 # unit online ! 47: .set OPRD,041 # read block ! 48: ! 49: # ! 50: # MicroVAX Q-bus defs ! 51: # ! 52: .set LMEAE,040 # bit to allow DMA from Q-bus ! 53: .set ICR,0x20001f40 # where to set it ! 54: ! 55: # ! 56: # boot ROM conventions ! 57: # ! 58: .set WMEM,0x200 # sp == some working memory + WMEM ! 59: # usually working memory == 0 ! 60: .set BSIZE,512 # size of a block ! 61: .set BBLOCK,1 # boot LBN ! 62: ! 63: ourstack: ! 64: # ! 65: # here to start off, at 0xfa02 ! 66: # registers: ! 67: # r2 device register address ! 68: # r3 unit number ! 69: # r5 boot flags; ignored but preserved ! 70: # sp working memory + WMEM ! 71: # ! 72: # registers to save: r0 r1 r3 r5 r10 r11 ap sp ! 73: # ! 74: rombegin: ! 75: movl sp,savesp ! 76: movab ourstack,sp ! 77: ! 78: # ! 79: # init the KDA50 ! 80: # ! 81: ! 82: bisw2 $LMEAE,*$ICR # enable dma ! 83: clrw IP(r2) # reset: kick into startup ! 84: 0: movw SA(r2),r7 ! 85: blss oops ! 86: bbc $STEP0+1,r7,0b # wait for step1 ! 87: movw $0x8000,SA(r2) # no vector, ring size (2^0,2^0) ! 88: 0: movw SA(r2),r7 ! 89: blss oops ! 90: bbc $STEP0+2,r7,0b # wait for step2 ! 91: movab rsp,r6 # ring address ! 92: movw r6,SA(r2) ! 93: 0: movw SA(r2),r7 ! 94: blss oops ! 95: bbc $STEP0+3,r7,0b # wait for step3 ! 96: ashl $-16,r6,r6 ! 97: movw r6,SA(r2) ! 98: 0: movw SA(r2),r7 ! 99: blss oops ! 100: bbc $STEP0+4,r7,0b # wait for step4 ! 101: movw $1,SA(r2) # GO ! 102: ! 103: # ! 104: # read boot block into bottom of memory ! 105: # ! 106: ! 107: pushl r0 # rblk eats it ! 108: movab rblk,r6 # set up device driver address ! 109: subl3 $WMEM,savesp,-(sp) # physical addr ! 110: # trick: we know driver doesn't use r5, so we needn't save boot flags ! 111: movl $BBLOCK,r8 ! 112: jsb (r6) ! 113: blbc r0,oops ! 114: tstl (sp)+ ! 115: movl (sp)+,r0 ! 116: # ! 117: # start boot block ! 118: # registers now: ! 119: # r0 device type (unchanged) ! 120: # r1 BI node number (unchanged) ! 121: # r2 device register addr ! 122: # r3 device unit number (unchanged) ! 123: # r5 boot flags (unchanged) ! 124: # r6 address of our device driver ! 125: # sp `working memory + 0x200' (unchanged) ! 126: # ! 127: movl savesp,sp ! 128: jmp 0xc-WMEM(sp) ! 129: ! 130: # ! 131: # here when something is broken ! 132: # ! 133: oops: halt ! 134: ! 135: # ! 136: # device driver; called above and by boot block and friends ! 137: # ! 138: # r2 device registers ! 139: # r3 device unit number ! 140: # r5 buffer address, relative to `working memory' (ignored) ! 141: # 4(sp) physical buffer address; we use that ! 142: # r8 block number ! 143: # ! 144: # do not destroy r1-r6 r10 r11 ap ! 145: # on return, low bit of r0 set if we read it, clear if we failed ! 146: # ! 147: ! 148: rblk: ! 149: movq r10,-(sp) ! 150: clrl r0 # assume failure ! 151: movab cp,r10 ! 152: movab rp,r11 ! 153: movab rsp,r9 ! 154: movzbl $OPRD,m_opcd(r10) # make READ packet ! 155: movl 4+8(sp),m_buff(r10) # unmapped address ! 156: movzwl $BSIZE,m_bcnt(r10) ! 157: movl r8,m_lbn(r10) ! 158: movzbl $SRSIZE,(r10) ! 159: bsbb sendrcv ! 160: beql rdone ! 161: movl r3,m_unit(r10) # didn't work; make ONLINE packet ! 162: movzbl $OPONL,m_opcd(r10) ! 163: movzbl $SOSIZE,(r10) ! 164: clrl m_bcnt(r10) # ugh ! 165: clrl m_buff(r10) # ugh ! 166: clrl m_lbn(r10) # ugh ! 167: bsbb sendrcv ! 168: bneq rfail ! 169: movzbl $OPRD,m_opcd(r10) # and try read again ! 170: movl 4+8(sp),m_buff(r10) ! 171: movzwl $BSIZE,m_bcnt(r10) ! 172: movl r8,m_lbn(r10) ! 173: movzbl $SRSIZE,(r10) ! 174: bsbb sendrcv ! 175: bneq rfail ! 176: rdone: incl r0 # success ! 177: rfail: movq (sp)+,r10 ! 178: rsb ! 179: ! 180: sendrcv: ! 181: movzbl $RPKSIZE,(r11) ! 182: movab m_crf(r10),RTOC(r9) ! 183: movab m_crf(r11),(r9) ! 184: bbss $BPOWN,(r9),0f # make response buffer available ! 185: 0: bbss $BPOWN,RTOC(r9),0f # send the ONLINE packet ! 186: 0: movw IP(r2),r7 # kick to make it go ! 187: 0: bbs $BPOWN,(r9),0b # wait for answer ! 188: tstb m_sts(r11) # tstb: ignore `already online' flag ! 189: rsb ! 190: ! 191: # ! 192: # KDB50 communication area ! 193: # ! 194: .align 2 ! 195: savesp: .space 4 # working mem + WMEM ! 196: .space 8 # crap at the top ! 197: rsp: .space 4 # response descriptor ! 198: .space 4 # command descriptor ! 199: ! 200: # ! 201: # a pair of packets ! 202: # +4 for length ! 203: # ! 204: ! 205: cp: .space SRSIZE+4 # command packet ! 206: rp: .space RPKSIZE+4 # response packet
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.