***************************************************************************

; frontpub v1.0 - 16/01/95 by Gunther Nikl - initial version
; frontpub v1.0 - 25/03/95 by Gunther Nikl - CheckFrontScr() rewritten

***************************************************************************

; include stuff

		include	exec/types.i
		include	lvo30/dos_lib.i
		include	lvo30/exec_lib.i
		include	lvo30/intuition_lib.i
		include	lvo30/commodities_lib.i

CALL		MACRO
		move.l	\2,a6
		jsr	_LVO\1(a6)
		ENDM

RECALL		MACRO
		jsr	_LVO\1(a6)
		ENDM

; global stuff

	STRUCTURE Globals,0
	  ULONG SysBase
	  ULONG WbMsg
	  ULONG IntBase
	  ULONG CxBase
	  ULONG FrontScr
	  ULONG Broker
	  UBYTE CxEnable
	  UBYTE CheckIt
	  UBYTE IntrSig
	  UBYTE Pad1
	  STRUCT NewBroker,26
	  STRUCT ScrIntr,22
	LABEL gb_SIZEOF

BrokerPort	equ	NewBroker+20

bp		equr	a4			; the base register

***************************************************************************

		SECTION start,CODE

start		moveq	#(gb_SIZEOF>>2)-1,d0
1$		clr.l	-(sp)			; clear local var area
		dbra	d0,1$
		move.l	sp,bp
		move.l	4,a6
		move.l	a6,SysBase(bp)		; cache SysBase
		suba.l	a1,a1
		RECALL	FindTask		; use system function ..
		move.l	d0,a2
		tst.l	172(a2)
		bne.s	fromCLI
fromWB		lea	92(a2),a0		; get wbmsg
		RECALL	WaitPort
		lea	92(a2),a0
		RECALL	GetMsg
		move.l	d0,WbMsg(bp)
fromCLI		bsr	main			; call main
		move.l	WbMsg(bp),d2
		beq.s	1$
		RECALL	Forbid
		move.l	d2,a1
		RECALL	ReplyMsg		; reply wbsmg
1$		moveq	#0,d0
		lea	gb_SIZEOF(bp),sp
		rts

***************************************************************************

InstallCx	CALL	CreateMsgPort,SysBase(bp) ; init & install broker
		move.l	d0,BrokerPort(bp)
		beq.s	1$			; no port ...
		lea	NewBroker(bp),a1
		move.w	#$500,(a1)+
		lea	ProgName(pc),a0
		move.l	a0,(a1)+
		lea	Version(pc),a0
		move.l	a0,(a1)+
		lea	Description(pc),a0
		move.l	a0,(a1)+
		move.w	#1,(a1)
		lea	NewBroker(bp),a0
		moveq	#0,d0
		CALL	CxBroker,CxBase(bp)
		move.l	d0,Broker(bp)
		beq.s	1$			; no broker ...
		move.l	d0,a0
		moveq	#1,d0
		RECALL	ActivateCxObj
		moveq	#1,d0			; all ok !
		move.b	d0,CxEnable(bp)
1$		rts

***************************************************************************

OpenLibs	move.l	SysBase(bp),a6		; open all libs!
		lea	IntName(pc),a1
		moveq	#37,d0
		RECALL	OpenLibrary
		move.l	d0,IntBase(bp)
		beq.s	3$			; no intuition v37+ !
		lea	CxName(pc),a1
		moveq	#37,d0
		RECALL	OpenLibrary
		move.l	d0,CxBase(bp)
		bne.s	1$			; commodities v37+ ok ! 
3$		tst.l	WbMsg(bp)
		bne.s	2$
		lea	DosName(pc),a1
		moveq	#0,d0
		RECALL	OpenLibrary
		move.l	d0,d6
		beq.s	2$			; no dos ...
		exg	d6,a6
		RECALL	Output
		move.l	d0,d1
		lea	NeedV37(pc),a2
		move.l	a2,d2
		moveq	#NeedV37len,d3
		RECALL	Write			; osversion message
		exg	d6,a6
		move.l	d6,a1
		RECALL	CloseLibrary
2$		moveq	#0,d0
1$		rts

***************************************************************************

main		movem.l	d2-d7/a2-a6,-(sp)	; main program
		bsr.s	OpenLibs
		beq	1$
		bsr	InstallCx
		beq	1$
		moveq	#-1,d0
		CALL	AllocSignal,SysBase(bp)	; allocate intr-signal
		move.b	d0,IntrSig(bp)
		bmi.s	1$
		moveq	#0,d0
		CALL	SetPubScreenModes,IntBase(bp)
		moveq	#1,d1
		or.w	d0,d1
		move.l	d1,d0
		RECALL	SetPubScreenModes
		lea	ScrIntr+8(bp),a1	; init & install intr-server
		move.w	#$2ff,(a1)+
		lea	ProgName(pc),a0
		move.l	a0,(a1)+
		move.l	bp,(a1)+
		lea	ScrHandler(pc),a0
		move.l	a0,(a1)
		lea	ScrIntr(bp),a1
		moveq	#5,d0
		CALL	AddIntServer,SysBase(bp)
		st	CheckIt(bp)
4$		moveq	#$40,d0			; build wait mask
		lsl.w	#6,d0
		move.b	IntrSig(bp),d1
		bset	d1,d0
		move.l	BrokerPort(bp),a1
		move.b	15(a1),d1
		bset	d1,d0
		RECALL	Wait
		btst	#12,d0
		bne.s	2$			; got CTRL_C !
		move.b	IntrSig(bp),d1
		btst	d1,d0
		beq.s	3$			; no signal from interrupt
		bsr	CheckFrontScr
3$		bsr	CheckBroker
		beq.s	4$			; no end request from Exchange
2$		lea	ScrIntr(bp),a1
		moveq	#5,d0
		RECALL	RemIntServer		; remove intr-server
1$		bsr.s	RemoveCx
		bsr.s	CloseLibs
		movem.l (sp)+,d2-d7/a2-a6	; exit main
		rts

***************************************************************************

CloseLibs	move.l	SysBase(bp),a6		; close all libs
		move.l	CxBase(bp),a1
		bsr.s	2$
		move.l	IntBase(bp),a1
2$		move.l	a1,d0
		beq.s	1$
		RECALL	CloseLibrary
1$		rts

***************************************************************************

RemoveCx	move.l	Broker(bp),d2		; free commodity stuff
		beq.s	2$
		move.l	d2,a0
		moveq	#0,d0
		CALL	ActivateCxObj,CxBase(bp)
		move.l	d2,a0
		RECALL	DeleteCxObjAll
2$		move.l	BrokerPort(bp),d0
		beq.s	1$
		move.l	d0,a0
		CALL	DeleteMsgPort,SysBase(bp)
1$		rts

***************************************************************************

CheckBroker	movem.l	d2/a2/a6,-(sp)
		moveq	#0,d2			; quit:=false
4$		move.l	BrokerPort(bp),a0	; check port
		CALL	GetMsg,SysBase(bp)
		move.l	d0,a2
		move.l	a2,d0
		beq.s	1$			; no message
		move.l	a2,a0
		CALL	CxMsgType,CxBase(bp)
		cmpi.w	#$40,d0			; CXM_COMMAND
		bne.s	2$
		move.l	a2,a0
		RECALL	CxMsgID
;		cmp.w	#25,d0			; CXCMD_UNIQUE
;		beq.s	2$
		cmpi.w	#23,d0			; CXCMD_KILL
		seq	d2
		beq.s	2$
		moveq	#1,d1
		cmpi.w	#17,d0			; CXCMD_ENABLE
		beq.s	3$
		moveq	#0,d1
		cmpi.w	#15,d0			; CXCMD_DISABLE
		bne.s	2$
3$		move.b	d1,CxEnable(bp)
		move.l	d1,d0
		move.l	Broker(bp),a0
		RECALL	ActivateCxObj		; enable or disable broker
2$		move.l	a2,a1
		CALL	ReplyMsg,SysBase(bp)	; reply message
		bra.s	4$
1$		move.l	d2,d0			; return 'quit'
		movem.l	(sp)+,d2/a2/a6
		rts

***************************************************************************

CheckFrontScr	move.l	a6,-(sp)
		move.l	a2,-(sp)
		link	a5,#-144
		CALL	Forbid,SysBase(bp)	; disable multitasking
		moveq	#0,d0
		CALL	LockIBase,IntBase(bp)
		move.l	d0,a0
		RECALL	UnlockIBase
		RECALL	LockPubScreenList	; get pubscreen list
		move.l	d0,a2
		move.l	sp,a0			; namebuf for defpubscr name
		RECALL	GetDefaultPubScreen
		move.l	a2,a0
		move.l	sp,a1
		CALL	FindName,SysBase(bp)	; screen in the list ?
		move.l	d0,a0
		move.l	a0,d0
		move.l	IntBase(bp),a6
		beq.s	2$
		move.l	60(a6),d0
		move.l	d0,FrontScr(bp)
		cmp.l	14(a0),d0		; is the screen the firstscreen ?
		beq.s	2$
4$		move.l	0(a2),a2		; check if frontscr is a pubscreen
		tst.l	0(a2)
		beq.s	2$
		cmp.l	14(a2),d0
		bne.s	4$
		btst	#0,19(a2)
		bne.s	2$
		move.l	10(a2),a0		; copy name of public screen
		move.l	sp,a1
3$		move.b	(a0)+,(a1)+		; for the sake of safety :)
		bne.s	3$
		suba.l	a2,a2
2$		RECALL	UnlockPubScreenList
		move.l	a2,d0
		bne.s	1$
		move.l	sp,a0			; frontscr becomes default pubscr
		RECALL	SetDefaultPubScreen
1$		CALL	Permit,SysBase(bp)	; enable multitasking
		st	CheckIt(bp)		; enable interrupt checking
		unlk	a5
		move.l	(sp)+,a2
		move.l	(sp)+,a6
		rts

***************************************************************************

ScrHandler	move.b	CxEnable(a1),d0		; commodity on ?
		add.b	CheckIt(a1),d0
		bne.s	1$
		move.l	IntBase(a1),a0
		move.l	60(a0),d0
		beq.s	1$			; no screen !?
		cmp.l	FrontScr(a1),d0
		beq.s	1$			; IntBase->FirstScreen != FrontScr
		clr.b	CheckIt(a1)
		move.l	SysBase(a1),a6
		moveq	#0,d0
		move.b	IntrSig(a1),d1
		bset	d1,d0
		move.l	BrokerPort(a1),a1
		move.l	16(a1),a1
		RECALL	Signal			; wakeup our task
1$		moveq	#0,d0
		rts

***************************************************************************

; static data

		dc.b	'$VER: '
Version		dc.b	'FrontPub 1.1 (25.3.95) © 1995 by G.Nikl',0
Description	dc.b	'frontmost pubscreen becomes default',0
ProgName	dc.b	'FrontPub',0
DosName		dc.b	'dos.library',0
IntName		dc.b	'intuition.library',0
CxName		dc.b	'commodities.library',0
NeedV37		dc.b	'This program requires at least v37 of the OS!',10,0
NeedV37len	equ	*-NeedV37-1

		end
