set headings unknown
set inblk 3
+proc manyset {list args} {
+ foreach val $list var $args { upvar 1 $var my; set my $val }
+}
+
proc inblk {bre hre} {
global inblk block headings
return [expr {
}]
}
+proc wantlockind {lockind thing l} {
+ switch -exact $lockind program { return 0 } data { return 1 } \
+ default { error "unknown $thing lockind $lockind in $l" }
+}
+
while {[gets $m l] >= 0} {
if {![regexp {\S} $l]} {
set inblk 0
incr inblk
} elseif {[inblk {^Section Info$} \
{^Section\s+Type\s+Address\s+Location\s+Size\(Bytes\)$}]} {
- if {[string compare udata [lindex $l 1]]} continue
- if {[string compare data [lindex $l 3]]} continue
- set loc [format %08x [lindex $l 2]]
- set s [lrange $l 0 end]
- lappend sections [lrange $l 0 end]
+ manyset $l sec type addr lockind size
+ switch -exact $type code { continue } udata { } \
+ default { error "unknown section type $type in $l" }
+ if {![wantlockind $lockind section $l]} continue
+ set addr [format 0x%08x $addr]
+ lappend sections [list $addr $sec [format 0x%08x $size]]
} elseif {[inblk {^Symbols$} \
{^Name\s+Address\s+Location\s+Storage\s+File$}]} {
- if {[string compare data [lindex $l 2]]} continue
- lappend symbols [lrange $l 0 end]
+ manyset $l sym addr lockind storage file
+ if {![wantlockind $lockind symbol $l]} continue
+ switch -exact $storage {
+ extern { set sym [list {} $sym] }
+ static {
+ regexp {^(.*)\.asm$} $file dummy file
+ set sym [list $file: $sym]
+ }
+ default { error "unknown storage $storage in $l" }
+ }
+ set addr [format 0x%08x $addr]
+ lappend symbols [list $addr $sym]
} elseif {$inblk==3} {
} else {
error "unknown $inblk <$block> <$headings> $l"
set h [open /usr/share/gputils/header/p18f458.inc]
set section unknown
+set lastaddr -1
while {[gets $h l]>=0} {
if {[regexp {^\;\-\-+\s+(\S.*\S)\s+\-\-+$} $l dummy section]} {
continue
} elseif {[regexp -nocase \
{^([a-z][a-z0-9]*)\s+equ\s+h\'0(f[0-9a-f]{2})\'\s*$} \
$l dummy sym loc]} {
+ set addr [format 0x%08x 0x$loc]
foreach pat $ok {
if {[string match $pat $sym]} {
- set loc 0x$loc
- lappend symbols [list $sym $loc data extern x]
- lappend sections [list SFR sfr $loc data 0x1]
+ if {$addr != $lastaddr} {
+ lappend sections [list $addr =SFRs= 0x1]
+ set lastaddr $addr
+ }
+ lappend symbols [list $addr [list SFR $sym]]
}
}
} elseif {[regexp -nocase {^\;\s*reserved} $l]} {
}
}
-puts >$sections<
-puts >$symbols<
-
-exit 0
+lappend sections [list 0x1000 =END= 0]
+set sections [lsort $sections]
+set symbols [lsort $symbols]
set p [open $port {RDWR NONBLOCK} 0]
exec stty -F $port min 1 time 0 -istrip -ocrnl -onlcr -onocr -opost \
9600 clocal cread -crtscts -hup -parenb cs8 -cstopb \
-ixoff bs0 cr0 ff0 nl0 -ofill -olcuc
-fconfigure $p -blocking yes
+fconfigure $p -blocking yes -buffering none \
+ -translation binary -encoding binary
-set ms [expr {$slave ? "m" : "s"}]
+set ms [expr {
+ $slave < 0 ? "t" :
+ $slave ? "m" :
+ "s"
+}]
+
+proc xmit {b} {
+ global p
+ puts -nonewline $p [format %c $b]
+}
proc xmit_s {b} {
xmit [expr {$b | 0x80}]
- xmit [expr {$slave ^ 0x30}] }
+ xmit [expr {$slave ^ 0x30}]
}
proc setup_m {} { xmit 0 }
proc setup_s {} { xmit 0; xmit_s 0 }
+proc setup_t {} { }
+
+proc selectaddr_m {a} { error }
+proc selectaddr_s {a} { error }
+proc selectaddr_t {a} { global tsa; set tsa $a }
+
+proc readbytes_m {n} { error }
+proc readbytes_s {n} { error }
+proc readbytes_t {n} {
+ global tsa
+ set l {}
+ while {$n > 0} {
+ lappend l [expr {$tsa - ($tsa >> 8)}]
+ incr tsa
+ incr n -1
+ }
+ return $l
+}
+
+set readcursor -1
+
+proc readbytes {addr n} {
+ global readcursor ms
+ if {$readcursor != $addr} {
+ if {$addr & ~0x0fff} { error "bad addr $addr" }
+ if {$n > (0x1000 - $addr)} { error "bad len $addr+$n" }
+ selectaddr_$ms $addr
+ set readcursor [expr {$addr + $n}]
+ }
+ return [readbytes_$ms $n]
+}
+
+proc thingbynum {thing nnum} {
+ upvar #0 ${thing}num num
+ upvar #0 ${thing}s things
+ upvar #0 ${thing}info info
+ upvar #0 ${thing}addr addr
+ upvar #0 ${thing} name
+ set num $nnum
+ if {$num < [llength $things]} {
+ set info [lindex $things $num]
+ } else {
+ set info {0x7fffffff =DUMMY-END= 1}
+ }
+ manyset $info addr name
+ if {![string compare $thing section]} {
+ global sectionsize sectionend
+ set sectionsize [lindex $info 2]
+ set sectionend [expr {$addr + $sectionsize}]
+ }
+}
+
+proc thingnext {thing} {
+ upvar #0 ${thing}num num
+ incr num
+ thingbynum $thing $num
+}
+
+thingbynum section 0
+thingbynum symbol 0
+set shownsection {}
+set sectionchange 0
+set insection 0
+set addr 0
+set now_max 4
+set inline -1
+set displine 0
setup_$ms
-xmit 0
+proc endline {} {
+ global inline displine
+ if {$inline} { puts -nonewline "\n"; incr displine }
+ set inline 0
+}
+
+proc show {sym} {
+ global insection section displine addr shownsection inline
+ if {$insection && [string compare $section $shownsection]} {
+ endline
+ puts "---------- $section ----------"
+ set shownsection $section
+ set displine 0
+ } elseif {!$insection && [string length $shownsection]} {
+ endline
+ puts "------------------------------"
+ set shownsection {}
+ set displine 0
+ }
+ if {[string length $sym]} {
+ if {$displine && $inline && !($displine&3)} {
+ puts -nonewline "\n"
+ }
+ endline
+ }
+ if {!$inline} {
+ puts -nonewline [format "%08x %-15s %-20s" $addr \
+ [lindex $sym 0] [lindex $sym 1]]
+ set inline 1
+ }
+}
-if {$slave} {
- xmit 0x80
-xmit_slave 0x80
- xmit
+while {$sectionnum < [llength $sections]} {
+ set now_section [expr {$sectionchange - $addr}]
+ if {!$now_section && !$insection} {
+ set insection 1
+ set sectionchange $sectionend
+ continue
+ }
+ set now_symbol [expr {$symboladdr - $addr}]
+ if {!$now_symbol} {
+ show $symbol
+ thingnext symbol
+ continue
+ }
+ if {!$now_section && $insection} {
+ if {[string compare $section =SFRs=]} {
+ show { }
+ }
+ thingnext section
+ set insection 0
+ set sectionchange $sectionaddr
+ }
+ set now $now_symbol
+ if {$now > $now_section} { set now $now_section }
+ if {!$insection} {
+ incr addr $now
+ continue
+ }
+ if {$now > $now_max} { set now $now_max }
+ show {}
+ set bytes [readbytes $addr $now]
+ foreach b $bytes {
+ puts -nonewline [format " %02x" [expr {$b & 0xff}]]
+ incr addr
+ }
+ set inline 1
}