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