;==============================================================[ Description ]=

;	This is an example of a source, which waits for message from other
;	task. You will have to run this file first, then another called PutMsg.
;	This routine reads the message and prints texts, that you have typed
;	after PutMsg program as arguments.

;	$VER: WaitPort.s V1.1 (30.10.94)
;	Source by Cromax of Alchemy (kita@sun10.ci.pwr.wroc.pl)

;===================================================================[ Values ]=

ExecBase		Equ	4

_LVOForbid		Equ	-132
_LVOPermit		Equ	-138
_LVOFindTask		Equ	-294
_LVOAddPort		Equ	-354
_LVORemPort		Equ	-360
_LVOGetMsg		Equ	-372
_LVOReplyMsg		Equ	-378
_LVOWaitPort		Equ	-384
_LVOCloseLibrary	Equ	-414
_LVOOpenLibrary		Equ	-552

_LVOWrite		Equ	-048
_LVOOutput		Equ	-060

NT_MSGPORT		Equ	4

lh_TailPred		Equ	008

mp_SigTask		Equ	016
mp_MsgList		Equ	020

mymsg_Length		Equ	4		; Offsets of our message
mymsg_String		Equ	8		; defined by myself

DOSVersion		Equ	33		; KickStart 1.2+

;=============================================================[ Main Program ]=

		Section	NewPort,Code_P

Begin:		bra.s	.Skip

		dc.b	"$VER: WaitPort V1.1 (30.10.94)",10,0
		even

.Skip:		movea.l	[ExecBase].w,a6
		lea	DOSName,a1
		moveq	#DOSVersion,d0
		jsr	_LVOOpenLibrary(a6)
		move.l	d0,_DOSBase		; Can not open DOS library?
		beq.w	CloseDown		; Then quit!

		movea.l	[ExecBase].w,a6
		jsr	_LVOForbid(a6)

		movea.l	[ExecBase].w,a6		; Find pointer to Task
		suba.l	a1,a1			; structure of our task
		jsr	_LVOFindTask(a6)	; (if a1=NULL)
		move.l	d0,_Task

		movea.l	[ExecBase].w,a6
		jsr	_LVOPermit(a6)

		lea	MsgPort,a0		; Complete MsgPort structure
		move.l	_Task,mp_SigTask(a0)	; If we didn't found anything
		beq.w	CloseDown		; then quit (rather impossible)
		adda.l	#mp_MsgList,a0		; Set pointers of List struct
		move.l	a0,lh_TailPred(a0)	; in MsgPort structure
		addq	#4,a0			; Get addres of lh_Tail
		clr.l	(a0)			; Clear lh_Tail
		move.l	a0,-(a0)		; Address of lh_Tail to lh_Head

		movea.l	[ExecBase].w,a6		; Add these lines, if you want
		lea	MsgPort,a1		; your port to be public (to
		jsr	_LVOAddPort(a6)		; add it to system's port list)

.Wait:		movea.l	[ExecBase].w,a6		; Wait for message...
		lea	MsgPort,a0
		jsr	_LVOWaitPort(a6)

		movea.l	[ExecBase].w,a6
		lea	MsgPort,a0
		jsr	_LVOGetMsg(a6)		; In d0 we have pointer to
		move.l	d0,_Message		; Message structure

		move.l	d0,a0
		adda.l	#20,a0
		move.l	a0,_OurMessage		; In a0 pointer to our message
		
		cmpi.l	#"CRMX",(a0)		; Compare ID Header...
		bne.s	.Wait			; Naw, it's some crap...

		movea.l	_DOSBase,a6
		jsr	_LVOOutput(a6)
		tst.l	d0
		beq.s	ReplyMessage		; No output for text to write

		movea.l	_DOSBase,a6
		move.l	d0,d1
		movea.l	_OurMessage,a0
		move.l	mymsg_String(a0),d2
		move.l	mymsg_Length(a0),d3
		cmpi.l	#1,d3
		beq.s	ReplyMessage
		jsr	_LVOWrite(a6)		; Write string we've received

ReplyMessage:	movea.l	[ExecBase].w,a6
		movea.l	_Message,a1
		jsr	_LVOReplyMsg(a6)

CloseDown:	nop				; Close everything down...

.RemPort:	tst.l	_Task
		beq.s	.End
		movea.l	[ExecBase].w,a6		; Add these lines, if your
		lea	MsgPort,a1		; port was public (to remove
		jsr	_LVORemPort(a6)		; it from port list)

.CloseDOS:	tst.l	_DOSBase
		beq.s	.End
		movea.l	[ExecBase].w,a6
		movea.l	_DOSBase,a1
		jsr	_LVOCloseLibrary(a6)

.End:		moveq	#0,d0
		rts

;=====================================================================[ Data ]=

		Section	Data,Data_P

MsgPort:	dc.l	0		; ln_Succ
		dc.l	0		; ln_Pred
		dc.b	NT_MSGPORT	; ln_Type
		dc.b	0		; ln_Pri
		dc.l	PortName	; ln_Name
		dc.b	0		; mp_Flags
		dc.b	0		; mp_SigBits
		dc.l	0		; mp_SigTask
		dc.l	0		; lh_Head
		dc.l	0		; lh_Tail
		dc.l	0		; lh_TailPred
		dc.b	0		; lh_Type
		dc.b	0		; lh_pad

DOSName:	dc.b	"dos.library",0
PortName:	dc.b	"Amsterdam",0

;=====================================================================[ Vars ]=

		Section	Vars,Bss

_DOSBase:	ds.l	1
_Task:		ds.l	1
_Message:	ds.l	1
_OurMessage:	ds.l	1

