Replace disam.h with opcodes{h,c}
authorHugo Villeneuve <hugo@hugovil.com>
Sat, 15 Feb 2014 06:43:32 +0000 (01:43 -0500)
committerHugo Villeneuve <hugo@hugovil.com>
Sat, 15 Feb 2014 06:43:32 +0000 (01:43 -0500)
Also rename opcode2c.pl -> opcodes2c.pl

src/common/Makefile.am
src/common/cpu8051.c
src/common/cpu8051.h
src/common/opcode2c.pl [deleted file]
src/common/opcodes2c.pl [new file with mode: 0755]
src/gtk/pgmwin.c

index aa19efe..267c498 100644 (file)
@@ -7,7 +7,8 @@ AM_CPPFLAGS = \
 noinst_LIBRARIES = libemu8051.a
 
 libemu8051_a_SOURCES = \
-       instructions_8051.c \
+       instructions_8051.c instructions_8051.h \
+       opcodes.c opcodes.h \
        options.c options.h \
        log.c log.h \
        hexfile.c hexfile.h \
@@ -21,8 +22,9 @@ libemu8051_a_SOURCES = \
        reg8051.h
 
 # These files are generated automatically by a perl script.
-instructions_8051.c instructions_8051.h disasm.h : opcode2c.pl opcodes.lst
-       ./opcode2c.pl
+instructions_8051.c instructions_8051.h opcodes.h opcodes.c : opcodes2c.pl opcodes.lst
+       @echo "  PERL     opcodes2c.pl"
+       @./opcodes2c.pl
 
 CLEANFILES = *~
 
@@ -30,10 +32,9 @@ MAINTAINERCLEANFILES = \
        Makefile.in \
        instructions_8051.c \
        instructions_8051.h \
-       disasm.h
+       opcodes.h \
+       opcodes.c
 
 EXTRA_DIST = \
-       opcode2c.pl \
-       opcodes.lst \
-       instructions_8051.h \
-       disasm.h
+       opcodes2c.pl \
+       opcodes.lst
index fb387ee..288c11e 100644 (file)
@@ -20,7 +20,7 @@
 #include "memory.h"
 #include "psw.h"
 #include "timers.h"
-#include "disasm.h"
+#include "opcodes.h"
 #include "options.h"
 #include "instructions_8051.h"
 
@@ -407,18 +407,11 @@ cpu8051_int_mem_bit_info(uint8_t bit_address, char *text)
        sprintf(&text[len], ".%X", bit_address);
 }
 
-/* Get instruction size from opcode */
-int
-cpu8051_get_instruction_size(unsigned char opcode)
-{
-       return instr_size[opcode];
-}
-
 /* Display instruction mnemonic. */
 int
 cpu8051_disasm_mnemonic(unsigned char opcode, char *buf)
 {
-       return sprintf(buf, "%s", instr_type_str[instr_type_id[opcode]]);
+       return sprintf(buf, "%s", opcodes_get_instr_type_str(opcode));
 }
 
 /* Disasm instruction arguments starting at address into a text string */
@@ -452,8 +445,9 @@ cpu8051_disasm_args(unsigned int address, char *buf)
                return;
        }
 
-       for (i = 1; i <= instr_arg_type_id[args_table_offset]; i++) {
-               switch (instr_arg_type_id[args_table_offset + i]) {
+       for (i = 1; i <= opcodes_get_instr_arg_type_id(args_table_offset);
+            i++) {
+               switch (opcodes_get_instr_arg_type_id(args_table_offset + i)) {
                case ADDR11: {
                        len += sprintf(&buf[len],
                                       "%.4XH", ((opcode << 3) & 0xF00) +
@@ -517,13 +511,12 @@ cpu8051_disasm_args(unsigned int address, char *buf)
                        break;
                }
                default: {
-                       len += sprintf(
-                               &buf[len], "%s",
-                               instr_arg_type_str[instr_arg_type_id[
-                                               args_table_offset + i]]);
+                       len += sprintf(&buf[len], "%s",
+                                      opcodes_get_instr_arg_type_str(
+                                              args_table_offset + i));
                }
                }
-               if (i < instr_arg_type_id[args_table_offset])
+               if (i < opcodes_get_instr_arg_type_id(args_table_offset))
                        len += sprintf(&buf[len], ",");
        }
 }
@@ -541,7 +534,7 @@ cpu8051_disasm(unsigned int address, char *text)
        len += sprintf(text, " %.4X ", address);
 
        opcode = mem_read8(PGM_MEM_ID, address);
-       inst_size = instr_size[opcode];
+       inst_size = opcodes_get_instr_size(opcode);
 
        /* Display hex bytes. */
        for (i = 0; i < inst_size; i++)
index 3348aee..ae17ead 100644 (file)
@@ -74,9 +74,6 @@ cpu8051_run(int instr_count, int (*interface_stop)(void));
 void
 cpu8051_reset(void);
 
-int
-cpu8051_get_instruction_size(unsigned char opcode);
-
 int
 cpu8051_disasm_mnemonic(unsigned char opcode, char *buf);
 
diff --git a/src/common/opcode2c.pl b/src/common/opcode2c.pl
deleted file mode 100755 (executable)
index 23800cc..0000000
+++ /dev/null
@@ -1,855 +0,0 @@
-#!/usr/bin/perl
-#
-# Copyright (C) 1999 Jonathan St-AndrĂ©
-# Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
-#
-# This file is released under the GPLv2
-
-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";
-
-# Write GPL license
-# Argument 0 is file descriptor
-sub write_header
-{
-    my $fd = $_[0];
-
-    print $fd " *\n";
-    print $fd " * Do not modify this file directly, as it was created by opcode2c.pl\n";
-    print $fd " * Any modifications made directly to this file will be lost.\n";
-    print $fd " *\n";
-    print $fd " * Copyright (C) 1999 Jonathan St-AndrĂ©\n";
-    print $fd " * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>\n";
-    print $fd " *\n";
-    print $fd " * This file is released under the GPLv2\n";
-    print $fd " */\n\n";
-}
-
-# Write C function source code line to INST_IMP file.
-# Prefix each line with a tab (indentation) and add newline character at the end.
-sub cfw
-{
-    print INST_IMP "\t",$_[0],"\n";
-}
-
-# Header for instructions_8051.c
-print INST_IMP "/*\n";
-print INST_IMP " * instructions_8051.c\n";
-write_header(INST_IMP);
-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";
-print INST_IMP "#include \"cpu8051.h\"\n";
-print INST_IMP "#include \"memory.h\"\n";
-print INST_IMP "#include \"psw.h\"\n";
-print INST_IMP "#include \"operations.h\"\n";
-print INST_IMP "#include \"instructions_8051.h\"\n\n\n";
-
-# Header for disasm.h
-print DISASM_H "/*\n";
-print DISASM_H " * disasm.h\n";
-write_header(DISASM_H);
-print DISASM_H "#ifndef DISASM_H\n";
-print DISASM_H "#define DISASM_H 1\n\n";
-
-# Column indexes in opcodes.lst table
-use constant COL_OPCODE => 0;
-use constant COL_INSTR  => 1;
-use constant COL_ARGS   => 2;
-
-use constant COL_COUNT_NO_ARGS => 4;
-
-$nbinst=0;
-$nbaddr=0;
-$nbargs=0;
-$instnumb=0;
-
-# Read file describing each instruction/opcode
-
-# Discard first two lines, which are comments
-$ligne = <OPCODELST>;
-$ligne = <OPCODELST>;
-
-while($ligne=<OPCODELST>) {
-    chop $ligne;
-
-    if (length $ligne < 2) {
-        next;
-    }
-
-    @wordlist = split ' ',$ligne;
-    $nbword = @wordlist;
-    $instruction = $wordlist[COL_INSTR];
-
-    for ($i = (COL_INSTR + 1); $i < ($nbword - 2); $i++) {
-        $instruction = "$instruction $wordlist[$i]";
-    }
-
-    $a_instruction[$instnumb] = $instruction;
-    $a_bytes[$instnumb] = $wordlist[$nbword - 2];
-    $a_cycles[$instnumb] = $wordlist[$nbword - 1];
-    $a_opcodehex[$instnumb] = $wordlist[COL_OPCODE];
-
-    $instfunction[$instnumb] = "CPU8051::OP_$wordlist[COL_OPCODE]";
-
-    $instargs[$instnumb << 2] = $instargs[($instnumb << 2) + 1] =
-        $instargs[($instnumb << 2) + 2] = $instargs[($instnumb << 2) + 3] = 0;
-
-    if ($nbword > COL_COUNT_NO_ARGS) {
-       @argslist = split /\,/,$wordlist[COL_ARGS];
-       $argslistsize = @argslist;
-       $instargs[$instnumb << 2] = $argslistsize;
-       for ($i = 0; $i < $argslistsize; $i++) {
-           if (not exists $argstypes{$argslist[$i]}) {
-               $argstypes[$nbargs] = $argslist[$i];
-               $argstypes{$argslist[$i]} = $nbargs++;
-           }
-           $instargs[($instnumb << 2) + $i + 1] = $argstypes{$argslist[$i]};
-       }
-    }
-
-    if (not exists $insttext{$wordlist[COL_INSTR]}) {
-       $insttext[$nbinst] = $wordlist[COL_INSTR];
-       $insttext{$wordlist[COL_INSTR]} = $nbinst++;
-    }
-
-    $insttype[$instnumb] = $insttext{$wordlist[COL_INSTR]};
-
-    if (not exists $addrmode{$wordlist[COL_ARGS]}) {
-       $addrmode[$nbaddr] = $wordlist[COL_ARGS];
-       $addrmode{$wordlist[COL_ARGS]} = $nbaddr++;
-    }
-
-    $nbbytes[$instnumb] = $wordlist[$nbword - 2];
-
-    $instaddr[$instnumb] = $addrmode{$wordlist[COL_ARGS]};
-
-    $instnumb++;
-}
-
-# ------------------------------------------------------------------------------
-print DISASM_H "/* Size(in bytes) of each instruction (offset in table is instruction opcode) */\n";
-
-$nbelement = @nbbytes;
-
-print DISASM_H "static int instr_size[$nbelement] = {";
-
-for ($i = 0; $i < $nbelement; $i++) {
-    if ($i % 16 == 0) {
-        print DISASM_H "\n\t";
-    } else {
-        print DISASM_H " ";
-    }
-    print DISASM_H "$nbbytes[$i],";
-}
-print DISASM_H "\n";
-print DISASM_H "};\n";
-print DISASM_H "\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 instr_type_str[]\n";
-print DISASM_H " */\n";
-
-$nbelement = @insttype;
-
-print DISASM_H "static int instr_type_id[$nbelement] = {";
-
-for ($i = 0; $i < $nbelement; $i++) {
-    if ($i % 16 == 0) {
-        print DISASM_H "\n\t";
-    } else {
-        print DISASM_H " ";
-    }
-    print DISASM_H "$insttype[$i],";
-}
-print DISASM_H "\n";
-print DISASM_H "};\n";
-print DISASM_H "\n";
-
-# ------------------------------------------------------------------------------
-print DISASM_H "/* List of instructions types referenced by instr_type_id[] */\n";
-$nbelement = @insttext;
-$elementnb = 0;
-print DISASM_H "static char *instr_type_str[$nbelement] = {\n";
-
-foreach $instruc (@insttext) {
-    print DISASM_H "\t\"$instruc\"";
-    if ($elementnb++ < ($nbelement - 1)) {
-        print DISASM_H ",";
-    }
-    print DISASM_H "\n";
-}
-
-print DISASM_H "};\n";
-print DISASM_H "\n";
-
-# ------------------------------------------------------------------------------
-print DISASM_H "/*\n";
-print DISASM_H " * Table describing all arguments types of an instruction\n";
-print DISASM_H " * The table is indexed instr_arg_type_id[ opcode * 4]\n";
-print DISASM_H " * instr_arg_type_id[opcode*4 + 1] gives number of instruction arguments\n";
-print DISASM_H " * instr_arg_type_id[opcode*4 + i] for i=1,2 and 3 gives 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 instr_arg_type_str[]\n";
-print DISASM_H " */\n";
-
-$nbelement = @instargs;
-
-print DISASM_H "static int instr_arg_type_id[$nbelement] = {";
-
-for ($i = 0; $i < $nbelement; $i++) {
-    if ($i % 16 == 0) {
-        print DISASM_H "\n\t";
-    } else {
-        print DISASM_H " ";
-    }
-
-    print DISASM_H "$instargs[$i],";
-}
-print DISASM_H "\n";
-print DISASM_H "};\n";
-print DISASM_H "\n";
-
-# ------------------------------------------------------------------------------
-print DISASM_H "/*\n";
-print DISASM_H " * List all types of arguments available to instructions\n";
-print DISASM_H " * Referenced by instr_arg_type_id[]\n";
-print DISASM_H " */\n";
-
-$nbelement = @argstypes;
-$elementnb = 0;
-
-print DISASM_H "static char *instr_arg_type_str[$nbelement] = {\n";
-
-foreach $args (@argstypes) {
-    print DISASM_H "\t\"$args\"";
-    if ($elementnb++ < $nbelement-1) {
-        print DISASM_H ",";
-    }
-    print DISASM_H "\n";
-}
-print DISASM_H "};\n";
-print DISASM_H "\n";
-
-# ------------------------------------------------------------------------------
-for ($i = 0 ; $i < 256; $i++) {
-    print INST_IMP "/*","*"x76,"\n";
-    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";
-    print INST_IMP "{\n";
-
-    if( $i == 0x85 ) {
-       # Cas particulier pour MOV direct,direct -> src et dest sont inverses dans la memoire
-        print INST_IMP "  unsigned char srcaddr = mem_read8( PGM_MEM_ID, cpu8051.pc++ );\n";
-       print INST_IMP "  unsigned char source = mem_read_direct( srcaddr );\n";
-       print INST_IMP "  unsigned char destaddr = mem_read8( PGM_MEM_ID, cpu8051.pc++ );\n";
-       print INST_IMP "  unsigned char destination = mem_read_direct( destaddr );\n";
-       print INST_IMP "  destination = source;\n";
-       print INST_IMP "  mem_write_direct( destaddr, destination );\n";
-    }
-    else {
-       if ($instargs[$i*4] > 0) {
-           $op_destination=$instargs[$i*4+1];
-           if ($op_destination == 0) { # addr11
-               cfw("unsigned int addr11 = ( ( mem_read8( PGM_MEM_ID, cpu8051.pc - 1 ) << 3 ) & 0xF00 ) + mem_read8( PGM_MEM_ID, cpu8051.pc );");
-               cfw("cpu8051.pc++;");
-           }
-           if ($op_destination == 1) { # addr16
-               cfw("uint16_t addr16 = pgm_read_addr16(cpu8051.pc);");
-               cfw("cpu8051.pc += 2;");
-           }
-           if ($op_destination == 2) { # A
-               cfw("unsigned char destination = mem_read_direct( _ACC_ );");
-           }
-           if ($op_destination == 3) { # direct
-               cfw("unsigned char destaddr = mem_read8( PGM_MEM_ID, cpu8051.pc++ );");
-               cfw("unsigned char destination = mem_read_direct( destaddr );");
-           }
-           if ($op_destination == 4) { # @R0
-               cfw("unsigned char destination = mem_read_indirect ( mem_read_direct( BANKPSW + _R0_ ) );");
-           }
-           if ($op_destination == 5) { # @R1
-               cfw("unsigned char destination = mem_read_indirect ( mem_read_direct( BANKPSW + _R1_ ) );");
-           }
-           if ($op_destination == 6) { # R0
-               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R0_ );");
-           }
-           if ($op_destination == 7) { # R1
-               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R1_ );");
-           }
-           if ($op_destination == 8) { # R2
-               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R2_ );");
-           }
-           if ($op_destination == 9) { # R3
-               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R3_ );");
-           }
-           if ($op_destination == 10) { # R4
-               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R4_ );");
-           }
-           if ($op_destination == 11) { # R5
-               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R5_ );");
-           }
-           if ($op_destination == 12) { # R6
-               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R6_ );");
-           }
-           if ($op_destination == 13) { # R7
-               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R7_ );");
-           }
-           if ($op_destination == 14) { # bitaddr
-               cfw("unsigned char destination, dstbitaddr = mem_read8( PGM_MEM_ID, cpu8051.pc++ );");
-               cfw("destination = mem_read_bit( dstbitaddr );");
-           }
-           if ($op_destination == 15) { # reladdr
-               cfw("cpu8051.pc++;");
-               cfw("unsigned int destination = ((char) mem_read8(PGM_MEM_ID, cpu8051.pc - 1)) + cpu8051.pc;");
-           }
-           if ($op_destination == 16) { # #data
-               cfw("unsigned char destination = mem_read8( PGM_MEM_ID, cpu8051.pc++ );");
-           }
-           if ($op_destination == 17) { # C
-               cfw("unsigned char destination = psw_read_cy();");
-           }
-           if ($op_destination == 18) { # @A+DPTR
-               cfw("unsigned int destination = mem_read_direct( _ACC_ ) + mem_sfr_read_dptr();");
-           }
-            if ($op_destination == 20) { # AB
-                cfw("unsigned char destination = mem_read_direct( _ACC_ );");
-                cfw("unsigned char source = mem_read_direct( _B_ );");
-            }
-           if ($op_destination == 21) { # DPTR
-               cfw("unsigned int destination = mem_sfr_read_dptr();");
-           }
-           if ($op_destination == 23) { # /bitaddr
-               cfw("unsigned char destination, dstbitaddr = mem_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
-               cfw("destination = ( mem_read_bit( dstbitaddr ) ^ 1 );");
-           }
-           if ($op_destination == 24) { # @DPTR
-               cfw("unsigned char destination = mem_read_indirect(mem_sfr_read_dptr());");
-           }
-       }
-
-       if ($instargs[$i*4] > 1) {
-           $op_source=$instargs[$i*4+2];
-           if ($op_source == 0) { # addr11
-               cfw("unsigned int addr11 = ( ( mem_read8( PGM_MEM_ID, cpu8051.pc - 1 ) << 3 ) & 0xF00 ) + mem_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
-           }
-           if ($op_source == 1) { # addr16
-               cfw("uint16_t addr16 = pgm_read_addr16(cpu8051.pc);");
-               cfw("cpu8051.pc += 2;");
-           }
-           if ($op_source == 2) { # A
-               cfw("unsigned char source = mem_read_direct( _ACC_ );");
-           }
-           if ($op_source == 3) { # direct
-               cfw("unsigned char srcaddr = mem_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
-               cfw("unsigned char source = mem_read_direct( srcaddr );");
-           }
-           if ($op_source == 4) { # @R0
-               cfw("unsigned char source = mem_read_indirect ( mem_read_direct( BANKPSW + _R0_ ) );");
-           }
-           if ($op_source == 5) { # @R1
-               cfw("unsigned char source = mem_read_indirect ( mem_read_direct( BANKPSW + _R1_ ) );");
-           }
-           if ($op_source == 6) { # R0
-               cfw("unsigned char source = mem_read_direct( BANKPSW + _R0_ );");
-           }
-           if ($op_source == 7) { # R1
-               cfw("unsigned char source = mem_read_direct( BANKPSW + _R1_ );");
-           }
-           if ($op_source == 8) { # R2
-               cfw("unsigned char source = mem_read_direct( BANKPSW + _R2_ );");
-           }
-           if ($op_source == 9) { # R3
-               cfw("unsigned char source = mem_read_direct( BANKPSW + _R3_ );");
-           }
-           if ($op_source == 10) { # R4
-               cfw("unsigned char source = mem_read_direct( BANKPSW + _R4_ );");
-           }
-           if ($op_source == 11) { # R5
-               cfw("unsigned char source = mem_read_direct( BANKPSW + _R5_ );");
-           }
-           if ($op_source == 12) { # R6
-               cfw("unsigned char source = mem_read_direct( BANKPSW + _R6_ );");
-           }
-           if ($op_source == 13) { # R7
-               cfw("unsigned char source = mem_read_direct( BANKPSW + _R7_ );");
-           }
-
-           if ($op_source == 14) { # bitaddr
-               cfw("unsigned char source, srcbitaddr = mem_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
-               cfw("source = mem_read_bit( srcbitaddr );");
-           }
-           if ($op_source == 15) { # reladdr
-               cfw("(cpu8051.pc)++;");
-               cfw("unsigned int source = ((char) mem_read8(PGM_MEM_ID, cpu8051.pc - 1)) + cpu8051.pc;");
-           }
-           if ($op_source == 16) { # #data
-               cfw("unsigned char source = mem_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
-           }
-           if ($op_source == 17) { # C
-               cfw("unsigned char source = psw_read_cy();");
-           }
-           if ($op_source == 18) { # @A+DPTR
-               cfw("unsigned char source = mem_read8( PGM_MEM_ID, mem_read_direct( _ACC_ ) + mem_sfr_read_dptr());");
-           }
-           if ($op_source == 19) { # @A+PC
-               cfw("unsigned char source = mem_read8( PGM_MEM_ID, mem_read_direct( _ACC_ ) + ( ++cpu8051.pc ) );");
-           }
-           if ($op_source == 21) { # DPTR
-               cfw("unsigned int source = mem_sfr_read_dptr();");
-           }
-           if ($op_source == 22) { # #data16
-               cfw("uint16_t source = pgm_read_addr16(cpu8051.pc);");
-               cfw("cpu8051.pc += 2;");
-           }
-           if ($op_source == 23) { # /bitaddr
-               cfw("unsigned char source, srcbitaddr = mem_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
-               cfw("source = ( mem_read_bit( srcbitaddr ) ^ 1 );");
-           }
-           if ($op_source == 24) { # @DPTR
-               cfw("unsigned char source = mem_read_indirect(mem_sfr_read_dptr());");
-           }
-       }
-
-##############################################################################
-       $modifysrc=0;
-
-       # RR
-       if ($insttype[$i] == 3) {
-           cfw("destination = ( destination >> 1 ) | ( destination << 7 );");
-       }
-
-       # INC
-       if ($insttype[$i] == 4) {
-           cfw("destination++;");
-       }
-
-       # JBC
-       if ($insttype[$i] == 5) {
-           cfw("if ( destination == 1 ) { cpu8051.pc = source; destination = 0; }");
-       }
-
-       # ACALL
-       if ($insttype[$i] == 6) {
-           cfw("stack_push16(cpu8051.pc);");
-       }
-
-       # LCALL
-       if ($insttype[$i] == 7) {
-           cfw("stack_push16(cpu8051.pc);");
-       }
-
-       # RRC
-       if ($insttype[$i] == 8) {
-           cfw("unsigned char new_cy = destination & 0x01;");
-           cfw("destination = ( destination >> 1 ) | (psw_read_cy() << 7);");
-           cfw("psw_write_cy(new_cy);");
-       }
-
-       # DEC
-       if ($insttype[$i] == 9) {
-           cfw("destination--;");
-       }
-
-       # JB
-       if ($insttype[$i] == 10) {
-           cfw("if ( destination == 1 ) { cpu8051.pc = source; }");
-       }
-
-       # RET
-       if ($insttype[$i] == 11) {
-            cfw("cpu8051.pc = stack_pop16();");
-       }
-
-       # RL
-       if ($insttype[$i] == 12) {
-           cfw("destination = ( destination << 1 ) | ( destination >> 7 );");
-       }
-
-       # ADD
-       if ($insttype[$i] == 13) {
-           cfw("destination = addition(destination, source, 0);");
-       }
-
-       # JNB
-       if ($insttype[$i] == 14) {
-           cfw("if ( destination == 0 ) { cpu8051.pc = source; }");
-       }
-
-       # RETI
-       if ($insttype[$i] == 15) {
-           cfw("cpu8051.active_priority = -1;");
-            cfw("cpu8051.pc = stack_pop16();");
-       }
-
-       # RLC
-       if ($insttype[$i] == 16) {
-           cfw("unsigned char new_cy = destination & 0x80;");
-           cfw("destination = ( destination << 1 ) | psw_read_cy();");
-           cfw("psw_write_cy(new_cy);");
-       }
-
-       # ADDC
-        # ADD and ADDC function identically except that ADDC adds the value of
-        # operand as well as the value of the Carry flag whereas ADD does not
-        # add the Carry flag to the result.
-       if ($insttype[$i] == 17) {
-           cfw("unsigned char carryflag = psw_read_cy();");
-           cfw("destination = addition(destination, source, carryflag);");
-       }
-
-       # JC
-       if ($insttype[$i] == 18) {
-           cfw("if (psw_read_cy()) { cpu8051.pc = destination; }");
-       }
-
-       # ORL
-       if ($insttype[$i] == 19) {
-            cfw("destination |= source;");
-       }
-
-       # JNC
-       if ($insttype[$i] == 20) {
-           cfw("if (psw_read_cy() == 0) { cpu8051.pc = destination; }");
-       }
-
-       # ANL
-       if ($insttype[$i] == 21) {
-            cfw("destination &= source;");
-       }
-
-       # JZ
-       if ($insttype[$i] == 22) {
-           cfw("if ( mem_read_direct( _ACC_ ) == 0 ) { cpu8051.pc = destination; }");
-       }
-
-       # XRL
-       if ($insttype[$i] == 23) {
-           cfw("destination ^= source;");
-       }
-
-       # JNZ
-       if ($insttype[$i] == 24) {
-           cfw("if ( mem_read_direct( _ACC_ ) != 0 ) { cpu8051.pc = destination; }");
-       }
-
-       # JMP
-       if ($insttype[$i] == 25) {
-           cfw("cpu8051.pc = destination;");
-       }
-
-       # MOV
-       if ($insttype[$i] == 26) {
-           cfw("destination = source;");
-       }
-
-       # SJMP
-       if ($insttype[$i] == 27) {
-           cfw("cpu8051.pc = destination;");
-       }
-
-       # MOVC
-       if ($insttype[$i] == 28) {
-           cfw("destination = source;");
-       }
-
-       # DIV
-       if ($insttype[$i] == 29) {
-            # A = destination
-            # B = source
-           cfw("psw_clr_cy();");
-            # If B is zero, the OV flag will be set indicating a
-            # division-by-zero error
-           cfw("if (source != 0) {");
-           cfw("    mem_write_direct(_ACC_, destination/source);");
-            cfw("    mem_write_direct( _B_, destination%source);");
-           cfw("    psw_clr_ov();");
-           cfw("} else {");
-           cfw("    psw_set_ov();");
-           cfw("}");
-       }
-
-       # SUBB
-       if ($insttype[$i] == 30) {
-           cfw("unsigned char carryflag = psw_read_cy();");
-           cfw("psw_clr_cy();");
-           cfw("psw_clr_ac();");
-           cfw("psw_clr_ov();");
-           cfw("if ( destination < ( source + carryflag ) ) {");
-           cfw("  psw_set_cy();");
-           cfw("  if ((destination & 0x7F) > ((source + carryflag) & 0x7F))  psw_set_ov();");
-           cfw("} else if ((destination & 0x7F) < ((source + carryflag) & 0x7F))   psw_set_ov();");
-           cfw("if ((destination & 0x0F) < ((source + carryflag) & 0x0F))   psw_set_ac();");
-           cfw("destination -= source + carryflag;");
-       }
-
-       # MUL
-       if ($insttype[$i] == 31) {
-            # A = destination
-            # B = source
-           cfw("psw_clr_cy();");
-           cfw("mem_write_direct(_ACC_, destination * source);");
-            cfw("mem_write_direct(_B_, (destination * source) / 0x100);");
-           cfw("if (mem_read_direct(_B_) > 0)");
-           cfw("    psw_set_ov();");
-           cfw("else");
-           cfw("    psw_clr_ov();");
-       }
-
-       # CPL
-       if ($insttype[$i] == 33) {
-           if ($instargs[$i*4+1] == 2) { cfw("destination ^= 0xFF;"); }
-           else { cfw("destination ^= 0x01;"); }
-       }
-
-       # CJNE
-       if ($insttype[$i] == 34) {
-           cfw("unsigned int reladdr = ((char) mem_read8(PGM_MEM_ID, cpu8051.pc)) + (cpu8051.pc + 1);");
-           cfw("psw_clr_cy();");
-           cfw("if ( destination < source ) psw_set_cy();");
-           cfw("if ( destination != source ) cpu8051.pc = reladdr; else cpu8051.pc++;");
-       }
-
-       # PUSH
-       if ($insttype[$i] == 35) {
-           cfw("stack_push8(destination);");
-       }
-
-       # CLR
-       if ($insttype[$i] == 36) {
-           cfw("destination = 0;");
-       }
-
-       # SWAP
-       if ($insttype[$i] == 37) {
-           cfw("destination = ( destination << 4 ) + ( destination >> 4 );");
-       }
-
-       # XCH
-       if ($insttype[$i] == 38) {
-           cfw("unsigned char tmpval = destination;");
-           cfw("destination = source; source = tmpval;");
-           $modifysrc=1;
-       }
-
-       # POP
-       if ($insttype[$i] == 39) {
-            cfw("destination = stack_pop8();");
-       }
-
-       # SETB
-       if ($insttype[$i] == 40) {
-           cfw("destination = 1;");
-       }
-
-       # DA
-       if ($insttype[$i] == 41) {
-           cfw("if (((destination & 0x0F) > 9) || psw_read_ac()) {");
-           cfw("   if ( ( destination + 6 ) > 0xFF)  psw_set_cy();");
-           cfw("   destination += 6;");
-           cfw("}");
-           cfw("if ( psw_read_cy() || ( ( destination & 0xF0 ) > 0x90 ) ) {");
-           cfw("   if ( ( destination + 0x60 ) > 0xFF ) psw_set_cy();");
-           cfw("   destination += 0x60;");
-           cfw("}");
-       }
-
-       # DJNZ
-       if ($insttype[$i] == 42) {
-           cfw("destination--;");
-           cfw("if ( destination != 0 ) cpu8051.pc = source;");
-       }
-
-       # XCHD
-       if ($insttype[$i] == 43) {
-           cfw("unsigned char tmpval = ( destination & 0x0F );");
-           cfw("destination = ( destination & 0xF0 ) + ( source & 0x0F );");
-           cfw("source = ( source & 0xF0 ) + tmpval;");
-           $modifysrc=1;
-       }
-
-       # MOVX
-       if ($insttype[$i] == 44) {
-           cfw("destination = source;");
-       }
-
-
-
-##############################################################################
-
-
-       if ($instargs[$i*4] > 0) {
-           $op_destination=$instargs[$i*4+1];
-           if ($op_destination == 0) { # addr11
-               cfw("cpu8051.pc = ( cpu8051.pc & 0xF800 ) | addr11;");
-           }
-           if ($op_destination == 1) { # addr16
-               cfw("cpu8051.pc = addr16;");
-           }
-           if ($op_destination == 2) { # A
-               cfw("mem_write_direct( _ACC_, destination );");
-           }
-           if ($op_destination == 3) { # direct
-               cfw("mem_write_direct( destaddr, destination );");
-           }
-           if ($op_destination == 4) { # @R0
-               cfw("mem_write_indirect( mem_read_direct( BANKPSW + _R0_ ), destination );");
-           }
-           if ($op_destination == 5) { # @R1
-               cfw("mem_write_indirect( mem_read_direct( BANKPSW + _R1_ ), destination );");
-           }
-           if ($op_destination == 6) { # R0
-               cfw("mem_write_direct( BANKPSW + _R0_, destination );");
-           }
-           if ($op_destination == 7) { # R1
-               cfw("mem_write_direct( BANKPSW + _R1_, destination );");
-           }
-           if ($op_destination == 8) { # R2
-               cfw("mem_write_direct( BANKPSW + _R2_, destination );");
-           }
-           if ($op_destination == 9) { # R3
-               cfw("mem_write_direct( BANKPSW + _R3_, destination );");
-           }
-           if ($op_destination == 10) { # R4
-               cfw("mem_write_direct( BANKPSW + _R4_, destination );");
-           }
-           if ($op_destination == 11) { # R5
-               cfw("mem_write_direct( BANKPSW + _R5_, destination );");
-           }
-           if ($op_destination == 12) { # R6
-               cfw("mem_write_direct( BANKPSW + _R6_, destination );");
-           }
-           if ($op_destination == 13) { # R7
-               cfw("mem_write_direct( BANKPSW + _R7_, destination );");
-           }
-
-           if ($op_destination == 14) { # bitaddr
-               cfw("mem_write_bit( dstbitaddr, destination );");
-           }
-           if ($op_destination == 17) { # C
-               cfw("psw_write_cy(destination);");
-           }
-           if ($op_destination == 21) { # DPTR
-               cfw("mem_sfr_write_dptr(destination);");
-           }
-           if ($op_destination == 23) { # /bitaddr
-               cfw("mem_write_bit( dstbitaddr, destination );");
-           }
-           if ($op_destination == 24) { # @DPTR
-               cfw("mem_write_indirect(mem_sfr_read_dptr(), destination);");
-           }
-       }
-
-       if ($modifysrc == 1) {
-           if ($instargs[$i*4] > 1) {
-               $op_source=$instargs[$i*4+2];
-               if ($op_source == 0) { # addr11
-                   cfw("cpu8051.pc = ( cpu8051.pc & 0xF800 ) | addr11;");
-               }
-               if ($op_source == 1) { # addr16
-                   cfw("cpu8051.pc = addr16;");
-               }
-               if ($op_source == 2) { # A
-                   cfw("mem_write_direct( _ACC_, source );");
-               }
-               if ($op_source == 3) { # direct
-                   cfw("mem_write_direct( srcaddr, source );");
-               }
-               if ($op_source == 4) { # @R0
-                   cfw("mem_write_indirect( mem_read_direct( BANKPSW + _R0_ ), source );");
-               }
-               if ($op_source == 5) { # @R1
-                   cfw("mem_write_indirect( mem_read_direct( BANKPSW + _R1_ ), source );");
-               }
-               if ($op_source == 6) { # R0
-                   cfw("mem_write_direct( BANKPSW + _R0_, source );");
-               }
-               if ($op_source == 7) { # R1
-                   cfw("mem_write_direct( BANKPSW + _R1_, source );");
-               }
-               if ($op_source == 8) { # R2
-                   cfw("mem_write_direct( BANKPSW + _R2_, source );");
-               }
-               if ($op_source == 9) { # R3
-                   cfw("mem_write_direct( BANKPSW + _R3_, source );");
-               }
-               if ($op_source == 10) { # R4
-                   cfw("mem_write_direct( BANKPSW + _R4_, source );");
-               }
-               if ($op_source == 11) { # R5
-                   cfw("mem_write_direct( BANKPSW + _R5_, source );");
-               }
-               if ($op_source == 12) { # R6
-                   cfw("mem_write_direct( BANKPSW + _R6_, source );");
-               }
-               if ($op_source == 13) { # R7
-                   cfw("mem_write_direct( BANKPSW + _R7_, source );");
-               }
-               if ($op_source == 14) { # bitaddr
-                   cfw("mem_write_bit( srcbitaddr, source );");
-               }
-               if ($op_source == 17) { # C
-                   cfw("psw_write_cy(source);");
-               }
-               if ($op_source == 21) { # DPTR
-                    cfw("mem_sfr_write_dptr(source);");
-               }
-               if ($op_source == 23) { # /bitaddr
-                   cfw("mem_write_bit( srcbitaddr, source );");
-               }
-               if ($op_source == 24) { # @DPTR
-                   cfw("mem_write_indirect(mem_sfr_read_dptr(), source);");
-               }
-           }
-       }
-    }
-    cfw("return $a_cycles[$i];");
-    print INST_IMP "}\n";
-    print INST_IMP "\n";
-}
-# ------------------------------------------------------------------------------
-
-
-# Header for instructions_8051.h
-print INST_DEF "/*\n";
-print INST_DEF " * instructions_8051.h\n";
-write_header(INST_DEF);
-print INST_DEF "#ifndef INSTRUCTIONS_8051_H\n";
-print INST_DEF "#define INSTRUCTIONS_8051_H 1\n\n\n";
-print INST_DEF "#define BANKPSW (mem_read_direct(_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 "\n";
-print INST_DEF "/* Exported variables. */\n";
-print INST_DEF "#ifdef INSTRUCTIONS_8051_M\n";
-print INST_DEF "OPCODE_FP opcode_table[256] = {\n";
-
-for ($i = 0; $i < 256; $i++) {
-    $ifunc = substr($instfunction[$i], 9);
-
-    print INST_DEF "\tcpu8051_$ifunc,\n";
-}
-print INST_DEF "};\n";
-print INST_DEF "#else\n";
-print INST_DEF "OPCODE_FP opcode_table[256];\n";
-print INST_DEF "#endif\n\n\n";
-
-print INST_DEF "#endif /* INSTRUCTIONS_8051_H */\n";
-
-print DISASM_H "#endif /* DISASM_H */\n";
-
-close DISASM_H;
-close OPCODELST;
-close INST_DEF;
-close INST_IMP;
diff --git a/src/common/opcodes2c.pl b/src/common/opcodes2c.pl
new file mode 100755 (executable)
index 0000000..2bc822a
--- /dev/null
@@ -0,0 +1,901 @@
+#!/usr/bin/perl
+#
+# Copyright (C) 1999 Jonathan St-AndrĂ©
+# Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
+#
+# This file is released under the GPLv2
+
+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 OPCODES_DEF, ">opcodes.h" or die "Error creating <opcodes.h> : $!\n";
+open OPCODES_IMP, ">opcodes.c" or die "Error creating <opcodes.c> : $!\n";
+
+# Write GPL license
+# Argument 0 is file descriptor
+sub write_header
+{
+    my $fd = $_[0];
+
+    print $fd " *\n";
+    print $fd " * Do not modify this file directly, as it was created by opcodes2c.pl\n";
+    print $fd " * Any modifications made directly to this file will be lost.\n";
+    print $fd " *\n";
+    print $fd " * Copyright (C) 1999 Jonathan St-AndrĂ©\n";
+    print $fd " * Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>\n";
+    print $fd " *\n";
+    print $fd " * This file is released under the GPLv2\n";
+    print $fd " */\n\n";
+}
+
+# Write C function source code line to INST_IMP file.
+# Prefix each line with a tab (indentation) and add newline character at the end.
+sub cfw
+{
+    print INST_IMP "\t",$_[0],"\n";
+}
+
+# Header for instructions_8051.c
+print INST_IMP "/*\n";
+print INST_IMP " * instructions_8051.c\n";
+write_header(INST_IMP);
+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";
+print INST_IMP "#include \"cpu8051.h\"\n";
+print INST_IMP "#include \"memory.h\"\n";
+print INST_IMP "#include \"psw.h\"\n";
+print INST_IMP "#include \"operations.h\"\n";
+print INST_IMP "#include \"instructions_8051.h\"\n\n\n";
+
+# Header for opcodes.h
+print OPCODES_DEF "/*\n";
+print OPCODES_DEF " * opcodes.h\n";
+write_header(OPCODES_DEF);
+print OPCODES_DEF "#ifndef OPCODES_H\n";
+print OPCODES_DEF "#define OPCODES_H 1\n\n";
+
+print OPCODES_DEF "int\n";
+print OPCODES_DEF "opcodes_get_instr_size(uint8_t opcode);\n";
+print OPCODES_DEF "char *\n";
+print OPCODES_DEF "opcodes_get_instr_type_str(uint8_t opcode);\n";
+print OPCODES_DEF "int\n";
+print OPCODES_DEF "opcodes_get_instr_arg_type_id(unsigned int offset);\n";
+print OPCODES_DEF "char *\n";
+print OPCODES_DEF "opcodes_get_instr_arg_type_str(unsigned int offset);\n";
+
+# opcodes.c
+print OPCODES_IMP "/*\n";
+print OPCODES_IMP " * opcodes.c\n";
+write_header(OPCODES_IMP);
+print OPCODES_IMP "#include <stdint.h>\n\n";
+
+# Column indexes in opcodes.lst table
+use constant COL_OPCODE => 0;
+use constant COL_INSTR  => 1;
+use constant COL_ARGS   => 2;
+
+use constant COL_COUNT_NO_ARGS => 4;
+
+$nbinst=0;
+$nbaddr=0;
+$nbargs=0;
+$instnumb=0;
+
+# Read file describing each instruction/opcode
+
+# Discard first two lines, which are comments
+$ligne = <OPCODELST>;
+$ligne = <OPCODELST>;
+
+while($ligne=<OPCODELST>) {
+    chop $ligne;
+
+    if (length $ligne < 2) {
+        next;
+    }
+
+    @wordlist = split ' ',$ligne;
+    $nbword = @wordlist;
+    $instruction = $wordlist[COL_INSTR];
+
+    for ($i = (COL_INSTR + 1); $i < ($nbword - 2); $i++) {
+        $instruction = "$instruction $wordlist[$i]";
+    }
+
+    $a_instruction[$instnumb] = $instruction;
+    $a_bytes[$instnumb] = $wordlist[$nbword - 2];
+    $a_cycles[$instnumb] = $wordlist[$nbword - 1];
+    $a_opcodehex[$instnumb] = $wordlist[COL_OPCODE];
+
+    $instfunction[$instnumb] = "CPU8051::OP_$wordlist[COL_OPCODE]";
+
+    $instargs[$instnumb << 2] = $instargs[($instnumb << 2) + 1] =
+        $instargs[($instnumb << 2) + 2] = $instargs[($instnumb << 2) + 3] = 0;
+
+    if ($nbword > COL_COUNT_NO_ARGS) {
+       @argslist = split /\,/,$wordlist[COL_ARGS];
+       $argslistsize = @argslist;
+       $instargs[$instnumb << 2] = $argslistsize;
+       for ($i = 0; $i < $argslistsize; $i++) {
+           if (not exists $argstypes{$argslist[$i]}) {
+               $argstypes[$nbargs] = $argslist[$i];
+               $argstypes{$argslist[$i]} = $nbargs++;
+           }
+           $instargs[($instnumb << 2) + $i + 1] = $argstypes{$argslist[$i]};
+       }
+    }
+
+    if (not exists $insttext{$wordlist[COL_INSTR]}) {
+       $insttext[$nbinst] = $wordlist[COL_INSTR];
+       $insttext{$wordlist[COL_INSTR]} = $nbinst++;
+    }
+
+    $insttype[$instnumb] = $insttext{$wordlist[COL_INSTR]};
+
+    if (not exists $addrmode{$wordlist[COL_ARGS]}) {
+       $addrmode[$nbaddr] = $wordlist[COL_ARGS];
+       $addrmode{$wordlist[COL_ARGS]} = $nbaddr++;
+    }
+
+    $nbbytes[$instnumb] = $wordlist[$nbword - 2];
+
+    $instaddr[$instnumb] = $addrmode{$wordlist[COL_ARGS]};
+
+    $instnumb++;
+}
+
+# ------------------------------------------------------------------------------
+print OPCODES_IMP "/* Size(in bytes) of each instruction (offset in table is instruction opcode) */\n";
+
+$nbelement = @nbbytes;
+
+print OPCODES_IMP "static int instr_size[$nbelement] = {";
+
+for ($i = 0; $i < $nbelement; $i++) {
+    if ($i % 16 == 0) {
+        print OPCODES_IMP "\n\t";
+    } else {
+        print OPCODES_IMP " ";
+    }
+    print OPCODES_IMP "$nbbytes[$i],";
+}
+print OPCODES_IMP "\n";
+print OPCODES_IMP "};\n";
+print OPCODES_IMP "\n";
+
+# ------------------------------------------------------------------------------
+print OPCODES_IMP "/*\n";
+print OPCODES_IMP " * For all 256 opcodes, the value in this table gives the instruction type\n";
+print OPCODES_IMP " * ex.: MOV, INC, CLR, CPL,...\n";
+print OPCODES_IMP " * To know what is the instruction type, use\n";
+print OPCODES_IMP " * the number as an offset in instr_type_str[]\n";
+print OPCODES_IMP " */\n";
+
+$nbelement = @insttype;
+
+print OPCODES_IMP "static int instr_type_id[$nbelement] = {";
+
+for ($i = 0; $i < $nbelement; $i++) {
+    if ($i % 16 == 0) {
+        print OPCODES_IMP "\n\t";
+    } else {
+        print OPCODES_IMP " ";
+    }
+    print OPCODES_IMP "$insttype[$i],";
+}
+print OPCODES_IMP "\n";
+print OPCODES_IMP "};\n";
+print OPCODES_IMP "\n";
+
+# ------------------------------------------------------------------------------
+print OPCODES_IMP "/* List of instructions types referenced by instr_type_id[] */\n";
+$nbelement = @insttext;
+$elementnb = 0;
+print OPCODES_IMP "static char *instr_type_str[$nbelement] = {\n";
+
+foreach $instruc (@insttext) {
+    print OPCODES_IMP "\t\"$instruc\"";
+    if ($elementnb++ < ($nbelement - 1)) {
+        print OPCODES_IMP ",";
+    }
+    print OPCODES_IMP "\n";
+}
+
+print OPCODES_IMP "};\n";
+print OPCODES_IMP "\n";
+
+# ------------------------------------------------------------------------------
+print OPCODES_IMP "/*\n";
+print OPCODES_IMP " * Table describing all arguments types of an instruction\n";
+print OPCODES_IMP " * The table is indexed instr_arg_type_id[ opcode * 4]\n";
+print OPCODES_IMP " * instr_arg_type_id[opcode*4 + 1] gives number of instruction arguments\n";
+print OPCODES_IMP " * instr_arg_type_id[opcode*4 + i] for i=1,2 and 3 gives type of each argument\n";
+print OPCODES_IMP " * for most instructions, the 3rd argument isn't used\n";
+print OPCODES_IMP " * the argument type is referenced to instr_arg_type_str[]\n";
+print OPCODES_IMP " */\n";
+
+$nbelement = @instargs;
+
+print OPCODES_IMP "static int instr_arg_type_id[$nbelement] = {";
+
+for ($i = 0; $i < $nbelement; $i++) {
+    if ($i % 16 == 0) {
+        print OPCODES_IMP "\n\t";
+    } else {
+        print OPCODES_IMP " ";
+    }
+
+    print OPCODES_IMP "$instargs[$i],";
+}
+print OPCODES_IMP "\n";
+print OPCODES_IMP "};\n";
+print OPCODES_IMP "\n";
+
+# ------------------------------------------------------------------------------
+print OPCODES_IMP "/*\n";
+print OPCODES_IMP " * List all types of arguments available to instructions\n";
+print OPCODES_IMP " * Referenced by instr_arg_type_id[]\n";
+print OPCODES_IMP " */\n";
+
+$nbelement = @argstypes;
+$elementnb = 0;
+
+print OPCODES_IMP "static char *instr_arg_type_str[$nbelement] = {\n";
+
+foreach $args (@argstypes) {
+    print OPCODES_IMP "\t\"$args\"";
+    if ($elementnb++ < $nbelement-1) {
+        print OPCODES_IMP ",";
+    }
+    print OPCODES_IMP "\n";
+}
+print OPCODES_IMP "};\n";
+print OPCODES_IMP "\n";
+
+print OPCODES_IMP "int\n";
+print OPCODES_IMP "opcodes_get_instr_size(uint8_t opcode)\n";
+print OPCODES_IMP "{\n";
+print OPCODES_IMP "\treturn instr_size[opcode];\n";
+print OPCODES_IMP "}\n";
+print OPCODES_IMP "\n";
+
+print OPCODES_IMP "char *\n";
+print OPCODES_IMP "opcodes_get_instr_type_str(uint8_t opcode)\n";
+print OPCODES_IMP "{\n";
+print OPCODES_IMP "\treturn instr_type_str[instr_type_id[opcode]];\n";
+print OPCODES_IMP "}\n";
+print OPCODES_IMP "\n";
+
+print OPCODES_IMP "int\n";
+print OPCODES_IMP "opcodes_get_instr_arg_type_id(unsigned int offset)\n";
+print OPCODES_IMP "{\n";
+print OPCODES_IMP "\treturn instr_arg_type_id[offset];\n";
+print OPCODES_IMP "}\n";
+print OPCODES_IMP "\n";
+
+print OPCODES_IMP "char *\n";
+print OPCODES_IMP "opcodes_get_instr_arg_type_str(unsigned int offset)\n";
+print OPCODES_IMP "{\n";
+print OPCODES_IMP "\treturn instr_arg_type_str[instr_arg_type_id[offset]];\n";
+print OPCODES_IMP "}\n";
+print OPCODES_IMP "\n";
+
+
+# ------------------------------------------------------------------------------
+for ($i = 0 ; $i < 256; $i++) {
+    print INST_IMP "/*","*"x76,"\n";
+    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";
+    print INST_IMP "{\n";
+
+    if( $i == 0x85 ) {
+       # Cas particulier pour MOV direct,direct -> src et dest sont inverses dans la memoire
+        print INST_IMP "  unsigned char srcaddr = mem_read8( PGM_MEM_ID, cpu8051.pc++ );\n";
+       print INST_IMP "  unsigned char source = mem_read_direct( srcaddr );\n";
+       print INST_IMP "  unsigned char destaddr = mem_read8( PGM_MEM_ID, cpu8051.pc++ );\n";
+       print INST_IMP "  unsigned char destination = mem_read_direct( destaddr );\n";
+       print INST_IMP "  destination = source;\n";
+       print INST_IMP "  mem_write_direct( destaddr, destination );\n";
+    }
+    else {
+       if ($instargs[$i*4] > 0) {
+           $op_destination=$instargs[$i*4+1];
+           if ($op_destination == 0) { # addr11
+               cfw("unsigned int addr11 = ( ( mem_read8( PGM_MEM_ID, cpu8051.pc - 1 ) << 3 ) & 0xF00 ) + mem_read8( PGM_MEM_ID, cpu8051.pc );");
+               cfw("cpu8051.pc++;");
+           }
+           if ($op_destination == 1) { # addr16
+               cfw("uint16_t addr16 = pgm_read_addr16(cpu8051.pc);");
+               cfw("cpu8051.pc += 2;");
+           }
+           if ($op_destination == 2) { # A
+               cfw("unsigned char destination = mem_read_direct( _ACC_ );");
+           }
+           if ($op_destination == 3) { # direct
+               cfw("unsigned char destaddr = mem_read8( PGM_MEM_ID, cpu8051.pc++ );");
+               cfw("unsigned char destination = mem_read_direct( destaddr );");
+           }
+           if ($op_destination == 4) { # @R0
+               cfw("unsigned char destination = mem_read_indirect ( mem_read_direct( BANKPSW + _R0_ ) );");
+           }
+           if ($op_destination == 5) { # @R1
+               cfw("unsigned char destination = mem_read_indirect ( mem_read_direct( BANKPSW + _R1_ ) );");
+           }
+           if ($op_destination == 6) { # R0
+               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R0_ );");
+           }
+           if ($op_destination == 7) { # R1
+               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R1_ );");
+           }
+           if ($op_destination == 8) { # R2
+               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R2_ );");
+           }
+           if ($op_destination == 9) { # R3
+               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R3_ );");
+           }
+           if ($op_destination == 10) { # R4
+               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R4_ );");
+           }
+           if ($op_destination == 11) { # R5
+               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R5_ );");
+           }
+           if ($op_destination == 12) { # R6
+               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R6_ );");
+           }
+           if ($op_destination == 13) { # R7
+               cfw("unsigned char destination = mem_read_direct( BANKPSW + _R7_ );");
+           }
+           if ($op_destination == 14) { # bitaddr
+               cfw("unsigned char destination, dstbitaddr = mem_read8( PGM_MEM_ID, cpu8051.pc++ );");
+               cfw("destination = mem_read_bit( dstbitaddr );");
+           }
+           if ($op_destination == 15) { # reladdr
+               cfw("cpu8051.pc++;");
+               cfw("unsigned int destination = ((char) mem_read8(PGM_MEM_ID, cpu8051.pc - 1)) + cpu8051.pc;");
+           }
+           if ($op_destination == 16) { # #data
+               cfw("unsigned char destination = mem_read8( PGM_MEM_ID, cpu8051.pc++ );");
+           }
+           if ($op_destination == 17) { # C
+               cfw("unsigned char destination = psw_read_cy();");
+           }
+           if ($op_destination == 18) { # @A+DPTR
+               cfw("unsigned int destination = mem_read_direct( _ACC_ ) + mem_sfr_read_dptr();");
+           }
+            if ($op_destination == 20) { # AB
+                cfw("unsigned char destination = mem_read_direct( _ACC_ );");
+                cfw("unsigned char source = mem_read_direct( _B_ );");
+            }
+           if ($op_destination == 21) { # DPTR
+               cfw("unsigned int destination = mem_sfr_read_dptr();");
+           }
+           if ($op_destination == 23) { # /bitaddr
+               cfw("unsigned char destination, dstbitaddr = mem_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
+               cfw("destination = ( mem_read_bit( dstbitaddr ) ^ 1 );");
+           }
+           if ($op_destination == 24) { # @DPTR
+               cfw("unsigned char destination = mem_read_indirect(mem_sfr_read_dptr());");
+           }
+       }
+
+       if ($instargs[$i*4] > 1) {
+           $op_source=$instargs[$i*4+2];
+           if ($op_source == 0) { # addr11
+               cfw("unsigned int addr11 = ( ( mem_read8( PGM_MEM_ID, cpu8051.pc - 1 ) << 3 ) & 0xF00 ) + mem_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
+           }
+           if ($op_source == 1) { # addr16
+               cfw("uint16_t addr16 = pgm_read_addr16(cpu8051.pc);");
+               cfw("cpu8051.pc += 2;");
+           }
+           if ($op_source == 2) { # A
+               cfw("unsigned char source = mem_read_direct( _ACC_ );");
+           }
+           if ($op_source == 3) { # direct
+               cfw("unsigned char srcaddr = mem_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
+               cfw("unsigned char source = mem_read_direct( srcaddr );");
+           }
+           if ($op_source == 4) { # @R0
+               cfw("unsigned char source = mem_read_indirect ( mem_read_direct( BANKPSW + _R0_ ) );");
+           }
+           if ($op_source == 5) { # @R1
+               cfw("unsigned char source = mem_read_indirect ( mem_read_direct( BANKPSW + _R1_ ) );");
+           }
+           if ($op_source == 6) { # R0
+               cfw("unsigned char source = mem_read_direct( BANKPSW + _R0_ );");
+           }
+           if ($op_source == 7) { # R1
+               cfw("unsigned char source = mem_read_direct( BANKPSW + _R1_ );");
+           }
+           if ($op_source == 8) { # R2
+               cfw("unsigned char source = mem_read_direct( BANKPSW + _R2_ );");
+           }
+           if ($op_source == 9) { # R3
+               cfw("unsigned char source = mem_read_direct( BANKPSW + _R3_ );");
+           }
+           if ($op_source == 10) { # R4
+               cfw("unsigned char source = mem_read_direct( BANKPSW + _R4_ );");
+           }
+           if ($op_source == 11) { # R5
+               cfw("unsigned char source = mem_read_direct( BANKPSW + _R5_ );");
+           }
+           if ($op_source == 12) { # R6
+               cfw("unsigned char source = mem_read_direct( BANKPSW + _R6_ );");
+           }
+           if ($op_source == 13) { # R7
+               cfw("unsigned char source = mem_read_direct( BANKPSW + _R7_ );");
+           }
+
+           if ($op_source == 14) { # bitaddr
+               cfw("unsigned char source, srcbitaddr = mem_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
+               cfw("source = mem_read_bit( srcbitaddr );");
+           }
+           if ($op_source == 15) { # reladdr
+               cfw("(cpu8051.pc)++;");
+               cfw("unsigned int source = ((char) mem_read8(PGM_MEM_ID, cpu8051.pc - 1)) + cpu8051.pc;");
+           }
+           if ($op_source == 16) { # #data
+               cfw("unsigned char source = mem_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
+           }
+           if ($op_source == 17) { # C
+               cfw("unsigned char source = psw_read_cy();");
+           }
+           if ($op_source == 18) { # @A+DPTR
+               cfw("unsigned char source = mem_read8( PGM_MEM_ID, mem_read_direct( _ACC_ ) + mem_sfr_read_dptr());");
+           }
+           if ($op_source == 19) { # @A+PC
+               cfw("unsigned char source = mem_read8( PGM_MEM_ID, mem_read_direct( _ACC_ ) + ( ++cpu8051.pc ) );");
+           }
+           if ($op_source == 21) { # DPTR
+               cfw("unsigned int source = mem_sfr_read_dptr();");
+           }
+           if ($op_source == 22) { # #data16
+               cfw("uint16_t source = pgm_read_addr16(cpu8051.pc);");
+               cfw("cpu8051.pc += 2;");
+           }
+           if ($op_source == 23) { # /bitaddr
+               cfw("unsigned char source, srcbitaddr = mem_read8( PGM_MEM_ID, (cpu8051.pc)++ );");
+               cfw("source = ( mem_read_bit( srcbitaddr ) ^ 1 );");
+           }
+           if ($op_source == 24) { # @DPTR
+               cfw("unsigned char source = mem_read_indirect(mem_sfr_read_dptr());");
+           }
+       }
+
+##############################################################################
+       $modifysrc=0;
+
+       # RR
+       if ($insttype[$i] == 3) {
+           cfw("destination = ( destination >> 1 ) | ( destination << 7 );");
+       }
+
+       # INC
+       if ($insttype[$i] == 4) {
+           cfw("destination++;");
+       }
+
+       # JBC
+       if ($insttype[$i] == 5) {
+           cfw("if ( destination == 1 ) { cpu8051.pc = source; destination = 0; }");
+       }
+
+       # ACALL
+       if ($insttype[$i] == 6) {
+           cfw("stack_push16(cpu8051.pc);");
+       }
+
+       # LCALL
+       if ($insttype[$i] == 7) {
+           cfw("stack_push16(cpu8051.pc);");
+       }
+
+       # RRC
+       if ($insttype[$i] == 8) {
+           cfw("unsigned char new_cy = destination & 0x01;");
+           cfw("destination = ( destination >> 1 ) | (psw_read_cy() << 7);");
+           cfw("psw_write_cy(new_cy);");
+       }
+
+       # DEC
+       if ($insttype[$i] == 9) {
+           cfw("destination--;");
+       }
+
+       # JB
+       if ($insttype[$i] == 10) {
+           cfw("if ( destination == 1 ) { cpu8051.pc = source; }");
+       }
+
+       # RET
+       if ($insttype[$i] == 11) {
+            cfw("cpu8051.pc = stack_pop16();");
+       }
+
+       # RL
+       if ($insttype[$i] == 12) {
+           cfw("destination = ( destination << 1 ) | ( destination >> 7 );");
+       }
+
+       # ADD
+       if ($insttype[$i] == 13) {
+           cfw("destination = addition(destination, source, 0);");
+       }
+
+       # JNB
+       if ($insttype[$i] == 14) {
+           cfw("if ( destination == 0 ) { cpu8051.pc = source; }");
+       }
+
+       # RETI
+       if ($insttype[$i] == 15) {
+           cfw("cpu8051.active_priority = -1;");
+            cfw("cpu8051.pc = stack_pop16();");
+       }
+
+       # RLC
+       if ($insttype[$i] == 16) {
+           cfw("unsigned char new_cy = destination & 0x80;");
+           cfw("destination = ( destination << 1 ) | psw_read_cy();");
+           cfw("psw_write_cy(new_cy);");
+       }
+
+       # ADDC
+        # ADD and ADDC function identically except that ADDC adds the value of
+        # operand as well as the value of the Carry flag whereas ADD does not
+        # add the Carry flag to the result.
+       if ($insttype[$i] == 17) {
+           cfw("unsigned char carryflag = psw_read_cy();");
+           cfw("destination = addition(destination, source, carryflag);");
+       }
+
+       # JC
+       if ($insttype[$i] == 18) {
+           cfw("if (psw_read_cy()) { cpu8051.pc = destination; }");
+       }
+
+       # ORL
+       if ($insttype[$i] == 19) {
+            cfw("destination |= source;");
+       }
+
+       # JNC
+       if ($insttype[$i] == 20) {
+           cfw("if (psw_read_cy() == 0) { cpu8051.pc = destination; }");
+       }
+
+       # ANL
+       if ($insttype[$i] == 21) {
+            cfw("destination &= source;");
+       }
+
+       # JZ
+       if ($insttype[$i] == 22) {
+           cfw("if ( mem_read_direct( _ACC_ ) == 0 ) { cpu8051.pc = destination; }");
+       }
+
+       # XRL
+       if ($insttype[$i] == 23) {
+           cfw("destination ^= source;");
+       }
+
+       # JNZ
+       if ($insttype[$i] == 24) {
+           cfw("if ( mem_read_direct( _ACC_ ) != 0 ) { cpu8051.pc = destination; }");
+       }
+
+       # JMP
+       if ($insttype[$i] == 25) {
+           cfw("cpu8051.pc = destination;");
+       }
+
+       # MOV
+       if ($insttype[$i] == 26) {
+           cfw("destination = source;");
+       }
+
+       # SJMP
+       if ($insttype[$i] == 27) {
+           cfw("cpu8051.pc = destination;");
+       }
+
+       # MOVC
+       if ($insttype[$i] == 28) {
+           cfw("destination = source;");
+       }
+
+       # DIV
+       if ($insttype[$i] == 29) {
+            # A = destination
+            # B = source
+           cfw("psw_clr_cy();");
+            # If B is zero, the OV flag will be set indicating a
+            # division-by-zero error
+           cfw("if (source != 0) {");
+           cfw("    mem_write_direct(_ACC_, destination/source);");
+            cfw("    mem_write_direct( _B_, destination%source);");
+           cfw("    psw_clr_ov();");
+           cfw("} else {");
+           cfw("    psw_set_ov();");
+           cfw("}");
+       }
+
+       # SUBB
+       if ($insttype[$i] == 30) {
+           cfw("unsigned char carryflag = psw_read_cy();");
+           cfw("psw_clr_cy();");
+           cfw("psw_clr_ac();");
+           cfw("psw_clr_ov();");
+           cfw("if ( destination < ( source + carryflag ) ) {");
+           cfw("  psw_set_cy();");
+           cfw("  if ((destination & 0x7F) > ((source + carryflag) & 0x7F))  psw_set_ov();");
+           cfw("} else if ((destination & 0x7F) < ((source + carryflag) & 0x7F))   psw_set_ov();");
+           cfw("if ((destination & 0x0F) < ((source + carryflag) & 0x0F))   psw_set_ac();");
+           cfw("destination -= source + carryflag;");
+       }
+
+       # MUL
+       if ($insttype[$i] == 31) {
+            # A = destination
+            # B = source
+           cfw("psw_clr_cy();");
+           cfw("mem_write_direct(_ACC_, destination * source);");
+            cfw("mem_write_direct(_B_, (destination * source) / 0x100);");
+           cfw("if (mem_read_direct(_B_) > 0)");
+           cfw("    psw_set_ov();");
+           cfw("else");
+           cfw("    psw_clr_ov();");
+       }
+
+       # CPL
+       if ($insttype[$i] == 33) {
+           if ($instargs[$i*4+1] == 2) { cfw("destination ^= 0xFF;"); }
+           else { cfw("destination ^= 0x01;"); }
+       }
+
+       # CJNE
+       if ($insttype[$i] == 34) {
+           cfw("unsigned int reladdr = ((char) mem_read8(PGM_MEM_ID, cpu8051.pc)) + (cpu8051.pc + 1);");
+           cfw("psw_clr_cy();");
+           cfw("if ( destination < source ) psw_set_cy();");
+           cfw("if ( destination != source ) cpu8051.pc = reladdr; else cpu8051.pc++;");
+       }
+
+       # PUSH
+       if ($insttype[$i] == 35) {
+           cfw("stack_push8(destination);");
+       }
+
+       # CLR
+       if ($insttype[$i] == 36) {
+           cfw("destination = 0;");
+       }
+
+       # SWAP
+       if ($insttype[$i] == 37) {
+           cfw("destination = ( destination << 4 ) + ( destination >> 4 );");
+       }
+
+       # XCH
+       if ($insttype[$i] == 38) {
+           cfw("unsigned char tmpval = destination;");
+           cfw("destination = source; source = tmpval;");
+           $modifysrc=1;
+       }
+
+       # POP
+       if ($insttype[$i] == 39) {
+            cfw("destination = stack_pop8();");
+       }
+
+       # SETB
+       if ($insttype[$i] == 40) {
+           cfw("destination = 1;");
+       }
+
+       # DA
+       if ($insttype[$i] == 41) {
+           cfw("if (((destination & 0x0F) > 9) || psw_read_ac()) {");
+           cfw("   if ( ( destination + 6 ) > 0xFF)  psw_set_cy();");
+           cfw("   destination += 6;");
+           cfw("}");
+           cfw("if ( psw_read_cy() || ( ( destination & 0xF0 ) > 0x90 ) ) {");
+           cfw("   if ( ( destination + 0x60 ) > 0xFF ) psw_set_cy();");
+           cfw("   destination += 0x60;");
+           cfw("}");
+       }
+
+       # DJNZ
+       if ($insttype[$i] == 42) {
+           cfw("destination--;");
+           cfw("if ( destination != 0 ) cpu8051.pc = source;");
+       }
+
+       # XCHD
+       if ($insttype[$i] == 43) {
+           cfw("unsigned char tmpval = ( destination & 0x0F );");
+           cfw("destination = ( destination & 0xF0 ) + ( source & 0x0F );");
+           cfw("source = ( source & 0xF0 ) + tmpval;");
+           $modifysrc=1;
+       }
+
+       # MOVX
+       if ($insttype[$i] == 44) {
+           cfw("destination = source;");
+       }
+
+
+
+##############################################################################
+
+
+       if ($instargs[$i*4] > 0) {
+           $op_destination=$instargs[$i*4+1];
+           if ($op_destination == 0) { # addr11
+               cfw("cpu8051.pc = ( cpu8051.pc & 0xF800 ) | addr11;");
+           }
+           if ($op_destination == 1) { # addr16
+               cfw("cpu8051.pc = addr16;");
+           }
+           if ($op_destination == 2) { # A
+               cfw("mem_write_direct( _ACC_, destination );");
+           }
+           if ($op_destination == 3) { # direct
+               cfw("mem_write_direct( destaddr, destination );");
+           }
+           if ($op_destination == 4) { # @R0
+               cfw("mem_write_indirect( mem_read_direct( BANKPSW + _R0_ ), destination );");
+           }
+           if ($op_destination == 5) { # @R1
+               cfw("mem_write_indirect( mem_read_direct( BANKPSW + _R1_ ), destination );");
+           }
+           if ($op_destination == 6) { # R0
+               cfw("mem_write_direct( BANKPSW + _R0_, destination );");
+           }
+           if ($op_destination == 7) { # R1
+               cfw("mem_write_direct( BANKPSW + _R1_, destination );");
+           }
+           if ($op_destination == 8) { # R2
+               cfw("mem_write_direct( BANKPSW + _R2_, destination );");
+           }
+           if ($op_destination == 9) { # R3
+               cfw("mem_write_direct( BANKPSW + _R3_, destination );");
+           }
+           if ($op_destination == 10) { # R4
+               cfw("mem_write_direct( BANKPSW + _R4_, destination );");
+           }
+           if ($op_destination == 11) { # R5
+               cfw("mem_write_direct( BANKPSW + _R5_, destination );");
+           }
+           if ($op_destination == 12) { # R6
+               cfw("mem_write_direct( BANKPSW + _R6_, destination );");
+           }
+           if ($op_destination == 13) { # R7
+               cfw("mem_write_direct( BANKPSW + _R7_, destination );");
+           }
+
+           if ($op_destination == 14) { # bitaddr
+               cfw("mem_write_bit( dstbitaddr, destination );");
+           }
+           if ($op_destination == 17) { # C
+               cfw("psw_write_cy(destination);");
+           }
+           if ($op_destination == 21) { # DPTR
+               cfw("mem_sfr_write_dptr(destination);");
+           }
+           if ($op_destination == 23) { # /bitaddr
+               cfw("mem_write_bit( dstbitaddr, destination );");
+           }
+           if ($op_destination == 24) { # @DPTR
+               cfw("mem_write_indirect(mem_sfr_read_dptr(), destination);");
+           }
+       }
+
+       if ($modifysrc == 1) {
+           if ($instargs[$i*4] > 1) {
+               $op_source=$instargs[$i*4+2];
+               if ($op_source == 0) { # addr11
+                   cfw("cpu8051.pc = ( cpu8051.pc & 0xF800 ) | addr11;");
+               }
+               if ($op_source == 1) { # addr16
+                   cfw("cpu8051.pc = addr16;");
+               }
+               if ($op_source == 2) { # A
+                   cfw("mem_write_direct( _ACC_, source );");
+               }
+               if ($op_source == 3) { # direct
+                   cfw("mem_write_direct( srcaddr, source );");
+               }
+               if ($op_source == 4) { # @R0
+                   cfw("mem_write_indirect( mem_read_direct( BANKPSW + _R0_ ), source );");
+               }
+               if ($op_source == 5) { # @R1
+                   cfw("mem_write_indirect( mem_read_direct( BANKPSW + _R1_ ), source );");
+               }
+               if ($op_source == 6) { # R0
+                   cfw("mem_write_direct( BANKPSW + _R0_, source );");
+               }
+               if ($op_source == 7) { # R1
+                   cfw("mem_write_direct( BANKPSW + _R1_, source );");
+               }
+               if ($op_source == 8) { # R2
+                   cfw("mem_write_direct( BANKPSW + _R2_, source );");
+               }
+               if ($op_source == 9) { # R3
+                   cfw("mem_write_direct( BANKPSW + _R3_, source );");
+               }
+               if ($op_source == 10) { # R4
+                   cfw("mem_write_direct( BANKPSW + _R4_, source );");
+               }
+               if ($op_source == 11) { # R5
+                   cfw("mem_write_direct( BANKPSW + _R5_, source );");
+               }
+               if ($op_source == 12) { # R6
+                   cfw("mem_write_direct( BANKPSW + _R6_, source );");
+               }
+               if ($op_source == 13) { # R7
+                   cfw("mem_write_direct( BANKPSW + _R7_, source );");
+               }
+               if ($op_source == 14) { # bitaddr
+                   cfw("mem_write_bit( srcbitaddr, source );");
+               }
+               if ($op_source == 17) { # C
+                   cfw("psw_write_cy(source);");
+               }
+               if ($op_source == 21) { # DPTR
+                    cfw("mem_sfr_write_dptr(source);");
+               }
+               if ($op_source == 23) { # /bitaddr
+                   cfw("mem_write_bit( srcbitaddr, source );");
+               }
+               if ($op_source == 24) { # @DPTR
+                   cfw("mem_write_indirect(mem_sfr_read_dptr(), source);");
+               }
+           }
+       }
+    }
+    cfw("return $a_cycles[$i];");
+    print INST_IMP "}\n";
+    print INST_IMP "\n";
+}
+# ------------------------------------------------------------------------------
+
+
+# Header for instructions_8051.h
+print INST_DEF "/*\n";
+print INST_DEF " * instructions_8051.h\n";
+write_header(INST_DEF);
+print INST_DEF "#ifndef INSTRUCTIONS_8051_H\n";
+print INST_DEF "#define INSTRUCTIONS_8051_H 1\n\n\n";
+print INST_DEF "#define BANKPSW (mem_read_direct(_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 "\n";
+print INST_DEF "/* Exported variables. */\n";
+print INST_DEF "#ifdef INSTRUCTIONS_8051_M\n";
+print INST_DEF "OPCODE_FP opcode_table[256] = {\n";
+
+for ($i = 0; $i < 256; $i++) {
+    $ifunc = substr($instfunction[$i], 9);
+
+    print INST_DEF "\tcpu8051_$ifunc,\n";
+}
+print INST_DEF "};\n";
+print INST_DEF "#else\n";
+print INST_DEF "OPCODE_FP opcode_table[256];\n";
+print INST_DEF "#endif\n\n\n";
+
+print INST_DEF "#endif /* INSTRUCTIONS_8051_H */\n";
+
+print OPCODES_DEF "#endif /* OPCODES_IMP */\n";
+
+close OPCODES_DEF;
+close OPCODES_IMP;
+close OPCODELST;
+close INST_DEF;
+close INST_IMP;
index 6cec8fb..4c35d7f 100644 (file)
@@ -16,6 +16,7 @@
 #include "common.h"
 #include "memory.h"
 #include "cpu8051.h"
+#include "opcodes.h"
 #include "pgmwin.h"
 #include "hexfile.h"
 
@@ -262,7 +263,7 @@ pgmwin_refresh(void)
                        gtk_list_store_set(store, &iter, COL_ADDR, str, -1);
 
                        opcode = mem_read8(PGM_MEM_ID, address);
-                       inst_size = cpu8051_get_instruction_size(opcode);
+                       inst_size = opcodes_get_instr_size(opcode);
 
                        /* Display instruction hex bytes. */
                        for (k = 0, col_id = COL_B0; k < 3; k++, col_id++) {