comparison lwasm/os9.c @ 354:60568b123281

Added os9 opcodes and ERROR
author lost@starbug
date Tue, 30 Mar 2010 23:10:01 -0600
parents old-trunk/lwasm/old/os9.c@eb230fa7d28e
children
comparison
equal deleted inserted replaced
353:faa97115952e 354:60568b123281
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
29 #include <lw_expr.h>
30
31 #include "lwasm.h"
32 #include "instab.h"
33
34
35 // OS9 syscall
36 PARSEFUNC(pseudo_parse_os9)
37 {
38 lw_expr_t e;
39
40 if (as -> output_format != OUTPUT_OS9)
41 {
42 lwasm_register_error(as, l, "os9 directive only valid for OS9 target");
43 return;
44 }
45
46 // fetch immediate value
47 e = lwasm_parse_expr(as, p);
48 if (!e)
49 {
50 lwasm_register_error(as, l, "Bad operand");
51 return;
52 }
53 lwasm_save_expr(l, 0, e);
54 l -> len = 3;
55 }
56
57 EMITFUNC(pseudo_emit_os9)
58 {
59 lw_expr_t e;
60
61 e = lwasm_fetch_expr(l, 0);
62
63 lwasm_emitop(l, 0x103f);
64 lwasm_emitexpr(l, e, 1);
65 }
66
67 PARSEFUNC(pseudo_parse_mod)
68 {
69 lw_expr_t e;
70 int i;
71
72 if (as -> output_format != OUTPUT_OS9)
73 {
74 lwasm_register_error(as, l, "mod directive only valid for OS9 target");
75 return;
76 }
77
78 if (as -> inmod)
79 {
80 lwasm_register_error(as, l, "Already in a module!");
81 return;
82 }
83
84 // parse 6 expressions...
85 for (i = 0; i < 5; i++)
86 {
87 e = lwasm_parse_expr(as, p);
88 if (!e)
89 {
90 lwasm_register_error(as, l, "Bad operand");
91 return;
92 }
93
94 lwasm_save_expr(l, i, e);
95
96 if (**p != ',')
97 {
98 lwasm_register_error(as, l, "Bad operand");
99 return;
100 }
101 (*p)++;
102 }
103
104 e = lwasm_parse_expr(as, p);
105 if (!e)
106 {
107 lwasm_register_error(as, l, "Bad operand");
108 return;
109 }
110 lwasm_save_expr(l, 5, e);
111
112 l -> inmod = 1;
113
114 // we have an implicit ORG 0 with "mod"
115 lw_expr_destroy(l -> addr);
116 l -> addr = lw_expr_build(lw_expr_type_int, 0);
117
118 // init crc
119 as -> inmod = 1;
120 }
121
122 EMITFUNC(pseudo_emit_mod)
123 {
124 lw_expr_t e1, e2, e3, e4;
125 int csum;
126
127 as -> crc[0] = 0xff;
128 as -> crc[1] = 0xff;
129 as -> crc[2] = 0xff;
130
131 // sync bytes
132 lwasm_emit(l, 0x87);
133 lwasm_emit(l, 0xcd);
134
135 // mod length
136 lwasm_emitexpr(l, e1 = lwasm_fetch_expr(l, 0), 2);
137
138 // name offset
139 lwasm_emitexpr(l, e2 = lwasm_fetch_expr(l, 1), 2);
140
141 // type
142 lwasm_emitexpr(l, e3 = lwasm_fetch_expr(l, 2), 1);
143
144 // flags/rev
145 lwasm_emitexpr(l, e4 = lwasm_fetch_expr(l, 3), 1);
146
147 // header check
148 csum = ~(0x87 ^ 0xCD ^(lw_expr_intval(e1) >> 8) ^ (lw_expr_intval(e1) & 0xff)
149 ^ (lw_expr_intval(e2) >> 8) ^ (lw_expr_intval(e2) & 0xff)
150 ^ lw_expr_intval(e3) ^ lw_expr_intval(e4));
151 lwasm_emit(l, csum);
152
153 // module type specific output
154 // note that these are handled the same for all so
155 // there need not be any special casing
156
157 // exec offset or fmgr name offset
158 lwasm_emitexpr(l, lwasm_fetch_expr(l, 4), 2);
159
160 // data size or drvr name offset
161 lwasm_emitexpr(l, lwasm_fetch_expr(l, 5), 2);
162 }
163
164 PARSEFUNC(pseudo_parse_emod)
165 {
166 if (as -> output_format != OUTPUT_OS9)
167 {
168 lwasm_register_error(as, l, "emod directive only valid for OS9 target");
169 return;
170 }
171
172 if (!(as -> inmod))
173 {
174 lwasm_register_error(as, l, "not in a module!");
175 return;
176 }
177
178 as -> inmod = 0;
179 }
180
181 EMITFUNC(pseudo_emit_emod)
182 {
183 unsigned char tcrc[3];
184
185 // don't mess with CRC!
186 tcrc[0] = as -> crc[0] ^ 0xff;
187 tcrc[1] = as -> crc[1] ^ 0xff;
188 tcrc[2] = as -> crc[2] ^ 0xff;
189 lwasm_emit(l, tcrc[0]);
190 lwasm_emit(l, tcrc[1]);
191 lwasm_emit(l, tcrc[2]);
192 }