*=- PROGRAM INFORMATION -=*************************************************************
* CDOpus, ©1996 Leo Davidson							      *
*=====================================================================================*
* Purpose: Conversion of the CDO.dopus5 and OCD.dopus5 scripts.			      *
*	   This program can CD to the path of the current DOpus5 source lister...     *
*	   ...or open a new lister with the same path as your shell.		      *
*	  (...and it does and bunch of other usefull Shell<->DOpus things too...)     *
***************************************************************************************
*   To Do: Make the HELP/S text pause when it fills up the shell window.	      *
*          See ASM:Routines/UnUsed/Window_Rows.s for my comments about this.	      *
***************************************************************************************

*=- ASSEMBLE-TIME SWITCHES -=**********************************************************
* Comment out to disable the effect(s) described.                                     *
***************************************************************************************
;Beta_Version		; Include Debug-Labels, Beta messages, etc.
;Beta_Version_ARexx	; Include runtime-info about ARexx messages sent.
;Test_Pool_On_OS3	; Force use of non-ROM pool routines, even with OS3+.
DOpus5_Error		; Enable Error messages via DOpus5/"dopus request".
;No_Requesters		; Disable all requester-based output.
			; All error messages will be sent to shell.
			; Will also turn off "Please insert volume XXX" reqs.
Default_Req		; Make requesters the default for error messages.

*=- VERSION INFORMATION -=*************************************************************
* Things like versions numbers, dates, and the name of the program are all defined    *
* here as macros to save having to edit the entire source code.                       *
*=====================================================================================*
* The version strings should conform to the style guide. (Even though I think it      *
* isn't the best way to do it, it's a standard :-(  ).                                *
***************************************************************************************
PROGNAM	MACRO				Program name.
	dc.b	"CDOpus"		/No spaces!/
	ENDM
VERSION	MACRO				The version of the program.
	dc.b	"1.7"			version.revision - /No leading zeros/
	ENDM
REVDATE	MACRO				Date of completion.
	dc.b	"6.1.96"		DD.MM.YY - /No leading zeros/
	ENDM
REVDAT2	MACRO				Date of completion.
	dc.b	"06-Jan-1996"		/Any format/ (Not in $VER string)
	ENDM
*=- ASSEMBLER INFORMATION/OPTIONS -=***************************************************
	Section	Super_Main,Code		Assemble to Public Memory.
	IFD	Beta_Version		-.
	Opt	D+			 |
	Opt	hcln			 |_ Debug info ON
	ELSE				 |  for Beta Versions.
	Opt	D-			 |
	ENDC				-'
***************************************************************************************
	Bra	ProgBeg			Jump to the start of the program.
***************************************************************************************
VerStr	Dc.b	"$VER: "		-.
	PROGNAM				 |
	IFD	Beta_Version		 |
	Dc.b	"_DEBUG"		 |
	ENDC				 |_ For 2.0+ Version Command
	Dc.b	" "			 |  (At the top to make "Version"
ActVer	VERSION				 |  find it quicker!)
	Dc.b	" ("			 |
	REVDATE				 |
	Dc.b	")",0			-'
	Even
;=====================================================================================;
;	Include	Asm:Include/Nudel_Constants.i
;
;	include	dos/dos.i
;	include	dos/var.i
;	include	exec/types.i
;	include	exec/nodes.i
;	include	exec/memory.i
;	include	rexx/storage.i
;	include	intuition/intuition.i
;	include	intuition/intuitionbase.i
;	include	libraries/iffparse.i
;
;	include	ASM:LVO3.0/dos_lib.i
;	include	ASM:LVO3.0/exec_lib.i
;	include	ASM:LVO3.0/intuition_lib.i
;	include	ASM:LVO3.0/rexxsyslib_lib.i
;	include	ASM:LVO3.0/utility_lib.i
;	include	ASM:LVO3.0/iffparse_lib.i
;	include	ASM:LVO3.0/mathieeedoubbas_lib.i
;	include	ASM:LVO3.0/graphics_lib.i

	Include	Nudel_Symbols.gs
***************************************************************************************
* The Variables (Address Equates for Space allocated at program start)                *
***************************************************************************************
	RSReset
	IFND	No_Requesters
;=====================================================================================;
N_EasyStruct	Equ	__RS		;- EasyStruct for EasyRequest ----------------;
;=====================================================================================;
N_ES_Length	Rs.l	1		Length of the structure.
N_ES_Flags	Rs.l	1		Flags (not currently supported).
N_ES_Title	Rs.l	1		Ptr to NullTerm Title Text.
N_ES_Body	Rs.l	1		Ptr to NullTerm Body Text.
N_ES_Gadgets	Rs.l	1		Prt to Gadget(s) Texts.
N_EasyStruct_Len	Equ	(__RS)-N_EasyStruct
	ENDC

;=====================================================================================;
; Nudel Info-Block Stuff							      ;
;=====================================================================================;
FakeNIB		Rs.b	NIB_SizeOf	;- Fake NIB for setting pseudo-filenames -----;
FakeNIB_Adrs	Rs.l	1		Address of FakeNIB (saves a few "lea"'s).
Active_NIB	Rs.l	1		Ptr to currently "Active" NIB, or null.
Base_NIB	Rs.l	1		Ptr to base NIB in linked list, or null.
Last_NIB	Rs.l	1		Ptr to last NIB in linked list, or null.
CAction		Rs.l	1		Ptr to current "Action" error message.
;-------------------------------------------------------------------------------------;
CD_NIB		Rs.l	1		NIB for locking of new CurrentDir
;=====================================================================================;

;=====================================================================================;
; READARGS() STUFF								      ;
;=====================================================================================;
RDA_Rtn		Rs.l	1		Pointer to returned RDArgs structure
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
RDA_Array	Equ	__RS		Array of longwords matching template
RDA_Template	Equ	*
RexxPort_K	Rs.l	1
		Dc.b	"RP=REXXPORT/K,"
Help_S		Rs.l	1
		Dc.b	"HELP/S,"
Quiet_S		Rs.l	1
		Dc.b	"QUIET/S,"
OpenLister_S	Rs.l	1
		Dc.b	"OL=OPENLISTER/S,"
ReadSource_S	Rs.l	1
		Dc.b	"RS=READSOURCE/S,"
ReadDest_S	Rs.l	1
		Dc.b	"RD=READDEST/S,"
DoAction_S	Rs.l	1
		Dc.b	"DA=DOACTION/S,"
NoFront_S	Rs.l	1
		Dc.b	"NOFRONT/S,"
NoNew_S		Rs.l	1
		Dc.b	"NONEW/S,"
Dir_K		Rs.l	1
		Dc.b	"DIR=PATH/K,"
Source_S	Rs.l	1
		Dc.b	"SOURCE/S,"
Dest_S		Rs.l	1
		Dc.b	"DEST/S,"
Lock_S		Rs.l	1
		Dc.b	"LOCK/S,"
Dimensions_K	Rs.l	1
		Dc.b	"POS=DIMENSIONS/K,"
ActPat_K	Rs.l	1
		Dc.b	"PAT=ACTPAT/K,"
ActCom_K	Rs.l	1
		Dc.b	"COM=ACTCOM/K,"
ActClose_S	Rs.l	1
		Dc.b	"ACTCLOSE/S,"
VarSource_S	Rs.l	1
		Dc.b	"VARSOURCE/S,"
VarDest_S	Rs.l	1
		Dc.b	"VARDEST/S,"
Global_S	Rs.l	1
		Dc.b	"GLOBAL/S"
RDA_Temp_Len	Equ	*-RDA_Template
		Dc.b	0
		Even
; Pseudo-Switch (setup in "Setup" routine).
NoReq_S		Rs.l	1

;=====================================================================================;
; OPEN_LIBRARIES STRUCTURES							      ;
;=====================================================================================;
LibBases_Start	Equ	__RS
LibData_Start	Equ	*
; NOTE: The open_lib_error routine requires lib-versions < 100
N_DOSBase	Rs.l	1
DOSName_Ptr	Dc.l	N_DOSName-LibNames_Start
DOSVers		Dc.l	37
N_RexBase	Rs.l	1
RexName_Ptr	Dc.l	N_RexName-LibNames_Start
RexVers		Dc.l	0
	IFND	No_Requesters
N_IntBase	Rs.l	1
IntBase_Ptr	Dc.l	N_IntName-LibNames_Start
IntVers		Dc.l	37
	ENDC
LibBases_Finish	Equ	__RS
NumLibs	Equ	(LibBases_Finish-LibBases_Start)/4
;-------------------------------------------------------------------------------------;
LibNames_Start	Equ	*
N_DOSName	DOSNAME
N_RexName	REXXSYSLIBNAME
	IFND	No_Requesters
N_IntName	INTNAME		Required by Open_Libraries_Error rtn.
	ENDC
	Even
;=====================================================================================;
; FLAG BYTES									      ;
;=====================================================================================;
STD_F_1		Rs.b	1		Standard files.
EVEN_F_1	Rs.b	1		(Here as an Even)
;=====================================================================================;
; VARIOUS DATA									      ;
;=====================================================================================;
DosRtnC		Rs.l	1		Return code for DOS. (-> d0 at end)
;=====================================================================================;
; RawDoFmt() Stuff								      ;
;=====================================================================================;
;	IFD	DATA_RAWDOFMT
RDF_Size	Rs.l	1		Size of RawDoFmt() buffer.
RDF_Adrs	Rs.l	1		Address of RawDoFmt() buffer.
RDF_Array	Equ	__RS
RDF_1_Long	Rs.l	1		-.
RDF_2_Long	Rs.l	1		 |_ DataArray
RDF_3_Long	Rs.l	1		 |  for RawDoFmt()
RDF_4_Long	Rs.l	1		-'
;	ENDC
;=====================================================================================;
; VARIOUS ADDRESS-POINTERS							      ;
;=====================================================================================;
StarStk		Rs.l	1		Original Stack Pointer.
PoolHead	Rs.l	1		Header for program's memory pool.
CLI_Hdl		Rs.l	1		Output CLI (or whatever) handle.
NudelPort	Rs.l	1		Pointer to our MsgPort.
NudelRexxMsg	Rs.l	1		Pointer to our RexxMsg.
CRexxPort	Rs.l	1		Ptr to name of current Rexx host to talk to.
;=====================================================================================;
; TEMP STORAGE									      ;
;=====================================================================================;
Buffer1Len	Equ	1024
Buffer1		Rs.b	Buffer1Len	Buffer for anything
Buffer2Len	Equ	1024
Buffer2		Rs.b	Buffer2Len	Buffer for anything
	IFD	Beta_Version_ARexx
BufferALen	Equ	1024
BufferA		Rs.b	BufferALen	Buffer for ARexx beta messages.
	ENDC
PathBuffer1Len	Equ	512
PathBuffer1	Rs.b	PathBuffer1Len
Source_HandleLen Equ	42
Source_Handle	Rs.b	Source_HandleLen
Temp001		Rs.l	1		-._ For temp storage
Temp002		Rs.l	1		-'  in routines.
;=====================================================================================;
NULLEND		Equ	__RS		;- Overlays Start Here -----------------------;
;=====================================================================================;
;=====================================================================================;
LENVARS		Equ	__RS		;- End of variables/overlays -----------------;
;=====================================================================================;

*=- MAIN PROGRAM -=********************************************************************
* Calls the subroutines.							      *
***************************************************************************************
ProgBeg	Bsr.s	Setup			Allocate Mem and initialize stuff.
	Bsr	Help			Send help text, if requested.
	Bsr.s	Choose_Routine		Call the appropriate routine.
	Bra	Finish			Close/Deallocate everything and exit.
***************************************************************************************
Choose_Routine
	Tst.l	OpenLister_S(a5)
	Beq.s	Choose_S1
	Bra	Get_CD_And_Open_Do_It_OpenLister
Choose_S1
	Tst.l	ReadSource_S(a5)
	Beq.s	Choose_S2
	Bra	Get_CD_And_Open_Do_It_ReadSource
Choose_S2
	Tst.l	ReadDest_S(a5)
	Beq.s	Choose_S3
	Bra	Get_CD_And_Open_Do_It_ReadDest
Choose_S3
	Tst.l	VarSource_S(a5)
	Beq.s	Choose_S4
	Bra	Set_Source_Env_Do_It
Choose_S4
	Tst.l	VarDest_S(a5)
	Beq.s	Choose_S5
	Bra	Set_Dest_Env_Do_It
Choose_S5
	Tst.l	DoAction_S(a5)
	Beq.s	Choose_S6
	Bra	Do_Action_Do_It
Choose_S6
	Bra	Get_Path_And_Change_Do_It

*=- SETUP -=***************************************************************************
* Allocate Memory, Open Libraries, Parse Commandline, etc			      *
* This MUST be the first Subroutine run.					      *
***************************************************************************************
Setup	Move.l	#MEMF_PUBLIC!MEMF_CLEAR,d0	Public, Cleared mem.
	Move.l	#5120,d1			Puddle size = 5k.
	Move.l	#5120,d2			Thresh size = Puddle size.
	Bsr	AsmCreatePool			Create this prog's mem pool.
	Move.l	a0,-(SP)		Preserve PoolHeader
	Bne.s	SGotMm1			-.
	Addq.l	#4,a7			 |_ If Allocation failed, Quick Exit.
	Moveq	#RETURN_FAIL,d0		 |  pool and do a quick exit.
	RTS				-'
SGotMm1	Move.l	#LENVARS,d0		Size of variables' memory
;;;;;;;	Move.l	a0,a0			PoolHeader to a0 for allocation.
	Bsr	AsmAllocPooled		Allocate for the variables.
	Move.l	(SP)+,a0		Restore PoolHeader
	Move.l	d0,a5			Put variable/overlay address into A5
	Tst.l	d0			(Moves to a? don't set CCR).
	Bne.s	SGotMm2			-.
	Bsr	AsmDeletePool		 |
	Addq.l	#4,a7			 |- If Allocation failed, delete the
	Moveq	#RETURN_FAIL,d0		 |  pool and do a quick exit.
	RTS				-'
SGotMm2	Move.l	a0,PoolHead(a5)		Store header of memory pool.
	Lea	FakeNIB(a5),a0		-._ Store address of FakeNIB(a5)
	Move.l	a0,FakeNIB_Adrs(a5)	-'  for quick access later.
	Move.l	#RETURN_OK,DosRtnC(a5)	Default DOS return code: "OK".
	IFD	LENOVER
	Lea	NULLEND(a5),a0		-.
	Lea	Over01(pc),a1		 |  Copy Overlay
	Move.l	#(LENOVER/2)-1,d0	 |- Backings onto
OverPrL	Move.w	(a1)+,(a0)+		 |  Overlay Space (word moves)
	DBra	d0,OverPrL		-'
	ENDC
;=====================================================================================;
	Move.l	a7,StarStk(a5)		Store Stack Pointer
	Addq.l	#4,StarStk(a5)		Compensate for this being a subrout.
	IFND	No_Requesters
	SetReqDefault			Set default to requester/shell.
	ENDC
	Bsr	Open_Libraries		Open libraries.
	N_CallDOS	Output		-._ Get output Handle
	Move.l	d0,CLI_Hdl(a5)		-'  (CLI window or whatever)

;;;;;;;	Setup any non-zero default values for switch options here (below).
	Bsr	RArgNor			Parse the commandline with ReadArgs
;=====================================================================================;
	Tst.l	NoNew_S(a5)
	Bne.s	NoNew_S_Skip
	BSet	#SF1_NewListers,STD_F_1(a5)	Get(Source|Dest)Handle: Allow new listers
NoNew_S_Skip
	Tst.l	RexxPort_K(a5)			-._ If RexxPort not given on CmdLine,
	Beq.s	Setup_RP_UseDef			-'  use the default one.
	Move.l	RexxPort_K(a5),CRexxPort(a5)	Else, use RexxPort from CmdLine.
	Bra.s	Setup_RP_UsedCmd
Setup_RP_UseDef
	Lea	Def_RexxPort(pc),a0
	Move.l	a0,CRexxPort(a5)
Setup_RP_UsedCmd

	Tst.l	ReadSource_S(a5)		-.
	Bne.s	Dont_KillReqs			 |
	Tst.l	ReadDest_S(a5)			 |_ If any of the Shell->Opus commands,
	Bne.s	Dont_KillReqs			 |  leave Error-Requesters ON.
	Tst.l	OpenLister_S(a5)		 |
	Bne.s	Dont_KillReqs			-'
	Move.l	#1,NoReq_S(a5)			Else, all Errors to the shell.
Dont_KillReqs
	Bra.s	CreateNudelPort		Create our MsgPort.
;;;;;;;	RTS for us.

Def_RexxPort
	Dc.b	"DOPUS.1",0
	Even

*=- FINISH -=**************************************************************************
* Close Everything Down, Return Memory Etc to System and End Program		      *
*=====================================================================================*
* All routines in this section MUST make sure that what they are about to free back   *
* to the system has actually been taken in the first place! (With the exception of    *
* the Main-Variable memory: if this could not be allocated the program will have      *
* quit without calling Finish.)							      *
*=====================================================================================*
* The Finish routine may be called from sub-routines at any level because the	      *
* original stack-pointer is restored so that RTS always quits the prog.		      *
***************************************************************************************
Finish
	IFD	Beta_Version
	Bsr_ErrorN	ErrAct_FinishBetaMsg(pc),#0
	ENDC

	Bsr	DeleteNudelRexxMsg	Delete our RexxMsg (also clears arguments).
	Bsr.s	DeleteNudelPort		Delete our MsgPort
	Bsr	NIBs_DeleteAll		Delete all Nudel-Info-Blocks :-)
	Bsr	FArgNor			Free the commandline related memory.
	Bsr	Close_Libraries		Close all open libraries.
	Move.l	StarStk(a5),a7		Ignore all Branches.
	Move.l	DosRtnC(a5),-(SP)	Store DOS return code...
	Bsr	LeoDeletePool		Free the entire memory pool.
	Move.l	(SP)+,d0		Return code to d0 for DOS.
	RTS				End Program

	IFD	Beta_Version
ErrAct_FinishBetaMsg
	Dc.b	"Finish routine run",0
	Even
	ENDC

*=- EXTERNAL SUB-ROUTINES -=***********************************************************
* Sub-routines stored in external "library" files.				      *
***************************************************************************************
;=====================================================================================;
; OS Subroutines.								      ;
;=====================================================================================;
SYS_CLIRITE	; Write text using CLI_Hdl(a5) as output handle.
SYS_READARG	; ReadArgs() routine.
SYS_FREEARG	; FreeArgs() routine.
SYS_CHKCRTC	; Check for ^C-Break and abort program if sent.
SYS_PORTS	; CreateMsgPort(), DeleteMsgPort() routines.
	Include	ASM:Source/Routines/System.s
;=====================================================================================;
; Data Subroutines. (Number/String Handling, etc etc)				      ;
;=====================================================================================;
DATA_NULLLEN	; Calculate the length of a Null-Term String.
DATA_COPYCN3	; Copy chars with Null-Term, don't copy Null, no Length
DATA_CHARCNT	; Copy x chars with Null-Term
DATA_CHARCOPNL	; Copy x chars with Null-Term and specified terminator.
DATA_NUM2ASC	; Raw Number to ASCII conversion.
DATA_RAWDOFMT	; RawDoFmt() routine.
	Include	ASM:Source/Routines/Data.s
;=====================================================================================;
; NudelInfoBlock Subroutines.							      ;
;=====================================================================================;
NIBR_UNLOCK	; DOS/UnLock
NIBR_LOCK	; DOS/Lock
	Include	ASM:Source/Routines/NIB.s
;=====================================================================================;
; Directory Opus 5 Subroutines.							      ;
;=====================================================================================;
DO5_GetSource	; Get first source handle.
DO5_GetDest	; Get first destination handle.
DO5_GetDest_OnlyToBuffer
DO5_GetPath	; Get the path of a lister.
DO5_NewLister	; Open a new lister.
DO5_SetPath	; Set (read) a new path into a lister.
DO5_ListerSet	; Generic "Lister Set..." routine.
DO5_Command	; Generic "command..." routine.
DO5_GenError	; Error message for things which really shouldn't go wrong.
DO5_ListerWait	; Wait for a lister to finish what it's doing.
DO5_DOpusFront	; Move the DOpus screen to the front, unless "NoFront/S"
DO5_ListClose	; Close a lister (does "wait" first).
	Include	ASM:Source/Routines/DOpus5_ARexx.s
;=====================================================================================;
; Other routines.								      ;
;=====================================================================================;
	Include	ASM:Source/Routines/ARexx.s
	Include	ASM:Source/Routines/Pool.s
	Include	ASM:Source/Routines/OpenLibraries.s

*=- HELP -=****************************************************************************
* Send the help text and exit if they gave that switch to ReadArgs()		      *
***************************************************************************************
Help	Tst.l	Help_S(a5)		Have they asked for help on cmd line?
	Bne.s	Help_
	RTS				If not, return.
Help_
	Lea	HelpTxt(pc),a0		-.
	Move.l	#HelpLen,d3		 |- Output Help Text.
	Bsr	CLIRite			-'
	Bra	Finish			Finish the program.
;-------------------------------------------------------------------------------------;
HelpTxt	Dc.b	10,155,"32;1m"
	PROGNAM
	Dc.b	" "
	VERSION
	Dc.b	" ",155,"0m[",155,"33m"
	REVDAT2
	Dc.b	155,"0m] ",155,"32m- ",155,"33m© Leo ",155,"0m'Nudel'",155,"33m Davidson",155,"32m for Gods'Gift Utilities",155,"0m",10
	Dc.b	10
	Dc.b	155,"0;32mThis program can CD to the path of the current DOpus5 ",155,"4msource",155,"0;32m lister,",10
	Dc.b	155,"0;32;1mor ",155,"0;32mread the shell's path into a new lister or the ",155,"4msource",155,"0;32m/",155,"4mdest",155,"0;32m lister.",10
	Dc.b	155,"0m100% Assembler Code for AmigaOS 2 or above - ",155,"1mMay be made resident.",155,"0m",10
	Dc.b	155,'0mType "CDOpus ?" for ReadArgs() command template.',10
	Dc.b	10
	Dc.b	155,"0;33mGeneric:",10
	Dc.b	" ",155,"43;32m RexxPort   ",155,'0m  Specify a differnt port to talk to, instead of "DOPUS.1".',10
	Dc.b	" ",155,"43;32m Help       ",155,"0m  ",155,"3mSwitch: ",155,"0mBrings up this text.",10
	Dc.b	155,"0;33mModes:",10
	Dc.b	" ",155,"43;32m <DEFAULT>  ",155,"0m  CD to 'source' lister's path.",10
	Dc.b	" ",155,"43;32m OpenLister ",155,"0m  ",155,"3mSwitch: ",155,"0mRead path into a new lister.",10
	Dc.b	" ",155,"43;32m DoAction   ",155,"0m  ",155,"3mSwitch: ",155,"0mRead path into new 'source' lister.",10
	Dc.b	" ",155,"43;32m ReadSource ",155,"0m  ",155,"3mSwitch: ",155,"0mRead path into the 'source' lister.",10
	Dc.b	" ",155,"43;32m ReadDest   ",155,"0m  ",155,"3mSwitch: ",155,"0mRead path into the 'dest' lister.",10
	Dc.b	" ",155,"43;32m VarSource  ",155,"0m  ",155,"3mSwitch: ",155,"0mSet CDOSource environment variable.",10
	Dc.b	" ",155,"43;32m VarDest    ",155,"0m  ",155,"3mSwitch: ",155,"0mSet CDODest environment variable.",10
	Dc.b	155,"0;33mCD mode only:",10
	Dc.b	" ",155,"43;32m Quiet      ",155,"0m  ",155,"3mSwitch: ",155,"0mDon't echo the new path to the shell.",10
	Dc.b	155,"0;33mOpenLister/DoAction/Read modes only:",10
	Dc.b	" ",155,"43;32m NoFront    ",155,"0m  ",155,"3mSwitch: ",155,"0mDon't pop the DOpus screen to front.",10
	Dc.b	" ",155,"43;32m Dir        ",155,"0m  Specify a different directory to read, instead of <CD>.",10
	Dc.b	155,"0;33mOpenLister mode only:",10
	Dc.b	" ",155,"43;32m Source     ",155,"0m  ",155,"3mSwitch: ",155,"0mMake new lister the 'Source' lister.",10
	Dc.b	" ",155,"43;32m Dest       ",155,"0m  ",155,"3mSwitch: ",155,"0mMake new lister the 'Dest' lister.",10
	Dc.b	" ",155,"43;32m Lock       ",155,"0m  ",155,"3mSwitch: ",155,"0mLock new lister as Source/Dest.",10
	Dc.b	155,"0;33mOpenLister/DoAction modes only:",10
	Dc.b	" ",155,"43;32m Dimensions ",155,"0m  Specify different lister dimensions in x/y/w/h format.",10
	Dc.b	155,"0;33mDoAction mode only:",10
	Dc.b	" ",155,"43;32m ActPat     ",155,"0m  Specify files to select.",10
	Dc.b	" ",155,"43;32m ActCom     ",155,"0m  Specify DOpus5 command to execute.",10
	Dc.b	" ",155,"43;32m ActClose   ",155,"0m  ",155,"3mSwitch: ",155,"0mClose lister on completion.",10
	Dc.b	155,"0;33mRead modes only:",10
	Dc.b	" ",155,"43;32m NoNew      ",155,"0m  ",155,"3mSwitch: ",155,"0mDisable automatic openning of new listers.",10
	Dc.b	155,"0;33mVar mode only:",10
	Dc.b	" ",155,"43;32m Global     ",155,"0m  ",155,"3mSwitch: ",155,"0mSet global variable instead of local.",10
	Dc.b	10
HelpLen	Equ	*-HelpTxt
	Even

***************************************************************************************
* Routine for getting the Source Lister's path and CD'ing to it.		      *
***************************************************************************************
Get_Path_And_Change_Do_It
	Sub.l	d0,d0			Abort if there isn't a source lister.
	Bsr	GetSourceHandle		Source handle -> Source_Handle(a5)

	Lea	Source_Handle(a5),a0	Handle to get path of.
	Lea	PathBuffer1(a5),a1	-._ Buffer to
	Move.w	#PathBuffer1Len,d7	-'  write into.
	Bsr	GetListerPath		Lister path -> PathBuffer1(a5)
;-------------------------------------------------------------------------------------;
	Tst.l	Quiet_S(a5)		-._ Skip output of new dir
	Bne.s	Quiet_Skip		-'  if "Quiet" switch given.

	Lea	PathBuffer1(a5),a0	New path...
	Move.l	a0,d2			To d2 to CLIRit2
	Bsr	NullLen			Find length...
	Move.l	d0,d3			...to d3.
	Bsr	CLIRit2			Output to the shell.
	Lea	Return_Char(pc),a0	-.
	Moveq	#Return_Char_Len,d3	 |- Write a return after it.
	Bsr	CLIRite			-'
	Bra.s	Quiet_Skip
Return_Char
	Dc.b	10
Return_Char_Len Equ *-Return_Char
	Even
Quiet_Skip
;-------------------------------------------------------------------------------------;
; For CD to be complete, must call BOTH SetCurrentDir() and SetCurrentDirName()	      ;
;-------------------------------------------------------------------------------------;
	Bsr	Create_NIB		Create a new NudelInfoBlock for Lock()ing...
	Move.l	Active_NIB(a5),a1	NIB Pointer to a1
	Move.l	a1,CD_NIB(a5)		Store our NIB pointer.

	Lea	PathBuffer1(a5),a2	-._ Pointer to returned path as
	Move.l	a2,NIB_NameAdrs(a1)	-'  the filename of our new NIB.

	Move.l	CD_NIB(a5),Active_NIB(a5)	Make it active.
	Moveq	#ACCESS_READ,d2			Do a read (shared) lock.
	Bsr	Lock_NIB			Get a lock() on the path.
	Tst.l	d0
	Beq_ErrorE	ErrAct_Lock(pc),Active_NIB(a5)

	Move.l	CD_NIB(a5),a0
	Move.l	NIB_Lock(a0),d1
	N_CallDOS	CurrentDir	Set new current dir.
	Move.l	CD_NIB(a5),a0
	Move.l	d0,NIB_Lock(a0)		Replace lock with the old CD's lock.
;;;;;;;	(We must unlock the OLD CD's lock, but not the lock of the CD we set)
	Move.l	CD_NIB(a5),Active_NIB(a5)	-._ Delete the CD_NIB, which
	Bsr	Delete_NIB			-'  includes UnLock()'ing.
;-------------------------------------------------------------------------------------;
	Lea	PathBuffer1(a5),a0
	Move.l	a0,d1				New dir path -> d1 for SetCDN()
	Move.l	d1,NIB_NameAdrs+FakeNIB(a5)	Set pseudo-filename in FakeNIB.
	N_CallDOS	SetCurrentDirName
	Tst.l	d0
	Beq_ErrorE	ErrAct_SetCurrentDirName(pc),FakeNIB_Adrs(a5)
;-------------------------------------------------------------------------------------;
	RTS

ErrAct_SetCurrentDirName
	Dc.b	"Could not set current directory name",0
	Even

***************************************************************************************
* Routine for getting the current dir and openning a new Lister in it.		      *
***************************************************************************************
;-------------------------------------------------------------------------------------;
ErrAct_GetCurrentDirName
	Dc.b	"Could not find the current directory",0
	Even
;=====================================================================================;
; ReadSource variant.								      ;
;=====================================================================================;
Get_CD_And_Open_Do_It_ReadSource
	Moveq	#1,d0			Open new source if one doesn't exist.
	Bsr	GetSourceHandle			Source handle -> Source_Handle(a5)
	Bra.s	Get_CD_And_Open_Do_It_Read_Main	Rest as for ReadDest

;=====================================================================================;
; ReadDest variant.								      ;
;=====================================================================================;
Get_CD_And_Open_Do_It_ReadDest
	Moveq	#1,d0			Open new dest if one doesn't exist.
	Lea	Source_Handle(a5),a1		-.
	Move.w	#Source_HandleLen,d7		 |- Dest handle -> Source_Handle(a5)
	Bsr	GetDestHandle_ToBuffer		-'
Get_CD_And_Open_Do_It_Read_Main
	Bsr	DOpusFront			DOpus screen to front.
	Bsr.s	Get_CD_And_Open_Get_Path	Path -> a0
	Move.l	a0,a1				Path -> a1
	Lea	Source_Handle(a5),a0		Handle -> a0
	Sub.l	d0,d0				Don't force into current path buffer.
	Bsr	ReadListerPath			Make the lister read the new path.
	RTS

;=====================================================================================;
; OpenLister variant.								      ;
;=====================================================================================;
Get_CD_And_Open_Do_It_OpenLister
	Bsr.s	Get_CD_And_Open_Get_Path	Path -> a0
	Move.l	Dimensions_K(a5),a1		Dimensions, or NULL (valid).
	Lea	Source_Handle(a5),a2		-._ Buffer to write
	Move.w	#Source_HandleLen,d7		-'  handle into.
	Bsr	NewLister			Open the new lister.
Get_CD_And_Open_MAIN
	Lea	Source_Handle(a5),a0		Lister handle.
	Sub.l	a1,a1				Default to "off" (not source or dest)
	Sub.l	a2,a2				Default to "unlocked"

	Tst.l	Source_S(a5)			-.
	Beq.s	Source_S_Skip			 |- "Source", if requested,
	Lea	Set_Source_SubCommand(pc),a1	-'  else check for "Dest"
	Bra.s	Dest_S_Skip
Source_S_Skip	
	Tst.l	Dest_S(a5)			-.
	Beq.s	Get_CD_ListerSet_Skip		 |- "Dest", if requested,
	Lea	Set_Dest_SubCommand(pc),a1	-'  else don't do a set at all.
Dest_S_Skip
	Tst.l	Lock_S(a5)			-.
	Beq.s	Lock_S_Skip			 |- "Lock", if requested.
	Lea	Set_Lock_SubCommand(pc),a2	-'
Lock_S_Skip
	Bsr	ListerSet			Set Source/Dest/Lock.
Get_CD_ListerSet_Skip
;-------------------------------------------------------------------------------------;
	RTS

;=====================================================================================;
; Point a0 to CD or Dir_S.							      ;
;=====================================================================================;
Get_CD_And_Open_Get_Path
	Tst.l	Dir_K(a5)			Did they specify a directoy?
	Bne.s	Get_CD_Use_Dir_K		If so, use it, else get CurrentDir.
	Lea	PathBuffer1(a5),a0		-._ Buffer to write
	Move.l	a0,d1				-'  CurrentDir into.
	Move.l	#PathBuffer1Len,d2		Size of the Buffer.
	N_CallDOS	GetCurrentDirName	CD -> Buffer.
	Tst.l	d0
	Beq_ErrorE	ErrAct_GetCurrentDirName(pc),#0
	
	Lea	PathBuffer1(a5),a0		Path to read.
	RTS
Get_CD_Use_Dir_K
	Move.l	Dir_K(a5),a0			Path to read.
	RTS

***************************************************************************************
* Routine for getting the Dest Lister's path and setting the CDOSource variable	      *
***************************************************************************************
Set_Dest_Env_Do_It
	Sub.l	d0,d0			Abort if there isn't a dest lister.

	Lea	Source_Handle(a5),a1		-.
	Move.w	#Source_HandleLen,d7		 |- Dest handle -> Source_Handle(a5)
	Bsr	GetDestHandle_ToBuffer		-'

	Lea	Source_Handle(a5),a0	Handle to get path of.
	Lea	PathBuffer1(a5),a1	-._ Buffer to
	Move.w	#PathBuffer1Len,d7	-'  write into.
	Bsr	GetListerPath		Lister path -> PathBuffer1(a5)
;-------------------------------------------------------------------------------------;
	Lea	Dest_Var_Name(pc),a0	Name of variable to set.
	Bra.s	SSE_Com			Rest common to Set_Source_Env.

***************************************************************************************
* Routine for getting the Source Lister's path and setting the CDOSource variable     *
***************************************************************************************
Set_Source_Env_Do_It
	Sub.l	d0,d0			Abort if there isn't a source lister.
	Bsr	GetSourceHandle		Source handle -> Source_Handle(a5)

	Lea	Source_Handle(a5),a0	Handle to get path of.
	Lea	PathBuffer1(a5),a1	-._ Buffer to
	Move.w	#PathBuffer1Len,d7	-'  write into.
	Bsr	GetListerPath		Lister path -> PathBuffer1(a5)
;-------------------------------------------------------------------------------------;
; Now we set the variable.							      ;
;-------------------------------------------------------------------------------------;
	Lea	Source_Var_Name(pc),a0	-._ Name of
SSE_Com	Move.l	a0,d1			-'  Variable
	Lea	PathBuffer1(a5),a0	-._ Buffer containing
	Move.l	a0,d2			-'  the path string.
	Moveq	#-1,d3			Buffer is null-terminated.

	Move.l	#GVF_LOCAL_ONLY,d4	Specify local variable...
	Tst.l	Global_S(a5)		Did they ask for a global variable?
	Beq.s	SSEDING			If not, leave it as local.
	Move.l	#GVF_GLOBAL_ONLY,d4	Else, set it to a global variable.
SSEDING
	Move.l	d1,NIB_NameAdrs+FakeNIB(a5)	Set pseudo-filename in FakeNIB.
	N_CallDOS	SetVar			Set the variable.
	Tst.l	d0
	Beq_ErrorE	ErrAct_SetEnvVar(pc),FakeNIB_Adrs(a5)
	RTS

Source_Var_Name
	Dc.b	"CDOSource",0
Dest_Var_Name
	Dc.b	"CDODest",0
ErrAct_SetEnvVar
	Dc.b	"Could not set environment variable ",0
	Even


***************************************************************************************
* Routine for reading path into new Source lister, selecting files + running command. *
***************************************************************************************
Do_Action_Do_It
	Bsr	Get_CD_And_Open_Get_Path	Path -> a0
	Move.l	Dimensions_K(a5),a1		Dimensions, or NULL (valid).
	Lea	Source_Handle(a5),a2		-._ Buffer to write
	Move.w	#Source_HandleLen,d7		-'  handle into.
	Bsr	NewLister			Open the new lister.

	Lea	Source_Handle(a5),a0		Lister handle.
	Lea	Set_Source_SubCommand(pc),a1	Make it the source lister.
	Sub.l	a2,a2				("unlocked")
	Bsr	ListerSet			Set lister as Source
;-------------------------------------------------------------------------------------;
; If the path is buffered by Opus it could have some files selected, so command none. ;
;-------------------------------------------------------------------------------------;
	Lea	Source_Handle(a5),a0		Lister handle.
	Lea	Command_None_SubCommand(pc),a1	"none"
	Sub.l	a2,a2				No second argument.
	Bsr	ListerCommand			De-select all files.
	Lea	Source_Handle(a5),a0		-._ Lister wait
	Bsr	ListerWait			-'  is required.

;-------------------------------------------------------------------------------------;
; Select files in the new lister if a pattern was given on the command line.	      ;
;-------------------------------------------------------------------------------------;
	Tst.l	ActPat_K(a5)		-._ Skip if no select
	Beq.s	DADI_SP			-'  pattern given.

	Lea	Source_Handle(a5),a0			Lister handle
	Lea	Command_Select_SubCommand(pc),a1	"select name"
	Move.l	ActPat_K(a5),a2				Pattern to select.
	Bsr	ListerCommand				Select the entries.
	Lea	Source_Handle(a5),a0		-._ Lister wait
	Bsr	ListerWait			-'  is required.

	Bra.s	DADI_SP
Command_Select_SubCommand
	Dc.b	"select name",0
Command_None_SubCommand
	Dc.b	"none",0
	Even
DADI_SP
;-------------------------------------------------------------------------------------;
; Issue command if one was given on the command line.				      ;
;-------------------------------------------------------------------------------------;
	Tst.l	ActCom_K(a5)		-._ Skip if no
	Beq.s	DADI_SK			-'  command given.

	Lea	Source_Handle(a5),a0	Lister handle.
	Move.l	ActCom_K(a5),a1		Command to issue.
	Sub.l	a2,a2			No second argument.
	Bsr	ListerCommand

DADI_SK
;-------------------------------------------------------------------------------------;
; Close the lister now, if requested to (handles lister-wait by itself).	      ;
;-------------------------------------------------------------------------------------;
	Tst.l	ActClose_S(a5)		-._ Skip if not asked
	Beq.s	DADI_SC			-'  to close the lister.
	Lea	Source_Handle(a5),a0	Lister handle.
	Bsr	ListerClose		Close the lister.	
DADI_SC
;-------------------------------------------------------------------------------------;
	RTS
***************************************************************************************
