diff options
Diffstat (limited to 'lib/simulator/engine/engine_auxiliary_alo_functions.tcl')
-rwxr-xr-x | lib/simulator/engine/engine_auxiliary_alo_functions.tcl | 171 |
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 +} |