summaryrefslogtreecommitdiff
path: root/lib/simulator/sfrmap.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'lib/simulator/sfrmap.tcl')
-rwxr-xr-xlib/simulator/sfrmap.tcl523
1 files changed, 523 insertions, 0 deletions
diff --git a/lib/simulator/sfrmap.tcl b/lib/simulator/sfrmap.tcl
new file mode 100755
index 0000000..d6d16d2
--- /dev/null
+++ b/lib/simulator/sfrmap.tcl
@@ -0,0 +1,523 @@
+#!/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
+# Implements window showing the map of avaliable special function register
+# --------------------------------------------------------------------------
+
+class SFRMap {
+ ## COMMON
+ common count 0 ;# Int: Counter of object instances
+
+ ## PRIVATE
+ private variable dialog_opened 0 ;# Bool: Dialog window opened
+ private variable defined_sfr ;# List: Addresses of defined SFR in this dialog
+ private variable win ;# Widget: Dialog window
+ private variable enabled 0 ;# Bool: True if simulator is engaged
+ private variable validation_ena 0 ;# Bool: Entry boxes validation enabled
+ private variable main_frame ;# Widget: Frame containing registers
+ private variable det_name ;# Widget: Entry box on bottom bar (Register name)
+ private variable det_hex ;# Widget: Entry box on bottom bar (HEX)
+ private variable det_dec ;# Widget: Entry box on bottom bar (DEC)
+ private variable det_bin ;# Widget: Entry box on bottom bar (BIN)
+ private variable det_oct ;# Widget: Entry box on bottom bar (OCT)
+ private variable bottom_right_frame ;# Widget: Bottom right frame
+ private variable selected_entry -1 ;# Int: Address of selected entry box in the map
+
+ constructor {} {
+ incr count
+ }
+
+ destructor {
+ if {$dialog_opened} {
+ destroy $win
+ }
+ }
+
+ ## Invoke dialog window
+ # @return void
+ public method sfrmap_invoke_dialog {} {
+ if {$dialog_opened} {return}
+ set dialog_opened 1
+
+ # Create dialog window
+ set enabled [$this is_frozen]
+ set win [toplevel .sfr_map$count -bg {#FFFFFF} -class {SFR map} -bg {#EEEEEE}]
+
+ # Create other widgets
+ create_win_gui
+
+ # Configure the window
+ wm iconphoto $win ::ICONS::16::kcmmemory_S
+ wm title $win "Map of SFR area - [string trim $this {:}] - MCU 8051 IDE"
+ wm resizable $win 0 0
+ wm protocol $win WM_DELETE_WINDOW "$this sfrmap_close_dialog"
+ bindtags $win [list $win Toplevel all .]
+ }
+
+ ## Create window widgets
+ # @return void
+ private method create_win_gui {} {
+ set main_frame [frame $win.main_frame -bg {#888888}]
+
+ ## Create headers for main frame
+ # Horizontal headers
+ set header_idx 0
+ for {set i 0; set j 8; set col 1} {$i < 8} {incr i; incr j; incr col} {
+ set k [format %X $j]
+ grid [label $main_frame.header_$header_idx \
+ -text "$i/$k" -bg {#FFFFFF} -fg {#555555} \
+ ] -sticky nsew -column $col -row 0
+ incr header_idx
+ grid [label $main_frame.header_$header_idx \
+ -text "$i/$k" -bg {#FFFFFF} -fg {#555555} \
+ ] -sticky nsew -column $col -row 17 -pady 1
+ incr header_idx
+ }
+ # Vertical headers
+ set row 1
+ foreach left {F8h F0h E8h E0h D8h D0h C8h C0h B8h B0h A8h A0h 98h 90h 88h 80h} \
+ right {FFh F7h EFh E7h DFh D7h CFh C7h BFh B7h AFh A7h 9Fh 97h 8Fh 87h} \
+ {
+ grid [label $main_frame.header_$header_idx \
+ -text $left -bg {#FFFFFF} -fg {#555555} \
+ ] -sticky nsew -column 0 -row $row
+ incr header_idx
+ grid [label $main_frame.header_$header_idx \
+ -text $right -bg {#FFFFFF} -fg {#555555} \
+ ] -sticky nsew -column 9 -row $row -padx 1
+ incr row
+ incr header_idx
+ }
+ # Corners
+ foreach row {0 0 17 17} col {0 9 0 9} {
+ grid [frame $main_frame.header_$header_idx -bg {#FFFFFF}] \
+ -row $row -column $col -sticky nsew
+ incr header_idx
+ }
+
+ # Create separate frame for each cell
+ set addr 128
+ for {set row 16} {$row > 0} {incr row -1} {
+ for {set col 1} {$col < 9} {incr col} {
+ set frame [frame $main_frame.cell_$addr -bg {#DDDDDD} -padx 1]
+ grid $frame \
+ -row $row -column $col \
+ -sticky nsew -padx [expr {$col % 2}] \
+ -pady [expr {$row % 2}]
+ incr addr
+ }
+ }
+
+ # Insure than all cells have the same width and heigh
+ for {set i 1} {$i < 9} {incr i} {
+ grid columnconfigure $main_frame $i -uniform sfr_col
+ }
+ for {set i 1} {$i < 17} {incr i} {
+ grid rowconfigure $main_frame $i -uniform sfr_row
+ }
+
+ # Create matrix of SFR
+ set validation_ena 0
+ set defined_sfr {}
+ foreach reg [$this simulator_get_sfrs] {
+ set addr [lindex $reg 0]
+ set name [lindex $reg 1]
+ set row 0
+
+ lappend defined_sfr $addr
+
+ switch -- $name {
+ {SBUFR} {
+ set name_d {SBUF R}
+ }
+ {SBUFT} {
+ set name_d {SBUF T}
+ }
+ default {
+ set name_d $name
+ }
+ }
+
+ set n_addr [expr {$addr & 0x0FF}]
+ if {$addr > 0xFF} {
+ set row 1
+ }
+
+ if {!($addr % 8)} {
+ set fg {#00DDDD}
+ } {
+ set fg {#0000DD}
+ }
+ $main_frame.cell_$n_addr configure -bg {#FFFFFF}
+ grid [label $main_frame.lbl_${addr} \
+ -text $name_d -bg {#FFFFFF} -fg $fg \
+ ] -in $main_frame.cell_$n_addr -sticky nsw -row $row -column 0
+ set entry [ttk::entry $main_frame.ent_${addr} \
+ -validatecommand "$this sfrmap_validate $addr h %P m" \
+ -style Simulator_WhiteBg.TEntry \
+ -validate all \
+ -takefocus 0 \
+ -width 3 \
+ -font ${::Simulator_GUI::entry_font} \
+ ]
+ grid $entry -in $main_frame.cell_$n_addr -padx 1 -pady 1 -row $row -column 1 -sticky nse
+ $entry insert end [$this getSfr $addr]
+ if {!$enabled} {
+ $entry configure -state disabled
+ }
+ if {$row} {
+ foreach widget [list \
+ $main_frame.lbl_${addr} $main_frame.lbl_${n_addr} \
+ $main_frame.ent_${addr} $main_frame.ent_${n_addr} \
+ ] {
+ catch {$widget configure -highlightthickness 0}
+ catch {$widget configure -pady 0}
+ catch {$widget configure -bd 0}
+
+ $widget configure -font [font create -family $::DEFAULT_FIXED_FONT -size -3]
+ grid configure $widget -pady 0 -ipady 0
+ }
+ foreach widget [list $main_frame.lbl_${addr} $main_frame.lbl_${n_addr}] {
+ $widget configure -pady 0
+ }
+ grid rowconfigure $main_frame.cell_$n_addr 0 -pad 0
+ grid rowconfigure $main_frame.cell_$n_addr 1 -pad 0
+ }
+ grid columnconfigure $main_frame.cell_$n_addr 0 -weight 1
+
+ bindtags $entry [list $entry TEntry $win all .]
+ bind $entry <Motion> {help_window_show %X %Y+30}
+ bind $entry <Leave> {help_window_hide}
+ bind $entry <FocusIn> "$this sfrmap_map_cell_focused $addr $name"
+ set hex_addr [format %X $addr]
+ if {[string length $hex_addr] == 1} {
+ set hex_addr "0$hex_addr"
+ }
+ bind $entry <Enter> "create_help_window $win \[$this getSfr $addr\] {$hex_addr SFR}"
+ }
+ set validation_ena 1
+
+ ## Create bottom frame
+ set bottom_frame [frame $win.bottom_frame -bg {#FFFFFF}]
+ # Create label "Reserved"
+ pack [label $bottom_frame.res_0 -text [mc "Reserved"] -bg {#FFFFFF}] -side left
+ pack [label $bottom_frame.res_1 -width 6 -bg {#CCCCCC} -bd 1 -relief raised] \
+ -side left -pady 5
+ pack [frame $bottom_frame.frame_foo -width 20] -side left
+ # Create label "Bit addressable"
+ pack [label $bottom_frame.bit_0 -text [mc "Bit addressable"] -bg {#FFFFFF}] -side left
+ pack [label $bottom_frame.bit_1 -width 6 -bg {#00DDDD} -bd 1 -relief raised] \
+ -side left -pady 5
+ # Create bottom right frame (additional entry boxes)
+ set bottom_right_frame [frame $bottom_frame.bottom_right -bg {#FFFFFF}]
+ set det_name [label $bottom_right_frame.name_lbl \
+ -bg {#FFFFFF} -fg {#0000DD} \
+ ]
+ set det_hex [ttk::entry $bottom_right_frame.hex_entry \
+ -validatecommand "$this sfrmap_validate {} h %P p" \
+ -style Simulator_WhiteBg.TEntry \
+ -validate all \
+ -width 3 \
+ ]
+ set det_dec [ttk::entry $bottom_right_frame.dec_entry \
+ -validatecommand "$this sfrmap_validate {} d %P p" \
+ -style Simulator_WhiteBg.TEntry \
+ -validate all \
+ -width 3 \
+ ]
+ set det_bin [ttk::entry $bottom_right_frame.bin_entry \
+ -validatecommand "$this sfrmap_validate {} b %P p" \
+ -style Simulator_WhiteBg.TEntry \
+ -validate all \
+ -width 8 \
+ ]
+ set det_oct [ttk::entry $bottom_right_frame.oct_entry \
+ -validatecommand "$this sfrmap_validate {} o %P p" \
+ -style Simulator_WhiteBg.TEntry \
+ -validate all \
+ -width 3 \
+ ]
+ foreach entry [list $det_hex $det_dec $det_bin $det_oct] {
+ bind $entry <FocusIn> "$this sfrmap_panel_entrybox_focused"
+ bindtags $entry [list $entry TEntry $win all .]
+ }
+ pack [ttk::separator $bottom_right_frame.sep -orient vertical] -side left -fill y -padx 3
+ pack $det_name -side left
+
+ pack [label $bottom_right_frame.lbl_hex \
+ -text [mc "HEX:"] -pady 0 -bg {#FFFFFF} \
+ -font ${::Simulator_GUI::smallfont} \
+ -fg ${::Simulator_GUI::small_color} \
+ ] -side left
+ pack $det_hex -side left
+ pack [label $bottom_right_frame.lbl_dec \
+ -text [mc "DEC:"] -pady 0 -bg {#FFFFFF} \
+ -font ${::Simulator_GUI::smallfont} \
+ -fg ${::Simulator_GUI::small_color} \
+ ] -side left
+ pack $det_dec -side left
+ pack [label $bottom_right_frame.lbl_bin \
+ -text [mc "BIN:"] -pady 0 -bg {#FFFFFF} \
+ -font ${::Simulator_GUI::smallfont} \
+ -fg ${::Simulator_GUI::small_color} \
+ ] -side left
+ pack $det_bin -side left
+ pack [label $bottom_right_frame.lbl_oct \
+ -text [mc "OCT:"] -pady 0 -bg {#FFFFFF} \
+ -font ${::Simulator_GUI::smallfont} \
+ -fg ${::Simulator_GUI::small_color} \
+ ] -side left
+ pack $det_oct -side left
+
+ # Pack main and bottom frame
+ pack $main_frame -fill both
+ pack $bottom_frame -side bottom -fill x
+ }
+
+ ## Close the dialog window
+ # @return void
+ public method sfrmap_close_dialog {} {
+ if {!$dialog_opened} {return}
+ set dialog_opened 0
+ destroy $win
+ }
+
+ ## Binding for event <FocusIn> on SFR entry box in the matrix
+ # @parm Int addr - Register address
+ # @parm String name - Register name
+ # @return void
+ public method sfrmap_map_cell_focused {addr name} {
+ set selected_entry $addr
+
+ # Pack bottom right frame if it has not been packed yet
+ if {![winfo viewable $bottom_right_frame]} {
+ pack $bottom_right_frame -side right -padx 5
+ }
+
+ # Adjust entry boxes
+ sfrmap_validate $addr h [$main_frame.ent_${addr} get] m
+ $det_name configure -text "${name}:"
+
+ # Restore normal color
+ foreach entry [list $main_frame.ent_${addr} $det_hex $det_oct $det_bin $det_dec] {
+ $entry configure -style Simulator_WhiteBg.TEntry
+ }
+
+ # Disable these entry boxes
+ if {!$enabled} {
+ foreach entry [list $det_hex $det_oct $det_bin $det_dec] {
+ $entry configure -state disabled
+ }
+ }
+ }
+
+ ## Binding for event <FocusIn> on SFR entry box in the bottom right panel
+ # Restore normal color for all enty boxes related to the selected SFR
+ # @return void
+ public method sfrmap_panel_entrybox_focused {} {
+ foreach entry [list $main_frame.ent_${selected_entry} $det_hex $det_oct $det_bin $det_dec] {
+ $entry configure -style Simulator_WhiteBg.TEntry
+ }
+ }
+
+ ## Set value for certain register
+ # @parm Int addr - Register address
+ # @parm Int value - New register value
+ # @return void
+ public method sfrmap_map_sync {addr val} {
+ # Check if this call has some meaning
+ if {!$dialog_opened || !$validation_ena} {return}
+ if {[lsearch $defined_sfr $addr] == -1} {return}
+ set original_val [$main_frame.ent_${addr} get]
+ if {[expr "0x$original_val"] == $val} {
+ return
+ }
+
+ # Adjust value
+ set val [format %X $val]
+ if {[string length $val] == 1} {
+ set val "0$val"
+ }
+
+ # Set value
+ $main_frame.ent_${addr} delete 0 end
+ $main_frame.ent_${addr} insert 0 $val
+
+ # Highlight entry boxes
+ $main_frame.ent_${addr} configure -style Simulator_WhiteBg_HG.TEntry
+ if {$selected_entry == $addr} {
+ foreach entry [list $det_hex $det_oct $det_bin $det_dec] {
+ $entry configure -style Simulator_WhiteBg_HG.TEntry
+ }
+ }
+ }
+
+ ## Validate value in some entry box in the matrix
+ # @parm Int addr - Register address
+ # @parm Char type - h == HEX; o == OCT; b == BIN; d == DEC
+ # @parm String value - Content to validate
+ # @parm Char from - m == Matrix; p == Bottom panel
+ # @return Bool - Result
+ public method sfrmap_validate {addr type value from} {
+ # Prevent recursion
+ if {!$validation_ena} {return 1}
+ set validation_ena 0
+
+ if {$from == {p}} {
+ set addr $selected_entry
+ }
+
+ # Validate the value
+ set value [string trimleft $value 0]
+ if {$value == {}} {
+ set value 0
+ }
+ switch -- $type {
+ h {
+ if {[string length $value] > 2 || ![string is xdigit $value]} {
+ set validation_ena 1
+ return 0
+ }
+ set value [expr "0x$value"]
+ }
+ d {
+ if {[string length $value] > 3 || ![string is digit $value]} {
+ set validation_ena 1
+ return 0
+ }
+ }
+ b {
+ if {[string length $value] > 8 || ![regexp {^[01]*$} $value]} {
+ set validation_ena 1
+ return 0
+ }
+ set value [NumSystem::bin2dec $value]
+ }
+ o {
+ if {[string length $value] > 3 || ![regexp {^[0-7]*$} $value]} {
+ set validation_ena 1
+ return 0
+ }
+ set value [expr "0$value"]
+ }
+ }
+ if {$value > 255 || $value < 0} {
+ set validation_ena 1
+ return 0
+ }
+
+ # Synchronize with engine and simulator control panel
+ $this setSfr $addr [format %X $value]
+ $this SimGUI_disable_sync
+ $this Simulator_GUI_sync S $addr
+ $this SimGUI_enable_sync
+
+ # Synchronize the rest of entry boxes related to this SFR
+ if {$selected_entry == $addr} {
+ if {$type != {d}} {
+ $det_dec delete 0 end
+ $det_dec insert 0 $value
+ }
+ if {$type != {b}} {
+ set txt [NumSystem::dec2bin $value]
+ set len [string length $txt]
+ if {$len != 8} {
+ set txt "[string repeat 0 [expr {8 - $len}]]$txt"
+ }
+ $det_bin delete 0 end
+ $det_bin insert 0 $txt
+ }
+ if {$type != {o}} {
+ set txt [format %o $value]
+ set len [string length $txt]
+ if {$len != 3} {
+ set txt "[string repeat 0 [expr {3 - $len}]]$txt"
+ }
+ $det_oct delete 0 end
+ $det_oct insert 0 $txt
+ }
+ }
+ set txt [format %X $value]
+ if {[string length $txt] == 1} {
+ set txt "0$txt"
+ }
+ if {$from == {p}} {
+ $main_frame.ent_${addr} delete 0 end
+ $main_frame.ent_${addr} insert 0 $txt
+ if {$selected_entry == $addr && $type != {h}} {
+ $det_hex delete 0 end
+ $det_hex insert 0 $txt
+ }
+ } elseif {$selected_entry == $addr} {
+ $det_hex delete 0 end
+ $det_hex insert 0 $txt
+ }
+
+ # Done
+ set validation_ena 1
+ return 1
+ }
+
+ ## Commint new set special function registers
+ # @return void
+ public method sfrmap_commit_new_sfr_set {} {
+ if {!$dialog_opened} {return}
+ foreach wdg [pack slaves $win] {
+ destroy $wdg
+ }
+ set validation_ena 0
+ set selected_entry -1
+ create_win_gui
+ }
+
+ ## Set state of this panel
+ # @parm Bool bool - 0 == Disable; 1 == Enable
+ # @return void
+ public method sfrmap_setEnabled {bool} {
+ if {!$dialog_opened} {return}
+ set enabled $bool
+ if {$bool} {
+ set bool {normal}
+ } {
+ set bool {disabled}
+ }
+ foreach entry [list $det_hex $det_oct $det_bin $det_dec] {
+ $entry configure -state $bool
+ }
+ foreach addr [$this simulator_get_avaliable_sfr] {
+ $main_frame.ent_${addr} configure -state $bool
+ }
+ }
+
+ ## Clear highlight of changed cells
+ # @return void
+ public method sfrmap_clear_hg {} {
+ if {!$dialog_opened} {return}
+
+ foreach addr $defined_sfr {
+ $main_frame.ent_${addr} configure -style Simulator_WhiteBg.TEntry
+ }
+ }
+}