


******** Routine permettant de rendre lancable un executable  ********
******** (Ce que réalise la fonction LoadSeg() de la dos.lib) ********



** Ne reconnait que 3 types de hunks:CODE,DATA,BSS **


** v1.0 by GRC ** le 28/06/92 à 00:24
** Fait d'après la BIBLE de L'AMIGA (si,si!)

** Routine crée pour Boot-Master v1.51 (Option 'Boot-exececutable')



reloc:

	lea	executable,a0

	cmp.l	#$000003f3,(a0)+	; un executable ?
	bne	error			; noooonnnn

cherche_nom:
	move.l	(a0)+,d0		; un nom de hunk ?
	tst.l	d0
	beq.s	plus_de_nom

	lsl.l	#2,d0			; multiplication par 4
	add.l	d0,a0			; va au prochain nom
	bra.s	cherche_nom		; on continue
	
plus_de_nom:

	move.l	(a0)+,nb_hunk		; nbre de hunk réalisant le programme
	
	cmp.l	#10,nb_hunk		; pas plus de 10 hunks
	bhi	error

	addq.l	#8,a0			; on passe de 'ou à ou'


	move.l	nb_hunk,d0
	subq	#1,d0
cherche_next_hunk:			; on cherche le 1er hunk
	addq.l	#4,a0
	dbra	d0,cherche_next_hunk


	move.l	a0,first_hunk		; on a l'adresse de la base
					; des hunks composant le prg

	cmp.l	#$000003e9,(a0)		; on regarde si c'est bien
	beq	an_exe			; un executable
	cmp.l	#$000003ea,(a0)		; -> hunk CODE ou DATA
	bne	error
an_exe:

	cmp.l	#$000003f2,(a0)		; hunk end ?
	beq	fin 


	bsr	cherche_addr_hunk	; on cherche l'adresse des différents
					; hunks
	cmp.l	#-1,d0
	beq	error

	move.w	#1,do_mem		; on veut allouer la mémoire
	bsr	cherche_hunk_bss	; on cherche les hunks_bss et
					; on alloue la mémoire demandée
	cmp.l	#-1,d0
	beq	error2

	bsr	do_reloc32		; on fait les correction d'adrresse

r:
	move.l	4,a6
	sub.l	a1,a1
	jsr	-294(a6)		; findtask
	move.l	d0,a4

	move.l	$ac(a4),-(a7)		; pour faire croire que l'on vient
	move.l	a4,-(a7)
	move.l	#-1,$ac(a4)		; du CLI
					; a enlever si c'est du boot-block
					; que cela est executé
	clr.l	d0
	lea	table_reel,a4
	move.l	(a4),a4
	jsr	(a4)			; on lance le prg

	move.l	(a7)+,a4
	move.l	(a7)+,$ac(a4)

cont:
	move.w	#2,do_mem		; on veut liberer la mémoire
	bsr	cherche_hunk_bss

fin:
	clr.l	d0
quitte:
	rts

error:
	move.l	#-1,d0
	bra	quitte
error2:
	move.l	#-2,d0
	bra	quitte


do_reloc32:
	clr.l	d0

	lea	table_reel,a4
	move.l	a4,a5

reloc_loop:
	tst.l	(a4)
	beq	end_reloc32

	move.l	(a4)+,a3		; adresse du hunk

	subq.l	#8,a3
	move.l	(a3)+,d2		; type du hunk


	cmp.l	#"BSS!",d2		; hunk bss
	beq.s	a_code

	and.l	#$0fffffff,d2

	cmp.l	#$000003e9,d2		; hunk code
	beq.s	a_code

	cmp.l	#$000003ea,d2		; hunk data
	bne.s	unkn_hunk
a_code:
	move.l	(a3)+,d1		; longueur du hunk

	move.l	(a4),d7			; pointeur sur le segment suivant
	tst.l	d7
	beq.s	zero			; si c'est a zero la suite est inutile
	subq.l	#4,d7
	lsr.l	#2,d7			; div. par 4
zero:
	move.l	d7,-4(a3)

	cmp.l	#"BSS!",d2		; pas de reloc pour le BSS
	beq	reloc_loop

	move.l	a3,a2
	lsl.l	#2,d1			; x4
	add.l	d1,a3			; fin du code

	cmp.l	#$000003f2,(a3)+	; hunk_end ?
	beq.s	reloc_loop		; y'a pas de correction à faire

re_loop:
	move.l	(a3)+,d7		; nb de correction à faire
	subq.l	#1,d7
	move.l	(a3)+,d1		; No de hunk
	lsl.l	#2,d1			; x4
	move.l	(a5,d1.l),d2		; adresse a ajouter pour corriger
correction_loop:
	move.l	(a3)+,d1		; offset pour la correction
	add.l	d2,(a2,d1.l)
	dbra	d7,correction_loop

	tst.l	(a3)
	bne.s	re_loop

	bra	reloc_loop

end_reloc32:
	clr.l	d0
r_32_quit:
	rts


unkn_hunk:
	move.l	#-1,d0
	bra.s	r_32_quit



cherche_hunk_bss:
	clr.l	d0

	lea	table_reel,a3
	lea	table,a4
	lea	table_bss,a5

	move.l	nb_hunk,d6
	subq.l	#1,d6
bss_loop:
	move.l	(a4)+,a0		; adresse contenant le hunk
	move.l	(a0)+,d2		; type de hunk
	and.l	#$0fffffff,d2

	move.l	-4(a4),(a3)+		; anticipation pour la vraie table
	addq.l	#8,-4(a3)		; on saute le hunk et sa longueur

	cmp.l	#$000003eb,d2		; hunk_bss ?
	bne.s	not_a_bss	

	cmp.w	#1,do_mem
	bne.s	libere
	move.l	(a0),d0			; taille a reserver
	lsl.l	#2,d0			; x4
	addq.l	#8,d0			; +8
	move.l	#$10002,d1		; chip+clear demandé
	move.l	4,a6
	jsr	-198(a6)		; alloc mem
	tst.l	d0
	beq.s	cherche_h_bss_error
	addq.l	#4,d0
	move.l	d0,(a5)+		; on sauve l'adresse de la mem

	move.l	d0,-4(a3)		; pour la vrai table
	move.l	d0,a0
	move.l	#"BSS!",-8(a0)
	bra.s	not_a_bss
libere:
	cmp.w	#2,do_mem
	bne.s	cherche_h_bss_error
	move.l	(a0),d0			; taille a liberer
	lsl.l	#2,d0			; x4
	addq.l	#8,d0			; +8
	tst.l	(a5)
	beq.s	not_a_bss		; rien a liberer
	move.l	(a5)+,a1		; adresse
	subq.l	#8,a1
	move.l	4,a6
	jsr	-210(a6)		; free mem
not_a_bss:
	dbra	d6,bss_loop

	clr.l	d0			; it's OK
cherche_h_bss_exit:
	rts

cherche_h_bss_error:
	move.l	#-1,d0			; ERREUR
	bra.s	cherche_h_bss_exit



cherche_addr_hunk:

	movem.l	d1-d7/a1-a6,-(a7)


	lea	table,a4

	move.l	first_hunk,a0

	move.l	a0,(a4)+


	clr.l	d7			; init. du compteur

hunk_boucle:
	move.l	(a0),d2
	and.l	#$0fffffff,d2

	cmp.l	#$000003e9,d2		; hunk code ?
	beq	pass_hunk_code
	
	cmp.l	#$000003ea,d2		; hunk data ?
	beq	pass_hunk_data

	cmp.l	#$000003eb,d2		; hunk bss ?
	beq	pass_hunk_bss

	moveq	#-1,d0			; erreur:hunk inconnu
	bra	hunk_error

fin_cherche:
	move.l	a0,(a4)+

	addq.l	#1,d7			; hunk=hunk+1
	cmp.l	nb_hunk,d7		; Fin de recherche
	bne	hunk_boucle		; nooonnn

	moveq	#0,d0			; ok
hunk_error:
	movem.l	(a7)+,d1-d7/a1-a6

	rts


pass_hunk_code:
	move.l	4(a0),d1		; nb de long mots contenant le prg
	lsl.l	#2,d1			; x4
	addq.l	#8,a0
	add.l	d1,a0

	cmp.l	#$000003f2,(a0)		; hunk_end ?
	beq.s	h_end

	cmp.l	#$000003ec,(a0)		; hunk reloc32
	bne.s	no_reloc32
	bsr	pass_hunk_reloc32
	bra	fin_cherche
h_end:
	addq.l	#4,a0
	bra	fin_cherche
no_reloc32:
	moveq	#-1,d0			; erreur:hunk inconnu
	bra	hunk_error

pass_hunk_data:
	move.l	4(a0),d1		; nb de long mots contenant le prg
	lsl.l	#2,d1			; x4
	addq.l	#8,a0
	add.l	d1,a0
	addq.l	#4,a0			; passe hunk_end
	bra	fin_cherche


pass_hunk_bss:
	add.l	#4*3,a0			; on passe le hunk,le nb de mem a 
					; reserver,le hunk_end
	bra	fin_cherche



pass_hunk_reloc32:
	addq.l	#4,a0			; on saute hunk

reloc32:
	move.l	(a0),d1			; nb d'offsets
	lsl.l	#2,d1			; * 4

	addq.l	#8,a0			; on saute hunk,nb offsets et
					; No offset

	add.l	d1,a0			; on saute les offsets
	
	tst.l	(a0)			; fin reloc32 ?
	bne.s	reloc32

	addq.l	#4,a0			; on saute le 0 terminateur

	cmp.l	#$000003f2,(a0)		; hunk_end ?
	bne.s	reloc32_end		; nooonn
	addq.l	#4,a0			; on passe le hunk end
reloc32_end:

	rts

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


	even

nb_hunk:
	dc.l	0
hunk_actuel:
	dc.l	0
first_hunk:
	dc.l	0
do_mem:					; 1 alloue , 2 libère la mémoire
	dc.w	0
table:					; 10 hunks possible en tout
	dcb.l	10,0
table_reel:
	dcb.l	10,0
table_bss:
	dcb.l	10-1,0


	cnop	0,4		; longword aligned

executable:			; ici l'executable a reloger

	incbin	"DH1:Tools/Colors1.3"



