DataMuseum.dk

Presents historical artifacts from the history of:

Philips Data Systems

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about Philips Data Systems

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download

⟦3854ea848⟧

    Length: 56176 (0xdb70)
    Notes: pts_type(SC)
    Names: »TOSSIO.SC«

Derivation

└─⟦781e933ac⟧ Bits:30009686 Philips computer tape "600310"
    └─⟦this⟧ »M:92T1/TOSSIO.SC« 

PTS(SC)

	IDENT TOSSIO 	REL 9.2 79-11-16  870105040920 

			=1, DM ATTACH HANG UP
			REL 9.1 79-05-23 
* 
* 
**************************************************
* 
*   PHILIPS TERMINAL SYSTEM PTS 
* 
*   TOSSIO = TOSS I/O LKM PROCESSOR 
* 
* 
* 
**************************************************
* 
* 
*   THIS IS THE TOSS I/O LKM PROCESSOR. 
*   IT CONTAINS THE FOLLOWING MONITOR SUBROUTINES:
* 
*   -TIO     INITIALIZE I/O 
* 
*   -TENDIO  END I/O
* 
*   -ATTACH  ATTACH DEVICE
* 
*   -DETACH  DETACH DEVICE
* 
*   SPECIAL ROUTINES ARE CARRIED OUT IN SYSTEMS 
*   WITH MEMORY MANAGEMENT UNIT (MMU).
* 
*   THIS MODULE ALSO CONTAINS STANDARD DISPLACEMENT 
*   VALUES FOR ECB AND DWT AREAS, AS WELL AS SPECIAL
*   MOVE ROUTINES FOR DATA COMMUNICATION. 
* 
	EJECT			TOSSIO 
* 
* 
*********** 
* ENTRIES * 
*********** 
* 
* 
	ENTRY	TIO	I/O PROCESSOR
	ENTRY	TENDIO	END I/O 
* 
	ENTRY	DC:MIN	MOVE ROUTINE FOR DATACOM, INPUT 
	ENTRY	DC:MOT	MOVE ROUTINE FOR DATACOM, OUTPUT
	ENTRY	MONMMU	MONITOR (SYSTEM) MMU TABLE
* 
	ENTRY	ECBFC	FILE CODE
	ENTRY	ECBBA	BUFFER ADDRESS 
	ENTRY	ECBRL	REQUESTED LENGTH 
	ENTRY	ECBEL	EFFECTIVE LENGTH 
	ENTRY	ECBRC	RETURN CODE
	ENTRY	ECBCW	CONTROL WORD 
	ENTRY	ECBCW2	SECOND CONTROL WORD (USED BY DM)
* 
	ENTRY	BUFLEN	MMU BUFFER LENGTH 
	ENTRY	ACTADR	ACTIVATION ADDRESS
	ENTRY	ABTADR	ABORT ADDRESS 
	ENTRY	INTADR	INTERRUPT ADDRESS 
	ENTRY	POLADR	BUFFER POOL ADDRESS (DC DRIVERS)
	ENTRY	RECADR	RECOVERY ADDRESS
	ENTRY	ECHADR	ECHO ADDRESS
* 
	ENTRY	DC:DIX	DEVICE INDEX DATA COMMUNICATION 
	ENTRY	DM:DIX	DEVICE INDEX DATA MANAGEMENT
	ENTRY	PC:DIX	DEVICE INDEX PROGRAMMED CHANNEL 
	ENTRY	MX:DIX	DEVICE INDEX MULTIPLEX CHANNEL
	ENTRY	KB:DIX	DEVICE INDEX KEYBOARD/CTW 
	ENTRY	IT:DIX	DEVICE INDEX INTERTASK COMMUNICATION
* 
	EJECT			TOSSIO 
* 
* 
	ENTRY	DWTCHP	CHANNEL PARAMETERS
	ENTRY	DWTST	STATUS 
	ENTRY	DWTBC	BYTE COUNTER 
	ENTRY	DWTECB	ECB ADDRESS 
	ENTRY	DWTOR	INDEX AND ORDER
	ENTRY	DWTOCH	LAST OUTPUT CHARACTER 
	ENTRY	DWTADR	DRIVER ADDRESS BLOCK
	ENTRY	DWTTAB	TTAB ADDRESS
	ENTRY	DWTWAT	WAIT/ACTIVATE INDICATOR 
	ENTRY	DWTTQ	TERMINAL QUEUE 
	ENTRY	DWTOTQ	OUTPUT QUEUE LINK 
	ENTRY	DWTTDM	DM REQUEST TTAB ADDRESS 
	ENTRY	DWTUEC	USER ECB ADDRESS
	ENTRY	DWTMEC	MMU ECB ADDRESS 
	ENTRY	DWTA2	SAVE AREA A2 
	ENTRY	DWTA3	SAVE AREA A3 
	ENTRY	DWTA4	SAVE AREA A4 
	ENTRY	DWTA5	SAVE AREA A5 
	ENTRY	DWTSB1	STACK BASE 1 IN DWT 
	ENTRY	DWTSB2	STACK BASE 2 IN DWT 
	ENTRY	DWTTP	TIMER POINTER
	ENTRY	DWTECH	ECHO DEVICE DWT 
	ENTRY	DWTSQ	START OF QUEUE 
	ENTRY	DWTVOL	DISC VOLUME NAME
* 
	EJECT			TOSSIO 
* 
* 
************* 
* EXTERNALS * 
************* 
* 
* 
	EXTRN	SAVE8	SAVE 8 REGISTERS 
	EXTRN	IHRET8	RESTORE 8 REGISTERS AND RETURN
	EXTRN	IHRTN	RETURN WITHOUT ENABLING INTERRUPTS 
	EXTRN	ACTOTP	ACTIVATE TERMINAL (LIFO)
	EXTRN	FNDDWT	SEARCH DWT
	EXTRN	QMJOB	QUEUE MONITOR TASK FOR DISPATCHING 
	EXTRN	QTJOB	QUEUE TERM.PROG. FOR DISP. 
	EXTRN	MEXIT	MONITOR TASK EXIT
	EXTRN	TDISP	DISPATCHER 
	EXTRN	DISEND	BRANCH TO DISPATCHER VIA TENDIO 
	EXTRN	LKMQDI	QUEUE TASK AND DISPATCH 
	EXTRN	GETBLK	PUT BLOCK IN PENDING QUEUE
	EXTRN	FREBLK	RELEASE BLOCK FROM PENDING QUEUE
	EXTRN	SETIMP	SET TIMER 
	EXTRN	TTMJOB	MONITOR TASK
	EXTRN	TTB:ID	TASK IDENTIFICATION 
	EXTRN	TTB:ST	TASK STATUS AND LEVEL 
	EXTRN	TTB:PW	PROGRAM STATUS WORD 
	EXTRN	TTB:SA	SAVE AREA 
	EXTRN	TTB:MT	MMUTAB
	EXTRN	TIODM	ENTRY FOR DM 
	EXTRN	REQEND	ENTRY FOR DM
	EXTRN	FDBADF	ADDRESS OF DATA FILE FDB
* 
	EJECT			TOSSIO 
* 
* 
***************************************** 
* 
*	CONDITIONAL ASSEMBLY
* 
***************************************** 
* 
*	A PROGRAM VERSION USING TOSS MMU PAGING 
*	IS OBTAINED BY SETTING MMUPAG EQU 1.
* 
MMUPAG	EQU	0
* 
* 
*	A PROGRAM VERSION USING THE EXTENDED INSTRUCTION
*	SET IS OBTAINED BY SETTING CPU852 EQU 0.
* 
CPU852	EQU	1
* 
* 
*	A PROGRAM VERSION INCLUDING ATTACH/DETACH 
*	IS OBTAINED BY SETTING ATTDET EQU 1.
* 
X:A	EQU	0 
ATTDET	EQU	1
* 
* 
*	A PROGRAM VERSION SPECIALIZED FOR THE 857 CPU 
*	IS OBTAINED BY SETTING CPU857 EQU 1.
* 
X:B	EQU	0 
CPU857	EQU	X:B
* 
	EJECT			TOSSIO 
* 
* 
******************* 
* FORM STATEMENTS * 
******************* 
* 
* 
BYTES	FORM	8,8
* 
	EJECT			TOSSIO 
* 
* 
********************* 
* DWT DISPLACEMENTS * 
********************* 
* 
*	DWT DISPLACEMENTS: FIXED PART 
* 
DWTCHP	EQU	/00	CHANNEL PARAMETERS 
DWTST	EQU	/02	STATUS
DWTBC	EQU	/03	BYTE COUNTER
DWTECB	EQU	/04	ECB ADDRESS
DWTOR	EQU	/06	INDEX AND ORDER 
DWTOCH	EQU	/06	LAST OUTPUT CHARACTER
DWTADR	EQU	/08	DRIVER ADDRESS BLOCK 
DWTTAB	EQU	/0A	TTAB ADDRESS 
DWTWAT	EQU	/0C	WAIT/ACTIVATE INDICATOR
DWTTQ	EQU	/0E	TERMINAL QUEUE
DWTUEC	EQU	/10	USER ECB ADDRESS 
DWTMEC	EQU	/12	MMU ECB ADDRESS
* 
	IFT	MMUPAG=0 
DWTDRD	EQU	DWTTQ+2	START OF DRIVER DEFINED PART 
	XIF
* 
	IFT	MMUPAG=1 
DWTDRD	EQU	DWTMEC+2	START OF DRIVER DEFINED PART
	XIF
* 
	EJECT			TOSSIO 
* 
*	DWT DISPLACEMENTS: DRIVER DEFINED PART
* 
DWTOTQ	EQU	DWTDRD+/00	OUTPUT QUEUE LINK 
DWTTDM	EQU	DWTDRD+/00	DM REQUEST TTAB ADDRESS 
DWTA2	EQU	DWTDRD+/02	SAVE AREA A2 
DWTA3	EQU	DWTDRD+/02	SAVE AREA A3 
DWTA4	EQU	DWTDRD+/04	SAVE AREA A4 
DWTA5	EQU	DWTDRD+/06	SAVE AREA A5 
DWTSB1	EQU	DWTDRD+/0A	STACK BASE 1 IN DWT 
DWTSB2	EQU	DWTDRD+/0E	STACK BASE 2 IN DWT 
DWTTP	EQU	DWTDRD+/10	TIMER POINTER
DWTECH	EQU	DWTDRD+/12	ECHO DEVICE DWT 
DWTSQ	EQU	DWTDRD+/1C	START OF QUEUE 
DWTVOL	EQU	DWTDRD+/1C	DISC VOLUME NAME
* 
	EJECT			TOSSIO 
* 
* 
**************************************
* DRIVER ADDRESS BLOCK DISPLACEMENTS *
**************************************
* 
* 
KEYLEN	EQU	-6	DWT KEYTABLE LENGTH 
BUFLEN	EQU	-4	DWT BUFFER LENGTH 
DEVIND	EQU	-2	DEVICE INDEX
ACTADR	EQU	0	ACTIVATION ADDRESS 
ABTADR	EQU	2	ABORT ADDRESS
INTADR	EQU	4	INTERRUPT ADDRESS
POLADR	EQU	4	BUFFER POOL ADDRESS
RECADR	EQU	6	RECOVERY ADDRESS 
ECHADR	EQU	8	ECHO ADDRESS 
* 
* 
*********************** 
* DEVICE INDEX VALUES * 
*********************** 
* 
* 
*   THE VALUES ARE USED IN MMU SYSTEMS FOR SELECTING A SPECIAL ROUTINE
*   FROM ADDRESS TABLES TIOTAB AND TENTAB AT READ/WRITE REQUESTS. 
* 
DC:DIX	EQU	-2	DATA COMMUNICATION
DM:DIX	EQU	0	DATA MANAGEMENT
PC:DIX	EQU	2	PROGRAMMED CHANNEL 
MX:DIX	EQU	4	MULTIPLEX CHANNEL
KB:DIX	EQU	6	KEYBOARD/CTW 
IT:DIX	EQU	8	INTERTASK COMMUNICATION
* 
	EJECT			TOSSIO 
* 
* 
********************* 
* ECB DISPLACEMENTS * 
********************* 
* 
* 
ECBFC	EQU	/01	FILE CODE 
ECBBA	EQU	/02	BUFFER ADDRESS
ECBRL	EQU	/04	REQUESTED LENGTH
ECBEL	EQU	/06	EFFECTIVE LENGTH
ECBRC	EQU	/08	RETURN CODE 
ECBCW	EQU	/0A	CONTROL WORD
ECBCW2	EQU	/0C	SECOND CONTROL WORD
* 
	EJECT			TOSSIO 
* 
* 
	IFT	MMUPAG=1 
* 
* 
**********
* TIOTAB *
**********
* 
*	TIOTAB CONTAINS ADDRESSES TO ROUTINES ENTERED FROM TIO
* 
TIOTAB	EQU	*	DEVICE TYPE/ROUTINE ADDRESS TABLE
	DATA	TIO:DM	DATA MANAGEMENT, INPUT/OUTPUT
	DATA	TIOPCI	PROGRAMMED CHANNEL, INPUT
	DATA	TIOMXI	MUX, INPUT 
	DATA	TIOKBI	KEYBOARD/CTW, INPUT
* 
TINDEX	EQU	*-TIOTAB 
	DATA	TIOITI	INTERTASK COMMUNICATION, INPUT 
	DATA	TIOPCO	PROGRAMMED CHANNEL, OUTPUT 
	DATA	TIOMXO	MUX, OUTPUT
	DATA	TIOKBO	KEYBOARD/CTW, OUTPUT 
	DATA	TIOITO	INTERTASK COMMUNICATION, OUTPUT
* 
	EJECT			TOSSIO 
* 
* 
**********
* TENTAB *
**********
* 
*	TENTAB CONTAINS ADDRESSES TO ROUTINES ENTERED FROM TENDIO 
* 
TENTAB	EQU	*	DEVICE TYPE/ROUTINE ADDRESS TABLE
	DATA	TEN:DM	DATA MANAGEMENT, INPUT/OUTPUT
	DATA	TENPCI	PROGRAMMED CHANNEL, INPUT
	DATA	TENMXI	MUX, INPUT 
	DATA	TENKBI	KEYBOARD/CTW, INPUT
	DATA	TENITI	INTERTASK COMMUNICATION, INPUT 
	DATA	TENPCO	PROGRAMMED CHANNEL, OUTPUT 
	DATA	TENMXO	MUX, OUTPUT
	DATA	TENKBO	KEYBOARD/CTW, OUTPUT 
	DATA	TENITO	INTERTASK COMMUNICATION, OUTPUT
	XIF
* 
	EJECT			TOSSIO 
* 
* 
**********
* MONMMU *
**********
* 
*	MONITOR (SYSTEM) MMU TABLE
* 
MONMMU	EQU	*	MONITOR (SYSTEM) MMU TABLE 
	IFT	MMUPAG=1 
	DATA	/0000,/0400,/0800,/0C00 
	DATA	/1000,/1400,/1800,/1C00 
	DATA	/2000,/2400,/2800,/2C00 
	DATA	/3000,/3400,/3800,/3C00 
	XIF
* 
	EJECT			TOSSIO 
* 
* 
	IFT	ATTDET=1 
* 
*	SUBROUTINES BELOW ARE USED BY ATTACH/DETACH 
* 
*	T I M O U T 
* 
* INPUT:  A1 = DWT ADDRESS
*         A2 = ADDRESS TO 2ND TIMER BLOCK 
* 
* OUTPUT: A4 = BLOCK ADDRESS
*         A5 = TTAB ADDRESS 
*         A6 = DWT ADDRESS
*         A1-A3 ARE DESTROYED 
* 
TIMOUT	LDR	A6,A1
	LDR*	A2,A2	TIMER POINTER ADDRESS 
	LD	A5,2,A2	GET TTAB ADDRESS
* 
	IFT	MMUPAG=1 
	TL	TTB:MT,A5	LOAD MMU REGISTERS FROM TTAB
	XIF
* 
	IFT	ATTDET=1 
	CF	A15,FNDBLK
	LDR*	A1,A4 
	STR	A1,A2	REMOVE FROM ATT:CH 
	CF	A15,FREBLK
* 
	EJECT			TOSSIO 
* 
*   	REMOVE TTAB FROM DEVICE QUEUE
* 
	LDR	A1,A6
	ADK	A1,DWTTQ	QUEUE ANCHOR ADDRESS
* 
TIM:10	LDR	A2,A1	SAVE 
	LDR*	A1,A1	NEXT IN QUEUE 
	RF(Z)	TIM:20	END OF QUEUE? 
 	CWR	A1,A5 
	RB(NE)	TIM:10	NOT FOUND? 
* 
	EJECT			TOSSIO 
* 
*  	TTAB FOUND - REMOVE FROM QUEUE
* 
	LDR*	A1,A1 
	STR	A1,A2
* 
TIM:20	EQU	*
	LDK	A3,4 
	ADS	A3,TTB:SA,A5	UPDATE DISPATCH ADDRESS 
	LD	A8,TTB:SA+16,A5	GET ECB ADDRESS FROM A8 SAVE AREA 
	LDK	A3,/40	SET TIMEOUT BIT 
* 
	IFT	MMUPAG=0 
	ST	A3,ECBRC,A8	INDICATE ERROR IN ECB 
	XIF
* 
	IFT	ATTDET=1 
	IFT	MMUPAG=1 
	ES	A3,ECBRC,A8	INDICATE ERROR IN ECB 
	TL	MONMMU	LOAD MONITOR (SYSTEM) MMU TABLE
	XIF
* 
	IFT	ATTDET=1 
	RF	TIORTN	QUEUE TASK AND DISPATCH
* 
	EJECT			TOSSIO 
* 
*	F N D B L K 
* 
* SUBROUTINE TO FIND BLOCK IN ATT:CH
* 
* INPUT:  A5 = TTAB ADDRESS 
* 
* OUTPUT: A2 = ADDRESS TO PRECEDING BLOCK IN CHAIN
*         A4 = BLOCK ADDRESS IF FOUND, ELSE 0 
* 
FNDBLK	LDKL	A4,ATT:CH	ANCHOR ADDRESS
* 
FND:10	LDR	A2,A4	SAVE A4
	LDR*	A4,A4 
	RF(Z)	FND:20	END OF ATT:CH?
	CW	A5,4,A4 
	RB(NE)	FND:10	NOT FOUND? 
* 
FND:20	EQU	*
	IFT	CPU852=1 
	ABL	IHRTN	RETURN 
	XIF
* 
	IFT	ATTDET=1 
	IFT	CPU852=0 
	RTN	A15	RETURN 
	XIF
* 
	IFT	ATTDET=1 
ATT:CH	DATA	0	ATTACH CHAIN ANCHOR 
* 
	EJECT			TOSSIO 
* 
*	F D B A T T / F D B D E T 
* 
* SUBROUTINE TO ATTACH/DETACH FDB:S 
* IN A DATA MANAGEMENT FILE STRUCTURE 
* 
* INPUT:  A5 = TTAB ADDRESS 
*         A6 = FDB ADDRESS
*        A10 = /800 (ATTACH BIT)
* 
* OUTPUT: A2-A4 AREA DESTROYED
* 
FDBDET	EQU	*
	C1R	A10,A10	A10=F7FF 
* 
FDBATT	EQU	*
	LDR	A4,A6	FDB ADDRESS
	ADKL	A4,FDBADF 
	LDK	A3,10	LOOP INDEX 
* 
FDB:10	SUK	A3,2 
	RB(N)	FND:20	ALL FDB:S READY?
	LDR*	A2,A4	NEXT FDB
	RF(Z)	FDB:20	NO FDB? 
	LDR	A10,A10
	RF(N)	FDB:15	DETACH REQUEST? 
	ORS	A10,DWTST,A2	ATTACH REQUEST
	ST	A5,DWTTAB,A2
	RF	FDB:20
* 
FDB:15	ANS	A10,DWTST,A2	DETACH REQUEST
	CF	A15,QREQ	UPDATE DWTTQ 
* 
FDB:20	ADK	A4,2	NEXT FDB ADDRESS
	RB	FDB:10
* 
	EJECT			TOSSIO 
* 
*	Q R E Q 
* 
* SUBROUTINE TO QUEUE TASK IN DEVICE QUEUE (IF ANY) 
* 
* INPUT:  A2 = DWT ADDRESS
* 
* OUTPUT: A7, A9 ARE DESTROYED
* 
QREQ	EQU	*
	LDR	A9,A5	SAVE A5 (TTAB ADDRESS) 
	LD	A5,DWTTQ,A2	ANY TASK IN QUEUE?
	RF(Z)	QRE:10	NO! 
	LDR*	A7,A5	YES,UPDATE QUEUE ANCHOR 
	ST	A7,DWTTQ,A2 
	CF	A15,QTJOB	QUEUE TASK
* 
QRE:10	EQU	*
	LDR	A5,A9	RESTORE TTAB ADDRESS 
	IFT	CPU852=1 
	RB	FND:20	RETURN 
	XIF
* 
	IFT	ATTDET=1 
	IFT	CPU852=0 
	RTN	A15	RETURN 
	XIF
* 
	IFT	ATTDET=1 
* 
	EJECT			TOSSIO 
* 
* 
**********
* ATTACH *
**********
* 
* 
*  THIS MODULE IS CALLED FROM TIO WITH
*  THE FOLLOWING PARAMETERS:
* 
*   A3  /8000 (REQUEST ERROR BIT) 
*   A4  I/O AND ACTIVATE INDICATOR
*   A5  TTAB ADDRESS
*   A6  DWT ADDRESS 
*   A7  ORDER CODE
*   A8  ECB ADDRESS 
*  A10  /0800 (ATTACH BIT)
*  A12  ADDRESS TO DRIVER ADDRESS BLOCK 
*  A13  DWT STATUS
* 
ATTACH	EQU	*	ENTRY
	ADK	A4,0	SET CR
	RF(NZ)	TIOERR	I/O AND ACTIVATE ERROR?
* 
	IFT	MMUPAG=0 
	CM	ECBRC,A8	RESET RETURN CODE
	XIF
* 
	IFT	ATTDET=1 
	IFT	MMUPAG=1 
	ES	A4,ECBRC,A8	RESET RETURN CODE 
	XIF
* 
	EJECT			TOSSIO 
* 
* 
	IFT	ATTDET=1 
	TM	A10,A13 
	RF(NZ)	ATT:40	DEVICE ALREADY ATTACHED? 
	LDR	A13,A13
	RF(NN)	ATT:50	DEVICE BUSY? 
* 
*   	ATTACH REQUESTING TASK 
* 
	ORS	A10,DWTST,A6	ATTACH
	ST	A5,DWTTAB,A6	PUT TTAB ADDRESS IN DWT
	CWK	A12,TIODM
	RF(NE)	ATT:15	NO DM REQUEST? 
	CF	A15,FDBATT	ATTACH FILE STRUCTURE
* 
ATT:15	EQU	*
	CF	A15,FNDBLK	ANY TIMERS ACTIVE? 
	ADK	A4,0	SET CR
	RF(Z)	ATTRTN	NO! 
* 
	EJECT			TOSSIO 
* 
*  	FREE BLOCK AND TIMER IN ATT:CH
* 
	CM*	2,A4	FREE TIMER
	LDR*	A3,A4	REMOVE FROM ATT:CH
	STR	A3,A2
	CF	A15,FREBLK	RELEASE BLOCK
	RF	ATTRTN	END REQUEST
* 
ATT:40	CW	A5,DWTTAB,A6
	RF(E)	TIOERR	ATTACHED TO REQUESTING TASK?
* 
ATT:50	CF	A15,FNDBLK	 
	ADK	A4,0	SET CR
	RF(NZ)	ATT:70	IS TIMER ACTIVE? 
* 
*    	SET TIMER 
* 
	IFT	MMUPAG=0 
	LD	A1,ECBCW,A8	TIME
	XIF
* 
	EJECT			TOSSIO 
* 
* 
	IFT	ATTDET=1 
	IFT	MMUPAG=1 
	EL	A1,ECBCW,A8	TIME
	XIF
* 
	IFT	ATTDET=1 
	RF(N)	TIOERR	NEGATIVE TIME?
	RF(Z)	ATT:80	END REQUEST?
* 
ATT:60	ST	A1,ATTIM
	LDR	A1,A5	TTAB ADDRESS 
	LD	A3,ATT:CH	ANCHOR
	CF	A15,GETBLK	GET BLOCK
	ST	A4,ATT:CH	UPDATE ANCHOR 
	ADK	A4,2	TIMER POINTER ADDRESS 
	LDR	A1,A6	DWT ADDRESS
	CF	A15,SETIMP	SET TIMER
	DATA	TIMOUT
* 
ATTIM	DATA	0
* 
ATT:70	LDK	A4,0	NOT ACTIVATION PARAMETER
	RF	TIOQ20
* 
ATT:80	LDK	A3,/40	SET TIME OUT BIT
	RF	TIOERR	RETURN 
* 
	EJECT			TOSSIO 
* 
* 
**********
* DETACH *
**********
* 
* THIS MODULE IS CALLED FROM TIO WITH 
* THE SAME PARAMETERS AS ATTACH.
* 
DETACH	EQU	*
	ADK	A4,0	SET CR
	RF(NZ)	TIOERR	I/O AND ACTIVATE ERROR?
	TM	A10,A13 
	RF(Z)	TIOERR	NOT ATTACHED? 
	CW	A5,DWTTAB,A6
	RF(NE)	TIOERR	ATTACHED TO OTHER TASK?
	XRS	A10,DWTST,A6	DETACH
	CWK	A12,TIODM
	RF(NE)	DET:05	NO DM REQUEST? 
	CF	A15,FDBDET	DETACH FILE STRUCTURE
	RF	DETRTN	END REQUEST
* 
DET:05	EQU	*
	LDR	A2,A6	QREQ INPUT 
	CF	A15,QREQ	UPDATE DWTTQ 
* 
ATTRTN	EQU	*	COMMON ATTACH/DETACH NORMAL EXIT 
DETRTN	LDK	A3,0	RETURN CODE 
	XIF
* 
	EJECT			TOSSIO 
* 
* 
**********
* TIOERR *
**********
* 
*	ERROR: FILE CODE UNKNOWN
*	TIOERR IS ALSO USED AS COMMON EXIT
*	FOR MODULES 'ATTACH' AND 'DETACH'.
* 
TIOERR	EQU	*
	IFT	MMUPAG=0 
	ST	A3,ECBRC,A8	INDICATE ERROR IN ECB 
	XIF
* 
	IFT	MMUPAG=1 
	ES	A3,ECBRC,A8	INDICATE ERROR IN ECB 
	XIF
* 
TIORTN	EQU	*
	ABL	LKMQDI	QUEUE TASK AND DISPATCH 
* 
	EJECT			TOSSIO 
* 
* 
****************
* QUEUE DEVICE *
****************
* 
* 
*	THIS IS THE ROUTINE FOR QUEUEING DEVICE REQUESTS. 
*	THE ROUTINE IS ENTERED AT DIFFERENT LABELS DEPENDING ON 
*	WHETHER THE DEVICE IS AN ECHO DEVICE OR NOT, AND DEPENDING
*	ON WHETHER THE DEVICE IS ATTACHED OR NOT, AND WHEN
*	ATTACHED, WHETHER THE DEVICE IS ATTACHED TO THE TASK OR NOT.
* 
*	QUEUE ECHO DEVICE FIRST 
* 
TIOQ00	LDR	A6,A2
* 
*	QUEUE DEVICE FIRST
* 
TIOQ05	ADK	A6,DWTTQ	GET QUEUE ANCHOR
	LDR	A2,A6
	LDR*	A6,A6 
	RF	TIOQ40	INSERT FIRST IN QUEUE
* 
TIOQ10	LDR	A6,A2	QUEUE ECHO DEVICE
* 
TIOQ20	ADK	A6,DWTTQ	GET QUEUE ANCHOR
	LD	A1,TTB:ST+1,A5	GET LEVEL
* 
	EJECT			TOSSIO 
* 
*	SEARCH QUEUE FOR PLACE OF INSERTION 
* 
TIOQ30	LDR	A2,A6
	LDR*	A6,A6	FOLLOW QUEUE TO END 
	RF(Z)	TIOQ40	END FOUND?
	CC	A1,TTB:ST+1,A6	COMPARE LEVELS 
	RB(NL)	TIOQ30	TRY NEXT?
* 
*	INSERT IN QUEUE AND UPDATE PROGRAM COUNTER
* 
TIOQ40	LDKL	A3,-4 
	STR	A6,A5	INSERT IN QUEUE
	STR	A5,A2
	ADK	A4,0	SET CR
	RF(Z)	TIOQ50	NO ACTIVATION?
	SUK	A3,2	ACTIVATION
* 
TIOQ50	ADS	A3,TTB:SA,A5	UPDATE PC TO REPEAT LKM 
* 
TIOQ60	EQU	*
	ABL	TDISP	GO TO DISPATCHER 
* 
	EJECT			TOSSIO 
* 
* 
******* 
* TIO * 
******* 
* 
* 
* THIS MODULE IS ENTERED WHEN TERMINAL I/O
* IS REQUIRED. IF A REQUEST CANNOT BE SERVICED
* DUE TO E.G. BUSY DEVICE, THE REQUEST IS QUEUED
* AND THE TERMINAL PROGRAM SET IN WAIT STATE. 
* 
* WHEN RUNNING WITH MMU OPTION SPECIAL DEVICE 
* DEPENDENT SUBROUTINES ARE PERFORMED.
* 
* THIS MODULE IS CALLED BY THE LKM HANDLING MODULE
* WITH THE FOLLOWING PARAMETERS:- 
* 
*  A1 = PARAMETER WHEN I/O AND ACTIVATION 
* 
*  A4 = ZERO, NORMAL I/O REQUEST
*       NOT ZERO, I/O AND ACTIVATION
* 
*  A5 = TTAB ADDRESS
* 
*  A7 = ORDER CODE
* 
*  A8 = ECB ADDRESS 
* 
	EJECT			TOSSIO 
* 
* 
* THE 'TIO'-ROUTINE EXITS TO REQUESTED ACTIVATION DRIVER
* WITH THE FOLLOWING REGISTER VAULES:-
* 
*  A5 = STACK BASE 2 IN DWT 
* 
*  A6 = DWT ADDRESS 
* 
*  A7 = ORDER CODE
* 
*  A8 = ECB ADDRESS 
* 
* A12 = ADDRESS TO DRIVER ADDRESS BLOCK 
* 
* A13 = 0, IF REQUEST ISSUED IN SYSTEM MODE 
*     = 1, "     "      "    "  USER MODE 
* 
* 
* THE FOLLOWING DWT FIELDS ARE UPDATED:-
* 
*  -DWTOR  DWT INDEX AND ORDER
*  -DWTECB ECB ADDRESS
*  -DWTST  READY AND ECHO FIELDS
*  -DWTTAB TTAB ADDRESS 
*  -DWTWAT WAIT/ACTIVATE INDICATOR
*  -DWTUEC USER ECB ADDRESS (MMU SYSTEMS) 
* 
* 
* THE FOLLOWING ECB FIELDS ARE RESET:-
* 
*  -BIT 0 IN THE FIRST WORD 
*  -ECBEL  EFFECTIVE LENGTH 
*  -ECBRC  RETURN CODE
* 
	EJECT			TOSSIO 
* 
*	GET DWT ADDRESS AND CHECK IF REQUEST IS BUSY
* 
TIO	CF	A15,FNDDWT	SEARCH DWT ADDRESS
	LDKL	A3,/8000
	ADK	A6,0	SET CR
	RB(Z)	TIOERR	FILE CODE UNKNOWN?
	LD	A12,DWTADR,A6	GET ADDRESS TO DRIVER ADDRESS BLOCK 
	LD	A13,DWTST,A6	GET DWT STATUS 
*			START OF =1 
	IFT	ATTDET=1 
	LDKL	A10,/0800	ATTACH BIT
	ANK	A7,/FF 
	SUK	A7,/BB 
	RB(Z)	ATTACH	ATTACH ORDER? 
	SUK	A7,1 
	RB(Z)	DETACH	DETACH ORDER? 
	ADK	A7,/BC	RESTORE ORDER CODE
	XIF
*			END OF =1 
	LD	A11,TTB:ID,A5	GET TASK ID 
	ANKL	A11,/FF44 
	SUKL	A11,'#D'	CHECK TASK ID
	RF(Z)	TIO020	DMTASK CALLING? 
	LDKL	A9,/4000	REQUEST BUSY BIT 
	TM	A9,A13
	RB(NZ)	TIOQ20	REQUEST BUSY?
* 
	EJECT			TOSSIO 
* 
*	CHECK IF DEVICE IS ATTACHED/BUSY
* 
	IFT	ATTDET=1 
	TM	A10,A13 
	RF(Z)	TIO020	NOT ATTACHED? 
	CW	A5,DWTTAB,A6
	RB(NE)	TIOQ20	ATTACHED TO OTHER TASK?
	TM	A3,A13
	RF(NZ)	TIO030	DEVICE NOT BUSY? 
	RB	TIOQ05	BUSY, QUEUE DEVICE 
	XIF
* 
TIO020	EQU	*
	TM	A3,A13
	RB(Z)	TIOQ20	DEVICE BUSY?
* 
	EJECT			TOSSIO 
* 
*	CHECK IF ECHO, AND WHEN TRUE CHECK IF ECHO DEVICE IS BUSY/ATTACHED
* 
TIO030	SC	A2,DWTOR,A6	STORE DWT INDEX 
	LDK	A2,/40	CHECK IF ECHO 
	ANR	A2,A7
	RF(Z)	TIO070	NOT ECHO? 
	CWK	A12,TIODM
	RF(NE)	TIO040	JUMP IF NOT DM REQUEST 
	LDKL	A3,/A000	BUSY AND EA BITS FOR DM
	RF	TIO070
* 
TIO040	LD	A2,DWTECH,A6	GET ECHO DEVICE DWT
	RF(Z)	TIO070	NO ECHO DEVICE? 
	LD	A9,DEVIND,A12	GET DEVICE INDEX
	CWK	A9,KB:DIX	CHECK IF KEYBOARD
	RF(NE)	TIO070	ECHO NOT ALLOWED IF NOT KEYBOARD 
	LD	A14,DWTST,A2	GET ECHO DWT STATUS
* 
	IFT	ATTDET=1 
	TM	A10,A14 
	RF(Z)	TIO050	ECHO DEVICE NOT ATTACHED? 
	CW	A5,DWTTAB,A2
	RB(NE)	TIOQ10	ECHO DEVICE ATTACHED TO OTHER TASK?
	TM	A3,A14
	RF(NZ)	TIO060	ECHO DEVICE NOT BUSY?
	RB	TIOQ00	BUSY, QUEUE ECHO DEVICE
	XIF
* 
	EJECT			TOSSIO 
* 
* 
TIO050	TM	A3,A14
	RB(Z)	TIOQ10	ECHO DEVICE BUSY? 
* 
TIO060	LDKL	A3,/A000
	XRS	A3,DWTST,A2	UPDATE BUSY & ECHO BITS IN DWT STATUS
* 
*	UPDATE ECB AND DWT FIELDS 
* 
TIO070	XRS	A3,DWTST,A6	UPDATE BUSY & ECHO BITS IN DWT STATUS
* 
	IFT	MMUPAG=1 
	LD	A13,TTB:PW,A5	GET PSW 
	ANKL	A13,1	GET SYSTEM/USER MODE BIT
	RF(NZ)	TIO100	JUMP IF USER MODE
	LDKL	A2,/7FFF
	ANRS	A2,A8	RESET BIT 0 IN ECB FILE CODE
	ST	A8,DWTECB,A6	SET ACTUAL ECB ADDRESS 
	CM	ECBEL,A8	 RESET EFFECTIVE LENGTH
	CM	ECBRC,A8	 RESET RETURN CODE 
	RF	TIO110
* 
	EJECT			TOSSIO 
* 
*	MOVE USER ECB TO DWT ECB
* 
TIO100	EQU	*
	LDKL	A2,/4FFF
	ELR	A3,A8	LOAD FIRST WORD OF USER ECB
	ANR	A3,A2	RESET BITS 0,2,3 IN ECB FILE CODE
	ESR	A3,A8
	LD	A2,DWTMEC,A6	GET DWT MMU ECB ADDRESS
	ST	A2,DWTECB,A6	SET ACTUAL ECB ADDRESS 
	STR	A3,A2
	ST	A8,DWTUEC,A6	SAVE USER ECB ADDRESS
	LDR	A9,A8
	LDK	A3,0 
	ES	A3,ECBEL,A8	RESET EFFECTIVE LENGTH
	ES	A3,ECBRC,A8	RESET RETURN CODE 
* 
	LDR	A10,A1	SAVE PARAMETER
	LDR	A1,A8
	ADK	A1,ECBRL 
	LDR	A8,A2	SET A8 TO DWT ECB ADDRESS
	ADK	A2,ECBRL 
	LDK	A3,8 
	MVUS	A3	MOVE PART OF USER ECB TO DWT ECB 
	LDR	A1,A10	RESTORE PARAMETER 
	XIF
* 
	IFT	MMUPAG=0 
	LDKL	A3,/7FFF
	ANRS	A3,A8	RESET BIT 0 IN ECB FILE CODE
	CM	ECBEL,A8	 RESET EFFECTIVE LENGTH
	CM	ECBRC,A8	 RESET RETURN CODE 
	XIF
* 
	EJECT			TOSSIO 
* 
* 
TIO110	EQU	*
	LDR	A3,A7	SAVE CODE
	ANK	A7,/3F 
	SC	A7,DWTOR+1,A6	STORE ORDER IN DWT
	CWK	A12,TIODM
	RF(NE)	TIO120	JUMP IF NOT DM REQUEST 
	ST	A5,DWTTDM,A6	SAVE TTAB ADDRESS IN DWTTDM
	RF	TIO130
* 
TIO120	EQU	*
	ST	A5,DWTTAB,A6	SAVE TTAB ADDRESS IN DWTTAB
* 
TIO130	EQU	*
	IFT	MMUPAG=0 
	ST	A8,DWTECB,A6	 SET ECB ADDRESS 
	XIF
* 
*	UPDATE DWTWAT (WAIT/ACTIVATE INDICATOR) 
* 
	LDR	A2,A4	CHECK PARAMETER
	RF(NZ)	TIO210	I/O AND ACTIVATION?
	ANK	A3,/80	NORMAL I/O. CHECK IF WAIT REQUESTED 
	RF(Z)	TIO220	NOT WAIT? 
	LDK	A4,1	INDICATE WAIT 
	RF	TIO230
* 
TIO210	CF	A15,GETBLK	SAVE PARAMETER AND DISPATCH ADDRESS
* 
TIO220	CF	A15,QTJOB	QUEUE TASK FOR DISPATCHING
* 
TIO230	ST	A4,DWTWAT,A6	STORE WAIT/ACTIVATE INDICATOR
* 
	EJECT			TOSSIO 
* 
* 
	IFT	MMUPAG=1 
	LDR	A13,A13	CHECK IF SYSTEM/USER MODE
	RF(Z)	TIO250	JUMP IF SYSTEM MODE 
	LD	A3,DEVIND,A12	GET DEVICE INDEX
	RF(N)	TIO250	NO SPECIAL ACTION REQUIRED? 
	RF(Z)	TIO240	DATA MANAGEMENT?
* 
*	PERFORM CHECK ON ORDER CODE 
* 
	LDR	A4,A7	GET ORDER CODE 
	CF	A15,RD:WR2 	CHECK IF ORDER IS READ/WRITE
	RF(Z)	TIO250	JUMP IF NO READ/WRITE ORDER 
* 
TIO240	EQU	*
	ENB
	CFI	A15,TIOTAB,A3	BRANCH TO RELEVANT READ/WRITE ROUTINE
	XIF
* 
TIO250	ENB		GIVE OTHER TASKS A CHANCE 
* 
TIO260	LDK	A5,DWTSB2	LOAD STACK BASE 2
	ADR	A5,A6
	INH
	ABR*	A12	GO TO DRIVER ACTIVATION 
* 
	EJECT			TOSSIO 
* 
* 
	IFT	MMUPAG=1 
* 
*	R D : W R 
* 
* THIS MODULE IS CALLED BY 'TIO' AND 'TENDIO' FOR SELECTING 
* THE APPROPRIATE ROUTINE AT READ/WRITE REQUESTS, DEPENDING 
* ON THE DEVICE CONNECTION (PROGRAMMED CHANNEL, MUX ETX). 
* IF NO READ/WRITE REQUEST, CONDITION REGISTER ON STACK IS
* SET TO ZERO, ELSE NOT EQUAL TO ZERO.
* 
* INPUT:  A3 = DEVICE INDEX 
*         A6 = DWT ADDRESS
* 
* OUTPUT: A3 = INDEX FOR USE IN THE INDEXED BRANCHING 
*         CR = 0 IF NO READ/WRITE REQUEST 
*         CR <> 0 IF READ/WRITE REQUEST 
*	 A4 IS DESTROYED
* 
RD:WR	LD	A4,DWTOR,A6	GET ORDER CODE FROM DWT
	ANK	A4,/3F 
* 
RD:WR2	ADKL	A15,4	ADJUST STACKPOINTER 
	LC	A4,ORDTAB,A4	GET ORDER INDEX
	ANK	A4,/FF 
	ABR(Z)*	A15	RETURN IF NO READ/WRITE ORDER
	SUK	A4,1 
	ADR	A3,A4	ADD READ/WRITE INDEX 
	ABR*	A15	RETURN WITHOUT CHANGING CR
* 
	EJECT			TOSSIO 
* 
* 
**********
* ORDTAB *
**********
* 
*	ORDTAB CONTAINS ORDER CONSTANTS AS FOLLOWS: 
* 
* 	=0: NO READ/WRITE ORDER
* 	=1: READ ORDER 
* 	=TINDEX+1: WRITE ORDER 
* 
ORDTAB	EQU	*	ORDER CONSTANTS
	BYTES	0,1	/00, /01 
	BYTES	1,1	/02, /03 
	BYTES	0,TINDEX+1	/04, /05
	BYTES	TINDEX+1,TINDEX+1	/06, /07 
	BYTES	TINDEX+1,0	/08, /09
	BYTES	1,TINDEX+1	/0A, /0B
	BYTES	0,0	/0C, /0D 
	BYTES	0,0	/0E, /0F 
	BYTES	0,1	/10, /11 
	BYTES	0,0	/12, /13 
	BYTES	0,TINDEX+1	/14, /15
	BYTES	0,0	/16, /17 
	BYTES	0,0	/18, /19 
	BYTES	0,0	/1A, /1B 
	BYTES	0,0	/1C, /1D 
	BYTES	0,0	/1E, /1F 
	BYTES	0,TINDEX+1	/20, /21
	BYTES	TINDEX+1,0	/22, /23
	BYTES	0,0	/24, /25 
	BYTES	0,0	/26, /27 
	BYTES	0,0	/28, /29 
	BYTES	0,0	/2A, /2B 
	BYTES	0,1	/2C, /2D 
	BYTES	1,TINDEX+1	/2E, /2F
	BYTES	0,0	/30, /31 
	BYTES	0,0	/32, /33 
	BYTES	0,0	/34, /35 
	BYTES	0,0	/36, /37 
	BYTES	0,0	/38, /39 
	BYTES	0,0	/3A, /3B 
	BYTES	0,0	/3C, /3D 
	BYTES	0,0	/3E, /3F 
* 
	EJECT			TOSSIO 
* 
*	T I O : D M 
* 
* THIS MODULE IS CALLED BY 'TIO' WHEN A REQUEST 
* FOR DATA MANAGEMENT HAS BEEN ISSUED.
* 
* INPUT:  A8 = FDB MMU ECB ADDRESS
*         A9 = USER ECB ADDRESS 
* 
* OUTPUT: A2 IS DESTROYED 
* 
TIO:DM	EQU	*	DATA MANAGEMENT, INPUT/OUTPUT
	EL	A2,ECBBA,A9	GET USER BUFFER ADDRESS 
	ST	A2,ECBBA,A8 
	EL	A2,ECBCW2,A9	GET SECOND CONTROL WORD
	ST	A2,ECBCW2,A8
* 
A15RTN	EQU	*
	RTN	A15
* 
	EJECT			TOSSIO 
* 
*	T I O P C I 
* 
* THIS MODULE IS CALLED BY 'TIO' WHEN A READ REQUEST HAS BEEN 
* ISSUED AND THE DEVICE IS RUNNING ON PROGRAMMED CHANNEL. 
* TIOPCI CHECKS USER AND DWT BUFFER ADDRESSES SO THAT BOTH ARE
* EVEN OR UNEVEN, DEPENDING ON THE USER BUFFER ADDRESS. 
* THE CORRESPONDING MODULE CALLED BY 'TENDIO' AT
* COMPLETION OF THE REQUEST IS 'TENPCI'.
* NOTICE THAT ENTRY TIPI05 IS USED BY 'TIOKBI'. 
* 
* INPUT:  A8 = DWT ECB ADDRESS
*         A9 = USER ECB ADDRESS 
*	A12 = ADDRESS TO DRIVER ADDRESS BLOCK 
* 
* OUTPUT: A1 IS DESTROYED 
* 
TIOPCI	EQU	*	PROGRAMMED CHANNEL, INPUT
	LD	A1,ECBRL,A8	GET REQUESTED LENGTH
	CW	A1,BUFLEN,A12	COMPARE WITH DWT BUFFER SIZE
	RF(G)	IO:ERR	REQ. LENGTH EXCEEDS DWT BUFFER SIZE?
* 
TIPI05	EQU	*	ENTRY POINT USED BY 'TIOKBI' 
	EL	A1,ECBBA,A9	GET USER BUFFER ADDRESS 
	ANK	A1,1 
	RF(Z)	TIPI10	USER BUFFER ADDRESS EVEN? 
	ORS	A1,ECBBA,A8
	RTN	A15
* 
TIPI10	SUK	A1,2	MAKE DWT BUFFER ADDRESS EVEN
	ANS	A1,ECBBA,A8
	RTN	A15
* 
	EJECT			TOSSIO 
* 
*	T I O M X I 
* 
* THIS MODULE IS CALLED BY 'TIO' WHEN A READ REQUEST HAS BEEN 
* ISSUED AND THE DEVICE IS RUNNING ON MULTIPLEXOR CHANNEL.
* TIOMXI ASSEMBLES THE FULL 18 BIT BUFFER ADDRESS WHICH IS
* TRANSFERRED TO THE MUX BY THE DRIVER. 
* THE CORRESPONDING MODULE CALLED BY 'TENDIO' AT
* COMPLETION OF THE REQUEST IS 'TENMXI'.
* NOTICE THAT MODULE 'TIOMXO' IS EQUAL TO TIOMXI. 
* 
* INPUT:  A5 = TTAB ADDRESS 
*         A8 = DWT ECB ADDRESS
*	 A9 = USER ECB ADDRESS
* 
* OUTPUT: A1-A2 ARE DESTROYED 
*         18 BIT USER BUFFER ADDRESS IS TRANSFERRED TO DWT ECB
* 
TIOMXI	EQU	*	MUX, INPUT 
	EL	A1,ECBBA,A9	GET USER BUFFER ADDRESS 
	ECR	A2,A1
	ANKL	A1,/FFF	SKIP 4 LEFTMOST BITS
	SRL	A2,3 
	ANK	A2,/1E	MMUTAB INDEX (5 BITS) 
	ADR	A2,A5	ADD TTAB ADDRESS 
	LC	A2,TTB:MT,A2	GET PHYSICAL PAGE ADDRESS
	SRL	A2,2 
	ANK	A2,/3F 
	SCR	A2,A8	STORE BITS 16-17 IN DWT ECB 1ST WORD 
	ANK	A2,/0F 
	SRC	A2,4 
	ORR	A1,A2
	ST	A1,ECBBA,A8	STORE MODIFIED BUFFER ADDRESS 
	RTN	A15
* 
	EJECT			TOSSIO 
* 
*	T I O K B I 
* 
* THIS MODULE IS CALLED BY 'TIO' WHEN A READ REQUEST HAS BEEN 
* ISSUED AND THE DEVICE IS KEYBOARD/CTW. TIOKBI WILL SET BUFFER ADDRESSES 
* AND MOVE KEYTABLE (IF ANY) BY USING ENTRY TIPI05
* IN 'TIOPCI' AND ENTRY TIPO05 IN 'TIOPCO'. 
* THE CORRESPONDING MODULE CALLED BY 'TENDIO' AT
* COMPLETION OF THE REQUEST IS 'TENKBI'.
* 
* INPUT:  A6 = DWT ADDRESS
*	 A7 = ORDER CODE
*         A8 = DWT ECB ADDRESS
*	 A9 = USER ECB ADDRESS
*	A12 = ADDRESS TO DRIVER ADDRESS BLOCK 
* 
* OUTPUT: A1-A4 ARE DESTROYED 
* 
TIOKBI	EQU	*	KEYBOARD/CTW 
	LD	A1,ECBRL,A8	GET REQUESTED LENGTH
	CW	A1,BUFLEN,A12	COMPARE WITH DWT BUFFER SIZE
	RF(G)	IO:ERR	REQ. LENGTH EXCEEDS DWT BUFFER SIZE?
	CF	A15,TIPI05	CHECK AND CORRECT BUFFER ADDRESSES 
	CWK	A7,1	CHECK ORDER CODE
	RF(E)	TIKB20	NO KEYTABLE IF BASIC READ 
	LD	A4,ECBCW,A8	GET USER KEYTABLE ADDRESS 
	RF(Z)	TIKB20	NO KEYTABLE?
* 
	EJECT			TOSSIO 
* 
* 
	LDR	A1,A9
	ADK	A1,8 
	ADKL	A8,12 
	ST	A8,-2,A8	SET DWT KEYTABLE ADDRESS 
	SUKL	A8,4
	ELR	A3,A4	GET FIRST WORD OF USER KEYTABLE
	ANK	A4,1 
	RF(NZ)	TIKB10	KEYTABLE ADDRESS UNEVEN? 
	ECR	A3,A3	NO, PUT LENGTH IN RIGHT BYTE 
* 
TIKB10	ANK	A3,/FF	SKIP LEFT CHARACTER 
	ADK	A3,1 
	CW	A3,KEYLEN,A12	CHECK KEYTABLE BUFFER SIZE
	RF(G)	IO:ERR	TOO SMALL?
	CF	A15,TIPO05
	SUKL	A8,8	ADJUST DWT ECB ADDRESS 
* 
TIKB20	EQU	*
	RTN	A15
* 
	EJECT			TOSSIO 
* 
*	T I O I T I 
* 
TIOITI	EQU	A15RTN	INTERTASK COMMUNICATION, INPUT
* 
	EJECT			TOSSIO 
* 
*	T I O P C O 
* 
* THIS MODULE IS CALLED BY 'TIO' WHEN A WRITE REQUEST HAS BEEN
* ISSUED AND THE DEVICE IS RUNNING ON PROGRAMMED CHANNEL. 
* TIOPCO CHECKS THAT REQUESTED LENGTH DOES NOT EXCEED THE DWT 
* BUFFER LENGTH, AND PERFORMS A MOVE OF THE CONTENTS OF THE USER
* BUFFER TO THE DWT BUFFER. 
* THE CORRESPONDING MODULE CALLED BY 'TENDIO' AT
* COMPLETION OF THE REQUEST IS 'TENPCO'.
* NOTICE THAT MODULE 'TIOKBO' IS EQUAL TO TIOPCO. 
* NOTICE ALSO THAT ENTRY TIPO05 IS USED BY 'TIOKBI' AND 'TENITO'. 
* TIOPCO IS ALSO USED BY 'DC:MOT'.
* 
* INPUT:  A6 = DWT ADDRESS
*         A8 = DWT ECB ADDRESS
* 
* OUTPUT: A1-A4 ARE DESTROYED 
* 
TIOPCO	EQU	*	PROGRAMMED CHANNEL, OUTPUT 
	LD	A2,DWTADR,A6	GET ADDRESS TO DRIVER ADDRESS BLOCK
	LD	A3,ECBRL,A8	GET REQUESTED LENGTH
	RF(NP)	TIPO20	REQUESTED LENGTH <= 0? 
	CW	A3,BUFLEN,A2	COMPARE WITH DWT BUFFER SIZE 
	RF(G)	IO:ERR	REQ. LENGTH EXCEEDS DWT BUFFER SIZE?
	LD	A1,DWTUEC,A6	GET USER ECB ADDRESS 
* 
	EJECT			TOSSIO 
* 
* 
TIPO05	EQU	*	ENTRY POINT USED BY 'TIOKBI' AND 'TENITO'
	ADK	A3,1 
	ANKL	A3,/FFFE	MAKE REQUESTED LENGTH EVEN 
	EL	A1,ECBBA,A1	GET USER BUFFER ADDRESS 
	LD	A2,ECBBA,A8	GET DWT BUFFER ADDRESS
	ANKL	A2,/FFFE	MAKE DWT BUFFER ADDRESS EVEN 
	LDR	A4,A1
	ANK	A4,1 
	RF(NZ)	TIPO30	USER BUFFER ADDRESS UNEVEN?
	ST	A2,ECBBA,A8 
* 
TIPO10	MVUS	A3	MOVE (USER BUFFER) TO SYSTEM BUFFER
* 
TIPO20	RTN	A15
* 
TIPO30	EQU	*	USER BUFFER ADDRESS WAS UNEVEN 
	ORS	A4,ECBBA,A8	MAKE DWT BUFFER ADDRESS UNEVEN 
	ELR	A4,A1	GET FIRST CHARACTER FROM USER BUFFER 
	STR	A4,A2	STORE FIRST CHARACTER IN DWT BUFFER
	ADK	A1,1	UPDATE USER BUFFER POINTER
	ADK	A2,2	UPDATE DWT BUFFER POINTER 
	RB	TIPO10	MOVE REMAINING CHARACTERS
* 
	EJECT			TOSSIO 
* 
*	I O : E R R 
* 
* DRIVER (DWT) MMU BUFFER IS TOO SMALL. 
* SET RETURN CODE /8008 (REQUEST ERROR AND INCORRECT LENGTH). 
* BRANCH TO DISPATCHER VIA TENDIO.
* 
IO:ERR	EQU	*	REQUEST ERROR EXIT FOR MMU ROUTINES
	INH
 	ADKL	A15,4	ADJUST STACKPOINTER
	LD	A1,DWTST,A6	GET DWT STATUS
	SLL	A1,2	CHECK ECHO BIT
	RF(NN)	IO:E10	NOT ECHO?
	LDR	A1,A6	SAVE DWT ADDRESS 
	LD	A6,DWTECH,A6	GET ECHO DWT ADDRESS 
	CF	A15,TENDIO
	LDR	A6,A1	RESTORE DWT ADDRESS
* 
IO:E10	EQU	*
	LDKL	A1,/8008	SET RETURN CODE
	ABL	DISEND	BRANCH TO DISPATCHER VIA TENDIO 
* 
	EJECT			TOSSIO 
* 
*	T I O M X O 
* 
TIOMXO	EQU	TIOMXI	MUX, OUTPUT 
* 
*	T I O K B O 
* 
TIOKBO	EQU	TIOPCO	KEYBOARD/CTW, OUTPUT
* 
*	T I O I T O 
* 
TIOITO	EQU	A15RTN	INTERTASK COMMUNICATION, OUTPUT 
* 
	EJECT			TOSSIO 
* 
*	T E N : D M 
* 
* THIS MODULE IS CALLED BY 'TENDIO' WHEN A REQUEST
* FOR DATA MANAGEMENT HAS BEEN COMPLETED. 
* 
* INPUT:  A6 = FDB ADDRESS
*         A8 = USER ECB ADDRESS 
* 
* OUTPUT: A1-A2 ARE DESTROYED 
* 
TEN:DM	EQU	*	DATA MANAGEMENT, INPUT/OUTPUT
	LD	A1,DWTMEC,A6	GET FDB MMU ECB ADDRESS
	EL	A2,ECBCW2,A8
	LC	A2,ECBCW2+1,A1
	ES	A2,ECBCW2,A8
	RTN	A15
* 
	EJECT			TOSSIO 
* 
*	T E N P C I 
* 
* THIS MODULE IS CALLED BY 'TENDIO' WHEN A READ REQUEST HAS BEEN
* COMPLETED AND THE DEVICE IS RUNNING ON PROGRAMMED CHANNEL.
* TENPCI PERFORMS A MOVE OF THE CONTENTS OF THE DWT BUFFER TO THE 
* USER BUFFER. THE CORRESPONDING MODULE CALLED BY 'TIO' AT
* ISSUING THE REQUEST IS 'TIOPCI'.
* NOTICE THAT MODULES 'TENKBI' AND 'TENITI' ARE EQUAL TO TENPCI.
* NOTICE ALSO THAT ENTRY TEN:DC IS USED BY 'DC:MIN'.
* 
* INPUT:  A6 = DWT ADDRESS
*         A8 = USER ECB ADDRESS 
* 
* OUTPUT: A1-A4, A8 ARE DESTROYED 
* 
TENPCI	EQU	*	PROGRAMMED CHANNEL, INPUT
	LD	A2,DWTECB,A6	GET DWT ECB ADDRESS
	LD	A4,ECBEL,A2	GET EFFECTIVE LENGTH
	RF(NP)	TEPI30	NO MOVE IF ZERO
	LD	A1,ECBBA,A2	GET DWT BUFFER ADDRESS
* 
TEN:DC	EQU	*	ENTRY POINT USED BY 'DC:MIN' 
	EL	A2,ECBBA,A8	GET USER BUFFER ADDRESS 
	LDK	A3,1	CHECK BUFFER ADDRESSES
	TM	A3,A1 
	RF(Z)	TEPI20	DWT BUFFER ADDRESS EVEN?
	TM	A3,A2	NO, CHECK USER BUFFER ADDRESS 
	RF(Z)	TEPI60	USER BUFFER ADDRESS EVEN? 
* 
	EJECT			TOSSIO 
* 
* 
TEPI10	EQU	*	BOTH BUFFER ADDRESSES WERE UNEVEN
 	LDR*	A3,A1	GET FIRST CHARACTER FROM DWT BUFFER
	ELR	A8,A2
* 
TEPI15	ANK	A3,/FF	SKIP LEFT CHARACTER 
	ANKL	A8,/FF00	SKIP RIGHT CHARACTER 
	ORR	A8,A3
	ESR	A8,A2	STORE CHARACTER IN USER BUFFER 
	ADK	A1,1	UPDATE BUFFER POINTERS
	ADK	A2,1 
	SUK	A4,1 
	RF(P)	TEPI25	MORE CHARACTERS TO MOVE?
	RTN	A15	NO, RETURN 
* 
TEPI20	TM	A3,A2 
	RF(Z)	TEPI25	USER BUFFER ADDRESS EVEN? 
	LDR	A3,A1	GET DWT BUFFER ADDRESS 
	ADR	A3,A4	ADD EFFECTIVE LENGTH 
* 
TEPI23	LC	A8,-1,A3	GET ONE CHARACTER
	SCR	A8,A3	MOVE THIS CHAR. ONE BYTE TO THE RIGHT
	SUK	A3,1	POINT TO NEXT CHARACTER 
	CWR	A3,A1	COMPARE WITH START ADDRESS OF BUFFER 
	RB(NE)	TEPI23	MORE CHARACTERS TO MOVE? 
	ADK	A1,1	NO, MAKE DWT BUFFER ADDRESS UNEVEN
	RB	TEPI10
* 
	EJECT			TOSSIO 
* 
* 
TEPI25	LDR	A3,A4	CHECK REQUESTED LENGTH 
	ANK	A3,1 
	RF(NZ)	TEPI40	EFFECTIVE LENGTH UNEVEN? 
	MVSU	A4	MOVE (SYSTEM BUFFER) TO USER BUFFER
* 
TEPI30	RTN	A15
* 
TEPI40	EQU	*	EFFECTIVE LENGTH WAS UNEVEN
	SUK	A4,1	MAKE EFFECTIVE LENGTH EVEN
	RF(Z)	TEPI50	ONLY ONE CHARACTER TO MOVE? 
	LDR	A8,A4	NO, SAVE A4
	MVSU	A4	MOVE (SYSTEM BUFFER) TO USER BUFFER
	ADR	A1,A8	UPDATE BUFFER POINTERS 
	ADR	A2,A8
* 
TEPI50	EQU	*
	LDR*	A8,A1	GET LAST CHARACTER FROM DWT BUFFER
	ELR	A3,A2
	RB	TEPI15
* 
TEPI60	EQU	*	DWT BUFFER ADDRESS WAS UNEVEN
	LDR	A3,A1	GET DWT BUFFER ADDRESS 
	ADR	A1,A4	ADD EFFECTIVE LENGTH 
* 
TEPI70	LCR	A8,A3	GET ONE CHARACTER
	SC	A8,-1,A3	MOVE THIS CHAR. ONE BYTE TO THE LEFT 
	ADK	A3,1	POINT TO NEXT CHARACTER 
	CWR	A3,A1	COMPARE WITH ENDING ADDRESS
	RB(NE)	TEPI70	MORE CHARACTERS TO MOVE? 
	SUR	A1,A4	NO, RESTORE DWT BUFFER ADDRESS 
	SUK	A1,1	MAKE DWT BUFFER ADDRESS EVEN
	RB	TEPI25
* 
	EJECT			TOSSIO 
* 
*	T E N M X I 
* 
TENMXI	EQU	A15RTN	MUX, INPUT
* 
*	T E N K B I 
* 
TENKBI	EQU	TENPCI	KEYBOARD, INPUT 
* 
*	T E N I T I 
* 
TENITI	EQU	TENPCI	INTERTASK COMMUNICATION, INPUT
* 
*	T E N P C O 
* 
TENPCO	EQU	A15RTN	PROGRAMMED CHANNEL, OUTPUT
* 
*	T E N M X O 
* 
TENMXO	EQU	A15RTN	MUX, OUTPUT 
* 
*	T E N K B O 
* 
TENKBO	EQU	A15RTN	KEYBOARD/CTW, OUTPUT
* 
	EJECT			TOSSIO 
* 
*	T E N I T O 
* 
* THIS MODULE IS CALLED BY 'TENDIO' WHEN A WRITE REQUEST HAS BEEN 
* COMPLETED FOR INTERTASK COMMUNICATION, IN PURPOSE TO MOVE THE CONTENTS
* OF THE USER BUFFER TO THE DRIVER BUFFER. THE ENTRY TIPO05 IN MODULE 
* 'TIOPCO' IS USED FOR MOVING THE DATA. 
* 
* INPUT:  A6 = DWT ADDRESS
* 
* OUTPUT: A1-A4, A8 ARE DESTROYED 
* 
TENITO	EQU	*	INTERTASK COMMUNICATION, OUTPUT
	LD	A8,DWTECB,A6	GET DWT ECB ADDRESS
	LD	A3,ECBEL,A8	GET EFFECTIVE LENGTH
	RF(NP)	TEIO10	NO MOVE? 
	LD	A1,DWTUEC,A6	GET USER ECB ADDRESS 
	CF	A15,TIPO05	MOVE BUFFER CONTENTS 
* 
TEIO10	RTN	A15
* 
	EJECT			TOSSIO 
* 
*	D C : M O T 
* 
* THIS MODULE IS CALLED BY THE DATA COMMUNICATION DRIVER
* IN PURPOSE TO MOVE THE CONTENTS OF THE USER BUFFER TO 
* THE DRIVER BUFFER. THE MOVE ROUTINE IN MODULE 'TIOPCO'
* IS USED FOR MOVING THE DATA.
* 
* INPUT:  A6 = DWT ADDRESS
* 
* OUTPUT: NO REGISTERS ARE DESTROYED
* 
DC:MOT	EQU	*	DATA COMMUNICATION, OUTPUT 
	MSR	8,A15	SAVE A1-A8 ON STACK
	SUKL	A15,32	ADJUST STACKPOINTER
	TS	2,A15	SAVE MMU REGISTERS ON STACK 
	LD	A5,DWTTAB,A6	GET TTAB ADDRESS 
	TL	TTB:MT,A5	LOAD MMU REGISTERS
	LD	A8,DWTMEC,A6	GET DWT ECB ADDRESS
	ENB
	CF	A15,TIOPCO	MOVE BUFFER CONTENTS 
* 
DC:RTN	EQU	*	RETURN TO DC DRIVER
	TL	2,A15	RESTORE MMU REGISTERS FROM STACK
	ADKL	A15,32	ADJUST STACKPOINTER
	MLR	8,A15	RESTORE A1-A8 FROM STACK...
	RTN	A15	...AND RETURN
	XIF
* 
	EJECT			TOSSIO 
* 
*	D C : M I N 
* 
* THIS MODULE IS CALLED BY THE DATA COMMUNICATION DRIVER
* IN PURPOSE TO MOVE THE CONTENTS OF THE DRIVER BUFFER TO THE USER BUFFER.
* 
* INPUT:  A1 = RETURN CODE
*         A4 = DRIVER BUFFER ADDRESS
*         A6 = DWT ADDRESS
* 
* OUTPUT: NO REGISTERS ARE DESTROYED
* 
DC:MIN	EQU	*
	IFT	MMUPAG=0 
	IFT	CPU852=1 
	CF	A15,SAVE8	SAVE A1-A8 ON STACK 
	XIF
* 
	IFT	CPU852=0 
	MSR	8,A15	SAVE A1-A8 ON STACK
* 
	IFT	MMUPAG=1 
	SUKL	A15,32	ADJUST STACKPOINTER
	TS	2,A15	SAVE MMU REGISTERS ON STACK 
	LD	A5,DWTTAB,A6	TTAB ADDRESS 
	TL	TTB:MT,A5	LOAD MMU REGISTERS
	XIF
* 
	EJECT			TOSSIO 
* 
*	CHECK MESSAGE LENGTH AND DECIDE 
*	IF TTMJOB IS TO BE ACTIVATED. 
* 
	LD	A3,DWTECB,A6	ECB ADDRESS
* 
	IFT	MMUPAG=0 
	LD	A5,ECBBA,A3	USER BUFFER ADDRESS 
* 
	IFT	CPU852=1 
	LDK	A7,128	852 CPU 
	ANK	A5,1	CHECK USER BUFFER ADDRESS 
	RF(NZ)	DCMI00	USER BUFFER ADDRESS UNEVEN 
	ADK	A7,128	A7 := 256 
	XIF
* 
	IFT	MMUPAG=0 
	IFT	CPU852=0 
	IFT	CPU857=0 
	LDK	A7,80	851 CPU
	ANK	A5,1	CHECK USER BUFFER ADDRESS 
	RF(NZ)	DCMI00	USER BUFFER ADDRESS UNEVEN 
	ADK	A7,120	A7 := 200 
	XIF
* 
	IFT	MMUPAG=0 
	IFT	CPU852=0 
	IFT	CPU857=1 
	LDKL	A7,256	857 CPU
	ANK	A5,1	CHECK USER BUFFER ADDRESS 
	RF(NZ)	DCMI00	USER BUFFER ADDRESS UNEVEN 
	ADR	A7,A7	A7 := 512
	XIF
* 
	EJECT			TOSSIO 
* 
* 
	IFT	MMUPAG=1 
	LD	A5,DWTUEC,A6	USER ECB ADDRESS 
	EL	A5,ECBBA,A5	USER BUFFER ADDRESS 
	LDKL	A7,256
	ANK	A5,1	CHECK USER BUFFER ADDRESS 
	RF(NZ)	DCMI00	USER BUFFER ADDRESS UNEVEN 
	SLL	A7,3	A7 := 2048
	XIF
* 
DCMI00	EQU	*
	CW	A7,ECBEL,A3	CHECK IF USER BUFFER IS LARGE ENOUGH
	RF(L)	QMTASK	LONG MOVE, ACTIVATE MONITOR TASK
	CF	A15,MINMOV	MOVE BUFFER CONTENTS 
* 
DCMRTN	EQU	*	RETURN TO DC DRIVER
	IFT	CPU852=1 
	ABL	IHRET8	RESTORE A1-A8 AND RETURN
	XIF
* 
	IFT	MMUPAG=0 
	IFT	CPU852=0 
	MLR	8,A15	RESTORE A1-A8 FROM STACK...
* 
DC:MOT	RTN	A15	...AND RETURN
	XIF
* 
	IFT	MMUPAG=1 
	RB	DC:RTN	RETURN TO DC DRIVER
	XIF
* 
	EJECT			TOSSIO 
* 
*	M I N M O V 
* 
* INPUT:  A1 = RETURN CODE
*         A3 = ECB ADDRESS
*         A4 = DRIVER BUFFER ADDRESS
*         A6 = DWT ADDRESS
* 
* OUTPUT: A1-A5, A7 ARE DESTROYED 
* 
MINMOV	EQU	*	DC:MIN MOVE ENTRY
	ENB
	LDR	A7,A4	SAVE DRIVER BUFFER ADDRESS 
	LD	A2,ECBEL,A3	EFFECTIVE LENGTH
	RF(NP)	MIN:40	NOTHING TO MOVE
	CW	A2,ECBRL,A3	CHECK IF USER BUFFER IS LARGE ENOUGH
	RF(G)	MIN:70	NO, REQUEST ERROR 
* 
	IFT	MMUPAG=0 
	LD	A5,ECBBA,A3	USER BUFFER ADDRESS 
	LDR	A3,A5
	ANK	A3,1	CHECK USER BUFFER ADDRESS 
	RF(NZ)	MIN:30	USER BUFFER ADDRESS UNEVEN 
	SUK	A2,2 
	RF(N)	MIN:30	ONLY ONE CHARACTER TO MOVE
* 
	EJECT			TOSSIO 
* 
*	WORD MOVE 
* 
MIN:10	EQU	*
	LDR*	A3,A7	MOVE ONE WORD 
	STR	A3,A5
	ADK	A7,2	INCREMENT BUFFER POINTERS 
	ADK	A5,2 
	SUK	A2,2	DECREMENT LOOP COUNTER
	RB(NN)	MIN:10	AT LEAST ONE MORE WORD TO MOVE 
* 
MIN:20	EQU	*
	ADK	A2,1 
	RF(N)	MIN:40	MOVE FINISHED 
* 
*	CHARACTER MOVE
* 
MIN:30	EQU	*
	LCR	A3,A7	MOVE ONE CHARACTER 
	SCR	A3,A5
	ADK	A7,1	INCREMENT BUFFER POINTERS 
	ADK	A5,1 
	SUK	A2,1	DECREMENT LOOP COUNTER
	RB(P)	MIN:30	AT LEAST ONE MORE CHARACTER TO MOVE 
	XIF
* 
	IFT	MMUPAG=1 
	ST	A1,ECBRC,A3	SET RETURN CODE IN ECB
	LDR	A1,A4	DRIVER BUFFER ADDRESS
	LDR	A4,A2	EFFECTIVE LENGTH 
	LD	A8,DWTUEC,A6	USER ECB ADDRESS 
	CF	A15,TEN:DC	MOVE BUFFER CONTENTS 
	LDR	A4,A7	RESTORE BUFFER ADDRESS 
	LDK	A1,0 
	XIF
* 
	EJECT			TOSSIO 
* 
* 
MIN:40	EQU	*
	INH
	CF	A15,TENDIO	PERFORM TENDIO 
* 
*	RELEASE BUFFER
* 
	LD	A1,DWTADR,A6	DRIVER ADDRESS BLOCK 
	LD	A1,POLADR,A1	BUFFER POOL ADDRESS
* 
MIN:50	EQU	*
	LDR	A2,A1	SAVE BUFFER ADDRESS
	LDR*	A1,A2	NEXT BUFFER ADDRESS 
	RB(NZ)	MIN:50	NOT LAST BUFFER IN CHAIN 
* 
*	INSERT BUFFER AT END OF CHAIN 
* 
	SUK	A4,6	REAL BUFFER ADDRESS 
	STR	A4,A2	UPDATE QUEUE LINKS 
	CMR	A4 
	RTN	A15
* 
*	ERROR EXIT
* 
MIN:70	EQU	*	DC:MIN ERROR EXIT
	LDKL	A1,/8008	REQUEST ERROR/INCORRECT LENGTH 
	RB	MIN:40	RETURN VIA TENDIO ETC
* 
	EJECT			TOSSIO 
* 
*	D C M I N T 
* 
* TTMJOB WILL BE DISPATCHED HERE TO CARRY OUT 
* THE MOVE OF THE DC DRIVER BUFFER CONTENTS TO
* THE USER BUFFER. ACTIVATION IS DONE BY 'DC:MIN'.
* 
* INPUT:  A1 = RETURN CODE
*         A3 = DWT ADDRESS
*         A4 = DRIVER BUFFER ADDRESS
* 
DCMINT	EQU	*	TTMJOB MOVE BUFFER ENTRY 
	LDR	A6,A3	DWT ADDRESS
	LD	A3,DWTECB,A6	ECB ADDRESS
* 
	IFT	MMUPAG=1 
	INH
	LD	A5,DWTTAB,A6	TTAB ADDRESS 
	TL	TTB:MT,A5	LOAD MMU REGISTERS
	LDKL	A5,TTMJOB	MONITOR TASK TTAB 
	TS	TTB:MT,A5	SET USER MMU TABLE IN TTMJOB
	XIF
* 
	CF	A15,MINMOV	MOVE BUFFER CONTENTS 
	ABL	MEXIT	EXIT TTMJOB
* 
	EJECT			TOSSIO 
* 
*	Q M T A S K 
* 
* WHEN THE MOVE WILL TAKE TOO LONG TIME TTMJOB WILL BE
* ACTIVATED AT ENTRY 'DCMINT' TO PERFORM THE MOVE.
* THE MOVE TIME DEPENDS ON THE COMPUTER TYPE USED.
* 
* INPUT:  A1 = RETURN CODE
*         A4 = DRIVER BUFFER ADDRESS
*         A6 = DWT ADDRESS
* 
QMTASK	EQU	*	ACTIVATE TTMJOB
	LDKL	A2,DCMINT	DISPATCH ADDRESS
	LDR	A3,A6	DWT ADDRESS
	CF	A15,QMJOB	ACTIVATE TTMJOB 
	LDKL	A1,/8000	NOT BUSY BIT 
	ORS	A1,DWTST,A6	SET DWT FREE 
	RB	DCMRTN	RETURN TO DC DRIVER
* 
	EJECT			TOSSIO 
* 
* 
	IFT	MMUPAG=0 
	IFT	CPU852=1 
DC:MOT	INH
 	ABL	IHRTN	RETURN WITHOUT ENABLING INTERRUPTS
	XIF
* 
	EJECT			TOSSIO 
* 
* 
**********
* TENDIO *
**********
* 
* 
* THIS MODULE IS CALLED WHEN COMPLETION OF
* I/O OCCURS. 
* 
* - IF I/O AND ACTIVATION REQUEST:- 
* 
*   ACTOTP IS CALLED TO START THE TASK
* 
* -IF NORMAL I/O WITH WAIT:-
* 
*   QTJOB IS CALLED TO QUEUE THE TASK 
*   FOR DISPATCHING WITH THE FOLLOWING PARAMETERS:- 
* 
*   A5 = TTAB ADDRESS 
* 
* -IF NORMAL I/O WITH NO WAIT:- 
* 
*   NO ACTION REQUIRED
* 
* IF AN EVENT WAS QUEUED FOR THIS DEVICE (DWTTQ NOT ZERO) 
* THAT TASK IS PUT IN DISPATCHER QUEUE TO REPEAT THE LKM INSTRUCTION. 
* 
	EJECT			TOSSIO 
* 
* 
* ENTRY PARAMETERS TO THIS SUBROUTINE ARE:- 
* 
*   A1 = RETURN CODE
* 
*   A6 = DWT ADDRESS
* 
* NO REGISTERS ARE DESTROYED
* 
* WHEN RUNNING WITH MMU OPTION SPECIAL DEVICE 
* DEPENDENT SUBROUTINES ARE PERFORMED.
* 
	EJECT			TOSSIO 
* 
*	END I/O ENTRY 
* 
TENDIO	EQU	*
	IFT	CPU852=1 
	CF	A15,SAVE8	SAVE A1-A8 ON STACK 
	XIF
* 
	IFT	CPU852=0 
	INH
	MSR	8,A15	SAVE A1-A8 ON STACK
	XIF
* 
TEN090	EQU	*
	ENB
	LDR	A4,A6	DWT ADDRESS
	ADK	A4,DWTST	POINT TO DWT STATUS 
	INH
	LD	A5,DWTTQ,A6	GET TERMINAL QUEUE LINK 
	RF(Z)	TEN110	NO TASK QUEUED? 
	LD	A2,TTB:ID,A5	GET TASK ID
	ANKL	A2,/FF44
	CWK	A2,'#D'	CHECK TASK ID
	RF(E)	TEN100	DM REQUEST NEXT?
	LDKL	A2,/800	ATTACH BIT
	ANR*	A2,A4 
	RF(Z)	TEN100	DEVICE NOT ATTACHED?
	CW	A5,DWTTAB,A6	ATTACHED TO OTHER TASK?
	RF(NE)	TEN110	YES, DON'T QUEUE TASK
* 
	EJECT			TOSSIO 
* 
* 
TEN100	EQU	*
	LDR*	A3,A5	UPDATE QUEUE ANCHOR ADDRESS 
	ST	A3,DWTTQ,A6 
	CF	A15,QTJOB	QUEUE TASK TO REPEAT REQUEST
* 
*	UPDATE ECB AND DWT
* 
TEN110	LD	A5,DWTTAB,A6	GET TTAB ADDRESS FROM DWT
	LDKL	A2,TIODM
	CW	A2,DWTADR,A6
	RF(NZ)	TEN120	NO DM REQUEST? 
	LD	A5,DWTTDM,A6	GET TTAB ADDRESS 
	CF	A15,REQEND	RESET REQUEST BUSY FOR ALL FILES 
* 
TEN120	LDKL	A2,/8000
	ORRS	A2,A4	INDICATE DEVICE READY IN DWT
	LDKL	A3,/DBFF
	ANRS	A3,A4	RESET ECHO BIT AND BIT 5
	LD	A3,DWTECB,A6	GET ECB ADDRESS
	RF(Z)	TEN260	BRANCH IF ENTERED FROM ECHO OR RECOVERY 
* 
	EJECT			TOSSIO 
* 
* 
	ORRS	A2,A3	SET EVENT COMPLETED IN ECB
	ORS	A1,ECBRC,A3	SET RETURN CODE IN ECB 
* 
	IFT	MMUPAG=1 
	LD	A4,TTB:PW,A5	GET PSW
	ANK	A4,1	GET SYSTEM/USER MODE BIT
	RF(Z)	TEN200	SYSTEM MODE?
* 
*	LOAD MMU REGISTERS
* 
TEN130	EQU	*
	SUKL	A15,32	ADJUST STACKPOINTER
	TS	2,A15	SAVE MMU REGISTERS ON STACK 
	TL	TTB:MT,A5	LOAD MMU REGISTERS FROM TTAB
* 
	EJECT			TOSSIO 
* 
*	MOVE DWT ECB TO USER ECB
* 
	LD	A8,DWTUEC,A6	GET USER ECB ADDRESS 
	ELR	A4,A8
	ORR	A4,A2	SET EVENT COMPLETED IN ECB 
	ESR	A4,A8
	LDR	A1,A3
	ADK	A1,ECBEL 
	LDR	A2,A8
	ADK	A2,ECBEL 
	LDK	A4,6 
	MVSU	A4	MOVE EFF. LENGTH, RTN CODE & CNTRL WORD
* 
	LD	A3,DWTADR,A6	GET ADDRESS TO DRIVER ADDRESS BLOCK
	LD	A3,DEVIND,A3	GET DEVICE INDEX 
	RF(N)	TEN160	NO SPECIAL ACTION REQUIRED? 
	RF(Z)	TEN140	DATA MANAGEMENT?
* 
*	PERFORM CHECK ON ORDER CODE 
* 
	CF	A15,RD:WR	CHECK IF IT WAS READ/WRITE
	RF(Z)	TEN160	JUMP IF NO READ/WRITE ORDER 
* 
TEN140	EQU	*
	ENB
	CFI	A15,TENTAB,A3	BRANCH TO RELEVANT READ/WRITE ROUTINE
* 
	EJECT			TOSSIO 
* 
*	RESTORE MMU REGISTERS 
* 
TEN150	EQU	*
	INH
* 
TEN160	EQU	*
	TL	2,A15	RESTORE MMU REGISTERS FROM STACK
	ADKL	A15,32	ADJUST STACKPOINTER
	XIF
* 
	EJECT			TOSSIO 
* 
*	CHECK IF NO WAIT, WAIT, MULTIPLE WAIT OR ACTIVATION 
* 
TEN200	EQU	*
	LD	A4,DWTWAT,A6	GET WAIT/ACTIVATE INDICATOR
	RF(Z)	TEN250	NOT WAIT OR ACTIVATION? 
	SUK	A4,1 
	RF(Z)	TEN240	WAIT? 
	ADK	A4,1 
	LDR	A3,A4
	ANK	A3,1 
	RF(Z)	TEN230	ACTIVATION? 
	LD	A8,DWTECB,A6	GET ECB ADDRESS
* 
	IFT	MMUPAG=1 
	AN	A3,TTB:PW,A5	GET SYSTEM/USER MODE BIT 
	RF(Z)	TEN210	SYSTEM MODE?
	LD	A8,DWTUEC,A6	NO, GET USER ECB ADDRESS 
	XIF
* 
TEN210	EQU	*
	ST	A8,TTB:SA+16,A5	SET TO A8 IN TTAB SAVE AREA 
* 
TEN220	ADK	A4,DWTWAT	POINT TO WAIT/ACTIVATE INDICATOR 
	LDR*	A3,A4	GET NEXT DWT ADDRESS
	RF(Z)	TEN240	NO MORE DWT:S?
	CMR	A4	SET TO NO WAIT AGAIN
	LDR	A4,A3
	RB	TEN220
* 
	EJECT			TOSSIO 
* 
* 
TEN230	EQU	*
	CF	A15,FREBLK	ACTIVATE: GET PARAMETER AND DISP ADDR
	CF	A15,ACTOTP	ACTIVATE TASK ON LIFO BASIS
	RF	TEN250
* 
TEN240	EQU	*
	CF	A15,QTJOB	WAIT: QUEUE TASK FOR DISPATCHING
* 
TEN250	EQU	*
	CM	DWTECB,A6	RESET ECB ADDRESS 
* 
TEN260	EQU	*
	IFT	CPU852=1 
	ABL	IHRET8 
	XIF
* 
	IFT	CPU852=0 
	MLR	8,A15	RESTORE A1-A8 FROM STACK...
	RTN	A15	...AND RETURN
	XIF
* 
* 
* 
	END

Full view