summaryrefslogtreecommitdiff
path: root/lib/simulator/engine/engine_auxiliary_alo_functions.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/simulator/engine/engine_auxiliary_alo_functions.tcl')
-rwxr-xr-xlib/simulator/engine/engine_auxiliary_alo_functions.tcl171
1 files changed, 171 insertions, 0 deletions
diff --git a/lib/simulator/engine/engine_auxiliary_alo_functions.tcl b/lib/simulator/engine/engine_auxiliary_alo_functions.tcl
new file mode 100755
index 0000000..d73b57e
--- /dev/null
+++ b/lib/simulator/engine/engine_auxiliary_alo_functions.tcl
@@ -0,0 +1,171 @@
+#!/usr/bin/tclsh
+# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
+
+############################################################################
+# Copyright (C) 2007-2009 by Martin Ošmera #
+# martin.osmera@gmail.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., #
+# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
+############################################################################
+
+# --------------------------------------------------------------------------
+# DESCRIPTION
+# Part of simulator engine functionality.
+#
+# --------------------------------------------------------------------------
+# AUXILIARY ALO FUNCTIONS
+# --------------------------------------------------------------------------
+
+## Generate random octet
+ # @return Int - random value in range 0..255
+private method undefined_octet {} {
+ switch -- ${::Simulator::undefined_value} {
+ 0 { ;# Return 0
+ return 0
+ }
+ 1 { ;# Return 255
+ return 255
+ }
+ 2 { ;# Return random value
+ set result [expr {int(rand() * 256)}]
+ if {$result == 256} {set result 255}
+ }
+ }
+ return $result
+}
+
+## Add value to accumulator and affect PSW flags
+ # @parm Int val - value to add
+ # @return void
+private method alo_add {val} {
+
+ # Adjust stepback stack
+ if {${::Simulator::reverse_run_steps}} {
+ stepback_reg_change S 224
+ }
+
+ # Local variables
+ set A_h [expr {($sfr(224) & 240) >> 4}] ;# High-order nibble of Acc
+ set A_l [expr {$sfr(224) & 15}] ;# Low-order nibble of Acc
+ set val_h [expr {($val & 0x1f0) >> 4}] ;# High-order nibble of val
+ set val_l [expr {$val & 15}] ;# Low-order nibble of val
+
+ # Compute low-order nibble of result
+ set result [expr {$val_l + $A_l}]
+
+ # Flag AC
+ if {$result > 15} {
+ incr val_h
+ incr result -16
+ setBit $symbol(AC) 1
+ } {
+ setBit $symbol(AC) 0
+ }
+
+ # Compute high-order nibble of result
+ incr result [expr {($val_h + $A_h) << 4}]
+
+ # Flag C
+ if {$result > 255} {
+ incr result -256
+ setBit $symbol(C) 1
+ } {
+ setBit $symbol(C) 0
+ }
+
+ # Flag OV
+ if {($val < 128) && ($sfr(224) < 128) && ($result > 127)} {
+ setBit $symbol(OV) 1
+ } elseif {($val > 127) && ($sfr(224) > 127) && ($result < 128)} {
+ setBit $symbol(OV) 1
+ } {
+ setBit $symbol(OV) 0
+ }
+
+ # Set Acc
+ set sfr(224) $result
+ evaluate_sfr 224
+}
+
+## Add value to accumulator with carry and affect PSW flags
+ # @parm Int val - value to add
+ # @return void
+private method alo_addc {val} {
+ if {[getBit $symbol(C)]} {
+ incr val
+ }
+ alo_add $val
+}
+
+## Subtract tegister from ACC with borrow and affect PSW flags
+ # @parm Int val - value to subtract
+ # @return void
+private method alo_subb {val} {
+
+ # Adjust stepback stack
+ if {${::Simulator::reverse_run_steps}} {
+ stepback_reg_change S 224
+ }
+
+ # Flag PSW.C
+ if {[getBit $symbol(C)]} {
+ incr val
+ }
+
+ # Local variables
+ set A_h [expr {($sfr(224) & 240) >> 4}] ;# High-order nibble of Acc
+ set A_l [expr {$sfr(224) & 15}] ;# Low-order nibble of Acc
+ set val_h [expr {($val & 0x1f0) >> 4}] ;# High-order nibble of val
+ set val_l [expr {$val & 15}] ;# Low-order nibble of val
+
+ # Compute low-order nibble of result
+ set result_l [expr {$A_l - $val_l}]
+
+ # Flag AC
+ if {$result_l < 0} {
+ incr result_l 16
+ incr val_h
+ setBit $symbol(AC) 1
+ } {
+ setBit $symbol(AC) 0
+ }
+
+ # Compute high-order nibble of result
+ set result_h [expr {$A_h - $val_h}]
+
+ # Flag C
+ if {$result_h < 0} {
+ incr result_h 16
+ setBit $symbol(C) 1
+ } {
+ setBit $symbol(C) 0
+ }
+
+ # Compute high-order nibble of result
+ set result [expr {($result_h << 4) + $result_l}]
+
+ # Flag OV
+ if {($val > 127) && ($sfr(224) < 128) && ($result > 127)} {
+ setBit $symbol(OV) 1
+ } elseif {($val < 128) && ($sfr(224) > 127) && ($result < 128)} {
+ setBit $symbol(OV) 1
+ } {
+ setBit $symbol(OV) 0
+ }
+
+ # Set Acc
+ set sfr(224) $result
+}