

****************************************************
********   ZSHELL (C) 1990,91 Paul Hayter   ********
********  updated to V2.0 by Martin Gierich ********
********    First major change: 08.06.93    ********
********	Last change: 06.06.94	    ********
****************************************************

***		TABSIZE = 8 Chars		 ***
***	 Local Labels named .A to .Z		 ***

FIB			equ	260		;FileInfoBlock
ACCESS_READ		equ	-2
ACCESS_WRITE		equ	-1
MODE_READWRITE		equ	1004
MODE_OLDFILE		equ	1005
MODE_NEWFILE		equ	1006

* DOS LIBRARY
dl_A2			equ	42

SIGBREAKB_CTRL_C	equ	$0C
SIGBREAKB_CTRL_D	equ	$0D
SIGBREAKB_CTRL_E	equ	$0E
SIGBREAKB_CTRL_F	equ	$0F
	
* FILE INFO BLOCK
fib_DiskKey		equ  $0000
fib_DirEntryType	equ  $0004
fib_FileName		equ  $0008
fib_Protection		equ  $0074
fib_EntryType		equ  $0078
fib_Size		equ  $007c
fib_NumBlocks		equ  $0080
fib_Date		equ  $0084
fib_Comment		equ  $0090
fib_Reserved		equ  $00e0

* INFO DATA STRUCTURE
id_NumSoftErrors	equ	0
id_UnitNumber		equ	4
id_DiskState		equ	8
id_NumBlocks		equ	12
id_NumBlocksUsed	equ	16
id_BytesPerBlock	equ	20
id_DiskType		equ	24
id_VolumeNode		equ	28
id_InUse		equ	32

* TASK
tc_State		equ	15
tc_SigWait		equ	22

* PROCESS
pr_MsgPort		equ	92
pr_SegList		equ	128
pr_StackSize		equ	132
pr_GlobVec		equ	136
pr_TaskNum		equ	140
pr_StackBase		equ	144
pr_Result2		equ	148
pr_CurrentDir		equ	152
pr_CIS			equ	156
pr_COS			equ	160
pr_ConsoleTask		equ	164
pr_FileSystemTask	equ	168
pr_CLI			equ	172
pr_ReturnAddr		equ	176
pr_PktWait		equ	180
pr_WindowPtr		equ	184

* COMMAND LINE INTERFACE
cli_Result		equ	0
cli_SetName		equ	4
cli_CommandDir		equ	8
cli_ReturnCode		equ	12
cli_CommandName		equ	16
cli_FailLevel		equ	20
cli_Prompt		equ	24
cli_StandardInput	equ	28
cli_CurrentInput	equ	32
cli_CommandFile		equ	36
cli_Interactive		equ	40
cli_Background		equ	44
cli_CurrentOutput	equ	48
cli_DefaultStack	equ	52
cli_StandardOutput	equ	56
cli_Module		equ	60

* FILE HANDLE
fh_Link			equ	0
fh_Port			equ	4
fh_Type			equ	8
fh_Buf			equ	12
fh_Pos			equ	16
fh_End			equ	20

* FILE LOCK
fl_Link			equ	0
fl_Key			equ	4
fl_Access		equ	8
fl_Task			equ	12
fl_Volume		equ	16

* DATESTAMP
ds_Days			equ	0
ds_Minute		equ	4
ds_Tick			equ	8

RETURN_OK		EQU  0
RETURN_WARN		EQU  5
RETURN_ERROR		EQU  10
RETURN_BAD		EQU  15
RETURN_FAIL		EQU  20

*Assign Stuff
dl_Root		equ	34	APTR
rn_Info		equ	24	BPTR
di_DevInfo	equ	4	BPTR
di_NetHand	equ	16	BPTR
dvi_Next	equ	0	BPTR
dvi_Type	equ	4	LONG
dvi_Task	equ	8	APTR
dvi_Lock	equ	12	BPTR
dvi_Handler	equ	16
dvi_StackSize	equ	20
dvi_Priority	equ	24
dvi_Startup	equ	28
dvi_SegList	equ	32
dvi_GlobVec	equ	36
dvi_Name	equ	40	BSTR
dt_device	equ	0	<-- contents of dvi_Type
dt_dir		equ	1
dt_volume	equ	2

*Resident Stuff
resi_link	equ	0	;BPTR
resi_usecount	equ	4	;LONG
resi_seglist	equ	8	;BPTR
resi_name	equ	12	;BSTR
resi_length	equ	4+4+4

*Icon Lib Stuff
sm_Process	equ	$14
sm_Segment	equ	$18
sm_NumArgs	equ	$1c
sm_ToolWindow	equ	$20
sm_ArgList	equ	$24
wa_Lock		equ	0
wa_Name		equ	4
do_Magic	equ	0	;must be $e310
do_Type		equ	$30
do_ToolTypes	equ	$36
do_ToolWindow	equ	$46
do_StackSize	equ	$4a

* AVAIL STUFF
MEMF_PUBLIC		equ 1
MEMF_CHIP		equ 2
MEMF_FAST		equ 4
MEMF_CLEAR		equ $10000
MEMF_LARGEST		equ $20000

* ACTIONS
ACTION_SCREEN_MODE	EQU	994
ACTION_INHIBIT		EQU	31
ACTION_MORE_CACHE	EQU	18
ACTION_RENAME_DISK	EQU	9
ACTION_DIE		EQU	5
ACTION_DISK_CHANGE	EQU	33
ACTION_SET_DATE		EQU	34
ACTION_DISK_INFO	EQU	25
ACTION_WRITE_PROTECT	EQU	1023
ACTION_FLUSH		EQU	27

dp_Link		EQU  $00   ;DosPacket Structure
dp_Port		EQU  $04
dp_Type		EQU  $08
dp_Arg1		EQU  $14
dp_SIZEOF	EQU  $30

sp_Msg		EQU  $00   ;StandardPacket Structure
sp_Pkt		EQU  $14
sp_SIZEOF	EQU  $44

LH_HEAD		equ	0
LH_TAIL		equ	4
LH_TAILPRED	equ	8
LH_TYPE		equ	12
LH_PAD		equ	13
LH_SIZE		equ	14

LN_SUCC		equ	0
LN_PRED		equ	4
LN_TYPE		equ	8
LN_PRI		equ	9
LN_NAME		equ	10
LN_SIZE		equ	14

NT_MSGPORT	EQU  4

MP_FLAGS	EQU  $0E   ;Message Port Structure
MP_SIGBIT	EQU  $0F   ;Signal bit number
MP_SIGTASK	EQU  $10   ;Task to be signalled
MP_MSGLIST	EQU  $14   ;Message linked list
MP_SIZE		EQU  $22

mn_ReplyPort	equ	14
mn_Length	equ	18
mn_Size		equ	20

PA_SIGNAL	EQU  0	   ;PutAction messages

	
* LIBRARY CALLS
* EXEC
_LVOOpenLibrary		equ	-552
_LVOCloseLibrary	equ	-414
_LVOSetFunction		equ	-420
_LVOAllocMem		equ	-198
_LVOFreeMem		equ	-210
_LVORawDoFmt		equ	-522
_LVORawMayGetChar	equ	-510
_LVOFindTask		equ	-294
_LVOSetTaskPri		equ	-300
_LVOAddTask		equ	-282
_LVOForbid		equ	-132
_LVOPermit		equ	-138
_LVOAvailMem		equ	-216
_LVOAddPort		equ	-354
_LVORemPort		equ	-360
_LVOFindPort		equ	-390
_LVOPutMsg		equ	-366
_LVOGetMsg		equ	-372
_LVOReplyMsg		equ	-378
_LVOWaitPort		equ	-384
_LVOWait		equ	-318
_LVOSignal		equ	-324
_LVOSetSignal		equ	-306
_LVOAllocSignal		equ	-330
_LVOFreeSignal		equ	-336
_LVOOpenDev		equ	-444
_LVOCloseDev		equ	-450
_LVODoIO		equ	-456

* DOS
_LVOSetProtection	equ	-186
_LVOOutput		equ	-60
_LVOWrite		equ	-48
_LVOLock		equ	-84
_LVOUnLock		equ	-90
_LVODupLock		equ	-96
_LVOExamine		equ	-102
_LVOExNext		equ	-108
_LVOOpen		equ	-30
_LVOClose		equ	-36
_LVORead		equ	-42
_LVOInput		equ	-54
_LVODeleteFile		equ	-72
_LVORename		equ	-78
_LVOCreateDir		equ	-120
_LVOCurrentDir		equ	-126
_LVOIoErr		equ	-132
_LVOParentDir		equ	-210
_LVOLoadSeg		equ	-150
_LVOUnLoadSeg		equ	-156
_LVOCreateProc		equ	-138
_LVOInfo		equ	-114
_LVODateStamp		equ	-192
_LVOSeek		equ	-66
_LVODeviceProc		equ	-174
_LVODelay		equ	-198
_LVOSetComment		equ	-180
_LVOIsInteractive	equ	-216

*Intuition
_LVOPrintIText		equ	-216
_LVODisplayBeep		equ	-96
_LVOLockIBase		equ	-414
_LVOUnlockIBase		equ	-420
_LVORefreshWindowFrame	equ	-456
_LVOSizeWindow		equ	-288
_LVOMoveWindow		equ	-168
_LVORemakeDisplay	equ	-384
_LVOMakeScreen		equ	-378
_LVORethinkDisplay	equ	-390

*Icon
_LVOGetDiskObject	equ	-78
_LVOFreeDiskObject	equ	-90
_LVOFindToolType	equ	-96
_LVOMatchToolValue	equ	-102


* NEED THESE 2 MACROS FOR A68K ASSEMBLER
;blo	macro
;	bcs \1
;	endm
	
;bhs	macro
;	bcc \1
;	endm

*SYSTEM0 stuff!!!!!!!!!!
REG_SysBase	equr a6

callsys	macro
	jsr _LVO\1(REG_SysBase)
	endm

* parameter offsets & stack
;SAVED_REGS	reg	a2-a6/d2-d3
DELTA		equ	7*4
ARG_NAME	equ	4+DELTA
ARG_SEGLIST	equ	8+DELTA
ARG_ARGS	equ	12+DELTA

* additional return codes
NO_CLI		equ	-1
NO_MEM		equ	-2

* local constants
MAXBSTR		equ	255
LF		equ	10

* register usage
REG_Result	equr	d3
REG_Process	equr	a2      ;may not be A4, see below!
REG_CLI		equr	a3
REG_CIS		equr	a4      ;may not be A3, see below!
REG_PrevStack	equr	a1	;V2.0 changed from a5 to a1

* local stack frame
* STRUCTURE      StackFrame,0
sf_CommandName	equ	0
sf_CommandArgs	equ	MAXBSTR+1        ;BSTR, length byte!
sf_PrevStack	equ	sf_CommandArgs+MAXBSTR+1        ;not a BSTR, LF-terminated!
sf_SaveReturnAddr	equ	sf_PrevStack+4
sf_SaveModule	equ	sf_SaveReturnAddr+4
sf_SaveCommandName	equ	sf_SaveModule+4
sf_StackBase	equ	sf_SaveCommandName+4
sf_StackSize	equ	sf_StackBase+4
sf_PushSize	equ	sf_StackSize+4
sf_Process	equ	sf_PushSize+4
sf_CLI		equ	sf_Process+4
sf_CIS		equ	sf_CLI+4
sf_SCB_Buf	equ	sf_CIS+4
sf_SCB_Pos	equ	sf_SCB_Buf+4
sf_SCB_End	equ	sf_SCB_Pos+4
sf_Membase	equ	sf_SCB_End+4
sf_SIZEOF	equ	sf_Membase+4

*Constants (only LONGS!)
SHELLINE_SIZE	equ	256	V1.30
CLIBUF_SIZE	equ	256
NEWPRINTSIZE	equ	200
PATH_SIZE	equ	256	V1.30
HISTORY_SIZE	equ	1024	MUST BE POWER OF 2
SEARCH_STRING_SIZE	equ	60
DEST_LABEL_SIZE	equ	60

* THE GENERAL MEMORY BLOCK (LONGS!)
blockbase	equ	0	;the fib or info goes here
sp_node		equ	blockbase+260	;DOSpacket
sp_reply	equ	sp_node+14
sp_length	equ	sp_reply+4
;sp_ptr		equ	;sp_ptr+4
sp_link		equ	sp_length+2
sp_port		equ	sp_link+4
packettype	equ	sp_port+4
sp_res1		equ	packettype+4
sp_res2		equ	sp_res1+4
myArg1		equ	sp_res2+4
myArg2		equ	myArg1+4
myArg3		equ	myArg2+4
myArg4		equ	myArg3+4
myArg5		equ	myArg4+4
myArg6		equ	myArg5+4
myArg7		equ	myArg6+4
packettask	equ	myArg7+4
devproc		equ	packettask+4
dirlock		equ	devproc+4
last_failcode	equ	dirlock+4
outhandle	equ	last_failcode+4	;Handles
inhandle	equ	outhandle+4
EntryA0		equ	inhandle+4
better_Seglist	equ	EntryA0+4
parm1		equ	better_Seglist+4 ;addr of each parameter within shelline
parm2		equ	parm1+4
parm3		equ	parm2+4
parm4		equ	parm3+4
parm5		equ	parm4+4
parm6		equ	parm5+4
parm7		equ	parm6+4
parm8		equ	parm7+4
parm9		equ	parm8+4
parm10		equ	parm9+4
parm11		equ	parm10+4
parm12		equ	parm11+4
parm13		equ	parm12+4
parm14		equ	parm13+4
parm15		equ	parm14+4
endofparms	equ	parm15+4+4*10	10 extra parms

shelline	equ	endofparms+4	for NULL-end		
endofshelline	equ	shelline+SHELLINE_SIZE

CLIbuf		equ	endofshelline
NewPrintBuffer	equ	CLIbuf+CLIBUF_SIZE
errorstack	equ	NewPrintBuffer+NEWPRINTSIZE
topstack	equ	errorstack+4
stacksize	equ	topstack+4
temp1		equ	stacksize+4
temp2		equ	temp1+4
temp3		equ	temp2+4
temp4		equ	temp3+4
tempbuf		equ	temp4+4
temp2buf	equ	tempbuf+2*SHELLINE_SIZE	;80 char temp buffer
dosbase		equ	temp2buf+80
intuibase	equ	dosbase+4
Result2		equ	intuibase+4
count_line	equ	Result2+4
ignoreit	equ	count_line+4	for filenamecompletition
unused_mem	equ	ignoreit+SEARCH_STRING_SIZE	for the future
bordersize	equ	unused_mem+12
scsize		equ	bordersize+4
scaddr		equ	scsize+4
scptr		equ	scaddr+4
scflag		equ	scptr+4		new v1.29
patharea	equ	scflag+2
now		equ	patharea+PATH_SIZE
nost		equ	now+4
then		equ	nost+4
past		equ	then+4	;history buffer=1024 bytes
thistask	equ	past+HISTORY_SIZE
gather_ptr	equ	thistask+4
gather		equ	gather_ptr+4 ;CSI string=40 bytes
tempbytes	equ	gather+40
first_set_defn	equ	tempbytes+2
set_search_string	equ	first_set_defn+4
line_count	equ	set_search_string+SEARCH_STRING_SIZE
mem_addr	equ	line_count+2
wild_flag	equ	mem_addr+4
stat_mode_flag	equ	wild_flag+1
wild_string	equ	stat_mode_flag+1	allow 80 chars for wildcard
date_mark	equ	wild_string+80	3 lwords
mem_mark	equ	date_mark+12	3 lwords chip/fast/total
CD_string	equ	mem_mark+12	Allow 80 bytes.
prompt_string	equ	CD_string+80	Allow 80 bytes.
prompt_args	equ	prompt_string+80	Allow 40 bytes
nonstdin	equ	prompt_args+40	Allow 40 bytes
nonstdout	equ	nonstdin+40	Allow 40 bytes
stdout		equ	nonstdout+40
stdin		equ	stdout+4
mult_comm_flag	equ	stdin+4
next_comm_ptr	equ	mult_comm_flag+2
ctrl_c_flag	equ	next_comm_ptr+4
failat_level	equ	ctrl_c_flag+2	word size
cd_block	equ	failat_level+2
cd_volnode	equ	cd_block+4
recurs_flag	equ	cd_volnode+4
indent_count	equ	recurs_flag+2
resi_flag	equ	indent_count+2
forcediskflag	equ	resi_flag+1
CLIflag		equ	forcediskflag+1
WBflag		equ	CLIflag+1
window_old	equ	WBflag+1
wb_msg		equ	window_old+4
iconbase	equ	wb_msg+4
diskobj		equ	iconbase+4
filesys_old	equ	diskobj+4
cdir_old	equ	filesys_old+4
cdback		equ	cdir_old+4
ctrl_codes	equ	cdback+4	Keyboard-CTRL-Codes
if_flag		equ	ctrl_codes+16
if_condition_flag	equ	if_flag+1
goto_flag	equ	if_condition_flag+1
kickver		equ	goto_flag+1
dest_label	equ	kickver+1
please_close_me	equ	dest_label+DEST_LABEL_SIZE
mem_offset_addr	equ	please_close_me+4
io_Message	equ	mem_offset_addr+4	;io-request (timer)
io_Device	equ	io_Message+20
io_Unit		equ	io_Device+4
io_Command	equ	io_Unit+4
io_Flags	equ	io_Command+2
io_Error	equ	io_Flags+1
tv_secs		equ	io_Error+1
tv_micro	equ	tv_secs+4
io_pad		equ	tv_micro+4	;don't remove
	
stackbot	equ	io_pad+8
sizeofblk	equ	stackbot



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

;	SECTION	MYSHELL,CODE
	
;Try to open dos then do the shell
start	moveq	#-1,d7
	move.l	a0,a2
	move.l	4.w,a6
	move.l	#sizeofblk,d0
	move.l	#1+1<<16,d1		"memf_public" & clear it
	jsr	_LVOAllocMem(a6)	alloc general mem block
	tst.l	d0
	beq	blkfail
	move.l	d0,a5			A5=MEMBASE
	move.l	sp,topstack(a5)
	move.l	a2,EntryA0(a5)
	cmp.w	#36,20(a6)		lib_Version
	blo.s	.D
	move.b	#2,kickver(a5)		KS2.0+
.D	moveq	#0,d0
	lea	intuiname(pc),a1
	jsr	_LVOOpenLibrary(a6)
	tst.l	d0
	beq	intfail
	move.l	d0,intuibase(a5)
	moveq	#0,d0
	lea	dosname(pc),a1
	jsr	_LVOOpenLibrary(a6)
	tst.l	d0
	beq	dosfail
	move.l	d0,dosbase(a5)
	clr.w	CLIflag(a5)		delete CLI&WBflag
	sub.l	a1,a1
	jsr	_LVOFindTask(a6)
	move.l	d0,thistask(a5)		save this task address
	move.l	d0,a2
	tst.l	pr_CLI(a2)
	bne.s	.A
	moveq	#-1,d0			WB-Start
	move.w	d0,CLIflag(a5)
	lea	pr_MsgPort(a2),a0
	jsr	_LVOWaitPort(a6)
	lea	pr_MsgPort(a2),a0
	jsr	_LVOGetMsg(a6)
	move.l	d0,wb_msg(a5)
	beq.s	.C
	move.l	d0,a0
	clr.l	sm_Segment(a0)		Clear Seg-Descriptor
.C	move.l	pr_StackSize(a2),stacksize(a5)
	move.l	pr_SegList(a2),a0
	add.l	a0,a0
	add.l	a0,a0
	clr.l	12(a0)			Clear SegPointer
	bra.s	.B
.A	move.l	pr_CLI(a2),a2		CLI-Start
	add.l	a2,a2
	add.l	a2,a2
	move.l	cli_DefaultStack(a2),d0
	asl.l	#2,d0
	move.l	d0,stacksize(a5)	save stacksize
	clr.l	cli_Module(a2)		do not free seglist
.B	move.l	dosbase(a5),a6		A6=DOSBASE
	lea	ZShellName(pc),a4
	bsr	search_res2
	lea	start-4(pc),a1
	tst.l	d0
	beq.s	cresi	!!!
	addq.l	#1,resi_usecount(a0)
	lsl.l	#2,d0
	cmp.l	a1,d0
	beq.s	doIT		running as resident
	add.l	#JumpIn-start+4,d0
	move.l	d0,a0
	jmp	(a0)	Jump to JumpIn, but in the resident Code
JumpIn	move.l	a1,d1	here it arrives
	lsr.l	#2,d1
	jsr	_LVOUnLoadSeg(a6)	free old mem
	bra.s	doIT
cresi	move.l	a1,d3
	lsr.l	#2,d3
	bsr	create_resi	make zshell resident
	bne	crfail
	addq.l	#1,resi_usecount(a2)
doIT	bsr	shell			***	DO IT	***
	bsr	deallocate_sets
	bsr	clkoff
	move.l	thistask(a5),a0
	move.l	window_old(a5),pr_WindowPtr(a0)
	bsr	RemoveCLI
	lea	ZShellName(pc),a4
	bsr	search_res2
	tst.l	d0
	beq.s	crfail
	subq.l	#1,resi_usecount(a0)
	tst.l	d7
	bne.s	crfail
	bsr	giveman		free manualmem
	moveq	#1,d1
	cmp.l	resi_usecount(a0),d1
	bne.s	crfail
	move.l	d0,d7	kill the ZShell-Resident
	move.l	a0,a2
	move.l	d2,a0
	move.l	resi_link(a2),resi_link(a0)
	clr.l	resi_link(a2)
	move.l	a2,d1
	lsr.l	#2,d1
	jsr	_LVOUnLoadSeg(a6)
	move.l	thistask(a5),a0
	tst.b	CLIflag(a5)	How to UnLoad the Segment
	beq.s	.A
	move.l	pr_SegList(a0),a0
	add.l	a0,a0
	add.l	a0,a0
	move.l	d7,12(a0)	Store Segment in SegPointer (WB/RUN)
	move.l	wb_msg(a5),d0
	beq.s	crfail
	move.l	d0,a0
	move.l	d7,sm_Segment(a0)	and in Seg-Descriptor	(WB)
	bra.s	crfail
.A	move.l	pr_CLI(a0),a0
	add.l	a0,a0
	add.l	a0,a0
	move.l	d7,cli_Module(a0)	Store Segment in Module	(CLI)
crfail	move.l	dosbase(a5),a1
	move.l	4.w,a6
	jsr	_LVOCloseLibrary(a6)
dosfail	move.l	intuibase(a5),a1
	jsr	_LVOCloseLibrary(a6)
intfail	move.l	wb_msg(a5),d2
	move.l	a5,a1
	move.l	#sizeofblk,d0
	jsr	_LVOFreeMem(a6)
	tst.l	d2
	beq.s	.A
	jsr	_LVOForbid(a6)	(what for ?)
	move.l	d2,a1		WB-Message
	jmp	_LVOReplyMsg(a6)	never returns !
.A	moveq	#0,d0
	rts
blkfail	moveq	#RETURN_ERROR,d0
	rts
	
initialise_default_paths
	lea	defpath1(pc),a0
	lea	patharea(a5),a1
.A	move.b	(a0)+,(a1)+
	bne.s	.A
	tst.b	(a0)
	bne.s	.A
	clr.b	(a1)		MAKE SURE 2 ZERO BYTES AT END
	rts

	
* PRINT DECIMAL print D0 as decimal
print10	movem.l	d0/a0-a1,-(sp)
	move.l	d0,-(sp)
	move.l	sp,a1
	lea	format(pc),a0
	bsr	new_print
	lea	4(sp),sp
	movem.l	(sp)+,d0/a0-a1
	rts

* PRINT HEXADECIMAL address in D0
printADR movem.l	d0/a0-a1,-(sp)
	move.l	d0,-(sp)
	move.l	sp,a1
	lea	formatADR(pc),a0
	bsr	new_print
	lea	4(sp),sp
	movem.l	(sp)+,d0/a0-a1
	rts

	
*PRINT STRING at a1	;saves some of the important low registers
pr_space lea	space(pc),a1
	bra.s	pr_string
pr_tab	lea tab(pc),a1
	bra.s pr_string
pr_prompt lea prompt_string(a5),a1
	bra.s pr_string	
pr_lf	lea lf(pc),a1
pr_string movem.l	d0-d3/a0-a3,-(sp)
	move.l	a1,d2
	moveq	#-1,d3
.A	addq.l	#1,d3
	tst.b	(a1)+
	bne.s	.A
	move.l	outhandle(a5),d1
	beq.s	.B
	jsr	_LVOWrite(a6)
.B	movem.l	(sp)+,d0-d3/a0-a3
	rts

*CHECK WHETHER A SCRIPT NAME WAS TYPED ON ENTRY TO ZSHELL
execscr	move.l	EntryA0(a5),a0
	tst.l	EntryA0(a5)
	beq.s	.C
	cmpi.b	#10,(a0)
	bne.s	execscr2
.C	moveq	#-1,d1		handle DEFAULT SCRIPT FILE s:zstart
	bsr	changeWindowPtr	disable volume requesters
	lea	defscript(pc),a2
	move.l	a2,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	tst.l	d0
	beq.s	.B
.A	move.l	d0,d1
	jsr	_LVOUnLock(a6)
	move.l	a2,a0
	moveq	#0,d1
	bsr	changeWindowPtr
	bra	xz2
.B	moveq	#0,d1
	bsr	changeWindowPtr
	rts
execscr2	move.l a0,a1
.A	cmpi.b #10,(a1)+
	bne.s	.A
	clr.b	-1(a1)	;A0 pts to CLI residue.
	bra	xz2	;NB this is OK, xz2 will pop the return addr 
			;and jump to chorus


*********************************
*	MAIN BIT		*
*********************************
shell	move.l	sp,errorstack(a5)
	move.l	thistask(a5),a0
	move.l	pr_WindowPtr(a0),window_old(a5)
	bsr	CreateCLI
	bne	cloga			exit on error
	bsr	raw_on
;	clr.l	first_set_defn(a5)	V2.0 all CLR removed
;	clr.b	stat_mode_flag(a5)		V1.09
;	clr.b	if_flag(a5)		No IF
;	clr.l	please_close_me(a5)
;	clr.b	goto_flag(a5)
;	clr.b	scflag(a5)
;	clr.l	then(a5)
;	clr.l	now(a5)
;	clr.l	nost(a5)
;	clr.b	nonstdin(a5)
;	clr.b	nonstdout(a5)
;	clr.b	mult_comm_flag(a5)
	move.w	#19,line_count(a5)
	jsr	_LVOOutput(a6)	SAVE THE CONSOLE HANDLERS
	move.l	d0,outhandle(a5)
	move.l	d0,stdout(a5)	V1.13
	jsr	_LVOInput(a6)
	move.l	d0,inhandle(a5)
	move.l	d0,stdin(a5)
	move.l	thistask(a5),a0
	move.l	pr_CurrentDir(a0),d1
	jsr	_LVODupLock(a6)
	move.l	d0,cdback(a5)
	cmp.b	#1,WBflag(a5)
	beq.s	notini		run/newcli
	move.w	#16,failat_level(a5)
	move.b	#$a,past(a5)
	bsr	initialise_default_paths
	lea	prompt_args_tx(pc),a0	init prompt
	lea	prompt_args(a5),a1
.A	move.b	(a0)+,(a1)+
	bne.s	.A
	moveq	#ctrl_inite-ctrl_init-1,d0
	lea	ctrl_init(pc),a0
	lea	ctrl_codes(a5),a1
.B	move.b	(a0)+,(a1)+		init ctrl-codes
	dbra	d0,.B
notini	bsr	eval_CD
	bsr	execscr	
chorus	bsr	close_redirection	HERE BEGINS THE MAIN LOOP
	bsr	raw_on		MAKE SURE RAW MODE IS ON
	bsr	compose_prompt
	bsr	get_line
	clr.b	ctrl_c_flag(a5)
	move.l	4.w,a6
	moveq	#0,d0		clear signals c&d
	moveq	#0,d1
	bset	#SIGBREAKB_CTRL_C,d1
	bset	#SIGBREAKB_CTRL_D,d1
	jsr	_LVOSetSignal(a6)
	move.l	dosbase(a5),a6
	clr.b	forcediskflag(a5)
	move.l	parm1(a5),a0
	move.b	(a0),d0
	cmp.b	ctrl_codes+13(a5),d0
	bne.s	.A
	addq.l	#1,a0
	tst.b	(a0)
	bne.s	.B
	move.l	cdback(a5),d1	dir back
	jsr	_LVODupLock(a6)
	move.l	d0,d1
	bsr	chdir
	bra.s	chorus
.B	move.l	a0,parm1(a5)
	addq.b	#1,forcediskflag(a5)
	bra	notfound	force disk-command
.A	cmp.b	#"#",(a0)	#-sign for ;#comment
	beq	chorus
	move.l	a0,d7		check for ? (help sign)
	tst.b	1(a0)
	bne.s	.C
	cmp.b	#"?",(a0)
	bne.s	.C
	bsr	help_man	? as command
	bra	chorus
.C	lea	comtext(pc),a1
	lea	comoffs(pc),a2
mtch	bsr	match
	tst.l	d0
	beq.s	notfound
	move.l	parm1(a5),d7		check for ? (help sign)
	move.l	parm2(a5),a1
	tst.b	1(a1)
	bne.s	.D
	cmp.b	#"?",(a1)
	bne.s	.D
	bsr	rawh_off
	bsr	help_man	? as arg
	bra	chorus
.D	move.l	sp,errorstack(a5)	important in scripts ?
	lea	start(pc),a0
intern	jsr	0(a0,d0.w)	call internal command
	tst.b	ctrl_c_flag(a5)
	bne.s	com_break
chkfail	move.l	d0,last_failcode(a5)
	cmp.w	failat_level(a5),d0	ALL COMMANDS MUST RETURN D0=0 unless failure
	blo	chorus
com_fail move.l	d0,-(sp)
	move.l	sp,a1
	lea	failertx(pc),a0
	bsr	new_print
	move.l	(sp)+,d0
com_break clr.b	mult_comm_flag(a5)
	tst.b	scflag(a5)
	beq	chorus
	bsr	kill_script
	bra	chorus
notfound bsr	archie3		TRY DISK
	move.l	d0,-(sp)
	move.l	thistask(a5),a0
	move.l	cd_volnode(a5),d0
	move.l	pr_CurrentDir(a0),a1
	add.l	a1,a1
	add.l	a1,a1
	cmp.l	fl_Volume(a1),d0	check volume node
	bne.s	.A
	move.l	cd_block(a5),d0
	cmp.l	fl_Key(a1),d0	check disk block number
	beq.s	.B
.A	bsr	eval_CD		If command changes cd then change prompt.
.B	move.l	(sp)+,d0
	bra.s	chkfail

	
*Match the string pointed to by A0 to one in a table pted to by a1
*The number of the matched string is linked to an offset table pted to by
*A2.  return with 
*D0 holding offset from 'start' so a jsr 0(a0,d0.w) can be done
*Entry	A1 pts to Command text table  A2 pts to command offset table

match	moveq	#0,d1	;command count
	move.l	a0,a3	;save command
mat2	move.b	(a0)+,d0
	cmp.b	ctrl_codes+13(a5),d0	;check "."
	bne.s	.A
	tst.b	(a0)
	beq.s	foundit	;shortcut
.A	cmp.b	(a1),d0	;V1.01
	beq.s	mat3
	add.b	#$20,d0	;'A' -> 'a'	handle commands typed in UCase
	cmp.b	(a1),d0
	bne.s	nextcom	;if any character wrong then check next
mat3	addq.l	#1,a1
	tst.b	-1(a0)	;check whether 0 was last compared
	beq.s	foundit	;if it was then success
	bra.s	mat2
nextcom	tst.b	(a1)+
	bne.s	nextcom
	addq.l	#2,d1	;each offset is a word
	move.l	a3,a0
	tst.b	(a1)	;put 0,0 at end of com table
	bne.s	mat2
	moveq	#0,d0	;D0 = 0 if command not found
	rts
foundit	move.w	0(a2,d1.l),d0	;get offset
	rts


* Subroutine for complet, limiting chars:":","/","""," " *
cjk1	cmp.b	#":",-1(a1)
	beq.s	cjke
	cmp.b	#"/",-1(a1)
	beq.s	cjke
cjk2	cmp.b	#$22,-1(a1)
	beq.s	cjke
	cmp.b	#" ",-1(a1)
cjke	rts

* Complete Filename in Shelline *
* a2 points to part of filename, d6 length of part *
* d4: linmax , d5:linhere *
complet	move.l	d5,d6
	clr.b	temp2buf(a5)
	lea	shelline(a5),a1
	move.l	a1,a0
	add.l	d5,a1
	bsr	cjk1
	beq.s	.C
.A	subq.l	#1,a1		look for begin of filename
	cmp.l	a1,a0
	beq.s	.B	
	bsr	cjk1
	bne.s	.A
.B	move.l	a1,a2		filename-pos. in a2
	sub.l	a0,a1
	sub.l	a1,d6		length in d6
	move.b	(a2),d3		save char
	clr.b	(a2)		null-end pathname
	move.l	a2,a1
	bra.s	.F
.D	subq.l	#1,a1		look for begin of path
.F	cmp.l	a1,a0
	beq.s	.E
	bsr	cjk2
	bne.s	.D
.E	move.l	a1,d1
	moveq	#-2,d2
	jsr	_LVOLock(a6)	lock path
	move.b	d3,(a2)		replace null-char by old one
	move.l	d0,d7		save lock
	beq.s	.C
	move.l	d0,d1
	lea	blockbase(a5),a0
	move.l	a0,d2
	jsr	_LVOExamine(a6)		get dir
	tst.l	d0
	beq.s	.G
	tst.l	fib_DirEntryType(a5)
	bpl.s	wdhcpl		if plus,is directory
.G	move.l	d7,d1
	jsr	_LVOUnLock(a6)
.C	rts			an error occured
wdhcpl	bsr	fibexnx		repeat to search whole dir
	tst.l	d0		next filename or dirname
	beq.s	endcpl
	lea	fib_FileName(a5),a0
	move.l	a0,a3
	lea	ignoreit(a5),a1
	tst.b	(a1)
	beq.s	.F
	bsr	wildmatch		;wildcheck
	tst.b	d0
	beq.s	wdhcpl
.F	move.l	a3,a0
	move.l	a2,a1
	move.l	d6,d2
	subq.l	#1,d2
.A	move.b	(a0)+,d0
	move.b	(a1)+,d1
	bsr	compD1D0nocase		does it fit ?
	bne.s	wdhcpl
	dbra	d2,.A
	lea	temp2buf(a5),a0
	tst.b	(a0)
	bne.s	.B
.C	move.b	(a3)+,(a0)+	first time: copy filename
	bne.s	.C
	move.b	#" ",-1(a0)	add a space at the end (files)
	clr.b	(a0)
	tst.l	fib_DirEntryType(a5)
	bmi.s	.E		if plus,is directory
	move.b	#"/",-1(a0)	add a / at the end (dirs)
.E	bra.s	wdhcpl
.B	move.b	(a0)+,d0
	move.b	(a3)+,d1
	bsr	compD1D0nocase	next time: find longest common part
	bne.s	.D
	tst.b	-1(a0)
	beq.s	.D
	tst.b	-1(a3)
	bne.s	.B
.D	clr.b	-1(a0)
	bra.s	wdhcpl		repeat with all filenames

endcpl	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	lea	temp2buf(a5),a0
	moveq	#-1,d3
.G	addq.l	#1,d3
	tst.b	(a0)+
	bne.s	.G
	subq.l	#1,a0
	sub.l	d6,d3		D3=length
	bmi.s	.B
	cmp.w	#SHELLINE_SIZE-2,d4	make sure line is not too long
	bhi.s	.B
	lea	shelline(a5),a1	ethel
	lea	1(a1,d4.w),a3	A3=linmax
	move.l	a3,a2
	add.l	d3,a2		A2=linmax+length
	lea	0(a1,d5.w),a1	linhere
.A	move.b	-(a3),-(a2)	insert chars into shelline
	cmp.l	a3,a1
	bne.s	.A
	move.l	d3,d0
	add.l	d6,d0	
	bra.s	.C
.D	move.b	-(a0),-(a2)	copy found filename
.C	dbra	d0,.D
	add.l	d3,d5
	add.l	d3,d4
	lea	shelline(a5),a2
	bsr	gimme3		print shelline
	move.l	d4,d0
	sub.l	d5,d0
	lea	tempbuf(a5),a1
	move.l	a1,a0
	bra.s	.E
.F	move.w	#$9b<<8+"D",(a0)+	left cursor
.E	dbra	d0,.F		
	clr.b	(a0)
	bsr	pr_string	restore cursorpos
.B	rts


get_one_char
read_kbd
;	moveq	#0,d0	for debugging
;	moveq	#0,d1
;	move.l	4.w,a6
;	bset	#SIGBREAKB_CTRL_F,d1
;	jsr	_LVOSetSignal(a6)
;	btst	#SIGBREAKB_CTRL_F,d0
;	bne	cloga
	move.l	dosbase(a5),a6
	lea	tempbytes(a5),a0
	move.l	a0,d2
	move.l	inhandle(a5),d1
	beq	cloga
	moveq	#1,d3
	jsr	_LVORead(a6)
	move.b	tempbytes(a5),d6
	rts

* A1 pts to past, d0=nost
gimme	lea	shelline(a5),a2
	move.l	d0,nost(a5)
	cmp.l	now(a5),d0
	bne.s	gimme2
	moveq	#0,d4		clear linmax
	moveq	#0,d5		clear linhere
	lea	delete_line(pc),a1
	bsr	pr_string
	bsr	pr_prompt
	rts
gimme2	moveq	#0,d5		linhere = 0

gimme5	addq.l	#1,d0		copy to shelline
	and.l	#HISTORY_SIZE-1,d0
	cmp.b	#$a,0(a1,d0.l)
	beq.s	.A
	move.b	0(a1,d0.l),0(a2,d5.l)
	addq.l	#1,d5
	bra.s	gimme5
.A	move.l	d5,d4		linmax=linhere
gimme3	lea	delete_line(pc),a1
	bsr	pr_string
	bsr	pr_prompt
	clr.b	0(a2,d4.l)	clear last
	move.l	a2,a1
	bra	pr_string


* READ TEXT LINE from keyboard or script into buffer pointed to by a0,
* and clear last byte. NOTE A0 is essentially ignored, and shelline is the
* assumed address. Return with a0 same, and d0=length of text read
type_in	tst.b	scflag(a5)		;check whether we're doing a script
	bne	scr_in
type_in2	move.l a0,-(sp)
type_in3	moveq	#0,d5		D5=linhere
	moveq	#0,d4		D4=linmax
next_ch	bsr	get_one_char
	cmp.b	#$9b,d6
	bne	not_csi
	clr.l	gather_ptr(a5)
fetch_csi	bsr	get_one_char
	lea	gather(a5),a0
	move.l	gather_ptr(a5),d0
	move.b	d6,0(a0,d0.l)		;save byte from CSI sequence.
	addq.l	#1,gather_ptr(a5)
	cmp.b	#'@',d6
	blo.s	fetch_csi		;keep gathering if char < @
	cmp.b	#'~',d6
	bhi.s	fetch_csi		;keep gathering if char > ~

	cmp.b	#"|",d6		CHECK CLOSE GADGET
	bne.s	not_cloga
cloga	move.l	dosbase(a5),a6	totally-exit-routine
	move.l	errorstack(a5),sp	;kill return address on stack
	tst.l	outhandle(a5)
	beq	.B
	bsr	raw_off
.B	moveq	#-1,d7
	tst.b	scflag(a5)
	beq.s	.A
	bsr	kill_script
.A	rts

not_cloga
	cmp.b	#'D',d6		CHECK LEFT ARROW	<CSI>D
	bne.s	not_left
	tst.l	d5
	beq.s	not_left
	subq.l	#1,d5
	lea	left_cursor(pc),a1
	bsr	pr_string
	bra	next_ch
	
not_left	cmp.b	#'Z',d6	CHECK TAB & SHIFT	<CSI> Z
	bne.s	not_tab_left
tab_left tst.l	d5
	beq.s	next_ch
	subq.l	#1,d5
	lea	left_cursor(pc),a1
	bsr	pr_string
	lea	shelline-1(a5),a0
	bsr	tab_check
	bne.s	tab_left
	bra	next_ch

tab_check cmp.b	#' ',(a0,d5.w) words are separated by / . : or space
	beq.s	.A
	cmp.b	#':',(a0,d5.w)
	beq.s	.A
	cmp.b	#'.',(a0,d5.w)
	beq.s	.A
	cmp.b	#'/',(a0,d5.w)
.A	rts
	
not_tab_left	cmp.b	#'A',d6
	bne.s	not_sh_left
	cmp.b	#' ',gather(a5)	CHECK SHIFT LEFT ARROW	<CSI> A
	bne.s	not_sh_left
	move.l	d5,d0
	lea	tempbuf(a5),a1
	move.l	a1,a0
	bra.s	.A
.B	move.w	#$9b<<8+"D",(a0)+	left cursor
.A	dbra	d0,.B
	clr.b	(a0)
	bsr	pr_string
	moveq	#0,d5
	bra	next_ch

not_sh_left
	cmp.b	#'C',d6		CHECK RIGHT ARROW	<CSI>C
	bne.s	not_right
	cmp.l	d4,d5
	bhs.s	not_right
	addq.l	#1,d5
	lea	right_cursor(pc),a1
	bsr	pr_string
	bra	next_ch

not_right	cmp.b	#'@',d6
	bne.s	not_sh_right
	cmp.b	#' ',gather(a5)	CHECK SHIFT RIGHT ARROW	<CSI> @
	bne.s	not_sh_right
	move.l	d4,d0
	sub.l	d5,d0
	lea	tempbuf(a5),a1
	move.l	a1,a0
	bra.s	.A
.B	move.w	#$9b<<8+"C",(a0)+	right cursor
.A	dbra	d0,.B
	clr.b	(a0)
	bsr	pr_string
	move.l	d4,d5
	bra	next_ch

not_sh_right
	cmp.b	#'A',d6		CHECK UP ARROW
	bne.s	not_up
	lea	past(a5),a1
	move.l	nost(a5),d0
	cmp.l	then(a5),d0
	beq.s	.B
.A	subq.l	#1,d0
	and.l	#HISTORY_SIZE-1,d0		WRAP AROUND
	cmp.b	#$a,0(a1,d0.l)
	bne.s	.A
.B	bsr	gimme
	bra	next_ch

not_up	cmp.b	#'B',d6		CHECK DOWN ARROW
	bne.s	not_down
up_bit	lea	past(a5),a1	CALLED BY SHIFT DOWN BIT
	move.l	nost(a5),d0
	cmp.l	now(a5),d0
	beq.s	.B
.A	addq.l	#1,d0
	and.l	#HISTORY_SIZE-1,d0
	cmp.b	#$a,0(a1,d0.l)
	bne.s	.A
.B	bsr	gimme
	bra	next_ch

not_down	cmp.b	#'T',d6		CHECK SHIFT UP
	bne	not_sh_up
	lea	past(a5),a1
	tst.l	d5
	bne.s	search_his
	move.l	then(a5),nost(a5)	nost = then (the top)
	move.l	nost(a5),d0
	bsr	gimme
	bra	next_ch
search_his			;search shelline in history	V2.0
	move.l	nost(a5),d0
.C	cmp.l	then(a5),d0
	bne.s	.A
	move.l	nost(a5),d0
	bra.s	end_seh
.A	subq.l	#1,d0
	and.l	#HISTORY_SIZE-1,d0
	cmp.b	#$a,0(a1,d0.l)
	bne.s	.A

	lea	shelline(a5),a0
	move.l	d5,d1
	subq.l	#1,d1
	move.l	d0,d2
.D	addq.l	#1,d2
	and.l	#HISTORY_SIZE-1,d2
	movem.l	d0/d1,-(sp)
	move.b	0(a1,d2.l),d0
	move.b	(a0),d1
	bsr	compD1D0nocase
	movem.l	(sp)+,d0/d1
	bne.s	.C
	addq.l	#1,a0
	dbra	d1,.D
end_seh	move.l	d5,d1		save d5
	bsr	gimme
	move.l	d5,d0
	sub.l	d1,d0
	bmi.s	.C
	lea	tempbuf(a5),a1
	move.l	a1,a0
	bra.s	.A
.B	move.w	#$9b<<8+"D",(a0)+	left cursor
.A	dbra	d0,.B
	clr.b	(a0)
	bsr	pr_string
	move.l	d1,d5
.C	bra	next_ch


not_sh_up	cmp.b	#'S',d6		CHECK SHIFT DOWN
	bne.s	not_sh_down
	move.l	now(a5),nost(a5)	nost = now (the bottom)
	bra	up_bit
	
not_sh_down			;NOTE V1.05
	cmp.b	#'~',d6		CHECK FUNCTION KEYS AND HELP KEY
	bne	next_ch
	cmp.b	#'?',gather(a5)
	bne.s	process_the_func_key
	lea	help_ret(pc),a1
	move.l	d0,-(sp)	need crap on stack to call print_def
	bsr	print_def	will rip last 2 addrs off stack
* never gets to this line
process_the_func_key
	bsr	translate_func_key
	bra	next_ch
		
* Was not a CSI code
not_csi	cmp.b	ctrl_codes+6(a5),d6		CHECK ESCAPE (ctrl+[)
	beq	cloga		exit immediately

	cmp.b	ctrl_codes+7(a5),d6	CHECK TAB (ctrl+I)
	bne.s	not_tab_right
.A	cmp.l	d4,d5
	bhs	next_ch
	addq.l	#1,d5
	lea	right_cursor(pc),a1
	bsr	pr_string
	lea	shelline-1(a5),a0
	bsr	tab_check
	bne.s	.A
	bra	next_ch
	
not_tab_right
	cmp.b	ctrl_codes+8(a5),d6		CHECK CTRL Y
	beq	tab_left		same as shift&tab

	cmp.b	ctrl_codes+9(a5),d6		CHECK BACKSPACE (ctrl+H)
	bne.s	not_bs
	tst.l	d5
	beq.s	not_bs
	subq.l	#1,d5
	lea	backspace_it(pc),a1
	bsr	pr_string
	bsr	del_str
	bra	next_ch

del_str	lea	shelline(a5),a4
	lea	SHELLINE_SIZE+shelline(a5),a1	NOTE SHELLINE SIZE!!!
	lea	0(a4,d5.w),a0
	lea	1(a0),a2
.A	move.b	(a2)+,(a0)+
	cmp.l	a2,a1
	bne.s	.A
	subq.l	#1,d4
	rts

not_bs	cmp.b	#$7f,d6				CHECK DELETE
	bne.s	not_del
	cmp.l	d4,d5
	bhs.s	not_del
	lea	delete_it(pc),a1
	bsr	pr_string
	bsr	del_str
	bra	next_ch
	
not_del	cmp.b	ctrl_codes+5(a5),d6		CHECK CTRL X
	bne.s	not_ctrlx
	moveq	#0,d5		delete shelline
	moveq	#0,d4
	lea	delete_line2(pc),a1
	bsr	pr_string
	bsr	pr_prompt
	bra	next_ch
	
not_ctrlx
	cmp.b	ctrl_codes+3(a5),d6		CHECK CTRL E
	bne.s	not_ctrle
.A	cmp.l	d4,d5		delete to end of line
	bhs	next_ch
	lea	delete_it(pc),a1
	bsr	pr_string
	bsr	del_str
	bra.s	.A
	
not_ctrle
	cmp.b	ctrl_codes+2(a5),d6		CHECK CTRL S
	bne.s	not_ctrls
.A	tst.l	d5		delete to start of line
	beq	next_ch
	subq.l	#1,d5
	lea	backspace_it(pc),a1
	bsr	pr_string
	bsr	del_str
	bra.s	.A
	
not_ctrls
	cmp.b	ctrl_codes+1(a5),d6		CHECK CTRL W
	bne.s	not_ctrlw
.A	tst.l	d5		delete last word
	beq	next_ch
	subq.l	#1,d5
	lea	backspace_it(pc),a1
	bsr	pr_string
	bsr	del_str
	lea	shelline-1(a5),a0
	bsr	tab_check
	bne.s	.A
	bra	next_ch

not_ctrlw
	cmp.b	ctrl_codes+0(a5),d6		CHECK CTRL Q
	bne.s	not_ctrlq
.A	cmp.l	d4,d5		delete next word
	bhs	next_ch
	lea	delete_it(pc),a1
	bsr	pr_string
	bsr	del_str
	lea	shelline+0(a5),a0
	bsr	tab_check
	bne.s	.A
	bra	next_ch

not_ctrlq
	cmp.b	ctrl_codes+4(a5),d6		CHECK CTRL A
	bne.s	not_ctrla
	tst.l	d5
	beq	next_ch
	movem.l	d3/d6/d7/a3,-(sp)
	bsr	complet		complete filename
	movem.l	(sp)+,d3/d6/d7/a3
	bra	next_ch

not_ctrla
	cmp.b	ctrl_codes+10(a5),d6		CHECK CTRL J
	bne.s	not_ctrlj
	move.b	#"^",d6		insert ^J
	bsr	ins_char
	move.b	#"J",d6
	bsr	ins_char
	bra	next_ch

not_ctrlj
	cmp.b	ctrl_codes+12(a5),d6		CHECK CTRL L
	bne.s	not_ctrll
	lea	clrtx(pc),a1
	bsr	pr_string	clear window
	move.l	errorstack(a5),sp
	bra	chorus

not_ctrll
	cmp.b	ctrl_codes+11(a5),d6		CHECK CTRL M
	beq.s	do_cr
	cmp.b	#$d,d6		CHECK CR
	bne	no_cr
do_cr	lea	return_it(pc),a1
	bsr	pr_string
	lea	shelline(a5),a4
	move.b	#10,0(a4,d4.w)	HACK JOB	(MUST END IN LF 0)
	clr.b	1(a4,d4.w)	FOR ALIAS STUFF
	tst.l	d4		CHECK IF NOTHING TYPED
	bne.s	history_it
	bsr	pr_prompt		IF JUST HIT RETURN, THEN START AGAIN
	bra	type_in3
history_it
	lea	past(a5),a1	CHECK IF LAST ENTRY IS SAME AS CURRENT
	move.l	now(a5),d0
	cmp.l	then(a5),d0
	beq.s	.B
	move.l	d0,nost(a5)
.A	subq.l	#1,d0		FIND LAST
	and.l	#HISTORY_SIZE-1,d0	WRAP AROUND
	cmp.b	#$a,0(a1,d0.l)
	bne.s	.A
	lea	(a4),a0
	bra.s	.C
.D	cmp.b	#$a,d1		COMPARE LAST TO SHELLINE
	beq	finland
.C	addq.l	#1,d0
	and.l	#HISTORY_SIZE-1,d0
	move.b	(a0)+,d1
	cmp.b	0(a1,d0.l),d1
	beq.s	.D

.B	move.l	a4,a3	lin	COPY LINE TO HISTORY  BUFFER
	move.l	now(a5),d3	pts to the last LF

.E	addq.l	#1,d3
	and.l	#HISTORY_SIZE-1,d3		WRAP AROUND
	move.b	(a3)+,d0
	move.b	d0,0(a1,d3.l)
	cmp.b	#10,d0
	bne.s	.E
dumped_hist
	move.l	d3,nost(a5)	nost = now
	move.l	d3,now(a5)
	move.l	then(a5),d1
	cmp.b	#$a,0(a1,d1.l)
	bne.s	wxv1	BRANCH IF WRAPPED AROUND
	cmp.l	d3,d1
	bne.s	finland	BRANCH IF THEN = (10) & THEN <> NOW
wxv1	
*	move.l	d3,then(a5)	then=now
wxv3	addq.l	#1,d3	SEARCH FOR NEXT LF (NEW TOP OF HISTORY)
	and.l	#HISTORY_SIZE-1,d3		WRAP AROUND
	move.b	0(a1,d3.l),d0
	cmp.b	#$a,d0
	bne.s	wxv3		***
wxv2	move.l	d3,then(a5) SET NEW THEN (TOP OF HISTORY)

******* 
finland
	move.l (sp)+,a0
	rts

no_cr	cmp.b	#' ',d6
	blo.w	dunno_it
	cmp.b	#'~',d6
	bls.s	nochkum
chkum	moveq	#umlautend-umlaut-1,d0	V2.0
	lea	umlaut(pc),a0
.A	cmp.b	(a0)+,d6
	beq.s	nochkum
	dbra	d0,.A
	bra	dunno_it
nochkum	bsr	ins_char
dunno_it bra	next_ch

* insert a char in the shelline
ins_char cmp.w	#SHELLINE_SIZE-2,d4	make sure line is not too long
	bhi.w	dunno_it
	lea	tempbuf(a5),a1
	move.w	#$9b<<8+"@",(a1)
	clr.b	3(a1)
	move.b	d6,2(a1)	shove printable char after insert seq
	bsr	pr_string		insert space for char
	lea	shelline(a5),a1	ethel
	lea	1(a1,d4.w),a0	linmax
	lea	1(a0),a2		A2=linmax+1
	lea	0(a1,d5.w),a1	linhere
tc_1	move.b	-(a0),-(a2)	insert char into shelline
	cmp.l	a0,a1
	bne.s	tc_1
plop_ch	lea	shelline(a5),a4
	move.b	d6,0(a4,d5.w)
	addq.l	#1,d5
	addq.l	#1,d4
	rts

* TRANSLATE FUNC CODE TO F1,F2 ETC AND SET UP POINTERS
translate_func_key
	lea	gather(a5),a0
	move.l	gather_ptr(a5),d0
	cmp.b	#3,d0		CHECK IF TWO CODES EG '12'
	beq	process_shift_func
unshifted_func_key
	cmp.b	#2,d0
	bne	translate_func_fail
	move.b	(A0),d0
	moveq	#'f',d1
act_sh	bsr	convert_to_set_name
	bsr	search_sets	returns D0 pointer to set
	bsr	print_func_defn
	rts
process_shift_func
	move.b	1(A0),d0
	moveq	#'F',d1
	bra.s	act_sh
translate_func_fail
	rts

*d0=set ptr
print_func_defn
	tst.l	d0
	beq	do_not_print_func
	move.l	d0,a1
	lea	set_defn(a1),a1
print_def	lea	shelline(a5),a2
	bra.s	.B
.A	addq.l	#1,d5		copy defn to shelline
.B	move.b	(a1)+,0(a2,d5.l)
	bne.s	.A
	cmp.b	#'M',-1(a2,d5.l)	check for auto return ^M
	bne.s	.C
	cmp.b	#'^',-2(a2,d5.l)
	bne.s	.C
	subq.l	#2,d5
	move.l	d5,d4
	bsr	gimme3		print it
	movem.l	(sp)+,d0-d1	get rid of last 2 return addresses
	bra	do_cr		do a carriage return

.C	move.l	d5,d4		linmax=linhere
	bra	gimme3		show prompt,new line
do_not_print_func
	rts
	
convert_to_set_name
	lea	set_search_string(a5),a1
	move.b	d1,(a1)+
	addq.b	#1,d0
	move.b	d0,(a1)+
	cmp.b	#':',d0
	bne	not_func10
	move.b	#'1',-1(a1)
	move.b	#'0',(a1)+
not_func10
	clr.b	(a1)
	rts

search_sets
* uses set_search_string, EXIT: D0 ptr to the associated set. D1 pts to prior set
* RETURN D0=0 IF NOT FOUND.
	movem.l	d2-d4/a1-a2,-(sp)
	lea	set_search_string(a5),a1
	move.l	a1,d2
	lea	first_set_defn(a5),a2
	move.l	a2,d4		NOTE PRIOR SET 
	move.l	(a2),d3
search_next_set
	beq	.B
	move.l	d3,a2
	lea	set_name(a2),a2	A2=current set name
	move.l	d2,a1		A1=name to match
	bra.s	.C
.A	tst.b	d0
	beq.s	.B
.C	move.b	(a1)+,d0
	move.b	(a2)+,d1
	bsr	compD1D0nocase
	beq.s	.A

	move.l	d3,a2
	move.l	d3,d4
	move.l	(a2),d3
	bra	search_next_set
.B	move.l	d3,d0
	move.l	d4,d1
	
	movem.l	(sp)+,d2-d4/a1-a2
	rts


* DO SCRIPT FILE STUFF   ENTRY A0 -> input line
scr_in	movem.l	a0-a1/a6,-(sp)
	clr.b	ctrl_c_flag(a5)
	move.l	4.w,a6
	moveq	#0,d0
	moveq	#0,d1
	bset	#SIGBREAKB_CTRL_D,d1
	jsr	_LVOSetSignal(a6)
	movem.l	(sp)+,a0-a1/a6
	btst	#SIGBREAKB_CTRL_D,d0	;checks if CTRL_D pressed
	beq.s	.B
	move.l	a0,-(sp)
	lea	breaktx(pc),a0
	bsr	new_print
	move.b	#1,ctrl_c_flag(a5)
	move.l	(sp)+,a0
	bra.s	terminate_script
.B	move.l	scsize(a5),d0	;read a line from the script file
	add.l	scaddr(a5),d0
	cmp.l	scptr(a5),d0
	bgt.s	scr_in2
terminate_script
	bsr	kill_script
	bsr	pr_prompt
	bra	type_in2
scr_in2	move.l	a0,a2
	moveq	#0,d0
	move.l	scptr(a5),a1
.A	move.b	(a1)+,(a2)+
	addq.l	#1,d0
	cmp.b	#10,(a1)
	bne.s	.A
	move.b	(a1)+,(a2)+	LF
	clr.b	(a2)		0
	move.l	a1,scptr(a5)
	rts

kill_script
	move.l	a0,-(sp)
	clr.b	scflag(a5)	clean up if no more lines left
	clr.b	if_flag(a5)	Make sure if structure ends
	clr.b	goto_flag(a5)	Make sure goto is terminated
	move.l	scaddr(a5),a1
	move.l	scsize(a5),d0
	bsr	givemem
	move.l	(sp)+,a0
	rts

** SAME AS compare_strings EXCEPT
** ALLOWS FOR A1 ENDING IN LF
lf_compare_strings
	movem.l	d0-d1/a0-a1,-(sp)
	bra.s	.A
.B	tst.b	d0
	beq.s	.C	RETURN EQ
.A	move.b	(a0)+,d0
	move.b	(a1)+,d1
	bsr	compD1D0nocase
	beq.s	.B	return NE
	tst.b	d0
	bne.s	.C
	cmp.b	#10,d1
.C	movem.l	(sp)+,d0-d1/a0-a1
	rts

	
** CASE INDEPENDENT STRING COMPARE. COMPARES (A0) TO (A1)
** RETURN EQ IF SAME
compare_strings
	movem.l	d0-d1/a0-a1,-(sp)
	bra.s	.A
.B	tst.b	d0
	beq.s	.C	RETURN EQ
.A	move.b	(a0)+,d0
	move.b	(a1)+,d1
	bsr	compD1D0nocase
	beq.s	.B	return NE
.C	movem.l	(sp)+,d0-d1/a0-a1
	rts

	
* COPY STRING :copys null ending string from A0 to A1, Return with D0=length+1
cp_string	movem.l a0-a1,-(sp)
	moveq #0,d0
cp_str1	addq.l #1,d0
	move.b (a0)+,(a1)+
	bne.s cp_str1
	movem.l (sp)+,a0-a1
	rts

*Get line of text and seperate into up to 6 parameters	
get_line	addq.l	#1,count_line(a5)
	bsr clr_parms
	lea	shelline(a5),a0
	tst.b	mult_comm_flag(a5) SKIP PROMPT IF SCRIPT OR MULT COMMANDS
	bne.s	.A
	tst.b	scflag(a5)
	bne.s	.B
	bsr	pr_prompt
.B	bsr	type_in	NOTE HISTORY STUFF ASSUMES SHELLINE HOLDS THE LINE
	cmp.b	#';',(a0)		;is 1st character a ';'
	beq.s	.C
	cmp.b	#'*',(a0)
	beq.s	.C
	cmp.b	#'#',(a0)
	bne.s	.A
.C	move.l	(sp)+,d0		;kill return address
	bra	chorus		;do next line if comment
.A	bsr	handle_mult_comms	MAYBE ALTER A0
	bsr	handle_command_alias
*	move.l	a0,-(sp)		TEST STUFF
*	move.l	a0,a1
*	bsr	pr_string
*	move.l	(sp)+,a0
	bsr	handle_redirection
gl16	lea	parm1(a5),a2 do 1st parm seperate to establish CLI residue
	bsr	get_parm
	move.l	a0,d7
	tst.l	d2
	beq	gl3			if no parms at all
	tst.b	goto_flag(a5)	CHECK IF IN GOTO SEARCH MODE
	beq.s	test_ifs
	move.l	a0,-(sp)
	lea	label_tx(pc),a0
	bsr	lf_compare_strings
	bne	skipline
	move.l	(sp)+,a0

* Script-IF handling
test_ifs	tst.b	if_flag(a5)	0 if if encountered earlier
	beq.s	no_ifs
	tst.b	if_condition_flag(a5)	0 if condition TRUE
	beq	no_ifs
if_false	move.l	a0,-(sp)		push ptr to next
	lea	else_tx(pc),a0
	bsr	lf_compare_strings
	bne.s	try_endif
	not.b	if_condition_flag(a5)	flip condition flag
skipline	movem.l	(sp)+,d0-d1	get rid of last plus return address
	bra	chorus
try_endif	lea	endif_tx(pc),a0
	bsr	lf_compare_strings
	bne.s	skipline
	clr.b	if_flag(a5)
	bra.s	skipline

no_ifs	move.l	a1,(a2)+	save address of parm1

	lea	CLIbuf(a5),a1
	bra.s	.A
.B	move.b	d0,(a1)+
.A	move.b	(a0)+,d0	copy sudoCLIresidue out
	cmp.b	#10,d0		only look for LF end
	bne.s	.B
	clr.b	(a1)		null end the copy
	move.l	d7,a0
	lea	endofparms(a5),a4	establish end of parms block
gl4	bsr	get_parm		
	tst.l	d2
	beq.s	gl3
	move.l	a1,(a2)+
	cmp.l	a2,a4		get out if more than 10 parms
	bne.s	gl4
	clr.b	(a0)		make sure parm6 ends in 0
gl3	rts

endifz	clr.b	if_flag(a5)
	moveq	#RETURN_OK,d0
	rts
elsez	not.b	if_condition_flag(a5)
	moveq	#RETURN_OK,d0
	rts

*************************
*        SKIP 		*
*************************

skipz	move.l	parm2(a5),d1
	bne	test_gs
skip_err	lea	goto_error_tx(pc),a1
	bsr	pr_string
	moveq	#RETURN_ERROR,d0
	rts
test_gs	tst.b	scflag(a5)	CAN ONLY GOTO FROM WITHIN SCRIPT
	beq	skip_err

	move.l	d1,a0
	lea	dest_label(a5),a1
.B	move.b	(a0)+,(a1)+
	bne.s	.B
	move.l	scaddr(a5),scptr(a5)  RESET TO START OF SCRIPT
	move.b	#$ff,goto_flag(a5)
	clr.b	if_flag(a5)	MAKE SURE IF IS TERMINATED
	moveq	#RETURN_OK,d0
	rts

*************************
*	LABEL		*	 DOES NOTHING IF NOT IN GOTO SEARCH MODE
*************************
labelz	tst.b	goto_flag(a5)
	bne.s	.A
.B	moveq	#RETURN_OK,D0
	RTS
.A	move.l	parm2(a5),d0
	beq.s	.B
	move.l	d0,a0
	lea	dest_label(a5),a1
	bsr	compare_strings
	bne	.B
	clr.b	goto_flag(a5)
	bra.s	.B
	
	
*ENTRY A0=shelline	ONLY HANDLES ALIASES OF FIRST KEYWORD.
handle_command_alias
	movem.l	d0-d2/a1-a4,-(sp)
	cmp.b	#10,(a0)
	beq	hca_nothing_typed
	move.l	a0,a1
	lea	tempbuf(a5),a3
	move.b	#10,(a3)
	clr.b	1(a3)	must be null end string
	lea	set_search_string(a5),a2	COPY PARM AT A0 TO SEARCH STR
.B	move.b	(a1)+,(a2)+
	cmp.b	#10,(a1)
	beq.s	.D		hca_one_parm
	cmp.b	#$20,(a1)
	bne.s	.B
.D	move.b	(a1)+,(a3)+	COPY FROM SPACE ONWARDS to tempbuf
	bne.s	.D	WHOLE LINE ENDS IN NULL.
hca_one_parm
	clr.b	(a2)	null end search string

hca_find_it
	move.l	a0,-(sp)
	bsr	search_sets
	move.l	(sp)+,a0
	tst.l	d0
	beq	hca_nothing_typed
	move.l	d0,a2

	lea	set_defn(a2),a2	A2=set defn
	lea	tempbuf(a5),a3	A3=line after alias
	move.l	a0,a1		A1=shelline ptr
	moveq	#7,d0
.F	clr.l	-(sp)		push down eight times 0=no entry.
	dbra	d0,.F
.E	move.b	(a2)+,d0		handle %1...$1
	beq	not_much_of_an_alias
	cmp.b	#$20,d0		skip spaces
	beq.s	.E
	cmp.b	#'%',d0
	bne.s	no_extra_parms
	move.b	(a2)+,d0
	and.w	#$0007,d0		only allow %0 --> %7
.A	move.b	(a3)+,d1		find where the next param starts
	cmp.b	#10,d1
	beq.s	.C		if no param then pt A3 to lf again
	cmp.b	#$20,d1
	beq.s	.A
.D	lsl.w	#2,d0		x 4
	move.l	a3,0(sp,d0.w)
	subq.l	#1,0(sp,d0.w)	put address of param on stack
.B	move.b	(a3)+,d1		get a3 to pt to next space
	cmp.b	#10,d1
	beq	.C
	cmp.b	#$20,d1
	bne.s	.B
.C	lea	-1(a3),a3		a3 ts to space
	bra.s	.E		do for more params
get_next_character
	move.b	(a2)+,d0
no_extra_parms
	cmp.b	#'$',d0
	bne.s	.A
	move.b	(a2)+,d0		grab number after $
	beq.s	not_much_of_an_alias
	and.w	#$0007,d0
	lsl.w	#2,d0		x 4
	move.l	0(sp,d0.w),d1
	beq.s	get_next_character
	move.l	d1,a4
.B	move.b	(a4)+,(a1)+	copy param N
	cmp.b	#10,(a4)
	beq.s	.C
	cmp.b	#$20,(a4)
	bne.s	.B
.C	bra.s	get_next_character
.A	move.b	d0,(a1)+		copy DEFN -> SHELLINE
	tst.b	d0
	bne.s	get_next_character

	lea	-1(a1),a1
not_much_of_an_alias
	lea	32(sp),sp		** NOTE STACK CHANGE
.D	move.b	(a3)+,(a1)+	copy tempbuf onto end
	bne.s	.D
	clr.b	mult_comm_flag(a5)
	bsr	handle_mult_comms
	bsr	handle_command_alias
	clr.b	mult_comm_flag(a5)
	bsr	handle_mult_comms	put LF at end Allow for aliases with ;'s
	
hca_nothing_typed
	movem.l	(sp)+,d0-d2/a1-a4
	rts


	
clr_parms	movem.l	a0-a1,-(sp)
	lea	parm1(a5),a0
	lea	endofparms(a5),a1
clr_loop1	clr.l	(a0)+
	cmp.l	a0,a1
	bne.s	clr_loop1
	movem.l	(sp)+,a0-a1
	rts

* GET PARM line pted to by A0
* LINE MUST END IN LF THEN 0
* returns A1 pointing to the address where the parm starts
* puts a 0 over the space or lf where it ends .A0 pts to next bit on end
* return d2=0 if got all possible commands from line
get_parm	moveq	#$20,d2	D2=delimiter
get_parm1	move.l	a0,a1	;make sure we can get the address before
	move.b	(a0)+,d1	;skip spaces
	cmp.b	#$20,d1
	beq.s	get_parm1
	cmp.b	#$9,d1	skip tabs
	beq.s	get_parm1
	cmp.b	#$0a,d1	;handle idiots who type spaces at end of line
	beq.s	last_parm
	cmp.b	#'"',d1	;handle double quotes
	bne.s	gp2
	addq.l	#1,a1
	moveq	#'"',d2	SET DELIMITER = "
	bra.s	gp2
gp4	addq.l	#1,a0	;make sure pts to after quotes d1 is dummy
gp2	move.b	(a0)+,d1	;a0 pts to after the space on exit
	cmp.b	#$0a,d1
	beq.s	gp3
	cmp.b	#$5c,d1	allow for \" (nested quotes)
	beq.s	gp4
	cmp.b	d2,d1
	bne.s	gp2
	clr.b -1(a0)	;make sure last byte is 0
	rts
last_parm	clr.b -1(a0)
	moveq #0,d2	;signify the end
	rts
gp3	lea -1(a0),a0 if ends in LF then dont null end, catch that next time
	rts

close_redirection
	tst.b	nonstdin(a5)
	beq	cls_outred
	move.l	thistask(a5),a0
	move.l	pr_CIS(a0),d1
	move.l	stdin(a5),pr_CIS(a0)	restore old stdin
	move.l	stdin(a5),inhandle(a5)
	jsr	_LVOClose(a6)
	clr.b	nonstdin(a5)
cls_outred
	tst.b	nonstdout(a5)
	beq	cls_nothing
	move.l	thistask(a5),a0
	move.l	pr_COS(a0),d1
	move.l	stdout(a5),pr_COS(a0)	restore old stdout
	move.l	stdout(a5),outhandle(a5)	
	jsr	_LVOClose(a6)
	clr.b	nonstdout(a5)
cls_nothing
	rts
	
* entry A0 pts to shelline
handle_redirection
	movem.l	d0/a0-a2,-(sp)
redir_2	move.b	(a0)+,d0	CHECK FOR REDIRECTION CHARS < >
	cmp.b	#$0A,d0
	beq	redir_fin
	cmp.b	#'"',d0	HANDLE QUOTES
	bne.s	.A
*	bsr	new_print
.B	move.b	(a0)+,d0
	cmp.b	#10,d0
	beq	redir_fin
	cmp.b	#'"',d0
	bne.s	.B
.A	cmp.b	#$20,d0
	bne.s	redir_2
	move.b	(a0),d0	TEST CHAR AFTER SPACE.
	cmp.b	#'>',d0
	beq.s	redir_out
	cmp.b	#'<',d0
	bne.s	redir_2
redir_in	lea	nonstdin(a5),a2
	move.l	#MODE_OLDFILE,d2
	bsr	redir_open
	move.l	thistask(a5),a0
	move.l	d0,pr_CIS(a0)	MAKE STDIN DIFFERENT.
	move.l	d0,inhandle(a5)
	move.l	a3,a0
	bra	redir_2		KEEP SEARCHING
redir_out	cmp.b	#'>',1(a0)
	beq.s	redir_append
	lea	nonstdout(a5),a2
	move.l	#MODE_NEWFILE,d2
	bsr	redir_open
	move.l	thistask(a5),a0
	move.l	d0,pr_COS(a0)
	move.l	d0,outhandle(a5)
	move.l	a3,a0
	bra	redir_2
redir_append
	lea	nonstdout(a5),a2
	move.l	#MODE_OLDFILE,d2
	bsr	redir_open
	move.l	thistask(a5),a0
	move.l	d0,pr_COS(a0)
	move.l	d0,outhandle(a5)
	move.l	d0,d1
	moveq	#0,d2	set position
	moveq	#1,d3	set mode
	jsr	_LVOSeek(a6)
	move.l	a3,a0
	bra	redir_2
	
redir_fin
	movem.l	(sp)+,d0/a0-a2
	rts

redir_open
	lea	-1(a0),a3		ALIGN WITH SPACE
	bsr	copy_redirector
	move.l	a2,d1
	jsr	_LVOOpen(a6)
	tst.l	d0
	bne.s	redopefin
	clr.b	(a2)
	bra	DOSerr
redopefin	rts
	
** ENTRY A0 pts redirection symbol. A2 pts to area to save redirection name
** EXIT A2 area holds null end string and redirection name is deleted from
**      shelline
copy_redirector
	movem.l	a0-a2,-(sp)
	move.l	a0,a1	SAVE START OF REDIRECTION STRING
	move.b	(a0)+,d0	BUMP PAST '<' or '>'
cpred3	move.b	(a0)+,d0
	cmp.b	#$20,d0
	beq.s	cpredsp
	cmp.b	#$0A,d0
	beq.s	cpredlf
	cmp.b	#'>',d0	HANDLE APPEND REDIRECTION PROPERLY
	beq.s	cpred3
	move.b	d0,(a2)+	COPY NEWSTDIN/OUT TO NONSTDIN/OUT
	bra.s	cpred3
cpredlf	lea	-1(a0),a0
	lea	-1(a1),a1
cpredsp	clr.b	(a2)+	A0 should point to after the space or lf
	lea	shelline+SHELLINE_SIZE(a5),a2
	move.l	a1,d0
	sub.l	a0,d0
	add.l	d0,next_comm_ptr(a5)	offset next_comm_ptr
cpred5	move.b	(a0)+,(a1)+	delete redirection string from shelline
	cmp.l	a0,a2
	bhi.s	cpred5
	movem.l	(sp)+,a0-a2
	rts

** V1.14 multiple commands on command line. Delimit by ';'
* ENTRY A0 pts to shelline, EXIT A0 pts to start of next bit on line.
handle_mult_comms
	movem.l	d0/a1,-(sp)
	tst.b	mult_comm_flag(a5)
	beq.s	.A
	move.l	next_comm_ptr(a5),a0
.A	move.l	a0,a1
.B	move.b	(a1)+,d0
	cmp.b	#'"',d0	ignore semi-colons between quotes
	bne.s	.C
.D	move.b	(a1)+,d0
	beq.s	endofline	END OF LINE IS NULL.
	cmp.b	#10,d0
	beq.s	fndret
	cmp.b	#'"',d0
	bne.s	.D
.C	cmp.b	#';',d0
	beq	fndsemi
	cmp.b	#10,d0
	bne.s	.B
fndret	tst.b	(a1)	IF NULL FOLLOWS LF THEN AT END OF LINE
	bne.s	fndsemi
endofline	clr.b	mult_comm_flag(a5)
	movem.l	(sp)+,d0/a1
	rts
fndsemi	move.b	#10,-1(a1)	REPLACE ; or LF WITH LF
	move.l	a1,next_comm_ptr(a5)
	move.b	#1,mult_comm_flag(a5)
	movem.l	(sp)+,d0/a1
	rts


* Create CLI-Interface-Structure	V2.0 *
CreateCLI tst.b	CLIflag(a5)
	beq	.A
	clr.l	EntryA0(a5)
	move.l	#64,d0
	move.l	#MEMF_CLEAR+1,d1	memory for CLI
	bsr	iwantmem
	beq	.B
	move.l	d0,a2
	move.l	thistask(a5),a3
	lsr.l	#2,d0
	move.l	d0,pr_CLI(a3)
	move.l	dl_Root(a6),a0
	move.l	(a0),a0
	add.l	a0,a0
	add.l	a0,a0
	moveq	#0,d1
	move.l	(a0),d0
	subq.l	#1,d0
.C	addq.l	#1,d1
	addq.l	#4,a0
	tst.l	(a0)		look for free CLI-Number
	dbeq	d0,.C
	tst.l	(a0)
	bne	.B
	lea	pr_MsgPort(a3),a1
	move.l	a1,(a0)
	move.l	d1,pr_TaskNum(a3)
	move.l	#10,cli_FailLevel(a2)
	move.l	#-1,cli_Interactive(a2)
	move.l	#1000,cli_DefaultStack(a2)	1000 LONGs
	move.l	pr_FileSystemTask(a3),filesys_old(a5)
	tst.l	wb_msg(a5)
	beq	.B	no WB-Msg -> Error ! (CreateCLI2)
	move.l	wb_msg(a5),a0
	tst.l	sm_Process(a0)
	beq	CreateCLI3	newcli/run -> CreateCLI3
	move.l	sm_ArgList(a0),a1
	moveq	#2,d0
	cmp.l	sm_NumArgs(a0),d0
	bhi.s	.H		Project ?
	addq.l	#8,a1
.H	move.l	(a1),a0		Lock on Current Dir
	move.l	a0,d1
	beq	.B
	add.l	a0,a0
	add.l	a0,a0
	move.l	fl_Task(a0),pr_FileSystemTask(a3)
	move.l	dosbase(a5),a6
	jsr	_LVODupLock(a6)		WB wants to free its own lock
	move.l	d0,d1
	jsr	_LVOCurrentDir(a6)
	move.l	d0,cdir_old(a5)
.E	move.l	4.w,a6
	moveq	#0,d0
	lea	iconname(pc),a1
	jsr	_LVOOpenLibrary(a6)	icon-library
	move.l	d0,iconbase(a5)
	beq	.B
	move.l	d0,a4
	move.l	wb_msg(a5),a0
	move.l	sm_ArgList(a0),a1
	moveq	#2,d0
	cmp.l	sm_NumArgs(a0),d0
	bhi.s	.I			Project ?
	move.l	12(a1),d0
	beq.s	.I
	move.l	d0,EntryA0(a5)		Name of Project as Script
	addq.l	#8,a1
.I	move.l	4(a1),a0		Name of Process
	move.l	a4,a6
	jsr	_LVOGetDiskObject(a6)
	move.l	d0,diskobj(a5)
	beq	.B
	move.l	d0,a0
	move.l	do_ToolTypes(a0),a0
	lea	wintool(pc),a1
	jsr	_LVOFindToolType(a6)	Look for WINDOW-ToolType
	lea	conname(pc),a0
	tst.l	d0
	beq.s	.D
	move.l	d0,a0
.D	move.l	a0,d1
	move.l	dosbase(a5),a6
	bsr	openwin			Open Window
	beq	.B
	move.l	diskobj(a5),a0
	move.l	do_ToolTypes(a0),a0
	lea	scripttool(pc),a1
	move.l	a4,a6
	jsr	_LVOFindToolType(a6)	Look for SCRIPT-ToolType
	tst.l	d0
	beq.s	.F
	move.l	d0,a0
	lea	prompt_string(a5),a1	there is enough place
	move.l	a1,EntryA0(a5)
.G	move.b	(a0)+,(a1)+	copy it
	bne.s	.G
	move.b	#10,-1(a1)	LF-End it
.F	move.l	diskobj(a5),a0
	jsr	_LVOFreeDiskObject(a6)
	clr.l	diskobj(a5)
	move.l	a4,a1
	move.l	4.w,a6
	jsr	_LVOCloseLibrary(a6)
	clr.l	iconbase(a5)
.A	move.l	dosbase(a5),a6
	moveq	#0,d0
	rts
.B	move.l	dosbase(a5),a6
	moveq	#-1,d0
	rts

* Open Window for both Input and Output, Name in d1 *
openwin	move.l	dosbase(a5),a6
	move.l	d1,a0
	cmp.b	#".",(a0)+
	bne.s	.C
	tst.b	(a0)
	beq.s	.A
.C	move.l	#MODE_NEWFILE,d2
	jsr	_LVOOpen(a6)		open output-Window
	move.l	d0,pr_COS(a3)
	beq	.B
	move.l	d0,cli_StandardOutput(a2)
	move.l	d0,cli_CurrentOutput(a2)
;	move.l	d0,outhandle(a5)
	move.l	d0,a0
	add.l	a0,a0
	add.l	a0,a0
	move.l	fh_Type(a0),pr_ConsoleTask(a3)
	lea	cone(pc),a0
	move.l	a0,d1
	move.l	#MODE_OLDFILE,d2
	jsr	_LVOOpen(a6)		open input-window
	move.l	d0,pr_CIS(a3)
	beq	.B
	move.l	d0,cli_StandardInput(a2)
	move.l	d0,cli_CurrentInput(a2)
.A	moveq	#-1,d0
.B	rts			d0=0 on Error

;* Create CLI-Interface-Structure without WB-Message for debugging V2.0 *
;CreateCLI2	lea	conname(pc),a0
;	move.l	a0,d1
;	bsr	openwin
;	beq.s	.B
;	lea	sysdisk(pc),a0
;	move.l	a0,d1
;	moveq	#-2,d2
;	jsr	_LVOLock(a6)
;	tst.l	d0
;	beq	.B
;	move.l	d0,a0
;	add.l	a0,a0
;	add.l	a0,a0
;	move.l	fl_Task(a0),pr_FileSystemTask(a3)
;	move.l	d0,d1
;	jsr	_LVOCurrentDir(a6)
;	move.l	d0,cdir_old(a5)
;	moveq	#0,d0
;	rts
;.B	moveq	#-1,d0
;	rts

* Create CLI-Interface-Structure with special newcli message	V2.0 *
*	a3:Process	a2:CLI_Struct	*
*sm_NumArgs:	General Memory Block
*sm_ToolWindow:	Current Dir
CreateCLI3	move.b	#1,WBflag(a5)	not started from WB
	move.l	sm_NumArgs(a0),a4	wb_msg in a0
	move.l	sm_ToolWindow(a0),d4
	clr.l	pr_ConsoleTask(a3)
	lea	conname(pc),a0
	move.l	parm2(a4),d1	WINDOW given ?
	bne.s	.I
	move.l	a0,d1
.I	bsr	openwin
	beq	.B
	move.l	d4,d1
	jsr	_LVODupLock(a6)		copy cd
	tst.l	d0
	beq	.B
	move.l	d0,a0
	add.l	a0,a0
	add.l	a0,a0
	move.l	fl_Task(a0),pr_FileSystemTask(a3)
	move.l	d0,d1
	jsr	_LVOCurrentDir(a6)
	move.l	d0,cdir_old(a5)
	lea	patharea(a4),a0
	lea	patharea(a5),a1
	bra.s	.C
.A	move.b	(a0)+,(a1)+	Copy Search-Paths
	bne.s	.A
.C	tst.b	(a0)
	bne.s	.A
	clr.b	(a1)
	lea	prompt_args(a4),a0
	lea	prompt_args(a5),a1
.G	move.b	(a0)+,(a1)+	Copy prompt
	bne.s	.G
	lea	now(a4),a0
	lea	now(a5),a1
	move.w	#HISTORY_SIZE+12-1,d0
.D	move.b	(a0)+,(a1)+	Copy History
	dbra	d0,.D
	move.l	failat_level(a4),failat_level(a5)
	moveq	#ctrl_inite-ctrl_init-1,d0
	lea	ctrl_codes(a4),a0
	lea	ctrl_codes(a5),a1
.E	move.b	(a0)+,(a1)+	Copy ctrl-codes
	dbra	d0,.E
	move.l	parm3(a4),d0	SCRIPT given ?
	beq.s	.H
	move.l	d0,a0
	lea	prompt_string(a5),a1	there is enough place
	move.l	a1,EntryA0(a5)
.F	move.b	(a0)+,(a1)+	Copy Script-Parm
	bne.s	.F
	move.b	#10,-1(a1)	LF-End it
.H	move.l	4.w,a6
	move.l	wb_msg(a5),a1
	jsr	_LVOReplyMsg(a6)
	clr.l	wb_msg(a5)
	move.l	dosbase(a5),a6
	moveq	#0,d0
	rts
.B	moveq	#-1,d0
	rts


* Remove CLI-Interface-Structure	V2.0 *
RemoveCLI tst.b	CLIflag(a5)
	beq	.A
	move.l	thistask(a5),a3
	tst.l	pr_CLI(a3)
	beq	.A
	move.l	pr_CLI(a3),d0
	add.l	d0,d0
	add.l	d0,d0
	move.l	d0,a2
	clr.l	pr_CLI(a3)	clear CLI-Pointer
	move.l	pr_TaskNum(a3),d0
	beq.s	.E
	add.l	d0,d0
	add.l	d0,d0
	move.l	dl_Root(a6),a0
	move.l	(a0),a0
	add.l	a0,a0
	add.l	a0,a0
	add.l	d0,a0
	clr.l	(a0)		free task-number
	clr.l	pr_TaskNum(a3)
.E	move.l	cdir_old(a5),d1
	jsr	_LVOCurrentDir(a6)
	move.l	d0,d1
	beq.s	.B
	jsr	_LVOUnLock(a6)
	move.l	cdback(a5),d1
	beq.s	.B
	jsr	_LVOUnLock(a6)
.B	move.l	filesys_old(a5),pr_FileSystemTask(a3)
	move.l	pr_CIS(a3),d1
	beq.s	.C
	jsr	_LVOClose(a6)	close input-window
	clr.l	pr_CIS(a3)
.C	move.l	pr_COS(a3),d1
	beq.s	.D
	jsr	_LVOClose(a6)	close output-window
	clr.l	pr_COS(a3)
.D	clr.l	pr_ConsoleTask(a3)
	clr.l	pr_Result2(a3)
	move.l	#64,d0
	move.l	a2,a1
	bsr	givemem		free memory of CLI
	move.l	diskobj(a5),d0
	beq.s	.F
	move.l	d0,a0
	move.l	iconbase(a5),a6
	jsr	_LVOFreeDiskObject(a6)
.F	move.l	iconbase(a5),d0
	beq.s	.A
	move.l	d0,a1
	move.l	4.w,a6
	jsr	_LVOCloseLibrary(a6)
.A	move.l	dosbase(a5),a6
	rts

*CHECK WHETHER THERE IS ENOUGH STACK FREE	V2.0 *
;d0=requested stacksize
stacktest movem.l	d0-d1/a0-a1,-(sp)
	move.l	topstack(a5),a0
	sub.l	sp,a0
	move.l	a0,d1
	add.l	d0,d1
	add.l	#1600,d1	;allow some bytes for DOS
	cmp.l	stacksize(a5),d1
	blo.s	.A
	lea	stack_tx(pc),a1
	bsr	pr_stringlf
	moveq	#-1,d0
	bra.s	.B
.A	moveq	#0,d0
.B	movem.l	(sp)+,d0-d1/a0-a1
	rts

too_less_args
	lea	less_args_tx(pc),a1
	bsr	pr_stringlf
	move.l	#RETURN_BAD,d0
	rts

*SendPacket-Error-Tester
PKTerr	tst.l	sp_res1(a5)
	bne	.A
	move.l	sp_res2(a5),d0
	bsr.s	pr_DOSerr
	bra.s	galactic
.A	rts
*DOSERRor but Unlock first using D7 as the lock
DOSerrUL	move.l d7,d1		;Assume D7=lock
	jsr _LVOUnLock(a6)		;NB the last DOS error may be destroyed
;DON'T PUT ANYTHING HERE
*DOSERRor handler D0=0 on entry
DOSerr	jsr _LVOIoErr(a6)
	cmp.l #232,d0
	bne.s .A
	moveq #0,d0
	rts			;Return if ERROR_NO_MORE_ENTRIES
.A	bsr.s	pr_DOSerr	;entry for dospacket
galactic	move.l	errorstack(a5),sp	;restore stack
	moveq	#RETURN_BAD,d0
	bra	chkfail		;reenter shell loop

* ENTRY D0=dos error number
pr_DOSerr	lea	doserrtx(pc),a1
	bsr	pr_string
	lea	doserror_text(pc),a1	v1.21 handle textual errors
	bra.s	.C
.B	tst.b	(a1)+
	bne.s	.B
.C	move.b	(a1)+,d1
	beq.s	.A
	cmp.b	d1,d0
	bne.s	.B
	bsr	pr_string
.A	bsr	print10
	bra	pr_lf
	
* fix up parameters that exist or not
fixpam32	move.l parm3(a5),d0
	move.l d0,a1
	bne.s fixpam2
	lea null(pc),a1
fixpam2	move.l parm2(a5),d0
	move.l d0,a0
	bne.s fxpam
	lea null(pc),a0
fxpam	rts
	
*************************
*	RENAME		*
*************************
renamez	bsr fixpam32
;DON'T PUT ANYTHING HERE
	* A0-> oldname  A1-> newname
rename	move.l a0,d1
	move.l a1,d2
	jsr _LVORename(a6)
	tst.l d0
	beq DOSerr
	moveq	#RETURN_OK,d0
	rts

*************************
*	MAKEDIR		*
*************************
makedirz	lea	parm2(a5),a4
.A	move.l	(a4)+,d1
	beq.s	.B
	bsr.s	mkdir
	bra.s	.A
.B	moveq	#RETURN_OK,d0
	rts
	
*MAKEDIR D1-> directory name
mkdir	jsr	_LVOCreateDir(a6)
	tst.l	d0
	beq	DOSerr
	move.l	d0,d1
	jsr	_LVOUnLock(a6)
*	moveq	#0,d0
	rts

** CHECK DIRECTORY DESCRIPTION IN (A0) AND CONVERTS INTO DIRNAME[0] AND PUTS
** THE WILD CARD IN WILD_STRING. ALSO SETS WILD_FLAG
handle_wild_dirs
	clr.b	wild_flag(a5)
	bsr	check_wild
	tst.b	d0
	bne.s	.A
	lea	wild_string(a5),a1
	bsr	split_wild
	move.b	#1,wild_flag(a5)
.A	rts	

*************************
*	DELETE		*
*************************
deletez	lea	parm2(a5),a4	v1.21 delete as many as you like.
	move.l	(a4),a0
	bsr	check_recurs
	tst.b	recurs_flag(a5)
	beq.s	.A
	addq.l	#4,a4
.A	move.l	(a4)+,d1
	beq.s	del_end
	bsr.s	delete2
	bra.s	.A
del_end	moveq	#RETURN_OK,d0
	rts
	
;DON'T PUT ANYTING HERE
*DELETE FILE D1-> filename
delete2	clr.w	indent_count(a5)
	move.l	d1,-(sp)			;NOTE D1 is pushed
	move.l	d1,a0
	bsr	handle_wild_dirs
	bsr	fibexam			LOCK DIRECTORY OR FILE
	tst.l	fib_DirEntryType(a5)
	bpl.s	delete_dir
	move.l	d7,d1
	jsr	_LVOUnLock(a6)		
	move.l	(sp)+,d1			;FIXED V1.05
	move.l	d1,a1
	bsr	prindent		PRINT NAME OF SINGLE FILE TO GO
	bra	del1file
delete_dir
	moveq	#0,d6			;init cd count
delete_dir2
	move.l	d7,d1
	jsr	_LVOCurrentDir(a6)		CD to the directory
	tst.l	d6
	bne.s	this_is_a_sub_dir
	move.l	d0,temp2(a5)		;save original directory lock
	bra.s	dd3		DONT UNLOCK THE ORIGINAL LOCK (YET)
this_is_a_sub_dir
	move.l	d0,d1			;unlock old entry dir.
	jsr	_LVOUnLock(a6)
dd3	bsr	check_c
	bne	del_die_safely
	bsr	fibexnx
	tst.l	d0
	beq	del_dir_finished

	tst.b	wild_flag(a5)
	beq.s	ddx500
	lea	fib_FileName(a5),a0
	lea	wild_string(a5),a1
	bsr	wildmatch
	tst.b	d0
	bne.s	dd3

ddx500	lea	fib_FileName(a5),a0
	lea	tempbuf(a5),a1
	bsr	cp_string			;copy filename to tempbuf
	move.l	fib_DirEntryType(a5),temp1(a5) ;save type
delete_d2	bsr	check_c
	bne	del_die_safely
	bsr	fibexnx			;get next entry
	tst.l	d0
	beq.s	ddx501
	tst.b	wild_flag(a5)
	beq.s	ddx501
	move.l	d0,d4
	lea	fib_FileName(a5),a0
	lea	wild_string(a5),a1
	bsr	wildmatch
	tst.b	d0
	bne.s	delete_d2
	move.l	d4,d0
ddx501	move.l	d0,-(sp)		push exnext result
	lea	-84(sp),sp		;alloc 84 bytes on stack
	lea	fib_FileName(a5),a0
	lea	4(sp),a1
	bsr	cp_string		;copy filename to stack

	move.l	fib_DirEntryType(a5),(sp)

	bsr	del_filet		DELETE PRIOR ENTRY
	
	move.l	(sp),temp1(a5)	grab dirtype
	lea	4(sp),a0
	lea	tempbuf(a5),a1
	bsr	cp_string		;copy stack to temp
	lea	84(sp),sp		;dealloc 84 bytes on stack
	move.l	(sp)+,d0
	tst.l	d0
	beq.s	del_dir_finished
	bra	delete_d2

del_filet lea	tempbuf(a5),a1	delete file (in tempbuf) or enter new dir
	tst.l	temp1(a5)
	bmi.s	del_print_file
	tst.b	recurs_flag(a5)
	bne.s	.A
.B	rts
.A	move.l	#230,d0	;(88+80+subs)
	bsr	stacktest
	bne.s	.B
	lea	farb3(pc),a1
	bsr	pr_string
	lea	tempbuf(a5),a1
del_print_file
	bsr	prindent		PRINT FILE OR DIR NAME
	lea	tempbuf(a5),a1
	move.l	a1,d1
	tst.l	temp1(a5)			;check dir type
	bmi.s	del1file
del_new_dir
	bsr	pr_tab
	lea	dirtext(pc),a1	PRINT "DIR"
	bsr	pr_stringlf
	addq.w	#2,indent_count(a5)
	addq.l	#1,d6
	lea	tempbuf(a5),a0		A0=tempbuf
	bsr	fibexam
	lea	-80(sp),sp
	lea	(sp),a1
	lea	fib_FileName(a5),a0
	bsr	cp_string		;copy dirname to stack
	bra	delete_dir2	recurs

* IF CTRLC CHECKING CALLS HERE IT WILL ONLY BREAK THE DELETION IN THE CURRENT DIR
del_dir_finished
	tst.l	d6
	bne.s	not_back_enough
	move.l	temp2(a5),d1
	jsr	_LVOCurrentDir(a6)
	move.l	d0,d1			;unlock old.
	jsr	_LVOUnLock(a6)
	move.l	(sp)+,d1
	jsr	_LVODeleteFile(a6)		;delete directory name
	bra	pr_lf

not_back_enough
	subq.l	#1,d6
	subq.w	#2,indent_count(a5)
	lea	backslash(pc),a0
	bsr	fibexam
	move.l	d7,d1
	jsr	_LVOCurrentDir(a6)
	move.l	d0,d1			;unlock old.
	jsr	_LVOUnLock(a6)
	lea	(sp),a1
	move.l	a1,d1
	jsr	_LVODeleteFile(a6)		;delete directory name
	lea	80(sp),sp
	move.l	d7,d0
	bsr	fibexam2
	bra	fibexnx

del1file
	movem.l	d2-d4/a2,-(sp)
;	move.l	d1,d4
;	lea	temp2buf(a5),a2
;	clr.b	(a2)
;	move.l	a2,d2
;	moveq	#20,d3	read only 1 char
;	move.l	inhandle(a5),d1
;	beq.s	.C
;	jsr	_LVORead(a6)
;	or.b	#$20,(a2)
;	cmp.b	#"y",(a2)	yes ?
;	beq.s	.C
;	cmp.b	#"j",(a2)
;	bne.s	.B
;.C	move.l	d4,d1
	jsr	_LVODeleteFile(a6)
	tst.l	d0
	beq.s	.A
	lea	deletedtx(pc),a1	PRINT "...DELETED"
	bsr	pr_string
.B	bsr	pr_lf
	movem.l	(sp)+,d2-d4/a2
	rts
.A	jsr	_LVOIoErr(a6)	IF FILE IS PROTECTED OR SOMETHING
	bsr	pr_DOSerr		THEN GET OUT TO OLD DIRECTLY LEVEL
del_die_safely
.C	tst.l	d6		CLEANLY.
	bne.s	.B
	move.l	temp2(a5),d1
	jsr	_LVOCurrentDir(a6)
	move.l	d0,d1			;unlock old.
	jsr	_LVOUnLock(a6)
	bsr	pr_lf
	bra	galactic		GET BACK TO ORIGINAL STACK LEVEL
*				AND GET TO MAIN LOOP
.B	subq.l	#1,d6
	lea	backslash(pc),a0
	bsr	fibexam
	move.l	d7,d1
	jsr	_LVOCurrentDir(a6)
	move.l	d0,d1			;unlock old.
	jsr	_LVOUnLock(a6)
	bra.s	.C

**************	
compose_prompt
	lea	prompt_string(a5),a1
	lea	farb3(pc),a0
cpro4	move.b	(a0)+,(a1)+	copy highlight colour
	bne.s	cpro4
	lea	-1(a1),a1
	lea	prompt_args(a5),a0
cpro3	move.b	(a0)+,d0
	beq	composer3
	cmp.b	#$5c,d0 ;\
	bne.s	.A
	move.b	(a0)+,d0
	bra.s	composer2
.A	cmp.b	#'%',d0
	bne.s	composer2
	move.b	(a0)+,d0
	cmp.b	#'p',d0		check if %p
	bne.s	try_line_num
	lea	CD_string(a5),a2
cpro2	move.b	(a2)+,(a1)+	copy cd_string to prompt_string
	bne.s	cpro2
	lea	-1(a1),a1
	bra	cpro3
try_line_num
	cmp.b	#'l',d0		check if %l
	bne.s	try_task_num
	move.l	count_line(a5),d0
	moveq	#0,d1
	move.l	a1,a2
	bsr	qdecpr		insert current line number
	move.l	a2,a1
	bra	cpro3
try_task_num
	cmp.b	#'n',d0		check if %n
	bne.s	composer2
	move.l	thistask(a5),a2
	move.l	pr_TaskNum(a2),d0
	add.b	#$30,d0
composer2	move.b	d0,(a1)+
	bra	cpro3
composer3	lea	farb1(pc),a0
cpro5	move.b	(a0)+,(a1)+
	bne.s	cpro5
	rts

*************************
*	PROMPT		*
*************************
promptz	tst.l	parm2(a5)
	beq.s	promptz2
	move.l	parm2(a5),a0
	lea	prompt_args(a5),a1
promptz3	move.b	(a0)+,(a1)+
	bne.s	promptz3
	MOVEQ	#RETURN_OK,D0
	rts
promptz2	lea	prompt_args(a5),a1
	bsr	pr_stringlf
	moveq	#RETURN_OK,d0
	rts
	
	
*FILL FIB WITH EXAMINE A0-> directory name ,D7=filelock on return
fibexam	move.l	a0,-(sp)
	moveq	#ACCESS_READ,d2
fibexam3 move.l a0,d1
	jsr	_LVOLock(a6)
	tst.l	d0
	beq	DOSerr
	bsr	fibexam2
	move.l	(sp)+,a0
	rts
fibexam2 move.l	d0,d7
	move.l	d0,d1
	move.l	a5,d2
	jsr	_LVOExamine(a6)
	tst.l	d0
	beq	DOSerrUL
	rts

*****************
*	CD	*
*****************
cdz	tst.l	parm2(a5)
	beq	querycd
	move.l	parm2(a5),a0
*CHANGE DIRECTORY A0-> new current directory
	bsr	fibexam
	tst.l	fib_DirEntryType(a5)	;check entry OK
	bpl.s	.A
	lea	cderrtx(pc),a1
	bsr	pr_string
	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	moveq	#RETURN_ERROR,d0
	rts
.A	move.l	d7,d1
chdir	jsr	_LVOCurrentDir(a6)
	move.l	cdback(a5),d1
	move.l	d0,cdback(a5)	remember old directory
	jsr	_LVOUnLock(a6)	unlock the old directory
	bsr	eval_CD		update cd string
	moveq	#RETURN_OK,d0
	rts
	
querycd	bsr	eval_CD
	lea	CD_string(a5),a0
	bsr	new_print
	moveq	#RETURN_OK,d0
	bra	pr_lf


** Evaluate entire name of current directory and put in CD_string
eval_CD	clr.b	CD_string(a5)
	lea	null(pc),a0
	move.l	a0,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	tst.l	d0
	beq.s	.A
	move.l	d0,a0
	add.l	a0,a0
	add.l	a0,a0
	move.l	fl_Key(a0),cd_block(a5)
	move.l	fl_Volume(a0),cd_volnode(a5)
	lea	CD_string(a5),a0
	bsr	eval_full_path
	jsr	_LVOUnLock(a6)
.A	rts
	
** evaluate entire name associated with lock in D0, store string in A0
** Return D1 = last lock to unlock
** Reg usage:a0,d0,d1,d2,a3 (must not use A2)
eval_full_path
	lea	-88(sp),sp
	move.l	a0,4(sp)		save address of string
	move.l	d0,(sp)		save original lock on stack
	move.l	d0,d1
	move.l	a5,d2
	jsr	_LVOExamine(a6)
	move.l	4(sp),a1
	lea	fib_FileName(a5),a0
evx1	move.b	(a0)+,(a1)+	COPY FILENAME TO deststring
	bne.s	evx1
	lea	-1(a1),a3
evcd2	move.l	(sp),d1		get lock
	jsr	_LVOParentDir(a6)
	tst.l	d0
	beq.s	root_found
	move.l	(sp),d1
	move.l	d0,(sp)
	jsr	_LVOUnLock(a6)	unlock last
	move.l	(sp),d1
	move.l	a5,d2
	jsr	_LVOExamine(a6)
	lea	fib_FileName(a5),a0
	lea	8(sp),a1
evx2	move.b	(a0)+,(a1)+	stackbuf = filename
	bne.s	evx2
	move.b	#'/',-1(a1)
	move.l	4(sp),a0
evx3	move.b	(a0)+,(a1)+	stackbuf = filename/CD_string
	bne.s	evx3
	move.l	4(sp),a1
	lea	8(sp),a0
evx4	move.b	(a0)+,d0
	move.b	d0,(a1)+
	cmp.b	#'/',d0
	bne.s	evx4
	lea	-1(a1),a3
evx5	move.b	(a0)+,(a1)+	dest string = stackbuf
	bne.s	evx5
	bra	evcd2
root_found
	move.l	(sp),d1
	tst.b	(a3)
	bne.s	root2
	clr.b	1(a3)
root2	move.b	#':',(a3)
	lea	88(sp),sp
	rts

*ADDPATH A0-> path  A1-> parameter  A2-> destination for string
** eg. (A0)='df0:libs',0  (A1)='arp.library',0  (A2)='df0:libs/arp.library',0
addpath	movem.l a0-a2,-(sp)
	move.b (a0),d0
	beq.s addp4
addp1	move.b (a0)+,d0
	beq.s addp2
	move.b d0,(a2)+
	bra.s addp1
addp2	move.b -2(a0),d0
	cmp.b #':',d0
	beq.s addp4
	cmp.b #'/',d0
	beq.s addp4
	move.b #'/',(a2)+
addp4	move.l a1,a0
	move.l a2,a1
	bsr cp_string
	movem.l (sp)+,a0-a2
	rts


* Search Resident list for command	V2.0:Global resi's
* RETURN D0=seglist OR 0 if not found
*	A0=addr of node		D2=addr of Vorgänger
search_res	move.l	parm1(a5),a4
search_res2
	bsr	resi_hand
	beq.s	.D
	move.l	a0,d2
.A	lsl.l	#2,d0
	move.l	a4,a1			string
	move.l	d0,a2
	lea	resi_name(a2),a0	BSTR
	moveq	#0,d3
	move.b	(a0)+,d3
	subq.w	#1,d3
.B	move.b	(a0)+,d0
	move.b	(a1)+,d1
	cmp.b	ctrl_codes+13(a5),d1
	bne.s	.F
	tst.b	(a1)
	beq.s	.C
.F	bsr	compD1D0nocase
	dbne	d3,.B
	bne.s	.E	not equal
	tst.b	(a1)
	beq.s	.C	the (null-)END
.E	move.l	a2,d2
	move.l	resi_link(a2),d0	get link
	bne.s	.A
.D	moveq	#0,d0
	rts
.C	moveq	#-1,d1
	cmp.l	resi_usecount(a2),d1	is it a system-resi ?
	beq.s	.D
	move.l	resi_seglist(a2),d0	get seglist
	move.l	a2,a0
	rts


*Search paths for command
spaths	move.l	parm1(a5),a4	A4=parm1
spaths2	move.l	a4,a2
	bsr	lock_or_load	search current
	tst.l	d0
	bne	gotit
	tst.l	d7
	beq.s	.C
	tst.b	forcediskflag(a5)
	bne.s	.D		do not change dir
	tst.l	fib_DirEntryType(a5)	is it a DIR ?
	bmi.s	.D			no !
	addq.l	#4,sp		return from archie3
	move.l	a2,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	move.l	d0,d1
	bra	chdir

.D	bsr	s_flagset	exec script ?
.C	move.l	a4,a0
.F	move.b	(a0)+,d0	are there path-specific chars in the name
	cmp.b	#"/",d0
	beq	no_more_paths
	cmp.b	#":",d0
	beq	no_more_paths
	tst.b	d0
	bne.s	.F
	moveq	#-1,d1
	bsr	changeWindowPtr		no requesters
	lea	patharea(a5),a0
.A	tst.b	(a0)
	beq.s	no_more_paths	CHECK IF PATH LIST IS EMPTY
	move.l	a0,d4
* path(a0) + parm1 -> tempbuf
	move.l	a4,a1
	lea	tempbuf(a5),a2
	bsr	addpath
	move.l	a2,d1
	bsr	lock_or_load
	tst.l	d0
	bne.s	gotit
	tst.l	d7
	beq.s	.E
	tst.l	fib_DirEntryType(a5)	is it a DIR ?
	bpl.s	.E
	bsr	s_flagset	exec script
.E	move.l	d4,a0
.B	tst.b	(a0)+
	bne.s	.B
	bra.s	.A
no_more_paths
	moveq	#0,d0
gotit	moveq	#0,d1
	bra	changeWindowPtr

lock_or_load
	move.l	a2,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	move.l	d0,d7
	beq.s	.A
	move.l	a2,d1
	jsr	_LVOLoadSeg(a6)
	tst.l	d0
	bne.s	.B
	move.l d7,d1
	move.l a5,d2
	jsr	_LVOExamine(a6)
	tst.l	d0
	bne.s	.C
	move.l	d7,d1
	jsr	_LVOUnLock(a6)
.A	moveq	#0,d7		file not found
	moveq	#0,d0
	rts
.C	moveq	#0,d0		file is a script or dir
.B	move.l	d0,-(sp)	file is executable
	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	move.l	(sp)+,d0
	rts

s_flagset	move.l	fib_Protection(a5),d0
	btst	#6,d0
	beq.s	.A
	bsr	readpathfile		;A2 pts to filename
	addq.l	#8,sp	;kill return addresses (archie3,spaths,s_flagset)
	addq.l	#4,sp
	bra	xz3
.A	rts

* ARCHIE 3 calls system0 to execute non internal commands
archie3	tst.l	parm1(a5)	;exit if nothing typed
	beq	noarch31
	bsr	save_mem
	clr.b	resi_flag(a5)	=0 if resident
	bsr	search_res	search resident list first
	tst.l	d0
	bne.s	.A
	addq.b	#1,resi_flag(a5)	=1 if not resident
	bsr	spaths		;load the command
	tst.l	d0
	beq	noarch32		;could not load
.A	move.l	d0,temp1(a5)		;save the segment
	bsr	raw_off
	bsr	save_time
	lea	CLIbuf(a5),a0
	move.l	a0,-(sp)	;push arg_args ptr.
	move.l	d0,-(sp)	;push seglist
	move.l	parm1(a5),d0
	move.l	d0,-(sp)	;push arg_name
	bsr	_System0	TAKES 3 PARMS(ARG_NAME,SEGLIST,ARGS)
	lea	12(sp),sp
	move.l	d0,-(sp)
	jsr	_LVOIoErr(a6)
	move.l	d0,Result2(a5)
	tst.b	resi_flag(a5)
	beq.s	.B
	move.l	better_Seglist(a5),d1
	jsr	_LVOUnLoadSeg(a6)
.B	tst.b	stat_mode_flag(a5)
	beq.s	.C
	bsr	show_status
.C	bsr	raw_on
	move.l	(sp)+,d2	RESULT IN D2
	beq.s	.D
	move.l	Result2(a5),d0
	bsr	pr_DOSerr	if result > 0 print error
.D	move.l	d2,d0	
noarch31	rts
noarch32	lea badcomm(pc),a1
	moveq	#RETURN_BAD,d0	return d0 bad	V1.30
	bra pr_string


*****	SYSTEM0 execute command from disk from Sozobon C distribution.
_System0
	movem.l	d2-d3/a2-a6,-(sp)	;SAVED_REGS
	moveq	#NO_CLI,REG_Result      ;#-1,d3 ERROR - not a CLI task
	move.l	4.w,REG_SysBase	;4,a6
	move.l	thistask(a5),REG_Process	;a2
	move.l	pr_CLI(REG_Process),d0
	beq	quit0

* build local stack frame & save some values
	lsl.l	#2,d0
	move.l	d0,REG_CLI	;a3
	move.l	sp,REG_PrevStack        ;a1 save old stack pointer
	move.l	sp,d0
	and.b	#$fc,d0 ;make SP longword-aligned for BPTRs
	move.l	d0,sp
	sub.l	#sf_SIZEOF,sp	;stack-frame-struct
	move.l	REG_PrevStack,sf_PrevStack(sp)
	move.l	REG_Process,sf_Process(sp)
	move.l	REG_CLI,sf_CLI(sp)
	move.l  pr_ReturnAddr(REG_Process),sf_SaveReturnAddr(sp)

* allocate space for stack
	moveq	#NO_MEM,REG_Result	;ERROR - no memory for STACK
	move.l	cli_DefaultStack(REG_CLI),d0	;in longwords for "VEC"
	lsl.l	#2,d0
	move.l	d0,sf_PushSize(sp)
	addq.l	#4,d0	;one additional longword
	move.l	d0,sf_StackSize(sp)
	moveq	#1,d1	;intentionally NOT "MEMF_PUBLIC"!; V2.0 Why not ?
	callsys	AllocMem
	tst.l	d0
	beq	quit1
	move.l	d0,sf_StackBase(sp)	;save result

* save old command pointer, build new BCPL command name
	move.l	cli_CommandName(REG_CLI),sf_SaveCommandName(sp)
	move.l	sf_PrevStack(sp),REG_PrevStack
	move.l	ARG_NAME(REG_PrevStack),a0 ;first parameter to "System0()"
	lea	sf_CommandName(sp),a1 ;BSTR
	move.w	#MAXBSTR-2,d0
	bsr	cpBSTR
	move.l	d0,cli_CommandName(REG_CLI)
* save contents of Current Input Stream
	move.l	pr_CIS(REG_Process),d0
	lsl.l	#2,d0
	move.l	d0,REG_CIS
	move.l	REG_CIS,sf_CIS(sp)
	move.l	fh_Buf(REG_CIS),sf_SCB_Buf(sp)
	move.l	fh_Pos(REG_CIS),sf_SCB_Pos(sp)
	move.l	fh_End(REG_CIS),sf_SCB_End(sp)

* convert argument to LF-terminated string
	move.l	sf_PrevStack(sp),REG_PrevStack
	move.l	ARG_ARGS(REG_PrevStack),a0 ;third argument to "System0()"
	lea	sf_CommandArgs(sp),a1	;first buffer location
	move.l	a1,d0
	lsr.l	#2,d0
	move.l	d0,fh_Buf(REG_CIS)
	move.w	#MAXBSTR-1,d0	;leave some room for terminating LF
	bra.s	.D
.C	move.b	d1,(a1)+
.D	move.b	(a0)+,d1
	dbeq	d0,.C
	move.b	#LF,(a1)
	move.l	sf_PrevStack(sp),REG_PrevStack
	sub.l	ARG_ARGS(REG_PrevStack),a0	;subtract first position
	move.l	a0,d0	;do NOT subtract 1, LF need this byte
* setup start/end indices in Stream Control Block
	clr.l   fh_Pos(REG_CIS)
	move.l  d0,fh_End(REG_CIS)

* misc setup
	clr.l	pr_Result2(REG_Process)	;clear secondary result
	move.l	a5,sf_Membase(sp)	;save membase
;	moveq	#0,d0
;	moveq	#0,d1
;	bset	#SIGBREAKB_CTRL_C,d1
;	callsys	SetSignal	;clear CTRL-C flag

* handle seglist and start address
	move.l	cli_Module(REG_CLI),sf_SaveModule(sp)
	move.l	sf_PrevStack(sp),REG_PrevStack
	move.l	ARG_SEGLIST(REG_PrevStack),d0 ;second argument to "System0()"
	move.l	d0,cli_Module(REG_CLI)
	lsl.l	#2,d0
	move.l	d0,a3
* setup processor registers & C-interface
	lea	sf_CommandArgs(sp),a0
	move.l	fh_End(REG_CIS),d0
* setup processor registers, BCPL-interface, stack & return address for "Exit()"
	move.l	sf_StackBase(sp),a1	;BCPL stack, low end
	move.l	sf_PushSize(sp),d2
	lea	4(a1,d2.l),a4	;must not destroy REG_Process!
	move.l	sp,-(a4)	;previous stack frame
	move.l	d2,-(a4)	:stack size in bytes
	move.l	a4,pr_ReturnAddr(REG_Process)
	move.l	a4,sp
	move.l	dosbase(a5),a4	;V2.0 small data
	movem.l	dl_A2(a4),a2/a5/a6

* now call the command at its entry point
	jsr	4(a3)	;code starts one longword behind segment pointer
	move.l	d0,REG_Result	;save return code

* get old stackframe & reload old register contents
	move.l	4(sp),sp	;old stack frame
	move.l	sf_Membase(sp),a5
	move.l	sf_Process(sp),a0
	move.l	sf_SaveReturnAddr(sp),pr_ReturnAddr(a0)
	move.l	sf_CIS(sp),d0
	move.l	d0,a1
	lsr.l	#2,d0
	move.l	d0,pr_CIS(a0)	;V2.0 restore CIS
	move.l	sf_CLI(sp),a0
	move.l	sf_SaveCommandName(sp),cli_CommandName(a0)
* Next line makes powerpacker programs deallocate memory properly
	move.l	cli_Module(a0),better_Seglist(a5)	;V2.0 small data
	move.l	sf_SaveModule(sp),cli_Module(a0)
* restore original contents of Current Input Stream
	move.l	sf_CIS(sp),a0
	lea	sf_CommandArgs(sp),a1
	move.l	a1,d0
	lsr.l	#2,d0
	cmp.l	fh_Buf(a0),d0	;still the same?
	bne.s	.E	;no: don't restore
	move.l	sf_SCB_Buf(sp),fh_Buf(a0)
.E	move.l	sf_SCB_Pos(sp),fh_Pos(a0)
	tst.l	fh_End(a0)	;end index set?
	beq.s	.F	;no: don't restore
	move.l	sf_SCB_End(sp),fh_End(a0)

* free temporary stack
.F	move.l	4.w,REG_SysBase
	move.l	sf_StackBase(sp),a1
	move.l	sf_StackSize(sp),d0
	callsys	FreeMem

quit1	move.l	sf_PrevStack(sp),sp	;UNLINK local variables
quit0	move.l	REG_Result,d0
	movem.l	(sp)+,d2-d3/a2-a6	;SAVED_REGS
quitx	rts


*************************
*	HELP		*
*************************
helpz	bsr	rawh_off
	move.l	parm2(a5),d7
	bne	help_man
	lea	help_tx1(pc),a1
	bsr	pr_stringlf
	lea	comtext(pc),a4
	lea	tempbuf(a5),a3
.D	moveq	#5,d3
.C	move.l	a3,a2
	tst.b	(a4)		
	beq	.E
	moveq	#12,d2
.B	subq.l	#1,d2
	move.b	(a4)+,(a2)+
	bne.s	.B
	tst.b	-(a2)	bump	back
.A	move.b	#$20,(a2)+
	dbra	d2,.A
	clr.b	(a2)
	move.l	a3,a1
	bsr	pr_string
	dbra	d3,.C
	bsr	pr_lf
	bra	.D
.E	bsr	pr_lf
	lea	help_tx2(pc),a1
	bsr	pr_string
	lea	help_tx3(pc),a1
	bsr	pr_stringlf
	moveq	#RETURN_OK,D0
	rts

* print out part of manual, d7 points to topic
help_man lea	manadr(pc),a2	global variable
	move.l	4(a2),d1
	move.l	(a2),d0
	bne.s	.A
	lea	helpman(pc),a0
	bsr	readfile	load manual
	move.l	d0,(a2)		manadr
	move.l	d1,4(a2)	mansize
.A	move.l	d0,a3
	move.l	d1,d5
	add.l	a3,d5
	move.l	a3,a2
	move.l	d7,a1		type all ?
	cmp.b	#"?",(a1)
	beq	make_screen	type all !
.B	move.l	d7,a1
	move.l	d5,a0
	addq.l	#1,a2
	bsr	searchSTR	search topic in manual
	cmp.b	#10,d0
	bne.s	.C
	cmp.b	#"-",-2(a2)	there must be a lot of "-" before topic
	bne.s	.B
	cmp.b	#"-",-3(a2)
	bne.s	.B
	move.l	a1,d4
.E	bsr	check_c		ctrl-c ?
	bne.s	.C
.D	cmp.l	d5,a1
	bhi.s	.C
	cmp.b	#10,(a1)+	print lines separately
	bne.s	.D
	move.l	d4,d2
	move.l	a1,d3
	sub.l	d2,d3
	move.l	a1,d4
	move.l	outhandle(a5),d1
	jsr	_LVOWrite(a6)
	move.l	d4,a1
	cmp.b	#"-",-2(a1)	search next lot of "-"
	bne.s	.E
	cmp.b	#"-",-3(a1)
	bne.s	.E
	bra.s	.B		another fitting topic ?
.C	moveq	#RETURN_OK,D0
	rts

giveman	movem.l	d0/d1/a0/a1,-(sp)	free manual-memory
	lea	manadr(pc),a0
	tst.l	(a0)
	beq.s	.A
	move.l	(a0),a1
	clr.l	(a0)
	move.l	4(a0),d0
	bsr	givemem
.A	movem.l	(sp)+,d0/d1/a0/a1
	rts


* PRINT A STRING BUT PUT A LINEFEED AFTER IT
pr_stringlf	bsr pr_string
		bra pr_lf

showpath	bsr	rawh_off
	lea	pcurrent(pc),a1
	bsr	pr_stringlf
	lea	patharea(a5),a1
sh_p3	tst.b	(a1)
	beq.s	sh_p1
	move.l	a1,d4
	bsr	pr_stringlf
	move.l	d4,a1
sh_p2	tst.b	(a1)+
	bne.s	sh_p2
	bra.s	sh_p3
sh_p1	moveq	#RETURN_OK,d0
	bra	pr_lf

*****************	
*	PATH	* 	Assign path or show it.
*****************
pathz	tst.l	parm2(a5)	see whether any parameters
	beq.s	showpath
	move.l	parm2(a5),a0
	bsr	return_dash_option
	lea	parm2(a5),a0
	lea	patharea(a5),a1
	cmp.b	#'C',d0
	bne.s	pc_jo
	clr.w	(a1)
	tst.l	(a0)+		dummy bump
	bra.s	pc_x2
pc_jo	tst.b	(a1)+
	bne.s	pc_jo
	tst.b	(a1)		test if 2 nulls
	bne.s	pc_jo
pc_x2	move.l	(a0),a2		go through each additional parameter
	tst.l	(a0)+
	beq.s	pc_x3
	
pc_x1	move.b	(a2)+,(a1)+
	bne.s	pc_x1
	bra.s	pc_x2
pc_x3	clr.b	(a1)
	moveq	#RETURN_OK,d0
	rts


*****************
*	INFO	*
*****************
infoz	bsr	rawh_off		;V2.0 (fully new)
	lea	inform_tx(pc),a1
	bsr	pr_stringlf
	move.l	$22(a6),a0	;rootnode
	move.l	$18(a0),a0	;dosinfo
	add.l	a0,a0
	add.l	a0,a0
	move.l	4(a0),d6	;devicelist
jajo	tst.l	d6
	bne	.B
	moveq	#RETURN_OK,d0
	rts

.B	lsl.l	#2,d6	;BPTR
	move.l	d6,a4
	move.l	(a4),d6		;next
	tst.l	4(a4)		;type
	bne.s	jajo	;was volume or assign
	tst.l	8(a4)		;task
	beq.s	jajo	;was non-disk-device
didev	move.l	$28(a4),a0	;name
	add.l	a0,a0
	add.l	a0,a0
	moveq	#0,d0
	move.b	(a0)+,d0
	lea	tempbuf(a5),a3
	move.l	a3,a2
	bra.s	.D
.C	move.b	(a0)+,(a2)+
.D	dbra	d0,.C
	move.b	#":",(a2)+
	clr.b	(a2)
	bsr	clearArgs
	move.l	8(a4),packettask(a5)	;aptr task
	moveq	#ACTION_DISK_INFO,d0
	move.l	d0,packettype(a5)
	move.l	a5,d0
	lsr.l	#2,d0
	move.l	d0,myArg1(a5)	;use FIB as INFO (bptr)
	bsr	sendpacket
	bsr	PKTerr
	bsr	do_forbid
	move.l	id_DiskType(a5),d0
	move.l	d0,d1
	clr.b	d1
	cmp.l	#"DOS"<<8,d1
	beq.s	itsDos		;DOS-Disk
	lea	nodisk(pc),a0
	moveq	#-1,d1
	cmp.l	d1,d0
	beq.s	.F
	lea	baddisk(pc),a0
	cmp.l	#"BAD"<<8,d0
	beq.s	.F
	lea	nodos(pc),a0
	cmp.l	#"NDOS",d0
	beq.s	.F
	lea	kickdisk(pc),a0
	cmp.l	#"KICK",d0
	beq.s	.F
	lea	statun(pc),a0
.F	move.l	a0,-(sp)
	move.l	id_UnitNumber(a5),-(sp)
	move.l	a3,-(sp)
	bsr	do_permit
	lea	(sp),a1
	lea	inform2(pc),a0
	bsr	new_print
	lea	12(sp),sp
	bra	jajo

itsDos	move.l	id_VolumeNode(a5),a0	;DOS-Disk
	add.l	a0,a0
	add.l	a0,a0
	move.l	$28(a0),a0		;name	(hope, it is NULL-ending)
	add.l	a0,a0
	add.l	a0,a0
	addq.l	#1,a0
	move.l	a0,-(sp)
	move.l	id_NumSoftErrors(a5),-(sp)	;SoftErrors
	move.l	id_DiskState(a5),d0
	lea	statro(pc),a0
	moveq	#80,d1
	cmp.l	d1,d0
	beq.s	.H
	lea	statrw(pc),a0
	moveq	#82,d1
	cmp.l	d1,d0
	beq.s	.H
	lea	statval(pc),a0
	moveq	#81,d1
	cmp.l	d1,d0
	beq.s	.H
	lea	statun(pc),a0
.H	move.l	a0,-(sp)		;Status
	move.l	id_BytesPerBlock(a5),d1
	move.l	d1,-(sp)		;BlockSize
	move.l	id_NumBlocks(a5),d0
	bsr	mult_32x32
	lsr.l	#8,d0
	lsr.l	#2,d0
	move.l	d0,d2
	move.l	id_NumBlocksUsed(a5),d0
	bsr	mult_32x32
	lsr.l	#8,d0
	lsr.l	#2,d0
	move.l	d2,d3
	sub.l	d0,d3
	moveq	#100,d1
	bsr	mult_32x32
	move.l	d2,d1
	beq.s	.D
	bsr	div_32	;%
.D	exg	d0,d2
	move.l	d3,d1
	movem.l	d0-d2,-(sp)		;Sizes
	lea	msd_tx(pc),a0	messydos ?
	move.l	$1c(a4),d0	dn_Startup
	moveq	#2,d1
	cmp.l	d1,d0
	bls.s	.A
	lsl.l	#2,d0
	move.l	d0,a1
	move.l	8(a1),d0	fssm_Environ
	beq.s	.A
	lsl.l	#2,d0
	move.l	d0,a1
	move.l	64(a1),d0	de_DosType
	cmp.l	#"MSD"<<8,d0	CrossDos ?
	beq.s	.C
.A	move.l	id_DiskType(a5),d0
	lea	quest_tx(pc),a0
	cmp.b	#5,d0
	bhi.s	.C	unknown
	ext.w	d0
	ext.l	d0
	lea	ofs_tx(pc),a0
	lsl.l	#2,d0
	add.l	d0,a0	d0*4+a0	access table
.C	move.l	a0,-(sp)		;System
	move.l	id_UnitNumber(a5),-(sp)	;Unit
	move.l	a3,-(sp)		;Name
	bsr	do_permit
	lea	(sp),a1
	lea	inform(pc),a0
	bsr	new_print
	lea	40(sp),sp
	bra	jajo



*****************
*	ENDCLI	*	EXIT FROM ZSHELL TO CLI.
*****************	IF WE EXIT FROM SCRIPT THEN FREE SCRIPT MEMORY
endcliz	bsr	raw_off
	move.l	parm2(a5),a0
	bsr	return_dash_option
	moveq	#-1,d7
	cmp.b	#'C',d0
	bne.s	.A
	moveq	#0,d7
.A	tst.b	scflag(a5)
	beq.s	byebye
	bsr	kill_script
byebye	move.l	(sp)+,d0	;kill return address on stack
	rts

** SPLIT STRING(A0) INTO DIRECTORY PATH AND WILDCARD DESCRIPTION
** NULL END THE PATH, AND MOVE THE WILDCARD TO (A1)
* eg. ram:c/*.info -> ram:c0 + *.info0
	
split_wild
	movem.l	d0-d1/a0-a2,-(sp)
	move.l	a0,d1
sp_w2	move.l	a0,a2	a2=temp
sp_w3	move.b	(a0)+,d0
	beq.s	sp_w4
	cmp.b	#':',d0
	beq.s	sp_w2	A0= 1 after :
	cmp.b	#'/',d0
	beq.s	sp_w2
	bra.s	sp_w3
sp_w4	cmp.l	a2,d1
	beq.s	sp_mis
	cmp.b	#':',-1(a2)
	bne.s	sp_w5
sp_mis	move.l	a2,d1	SAVE POSITION
sp_w6	move.b	(a2)+,(a1)+
	bne.s	sp_w6
	move.l	d1,a2
	clr.b	(a2)
	movem.l	(sp)+,d0-d1/a0-a2
	rts
sp_w5	clr.b	-1(a2)
sp_w7	move.b	(a2)+,(a1)+
	bne.s	sp_w7
	movem.l	(sp)+,d0-d1/a0-a2
	rts
	
** CHECK STRING(A0) IF IT CONTAINS WILDCARD SPECIFIC CHARS
** RETURN D0=0 IF WILDS FOUND
check_wild
	move.l	a0,-(sp)
chk_w3	move.b	(a0)+,d0
	beq.s	chk_w2
	cmp.b	#'*',d0
	beq.s	chk_w4
	cmp.b	#'~',d0	special not char
	beq.s	chk_w4
	cmp.b	#'[',d0
	beq.s	chk_w4
	cmp.b	#']',d0
	beq.s	chk_w4
	cmp.b	#'|',d0 or char
	beq.s	chk_w4
	cmp.b	#'?',d0
	bne.s	chk_w3
chk_w4	moveq	#0,d0
	move.l	(sp)+,a0
	rts
chk_w2	moveq	#1,d0
	move.l	(sp)+,a0
	rts

* NOTE this wildmatcher only handles cases where the wildcard has one * in it.
** WILDCARD MATCHER. CHECK IF STRING(A0) MATCHES WILDCARD(A1)
** RETURN D0=0 IF MATCH
wildmatch movem.l	d2/a2-a3,-(sp)
	move.b	(a1),d2
	cmp.b	#"~",d2		;check if all is negated
	bne.s	.C
	addq.l	#1,a1
.C	move.l	a1,a2
	move.l	a0,a3
.A	move.b	(a2)+,d0
	beq.s	.B
	cmp.b	#"|",d0		;or-symbol  V2.0
	bne.s	.A
	move.b	#0,-1(a2)	;change wildcard to end
	bsr.s	wildermatch
	move.b	#"|",-1(a2)	;restore
	tst.l	d0
	beq.s	gut
	lea	(a3),a0
	lea	(a2),a1
	bra.s	.A
.B	bsr.s	wildermatch
gut	cmp.b	#"~",d2
	bne.s	.D
	subq.l	#1,d0
.D	movem.l	(sp)+,d2/a2-a3
	rts

wildermatch
	cmp.b	#'~',(a1)		check for NOT specifier
	bne.s	wm_1
	move.b	(a1)+,d0
	bsr.s	wm_1
	subq.l	#1,d0	0 --> -1     1 --> 0
	rts
	
wm_1	move.b	(a0)+,d0
	beq	source_fin1
	move.b	(a1)+,d1
	cmp.b	#'*',d1
	beq.s	wild_run
	cmp.b	#'[',d1		handle character classes
	bne.s	.A
.B	move.b	(a1)+,d1
	beq.s	wild_fail
	cmp.b	#']',d1
	beq.s	wild_fail
	bsr	compD1D0nocase
	bne.s	.B
.C	move.b	(a1)+,d1
	beq.s	wild_fail
	cmp.b	#']',d1
	bne.s	.C
	bra.s	wm_1
.A	cmp.b	#'?',d1
	beq.s	wm_1
	bsr	compD1D0nocase
	beq.s	wm_1
	
wild_fail	moveq	#1,d0
	rts
wild_run	
wr_3	tst.b	(a0)+	GOTO END OF STRING
	bne.s	wr_3
wr_4	tst.b	(a1)+	GOTO END OF WILDCARD
	bne.s	wr_4
wr_5	move.b	-(a1),d0	get tail of wildcard (1st should be null)
	move.b	-(a0),d1
	cmp.b	#'*',d0
	beq.s	source_fin2
	cmp.b	#']',d0		handle class [xyz]
	bne.s	.A
.B	move.b	-(a1),d0
	cmp.b	#'*',d0
	beq.s	wild_fail
	cmp.b	#'[',d0
	beq.s	wild_fail
	bsr	compD1D0nocase
	bne.s	.B
.C	move.b	-(a1),d0
	beq.s	wild_fail	should never happen but should leave in
	cmp.b	#'[',d0
	bne.s	.C
	bra.s	wr_5
.A	cmp.b	#'?',d0
	beq.s	wr_5
	bsr	compD1D0nocase
	beq.s	wr_5
	bra.s	wild_fail
source_fin1
	tst.b	(a1)
	beq.s	source_fin2
	cmp.b	#'*',(a1)
	bne.s	wild_fail
source_fin2
	moveq	#0,d0
	rts

compD1D0nocase ;lowercase d0 and d1 then compare them
	cmp.b	#'Z',d1
	bhi.s	D1_OK
	cmp.b	#'A',d1
	blo.s	D1_OK
	add.b	#$20,d1
D1_OK	cmp.b	#'Z',d0
	bhi.s	D0_OK
	cmp.b	#'A',d0
	blo.s	D0_OK
	add.b	#$20,d0
D0_OK	cmp.b	d1,d0
	rts
	
fibexnx	move.l	d7,d1
	move.l	a5,d2
	jsr	_LVOExNext(a6)
	rts

*************************
*	RECOPY		*
*************************
rcsize	equ	50000		V2.0
recopyz	move.l	parm2(a5),a0		;RECOPY DIR
	bsr	check_recurs
	tst.b	recurs_flag(a5)		;RECURS-option ?
	beq	.A
	move.l	parm3(a5),parm2(a5)
	move.l	parm4(a5),parm3(a5)
.A	moveq	#0,d0
	bset.l	#29,d0		;bit 29=recopy flag
	move.l	d0,temp2(a5)
	move.l	#rcsize,d0	;50KB copy buffer
	moveq	#1,d1
	bsr	iwantmem
	move.l	d0,temp4(a5)
	beq.s	rece
	lea	date_mark(a5),a0
	bsr	get_time
	move.l	a0,a1
	lea	-14(sp),sp
	lea	(sp),a0
	bsr	convert_time
	lea	(sp),a1
	lea	time_text(pc),a0
	bsr	new_print
	lea	14(sp),sp
	bsr	directory 		;call it
	move.l	temp4(a5),a1
	move.l	#rcsize,d0
	bsr	givemem
rece	rts

*********************************
*	DIRECTORY LISTER	*
*********************************
dirz	clr.b	recurs_flag(a5)		;WIDE DIR
	moveq	#1,d0
	bset.l	#31,d0		;bit 31=wide flag
	move.l	d0,temp2(a5)
	bra.s	directory
	
listz	move.l	parm2(a5),a0		;NARROW DIR
	bsr	check_recurs
	tst.b	recurs_flag(a5)		;RECURS-option ?
	beq	.A
	move.l	parm3(a5),parm2(a5)
	move.l	parm4(a5),parm3(a5)
.A	clr.l	temp2(a5)			;clear wide flag
;DON'T PUT ANYTHING HERE
*PRINT DIRECTORY A0-> name of directory
directory		;V2.0:many things better (sort!)
	bset.l	#30,temp2(a5)
	btst.l	#29,temp2(a5)	;no quick recopy (will GURU !)
	bne.s	.B
	move.l	parm2(a5),a0
	bsr	return_dash_option
	cmp.b	#"Q",d0			;QUICK-option ?
	bne.s	.B
	bclr.l	#30,temp2(a5)	;bit 30=quick flag
	move.l	parm3(a5),parm2(a5)
.B	bsr	fixpam2
	bsr	rawh_off		V0.15
	clr.l	temp1(a5)			;init total size
	clr.l	temp3(a5)
	clr.w	indent_count(a5)
	bsr	handle_wild_dirs
	move.l	a0,d1
	jsr	_LVODeviceProc(a6)
	tst.l	d0
	beq	DOSerr
	move.l	d0,devproc(a5)
	move.l	parm2(a5),a0
	lea	tempbuf(a5),a4
.C	move.b	(a0)+,(a4)+
	bne.s	.C
	bsr	pr_dir			;print the dir
pr_size	movem.l	d0-d2,-(sp)
	move.l	temp2(a5),d0		;are we printing wide
	bpl.s	.B
	btst.l	#0,d0
	bne.s	.B
	bsr	pr_lf
.B	lea	(sp),a1
	lea	totsize(pc),a0
	bsr	new_print
	lea	12(sp),sp
	moveq	#RETURN_OK,d0
	rts

fname	equ	40

pr_dir	sub.l	a3,a3	;clr a3
	lea	tempbuf(a5),a0
	bsr	fibexam
	tst.l	fib_DirEntryType(a5)	;check entry OK
	bpl.s	prd20			;Directory V1.05
	btst.l	#29,temp2(a5)
	bne.s	.A
	bsr	pr_it			;was a file
.A	bra	unlock			;make sure to unlock

prd20	tst.w	indent_count(a5)		;was a dir
	bne.s	prd2
	bsr	num_spc
	clr.b	(a2)
	lea	temp2buf(a5),a1
	bsr	pr_string
	lea	dirof(pc),a1
	bsr	pr_string
	lea	fib_FileName(a5),a1
	bsr	pr_stringlf		;print dircetory's name
prd2
	bsr	check_c
	bne	unlock
	bsr	fibexnx
	tst.l	d0
	beq	unlk		;sort ?
	move.l	fib_Protection(a5),d0
	btst	#7,d0
	beq.s	.B
	btst	#31,temp2(a5)
	bne.s	prd2	hide if hide flag is set in wide dir lister
.B	tst.b	wild_flag(a5)
	beq.s	dozel
	tst.b	recurs_flag(a5)
	beq.s	.A
	tst.l	fib_DirEntryType(a5)
	bpl.s	dozel
.A	lea	fib_FileName(a5),a0
	lea	wild_string(a5),a1
	bsr	wildmatch		;wildcheck
	tst.b	d0
	bne.s	prd2
dozel	btst.l	#30,temp2(a5)
	bne.s	collect
	bsr	zelma
	bra.s	prd2
collect moveq	#fname,d0		;collect files to sort  V2.0
	lea	fib_FileName(a5),a0
	lea	(a0),a2
.A	addq.l	#1,d0
	tst.b	(a0)+
	bne.s	.A
	lea	fib_Comment(a5),a0
.B	addq.l	#1,d0
	tst.b	(a0)+
	bne.s	.B
	moveq	#1,d1
	bsr	iwantmem
	beq	unlock
	move.l	d0,a0
	move.l	a3,(a0)+
	lea	-4(a0),a3
	lea	fib_DiskKey(a5),a1	;store fib in mem
	move.l	(a1)+,(a0)+
	move.l	(a1)+,(a0)+
	lea	fib_Protection(a5),a1
	moveq	#6,d1
.C	move.l	(a1)+,(a0)+
	dbra	d1,.C
.D	move.b	(a2)+,(a0)+	;name
	bne.s	.D
.E	move.b	(a1)+,(a0)+	;comment
	bne.s	.E
	bra	prd2

unlk	btst.l	#30,temp2(a5)
	beq	unlock
	move.l	a3,d0	
	beq	unlock	;no files

	movem.l	a4-a6,-(sp)
	lea	(a3),a0		;INSERTION SORT  V2.0   (ooohuuooo)
aussort	lea	(a3),a1
	move.l	(a0),a2	;remove (a0->) a2
	move.l	a2,d0
	beq.s	snull	;end of list
	move.l	(a2),(a0)
	bsr	strcmp	;compare a1 and a2
	bne.s	insort	;insert a2 (old place)
	move.l	a2,a3	;a2->start
	move.l	a1,(a2)	;a1=old start
	bra.s	aussort	;next
insort	move.l	a1,a4	;reminder
	move.l	(a1),a1	;next a1
	cmp.l	a0,a4
	beq.s	inold
shno	bsr	strcmp	;compare a1 and a2
	bne.s	insort	;go on
	move.l	a2,(a4)	;insert a2
	move.l	a1,(a2)	;a4->a2->a1
	bra.s	aussort
inold	move.l	(a0),(a2) ;a2 back at old place
	move.l	a2,(a0)	;a0->a2->next
	move.l	a2,a0	;next a0
	bra.s	aussort
snull	movem.l	(sp)+,a4-a6	;FINISHED !!!

	tst.l	temp2(a5)	
	bpl.s	nextfi
	moveq	#1,d0		prepare for printing in 2 columns
	move.l	a3,d1
.A	addq.l	#1,d0
	move.l	d1,a0
	move.l	(a0),d1
	bne.s	.A		count number of entries (d0)
	lsr.l	#1,d0		divide by two
	move.l	a3,a2
	bra.s	.B
.C	move.l	a2,a0
	move.l	(a2),a2
.B	dbra	d0,.C		find the middle	(a2 ,precedor in a0)
	clr.l	(a0)

nextfi	bsr	check_c	;print all files
	bne	unlock
	lea	4(a3),a1
	lea	fib_DiskKey(a5),a0	;restore fib from mem
	move.l	(a1)+,(a0)+
	move.l	(a1)+,(a0)+
	lea	fib_Protection(a5),a0
	moveq	#6,d1
.F	move.l	(a1)+,(a0)+
	dbra	d1,.F
	moveq	#fname,d0
	lea	fib_FileName(a5),a0
.H	addq.l	#1,d0
	move.b	(a1)+,(a0)+	;name
	bne.s	.H
	lea	fib_Comment(a5),a0
.B	addq.l	#1,d0
	move.b	(a1)+,(a0)+	;comment
	bne.s	.B
	movem.l	d0/a2/a3,-(sp)
	bsr	zelma
	movem.l	(sp)+,d0/a2/a3
	move.l	(a3),d2
	lea	(a3),a1
	bsr	givemem
	move.l	d2,a3
	tst.l	temp2(a5)
	bpl.s	.A
	move.l	a2,a0		swap lower and upper list
	move.l	a3,a2
	move.l	a0,a3
.A	move.l	a3,d0		tst.l	a3
	bne	nextfi

unlock	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	move.l	temp1(a5),d0	;total size
	move.l	temp2(a5),d1	;No. of files and dirs
	btst.l	#31,d1
	beq.s	.A
	subq.l	#1,d1
.A	and.l	#$00ffffff,d1	;16777215 files max. should be enough
	move.l	temp3(a5),d2	;No. of dirs
	sub.l	d2,d1
	rts

strcmp	move.l	8(a1),d0
	move.l	8(a2),d1
	cmp.l	d0,d1		;files prefered
	blo.s	donoth		;a2:file, a1:dir
	bhi.s	inseit		;a2:dir,  a1:file
	lea	fname(a1),a5
	lea	fname(a2),a6
stcmp	move.b	(a5)+,d1	;compare strings in a3 and a4
	beq.s	donoth
	move.b	(a6)+,d0
	beq.s	inseit
	bsr	compD1D0nocase
	beq.s	stcmp
	bhi.s	donoth
inseit	moveq	#0,d0		;insert it !
	rts
donoth	moveq	#1,d0		;do nothing !
	rts


zelma	bsr	pr_it			;print fib
	tst.l	fib_DirEntryType(a5)	;	   recursively
	bmi.s	.B
	tst.b	recurs_flag(a5)
	bne.s	.C
.B	rts
.C	moveq	#100,d0	;(24bytes per recurs + subs)
	bsr	stacktest
	bne	.B
;	lea	fib_Date(a5),a0		;save fib in stack
;	moveq	#2,d0
;.A	move.l	(a0)+,-(sp)
;	dbra	d0,.A
	move.l	fib_DiskKey(a5),d0
	movem.l	d0/d7/a4,-(sp)
	lea	fib_FileName(a5),a0
	lea	-1(a4),a4
	lea	tempbuf(a5),a1
	cmp.l	a1,a4
	beq.s	jo
	cmp.b	#":",-1(a4)
	beq.s	jo
	move.b	#"/",(a4)
	lea	1(a4),a4
jo	move.b	(a0)+,(a4)+		;addpath
	bne.s	jo
	addq.w	#2,indent_count(a5)
jojo	bsr	pr_dir			RECURSION    V2.0
	subq.w	#2,indent_count(a5)
	movem.l	(sp)+,d0/d7/a4
	move.l	d0,fib_DiskKey(a5)	;restore fib
	lea	-1(a4),a0
	cmp.b	#"/",(a0)
	bne.s	.D
	clr.b	(a0)
	lea	1(a0),a0
.D	lea	(a0),a2
	lea	fib_FileName(a5),a1
je	move.b	(a0)+,(a1)+
	bne.s	je
	clr.b	(a2)
	moveq	#2,d0
	move.l	d0,fib_DirEntryType(a5)
	move.l	d0,fib_EntryType(a5)
	moveq	#0,d0
	move.l	d0,fib_Size(a5)
	move.l	d0,fib_NumBlocks(a5)
;	lea	fib_Date+12(a5),a0
;	moveq	#2,d0
;.B	move.l	(sp)+,-(a0)
;	dbra	d0,.B
	rts

pr_it	bsr	num_spc			;print file or dir
	tst.l	fib_DirEntryType(a5)	;check whether is dir
	bmi.s	.A			;if plus,is directory
	lea	farb3(pc),a1		;change foregnd colour
	bsr	addstring
	addq.l	#1,temp3(a5)		;one dir more
.A	lea	fib_FileName(a5),a1
	move.l	a1,a0
	moveq	#-1,d2
	add.w	indent_count(a5),d2
.B	addq	#1,d2
	tst.b	(a0)+
	bne.s	.B
	bsr 	addstring		;print filename
	tst.l	fib_DirEntryType(a5)
	bpl.s	.C
	move.l	fib_Size(a5),d0
	add.l	d0,temp1(a5)		;increase total size
	move.b	#" ",(a2)+
	moveq	#34,d1
	sub.w	d2,d1
	bsr	qdecpr
	bra.s	.E
.C	moveq	#29,d1
	sub.w	d2,d1
	bpl.s	.D
	moveq	#0,d1
.D	move.b	#" ",(a2)+
	dbra	d1,.D
	lea	dirtext(pc),a1
	bsr	addstring
.E	move.b	#" ",(a2)+
	move.b	#0,(a2)
	addq.l	#1,temp2(a5)
	move.l	temp2(a5),d0		;are we printing wide
	bpl.s	wpro
	btst.l	#0,d0
	beq.s	.F
	move.b	#10,(a2)+
	clr.b	(a2)
	lea	temp2buf(a5),a1
	bra	pr_string		;print string&return and return
.F	move.b	#" ",(a2)+
	move.b	#" ",(a2)+
	move.b	#" ",(a2)+
	clr.b	(a2)
	lea	temp2buf(a5),a1
	bra	pr_string		;send tab and return

wpro	lea	temp2buf(a5),a1
	bsr	pr_string
	bsr	pr_prot			print protection V2.0
	lea	fib_Date(a5),a1		(goes to temp2buf)
	lea	-14(sp),sp
	lea	(sp),a0
	bsr	convert_time
	lea	temp2buf(a5),a1
	addq.l	#8,a1			protect uses 8 bytes
	move.b	#" ",(a1)+
	bsr	qprint10
	move.b	#".",(a1)+
	bsr	qprint10
	move.b	#".",(a1)+
	bsr	qprint10
	move.b	#" ",(a1)+
	move.b	#" ",(a1)+
	bsr	qprint10
	move.b	#":",(a1)+
	bsr	qprint10
	move.b	#":",(a1)+
	bsr	qprint10
	clr.b	(a1)
	lea	14(sp),sp
	lea	temp2buf(a5),a1
	bsr	pr_string		;print date/time V2.0

	btst.l	#29,temp2(a5)
	beq	fort2		;recopy flag not set
	tst.l	fib_DirEntryType(a5)
	bpl	fort2		;don't recopy dirs
hardo	movem.l	d4-d7/a2-a4,-(sp)	;DO RECOPY V2.0
	move.l	d7,dirlock(a5)
	move.l	d7,d1
	jsr	_LVOCurrentDir(a6)	;set current path
	move.l	d0,d7
	lea	fib_FileName(a5),a2
	lea	temp2buf(a5),a3
	moveq	#0,d6
	move.l	a2,a0
	move.l	a3,a1
.A	move.b	(a0)+,(a1)+
	bne.s	.A
	lea	-1(a1),a1
	lea	append(pc),a0
.B	move.b	(a0)+,(a1)+
	bne.s	.B
	move.l	a2,d1
dbrc	move.l	#MODE_OLDFILE,d2
	jsr	_LVOOpen(a6)	;open fib file
	move.l	d0,d4
	beq	perr1		;access_write lock ?
	move.l	a3,d1
	move.l	#MODE_NEWFILE,d2
	jsr	_LVOOpen(a6)	;open new file (*.rcy)
	move.l	d0,d5
	beq	perr3		;disk full ?
doreco	move.l	d4,d1
	move.l	temp4(a5),d2
	move.l	#rcsize,d3
	jsr	_LVORead(a6)
	move.l	d0,d3
	bmi	perr3		;read error ?
	beq.s	recoend
	move.l	d3,-(sp)
	move.l	d5,d1
	move.l	temp4(a5),d2
	jsr	_LVOWrite(a6)
	move.l	(sp)+,d3
	tst.l	d0
	bmi	perr3		;disk full ?
	cmp.l	d0,d3
	bne	perr3		;disk full
	add.l	d0,d6
	bra.s	doreco
recoend	bsr	closett
	move.l	a2,d1
	moveq	#$0,d2
	jsr	_LVOSetProtection(a6)
	tst.l	d0
	beq	perr1
	move.l	a2,d1
	jsr	_LVODeleteFile(a6)	;delete fib file
	tst.l	d0
	beq	perr1		;is there a lock on it ?
	move.l	a3,d1
	move.l	a2,d2
	jsr	_LVORename(a6)
	tst.l	d0
	beq	perr1		;?
	move.l	a2,d1
	move.l	fib_Protection(a5),d2
	jsr	_LVOSetProtection(a6)	;set old protection
	tst.l	d0
	beq	perr1
	move.l	a2,d1
	lea	fib_Comment(a5),a0	;copy comment
	move.l	a0,d2
	jsr	_LVOSetComment(a6)
	tst.l	d0
	beq	perr1
	bsr	clearArgs		;set old date
	lea	fib_Date(a5),a0
	move.l	a0,myArg4(a5)
	move.l	devproc(a5),packettask(a5)
	move.l	dirlock(a5),myArg2(a5)
	lea	temp2buf(a5),a1
	move.l	a1,d2
	lsr.l	#2,d2
	move.l	d2,myArg3(a5)
	addq.l	#1,a1
	moveq	#-1,d0
.B	addq.l	#1,d0
	move.b	(a2)+,(a1)+
	bne.s	.B
	move.b	d0,temp2buf(a5)
	moveq	#ACTION_SET_DATE,d0
	move.l	d0,packettype(A5)
	bsr	sendpacket
	tst.l	sp_res1(a5)
	beq	perr1
	move.l	d7,d1
	jsr	_LVOCurrentDir(a6)	;reset path
	cmp.l	fib_Size(a5),d6
	beq.s	sizok
	lea	errsiz(pc),a1	;wrong size
	bsr	pr_string
	move.l	d6,d0
	bsr	print10
	bra.s	nsizeok
sizok	lea	prok(pc),a1	;all OK
	bsr	pr_string
nsizeok	movem.l	(sp)+,d4-d7/a2-a4

fort2	bsr	pr_lf	;hello again !
	tst.b	fib_Comment(a5)
	beq.s	fort
	bsr	num_spc
	lea	farb2(pc),a1
	bsr	pr_string
	lea	fib_Comment(a5),a1	;print Comment V2.0
	bsr	pr_string
	lea	farb1(pc),a1
	bsr	pr_stringlf
fort	rts

perr3	bsr	closett
perr1	jsr	_LVOIoErr(a6)
	move.l	d0,-(sp)
	lea	errnum(pc),a1	;errornumber
	bsr	pr_string
	move.l	(sp)+,d0
	bsr	print10
perr2	move.l	d7,d1
	jsr	_LVOCurrentDir(a6)	;reset path
	movem.l	(sp)+,d4-d7/a2-a4
	bra.s	fort2

closett	move.l	d4,d1	;close files in d4 & d5
	beq.s	.A
	jsr	_LVOClose(a6)
.A	move.l	d5,d1
	beq.s	.B
	jsr	_LVOClose(a6)
.B	rts

qprint10 move.w	(a0)+,d0	V2.0
qpr10	ext.l	d0	(also used by more)
	divu	#10,d0	Value in d0 , Buffer in a1
	add.b	#"0",d0
	move.b	d0,(a1)+
	swap	d0
	add.b	#"0",d0
	move.b	d0,(a1)+
	rts

num_spc	lea	temp2buf(a5),a2		V2.0
	move.w	indent_count(a5),d0
	moveq	#$3f,d1
	and.l	d1,d0
	bra.s	.B
.A	move.b	#" ",(a2)+	the preceding spaces
.B	dbra	d0,.A
;	move.b	#0,(a2)
;	lea	temp2buf(a5),a1
;	bsr	pr_string	;print some spaces (fast)
	rts

addstring move.b (a1)+,(a2)+
	bne.s	addstring
	subq.l	#1,a2
	rts

qdecpr	* Number in d0.l , Length in d1.w , adds string to buffer in a2
	movem.l	d2/d3/a0,-(sp)	;Prints Decimal Number in (a2)
	lea	-12(sp),sp
	move.l	sp,a0
	move.l	d1,d3
	moveq	#0,d2
.A	moveq	#10,d1
	bsr	div_32
	add.b	#$30,d1
	move.b	d1,(a0)+
	addq.w	#1,d2
	tst.l	d0
	bne.s	.A
	sub.w	d2,d3
	subq.w	#1,d3
	bmi.s	.B
.D	move.b	#" ",(a2)+
	dbra	d3,.D
.B	subq.w	#1,d2
.C	move.b	-(a0),(a2)+
	dbra	d2,.C
	lea	12(sp),sp
	movem.l	(sp)+,d2/d3/a0
	rts



*** CHECK CTRL_C
** RETURN NE if ctrl c, EQ if not
check_c	movem.l	d0-d1/a0-a1/a6,-(sp)	checks if CTRL_C pressed
	moveq	#0,d0
	moveq	#0,d1
	move.l	4.w,a6
	bset	#SIGBREAKB_CTRL_C,d1
	jsr	_LVOSetSignal(a6)
	btst	#SIGBREAKB_CTRL_C,d0
	beq.s	ck_nostop
;	moveq	#0,d0
;	moveq	#0,d1
;	bset	#SIGBREAKB_CTRL_C,d1
;	jsr	_LVOSetSignal(a6)
	move.l	dosbase(a5),a6
	lea	breaktx(pc),a0
	bsr	new_print
	moveq	#1,d0			NE: STOP!!!
	move.b	d0,ctrl_c_flag(a5)
	movem.l	(sp)+,d0-d1/a0-a1/a6
	rts
ck_nostop
	clr.b	ctrl_c_flag(a5)
	moveq	#0,d0			EQ: no stop
	movem.l	(sp)+,d0-d1/a0-a1/a6
	rts


*ALLOCATE MEMORY D0=size D1=type
iwantmem	movem.l d1/a0-a1,-(sp)
	move.l 4.w,a6
	jsr _LVOAllocMem(a6)
	move.l dosbase(a5),a6
	movem.l (sp)+,d1/a0-a1
	tst.l	d0
	rts
*FREEMEM A1=ptr to mem block D0=size
givemem	move.l 4.w,a6
	jsr _LVOFreeMem(a6)
	move.l dosbase(a5),a6
	rts
	

*REMOVE PATH A0-> source A1->destination
rempath	movem.l d0/a0-a2,-(sp)
rempath1	move.l a0,a2
rempath2	move.b (a0)+,d0
	cmp.b #'/',d0
	beq.s rempath1
	cmp.b #':',d0
	beq.s rempath1
	tst.b d0
	bne.s rempath2
	move.l a2,a0
	bsr cp_string
	movem.l (sp)+,d0/a0-a2
	rts


** PRINT STRING (A1) USING indent_count(a5) AS A SPACE INDENT COUNT
prindent	movem.l	d7/a0-a1,-(sp)
	move.w	indent_count(a5),d7
	move.l	a1,a0
	and.w	#$3f,d7
	beq.s	.A
	bra.s	.B
.C	bsr	pr_space	print d7 spaces
.B	dbra	d7,.C
	move.l	a0,a1
.A	bsr	pr_string
	movem.l	(sp)+,d7/a0-a1
	rts

** ENTRY A0 pts to parameter.
** EXIT D0=lower case char after dash OR 0 if no dash command.
return_dash_option
	moveq	#0,d0
	cmp.b	#'-',(a0)
	bne.s	.B
.A	move.b	1(a0),d0
	cmp.b	#'a',d0
	blo.s	.B
	cmp.b	#'z',d0
	bhi.s	.B
	sub.b	#$20,d0
.B	rts

** ENTRY A0 pts to parameter. If it is -r then set "recurs_flag, otherwise clr it
check_recurs
	move.l	d0,-(sp)
	clr.b	recurs_flag(a5)
	bsr	return_dash_option
	cmp.b	#'R',d0
	bne.s	.A
	move.b	#1,recurs_flag(a5)
.A	move.l	(sp)+,d0
	rts

*********************************
*	THE COPY COMMAND	*
*********************************
** V1.23 major alterations to allow recursive file copying
copyz	lea	parm2(a5),a2
	tst.l	4(a2)		check if only 2 parameters
	beq	too_less_args
	move.l	(a2),a0
	bsr	check_recurs
	tst.b	recurs_flag(a5)
	beq.s	.A
	move.l	(a2)+,d0		bump the pointer
.A	tst.l	8(a2)		CHECK PARM4 IF DOING MULTIPLE FILE COPY
	beq.s	.B
.D	move.l	(a2)+,a3		multiple files to directory copy
	lea	-4(a2),a1
.C	move.l	(a1)+,d0		search for end
	bne.s	.C
	move.l	-8(a1),a4		grab dest directory
	cmp.l	a4,a3
	beq	copy_fin
	move.l	a2,-(sp)
	bsr.s	.E		do one copy
	move.l	(sp)+,a2
	tst.l	d0
	bne.s	copy_fail
	bra.s	.D
	
.B	move.l	(a2)+,a3		SOURCE
	move.l	(a2),a4		DEST
.E	move.l	a4,d1
	jsr	_LVODeviceProc(a6)
	tst.l	d0
	beq	DOSerr
	move.l	d0,devproc(a5)
	moveq	#0,d6
	clr.w	indent_count(a5)
	bsr	perform_copy
	tst.l	d6
	bne.s	copy_fail
copy_fin	moveq	#RETURN_OK,D0
	rts
copy_fail	moveq	#RETURN_ERROR,D0
	rts

***  SUPPLEMENTARY COPY ROUTINES ***
** ENTRY A2=fib, RETURN D0=address
alloc_file_space
	move.l	fib_Size(a2),d0
	move.l	d0,4+cp_filesize(sp)
	moveq	#1,d1
	bsr	iwantmem		ALLOCATE SPACE FOR FILE
	move.l	d0,4+cp_fileaddr(sp)	save 0 if failure
	rts
	
** ENTRY D1=name, RETURN D0=handle
open_read_file
	move.l	#MODE_OLDFILE,d2
	jsr	_LVOOpen(a6)	OPEN FILE
	move.l	d0,4+cp_ropen(sp)	save the handle
	rts

**ENTRY D0=handle
read_to_mem
	move.l	d0,d1
	move.l	4+cp_fileaddr(sp),d2
	move.l	4+cp_filesize(sp),d3
	jsr	_LVORead(a6)	READ FILE returns -1 if error
	rts

close_read_file
	move.l	4+cp_ropen(sp),d1
	jsr	_LVOClose(a6)	CLOSE FILE
	clr.l	4+cp_ropen(sp)		null it incase later dos errs
	rts

**ENTRY D1=name, RETURN D0=handle
open_write_file
	move.l	#MODE_NEWFILE,d2
	jsr	_LVOOpen(a6)	OPEN FILE
	move.l	d0,4+cp_wopen(sp)	save the handle
	rts

**ENTRY D0=handle
write_from_mem
	move.l	d0,d1
	move.l	4+cp_fileaddr(sp),d2
	move.l	4+cp_filesize(sp),d3
	jsr	_LVOWrite(a6)	WRITE FILE returns -1 if error
	rts

close_write_file
	move.l	4+cp_wopen(sp),d1
	jsr	_LVOClose(a6)	CLOSE FILE
	clr.l	4+cp_wopen(sp)
	rts

dealloc_file_space
	move.l	4+cp_fileaddr(sp),a1
	move.l	4+cp_filesize(sp),d0
	bsr	givemem		DEALLOCATE FILE SPACE
	clr.l	4+cp_fileaddr(sp)
	rts

;restorethings		;does not work
;	movem.l	a2-a3,-(sp)
;	lea	fib_FileName(a2),a3
;	move.l	a3,d1
;	move.l	fib_Protection(a2),d2
;	jsr	_LVOSetProtection(a6)	;set old protection
;	tst.l	d0
;	beq	cerr1
;	move.l	a3,d1
;	lea	fib_Comment(a2),a0	;copy comment
;	move.l	a0,d2
;	jsr	_LVOSetComment(a6)
;	tst.l	d0
;	beq	cerr1
;	bsr	clearArgs		;set old date
;	lea	fib_Date(a2),a0
;	move.l	a0,myArg4(a5)
;	move.l	devproc(a5),packettask(a5)
;	move.l	d7,myArg2(a5)
;	lea	temp2buf(a5),a1
;	move.l	a1,d2
;	lsr.l	#2,d2
;	move.l	d2,myArg3(a5)
;	addq.l	#1,a1
;	moveq	#-1,d0
;.B	addq.l	#1,d0
;	move.b	(a3)+,(a1)+
;	bne.s	.B
;	move.b	d0,temp2buf(a5)
;	moveq	#ACTION_SET_DATE,d0
;	move.l	d0,packettype(a5)
;	bsr	sendpacket
;	tst.l	sp_res1(a5)
;	beq	cerr1
;	movem.l	(sp)+,a2-a3
;	moveq	#0,d0
;	rts
;cerr1	movem.l	(sp)+,a2-a3
;	moveq	#-1,d0
;	rts

print_copyOK
	lea	copyOK(pc),a1
	bsr	pr_string		;print '...copied'
	rts
	
*STACK STUFF
cp_fibaddr	equ	0
cp_srclock	equ	cp_fibaddr+4
cp_fileaddr	equ	cp_srclock+4
cp_filesize	equ	cp_fileaddr+4
cp_ropen		equ	cp_filesize+4
cp_wopen		equ	cp_ropen+4
cp_fname		equ	cp_wopen+4	allow 128 bytes
	
cp_size		equ	cp_fname+128

** RECURSIVE STACK FRAME
nth_srcname	equ	0
nth_destname	equ	128
nth_size		equ	256
	
** ENTRY A3 = source   A4 = destination  D6=0 no errors yet, NE just exit
** indent_count(a5) is used
perform_copy
	tst.l	d6
	beq.s	.A	exit if D6<>0
	rts
.A	lea	-cp_size(sp),sp	ALLOCATE STACK SPACE
	move.l	sp,a0
	lea	cp_fname(sp),a1
.B	clr.b	(a0)+		clear all parameters on stack
	cmp.l	a1,a0
	blo.s	.B
	move.l	a3,a0
	bsr	handle_wild_dirs
	move.l	a3,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	move.l	d0,cp_srclock(sp)	store 0 if failure
	tst.l	d0
	beq	kill_copyDOS
* ALLOCATE FILEINFOBLOCK
	move.l	#FIB,D0
	moveq	#1,d1
	bsr	iwantmem
	move.l	d0,cp_fibaddr(sp)	store 0 if failure ,save fib addr
	beq	kill_copy
* EXAMINE SOURCE
	move.l	cp_srclock(sp),d1
	move.l	cp_fibaddr(sp),d2
	move.l	d2,a2		A2=fibaddr
	jsr	_LVOExamine(a6)	EXAMINE SOURCE
	tst.l	d0
	beq	kill_copyDOS
	lea	fib_FileName(a2),a1
*	bsr	pr_string
	tst.l	fib_DirEntryType(a2)
	bpl	next_dir_entry	if source is dir then attempt dir to dir

* HANDLE FILE TO FILE or FILE TO DIR
	move.l	a3,a1

	bsr	prindent		PRINT NAME OF FILE BEING COPIED
	move.l	cp_fibaddr(sp),a2	reset a2 to fibaddr
	bsr	alloc_file_space

	tst.l	d0
	beq	kill_copy
	move.l	a3,d1
	bsr	open_read_file

	tst.l	d0
	beq	kill_copyDOS
	bsr	read_to_mem

	tst.l	d0
	bmi	kill_copyDOS
	bsr	close_read_file
	
	move.l	a3,a0
	lea	cp_fname(sp),a1
	bsr	rempath		REMOVE PATH FROM SRC NAME
	move.l	a4,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)	LOCK DEST
	move.l	d0,d7
	beq	do_file_to_file
	move.l	d0,d1
	move.l	d0,d5		D5=lock temporary
	move.l	cp_fibaddr(sp),d2
	move.l	d2,a2		A2=fibaddr
	jsr	_LVOExamine(a6)	EXAMINE SOURCE  assume does not fail
	move.l	fib_DirEntryType(a2),d4
	move.l	d5,d1
	jsr	_LVOUnLock(a6)
	tst.l	d4
	bmi	do_file_to_file
	move.l	a4,a0		DO ONLY IF FILE TO DIR
	lea	cp_fname(sp),a1
	lea	fib_FileName(a2),a2	!!!! USING FIB AS TEMPORARY FOR NEW FNAME
	bsr	addpath
	move.l	a2,d1
	bra.s	go_open
do_file_to_file
	move.l	a4,d1		destination = new filename
go_open	bsr	open_write_file
	tst.l	d0
	beq	kill_copyDOS
	move.l	cp_fibaddr(sp),a2	reset a2 to fibaddr
	bsr	write_from_mem
	tst.l	d0
	bmi	kill_copyDOS
;	bsr	restorethings
;	bne	kill_copyDOS
	bsr	close_write_file
	bsr	dealloc_file_space
	bsr	print_copyOK
	bra	exit_cp

** MAIN LOOP FOR DIR TO DIR COPYING STARTS HERE
next_dir_entry
	bsr	check_c
	bne	kill_copy
	move.l	cp_srclock(sp),d1
	move.l	cp_fibaddr(sp),d2
	move.l	d2,a2		guarantee a2=fibaddr
	jsr	_LVOExNext(a6)	get next entry
	tst.l	d0
	beq.s	exit_cp
	
	tst.b	wild_flag(a5)
	beq	test_if_file
	lea	fib_FileName(a2),a0
	lea	wild_string(a5),a1
	bsr	wildmatch
	tst.b	d0
	bne.s	next_dir_entry
	bra	test_if_file

exit_cp	move.l	cp_srclock(sp),d1	if no more entries then exit
	jsr	_LVOUnLock(a6)
	move.l	cp_fibaddr(sp),a1
	move.l	#FIB,d0
	bsr	givemem
	lea	cp_size(sp),sp
	rts			EXIT BACK
test_if_file
	tst.l	fib_DirEntryType(a2)
	bpl	must_be_dir
	move.l	a3,a0		*** COPY A FILE ***
	lea	fib_FileName(a2),a1
	lea	cp_fname(sp),a2
	bsr	addpath		add src dir path to filename
	move.l	a2,a1
	bsr	prindent		PRINT NAME OF FILE BEING COPIED
	move.l	cp_fibaddr(sp),a2	reset a2 to fibaddr
	bsr	alloc_file_space

	tst.l	d0
	beq	kill_copy
	lea	cp_fname(sp),a0
	move.l	a0,d1
	bsr	open_read_file
	tst.l	d0
	beq	kill_copyDOS
	bsr	read_to_mem
	tst.l	d0
	bmi	kill_copyDOS
	bsr	close_read_file
	
	move.l	a4,a0		dest name
	lea	fib_FileName(a2),a1
	lea	cp_fname(sp),a2
	bsr	addpath		add dest dir path to filename
	
	move.l	a2,d1
	bsr	open_write_file

	tst.l	d0
	beq	kill_copyDOS
	move.l	cp_fibaddr(sp),a2	reset a2 to fibaddr
	bsr	write_from_mem

	tst.l	d0
	bmi	kill_copyDOS
	bsr	close_write_file
	bsr	dealloc_file_space
	bsr	print_copyOK
	BRA	next_dir_entry
must_be_dir
	tst.b	recurs_flag(a5)
	beq	next_dir_entry
	move.l	#520,d0	;(nth_size+cp_size+subs)
	bsr	stacktest
	bne	next_dir_entry
	lea	-nth_size(sp),sp
	move.l	a4,a0
	lea	fib_FileName(a2),a1
	lea	nth_destname(sp),a2	NEW DESTINATION DIRECTORY
	bsr	addpath		add dest dir path to filename
	
	move.l	a2,d1
	jsr	_LVOCreateDir(a6)	dont care if error is reported
	move.l	d0,d1			 (will be picked up later)
	beq.s	.A
	jsr	_LVOUnLock(a6)
.A	move.l	cp_fibaddr+nth_size(sp),a2
	move.l	a3,a0
	lea	fib_FileName(a2),a1
	lea	nth_srcname(sp),a2	NEW SOURCE DIRECTORY
	bsr	addpath
	move.l	a2,a1
	bsr	prindent		PRINT NAME OF NEW DIR
	bsr	pr_lf
	addq.w	#2,indent_count(a5)
	MOVEM.L	a3-a4,-(sp)	save old source and dest
	lea	8+nth_srcname(sp),a3
	lea	8+nth_destname(sp),a4
	bsr	perform_copy	RECURSION!!!!
	MOVEM.L	(SP)+,A3-A4
	lea	nth_size(sp),sp
	subq.w	#2,indent_count(a5)
	tst.l	d6
	bne	kill_copy
	bra	next_dir_entry

	
*** SAFELY HANDLE ERRORS
kill_copyDOS
	jsr	_LVOIoErr(a6)
	bsr	pr_DOSerr		print error
kill_copy	move.l	cp_fibaddr(sp),d0
	beq.s	.A
	move.l	d0,a1
	move.l	#FIB,d0
	bsr	givemem
.A	move.l	cp_srclock(sp),d1
	beq.s	.B
	jsr	_LVOUnLock(a6)
.B	move.l	cp_fileaddr(sp),d0
	beq.s	.C
	move.l	d0,a1
	move.l	cp_filesize(sp),d0
	bsr	givemem
.C	move.l	cp_ropen(sp),d1
	beq.s	.D	open return D0=0 if failure
	jsr	_LVOClose(a6)
.D	move.l	cp_wopen(sp),d1
	beq.s	.E
	jsr	_LVOClose(a6)
.E	MOVEQ	#1,D6		SET THE ERROR FLAG!!!!!
	lea	cp_size(sp),sp
	rts			EXIT BACK

***	END oF COPY	***


** ENTRY A0=name
** EXIT  D0=address, D1=size
readfile	movem.l	d2-d6/a0-a4,-(sp)
	move.l	a0,d1
	move.l	a0,a4
	move.l	#MODE_OLDFILE,d2
	jsr	_LVOOpen(a6)	OPEN FILE
	move.l	d0,d4	d4=handle
	bne.s	gotop
	moveq	#-1,d1		Don't request
	bsr	changeWindowPtr
	lea	patharea(a5),a0	CHECK PATH LIST  V2.0
rpa_3	tst.b	(a0)
	beq	readerr	CHECK IF PATH LIST IS EMPTY
	move.l	a0,d5
	move.l	a4,a1
	lea	tempbuf(a5),a2		;use temp buffer
	bsr	addpath
	bra.s	rpa_2
readpathfile		;entry:	a2=name with path (must exist)
	movem.l	d2-d6/a0-a4,-(sp)
rpa_2	move.l	a2,d1
	move.l	#MODE_OLDFILE,d2
	jsr	_LVOOpen(a6)
	move.l	d0,d4
	bne.s	gotop
	move.l	d5,a0
rpa_1	tst.b	(a0)+
	bne.s	rpa_1
	bra.s	rpa_3
gotop	moveq	#0,d1
	bsr	changeWindowPtr
	moveq	#1,d3
	moveq	#0,d2
	move.l	d4,d1
	jsr	_LVOSeek(a6)
	moveq	#-1,d3
	moveq	#0,d2
	move.l	d4,d1
	jsr	_LVOSeek(a6)
	move.l	d0,d5	d5=size	;handles also powerpacked files
	moveq	#1,d1
	bsr	iwantmem
	beq	readerr2
	move.l	d0,d6	d6=addr
	move.l	d6,d2
	move.l	d5,d3
	move.l	d4,d1
	jsr	_LVORead(a6)	READ IT
	tst.l	d0
	bmi	readerr3
	move.l	d4,d1
	jsr	_LVOClose(a6)
	move.l	d6,d0
	move.l	d5,d1
	movem.l	(sp)+,d2-d6/a0-a4
	rts
readerr3	move.l	d6,a1
	move.l	d5,d0
	bsr	givemem		;NB won't work correctly if memory fail occurs.
			 	;Will try to print DOS error for this
readerr2	move.l	d4,d1
	jsr	_LVOClose(a6)
readerr		moveq	#0,d1
	bsr	changeWindowPtr
	move.l	please_close_me(a5),d1	V1.29 Allows for additional
	beq.s	.A			file closure. Needed for
	jsr	_LVOClose(a6)		JOIN command
	clr.l	please_close_me(a5)
.A	bra	DOSerr

*****************
*	MORE	*
*****************
morez	tst.l	parm2(a5)
	beq	too_less_args
	move.w	line_count(a5),d4
	move.l	parm3(a5),d0
	beq	.C
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	tst.w	d0
	beq.s	.C
	subq.w	#1,d0
	move.w	d0,d4
.C	move.w	d4,line_count(a5)

	move.l	parm2(a5),a0
	bsr	readfile
	move.l	d0,-(sp)	push address
	move.l	d1,-(sp)	push size
	bsr	make_screen
	move.l	(sp)+,d0
	move.l	(sp)+,a1
	bsr	givemem
	moveq	#RETURN_OK,D0
	RTS

make_screen	* more main-routine, also used for help
	move.l	d0,d5	d5=start
	move.l	d0,a4	a4=ptr
	move.l	d0,a3
	move.l 	d0,d6
	add.l	d1,d6	d6=end addr
	lea	hide_cursor(pc),a1
	bsr	pr_string
mk_screen
	lea	clrtx(pc),a1
	bsr	pr_string
	move.w	line_count(a5),d1
	move.l	a4,-(sp)
	bra.s	.A
.C	bsr	pr_lf	PRINT SCREEN FULL OF LINES
.A	bsr	pr_line
.B	cmp.l	d6,a4	check against end
	beq.s	.E
	move.b	(a4)+,d0
	cmp.b	#10,d0
	bne.s	.B
	dbra	d1,.C
	move.l	a4,a3	A3 points to end of page marker
	
.E	move.l	a4,d7	D7 points to end
	move.l	(sp)+,a4	
waitabit	
	move.l	inhandle(a5),d1
	beq	cloga
	lea	tempbytes(a5),a0
	move.l	a0,d2
	moveq	#1,d3
	jsr	_LVORead(a6)		wait for space key
.A	moveq	#0,d0			clear top bytes
	move.b	tempbytes(a5),d0	test byte of input line
	cmp.b	#$9b,d0
	beq.s	waitabit		CSI ? Try again !
tastes	cmp.b	#'a',d0
;	blo.s	go_upper
;	sub.b	#$20,d0

go_upper	cmp.b	#$42,d0		cursor down ?
	bne.s	ck_up
	lea	scroll_up_tx(pc),a1	SCROLL UP ONE LINE,
	bsr	pr_string	SEND CURSOR TO START OF LINE
.B	cmp.l	d6,a4	advance one line
	beq.s	.C
	move.b	(a4)+,d0
	cmp.b	#10,d0
	bne.s	.B
.C	cmp.l	d6,a3	move a3 down one line too
	beq.s	.D
	move.b	(a3)+,d0
	cmp.b	#10,d0
	bne.s	.C
.D	move.l	a4,-(sp)
	move.l	d7,a4
	cmp.l	d7,d6
	beq.s	.A
	bsr	pr_line	print line from d7
.A	cmp.l	d6,a4	advance D7 one line
	beq.s	.E
	move.b	(a4)+,d0
	cmp.b	#10,d0
	bne.s	.A
.E	move.l	a4,d7
	move.l	(sp)+,a4
	bra	waitabit

ck_up	cmp.b	#$41,d0		V2.0	cursor up ?
	bne.s	ck_fwd
	lea	scroll_down_tx(pc),a1	SCROLL DOWN ONE LINE,
	bsr	pr_string	SEND CURSOR TO TOP LEFT
	cmp.l	d5,a4
	bls.s	.E
	subq.l	#1,a4
.B	cmp.l	d5,a4
	beq.s	.A
	cmp.b	#10,-(a4)
	bne.s	.B
	addq.l	#1,a4
.A	bsr	pr_line
.E	move.l	d7,a3
	cmp.l	d5,a3
	beq.s	.C
	subq.l	#1,a3
.D	cmp.l	d5,a3
	beq.s	.C
	cmp.b	#10,-(a3)
	bne.s	.D
	addq.l	#1,a3
.C	move.l	a3,d7
	lea	temp2buf(a5),a1
	move.b	#$9b,(a1)+
	move.w	line_count(a5),d0
	addq.w	#1,d0
	bsr	qpr10
	move.b	#"H",(a1)+
	clr.b	(a1)
	lea	temp2buf(a5),a1
	bsr	pr_string	CURSOR some lines down
	bra	waitabit

ck_fwd	cmp.b	#$53,d0			shift cursor down ?
	bne.s	ck_top
	move.l	a3,a4
	bra	mk_screen
ck_top	cmp.b	#$44,d0			cursor left ?
	bne.s	ck_bot
	move.l	d5,a4
	bra	mk_screen
ck_bot	cmp.b	#$43,d0			cursor right ?
	bne.s	ck_back
	move.l	d6,a4
	bra.s	look_back
ck_back	cmp.b	#$54,d0			shift cursor up ?
	bne.s	ck_skey
look_back
	move.w	line_count(a5),d1
	addq.w	#1,d1
.F	cmp.l	d5,a4	check against start
	beq.s	.E
	move.b	-(a4),d0
	cmp.b	#10,d0
	bne.s	.F
	dbra	d1,.F
	lea	1(a4),a4
.E	bra	mk_screen

ck_skey	cmp.b	#"s",d0		V2.0	search string ?
	bne.s	ck_pkey
	bsr	raw_off
	lea	msearch(pc),a1
	bsr	pr_string
	lea	tempbuf(a5),a2
	move.b	(a2),d4		save first char
	move.l	a2,d2
	moveq	#120,d3
	move.l	inhandle(a5),d1
	beq.s	.A
	jsr	_LVORead(a6)
	tst.l	d0
	bmi.s	.A
	move.l	a2,a1
	add.l	d0,a2
	subq.l	#1,a2
	move.b	d4,(a2)
	cmp.l	a1,a2		just pressed return ?
	beq.s	.B
	clr.b	(a2)	no
.B	move.l	d5,a3
	move.l	a4,a0
	bsr	find_end_of_line
	move.l	a0,a2
	move.l	d6,a0
	bsr	searchSTR
	cmp.b	#10,d0
	bne.s	.A
	move.l	a1,a4	set begin of line on top
	bra.s	.C
.A	move.l	intuibase(a5),a6
	suba.l	a0,a0
	jsr	_LVODisplayBeep(a6)
	move.l	dosbase(a5),a6
.C	bsr	raw_on
	lea	hide_cursor(pc),a1
	bsr	pr_string
	bra	mk_screen

ck_pkey	cmp.b	#"p",d0		V2.0	print text ?
	bne.s	unknown_key
	lea	prtdev(pc),a0
	move.l	a0,d1
	move.l	#MODE_OLDFILE,d2
	jsr	_LVOOpen(a6)
	move.l	d0,d4
	beq.s	.A
	lea	prtit(pc),a1
	bsr	pr_string
	move.l	d4,d1
	move.l	d5,d2
	move.l	d6,d3
	sub.l	d2,d3
	jsr	_LVOWrite(a6)
	move.l	d4,d1
	jsr	_LVOClose(a6)
.A	bra	mk_screen

unknown_key
	lea	show_cursor(pc),a1	unknown key to exit !
	bsr	pr_stringlf
	moveq	#RETURN_OK,d0
	rts

find_end_of_line
.B	cmp.l	d6,a0	check against end
	beq.s	.A
	move.b	(a0)+,d0
	cmp.b	#10,d0
	bne.s	.B
	lea	-1(a0),a0
.A	rts

** PRINT STRING AT A4 ENDING IN LF
pr_line	movem.l	d0-d3/a0,-(sp)
	move.l	a4,d2
	move.l	outhandle(a5),d1
	beq.s	.C
	move.l	a4,a0
	bsr	find_end_of_line
	sub.l	a4,a0
	move.l	a0,d3
	beq.s	.C	don't print if 0
	jsr	_LVOWrite(a6)
.C	movem.l	(sp)+,d0-d3/a0
	rts


** ENTRY D6=end of file A4=current pos
pr_screen	bsr	check_c
	bne	type_break
	bsr	pr_line
	bsr	pr_lf
.B	cmp.l	d6,a4	check against end
	bhs.s	type_break
	move.b	(a4)+,d0
	cmp.b	#10,d0
	bne.s	.B
	bra.s	pr_screen
type_break
	moveq	#RETURN_OK,D0
	rts

*****************
*	TYPE	*		Type out ASCII file command	
*****************
typez	tst.l	parm2(a5)
	beq	too_less_args
	move.l	parm2(a5),a0
	bsr	readfile
	bsr	rawh_off	MAKE SURE YOU CAN PRESS SPACE TO HOLD IT
	move.l	d0,-(sp)	push address
	move.l	d1,-(sp)	push size
	move.l	d0,a4	a4=ptr
	move.l 	d0,d6
	add.l	d1,d6	d6=end addr
next_scr	bsr	pr_screen
freef1	move.l	(sp)+,d0
	move.l	(sp)+,a1
	bsr	givemem
	moveq	#RETURN_OK,D0
	RTS

***********************
* EXECUTE SCRIPT FILE *
***********************
executez	tst.l	parm2(a5)
	beq	too_less_args
	bsr	fixpam2
xz2	bsr	readfile	A0 pts to filename
	move.l	d0,a0
	cmp.l	#$000003f3,(a0)	is it executable ?
	beq.s	exerr
	addq.l	#4,sp		kill return address
xz3	move.l	d0,a0
	cmp.w	#"/*",(a0)
	beq.s	xrexx
	move.l	d1,scsize(a5)
	move.l	d0,scaddr(a5)
	move.l	d0,scptr(a5)
	move.b	#1,scflag(a5)	make shell think text lines are in memory
	clr.b	mult_comm_flag(a5)
	bra	chorus
exerr	moveq	#RETURN_ERROR,d0
	rts
xrexx	move.l	d0,a1		execute AREXX-script
	move.l	d1,d0
	bsr	givemem		kill script
	lea	rexxtx(pc),a1
	move.l	a1,parm1(a5)
	bra	notfound	execute archie3

echo_parm	bsr	fixpam2
	move.l	a0,a1
	move.l	a0,a2
	bra.s	.C
.B	move.b	d0,(a2)+
.C	move.b	(a0)+,d0
	beq.s	.A
	cmp.b	#$5c,d0 ;\	Ignore Specialchar
	bne.s	.D
	move.b	(a0)+,d0
	bra.s	.B
.D	cmp.b	#'^',d0		^-Character
	bne.s	.B
	move.b	(a0)+,d0
	cmp.b	#"$",d0		Number given ?
	beq.s	.F
	cmp.b	#"%",d0
	beq.s	.F
	cmp.b	#"0",d0
	blo.s	.E
	cmp.b	#"9",d0
	bhi.s	.E
.F	subq.l	#1,a0
	movem.l	d1/d2/a1,-(sp)
	move.l	a0,a1
	bsr	convert_ASCII_to_num
	lea	-1(a1),a0
	movem.l	(sp)+,d1/d2/a1
	cmp.b	#".",(a0)
	bne.s	.B
	addq.l	#1,a0
	bra.s	.B		Number was given
.E	and.b	#$3f,d0		Control Char
	bra.s	.B
.A	clr.b	(a2)+
	bsr pr_string
	rts

*****************
*	ECHO	*
*****************
echoz	bsr	echo_parm
;	bsr	pr_lf	;lf removed
	moveq	#RETURN_OK,d0
	rts
	
*****************
*	CLS	*
*****************
clsz	lea	clstx(pc),a1
	bsr	pr_string
	moveq	#RETURN_OK,d0
	rts

** MEM INFO :RETURN 3 LONGWORDS AT A0 -> FREE CHIP,FAST,TOTAL
memory_info
	move.l	4.w,a6
	jsr	_LVOForbid(a6)	; don't let 'em change while we ask
	move.l	#MEMF_CHIP,d1	; ok, check free chip
	jsr	_LVOAvailMem(a6)	; ask system how much there is
	move.l	d0,(A0)
	move.l	#MEMF_FAST,d1	; check fast mem avail
	jsr	_LVOAvailMem(a6)
	move.l	d0,4(a0)
	move.l	#MEMF_PUBLIC,d1 	; get all available memory
	jsr	_LVOAvailMem(a6)
	move.l	d0,8(a0)
	jsr	_LVOPermit(a6)
	move.l	dosbase(a5),a6	;restore dosbase
	rts

*****************
*	AVAIL	*
*****************
availz	tst.l	parm2(a5)
	beq.s	.A
	move.l	parm2(a5),a0
	bsr	return_dash_option
	cmp.b	#'C',d0
	bne.s	.A
	bsr	giveman		free some memory
	move.l	4.w,a6
	moveq	#-1,d0		Free mem
	move.l	#$00002711,d1	MAGIC NUMBER (from FIDO-net)
	jsr	_LVOAllocMem(a6)
	jsr	_LVOForbid(a6)
	movea.l	a6,a0
	moveq	#72,d0
	add.l	d0,a0
	moveq	#15,d0		free 16 interrupts
	moveq	#-1,d1
	moveq	#12,d2
.B	add.l	d2,a0
	cmp.l	(a0),d1
	bne.s	.C
	cmp.l	4(a0),d1
	bne.s	.C
	clr.l	(a0)
	clr.l	4(a0)
.C	dbra	d0,.B
	jsr	_LVOPermit(a6)
	move.l	dosbase(a5),a6
.A	lea	-12(sp),sp	show mem
	lea	(sp),a0
	bsr	memory_info
	move.l	a0,a1
	lea	memess(pc),a0
	bsr	new_print	show memory
	lea	12(sp),sp
	moveq	#RETURN_OK,d0
	rts


* ALTER WINDOW PTR FOR THIS PROCESS. USE TO DISABLE REQUESTERS POPPING UP.
* ENTRY D1=0 (NORMAL)  D1=-1 (SUBNORMAL, no requesters).
changeWindowPtr
	movem.l	d1/a0,-(sp)
	tst.l	d1
	bne.s	.A
	move.l	window_old(a5),d1
.A	move.l	thistask(a5),a0
	move.l	d1,pr_WindowPtr(a0)
	movem.l	(sp)+,d1/a0
	rts

raw_on	movem.l	d6/a1,-(sp)	switch console to raw mode
	lea	show_cursor(pc),a1
	bsr	pr_string
	moveq	#-1,d6
	bra.s	raw_switch

rawh_off	movem.l	d6/a1,-(sp)	like raw_off,but hides the cursor
	lea	hide_cursor(pc),a1
	bsr	pr_string
	moveq	#0,d6
	bra.s	raw_switch

raw_off	movem.l	d6/a1,-(sp)	switch console to normal mode
	moveq	#0,d6
;	bra.s	raw_switch

*WINDOW TYPE CHANGER	
raw_switch
	move.l	thistask(a5),a1
	move.l	pr_ConsoleTask(a1),packettask(a5)
	bsr	clearArgs
	move.l	#ACTION_SCREEN_MODE,packettype(a5)
	move.l	d6,myArg1(a5)
	bsr	sendpacket
	movem.l	(sp)+,d6/a1
	rts

clearArgs movem.l	d0/a0,-(sp)
	lea	sp_node(a5),a0
	moveq	#16,d0	;68bytes
.A	clr.l	(a0)+
	dbra	d0,.A
	movem.l	(sp)+,d0/a0
	rts
	
** ENTRY Uses myArg1-myArg7, and packettask, packettype
sendpacket	tst.l	packettask(a5)
	beq.s	.A
	movem.l	d0-d1/a0-a2,-(sp)	V2.0 (new written)
	move.l	4.w,a6
	move.b	#5,LN_TYPE+sp_node(a5)	;message
	move.l	thistask(a5),a2
	lea	pr_MsgPort(a2),a2	;Process-MsgPort !
	move.l	a2,sp_reply(a5)		;Replyport
	move.l	a2,sp_port(a5)
	move.w	#dp_SIZEOF+4,sp_length(a5)
	lea	sp_link(a5),a0
;	move.l	a0,sp_ptr(a5)
	move.l	a0,LN_NAME+sp_node(a5)	;points to link
	lea	sp_node(a5),a1
	move.l	a1,sp_link(a5)		;linked to itself
	move.l	packettask(a5),a0
	jsr	_LVOPutMsg(a6)
	move.l	a2,a0
	jsr	_LVOWaitPort(a6)
	move.l	a2,a0
	jsr	_LVOGetMsg(a6)
	move.l	dosbase(a5),a6
	movem.l	(sp)+,d0-d1/a0-a2
.A	rts


*************************
*	RELABEL 	*
*************************
relabelz	tst.l	parm3(a5)
	beq	too_less_args
	move.l	parm2(a5),a0
	bsr	check_for_colon
	beq.s	.D
	lea	no_colon_tx(pc),a1
	bsr	pr_string
	moveq	#RETURN_ERROR,D0
	rts
.D	move.l	parm2(a5),d1	PARM2=DF0: etc
	jsr	_LVODeviceProc(a6)
	tst.l	d0
	beq	DOSerr
	move.l	d0,packettask(a5)
	move.l	#256,d0
	moveq	#1,d1
	bsr	iwantmem		ASSUME GETS 256 BYTES
	move.l	d0,a2		A2=destination
	lsr.l	#2,d0
	bsr	clearArgs
	move.l	d0,myArg1(a5)	BPTR to my string
	move.l	parm3(a5),a0	NewName
	lea	1(a2),a1		A1=after count
	moveq	#0,d0
.A	move.b	(a0)+,(a1)+
	addq.l	#1,d0
	cmp.b	#':',(a0)		ALLOW FOR IDIOTS WHO PUT : ON END
	beq.s	.C
	tst.b	(a0)
	bne.s	.A
.C	clr.b	(a1)
	move.b	d0,(a2)
	moveq	#ACTION_RENAME_DISK,d0
	move.l	d0,packettype(a5)	TYPE=RENAME_DISK
	bsr	sendpacket
	move.l	a2,a1
	move.l	#256,d0
	bsr	givemem
	bsr	changedisk	;(moved to dc)
*	bsr	eval_CD		-IS MORE ELEGANT IF I LEAVE OUT.
	moveq	#RETURN_OK,d0	USER WILL HAVE TO TYPE CD TO CHANGE
	rts			PROPER.

*************************
*	ADDBUFFERS	*
*************************
addbuffersz
	tst.l	parm3(a5)
	beq	too_less_args
	bsr	clearArgs
	move.l	parm3(a5),a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	cmp.l	#32767,d0
	bhi	bad_number_error
	move.l	d0,myArg1(a5)
	move.l	parm2(a5),d1	PARM2=DF0: etc
	jsr	_LVODeviceProc(a6)
	tst.l	d0
	beq	DOSerr
	move.l	d0,packettask(a5)
	moveq	#ACTION_MORE_CACHE,d0
	move.l	d0,packettype(A5)
	bsr	sendpacket
	bsr	PKTerr
	moveq	#RETURN_OK,d0
	rts

*************************
*	DIE-Handler	*
*************************
diez	tst.l	parm2(a5)
	beq	too_less_args
	bsr	clearArgs
	move.l	parm2(a5),d1	PARM2=DF0: etc
	jsr	_LVODeviceProc(a6)
	tst.l	d0
	beq	DOSerr
	move.l	d0,packettask(a5)
	moveq	#ACTION_DIE,d0
	move.l	d0,packettype(A5)
	bsr	sendpacket
	moveq	#RETURN_OK,d0
	rts

*************************
*	SETDATE		*
*************************
setdatez tst.l	parm2(a5)
	beq	too_less_args
	move.l	parm2(a5),a2
	bsr	clearArgs
	lea	date_mark(a5),a0
	lea	(a0),a3
	move.l	a0,myArg4(a5)	;APTR datestamp
	bsr	get_time
	tst.l	parm3(a5)
	beq	nospda
	move.l	a2,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	move.l	d0,d7
	beq	DOSerr
	move.l	d0,d1
	lea	fib_DiskKey(a5),a0
	move.l	a0,d2
	jsr	_LVOExamine(a6)
	tst.l	d0
	beq	DOSerrUL
	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	lea	-14(sp),sp
	lea	(sp),a0
	lea	fib_Date(a5),a1
	bsr	convert_time
	lea	parm3(a5),a0
	lea	(sp),a1
	bsr	settime
	move.w	12(sp),d1
	lea	14(sp),sp
	tst.l	d0
	beq	.B
	rts

.B	lea	(a3),a0
	move.l	d5,(a0)+	;days
	divu	#60,d6
	move.w	d6,d0
	ext.l	d0
	move.l	d0,(a0)+	;mins
	swap	d6
	mulu	#50,d6
	add.l	d1,d6
	move.l	d6,(a0)		;ticks
nospda	move.l	a2,d1	;filename
	jsr	_LVODeviceProc(a6)
	tst.l	d0
	beq	DOSerr
	move.l	d0,packettask(a5)
	move.l	a2,a0
	lea	temp2buf(a5),a1
	move.l	a1,a3
	bsr	split_wild	;No wildcard ! Only separates filename !
	move.l	a2,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	move.l	d0,d7
	beq	DOSerr
	move.l	d0,myArg2(a5)	;BPTR lock
	move.l	a3,a0
	lea	tempbuf(a5),a1
	moveq	#-1,d0
	bsr	cpBSTR
	move.l	d0,myArg3(a5)	;BSTR filename
	moveq	#ACTION_SET_DATE,d0
	move.l	d0,packettype(A5)
	bsr	sendpacket
	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	bsr	PKTerr
	moveq	#RETURN_OK,d0
	rts

*************************
*	DISKCHANGE	*
*************************
diskchangez
	tst.l	parm2(a5)
	beq	too_less_args
	move.l	parm2(a5),d1	PARM2=DF0: etc
	jsr	_LVODeviceProc(a6)
	tst.l	d0
	beq	DOSerr
	move.l	d0,packettask(a5)
	bsr	changedisk
	moveq	#RETURN_OK,d0
	rts

** USES task in packettask
changedisk
	bsr	clearArgs
	moveq	#ACTION_INHIBIT,d0
	move.l	d0,packettype(a5)
	moveq	#-1,d0	;1?
	move.l	d0,myArg1(a5)
	bsr	sendpacket
	bsr	PKTerr
	clr.l	myArg1(a5)
	bsr	sendpacket
	bsr	PKTerr
	rts

*************************
*	LOCK		*
*************************
lockz	tst.l	parm2(a5)
	beq	too_less_args
	tst.l	parm3(a5)
	beq	help_status
	move.l	parm3(a5),a0
	moveq	#-1,d7
	move.b	1(a0),d0
	bset	#5,d0
	cmp.b	#"n",d0	;oN
	beq.s	.B
	moveq	#0,d7
.B	move.l	parm2(a5),d1	PARM2=DF0: etc
	jsr	_LVODeviceProc(a6)
	tst.l	d0
	beq	DOSerr
	move.l	d0,packettask(a5)
	bsr	clearArgs
	move.l	#ACTION_WRITE_PROTECT,d0
	move.l	d0,packettype(a5)
	move.l	d7,myArg1(a5)
	bsr	sendpacket
	bsr	PKTerr
	moveq	#RETURN_OK,d0
	rts

*********************************
*	UNSET VARIABLE		*
*********************************
unsetz	lea	parm2(a5),a3
.A	tst.l	(a3)
	beq	no_more_unsets
	move.l	(a3)+,a0
	bsr	check_if_set_already_there
	tst.l	d0
	beq	unset_failure
	move.l	d0,a1
	move.l	(a1),d2	GRAB NEXT SET POINTER
	move.l	set_size(a1),d0
	move.l	d1,a0	D1=prior set
	move.l	d2,(a0)	SKIP OVER SET TO DELETE
	bsr	givemem
	bra	.A
no_more_unsets
	moveq	#RETURN_OK,d0
	rts
unset_failure
	lea	set_search_string(a5),a1
	bsr	pr_string
	lea	bad_unset_tx(pc),a1
	bsr	pr_string
	moveq	#RETURN_ERROR,d0
	rts

*********************************
*	SET VARIABLE KEY	*
*********************************
set_funcz	tst.l	parm2(a5)		SEE IF ANY PARAMETERS TYPED
	beq	show_current_sets
	bsr	fixpam32		A0=parm2 A1=parm3
	bsr	check_if_set_already_there
	tst.l	d0
	beq	create_new_set
	bra	update_old_set

create_new_set
	bsr	allocate_temp_space	GET BIG BLOCK
	tst.l	d0
	beq.s	end_set_func
	bsr	copy_func_defn_to_space
	move.l	a1,d4		D4=after end
	sub.l	a3,a1		WORK OUT HOW BIG IS ACTUALLY
	move.l	a1,d0
	moveq	#1,d1
	bsr	iwantmem		allocate block big enough for everything
	beq.s	.A
	move.l	d0,a2
	move.l	a1,set_size(a2)
	bsr	insert_new_set
	lea	set_name(a2),a1	new block
	lea	set_name(a3),a0	temp block
.B	move.b	(a0)+,(a1)+
	cmp.l	a0,d4
	bne.s	.B
.A	move.l	a3,a1
	move.l	#temp_set_size,d0
	bsr	givemem
end_set_func
	moveq	#RETURN_OK,d0
	rts
	

check_if_set_already_there
* A0= set name
	movem.l	a0-a1,-(sp)
	lea	set_search_string(a5),a1
	bsr	cp_string
	bsr	search_sets
	movem.l	(sp)+,a0-a1
	rts

update_old_set
* first delete old one
	movem.l	a0-a1,-(sp)
	move.l	d0,a1
	move.l	(a1),d2	GRAB NEXT SET POINTER
	move.l	set_size(a1),d0
	move.l	d1,a0	D1=prior set
	move.l	d2,(a0)	SKIP OVER SET TO DELETE
	bsr	givemem
	movem.l	(sp)+,a0-a1
* and replace with new set
	bra	create_new_set

temp_set_size	equ	SHELLINE_SIZE+$60

allocate_temp_space
	move.l	#temp_set_size,d0
	moveq	#1,d1
	bra	iwantmem
	

deallocate_sets
	move.l	first_set_defn(a5),d3
	beq	no_sets_to_lose
lose_next_set
	move.l	d3,a1
	move.l	(a1),-(sp)
	move.l	set_size(a1),d0
	bsr	givemem
	move.l	(sp)+,d3
	bne	lose_next_set
no_sets_to_lose
	rts

insert_new_set
	move.l	a3,-(sp)
	move.l	d0,a3			A3=new space
	move.l	first_set_defn(a5),d1
	move.l	d1,(a3)			new pts to old
	move.l	a3,first_set_defn(a5)
	move.l	(sp)+,a3
	rts

set_size		equ	4
set_name		equ	8
set_defn		equ	24

** ENTRY D0=space, A0=name, A1=defn
** EXIT A1=after zero in dest, A3=space
copy_func_defn_to_space
	move.l	d0,a3
	move.l	a1,-(sp)
	lea	set_name(a3),a1
	bsr	cp_string		COPY SET NAME TO SPACE
	move.l	(sp)+,a0
	lea	set_defn(a3),a1
	bra	cp_string_special	COPY SET DEFN TO SPACE

* THIS STRING COPY COPYS A0->A1 BUT CONVERTS ALL \n to n
* RETURN A0 = after zero in src, A1 = after zero in dest
cp_string_special
	move.l	d0,-(sp)
	bra.s	.B
.A	cmp.b	#$5c,d0 ;\
	beq.s	.B
	move.b	d0,(a1)+
.B	move.b	(a0)+,d0
	bne.s	.A
	move.b	d0,(a1)+
	move.l	(sp)+,d0
	rts
	
	
show_current_sets
	bsr	rawh_off
	move.l	first_set_defn(a5),d0
	beq	no_sets_to_show
show_next_set
	move.l	d0,a3
	lea	set_name(a3),a1
	bsr	pr_string
	bsr	pr_tab
	lea	set_defn(a3),a1
	bsr	pr_stringlf
	move.l	(a3),d0		CHECK NEXT SET ADDRESS
	bne	show_next_set
no_sets_to_show
	moveq	#RETURN_OK,d0
	rts

*************************
*	RESIDENT	*	V2.0:uses the GLOBAL resident-list
*************************	(many things changed)
residentz	move.l	parm2(a5),d0	SEE IF ANY PARAMETERS TYPED
	beq	show_current_residents
	lea	parm2(a5),a3
	move.l	(a3),a0
	bsr	return_dash_option
	cmp.b	#'C',d0
	beq	kill_resi
next_resi	move.l	(a3)+,d0
	bne.s	.B
	moveq	#RETURN_OK,d0
	rts
.B	move.l	d0,a4		A4=parmName
	bsr	spaths2		SEARCH PATHS FOR THE COMMAND
	tst.l	d0
	beq	resi_not_found
	move.l	d0,-(sp)	push seglist
	move.l	a4,a0
	move.l	a4,a1
	bsr	rempath		SRC = DEST is OK
	bsr	search_res2	find if same name is on resi list
	move.l	(sp)+,d3
	move.l	d0,d1
	bne.s	.A
	bsr	create_resi
	bra.s	next_resi
.A	moveq	#1,d0
	cmp.l	resi_usecount(a0),d0
	bne.s	resi_inuse
	move.l	d0,resi_usecount(a0)
	move.l	d3,resi_seglist(a0)	new seglist
	jsr	_LVOUnLoadSeg(a6)	Unload old one with same name
	bra.s	next_resi

kill_resi	tst.l	(a3)+
.B	move.l	(a3)+,d0
	bne.s	.A
	moveq	#RETURN_OK,d0
	rts
.A	move.l	d0,a4
	move.l	a4,a0
	move.l	a4,a1
	bsr	rempath		SRC = DEST is OK
	bsr	search_res2	find if same name is on resi list
	move.l	d0,d1		gives d0,a0,d2
	beq.s	resi_not_found
	moveq	#1,d0
	cmp.l	resi_usecount(a0),d0
	bne.s	resi_inuse
	move.l	a0,a2
	move.l	d2,a0
	move.l	resi_link(a2),resi_link(a0)
	clr.l	resi_link(a2)
	jsr	_LVOUnLoadSeg(a6)	Unload old one with same name
	move.l	a2,d1
	lsr.l	#2,d1
	jsr	_LVOUnLoadSeg(a6)
	bra.s	.B

resi_not_found
	lea	badcomm(pc),a1
	bsr	pr_string
	bra.s	resi_error
resi_no_mem
	lea	resi_no_mem_tx(pc),a1
	bsr	pr_stringlf
	bra.s	resi_error
resi_inuse
	lea	resi_inuse_tx(pc),a1
	bsr	pr_stringlf
resi_error
	moveq	#RETURN_ERROR,d0
	rts

create_resi		;D3:SegList, A4:Name
	moveq	#resi_length,d0
	move.l	a4,a0
.A	addq.l	#1,d0	one more for lenght-byte
	tst.b	(a0)+
	bne.s	.A
	addq.l	#4,d0	4 more for segment-length
	addq.l	#7,d0	(7 more for and'ing needed by UnLoadSeg)
	moveq	#-4,d1
	and.l	d1,d0
	move.l	d0,d2
	moveq	#1,d1
	bsr	iwantmem
	beq.s	resi_no_mem
	addq.l	#4,d0
	move.l	d0,a2		D0=addr of resi_list_node
	move.l	d2,-4(a2)	save segment-length
	bsr	do_forbid
	bsr	resi_hand
	move.l	d0,resi_link(a2)
	move.l	a2,d0
	lsr.l	#2,d0
	move.l	d0,(a0)
	moveq	#1,d0
	move.l	d0,resi_usecount(a2)
	move.l	d3,resi_seglist(a2)
	lea	resi_name(a2),a1
	move.l	a4,a0
	moveq	#-1,d0
	bsr	cpBSTR
	bsr	do_permit
	moveq	#0,d0
	rts

resi_hand	move.l	dl_Root(a6),a0
	move.l	rn_Info(a0),a0
	add.l	a0,a0
	add.l	a0,a0
	lea	di_NetHand(a0),a0	NetHand in A0
	move.l	(a0),d0		Start of Resi-List in D0
	rts

show_current_residents
	lea	residetx(pc),a1
	bsr	pr_stringlf
	bsr	rawh_off
	bsr	resi_hand
	beq	no_resis_to_show
.A	lsl.l	#2,d0
	move.l	d0,a3
	move.l	resi_usecount(a3),d0
	subq.l	#1,d0
	bsr	print10
	bsr	pr_space
	move.l	a3,d0
	bsr	printADR
	bsr	pr_space
	lea	resi_name(a3),a1
	moveq	#0,d3
	move.b	(a1)+,d3
	move.l	a1,d2
	move.l	outhandle(a5),d1
	beq.s	.B
	jsr	_LVOWrite(a6)
	bsr	pr_lf
.B	bsr	check_c
	bne.s	no_resis_to_show
	move.l	resi_link(a3),d0
	bne	.A
no_resis_to_show
	moveq	#RETURN_OK,d0
	rts

******	Copy String from A0 to BSTR A1
cpBSTR	movem.l	d1-d2/a0-a2,-(sp)	max. Length-2 in D0
	lea	1(a1),a2
	moveq	#0,d2
	bra.s	.B
.A	move.b	d1,(a2)+
	addq.l	#1,d2
.B	move.b	(a0)+,d1
	dbeq	d0,.A
	clr.b	(a2)	;NULL-end it
	move.b	d2,(a1)
	move.l	a1,d0
	lsr.l	#2,d0
	movem.l	(sp)+,d1-d2/a0-a2	D0 is BPTR to the BSTR
	rts


*************************
*	PROTECT		*
*************************
protectz	bsr	fixpam32
	tst.b	(a1)
	beq	check_existing_protection
	bsr	get_protection_bits
	bsr	alter_protection_bits
	moveq	#RETURN_OK,d0
	rts

alter_protection_bits
* A1-> rwed etc.   A2-> prot table  A0-> filename  D3=old prot bits.
	lea	prot_bits_table(pc),a2
	tst.b	(a1)
	beq	set_the_protection
apb_loop	move.b	(a2)+,d1	get letter from table
	bne.s	.A
	lea	bad_prot_bits_tx(pc),a1
	bsr	pr_string
	moveq	#RETURN_ERROR,D0
	rts

.A	move.b	(a2)+,d2	get code from table
	move.b	(a1),d0
	bsr	compD1D0nocase
	bne.s	apb_loop
	eor.b	d2,d3
	move.b	(a1)+,d1	dummy,bump ptr
	bra	alter_protection_bits
set_the_protection
	move.l	d3,d2
	move.l	a0,d1
	jsr	_LVOSetProtection(a6)
	rts

check_existing_protection
	bsr	get_protection_bits
	bsr	translate_prot_bits
	moveq	#RETURN_OK,d0
	rts

get_protection_bits
	movem.l	a0-a1,-(sp)
	bsr	fibexam
	move.l	fib_Protection(a5),d3
	bsr	unlock
	movem.l	(sp)+,a0-a1
	rts
	
translate_prot_bits
	lea	fib_FileName(a5),a1
	bsr	pr_string
	bsr	pr_tab
	bsr	pr_prot
	bra	pr_stringlf

pr_prot	moveq	#7,d0			V2.0
	move.l	fib_Protection(a5),d1
	eor.b	#$0f,d1
	lea	temp2buf(a5),a0
.A	move.b	#"-",(a0)+
	btst	d0,d1
	beq.s	.B
	move.b	protflags(pc,d0.w),-1(a0)
.B	dbra	d0,.A
	clr.b	(a0)
	lea	temp2buf(a5),a1
	rts

protflags	dc.b	'dewrapsh'
prot_bits_table
	dc.b	'h',$80
	dc.b	's',$40
	dc.b	'p',$20
	dc.b	'a',$10
	dc.b	'r',$08
	dc.b	'w',$04
	dc.b	'e',$02
	dc.b	'd',$01
	dc.w	0

*********************************
*	RPN CALCULATOR		*
*********************************
evalz	lea	parm2(a5),a4
	move.l	sp,d5		remember the stack ptr
rpn_loop1	move.l	(a4)+,d1
	beq	show_rpn_result
	lea	endofparms(a5),a1
	cmp.l	a1,a4
	bhi	show_rpn_result
	move.l	d1,a1
	lea	8(sp),a0
	cmp.l	a0,d5
	blo	not_poke32

	cmp.b	#'+',(a1)		
	bne.s	not_add		
	move.l	(sp)+,d0		DO ADD
	add.l	d0,(sp)
	bra	rpn_loop1
not_add	cmp.b	#'-',(a1)
	bne.s	not_sub
	move.l	(sp)+,d0
	sub.l	d0,(sp)
	bra	rpn_loop1
	
not_sub	cmp.b	#'*',(a1)
	bne.s	not_mult
	move.l	(sp)+,d0	last	DO MULT
	move.l	(sp)+,d1	2nd last
	bsr	mult_32x32
	move.l	d0,-(sp)
	bra	rpn_loop1
not_mult	cmp.b	#'/',(a1)
	bne.s	not_div
	move.l	(sp)+,d1	last	DO DIVIDE
	move.l	(sp)+,d0	2nd last
	tst.l	d1
	beq	rpn_error		NO DIVIDE BY ZERO
	bsr	div_32
	move.l	d0,-(sp)
	bra	rpn_loop1
not_div	cmp.b	#'&',(a1)
	bne.s	not_and
	move.l	(sp)+,d0
	and.l	d0,(sp)
	bra	rpn_loop1
not_and	cmp.b	#"|",(a1)
	bne.s	not_or
	move.l	(sp)+,d0
	or.l	d0,(sp)
	bra	rpn_loop1
not_or	cmp.b	#'!',(a1)
	bne.s	not_poke32
	move.l	(sp)+,d0	GET ADDR		DO POKE 32
	move.l	(sp)+,d1	GET VALUE
	and.b	#$fe,d0
	move.l	d0,a0
	move.l	d1,(a0)
	bra	rpn_loop1
not_poke32
	cmp.b	#'@',(a1)
	bne.s	not_peek32
	move.l	(sp)+,d0	ADDR	DO PEEK 32
	cmp.l	sp,d5
	blo	rpn_error
	and.b	#$fe,d0
	move.l	d0,a0
	move.l	(a0),-(sp)
	bra	rpn_loop1

not_peek32
	bsr	convert_ASCII_to_num
	beq	rpn_error
	move.l	d0,-(sp)
	bra	rpn_loop1
rpn_error	move.l	d5,sp
	rts

show_rpn_result
	move.l	(sp),-(sp)
	moveq	#RETURN_ERROR,d7	error on equal
	tst.l	(sp)
	beq.s	.B
	bpl.s	.C
	moveq	#RETURN_WARN,d7		warn on minus
	bra.s	.B
.C	moveq	#RETURN_OK,d7		ok on plus
.B	lea	(sp),a1
	move.l	sp,a1
	lea	rpn_result_tx(pc),a0	print hex & dec
	move.l	outhandle(a5),d0
	cmp.l	stdout(a5),d0	output redirected ?
	beq.s	.A
	moveq	#RETURN_OK,d7
	lea	rpn_res2(pc),a0	print only number
.A	bsr	new_print
	move.l	d5,sp
	move.l	d7,d0
	rts

div_32	movem.l	d2-d4,-(sp)
	moveq	#0,d2
	moveq	#31,d4
_divu1	roxl.l	#1,d0	; divident
	roxl.l	#1,d2	; work accum
	cmp.l	d1,d2	; cmp with divisor
	blo.s	_divu2
	sub.l	d1,d2
	dc.l	$003c0010	;ori.b	#16,CCR	;setx
_divu2	roxl.l	#1,d3	; result
	dbf	d4,_divu1
	move.l	d3,d0
	move.l	d2,d1
	movem.l	(sp)+,d2-d4	;result:d0 rest:d1
	rts


mult_32x32
* D1 = 32 bit, D0 = 32 bit (result)
	movem.l	d1-d3,-(sp)
	move.l	d0,d2
	move.l	d0,d3
	mulu	d1,d0	save intermediate result
	swap	d3
	mulu	d1,d3
	swap	d3
	clr.w	d3
	add.l	d3,d0
	swap	d1
	mulu	d1,d2
	swap	d2
	clr.w	d2
	add.l	d2,d0
	movem.l	(sp)+,d1-d3
	rts

* Convert null ending ASCII number(A1) to 32bit number in D0
* Return D1=0 if bad number (a1:current pos)
convert_ASCII_to_num	
	movem.l	d2/d3/a0,-(sp)
	moveq	#0,d3	SET POSITIVE
	moveq	#0,d1	RESET BASE
.A	cmp.b	#'|',(a1)
	bne.s	convnor
	lea	1(a1),a0
	bsr	readfile
	cmp.w	#NEWPRINTSIZE-2,d1
	bhs	conversion_finished
	move.l	d0,a0
	lea	NewPrintBuffer(a5),a1
	move.l	d1,d2
	subq.w	#1,d2
.B	move.b	(a0)+,(a1)+
	dbra	d2,.B
	clr.b	(a1)
	move.l	d0,a1
	move.l	d1,d0
	bsr	givemem
	lea	NewPrintBuffer(a5),a1
;	bset	#0,d3
	bra.s	.A
convnor	moveq	#0,d0	RESET RESULT
	moveq	#0,d1	RESET BASE
	tst.b	(a1)
	beq	conversion_finished
	moveq	#10,d1	SET THE BASE
	cmp.b	#'-',(a1)	negative sign
	bne.s	.A
	bset	#3,d3
.D	addq.l	#1,a1
.A	cmp.b	#'+',(a1)	positive sign
	beq.s	.D
	cmp.b	#'&',(a1)	for APTR (hex!) -> BPTR
	bne.s	.B
	addq.l	#1,a1
	bset	#1,d3
	moveq	#16,d1	SET RADIX16
	bra	same_base
.B	cmp.b	#'§',(a1)	for BPTR (hex!) -> APTR
	bne.s	.C
	addq.l	#1,a1
	bset	#2,d3
	moveq	#16,d1	SET RADIX16
	bra	same_base
.C	cmp.b	#'$',(a1)
	bne.s	other_base
	move.b	(a1)+,d2	DUMMY BUMP
	moveq	#16,d1	SET RADIX16
	bra	same_base

other_base
	cmp.b	#'%',(a1)
	bne.s	same_base
	move.b	(a1)+,d2
	moveq	#2,d1	SET RADIX2
same_base	moveq	#0,d2
	move.b	(a1)+,d2
	beq	conversion_finished
	bsr	convert_D2_to_num
	tst.l	d1
	beq.s	conversion_finished
	bsr	mult_32x32
	add.l	d2,d0
	bra	same_base
conversion_finished
	btst	#3,d3
	beq.s	.A
	neg.l	d0
.A	btst	#1,d3
	beq.s	.B
	lsr.l	#2,d0
.B	btst	#2,d3
	beq.s	.C
	lsl.l	#2,d0
.C	movem.l	(sp)+,d2/d3/a0
	tst.b	d1
	rts
	
convert_D2_to_num
	cmp.b	#'0',d2
	blo.s	bad_number
	cmp.b	#'9',d2
	bhi.s	check_hex
	sub.b	#'0',d2
	rts
check_hex	cmp.b	#16,d1
	bne.s	bad_number
	cmp.b	#'f',d2
	bhi.s	bad_number
	cmp.b	#'A',d2
	blo.s	bad_number
	cmp.b	#'F',d2
	bhi.s	check_upper_hex
	sub.b	#55,d2
	rts
check_upper_hex
	cmp.b	#'a',d2
	blo.s	bad_number
	sub.b	#87,d2
	rts
bad_number
	moveq	#0,d1	FLAG ERROR thru silly base
	rts

*********************************
*	MEMORY EXAMINE		*
*********************************
memexamz	clr.l	mem_offset_addr(a5)
	moveq	#0,d7
	tst.l	parm2(a5)		CHECK IF NO ADDRESS.
	bne.s	.E
	moveq	#10,d7
	bra	show_mempage
.E	bsr	fixpam32
	tst.b	(a1)
	beq.s	.A
	move.l	a0,-(sp)
	bsr	convert_ASCII_to_num	convert 2nd num
	move.l	(sp)+,a0
	tst.b	d1
	beq	bad_number_error
	move.l	d0,d7			D7=2nd num
.A	move.l	a0,a1
	bsr	convert_ASCII_to_num	convert 1st num
	beq	bad_number_error
.C	tst.l	d7
	bne.s	.D
	moveq	#10,d7
	bra.s	memex2
.D	sub.l	d0,d7
	lsr.l	#4,d7
	addq.l	#1,d7

memex2	move.l	d0,mem_addr(a5)
show_mempage
	and.b	#$fe,mem_addr+3(a5)	MAKE SURE EVEN ADDRESS
*	moveq	#19,d7		D7=count
shmem2	bsr	check_c
	bne	.A
	bsr	show_16_locs
	subq.l	#1,d7
	bne.s	shmem2
.A	moveq	#RETURN_OK,d0
	rts
	
show_16_locs
	move.l	mem_addr(a5),a1
	lea	CLIbuf(a5),a3
	move.l	a3,a0
	moveq	#15,d0
sh_16_1	move.b	(a1)+,d1
	move.b	#'.',(a0)+
	move.b	d1,d2
	bclr	#7,d2
	cmp.b	#' ',d2
	blo.s	sh_16_2
	move.b	d1,-1(a0)
sh_16_2	dbra	d0,sh_16_1
	clr.b	(a0)
	move.l	a3,-(sp)		PUSH STRING ADDR
	move.l	-(a1),-(sp)	PUSH LAST BYTES
	move.l	-(a1),-(sp)
	move.l	-(a1),-(sp)
	move.l	-(a1),-(sp)	PUSH FIRST BYTES
	move.l	mem_addr(a5),d0
	sub.l	mem_offset_addr(a5),d0
	move.l	d0,-(sp)
	lea	mem_line(pc),a0
	lea	(sp),a1
	bsr	new_print
	movem.l	(sp)+,d0-d5	DUMMY
	add.l	#16,mem_addr(a5)
	rts

* ENTRY A0=FORMATSTRING A1=DATASTREAM.
new_print	;v2.0 small data
	movem.l	d0-d3/a0-a3,-(sp)
	lea	NewPrintBuffer(a5),a3	;V2.0 not on stack
	lea	KPutChar(pc),a2
	move.l	4.w,a6
	jsr	_LVORawDoFmt(a6)
	move.l	dosbase(a5),a6
	move.l	outhandle(a5),d1
	beq.s	.B
	lea	NewPrintBuffer(a5),a0
	move.l	a0,d2
	moveq	#-1,d3
.A	addq.l	#1,d3
	tst.b	(a0)+
	bne.s	.A
	jsr	_LVOWrite(a6)
.B	movem.l	(sp)+,d0-d3/a0-a3
	rts

KPutChar move.b	d0,(a3)+
	rts

*************************
*	VEC/RESET	*
*************************
resetz	lea	resask(pc),a1
	bsr	pr_string
	bsr	rask	;ask politely V2.0
	tst.l	d0
	bne.s	BigCrash
	moveq	#RETURN_FAIL,d0
	rts
BigCrash move.l	(4).w,a6
	clr.l	$0026(A6)
	move.l	#$00FC00D2,$0080
	trap	#$00
	rts	;will never arrive

eb_CoolCapture	equ	46
eb_ColdCapture	equ	42
eb_WarmCapture	equ	50
eb_KickMemPtr	equ	546
eb_KickTagPtr	equ	550
eb_KickCheckSum	equ	554

vecz	move.l	4.w,a0
	move.l	eb_KickCheckSum(a0),-(sp)
	move.l	eb_KickMemPtr(a0),-(sp)
	move.l	eb_KickTagPtr(a0),-(sp)
	move.l	eb_ColdCapture(a0),-(sp)
	move.l	eb_CoolCapture(a0),-(sp)
	move.l	eb_WarmCapture(a0),-(sp)
	lea	(sp),a1
	lea	vec_line(pc),a0
	bsr	new_print
	moveq	#RETURN_ERROR,d0
	moveq	#5,d1
	move.l	sp,a0
.A	tst.l	(a0)+
	bne.s	.B
	dbra	d1,.A
	moveq	#RETURN_OK,d0
.B	movem.l	(sp)+,d1-d6	get rid of trash
	rts

** SAVE STATS store current time in date mark, and current memory use in mem mark
save_time
	movem.l	d0-d1/a0,-(sp)
	lea	date_mark(a5),a0
	bsr	get_time
	movem.l	(sp)+,d0-d1/a0
	rts
save_mem	movem.l	d0-d1/a0,-(sp)
	lea	mem_mark(a5),a0
	bsr	memory_info	
	movem.l	(sp)+,d0-d1/a0
	rts

** DISPLAY TIME ELAPSED SINCE LAST CALL TO SAVE TIME AND
**  ALSO CHANGE IN MEMORY AVAILABLE. EXPECTS RETURN CODE TO BE ABOVE RETURN
**  ADDRESS ON STACK ie 4(sp)
show_status
	jsr	_LVOIoErr(a6)
	lea	-34(sp),sp
	lea	(sp),a0		A0=time area
	move.l	d0,(a0)+	;-4(a0) result2
	bsr	get_time	
	lea	date_mark(a5),a1
	move.l	ds_Tick(a0),d0
	sub.l	ds_Tick(a1),d0
	bpl.s	no_tick_carry
	add.l	#3000,d0
	subq.l	#1,ds_Minute(a0)
no_tick_carry
	move.l	d0,ds_Tick(a1)	store in datemark
	move.l	ds_Minute(a0),d0
	sub.l	ds_Minute(a1),d0
	move.l	d0,ds_Minute(a1)
	bsr	convert_time	A0=4+3 words of time
do_mem_deltas
	lea	14(a0),a0
	bsr	memory_info
	lea	mem_mark(a5),a1
	move.l	(a1),d0
	sub.l	d0,(a0)	subtract old from new	;chip
	move.l	4(a1),d0
	sub.l	d0,4(a0)			;fast
	move.l	8(a1),d0
	sub.l	d0,8(a0)			;total
	lea	-12(a0),a1
	move.l	-18(a0),(a1)
	lea	stat_text(pc),a0
	bsr	new_print
	lea	34(sp),sp
	rts

*************************	
*	DATE/TIME	*
*************************
datez	lea	date_mark(a5),a2
	move.l	a2,a0
	bsr	get_time
	move.l	a2,a1
	lea	-14(sp),sp
	lea	(sp),a0
	bsr	convert_time
	tst.l	parm2(a5)
	beq.s	.A
	lea	parm2(a5),a0
	lea	(sp),a1
	bsr.s	settime
	lea	14(sp),sp
	bne.s	.B
	bsr	tset
	clr.l	parm2(a5)
	bra.s	datez	;now print date/time
.A	lea	(sp),a1
	lea	time_text(pc),a0
	bsr	new_print
	lea	14(sp),sp
	moveq	#RETURN_OK,d0
.B	rts

settime	movem.l	d1-d4/a0-a4,-(sp)	V2.0
	move.l	a0,a4		;a0=parameters
	move.l	a1,temp1(a5)	;a1=date/time
settim	move.l	(a4)+,a0
	lea	temp2buf(a5),a2
	moveq	#2,d3
aa1	move.l	a0,a1
	bsr	gab
	move.b	d0,d4
	beq.s	bb1
	clr.b	-1(a0)
	cmp.b	#".",d0		;day.month.year
	bne.s	dat2
bb1	bsr	convert_ASCII_to_num
	cmp.w	#99,d0	;rough check
	bhi	muell
	move.w	d0,(a2)+
	tst.l	d1
	beq	muell
	tst.b	d4
	dbeq	d3,aa1
mull1	tst.w	d3
	bne	muell
	lea	temp2buf(a5),a2
	move.l	temp1(a5),a1
	moveq	#2,d3
.B	move.w	(a2)+,(a1)+
	dbra	d3,.B
	bra	oktt
aa2	move.l	a0,a1
	bsr	gab
	move.b	d0,d4
	beq.s	bb2
	clr.b	-1(a0)
dat2	cmp.b	#":",d0		;hour:minute:second
	bne.s	dat3
bb2	bsr	convert_ASCII_to_num
	cmp.w	#99,d0
	bhi	muell
	move.w	d0,(a2)+
	tst.l	d1
	beq	muell
	tst.b	d4
	dbeq	d3,aa2
mull2	tst.w	d3
	bne	muell
	lea	temp2buf(a5),a2
	move.l	temp1(a5),a1
	lea	6(a1),a1
	moveq	#2,d3
.B	move.w	(a2)+,(a1)+
	dbra	d3,.B
	bra	oktt
	moveq	#2,d3
aa3	move.l	a0,a1
	bsr	gab
	move.b	d0,d4
	beq.s	bb3
	clr.b	-1(a0)
dat3	cmp.b	#"-",d0		;month-day-year
	bne	muell
bb3	bsr	convert_ASCII_to_num
	cmp.w	#99,d0
	bhi	muell
	move.w	d0,(a2)+
	tst.l	d1
	beq	muell
	tst.b	d4
	dbeq	d3,aa3
mull3	tst.w	d3
	bne	muell
	lea	temp2buf(a5),a2
	move.l	temp1(a5),a1
	move.w	(a2)+,2(a1)
	move.w	(a2)+,(a1)
	move.w	(a2)+,4(a1)
oktt	tst.l	(a4)
	bne	settim
	lea	chaotab(pc),a0
	move.l	temp1(a5),a1
	lea	temp2buf(a5),a3
	moveq	#5,d0
	moveq	#0,d1
.A	move.b	(a0)+,d1
	move.w	0(a1,d1),d2
	move.b	d2,(a3)+
	dbra	d0,.A
	lea	temp2buf(a5),a3
	bsr	calcsec
	movem.l	(sp)+,d1-d4/a0-a4
	moveq	#RETURN_OK,d0
	rts	;result in d5-d7

muell	lea	muell_tx(pc),a1
	bsr	pr_stringlf
	movem.l	(sp)+,d1-d4/a0-a4
	moveq	#RETURN_ERROR,d0
	rts

gab	move.b	(a0)+,d0
	cmp.b	#$30,d0
	blo.s	.A
	cmp.b	#$39,d0
	bls.s	gab
.A	cmp.b	#"%",d0	;handle bin (that's fun !)
	beq.s	gab
	rts

** GET TIME STORE DAYS,MINUTES,TICKS AT A0
get_time	move.l	a0,-(sp)
	move.l	a0,d1
	jsr	_LVODateStamp(a6)
	move.l	(sp)+,a0
	rts

** ENTRY A0 pts to 7 words of storage, A1 pts to date stamp
** send time to A0 --> 13(A0)
convert_time
	movem.l	d0-d3/a0-a2,-(sp)
	move.l	ds_Tick(a1),d0
	divu	#50,d0
	move.w	d0,4+6(a0)		seconds
	swap	d0
	asl.w	#1,d0
	move.w	d0,6+6(a0)		hundredths
	move.l	ds_Minute(a1),d0
	divu	#60,d0
	move.w	d0,0+6(a0)		hours
	swap	d0	
	move.w	d0,2+6(a0)		minutes
	move.l	ds_Days(a1),d0
	move.w	#365,d1		V2.0:year, day, month
	move.w	#77,d2
wdhj	addq.w	#1,d2
	sub.w	d1,d0
	bcs.s	mon
	move.w	d2,d3
	and.w	#3,d3
	bne.s	wdhj
	cmp.w	#100,d2
	blo.s	ork
	moveq	#1,d3
	addq.w	#1,d0
	sub.w	#100,d2
ork	subq.w	#1,d0
	bcc.s	wdhj
	addq.w	#1,d0
mon	add.w	d1,d0
	move.w	d2,4(a0)	year (lots of work)
	moveq	#0,d2
	lea	montab(pc),a2
wdhm	addq.w	#1,d2
	moveq	#0,d1
	move.b	(a2)+,d1
	sub.w	d1,d0
	bcs.s	tag
	cmp.w	#2,d2
	bne.s	wdhm
	move.w	4(a0),d3
	beq.s	wdhm
	and.w	#3,d3
	bne.s	wdhm
	subq.w	#1,d0
	bcc.s	wdhm
	addq.w	#1,d0
tag	add.w	d1,d0
	addq.w	#1,d0
	move.w	d2,2(a0)	month (i don't like february)
	move.w	d0,(a0)		day
	movem.l	(sp)+,d0-d3/a0-a2
	rts

montab	dc.b	31,28,31,30,31,30,31,31,30,31,30,31

*************************
*	CHECK		*	ALLOWS DIS/ENABLING OF STATUS DISPLAY
*************************
checkz	tst.l	parm2(a5)
	beq.s	help_status
	move.l	parm2(a5),a0
	clr.b	stat_mode_flag(a5)	=00
	move.b	1(a0),d0
	bset	#5,d0
	cmp.b	#"n",d0	;oN
	bne.s	say_OK
stat_yes	not.b	stat_mode_flag(a5)	=FF
say_OK	lea	OK_text(pc),a1
	bsr	pr_string
	moveq	#RETURN_OK,d0
	rts
help_status
	lea	chkuse(pc),a1
	bsr	pr_stringlf
	moveq	#RETURN_BAD,d0
	rts

*************************
*	STACK		*
*************************
stackz	move.l	thistask(a5),a0
	move.l	pr_CLI(a0),a4
	add.l	a4,a4
	add.l	a4,a4		A4=cli ptr

	move.l	cli_DefaultStack(a4),d7
	asl.l	#2,d7
	tst.l	parm2(a5)
	beq.s	show_stack
	move.l	parm2(a5),a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
stk_num_OK
	move.l	d0,d6
	cmpi.l	#1600,d6  ;allow 1600 bytes for DOS
	blt.s	stoosmall
	move.l	d6,d0
	moveq	#1,d1   
	bsr	iwantmem 
	beq.s	stoobig   
	move.l	d0,a1   
	move.l	d6,d0   
	bsr	givemem  
	
	asr.l	#2,d6
	move.l	d6,cli_DefaultStack(a4)
	moveq	#RETURN_OK,d0
	rts
stoosmall	lea	stk_too_small_tx(pc),a0
	moveq	#RETURN_ERROR,d0
	bra	new_print
stoobig	lea	stk_too_big_tx(pc),a0
	moveq	#RETURN_ERROR,d0
	bra	new_print
show_stack
	move.l	d7,-(sp)
	lea	(sp),a1
	lea	stk_size_tx(pc),a0
	bsr	new_print
	move.l	(sp)+,d0
	moveq	#RETURN_OK,d0
	rts

** CHECK STRING A0 IF ENDING IN :
** RETURN EQ IF DOES END IN COLON
check_for_colon
.A	tst.b	(a0)+	MAKE SURE ENDS IN :
	bne.s	.A
	move.b	-2(a0),d0
	cmp.b	#':',d0
	rts

do_forbid	move.l	4.w,a6
	jsr	_LVOForbid(a6)
	move.l	dosbase(a5),a6
	rts
do_permit	move.l	4.w,a6
	jsr	_LVOPermit(a6)
	move.l	dosbase(a5),a6
	rts
	
*************************
*	ASSIGN 		*
*************************
assignz	bsr	do_forbid		FORBID
	bsr	get_first_devinfo
	tst.l	parm2(a5)
	beq	show_assigns
	tst.l	parm3(a5)
	beq	exit_assignf	ONLY TWO PARMS TYPED (NEED 3)
	move.l	parm2(a5),a0
	bsr	check_for_colon
	beq	.B
	bsr	do_permit
	lea	no_colon_tx(pc),a1
	bsr	pr_string
	moveq	#RETURN_ERROR,d0
	rts
	
.B	moveq	#dt_dir,d1	CREATE/MODIFY ASSIGN ******
	bsr	find_next_assign
	tst.l	d0
	bne	no_more_dir_assigns
	move.l	a0,d5
	move.l	parm2(a5),a0	A0=assigned name[0]
	moveq	#0,d2
	move.b	(a1)+,d2		get char count
.A	move.b	(a1)+,d0
	move.b	(a0)+,d1
	beq.s	.B
	subq.l	#1,d2
	bmi.s	.C
	bsr	compD1D0nocase
	beq.s	.A
.D	bra.s	.B

.C	cmp.b	#':',d1	CHANGE EXISTING
	bne.s	.D
	bsr	do_permit		PERMIT
	move.l	d5,a2		GOT A MATCH
	moveq	#ACCESS_READ,d2
	move.l	parm3(a5),d1
	jsr	_LVOLock(a6)
	tst.l	d0
	beq	exit_assignp
	move.l	d0,a3
	bsr	do_forbid		FORBID
	move.l	dvi_Lock(a2),d4
	move.l	a3,dvi_Lock(a2)	new lock
	add.l	a3,a3
	add.l	a3,a3
	move.l	fl_Task(a3),dvi_Task(a2)
	clr.l	dvi_Handler(a2)
	clr.l	dvi_StackSize(a2)
	clr.l	dvi_Priority(a2)
	clr.l	dvi_Startup(a2)
	clr.l	dvi_SegList(a2)
	clr.l	dvi_GlobVec(a2)
	bsr	do_permit
	move.l	d4,d1
	jsr	_LVOUnLock(a6)
	bra	exit_assignp
	
no_more_dir_assigns
	bsr	do_permit		CREATE NEW ASSIGN
	moveq	#48,d0
	move.l	#MEMF_CLEAR+1,d1
	bsr	iwantmem
	beq	exit_assignp
	move.l	d0,a4
	move.l	#48,(a4)+		save size byte
	move.l	parm2(a5),a0
	moveq	#4,d0	4+1 extra bytes for dos(nb: : is ignored)
.A	addq.l	#1,d0
	tst.b	(a0)+
	bne.s	.A
	move.l	d0,d3	D3=size+5+1	(block size|char_count|chars)
	moveq	#1,d1
	bsr	iwantmem
	beq	rem_dvi
	move.l	d0,a3
	move.l	d0,d4		D4=string ptr
	move.l	d3,(a3)+		save size byte
	subq.l	#6,d3
	move.b	d3,(a3)+		save char_count
	move.l	parm2(a5),a0
	bra.s	.C
.B	move.b	d1,(a3)+		copy string to NAME
.C	move.b	(a0)+,d1
	cmp.b	#':',d1
	bne.s	.B
	clr.b	(a3)		;NULL-ending V2.0
	addq.l	#4,d0
	lsr.l	#2,d0	convert to bstr
	move.l	d0,dvi_Name(a4)
	move.l	#dt_dir,dvi_Type(a4)
	moveq	#ACCESS_READ,d2
	move.l	parm3(a5),d1
	jsr	_LVOLock(a6)
	tst.l	d0
	beq	rem_str
	move.l	d0,dvi_Lock(a4)
	asl.l	#2,d0		x 4
	move.l	d0,a0
	move.l	fl_Task(a0),dvi_Task(a4)
	bsr	do_forbid
	bsr	get_first_devinfo	RETURNS A1 pts info substr, A2 pts 1st devinfo
	move.l	a2,dvi_Next(a4)
	move.l	a4,d0
	lsr.l	#2,d0
	move.l	d0,di_DevInfo(a1)	Insert new top of chain
	bsr	do_permit
	
	bra.s	exit_assignp
rem_str	move.l	d4,a1
	move.l	(a1),d0
	bsr	givemem
rem_dvi	lea	-4(a4),a1
	moveq	#48,d0
	bsr	givemem
exit_assignp
	moveq	#RETURN_OK,d0
	rts
exit_assignf
	bsr	do_permit
	moveq	#RETURN_OK,d0
	rts
	
* SHOW ASSIGNS	ALREADY IN FORBID STATE
show_assigns
	lea	-8(sp),sp
	move.l	a2,(sp)		0(sp)= BPTR of first devinfo
	move.l	#1024,d0
	moveq	#1,d1
	bsr	iwantmem		allocate big block
	beq	asg_fail
	move.l	d0,a4		A4 = string block
	move.l	d0,4(sp)		4(sp) = string block
	lea	volume_tx(pc),a0	PRINT VOLUMES:
	bsr	copy_name
	moveq	#dt_volume,d1
do_volumes
.E	bsr	find_next_assign	COPY ALL DEVICES THAT MATCH TYPE IN D1
	tst.l	d0		 TO THE BIG STRING
	bne.s	do_devices
	bsr	copy_bstr
	move.b	#$20,(a4)+	seperate with spaces
	tst.l	dvi_Task(a0)
	beq.s	.H
	lea	mounted_tx(pc),a0
	bsr	copy_name
.H	move.b	#$0a,(a4)+
	bra.s	.E
do_devices	
	move.l	(sp),a2		restart at first devinfo
	lea	device_tx(pc),a0	PRINT DEVICES:
	bsr	copy_name
	moveq	#dt_device,d1
	bsr	store_mult_entries
	move.l	(sp),a2
do_dirs
	lea	assign_tx(pc),a0	PRINT DIRECTORIES
	bsr	copy_name
	move.l	#-1,-(sp)		PUSH NEGATIVE ON STACK
.B	moveq	#dt_dir,d1
	bsr	find_next_assign	COPY ALL DEVICES THAT MATCH TYPE IN D1
	tst.l	d0		 TO THE BIG STRING
	bne.s	get_nxt_lock
	lea	-38(sp),sp	ALLOW 38 BYTES FOR STRING
	move.l	dvi_Lock(a0),-(sp)	push lock
	lea	4(sp),a0
	move.b	(a1)+,d0
	bra.s	.J
.H	move.b	(a1)+,(a0)+	copy name onto stack
.J	dbra	d0,.H
	clr.b	(a0)+
	bra.s	.B

get_nxt_lock
	move.l	(sp)+,d1		get lock
	bmi	.A
	lea	(sp),a0
.F	move.b	(a0)+,(a4)+	copy name to store
	bne.s	.F
	lea	38(sp),sp
	move.b	#$9,-1(a4)
	tst.l	d1
	beq	.C		no lock
	move.l	d1,a0
	add.l	a0,a0
	add.l	a0,a0
	move.l	fl_Volume(a0),a0
	add.l	a0,a0
	add.l	a0,a0
	tst.l	dvi_Task(a0)
	bne.s	.E
	lea	unmounted_tx(pc),a0
	bsr	copy_name
	bra.s	get_nxt_lock
.E	bsr	do_permit
	jsr	_LVODupLock(a6)	copy lock(D1) --> (D0)
	move.l	a4,a0
	bsr	eval_full_path
	jsr	_LVOUnLock(a6)
	bsr	do_forbid
.D	tst.b	(a4)+
	bne.s	.D
.C	move.b	#$0a,-1(a4)	overwrite null or tab
	bra.s	get_nxt_lock
.A	move.b	#$0a,(a4)+	linefeed at end

	clr.b	(a4)+
	bsr	do_permit
	move.l	4(sp),a1
	bsr	pr_string
	move.l	4(sp),a1
	move.l	#1024,d0
	bsr	givemem
	bra.s	asg_fail2
asg_fail	bsr	do_permit
asg_fail2	lea	8(sp),sp
	moveq	#RETURN_OK,d0
	rts


store_mult_entries
.B	bsr	find_next_assign	COPY ALL DEVICES THAT MATCH TYPE IN D1
	tst.l	d0		 TO THE BIG STRING
	bne.s	.A
	bsr	copy_bstr
	move.b	#$20,(a4)+	seperate with spaces
	move.b	#$20,(a4)+
	bra.s	.B
.A	move.b	#$0a,(a4)+	linefeed at end
	rts

get_first_devinfo
	move.l	dl_Root(a6),a1
	move.l	rn_Info(a1),a1
	add.l	a1,a1
	add.l	a1,a1
	move.l	di_DevInfo(a1),a2	A2=BPTR to first devinfo
	rts

copy_name	move.b	(a0)+,(a4)+
	bne.s	copy_name
	lea	-1(a4),a4
	rts

**COPY BSTR FROM A1 TO A4, DONT NULL END
copy_bstr	move.b	(a1)+,d0
	bra.s	.C
.B	move.b	(a1)+,(a4)+
.C	dbra	d0,.B
	rts
	
**ENTRY: D1=type ,A2=Bptr of devinfo, EXIT: A2=Bptr to next ,D0=0 if found
**EXIT: D2=lock, D1=type, A1 pts to string, A0 pts devinfo struct
find_next_assign
.A	add.l	a2,a2	FIND NEXT DEVINFO THAT MATCHES THE TYPE (D1)
	add.l	a2,a2		A2 pts to first devinfo structure
	move.l	a2,d0		tst.l	(a2)
	beq.s	.B
	move.l	a2,a0
	move.l	dvi_Name(a2),a1
	move.l	dvi_Lock(a2),d2
	move.l	dvi_Type(a2),d0
	move.l	(a2),a2
	cmp.l	d0,d1
	bne.s	.A
	add.l	a1,a1
	add.l	a1,a1
	moveq	#0,d0
	rts
.B	moveq	#1,d0
	rts

bad_number_error
	move.l	a1,-(sp)
	lea	bad_number_tx(pc),a1
	bsr	pr_stringlf
	move.l	(sp)+,a1
	moveq	#RETURN_ERROR,D0
	rts

*************************
*	FAILAT 		*
*************************
failatz	tst.l	parm2(a5)
	beq.s	show_failat
	move.l	parm2(a5),a1
	bsr	convert_ASCII_to_num
	bne.s	failat_OK
	bra	bad_number_error
failat_OK	move.w	d0,failat_level(a5)
	moveq	#RETURN_OK,d0
	RTS
show_failat
	lea	failat_level(a5),a1
	lea	failat_tx(pc),a0
	bsr	new_print
	moveq	#RETURN_OK,d0
	rts

*************************
*	IF 		*
*************************
ifz	move.b	#$ff,if_flag(a5)
	move.b	#$ff,if_condition_flag(a5)	set FALSE
	lea	parm2(a5),a4
	moveq	#0,d4		not state
.C	move.l	(a4)+,d0
	beq	if_fail
	move.l	d0,a0
	lea	not_tx(pc),a1
	bsr	compare_strings
	bne.s	.B
	not.b	d4		set D4=FF if not
	bra	.C
.B	lea	exists_tx(pc),a1
	bsr	compare_strings
	bne.s	try_warn	IF NOT AN EXISTS TYPE COMPARE
	move.l	(a4)+,d1
	beq	if_fail
	moveq	#0,d3		d3=0	doesnt exist
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	tst.l	d0
	beq.s	save_state
	move.l	d0,d1
	jsr	_LVOUnLock(a6)
	not.b	d3		d3=ff	exists
save_state
	not.b	d3		d3=0	true
	eor.b	d4,d3
	move.b	d3,if_condition_flag(a5)
	moveq	#RETURN_OK,D0
	RTS
try_warn	move.l	last_failcode(a5),d5
	moveq	#RETURN_WARN,d6
	lea	warn_tx(pc),a1	CHECK IF 'IF WARN'
	bsr	compare_strings
	bne	try_error
set_error_state
	moveq	#0,d3
	cmp.l	d6,d5
	bne	save_state
	not.b	d3
	bra	save_state
try_error	lea	error_tx(pc),a1
	bsr	compare_strings
	bne	try_fail
	moveq	#RETURN_ERROR,d6
	bra	set_error_state
try_fail	lea	fail_tx(pc),a1
	bsr	compare_strings
	bne	if_fail
	moveq	#RETURN_FAIL,d6
	bra	set_error_state
if_fail	not.b	if_flag(a5)	clear it
	lea	if_error_tx(pc),a1
	bsr	pr_string
	MOVEQ	#RETURN_ERROR,D0
	RTS

*************************
*	ASK 		*
*************************
askz	bsr	echo_parm		print the parm same as echo does
rask	bsr	raw_off
	move.l	inhandle(a5),d1
	beq.s	.A
	lea	tempbuf(a5),a4	a4:tempbuf
	clr.b	(a4)
	move.l	a4,d2
	moveq	#120,d3
	jsr	_LVORead(a6)	read input
	tst.l	d0
	bmi.s	.A
	beq.s	.A
	move.l	outhandle(a5),d1
	cmp.l	stdout(a5),d1	output redirected ?
	beq.s	.C
	move.l	a4,a0
	add.l	d0,a0
	subq.l	#1,a0
	clr.b	(a0)	Null-End
	move.l	a4,a1
	bsr	pr_string	repeat input
	bra	.A
.C	or.b	#$20,(a4)
	moveq	#RETURN_FAIL,d0
	cmp.b	#'f',(a4)	V2.0
	beq	.B
	moveq	#RETURN_ERROR,d0
	cmp.b	#'e',(a4)	V2.0
	beq	.B
	moveq	#RETURN_WARN,d0
	cmp.b	#'j',(a4)	V2.0
	beq	.B
	cmp.b	#'y',(a4)
	beq	.B
.A	moveq	#RETURN_OK,D0
.B	rts

*************************
*	WAIT 		*
*************************
waitz	move.l	parm2(a5),d0
	beq	too_less_args
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	move.l	d0,d4
	lsl.l	#2,d4		d4*4
	add.l	d0,d4		d4:=d0*5 (d4*4+d4)
.C	bsr	check_c
	bne.s	.E
	moveq	#10,d1		1/5 second
	jsr	_LVODelay(a6)
	subq.l	#1,d4
	bne.s	.C
.E	moveq	#RETURN_OK,D0
	RTS

*************************
*	QUIT 		*
*************************
* only returns from script files.
quitz	tst.b	scflag(a5)
	bne.s	.A
	moveq	#RETURN_OK,D0
	RTS
.A	move.l	parm2(a5),d0
	beq	.B
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	bne	.B
	bsr	bad_number_error
.B	move.l	d0,-(sp)
	bsr	kill_script	guarantee that script is dead
	move.l	(sp)+,d0
	rts
	
*************************
*	JOIN 		*
*************************
joinz	lea	parm2(a5),a4
	move.l	a4,a3
	tst.l	4(a3)	must have at least 2 parameters
	beq	too_less_args
.A	tst.l	(a3)+		FIND LAST PARAMETER
	bne.s	.A
	lea	-8(a3),a3		A3=last parm ie the write file
	move.l	(a3),d1
	move.l	#MODE_NEWFILE,D2
	jsr	_LVOOpen(a6)
	tst.l	d0
	beq	DOSjoin_failure
	move.l	d0,please_close_me(a5)	write handle
	
.B	cmp.l	a4,a3
	beq	finish_join
	move.l	(a4)+,a0
	bsr	readfile
	move.l	d0,d2
	move.l	d0,d5	D5=addr
	move.l	d1,d3
	move.l	d1,d6	D6=size
	move.l	please_close_me(a5),d1
	jsr	_LVOWrite(a6)
	tst.l	d0
	bmi	DOSjoin_failure3
	bsr	free_joiner
	bra	.B
finish_join
	bsr	close_the_joined
	moveq	#RETURN_OK,D0
	RTS
	
DOSjoin_failure3
	bsr	free_joiner		dealloc readfile
	bsr	close_the_joined
DOSjoin_failure
	bra	DOSerr

free_joiner
	move.l	d5,a1
	move.l	d6,d0
	bra	givemem		dealloc readfile

close_the_joined
	move.l	please_close_me(a5),d1
	jsr	_LVOClose(a6)	close write file
	clr.l	please_close_me(a5)
	rts

*************************
*	HTYPE 		*
*************************
htypez	move.l	parm2(a5),d1
	beq	too_less_args
	move.l	d1,a0
	bsr	readfile
	move.l	d0,mem_addr(a5)
	move.l	d0,mem_offset_addr(a5)
	move.l	d1,temp1(a5)
	add.l	d0,d1
	move.l	d1,d7		end marker
	bsr	rawh_off
.B	bsr	check_c
	bne	htype_end
	bsr	show_16_locs
	cmp.l	mem_addr(a5),d7
	bhi	.B
htype_end	move.l	mem_offset_addr(a5),a1
	move.l	temp1(a5),d0
	bsr	givemem
	moveq	#RETURN_OK,D0
	RTS

*************************
*	STRINGS 	*
*************************
stringsz	move.l	parm2(a5),d0
	beq	too_less_args
	moveq	#7,d7		default 7
	move.l	parm3(a5),d0
	beq.s	.B
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	
	move.l	d0,d7		D7=min_string
.B	move.l	parm2(a5),a0
	bsr	readfile
	move.l	d0,a4		A4=addr of file
	move.l	a4,a3
	move.l	d1,d6		D6=size of file
	add.l	d0,d1
	move.l	d1,d4		D4=max addr
	movem.l	d4-d7/a3-a4,-(sp)
	bsr	rawh_off
	movem.l	(sp)+,d4-d7/a3-a4
str_next	bsr	check_c
	bne	kill_string_file
	moveq	#0,d5		D5=current string size
	move.l	a3,a2
valid_ch	cmp.l	a3,d4
	beq	string_fin
	move.b	(a3)+,d0
	cmp.b	#' ',d0
	blo.s	not_valid_char
	cmp.b	#$7f,d0
	bhi.s	not_valid_char
	addq.l	#1,d5
	bra	valid_ch
not_valid_char
	cmp.l	d7,d5
	blo	str_next
	bsr	write_my_string
	bra	str_next

string_fin
	cmp.l	d7,d5
	blo	kill_string_file
	bsr	write_my_string
kill_string_file
	move.l	a4,a1
	move.l	d6,d0
	bsr	givemem
	moveq	#RETURN_OK,D0
	RTS
	
write_my_string
	move.l	outhandle(a5),d1
	beq.s	.A
	move.l	a2,d2
	move.l	d5,d3
	jsr	_LVOWrite(a6)
.A	bra	pr_lf

*************************
*	FILENOTE	*
*************************
filenotez bsr	fixpam32		V2.0
	move.l	a0,d1
	move.l	a1,d2
	move.l	a1,a2
	moveq	#78,d0
.A	tst.b	(a2)+
	beq.s	fnok
	dbra	d0,.A
	moveq	#RETURN_ERROR,d0	;more than 80 chars
	rts
fnok	jsr	_LVOSetComment(a6)
	addq.l	#1,d0
	bne	DOSerr
	rts

*************************
*	SEARCH		*	Searches a string in a file
*************************
searchz	bsr	rawh_off		V2.0
	bsr	fixpam32
	tst.b	(a1)
	beq	too_less_args
	move.l	a1,d7
	bsr	readfile	get file
	move.l	d1,d5		push size
	move.l	d0,d6
	add.l	d1,d6
	move.l	d0,a2
	move.l	d0,a3		a3:start of file
.A	move.l	d7,a1		d7:search string
	move.l	d6,a0		d6:end of file
	bsr	searchSTR	a2:current searchpos
	cmp.b	#1,d0
	beq.s	.B
	move.l	a0,-(sp)
	move.l	d7,a0
	moveq	#-1,d4
.D	addq.l	#1,d4
	tst.b	(a0)+		length of searchstr.
	bne.s	.D
	move.l	a1,d2
	move.l	a2,d3
	sub.l	d2,d3
	beq.s	.C
	move.l	outhandle(a5),d1
	jsr	_LVOWrite(a6)	write part before searchstr.
.C	lea	farb3(pc),a1
	bsr	pr_string
	move.l	a2,d2
	move.l	d4,d3
	move.l	outhandle(a5),d1
	jsr	_LVOWrite(a6)	write searchstr.
	lea	farb1(pc),a1
	bsr	pr_string
	move.l	(sp)+,a0
	move.l	a2,d2
	add.l	d4,d2
	move.l	a0,d3
	sub.l	d2,d3
	beq.s	.E
	move.l	outhandle(a5),d1
	jsr	_LVOWrite(a6)	write part after searchstr.
.E	bsr	pr_lf
	addq.l	#1,a2
	bsr	check_c
	beq.s	.A
.B	move.l	d5,d0
	move.l	a3,a1
	bsr	givemem		free file
endse	moveq	#RETURN_OK,d0
	rts

* Searches for a string
* ENTRY:a1 points to the string to search for (ends in NULL)
* 	a2 points to start position, a0 to end of file, a3 to start
* EXIT: a2  to found-position, a0 to NULL- or LF-end, a1 to LF-start
*	d0=1 not found, d0= found NULL-ended, d0=10 found LF-ended
searchSTR
	movem.l	d1-d3/a3-a4,-(sp)
	move.b	(a1),d0
	cmp.b	ctrl_codes+13(a5),d0
	bne.s	.I
	move.b	#10,(a1)	begins with LineFeed
.I	move.l	a3,d3
	moveq	#0,d0
	moveq	#1,d2
.A	move.b	(a1),d0
	cmp.l	a0,a2
	bhi	.E
	move.b	(a2)+,d1
	bsr	compD1D0nocase	search first char
	bne.s	.A
	move.l	a1,a3
	addq.l	#1,a3
	move.l	a2,a4
.B	move.b	(a3)+,d0
	beq.s	.C
	cmp.l	a0,a4
	bhi	.E
	move.b	(a4)+,d1
	bsr	compD1D0nocase	compare other chars
	bne.s	.A
	bra.s	.B
.C	subq.l	#1,a2
	move.l	a2,a1
.D	cmp.l	a0,a4
	bhi	.E
	move.b	(a4)+,d1	search end
	beq.s	.G
	cmp.b	#10,d1
	bne.s	.D
	cmp.b	#10,(a1)
	beq.s	.H
.F	cmp.l	d3,a1
	bls	.G
	move.b	-(a1),d0
	beq.s	.H
	cmp.b	#10,d0		search beginning (if LF)
	bne.s	.F
.H	addq.l	#1,a1
.G	move.b	d1,d2
	lea	-1(a4),a0
.E	move.l	d2,d0
	movem.l	(sp)+,d1-d3/a3-a4
	rts


*****************
*	FAULT	*
*****************
faultz	move.l	parm2(a5),d0			V2.0
	beq	too_less_args
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	bsr	pr_DOSerr
.A	moveq	#RETURN_OK,d0
	rts

*************************
*	SETCLOCK	*
*************************
setclockz lea	$dc0000,a4	;clockbase	V2.0
	move.b	1(a4),d4
	moveq	#75,d1
	jsr	_LVODelay(a6)
	cmp.b	1(a4),d4	;secs changed ?
	beq.s	noclk
	move.l parm2(a5),a0
	move.b	(a0),d0
	bset.l	#5,d0
	cmp.b	#"l",d0
	beq	clkload
	cmp.b	#"s",d0
	beq.s	clksave
	lea	clk_tx(pc),a1
	bsr	pr_stringlf
uu	moveq	#RETURN_ERROR,d0
	rts
noclk	lea	noclk_tx(pc),a1
	bsr	pr_stringlf
	bra.s	uu

clksave	lea	date_mark(a5),a2
	move.l	a2,a0
	bsr	get_time
	move.l	a2,a1
	lea	-14(sp),sp
	lea	(sp),a0
	bsr	convert_time
	move.b	61(a4),d0	;reset clock
	or.b	#1,d0		;(don't use bset or bclr !)
	move.b	d0,61(a4)
	move.b	#0,57(a4)
	move.b	#5,61(a4)
	move.b	#4,61(a4)
	move.b	53(a4),d0	;hold clock
	or.b	#1,d0
	move.b	d0,53(a4)
clks	btst	#1,53(a4)
	bne.s	clks
	lea	(sp),a0
	lea	chaotab(pc),a1
	moveq	#1,d6
	moveq	#0,d1
	moveq	#5,d0
.A	move.b	(a1)+,d1
	moveq	#0,d2
	move.w	0(a0,d1),d2
	divu	#10,d2
	swap	d2
	move.b	d2,0(a4,d6)
	swap	d2
	move.b	d2,4(a4,d6)
	addq.l	#8,d6
	dbra	d0,.A
	move.b	53(a4),d0
	and.b	#$0e,d0
	move.b	d0,53(a4)	;run clock
	lea	14(sp),sp
	moveq	#RETURN_OK,d0
	rts

chaotab	dc.b	10,8,6,0,2,4

getclk	move.b	0(a4,d6),d1	;Read realtimeclock
	move.b	4(a4,d6),d0	;(adress in a4,offset in d6)
	addq.l	#8,d6
	and.w	#$f,d0
	and.w	#$f,d1
	mulu	#10,d0
	add.w	d1,d0
	ext.l	d0	;result
	rts

		;load current time from realtime-clock
clkload	move.b	53(a4),d0
	or.b	#1,d0
	move.b	d0,53(a4)
clkw	btst	#1,53(a4)
	bne.s	clkw
	lea	-6(sp),sp
	lea	(sp),a3
	moveq	#5,d2
	moveq	#1,d6
.A	bsr	getclk
	move.b	d0,(a3)+
	dbra	d2,.A
	lea	(sp),a3
	bsr	calcsec		;how many secs ?
	move.b	53(a4),d0
	and.b	#$0e,d0
	move.b	d0,53(a4)
	lea	6(sp),sp
	bsr	tset		;give it to system
	moveq	#RETURN_OK,d0
	rts

calcsec	moveq	#0,d7		;a3->points to 6 bytes of date/time
	moveq	#1,d6					V2.0
	move.b	(a3)+,d7	;sec (collect secs in d7)
	moveq	#0,d0
	move.b	(a3)+,d0	;min
	mulu	#smin,d0
	add.l	d0,d7
	moveq	#0,d0
	move.b	(a3)+,d0	;std
	mulu	#sst,d0
	add.l	d0,d7
	moveq	#0,d0
	move.b	(a3)+,d0	;tag
	subq.l	#1,d0
	move.l	d0,d5		;collect days in d5
	moveq	#0,d2
	move.b	(a3)+,d2	;monat
	lea	montab(pc),a0
	moveq	#0,d3
	move.b	(a3)+,d3	;jahr
	move.l	d3,d0
	and.w	#3,d0
	bne.s	nosj
	move.b	#29,1(a0)	;change montab
nosj	subq.l	#2,d2
	bmi.s	jan
madd	moveq	#0,d0
	move.b	0(a0,d2),d0
	add.w	d0,d5
	dbra	d2,madd
jan	cmp.b	#78,d3
	beq.s	tset
	subq.l	#1,d3
	moveq	#0,d1
jadd	add.w	#tjahr,d5
	move.l	d3,d0
	and.w	#3,d0
	bne.s	nosj2
	addq.l	#1,d5
nosj2	cmp.b	#78,d3
	dbeq	d3,jadd
	move.b	#28,1(a0)
	move.l	#stag,d1
	move.l	d5,d0
	bsr	mult_32x32
	move.l	d7,d6		;d6=secs, d5=days
	add.l	d0,d7		;d7=all seconds since 1.1.78
	rts

clrio	lea	io_Message(a5),a1	;initialisiert IO-Request  V2.0
	move.l	a1,a0
	moveq	#$2f,d0
clst3	clr.b	(a0)+
	dbra	d0,clst3
	move.b	#5,io_Message+8(a5)
	move.l	thistask(a5),a0
	lea	pr_MsgPort(a0),a0
	move.l	a0,io_Message+14(a5)
	move.w	#$30,io_Message+18(a5)
	rts		;a1:IO-Request a0:Msg-Port

tset	move.l	4.w,a6		;set time with timer-device (secs in d7)
	bsr	clrio				V2.0
	move.w	#40,io_Message+18(a5)
	lea	timdev(pc),a0
	moveq	#1,d0
	moveq	#0,d1
	jsr	_LVOOpenDev(a6)
	tst.l	d0
	bne	tmfehl
	lea	io_Message(a5),a1
	move.w	#11,io_Command(a5)
	clr.w	io_Flags(a5)
	move.l	d7,tv_secs(a5)
	clr.l	tv_micro(a5)
	jsr	_LVODoIO(a6)
	tst.l	d0
;	bne.s	tmfehl	;better leave out
	lea	io_Message(a5),a1
	clr.l	io_Command(a5)
	jsr	_LVOCloseDev(a6)
tmfehl	move.l	dosbase(a5),a6
	rts

smin	equ	60
sst	equ	60*smin
stag	equ	24*sst
tjahr	equ	365


*************************
*	SHOW		*
*************************
showz	bsr	rawh_off			V2.0
	move.l	parm2(a5),d0
	beq	sdft
	move.l	d0,a0
	move.b	(a0),d1
	bset	#5,d1
	cmp.b	#"t",d1
	beq	shtask
	lea	styp(pc),a0
	moveq	#6,d0	;7 Lists
.D	cmp.b	0(a0,d0.w),d1
	dbeq	d0,.D
	move.w	d0,d7
	bmi	sdft
	lea	show_tx(pc),a1
	cmp.w	#2,d7
	bhi.s	.C
	lea	show2_tx(pc),a1
.C	bsr	pr_stringlf
	bsr	do_forbid
	add.w	d0,d0
	lea	soffs(pc),a0
	move.w	0(a0,d0.w),d0
	move.l	4.w,a4
	move.l	0(a4,d0.w),a1
;	move.l	8(a4,d0.w),a2
	lea	tempbuf(a5),a3
.A	tst.l	(a1)
	beq.s	.B
	move.l	a1,(a3)+
	move.l	(a1),a1
	bra.s	.A
.B	clr.l	(a3)
	bsr	do_permit
	lea	tempbuf(a5),a3
da	tst.l	(a3)
	beq	sdf
	move.l	(a3)+,a2
	move.l	10(a2),-(sp)
	lea	shform(pc),a0
	cmp.w	#2,d7
	bhi.s	.E
	lea	shform2(pc),a0
	move.w	22(a2),-(sp)
	move.w	20(a2),-(sp)
.E	move.b	9(a2),d0
	ext.w	d0
	move.w	d0,-(sp)
	move.l	a2,-(sp)
	lea	(sp),a1
	bsr	new_print
	lea	10(sp),sp
	cmp.w	#2,d7
	bhi.s	da
	addq.l	#4,sp
	bra.s	da
sdft	lea	shuse_tx(pc),a1
	bsr	pr_stringlf
	moveq	#RETURN_BAD,d0
	rts
sdf	moveq	#RETURN_OK,d0
	rts

shtask	lea	tempbuf(a5),a3	;enough for 96 tasks
	move.l	4.w,a6
	jsr	_LVOForbid(a6)
	lea	420(a6),a0
	move.l	(a0),a1
.A	tst.l	(a1)
	beq.s	.B
	move.l	a1,(a3)+
	move.l	(a1),a1
	bra.s	.A
.B	lea	406(a6),a0
	move.l	(a0),a1
.C	tst.l	(a1)
	beq.s	.D
	move.l	a1,(a3)+
	move.l	(a1),a1
	bra.s	.C
.D	move.l	276(a6),(a3)+
	clr.l	(a3)
	jsr	_LVOPermit(a6)
	move.l	dosbase(a5),a6
	lea	shta_tx(pc),a1
	bsr	pr_stringlf
	lea	tempbuf(a5),a3
prsht	move.l	(a3)+,a2
	move.l	10(a2),-(sp)
	move.l	pr_MsgPort+MP_SIGTASK(a2),a4
	move.l	#$00540061,d0	;Task
	cmp.l	a4,a2
	bne.s	.C
	sub.l	a4,a4		clear a4
	move.l	#$0054006d,d0	;Task with Message-Port
	move.l	pr_CLI(a2),d1
	beq.s	.D
	lsl.l	#2,d1
	move.l	d1,a0
	move.l	cli_DefaultStack(a0),d2
	lsl.l	#2,d2
	move.l	62(a2),d1		;62:tc_SPUpper
	sub.l	58(a2),d1
	cmp.l	d1,d2
	beq.s	.I
.D	move.l	pr_StackBase(a2),d1
	lsl.l	#2,d1
	cmp.l	58(a2),d1		;58:tc_SPLower
	bne.s	.C
	move.l	62(a2),d1		;62:tc_SPUpper
	sub.l	58(a2),d1
	cmp.l	pr_StackSize(a2),d1
	bne.s	.C
.I	move.l	a2,a4
	move.l	#$00500072,d0	;Process
.C	move.w	d0,-(sp)
	swap	d0
	move.w	d0,-(sp)
	move.l	tc_SigWait(a2),-(sp)
	moveq	#0,d0
	move.b	tc_State(a2),d0
	lea	ttyp(pc),a0
	bra.s	.A
.B	tst.b	(a0)+
	bne.s	.B
.A	dbra	d0,.B
	move.l	a0,-(sp)
	move.b	LN_PRI(a2),d0
	ext.w	d0
	move.w	d0,-(sp)
	move.l	a2,-(sp)
	lea	(sp),a1
	lea	shtaform(pc),a0
	bsr	new_print		;Print it
	lea	22(sp),sp
	cmp.l	a4,a2
	bne.s	snocli
	move.l	pr_TaskNum(a2),d0
	cmp.l	#60,d0
;	bhi.s	snocli
	move.l	pr_CLI(a2),d1
	beq.s	snocli
	lsl.l	#2,d1	;cli-process
	move.l	d1,a0
	tst.l	cli_CommandName(a0)
	bne.s	.G
	lea	null(pc),a1
	move.l	a1,-(sp)
	bra.s	.H
.G	move.l	cli_CommandName(a0),a0
	add.l	a0,a0
	add.l	a0,a0
	lea	temp2buf(a5),a1		;BSTR
	move.l	a1,-(sp)
	moveq	#0,d1
	move.b	(a0)+,d1
	bra.s	.E
.F	move.b	(a0)+,(a1)+
.E	dbra	d1,.F
	clr.b	(a1)
.H	move.l	d0,-(sp)
	lea	proform(pc),a0
	lea	(sp),a1
	bsr	new_print		;Print CLI-Add
	lea	8(sp),sp
snocli	bsr	pr_lf
	tst.l	(a3)
	bne	prsht	;at least one task
	move.l	d6,d0
shtok	moveq	#RETURN_OK,D0
	rts

soffs	dc.w	378,336,350,364,322,392,532


*************************
*	MemClock	*	V2.0
*************************

ckstackSIZE	equ	2000
cktask	equ	0		;Task-Struct
ckport	equ	cktask+92	;MsgPort
ckstack	equ	ckport+34	;Stack
ckustack equ	ckstack+ckstackSIZE
ckdos	equ	ckustack	;DOSBase
ckint	equ	ckdos+4		;Intuitionbase
ckitxt	equ	ckint+4		;IntuiTextStruct
ckdate	equ	ckitxt+20	;DateStamp
ckrawdo	equ	ckdate+12	;DataStream
ckcook	equ	ckrawdo+6+8	;Formatted String
ckrast	equ	ckcook+40	;Rastports of all Windows
cknum	equ	ckrast+20*4	;Number of Windows
ckalarm	equ	cknum+4		;Alarm-Time
ckpad	equ	ckalarm+8
cksize	equ	ckpad+2

mlnode	equ	0		;Memory-List
mlnum	equ	mlnode+14
mladdr	equ	mlnum+2
mllen	equ	mladdr+4
mlsize	equ	mllen+4

memclkz	move.l	parm2(a5),a0
	move.l	a0,d0
	beq.s	.A
	move.b	(a0),d0
	bset	#5,d0
	cmp.b	#"a",d0	;alarm
	beq	clkalm
	move.b	1(a0),d0
	bset	#5,d0
	cmp.b	#"n",d0	;oN
	beq	clkon
	cmp.b	#"f",d0	;oFF
	beq	clkoff
.A	lea	clkuse(pc),a1
	bsr	pr_stringlf
	moveq	#RETURN_BAD,d0
	rts

clkon	move.l	4.w,a6		;switch it on
	lea	clktask(pc),a1
	jsr	_LVOFindTask(a6)
	move.l	d0,a4
	tst.l	d0
	beq.s	.A	;not already running
	bsr	winclk
	move.l	dosbase(a5),a6
.B	moveq	#RETURN_OK,d0
	rts
.A	move.l	#cksize,d0
	move.l	#1+1<<16,d1
	jsr	_LVOAllocMem(a6)
	tst.l	d0
	beq.s	.B
	move.l	d0,a4
	move.w	#$0104,cktask+8(a4)	;type/pri
	lea	clktask(pc),a0
	move.l	a0,cktask+10(a4)	;name
	lea	ckstack(a4),a0
	lea	ckustack(a4),a1
	move.l	a1,cktask+54(a4)	;SPreg
	move.l	a0,cktask+58(a4)	;lowerstack
	move.l	a1,cktask+62(a4)	;upperstack
	move.l	a4,ckport+16(a4)	;sigtask
	lea	ckport+20+4(a4),a0
	move.l	a0,ckport+20(a4)
	lea	ckport+20(a4),a0
	move.l	a0,ckport+20+8(a4)
	move.l	#mlsize,d0
	move.l	#1+1<<16,d1
	jsr	_LVOAllocMem(a6)
	tst.l	d0
	beq.s	.B
	move.l	d0,a2
	moveq	#1,d0
	move.w	d0,mlnum(a2)
	move.l	a4,mladdr(a2)
	move.l	#cksize,mllen(a2)
	lea	mlnode(a2),a0
	lea	cktask+78(a4),a1
	move.l	a0,-4(a1)
	move.l	a0,4(a1)
	move.l	a1,(a0)
	move.l	a1,4(a0)
	move.l	dosbase(a5),ckdos(a4)
	move.l	intuibase(a5),ckint(a4)
	bsr	winclk
	move.l	a4,a1
	lea	clkstart(pc),a2
	moveq	#0,d0
	move.l	d0,a3
	jsr	_LVOAddTask(a6)
	move.l	dosbase(a5),a6
	moveq	#RETURN_OK,d0
	rts

winclk	bsr	findrast	;check if rastport already exists,
	tst.w	d1		;else move rastport in table
	bpl.s	.C
	moveq	#19,d1
.B	tst.l	(a1)+
	dbeq	d1,.B
	bne.s	.C
	move.l	d0,-4(a1)
.C	rts

findrast	move.l	intuibase(a5),a0
	move.l	$34(a0),a0	;active window
	move.l	$32(a0),d0	;rastport
	lea	ckrast(a4),a0
	move.l	a0,a1
	moveq	#19,d1
.A	cmp.l	(a0)+,d0
	dbeq	d1,.A
	rts

clkoff	move.l	4.w,a6		;switch it off
	lea	clktask(pc),a1
	jsr	_LVOFindTask(a6)
	move.l	d0,a4
	tst.l	d0
	beq.s	.A
	bsr	findrast
	tst.w	d1
	bmi.s	.A
	moveq	#0,d0
	move.l	d0,-4(a0)
.A	move.l	dosbase(a5),a6
	moveq	#RETURN_OK,d0
	rts	

clkalm	move.l	4.w,a6		;set alarm-time
	lea	clktask(pc),a1
	jsr	_LVOFindTask(a6)
	move.l	dosbase(a5),a6
	move.l	d0,a4
	tst.l	d0
	beq.s	.A
	tst.l	parm3(a5)
	bne.s	.B
	lea	ckalarm(a4),a1
	bsr	pr_stringlf	show alarm
	bra.s	.A
.B	move.l	parm3(a5),a0
	lea	ckalarm(a4),a1
	moveq	#7,d0
.C	move.b	(a0)+,(a1)+	set alarm
	dbra	d0,.C
.A	moveq	#RETURN_OK,d0
	rts	

clkstart sub.l	a1,a1	;Here starts the MemClockTaskCode !
	move.l	4.w,a6
	jsr	_LVOFindTask(a6)
	move.l	d0,a5
	move.l	#$00010100,ckitxt(a5)
.A	move.l	d5,cknum(a5)	;teststuff
	lea	ckdate(a5),a0
	move.l	a0,d1
	move.l	ckdos(a5),a6
	jsr	_LVODateStamp(a6)
	move.l	ckdate+4(a5),d0		;mins
	divu	#60,d0
	move.w	d0,ckrawdo+8(a5)
	swap	d0
	move.w	d0,ckrawdo+10(a5)
	move.l	ckdate+8(a5),d0		;secs
	divu	#50,d0
	move.w	d0,ckrawdo+12(a5)
	moveq	#2,d1
	move.l	4.w,a6
	jsr	_LVOAvailMem(a6)	;memory
	move.l	d0,ckrawdo+4(a5)
	moveq	#1,d1
	jsr	_LVOAvailMem(a6)
	move.l	d0,ckrawdo+0(a5)
	lea	clkform(pc),a0
	lea	ckrawdo(a5),a1
	lea	KPutChar(pc),a2
	lea	ckcook(a5),a3
	jsr	_LVORawDoFmt(a6)	;rawdofmt
	lea	ckcook+26(a5),a0
	lea	ckalarm(a5),a1
	moveq	#7,d0
.D	move.b	(a0)+,d1
	cmp.b	(a1)+,d1
	bne.s	.E
	dbra	d0,.D
	move.l	ckint(a5),a6
	suba.l	a0,a0
	jsr	_LVODisplayBeep(a6)
.E	lea	ckcook(a5),a0
	move.l	a0,ckitxt+12(a5)
	lea	ckrast(a5),a2
	moveq	#0,d5
	moveq	#19,d4
.B	move.l	(a2)+,a0		;check all 20 Rastports
	move.l	a0,d0
	beq.s	.C
	addq.l	#1,d5
	lea	ckitxt(a5),a1
	moveq	#0,d0
	moveq	#1,d1
	move.l	ckint(a5),a6
	jsr	_LVOPrintIText(a6)
.C	dbra	d4,.B
	moveq	#10,d1
	move.l	ckdos(a5),a6
	jsr	_LVODelay(a6)		;wait 1/5 sec
	tst.l	d5
	bne	.A
	move.l	4.w,a6
	rts


*************************
*	CTRL		*	V2.0
*************************	set or show ctrl-codes
ctrlz	move.l	parm2(a5),d0
	beq.s	.A
	move.l	d0,a0
	bsr	return_dash_option
	cmp.b	#'C',d0		option -COMPLET ?
	beq.s	ctrlcpl
	lea	ctrl_codes(a5),a1
	moveq	#ctrl_inite-ctrl_init-1,d1
.B	move.b	(a0)+,d0
	beq.s	.A
	and.b	#$3f,d0		set ctrl codes
	move.b	d0,(a1)+
	dbra	d1,.B
.A	lea	ctrl_tx(pc),a1	show ctrl codes
	bsr	pr_string
	lea	ctrl_codes(a5),a0
	lea	tempbuf(a5),a1
	move.l	a1,a2
	moveq	#ctrl_inite-ctrl_init-1,d1
.C	move.b	(a0)+,d0
	add.b	#$40,d0
	move.b	d0,(a2)+
	dbra	d1,.C
	clr.b	(a2)
	bsr	pr_stringlf
ctrlend	moveq	#RETURN_OK,d0
	rts

ctrlcpl	lea	ignoreit(a5),a1	set or show exeptions of
	move.l	parm3(a5),d0	filenamecompletition
	beq.s	.A
	move.l	d0,a0
	moveq	#SEARCH_STRING_SIZE-1,d0
.B	move.b	(a0)+,(a1)+
	beq.s	ctrlend
	dbra	d0,.B
	bra.s	ctrlend
.A	bsr	pr_stringlf
	bra.s	ctrlend

*************************
*	Locate		*	V2.0
************************* Show the Path and Filename of a Lock-Struct
locatez			;or lock object or delete lock
	bsr	fixpam32
	move.l	a0,a3
	move.l	a1,a2
	move.l	a0,a1	;parm2
	moveq	#0,d7
	bsr	return_dash_option
	cmp.b	#"C",d0
	bne.s	.F
	moveq	#-1,d7		delete lock after showing
	move.l	a2,a1
.F	bsr	convert_ASCII_to_num
	bne.s	.D
	moveq	#ACCESS_READ,d2
	move.l	a2,a1	;parm3	create lock
	bsr	convert_ASCII_to_num
	beq.s	.E
	move.l	d0,d2
.E	move.l	a3,d1	;parm2
	jsr	_LVOLock(a6)
	tst.l	d0
	beq	.A
.D	move.l	d0,a2		write out name
	move.l	d0,d6
	add.l	a2,a2
	add.l	a2,a2
	moveq	#ACCESS_WRITE,d1
	cmp.l	fl_Access(a2),d1	what kind of lock
	bne.s	.B
	lea	lockwrite(pc),a1
	bra.s	.C
.B	subq.l	#1,d1
	cmp.l	fl_Access(a2),d1
	bne.s	.A
	lea	lockread(pc),a1
.C	lea	-16(sp),sp
	move.l	a1,(sp)
	move.l	fl_Link(a2),12(sp)
	move.l	d6,8(sp)
	move.l	d0,d1
	jsr	_LVODupLock(a6)
	lea	tempbuf(a5),a0
	move.l	a0,4(sp)
	bsr	eval_full_path	evaluate the full name
	jsr	_LVOUnLock(a6)
	move.l	sp,a1
	lea	locktext(pc),a0
	bsr	new_print
	lea	16(sp),sp
	tst.l	d7
	beq.s	.G
	move.l	d6,d1
	jsr	_LVOUnLock(a6)
	lea	deletedtx(pc),a1
	bsr	pr_string
.G	moveq	#RETURN_OK,d0
	rts
.A	lea	lockntx(pc),a1
	bsr	pr_stringlf
lkerr	moveq	#RETURN_ERROR,d0
	rts

*************************
*	NewCLI		*	V2.0
*************************
newcliz	lea	ZShellName(pc),a0
	move.l	a0,d1		process-name
	moveq	#0,d2		priority
	lea	start-4(pc),a0
	move.l	a0,d3		
	lsr.l	#2,d3		seglist
	move.l	#4000,d4	stacksize
	jsr	_LVOCreateProc(a6)
	tst.l	d0
	beq.s	lkerr
	move.l	d0,a4		a4:new process
	moveq	#$24,d0
	move.l	#MEMF_CLEAR+1,d1	memory for Message
	bsr	iwantmem
	beq.s	lkerr
	move.l	d0,a1		a1,a3:message
	move.l	a1,a3
	move.b	#5,LN_TYPE(a1)
	move.l	thistask(a5),a0
	lea	pr_MsgPort(a0),a2	a2:msgport of this task
	move.l	a2,mn_ReplyPort(a1)
	move.w	#$24,mn_Length(a1)
	move.l	pr_CurrentDir(a0),sm_ToolWindow(a1)
	move.l	a5,sm_NumArgs(a1)
	move.l	a4,a0
	move.l	4.w,a6
	jsr	_LVOPutMsg(a6)
	move.l	a2,a0
	jsr	_LVOWaitPort(a6)
	move.l	a2,a0
	jsr	_LVOGetMsg(a6)
	cmp.l	a3,d0
	bne	lkerr
;	move.l	dosbase(a5),a6
	move.l	d0,a1
	moveq	#$24,d0
	bsr	givemem
	moveq	#RETURN_OK,d0
	rts

*************************
*	TaskPri		*	V2.0
*************************
taskpriz bsr	fixpam32
	move.l	a1,a2
	move.l	a0,a1
	tst.b	(a1)
	beq	too_less_args
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	move.l	d0,d7
	bsr	findtsk
	beq.s	tskfail
	move.l	a0,a1
	move.b	d7,d0
	move.l	4.w,a6
	jsr	_LVOSetTaskPri(a6)
tskok	move.l	dosbase(a5),a6
	lea	OK_text(pc),a1
	bsr	pr_string
	moveq	#RETURN_OK,d0
	rts
tskfail	lea	notasktx(pc),a1
	bsr	pr_stringlf
tkfail	moveq	#RETURN_ERROR,d0
	rts

* Find Task given in a2 (ptr,string,cli-number,null)
* RETURN: d0,a0 address (0 if not found)
findtsk	move.l	a2,a1
	moveq	#0,d0
	tst.b	(a1)
	beq.s	.E
	bsr	convert_ASCII_to_num
	beq.s	.C
.E	cmp.l	#20,d0
	bhi.s	.A		is address
	move.l	d0,a1
	tst.l	d0		0 means own task
	beq.s	.D
	lsl.l	#2,d0		is a cli-number
	move.l	dl_Root(a6),a0
	move.l	(a0),a0
	add.l	a0,a0
	add.l	a0,a0
	add.l	d0,a0
	move.l	(a0),d0
	beq.s	.B
	sub.l	#pr_MsgPort,d0
	bra.s	.A
.C	move.l	a2,a1
.D	move.l	4.w,a6
	jsr	_LVOFindTask(a6)	search name
	move.l	dosbase(a5),a6
.A	tst.l	d0
	beq.s	.B
	move.l	d0,a0
	cmp.b	#01,LN_TYPE(a0)	is it a TASK-struct ?
	beq.s	.B
	cmp.b	#13,LN_TYPE(a0)	is it a PROCESS-struct ?
	beq.s	.B
	moveq	#0,d0
.B	tst.l	d0
	rts

*************************
*	Break		*	V2.0
*************************
breakz	bsr	fixpam32
	move.l	a0,a2
	move.l	a1,a3
	tst.b	(a2)
	beq	too_less_args
	bsr	findtsk
	beq.s	tskfail
	move.l	a3,a1
	move.l	a0,a2
	tst.b	(a1)
	beq.s	.B
	bsr	convert_ASCII_to_num
	bne.s	.C
	move.b	(a3),d1
	bclr	#5,d1
	cmp.b	#"C",d1
	blo	tkfail
	cmp.b	#"F",d1
	bhi	tkfail
	sub.b	#55,d1
	moveq	#0,d0
	bset	d1,d0
	bra.s	.C
.B	move.l	tc_SigWait(a2),d0
.C	move.l	a2,a1
	move.l	4.w,a6
	jsr	_LVOSignal(a6)	set signals given in mask
	bra	tskok

*************************
*	PutMsg		*	V2.0
*************************
putmsgz	move.l	parm2(a5),d7
	beq	printa5
	move.l	d7,a1
	bsr	convert_ASCII_to_num
	bne.s	.D
	move.l	d7,a1
	move.l	4.w,a6
	jsr	_LVOFindPort(a6)	search name
	move.l	dosbase(a5),a6
	tst.l	d0
	beq.s	.B
	move.l	d0,a0
	bra.s	.E
.D	move.l	d0,a0
	cmp.l	#20,d0
	bls.s	.B
	cmp.b	#04,LN_TYPE(a0)	is it a MSGPORT-struct ?
	beq.s	.E
.B	move.l	d7,a2
	bsr	findtsk		search task
	bne.s	.C
.A	lea	noporttx(pc),a1
	bsr	pr_stringlf
	moveq	#RETURN_ERROR,d0
	rts
.C	cmp.b	#13,LN_TYPE(a0)	is it a PROCESS-struct ?
	bne.s	.A
	lea	pr_MsgPort(a0),a0
.E	bsr	clearArgs
	move.l	thistask(a5),a2
	lea	pr_MsgPort(a2),a2
	move.l	a2,sp_reply(a5)
	move.b	#5,LN_TYPE+sp_node(a5)
	lea	parm3(a5),a2
	lea	sp_link(a5),a3
	moveq	#mn_Size,d2
.G	move.l	(a2)+,d3
	beq.s	.F
	move.l	d3,a1
	bsr	convert_ASCII_to_num
	bne.s	.H
	move.l	d3,d0
.H	move.l	d0,(a3)+
	addq.w	#4,d2
	bra.s	.G
.F	move.w	d2,sp_length(a5)
	move.l	sp_link(a5),a1
	move.b	(a1),d0
	cmp.b	ctrl_codes+13(a5),d0
	bne.s	.I
	lea	sp_link(a5),a1		for DOSpackets
	move.l	a1,LN_NAME+sp_node(a5)
	lea	sp_node(a5),a1
	move.l	a1,sp_link(a5)
	move.l	sp_reply(a5),sp_port(a5)
.I	lea	msendtx(pc),a1
	bsr	pr_stringlf
	lea	sp_node(a5),a1		message
	move.l	4.w,a6
	jsr	_LVOPutMsg(a6)
	move.l	dosbase(a5),a6
	clr.l	parm2(a5)
	bra.s	getmsg1

*************************
*	GetMsg		*	V2.0
*************************
getmsgz	moveq	#0,d7
	moveq	#0,d6
	move.l	parm2(a5),d2
	beq.s	getmsg1
	move.l	d2,a1
	move.l	4.w,a6
	jsr	_LVOFindPort(a6)	does it already exist ?
	tst.l	d0
	bne.s	getmsg1
	move.l	thistask(a5),a1
	lea	pr_MsgPort(a1),a1
	move.l	d2,LN_NAME(a1)
	jsr	_LVOAddPort(a6)
	moveq	#1,d6
getmsg1	move.l	thistask(a5),a2
	lea	pr_MsgPort(a2),a2
	move.l	4.w,a6
	move.l	a2,a0
	jsr	_LVOGetMsg(a6)
	tst.l	d0
	bne.s	.A
	moveq	#0,d2
	move.b	MP_SIGBIT(a2),d1
	bset	d1,d2
	bset	#SIGBREAKB_CTRL_C,d2
	move.l	d2,d1
;	moveq	#0,d0
	jsr	_LVOSetSignal(a6)	clear signals
	move.l	d2,d0
	jsr	_LVOWait(a6)	wait for msgport or ctrl-c
	move.l	a2,a0
	jsr	_LVOGetMsg(a6)
.A	move.l	dosbase(a5),a6
	tst.l	d0
	beq	msgfail
	move.l	d0,a2
	move.w	mn_Length(a2),d2
	move.w	d2,-(sp)
	move.l	a2,-(sp)
	lea	msgtx(pc),a0
	move.l	sp,a1
	bsr	new_print
	addq.l	#6,sp
	sub.w	#mn_Size,d2
	lsr.w	#2,d2
	lea	mn_Size(a2),a3
	bra.s	.D
.C	move.l	(a3)+,d0
	cmp.l	#$dfe000,d0
	bhs.s	.E
	cmp.l	#$a00000,d0
	blo.s	.F
	cmp.l	#$c00000,d0
	blo.s	.E
.F	move.l	d0,a0
	moveq	#79,d1
.H	move.b	(a0)+,d3
	beq.s	.G
	cmp.b	#" ",d3
	blo.s	.E
	cmp.b	#"~",d3
	bhi.s	.E
	dbra	d1,.H
	bra.s	.E
.G	cmp.w	#76,d1
	bhs.s	.E
	bsr	printADR
	bsr	pr_space
	move.l	d0,a1
	bsr	pr_stringlf
	bra.s	.D
.E	bsr	printADR
	bsr	pr_lf
.D	dbra	d2,.C
	tst.l	d7
	bne.s	.B
	tst.l	d6
	beq.s	.I
	move.l	thistask(a5),a1
	lea	pr_MsgPort(a1),a1
	move.l	4.w,a6
	jsr	_LVORemPort(a6)
	move.l	dosbase(a5),a6
.I	lea	replytx(pc),a1
	bsr	pr_string
	bsr	rask
	move.l	d0,d2
	beq.s	.B
	move.l	4.w,a6
	move.l	a2,a1
	jsr	_LVOReplyMsg(a6)
	move.l	dosbase(a5),a6
	cmp.b	#RETURN_ERROR,d2
	beq	getmsg1
.B	moveq	#RETURN_OK,d0
	rts
printa5	move.l	a5,-(sp)
	move.l	sp,a1
	lea	pra5tx(pc),a0
	bsr	new_print
	addq.l	#4,sp
	move.l	intuibase(a5),a6
	suba.l	a0,a0
	jsr	_LVODisplayBeep(a6)
	move.l	dosbase(a5),a6
msgfail	moveq	#RETURN_ERROR,d0
	rts

*************************
*	Border		*	V2.0
*************************
wd_BorderLeft	equ	54
wd_Flags	equ	24

borderz	move.l	intuibase(a5),a6
	moveq	#0,d0
	jsr	_LVOLockIBase(a6)
	move.l	d0,d7
	move.l	$34(a6),a4	active window
	move.l	parm2(a5),a0
	move.l	a0,d0
	beq.s	.A
	move.b	1(a0),d0
	bset	#5,d0
	cmp.b	#"n",d0	;oN
	beq	bordon
	cmp.b	#"f",d0	;oFF
	beq	bordoff
.A	bsr	borne
	bra	help_status

bordon	tst.l	bordersize(a5)
	beq.s	borne
	bclr	#11,wd_Flags+2(a4)	unset noborder
	move.l	bordersize(a5),wd_BorderLeft(a4)
	bra.s	borjo

bordoff	tst.l	wd_BorderLeft(a4)
	beq.s	borjo
	bset	#11,wd_Flags+2(a4)	set noborder-window
	move.l	wd_BorderLeft(a4),bordersize(a5)
	clr.l	wd_BorderLeft(a4)
borjo	moveq	#$00,d0		null resize
	moveq	#$00,d1
	move.l	a4,a0
	jsr	_LVOSizeWindow(a6)
	move.l	a4,a0
	jsr	_LVORefreshWindowFrame(a6)	redraw
borne	move.l	d7,a0
	jsr	_LVOUnlockIBase(a6)
	move.l	parm3(a5),d0
	beq.s	nosiz
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	tst.l	d1
	beq.s	nosiz
				;resize window to fill screen
	move.l	$2e(a4),a1	points to screen
	move.l	d0,d4	width of menubar
	bpl.s	.A
	moveq	#0,d4
	move.b	30(a1),d4
	add.b	31(a1),d4
.A	moveq	#-1,d2
	move.l	12(a1),d3
	sub.w	10(a4),d3
	sub.w	d4,d3
	move.w	d3,d1
	bpl.s	bklein
	moveq	#0,d2
	moveq	#0,d0
	move.l	a4,a0
	jsr	_LVOSizeWindow(a6)
bklein	moveq	#0,d0
	sub.w	4(a4),d0
	move.l	d4,d1
	sub.w	6(a4),d1
	move.l	a4,a0
	jsr	_LVOMoveWindow(a6)
	moveq	#0,d1
	tst.b	d2
	beq.s	bgross
	move.w	d3,d1
bgross	swap	d3
	sub.w	8(a4),d3
	move.w	d3,d0
	move.l	a4,a0
	jsr	_LVOSizeWindow(a6)
	jsr	_LVORethinkDisplay(a6)
	
nosiz	move.l	dosbase(a5),a6
	moveq	#10,d1		wait more than 1/10 sec
	jsr	_LVODelay(a6)
	moveq	#RETURN_OK,d0
	rts






doserror_text		;V2.0:extended
	dc.b	103,'NO FREE STORE',0
	dc.b	105,'TASK TABLE FULL',0
	dc.b	114,'BAD TEMPLATE',0
	dc.b	115,'BAD NUMBER',0
	dc.b	116,'REQUIRED ARG MISSING',0
	dc.b	117,'KEY NEEDS ARG',0
	dc.b	118,'TOO MANY ARGS',0
	dc.b	119,'UNMATCHED QUOTES',0
	dc.b	120,'LINE TOO LONG',0
	dc.b	121,'FILE NOT OBJECT',0
	dc.b	122,'INVALID RESIDENT LIB',0
	dc.b	201,'NO DEFAULT DIR',0
	dc.b	202,'OBJECT IN USE',0
	dc.b	203,'OBJECT EXISTS',0
	dc.b	204,'DIR NOT FOUND',0
	dc.b	205,'OBJECT NOT FOUND',0
	dc.b	206,'BAD STREAM NAME',0
	dc.b	207,'OBJECT TOO LARGE',0
	dc.b	209,'ACTION NOT KNOWN',0
	dc.b	210,'INVALID COMPONENT NAME',0
	dc.b	211,'INVALID LOCK',0
	dc.b	212,'OBJECT WRONG TYPE',0
	dc.b	213,'DISK NOT VALIDATED',0
	dc.b	214,'DISK WRITE PROTECTED',0
	dc.b	215,'RENAME ACROSS DEVICES',0  
	dc.b	216,'DIRECTORY NOT EMPTY',0
	dc.b	217,'TOO MANY LEVELS',0
	dc.b	218,'DEVICE NOT MOUNTED',0
	dc.b	219,'SEEK ERROR',0
	dc.b	220,'COMMENT TOO BIG',0
	dc.b	221,'DISK FULL',0
	dc.b	222,'DELETE PROTECTED',0
	dc.b	223,'WRITE PROTECTED',0
	dc.b	224,'READ PROTECTED',0
	dc.b	225,'NOT A DOS DISK',0
	dc.b	226,'NO  DISK',0
	dc.b	232,'NO MORE ENTRIES',0
	dc.b	233,'IS SOFT LINK',0
	dc.b	234,'OBJECT LINKED',0
	dc.b	235,'BAD HUNK',0
	dc.b	236,'NOT IMPLEMENTED',0
	dc.b	240,'RECORD NOT LOCKED',0
	dc.b	241,'LOCK COLLOSION',0
	dc.b	242,'LOCK TIMEOUT',0
	dc.b	243,'UNLOCK ERROR',0
	dc.b	47,'BUFFER OVERFLOW',0		303
	dc.b	48,'BREAK',0			304
	dc.b	49,'NOT EXECUTABLE',0		305
	dc.b	0

VersionNo	dc.b	'$VER: ZShell V2.0 (06.06.94)',0
ZShellName	dc.b	'ZShell',0
dosname		dc.b	'dos.library',0
intuiname	dc.b	'intuition.library',0
iconname	dc.b	'icon.library',0
timdev		dc.b	'timer.device',0
conname		dc.b	'CON:0/10/640/190/ZShell V2.0/CLOSE',0
cone		dc.b	'*',0
;sysdisk	dc.b	'SYS:',0	only for CreateCLI2
wintool		dc.b	'WINDOW',0
scripttool	dc.b	'SCRIPT',0
clktask		dc.b	'MemClock',0
clkform		dc.b	' Mem:%7ld Chip:%6ld  %02d:%02d:%02d ',0
clkuse		dc.b	'Use ON, OFF or ALARM',0
chkuse		dc.b	'Use ON or OFF',0
bad_number_tx	dc.b	'Cannot understand number',0
less_args_tx	dc.b	'Not enough arguments',0
goto_error_tx	dc.b	'GOTO statement error',10,0
if_error_tx	dc.b	'IF statement error',10,0
warn_tx		dc.b	'warn',0
error_tx	dc.b	'error',0
fail_tx		dc.b	'fail',0
not_tx		dc.b	'not',0
exists_tx	dc.b	'exists',0
bad_prot_bits_tx	dc.b	'Unknown protection bit',10,0
no_colon_tx	dc.b	'Name MUST end in :',10,0
residetx	dc.b	$9b,'32mUsecount  Adress Name',$9b,'m',0
resi_no_mem_tx	dc.b	'Not enough memory',0
resi_inuse_tx	dc.b	'Resident is used',0
rpn_result_tx	dc.b	'RESULT: Dec %ld  Hex $%08lx',10,0
rpn_res2	dc.b	'%ld',0
failat_tx	dc.b	'Failat: %d',10,0
defscript	dc.b	'S:ZStart',0	;changed V2.0
rexxtx		dc.b	'REXX:RX',0
unmounted_tx	dc.b	'[UnMounted]',10,0
mounted_tx	dc.b	'[Mounted]',0
assign_tx	dc.b	10,$9b,'32mAssigns:',$9b,'m',10,0
volume_tx	dc.b	$9b,'32mVolumes:',$9b,'m',10,0
device_tx	dc.b	10,$9b,'32mDevices:',$9b,'m',10,0
bad_unset_tx	dc.b	' could not be unset!',10,0
breaktx		dc.b	10,$9b,'36m*** BREAK ***',$9b,'m',10,0
prompt_args_tx	dc.b	'%p> ',0
stk_too_small_tx	dc.b	'Too Small',10,0
stk_too_big_tx	dc.b	'Too Big',10,0
stk_size_tx	dc.b	'Current Stack: %ld bytes',10,0
stack_tx	dc.b	'Stack overflow',0
lockntx		dc.b	'Give LOCK-BPTR or NAME',0
lockread	dc.b	'READ',0
lockwrite	dc.b	'WRITE',0
locktext	dc.b	'%s-Lock on ',$9b,'33m%s',$9b,'m'
		dc.b	10,'This Lock: $%06lx  Next: $%06lx',10,0
clk_tx		dc.b	'Use LOAD or SAVE',0
noclk_tx	dc.b	'No Clock found',0
muell_tx	dc.b	'Format: DD.MM.YY or MM-DD-YY or HH:MM:SS',0
styp		dc.b	'lrdimps'
shuse_tx	dc.b	'Use D,I,L,M,P,R,S or T',0
show_tx		dc.b	$9b,'32mAdress Pri Name',$9b,'m',0
show2_tx	dc.b	$9b,'32mAdress Pri Ver Rev Name',$9b,'m',0
shform		dc.b	'%06lx%4d %s',10,0
shform2		dc.b	'%06lx%4d%4d%4d %s',10,0
shta_tx		dc.b	$9b,'32mAdress Pri State SignWait PT '
		dc.b	'Name',$9b,'m',0
shtaform	dc.b	'%06lx%4d %-5s %08lx %c%c %s',0
proform		dc.b	32,9,$9b,'33m->CLI %ld:',$9b,'m %s',0
ttyp		dc.b	"Inval",0,"Added",0,"Run",0,"Ready",0
		dc.b	"Wait",0,"Exept",0,"Remov",0
inform_tx	dc.b	$9b,'32mName Unit Sys    Size    Free Full Block'
		dc.b	'   Status   Err  Volume',$9b,'m',0
inform		dc.b	'%-7s%2ld %3s%7ldK%7ldK',$9b,'37m%4ld%%',$9b
		dc.b	'm%6ld %-10s%3ld   %s',10,0
inform2		dc.b	'%-7s%2ld     ',$9b,'35m%s',$9b,'m',10,0
statro		dc.b	"Read only",0
statrw		dc.b	"Read/Write",0
statval		dc.b	"Validating",0
statun		dc.b	"Unknown",0
nodisk		dc.b	"No Disk present",0
baddisk		dc.b	"Unreadable Disk",0
nodos		dc.b	"Not a DOS-Disk",0
kickdisk	dc.b	"Kickstart-Disk",0
ofs_tx		dc.b	"OFS",0	OldFilesystem
		dc.b	"FFS",0	FastFilesystem
		dc.b	"INO",0	International OFS
		dc.b	"INF",0	International FFS
		dc.b	"DCO",0	Dir Cache OFS
		dc.b	"DCF",0 Dir Cache FFS
msd_tx		dc.b	"MSD",0	MessyDOS
quest_tx	dc.b	"???",0	Unknown
OK_text		dc.b	"OK.",10,0
notasktx	dc.b	"Task not found",0
noporttx	dc.b	"Port not found",0
msendtx		dc.b	"send",0
pra5tx		dc.b	"A5=%06lx",10,0
msgtx		dc.b	"Message=%06lx  Length=%d",10,0
time_text	dc.b	"Date: %02d.%02d.%02d    "
		dc.b	"Time: %02d:%02d:%02d.%02d",10,0
stat_text	dc.b	$9b,"37mResult2=%ld  Time=%02d:%02d:%02d.%02d"
		dc.b	"  Changes-> Chip:%ld  Fast:%ld  Total:%ld"
		dc.b	$9b,"m",10,0
failertx	dc.b	$9b,"1mFail-Level: %ld",$9b,"m",10,0
replytx		dc.b	"Reply? ",0
mem_line	dc.b	"%08lx: %08lx %08lx %08lx %08lx   '%s'",10,0
vec_line	dc.b	"WarmCapture  $%06lx",10,"CoolCapture  $%06lx",10
		dc.b	"ColdCapture  $%06lx",10,"KickTagPtr   $%06lx",10
		dc.b	"KickMemPtr   $%06lx",10,"KickCheckSum $%06lx",10,0
format		dc.b	'%8ld',0	;print a longw right justified
formatADR	dc.b	'$%06lx',0	;print address 
totsize		dc.b	$9b,'37mTotal Bytes: %ld   Files: %ld   '
		dc.b	'Dirs: %ld',$9b,'m',10,0
dirtext		dc.b	'(Dir)',$9b,'m',0
cderrtx		dc.b	'Where ?',10,0
dirof		dc.b	$9b,'36mDirectory of -> ',$9b,'m',0
defpath1	dc.b	'RAM:',0
		dc.b	'C:',0
		dc.b	'SYS:',0
		dc.b	'DF0:',0
		dc.b	'S:',0
		dc.b	0
pcurrent	dc.b	'Current',0
msearch		dc.b	12,$9b,'BSearch: ',$9b," p",0
prtdev		dc.b	'PRT:',0
prtit		dc.b	12,$9b,'BPrinting',0
badcomm		dc.b	'Command not found',10,0
copyOK		dc.b	' ...copied',10,0
deletedtx	dc.b	' ...deleted',0
memess		dc.b	"Chip: %ld   Fast: %ld   Total Free: %ld",10,0
resask		dc.b	'Really RESET ? ',0
append		dc.b	'.rcy',0
errsiz		dc.b	$9b,'32m Size:',$9b,'m',0
errnum		dc.b	$9b,'33m ERROR',$9b,'m',0
prok		dc.b	'  OK',0
farb1		dc.b	$9b,'m',0
farb2		dc.b	$9b,'32m',0
farb3		dc.b	$9b,'33m',0
lf		dc.b	10,0
tab		dc.b	9,0
backspace_it	dc.b	8		DON'T SEPERATE
delete_it	dc.b	$9b,'P',0		THESE LINES
return_it	dc.b	13,10,0
right_cursor	dc.b	$9b,'C',0
left_cursor	dc.b	$9b,'D',0
delete_line	dc.b	13,$9b,'M',0
delete_line2	dc.b	$9b,'M',13,0
backslash	dc.b	'/',0
help_ret	dc.b	'help^M',0
clstx		dc.b	27,"c",0	reset console
clrtx		dc.b	12,0	clear screen
scroll_up_tx	dc.b	$9b,"S",13,0
scroll_down_tx	dc.b	$9b,"M",$9b,"T",$9b,"1H",0
hide_cursor	dc.b	$9b,"0 p",0
show_cursor	dc.b	$9b," p",0

umlaut		dc.b	'äÄöÖüÜß§£'
umlautend
ctrl_tx	dc.b	'Actual CTRL-Codes: ',0
ctrl_init dc.b	17,23,19,5,1,24,27,9,25,8,10,13,12,46 initial CTRL-Codes
ctrl_inite
doserrtx	dc.b	$9b,'36mERROR:',$9b,'m'	;DON'T SEPERATE
space	dc.b	' '
null	dc.b	0		;THESE 3 LINES

helpman	dc.b	"ZShell.Doc",0
help_tx1 dc.b	"ZShell  (C)1990,91 Paul Hayter",10
	dc.b	"Updated 1993/94 to V2.0 by Martin Gierich",10
	dc.b	"Freeware, NO commercial usage !",10,10
	dc.b	"Commands:",0
help_tx2 dc.b	10,"Options:",10
	dc.b	"-r/-RECURSIVE (copy,delete,list,recopy)",10
	dc.b	"-c/-CLEAR (endcli,locate,path,resident,avail,ctrl)",10
	dc.b	"-q/-QUICK (dir,list)",10,0
help_tx3 dc.b	10,"Wildcards:",10
	dc.b	"* : Match some charcters",10
	dc.b	"? : Match one character",10
	dc.b	"~ : Negate following wildcard",10
	dc.b	"[]: Surrounds class of characters",10
	dc.b	"| : Separate multiple wildcards",10
	dc.b	10,"Editing: Cursor, SHIFT+Cursor, <-, DEL, TAB,"
	dc.b	" SHIFT+TAB, ESC and see ctrl",10
	dc.b	". for dir back, force disk or abbreviation",10
	dc.b	"Type 'help ?' for more help.",0

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

comtext	dc.b	'addbuffers',0	V1.27
	dc.b	'alias',0
	dc.b	'ask',0		V1.28
	dc.b	'assign',0
	dc.b	'avail',0
	dc.b	'border',0	V2.0
	dc.b	'break',0	V2.0
	dc.b	'cd',0
	dc.b	'check',0
	dc.b	'cls',0		V2.0
	dc.b	'copy',0
	dc.b	'ctrl',0	V2.0
	dc.b	'date',0
	dc.b	'diskchange',0	V2.0
	dc.b	'delete',0
	dc.b	'die',0		V2.0
	dc.b	'dir',0
	dc.b	'echo',0
else_tx	dc.b	'else',0	V1.28
	dc.b	'endcli',0
endif_tx dc.b	'endif',0	V1.28
	dc.b	'eval',0
	dc.b	'execute',0
	dc.b	'failat',0
	dc.b	'fault',0	V2.0
	dc.b	'filenote',0	V2.0
	dc.b	'getmsg',0	V2.0
	dc.b	'help',0
	dc.b	'htype',0	V1.29
	dc.b	'if',0		V1.28
	dc.b	'info',0
	dc.b	'join',0	V1.29
label_tx dc.b	'lab',0		V1.29
	dc.b	'list',0
	dc.b	'locate',0	V2.0
	dc.b	'lock',0	V2.0
	dc.b	'm',0
	dc.b	'makedir',0
	dc.b	'memclk',0	V2.0
	dc.b	'more',0	V1.23
	dc.b	'newcli',0	V2.0
	dc.b	'path',0
	dc.b	'prompt',0
	dc.b	'protect',0
	dc.b	'putmsg',0	V2.0
	dc.b	'quit',0	V1.29
	dc.b	'recopy',0	V2.0
	dc.b	'relabel',0	V1.27
	dc.b	'rename',0
	dc.b	'reset',0
	dc.b	'resident',0	V1.25
	dc.b	'search',0	V2.0
	dc.b	'setclock',0	V2.0
	dc.b	'setdate',0	V2.0
	dc.b	'show',0	V2.0
	dc.b	'skip',0
	dc.b	'stack',0
	dc.b	'strings',0	V1.29
	dc.b	'taskpri',0	V2.0
	dc.b	'type',0
	dc.b	'unalias',0
	dc.b	'vec',0
	dc.b	'wait',0
	dc.b	0
	
	
	cnop	0,2
comoffs
	dc.w	addbuffersz-start
	dc.w	set_funcz-start	;alias
	dc.w	askz-start
	dc.w	assignz-start
	dc.w	availz-start
	dc.w	borderz-start
	dc.w	breakz-start
	dc.w	cdz-start
	dc.w	checkz-start
	dc.w	clsz-start
	dc.w	copyz-start
	dc.w	ctrlz-start
	dc.w	datez-start
	dc.w	diskchangez-start
	dc.w	deletez-start
	dc.w	diez-start
	dc.w	dirz-start
	dc.w	echoz-start
	dc.w	elsez-start
	dc.w	endcliz-start
	dc.w	endifz-start
	dc.w	evalz-start
	dc.w	executez-start
	dc.w	failatz-start
	dc.w	faultz-start
	dc.w	filenotez-start
	dc.w	getmsgz-start
	dc.w	helpz-start
	dc.w	htypez-start
	dc.w	ifz-start
	dc.w	infoz-start
	dc.w	joinz-start
	dc.w	labelz-start	;lab
	dc.w	listz-start
	dc.w	locatez-start
	dc.w	lockz-start
	dc.w	memexamz-start	;m
	dc.w	makedirz-start
	dc.w	memclkz-start
	dc.w	morez-start
	dc.w	newcliz-start
	dc.w	pathz-start
	dc.w	promptz-start
	dc.w	protectz-start
	dc.w	putmsgz-start
	dc.w	quitz-start
	dc.w	recopyz-start
	dc.w	relabelz-start
	dc.w	renamez-start
	dc.w	resetz-start
	dc.w	residentz-start
	dc.w	searchz-start
	dc.w	setclockz-start
	dc.w	setdatez-start
	dc.w	showz-start
	dc.w	skipz-start
	dc.w	stackz-start
	dc.w	stringsz-start
	dc.w	taskpriz-start
	dc.w	typez-start
	dc.w	unsetz-start	;unalias
	dc.w	vecz-start
	dc.w	waitz-start

manadr	dc.l	0	here are 2 global variables
mansize	dc.l	0	because the online-help-manual is used globally

	end	;***	here it ends	***



