
		incpath	include:
		maclib	sm.mac
		macfile	macro.i

VERSION		equ	37
REVISION	equ	2
		
		STRUCTURE BreakStack,0
		APTR	stack_DosBase
		APTR	stack_ReadArgs
		APTR	stack_Process
		APTR	stack_Name
		APTR	stack_Task
		APTR	stack_Mask
		ULONG	stack_All
		ULONG	stack_C
		ULONG	stack_D
		ULONG	stack_E
		ULONG	stack_F
		ULONG	stack_Argument
		LABEL	stack_SIZEOF

		ENTRY	main,d1-d7/a0-a6,stack_SIZEOF,a5

;--------------	open dos.library
		lea	(dosName,pc),a1
		moveq	#36,d0
		CALL	OpenLibrary,<(execBase).w>
		move.l	d0,(stack_DosBase,a5)
		beq	.NODOSBASE
		movea.l	d0,a6	; load dos.library to a6

;--------------	read arguments
		lea	(argTemplate,pc),a0
		move.l	a0,d1
		lea	(stack_Process,a5),a0
		move.l	a0,d2
		moveq	#0,d3
		CALL	ReadArgs
		move.l	d0,(stack_ReadArgs,a5)
		beq	.DOSERROR

;--------------	setup bitmask. the priority settings are
;--------------	
;--------------	 - flag ALL is set -> set all bits
;--------------	 - mask defined -> change bits set in this mask
;--------------	 - special bit request (e.g.CTRL_C) -> change bit
;--------------	 - if nothing else, send at least CTRL_C
;--------------	
		moveq	#0,d0
		tst.l	(stack_All,a5)
		beq.b	.NotAll
		move.l	#SIGBREAKF_CTRL_C|SIGBREAKF_CTRL_D|SIGBREAKF_CTRL_E|SIGBREAKF_CTRL_F,d0
.NotAll		tst.l	(stack_Mask,a5)
		beq.b	.NoMask
		move.l	d0,d2
		movea.l	(stack_Mask,a5),a0
		moveq	#STVFORMAT_BIN,d0
		bsr	StringToValue
		or.l	d0,d2
		move.l	d2,d0
.NoMask		tst.l	(stack_C,a5)
		beq.b	.NotCtrlC
		bchg	#SIGBREAKB_CTRL_C,d0
.NotCtrlC	tst.l	(stack_D,a5)
		beq.b	.NotCtrlD
		bchg	#SIGBREAKB_CTRL_D,d0
.NotCtrlD	tst.l	(stack_E,a5)
		beq.b	.NotCtrlE
		bchg	#SIGBREAKB_CTRL_E,d0
.NotCtrlE	tst.l	(stack_F,a5)
		beq.b	.NotCtrlF
		bchg	#SIGBREAKB_CTRL_F,d0
.NotCtrlF	tst.l	d0
		bne.b	.Nothing
		move.l	#SIGBREAKF_CTRL_C,d0
.Nothing	move.l	d0,d6

;--------------	find process
		tst.l	(stack_Process,a5)
		beq	.NoProcess
		movea.l	(stack_Process,a5),a0
.ProcessLoop	move.l	(a0)+,d7	; find NULL ptr
		beq	.Ready
		move.l	a0,(stack_Process,a5) ; next process-ptr
 		movea.l	d7,a0 
		move.l	(a0),d7
		movea.l	(execBase).w,a6
		lea	(TaskWait,a6),a1
		movea.l	(LH_HEAD,a1),a1
.FindProcess	tst.l	(LN_SUCC,a1)
		beq.b	.ProcNotFound
		cmpi.b	#NT_PROCESS,(LN_TYPE,a1)
		bne.b	.IsNotAProcess
		tst.l	(pr_TaskNum,a1)
		beq.b	.IsNotAProcess
		cmp.l	(pr_TaskNum,a1),d7
		bne.b	.IsNotAProcess
		bsr.b	.MProcessFound
		movea.l	(stack_Process,a5),a0
		bra.b	.ProcessLoop
.IsNotAProcess	movea.l	(LN_SUCC,a1),a1
		bra.b	.FindProcess

;--------------	found a process -> send signal mask
.MProcessFound	move.l	d6,d0
		CALL	Signal
		rts

;--------------	process found -> send signal mask
.ProcessFound	move.l	d6,d0
		CALL	Signal,<(execBase).w>
		bra.b	.Ready

;--------------	process not found -> send error message
.ProcNotFound	lea	(NoProcessMsg,pc),a0
		lea	(stack_Argument,a5),a1
		move.l	d7,(stack_Argument,a5)

;--------------	=> a0:APTR String
;--------------	   a1:APTR Argumente
.Ausgabe	move.l	a0,d1
		move.l	a1,d2
		CALL	VPrintf,<(stack_DosBase,a5)>
		bra.b	.Ready

;--------------	find task by name
.NoProcess	tst.l	(stack_Name,a5)
		beq.b	.NoName
		movea.l	(stack_Name,a5),a1
		bsr	FindTask
		tst.l	d0
		beq.b	.NameNotFound
		movea.l	d0,a1
		bra.b	.ProcessFound
.NameNotFound	lea	(NoNameMsg,pc),a0
		lea	(stack_Name,a5),a1
		bra.b	.Ausgabe

;--------------	find task by address
.NoName		tst.l	(stack_Task,a5)
		beq.b	.NoAddr
		movea.l	(stack_Task,a5),a0
		moveq	#STVFORMAT_HEX,d0
		bsr	StringToValue
		tst.l	d0
		beq.b	.AddrNotFound
		bclr	#0,d0	; skip odd addr
		movea.l	d0,a1
		cmpi.b	#NT_PROCESS,(LN_TYPE,a1)
		beq.b	.ProcessFound
		cmpi.b	#NT_TASK,(LN_TYPE,a1)
		beq.b	.ProcessFound
.AddrNotFound	lea	(NoAddrMsg,pc),a0
		lea	(stack_Argument,a5),a1
		move.l	d0,(a1)
		bra	.Ausgabe
.NoAddr		moveq	#ERROR_REQUIRED_ARG_MISSING,d1
		moveq	#0,d2
		CALL	PrintFault,<(stack_DosBase,a5)>

;--------------	close everything
.Ready		bsr.b	FreeDosArgs
		moveq	#RETURN_OK,d0
		bra.b	main_done

;--------------	error opening the dos.library
.NODOSBASE	moveq	#RETURN_FAIL,d0
		bra.b	main_done
		
;--------------	show dos.library error
.DOSERROR	bsr	ShowDosError
		bsr.b	FreeDosArgs
		moveq	#RETURN_ERROR,d0
		DONE	main

*******************************************************************************
;--------------	free dos arguments
;--------------	
		ENTRY	FreeDosArgs
		move.l	(stack_ReadArgs,a5),d1
		beq.b	1$
		clr.l	(stack_ReadArgs,a5)
		CALL	FreeArgs,<(stack_DosBase,a5)>
1$		DONE	FreeDosArgs

*******************************************************************************
;--------------	Diese Funktion konvertiert einen String in eine Zahl, wobei der
;--------------	String in Hexadezimal($),Dezimal(#),Oktal(@) oder Dual(%) vorliegen
;--------------	kann. Zusätzlich kann eine Voreinstellung angenommen werden, um
;--------------	z.B. ständige '#' bei rein Dezimalen Strings zu überbrücken.
;--------------	Irgendwann mal in absolut ferner Zukunft habe ich vor, hier noch
;--------------	einen 'Calculator' reinzuhängen: Damit wäre in jedem Programm,
;--------------	daß über StringToValue aus Strings Zahlen macht, gleich eine
;--------------	Taschenrechnerfunktion drinnen..
;--------------	=> d0: ULONG Vordefinierter Typ des Strings
;--------------	   a0: APTR Der String mit der Zahl
;--------------	<= d0: LONG Die (vorzeichenbehaftete) IntegerZahl

;--------------	Voreinstellungen für StringToValue()
STVFORMAT_DEC	equ	0
STVFORMAT_HEX	equ	1
STVFORMAT_OCT	equ	2
STVFORMAT_BIN	equ	3

;--------------	Identifikatoren für StringToValue()
STVTYPE_DEC	equ	'#'
STVTYPE_HEX	equ	'$'
STVTYPE_OCT	equ	'@'
STVTYPE_BIN	equ	'%'

		ENTRY	StringToValue,d1-d2
		moveq	#10,d2
		cmpi.b	#STVFORMAT_HEX,d0
		bne.b	.NotHex
		moveq	#16,d2
.NotHex		cmpi.b	#STVFORMAT_BIN,d0
		bne.b	.NotBin
		moveq	#2,d2
.NotBin		cmpi.b	#STVFORMAT_OCT,d0
		bne.b	.NotOct
		moveq	#8,d2
.NotOct		cmpi.b	#'-',(a0)
		bne.b	.NormalUse
		addq.l	#1,a0
		bsr.b	.Check4Sign
		bsr.b	.Get_s2v
		neg.l	d0
		bra	StringToValue_done

.NormalUse	bsr.b	.Check4Sign
		bsr.b	.Get_s2v
		bra	StringToValue_done

.Check4Sign	move.b	(a0),d0
		cmpi.b	#STVTYPE_DEC,d0
		bne.b	1$
		moveq	#10,d2
		addq.l	#1,a0
1$		cmpi.b	#STVTYPE_HEX,d0
		bne.b	2$
		moveq	#16,d2
		addq.l	#1,a0
2$		cmpi.b	#STVTYPE_OCT,d0
		bne.b	3$
		moveq	#8,d2
		addq.l	#1,a0
3$		cmpi.b	#STVTYPE_BIN,d0
		bne.b	4$
		moveq	#2,d2
		addq.l	#1,a0
4$		moveq	#0,d0
		rts

.Get_s2v	moveq	#0,d1
		move.b	(a0)+,d1
		cmpi.b	#'a',d1
		blt.b	.NoUpcaseChose
		cmpi.b	#'z',d1
		bgt.b	.NoUpcaseChose
		sub.b	#('a'-'A'),d1 
.NoUpcaseChose 	subi.b	#"0",d1
		cmpi.b	#10,d1
		bls.b	.s2v_Overdose
		cmpi.l	#16,d2
		bne.s	.s2v_Overdose
		subq.b	#'A'-('9'+1),d1
.s2v_Overdose	cmp.b	d2,d1
		bcc.b	.s2v_Done
		bsr.b	ExtendedMulu
		add.w	d1,d0
		bra.b	.Get_s2v
.s2v_Done	rts
		DONE	StringToValue

;--------------	Diese Funktion Multipliziert zwei Langwerte
;--------------	=> d1: LONG Wert 1 
;--------------	   d2: LONG Wert 2
;--------------	<= d0: LONG Result
		ENTRY	ExtendedMulu,d1/d2
		cmpi.l	#$7FFF,d2
		bcc.b	2$
		cmpi.l	#$7FFF,d0
		bcc.b	2$
		mulu	d2,d0
		bra.b	ExtendedMulu_done
2$		moveq	#0,d1
		subq.l	#1,d2
1$		add.l	d0,d1
		dbra	d2,1$
		move.l	d1,d0
		DONE	ExtendedMulu

*******************************************************************************
;--------------	=> a1: STRPTR taskname
;--------------	
		ENTRY	FindTask,d5-d7/a0-a6
		CALL	Forbid,<(execBase).w>
		lea	(TaskReady,a6),a0
		bsr.b	.FINDTASK
		tst.l	d0
		bne.b	.FOUND
		lea	(TaskWait,a6),a0
		bsr.b	.FINDTASK
.FOUND		CALL	Permit
		bra.b	FindTask_done

.FINDTASK	movea.l	(LH_HEAD,a0),a0
.LOOP		tst.l	(LN_SUCC,a0)
		beq.b	.NOTFOUND
		movea.l	(LN_NAME,a0),a2
		movea.l	a1,a3
		cmpi.b	#NT_PROCESS,(LN_TYPE,a0)
		bne.b	.STRCMP
		tst.l	(pr_TaskNum,a0)
		beq.b	.STRCMP
		move.l	(pr_CLI,a0),d1
		lsl.l	#2,d1
		movea.l	d1,a2
		move.l	(cli_CommandName,a2),d1
		lsl.l	#2,d1
		addq.l	#1,d1
		movea.l	d1,a2
.STRCMP		move.b	(a2)+,d1
		move.b	(a3)+,d2
		cmp.b	d1,d2
		bne.b	.NEXT
		tst.b	d1
		bne.b	.STRCMP
		move.l	a0,d0
		rts
.NEXT		movea.l	(LN_SUCC,a0),a0
		bra.b	.LOOP
.NOTFOUND	moveq	#0,d0
		rts
		DONE	FindTask

*******************************************************************************
;--------------	show dos.library error
		ENTRY	ShowDosError
		CALL	IoErr,<(stack_DosBase,a5)>
		move.l	d0,d1
		moveq	#0,d2
		CALL	PrintFault
		DONE	ShowDosError

;--------------	data area
dosName		cstr	'dos.library'
		cstr	'$VER: break ',_VALOF(VERSION),'.',_VALOF(REVISION),'a (1.8.1992)'
argTemplate	cstr	'PROCESS/N/M,NAME/K,TASK/K,MASK/K,ALL/S,C/S,D/S,E/S,F/S'
NoProcessMsg	cstr	'Process %ld does not exist\n'
NoNameMsg	cstr	'No task named "%s" exists\n'
NoAddrMsg	cstr	'$%lx does not point to a task\n'
		even

		end

*******************************************************************************
;--------------	
