/[gxemul]/upstream/0.3.3.1/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.3.1/experiments/rssb_as.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 7 - (show annotations)
Mon Oct 8 16:18:14 2007 UTC (16 years, 6 months ago) by dpavlin
File MIME type: text/plain
File size: 6750 byte(s)
0.3.3.1
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.2 2005/03/08 23:10:10 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 strcpy(s->name, symbol);
86 s->name[strlen(symbol)] = 0;
87 s->addr = addr;
88
89 if (debug > 1)
90 printf(" %08x = %s\n", addr, symbol);
91
92 s->next = first_symbol;
93 first_symbol = s;
94 }
95
96
97 uint32_t pass1(FILE *fin)
98 {
99 uint32_t curaddr = 0;
100 char line[200];
101 int lineno = 0;
102
103 if (debug > 0)
104 printf("Pass 1\n");
105
106 while (!feof(fin)) {
107 line[0] = '\0';
108 fgets(line, sizeof(line), fin);
109 lineno++;
110 if (line[0]) {
111 if (line[strlen(line)-1]=='\n')
112 line[strlen(line)-1]=0;
113
114 if (debug > 2)
115 printf(" addr=%08x line='%s'\n",
116 curaddr,line);
117
118 switch (line[0]) {
119 case '\0':
120 case '#':
121 break;
122 case 'L':
123 /* Add a symbol: */
124 add_symbol(line+1, curaddr);
125 break;
126 case 'A':
127 case 'D':
128 case 'E':
129 /* Increase addr by 4: */
130 curaddr += sizeof(uint32_t);
131 break;
132 case 'O':
133 /* Set orig manually: */
134 curaddr = atoi(line+1);
135 break;
136 default:
137 fprintf(stderr, "error on input line %i\n",
138 lineno);
139 exit(1);
140 }
141 }
142 }
143
144 return curaddr;
145 }
146
147
148 void pass2(FILE *fin, FILE *fout, uint32_t first_diffaddr)
149 {
150 uint32_t curaddr = 0;
151 uint32_t curdiffaddr = first_diffaddr;
152 uint32_t value, value2;
153 char line[200];
154 int lineno = 0;
155 char *p;
156 unsigned char b1;
157 unsigned char b2;
158 unsigned char b3;
159 unsigned char b4;
160
161 if (debug > 0)
162 printf("Pass 2\n");
163
164 while (!feof(fin)) {
165 line[0] = '\0';
166 fgets(line, sizeof(line), fin);
167 lineno++;
168 if (line[0]) {
169 if (line[strlen(line)-1]=='\n')
170 line[strlen(line)-1]=0;
171
172 if (debug > 2)
173 printf(" addr=%08x line='%s'\n",
174 curaddr,line);
175
176 switch (line[0]) {
177 case '\0':
178 case '#':
179 case 'L':
180 break;
181 case 'A':
182 /* Output value and increase addr by 4: */
183 fseek(fout, curaddr, SEEK_SET);
184 if (line[1]>='0' && line[1]<='9')
185 value = atoi(line+1);
186 else
187 value = get_symbol(line+1);
188 b1 = value >> 24;
189 b2 = value >> 16;
190 b3 = value >> 8;
191 b4 = value;
192 fwrite(&b1, 1, 1, fout);
193 fwrite(&b2, 1, 1, fout);
194 fwrite(&b3, 1, 1, fout);
195 fwrite(&b4, 1, 1, fout);
196
197 curaddr += sizeof(uint32_t);
198 break;
199 case 'D':
200 case 'E':
201 /* Address differance calculation: */
202 p = line+1;
203 while (*p && *p!=' ')
204 p++;
205 if (!*p) {
206 fprintf(stderr, "error on input line"
207 " %i, D syntax error\n", lineno);
208 exit(1);
209 }
210 p[0]=0; p++;
211
212 if (line[1]>='0' && line[1]<='9')
213 value = atoi(line+1);
214 else
215 value = get_symbol(line+1);
216
217 if (p[0]>='0' && p[0]<='9')
218 value2 = atoi(p);
219 else
220 value2 = get_symbol(p);
221
222 if (line[0]=='D') {
223 if (value < value2)
224 value = value - value2 + 4;
225 else
226 value = value - value2;
227 } else {
228 /* In conditional jumps: The -4
229 is because PC is already
230 updated when it is written
231 back to: */
232 value = value - value2 - 4;
233 }
234
235 /* Output value in the diff section: */
236 fseek(fout, curdiffaddr, SEEK_SET);
237 b1 = value >> 24;
238 b2 = value >> 16;
239 b3 = value >> 8;
240 b4 = value;
241 fwrite(&b1, 1, 1, fout);
242 fwrite(&b2, 1, 1, fout);
243 fwrite(&b3, 1, 1, fout);
244 fwrite(&b4, 1, 1, fout);
245
246 /* Output the diff addr to the code section: */
247 fseek(fout, curaddr, SEEK_SET);
248 value = curdiffaddr;
249 b1 = value >> 24;
250 b2 = value >> 16;
251 b3 = value >> 8;
252 b4 = value;
253 fwrite(&b1, 1, 1, fout);
254 fwrite(&b2, 1, 1, fout);
255 fwrite(&b3, 1, 1, fout);
256 fwrite(&b4, 1, 1, fout);
257
258 curaddr += sizeof(uint32_t);
259 curdiffaddr += sizeof(uint32_t);
260 break;
261 case 'O':
262 /* Set orig manually: */
263 curaddr = atoi(line+1);
264 break;
265 default:
266 fprintf(stderr, "error on input line %i\n",
267 lineno);
268 exit(1);
269 }
270 }
271 }
272 }
273
274
275 int main(int argc, char *argv[])
276 {
277 FILE *fin, *fout;
278 uint32_t first_diffaddr;
279
280 if (argc != 3) {
281 fprintf(stderr, "usage: %s asmsource binimage\n", argv[0]);
282 fprintf(stderr, "Input is read from asmsource and "
283 "output is written to binimage\n");
284 exit(1);
285 }
286
287 fin = fopen(argv[1], "r");
288 if (fin == NULL) {
289 perror(argv[1]);
290 exit(2);
291 }
292
293 fout = fopen(argv[2], "w");
294 if (fout = NULL) {
295 perror(argv[2]);
296 exit(2);
297 }
298
299 first_diffaddr = pass1(fin);
300 fseek(fin, 0, SEEK_SET);
301 pass2(fin, fout, first_diffaddr);
302
303 fclose(fin);
304 fclose(fout);
305
306 return 0;
307 }
308

  ViewVC Help
Powered by ViewVC 1.1.26