
*********************************************************************
*
*  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
		OPT	O+		; Optimizing on
	ENDC


	INCDIR	INC:
	INCLUDE	exec/types.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 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
	CLD	6
	CLD	5
	move.l	Default(pc),d3		; Default signal
	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	; Otherwise 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
	SYS	OpenLibrary
	move.l	d0,d6
	beq.b	.wb			; No library around...

	lea	DosName_Msg(pc),a1	; Also need dos.library
	CLD	0
	SYS	OpenLibrary
	move.l	d0,d5
	beq.b	.no_dos			; No library around...

	move.l	d7,a2
	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

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

	move.l	d0,a0
	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
	beq.b	.icon_ok		; No tooltype found

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

.icon_ok
	move.l	d2,a0
	SYS	FreeDiskObject		; And free icon

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

	move.l	d5,a1
	SYS	CloseLibrary		; Close dos.library
.no_dos	move.l	d6,a1
	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

.wb	SYS	Forbid
	lea	PortName_Msg(pc),a1
	SYS	FindPort		; Try to locate port
	tst.l	d0
	beq.b	.skip			; No port

	move.l	d0,a0
	move.l	MP_SIGTASK(a0),a1	; Task to signal
	move.l	d3,d0			; Signal to send
	SYS	Signal			; And do it

.skip	move.l	d7,d0			; Any WBMsg?
	beq.b	.cli_end		; No

	move.l	d7,a1
	SYS	ReplyMsg		; Otherwise reply it
	rts

.cli_end
	SYS	Permit			; Re-enable other tasks
	rts

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

GetBreakBit
	CLD	0
.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
	bmi.b	.end			; Out of range

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

	lsl.l	#2,d0			; To index longwords
	move.l	BreakBits(pc,d0.w),d3	; Get value
.end	rts				; All done


BreakBits
	dc.l	SIGBREAKF_CTRL_C
	dc.l	SIGBREAKF_CTRL_D
Default	dc.l	SIGBREAKF_CTRL_E
	dc.l	SIGBREAKF_CTRL_F

	dc.b	"$VER: SignalRC 1.0 (4.8.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
