home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.whtech.com
/
ftp.whtech.com.tar
/
ftp.whtech.com
/
club100
/
ref
/
binary.doc
< prev
next >
Wrap
Text File
|
2006-10-19
|
4KB
|
76 lines
_Using .DO files to store 8-bit binary data_
by Tracy Allen, 5/8/89
released through Club 100 to the public domain, except for for-profit
publication.
.
I often need to store 8-bit data in .DO files on the M100/102/200. This
data comes from sensors (temperature, etc.) and takes on byte values in
the range of 0 to 255. If it is stored in its ascii form it takes a lot
more room in memory than it does when it is stored in binary. For
example, a temperature of 212 degrees Celsius stored as ascii takes three
bytes "2" "1" "2" plus a space or a tab to separate it from the next
datum. The same datum stored as binary takes only one byte, and no space
or tab is needed, because _all_ data take only one byte with a binary
range of 0 to 255. It is efficient data compression.
.
The problem is that 5 out of the 256 possible byte values have special
meaning to the M100/102/200. These special ascii byte values are: 0
(zero, null), 10 (line-feed), 13 (carriage return), 26 (end-of-file) and
127 (delete). Of those, the the 0 or the 127 cannot be entered in a file
using normal PRINT# statements. The 26 means end-of-file and you will get
an error message if you try to read past it using normal INPUT#
statements, and the operating system sooner or later will zap anything
that follows the 26. The 10 and the 13 can be stored and retreived from
the files, but carriage return and linefeed have special significance to
the LINEINPUT# statement. I like to use LINEINPUT# to retrieve groups of
readings. I store groups of hourly readings on lines terminated by a
carriage return, and doing so helps to maintain the integrity of the data
should a reading happen to be lost. The line-feed caharacter is special
only because of a peculiarity of the LINEINPUT# command. If line-feed
precedes carriage-return, the LINEINPUT# command does not recognize the
carriage-return as the end-of-line character and will instead read it in
as data up to the next carriage return that is not preceded by line-feed.
Line-feeds that immediately follow a carriage return are treated as part
of the end-of-line. So you canUt have LF as part of data either directly
before or directly after a CR.
.
An approach that gets around this is to map the five special characters up
to characters 251->255. I can discard those high values, because the
temperatures and other data never get so high:
. If D%>250 then D%=250
.where D% is the datum to be stored. Map the characters as follows:
. If D%=0 then D%=255
. If D%=10 then D%=254
. If D%=13 then D%=253
. If D%=26 then D%=252
. If D%=127 then D%=251
At this point the data contain none of the offending characters. Write it:
. PRINT#1,D%;
And when it's time to end a line of data, put in a CR:
. PRINT#1,CHR$(13);
That's it for storing the data.
Reading in the data is exactly the opposite process. Let's say you want
to send the data (TAB-delimitd) over the modem to another computer:
. MAXFILES=2
. OPEN "DATA.DO" FOR INPUT AS 1
. OPEN "MDM:8N1E" FOR OUTPUT AS 2
.LOOP: IF EOF(1) THEN PRINT#2,CHR$(26):CLOSE:END
. LINEINPUT#1,A$
. FOR I=1 TO LEN(A$)
. D%=VAL(MID$(A$,I,1)) 'get the I'th ascii chr in
line
. IF D%=255 THEN D%=0 'reverse mapping
. IF D%=254 THEN D%=10
. IF D%=253 THEN D%=13
. IF D%=252 THEN D%=26
. IF D%=251 THEN D%=127
. PRINT#2,D%;
. IF I<LEN(A%) THEN PRINT#2,CHR$(9); 'TAB-delimit
. NEXT I
. GOTO LOOP
.
That's it! -- Tracy