;****** Auto-Revision Header (do not edit) *******************************
;*
;* © Copyright by MMSoftware
;*
;* Filename         : QuickAssign.s
;* Created on       : 01-Oct-93
;* Created by       : M.Meany
;* Current revision : V1.001
;*
;*
;* Purpose: Allows assigns to be quickly set from the Workbench.
;*          
;*                                                    M.Meany (01-Oct-93)
;*          
;*
;* V1.001 : Added better AmigaDOS error handling.
;*          If user-startup does not exsist option is given to create it.
;*                                                    M.Meany (04-Nov-90)
;*          
;* V1.000 : --- Initial release ---
;*
;*************************************************************************
REVISION        MACRO
                dc.b "1.001"
                ENDM
REVDATE         MACRO
                dc.b "04-Nov-90"
                ENDM


	incdir	sys:include/
	include exec/exec.i
	include exec/exec_lib.i

	include libraries/dos.i
	include libraries/dosextens.i
	include libraries/dos_lib.i

	include graphics/gfxbase.i
	include	graphics/graphics_lib.i

	include intuition/intuition.i
	include intuition/intuition_lib.i

	include	devices/console_lib.i
	include devices/inputevent.i
	include	source:include/mmMacros.i
		include		exec/types.i
		include		intuition/classes.i
		include		intuition/classusr.i
		include		intuition/imageclass.i
		include		intuition/gadgetclass.i
		include		libraries/gadtools.i
		include		libraries/gadtools_lib.i
		include		libraries/asl.i
		include		libraries/asl_lib.i
		include		graphics/displayinfo.i
		include		graphics/gfxbase.i


		include		misc/easystart.i

_SysBase	equ		4

		lea		Variables,a5		a5->var base
	
		move.l		a0,_args(a5)		save addr of CLI args
		move.l		d0,_argslen(a5)		and the length

		bsr.s		Openlibs		open libraries
		tst.l		d0			any errors?
		beq.s		no_libs			if so quit

		bsr		Init			Initialise data
		tst.l		d0			any errors?
		beq.s		no_libs			if so quit

		bsr		Openwin			open window
		tst.l		d0			any errors?
		beq.s		no_win			if so quit

		bsr		WaitForMsg		wait for user

no_win		bsr		Closewin		close our window

		bsr		DeInit			free resources

no_libs		bsr		Closelibs		close open libraries

		rts					finish


;**************	Open all required libraries

; If d0=0 on return then one or more libraries are not open.

Openlibs	lea		dosname,a1		a1->lib name
		moveq.l		#36,d0			WB2 or higher
		CALLEXEC	OpenLibrary		and open it
		move.l		d0,_DOSBase		save base ptr
		beq.s		.lib_error		quit if error

		lea		intname,a1		a1->lib name
		moveq.l		#36,d0			WB2 or higher
		CALLSYS		OpenLibrary		and open it
		move.l		d0,_IntuitionBase	save base ptr
		beq.s		.lib_error		quit if error

		lea		gfxname,a1		a1->lib name
		moveq.l		#36,d0			WB2 or higher
		CALLSYS		OpenLibrary		and open it
		move.l		d0,_GfxBase		save base ptr
		beq.s		.lib_error		quit if error

		lea		gadtoolsname,a1
		moveq.l		#36,d0			WB2 or higher
		CALLSYS		OpenLibrary		and open it
		move.l		d0,_GadToolsBase	save base ptr
		beq.s		.lib_error		quit if error

		lea		utilityname,a1
		moveq.l		#36,d0			WB2 or higher
		CALLSYS		OpenLibrary		and open it
		move.l		d0,_UtilityBase		save base ptr
		beq.s		.lib_error		quit if error

		lea		aslname,a1
		moveq.l		#36,d0			WB2 or higher
		CALLSYS		OpenLibrary		and open it
		move.l		d0,_AslBase		save base ptr

.lib_error	rts

*************** Initialise any data

;--------------	At present just check for usage request from CLI

Init		tst.l		returnMsg		from WorkBench?
		bne.s		.ok			yes, ignore usage

		move.l		_args(a5),a0		get addr of CLI args
		cmpi.b		#'?',(a0)		is the first arg a ?
		bne.s		.ok			no, skip next bit

		lea		_UsageText,a0		a0->the usage text
		bsr		DosMsg			and display it
.err		moveq.l		#0,d0			set an error
		bra.s		.error			and finish

;--------------	Your Initialisations should start here

; Get VisualInfo for gadtools use

.ok		bsr		SetupScreen		prep GadTools
		tst.l		d0
		bne.s		.err			exit if errors

; Allocate a Load file requester structure from asl

		moveq.l		#ASL_FileRequest,d0
		lea		ASLLOADTAGS(pc),a0
		CALLASL		AllocAslRequest
		move.l		d0,LoadRequest(a5)		

; Set flag to signal not adding to user-startup just yet!

		move.w		#0,WriteFlag(a5)

.error		rts					back to main

; Tag list supplied to AslRequest in above routine. Note we are specifying a
;requester that can select drawers only and ignores double-click selections!

ASLLOADTAGS	dc.l		ASLFR_TitleText,LoadTitle
		dc.l		ASLFR_Flags2,FRF_DRAWERSONLY
		dc.l		ASLFR_Flags1,FRF_DOSAVEMODE
		dc.l		TAG_DONE		

LoadTitle	dc.b		'Assign to Drawer...',0
		even

*************** Open An Intuition Window

; Opens an intuition window. If d0=0 on return then window could not be
;opened.

; Call function generated by GadToolsBox

Openwin		bsr		OpenMarksWindow
		tst.l		d0
		beq.s		.GotWin
		moveq.l		#0,d0
		bra.s		.done

; Get pointers to important window related structures

.GotWin		move.l		MarksWnd,a0		   a0->win struct
		move.l		a0,win.ptr(a5)		   save window ptr
		move.l		wd_UserPort(a0),win.up(a5) save up ptr
		move.l		wd_RPort(a0),win.rp(a5)    save rp ptr

; Activate the string gadget ready for next input

		move.l		MarksGadgets,a0
		move.l		win.ptr(a5),a1
		suba.l		a2,a2
		CALLINT		ActivateGadget

		moveq.l		#1,d0			no errors

.done		rts					all done so return

*************** Deal with User interaction

; Uses gadtools functions to get and reply messages.

WaitForMsg	move.l		win.up(a5),a0		a0->user port
		CALLEXEC	WaitPort		wait for message
		move.l		win.up(a5),a0		a0->user port
		CALLGAD		GT_GetIMsg		get any messages
		tst.l		d0			was there a message ?
		beq.s		WaitForMsg		if not loop back
		move.l		d0,a1			a1-->message
		move.l		im_Class(a1),d2		d2=IDCMP flags
		move.l		im_IAddress(a1),a4 	a4=addr of structure
		CALLSYS		GT_ReplyIMsg		answer os

; Was this a gadget up message?

		cmp.l		#GADGETUP,d2
		bne.s		_test_win
		
		moveq.l		#0,d0			clear
		move.w		gg_GadgetID(a4),d0	get gadget ID
		asl.l		#2,d0			x4 = LONG offset
		lea		GadgetVectors(pc),a0	->vector table
		move.l		(a0,d0),a0		get function vector

		jsr		(a0)			call function

; See if user has decided to quit.

_test_win	cmp.l		#CLOSEWINDOW,d2  	window closed ?
		bne.s		WaitForMsg	 	if not then jump

; Give them a chance to change their mind.

		lea		QuitMsg,a0
		bsr		TFReq
		tst.l		d0
		beq.s		WaitForMsg

		rts

; Vector table used to locate function for a gadget based on it's ID.

GadgetVectors	dc.l		DoLoad		0
		dc.l		NoFunction	1
		dc.l		NoFunction	2
		dc.l		DoWrite		3
		
NoFunction	rts

**************	User has entered a string, set an assign!

; Display name of assign given by user

DoLoad		move.l		MarksGadgets,a0		a0->string gadget
		move.l		gg_SpecialInfo(a0),a0	a0->String Info
		move.l		(a0),NameHere		set name pointer
		move.l		(a0),DStream(a5)
		
		lea		MarksGadgets,a0
		move.l		4(a0),a0		gadget
		move.l		win.ptr(a5),a1		window
		suba.l		a2,a2			no requester
		lea		TextTAGS,a3
		CALLGAD		GT_SetGadgetAttrsA	refresh title

; Use file requester to select a directory

		move.l		LoadRequest(a5),d0
		beq		.done

; Obtain name of directory to assign
		
		move.l		d0,a0			request
		suba.l		a1,a1			no tags
		CALLASL		AslRequest		file request
		tst.l		d0
		beq		.done			cancel selected

; Display name of directory selected

		move.l		LoadRequest(a5),a0
		move.l		fr_Drawer(a0),NameHere
		move.l		fr_Drawer(a0),DStream+4(a5)

		lea		MarksGadgets,a0
		move.l		8(a0),a0		gadget
		move.l		win.ptr(a5),a1		window
		suba.l		a2,a2			no requester
		lea		TextTAGS,a3
		CALLGAD		GT_SetGadgetAttrsA	refresh title

; Build string that will make the assign

		lea		.template,a0		Template
		lea		DStream(a5),a1		DataStream
		lea		.PutC(pc),a2		PutChar routine
		lea		RDFBuffer(a5),a3	dest buffer
		CALLEXEC	RawDoFmt

; Now execute the string

		lea		RDFBuffer(a5),a0
		move.l		a0,d1
		moveq.l		#0,d2
		moveq.l		#0,d3
		CALLDOS		Execute

; Add string to user-startup if flag is set

		tst.w		WriteFlag(a5)
		beq		.done

	; open s:user-startup
		
		move.l		#.user,d1
		move.l		#MODE_OLDFILE,d2
		CALLDOS		Open
		move.l		d0,d7			save handle
		bne.s		.UserOpen
	
	; could not open file, determine why!
	
		CALLSYS		IoErr
		cmp.l		#205,d0			'Object not found'?
		bne.s		.ShowError

	; 'User-Startup' does not exsist, give user chance to create it!
	
		lea		.startuptext(pc),a0
		bsr		TFReq			use requester
		tst.l		d0
		beq		.done
	
	; Lets make a 'User-Startup' file for them
	
		move.l		#.user,d1
		move.l		#MODE_NEWFILE,d2
		CALLSYS		Open
		move.l		d0,d7			save handle
		bne.s		.UserOpen

	; Still no user-startup, time to give up!

		CALLSYS		IoErr
	
	; UserStartup cannot be accessed, show user the DOS error
	
.ShowError	move.l		d0,d1			error message
		lea		.header(pc),a0
		move.l		a0,d2			header text
		lea		RDFBuffer(a5),a0
		move.l		a0,d3			dest buffer
		moveq.l		#127,d4			buffer length
		CALLSYS		Fault
		tst.l		d0			get a message?
		beq.s		.error			nope, just quit!

		lea		RDFBuffer(a5),a0
		bsr		OKReq
		bra.s		.error

	; move to end of file

; NOTE: Cannot check for errors on Seek() as CBM made a cock up in the V36 &
; V37 ROMs. Seek() returns current position instead of -1 when an error
; occurs ... The AmigaDOS Manual is wrong ;-)
	
.UserOpen	move.l		d7,d1
		moveq.l		#0,d2
		moveq.l		#OFFSET_END,d3
		CALLSYS		Seek

	; write a line feed to the file .. now check for errors!

		move.l		d7,d1
		move.l		#.lf,d2
		moveq.l		#1,d3
		CALLSYS		Write
		cmp.l		#-1,d0		byte written ?
		bne.s		.UserWriteable

	; Byte no written to file, inform user and exit!

		CALLSYS		IoErr
		bra.s		.ShowError
		
	; file is writeable, so add the assign

.UserWriteable	move.l		d7,d1
		lea		RDFBuffer(a5),a0
		move.l		a0,d2

	; determine length of assign string and write it to file

		moveq.l		#-1,d3
.UserLoop	addq.l		#1,d3
		tst.b		(a0)+
		bne.s		.UserLoop
		CALLSYS		Write
	
	; write a line feed to the file

		move.l		d7,d1
		move.l		#.lf,d2
		moveq.l		#1,d3
		CALLSYS		Write
		
	; close the file
	
.error		move.l		d7,d1
		beq.s		.done			exit if no lock
		CALLDOS		Close
		
; Reactivate the string gadget ready for next input

.done		move.l		MarksGadgets,a0
		move.l		win.ptr(a5),a1
		suba.l		a2,a2
		CALLINT		ActivateGadget

		moveq.l		#0,d2
		rts

; The following function is called by RawDoFmt() and copies each byte as it
;is generated into the destintion buffer.

.PutC		move.b		d0,(a3)+
		rts

; The template passed to RawDoFmt() that generates the CLI command we need.

.template	dc.b		'assign "%s" "%s"',0
		even
		
; Name of file to add the assign to

.user		dc.b		's:user-startup',0
		even

; A single line feed byte

.lf		dc.b		$0a
		even

; A couple of error messages

.startuptext	dc.b		"The file 's:user-startup' does not exsist!",$0a
		dc.b		'         I can create one for you?',0
		even

.header		dc.b		'AmigaDOS error',0
		even

; TAGs used to set the text displayed in info gadgets

TextTAGS	dc.l		GTTX_Text
NameHere	dc.l		NoDataLoaded
		dc.l		TAG_DONE

NoDataLoaded	dc.b		'Error!',0
		even

***************	Toggle write enable flag

DoWrite		not.w		WriteFlag(a5)

; Reactivate the string gadget ready for next input

		move.l		MarksGadgets,a0
		move.l		win.ptr(a5),a1
		suba.l		a2,a2
		CALLINT		ActivateGadget

		moveq.l		#0,d2
		rts

*************** Close the Intuition window.

; Calls the function generated by GadToolsBox

Closewin	bsr		CloseMarksWindow

		rts

***************	Release any additional resources used

DeInit		bsr		CloseDownScreen

; Free file requester structures

.NoFile		move.l		LoadRequest(a5),d0
		beq.s		.done
		move.l		d0,a0
		CALLASL		FreeAslRequest

.done		rts

***************	Close all open libraries

; Closes any libraries the program managed to open.

Closelibs	move.l		_DOSBase,d0		d0=base ptr
		beq.s		.lib_error		quit if 0
		move.l		d0,a1			a1->lib base
		CALLEXEC	CloseLibrary		close lib

		move.l		_IntuitionBase,d0	d0=base ptr	
		beq.s		.lib_error		quit if 0
		move.l		d0,a1			a1->lib base
		CALLSYS		CloseLibrary		close lib

		move.l		_GfxBase,d0		d0=base ptr
		beq.s		.lib_error		quit if 0
		move.l		d0,a1			a1->lib base
		CALLSYS		CloseLibrary		close lib

		move.l		_GadToolsBase,d0	d0=base ptr
		beq.s		.lib_error		quit if 0
		move.l		d0,a1			a1->lib base
		CALLSYS		CloseLibrary		close lib

		move.l		_UtilityBase,d0		d0=base ptr
		beq.s		.lib_error		quit if 0
		move.l		d0,a1			a1->lib base
		CALLSYS		CloseLibrary		close lib

		move.l		_AslBase,d0		d0=base ptr
		beq.s		.lib_error		quit if 0
		move.l		d0,a1			a1->lib base
		CALLSYS		CloseLibrary		close lib

.lib_error	rts

*****************************************************************************
*			Useful Subroutines Section					    *
*****************************************************************************

**************	OK requester

; This should be used a general information requester.

; Entry		a0->text string

; Exit		none

; Corrupt	d0

OKReq		PUSHALL

		lea		.TheEasy,a1		EasyStruct
		move.l		a0,es_TextFormat(a1)	set text
		
		move.l		win.ptr(a5),a0		Window
		suba.l		a2,a2			No IDCMP
		suba.l		a3,a3
		CALLINT		EasyRequestArgs		display it

.done		PULLALL
		rts

.TheEasy	dc.l		es_SIZEOF
		dc.l		0			no flags
		dc.l		0			title
		dc.l		0			text
		dc.l		.Gadgets

.Gadgets	dc.b		'Ok',0
		even

**************	True/False requester

; This should be used to obtain Yes/No responses from the user.

; Entry		a0->text string

; Exit		d0=result 1=true( OK ), 0=false( Cancel )

; Corrupt	d0

TFReq		PUSHALL

		lea		.TheEasy,a1		EasyStruct
		move.l		a0,es_TextFormat(a1)	set text
		
		move.l		win.ptr(a5),a0		Window
		suba.l		a2,a2			No IDCMP
		suba.l		a3,a3
		CALLINT		EasyRequestArgs		display it

.done		PULLALL
		rts

.TheEasy	dc.l		es_SIZEOF
		dc.l		0			no flags
		dc.l		0			title
		dc.l		0			text
		dc.l		.Gadgets

.Gadgets	dc.b		'Ok|Cancel',0
		even

**************	General CLI printing routine

; Entry		a0 must hold address of 0 terminated message.
;		DOS library must be open

DosMsg		movem.l		d0-d3/a0-a3,-(sp) 	save registers

		move.l		a0,d1			format string
		lea		DStream(a5),a0
		move.l		a0,d2			Data Stream
		CALLDOS		VPrintf

		movem.l		(sp)+,d0-d3/a0-a3	restore registers
		rts

		include		assign.i

*****************************************************************************
*			Data Section					    *
*****************************************************************************

; Program revision details. Can be viewed using 'version' command.

		dc.b		'$VER: QuickAssign v'
		REVISION
		dc.b		', © M.Meany ('
		REVDATE
		dc.b		')',0
		even

; Names of all libraries used by this program

dosname		dc.b		'dos.library',0
		even
intname		dc.b		'intuition.library',0
		even
gfxname		dc.b		'graphics.library',0
		even
gadtoolsname	dc.b		'gadtools.library',0
		even
utilityname	dc.b		'utility.library',0
		even
aslname		dc.b		'asl.library',0
		even

; Usage text displayed in shell when requested

_UsageText	dc.b		$0a
		dc.b		'QuickAssign v'
		REVISION
		dc.b		', © M.Meany ('
		REVDATE
		dc.b		')',$0a
		dc.b		$0a
		dc.b		'Set up assigns from the WorkBench.'
		dc.b		$0a,$0a,0
		even

; Text displayed when user decides to quit

QuitMsg		dc.b		'Quit the program?',0
		even

;***********************************************************
;	SECTION	Vars,BSS
;***********************************************************

		rsreset
_args		rs.l		1
_argslen	rs.l		1

win.ptr		rs.l		1
win.rp		rs.l		1
win.up		rs.l		1

LoadRequest	rs.l		1

DStream		rs.l		2

RDFBuffer	rs.b		160

WriteFlag	rs.w		1

varsize		rs.b		0

		SECTION	Vars,BSS

_DOSBase	ds.l		1
_IntuitionBase	ds.l		1
_GfxBase	ds.l		1
_GadToolsBase	ds.l		1
_UtilityBase	ds.l		1
_AslBase	ds.l		1

Variables	ds.b		varsize

