From dd7540145e5dea4378cd313f8719f7f26114a393 Mon Sep 17 00:00:00 2001 From: Hugo Villeneuve Date: Fri, 3 Jan 2014 02:57:16 -0500 Subject: [PATCH] Merge ADD and ADDC operations into common function --- src/common/Makefile.am | 1 + src/common/opcode2c.pl | 36 ++-------------------- src/common/operations.c | 68 +++++++++++++++++++++++++++++++++++++++++ src/common/operations.h | 27 ++++++++++++++++ 4 files changed, 99 insertions(+), 33 deletions(-) create mode 100644 src/common/operations.c create mode 100644 src/common/operations.h diff --git a/src/common/Makefile.am b/src/common/Makefile.am index ba295d9..aa19efe 100644 --- a/src/common/Makefile.am +++ b/src/common/Makefile.am @@ -15,6 +15,7 @@ libemu8051_a_SOURCES = \ memory.c memory.h \ psw.c psw.h \ sfr.c sfr.h \ + operations.c operations.h \ timers.c timers.h \ common.h \ reg8051.h diff --git a/src/common/opcode2c.pl b/src/common/opcode2c.pl index df8b04e..1030b56 100755 --- a/src/common/opcode2c.pl +++ b/src/common/opcode2c.pl @@ -68,6 +68,7 @@ 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 @@ -444,27 +445,7 @@ for ($i=0 ; $i< 256; $i++) { # ADD if ($insttype[$i] == 13) { - cfw("psw_clr_cy();"); - cfw("psw_clr_ac();"); - cfw("psw_clr_ov();"); - # The Overflow (OV) bit is set if there is a carry-out of bit 6 or - # out of bit 7, but not both. In other words, if the addition of the - # Accumulator, operand and (in the case of ADDC) the Carry flag - # treated as signed values results in a value that is out of the - # range of a signed byte (-128 through +127) the Overflow flag is - # set. Otherwise, the Overflow flag is cleared. - cfw("if ( destination + source > 0xFF ) {"); - # Carry from bit 7 - cfw(" psw_set_cy();"); - # If no carry from bit 6, set OV - cfw(" if (((destination & 0x7F) + (source & 0x7F)) < 0x80)"); - cfw(" psw_set_ov();"); - # If no carry from bit 7, but caary from bit 6, set OV - cfw("} else if (((destination & 0x7F) + (source & 0x7F)) > 0x7F )"); - cfw(" psw_set_ov();"); - cfw("if (((destination & 0x0F) + (source & 0x0F)) > 0x0F)"); - cfw(" psw_set_ac();"); - cfw("destination += source;"); + cfw("destination = addition(destination, source, 0);"); } # JNB @@ -491,18 +472,7 @@ for ($i=0 ; $i< 256; $i++) { # add the Carry flag to the result. if ($insttype[$i] == 17) { cfw("unsigned char carryflag = psw_read_cy();"); - cfw("psw_clr_cy();"); - cfw("psw_clr_ac();"); - cfw("psw_clr_ov();"); - cfw("if ( destination + source + carryflag > 0xFF ) {"); - cfw(" psw_set_cy();"); - cfw(" if (((destination & 0x7F) + (source & 0x7F) + carryflag) < 0x80)"); - cfw(" psw_set_ov();"); - cfw("} else if (((destination & 0x7F) + (source & 0x7F) + carryflag) > 0x7F)"); - cfw(" psw_set_ov();"); - cfw("if (((destination & 0x0F) + (source & 0x0F) + carryflag) > 0x0F)"); - cfw(" psw_set_ac();"); - cfw("destination += source + carryflag;"); + cfw("destination = addition(destination, source, carryflag);"); } # JC diff --git a/src/common/operations.c b/src/common/operations.c new file mode 100644 index 0000000..a454712 --- /dev/null +++ b/src/common/operations.c @@ -0,0 +1,68 @@ +/* + * operations.c + * + * Copyright (C) 2014 Hugo Villeneuve + * + * 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. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include "common.h" +#include "reg8051.h" +#include "cpu8051.h" +#include "sfr.h" +#include "psw.h" +#include "memory.h" +#include "operations.h" + +/* + * 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. + */ +int +addition(int dst, int src, int carry) +{ + psw_clr_cy(); + psw_clr_ac(); + psw_clr_ov(); + + /* + * The Overflow (OV) bit is set if there is a carry-out of bit 6 or + * out of bit 7, but not both. In other words, if the addition of the + * Accumulator, operand and (in the case of ADDC) the Carry flag + * treated as signed values results in a value that is out of the + * range of a signed byte (-128 through +127) the Overflow flag is + * set. Otherwise, the Overflow flag is cleared. + */ + if (dst + src + carry > 0xFF) { + /* Carry from bit 7. */ + psw_set_cy(); + + if (((dst & 0x7F) + (src & 0x7F) + carry) < 0x80) + psw_set_ov(); /* If no carry from bit 6, set OV. */ + } else if (((dst & 0x7F) + (src & 0x7F) + carry) > 0x7F) { + /* If no carry from bit 7, but carry from bit 6, set OV. */ + psw_set_ov(); + } + + if (((dst & 0x0F) + (src & 0x0F) + carry) > 0x0F) + psw_set_ac(); + + return dst + src + carry; +} diff --git a/src/common/operations.h b/src/common/operations.h new file mode 100644 index 0000000..a7533ab --- /dev/null +++ b/src/common/operations.h @@ -0,0 +1,27 @@ +/* + * operations.h + * + * Copyright (C) 2014 Hugo Villeneuve + * + * 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. + */ + +#ifndef OPERATIONS_H +#define OPERATIONS_H 1 + +int +addition(int dest, int src, int carry); + +#endif /* OPERATIONS_H */ -- 2.20.1