_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