********************************************************************
*                                                                  *
*  Small program to send any SIGBREAKF_CTRL_? signal to ReqChange  *
*  (these signals are also know as break c, d, e and f). Works on  *
*  both OS 1.2/1.3 and OS 2.0.                                     *
*  Should assemble ok with most assemblers.                        *
*                                                                  *
*  Public Domain 1992. Written by Magnus Holmgren.                 *
*                                                                  *
********************************************************************

	IFD	__G2			; Only DevPac
		OPT	O+,L-
	ENDC

	INCDIR	INC:
	INCLUDE	exec/types.i
	INCLUDE	exec/funcdef.i
	INCLUDE	exec/exec_lib.i		; _LVO definitions for exec.library
	INCLUDE	exec/execbase.i
	INCLUDE	exec/ports.i
	INCLUDE	dos/dos.i
	INCLUDE	dos/dosextens.i
	INCLUDE	dos/dos_lib.i		; _LVO definitions for dos.library
	INCLUDE	workbench/icon_lib.i	; _LVO definitions for icon.library
	INCLUDE	workbench/startup.i
	INCLUDE	workbench/workbench.i


*
* Macro for calling library routines. Parameter 1 is the offset to the
* routine.
*

SYS	MACRO	; _LVO
	IFC	"\1",""
	FAIL	"SYS macro: No _LVO"
	ENDC

	jsr	_LVO\1(a6)              ; Call library routine
	ENDM


*
* Macro for jumping to library routines. Parameter 1 is the offset to the
* routine.
*

SYSJMP	MACRO	; _LVO
	IFC	"\1",""
	FAIL	"SYSJMP macro: No _LVO"
	ENDC

	jmp	_LVO\1(a6)              ; Call library routine
	ENDM


*
* Macro to clear data register. "CLD x" clears data register x.
*

CLD	MACRO	; Registernumber

	IFC	"\1",""
	FAIL	"CLD macro: No registernumber"
	ENDC

	moveq	#0,d\1
	ENDM


Start	CLD	7			; WB message storage
	CLD	6			; IconBase storage
	CLD	5			; DOSBase storage
	CLD	4			; No signal (yet)
	move.l	4.w,a6			; Get ExecBase
	move.l	ThisTask(a6),a5		; Current process
	tst.l	pr_CLI(a5)		; CLI start?
	bne	.cli			; Yep

	lea	pr_MsgPort(a5),a2	; Get message port
	move.l	a2,a0
	SYS	WaitPort		; And wait for message
	move.l	a2,a0
	SYS	GetMsg			; Get message
	move.l	d0,d7			; And save it

	lea	IconName_Msg(pc),a1	; We need icon.library
	CLD	0			; Any version will do
	SYS	OpenLibrary		; Open it
	move.l	d0,d6			; Save libbase
	beq.b	.wb			; No library around...

	lea	DosName_Msg(pc),a1	; Also need dos.library
	CLD	0			; Any version will do
	SYS	OpenLibrary		; And open it
	move.l	d0,d5			; Save libbase
	beq.b	.no_dos			; No library around...

	move.l	d7,a2			; WB startup message
	move.l	sm_ArgList(a2),a3	; Get startup arguments
	move.l	wa_Lock(a3),d1		; Dir for this program
	move.l	d5,a6			; Get DOSBase
	SYS	CurrentDir		; CD there
	move.l	d0,d4			; Save old cd

	move.l	wa_Name(a3),a0		; Name of our program
	move.l	d6,a6			; Get IconBase
	SYS	GetDiskObject		; Get DiskObject
	move.l	d0,d2			; Save it
	beq.b	.icon_done		; No DiskObject available

	move.l	d0,a0			; Get DiskObject
	move.l	do_ToolTypes(a0),a0	; Tooltypes array
	lea	Signal_Msg(pc),a1	; Tooltype to search for
	SYS	FindToolType		; Try to find it
	tst.l	d0			; Got it?
	beq.b	.icon_ok		; No tooltype found

	move.l	d0,a0			; ToolType string
	bsr.b	GetBreakBit		; Get appropriate signal

.icon_ok
	move.l	d2,a0			; Get DiskObject again
	SYS	FreeDiskObject		; And free it

.icon_done
	move.l	d4,d0			; Old cd
	move.l	d5,a6			; Get DOSBase
	SYS	CurrentDir		; CD back to original dir
	move.l	4.w,a6			; Get SysBase

	move.l	d5,a1			; Get DOSBase
	SYS	CloseLibrary		; Close dos.library
.no_dos	move.l	d6,a1			; Get IconBase
	SYS	CloseLibrary		; Close icon.library
	bra.b	.wb			; Skip to "main"

.cli	clr.b	-1(a0,d0.l)		; Null terminate argument string
	bsr.b	GetBreakBit		; Get appropriate signal

.wb	SYS	Forbid			; Stop other tasks
	tst.l	d4			; Any signal bit?
	beq.b	.skip			; No

	lea	PortName_Msg(pc),a1	; Name of port
	SYS	FindPort		; Try to locate port
	tst.l	d0			; Found it?
	beq.b	.skip			; No port

	move.l	d0,a0			; Port structure
	move.l	MP_SIGTASK(a0),a1	; Task to signal
	CLD	0
	bset	d4,d0			; Prepare signal mask
	SYS	Signal			; And send it

.skip	tst.l	d7			; Any WBMsg?
	beq.b	.cli_end		; No

	move.l	d7,a1			; Get WBMsg
	SYSJMP	ReplyMsg		; Otherwise reply it

.cli_end
	SYSJMP	Permit			; Re-enable other tasks


*
* Checks null-terminated string at a0 for the breakbit to send.
* Skips leading tabs and spaces.
*

GetBreakBit
	CLD	0			; Clear d0
.scan	move.b	(a0)+,d0		; Get next char
	beq.b	.end			; End of string

	cmp.b	#" ",d0			; Skip space
	beq.b	.scan

	cmp.b	#9,d0			; Skip tabs
	beq.b	.scan

	bclr	#5,d0			; Make it upper case
	sub.b	#"C",d0			; Turn into "ordinal number"
	bmi.b	.end			; Out of range

	cmp.b	#4,d0
	bgt.b	.end			; Out of range

	move.b	d0,d4			; D4 does not contain garbage
	add.b	#SIGBREAKB_CTRL_C,d4	; Make it "proper"
.end	rts				; All done


	dc.b	"$VER: SignalRC 1.1 (25.11.92)",0

PortName_Msg
	dc.b	"ReqChange",0

DosName_Msg
	dc.b	"dos.library",0

IconName_Msg
	dc.b	"icon.library",0

Signal_Msg
	dc.b	"SIGNAL",0

	END
