Mercurial > hg > index.cgi
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 } |