;:ts=8
;
; Initial startup routine for Aztec 'C' and ARP using RESIDENT.
; NB: This should allow access to all Aztec Features, math, etc.
;     Could be made smaller if only for CLI, only for Workbench,
;     Could be made smaller if only this or that.
;
; Created 02-18-88 by -+=SDB+=- from arpcrt0.s
; Copyright (c) 1988 by Scott Ballantyne, may be freely
; used by Arp Supporters/users.
; Use at your own risk.
;
; NB: References to the ___fromdisk__ long have to be handled carefully,
;     since they are somewhat shizophrenic, sometimes referring to copied
;     data, sometimes not.  Note that they should fine for the C code without
;     special handling as long as small model is used.
;
; 10-Mar-90:	Put together from resgeta4.s & arprescrt0.s for
;		Aztec 5.0 release.

	include "exec/types.i"
	include "exec/execbase.i"
	include "exec/tasks.i"
	include "exec/alerts.i"
	include "libraries/arpbase.i"

call	macro
	xref	_LVO\1
	jsr	_LVO\1(a6)
	endm

	entry	.begin
	public	.begin
	public	_geta4

*	If you need more or less stack, change the first number below
*	For example, if your program only needs 4000 bytes of stack, the
*	line below would read:
*	RESIDENT 4000,__H2_end-__H1_org,loaded

.begin
	RESIDENT 14096,__H2_end-__H1_org,loaded

	move.l	a4,a3			; copy base
	add.l	#32766,a4		; bias
	bra.s	clonedata		; and copy the data segment only

loaded:
	moveq	#-1,d7			; flag not resident (start if from disk)
	far	data
	move.l	d7,___fromdisk__	; needs to be set for _geta4
	near	data

	bsr.s	_geta4			; set up data base register

	lea	__H1_end,a1
	lea	__H2_org,a2
	cmp.l	a1,a2			; check if BSS and DATA together
	bne.s	normal			; this would actually be an error.

	move.w	#((__H2_end-__H2_org)/4)-1,d1
	bmi.s	normal
	moveq	#0,d2

clear_loop:
	move.l	d2,(a1)+		; clear out memory
	dbra	d1,clear_loop
	bra.s	normal

clonedata:
	move.l	#((__H1_end-__H1_org)/4)-1,d1
	bmi.s	normal
	far	data
	lea	__H1_end,a1
	lea	__H2_org,a2
	near	data
	cmp.l	a1,a2
	beq.s	clone_no_error
	move.l	#500,d2			; error, must be same hunk, so scram
	bra.s	exit

clone_no_error:
	far	data
	lea	__H1_org,a1		; clone data and bss
	near	data

clone_loop:
	move.l	(a1)+,(a3)+		; a3 set to point to base
	dbra	d1,clone_loop

normal:
	move.l	sp,__savsp		; save stack pointer
	move.l	(4).w,a6		; get Exec's library base pointer
	move.l	a6,_SysBase		; put where we can get it

	movem.l d0/a0,-(sp)		; save CLI command parameters
	lea	dos_name(pc),a1		; get name of dos library
	moveq	#0,d0			; any version
	call	OpenLibrary		; open the library
	move.l	d0,_DOSBase		; set it up
	movem.l (sp)+,d0/a0		; restore CLI command parameters
	tst.l	_DOSBase		; check base ptr
	bne.s	start_main		; skip if okay

  	move.l  #AG_OpenLib!AO_DOSLib,d7
	call	Alert
	move.l	#500,d2			; set return code
	bra.s	exit

start_main:
	jsr	__main			; call the startup stuff
	move.l	d0,d2			; remember return code

	move.l	_DOSBase,d0		; lib still open?
	beq.s	exit			; nope
	move.l	d0,a1
	move.l	(4).w,a6
	call	CloseLibrary		; close it

exit:
	move.l	d2,d0			; set return code
	rts				; and return

_geta4:
	movem.l d0-d1/a0-a1/a6,-(sp)	; max safety here...
	far	data
	tst.l	___fromdisk__
	near	data
	bne.s	1$

	move.l	(4).w,a6
	sub.l	a1,a1
	call	FindTask
	move.l	d0,a0
	lea	TC_MEMENTRY(a0),a0
	lea	PMEM(pc),a1
	call	FindName
	tst.l	d0
	beq.s	1$			; not resident

	move.l	d0,a0
	cmp.w	#2,pm_Num(a0)		; check for data
	bne.s	1$			; resident, but no data allocated.
	move.l	pm_Data(a0),a4		; get data pointer
	add.l	#32766,a4		; bias 
	bra.s	2$
1$	far	data
	lea	__H1_org+32766,a4
	near	data
2$	movem.l (sp)+,d0-d1/a0-a1/a6
	rts

dos_name:
	dc.b	'dos.library',0

PMEM	PMEM_NAME

	even

	far	data

	public	__main,__H0_org

	dseg
	
	public	_SysBase,_DOSBase,__savsp,___fromdisk__
	public	__H1_org,__H1_end,__H2_org,__H2_end

	near	data

___fromdisk__:
	dc.l	0	; default is resident

	end
