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

* See documentation for Copyright and Disclaimer !
*
* Please do not distribute modified versions of ZShell by your own,
* this would result in absolute chaos !
* The source code is provided, because there are so many interesting
* things in it and you can learn from it.
*
* It is OK to change the source to adapt ZShell to your personal needs,
* but if you want to distribute a modified version, you have to
* follow these rules:
*
* 1) It is strictly forbidden to use parts of the source or the whole
*    source or other parts of the ZShell distribution in commercial
*    software or in shareware !
* 2) You have to keep at least the copyright part, the author list and
*    the credits part of the documentation with your executable !
*    You may add yourself to them, but do not change them !
*    It is important that this remains freeware and all past authors
*    are still named as authors !
* 3) Distribute the source code with the executable !
* 4) Change the name of the program to avoid confusion !
* 5) Please contact me before, maybe I can include your changes into the
*    next release of ZShell !




ZVERSION = "2.9c"
*mempool in Delete fixed
*show cursor fixed
*address display fixed
*Enforcerhits in _System0 fixed
*nested Ifs added (Mark J. Swift)
*ASSIGN EXISTS added (Mark J. Swift)

;DEBUG	= 1
;KILL	= 1

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

;ZSH V2.2 needs:
;sizeofblk=3944
;VCheck-start=222
;JumpIn-start=244

VERSION		= $1234
POOLSIZE	= 2000

FLcheck		= 0	byte 3
FLmatch		= 1
FLappicon	= 2
FLwild		= 3
FLerrors	= 4
FLdebug		= 5
FLcutline	= 6
FLall		= 7
FLhide		= 0	byte 2
FLpipe		= 1
FLraw		= 2
FLconfirm	= 3
FLhbit		= 4
MaxFlags 	= 13

DefaultFlags	= %1111111001010

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

SIGBREAKB_CTRL_C	equ	$C
SIGBREAKB_CTRL_D	equ	$D
SIGBREAKB_CTRL_E	equ	$E
SIGBREAKB_CTRL_F	equ	$F

eb_CoolCapture	equ	46
eb_ColdCapture	equ	42
eb_WarmCapture	equ	50
eb_KickMemPtr	equ	546
eb_KickTagPtr	equ	550
eb_KickCheckSum	equ	554
	
* 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
pr_HomeDir		equ	188	KS2
pr_Flags		equ	192
pr_ExitCode		equ	196
pr_ExitData		equ	200
pr_Arguments		equ	204
pr_CES			equ	224

* 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
rn_Flags	equ	52	LONG
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	(PathPtr)
dvi_StackSize	equ	20
dvi_LockList	equ	20
dvi_Priority	equ	24
dvi_Startup	equ	28
dvi_SegList	equ	32
dvi_GlobVec	equ	36
dvi_Name	equ	40	BSTR
dlt_device	equ	0	<-- contents of dvi_Type
dlt_directory	equ	1
dlt_volume	equ	2
dlt_late	equ	3
dlt_nonbind	equ	4

*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

*WAppMessage
am_Type		equ	20
am_NumArgs	equ	30
am_ArgList	equ	34

* 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
ACTION_READ		EQU	"R"
ACTION_WRITE		EQU	"W"

dp_Link		equ	0	;DosPacket Structure
dp_Port		equ	4
dp_Action	equ	8
dp_Res1		equ	12
dp_Res2		equ	16
dp_Arg1		equ	20
dp_Arg2		equ	24
dp_Arg3		equ	28
dp_SIZEOF	equ	48

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


TAG_USER	equ	$80000000
ASL_TB		equ	TAG_USER!$80000

* LIBRARY CALLS
* EXEC
_LVOOpenLibrary		equ	-552
_LVOOldOpenLibrary	equ	-408
_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
_LVORemTask		equ	-288
_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
_LVOCopyMem		equ	-624
_LVOCreateMsgPort	equ	-666	KS 2.0+
_LVODeleteMsgPort	equ	-672

* DOS
_LVOSetProtection	equ	-186
_LVOExecute		equ	-222
_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
_LVOReadLink		equ	-438	KS 2.0+
_LVOMakeLink		equ	-444
_LVOFault		equ	-468
_LVOPrintFault		equ	-474
_LVOAssignLock		equ	-612
_LVOAssignLate		equ	-618
_LVOAssignPath		equ	-624
_LVOAssignAdd		equ	-630
_LVORemAssignList	equ	-636
_LVOFormat		equ	-714
_LVOAddBuffers		equ	-732
_LVOFilePart		equ	-870
_LVOPathPart		equ	-876
_LVOInhibit		equ	-726
_LVOParsePatternNC	equ	-966
_LVOMatchPatternNC	equ	-972
_LVONameFromLock	equ	-402

*Intuition
_LVOPrintIText		equ	-216
_LVODisplayAlert	equ	-90
_LVODisplayBeep		equ	-96
_LVOLockIBase		equ	-414
_LVOUnlockIBase		equ	-420
_LVORefreshWindowFrame	equ	-456
_LVOSizeWindow		equ	-288
_LVOMoveWindow		equ	-168
_LVOActivateWindow	equ	-450
_LVORemakeDisplay	equ	-384
_LVOMakeScreen		equ	-378
_LVORethinkDisplay	equ	-390
_LVOCloseScreen		equ	-66
_LVOItemAddress		equ	-144
_LVOSetMenuStrip	equ	-264
_LVOClearMenuStrip	equ	-54
_LVOOpenScreenTagList	equ	-612	KS2.0+
_LVOPubScreenStatus	equ	-552
_LVOLockPubScreen	equ	-510
_LVOUnlockPubScreen	equ	-516

*Icon
_LVOGetDiskObject	equ	-78
_LVOGetDefDiskObject	equ	-120
_LVOPutDiskObject	equ	-84
_LVOFreeDiskObject	equ	-90
_LVOFindToolType	equ	-96
_LVOMatchToolValue	equ	-102

*Workbench
_LVOAddAppIconA		equ	-60	KS2.0+
_LVOAddAppWindowA	equ	-48
_LVORemoveAppIcon	equ	-66
_LVORemoveAppWindow	equ	-54
_LVOWBInfo		equ	-90

*Utility
_LVOToUpper		equ	-174	KS2.0+
_LVOStricmp		equ	-162
_LVOStrnicmp		equ	-168

*Asl
_LVOAllocAslRequest	equ	-48	KS2.0+
_LVOFreeAslRequest	equ	-54
_LVOAslRequest		equ	-60

*XPKMaster
_LVOXpkExamine		equ	-36
_LVOXpkUnpack		equ	-48

*AmigaGuide
_LVOOpenAmigaGuideA	equ	-54
_LVOCloseAmigaGuide	equ	-66

*GadTools
_LVOCreateMenusA	equ	-48
_LVOFreeMenus		equ	-54
_LVOLayoutMenuItemsA	equ	-60
_LVOLayoutMenusA	equ	-66
_LVOGetVisualInfoA	equ	-126
_LVOFreeVisualInfo	equ	-132


wd_WScreen	= 46
wd_Flags	= 24
wd_BorderLeft	equ	54
mi_SIZEOF	= 34
WFLG_NEWLOOKMENUS = $00200000

rf_File		= 4
rf_Dir		= 8

XPK_InName	= $80005851	filename
XPK_OutName	= $80005860	filename
XPK_GetError	= $80005875	buffer
XPK_TaskPri	= $8000587f	ubyte

*GadTools NewMenu structure
		RSRESET
gnm_Type	RS.B	1
gnm_Pad		RS.B	1
gnm_Label	RS.L	1
gnm_CommKey	RS.L	1
gnm_Flags	RS.W	1
gnm_MutualExcl	RS.L	1
gnm_UserData	RS.L	1
gnm_SIZEOF	RS.W	0

NM_END		= 0
NM_TITLE	= 1
NM_ITEM		= 2
NM_SUB		= 3
NM_IGNORE	= 64
NM_BARLABEL	= -1
COMMSEQ		= 4

GT_TagBase		= TAG_USER+$80000
GTMN_FullMenu		= 62+GT_TagBase
GTMN_NewLookMenus	= 67+GT_TagBase

		RSRESET
;NewAmigaGuide-structure
nag_Lock	RS.L	1
nag_Name	RS.L	1
nag_Screen	RS.L	1
nag_PubScreen	RS.L	1
nag_HostPort	RS.L	1
nag_ClientPort	RS.L	1
nag_BaseName	RS.L	1
nag_Flags	RS.L	1
nag_Context	RS.L	1
nag_Node	RS.L	1
nag_Line	RS.L	1
nag_Extens	RS.L	1
nag_Client	RS.L	1
NewAmigaGuide_SIZEOF	RS.W	0

* DOS LIBRARY
dl_A2			equ	42

*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_CmdLine	equr	d2
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
		RSRESET
sf_CommandName	RS.B	MAXBSTR+1        ;BSTR, length byte!
sf_CommandArgs	RS.B	MAXBSTR+1        ;not a BSTR, LF-terminated!
sf_PrevStack		RS.L	1
sf_SaveReturnAddr	RS.L	1
sf_SaveModule		RS.L	1
sf_SaveCommandName	RS.L	1
sf_StackBase	RS.L	1
sf_StackSize	RS.L	1
sf_PushSize	RS.L	1
sf_Process	RS.L	1
sf_CLI		RS.L	1
sf_CIS		RS.L	1
sf_SCB_Buf	RS.L	1
sf_SCB_Pos	RS.L	1
sf_SCB_End	RS.L	1
sf_Membase	RS.L	1
sf_Arguments	RS.L	1
sf_SIZEOF	RS.W	0

*Constants (only LONGS!)
SHELLINE_SIZE	equ	256	V1.30
CLIBUF_SIZE	equ	256
NEWPRINTSIZE	equ	200
HISTORY_SIZE	equ	1024	MUST BE POWER OF 2
IFSIZE		equ	17

* THE GENERAL MEMORY BLOCK (LONGS!)
		RSRESET
blockbase	RS.B	260	the fib or info goes here
sp_node		RS.B	14	DOSpacket
sp_reply	RS.L	1
sp_length	RS.W	1
sp_link		RS.L	1
sp_port		RS.L	1
packettype	RS.L	1
sp_res1		RS.L	1
sp_res2		RS.L	1
myArg1		RS.L	1
myArg2		RS.L	1
myArg3		RS.L	1
myArg4		RS.L	1
myArg5		RS.L	1
myArg6		RS.L	1
myArg7		RS.L	1
packettask	RS.L	1
devproc		RS.L	1	endofpacket
chartable	RS.L	1
last_failcode	RS.L	1
outhandle	RS.L	1
inhandle	RS.L	1
if_condition	RS.B	IFSIZE
x1		RS.B	80-IFSIZE
stdout		RS.L	1
stdin		RS.L	1
EntryA0		RS.L	1
better_Seglist	RS.L	1
parm1		RS.L	1	addr of each parameter within shelline
parm2		RS.L	1
parm3		RS.L	1
parm4		RS.L	1
parm5		RS.L	1
parm6		RS.L	1
parm7		RS.L	1
parm8		RS.L	1
parm9		RS.L	1
parm10		RS.B	4*16	16 extra parms
endofparms	RS.L	1	for NULL end

shelline	RS.B	SHELLINE_SIZE
CLIbuf		RS.B	CLIBUF_SIZE
NewPrintBuffer	RS.B	NEWPRINTSIZE
errorstack	RS.L	1
topstack	RS.L	1
stacksize	RS.L	1
temp1		RS.L	1
temp2		RS.L	1
temp3		RS.L	1
temp4		RS.L	1
tempbuf		RS.B	2*SHELLINE_SIZE	double shellinesizebuffer
temp2buf	RS.B	80	80 char temp buffer
dosbase		RS.L	1
intuibase	RS.L	1
Result2		RS.L	1
kickver		RS.W	1
old_prompt	RS.L	1
old_setname	RS.L	1
old_homedir	RS.L	1
redirect_in	RS.B	1
redirect_out	RS.B	1
CLIptr		RS.L	1
Flags		RS.L	1
dirpool		RS.L	1
ConsoleSwitch	RS.L	1
count_line	RS.L	1
FNCignore	RS.B	30	pattern for files to ignore
FNCvolume	RS.L	1	volume-ID
FNCkey		RS.L	1	directory-ID
FNCdate		RS.L	1	date of last change
FNCsize		RS.L	1	size of buffer
FNCbuffer	RS.L	1	start of buffer
FNCcycle	RS.L	1	buffer pos to cycle
FNCfill		RS.W	1	free bytes in buffer
FNCbuffered	RS.B	1	data in buffer ?
FNCchars	RS.B	1	number of chars to delete for cycle
FNCback		RS.B	1	cycle backwards flag
FNCnumchars	RS.B	1	number of chars in curremnt line
OldCTask	RS.L	1
OldCIS		RS.L	1
OldCOS		RS.L	1
bordersize	RS.L	1
scsize		RS.L	1
scaddr		RS.L	1
scptr		RS.L	1
scflag		RS.B	1
openwin_flag	RS.B	1
noresi_flag	RS.B	1
noreview_flag	RS.B	1
ReviewMem	RS.L	1
ReviewPtr	RS.L	1
ReviewSize	RS.L	1
gather_ptr	RS.L	1
tempbytes	RS.W	1
gather		RS.B	80	for CSI string and error-string
pipe_in		RS.B	14
pipe_out	RS.B	14
PipeTask	RS.L	1
old_linhere	RS.L	1
old_linmax	RS.L	1
morekeys	RS.B	20
dotchar		RS.B	1
ctrl_codes	RS.B	29	Keyboard-CTRL-Codes
CDbackstr	RS.B	80	string of last directory
now		RS.L	1
nost		RS.L	1
then		RS.L	1
past		RS.B	HISTORY_SIZE	history buffer=1024 bytes
thistask	RS.L	1
x5		RS.L	1
raw_mode	RS.L	1
cursor_mode	RS.B	1
x7		RS.B	5
gadbase		RS.L	1
MyScreen	RS.L	1
VisualInfo	RS.L	1
first_menudef	RS.L	1
menu_count	RS.L	1
first_menu	RS.L	1
menu_pool	RS.L	1
alias_pool	RS.L	1
first_alias	RS.L	1
MPipePtr	RS.L	1
app_name	RS.L	1
wbbase		RS.L	1
copysize	RS.L	1
temp5		RS.L	1
temp6		RS.L	1
temp7		RS.L	1
appwinport	RS.L	1
appwindow	RS.L	1
pubscreen	RS.L	1
pubname		RS.L	1
windowptr	RS.L	1
utilbase	RS.L	1
online_help	RS.L	1
windowname	RS.L	1
mem_addr	RS.L	1
wild_flag	RS.B	1
help_flag	RS.B	1
x9		RS.W	1
getmemchar	RS.L	1
getcharmem	RS.L	1
DIRignore	RS.B	30
wild_string	RS.B	40	allow 40 chars for wildcard
date_mark	RS.L	3	3 lwords
mem_mark	RS.L	3	3 lwords chip/fast/total
CD_string	RS.B	80	Allow 80 bytes.
prompt_string	RS.B	80	Allow 80 bytes.
prompt_args	RS.B	40	Allow 40 bytes
line_count	RS.W	1
mult_comm_ptr	RS.L	1
winXsize	RS.W	1
winYsize	RS.W	1
pipe_count	RS.B	1
break_flag	RS.B	1
cd_block	RS.L	1
cd_volnode	RS.L	1
x8		RS.W	1
indent_count	RS.W	1
resi_flag	RS.B	1
forcediskflag	RS.B	1
CLIflag		RS.B	1
WBflag		RS.B	1
oldwindowptr	RS.L	1
wb_msg		RS.L	1
iconbase	RS.L	1
diskobj		RS.L	1
filesys_old	RS.L	1
cdir_old	RS.L	1
if_flag		RS.B	1
x2		RS.B	1
goto_flag	RS.B	1
memclk_flag	RS.B	1
dest_label	RS.B	80
CLIbufstart	RS.L	1
mem_offset_addr	RS.L	1
io_Message	RS.B	20	io-request (timer)
io_Device	RS.L	1
io_Unit		RS.L	1
io_Command	RS.W	1
io_Flags	RS.B	1
io_Error	RS.B	1
tv_secs		RS.L	1
tv_micro	RS.L	1
io_pad		RS.L	2	don't remove
sizeofblk	RS.W	0



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

;	SECTION	MYSHELL,CODE
	
;Try to open dos then do the shell
start	moveq	#-1,d7
	move.l	a0,a3
	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	a3,EntryA0(a5)
	move.w	20(a6),kickver(a5)		Kickstart-Version
	lea	intuiname(pc),a1
	jsr	_LVOOldOpenLibrary(a6)
	tst.l	d0
	beq	intfail
	move.l	d0,intuibase(a5)
	lea	dosname(pc),a1
	jsr	_LVOOldOpenLibrary(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
	move.l	pr_CLI(a2),d0
	bne.s	.A
	subq.w	#1,CLIflag(a5)		WB-Start (set CLI&WBflag)
	lea	pr_MsgPort(a2),a0
	IFND	DEBUG
	jsr	_LVOWaitPort(a6)
	ENDC
	IFD	DEBUG
	moveq	#-1,d0
.AA	move.l	#1,d1
	dbra	d0,.AA
	ENDC
	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),d0
	beq.s	.B
	lsl.l	#2,d0
	move.l	d0,a0
	clr.l	12(a0)			Clear SegPointer
	bra.s	.B
.A	lsl.l	#2,d0			CLI-Start
	move.l	d0,a2
	move.l	cli_DefaultStack(a2),d0
	lsl.l	#2,d0
	move.l	d0,stacksize(a5)	save stacksize
	clr.l	cli_Module(a2)		do not free seglist
	cmp.b	#"r",1(a3)
	bne.s	.B
	addq.b	#1,noresi_flag(a5)
.B	move.l	dosbase(a5),a6		A6=DOSBASE
	tst.b	noresi_flag(a5)
	bne.s	doIT
	lea	ZShellName(pc),a4
	bsr	search_res2
	lea	start-4(pc),a1
	tst.l	d0
	IFD	DEBUG
	bra.s	doIT
	ENDC
	beq.s	cresi
	lsl.l	#2,d0
	move.l	d0,a2
	nop
	nop
VCheck	cmp.w	#VERSION,VCheck-start+6(a2)
	bne.w	normex
	addq.l	#1,resi_usecount(a0)
	cmp.l	a1,a2
	beq.s	doIT		running as resident
	jmp	JumpIn-start+4(a2) 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	KillAppWin
	bsr	FreeFNC
	bsr	FreeStuff
	moveq	#1,d1
	bsr	OutputCLInum
	bsr	RemoveCLI
	lea	start-4(pc),a0
	move.l	a0,d6
	lsr.l	#2,d6
	tst.b	noresi_flag(a5)
	bne.s	normex
	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
	moveq	#1,d1
	cmp.l	resi_usecount(a0),d1
	bne.s	crfail
	move.l	d0,d6	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)
normex	bsr	closelog	close logfile
	bsr	giveman		free manualmem
	move.l	thistask(a5),a0
	tst.b	CLIflag(a5)	How to UnLoad the Segment
	beq.s	.A
	move.l	pr_SegList(a0),d0
	beq.s	.B
	lsl.l	#2,d0
	move.l	d0,a0
	move.l	d6,12(a0)	Store Segment in SegPointer (WB/RUN)
.B	move.l	wb_msg(a5),d0
	beq.s	crfail
	move.l	d0,a0
	move.l	d6,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	d6,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

*********************************
*	MAIN BIT		*
*********************************
shell	move.l	sp,errorstack(a5)
	IFD	KILL
	cmp.w	#36,kickver(a5)
	blo.s	.D
	move.l	thistask(a5),a3
	lea	CleanUp(pc),a0
	move.l	a0,pr_ExitCode(a3)
	move.l	a5,pr_ExitData(a3)
.D	ENDC
	bsr	InitUtil
	lea	appicontx(pc),a0
	move.l	a0,app_name(a5)
	move.l	#DefaultFlags,d0
	bsr	SetFlags
	bsr	CreateCLI
	bne	ExitZShell		exit on error
	move.l	thistask(a5),a3
	move.l	pr_CLI(a3),a2
	add.l	a2,a2
	add.l	a2,a2
	move.l	a2,CLIptr(a5)
	move.l	cli_Prompt(a2),old_prompt(a5)	save prompt
	lea	prompt_args(a5),a0
	move.l	a0,d0
	lsr.l	#2,d0
	move.l	d0,cli_Prompt(a2)
	move.l	cli_SetName(a2),old_setname(a5)	save current dir name
	lea	CD_string(a5),a0
	move.l	a0,d0
	lsr.l	#2,d0
	move.l	d0,cli_SetName(a2)
	bsr	SetConHandles
;	bsr	SetMenuStrip
	cmp.w	#36,kickver(a5)		OS2 ?
	blo.s	.C
	move.l	pr_HomeDir(a3),old_homedir(a5)	save PROGDIR:
	clr.l	pr_HomeDir(a3)
	move.l	dl_Root(a6),a0
	bset	#0,rn_Flags(a0)	set wildstar flag (bit 24)
	bsr	InitAppWin
	tst.l	pr_CES(a3)
	bne.s	.C
	jsr	_LVOOutput(a6)
	move.l	d0,pr_CES(a3)		set error output handle
.C	tst.b	WBflag(a5)
	bne.s	notini		0=WB/1=newcli/2=run/3=pipe
	move.l	CLIptr(a5),a2
	moveq	#16,d0
	move.l	d0,cli_FailLevel(a2)
	bsr	initialise_default	initialize other stuff
notini	moveq	#0,d1
	bsr	OutputCLInum
	tst.b	CLIflag(a5)
	beq.s	.A
	cmp.b	#2,WBflag(a5)
	bhs.s	.A
	moveq	#-127,d0
	subq.l	#2,d0
	bsr	GetMessage	Welcome-Message
	lea	pr_TaskNum(a3),a1
	bsr	new_print
.A	bsr	eval_CD
	IFND	DEBUG
	bsr	execscr		execute startup script
	ENDC
chorus	bsr	CheckForbid	HERE BEGINS THE MAIN LOOP
	bsr	close_redirection
	bsr	pr_show_cursor	make sure cursor is visible
	bsr	raw_off		and raw mode is off
	clr.b	noreview_flag(a5)	and review is enabled
	bsr	get_line
	clr.b	break_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	dotchar(a5),d0
	bne.s	.A
	addq.l	#1,a0
	tst.b	(a0)
	bne.s	.B
	lea	CDbackstr(a5),a0	dir back
	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
	moveq	#0,d7
	move.b	#"?",d0		check for ? (help sign)
	bsr	CheckOneChar
	bne.s	.C
	bsr	help_man	? as command
	bra	chorus
.C	bsr	matchcmd		offset to d2.w
	beq.s	notfound
	move.l	parm1(a5),d7		check for ? (help sign)
	move.l	parm2(a5),d0
	beq.s	.D
	move.l	d0,a0
	move.b	#"?",d0
	bsr	CheckOneChar
	bne.s	.D
	bsr	help_man	? as arg
	bra	chorus
.D	move.l	sp,errorstack(a5)	important in scripts ?
	lea	cmdstart(pc),a0
intern	jsr	0(a0,d2.w)	call internal command
	tst.b	break_flag(a5)
	bne.s	com_break
chkfail	move.l	d0,last_failcode(a5)
	move.l	CLIptr(a5),a0
	cmp.l	cli_FailLevel(a0),d0	ALL COMMANDS MUST RETURN D0=0 unless failure
	blo	chorus
com_fail move.l	d0,-(sp)
	bsr	close_redirection	additional for pipes
	bsr	FreeGetChar
	move.l	#-154,d0
	bsr	GetMessage		Fail Level
	move.l	sp,a1
	bsr	new_print
	move.l	(sp)+,d0
com_break 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

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

ZShellName	dc.b	"ZShell",0
dosname		dc.b	"dos.library",0
intuiname	dc.b	"intuition.library",0
utilname	dc.b	"utility.library",0

defscript	dc.b	"S:ZStart",0	;changed V2.0
appicontx	dc.b	"Shell-It !",0
prompt_args_tx	dc.b	9,27,'[33m%P> ',0
end_tx		dc.b	" end",0
askforsize	dc.b	$9b," q",0
help_ret	dc.b	"^XHELP^M",0

helpld	dc.b	"Loading "
helpman	dc.b	"ZShell.doc",0
helpmor	dc.b	13,$9b,"2m %d%% %ld bytes. Use: (shift+)cursor,"
	dc.b	"(back)space,numeric,s,n,j,w,r,h",$9b,"K",$9b,"m",13,0

ctrl_init	dc.b	46,23,17,19,5,9,24,27,20,25,8,10,13,12,18,22,6,16
ctrl_inite		;CTRL-Codes
more_init	dc.b	"ABCDSTqsnjwrh"	MORE keys
more_inite

	dc.b	0,"$VER: "
helptx1 dc.b	"ZShell "
	dc.l	ZVERSION
	dc.b	" (31-Jul-96)",10
	dc.b	"(C)1990,91 Paul Hayter (V1.3); "
	dc.b	"Updated 1993-96 by Martin Gierich.",10
	dc.b	"Freeware, NO commercial usage !",10
	dc.b	"Please send your comments to"
	dc.b	" uj3w@rz.uni-karlsruhe.de",10,10
	dc.b	"Commands:",0
helptx2 dc.b	"Options:",10
	dc.b	"-r (recursive): Copy,Delete,Dir,Join,List,Move,Protect",10
	dc.b	"-c (clear): Avail,Endcli,Locate,Menu,Path,Resident",10
	dc.b	"-q (quick): Dir,List,Delete",10,10
	dc.b	"Editing: (SHIFT+) Cursor, <-, DEL,"
	dc.b	" (SHIFT+) TAB, ESC and see CONFIG CTRLKEYS",10
	dc.b	". for dir back, force disk or abbreviation",10
	dc.b	"Type 'help ?' for more help."
helptx3	even

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

InitUtil	;init to-upper-conversion table
	moveq	#64,d0
	lsl.l	#2,d0
	bsr	iwantmem
	move.l	d0,chartable(a5)
	beq	ExitZShell
	move.l	d0,a2
	move.w	#255,d0
.A	move.b	d0,0(a2,d0.w)
	dbra	d0,.A
	moveq	#"A",d0
.C	move.b	d0,"a"-"A"(a2,d0.w)
	addq.w	#1,d0
	cmp.b	#"Z"+1,d0
	bne.s	.C
	move.w	#192,d0
.F	move.b	d0,224-192(a2,d0.w)
	addq.w	#1,d0
	cmp.b	#222+1,d0
	bne.s	.F

	move.l	4.w,a6
	lea	utilname(pc),a1	open utility.library
	moveq	#37,d0
	jsr	_LVOOpenLibrary(a6)
	move.l	d0,utilbase(a5)
	beq.s	.D
	move.l	d0,a6
	move.w	#255,d2
.E	move.w	d2,d0
	jsr	_LVOToUpper(a6)
	move.b	d0,0(a2,d2.w)
	dbra	d2,.E
.D	move.l	dosbase(a5),a6
	rts

FreeUtil
	move.l	chartable(a5),a1
	moveq	#64,d0
	lsl.l	#2,d0
	bsr	givemem
	move.l	utilbase(a5),d0
	beq.s	.D
	move.l	d0,a1
	move.l	4.w,a6
	jsr	_LVOCloseLibrary(a6)
.D	move.l	dosbase(a5),a6
	rts

initialise_default
	move.b	#LF,past(a5)
	lea	prompt_args_tx(pc),a0	init prompt
	lea	prompt_args(a5),a1
.C	move.b	(a0)+,(a1)+
	bne.s	.C
	moveq	#ctrl_inite-ctrl_init-1,d0
	lea	ctrl_init(pc),a0
	lea	ctrl_codes-1(a5),a1
.B	move.b	(a0)+,(a1)+		init ctrl-codes and dotchar
	dbra	d0,.B
	moveq	#more_inite-more_init-1,d0
	lea	more_init(pc),a0
	lea	morekeys(a5),a1
.A	move.b	(a0)+,(a1)+		init keys for MORE
	dbra	d0,.A
	lea	helpman(pc),a0
	move.l	a0,online_help(a5)
	move.l	#50000,copysize(a5)
	move.l	#4000,FNCsize(a5)
	rts

SetConHandles
	jsr	_LVOOutput(a6)	SAVE THE CONSOLE HANDLERS
	move.l	d0,outhandle(a5)
	move.l	d0,stdout(a5)
	jsr	_LVOInput(a6)
	move.l	d0,inhandle(a5)
	move.l	d0,stdin(a5)
	rts

CheckOneChar	;d0=char to check in a0=parm
	move.b	(a0),d1
	bsr	compD1D0nocase
	bne.s	.A
	tst.b	1(a0)
	bne.s	.A
	cmp.b	#$22,-1(a0)
	beq.s	.A
	moveq	#0,d0
	rts
.A	moveq	#1,d0
	rts

OutputCLInum		;ENTRY: d1=0:start, d1=1:end
	btst	#FLdebug,Flags+3(a5)
	beq.s	.A
	lea	tempbuf(a5),a1
	bsr.s	InsertCLInum
	tst.l	d1
	beq.s	.B
	lea	end_tx(pc),a2
.C	move.b	(a2)+,(a1)+
	bne.s	.C
	subq.l	#1,a1
.B	move.b	#LF,(a1)+
	clr.b	(a1)
	lea	tempbuf(a5),a1
	bsr	pr_error
.A	rts

InsertCLInum		;string in a1
	lea	ZShellName(pc),a2
.B	move.b	(a2)+,(a1)+	append "ZShell"
	bne.s	.B
	subq.l	#1,a1
InsertCLInum2
	move.l	thistask(a5),a2
	move.l	pr_TaskNum(a2),d0
	bra	qpr10		append CLI number

InitAppWin
	btst	#FLraw,Flags+2(a5)	test raw-mode
	beq.s	.A
	move.l	4.w,a6
	jsr	_LVOCreateMsgPort(a6)	get MsgPort
	move.l	d0,appwinport(a5)
	beq.s	.A
	move.l	d0,a2
	move.l	dosbase(a5),a6
	move.l	windowptr(a5),d2	get ptr to window
	beq.s	.A
	bsr	OpenWBLib
	beq	.A
	moveq	#0,d0
	moveq	#0,d1
	move.l	d2,a0
	sub.l	a1,a1
	exg.l	a1,a2
	jsr	_LVOAddAppWindowA(a6)	make AppWin
	move.l	d0,appwindow(a5)
.A	move.l	dosbase(a5),a6
	rts

KillAppWin
	move.l	appwindow(a5),d2
	beq.s	.B
	bsr	OpenWBLib
	move.l	d2,a0
	jsr	_LVORemoveAppWindow(a6)	remove AppWin
	clr.l	appwindow(a5)
.B	move.l	appwinport(a5),d0
	beq.s	.A
	move.l	d0,a0
	move.l	4.w,a6
	jsr	_LVODeleteMsgPort(a6)	remove MsgPort
	clr.l	appwinport(a5)
.A	move.l	dosbase(a5),a6
	rts

GetWindowPtr	;pointer to Console-Window to d0 (0 for fail)
	move.l	thistask(a5),a0
	move.l	pr_ConsoleTask(a0),d0
	move.l	d0,packettask(a5)
	beq.s	.A
	bsr	GetDiskInfo
	beq.s	.A
	moveq	#0,d0
	tst.l	sp_res1(a5)
	beq.s	.A
	move.l	id_VolumeNode(a5),windowptr(a5)	it is in here !
	bsr	RequestersOn
.A	rts

GetWinSize	;Get dimensions of current output console
	movem.l	d2/d3/a2,-(sp)
	move.l	outhandle(a5),d1
	beq.s	.H
	jsr	_LVOIsInteractive(a6)
	tst.l	d0
	beq.s	.H
	lea	askforsize(pc),a1
	bsr	pr_string
	move.l	outhandle(a5),d1
	lea	NewPrintBuffer(a5),a2
	move.l	a2,d2
	moveq	#100,d3
	jsr	_LVORead(a6)	get size of window
	move.l	a2,a0
	add.l	d0,a2
	cmp.b	#$9b,-1(a2)	has it read the whole thing ?
	bne.s	.B
.D	move.l	outhandle(a5),d1
	move.l	a2,d2
	moveq	#1,d3		read a single char
	move.l	a0,-(sp)
	jsr	_LVORead(a6)
	move.l	(sp)+,a0
	moveq	#1,d1
	cmp.l	d0,d1
	bne.s	.H		got a single char ?
	addq.l	#1,a2
	cmp.b	#"r",-1(a2)	check for "r" at end
	bne.s	.D

.B	cmp.l	a0,a2
	bls.s	.H
	cmp.b	#"r",-(a2)	"r" at end
	bne.s	.B
	cmp.b	#" ",-(a2)	" " as second last
	bne.s	.B
	moveq	#1,d1		go two numbers back
.C	cmp.b	#";",-(a2)	";" to limit numbers
	bne.s	.C
	dbra	d1,.C
	addq.l	#1,a2
	move.l	a2,a1
	bsr	convert_ASCII_to_num
	move.w	d0,winYsize(a5)
	bsr	convert_ASCII_to_num
	move.w	d0,winXsize(a5)
.H	move.w	winYsize(a5),d0
	bne.s	.A
	moveq	#18,d0
.A	movem.l	(sp)+,d2/d3/a2
	rts

dec2asc	ext.l	d0	put decimal number in D0.w to string in A0
	move.l	#10000,d1
.C	divu	d1,d0
	bne.s	.E
	divu	#10,d1
	beq.s	.A
	swap	d0
	bne.s	.C
.D	divu	d1,d0
.E	add.b	#"0",d0
	move.b	d0,(a0)+
	swap	d0
	ext.l	d0
	divu	#10,d1
	bne.s	.D
.A	rts


*CHECK WHETHER A SCRIPT NAME WAS TYPED ON ENTRY TO ZSHELL
execscr	move.l	EntryA0(a5),d0
	move.l	d0,parm1(a5)
	beq.s	.C
	move.l	d0,a0
	tst.b	(a0)
	bne	xz2	;NB this is OK, xz2 will pop the return addr 
			;and jump to chorus
	rts
.C			;handle DEFAULT SCRIPT FILE s:zstart
	bsr	RequestersOff	disable volume requesters
	lea	defscript(pc),a2
	move.l	a2,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	bsr	RequestersOn
	move.l	d0,d1	test lock
	beq.s	.B
	jsr	_LVOUnLock(a6)
	move.l	a2,a0
	bra	xz2
.B	rts

CheckForbid
	move.l	4.w,a0		Check for not closed
	moveq	#-1,d0
	cmp.b	294(a0),d0	Disables or
	bne.s	.A
	cmp.b	295(a0),d0	Forbids
	beq.s	.B
.A	move.b	d0,294(a0)	and avoids crashes !
	move.b	d0,295(a0)
	moveq	#22,d1
	bsr	GuruIt
.B	rts

	IFD	KILL
CleanUp	movem.l	d0-d7/a0-a6,-(sp)
	move.l	d1,a5
	move.l	intuibase(a5),a6
	suba.l	a0,a0
	jsr	_LVODisplayBeep(a6)
	move.l	thistask(a5),a3
	clr.l	pr_ExitCode(a3)
	movem.l	(sp)+,d0-d7/a0-a6
	rts
	ENDC

**********************************************************
FreeFNC	move.l	FNCbuffer(a5),d0
	beq.s	.A
	move.l	d0,a1
	move.l	FNCsize(a5),d0
	bsr	givemem
.A	clr.l	FNCbuffer(a5)
FlushFNC
	clr.l	FNCcycle(a5)
	clr.w	FNCfill(a5)
	clr.b	FNCbuffered(a5)
	rts

* Subroutine for name2complete, limiting chars: : / " ; | and space
cjk1	subq.l	#1,a1
	cmp.b	#":",(a1)
	beq.s	cjke
	cmp.b	#"/",(a1)
	beq.s	cjke
cjk2	cmp.b	#$22,(a1)
	beq.s	cjke
	cmp.b	#" ",(a1)
	beq.s	cjke
	cmp.b	#";",(a1)
	beq.s	cjke
	cmp.b	#"|",(a1)
cjke	addq.l	#1,a1
	rts

name2complete	;used by complet and CTRL-F
	lea	shelline(a5),a1
	move.l	a1,a0
	move.l	d5,d6
	beq.s	.B
	add.l	d5,a1
	bsr	cjk1
	beq.s	.B
.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 in d3
	tst.l	FNCcycle(a5)
	bne.s	.I
	lea	0(a2,d6.l),a3
	move.b	(a3),d2
	clr.b	(a3)
	move.l	a0,-(sp)
	move.l	a2,a0
	bsr	handle_wild_dirs	check for wild cards
	move.l	(sp)+,a0
	move.b	d2,(a3)
.I	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
	subq.l	#1,a1
	bsr	cjk2
	bne.s	.D
.E	rts

* Complete Filename in Shelline *
* INTERNAL: a2 points to part of filename, d6 length of part *
* ENTRY: d4: linmax , d5:linhere *
complet	tst.l	FNCcycle(a5)
	beq.s	.C
	moveq	#0,d0
	move.b	FNCchars(a5),d0
	sub.l	d0,d5		delete some chars for cycling
	bsr	delete_in_mem
.C	clr.b	temp2buf(a5)
	bsr	name2complete
	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	DisplayBeep
	bsr	fibexam2
	moveq	#0,d3
	tst.l	fib_DirEntryType(a5)
	bpl.s	cplbuf		if plus,is directory
cplunlk	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	rts			an error occured

cplbuf	move.l	FNCbuffer(a5),d0	create and init FNC buffer
	bne.s	.A
	move.l	FNCsize(a5),d0
	bsr	iwantmem
	beq.s	wdhcpl
	move.l	d0,FNCbuffer(a5)
.A	move.l	FNCcycle(a5),d1
	beq.s	.B
	move.l	d1,d0
.B	move.l	d0,a4
	move.b	#1,FNCbuffered(a5)
	move.l	d7,d0
	lsl.l	#2,d0
	move.l	d0,a1
	move.l	fl_Volume(a1),d0
	move.l	fl_Key(a1),d1
	lea	fib_Date(a5),a0
	move.l	(a0)+,d2
	add.l	(a0)+,d2
	add.l	(a0)+,d2
	tst.w	FNCfill(a5)
	beq.s	.C
	cmp.l	FNCvolume(a5),d0	check volume node
	bne.s	.C
	cmp.l	FNCkey(a5),d1		check disk block number
	bne.s	.C
	cmp.l	FNCdate(a5),d2		check date of last change
	beq.s	wdhcpl
.C	move.l	d0,FNCvolume(a5)
	move.l	d1,FNCkey(a5)
	move.l	d2,FNCdate(a5)
	move.l	FNCbuffer(a5),a4
	clr.l	FNCcycle(a5)
	clr.b	FNCbuffered(a5)
	clr.b	(a4)+
	move.l	FNCsize(a5),d0
	subq.l	#2,d0
	move.w	d0,FNCfill(a5)

wdhcpl	tst.b	FNCbuffered(a5)
	bne.s	cplbuffered
	bsr	fibexnx		not buffered: get next filename from dir
	tst.l	d0		next filename or dirname
	beq	endcpl
;	lea	fib_FileName(a5),a0
	bsr	ignorematch	wildcheck for names to ignore
	beq.s	wdhcpl
;	lea	fib_FileName(a5),a0
	lea	tempbuf(a5),a1	store filename in tempbuf
	move.l	a1,a3
.B	tst.w	FNCfill(a5)
	bne.s	.D
	move.b	(a0)+,(a1)+	buffer already full: only copy name
	bne.s	.B
	bra.s	.F
.D	subq.w	#1,FNCfill(a5)
	move.b	(a0),(a1)+	copy name
	move.b	(a0)+,(a4)+	store filename to buffer
	bne.s	.B
.F	moveq	#" ",d0		add a space at the end of files
	tst.l	fib_DirEntryType(a5)
	bmi.s	.G		if plus,is directory
	moveq	#"/",d0		add a / at the end of dirs
.G	move.b	d0,-1(a1)
	clr.b	(a1)		null-end
	tst.w	FNCfill(a5)
	beq.s	.E
	subq.w	#1,FNCfill(a5)	if buffer not full: do same with buffer
	move.b	d0,-1(a4)
	clr.b	(a4)+
.E	bra.s	wd2cpl

cplbuffered
	tst.b	FNCback(a5)	cycle back ?
	beq.s	.A
.D	subq.l	#1,a4
	cmp.l	FNCbuffer(a5),a4	yes: check for begin of buffer
	bls.s	.E
	tst.b	-1(a4)		look for begin of previous name
	bne.s	.D
	bra.s	.C
.E	move.l	FNCbuffer(a5),a4	look for end of buffer
.F	tst.b	(a4)+
	bne.s	.F
	tst.b	(a4)
	bne.s	.F
	bra.s	.D

.A	tst.b	(a4)+		was buffered: skip to next name
	bne.s	.A
	tst.b	(a4)		test for end of buffer
	bne.s	.C
	tst.l	FNCcycle(a5)
	beq	endcpl
	move.l	FNCbuffer(a5),a4	end of buffer: set at begin
	addq.l	#1,a4		skip first null-byte
.C	move.l	a4,a3

wd2cpl	move.l	a3,a0
	tst.b	wild_flag(a5)
	beq.s	.F
.B	tst.b	(a3)+
	bne.s	.B
	subq	#2,a3
	move.b	(a3),d2		save last char
	clr.b	(a3)		clear space or /
	bsr	wildmatcher	check wildcards
	move.b	d2,(a3)
	move.l	a0,a3
	tst.l	d0
	bne	wdhcpl
	bra.s	.H		do not check for matching parts
.F	move.l	a2,a1
	move.l	d6,d2
	bra.s	.D
.A	move.b	(a0)+,d0
	move.b	(a1)+,d1
	bsr	compD1D0nocase		does it match to part ?
	bne	wdhcpl
.D	dbra	d2,.A
.H	tst.l	d3
	bne.s	wd3cpl
	moveq	#-1,d0		! first time: copy filename !
	lea	temp2buf(a5),a0
.C	addq.l	#1,d0
	move.b	(a3)+,(a0)+
	bne.s	.C
	moveq	#1,d3
	tst.l	FNCcycle(a5)
	beq	wdhcpl
	sub.l	d6,d0
	move.b	d0,FNCchars(a5)	chars more than given part of name
	move.l	a4,FNCcycle(a5)	position of next name to FNCcycle
	bra	endcpl

wd3cpl	tst.l	d3		! next time !
	bmi.s	.E
	moveq	#-1,d3
	btst	#FLmatch,Flags+3(a5)
	beq.s	.E
	btst	#FLhide,Flags+2(a5)
	beq.s	.H
	bsr	pr_hide_cursor
	bsr	GetWinSize
.H	bsr	pr_lf
	lea	temp2buf(a5),a1	print first time
	move.l	a1,a0
	moveq	#-1,d0
.C	addq.l	#1,d0
	tst.b	(a0)+
	bne.s	.C
	move.b	d0,FNCnumchars(a5)
	bsr	pr_string
	bsr	pr_space
.E	move.l	a3,a1
	lea	temp2buf(a5),a0
.G	move.b	(a0)+,d0
	move.b	(a1)+,d1
	bsr	compD1D0nocase	next time: find longest common part
	bne.s	.D
	tst.b	-1(a0)
	beq.s	.D
	tst.b	-1(a1)
	bne.s	.G
.D	clr.b	-1(a0)
	btst	#FLmatch,Flags+3(a5)
	beq	wdhcpl
	lea	NewPrintBuffer(a5),a0
	moveq	#0,d0
.A	addq.l	#1,d0
	move.b	(a3)+,(a0)+
	bne.s	.A
	move.b	#" ",-1(a0)
	clr.b	(a0)
	move.l	d0,d1
	tst.w	winXsize(a5)
	beq.s	.F
	add.b	FNCnumchars(a5),d1
	cmp.w	winXsize(a5),d1
	blo.s	.F
	move.l	d0,d1
	bsr	pr_lf
.F	move.b	d1,FNCnumchars(a5)
	lea	NewPrintBuffer(a5),a1
	bsr	pr_string	print other times
	bra	wdhcpl		repeat with all filenames

endcpl	tst.b	FNCbuffered(a5)
	bne.s	.A
	clr.b	(a4)		end buffer with 0
.A	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	tst.l	d3
	beq	DisplayBeep
	bpl.s	.D		enable cycling if multiple matches found
	move.l	FNCbuffer(a5),FNCcycle(a5)
	clr.b	FNCchars(a5)
	btst	#FLmatch,Flags+3(a5)
	beq	.B
	bsr	pr_lf
	bsr	gimme4		print shelline again
.B	tst.b	wild_flag(a5)
	beq.s	.D
	move.b	d6,FNCchars(a5)
	rts
.D	lea	temp2buf(a5),a1
	move.l	d6,d2
	bra.s	insert_string2	insert new stuff in shelline

insert_string	;insert string in a1 into shelline
	moveq	#0,d2
insert_string2	;d2=number of chars before current pos
	moveq	#-1,d1
.G	addq.l	#1,d1		D1=length
	tst.b	(a1)+
	bne.s	.G
	sub.l	d2,d1
	bpl.s	.B
	move.l	d1,d0		calc chars to backspace
	neg.l	d0
	sub.l	d0,d2
	move.l	a1,-(sp)
	sub.l	d0,d5
	bsr	delete_in_mem	string to overwrite was longer
	move.l	(sp)+,a1
	moveq	#0,d1
.B	subq.l	#1,a1		for later
	move.l	d4,d0
	add.l	d1,d0
	cmp.w	#SHELLINE_SIZE-2,d0	make sure line is not too long
	blo.s	.E
	bsr	DisplayBeep
	bra	gimme3
.E	movem.l	a2-a3,-(sp)
	lea	shelline(a5),a0	ethel
	lea	1(a0,d4.w),a3	A3=linmax
	move.l	a3,a2
	add.l	d1,a2		A2=linmax+length
	lea	0(a0,d5.w),a0	linhere
.A	move.b	-(a3),-(a2)	insert chars into shelline
	cmp.l	a3,a0
	bne.s	.A
	move.l	d1,d0
	add.l	d2,d0
	bra.s	.C
.D	move.b	-(a1),-(a2)	copy found filename
.C	dbra	d0,.D
	movem.l	(sp)+,a2-a3
	add.l	d1,d5
	add.l	d1,d4
.F	bra	gimme3		print shelline


**********	END OF FNC	***********

FreeGetChar
	move.l	getcharmem(a5),d0
	beq.s	.A
	move.l	d0,a1
	move.l	#400,d0
	bsr	givemem
	clr.l	getmemchar(a5)
	clr.l	getcharmem(a5)
.A	rts

get_one_char	;read one char from keyboard to d6, process AppWindow
	move.l	getmemchar(a5),d0
	beq.s	.G
	addq.l	#1,getmemchar(a5)
	move.l	d0,a0
	move.b	(a0),d6		get char from memory (for function keys)
	beq.s	.H
	rts
.H	bsr.s	FreeGetChar
.G	bsr	clearArgs
	move.l	inhandle(a5),myArg1(a5)
	lea	tempbytes(a5),a0
	move.l	a0,myArg2(a5)
	moveq	#1,d0
	move.l	d0,myArg3(a5)
	move.l	thistask(a5),a0
	move.l	pr_ConsoleTask(a0),packettask(a5)
	moveq	#ACTION_READ,d0
	move.l	d0,packettype(A5)
	bsr	sendpacket2	read keyboard with packets
	moveq	#0,d3
	move.l	thistask(a5),a0
	move.b	pr_MsgPort+MP_SIGBIT(a0),d1
	bset	d1,d3		set wait bit for reading
	move.l	appwinport(a5),d2
	beq.s	.A
	move.l	d2,a0
	move.b	MP_SIGBIT(a0),d1
	bset	d1,d3		set wait bit for appwindow
.A	move.l	d3,d0
	jsr	_LVOWait(a6)	wait for anything
	tst.l	d2
	beq.s	.B
	move.l	d2,a0
	jsr	_LVOGetMsg(a6)	try to get appwinmsg
	tst.l	d0
	beq.s	.B
	move.l	d0,a2
	bsr	ProcessApp	look at it
	move.l	a2,a1
	jsr	_LVOReplyMsg(a6)
	move.l	dosbase(a5),a6
	lea	tempbuf(a5),a1
	move.l	d2,-(sp)
	bsr	insert_string	write iconname to shelline
	move.l	d5,old_linhere(a5)
	move.l	d4,old_linmax(a5)
	move.l	(sp)+,d2
	move.l	intuibase(a5),a6
	move.l	windowptr(a5),d0
	beq.s	.C
	move.l	d0,a0
	jsr	_LVOActivateWindow(a6)
.C	move.l	4.w,a6

.B	move.l	thistask(a5),a0
	lea	pr_MsgPort(a0),a0
	jsr	_LVOGetMsg(a6)	try to get read-packet-reply
	move.l	d0,d1
	beq.s	.A
	move.l	dosbase(a5),a6
	lea	sp_node(a5),a0
	move.l	#212,d0
	cmp.l	d1,a0
	bne	pr_galactic	got wrong dospacket
	tst.l	sp_res1(a5)
	bmi.s	.D		error occured
	beq.s	.E
	move.b	tempbytes(a5),d6
	rts
.D	moveq	#20,d1
	bra.s	.F
.E	moveq	#21,d1
.F	bsr	GuruIt
	bra	ExitZShell

saveundo
	lea	shelline(a5),a0
	lea	CLIbuf(a5),a1
	move.l	d4,d0
	bra.s	.B
.A	move.b	(a0)+,(a1)+
.B	dbra	d0,.A
	clr.b	(a1)
	rts

* A1 pts to past, d0=nost
gimme	lea	shelline(a5),a2	Get shelline from history
	move.l	d0,nost(a5)
	cmp.l	now(a5),d0
	bne.s	.C
	moveq	#-1,d4		reset linmax
	lea	CLIbuf(a5),a0
.D	addq.l	#1,d4
	move.b	(a0)+,(a2)+	copy undo to shelline
	bne.s	.D
	move.l	d4,d5		linmax=linhere
	bra	gimme3

.C	moveq	#0,d5		linhere = 0
.B	addq.l	#1,d0		copy to shelline
	and.l	#HISTORY_SIZE-1,d0
	cmp.b	#LF,0(a1,d0.l)
	beq.s	.A
	move.b	0(a1,d0.l),0(a2,d5.l)
	addq.l	#1,d5
	bra.s	.B
.A	move.l	d5,d4		linhere=linmax

gimme3	bsr	pr_hide_cursor		Print out newer shelline
	move.l	old_linhere(a5),d0	and overwrite old one
	bsr	cursor_left	go to left start of line
	lea	shelline(a5),a1
	move.l	a1,a0
	add.l	d4,a0
	move.l	d4,d0
	move.l	old_linmax(a5),d1
	sub.l	d4,d1
	bmi.s	.A
	add.l	d1,d0
	bra.s	.C
.D	move.b	#" ",(a0)+	append some spaces, if needed
.C	dbra	d1,.D
.A	clr.b	(a0)
	bsr	pr_string	overwrite old line
	sub.l	d5,d0
	bsr	cursor_left	restore cursor
	bra	pr_show_cursor

gimme4	bsr	pr_prompt		Print out shelline again
	lea	shelline(a5),a1
	clr.b	0(a1,d4.l)	clear last byte
	bsr	pr_string	print shelline
	bsr	pr_show_cursor
restore_cursor
	move.l	d4,d0
	sub.l	d5,d0

cursor_left	;move cursor d0 chars left
	move.l	d0,-(sp)
	beq.s	.A
	bsr	csi_with_num
	move.b	#"D",(a0)
	bsr	pr_string
.A	move.l	(sp)+,d0
	rts

cursor_right	;move cursor d0 chars right
	move.l	d0,-(sp)
	beq.s	.A
	bsr	csi_with_num
	move.b	#"C",(a0)
	bsr	pr_string
.A	move.l	(sp)+,d0
	rts

csi_with_num	;puts <ESC>[ and number in d0 to tempbuf=a1
	lea	NewPrintBuffer(a5),a1
	move.l	a1,a0
	move.b	#27,(a0)+
	move.b	#"[",(a0)+
	bsr	dec2asc
	clr.b	1(a0)
	rts

************************************************************************
* 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
	move.l	a0,-(sp)
	addq.b	#1,noreview_flag(a5)
	bsr	do_show_cursor
	bsr	compose_prompt
	bsr	pr_prompt
	moveq	#0,d5		D5=linhere
	moveq	#0,d4		D4=linmax
	btst	#FLraw,Flags+2(a5)	test noraw-mode
	bne.s	.A
	move.l	a0,a2			use console in cooked mode
.C	move.l	a2,d2
	move.l	stdin(a5),d1
	beq	ExitZShell
	move.l	#SHELLINE_SIZE,d3
	jsr	_LVORead(a6)
	move.l	d0,d4
	bmi	ExitZShell
	bne.s	.D
	bsr	Kiconify
	bclr	#FLraw,Flags+2(a5)
	bra.s	.C
.D	clr.b	0(a2,d4.l)
	cmp.b	#LF,-1(a2,d4.l)
	bne.s	.C
	move.l	(sp)+,a2
	bra	finland
	
.A	clr.b	CLIbuf(a5)	(for undo)	use console in raw mode
next_ch	move.l	d5,old_linhere(a5)
	move.l	d4,old_linmax(a5)
	bsr	raw_on		MAKE SURE RAW MODE IS ON
	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),a2
	move.l	gather_ptr(a5),d0
	move.b	d6,0(a2,d0.l)		save byte from CSI sequence.
	addq.l	#1,gather_ptr(a5)
	moveq	#79,d1
	cmp.l	d1,d0
	blo.s	.A
	clr.l	gather_ptr(a5)
.A	cmp.b	#'@',d6
	blo.s	fetch_csi		keep gathering if char < @
	cmp.b	#'~',d6
	bhi.s	fetch_csi		keep gathering if char > ~

Krawevent
	cmp.b	#"|",d6		CHECK RAW EVENTS
	bne	Kfunc_key
	move.l	a2,a1
	bsr	convert_ASCII_to_num
ev_menu	moveq	#10,d1
	cmp.l	d0,d1		CHECK MENU EVENT
	bne.s	ev_clog
	bsr	convert_ASCII_to_num
	bsr	convert_ASCII_to_num
	move.l	windowptr(a5),d1
	beq.s	.C
	move.l	d1,a0
	move.l	28(a0),a0	Window->MenuStrip
	move.l	intuibase(a5),a6
	jsr	_LVOItemAddress(a6)
	move.l	dosbase(a5),a6
	tst.l	d0
	beq.s	.C
	move.l	d0,a0
	move.l	mi_SIZEOF(a0),d0
.C	beq	next_ch
	move.l	d0,a1
	bra	insert_macro

ev_clog	moveq	#11,d1
	cmp.l	d0,d1		CHECK CLOSE GADGET EVENT
	bne.s	.A
	bsr	Kiconify
.A	bra	next_ch

ExitZShell
	move.l	dosbase(a5),a6		TOTALLY-EXIT-ROUTINE
	move.l	errorstack(a5),sp	kill return address on stack
	bsr	close_redirection
	bsr	raw_off
	bsr	kill_script
	moveq	#-1,d7
	rts

Kfunc_key
	cmp.b	#'~',d6		CHECK FUNCTION KEYS AND HELP KEY
	bne	Kcsr_right
* TRANSLATE FUNC CODE TO F1,F2 ETC AND SET UP POINTERS
	lea	temp2buf(a5),a1	create search string in temp2buf
	cmp.b	#"?",(a2)	a2=gather
	bne.s	.E
	lea	help_ret(pc),a1	HELP KEY
	bra.s	insert_macro

.E	move.l	gather_ptr(a5),d0
	cmp.b	#3,d0		check if two codes eg '12'
	bne.s	.A
	move.b	#"S",(a1)+	SHIFT+FUNCTION
	addq.l	#1,a2
	bra.s	.C
.A	cmp.b	#2,d0		UNSHIFTED FUNCTION
	bne.s	next_c8

.C	move.b	(a2),d0
	move.b	#"F",(a1)+	insert "F"
	addq.b	#1,d0
	move.b	d0,(a1)+	insert one digit number
	cmp.b	#':',d0
	blo.s	.D
	move.b	#'1',-1(a1)	insert 10
	move.b	#'0',(a1)+
.D	clr.b	(a1)

	bsr	search_alias	returns d0=pointer to alias
	beq.s	next_c8
	move.l	d0,a1
	lea	4(a1),a1	skip link and name
.F	tst.b	(a1)+
	bne.s	.F
insert_macro		;Insert macro definition in a1 into shelline
	tst.l	getmemchar(a5)
	bne.s	next_c8
	move.l	#400,d0
	bsr	iwantmem
	beq.s	next_c8
	move.l	d0,getcharmem(a5)
	move.l	d0,getmemchar(a5)
	move.l	d0,a0
	move.w	#400-2,d1
.C	move.b	(a1)+,(a0)+
	beq.s	.A
	dbra	d1,.C
	clr.b	(a0)
.A	bsr	parse_echo	convert control characters
next_c8	bra	next_ch


Kcsr_right
	cmp.b	#' ',gather(a5)	check for shifted cursor up/down
	beq	Kshift_left
	cmp.b	#'C',d6		CHECK RIGHT ARROW	<CSI>C
	bne.s	Kcsr_left
	move.l	FNCcycle(a5),d0
	beq.s	.B
	cmp.l	FNCbuffer(a5),d0
	bne.s	.A
.B	cmp.l	d4,d5
	bhs.s	Kcsr_left
	addq.l	#1,d5
	moveq	#1,d0
	bsr	cursor_right
.A	clr.l	FNCcycle(a5)
	bra.s	next_c8

Kcsr_left
	clr.l	FNCcycle(a5)
	cmp.b	#'D',d6		CHECK LEFT ARROW	<CSI>D
	bne.s	Kcsr_up
	tst.l	d5
	beq.s	Kcsr_up
	subq.l	#1,d5
	moveq	#1,d0
	bsr	cursor_left
	bra.s	next_c8

Kcsr_up	cmp.b	#'A',d6		CHECK UP ARROW		<CSI>A
	bne.s	Kcsr_down
	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	#LF,0(a1,d0.l)
	bne.s	.A
.B	bsr	gimme
next_c5	bra.s	next_c8

Kcsr_down
	cmp.b	#'B',d6		CHECK DOWN ARROW	<CSI>B
	bne.s	Kshift_tab
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	#LF,0(a1,d0.l)
	bne.s	.A
.B	bsr	gimme
	bra.s	next_c5

Kshift_tab
	cmp.b	#'Z',d6		CHECK TAB & SHIFT	<CSI>Z
	bne.s	Kshift_down
	move.b	#"Y"&$3f,d6	emulate CTRL-Y
	bra	not_csi

Kshift_down
	cmp.b	#'S',d6		CHECK SHIFT DOWN	<CSI>S
	bne.s	Kshift_up
	move.l	now(a5),nost(a5)	nost = now (the bottom)
	bra.s	up_bit

Kshift_up
	cmp.b	#'T',d6		CHECK SHIFT UP		<CSI>T
	bne.s	next_c5
	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
next_c6	bra.s	next_c5
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	#LF,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,d2		save d5
	bsr	gimme
	move.l	d2,d5
	bsr	restore_cursor
	bra.s	next_c6


Kshift_left
	clr.l	FNCcycle(a5)
	cmp.b	#'A',d6		CHECK SHIFT LEFT ARROW	<CSI> A
	bne.s	Kshift_right
	move.l	d5,d0
	bsr	cursor_left
	moveq	#0,d5
next_c7	bra.s	next_c6

Kshift_right
	cmp.b	#'@',d6		CHECK SHIFT RIGHT ARROW	<CSI> @
	bne.s	next_c7
	move.l	d4,d0
	sub.l	d5,d0
	bsr	cursor_right
	move.l	d4,d5
	bra.s	next_c7

*********************************************************************
* Was not a CSI code
not_csi	tst.l	FNCcycle(a5)			CHECK BACKTICK
	beq.s	.C	only in fnc-cycle mode
	cmp.b	#"`",d6
	bne.s	.C
	addq.b	#1,FNCback(a5)
	bra.s	.D

.C	cmp.b	ctrl_codes+4(a5),d6		CHECK TAB
	bne.s	not_fnc
.D	bsr	RequestersOff
	move.l	FNCcycle(a5),-(sp)
	bsr	complet		complete filename
	tst.l	(sp)+
	bne.s	.A
	bsr	saveundo
.A	bsr	RequestersOn
	clr.b	FNCback(a5)
	bra.s	next_c7

not_fnc
	clr.l	FNCcycle(a5)
	lea	ctrl_codes(a5),a0
	lea	ctrlkeys_tab(pc),a1
	moveq	#ctrl_inite-ctrl_init-2,d0
.A	cmp.b	(a0)+,d6
	bne.s	.C
	move.w	(a1),d0
	lea	not_csi(pc),a0
	jsr	0(a0,d0.w)
	bra.s	next_c7
.C	addq.l	#2,a1
	dbra	d0,.A

not_ctrlkey
	cmp.b	#$7f,d6				CHECK DELETE
	bne.s	not_del
	cmp.l	d4,d5
	bhs.s	.A
	moveq	#1,d0
	bsr	delete_chars
.A
next_c9	bra.s	next_c7

not_del
	cmp.b	#13,d6				CHECK CR
	beq	do_cr
	cmp.b	#" ",d6				CHECK normal char
	blo.s	.C
	cmp.w	#SHELLINE_SIZE-2,d4	INSERT A CHAR IN THE SHELLINE
	blo.s	.D
	bsr	DisplayBeep		make sure line is not too long
	bra.s	.C
.D	bsr	pr_hide_cursor
	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
.A	move.b	-(a0),-(a2)	insert char into shelline
	cmp.l	a0,a1
	bne.s	.A
	lea	shelline(a5),a1
	move.b	d6,0(a1,d5.w)
	addq.l	#1,d4
	clr.b	0(a1,d4.l)	clear last
	add.l	d5,a1
	bsr	pr_string	print last part of line
	addq.l	#1,d5
	move.l	d4,d0
	sub.l	d5,d0
	bsr	cursor_left	restore cursor
	bsr	pr_show_cursor
	bsr	saveundo
.C	bra.s	next_c9


ctrlkeys_tab
	dc.w	Kdel_right_word-not_csi		0  CTRL-W
	dc.w	Kdel_left_word-not_csi		1  CTRL-Q
	dc.w	Kdel_to_start-not_csi		2  CTRL-S
	dc.w	Kdel_to_end-not_csi		3  CTRL-E
	dc.w	DisplayBeep-not_csi		4  CTRL-I (TAB)
	dc.w	Kdel_line-not_csi		5  CTRL-X
	dc.w	Kiconify-not_csi		6  CTRL-[ (ESC)
	dc.w	Kword_right-not_csi		7  CTRL-T
	dc.w	Kshow_review-not_csi		8  CTRL-Y (Shift-TAB)
	dc.w	Kbackspace-not_csi		9  CTRL-H (Backspace)
	dc.w	Kto_history-not_csi		10 CTRL-J (Shift-Return)
	dc.w	Kreturn-not_csi			11 CTRL-M (Return)
	dc.w	Kclear_screen-not_csi		12 CTRL-L
	dc.w	Kword_left-not_csi		13 CTRL-R
	dc.w	Kshow_history-not_csi		14 CTRL-V
	dc.w	Krequest_file-not_csi		15 CTRL-F
	dc.w	FreeFNC-not_csi			16 CTRL-P


back_chars		;delete d0 chars left to cursor
	sub.l	d0,d5
	bmi	GuruIt
	bsr	cursor_left
delete_chars		;delete d0 chars under cursor
	bsr	delete_in_mem
	move.l	d0,d1
	bra.s	.D
.E	move.b	#" ",(a0)+	append spaces to overwrite
.D	dbra	d1,.E
	clr.b	(a0)
	bsr	pr_hide_cursor
	lea	shelline(a5),a1
	add.l	d5,a1
	bsr	pr_string	print last part of line
	add.l	d4,d0
	sub.l	d5,d0
	bsr	cursor_left	restore cursor
	bsr	pr_show_cursor
	rts

delete_in_mem		;delete d0 chars under cursor in shelline(a5)
	lea	shelline(a5),a0
	add.l	d5,a0
	lea	0(a0,d0.l),a1
	move.l	d4,d1
	sub.l	d5,d1
	sub.l	d0,d1
	bmi	GuruIt
	bra.s	.B
.A	move.b	(a1)+,(a0)+	copy last part of line
.B	dbra	d1,.A
	sub.l	d0,d4
	rts

word_left
	lea	shelline-1(a5),a0
	add.l	d5,a0
	moveq	#0,d0
	move.l	d5,d1
.F	beq.s	.D
	bsr	tab_check
	bne.s	.C
	addq.l	#1,d0
	subq.l	#1,a0
	subq.l	#1,d1
	bra.s	.F
.A	bsr	tab_check
	beq.s	.D
	addq.l	#1,d0
	subq.l	#1,a0
.C	dbra	d1,.A
.D	rts

word_right
	lea	shelline(a5),a0
	add.l	d5,a0
	moveq	#0,d0
	move.l	d4,d1
	sub.l	d5,d1
.F	beq.s	.D
	bsr	tab_check
	beq.s	.C
	addq.l	#1,d0
	addq.l	#1,a0
	subq.l	#1,d1
	bra.s	.F
.A	bsr	tab_check
	bne.s	.D
	addq.l	#1,d0
	addq.l	#1,a0
.C	dbra	d1,.A
.D	rts

tab_check cmp.b	#' ',(a0) words are separated by / . : ; | or space
	beq.s	.A
	cmp.b	#':',(a0)
	beq.s	.A
	cmp.b	#'.',(a0)
	beq.s	.A
	cmp.b	#'/',(a0)
	beq.s	.A
	cmp.b	#';',(a0)
	beq.s	.A
	cmp.b	#'|',(a0)
.A	rts

Kword_left
	bsr	word_left	go to last word
	sub.l	d0,d5
	bra	cursor_left

Kword_right
	bsr	word_right	go to next word
	add.l	d0,d5
	bra	cursor_right

Kbackspace
	tst.l	d5
	beq.s	.A
	moveq	#1,d0
	bsr	back_chars	delete one char left to cursor
.A	rts

Kdel_to_start
	move.l	d5,d0
	bra	back_chars	delete to start of line

Kdel_to_end
	move.l	d4,d0
	sub.l	d5,d0
	bra	delete_chars	delete to end of line

Kdel_left_word
	bsr	word_left	delete last word
	bsr	back_chars
	rts

Kdel_right_word
	bsr	word_right	delete next word
	bra	delete_chars

Kdel_line
	bsr	saveundo
	moveq	#0,d4
	moveq	#0,d5
	bra	gimme3		delete whole shelline

Kto_history
	bsr	do_cr2		push line to history
	move.l	errorstack(a5),sp
	bra	chorus

Kclear_screen
	lea	clrtx(pc),a1
	bsr	pr_string	clear window
	bra	gimme4

Kshow_history
	movem.l	d3-d7/a2-a4,-(sp)
	lea	past(a5),a2
	move.l	now(a5),d3
	move.l	#HISTORY_SIZE,d2
	sub.l	a3,a3
	moveq	#0,d6
	bsr	viewhist	view history buffer with MORE
	movem.l	(sp)+,d3-d7/a2-a4
	bra	gimme4

Kshow_review
	tst.l	ReviewSize(a5)
	beq.s	.A
	movem.l	d3-d7/a2-a4,-(sp)
	sub.l	a3,a3
	moveq	#0,d6
	bsr	viewbuffer	view review buffer with MORE
	movem.l	(sp)+,d3-d7/a2-a4
	bsr	gimme4
.A	rts

Kiconify
	btst	#FLappicon,Flags+3(a5)
	beq.s	.C		exit immediately
	tst.b	openwin_flag(a5)
.C	beq	ExitZShell
	bsr	WaitAppIcon
	bsr	gimme4
	lea	tempbuf(a5),a1
	tst.b	(a1)
	beq.s	.A
	bsr	insert_string
.A	rts

Krequest_file
	tst.l	windowptr(a5)		Display Filerequester
	beq	.A
	move.l	4.w,a6
	lea	aslname(pc),a1
	jsr	_LVOOldOpenLibrary(a6)
	move.l	d0,d7
	beq	.A
	move.l	dosbase(a5),a6
	bsr	name2complete
	move.l	d7,a6
	lea	tempbuf(a5),a0
	move.l	a0,a3
	move.l	d6,d7
.F	addq.l	#1,d7
	move.b	(a1)+,(a0)+		copy path
	bne.s	.F
	move.b	d3,(a2)			replace null-char by old one
	move.l	a0,a1
	bra.s	.G
.H	move.b	(a2)+,(a0)+		copy pattern or filepart
.G	dbra	d6,.H
	tst.b	wild_flag(a5)
	bne.s	.I
	move.b	#"*",(a0)+
.I	clr.b	(a0)
	lea	temp2buf(a5),a0
	moveq	#-1,d0
	move.l	a0,a2
	move.l	#ASL_TB+10,(a2)+	InitialPattern
	move.l	a1,(a2)+
	move.l	#ASL_TB+9,(a2)+		InitialDrawer
	move.l	a3,(a2)+
	move.l	#ASL_TB+2,(a2)+		Window
	move.l	windowptr(a5),(a2)+
	move.l	#ASL_TB+43,(a2)+	SleepWindow
	move.l	d0,(a2)+
	move.l	#ASL_TB+1,(a2)+		TitleText
	lea	ZShellName(pc),a1
	move.l	a1,(a2)+
	move.l	#ASL_TB+46,(a2)+	DoPatterns
	move.l	d0,(a2)+
	btst	#FLwild,Flags+3(a5)
	beq.s	.E
	move.l	#ASL_TB+61,(a2)+	RejectPattern
	lea	FNCignore(a5),a1
	move.l	a1,(a2)+
.E	move.l	#ASL_TB+63,(a2)+	FilterDrawers
	clr.l	(a2)+
	clr.l	(a2)			TAG_END
	moveq	#0,d0
	jsr	_LVOAllocAslRequest(a6)
	move.l	d0,d3
	beq.s	.B
	move.l	d3,a0		request-struct
	move.l	a2,a1		no tags
	jsr	_LVOAslRequest(a6)
	tst.l	d0
	beq.s	.C
	move.l	d3,a0
	move.l	rf_File(a0),a1
	move.l	rf_Dir(a0),a0
	lea	tempbuf(a5),a2
	move.l	a2,a3
	bsr	addpath
.D	tst.b	(a2)+
	bne.s	.D
	subq.l	#1,a2
	bsr	MaybeInsertQuote
	move.b	#" ",(a2)+
	clr.b	(a2)
	move.l	a3,a1
	move.l	d7,d2
	subq.l	#1,d2
	move.l	a6,a4
	move.l	dosbase(a5),a6
	bsr	insert_string2
	move.l	a4,a6
	bra.s	.J
.C	bsr	FreeGetChar
.J	move.l	d3,a0
	jsr	_LVOFreeAslRequest(a6)
.B	move.l	a6,a1
	move.l	4.w,a6
	jsr	_LVOCloseLibrary(a6)
.A	move.l	dosbase(a5),a6
	rts

******************************************************************
Kreturn	addq.l	#4,sp
do_cr	move.l	(sp)+,a2
do_cr2	move.l	d4,d0
	sub.l	d5,d0
	bsr	cursor_right	to end of line
	bsr	pr_lf
	lea	shelline(a5),a4
	move.b	#LF,0(a4,d4.w)	hack job	(MUST END IN LF 0)
	clr.b	1(a4,d4.w)	for alias stuff
	tst.l	d4		nothing typed ?
	beq	finland
;push it to history
	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	#LF,0(a1,d0.l)
	bne.s	.A
	lea	(a4),a0
	bra.s	.C
.D	cmp.b	#LF,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	#LF,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	#LF,0(a1,d1.l)
	bne.s	.G	BRANCH IF WRAPPED AROUND
	cmp.l	d3,d1
	bne.s	finland	BRANCH IF THEN = (10) & THEN <> NOW
.G	
*	move.l	d3,then(a5)	then=now
.H	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	#LF,d0
	bne.s	.H		***
	move.l	d3,then(a5) SET NEW THEN (TOP OF HISTORY)

******* 
finland	lea	prompt_string(a5),a1	write to review-buffer
	move.l	a1,d2
	moveq	#-1,d3
.E	addq.l	#1,d3
	tst.b	(a1)+
	bne.s	.E
	bsr	toreview
	move.l	a2,d2
	move.l	d4,d3
	addq.l	#1,d3
	bsr	toreview
.D	bsr	GetWindowPtr
	bsr	raw_off
	move.l	a2,a0
	move.l	d4,d0
	rts

;	End of Command Line Editor
**********************************************


* DO SCRIPT FILE STUFF   ENTRY A0 -> input line
scr_in	movem.l	a0-a1/a6,-(sp)
	clr.b	break_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	#304,d0
	bsr	pr_DOSerr
	move.b	#1,break_flag(a5)
	bra.s	terminate_script
.B	move.l	scsize(a5),d1	;read a line from the script file
	add.l	scaddr(a5),d1
	sub.l	scptr(a5),d1
	beq.s	terminate_script
	bpl.s	scr_in2
terminate_script
	bsr	kill_script
	move.l	errorstack(a5),sp
	bra	chorus

scr_in2	move.l	a0,a2
	move.l	#SHELLINE_SIZE-2,d2
	moveq	#0,d0
	move.l	scptr(a5),a1
	cmp.b	#LF,(a1)	single LF line ?
	beq.s	.B
.A	move.b	(a1)+,(a2)+	copy line from script
.F	subq.l	#1,d2		check shelline size limit
	beq.s	.G
	addq.l	#1,d0
	subq.l	#1,d1
	bne.s	.D
.G	move.b	#LF,(a2)+	script end without LF
	bra.s	.E
.D	cmp.b	#LF,(a1)	LF at end of line ?
	bne.s	.A
	cmp.b	#$5c,-1(a1)	escaped ?
	bne.s	.B
	subq.l	#1,a2		YES: skip LF and overwrite \
	addq.l	#1,a1
	bra.s	.F
.B	move.b	(a1)+,(a2)+	LF
.E	clr.b	(a2)		0 at end
	move.l	a1,scptr(a5)
	btst	#FLdebug,Flags+3(a5)	debug output ?
	beq.s	.C
	bsr	compose_prompt
	bsr	pr_prompt
	move.l	a0,a1
	bsr	pr_error
.C	rts			a0=shelline, d0=length

kill_script
	move.l	a0,-(sp)
	tst.b	scflag(a5)
	beq.s	.A
	move.l	scaddr(a5),a1
	move.l	scsize(a5),d0
	bsr	givemem
.A	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
	clr.l	mult_comm_ptr(a5)	break multiple commands
	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	#LF,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 25 parameters	*
*********************************************************
get_line
	addq.l	#1,count_line(a5)
	lea	ZShellName(pc),a0
	move.l	a0,parm1(a5)
	lea	shelline(a5),a0
	move.l	mult_comm_ptr(a5),d0 SKIP PROMPT IF SCRIPT OR MULT COMMANDS
	bne.s	.D
	cmp.b	#2,WBflag(a5)
	bhs	endbground
	bsr	type_in	NOTE HISTORY STUFF ASSUMES SHELLINE HOLDS THE LINE
	clr.b	noreview_flag(a5)
	cmp.b	#';',(a0)		is 1st character a ';'
	beq.s	get_line
	cmp.b	#'*',(a0)
	beq.s	get_line
	cmp.b	#'#',(a0)
	beq.s	get_line		do next line if comment
	cmp.b	#LF,(a0)
	beq.s	get_line
	tst.b	scflag(a5)
	bne.s	.C
	bsr	handle_logfile
	bra.s	.C
.D	move.l	d0,a0		change A0 for multiple commands
.C	bsr	handle_command_alias	keep A0
	bsr	parse_line
	bsr	handle_real_pipes
	btst	#FLdebug,Flags+3(a5)
	beq.s	gl16
	tst.b	scflag(a5)
	bne.s	gl16
	move.l	thistask(a5),a1
	move.l	pr_TaskNum(a1),d0
	lea	tempbuf(a5),a1
	bsr	qpr10		get CLI number
	move.l	#"-> "<<8,(a1)+
	subq.l	#6,a1
	bsr	pr_error
	move.l	a0,a1
	bsr	pr_error
gl16	move.l	a0,-(sp)	clear parms
	lea	parm1(a5),a0
	lea	endofparms(a5),a1
.A	clr.l	(a0)+
	cmp.l	a0,a1
	bne.s	.A
	move.l	(sp)+,a0
	lea	parm1(a5),a2 do 1st parm seperate to establish CLI residue
	bsr	get_parm
	tst.l	d2
	bne.s	.C
	move.l	errorstack(a5),sp	no command
	bra	chorus
.C	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	labeltx+1(pc),a0
	bsr	lf_compare_strings
	bne	skipline
	move.l	(sp)+,a0

* Script-IF handling		V2.9c: nested ifs (Mark J. Swift)
test_ifs
	moveq	#0,d0
        move.b	if_flag(a5),d0          <>0 if if encountered earlier
        beq.s	no_ifs
        add.w	#if_condition,d0
        tst.b	0(a5,d0.w)              0 if condition TRUE
        beq.s	no_ifs
if_false move.l	a0,-(sp)               push ptr to next
        cmp.b	#IFSIZE,if_flag(a5)
        bge.s	try_else
try_if  lea	iftx+1(pc),a0
        bsr	lf_compare_strings
        bne.s	try_else
        moveq	#0,d0
        move.b	if_flag(a5),d0
        addq.w	#1,d0
        move.b	d0,if_flag(a5)
        add.w	#if_condition,d0
        move.b	-1(a5,d0.w),0(a5,d0.w)
        bra.s	skipline
try_else lea	elsetx+1(pc),a0
        bsr	lf_compare_strings
        bne.s	try_endif
        moveq	#0,d0
        move.b	if_flag(a5),d0
        add.w	#if_condition,d0
        tst.b	-1(a5,d0.w)
        bne.s	skipline
        not.b	0(a5,d0.w)
        bra.s	skipline
try_endif lea	endiftx+1(pc),a0
        bsr	lf_compare_strings
        bne.s	skipline
        sub.b	#1,if_flag(a5)
skipline addq.l	#8,sp            get rid of last plus return address
	bra	chorus

no_ifs	move.l	a1,(a2)+	save address of parm1
	lea	CLIbuf(a5),a1
.C	move.l	a0,CLIbufstart(a5)
	move.b	(a0)+,d0	skip all preceding spaces
	cmp.b	#LF,d0
	beq.s	.D
	cmp.b	#" ",d0
	beq.s	.C
.B	move.b	d0,(a1)+
	move.b	(a0)+,d0	copy sudoCLIresidue out
	cmp.b	#LF,d0		only look for LF end
	bne.s	.B
.E	move.b	-(a1),d0	skip all ending spaces
	cmp.b	#" ",d0
	beq.s	.E
	addq.l	#1,a1
.D	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 25 parms
	bne.s	gl4
	moveq	#118,d0		too many args error
	bra	pr_galactic
gl3	rts

endifz  tst.b	if_flag(a5)
        beq.s	elseOK
        sub.b	#1,if_flag(a5)
        moveq	#RETURN_OK,d0
        rts
elsez   moveq	#0,d0
        move.b	if_flag(a5),d0
        beq.s	elseOK
        add.w	#if_condition,d0
        not.b	0(a5,d0.w)
elseOK  moveq	#RETURN_OK,d0
        rts

*************************
*        SKIP 		*
*************************
skipz	move.l	parm2(a5),d1
	beq	too_less_args
test_gs	tst.b	scflag(a5)	CAN ONLY GOTO FROM WITHIN SCRIPT
	bne.s	.A
	moveq	#RETURN_ERROR,d0
	rts
.A	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
	
**************************************************************
handle_logfile		;writes date/time and commandline to logfile
	move.l	loghandle(pc),d0
	beq.s	logend
	move.l	a0,a3
	lea	temp2buf(a5),a2
	move.l	a2,d1
	jsr	_LVODateStamp(a6)
	move.l	a2,a1
	lea	tempbuf(a5),a2
	bsr	insert_date
	move.b	#" ",(a2)+
	move.l	a2,a1
	bsr	InsertCLInum2
	move.b	#" ",(a1)+
	move.l	a3,a0
.C	move.b	(a0)+,(a1)+
	bne.s	.C
	lea	tempbuf(a5),a0
write2log		;write string in a0 to logfile
	move.l	loghandle(pc),d1
	move.l	a0,d2
	moveq	#-1,d3
.A	addq.l	#1,d3
	tst.b	(a0)+
	bne.s	.A
	jsr	_LVOWrite(a6)
	move.l	a3,a0
logend	rts
	
*ENTRY A0=shelline	ONLY HANDLES ALIASES OF FIRST KEYWORD.
handle_command_alias
	movem.l	d0-d2/a1-a4,-(sp)
	cmp.b	#LF,(a0)
	beq	hca_nothing_typed
	move.l	a0,a1
.A	cmp.b	#" ",(a1)+	skip preceding spaces
	beq.s	.A
	subq.l	#1,a1
	lea	tempbuf(a5),a3
	move.b	#LF,(a3)
	clr.b	1(a3)	must be null end string
	lea	temp2buf(a5),a2	COPY PARM AT A0 TO SEARCH STR
	moveq	#78,d1
.B	move.b	(a1)+,d0
	bsr	checkendofline
	beq.s	.D		hca_one_parm
	cmp.b	#" ",d0
	beq.s	.D		hca_one_parm
	move.b	d0,(a2)+
	dbra	d1,.B
.D	subq.l	#1,a1
.E	move.b	(a1)+,(a3)+	COPY FROM SPACE ONWARDS to tempbuf
	bne.s	.E	WHOLE LINE ENDS IN NULL.
hca_one_parm
	clr.b	(a2)	null end search string

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

	lea	4(a2),a2
.G	tst.b	(a2)+		A2=alias definition
	bne.s	.G
	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	#LF,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	#LF,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	#LF,(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
	move.l	a1,a4
.D	move.b	(a3)+,(a1)+	copy tempbuf onto end
	bne.s	.D
	moveq	#100,d0
	bsr	stacktest
	bne	redirtw
	bsr	handle_command_alias	recursive alias substitution
	
hca_nothing_typed
	movem.l	(sp)+,d0-d2/a1-a4
	rts

search_alias
* uses temp2buf
* EXIT: D0 ptr to the associated alias. D1 pts to prior alias
* RETURN D0=0 IF NOT FOUND.
	movem.l	d2-d4/a1-a2,-(sp)
	lea	temp2buf(a5),a1
	move.l	a1,d2
	lea	first_alias(a5),a2
	move.l	a2,d4		NOTE PRIOR ALIAS
	move.l	(a2),d3

.D	beq.s	.B
	move.l	d3,a2
	lea	4(a2),a2	A2=current alias 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.s	.D
.B	move.l	d4,d1
	move.l	d3,d0
	movem.l	(sp)+,d2-d4/a1-a2
	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
	beq.s	last_parm2
	cmp.b	#$20,d1
	beq.s	get_parm1
	cmp.b	#$9,d1		skip tabs
	beq.s	get_parm1
	cmp.b	#LF,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	cmp.b	#LF,(a0)	handle idiots who type \ at end of line
	beq.s	gp3
	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	#LF,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)
last_parm2	moveq #0,d2	;signify the end
		rts
gp3	subq.l	#1,a0	if ends in LF then dont null end, catch that next time
	rts

**************************************************
close_redirection
	tst.b	redirect_in(a5)
	beq.s	.A
	tst.l	PipeTask(a5)		handle real pipe
	beq.s	.G
.H	move.l	inhandle(a5),d1
	lea	tempbuf(a5),a0
	move.l	a0,d2
	move.l	#2*SHELLINE_SIZE,d3
	jsr	_LVORead(a6)		read till pipe_in is empty
	tst.l	d0
	bmi.s	.G
	bne.s	.H
.G	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)
.A	tst.b	redirect_out(a5)
	beq.s	.B
	move.l	MPipePtr(a5),d0
	beq.s	.I
	clr.l	MPipePtr(a5)
	movem.l	d2-d7/a2-a4,-(sp)
	sub.l	a3,a3
	move.l	d0,d6
	bsr	viewbuffer		>M show output with more
	movem.l	(sp)+,d2-d7/a2-a4
	bra.s	.B
.I	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)
.B	clr.w	redirect_in(a5)		clear redirect_in and redirect_out

	btst	#FLpipe,Flags+2(a5)
	bne.s	.E
	lea	pipe_in(a5),a2		handle pseudo pipe
	tst.b	(a2)
	beq.s	.C
	move.l	a2,d1
	jsr	_LVODeleteFile(a6)	delete temporary file
.C	lea	pipe_out(a5),a1
.D	move.b	(a1)+,(a2)+		copy pipe_out to pipe_in
	bne.s	.D
	bra.s	.F

.E	tst.b	pipe_out(a5)		handle real pipe
	beq.s	.F
	move.l	4.w,a6
	moveq	#0,d0
	bset	#SIGBREAKB_CTRL_E,d0
	jsr	_LVOWait(a6)	wait for CTRL-F or till task returns
	move.l	dosbase(a5),a6
.F	clr.b	pipe_out(a5)		no pipe_out
	rts

*************************************************
*	This is the command line parser	V2.8	*
*	Entry: A0 points to shelline		*
*************************************************
parse_line
	move.l	a0,-(sp)
	move.l	a0,-(sp)
	lea	pipe_in(a5),a2
	tst.b	(a2)
	beq.s	.A
	bsr	re_in3
.A	move.l	(sp)+,a4	a4=new commandline
	move.l	a4,a3		a3=old commandline
	move.l	a4,d4		d5 used by redirect
	addq.l	#1,d4		d4=start of commandline
parseloop
	move.b	(a3)+,d0
	move.b	d0,(a4)+
	cmp.b	#$5c,d0		IS IT BACKSLASH \ ?
	bne.s	psquote
	tst.b	pipe_out(a5)
	bne.s	psquote
.C	move.b	(a3)+,d0	skip next char and check for LF
	cmp.b	#";",d0
	beq.s	.G
	cmp.b	#"|",d0
	beq.s	.G
	cmp.b	#"<",d0
	beq.s	.G
	cmp.b	#">",d0
	beq.s	.G
	move.l	d4,d1
	addq.l	#1,d1
	cmp.l	d1,a3		start of line -> alias-disabling
	bne.s	.H
.G	subq.l	#1,a4		overwrite \ if followed by ; | < >
.H	move.b	d0,(a4)+
	cmp.b	#$5c,d0		double backslash ?
	beq.s	.C
	bra	pschklf
psquote	cmp.b	#'"',d0		IGNORE ; AND | BETWEEN QUOTES
	bne.s	psmulti
	cmp.l	d4,a4		start of line ?
	beq.s	.D
	cmp.b	#" ",-2(a4)	space before starting quote ?
	beq.s	.D
	cmp.b	#"=",-2(a4)	= before starting quote ? (for AmigaDOS)
	bne	redspc
.D	move.b	(a3)+,d0
	move.b	d0,(a4)+
	cmp.b	#LF,d0		missing ending quote ?
.A	beq	redquo
	cmp.b	#$5c,-2(a4)
	beq.s	.D
	cmp.b	#'"',d0
	bne.s	.D
	cmp.b	#" ",(a3)	space behind ending quote ?
	beq.s	psmulti
	cmp.b	#LF,(a3)	except at end of line
	bne	redspc
psmulti	cmp.b	#";",d0		CHECK MULTI CMD OR PIPE
	bne.s	.A
	move.b	#LF,-1(a4)	replace ; with LF
	tst.l	PipeTask(a5)	is it a pipe task ?
	bne.s	pslend		yes: no mult comms
	move.l	a4,mult_comm_ptr(a5)
	bra.s	psexit
.A	cmp.b	#"|",d0
	beq	handle_pipes
psredir	cmp.b	#" ",-2(a4)	look for space before < or >
	bne.s	.F
	tst.b	pipe_out(a5)
	bne.s	.F
	lea	redir_tx(pc),a0	CHECK REDIRECTION
	move.l	a0,parm1(a5)
	cmp.b	#'>',d0
	bne.s	.I
	bsr	redir_out
	bra.s	.C
.I	cmp.b	#'<',d0
	bne.s	.C
	bsr	redir_in
.C	lea	ZShellName(pc),a0
	move.l	a0,parm1(a5)
.F
pschklf	cmp.b	#LF,d0		there must be a LF at end
	bne	parseloop
pslend	clr.l	mult_comm_ptr(a5)
	clr.b	pipe_count(a5)
psexit	move.b	(a3)+,(a4)+	copy other multi commands
	bne.s	psexit
	lea	pipe_out(a5),a2
	tst.b	(a2)
	beq.s	.A
	bsr	re_out2		output redirect pipes
.A	move.l	(sp)+,a0
	rts

checkendofline
	cmp.b	#";",d0
	beq.s	.D
	cmp.b	#"|",d0
	beq.s	.D
	cmp.b	#LF,d0		look for end of line
.D	rts

redquo	moveq	#119,d0
	bra.s	rederr2
rederr	jsr	_LVOIoErr(a6)	print DOS error
rederr2	bsr	pr_DOSerr	print error in D0
	bra.s	redirtw

redspc	lea	nospace_tx(pc),a0
	bra.s	reditw
redir_twice
	lea	redirtwice(pc),a0
reditw	bsr	PrintError
redirtw	move.l	thistask(a5),a1
	bsr	SetSignalE
	move.l	a4,d2
.A	move.b	(a3)+,(a4)+	copy other multi commands
	bne.s	.A
	lea	shelline(a5),a1
	move.l	mult_comm_ptr(a5),d0
	beq.s	.B
	move.l	d0,a1
.B	sub.l	a1,d2
	bsr	pr_error
	lea	tempbuf(a5),a0
	move.l	a0,a1
	tst.l	d2
	beq.s	.D
	subq.l	#1,d2
	bra.s	.D
.C	move.b	#" ",(a0)+
.D	dbra	d2,.C
	move.b	#"^",(a0)+
	move.b	#LF,(a0)+
	clr.b	(a0)
	bsr	pr_error
	clr.b	pipe_out(a5)
	clr.l	mult_comm_ptr(a5)
	bra	galactic

redir_in
	tst.b	redirect_in(a5)
	bne.s	redir_twice
	cmp.b	#">",(a3)
	beq.s	redir_both
re_in2	bsr	copy_redirector
re_in3	move.l	#MODE_OLDFILE,d2
	bsr	redir_open2
	bra	ChngIn
redir_both
	tst.b	redirect_out(a5)
	bne.s	redir_twice
	bsr	re_in2
	lsl.l	#2,d0
	move.l	d0,a0
	move.l	thistask(a5),a1
	move.l	pr_ConsoleTask(a1),-(sp)
	move.l	fh_Type(a0),pr_ConsoleTask(a1)
	beq.s	.A
	lea	star(pc),a2
.A	addq.l	#1,a4
	bsr	re_out2
	move.l	thistask(a5),a1
	move.l	(sp)+,pr_ConsoleTask(a1)
	rts
redir_out
	tst.b	redirect_out(a5)
	bne	redir_twice
	cmp.b	#">",(a3)
	beq.s	redir_append
	bsr	copy_redirector
	move.l	a2,a0
	move.b	#"M",d0
	bsr	CheckOneChar
	bne.s	re_out2
	move.l	ReviewPtr(a5),MPipePtr(a5)	redir to MORE
	beq	redir_open3
	addq.b	#1,redirect_out(a5)
	bra	redir_open3
re_out2	move.l	#MODE_NEWFILE,d2
	bsr	redir_open2
	bra	ChngOut
redir_append
	move.l	#MODE_READWRITE,d2
	bsr	redir_open
	bsr	ChngOut
	move.l	d0,d1
	moveq	#0,d2	set position
	moveq	#1,d3	set mode
	jsr	_LVOSeek(a6)
	rts

ChngIn	move.l	thistask(a5),a0
	move.l	d0,pr_CIS(a0)	MAKE STDIN DIFFERENT.
	move.l	d0,inhandle(a5)
	addq.b	#1,redirect_in(a5)
	rts
ChngOut	move.l	thistask(a5),a0
	move.l	d0,pr_COS(a0)
	move.l	d0,outhandle(a5)
	addq.b	#1,redirect_out(a5)
	rts

redir_open
	bsr	copy_redirector
redir_open2
	tst.b	(a2)		null string opens NIL:
	bne.s	.B
	lea	connil(pc),a2
.B	move.l	a2,a0
	move.b	#"W",d0		"w" opens default window
	bsr	CheckOneChar
	bne.s	.C
	lea	conname(pc),a2
	move.l	windowname(a5),d0
	beq.s	.C
	move.l	d0,a2	
.C	move.l	a2,d1
	jsr	_LVOOpen(a6)	open file
	tst.l	d0
	beq	rederr
redir_open3
	move.l	d5,a3	skip redir-name in cmdline
.A	subq.l	#1,a4
	cmp.b	#" ",-1(a4)
	beq.s	.A
	rts

* ENTRY	A3 pts to redirection symbol
*	A4 pts to new shelline
* EXIT	A2 pts to null end string in tempbuf
*	A3 is increased, so that redir name is deleted from shelline
*	A4 is decreased to delete space before redir
copy_redirector
	lea	tempbuf(a5),a2
	move.l	a2,a0
	move.l	a3,a1		save start of redirection string
	cmp.b	#">",(a1)	handle append redirection properly
	bne.s	.B
	addq.l	#1,a1
.B	cmp.b	#$22,(a1)	is string enclosed in quotes ?
	bne.s	.A
	addq.l	#1,a1		skip first quote
	move.b	#$22,(a0)+	remember quotes
	addq.l	#1,a2
.C	move.b	(a1)+,d0
	cmp.b	#$22,d0		look for last quote
	beq.s	cpredsp
	cmp.b	#LF,d0		missing last quote ?
	beq	redquo
	move.b	d0,(a0)+	copy newstdin/out to nonstdin/out
	bra.s	.C
.A	move.b	(a1)+,d0
	cmp.b	#" ",d0		look for ending space
	beq.s	cpredlf
	bsr	checkendofline
	beq.s	cpredlf
	move.b	d0,(a0)+	copy newstdin/out to nonstdin/out
	bra.s	.A

cpredlf	subq.l	#1,a1
	cmp.b	#$22,-1(a1)
	beq	redquo
cpredsp	move.l	a1,d5
	clr.b	(a0)+	A0 should point to after the space or lf
	rts

*** PIPES V2.7 ***
handle_pipes
	btst	#FLpipe,Flags+2(a5)
	beq.s	.D
	tst.b	pipe_out(a5)
	bne	parseloop	check for next multi cmd or end of line
.D	move.b	#LF,-1(a4)		replace | with LF
	addq.b	#1,pipe_count(a5)
	tst.b	redirect_out(a5)
	bne	redir_twice
	move.l	a4,mult_comm_ptr(a5)
	lea	pipe_out(a5),a1
	lea	devpipe(pc),a2
	btst	#FLpipe,Flags+2(a5)
	bne.s	.A
	lea	devtemp(pc),a2
.A	move.b	(a2)+,(a1)+	copy "PIPE:" or "T:" to pipe_out
	bne.s	.A
	subq.l	#1,a1
	bsr	InsertCLInum
	btst	#FLpipe,Flags+2(a5)	real pipe ?
	bne.s	.C
	move.b	pipe_count(a5),d0	append pipe number for pseudo pipes
	bsr	qpr10
	clr.b	(a1)
	bra	psexit		do same like multi cmds
.C	clr.b	(a1)
	bra	parseloop	check for next multi cmd or end of line

handle_real_pipes
	btst	#FLpipe,Flags+2(a5)
	beq.s	.B
	tst.b	pipe_out(a5)
	beq.s	.B
	movem.l	d2-d7/a0-a4,-(sp)
	move.l	a0,a1
.C	cmp.b	#LF,(a1)+
	bne.s	.C
	lea	tempbuf(a5),a2		create parms for new task
	move.l	a2,parm2(a5)
	move.l	#"-w*"<<8,(a2)+
	move.l	a2,parm3(a5)
	move.w	#"-c",(a2)+
	clr.l	parm4(a5)
.F	move.b	(a1)+,(a2)+
	bne.s	.F
	clr.b	-2(a2)		clear LF
	move.l	4.w,a6
	moveq	#0,d0
	moveq	#0,d1
	bset	#SIGBREAKB_CTRL_E,d1
	jsr	_LVOSetSignal(a6)	clear signal CTRL-F
	move.l	dosbase(a5),a6
	moveq	#3,d7
	bsr	create_new_cli		create new task for real pipes
	beq.s	.A
	moveq	#16,d1
	bsr	GuruIt			creation of task failed
	lea	shelline(a5),a4
	bra	redirtw
.A	movem.l	(sp)+,d2-d7/a0-a4
.B	rts

endbground
	move.l	PipeTask(a5),d0
	beq.s	.A		started with RUN
	move.l	d0,a1		task real pipe started from
	bsr	SetSignalE	tell it to end
.A	bra	ExitZShell

SetSignalE		;a1=taskaddress
	move.l	4.w,a6
	moveq	#0,d0
	bset	#SIGBREAKB_CTRL_E,d0
	jsr	_LVOSignal(a6)
	move.l	dosbase(a5),a6
	rts

******************************
* Iconify Shell		V2.3 *
******************************
WaitAppIcon
	movem.l	d2-d7/a2-a4,-(sp)
	clr.b	tempbuf(a5)
;	cmp.w	#36,kickver(a5)
;	blo	.G
	bsr	KillAppWin
	bsr	raw_off
	bsr	clkof2
	bsr	ClearMenuStrip
	bsr	FreeGadTools
	bsr	CloseWin

	tst.l	diskobj(a5)
	bne.s	.I
	bsr	OpenIconLib
	beq.s	.A
	moveq	#3,d0
	jsr	_LVOGetDefDiskObject(a6)
	move.l	d0,diskobj(a5)
	beq	.A
.I	bsr	OpenWBLib
	beq	.A
	moveq	#0,d0	opened workbench.library
	moveq	#0,d1
	move.l	app_name(a5),a0
	move.l	thistask(a5),a1
	lea	pr_MsgPort(a1),a1
	move.l	a1,d3
	sub.l	a2,a2
	move.l	diskobj(a5),a3
	sub.l	a4,a4
	jsr	_LVOAddAppIconA(a6)	add appicon
	move.l	d0,d2
	beq.s	.B
	move.l	4.w,a6
.C	move.l	d3,a0
	jsr	_LVOWaitPort(a6)	wait for one message
	bsr	GetAppIMsgs
	move.l	wbbase(a5),a6
	move.l	d2,a0
	jsr	_LVORemoveAppIcon(a6)	remove appicon
.B	bsr	GetAppIMsgs

.A	move.l	dosbase(a5),a6
	tst.b	openwin_flag(a5)	restore window
	beq.s	.G
	move.l	thistask(a5),a3
	move.l	CLIptr(a5),a2
	move.l	windowname(a5),d1
	clr.b	openwin_flag(a5)
	bsr	OpenWin
	beq	ExitZShell
	bsr	SetConHandles
	bsr	PatchOuthandle
	bsr	InitAppWin
	move.l	first_menu(a5),d2
	beq.s	.D
	bsr	InitGadTools
	beq.s	.D
	bsr	CreateMenuStrip
.D	tst.b	memclk_flag(a5)
	beq.s	.G
	bsr	clkon
.G	movem.l	(sp)+,d2-d7/a2-a4
	rts

GetAppIMsgs
	move.l	4.w,a6
.B	move.l	d3,a0
	jsr	_LVOGetMsg(a6)		get all messages
	tst.l	d0
	beq.s	.A
	move.l	d0,a2
	cmp.w	#8,am_Type(a2)
	bne.s	.B
	bsr	ProcessApp
	move.l	a2,a1
	jsr	_LVOReplyMsg(a6)	reply them
	bra.s	.B
.A	rts

ProcessApp	;Message in a2
	movem.l	a2-a6,-(sp)
	move.l	am_NumArgs(a2),d0
	move.l	am_ArgList(a2),a0
	lea	tempbuf(a5),a2
	bra.s	.D

.E	move.l	a2,a3
	move.l	(a0)+,d1	process all args
	beq.s	.C		get name from lock to dir
	movem.l	d0-d3/a0/a3,-(sp)
	move.l	dosbase(a5),a6
	jsr	_LVODupLock(a6)
	move.l	a2,a0
	bsr	eval_full_path
	jsr	_LVOUnLock(a6)
.A	tst.b	(a2)+
	bne.s	.A
	subq.l	#1,a2
	cmp.b	#":",-1(a2)
	beq.s	.B
	move.b	#"/",(a2)+	/-end path
.B	movem.l	(sp)+,d0-d3/a0/a3

.C	move.l	(a0)+,d1	get filename
	beq.s	.D
	move.l	d1,a1
	bsr	addstring
	bsr.s	MaybeInsertQuote
	move.b	#" ",(a2)+	space-end

.D	dbra	d0,.E
	clr.b	(a2)
	movem.l	(sp)+,a2-a6
	rts

MaybeInsertQuote	;a3=start, a2=end of string
	move.l	a3,a1	changes only d1, a1, a2
	moveq	#0,d1	Inserts quotes if strings contains spaces
	cmp.l	a2,a3
	beq.s	.A
.G	cmp.b	#" ",(a1)+
	bne.s	.F
.A	moveq	#1,d1	space found
.F	cmp.l	a1,a2
	bhi.s	.G
	tst.l	d1
	beq.s	.H	jump if no spaces
	addq.l	#1,a2
	move.b	#$22,(a2)+	append last quote
	bra.s	.C
.I	move.b	-1(a1),(a1)	insert one char
	subq.l	#1,a1
.C	cmp.l	a1,a3
	blo.s	.I
	move.b	#$22,(a1)	store starting quote
.H	rts

** evaluate entire name associated with lock in D0, store string in A0
** Return D1 = last lock to unlock
** Reg usage: d0,d1,d2,d3,a0,a1,a3 (must not use A2)

OpenIconLib
	move.l	iconbase(a5),d0
	bne.s	.A
	move.l	4.w,a6
	lea	iconname(pc),a1
	jsr	_LVOOldOpenLibrary(a6)	icon-library
	move.l	d0,iconbase(a5)
.A	move.l	d0,a6
	rts

OpenWBLib
	move.l	wbbase(a5),d0
	bne.s	.A
	move.l	4.w,a6
	lea	wbname(pc),a1
	jsr	_LVOOldOpenLibrary(a6)
	move.l	d0,wbbase(a5)
.A	move.l	d0,a6
	rts

OpenGadLib
	move.l	gadbase(a5),d0
	bne.s	.A
	move.l	4.w,a6
	lea	gadname(pc),a1
	jsr	_LVOOldOpenLibrary(a6)
	move.l	d0,gadbase(a5)
.A	move.l	d0,a6
	rts

**********************************************
* Create CLI-Interface-Structure	V2.0 *
**********************************************
CreateCLI
	clr.b	WBflag(a5)	0=WB or CLI/1=newcli/2=run/3=pipe
	move.l	thistask(a5),a3
	move.l	pr_WindowPtr(a3),d0
	move.l	d0,oldwindowptr(a5)	preserve old winptr
	move.l	d0,windowptr(a5)
	bsr	GetWindowPtr
	tst.b	CLIflag(a5)
	beq	CCli3
	clr.l	EntryA0(a5)		started from WB
	move.l	#64+$28+$50,d0
	bsr	iwantcleanmem		memory for CLI
	moveq	#1,d1
	tst.l	d0
	beq	CCli2
	move.l	d0,a2
	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,d2
	move.l	(a0),d0
	subq.l	#1,d0
.C	addq.l	#1,d2
	addq.l	#4,a0
	tst.l	(a0)		look for free CLI-Number
	dbeq	d0,.C
	moveq	#2,d1
	tst.l	(a0)
	bne	CCli2
	lea	pr_MsgPort(a3),a1
	move.l	a1,(a0)
	move.l	d2,pr_TaskNum(a3)
	moveq	#10,d0
	move.l	d0,cli_FailLevel(a2)
	moveq	#-1,d0
	move.l	d0,cli_Interactive(a2)
	move.l	#1000,cli_DefaultStack(a2)	1000 LONGs
	move.l	pr_FileSystemTask(a3),filesys_old(a5)
	lea	64(a2),a0
	move.l	a0,d0
	lsr.l	#2,d0
	move.l	d0,cli_CommandFile(a2)
	lea	64+$28(a2),a0
	move.l	a0,d0
	lsr.l	#2,d0
	move.l	d0,cli_CommandName(a2)
	IFD	DEBUG
	tst.l	wb_msg(a5)
	beq	CreateCLI2	no WB-Msg -> CreateCLI2
	ENDC
	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	.A		Project ?
	addq.l	#8,a1
.A	move.l	(a1),a0		Lock on Current Dir
	moveq	#3,d1
	move.l	a0,d0
	beq	CCli2
	move.l	a0,d1
	move.l	dosbase(a5),a6
	jsr	_LVODupLock(a6)		WB wants to free its own lock
	bsr	SetCurrentDir
	move.l	4.w,a6
	lea	wbenchtx(pc),a1
	jsr	_LVOFindTask(a6)
	tst.l	d0
	beq.s	.E
	move.l	d0,a0
	tst.l	pr_CLI(a0)
	beq.s	.E
	move.l	dosbase(a5),a6
	bsr	CopyPaths	copy paths from workbench
.E	bsr	OpenIconLib
	moveq	#4,d1
	tst.l	d0
	beq	CCli2
	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	.B			Project ?
	move.l	12(a1),d0
	beq.s	.B
	move.l	d0,EntryA0(a5)		Name of Project as Script
	addq.l	#8,a1
.B	move.l	4(a1),a0		Name of Process
	jsr	_LVOGetDiskObject(a6)
	moveq	#5,d1
	move.l	d0,diskobj(a5)
	beq	CCli2
	move.l	d0,a0
	moveq	#0,d0
	bset	#31,d0		unset icon position
	move.l	d0,$3a(a0)	CurrentX
	move.l	d0,$3e(a0)	CurrentY
	move.b	#8,$30(a0)	Type=AppIcon
	move.l	do_ToolTypes(a0),d3	d3=ToolTypes
checktooltypes
	move.l	d3,a0
	lea	xpostool(pc),a1
	jsr	_LVOFindToolType(a6)	Look for XPOS-ToolType
	tst.l	d0
	beq.s	.G
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq.s	.G
	move.l	diskobj(a5),a0
	move.l	d0,$3a(a0)
.G	move.l	d3,a0
	lea	ypostool(pc),a1
	jsr	_LVOFindToolType(a6)	Look for YPOS-ToolType
	tst.l	d0
	beq.s	.E
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq.s	.E
	move.l	diskobj(a5),a0
	move.l	d0,$3e(a0)
.E	move.l	d3,a0
	lea	nametool(pc),a1
	jsr	_LVOFindToolType(a6)	Look for ICONNAME-ToolType
	tst.l	d0
	beq.s	.C
	move.l	d0,app_name(a5)
.C	move.l	d3,a0
	lea	iconifytool(pc),a1
	jsr	_LVOFindToolType(a6)	Look for ICONIFY-ToolType
	tst.l	d0
	beq.s	.B
	bset	#FLappicon,Flags+3(a5)
	movem.l	d2-d5/a6,-(sp)
	moveq	#0,d4
	moveq	#0,d5
	bsr	WaitAppIcon
	movem.l	(sp)+,d2-d5/a6
.B	move.l	d3,a0
	lea	screentool(pc),a1
	jsr	_LVOFindToolType(a6)	Look for SCREEN-ToolType
	move.l	d0,pubname(a5)
	move.l	d3,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	CCli2a
	move.l	d3,a0
	lea	scripttool(pc),a1
	move.l	a4,a6
	jsr	_LVOFindToolType(a6)	Look for SCRIPT-ToolType
	tst.l	EntryA0(a5)	project ?
	bne.s	.F
	move.l	d0,EntryA0(a5)
.F	move.l	d3,a0
	lea	norawtool(pc),a1
	jsr	_LVOFindToolType(a6)	Look for NORAW-ToolType
	tst.l	d0
	beq.s	.A
	bclr	#FLraw,Flags+2(a5)
.A	move.l	d3,a0
	lea	helptool(pc),a1
	jsr	_LVOFindToolType(a6)	Look for HELPMAN-ToolType
	tst.l	d0
	beq.s	.H
	move.l	d0,online_help(a5)
.H	move.l	d3,a0
	lea	commandtool(pc),a1
	jsr	_LVOFindToolType(a6)	Look for COMMAND-ToolType
	move.l	d0,d2
	bsr	Com2Script
CCli1	move.l	dosbase(a5),a6
	moveq	#0,d0
	rts
CCli2	bsr	GuruIt
CCli2a	move.l	dosbase(a5),a6
	moveq	#-1,d0
	rts

CCli3	move.l	pr_COS(a3),outhandle(a5)	started from CLI
	move.l	pr_CurrentDir(a3),d1
	bne.s	.D
	moveq	#-2,d2
	jsr	_LVOLock(a6)
	tst.l	d0
	beq	.D
	bsr	SetCurrentDir
.D	move.l	EntryA0(a5),d0	process CLI-Command-Line
	beq.s	CCli1
	clr.l	EntryA0(a5)
	move.l	d0,a0
	lea	parm2(a5),a2
	lea	endofparms(a5),a4	establish end of parms block
.A	bsr	get_parm		
	tst.l	d2
	beq.s	.B
	move.l	a1,(a2)+
	cmp.l	a2,a4		get out if more than 25 parms
	bne.s	.A
	clr.b	(a0)		make sure last parm ends in 0
.B	lea	parm2(a5),a1
	bsr.s	StartOpts
	bne.s	CCli2a
	tst.l	d3
	beq.s	.C
	bclr	#FLraw,Flags+2(a5)
.C	tst.l	d1
	beq.s	CCli1
	move.l	thistask(a5),a3
	move.l	pr_CLI(a3),a2
	add.l	a2,a2
	add.l	a2,a2
	bsr	OpenWin
	tst.l	d0
	beq.s	CCli2a
	tst.l	d3
	beq	CCli1
	bclr	#FLraw,Flags+2(a5)
	bra	CCli1

StartOpts		;examine startup-options, parms in a1
	moveq	#0,d1	returns window in d1, script in EntryA0
	moveq	#0,d2	and start-command in d2
	moveq	#0,d3	d3>0 if noraw, screen in pubname
.A	move.l	(a1)+,d0
	beq.s	Com2Script	exit to Com2Script
	move.l	d0,a0
	cmp.b	#"-",(a0)+
	bne.s	.H
	move.b	(a0)+,d0
	or.b	#$20,d0
	cmp.b	#"s",d0		-s for Script
	bne.s	.B
	move.l	a0,EntryA0(a5)
	bra.s	.A
.B	cmp.b	#"w",d0		-w for Window
	bne.s	.C
	move.l	a0,d1
	bra.s	.A
.C	cmp.b	#"c",d0		-c for Command
	bne.s	.D
	move.l	a0,d2
	bra.s	.A
.D	cmp.b	#"d",d0		-d for detach
	bne.s	.E
	clr.l	-4(a1)
	bsr	initialise_default
	bsr	newcliz
	bra.s	.I
.E	cmp.b	#"r",d0		-r for not Resident
	beq.s	.A
	cmp.b	#"n",d0		-n for Noraw
	bne.s	.F
	moveq	#1,d3
	bra.s	.A
.F	cmp.b	#"e",d0		-e for scrEen
	bne.s	.H
	move.l	a0,pubname(a5)
	bra.s	.A
.H	cmp.b	#"h",d0		-h for Helpman
	bne.s	.J
	move.l	a0,online_help(a5)
	bra.s	.A
.J	lea	useit(pc),a1
	bsr	pr_stringlf
.I	moveq	#-1,d0
	rts

Com2Script		;Makes a command to script, d2=command
	move.l	d1,-(sp)	returns d0=0 for OK
	tst.l	d2		V2.7: uses mult_comm_ptr, cannot fail
	beq.s	.B
	lea	null(pc),a0
	move.l	a0,EntryA0(A5)	no (default) script
	move.l	d2,a0
	lea	shelline(a5),a1
	move.l	a1,mult_comm_ptr(a5)
.D	move.b	(a0)+,(a1)+	copy command to shelline
	bne.s	.D
	move.b	#LF,-1(a1)
	clr.b	(a1)
.B	move.l	(sp)+,d1
	moveq	#0,d0
	rts

SetCurrentDir	;lock in d0
	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)
	rts

* Create CLI-Interface-Structure without WB-Message	V2.0 *
	IFD	DEBUG
CreateCLI2
	lea	conname(pc),a0
	move.l	a0,d1
	bsr	OpenWin
	beq.s	.B
	lea	ramdisk(pc),a0
	move.l	a0,d1
	moveq	#-2,d2
	jsr	_LVOLock(a6)
	tst.l	d0
	beq	.B
	bsr	SetCurrentDir
	moveq	#0,d0
	rts
.B	moveq	#-1,d0
	rts

ramdisk	dc.b	"RAM:",0
	even
	ENDC

* Create CLI-Interface-Structure with special message	V2.0
* ENTRY: a0:wb_msg, a2:CLI_Struct, a3:Process
*sm_NumArgs:	General Memory Block
*sm_ToolWindow:	Mode (1=newcli, 2=run, 3=pipe)
CreateCLI3
	move.b	sm_ToolWindow(a0),WBflag(a5)	not started from WB
	move.l	sm_NumArgs(a0),a4	wb_msg in a0
	move.l	Flags(a4),Flags(a5)
	move.l	copysize(a4),copysize(a5)
	move.l	FNCsize(a4),FNCsize(a5)
	move.l	app_name(a4),app_name(a5)
	move.l	online_help(a4),online_help(a5)
	move.l	pubname(a4),pubname(a5)
	move.l	thistask(a4),a0
	move.l	pr_CurrentDir(a0),d1
	move.l	pr_CLI(a0),a0
	add.l	a0,a0
	add.l	a0,a0
	move.l	cli_DefaultStack(a0),cli_DefaultStack(a2)
	move.l	cli_FailLevel(a0),cli_FailLevel(a2)
	jsr	_LVODupLock(a6)		COPY CD
	moveq	#15,d1
	tst.l	d0
	beq	cce3
	bsr	SetCurrentDir
	move.l	stdout(a4),outhandle(a5)	PROCESS PARMS
	lea	parm2(a4),a1
	bsr	StartOpts
	clr.l	outhandle(a5)
	tst.l	d0
	bne	cce2
	move.l	thistask(a4),a0		OPEN WINDOW
	move.l	pr_ConsoleTask(a0),pr_ConsoleTask(a3)
	cmp.b	#2,WBflag(a5)
	bne.s	.K
	tst.b	redirect_out(a4)	out-redirected run command ?
	beq.s	.K
	tst.l	outhandle(a4)
	beq.s	.K
	move.l	outhandle(a4),a0
	add.l	a0,a0
	add.l	a0,a0
	move.l	fh_Type(a0),d0
	move.l	d0,pr_ConsoleTask(a3)
.K	lea	conname(pc),a0
	tst.l	d1
	bne.s	.H
	move.l	a0,d1
	move.l	windowname(a4),d0
	beq.s	.H
	move.l	d0,d1
.H	bsr	OpenWin
	beq	cce2
	cmp.b	#2,WBflag(a5)	background tasks are noraw
	bhs.s	.J
	btst	#FLraw,Flags+2(a4)	inherit noraw ?
	beq.s	.J
	tst.l	d3		force noraw ?
	beq.s	.B
.J	bclr	#FLraw,Flags+2(a5)
.B	move.l	thistask(a4),a0			COPY SEARCH PATHS
	bsr	CopyPaths
	lea	prompt_args(a4),a0	COPY PROMPT
	lea	prompt_args(a5),a1
.G	move.b	(a0)+,(a1)+
	bne.s	.G
	lea	now(a4),a0		COPY HISTORY
	lea	now(a5),a1
	move.w	#HISTORY_SIZE+12-1,d0
.D	move.b	(a0)+,(a1)+
	dbra	d0,.D
	moveq	#ctrl_inite-ctrl_init-1,d0	COPY CTRL-CODES
	lea	ctrl_codes-1(a4),a0
	lea	ctrl_codes-1(a5),a1
.E	move.b	(a0)+,(a1)+
	dbra	d0,.E
	moveq	#more_inite-more_init-1,d0	COPY MORE-KEYS
	lea	morekeys(a4),a0
	lea	morekeys(a5),a1
.I	move.b	(a0)+,(a1)+
	dbra	d0,.I
	lea	FNCignore(a4),a0		COPY FNC-ignore
	lea	FNCignore(a5),a1
.F	move.b	(a0)+,(a1)+
	bne	.F
ccs1	movem.l	a2-a4,-(sp)	COPY ALL ALIASES
	lea	first_alias(a4),a2
.A	move.l	(a2),d0
	beq.s	.E
	move.l	d0,-(sp)
	addq.l	#4,d0		skip link
	move.l	d0,a2		start to A2
	move.l	d0,a3
.C	tst.b	(a3)+		skip name
	bne.s	.C
.D	tst.b	(a3)+		skip definition
	bne.s	.D
	bsr	copy_new_alias
	move.l	(sp)+,a2
	beq.s	.A		check for error
	moveq	#17,d1
	bsr	GuruIt
.E
;	cmp.b	#2,WBflag(a5)		CREATE REVIEW-BUFFER
;	bhs.s	.F
;	move.l	ReviewSize(a4),d0
;	beq.s	.G
;	bsr	MakeReview
;.G
;	tst.l	first_menudef(a4)	CREATE MENUS
;	beq.s	.F
;	bsr	InitGadTools
;	beq.s	.F
;	move.l	d0,menu_pool(a5)
;	move.l	d0,d7
;	lea	first_menudef(a4),a2
;	move.l	menu_count(a4),d0
;	bsr	CreateMenuStrip2
.F	movem.l	(sp)+,a2-a4
ccs2	cmp.b	#2,WBflag(a5)		BACKGROUND PROCESS
	blo.s	.D
	moveq	#-1,d0
	move.l	d0,cli_Background(a2)
	cmp.b	#3,WBflag(a5)		COPY PIPENAME
	bne.s	.D
	lea	pipe_out(a4),a0
	lea	pipe_in(a5),a1
.E	move.b	(a0)+,(a1)+
	bne.s	.E
	move.l	thistask(a4),PipeTask(a5)
.D
;	lea	null(pc),a0	no default script
;	move.l	a0,d0
	move.l	EntryA0(a5),d1		SCRIPT GIVEN ?
	beq.s	.A
	move.l	d1,a0
	lea	prompt_string(a5),a1	there is enough place
	move.l	a1,d0
.B	move.b	(a0)+,(a1)+	Copy Script-Parm
	bne.s	.B
	move.l	d0,EntryA0(a5)
.A	moveq	#RETURN_OK,d0
	bra.s	cce1
cce3	bsr	GuruIt
cce2	moveq	#RETURN_ERROR,d0
cce1	move.l	d0,-(sp)
	move.l	4.w,a6
	move.l	wb_msg(a5),a1
	move.l	d0,sm_ToolWindow(a1)	return success to calling task
	jsr	_LVOReplyMsg(a6)
	clr.l	wb_msg(a5)
	move.l	dosbase(a5),a6
	move.l	(sp)+,d0
	rts

*************************************************************
* Open Window for both Input and Output, Name in d1 , a2,a3 *
*************************************************************
OpenWin	move.l	dosbase(a5),a6
	moveq	#0,d0
	cmp.b	#1,openwin_flag(a5)
	beq	.C
	move.b	#1,openwin_flag(a5)
	move.l	pr_CIS(a3),OldCIS(a5)
	move.l	pr_COS(a3),OldCOS(a5)
	clr.l	pr_CIS(a3)		avoid freeing it
	clr.l	pr_COS(a3)
	move.l	pr_ConsoleTask(a3),OldCTask(a5)
	bclr	#FLraw,Flags+2(a5)
	move.l	d1,a0
	move.l	a0,windowname(a5)
	tst.b	(a0)
	beq	.A			NIL:
	cmp.w	#36,kickver(a5)
	blo	.D
	move.l	pubname(a5),d0
	beq	.D

	movem.l	d1-d2/a2,-(sp)	open Public Screen
	lea	PubTags(pc),a0
	lea	temp2buf(a5),a1		copy tags-field
	move.l	a1,a2
.E	move.l	(a0)+,(a1)+
	clr.l	(a1)+
	tst.l	-8(a1)
	bne.s	.E
	move.l	d0,a1
	moveq	#2,d0
	addq.l	#1,a1
	tst.b	-1(a1)
	beq.s	.H
	subq.l	#1,a1
	bsr	convert_ASCII_to_num
.H	move.l	d0,1*4(a2)	Depth
	move.l	#$8000,d0
	tst.b	-1(a1)
	beq.s	.I
	bsr	convert_ASCII_to_num
.I	move.l	d0,9*4(a2)	DisplayID
	moveq	#1,d0
	tst.b	-1(a1)
	beq.s	.J
	bsr	convert_ASCII_to_num
.J	move.l	d0,11*4(a2)	Overscan
	lea	ZShellName(pc),a0	fill up tags-field
	tst.b	-1(a1)
	beq.s	.G
	move.l	a1,a0
.G	move.l	a0,3*4(a2)	Screentitle
	move.l	a0,7*4(a2)
	moveq	#2,d0
	move.l	d0,5*4(a2)	Pubscreen
	moveq	#12,d0
	move.l	d0,13*4(a2)	PubSig=ctrl-C
	lea	PenAray(pc),a0
	move.l	a0,15*4(a2)	Drawinfo
	moveq	#1,d0
	move.l	d0,17*4(a2)	SysFont=System default screenfont
	move.l	a2,a1
	sub.l	a0,a0
	move.l	intuibase(a5),a6
	jsr	_LVOOpenScreenTagList(a6)	open Screen
	move.l	d0,pubscreen(a5)
	beq.s	.F
	move.l	d0,a0
	moveq	#0,d0
	jsr	_LVOPubScreenStatus(a6)	make Pubscreen public
.F	move.l	dosbase(a5),a6
	movem.l	(sp)+,d1-d2/a2

.D	cmp.b	#2,WBflag(a5)
	bne.s	.L
	move.l	temp4(a4),d0		use outhandle of RUN command
	bne.s	.M
.L	bsr	OpenNewfile		open output-Window
.M	moveq	#11,d1
	move.l	d0,pr_COS(a3)
	beq	.B
	move.l	d0,d1
	move.l	d0,cli_StandardOutput(a2)
	move.l	d0,cli_CurrentOutput(a2)
	lsl.l	#2,d0
	move.l	d0,-(sp)
	jsr	_LVOIsInteractive(a6)
	moveq	#12,d1
	move.l	(sp)+,a0
	tst.l	d0
	bne.s	.K
	cmp.b	#2,WBflag(a5)	NIL: output on RUN command ?
	beq.s	.A
	bra.s	.B
.K	move.l	fh_Type(a0),d0
	move.l	d0,pr_ConsoleTask(a3)
	bset	#FLraw,Flags+2(a5)
	lea	star(pc),a0
	move.l	a0,d1
	bsr	OpenOldfile		open input-window
	moveq	#13,d1
	move.l	d0,pr_CIS(a3)
	beq	.B
	move.l	d0,cli_StandardInput(a2)
	move.l	d0,cli_CurrentInput(a2)
.A	bsr	GetWindowPtr
	clr.l	raw_mode(a5)
	moveq	#-1,d0
	rts			d0<>0 if OK
.C	moveq	#10,d1
.B	bra	GuruIt		d0=0 on error

PubTags	dc.l	$80000000+37	Depth=2/1
	dc.l	$80000000+40	Title=*ZShell/3
	dc.l	$80000000+45	Type=Publicscreen/5
	dc.l	$80000000+47	PubName=*ZShell/7
	dc.l	$80000000+50	DisplayID=Hires/9
	dc.l	$80000000+52	Overscan=1/11
	dc.l	$80000000+48	PubSig=12/13
	dc.l	$80000000+58	Pens=*PenArray/15
	dc.l	$80000000+44	SysFont=1/17
	dc.l	0
PenAray	dc.w	0,-1

*******************************
CloseWin
	move.l	thistask(a5),a3
	tst.b	openwin_flag(a5)
	beq.s	.A
	move.l	pr_CIS(a3),d1
	beq.s	.C
	jsr	_LVOClose(a6)	close input-window
.C	move.l	pr_COS(a3),d1
	beq.s	.D
	jsr	_LVOClose(a6)	close output-window
.D	move.l	OldCIS(a5),d0
	move.l	d0,pr_CIS(a3)
	move.l	OldCOS(a5),d1
	move.l	d1,pr_COS(a3)
	move.l	OldCTask(a5),pr_ConsoleTask(a3)
	tst.l	pr_CLI(a3)
	beq.s	.G
	move.l	pr_CLI(a3),a2
	add.l	a2,a2
	add.l	a2,a2
	move.l	d0,cli_StandardInput(a2)
	move.l	d0,cli_CurrentInput(a2)
	move.l	d1,cli_StandardOutput(a2)
	move.l	d1,cli_CurrentOutput(a2)
.G	move.l	pubscreen(a5),d0
	beq.s	.A
	move.l	d0,a0
	move.l	intuibase(a5),a6
	jsr	_LVOCloseScreen(a6)	close Public Screen
	tst.l	d0
	bne.s	.A
	move.l	4.w,a6
	moveq	#0,d0
	bset	#SIGBREAKB_CTRL_C,d0
	jsr	_LVOWait(a6)
	bra.s	.G
.A	move.l	dosbase(a5),a6
	rts

**********************************************
* Remove CLI-Interface-Structure	V2.0 *
**********************************************
RemoveCLI
	move.l	thistask(a5),a3
	IFD	KILL
	cmp.w	#36,kickver(a5)
	blo.s	.G
	clr.l	pr_ExitCode(a3)
.G	ENDC
	move.l	oldwindowptr(a5),pr_WindowPtr(a3)
	move.l	old_homedir(a5),d0
	beq.s	.B
	move.l	d0,pr_HomeDir(a3)
.B
	bsr	clkoff
	bsr	CloseWin
	move.l	diskobj(a5),d0
	beq.s	.F
	move.l	d0,a0
	move.l	iconbase(a5),a6
	jsr	_LVOFreeDiskObject(a6)
.F	move.l	4.w,a6
	move.l	iconbase(a5),d0
	beq.s	.A
	move.l	d0,a1
	jsr	_LVOCloseLibrary(a6)
.A	move.l	wbbase(a5),d0
	beq.s	.C
	move.l	d0,a1
	jsr	_LVOCloseLibrary(a6)
.C	move.l	dosbase(a5),a6
	move.l	pr_CLI(a3),d0
	beq	remend
	lsl.l	#2,d0
	move.l	d0,a2
	moveq	#10,d0
	move.l	d0,cli_FailLevel(a2)
	move.l	old_setname(a5),d0
	beq.s	remcli
	move.l	d0,cli_SetName(a2)
	lsl.l	#2,d0
	move.l	d0,a1
	lea	CD_string(a5),a0
.E	move.b	(a0)+,(a1)+	copy current dir name
	bne.s	.E
	move.l	old_prompt(a5),cli_Prompt(a2)

remcli	tst.b	CLIflag(a5)
	beq.s	remend
	clr.l	pr_CLI(a3)	clear CLI-Pointer
	move.l	pr_TaskNum(a3),d0
	beq.s	.E
	lsl.l	#2,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	lea	cli_CommandDir(a2),a4
	bsr	DeletePaths	free search paths
	move.l	cdir_old(a5),d1
	jsr	_LVOCurrentDir(a6)
	move.l	d0,d1
	beq.s	.B
	jsr	_LVOUnLock(a6)	free current dir
.B	move.l	filesys_old(a5),pr_FileSystemTask(a3)
	clr.l	pr_Result2(a3)
	move.l	#64+$28+$50,d0
	move.l	a2,a1
	bsr	givemem		free memory of CLI
remend	move.l	dosbase(a5),a6
	rts

**************************************************************
GuruIt	;get errornumber in d1 and display a recoverable alert
	movem.l	d0-d1/a0-a2/a6,-(sp)
	lea	tempbuf(a5),a0
	move.l	a0,a1
	clr.b	(a1)+
	move.b	#250,(a1)+
	move.b	#15,(a1)+
	lea	ZShellName(pc),a2
.A	move.b	(a2)+,(a1)+
	bne.s	.A
	move.b	#" ",-1(a1)
	move.l	d1,d0
	bsr	qpr10
	clr.b	(a1)+
	clr.b	(a1)+
	move.l	intuibase(a5),a6
	moveq	#0,d0
	moveq	#35,d1
	jsr	_LVODisplayAlert(a6)
	movem.l	(sp)+,d0-d1/a0-a2/a6
	tst.l	d0
	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),a0
	bsr	PrintError
	moveq	#-1,d0
	bra.s	.B
.A	moveq	#0,d0
.B	movem.l	(sp)+,d0-d1/a0-a1
	rts

bad_number_error
	moveq	#115,d0
	bra.s	pr_galactic

too_less_args
	moveq	#116,d0
	bra.s	pr_galactic

*SendPacket-Error-Tester
PKTerr	tst.l	sp_res1(a5)
	bne	.A
	move.l	sp_res2(a5),d0
	bra.s	pr_galactic
.A	rts
*DOSERRor but Unlock first using D7 as the lock
DOSerrUL	move.l d7,d1		;Assume D7=lock
	beq.s	DOSerr
	move.l	thistask(a5),a2
	move.l	pr_Result2(a2),d2
	jsr	_LVOUnLock(a6)
	move.l	d2,pr_Result2(a2)
*DOSERRor handler
DOSerr	jsr	_LVOIoErr(a6)
	cmp.l	#232,d0
	bne.s	pr_galactic
	moveq	#0,d0
	rts			;Return if ERROR_NO_MORE_ENTRIES

pr_galactic
	bsr.s	pr_DOSerr	;entry for dospacket
galactic
	move.l	errorstack(a5),sp	;restore stack
	moveq	#RETURN_BAD,d0
	bra	chkfail		;reenter shell loop

maybeDOSerr	;checks if d0=0, then prints DOSerr
	move.l	d0,-(sp)
	bne.s	.A
	jsr	_LVOIoErr(a6)
	bsr	pr_DOSerr		error occured
.A	move.l	(sp)+,d0
	rts

* ENTRY D0=dos error number
pr_DOSerr
	clr.b	noreview_flag(a5)
	move.l	a2,-(sp)
	move.l	d0,-(sp)
	bsr	pr_DOSerr1
	bsr	GetMessage
	bsr	pr_DOSerr2
	tst.l	d0
	bne.s	.A
	move.l	#-155,d0
	bsr	GetMessage
	move.l	sp,a1
	bsr	new_print
.A	lea	lf(pc),a1
	bsr	pr_error
	addq.l	#4,sp
	move.l	(sp)+,a2
	moveq	#RETURN_ERROR,d0
	rts

pr_DOSerr1
	lea	NewPrintBuffer(a5),a2
	lea	farb2(pc),a1
	bsr	addstring
	move.l	parm1(a5),a1
	bsr	addstring
	move.b	#":",(a2)+
	move.b	#" ",(a2)+
	rts

pr_DOSerr2
	move.l	a0,a1
	bsr	addstring
	lea	farb1(pc),a1
	bsr	addstring
	lea	NewPrintBuffer(a5),a1
	bsr	pr_error
	rts

PrintError	;string to print in a0
	move.l	a2,-(sp)
	bsr	pr_DOSerr1
	bsr	pr_DOSerr2
	lea	lf(pc),a1
	bsr	pr_error
	move.l	(sp)+,a2
	moveq	#RETURN_ERROR,d0
	rts

GetMessage
	cmp.w	#36,kickver(a5)
	blo.s	.E
	movem.l	d2-d4,-(sp)	OS2.0+ stuff
	move.l	d0,d1
	lea	null(pc),a0
	move.l	a0,d2
	lea	gather(a5),a0
	clr.b	2(a0)
	move.l	a0,d3
	moveq	#80,d4
	jsr	_LVOFault(a6)
	movem.l	(sp)+,d2-d4
	lea	gather+2(a5),a0
	rts
.E	lea	doserror_text(pc),a0	OS1.3- stuff
	bra.s	.C
.B	tst.b	(a0)+
	bne.s	.B
.C	move.b	(a0)+,d1
	beq.s	.A
	cmp.b	d1,d0
	bne.s	.B
	rts
.A	moveq	#0,d0
	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
	addq.l	#4,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
	addq.l	#4,sp
	movem.l	(sp)+,d0/a0-a1
	rts

DisplayBeep
	lea	beep(pc),a1
	bra.s	pr_error

pr_prompt
	lea	prompt_string(a5),a1
pr_error
	movem.l	d0-d3/a0-a1,-(sp)
	move.l	stdout(a5),d1
	bra.s	pr_str1

pr_space lea	space(pc),a1
	bra.s	pr_string
pr_tab	lea tab(pc),a1
	bra.s pr_string
pr_lf	lea lf(pc),a1

*PRINT STRING at a1	;saves some of the important low registers
pr_string
	movem.l	d0-d3/a0-a1,-(sp)	print String in a1
	move.l	outhandle(a5),d1
pr_str1	beq.s	.B
	move.l	a1,d2
	moveq	#-1,d3
.A	addq.l	#1,d3
	tst.b	(a1)+
	bne.s	.A
	jsr	_LVOWrite(a6)
.B	movem.l	(sp)+,d0-d3/a0-a1
	rts

OpenOldfile
	move.l	#MODE_OLDFILE,d2
	jmp	_LVOOpen(a6)

OpenNewfile
	move.l	#MODE_NEWFILE,d2
	jmp	_LVOOpen(a6)

OpenReadWrite
	move.l	#MODE_READWRITE,d2
	jmp	_LVOOpen(a6)

* Simple Memory Pool Manager, no single deallocations possible V2.8
pud_link = 0	;APTR	Link to next puddle
pud_free = 4	;APTR	Points to start of free space in current puddle
pud_size = 8	;LONG	Size of current puddle
pud_resv = 12	;LONG	Reserved
pud_data = 16	;	puddle data
;POOLSIZE=size of standard puddles, but size can vary
* Create memory pool, no entry, exit: d0=poolheader d1=first free pos
CreatePool
	move.l	#POOLSIZE,d0
	bsr	iwantcleanmem	allocate first puddle
	move.l	d0,d1
	beq.s	.A
	move.l	d0,a0
	addq.l	#8,d1
	addq.l	#8,d1
	move.l	d1,pud_free(a0)
	move.l	#POOLSIZE,pud_size(a0)
.A	rts

* Delete whole memory pool, entry: a1=&poolheader (may be 0), no exit
DeletePool
	move.l	(a1),a0
	clr.l	(a1)
	bra.s	.C
.A	move.l	(a0),-(sp)
	move.l	a0,a1
	move.l	pud_size(a0),d0
	bsr	givemem		free all puddles
	move.l	(sp)+,a0
.C	move.l	a0,d0
	bne.s	.A
	rts

* Allocate memory in pool, entry: a1=&poolheader d0=size, exit: d0=addr
* Creates pool first, if neccessary
AutoAllocPooled
	move.l	d0,-(sp)
	move.l	(a1),d0
	bne.s	.A
	bsr	CreatePool
	beq	PolFail
	move.l	d0,(a1)
.A	move.l	d0,a0
	move.l	(sp)+,d0
* Allocate memory in pool, entry: a0=poolheader d0=size, exit: d0=addr
AllocPooled
	move.l	d2,-(sp)
	addq.l	#1,d0
	bclr	#0,d0		word-align
	cmp.l	#(POOLSIZE-pud_data)/2,d0	is it too big for pool ?
	bls.s	.A
	addq.l	#8,d0
	addq.l	#8,d0
	move.l	d0,d2
	bsr	iwantcleanmem	allocate separate memory for it
	beq.s	.F
	move.l	d0,a1
	move.l	d2,pud_size(a1)	size is different from POOLSIZE !
	add.l	a1,d2
	move.l	d2,pud_free(a1)	declare it as full
	move.l	a0,d1
.C	move.l	d1,a0
	move.l	(a0),d1
	bne.s	.C		look for end of puddles list
	move.l	a1,pud_link(a0)	connect
	addq.l	#8,d0
	addq.l	#8,d0
	bra.s	.F

.A	move.l	a0,d2
.B	move.l	d2,a0
	move.l	d0,d1
	move.l	pud_free(a0),a1
	add.l	a1,d1
	sub.l	a0,d1
	cmp.l	pud_size(a0),d1	check if it fits into puddle
	bls.s	.D
	move.l	(a0),d2
	bne.s	.B		look for end of puddles list

	move.l	d0,d2
	move.l	a0,-(sp)
	bsr	CreatePool	allocate new puddle
	move.l	(sp)+,a0
	beq.s	.F
	move.l	d0,(a0)		connect
	move.l	d0,a0
	move.l	d2,d0
	move.l	d1,a1
.D	add.l	d0,pud_free(a0)
	move.l	a1,d0
.F	move.l	(sp)+,d2
PolFail	tst.l	d0
	rts

* Allocate memory in pool and copy string in there
* Entry: a1=&poolheader d0=string, exit: d0=string in pool
StringPooled
	move.l	d0,-(sp)
	move.l	d0,a0
.A	tst.b	(a0)+
	bne.s	.A
	sub.l	d0,a0
	move.l	a0,d0
	bsr	AutoAllocPooled
	move.l	(sp)+,a1
	beq	resi_no_mem
	move.l	d0,a0
.C	move.b	(a1)+,(a0)+
	bne.s	.C
	rts

*ALLOCATE MEMORY D0=size D1=type
iwantcleanmem	
	movem.l d1/a0-a1,-(sp)
	move.l	#MEMF_CLEAR+1,d1
	bra.s	iwmem
iwantmem	
	movem.l d1/a0-a1,-(sp)
	moveq	#1,d1
iwmem	move.l	4.w,a6
	jsr	_LVOAllocMem(a6)
	move.l	dosbase(a5),a6
	tst.l	d0
	bne.s	.A
	move.l	thistask(a5),a0
	moveq	#103,d1
	move.l	d1,pr_Result2(a0)
.A	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


* ALTER WINDOW PTR FOR THIS PROCESS. USE TO DISABLE REQUESTERS POPPING UP.
RequestersOff
	movem.l	d1/a0,-(sp)
	moveq	#-1,d1
	bra.s	changeWindowPtr

RequestersOn
	movem.l	d1/a0,-(sp)
	move.l	windowptr(a5),d1
	bne.s	changeWindowPtr
	moveq	#-1,d1	no window pointer, no requesters

changeWindowPtr	
	move.l	thistask(a5),a0
	move.l	d1,pr_WindowPtr(a0)
	movem.l	(sp)+,d1/a0
	rts

do_show_cursor	
	btst	#FLhide,Flags+2(a5)
	beq.s	.A
	lea	show_cursor(pc),a1
	bsr	pr_string
	clr.b	cursor_mode(a5)
.A	rts

pr_show_cursor	
	btst	#FLhide,Flags+2(a5)
	beq.s	.A
	tst.b	redirect_out(a5)
	bne.s	.A
	tst.b	cursor_mode(a5)
	beq.s	.A
	addq.b	#1,noreview_flag(a5)
	lea	show_cursor(pc),a1
	bsr	pr_string
	subq.b	#1,noreview_flag(a5)
	clr.b	cursor_mode(a5)
.A	rts

pr_hide_cursor	
	btst	#FLhide,Flags+2(a5)
	beq.s	.A
	tst.b	redirect_out(a5)
	bne.s	.A
	tst.b	cursor_mode(a5)
	bne.s	.A
	addq.b	#1,noreview_flag(a5)
	lea	hide_cursor(pc),a1
	bsr	pr_string
	subq.b	#1,noreview_flag(a5)
	move.b	#1,cursor_mode(a5)
.A	rts

raw_on	movem.l	d0/a1,-(sp)	switch console to raw mode
	moveq	#-1,d0
	bra.s	raw_switch

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

*WINDOW TYPE CHANGER	
raw_switch
	cmp.l	raw_mode(a5),d0
	beq.s	.A
	move.l	d0,raw_mode(a5)
	move.l	thistask(a5),a1
	move.l	pr_ConsoleTask(a1),packettask(a5)
	bsr	clearArgs
	move.l	#ACTION_SCREEN_MODE,packettype(a5)
	move.l	d0,myArg1(a5)
	bsr	sendpacket
.A	movem.l	(sp)+,d0/a1
	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)
	bsr	sendpacket2
	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
	tst.l	sp_res1(a5)
.A	rts

sendpacket2	;used by sendpacket and get_one_char
	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)
	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

*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 
*D2 holding offset from 'cmdstart' so a jsr 0(a0,d2.w) can be done
*Entry	A1 pts to Command text table  A2 pts to command offset table
matchcmd
	lea	comtext(pc),a1
	lea	comoffs(pc),a2
	moveq	#0,d1	command count
	move.l	a0,a3	save command
	moveq	#0,d3
mat1	move.b	(a1)+,d3	save number of args
mat2	move.b	(a0)+,d0
	bset	#5,d0
	cmp.b	dotchar(a5),d0	check "."
	bne.s	.A
	tst.b	(a0)
	beq.s	foundit	shortcut
.A	move.b	(a1),d2
	bset	#5,d2
	cmp.b	d2,d0
	bne.s	nextcom	if any character wrong then check next
	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	1(a1)	put 0,0 at end of com table
	bne.s	mat1
	moveq	#0,d2	D2 = 0 if command not found
	rts
foundit	tst.b	d3
	bmi.s	.A
	lsl.l	#2,d3
	lea	parm2(a5),a0
	tst.l	0(a0,d3.l)
	beq.s	.A
	moveq	#118,d0		too many args error
	bra	pr_galactic
.A	move.w	0(a2,d1.l),d2	get offset
	rts

*****************************************
*	Start of internal commands	*
*****************************************
cmdstart

FreeStuff	;deallocates stuff alllocated by commands
	bsr	ClearMenuStrip
	bsr	ClearMenuDef
	bsr	deallocate_aliases
	bsr	reviewend
	bsr	FreeGetChar
	bra	FreeUtil

*************************
*	RUN		*	V2.2
*************************
runz	clr.l	temp4(a5)
	tst.b	redirect_out(a5)
	beq.s	.B
	tst.l	MPipePtr(a5)
	bne.s	.B
	tst.b	pipe_out(a5)
	bne.s	.B
	move.l	thistask(a5),a0
	move.l	pr_COS(a0),temp4(a5)
	move.l	stdout(a5),pr_COS(a0)	restore old stdout
	move.l	stdout(a5),outhandle(a5)	
.B	clr.b	redirect_out(a5)
	clr.l	parm4(a5)
	lea	tempbuf(a5),a0
	move.l	a0,parm2(a5)
	move.l	#"-w*"<<8,(a0)+
	move.l	a0,parm3(a5)
	move.w	#'-c',(a0)+
	lea	CLIbuf(a5),a1
.A	move.b	(a1)+,(a0)+	copy CLIbuf
	bne.s	.A
	moveq	#2,d7
	bra.s	create_new_cli

*************************
*	NewCLI		*	V2.0
*************************
newcliz	moveq	#1,d7
create_new_cli		;ENTRY: d7=Mode
	tst.b	noresi_flag(a5)
	bne	.B
	lea	ZShellName(pc),a0
	move.l	a0,d1		process-name
	move.l	thistask(a5),a0
	moveq	#0,d2		priority
	move.b	LN_PRI(a0),d2
	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	.B
	move.l	d0,a4		a4:new process
	moveq	#$24,d0
	bsr	iwantcleanmem	memory for Message
	beq.s	.B
	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	a5,sm_NumArgs(a1)
	move.b	d7,sm_ToolWindow(a1)
	move.l	a4,a0
	move.l	4.w,a6
	jsr	_LVOPutMsg(a6)
.A	move.l	a2,a0
	jsr	_LVOWaitPort(a6)
	move.l	a2,a0
	jsr	_LVOGetMsg(a6)
	cmp.l	a3,d0
	bne	.A
	move.l	sm_ToolWindow(a3),-(sp)	return value
;	move.l	dosbase(a5),a6
	move.l	d0,a1
	moveq	#$24,d0
	bsr	givemem
	move.l	(sp)+,d0
	rts
.B	moveq	#RETURN_ERROR,d0
	rts

*************************
*	RENAME		*
*************************
renamez	move.l	parm3(a5),d2
	beq	too_less_args
	move.l	parm2(a5),d1
	jsr	_LVORename(a6)
	tst.l	d0
	beq	DOSerr
	moveq	#RETURN_OK,d0
	rts

*************************
*	MAKEDIR		*
*************************
makedirz	lea	parm2(a5),a4
.A	move.l	(a4)+,d3
	beq.s	.C
	move.l	d3,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	tst.l	d0
	beq.s	.D
	move.l	d0,d1
	jsr	_LVOUnLock(a6)
	move.l	#203,d0
	bra	resi_error
.D	move.l	d3,d1
	jsr	_LVOCreateDir(a6)
	tst.l	d0
	beq	DOSerr
	move.l	d0,d1
	jsr	_LVOUnLock(a6)
	bra.s	.A
.C	moveq	#RETURN_OK,d0
	rts
	
*************************
*	PROMPT		*
*************************
promptz	move.l	parm2(a5),d0
	beq.s	.B
	bsr	parse_echo
	move.l	parm2(a5),a0
	lea	prompt_args(a5),a2
	lea	1(a2),a1
	moveq	#-1,d0
.A	addq.b	#1,d0
	move.b	(a0)+,(a1)+
	bne.s	.A
.C	move.b	d0,(a2)
	MOVEQ	#RETURN_OK,D0
	rts
.B	lea	prompt_args+1(a5),a1
	bsr	pr_stringlf
	moveq	#RETURN_OK,d0
	rts
	
**************	
compose_prompt
	movem.l	d0-d1/a0-a2,-(sp)
	lea	prompt_string(a5),a1
	lea	prompt_args+1(a5),a0
cpro3	move.b	(a0)+,d0
	beq	composer3
	cmp.b	#$5c,d0 ;\
	bne.s	.A
	move.b	(a0)+,d0
	bra	composer2
.A	cmp.b	#'%',d0
	bne	composer2
	move.b	(a0)+,d0
	bset	#5,d0
	cmp.b	#'p',d0		check if %p
	bne.s	try_halfcd
	lea	CD_string+1(a5),a2
.B	move.b	(a2)+,(a1)+	copy cd_string to prompt_string
	bne.s	.B
	lea	-1(a1),a1
	bra	cpro3
try_halfcd
	cmp.b	#'s',d0		check if %s
	bne.s	try_line_num
	lea	CD_string+1(a5),a2
	move.l	a2,d1
.A	tst.b	(a2)+
	bne.s	.A
	subq.l	#2,a2
	bra.s	.D
.C	move.b	-(a2),d0
.D	cmp.l	a2,d1
	bhi.s	.E
	cmp.b	#"/",d0
	beq.s	.E
	cmp.b	#":",d0
	bne.s	.C
.E	addq.l	#1,a2
.B	move.b	(a2)+,(a1)+	copy cd_string to prompt_string
	bne.s	.B
	lea	-1(a1),a1
	bra	cpro3
try_line_num
	cmp.b	#'l',d0		check if %l
	bne.s	try_oldcmd
	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_oldcmd
	cmp.b	#'c',d0		check if %c
	bne.s	try_task_num
	lea	shelline(a5),a2
.B	move.b	(a2)+,(a1)+
	bne.s	.B
	lea	-1(a1),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
.A	move.b	(a0)+,(a1)+
	bne.s	.A
	movem.l	(sp)+,d0-d1/a0-a2
	rts


*FILL FIB WITH EXAMINE A0-> directory name ,D7=filelock on return
fibexam	move.l	a0,-(sp)
	moveq	#ACCESS_READ,d2
	move.l a0,d1
	jsr	_LVOLock(a6)
	move.l	d0,d7
	beq	DOSerr
	bsr	fibexam2
	move.l	(sp)+,a0
	rts
fibexam2
	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
chdir	* check and change directory, a0=dirname
	move.l	d7,-(sp)
	bsr	fibexam
	move.l	d7,d1
	move.l	(sp)+,d7
	tst.l	fib_DirEntryType(a5)	;check entry OK
	bpl.s	.A
	jsr	_LVOUnLock(a6)
	move.l	#212,d0
	bra	pr_galactic
*CHANGE DIRECTORY d1:lock to new current directory
.A	move.l	d1,a0
	add.l	a0,a0
	add.l	a0,a0
	move.l	thistask(a5),a1
	move.l	fl_Task(a0),pr_FileSystemTask(a1)
	jsr	_LVOCurrentDir(a6)
	move.l	d0,d1
	jsr	_LVOUnLock(a6)	unlock the old directory
	lea	CD_string+1(a5),a0
	lea	CDbackstr(a5),a1
.B	move.b	(a0)+,(a1)+	remember old directory
	bne.s	.B
	bsr	eval_CD		update cd string
	moveq	#RETURN_OK,d0
	rts
	
querycd	bsr	eval_CD
	lea	CD_string+1(a5),a1
	bsr	pr_stringlf
	moveq	#RETURN_OK,d0
	rts


** Evaluate entire name of current directory and put in CD_string
eval_CD	clr.b	CD_string+1(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+1(a5),a0
	bsr	eval_full_path
	jsr	_LVOUnLock(a6)
.A	moveq	#-1,d0
	lea	CD_string(a5),a0
	lea	1(a0),a1
.B	addq.b	#1,d0	calculate size of BSTR
	tst.b	(a1)+
	bne.s	.B
	move.b	d0,(a0)
	rts
	
** evaluate entire name associated with lock in D0, store string in A0
** Return D1 = last lock to unlock
** Reg usage: d0,d1,d2,d3,a0,a1,a3 (must not use A2)
eval_full_path
	move.b	#"?",(a0)
	clr.b	1(a0)
	move.l	d0,d1
	beq.s	.C
	lsl.l	#2,d0
	move.l	d0,a1
	moveq	#ACCESS_READ,d0
	cmp.l	fl_Access(a1),d0	only eval read locks
	bne.s	.B
.C	cmp.w	#36,kickver(a5)
	blo.s	.A
	move.l	d1,a3
	move.l	a0,d2
	moveq	#78,d3
	jsr	_LVONameFromLock(a6)
	move.l	a3,d1
.B	rts
.A	lea	-88(sp),sp
	move.l	a0,4(sp)		save address of string
	move.l	d1,(sp)		save original lock on stack
	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	dotchar(a5),d1
	bne.s	.F
	tst.b	(a1)
	beq.s	.C
.F	tst.l	chartable(a5)
	bne.s	.G
	bclr	#5,d0	just for searching ZShell
	bclr	#5,d1
	cmp.b	d1,d0
	bra.s	.H
.G	bsr	compD1D0nocase	normal compare
.H	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
*Exit: d0=seglist, d4=PROGDIR:, branches if script file
spaths	move.l	parm1(a5),a4	A4=parm1
spaths2	moveq	#0,d4	jump-in for resident,do not load scripts with it!
	move.l	thistask(a5),a3
	lea	pr_CurrentDir(a3),a3	(A3)=ptr to current dir
	move.l	(a3),d3			d3=current dir at beginning
	move.l	d3,d4			d4=PROGDIR:
	bsr	lock_or_load
	tst.l	d0
	bmi.s	.C		not found
	bne	gotit		found & executable
	tst.b	forcediskflag(a5)
	bne.s	.C		do not change dir
	tst.l	fib_DirEntryType(a5)	is it a DIR ?
	bmi	s_flagset	no, exec script ?
	tst.l	parm2(a5)
	bne.s	.C		argument given: do not change dir
	addq.l	#4,sp		return from archie3
	move.l	a4,a0
	bra	chdir		change current dir

.C	move.l	a4,a0
.F	move.b	(a0)+,d0	are there path-specific chars in the name
	cmp.b	#"/",d0
	beq.s	no_more_paths
	cmp.b	#":",d0
	beq.s	no_more_paths
	tst.b	d0
	bne.s	.F
	bsr	RequestersOff		no requesters
	move.l	CLIptr(a5),a2
	lea	cli_CommandDir(a2),a2	A2=ptr to current path

.A	move.l	(a2),d0		search all paths
	beq.s	no_more_paths
	lsl.l	#2,d0
	move.l	d0,a2
	move.l	4(a2),d4	d4=PROGDIR:
	beq.s	.A
	move.l	d4,(a3)
	bsr	lock_or_load	disk access
	tst.l	d0
	bmi.s	.A
	bne.s	gotit
	tst.l	fib_DirEntryType(a5)	is it a DIR ?
	bpl.s	.A
	bra.s	s_flagset	exec script
no_more_paths
	moveq	#0,d0
gotit	move.l	d3,(a3)		restore current dir
	bra	RequestersOn

lock_or_load
	move.l	a4,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	move.l	d0,d7
	bne.s	.A
	moveq	#-1,d0		file not found
	rts
.A	bsr	fibexam2
	moveq	#0,d0
	tst.l	fib_DirEntryType(a5)
	bpl.s	.C
	move.l	fib_Protection(a5),d1
	btst	#6,d1	script-bit ?
	bne.s	.C
	btst	#1,d1	not-execute-bit ?
	bne.s	.C
	move.l	a4,d1
	jsr	_LVOLoadSeg(a6)
.C	move.l	d0,-(sp)
	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	move.l	(sp)+,d0
	rts

s_flagset
	move.l	d3,(a3)		restore current dir
	bsr	RequestersOn
	addq.l	#4,sp	kill return addresses (archie3,spaths)
	move.l	fib_Protection(a5),d1
	btst	#6,d1
	beq.s	.A
	addq.l	#4,sp	kill return addresses (archie3,spaths)
	move.l	a4,a0	A4 pts to filename
	bsr	readfile
	move.l	d3,(a3)		restore current dir
	bra	xz3
.A	move.l	#305,d0
	tst.l	parm2(a5)	argument given: do not show file
	bne.s	.E
	tst.l	windowptr(a5)	no window ptr -> AUX: mode
	beq	pr_DOSerr
	cmp.l	d3,d4		PROGDIR=Current Dir ?
.E	bne	pr_DOSerr	NO: file not executable

showguide	;show ascii or amigaguide text
	move.l	thistask(a5),a0
	cmp.w	#36,kickver(a5)
	blo.s	.F
	move.l	d4,pr_HomeDir(a0)	init PROGDIR:
.F	move.l	4.w,a6		YES: show it with Amigaguide
	lea	guidename(pc),a1
	jsr	_LVOOldOpenLibrary(a6)
	tst.l	d0
	beq.s	.C		opened amigaguide.library ?
	move.l	d0,a6
	moveq	#NewAmigaGuide_SIZEOF/4-1,d0
.D	clr.l	-(sp)
	dbra	d0,.D
	move.l	a4,nag_Name(sp)	filename into nag
	move.l	windowptr(a5),a0
	move.l	wd_WScreen(a0),nag_Screen(sp) set screen
	move.l	sp,a0		nag to a0
	sub.l	a1,a1		must be zero
	jsr	_LVOOpenAmigaGuideA(a6)	open guide
	tst.l	d0
	beq.s	.B		failed to open guide ?
	move.l	d0,a0
	jsr	_LVOCloseAmigaGuide(a6)	wait till user closes guide
.B	lea	NewAmigaGuide_SIZEOF(sp),sp
	move.l	a6,a1		Free library
	move.l	4.w,a6
	jsr	_LVOCloseLibrary(a6)
.C	move.l	dosbase(a5),a6
	move.l	thistask(a5),a0
	cmp.w	#36,kickver(a5)
	blo.s	.G
	clr.l	pr_HomeDir(a0)		reset PROGDIR:
.G	rts


* ARCHIE 3 calls system0 to execute non internal commands
archie3	tst.l	parm1(a5)		exit if nothing typed
	beq	noarch31
	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
	cmp.w	#36,kickver(a5)
	blo.s	.A
	move.l	thistask(a5),a3
	move.l	d4,pr_HomeDir(a3)	init PROGDIR:
.A	move.l	d0,temp1(a5)		save the segment
	bsr	save_mem_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)
	cmp.w	#36,kickver(a5)
	blo.s	.G
	move.l	thistask(a5),a3
	clr.l	pr_HomeDir(a3)		reset PROGDIR:
.G	jsr	_LVOIoErr(a6)
	move.l	d0,Result2(a5)
	btst	#FLcheck,Flags+3(a5)
	beq.s	.C
	bsr	show_status
.C	tst.b	resi_flag(a5)
	beq.s	.B
	move.l	better_Seglist(a5),d1
	jsr	_LVOUnLoadSeg(a6)
.B	move.l	(sp)+,d2	RESULT IN D2
	beq.s	.D
	btst	#FLerrors,Flags+3(a5)
	beq.s	.D
	move.l	Result2(a5),d0
	beq.s	.D
	bsr	pr_DOSerr	if result > 0 print error
.D	move.l	d2,d0	
noarch31	rts
noarch32
	moveq	#-121,d0		command not found
	bsr	pr_DOSerr
	moveq	#RETURN_BAD,d0		return d0 bad
	rts


*****	SYSTEM0 execute command from disk. From Sozobon C distribution.
* Copyright © 1988 by Ralph Babel.
*
* This piece of code may be used as part of any product as
* long as the source code for the complete program can be
* obtained free of charge (except for a small copying fee)
* and this copyright notice is left unchanged.
_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)
	beq.s	.A
	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)
.A
* convert argument to LF-terminated string
tstsys0	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	REG_CIS,d1
	beq.s	.I
	move.l	d0,fh_Buf(REG_CIS)
.I	move.w	#MAXBSTR-2,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)+
	clr.b	(a1)
	move.l	sf_PrevStack(sp),REG_PrevStack
	sub.l	ARG_ARGS(REG_PrevStack),a0	;subtract first position
	move.l	a0,REG_CmdLine	;do NOT subtract 1, LF need this byte
* setup start/end indices in Stream Control Block
	move.l	REG_CIS,d0
	beq.s	.H
	clr.l   fh_Pos(REG_CIS)
	move.l  REG_CmdLine,fh_End(REG_CIS)
.H	cmp.w	#36,kickver(a5)
	blo.s	.A
	move.l	thistask(a5),a0		OS2: set argument string
	move.l	pr_Arguments(a0),sf_Arguments(sp)
	lea	sf_CommandArgs(sp),a1
	move.l	a1,pr_Arguments(a0)

* misc setup
.A	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	REG_CmdLine,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
	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),d0
	beq.s	.F
	move.l	d0,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)
.F	cmp.w	#36,kickver(a5)
	blo.s	.G
	move.l	thistask(a5),a0		OS2: reset argument string
	move.l	sf_Arguments(sp),pr_Arguments(a0)

* free temporary stack
.G	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	pr_hide_cursor
	move.l	parm2(a5),d7
	bne	help_man
	lea	helptx1(pc),a1
	bsr	pr_stringlf
	lea	comtext(pc),a4
	lea	tempbuf(a5),a3
.D	moveq	#5,d3
.C	move.l	a3,a2
	addq.l	#1,a4
	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
	bsr	pr_lf
	lea	helptx2(pc),a4
	lea	helptx3(pc),a0
	move.l	a0,d6
	bsr	pr_screen
	moveq	#RETURN_OK,D0
	rts

* print out part of manual, d7 points to topic
help_man
	bsr	pr_hide_cursor
	lea	manadr(pc),a2	global variable
	move.l	4(a2),d1
	move.l	(a2),d0
	bne.s	.A
	lea	helpld(pc),a1
	bsr	pr_string
	bsr	pr_lf
	move.l	online_help(a5),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
	moveq	#0,d4
	tst.l	d7
	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	#LF,d0
	bne.s	.C
	cmp.b	#"=",-6(a2)	there must be a lot of "=" before topic
	bne.s	.B
	cmp.b	#"=",-7(a2)	leave room for underlined sequence
	bne.s	.B
	cmp.b	#LF,-1(a2)
	beq.s	.F
	cmp.b	#"m",-1(a2)
	bne.s	.B
.F	move.l	a1,d4
.E	bsr	check_c		ctrl-c ?
	bne.s	.C
.D	cmp.l	d5,a1
	bhi.s	.C
	cmp.b	#LF,(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

*****************	
*	PATH	* 	Assign path or show it.
*****************
pathz	lea	parm2(a5),a3
	move.l	(a3),d0		see whether any parameters
	beq	ShowPaths
	move.l	CLIptr(a5),a4
	lea	cli_CommandDir(a4),a4
	move.l	d0,a0
	bsr	return_dash_option
	cmp.b	#"C",d0
	bne.s	.F
	bsr	DeletePaths	* remove all paths
	addq.l	#4,a3

.F	moveq	#-1,d3		reverse order
.G	addq.l	#1,d3
	tst.l	(a3)+
	bne.s	.G
	subq.l	#4,a3
	bra.s	.D
.C	move.l	-(a3),d1
	moveq	#ACCESS_READ,d2	* add as many paths as given
	jsr	_LVOLock(a6)	get a lock
	move.l	d0,d2
	beq	DOSerr
	bsr	CreatePath
	beq	resi_no_mem
.D	dbra	d3,.C
	moveq	#RETURN_OK,d0
	rts

DeletePaths	;a4=cli_CommandDir, removes all paths
	move.l	a2,-(sp)
	move.l	a4,a2
.A	move.l	(a2),d0
	beq.s	.B
	lsl.l	#2,d0
	move.l	d0,a2
	move.l	4(a2),d1
	beq.s	.A
	jsr	_LVOUnLock(a6)	unlock all paths
	bra.s	.A
.B	move.l	(a4),d1
	beq.s	.E
	jsr	_LVOUnLoadSeg(a6)	free memory
	tst.l	d0
	beq	DOSerr
	clr.l	(a4)		set path ptr to nil
.E	move.l	(sp)+,a2
	rts

CreatePath	;d2=Lock, a4=cli_CommandDir
	moveq	#12,d0
	bsr	iwantmem	create seglist
	bsr	maybeDOSerr
	beq.s	.A
	move.l	d0,a0
	addq.l	#4,d0
	lsr.l	#2,d0
	moveq	#12,d1
	move.l	d1,(a0)		size of seglist
	move.l	(a4),4(a0)	link the new path
	move.l	d2,8(a0)	bptr to lock
	move.l	d0,(a4)		first in path-list
.A	rts

ShowPaths
	bsr	pr_hide_cursor
	move.l	#-152,d0
	bsr	GetMessage
	move.l	a0,a1
	bsr	pr_stringlf
	move.l	CLIptr(a5),a0
	lea	cli_CommandDir(a0),a2
.A	move.l	(a2),d0
	beq.s	.B
	lsl.l	#2,d0
	move.l	d0,a2
	move.l	4(a2),d1
	beq.s	.A
	jsr	_LVODupLock(a6)
	tst.l	d0
	beq.s	.A
	lea	tempbuf(a5),a0
	bsr	eval_full_path
	jsr	_LVOUnLock(a6)
	lea	tempbuf(a5),a1
	bsr	pr_stringlf
	bra.s	.A
.B	moveq	#RETURN_OK,d0
	rts

CopyPaths	;copy paths from task in a0 to this task
	movem.l	d2-d3/a2-a4,-(sp)
	move.l	thistask(a5),a4
	move.l	pr_CLI(a4),d0
	beq.s	.D
	lsl.l	#2,d0
	move.l	d0,a4
	lea	cli_CommandDir(a4),a4
	move.l	pr_CLI(a0),d0
	beq.s	.D
	lsl.l	#2,d0
	move.l	d0,a0
	lea	cli_CommandDir(a0),a2
	lea	tempbuf(a5),a3
	moveq	#0,d3
.A	move.l	(a2),d0		* walk through all paths
	beq.s	.C
	lsl.l	#2,d0
	move.l	d0,a2
	move.l	4(a2),d1
	beq.s	.A
	move.l	d1,(a3)+
	addq.l	#1,d3
	bra.s	.A
.B	move.l	-(a3),d1
	jsr	_LVODupLock(a6)	copy lock
	move.l	d0,d2
	beq.s	.C
	bsr	CreatePath	add path
.C	dbra	d3,.B
.D	movem.l	(sp)+,d2-d3/a2-a4	return
	rts

*****************
*	INFO	*
*****************
infoz	bsr	pr_hide_cursor	;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)
	move.l	8(a4),packettask(a5)	;aptr task
	bsr	GetDiskInfo
	bne	.A		check for error
	move.l	sp_res2(a5),d0
	cmp.l	#209,d0
	beq.s	jajo
	bsr	pr_DOSerr
	bra.s	jajo
.A	bsr	do_forbid
	move.l	id_DiskType(a5),d1
	move.l	d1,d0
	clr.b	d0
	cmp.l	#"DOS"<<8,d0
	beq.s	itsDos		;DOS-Disk
	move.l	#226,d0
	moveq	#-1,d2
	cmp.l	d1,d2
	beq.s	.F
	subq.l	#1,d0
	cmp.l	#"BAD"<<8,d1
	beq.s	.F
	cmp.l	#"NDOS",d1
	beq.s	.F
	lea	kickdisk(pc),a0
	cmp.l	#"KICK",d1
	beq.s	.G
	move.l	#213,d0
.F	bsr	GetMessage
.G	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	quest_tx(pc),a0
	cmp.w	#36,kickver(a5)
	blo.s	.A
	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
	lea	64(a1),a1	de_DosType
	move.l	(a1),d0
	clr.b	d0
	cmp.l	#"DOS"<<8,d0
	beq.s	.A
	move.l	id_DiskType(a5),d0
	clr.b	d0
	cmp.l	#"DOS"<<8,d0
	bne.s	.C
	lea	temp2buf(a5),a0
	moveq	#4-1,d0
.F	move.b	(a1)+,(a0)+
	dbra	d0,.F
	clr.b	(a0)
	subq.l	#4,a0
	bra.s	.C
.A	move.l	id_DiskType(a5),d0
	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	close_redirection
	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	bsr	kill_script
	move.l	errorstack(a5),sp	kill return address on stack
	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)
	btst	#FLwild,Flags+3(a5)
	beq.s	.B
;	cmp.w	#37,kickver(a5)
;	blo.s	.B
	movem.l	d2-d3/a0/a1,-(sp)
	lea	tempbuf(a5),a1
	move.l	a1,d1
	bsr	rempath
	lea	wild_string(a5),a0
	move.l	a0,d2
	moveq	#40,d3
	jsr	_LVOParsePatternNC(a6)	external matcher
	movem.l	(sp)+,d2-d3/a0/a1
	tst.l	d0
	bmi.s	.A
	beq.s	.A
	lea	tempbuf(a5),a1
	bra.s	.C
.B	lea	wild_string(a5),a1	internal matcher
	clr.b	(a1)
	bsr	check_wild
	tst.b	d0
	bne.s	.A
.C	bsr	split_wild
	move.b	#1,wild_flag(a5)
.A	rts	

** CHECK STRING(A0) IF IT CONTAINS WILDCARD SPECIFIC CHARS
** RETURN D0=0 IF WILDS FOUND
check_wild	;only used by handle_wild_dirs
	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

** 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)
	cmp.w	#36,kickver(a5)
	blo.s	.A
	move.l	a0,a2
	move.l	a1,-(sp)
	move.l	a2,d1
	jsr	_LVOFilePart(a6)
	move.l	d0,a0
	move.l	(sp)+,a1
.C	move.b	(a0)+,(a1)+
	bne.s	.C
	move.l	a2,d1
	jsr	_LVOPathPart(a6)
	move.l	d0,a0
	clr.b	(a0)
	bra.s	sp_w8

.A	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
sp_w8	movem.l	(sp)+,d0-d1/a0-a2
	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
ignorematch
	lea	fib_FileName(a5),a0
	lea	FNCignore(a5),a1
	tst.b	(a1)
	bne.s	wildmatch	wildcheck for names to ignore
	moveq	#1,d0
	rts

wildmatcher
	lea	wild_string(a5),a1
wildmatch
	btst	#FLwild,Flags+3(a5)
	beq.s	iwildmatch
;	cmp.w	#37,kickver(a5)
;	blo.s	iwildmatch
	movem.l	d2/a0/a1,-(sp)
	move.l	a0,d2
	move.l	a1,d1
	jsr	_LVOMatchPatternNC(a6)	external matcher
	movem.l	(sp)+,d2/a0/a1
	moveq	#0,d1
	tst.l	d0
	bne.s	.A
	addq.l	#1,d1
.A	move.l	d1,d0
	rts
iwildmatch
	movem.l	d2/a0-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
	clr.b	-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/a0-a3
	tst.l	d0
	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	;uppercase d0 and d1 then compare them
	movem.l	d2/a0,-(sp)
	moveq	#0,d2
	move.l	chartable(a5),a0
	move.b	d0,d2
	move.b	0(a0,d2.w),d0
	move.b	d1,d2
	move.b	0(a0,d2.w),d1
	movem.l	(sp)+,d2/a0
	cmp.b	d1,d0
	rts

fibexnx	move.l	d7,d1
	move.l	a5,d2
	jsr	_LVOExNext(a6)
	rts

*********************************
*	DIRECTORY LISTER	*
*********************************
fname	equ	40	for sorting

* d6 bits:
DLwide		= 31	wide dir: DIR
DLquick		= 30	quick, nosort: (all)
DLverbose	= 29	verbose list: LIST
DLcomment	= 28	comment: LIST
DLfooter	= 27	footer: (auto)
DLdelete	= 26	delete file: DELETE,MOVE
DLnotproc	= 25	not process file: DELETE,COPY,MOVE
DLprotect	= 24	protect: PROTECT
DLcopy		= 23	copy: COPY,MOVE
DLmove		= 22	move: MOVE
DLrename	= 21	rename: MOVE
DLjoin		= 20	join: JOIN
DLsplit		= 19	split: SPLIT
DLsecond	= 18	left or right column: DIR
DLrecurs	= 17	recursive: (all)
DLsearch	= 16	search: SEARCH

dirz	moveq	#0,d6		WIDE DIR, 2 columns
	bset	#DLwide,d6
	bra.s	directory

listz	moveq	#0,d6		NARROW DIR, clear wide flag
	bset	#DLverbose,d6
	bset	#DLcomment,d6
directory		;V2.0:many things better (sort!)
	bsr	check_q_r
directory2
	bsr	pr_hide_cursor
	lea	parm2(a5),a2
	move.l	(a2),d1
	bne.s	.A
	lea	null(pc),a0
	move.l	a0,d1
	bra.s	.B

.A	move.l	(a2)+,d1	list all parms
	beq.s	.C
.B	move.l	a2,-(sp)
	move.l	d1,a2
	bsr	DirLister
	move.l	(sp)+,a2
	tst.l	d0
	bne.s	.E
	tst.b	break_flag(a5)
	beq.s	.A
.C	moveq	#RETURN_OK,d0
.E	rts

DirLister	;wants dirname or filename in a2
	lea	temp1(a5),a0		init total size
	clr.l	(a0)+
	clr.l	(a0)+
	clr.l	(a0)+
	clr.l	(a0)+
	bset	#DLrename,d6
	btst	#DLwide,d6
	beq.s	.A
	bset	#DLsecond,d6
.A	clr.w	indent_count(a5)
	move.l	a2,a0
	bsr	handle_wild_dirs
	lea	tempbuf(a5),a4
.C	move.b	(a2)+,(a4)+
	bne.s	.C
	bsr	pr_dir			-> print the dir

pr_size		;end of dirlister
	btst	#DLwide,d6		are we printing wide
	beq.s	.B
	btst	#DLsecond,d6
	bne.s	.B
	bsr	pr_lf			print missing lf
.B	lea	temp1(a5),a1
	lea	totsize(pc),a0
	btst	#DLfooter,d6
	beq.s	.A
	bsr	new_print		print footer
.A	btst	#DLdelete,d6		delete flag ?
	beq.s	.C
	btst	#DLrecurs,d6		recursiv, but no wildcard
	beq.s	.C
	tst.b	wild_flag(a5)
	bne.s	.C
	lea	tempbuf(a5),a0
	bsr	fibexam
	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	bsr	SingleFile		delete parent dir
.C	moveq	#RETURN_OK,d0
	rts

pr_dir	clr.l	dirpool(a5)
	bset	#DLfooter,d6
	bclr	#DLnotproc,d6
	lea	tempbuf(a5),a0
	bsr	fibexam
	bsr	fixsoftlink
	btst	#DLrecurs,d6
	bne.s	.B
	btst	#DLprotect,d6	protect flag ?
	bne.s	.D
	btst	#DLdelete,d6	delete flag ?
	beq.s	.B
.D	tst.b	wild_flag(a5)
	beq.s	.C
.B	tst.l	fib_DirEntryType(a5)	check entry OK
	bpl.s	prd20			print whole Directory

.C	bsr	check_c
	bne	unlock
	move.l	d7,d1
	jsr	_LVOUnLock(a6)		unlock file
SingleFile
	lea	tempbuf(a5),a0		process a single file/dir
	move.l	a0,a1
	tst.b	(a1)
	beq.s	.B
.A	tst.b	(a1)+
	bne.s	.A
	cmp.b	#"/",-2(a1)		make sure it does not end in /
	bne.s	.B
	clr.b	-2(a1)
.B	lea	temp2buf(a5),a1
	bsr	split_wild		separate path and filename
	lea	tempbuf(a5),a0
	move.l	a0,d1			get a lock on the dir
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	move.l	d0,d7
	bsr	pr_it			print single file/dir
	bclr	#DLfooter,d6		do not print footer
	bra	unlock			make sure to unlock

prd20	tst.w	indent_count(a5)	was a dir
	bne.s	.A
	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	lea	tempbuf(a5),a0
	move.l	a0,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	lea	temp2buf(a5),a0		get full dir name for later
	clr.b	(a0)
	tst.l	d0
	beq	DOSerr
	bsr	eval_full_path
	jsr	_LVOUnLock(a6)
	lea	dirof(pc),a1
	bsr	pr_string
	lea	temp2buf(a5),a1
	bsr	pr_stringlf		print directory's name
	lea	tempbuf(a5),a0
	bsr	fibexam

.A	sub.l	a3,a3	;clr a3
prd2
	bsr	check_c		CTRL-C pressed ?
	bne	unlk
	bsr	fibexnx
	tst.l	d0
	beq	unlk		;sort ?
	bsr	fixsoftlink
	btst	#DLwide,d6
	beq.s	.C
	btst	#FLhbit,Flags+2(a5)	check for H protection bit ?
	beq.s	.F
	btst	#7,fib_Protection+3(a5)
	bne.s	prd2
.F	lea	fib_FileName(a5),a0
	bsr	ignorematch		hide config-hide
	beq.s	prd2
.C	tst.b	wild_flag(a5)
	beq.s	dozel
	btst	#DLrecurs,d6
	beq.s	.A
	tst.l	fib_DirEntryType(a5)
	bpl.s	dozel
.A	lea	fib_FileName(a5),a0
	bsr	wildmatcher		check wildcards
	tst.b	d0
	bne.s	prd2
	btst	#DLcopy,d6	copy, move or join ?
	bne.s	.E
	btst	#DLjoin,d6
	beq.s	.D
.E	move.l	d7,a0		check for destination dir/file
	add.l	a0,a0
	add.l	a0,a0
	move.l	temp5(a5),a1
	add.l	a1,a1
	add.l	a1,a1
	move.l	fl_Volume(a0),d0
	cmp.l	fl_Volume(a1),d0
	bne.s	.D
	move.l	fl_Key(a1),d0
	cmp.l	fib_DiskKey(a5),d0
	beq	prd2
.D
dozel	btst	#DLquick,d6
	beq.s	collect			not quick
	btst	#DLdelete,d6
	bne.s	collect			delete
	bsr	zelma
	bra	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
	lea	dirpool(a5),a1
	bsr	AutoAllocPooled
	bsr	maybeDOSerr
	beq	unlock
	move.l	d0,a0
	move.l	a3,(a0)+
	move.l	d0,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	#DLdelete,d6
	bne.s	.A		delete
	btst	#DLquick,d6
	bne	unlock		quick
.A	move.l	a3,d0	
	beq	unlock		no files
;	tst.b	break_flag(a5)
;	bne.s	nextfi		CTRL-C pressed

	movem.l	a4-a6,-(sp)
	btst	#DLquick,d6
	bne	snull		quick
	move.l	chartable(a5),d2
	lea	(a3),a0		;INSERTION SORT  V2.0   (ooohuuooo)
aussort	lea	(a3),a1
	move.l	(a0),a2	;remove (a0->) a2
	move.l	a2,d0
	beq	snull	;end of list
	move.l	(a2),(a0)
	bsr.s	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.s	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

strcmp	exg	d2,a0
	move.l	8(a1),d0
	move.l	8(a2),d1
	bmi.s	.A
	tst.l	d0	a2 is dir
	bpl.s	.B	a1 is dir too
	bra	donoth	a2:dir	a1:file
.A	tst.l	d0	a2 is file
	bpl	inseit	a2:file	a1:dir
.B	lea	fname(a1),a5	a1 is file too
	lea	fname(a2),a6
	moveq	#0,d0
	moveq	#0,d1
.C	move.b	(a5)+,d1	compare strings in a5 and a6
	beq.s	donoth
	move.b	(a6)+,d0
	beq.s	inseit
	move.b	0(a0,d0.w),d0
	cmp.b	0(a0,d1.w),d0
	beq.s	.C
	move.b	0(a0,d1.w),d1
	cmp.b	#"9",d0		check for numbers
	bhi.s	.D
	cmp.b	#"9",d1
	bhi.s	.D
	cmp.b	#"0",d0
	blo.s	.D
	cmp.b	#"0",d1
	blo.s	.D
	movem.l	d0-d2,-(sp)	compare numbers
	moveq	#0,d2
.G	move.b	(a5)+,d1	check first name for number
	beq.s	.E
	cmp.b	#"9",d1
	bhi.s	.E
	cmp.b	#"0",d1
	bhs.s	.H
.E	moveq	#1,d2		not a number
.H	move.b	(a6)+,d0	check second name for number
	beq.s	.F
	cmp.b	#"9",d0
	bhi.s	.F
	cmp.b	#"0",d0
	bhs.s	.J
.F	tst.l	d2		not a number
	bne.s	.I		both no numbers -> compare first char
	moveq	#-1,d2		second no number -> inseit
	bra.s	.I
.J	tst.l	d2
	beq.s	.G		both numbers
	moveq	#0,d2		first no number -> donoth
.I	tst.l	d2
	movem.l	(sp)+,d0-d2
	beq.s	donoth
	bmi.s	inseit
.D	cmp.b	d1,d0
	bhi.s	donoth
inseit	exg	d2,a0
	moveq	#0,d0		insert it !
	rts
donoth	exg	d2,a0
	moveq	#1,d0		do nothing !
	rts

snull	movem.l	(sp)+,a4-a6	;FINISHED SORTING !!!
	btst	#DLwide,d6	for normal DIR
	beq.s	nextfi
	btst	#DLrecurs,d6
	bne.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	lea	4(a3),a1	print all files
	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)
	tst.b	break_flag(a5)
	bne.s	.C		CTRL-C pressed
	bsr	check_c
	bne.s	.C
	bsr	zelma
.C	movem.l	(sp)+,d0/a2/a3
	move.l	(a3),d2
	lea	(a3),a1
;	bsr	givemem
	move.l	d2,a3
	btst	#DLwide,d6
	beq.s	.A
	btst	#DLrecurs,d6
	bne.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	lea	dirpool(a5),a1
	bsr	DeletePool
	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	rts

zelma	tst.l	fib_DirEntryType(a5)
	bpl.s	.C
	bsr	pr_it		print file
	rts
.C	btst	#DLrecurs,d6
	bne.s	.B
	bsr	pr_it		print dir
.A	rts
.B	bset	#DLnotproc,d6	do not process this dir
	bsr	pr_it		print dir recursive
	bclr	#DLnotproc,d6
	move.l	d6,d0
	and.l	#1<<DLdelete!1<<DLcopy!1<<DLjoin,d0	copy,delete or join flag
	beq.s	.D		no
	btst	#DLcopy,d6	copy ?
	beq.s	.E
	move.l	temp5(a5),d1	yes:create new dir
	bsr	CurrentDir
	move.l	d0,d3
	lea	fib_FileName(a5),a2	copy: create dir
	move.l	a2,d1
	jsr	_LVOCreateDir(a6)
	move.l	d0,d2
	bne.s	.F
.G	jsr	_LVOIoErr(a6)
	cmp.l	#203,d0
	beq.s	.H
	move.l	d0,d2
	bsr	pr_lf
	move.l	d3,d1
	bsr	CurrentDir
	move.l	d2,d0
	bsr	pr_DOSerr
	rts
.F	move.l	d2,d1		unlock new dir, because is exclusive
	jsr	_LVOUnLock(a6)
.H	move.l	a2,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	move.l	d0,d2
	beq.s	.G
	move.l	d3,d1
	bsr	CurrentDir
	move.l	temp5(a5),d1	unlock old in temp5
	jsr	_LVOUnLock(a6)
	move.l	d2,temp5(a5)
	lea	makedirOK(pc),a1
	bsr	pr_string
	bsr	AdjustPath
	bra.s	.D
.E	bsr	pr_lf		no copy: just print lf

.D	moveq	#120,d0	;(24bytes per recurs + subs + move-path)
	bsr	stacktest
	bne	.A
	move.l	fib_DiskKey(a5),d0
	movem.l	d0/d7/a4,-(sp)
	move.l	dirpool(a5),-(sp)
	lea	fib_FileName(a5),a0
	subq.l	#1,a4
	lea	tempbuf(a5),a1
	cmp.l	a1,a4
	beq.s	jo
	cmp.b	#":",-1(a4)
	beq.s	jo
	cmp.b	#"/",-1(a4)
	beq.s	jo
	move.b	#"/",(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)
	move.l	(sp)+,dirpool(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)
	addq.l	#1,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)
	btst	#DLcopy,d6		copy ?
	beq.s	.B
	move.l	temp5(a5),d2	COPY
	move.l	d2,d1
	jsr	_LVOParentDir(a6)
	move.l	d0,temp5(a5)
	move.l	d2,d1
	jsr	_LVOUnLock(a6)
	bsr	AdjustPath
.B	btst	#DLdelete,d6		delete ?
	beq.s	.A
	move.l	d6,-(sp)
	bclr	#DLmove,d6	move off
	bsr	pr_it		now delete this dir
	move.l	(sp)+,d6
.A	rts

AdjustPath
	btst	#DLmove,d6
	beq.s	.D
	btst	#DLrename,d6
	beq.s	.D
	move.l	temp5(a5),d1
	jsr	_LVODupLock(a6)
	tst.l	d0
	beq	DOSerr
	move.l	temp7(a5),a0
	bsr	eval_full_path
	jsr	_LVOUnLock(a6)
.D	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
	addq.l	#1,temp4(a5)		one dir more
	lea	farb3(pc),a1		change foregnd colour
	bsr	addstring
	btst	#DLwide,d6		check for "DIR -R"
	beq.s	.A
	btst	#DLrecurs,d6
	beq.s	.A
	btst	#DLsecond,d6
	bne.s	.H
	bsr	pr_lf			for DIR -R directories
	bra.s	.A
.H	bchg	#DLsecond,d6

.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
	addq.l	#1,temp3(a5)		one file more
	move.l	fib_NumBlocks(a5),d0
	add.l	d0,temp2(a5)
	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	prlink
.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
prlink	move.b	#" ",(a2)+
	move.b	#" ",(a2)+
	move.l	fib_DirEntryType(a5),d0
	moveq	#-6,d1
	cmp.l	d1,d0
	bne.s	.B
	move.b	#"S",-1(a2)
	bra.s	.A
.B	moveq	#4,d1
	cmp.l	d1,d0
	bne.s	.C
	move.b	#"H",-1(a2)
	bra.s	.A
.C	moveq	#-4,d1
	cmp.l	d1,d0
	bne.s	.A
	move.b	#"H",-1(a2)
.A	move.b	#" ",(a2)+
	btst	#DLwide,d6		are we printing wide
	beq.s	wpro
	bchg	#DLsecond,d6
	bne.s	.F
	move.b	#LF,(a2)+
.F	clr.b	(a2)
	lea	temp2buf(a5),a1
	bra	pr_string		print string&return and return

wpro	btst	#DLverbose,d6
	beq.s	.E
	move.l	a2,a0
	bsr	pr_pro2			print protection V2.0
	move.b	#" ",(a0)+
	move.l	a0,a2			(goes to temp2buf)
	btst	#DLprotect,d6	protect flag ?
	bne.s	.E
	lea	fib_Date(a5),a1
	bsr	insert_date
	move.b	#LF,(a2)+
.E	clr.b	(a2)
	lea	temp2buf(a5),a1
	bsr	pr_string		print date/time V2.0

	move.l	d7,d1
	bsr	CurrentDir		d0=old current dir
	movem.l	d0/d4-d5/d7/a3-a4,-(sp)
	move.l	d7,d5
	btst	#DLcomment,d6
	beq	fort
	tst.b	fib_Comment(a5)
	beq.s	.A
	bsr	num_spc
	lea	farb2(pc),a1
	bsr	addstring
	move.b	#":",(a2)+
	clr.b	(a2)
	lea	temp2buf(a5),a1
	bsr	pr_string
	lea	fib_Comment(a5),a1
	bsr	pr_string		print Comment V2.0
	lea	farb1(pc),a1
	bsr	pr_stringlf

.A	cmp.w	#36,kickver(a5)
	blo	fort
	move.l	fib_DirEntryType(a5),d0
	bpl.s	.F
	neg.l	d0
.F	moveq	#4,d1
	cmp.l	d0,d1
	bne.s	.G
	lea	NewPrintBuffer(a5),a2	process hardlinks
	lea	farb2(pc),a1
	bsr	addstring
	lea	pfeil(pc),a1
	bsr	addstring
	lea	fib_FileName(a5),a0
	move.l	a0,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	tst.l	d0
	beq.s	.C
	move.l	a2,a0
	bsr	eval_full_path
	jsr	_LVOUnLock(a6)
	bra.s	.B
.G	moveq	#-6,d0
	cmp.l	fib_DirEntryType(a5),d0	check whether is softlink
	bne.s	fort
	lea	fib_FileName(a5),a2	process softlinks
	move.l	a2,d1
	jsr	_LVODeviceProc(a6)
	move.l	d0,d4
	beq.s	.C
	move.l	a2,d3	path (filename)
	lea	NewPrintBuffer(a5),a2
	lea	farb2(pc),a1
	bsr	addstring
	lea	pfeil(pc),a1
	bsr	addstring
	move.l	d4,d1	msgport of device
	move.l	d5,d2	lock on current dir
	move.l	a2,d4	buffer
	moveq	#120,d5	size of buffer
	jsr	_LVOReadLink(a6)
.C	bsr	maybeDOSerr
	beq.s	fort
.B	lea	NewPrintBuffer(a5),a1
	bsr	pr_string		;print softlink V2.3
	lea	farb1(pc),a1
	bsr	pr_stringlf

fort	move.l	d6,d0
	and.l	#1<<DLdelete!1<<DLcopy!1<<DLjoin,d0	copy,delete or join flag
	beq	.B		no: try protect
	btst	#DLnotproc,d6
	bne	.A		not process flag ?

	btst	#DLmove,d6		move flag ?
	beq.s	.E
	btst	#DLrename,d6		MOVE !
	beq.s	.E	need not try to rename
	tst.l	fib_DirEntryType(a5)
	bpl.s	.D	delete dir
	lea	fib_FileName(a5),a0
	bsr	MoveFile
	bne	.A
	jsr	_LVOIoErr(a6)
	cmp.l	#215,d0
	bne.s	.E
	bclr	#DLrename,d6		cannot rename

.E	btst	#DLcopy,d6		copy flag ?
	beq.s	.D
	tst.l	fib_DirEntryType(a5)
	bpl	.H
	lea	fib_FileName(a5),a0	COPY !
	bsr	CopyFileToDir
	bne	.A		error occured->not delete

.D	btst	#DLdelete,d6		delete flag ?
	beq.s	.C
	lea	fib_FileName(a5),a0	DELETE !
	tst.l	fib_DirEntryType(a5)
	bpl.s	.I	
	bsr	DoDelete
	bra.s	.C
.I	bsr	DoDelete2

.C	btst	#DLjoin,d6		join flag ?
	beq.s	.B
	tst.l	fib_DirEntryType(a5)
	bpl.s	.H
	lea	fib_FileName(a5),a0	JOIN !
	bsr	JoinFile

.B	btst	#DLsearch,d6		search flag ?
	beq.s	.G
	tst.l	fib_DirEntryType(a5)
	bpl.s	.H
	lea	fib_FileName(a5),a0	SEARCH !
	bsr	SearchFile

.G	btst	#DLprotect,d6		protect flag ?
	beq.s	.A
	btst	#DLrecurs,d6		PROTECT !
	beq.s	.F
	tst.l	fib_DirEntryType(a5)	no recursive dir protects
	bpl.s	.H
.F	move.l	fib_Protection(a5),d2
	move.l	d2,d0
	eor.b	#$0f,d2
	and.l	temp6(a5),d2
	or.l	temp5(a5),d2
	eor.b	#$0f,d2
	cmp.l	d2,d0
	beq.s	.H
	move.l	d2,fib_Protection(a5)
	lea	fib_FileName(a5),a0
	move.l	a0,d1
	jsr	_LVOSetProtection(a6)
	bsr	maybeDOSerr
	lea	temp2buf(a5),a2	print new protection
	lea	pfeil(pc),a1
	bsr	addstring
	move.l	a2,a0
	bsr	pr_pro2
	move.b	#LF,(a0)+
	clr.b	(a0)
	bsr	pr_string	(temp2buf in a1)

	bra.s	.A
.H	bsr	pr_lf
.A	movem.l	(sp)+,d0/d4-d5/d7/a3-a4
	move.l	d0,d1
	bsr	CurrentDir
	rts

insert_date	;a1 points to datestamp, string goes to a2
	lea	-14(sp),sp
	lea	(sp),a0
	bsr	convert_time
	move.l	a2,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
	lea	14(sp),sp
	move.l	a1,a2
	rts

qprint10 move.w	(a0)+,d0	V2.0
qpr10	ext.l	d0	(also used by More, GuruIt and Pipe)
	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
	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	#LF,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

fixsoftlink
	moveq	#3,d0
	cmp.l	fib_DirEntryType(a5),d0		is it a softlink ?
	bne.s	.A
	move.l	#-6,fib_DirEntryType(a5)	make it look like a file
.A	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
	tst.b	break_flag(a5)
	bne.s	.A
	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	.B
.A	move.l	dosbase(a5),a6
	move.l	#304,d0
	bsr	pr_DOSerr
	move.b	#1,break_flag(a5)	NE: STOP!!!
	movem.l	(sp)+,d0-d1/a0-a1/a6
	rts
.B	clr.b	break_flag(a5)
	moveq	#0,d0			EQ: no stop
	movem.l	(sp)+,d0-d1/a0-a1/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


** ENTRY A0 pts to parameter.
** EXIT D0=lower case char after dash OR 0 if no dash command.
return_dash_option
	move.l	a0,d0
	beq.s	.B
	moveq	#0,d0
	cmp.b	#$22,-1(a0)	enclosed in quotes ?
	beq.s	.B
	cmp.b	#'-',(a0)	options start with a dash
	bne.s	.B
	tst.b	2(a0)		max. 1 char each option
	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

check_q_r	;checks for -q, -s or -r (or ALL) options, parm-ptr in a2
	lea	parm2(a5),a2
	bclr	#DLrecurs,d6
	btst	#FLall,Flags+3(a5)
	beq.s	.A
	lea	alltx(pc),a0
	bsr	LookForOpt
	bne.s	.A
	bset	#DLrecurs,d6
.A	move.l	a2,a1
	move.l	(a1),d0
	beq.s	.E
	move.l	d0,a0
	bsr	return_dash_option
	tst.l	d0
	beq.s	.E
	cmp.b	#"R",d0
	bne.s	.B
	bset	#DLrecurs,d6		-r -> recursive
	bra.s	.G
.B	cmp.b	#"Q",d0
	bne.s	.C
	bset	#DLquick,d6		-q -> quick,nosort
	bra.s	.G
.C	cmp.b	#"S",d0
	bne.s	.E
	bclr	#DLquick,d6		-s -> noquick,sort
.G	lea	4(a1),a0
.F	move.l	(a0)+,(a1)+
	bne.s	.F
	bra.s	.A
.E	rts


CurrentDir	;same as _LVOCurrentDir(a6)
	move.l	thistask(a5),a0
	lea	pr_CurrentDir(a0),a0
	move.l	(a0),d0
	move.l	d1,(a0)
	rts

*************************
*	DELETE		*	V2.3 new written
*************************
deletez	moveq	#0,d6
	bset	#DLdelete,d6
	bsr	check_q_r
	move.l	(a2),d0
	beq	too_less_args
	move.l	d0,a0
	lea	devicetx(pc),a1
	bsr	CheckOpt
	beq	deldevice	format device quick
	lea	forcetx(pc),a0
	bsr	LookForOpt	FORCE-flag ?
	subq.l	#1,d0
	move.l	d0,temp5(a5)
	bra	directory2	delete as many files as given

DoDelete	;file to delete in a0
	bsr	AskYesNo	ASK first
	bne.s	DoDeEnd
DoDelete2
	move.l	a0,a2
.E	move.l	a2,d1
	jsr	_LVODeleteFile(a6)	delete file/dir
	tst.l	d0
	bne.s	.B
.D	jsr	_LVOIoErr(a6)
	cmp.l	#222,d0		delete-protected ?
	bne.s	.A
	tst.l	temp5(a5)	FORCE-flag ?
	beq.s	.A
	move.l	a2,d1
	moveq	#0,d2
	jsr	_LVOSetProtection(a6)
	tst.l	d0
	beq.s	.D
	bra.s	.E		try again
.A	btst	#DLmove,d6
	bne.s	.F		move: do not print lf
	bsr	pr_lf			error occured
.F	bsr	pr_DOSerr
	bra.s	DoDeEnd
.B	lea	deleteOK(pc),a1	delete successful
	btst	#DLmove,d6
	bne.s	DoDeEnd		move: do not print
	bsr	pr_string
DoDeEnd	rts


AskYesNo
	movem.l	d1-d3/a0-a2,-(sp)
	btst	#FLconfirm,Flags+2(a5)
	beq	.B
	btst	#DLquick,d6		quick flag set
	bne.s	.B
	btst	#DLmove,d6		move-> do not ask
	bne.s	.B
	move.l	stdin(a5),d1
	beq.s	.B
	bsr	raw_on
	bsr	pr_show_cursor
	lea	yesnotx(pc),a1
	bsr	pr_string
	lea	temp2buf(a5),a2
	clr.b	(a2)
	move.l	a2,d2
	moveq	#20,d3	read only 1 char
	jsr	_LVORead(a6)
	clr.b	1(a2)
	cmp.b	#13,(a2)
	bne.s	.F
	move.b	#"Y",(a2)
.F	bclr	#5,(a2)
	move.l	a2,a1
	bsr	pr_string	show it
	bsr	pr_space
	bsr	pr_hide_cursor
	bsr	raw_off
	cmp.b	#"Y",(a2)	yes ?
	beq.s	.B
	cmp.b	#"A",(a2)	all ?
	bne.s	.A
	bset	#DLquick,d6	set quick flag
	bra.s	.B
.A	cmp.b	#"Q",(a2)	quit ?
	bne.s	.E
	move.b	#1,break_flag(a5)
.E	bsr	pr_lf
.C	moveq	#-1,d0		NO end
	bra.s	.D
.B	moveq	#0,d0		YES end
.D	movem.l	(sp)+,d1-d3/a0-a2
	rts

*************************
deldevice		;formats device quick	V2.3
	bsr	CheckKS
	move.l	parm3(a5),d1
	beq	too_less_args
	move.l	d1,a2
	moveq	#-2,d2
	jsr	_LVOLock(a6)	lock on drive
	move.l	d0,d7
	beq	DOSerr
	move.l	d0,d1
	move.l	a5,d2		get info data into fib
	jsr	_LVOInfo(a6)
	tst.l	d0
	beq	DOSerrUL
	move.l	d7,d1
	jsr	_LVOUnLock(a6)
	lea	formatask(pc),a1
	bsr	pr_string
	bsr	rask
	tst.l	d0
	beq.s	.A
	move.l	parm4(a5),d4
	bne.s	.B
	move.l	id_VolumeNode(a5),a0
	add.l	a0,a0
	add.l	a0,a0
	move.l	$28(a0),a1	volumename
	add.l	a1,a1
	add.l	a1,a1
	lea	temp2buf(a5),a4
	move.l	a4,d4
	bsr	copy_bstr
	clr.b	(a4)
.B	move.l	parm5(a5),d0	check for filesystem
	beq.s	.D
	lea	ofs_tx(pc),a1
	move.l	d0,a0
	moveq	#0,d3
.E	bsr	CheckOpt
	bne.s	.F
	add.l	#"DOS"<<8,d3
	bra.s	.G
.F	addq.b	#1,d3
	cmp.b	#6,d3
	bne.s	.E
.D	move.l	id_DiskType(a5),d3	dostype
.G	move.l	a2,d1
	moveq	#-1,d2
	jsr	_LVOInhibit(a6)		disable drive
	tst.l	d0
	beq	DOSerr
	move.l	a2,d1
	move.l	d4,d2
	jsr	_LVOFormat(a6)		format it quick !
	bsr	maybeDOSerr
	move.l	a2,d1
	moveq	#0,d2
	jsr	_LVOInhibit(a6)		enable drive
	tst.l	d0
	beq	DOSerr
.A	moveq	#RETURN_OK,d0
	rts

*************************
*	PROTECT		*	V2.3 new written
*************************
protectz
	moveq	#0,d6
	bset	#DLverbose,d6
	bset	#DLprotect,d6
	bset	#DLquick,d6
	bsr	check_q_r
	tst.l	(a2)+
	beq	too_less_args
	clr.l	temp5(a5)
	clr.l	temp6(a5)
.A	move.l	(a2)+,d0
	beq.s	.D
	move.l	d0,a0
	cmp.b	#"+",(a0)	look for add-option
	bne.s	.B
	bsr	GetProtMask
	or.l	d0,temp5(a5)
	bra.s	.C
.B	cmp.b	#"-",(a0)	look for sub-option
	bne.s	.F
	bsr	GetProtMask
	or.l	d0,temp6(a5)
	bra.s	.C
.F	cmp.b	#"=",(a0)	look for equal-option
	bne.s	.A
	bsr	GetProtMask
	move.l	d0,temp5(a5)
	moveq	#-1,d0
	move.l	d0,temp6(a5)
.C	move.l	a2,a0
	lea	-4(a2),a1
.E	move.l	(a0)+,(a1)+	delete this parm
	bne.s	.E
	subq.l	#4,a2
	bra.s	.A

.D	moveq	#-1,d0
	eor.l	d0,temp6(a5)
	bra	directory2	jump into dir-lister


GetProtMask	;a0=bits-string, d0=bit-mask
	moveq	#0,d0
	addq.l	#1,a0
.B	move.b	(a0)+,d1
	beq.s	.C
	moveq	#7,d2
.A	cmp.b	protflags(pc,d2.w),d1
	bne.s	.D
	bset	d2,d0
	bra.s	.B
.D	dbra	d2,.A
	lea	badprotbit(pc),a0
	bra	ErrorExit
.C	rts

pr_prot	lea	temp2buf(a5),a0		V2.0
pr_pro2	moveq	#7,d0
	move.l	fib_Protection(a5),d1
	eor.b	#$0f,d1
.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'

*************************
*	JOIN		*	V2.3 new written
*************************
joinz	moveq	#0,d6
	bset	#DLjoin,d6	set join flag
	bsr	check_q_r
	clr.l	devproc(a5)
	clr.l	temp5(a5)	destination lock
	clr.l	temp6(a5)	memory block
	clr.l	temp7(a5)	destination file
	lea	parm2(a5),a3
	addq.l	#4,a3
	tst.l	(a3)+
	beq	too_less_args	no arg given
.A	tst.l	(a3)+
	bne.s	.A
	move.l	-8(a3),a2	get last parm
	clr.l	-8(a3)		and remove it
	move.l	a2,d1
	bsr	OpenReadWrite
	move.l	d0,temp7(a5)	open output file and store it
	beq	DOSerr
	move.l	d0,d1
	moveq	#0,d2
	moveq	#1,d3
	jsr	_LVOSeek(a6)	look for end, no error checking
	move.l	a2,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)
	move.l	d0,temp5(a5)
	bsr	GetCopyBlock
	beq	.F
	move.l	d0,temp6(a5)
	bsr	directory2	DO COPY !
	bsr	FreeCopyBlock
.F	move.l	temp5(a5),d1
	jsr	_LVOUnLock(a6)
	move.l	temp7(a5),d1
	jsr	_LVOClose(a6)
	moveq	#RETURN_OK,d0
	rts

JoinFile	;a0=filename, temp5=outfile, temp6=mem block
	moveq	#0,d4
	move.l	a0,d1
	bsr	OpenOldfile	open input file
	move.l	d0,d4		d4=input file handle
	beq	perr3
	move.l	temp7(a5),d5	d5=output file handle
	bsr	PerformCopy		Main Stuff !
	bne.s	.C
	lea	processOK(pc),a1	all OK
	bsr	pr_string
	moveq	#RETURN_OK,d0
.C	rts

*************************
*	MOVE		*	V2.3
*************************
movez	moveq	#0,d6
	bset	#DLmove,d6	set move flag
	bset	#DLrename,d6	set rename flag
	bset	#DLdelete,d6	set delete flag
	clr.l	temp7(a5)	holds full dest. pathname
	bra.s	Copy1

MoveFile	;Filename in a0
	move.l	a0,a3
	move.l	temp7(a5),a0	path
	move.l	a3,a1		name
	lea	temp2buf(a5),a2	path+name
	bsr	addpath
	move.l	a2,d2
	move.l	a3,d1
	jsr	_LVORename(a6)
	tst.l	d0
	beq.s	.A
	lea	moveOK(pc),a1
	bsr	pr_string
	moveq	#1,d0
.A	rts

*************************
*	COPY		*	V2.3 new written
*************************
copyz	moveq	#0,d6
Copy1	bset	#DLcopy,d6
	bset	#DLquick,d6
	bsr	check_q_r
	clr.l	devproc(a5)
	clr.l	temp5(a5)	destination dir
	clr.l	temp6(a5)	memory block
	lea	parm2(a5),a2
	tst.l	(a2)+
	beq	too_less_args	*no arg given
	tst.l	(a2)+
	bne.s	Copy2
	lea	null(pc),a2	*one arg -> copy to current dir
	bra	Copy3b

Copy2	tst.l	(a2)+
	bne	Copy3
	move.l	-8(a2),a0	*two args -> copy to file/dir
	clr.l	-8(a2)		get it and remove it
	move.l	a0,a2
	move.l	parm2(a5),a0
	bsr	check_wild
	tst.l	d0
	beq	Copy3b		wildcards->copy to dir
	move.l	a2,a0
	move.b	dotchar(a5),d0
	bsr	CheckOneChar
	bne.s	.F
	lea	CDbackstr(a5),a2	dot->copy to last used dir
	bra	Copy3b
.F	btst	#DLmove,d6
	beq.s	.B		move: try to rename
	move.l	parm2(a5),d1
	move.l	a2,d2
	jsr	_LVORename(a6)
	tst.l	d0
	beq.s	.B		move:	failed
	move.l	parm2(a5),a1		OK
	bsr	pr_string
	bsr	pr_space
	lea	moveOK(pc),a1
	bsr	pr_string
	moveq	#RETURN_OK,d0
	rts
.B	move.l	parm2(a5),d1	try to copy file to file:
	bsr	OpenOldfile	try to open input file	(d4)
	move.l	d0,d4
	beq.s	Copy3b		input not found->maybe a dir
	move.l	a2,d1
	bsr	OpenNewfile	try to open output file (d5)
	move.l	d0,d5
	bne.s	.D
	bsr	closett
	bra.s	Copy3b
.D	move.l	parm2(a5),a1
	bsr	pr_string
	bsr	pr_space
	bsr	GetCopyBlock
	bne.s	.A
	bsr	closett
	bra	resi_no_mem
.A	bsr	PerformCopy	do copy !
	move.l	d0,d4
	bsr	FreeCopyBlock
	tst.l	d4		error occured ?
	bne.s	.E
	btst	#DLmove,d6	move flag ?
	beq.s	.C
	move.l	parm2(a5),a0
	bsr	DoDelete	move: delete old file
.C	lea	copyOK(pc),a1		all OK
	bsr	pr_string
.E	move.l	d4,d0
	rts

Copy3	tst.l	(a2)+		*three or more args -> copy them to dir
	bne.s	Copy3		look for last parm
	move.l	-8(a2),a0	get it
	clr.l	-8(a2)		and remove it
	move.l	a0,a2
Copy3b	move.l	a2,d1
	moveq	#ACCESS_READ,d2
	jsr	_LVOLock(a6)	try to lock dir
	move.l	d0,d7
	bne.s	.B		found
	jsr	_LVOIoErr(a6)
	cmp.l	#205,d0		object not found ?
	beq.s	.C
	bra	pr_galactic	no
.C	move.l	a2,d1
	jsr	_LVOCreateDir(a6)	yes, make dir
	move.l	d0,d1
	beq	DOSerr
	jsr	_LVOUnLock(a6)	unlock and try again
	move.l	a2,a1
	bsr	pr_string
	bsr	pr_space
	lea	makedirOK(pc),a1
	bsr	pr_string
	bra.s	Copy3b
.B	bsr	fibexam2
	tst.l	fib_DirEntryType(a5)	file or dir ?
	bpl.s	.E
	move.l	d7,d1
	jsr	_LVOUnLock(a6)	was not a dir
	move.l	#212,d0
	bra	pr_galactic
.E	move.l	d7,temp5(a5)	was a dir: store lock
	lea	-80(sp),sp
	move.l	sp,temp7(a5)
	bsr	AdjustPath	move: get full path
	move.l	a2,d1
	jsr	_LVODeviceProc(a6)
	move.l	d0,devproc(a5)
	bsr	GetCopyBlock
	beq	.F
	bsr	directory2	DO COPY !
	bsr	FreeCopyBlock
.F	lea	80(sp),sp	space needed for move
	move.l	temp5(a5),d1
	jsr	_LVOUnLock(a6)	unlock dir
	moveq	#RETURN_OK,d0
	rts

GetCopyBlock
	move.l	copysize(a5),d0
	bsr	iwantmem	get memory block
	move.l	d0,temp6(a5)
	bsr	maybeDOSerr
	rts

FreeCopyBlock
	move.l	temp6(a5),a1
	move.l	copysize(a5),d0
	bra	givemem		free memory block

CopyFileToDir	;a0=filename
*current path set, destination path in temp5, memory block in temp6
	moveq	#0,d4
	moveq	#0,d5
	move.l	a0,a2
	move.l	a0,d1
	bsr	OpenOldfile	open input file
	move.l	d0,d4		d4=input file handle
	beq	perr3		read protected ?
	move.l	a2,a0
	lea	temp2buf(a5),a2
	move.l	a2,a1
	bsr	rempath
	move.l	temp5(a5),d1
	bsr	CurrentDir
	move.l	d0,a3		a3 holds current dir
	move.l	a2,d1
	bsr	OpenNewfile	open output file
	move.l	d0,d5		d5=output file handle
	beq	perr4		already exits/disk full ?
	move.l	a3,d1
	bsr	CurrentDir
	bsr	PerformCopy		Main Stuff !
	bne.s	.C
	cmp.l	fib_Size(a5),d3
	beq.s	.B
	lea	wrongsize(pc),a1	wrong size
	bsr	pr_string
	move.l	d3,d0
	bsr	print10
	bsr	pr_lf
	bra.s	.A
.B	lea	copyOK(pc),a1		all OK
	bsr	pr_string
.A	moveq	#RETURN_OK,d0
.C	rts

PerformCopy		;dest. filename in a2, d4,d5:filehandles
	moveq	#-1,d3
PerformCopy1
	move.l	d6,-(sp)
	move.l	d3,d6		d6 holds maximum filesize
.A	move.l	d4,d1
	move.l	temp6(a5),d2
	move.l	copysize(a5),d3
	cmp.l	d3,d6
	bhi.s	.E
	move.l	d6,d3
.E	jsr	_LVORead(a6)	read a block
	move.l	d0,d3
	bmi	perr2		read error ?
	beq.s	recoend
	move.l	d5,d1
	move.l	temp6(a5),d2
	jsr	_LVOWrite(a6)	write as much as read
	tst.l	d0
	bmi	perr2		disk full ?
	cmp.l	d0,d3
	bne	perr2		disk full ?
	cmp.l	copysize(a5),d3
	bne.s	.B		buffer not filled by Read
	lea	dot(pc),a1
	bsr	pr_string	print dots as progress-indicator
.B	sub.l	d0,d6		sum up size in d6
	beq.s	recoend
	bsr	check_c		check for CTRL-C break
	beq.s	.A
recoend	addq.l	#1,d6
	neg.l	d6		calculate real filesize
	move.l	d6,d3
	move.l	(sp)+,d6
	bsr	closett
adjust	tst.l	devproc(a5)
	beq.s	.A
	move.l	temp5(a5),d1
	bsr	CurrentDir
	move.l	d0,a3
	move.l	a2,d1
	move.l	fib_Protection(a5),d2
	jsr	_LVOSetProtection(a6)	set old protection
;	tst.l	d0
;	beq	perr4
.D	move.l	a2,d1
	lea	fib_Comment(a5),a0	copy comment
	move.l	a0,d2
	jsr	_LVOSetComment(a6)
;	tst.l	d0
;	beq	perr4
.C	bsr	clearArgs		set old date
	lea	fib_Date(a5),a0
	move.l	a0,myArg4(a5)
	move.l	devproc(a5),packettask(a5)
	move.l	temp5(a5),myArg2(a5)
	lea	NewPrintBuffer(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,NewPrintBuffer(a5)
	moveq	#ACTION_SET_DATE,d0
	move.l	d0,packettype(A5)
	bsr	sendpacket
;	beq	perr4
	move.l	a3,d1
	bsr	CurrentDir
.A	moveq	#RETURN_OK,d0
	rts

perr4	move.l	a3,d1
	bsr	CurrentDir
	bra.s	perr3

perr2	move.l	(sp)+,d6
perr3	bsr	closett
	jsr	_LVOIoErr(a6)
	cmp.l	#221,d0			disk full ?
	bne.s	.A
	tst.l	devproc(a5)		is dest. filename in a2 ?
	beq.s	.C
	move.l	d0,-(sp)
	move.l	temp5(a5),d1
	bsr	CurrentDir
	move.l	d0,a3
	move.l	a2,d1
	jsr	_LVODeleteFile(a6)	delete incomlete file
	move.l	a3,d1
	bsr	CurrentDir
	move.l	(sp)+,d0
.C	move.b	#1,break_flag(a5)	break if disk is full
.A	bsr	pr_lf
	bsr	pr_DOSerr
	moveq	#RETURN_ERROR,d0
	rts

closett	move.l	thistask(a5),a0	close files in d4 & d5
	move.l	pr_Result2(a0),-(sp)
	move.l	d4,d1
	beq.s	.A
	btst	#DLsplit,d6	split: do not close infile
	bne.s	.A
	jsr	_LVOClose(a6)
	moveq	#0,d4
.A	move.l	d5,d1
	beq.s	.B
	btst	#DLjoin,d6	join: do not close outfile
	bne.s	.B
	jsr	_LVOClose(a6)
	moveq	#0,d5
.B	move.l	thistask(a5),a0
	move.l	(sp)+,pr_Result2(a0)
	rts



*************************************************************
* read a file to memory
* ENTRY A0=name
* EXIT  D0=address, D1=size
readfile	movem.l	d2-d7/a0-a4,-(sp)
	move.l	a0,d1
	move.l	a0,a4
	bsr	OpenOldfile	try to open it in current dir
	move.l	d0,d4		d4=filehandle
	bne.s	.A
	bsr	RequestersOff
	lea	paths(pc),a0
	move.l	a4,a1
	lea	tempbuf(a5),a2
	bsr	addpath
	move.l	a2,d1
	bsr	OpenOldfile	try to open it in S: dir
	move.l	d0,d4
	beq	reader
	bsr	RequestersOn

.A	move.l	d4,d7		d7=filehandle to close
	bsr	tryseek
	beq	reader4
	bmi	reader2
	bsr	readdata		open succeded
	move.l	d4,d1
	jsr	_LVOClose(a6)	close it
readfileend
	move.l	d6,d0
	move.l	d5,d1
	movem.l	(sp)+,d2-d7/a0-a4
	rts

* read things from stdin to memory
* EXIT  D0=address, D1=size
readstdin	movem.l	d2-d7/a0-a4,-(sp)
	move.l	inhandle(a5),d4
	moveq	#0,d7		do not close filehandle
	bsr	tryseek
	bmi	reader
	beq.s	.A
	bsr	readdata
	bra.s	readfileend
.A	moveq	#0,d5
	moveq	#0,d6
	sub.l	a2,a2
	sub.l	a3,a3
.loop	move.l	#$00010004,d0
	bsr	iwantmem
	beq	readster
	move.l	a3,d1
	bne.s	.C
	move.l	d0,a3
	move.l	d0,a2
	bra.s	.B
.C	move.l	d0,(a2)
	move.l	d0,a2
.B	clr.l	(a2)
	move.l	a2,d2
	addq.l	#4,d2
	moveq	#1,d3
	swap	d3
.D	move.l	d4,d1
	jsr	_LVORead(a6)
	tst.l	d0
	bmi	readster
	beq.s	.E
	add.l	d0,d2
	sub.l	d0,d3
	bne.s	.D
	add.l	#$00010000,d5
	bra.s	.loop
.E	sub.l	a2,d2
	subq.l	#4,d2
	add.l	d2,d5
	move.l	d5,d0
	bsr	iwantmem
	move.l	d0,d6	d6=addr
	beq	readster
	move.l	d6,a2
	move.l	d5,d2
	swap	d2
	move.l	4.w,a6
	bra.s	.F
.G	move.l	a3,a0
	addq.l	#4,a0
	move.l	a2,a1
	moveq	#1,d0
	swap	d0
	add.l	d0,a2
	jsr	_LVOCopyMem(a6)
	move.l	a3,a1
	move.l	(a3),a3
	move.l	#$00010004,d0
	jsr	_LVOFreeMem(a6)
.F	dbra	d2,.G
	moveq	#0,d0
	move.w	d5,d0
	move.l	a3,a0
	addq.l	#4,a0
	move.l	a2,a1
	jsr	_LVOCopyMem(a6)
	move.l	a3,a1
	move.l	#$00010004,d0
	jsr	_LVOFreeMem(a6)
	move.l	dosbase(a5),a6
	bra	readfileend

readster
	tst.l	d6
	beq.s	.A
	move.l	d6,a1
	move.l	d5,d0
	bsr	givemem
.A	move.l	a3,d0
	beq	reader
	move.l	a3,a1
	move.l	(a3),a3
	move.l	#$00010004,d0
	bsr	givemem
	bra.s	.A
	
* read the contents of a file to memory
* ENTRY: d4=filehandle
* EXIT:  d5=size, d6=address of memory block
tryseek	moveq	#1,d3
	moveq	#0,d2
	move.l	d4,d1
	jsr	_LVOSeek(a6)
	tst.l	d0
	bmi.s	reader2
	moveq	#-1,d3
	moveq	#0,d2
	move.l	d4,d1
	jsr	_LVOSeek(a6)
	move.l	#-148,d1
	move.l	d0,d5	d5=size, handles also powerpacked files
	rts
readdata
	bsr	iwantmem
	move.l	d0,d6	d6=addr
	beq	reader2
	move.l	d6,d2
	move.l	d5,d3
	move.l	d4,d1
	jsr	_LVORead(a6)	READ IT
	tst.l	d0
	bmi	reader3
	rts

reader4	move.l	d1,-(sp)
	bra.s	reade22
reader3	move.l	d6,a1
	move.l	d5,d0
	bsr	givemem
reader2	move.l	thistask(a5),a0
	move.l	pr_Result2(a0),-(sp)
reade22	move.l	d7,d1
	beq.s	.A
	jsr	_LVOClose(a6)
.A	move.l	thistask(a5),a0
	move.l	(sp)+,pr_Result2(a0)
reader	bsr	RequestersOn
	bra	DOSerr

*****************
*	MORE	*
*****************
morez	lea	parm2(a5),a0
	tst.b	redirect_in(a5)
	bne.s	.A
	move.l	(a0),d2
	beq	too_less_args
	addq.l	#4,a0
.A	moveq	#0,d4
	move.l	(a0),d0
	beq	.C
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	tst.w	d0
	beq.s	.C
	move.w	d0,d4

.C	tst.b	redirect_in(a5)
	bne.s	.B
	move.l	d2,a0
	bsr	readfile	read from file
	bra.s	.D
.B	bsr	readstdin	read from inhandle
.D	moveq	#0,d2
ViewMore		;Jump-In to review the buffer
	move.l	d0,-(sp)	push address
	move.l	d1,-(sp)	push size
	move.l	d0,a0
	cmp.l	#$3f3,(a0)
	bne.s	.B
	move.l	#212,d0
	bsr	pr_DOSerr
	bra.s	.A
.B	bsr	make_screen
.A	move.l	(sp)+,d0
	move.l	(sp)+,a1
	bsr	givemem
	moveq	#RETURN_OK,D0
	RTS

make_screen	* more main-routine, also used for help
* Entry: d0=start adress, d1=length, d4=number of lines or 0, d2=lookback
	movem.l	d0-d2,-(sp)
	addq.b	#1,noreview_flag(a5)
	bsr	raw_on
	bsr	ClearMenuStrip
	btst	#FLcutline,Flags+3(a5)
	beq.s	.G
	lea	cutontx(pc),a1
	bsr	pr_string
.G	tst.w	d4
	bne.s	.A
	bsr	GetWinSize
	move.w	d0,d4
.A	movem.l	(sp)+,d0-d2
	move.w	d4,line_count(a5)
	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
	tst.l	d2
	beq.s	mk_screen
	move.l	d6,a4
	bra	look_back
mk_screen
	clr.b	help_flag(a5)
	lea	clrhide(pc),a1
	btst	#FLhide,Flags+2(a5)
	bne.s	.F
	lea	clrtx(pc),a1
.F	bsr	pr_string
	move.w	line_count(a5),d2
	subq.w	#1,d2
	move.l	a4,-(sp)
	moveq	#0,d0
	bra.s	.A
.C	moveq	#1,d0	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	#LF,d0
	bne.s	.B
	dbra	d2,.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
;	bra	waitabit

	move.l	a4,d2
	move.l	outhandle(a5),d1
	beq.s	waitabit
	move.l	d7,d3
	sub.l	a4,d3
	subq.l	#1,d3
	bmi.s	waitabit	don't print if 0
	cmp.l	d7,d6
	bne.s	.D
	cmp.l	a3,d7
	beq.s	.D
	addq.l	#1,d3
.D	jsr	_LVOWrite(a6)

waitabit	
	move.l	stdin(a5),d1
	beq	ExitZShell
	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	morekeys+1(a5),d0		cursor down ?
	beq.s	.G
	cmp.b	#"2",d0
	bne.s	ck_up
.G	cmp.l	d7,d6
	beq	waitabit
	tst.b	help_flag(a5)
	beq.s	.E
	clr.b	help_flag(a5)
	move.l	d7,a1
	subq.l	#1,a1
.F	cmp.l	d5,a1
	beq.s	.A
	cmp.b	#LF,-(a1)
	bne.s	.F
	addq.l	#1,a1
.A	move.l	a1,d7
	bsr.s	D7up
	lea	del2eol(pc),a1
	bsr	pr_string
.E	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	#LF,d0
	bne.s	.B
.C	cmp.l	d6,a3	move a3 down one line too
	beq.s	.D
	move.b	(a3)+,d0
	cmp.b	#LF,d0
	bne.s	.C
.D	bsr.s	D7up
	bra	waitabit

D7up	move.l	a4,-(sp)
	move.l	d7,a4
;	cmp.l	d7,d6
;	beq.s	.A
	moveq	#0,d0
	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	#LF,d0
	bne.s	.A
.E	move.l	a4,d7
	move.l	(sp)+,a4
	rts

ck_up	cmp.b	morekeys+0(a5),d0		V2.0	cursor up ?
	beq.s	.G
	cmp.b	#"8",d0
	bne.s	ck_fwd
.G	cmp.l	d5,a4
	beq	waitabit
	clr.b	help_flag(a5)
	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	#LF,-(a4)
	bne.s	.B
	addq.l	#1,a4
.A	moveq	#0,d0
	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	#LF,-(a3)
	bne.s	.D
	addq.l	#1,a3
.C	move.l	a3,d7
	lea	temp2buf(a5),a1
	move.l	a1,a0
	move.b	#$9b,(a0)+
	move.w	line_count(a5),d0
	bsr	dec2asc
	move.b	#"H",(a0)+
	clr.b	(a0)
	bsr	pr_string	CURSOR some lines down
	bra	waitabit

ck_fwd	cmp.b	morekeys+2(a5),d0	cursor right ?
	beq.s	.A
	cmp.b	#"3",d0
	beq.s	.A
	cmp.b	#" ",d0
	bne.s	ck_top
.A	cmp.l	d7,d6		one page forward
	beq	waitabit
	move.l	a3,a4
	bra	mk_screen
ck_top	cmp.b	morekeys+5(a5),d0	shift cursor up ?
	beq.s	.A
	cmp.b	#"7",d0
	bne.s	ck_bot
.A	cmp.l	d5,a4		start of text
	beq	waitabit
	move.l	d5,a4
	bra	mk_screen
ck_bot	cmp.b	morekeys+4(a5),d0	shift cursor down ?
	beq.s	.A
	cmp.b	#"1",d0
	bne.s	ck_back
.A	cmp.l	a3,d6		end of text
	beq	waitabit
	move.l	d6,a4
	bra.s	look_back
ck_back	cmp.b	morekeys+3(a5),d0	cursor left ?
	beq.s	.A
	cmp.b	#"9",d0
	beq.s	.A
	cmp.b	#8,d0	backspace
	bne.s	ck_nkey
.A	cmp.l	d5,a4		one page back
	beq	waitabit
look_back
	move.w	line_count(a5),d1
mlook2	cmp.l	d5,a4	check against start
	beq.s	.E
	move.b	-(a4),d0
	cmp.b	#LF,d0
	bne.s	mlook2
	dbra	d1,mlook2
	lea	1(a4),a4
.E	bra	mk_screen


ck_nkey	cmp.b	morekeys+8(a5),d0	V2.7	search next string ?
	bne.s	ck_skey
	lea	tempbuf(a5),a1
	bra.s	more_sn

ck_skey	cmp.b	morekeys+7(a5),d0	V2.0	search string ?
	bne.s	ck_jkey
	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	stdin(a5),d1
	beq.s	more_se
	jsr	_LVORead(a6)
	tst.l	d0
	bmi.s	more_se
	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	more_sn
	clr.b	(a2)	no
more_sn	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	#LF,d0
	bne.s	more_se
	move.l	a1,a4	set begin of line on top
	bra.s	more_sx
more_se	bsr	DisplayBeep
more_sx	bsr	raw_on
	bra	mk_screen

ck_jkey	cmp.b	morekeys+9(a5),d0	V2.3	jump to % ?
	bne.s	ck_wkey
	bsr	raw_off
	lea	mjump(pc),a1
	bsr	pr_string
	lea	tempbuf(a5),a2
	move.l	a2,d2
	moveq	#120,d3
	move.l	stdin(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
	cmp.l	a1,a2		just pressed return ?
	beq.s	.A
	clr.b	(a2)	no
	bsr	convert_ASCII_to_num
	beq.s	.A
	moveq	#100,d1
	cmp.l	d1,d0
	bhi.s	.A
	move.l	d6,d1
	sub.l	d5,d1	calc % of size
	bsr	mult_32x32
	moveq	#100,d1
	bsr	div_32
	move.l	d5,a4
	add.l	d0,a4	new pointer
	bsr	raw_on
	moveq	#0,d1
	bra	mlook2	search begin of line
.A	bsr	raw_on
	bra	mk_screen

ck_wkey	cmp.b	morekeys+10(a5),d0	V2.3	write text to file (or print) ?
	bne.s	ck_hkey
	bsr	raw_off
	lea	mwrite(pc),a1
	bsr	pr_string
	lea	tempbuf(a5),a2
	move.l	a2,d2
	moveq	#120,d3
	move.l	stdin(a5),d1
	beq.s	.C
	jsr	_LVORead(a6)
	move.l	a2,a1
	add.l	d0,a2
	subq.l	#1,a2
	clr.b	(a2)		null-end
	cmp.l	a1,a2		just pressed return ?
	beq.s	.C		yes,quit
	move.l	a1,d1
	bsr	OpenNewfile
	move.l	d0,d4
	beq.s	.C
	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)
.C	bsr	raw_on
	bra	mk_screen

ck_hkey	cmp.b	morekeys+12(a5),d0	V2.3	help info ?
	beq.s	.A
	cmp.b	#$3f,d0		help key ?
	bne.s	ck_rkey
.A	move.l	d6,d2
	sub.l	d5,d2
	move.l	d2,-(sp)
	move.l	a4,d0
	sub.l	d5,d0
	moveq	#100,d1
	bsr	mult_32x32
	move.l	d2,d1
	bsr	div_32
	move.w	d0,-(sp)
	move.l	sp,a1
	lea	helpmor(pc),a0
	bsr	new_print
	addq.l	#6,sp
	addq.b	#1,help_flag(a5)
	bra	waitabit

ck_rkey	cmp.b	morekeys+11(a5),d0	V2.3	resized window ?
	bne.s	unknown_key
	bsr	GetWinSize
	move.w	d0,line_count(a5)
	bra	mk_screen

unknown_key
	cmp.b	morekeys+6(a5),d0	quit more ?
	beq.s	.A
	cmp.b	#27,d0		ESC key ?
	bne	waitabit
.A	btst	#FLcutline,Flags+3(a5)	unknown key to exit !
	beq.s	.G
	lea	cutofftx(pc),a1
	bsr	pr_string
.G	bsr	SetMenuStrip
	bsr	pr_lf
	bsr	do_show_cursor
	bsr	raw_off
	subq.b	#1,noreview_flag(a5)
	moveq	#RETURN_OK,d0
	rts

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

** PRINT STRING AT A4 ENDING IN LF
pr_line	movem.l	d0-d4/a0,-(sp)
	move.l	d0,d4
	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
	tst.l	d4
	beq.s	.A
	subq.l	#1,d2
	addq.l	#1,d3
.A	tst.l	d3
	beq.s	.C	don't print if 0
	jsr	_LVOWrite(a6)
.C	movem.l	(sp)+,d0-d4/a0
	rts

*****************
*	TYPE	*		Type out ASCII file command	
*****************
typez	bsr	pr_hide_cursor
	tst.b	redirect_in(a5)
	beq.s	.C
	bsr	readstdin	read from inhandle
	bra.s	.D
.C	move.l	parm2(a5),d0
	beq	too_less_args
	move.l	d0,a0
	bsr	readfile	read from file
.D	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

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

***********************
* EXECUTE SCRIPT FILE *
***********************
executez	;execute AmigaDOS script
	move.l	parm2(a5),d0
	beq	too_less_args
	move.l	d0,a0
	lea	ZShellName(pc),a1
	bsr	CheckOpt	look for ZSHELL option
	beq.s	execzsh
	lea	tempbuf(a5),a0
	move.l	a0,d1
	lea	exectx+1(pc),a1
.A	move.b	(a1)+,(a0)+	"execute"
	bne.s	.A
	move.b	#" ",-1(a0)	space
	lea	CLIbuf(a5),a1
.B	move.b	(a1)+,(a0)+	filename & args
	bne.s	.B
	move.b	#LF,-1(a0)	linefeed
	lea	endcltx+1(pc),a1
.D	move.b	(a1)+,(a0)+	"endcli"
	bne.s	.D
	move.l	thistask(a5),a1
	move.l	pr_CIS(a1),d2
	move.l	pr_COS(a1),d3
	jsr	_LVOExecute(a6)	execute AmigaDOS script
	moveq	#RETURN_OK,d0
	rts

execzsh	tst.b	redirect_in(a5)
	beq.s	.C
	bsr	readstdin	read from inhandle
	bra.s	xz4
.C	move.l	parm3(a5),d0
	beq	too_less_args
	move.l	d0,a0		read from file
* Execute ZShell script
xz2	bsr	readfile	A0 pts to filename
xz4	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.l	mult_comm_ptr(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	CLIbuf(a5),a0
	move.l	parm1(a5),d0
	beq.s	.A
	move.l	d0,a1
.B	move.b	(a1)+,(a0)+	copy rexx-file to CLIbuf
	bne.s	.B
.A	lea	rexxtx(pc),a1
	move.l	a1,parm1(a5)
	bra	notfound	execute archie3

*****************
*	ECHO	*
*****************
echoz	lea	parm2(a5),a3
	move.l	(a3)+,d0
	beq.s	.B
	bra.s	.D
.A	move.l	(a3)+,d0
	bne.s	.C
.B	moveq	#RETURN_OK,d0
	rts
.C	bsr	pr_space
.D	bsr	parse_echo
	bsr	pr_string
	bra	.A

parse_echo		;parse string in d0 in place
	move.l	a2,-(sp)
	move.l	d0,a0
	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
	beq.s	.A
	bra.s	.B
.D	cmp.b	#'^',d0		^-Character
	bne.s	.B
	move.b	(a0)+,d0
	beq.s	.A
	cmp.b	#"*",d0
	bne.s	.G
	move.b	#$9b,d0
	bra.s	.B
.G	cmp.b	#"$",d0		Number given ?
	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)+
	move.l	(sp)+,a2
	rts

*****************
*	CLS	*
*****************
clsz	lea	clstx(pc),a1
	bsr	pr_string
	moveq	#RETURN_OK,d0
	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
	bsr	FreeFNC
	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

** MEM INFO :RETURN 3 LONGWORDS AT A0 -> FREE CHIP,FAST,TOTAL
memory_info
	movem.l	a0-a2/a6,-(sp)
	move.l	a0,a2
	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,(a2)
	move.l	#MEMF_FAST,d1	; check fast mem avail
	jsr	_LVOAvailMem(a6)
	move.l	d0,4(a2)
	move.l	#MEMF_PUBLIC,d1 	; get all available memory
	jsr	_LVOAvailMem(a6)
	move.l	d0,8(a2)
	jsr	_LVOPermit(a6)
	movem.l	(sp)+,a0-a2/a6
	rts

*************************
*	RELABEL 	*
*************************
relabelz	tst.l	parm3(a5)
	beq	too_less_args
	move.l	parm2(a5),a0
	bsr	check_for_colon
	bne	no_col
.D	move.l	parm2(a5),d1	PARM2=DF0: etc
	jsr	_LVODeviceProc(a6)
	tst.l	d0
	beq	DOSerr
	move.l	d0,packettask(a5)
	lea	tempbuf(a5),a2	A2=destination
	move.l	a2,d0
	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
	bsr	PKTerr
	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
	cmp.w	#36,kickver(a5)
	blo.s	.A
	move.l	parm2(a5),d3
	beq	too_less_args
	move.l	parm3(a5),d0
	beq.s	.B
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
.B	move.l	d3,d1
	move.l	d0,d2
	jsr	_LVOAddBuffers(a6)
	tst.l	d0
	beq	DOSerr
	moveq	#-1,d1
	cmp.l	d1,d0
	bne.s	.C
	jsr	_LVOIoErr(a6)
.C	move.l	d0,-(sp)
	move.l	d3,-(sp)
	lea	(sp),a1
	lea	addbufftx(pc),a0
	bsr	new_print
	addq.l	#8,sp
	bra.s	.D

.A	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
.D	moveq	#RETURN_OK,d0
	rts

*************************
*	KILL	*
*************************
killz	move.l	parm2(a5),d1
	beq	too_less_args
	move.l	d1,a0
	bsr	check_for_colon
	bne.s	.A
	bsr	clearArgs	kill filesystemhandler
	jsr	_LVODeviceProc(a6)	PARM2=DF0: etc
	tst.l	d0
	beq	DOSerr
	move.l	d0,packettask(a5)
	moveq	#ACTION_DIE,d0
	move.l	d0,packettype(A5)
	bsr	sendpacket
	bsr	PKTerr
.B	moveq	#RETURN_OK,d0
	rts

.A	move.l	d1,a2		kill task or cli-process
	bsr	findtsk
	beq.s	.B
	move.l	a0,a2
	move.l	pr_CIS(a2),d1
	beq.s	.C
	jsr	_LVOClose(a6)
.C	move.l	pr_COS(a2),d1
	beq.s	.D
	jsr	_LVOClose(a6)
	moveq	#25,d1
	jsr	_LVODelay(a6)
.D	move.l	4.w,a6
	jsr	_LVOForbid(a6)
	move.l	a2,a1
	jsr	_LVORemTask(a6)
	jsr	_LVOPermit(a6)
	move.l	dosbase(a5),a6
	bra.s	.B

*************************
*	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
	bsr	fibexam2
	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	move.l	parm3(a5),a0
	moveq	#-1,d7
	bsr	CheckOnOff
	bne.s	.B
	moveq	#0,d7
.B	move.l	parm2(a5),d1	PARM2=DF0: etc
	beq	too_less_args
	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

*************************
*	ALIAS		*	V2.9 uses Pool
*************************
;LONG	alias_link
;STRING	alias_name
;STRING	alias_defn

aliasz	move.l	parm2(a5),d0
	beq	show_current_aliases
	tst.l	parm3(a5)
	beq	too_less_args
	move.l	d0,a0		A0=parm2
	bsr	check_if_alias_exits	update old alias ?
	beq	create_new_alias
	move.l	d0,a1		first delete old one
	move.l	(a1),d2		grab next alias pointer
	move.l	d1,a0		D1=prior alias
	move.l	d2,(a0)		skip over alias to delete
	move.l	parm2(a5),a0	 and replace with new alias

create_new_alias	;a0=name
	lea	tempbuf(a5),a3	create alias in tempbuf first
	move.l	a0,a1
.A	move.b	(a1)+,(a3)+	copy alias name
	bne.s	.A
	lea	CLIbuf(a5),a2	use CLIbuf, end in a1
	sub.l	CLIbufstart(a5),a2
	add.l	parm3(a5),a2
	cmp.b	#$22,-1(a2)
	bne.s	.D
	move.l	a2,a1
.E	move.b	(a1)+,d1
	beq.s	.D
	cmp.b	#$22,d1
	bne.s	.E
	clr.b	-1(a1)
.D	move.l	a2,a1
.F	move.b	(a1)+,(a3)+	copy alias definition
	bne.s	.F
	lea	tempbuf(a5),a2
;alias in A2, A3 points to end
copy_new_alias
	lea	alias_pool(a5),a1
	move.l	a3,d0
	sub.l	a2,d0
	addq.l	#4,d0		for link
	bsr	AutoAllocPooled
	beq.s	.I
	move.l	d0,a0
	clr.l	(a0)+		clear link
.G	move.b	(a2)+,(a0)+	copy tempbuf to real alias position
	cmp.l	a3,a2
	blo.s	.G
	lea	first_alias(a5),a0
	move.l	a0,d1
.H	move.l	d1,a0
	move.l	(a0),d1		look for end of list
	bne.s	.H
	move.l	d0,(a0)		a0=last alias points to d0=new alias
	moveq	#RETURN_OK,d0
	rts
.I	moveq	#RETURN_ERROR,d0
	rts

check_if_alias_exits
	move.l	a0,-(sp)	A0=alias name
	lea	temp2buf(a5),a1
	bsr	cp_string
	bsr	search_alias
	move.l	(sp)+,a0
	rts

show_current_aliases
	bsr	pr_hide_cursor
	lea	first_alias(a5),a2
.C	move.l	(a2),d0
	beq.s	.A
	move.l	d0,a2		walk through list
	lea	4(a2),a1	alias name
	move.l	a1,a0
.D	tst.b	(a0)+		look for alias definition
	bne.s	.D
	bsr	pr_string
	bsr	pr_tab
	move.l	a0,a1
	bsr	pr_stringlf
	bra.s	.C
.A	moveq	#RETURN_OK,d0
	rts

*************************
*	UNALIAS		*	V2.9 uses Pool
*************************
;NOTE: unsetting single aliases does not free memory
unaliasz
	lea	parm2(a5),a3
	move.l	(a3)+,d0
	beq	deallocate_aliases
.A	move.l	d0,a0
	bsr	check_if_alias_exits
	beq.s	.C
	move.l	d0,a1
	move.l	(a1),d2	grab next alias pointer
	move.l	d1,a0	D1=prior alias
	move.l	d2,(a0)	skip over alias to delete
	move.l	(a3)+,d0 and replace with new alias
	bne.s	.A
	moveq	#RETURN_OK,d0
	rts

.C	lea	temp2buf(a5),a2
pr_notfound	;string in a2
	move.l	a2,a1
	bsr	pr_string
	lea	notfund(pc),a1
	bsr	pr_stringlf
	moveq	#RETURN_ERROR,d0
	rts

deallocate_aliases
	clr.l	first_alias(a5)
	lea	alias_pool(a5),a1
	bsr	DeletePool
	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
	move.l	a3,-(sp)
	bsr	spaths2		SEARCH PATHS FOR THE COMMAND
	move.l	(sp)+,a3
	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
	move.l	#205,d0
	bra.s	resi_error
resi_no_mem
	moveq	#103,d0
	bra.s	resi_error
resi_inuse
	move.l	#202,d0
resi_error
	move.l	dosbase(a5),a6
	bra	pr_galactic

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
	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
	bsr	pr_hide_cursor
	lea	residetx(pc),a1
	bsr	pr_stringlf
	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


*********************************
*	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
	move.l	d1,a1
	tst.b	1(a1)
	bne	not_peek32
	lea	8(sp),a0
	cmp.l	a0,d5
	blo	not_poke32

	cmp.b	#'+',(a1)		+	ADD
	bne.s	not_add
	move.l	(sp)+,d0
	add.l	d0,(sp)
	bra.s	rpn_loop1
not_add	cmp.b	#'-',(a1)		-	SUBTRACT
	bne.s	not_sub
	move.l	(sp)+,d0
	sub.l	d0,(sp)
	bra.s	rpn_loop1

not_sub	cmp.b	#'*',(a1)		*	MULTIPLY
	bne.s	not_mult
	move.l	(sp)+,d0	last
	move.l	(sp)+,d1	2nd last
	bsr	mult_32x32
	move.l	d0,-(sp)
	bra.s	rpn_loop1
not_mult	cmp.b	#'/',(a1)	/	DIVIDE
	bne.s	not_div
	move.l	(sp)+,d1	last
	move.l	(sp)+,d0	2nd last
	tst.l	d1
	beq.s	rpn_error	no divide by zero
	bsr	div_32
	move.l	d0,-(sp)
	bra.s	rpn_loop1

not_div	cmp.b	#'&',(a1)		&	AND
	bne.s	not_and
	move.l	(sp)+,d0
	and.l	d0,(sp)
rpn_lp1	bra.s	rpn_loop1
not_and	cmp.b	#"!",(a1)		!	OR
	bne.s	not_or
	move.l	(sp)+,d0
	or.l	d0,(sp)
	bra.s	rpn_lp1
not_or	cmp.b	#'=',(a1)		=	POKE
	bne.s	not_poke32
	move.l	(sp)+,d1	get value
	move.l	(sp)+,d0	get addr
	and.b	#$fe,d0
	move.l	d0,a0
	move.l	(a0),-(sp)	peek it
	move.l	d1,(a0)		poke it
	bra.s	rpn_lp1
not_poke32
	cmp.b	#'?',(a1)		?	PEEK
	bne.s	not_peek32
	move.l	(sp)+,d0	get addr
	cmp.l	sp,d5
	blo.s	rpn_error
	and.b	#$fe,d0
	move.l	d0,a0
	move.l	(a0),-(sp)
	bra.s	rpn_lp1

not_peek32
	bsr	convert_ASCII_to_num
	beq.s	rpn_error2
	move.l	d0,-(sp)
	bra.s	rpn_lp1
rpn_error2
	moveq	#115,d0
	bra.s	rpn_error1
rpn_error
	moveq	#-119,d0
rpn_error1
	move.l	d5,sp
	bsr	pr_DOSerr
	moveq	#RETURN_ERROR,d0
	rts

show_rpn_result
	lea	4(sp),a0
	cmp.l	a0,d5
	bne	rpn_error
	move.l	(sp),-(sp)		have result twice
	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	move.l	sp,a1
	lea	rpn_result_tx(pc),a0	print hex & dec
	tst.b	redirect_out(a5)	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)	;d0=d0/d1
	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
	dbra	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	#LF,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	#8,d7

	move.l	parm2(a5),d0
	beq.s	show_mempage
	move.l	d0,a1
	bsr	convert_ASCII_to_num	convert 1st num
	beq.s	.A
	move.l	d0,mem_addr(a5)

	move.l	parm3(a5),d0
	beq.s	show_mempage
	move.l	d0,a1
	bsr	convert_ASCII_to_num	convert 2nd num
.A	beq	bad_number_error
	move.l	d0,d7			D7=2nd num
	sub.l	mem_addr(a5),d7
	lsr.l	#4,d7
	addq.l	#1,d7

show_mempage
	and.b	#$fe,mem_addr+3(a5)	MAKE SURE EVEN ADDRESS
shmem2	bsr	check_c
	bne	.A
	bsr	show_16_locs
	subq.l	#1,d7		D7=count
	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

** SAVE STATS store current time in date mark, and current memory use in mem mark
save_mem_time
	movem.l	d0-d1/a0-a1,-(sp)
	clr.l	temp2(a5)
	btst	#FLcheck,Flags+3(a5)
	beq.s	.C
	move.l	4.w,a0
	tst.w	296(a0)		CPU better than 68000 ?
	bne.s	.A
	move.l	#1024,d0	no, store lower memory
	bsr	iwantmem
	move.l	d0,temp2(a5)
	beq.s	.A
	move.l	d0,a1
	sub.l	a0,a0		adress 0 to 1023
	move.l	#$C0DEDBAD,(a0)	Mungwall does the same
	move.l	#1024/4-1,d0
.B	move.l	(a0)+,(a1)+
	dbra	d0,.B
.A	lea	mem_mark(a5),a0
	bsr	memory_info	remember memory usage
.C	lea	date_mark(a5),a0
	bsr	get_time	remember this time
	movem.l	(sp)+,d0-d1/a0-a1
	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
	lea	-34(sp),sp
	lea	(sp),a0		A0=time area
	move.l	Result2(a5),(a0)+	-4(a0) ioerr-result
	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
	move.l	temp2(a5),d0	check low memory
	beq.s	.A
	move.l	d0,a1		show changes of low memory
	sub.l	a0,a0
	move.l	#1024/4-1,d0
.B	move.l	(a0)+,d1
	cmp.l	(a1)+,d1
	beq.s	.C
	movem.l	a0-a1,-(sp)
	move.l	-4(a0),-(sp)
	move.l	-4(a1),-(sp)
	move.l	a0,-(sp)
	subq.l	#4,(sp)
	move.l	sp,a1
	lea	lowmemtx(pc),a0	print the changes
	bsr	new_print
	lea	12(sp),sp
	movem.l	(sp)+,a0-a1
.C	dbra	d0,.B
	move.l	temp2(a5),a1
	move.l	#1024,d0
	bsr	givemem
.A	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

*************************
*	STACK		*
*************************
stackz	move.l	CLIptr(a5),a4
	move.l	cli_DefaultStack(a4),d7
	lsl.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
	bsr	iwantmem 
	beq.s	stoobig   
	move.l	d0,a1   
	move.l	d6,d0   
	bsr	givemem  
	
	lsr.l	#2,d6
	move.l	d6,cli_DefaultStack(a4)
	moveq	#RETURN_OK,d0
	rts
stoosmall
	move.l	#-148,d0
	bra	pr_galactic
stoobig
	bra	resi_no_mem
show_stack
	move.l	d7,-(sp)
	move.l	#-146,d0
	bsr	GetMessage
	lea	(sp),a1
	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	cmp.w	#36,kickver(a5)
	blo	assi13
	tst.l	parm2(a5)
	beq	assi13
	move.l	parm3(a5),d2
	beq	too_less_args
	move.l	parm2(a5),a2
	lea	assignuse(pc),a1
	move.l	d2,a0
	bsr	CheckOpt
	beq	assi13
	move.l	a2,a0
	bsr	check_for_colon
	bne.s	.G
	clr.b	-2(a0)	no colon-end

.G	move.l	parm4(a5),d0
	bne.s	.B
	move.l	d2,a0
	bsr	CheckOpt
	beq.s	.C
	move.l	d2,d1		Assign LOCK
	moveq	#-2,d2
	jsr	_LVOLock(a6)
	move.l	d0,d7
	move.l	d0,d2
	beq	DOSerr
	move.l	a2,d1
	jsr	_LVOAssignLock(a6)
	tst.l	d0
	beq	DOSerrUL
	bra	.A
.C	move.l	a2,d1		Assign REMOVE
	moveq	#0,d2
	jsr	_LVOAssignLock(a6)
	tst.l	d0
	beq	DOSerr
	bra.s	.A

.B	move.l	d0,a0
	bsr	CheckOpt
	bne.s	.H
	move.l	d2,d1		Assign REMOVE part
	moveq	#-2,d2
	jsr	_LVOLock(a6)
	move.l	d0,d7
	move.l	d0,d2
	beq	DOSerr
	move.l	a2,d1
	jsr	_LVORemAssignList(a6)
	tst.l	d0
	beq	DOSerrUL
	bra.s	.A
.H	bsr	CheckOpt
	bne.s	.D
	move.l	d2,d1		Assign ADD
	moveq	#-2,d2
	jsr	_LVOLock(a6)
	move.l	d0,d7
	move.l	d0,d2
	beq	DOSerr
	move.l	a2,d1
	jsr	_LVOAssignAdd(a6)
	tst.l	d0
	beq	DOSerrUL
	bra.s	.A
.D	bsr	CheckOpt
	bne.s	.E
	move.l	a2,d1		Assign PATH
	jsr	_LVOAssignPath(a6)
	tst.l	d0
	beq	DOSerr
	bra.s	.A
.E	bsr	CheckOpt
	bne.s	.F
	move.l	a2,d1		Assign DEFER
	jsr	_LVOAssignLate(a6)
	tst.l	d0
	beq	DOSerr
	bra.s	.A
.F	lea	assignuse(pc),a1
	bsr	pr_stringlf
.A	moveq	#RETURN_OK,d0
	rts

assi13	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	assiexists
	bsr	do_permit
no_col	move.l	#210,d0
	bra	pr_galactic

assiexists:		;V2.9c: TEST ASSIGN EXISTS (Mark J. Swift)
        move.l  parm3(a5),a0
        lea     exists(pc),a1
        bsr     compare_strings
        bne     assi14

assiexists2:
.B      add.l   a2,a2            FIND NEXT DEVINFO
        add.l   a2,a2            A2 pts to first devinfo structure
        move.l  a2,d0            tst.l   (a2)
        beq.s   .C
        move.l  a2,a0
        move.l  dvi_Name(a2),a1
        move.l  (a2),a2
        add.l   a1,a1
        add.l   a1,a1

        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   .E
        bsr     compD1D0nocase
        beq.s   .A
.D      bra.s   .B

.C      bsr     do_permit
        moveq   #RETURN_WARN,d0
        rts

.E      bsr     do_permit
        moveq   #RETURN_OK,d0
        rts

assi14	moveq	#dlt_directory,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	assi14
	subq.l	#1,d2
	bmi.s	.C
	bsr	compD1D0nocase
	beq.s	.A
.D	bra.s	assi14

.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
	bsr	iwantcleanmem
	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)
	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	#dlt_directory,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)
	lsl.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	#5000,d0
	bsr	iwantmem		allocate big block
	beq	asg_fail
	move.l	d0,a4		A4 = string block
	move.l	d0,a3
	add.l	#5000,a3	A3 = end of string block
	move.l	d0,4(sp)		4(sp) = string block
	lea	volume_tx(pc),a0	PRINT VOLUMES:
	bsr	copy_name
	moveq	#dlt_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_devices1
	bsr	copy_bstr
	move.b	#$20,(a4)+	seperate with spaces
	tst.l	dvi_Task(a0)
	bne.s	.H
	lea	unmounted_tx(pc),a0
	bsr	copy_name
	bra.s	.A
.H	move.b	#"[",(a4)+
	lea	mounted_tx(pc),a0
	bsr	copy_name
.A	move.b	#LF,(a4)+
	bra.s	.E
do_devices1
	move.l	(sp),a2		restart at first devinfo
	lea	device1_tx(pc),a0	PRINT DEVICES:
	bsr	copy_name
	lea	device3_tx(pc),a0
	bsr	copy_name
.B	moveq	#dlt_device,d1
	bsr	find_next_assign	COPY ALL DEVICES THAT MATCH TYPE IN D1
	tst.l	d0		 TO THE BIG STRING
	bne.s	.A
	tst.l	dvi_Task(a0)
	bne.s	.B
	bsr	copy_bstr
	move.b	#$20,(a4)+	seperate with spaces
	move.b	#$20,(a4)+
	bra.s	.B
.A	move.b	#LF,(a4)+	linefeed at end
do_devices2
	move.l	(sp),a2		restart at first devinfo
	lea	device1_tx(pc),a0	PRINT DEVICES:
	bsr	copy_name
	lea	device2_tx(pc),a0
	bsr	copy_name
.B	moveq	#dlt_device,d1
	bsr	find_next_assign	COPY ALL DEVICES THAT MATCH TYPE IN D1
	tst.l	d0		 TO THE BIG STRING
	bne.s	.A
	tst.l	dvi_Task(a0)
	beq.s	.B
	bsr	copy_bstr
	move.b	#$20,(a4)+	seperate with spaces
	move.b	#$20,(a4)+
	bra.s	.B
.A	move.b	#LF,(a4)+	linefeed at end
do_late
	move.l	(sp),a2
	lea	assign_tx(pc),a0	PRINT DIRECTORIES
	bsr	copy_name
	moveq	#dlt_late,d1
.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	#":",(a4)+
	move.b	#9,(a4)+	seperate with tab
	move.b	#"<",(a4)+
	move.l	dvi_Handler(a0),a0
	bsr	copy_name
	move.b	#">",(a4)+
	move.b	#LF,(a4)+	linefeed at end
	bra.s	.B
.A	move.l	(sp),a2
do_nonbind
	moveq	#dlt_nonbind,d1
.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	#":",(a4)+
	move.b	#9,(a4)+	seperate with tab
	move.b	#"[",(a4)+
	move.l	dvi_Handler(a0),a0
	bsr	copy_name
	move.b	#"]",(a4)+
	move.b	#LF,(a4)+	linefeed at end
	bra.s	.B
.A	move.l	(sp),a2
do_dirs		;uses top of big mem block (end in a3)
	move.w	#-1,-(a3)	push negative
.G	moveq	#dlt_directory,d1
	bsr	find_next_assign	COPY ALL DEVICES THAT MATCH TYPE IN D1
	tst.l	d0		 TO THE BIG STRING
	bne.s	.E
	clr.l	-(a3)		null-end locks
	cmp.w	#36,kickver(a5)
	blo.s	.A		OS1.3-: no assign add
	move.l	dvi_LockList(a0),d0	search locklist (assign add)
	beq.s	.A
.B	move.l	d0,a1
	move.l	4(a1),-(a3)	push locks
	move.l	(a1),d0
	bne.s	.B
.A	move.l	d2,-(a3)	push main lock
	clr.b	-(a3)		null-end name
	move.l	dvi_Name(a0),a1
	add.l	a1,a1
	add.l	a1,a1
	moveq	#0,d0
	move.b	(a1),d0		name-length
	btst	#0,d0
	bne.s	.C
	clr.b	-(a3)		for word-align
.C	add.l	d0,a1
	addq.l	#1,a1		a3=end of name
	bra.s	.D
.F	move.b	-(a1),-(a3)
.D	dbra	d0,.F
	bra.s	.G

.E	bsr	do_permit
get_nxt_lock
	cmp.b	#$ff,(a3)	check for end
	beq.s	.A
	move.l	a3,a0
	bsr	copy_name	copy assign-name
.B	tst.b	(a3)+		look for end
	bne.s	.B
	move.b	#9,(a4)+	copy tab
	move.l	a3,d0
	addq.l	#1,d0
	and.w	#$fffe,d0	word-align
	move.l	d0,a3
	move.l	(a3)+,d1	first lock
	beq.s	.F
	bra.s	.G
.C	move.l	(a3)+,d1
	beq.s	get_nxt_lock
	move.b	#9,(a4)+	other locks are assign adds
	move.b	#"+",(a4)+
	move.b	#" ",(a4)+
.G	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)	check for mounted
	bne.s	.E
.F	lea	unmounted_tx(pc),a0
	bsr	copy_name
	move.b	#LF,(a4)+
	bra.s	.C
.E	jsr	_LVODupLock(a6)	copy lock(D1) --> (D0)
	tst.l	d0
	beq.s	.F		could not dup lock
	move.l	a4,a0
	move.l	a3,-(sp)
	bsr	eval_full_path	write path to big block
	move.l	(sp)+,a3
	jsr	_LVOUnLock(a6)
.D	tst.b	(a4)+		look for end
	bne.s	.D
	move.b	#LF,-1(a4)	overwrite null or tab
	bra.s	.C
.A	clr.b	(a4)		null-end

	move.l	a4,d6
	subq.l	#1,d6
	move.l	4(sp),a4
	bsr	pr_hide_cursor
	bsr	pr_screen
	move.l	4(sp),a1
	move.l	#5000,d0
	bsr	givemem
	bra.s	asg_fail2
asg_fail	bsr	do_permit
asg_fail2	lea	8(sp),sp
	moveq	#RETURN_OK,d0
	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	moveq	#0,d0
	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

*************************
*	FAILAT 		*
*************************
failatz	move.l	parm2(a5),d0
	beq.s	.A
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	move.l	CLIptr(a5),a0
	move.l	d0,cli_FailLevel(a0)
	bra.s	.B
.A	move.l	#-154,d0
	bsr	GetMessage
	move.l	CLIptr(a5),a1
	lea	cli_FailLevel(a1),a1
	bsr	new_print
.B	moveq	#RETURN_OK,d0
	rts

*************************
*	IF 		*	V2.9c: nested Ifs (Mark J. Swift)
*************************
ifz     cmp.b	#IFSIZE,if_flag(a5)
        bge.s	ifOK
        add.b	#1,if_flag(a5)
        moveq	#0,d0
        move.b	if_flag(a5),d0
        add.w	#if_condition,d0
        move.b	#$ff,0(a5,d0.w)          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.s	.C
.B	lea	exists(pc),a1
	bsr	compare_strings
	bne.s	try_warn	IF NOT AN EXISTS TYPE COMPARE
	move.l	(a4)+,d1
	beq.s	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
        moveq	#0,d0
        move.b	if_flag(a5),d0
        add.w	#if_condition,d0
        move.b	d3,0(a5,d0.w)
ifOK	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.s	try_error
set_error_state
	moveq	#0,d3
	cmp.l	d6,d5
	bne.s	save_state
	not.b	d3
	bra.s	save_state
try_error	lea	error_tx(pc),a1
	bsr	compare_strings
	bne.s	try_fail
	moveq	#RETURN_ERROR,d6
	bra.s	set_error_state
try_fail	lea	fail_tx(pc),a1
	bsr	compare_strings
	bne.s	if_fail
	moveq	#RETURN_FAIL,d6
	bra.s	set_error_state
if_fail	sub.b	#1,if_flag(a5)		sytntax error, so drop current IF
	bra	too_less_args

*************************
*	ASK 		*
*************************
askz	bsr	echoz		print the parm same as echo does
rask	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	a4,a0
	add.l	d0,a0
	subq.l	#1,a0
	clr.b	(a0)	Null-End
	tst.b	redirect_out(a5)	output redirected ?
	beq.s	.C
	move.l	a4,a1
	bsr	pr_string	repeat input
	bra	.A
.C	move.b	(a4),d1
	bset	#5,d1
	moveq	#RETURN_FAIL,d0
	cmp.b	#'f',d1		V2.0
	beq	.B
	moveq	#RETURN_ERROR,d0
	cmp.b	#'e',d1		V2.0
	beq	.B
	moveq	#RETURN_WARN,d0
	cmp.b	#'j',d1		V2.0
	beq	.B
	cmp.b	#'y',d1
	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	#LF,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
	
*************************
*	HTYPE 		*
*************************
htypez	bsr	pr_hide_cursor
	tst.b	redirect_in(a5)
	beq.s	.C
	bsr	readstdin	read from inhandle
	bra.s	.D
.C	move.l	parm2(a5),d0
	beq	too_less_args
	move.l	d0,a0
	bsr	readfile	read from file
.D	move.l	d0,mem_addr(a5)
	move.l	d0,mem_offset_addr(a5)
	move.l	d1,temp1(a5)
	move.l	d1,d2
	add.l	d0,d1
	move.l	d1,d7		end marker
	move.l	parm3(a5),d0
	beq.s	.B
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq.s	.B
	cmp.l	d0,d2
	bls.s	.B
	add.l	d0,mem_addr(a5)
.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
	bsr	pr_hide_cursor
	lea	parm2(a5),a0
	tst.b	redirect_in(a5)
	bne.s	.A
	move.l	(a0),d2
	beq	too_less_args
	addq.l	#4,a0
.A	moveq	#7,d7		7=default number of characters
	move.l	(a0),d0
	beq	.C
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	move.l	d0,d7
.C	tst.b	redirect_in(a5)
	bne.s	.B
	move.l	d2,a0
	bsr	readfile	read from file
	bra.s	.D
.B	bsr	readstdin	read from inhandle
.D	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
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	*		V2.0
*************************
filenotez
	move.l	parm3(a5),d2
	beq	too_less_args
	move.l	parm2(a5),d1
	jsr	_LVOSetComment(a6)
	tst.l	d0
	beq	DOSerr
	moveq	#RETURN_OK,d0
	rts

*************************
*	SEARCH		*	Searches a string in a file
*************************
searchz	lea	parm2(a5),a2		V2.0
	tst.b	redirect_in(a5)
	bne	SearchStdin
	moveq	#0,d6
	bset	#DLsearch,d6	set join flag
	bsr	check_q_r
	clr.l	devproc(a5)
	addq.l	#4,a2
	tst.l	(a2)
	beq	too_less_args	no arg given
	move.l	(a2),temp5(a5)	get string to search for
	clr.l	(a2)		and remove it
	bsr	directory2	DO SEARCH !
	moveq	#RETURN_OK,d0
	rts

SearchFile	;a0=filename, temp5=string to search for
	bsr	pr_lf
	move.l	temp5(a5),d7
	bsr	readfile
	bra	DoSearch

SearchStdin
	move.l	(a2),d7
	beq	too_less_args
	bsr	readstdin	read from inhandle
	bsr	pr_hide_cursor
	
DoSearch
	move.l	d6,-(sp)
	move.l	d1,d5		d5:size of file
	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
	move.l	(sp)+,d6
	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-d4/a3-a6,-(sp)
	move.l	a1,a4
	move.l	chartable(a5),a6
	moveq	#0,d0
	moveq	#0,d1
	moveq	#0,d4
.E	move.b	(a4),d0
	beq.s	.D
	addq.l	#1,d4		count chars to search for
	move.b	0(a6,d0.w),d0
	move.b	d0,(a4)+	uppercase them
	bra.s	.E
.D	move.b	(a1),d0
	cmp.b	dotchar(a5),d0
	bne.s	.C
	move.b	#LF,(a1)	begins with LineFeed
.C	move.l	a3,a5
	move.l	a0,d0		calc length of text
	sub.l	a2,d0
	sub.l	d4,d0
	move.l	d0,d4
	move.l	d4,d3
	swap	d3
	moveq	#0,d0
	moveq	#0,d2
	move.b	(a1),d2
	bra.s	seabeg
seastrt	move.b	(a2)+,d1
	move.b	0(a6,d1.w),d1
	cmp.b	d2,d1		compare first char
	bne.s	seabeg

	lea	1(a1),a3
	move.l	a2,a4
.C	move.b	(a3)+,d0
	beq.s	seafnd
	move.b	(a4)+,d1
	move.b	0(a6,d1.w),d1
	cmp.b	d0,d1		compare other chars
	beq.s	.C

seabeg	dbra	d4,seastrt
	dbra	d3,seastrt
	bra	seaend

seafnd	subq.l	#1,a2
	move.l	a2,a1
.D	cmp.l	a0,a4
	bhi	seaend
	move.b	(a4)+,d1	search end
	beq.s	.G
	cmp.b	#LF,d1
	bne.s	.D
	cmp.b	#LF,(a1)
	beq.s	.H
.F	cmp.l	a5,a1
	bls	.G
	move.b	-(a1),d0
	beq.s	.H
	cmp.b	#LF,d0		search beginning (if LF)
	bne.s	.F
.H	addq.l	#1,a1
.G	move.b	d1,d2
	lea	-1(a4),a0
	move.l	d2,d0
	movem.l	(sp)+,d1-d4/a3-a6
	rts
seaend	moveq	#1,d0
	movem.l	(sp)+,d1-d4/a3-a6
	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
	lea	clk_tx(pc),a2
	move.l	parm2(a5),d0
	beq.s	.A
	move.l	d0,a0
	move.l	a2,a1
	bsr	CheckOpt
	beq	clkload
	lea	8(a2),a1
	bsr	CheckOpt
	beq.s	clksave
.A	move.l	a2,a1
	bsr	pr_stringlf
	moveq	#RETURN_ERROR,d0
	rts
noclk	lea	noclk_tx(pc),a0
	bsr	PrintError
	rts

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	#LF,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	#LF,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		*
*************************
soffs	dc.w	378,336,350,364,322,392,532

showz	bsr	pr_hide_cursor		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
	cmp.b	#"v",d1
	beq	shvec
	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	#$00540061,d0	Task
	cmp.b	#13,LN_TYPE(a2)
	bne.s	.C
	move.l	#$00500072,d0	Process
	cmp.w	#36,kickver(a5)
	blo.s	.C
	tst.l	pr_ExitCode(a2)
	beq.s	.C
	move.l	#$00500021,d0	Process with exit code
.C	move.l	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.b	#13,LN_TYPE(a2)
	bne.s	snocli
	move.l	pr_CLI(a2),d1
	beq.s	snocli
	lsl.l	#2,d1	;cli-process
	move.l	d1,a4
	lea	null(pc),a1
	move.l	a1,-(sp)
	move.l	pr_COS(a2),d1
	cmp.l	cli_StandardOutput(a4),d1
	beq.s	.J
	lea	bigger(pc),a0
	move.l	a0,(sp)
.J	move.l	a1,-(sp)
	move.l	pr_CIS(a2),d1
	cmp.l	cli_StandardInput(a4),d1
	beq.s	.G
	lea	smaller(pc),a0
	move.l	a0,(sp)
.G	move.l	a1,-(sp)
	move.l	cli_CommandName(a4),d1
	beq.s	.H
	lsl.l	#2,d1
	move.l	d1,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	pr_TaskNum(a2),-(sp)
	lea	null(pc),a1
	move.l	a1,-(sp)
	tst.l	cli_Background(a4)	background ?
	beq.s	.I
	lea	backcli(pc),a1
	move.l	a1,(sp)
.I	lea	proform(pc),a0
	lea	(sp),a1
	bsr	new_print		Print CLI-Add
	lea	20(sp),sp
snocli	bsr	pr_lf
	tst.l	(a3)
	bne	prsht	;at least one task
shtok	moveq	#RETURN_OK,D0
	rts

shvec	move.l	4.w,a0
	move.l	eb_KickCheckSum(a0),-(sp)
	move.l	eb_ColdCapture(a0),-(sp)
	move.l	eb_KickTagPtr(a0),-(sp)
	move.l	eb_CoolCapture(a0),-(sp)
	move.l	eb_KickMemPtr(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	lea	6*4(sp),sp	get rid of trash
	rts


*************************
*	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
ckwint	equ	ckcook+40	;Table of all Windows
cknum	equ	ckwint+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),d0
	beq	too_less_args
	move.l	d0,a0
	move.b	(a0),d0
	bset	#5,d0
	cmp.b	#"a",d0	;alarm
	beq	clkalm
	bsr	CheckOnOff
	beq	clkoff

clkon	move.b	#1,memclk_flag(a5)	switch it on
	move.l	4.w,a6
	lea	clktask+1(pc),a1
	jsr	_LVOFindTask(a6)
	move.l	d0,a4
	tst.l	d0
	beq.s	.A	;not already running
	bsr	winclk
.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+1(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	4.w,a6
	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	findwin		check if window already exists,
	tst.w	d1		otherwise move window 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

findwin
	move.l	dosbase(a5),a6
	move.l	windowptr(a5),d0
	beq.s	.B
	lea	ckwint(a4),a0
	move.l	a0,a1
	moveq	#19,d1
.A	cmp.l	(a0)+,d0
	dbeq	d1,.A
.B	rts

clkoff	clr.b	memclk_flag(a5)	switch it off
clkof2	move.l	a4,-(sp)
	move.l	4.w,a6
	lea	clktask+1(pc),a1
	jsr	_LVOFindTask(a6)
	move.l	d0,a4
	tst.l	d0
	beq.s	.A
	bsr	findwin
	tst.w	d1
	bmi.s	.A
	moveq	#0,d0
	move.l	d0,-4(a0)
.A	move.l	(sp)+,a4
	move.l	windowptr(a5),d0
	beq.s	.C
	move.l	d0,a0
	move.l	intuibase(a5),a6
	jsr	_LVORefreshWindowFrame(a6)
.C	move.l	dosbase(a5),a6
	moveq	#RETURN_OK,d0
	rts	

clkalm	move.l	4.w,a6		;set alarm-time
	lea	clktask+1(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	ckwint(a5),a2
	moveq	#0,d5
	moveq	#19,d4
.B	move.l	(a2)+,a0		;check all 20 windows
	move.l	a0,d0
	beq.s	.C
	move.l	46(a0),a1	screen
	move.l	40(a1),d0	font
	move.l	50(a0),a0	rastport
	lea	ckitxt(a5),a1
	move.l	d0,8(a1)
	addq.l	#1,d5
	moveq	#0,d0
	moveq	#1,d1
	move.l	ckint(a5),a6
	jsr	_LVOPrintIText(a6)
.C	dbra	d4,.B
	moveq	#LF,d1
	move.l	ckdos(a5),a6
	jsr	_LVODelay(a6)		;wait 1/5 sec
	tst.l	d5
	bne	.A
	move.l	4.w,a6
	rts


*************************
*	CONFIG		*	V2.0
*************************	set or show configuration
configz	move.l	parm2(a5),d0
	beq	ctrlerr
	move.l	d0,a0
	lea	configuse(pc),a1
ctrlkey	bsr	CheckOpt	keys pressed with CTRL
	bne.s	ctrlmor
	move.l	parm3(a5),d0
	beq.s	.A
	move.l	d0,a0
	lea	ctrl_codes(a5),a1
	moveq	#ctrl_inite-ctrl_init-2,d1
.B	move.b	(a0)+,d0
	beq.s	.D
	and.b	#$3f,d0		set ctrl codes
	move.b	d0,(a1)+
	dbra	d1,.B
	bra.s	.D
.A	lea	ctrl_codes(a5),a0	show ctrl codes
	lea	tempbuf(a5),a1
	move.l	a1,a2
	moveq	#ctrl_inite-ctrl_init-2,d1
.C	move.b	(a0)+,d0
	add.b	#$40,d0
	move.b	d0,(a2)+
	dbra	d1,.C
	clr.b	(a2)
	bsr	pr_stringlf
.D	bra.s	ctrl2

ctrlmor	bsr	CheckOpt	keys pressed in MORE
	bne.s	ctrldot
	move.l	parm3(a5),d0
	beq.s	.A
	bsr	parse_echo
	move.l	parm3(a5),a0
	lea	morekeys(a5),a1
	moveq	#more_inite-more_init-1,d1
.B	move.b	(a0)+,d0
	beq.s	.D
	move.b	d0,(a1)+	set MORE keys
	dbra	d1,.B
	bra.s	.D
.A	lea	morekeys(a5),a1	show more keys
	bsr	pr_stringlf
.D	bra.s	ctrl2

ctrldot	bsr	CheckOpt	dot (.) character
	bne.s	ctrlign
	move.l	parm3(a5),d0
	beq	too_less_args
	move.l	d0,a0
	move.b	(a0),dotchar(a5)
ctrl2	bra.s	ctrl3

ctrlign	bsr	CheckOpt	ignore-string for DIR and FNC
	bne.s	ctrlcol
	tst.l	parm3(a5)	set or show exeptions of
	beq.s	.A		filenamecompletition or dir
	bsr	FlushFNC
	move.l	parm3(a5),a0
	bsr	handle_wild_dirs
	lea	wild_string(a5),a0
	lea	FNCignore(a5),a1
	moveq	#30-2,d0
.B	move.b	(a0)+,(a1)+
	beq	.D
	dbra	d0,.B
	bra.s	.D
.A	lea	FNCignore(a5),a1
	bsr	pr_stringlf
.D	bra.s	ctrl3

ctrlcol	bsr	CheckOpt	redefine colors
	bne.s	ctrlcpy
	move.l	parm3(a5),d0
	beq	too_less_args
	move.l	d0,a3
	lea	stringstart(pc),a0
	lea	recol1(pc),a1
	lea	recol2(pc),a2
	moveq	#0,d1
	moveq	#0,d2
	moveq	#(recol2-recol1)/2-1,d0
.A	move.w	(a1)+,d1
	move.b	(a2)+,d2
	add.b	d2,d2
	move.b	0(a3,d2.l),d3
	move.b	d3,0(a0,d1.l)
	move.b	1(a3,d2.l),d3
	move.b	d3,1(a0,d1.l)
	dbra	d0,.A
ctrl3	bra.s	ctrl4

ctrlcpy	bsr	CheckOpt	buffer for copy/move/join/split
	bne.s	ctrlfnc
	move.l	parm3(a5),d0
	beq.s	.A
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	move.l	d0,copysize(a5)
	bra.s	ctrl4
.A	lea	copysize(a5),a1
ShowBuffer	;shows bytesize in (A1)
	lea	bytes_tx(pc),a0
	bsr	new_print
	bra.s	ctrl4
 
ctrlfnc	bsr	CheckOpt	buffer for filenamecompletion
	bne.s	ctrllog
	tst.l	parm3(a5)
	bne.s	.A
	lea	FNCsize(a5),a1
	bra.s	ShowBuffer
.A	bsr	FreeFNC
	move.l	parm3(a5),a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	move.l	d0,FNCsize(a5)
ctrl4	bra.s	ctrlend

ctrllog	bsr	CheckOpt
	bne.s	ctrlerr
	move.l	parm3(a5),d1
	beq.s	closelog
	lea	loghandle(pc),a3
	tst.l	(a3)	logfile already opened ?
	bne.s	ctrl5
	bsr	OpenReadWrite	open logfile
	move.l	d0,(a3)
	beq	DOSerr
	move.l	d0,d1
	moveq	#0,d2	set position
	moveq	#1,d3	set mode
	jsr	_LVOSeek(a6)	jump to end of file
	lea	name_tx(pc),a1
	bsr	pr_string
	bsr	rask
	move.l	a4,a0
	bsr	write2log
	lea	lf(pc),a0
	bsr	write2log
	bra.s	ctrl5
closelog lea	loghandle(pc),a2
	tst.l	(a2)
	beq.s	ctrl5
	lea	lf(pc),a0
	bsr	write2log
	move.l	(a2),d1
	jsr	_LVOClose(a6)	close logfile if no filename given
	clr.l	(a2)
ctrl5	bra.s	ctrlend

ctrlerr	lea	configuse(pc),a1
	bsr	pr_stringlf
ctrlend	moveq	#RETURN_OK,d0
	rts

*************************
*	Locate		*	V2.0
************************* Show the Path and Filename of a Lock-Struct
locatez			;or lock object or delete lock
	bsr	pr_hide_cursor
	lea	parm2(a5),a3
	move.l	(a3),d0
	beq	ShowLocks
	move.l	d0,a0
	moveq	#0,d7
	bsr	return_dash_option
	cmp.b	#"C",d0
	bne.s	.F
	moveq	#-1,d7		delete lock after showing
	addq.l	#4,a3
	tst.l	(a3)
	beq.s	SyntaxError
.F	move.l	(a3),a1
	bsr	convert_ASCII_to_num
	bne.s	ShowLock

	move.l	4(a3),d0	access mode
	beq.s	SyntaxError
	move.l	d0,a0
	moveq	#ACCESS_READ,d2
	lea	lockread(pc),a1
	bsr	CheckOpt
	beq.s	.E
	moveq	#ACCESS_WRITE,d2
	lea	lockwrite(pc),a1
	bsr	CheckOpt
	bne.s	SyntaxError
.E	move.l	(a3),d1		name to lock
	jsr	_LVOLock(a6)	get new lock
	tst.l	d0
	bne.s	ShowLock
SyntaxError
	moveq	#-119,d0
	bra	pr_galactic

ShowLock
	lea	-12(sp),sp	write out name of lock
	move.l	d0,(sp)		d7<>0 : delete lock
	move.l	d0,d6
	lsl.l	#2,d0
	move.l	d0,a0
	lea	lockwrite(pc),a1
	moveq	#ACCESS_WRITE,d1
	cmp.l	fl_Access(a0),d1	what kind of lock
	beq.s	.C
	lea	lockread(pc),a1
	subq.l	#1,d1
	cmp.l	fl_Access(a0),d1
	bne.s	.A
.C	move.l	a1,4(sp)
	move.l	d6,d1
	jsr	_LVODupLock(a6)
	lea	tempbuf(a5),a0
	move.l	a0,8(sp)
	bsr	eval_full_path	evaluate the full name
	jsr	_LVOUnLock(a6)
	move.l	sp,a1
	lea	locktext(pc),a0
	bsr	new_print
.A	lea	12(sp),sp
	tst.l	d7
	beq.s	.G
	move.l	d6,d1
	jsr	_LVOUnLock(a6)
	lea	deleteOK(pc),a1
	bsr	pr_string
.G	bra.s	LockOK

ShowLocks
	moveq	#0,d3
	bsr	get_first_devinfo
.D	moveq	#dlt_device,d1
	bsr	find_next_assign	walk through dos-list
	tst.l	d0
	bne.s	.C
	move.l	8(a0),packettask(a5)	task
	beq.s	.D		was non-disk-device
	bsr	GetDiskInfo
	beq.s	.D
	move.l	id_InUse(a5),d0	lock
	beq.s	.D
.A	addq.l	#1,d3	count locks
	movem.l	d0-d3/a0-a2,-(sp)
	moveq	#0,d7
	bsr	ShowLock	show lock
	movem.l	(sp)+,d0-d3/a0-a2
	lsl.l	#2,d0
	move.l	d0,a0
	move.l	(a0),d0
	bne.s	.A
	bra.s	.D
.C	move.l	d3,-(sp)
	move.l	sp,a1
	lea	numoflocks(pc),a0
	bsr	new_print
	addq.l	#4,sp
LockOK	moveq	#RETURN_OK,d0
	rts

GetDiskInfo	;device-task must be in packettask(a5), gets info to a5
	bsr	clearArgs
	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)
	bra	sendpacket

*************************
*	TaskPri		*	V2.0
*************************
taskpriz
	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,d7
	move.l	parm3(a5),a2
	bsr	findtsk
	beq	pr_notfound
	move.l	d0,a1
	move.l	d7,d0
	move.l	4.w,a6
	jsr	_LVOSetTaskPri(a6)
tskok	move.l	dosbase(a5),a6
	moveq	#RETURN_OK,d0
	rts

* Find Task given in a2 (ptr,string,cli-number,null)
* RETURN: d0,a0 address (0 if not found)
findtsk	moveq	#0,d0
	move.l	a2,d1
	beq.s	.E
	move.l	a2,a1
	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	move.l	parm2(a5),d0
	beq	too_less_args
	move.l	d0,a2
	bsr	findtsk
	beq	pr_notfound
	move.l	d0,a2
	move.l	tc_SigWait(a2),d0
	move.l	parm3(a5),d1
	beq.s	.C
	move.l	d1,a1
	move.b	(a1),d2
	bsr	convert_ASCII_to_num
	bne.s	.C
	moveq	#RETURN_ERROR,d0
	bclr	#5,d2
	cmp.b	#"C",d2
	blo.s	.A
	cmp.b	#"F",d2
	bhi.s	.A
	sub.b	#55,d2
	moveq	#0,d0
	bset	d2,d0
.C	move.l	a2,a1
	move.l	4.w,a6
	jsr	_LVOSignal(a6)	set signals given in mask
	move.l	dosbase(a5),a6
	moveq	#RETURN_OK,d0
.A	rts

*************************
*	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	bra	pr_notfound
.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	dotchar(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
	sub.l	a0,a0
	jsr	_LVODisplayBeep(a6)
	move.l	dosbase(a5),a6
msgfail	moveq	#RETURN_ERROR,d0
	rts

*************************
*	Border		*	V2.0
*************************
borderz	move.l	parm2(a5),a0
	bsr	CheckOnOff
	move.l	windowptr(a5),d1
	beq	nosiz
	move.l	d0,-(sp)
	move.l	d1,a0
	move.l	a0,a4		this window
	move.l	intuibase(a5),a6
	moveq	#0,d0
	jsr	_LVOLockIBase(a6)
	move.l	d0,d7
	move.l	(sp)+,d0
	beq	bordoff

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

bordoff	tst.l	wd_BorderLeft(a4)
	beq.s	borjo
	bset	#3,wd_Flags+2(a4)	set noborder-window (bit 11)
	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

*************************
*	Review		*	V2.1
*************************
reviewz	move.l	parm2(a5),d0
	beq.s	ShowReview
	move.l	d0,a1
	move.l	d0,a2
	bsr	convert_ASCII_to_num
	move.l	d0,d7
	tst.l	d1
	bne.s	MakeReview
	addq.l	#1,a2
	or.b	#$20,(a2)
	cmp.b	#"c",(a2)
	beq.s	ClearReview
	cmp.b	#"s",(a2)
	bne.s	ShowReview
	move.l	parm3(a5),d0		Save review-buffer
	beq	too_less_args
	tst.l	ReviewSize(a5)
	beq.s	ShowReview
	move.l	d0,a3
	moveq	#0,d6
	bra	viewbuffer

ShowReview
	lea	ReviewSize(a5),a1	Show review-info
	bra	ShowBuffer

ClearReview
	move.l	ReviewMem(a5),a0
	move.l	ReviewSize(a5),d0
	beq.s	.A
	move.l	d0,d1
	swap	d1
	bra.s	.D
.E	move.b	#" ",(a0)+	Fill with spaces
.D	dbra	d0,.E
	dbra	d1,.E
	move.b	#LF,-1(a0)	Last char is LF
	clr.l	ReviewPtr(a5)
.A	moveq	#RETURN_OK,d0
	rts

MakeReview	;entry: d7=size
	tst.l	d7			Add review-buffer
	beq	reviewend
	tst.l	ReviewSize(a5)
	beq.s	.F
	bsr	reviewend

.F	move.l	ReviewList(pc),d0
	bne.s	.A
	lea	rviewtx+1(pc),a0
	move.l	a0,d1
	moveq	#4,d2
	lea	ReviewHandler(pc),a0
	move.l	a0,d3
	lsr.l	#2,d3
	move.l	#1000,d4
	jsr	_LVOCreateProc(a6)
	tst.l	d0
	beq.s	MRend
	moveq	#1,d1
	jsr	_LVODelay(a6)
	move.l	ReviewList(pc),d0
	beq.s	MRend
.A	move.l	d0,a2
	move.l	ReviewPort(pc),d0
	beq.s	MRend

	move.l	d7,d0
	bsr	iwantmem
	beq.s	MRend
	move.l	d0,ReviewMem(a5)
	move.l	d7,ReviewSize(a5)
	bsr	ClearReview

	moveq	#20-1,d0
.C	tst.l	(a2)+
	beq.s	PatchO
	addq.l	#8,a2
	dbra	d0,.C
	bra.s	MRend

PatchOuthandle
	move.l	ReviewList(pc),d0	Remove a5-table entry
	beq.s	PatchE
	move.l	d0,a2
	moveq	#20-1,d0
.A	cmp.l	(a2)+,a5
	beq.s	PatchO
	addq.l	#8,a2
	dbra	d0,.A
	bra.s	PatchE
PatchO	move.l	a5,-4(a2)
	move.l	stdout(a5),a1
	add.l	a1,a1
	add.l	a1,a1
	move.l	a1,(a2)
	move.l	thistask(a5),a0
	lea	pr_MsgPort(a0),a0
	move.l	a0,4(a2)
	move.l	fh_Type(a1),d0
	move.l	thistask(a5),a0
	cmp.l	pr_ConsoleTask(a0),d0
	bne.s	MRend
	move.l	ReviewPort(pc),fh_Type(a1)
PatchE	moveq	#RETURN_OK,d0
	rts

MRend	bsr	DisplayBeep
reviewend		;Remove review-buffer
	move.l	ReviewList(pc),d0	Remove a5-table entry
	beq.s	remmem2
	move.l	d0,a0
	move.l	a0,a1
	moveq	#20-1,d0
.A	cmp.l	(a0)+,a5
	beq.s	.B
	addq.l	#8,a0
	dbra	d0,.A
	bra.s	.D
.B	clr.l	-4(a0)
	clr.l	(a0)
	clr.l	4(a0)
	move.l	stdout(a5),a2
	add.l	a2,a2
	add.l	a2,a2
	move.l	thistask(a5),a0
	move.l	pr_ConsoleTask(a0),fh_Type(a2)

.D	moveq	#20-1,d0	look for other entries
.C	tst.l	(a1)+
	bne.s	remmem2
	addq.l	#8,a1
	dbra	d0,.C
	bsr	clearArgs	kill review handler
	move.l	ReviewPort(pc),packettask(a5)
	moveq	#ACTION_DIE,d0
	move.l	d0,packettype(A5)
	bsr	sendpacket
remmem2	move.l	ReviewSize(a5),d0	Remove buffer-memory
	beq.s	.A
	move.l	ReviewMem(a5),a1
	bsr	givemem
	clr.l	ReviewSize(a5)
.A	moveq	#RETURN_OK,d0
	rts

		cnop	0,4	two global variables
ReviewList	dc.l	0
ReviewPort	dc.l	0
;review-list:
;LONG	a5 address
;LONG	stdout
;LONG	msgport of task

*********
;Start of Review-Handler segment
		dc.l	0	length of segment (zero to avoid freeing)
ReviewHandler	dc.l	0	no next segment
ReviewCode
	move.l	4.w,a6
	move.l	#20*4*3,d0
	move.l	#1+1<<16,d1		"memf_public" & clear it
	jsr	_LVOAllocMem(a6)	get some memory
	tst.l	d0
	beq	.end
	lea	ReviewList(pc),a2
	move.l	d0,(a2)+	store as global variable
	sub.l	a1,a1
	jsr	_LVOFindTask(a6)	find this task
	move.l	d0,a4
	lea	pr_MsgPort(a4),a4	a4=this MsgPort
	move.l	a4,(a2)		store as global variable

.wait	move.l	a4,a0
	jsr	_LVOWaitPort(a6)
	move.l	a4,a0
	jsr	_LVOGetMsg(a6)	get next dos packet
	tst.l	d0
	beq.s	.wait		wait for next packet
	move.l	d0,a0
	move.l	LN_NAME(a0),d0
	beq.s	.wait
	move.l	d0,a3			a3=current dos packet
	moveq	#ACTION_DIE,d0
	cmp.l	dp_Action(a3),d0
	beq.s	.die		kill review handler
	move.l	dp_Port(a3),a0	look for task in list
	move.l	ReviewList(pc),a1
	moveq	#20-1,d0
.C	move.l	(a1)+,a5
	addq.l	#4,a1
	cmp.l	(a1)+,a0
	beq.s	.E
	dbra	d0,.C
	move.l	dp_Arg1(a3),a0	look for filehandle in list
	move.l	ReviewList(pc),a1
	moveq	#20-1,d0
.D	move.l	(a1)+,a5
	cmp.l	(a1)+,a0
	addq.l	#4,a1
	beq.s	.E
	dbra	d0,.D
	bra.s	.wait		do not reply (hang up)

.E	tst.b	noreview_flag(a5)
	bne.s	.A
	moveq	#ACTION_WRITE,d0	Write() call ?
	cmp.l	dp_Action(a3),d0
	bne.s	.A
	move.l	dp_Arg2(a3),d2
	move.l	dp_Arg3(a3),d3
	bsr	toreview
	tst.l	MPipePtr(a5)
	beq.s	.A
	move.l	dp_Arg3(a3),dp_Res1(a3)	redirect to nil
	move.l	dp_Port(a3),a0
	move.l	a4,dp_Port(a3)
	bra.s	.F
.A	move.l	thistask(a5),a0
	move.l	pr_ConsoleTask(a0),a0
.F	move.l	dp_Link(a3),a1
	jsr	_LVOPutMsg(a6)
	bra	.wait

.die	move.l	dp_Link(a3),a1
	move.l	dp_Port(a3),a0
	move.l	a4,dp_Port(a3)
	jsr	_LVOPutMsg(a6)
	lea	ReviewList(pc),a0
	move.l	(a0),a1
	clr.l	(a0)+
	clr.l	(a0)
	move.l	#20*4*3,d0
	jsr	_LVOFreeMem(a6)
.end	rts

toreview	;Writes data to review-buffer,Entry: d2=Adress, d3=Length
	move.l	d2,a0
	move.l	ReviewMem(a5),a1
	move.l	ReviewPtr(a5),d1
	move.l	ReviewSize(a5),d2
	beq.s	.C
	move.l	d3,d0
	swap	d0
	bra.s	.B
.A	move.b	(a0)+,0(a1,d1.l)
	addq.l	#1,d1
	cmp.l	d1,d2
	bhi.s	.B
	clr.l	d1
.B	dbra	d3,.A
	dbra	d0,.A
	move.l	d1,ReviewPtr(a5)
.C	rts

**********
viewbuffer		;Show the review-buffer using more
	;a3=filename to save, d6=MPipePtr
	move.l	ReviewMem(a5),a2
	move.l	ReviewPtr(a5),d3
	move.l	ReviewSize(a5),d2
	bne.s	viewhist
	rts
viewhist	;Show a circular buffer using more
	move.l	d2,d4
	move.l	d6,d1
	beq.s	.A
	move.l	d3,d0	for redirecting to more
	move.l	d1,d3
	sub.l	d0,d1
	bpl.s	.C
	add.l	d2,d1
	bra.s	.C
.A
.I	move.b	0(a2,d3.l),d0
	addq.l	#1,d3
	cmp.l	d3,d2
	bhi.s	.B
	clr.l	d3
.B	addq.l	#1,d1
	cmp.b	#LF,d0
	beq.s	.C
	cmp.b	#12,d0
	bne.s	.I
.C	sub.l	d1,d2
	move.l	d2,d0
	beq	viewOK
	bsr	iwantmem
	beq	viewOK
	move.l	d0,a0
	move.l	a0,a1
	move.l	d4,d1
	move.l	d2,d4
	move.l	d2,d5
	swap	d5
	bra.s	.E
.D	move.b	0(a2,d3.l),d0
	cmp.b	#12,d0
	bne.s	.G
	move.b	#LF,d0
.G	cmp.b	#"c",d0
	bne.s	.H
	cmp.b	#27,-1(a0)
	bne.s	.H
	move.b	#LF,-1(a0)
	move.b	#LF,d0
.H	move.b	d0,(a0)+
	addq.l	#1,d3
	cmp.l	d3,d1
	bhi.s	.E
	clr.l	d3
.E	dbra	d2,.D
	dbra	d5,.D
	move.l	a3,d0
	bne.s	viewwrite
	move.l	a1,d0
	move.l	d4,d1
	moveq	#-1,d2
	tst.l	d6
	beq.s	.F
	moveq	#0,d2
.F	moveq	#0,d4
	bra	ViewMore
viewwrite		;write buffer to file
	move.l	a1,a2
	move.l	a3,d1
	bsr	OpenNewfile
	tst.l	d0
	beq.s	.A
	move.l	d0,a3
	move.l	a3,d1
	move.l	a2,d2
	move.l	d4,d3
	move.l	d3,-(sp)
	jsr	_LVOWrite(a6)
	move.l	(sp)+,d3
	sub.l	d0,d3
	move.l	a3,d1
	jsr	_LVOClose(a6)
	moveq	#1,d0
	tst.l	d3
	beq.s	.A
	moveq	#0,d0
.A	move.l	d0,d2
	move.l	d4,d0
	move.l	a2,a1
	bsr	givemem
	tst.l	d2
	beq	DOSerr
viewOK	moveq	#RETURN_OK,d0
	rts


**********************************************************************
; check if string in a0 is same as in a1 (limited by null,comma,space)
; return: d0=0 for match, 1 otherwise
CheckOpt	
	move.l	a0,-(sp)
	cmp.b	#$22,-1(a0)	options are not enclosed in quotes
	beq.s	.H
	move.b	dotchar(a5),d0
	bsr	CheckOneChar	single dotchar is not an option
	beq.s	.H
.A	move.b	(a1)+,d1	compare things
	beq.s	.B
	cmp.b	#" ",d1
	beq.s	.B
	cmp.b	#",",d1
	beq.s	.B
	move.b	(a0)+,d0
	beq.s	.H
	cmp.b	dotchar(a5),d0	check for .
	bne.s	.F
	tst.b	(a0)
	beq.s	.G
.F	bsr	compD1D0nocase
	beq.s	.A
.H	moveq	#1,d0		failed (not matched)
	bra.s	.E
.G	moveq	#0,d0		success	(abbreviated)
.E	move.b	(a1)+,d1	search for end
	beq.s	.D
	cmp.b	#" ",d1
	beq.s	.D
	cmp.b	#",",d1
	bne.s	.E
	bra.s	.D
.B	moveq	#1,d0		success or a0 is too long ?
	tst.b	(a0)
	bne.s	.D
	moveq	#0,d0		length is same -> success
.D	move.l	(sp)+,a0
	tst.l	d0
	rts

*************************
; check a0 for ON (d0=1) or OFF (d0=0) option, otherwise error-exit
CheckOnOff
	move.l	a2,-(sp)
	lea	onoffuse(pc),a2
	move.l	a0,d0
	beq.s	.B
	lea	6(a2),a1
	bsr	CheckOpt
	beq.s	.A
	move.l	a2,a1
	bsr	CheckOpt
	bne.s	.B
	moveq	#1,d0
.A	move.l	(sp)+,a2
	rts
.B	move.l	a2,a0
*************************
; print error in a0 and exit
ErrorExit
	bsr	PrintError
	bra	galactic

*************************
; check for Kickstart 2.0 or better, exit on error
CheckKS	lea	oldkick_tx(pc),a0
	cmp.w	#36,kickver(a5)
	blo.s	ErrorExit
	rts

**********************************************************************
; check if option in a0 is in parm-list and deletes it from parm-list
; return: d0=0 for match, 1 otherwise
LookForOpt
	movem.l	a2-a3,-(sp)
	move.l	a0,a2
	lea	parm2(a5),a3
.A	move.l	(a3)+,d0	search all parms
	beq.s	.B
	move.l	a2,a1
	move.l	d0,a0
	bsr	CheckOpt	look for option
	bne.s	.A
	lea	-4(a3),a2	found it !
.D	move.l	(a3)+,(a2)+	delete found parm
	bne.s	.D
	moveq	#0,d0
	bra.s	.C
.B	moveq	#1,d0		not found !
.C	movem.l	(sp)+,a2-a3
	rts

*************************
*	MakeLink	*	V2.3
*************************
makelinkz
	bsr	CheckKS
	moveq	#0,d7
	moveq	#0,d3
	move.l	parm4(a5),d0
	beq.s	.B
	move.l	d0,a0
	lea	softtx(pc),a1
	bsr	CheckOpt
	bne	SyntaxError
	moveq	#-1,d3
.B	move.l	parm3(a5),d1
	beq	too_less_args
	move.l	d1,d2
	tst.l	d3
	bne.s	.D
	moveq	#-2,d2
	jsr	_LVOLock(a6)
	move.l	d0,d7
	beq	DOSerr
	move.l	d0,d2
.D	move.l	parm2(a5),d1
	jsr	_LVOMakeLink(a6)
	tst.l	d0
	beq	DOSerrUL
	move.l	d7,d1
	beq.s	.A
	jsr	_LVOUnLock(a6)
.A	moveq	#RETURN_OK,d0
	rts

*************************
*	Flags		*	V2.3
*************************
flagsz	lea	parm2(a5),a3
	move.l	Flags(a5),d3
	tst.l	(a3)
	beq.s	.F
.A	move.l	d3,d0
	bsr	SetFlags
	move.l	(a3)+,d0
	beq.s	.C
	move.l	d0,a0
	lea	flagsuse(pc),a1
	moveq	#0,d2
.B	bsr	CheckOpt	look for flag
	beq.s	.D
	addq.w	#1,d2
	cmp.w	#MaxFlags,d2
	bne.s	.B
	lea	flagsuse(pc),a1
	bsr	pr_stringlf
	bra.s	.C
.D	move.l	(a3)+,a0	change flag
	bclr	d2,d3
	bsr	CheckOnOff
	beq.s	.A
	bset	d2,d3
	bra.s	.A

.F	moveq	#0,d2		print all flags
	lea	flagsuse(pc),a3
.E	lea	temp2buf(a5),a2
.G	move.b	(a3)+,d0
	move.b	d0,(a2)+
	cmp.b	#" ",d0
	beq.s	.H
	cmp.b	#",",d0
	bne.s	.G
.H	subq.l	#1,a2
	lea	flagsoff(pc),a1
	btst	d2,d3
	beq.s	.I
	lea	flagson(pc),a1
.I	bsr	addstring
	lea	temp2buf(a5),a1
	bsr	pr_string
	addq.w	#1,d2
	cmp.w	#MaxFlags,d2
	bne.s	.E
.C	moveq	#RETURN_OK,d0
	rts

SetFlags
	cmp.w	#36,kickver(a5)
	bhs.s	.A
	and.l	#-1-%1100,d0	ICON and WILD not possible with OS1.3
.A	move.l	d0,Flags(a5)	set Flags
	rts

*************************
*	MakeIcon	*	V2.3
*************************
makeiconz
	bsr	CheckKS
	move.l	parm2(a5),d3
	beq.s	.F
	move.l	parm3(a5),d0
.F	beq	too_less_args
	move.l	d0,a0
	moveq	#1,d2
	lea	iconuse(pc),a1
.D	bsr	CheckOpt
	beq.s	.C
	addq.l	#1,d2
	cmp.b	#9,d2
	bne.s	.D
.B	move.l	dosbase(a5),a6
	lea	iconuse(pc),a1
	bsr	pr_stringlf
	bra.s	.A
.C	bsr	OpenIconLib
	beq.s	.B
	move.l	d2,d0
	jsr	_LVOGetDefDiskObject(a6)
	move.l	d0,d2
	beq	resi_not_found
	move.l	d0,a1
	move.l	d3,a0
	jsr	_LVOPutDiskObject(a6)
	move.l	d0,d3
	move.l	d2,a0
	jsr	_LVOFreeDiskObject(a6)
	tst.l	d3
	beq	resi_not_found
.A	move.l	dosbase(a5),a6
	moveq	#RETURN_OK,d0
	rts

*************************
*	Split		*	V2.6
*************************
splitz	moveq	#0,d6
	tst.l	parm4(a5)
	beq	too_less_args
	moveq	#0,d5
	moveq	#0,d7		d7=current number
	clr.l	devproc(a5)
	bset	#DLsplit,d6	split flag
	bsr	check_q_r
	move.l	parm4(a5),a1	get length
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	move.l	d0,a3
	move.l	parm2(a5),d1
	bsr	OpenOldfile	open input file
	move.l	d0,d4		d4=input file handle
	beq	perr3
	move.l	parm5(a5),d0	may get offset
	beq.s	.A
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq.s	.A
	move.l	d4,d1
	move.l	d0,d2
	moveq	#-1,d3
	jsr	_LVOSeek(a6)	skip offset
	tst.l	d0
	bmi.s	splend2
.A	bsr	GetCopyBlock
	beq.s	splend2

sploop	move.l	parm3(a5),a0
	lea	tempbuf(a5),a1
	move.l	a1,d1
.A	move.b	(a0)+,(a1)+	copy output name
	bne.s	.A
	subq.l	#1,a1
	addq.l	#1,d7
	move.l	d7,d0
	bsr	qpr10		append number to name
	clr.b	(a1)
	move.l	d1,a1
	bsr	pr_string
	bsr	pr_space
	bsr	AskYesNo	ask
	beq.s	.B
	bsr	check_c
	bne.s	splend
	move.l	d4,d1
	move.l	a3,d2
	moveq	#0,d3
	jsr	_LVOSeek(a6)	skip part
	tst.l	d0
	bpl.s	sploop
	bra.s	splend

.B	bsr	OpenNewfile	open output file
	move.l	d0,d5		d5=output file handle
	bne.s	.D		a3 holds filesize
	bsr	perr3
	bra.s	splend
.D	move.l	a3,d3
	bsr	PerformCopy1	copy part to output
	bsr	check_c
	bne.s	splend
	tst.l	d0
	bne.s	.C
	lea	processOK(pc),a1	all OK
	bsr	pr_string
.C	moveq	#-1,d0
	cmp.l	d0,d3		check for input-fileend
	beq.s	sploop

splend	bsr	FreeCopyBlock
splend2	move.l	d4,d1
	jsr	_LVOClose(a6)	close input
	moveq	#RETURN_OK,d0
	rts

*************************
*	Compare		*	V2.9
*************************
comparez
	clr.l	temp3(a5)	temp3=current pos.
	moveq	#10,d0
	move.l	d0,temp5(a5)	temp5=result
	move.l	parm3(a5),d1
	beq	too_less_args
	bsr	OpenOldfile	open file2
	bsr	maybeDOSerr
	move.l	d0,d5		d5=file2 input handle
	beq	compen4
	move.l	parm2(a5),d1
	bsr	OpenOldfile	open file1
	bsr	maybeDOSerr
	move.l	d0,d4		d4=file1 input handle
	beq	compen3
	move.l	d4,d2			handle offsets
	move.l	parm4(a5),d0	may get offset1
	bsr	compsk
	bmi	compen2
	move.l	d5,d2
	move.l	parm5(a5),d0	may get offset2
	bsr	compsk
	bmi	compen2

	bsr	GetCopyBlock		get memory
	beq	compen2
	move.l	copysize(a5),d7	d7=block size
	lsr.l	#1,d7
	move.l	temp6(a5),a3	a3=block1
	move.l	a3,a4
	add.l	d7,a4		a4=block2
	subq.l	#5,temp5(a5)

complp	move.l	d4,d1			compare-loop
	move.l	a3,d2
	move.l	d7,d3
	jsr	_LVORead(a6)	read from file1
	move.l	d0,d6		d6=current length1
	bmi.s	compen1
	move.l	d5,d1
	move.l	a4,d2
	move.l	d7,d3
	jsr	_LVORead(a6)	read from file2
	tst.l	d0		d0=current length2
	bmi.s	compen1
	bne.s	.A
	tst.l	d6
	bne.s	compen0
	lea	comp_same(pc),a1	reached both ends
	bsr	pr_stringlf
	clr.l	temp5(a5)
	bra.s	compen1

.A	tst.l	d6
	beq.s	compen0
	cmp.l	d0,d6
	bls.s	.E
	exg	d0,d6
.E	move.l	a3,a0
	move.l	a4,a1
	moveq	#0,d2
.C	addq.l	#1,d2
	move.b	(a0)+,d1
	cmp.b	(a1)+,d1
	beq.s	.D
	subq.l	#1,d2
	add.l	d2,temp3(a5)
	lea	temp3(a5),a1
	lea	comp_diff(pc),a0
	bsr	new_print
	bra.s	compen1
.D	cmp.l	d2,d6
	bhi.s	.C
	add.l	d6,temp3(a5)
	cmp.l	d0,d6
	beq.s	complp

compen0	lea	diff_size(pc),a1	size different
	bsr	pr_stringlf
compen1	bsr	FreeCopyBlock
compen2	move.l	d5,d1
	jsr	_LVOClose(a6)	close file1
compen3	move.l	d4,d1
	jsr	_LVOClose(a6)	close file2
compen4	move.l	temp5(a5),d0
	rts

compsk	beq.s	.A
	move.l	d0,a1
	bsr	convert_ASCII_to_num
	beq	bad_number_error
	move.l	d2,d1
	move.l	d0,d2
	moveq	#-1,d3
	jsr	_LVOSeek(a6)	skip offset
	tst.l	d0
.A	rts

*************************
*	Menu		*	V2.9
*************************
menuz	bsr	InitGadTools
	beq	menu_fail
	lea	parm2(a5),a4
	move.l	(a4),d0
	beq	too_less_args
	move.l	d0,a0
	bsr	return_dash_option
	cmp.b	#"C",d0
	bne.s	.C
	bsr	ClearMenuStrip
	bra	ClearMenuDef
.C	lea	menu_pool(a5),a1
	move.l	a1,d7		d7=&poolheader
	moveq	#0,d6		d6=size of newmenu array (longs)
	lea	tempbuf(a5),a3
	lea	2*SHELLINE_SIZE-40(a3),a2

menu_loop
	bsr	CheckItemType	get type (title, item ...)
.D	beq	menu_lend
	bpl.s	.C
	lea	menuuse(pc),a0
	bra	ErrorExit
.C	cmp.w	#6,d0
	bne.s	.G
	bsr	menu_lend
	beq	CreateMenuStrip
.G	cmp.l	a2,a3
	bhs.s	menu_lend
	cmp.w	#4,d0
	bhs.s	.F
	lsl.l	#8,d0
	move.w	d0,(a3)+
	move.l	(a4)+,d0	get label string
	beq	too_less_args
	move.l	d7,a1
	bsr	StringPooled
	bra.s	.A
.F	subq.l	#2,d0
	lsl.l	#8,d0
	move.w	d0,(a3)+
	moveq	#-1,d0
.A	move.l	d0,(a3)+
	clr.l	(a3)+
	clr.w	(a3)+
	clr.l	(a3)+
	move.l	d0,(a3)+
	addq.l	#5,d6
	bsr	CheckItemType	maybe get action string
	bpl.s	.D
	move.l	a0,d0
	move.l	d7,a1
	bsr	StringPooled
	move.l	d0,-4(a3)
	bsr	CheckItemType	maybe get command key string
	bpl.s	.D
	tst.b	1(a0)
	beq.s	.E
	move.w	#COMMSEQ,-10(a3)
.E	move.l	a0,d0
	move.l	d7,a1
	bsr	StringPooled
	move.l	d0,-14(a3)
	bra	menu_loop

menu_lend
	move.l	d7,a1
	move.l	d6,d0
	lsl.l	#2,d0
	addq.l	#8,d0		space for link and size
	bsr	AutoAllocPooled
	beq	resi_no_mem
	add.l	d6,menu_count(a5)
	move.l	d0,a0
	clr.l	(a0)+		clear link
	move.l	d6,(a0)+	store size
	lea	tempbuf(a5),a1
	bra.s	.A
.C	move.l	(a1)+,(a0)+	copy tempbuf to memory
.A	dbra	d6,.C
	lea	first_menudef(a5),a0
	move.l	a0,d1
.H	move.l	d1,a0
	move.l	(a0),d1		look for end of list
	bne.s	.H
	move.l	d0,(a0)		link together
	moveq	#RETURN_OK,d0
	bra.s	menu_fail3
menu_fail
	moveq	#RETURN_ERROR,d0
menu_fail3
	move.l	dosbase(a5),a6
	rts

CreateMenuStrip
	lea	first_menudef(a5),a2
	move.l	menu_count(a5),d0
	beq.s	menu_fail
CreateMenuStrip2		;entry for CreateCLI3
	lsl.l	#2,d0
	addq.l	#8,d0
	addq.l	#8,d0
	move.l	d0,d3
	bsr	iwantmem
	beq	resi_no_mem
	move.l	d0,a4
	move.l	d0,a3
.D	move.l	(a2),d0
	beq.s	.E
	move.l	d0,a2
	move.l	4(a2),d0
	lea	8(a2),a0
	bra.s	.A
.C	move.l	(a0)+,(a3)+
.A	dbra	d0,.C
	bra.s	.D
.E	clr.l	(a3)+
	bsr	ClearMenuStrip
	move.l	gadbase(a5),a6
	move.l	first_menu(a5),a0
	jsr	_LVOFreeMenus(a6)	clear menu strip
	move.l	a4,a0
	move.l	a3,a1
	move.l	#GTMN_FullMenu,(a3)+
	moveq	#1,d0
	move.l	d0,(a3)+
	clr.l	(a3)
	jsr	_LVOCreateMenusA(a6)
	move.l	d0,first_menu(a5)
	beq.s	menu_fail
	move.l	a4,a1
	move.l	d3,d0
	bsr	givemem

LayoutMenuStrip
	move.l	first_menu(a5),d0
	beq	menu_fail
	move.l	d0,a0		assumes VisualInfo and gadbase is valid
	sub.l	a2,a2
	move.l	windowptr(a5),d0
	beq.s	.A
	move.l	d0,a1
	btst	#5,wd_Flags+1(a1)	test WFLG_NEWMENU (bit 21)
	beq.s	.A
	lea	temp2buf(a5),a2
	move.l	a2,a1
	move.l	#GTMN_NewLookMenus,(a1)+
	moveq	#1,d0
	move.l	d0,(a1)+
	clr.l	(a1)
.A	move.l	VisualInfo(a5),a1
	move.l	gadbase(a5),a6
	jsr	_LVOLayoutMenusA(a6)
	tst.l	d0
	beq	ClearMenuDef

SetMenuStrip
	move.l	first_menu(a5),d0
	beq.s	.A
	move.l	d0,a1
	move.l	windowptr(a5),a0
	move.l	intuibase(a5),a6
	jsr	_LVOSetMenuStrip(a6)
	tst.l	d0
.A	beq	menu_fail
	move.l	dosbase(a5),a6
	lea	menuon_tx(pc),a1
	bsr	pr_error
	moveq	#RETURN_OK,d0
	rts

ClearMenuStrip
	tst.l	first_menu(a5)
	beq.s	.C
	move.l	windowptr(a5),a0
	move.l	intuibase(a5),a6
	jsr	_LVOClearMenuStrip(a6)	remove menu strip
	move.l	dosbase(a5),a6
	lea	menuoff_tx(pc),a1
	bsr	pr_error
.C	rts

ClearMenuDef
	move.l	first_menu(a5),d2
	beq.s	.A
	bsr	OpenGadLib
	beq.s	.A
	move.l	d2,a0
	jsr	_LVOFreeMenus(a6)	clear menu strip
	clr.l	first_menu(a5)
.A	clr.l	first_menudef(a5)
	clr.l	menu_count(a5)
	lea	menu_pool(a5),a1
	bsr	DeletePool

FreeGadTools
	move.l	VisualInfo(a5),d0
	beq.s	.A
	move.l	d0,a0
	move.l	gadbase(a5),a6
	jsr	_LVOFreeVisualInfo(a6)	clear visual info
	clr.l	VisualInfo(a5)
.A	move.l	4.w,a6
	move.l	gadbase(a5),d0
	beq.s	.F
	move.l	d0,a1
	jsr	_LVOCloseLibrary(a6)	close gadtools.library
	clr.l	gadbase(a5)
.F	move.l	dosbase(a5),a6
	moveq	#RETURN_OK,d0
	rts

InitGadTools
	tst.l	VisualInfo(a5)		was fully initialized ?
	bne.s	.F
	btst	#FLraw,Flags+2(a5)	test raw-mode
	beq.s	.F
	move.l	windowptr(a5),d0
	beq.s	.F
	move.l	d0,a0
	move.l	wd_WScreen(a0),d2	get screen pointer
	beq.s	.F
	move.l	d2,MyScreen(a5)
	bsr	OpenGadLib		gadtools.library
	beq.s	.F
	move.l	d2,a0
	sub.l	a1,a1
	jsr	_LVOGetVisualInfoA(a6)	visual info
	move.l	d0,VisualInfo(a5)
.F	move.l	dosbase(a5),a6
	rts

*1: Title
*2: Item
*3: Subitem
*4: Itembar
*5: Subitembar
*6: End
CheckItemType	;returns d0=type, -1 if error, a0=string, uses d2
	move.l	(a4)+,d2
	beq.s	.D
	move.l	d2,a0
	moveq	#1,d2
	lea	menuuse(pc),a1
.A	bsr	CheckOpt
	beq.s	.D
	addq.w	#1,d2
	cmp.w	#7,d2
	bne.s	.A
.C	moveq	#-1,d2
.D	move.l	d2,d0
	rts



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


* Localized Error-Messages
doserror_text
	dc.b	 48,'*** BREAK ***',0		304
	dc.b	 49,'Not executable',0		305
	dc.b	103,'Not enough Memory',0
	dc.b	108,'Too small',0		-148
	dc.b	115,'Bad number',0
	dc.b	116,'Not enough Arguments',0
	dc.b	118,'Too many Arguments',0
	dc.b	119,'Unmatched Quotes',0
	dc.b	135,'Command not found',0	-121
	dc.b	137,'Syntax Error',0		-119
	dc.b	202,'Object in use',0
	dc.b	203,'Object '
exists		dc.b	'exists',0
	dc.b	204,'Dir not found',0
	dc.b	205,'Object'
notfund		dc.b	' not found',0
	dc.b	209,'Action unknown',0
	dc.b	210,'Invalid Name',0
	dc.b	212,'Object wrong Type',0
	dc.b	213,'Not validated',0
	dc.b	214,'Disk write-protected',0
	dc.b	215,'Rename across Devices',0  
	dc.b	216,'Dir not empty',0
	dc.b	218,'Device not mounted',0
	dc.b	221,'Disk full',0
	dc.b	222,'Delete protected',0
	dc.b	223,'Write protected',0
	dc.b	225,'Not a DOS Disk',0
	dc.b	226,'No Disk present',0

	dc.b	101,'Error %3ld',0		-155
	dc.b	102,'Failat: %ld',10,0		-154
	dc.b	104,'Current Dir',0		-152
	dc.b	110,'Stack: %ld bytes',10,0	-146
	dc.b	127,'ZShell Process %ld',10,0	-129
	dc.b	0,0


*Standard-Strings
stringstart
iconname	dc.b	"icon.library",0
wbname		dc.b	"workbench.library",0
aslname		dc.b	"asl.library",0
guidename	dc.b	"amigaguide.library",0
gadname		dc.b	"gadtools.library",0
timdev		dc.b	"timer.device",0
conname		dc.b	"CON:0/10/640/190/ZShell V"
		dc.l	ZVERSION
		dc.b	"/CLOSE",0
connil		dc.b	"NIL:",0
devpipe		dc.b	"PIPE:",0
devtemp		dc.b	"T:",0
wintool		dc.b	"WINDOW",0
screentool	dc.b	"SCREEN",0
scripttool	dc.b	"SCRIPT",0
norawtool	dc.b	"NORAW",0
commandtool	dc.b	"COMMAND",0
iconifytool	dc.b	"ICONIFY",0
xpostool	dc.b	"XPOS",0
ypostool	dc.b	"YPOS",0
nametool	dc.b	"ICONNAME",0
helptool	dc.b	"HELPMAN",0
wbenchtx	dc.b	"Workbench",0
useit		dc.b	"Usage: ZShell [-Wwindow] [-Sscript]"
		dc.b	" [-Ccommand] [-Hhelpman] [-N] [-E] [-D]",0
onoffuse	dc.b	"ON or OFF ?",0
flagsuse	dc.b	"CHECK,MATCH,ICON,WILD,ERRORS,DEBUG,CUT,ALL"
		dc.b	",HIDE,PIPE,RAW,CONFIRM,HBIT ?",0
iconuse		dc.b	"DISK,DRAWER,TOOL,PROJECT,GARBAGE"
		dc.b	",DEVICE,KICK,APPICON ?",0
configuse	dc.b	"CTRLKEYS,MOREKEYS,DOT,HIDE,COLOR"
		dc.b	",COPYSIZE,FNCSIZE,LOGFILE ?",0
assignuse	dc.b	"EXISTS,REMOVE,ADD,PATH,DEFER ?",0
menuuse		dc.b	"TITLE,ITEM,SUBITEM,BAR,SUBBAR,END ?",0
softtx		dc.b	"SOFT",0
devicetx	dc.b	"DISK",0
forcetx		dc.b	"FORCE",0
alltx		dc.b	"ALL",0
rexxtx		dc.b	"REXX:RX",0
clkform		dc.b	' Mem:%7ld Chip:%6ld  %02d:%02d:%02d ',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
oldkick_tx	dc.b	"Needs Kickstart 2.0+",0
nospace_tx	dc.b	"Missing Space",0
redirtwice	dc.b	"Double "
redir_tx	dc.b	"Redirection",0
badprotbit	dc.b	'Unknown flag',0
noclk_tx	dc.b	'No Clock',0
stack_tx	dc.b	'Stack overflow',0
bytes_tx	dc.b	'%ld Bytes',10,0
residetx	dc.b	27,'[36mUsecount  Name',27,'[m',0
rpn_result_tx	dc.b	'RESULT: Dec %ld  Hex $%08lx',10,0
rpn_res2	dc.b	'%ld',0
unmounted_tx	dc.b	'[Un'
mounted_tx	dc.b	'Mounted]',0
assign_tx	dc.b	10,27,'[32mAssigns:',27,'[m',10,0
volume_tx	dc.b	27,'[32mVolumes:',27,'[m',10,0
device1_tx	dc.b	10,27,'[32m',0
device2_tx	dc.b	'Disk-'
device3_tx	dc.b	'Devices:',27,'[m',10,0
lockread	dc.b	'READ',0
lockwrite	dc.b	'WRITE',0
locktext	dc.b	'$%08lx: %s-Lock on ',27,'[32m%s',27,'[m',10,0
numoflocks	dc.b	'%ld locks',10,0
clk_tx		dc.b	'LOAD or SAVE ?',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,T or V',0
show_tx		dc.b	27,'[36mAddress  Pri Name',27,'[m',0
show2_tx	dc.b	27,'[36mAddress  Pri Ver Rev Name',27,'[m',0
shform		dc.b	'%08lx%4d %s',10,0
shform2		dc.b	'%08lx%4d%4d%4d %s',10,0
shta_tx		dc.b	27,'[36mAddress  Pri State SignWait PT '
		dc.b	'Name',27,'[m',0
shtaform	dc.b	'%08lx%4d %-5s %08lx %c%c %s',0
proform		dc.b	32,9,27,'[32m->%sCLI %ld:',27,'[m %s %s%s',0
backcli		dc.b	"Bg-",0
ttyp		dc.b	"Inval",0,"Added",0,"Run",0,"Ready",0
		dc.b	"Wait",0,"Exept",0,"Remov",0
inform_tx	dc.b	27,'[36mName Unit Sys      Size     Free Full '
		dc.b	'Block   Status   Err  Volume',27,'[m',0
inform		dc.b	'%-7s%2ld %-4s%8ldK%8ldK',27,'[37m%4ld%%',27
		dc.b	'[m%6ld %-10s%3ld   %s',10,0
inform2		dc.b	'%-7s%2ld      ',27,'[35m%s',27,'[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
kickdisk	dc.b	"Kick",0
ofs_tx		dc.b	"OFS",0	Old FS
		dc.b	"FFS",0	Fast FS
		dc.b	"OIN",0	International OFS
		dc.b	"FIN",0	International FFS
		dc.b	"ODC",0	Dir Cache OFS
		dc.b	"FDC",0 Dir Cache FFS
;msd_tx		dc.b	"MSD",0	MessyDOS FS
;mufs_tx	dc.b	"MUF",0	MultiUser FS
quest_tx	dc.b	"???",0	Unknown FS
msendtx		dc.b	"sent",0
pra5tx		dc.b	"A5=%08lx",10,0
msgtx		dc.b	"Message=%08lx  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	27,"[37mResult2=%ld  Time=%02d:%02d:%02d.%02d"
		dc.b	"  Changes-> Chip:%ld  Fast:%ld  Total:%ld"
		dc.b	27,"[m",10,0
lowmemtx	dc.b	"Changed %08lx: %08lx -> %08lx",10,0
replytx		dc.b	"Reply? ",0
mem_line	dc.b	"%08lx: %08lx %08lx %08lx %08lx   '%s'",10,0
vec_line	dc.b	"Warm $%08lx MemPtr $%08lx",10
		dc.b	"Cool $%08lx TagPtr $%08lx",10
		dc.b	"Cold $%08lx Check  $%08lx",10,0
formatask	dc.b	"Delete whole disk ? ",0
addbufftx	dc.b	"%s has %ld buffers",10,0
pfeil		dc.b	"-> ",0
flagsoff	dc.b	": OFF",10,0
flagson		dc.b	": ON",10,0
name_tx		dc.b	"Name: ",0

format		dc.b	'%8ld',0	;print a longw right justified
formatADR	dc.b	'$%08lx',0	;print address 
totsize		dc.b	27,'[37mTotal Bytes: %ld  Blocks: %ld   '
		dc.b	'Files: %ld  Dirs: %ld',27,'[m',10,0
dirtext		dc.b	'(Dir)',27,'[m',0
dirof		dc.b	27,'[36mDirectory of ',27,'[m',0
paths		dc.b	"S:",0
msearch		dc.b	12,$9b,'BSearch: ',$9b," p",0
mjump		dc.b	12,$9b,'BJump to %: ',$9b," p",0
mwrite		dc.b	12,$9b,'BWrite to: ',$9b," p",0
wrongsize	dc.b	'New size:',0
makedirOK	dc.b	'created',10,0
copyOK		dc.b	'copied',10,0
moveOK		dc.b	'moved',10,0
processOK	dc.b	'processed',10,0
deleteOK	dc.b	'deleted',10,0
yesnotx		dc.b	'Yes/No/All/Quit ? ',0
memess		dc.b	"Chip: %ld  Fast: %ld  Total Free: %ld",10,0
comp_same	dc.b	"Files are equal",0
diff_size	dc.b	"Different size",0
comp_diff	dc.b	"Files differ at offset %ld",10,0

star		dc.b	"*",0
dot		dc.b	".",0
smaller		dc.b	"<",0
bigger		dc.b	">",0
beep		dc.b	7,0
lf		dc.b	10,0
tab		dc.b	9,0
space		dc.b	" "
null		dc.b	0
farb1		dc.b	27,'[m',0
farb2		dc.b	27,'[32m',0
farb3		dc.b	27,'[33m',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,"H",0
del2eol		dc.b	$9b,"K",0
clrhide		dc.b	12
hide_cursor	dc.b	$9b,"0 p",0
show_cursor	dc.b	$9b," p",0
cutontx		dc.b	$9b,"?7l",0
cutofftx	dc.b	$9b,"?7h",0
menuon_tx	dc.b	$9b,"10{",0
menuoff_tx	dc.b	$9b,"10}",0

	even
recol1	dc.w	residetx+2-stringstart
	dc.w	assign_tx+3-stringstart
	dc.w	volume_tx+2-stringstart
	dc.w	device1_tx+3-stringstart
	dc.w	locktext+21-stringstart
	dc.w	show_tx+2-stringstart
	dc.w	show2_tx+2-stringstart
	dc.w	shta_tx+2-stringstart
	dc.w	proform+4-stringstart
	dc.w	inform_tx+2-stringstart
	dc.w	inform+25-stringstart
	dc.w	inform2+16-stringstart
	dc.w	stat_text+2-stringstart
	dc.w	totsize+2-stringstart
	dc.w	dirof+2-stringstart
	dc.w	farb2+2-stringstart
	dc.w	farb3+2-stringstart
;	dc.w	helpmor+2-stringstart

recol2	;Recolour-table to switch globally to one colour
	dc.b	6,2,2,2,2,6,6,6,2,6,7,5,7,7,6,2,3

comtext	dc.b	2,'AddBuffers',0	V1.27
	dc.b	-1,'Alias',0
	dc.b	-1,'Ask',0		V1.28
	dc.b	3,'Assign',0
	dc.b	1,'Avail',0
	dc.b	2,'Border',0		V2.0
	dc.b	2,'Break',0		V2.0
	dc.b	1,'CD',0
	dc.b	0,'Cls',0		V2.0
	dc.b	4,'Compare',0		V2.9
	dc.b	3,'Config',0		V2.0
	dc.b	-1,'Copy',0
	dc.b	2,'Date',0
	dc.b	-1,'Delete',0
	dc.b	-1,'Dir',0
	dc.b	1,'DiskChange',0	V2.0
	dc.b	-1,'Echo',0
elsetx	dc.b	0,'Else',0		V1.28
endcltx	dc.b	1,'EndCLI',0
endiftx dc.b	0,'EndIf',0		V1.28
	dc.b	-1,'Eval',0
exectx	dc.b	-1,'Execute',0
	dc.b	1,'FailAt',0
	dc.b	1,'Fault',0		V2.0
	dc.b	2,'FileNote',0		V2.0
	dc.b	-1,'Flags',0		V2.3
	dc.b	1,'GetMsg',0		V2.0
	dc.b	1,'Help',0
	dc.b	2,'HType',0		V1.29
iftx	dc.b	3,'If',0		V1.28
	dc.b	0,'Info',0
	dc.b	-1,'Join',0		V1.29
	dc.b	1,'Kill',0		V2.0
labeltx dc.b	1,'Lab',0		V1.29
	dc.b	-1,'List',0
	dc.b	3,'Locate',0		V2.0
	dc.b	2,'Lock',0		V2.0
	dc.b	2,'M',0
	dc.b	-1,'MakeDir',0
	dc.b	2,'MakeIcon',0		V2.3
	dc.b	3,'MakeLink',0		V2.3
clktask	dc.b	2,'MemClk',0		V2.0
	dc.b	-1,'Menu',0		V2.9
	dc.b	2,'More',0		V1.23
	dc.b	-1,'Move',0		V2.3
	dc.b	-1,'NewCLI',0		V2.0
	dc.b	-1,'Path',0
	dc.b	1,'Prompt',0
	dc.b	-1,'Protect',0
	dc.b	-1,'PutMsg',0		V2.0
	dc.b	1,'Quit',0		V1.29
	dc.b	2,'Relabel',0		V1.27
	dc.b	2,'Rename',0
	dc.b	-1,'Resident',0		V1.25
rviewtx	dc.b	2,'Review',0		V2.1
	dc.b	-1,'Run',0		V2.2
	dc.b	2,'Search',0		V2.0
	dc.b	1,'SetClock',0		V2.0
	dc.b	3,'SetDate',0		V2.0
	dc.b	1,'Show',0		V2.0
	dc.b	1,'Skip',0
	dc.b	5,'Split',0		V2.6
	dc.b	1,'Stack',0
	dc.b	2,'Strings',0		V1.29
	dc.b	2,'TaskPri',0		V2.0
	dc.b	1,'Type',0
	dc.b	-1,'UnAlias',0
	dc.b	1,'Wait',0
	dc.b	0,0
	even	

comoffs
	dc.w	addbuffersz-cmdstart
	dc.w	aliasz-cmdstart
	dc.w	askz-cmdstart
	dc.w	assignz-cmdstart
	dc.w	availz-cmdstart
	dc.w	borderz-cmdstart
	dc.w	breakz-cmdstart
	dc.w	cdz-cmdstart
	dc.w	clsz-cmdstart
	dc.w	comparez-cmdstart
	dc.w	configz-cmdstart
	dc.w	copyz-cmdstart
	dc.w	datez-cmdstart
	dc.w	deletez-cmdstart
	dc.w	dirz-cmdstart
	dc.w	diskchangez-cmdstart
	dc.w	echoz-cmdstart
	dc.w	elsez-cmdstart
	dc.w	endcliz-cmdstart
	dc.w	endifz-cmdstart
	dc.w	evalz-cmdstart
	dc.w	executez-cmdstart
	dc.w	failatz-cmdstart
	dc.w	faultz-cmdstart
	dc.w	filenotez-cmdstart
	dc.w	flagsz-cmdstart
	dc.w	getmsgz-cmdstart
	dc.w	helpz-cmdstart
	dc.w	htypez-cmdstart
	dc.w	ifz-cmdstart
	dc.w	infoz-cmdstart
	dc.w	joinz-cmdstart
	dc.w	killz-cmdstart
	dc.w	labelz-cmdstart	;lab
	dc.w	listz-cmdstart
	dc.w	locatez-cmdstart
	dc.w	lockz-cmdstart
	dc.w	memexamz-cmdstart	;m
	dc.w	makedirz-cmdstart
	dc.w	makeiconz-cmdstart
	dc.w	makelinkz-cmdstart
	dc.w	memclkz-cmdstart
	dc.w	menuz-cmdstart
	dc.w	morez-cmdstart
	dc.w	movez-cmdstart
	dc.w	newcliz-cmdstart
	dc.w	pathz-cmdstart
	dc.w	promptz-cmdstart
	dc.w	protectz-cmdstart
	dc.w	putmsgz-cmdstart
	dc.w	quitz-cmdstart
	dc.w	relabelz-cmdstart
	dc.w	renamez-cmdstart
	dc.w	residentz-cmdstart
	dc.w	reviewz-cmdstart
	dc.w	runz-cmdstart
	dc.w	searchz-cmdstart
	dc.w	setclockz-cmdstart
	dc.w	setdatez-cmdstart
	dc.w	showz-cmdstart
	dc.w	skipz-cmdstart
	dc.w	splitz-cmdstart
	dc.w	stackz-cmdstart
	dc.w	stringsz-cmdstart
	dc.w	taskpriz-cmdstart
	dc.w	typez-cmdstart
	dc.w	unaliasz-cmdstart
	dc.w	waitz-cmdstart


ende	end	;***	here it ends	***

