Mercurial > hg-old > index.cgi
comparison src/output.c @ 0:57495da01900
Initial checking of LWASM
author | lost |
---|---|
date | Fri, 03 Oct 2008 02:44:20 +0000 |
parents | |
children | 34568fab6058 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:57495da01900 |
---|---|
1 /* | |
2 * output.c | |
3 * | |
4 * code for actually outputting the assembled code | |
5 */ | |
6 | |
7 //#include <ctype.h> | |
8 #include <errno.h> | |
9 #include <stdio.h> | |
10 //#include <stdlib.h> | |
11 #include <string.h> | |
12 #include <unistd.h> | |
13 #define __output_c_seen__ | |
14 //#include "instab.h" | |
15 #include "lwasm.h" | |
16 | |
17 void write_code_raw(asmstate_t *as, FILE *of); | |
18 void write_code_decb(asmstate_t *as, FILE *of); | |
19 void write_code_rawrel(asmstate_t *as, FILE *of); | |
20 | |
21 void write_code(asmstate_t *as) | |
22 { | |
23 FILE *of; | |
24 | |
25 if (as -> errorcount > 0) | |
26 { | |
27 fprintf(stderr, "Not doing output due to assembly errors.\n"); | |
28 return; | |
29 } | |
30 | |
31 of = fopen(as -> outfile, "wb"); | |
32 if (!of) | |
33 { | |
34 fprintf(stderr, "Cannot open '%s' for output", as -> outfile); | |
35 perror(""); | |
36 return; | |
37 } | |
38 | |
39 switch (as -> outformat) | |
40 { | |
41 case OUTPUT_RAW: | |
42 write_code_raw(as, of); | |
43 break; | |
44 | |
45 case OUTPUT_DECB: | |
46 write_code_decb(as, of); | |
47 break; | |
48 | |
49 case OUTPUT_RAWREL: | |
50 write_code_rawrel(as, of); | |
51 break; | |
52 | |
53 default: | |
54 fprintf(stderr, "BUG: unrecognized output format when generating output file\n"); | |
55 fclose(of); | |
56 unlink(as -> outfile); | |
57 return; | |
58 } | |
59 | |
60 fclose(of); | |
61 } | |
62 | |
63 /* | |
64 rawrel output treats an ORG directive as an offset from the start of the | |
65 file. Undefined results will occur if an ORG directive moves the output | |
66 pointer backward. This particular implementation uses "fseek" to handle | |
67 ORG requests and to skip over RMBs. | |
68 | |
69 This simple brain damanged method simply does an fseek before outputting | |
70 each instruction. | |
71 */ | |
72 void write_code_rawrel(asmstate_t *as, FILE *of) | |
73 { | |
74 sourceline_t *cl; | |
75 | |
76 for (cl = as -> source_head; cl; cl = cl -> next) | |
77 { | |
78 if (cl -> nocode) | |
79 continue; | |
80 | |
81 fseek(of, cl -> addr, SEEK_SET); | |
82 fwrite(cl -> codebytes, cl -> numcodebytes, 1, of); | |
83 } | |
84 } | |
85 | |
86 /* | |
87 raw merely writes all the bytes directly to the file as is. ORG is just a | |
88 reference for the assembler to handle absolute references. Multiple ORG | |
89 statements will produce mostly useless results | |
90 */ | |
91 void write_code_raw(asmstate_t *as, FILE *of) | |
92 { | |
93 sourceline_t *cl; | |
94 | |
95 for (cl = as -> source_head; cl; cl = cl -> next) | |
96 { | |
97 if (cl -> nocode && cl -> len > 0) | |
98 { | |
99 int i; | |
100 for (i = 0; i < cl -> len; i++) | |
101 fwrite("\0", 1, 1, of); | |
102 continue; | |
103 } | |
104 if (cl -> nocode) | |
105 continue; | |
106 | |
107 fwrite(cl -> codebytes, cl -> numcodebytes, 1, of); | |
108 } | |
109 } | |
110 | |
111 void write_code_decb(asmstate_t *as, FILE *of) | |
112 { | |
113 long preambloc; | |
114 sourceline_t *cl; | |
115 int blocklen = -1; | |
116 int nextcalc = -1; | |
117 unsigned char outbuf[5]; | |
118 | |
119 for (cl = as -> source_head; cl; cl = cl -> next) | |
120 { | |
121 if (cl -> nocode) | |
122 continue; | |
123 if (cl -> addr != nextcalc && cl -> numcodebytes > 0) | |
124 { | |
125 // need preamble here | |
126 if (blocklen > 0) | |
127 { | |
128 fseek(of, preambloc, SEEK_SET); | |
129 outbuf[0] = (blocklen >> 8) & 0xFF; | |
130 outbuf[1] = blocklen & 0xFF; | |
131 fwrite(outbuf, 2, 1, of); | |
132 fseek(of, 0, SEEK_END); | |
133 } | |
134 blocklen = 0; | |
135 nextcalc = cl -> addr; | |
136 outbuf[0] = 0x00; | |
137 outbuf[1] = 0x00; | |
138 outbuf[2] = 0x00; | |
139 outbuf[3] = (nextcalc >> 8) & 0xFF; | |
140 outbuf[4] = nextcalc & 0xFF; | |
141 preambloc = ftell(of) + 1; | |
142 fwrite(outbuf, 5, 1, of); | |
143 } | |
144 nextcalc += cl -> numcodebytes; | |
145 fwrite(cl -> codebytes, cl -> numcodebytes, 1, of); | |
146 blocklen += cl -> numcodebytes; | |
147 } | |
148 if (blocklen > 0) | |
149 { | |
150 fseek(of, preambloc, SEEK_SET); | |
151 outbuf[0] = (blocklen >> 8) & 0xFF; | |
152 outbuf[1] = blocklen & 0xFF; | |
153 fwrite(outbuf, 2, 1, of); | |
154 fseek(of, 0, SEEK_END); | |
155 } | |
156 | |
157 // now write postamble | |
158 outbuf[0] = 0xFF; | |
159 outbuf[1] = 0x00; | |
160 outbuf[2] = 0x00; | |
161 outbuf[3] = (as -> execaddr >> 8) & 0xFF; | |
162 outbuf[4] = (as -> execaddr) & 0xFF; | |
163 fwrite(outbuf, 5, 1, of); | |
164 } |