*>b:DignetTERM

	*«««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*
	*   Copyright © 1997 by Kenneth C. Nilsen.  E-Mail: kennecni@IDGonline.no		      *
	*   Source viewed in 800x600 with Thin711.font (11) in CED				      *
	*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»*
	*
	*   Name
	*	DignetTERM 2.1
	*
	*   Synopsis
	*       Demo program for dignet.library to show one of the capability it has.
	*
	*   Function
	*	Simple communication with the modem or a console in the other end. Feel free
	*	to modify this program for your own needs.
	*
	*	This source demostrates the capability of the dignet.library. It will let you
	*	communicate with a device, for example the serial.device. You can use this little
	*	program to enter a BBS or the internet for that matter.
	*	It is slower than for example NComm and Term due to that each read/write is called
	*	as a library function with stack store/restore, reading and init of net structure
	*	and etcetera. To make it as fast as those regular terminal programs you would have
	*	to read the DoIO/SendIO your self, but then the point with this library is gone.
	*
	*	You can use the new function GetNetport to use a own console window and IDCMP with
	*	Wait() on the signal collection of the ports. This way you can write your own
	*	complete terminal program, but we will not stand for the speed it will give.
	*
	*	You could easily make modem and/or nullmodem support for your programs. To make them
	*	modem capable you just send ATDT<number>(13)(10) and handle OK/CONNECT/ERROR returns.
	*	Exclude that part and you have a nullmodem capable program.
	*
	*	If anything is unclear e-mail us at: kenny@bgnett.no
	*
	*   Inputs
	*	DignetTERM <device> [unit]   unit defaults to 0 if not provided
	*
	*   Notes
	*
	*   Bugs
	*	
	*   Created	: 09.03.97
	*   Changes	: 09.03.97, 13.03.97, 14.03.97, 15.03.97, 17.03.97
	*««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««*


;StartSkip	=	0

;DODUMP		SET	1

BufferSize	=	1024*2


		Incdir	""

		include	lvo:exec_lib.i
		include	lvo:dos_lib.i
		include	lvo:dignet_lib.i

		Incdir	inc:

;these two files are included:

		include	dignet/dignet.i
		include	digital.macs
		include	startup.asm

		Incdir	""

		dc.b	"$VER: DignetTERM 2.1 (17.3.97)",10
		dc.b	"Copyright © 1997 Digital Surface. PUBLIC DOMAIN",0
		even
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»*
Init		TaskName	"DignetTERM"
		DefLib	dignet,3		;version 3+ of dignet.library
		DefLib	dos,37			;version 37 of dos.library
		DefEnd

Start	NextArg				;any args for this program ?
	beq	About			;none, show About/usage
	move.l	d0,a0
	cmp.b	#'?',(a0)		;info wanted ? show About/Usage
	beq	About

	lea	DevN(pc),a1		;we asume a device name

.copyDevice
	move.b	(a0)+,(a1)+		;copy name to our own buffer
	bne.b	.copyDevice		;you could easily default this to serial.device

	NextArg				;unit provided ?
	beq	.noUnit			;if no unit provided, default to 0

	move.l	d0,a0			;this is just a demo so we take a simple convert
	move.b	(a0),d0
	ext.w	d0
	ext.l	d0
	sub.w	#48,d0			;simple convert (!)
	move.l	d0,Unit

.noUnit	LibBase	dignet

	lea	DevN(pc),a0		;device we want to use
	move.l	Unit(pc),d0		;unit
	Call	AllocNet		;alloc a net structure
	move.l	d0,Net			;ok, it's ready for use
	beq	ErrorNet

;	move.l	d0,a0			;problems with connect ? use this one..
;	Call	SetDefault

;prepare console for in/out.

	LibBase	dos

	Call	Input			;get def. input handler (CON)
	move.l	d0,In			;store
	beq	Errorin

	Call	Output			;get def. output handler (CON)
	move.l	d0,Out
	beq	Close			;if error quit (nowhere to print message)

	move.l	In(pc),d1
	moveq.l	#1,d2
	Call	SetMode			;set RAW mode so we don't have to wait until
					;a CR (return button) is pressed
;Print Welcome text:

	lea	Welcome(pc),a0
	bsr	Print

	LibBase	dignet

	move.l	Net(pc),a0
	Call	FlushNet

	moveq.l	#-1,d0

	move.l	Net(pc),a0
	lea	InitCmd(pc),a1		;our optional command
	lea	Buffer(pc),a2		;result buffer from modem (OK|ERROR)
	Call	InitModem		;our new function
	tst.l	d0			;ok ?
	beq	Main			;d0=0 then ok (!)
	cmp.l	#DNETERROR_TIMEOUT,d0	;timed out?
	bne.b	.noTO			;nope..

	lea	TimedOut(pc),a0
	bsr	Print			;print timeout message and...

.noTO	lea	NoModem(pc),a0
	bsr	Print			;no modem connected? text

; MAIN LOOP: Here we read char and modem and print from modem to CON

Main	LibBase	exec

;check for ctrl + c:

	moveq	#0,d0
	moveq	#0,d1
	bset	#12,d1
	Call	SetSignal		;check for ctrl + c
	btst	#12,d0
	bne	Exit			;yes ? then quit

	LibBase	dos

	move.l	In(pc),d1
	move.l	#12000,d2		;wait a while (this can be done better with signal
					;handling etcetera..
	Call	WaitForChar		;wait for keypress
	tst.l	d0
	beq	.noChar			;no key ? then check net only

	move.l	In(pc),d1		;read from def. Input handler
	move.l	#Buffer,d2		;to buffer
	moveq.l	#1,d3			;only one char at the time
	Call	Read			;read char

;echo/half duplex:			;uncomment these line below to have
;	move.l	Out(pc),d1		;echoing of what you write when you're online.
;	move.l	#Buffer,d2
;	moveq.l	#1,d3
;	Call	Write

	LibBase	dignet
	move.l	Net(pc),a0
	lea	Buffer(pc),a1		;write from buffer
	moveq.l	#1,d0			;one char
	Call	WriteNet		;write char to net (modem perhaps)

.noChar	LibBase	dignet

	move.l	Net(pc),a0
	Call	QueryNet		;how many chars are waiting ?
	tst.l	d0			;none, then loop back to Main
	beq	Main

;read all chars in buffer

	move.l	Net(pc),a0
	lea	Buffer(pc),a1		;read to buffer
	cmp.l	#BufferSize,d0
	ble.b	.sizeOk
	move.l	#BufferSize,d0		;max chars (can be increased/decreased)
.sizeOk	move.l	d0,d3
	Call	ReadNet			;read chars from net

;print char to screen

	LibBase	dos
	move.l	Out(pc),d1		;write to def. output handler
	move.l	#Buffer,d2		;from buffer
	Call	Write			;print that char to screen

;by printing the char you typed in CON you can provide echoing as well.

	bra	.noChar

Exit	lea	QuitText(pc),a0
	bsr	Print

	LibBase	dos
	move.l	In(pc),d1		;input handler
	moveq.l	#0,d2			;set CON mode
	Call	Setmode			;set back to CON mode !!
*------------------------------------------------------------------------------------------------------------*
Close	LibBase	dignet			;cleanup
	tst.l	Net
	beq.b	.noNet
	move.l	Net(pc),a0
	Call	FreeNet			;free out net structure
	tst.l	d0
	beq	.noNet

	LibBase	dos
	Call	Output			;print error message if wrong net structure
	move.l	d0,d1			;well.. to show the options
	beq	.noNet
	move.l	#FreeError,d2
	move.l	#FreeErrorL,d3
	Call	Write

.noNet	Return	0			;quit program with 0 in return code
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»*
ErrorIn
	lea	NoInTxt(pc),a0		;if no input handler available
	bsr	Print			;print error message
	bra	Close

ErrorNet
	LibBase	exec			;report error on device/unit
	lea	NoNetTxt(pc),a0
	lea	Table(pc),a1
	move.l	#DevN,(a1)
	move.l	Unit(pc),4(a1)
	lea	Proc(pc),a2
	lea	Buffer(pc),a3
	Call	RawDoFmt

	lea	Buffer(pc),a0
	bsr	Print
	bra	Close

About	lea	AboutTxt(pc),a0		;About/Usage message
	bsr	Print
	bra	Close

Print	movem.l	d0-a6,-(sp)		;our sub routine that prints to def. out

	LibBase	dos
	move.l	a0,d2			;backup string ptr.
	Call	Output			;get def. outhandler
	move.l	d0,d1
	beq	.exit			;null ? then exit

	move.l	d2,a0			;start count of length of string
	moveq.l	#0,d3			;length
.count	tst.b	(a0)+			;a null termination ?
	beq.b	.print			;yep, print
	addq.l	#1,d3			;no, add one more char
	bra.b	.count			;loop
.print	Call	Write			;write string to def Out which is our console

.exit	movem.l	(sp)+,d0-a6
	rts

Proc	move.b	d0,(a3)+
	rts
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»*
In		dc.l	0		;input handler
Out		dc.l	0		;output handler

Net		dc.l	0		;ptr. to net structure
Table		dc.l	0,0		;ptr. table for RawDoFmt()

Unit		dc.l	0		;unit number
DevN		dcb.b	80,0		;device name, insert "serial.device" in beginning to def. to that

Buffer		dcb.b	BufferSize,0	;buffer for chars and RawDoFmt()
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»*
Timedout	dc.b	"Timeout on line!",10,0
NoModem		dc.b	"NO MODEM CONNECTED ?",10,10,0

Welcome		dc.b	12,"___________________________________________________________________________",10
		dc.b	27,"[32m",27,"[1m",27,"[44m¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯",27,"[0m",10
		dc.b	27,"[1m",27,"[44m          D I G N E T T E R M ",27,"[0m",27,"[44m 2.0 - 1997 by Kenny. Public Domain",27,"[1m          ",10
		dc.b	27,"[44m___________________________________________________________________________[0m",10
		dc.b	27,"[32m",27,"[1m¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯",27,"[0m",10
		dc.b	" This program demostrates some of the capabillities of the dignet.library.",10
		dc.b	" Feel free to expande it for your own taste.    Note that the handler loop",10
		dc.b	" isn't the most efficent way to handle in/out data.  You should convert it",10
		dc.b	" a Wait() loop if you intend to release it in public.   The intention with",10
		dc.b	" this program is demostration only.",10
		dc.b	"___________________________________________________________________________[0m",10
		dc.b	27,"[32m",27,"[1m¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯",27,"[0m",10,0


QuitText	dc.b	27,"[0m",12,"*** DignetTERM: CTRL+C BREAK",10,0
NoNetTxt	dc.b	"Couldn't open %s unit %ld!",10,10,0
NoInTxt		dc.b	"No input handler!",10,10,0
AboutTxt	dc.b	"DignetTERM 1.2 demo program for dignet.library",10,10
		dc.b	"USAGE: DignetTERM <device> [unit]",10,10
		dc.b	"Press CTRL + C to quit",10,10,0
FreeError	dc.b	"Error freeing net!",10
FreeErrorL	=*-FreeError

InitCmd		dc.b	"ATZ\r",0
*»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»»*
