Mercurial > hg-old > index.cgi
annotate src/output.c @ 74:c8c772ef5df9
Checkpointing object target implementation
author | lost |
---|---|
date | Thu, 08 Jan 2009 01:18:40 +0000 |
parents | 6de358e7903f |
children | 918be0c02239 |
rev | line source |
---|---|
0 | 1 /* |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
2 output.c |
46 | 3 Copyright © 2009 William Astle |
4
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
4 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
5 This file is part of LWASM. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
6 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
7 LWASM is free software: you can redistribute it and/or modify it under the |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
8 terms of the GNU General Public License as published by the Free Software |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
9 Foundation, either version 3 of the License, or (at your option) any later |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
10 version. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
11 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
12 This program is distributed in the hope that it will be useful, but WITHOUT |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
15 more details. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
16 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
17 You should have received a copy of the GNU General Public License along with |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
18 this program. If not, see <http://www.gnu.org/licenses/>. |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
19 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
20 |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
21 Contains the code for actually outputting the assembled code |
34568fab6058
Fixed package to include all required files; also added copyright preamble to all source files
lost
parents:
0
diff
changeset
|
22 */ |
0 | 23 |
24 //#include <ctype.h> | |
25 #include <errno.h> | |
26 #include <stdio.h> | |
27 //#include <stdlib.h> | |
28 #include <string.h> | |
29 #include <unistd.h> | |
30 #define __output_c_seen__ | |
31 //#include "instab.h" | |
32 #include "lwasm.h" | |
33 | |
34 void write_code_raw(asmstate_t *as, FILE *of); | |
35 void write_code_decb(asmstate_t *as, FILE *of); | |
36 void write_code_rawrel(asmstate_t *as, FILE *of); | |
37 | |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
38 // this prevents warnings about not using the return value of fwrite() |
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
39 #define writebytes(s, l, c, f) do { int r; r = fwrite((s), (l), (c), (f)); } while (0) |
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
40 |
46 | 41 void lwasm_output(asmstate_t *as) |
0 | 42 { |
43 FILE *of; | |
44 | |
45 if (as -> errorcount > 0) | |
46 { | |
47 fprintf(stderr, "Not doing output due to assembly errors.\n"); | |
48 return; | |
49 } | |
50 | |
51 of = fopen(as -> outfile, "wb"); | |
52 if (!of) | |
53 { | |
54 fprintf(stderr, "Cannot open '%s' for output", as -> outfile); | |
55 perror(""); | |
56 return; | |
57 } | |
58 | |
59 switch (as -> outformat) | |
60 { | |
61 case OUTPUT_RAW: | |
62 write_code_raw(as, of); | |
63 break; | |
64 | |
65 case OUTPUT_DECB: | |
66 write_code_decb(as, of); | |
67 break; | |
68 | |
69 case OUTPUT_RAWREL: | |
70 write_code_rawrel(as, of); | |
71 break; | |
72 | |
73 default: | |
74 fprintf(stderr, "BUG: unrecognized output format when generating output file\n"); | |
75 fclose(of); | |
76 unlink(as -> outfile); | |
77 return; | |
78 } | |
79 | |
80 fclose(of); | |
81 } | |
82 | |
83 /* | |
84 rawrel output treats an ORG directive as an offset from the start of the | |
85 file. Undefined results will occur if an ORG directive moves the output | |
86 pointer backward. This particular implementation uses "fseek" to handle | |
87 ORG requests and to skip over RMBs. | |
88 | |
89 This simple brain damanged method simply does an fseek before outputting | |
90 each instruction. | |
91 */ | |
92 void write_code_rawrel(asmstate_t *as, FILE *of) | |
93 { | |
46 | 94 lwasm_line_t *cl; |
0 | 95 |
46 | 96 for (cl = as -> lineshead; cl; cl = cl -> next) |
0 | 97 { |
46 | 98 if (cl -> codelen == 0) |
0 | 99 continue; |
100 | |
46 | 101 fseek(of, cl -> codeaddr, SEEK_SET); |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
102 writebytes(cl -> bytes, cl -> codelen, 1, of); |
0 | 103 } |
104 } | |
105 | |
106 /* | |
107 raw merely writes all the bytes directly to the file as is. ORG is just a | |
108 reference for the assembler to handle absolute references. Multiple ORG | |
109 statements will produce mostly useless results | |
110 */ | |
111 void write_code_raw(asmstate_t *as, FILE *of) | |
112 { | |
46 | 113 lwasm_line_t *cl; |
0 | 114 |
46 | 115 for (cl = as -> lineshead; cl; cl = cl -> next) |
0 | 116 { |
46 | 117 if (cl -> nocodelen) |
0 | 118 { |
119 int i; | |
46 | 120 for (i = 0; i < cl -> nocodelen; i++) |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
121 writebytes("\0", 1, 1, of); |
0 | 122 continue; |
123 } | |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
124 writebytes(cl -> bytes, cl -> codelen, 1, of); |
0 | 125 } |
126 } | |
127 | |
128 void write_code_decb(asmstate_t *as, FILE *of) | |
129 { | |
130 long preambloc; | |
46 | 131 lwasm_line_t *cl; |
0 | 132 int blocklen = -1; |
133 int nextcalc = -1; | |
134 unsigned char outbuf[5]; | |
135 | |
46 | 136 for (cl = as -> lineshead; cl; cl = cl -> next) |
0 | 137 { |
46 | 138 if (cl -> nocodelen) |
0 | 139 continue; |
46 | 140 if (cl -> codeaddr != nextcalc && cl -> codelen > 0) |
0 | 141 { |
142 // need preamble here | |
143 if (blocklen > 0) | |
144 { | |
46 | 145 // update previous preamble if needed |
0 | 146 fseek(of, preambloc, SEEK_SET); |
147 outbuf[0] = (blocklen >> 8) & 0xFF; | |
148 outbuf[1] = blocklen & 0xFF; | |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
149 writebytes(outbuf, 2, 1, of); |
0 | 150 fseek(of, 0, SEEK_END); |
151 } | |
152 blocklen = 0; | |
46 | 153 nextcalc = cl -> codeaddr; |
0 | 154 outbuf[0] = 0x00; |
155 outbuf[1] = 0x00; | |
156 outbuf[2] = 0x00; | |
157 outbuf[3] = (nextcalc >> 8) & 0xFF; | |
158 outbuf[4] = nextcalc & 0xFF; | |
159 preambloc = ftell(of) + 1; | |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
160 writebytes(outbuf, 5, 1, of); |
0 | 161 } |
46 | 162 nextcalc += cl -> codelen; |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
163 writebytes(cl -> bytes, cl -> codelen, 1, of); |
46 | 164 blocklen += cl -> codelen; |
0 | 165 } |
166 if (blocklen > 0) | |
167 { | |
168 fseek(of, preambloc, SEEK_SET); | |
169 outbuf[0] = (blocklen >> 8) & 0xFF; | |
170 outbuf[1] = blocklen & 0xFF; | |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
171 writebytes(outbuf, 2, 1, of); |
0 | 172 fseek(of, 0, SEEK_END); |
173 } | |
174 | |
175 // now write postamble | |
176 outbuf[0] = 0xFF; | |
177 outbuf[1] = 0x00; | |
178 outbuf[2] = 0x00; | |
179 outbuf[3] = (as -> execaddr >> 8) & 0xFF; | |
180 outbuf[4] = (as -> execaddr) & 0xFF; | |
48
6de358e7903f
Cleaned up warnings about the return value of fwrite() being ignored (it still is but now there's no warning)
lost
parents:
46
diff
changeset
|
181 writebytes(outbuf, 5, 1, of); |
0 | 182 } |