	opt	O+,i+

	incdir	include:
	include	exec/execbase.i
	include	libraries/dosextens.i
	include	exec/exec_lib.i
	include	libraries/arpbase.i

	rsreset
tNAME	rs.l	1
tADDR	rs.l	1
tCLI	rs.l	1
tPRI	rs.l	1
tREMOVE	rs.l	1
tFREEZE	rs.l	1
tWAIT	rs.l	1
tREADY	rs.l	1
tEXIT	rs.l	1
tBREAK	rs.l	1
tARP	rs.l	1
tPRIVAL	rs.l	1
tABASE	rs.l	1
tUDATA	rs.l	1
tMTASK	rs.l	1
tTASKPC	rs.l	1
tFEXA	rs.b	1
tSIGNAL	rs.b	1
tEND	rs.w	0	;Anzahl	der zu reservierenden Bytes


	OPENARP		;Wir nutzen ARP
	move.l	(_SysBase).w,a5
	movem.l	(sp)+,a0/d0
	moveq.l	#0,d7
	lea	HELP.msg(pc),a1
	lea	-tEND(sp),sp
	move.l	sp,a2
	move.l	a6,tABASE(a2)
	clr.b	tFEXA(a2)
	lea	TPLATE.msg(pc),a3
	SYSCALL	GADS		;Argumente auswerten
	move.l	d0,d0
	bmi	Default	;Fehler in der Argumenten-Liste
	bne.s	ArgsDa
	move.l	d0,tNAME(a2)	;"Default-Werte" löschen, damit
	move.l	d0,tADDR(a2)	;sie nachher nicht falsch inter-
	move.l	d0,tCLI(a2)	;pretiert werden
	bra.s	NoPri
ArgsDa	move.l	tNAME(a2),d0
	bne.s	NameDa
	move.l	tADDR(a2),d0
	bne.s	NameDa
	move.l	tCLI(a2),d0
	beq	Default	;Manipulationen am nichtangegebenen Task ?!?
NameDa	move.l	tPRI(a2),a0
	move.l	a0,d0
	beq.s	NoPri
	SYSCALL	Atol
	beq.s	NoPri	;Fehler bei der Zahlen-Auswertung
	move.l	d0,d1
	andi.l	#$ff,d1
	ext.w	d1
	ext.l	d1
	cmp.l	d0,d1
	beq.s	PriOK
	clr.l	tPRI(a2)
	lea	PRIVALUES.msg(pc),a1
	SYSCALL	Puts
PriOK	move.l	d0,tPRIVAL(a2)
NoPri	move.l	tCLI(a2),d0
	beq.s	.noCLI
	move.l	d0,a0
	SYSCALL	Atol
	move.l	d0,tCLI(a2)
.noCLI	moveq.l	#0,d5
	exg.l	a5,a6
	SYSCALL	Disable
	bsr	_ReadTasks
	move.l	d0,d7
	move.l	tADDR(a2),d0
	beq	NoAddress
	move.l	d0,a0
	bsr	_HexToDez
	move.l	d0,tADDR(a2)

	move.l	d7,d1
	move.l	sp,a3
AddrLoop	move.l	(a3)+,a1
	cmp.l	a1,d0
	beq.s	AddrFound
	subq	#1,d1
	bne.s	AddrLoop

NoMoreAddr	move.l	d0,-(sp)
	SYSCALL	Enable	;Interrupts wieder zulassen
	exg.l	a5,a6	;ArpBase wieder nach a6
	move.l	sp,a1
	lea	NOADDR.msg(pc),a0
	SYSCALL	Printf
	addq.l	#4,sp
	bra	CleanUp

AddrFound	move.l	tCLI(a2),d1
	beq.s	NoCLIAddr
	cmp.l	pr_TaskNum(a1),d1
	bne.s	FalseCLIAddr
	cmp.b	#NT_PROCESS,LN_TYPE(a1)
	beq.s	NoCLIAddr
FalseCLIAddr	movem.l	d0/d1,-(sp)
	SYSCALL	Enable
	exg.l	a5,a6
	move.l	sp,a1
	lea	NOADDRCLI.msg(pc),a0
	SYSCALL	Printf
	addq.l	#8,sp
	bra	CleanUp
	
NoCLIAddr	move.l	tNAME(a2),d0
	beq.s	Operate1
	move.l	d0,a0
	move.l	LN_NAME(a1),a3
.cmploop	cmpm.b	(a0)+,(a3)+
	bne.s	NotRight
	tst.b	-1(a0)
	bne.s	.cmploop
Operate1	bsr	_Operate
	bra	CleanUp
NotRight	move.l	a1,-(sp)
	move.l	d0,-(sp)
	SYSCALL	Enable	;Interrupts wieder zulassen
	move.l	sp,a1
	lea	NOADDRNAME.msg(pc),a0
	SYSCALL	Printf
	addq.l	#8,sp
	bra	CleanUp

NoAddress	move.l	tCLI(a2),a0
	move.l	a0,d0
	beq.s	NoCLI
	
	move.l	d7,d1
	move.l	sp,a3
CLILoop	move.l	(a3)+,a1
	cmp.l	pr_TaskNum(a1),d0
	beq.s	CLIFound
NotProc	subq	#1,d1
	bne.s	CLILoop

	move.l	d0,-(sp)
	SYSCALL	Enable	;Interrupts wieder zulassen
	exg.l	a5,a6	;ArpBase wieder nach a6
	move.l	sp,a1
	lea	NOCLI.msg(pc),a0
	SYSCALL	Printf
	addq.l	#4,sp
	bra	CleanUp

CLIFound	cmp.b	#NT_PROCESS,LN_TYPE(a1)
	bne.s	NotProc
	move.l	tNAME(a2),d1
	beq.s	Operate1
	move.l	d1,a0
	move.l	LN_NAME(a1),a3
.cmploop	cmpm.b	(a0)+,(a3)+
	bne.s	.NotRight
	tst.b	-1(a0)
	bne.s	.cmploop
	bra.s	Operate1
.NotRight	movem.l	d0,-(sp)
	move.l	d1,-(sp)
	SYSCALL	Enable	;Interrupts wieder zulassen
	exg.l	a5,a6
	move.l	sp,a1
	lea	NOCLINAME.msg(pc),a0
	SYSCALL	Printf
	addq.l	#8,sp
	bra	CleanUp
	

NoCLI	move.l	tNAME(a2),d0
	beq.s	ListAllTasks
	move.l	d7,d1
	subq	#1,d1
	move.l	sp,a3
	moveq	#0,d6
NamLoop	move.l	(a3)+,a1
	subq	#1,d1
	beq.s	NoMoreNams
	move.l	d0,a4
	move.l	LN_NAME(a1),a0
NcmpLoop	cmpm.b	(a0)+,(a4)+
	bne.s	NamLoop
	tst.b	-1(a0)
	bne.s	NcmpLoop
	move.l	d6,d6
	bne.s	MoreTOne
	move.l	a1,d6
	bra.s	NamLoop

MoreTOne	move.l	d0,-(sp)
	SYSCALL	Enable
	move.l	sp,a1
	exg.l	a5,a6
	lea	MORETHANONE.msg(pc),a0
	SYSCALL	Printf
	addq.l	#4,sp
	bra.s	ListAllTasks1

NoMoreNams	move.l	d6,a1
	move.l	d6,d6
	bne	Operate1
	move.l	d0,-(sp)
	SYSCALL	Enable
	move.l	sp,a1
	exg.l	a5,a6
	lea	NOTASKNAME.msg(pc),a0
	SYSCALL	Printf
	addq.l	#4,sp
	bra.s	NoTask

ListAllTasks	SYSCALL	Enable
	exg.l	a5,a6
ListAllTasks1	move.l	d7,d2
	lsl.l	#2,d2
TLoop	move.l	-4(sp,d2.l),a0
	bsr.s	_Examine
	subq	#4,d2
	bne.s	TLoop

NoTask	lea	CHR10.msg(pc),a0
	SYSCALL	Printf
	bra.s	CleanUp

Default	lea	HELP.msg(pc),a1
	SYSCALL	Puts
	moveq.l	#120,d1
	bra.s	HauAb

CleanUp1	SYSCALL	Enable
	exg.l	a5,a6
CleanUp	moveq.l	#0,d1
HauAb	moveq.l	#0,d0
	SYSCALL	ArpExit


_Examine	movem.l	a3/a4,-(sp)	;a0=Task, a2=Args, a6=ARP
	move.l	a0,a4
	move.b	tFEXA(a2),d0
	bne.s	DisplAl
	lea	Listext(pc),a1
	SYSCALL	Puts
	move.b	#-1,tFEXA(a2)

DisplAl	move.l	sp,a3		;flexibler Stapel
	move.w	pr_TaskNum+2(a4),-(sp)
	move.l	pr_CLI(a4),d0
	asl.l	#2,d0
	move.l	d0,a1
	move.l	cli_CommandName(a1),d0
	asl.l	#2,d0
	addq.l	#1,d0
	move.l	d0,-(sp)
	move.l	TC_Struct+LN_NAME(a4),-(sp)
	move.b	TC_Struct+LN_PRI(a4),d0
	ext.w	d0
	move.w	d0,-(sp)
	moveq.l	#0,d0
	pea	Invalid(pc)
	move.b	TC_STATE(a4),d0
	rol	#3,d0
	add.l	d0,(sp)
	move.l	TC_SPUPPER(a4),d0
	sub.l	TC_SPLOWER(a4),d0
	move.l	d0,-(sp)
	move.l	pr_SegList(a4),-(sp)
	cmpi.b	#NT_PROCESS,TC_Struct+LN_TYPE(a4)
	bne.s	NormTask
	move.l	pr_TaskNum(a4),d0
	beq.s	NoCli
	lea	CLI.schab(pc),a0
	bra.s	TypeOk
NoCli	lea	PROCESS.schab(pc),a0
	bra.s	TypeOk
NormTask	lea	TASK.schab(pc),a0
	addq.l	#4,sp
TypeOk	move.l	a4,-(sp)
	move.l	sp,a1
	SYSCALL	Printf
	move.l	a3,sp
	movem.l	(sp)+,a3/a4
	rts

_Operate	;a1=Task,	a6=SysBase
	move.l	a1,-(sp)
	move.l	tPRI(a2),d0
	beq.s	.L1
	move.l	tPRIVAL(a2),d0
	bsr	Priori
	move.l	(sp),a1
.L1	move.l	tBREAK(a2),d0
	beq.s	.L2
	cmp.l	ThisTask(a6),a1
	beq	OwnTask
	cmp.b	#9,TC_STATE(a1)
	beq	Swapped
	bsr	TaskBreak
	move.l	(sp),a1
.L2	move.l	tFREEZE(a2),d0
	beq.s	.L3.1
	cmp.l	ThisTask(a6),a1
	beq	OwnTask
	cmp.b	#9,TC_STATE(a1)
	beq	Swapped
	bsr	SetFreeze
	move.l	(sp),a1
.L3.1	move.l	tREADY(a2),d0
	beq.s	.L3.2
	cmp.l	ThisTask(a6),a1
	beq.s	OwnTask
	cmp.b	#9,TC_STATE(a1)
	beq	Swapped
	bsr	SetReady
	move.l	(sp),a1
.L3.2	move.l	tWAIT(a2),d0
	beq.s	.L3
	cmp.l	ThisTask(a6),a1
	beq.s	OwnTask
	cmp.b	#9,TC_STATE(a1)
	beq.s	Swapped
	bsr	SetWait
	move.l	(sp),a1
.L3	move.l	tEXIT(a2),d0
	beq.s	.L4
	cmp.l	ThisTask(a6),a1
	beq.s	OwnTask
	cmp.b	#9,TC_STATE(a1)
	beq.s	Swapped
	cmp.b	#NT_PROCESS,LN_TYPE(a1)
	bne.s	NoProc
	bsr	SetExit
	bra.s	.L5
	move.l	(sp),a1
.L4	move.l	tREMOVE(a2),d0
	beq.s	.L5
	cmp.l	ThisTask(a6),a1
	beq.s	OwnTask
	cmp.b	#9,TC_STATE(a1)
	beq.s	Swapped
	bsr	Remove
.L5	SYSCALL	Enable
	move.l	(sp)+,a0
	exg.l	a5,a6
	bra	_Examine
OwnTask	SYSCALL	Enable
	exg.l	a5,a6
	lea	OWNTASK.msg(pc),a1
	SYSCALL	Puts
	move.l	(sp)+,a0
	bra	_Examine
NoProc	SYSCALL	Enable
	exg.l	a5,a6
	lea	NOPROC.msg(pc),a1
	SYSCALL	Puts
	move.l	(sp)+,a0
	bra	_Examine
Swapped	SYSCALL	Enable
	exg.l	a5,a6
	lea	SWAPPED.msg(pc),a1
	SYSCALL	Puts
	move.l	(sp)+,a0
	bra	_Examine

Priori	SYSCALL	SetTaskPri
	rts
TaskBreak	moveq.l	#15<<4,d0
	rol.l	#8,d0
	SYSCALL	Signal
	rts
SetFreeze	move.l	a1,-(sp)
	SYSCALL	Remove
	move.l	(sp)+,a1
	move.b	#8,TC_STATE(a1)
	lea	IntrList(a6),a0
	SYSCALL	Enqueue
	rts
SetWait	move.l	a1,-(sp)
	SYSCALL	Remove
	move.l	(sp)+,a1
	move.b	#TS_WAIT,TC_STATE(a1)
	lea	TaskWait(a6),a0
	SYSCALL	AddTail
	rts
SetReady	move.l	a1,-(sp)
	SYSCALL	Remove
	move.l	(sp)+,a1
	move.b	#TS_READY,TC_STATE(a1)
	lea	TaskReady(a6),a0
	SYSCALL	Enqueue
	rts

SetExit	moveq	#-1,d0
	move.l	a1,-(sp)
	SYSCALL	AllocSignal
	move.l	(sp)+,a1
	move.b	d0,tSIGNAL(a2)
	addq	#1,d0
	beq.s	.fail
	move.l	ThisTask(a6),tMTASK(a2)
	move.l	TC_SPREG(a1),a0
	move.l	(a0),tTASKPC(a2)
	move.l	a2,-(sp)
	lea	_ExitCode(pc),a2
	move.l	a2,(a0)
	move.l	(sp)+,a2
	move.l	TC_Userdata(a1),tUDATA(a2)
	move.l	a2,TC_Userdata(a1)
	bsr.s	SetReady
	moveq	#0,d1
	moveq	#0,d0
	move.b	tSIGNAL(a2),d1
	bset.l	d1,d0
	SYSCALL	Wait
	moveq	#0,d0
	move.b	tSIGNAL(a2),d0
	SYSCALL	FreeSignal
.fail	rts

Remove	SYSCALL	RemTask
	rts

_ExitCode	clr.l	-(sp)
	movem.l	d0/d1/a0-a2/a6,-(sp)
	move.l	(_SysBase).w,a6
	SYSCALL	Forbid
	move.l	ThisTask(a6),a1
	move.l	TC_Userdata(a1),a2
	move.l	tUDATA(a2),TC_Userdata(a1)
	move.l	tTASKPC(a2),24(sp)
	moveq	#0,d0
	moveq	#0,d1
	move.b	tSIGNAL(a2),d1
	bset.l	d1,d0
	move.l	tMTASK(a2),a1
	SYSCALL	Signal
	move.l	tABASE(a2),a6
	moveq	#0,d0
	tst.l	tARP(a2)
	beq.s	.narp
	SYSCALL	ArpExit
.narp	SYSCALL	Exit
	movem.l	(sp)+,d0/d1/a0-a2/a6
	rts

_ReadTasks	;a6=SysBase	;Zurück: d0=Taskeinträge
	move.l	(sp)+,a1
	move.l	ThisTask(a6),-(sp)
	moveq	#1,d0
	move.l	TaskReady(a6),a0
ReadyLoop	move.l	(a0),d1	;ReadyTask-Liste auslesen
	beq.s	ReadWait
	move.l	a0,-(sp)
	addq	#1,d0
	move.l	d1,a0
	bra.s	ReadyLoop

ReadWait	move.l	TaskWait(a6),a0
WaitLoop	move.l	(a0),d1	;WaitTask-Liste auslesen
	beq.s	ReadFroz
	move.l	a0,-(sp)
	addq	#1,d0
	move.l	d1,a0
	bra.s	WaitLoop

ReadFroz	move.l	IntrList(a6),a0
FrozLoop	move.l	(a0),d1	;Frozn-Liste auslesen
	beq.s	ReadAll
	cmpi.b	#NT_TASK,LN_TYPE(a0)
	beq.s	.istask
	cmpi.b	#NT_PROCESS,LN_TYPE(a0)
	bne.s	.notask
.istask	move.l	a0,-(sp)
	addq	#1,d0
.notask	move.l	d1,a0
	bra.s	FrozLoop
ReadAll	jmp	(a1)

_HexToDez	;a0=HexString, Zurück: d0=Zahl
	moveq.l	#0,d0
	moveq.l	#0,d1
HexLoop	move.b	(a0)+,d1
	beq.s	AllHex
	lsl.l	#4,d0
	cmpi.b	#'9',d1
	ble.s	IsNum
	addi.w	#9,d1
IsNum	andi.w	#15,d1
	or.b	d1,d0
	bra.s	HexLoop
AllHex	rts


	dc.b	'$VER: Act 1.0 (25.10.95)',0
Listext	dc.b	'Taskadress  SegList  StackSize  State   Pri.  Name',10
	dc.b	'----------  -------  ---------  -----   ----  ----',0
Invalid	dc.b	'INVALID',0
	dc.b	'  ADDED',0
	dc.b	'RUNNING',0
	dc.b	'  READY',0
	dc.b	'WAITING',0
	dc.b	' EXCEPT',0
	dc.b	'REMOVED',0
	dc.b	'UNKNOWN',0
	dc.b	'  FROZN',0
	dc.b	'SWAPPED',0
CLI.schab	dc.b	'%9lx%9lx%11ld%9s%6d %s [%s][%d]',10,0
PROCESS.schab	dc.b	'%9lx%9lx%11ld%9s%6d %s',10,0
TASK.schab	dc.b	'%9lx%20ld%9s%6d %s'
CHR10.msg	dc.b	10,0
OWNTASK.msg	dc.b	'Can''t manipulate own Task with ''REMOVE'', ''FREEZE'', ''WAIT'', ''READY'', ''EXIT'' or ''BREAK''.',0
NOCLI.msg	dc.b	'No Task with CLI Number %ld found.',10,0
NOADDRCLI.msg	dc.b	'No Task on Address %lx with CLI Number %ld found.',10,0
NOCLINAME.msg	dc.b	'No Task named ''%s'' with CLI Number %ld found.',10,0
NOADDR.msg	dc.b	'No Task on Address %lx found.',10,0
NOADDRNAME.msg	dc.b	'No Task named ''%s'' on Address %lx found.',10,0
NOTASKNAME.msg	dc.b	'No Task named ''%s'' found.',10,0
MORETHANONE.msg	dc.b	'There are more Tasks than one named ''%s''. Please specify',10,0
SWAPPED.msg	dc.b	'Can''t manipulate SWAPPED Task with ''REMOVE'', ''FREEZE'', ''WAIT'', ''READY'', ''EXIT'' or ''BREAK'' yet.',0
NOPROC.msg	dc.b	'Can''t manipulate this Task with EXIT(). It is not a Process!',10,0
PRIVALUES.msg	dc.b	'PRI must be between -128 and 127.',0
TPLATE.msg	dc.b	'NAME,ADDR/k,CLI/k,PRI/k,REMOVE/s,FREEZE/s,WAIT/s,READY/s,EXIT/s,BREAK/s,ARP/s',0
HELP.msg	dc.b	'Usage: Act [NAME taskname] [ADDR taskaddress(hex)] [CLI clinum] '
		dc.b	'[PRI pri] [REMOVE] [FREEZE] [WAIT] [READY] [EXIT] [BREAK] [ARP]',0
		
