# HG changeset patch # User lost # Date 1223001860 0 # Node ID 57495da019003c998de7ddb380a5f57afdcdcb46 Initial checking of LWASM diff -r 000000000000 -r 57495da01900 COPYING --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/COPYING Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program 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 . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff -r 000000000000 -r 57495da01900 README --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,5 @@ +This distribution constitutes the LWASM cross-assembler for the MC6809 and +HD6309 microprocessors. + +All files that form a part of this distribution use the UTF8 character +encoding method unless otherwise noted. diff -r 000000000000 -r 57495da01900 misc/fileheader --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc/fileheader Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,16 @@ +Copyright © 2008 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 . diff -r 000000000000 -r 57495da01900 src/index.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/index.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,315 @@ +/* + * index.c + * + * code for parsing indexed addressing modes + */ + +#include +//#include +//#include +//#include +#include +#define __index_c_seen__ +//#include "instab.h" +#include "lwasm.h" +#include "instab.h" + + +int parse_index_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *postbyte, int *opmode, int *v1) +{ + static const char *regs = "X Y U S W PCRPC "; + static const struct { char *opstr; int pb; } simpleindex[] = + { + {",x", 0x84}, {",y", 0xa4}, {",u", 0xc4}, {",s", 0xe4}, + {",x+", 0x80}, {",y+", 0xa0}, {",u+", 0xc0}, {",s+", 0xe0}, + {",x++", 0x81}, {",y++", 0xa1}, {",u++", 0xc1}, {",s++", 0xe1}, + {",-x", 0x82}, {",-y", 0xa2}, {",-u", 0xc2}, {",-s", 0xe2}, + {",--x", 0x83}, {",--y", 0xa3}, {",--u", 0xc3}, {",--s", 0xe3}, + {"a,x", 0x86}, {"a,y", 0xa6}, {"a,u", 0xc6}, {"a,s", 0xe6}, + {"b,x", 0x85}, {"b,y", 0xa5}, {"b,u", 0xc5}, {"b,s", 0xe5}, + {"e,x", 0x87}, {"e,y", 0xa7}, {"e,u", 0xc7}, {"e,s", 0xe7}, + {"f,x", 0x8a}, {"f,y", 0xaa}, {"f,u", 0xca}, {"f,s", 0xea}, + {"d,x", 0x8b}, {"d,y", 0xab}, {"d,u", 0xcb}, {"d,s", 0xed}, + {"w,x", 0x8e}, {"w,y", 0xae}, {"w,u", 0xce}, {"w,s", 0xee}, + {",w", 0x8f}, {",w++", 0xcf}, {",--w", 0xef}, + + {"[,x]", 0x94}, {"[,y]", 0xb4}, {"[,u", 0xd4}, {"[,s]", 0xf4}, + {"[,x++]", 0x91}, {"[,y++]", 0xb1}, {"[,u++]", 0xd1}, {"[,s++]", 0xf1}, + {"[,--x]", 0x93}, {"[,--y]", 0xb3}, {"[,--u]", 0xd3}, {"[,--s]", 0xf3}, + {"[a,x]", 0x96}, {"[a,y]", 0xb6}, {"[a,u]", 0xd6}, {"[a,s]", 0xf6}, + {"[b,x]", 0x95}, {"[b,y]", 0xb5}, {"[b,u]", 0xd5}, {"[b,s]", 0xf5}, + {"[e,x]", 0x97}, {"[e,y]", 0xb7}, {"[e,u]", 0xd7}, {"[e,s]", 0xf7}, + {"[f,x]", 0x9a}, {"[f,y]", 0xba}, {"[f,u]", 0xda}, {"[f,s]", 0xfa}, + {"[d,x]", 0x9b}, {"[d,y]", 0xbb}, {"[d,u]", 0xdb}, {"[d,s]", 0xfd}, + {"[w,x]", 0x9e}, {"[w,y]", 0xbe}, {"[w,u]", 0xde}, {"[w,s]", 0xfe}, + {"[,w]", 0x90}, {"[,w++]", 0xd0}, {"[,--w]", 0xf0}, + + { "", -1 } + }; + char stbuf[25]; + int i; + int f8 = 0, f16 = 0; + int rn; + int indir = 0; + int rval; + int f0 = 0; + + for (i = 0; i < 24; i++) + { + if (*((*optr) + i) && !isspace(*((*optr) + i))) + stbuf[i] = *((*optr) + i); + else + break; + } + stbuf[i] = '\0'; + if (!*((*optr) + i) || isspace(*((*optr) + i))) + { + int j; + // do simple lookup + for (j = 0; simpleindex[j].opstr[0]; j++) + { + if (!strcasecmp(stbuf, simpleindex[j].opstr)) + break; + } + if (simpleindex[j].opstr[0]) + { + *postbyte = simpleindex[j].pb; + *opmode = OPER_INDEX; + (*optr) += i; + return 0; + } + } + + // now we have the hard ones to work out here + + if (**optr == '[') + { + indir = 1; + (*optr)++; + } + + rn = 0; + for (i = 0; (*optr)[i] && !isspace((*optr)[i]); i++) + { + if ((*optr)[i] == ',') + { + rn = 1; + break; + } + } + + if (!rn && indir) + { + // extended indir + *postbyte = 0x9f; + *opmode = OPER_EXTIND; + rval = eval_expr(as, cl, optr, v1); + if (**optr != ']') + { + errorp1(ERR_BADOPER); + } + (*optr)++; + return 0; + } + + if (cl -> p1f16) + f16 = 1; + if (**optr == '<') + { + f8 = 1; + (*optr)++; + } + else if (**optr == '>') + { + f16 = 1; + (*optr)++; + } + + if (**optr == '0' && *(*optr+1) == ',') + { + f0 = 1; + } + + // now we have to evaluate the expression + rval = eval_expr(as, cl, optr, v1); + + if (cl -> undef && as -> passnum == 1) + { + cl -> p1f16 = 1; + f16 = 1; + } + + // now look for a comma; if not present, explode + if (rval == -1 || *(*optr)++ != ',') + { + // syntax error; force 0 bit + *postbyte = -1; + *opmode = OPER_INDEX; + return -2; + } + + // now get the register + rn = lookupreg3(regs, optr); + if (rn < 0) + goto reterr; + +// debug("Reg: %d\n", rn); + + if (indir && **optr != ']') + goto reterr; + else + (*optr)++; + + // nnnn,W is only 16 bit + if (rn == 4) + { + if (f8) + goto reterr; + if (!f16 && !f0 && !(as -> pragmas & PRAGMA_NOINDEX0TONONE) && *v1 == 0) + { + *opmode = OPER_INDEX; + if (indir) + *postbyte = 0x90; + else + *postbyte = 0x8f; + return 0; + } + *opmode = OPER_INDEX16; + if (indir) + *postbyte = 0xb0; + else + *postbyte = 0xcf; + return 0; + } + + if (indir) indir = 0x10; + + // forward ref; we can't figure anything + if (cl -> undef) + { + f16 = 1; + } + + // PCR? redo v1, v2 relative to current address + if (rn == 5) + { + *v1 -= as -> addr; + + // we have a slight problem here + // PCR based on current insn loc is really + // -125 <= offset <= +130 (8 bit offset) + if (f8 || (!f16 && *v1 >= -125 && *v1 <= 130)) + { + *opmode = OPER_INDEX8; + *postbyte = indir | 0x8C; + *v1 -= 3; + if (*v1 < -128 || *v1 > 127) + errorp2(ERR_OVERFLOW); + return 0; + } + + // anything else is 16 bit offset + // need 16 bit + *opmode = OPER_INDEX16; + *postbyte = indir | 0x8D; + *v1 -= 4; + return 0; + } + + // constant offset from PC + if (rn == 6) + { + if (f8 || (!f16 && *v1 >= -128 && *v1 <= 127)) + { + *opmode = OPER_INDEX8; + *postbyte = indir | 0x8C; + if (*v1 < -128 || *v1 > 127) + errorp2(ERR_OVERFLOW); + return 0; + } + + // everything else must be 16 bit + // need 16 bit + *opmode = OPER_INDEX16; + *postbyte = indir | 0x8D; + return 0; + + } + + // we only have to deal with x,y,u,s here + if (!f8 && !f16 && *v1 >= -16 && *v1 <= 15) + { + if (*v1 == 0 && !f0 && !(as -> pragmas & PRAGMA_NOINDEX0TONONE)) + { + *postbyte = rn << 5 | indir | 0x80 | 0x04; + *opmode = OPER_INDEX; + return 0; + } + // we pick the smallest value here + if (indir) + { + f8 = 1; + goto no5bit; + } + *postbyte = rn << 5 | (*v1 & 0x1F); + *opmode = OPER_INDEX5; + return 0; + } +no5bit: + if (f16 || (!f8 && (*v1 < -128 || *v1 > 127))) + { + // must be a 16 bit offset here + *postbyte = rn << 5 | indir | 0x80 | 0x09; + *opmode = OPER_INDEX16; + return 0; + } + + // if we're here, we have an 8 bit offset + *postbyte = rn << 5 | indir | 0x80 | 0x08; + *opmode = OPER_INDEX8; + if (*v1 < -128 || *v1 > 127) + errorp2(ERR_OVERFLOW); + return 0; +reterr: + *postbyte = -1; + *opmode = OPER_INDEX; + return -2; +} + +void insn_indexed_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3) +{ + int rval; + int v1, pb = -1; + + *b1 = *b2 = *b3 = -1; + + rval = parse_index_expr(as, cl, optr, &pb, &(cl -> addrmode), &v1); + if (rval < 0) + errorp1(ERR_BADOPER); + *b1 = pb; + + if (cl -> addrmode == OPER_INDEX8) + { + *b2 = v1 & 0xff; + } + else if (cl -> addrmode == OPER_INDEX16 || cl -> addrmode == OPER_EXTIND) + { + *b2 = (v1 & 0xffff) >> 8; + *b3 = v1 & 0xff; + } +} + +void insn_indexed(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int b1, b2, b3; + + emitop(instab[cl -> opcode].ops[0]); + insn_indexed_aux(as, cl, optr, &b1, &b2, &b3); + if (b1 != -1) + emit(b1); + if (b2 != -1) + emit(b2); + if (b3 != -1) + emit(b3); +} + diff -r 000000000000 -r 57495da01900 src/insn_gen.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/insn_gen.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,154 @@ +/* + * insn_gen.c + * + * parsing general addressing modes (IMM+DIR+EXT+IND) + */ + +#include +#include "lwasm.h" +#include "instab.h" + +extern void insn_indexed_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3); + +void insn_gen_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3, int *op) +{ + *b1 = *b2 = *b3 = -1; + char *optr2; + int v1, tv, rval; + + optr2 = *optr; + while (*optr2 && !isspace(*optr2) && *optr2 != ',') optr2++ + ; + if (*optr2 != ',' && **optr != '[') + { + // not indexed + if (**optr == '<') + { + (*optr)++; + rval = eval_expr(as, cl, optr, &v1); + v1 = v1 & 0xffff; + tv = v1 - ((cl -> dpval) << 8); + if (tv < 0 || tv > 0xff) + { + errorp2(ERR_OVERFLOW); + } + v1 = v1 & 0xff; + goto ins_gen_dir; + } + else if (**optr == '>') + { + // extended mode + (*optr)++; + rval = eval_expr(as, cl, optr, &v1); + goto ins_gen_ext; + } + else + { + // eval expr and see how big it is + rval = eval_expr(as, cl, optr, &v1); + v1 = v1 & 0xFFFF; + + if (cl -> undef && as -> passnum == 1) + { + cl -> p1f16 = 1; + goto ins_gen_ext; + } + + tv = v1 - (cl -> dpval << 8); + + if (tv < 0 || tv > 0xff || cl -> p1f16) + goto ins_gen_ext; + else + { + v1 = v1 & 0xff; + goto ins_gen_dir; + } + } + return; + } + + *op = instab[cl -> opcode].ops[1]; + insn_indexed_aux(as, cl, optr, b1, b2, b3); + return; + +ins_gen_dir: + *op = instab[cl -> opcode].ops[0]; +// cl -> code_operlen = 1; + cl -> addrmode = OPER_DIR; + if ((v1 & 0xFFFF) > 0xff) + errorp2(ERR_OVERFLOW); + *b1 = (v1); + return; + +ins_gen_ext: + *op = instab[cl -> opcode].ops[2]; +// cl -> code_operlen = 2; + cl -> addrmode = OPER_EXT; + *b1 = (v1 >> 8); + *b2 = (v1 & 0xff); + return; +} + +void insn_gen(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval; + int v1; + int b1, b2, b3, op; + + if (**optr == '#') + { + // immediate mode has perterbations on instruction size + (*optr)++; + emitop(instab[cl -> opcode].ops[3]); + rval = eval_expr(as, cl, optr, &v1); + + switch (instab[cl -> opcode].instype) + { + case INSTYPE_GEN8: + case INSTYPE_IMM8: + cl -> addrmode = OPER_IMM8; +// cl -> code_operlen = 1; + emit(v1 & 0xff); + if (v1 < -128 || v1 > 255) + errorp2(ERR_OVERFLOW); + return; + + case INSTYPE_GEN: + cl -> addrmode = OPER_IMM16; +// cl -> code_operlen = 2; + emit(v1 >> 8); + emit(v1 & 0xff); + return; + + case INSTYPE_GEN32: + cl -> addrmode = OPER_IMM32; +// cl -> code_operlen = 4; + emit(v1 >> 24); + emit((v1 >> 16) & 0xff); + emit((v1 >> 8) & 0xff); + emit(v1 & 0xff); + return; + + default: + errorp1(ERR_BADOPER); + return; + + } + + return; + } + if (instab[cl -> opcode].instype == INSTYPE_IMM8) + { + errorp1(ERR_BADOPER); + return; + } + + insn_gen_aux(as, cl, optr, &b1, &b2, &b3, &op); + emitop(op); + if (b1 != -1) + emit(b1); + if (b2 != -1) + emit(b2); + if (b3 != -1) + emit(b3); +} diff -r 000000000000 -r 57495da01900 src/insn_misc.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/insn_misc.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,315 @@ +/* + * insn_misc.c + * + * parsing miscelaneous addressing modes + */ + +#include +#include +#include +#include "lwasm.h" +#include "instab.h" + +extern void insn_gen_aux(asmstate_t *as, sourceline_t *cl, char **optr, int *b1, int *b2, int *b3, int *op); + +void insn_inh(asmstate_t *as, sourceline_t *cl, char **optr) +{ + cl -> addrmode = OPER_INH; + emitop(instab[cl -> opcode].ops[0]); +} + +void insn_rtor(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int r0, r1; + static const char *regs = "D X Y U S PCW V A B CCDP0 0 E F "; + + cl -> addrmode = OPER_RTOR; + emitop(instab[cl -> opcode].ops[0]); + // register to register (r0,r1) + // registers are in order: + // D,X,Y,U,S,PC,W,V + // A,B,CC,DP,0,0,E,F + r0 = lookupreg(regs, optr); + if (r0 < 0 || *(*optr)++ != ',') + { + errorp1(ERR_BADOPER); + r0 = r1 = 0; + } + else + { + r1 = lookupreg(regs, optr); + if (r1 < 0) + { + errorp1(ERR_BADOPER); + r0=r1=0; + } + } + emit((r0 << 4) | r1); +} + +void insn_rlist(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rb = 0; + int rn; + static const char *regs = "CCA B DPX Y U PCD S "; + + emitop(instab[cl -> opcode].ops[0]); + cl -> addrmode = OPER_RLIST; + while (**optr && !isspace(**optr)) + { + rn = lookupreg(regs, optr); + if (rn < 0) + { + printf("Bad reg (%s)\n", *optr); + errorp1(ERR_BADOPER); + emit(0); + return; + } + if (**optr && **optr != ',' && !isspace(**optr)) + { + printf("Bad char (%c)\n", **optr); + errorp1(ERR_BADOPER); + emit(0); + return; + } + if (**optr == ',') + (*optr)++; + if (rn == 8) + rn = 6; + else if (rn == 9) + rn = 0x40; + else + rn = 1 << rn; + rb |= rn; + } + emit(rb); +} + +// for aim, oim, eim, tim +void insn_logicmem(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + int b1, b2, b3, op; + + if (**optr == '#') + (*optr)++; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + return; + + if (v1 < -128 || v1 > 255) + { + errorp2(ERR_OVERFLOW); + v1 = 0; + } + + if (**optr != ',' && **optr != ';') + { + errorp1(ERR_BADOPER); + return; + } + + (*optr)++; + + // now we have a general addressing mode - call for it + insn_gen_aux(as, cl, optr, &b1, &b2, &b3, &op); + + emitop(op); + emit(v1 & 0xff); + if (b1 != -1) + { + emit(b1); + } + if (b2 != -1) + { + emit(b2); + } + if (b3 != -1) + { + emit(b3); + } +} + +void insn_tfm(asmstate_t *as, sourceline_t *cl, char **optr) +{ + static const char *reglist = "DXYUS AB 00EF"; + int r0, r1; + char *c; + int tfm = 0; + + cl -> addrmode = OPER_TFM; + + c = strchr(reglist, toupper(*(*optr)++)); + if (!c) + { + errorp1(ERR_BADOPER); + return; + } + r0 = c - reglist; + if (**optr == '+') + { + (*optr)++; + tfm = 1; + } + else if (**optr == '-') + { + (*optr)++; + tfm = 2; + } + if (*(*optr)++ != ',') + { + errorp1(ERR_BADOPER); + return; + } + c = strchr(reglist, toupper(*(*optr)++)); + if (!c) + { + errorp1(ERR_BADOPER); + return; + } + r1 = c - reglist; + + if (**optr == '+') + { + (*optr)++; + tfm |= 4; + } + else if (**optr == '-') + { + (*optr)++; + tfm |= 8; + } + + if (**optr && !isspace(**optr)) + { + errorp1(ERR_BADOPER); + return; + } + + // valid values of tfm here are: + // 1: r0+,r1 (2) + // 4: r0,r1+ (3) + // 5: r0+,r1+ (0) + // 10: r0-,r1- (1) + switch (tfm) + { + case 5: //r0+,r1+ + emitop(instab[cl -> opcode].ops[0]); + break; + case 10: //r0-,r1- + emitop(instab[cl -> opcode].ops[1]); + break; + case 1: // r0+,r1 + emitop(instab[cl -> opcode].ops[2]); + break; + case 4: // r0,r1+ + emitop(instab[cl -> opcode].ops[3]); + break; + default: + errorp1(ERR_BADOPER); + return; + } + emit((r0 << 4) | r1); +} + +void insn_bitbit(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int r; + int rval; + int v1; + int tv; + + emitop(instab[cl -> opcode].ops[0]); + + cl -> addrmode = OPER_BITBIT; + + r = toupper(*(*optr)++); + if (r == 'A') + r = 1; + else if (r == 'B') + r = 2; + else if (r == 'C' && toupper(**optr) == 'C') + { + r = 0; + (*optr)++; + } + else + { + errorp1(ERR_BADREG); + return; + } + if (*(*optr)++ != ',') + { + errorp1(ERR_BADOPER); + return; + } + rval = eval_expr(as, cl, optr, &v1); + if (v1 < 0 || v1 > 7) + { + errorp2(ERR_OVERFLOW3); + v1 = 0; + } + if (*(*optr)++ != ',') + { + errorp1(ERR_BADOPER); + return; + } + r = (r << 6) | (v1 << 3); + rval = eval_expr(as, cl, optr, &v1); + if (v1 < 0 || v1 > 7) + { + errorp2(ERR_OVERFLOW3); + v1 = 0; + } + if (*(*optr)++ != ',') + { + errorp1(ERR_BADOPER); + return; + } + r |= v1; + + emit(r); + + // ignore base page address modifier + if (**optr == '<') + optr++; + + rval = eval_expr(as, cl, optr, &v1); + v1 &= 0xFFFF; + tv = v1 - ((cl -> dpval) << 8); + if (tv > 0xFF || tv < 0) + errorp2(ERR_OVERFLOW); + emit(tv & 0xff); +} + +void insn_rel8(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int v1, rval; + + emitop(instab[cl -> opcode].ops[0]); + cl -> addrmode = OPER_REL8; + rval = eval_expr(as, cl, optr, &v1); + v1 &= 0xFFFF; + v1 -= cl -> addr + 2; + if (v1 < -128 || v1 > 127) + errorp2(ERR_OVERFLOW); + v1 &= 0xFFFF; + emit(v1 & 0xff); +} + +void insn_rel16(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int v1, rval; + + emitop(instab[cl -> opcode].ops[0]); + cl -> addrmode = OPER_REL16; + rval = eval_expr(as, cl, optr, &v1); + v1 &= 0xFFFF; + v1 -= cl -> addr + 3; + if (instab[cl -> opcode].ops[0] > 0xff) + v1 -= 1; + v1 &= 0xFFFF; + emit(v1 >> 8); + emit(v1 & 0xff); +} diff -r 000000000000 -r 57495da01900 src/instab.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/instab.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,382 @@ +/* + * instab.c + * + * instruction table for assembling + */ + +#include + +#define __instab_c_seen__ +#include "instab.h" + +extern void insn_gen(asmstate_t *as, sourceline_t *cl, char **optr); +extern void insn_inh(asmstate_t *as, sourceline_t *cl, char **optr); +extern void insn_indexed(asmstate_t *as, sourceline_t *cl, char **optr); +extern void insn_rtor(asmstate_t *as, sourceline_t *cl, char **optr); +extern void insn_rlist(asmstate_t *as, sourceline_t *cl, char **optr); +extern void insn_logicmem(asmstate_t *as, sourceline_t *cl, char **optr); +extern void insn_bitbit(asmstate_t *as, sourceline_t *cl, char **optr); +extern void insn_tfm(asmstate_t *as, sourceline_t *cl, char **optr); +extern void insn_rel8(asmstate_t *as, sourceline_t *cl, char **optr); +extern void insn_rel16(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_org(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_equ(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_setdp(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_fcb(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_fdb(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_fqb(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_fcc(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_fcs(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_fcn(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_rmb(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_rmd(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_rmq(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_zmb(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_zmd(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_zmq(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_align(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_end(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_include(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_macro(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_endm(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_cond(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_else(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_endc(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_ifne(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_ifeq(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_ifge(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_ifgt(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_ifle(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_iflt(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_error(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_set(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_pragma(asmstate_t *as, sourceline_t *cl, char **optr); +extern void pseudo_starpragma(asmstate_t *as, sourceline_t *cl, char **optr); + +instab_t instab[] = +{ + { "abx", { 0x3a, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "adca", { 0x99, 0xa9, 0xb9, 0x89 }, INSTYPE_GEN8, 0, insn_gen }, + { "adcb", { 0xd9, 0xe9, 0xf9, 0xc9 }, INSTYPE_GEN8, 0, insn_gen }, + { "adcd", { 0x1099, 0x10a9, 0x10b9, 0x1089 }, INSTYPE_GEN, 0, insn_gen }, + { "adcr", { 0x1031, -0x1, -0x1, -0x1 }, INSTYPE_RTOR, 0, insn_rtor }, + { "adda", { 0x9b, 0xab, 0xbb, 0x8b }, INSTYPE_GEN8, 0, insn_gen }, + { "addb", { 0xdb, 0xeb, 0xfb, 0xcb }, INSTYPE_GEN8, 0, insn_gen }, + { "addd", { 0xd3, 0xe3, 0xf3, 0xc3 }, INSTYPE_GEN, 0, insn_gen }, + { "adde", { 0x119b, 0x11ab, 0x11bb, 0x118b }, INSTYPE_GEN8, 0, insn_gen }, + { "addf", { 0x11db, 0x11eb, 0x11fb, 0x11cb }, INSTYPE_GEN8, 0, insn_gen }, + { "addr", { 0x1030, -0x1, -0x1, -0x1 }, INSTYPE_RTOR, 0, insn_rtor }, + { "addw", { 0x109b, 0x10ab, 0x10bb, 0x108b }, INSTYPE_GEN, 0, insn_gen }, + { "aim", { 0x02, 0x62, 0x72, -0x1 }, INSTYPE_LOGICMEM, 0, insn_logicmem }, + { "anda", { 0x94, 0xa4, 0xb4, 0x84 }, INSTYPE_GEN8, 0, insn_gen }, + { "andb", { 0xd4, 0xe4, 0xf4, 0xc4 }, INSTYPE_GEN8, 0, insn_gen }, + { "andcc", { 0x1c, -0x1, -0x1, 0x1c }, INSTYPE_IMM8, 0, insn_gen }, + { "andd", { 0x1094, 0x10a4, 0x10b4, 0x1084 }, INSTYPE_GEN, 0, insn_gen }, + { "andr", { 0x1034, -0x1, -0x1, -0x1 }, INSTYPE_RTOR, 0, insn_rtor }, + { "asl", { 0x08, 0x68, 0x78, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "asla", { 0x48, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "aslb", { 0x58, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "asld", { 0x1048, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "asr", { 0x07, 0x67, 0x77, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "asra", { 0x47, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "asrb", { 0x57, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "asrd", { 0x1047, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + + { "band", { 0x1130, -0x1, -0x1, -0x1 }, INSTYPE_BITBIT, 0, insn_bitbit }, + { "bcc", { 0x24, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bcs", { 0x25, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "beor", { 0x1134, -0x1, -0x1, -0x1 }, INSTYPE_BITBIT, 0, insn_bitbit }, + { "beq", { 0x27, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bge", { 0x2c, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bgt", { 0x2e, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bhi", { 0x22, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bhs", { 0x24, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "biand", { 0x1131, -0x1, -0x1, -0x1 }, INSTYPE_BITBIT, 0, insn_bitbit }, + { "bieor", { 0x1135, -0x1, -0x1, -0x1 }, INSTYPE_BITBIT, 0, insn_bitbit }, + { "bior", { 0x1133, -0x1, -0x1, -0x1 }, INSTYPE_BITBIT, 0, insn_bitbit }, + { "bita", { 0x95, 0xa5, 0xb5, 0x85 }, INSTYPE_GEN8, 0, insn_gen }, + { "bitb", { 0xd5, 0xe5, 0xf5, 0xc5 }, INSTYPE_GEN8, 0, insn_gen }, + { "bitd", { 0x1095, 0x10a5, 0x10b5, 0x1085 }, INSTYPE_GEN, 0, insn_gen }, + { "bitmd", { 0x113c, -0x1, -0x1, 0x113c }, INSTYPE_IMM8, 0, insn_gen }, + { "ble", { 0x2f, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "blo", { 0x25, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bls", { 0x23, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "blt", { 0x2d, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bmi", { 0x2b, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bne", { 0x26, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bor", { 0x1132, -0x1, -0x1, -0x1 }, INSTYPE_BITBIT, 0, insn_bitbit }, + { "bpl", { 0x2a, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bra", { 0x20, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "brn", { 0x21, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bsr", { 0x8d, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bvc", { 0x28, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "bvs", { 0x29, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + + { "clr", { 0x0f, 0x6f, 0x7f, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "clra", { 0x4f, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "clrb", { 0x5f, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "clrd", { 0x104f, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "clre", { 0x114f, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "clrf", { 0x115f, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "clrw", { 0x105f, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "cmpa", { 0x91, 0xa1, 0xb1, 0x81 }, INSTYPE_GEN8, 0, insn_gen }, + { "cmpb", { 0xd1, 0xe1, 0xf1, 0xc1 }, INSTYPE_GEN8, 0, insn_gen }, + { "cmpd", { 0x1093, 0x10a3, 0x10b3, 0x1083 }, INSTYPE_GEN, 0, insn_gen }, + { "cmpe", { 0x1191, 0x11a1, 0x11b1, 0x1181 }, INSTYPE_GEN8, 0, insn_gen }, + { "cmpf", { 0x11d1, 0x11e1, 0x11f1, 0x11c1 }, INSTYPE_GEN8, 0, insn_gen }, + { "cmpr", { 0x1037, -0x1, -0x1, -0x1 }, INSTYPE_RTOR, 0, insn_rtor }, + { "cmps", { 0x119c, 0x11ac, 0x11bc, 0x118c }, INSTYPE_GEN, 0, insn_gen }, + { "cmpu", { 0x1193, 0x11a3, 0x11b3, 0x1183 }, INSTYPE_GEN, 0, insn_gen }, + { "cmpw", { 0x1091, 0x10a1, 0x10b1, 0x1081 }, INSTYPE_GEN, 0, insn_gen }, + { "cmpx", { 0x9c, 0xac, 0xbc, 0x8c }, INSTYPE_GEN, 0, insn_gen }, + { "cmpy", { 0x109c, 0x10ac, 0x10bc, 0x108c }, INSTYPE_GEN, 0, insn_gen }, + { "com", { 0x03, 0x63, 0x73, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "coma", { 0x43, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "comb", { 0x53, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "comd", { 0x1043, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "come", { 0x1143, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "comf", { 0x1153, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "comw", { 0x1053, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "cwai", { 0x3c, -0x1, -0x1, -0x1 }, INSTYPE_IMM8, 0, insn_gen }, + + { "daa", { 0x19, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "dec", { 0x0a, 0x6a, 0x7a, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "deca", { 0x4a, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "decb", { 0x5a, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "decd", { 0x104a, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "dece", { 0x114a, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "decf", { 0x115a, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "decw", { 0x105a, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "divd", { 0x118d, 0x119d, 0x11ad, 0x11bd }, INSTYPE_GEN8, 0, insn_gen }, + { "divq", { 0x118e, 0x119e, 0x11ae, 0x11be }, INSTYPE_GEN, 0, insn_gen }, + + { "eim", { 0x05, 0x65, 0x75, -0x1 }, INSTYPE_LOGICMEM, 0, insn_logicmem }, + { "eora", { 0x98, 0xa8, 0xb8, 0x88 }, INSTYPE_GEN8, 0, insn_gen }, + { "eorb", { 0xd8, 0xe9, 0xf9, 0xc8 }, INSTYPE_GEN8, 0, insn_gen }, + { "eord", { 0x1098, 0x10a8, 0x10b8, 0x1088 }, INSTYPE_GEN, 0, insn_gen }, + { "eorr", { 0x1036, -0x1, -0x1, -0x1 }, INSTYPE_RTOR, 0, insn_rtor }, + { "exg", { 0x1e, -0x1, -0x1, -0x1 }, INSTYPE_RTOR, 0, insn_rtor }, + + { "inc", { 0x0c, 0x6c, 0x7c, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "inca", { 0x4c, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "incb", { 0x5c, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "incd", { 0x104c, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "ince", { 0x114c, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "incf", { 0x115c, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "incw", { 0x105c, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + + { "jmp", { 0x0e, 0x6e, 0x7e, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "jsr", { 0x9d, 0xad, 0xbd, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + + { "lbcc", { 0x1024, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbcs", { 0x1025, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbeq", { 0x1027, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbge", { 0x102c, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbgt", { 0x102e, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbhi", { 0x1022, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbhs", { 0x1024, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lble", { 0x102f, -0x1, -0x1, -0x1 }, INSTYPE_REL8, 0, insn_rel8 }, + { "lblo", { 0x1025, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbls", { 0x1023, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lblt", { 0x102d, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbmi", { 0x102b, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbne", { 0x1026, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbpl", { 0x102a, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbra", { 0x16, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbrn", { 0x1021, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbsr", { 0x17, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbvc", { 0x1028, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lbvs", { 0x1029, -0x1, -0x1, -0x1 }, INSTYPE_REL16, 0, insn_rel16 }, + { "lda", { 0x96, 0xa6, 0xb6, 0x86 }, INSTYPE_GEN8, 0, insn_gen }, + { "ldb", { 0xd6, 0xe6, 0xf6, 0xc6 }, INSTYPE_GEN8, 0, insn_gen }, + { "ldbt", { 0x1136, -0x1, -0x1, -0x1 }, INSTYPE_BITBIT, 0, insn_bitbit }, + { "ldd", { 0xdc, 0xec, 0xfc, 0xcc }, INSTYPE_GEN, 0, insn_gen }, + { "lde", { 0x1196, 0x11a6, 0x11b6, 0x1186 }, INSTYPE_GEN8, 0, insn_gen }, + { "ldf", { 0x11d6, 0x11e6, 0x11f6, 0x11c6 }, INSTYPE_GEN8, 0, insn_gen }, + { "ldq", { 0x10dc, 0x10ec, 0x10fc, 0xcd }, INSTYPE_GEN32, 0, insn_gen }, + { "lds", { 0x10de, 0x10ee, 0x10fe, 0x10ce }, INSTYPE_GEN, 0, insn_gen }, + { "ldu", { 0xde, 0xee, 0xfe, 0xce }, INSTYPE_GEN, 0, insn_gen }, + { "ldw", { 0x1096, 0x10a6, 0x10b6, 0x1086 }, INSTYPE_GEN, 0, insn_gen }, + { "ldx", { 0x9e, 0xae, 0xbe, 0x8e }, INSTYPE_GEN, 0, insn_gen }, + { "ldy", { 0x109e, 0x10ae, 0x10be, 0x108e }, INSTYPE_GEN, 0, insn_gen }, + { "ldmd", { 0x113d, -0x1, -0x1, 0x113d }, INSTYPE_IMM8, 0, insn_gen }, + { "leas", { 0x32, -0x1, -0x1, -0x1 }, INSTYPE_INDEX, 0, insn_indexed }, + { "leau", { 0x33, -0x1, -0x1, -0x1 }, INSTYPE_INDEX, 0, insn_indexed }, + { "leax", { 0x30, -0x1, -0x1, -0x1 }, INSTYPE_INDEX, 0, insn_indexed }, + { "leay", { 0x31, -0x1, -0x1, -0x1 }, INSTYPE_INDEX, 0, insn_indexed }, + { "lsl", { 0x08, 0x68, 0x78, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "lsla", { 0x48, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "lslb", { 0x58, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "lsld", { 0x1048, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "lsr", { 0x04, 0x64, 0x74, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "lsra", { 0x44, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "lsrb", { 0x54, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "lsrd", { 0x1044, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "lsrw", { 0x1054, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + + { "mul", { 0x3d, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "muld", { 0x118f, 0x119f, 0x11af, 0x11bf }, INSTYPE_GEN, 0, insn_gen }, + + { "neg", { 0x00, 0x60, 0x70, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "nega", { 0x40, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "negb", { 0x50, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "negd", { 0x1040, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "nop", { 0x12, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + + { "oim", { 0x01, 0x61, 0x71, -0x1 }, INSTYPE_LOGICMEM, 0, insn_logicmem }, + { "ora", { 0x9a, 0xaa, 0xba, 0x8a }, INSTYPE_GEN8, 0, insn_gen }, + { "orb", { 0xda, 0xea, 0xfa, 0xca }, INSTYPE_GEN8, 0, insn_gen }, + { "orcc", { 0x1a, -0x1, -0x1, 0x1a }, INSTYPE_IMM8, 0, insn_gen }, + { "ord", { 0x109a, 0x10aa, 0x10ba, 0x108a }, INSTYPE_GEN, 0, insn_gen }, + { "orr", { 0x1035, -0x1, -0x1, -0x1 }, INSTYPE_RTOR, 0, insn_rtor }, + + { "pshs", { 0x34, -0x1, -0x1, -0x1 }, INSTYPE_RLIST, 0, insn_rlist }, + { "pshsw", { 0x1038, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "pshu", { 0x36, -0x1, -0x1, -0x1 }, INSTYPE_RLIST, 0, insn_rlist }, + { "pshuw", { 0x103a, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "puls", { 0x35, -0x1, -0x1, -0x1 }, INSTYPE_RLIST, 0, insn_rlist }, + { "pulsw", { 0x1039, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "pulu", { 0x37, -0x1, -0x1, -0x1 }, INSTYPE_RLIST, 0, insn_rlist }, + { "puluw", { 0x103b, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + + { "rol", { 0x09, 0x69, 0x79, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "rola", { 0x49, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "rolb", { 0x59, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "rold", { 0x1049, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "rolw", { 0x1059, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "ror", { 0x06, 0x66, 0x76, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "rora", { 0x46, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "rorb", { 0x56, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "rord", { 0x1046, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "rorw", { 0x1056, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "rti", { 0x3b, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "rts", { 0x39, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + + { "sbca", { 0x92, 0xa2, 0xb2, 0x82 }, INSTYPE_GEN8, 0, insn_gen }, + { "sbcb", { 0xd2, 0xe2, 0xf2, 0xc2 }, INSTYPE_GEN8, 0, insn_gen }, + { "sbcd", { 0x1092, 0x10a2, 0x10b2, 0x1082 }, INSTYPE_GEN, 0, insn_gen }, + { "sbcr", { 0x1033, -0x1, -0x1, -0x1 }, INSTYPE_RTOR, 0, insn_rtor }, + { "sex", { 0x1d, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "sexw", { 0x14, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "sta", { 0x97, 0xa7, 0xb7, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "stb", { 0xd7, 0xe7, 0xf7, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "stbt", { 0x1137, -0x1, -0x1, -0x1 }, INSTYPE_BITBIT, 0, insn_bitbit }, + { "std", { 0xdd, 0xed, 0xfd, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "ste", { 0x1197, 0x11a7, 0x11b7, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "stf", { 0x11d7, 0x11e7, 0x11f7, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "stq", { 0x10dd, 0x10ed, 0x10fd, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "sts", { 0x10df, 0x10ef, 0x10ff, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "stu", { 0xdf, 0xef, 0xff, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "stw", { 0x1097, 0x10a7, 0x10b7, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "stx", { 0x9f, 0xaf, 0xbf, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "sty", { 0x109f, 0x10af, 0x10bf, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "suba", { 0x90, 0xa0, 0xb0, 0x80 }, INSTYPE_GEN8, 0, insn_gen }, + { "subb", { 0xd0, 0xe0, 0xf0, 0xc0 }, INSTYPE_GEN8, 0, insn_gen }, + { "subd", { 0x93, 0xa3, 0xb3, 0x83 }, INSTYPE_GEN, 0, insn_gen }, + { "sube", { 0x1190, 0x11a0, 0x11b0, 0x1180 }, INSTYPE_GEN8, 0, insn_gen }, + { "subf", { 0x11d0, 0x11e0, 0x11f0, 0x11c0 }, INSTYPE_GEN8, 0, insn_gen }, + { "subr", { 0x1032, -0x1, -0x1, -0x1 }, INSTYPE_RTOR, 0, insn_rtor }, + { "subw", { 0x1090, 0x10a0, 0x1090, 0x1080 }, INSTYPE_GEN8, 0, insn_gen }, + { "swi", { 0x3f, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "swi2", { 0x103f, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "swi3", { 0x113f, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "sync", { 0x13, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + + // note: r+,r+ r-,r- r+,r r,r+ + { "tfm", { 0x1138, 0x1139, 0x113a, 0x113b }, INSTYPE_TFM, 0, insn_tfm }, + + { "tfr", { 0x1f, -0x1, -0x1, -0x1 }, INSTYPE_RTOR, 0, insn_rtor }, + { "tim", { 0x0b, 0x6b, 0x7b, -0x1 }, INSTYPE_LOGICMEM, 0, insn_logicmem }, + { "tst", { 0x0d, 0x6d, 0x7d, -0x1 }, INSTYPE_GENNOIMM, 0, insn_gen }, + { "tsta", { 0x4d, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "tstb", { 0x5d, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "tstd", { 0x104d, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "tste", { 0x114d, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "tstf", { 0x115d, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + { "tstw", { 0x105d, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh }, + + // pseudo ops are here + { "org", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_ORG, pseudo_org }, + { "equ", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_EQU, pseudo_equ }, + { "=", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_EQU, pseudo_equ }, + { "setdp", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_SETDP, pseudo_setdp }, + { "fcb", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_FCB, pseudo_fcb }, + { "fdb", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_FDB, pseudo_fdb }, + { "fqb", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_FQB, pseudo_fqb }, + { "fcc", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_FCC, pseudo_fcc }, + { "fcs", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_FCS, pseudo_fcs }, + { "fcn", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_FCN, pseudo_fcn }, + { "rmb", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_RMB, pseudo_rmb }, + { "align", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_ALIGN, pseudo_align }, + { "end", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_END, pseudo_end }, + { "include",{ -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_INCLUDE, pseudo_include }, +// { "absolute", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "bsz", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "byte", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_fcb }, +// { "cond", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_cond }, +// { "db", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_fcb }, +// { "ds", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_rmb }, +// { "dtb", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "dts", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "dw", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_fdb }, +// { "dword", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_fqb }, + { "else", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_ELSE, pseudo_else }, +// { "emod", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, + { "endc", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_ENDC, pseudo_endc }, + { "endif", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_ENDC, pseudo_endc }, +// { "even", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "fcr", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "fill", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "fzb", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "fzd", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "fzq", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, + { "if", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_COND, pseudo_ifne }, + { "ifeq", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_COND, pseudo_ifeq }, + { "ifge", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_COND, pseudo_ifge }, + { "ifgt", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_COND, pseudo_ifgt }, + { "ifle", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_COND, pseudo_ifle }, + { "iflt", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_COND, pseudo_iflt }, + { "ifne", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_COND, pseudo_ifne }, +// { "ifp1", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "ifp2", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "lib", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "mod", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "nam", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "name", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "nam", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "odd", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "opt", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "pag", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "page", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "page0", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "page1", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, + { "rmd", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_rmd }, + { "rmq", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_rmq }, +// { "set", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "spc", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "title", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "ttl", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "use", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "word", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_fdb }, + { "zmb", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_zmb }, + { "zmd", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_zmd }, + { "zmq", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_zmq }, + + { "macro", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_MACRO, pseudo_macro }, + { "endm", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, SPECIAL_ENDM, pseudo_endm }, +// { "struct", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, +// { "endstruct", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, NULL }, + +// { "namespace", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_namespace }, +// { "endnamespace", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_endnamespace }, +// { "endname", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_endnamespace }, + { "error", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_error }, + + { "set", { -1, -1, -1, -1 }, INSTYPE_PSEUDO, 0, pseudo_set }, + + { "pragma", { -1, -1, -1, -1}, INSTYPE_PSEUDO, 0, pseudo_pragma }, + { "*pragma", { -1, -1, -1, -1}, INSTYPE_PSEUDO, 0, pseudo_starpragma }, + + /* flag end of table */ + { NULL, { -0x1, -0x1, -0x1, -0x1 }, INSTYPE_INH, 0, insn_inh } +}; diff -r 000000000000 -r 57495da01900 src/instab.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/instab.h Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,60 @@ +/* + * instab.h + * + * definitions for the instruction table + */ + +#include "lwasm.h" + +#ifndef __instab_h_seen__ +#define __instab_h_seen__ + +#define INSTYPE_INH 0 /* inherent addressing */ +#define INSTYPE_GEN 1 /* general addressing modes */ +#define INSTYPE_GEN8 2 /* general addressing, 8 bit immed */ +#define INSTYPE_GENNOIMM 3 /* no immediate addressing */ +#define INSTYPE_RTOR 4 /* register to register */ +#define INSTYPE_RLIST 5 /* register list */ +#define INSTYPE_REL8 6 /* relative addressing */ +#define INSTYPE_REL16 7 /* 16 bit relative addressing */ +#define INSTYPE_INDEX 8 /* indexed mode only */ +#define INSTYPE_IMM8 9 /* immediate only 8 bit (andcc, cwai) */ +#define INSTYPE_LOGICMEM 10 /* aim/oim/eim/tim */ +#define INSTYPE_BITBIT 11 /* bit to bit ops */ +#define INSTYPE_TFM 12 /* TFM ops */ +#define INSTYPE_GEN32 13 /* general addressing, 32 bit immed */ +#define INSTYPE_PSEUDO 14 /* special handling, pseudo op */ + +#define SPECIAL_EQU 1 /* equ */ +#define SPECIAL_ORG 2 /* org */ +#define SPECIAL_SETDP 3 +#define SPECIAL_FCB 4 +#define SPECIAL_FDB 5 +#define SPECIAL_FQB 6 +#define SPECIAL_FCC 7 +#define SPECIAL_FCS 8 +#define SPECIAL_FCN 9 +#define SPECIAL_RMB 10 +#define SPECIAL_ALIGN 11 +#define SPECIAL_END 12 +#define SPECIAL_INCLUDE 13 +#define SPECIAL_ENDM 14 +#define SPECIAL_ENDC 15 +#define SPECIAL_MACRO 16 +#define SPECIAL_COND 17 +#define SPECIAL_ELSE 18 + +typedef struct +{ + char *opcode; /* the mneumonic */ + int ops[4]; /* opcode values for up to four addr modes */ + int instype; /* type of instruction (see above) */ + int specialnum; /* type of special instruction */ + void (*opfn)(asmstate_t *as, sourceline_t *cl, char **optr); +} instab_t; + +#ifndef __instab_c_seen__ +extern instab_t instab[]; +#endif //__instab_c_seen__ + +#endif //__instab_h_seen__ diff -r 000000000000 -r 57495da01900 src/list.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/list.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,154 @@ +/* + * list.c + * + * code for displaying a program listing in lwasm + */ + +//#include +#include +#include +//#include +#include +#define __list_c_seen__ +//#include "instab.h" +#include "lwasm.h" + +const char *errlist[] = +{ + "No error", + "Bad opcode", + "Illegal Symbol", + "Multiply defined symbol", + "Symbol required but not present", + "Forward references not permitted", + "Byte overflow", + "Phase error", + "Bad operand", + "Symbol not permitted here", + "Undefined symbol", + "Bit number out of range", + "Invalid expression", + "Invalid register", + "Bad file name", + "ENDM without MACRO", + "Redefined macro", + "Nested namespace", + "Bad condition", + "User error", + "Bad pragma", + "" +}; + +void list_code(asmstate_t *as) +{ + FILE *lf; + sourceline_t *cl; + int bn; + int c; + char *t; + + if (as -> listfile && strcmp(as -> listfile, "-")) + { + lf = fopen(as -> listfile, "w"); + if (!lf) + { + perror("Cannot open list file"); + return; + } + } + else + { + lf = stdout; + } + + for (cl = as -> source_head; cl; cl = cl -> next) + { + bn = 0; + if (cl -> errors) + { + errortab_t *e; + for (e = cl -> errors; e; e = e -> next) + { + if (e -> errnum < ERR_MAXERR && e -> errnum != ERR_USER) + fprintf(lf, "*****ERROR: %s\n", errlist[e -> errnum]); + } + if (cl -> user_error) + { + fprintf(lf, "*****ERROR: %s\n", cl -> user_error); + } + } + if (cl -> skipped) + { + fprintf(lf, "%-15.15s", ""); + } + else if (cl -> macrodef) + { + fprintf(lf, "%-15.15s", ""); + } + else if (cl -> opcode >= 0 && cl -> numcodebytes > 0) + { + fprintf(lf, "%04X ", cl -> addr); + while (bn < 5 && bn < cl -> numcodebytes) + { + fprintf(lf, "%02X", cl -> codebytes[bn]); + bn++; + } + while (bn < 5) + { + fprintf(lf, " "); + bn++; + } + } + else if (cl -> addrset || (cl -> len && cl -> numcodebytes == 0)) + { + fprintf(lf, "%04X %10s", cl -> addr, ""); + } + else if (cl -> isequ) + { + fprintf(lf, " %04X ", cl -> symaddr); + } + else if (cl -> issetdp) + { + fprintf(lf, " %02X ", cl -> dpval); + } + else + fprintf(lf, " "); + fprintf(lf, " %15.15s:%06d ", cl -> sourcefile, cl -> lineno); + // actually display the line from the file + for (c = 0, t = cl -> line; *t; t++) + { + if (*t == '\n' || *t == '\r') + break; + if (*t == '\t') + { + do + { + fprintf(lf, " "); + c++; + } while (c % 8); + } + else + { + c++; + fprintf(lf, "%c", *t); + } + } +// fprintf(lf, "\n"); + + while (bn < cl -> numcodebytes) + { + if (bn % 5 == 0) + fprintf(lf, "\n%04X ", (cl -> addr + bn) & 0xFFFF); + fprintf(lf, "%02X", cl -> codebytes[bn]); + bn++; + } + fprintf(lf, "\n"); + } + + fprintf(lf, "\n"); + list_symbols(as, lf); + + if (lf != stdout) + fclose(lf); +} + diff -r 000000000000 -r 57495da01900 src/lwasm.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lwasm.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,879 @@ +/* + * lwasm.c + * + * main code for lwasm + */ + +#include +#include +#include +#include +#include +#define __lwasm_c_seen__ +#include "instab.h" +#include "lwasm.h" + +void lwasm_read_file(asmstate_t *as, char *fname); +extern int add_macro_line(asmstate_t *as, sourceline_t *cl, char *optr); +extern void expand_macro(asmstate_t *as, sourceline_t *cl, char **optr); + +#define debug(mess, ...) do { if (as->debug) { fprintf(stderr, "DEBUG: "); fprintf(stderr, (mess), ## __VA_ARGS__); } } while (0) + +void register_error(asmstate_t *as, sourceline_t *cl, int errcode) +{ + errortab_t *e; + + e = malloc(sizeof(errortab_t)); + + e -> errnum = errcode; + e -> line = cl; + e -> next = cl -> errors; + cl -> errors = e; + + as -> errorcount++; +} + +int eval_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *val); + +int eval_min(int v1, int v2, int v3, int v4) +{ + if (v2 < v1) + v1 = v2; + if (v3 < v1) + v1 = v3; + if (v4 < v1) + v1 = v4; + return v1; +} + +int eval_max(int v1, int v2, int v3, int v4) +{ + if (v2 > v1) + v1 = v2; + if (v3 > v1) + v1 = v3; + if (v4 > v1) + v1 = v4; + return v1; +} + +int lookupreg3(const char *rlist, char **str) +{ + int rval = 0; + int f = 0; + const char *reglist = rlist; + + while (*reglist) + { + if (toupper(**str) == *reglist) + { + // first char matches + if (reglist[1] == ' ') + { + f = 1; + break; + } + if (toupper(*(*str + 1)) == reglist[1]) + { + // second char matches + if (reglist[2] == ' ') + { + f = 1; + break; + } + if (toupper(*(*str + 2)) == reglist[2]) + { + f = 1; + break; + } + } + } + reglist += 3; + rval++; + } + if (f == 0) + return -1; + + + reglist = rval * 3 + rlist; + if (reglist[1] == ' ') + (*str) += 1; + else if (reglist[2] == ' ') + (*str) += 2; + else + (*str)+=3; + return rval; +} + + +int lookupreg(const char *reglist, char **str) +{ + int rval = 0; + while (*reglist) + { + if (toupper(**str) == *reglist) + { + // first char matches + if (reglist[1] == ' ' && !isalpha(*(*str + 1))) + break; + if (toupper(*(*str + 1)) == reglist[1]) + break; + } + reglist += 2; + rval++; + } + if (!*reglist) + return -1; + if (reglist[1] == ' ') + (*str)++; + else + (*str)+=2; + return rval; +} + +void addcodebyte(asmstate_t *as, sourceline_t *cl, int cb) +{ + cl -> len += 1; + if (as -> passnum != 2) + return; + + if (cl -> numcodebytes >= cl -> codesize) + { + cl -> codebytes = realloc(cl -> codebytes, cl -> codesize + 32); + cl -> codesize += 32; + } + debug("EMIT: %02x\n", cb & 0xff); + cl -> codebytes[cl -> numcodebytes++] = cb & 0xFF; +} + +// parse a symble out of the line and return a pointer +// to a static pointer +// return NULL if not a symbol or a bad symbol +char *parse_symbol(asmstate_t *as, char **ptr) +{ + static char *symptr = NULL; + char *tptr = *ptr; + int sl = 0; + + // symbol can start with _,a-z,A-Z + + if (!strchr(SYMCHAR_START, **ptr)) + return NULL; + + while (*tptr && !isspace(*tptr) && strchr(SYMCHAR, *tptr)) + { + tptr++; + sl++; + } + + symptr = realloc(symptr, sl + 1); + tptr = symptr; + while (sl) + { + *tptr++ = *(*ptr)++; + sl--; + } + *tptr = '\0'; + return symptr; +} + +// resolve an instruction +void resolve_insn(asmstate_t *as, sourceline_t *cl) +{ + char *optr; + char opbuf[MAX_OP_LEN + 1]; + char *symbol = NULL; + int c; + + cl -> code_symloc = as -> addr; + + cl -> addrset = 0; + cl -> isequ = 0; + cl -> len = 0; + cl -> undef = 0; + + // only parse line on first pass + if (as -> passnum == 1) + { + optr = cl -> line; + if (!*optr || *optr == '*' || *optr == ';') + { + cl -> opcode = -1; + cl -> remainder = cl -> line; + return; + } + + if (!isspace(*optr)) + { + symbol = parse_symbol(as, &optr); + if (*optr && !isspace(*optr) && !(as -> inmacro)) + { + errorp1(ERR_BADSYM); + while (*optr && !isspace(*optr)) + optr++; + } + if (symbol) + { + cl -> symstr = strdup(symbol); + cl -> hassym = 1; + } + } + + while (isspace(*optr)) + optr++; + + // parse opcode + if (*optr && *optr != ';') + { + c = 0; + while (c < MAX_OP_LEN && *optr && !isspace(*optr)) + { + opbuf[c++] = *optr++; + } + opbuf[c] = '\0'; + if (*optr && !isspace(*optr) && !(as -> inmacro)) + { + errorp1(ERR_BADOP); + cl -> opcode = -1; + } + else + { + cl -> opcstr = strdup(opbuf); + for (c = 0; instab[c].opcode; c++) + { + if (!strcasecmp(opbuf, instab[c].opcode)) + break; + } + if (!instab[c].opcode && opbuf[0] == '*') + { + cl -> opcode = -1; + } + else if (!instab[c].opcode && !(as -> inmacro)) + { + cl -> opcode = -1; + + // look up macro + if (as -> macros) + { + macrotab_t *m; + + for (m = as -> macros; m; m = m -> next) + { + if (!strcmp(m -> name, opbuf)) + break; + } + if (m) + { + // we have a macro here + cl -> macro = m; + while (*optr && isspace(*optr)) + optr++; + expand_macro(as, cl, &optr); + return; + } + else + { + errorp1(ERR_BADOP); + } + } + else + { + errorp1(ERR_BADOP); + } + } + else + cl -> opcode = c; + } + } + else + cl -> opcode = -1; + + if (as -> inmacro && cl -> opcode >= 0 && instab[cl -> opcode].specialnum != SPECIAL_ENDM) + { + add_macro_line(as, cl, cl -> line); + cl -> opcode = -1; + cl -> remainder = cl -> line; + cl -> opcstr = NULL; + cl -> operstr = NULL; + cl -> symstr = NULL; + cl -> hassym = 0; + cl -> macrodef = 1; + return; + } + // parse operand + while (*optr && isspace(*optr)) + optr++; + + cl -> operstr = optr; + } + else + optr = cl -> operstr; + + if (as -> skipcond) + { + // if skipping a condition, need to skip a macro + if (cl -> opcode >= 0) + { + if (instab[cl -> opcode].specialnum == SPECIAL_MACRO) + { + as -> skipmacro = 1; + } + else if (instab[cl -> opcode].specialnum == SPECIAL_ENDM) + { + as -> skipmacro = 0; + } + else if (instab[cl -> opcode].specialnum == SPECIAL_COND && !(as -> skipmacro)) + { + as -> skipcount++; + } + else if (instab[cl -> opcode].specialnum == SPECIAL_ENDC && !(as -> skipmacro)) + { + as -> skipcount--; + if (as -> skipcount <= 0) + { + as -> skipcond = 0; + as -> noelse = 0; + } + } + else if (instab[cl -> opcode].specialnum == SPECIAL_ELSE && !(as -> skipmacro)) + { + if (as -> skipcount == 1) + { + as -> skipcount = 0; + as -> skipcond = 0; + as -> noelse = 1; + return; + } + } + } + if (as -> skipcond) + cl -> skipped = 1; + return; + } + + // do the code thing + // on pass 1, no code is generated + // on pass 2, code is generated using the "emit()" macro + if (cl -> opcode >= 0) + { + if (instab[cl -> opcode].opfn) + { + (*(instab[cl -> opcode].opfn))(as, cl, &optr); + if (as -> passnum == 1) + { + if (*optr) + { + char *t = optr; + char t2; + + t2 = *optr; + cl -> operstr = strdup(cl -> operstr); + *optr = t2; + while (*t && isspace(*t)) + t++; + cl -> remainder = strdup(t); + + } + cl -> remainder = optr; + } + } + else + { + errorp1(ERR_BADOP); + cl -> opcode = -1; + } + } + // address of the symbol may have been changed by a pseudo op + // so we couldn't register it above + // that means it may turn out to be a "forward ref" in pass 1 + if (cl -> hassym) + { + register_symbol(as, cl, cl -> symstr, cl -> code_symloc, cl -> isset ? SYMFLAG_SET : SYMFLAG_NONE); + } + + as -> addr += cl -> len; +} + +void generate_code(asmstate_t *as) +{ + sourceline_t *cl; + + as -> addr = 0; + as -> dpval = 0; + as -> passnum = 2; + for (cl = as -> source_head; cl; cl = cl -> next) + { + resolve_insn(as, cl); + } +} + +void lwasm_read_file(asmstate_t *as, char *fname) +{ + FILE *f; + int cline = 0; + sourceline_t *cl; + size_t bufflen; + char *buff = NULL; + int retval; + + as -> passnum = 1; + + f = fopen(fname, "r"); + if (!f) + { + fprintf(stderr, "Cannot open input file %s: %s\n", fname, strerror(errno)); + return; + } + + while (!feof(f)) + { + retval = getline(&buff, &bufflen, f); + debug(" read line (%s:%d): %s\n", fname, cline, buff); + if (retval < 0) + { + if (feof(f)) + break; + fprintf(stderr, "Error reading '%s': %s\n", fname, strerror(errno)); + exit(1); + } + if (strchr(buff, '\n')) + *strchr(buff, '\n') = '\0'; + if (strchr(buff, '\r')) + *strchr(buff, '\r') = '\0'; + cl = calloc(sizeof(sourceline_t), 1); + if (!cl) + { + perror("Malloc"); + exit(1); + } + + cl -> lineno = cline++; + cl -> sourcefile = fname; + cl -> opcode = -1; + cl -> addrmode = -1; + cl -> addr = as -> addr; + cl -> dpval = as -> dpval; + cl -> prev = as -> source_tail; + if (as -> source_tail) + as -> source_tail -> next = cl; + as -> source_tail = cl; + if (as -> source_head == NULL) + as -> source_head = cl; + cl -> line = strdup(buff); + + resolve_insn(as, cl); + + if (cl -> opcode >= 0 && instab[cl -> opcode].instype == INSTYPE_PSEUDO && instab[cl -> opcode].specialnum == SPECIAL_END) + break; + + *buff = '\0'; + + } + if (buff) + free(buff); + + fclose(f); + + return; +} + +/* +below this point is the expression evaluation package + +Supported binary operators: + - / * % +Supported unary operators: - + +: + | - | * | / | % +: - +: +: +: ( ) +: +: ' +: " +: * +: + +: +: & + +: $ +: H +: @ +: O +: Q + +: % +: B + +: 0 | 1 +: | 2 | 3 | 4 | 5 | 6 | 7 +: | 8 | 9 +: | A | B | C | D | E | F + +NOTE: hex values which start with a non-digit will need to be prefixed +by $ or have a 0 as the leading digit; hence: $CC or 0CCH otherwise the +assembler cannot tell the difference between CCH as a symbol or CCH as +the value $CC + +*/ + +// will throw an error and return 0 in tval if there's a problem +// -1 is problem; cl -> undef set is undefined symbol +int eval_term(asmstate_t *as, sourceline_t *cl, char **optr, int *tval) +{ + char tc; + int rval; + int binval; + int octval; + int decval; + int hexval; + int valtype; + int digval; + int bindone = 0; + + *tval = 0; + +beginagain: + tc = **optr; + if (tc == '+') + { + // unary +, ignored for symetry + (*optr)++; + goto beginagain; + } + + if (tc == '(') + { + (*optr)++; + rval = eval_expr(as, cl, optr, tval); + if (rval < 0) + return rval; + if (**optr != ')') + { + errorp1(ERR_BADEXPR); + return -1; + } + (*optr)++; + return 0; + } + + if (tc == '-') + { + (*optr)++; + rval = eval_term(as, cl, optr, tval); + if (rval < 0) + return rval; + *tval = -*tval; + return 0; + } + + // current address (of current instruction, not PC) + if (tc == '*') + { + *tval = cl -> addr; + (*optr)++; + return 0; + } + + if (strchr("abcdefghijklmnopqrstuvwxyz_", tolower(tc))) + { + // evaluate a symbol + char *symbuf; + + symbuf = parse_symbol(as, optr); + if (!symbuf) + { + errorp1(ERR_BADSYM); + *tval = 0; + return -1; + } + + debug(" looking up symbol: %s\n", symbuf); + *tval = lookup_symbol(as, symbuf); + + // if not found, flag forward ref + if (*tval == -1) + { + errorp2(ERR_UNDEF); + cl -> undef = 1; + *tval = 0; + return 0; + } + return 0; + } + + if (tc == '%') + { + // binary number + int v1 = 0; + (*optr)++; + while (strchr("01", **optr)) + { + v1 = v1 << 1 | ((*(*optr)++) - '0'); + } + *tval = v1; + return 0; + } + if (tc == '$') + { + // hex number + int v1 = 0; + (*optr)++; + debug("HEX CONST: %s\n", *optr); + while (**optr && strchr("01234567890ABCDEF", toupper(tc = **optr))) + { + debug("HEX 2: %02x\n", tc); + if (**optr >= 'A') + { + v1 = v1 << 4 | (toupper((*(*optr)++)) - 'A' + 10); + } + else + { + v1 = v1 << 4 | ((*(*optr)++) - '0'); + } + } + *tval = v1; + return 0; + } + if (tc == '@') + { + // octal number + int v1 = 0; + (*optr)++; + while (strchr("01234567", **optr)) + { + v1 = v1 << 3 | ((*(*optr)++) - '0'); + } + *tval = v1; + return 0; + } + if (tc == '&') + { + // decimal number + int v1 = 0; + (*optr)++; + while (strchr("0123456789", **optr)) + { + v1 = v1 * 10 + ((*(*optr)++) - '0'); + } + *tval = v1; + return 0; + } + if (tc == '\'') + { + (*optr)++; + if (!**optr) + { + errorp1(ERR_BADEXPR); + return -2; + } + *tval = *(*optr)++; + return 0; + } + if (tc == '"') + { + (*optr)++; + if (!**optr || !*(*optr + 1)) + { + errorp1(ERR_BADEXPR); + return -2; + } + *tval = *(*optr)++ << 8 | *(*optr)++; + return 0; + } + // end of string + if (tc == '\0') + { + // error if at EOS as we are looking for a term + errorp1(ERR_BADEXPR); + return -1; + } + + // we have a generic number here which may be decimal, hex, binary, or octal + // based on a suffix + + // possible data types are binary (1), octal (2), decimal(4), hex (8) + valtype = 15; + hexval = octval = decval = binval = 0; + while (1) + { + +// printf(" %c\n", **optr); + if (!**optr || !strchr("ABCDEFabcdefqhoQHO0123456789", **optr)) + { + // end of string, must be decimal or the end of a bin + if (bindone == 1) + { + *tval = binval; + return 0; + } + if (valtype & 4) + { + *tval = decval; + return 0; + } + else + { + errorp1(ERR_BADEXPR); + return -1; + } + } + tc = toupper(*(*optr)++); + + if (tc == 'H') + { + if (valtype & 8) + { + *tval = hexval; + return 0; + } + else + { + // syntax error + errorp1(ERR_BADEXPR); + return -1; + } + } + + if (tc == 'Q' || tc == 'O') + { + if (valtype && 2) + { + *tval = octval; + return 0; + } + else + { + errorp1(ERR_BADEXPR); + return -1; + } + } + + digval = tc - '0'; + if (digval > 9) + digval -= 7; + + // if it's not in the range of a hex digit, error out + if (tc < '0' || (tc > '9' && tc < 'A') || tc > 'F') + { + (*optr)--; + if (valtype & 4) + { + *tval = decval; + return 0; + } + // if we're in hex/bin mode and run to the end of the number + // we must have a binary constant or an error + // if the previous character is B, then we have binary + // else we have error since hex would require a terminating H + // which would be caught above + if (valtype == 8 && toupper(*(*optr)) == 'B') + { + *tval = binval; + return 0; + } + errorp1(ERR_BADEXPR); + return -1; + } + + // if we have any characters past the end of the B, it's not binary + if (bindone == 1) + bindone = 0; + if (tc == 'B') + bindone = 1; + if (digval > 1) + valtype &= 14; + else if (digval > 7) + valtype &= 13; + else if (digval > 9) + valtype &= 11; + + if (valtype & 8) + { + hexval = (hexval << 4) | digval; + } + if (valtype & 4) + { + decval = decval * 10 + digval; + } + if (valtype & 2) + { + octval = (octval << 3) | digval; + } + if (valtype & 1 && !bindone) + { + binval = (binval << 1) | digval; + } + + } + // can't get here from there +} + +// returns -1 if the expression cannot be parsed +// and returns -2 if there is an undefined symbol reference +// resulting value will be in *val; undefined symbols are parsed as +// value 0 but cl -> undef will be set. +int eval_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *val) +{ + int left; + int right; + char oper; + int rval; + + // by default, return 0 in val + *val = 0; + cl -> undef = 0; + + rval = eval_term(as, cl, optr, &left); + if (rval < 0) + return rval; + +nextop: + oper = **optr; + + // end of expr + if (isspace(oper) || oper == ',' || oper == '\0' || oper == ']' || oper == ')') + goto retleft; + + // unrecognized chars + if (!strchr("+-*/%", oper)) + goto retleft; + + (*optr)++; + + rval = eval_term(as, cl, optr, &right); + // propagate error + if (rval < 0) + return rval; + + // do the operation and put it in "left" + switch (oper) + { + case '+': + left += right; + break; + + case '-': + left -= right; + break; + + case '*': + left *= right; + break; + + case '/': + left /= right; + break; + + case '%': + left %= right; + break; + } + + goto nextop; + +retleft: + *val = left; + return 0; +} diff -r 000000000000 -r 57495da01900 src/lwasm.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/lwasm.h Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,219 @@ +/* + * lwasm.h + * + * main defs used by the assembler + * + */ + + +#ifndef __lwasm_h_seen__ +#define __lwasm_h_seen__ + +#define MAX_OP_LEN 32 +#define SYMCHAR_START "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define SYMCHAR "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$." + +#define MACROCHAR_START "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" +#define MACROCHAR "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" + + +#define OPER_INH 0 +#define OPER_RTOR 1 +#define OPER_RLIST 2 +#define OPER_TFM 3 +#define OPER_IMM8 4 +#define OPER_IMM16 5 +#define OPER_IMM32 6 +#define OPER_DIR 7 +#define OPER_EXT 8 +#define OPER_INDEX 9 // indexed with no offset +#define OPER_DIREXT 10 // used as a placeholder when direct/extended unknown +#define OPER_BITBIT 11 // bit to bit direct page opers +#define OPER_REL8 12 +#define OPER_REL16 13 +#define OPER_INDEX5 14 // 5 bit offset indexed +#define OPER_INDEX8 15 // 8 bit offset indexed +#define OPER_INDEX16 16 // 16 bit offset indexed +#define OPER_INDEXV 17 // unknown size offset indexed +#define OPER_EXTIND 18 // extended indirect +#define OPER_LOGICD 19 // logic on mem, direct mode +#define OPER_LOGICE 20 // logic on mem, extended mode +#define OPER_LOGICEI 21 // logic on mem, extended indir mode +#define OPER_LOGICI 22 // logic on mem, indexed no offset +#define OPER_LOGICI5 23 // logic on mem, 5 bit indexed offset +#define OPER_LOGICI8 24 // logic on mem, 8 bit indexed offset +#define OPER_LOGICI16 25 // logic on mem, 16 bit indexed offset +#define OPER_LOGICIV 26 // logic on mem, unknown size offset + +#define OUTPUT_DECB 0 // DECB multirecord format +#define OUTPUT_RAW 1 // raw sequence of bytes +#define OUTPUT_RAWREL 2 // raw but with ORG as a relative offset + +enum +{ + ERR_NONE, // no error + ERR_BADOP, // bad opcode + ERR_BADSYM, // illegal symbol + ERR_DUPSYM, // duplicate symbol definition + ERR_NOSYM, // symbol required but not present + ERR_FORWARD, // forward references not permitted here + ERR_OVERFLOW, // byte overflow + ERR_PHASE, // phasing error + ERR_BADOPER, // bad operand + ERR_SYM, // symbol present where not permitted + ERR_UNDEF, // undefined symbol + ERR_OVERFLOW3, // bit number out of range + ERR_BADEXPR, // invalid expression + ERR_BADREG, // invalid register + ERR_BADFN, // bad file name + ERR_ENDM, // end macro without macro + ERR_MACRO, // redefined macro + ERR_NESTNAME, // nested namespace + ERR_BADCOND, // bad condition + ERR_USER, // user error + ERR_PRAGMA, // bad pragma + + ERR_MAXERR // last error in the list +}; + +typedef struct sourceline_s sourceline_t; + +// structure to keep track of errors +typedef struct errortab_s errortab_t; +struct errortab_s { + int errnum; + sourceline_t *line; + errortab_t *next; +}; + +typedef struct macroline_s macroline_t; +struct macroline_s +{ + char *linetext; + macroline_t *next; +}; + +typedef struct macrotab_s macrotab_t; +struct macrotab_s +{ + char *name; // name of the macro + macroline_t *linehead; // start of the macro lines + macroline_t *linetail; // last line of macro + macrotab_t *next; +}; + + +// structure to keep track of each line of the source +// this also keeps various bits of state about a line +struct sourceline_s { + char *sourcefile; // name of the source file + int lineno; // line number in the source file + char *symstr; // symbol on this line (if any) + int opcode; // index to instab for this line + int opbytes; // actual bytes of opcode + int postbyte; // post byte for the instruction + int numcodebytes; // how many code bytes for this line + unsigned char *codebytes; // actual code for this line + int codesize; // size of codebytes +// if minaddr and maxaddr are the same, we know exactly which address +// we are at so there can be no possible phase error with symbols defined +// here; these are *code* addresses + int len; // length of this insn + int in_macro; // set if it's a macro expansion line + int code_symloc; + int addrmode; // addressing mode of this insn + int addr; // the lowest possible address of this line + int dpval; // dp value at this point in the code + int hassym; // is there a symbol on this line + int addrset; // is this insn a point where the address is *set* (org) + int isequ; // does this insn set a symbol address (equ)? + int isset; // is the address setting from a "set"? + int issetdp; // this insn sets DP + int symaddr; // address for the symbol (if we're setting one) + // also used for "setdp" + int undef; // set if the symbol is undefined + int p1f16; // if we forced 16 bit on pass 1 so we can force it on pass 2 + int nocode; // if set, there is no code to output (rmb) + int notinsn; // if this is not a regular insn (used for formatting output) + char *line; // the text of the line + char *opcstr; // opcode string + char *operstr; // operand string + char *remainder; // remainder string (whole line if no opcode/operand + errortab_t *errors; // errors on this line + sourceline_t *next; // next line + sourceline_t *prev; // previous line + macrotab_t *macro; // pointer to macro table entry if this is a macro + int skipped; // set if the line was skipped + char *user_error; // user error message + int macrodef; // set if it's a macro definition line +}; + +// structure to keep the symbol table +typedef struct symtab_s symtab_t; +struct symtab_s { + char *symbol; // symbol name + sourceline_t *line; // pointer to the line where symbol is defined + int addr; // address of symbol (-1 for unknown) + int flags; // flags for symbol + symtab_t *next; // next symbol +}; + + +// keep track of current assembler state +typedef struct { + int dpval; // current dp value (setdp) + int addr; // current address + symtab_t *symbol_table; + sourceline_t *source_head; + sourceline_t *source_tail; + int errorcount; // error count + int passnum; // which pass are we on? + const char *infile; // input file + const char *outfile;// output file + const char *listfile; // output listing file + int debug; // debug mode + int outformat; // output format type: 0 = decb, 1 = raw + int execaddr; // execution address for the program (END ....) + macrotab_t *macros; // pointer to macros + int inmacro; // are we in a macro? + char *cur_namespace; // current namespace prefix + int skipcond; // are we skipping a condition? + int skipcount; // number of endc we need before we stop skipping + int skipmacro; // are we skipping a macro definition? + int noelse; // skipped an else? + int pragmas; // what pragmas are in effect? +} asmstate_t; + +#define PRAGMA_NOINDEX0TONONE 1 + + +#ifndef __lwasm_c_seen__ +extern int eval_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *val); +extern void register_error(asmstate_t *as, sourceline_t *cl, int errcode); +extern int lookupreg3(const char *rlist, char **str); +extern int lookupreg(const char *reglist, char **str); +extern void lwasm_read_file(asmstate_t *as, char *fname); +extern void addcodebyte(asmstate_t *as, sourceline_t *cl, int cb); +#endif + +#define SYMFLAG_NONE 0 +#define SYMFLAG_SET 1 + +#ifndef __symtab_c_seen__ +#include +extern void register_symbol(asmstate_t *as, sourceline_t *cl, char *symstr, int val, int flags); +extern int lookup_symbol(asmstate_t *as, char *symstr); +extern void list_symbols(asmstate_t *as, FILE *f); +#endif + + +#ifndef __index_c_seen__ +extern int parse_index_expr(asmstate_t *as, sourceline_t *cl, char **optr, int *postbyte, int *opmode, int *v1); +#endif + +#define emit(cb) do { addcodebyte(as, cl, (cb)); } while (0) +#define emitop(cb) do { if ((cb) > 0xff) addcodebyte(as, cl, (cb)>>8); addcodebyte(as, cl, (cb) & 0xff); } while (0) +#define errorp1(e) do { if (as -> passnum == 1) register_error(as, cl, (e)); } while (0) +#define errorp2(e) do { if (as -> passnum == 2) register_error(as, cl, (e)); } while (0) + +#endif //__lwasm_h_seen__ diff -r 000000000000 -r 57495da01900 src/macro.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/macro.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,215 @@ +/* + * macro.c + * + * stuff associated with macro processing + */ + +#include +#include +#include +#include "lwasm.h" + +extern void resolve_insn(asmstate_t *as, sourceline_t *cl); + +void pseudo_macro(asmstate_t *as, sourceline_t *cl, char **optr) +{ + macrotab_t *m; + + if (as -> inmacro) + { + errorp1(ERR_MACRO); + return; + } + as -> inmacro = 1; + if (as -> passnum != 1) + return; + + for (m = as -> macros; m; m = m -> next) + { + if (!strcmp(m -> name, cl -> symstr)) + break; + } + if (m) + { + errorp1(ERR_DUPSYM); + return; + } + m = calloc(sizeof(macrotab_t), 1); + m -> name = strdup(cl -> symstr); + m -> next = as -> macros; + as -> macros = m; + cl -> hassym = 0; + while (**optr && !isspace(**optr)) + (*optr)++; + cl -> macrodef = 1; +} + +void pseudo_endm(asmstate_t *as, sourceline_t *cl, char **optr) +{ + if (!as -> inmacro) + { + errorp1(ERR_ENDM); + return; + } + + as -> inmacro = 0; + cl -> macrodef = 1; +} + +int add_macro_line(asmstate_t *as, sourceline_t *cl, char *optr) +{ + macroline_t *l; + + if (!as -> inmacro) + return 0; + + if (as -> passnum == 2) + return 1; + + l = calloc(sizeof(macroline_t), 1); + l -> linetext = strdup(optr); + if (as -> macros -> linetail) + as -> macros -> linetail -> next = l; + as -> macros -> linetail = l; + if (!(as -> macros -> linehead)) + as -> macros -> linehead = l; + return 1; +} + +void macro_add_to_buff(char **buff, int *loc, int *len, char c) +{ + if (*loc == *len) + { + *buff = realloc(*buff, *len + 32); + *len += 32; + } + (*buff)[(*loc)++] = c; +} + +// this is just like a regular operation function +/* +macro args are references by "\n" where 1 <= n <= 9 +or by "\{n}"; a \ can be included by writing \\ +*/ +void expand_macro(asmstate_t *as, sourceline_t *cl, char **optr) +{ + char **args = NULL; + int nargs = 0; + int c; + sourceline_t *nl; + int nline = 1; + macrotab_t *m; + macroline_t *ml; + char *buff = NULL; + int bufflen = 0, buffloc; + + m = cl -> macro; + + // step the first: parse arguments + while (**optr && !isspace(**optr)) + { + c = 0; + while ((*optr)[c] && !isspace((*optr)[c]) && (*optr)[c] != ',') + { + c++; + } + args = realloc(args, sizeof(char *) * (nargs + 1)); + args[nargs] = malloc(c + 1); + strncpy(args[nargs], *optr, c); + args[nargs][c] = '\0'; + nargs++; + *optr += c; + if (**optr == ',') + (*optr)++; + } + + // step the second: iterate over the lines and expand arguments and add + // them after "cl" + for (ml = m -> linehead; ml; ml = ml -> next) + { + nl = calloc(sizeof(sourceline_t), 1); + + nl -> lineno = nline++; + nl -> sourcefile = m -> name; + nl -> opcode = -1; + nl -> addrmode = -1; + nl -> addr = as -> addr; + nl -> dpval = as -> dpval; + nl -> prev = cl; + if (!(cl -> next)) + as -> source_tail = nl; + nl -> next = cl -> next; + cl -> next = nl; + + buffloc = 0; + c = 0; + while (ml -> linetext[c]) + { + int ch; + ch = ml -> linetext[c++]; + if (ch == '{') + { + int v = 0; + again: + ch = ml -> linetext[c++]; + if (!ch) + { + c--; + continue; + } + if (ch >= '0' && ch <= '9') + { + v = v * 10 + (ch - '0'); + goto again; + } + if (ch == '}') + { + v--; + if (v < nargs) + { + char *t; + for (t = args[v]; *t; t++) + { + macro_add_to_buff(&buff, &buffloc, &bufflen, *t); + } + } + continue; + } + else + continue; + } + else if (ch == '\\' && ml -> linetext[c]) + { + ch = ml -> linetext[c++]; + if (ch >= '1' && ch <= '9') + { + ch -= '1'; + if (ch < nargs) + { + char *t; + for (t = args[ch]; *t; t++) + { + macro_add_to_buff(&buff, &buffloc, &bufflen, *t); + } + } + } + else + { + c--; + macro_add_to_buff(&buff, &buffloc, &bufflen, '\\'); + } + } + else + { + macro_add_to_buff(&buff, &buffloc, &bufflen, ch); + } + } + macro_add_to_buff(&buff, &buffloc, &bufflen, 0); + nl -> line = strdup(buff); + + resolve_insn(as, nl); + cl = nl; + } + if (buff) + free(buff); +} diff -r 000000000000 -r 57495da01900 src/main.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/main.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,140 @@ +/* +main.c + +Implements the program startup code + +*/ + +#include +#include +#include +#include + +#include "lwasm.h" + +// external declarations +extern void resolve_phasing(asmstate_t *as); +extern void generate_code(asmstate_t *as); +extern void list_code(asmstate_t *as); +extern void write_code(asmstate_t *as); + + +// command line option handling +const char *argp_program_version = "LWASM Version 0.0"; +const char *argp_program_bug_address = "lost@l-w.ca"; + +static error_t parse_opts(int key, char *arg, struct argp_state *state) +{ + asmstate_t *as = state -> input; + + switch (key) + { + case 'o': + // output + if (as -> outfile) + { + } + as -> outfile = arg; + break; + + case 'd': + // debug + as -> debug++; + break; + + case 'l': + // list + if (arg) + as -> listfile = arg; + else + as -> listfile = "-"; + break; + + case 'b': + // decb output + as -> outformat = OUTPUT_DECB; + break; + + case 'r': + // raw binary output + as -> outformat = OUTPUT_RAW; + break; + + case ARGP_KEY_END: + // done; sanity check + if (!as -> outfile) + as -> outfile = "a.out"; + break; + + case ARGP_KEY_ARG: + // non-option arg + if (as -> infile) + argp_usage(state); + as -> infile = arg; + break; + + default: + return ARGP_ERR_UNKNOWN; + } + return 0; +} + +static struct argp_option options[] = +{ + { "output", 'o', "FILE", 0, + "Output to FILE"}, + { "debug", 'd', 0, 0, + "Set debug mode"}, + { "list", 'l', "FILE", OPTION_ARG_OPTIONAL, + "Generate list [to FILE]"}, + { "decb", 'b', 0, 0, + "Generate DECB .bin format output"}, + { "raw", 'r', 0, 0, + "Generate raw binary format output"}, + { "rawrel", 0, 0, 0, + "Generate raw binary respecing ORG statements as offsets from the start of the file"}, + { 0 } +}; + +static struct argp argp = +{ + options, + parse_opts, + "", + "LWASM, a HD6309 and MC6809 cross-assembler" +}; + +// main function; parse command line, set up assembler state, and run the +// assembler on the first file +int main(int argc, char **argv) +{ + // assembler state + asmstate_t asmstate = { 0 }; + + argp_parse(&argp, argc, argv, 0, 0, &asmstate); + if (!asmstate.listfile) + asmstate.listfile = "-"; + +// printf("Assembling %s to %s; list to %s\n", asmstate.infile, asmstate.outfile, asmstate.listfile); + + /* pass 1 - collect the symbols and assign addresses where possible */ + /* pass 1 also resolves included files, etc. */ + /* that means files are read exactly once unless included multiple times */ + lwasm_read_file(&asmstate, (char *)(asmstate.infile)); + + // pass 2: actually generate the code; if any phasing errors appear + // at this stage, we have a bug + generate_code(&asmstate); + + // now make a pretty listing + list_code(&asmstate); + + // now write the code out to the output file + write_code(&asmstate); + + if (asmstate.errorcount > 0) + exit(1); + + exit(0); +} + diff -r 000000000000 -r 57495da01900 src/output.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/output.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,164 @@ +/* + * output.c + * + * code for actually outputting the assembled code + */ + +//#include +#include +#include +//#include +#include +#include +#define __output_c_seen__ +//#include "instab.h" +#include "lwasm.h" + +void write_code_raw(asmstate_t *as, FILE *of); +void write_code_decb(asmstate_t *as, FILE *of); +void write_code_rawrel(asmstate_t *as, FILE *of); + +void write_code(asmstate_t *as) +{ + FILE *of; + + if (as -> errorcount > 0) + { + fprintf(stderr, "Not doing output due to assembly errors.\n"); + return; + } + + of = fopen(as -> outfile, "wb"); + if (!of) + { + fprintf(stderr, "Cannot open '%s' for output", as -> outfile); + perror(""); + return; + } + + switch (as -> outformat) + { + case OUTPUT_RAW: + write_code_raw(as, of); + break; + + case OUTPUT_DECB: + write_code_decb(as, of); + break; + + case OUTPUT_RAWREL: + write_code_rawrel(as, of); + break; + + default: + fprintf(stderr, "BUG: unrecognized output format when generating output file\n"); + fclose(of); + unlink(as -> outfile); + return; + } + + fclose(of); +} + +/* +rawrel output treats an ORG directive as an offset from the start of the +file. Undefined results will occur if an ORG directive moves the output +pointer backward. This particular implementation uses "fseek" to handle +ORG requests and to skip over RMBs. + +This simple brain damanged method simply does an fseek before outputting +each instruction. +*/ +void write_code_rawrel(asmstate_t *as, FILE *of) +{ + sourceline_t *cl; + + for (cl = as -> source_head; cl; cl = cl -> next) + { + if (cl -> nocode) + continue; + + fseek(of, cl -> addr, SEEK_SET); + fwrite(cl -> codebytes, cl -> numcodebytes, 1, of); + } +} + +/* +raw merely writes all the bytes directly to the file as is. ORG is just a +reference for the assembler to handle absolute references. Multiple ORG +statements will produce mostly useless results +*/ +void write_code_raw(asmstate_t *as, FILE *of) +{ + sourceline_t *cl; + + for (cl = as -> source_head; cl; cl = cl -> next) + { + if (cl -> nocode && cl -> len > 0) + { + int i; + for (i = 0; i < cl -> len; i++) + fwrite("\0", 1, 1, of); + continue; + } + if (cl -> nocode) + continue; + + fwrite(cl -> codebytes, cl -> numcodebytes, 1, of); + } +} + +void write_code_decb(asmstate_t *as, FILE *of) +{ + long preambloc; + sourceline_t *cl; + int blocklen = -1; + int nextcalc = -1; + unsigned char outbuf[5]; + + for (cl = as -> source_head; cl; cl = cl -> next) + { + if (cl -> nocode) + continue; + if (cl -> addr != nextcalc && cl -> numcodebytes > 0) + { + // need preamble here + if (blocklen > 0) + { + fseek(of, preambloc, SEEK_SET); + outbuf[0] = (blocklen >> 8) & 0xFF; + outbuf[1] = blocklen & 0xFF; + fwrite(outbuf, 2, 1, of); + fseek(of, 0, SEEK_END); + } + blocklen = 0; + nextcalc = cl -> addr; + outbuf[0] = 0x00; + outbuf[1] = 0x00; + outbuf[2] = 0x00; + outbuf[3] = (nextcalc >> 8) & 0xFF; + outbuf[4] = nextcalc & 0xFF; + preambloc = ftell(of) + 1; + fwrite(outbuf, 5, 1, of); + } + nextcalc += cl -> numcodebytes; + fwrite(cl -> codebytes, cl -> numcodebytes, 1, of); + blocklen += cl -> numcodebytes; + } + if (blocklen > 0) + { + fseek(of, preambloc, SEEK_SET); + outbuf[0] = (blocklen >> 8) & 0xFF; + outbuf[1] = blocklen & 0xFF; + fwrite(outbuf, 2, 1, of); + fseek(of, 0, SEEK_END); + } + + // now write postamble + outbuf[0] = 0xFF; + outbuf[1] = 0x00; + outbuf[2] = 0x00; + outbuf[3] = (as -> execaddr >> 8) & 0xFF; + outbuf[4] = (as -> execaddr) & 0xFF; + fwrite(outbuf, 5, 1, of); +} diff -r 000000000000 -r 57495da01900 src/pragma.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pragma.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,85 @@ +/* + * pragma.c + * + * stuff associated with lwasm specific strangeness + */ + +#include +#include +#include +#include "lwasm.h" + +/* +A pragma is a means of controlling code generation. + +The pseudo op "*pragma" which will be treated as a comment by an assembler +that doesn't recognize it and thus will not cause assembly errors. This is +the preferred way of flagging a pragma if it will not cause incorrect +execution of the program. + +The pseudo op "pragma" which will cause an error on an assembler that does +not understand it. + +In the case of "*pragma", unrecognized pragmas MUST be silently ignored. In +the case of "pragma", unrecognized pragmas should raise an error. + +LWASM understands the following pragmas: + +index0tonone +noindex0tonone + +When set (index0tonone), an expression that evaluates to 0, other than a +bare constant, in a ,r operand will cause the code for ",r" to be +emitted rather than "0,r". If not set (noindex0tonone), the "0,r" output +will be emitted. The default is to perform the optimization. + +This particular optimization will save a cycle for a direct operation. For +an indirect operation, however, it will save several cycles and a program byte +which may be very useful. +*/ + +void pseudo_pragma_real(asmstate_t *as, sourceline_t *cl, char **optr, int error) +{ + char pragma[128]; + int c = 0; + + while (isspace(**optr)) + (*optr)++; + + while (c < 127 && **optr && !isspace(**optr)) + { + pragma[c++] = **optr; + (*optr)++; + } + + if (c == 0 || (**optr && !isspace(**optr))) + { + if (error) + errorp1(ERR_PRAGMA); + return; + } + pragma[c] = 0; + if (!strcmp(pragma, "noindex0tonone")) + { + as -> pragmas |= PRAGMA_NOINDEX0TONONE; + } + else if (!strcmp(pragma, "index0tonone")) + { + as -> pragmas &= ~PRAGMA_NOINDEX0TONONE; + } + else + { + if (error) + errorp1(ERR_PRAGMA); + } +} + +void pseudo_pragma(asmstate_t *as, sourceline_t *cl, char **optr) +{ + pseudo_pragma_real(as, cl, optr, 1); +} + +void pseudo_starpragma(asmstate_t *as, sourceline_t *cl, char **optr) +{ + pseudo_pragma_real(as, cl, optr, 0); +} diff -r 000000000000 -r 57495da01900 src/pseudo.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pseudo.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,569 @@ +/* + * pseudo.c + * + * pseudo operations + */ + +#include +#include +#include +#include "lwasm.h" +#include "instab.h" + +#include + +void pseudo_org(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int v1, rval; + + if (cl -> hassym) + { + register_error(as, cl, ERR_SYM); + cl -> hassym = 0; + } + rval = eval_expr(as, cl, optr, &v1); + cl -> addr = v1; + cl -> addrset = 1; + as -> addr = v1; +} + +void pseudo_include(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int v1; + + if (as -> passnum != 1) + return; + while (**optr && isspace(**optr)) + (*optr)++; + if (!**optr) + { + register_error(as, cl, ERR_BADFN); + return; + } + for (v1 = 0; *((*optr)+v1) && !isspace(*((*optr)+v1)); v1++) + ; + { + char *fn = malloc(v1 + 1); + strncpy(fn, *optr, v1); + fn[v1] = '\0'; + lwasm_read_file(as, fn); + } +} + + +void pseudo_rmb(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_FORWARD); + return; + } + if (v1 < 0) + { + errorp1(ERR_BADOPER); + return; + } + cl -> len = v1; + cl -> nocode = 1; +} + +void pseudo_rmd(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_FORWARD); + return; + } + if (v1 < 0) + { + errorp1(ERR_BADOPER); + return; + } + cl -> len = v1 * 2; + cl -> nocode = 1; +} + +void pseudo_rmq(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_FORWARD); + return; + } + if (v1 < 0) + { + errorp1(ERR_BADOPER); + return; + } + cl -> len = v1 * 4; + cl -> nocode = 1; +} + +void pseudo_zmb(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_FORWARD); + return; + } + if (v1 < 0) + { + errorp1(ERR_BADOPER); + return; + } + while (v1--) + emit(0); +} + +void pseudo_zmd(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_FORWARD); + return; + } + if (v1 < 0) + { + errorp1(ERR_BADOPER); + return; + } + while (v1--) + { + emit(0); + emit(0); + } +} + +void pseudo_zmq(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_FORWARD); + return; + } + if (v1 < 0) + { + errorp1(ERR_BADOPER); + return; + } + while (v1--) + { + emit(0); + emit(0); + emit(0); + emit(0); + } +} + +void pseudo_end(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + + while (**optr && isspace(**optr)) + ; + if (**optr && **optr != '*' && **optr != ';') + { + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_FORWARD); + return; + } + } + else + { + v1 = 0; + } + if (as -> passnum == 2) + as -> execaddr = v1; +} + +void pseudo_align(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + int cn; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_FORWARD); + return; + } + cn = cl -> addr % v1; + if (cn) + cn = v1 - cn; + + while (cn) + { + emit(0); + cn--; + } +} + +void pseudo_equ(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + + if (cl -> hassym == 0) + { + errorp1(ERR_NOSYM); + return; + } + rval = eval_expr(as, cl, optr, &v1); + // eval_expr returns -1 if there was a forward ref + // or -2 if the expr was invalid + if (rval == -2) + { + // carp + errorp1(ERR_FORWARD); + } + if (rval < 0) + { + // remove symbol ref + cl -> hassym = 0; + // mark as a "comment" so it isn't processed next time + cl -> opcode = -1; + return; + } + cl -> code_symloc = v1; + cl -> isequ = 1; + cl -> symaddr = v1 & 0xFFFF; +} + +void pseudo_set(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + + if (cl -> hassym == 0) + { + errorp1(ERR_NOSYM); + return; + } + rval = eval_expr(as, cl, optr, &v1); + // eval_expr returns -1 if there was a forward ref + // or -2 if the expr was invalid + if (rval == -2) + { + // carp + errorp1(ERR_FORWARD); + } + if (rval < 0) + { + // remove symbol ref + cl -> hassym = 0; + // mark as a "comment" so it isn't processed next time + cl -> opcode = -1; + return; + } + cl -> code_symloc = v1; + cl -> isset = 1; + cl -> isequ = 1; + cl -> symaddr = v1 & 0xFFFF; +} + +void pseudo_setdp(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + + if (cl -> hassym) + { + register_error(as, cl, ERR_SYM); + cl -> hassym = 0; + return; + } + else + { + rval = eval_expr(as, cl, optr, &v1); + if (rval == -1) + { + errorp1(ERR_FORWARD); + } + if (rval < 0) + { + cl -> opcode = -1; + return; + } + } + // setdp needs to resolve properly on pass 2 + if (v1 > 0xff || v1 < 0) + { + errorp1(ERR_OVERFLOW); + } + as -> dpval = v1 & 0xff; + cl -> dpval = v1 & 0xff; + cl -> issetdp = 1; + cl -> numcodebytes = 0; +//printf("%s\n", "SETDP2"); +} + +void pseudo_fcc(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int cn = 0; + int delim = 0; + + delim = *(*optr)++; + if (!delim) + { + errorp1(ERR_BADOPER); + } + else + { + while (**optr && **optr != delim) + { + emit(**optr); + (*optr)++; + cn += 1; + } + } + cl -> len = cn; +} + +void pseudo_fcs(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int cn = 0; + int delim = 0; + + delim = *(*optr)++; + if (!delim) + { + errorp1(ERR_BADOPER); + } + else + { + while (**optr && **optr != delim) + { + if (!*((*optr) + 1) || *((*optr) + 1) == delim) + emit((**optr) | 0x80); + else + emit(**optr); + (*optr)++; + cn += 1; + } + } + cl -> len = cn; +} + +void pseudo_fcn(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int cn = 0; + int delim = 0; + + delim = *(*optr)++; + if (!delim) + { + errorp1(ERR_BADOPER); + } + else + { + while (**optr && **optr != delim) + { + emit(**optr); + (*optr)++; + cn += 1; + } + } + emit(0); + cl -> len = cn + 1; +} + +void pseudo_fcb(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + +fcb_again: + rval = eval_expr(as, cl, optr, &v1); + if (v1 < -127 || v1 > 0xff) + errorp2(ERR_OVERFLOW); + emit(v1 & 0xff); + if (**optr == ',') + { + (*optr)++; + goto fcb_again; + } +} + +void pseudo_fdb(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + +fdb_again: + rval = eval_expr(as, cl, optr, &v1); + emit((v1 >> 8) & 0xff); + emit(v1 & 0xff); + if (**optr == ',') + { + (*optr)++; + goto fdb_again; + } +} + +void pseudo_fqb(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int rval, v1; + +fqb_again: + rval = eval_expr(as, cl, optr, &v1); + emit((v1 >> 24) & 0xff); + emit((v1 >> 16) & 0xff); + emit((v1 >> 8) & 0xff); + emit(v1 & 0xff); + if (**optr == ',') + { + (*optr)++; + goto fqb_again; + } +} + +// don't need to do anything if we are executing one of these +void pseudo_endc(asmstate_t *as, sourceline_t *cl, char **optr) +{ + return; +} + +// if "else" executes, we must be going into an "ignore" state +void pseudo_else(asmstate_t *as, sourceline_t *cl, char **optr) +{ + as -> skipcond = 1; + as -> skipcount = 1; +} + +void pseudo_ifne(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int v1; + int rval; +// printf("ifne %s\n", *optr); + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_BADCOND); + } + else + { +// printf("Condition value: %d\n", v1); + if (!v1) + { +// printf("condition no match\n"); + as -> skipcond = 1; + as -> skipcount = 1; + } + } +} +void pseudo_ifeq(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int v1; + int rval; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_BADCOND); + } + else + { + if (v1) + { + as -> skipcond = 1; + as -> skipcount = 1; + } + } +} +void pseudo_iflt(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int v1; + int rval; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_BADCOND); + } + else + { + if (v1 >= 0) + { + as -> skipcond = 1; + as -> skipcount = 1; + } + } +} +void pseudo_ifle(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int v1; + int rval; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_BADCOND); + } + else + { + if (v1 > 0) + { + as -> skipcond = 1; + as -> skipcount = 1; + } + } +} +void pseudo_ifgt(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int v1; + int rval; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_BADCOND); + } + else + { + if (v1 <= 0) + { + as -> skipcond = 1; + as -> skipcount = 1; + } + } +} +void pseudo_ifge(asmstate_t *as, sourceline_t *cl, char **optr) +{ + int v1; + int rval; + + rval = eval_expr(as, cl, optr, &v1); + if (rval < 0) + { + errorp1(ERR_BADCOND); + } + else + { + if (v1 < 0) + { + as -> skipcond = 1; + as -> skipcount = 1; + } + } +} + +void pseudo_error(asmstate_t *as, sourceline_t *cl, char **optr) +{ + cl -> user_error = strdup(*optr); + errorp1(ERR_USER); +} diff -r 000000000000 -r 57495da01900 src/symtab.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/symtab.c Fri Oct 03 02:44:20 2008 +0000 @@ -0,0 +1,97 @@ +/* + * symtab.c + * + * main code for lwasm + */ + +#include +#include +#include +#include +#include +#define __symtab_c_seen__ +#include "lwasm.h" + +void register_symbol(asmstate_t *as, sourceline_t *cl, char *symstr, int val, int flags) +{ + symtab_t *st; + symtab_t *prev; + int cv = -2; + + for (prev = NULL, st = as -> symbol_table; st; st = st -> next) + { + cv = strcasecmp(st -> symbol, symstr); + if (cv == 0) + { + cv = strcmp(st -> symbol, symstr); + } + if (cv >= 0) + break; + prev = st; + } + // cv is 0 if we found the symbol, > 0 if we didn't and found one + // later in order, or -2 if we never did a comparison + // if st is NULL, the value of cv is irrelevant as it means + // we fell off the end of the list + // if st is NULL and prev is not, then prev is the tail of the list + // if both are NULL, the list is empty + + // handle adding the symbol if needed + if (!st || cv != 0) + { + symtab_t *st2; + // register the symbol + st2 = malloc(sizeof(symtab_t)); + st2 -> symbol = strdup(symstr); + st2 -> addr = val; + st2 -> flags = 0; + if (flags & SYMFLAG_SET) + st2 -> flags |= SYMFLAG_SET; + + if (prev) + prev -> next = st2; + else + as -> symbol_table = st2; + + st2 -> next = st; + return; + } + + // st is NOT NULL here and cv IS 0 + if ((flags & SYMFLAG_SET) && ((st -> flags) & SYMFLAG_SET)) + { + // symbol already exists but it is a "SET" symbol so reset the value + st -> addr = val; + return; + } + if (st && as -> passnum == 1) + { + // duplicate symbol, flag error + errorp1(ERR_DUPSYM); + } + if (st -> addr != val) + errorp2(ERR_PHASE); +} + +int lookup_symbol(asmstate_t *as, char *symstr) +{ + symtab_t *st; + + for (st = as -> symbol_table; st; st = st -> next) + { + if (!strcmp(symstr, st -> symbol)) + break; + } + if (st) + return st -> addr; + return -1; +} + +void list_symbols(asmstate_t *as, FILE *f) +{ + symtab_t *st; + for (st = as -> symbol_table; st; st = st -> next) + { + fprintf(f, "%04X %s%s\n", st -> addr, st -> symbol, (st -> flags & SYMFLAG_SET) ? "(S)" : ""); + } +}