*******************************************************************************
* Ami-Express /X3.xx 'amix.Library'		   Copyright İ 1994 2-Cool/EX4!
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* $Release	: 0.1 $
* $Revision	: 1.02 $
* $Date		: 02-Jan-93 $
*
* $Authors	: Written by 2-Cool/EX4
*
* $Purpose	: An Ami-Express Door Interface library for AmiX 'door modules'
*		: Compatible with AEDoor library with more functions
*******************************************************************************
AbsExecBase	=	4
xid_syslib	=	34
xid_seglist	=	42

;-------------- Definition Includes

		incdir	"includes:"
		include	"exec/exec.i"
		include	"exec/exec_lib.i"

		include	"exec/types.i"
		include	"exec/initializers.i"
		include	"exec/libraries.i"
		include	"exec/lists.i"
		include	"exec/nodes.i"
		include	"exec/resident.i"
		
		include	"libraries/dos.i"
		include	"libraries/dos_lib.i"
		include	"amix/amix.i"

CALL		macro
		jsr	_LVO\1(a6)
		endm

DummyEntry:	moveq	#-1,d0	;Tell all fools trying to execute us
		rts		;that our execution failed. ;-)


Resident:	dc.w	RTC_MATCHWORD
		dc.l	Resident
		dc.l	ResEnd
		dc.b	RTF_AUTOINIT
		dc.b	1				;version
		dc.b	NT_LIBRARY
		dc.b	0				;task Pri
		dc.l	LibName
		dc.l	IdString
		dc.l	Init

LibName:	dc.b	'amix.library',0
IdString:	dc.b	'$VER: amix.library v1.02'
		dc.b	' (02-Jan-94)',13,10,0
		EVEN
ResEnd:

Init:		dc.l	200			;AXLib_SIZEOF
		dc.l	FuncTable		;-6
		dc.l	DataTable		;-5
		dc.l	InitRoutine		;-4

; --- sys
FuncTable:	dc.l	Open			;-3
		dc.l	Close			;-2
		dc.l	Expunge			;-1
		dc.l	Null			;0

		dc.l	_LVOCreateComm		;01: create comms channel
		dc.l	_LVODeleteComm		;02: delete comms channel
		dc.l	_LVOSendCmd		;03: send a cmd
		dc.l	_LVOSendStrCmd		;04: send string & cmd
		dc.l	_LVOSendDataCmd		;05: send cmd & data
		dc.l	_LVOSendStrDataCmd	;06: send string & cmd & data
		dc.l	_LVOGetData		;07: get data ptr
		dc.l	_LVOGetString		;08: get string ptr
		dc.l	_LVOPrompt		;09: prompt for a string
		dc.l	_LVOWriteStr		;10: send a text string
		dc.l	_LVOShowGFile		;11: show an /X File
		dc.l	_LVOShowFile		;12: show a text file
		dc.l	_LVOSetDT		;13: set data
		dc.l	_LVOGetDT		;14: get data
		dc.l	_LVOGetStr		;15: get string
		dc.l	_LVOCopyStr		;16: make a fast copy of string
		dc.l	_LVOHotKey		;17: wait for keypress
		dc.l	-1

DataTable:	INITBYTE	LH_TYPE,NT_LIBRARY
		INITLONG	LN_NAME,LibName
		INITBYTE	LIB_FLAGS,LIBF_SUMUSED+LIBF_CHANGED
		INITWORD	1,1
		INITWORD	2,1
		INITLONG	LIB_IDSTRING,IdString
		dc.l	0

InitRoutine:	move.l	a5,-(a7)
		move.l	d0,a5
		move.l	a6,xid_SysLib(a5)		;34
		move.l	a0,xid_SegList(a5)		;42
		move.l	(a7)+,a5
		rts

;--- sys entries

Open:		addq.w	#1,LIB_OPENCNT(a6)
		bclr.b	#LIBB_DELEXP,LIB_FLAGS(a6)
		move.l	a6,d0
rts00:		rts


Close:		moveq	#0,d0
		subq.w	#1,LIB_OPENCNT(a6)
		bne.s	rts00
		btst.b	#LIBB_DELEXP,LIB_FLAGS(a6)
		beq.s	rts00

	;;; Fall through to Expunge and remove the lib from memory.

Expunge:	movem.l	d1-d2/a5-a6,-(a7)
		move.l	a6,a5
		move.l	xid_SysLib(a5),a6
		tst.w	LIB_OPENCNT(a5)
		beq.s	exp1
		bset.b	#LIBB_DELEXP,LIB_FLAGS(a5)
		moveq	#0,d0
		bra.s	expEnd

exp1:		move.l	xid_SegList(a5),d2
		move.l	a5,a1
		CALL	Remove
		moveq	#0,d0
		move.l	a5,a1
		move.w	LIB_NEGSIZE(a5),d0
		sub.l	d0,a1
		add.w	LIB_POSSIZE(a5),d0
		CALL	FreeMem
		move.l	d2,d0
expEnd:		movem.l	(a7)+,d1-d2/a5-a6
		rts

Null:		moveq	#0,d0
		rts

*******************************************************************************
* CreateComm() : Creates a door Communication Channel
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	d0 = Node Number (AS ASCII!)
* OUTPUTS:	d0 = Ptr to DoorInterface Structure (DIFStruct)
*******************************************************************************

_LVOCreateComm:	cmp.b	#10,d0
		bne.b	NodeOk
_SignalFailed:	moveq	#0,d0				;CreateComm failed
		rts
memfail		moveq	#-1,d0
		rts

NodeOk:		lea	_Arg1(pc),a4
		move.b	d0,(a4)
		move.b	d0,_Arg2-_Arg1(a4)

		move.l	(AbsExecBase).w,a6	;get execbase
		move.l	#236,d0			;length for our port store
		move.l	#MEMF_PUBLIC+MEMF_CLEAR,d1 ;we want public mem, cleared
		CALL	AllocMem		;allocate it...
		move.l	d0,DIFStructPt-_Arg1(a4) ;ptr to our RS.Variables base
		beq.s	memfail

		moveq	#-1,d0
		jsr	_LVOAllocSignal(a6)
		cmp.b	#$FF,d0
		beq.s	_SignalFailed

		lea	_MsgSt(pc),a0
		move.b	d0,Signal-_MsgSt(a0)
		move.b	d0,15(a0)
		sf.b	9(a0)
		move.b	#4,8(a0)
		sf.b	14(a0)
		lea	DRPort.txt(pc),a1
		move.l	a1,10(a0)
		suba.l	a1,a1
		jsr	_LVOFindTask(a6)

		lea	_MsgSt(pc),a1
		move.l	d0,16(a1)
		jsr	_LVOAddPort(a6)

DoorReplyMsg:	move.l	DIFStructPt(pc),a3
		move.b	#5,8(a3)
		move.w	#236,18(a3)

		lea	_MsgSt(pc),a1
		move.l	a1,14(a3)
		moveq	#-1,d0
		move.l	d0,228(a3)
		clr.l	232(a3)
		moveq	#2,d0
		move.l	d0,220(a1)
		moveq	#1,d0
		move.l	d0,224(a3)

		lea	DRPort.txt(pc),a0		;source
		move.l	a3,a1				;DIFStruct
		bsr.w	_LVOPutStr			;put into DIFStruct

		lea	AEDoorPort.MSG(pc),a1
GetPort:	move.l	(AbsExecBase).w,a6
		jsr	_LVOFindPort(a6)
		move.l	d0,_PortBase
		beq.s	GetPort

		bsr.w	_PutPortMsg

		moveq	#0,d1
		move.b	Signal(pc),d1
		moveq	#1,d0
		asl.l	d1,d0
		move.l	(AbsExecBase).w,a6
		jsr	_LVOWait(a6)
		lea	_MsgSt(pc),a0
		jsr	_LVOGetMsg(a6)

		move.l	DIFStructPt(pc),a0
		lea	20(a0),a1		;String-DIFStruct(a0),a1
		move.l	a1,StringPtr-_Arg1(a4)
		lea	220(a0),a1		;Data-DIFStruct(a0),a1
		move.l	a1,DataPtr-_Arg1(a4)
		move.l	a0,d0
		rts

*******************************************************************************
* DeleteComm() : Deletes our door Communication Channel
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a1 = Ptr to DoorInterface Structure (DIFStruct)
*******************************************************************************

_LVODeleteComm:	move.l	a1,a0
		move.l	#2,$E0(a0)
		bsr.w	_PutPortMsg

		moveq	#0,d1
		move.b	Signal(pc),d1
		moveq	#1,d0
		asl.l	d1,d0
		move.l	(AbsExecBase).w,a6
		jsr	_LVOWait(a6)

		lea	_MsgSt(pc),a0
		jsr	_LVOGetMsg(a6)

		lea	_MsgSt(pc),a1
		jsr	_LVORemPort(a6)

		lea	_MsgSt(pc),a0
		moveq	#-1,d0
		move.l	d0,$10(a0)
		move.l	d0,$14(a0)

		moveq	#0,d0
		move.b	Signal(pc),d0
		move.l	(AbsExecBase).w,a6
		jsr	_LVOFreeSignal(a6)

		move.l	DIFStructPt(pc),a1	;ptr to our RS.Variables base
		move.l	#236,d0			;no. of bytes to free
		jmp	_LVOFreeMem(a6)		;free the memory

*******************************************************************************
* Prompt()	: Prompt user for an input string
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 = Prompt String
*		a1 = DIFStruct
*		d1 = String Length
*******************************************************************************

_LVOPrompt	moveq	#JH_PM,d0
		bsr.s	_LVOSendStrDataCmd
		move.l	StringPtr(pc),a0
		move.l	a0,d0
		move.l	DataPtr(pc),a0
		cmp.l	#-1,(a0)
		beq.s	.carrier_lost
		rts
.carrier_lost	moveq	#0,d0
		rts

_LVOGetString	move.l	StringPtr(pc),a0
		rts
_LVOGetData	move.l	DataPtr(pc),a0
		rts

*******************************************************************************
* HotKey()	: Prompt user for key
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 = Hotkey String
*		a1 = DIFStruct
*******************************************************************************

_LVOHotkey	moveq	#JH_HK,d0
		bsr.s	_LVOSendStrCmd
		move.l	DataPtr(pc),a0
		move.l	(a0),d0
		bmi.s	.carrier_lost
		move.l	StringPtr(pc),a0
		moveq	#0,d0
		move.b	(a0),d0			;d0=key
		moveq	#0,d1			;d1=0
.carrier_lost:	rts

*******************************************************************************
* GetStr()	: Get string
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 = String
*		a1 = DIFStruct
*******************************************************************************

_LVOGetStr	moveq	#0,d0
		bsr.s	_LVOSendStrDataCmd
		move.l	DataPtr(pc),a0
		cmp.l	#-1,(a0)
		beq.s	.carrier_lost
		move.l	StringPtr(pc),d0
.carrier_lost:	rts
		
*******************************************************************************
* SetDT()	: 
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 = ASCIIZ String
*		a1 = DIFStruct
*		d1 = Data ID
*******************************************************************************

_LVOSetDT	moveq	#0,d0
		bra.s	_LVOSendStrDataCmd

*******************************************************************************
* GetDT()	: 
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 = ASCIIZ String
*		a1 = DIFStruct
*		d1 = Data ID
*******************************************************************************

_LVOGetDT	moveq	#1,d0
		bra.s	_LVOSendStrDataCmd

*******************************************************************************
* ShowFile()	: Shows an /X File
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 = ASCIIZ String
*		a1 = DIFStruct
*******************************************************************************

_LVOShowGFile	moveq	#JH_SG,d0
		bra.s	_LVOSendStrCmd

*******************************************************************************
* ShowFile()	: Shows a File
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 = ASCIIZ String
*		a1 = DIFStruct
*******************************************************************************

_LVOShowFile	moveq	#JH_SF,d0
		
*******************************************************************************
* SendStrCmd()	: Sends a text string and command
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 = ASCIIZ String
*		a1 = DIFStruct
*		d0 = AECommand
*******************************************************************************

_LVOSendStrCmd:	move.l	a1,-(sp)
		bsr.b	_LVOPutStr		;put into DIFStruct
		move.l	(sp)+,a1
		bra.s	_LVOSendCmd

*******************************************************************************
* WriteStr():	Sends a text string
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 = ASCIIZ String
*		a1 = DIFStruct
*		d1 = LF/NOLF
*******************************************************************************

_LVOWriteStr	moveq	#4,d0			;JH_SM

*******************************************************************************
* SendStrDataCmd(): Sends a text string and data command
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 = ASCIIZ String
*		a1 = DIFStruct
*		d0 = AECommand
*******************************************************************************

_LVOSendStrDataCmd:
		move.l	a1,-(sp)
		bsr.b	_LVOPutStr		;put into DIFStruct
		move.l	(sp)+,a1
		
*******************************************************************************
* SendDataCmd()	: Sends an /X Data & Command request
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	d0 = AECommand
* 		d1 = Data
*		a1 = DIFStruct
*******************************************************************************

_LVOSendDataCmd:
		move.l	d1,$DC(a1)

;-------------- falls through to SendCmd


*******************************************************************************
* SendCmd()	: Sends a simple /X Command request
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	d0 = AECommand
*		a1 = DIFStruct
*******************************************************************************

_LVOSendCmd:	move.l	d0,$E0(a1)		;JH_SM
		bsr.s	_PutPortMsg
		lea	_MsgSt(pc),a0
		move.l	(AbsExecBase).w,a6
		jsr	_LVOWaitPort(a6)
		lea	_MsgSt(pc),a0
		jmp	_LVOGetMsg(a6)

_PutPortMsg:	move.l	_PortBase(pc),a0
		move.l	DIFStructPt(pc),a1
		move.l	(AbsExecBase).w,a6
		jmp	_LVOPutMsg(a6)

*******************************************************************************
* CopyStr()	: Extracts ASCIIZ string (from DIFStruct) to <Destination>
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 = Destination
*		a1 = DIFStruct
*******************************************************************************

_LVOCopyStr:	move.l	a0,a2			;a2=<destination>
		lea	5*4(a1),a1		;a1=<source>
		bra.w	ByteCopy

*******************************************************************************
* PutStr()	: Inserts ASCIIZ string (from <SOURCE>) into DIFString
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a0 = Source
*		a1 = DIFStruct
*******************************************************************************

_LVOPutStr:	lea	5*4(a1),a2		;a2=<destination>
		move.l	a0,a1			;a1=<source)

;-------------- fall through to byte copy

*******************************************************************************
* ByteCopy()	: Copies an ASCIIZ string , <source> to <dest>
* ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ
* INPUTS:	a1 = source
*		a2 = dest
*******************************************************************************

ByteCopy:	moveq	#-1,d5
copyloop:	addq.b	#1,d5
		cmp.b	#200-1,d5	;string > 200 bytes?
		beq.s	clearbyte	;if so null terminate it and exit...
		move.b	(a1)+,(a2)+
		bne.s	copyloop
clearbyte:	clr.b	(a2)		;null string
		rts

_PortBase:	ds.l	1
_MsgSt:		ds.l	8
StringPtr	ds.l	1
DataPtr		ds.l	1
DIFStructPt:	ds.l	1		;ptr to 236 bytes of memory
		 
;-------------- AEDoor Interface Messsage Structure
;
;DIFStruct:	ds.l	1		;000 : Msg_Ax1     (001 ULONG PTR)
;		ds.l	1		;004 : Msg_Ax2     (001 ULONG PTR)
;		ds.l	1		;008 : Msg_Ax3     (001 ULONG PTR)
;		ds.l	1		;012 : Msg_Ax4     (001 ULONG PTR)
;		ds.l	1		;016 : Msg_Ax5     (001 ULONG PTR)
;		ds.b	200		;216 : Msg_String  (200 UBYTES)
;		ds.l	1		;220 : Msg_Data    (001 ULONG PTR)
;		ds.l	1		;224 : Msg_Command (001 ULONG PTR)
;		ds.l	1		;228 : Msg_NodeID  (001 ULONG PTR)
;		ds.l	1		;232 : Msg_LineNo  (001 ULONG PTR)

DRPort.txt:	dc.b	'DoorReplyPort'
_Arg1:		dc.b	0,0,0
		even
AEDoorPort.MSG:	dc.b	'AEDoorPort'
_Arg2:		dc.b	0,0,0
		even
Signal:		dc.b	0
		even

		end
