;----------------------------------------------------------------------------
;File name:	ESel.S				Revision date:	1996.08.22
;Creator:	Ulf Ronald Andersson		Creation date:	1996.08.22
;(c)1996 by:	Ulf Ronald Andersson		All rights reserved
;----------------------------------------------------------------------------
;
;;;huge_program		= 1	;uncomment if TEXT+DATA sections are > 32KB
;;;keep_windows		= 1	;uncomment to keep ACC vwk in main eventloop
;;;exec_timeout		= 100	;uncomment to enable timer in main eventloop
;;;exec_message		= 1	;uncomment for messages in main eventloop
;
;----------------------------------------------------------------------------
ES_CUR_VER	=	0001
ES_INT_VER	=	0001
ES_MAGIC	=	'ESel'
ESD_MAGIC	=	'ESel'
;
ES_magic	=	0	;.L == ES_MAGIC
ES_cur_ver	=	4	;.W == Version code of current ESel
ES_int_ver	=	6	;.W == Version code of Esel interface
ES_interface	=	8	;.L -> ESel interface function
ES_size		=	256
;
ESD_magic	=	0	;.L == ESD_MAGIC
ESD_cur_ver	=	4	;.W == Version code of current ESel lib
ESD_int_ver	=	6	;.W == Version code of ESel lib interface
ESD_size	=	256
;
;----------------------------------------------------------------------------
;
	output	.PRG
;
	include	URAn_DOS.S
	include	URAn_SIM.S
	include	URAn_LA.S
	include	URAn_AV.S
	include	URAn_XB.S
	include URAn_JAR.S
	include	LVAR.S
;
;;;	include	ESel_Ck.S	;Cookie jar def's for ESel
;
;----------------------------------------------------------------------------
;
	SECTION	TEXT
;
	include	URAn_APP.S
;
;----------------------------------------------------------------------------
;
	ifnd	huge_program
	SECTION	DATA
	endc
;
acc_name:	dc.b	'  Acc name',NUL	;for ACC menu registration
		dc.b	NUL
;
;----------------------------------------------------------------------------
;
	ifnd	huge_program
	SECTION	BSS
	endc
;
message:	ds.w	8		;evnt_mesag message pipe
intin:		ds.w	30		;30 words or more for AES/VDI
intout:		ds.w	45		;45 words or more for AES/VDI
ptsin:		ds.w	30		;30 words or more for VDI
ptsout:		ds.w	12		;12 words or more for VDI output coordinates
		ds.l	200		;subroutine stack >= 100 longs
mystack:	ds.l	1		;top of subroutine stack
;
;----------------------------------------------------------------------------
;
	SECTION	TEXT
;
;----------------------------------------------------------------------------
;	Constants, Variables, and Usage of the URAn_APP.S library
;
;rz		'relative zero' for internal references
;basepage_p	-> program's base page
;tsr_size	.L size of BASEPAGE+TEXT+DATA+BSS  (only TOS/TTP may TSR)
;progtype	.L indicates program type:
;  ...			$0000.$FFFF == TOS/TTP/boot_PRG
;  ...			$0000.ap_id == APP/GTP/non_boot_PRG
;  ...			$FFFF.ap_id == ACC
;acc_flag	is the high word of 'progtype'
;tos_flag	is the low word of 'progtype'
;bootflag	.W $FFFF == PRG booted from AUTO (also sets 'tos_flag')
;menu_id	.W menu id for an ACC, otherwise null
;g_handle	.W workstation handle for ACC/APP/GTP/non_boot_PRG
;vwk_handle	.W virtual workstation handle
;contrl		12 words for AES/VDI control data
;
;wk_x_rez \
;wk_y_rez  \/ from
;wk_pix_w  /\ opnvwk
;wk_pix_h /
;
;MiNT_p		.L NULL or -> MiNT structure
;MagX_p		.L NULL or -> MagX structure
;nAES_p		.L NULL or -> nAES structure
;Gnva_p		.L NULL or -> Gnva structure
;
;line_a_base_p	.L -> line_a variable base
;kbshift_p	.L -> kbshift byte of OS
;currbp_p_p	.L -> OS var -> current basepage
;
;NB: if symbol 'huge_program' is defined, above data is in TEXT section (else in BSS)
;NB: defining 'huge_program' also makes function calls use 'jsr' (instead of bsr)
;
;Required user routines:
;
;init_app	called for ACC/APP/GTP/non_boot_PRG to init application,
;		but doesn't need appl_init, graf_handle, or v_opnvwk,
;		nor does an ACC need menu_register.
;		Suitable use is for initialization of object trees.
;NB:  for ACC	menu_register is called between init_app and exec_app
;
;exec_app	called to execute the main application regardless of type,
;		but doesn't need v_clsvwk, or appl_exit, or ACC appl_mesag.
;		This call will be repeated for a reactivated ACC.
;		Non_acc programs should have exit code in d0 at RTS.
;		(See details at 'Exit codes:' below)
;
;	At entry to either of these two routines:
;
;		d6.W	== bootflag	\
;		d7.L	== progtype	 > See descriptions above.
;		a6.L	== rz		/
;
;Optional user routines:
;
;exec_timer	Called for ACC that has a defined constant 'exec_timeout',
;		whenever evnt_multi produces such a timer event.
;		The constant is placed as long at 'main_timeout', and may
;		there be dynamically adjusted by the program.
;
;exec_mesag	Called for ACC that has a defined constant 'exec_message',
;		whenever evnt_multi/evnt_mesag produces messages that are
;		not AC_OPEN  (such as VA_START).
;
;		If the constant 'keep_windows' is also set, the workstation
;		will not be closed at each return (you must obey AC_CLOSE).
;		This places a word == $FF00 at 'keep_wind_f', and if the top
;		byte is cleared the workstation closure is enabled again.
;
;NB:	Top bit of the word 'revise_type_f' is used for 3 purposes:
;   1:	Let ACC start 'exec_app' directly without awaiting event.
;   2:	Let APP delay 'exec_app' until an event occurs.
;   3:	Let APP loop back for more events after 'exec_app'
;The flag must be set by 'init_app' in the first two cases, and in case 3
;should be set/cleared in 'exec_app' to decide whether to exit program.
;
;Exit codes:	At exit from exec_app, d0 has the following effects
;		when the program was not started as accessory.
;
; negative	=> Pterm(d0)			=> error code exit
; 0		=> Pterm(d0)			=> error free exit
; 0x0000ADD0	=> Ptermres(tsr_size,0)		=> error free resident exit
; 0x0000ADD1	=> Ptermres(d1,0)		=> error free resident exit
; 0x0000ADD2	=> Ptermres(d1,d2)		=> error code resident exit
;
;----------------------------------------------------------------------------
;Start of:	init_app
;----------------------------------------------------------------------------
;
init_app:
	include	URAn_ARG.S
	xbios	Supexec,init_main(pc)
	rts
;
;----------------------------------------------------------------------------
;End of:	init_app
;----------------------------------------------------------------------------
;	URAn_ARG.S defines two variables
;
;arg_cnt	== number of strings on command line
;arg_ptr	-> NUL_separated argument strings + final NUL
;
;NB:	Both of the above include a dummy program name (first string==NUL).
;----------------------------------------------------------------------------
;Start of:	exec_app
;----------------------------------------------------------------------------
;
exec_app:
exit_exec_app:
	tst.b	restarted_f-rz(a6)
	bne.s	use_old_ESel
	tst.b	TSR_flag
	bne.s	set_new_ESel
	gemdos	Cconws,cookie_err_s
	move.l	err_code-rz(a6),d0
	rts
;
;------------------------------------
;
set_new_ESel:
.exit:
	move.l	#$ADD0,d0
	rts
;
;------------------------------------
;
use_old_ESel:
	clr.l	-(sp)
	move.l	ESel_Ck_p-rz(a6),a0
	move.l	ES_interface(a0),a0
	jsr	(a0)
	addq	#4,sp
.exit:
	clr.l	d0
	rts
;
;----------------------------------------------------------------------------
;End of:	exec_app
;----------------------------------------------------------------------------
;Start of:	exec_timer
;----------------------------------------------------------------------------
;
	ifd	exec_timeout	;cond:	ifd exec_timeout
exec_timer:
exit_exec_timer:
	rts
	endc			;ends:	ifd exec_timeout
;
;----------------------------------------------------------------------------
;End of:	exec_timer
;----------------------------------------------------------------------------
;Start of:	exec_mesag
;----------------------------------------------------------------------------
;
	ifd	exec_message	;cond:	ifd exec_message
exec_mesag:
	cmp	#AC_CLOSE,message
	beq	exec_mesag_AC_CLOSE
;
	bra	exit_exec_mesag
;
exec_mesag_AC_CLOSE:
	sf	keep_wind_f
exit_exec_mesag:
	rts
	endc			;ends:	ifd exec_message
;
;----------------------------------------------------------------------------
;End of:	exec_mesag
;----------------------------------------------------------------------------
;Start of:	init_main	Supexec subroutine
;----------------------------------------------------------------------------
;
init_main:
	make_cookie	#'ESel',ESel_Ck_p(pc)
	move.l		d0,err_code
	spl		TSR_flag
	bpl.s		.exit
	move.l		d0,ESel_Ck_p
	cmp		#E_ACCDN,d0
	seq		restarted_f
.exit:
	rts
;
;----------------------------------------------------------------------------
;End of:	init_main
;----------------------------------------------------------------------------
;Start of:	ES_interface_code
;----------------------------------------------------------------------------
;
ES_interface_code:
	lv_init	a6			;a6 -> lvars of ES_interface_code
	movem.l	d1-d7/a1-a5,-(sp)
	lea	rz(pc),a5		;a5 -> global code base
;
	moveq	#E_OK,d1		;d1 = E_OK
	move.l	8(a6),d0		;d0 =  argument -> struct ESD
	beq.s	.use_default
	blt.s	.bad_default
	btst	#0,d0
	beq.s	.try_ESD
.bad_default:
	moveq	#E_IMBA,d1		;d1 =  Invalid Memory Block Access
	bra.s	.exit_ret_d1
;
.use_default:
	lea	def_ESD-rz(a6),a4	;a4 -> default ESD structure
	bra.s	.have_ESD
;
.try_ESD:
	move.l	d0,a4			;a5 -> callers ESD structure
	cmp.l	#'ESel',ESD_magic(a4)
	beq.s	.have_ESD
.bad_ESD:
	moveq	#E_INVFN,d1		;d1 = INValid FuNction
	bra.s	.exit_ret_d1
;
.have_ESD:
;;;patch ES_interface_code here
	bra.s	.exit_ret_a4
;
.exit_ret_d1:
	move.l	d1,a4
.exit_ret_a4:
	move.l	a4,a0
	movem.l	(sp)+,d1-d7/a1-a5
	lv_exit	a6
	move.l	a0,d0
	rts				;exit with a0 = d0 as -> ESD
;
;----------------------------------------------------------------------------
;End of:	ES_interface_code
;----------------------------------------------------------------------------
;
	make	AV_links
	make	SIM_links
	make	JAR_links
;
;----------------------------------------------------------------------------
;
text_limit:	section	DATA
;
;----------------------------------------------------------------------------
;Enter program constant definitions below:
;
		dc.l	'ESel','_Ck:'
ESel_Ck:	dc.l	ES_MAGIC
		dc.w	ES_CUR_VER
		dc.w	ES_INT_VER
		dc.l	ES_interface_code
		ds.b	ES_size-(*-ESel_Ck)
;
		dc.l	'def_','ESD:'
def_ESD:	dc.l	ESD_MAGIC
		ds.b	ESD_size-(*-def_ESD)
;
err_code:	dc.l	0	;set to code after error
ESel_Ck_p:	dc.l	ESel_Ck
;
;
;------------------------------------
;	Place unaligned bytes below
;------------------------------------
;
restarted_f:	dc.b	0	;set at E_ACCDN from make_cookie
TSR_flag:	dc.b	0	;set at E_OK from make_cookie
;
;------------------------------------
;	Place strings below
;------------------------------------
;
cookie_err_s:
	dc.b	CR,LF
	dc.b	CR,LF,' The ESel cookie could not be installed'
	dc.b	CR,LF,' at this time, so ESel will not work.'
	dc.b	CR,LF,NUL
;
;------------------------------------
;
		EVEN
;
;----------------------------------------------------------------------------
;
data_limit:	SECTION	BSS
;
;----------------------------------------------------------------------------
;Enter program variable definitions below:
;
;
;----------------------------------------------------------------------------
bss_limit:	END
;----------------------------------------------------------------------------
;End of file:	ESel.S
;----------------------------------------------------------------------------
