Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:binconvert 0.2.1: Fix titxt input/output, add debug output, fix comments to fix autogenerated documentation.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:5c5dcd2f501206794ff8daf9a3eca13837455339
User & Date: erikj 2017-11-29 01:19:59
Context
2017-11-29
01:22
Discovered pkgindex.tcl wasn't properly added. Added it. check-in: 8d46527ba7 user: erikj tags: trunk
01:19
binconvert 0.2.1: Fix titxt input/output, add debug output, fix comments to fix autogenerated documentation. check-in: 5c5dcd2f50 user: erikj tags: trunk
2017-11-16
21:07
Added *nix script make_pycco mirroring Windows .bat version. Regenerated docs. check-in: 54828bd154 user: erikj tags: trunk
Changes

Changes to binconvert.tcl.

62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
...
185
186
187
188
189
190
191

192
193
194
195
196
197
198
...
229
230
231
232
233
234
235

236
237
238
239
240
241
242
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
...
404
405
406
407
408
409
410
411
412
413

set dir [file dirname [info script]]

##### Usage
# The package procedures are assembled into an ensemble command for external
# use.  Normal usages are:
#
#   * binconvert [readFile](binconvert.html#readfile) <i>format fileName</i>
# (returns *segmentList*)
#   * binconvert [writeFile](binconvert.html#writefile) <i>format segmentList
# fileName</i>
#  * binconvert [addparser](binconvert.html#addparser) <i>fmtId lineParserName
# outputWriterName</i>
#  * binconvert loglevel *newLogLevel*
#
# For Ihex and Srec files, *writeFile* detects the address space needed
# by the Segment List and will automatically select the appropriate subformat
................................................................................

# A simple accessor to change the logging level of the package for debugging.
proc ::binconvert::loglevel {newLevel} {
    ::binconvert::log::setlevel $newLevel
}

# The default log setting for *binconvert* is warning or higher.
loglevel warn


#--------------------------------------------------------------------------
# <a name="readfile"></a>
### readfile

# *readfile* accepts as  its arguments the name of an input file and a token
................................................................................
    try {
        # Unless the data is raw binary, split the input data into lines.
        # If the format *is* raw binary, there's no lines to split, but we
        # need to read it as binary.
        if {$datafmt ne "rawbin"} {
            set dataS [read $chan]
            set dataL [split $dataS \n]

        } else {
            chan configure $chan -translation {binary binary} -encoding binary
            set dataS [read $chan]
        }
    } finally {
        chan close $chan
    }
................................................................................
            # Check the address.  If it's not continuous with the
            # current segment, wrap up the current segment and init a
            # new segment.
            # Either way, after any fix-up work, append the line data
            # to the current active segment.
            }
            DATA {

                if {([lindex $lineL 1] + $segAddr) != $address} {
                    if {[llength $segData] != 0} {
                        lappend resultL $startAddress $segData
                    }
                    set address [expr {[lindex $lineL 1] + $segAddr}]
                    set startAddress $address
                    set segData [list]
................................................................................
            ##### Segment Address line.
            # New segment offset address, where segAddr is an offset that will
            # be added to all line addresses until the next segment addr line.
            #
            # Wrap up any ongoing segment and init a new segment.
            }
            SEGADDR {
                log::debug "Found OFFSETADDR [lindex $lineL 1]"
                set segAddr [lindex $lineL 1]
                if {[llength $segData] != 0} {
                    lappend resultL $startAddress $segData
                }
                set address $segAddr
                set startAddress $address
                set segData [list]

            ##### Start Address line.
            # Contains processor address at which to start execution from,
            # if this was a processor.
            #
            # Note: All start address types map to this.  Because it's
            # relevant to their output format, I16hex and I32hex include an
            # extra field in their output with the format type.  This is
            # passed along and must be dealt with in the writers.
            #
            # N.B. that the "address" for this segment is the text
            # string "STARTADDR", and the data is a single address number
            # rather than a byte list.
            }
            STARTADDR {
                log::debug "Found STARTADDR"
                if {[llength $segData] != 0} {
                    lappend resultL $startAddress $segData
                }
                set address "STARTADDR"
                set startAddress $address
                set segData [lrange $lineL 1 end]

................................................................................
::binconvert::addparser i16hex ProcessIhexLine WriteI16hexFile
::binconvert::addparser i32hex ProcessIhexLine WriteI32hexFile
::binconvert::addparser srec ProcessSrecLine WriteSrecFile
::binconvert::addparser S19 ProcessSrecLine WriteSrecFile S19
::binconvert::addparser S28 ProcessSrecLine WriteSrecFile S28
::binconvert::addparser S37 ProcessSrecLine WriteSrecFile S37
::binconvert::addparser titxt ProcessTitxtLine WriteTitxtFile
::binconvert::addparser titxt ProcessRawbinLine WriteRawbinFile

unset ::BINCONVERT_PKG_VERSION







|

|







 







|







 







>







 







>







 







|









|








|
|


|







 







|


62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
...
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
...
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
...
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
...
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
...
406
407
408
409
410
411
412
413
414
415

set dir [file dirname [info script]]

##### Usage
# The package procedures are assembled into an ensemble command for external
# use.  Normal usages are:
#
#   * binconvert [readfile](binconvert.html#readfile) <i>format fileName</i>
# (returns *segmentList*)
#   * binconvert [writefile](binconvert.html#writefile) <i>format segmentList
# fileName</i>
#  * binconvert [addparser](binconvert.html#addparser) <i>fmtId lineParserName
# outputWriterName</i>
#  * binconvert loglevel *newLogLevel*
#
# For Ihex and Srec files, *writeFile* detects the address space needed
# by the Segment List and will automatically select the appropriate subformat
................................................................................

# A simple accessor to change the logging level of the package for debugging.
proc ::binconvert::loglevel {newLevel} {
    ::binconvert::log::setlevel $newLevel
}

# The default log setting for *binconvert* is warning or higher.
::binconvert::loglevel warn


#--------------------------------------------------------------------------
# <a name="readfile"></a>
### readfile

# *readfile* accepts as  its arguments the name of an input file and a token
................................................................................
    try {
        # Unless the data is raw binary, split the input data into lines.
        # If the format *is* raw binary, there's no lines to split, but we
        # need to read it as binary.
        if {$datafmt ne "rawbin"} {
            set dataS [read $chan]
            set dataL [split $dataS \n]
            log::debug "File read.  [llength $dataL] lines found."
        } else {
            chan configure $chan -translation {binary binary} -encoding binary
            set dataS [read $chan]
        }
    } finally {
        chan close $chan
    }
................................................................................
            # Check the address.  If it's not continuous with the
            # current segment, wrap up the current segment and init a
            # new segment.
            # Either way, after any fix-up work, append the line data
            # to the current active segment.
            }
            DATA {
                log::debug "DATA: $lineL"
                if {([lindex $lineL 1] + $segAddr) != $address} {
                    if {[llength $segData] != 0} {
                        lappend resultL $startAddress $segData
                    }
                    set address [expr {[lindex $lineL 1] + $segAddr}]
                    set startAddress $address
                    set segData [list]
................................................................................
            ##### Segment Address line.
            # New segment offset address, where segAddr is an offset that will
            # be added to all line addresses until the next segment addr line.
            #
            # Wrap up any ongoing segment and init a new segment.
            }
            SEGADDR {
                log::debug "Found SEGADDR [lindex $lineL 1]"
                set segAddr [lindex $lineL 1]
                if {[llength $segData] != 0} {
                    lappend resultL $startAddress $segData
                }
                set address $segAddr
                set startAddress $address
                set segData [list]

            ##### Start Address line.
            # Contains processor address from which to start execution,
            # if this was a processor.
            #
            # Note: All start address types map to this.  Because it's
            # relevant to their output format, I16hex and I32hex include an
            # extra field in their output with the format type.  This is
            # passed along and must be dealt with in the writers.
            #
            # N.B. that the "address" for this segment is the text
            # string "STARTADDR", not an actual numeric address, and the
            # data is a single execution address rather than a byte list.
            }
            STARTADDR {
                log::debug "Found STARTADDR [lrange $lineL 1 end]"
                if {[llength $segData] != 0} {
                    lappend resultL $startAddress $segData
                }
                set address "STARTADDR"
                set startAddress $address
                set segData [lrange $lineL 1 end]

................................................................................
::binconvert::addparser i16hex ProcessIhexLine WriteI16hexFile
::binconvert::addparser i32hex ProcessIhexLine WriteI32hexFile
::binconvert::addparser srec ProcessSrecLine WriteSrecFile
::binconvert::addparser S19 ProcessSrecLine WriteSrecFile S19
::binconvert::addparser S28 ProcessSrecLine WriteSrecFile S28
::binconvert::addparser S37 ProcessSrecLine WriteSrecFile S37
::binconvert::addparser titxt ProcessTitxtLine WriteTitxtFile
::binconvert::addparser rawbin ProcessRawbinLine WriteRawbinFile

unset ::BINCONVERT_PKG_VERSION

Changes to docs/binconvert.html.

95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
      <div class='octowrap'>
        <a class='octothorpe' href='#section-3'>#</a>
      </div>
      <h4>Usage</h4>
<p>The package procedures are assembled into an ensemble command for external
use.  Normal usages are:</p>
<ul>
<li>binconvert <a href="binconvert.html#readfile">readFile</a> <i>format fileName</i>
(returns <em>segmentList</em>)</li>
<li>binconvert <a href="binconvert.html#writefile">writeFile</a> <i>format segmentList
fileName</i></li>
<li>binconvert <a href="binconvert.html#addparser">addparser</a> <i>fmtId lineParserName
outputWriterName</i></li>
<li>binconvert loglevel <em>newLogLevel</em></li>
</ul>
<p>For Ihex and Srec files, <em>writeFile</em> detects the address space needed
by the Segment List and will automatically select the appropriate subformat
................................................................................
    <div class='docs'>
      <div class='octowrap'>
        <a class='octothorpe' href='#section-11'>#</a>
      </div>
      <p>The default log setting for <em>binconvert</em> is warning or higher.</p>
    </div>
    <div class='code'>
      <div class="highlight"><pre><span class="nv">loglevel</span> warn</pre></div>
    </div>
  </div>
  <div class='clearall'></div>
  <div class='section' id='section-12'>
    <div class='docs'>
      <div class='octowrap'>
        <a class='octothorpe' href='#section-12'>#</a>







|

|







 







|







95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
...
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
      <div class='octowrap'>
        <a class='octothorpe' href='#section-3'>#</a>
      </div>
      <h4>Usage</h4>
<p>The package procedures are assembled into an ensemble command for external
use.  Normal usages are:</p>
<ul>
<li>binconvert <a href="binconvert.html#readfile">readfile</a> <i>format fileName</i>
(returns <em>segmentList</em>)</li>
<li>binconvert <a href="binconvert.html#writefile">writefile</a> <i>format segmentList
fileName</i></li>
<li>binconvert <a href="binconvert.html#addparser">addparser</a> <i>fmtId lineParserName
outputWriterName</i></li>
<li>binconvert loglevel <em>newLogLevel</em></li>
</ul>
<p>For Ihex and Srec files, <em>writeFile</em> detects the address space needed
by the Segment List and will automatically select the appropriate subformat
................................................................................
    <div class='docs'>
      <div class='octowrap'>
        <a class='octothorpe' href='#section-11'>#</a>
      </div>
      <p>The default log setting for <em>binconvert</em> is warning or higher.</p>
    </div>
    <div class='code'>
      <div class="highlight"><pre><span class="o">::</span><span class="nv">binconvert</span><span class="o">::</span>loglevel warn</pre></div>
    </div>
  </div>
  <div class='clearall'></div>
  <div class='section' id='section-12'>
    <div class='docs'>
      <div class='octowrap'>
        <a class='octothorpe' href='#section-12'>#</a>

Changes to titxt.tcl.

41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# N.B. that there are no checksums or CRCs, and thus no way of detecting a
# corrupted file unless the corruption makes a line not interpretable.
proc ::binconvert::ProcessTitxtLine {line} {
    # If the line starts with "@", it's an address.
    # Address lines are reported as segment addresses.
    if {[string range $line 0 0] eq "@"} {
        set ::binconvert::TitxtLineAddr 0
        set segAddr [expr {[format "0x%x" [string range $line 1 end]]}]
        return [list SEGADDR $segAddr]
    # If the line is "q", it's the file terminator, reported as EOF.
    } elseif {([string range $line 0 0] eq "q") && ([string length $line] == 1)} {
        return {"EOF" {} }
    # Otherwise, the line should have 1-16 two-digit hexadecimal numbers,
    # each representing one byte, separated by spaces.  Data lines keep a
    # running count of bytes processed since the last segment, to be used
    # as a line address.
    } else {

        try {
            foreach databyte [split $line " "] {
                lappend dataL [expr {[format "0x%x" $databyte] % 256}]
            }
        } on error {result} {
            set errMsg "binconvert: ValidateTitxtLine: Input file syntax error: \
                        could not parse line: $line"
            log::error $errMsg
            puts $result
            puts $::errorCode
            puts $::errorInfo
            error $errMsg
        }
        if {[llength $dataL] > 16} {
            set errMsg "binconvert: ValidateTitxtLine: Input file syntax error: \
                        data line too long (>16 bytes): $line"
            log::error $errMsg
            error $errMsg
        }
        set addr $::binconvert::TitxtLineAddr
        incr ::binconvert::TitxtLineAddr [llength $dataL]
        return [list $addr $dataL]
    }
}


#--------------------------------------------------------------------------
# <a name="WriteTitxtFile"></a>
### WriteTitxtFile

# *WriteTitxtFile* iterates over the segments of the segment list.
#
proc ::binconvert::WriteTitxtFile {segmentList outchan} {
    foreach {addr dataL} $segmentList {
        # For each segment, write the address as an address line
        # (e.g., @5C00).
        puts $outchan [format "\@%x" $addr]

        # The address is followed by the data in lines of 16 bytes,
        # with any short line at the end.  Each byte is represented by
        # two hex digits, separated by a space.
        set outS ""
        foreach databyte $dataL {
            append outS [format "%02x " $databyte]
            if {[string length $outS] > 45} {
                puts $outchan [string trimright $outS]
                set outS ""
            }
        }
        if {[string length $outS] > 0} {
            puts $outchan [string trimright $outS]
        }
    }
    # After all segments are written out, write the "q" line and end.
    puts $outchan "q"
}







|








<
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<













|






|












41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# N.B. that there are no checksums or CRCs, and thus no way of detecting a
# corrupted file unless the corruption makes a line not interpretable.
proc ::binconvert::ProcessTitxtLine {line} {
    # If the line starts with "@", it's an address.
    # Address lines are reported as segment addresses.
    if {[string range $line 0 0] eq "@"} {
        set ::binconvert::TitxtLineAddr 0
        set segAddr [expr {[format "0x%s" [string range $line 1 end]]}]
        return [list SEGADDR $segAddr]
    # If the line is "q", it's the file terminator, reported as EOF.
    } elseif {([string range $line 0 0] eq "q") && ([string length $line] == 1)} {
        return {"EOF" {} }
    # Otherwise, the line should have 1-16 two-digit hexadecimal numbers,
    # each representing one byte, separated by spaces.  Data lines keep a
    # running count of bytes processed since the last segment, to be used
    # as a line address.

    }
    try {
        foreach databyte [split $line " "] {
            lappend dataL [expr {[format "0x%s" $databyte] % 256}]
        }
    } on error {result} {
        set errMsg "binconvert: ValidateTitxtLine: Input file syntax error: \
                    could not parse line: $line"
        log::error $errMsg
        puts $result
        puts $::errorCode
        puts $::errorInfo
        error $errMsg
    }
    if {[llength $dataL] > 16} {
        set errMsg "binconvert: ValidateTitxtLine: Input file syntax error: \
                    data line too long (>16 bytes): $line"
        log::error $errMsg
        error $errMsg
    }
    set addr $::binconvert::TitxtLineAddr
    incr ::binconvert::TitxtLineAddr [llength $dataL]
    return [list DATA $addr $dataL]

}


#--------------------------------------------------------------------------
# <a name="WriteTitxtFile"></a>
### WriteTitxtFile

# *WriteTitxtFile* iterates over the segments of the segment list.
#
proc ::binconvert::WriteTitxtFile {segmentList outchan} {
    foreach {addr dataL} $segmentList {
        # For each segment, write the address as an address line
        # (e.g., @5C00).
        puts $outchan [format "\@%X" $addr]

        # The address is followed by the data in lines of 16 bytes,
        # with any short line at the end.  Each byte is represented by
        # two hex digits, separated by a space.
        set outS ""
        foreach databyte $dataL {
            append outS [format "%02X " $databyte]
            if {[string length $outS] > 45} {
                puts $outchan [string trimright $outS]
                set outS ""
            }
        }
        if {[string length $outS] > 0} {
            puts $outchan [string trimright $outS]
        }
    }
    # After all segments are written out, write the "q" line and end.
    puts $outchan "q"
}