comparison lwasm/os9.c @ 236:a58f49a77441

Added os9 target, pragma to control whether $ localizes a symbol, and fixed some condition nesting bugs
author lost
date Fri, 14 Aug 2009 03:22:26 +0000
parents
children a9a14e6b4bc8
comparison
equal deleted inserted replaced
235:aa0056ca7319 236:a58f49a77441
1 /*
2 os9.c
3 Copyright © 2009 William Astle
4
5 This file is part of LWASM.
6
7 LWASM is free software: you can redistribute it and/or modify it under the
8 terms of the GNU General Public License as published by the Free Software
9 Foundation, either version 3 of the License, or (at your option) any later
10 version.
11
12 This program is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 more details.
16
17 You should have received a copy of the GNU General Public License along with
18 this program. If not, see <http://www.gnu.org/licenses/>.
19
20
21 This file implements the various pseudo operations related to OS9 target
22 */
23 #include <config.h>
24 #include <errno.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include "lwasm.h"
29 #include "instab.h"
30 #include "expr.h"
31 #include "util.h"
32
33 OPFUNC(pseudo_os9)
34 {
35 int r, rval;
36
37 if (as -> outformat != OUTPUT_OS9)
38 {
39 register_error(as, l, 1, "os9 directive only valid for OS9 target");
40 return;
41 }
42
43 // fetch immediate value
44 r = lwasm_expr_result2(as, l, p, 0, &rval, 0);
45 if (r != 0)
46 rval = 0;
47 if (r == 1 && as -> passnum == 2)
48 register_error(as, l, 2, "Illegal external or intersegment reference");
49
50 // SWI2; FCB ...
51 lwasm_emit(as, l, 0x10);
52 lwasm_emit(as, l, 0x3f);
53 lwasm_emit(as, l, rval);
54 }
55
56 OPFUNC(pseudo_mod)
57 {
58 int modvals[6];
59 int r, v, i;
60
61 if (as -> outformat != OUTPUT_OS9)
62 {
63 register_error(as, l, 1, "mod directive only valid for OS9 target");
64 return;
65 }
66
67 if (as -> inmod)
68 {
69 register_error(as, l, 1, "Already in a module!");
70 return;
71 }
72
73 // parse 6 expressions...
74 for (i = 0; i < 5; i++)
75 {
76 r = lwasm_expr_result2(as, l, p, 0, &v, -1);
77 if (r < 0)
78 return;
79 if (r > 0)
80 {
81 register_error(as, l, 2, "Illegal external or inter-segment reference (only 1 per FDB line)");
82 v = 0;
83 }
84 else
85 {
86 modvals[i] = v;
87 }
88 if (**p != ',')
89 {
90 register_error(as, l, 1, "Bad operand");
91 return;
92 }
93 (*p)++;
94 }
95 r = lwasm_expr_result2(as, l, p, 0, &v, -1);
96 if (r < 0)
97 return;
98 if (r > 0)
99 {
100 register_error(as, l, 2, "Illegal external or inter-segment reference (only 1 per FDB line)");
101 v = 0;
102 }
103 else
104 {
105 modvals[5] = v;
106 }
107
108 l -> inmod = 1;
109
110 // we have an implicit ORG 0 with "mod"
111 l -> codeaddr = 0;
112 l -> addrset = 1;
113 as -> addr = 0;
114
115 // init crc
116 as -> crc = 0xffffff;
117 as -> inmod = 1;
118
119 // sync bytes
120 lwasm_emit(as, l, 0x87);
121 lwasm_emit(as, l, 0xcd);
122
123 // mod length
124 lwasm_emit(as, l, modvals[0] >> 8);
125 lwasm_emit(as, l, modvals[0] & 0xff);
126
127 // name offset
128 lwasm_emit(as, l, modvals[1] >> 8);
129 lwasm_emit(as, l, modvals[1] & 0xff);
130
131 // type
132 lwasm_emit(as, l, modvals[2]);
133
134 // flags/rev
135 lwasm_emit(as, l, modvals[3]);
136
137 // header check
138 lwasm_emit(as, l, ~(0x87 ^ 0xCD ^ (modvals[0] >> 8) ^ (modvals[0] & 0xff)
139 ^ (modvals[1] >> 8) ^ (modvals[1] & 0xff)
140 ^ modvals[2] ^ modvals[3]));
141
142 // module type specific output
143 // note that these are handled the same for all so
144 // there need not be any special casing
145
146 // exec offset or fmgr name offset
147 lwasm_emit(as, l, modvals[4] >> 8);
148 lwasm_emit(as, l, modvals[4] & 0xff);
149
150 // data size or drvr name offset
151 lwasm_emit(as, l, modvals[5] >> 8);
152 lwasm_emit(as, l, modvals[5] & 0xff);
153 }
154
155 OPFUNC(pseudo_emod)
156 {
157 unsigned long tcrc;
158
159 if (as -> outformat != OUTPUT_OS9)
160 {
161 register_error(as, l, 1, "emod directive only valid for OS9 target");
162 return;
163 }
164
165 if (!(as -> inmod))
166 {
167 register_error(as, l, 1, "not in a module!");
168 return;
169 }
170
171 // don't mess with CRC!
172 tcrc = as -> crc;
173 lwasm_emit(as, l, tcrc >> 16);
174 lwasm_emit(as, l, tcrc >> 8);
175 lwasm_emit(as, l, tcrc);
176 as -> inmod = 0;
177 }