{"id":1135,"date":"2019-05-06T17:42:55","date_gmt":"2019-05-07T00:42:55","guid":{"rendered":"https:\/\/www.pagetable.com\/?p=1135"},"modified":"2019-05-06T17:42:55","modified_gmt":"2019-05-07T00:42:55","slug":"commodore-peripheral-bus-part-4-standard-serial","status":"publish","type":"post","link":"https:\/\/www.pagetable.com\/?p=1135","title":{"rendered":"Commodore Peripheral Bus: Part 4: Standard Serial"},"content":{"rendered":"<p>In the <a href=\"https:\/\/www.pagetable.com\/?p=1018\">series about the variants of the Commodore Peripheral Bus family<\/a>, this article covers the lowest two layers (electrical and byte transfer) of the \u201cStandard Serial\u201d bus as found on the VIC-20\/C64 as the main bus, but also supported by all other Commodore home computers.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial_layers.png\" alt=\"\" width=\"371\" height=\"241\" \/><\/p>\n<hr \/>\n<blockquote><p><strong><em>NOTE:<\/em><\/strong> I am releasing one part every week, at which time links will be added to the bullet points below. The articles will also be announced on my Twitter account <a href=\"https:\/\/twitter.com\/pagetable\">@pagetable<\/a> and my Mastodon account <a href=\"https:\/\/mastodon.social\/@pagetable\">@pagetable@mastodon.social<\/a>.<\/p><\/blockquote>\n<hr \/>\n<ul>\n<li><a href=\"https:\/\/www.pagetable.com\/?p=1018\">Part 0: Overview and Introduction<\/a><\/li>\n<li><a href=\"https:\/\/www.pagetable.com\/?p=1023\">Part 1: IEEE-488<\/a> [PET\/CBM Series; 1977]<\/li>\n<li><a href=\"https:\/\/www.pagetable.com\/?p=1031\">Part 2: The TALK\/LISTEN Layer<\/a><\/li>\n<li><a href=\"https:\/\/www.pagetable.com\/?p=1038\">Part 3: The Commodore DOS Layer<\/a><\/li>\n<li><strong>Part 4: Standard Serial (IEC) [VIC-20, C64; 1981]<\/strong> \u2190 <em>this article<\/em><\/li>\n<li>Part 5: TCBM [C16, C116, Plus\/4; 1984] <em>(coming soon)<\/em><\/li>\n<li>Part 6: JiffyDOS [1985] <em>(coming soon)<\/em><\/li>\n<li>Part 7: Fast Serial [C128; 1986] <em>(coming soon)<\/em><\/li>\n<li>Part 8: CBDOS [C65; 1991] <em>(coming soon)<\/em><\/li>\n<\/ul>\n<h2 id=\"Naming-and-Context\">Naming and Context<\/h2>\n<p>First let\u2019s clarify the naming. Commodore calls the three-wire protocol used e.g. by the Commodore C64 and the 1541 disk drives \u201cSerial\u201d in its reference documents. Later documentation calls it \u201cStandard Serial\u201d to distinguish it from the later backwards-compatible \u201cFast Serial\u201d<sup id=\"fnref:1\"><a href=\"#fn:1\" rel=\"footnote\">1<\/a><\/sup> protocol of the C128. This also matches the naming in <a href=\"https:\/\/github.com\/mist64\/cbmsrc\/tree\/master\/KERNAL_C64_03\">Commodore\u2019s source code<\/a>, where the protocol is called \u201cserial\u201d<sup id=\"fnref:2\"><a href=\"#fn:2\" rel=\"footnote\">2<\/a><\/sup>.<\/p>\n<p>\u201cStandard Serial\u201d is based on the PET\u2019s parallel IEEE-488 bus (covered in <a href=\"https:\/\/www.pagetable.com\/?p=1023\">part 1<\/a>), which was standardized internationally as IEC-625. In Europe, IEEE-488 was therefore commonly referred to as the \u201cIEC bus\u201d. The serial version was then often called \u201cSerial IEC\u201d, even though this variant was not an IEC standard. Finally, the \u201cserial\u201d attribute was often dropped in European books and magazines, which is why \u201cStandard Serial\u201d is most often refered to as just the \u201cIEC bus\u201d.<\/p>\n<p>There are two extensions to Standard Serial: The already mentioned \u201cFast Serial\u201d (C128), as well as the third party \u201cJiffyDOS\u201d. They both share the same basic idea but are incompatible with each other. Both protocols also use the same cable as Standard Serial and are completely backwards-compatible with it. If they detect that their peers also speak the improved protocol, they will then switch to it. Fast Serial and JiffyDOS will be covered in separate articles.<\/p>\n<h2 id=\"History-and-Development\">History and Development<\/h2>\n<p>Commodore had been using the standard IEEE-488 bus on the PET series of computers and its disk drives and printers. Unhappy with the price of the parallel connectors and cables, they developed a serial version of layers 1 and 2 of the protocol for the upcoming VIC-20 (1981).<\/p>\n<p>The design goal was to retain all of the core properties of the IEEE-488 bus:<\/p>\n<ul>\n<li>All participants are <strong>daisy-chained<\/strong>.<\/li>\n<li><strong>One dedicated controller<\/strong> (the computer) does bus arbitration of <strong>up to 31 devices<\/strong>.<\/li>\n<li><strong>One-to-many<\/strong>: Any participant can send data to any set of participants.<\/li>\n<li>A device has <strong>multiple channels<\/strong> for different functions.<\/li>\n<li>Data transmission is <strong>byte stream<\/strong> based.<\/li>\n<\/ul>\n<p>The challenge was to reduce the 16 data lines of IEEE-488 down to 5 within these constraints:<\/p>\n<table>\n<thead>\n<tr>\n<th>IEEE-488 Signal<\/th>\n<th>Description<\/th>\n<th>Serial Signal<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>DIO1-8<\/td>\n<td>Data I\/O<\/td>\n<td>DATA, CLK<\/td>\n<\/tr>\n<tr>\n<td>EOI<\/td>\n<td>End Or Identify<\/td>\n<td>(timing)<\/td>\n<\/tr>\n<tr>\n<td>DAV<\/td>\n<td>Data Valid<\/td>\n<td>(CLK)<\/td>\n<\/tr>\n<tr>\n<td>NRFD<\/td>\n<td>Not Ready For Data<\/td>\n<td>(DATA)<\/td>\n<\/tr>\n<tr>\n<td>NDAC<\/td>\n<td>No Data Accepted<\/td>\n<td>(timing)<\/td>\n<\/tr>\n<tr>\n<td>IFC<\/td>\n<td>Interface Clear<\/td>\n<td>RESET<\/td>\n<\/tr>\n<tr>\n<td>SRQ<\/td>\n<td>Service Request<\/td>\n<td>SRQ<\/td>\n<\/tr>\n<tr>\n<td>ATN<\/td>\n<td>Attention<\/td>\n<td>ATN<\/td>\n<\/tr>\n<tr>\n<td>REN<\/td>\n<td>Remote Enable<\/td>\n<td>&#8211;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<ul>\n<li><strong>Data<\/strong>: Instead of transmitting 8 bits in parallel, they are sent serially, using a CLK and a DATA line.<\/li>\n<li><strong>Handshake<\/strong>: The function of the DAV and NRFD lines is taken over by the CLK and DATA lines. There is no NDAC signal, accepting data is based on timing.<\/li>\n<li><strong>Management<\/strong>: REN (already unsupported on the PET) is removed. EOI is removed, the information is now transmitted through a timing sidechannel. RESET (IFC), SRQ and ATN are retained.<\/li>\n<\/ul>\n<p>One property they could not keep was the relaxed timing requirement of IEEE-488: At most points in an IEEE-488 communication, any participant can stall for any amount of time. This makes it easy to implement the protocol completely in software, without any hardware that would guarantee strict timings. Serial on the other hand was designed with a dedicated hardware shift register in mind.<\/p>\n<h2 id=\"Layer-1:-Electrical\">Layer 1: Electrical<\/h2>\n<h3 id=\"Connectors-and-Pinout\">Connectors and Pinout<\/h3>\n<p>Both computers and devices use female 6-pin <a href=\"https:\/\/en.wikipedia.org\/wiki\/DIN_connector\">DIN<\/a> 45322 connectors.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial_connector.svg\" alt=\"\" width=\"220\" height=\"220\" \/><\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial_cable.jpg\" alt=\"\" width=\"300\" height=\"207\" \/><\/p>\n<p>Since devices can be daisy-chained, most peripherals have two serial ports to connect to both the previous device (or the computer) and to the next device, if any. Either port can be used for the previous or the next device in the chain, but some devices labeled them one way anyway.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial_port_1541-II.jpg\" alt=\"\" width=\"300\" height=\"171\" \/><\/p>\n<p>This is the pinout:<\/p>\n<table>\n<thead>\n<tr>\n<th>Pin<\/th>\n<th>Signal<\/th>\n<th>Description<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>1<\/td>\n<td>SRQ<\/td>\n<td>Service Request<\/td>\n<\/tr>\n<tr>\n<td>2<\/td>\n<td>GND<\/td>\n<td>Ground<\/td>\n<\/tr>\n<tr>\n<td>3<\/td>\n<td>ATN<\/td>\n<td>Attention<\/td>\n<\/tr>\n<tr>\n<td>4<\/td>\n<td>CLK<\/td>\n<td>Clock<\/td>\n<\/tr>\n<tr>\n<td>5<\/td>\n<td>DATA<\/td>\n<td>Data<\/td>\n<\/tr>\n<tr>\n<td>6<\/td>\n<td>RESET<\/td>\n<td>Reset<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<ul>\n<li>The CLK and DATA line carry the data and are used for handshaking.<\/li>\n<li>ATN and SRQ are control lines. (SRQ is unused, see below.)<\/li>\n<li>The RESET line resets all devices.<\/li>\n<\/ul>\n<h3 id=\"Open-Collector-Logic\">Open Collector Logic<\/h3>\n<p><!--- this is the same as in part 1 --><\/p>\n<p>All signal lines are TTL open collector, which means:<\/p>\n<ul>\n<li>All participants of the bus can not only read, but also write to the line.<\/li>\n<li>When <strong>all<\/strong> participants write 0, the line will read back 0, but if any device writes 1, the bus will read back as 1.<\/li>\n<li>The logic is inverted: 5V is 0 (false), and 0V is 1 (true).<\/li>\n<\/ul>\n<p>In other words: If the line is <em>released<\/em> by all bus participants, it will be 5V (logically 0), and any participant can <em>pull<\/em> it to 0V (logically 1).<\/p>\n<p>This can be visualized with two (or more) hands that can pull the line to 1, and a spring that pushes it to 0:<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/open_collector.gif\" alt=\"\" width=\"302\" height=\"162\" \/><\/p>\n<p>So when a line reads as 0, it is known that it is currently released by all participants, and if a line reads as 1, one or more participants are pulling it, but it is impossible to know who or even how many.<\/p>\n<h2 id=\"Layer-2:-Byte-Transfer\">Layer 2: Byte Transfer<\/h2>\n<p>Like with IEEE-488, the basic byte transfer protocol of the Serial Bus is based on transmissions of byte streams from one sender to one or more receivers. Additional bus participants will remain silent. There are no fixed assignments of senders and receivers, the roles of sender and receiver are per transmission.<\/p>\n<h3 id=\"Sending-Bytes\">Sending Bytes<\/h3>\n<p>For the transmission of a byte stream, just two wires, CLK and DATA are used. The CLK line is exclusively operated by the sender, while the DATA line is operated by the sender during the transmission of bits, and by the receivers between the transmission of bytes.<\/p>\n<p>The CLK line is the sender\u2019s handshake, and outside of bit transmission, the DATA line is the receiver\u2019s handshake.<\/p>\n<p>The following animation shows a byte being sent to two receivers.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial.gif\" alt=\"\" width=\"601\" height=\"344\" \/><\/p>\n<p>Let\u2019s go through it step by step:<\/p>\n<h4 id=\"0:-Initial-State\">0: Initial State<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-01.png\" alt=\"\" width=\"601\" height=\"131\" \/><br \/>\nIn the initial state, the sender is holding the CLK line to indicate that it it is not ready to send. The receivers are holding the DATA line, meaning they are not ready to receive.<\/p>\n<h4 id=\"1:-Sender-is-ready-to-send\">1: Sender is ready to send<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-02.png\" alt=\"\" width=\"601\" height=\"131\" \/><br \/>\nTransmission of a new byte is initiated by the sender, indicating that it is ready to send by releasing the CLK line.<\/p>\n<h4 id=\"2:-A-is-now-ready-to-receive-data\">2: A is now ready to receive data<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-03.png\" alt=\"\" width=\"601\" height=\"131\" \/><br \/>\nTransmission of the bits cannot begin until all receivers are ready to receive. So at some point the first receiver is done handling the previous byte it may have received and signals that it is ready for data by releasing DATA. The DATA wire is still pulled by the other receiver though, so its value is still 1.<\/p>\n<h4 id=\"3:-All-receivers-are-now-ready-to-receive-data\">3: All receivers are now ready to receive data<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-04.png\" alt=\"\" width=\"601\" height=\"131\" \/><br \/>\nWhenever the other receiver is ready to receive the next byte, it will also release DATA, so it will now read back as 0: All receivers are ready to receive data.<\/p>\n<p>During the actual transmission of the data, both CLK and DATA are now operated by the sender.<\/p>\n<h4 id=\"4:-Data-is-not-valid-\u2013-hold-for-60-\u00b5s\">4: Data is not valid \u2013 hold for 60 \u00b5s<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-05.png\" alt=\"\" width=\"601\" height=\"131\" \/><br \/>\nFor the transmission of the bits, the CLK line will indicate whether the data on the DATA line is valid. So for the initial state, the sender pulls CLK, indicating that data is not valid.<\/p>\n<p>Since both lines are now controlled by the sender, there is no back channel for the receivers, and they cannot acklowledge any state transition. So from now on, everything is based on timing. As a part of this, the CLK line has to be pulled for at least 60 \u00b5s until it is released again in step 6, to make sure the receiver notices the state change.<\/p>\n<h4 id=\"5:-Sender-puts-data-bit-#0-onto-the-wire\">5: Sender puts data bit #0 onto the wire<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-06.png\" alt=\"\" width=\"601\" height=\"131\" \/><br \/>\nThe sender now puts the value of the first bit into DATA.<\/p>\n<h4 id=\"6:-Data-is-now-valid-\u2013-hold-for-60-\u00b5s\">6: Data is now valid \u2013 hold for 60 \u00b5s<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-07.png\" alt=\"\" width=\"601\" height=\"131\" \/><br \/>\nAfter that, the sender releases CLK, signaling that the data bit in DATA is valid.<\/p>\n<p>There is no way for the receivers to signal \u201cdata accepted\u201d for the bit. The sender must hold this state for at least 60 \u00b5s, and receivers must be able to accept the bit within this time.<\/p>\n<h4 id=\"7:-Data-is-not-valid-\u2013-hold-for-60-\u00b5s\">7: Data is not valid \u2013 hold for 60 \u00b5s<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-08.png\" alt=\"\" width=\"601\" height=\"131\" \/><br \/>\nAfter the 60 \u00b5s, the sender pulls CLK again to signal that the data is not valid, and releases the DATA line.<\/p>\n<h4 id=\"8-27:-Repeat-steps-5-7-for-bits-#1-to-#7\">8-27: Repeat steps 5-7 for bits #1 to #7<\/h4>\n<p>The wires are in the same state again as in step 4, before sending the bit. The seven remaining bits will be transmitted the same way: CLK=1 for 60 \u00b5s, then CLK=0 for 60 \u00b5s with a data bit on DATA, and so on.<\/p>\n<h4 id=\"28:-Data-is-not-valid\">28: Data is not valid<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-29.png\" alt=\"\" width=\"601\" height=\"131\" \/><br \/>\nLike for the previous bits, the last step of the last bit has the sender pulling CLK and releasing DATA.<\/p>\n<p>From now on, the DATA line will be operated by the receivers again.<\/p>\n<h4 id=\"29:-Receiver-A-is-now-busy-again\">29: Receiver A is now busy again<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-30.png\" alt=\"\" width=\"601\" height=\"131\" \/><br \/>\nOnce all 8 bits have been transmitted, the receivers have to signal within 1000 \u00b5s that they are busy, so that after accepting the data, the sender won\u2019t think the receivers are immediately ready for the next byte<sup id=\"fnref:3\"><a href=\"#fn:3\" rel=\"footnote\">3<\/a><\/sup>. So now, the first receiver pulls DATA, so DATA is 1.<\/p>\n<h4 id=\"30:-Receiver-B-is-now-busy\">30: Receiver B is now busy<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-31.png\" alt=\"\" width=\"601\" height=\"131\" \/><br \/>\nThe other receiver also has to signal that it is busy by pulling DATA. The line was already 1 and will stay at 1. All wires are now in the initial state again. After a minimum delay of 100 \u00b5s (\u201cbetween bytes time\u201d), the sender can start repeating the sequence as long as there is more data to be sent.<\/p>\n<p>Note that the protocol only specifies the triggers: For example, the receivers are to read the bit from DATA while CLK = 0, so it would be just as legal in step 7 for the the sender to hold CLK and release DATA in two steps (the 1541 does this, the C64 doesn\u2019t).<\/p>\n<p>Also, there is no ordering on which receiver pulls or releases its line first. The receivers don\u2019t care about the other receivers, they only follow the protocol with the sender. The open collector property of the signal lines automatically combines the outputs of the different receivers.<\/p>\n<h3 id=\"End-of-Stream\">End of Stream<\/h3>\n<p>If there is no more data to be transmitted, the sequence stops at step 30 (which is the same state as step 0). In this step, there is no way for the sender to signal the end of the stream, because it only controls one bit (0 = ready to send the next byte, 1 = it has more data but is not ready to send yet). Therefore, the sender already signals this during the transmission of the last byte. The number of wires for carrying information is still limited, but it can do it through a timing sidechannel<sup id=\"fnref:4\"><a href=\"#fn:4\" rel=\"footnote\">4<\/a><\/sup>. (Consistent with IEEE-488, this event is called \u201cEOI\u201d, \u201cEnd Or Identify\u201d.)<\/p>\n<h4 id=\"3:-Sender-delays-for-256-\u00b5s-to-signal-EOI\">3: Sender delays for 256 \u00b5s to signal EOI<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-32.png\" alt=\"\" width=\"601\" height=\"131\" \/><br \/>\nTo indicate the end of the stream, the sender delays step 4 by at least 200 \u00b5s. That is, after the sender has signaled that it has more data available (CLK = 0), and after all receivers have signaled that they are ready for data (DATA = 0), the sender doesn\u2019t immediately pull the CLK line to start transmission.<\/p>\n<h4 id=\"4:-Data-is-not-valid\">4: Data is not valid<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-33.png\" alt=\"\" width=\"601\" height=\"131\" \/><\/p>\n<p>After the delay, it then pulls CLK, signaling that the data is not valid.<\/p>\n<h4 id=\"4a:-Receiver-A-acknowledges-EOI-\u2013-hold-for-60-\u00b5s\">4a: Receiver A acknowledges EOI \u2013 hold for 60 \u00b5s<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-34.png\" alt=\"\" width=\"601\" height=\"131\" \/><\/p>\n<p>All receivers have to acknowledge that they have understood the EOI signal. So the first receiver will<br \/>\ndo this by holding the DATA line for at least 60 \u00b5s.<\/p>\n<h4 id=\"4b:-Receiver-B-acknowledges-EOI-\u2013-hold-for-60-\u00b5s\">4b: Receiver B acknowledges EOI \u2013 hold for 60 \u00b5s<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-35.png\" alt=\"\" width=\"601\" height=\"131\" \/><\/p>\n<p>The other receiver also has to hold the DATA line for 60 \u00b5s.<\/p>\n<h4 id=\"4c:-A-has-finished-acknowledging-EOI\">4c: A has finished acknowledging EOI<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-36.png\" alt=\"\" width=\"601\" height=\"131\" \/><\/p>\n<p>After the delay, the first receiver releases DATA agin. The wire is still pulled by the other receiver though, so its value is still 1.<\/p>\n<h4 id=\"4d:-B-has-finished-acknowledging-EOI\">4d: B has finished acknowledging EOI<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-37.png\" alt=\"\" width=\"601\" height=\"131\" \/><\/p>\n<p>After its delay, the other receiver will also release DATA, so it will now read back as 0.<\/p>\n<p>After the sender has signaled EOI, it will wait for the DATA line to become 1, and then 0 again, until resuming the transmission of the final byte at step 5.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial.png\" alt=\"\" width=\"601\" height=\"301\" \/><\/p>\n<h3 id=\"Empty-Stream\">Empty Stream<\/h3>\n<p>With EOI being signaled during the transmission of the last byte of a stream, this method does not allow empty streams.<\/p>\n<p>There is a separate mechanism for this case, also using timing: At step 3 of what would be the transmission of the first byte, the sender just completely stops, and leaves both DATA and CLK released.<\/p>\n<p>Based on the time the transition from step 3 to step 4 takes, one of three different events is signaled:<\/p>\n<ul>\n<li>0-256 \u00b5s: The following byte is not the last one in the stream.<\/li>\n<li>256-512 \u00b5s: The following byte is the last one in the stream.<\/li>\n<li>512+ \u00b5s: The stream is empty, the receiver will not transmit anything.<\/li>\n<\/ul>\n<p>The empty stream case is equivalent to the IEEE-488 sender timeout, which is also what it is called in the Standard Serial specification. <a href=\"https:\/\/www.pagetable.com\/?p=1038\">Commodore DOS (layer 4)<\/a> interprets an empty stream as a \u201cFILE NOT FOUND\u201d condition.<\/p>\n<h3 id=\"Sending-Commands\">Sending Commands<\/h3>\n<p><!--- this is almost the same as in part 1 --><\/p>\n<p>The assignment of senders and receivers to transmissions is the job of layer 3 (Bus Arbitration), described in <a href=\"https:\/\/www.pagetable.com\/?p=1031\">part 3<\/a> of this series.<\/p>\n<p>But there are also <strong>command<\/strong> transmissions, where one particiant can start a transmission to <em>all<\/em> other participants at any time.<\/p>\n<p>Only so-called \u201ccontrollers\u201d may perform a command transmission, and on Commodore busses, there is always only one controller: the computer. All bus participants that are not controllers are called \u201cdevices\u201d.<\/p>\n<p>When the controller wants to send a command, it pulls the ATN (\u201cAttention\u201d) line at any time, possibly even in the middle of a byte transmission. (The byte stream will not be resumed after the command.) It then pulls CLK and releases DATA, because it is now the sender.<\/p>\n<p>All devices on the bus have to respond to ATN by pulling DATA within 1000 \u00b5s (\u201cATN Response Timing\u201d), and also eventually release CLK, because they are now receivers. Devices usually implement this in hardware by automatically answering ATN=1 with DATA=1, so that they can participate in receiving the command even when the CPU is busy and cannot be interrupted.<\/p>\n<p>All devices then have to participate in receiving the command byte stream, but as in any transmission, any device can stall after step 1, signaling that it is not yet ready for data.<\/p>\n<p>The controller sends the command data like any other transmission, and releases ATN afterwards. It does not signal EOI during the transmission of the last byte, since the release of ATN already signals the end of the stream.<\/p>\n<p>The encoding of commands is part of the <a href=\"https:\/\/www.pagetable.com\/?p=1031\">layer 3 bus arbitration protocol<\/a>.<\/p>\n<h3 id=\"Initiating\/Ending-a-Transmission-and-Bus-Turnaround\">Initiating\/Ending a Transmission and Bus Turnaround<\/h3>\n<p>On an idle bus, CLK and DATA are released, so they read as 0. The initial state of the transmission of a byte has both lines pulled, so first, the sender has to pull CLK, then the receivers have to pull DATA. This is what happens at the beginning of a command transmission when the bus is idle. Similarly, at the end of the transmission, the sender releases CLK, and the receivers release DATA, so the bus is idle again.<\/p>\n<p>It becomes interesting when two transmissions follow each other immediately, and the sender and receiver roles are different between transmissions. The assignment of senders and receivers can only be changed by a command (during ATN = 1), which itself is a transmission with a potentially different set of senders and receivers anyway. So at the end of the command, there needs to be an orderly transition from the end state of the old transmission to the initial state of the new one \u2013 a bus turnaround.<\/p>\n<h4 id=\"A:-End-state-of-the-original-transmission\">A: End state of the original transmission<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-39.png\" alt=\"\" width=\"601\" height=\"131\" \/><\/p>\n<p>In the last step of a command transmission \u2013\u00a0like in any transmission \u2013 the controller (the sender), is holding CLK, and the devices (the receivers) are holding DATA. (For simplicity, this visualization only has two devices on the bus.)<\/p>\n<h4 id=\"B:-Reversed-roles\">B: Reversed roles<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-40.png\" alt=\"\" width=\"601\" height=\"131\" \/><\/p>\n<p>Let\u2019s assume the command has reversed the roles of sender and receiver, so the previous receiver is now the new sender and is still holding DATA, and the previous sender is now the receiver and is still holding CLK. This needs to be reversed.<\/p>\n<h4 id=\"C:-New-receiver-switches-lines\">C: New receiver switches lines<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-41.png\" alt=\"\" width=\"601\" height=\"131\" \/><\/p>\n<p>First, the new receiver pulls DATA and lets go of CLK. DATA remains 1, but CLK is now released by both the sender and the receiver and will read back as 0.<\/p>\n<h4 id=\"D:-New-sender-switches-lines\">D: New sender switches lines<\/h4>\n<p><img loading=\"lazy\" decoding=\"async\" src=\"docs\/cbmbus\/serial-42.png\" alt=\"\" width=\"601\" height=\"131\" \/><\/p>\n<p>Triggered by CLK being 0, the new sender pulls down CLK and releases DATA. Both lines now read back as 1, which is the initial state for byte transmission, and the correct lines are held by the respective bus participants.<\/p>\n<h3 id=\"Errors\">Errors<\/h3>\n<p>There are several possible error conditions:<\/p>\n<ul>\n<li>If at the beginning of a transmission, none of the receivers exist, DATA will not get pulled. After a timeout of 256 \u00b5s, this will cause a \u201cDEVICE NOT PRESENT\u201d error. This also applies to the transmission of a command: All devices are required to pull DATA in this case, and if DATA remains at 0, it means that there no devices connected at all.<\/li>\n<li>There is no way to detect whether the sender exists. When a device is told to send, there are no specified timing requirements about when it has to pull the CLK line.<\/li>\n<li>If no receiver pulls DATA within 1000 \u00b5s at the end of the transmission of a byte (after step 28), a receiver timeout is raised.<\/li>\n<li>If the sender does not pull CLK within 512 \u00b5s after step 3, a sender timeout is raised. The sender hits this timeout on purpose to signal an empty stream.<\/li>\n<\/ul>\n<h3 id=\"Timing\">Timing<\/h3>\n<h4 id=\"Original-Design\">Original Design<\/h4>\n<p>The design goal of Standard Serial was that its speed would be comparable to IEEE-488. Byte transmission was supposed to be handled by a dedicated shift register, so that the CPU would perform the byte handshake, but the individual bits would be transfered automatically by the hardware. The VIC-20 and the 1540 disk drive, the first devices with the Standard Serial bus, each contained a 6522 VIA I\/O controller that supported automatic serial transmission. The hold times for CLK=0 and CLK=1 were 4 \u00b5s each<sup id=\"fnref:5\"><a href=\"#fn:5\" rel=\"footnote\">5<\/a><\/sup>, so a byte could be transfered in 8 \u00b5s. This would result in theoretical transmission speeds above 10 KB\/sec.<\/p>\n<p>The timing of the CPU-side of the original protocol was very relaxed. Timeouts were on the order of hundreds of \u00b5s.<\/p>\n<p>This design never shipped though.<\/p>\n<h4 id=\"VIC-20\">VIC-20<\/h4>\n<p>Unfortunately, the Commodore engineers did not account for a bug in the 6522 shift register that was already documented<sup id=\"fnref:6\"><a href=\"#fn:6\" rel=\"footnote\">6<\/a><\/sup> by the time the Serial Bus was designed. At the last minute, they increased the hold times to 20 \u00b5s, which allowed them to implement the otherwise unchanged protocol in software both in the VIC-20 and the 1540. This reduced the theoretical throughput to 2 KB\/sec.<\/p>\n<p>The fact that it was now a pure software protocol also changed the quality of the timing constraints: While the protocol was originally designed to allow any participant to stall in most states, and to only require relatively relaxed timing, the critical byte transmission window now requires the CPU to commit to being undisturbed for 20 \u00b5s \u00d7 2 \u00d7 8 = 320 \u00b5s.<\/p>\n<h4 id=\"C64\">C64<\/h4>\n<p>The Commodore 64, which was the successor to the VIC-20, contained a 6526 CIA I\/O controller that had a working shift register, but Commodore did not enable it for hardware-supported byte transfers, since the accompanying disk drive, the 1541, was not planned to be updated from the buggy 6522 VIA.<\/p>\n<p>To make matter worse, the system architecture of the C64 had the video chip halt the CPU for about 40 \u00b5s every ~500 \u00b5s, which would make it likely for the CPU to miss the 20 \u00b5s window in which a bit was valid. The Commodore engineers decided not to turn off the display during Serial Bus operations (to disable video DMA), as it is done for tape access.<\/p>\n<p>In theory, it would be possible to fit the 320 \u00b5s to transmit a byte within the predictable 500 \u00b5s window between DMAs, but it is the sender that decides when to start the transmission of a byte and controls the actual transmission speed.<\/p>\n<p>So the specification of the protocol was <em>changed<\/em> to increase the hold time by 40 \u00b5s, to 60 \u00b5s \u2013\u00a0but only in some cases: It was acknowledged that computers like the C64 might need more time to see a bit on the bus, but devices were still required to make the 20 \u00b5s window. Therefore, all devices use 60 \u00b5s hold times when sending data, but controllers can use 20 \u00b5s<sup id=\"fnref:7\"><a href=\"#fn:7\" rel=\"footnote\">7<\/a><\/sup>. This reduces the theoretical throughput from devices to controllers to below 1 KB\/sec.<\/p>\n<p>In practice, the Serial Bus implementation in the system software of the VIC-20 was still standards compliant. The 1540 disk drive was updated as the 1541 with the new (slower) timing, but an option to change the bus speed to VIC-20 mode (<a href=\"https:\/\/www.pagetable.com\/?p=1038\">Commodore DOS<\/a> command \u201c<code>UI-<\/code>\u201d). Printers and plotters designed for the VIC-20 did not have to be updated to work with the C64, because they only received data and never sent any.<\/p>\n<h3 id=\"SRQ\">SRQ<\/h3>\n<p>There is one more data wire in the cable: The SRQ (\u201cService Request\u201d) line. In the IEEE-488 protocol, SRQ is basically an interrupt line that allows any device to signal the controller that it would like its attention. The controller would then use <a href=\"https:\/\/www.pagetable.com\/?p=1031\">layer 3<\/a> commands to find out which device sent the request and handle it accordingly. The PET has the line connected and makes it available to software, but the KERNAL driver does not support it, and no Commodore devices make use of it. The Serial Bus inherited the SRQ line, but again, while it is connected and accessible by software (VIC-20, C64), neither the KERNAL nor any devices support it. On the Plus\/4, the line is no longer connected to anything.<\/p>\n<p>On the C128, the wire was reused in an unrelated way for the Fast Serial protocol.<\/p>\n<h3 id=\"Discussion\">Discussion<\/h3>\n<p>While the open collector property of CLK and DATA allows several devices to signal their state over a single wire, the bus is nevertheless severely constrained in terms of wires. While the parallel IEEE-488 bus has practically no timing requirements, the serial version requires strict timing in most states.<\/p>\n<h4 id=\"Between-Bytes-Bug\">Between Bytes Bug<\/h4>\n<p>There is one bug in the specification that is caused by these timing complexities. After all bits of a byte have been sent, all receivers are required to pull DATA within 1000 \u00b5s to signal they are not ready for the next byte. All receivers share the same DATA line, and it will read back as soon as any receiver pulls it. So once the first receiver pulls it, the sender signals it is ready to send the next byte after a delay of 100 \u00b5s (\u201cbetween bytes time\u201d). It then waits for DATA to be 0 again, which can happen immediately once the same receiver releases it. Now, in the middle of the transmission of the byte, another receiver wakes up and pulls DATA, still within the legal 1000 \u00b5s, destroying the transmission.<\/p>\n<p>In the original IEEE-4888 protocol, there is the dedicated NRFD (\u201cnot ready for data\u201d) line that is pulled by all receivers before accepting the data, so all receivers have to release it before transmission can continue. On the Serial Bus, both the CLK and the DATA line are operated by the sender until the completion of the byte transmission, so there is no way for the receivers to communicate anything before that.<\/p>\n<p>The bug would be fixed by reducing the allowed time to pull DATA to 100 \u00b5s, the same as the \u201cbetween bytes time\u201d. In practice, this is not an issue though, because one-to-many communcation is extremely rarely used, and because Serial Bus devices tend to respond within 100 \u00b5s anyway.<\/p>\n<h4 id=\"Data-Valid-Window-vs.-CLK\/DATA\">Data Valid Window vs. CLK\/DATA<\/h4>\n<p>While the specification change between the VIC-20 and the C64 had to be minimal to keep as much compatibility as possible, the change between the original design, which never shipped, and the VIC-20 had no compatibility requirements. On the VIC-20, the transmission of a byte through CLK and DATA followed the protocol of the 6522 VIA shift register, even though it was implemented in software.<\/p>\n<p>Instead, a modified protocol could have sent one bit on every <em>edge<\/em> of CLK, doubling the data rate. They could also have sent two bits at a time, one in CLK and one in DATA with a strict timing of 20 \u00b5s per bit. This would only have required the receiver to commit to a 80 \u00b5s window of being able to receive data with a timing accuracy below 20 \u00b5s. This would have broken horribly on the C64 though, which cannot commit to this, but alternative protocols including JiffyDOS (part 6 of this series), are based on this strategy.<\/p>\n<p>The advantage of keeping the 6522 VIA shift register protocol was that they would be able to use a working shift register in later devices and just switch to the original timing \u2013 optionally, if all devices supported it. The Fast Serial protocol of the C128 does indeed use the shift register of the 6526 CIA I\/O controller, but does not use the same CLK\/DATA protocol with it.<\/p>\n<h3 id=\"Next-Up\">Next Up<\/h3>\n<p>Part 5 of the series of articles on the Commodore Peripheral Bus family will cover layers 1 and 2 of the TCBM protocol as used on the TED series of computers (C16, C116, Plus\/4).<\/p>\n<blockquote><p>This article series is an Open Source project. Corrections, clarifications and additions are <strong>highly<\/strong> appreciated. I will regularly update the articles from the repository at <a href=\"https:\/\/github.com\/mist64\/cbmbus_doc\">https:\/\/github.com\/mist64\/cbmbus_doc<\/a>.<\/p><\/blockquote>\n<h3 id=\"References\">References<\/h3>\n<ul>\n<li><a href=\"https:\/\/codebase64.org\/doku.php?id=base:how_the_vic_64_serial_bus_works\">How The VIC\/64 Serial Bus Works<\/a> by Jim Butterfield<\/li>\n<li><a href=\"http:\/\/www.zimmers.net\/anonftp\/pub\/cbm\/programming\/serial-bus.pdf\">IEC disected<\/a> by J. Derogee<\/li>\n<\/ul>\n<div class=\"footnotes\">\n<hr \/>\n<ol>\n<li id=\"fn:1\">Related to, but not the same as, and often confused with \u201cBurst Mode\u201d.<a href=\"#fnref:1\" rev=\"footnote\">\u21a9<\/a><\/li>\n<li id=\"fn:2\">The implementation file in the Commodore 64 KERNAL source is \u201c<code>serial4.0<\/code>\u201d. The context of the version number is unknown, since no other versions have appeared. On the TED and the C128, the file is just called \u201c<code>serial.src<\/code>\u201d.<a href=\"#fnref:2\" rev=\"footnote\">\u21a9<\/a><\/li>\n<li id=\"fn:3\">The specification states calls this action \u201cdata accepted\u201d, which makes no sense. \u201cData accepted\u201d would mean that the sender can now remove the data from the bus, because all receivers have seen it. But at this point, there is no more data on the bus, there is nothing for the sender to remove, and the positive logic means that any receiver would be able to accept the data for all receivers.<a href=\"#fnref:3\" rev=\"footnote\">\u21a9<\/a><\/li>\n<li id=\"fn:4\">IEEE-488 also signals this during the last byte, by pulling the dedicated EOI line to 1 while the data is valid.<a href=\"#fnref:4\" rev=\"footnote\">\u21a9<\/a><\/li>\n<li id=\"fn:5\">It is not documented what the planned hold times were. The software implementation of the VIC-20 uses 20 \u00b5s, and Jim Butterfield\u2019s \u201cA brief history of the IEC-bus\u201d states that this was \u201c5 to 6\u201d times slower than planned. 5 times slower would point to a planned hold time of 4 \u00b5s, and 6 times slower might account for the software implementation taking an extra cycle here and there. The 6522 documentation doesn\u2019t seem to say anything about the minimum cycle time for the shift register, but the docs of the successor, the 6526 CIA, state a minimum clock of Phi0\/4, i.e. a hold time of 4 \u00b5s.<a href=\"#fnref:5\" rev=\"footnote\">\u21a9<\/a><\/li>\n<li id=\"fn:6\"><a href=\"http:\/\/forum.6502.org\/viewtopic.php?t=342#p2310\">Garth Wilson<\/a> posted a workaround in December 2000.<a href=\"#fnref:6\" rev=\"footnote\">\u21a9<\/a><\/li>\n<li id=\"fn:7\">In practice, the C64 holds CLK for 42 \u00b5s and the 1541 for 74 \u00b5s, for example.<a href=\"#fnref:7\" rev=\"footnote\">\u21a9<\/a><\/li>\n<\/ol>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>In the series about the variants of the Commodore Peripheral Bus family, this article covers the lowest two layers (electrical and byte transfer) of the \u201cStandard Serial\u201d bus as found on the VIC-20\/C64 as the main bus, but also supported by all other Commodore home computers. NOTE: I am releasing one part every week, at &#8230; <a title=\"Commodore Peripheral Bus: Part 4: Standard Serial\" class=\"read-more\" href=\"https:\/\/www.pagetable.com\/?p=1135\" aria-label=\"Read more about Commodore Peripheral Bus: Part 4: Standard Serial\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[41,8,9,13,16,34],"tags":[],"class_list":["post-1135","post","type-post","status-publish","format-standard","hentry","category-c64","category-commodore","category-commodore-peripheral-bus","category-floppy-disks","category-github","category-vic-20"],"_links":{"self":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts\/1135","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=1135"}],"version-history":[{"count":0,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=\/wp\/v2\/posts\/1135\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=1135"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=1135"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.pagetable.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=1135"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}