Mercurial > hg > index.cgi
comparison lwasm/output.c @ 406:4411a6123716
Add "basic" output format
Add "basic" output format. This outputs the code in the form of a Basic
program that installs the assembled output. If an execution address is
provided to the END pseudo operation, it will transfer control there using
the Basic EXEC command.
Thanks to Tim Lindner <tlindner@macmess.org> for the original patch. I used
it mostly as is except for a couple of minor fixes for coding style and
removing a variable declaration from inside a for() statement for
portability reasons.
author | William Astle <lost@l-w.ca> |
---|---|
date | Thu, 03 Mar 2016 21:04:39 -0700 |
parents | ade217fd76a5 |
children | 7f538053492c |
comparison
equal
deleted
inserted
replaced
405:4c8925f97eb5 | 406:4411a6123716 |
---|---|
33 | 33 |
34 #include "lwasm.h" | 34 #include "lwasm.h" |
35 | 35 |
36 void write_code_raw(asmstate_t *as, FILE *of); | 36 void write_code_raw(asmstate_t *as, FILE *of); |
37 void write_code_decb(asmstate_t *as, FILE *of); | 37 void write_code_decb(asmstate_t *as, FILE *of); |
38 void write_code_BASIC(asmstate_t *as, FILE *of); | |
38 void write_code_rawrel(asmstate_t *as, FILE *of); | 39 void write_code_rawrel(asmstate_t *as, FILE *of); |
39 void write_code_obj(asmstate_t *as, FILE *of); | 40 void write_code_obj(asmstate_t *as, FILE *of); |
40 void write_code_os9(asmstate_t *as, FILE *of); | 41 void write_code_os9(asmstate_t *as, FILE *of); |
41 void write_code_hex(asmstate_t *as, FILE *of); | 42 void write_code_hex(asmstate_t *as, FILE *of); |
42 void write_code_srec(asmstate_t *as, FILE *of); | 43 void write_code_srec(asmstate_t *as, FILE *of); |
71 break; | 72 break; |
72 | 73 |
73 case OUTPUT_DECB: | 74 case OUTPUT_DECB: |
74 write_code_decb(as, of); | 75 write_code_decb(as, of); |
75 break; | 76 break; |
77 | |
78 case OUTPUT_BASIC: | |
79 write_code_BASIC(as, of); | |
80 break; | |
76 | 81 |
77 case OUTPUT_RAWREL: | 82 case OUTPUT_RAWREL: |
78 write_code_rawrel(as, of); | 83 write_code_rawrel(as, of); |
79 break; | 84 break; |
80 | 85 |
105 return; | 110 return; |
106 } | 111 } |
107 | 112 |
108 fclose(of); | 113 fclose(of); |
109 } | 114 } |
115 | |
116 int write_code_BASIC_fprintf(FILE *of, int linelength, int *linenumber, int value) | |
117 { | |
118 if (linelength > 247) | |
119 { | |
120 fprintf(of, "\n"); | |
121 linelength = fprintf(of, "%d DATA ", *linenumber); | |
122 *linenumber += 10; | |
123 } | |
124 else | |
125 { | |
126 linelength += fprintf(of, ","); | |
127 } | |
128 linelength += fprintf(of, "%d", value); | |
129 | |
130 return linelength; | |
131 } | |
132 | |
133 void write_code_BASIC(asmstate_t *as, FILE *of) | |
134 { | |
135 line_t *cl; | |
136 line_t *startblock = as -> line_head; | |
137 line_t *endblock; | |
138 int linenumber, linelength, startaddress, lastaddress, address; | |
139 int outidx; | |
140 | |
141 fprintf(of, "10 READ A,B\n"); | |
142 fprintf(of, "20 IF A=-1 THEN 70\n"); | |
143 fprintf(of, "30 FOR C = A TO B\n"); | |
144 fprintf(of, "40 READ D:POKE C,D\n"); | |
145 fprintf(of, "50 NEXT C\n"); | |
146 fprintf(of, "60 GOTO 10\n"); | |
147 | |
148 if (as -> execaddr == 0) | |
149 { | |
150 fprintf(of, "70 END"); | |
151 } | |
152 else | |
153 { | |
154 fprintf(of, "70 EXEC %d", as -> execaddr); | |
155 } | |
156 | |
157 linenumber = 80; | |
158 linelength = 255; | |
159 | |
160 while(startblock) | |
161 { | |
162 startaddress = -1; | |
163 endblock = NULL; | |
164 | |
165 for (cl = startblock; cl; cl = cl -> next) | |
166 { | |
167 if (cl -> outputl < 0) | |
168 continue; | |
169 | |
170 address = lw_expr_intval(cl -> addr); | |
171 | |
172 if (startaddress == -1) | |
173 { | |
174 startaddress = address; | |
175 lastaddress = address + cl -> outputl - 1; | |
176 } | |
177 else | |
178 { | |
179 if (lastaddress != address - 1) | |
180 { | |
181 endblock = cl; | |
182 break; | |
183 } | |
184 | |
185 lastaddress += cl -> outputl; | |
186 } | |
187 } | |
188 | |
189 linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, startaddress); | |
190 linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, lastaddress); | |
191 | |
192 for (cl = startblock; cl != endblock; cl = cl -> next) | |
193 { | |
194 if (cl -> outputl < 0) | |
195 continue; | |
196 | |
197 for (outidx=0; outidx<cl -> outputl; outidx++) | |
198 { | |
199 linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, cl -> output[outidx]); | |
200 } | |
201 } | |
202 | |
203 startblock = cl; | |
204 } | |
205 | |
206 linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, -1); | |
207 linelength = write_code_BASIC_fprintf(of, linelength, &linenumber, -1); | |
208 | |
209 fprintf(of, "\n"); | |
210 } | |
211 | |
110 | 212 |
111 /* | 213 /* |
112 rawrel output treats an ORG directive as an offset from the start of the | 214 rawrel output treats an ORG directive as an offset from the start of the |
113 file. Undefined results will occur if an ORG directive moves the output | 215 file. Undefined results will occur if an ORG directive moves the output |
114 pointer backward. This particular implementation uses "fseek" to handle | 216 pointer backward. This particular implementation uses "fseek" to handle |