********************************************************************
** NETWORK FILESYSTEM - INTERACTIVE
**
** (c) Spak, Darrell Tam, c9107253@ee.newcastle.edu.au (1994)
** phone (Australia) 049-829-710
**                    49-829-710
** (c) SST 1994
**
** SOFTWARE INTERRUPT - STUFF TO MAKE SHELLS WORK OVER THE NETWORK
**
** HOWEVER CTRL - C, D, E & F ARE MISSED ON REMOTE CONSOLE WINDOWS
**
** Allows the handler to support "con:" type devices used in shells
** All FINDxxx actions are ignored with the filhandle being patched
** (fh_Arg1 = first Arg1) so the result is not an exact duplicate of
** real interactive handlers (ie Open("*",xxx) is actually ignored!)
**
** Under 3.0 & 1.3 (at least) shells open up FINE!
** However 1.3 shells are a bit slooow because 1.3 sends out lines
** at a time, while 3.0 is tricked into thinking the output is a
** file, so it sends out blocks
**
** TABS to 4
********************************************************************/
	opt L+
	opt O+


; if with some future OS, writing to a console window occurs spasmotically
; in BIG chunks then comment out this line - at the moment shells are tricked
; into thinking the output is NONinteractive while the input is, meaning they
; write out several lines in a hit instead of one (improving performance)
; NB under 1.3 there is no difference, using the ARP shell at least
TRICKABLE_OS	= 1


	include "//stone/dazsys/macros.i"
	incdir "include:"
	include "exec/funcdef.i"
	include "exec/types.i"
	include "exec/ports.i"
	include "exec/interrupts.i"
	include "exec/exec_lib.i"
	include "dos/dosextens.i"
	include "dos/dos_lib.i"

	xdef _handle_interactive_stuff
	xdef @handle_interactive_stuff

** INTER-PORT STRUCTURE
	rsset	0
ip_mp			rs.b	MP_SIZE
ip_i			rs.b	IS_SIZE
ip_fa1			rs.l	1			;
ip_pass 		rs.l	1			; host handler's message port
ip_opencount	rs.l	1

********************************************************************
		_handle_interactive_stuff:
		@handle_interactive_stuff:
********************************************************************
; a1 contains the above structure - software interrupt routine
;
; all this has to do is:
; Get the message, put the mp_replyport as msg->mn_Node.ln_Name->dp_port
; put our port into dp_port so they know where to send another message
; check out the packet
; if it is another FINDxxx patch fh_Arg1 & fh_Type to point at us and
; increment the open count
; if it is an action end decrement the open count and pass on the packet
********************************************************************
		movem.l		d0-d7/a0-a6,-(sp)
		getexec										;a6 <== EXEC BASE
		move.l		a1,a4							;a4 <== interport structure

*** GET THE MESSAGE
		move.l		a1,a0							;message port first
		jsr			_LVOGetMsg(A6)					;a0 : d0
		if.l		not,d0,bra,_his_nomore

*** WRITE THE STUFF INTO THE PACKET (PREPARE FOR RETURNING)
		move.l		d0,a1							;a1 <== message (keep)
		move.l		LN_NAME(a1),a3					;a3 <== dos packet message
		move.l		dp_Port(a3),a0					;a0 <== original reply port
		move.l		a0,MN_REPLYPORT(a1)				;fill the reply port for "main"
		move.l		a4,dp_Port(a3)					;put our port in

*** CHECK OUT THE PACKET
		move.l		dp_Arg1(a3),a2					;a2 <== filehandle
		add.l		a2,a2
		add.l		a2,a2							;BTOC
		move.l		dp_Type(a3),d0
		if.l		d0,hi,#$ffff,_his_sendback		; greater than 65000?
		if.w		d0,eq,#ACTION_FINDINPUT,_his_openread
		if.w		d0,eq,#ACTION_FINDOUTPUT,_his_openwrite
		if.w		d0,eq,#ACTION_FINDUPDATE,_his_openwrite
		if.w		d0,eq,#ACTION_END,_his_end
		if.w		d0,eq,#ACTION_WAIT_CHAR,_his_patchwaitchar

*** PASS THE PACKET ALONG TO "MAIN" (OR PUT BACK TO SENDER)
_his_sendback:
		move.l		ip_pass(a4),a0					;send to "main", not return
_his_return:
		jsr			_LVOPutMsg(A6)					;port a0 /msg a1

_his_nomore:
		movem.l (sp)+,d0-d7/a0-a6
		rts


*** PATCH THE FILEHANDLE TO POINT AT OUR PORT & RETURN TO SENDER
_his_openread:
		IFND	TRICKABLE_OS						;CAN'T TRICK -> INTERACTIVE
_his_openwrite:
		ENDC

		move.l	#-1,fh_Interactive(a2)				;read is INTERACTIVE

		IFD		TRICKABLE_OS						;TRICK = NON INTERACTIVE WRITE
_his_openwrite:
		ENDC

		move.l	ip_fa1(a4),fh_Arg1(a2)				;Patch FileHandle Arg1
		move.l	a4,fh_Type(a2)						;make sure the port is US!
		moveq	#-1,d0
		move.l	d0,dp_Res1(a3)
		move.l	d0,dp_Res2(a3)						;return "OK"!
		addq.l	#1,ip_opencount(a4)					;extra open!
		bra.s	_his_return


** CHECK TO SEE IF WE SHOULD REALLY PASS ON THE ACTION_END
_his_end:
		subq.l	#1,ip_opencount(a4)					;one less open
		if		gt,_his_return 						;files opened still
;		clr.l	dp_Port(a3)							;no reply port
		bra.s	_his_sendback

** PATCH THE WAIT CHAR ACTION (dp_Arg2 to contain fh_Arg1)
_his_patchwaitchar:
		move.l	ip_fa1(a4),dp_Arg2(a3)				;patch dp_Arg2 as fh_Arg1
		bra.s	_his_sendback
