TPDD Base Protocol: Difference between revisions

From Bitchin100 DocGarden
Jump to navigationJump to search
No edit summary
 
(26 intermediate revisions by 2 users not shown)
Line 1: Line 1:
<P><B>General Reference</B><UL><LI>Disks are single sided 3.5 inch standard disks</LI><LI>PDD1 - 40 tracks 2 sectors 1280 bytes/sector (100K/disk)</LI><LI>PDD2 - 80 tracks 2 sectors 1280 bytes/sector (200K/disk treated as two banks of 100k
== General Reference ==
each)</LI><LI>Maximum file size = 64k. </LI><LI>Maximum number of directory entries (files) is 40 for PDD1 and 80 for PDD2.</LI><LI>File names are maximum 24 characters (padded with trailing blanks) although Tandy always
 
used 6 for filename and 2 for filetype, with period seperator (i.e. XXXXXX.TT) </LI><LI>All communications with drive are at 19,200 bps. PDD1 has dip switches so this can drop
Note that this information was taken from Compuserve archives. Some stuff has been fixed. The best way to understand the protocol is to look at existing code like LaddieAlpha or DLPlus.
to 9600bps. PDD2 is auto sensing down to 1200bps (??? - can anyone confirm this?).</LI></UL>
 
If you have changes please suggest or make them.
 
<UL>
  <LI>Disks are single sided 3.5 inch standard disks</LI>
  <LI>PDD1 - 40 tracks 2 sectors 1280 bytes/sector (100K/disk)</LI>
  <LI>PDD2 - 80 tracks 2 sectors 1280 bytes/sector (200K/disk treated as two banks of 100k
each)</LI>
  <LI>Maximum file size = 64k. </LI>
  <LI>Maximum number of directory entries (files) is 40 for PDD1 and 80 for PDD2.</LI>
  <LI>File names are maximum 24 characters (padded with trailing blanks) although Tandy always
used 6 for filename and 2 for filetype, with period seperator (i.e. XXXXXX.TT)</LI>
  <LI>All communications with drive are at 19,200 bps. PDD1 has dip switches so this can drop
to 9600bps. PDD2 is auto sensing down to 1200bps (??? - can anyone confirm this?).</LI>
</UL>


== Command Format ==
== Command Format ==
Line 20: Line 34:
</BLOCKQUOTE>
</BLOCKQUOTE>


<H2>Command Type</H2><P ALIGN="CENTER">(all values are in HEX)</P>
== Command Type ==
 
<P ALIGN="CENTER">(all values are in HEX)</P>
 
{|  WIDTH="100%" BORDER="1"  
{|  WIDTH="100%" BORDER="1"  
! &nbsp;command  
! &nbsp;command  
Line 65: Line 82:
| &nbsp;0D
| &nbsp;0D
| &nbsp;12
| &nbsp;12
|}<P>* PDD2 treats the disk as two banks of 100k each. All commands except these two must
|}
 
<P>* PDD2 treats the disk as two banks of 100k each. All commands except these two must
specify the bank number as part of the request. The above commands reference BANK 0. To
specify the bank number as part of the request. The above commands reference BANK 0. To
reference BANK 1 you must add 40 HEX to these values (bit 6 = bank number). E.G. 'open
reference BANK 1 you must add 40 HEX to these values (bit 6 = bank number). E.G. 'open
file' becomes 41 for BANK 1.</P><HR><H2>Request Command details</H2>
file' becomes 41 for BANK 1.</P>
{|  WIDTH="100%" BORDER="1"
 
| &nbsp;<P><B><FONT SIZE="+1">Type 00 - Directory Reference</FONT></B></P><PRE><BIG><FONT SIZE="-1">    2  1  1  24            1          1          1      bytes</FONT><FONT SIZE="-1"> +----+--+--+--------------+----------+------------+------+</FONT><FONT SIZE="-1"> &#124;5a5a&#124;00&#124;1a&#124; filename    &#124;attribute &#124;search form &#124;chksum&#124;</FONT><FONT SIZE="-1"> +----+--+--+--------------+----------+------------+------+</FONT></BIG></PRE><P>Preamble - always 'ZZ'<BR>
== Request Command details ==
request - type 00h<BR>
 
length - length of data 1ah (26 decimal)<BR>
=== Type 00 - Directory Reference ===
filename - padded with blanks<BR>
 
attribute - specify 'F' (not used normally)<BR>
<PRE>    2  1  1  24            1          1          1      bytes
search form -</P><BLOCKQUOTE><P>00h - reference file for open or delete<BR>
+----+--+--+--------------+----------+------------+------+
01h - request first directory block<BR>
&#124;5a5a&#124;00&#124;1a&#124; filename    &#124;attribute &#124;search form &#124;chksum&#124;  
02h - request next directory block<BR>
+----+--+--+--------------+----------+------------+------+</PRE>
03h - request previous directory block<BR>
 
04h - end directory reference</P></BLOCKQUOTE><P>checksum - see below for calculating
* Preamble - always 'ZZ'
|-
* request - type 00h*
| &nbsp;<P><B><FONT SIZE="+1">Type 01 - Open file</FONT></B></P><PRE><FONT SIZE="-1"><BIG>  2  1  1  1    1      bytes</BIG></FONT><BIG><FONT SIZE="-1"> +----+--+--+------+------+</FONT><FONT SIZE="-1"> &#124;5a5a&#124;01&#124;01&#124; mode &#124;chksum&#124;</FONT><FONT SIZE="-1"> +----+--+--+------+------+</FONT></BIG></PRE><P>Preamble - always 'ZZ'<BR>
* length - length of data 1ah (26 decimal)
request - type 01h<BR>
* filename - padded with blanks
length - length of data 01h (1 decimal)<BR>
* attribute - specify 'F' (not used normally)
mode - </P><BLOCKQUOTE><P>01h - open new file for WRITE<BR>
* search form
02h - open existing file for APPEND<BR>
 
03h - open existing file for READ</P></BLOCKQUOTE><P>checksum - see below for calculating
<BLOCKQUOTE>
|-
* 00h - reference file for open or delete
| &nbsp;<P><B><FONT SIZE="+1">Type 02 - Close file</FONT></B></P><PRE><FONT SIZE="-1"><BIG>  2  1  1  1        bytes</BIG></FONT><BIG><FONT SIZE="-1"> +----+--+--+------+</FONT><FONT SIZE="-1"> &#124;5a5a&#124;02&#124;00&#124;chksum&#124;</FONT><FONT SIZE="-1"> +----+--+--+------+</FONT></BIG></PRE><P>Preamble - always 'ZZ'<BR>
* 01h - request first directory block
request - type 02h<BR>
* 02h - request next directory block
length - length of data 00h (no data field)<BR>
* 03h - request previous directory block
* 04h - end directory reference
</BLOCKQUOTE>
 
checksum - see below for calculating
checksum - see below for calculating
|-
 
| <B><FONT SIZE="+1">Type 03 - Read file</FONT></B><PRE><FONT SIZE="-1"><BIG>  2  1  1  1       bytes</BIG></FONT><BIG><FONT SIZE="-1"> +----+--+--+------+</FONT><FONT SIZE="-1"> &#124;5a5a&#124;03&#124;00&#124;chksum&#124;</FONT><FONT SIZE="-1"> +----+--+--+------+</FONT></BIG></PRE><P>Preamble - always 'ZZ'<BR>
=== Type 01 - Open file ===
request - type 03h<BR>
 
length - length of data 00h (no data field)<BR>
<PRE>  2  1  1  1     1      bytes
+----+--+--+------+------+
&#124;5a5a&#124;01&#124;01&#124; mode &#124;chksum&#124;
+----+--+--+------+------+</PRE>
 
* Preamble - always 'ZZ'
* request - type 01h
* length - length of data 01h (1 decimal)
* mode -
 
<BLOCKQUOTE>
* 01h - open new file for WRITE
* 02h - open existing file for APPEND
* 03h - open existing file for READ
</BLOCKQUOTE>
 
checksum - see below for calculating
checksum - see below for calculating
|-
 
| <B><FONT SIZE="+1">Type 04 - Write file</FONT></B><PRE><FONT SIZE="-1"><BIG>  2  1  1   1-128 1       bytes</BIG></FONT><BIG><FONT SIZE="-1"> +----+--+---+------+------+</FONT><FONT SIZE="-1"> &#124;5a5a&#124;04&#124;01-&#124;data  &#124;chksum&#124;</FONT><FONT SIZE="-1"> &#124;    &#124;  &#124; 80&#124;      &#124;      &#124;</FONT><FONT SIZE="-1"> +----+--+---+------+------+</FONT></BIG></PRE><P>Preamble - always 'ZZ'<BR>
=== Type 02 - Close file ===
reques - type 04<BR>
 
length - length of data 01h-80h (actual length of data)<BR>
<PRE>  2  1  1  1       bytes
checksum - see below for calculating
+----+--+--+------+
|-
&#124;5a5a&#124;02&#124;00&#124;chksum&#124;
| <B><FONT SIZE="+1">Type 05 - Delete file</FONT></B><PRE><FONT SIZE="-1"><BIG>  2  1  1  1       bytes</BIG></FONT><BIG><FONT SIZE="-1"> +----+--+--+------+</FONT><FONT SIZE="-1"> &#124;5a5a&#124;05&#124;00&#124;chksum&#124;</FONT><FONT SIZE="-1"> +----+--+--+------+</FONT></BIG></PRE><P>Preamble - always 'ZZ'<BR>
+----+--+--+------+</PRE>
request - type 05h<BR>
 
length - length of data 00h (no data field)<BR>
* Preamble - always 'ZZ'
checksum - see below for calculating
* request - type 02h
|-
* length - length of data 00h (no data field)
| <B><FONT SIZE="+1">Type 06 - Format Disk</FONT></B><PRE><FONT SIZE="-1"><BIG>  2  1  1  1        bytes</BIG></FONT><BIG><FONT SIZE="-1"> +----+--+--+------+</FONT><FONT SIZE="-1"> &#124;5a5a&#124;06&#124;00&#124;chksum&#124;</FONT><FONT SIZE="-1"> +----+--+--+------+</FONT></BIG></PRE><P>Preamble - always 'ZZ'<BR>
* checksum - see below for calculating
request - type 06h<BR>
 
length - length of data 00h (no data field)<BR>
=== Type 03 - Read file ===
checksum - see below for calculating
 
|-  
<pre>   2  1  1  1        bytes
| <B><FONT SIZE="+1">Type 07 - Drive Status</FONT></B><PRE><FONT SIZE="-1"><BIG>  2  1  1  1        bytes</BIG></FONT><BIG><FONT SIZE="-1"> +----+--+--+------+</FONT><FONT SIZE="-1"> &#124;5a5a&#124;07&#124;00&#124;chksum&#124;</FONT><FONT SIZE="-1"> +----+--+--+------+</FONT></BIG></PRE><P>Preamble - always 'ZZ'<BR>
+----+--+--+------+
request - type 07h<BR>
&#124;5a5a&#124;03&#124;00&#124;chksum&#124;
length - length of data 00h (no data field)<BR>
+----+--+--+------+</PRE>
checksum - see below for calculating
 
|-
* Preamble - always 'ZZ'
| <B><FONT SIZE="+1">Type 0C - Drive Condition</FONT></B><PRE><FONT SIZE="-1"><BIG>  2  1  1  1        bytes</BIG></FONT><BIG><FONT SIZE="-1"> +----+--+--+------+</FONT><FONT SIZE="-1"> &#124;5a5a&#124;0C&#124;00&#124;chksum&#124;</FONT><FONT SIZE="-1"> +----+--+--+------+</FONT></BIG></PRE><P>Preamble - always 'ZZ'<BR>
* request - type 03h
request - type 0Ch<BR>
* length - length of data 00h (no data field)
length - length of data 00h (no data field)<BR>
* checksum - see below for calculating
checksum - see below for calculating
 
|-
=== Type 04 - Write file ===
| <B><FONT SIZE="+1">Type 0D - Rename file </FONT></B><PRE><FONT SIZE="-1"><BIG>  2  1  1  24    1      1      bytes</BIG></FONT><BIG><FONT SIZE="-1"> +----+--+--+-------+------+------+</FONT><FONT SIZE="-1"> &#124;5a5a&#124;0D&#124;19&#124;newname&#124;attrib&#124;chksum&#124;</FONT><FONT SIZE="-1"> +----+--+--+-------+------+------+</FONT></BIG></PRE><P>Preamble - always 'ZZ'<BR>
 
request - type 0D<BR>
<PRE>  2  1  1   1-128 1       bytes
length - length of data 19h (25 decimal)<BR>
+----+--+---+------+------+
newname - new name for the file<BR>
&#124;5a5a&#124;04&#124;01-&#124;data  &#124;chksum&#124;
attribute- not used (specify 'F')<BR>
&#124;    &#124;  &#124; 80&#124;      &#124;      &#124;
checksum - see below for calculating
+----+--+---+------+------+</PRE>
|}<H2>Return Command Details</H2>
 
{| WIDTH="100%" BORDER="1"
* Preamble - always 'ZZ'
| <B><FONT SIZE="+1">Type 10 - Read file Return </FONT></B><PRE><FONT SIZE="-1"><BIG> 1  1  0-128      1      bytes</BIG></FONT><BIG><FONT SIZE="-1"> +--+---+----------+-----+</FONT><FONT SIZE="-1"> &#124;10&#124;00-&#124; file data&#124;cksum&#124;</FONT><FONT SIZE="-1"> &#124; &#124; 80&#124;          &#124;cksum&#124;</FONT><FONT SIZE="-1"> +--+---+----------+-----+</FONT></BIG></PRE><P>return - type 10<BR>
* request - type 04
length - length of data 00h-80h (0-128 decimal)<UL><LI>if length is equal to 80h there may be more data - you must issue another read command</LI><LI>if length is less than 80h then this is last block</LI></UL><P>file data - data read from file<BR>
* length - length of data 01h-80h (actual length of data)
checksum - see below for calculating
* checksum - see below for calculating
|-
 
| <B><FONT SIZE="+1">Type 11 - Directory reference return</FONT></B><PRE><FONT SIZE="-1"><BIG> 1  1  24       1      2    1    1      bytes</BIG></FONT><BIG><FONT SIZE="-1"> +--+--+--------+------+----+----+-----+</FONT><FONT SIZE="-1"> &#124;11&#124;1c&#124;filename&#124;attrib&#124;size&#124;free&#124;cksum&#124;</FONT><FONT SIZE="-1"> +--+--+--------+------+----+----+-----+</FONT></BIG></PRE><P>return - type 11h<BR>
=== Type 05 - Delete file ===
length - length of data 1Ch (28 decimal)<BR>
 
filename - file name - if no name specied is 00H. If at end of directory is 00H.<BR>
<PRE>   2  1  1  1        bytes
attribute - not used<BR>
+----+--+--+------+
size - size of file<BR>
&#124;5a5a&#124;05&#124;00&#124;chksum&#124;
free - number of free sectors (multiply by 1280 for bytes)<BR>
+----+--+--+------+</PRE>
checksum - see below for calculating
 
|-
* Preamble - always 'ZZ'
| &nbsp;<P><B><FONT SIZE="+1">Type 12 - Normal Return</FONT></B></P><PRE><FONT SIZE="-1"><BIG> 1 1 1      1     bytes</BIG></FONT><BIG><FONT SIZE="-1"> +--+--+-----+-----+</FONT><FONT SIZE="-1"> &#124;12&#124;01&#124;error&#124;cksum&#124;</FONT><FONT SIZE="-1"> +--+--+-----+-----+</FONT></BIG></PRE><P>return - type 12h<BR>
* request - type 05h
length - length of data 01h <BR>
* length - length of data 00h (no data field)
error code-</P>
* checksum - see below for calculating
 
=== Type 06 - Format Disk ===
 
<PRE>   2  1  1  1        bytes
+----+--+--+------+
&#124;5a5a&#124;06&#124;00&#124;chksum&#124;
+----+--+--+------+</PRE>
 
* Preamble - always 'ZZ'
* request - type 06h
* length - length of data 00h (no data field)
* checksum - see below for calculating
 
=== Type 07 - Drive Status ===
<PRE>
  2  1  1  1        bytes<
+----+--+--+------+
&#124;5a5a&#124;07&#124;00&#124;chksum&#124;
+----+--+--+------+</PRE>
 
* Preamble - always 'ZZ'
* request - type 07h
* length - length of data 00h (no data field)
* checksum - see below for calculating
 
=== Type 0C - Drive Condition ===
<PRE>
  2  1 1  1       bytes
  +----+--+--+------+
&#124;5a5a&#124;0C&#124;00&#124;chksum&#124;
+----+--+--+------+</PRE>
 
* Preamble - always 'ZZ'
* request - type 0Ch
* length - length of data 00h (no data field)
* checksum - see below for calculating
 
=== Type 0D - Rename file ===
<PRE>
  2  1  1  24    1      1      bytes<
  +----+--+--+-------+------+------+
&#124;5a5a&#124;0D&#124;19&#124;newname&#124;attrib&#124;chksum&#124;
+----+--+--+-------+------+------+</PRE>
 
* Preamble - always 'ZZ'
* request - type 0D
* length - length of data 19h (25 decimal)
* newname - new name for the file
* attribute- not used (specify 'F')
* checksum - see below for calculating
 
== Return Command Details ==
=== Type 10 - Read file Return ===
<PRE>
1  1  0-128       1      bytes
+--+---+----------+-----+
&#124;10&#124;00-&#124; file data&#124;cksum&#124;
&#124; &#124; 80&#124;         &#124;cksum&#124;
+--+---+----------+-----+</PRE>
 
* return - type 10
* length - length of data 00h-80h (0-128 decimal)<UL><LI>if length is equal to 80h there may be more data - you must issue another read command</LI><LI>if length is less than 80h then this is last block</LI></UL>
* file data - data read from file
* checksum - see below for calculating
 
=== Type 11 - Directory reference return ===
<PRE>
1 1   24      1      2    1    1       bytes
+--+--+--------+------+----+----+-----+
&#124;11&#124;1c&#124;filename&#124;attrib&#124;size&#124;free&#124;cksum&#124;
+--+--+--------+------+----+----+-----+</PRE>
 
* return - type 11h
* length - length of data 1Ch (28 decimal)
* filename - file name - if no name specied is 00H. If at end of directory is 00H.
* attribute - not used
* size - size of file, big endian format
* free - number of free sectors (multiply by 1280 for bytes)
* checksum - see below for calculating
 
=== Type 12 - Normal Return ===
<PRE> 1  1  1      1      bytes
+--+--+-----+-----+
&#124;12&#124;01&#124;error&#124;cksum&#124;
+--+--+-----+-----+</PRE>
 
* return - type 12h
* length - length of data 01h
* error code-
 
{|  WIDTH="100%" BORDER="1"  
{|  WIDTH="100%" BORDER="1"  
| &nbsp;00 - normal (no error)
| &nbsp;00 - normal (no error)
Line 182: Line 309:
| &nbsp;71 - disk change error
| &nbsp;71 - disk change error
| &nbsp;
| &nbsp;
|}<P>checksum - see below for calculating
|}
|-
 
| <B>Type 15 - Drive Condition Return </B><PRE><FONT SIZE="-1"><BIG> 1  1  1          1      bytes</BIG></FONT><BIG><FONT SIZE="-1"> +--+--+---------+-----+</FONT><FONT SIZE="-1"> &#124;15&#124;01&#124;condition&#124;cksum&#124;</FONT><FONT SIZE="-1"> +--+--+---------+-----+</FONT></BIG></PRE><P>return - type 15h<BR>
* checksum - see below for calculating
length - length of data 01h <BR>
 
condition- bit values</P><PRE><FONT SIZE="-1">        7 6 5 4 3 2 1 0    bit</FONT><FONT SIZE="-1">        +-+-+-+-+-+-+-+-+</FONT><FONT SIZE="-1">    MSB &#124;0&#124;0&#124;0&#124;0&#124;x&#124;x&#124;x&#124;x&#124; LSB</FONT><FONT SIZE="-1">        +-+-+-+-+-+-+-+-+</FONT><FONT SIZE="-1">                &#124; &#124; &#124; &#124;</FONT><FONT SIZE="-1">                &#124; &#124; &#124; +--power (0=normal 1=low)</FONT><FONT SIZE="-1">                &#124; &#124; +----write protect (0=not prot 1=prot)</FONT><FONT SIZE="-1">                &#124; +------disk out (0=disk in 1=disk out)</FONT><FONT SIZE="-1">                +--------disk change status (0=not changed 1=changed)</FONT></PRE><P>checksum - see below for calculating
=== Type 15 - Drive Condition Return ===
|}<HR><H2>Sequence of Events</H2>
<PRE>
{|  WIDTH="100%" BORDER="1"  
1  1  1          1      bytes
+--+--+---------+-----+
&#124;15&#124;01&#124;condition&#124;cksum&#124;
+--+--+---------+-----+</PRE>
 
* return - type 15h
* length - length of data 01h
* condition- bit values
 
<PRE>        7 6 5 4 3 2 1 0    bit
        +-+-+-+-+-+-+-+-+
    MSB &#124;0&#124;0&#124;0&#124;0&#124;x&#124;x&#124;x&#124;x&#124; LSB
        +-+-+-+-+-+-+-+-+
                &#124; &#124; &#124; &#124;
                &#124; &#124; &#124; +--power (0=normal 1=low)
                &#124; &#124; +----write protect (0=not prot 1=prot)
                &#124; +------disk out (0=disk in 1=disk out)
                +--------disk change status (0=not changed 1=changed)</PRE>
* checksum - see below for calculating
 
<H2>Sequence of Events</H2>
{|  WIDTH="100%"  
| &nbsp;<I>Get directory</I>
| &nbsp;<I>Get directory</I>
| req 00 search form 01<BR>
| req 00 search form 01<BR>
Line 212: Line 360:
| &nbsp;req 00 search form 00<BR>
| &nbsp;req 00 search form 00<BR>
req 05
req 05
|}<HR><H2>Calculating Checksum</H2><P>The check sum is &quot;the one's complement of the least significant byte of the number
|}<HR>
 
<H2>Calculating Checksum</H2><P>The check sum is &quot;the one's complement of the least significant byte of the number
of bytes from the block format through the data block&quot;. Most people (me included)
of bytes from the block format through the data block&quot;. Most people (me included)
don't understand what that involves if you have to calculate it. Fortunately I found an
don't understand what that involves if you have to calculate it. Fortunately I found an
example of how to do this and so I'm passing it on to you.</P><P>Checksum=(bytes MOD 256) XOR 255</P><P>where bytes = number of bytes including the Request Type, Length and all Data fields
example of how to do this and so I'm passing it on to you.</P><P>Checksum=(sum-of-bytes MOD 256) XOR 255</P><P>where bytes = the bytes including the Request Type, Length and all Data fields
(but not including the preamble).</P><HR><H2>Using this Information</H2><P>A lot of the above commands can be set up in advance since there is no variable part to
(but not including the preamble).</P><HR><H2>Using this Information</H2><P>A lot of the above commands can be set up in advance since there is no variable part to
calculate. Some commands must have the length and checksum calculate as the data is built
calculate. Some commands must have the length and checksum calculate as the data is built
but the others don't. Here's how I set up some of the commands in my program:</P><P><FONT FACE="Arial"><FONT SIZE="-1">Close$=&quot;ZZ&quot;+Chr$(2)+Chr$(0)+Chr$(253)</FONT><BR><FONT SIZE="-1">Dir1$=&quot;ZZ&quot;+Chr$(0)+Chr$(26)+Space$(24)+&quot;F&quot;+Chr$(1)+Chr$(158)</FONT><BR><FONT SIZE="-1">Dir2$=&quot;ZZ&quot;+Chr$(0)+Chr$(26)+Space$(24)+&quot;F&quot;+Chr$(2)+Chr$(157)</FONT><BR><FONT SIZE="-1">Status$=&quot;ZZ&quot;+Chr$(7)+Chr$(0)+Chr$(248)+Chr$(13)</FONT><BR><FONT SIZE="-1">Format$=&quot;ZZ&quot;+Chr$(6)+Chr$(0)+Chr$(249)+Chr$(13)<BR>
but the others don't. Here's how I set up some of the commands in my program:</P>
Erase$=&quot;ZZ&quot;+Chr$(5)+Chr$(0)+Chr$(250)</FONT><BR><FONT SIZE="-1">Seek$(1)=&quot;ZZ&quot;+Chr$(1)+Chr$(1)+Chr$(1)+Chr$(252)</FONT><BR><FONT SIZE="-1">Seek$(2)=&quot;ZZ&quot;+Chr$(1)+Chr$(1)+Chr$(2)+Chr$(251)</FONT><BR><FONT SIZE="-1">Seek$(3)=&quot;ZZ&quot;+Chr$(1)+Chr$(1)+Chr$(3)+Chr$(250)</FONT></FONT></P><P>The above commands can be sent directly without any calculating to speed up your
 
program. </P><HR><P ALIGN="center"><A HREF="index.html"><IMG SRC="../graphics/ureturn.gif" ALT="ureturn.gif (2080 bytes)" WIDTH="155" HEIGHT="60"></A></P><P><BR></P>
<pre>
Close$   = "ZZ"+Chr$(2)+Chr$(0)+Chr$(253)
Dir1$   = "ZZ"+Chr$(0)+Chr$(26)+Space$(24)+"F"+Chr$(1)+Chr$(158)
Dir2$   = "ZZ"+Chr$(0)+Chr$(26)+Space$(24)+"F"+Chr$(2)+Chr$(157)
Status$ = "ZZ"+Chr$(7)+Chr$(0)+Chr$(248)+Chr$(13)
Format$ = "ZZ"+Chr$(6)+Chr$(0)+Chr$(249)+Chr$(13)
Erase$   = "ZZ"+Chr$(5)+Chr$(0)+Chr$(250)
Seek$(1) = "ZZ"+Chr$(1)+Chr$(1)+Chr$(1)+Chr$(252)
Seek$(2) = "ZZ"+Chr$(1)+Chr$(1)+Chr$(2)+Chr$(251)
Seek$(3) = "ZZ"+Chr$(1)+Chr$(1)+Chr$(3)+Chr$(250)
</pre>
 
<P>The above commands can be sent directly without any calculating to speed up your
program. </P>
 
[[Category:Model T Developer Reference]]

Latest revision as of 15:17, 12 December 2019

General Reference

Note that this information was taken from Compuserve archives. Some stuff has been fixed. The best way to understand the protocol is to look at existing code like LaddieAlpha or DLPlus.

If you have changes please suggest or make them.

  • Disks are single sided 3.5 inch standard disks
  • PDD1 - 40 tracks 2 sectors 1280 bytes/sector (100K/disk)
  • PDD2 - 80 tracks 2 sectors 1280 bytes/sector (200K/disk treated as two banks of 100k each)
  • Maximum file size = 64k.
  • Maximum number of directory entries (files) is 40 for PDD1 and 80 for PDD2.
  • File names are maximum 24 characters (padded with trailing blanks) although Tandy always used 6 for filename and 2 for filetype, with period seperator (i.e. XXXXXX.TT)
  • All communications with drive are at 19,200 bps. PDD1 has dip switches so this can drop to 9600bps. PDD2 is auto sensing down to 1200bps (??? - can anyone confirm this?).

Command Format

All commands are in a request/return format (half-duplex)

General request format:

preamble type length data checksum

General return format:

type length data checksum

Command Type

(all values are in HEX)

 command  request  return
 directory ref  00  11 12
 open file  01  12
 close file  02  12
 read file  03  10 12
 write file  04  12
 delete file  05  12
 format disk  06 *  12
 drive status  07 *  12
 drive condition  0C *  15
  rename file  0D  12

* PDD2 treats the disk as two banks of 100k each. All commands except these two must specify the bank number as part of the request. The above commands reference BANK 0. To reference BANK 1 you must add 40 HEX to these values (bit 6 = bank number). E.G. 'open file' becomes 41 for BANK 1.

Request Command details

Type 00 - Directory Reference

    2   1  1  24             1           1           1      bytes
 +----+--+--+--------------+----------+------------+------+
 |5a5a|00|1a| filename     |attribute |search form |chksum| 
 +----+--+--+--------------+----------+------------+------+
  • Preamble - always 'ZZ'
  • request - type 00h*
  • length - length of data 1ah (26 decimal)
  • filename - padded with blanks
  • attribute - specify 'F' (not used normally)
  • search form
  • 00h - reference file for open or delete
  • 01h - request first directory block
  • 02h - request next directory block
  • 03h - request previous directory block
  • 04h - end directory reference

checksum - see below for calculating

Type 01 - Open file

   2   1  1  1     1      bytes
 +----+--+--+------+------+
 |5a5a|01|01| mode |chksum|
 +----+--+--+------+------+
  • Preamble - always 'ZZ'
  • request - type 01h
  • length - length of data 01h (1 decimal)
  • mode -
  • 01h - open new file for WRITE
  • 02h - open existing file for APPEND
  • 03h - open existing file for READ

checksum - see below for calculating

Type 02 - Close file

   2   1  1  1        bytes
 +----+--+--+------+
 |5a5a|02|00|chksum|
 +----+--+--+------+
  • Preamble - always 'ZZ'
  • request - type 02h
  • length - length of data 00h (no data field)
  • checksum - see below for calculating

Type 03 - Read file

   2   1  1  1        bytes
 +----+--+--+------+
 |5a5a|03|00|chksum|
 +----+--+--+------+
  • Preamble - always 'ZZ'
  • request - type 03h
  • length - length of data 00h (no data field)
  • checksum - see below for calculating

Type 04 - Write file

   2   1  1   1-128  1       bytes
 +----+--+---+------+------+
 |5a5a|04|01-|data  |chksum|
 |    |  | 80|      |      |
 +----+--+---+------+------+
  • Preamble - always 'ZZ'
  • request - type 04
  • length - length of data 01h-80h (actual length of data)
  • checksum - see below for calculating

Type 05 - Delete file

   2   1  1  1        bytes
 +----+--+--+------+
 |5a5a|05|00|chksum|
 +----+--+--+------+
  • Preamble - always 'ZZ'
  • request - type 05h
  • length - length of data 00h (no data field)
  • checksum - see below for calculating

Type 06 - Format Disk

   2   1  1  1        bytes
 +----+--+--+------+
 |5a5a|06|00|chksum|
 +----+--+--+------+
  • Preamble - always 'ZZ'
  • request - type 06h
  • length - length of data 00h (no data field)
  • checksum - see below for calculating

Type 07 - Drive Status

   2   1  1  1        bytes<
 +----+--+--+------+
 |5a5a|07|00|chksum|
 +----+--+--+------+
  • Preamble - always 'ZZ'
  • request - type 07h
  • length - length of data 00h (no data field)
  • checksum - see below for calculating

Type 0C - Drive Condition

   2   1  1  1        bytes
 +----+--+--+------+
 |5a5a|0C|00|chksum|
 +----+--+--+------+
  • Preamble - always 'ZZ'
  • request - type 0Ch
  • length - length of data 00h (no data field)
  • checksum - see below for calculating

Type 0D - Rename file

   2   1  1  24     1       1       bytes<
 +----+--+--+-------+------+------+
 |5a5a|0D|19|newname|attrib|chksum|
 +----+--+--+-------+------+------+
  • Preamble - always 'ZZ'
  • request - type 0D
  • length - length of data 19h (25 decimal)
  • newname - new name for the file
  • attribute- not used (specify 'F')
  • checksum - see below for calculating

Return Command Details

Type 10 - Read file Return

 1  1   0-128       1      bytes
 +--+---+----------+-----+
 |10|00-| file data|cksum|
 |  | 80|          |cksum|
 +--+---+----------+-----+
  • return - type 10
  • length - length of data 00h-80h (0-128 decimal)
    • if length is equal to 80h there may be more data - you must issue another read command
    • if length is less than 80h then this is last block
  • file data - data read from file
  • checksum - see below for calculating

Type 11 - Directory reference return

 1  1   24       1      2    1    1       bytes
 +--+--+--------+------+----+----+-----+
 |11|1c|filename|attrib|size|free|cksum|
 +--+--+--------+------+----+----+-----+
  • return - type 11h
  • length - length of data 1Ch (28 decimal)
  • filename - file name - if no name specied is 00H. If at end of directory is 00H.
  • attribute - not used
  • size - size of file, big endian format
  • free - number of free sectors (multiply by 1280 for bytes)
  • checksum - see below for calculating

Type 12 - Normal Return

 1  1  1      1      bytes
 +--+--+-----+-----+
 |12|01|error|cksum|
 +--+--+-----+-----+
  • return - type 12h
  • length - length of data 01h
  • error code-
 00 - normal (no error)  10 - file does not exist  11 - file exists
 30 - no filename  31 - dir search error  35 - bank error
 36 - parameter error  37 - open format mismatch  3f - end of file
 40 - no start mark  41 - crc check error in ID  42 - sector length error
 44 - format verify error  46 - format interruption  47 - erase offset error
 49 - crc check error in data  4a - sector number error  4b - read data timeout
 4d - sector number error  50 - disk write protect  5e - un-initilized disk
 60 - directory full  61 - disk full  6e - file too long
 70 - no disk  71 - disk change error  
  • checksum - see below for calculating

Type 15 - Drive Condition Return

 1  1  1          1      bytes
 +--+--+---------+-----+
 |15|01|condition|cksum|
 +--+--+---------+-----+
  • return - type 15h
  • length - length of data 01h
  • condition- bit values
         7 6 5 4 3 2 1 0    bit
        +-+-+-+-+-+-+-+-+
    MSB |0|0|0|0|x|x|x|x| LSB
        +-+-+-+-+-+-+-+-+
                 | | | |
                 | | | +--power (0=normal 1=low)
                 | | +----write protect (0=not prot 1=prot)
                 | +------disk out (0=disk in 1=disk out)
                 +--------disk change status (0=not changed 1=changed)
  • checksum - see below for calculating

Sequence of Events

 Get directory req 00 search form 01

req 00 search form 02 (repeat as needed)

 Write file req 00 search form 00

req 01 mode 01 or 02
req 04 (repeat as needed)
req 02

 Read file req 00 search form 00

req 01 mode 03
req 03 (repeat as needed)
req 02

 Rename file req 00 search form 00

req 0d

 Delete file  req 00 search form 00

req 05


Calculating Checksum

The check sum is "the one's complement of the least significant byte of the number

of bytes from the block format through the data block". Most people (me included) don't understand what that involves if you have to calculate it. Fortunately I found an

example of how to do this and so I'm passing it on to you.

Checksum=(sum-of-bytes MOD 256) XOR 255

where bytes = the bytes including the Request Type, Length and all Data fields (but not including the preamble).


Using this Information

A lot of the above commands can be set up in advance since there is no variable part to

calculate. Some commands must have the length and checksum calculate as the data is built

but the others don't. Here's how I set up some of the commands in my program:

Close$   = "ZZ"+Chr$(2)+Chr$(0)+Chr$(253)
Dir1$    = "ZZ"+Chr$(0)+Chr$(26)+Space$(24)+"F"+Chr$(1)+Chr$(158)
Dir2$    = "ZZ"+Chr$(0)+Chr$(26)+Space$(24)+"F"+Chr$(2)+Chr$(157)
Status$  = "ZZ"+Chr$(7)+Chr$(0)+Chr$(248)+Chr$(13)
Format$  = "ZZ"+Chr$(6)+Chr$(0)+Chr$(249)+Chr$(13)
Erase$   = "ZZ"+Chr$(5)+Chr$(0)+Chr$(250)
Seek$(1) = "ZZ"+Chr$(1)+Chr$(1)+Chr$(1)+Chr$(252)
Seek$(2) = "ZZ"+Chr$(1)+Chr$(1)+Chr$(2)+Chr$(251)
Seek$(3) = "ZZ"+Chr$(1)+Chr$(1)+Chr$(3)+Chr$(250)

The above commands can be sent directly without any calculating to speed up your program.