Fix error with CJNE instruction
[emu8051.git] / src / opcode2c.pl
index 8aaae22..a80f651 100755 (executable)
@@ -1,14 +1,51 @@
 #!/usr/bin/perl
-
+#
+# Copyright (C) 1999 Jonathan St-André
+# Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
+#
+# 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 St, Fifth Floor, Boston, MA 02110-1301, USA.
 
 open INST_DEF, ">instructions_8051.h" or die "Error creating <instructions_8051.h> : $!\n";
 open INST_IMP, ">instructions_8051.c" or die "Error creating <instructions_8051.c> : $!\n";
 open OPCODELST, "opcodes.lst" or die "Error opening <opcodes.lst> : $!\n";
 open DISASM_H, ">disasm.h" or die "Error creating <disasm.h> : $!\n";
 
-print INST_IMP "/* instructions_8051.c */\n\n\n";
-print INST_IMP "/* Do not modify this file directly, as it was created by opcode2c.pl\n";
-print INST_IMP " * Any modifications made directly to this file will be lost. */\n\n\n";
+# Header for instructions_8051.c
+print INST_IMP "/*\n";
+print INST_IMP " * instructions_8051.c\n";
+print INST_IMP " *\n";
+print INST_IMP " * Do not modify this file directly, as it was created by opcode2c.pl\n";
+print INST_IMP " * Any modifications made directly to this file will be lost.\n";
+print INST_IMP " *\n";
+print INST_IMP " * Copyright (C) 1999 Jonathan St-André\n";
+print INST_IMP " * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>\n";
+print INST_IMP " *\n";
+print INST_IMP " * This program is free software; you can redistribute it and/or modify\n";
+print INST_IMP " * it under the terms of the GNU General Public License as published by\n";
+print INST_IMP " * the Free Software Foundation; either version 2 of the License, or\n";
+print INST_IMP " * (at your option) any later version.\n";
+print INST_IMP " *\n";
+print INST_IMP " * This program is distributed in the hope that it will be useful,\n";
+print INST_IMP " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n";
+print INST_IMP " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n";
+print INST_IMP " * GNU General Public License for more details.\n";
+print INST_IMP " *\n";
+print INST_IMP " * You should have received a copy of the GNU General Public License\n";
+print INST_IMP " * along with this program; if not, write to the Free Software\n";
+print INST_IMP " * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.\n";
+print INST_IMP "*/\n\n";
 print INST_IMP "/* Define only here, for not having extern scope on local variables. */\n";
 print INST_IMP "#define INSTRUCTIONS_8051_M 1\n\n\n";
 print INST_IMP "#include \"reg8051.h\"\n";
@@ -16,12 +53,32 @@ print INST_IMP "#include \"cpu8051.h\"\n";
 print INST_IMP "#include \"memory.h\"\n";
 print INST_IMP "#include \"instructions_8051.h\"\n\n\n";
 
-print DISASM_H "/* disasm.h */\n\n\n";
-print DISASM_H "/* Do not modify this file directly, as it was created by opcode2c.pl\n";
-print DISASM_H " * Any modifications made directly to this file will be lost. */\n\n\n";
+# Header for disasm.h
+print DISASM_H "/*\n";
+print DISASM_H " * disasm.h\n";
+print DISASM_H " *\n";
+print DISASM_H " * Do not modify this file directly, as it was created by opcode2c.pl\n";
+print DISASM_H " * Any modifications made directly to this file will be lost.\n";
+print DISASM_H " *\n";
+print DISASM_H " * Copyright (C) 1999 Jonathan St-André\n";
+print DISASM_H " * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>\n";
+print DISASM_H " *\n";
+print DISASM_H " * This program is free software; you can redistribute it and/or modify\n";
+print DISASM_H " * it under the terms of the GNU General Public License as published by\n";
+print DISASM_H " * the Free Software Foundation; either version 2 of the License, or\n";
+print DISASM_H " * (at your option) any later version.\n";
+print DISASM_H " *\n";
+print DISASM_H " * This program is distributed in the hope that it will be useful,\n";
+print DISASM_H " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n";
+print DISASM_H " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n";
+print DISASM_H " * GNU General Public License for more details.\n";
+print DISASM_H " *\n";
+print DISASM_H " * You should have received a copy of the GNU General Public License\n";
+print DISASM_H " * along with this program; if not, write to the Free Software\n";
+print DISASM_H " * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.\n";
+print DISASM_H "*/\n\n";
 print DISASM_H "#ifndef DISASM_H\n";
-print DISASM_H "#define DISASM_H 1\n\n\n";
-
+print DISASM_H "#define DISASM_H 1\n\n";
 
 $nbinst=0;
 $nbaddr=0;
@@ -59,7 +116,7 @@ while($ligne=<OPCODELST>) {
            $instargs[($instnumb << 2) + $i + 1]=$argstypes{$argslist[$i]};
        }
     }
-       
+
     if (not exists $insttext{$wordlist[2]}) {
        $insttext[$nbinst]=$wordlist[2];
        $insttext{$wordlist[2]}=$nbinst++;
@@ -79,9 +136,12 @@ while($ligne=<OPCODELST>) {
     $instnumb++;
 }
 # ------------------------------------------------------------------------------
-print DISASM_H "// For all 256 opcodes, the value in this table gives the instruction type\n";
-print DISASM_H "// ex.: MOV, INC, CLR, CPL,...\n";
-print DISASM_H "// To know what is the instruction type, use the number as an offset in the InstTextTbl[]\n";
+print DISASM_H "/*\n";
+print DISASM_H " * For all 256 opcodes, the value in this table gives the instruction type\n";
+print DISASM_H " * ex.: MOV, INC, CLR, CPL,...\n";
+print DISASM_H " * To know what is the instruction type, use\n";
+print DISASM_H " * the number as an offset in the InstTextTbl[]\n";
+print DISASM_H " */\n";
 print DISASM_H "static int InstTypesTbl[] = {\n";
 for($i=0;$i<256;$i++) {
     print DISASM_H " $insttype[$i]";
@@ -89,9 +149,9 @@ for($i=0;$i<256;$i++) {
     if (($i+1) % 16 == 0) { print DISASM_H "\n"; }
 }
 print DISASM_H "};\n";
-print DISASM_H "\n\n";
+print DISASM_H "\n";
 # ------------------------------------------------------------------------------
-print DISASM_H "// Size(in bytes) of each instruction (offset in table is instruction opcode)\n";
+print DISASM_H "/* Size(in bytes) of each instruction (offset in table is instruction opcode) */\n";
 print DISASM_H "static int InstSizesTbl[] = {\n";
 for($i=0;$i<256;$i++) {
     print DISASM_H " $nbbytes[$i]";
@@ -99,9 +159,9 @@ for($i=0;$i<256;$i++) {
     if (($i+1) % 16 == 0) { print DISASM_H "\n"; }
 }
 print DISASM_H "};\n";
-print DISASM_H "\n\n";
+print DISASM_H "\n";
 # ------------------------------------------------------------------------------
-print DISASM_H "// List of instructions types referenced by InstTypesTbl[]\n";
+print DISASM_H "/* List of instructions types referenced by InstTypesTbl[] */\n";
 $nbelement=@insttext;
 print DISASM_H "\#define InstTextTblLength $nbelement\n";
 $elementnb=0;
@@ -112,14 +172,16 @@ foreach $instruc (@insttext) {
     print DISASM_H "\n";
 }
 print DISASM_H "};\n";
-print DISASM_H "\n\n";
+print DISASM_H "\n";
 # ------------------------------------------------------------------------------
-print DISASM_H "// Table describing all arguments types of an instruction\n";
-print DISASM_H "// The table is indexed InstArgTbl[ opcode * 4]\n";
-print DISASM_H "// InstArgTbl[opcode*4 + 1] gives the number of arguments the instruction has\n";
-print DISASM_H "// InstArgTbl[opcode*4 + i] for i=1,2 and 3 give the type of each argument\n";
-print DISASM_H "// for most instructions, the 3rd argument isn't used\n";
-print DISASM_H "// the argument type is referecing to ArgsTextTbl[]\n";
+print DISASM_H "/*\n";
+print DISASM_H " * Table describing all arguments types of an instruction\n";
+print DISASM_H " * The table is indexed InstArgTbl[ opcode * 4]\n";
+print DISASM_H " * InstArgTbl[opcode*4 + 1] gives the number of arguments the instruction has\n";
+print DISASM_H " * InstArgTbl[opcode*4 + i] for i=1,2 and 3 give the type of each argument\n";
+print DISASM_H " * for most instructions, the 3rd argument isn't used\n";
+print DISASM_H " * the argument type is referecing to ArgsTextTbl[]\n";
+print DISASM_H " */\n";
 print DISASM_H "\#define InstArgTblLength 256\n";
 print DISASM_H "static int InstArgTbl[] = {\n";
 for($i=0;$i<1024;$i++) {
@@ -128,10 +190,12 @@ for($i=0;$i<1024;$i++) {
     if (($i+1) % 16 == 0) { print DISASM_H "\n"; }
 }
 print DISASM_H "};\n";
-print DISASM_H "\n\n";
+print DISASM_H "\n";
 # ------------------------------------------------------------------------------
-print DISASM_H "// List all types of arguments available to instructions\n";
-print DISASM_H "// Referenced by InstArgsTbl[]\n";
+print DISASM_H "/*\n";
+print DISASM_H " * List all types of arguments available to instructions\n";
+print DISASM_H " * Referenced by InstArgsTbl[]\n";
+print DISASM_H " */\n";
 $nbelement=@argstypes;
 print DISASM_H "\#define ArgsTextTblLength $nbelement\n";
 $elementnb=0;
@@ -142,7 +206,7 @@ foreach $args (@argstypes) {
     print DISASM_H "\n";
 }
 print DISASM_H "};\n";
-print DISASM_H "\n\n";
+print DISASM_H "\n";
 
 # ------------------------------------------------------------------------------
 for ($i=0 ; $i< 256; $i++) {
@@ -150,9 +214,7 @@ for ($i=0 ; $i< 256; $i++) {
     print INST_IMP " * Instruction \"$a_instruction[$i]\" takes $a_cycles[$i] cycle(s) and $a_bytes[$i] byte(s).\n";
     print INST_IMP " ","*"x76,"/\n";
     print INST_IMP "int\n";
-    print INST_IMP "cpu8051_OP_$a_opcodehex[$i]( void )\n";
-# TEST hugo new...
-#    print INST_DEF "int OP_$a_opcodehex[$i]( );\n";
+    print INST_IMP "cpu8051_OP_$a_opcodehex[$i](void)\n";
     print INST_IMP "{\n";
 
     if( $i == 0x85 ) {
@@ -187,7 +249,7 @@ for ($i=0 ; $i< 256; $i++) {
            if ($op_destination == 5) { # @R1
                print INST_IMP "unsigned char destination = cpu8051_ReadI ( cpu8051_ReadD( BANKPSW + _R1_ ) );\n";
            }
-           
+
            if ($op_destination == 6) { # R0
                print INST_IMP "unsigned char destination = cpu8051_ReadD( BANKPSW + _R0_ );\n";
            }
@@ -218,7 +280,7 @@ for ($i=0 ; $i< 256; $i++) {
            }
            if ($op_destination == 15) { # reladdr
                print INST_IMP "cpu8051.pc++;\n";
-               print INST_IMP "unsigned int destination = ( ( memory_read8( PGM_MEM_ID, cpu8051.pc - 1 ) + cpu8051.pc ) & 0xFF ) + ( cpu8051.pc & 0xFF00 );\n";
+               print INST_IMP "unsigned int destination = ((char) memory_read8(PGM_MEM_ID, cpu8051.pc - 1)) + cpu8051.pc;\n";
            }
            if ($op_destination == 16) { # #data
                print INST_IMP "unsigned char destination = memory_read8( PGM_MEM_ID, cpu8051.pc++ );\n";
@@ -303,7 +365,7 @@ for ($i=0 ; $i< 256; $i++) {
            }
            if ($op_source == 15) { # reladdr
                print INST_IMP "(cpu8051.pc)++;\n";
-               print INST_IMP "unsigned int source = ( ( memory_read8( PGM_MEM_ID, cpu8051.pc - 1 ) + cpu8051.pc ) & 0xFF ) + ( cpu8051.pc & 0xFF00 );\n";
+               print INST_IMP "unsigned int source = ((char) memory_read8(PGM_MEM_ID, cpu8051.pc - 1)) + cpu8051.pc;\n";
            }
            if ($op_source == 16) { # #data
                print INST_IMP "unsigned char source = memory_read8( PGM_MEM_ID, (cpu8051.pc)++ );\n";
@@ -545,10 +607,10 @@ for ($i=0 ; $i< 256; $i++) {
 
        # CJNE
        if ($insttype[$i] == 34) {
-           print INST_IMP "unsigned int reladdr = ( ( memory_read8( PGM_MEM_ID, cpu8051.pc ) + ( ( cpu8051.pc + 1 ) & 0x00FF ) ) & 0x00FF ) + ( ( cpu8051.pc + 1 ) & 0xFF00 );\n";
+           print INST_IMP "unsigned int reladdr = ((char) memory_read8(PGM_MEM_ID, cpu8051.pc)) + (cpu8051.pc + 1);\n";
            print INST_IMP "cpu8051_WriteD( _PSW_, ( cpu8051_ReadD( _PSW_ ) & 0x7F ) );\n";
            print INST_IMP "if ( destination < source ) cpu8051_WriteD( _PSW_, ( cpu8051_ReadD( _PSW_ ) | 0x80 ) );\n";
-           print INST_IMP "if ( destination != source ) cpu8051.pc = reladdr;\n";
+           print INST_IMP "if ( destination != source ) cpu8051.pc = reladdr; else cpu8051.pc++; \n";
        }
 
        # PUSH
@@ -757,17 +819,38 @@ for ($i=0 ; $i< 256; $i++) {
 # ------------------------------------------------------------------------------
 
 
+# Header for instructions_8051.h
+print INST_DEF "/*\n";
+print INST_DEF " * instructions_8051.h\n";
+print INST_DEF " *\n";
+print INST_DEF " * Do not modify this file directly, as it was created by opcode2c.pl\n";
+print INST_DEF " * Any modifications made directly to this file will be lost.\n";
+print INST_DEF " *\n";
+print INST_DEF " * Copyright (C) 1999 Jonathan St-André\n";
+print INST_DEF " * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>\n";
+print INST_DEF " *\n";
+print INST_DEF " * This program is free software; you can redistribute it and/or modify\n";
+print INST_DEF " * it under the terms of the GNU General Public License as published by\n";
+print INST_DEF " * the Free Software Foundation; either version 2 of the License, or\n";
+print INST_DEF " * (at your option) any later version.\n";
+print INST_DEF " *\n";
+print INST_DEF " * This program is distributed in the hope that it will be useful,\n";
+print INST_DEF " * but WITHOUT ANY WARRANTY; without even the implied warranty of\n";
+print INST_DEF " * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n";
+print INST_DEF " * GNU General Public License for more details.\n";
+print INST_DEF " *\n";
+print INST_DEF " * You should have received a copy of the GNU General Public License\n";
+print INST_DEF " * along with this program; if not, write to the Free Software\n";
+print INST_DEF " * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.\n";
+print INST_DEF "*/\n\n";
 
-print INST_DEF "/* instructions_8051.h */\n\n\n";
-print INST_DEF "/* Do not modify this file directly, as it was created by opcode2c.pl\n";
-print INST_DEF " * Any modifications made directly to this file will be lost. */\n\n\n";
 print INST_DEF "#ifndef INSTRUCTIONS_8051_H\n";
 print INST_DEF "#define INSTRUCTIONS_8051_H 1\n\n\n";
-print INST_DEF "#define BANKPSW ( cpu8051_ReadD( _PSW_ ) & 0x18 )\n\n";
-print INST_DEF "typedef int (*OPCODE_FP)( void );\n\n\n";
+print INST_DEF "#define BANKPSW (cpu8051_ReadD(_PSW_) & 0x18)\n\n";
+print INST_DEF "typedef int (*OPCODE_FP)(void);\n\n\n";
 for( $i=0; $i<256; $i++ ) {
     print INST_DEF "int\n";
-    print INST_DEF "cpu8051_OP_$a_opcodehex[$i]( void );\n\n";
+    print INST_DEF "cpu8051_OP_$a_opcodehex[$i](void);\n\n";
 }
 print INST_DEF "\n";
 print INST_DEF "/* Exported variables. */\n";
@@ -790,16 +873,9 @@ print INST_DEF "#endif\n\n\n";
 
 print INST_DEF "#endif /* INSTRUCTIONS_8051_H */\n";
 
-
-
-
-
-
-print DISASM_H "\n\n#endif /* DISASM_H */\n";
+print DISASM_H "#endif /* DISASM_H */\n";
 
 close DISASM_H;
 close OPCODELST;
 close INST_DEF;
 close INST_IMP;
-
-