summaryrefslogtreecommitdiff
path: root/LoadSeg.S
blob: a09bbf6ef14b99aa0226d3f15743c07c0267c380 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
**************************************************************************
**                                                                      **
**   Modification History                                               **
**   --------------------                                               **
**                                                                      **
**   15-May-89  CHW  Created this file!                                 **
**   24-Oct-90  CHW  Schrottet die Memoryliste nicht mehr               **
**                                                                      **
**************************************************************************

		IDNT	LoadSeg
		SECTION	text,CODE

		INCLUDE	"MyExec.i"

		XREF	AllocMemFunc,FreeMemFunc
		XREF	LoadFileFunc,LoadFastFileFunc

		XDEF	LoadSegFunc,UnLoadSegFunc

SEGMAGIC:	EQU	'SEG2'	; Neues Format
RELOCMAGIC:	EQU	'RLOC'

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

	IFD sakdksdhgksdjhg

'struct' SpecialFile
{
	ULONG	ID;			/* Segment-Start-Magic SPECIAL_SEGID */
	ULONG	CodeSize;		/* CODE-Size (FAST-RAM) in Bytes */
	ULONG	DataSize;		/* DATA-Size (CHIP-RAM) in Bytes */
	ULONG	BSSSize;		/* BSS-Size, mindestens 4 Bytes FAST RAM */

	BYTE	Code[0];		/* CodeSize Bytes, geht ins FAST RAM */

	ULONG	rloc1;			/* muss SPECIAL_RELOC sein */
	ULONG	Numccrelocs;		/* Anzahl folgende Relocs */
	BYTE	CCRelocs[0];		/* Im Code nach Code relocs */

	ULONG	rloc2;			/* muss SPECIAL_RELOC sein */
	ULONG	Numcdrelocs;		/* Anzahl folgende Relocs */
	BYTE	CDRelocs[0];		/* Im Code nach Data relocs */

	ULONG	rloc3;			/* muss SPECIAL_RELOC sein */
	ULONG	Numcbrelocs;		/* Anzahl folgende Relocs */
	BYTE	CBRelocs[0];		/* Im Code nach BSS relocs */


	BYTE	Data[0];		/* DataSize Bytes, geht ins CHIP RAM */

	ULONG	rloc4;			/* muss SPECIAL_RELOC sein */
	ULONG	Numdcrelocs;		/* Anzahl folgende Relocs */
	BYTE	DCRelocs[0];		/* Im Data nach Code relocs */

	ULONG	rloc5;			/* muss SPECIAL_RELOC sein */
	ULONG	Numddrelocs;		/* Anzahl folgende Relocs */
	BYTE	DDRelocs[0];		/* Im Data nach Data relocs */

	ULONG	rloc6;			/* muss SPECIAL_RELOC sein */
	ULONG	Numdbrelocs;		/* Anzahl folgende Relocs */
	BYTE	DBRelocs[0];		/* Im Data nach BSS relocs */
};

	ENDC

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

	*** D0 :  Filename

LoadSegFunc:	movem.l	d1-d6/a0-a5,-(SP)
		bsr	LoadFastFileFunc	; File ins FAST RAM einladen
		movea.l	d0,a2			; A2 :  File-Base
		move.l	a2,d6			; D6 :  File-Base für später
		move.l	#RELOCMAGIC,d5

	*** Parameter aus FileHeader holen

		move.l	#SEGMAGIC,d0
		cmp.l	(a2)+,d0		; Kennung OK ?
		beq.s	1$			; ja --->
		SMSG	<"Not an object module at $%08lx">,d6
		jmp	meb_ColdReboot(a6)
1$:
		movem.l	(a2)+,d2-d4		; D2 : CODESIZE, D3: DATASIZE
						; D4 : BSSSIZE
		SMSG	<"Code:%ld, Data:%ld, BSS:%ld">,d2,d3,d4

	*** Speicher für Code, Data und BSS allozieren

		move.l	d2,d0			; CODE-Size
		addq.l	#8,d0			; Platz für DATA- und BSS-Zeiger
		jsr	meb_AllocFastMem(a6)	; FAST RAM reservieren
		movea.l	d0,a3			; A3 :  CODE-Segment

		move.l	d3,d0			; DATA-Size
		jsr	meb_AllocMem(a6)	; CHIP RAM reservieren
		movea.l	d0,a4			; A4 :  DATA-Segment
		move.l	a4,(a3)+		; in Code-Segment merken

	SMSG	<"Allocation BSS ...">
		move.l	d4,d0			; BSS-Size
		jsr	meb_AllocClearMem(a6)	; BSS wird gelöscht
		movea.l	d0,a5			; A5 :  BSS-Segment
		move.l	a5,(a3)+		; in Code-Segment merken

	*** Code ins Code-Segment rüberkopieren, FilePtr auf Relocs

		movea.l	a2,a0			; Source: File
		movea.l	a3,a1			; Destination: Code-Segment
		move.l	d2,d0			; Code-Size
		jsr	meb_CopyMem(a6)		; Segment kopieren
		adda.l	d2,a2			; File-Zeiger vorrücken

	*** Code to Code/Data/BSS Relocs ausführen
	*** Relocs sind 16bit signed deltas oder 0 und dann 32bit signed

		cmp.l	(a2)+,d5		; Magic vorhanden ?
		bne	BadReloc		; nein ---> Error
		move.l	(a2)+,d0		; Anzahl Code-Code-Relocs
		move.l	a3,d1			; Zu addierender Wert
		movea.l	a3,a0			; Zu relozierender Code
		bsr	DoReloc

		cmp.l	(a2)+,d5		; Magic vorhanden ?
		bne	BadReloc		; nein ---> Error
		move.l	(a2)+,d0		; Anzahl Code-Data-Relocs
		move.l	a4,d1			; Zu addierender Wert
		movea.l	a3,a0			; Zu relozierender Code
		bsr	DoReloc

		cmp.l	(a2)+,d5		; Magic vorhanden ?
		bne	BadReloc		; nein ---> Error
		move.l	(a2)+,d0		; Anzahl Code-BSS-Relocs
		move.l	a5,d1			; Zu addierender Wert
		movea.l	a3,a0			; Zu relozierender Code
		bsr	DoReloc

	*** Data ins Data-Segment rüberkopieren, FilePtr auf Relocs

		movea.l	a2,a0			; Source: File
		movea.l	a4,a1			; Destination: Data-Segment
		move.l	d3,d0			; Data-Size
		jsr	meb_CopyMem(a6)		; Segment kopieren
		adda.l	d3,a2			; File-Zeiger vorrücken

	*** Data to Code/Data/BSS Relocs ausführen

		cmp.l	(a2)+,d5		; Magic vorhanden ?
		bne	BadReloc		; nein ---> Error
		move.l	(a2)+,d0		; Anzahl Data-Code-Relocs
		move.l	a3,d1			; Zu addierender Wert
		movea.l	a4,a0			; Zu relozierender Code
		bsr	DoReloc

		cmp.l	(a2)+,d5		; Magic vorhanden ?
		bne	BadReloc		; nein ---> Error
		move.l	(a2)+,d0		; Anzahl Data-Data-Relocs
		move.l	a4,d1			; Zu addierender Wert
		movea.l	a4,a0			; Zu relozierender Code
		bsr	DoReloc

		cmp.l	(a2)+,d5		; Magic vorhanden ?
		bne	BadReloc		; nein ---> Error
		move.l	(a2)+,d0		; Anzahl Data-BSS-Relocs
		move.l	a5,d1			; Zu addierender Wert
		movea.l	a4,a0			; Zu relozierender Code
		bsr	DoReloc

	*** Ur-File freigeben

		movea.l	d6,a1			; File
		jsr	meb_FreeMem(a6)
LoadSegEnd:
		move.l	a3,d0			; The File
		movem.l	(SP)+,d1-d6/a0-a5
		rts

BadReloc:	SMSG	<"File $%08lx: Bad reloc magic">,d6
		jmp	meb_ColdReboot(a6)


	*** D0=Anzahl, D1=Offset, A0=Segment, A2=File, wird vorgerückt

DoReloc:	movem.l	d1-d3,-(SP)
		moveq.l	#0,d2			; Reloc-Pointer resetten
		bra.s	3$			; Für dbf
1$:		move.w	(a2)+,d3		; Nächste Adresse
		ext.l	d3			; auf Langwort erweitern
		bne.s	2$			; nicht 0 ---> 16bit-delta
		move.l	(a2)+,d3		; sonst 32bit-delta
2$:		add.l	d3,d2			; Delta-Wert addieren
		add.l	d1,0(a0,d2.l)		; Tada!
3$:		dbf	d0,1$
		movem.l	(SP)+,d1-d3
		rts

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

	*** A1 :  Segmentliste von LoadSeg()

UnLoadSegFunc:	movem.l	a0-a1,-(SP)
		movea.l	a1,a0
		movea.l	-(a0),a1		; A1 :  BSS-Segment
		jsr	meb_FreeMem(a6)		; Segment freigeben
		movea.l	-(a0),a1		; A1 :  Data-Segment
		jsr	meb_FreeMem(a6)		; Segment freigeben
		movea.l	a0,a1			; A1 :  CodeSegment
		jsr	meb_FreeMem(a6)		; Segment freigeben
		movem.l	(SP)+,a0-a1
		rts