annotate src/output.c @ 68:cef25b0088e6

Fixed some problems detected by valgrind and testing
author lost
date Mon, 05 Jan 2009 06:14:41 +0000
parents 6de358e7903f
children 918be0c02239
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
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
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
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
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
23
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
24 //#include <ctype.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
25 #include <errno.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
26 #include <stdio.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
27 //#include <stdlib.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
28 #include <string.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
29 #include <unistd.h>
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
30 #define __output_c_seen__
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
31 //#include "instab.h"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
32 #include "lwasm.h"
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
33
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
34 void write_code_raw(asmstate_t *as, FILE *of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
35 void write_code_decb(asmstate_t *as, FILE *of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
36 void write_code_rawrel(asmstate_t *as, FILE *of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
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
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
41 void lwasm_output(asmstate_t *as)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
42 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
43 FILE *of;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
44
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
45 if (as -> errorcount > 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
46 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
47 fprintf(stderr, "Not doing output due to assembly errors.\n");
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
48 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
49 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
50
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
51 of = fopen(as -> outfile, "wb");
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
52 if (!of)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
53 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
54 fprintf(stderr, "Cannot open '%s' for output", as -> outfile);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
55 perror("");
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
56 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
57 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
58
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
59 switch (as -> outformat)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
60 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
61 case OUTPUT_RAW:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
62 write_code_raw(as, of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
63 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
64
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
65 case OUTPUT_DECB:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
66 write_code_decb(as, of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
67 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
68
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
69 case OUTPUT_RAWREL:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
70 write_code_rawrel(as, of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
71 break;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
72
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
73 default:
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
74 fprintf(stderr, "BUG: unrecognized output format when generating output file\n");
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
75 fclose(of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
76 unlink(as -> outfile);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
77 return;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
78 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
79
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
80 fclose(of);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
81 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
82
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
83 /*
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
84 rawrel output treats an ORG directive as an offset from the start of the
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
85 file. Undefined results will occur if an ORG directive moves the output
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
86 pointer backward. This particular implementation uses "fseek" to handle
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
87 ORG requests and to skip over RMBs.
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
88
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
89 This simple brain damanged method simply does an fseek before outputting
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
90 each instruction.
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
91 */
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
92 void write_code_rawrel(asmstate_t *as, FILE *of)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
93 {
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
94 lwasm_line_t *cl;
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
95
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
96 for (cl = as -> lineshead; cl; cl = cl -> next)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
97 {
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
98 if (cl -> codelen == 0)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
99 continue;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
100
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
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
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
103 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
104 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
105
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
106 /*
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
107 raw merely writes all the bytes directly to the file as is. ORG is just a
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
108 reference for the assembler to handle absolute references. Multiple ORG
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
109 statements will produce mostly useless results
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
110 */
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
111 void write_code_raw(asmstate_t *as, FILE *of)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
112 {
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
113 lwasm_line_t *cl;
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
114
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
115 for (cl = as -> lineshead; cl; cl = cl -> next)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
116 {
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
117 if (cl -> nocodelen)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
118 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
119 int i;
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
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
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
122 continue;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
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
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
125 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
126 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
127
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
128 void write_code_decb(asmstate_t *as, FILE *of)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
129 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
130 long preambloc;
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
131 lwasm_line_t *cl;
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
132 int blocklen = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
133 int nextcalc = -1;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
134 unsigned char outbuf[5];
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
135
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
136 for (cl = as -> lineshead; cl; cl = cl -> next)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
137 {
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
138 if (cl -> nocodelen)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
139 continue;
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
140 if (cl -> codeaddr != nextcalc && cl -> codelen > 0)
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
141 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
142 // need preamble here
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
143 if (blocklen > 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
144 {
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
145 // update previous preamble if needed
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
146 fseek(of, preambloc, SEEK_SET);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
147 outbuf[0] = (blocklen >> 8) & 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
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
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
150 fseek(of, 0, SEEK_END);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
151 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
152 blocklen = 0;
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
153 nextcalc = cl -> codeaddr;
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
154 outbuf[0] = 0x00;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
155 outbuf[1] = 0x00;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
156 outbuf[2] = 0x00;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
157 outbuf[3] = (nextcalc >> 8) & 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
158 outbuf[4] = nextcalc & 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
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
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
161 }
46
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
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
b962cee20bf4 Ported output modules forward from old version
lost
parents: 4
diff changeset
164 blocklen += cl -> codelen;
0
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
165 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
166 if (blocklen > 0)
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
167 {
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
168 fseek(of, preambloc, SEEK_SET);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
169 outbuf[0] = (blocklen >> 8) & 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
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
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
172 fseek(of, 0, SEEK_END);
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
173 }
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
174
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
175 // now write postamble
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
176 outbuf[0] = 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
177 outbuf[1] = 0x00;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
178 outbuf[2] = 0x00;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
179 outbuf[3] = (as -> execaddr >> 8) & 0xFF;
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
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
57495da01900 Initial checking of LWASM
lost
parents:
diff changeset
182 }