license

port_tube. This is object installed by the server. The server is the task providing the info. The terminal is the client. Same convention as the network, inverse convention to X. The control block must exist in duel port. Because of history the port_tube object has to allocated a number. This is the location the control block address is placed in the table pointed to by %port_pbase. The object is created with the string pipe_tube/nn for example to create an object for the operator task:

 
S" pipe_tube/$1F" R/W OPEN-FILE $ABORT
 

Neat or what.

    
	tube class
		m: ( --)
			\ does the unlinking
			this [parent] :destruct
		; overrides :destruct

		\ This will set up up as a normal tube, it is Sopen that converts us to
		\ port_tube
		m: ( number parent--)
			this [parent] :construct
		; overrides :construct
		
		\ you can open the device and particular port with the code
		\ tube_port/nn
		\ this code should receive the string nn.
		\ As the open operation creates the dual port memory area
		\ the device must be opened and closed from a task that has duel
		\ port memory to allocate ( all owned by operator in the begining)
		\ before the device is opened by a task not having the memory to allocate.
		m: ( addr num mode-- handle )
			this :!mode
			\ because thats what out I/O standard expect us to do.
			[CHAR] / remove_leading
			2DUP this :!name
			\ because this is what we want
			Snumber \ number<--
			DUP #port_tube_max < not ABORT" Port number out of range"
			\ Now this may seem strange but we have to take care. 
			DUP CELLS %port_tube_control> +  
			_lock_word 
			@ not IF
				\ We can not store a random number as master side will only test for zero.
				\ This is not 100% correct but as we can no longer save a binary
				\ image of the application it's ok. Run time code is allocating dual
				\ port memory; thats the problem. Note we take care to only allocate
				\ it once for each port. The memory belongs to the port not the object.
				\ There is no place to return it so once allocated it remains until
				\ the system is restarted. A system restart reloads the application.
				\ Obviously the port has to be opened first in a task that has duel port
				\ memory to allocate.
				port_here \ num base(--
				\ this could be nasty an ABORT with interrupts disabled
				_#control_block_size ['] port_allot CATCH ?DUP IF
					_unlock_word $ABORT
				THEN
				\ num base(--
				DUP _#control_block_size ERASE
				port_here OVER #p_tpoint + !
				_#write_buffer_length 
				['] port_allot CATCH ?DUP IF
					_unlock_word $ABORT
				THEN
				OVER \ num base num<--
				CELLS %port_tube_control> + !
			THEN
			_unlock_word
			\ num<--
			CELLS %port_tube_control> + @ this :!control_block
			this
		; overrides :Sopen

		m: ( indent --)
			CR DUP SPACES ." port_tube | " ." Object: " this .h  
			DROP send
		; overrides :print

target_also
&drivers
target_definitions

	end_class port_tube

target_previous_definitions
target_previous