.title M9312 'DD' BOOT prom for TU58 DECtapeII serial tape controller (REVISED) ; This source code is an M9312 boot PROM for the TU58 version 23-765B9. ; ; This boot PROM is for the TU58 DECtapeII serial tape controller. ; ; Multiple units and/or CSR addresses are supported via different entry points. ; ; Standard devices are 82S131, Am27S13, 74S571 or other compatible bipolar ; PROMs with a 512x4 TriState 16pin DIP architecture. This code resides in ; the low half of the device; the top half is blank and unused. ; ; Alternatively, 82S129 compatible 256x4 TriState 16pin DIP devices can be ; used, as the uppermost address line (hardwired low) is an active low chip ; select (and will be correctly asserted low). ;VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV ; ; The original code in 23-765A9 is REALLY BROKEN when it comes to ; supporting a non-std CSR other than 776500 in R1 on entry ; ; All the hard references to: ddrbuf, ddxcsr, ddxbuf ; have been changed to: 2(R1), 4(R1), 6(R1) ; ; The one reference where 'ddrcsr' might have been used is '(R1)' instead ; which is actually correct (but totally inconsistent with other usage). ; ;AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA ddcsr =176500 ; std TU58 csrbase ddrcsr =+0 ; receive control ddrbuf =+2 ; receive data ddxcsr =+4 ; transmit control ddxbuf =+6 ; transmit data diags =165564 ; console diags phase2 entry .asect .=173000 ; -------------------------------------------------- start: .ascii "DD" ; device code (reversed) .word last-. ; offset to next boot header dd0n: sec ; boot std csr, unit zero, no diags dd0d: mov #0,r0 ; boot std csr, unit zero, with diags ddNr: mov #ddcsr,r1 ; boot std csr, unit ddNb: mov pc,r4 ; boot csr , unit bcc diag ; br if diags requested br go ; return to (R4)+2 from diags ; then skip over pseudo reboot vector ; -------------------------------------------------- .word 173000 ; prom start addess @ 24 .word 340 ; and priority level @ 26 ; -------------------------------------------------- go: mov #2000,sp ; setup a stack clr r4 ; zap old return address inc ddxcsr(r1) ; set break bit clr r3 ; data 000,000 jsr pc,10$ ; transmit a bunch of zero chars clr ddxcsr(r1) ; clear break bit tst ddrbuf(r1) ; read/flush any stale rx char mov #<010*400>+004,r3 ; data 010,004 jsr pc,12$ ; transmit 004 (init) and 010 (boot) mov r0,r3 ; get unit number jsr pc,13$ ; transmit unit number clr r3 ; clear rx buffer ptr 2$: tstb (r1) ; wait for rcv'd char available bpl 2$ ; br if not yet movb ddrbuf(r1),(r3)+ ; store the char in buffer, bump ptr cmp #1000,r3 ; hit end of buffer (512. bytes)? bhi 2$ ; br if not yet clr pc ; jump to bootstrap at zero 10$: jsr pc,(pc) ; recursive call for char replication 11$: jsr pc,(pc) ; recursive call for char replication 12$: jsr pc,(pc) ; recursive call for char replication 13$: tstb ddxcsr(r1) ; wait for xmit buffer available bpl 13$ ; br if not yet movb r3,ddxbuf(r1) ; send the char swab r3 ; swap to other char rts pc ; now recurse or return ; -------------------------------------------------- dd1n: sec ; boot std csr, unit one, no diags dd1d: mov #1,r0 ; boot std csr, unit one, with diags br ddNr ; continue ; -------------------------------------------------- diag: jmp @#diags ; jump to console diags ; -------------------------------------------------- .word 0,0,0,0,0,0,0 ; unused ; -------------------------------------------------- .=start+176 crc16: .word <046154> ; CRC-16 will go here last: ; next boot prom starts here .end