;+ ; ; A9 boot PROM for MSCP disks. ; ; By John Wilson . ; This program is hereby placed in the public domain. ; ; 10/20/2000 JMBW Created. ; ;- du$csr= 172150 ;base UDA50 (etc.) CSR ; duip= 0 ;(772150) initialization, polling dusa= 2 ;(772152) status/addr, purge ; .asect .=0 p.crf: .blkw 2 ;(00) command reference number p.unit: .blkw ;(04) unit number .blkw ;(06) (reserved) p.opcd: .blkb ;(10) opcode p.flgs: .blkb ;(11) end message flags (reserved in cmd msg) p.mod: ;(12) modifiers p.sts: .blkw ;(12) status (in end msgs) p.bcnt: .blkw ;(14) byte count (or record/object count) p.unfl: .blkw ;(16) unit flags p.tcnt: ;(20) tape mark count p.buff: .blkw 6 ;(20) buffer descriptor p.medi: ;(34) medium ID, 4 bytes p.lbn: .blkw 2 ;(34) logical block number ; op.scc= 004 ;set controller characteristics op.onl= 011 ;online op.rd= 041 ;read data ; stack= 2000 ;stack ends here dupack= 2000+4 ;address of cmd/response packet, allow for pfx during= 3000+4 ;response ring, allowing space for int flags ; ; Macro to check an assumption about constants: ; .macro .assume a,cond,b .if cond - .iff .err ; assumption a cond b is false .endc .endm ; ; ROM header ; .asect .= 0 name: .word 'D*400!'U ;DU, backwards .word 200-. ;offset to next PROM nodiag: ; no-diags DU0: entry is at +4 br du0 ;skip diags diag: ; diag DU0: entry is at +6 ;;; diags like what? du0: clr r0 ;no console emulator, always use unit #0 .= 10 ;(already there) go: ; +10 -- unit # in R0 br go1 ; +12 -- unit # in R0 ;;; supposed diags here too? no space anyway go1: mov #du$csr,r1 ;R1 points at base CSR mov pc,r4 ;must point 20 bytes past signature .assume . eq 20 ; go through 4-step init process clr (r1)+ ;write IP, start init process .assume duip eq 0 mov #4000,r2 ;step 1 flag mov #stack,sp ;set up stack jsr r5,10$ ;R5 pts at next word (PIC) ;(wastes a word on our short-lived stack) ; table of 4 values written in on each step .word 100000 ;STEP bit, no interrupts, rings=1 entry each .word during ;LSW of ring pointer base .word 0 ;MSW=0 .word 1 ;burst=default, last fail=no, go 10$: ; wait for next step bit r2,(r1) ;is our step on yet? .assume dusa eq duip+2 beq 10$ ;loop if not (hangs on error) ; in next step, write next word mov (r5)+,(r1) ;store next word asl r2 ;shift to next step bpl 10$ ;loop unless ran into bit 15 ; R2=100000 from now on ; resync per page 4-17 of MSCP Basic Disk Functions Manual jsr r4,cmd ;set controller characteristics (to defaults) .byte op.scc,0 jsr r4,cmd ;bring unit online .byte op.onl,0 ; read block 0 into address 00000000 jsr r4,cmd ;read boot block .byte op.rd,1000/400 clr -(r1) ;restart init process (for RSX11M+ boot) clr pc ;drop into boot block ;+ ; ; Execute command. ; ; Call: ; JSR R4,CMD ; .BYTE OPC ;opcode ; .BYTE BC/400 ;high byte of byte count ; ; r0 unit (preserved) ; r1 DUSA (preserved) ; r2 100000 (preserved) ; ;- cmd: ; init command packet mov #dupack-4,r5 ;point at it (allow for prefix) mov #60,(r5)+ ;set length clr (r5)+ ;virtual circuit #0 (MSCP) ; (set up ring descriptors to point at this buffer) mov #during,r3 ;point at descriptors mov r5,(r3)+ ;init both of them (to point at same buf) mov r2,(r3)+ ;(R2=100000) OWN=1, FLAG=0 mov r5,(r3)+ mov r2,(r3) 10$: clr (r5)+ ;clear out the rest cmp r5,#dupack+60 ;done all? blo 10$ ;loop if not ; fill in unit/opcode/byte count mov r0,@#dupack+p.unit ;set unit # movb (r4)+,@#dupack+p.opcd ;and opcode movb (r4)+,@#dupack+p.bcnt+1 ;set high byte of byte count for OP.RD tst -2(r1) ;start it going .assume duip eq dusa-2 20$: tst -4(r3) ;wait for response buf to be returned bmi 20$ rts r4 ;ignore errors, out of space and no way to ;report them anyway (will be obvious though) ; .end