From bschor@vms.cis.pitt.edu Mon Dec  5 14:19:33 PST 1994
Article: 3487 of vmsnet.pdp-11
Path: nntp-server.caltech.edu!pagesat.net!dfw.net!convex!cs.utexas.edu!howland.reston.ans.net!gatech!newsfeed.pitt.edu!vms.cis.pitt.edu!bschor
From: bschor@vms.cis.pitt.edu
Newsgroups: vmsnet.pdp-11
Subject: MSCP (DU0) Bootstrap
Date: 5 Dec 94 16:09:26 EST
Organization: University of Pittsburgh
Lines: 151
Message-ID: <3bvviu$5ca@usenet.srv.cis.pitt.edu>
NNTP-Posting-Host: axpvm1.cis.pitt.edu

The following is MSCP.MAC, the code for the toggle-in bootstrap for DU0 as
listed (almost) in the RT-11 5.6 manuals.  When this is assembled, the .SAV
image at 76000 will match that of the boot.

The first set of comments on the right are the (octal) location and 
contents of the bootstrap, should you actually need to toggle it in.  I am 
indebted to Jim Crapuchettes for deducing the missing word in the manual
listing, and for providing the comments as to what the code is doing.  
[MSCP is a pretty mysterious protocol.  Suffice to say that you build 
instruction packets in PDP-11 memory, then tell the controller to execute 
them.]

Note that I have used this code, as ODT instructions, to "ram" the 
bootstrap over a serial line to an 11/73 which had no DU boot.  The 11/73 
came up in ODT, so all I had to do was to fire up VTCOM and send the 
ODT-like instructions over the serial line (ending, of course, with 
76000G).  To my surprise, it worked!


;------------------------------------------------------------------------------
;This is the MSCP bootstrap as listed in the RT-11 5.6 INS manual ...
; along with its disassembly (by hand!).  Additional comments and
; attempts to make "nicer" assembly by
;       Bob Schor       bschor@vms.cis.pitt.edu         (412) 647-2116 (w)
;
;Missing word (at 76102) and most of the explanation supplied by
;       Jim Crapuchettes        jimc@netcom.com         408-732-0569
;
        .asect
 
        . = 42
 
        .word   1000    ;-; Set stack pointer for RT-11 - don't "toggle" in
 
        . = 76000
 
; The contents of R0 must be the MSCP unit number.  Although it is set to 0
; below, it could be manually set to some other value and then execution
; started at 76002.
 
start:  clr     r0              ;76000/5000     ;; Preset register to 0 
(unit)
        mov     #172150, r1     ;76002/12701    ;; Point to IP register
                                ;76004/172150
1$:     mov     #itabl, r4      ;76006/12704    ;; Point to init/cmd params
                                ;76010/76156
        mov     #4000, r5       ;76012/12705    ;; Set init step to 1
                                ;76014/4000
 
; Do 4-step controller initialization.  Begin by writing any value to IP to
; reset the controller; all the rest of initialization is done through SA.
 
        mov     r1, r2          ;76016/10102    ;; Copy IP address, write 
to
        mov     r0, (r2)+       ;76020/10022    ;;  IP to init & bump to SA
2$:     tst     (r2)            ;76022/5712     ;; Test for error bit in SA
        bmi     1$              ;76024/100770   ;;  Error = start init 
again
        bit     (r2), r5        ;76026/31205    ;; Test step bit in SA
        br      3$              ;76030/401      ;; ????, appears to skip 
next
        bic     (r1)+, (r5)+    ;76032/42125    ;; ????, seems to be 
skipped
3$:     beq     2$              ;76034/1772     ;; Wait for next step ready
        mov     -(r4),(r2)      ;76036/14412    ;; Next init param to SA
        asl     r5              ;76040/6305     ;; Move to next init step
        bpl     2$              ;76042/100367   ;;  Loop thru 4 steps
 
; Bring unit on-line, read bootstrap (block 0) from the disk and start it 
up.
 
4$:     tstb    -(r4)           ;76044/105744   ;; Point to next cmd byte
        bne     5$              ;76046/1002     ;;  Loop thru commands
        mov     pc, r4          ;76050/10704    ;; Point r4 to "clr pc" and
        clr     pc              ;76052/5007     ;;  go start at location 0
 
5$:     clr     r2              ;76054/5002     ;; Init for clearing memory
6$:     clr     (r2)+           ;76056/5022     ;; Clear memory from loc 0
        cmp     r2, #17204      ;76060/20227    ;;  thru loc 17202
                                ;76062/17204
        blo     6$              ;76064/103774   ;;  Loop until done
        incb    @#17101         ;76066/105237   ;; Packet length = 400 
bytes
                                ;76070/17101
        mov     r0, @#17110     ;76072/10037    ;; Set unit number = 0
                                ;76074/17110
        movb    (r4), @#17114   ;76076/111437   ;; Move command to cmd pkt
                                ;76100/17114
        movb    -(r4), @#17121  ;76102/114437   ;; Set parameter from table
                                ;76104/17121
        mov     #17004, (r2)+   ;76106/12722    ;; Set response packet de-
                                ;76110/17004    ;;  scriptor: low 16 
address
        mov     r5, (r2)+       ;76112/10522    ;;   bits & PortOwn bit
        mov     #17104, (r2)+   ;76114/12722    ;; Set command packet de-
                                ;76116/17104    ;;  scriptor: low 16 
address
        mov     r5, (r2)        ;76120/10512    ;;   bits & PortOwn bit
        cmp     -(r2),-(r2)     ;76122/24242    ;; Point back to resp desc
        tst     (r1)            ;76124/5711     ;; Poll controller to start
7$:     tst     (r2)            ;76126/5712     ;; Wait for resp desc PO 
bit
        bmi     7$              ;76130/100776   ;;  => 0 == response 
received
        tst     @#17016         ;76132/5737     ;; Status byte = success 
(0)?
                                ;76134/17016
        beq     4$              ;76136/1742     ;; Yes, go to next command
stop:   halt                    ;76140/0        ;;  No, stop here...
 
; NOTE: This table MUST be - immediately preceeded by a zero byte (the HALT
; instruction) because it is the "end-of-table" marker; and immediately
; precede the Initialization Step Parameter table since a single register
; points first to the IStep Params (1 word each) and then to the commands
; (1 byte for the command, 1 byte for the parameter), passing through them
; in reverse.
 
        .byte   2               ;;  Set byte count to 1000 for OP.RD
        .byte   41              ;; OP.RD  = ReaD
        .byte   0               ;;  0 parameter for OP.ONL
        .byte   11              ;; OP.ONL = ON Line
;;      .word   20402           ;76142/20402
;;      .word   4400            ;76144/4400
 
        .word   1               ;76146/1        ;; IS4: GO bit
        .word   0               ;76150/0        ;; IS3: Ring base high 
address
        .word   17204           ;76152/17204    ;; IS2: Ring base low 
address
        .word   100000          ;76154/100000   ;; IS1: bits-
                                ;; [15] = 1, [14] (WR) = 0, [13:11] (cmd 
ring
                                ;; size) = 0, [10:8] (resp ring size) = 0, 
[7]
                                ;; (IE) = 0, [6:0] (int vect/4) = 0 :: 
command
                                ;; and response rings = 1 element, no 
inter-
                                ;; rupts and no interrupt vector.
        itabl   =:      .       ;need pointer to end of table
 
                                ;76000g to start ODT
 
        .end    stop    ;For RT-11 only, don't "toggle" in
                                                                            
                                                                            
                                                                            
                                                                            
                                                                            
 



