summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--LICENSE339
-rw-r--r--Makefile3
-rw-r--r--asmmon.c932
-rw-r--r--opcode.h657
-rw-r--r--programs/forg.s17
-rw-r--r--programs/hex-to-bcd.s7
-rw-r--r--programs/subasm.s296
-rw-r--r--sux.c1230
-rw-r--r--test/asr.s6
-rw-r--r--test/fib2.s26
-rw-r--r--test/ind-addr.s27
-rw-r--r--test/input.s195
-rw-r--r--test/test-stack.s3
-rw-r--r--test/the-tests.s35
14 files changed, 2293 insertions, 1480 deletions
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..d159169
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,339 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) 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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. 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.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE 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.
+
+ 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
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ 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 2 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, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision 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, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This 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.
diff --git a/Makefile b/Makefile
index 7266284..de1d6b5 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,8 @@ endif
CFLAGS = $(PCC_CFLAGS) $(CFLAGS_EXTRA)
OBJS = asmmon.o sux.o
OBJ_NAME = cisc-0.2
-all : $(OBJS)
+all : clean $(OBJ_NAME)
+cisc-0.2: $(OBJS)
$(CC) $(OBJS) $(CFLAGS) -lpthread -lcurses -o $(OBJ_NAME)
sux.o :
$(CC) sux.c -c $(CFLAGS) -o sux.o
diff --git a/asmmon.c b/asmmon.c
index 7af4695..085d7ba 100644
--- a/asmmon.c
+++ b/asmmon.c
@@ -4,7 +4,6 @@
#define debug 1
-#define OPNUM 93
#define SETOP(num, _mne, _IMM, _ZM, _ZMX, _ZMY, _IND, _INX, _INY, _ABS, _IMPL) \
{opcodes[num].mnemonic[3] = '\0'; strncpy(opcodes[num].mnemonic, _mne, 3); \
opcodes[num].imm = _IMM; \
@@ -60,19 +59,6 @@ uint64_t use_label(const char *name, uint64_t adr) {
struct label *l = mklabel(name, 0, 0);
adr++;
if (l->def) {
- addr[adr] = l->adr & 0xFF;
- if (l->adr & 0xFF00)
- addr[adr+1] = l->adr >> 8;
- if (l->adr & 0xFF000000) {
- addr[adr+2] = l->adr >> 16;
- addr[adr+3] = l->adr >> 24;
- }
- if (l->adr & 0xFF00000000000000) {
- addr[adr+4] = l->adr >> 32;
- addr[adr+5] = l->adr >> 40;
- addr[adr+6] = l->adr >> 48;
- addr[adr+7] = l->adr >> 56;
- }
return l->adr;
} else {
printf("oof, label %s, does not exist, yet.\n", name);
@@ -124,102 +110,201 @@ void viewmem(uint64_t address) {
printf("\n");
}
}
+
+void usage() {
+ puts("SuBAsm for CISC-0.2");
+ puts("Commands:");
+ puts("\tviewmem, vm, v\t\tGet the contents of memory\n"
+ "\t\t\t\t(Displays 256 bytes of memory\n"
+ "\t\t\t\t starting from where the program counter\n"
+ "\t\t\t\t currently is).");
+ puts("\trelsv, rf, r\t\tResolve any currently unknown labels.");
+ puts("\tdisasm, dis,\n"
+ "\td [start-][end]\t\tDisassemble from starting address, to\n"
+ "\t\t\t\tending address.");
+ puts("\tinst, i [inst]\t\tGet a descriptions of that instruction.\n"
+ "\t\t\t\tIf no argument is specified, or the\n"
+ "\t\t\t\targument specified is \"all\", list all\n"
+ "\t\t\t\tinstructions, along with a description\n"
+ "\t\t\t\tfor each of them.");
+ puts("\tquit, q\t\t\tQuit the emulator.");
+ puts("\thelp, h\t\t\tDisplays this mesage.");
+}
+
+void instinfo(const char *inst) {
+ for(int i = 0; i < OPNUM; i++) {
+ if (!strcasecmp(inst, mne[i])) {
+ printf("%s\t%s\n", mne[i], instdesc[i]);
+ break;
+ } else if (!strcasecmp(inst, "all")) {
+ printf("%s\t%s\n", mne[i], instdesc[i]);
+ }
+ }
+}
+
+void disasm(uint8_t prefix, uint8_t opcode, uint64_t value) {
+ char postfix[3];
+ char op[4];
+ uint8_t addrsize = (prefix & 8) >> 3;
+ uint8_t rs = (prefix & 0x30) >> 4;
+ uint8_t regsize = (1 << rs);
+ op[0] = opname[opcode][0];
+ op[1] = opname[opcode][1];
+ op[2] = opname[opcode][2];
+ op[3] = '\0';
+ if (regsize == 1) {
+ postfix[0] = '\0';
+ postfix[1] = '\0';
+ postfix[2] = '\0';
+ } else {
+ postfix[0] = '.';
+ if (regsize == 2)
+ postfix[1] = 'W';
+ else if (regsize == 4)
+ postfix[1] = 'D';
+ else if (regsize == 8)
+ postfix[1] = 'Q';
+ else {
+ postfix[0] = '\0';
+ postfix[1] = '\0';
+ }
+ postfix[2] = '\0';
+ }
+ switch (optype[opcode]) {
+ case IMPL:
+ printf("%s\n" , opname[opcode]);
+ break;
+ case IMM:
+ if (regsize == 1)
+ printf("%s #$%02x\n" , op, value);
+ if (regsize == 2)
+ printf("%s%s #$%04x\n" , op, postfix, value);
+ if (regsize == 4)
+ printf("%s%s #$%08x\n" , op, postfix, value);
+ if (regsize == 8)
+ printf("%s%s #$%016llx\n" , op, postfix, value);
+ break;
+ case ZM:
+ case ZMX:
+ case ZMY:
+ if (addrsize)
+ printf("%s%s $%08x%s\n" , op, postfix, value, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y"));
+ else
+ printf("%s%s $%02x%s\n" , op, postfix, value, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y"));
+ break;
+ case IND:
+ case INDX:
+ case INDY:
+ if (addrsize)
+ printf("%s%s ($%08x%s\n" , op, postfix, value, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y"));
+ else
+ printf("%s%s ($%02x%s\n" , op, postfix, value, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y"));
+ break;
+ case ABS:
+ if (addrsize)
+ printf("%s%s $%016llx\n" , op, postfix, value);
+ else
+ printf("%s%s $%04x\n" , op, postfix, value);
+ break;
+
+ }
+}
+
int asmmon(const char *fn) {
- opent opcodes[OPNUM];
/* mne IMM ZM ZMX ZMY IND INX INY ABS IMPL*/
SETOP( 0, "CPS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
SETOP( 1, "ADC", 0x01, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00);
SETOP( 2, "AAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02);
- SETOP( 3, "PHB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06);
- SETOP( 4, "PHP", 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP( 5, "PHA", 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP( 6, "PHY", 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP( 7, "TAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0B);
- SETOP( 8, "PHX", 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP( 9, "TAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D);
- SETOP(10, "TYX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0E);
- SETOP(11, "JMP", 0x00, 0xD0, 0x00, 0x00, 0x04, 0x14, 0x24, 0x10, 0x00);
- SETOP(12, "SBC", 0x11, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00);
- SETOP(13, "SAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12);
- SETOP(14, "PLB", 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(15, "PLP", 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(16, "PLA", 0x19, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(17, "PLY", 0x1A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(18, "TYA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B);
- SETOP(19, "PLX", 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(20, "TXA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1D);
- SETOP(21, "TXY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1E);
- SETOP(22, "JSR", 0x00, 0x20, 0x00, 0x00, 0x34, 0x44, 0x54, 0x00, 0x00);
- SETOP(23, "AND", 0x21, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00);
- SETOP(24, "ABA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22);
- SETOP(25, "STT", 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(26, "TAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x26);
- SETOP(27, "TSX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2E);
- SETOP(28, "BPO", 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00);
- SETOP(29, "ORA", 0x31, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00);
- SETOP(30, "OAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32);
- SETOP(31, "TBA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36);
- SETOP(32, "SEI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38);
- SETOP(33, "TXS", 0x3E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
- SETOP(34, "BNG", 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00);
- SETOP(35, "XOR", 0x41, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00);
- SETOP(36, "XAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42);
- SETOP(37, "CLI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48);
- SETOP(38, "BCS", 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00);
- SETOP(39, "LSL", 0x51, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00);
- SETOP(40, "LLB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52);
- SETOP(41, "STB", 0x00, 0x7F, 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0x5F, 0x00);
- SETOP(42, "SEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58);
- SETOP(43, "STA", 0x00, 0x7B, 0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0x5B, 0x00);
- SETOP(44, "STY", 0x00, 0x7D, 0x8D, 0x00, 0xAD, 0xBD, 0x00, 0x5D, 0x00);
- SETOP(45, "STX", 0x00, 0x7E, 0x00, 0x9E, 0xAE, 0x00, 0xCE, 0x5E, 0x00);
- SETOP(46, "BCC", 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00);
- SETOP(47, "LSR", 0x61, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00);
- SETOP(48, "LRB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62);
- SETOP(49, "LDB", 0x66, 0x76, 0x86, 0x96, 0xA6, 0xB6, 0xC6, 0x56, 0x00);
- SETOP(50, "CLC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68);
- SETOP(51, "LDA", 0x69, 0x79, 0x89, 0x99, 0xA9, 0xB9, 0xC9, 0x59, 0x00);
- SETOP(52, "LDY", 0x6A, 0x7A, 0x8A, 0x00, 0xAA, 0xBA, 0x00, 0x5A, 0x00);
- SETOP(53, "LDX", 0x6C, 0x7C, 0x00, 0x9C, 0xAC, 0x00, 0xCC, 0x5C, 0x00);
- SETOP(54, "BEQ", 0x00, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00);
- SETOP(55, "ROL", 0x71, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00);
- SETOP(56, "RLB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72);
- SETOP(57, "SSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78);
- SETOP(58, "BNE", 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00);
- SETOP(59, "ROR", 0x81, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00);
- SETOP(60, "RRB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82);
- SETOP(61, "CSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88);
- SETOP(62, "BVS", 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00);
- SETOP(63, "MUL", 0x91, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x00);
- SETOP(64, "MAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92);
- SETOP(65, "SEV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98);
- SETOP(66, "BVC", 0x00, 0x2F, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00);
- SETOP(67, "DIV", 0xA1, 0xA5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00);
- SETOP(68, "DAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2);
- SETOP(69, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8);
- SETOP(70, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0);
- SETOP(71, "CMP", 0xB1, 0xB5, 0x00, 0x00, 0xE9, 0xEB, 0xED, 0xB3, 0x00);
- SETOP(72, "CAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2);
- SETOP(73, "CPY", 0x2A, 0x3B, 0x00, 0x00, 0xEA, 0xFA, 0x00, 0x2B, 0x00);
- SETOP(74, "CPX", 0xBC, 0x3D, 0x00, 0x00, 0xEC, 0x00, 0xFC, 0x2D, 0x00);
- SETOP(75, "CPB", 0xD6, 0xF6, 0x00, 0x00, 0xDF, 0xEF, 0xFF, 0xE6, 0x00);
- SETOP(76, "ENT", 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP( 3, "JMP", 0x00, 0xD0, 0x00, 0x00, 0x04, 0x14, 0x24, 0x10, 0x00);
+ SETOP( 4, "PHB", 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP( 5, "PHP", 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP( 6, "LDA", 0x09, 0x39, 0x59, 0x79, 0x99, 0xB9, 0xD9, 0x19, 0x00);
+ SETOP( 7, "LDY", 0x0A, 0x3A, 0x5A, 0x00, 0x7A, 0x9A, 0x00, 0x1A, 0x00);
+ SETOP( 8, "LDX", 0x0B, 0x3B, 0x00, 0x5B, 0x7B, 0x00, 0x9B, 0x1B, 0x00);
+ SETOP( 9, "TAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C);
+ SETOP(10, "LDB", 0x0E, 0x3E, 0x5E, 0x7E, 0x9E, 0xBE, 0xDE, 0x1E, 0x00);
+ SETOP(11, "SBC", 0x11, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00);
+ SETOP(12, "SAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12);
+ SETOP(13, "PLB", 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(14, "PLP", 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(15, "TBA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1C);
+ SETOP(16, "JSR", 0x00, 0x20, 0x00, 0x00, 0x34, 0x44, 0x54, 0x00, 0x00);
+ SETOP(17, "AND", 0x21, 0x25, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00);
+ SETOP(18, "ABA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22);
+ SETOP(19, "CPB", 0x26, 0x46, 0x00, 0x00, 0x56, 0x66, 0x76, 0x36, 0x00);
+ SETOP(20, "STT", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28);
+ SETOP(21, "STA", 0x00, 0x49, 0x69, 0x89, 0xA9, 0xC9, 0xE9, 0x29, 0x00);
+ SETOP(22, "STY", 0x00, 0x4A, 0x6A, 0x00, 0x8A, 0xAA, 0x00, 0x2A, 0x00);
+ SETOP(23, "STX", 0x00, 0x4B, 0x00, 0x6B, 0x8B, 0x00, 0xAB, 0x2B, 0x00);
+ SETOP(24, "TAY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2C);
+ SETOP(25, "STB", 0x00, 0x4E, 0x6E, 0x8E, 0xAE, 0xCE, 0xEE, 0x2E, 0x00);
+ SETOP(26, "BPO", 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00);
+ SETOP(27, "ORA", 0x31, 0x35, 0x00, 0x00, 0x00, 0x00, 0x00, 0x33, 0x00);
+ SETOP(28, "OAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32);
+ SETOP(29, "SEI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38);
+ SETOP(30, "TYA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C);
+ SETOP(31, "BNG", 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00);
+ SETOP(32, "XOR", 0x41, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00);
+ SETOP(33, "XAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42);
+ SETOP(34, "CLI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48);
+ SETOP(35, "TAX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C);
+ SETOP(36, "BCS", 0x00, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x00);
+ SETOP(37, "LSL", 0x51, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x53, 0x00);
+ SETOP(38, "LLB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x52);
+ SETOP(39, "SEC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58);
+ SETOP(40, "TXA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C);
+ SETOP(41, "BCC", 0x00, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x00);
+ SETOP(42, "LSR", 0x61, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x00);
+ SETOP(43, "LRB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62);
+ SETOP(44, "CLC", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68);
+ SETOP(45, "TYX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C);
+ SETOP(46, "BEQ", 0x00, 0xA4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x00);
+ SETOP(47, "ROL", 0x71, 0x75, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x00);
+ SETOP(48, "RLB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72);
+ SETOP(49, "SSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78);
+ SETOP(50, "TXY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C);
+ SETOP(51, "BNE", 0x00, 0xB4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00);
+ SETOP(52, "ROR", 0x81, 0x85, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x00);
+ SETOP(53, "RRB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82);
+ SETOP(54, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86);
+ SETOP(55, "CSP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88);
+ SETOP(56, "TSX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C);
+ SETOP(57, "BVS", 0x00, 0xC4, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0x00);
+ SETOP(58, "MUL", 0x91, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x00);
+ SETOP(59, "MAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92);
+ SETOP(60, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x96);
+ SETOP(61, "SEV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98);
+ SETOP(62, "TXS", 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(63, "BVC", 0x00, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x00);
+ SETOP(64, "DIV", 0xA1, 0xA5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x00);
+ SETOP(65, "DAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2);
+ SETOP(66, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6);
+ SETOP(67, "CLV", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA8);
+ SETOP(68, "PHY", 0xAC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(69, "RTS", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB0);
+ SETOP(70, "CMP", 0xB1, 0xB5, 0x00, 0x00, 0xF1, 0xF3, 0xF5, 0xB3, 0x00);
+ SETOP(71, "CAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2);
+ SETOP(72, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB6);
+ SETOP(73, "ENT", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB8);
+ SETOP(74, "CPY", 0xBA, 0xDA, 0x00, 0x00, 0xEA, 0xFA, 0x00, 0xCA, 0x00);
+ SETOP(75, "CPX", 0xBB, 0xDB, 0x00, 0x00, 0xEB, 0x00, 0xFB, 0xCB, 0x00);
+ SETOP(76, "PLY", 0xBC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
SETOP(77, "RTI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0);
SETOP(78, "INC", 0x00, 0xC5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0xC1);
SETOP(79, "IAB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC2);
- SETOP(80, "INY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A);
- SETOP(81, "INX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C);
+ SETOP(80, "WAI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC8);
+ SETOP(81, "PHX", 0xCC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
SETOP(82, "DEC", 0x00, 0xD5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD3, 0xD1);
SETOP(83, "DBA", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD2);
- SETOP(84, "DEY", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4A);
- SETOP(85, "DEX", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4C);
- SETOP(86, "WAI", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8);
- SETOP(87, "JSL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00);
- SETOP(88, "ASR", 0xE1, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x00);
- SETOP(89, "ARB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2);
- SETOP(90, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8);
- SETOP(91, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0);
- SETOP(92, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8);
+ SETOP(84, "PLX", 0xDC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(85, "JSL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0x00);
+ SETOP(86, "ASR", 0xE1, 0xE5, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE3, 0x00);
+ SETOP(87, "ARB", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE2);
+ SETOP(88, "NOP", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE8);
+ SETOP(89, "PHA", 0xEC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
+ SETOP(90, "RTL", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0);
+ SETOP(91, "BRK", 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8);
+ SETOP(92, "PLA", 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
FILE *fp;
if (strcasecmp(fn, "stdin") != 0) {
fp = fopen(fn, "r");
@@ -228,21 +313,25 @@ int asmmon(const char *fn) {
}
uint8_t done = 0;
uint64_t address = 0x0000;
+ uint64_t start, end;
+ uint8_t prefix, opcode;
while (!(done & 1)) {
char *buf = NULL;
char *ins;
char *postfix;
char mode[3];
opent op;
- uint8_t addrmode = 0;
+ uint8_t addrmode = IMPL;
uint64_t value = 0;
char *oprand;
char *cmd;
char ir[2] = ""; /* Index register. */
int a = 0;
+ int b = 0;
char *tmp = malloc(sizeof(char *)*128);
size_t size;
- done &= ~0x1F;
+ prefix = 0;
+ done = 0;
if (!strcasecmp(fn, "stdin")) {
getline(&buf, &size, stdin);
} else {
@@ -260,7 +349,7 @@ int asmmon(const char *fn) {
if (oprand != NULL) {
for (int i = 0; i < strlen(oprand); i++) {
if (oprand[i] == '(')
- addrmode = 6;
+ addrmode = IND;
if (oprand[i] == '"')
break;
if (a && oprand[a] == ',') {
@@ -272,7 +361,13 @@ int asmmon(const char *fn) {
ir[0] = 'y';
ir[1] = '\0';
}
+ if (b && ir[0] == 'y')
+ oprand[b] = '\0';
}
+ if (oprand[i] == ')' && oprand[i+1] == ',')
+ b = i;
+ else if (oprand[i] == ')')
+ oprand[i] = '\0';
if (oprand[i] == ',' || oprand[i] == ';')
a = i;
}
@@ -287,173 +382,327 @@ int asmmon(const char *fn) {
done |= 4;
viewmem(address);
}
+ if (!strcasecmp(cmd, "reslv") || !strcasecmp(cmd, "rf") || !strcasecmp(cmd, "r")) {
+ done |= 4;
+ puts("Resolving unknown labels.");
+ reslv_fixups();
+ puts("Finished resolving unknown labels.");
+ }
+ if (!strcasecmp(cmd, "help") || !strcasecmp(cmd, "h")) {
+ done |= 4;
+ usage();
+ }
if (oprand == NULL && ins == NULL && postfix == NULL) {
done |= 2;
}
- if (ins != NULL) {
- for (int i = 0; i < strlen(ins); i++) {
- if (i && ins[i] == ':') {
- ins[i] = '\0';
- mklabel(ins, address, 1);
- #if debug
- printf("Created label with the name %s, at address: $%llx\n", ins, address);
- #endif
- done |= 6;
- break;
- }
- if (ins[i] == ';') {
- if (i && (ins[i-1] == ' ' || ins[i-1] == '\t'))
- ins[i] = '\0';
- else
- done |=6;
- break;
- }
- }
- if (strcasecmp(ins, ".org") == 0) {
- done |= 6;
- oprand = strtok(oprand, "$");
- address = strtoull(oprand, NULL, 16);
- #if debug
- printf("Origin for program code is now at address $%llx.\n", address);
- #endif
+ cmd = strtok(cmd, " \n");
+ if (!strcasecmp(cmd, "inst") || !strcasecmp(cmd, "i")) {
+ done |= 64;
+ done |= 6;
+ if (oprand != NULL) {
+ instinfo(oprand);
+ } else {
+ instinfo("all");
}
- if (strcasecmp(ins, ".byte") == 0 || strcasecmp(ins, ".word") == 0 || strcasecmp(ins, ".dword") == 0 || strcasecmp(ins, ".qword") == 0) {
- done |= 6;
- uint8_t qstr = 0;
- uint64_t staddr = address;
- uint16_t slen = 0;
- char *tmpstr = tstr;
- char c;
- for (int i = 0; i < strlen(oprand); i++) {
- if (!qstr) {
- if ((isalnum(oprand[i]) || oprand[i] == '_') && oprand[i] != '"') {
- qstr = 0;
- value = use_label(oprand, address);
- sprintf(oprand, "%llx", value);
+
+ }
+ if (!strcasecmp(cmd, "disasm") || !strcasecmp(cmd, "dis") || !strcasecmp(cmd, "d")) {
+ done |= 64;
+ done |= 6;
+ if (oprand != NULL) {
+ cmd = strtok_r(oprand, " -", &tmp);
+ if (cmd != NULL) {
+ for (int i = 0; i < strlen(cmd); i++) {
+ if ((isalnum(cmd[i]) || cmd[i] == '_') && cmd[i] != '"') {
+ value = use_label(tmp, address);
+ sprintf(tmp, "%llx", value);
break;
}
- if (oprand[i] == '"' && !strcasecmp(ins, ".byte")) {
- qstr = 1;
- continue;
+ if (cmd[i] == '$') {
+ cmd = strtok(cmd, "$");
+ value = strtoull(cmd, NULL, 16);
+ break;
}
- if (oprand[i] == '$') {
- qstr = 0;
- oprand = strtok(oprand, "$");
- value = strtoull(oprand, NULL, 16);
+ if (cmd[i] == ';') {
+ done |= 16;
+ break;
+ }
+ }
+ start = value;
+ for (int i = 0; i < strlen(tmp); i++) {
+ if ((isalnum(tmp[i]) || tmp[i] == '_') && tmp[i] != '"') {
+ value = use_label(tmp, address);
+ sprintf(tmp, "%llx", value);
+ break;
+ }
+ if (tmp[i] == '$') {
+ tmp = strtok(tmp, "$");
+ value = strtoull(tmp, NULL, 16);
break;
}
- if (oprand[i] == ';') {
- qstr = 0;
+ if (tmp[i] == ';') {
done |= 16;
break;
}
- } else if (qstr == 1) {
- switch (oprand[i]) {
- case 0:
- puts("oof, unterminated string.");
- qstr = 2;
- break;
- case '"':
- value = '\0';
- c = '\0';
- tmpstr[slen++] = '\0';
- qstr = 3;
- break;
- case '\\':
- switch (oprand[i+1]) {
- case 'n':
- value = '\n';
- c = '\n';
- tmpstr[slen++] = '\\';
- tmpstr[slen++] = 'n';
- break;
- case 't':
- value = '\t';
- c = '\t';
- tmpstr[slen++] = '\\';
- tmpstr[slen++] = 't';
- break;
- case 'r':
- value = '\r';
- c = '\r';
- tmpstr[slen++] = '\\';
- tmpstr[slen++] = 'r';
+ }
+ (!strlen(tmp)) ? (end = address) : (end = value);
+ } else {
+ start = value;
+ end = address;
+ }
+ } else {
+ start = 0;
+ end = address;
+ }
+ while (start < end) {
+ uint8_t rs;
+ uint8_t regsize;
+ uint8_t addrsize;
+ if (start < 0xFF)
+ printf("$%02llx: ", start);
+ else if (start < 0xFFFF)
+ printf("$%04llx: ", start);
+ else if (start < 0xFFFFFFFF)
+ printf("$%08llx: ", start);
+ else if (start < 0xFFFFFFFFFFFFFFFF)
+ printf("$%016llx: ", start);
+ prefix = addr[start];
+ if ((prefix & 0x07) == 0x07) {
+ start+=1;
+ addrsize = (prefix & 8) >> 3;
+ rs = (prefix & 0x30) >> 4;
+ regsize = (1 << rs);
+ } else {
+ prefix = 0;
+ regsize = 1;
+ addrsize = 0;
+ }
+ opcode = addr[start];
+ start+=1;
+ switch (optype[opcode]) {
+ case IMPL:
+ break;
+ case IMM:
+ value = addr[start];
+ if (regsize >= 2)
+ value |= addr[start+1] << 8;
+ if (regsize >= 4) {
+ value |= addr[start+2] << 16;
+ value |= addr[start+3] << 24;
+ }
+ if (regsize >= 8) {
+ value |= (uint64_t)addr[start+4] << 32;
+ value |= (uint64_t)addr[start+5] << 40;
+ value |= (uint64_t)addr[start+6] << 48;
+ value |= (uint64_t)addr[start+7] << 56;
+ }
+ start += regsize;
+ break;
+ case ZM:
+ case ZMX:
+ case ZMY:
+ case IND:
+ case INDX:
+ case INDY:
+ value = addr[start];
+ if (addrsize) {
+ value |= addr[start+1] << 8;
+ value |= addr[start+2] << 16;
+ value |= addr[start+3] << 24;
+ start+=4;
+ } else {
+ start+=1;
+ }
+ break;
+ case ABS:
+ value = addr[start];
+ value |= addr[start+1] << 8;
+ if (addrsize) {
+ value |= (uint64_t)addr[start+2] << 16;
+ value |= (uint64_t)addr[start+3] << 24;
+ value |= (uint64_t)addr[start+4] << 32;
+ value |= (uint64_t)addr[start+5] << 40;
+ value |= (uint64_t)addr[start+6] << 48;
+ value |= (uint64_t)addr[start+7] << 56;
+ start+=8;
+ } else {
+ start+=2;
+ }
+ break;
+ }
+ disasm(prefix, opcode, value);
+ }
+ }
+ if (!(done & 64)) {
+ if (ins != NULL) {
+ for (int i = 0; i < strlen(ins); i++) {
+ if (i && ins[i] == ':') {
+ ins[i] = '\0';
+ mklabel(ins, address, 1);
+ #if debug
+ printf("Created label with the name %s, at address: $%llx\n", ins, address);
+ #endif
+ done |= 6;
+ break;
+ }
+ if (ins[i] == ';') {
+ if (i && (ins[i-1] == ' ' || ins[i-1] == '\t'))
+ ins[i] = '\0';
+ else
+ done |=6;
+ break;
+ }
+ }
+ if (!(done & 6)) {
+ if (oprand != NULL) {
+ if (!strcasecmp(ins, ".org")) {
+ done |= 6;
+ oprand = strtok(oprand, "$");
+ address = strtoull(oprand, NULL, 16);
+ #if debug
+ printf("Origin for program code is now at address $%llx.\n", address);
+ #endif
+ }
+ if (!strcasecmp(ins, ".byte") || !strcasecmp(ins, ".word") || !strcasecmp(ins, ".dword") || !strcasecmp(ins, ".qword")) {
+ done |= 6;
+ uint8_t qstr = 0;
+ uint64_t staddr = address;
+ uint16_t slen = 0;
+ char *tmpstr = tstr;
+ char c;
+ for (int i = 0; i < strlen(oprand); i++) {
+ if (!qstr) {
+ if ((isalnum(oprand[i]) || oprand[i] == '_') && oprand[i] != '"') {
+ qstr = 0;
+ value = use_label(oprand, address);
+ sprintf(oprand, "%llx", value);
break;
- case '0':
+ }
+ if (oprand[i] == '"' && !strcasecmp(ins, ".byte")) {
+ qstr = 1;
+ continue;
+ }
+ if (oprand[i] == '$') {
+ qstr = 0;
+ oprand = strtok(oprand, "$");
+ value = strtoull(oprand, NULL, 16);
break;
- default:
- value = oprand[i];
- tmpstr[slen++] = '\\';
- tmpstr[slen++] = oprand[i];
+ }
+ if (oprand[i] == ';') {
+ qstr = 0;
+ done |= 16;
break;
+ }
+ } else if (qstr == 1) {
+ switch (oprand[i]) {
+ case 0:
+ puts("oof, unterminated string.");
+ qstr = 2;
+ break;
+ case '"':
+ value = '\0';
+ c = '\0';
+ tmpstr[slen++] = '\0';
+ qstr = 3;
+ break;
+ case '\\':
+ switch (oprand[i+1]) {
+ case 'n':
+ value = '\n';
+ c = '\n';
+ tmpstr[slen++] = '\\';
+ tmpstr[slen++] = 'n';
+ break;
+ case 't':
+ value = '\t';
+ c = '\t';
+ tmpstr[slen++] = '\\';
+ tmpstr[slen++] = 't';
+ break;
+ case 'r':
+ value = '\r';
+ c = '\r';
+ tmpstr[slen++] = '\\';
+ tmpstr[slen++] = 'r';
+ break;
+ case '0':
+ break;
+ default:
+ value = oprand[i];
+ tmpstr[slen++] = '\\';
+ tmpstr[slen++] = oprand[i];
+ break;
+ }
+ i++;
+ break;
+ default:
+ value = oprand[i];
+ c = oprand[i];
+ tmpstr[slen++] = c;
+ break;
+ }
+ addr[address++] = (uint8_t)value & 0xFF;
}
- i++;
- break;
- default:
- value = oprand[i];
- c = oprand[i];
- tmpstr[slen++] = c;
- break;
+ }
+ if (!strcasecmp(ins, ".byte") && !qstr)
+ addr[address++] = value & 0xFF;
+ if (!strcasecmp(ins, ".word")) {
+ addr[address] = (uint8_t)value & 0xFF;
+ addr[address+1] = value >> 8;
+ address+=2;
+ }
+ if (!strcasecmp(ins, ".dword")) {
+ addr[address] = (uint8_t)value & 0xFF;
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ address+=4;
+ }
+ if (!strcasecmp(ins, ".qword")) {
+ addr[address] = (uint8_t)value & 0xFF;
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ addr[address+4] = value >> 32;
+ addr[address+5] = value >> 40;
+ addr[address+6] = value >> 48;
+ addr[address+7] = value >> 56;
+ address+=8;
+ }
+ #if debug
+ if (!qstr) {
+ printf("The value $%llx was placed at address%s ", value, (staddr != address-1) ? "es" : "");
+ if (staddr == address-1)
+ printf("$%llx.\n", staddr);
+ else
+ printf("$%llx-$%llx.\n", staddr, address-1);
+ } else {
+ printf("The string \"%s\", was placed at address%s ", tmpstr, (staddr != address-1) ? "es" : "");
+ if (staddr == address-1)
+ printf("$%llx.\n", staddr);
+ else
+ printf("$%llx-$%llx.\n", staddr, address-1);
+ }
+ #endif
}
- addr[address++] = value & 0xFF;
}
}
- if (strcasecmp(ins, ".byte") == 0 && !qstr)
- addr[address++] = value & 0xFF;
- if (strcasecmp(ins, ".word") == 0) {
- addr[address] = value & 0xFF;
- addr[address+1] = value >> 8;
- address+=2;
- }
- if (strcasecmp(ins, ".dword") == 0) {
- addr[address] = value & 0xFF;
- addr[address+1] = value >> 8;
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- address+=4;
- }
- if (strcasecmp(ins, ".qword") == 0) {
- addr[address] = value & 0xFF;
- addr[address+1] = value >> 8;
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- addr[address+4] = value >> 32;
- addr[address+5] = value >> 40;
- addr[address+6] = value >> 48;
- addr[address+7] = value >> 56;
- address+=8;
- }
- #if debug
- if (!qstr) {
- printf("The value $%llx was placed at address%s ", value, (staddr != address-1) ? "es" : "");
- if (staddr == address-1)
- printf("$%llx.\n", staddr);
- else
- printf("$%llx-$%llx.\n", staddr, address-1);
- } else {
- printf("The string \"%s\", was placed at address%s ", tmpstr, (staddr != address-1) ? "es" : "");
- if (staddr == address-1)
- printf("$%llx.\n", staddr);
- else
- printf("$%llx-$%llx.\n", staddr, address-1);
- }
- #endif
}
}
if (oprand == NULL && !strcasecmp(ins, "TXS")) {
- addrmode = 1;
+ addrmode = IMM;
done |= 32;
}
else if (oprand != NULL && !strcasecmp(ins, "TXS"))
- addr[address++] = 0x17;
+ prefix = 0x17;
if (!(done & 2) && oprand != NULL) {
mode[0] = oprand[0];
mode[1] = oprand[1];
- if (oprand[0] == '#' || oprand[0] == '$' || oprand[0] == '(') {
+ if (oprand[0] == '#' || oprand[0] == '$' || (oprand[0] == '(' && (oprand[1] == '$' || oprand[1] == '%'))) {
oprand = strtok(oprand, "#($%");
if (mode[0] == '#') {
- addrmode = 1;
+ addrmode = IMM;
done |= 32;
if (mode[1] == '$')
value = strtoull(oprand, NULL, 16);
@@ -468,26 +717,33 @@ int asmmon(const char *fn) {
value = strtoull(oprand, NULL, 2);
else
value = strtoull(oprand, NULL, 10);
+ if (value & 0xFFFFFF00 && (ir[0] == 'x' || ir[0] == 'y'))
+ prefix |= 0xF;
if (mode[0] != '(') {
- if (value & 0xFFFFFFFF || !value) {
- addrmode = 2;
- } else if (value & 0xFFFFFFFF00000000) {
- addrmode = 5;
+ if (value & 0xFFFF0000 || (value <= 0xFF) ||
+ (value & 0xFF00 && address <= 0xFFFF && (ir[0] == 'x' || ir[0] == 'y'))) {
+ addrmode = ZM;
+ if (value & 0xFFFFFF00)
+ prefix |= 0xF;
+ } else if (value & 0xFFFFFFFF00000000 || (value & 0xFF00 && address <= 0xFFFF)) {
+ addrmode = ABS;
+ if (value & 0xFFFFFFFF00000000)
+ prefix |= 0xF;
}
}
if ((addrmode == 2 || addrmode == 6) && ir != NULL) {
switch (ir[0]) {
case 'x':
- if (addrmode == 2)
- addrmode = 3;
- else if (addrmode == 6)
- addrmode = 7;
+ if (addrmode == ZM)
+ addrmode = ZMX;
+ else if (addrmode == IND)
+ addrmode = INDX;
break;
case 'y':
- if (addrmode == 2)
- addrmode = 4;
- else if (addrmode == 6)
- addrmode = 8;
+ if (addrmode == ZM)
+ addrmode = ZMY;
+ else if (addrmode == IND)
+ addrmode = INDY;
break;
default:
done |= 32;
@@ -496,6 +752,8 @@ int asmmon(const char *fn) {
}
}
} else {
+ if (mode[0] == '(')
+ oprand = strtok(oprand, "#($%");
for (int i = 0; i < strlen(oprand); i++) {
if (oprand[i] == ';') {
done |= 16;
@@ -503,26 +761,33 @@ int asmmon(const char *fn) {
}
if ((isalnum(oprand[i]) || oprand[i] == '_') && oprand[i] != '"') {
value = use_label(oprand, address);
+ if (value & 0xFFFFFF00 && (ir[0] == 'x' || ir[0] == 'y'))
+ prefix |= 0xF;
if (mode[0] != '(') {
- if (value & 0xFFFFFFFF || !value) {
- addrmode = 2;
- } else if (value & 0xFFFFFFFF00000000) {
- addrmode = 5;
+ if (value & 0xFFFF0000 || (value <= 0xFF) ||
+ (value <= 0xFFFF && address <= 0xFFFF && (ir[0] == 'x' || ir[0] == 'y'))) {
+ addrmode = ZM;
+ if (value & 0xFFFFFF00)
+ prefix |= 0xF;
+ } else if (value & 0xFFFFFFFF00000000 || (value & 0xFF00 && address <= 0xFFFF)) {
+ addrmode = ABS;
+ if (value & 0xFFFFFFFF00000000)
+ prefix |= 0xF;
}
}
- if ((addrmode == 2 || addrmode == 6) && ir != NULL && a) {
+ if ((addrmode == ZM || addrmode == IND) && ir != NULL && a) {
switch (ir[0]) {
case 'x':
- if (addrmode == 2)
- addrmode = 3;
- else if (addrmode == 6)
- addrmode = 7;
+ if (addrmode == ZM)
+ addrmode = ZMX;
+ else if (addrmode == IND)
+ addrmode = INDX;
break;
case 'y':
- if (addrmode == 2)
- addrmode = 4;
- else if (addrmode == 6)
- addrmode = 8;
+ if (addrmode == ZM)
+ addrmode = ZMY;
+ else if (addrmode == IND)
+ addrmode = INDY;
break;
default:
done |= 32;
@@ -539,14 +804,16 @@ int asmmon(const char *fn) {
uint8_t i;
for (i = 0; i < OPNUM; i++) {
if (strcasecmp(opcodes[i].mnemonic, ins) == 0) {
- if (addrmode == 0 && (opcodes[i].impl || opcodes[i].impl == CPS)) {
+ if (addrmode == IMPL && (opcodes[i].impl || opcodes[i].impl == CPS)) {
done |= 8;
- } else if (addrmode == 1) {
+ } else if (addrmode == IMM) {
switch (opcodes[i].imm) {
+ case PHB:
case PHP:
case PHA:
case PHY:
case PHX:
+ case PLB:
case PLP:
case PLA:
case PLY:
@@ -594,24 +861,27 @@ int asmmon(const char *fn) {
}
if (postfix != NULL && !(done & 8)) {
if (!strcasecmp(postfix, "w") || !strcasecmp(postfix, "2")) {
- addr[address++] = 0x17;
+ prefix |= 0x17;
} else if (!strcasecmp(postfix, "d") || !strcasecmp(postfix, "4")) {
- addr[address++] = 0x27;
+ prefix |= 0x27;
} else if (!strcasecmp(postfix, "q") || !strcasecmp(postfix, "8")) {
- addr[address++] = 0x37;
- } else {
+ prefix |= 0x37;
+ } else if (!prefix) {
done |=8;
}
- } else if (postfix == NULL && !(done & 8)) {
+ } else if (postfix == NULL && (!(done & 8) && !prefix)) {
done |=8;
}
uint8_t r;
- if (!(done & 8))
- r = addr[address-1];
- else
+ if (!(done & 8)) {
+ r = prefix;
+ addr[address] = prefix;
+ address += 1;
+ } else {
r = 0;
+ }
switch (addrmode) {
- case 0:
+ case IMPL:
if (op.impl || op.impl == CPS) {
addr[address++] = op.impl;
break;
@@ -619,10 +889,10 @@ int asmmon(const char *fn) {
fprintf(stderr, "oof, %s requires an operand.\n", op.mnemonic);
}
break;
- case 1:
+ case IMM:
if (op.imm) {
- if (addr[address-1] == 0x17 && op.imm == TXS)
- r = 0x17;
+ if ((prefix & 0x30) == 0x10 && op.imm == TXS)
+ r = prefix;
addr[address++] = op.imm;
switch (op.imm) {
case PHP:
@@ -643,7 +913,7 @@ int asmmon(const char *fn) {
addr[address++] = value & 0xFF;
break;
case TXS:
- if (r == 0x17) {
+ if ((r & 0x30) == 0x10) {
addr[address] = value & 0xFF;
addr[address+2] = value >> 8;
address+=2;
@@ -670,96 +940,124 @@ int asmmon(const char *fn) {
fprintf(stderr, "oof, %s does not use Immediate data.\n", op.mnemonic);
}
break;
- case 2:
+ case ZM:
if (op.zm) {
addr[address++] = op.zm;
addr[address] = value & 0xFF;
- addr[address+1] = value >> 8;
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- address+=4;
+ if ((r & 8) == 8) {
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ address+=4;
+ } else {
+ address+=1;
+ }
break;
} else {
fprintf(stderr, "oof, %s does not use Zero Matrix.\n", op.mnemonic);
}
break;
- case 3:
+ case ZMX:
if (op.zmx) {
addr[address++] = op.zmx;
addr[address] = value & 0xFF;
- addr[address+1] = value >> 8;
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- address+=4;
+ if ((r & 8) == 8) {
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ address+=4;
+ } else {
+ address+=1;
+ }
break;
} else {
fprintf(stderr, "oof, %s does not use Zero Matrix, indexed with x.\n", op.mnemonic);
}
break;
- case 4:
+ case ZMY:
if (op.zmy) {
addr[address++] = op.zmy;
addr[address] = value & 0xFF;
- addr[address+1] = value >> 8;
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- address+=4;
+ if ((r & 8) == 8) {
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ address+=4;
+ } else {
+ address+=1;
+ }
break;
} else {
fprintf(stderr, "oof, %s does not use Zero Matrix, indexed with y.\n", op.mnemonic);
}
break;
- case 5:
+ case ABS:
if (op.abs) {
addr[address++] = op.abs;
addr[address] = value & 0xFF;
addr[address+1] = value >> 8;
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- addr[address+4] = value >> 32;
- addr[address+5] = value >> 40;
- addr[address+6] = value >> 48;
- addr[address+7] = value >> 56;
- address+=8;
+ if ((r & 8) == 8) {
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ addr[address+4] = value >> 32;
+ addr[address+5] = value >> 40;
+ addr[address+6] = value >> 48;
+ addr[address+7] = value >> 56;
+ address+=8;
+ } else {
+ address+=2;
+ }
break;
} else {
fprintf(stderr, "oof, %s cannot be an absolute dictator.\n", op.mnemonic);
}
break;
- case 6:
+ case IND:
if (op.ind) {
addr[address++] = op.ind;
addr[address] = value & 0xFF;
- addr[address+1] = value >> 8;
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- address+=4;
+ if ((r & 8) == 8) {
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ address+=4;
+ } else {
+ address+=1;
+ }
break;
} else {
fprintf(stderr, "oof, %s cannot use pointers.\n", op.mnemonic);
}
break;
- case 7:
+ case INDX:
if (op.inx) {
addr[address++] = op.inx;
addr[address] = value & 0xFF;
- addr[address+1] = value >> 8;
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- address+=4;
+ if ((r & 8) == 8) {
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ address+=4;
+ } else {
+ address+=1;
+ }
break;
} else {
fprintf(stderr, "oof, %s does not use Indexed Indirect.\n", op.mnemonic);
}
break;
- case 8:
+ case INDY:
if (op.iny) {
addr[address++] = op.iny;
addr[address] = value & 0xFF;
- addr[address+1] = value >> 8;
- addr[address+2] = value >> 16;
- addr[address+3] = value >> 24;
- address+=4;
+ if ((r & 8) == 8) {
+ addr[address+1] = value >> 8;
+ addr[address+2] = value >> 16;
+ addr[address+3] = value >> 24;
+ address+=4;
+ } else {
+ address+=1;
+ }
break;
} else {
fprintf(stderr, "oof, %s does not use Indirect Indexed.\n", op.mnemonic);
diff --git a/opcode.h b/opcode.h
index 3e754c2..a65720a 100644
--- a/opcode.h
+++ b/opcode.h
@@ -9,94 +9,96 @@
#define AAB 0x02 /* Add Accumulator with carry by B register. */
#define PHB 0x06 /* PusH B register to stack. */
#define PHP 0x08 /* PusH Processor status to stack. */
-#define PHA 0x09 /* PusH Accumulator to stack. */
-#define PHY 0x0A /* PusH Y register to stack. */
-#define TAY 0x0B /* Transfer Accumulator to Y. */
-#define PHX 0x0C /* PusH X register to stack. */
-#define TAX 0x0D /* Transfer Accumulator to X. */
-#define TYX 0x0E /* Transfer Y to X. */
+#define LDA 0x09 /* LoaD Accumulator. */
+#define LDY 0x0A /* LoaD Y register. */
+#define LDX 0x0B /* LoaD X register. */
+#define TAB 0x0C /* Transfer Accumulator to B. */
+#define LDB 0x0E /* LoaD B register. */
#define JMP 0x10 /* JuMP to memory location. */
#define SBC 0x11 /* SuBtract with Carry. */
#define SAB 0x12 /* Subtract Accumulator with carry by B register. */
#define PLB 0x16 /* PuLl B register to stack. */
#define PLP 0x18 /* PuLl Processor status from stack. */
-#define PLA 0x19 /* PuLl Accumulator from stack. */
-#define PLY 0x1A /* PuLl Y register from stack. */
-#define TYA 0x1B /* Transfer Y to Accumulator. */
-#define PLX 0x1C /* PuLl X register from stack. */
-#define TXA 0x1D /* Transfer X to Accumulator. */
-#define TXY 0x1E /* Transfer X to Y. */
+#define TBA 0x1C /* Transfer B to Accumulator. */
#define JSR 0x20 /* Jump to SubRoutine. */
#define AND 0x21 /* bitwise AND with accumulator. */
#define ABA 0x22 /* bitwise And with Accumulator, and B register. */
-#define TAB 0x26 /* Transfer Accumulator to B. */
+#define CPB 0x26 /* ComPare B register. */
#define STT 0x28 /* STart Threads. */
-#define CPY 0x2A /* ComPare Y register. */
-#define CPX 0x2C /* ComPare X register. */
-#define TSX 0x2E /* Transfer Stack pointer to X. */
+#define STA 0x29 /* STore Accumulator. */
+#define STY 0x2A /* STore Y register. */
+#define STX 0x2B /* STore X register. */
+#define TAY 0x2C /* Transfer Accumulator to Y. */
+#define STB 0x2E /* STore B register. */
#define BPO 0x30 /* Branch if POsitive. */
#define ORA 0x31 /* bitwise OR with Accumulator. */
#define OAB 0x32 /* bitwise Or with Accumulator, and B register. */
-#define TBA 0x36 /* Transfer B to Accumulator. */
#define SEI 0x38 /* SEt Interupt flag. */
-#define INY 0x3A /* INcrement Y register. */
-#define INX 0x3C /* INcrement X register. */
-#define TXS 0x3E /* Transfer X to Stack pointer. */
+#define TYA 0x3C /* Transfer Y to Accumulator. */
#define BNG 0x40 /* Branch if NeGative. */
#define XOR 0x41 /* bitwise XOR with accumulator. */
#define XAB 0x42 /* bitwise Xor with Accumulator, and B register. */
#define CLI 0x48 /* CLear Interupt flag. */
-#define DEY 0x4A /* DEcrement Y register. */
-#define DEX 0x4C /* DEcrement X register. */
+#define TAX 0x4C /* Transfer Accumulator to X. */
#define BCS 0x50 /* Branch if Carry Set. */
#define LSL 0x51 /* Logical Shift Left. */
#define LLB 0x52 /* Logical shift Left accumulator by B. */
#define SEC 0x58 /* SEt Carry flag. */
-#define STA 0x5B /* STore Accumulator. */
-#define STY 0x5D /* STore Y register. */
-#define STX 0x5E /* STore X register. */
-#define STB 0x5F /* STore B register. */
+#define TXA 0x5C /* Transfer X to Accumulator. */
#define BCC 0x60 /* Branch if Carry Clear. */
#define LSR 0x61 /* Logical Shift Right. */
#define LRB 0x62 /* Logical shift Right accumulator by B. */
-#define LDB 0x66 /* LoaD B register. */
#define CLC 0x68 /* CLear Carry flag. */
-#define LDA 0x69 /* LoaD Accumulator. */
-#define LDY 0x6A /* LoaD Y register. */
-#define LDX 0x6C /* LoaD X register. */
+#define TYX 0x6C /* Transfer Y to X. */
#define BEQ 0x70 /* Branch if EQual. */
#define ROL 0x71 /* ROtate Left. */
#define RLB 0x72 /* Rotate Left accumulator by B. */
#define SSP 0x78 /* Set Stack Protection flag. */
+#define TXY 0x7C /* Transfer X to Y. */
#define BNE 0x80 /* Branch if Not Equal. */
#define ROR 0x81 /* ROtate Right. */
#define RRB 0x82 /* Rotate Right accumulator by B. */
+#define INY 0x86 /* INcrement Y register. */
#define CSP 0x88 /* Clear Stack Protection flag. */
+#define TSX 0x8C /* Transfer Stack pointer to X. */
#define BVS 0x90 /* Branch if oVerflow Set. */
#define MUL 0x91 /* MULtiply accumulator. */
#define MAB 0x92 /* Multiply Accumulator by B. */
+#define DEY 0x96 /* DEcrement Y register. */
#define SEV 0x98 /* SEt oVerflow flag. */
+#define TXS 0x9C /* Transfer X to Stack pointer. */
#define BVC 0xA0 /* Branch if oVerflow Clear. */
#define DIV 0xA1 /* DIVide with accumulator. */
#define DAB 0xA2 /* Divide Accumulator by B. */
+#define INX 0xA6 /* INcrement X register. */
#define CLV 0xA8 /* CLear oVerflow flag. */
+#define PHY 0xAC /* PusH Y register to stack. */
#define RTS 0xB0 /* ReTurn from Subroutine. */
#define CMP 0xB1 /* CoMPare accumulator. */
#define CAB 0xB2 /* Compare Accumulator, and B. */
+#define DEX 0xB6 /* DEcrement X register. */
#define ENT 0xB8 /* ENd Threads. */
+#define CPY 0xBA /* ComPare Y register. */
+#define CPX 0xBB /* ComPare X register. */
+#define PLY 0xBC /* PuLl Y register from stack. */
#define RTI 0xC0 /* ReTurn from Interrupt. */
#define INC 0xC1 /* INCrement accumulator. */
#define IAB 0xC2 /* Increment Accumulator, and B register. */
+#define WAI 0xC8 /* WAit for Interrupt. */
+#define PHX 0xCC /* PusH X register to stack. */
#define DEC 0xD1 /* DECrement accumulator. */
#define DBA 0xD2 /* Decrement Accumulator, and B register. */
-#define CPB 0xD6 /* ComPare B register. */
-#define WAI 0xD8 /* WAit for Interrupt. */
+#define PLX 0xDC /* PuLl X register from stack. */
#define JSL 0xE0 /* Jump to Subroutine Long. */
#define ASR 0xE1 /* Arithmetic Shift Right. */
#define ARB 0xE2 /* Arithmetic shift Right accumulator by B. */
#define NOP 0xE8 /* No OPeration. */
+#define PHA 0xEC /* PusH Accumulator to stack. */
#define RTL 0xF0 /* ReTurn from subroutine Long. */
#define BRK 0xF8 /* BReaK. */
+#define PLA 0xFC /* PuLl Accumulator from stack. */
+
+#define OPNUM 93
#define C ((uint64_t)1 << 0)
#define Z ((uint64_t)1 << 1)
@@ -134,6 +136,403 @@ typedef struct {
uint8_t impl;
} opent;
+opent opcodes[OPNUM];
+
+enum {IMPL, IMM, ZM, ZMX, ZMY, ABS, IND, INDX, INDY};
+
+static const uint8_t optype[0x100] = {
+ [0x00] = IMPL,
+ [0x01] = IMM,
+ [0x02] = IMPL,
+ [0x03] = ABS,
+ [0x04] = IND,
+ [0x05] = ZM,
+ [0x06] = IMM,
+ [0x08] = IMM,
+ [0x09] = IMM,
+ [0x0A] = IMM,
+ [0x0B] = IMM,
+ [0x0C] = IMPL,
+ [0x0E] = IMM,
+ [0x10] = ABS,
+ [0x11] = IMM,
+ [0x12] = IMPL,
+ [0x13] = ABS,
+ [0x14] = INDX,
+ [0x15] = ZM,
+ [0x16] = IMM,
+ [0x18] = IMM,
+ [0x19] = ABS,
+ [0x1A] = ABS,
+ [0x1B] = ABS,
+ [0x1C] = IMPL,
+ [0x1E] = ABS,
+ [0x20] = ZM,
+ [0x21] = IMM,
+ [0x22] = IMPL,
+ [0x23] = ABS,
+ [0x24] = INDY,
+ [0x25] = ZM,
+ [0x26] = IMM,
+ [0x28] = IMPL,
+ [0x29] = ABS,
+ [0x2A] = ABS,
+ [0x2B] = ABS,
+ [0x2C] = IMPL,
+ [0x2E] = ABS,
+ [0x30] = ABS,
+ [0x31] = IMM,
+ [0x32] = IMPL,
+ [0x33] = ABS,
+ [0x34] = IND,
+ [0x35] = ZM,
+ [0x36] = ABS,
+ [0x38] = IMPL,
+ [0x39] = ZM,
+ [0x3A] = ZM,
+ [0x3B] = ZM,
+ [0x3C] = IMPL,
+ [0x3E] = ZM,
+ [0x40] = ABS,
+ [0x41] = IMM,
+ [0x42] = IMPL,
+ [0x43] = ABS,
+ [0x44] = INDX,
+ [0x45] = ZM,
+ [0x46] = ZM,
+ [0x48] = IMPL,
+ [0x49] = ZM,
+ [0x4A] = ZM,
+ [0x4B] = ZM,
+ [0x4C] = IMPL,
+ [0x4E] = ZM,
+ [0x50] = ABS,
+ [0x51] = IMM,
+ [0x52] = IMPL,
+ [0x53] = ABS,
+ [0x54] = INDY,
+ [0x55] = ZM,
+ [0x56] = IND,
+ [0x58] = IMPL,
+ [0x59] = ZMX,
+ [0x5A] = ZMX,
+ [0x5B] = ZMY,
+ [0x5C] = IMPL,
+ [0x5E] = ZMX,
+ [0x60] = ABS,
+ [0x61] = IMM,
+ [0x62] = IMPL,
+ [0x63] = ABS,
+ [0x64] = ZM,
+ [0x65] = ZM,
+ [0x66] = INDX,
+ [0x68] = IMPL,
+ [0x69] = ZMX,
+ [0x6A] = ZMX,
+ [0x6B] = ZMY,
+ [0x6C] = IMPL,
+ [0x6E] = ZMX,
+ [0x70] = ABS,
+ [0x71] = IMM,
+ [0x72] = IMPL,
+ [0x73] = ABS,
+ [0x74] = ZM,
+ [0x75] = ZM,
+ [0x76] = INDY,
+ [0x78] = IMPL,
+ [0x79] = ZMY,
+ [0x7A] = IND,
+ [0x7B] = IND,
+ [0x7C] = IMPL,
+ [0x7E] = ZMY,
+ [0x80] = ABS,
+ [0x81] = IMM,
+ [0x82] = IMPL,
+ [0x83] = ABS,
+ [0x84] = ZM,
+ [0x85] = ZM,
+ [0x86] = IMPL,
+ [0x88] = IMPL,
+ [0x89] = ZMY,
+ [0x8A] = IND,
+ [0x8B] = IND,
+ [0x8C] = IMPL,
+ [0x8E] = ZMY,
+ [0x90] = ABS,
+ [0x91] = IMM,
+ [0x92] = IMPL,
+ [0x93] = ABS,
+ [0x94] = ZM,
+ [0x95] = ZM,
+ [0x96] = IMPL,
+ [0x98] = IMPL,
+ [0x99] = IND,
+ [0x9A] = INDX,
+ [0x9B] = INDY,
+ [0x9C] = IMM,
+ [0x9E] = IND,
+ [0xA0] = ABS,
+ [0xA1] = IMM,
+ [0xA2] = IMPL,
+ [0xA3] = ABS,
+ [0xA4] = ZM,
+ [0xA5] = ZM,
+ [0xA6] = IMPL,
+ [0xA8] = IMPL,
+ [0xA9] = IND,
+ [0xAA] = INDX,
+ [0xAB] = INDY,
+ [0xAC] = IMM,
+ [0xAE] = IND,
+ [0xB0] = IMPL,
+ [0xB1] = IMM,
+ [0xB2] = IMPL,
+ [0xB3] = ABS,
+ [0xB4] = ZM,
+ [0xB5] = ZM,
+ [0xB6] = IMPL,
+ [0xB8] = IMPL,
+ [0xB9] = INDX,
+ [0xBA] = IMM,
+ [0xBB] = IMM,
+ [0xBC] = IMM,
+ [0xBE] = INDX,
+ [0xC0] = IMPL,
+ [0xC1] = IMPL,
+ [0xC2] = IMPL,
+ [0xC3] = ABS,
+ [0xC4] = ZM,
+ [0xC5] = ZM,
+ [0xC8] = IMPL,
+ [0xC9] = INDX,
+ [0xCA] = ABS,
+ [0xCB] = ABS,
+ [0xCC] = IMM,
+ [0xCE] = INDX,
+ [0xD0] = ZM,
+ [0xD1] = IMPL,
+ [0xD2] = IMPL,
+ [0xD3] = ABS,
+ [0xD4] = ZM,
+ [0xD5] = ZM,
+ [0xD9] = INDY,
+ [0xDA] = ZM,
+ [0xDB] = ZM,
+ [0xDC] = IMM,
+ [0xDE] = INDY,
+ [0xE0] = ABS,
+ [0xE1] = IMM,
+ [0xE2] = IMPL,
+ [0xE3] = ABS,
+ [0xE5] = ZM,
+ [0xE8] = IMPL,
+ [0xE9] = INDY,
+ [0xEA] = IND,
+ [0xEB] = IND,
+ [0xEC] = IMM,
+ [0xEE] = INDY,
+ [0xF0] = IMPL,
+ [0xF1] = IND,
+ [0xF3] = INDX,
+ [0xF5] = INDY,
+ [0xF8] = IMPL,
+ [0xFA] = INDX,
+ [0xFB] = INDY,
+ [0xFC] = IMM
+};
+
+static const char *mne[OPNUM] = {
+ [ 0] = "CPS",
+ [ 1] = "ADC",
+ [ 2] = "AAB",
+ [ 3] = "JMP",
+ [ 4] = "PHB",
+ [ 5] = "PHP",
+ [ 6] = "LDA",
+ [ 7] = "LDY",
+ [ 8] = "LDX",
+ [ 9] = "TAB",
+ [10] = "LDB",
+ [11] = "SBC",
+ [12] = "SAB",
+ [13] = "PLB",
+ [14] = "PLP",
+ [15] = "TBA",
+ [16] = "JSR",
+ [17] = "AND",
+ [18] = "ABA",
+ [19] = "CPB",
+ [20] = "STT",
+ [21] = "STA",
+ [22] = "STY",
+ [23] = "STX",
+ [24] = "TAY",
+ [25] = "STB",
+ [26] = "BPO",
+ [27] = "ORA",
+ [28] = "OAB",
+ [29] = "SEI",
+ [30] = "TYA",
+ [31] = "BNG",
+ [32] = "XOR",
+ [33] = "XAB",
+ [34] = "CLI",
+ [35] = "TAX",
+ [36] = "BCS",
+ [37] = "LSL",
+ [38] = "LLB",
+ [39] = "SEC",
+ [40] = "TXA",
+ [41] = "BCC",
+ [42] = "LSR",
+ [43] = "LRB",
+ [44] = "CLC",
+ [45] = "TYX",
+ [46] = "BEQ",
+ [47] = "ROL",
+ [48] = "RLB",
+ [49] = "SSP",
+ [50] = "TXY",
+ [51] = "BNE",
+ [52] = "ROR",
+ [53] = "RRB",
+ [54] = "INY",
+ [55] = "CSP",
+ [56] = "TSX",
+ [57] = "BVS",
+ [58] = "MUL",
+ [59] = "MAB",
+ [60] = "DEY",
+ [61] = "SEV",
+ [62] = "TXS",
+ [63] = "BVC",
+ [64] = "DIV",
+ [65] = "DAB",
+ [66] = "INX",
+ [67] = "CLV",
+ [68] = "PHY",
+ [69] = "RTS",
+ [70] = "CMP",
+ [71] = "CAB",
+ [72] = "DEX",
+ [73] = "ENT",
+ [74] = "CPY",
+ [75] = "CPX",
+ [76] = "PLY",
+ [77] = "RTI",
+ [78] = "INC",
+ [79] = "IAB",
+ [80] = "WAI",
+ [81] = "PHX",
+ [82] = "DEC",
+ [83] = "DBA",
+ [84] = "PLX",
+ [85] = "JSL",
+ [86] = "ASR",
+ [87] = "ARB",
+ [88] = "NOP",
+ [89] = "PHA",
+ [90] = "RTL",
+ [91] = "BRK",
+ [92] = "PLA"
+};
+
+static const char *instdesc[OPNUM] = {
+ [ 0] = "Clears the Processor Status register.",
+ [ 1] = "ADd accumulator, with operand, Carry if needed.",
+ [ 2] = "Add Accumulator, with B, carry if needed.",
+ [ 3] = "JuMP to the address specified.",
+ [ 4] = "PusH the number of bytes specified, from the B register to the stack.",
+ [ 5] = "PusH the number of bytes specified, from the Processor status register to the stack.",
+ [ 6] = "LoaD the value from the operand, to the Accumulator.",
+ [ 7] = "LoaD the value from the operand, to the Y register.",
+ [ 8] = "LoaD the value from the operand, to the X register.",
+ [ 9] = "Transfer the value from the Accumulator, to the B register.",
+ [10] = "LoaD the value from the operand, to the B register.",
+ [11] = "SuBtract accumulator, with operand, Carry if needed",
+ [12] = "Subtract Accumulator, with B, carry if needed.",
+ [13] = "PuLl the number of bytes specified, from the stack, to the B register.",
+ [14] = "PuLl the number of bytes specified, from the stack, to the Processor status register.",
+ [15] = "Transfer the value from the Y register, to the Accumulator.",
+ [16] = "Jump to a SubRoutine.",
+ [17] = "Bitwise AND accumulator, with operand.",
+ [18] = "Bitwise AND Accumulator, with B.",
+ [19] = "ComPare the B register, with operand.",
+ [20] = "STart a Thread.",
+ [21] = "STore the value from the Accumulator, in memory.",
+ [22] = "STore the value from the Y register, in memory.",
+ [23] = "STore the value from the X register, in memory.",
+ [24] = "Transfer the value from the Accumulator, to the Y register.",
+ [25] = "STore the value from the B register, in memory.",
+ [26] = "Branch if POsitive.",
+ [27] = "Bitwise OR Accumulator, with operand.",
+ [28] = "Bitwise OR Accumulator, with B.",
+ [29] = "SEt the Interrupt flag.",
+ [30] = "Transfer the value from the Y register, to the Accumulator.",
+ [31] = "Branch if NeGative.",
+ [32] = "Bitwise XOR Accumulator, with operand.",
+ [33] = "Bitwise XOR Accumulator, with B.",
+ [34] = "CLear the Interrupt flag.",
+ [35] = "Transfer the value from the Accumulator, to the X register.",
+ [36] = "Branch if the Carry flag is Set.",
+ [37] = "Logical Shift Left accumulator, with operand.",
+ [38] = "Logical Shift Left accumulator, with B.",
+ [39] = "SEt the Carry flag.",
+ [40] = "Transfer the value from the X register, to the Accumulator.",
+ [41] = "Branch if the Carry flag has been Cleared.",
+ [42] = "Logical Shift Right accumulator, with operand.",
+ [43] = "Logical Shift Right accumulator, with B.",
+ [44] = "CLear the Carry flag.",
+ [45] = "Transfer the value from the Y register, to the X register.",
+ [46] = "Branch if EQual (the zero flag has been set).",
+ [47] = "ROtate Left accumulator, with operand.",
+ [48] = "Rotate Left accumulator, with B.",
+ [49] = "Set the Stack Protection flag.",
+ [50] = "Transfer the value from the X register, to the Y register.",
+ [51] = "Branch if Not Equal (the zero flag has been cleared).",
+ [52] = "ROtate Right accumulator, with operand.",
+ [53] = "Rotate Right accumulator, with B.",
+ [54] = "INcrement the Y register.",
+ [55] = "Clear the Stack Protection flag.",
+ [56] = "Transfer the value from the Stack pointer, to the X register.",
+ [57] = "Branch if the oVerflow flag is Set.",
+ [58] = "MULtiply accumulator, with operand.",
+ [59] = "Multiply Accumulator, with B.",
+ [60] = "DEcrement the Y register.",
+ [61] = "SEt the oVerflow flag.",
+ [62] = "Transfer the value from the X register, to the Stack pointer.",
+ [63] = "Branch if the oVerflow flag has been Cleared.",
+ [64] = "DIVide accumulator, with operand, and put the remainder into the B register.",
+ [65] = "Divide Accumulator, with B, and put the remainder into the X register.",
+ [66] = "INcrement the X register.",
+ [67] = "CLear the oVerflow flag.",
+ [68] = "PusH the number of bytes specified, from the Y register to the stack.",
+ [69] = "ReTurn from a Subroutine.",
+ [70] = "CoMPare acumulator, with operand.",
+ [71] = "Compare Accumulator, with B.",
+ [72] = "DEcrement the X register.",
+ [73] = "ENd a Thread.",
+ [74] = "ComPare the Y register, with operand.",
+ [75] = "ComPare the X register, with operand.",
+ [76] = "PuLl the number of bytes specified, from the stack, to the Y register.",
+ [77] = "ReTurn from an Interrupt.",
+ [78] = "INCrement accumulator, or memory.",
+ [79] = "Increment Accumulator, and B.",
+ [80] = "WAIt for an interrupt.",
+ [81] = "PusH the number of bytes specified, from the X register to the stack.",
+ [82] = "DECrement accumulator, or memory.",
+ [83] = "Decrement Accumulator, and B.",
+ [84] = "PuLl the number of bytes specified, from the stack, to the X register.",
+ [85] = "Jump to a Subroutine, Long address.",
+ [86] = "Arithmetic Shift Right accumulator, with operand.",
+ [87] = "Arithmetic shift Right accumulator, with B.",
+ [88] = "NO oPeration.",
+ [89] = "PusH the number of bytes specified, from the Accumulator to the stack.",
+ [90] = "ReTurn from subroutine, Long address.",
+ [91] = "BReaKpoint.",
+ [92] = "PuLl the number of bytes specified, from the stack, to the Accumulator."
+};
+
static const char *opname[0x100] = {
[0x00] = "CPS",
[0x01] = "ADC #",
@@ -143,12 +542,11 @@ static const char *opname[0x100] = {
[0x05] = "ADC zm",
[0x06] = "PHB",
[0x08] = "PHP",
- [0x09] = "PHA",
- [0x0A] = "PHY",
- [0x0B] = "TAY",
- [0x0C] = "PHX",
- [0x0D] = "TAX",
- [0x0E] = "TYX",
+ [0x09] = "LDA #",
+ [0x0A] = "LDY #",
+ [0x0B] = "LDX #",
+ [0x0C] = "TAB",
+ [0x0E] = "LDB #",
[0x10] = "JMP a",
[0x11] = "SBC #",
[0x12] = "SAB",
@@ -157,182 +555,183 @@ static const char *opname[0x100] = {
[0x15] = "SBC zm",
[0x16] = "PLB",
[0x18] = "PLP",
- [0x19] = "PLA",
- [0x1A] = "PLY",
- [0x1B] = "TYA",
- [0x1C] = "PLX",
- [0x1D] = "TXA",
- [0x1E] = "TXY",
+ [0x19] = "LDA a",
+ [0x1A] = "LDY a",
+ [0x1B] = "LDX a",
+ [0x1C] = "TBA",
+ [0x1E] = "LDB a",
[0x20] = "JSR",
[0x21] = "AND #",
[0x22] = "ABA",
[0x23] = "AND a",
[0x24] = "JMP (ind), y",
[0x25] = "AND zm",
- [0x26] = "TAB",
+ [0x26] = "CPB #",
[0x28] = "STT",
- [0x2A] = "CPY #",
- [0x2B] = "CPY a",
- [0x2C] = "CPX #",
- [0x2D] = "CPX a",
- [0x2E] = "TSX",
- [0x30] = "BPO a",
+ [0x29] = "STA a",
+ [0x2A] = "STY a",
+ [0x2B] = "STX a",
+ [0x2C] = "TAY",
+ [0x2E] = "STB a",
+ [0x30] = "BPO",
[0x31] = "ORA #",
[0x32] = "OAB",
[0x33] = "ORA a",
[0x34] = "JSR (ind)",
[0x35] = "ORA zm",
- [0x36] = "TBA",
+ [0x36] = "CPB a",
[0x38] = "SEI",
- [0x3A] = "INY",
- [0x3B] = "CPY zm",
- [0x3C] = "INX",
- [0x3D] = "CPX zm",
- [0x3E] = "TXS",
- [0x40] = "BNG a",
+ [0x39] = "LDA zm",
+ [0x3A] = "LDY zm",
+ [0x3B] = "LDX zm",
+ [0x3C] = "TYA",
+ [0x3E] = "LDB zm",
+ [0x40] = "BNG",
[0x41] = "XOR #",
[0x42] = "XAB",
[0x43] = "XOR a",
[0x44] = "JSR (ind, x)",
[0x45] = "XOR zm",
+ [0x46] = "CPB zm",
[0x48] = "CLI",
- [0x4A] = "DEY",
- [0x4C] = "DEX",
- [0x50] = "BCS a",
+ [0x49] = "STA zm",
+ [0x4A] = "STY zm",
+ [0x4B] = "STX zm",
+ [0x4C] = "TAX",
+ [0x4E] = "STB zm",
+ [0x50] = "BCS",
[0x51] = "LSL #",
[0x52] = "LLB",
[0x53] = "LSL a",
[0x54] = "JSR (ind), y",
[0x55] = "LSL zm",
- [0x56] = "LDB a",
+ [0x56] = "CPB (ind)",
[0x58] = "SEC",
- [0x59] = "LDA a",
- [0x5A] = "LDY a",
- [0x5B] = "STA a",
- [0x5C] = "LDX a",
- [0x5D] = "STY a",
- [0x5E] = "STX a",
- [0x5F] = "STB a",
- [0x60] = "BCC a",
+ [0x59] = "LDA zm, x",
+ [0x5A] = "LDY zm, x",
+ [0x5B] = "LDX zm, y",
+ [0x5C] = "TXA",
+ [0x5E] = "LDB zm, x",
+ [0x60] = "BCC",
[0x61] = "LSR #",
[0x62] = "LRB",
[0x63] = "LSR a",
[0x64] = "BPO zm",
[0x65] = "LSR zm",
- [0x66] = "LDB #",
+ [0x66] = "CPB (ind, x)",
[0x68] = "CLC",
- [0x69] = "LDA #",
- [0x6A] = "LDY #",
- [0x6C] = "LDX #",
- [0x70] = "BEQ a",
+ [0x69] = "STA zm, x",
+ [0x6A] = "STY zm, x",
+ [0x6B] = "STX zm, y",
+ [0x6C] = "TYX",
+ [0x6E] = "STB zm, x",
+ [0x70] = "BEQ",
[0x71] = "ROL #",
[0x72] = "RLB",
[0x73] = "ROL a",
[0x74] = "BNG zm",
[0x75] = "ROL zm",
- [0x76] = "LDB zm",
+ [0x76] = "CPB (ind), y",
[0x78] = "SSP",
- [0x79] = "LDA zm",
- [0x7A] = "LDY zm",
- [0x7B] = "STA zm",
- [0x7C] = "LDX zm",
- [0x7D] = "STY zm",
- [0x7E] = "STX zm",
- [0x7F] = "STB zm",
- [0x80] = "BNE a",
+ [0x79] = "LDA zm, y",
+ [0x7A] = "LDY (ind)",
+ [0x7B] = "LDX (ind)",
+ [0x7C] = "TXY",
+ [0x7E] = "LDB zm, y",
+ [0x80] = "BNE",
[0x81] = "ROR #",
[0x82] = "RRB",
[0x83] = "ROR a",
[0x84] = "BCS zm",
[0x85] = "ROR zm",
- [0x86] = "LDB zm, x",
+ [0x86] = "INY",
[0x88] = "CSP",
- [0x89] = "LDA zm, x",
- [0x8A] = "LDY zm, x",
- [0x8B] = "STA zm, x",
- [0x8D] = "STY zm, x",
- [0x8F] = "STB zm, x",
- [0x90] = "BVS a",
+ [0x89] = "STA zm, y",
+ [0x8A] = "STY (ind)",
+ [0x8B] = "STX (ind)",
+ [0x8C] = "TSX",
+ [0x8E] = "STB zm, y",
+ [0x90] = "BVS",
[0x91] = "MUL #",
[0x92] = "MAB",
[0x93] = "MUL a",
[0x94] = "BCC zm",
[0x95] = "MUL zm",
- [0x96] = "LDB zm, y",
+ [0x96] = "DEY",
[0x98] = "SEV",
- [0x99] = "LDA zm, y",
- [0x9B] = "STA zm, y",
- [0x9C] = "LDX zm, y",
- [0x9E] = "STX zm, y",
- [0x9F] = "STB zm, y",
- [0xA0] = "BVC a",
+ [0x99] = "LDA (ind)",
+ [0x9A] = "LDY (ind, x)",
+ [0x9B] = "LDX (ind), y",
+ [0x9C] = "TXS",
+ [0x9E] = "LDB (ind)",
+ [0xA0] = "BVC",
[0xA1] = "DIV #",
[0xA2] = "DAB",
[0xA3] = "DIV a",
[0xA4] = "BEQ zm",
[0xA5] = "DIV zm",
- [0xA6] = "LDB (ind)",
+ [0xA6] = "INX",
[0xA8] = "CLV",
- [0xA9] = "LDA (ind)",
- [0xAA] = "LDY (ind)",
- [0xAB] = "STA (ind)",
- [0xAC] = "LDX (ind)",
- [0xAD] = "STY (ind)",
- [0xAE] = "STX (ind)",
- [0xAF] = "STB (ind)",
+ [0xA9] = "STA (ind)",
+ [0xAA] = "STY (ind, x)",
+ [0xAB] = "STX (ind), y",
+ [0xAC] = "PHY",
+ [0xAE] = "STB (ind)",
[0xB0] = "RTS",
[0xB1] = "CMP #",
[0xB2] = "CAB",
[0xB3] = "CMP a",
[0xB4] = "BNE zm",
[0xB5] = "CMP zm",
- [0xB6] = "LDB (ind, x)",
+ [0xB6] = "DEX",
[0xB8] = "ENT",
[0xB9] = "LDA (ind, x)",
- [0xBA] = "LDY (ind, x)",
- [0xBB] = "STA (ind, x)",
- [0xBD] = "STY (ind, x)",
- [0xBF] = "STB (ind, x)",
+ [0xBA] = "CPY #",
+ [0xBB] = "CPX #",
+ [0xBC] = "PLY",
+ [0xBE] = "LDB (ind, x)",
[0xC0] = "RTI",
[0xC1] = "INC A",
[0xC2] = "IAB",
[0xC3] = "INC a",
[0xC4] = "BVS zm",
[0xC5] = "INC zm",
- [0xC6] = "LDB (ind), y",
- [0xC9] = "LDA (ind), y",
- [0xCB] = "STA (ind), y",
- [0xCC] = "LDX (ind), y",
- [0xCE] = "STX (ind), y",
- [0xCF] = "STB (ind), y",
+ [0xC8] = "WAI",
+ [0xC9] = "STA (ind, x)",
+ [0xCA] = "CPY a",
+ [0xCB] = "CPX a",
+ [0xCC] = "PHX",
+ [0xCE] = "STB (ind, x)",
[0xD0] = "JMP zm",
[0xD1] = "DEC A",
[0xD2] = "DBA",
[0xD3] = "DEC a",
[0xD4] = "BVC zm",
[0xD5] = "DEC zm",
- [0xD6] = "CPB #",
- [0xD8] = "WAI",
- [0xDF] = "CPB (ind)",
+ [0xD9] = "LDA (ind), y",
+ [0xDA] = "CPY zm",
+ [0xDB] = "CPX zm",
+ [0xDC] = "PLX",
+ [0xDE] = "LDB (ind), y",
[0xE0] = "JSL",
[0xE1] = "ASR #",
[0xE2] = "ARB",
[0xE3] = "ASR a",
[0xE5] = "ASR zm",
- [0xE6] = "CPB a",
[0xE8] = "NOP",
- [0xE9] = "CMP (ind)",
+ [0xE9] = "STA (ind), y",
[0xEA] = "CPY (ind)",
- [0xEB] = "CMP (ind, x)",
- [0xEC] = "CPX (ind)",
- [0xED] = "CMP (ind), y",
- [0xEF] = "CPB (ind, x)",
+ [0xEB] = "CPX (ind)",
+ [0xEC] = "PHA",
+ [0xEE] = "STB (ind), y",
[0xF0] = "RTL",
- [0xF6] = "CPB zm",
+ [0xF1] = "CMP (ind)",
+ [0xF3] = "CMP (ind, x)",
+ [0xF5] = "CMP (ind), y",
[0xF8] = "BRK",
[0xFA] = "CPY (ind, x)",
- [0xFC] = "CPX (ind), y",
- [0xFF] = "CPB (ind), y"
+ [0xFB] = "CPX (ind), y",
+ [0xFC] = "PLA"
};
extern int asmmon();
diff --git a/programs/forg.s b/programs/forg.s
new file mode 100644
index 0000000..3e6aea1
--- /dev/null
+++ b/programs/forg.s
@@ -0,0 +1,17 @@
+forg:
+ iny ; Increment offset.
+ lda buf, y
+ jsr iswhite
+ bcs forg ; Reset y, if we hit the null terminator.
+ cmp #$2E ; Is this character a '.'?
+ bne forg_exit ; No, so return.
+ sty org ; Yes, so store the origin.
+forg_end:
+ iny ; Increment offset.
+ lda buf, y
+ jsr istoken
+ bcs forg_end
+ dey
+ sty scr_col
+forg_exit:
+ rts ; End of forg.
diff --git a/programs/hex-to-bcd.s b/programs/hex-to-bcd.s
new file mode 100644
index 0000000..53a3ff2
--- /dev/null
+++ b/programs/hex-to-bcd.s
@@ -0,0 +1,7 @@
+hex_to_bcd:
+ pla #1 ; Get argument.
+ div #10 ; Divide A by 10.
+ lsl #4 ; Shift the result left by 4 bits.
+ oab ; Or the result, with the remainder.
+ pha #1 ; Push the packed BCD result to the stack.
+ rts ; Return the result.
diff --git a/programs/subasm.s b/programs/subasm.s
index ddb7ba2..50f2e8d 100644
--- a/programs/subasm.s
+++ b/programs/subasm.s
@@ -12,6 +12,111 @@ ver_txt:
ver_num:
.byte "0.1"
+; Directives.
+dir:
+ .byte "org"
+ .byte "byte"
+ .byte "word"
+ .byte "dword"
+ .byte "qword"
+
+; Instruction mnemonics.
+mne:
+ .byte "CPS"
+ .byte "ADC"
+ .byte "AAB"
+ .byte "PHB"
+ .byte "PHP"
+ .byte "PHA"
+ .byte "PHY"
+ .byte "TAY"
+ .byte "PHX"
+ .byte "TAX"
+ .byte "TYX"
+ .byte "JMP"
+ .byte "SBC"
+ .byte "SAB"
+ .byte "PLB"
+ .byte "PLP"
+ .byte "PLA"
+ .byte "PLY"
+ .byte "TYA"
+ .byte "PLX"
+ .byte "TXA"
+ .byte "TXY"
+ .byte "JSR"
+ .byte "AND"
+ .byte "ABA"
+ .byte "STT"
+ .byte "TAB"
+ .byte "TSX"
+ .byte "BPO"
+ .byte "ORA"
+ .byte "OAB"
+ .byte "TBA"
+ .byte "SEI"
+ .byte "TXS"
+ .byte "BNG"
+ .byte "XOR"
+ .byte "XAB"
+ .byte "CLI"
+ .byte "BCS"
+ .byte "LSL"
+ .byte "LLB"
+ .byte "STB"
+ .byte "SEC"
+ .byte "STA"
+ .byte "STY"
+ .byte "STX"
+ .byte "BCC"
+ .byte "LSR"
+ .byte "LRB"
+ .byte "LDB"
+ .byte "CLC"
+ .byte "LDA"
+ .byte "LDY"
+ .byte "LDX"
+ .byte "BEQ"
+ .byte "ROL"
+ .byte "RLB"
+ .byte "SSP"
+ .byte "BNE"
+ .byte "ROR"
+ .byte "RRB"
+ .byte "CSP"
+ .byte "BVS"
+ .byte "MUL"
+ .byte "MAB"
+ .byte "SEV"
+ .byte "BVC"
+ .byte "DIV"
+ .byte "DAB"
+ .byte "CLV"
+ .byte "RTS"
+ .byte "CMP"
+ .byte "CAB"
+ .byte "CPY"
+ .byte "CPX"
+ .byte "CPB"
+ .byte "ENT"
+ .byte "RTI"
+ .byte "INC"
+ .byte "IAB"
+ .byte "INY"
+ .byte "INX"
+ .byte "DEC"
+ .byte "DBA"
+ .byte "DEY"
+ .byte "DEX"
+ .byte "WAI"
+ .byte "JSL"
+ .byte "ASR"
+ .byte "ARB"
+ .byte "NOP"
+ .byte "RTL"
+ .byte "BRK"
+
+
scr_row:
.byte $0
scr_col:
@@ -31,6 +136,13 @@ str_buf:
.org $2000
buf:
+.org $2400
+ptr1:
+ .qword $2500
+
+ptr2:
+ .qword $2900
+
; Control Register.
.org $C000
ctrl_reg:
@@ -49,22 +161,22 @@ reset:
cps
ldx.w #$FFFF
txs
- ldy #$0
+ ldy #0
jsr clr_buf
- ldx.w #$0 ; Reset x.
- ldy #$0 ; Reset y.
+ ldx.w #0 ; Reset x.
+ ldy #0 ; Reset y.
jmp print_title
read:
lda ctrl_reg ; Is the keyboard ready?
beq read ; Loop until the keyboard is ready.
- lda #$0 ; Start resetting the control register.
+ lda #0 ; Start resetting the control register.
sta ctrl_reg ; Reset the control register.
jmp getchar ; We got a key.
rset_x:
- ldx #$0 ; Reset x.
+ ldx #0 ; Reset x.
stx.w x
rts
@@ -94,7 +206,7 @@ getline:
lda #$A
sta scr ; Print newline
inc scr_row
- lda #$0
+ lda #0
sta scr_col
inc y
jsr rset_x
@@ -106,7 +218,7 @@ getchar:
beq esc ; Yes, so start getting the escape code.
cmp #$A ; Did the user type a newline?
beq nl ; Yes, so start parsing the input.
- cmp #$8 ; Did the user type a backspace?
+ cmp #8 ; Did the user type a backspace?
beq bs ; Yes, so start checking the buffer.
jsr echo ; Print character to screen.
@@ -123,16 +235,16 @@ esc:
sta c ; Store the escape code, until we need it.
jsr isup ; Check if the user pressed up.
lda d
- cmp #$0
+ cmp #0
bne esc_end
jsr isdown ; Check if the user pressed down.
lda d
- cmp #$0
+ cmp #0
bne esc_end
- lda #$0
+ lda #0
jsr isleft ; Check if the user pressed left.
lda d
- cmp #$0
+ cmp #0
bne esc_end
jsr isright ; Check if the user pressed right.
esc_end:
@@ -181,13 +293,13 @@ isleft_done:
up:
dec scr_row
jsr update_pos
- lda #$1
+ lda #1
sta d
jmp isup_done
down:
inc scr_row
jsr update_pos
- lda #$1
+ lda #1
sta d
jmp isdown_done
right:
@@ -197,7 +309,7 @@ right:
left:
dec scr_col
jsr update_pos
- lda #$1
+ lda #1
sta d
jmp isleft_done
@@ -237,47 +349,81 @@ getcol:
nl:
sta scr ; Print newline.
inc scr_row ; Move the cursor down one line.
- lda #$0 ; Put a null terminator, in place of the newline.
+ lda #0 ; Put a null terminator, in place of the newline.
sta scr_col ; Move the cursor back to column 0.
- sta str_buf, y ; Place it into the input buffer.
- ldy.w #$0 ; Reset y, to parse the input.
+ sta buf, y ; Place it into the input buffer.
+ ldy.w #0 ; Reset y, to parse the input.
jsr parse ; Start parsing input.
back:
sta scr ; Print backspace.
- lda #$0 ; Put a null terminator, in place of the backspace.
- sta str_buf, y ; Place it into the input buffer.
+ lda #0 ; Put a null terminator, in place of the backspace.
+ sta buf, y ; Place it into the input buffer.
dey ; Decrement buffer offset.
dec scr_col
jmp read ; Get next character.
bs:
- cpy #$0 ; Are we at the start of the buffer?
+ cpy #0 ; Are we at the start of the buffer?
beq read ; We are, so do not store the backspace into the buffer.
jmp back ; We are not, so add the backspace to the buffer.
parse:
- jmp parse ; Keep printing.
- jsr clr_sbuf
+ jsr getdir
+ jsr
rts
-forg:
+getdir:
iny ; Increment offset.
- lda str_buf, y
+ lda buf, y
jsr iswhite
- bcs forg ; Reset y, if we hit the null terminator.
+ bcs getdir ; Reset y, if we hit the null terminator.
cmp #$2E ; Is this character a '.'?
- bne forg_exit ; No, so return.
- sty org ; Yes, so store the origin.
-forg_end:
+ bne getdir_exit ; No, so return.
+ jsr clr_ptr
+
+getdir_end:
iny ; Increment offset.
- lda str_buf, y
+ lda buf, y
+ jsr iswhite
+ bcs getdir_cmp
+ ora #%00100000 ; Make character lower case.
+ sta (ptr1), y
+ jmp getdir_end
+gettok:
+ ply #1
+ iny
+gettok2:
+ lda buf, y
jsr istoken
- bcs forg_end
- dey
- sty scr_col
-forg_exit:
- rts ; End of forg.
+ bcs gettok3
+ jmp gettok2
+gettok3:
+ cmp #$
+ cmp #$24 ; Is this character, a '$'?
+ beq getaddr ; Yes, so start getting the address.
+
+
+
+getdir_cmp:
+ phy #1
+ ldy.w #0
+ tyx
+getdir_cpl:
+ ldb dir, x ; Start checking if the directive we're using, is "org".
+ stb (ptr2), y
+ beq getdir_scmp
+ inx
+ iny
+ jmp getdir_cpl
+getdir_scmp:
+ ldy #0
+ jsr strcmp
+ cpx #0
+ beq getdir_tok
+getdir_exit:
+ rts ; End of getdir.
+
istoken:
cmp #$20 ; Is this character a space?
@@ -288,7 +434,7 @@ istoken:
beq istoken_f ; Yes, so return false.
cmp #$3B ; Is this character a ';'?
beq istoken_f ; Yes, so return false.
- cmp #$0 ; Is this character a null terminator?
+ cmp #0 ; Is this character a null terminator?
beq istoken_f ; Yes, so return false.
sec ; Return true.
rts ; End of istoken.
@@ -299,7 +445,7 @@ istoken_f
iswhite:
cmp #$20 ; Is this character a space?
beq iswhite_t ; Yes, so return true.
- cmp #$09 ; Is this character a tab?
+ cmp #9 ; Is this character a tab?
beq iswhite_t ; Yes, so return true.
clc ; No, so return false.
rts ; End of iswhite.
@@ -308,7 +454,7 @@ iswhite_t:
rts ; End of iswhite_t.
rset_y:
- ldy.w #$0
+ ldy.w #0
jmp print_buf ; Print the input buffer.
print_buf:
@@ -325,15 +471,15 @@ spin:
jmp spin
clr_buf:
- lda #$0
- cpy.w #$1000
+ lda #0
+ cpy.w #$3FF
beq clr_end
sta buf, y
iny
jmp clr_buf
clr_sbuf:
- lda #$0
- cpy.w #$40
+ lda #0
+ cpy.w #$1FF
beq clr_end
sta str_buf, y
iny
@@ -343,7 +489,7 @@ clr_end:
rts
echo:
- sta a
+ tab
ldx scr_col
cpx #$4F
bne echo_print
@@ -351,17 +497,51 @@ echo:
beq linewrap
linewrap:
inc scr_row
- ldx #$0
+ ldx #0
stx scr_col
jsr update_pos
echo_print:
- lda a
+ tba
sta scr ; Echo typed character.
inc scr_col ; Increment the cursor's x coordinate.
- sta str_buf, y ; Store typed character into the input buffer.
+ sta buf, y ; Store typed character into the input buffer.
iny ; Increment the buffer offset.
rts ; Return.
+clr_ptr:
+ lda #0
+ cpy.w #$3FF
+ beq ptr_end
+ sta (ptr1), y
+ sta (ptr2), y
+ iny
+ jmp clr_ptr
+ptr_end:
+ rts
+
+strcmp:
+ lda (ptr1), y
+ cmp (ptr2), y
+ bne strcmp_l1
+ tax
+ beq strcmp_l3
+ iny
+ bne strcmp
+ jmp strcmp
+
+
+strcmp_l1:
+ bcs strcmp_l2
+ ldx #0
+ dex
+ rts
+
+strcmp_l2:
+ ldx #1
+strcmp_l3:
+ rts
+
+
.org $FFC0
.qword reset
@@ -376,9 +556,23 @@ echo_print:
.org $FFA0
.qword irq_routine
-;.org $0
-;viewmem
-;.org $100
-;viewmem
-;q
-done
+.org $0
+v
+.org $100
+v
+.org $200
+v
+.org $300
+v
+.org $1000
+v
+.org $1100
+v
+.org $1200
+v
+.org $1300
+v
+.org $1400
+v
+q
+
diff --git a/sux.c b/sux.c
index 85280c1..1fc8fe2 100644
--- a/sux.c
+++ b/sux.c
@@ -1,15 +1,16 @@
#include "opcode.h"
#include <assert.h>
-#include <curses.h>
#include <ctype.h>
#include <string.h>
#include <pthread.h>
#define bench 0
-#define debug 1
-#define IO 0
+#define debug 0
+#define IO 1
#define keypoll 0
#if bench
#include <sys/time.h>
+#else
+#include <curses.h>
#endif
#define THREADS 1
@@ -27,7 +28,9 @@ uint8_t threads_done = 0;
uint8_t kbd_rdy = 0;
uint8_t wai = 0;
uint8_t irq = 0;
+#if !bench
WINDOW *scr;
+#endif
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t main_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
@@ -46,21 +49,26 @@ void *run(void *args) {
struct sux *cpu = &thr->sx;
uint8_t thread = thr->th;
uint64_t address = 0;
+ uint64_t tmpaddr = 0;
uint8_t prefix = 0;
uint8_t opcode = 0;
uint8_t end = 0;
+ uint8_t stksize;
uint64_t sum = 0;
uint64_t value = 0;
+ uint64_t reg = 0;
uint64_t iclk = 0;
uint64_t ins = 0;
uint64_t sign = 0;
char *s = malloc(2048);
+#if !bench
uint8_t lines = (6*thread)+2;
uint8_t bcd[4];
uint8_t idx = 3, iscol = 0;
- uint16_t tv = 0xFF50; /* Starting address of the Thread Vectors. */
int x = 0, y = 0;
uint8_t esc = 0;
+#endif
+ uint16_t tv = 0xFF50; /* Starting address of the Thread Vectors. */
#if bench
gettimeofday(&str[thread], 0);
#endif
@@ -90,35 +98,229 @@ void *run(void *args) {
kbd_rdy &= (uint8_t)~(1 << thread);
}
prefix = addr[cpu->pc[thread]];
- if ((prefix & 0x0F) == 0x07)
+ if ((prefix & 0x07) == 0x07)
cpu->pc[thread]++;
else
prefix = 0;
opcode = addr[cpu->pc[thread]];
+
#if debug && !bench
+ if (lines > 24*(thread+1)) {
+ lines = (24*thread)+2;
+ }
#if keypoll
pthread_mutex_lock(&mutex);
#endif
mvwprintw(scr, lines, 0, "pc: $%08llx, a: $%016llx, b: $%016llx, x: $%016llx, y: $%016llx"
- ", sp: $%04lx, ps: $%016llx, prefix: $%02x, opcode: $%02x, thread: %u, inst: %s \r"
+ ", sp: $%04lx, ps: $%016llx, prefix: $%02x, opcode: $%02x, thread: %u, inst: "
, cpu->pc[thread], cpu->a[thread], cpu->b[thread], cpu->x[thread], cpu->y[thread]
- , cpu->sp[thread], cpu->ps, prefix, opcode, thread, opname[opcode]);
- wrefresh(scr);
+ , cpu->sp[thread], cpu->ps, prefix, opcode, thread);
#if keypoll
pthread_mutex_unlock(&mutex);
#endif
- lines++;
- if (lines > 24*(thread+1))
- lines = (24*thread)+2;
#endif
+ uint8_t addrsize = (prefix & 8) == 8;
uint8_t rs = (prefix & 0x30) >> 4;
uint8_t regsize = (1 << rs);
uint8_t tmp;
address = cpu->pc[thread];
cpu->pc[thread]++;
iclk++;
+ switch (optype[opcode]) {
+ case IMPL:
+ break;
+ case IMM:
+ switch (opcode) {
+ case TXS:
+ case PHB:
+ case PHP:
+ case PHA:
+ case PHY:
+ case PHX:
+ case PLB:
+ case PLP:
+ case PLA:
+ case PLY:
+ case PLX:
+ break;
+ case STT:
+ case LSL:
+ case LSR:
+ case ROL:
+ case ROR:
+ case ASR:
+ case ENT:
+ address = cpu->pc[thread];
+ cpu->pc[thread]+=1;
+ break;
+ default:
+ address = cpu->pc[thread];
+ cpu->pc[thread]+=regsize;
+ break;
+ }
+ break;
+ case ZM:
+ case ZMX:
+ case ZMY:
+ address = addr[cpu->pc[thread]];
+ if (addrsize) {
+ address |= addr[cpu->pc[thread]+1] << 8;
+ address |= addr[cpu->pc[thread]+2] << 16;
+ address |= addr[cpu->pc[thread]+3] << 24;
+ cpu->pc[thread]+=4;
+ } else {
+ cpu->pc[thread]+=1;
+ }
+ tmpaddr = address;
+ if (optype[opcode] == ZMX)
+ address += cpu->x[thread];
+ if (optype[opcode] == ZMY)
+ address += cpu->y[thread];
+ break;
+ case IND:
+ case INDX:
+ case INDY:
+ address = addr[cpu->pc[thread]];
+ if (addrsize) {
+ address |= addr[cpu->pc[thread]+1] << 8;
+ address |= addr[cpu->pc[thread]+2] << 16;
+ address |= addr[cpu->pc[thread]+3] << 24;
+ cpu->pc[thread]+=4;
+ } else {
+ cpu->pc[thread]+=1;
+ }
+ tmpaddr = address;
+ if (optype[opcode] == INDX)
+ address += cpu->x[thread];
+ value = (uint64_t)addr[address]
+ | (uint64_t)addr[address+1] << 8
+ | (uint64_t)addr[address+2] << 16
+ | (uint64_t)addr[address+3] << 24
+ | (uint64_t)addr[address+4] << 32
+ | (uint64_t)addr[address+5] << 40
+ | (uint64_t)addr[address+6] << 48
+ | (uint64_t)addr[address+7] << 56;
+ if (optype[opcode] == INDY)
+ value += cpu->y[thread];
+ address = value;
+ value = 0;
+ iclk++;
+ break;
+ case ABS:
+ address = addr[cpu->pc[thread]];
+ address |= addr[cpu->pc[thread]+1] << 8;
+ if (addrsize) {
+ address |= (uint64_t)addr[cpu->pc[thread]+2] << 16;
+ address |= (uint64_t)addr[cpu->pc[thread]+3] << 24;
+ address |= (uint64_t)addr[cpu->pc[thread]+4] << 32;
+ address |= (uint64_t)addr[cpu->pc[thread]+5] << 40;
+ address |= (uint64_t)addr[cpu->pc[thread]+6] << 48;
+ address |= (uint64_t)addr[cpu->pc[thread]+7] << 56;
+ cpu->pc[thread]+=8;
+ iclk++;
+ } else {
+ cpu->pc[thread]+=2;
+ }
+
+ break;
+
+ }
+ value = addr[address];
+ if (regsize >= 2) {
+ value |= addr[address+1] << 8;
+ if (regsize >= 4) {
+ value |= addr[address+2] << 16;
+ value |= addr[address+3] << 24;
+ }
+ if (regsize >= 8) {
+ value |= (uint64_t)addr[address+4] << 32;
+ value |= (uint64_t)addr[address+5] << 40;
+ value |= (uint64_t)addr[address+6] << 48;
+ value |= (uint64_t)addr[address+7] << 56;
+ }
+ }
+ #if debug && !bench
+ int row, col;
+ #if keypoll
+ pthread_mutex_lock(&mutex);
+ #endif
+ getyx(scr,row, col);
+ char postfix[3];
+ char op[4];
+ op[0] = opname[opcode][0];
+ op[1] = opname[opcode][1];
+ op[2] = opname[opcode][2];
+ op[3] = '\0';
+ if (regsize == 1) {
+ postfix[0] = '\0';
+ postfix[1] = '\0';
+ postfix[2] = '\0';
+ } else {
+ postfix[0] = '.';
+ if (regsize == 2)
+ postfix[1] = 'W';
+ if (regsize == 4)
+ postfix[1] = 'D';
+ if (regsize == 8)
+ postfix[1] = 'Q';
+ postfix[2] = '\0';
+ }
+ switch (optype[opcode]) {
+ case IMPL:
+ mvwprintw(scr, lines, col, "%s \r" , opname[opcode]);
+ break;
+ case IMM:
+ if (regsize == 1) {
+ mvwprintw(scr, lines, col, "%s #$%02x \r" , op, value);
+ }
+ if (regsize == 2) {
+ mvwprintw(scr, lines, col, "%s%s #$%04x \r" , op, postfix, value);
+ }
+ if (regsize == 4) {
+ mvwprintw(scr, lines, col, "%s%s #$%08x \r" , op, postfix, value);
+ }
+ if (regsize == 8) {
+ mvwprintw(scr, lines, col, "%s%s #$%016llx\r" , op, postfix, value);
+ }
+ break;
+ case ZM:
+ case ZMX:
+ case ZMY:
+ if (optype[opcode] == ZMX)
+ tmpaddr = address - cpu->x[thread];
+ if (optype[opcode] == ZMY)
+ tmpaddr = address - cpu->y[thread];
+ if (addrsize)
+ mvwprintw(scr, lines, col, "%s%s $%08x%s \r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y"));
+ else
+ mvwprintw(scr, lines, col, "%s%s $%02x%s \r" , op, postfix, tmpaddr, (optype[opcode] == ZM) ? "" : ((optype[opcode] == ZMX) ? ", x" : ", y"));
+ break;
+ case IND:
+ case INDX:
+ case INDY:
+ if (addrsize)
+ mvwprintw(scr, lines, col, "%s%s ($%08x%s \r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y"));
+ else
+ mvwprintw(scr, lines, col, "%s%s ($%02x%s \r" , op, postfix, tmpaddr, (optype[opcode] == IND) ? ")" : ((optype[opcode] == INDX) ? ", x)" : "), y"));
+ break;
+ case ABS:
+ tmpaddr = address;
+ if (addrsize)
+ mvwprintw(scr, lines, col, "%s%s $%016llx\r" , op, postfix, value);
+ else
+ mvwprintw(scr, lines, col, "%s%s $%04x \r" , op, postfix, tmpaddr);
+ break;
+
+ }
+ mvwprintw(scr, 29, 0, "address: $%016llx\r", address);
+ wrefresh(scr);
+ #if keypoll
+ pthread_mutex_unlock(&mutex);
+ #endif
+ lines+=1;
+ #endif
switch(opcode) {
case CPS: /* Clear Processor Status. */
for (uint8_t i = 0; i < 8; i++) {
@@ -135,48 +337,8 @@ void *run(void *args) {
case AAB: /* Add Accumulator with carry by B register. */
case 0x03: /* ADC Absolute. */
case 0x05: /* ADC Zero Matrix. */
- if (opcode != AAB) {
- if (opcode == ADC) {
- address = cpu->pc[thread];
- cpu->pc[thread]+=regsize;
- }
- if (opcode == 0x03) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0x05) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
- value = addr[address];
- if (regsize >= 2) {
- value += (uint64_t)addr[address+1] << 8;
- }
- if (regsize >= 4) {
- value += (uint64_t)addr[address+2] << 16;
- value += (uint64_t)addr[address+3] << 24;
- }
- if (regsize >= 8) {
- value += (uint64_t)addr[address+4] << 32;
- value += (uint64_t)addr[address+5] << 40;
- value += (uint64_t)addr[address+6] << 48;
- value += (uint64_t)addr[address+7] << 56;
- }
- } else {
+ if (opcode == AAB)
value = cpu->b[thread];
- }
sum = cpu->a[thread]+value+cpu->c[thread];
cpu->a[thread] = sum;
cpu->z[thread] = (sum == 0);
@@ -305,62 +467,13 @@ void *run(void *args) {
}
break;
case JMP: /* JMP Absolute. */
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
cpu->pc[thread] = address;
break;
case SBC: /* SBC Immediate. */
case SAB: /* Subtract Accumulator with carry by B register. */
case 0x13: /* SBC Absolute. */
case 0x15: /* SBC Zero Matrix. */
- if (opcode != SAB) {
- if (opcode == SBC) {
- address = cpu->pc[thread];
- cpu->pc[thread]+=regsize;
- }
- if (opcode == 0x13) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0x15) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
- value = addr[address];
- if (regsize >= 2) {
- value += (uint64_t)addr[address+1] << 8;
- }
- if (regsize >= 4) {
- value += (uint64_t)addr[address+2] << 16;
- value += (uint64_t)addr[address+3] << 24;
- }
- if (regsize >= 8) {
- value += (uint64_t)addr[address+4] << 32;
- value += (uint64_t)addr[address+5] << 40;
- value += (uint64_t)addr[address+6] << 48;
- value += (uint64_t)addr[address+7] << 56;
- }
- } else {
+ if (opcode == SAB) {
value = cpu->b[thread];
}
sum = cpu->a[thread]-value-!cpu->c[thread];
@@ -438,25 +551,10 @@ void *run(void *args) {
case 0x44: /* JSR Indexed Indirect. */
case 0x54: /* JSR Indirect Indexed. */
case JSR: /* Jump to SubRoutine. */
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24;
- if (opcode == 0x34 || opcode == 0x44 || opcode == 0x54) {
- address = (uint64_t)addr[address]
- | (uint64_t)addr[address+1] << 8
- | (uint64_t)addr[address+2] << 16
- | (uint64_t)addr[address+3] << 24
- | (uint64_t)addr[address+4] << 32
- | (uint64_t)addr[address+5] << 40
- | (uint64_t)addr[address+6] << 48
- | (uint64_t)addr[address+7] << 56;
- if (opcode == 0x44)
- address += cpu->x[thread];
- if (opcode == 0x54)
- address += cpu->y[thread];
- }
- cpu->pc[thread]+=4;
+ if (addrsize)
+ stksize = 24;
+ else
+ stksize = 0;
for (int8_t i = 24; i >= 0; i-=8) {
if (i)
addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> i;
@@ -470,44 +568,8 @@ void *run(void *args) {
case ABA: /* bitwise And with Accumulator, and B register. */
case 0x23: /* AND Absolute. */
case 0x25: /* AND Zero Matrix. */
- if (opcode != ABA) {
- if (opcode == AND) {
- address = cpu->pc[thread];
- cpu->pc[thread]+=regsize;
- }
- if (opcode == 0x23) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0x25) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
- value = (uint64_t)addr[address];
- if (regsize >= 2)
- value += (uint64_t)addr[address+1] << 8;
- if (regsize >= 4) {
- value += (uint64_t)addr[address+2] << 16;
- value += (uint64_t)addr[address+3] << 24;
- }
- if (regsize >= 8) {
- value += (uint64_t)addr[address+4] << 32;
- value += (uint64_t)addr[address+5] << 40;
- value += (uint64_t)addr[address+6] << 48;
- value += (uint64_t)addr[address+7] << 56;
- }
+ if (opcode == ABA) {
+ value = cpu->b[thread];
}
cpu->a[thread] &= value;
cpu->z[thread] = (value == 0);
@@ -516,9 +578,6 @@ void *run(void *args) {
(cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
break;
case STT: /* STart Thread. */
- address = cpu->pc[thread];
- cpu->pc[thread]++;
- value = addr[address];
cpu->crt |= value;
for (uint8_t i = 0; i < 7; i++) {
if ((value >> i) & 1) {
@@ -536,25 +595,6 @@ void *run(void *args) {
break;
case BPO: /* BPO Absolute. */
case 0x64: /* BPO Zero Matrix. */
- if (opcode == BPO) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- } else {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
if (cpu->n[thread])
cpu->pc[thread] = address;
break;
@@ -562,45 +602,7 @@ void *run(void *args) {
case OAB: /* bitwise Or with Accumulator, and B register. */
case 0x33: /* ORA Absolute. */
case 0x35: /* ORA Zero Matrix. */
- if (opcode != OAB) {
- if (opcode == ORA) {
- address = cpu->pc[thread];
- cpu->pc[thread]+=regsize;
- }
- if (opcode == 0x39) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0x3B) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
- value = (uint64_t)addr[address];
- if (regsize >= 2)
- value += (uint64_t)addr[address+1] << 8;
- if (regsize >= 4) {
- value += (uint64_t)addr[address+2] << 16;
- value += (uint64_t)addr[address+3] << 24;
- }
- if (regsize >= 8) {
- value += (uint64_t)addr[address+4] << 32;
- value += (uint64_t)addr[address+5] << 40;
- value += (uint64_t)addr[address+6] << 48;
- value += (uint64_t)addr[address+7] << 56;
- }
- } else {
+ if (opcode == OAB) {
value = cpu->b[thread];
}
cpu->a[thread] |= value;
@@ -615,25 +617,6 @@ void *run(void *args) {
break;
case BNG: /* BNG Absolute. */
case 0x74: /* BNG Zero Matrix. */
- if (opcode == BNG) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- } else {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
if (!cpu->n[thread])
cpu->pc[thread] = address;
break;
@@ -641,45 +624,7 @@ void *run(void *args) {
case XAB: /* bitwise Xor with Accumulator, and B register. */
case 0x43: /* XOR Absolute. */
case 0x45: /* XOR Zero Matrix. */
- if (opcode != XAB) {
- if (opcode == XOR) {
- address = cpu->pc[thread];
- cpu->pc[thread]+=regsize;
- }
- if (opcode == 0x49) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0x4B) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
- value = (uint64_t)addr[address];
- if (regsize >= 2)
- value += (uint64_t)addr[address+1] << 8;
- if (regsize >= 4) {
- value += (uint64_t)addr[address+2] << 16;
- value += (uint64_t)addr[address+3] << 24;
- }
- if (regsize >= 8) {
- value += (uint64_t)addr[address+4] << 32;
- value += (uint64_t)addr[address+5] << 40;
- value += (uint64_t)addr[address+6] << 48;
- value += (uint64_t)addr[address+7] << 56;
- }
- } else {
+ if (opcode == XAB) {
value = cpu->b[thread];
}
cpu->a[thread] ^= value;
@@ -694,25 +639,6 @@ void *run(void *args) {
break;
case BCS: /* BCS Absolute. */
case 0x84: /* BCS Zero Matrix. */
- if (opcode == BCS) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- } else {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
if (cpu->c[thread])
cpu->pc[thread] = address;
break;
@@ -720,34 +646,7 @@ void *run(void *args) {
case LLB: /* Logical shift Left accumulator by B. */
case 0x53: /* LSL Absolute. */
case 0x55: /* LSL Zero Matrix. */
- if (opcode != LLB) {
- if (opcode == LSL) {
- address = cpu->pc[thread];
- cpu->pc[thread]++;
- }
- if (opcode == 0x53) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
-
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0x55) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
- value = addr[address];
- } else {
+ if (opcode == LLB) {
value = cpu->b[thread];
}
sum = (value < 64) ? cpu->a[thread] << value : 0;
@@ -767,69 +666,33 @@ void *run(void *args) {
case STY: /* STY Absolute. */
case STX: /* STX Absolute. */
case STB: /* STB Absolute. */
- case 0x7B: /* STA Zero Matrix. */
- case 0x7D: /* STY Zero Matrix. */
- case 0x7E: /* STX Zero Matrix. */
- case 0x7F: /* STB Zero Matrix. */
- case 0x8B: /* STA Zero Matrix, Indexed with X. */
- case 0x8D: /* STY Zero Matrix, Indexed with X. */
- case 0x8F: /* STA Zero Matrix, Indexed with X. */
- case 0x9B: /* STA Zero Matrix, Indexed with Y. */
- case 0x9E: /* STX Zero Matrix, Indexed with Y. */
- case 0x9F: /* STA Zero Matrix, Indexed with Y. */
- case 0xAB: /* STA Indirect. */
- case 0xAD: /* STY Indirect. */
- case 0xAE: /* STX Indirect. */
- case 0xAF: /* STB Indirect. */
- case 0xBB: /* STA Indexed Indirect. */
- case 0xBD: /* STY Indexed Indirect. */
- case 0xBF: /* STB Indexed Indirect. */
- case 0xCB: /* STA Indirect Indexed. */
- case 0xCE: /* STX Indirect Indexed. */
- case 0xCF: /* STB Indirect Indexed. */
- if (opcode == STA || opcode == STY || opcode == STX || opcode == STB) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- } else {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- if (opcode == 0xAB || opcode == 0xAD || opcode == 0xAE || opcode == 0xAF || opcode == 0xBB ||
- opcode == 0xBD || opcode == 0xBF || opcode == 0xCB || opcode == 0xCE || opcode == 0xCF) {
- address = (uint64_t)addr[address]
- | (uint64_t)addr[address+1] << 8
- | (uint64_t)addr[address+2] << 16
- | (uint64_t)addr[address+3] << 24
- | (uint64_t)addr[address+4] << 32
- | (uint64_t)addr[address+5] << 40
- | (uint64_t)addr[address+6] << 48
- | (uint64_t)addr[address+7] << 56;
- }
- if (opcode == 0x8B || opcode == 0x8D || opcode == 0x8F ||
- opcode == 0xBB || opcode == 0xBD || opcode == 0xBF)
- address += cpu->x[thread];
- if (opcode == 0x9B || opcode == 0x9E || opcode == 0x9F ||
- opcode == 0xCB || opcode == 0xCE || opcode == 0xCF)
- address += cpu->y[thread];
- cpu->pc[thread]+=4;
- iclk++;
- }
- if (opcode == STA || opcode == 0x7B || opcode == 0x8B || opcode == 0x9B)
+ case 0x49: /* STA Zero Matrix. */
+ case 0x4A: /* STY Zero Matrix. */
+ case 0x4B: /* STX Zero Matrix. */
+ case 0x4E: /* STB Zero Matrix. */
+ case 0x69: /* STA Zero Matrix, Indexed with X. */
+ case 0x6A: /* STY Zero Matrix, Indexed with X. */
+ case 0x6B: /* STX Zero Matrix, Indexed with Y. */
+ case 0x6E: /* STB Zero Matrix, Indexed with X. */
+ case 0x89: /* STA Zero Matrix, Indexed with Y. */
+ case 0x8A: /* STY Indirect. */
+ case 0x8B: /* STX Indirect. */
+ case 0x8E: /* STB Zero Matrix, Indexed with Y. */
+ case 0xA9: /* STA Indirect. */
+ case 0xAA: /* STY Indexed Indirect. */
+ case 0xAB: /* STX Indirect Indexed. */
+ case 0xAE: /* STB Indirect. */
+ case 0xC9: /* STA Indexed Indirect. */
+ case 0xCE: /* STB Indexed Indirect. */
+ case 0xE9: /* STA Indirect Indexed. */
+ case 0xEE: /* STB Indirect Indexed. */
+ if (opcode == STA || opcode == 0x49 || opcode == 0x69 || opcode == 0x89 || opcode == 0xA9 || opcode == 0xC9 || opcode == 0xE9)
value = cpu->a[thread];
- if (opcode == STY || opcode == 0x7D || opcode == 0x8D)
+ if (opcode == STY || opcode == 0x4A || opcode == 0x6A || opcode == 0x8A || opcode == 0xAA)
value = cpu->y[thread];
- if (opcode == STX || opcode == 0x7E || opcode == 0x9E)
+ if (opcode == STY || opcode == 0x4B || opcode == 0x6B || opcode == 0x8B || opcode == 0xAB)
value = cpu->x[thread];
- if (opcode == STB || opcode == 0x7F || opcode == 0x8F || opcode == 0x9F)
+ if (opcode == STB || opcode == 0x4E || opcode == 0x6E || opcode == 0x8E || opcode == 0xAE || opcode == 0xCE || opcode == 0xEE)
value = cpu->b[thread];
addr[address] = value & 0xFF;
#if IO
@@ -923,6 +786,7 @@ void *run(void *args) {
#endif
}
#else
+ #if !bench
if (address == TX_ADDR) {
if (esc) {
switch(addr[address]) {
@@ -955,7 +819,8 @@ void *run(void *args) {
x = 0;
else
x = ((bcd[1]*10) + bcd[0]);
- mvwprintw(scr, getmaxy(scr)-25, 0, "x: %i, y: %i ", x, y);
+ mvwprintw(scr, 30, 0, "x: %i, y: %i ", x, y);
+ wrefresh(scr);
idx = 3;
bcd[0] = 0;
bcd[1] = 0;
@@ -997,6 +862,7 @@ void *run(void *args) {
}
}
#endif
+ #endif
if (regsize >= 2)
addr[address+1] = value >> 8;
if (regsize >= 4) {
@@ -1012,25 +878,6 @@ void *run(void *args) {
break;
case BCC: /* BCC Absolute. */
case 0x94: /* BCC Zero Matrix. */
- if (opcode == BCC) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- } else {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
if (!cpu->c[thread])
cpu->pc[thread] = address;
break;
@@ -1038,46 +885,26 @@ void *run(void *args) {
case LRB: /* Logical shift Right accumulator by B. */
case 0x63: /* LSR Absolute. */
case 0x65: /* LSR Zero Matrix. */
+ if (opcode == LRB) {
+ value = cpu->b[thread];
+ }
+ sum = (value < 64) ? cpu->a[thread] >> value : 0;
+ cpu->z[thread] = (sum == 0);
+ cpu->n[thread] = (sum >> 63);
+ cpu->c[thread] = cpu->a[thread] & 1;
+ cpu->a[thread] = sum;
+ (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread));
+ (cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
+ (cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread));
+ break;
case ASR: /* ASR Immediate. */
case ARB: /* Arithmetic shift Right accumulator by B. */
case 0xE3: /* ASR Absolute. */
case 0xE5: /* ASR Zero Matrix. */
- if (opcode != LRB || opcode != ARB) {
- if (opcode == LSR || opcode == ASR) {
- address = cpu->pc[thread];
- cpu->pc[thread]++;
- }
- if (opcode == 0x63 || opcode == 0xE3) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0x65 || opcode == 0xE5) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
- value = addr[address];
- } else {
+ if (opcode == ARB)
value = cpu->b[thread];
- }
- if (opcode == ASR || opcode == ARB || opcode == 0xE3 || opcode == 0xE5) {
- sign = cpu->a[thread] & 0x8000000000000000;
- sum = (value < 64) ? (cpu->a[thread] >> value) | sign : 0;
- }
- if (opcode == LSR || opcode == LRB || opcode == 0x63 || opcode == 0x65) {
- sum = (value < 64) ? cpu->a[thread] >> value : 0;
- }
+ sign = cpu->a[thread] & 0x8000000000000000;
+ sum = (value < 64) ? (cpu->a[thread] >> value) | sign : 0;
cpu->z[thread] = (sum == 0);
cpu->n[thread] = (sum >> 63);
cpu->c[thread] = cpu->a[thread] & 1;
@@ -1090,73 +917,34 @@ void *run(void *args) {
cpu->c[thread] = 0;
(cpu->ps &= ~(C << 8*thread));
break;
- case 0x56: /* LDB Absolute. */
- case 0x59: /* LDA Absolute. */
- case 0x5A: /* LDY Absolute. */
- case 0x5C: /* LDX Absolute. */
case LDB: /* LDB Immediate. */
case LDA: /* LDA Immediate. */
case LDY: /* LDY Immediate. */
case LDX: /* LDX Immediate. */
- case 0x76: /* LDB Zero Matrix. */
- case 0x79: /* LDA Zero Matrix. */
- case 0x7A: /* LDY Zero Matrix. */
- case 0x7C: /* LDX Zero Matrix. */
- case 0x86: /* LDB Zero Matrix, Indexed with X. */
- case 0x89: /* LDA Zero Matrix, Indexed with X. */
- case 0x8A: /* LDY Zero Matrix, Indexed with X. */
- case 0x96: /* LDB Zero Matrix, Indexed with Y. */
- case 0x99: /* LDA Zero Matrix, Indexed with Y. */
- case 0x9C: /* LDX Zero Matrix, Indexed with Y. */
- case 0xA6: /* LDB Indirect. */
- case 0xA9: /* LDA Indirect. */
- case 0xAA: /* LDY Indirect. */
- case 0xAC: /* LDX Indirect. */
- case 0xB6: /* LDB Indexed Indirect. */
+ case 0x1E: /* LDB Absolute. */
+ case 0x19: /* LDA Absolute. */
+ case 0x1A: /* LDY Absolute. */
+ case 0x1B: /* LDX Absolute. */
+ case 0x3E: /* LDB Zero Matrix. */
+ case 0x39: /* LDA Zero Matrix. */
+ case 0x3A: /* LDY Zero Matrix. */
+ case 0x3B: /* LDX Zero Matrix. */
+ case 0x5E: /* LDB Zero Matrix, Indexed with X. */
+ case 0x59: /* LDA Zero Matrix, Indexed with X. */
+ case 0x5A: /* LDY Zero Matrix, Indexed with X. */
+ case 0x5B: /* LDX Zero Matrix, Indexed with Y. */
+ case 0x7E: /* LDB Zero Matrix, Indexed with Y. */
+ case 0x79: /* LDA Zero Matrix, Indexed with Y. */
+ case 0x7A: /* LDY Indirect. */
+ case 0x7B: /* LDX Indirect. */
+ case 0x9E: /* LDB Indirect. */
+ case 0x99: /* LDA Indirect. */
+ case 0x9A: /* LDY Indexed Indirect. */
+ case 0x9B: /* LDX Indirect Indexed. */
+ case 0xBE: /* LDB Indexed Indirect. */
case 0xB9: /* LDA Indexed Indirect. */
- case 0xBA: /* LDY Indexed Indirect. */
- case 0xC6: /* LDB Indirect Indexed. */
- case 0xC9: /* LDA Indirect Indexed. */
- case 0xCC: /* LDX Indirect Indexed. */
- if (opcode == LDB || opcode == LDA || opcode == LDY || opcode == LDX) {
- address = cpu->pc[thread];
- cpu->pc[thread]+=regsize;
- } else if (opcode == 0x56 || opcode == 0x59 || opcode == 0x5A || opcode == 0x5C) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- } else {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- if (opcode == 0xA6 || opcode == 0xA9 || opcode == 0xAA || opcode == 0xAC || opcode == 0xB6 ||
- opcode == 0xB9 || opcode == 0xBA || opcode == 0xC6 || opcode == 0xC9 || opcode == 0xCC) {
- address = (uint64_t)addr[address]
- | (uint64_t)addr[address+1] << 8
- | (uint64_t)addr[address+2] << 16
- | (uint64_t)addr[address+3] << 24
- | (uint64_t)addr[address+4] << 32
- | (uint64_t)addr[address+5] << 40
- | (uint64_t)addr[address+6] << 48
- | (uint64_t)addr[address+7] << 56;
- }
- if (opcode == 0x86 || opcode == 0x89 || opcode == 0x8A ||
- opcode == 0xB6 || opcode == 0xB9 || opcode == 0xBA)
- address += cpu->x[thread];
- if (opcode == 0x96 || opcode == 0x99 || opcode == 0x9C ||
- opcode == 0xC6 || opcode == 0xC9 || opcode == 0xCC)
- address += cpu->y[thread];
- cpu->pc[thread]+=4;
- iclk++;
- }
+ case 0xDE: /* LDB Indirect Indexed. */
+ case 0xD9: /* LDA Indirect Indexed. */
if (address == CTRL_ADDR) {
pthread_mutex_lock(&main_mutex);
pthread_cond_signal(&main_cond);
@@ -1180,13 +968,13 @@ void *run(void *args) {
value += (uint64_t)addr[address+6] << 48;
value += (uint64_t)addr[address+7] << 56;
}
- if (opcode == LDB || opcode == 0x56 || opcode == 0x76 || opcode == 0x86 || opcode == 0x96)
+ if (opcode == LDB || opcode == 0x1E || opcode == 0x3E || opcode == 0x5E || opcode == 0x7E || opcode == 0x9E || opcode == 0xBE || opcode == 0xDE)
cpu->b[thread] = value;
- if (opcode == LDA || opcode == 0x59 || opcode == 0x79 || opcode == 0x89 || opcode == 0x99)
+ if (opcode == LDA || opcode == 0x19 || opcode == 0x39 || opcode == 0x59 || opcode == 0x79 || opcode == 0x99 || opcode == 0xB9 || opcode == 0xD9)
cpu->a[thread] = value;
- if (opcode == LDY || opcode == 0x5A || opcode == 0x7A || opcode == 0x8A)
+ if (opcode == LDY || opcode == 0x1A || opcode == 0x3A || opcode == 0x5A || opcode == 0x7A || opcode == 0x9A)
cpu->y[thread] = value;
- if (opcode == LDX || opcode == 0x5C || opcode == 0x7C || opcode == 0x9C)
+ if (opcode == LDX || opcode == 0x1B || opcode == 0x3B || opcode == 0x5B || opcode == 0x7B || opcode == 0x9B)
cpu->x[thread] = value;
cpu->z[thread] = (value == 0);
cpu->n[thread] = (value >> 63);
@@ -1195,25 +983,6 @@ void *run(void *args) {
break;
case BEQ: /* BEQ Absolute. */
case 0xA4: /* BEQ Zero Matrix. */
- if (opcode == BEQ) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- } else {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
if (cpu->z[thread])
cpu->pc[thread] = address;
break;
@@ -1221,33 +990,7 @@ void *run(void *args) {
case RLB: /* Rotate Left accumulator by B. */
case 0x73: /* ROL Absolute. */
case 0x75: /* ROL Zero Matrix. */
- if (opcode != RLB) {
- if (opcode == ROL) {
- address = cpu->pc[thread];
- cpu->pc[thread]++;
- }
- if (opcode == 0x73) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0x75) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
- value = addr[address];
- } else {
+ if (opcode == RLB) {
value = cpu->b[thread];
}
sum = cpu->a[thread] << value;
@@ -1266,25 +1009,6 @@ void *run(void *args) {
break;
case BNE: /* BNE Absolute. */
case 0xB4: /* BNE Zero Matrix. */
- if (opcode == BNE) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- } else {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
if (!cpu->z[thread])
cpu->pc[thread] = address;
break;
@@ -1292,33 +1016,7 @@ void *run(void *args) {
case RRB: /* Rotate Right accumulator by B. */
case 0x83: /* ROR Absolute. */
case 0x85: /* ROR Zero Matrix. */
- if (opcode != RRB) {
- if (opcode == ROR) {
- address = cpu->pc[thread];
- cpu->pc[thread]++;
- }
- if (opcode == 0x83) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0x85) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
- value = addr[address];
- } else {
+ if (opcode == RRB) {
value = cpu->b[thread];
}
sum = cpu->a[thread] >> value;
@@ -1337,25 +1035,6 @@ void *run(void *args) {
break;
case BVS: /* BVS Absolute. */
case 0xC4: /* BVS Zero Matrix. */
- if (opcode == BVS) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- } else {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
if (cpu->v[thread])
cpu->pc[thread] = address;
break;
@@ -1363,46 +1042,7 @@ void *run(void *args) {
case MAB: /* Multiply Accumulator by B. */
case 0x93: /* MUL Absolute. */
case 0x95: /* MUL Zero Matrix. */
- if (opcode != MAB) {
- if (opcode == MUL) {
- address = cpu->pc[thread];
- cpu->pc[thread]+=regsize;
- }
- if (opcode == 0x93) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0x95) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
- value = addr[address];
- if (regsize >= 2) {
- value += (uint64_t)addr[address+1] << 8;
- }
- if (regsize >= 4) {
- value += (uint64_t)addr[address+2] << 16;
- value += (uint64_t)addr[address+3] << 24;
- }
- if (regsize >= 8) {
- value += (uint64_t)addr[address+4] << 32;
- value += (uint64_t)addr[address+5] << 40;
- value += (uint64_t)addr[address+6] << 48;
- value += (uint64_t)addr[address+7] << 56;
- }
- } else {
+ if (opcode == MAB) {
value = cpu->b[thread];
}
sum = cpu->a[thread]*value+cpu->c[thread];
@@ -1422,25 +1062,6 @@ void *run(void *args) {
break;
case BVC: /* BVC Absolute. */
case 0xD4: /* BVC Zero Matrix. */
- if (opcode == BVC) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- } else {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
if (!cpu->v[thread])
cpu->pc[thread] = address;
break;
@@ -1449,44 +1070,6 @@ void *run(void *args) {
case 0xA3: /* DIV Absolute. */
case 0xA5: /* DIV Zero Matrix. */
if (opcode != DAB) {
- if (opcode == DIV) {
- address = cpu->pc[thread];
- cpu->pc[thread]+=regsize;
- }
- if (opcode == 0xA3) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0xA5) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
- value = addr[address];
- if (regsize >= 2) {
- value += (uint64_t)addr[address+1] << 8;
- }
- if (regsize >= 4) {
- value += (uint64_t)addr[address+2] << 16;
- value += (uint64_t)addr[address+3] << 24;
- }
- if (regsize >= 8) {
- value += (uint64_t)addr[address+4] << 32;
- value += (uint64_t)addr[address+5] << 40;
- value += (uint64_t)addr[address+6] << 48;
- value += (uint64_t)addr[address+7] << 56;
- }
cpu->b[thread] = cpu->a[thread] % value;
} else {
value = cpu->b[thread];
@@ -1504,7 +1087,11 @@ void *run(void *args) {
(cpu->ps &= ~(V << 8*thread));
break;
case RTS: /* ReTurn from Subroutine. */
- for (uint8_t i = 0; i < 32; i+=8) {
+ if (addrsize)
+ stksize = 32;
+ else
+ stksize = 8;
+ for (uint8_t i = 0; i < stksize; i+=8) {
cpu->sp[thread]++;
if (i)
cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i;
@@ -1517,93 +1104,46 @@ void *run(void *args) {
case CAB: /* Compare Accumulator, and B. */
case CPY: /* CPY Immediate. */
case CPX: /* CPX Immediate. */
- case 0x2B: /* CPY Absolute. */
- case 0x2D: /* CPX Absolute. */
+ case 0xCA: /* CPY Absolute. */
+ case 0xCB: /* CPX Absolute. */
case 0xB3: /* CMP Absolute. */
- case 0xE6: /* CPB Absolute. */
- case 0x3B: /* CPY Zero Matrix. */
- case 0x3D: /* CPX Zero Matrix. */
+ case 0x36: /* CPB Absolute. */
+ case 0xDA: /* CPY Zero Matrix. */
+ case 0xDB: /* CPX Zero Matrix. */
case 0xB5: /* CMP Zero Matrix. */
- case 0xF6: /* CPB Zero Matrix. */
- case 0xE9: /* CMP Indirect. */
+ case 0x46: /* CPB Zero Matrix. */
+ case 0xF1: /* CMP Indirect. */
case 0xEA: /* CPY Indirect. */
- case 0xEC: /* CPX Indirect. */
- case 0xDF: /* CPB Indirect. */
- case 0xEB: /* CMP Indexed Indirect. */
+ case 0xEB: /* CPX Indirect. */
+ case 0x56: /* CPB Indirect. */
+ case 0xF3: /* CMP Indexed Indirect. */
case 0xFA: /* CPY Indexed Indirect. */
- case 0xEF: /* CPB Indexed Indirect. */
- case 0xED: /* CMP Indirect Indexed. */
- case 0xFC: /* CPX Indirect Indexed. */
- case 0xFF: /* CPB Indirect Indexed. */
- if (opcode != CAB) {
- if (opcode == CMP || opcode == CPY || opcode == CPX || opcode == CPB) {
- address = cpu->pc[thread];
- cpu->pc[thread]+=regsize;
- } else if (opcode == 0xB3 || opcode == 0x2B || opcode == 0x2D) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- } else {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- if (opcode == 0xDF || opcode == 0xE9 || opcode == 0xEA || opcode == 0xEB || opcode == 0xEC ||
- opcode == 0xED || opcode == 0xEF || opcode == 0xFA || opcode == 0xFC || opcode == 0xFF) {
- address = (uint64_t)addr[address]
- | (uint64_t)addr[address+1] << 8
- | (uint64_t)addr[address+2] << 16
- | (uint64_t)addr[address+3] << 24
- | (uint64_t)addr[address+4] << 32
- | (uint64_t)addr[address+5] << 40
- | (uint64_t)addr[address+6] << 48
- | (uint64_t)addr[address+7] << 56;
- if (opcode == 0xEB || opcode == 0xEF || opcode == 0xFA)
- address += cpu->x[thread];
- if (opcode == 0xED || opcode == 0xFC || opcode == 0xFF)
- address += cpu->y[thread];
- }
- cpu->pc[thread]+=4;
- iclk++;
- }
- value = (uint64_t)addr[address];
- if (regsize >= 2)
- value += (uint64_t)addr[address+1] << 8;
- if (regsize >= 4) {
- value += (uint64_t)addr[address+2] << 16;
- value += (uint64_t)addr[address+3] << 24;
- }
- if (regsize >= 8) {
- value += (uint64_t)addr[address+4] << 32;
- value += (uint64_t)addr[address+5] << 40;
- value += (uint64_t)addr[address+6] << 48;
- value += (uint64_t)addr[address+7] << 56;
- }
- } else {
+ case 0x66: /* CPB Indexed Indirect. */
+ case 0xF5: /* CMP Indirect Indexed. */
+ case 0xFB: /* CPX Indirect Indexed. */
+ case 0x76: /* CPB Indirect Indexed. */
+ if (opcode == CAB) {
value = cpu->b[thread];
}
- if (opcode == CMP || opcode == CAB || opcode == 0xE5 || opcode == 0xF5)
- sum = cpu->a[thread]-value;
- if (opcode == CPY || opcode == 0xE2 || opcode == 0xF2)
- sum = cpu->y[thread]-value;
- if (opcode == CPX || opcode == 0xE4 || opcode == 0xF4)
- sum = cpu->x[thread]-value;
+ if (opcode == CPB || opcode == 0x36 || opcode == 0x46 || opcode == 0x56 || opcode == 0x66 || opcode == 0x76)
+ reg = cpu->b[thread];
+ if (opcode == CMP || opcode == CAB || opcode == 0xB3 || opcode == 0xB5 || opcode == 0xF1 || opcode == 0xF3 || opcode == 0xF5)
+ reg = cpu->a[thread];
+ if (opcode == CPY || opcode == 0xCA || opcode == 0xDA || opcode == 0xEA || opcode == 0xFA)
+ reg = cpu->y[thread];
+ if (opcode == CPX || opcode == 0xCB || opcode == 0xDB || opcode == 0xEB || opcode == 0xFB)
+ reg = cpu->x[thread];
+ sum = reg-value;
cpu->n[thread] = (sum & 0x8000000000000000) ? 1 : 0;
+ cpu->v[thread] = ((reg^value) & 0x8000000000000000) && ((reg^sum) & 0x8000000000000000);
cpu->z[thread] = (sum == 0) ? 1 : 0;
cpu->c[thread] = (sum > value) ? 1 : 0;
- (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread));
(cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
+ (cpu->v[thread]) ? (cpu->ps |= (V << 8*thread)) : (cpu->ps &= ~(V << 8*thread));
+ (cpu->z[thread]) ? (cpu->ps |= (Z << 8*thread)) : (cpu->ps &= ~(Z << 8*thread));
(cpu->c[thread]) ? (cpu->ps |= (C << 8*thread)) : (cpu->ps &= ~(C << 8*thread));
break;
case ENT: /* ENd Thread. */
- value = addr[address];
cpu->crt &= ~value;
for (uint8_t i = 0; i < 7; i++)
if ((value >> i) & 1)
@@ -1648,27 +1188,6 @@ void *run(void *args) {
case 0x14: /* JMP Indexed Indirect. */
case 0x24: /* JMP Indirect Indexed. */
case 0xD0: /* JMP Zero Matrix. */
- address = (uint32_t)addr[cpu->pc[thread]]
- |(uint32_t)addr[cpu->pc[thread]+1] << 8
- |(uint32_t)addr[cpu->pc[thread]+2] << 16
- |(uint32_t)addr[cpu->pc[thread]+3] << 24;
-
- if (opcode == 0x04 || opcode == 0x14 || opcode == 0x24) {
- address = (uint64_t)addr[address]
- | (uint64_t)addr[address+1] << 8
- | (uint64_t)addr[address+2] << 16
- | (uint64_t)addr[address+3] << 24
- | (uint64_t)addr[address+4] << 32
- | (uint64_t)addr[address+5] << 40
- | (uint64_t)addr[address+6] << 48
- | (uint64_t)addr[address+7] << 56;
- if (opcode == 0x14)
- address += cpu->x[thread];
- if (opcode == 0x24)
- address += cpu->y[thread];
- }
- cpu->pc[thread]+=4;
- iclk++;
cpu->pc[thread] = address;
break;
@@ -1697,16 +1216,11 @@ void *run(void *args) {
(cpu->n[thread]) ? (cpu->ps |= (N << 8*thread)) : (cpu->ps &= ~(N << 8*thread));
break;
case JSL: /* Jump to Subroutine Long. */
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- for (int8_t i = 56; i >= 0; i-=8) {
+ if (addrsize)
+ stksize = 56;
+ else
+ stksize = 8;
+ for (int8_t i = stksize; i >= 0; i-=8) {
if (i)
addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] = (uint64_t)cpu->pc[thread] >> i;
else
@@ -1717,63 +1231,25 @@ void *run(void *args) {
break;
case 0xC3: /* INC Absolute. */
case 0xC5: /* INC Zero Matrix. */
- if (opcode == 0xC3) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0xC5) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
addr[address]++;
break;
case NOP: /* No OPeration. */
break;
case RTL: /* ReTurn from subroutine Long. */
- for (uint8_t i = 0; i < 64; i+=8) {
+ if (addrsize)
+ stksize = 64;
+ else
+ stksize = 16;
+ for (uint8_t i = 0; i < stksize; i+=8) {
cpu->sp[thread]++;
- if (i < 56)
- cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i;
- else if (i == 56)
- cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i + 1;
+ if (i)
+ cpu->pc[thread] += addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]] << i;
else
cpu->pc[thread] = addr[(cpu->stk_st[thread] << 16)+cpu->sp[thread]];
}
break;
case 0xD3: /* DEC Absolute. */
case 0xD5: /* DEC Zero Matrix. */
- if (opcode == 0xD3) {
- address = (uint64_t)addr[cpu->pc[thread]]
- | (uint64_t)addr[cpu->pc[thread]+1] << 8
- | (uint64_t)addr[cpu->pc[thread]+2] << 16
- | (uint64_t)addr[cpu->pc[thread]+3] << 24
- | (uint64_t)addr[cpu->pc[thread]+4] << 32
- | (uint64_t)addr[cpu->pc[thread]+5] << 40
- | (uint64_t)addr[cpu->pc[thread]+6] << 48
- | (uint64_t)addr[cpu->pc[thread]+7] << 56;
- cpu->pc[thread]+=8;
- iclk++;
- }
- if (opcode == 0xD5) {
- address = addr[cpu->pc[thread]]
- | addr[cpu->pc[thread]+1] << 8
- | addr[cpu->pc[thread]+2] << 16
- | addr[cpu->pc[thread]+3] << 24;
- cpu->pc[thread]+=4;
- iclk++;
- }
addr[address]--;
break;
case BRK: /* BReaK. */
@@ -1810,18 +1286,17 @@ void *run(void *args) {
break;
}
ins++;
- usleep(100000);
#if debug && !bench
#if keypoll
pthread_mutex_lock(&mutex);
#endif
- mvwprintw(scr, getmaxy(scr)-lines, 0, "Operand: $%llx"
+ /*mvwprintw(scr, getmaxy(scr)-lines, 0, "Operand: $%llx"
", $%04llx: $%02x, $%04llx: $%02x"
", $1000: $%02x, $1001: $%02x "
, value
, RX_ADDR, addr[RX_ADDR], TX_ADDR, addr[TX_ADDR]
- , addr[0x1000], addr[0x1001]);
- mvwprintw(scr, (24*thread)+1, 0, "Instructions executed: %llu, Clock cycles: %llu\r", ins, iclk);
+ , addr[0x1000], addr[0x1001]);*/
+ mvwprintw(scr, (6*thread)+1, 0, "Instructions executed: %llu, Clock cycles: %llu\r", ins, iclk);
wrefresh(scr);
#if keypoll
pthread_mutex_unlock(&mutex);
@@ -1830,12 +1305,12 @@ void *run(void *args) {
#if bench
if (ins >= BENCH_INST) {
end = 1;
- pthread_mutex_lock(&mutex);
+ pthread_mutex_lock(&main_mutex);
threads_done++;
inst[thread] = ins;
clk[thread] = iclk;
pthread_cond_signal(&main_cond);
- pthread_mutex_unlock(&mutex);
+ pthread_mutex_unlock(&main_mutex);
gettimeofday(&en[thread], 0);
}
#endif
@@ -1861,6 +1336,7 @@ int main(int argc, char **argv) {
sprintf(tmp, "\033[2J\033[H");
fwrite(tmp, sizeof(char), strlen(tmp), stdout);
fflush(stdout);
+#if !bench
if(!scr)
scr = initscr();
nodelay(stdscr, 0);
@@ -1876,11 +1352,13 @@ int main(int argc, char **argv) {
init_pair(1, COLOR_WHITE, -1);
attron(COLOR_PAIR(1) | A_BOLD);
wmove(scr, 0, 0);
+#endif
for (int i = 0; i < THREADS; i++) {
thr[i].sx.sp[i] = 0xFFFF;
thr[i].sx.stk_st[i] = i+1;
if (i) {
thr[i].sx.a[i] = 0;
+ thr[i].sx.b[i] = 0;
thr[i].sx.x[i] = 0;
thr[i].sx.y[i] = 0;
thr[i].sx.pc[i] = (uint64_t)addr[0xFF50+(8*(i-1))]
@@ -1893,6 +1371,7 @@ int main(int argc, char **argv) {
| (uint64_t)addr[0xFF57+(8*(i-1))] << 56;
} else {
thr[i].sx.a[i] = 0;
+ thr[i].sx.b[i] = 0;
thr[i].sx.x[i] = 0;
thr[i].sx.y[i] = 0;
thr[i].sx.pc[i] = (uint64_t)addr[0xFFC0]
@@ -1916,10 +1395,12 @@ int main(int argc, char **argv) {
assert(!result);
}
int c = 0;
+#if !bench
werase(scr);
+#endif
while (threads_done < THREADS) {
- int x, y, i = 0;
#if !bench
+ int x, y, i = 0;
if ((c != EOF && c !=-1)) {
pthread_mutex_lock(&main_mutex);
curs_set(0);
@@ -1945,6 +1426,7 @@ int main(int argc, char **argv) {
default:
addr[RX_ADDR] = (uint8_t)c;
addr[CTRL_ADDR] = 1;
+ kbd_rdy = 1;
#if !keypoll
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
@@ -1963,10 +1445,6 @@ int main(int argc, char **argv) {
}
#if bench
if (threads_done == THREADS) {
- #if en_nc
- scr = NULL;
- endwin();
- #endif
double tm_sec, tm_usec, tm[THREADS], ttm;
double clkspd;
double mhz;
diff --git a/test/asr.s b/test/asr.s
index ca5eff1..4bc388f 100644
--- a/test/asr.s
+++ b/test/asr.s
@@ -7,15 +7,17 @@ reset:
start:
lda.q #$-FFFF
+ ldb.q #-1
signshft:
- asr #$1
- cmp.q #$-1
+ asr #1
+ cab
beq start
jmp signshft
.org $FFC0
.qword reset
.org $0
+v
done
diff --git a/test/fib2.s b/test/fib2.s
new file mode 100644
index 0000000..d8c0d42
--- /dev/null
+++ b/test/fib2.s
@@ -0,0 +1,26 @@
+; Variables for thread 0.
+.org $1000
+x:
+ .qword $0
+y:
+ .qword $1
+z:
+ .qword $0
+
+.org $0
+init:
+ cps ; Clear the Processor Status register.
+
+start:
+ lda #0 ; Clear the accumulator.
+ ldb.q y ; b=1.
+fib:
+ aab ; Add x with y.
+ ldb.q y
+ stb.q x ; x=y.
+ sta.q y ; y=z.
+ tab
+ lda.q x
+ bcs start ; Start all over again, if the carry flag was set.
+ jmp fib ; Otherwise, keep looping.
+done
diff --git a/test/ind-addr.s b/test/ind-addr.s
new file mode 100644
index 0000000..0c9365b
--- /dev/null
+++ b/test/ind-addr.s
@@ -0,0 +1,27 @@
+.org $0
+reset:
+ cps
+ lda #1
+ ldb #1
+main:
+ jsr (rot)
+ jmp main
+
+rotate_left:
+ rlb
+ rts
+
+rotate_right:
+ rrb
+ rts
+
+.org $1000
+rot:
+ .qword rotate_left
+r
+.org $0
+v
+.org $1000
+v
+done
+
diff --git a/test/input.s b/test/input.s
index 20ab3d1..a8b0830 100644
--- a/test/input.s
+++ b/test/input.s
@@ -4,22 +4,26 @@
; mr b0nk 500 <b0nk@b0nk.xyz>
+; Input buffer.
+.org $4000
+buffer:
+
; Initalize some variables.
-.org $1000
+.org $0
scr_row:
.byte $0
scr_col:
.byte $0
a:
- .word $0
+ .byte $0
b:
- .word $0
+ .byte $0
c:
- .word $0
+ .byte $0
d:
- .word $0
+ .byte $0
e:
- .word $0
+ .byte $0
string:
.byte "Please, type something.\n"
string2:
@@ -27,9 +31,9 @@ string2:
end:
.byte $0
-; Input buffer.
-.org $0000
-buffer:
+; String Pointer
+ptr:
+ .qword buffer
; Main program
.org $8000
@@ -37,35 +41,32 @@ reset:
cps
ldx.w #$FFFF
txs
- ldy #$0
+ ldy #0
+ lda #0
clr_buf:
- lda #$0
- cpy.w #$1000
+ cpy.w #$FFF
beq start
- sta buffer, y
+ sta (ptr), y
iny
jmp clr_buf
start:
- ldx.w #$0 ; Reset x.
- ldy.w #$0 ; Reset y.
+ tax ; Reset x.
+ tay ; Reset y.
jmp print
rset_a:
- lda #$10
-delay:
- beq read
- dec
- jmp delay
-sleep:
- lda end
- bne spin ; Are we done with getting input?
+ lda #1
+
read:
lda $C000 ; Get control register.
beq rset_a ; Loop until we get a character.
- lda #$0
+ lda #0
sta $C000
jmp getchar ; We got a key.
+sleep:
+ lda end
+ bne spin ; Are we done with getting input?
print:
lda string, x ; Get character at offset x.
@@ -78,7 +79,7 @@ print:
jmp print
inc_row:
inc scr_row
- lda #$0
+ lda #0
sta scr_col
jmp print ; Keep printing more characters.
@@ -88,26 +89,26 @@ getchar:
beq esc
cmp #$A
beq nl ; Did the user type a newline?
- cmp #$8
+ cmp #8
beq bs ; Did the user type a backspace?
cmp #$7F
beq bs ; Did the user type a backspace?
echo:
sta a
ldx scr_col
- cpx #$4F
+ cpx #79
bne echo_print
linewrap:
inc scr_row
- ldx #$0
+ ldx #0
stx scr_col
lda scr_row
- jsr update_pos
+ jsl update_pos
echo_print:
lda a
sta $C001 ; Echo typed character.
inc scr_col ; Increment the cursor's x coordinate.
- sta buffer, y ; Store typed character into the input buffer.
+ sta (ptr), y ; Store typed character into the input buffer.
iny
jmp rset_a ; Start getting user input.
@@ -117,22 +118,22 @@ esc:
beq read ; We have an error, so discard it, and go back to getting user input.
lda $C002 ; Get the escape code.
sta c ; Store the escape code, until we need it.
- jsr isup ; Check if the user pressed up.
+ jsl isup ; Check if the user pressed up.
lda d
- cmp #$0
+ cmp #0
bne esc_end
- jsr isdown ; Check if the user pressed down.
+ jsl isdown ; Check if the user pressed down.
lda d
- cmp #$0
+ cmp #0
bne esc_end
- lda #$0
- jsr isleft ; Check if the user pressed left.
+ lda #0
+ jsl isleft ; Check if the user pressed left.
lda d
- cmp #$0
+ cmp #0
bne esc_end
- jsr isright ; Check if the user pressed right.
+ jsl isright ; Check if the user pressed right.
esc_end:
- lda #$0
+ lda #0
sta d
jmp rset_a ; Go back to getting user input.
@@ -143,27 +144,27 @@ isup:
cmp #$41 ; Did the user press the up arrow key?
beq up ; Yes, so move the cursor up.
isup_done:
- rts ; End of isup.
+ rtl ; End of isup.
isdown:
lda scr_row ; Start checking the y coordinate of the cursor.
- cmp #$17 ; Is the cursor at the bottom of the screen?
+ cmp #23 ; Is the cursor at the bottom of the screen?
beq isdown_done ; Yes, so return.
lda c ; No, so load the escape code back into the accumulator.
cmp #$42 ; Did the user press the down arrow key?
beq down ; Yes, so move the cursor down.
isdown_done:
- rts ; End of isdown.
+ rtl ; End of isdown.
isright:
lda scr_col ; Start checking the x coordinate of the cursor.
- cmp #$4F ; Is the cursor at the far right of the screen?
+ cmp #79 ; Is the cursor at the far right of the screen?
beq isright_end ; Yes, so return.
lda c ; No, so load the escape code back into the accumulator.
cmp #$43 ; Did the user press the right arrow key?
beq right ; Yes, so move the cursor right.
isright_end:
- rts ; End of isright.
+ rtl ; End of isright.
isleft:
lda scr_col ; Is the cursor at the far left of the screen?
@@ -172,36 +173,28 @@ isleft:
cmp #$44 ; Did the user press the left arrow key?
beq left ; Yes, so move the cursor left.
isleft_done:
- rts ; End of isleft.
+ rtl ; End of isleft.
up:
dec scr_row
- lda #$0
- sta e
- jsr update_pos
- lda #$1
+ jsl update_pos
+ lda #1
sta d
jmp isup_done
down:
inc scr_row
- lda #$1
- sta e
- jsr update_pos
- lda #$1
+ jsl update_pos
+ lda #1
sta d
jmp isdown_done
right:
inc scr_col
- lda #$2
- sta e
- jsr update_pos
+ jsl update_pos
jmp isright_end
left:
dec scr_col
- lda #$3
- sta e
- jsr update_pos
- lda #$1
+ jsl update_pos
+ lda #1
sta d
jmp isleft_done
@@ -210,74 +203,65 @@ update_pos:
sta $C001 ; to the screen.
lda #$5B ; Print '['
sta $C001 ; to the screen, and start the escape sequence.
- jsr getrow ; Start printing the row number to the screen.
- jsr getcol ; Start printing the column number to the screen.
+ jsl getrow ; Start printing the row number to the screen.
+ jsl getcol ; Start printing the column number to the screen.
lda #$48 ; Print 'H'
sta $C001 ; to the screen.
- rts ; End of update_pos.
+ rtl ; End of update_pos.
getrow:
lda scr_row ; Get the cursor's y coordinate.
- div #$A ; Divide A by 10.
+ div #10 ; Divide A by 10.
adc #$30 ; Convert it to ascii, and
sta $C001 ; print to the screen.
tba ; Get the remainder.
adc #$30 ; Convert it to ascii, and
sta $C001 ; print to the screen.
- rts ; End of getrow.
+ rtl ; End of getrow.
getcol:
lda #$3B ; Print ';'
sta $C001 ; to the screen.
lda scr_col ; Get the cursor's x coordinate.
- div #$A ; Divide A by 10.
+ div #10 ; Divide A by 10.
adc #$30 ; Convert it to ascii, and
sta $C001 ; print to the screen.
tba ; Get the remainder.
adc #$30 ; Convert it to ascii, and
sta $C001 ; print to the screen.
- rts ; End of getrow.
+ rtl ; End of getrow.
-uint_to_bcd:
- div #$A ; Divide A by 10.
- lsl #$4 ; Shift the result left by 4 bits.
- sta a ; Store the result for later.
- tba ; Get the remainder.
- sta b ; Store the remainder for later.
- lda a ; Get the result.
- ora b ; Or the result, with the remainder.
- rts ; We've converted the value to BCD, so return.
nl:
lda #$A
sta $C001
inc scr_row
- lda #$0 ; Replace newline with a null terminator.
- sta buffer, y ; Store said terminator into the input buffer.
+ lda #0 ; Replace newline with a null terminator.
+ sta (ptr), y ; Store said terminator into the input buffer.
sta scr_col
- ldy.w #$0 ; Reset y, to print the result.
+ ldy.w #0 ; Reset y, to print the result.
jmp result
back:
sta $C001 ; Print backspace.
- lda #$0 ; Put a null terminator, in place of the backspace.
- sta buffer, y ; Place it into the input buffer.
+ lda #0 ; Put a null terminator, in place of the backspace.
+ sta (ptr), y ; Place it into the input buffer.
dey ; Decrement buffer offset.
dec scr_col
jmp read ; Get next character.
bs:
- cpy #$0 ; Are we at the start of the buffer?
+ cpy #0 ; Are we at the start of the buffer?
beq rset_a ; We are, so do not store the backspace into the buffer.
jmp back ; We are not, so add the backspace to the buffer.
result:
ldx scr_col
- cpx #$4F
+ cpx #79
bne result_print
linewrap2:
inc scr_row
ldx #$0
stx scr_col
- jsr update_pos
+ jsl update_pos
result_print:
lda string2, y
beq rset_y ; Reset y, if we hit the null terminator.
@@ -288,20 +272,20 @@ result_print:
rset_y:
- ldy.w #$0 ; Reset y.
+ ldy.w #0 ; Reset y.
jmp print_buf ; Print the input buffer.
print_buf:
ldx scr_col
- cpx #$4F
+ cpx #79
bne buf_print
linewrap3:
inc scr_row
- ldx #$0
+ ldx #0
stx scr_col
- jsr update_pos
+ jsl update_pos
buf_print:
- lda buffer, y ; Get a character from the input buffer.
+ lda (ptr), y ; Get a character from the input buffer.
beq spin ; Are we done with printing the buffer?
sta $C001 ; Print said character.
inc scr_col ; Increment the cursor's x coordinate.
@@ -310,11 +294,11 @@ buf_print:
scr_to_buf:
tax
- mul #$50
+ mul #80
adc scr_col
tay
txa
- rts
+ rtl
spin:
nop
@@ -322,6 +306,20 @@ spin:
nop
jmp spin
+.org $1000
+v
+.org $1100
+v
+.org $1200
+v
+.org $8000
+v
+.org $8100
+v
+.org $8200
+v
+.org $8300
+v
.org $FFC0
.qword reset
@@ -333,15 +331,8 @@ spin:
.qword spin
.qword spin
.qword spin
-
-.org $FFA0
-.qword irq_routine
-;.org $8000
-;viewmem
-;.org $8100
-;viewmem
-;.org $8200
-;viewmem
-;q
-done
+.org $FF50
+v
+;done
+q
diff --git a/test/test-stack.s b/test/test-stack.s
index 5c7e0fd..193cca7 100644
--- a/test/test-stack.s
+++ b/test/test-stack.s
@@ -2,10 +2,9 @@ init:
cps
ldx.w #$FFFF
txs
-ldx.d #$00
loop:
-iax
+iab
pha #$08
ply #$08
jmp loop
diff --git a/test/the-tests.s b/test/the-tests.s
new file mode 100644
index 0000000..ae31e26
--- /dev/null
+++ b/test/the-tests.s
@@ -0,0 +1,35 @@
+.org $0
+init:
+ cps
+
+lstart:
+ lda #1
+ tab
+
+lshft:
+ llb
+ bcs rstart
+ jmp lshft
+
+rstart:
+ tba
+ lsl #63
+
+rshft:
+ lrb
+ bcs lstart
+ jmp rshft
+
+.org $FFC0
+.qword init
+
+.org $FF50
+.qword init
+.qword init
+.qword init
+.qword init
+.qword init
+.qword init
+.qword init
+.qword init
+done