Mercurial > hg-old > index.cgi
view old-trunk/lwasm/old/os9.c @ 348:11a95c6414b4
Added third func to instab to split resolve and emit logic
author | lost@starbug |
---|---|
date | Sat, 27 Mar 2010 22:15:07 -0600 |
parents | eb230fa7d28e |
children |
line wrap: on
line source
/* os9.c Copyright © 2009 William Astle This file is part of LWASM. LWASM is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. This file implements the various pseudo operations related to OS9 target */ #include <config.h> #include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include "lwasm.h" #include "instab.h" #include "expr.h" #include "util.h" OPFUNC(pseudo_os9) { int r, rval; if (as -> outformat != OUTPUT_OS9) { register_error(as, l, 1, "os9 directive only valid for OS9 target"); return; } // fetch immediate value r = lwasm_expr_result2(as, l, p, 0, &rval, 0); if (r != 0) rval = 0; if (r == 1 && as -> passnum == 2) register_error(as, l, 2, "Illegal external or intersegment reference"); // SWI2; FCB ... lwasm_emit(as, l, 0x10); lwasm_emit(as, l, 0x3f); lwasm_emit(as, l, rval); } OPFUNC(pseudo_mod) { int modvals[6]; int r, v, i; if (as -> outformat != OUTPUT_OS9) { register_error(as, l, 1, "mod directive only valid for OS9 target"); return; } if (as -> inmod) { register_error(as, l, 1, "Already in a module!"); return; } // parse 6 expressions... for (i = 0; i < 5; i++) { r = lwasm_expr_result2(as, l, p, 0, &v, -1); if (r < 0) return; if (r > 0) { register_error(as, l, 2, "Illegal external or inter-segment reference (only 1 per FDB line)"); v = 0; } else { modvals[i] = v; } if (**p != ',') { register_error(as, l, 1, "Bad operand"); return; } (*p)++; } r = lwasm_expr_result2(as, l, p, 0, &v, -1); if (r < 0) return; if (r > 0) { register_error(as, l, 2, "Illegal external or inter-segment reference (only 1 per FDB line)"); v = 0; } else { modvals[5] = v; } l -> inmod = 1; // we have an implicit ORG 0 with "mod" l -> codeaddr = 0; l -> addrset = 1; as -> addr = 0; // init crc as -> crc[0] = 0xff; as -> crc[1] = 0xff; as -> crc[2] = 0xff; as -> inmod = 1; // sync bytes lwasm_emit(as, l, 0x87); lwasm_emit(as, l, 0xcd); // mod length lwasm_emit(as, l, modvals[0] >> 8); lwasm_emit(as, l, modvals[0] & 0xff); // name offset lwasm_emit(as, l, modvals[1] >> 8); lwasm_emit(as, l, modvals[1] & 0xff); // type lwasm_emit(as, l, modvals[2]); // flags/rev lwasm_emit(as, l, modvals[3]); // header check lwasm_emit(as, l, ~(0x87 ^ 0xCD ^ (modvals[0] >> 8) ^ (modvals[0] & 0xff) ^ (modvals[1] >> 8) ^ (modvals[1] & 0xff) ^ modvals[2] ^ modvals[3])); // module type specific output // note that these are handled the same for all so // there need not be any special casing // exec offset or fmgr name offset lwasm_emit(as, l, modvals[4] >> 8); lwasm_emit(as, l, modvals[4] & 0xff); // data size or drvr name offset lwasm_emit(as, l, modvals[5] >> 8); lwasm_emit(as, l, modvals[5] & 0xff); } OPFUNC(pseudo_emod) { unsigned char tcrc[3]; if (as -> outformat != OUTPUT_OS9) { register_error(as, l, 1, "emod directive only valid for OS9 target"); return; } if (!(as -> inmod)) { register_error(as, l, 1, "not in a module!"); return; } // don't mess with CRC! tcrc[0] = as -> crc[0] ^ 0xff; tcrc[1] = as -> crc[1] ^ 0xff; tcrc[2] = as -> crc[2] ^ 0xff; lwasm_emit(as, l, tcrc[0]); lwasm_emit(as, l, tcrc[1]); lwasm_emit(as, l, tcrc[2]); as -> inmod = 0; }