/[gxemul]/upstream/0.3.4/experiments/rssb_as.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Contents of /upstream/0.3.4/experiments/rssb_as.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 11 - (show annotations)
Mon Oct 8 16:18:31 2007 UTC (16 years, 7 months ago) by dpavlin
File MIME type: text/plain
File size: 6737 byte(s)
0.3.4
1 /*
2 * Copyright (C) 2002,2005 Anders Gavare. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * 3. The name of the author may not be used to endorse or promote products
13 * derived from this software without specific prior written permission.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 * $Id: rssb_as.c,v 1.3 2005/06/20 05:52:45 debug Exp $
28 *
29 * A simple assembler for URISC ("reverse subtract and skip on borrow").
30 */
31
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <inttypes.h>
36
37
38 #define MAX_SYMBOL_LEN 64
39
40 struct symbol {
41 char name[MAX_SYMBOL_LEN];
42 uint32_t addr;
43 struct symbol *next;
44 };
45
46
47 struct symbol *first_symbol = NULL;
48
49
50 int debug = 0;
51
52
53 uint32_t get_symbol(char *symbol)
54 {
55 struct symbol *s;
56
57 s = first_symbol;
58 while (s != NULL) {
59 if (strcmp(symbol, s->name) == 0)
60 return s->addr;
61
62 s = s->next;
63 }
64
65 fprintf(stderr, "undefined symbol '%s'\n", symbol);
66 exit(1);
67 }
68
69
70 void add_symbol(char *symbol, uint32_t addr)
71 {
72 struct symbol *s;
73
74 if (strlen(symbol) > MAX_SYMBOL_LEN-1) {
75 fprintf(stderr, "symbol '%s' too long\n", symbol);
76 exit(1);
77 }
78
79 s = malloc(sizeof(struct symbol));
80 if (s == NULL) {
81 fprintf(stderr, "out of memory\n");
82 exit(1);
83 }
84
85 strlcpy(s->name, symbol, MAX_SYMBOL_LEN);
86 s->addr = addr;
87
88 if (debug > 1)
89 printf(" %08x = %s\n", addr, symbol);
90
91 s->next = first_symbol;
92 first_symbol = s;
93 }
94
95
96 uint32_t pass1(FILE *fin)
97 {
98 uint32_t curaddr = 0;
99 char line[200];
100 int lineno = 0;
101
102 if (debug > 0)
103 printf("Pass 1\n");
104
105 while (!feof(fin)) {
106 line[0] = '\0';
107 fgets(line, sizeof(line), fin);
108 lineno++;
109 if (line[0]) {
110 if (line[strlen(line)-1]=='\n')
111 line[strlen(line)-1]=0;
112
113 if (debug > 2)
114 printf(" addr=%08x line='%s'\n",
115 curaddr,line);
116
117 switch (line[0]) {
118 case '\0':
119 case '#':
120 break;
121 case 'L':
122 /* Add a symbol: */
123 add_symbol(line+1, curaddr);
124 break;
125 case 'A':
126 case 'D':
127 case 'E':
128 /* Increase addr by 4: */
129 curaddr += sizeof(uint32_t);
130 break;
131 case 'O':
132 /* Set orig manually: */
133 curaddr = atoi(line+1);
134 break;
135 default:
136 fprintf(stderr, "error on input line %i\n",
137 lineno);
138 exit(1);
139 }
140 }
141 }
142
143 return curaddr;
144 }
145
146
147 void pass2(FILE *fin, FILE *fout, uint32_t first_diffaddr)
148 {
149 uint32_t curaddr = 0;
150 uint32_t curdiffaddr = first_diffaddr;
151 uint32_t value, value2;
152 char line[200];
153 int lineno = 0;
154 char *p;
155 unsigned char b1;
156 unsigned char b2;
157 unsigned char b3;
158 unsigned char b4;
159
160 if (debug > 0)
161 printf("Pass 2\n");
162
163 while (!feof(fin)) {
164 line[0] = '\0';
165 fgets(line, sizeof(line), fin);
166 lineno++;
167 if (line[0]) {
168 if (line[strlen(line)-1]=='\n')
169 line[strlen(line)-1]=0;
170
171 if (debug > 2)
172 printf(" addr=%08x line='%s'\n",
173 curaddr,line);
174
175 switch (line[0]) {
176 case '\0':
177 case '#':
178 case 'L':
179 break;
180 case 'A':
181 /* Output value and increase addr by 4: */
182 fseek(fout, curaddr, SEEK_SET);
183 if (line[1]>='0' && line[1]<='9')
184 value = atoi(line+1);
185 else
186 value = get_symbol(line+1);
187 b1 = value >> 24;
188 b2 = value >> 16;
189 b3 = value >> 8;
190 b4 = value;
191 fwrite(&b1, 1, 1, fout);
192 fwrite(&b2, 1, 1, fout);
193 fwrite(&b3, 1, 1, fout);
194 fwrite(&b4, 1, 1, fout);
195
196 curaddr += sizeof(uint32_t);
197 break;
198 case 'D':
199 case 'E':
200 /* Address differance calculation: */
201 p = line+1;
202 while (*p && *p!=' ')
203 p++;
204 if (!*p) {
205 fprintf(stderr, "error on input line"
206 " %i, D syntax error\n", lineno);
207 exit(1);
208 }
209 p[0]=0; p++;
210
211 if (line[1]>='0' && line[1]<='9')
212 value = atoi(line+1);
213 else
214 value = get_symbol(line+1);
215
216 if (p[0]>='0' && p[0]<='9')
217 value2 = atoi(p);
218 else
219 value2 = get_symbol(p);
220
221 if (line[0]=='D') {
222 if (value < value2)
223 value = value - value2 + 4;
224 else
225 value = value - value2;
226 } else {
227 /* In conditional jumps: The -4
228 is because PC is already
229 updated when it is written
230 back to: */
231 value = value - value2 - 4;
232 }
233
234 /* Output value in the diff section: */
235 fseek(fout, curdiffaddr, SEEK_SET);
236 b1 = value >> 24;
237 b2 = value >> 16;
238 b3 = value >> 8;
239 b4 = value;
240 fwrite(&b1, 1, 1, fout);
241 fwrite(&b2, 1, 1, fout);
242 fwrite(&b3, 1, 1, fout);
243 fwrite(&b4, 1, 1, fout);
244
245 /* Output the diff addr to the code section: */
246 fseek(fout, curaddr, SEEK_SET);
247 value = curdiffaddr;
248 b1 = value >> 24;
249 b2 = value >> 16;
250 b3 = value >> 8;
251 b4 = value;
252 fwrite(&b1, 1, 1, fout);
253 fwrite(&b2, 1, 1, fout);
254 fwrite(&b3, 1, 1, fout);
255 fwrite(&b4, 1, 1, fout);
256
257 curaddr += sizeof(uint32_t);
258 curdiffaddr += sizeof(uint32_t);
259 break;
260 case 'O':
261 /* Set orig manually: */
262 curaddr = atoi(line+1);
263 break;
264 default:
265 fprintf(stderr, "error on input line %i\n",
266 lineno);
267 exit(1);
268 }
269 }
270 }
271 }
272
273
274 int main(int argc, char *argv[])
275 {
276 FILE *fin, *fout;
277 uint32_t first_diffaddr;
278
279 if (argc != 3) {
280 fprintf(stderr, "usage: %s asmsource binimage\n", argv[0]);
281 fprintf(stderr, "Input is read from asmsource and "
282 "output is written to binimage\n");
283 exit(1);
284 }
285
286 fin = fopen(argv[1], "r");
287 if (fin == NULL) {
288 perror(argv[1]);
289 exit(2);
290 }
291
292 fout = fopen(argv[2], "w");
293 if (fout = NULL) {
294 perror(argv[2]);
295 exit(2);
296 }
297
298 first_diffaddr = pass1(fin);
299 fseek(fin, 0, SEEK_SET);
300 pass2(fin, fout, first_diffaddr);
301
302 fclose(fin);
303 fclose(fout);
304
305 return 0;
306 }
307

  ViewVC Help
Powered by ViewVC 1.1.26