PGM VMIDRIV REL ************************************************************ * * * Device driver for the Logica VTS VMI-1 intelligent * * multibus ring (Polynet) interface. * * * ************************************************************ MPICMSK EQU #C2 V.DEMPTY EQU #40 ERRVEC EQU #3FC VMICTRL EQU #50 VMIDATA EQU #51 * * Pkt types * A.TELL EQU 979 A.AHA EQU 978 A.INIT EQU 977 A.CLEAR EQU 976 * * DCB symbols * * 0 device driver ptr (BCPL) * 2 link to code (=0) * 4 D.ID EQU 6 id D.WKQ EQU 8 work q D.START EQU 10 start rtn for qpkt D.STOP EQU 14 D.CALL EQU 18 D.INT EQU 20 D.I EQU D.CALL+6 D.VEC EQU 24 * * Pkt sumbols P.ID EQU 2 P.TYPE EQU 4 P.RES1 EQU 6 P.RES2 EQU 8 P.A1 EQU 10 P.A2 EQU 12 * * The Rootnode * CRNTSK EQU #506 DEVMVP EQU #51A DEVINT EQU #51E DEVRET EQU #522 * DW VMINITI init. routine DW VMUNINI unin. routine * * Initialisation routine, * entry: BX = MC DCB address * preserve: DX,DI,BP VMINIT MOV D.START(BX),!VMISTART MOV D.STOP(BX),!VMISTOP MOV D.START+2(BX),CS MOV D.STOP+2(BX),CS * MOV D.INT(BX),!VMINT CALLS offset MOV D.INT+2(BX),CS MOV SI,D.VEC(BX) interrupt vector no. ADD SI,!40 SHL SI SHL SI MOV (SI),BX plug int. vec. with CALLS address ADD (SI),!D.CALL MOV 2(SI),!0 RETS * * Uninitialisation, * entry: BX = MC DCB address * preserve: BX VMUNIN MOV SI,D.VEC(BX) int. vec no. * disable interrupts MOV CX,SI MOV DL,!1 SHL DL,CL IN MPICMSK OR AL,DL OUT MPICMSK * ADD SI,!40 SHL SI SHL SI MOV AX,ERRVEC MOV (SI),AX MOV AX,ERRVEC+2 MOV 2(SI),AX RETS * * Start routine, * entry: BX = MC DCB address * SI = BCPL pkt address * return: non-zero * preserve: BP,DI * VMISTART SHL SI MC pkt addr MOV D.WKQ(BX),!0 clear work q MOV AX,P.TYPE(SI) CMP AX,!A.CLEAR JNE VMI0 * clear interrupt by reading control port IN VMICTRL JMP RPKT * VMI0 CMP AX,!A.TELL JNE VMI1 * interrupt the VMI-1 OUT VMIDATA JMP RPKT * VMI1 CMP AX,!A.AHA JNE VMI2 * pkt to pick up signal from VMI-1, * is there one pending? CMP PENDFLG,!0 JE VMI10 not pending * is one, return pkt MOV PENDFLG,!0 clear flag JMP RPKT * VMI10 MOV AHAPKT,SI save MC pkt addr (only one) RETS * VMI2 CMP AX,!A.INIT JE VMI3 JMP RPKT return junk pkt * perform initialisation, arg1 is byte offset of shared memory VMI3 OUT VMICTRL reset the b****r * write the start address MOV AX,P.A1(SI) CALL SVMI writes AL MOV AX,P.A1(SI) MOV AL,AH CALL SVMI XOR AL,AL CALL SVMI CALL SVMI * MOV AHAPKT,!0 MOV PENDFLG,!0 MOV P.RES1(SI),!0 result is 0 MOV CL,D.VEC(BX) * enable ints. MOV DL,!1 SHL DL,CL NOT DL IN MPICMSK AND AL,DL OUT MPICMSK * * return pkt to sender RPKT MOV CX,D.ID(BX) MOV BX,CRNTSK SHL BX JIS DEVMVP & return from this routine * * Stop * VMISTOP RETS * * Interrupt service, * return aha pkt or set flag. VMINT PUSH BX PUSH AX PUSH CX PUSH DX PUSH SI MOV BX,SP MOV BX,10(BX) get old IP pointing into DCB * MOV SI,AHAPKT OR SI,SI exists ahapkt? JE VMINA no * return aha pkt MOV AHAPKT,!0 MOV PENDFLG,!0 MOV CX,D.ID-D.I(BX) MOV BX,CRNTSK SHL BX CIS DEVMVP JIS DEVINT * set pending flag VMINA MOV PENDFLG,!1 JIS DEVRET quick return * * Svmi routine sends init. data to VMI-1 from AL. SVMI MOV AH,AL save S0 IN VMICTRL TEST AL,!V.DEMPTY JE S0 not ready MOV AL,AH OUT VMIDATA write RET * EVEN DSEG VMINITI DW VMINIT DW 0 VMUNINI DW VMUNIN DW 0 * PENDFLG DW 0 AHAPKT DW 0 * END