comparison lwasm/os9.c @ 556:928c033c0cd0

Allow MOD directive to accept only the standard base header parameters There are cases where only the standard OS9 module header fields are to be provided. This could be, for instance, in the case of a nonstandard user type module. So allow the execution offset and data size fields to be omitted entirely and handle the module length correctly as well.
author William Astle <lost@l-w.ca>
date Fri, 08 Sep 2023 00:32:40 -0600
parents 8764142b3192
children dba08c7dff96
comparison
equal deleted inserted replaced
555:bbc600db5016 556:928c033c0cd0
80 lwasm_register_error(as, l, E_MODULE_IN); 80 lwasm_register_error(as, l, E_MODULE_IN);
81 skip_operand(p); 81 skip_operand(p);
82 return; 82 return;
83 } 83 }
84 84
85 // parse 6 expressions... 85 // parse 6 (or 4) expressions...
86 for (i = 0; i < 5; i++) 86 for (i = 0; i < 5; i++)
87 { 87 {
88 e = lwasm_parse_expr(as, p); 88 e = lwasm_parse_expr(as, p);
89 if (!e) 89 if (!e)
90 { 90 {
94 94
95 lwasm_save_expr(l, i, e); 95 lwasm_save_expr(l, i, e);
96 96
97 if (**p != ',') 97 if (**p != ',')
98 { 98 {
99 if (i == 3)
100 {
101 // we don't have the extra items; flag it and don't bother
102 // with them later; goto is to short circuit the rest of
103 // the expression parsing
104 l -> lint = 4;
105 goto doneexpr;
106 }
99 lwasm_register_error(as, l, E_OPERAND_BAD); 107 lwasm_register_error(as, l, E_OPERAND_BAD);
100 return; 108 return;
101 } 109 }
102 (*p)++; 110 (*p)++;
103 } 111 }
104
105 e = lwasm_parse_expr(as, p); 112 e = lwasm_parse_expr(as, p);
106 if (!e) 113 if (!e)
107 { 114 {
108 lwasm_register_error(as, l, E_OPERAND_BAD); 115 lwasm_register_error(as, l, E_OPERAND_BAD);
109 return; 116 return;
110 } 117 }
111 lwasm_save_expr(l, 5, e); 118 lwasm_save_expr(l, 5, e);
112 119 l -> lint = 6;
120
121 doneexpr:
113 l -> inmod = 1; 122 l -> inmod = 1;
114 123
115 // we have an implicit ORG 0 with "mod" 124 // we have an implicit ORG 0 with "mod"
116 lw_expr_destroy(l -> addr); 125 lw_expr_destroy(l -> addr);
117 l -> addr = lw_expr_build(lw_expr_type_int, 0); 126 l -> addr = lw_expr_build(lw_expr_type_int, 0);
121 l -> daddr = lw_expr_build(lw_expr_type_int, 0); 130 l -> daddr = lw_expr_build(lw_expr_type_int, 0);
122 131
123 // init crc 132 // init crc
124 as -> inmod = 1; 133 as -> inmod = 1;
125 134
126 l -> len = 13; 135 l -> len = (i == 6) ? 13 : 9;
127 } 136 }
128 137
129 EMITFUNC(pseudo_emit_mod) 138 EMITFUNC(pseudo_emit_mod)
130 { 139 {
131 lw_expr_t e1, e2, e3, e4; 140 lw_expr_t e1, e2, e3, e4;
155 csum = ~(0x87 ^ 0xCD ^(lw_expr_intval(e1) >> 8) ^ (lw_expr_intval(e1) & 0xff) 164 csum = ~(0x87 ^ 0xCD ^(lw_expr_intval(e1) >> 8) ^ (lw_expr_intval(e1) & 0xff)
156 ^ (lw_expr_intval(e2) >> 8) ^ (lw_expr_intval(e2) & 0xff) 165 ^ (lw_expr_intval(e2) >> 8) ^ (lw_expr_intval(e2) & 0xff)
157 ^ lw_expr_intval(e3) ^ lw_expr_intval(e4)); 166 ^ lw_expr_intval(e3) ^ lw_expr_intval(e4));
158 lwasm_emit(l, csum); 167 lwasm_emit(l, csum);
159 168
160 // module type specific output 169 if (l -> lint == 6)
161 // note that these are handled the same for all so 170 {
162 // there need not be any special casing 171 // module type specific output, if provided
163 172 // note that these are handled the same for all so
164 // exec offset or fmgr name offset 173 // there need not be any special casing
165 lwasm_emitexpr(l, lwasm_fetch_expr(l, 4), 2); 174
166 175 // exec offset or fmgr name offset
167 // data size or drvr name offset 176 lwasm_emitexpr(l, lwasm_fetch_expr(l, 4), 2);
168 lwasm_emitexpr(l, lwasm_fetch_expr(l, 5), 2); 177
178 // data size or drvr name offset
179 lwasm_emitexpr(l, lwasm_fetch_expr(l, 5), 2);
180 }
169 } 181 }
170 182
171 PARSEFUNC(pseudo_parse_emod) 183 PARSEFUNC(pseudo_parse_emod)
172 { 184 {
173 skip_operand(p); 185 skip_operand(p);