comparison lwlink/output.c @ 148:08fb11004df9

Initial pass at OS9 module support for lwlink
author lost@l-w.ca
date Fri, 26 Aug 2011 23:26:00 -0600
parents 2c24602be78f
children 3b58d76ea032
comparison
equal deleted inserted replaced
147:9cf1796259b2 148:08fb11004df9
30 // this prevents warnings about not using the return value of fwrite() 30 // this prevents warnings about not using the return value of fwrite()
31 // and, theoretically, can be replaced with a function that handles things 31 // and, theoretically, can be replaced with a function that handles things
32 // better in the future 32 // better in the future
33 #define writebytes(s, l, c, f) do { int r; r = fwrite((s), (l), (c), (f)); } while (0) 33 #define writebytes(s, l, c, f) do { int r; r = fwrite((s), (l), (c), (f)); } while (0)
34 34
35 void do_output_os9(FILE *of);
35 void do_output_decb(FILE *of); 36 void do_output_decb(FILE *of);
36 void do_output_raw(FILE *of); 37 void do_output_raw(FILE *of);
37 void do_output_lwex0(FILE *of); 38 void do_output_lwex0(FILE *of);
38 39
39 void do_output(void) 40 void do_output(void)
60 61
61 case OUTPUT_LWEX0: 62 case OUTPUT_LWEX0:
62 do_output_lwex0(of); 63 do_output_lwex0(of);
63 break; 64 break;
64 65
66 case OUTPUT_OS9:
67 do_output_os9(of);
68 break;
69
65 default: 70 default:
66 fprintf(stderr, "Unknown output format doing output!\n"); 71 fprintf(stderr, "Unknown output format doing output!\n");
67 exit(111); 72 exit(111);
68 } 73 }
69 74
211 nskips--; 216 nskips--;
212 } 217 }
213 writebytes(sectlist[sn].ptr -> code, 1, sectlist[sn].ptr -> codesize, of); 218 writebytes(sectlist[sn].ptr -> code, 1, sectlist[sn].ptr -> codesize, of);
214 } 219 }
215 } 220 }
221
222 void os9crc(unsigned char crc[3], unsigned char b)
223 {
224 b ^= crc[0];
225 crc[0] = crc[1];
226 crc[1] = crc[2];
227 crc[1] ^= b >> 7;
228 crc[2] = b << 1;
229 crc[1] ^= b >> 2;
230 crc[2] ^= b << 6;
231 b ^= b << 1;
232 b ^= b << 2;
233 b ^= b << 4;
234 if (b & 0x80)
235 {
236 crc[0] ^= 0x80;
237 crc[2] ^= 0x21;
238 }
239 }
240
241
242 void do_output_os9(FILE *of)
243 {
244 int sn;
245 int codedatasize = 0;
246 int bsssize = 0;
247 int i;
248
249 unsigned char buf[16];
250 unsigned char crc[3];
251
252 // calculate items for the file header
253 for (sn = 0; sn < nsects; sn++)
254 {
255 if (sectlist[sn].ptr -> flags & SECTION_BSS)
256 {
257 // no output for a BSS section
258 bsssize += sectlist[sn].ptr -> codesize;
259 continue;
260 }
261 codedatasize += sectlist[sn].ptr -> codesize;
262 }
263
264 // now bss size is the data size for the module
265 // and codesize is the length of the module minus the module header
266 // and CRC
267
268 codedatasize += 16; // add in headers
269 codedatasize += strlen(linkscript.name); // add in name length
270
271 // output the file header
272 buf[0] = 0x87;
273 buf[1] = 0xCD;
274 buf[2] = (codedatasize >> 8) & 0xff;
275 buf[3] = codedatasize & 0xff;
276 buf[4] = 0;
277 buf[5] = 13;
278 buf[6] = (linkscript.modtype << 4) | (linkscript.modlang);
279 buf[7] = (linkscript.modattr << 4) | (linkscript.modrev);
280 buf[8] = (~(buf[0] ^ buf[1] ^ buf[2] ^ buf[3] ^ buf[4] ^ buf[5] ^ buf[6] ^ buf[7])) & 0xff;
281 buf[9] = (linkscript.execaddr >> 8) & 0xff;
282 buf[10] = linkscript.execaddr & 0xff;
283 buf[11] = (bsssize >> 8) & 0xff;
284 buf[12] = bsssize & 0xff;
285
286 crc[0] = 0xff;
287 crc[1] = 0xff;
288 crc[2] = 0xff;
289
290 os9crc(crc, buf[0]);
291 os9crc(crc, buf[1]);
292 os9crc(crc, buf[2]);
293 os9crc(crc, buf[3]);
294 os9crc(crc, buf[4]);
295 os9crc(crc, buf[5]);
296 os9crc(crc, buf[6]);
297 os9crc(crc, buf[7]);
298 os9crc(crc, buf[8]);
299 os9crc(crc, buf[9]);
300 os9crc(crc, buf[10]);
301 os9crc(crc, buf[11]);
302 os9crc(crc, buf[12]);
303
304
305 writebytes(buf, 1, 13, of);
306
307 // output the name
308 for (i = 0; linkscript.name[i + 1]; i++)
309 {
310 writebytes(linkscript.name + i, 1, 1, of);
311 os9crc(crc, linkscript.name[i]);
312 }
313 buf[0] = linkscript.name[i] | 0x80;
314 writebytes(buf, 1, 1, of);
315 os9crc(crc, buf[0]);
316
317 // output the data
318 // NOTE: disjoint load addresses will not work correctly!!!!!
319 for (sn = 0; sn < nsects; sn++)
320 {
321 if (sectlist[sn].ptr -> flags & SECTION_BSS)
322 {
323 // no output for a BSS section
324 continue;
325 }
326 writebytes(sectlist[sn].ptr -> code, 1, sectlist[sn].ptr -> codesize, of);
327 for (i = 0; i < sectlist[sn].ptr -> codesize; i++)
328 os9crc(crc, sectlist[sn].ptr -> code[i]);
329 }
330
331 crc[0] ^= 0xff;
332 crc[1] ^= 0xff;
333 crc[2] ^= 0xff;
334 writebytes(crc, 1, 3, of);
335 }