summaryrefslogtreecommitdiff
path: root/lib/pale/pale.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/pale/pale.tcl')
-rw-r--r--[-rwxr-xr-x]lib/pale/pale.tcl185
1 files changed, 103 insertions, 82 deletions
diff --git a/lib/pale/pale.tcl b/lib/pale/pale.tcl
index 3b4b61c..37a3fe1 100755..100644
--- a/lib/pale/pale.tcl
+++ b/lib/pale/pale.tcl
@@ -2,7 +2,7 @@
# Part of MCU 8051 IDE ( http://mcu8051ide.sf.net )
############################################################################
-# Copyright (C) 2007-2009 by Martin Ošmera #
+# Copyright (C) 2007, 2008, 2009, 2010, 2011, 2012 by Martin Ošmera #
# martin.osmera@gmail.com #
# #
# This program is free software; you can redistribute it and#or modify #
@@ -21,22 +21,33 @@
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #
############################################################################
+# >>> File inclusion guard
+if { ! [ info exists _PALE_TCL ] } {
+set _PALE_TCL _
+# <<< File inclusion guard
+
# --------------------------------------------------------------------------
# DESCRIPTION
# PALE (Peripheral Abstraction Layer Engine) - simulates virtual hardware
# --------------------------------------------------------------------------
-# Load base class for Virtual HW components
-source "${::LIB_DIRNAME}/pale/virtual_hw_component.tcl"
-
-# Load Virtual HW components
-source "${::LIB_DIRNAME}/pale/ledpanel.tcl"
-source "${::LIB_DIRNAME}/pale/leddisplay.tcl"
-source "${::LIB_DIRNAME}/pale/ledmatrix.tcl"
-source "${::LIB_DIRNAME}/pale/multiplexedleddisplay.tcl"
-source "${::LIB_DIRNAME}/pale/simplekeypad.tcl"
-source "${::LIB_DIRNAME}/pale/matrixkeypad.tcl"
+if {$::GUI_AVAILABLE} {
+ # Load base class for Virtual HW components
+ source "${::LIB_DIRNAME}/pale/virtual_hw_component.tcl"
+
+ # Load Virtual HW components
+ source "${::LIB_DIRNAME}/pale/ledpanel.tcl"
+ source "${::LIB_DIRNAME}/pale/leddisplay.tcl"
+ source "${::LIB_DIRNAME}/pale/ledmatrix.tcl"
+ source "${::LIB_DIRNAME}/pale/multiplexedleddisplay.tcl"
+ source "${::LIB_DIRNAME}/pale/simplekeypad.tcl"
+ source "${::LIB_DIRNAME}/pale/matrixkeypad.tcl"
+ source "${::LIB_DIRNAME}/pale/lcd_hd44780.tcl"
+ source "${::LIB_DIRNAME}/pale/ds1620.tcl"
+ source "${::LIB_DIRNAME}/pale/virtual_uart_term.tcl"
+ source "${::LIB_DIRNAME}/pale/file_interface.tcl"
+}
class Pale {
private variable scenario_file {} ;# String: Name of PALE scenario file
@@ -49,7 +60,7 @@ class Pale {
private variable portConfig ;# Array of Int: Index 0..4, defines port pin functions
private variable portConfig_mod 0 ;# Bool: $portConfig contain special configuration
- private variable instruction_cycles 0 ;# Int: Nummber of instruction cycles performed during this simulation cycle
+ private variable instruction_cycles 0 ;# Int: Number of instruction cycles performed during this simulation cycle
private variable last_output {} ;# List: 5x{8x{...}} Last port outputs
private variable last_input {} ;# List: 5x{8x{...}} Last port inputs
@@ -130,7 +141,7 @@ class Pale {
# Try to open the file
if {[catch {
- set file [open $scenario_file "w" 420]
+ set file [open $scenario_file "w" 0640]
}]} then {
puts stderr "Unable to save to file: \"$scenario_file\""
return 0
@@ -138,8 +149,7 @@ class Pale {
# Save data to the file
puts $file "# MCU 8051 IDE: Virtual HW configuration file"
- puts $file "# Date: [clock format [clock seconds] -format {%D}]"
- puts $file "# Project: [string trim $this {:}]\n"
+ puts $file "# Project: [$this cget -projectName]\n"
foreach dev [concat $output_devices $input_devices] {
puts $file [$dev get_config]
}
@@ -177,7 +187,7 @@ class Pale {
if {![string first $prj_path $scenario_file]} {
return [string range $scenario_file [string length $prj_path] end]
# Return absolute directory location
- } {
+ } else {
return $scenario_file
}
}
@@ -210,7 +220,7 @@ class Pale {
![file exists $filename] ||
![file isfile $filename] ||
(!$::MICROSOFT_WINDOWS && ![file readable $filename])
- } {
+ } then {
return 0
}
@@ -259,7 +269,7 @@ class Pale {
$obj set_config $conf
# Error detected
}]} then {
- puts stderr "Unable to create PALE object: \"$obj\", maybe you are using old version of MCU 8051 IDE\n"
+ puts stderr "Unable to create PALE object: \"$obj\", maybe you are using an old version of MCU 8051 IDE.\n"
puts stderr $::errorInfo
catch {
@@ -387,7 +397,7 @@ class Pale {
{X} { ;# Access to external memory
append result [expr {rand() < 0.5}]
}
- {-} { ;# Undeterminable value (some noise)
+ {-} { ;# Indeterminable value (some noise)
append result [expr {rand() < 0.5}]
}
{|} { ;# High frequency
@@ -406,21 +416,18 @@ class Pale {
}
## Read Real Port Pin Voltage - 1 bit value (0 or 1)
- # @parm List - {port_number bit_number}
- # @parm Int = 0 - Position in history (positive number)
+ # @parm List pn_bn - {port_number bit_number}
+ # @parm Int position=0 - Position in history (positive number)
# @return Bool - Boolean value
- public method pale_RRPPV args {
+ public method pale_RRPPV {pn_bn {position 0}} {
if {!$is_enabled} {return 1}
# Parse input arguments
- set port [lindex $args {0 0}]
- set bit [lindex $args {0 1}]
- set position [lindex $args 1]
+ set port [lindex $pn_bn 0]
+ set bit [lindex $pn_bn 1]
# Adjust arguments
- if {![string length $position]} {
- set position 0
- } elseif {$position < 0} {
+ if {$position < 0} {
set position [expr {[llength $portState] + $position}]
}
set bit [expr {7 - $bit}]
@@ -453,30 +460,20 @@ class Pale {
}
## Write to port with bypassed latch (takes effect on next simulation cycle)
- # @parm Int - Port number
- # @parm List - New value -- list of 8 values {bit0 bit1 bit2 ... bit7}
+ # @parm Int port - Port number
+ # @parm List value - New value -- list of 8 values {bit0 bit1 bit2 ... bit7}
# '0' - Logical 0
# '1' - Logical 1
# '|' - High frequency pulse
# 'X' - Access to external memory
# '?' - No volatge
- # '-' - Undeterminable value (some noise)
+ # '-' - Indeterminable value (some noise)
# '=' - High forced to low
- # @parm Int = 0 - Position in history (zero or negative number)
+ # @parm Int position=0 - Position in history (zero or negative number)
# @return void
- public method pale_WPBL args {
+ public method pale_WPBL {port value {position 0}} {
if {!$is_enabled} {return}
- # Parse input arguments
- set port [lindex $args 0]
- set value [lindex $args 1]
- set position [lindex $args 2]
-
- # Adjust arguments
- if {![string length $position]} {
- set position 0
- }
-
# Set value
for {set bit 0} {$bit < 8} {incr bit} {
lappend special_func [list $port $bit $value $position]
@@ -484,30 +481,24 @@ class Pale {
}
## Write to port bit with bypassed latch
- # @parm List - {port_number bit_number}
- # @parm Char - New value
+ # @parm List pn_bn - {port_number bit_number}
+ # @parm Char value - New value
# '0' - Logical 0
# '1' - Logical 1
# '|' - High frequency pulse
# 'X' - Access to external memory
# '?' - No volatge
- # '-' - Undeterminable value (some noise)
+ # '-' - Indeterminable value (some noise)
# '=' - High forced to low
- # @parm Int = 0 - Position in history (zero or negative number)
+ # @parm Int position=0 - Position in history (zero or negative number)
# @return void
- public method pale_WPBBL args {
+ public method pale_WPBBL {pn_bn value {position 0}} {
if {!$is_enabled} {return}
# Parse input arguments
- set port [lindex $args {0 0}]
- set bit [lindex $args {0 1}]
- set value [lindex $args 1]
- set position [lindex $args 2]
+ set port [lindex $pn_bn 0]
+ set bit [lindex $pn_bn 1]
- # Adjust arguments
- if {![string length $position]} {
- set position 0
- }
set bit [expr {7 - $bit}]
# Set value
@@ -583,7 +574,7 @@ class Pale {
for {set i -1; set j 0} {$j < $instruction_cycles} {incr i; incr j} {
if {$i < 0} {
set previous_output_state $last_output
- } {
+ } else {
set previous_output_state [lindex $portOutput $i]
}
foreach prev $previous_output_state new [lindex $portOutput $j] port {0 1 2 3 4} {
@@ -638,16 +629,16 @@ class Pale {
set last_output [lindex $portOutput end]
set last_input [lindex $portInput end]
set last_state [lindex $portState end]
- set portLatch [list]
- set portOutput [list]
- set portInput [list]
+ set portLatch [list]
+ set portOutput [list]
+ set portInput [list]
set special_func [list]
# Inform output devices about the new port outputs
foreach dev $output_devices {
- $dev new_state $last_state
- update
+ $dev new_state last_state
}
+ update
}
## Determinate resulting value when two values clash on one wire
@@ -678,7 +669,7 @@ class Pale {
{?} { ;# No volatge
return $in1
}
- {-} { ;# Undeterminable value (some noise)
+ {-} { ;# Indeterminable value (some noise)
return {-}
}
{=} { ;# High forced to low
@@ -690,7 +681,7 @@ class Pale {
{1} { ;# Logical 1
if {$in1 == {?}} {
return 1
- } {
+ } else {
return $in1
}
}
@@ -712,8 +703,10 @@ class Pale {
# Call all input devices
foreach dev $input_devices {
# Call device to change the current state
- set input [$dev new_state $input]
- update
+ $dev new_state input
+
+ # Clear list of devices already confronted with the new state
+ set already_evaluated [list]
# Inform all other devices interconnected with this one
for {set p 0} {$p < 5} {incr p} {
@@ -729,17 +722,22 @@ class Pale {
# Call all affected devices
foreach affected_dev $engaged_pins($p,$b) {
+ # Do not confront the device with itself
if {$affected_dev == $dev} {
continue
}
- set input [$affected_dev new_state $input]
- update
+ # Do not confront the device with another device more than once per ``foreach dev ...'' iteration
+ if {[lsearch -ascii -exact $already_evaluated $affected_dev] != -1} {
+ continue
+ }
+
+ lappend already_evaluated $affected_dev
+ $affected_dev new_state input
}
# Again call the current device
- set input [$dev new_state $input]
- update
+ $dev new_state input
}
}
}
@@ -762,9 +760,9 @@ class Pale {
# Inform output devices about the new port outputs
foreach dev $output_devices {
- $dev new_state $last_state
- update
+ $dev new_state last_state
}
+ update
}
## Call input devices to evaluate input values
@@ -776,8 +774,10 @@ class Pale {
# Call all input devices
foreach dev $input_devices {
# Call device to change the current state
- set input [$dev new_state $input]
- update
+ $dev new_state input
+
+ # Clear list of devices already confronted with the new state
+ set already_evaluated [list]
# Inform all other devices interconnected with this one
for {set p 0} {$p < 5} {incr p} {
@@ -793,17 +793,21 @@ class Pale {
# Call all affected devices
foreach affected_dev $engaged_pins($p,$b) {
+ # Do not confront the device with itself
if {$affected_dev == $dev} {
continue
}
- set input [$affected_dev new_state $input]
- update
+ # Do not confront the device with another device more than once per ``foreach dev ...'' iteration
+ if {[lsearch -ascii -exact $already_evaluated $affected_dev] != -1} {
+ continue
+ }
+
+ $affected_dev new_state input
}
# Again call the current device
- set input [$dev new_state $input]
- update
+ $dev new_state input
}
}
}
@@ -890,6 +894,9 @@ class Pale {
pale_disengage_pin_by_input_device $p $b $object
}
}
+
+ # Make this change in the environment visible right away
+ pale_reevaluate_IO
}
## Inform PALE system about that than some input device is
@@ -907,6 +914,9 @@ class Pale {
# * PALE VHW component must extend class "VirtualHWComponent"
# * Input devices CAN affect port inputs, output cannot
public method pale_engage_pin_by_input_device {port pin dev} {
+ if {[lsearch -ascii -exact $engaged_pins($port,$pin) $dev] != -1} {
+ return
+ }
lappend engaged_pins($port,$pin) $dev
}
@@ -928,6 +938,7 @@ class Pale {
# * Input devices CAN affect port inputs, output cannot
public method pale_disengage_pin_by_input_device {port pin dev} {
set idx [lsearch -ascii -exact $engaged_pins($port,$pin) $dev]
+
if {$idx == -1} {
return
}
@@ -955,7 +966,7 @@ class Pale {
# '|' - High frequency pulse
# 'X' - Access to external memory
# '?' - No volatge
- # '-' - Undeterminable value (some noise)
+ # '-' - Indeterminable value (some noise)
# '=' - High forced to low
public method pale_get_output_state {} {
return $last_output
@@ -969,15 +980,15 @@ class Pale {
# '|' - High frequency pulse
# 'X' - Access to external memory
# '?' - No volatge
- # '-' - Undeterminable value (some noise)
+ # '-' - Indeterminable value (some noise)
# '=' - High forced to low
public method pale_get_true_state {} {
return $last_state
}
- ## Get list of avaliable port number on the current MCU
+ ## Get list of available port number on the current MCU
# @return List of Int - e.g. {1 3}
- public method pale_get_avaliable_ports {} {
+ public method pale_get_available_ports {} {
return [lindex [$this get_ports_info] 1]
}
@@ -988,4 +999,14 @@ class Pale {
$dev mcu_changed
}
}
+
+ ## Get number of instruction cycles performed during this simulation cycle
+ # @return Int - Number of instruction cycles
+ public method pale_get_number_of_instruction_cycles {} {
+ return $instruction_cycles
+ }
+}
+
+# >>> File inclusion guard
}
+# <<< File inclusion guard