comparison lwasm/os9.c @ 0:2c24602be78f

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