mirror of
https://github.com/SEPPDROID/Digital-Research-Source-Code.git
synced 2025-10-23 08:24:18 +00:00
595 lines
39 KiB
Plaintext
595 lines
39 KiB
Plaintext
C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.03 Page 1
|
||
Source File: pgmld.s
|
||
|
||
1
|
||
2 *********************************
|
||
3 * *
|
||
4 * Function 59 -- Program Load *
|
||
5 * Assembly language version *
|
||
6 * *
|
||
7 * June 8, 1982 *
|
||
8 * *
|
||
9 *********************************
|
||
10
|
||
11 .globl _pgmld * this routine is public
|
||
12
|
||
13 secsize = 128 * CP/M sector size
|
||
14
|
||
15 * d0 always contains the return parameter from pgmld
|
||
16 * d1 is the return register from local subroutines
|
||
17 * a0 contains the pointer to the Load Parm Block passed to pgmld
|
||
18
|
||
19 * Return parameters in d0 are:
|
||
20 * 00 - function successful
|
||
21 * 01 - insufficient memory or bad header in file
|
||
22 * 02 - read error on file
|
||
23 * 03 - bad relocation information in file
|
||
24
|
||
25
|
||
26 * Entry point for Program Load routine
|
||
27 _pgmld:
|
||
28 00000000 48E77FFE movem.l d1-d7/a0-a6, -(sp) * save everything, just to be safe
|
||
29 00000004 206F003C move.l 60(sp),a0 * get pointer to LPB
|
||
30 00000008 4280 clr.l d0 * start with return parm cleared
|
||
31 0000000A 6154 bsr gethdr * get header
|
||
32 0000000C 4A40 tst d0
|
||
33 0000000E 662A bne lddone * if unsuccessful, return
|
||
34 00000010 61000108 bsr setaddr * set up load addresses
|
||
35 00000014 4A40 tst d0
|
||
36 00000016 6622 bne lddone * if unsuccessful, return
|
||
37 00000018 61000258 bsr rdtxt * read code and data text segments into mem
|
||
38 0000001C 4A40 tst d0
|
||
39 0000001E 661A bne lddone * if unsuccessful, return
|
||
40 00000020 2E3900000016 move.l tstart,d7
|
||
41 00000026 BEB900000024 cmp.l cseg,d7
|
||
42 0000002C 6704 beq noreloc
|
||
43 0000002E 61000350 bsr reloc * do relocation if necessary
|
||
44 noreloc:
|
||
45 00000032 4A40 tst d0
|
||
46 00000034 6604 bne lddone
|
||
47 00000036 610003E8 bsr setrtn * set up return parameters
|
||
48 lddone:
|
||
49 0000003A 222F0040 move.l 64(sp), d1
|
||
50 0000003E 6116 bsr setdma * restore dma address
|
||
51 00000040 4CDF7FFE movem.l (sp)+,d1-d7/a0-a6
|
||
52 00000044 4E75 rts
|
||
53
|
||
54 * Subroutines
|
||
55
|
||
C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.03 Page 2
|
||
Source File: pgmld.s
|
||
|
||
56 readseq:
|
||
57 * CP/M read sequential function
|
||
58 00000046 2F00 move.l d0,-(sp) * save return parm
|
||
59 00000048 22280000 move.l FCBPtr(a0),d1
|
||
60 0000004C 7014 moveq #20,d0 * read seq function
|
||
61 0000004E 4E42 trap #2 * call bdos
|
||
62 00000050 2200 move.l d0,d1 * return parm in d1
|
||
63 00000052 201F move.l (sp)+,d0
|
||
64 00000054 4E75 rts
|
||
65
|
||
66
|
||
67 setdma:
|
||
68 * CP/M set dma function
|
||
69 00000056 2F00 move.l d0,-(sp) * save return parm
|
||
70 00000058 701A moveq #26,d0 * set dma function
|
||
71 0000005A 4E42 trap #2 * call bdos
|
||
72 0000005C 201F move.l (sp)+,d0 * restore d0
|
||
73 0000005E 4E75 rts
|
||
74
|
||
75
|
||
76 gethdr:
|
||
77 * Get header into buffer in data segment
|
||
78 00000060 22280004 move.l LoAdr(a0),d1
|
||
79 00000064 61F0 bsr setdma
|
||
80 00000066 61DE bsr readseq
|
||
81 00000068 4A41 tst d1 * read ok?
|
||
82 0000006A 6614 bne badhdr * if no, return bad
|
||
83 0000006C 7E12 moveq #18,d7
|
||
84 0000006E 2A680004 movea.l LoAdr(a0),a5
|
||
85 00000072 2C7C00000000 movea.l #hdr,a6
|
||
86 00000078 3CDD geth1: move.w (a5)+,(a6)+ * move header into hdr
|
||
87 0000007A 51CFFFFC dbf d7,geth1
|
||
88 0000007E 4E75 rts
|
||
89 00000080 7002 badhdr: moveq #2,d0
|
||
90 00000082 4E75 rts
|
||
91
|
||
92
|
||
93 conflict:
|
||
94 * input parms: d2, d3 = 4 * segment nmbr
|
||
95 * if segment d2/4 overlaps segment d3/4, then return 1 in d1
|
||
96 * else return 0 in d1
|
||
97 * uses d7, a2, a3
|
||
98 00000084 4281 clr.l d1 * assume it will work
|
||
99 00000086 247C00000024 movea.l #cseg,a2 * a2 points to start of segment addresses
|
||
100 0000008C 267C00000002 movea.l #csize,a3 * a3 points to start of segment lengths
|
||
101 00000092 2E322000 move.l 0(a2,d2),d7 * get 1st seg start
|
||
102 00000096 BEB23000 cmp.l 0(a2,d3),d7 * is 1st seg above 2nd seg?
|
||
103 0000009A 6C0C bge conf1
|
||
104 0000009C DEB32000 add.l 0(a3,d2),d7 * yes, find top of 1st seg
|
||
105 000000A0 BEB23000 cmp.l 0(a2,d3),d7 * above start of 2nd seg?
|
||
106 000000A4 6E10 bgt confbd * if yes, we have a conflict
|
||
107 000000A6 4E75 rts * else, return good
|
||
108 conf1:
|
||
109 000000A8 2E323000 move.l 0(a2,d3),d7
|
||
110 000000AC DEB33000 add.l 0(a3,d3),d7 * find top of 2nd seg
|
||
C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.03 Page 3
|
||
Source File: pgmld.s
|
||
|
||
111 000000B0 BEB22000 cmp.l 0(a2,d2),d7 * above start of 1st seg?
|
||
112 000000B4 6F02 ble confgd * if no, we're ok
|
||
113 000000B6 7201 confbd: moveq.l #1,d1
|
||
114 000000B8 4E75 confgd: rts
|
||
115
|
||
116
|
||
117 trymemtp:
|
||
118 * entry: d2 is a segment nmbr [0..4]
|
||
119 * try to fit it at top of memory
|
||
120 * uses d3, d6, d7, a5, a6
|
||
121 * returns 0 in d1 if ok
|
||
122 000000BA 2C02 move.l d2,d6 * d6 is loop counter for chksegs
|
||
123 000000BC 5346 subq #1,d6
|
||
124 000000BE E54A lsl #2,d2 * multiply d2 by 4
|
||
125 000000C0 2E280008 move.l HiAdr(a0),d7 * top of mem to d7
|
||
126
|
||
127 chksegs:
|
||
128 * entry: d2 = 4 * (segment nmbr to try)
|
||
129 * d6 = (d2/4) - 1 (loop counter)
|
||
130 * d7 = address below which to try it
|
||
131 * check for conflicts with segments [0..d6] and low memory boundary
|
||
132 * return 0 in d1 if no conflicts, else d1 = 1
|
||
133 * uses d3, a5, a6
|
||
134 000000C4 2A7C00000024 movea.l #cseg,a5
|
||
135 000000CA 2C7C00000002 movea.l #csize,a6
|
||
136 000000D0 9EB62000 sub.l 0(a6,d2),d7 * subtract size of segment to try
|
||
137 000000D4 08870000 bclr #0,d7 * make it even address
|
||
138 000000D8 2B872000 move.l d7,0(a5,d2) * insert address in segment table
|
||
139 000000DC BEA80004 cmp.l LoAdr(a0),d7 * check for conflict with low memory
|
||
140 000000E0 6DD4 blt confbd
|
||
141 000000E2 4283 clr.l d3 * check for conflicts with 0..d6
|
||
142 chk1:
|
||
143 000000E4 619E bsr conflict
|
||
144 000000E6 5883 addq.l #4,d3
|
||
145 000000E8 4A81 tst.l d1 * conflict with this seg?
|
||
146 000000EA 56CEFFF8 dbne d6,chk1 * if no, try next
|
||
147 000000EE 4E75 rts
|
||
148
|
||
149
|
||
150 fndseg:
|
||
151 * entry: d2 is a segment nmbr [0..4]
|
||
152 * try to fit segment d2 directly below segments 0..(d2-1)
|
||
153 * uses d3-d7, a5, a6
|
||
154 000000F0 2A02 move.l d2,d5 * d5 is loop counter to find fit
|
||
155 000000F2 5385 subq.l #1,d5
|
||
156 000000F4 23C50000003C move.l d5,temp
|
||
157 000000FA E58A lsl.l #2,d2 * multiply segment by 4
|
||
158 000000FC 4284 clr.l d4 * d4 is segment to try to fit below
|
||
159 fnd1:
|
||
160 000000FE 2C390000003C move.l temp,d6 * d6 is loop counter for chksegs
|
||
161 00000104 2A7C00000024 movea.l #cseg,a5
|
||
162 0000010A 2E354000 move.l 0(a5,d4),d7 * segment address to d7
|
||
163 0000010E 61B4 bsr chksegs * check for conflicts
|
||
164 00000110 5884 addq.l #4,d4
|
||
165 00000112 4A81 tst.l d1
|
||
C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.03 Page 4
|
||
Source File: pgmld.s
|
||
|
||
166 00000114 57CDFFE8 dbeq d5,fnd1 * if conflict, try next
|
||
167 00000118 4E75 rts
|
||
168
|
||
169
|
||
170 setaddr:
|
||
171 * Set up load addresses for cseg, dseg, bss, basepg, and stack
|
||
172 0000011A 3C3900000000 move.w magic,d6
|
||
173 00000120 0246FFFE andi.w #$fffe,d6
|
||
174 00000124 0C46601A cmpi.w #$601a,d6
|
||
175 00000128 66000120 bne badadr * if magic nmbr <> 601a or 601b, skip
|
||
176 0000012C 23F90000000E00000038 move.l bpsize,symsize
|
||
177 00000136 2E3C00000100 move.l #256,d7
|
||
178 0000013C 23C70000000E move.l d7,bpsize * base page is 256 bytes
|
||
179 00000142 45F900000012 lea stksize,a2
|
||
180 00000148 BE52 cmp (a2),d7
|
||
181 0000014A 6D02 blt set0 * if stack size < 256, set to 256
|
||
182 0000014C 2487 move.l d7,(a2)
|
||
183 0000014E 0C79601B00000000 set0: cmpi.w #$601b,magic
|
||
184 00000156 6708 beq seta
|
||
185 00000158 4A790000001A tst.w rlbflg
|
||
186 0000015E 670C beq set1
|
||
187 00000160 23F90000001600000024 seta: move.l tstart,cseg * if not relocatable or hdr = $601b,
|
||
188 0000016A 6040 bra set2 * cseg starts at tstart
|
||
189 0000016C 082800000015 set1: btst #0,Flags(a0)
|
||
190 00000172 6616 bne sldhi
|
||
191 * relocatable, load low
|
||
192 00000174 2E280004 move.l LoAdr(a0),d7
|
||
193 00000178 DEBC00000101 add.l #$101,d7 * leave room for base page
|
||
194 0000017E 08870000 bclr #0,d7
|
||
195 00000182 23C700000024 move.l d7,cseg * cseg is bottom of mem + $100 (even boundary)
|
||
196 00000188 6022 bra set2
|
||
197 sldhi:
|
||
198 * relocatable, load high
|
||
199 0000018A 2E280008 move.l HiAdr(a0),d7
|
||
200 0000018E 9EB900000002 sub.l csize,d7
|
||
201 00000194 9EB900000006 sub.l dsize,d7
|
||
202 0000019A 9EB90000000A sub.l bsize,d7
|
||
203 000001A0 5987 subq.l #4,d7
|
||
204 000001A2 08870000 bclr #0,d7 * put cseg at next even address below
|
||
205 000001A6 23C700000024 move.l d7,cseg * high memory - (sum of sizes)
|
||
206 set2:
|
||
207 * Cseg has been set up. Now do dseg, bseg
|
||
208 000001AC 0C79601B00000000 cmpi.w #$601b,magic
|
||
209 000001B4 6616 bne set3
|
||
210 * if magic # = 601b, take addr from hdr
|
||
211 000001B6 23F90000001C00000028 move.l dstart,dseg
|
||
212 000001C0 23F9000000200000002C move.l bstart,bseg
|
||
213 000001CA 602A bra set4
|
||
214 set3:
|
||
215 * if short header, dseg and bseg follow cseg
|
||
216 000001CC 2E3900000024 move.l cseg,d7
|
||
217 000001D2 DEB900000002 add.l csize,d7
|
||
218 000001D8 5287 addq.l #1,d7
|
||
219 000001DA 08870000 bclr #0,d7
|
||
220 000001DE 23C700000028 move.l d7,dseg
|
||
C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.03 Page 5
|
||
Source File: pgmld.s
|
||
|
||
221 000001E4 DEB900000006 add.l dsize,d7
|
||
222 000001EA 5287 addq.l #1,d7
|
||
223 000001EC 08870000 bclr #0,d7
|
||
224 000001F0 23C70000002C move.l d7,bseg
|
||
225 set4:
|
||
226 * cseg, dseg, bseg set up
|
||
227 * now find a place for the base page and stack
|
||
228 000001F6 7403 moveq.l #3,d2
|
||
229 000001F8 6100FEF6 bsr fndseg * try to fit base page below cseg, dseg, bseg
|
||
230 000001FC 4A81 tst.l d1
|
||
231 000001FE 670A beq set5 * if found, skip
|
||
232 00000200 7403 moveq.l #3,d2
|
||
233 00000202 6100FEB6 bsr trymemtp * else, try top of memory
|
||
234 00000206 4A81 tst.l d1
|
||
235 00000208 6640 bne badadr * if fail, exit
|
||
236 0000020A 7404 set5: moveq.l #4,d2
|
||
237 0000020C 6100FEAC bsr trymemtp * try to fit stack at top of memory
|
||
238 00000210 4A81 tst.l d1
|
||
239 00000212 670A beq set6 * if ok, skip
|
||
240 00000214 7404 moveq.l #4,d2
|
||
241 00000216 6100FED8 bsr fndseg * else, try to fit below other segs
|
||
242 0000021A 4A81 tst.l d1
|
||
243 0000021C 662C bne badadr
|
||
244 set6:
|
||
245 * now check all segments for conflicts with low and high memory boundaries
|
||
246 0000021E 2A7C00000024 movea.l #cseg,a5
|
||
247 00000224 2C7C00000002 movea.l #csize,a6
|
||
248 0000022A 4282 clr.l d2
|
||
249 0000022C 7604 moveq #4,d3 * loop counter
|
||
250 0000022E 2E352000 set7: move.l 0(a5,d2),d7 * get segment base
|
||
251 00000232 BEA80004 cmp.l LoAdr(a0),d7 * above bottom of memory?
|
||
252 00000236 6D12 blt badadr
|
||
253 00000238 DEB62000 add.l 0(a6,d2),d7 * find top of segment
|
||
254 0000023C BEA80008 cmp.l HiAdr(a0),d7 * below top of memory?
|
||
255 00000240 6E08 bgt badadr
|
||
256 00000242 5882 addq.l #4,d2 * point to next segment
|
||
257 00000244 51CBFFE8 dbf d3,set7
|
||
258 00000248 4E75 rts
|
||
259 0000024A 7001 badadr: moveq.l #1,d0
|
||
260 0000024C 4E75 rts
|
||
261
|
||
262
|
||
263 movebuf:
|
||
264 * move (d3) bytes from the base page buffer to (a2)
|
||
265 * uses d6
|
||
266 0000024E 227900000030 movea.l basepg,a1
|
||
267 00000254 2C3C00000080 move.l #secsize,d6
|
||
268 0000025A 9C7900000042 sub.w bufbyts,d6 * address to move from =
|
||
269 00000260 D2C6 adda.w d6,a1 * (basepg) + secsize - (bufbyts)
|
||
270 00000262 977900000042 sub.w d3,bufbyts * update # bytes buffered
|
||
271 00000268 6002 bra moveb2
|
||
272 0000026A 14D9 moveb1: move.b (a1)+,(a2)+ * do the move
|
||
273 0000026C 51CBFFFC moveb2: dbf d3,moveb1
|
||
274 00000270 4E75 rts
|
||
275
|
||
C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.03 Page 6
|
||
Source File: pgmld.s
|
||
|
||
276
|
||
277 rdtxt:
|
||
278 * Read code and data text into memory
|
||
279 * during this routine, a2 is always the load address,
|
||
280 * d2 is number of bytes left to load
|
||
281 00000272 7E3F moveq #63,d7
|
||
282 00000274 2A680004 movea.l LoAdr(a0),a5
|
||
283 00000278 2C7900000030 movea.l basepg,a6
|
||
284 0000027E 3CDD rdtxt1: move.w (a5)+,(a6)+ * move header sector to base page
|
||
285 00000280 51CFFFFC dbf d7,rdtxt1
|
||
286 00000284 3E3C0064 move.w #secsize-28,d7
|
||
287 00000288 0C79601A00000000 cmpi.w #$601a,magic * short header?
|
||
288 00000290 6702 beq rdtxt2
|
||
289 00000292 5147 subq.w #8,d7
|
||
290 00000294 33C700000042 rdtxt2: move.w d7,bufbyts * indicate # bytes of text in buffer
|
||
291 0000029A 33FC000200000040 move.w #2,loop * do for code, data segments
|
||
292 000002A2 247900000024 move.l cseg,a2 * start at cseg
|
||
293 000002A8 243900000002 move.l csize,d2 * for csize bytes
|
||
294 rdtxt3:
|
||
295 000002AE 4283 clr.l d3
|
||
296 000002B0 363900000042 move.w bufbyts,d3
|
||
297 000002B6 B682 cmp.l d2,d3 * # bytes in buffer >= # bytes to load?
|
||
298 000002B8 6D06 blt rdtxt4
|
||
299 000002BA 2602 move.l d2,d3
|
||
300 000002BC 6190 bsr movebuf * if yes, move # bytes to load
|
||
301 000002BE 6048 bra finrd
|
||
302 rdtxt4:
|
||
303 000002C0 9483 sub.l d3,d2 * if no, update # bytes to load
|
||
304 000002C2 618A bsr movebuf * move remainder of buffer
|
||
305 000002C4 263C00000080 move.l #secsize,d3 * d3 = secsize fo following loop
|
||
306 rdtxt5:
|
||
307 000002CA B483 cmp.l d3,d2 * have at least one more full sector?
|
||
308 000002CC 6D18 blt rdtxt6
|
||
309 000002CE 220A move.l a2,d1
|
||
310 000002D0 6100FD84 bsr setdma * if yes, set up dma address
|
||
311 000002D4 6100FD70 bsr readseq * read next sector
|
||
312 000002D8 4A41 tst.w d1
|
||
313 000002DA 6656 bne rdbad * if no good, exit
|
||
314 000002DC 9483 sub.l d3,d2 * decrement # bytes to load
|
||
315 000002DE D5FC00000080 adda.l #secsize,a2 * increment dma address
|
||
316 000002E4 60E4 bra rdtxt5
|
||
317 rdtxt6:
|
||
318 000002E6 4A82 tst.l d2 * any more bytes to read?
|
||
319 000002E8 671E beq finrd
|
||
320 000002EA 223900000030 move.l basepg,d1
|
||
321 000002F0 6100FD64 bsr setdma
|
||
322 000002F4 6100FD50 bsr readseq * if yes, read into base page
|
||
323 000002F8 4A41 tst.w d1
|
||
324 000002FA 6636 bne rdbad
|
||
325 000002FC 33C300000042 move.w d3,bufbyts * indicate that we've buffered a sector
|
||
326 00000302 2602 move.l d2,d3
|
||
327 00000304 6100FF48 bsr movebuf * move remainder of segment
|
||
328 finrd:
|
||
329 00000308 247900000028 move.l dseg,a2 * set up to load data segment
|
||
330 0000030E 243900000006 move.l dsize,d2
|
||
C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.03 Page 7
|
||
Source File: pgmld.s
|
||
|
||
331 00000314 537900000040 sub.w #1,loop
|
||
332 0000031A 6692 bne rdtxt3
|
||
333 0000031C 24790000002C move.l bseg,a2 * clear the bss segment
|
||
334 00000322 24390000000A move.l bsize,d2
|
||
335 00000328 6706 beq rdtxt8
|
||
336 0000032A 421A rdtxt7: clr.b (a2)+
|
||
337 0000032C 5382 subq.l #1,d2
|
||
338 0000032E 66FA bne rdtxt7
|
||
339 00000330 4E75 rdtxt8: rts
|
||
340
|
||
341 00000332 7002 rdbad: moveq.l #2,d0
|
||
342 00000334 4E75 rts
|
||
343
|
||
344
|
||
345 relocword:
|
||
346 * relocate word at (a2) based on reloc bits at (a3)
|
||
347 * lsb of d2 indicates whether previous word was 1st half of long-word
|
||
348 00000336 3E1B move.w (a3)+,d7 * get relocation info
|
||
349 00000338 02470007 andi.w #7,d7 * strip off symbol table bits
|
||
350 0000033C E34F lsl #1,d7 * multiply by 2
|
||
351 0000033E 4EFB7002 jmp 2(pc,d7)
|
||
352
|
||
353 00000342 6014 bra relabs
|
||
354 00000344 6022 bra reldata
|
||
355 00000346 6020 bra relcode
|
||
356 00000348 601E bra relbss
|
||
357 0000034A 6006 bra relbad
|
||
358 0000034C 6012 bra rellong
|
||
359 0000034E 6002 bra relbad
|
||
360 00000350 6006 bra relop
|
||
361
|
||
362 00000352 201F relbad: move.l (sp)+,d0 * pop return address
|
||
363 00000354 7003 moveq #3,d0 * return bad relocation to main routine
|
||
364 00000356 4E75 rts
|
||
365
|
||
366 relabs:
|
||
367 00000358 08820000 relop: bclr #0,d2 * reset long word flag
|
||
368 0000035C 4A5A tst.w (a2)+ * point to next word of segment
|
||
369 0000035E 4E75 rts
|
||
370
|
||
371 rellong:
|
||
372 00000360 08C20000 bset #0,d2 * set long word flag
|
||
373 00000364 4A5A tst.w (a2)+ * point to next word of segment
|
||
374 00000366 4E75 rts
|
||
375
|
||
376 reldata:
|
||
377 relbss:
|
||
378 relcode:
|
||
379 00000368 08820000 bclr #0,d2 * long word flag set?
|
||
380 0000036C 6608 bne relc1 * if yes, skip
|
||
381 0000036E 3C12 move.w (a2),d6
|
||
382 00000370 DC45 add.w d5,d6
|
||
383 00000372 34C6 move.w d6,(a2)+
|
||
384 00000374 4E75 rts
|
||
385
|
||
C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.03 Page 8
|
||
Source File: pgmld.s
|
||
|
||
386 00000376 4A62 relc1: tst.w -(a2) * point to first word of long
|
||
387 00000378 2C12 move.l (a2),d6
|
||
388 0000037A DC85 add.l d5,d6
|
||
389 0000037C 24C6 move.l d6,(a2)+ * note that a2 points past long word
|
||
390 0000037E 4E75 rts
|
||
391
|
||
392
|
||
393 reloc:
|
||
394 * Modify address references of code and data segments based on relocation bits
|
||
395 * During this routine,
|
||
396 * a2 points to text file to relocate
|
||
397 * a3 points to relocation word in basepg
|
||
398 * lsb of d2 is long word flag (set on reloc type 5, reset on next word)
|
||
399 * d3 is # words in relocation buffer
|
||
400 * d4 is nmbr of words left to relocate
|
||
401 * d5 is relocation offset
|
||
402
|
||
403 00000380 223900000030 move.l basepg,d1
|
||
404 00000386 6100FCCE bsr setdma * we will always read into base page
|
||
405 * skip past the symbol table
|
||
406 0000038A 2E3900000038 move.l symsize,d7
|
||
407 00000390 8EFC0080 divu #secsize,d7 * calculate how many sectors to skip
|
||
408 * note that max # symbols is 8k, which is 896 sectors of 128 bytes
|
||
409 00000394 3C07 move.w d7,d6 * d6 is nmbr sectors to skip
|
||
410 00000396 4847 swap d7 * d7 is nmbr bytes to skip
|
||
411 00000398 363900000042 move.w bufbyts,d3
|
||
412 0000039E 9647 sub.w d7,d3 * subtract bytes to skip from buffer
|
||
413 000003A0 6C06 bge skip1
|
||
414 000003A2 06430080 addi #secsize,d3 *if amt in buffer < # bytes to skip,
|
||
415 000003A6 5246 addq #1,d6 * read in 1 extra sector
|
||
416 000003A8 267900000030 skip1: move.l basepg,a3
|
||
417 000003AE D6FC0080 adda #secsize,a3
|
||
418 000003B2 96C3 suba.w d3,a3 * set up a3 to point to buffer
|
||
419 000003B4 E24B lsr #1,d3 * d3 is nmbr words in buffer
|
||
420 000003B6 600A bra skip3
|
||
421 skip2:
|
||
422 000003B8 6100FC8C bsr readseq * read next symbol table sector
|
||
423 000003BC 4A41 tst.w d1
|
||
424 000003BE 6600FF72 bne rdbad
|
||
425 000003C2 51CEFFF4 skip3: dbf d6,skip2
|
||
426 * we got past symbol table
|
||
427 * a3, d3 are set up
|
||
428 000003C6 2A3900000024 move.l cseg,d5
|
||
429 000003CC 2445 move.l d5,a2 * relocate cseg first
|
||
430 000003CE 9AB900000016 sub.l tstart,d5 * d5 contains the relocation offset
|
||
431 000003D4 283900000002 move.l csize,d4 * nmbr of bytes to relocate
|
||
432 000003DA 33FC000200000040 move.w #2,loop * we're going to relocate 2 segments
|
||
433 reloc1:
|
||
434 * relocate one segment
|
||
435 000003E2 4282 clr.l d2 * clear long word flag
|
||
436 000003E4 E28C lsr.l #1,d4 * make d4 indicate # words
|
||
437 000003E6 601E bra reloc4
|
||
438 reloc2:
|
||
439 000003E8 5343 subq.w #1,d3
|
||
440 000003EA 6A14 bpl reloc3
|
||
C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.03 Page 9
|
||
Source File: pgmld.s
|
||
|
||
441 000003EC 6100FC58 bsr readseq * if no more words in buffer, refill it
|
||
442 000003F0 4A41 tst.w d1
|
||
443 000003F2 6600FF3E bne rdbad
|
||
444 000003F6 267900000030 move.l basepg,a3
|
||
445 000003FC 363C003F move.w #(secsize/2)-1,d3
|
||
446 reloc3:
|
||
447 00000400 6100FF34 bsr relocword * relocate one word
|
||
448 00000404 5384 subq.l #1,d4
|
||
449 reloc4:
|
||
450 00000406 4A84 tst.l d4 * any more to relocate in this segment?
|
||
451 00000408 66DE bne reloc2 * if yes, do it
|
||
452 0000040A 247900000028 move.l dseg,a2 * else, set up for dseg
|
||
453 00000410 283900000006 move.l dsize,d4
|
||
454 00000416 537900000040 sub.w #1,loop
|
||
455 0000041C 66C4 bne reloc1
|
||
456 0000041E 4E75 rts
|
||
457
|
||
458
|
||
459 setrtn:
|
||
460 * Set up the return parameters in Ld Parm Blk and Base Page
|
||
461 00000420 217900000030000C move.l basepg,BasPage(a0)
|
||
462 00000428 2E3900000034 move.l stk,d7
|
||
463 0000042E DEB900000012 add.l stksize,d7
|
||
464 00000434 08870000 bclr #0,d7
|
||
465 00000438 21470010 move.l d7,Stack(a0)
|
||
466 0000043C 227900000030 move.l basepg,a1
|
||
467 00000442 22E80004 move.l LoAdr(a0),(a1)+
|
||
468 00000446 22E80008 move.l HiAdr(a0),(a1)+
|
||
469 0000044A 22F900000024 move.l cseg,(a1)+
|
||
470 00000450 22F900000002 move.l csize,(a1)+
|
||
471 00000456 22F900000028 move.l dseg,(a1)+
|
||
472 0000045C 22F900000006 move.l dsize,(a1)+
|
||
473 00000462 22F90000002C move.l bseg,(a1)+
|
||
474 00000468 22B90000000A move.l bsize,(a1)
|
||
475 * find size of free memory after bss segment
|
||
476 0000046E 2E280008 move.l HiAdr(a0),d7 * d7 contains next segment above bss
|
||
477 00000472 2C29FFFC move.l -4(a1),d6
|
||
478 00000476 DC99 add.l (a1)+,d6 * d6 points to start of free mem after bss
|
||
479 00000478 2C7C00000024 movea.l #cseg,a6 * a6 points to segment to try
|
||
480 0000047E 7A04 moveq #4,d5 * try for all segments
|
||
481 00000480 42B90000002C clr.l bseg * but force bss not to appear
|
||
482 00000486 BC96 setb1: cmp.l (a6),d6 * segment above bss?
|
||
483 00000488 6206 bhi setb2
|
||
484 0000048A BE96 cmp.l (a6),d7 * segment is above bss. Is it below previous?
|
||
485 0000048C 6302 bls setb2
|
||
486 0000048E 2E16 move.l (a6),d7
|
||
487 00000490 4A9E setb2: tst.l (a6)+ * point to next segment
|
||
488 00000492 51CDFFF2 dbf d5,setb1
|
||
489 00000496 9E86 sub.l d6,d7 * diff between bss top and next segment abv
|
||
490 00000498 22C7 move.l d7,(a1)+
|
||
491 * now put disk number that we loaded from into base page
|
||
492 0000049A 24680000 movea.l FCBPtr(a0),a2
|
||
493 0000049E 1012 move.b (a2),d0 * get disk select byte
|
||
494 000004A0 6606 bne setb3 * if not auto-select, skip
|
||
495 000004A2 7019 move #25,d0
|
||
C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.03 Page 10
|
||
Source File: pgmld.s
|
||
|
||
496 000004A4 4E42 trap #2 * get default disk
|
||
497 000004A6 5240 addq #1,d0 * we want it in range of 1..16
|
||
498 000004A8 12C0 setb3: move.b d0,(a1)+ * move disk number into base page
|
||
499 000004AA 4280 clr.l d0 * function OK
|
||
500 000004AC 4E75 rts
|
||
501
|
||
502
|
||
503 00000000 .bss
|
||
504
|
||
505 * offsets from start of parameter block
|
||
506 FCBPtr = 0
|
||
507 LoAdr = 4
|
||
508 HiAdr = 8
|
||
509 BasPage = 12 * return parameters
|
||
510 Stack = 16
|
||
511 Flags = 21
|
||
512
|
||
513 hdr:
|
||
514 * load file header is read into here
|
||
515 00000000 magic: .ds.w 1
|
||
516 00000002 csize: .ds.l 1
|
||
517 00000006 dsize: .ds.l 1
|
||
518 0000000A bsize: .ds.l 1
|
||
519 0000000E bpsize: .ds.l 1 * symb tbl size is swapped with base page size
|
||
520 00000012 stksize: .ds.l 1
|
||
521 00000016 tstart: .ds.l 1
|
||
522 0000001A rlbflg: .ds.w 1
|
||
523 0000001C dstart: .ds.l 1
|
||
524 00000020 bstart: .ds.l 1
|
||
525
|
||
526 00000024 cseg: .ds.l 1
|
||
527 00000028 dseg: .ds.l 1
|
||
528 0000002C bseg: .ds.l 1
|
||
529 00000030 basepg: .ds.l 1
|
||
530 00000034 stk: .ds.l 1
|
||
531
|
||
532 00000038 symsize: .ds.l 1
|
||
533 0000003C temp: .ds.l 1
|
||
534 00000040 loop: .ds.w 1
|
||
535 00000042 bufbyts: .ds.w 1
|
||
536
|
||
537 00000044 .end
|
||
C P / M 6 8 0 0 0 A s s e m b l e r Revision 02.03 Page 11
|
||
Source File: pgmld.s
|
||
|
||
S y m b o l T a b l e
|
||
|
||
BasPage 0000000C ABS FCBPtr 00000000 ABS Flags 00000015 ABS HiAdr 00000008 ABS
|
||
LoAdr 00000004 ABS Stack 00000010 ABS _pgmld 00000000 TEXT badadr 0000024A TEXT
|
||
badhdr 00000080 TEXT basepg 00000030 BSS bpsize 0000000E BSS bseg 0000002C BSS
|
||
bsize 0000000A BSS bstart 00000020 BSS bufbyts 00000042 BSS chk1 000000E4 TEXT
|
||
chksegs 000000C4 TEXT conf1 000000A8 TEXT confbd 000000B6 TEXT confgd 000000B8 TEXT
|
||
conflict 00000084 TEXT cseg 00000024 BSS csize 00000002 BSS dseg 00000028 BSS
|
||
dsize 00000006 BSS dstart 0000001C BSS finrd 00000308 TEXT fnd1 000000FE TEXT
|
||
fndseg 000000F0 TEXT geth1 00000078 TEXT gethdr 00000060 TEXT hdr 00000000 BSS
|
||
lddone 0000003A TEXT loop 00000040 BSS magic 00000000 BSS moveb1 0000026A TEXT
|
||
moveb2 0000026C TEXT movebuf 0000024E TEXT noreloc 00000032 TEXT rdbad 00000332 TEXT
|
||
rdtxt 00000272 TEXT rdtxt1 0000027E TEXT rdtxt2 00000294 TEXT rdtxt3 000002AE TEXT
|
||
rdtxt4 000002C0 TEXT rdtxt5 000002CA TEXT rdtxt6 000002E6 TEXT rdtxt7 0000032A TEXT
|
||
rdtxt8 00000330 TEXT readseq 00000046 TEXT relabs 00000358 TEXT relbad 00000352 TEXT
|
||
relbss 00000368 TEXT relc1 00000376 TEXT relcode 00000368 TEXT reldata 00000368 TEXT
|
||
rellong 00000360 TEXT reloc 00000380 TEXT reloc1 000003E2 TEXT reloc2 000003E8 TEXT
|
||
reloc3 00000400 TEXT reloc4 00000406 TEXT relocwor 00000336 TEXT relop 00000358 TEXT
|
||
rlbflg 0000001A BSS secsize 00000080 ABS set0 0000014E TEXT set1 0000016C TEXT
|
||
set2 000001AC TEXT set3 000001CC TEXT set4 000001F6 TEXT set5 0000020A TEXT
|
||
set6 0000021E TEXT set7 0000022E TEXT seta 00000160 TEXT setaddr 0000011A TEXT
|
||
setb1 00000486 TEXT setb2 00000490 TEXT setb3 000004A8 TEXT setdma 00000056 TEXT
|
||
setrtn 00000420 TEXT skip1 000003A8 TEXT skip2 000003B8 TEXT skip3 000003C2 TEXT
|
||
sldhi 0000018A TEXT stk 00000034 BSS stksize 00000012 BSS symsize 00000038 BSS
|
||
temp 0000003C BSS trymemtp 000000BA TEXT tstart 00000016 BSS |