PGM   VMPRX
         REL
*
MPICMSK  EQU   #C2
ERRVEC   EQU   #3FC
* VMP addresses
VB       EQU   #80
VCTRL    EQU   VB+4
VRXG     EQU   VB+7
VSOURCE  EQU   VB+1
VSSR     EQU   VB+0
VRXB     EQU   VB+5
* VMP bits
VRON     EQU   #T00001000
VRRST    EQU   #T00000100
VNEN     EQU   #T00000001
VRTRY    EQU   #T00000010
* DCB symbols
D.ID     EQU   6
D.WKQ    EQU   8
D.START  EQU   10
D.STOP   EQU   14
D.CALL   EQU   18
D.INT    EQU   20
D.I      EQU   D.CALL+6
D.VEC    EQU   24
* Pkt symbols
P.ID     EQU   2
P.TYPE   EQU   4
P.RES1   EQU   6
P.RES2   EQU   8
P.A1     EQU   10
P.A2     EQU   12
* Rootnode
CRNTSK   EQU   #506
DEVMVP   EQU   #51A
DEVINT   EQU   #51E
DEVRET   EQU   #522
*
         DW    VMPINITI
         DW    VMPUNINI
*
* Init.
*   entry: BX = MC DCB addr.
*   preserve: DX,DI,BP except DX=0 on error
VMPINIT  MOV   D.START(BX),!VMPSTART
         MOV   D.STOP(BX),!VMPSTOP
         MOV   D.START+2(BX),CS
         MOV   D.STOP+2(BX),CS
*   check that ring is up
         IN    VCTRL
         TEST  AL,!VRON
         JNE   VI0
*   not on, return 0
         XOR   DX,DX
         RETS
*   is on, plug interrupt vector
VI0      IN    VCTRL
         AND   AL,!VTRST          preserve tx setting
         OR    AL,!VRRST+VNEN
         OUT   VCTRL
         MOV   D.INT(BX),!VMPINT
         MOV   D.INT+2(BX),CS
         MOV   SI,D.VEC(BX)
         ADD   SI,!40
         SHL   SI
         SHL   SI
         MOV   (SI),BX
         ADD   (SI),!D.CALL
         MOV   2(SI),!0
         RETS
*
* Uninit.
*   entry: BX = MC DCB addr.
*   preserve: BX
VMPUNIN  CALL  DISINT
         MOV   SI,D.VEC(BX)