
****************************************************
********   ZSHELL (C) 1990,91 Paul Hayter   ********
********  updated to V2.2 by Martin Gierich ********
******** 	ZShell-Starter (ZSH)	    ********
****************************************************

* 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 !



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

VERSION			equ	$1234

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

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

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

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

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

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

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

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

* LIBRARY CALLS
* EXEC
_LVOOldOpenLibrary	equ	-408
_LVOOpenLibrary		equ	-552
_LVOCloseLibrary	equ	-414
_LVOSetFunction		equ	-420
_LVOAllocMem		equ	-198
_LVOFreeMem		equ	-210
_LVORawDoFmt		equ	-522
_LVORawMayGetChar	equ	-510
_LVOFindTask		equ	-294
_LVOAddTask		equ	-282
_LVOForbid		equ	-132
_LVOPermit		equ	-138
_LVOAvailMem		equ	-216
_LVOPutMsg		equ	-366
_LVOGetMsg		equ	-372
_LVOReplyMsg		equ	-378
_LVOWaitPort		equ	-384
_LVOSetSignal		equ	-306
_LVOAllocSignal		equ	-330
_LVOFreeSignal		equ	-336
_LVOOpenDev		equ	-444
_LVOCloseDev		equ	-450
_LVODoIO		equ	-456

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

*Intuition
_LVOPrintIText		equ	-216
_LVODisplayBeep		equ	-96

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


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

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

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

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

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



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

;	SECTION	MYSHELL,CODE
	
;Try to open dos then do the shell
start	moveq	#-1,d7
	move.l	a0,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
	lea	pr_MsgPort(a2),a0
	jsr	_LVOWaitPort(a6)	!!!
	lea	pr_MsgPort(a2),a0
	jsr	_LVOGetMsg(a6)
	move.l	d0,wb_msg(a5)
	beq.s	.C
	move.l	d0,a0
	clr.l	sm_Segment(a0)		Clear Seg-Descriptor
.C	move.l	pr_StackSize(a2),stacksize(a5)
	move.l	pr_SegList(a2),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	crerror
lookres	lea	ZShellName(pc),a4
	bsr	search_res2
	lea	start-4(pc),a1
	tst.l	d0
	beq.s	cresi
	lsl.l	#2,d0
	move.l	d0,a2
	nop
	nop
VCheck	cmp.w	#VERSION,VCheck-start+6(a2)
	bne.w	crerror
	addq.l	#1,resi_usecount(a0)
	cmp.l	a1,d0
	beq.s	crerror		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	lea	ZShellCom(pc),a0
	move.l	a0,d1
	jsr	_LVOLoadSeg(a6)
	lea	ZShellName(pc),a4
	move.l	d0,d3
	beq.s	crerror
	bsr	create_resi	make zshell resident
	bne.s	crerror
	bra.s	lookres

crerror	lea	console(pc),a0	output a message
	move.l	a0,d1
	move.l	#1005,d2
	jsr	_LVOOpen(a6)	on a simple CON: window
	move.l	d0,d4
	beq.s	crfail
	move.l	d0,d1
	lea	errtx(pc),a0
	move.l	a0,d2
	move.l	#errtxend-errtx,d3
	jsr	_LVOWrite(a6)
	moveq	#120,d1
	jsr	_LVODelay(a6)	wait a bit
	move.l	d4,d1
	jsr	_LVOClose(a6)
crfail	move.l	dosbase(a5),a1	bad error occured
	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
	

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
	bsr	compD1D0nocase
	dbne	d3,.B
	bne.s	.E	not equal
	tst.b	(a1)
	beq.s	.C	the (null-)END
.E	move.l	a2,d2
	move.l	resi_link(a2),d0	get link
	bne.s	.A
.D	moveq	#0,d0
	rts
.C	move.l	resi_seglist(a2),d0	get seglist
	move.l	a2,a0
	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

compD1D0nocase
	cmp.b	#'a',d1
	blo.s	D1_OK
	cmp.b	#'z',d1
	bhi.s	D1_OK
	sub.b	#$20,d1
D1_OK	cmp.b	#'a',d0
	blo.s	D0_OK
	cmp.b	#'z',d0
	bhi.s	D0_OK
	sub.b	#$20,d0
D0_OK	cmp.b	d1,d0
	rts

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

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

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
	
ZShellCom	dc.b	'C:'
ZShellName	dc.b	'ZShell',0
console		dc.b	'CON:100/20/450/80/$VER: ZSH 2.2 (02.01.95)',0
errtx		dc.b	'Please copy "ZShell" to C: !'
errtxend
dosname		dc.b	'dos.library',0
intuiname	dc.b	'intuition.library',0

	end
****************************************************************

