comparison old-trunk/lwasm/old/os9.c @ 339:eb230fa7d28e

Prepare for migration to hg
author lost
date Fri, 19 Mar 2010 02:54:14 +0000
parents
children
comparison
equal deleted inserted replaced
338:e7885b3ee266 339:eb230fa7d28e
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[0] = 0xff;
117 as -> crc[1] = 0xff;
118 as -> crc[2] = 0xff;
119 as -> inmod = 1;
120
121 // sync bytes
122 lwasm_emit(as, l, 0x87);
123 lwasm_emit(as, l, 0xcd);
124
125 // mod length
126 lwasm_emit(as, l, modvals[0] >> 8);
127 lwasm_emit(as, l, modvals[0] & 0xff);
128
129 // name offset
130 lwasm_emit(as, l, modvals[1] >> 8);
131 lwasm_emit(as, l, modvals[1] & 0xff);
132
133 // type
134 lwasm_emit(as, l, modvals[2]);
135
136 // flags/rev
137 lwasm_emit(as, l, modvals[3]);
138
139 // header check
140 lwasm_emit(as, l, ~(0x87 ^ 0xCD ^ (modvals[0] >> 8) ^ (modvals[0] & 0xff)
141 ^ (modvals[1] >> 8) ^ (modvals[1] & 0xff)
142 ^ modvals[2] ^ modvals[3]));
143
144 // module type specific output
145 // note that these are handled the same for all so
146 // there need not be any special casing
147
148 // exec offset or fmgr name offset
149 lwasm_emit(as, l, modvals[4] >> 8);
150 lwasm_emit(as, l, modvals[4] & 0xff);
151
152 // data size or drvr name offset
153 lwasm_emit(as, l, modvals[5] >> 8);
154 lwasm_emit(as, l, modvals[5] & 0xff);
155 }
156
157 OPFUNC(pseudo_emod)
158 {
159 unsigned char tcrc[3];
160
161 if (as -> outformat != OUTPUT_OS9)
162 {
163 register_error(as, l, 1, "emod directive only valid for OS9 target");
164 return;
165 }
166
167 if (!(as -> inmod))
168 {
169 register_error(as, l, 1, "not in a module!");
170 return;
171 }
172
173 // don't mess with CRC!
174 tcrc[0] = as -> crc[0] ^ 0xff;
175 tcrc[1] = as -> crc[1] ^ 0xff;
176 tcrc[2] = as -> crc[2] ^ 0xff;
177 lwasm_emit(as, l, tcrc[0]);
178 lwasm_emit(as, l, tcrc[1]);
179 lwasm_emit(as, l, tcrc[2]);
180 as -> inmod = 0;
181 }