CINXE.COM
Ken Shirriff's blog: November 2020
<!DOCTYPE html> <html class='v2' dir='ltr' xmlns='http://www.w3.org/1999/xhtml' xmlns:b='http://www.google.com/2005/gml/b' xmlns:data='http://www.google.com/2005/gml/data' xmlns:expr='http://www.google.com/2005/gml/expr'> <head> <link href='https://www.blogger.com/static/v1/widgets/3566091532-css_bundle_v2.css' rel='stylesheet' type='text/css'/> <meta content='width=1100' name='viewport'/> <meta content='text/html; charset=UTF-8' http-equiv='Content-Type'/> <meta content='blogger' name='generator'/> <link href='http://www.righto.com/favicon.ico' rel='icon' type='image/x-icon'/> <link href='http://www.righto.com/2020/11/' rel='canonical'/> <link rel="alternate" type="application/atom+xml" title="Ken Shirriff's blog - Atom" href="http://www.righto.com/feeds/posts/default" /> <link rel="alternate" type="application/rss+xml" title="Ken Shirriff's blog - RSS" href="http://www.righto.com/feeds/posts/default?alt=rss" /> <link rel="service.post" type="application/atom+xml" title="Ken Shirriff's blog - Atom" href="https://www.blogger.com/feeds/6264947694886887540/posts/default" /> <!--Can't find substitution for tag [blog.ieCssRetrofitLinks]--> <meta content='http://www.righto.com/2020/11/' property='og:url'/> <meta content='Ken Shirriff's blog' property='og:title'/> <meta content='Computer history, restoring vintage computers, IC reverse engineering, and whatever' property='og:description'/> <title>Ken Shirriff's blog: November 2020</title> <style type='text/css'>@font-face{font-family:'Play';font-style:normal;font-weight:400;font-display:swap;src:url(//fonts.gstatic.com/s/play/v19/6aez4K2oVqwIvtU2Gw.eot);}</style> <style id='page-skin-1' type='text/css'><!-- /* ----------------------------------------------- Blogger Template Style Name: Simple Designer: Blogger URL: www.blogger.com ----------------------------------------------- */ /* Variable definitions ==================== <Variable name="keycolor" description="Main Color" type="color" default="#66bbdd"/> <Group description="Page Text" selector="body"> <Variable name="body.font" description="Font" type="font" default="normal normal 12px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="body.text.color" description="Text Color" type="color" default="#222222"/> </Group> <Group description="Backgrounds" selector=".body-fauxcolumns-outer"> <Variable name="body.background.color" description="Outer Background" type="color" default="#66bbdd"/> <Variable name="content.background.color" description="Main Background" type="color" default="#ffffff"/> <Variable name="header.background.color" description="Header Background" type="color" default="transparent"/> </Group> <Group description="Links" selector=".main-outer"> <Variable name="link.color" description="Link Color" type="color" default="#2288bb"/> <Variable name="link.visited.color" description="Visited Color" type="color" default="#888888"/> <Variable name="link.hover.color" description="Hover Color" type="color" default="#33aaff"/> </Group> <Group description="Blog Title" selector=".header h1"> <Variable name="header.font" description="Font" type="font" default="normal normal 60px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="header.text.color" description="Title Color" type="color" default="#3399bb" /> </Group> <Group description="Blog Description" selector=".header .description"> <Variable name="description.text.color" description="Description Color" type="color" default="#777777" /> </Group> <Group description="Tabs Text" selector=".tabs-inner .widget li a"> <Variable name="tabs.font" description="Font" type="font" default="normal normal 14px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="tabs.text.color" description="Text Color" type="color" default="#999999"/> <Variable name="tabs.selected.text.color" description="Selected Color" type="color" default="#000000"/> </Group> <Group description="Tabs Background" selector=".tabs-outer .PageList"> <Variable name="tabs.background.color" description="Background Color" type="color" default="#f5f5f5"/> <Variable name="tabs.selected.background.color" description="Selected Color" type="color" default="#eeeeee"/> </Group> <Group description="Post Title" selector="h3.post-title, .comments h4"> <Variable name="post.title.font" description="Font" type="font" default="normal normal 22px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> </Group> <Group description="Date Header" selector=".date-header"> <Variable name="date.header.color" description="Text Color" type="color" default="#222222"/> <Variable name="date.header.background.color" description="Background Color" type="color" default="transparent"/> <Variable name="date.header.font" description="Text Font" type="font" default="normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="date.header.padding" description="Date Header Padding" type="string" default="inherit"/> <Variable name="date.header.letterspacing" description="Date Header Letter Spacing" type="string" default="inherit"/> <Variable name="date.header.margin" description="Date Header Margin" type="string" default="inherit"/> </Group> <Group description="Post Footer" selector=".post-footer"> <Variable name="post.footer.text.color" description="Text Color" type="color" default="#666666"/> <Variable name="post.footer.background.color" description="Background Color" type="color" default="#f9f9f9"/> <Variable name="post.footer.border.color" description="Shadow Color" type="color" default="#eeeeee"/> </Group> <Group description="Gadgets" selector="h2"> <Variable name="widget.title.font" description="Title Font" type="font" default="normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif"/> <Variable name="widget.title.text.color" description="Title Color" type="color" default="#000000"/> <Variable name="widget.alternate.text.color" description="Alternate Color" type="color" default="#999999"/> </Group> <Group description="Images" selector=".main-inner"> <Variable name="image.background.color" description="Background Color" type="color" default="#ffffff"/> <Variable name="image.border.color" description="Border Color" type="color" default="#eeeeee"/> <Variable name="image.text.color" description="Caption Text Color" type="color" default="#222222"/> </Group> <Group description="Accents" selector=".content-inner"> <Variable name="body.rule.color" description="Separator Line Color" type="color" default="#eeeeee"/> <Variable name="tabs.border.color" description="Tabs Border Color" type="color" default="#eeeeee"/> </Group> <Variable name="body.background" description="Body Background" type="background" color="#f6fbf6" default="$(color) none repeat scroll top left"/> <Variable name="body.background.override" description="Body Background Override" type="string" default=""/> <Variable name="body.background.gradient.cap" description="Body Gradient Cap" type="url" default="url(https://resources.blogblog.com/blogblog/data/1kt/simple/gradients_light.png)"/> <Variable name="body.background.gradient.tile" description="Body Gradient Tile" type="url" default="url(https://resources.blogblog.com/blogblog/data/1kt/simple/body_gradient_tile_light.png)"/> <Variable name="content.background.color.selector" description="Content Background Color Selector" type="string" default=".content-inner"/> <Variable name="content.padding" description="Content Padding" type="length" default="10px" min="0" max="100px"/> <Variable name="content.padding.horizontal" description="Content Horizontal Padding" type="length" default="10px" min="0" max="100px"/> <Variable name="content.shadow.spread" description="Content Shadow Spread" type="length" default="40px" min="0" max="100px"/> <Variable name="content.shadow.spread.webkit" description="Content Shadow Spread (WebKit)" type="length" default="5px" min="0" max="100px"/> <Variable name="content.shadow.spread.ie" description="Content Shadow Spread (IE)" type="length" default="10px" min="0" max="100px"/> <Variable name="main.border.width" description="Main Border Width" type="length" default="0" min="0" max="10px"/> <Variable name="header.background.gradient" description="Header Gradient" type="url" default="none"/> <Variable name="header.shadow.offset.left" description="Header Shadow Offset Left" type="length" default="-1px" min="-50px" max="50px"/> <Variable name="header.shadow.offset.top" description="Header Shadow Offset Top" type="length" default="-1px" min="-50px" max="50px"/> <Variable name="header.shadow.spread" description="Header Shadow Spread" type="length" default="1px" min="0" max="100px"/> <Variable name="header.padding" description="Header Padding" type="length" default="30px" min="0" max="100px"/> <Variable name="header.border.size" description="Header Border Size" type="length" default="1px" min="0" max="10px"/> <Variable name="header.bottom.border.size" description="Header Bottom Border Size" type="length" default="0" min="0" max="10px"/> <Variable name="header.border.horizontalsize" description="Header Horizontal Border Size" type="length" default="0" min="0" max="10px"/> <Variable name="description.text.size" description="Description Text Size" type="string" default="140%"/> <Variable name="tabs.margin.top" description="Tabs Margin Top" type="length" default="0" min="0" max="100px"/> <Variable name="tabs.margin.side" description="Tabs Side Margin" type="length" default="30px" min="0" max="100px"/> <Variable name="tabs.background.gradient" description="Tabs Background Gradient" type="url" default="url(https://resources.blogblog.com/blogblog/data/1kt/simple/gradients_light.png)"/> <Variable name="tabs.border.width" description="Tabs Border Width" type="length" default="1px" min="0" max="10px"/> <Variable name="tabs.bevel.border.width" description="Tabs Bevel Border Width" type="length" default="1px" min="0" max="10px"/> <Variable name="post.margin.bottom" description="Post Bottom Margin" type="length" default="25px" min="0" max="100px"/> <Variable name="image.border.small.size" description="Image Border Small Size" type="length" default="2px" min="0" max="10px"/> <Variable name="image.border.large.size" description="Image Border Large Size" type="length" default="5px" min="0" max="10px"/> <Variable name="page.width.selector" description="Page Width Selector" type="string" default=".region-inner"/> <Variable name="page.width" description="Page Width" type="string" default="auto"/> <Variable name="main.section.margin" description="Main Section Margin" type="length" default="15px" min="0" max="100px"/> <Variable name="main.padding" description="Main Padding" type="length" default="15px" min="0" max="100px"/> <Variable name="main.padding.top" description="Main Padding Top" type="length" default="30px" min="0" max="100px"/> <Variable name="main.padding.bottom" description="Main Padding Bottom" type="length" default="30px" min="0" max="100px"/> <Variable name="paging.background" color="#ffffff" description="Background of blog paging area" type="background" default="transparent none no-repeat scroll top center"/> <Variable name="footer.bevel" description="Bevel border length of footer" type="length" default="0" min="0" max="10px"/> <Variable name="mobile.background.overlay" description="Mobile Background Overlay" type="string" default="transparent none repeat scroll top left"/> <Variable name="mobile.background.size" description="Mobile Background Size" type="string" default="auto"/> <Variable name="mobile.button.color" description="Mobile Button Color" type="color" default="#ffffff" /> <Variable name="startSide" description="Side where text starts in blog language" type="automatic" default="left"/> <Variable name="endSide" description="Side where text ends in blog language" type="automatic" default="right"/> */ /* Content ----------------------------------------------- */ body { font: normal normal 14px Arial, Tahoma, Helvetica, FreeSans, sans-serif; color: #222222; background: #f6fbf6 none repeat scroll top left; padding: 0 40px 40px 40px; } html body .region-inner { min-width: 0; max-width: 100%; width: auto; } h2 { font-size: 22px; } a:link { text-decoration:none; color: #121fb3; } a:visited { text-decoration:none; color: #121fb3; } a:hover { text-decoration:underline; color: #1a00ff; } .body-fauxcolumn-outer .fauxcolumn-inner { background: transparent url(//www.blogblog.com/1kt/simple/body_gradient_tile_light.png) repeat scroll top left; _background-image: none; } .body-fauxcolumn-outer .cap-top { position: absolute; z-index: 1; height: 400px; width: 100%; } .body-fauxcolumn-outer .cap-top .cap-left { width: 100%; background: transparent url(//www.blogblog.com/1kt/simple/gradients_light.png) repeat-x scroll top left; _background-image: none; } .content-outer { -moz-box-shadow: 0 0 40px rgba(0, 0, 0, .15); -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, .15); -goog-ms-box-shadow: 0 0 10px #333333; box-shadow: 0 0 40px rgba(0, 0, 0, .15); margin-bottom: 1px; } .content-inner { padding: 10px 10px; } .content-inner { background-color: #ffffff; } /* Header ----------------------------------------------- */ .header-outer { background: #f6fbf7 url(//www.blogblog.com/1kt/simple/gradients_light.png) repeat-x scroll 0 -400px; _background-image: none; } .Header h1 { font: normal normal 42px Play; color: #666666; text-shadow: 1px 2px 3px rgba(0, 0, 0, .2); } .Header h1 a { color: #666666; } .Header .description { font-size: 140%; color: #666666; } .header-inner .Header .titlewrapper { padding: 22px 30px; } .header-inner .Header .descriptionwrapper { padding: 0 30px; } /* Tabs ----------------------------------------------- */ .tabs-inner .section:first-child { border-top: 0 solid #eeeeee; } .tabs-inner .section:first-child ul { margin-top: -0; border-top: 0 solid #eeeeee; border-left: 0 solid #eeeeee; border-right: 0 solid #eeeeee; } .tabs-inner .widget ul { background: #f5f5f5 url(//www.blogblog.com/1kt/simple/gradients_light.png) repeat-x scroll 0 -800px; _background-image: none; border-bottom: 1px solid #eeeeee; margin-top: 0; margin-left: -30px; margin-right: -30px; } .tabs-inner .widget li a { display: inline-block; padding: .6em 1em; font: normal normal 14px Arial, Tahoma, Helvetica, FreeSans, sans-serif; color: #999999; border-left: 1px solid #ffffff; border-right: 1px solid #eeeeee; } .tabs-inner .widget li:first-child a { border-left: none; } .tabs-inner .widget li.selected a, .tabs-inner .widget li a:hover { color: #000000; background-color: #eeeeee; text-decoration: none; } /* Columns ----------------------------------------------- */ .main-outer { border-top: 0 solid #eeeeee; } .fauxcolumn-left-outer .fauxcolumn-inner { border-right: 1px solid #eeeeee; } .fauxcolumn-right-outer .fauxcolumn-inner { border-left: 1px solid #eeeeee; } /* Headings ----------------------------------------------- */ div.widget > h2, div.widget h2.title { margin: 0 0 1em 0; font: normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif; color: #000000; } /* Widgets ----------------------------------------------- */ .widget .zippy { color: #999999; text-shadow: 2px 2px 1px rgba(0, 0, 0, .1); } .widget .popular-posts ul { list-style: none; } /* Posts ----------------------------------------------- */ h2.date-header { font: normal bold 11px Arial, Tahoma, Helvetica, FreeSans, sans-serif; } .date-header span { background-color: transparent; color: transparent; padding: inherit; letter-spacing: inherit; margin: inherit; } .main-inner { padding-top: 30px; padding-bottom: 30px; } .main-inner .column-center-inner { padding: 0 15px; } .main-inner .column-center-inner .section { margin: 0 15px; } .post { margin: 0 0 25px 0; } h3.post-title, .comments h4 { font: normal normal 22px Arial, Tahoma, Helvetica, FreeSans, sans-serif; margin: .75em 0 0; } .post-body { font-size: 110%; line-height: 1.4; position: relative; } .post-body img, .post-body .tr-caption-container, .Profile img, .Image img, .BlogList .item-thumbnail img { padding: 2px; background: #ffffff; border: 1px solid #ffffff; -moz-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); -webkit-box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); box-shadow: 1px 1px 5px rgba(0, 0, 0, .1); } .post-body img, .post-body .tr-caption-container { padding: 5px; } .post-body .tr-caption-container { color: #222222; } .post-body .tr-caption-container img { padding: 0; background: transparent; border: none; -moz-box-shadow: 0 0 0 rgba(0, 0, 0, .1); -webkit-box-shadow: 0 0 0 rgba(0, 0, 0, .1); box-shadow: 0 0 0 rgba(0, 0, 0, .1); } .post-header { margin: 0 0 1.5em; line-height: 1.6; font-size: 90%; } .post-footer { margin: 20px -2px 0; padding: 5px 10px; color: #666666; background-color: #f9f9f9; border-bottom: 1px solid #eeeeee; line-height: 1.6; font-size: 90%; } #comments .comment-author { padding-top: 1.5em; border-top: 1px solid #eeeeee; background-position: 0 1.5em; } #comments .comment-author:first-child { padding-top: 0; border-top: none; } .avatar-image-container { margin: .2em 0 0; } #comments .avatar-image-container img { border: 1px solid #ffffff; } /* Comments ----------------------------------------------- */ .comments .comments-content .icon.blog-author { background-repeat: no-repeat; background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAAZiS0dEAP8A/wD/oL2nkwAAAAlwSFlzAAALEgAACxIB0t1+/AAAAAd0SU1FB9sLFwMeCjjhcOMAAAD+SURBVDjLtZSvTgNBEIe/WRRnm3U8RC1neQdsm1zSBIU9VVF1FkUguQQsD9ITmD7ECZIJSE4OZo9stoVjC/zc7ky+zH9hXwVwDpTAWWLrgS3QAe8AZgaAJI5zYAmc8r0G4AHYHQKVwII8PZrZFsBFkeRCABYiMh9BRUhnSkPTNCtVXYXURi1FpBDgArj8QU1eVXUzfnjv7yP7kwu1mYrkWlU33vs1QNu2qU8pwN0UpKoqokjWwCztrMuBhEhmh8bD5UDqur75asbcX0BGUB9/HAMB+r32hznJgXy2v0sGLBcyAJ1EK3LFcbo1s91JeLwAbwGYu7TP/3ZGfnXYPgAVNngtqatUNgAAAABJRU5ErkJggg==); } .comments .comments-content .loadmore a { border-top: 1px solid #999999; border-bottom: 1px solid #999999; } .comments .comment-thread.inline-thread { background-color: #f9f9f9; } .comments .continue { border-top: 2px solid #999999; } /* Accents ---------------------------------------------- */ .section-columns td.columns-cell { border-left: 1px solid #eeeeee; } .blog-pager { background: transparent none no-repeat scroll top center; } .blog-pager-older-link, .home-link, .blog-pager-newer-link { background-color: #ffffff; padding: 5px; } .footer-outer { border-top: 0 dashed #bbbbbb; } /* Mobile ----------------------------------------------- */ body.mobile { background-size: auto; } .mobile .body-fauxcolumn-outer { background: transparent none repeat scroll top left; } .mobile .body-fauxcolumn-outer .cap-top { background-size: 100% auto; } .mobile .content-outer { -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, .15); box-shadow: 0 0 3px rgba(0, 0, 0, .15); } .mobile .tabs-inner .widget ul { margin-left: 0; margin-right: 0; } .mobile .post { margin: 0; } .mobile .main-inner .column-center-inner .section { margin: 0; } .mobile .date-header span { padding: 0.1em 10px; margin: 0 -10px; } .mobile h3.post-title { margin: 0; } .mobile .blog-pager { background: transparent none no-repeat scroll top center; } .mobile .footer-outer { border-top: none; } .mobile .main-inner, .mobile .footer-inner { background-color: #ffffff; } .mobile-index-contents { color: #222222; } .mobile-link-button { background-color: #121fb3; } .mobile-link-button a:link, .mobile-link-button a:visited { color: #ffffff; } .mobile .tabs-inner .section:first-child { border-top: none; } .mobile .tabs-inner .PageList .widget-content { background-color: #eeeeee; color: #000000; border-top: 1px solid #eeeeee; border-bottom: 1px solid #eeeeee; } .mobile .tabs-inner .PageList .widget-content .pagelist-arrow { border-left: 1px solid #eeeeee; } .content-outer { max-width: 1400px !important; } /* fix header */ #header-inner { width: 100% !important; background-position: right !important; } .titlewrapper { padding: 11px 30px 0 !important; } .descriptionwrapper { margin-bottom: 0 !important; } .description { font-size: 120% !important; } /* suppress things */ .date-header { display: none; } #Attribution1 { display: none; } .post-author, .post-timestamp, .reaction-buttons { display: none; } /* h2: sidebar titles */ /* h3: post title */ .post-title , .entry-title { font-size: 180% !important; margin-top: 0 !important; } .entry-title a:link, .entry-title a:visited, .entry-title a:active{ color: #a03; } #main h2 { color:#333; margin-bottom:.4em; margin-top: 13px; font-size:140%; } #main h3 { color:#333; margin-bottom:.4em; margin-top: 13px; font-size:110%; } #main h4 { color:#333; margin-bottom:.5em; } #sidebar-right-1 a:link, #sidebar-right-1 a:visited, #sidebar-right-1 a:active { color: #666; } #sidebar-right-1 h2 { font-size: 100%; color: #666; } /* disable image box */ element.style { } table.chargers img { height: 18px; } table.chargers img { height: 18px; } .post-body img, .post-body .tr-caption-container { padding: 5px; } .post-body img, .post-body .tr-caption-container, .Profile img, .Image img, .BlogList .item-thumbnail img { padding: 0; background: #ffffff; border: none; -moz-box-shadow: none; -webkit-box-shadow: none; box-shadow: none; } /* Special items */ a:link img.hilite, a:visited img.hilite { color: #fff; } a:hover img.hilite, a:hover img.hilite2 { color: #f66; } a:active img.hilite { color: #33c; } .hilite {cursor:zoom-in} pre {color:#000000;border:1px solid #000000;} pre.repl { background-color:#e0e0f0; font-size:120%;} pre.arc { background-color:#e0e0f0; font-size:120%;} pre.code { background-color:#e0f0e0; font-size:120%; white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word;text-wrap:unrestricted;} code { font-size: 100%;} blockquote { font-size: 110%; background: transparent url("//static.righto.com/images/blockquote.gif") no-repeat 0 0; margin: 20px 0px; padding: 0px 40px;} div.cite {font-size: .8em;.; font-style: italic; color: #888; margin-bottom: 9px;} a.ref { color: gray;vertical-align: super; text-decoration: none; font-size:60%;margin-left: 2px;} a img.hilite { border: 1px solid; color: #888; z-index: 2; } a img.hilite2, a:active img.hilite2 { border: 1px solid; color: #f6fbf6; } table.chargers { border-width: 1px; border-spacing: 2px; border-style: outset; border-color: gray; border-collapse: collapse; background-color: white; } table.chargers th.maker { padding-right: 5px; text-align: right; } table.chargers th { border-width: 1px; padding: 3px; border-style: inset; border-color: gray; background-color: white; text-align: center; } table.chargers img { height: 18px; } table.chargers td { text-align: center; border-width: 1px; padding: 2px 8px; border-style: inset; border-color: gray; background-color: white; } --></style> <style id='template-skin-1' type='text/css'><!-- body { min-width: 750px; } .content-outer, .content-fauxcolumn-outer, .region-inner { min-width: 750px; max-width: 750px; _width: 750px; } .main-inner .columns { padding-left: 0px; padding-right: 240px; } .main-inner .fauxcolumn-center-outer { left: 0px; right: 240px; /* IE6 does not respect left and right together */ _width: expression(this.parentNode.offsetWidth - parseInt("0px") - parseInt("240px") + 'px'); } .main-inner .fauxcolumn-left-outer { width: 0px; } .main-inner .fauxcolumn-right-outer { width: 240px; } .main-inner .column-left-outer { width: 0px; right: 100%; margin-left: -0px; } .main-inner .column-right-outer { width: 240px; margin-right: -240px; } #layout { min-width: 0; } #layout .content-outer { min-width: 0; width: 800px; } #layout .region-inner { min-width: 0; width: auto; } --></style> <meta content='width=device-width, initial-scale=1.0, maximum-scale=12.0, minimum-scale=.25, user-scalable=yes' name='viewport'/> <meta content='mw8ww70r3jW0GzXY6j1d' name='follow_it-verification-code'/> <link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=6264947694886887540&zx=0ab53985-160a-4fab-8570-25779a6f0b03' media='none' onload='if(media!='all')media='all'' rel='stylesheet'/><noscript><link href='https://www.blogger.com/dyn-css/authorization.css?targetBlogID=6264947694886887540&zx=0ab53985-160a-4fab-8570-25779a6f0b03' rel='stylesheet'/></noscript> <meta name='google-adsense-platform-account' content='ca-host-pub-1556223355139109'/> <meta name='google-adsense-platform-domain' content='blogspot.com'/> </head> <body class='loading'> <div class='navbar no-items section' id='navbar'> </div> <div class='body-fauxcolumns'> <div class='fauxcolumn-outer body-fauxcolumn-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <div class='content'> <div class='content-fauxcolumns'> <div class='fauxcolumn-outer content-fauxcolumn-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <div class='content-outer'> <div class='content-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left content-fauxborder-left'> <div class='fauxborder-right content-fauxborder-right'></div> <div class='content-inner'> <header> <div class='header-outer'> <div class='header-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left header-fauxborder-left'> <div class='fauxborder-right header-fauxborder-right'></div> <div class='region-inner header-inner'> <div class='header section' id='header'><div class='widget Header' data-version='1' id='Header1'> <div id='header-inner' style='background-image: url("https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-4KXwYe0lQ4HFzhAye9vvRlij2ZYvMbfPCnqEE__1o85Fjo3XgefxJQhWRdwR3EzNWNMWT3yMaj2QZaT9GazqQx3C6oWa3-hBNlRHG7f-Oib-lv1Wq_C2_A0rt8xZgs87iNqzRVKK7H0A/s800/background.jpg"); background-position: left; width: 550px; min-height: 105px; _height: 105px; background-repeat: no-repeat; '> <div class='titlewrapper' style='background: transparent'> <h1 class='title' style='background: transparent; border-width: 0px'> <a href='http://www.righto.com/'> Ken Shirriff's blog </a> </h1> </div> <div class='descriptionwrapper'> <p class='description'><span>Computer history, restoring vintage computers, IC reverse engineering, and whatever</span></p> </div> </div> </div></div> </div> </div> <div class='header-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </header> <div class='tabs-outer'> <div class='tabs-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left tabs-fauxborder-left'> <div class='fauxborder-right tabs-fauxborder-right'></div> <div class='region-inner tabs-inner'> <div class='tabs no-items section' id='crosscol'></div> <div class='tabs no-items section' id='crosscol-overflow'></div> </div> </div> <div class='tabs-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='main-outer'> <div class='main-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left main-fauxborder-left'> <div class='fauxborder-right main-fauxborder-right'></div> <div class='region-inner main-inner'> <div class='columns fauxcolumns'> <div class='fauxcolumn-outer fauxcolumn-center-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='fauxcolumn-outer fauxcolumn-left-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <div class='fauxcolumn-outer fauxcolumn-right-outer'> <div class='cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left'> <div class='fauxborder-right'></div> <div class='fauxcolumn-inner'> </div> </div> <div class='cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <!-- corrects IE6 width calculation --> <div class='columns-inner'> <div class='column-center-outer'> <div class='column-center-inner'> <div class='main section' id='main'><div class='widget Blog' data-version='1' id='Blog1'> <div class='blog-posts hfeed'> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://static.righto.com/images/tms1000-ram/tms-1000-labeled-w500.jpg' itemprop='image_url'/> <meta content='6264947694886887540' itemprop='blogId'/> <meta content='7549419045871524985' itemprop='postId'/> <a name='7549419045871524985'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='http://www.righto.com/2020/11/reverse-engineering-ram-storage-in.html'>Reverse engineering RAM storage in early Texas Instruments calculator chips</a> </h3> <div class='post-header'> <div class='post-header-line-1'></div> </div> <div class='post-body entry-content' id='post-body-7549419045871524985' itemprop='description articleBody'> <style> .hilite {cursor:zoom-in} a:link img.hilite, a:visited img.hilite { color: #fff;} </style> <p>Texas Instruments introduced the first commercial single-chip computer in 1974, combining the CPU, RAM, ROM, and I/O into one chip. This family of 4-bit processors was called the TMS1000.<span id="fnref:tms0100"><a class="ref" href="#fn:tms0100">1</a></span> A 4-bit processor now seems very limited, but it was a good match for calculators, where each decimal digit fit into four bits. This microcontroller was also used in hand-held games<span id="fnref:speakandspell"><a class="ref" href="#fn:speakandspell">2</a></span> and simple control applications such as microwave ovens.<span id="fnref:architecture"><a class="ref" href="#fn:architecture">3</a></span> Since its software was in ROM, the TMS1000 needed to be custom-manufactured for each application, but it was inexpensive and sold for $2-$4 in quantity. It became very popular and was <a href="http://smithsonianchips.si.edu/augarten/p38.htm">said to be</a> the best-selling "computer on a chip".</p> <p><a href="https://static.righto.com/images/tms1000-ram/tms-1000-labeled.jpg"><img alt="TMS-1000 die with key functional blocks labeled. Die photo courtesy of Sean Riddle." class="hilite" height="494" src="https://static.righto.com/images/tms1000-ram/tms-1000-labeled-w500.jpg" title="TMS-1000 die with key functional blocks labeled. Die photo courtesy of Sean Riddle." width="500" /></a><div class="cite">TMS-1000 die with key functional blocks labeled. Die photo courtesy of <a href="https://seanriddle.com/entexbaseballmetal.jpg">Sean Riddle</a>.</div></p> <p>The die photo above shows the main functional blocks of the TMS1000. One thing that distinguishes the TMS1000 (and most microcontrollers) from regular processors is the "Harvard architecture", where code and data are stored and accessed separately. In the TMS1000, code and data even have different sizes: instructions were 8 bits and stored in a 1-kilobyte ROM, while data was 4 bits and stored in a 64×4 (256-bit) RAM.<span id="fnref:manual"><a class="ref" href="#fn:manual">4</a></span> Since the space for RAM was limited, Texas Instruments developed new circuits for RAM. In this blog post, I look at how the TMS1000 and later TI chips implemented their on-chip RAM.</p> <!--  --> <h2>TMS1000 RAM</h2> <p>Dynamic RAM revolutionized memory storage in the <a href="https://www.computerhistory.org/siliconengine/mos-dynamic-ram-competes-with-magnetic-core-memory-on-price/">early 1970s</a>; its low cost and high density rapidly made magnetic core memory obsolete. Dynamic RAM uses a tiny capacitor to store each bit, with a 0 or 1 represented by a low or high voltage stored in the capacitor. The problem with dynamic RAM is that the charge leaks away after a few milliseconds, so the values need to be constantly refreshed by reading the data, amplifying the voltages, and storing the values back in the capacitors.<span id="fnref:reg8008"><a class="ref" href="#fn:reg8008">5</a></span> Texas Instruments developed a new dynamic RAM circuit for the TMS1000 to avoid the complexity of an external refresh circuit. Instead, each memory cell uses a clock signal to refresh itself internally.</p> <p>The diagram below zooms in on the TMS1000 die photo, showing the 16×16 grid of RAM storage cells. The inset at the right shows a single storage cell. This photo shows the chip's metal layer; the transistors are underneath.</p> <p><a href="https://static.righto.com/images/tms1000-ram/tms-1000-zoom.jpg"><img alt="Zooming in on the RAM array, and then a single bit of storage." class="hilite" height="402" src="https://static.righto.com/images/tms1000-ram/tms-1000-zoom-w500.jpg" title="Zooming in on the RAM array, and then a single bit of storage." width="500" /></a><div class="cite">Zooming in on the RAM array, and then a single bit of storage.</div></p> <p>The TMS1000 is constructed from a type of transistor called PMOS, shown below. At the bottom, two regions of silicon (red) are doped to make them conductive, forming the source and drain of the transistor. A metal strip in between forms the gate, separated from the silicon by a thin layer of insulating oxide. (These layers—Metal, Oxide, Semiconductor—give the MOS transistor its name.) The transistor can be considered a switch between the source and drain, controlled by the gate. The metal layer also provides the main wiring of the integrated circuit, although the silicon layer is also used for some wiring.</p> <p><a href="https://static.righto.com/images/tms1000-ram/mosfet-red.jpg"><img alt="Structure of a PMOS metal-gate transistor." class="hilite" height="232" src="https://static.righto.com/images/tms1000-ram/mosfet-red-w400.jpg" title="Structure of a PMOS metal-gate transistor." width="400" /></a><div class="cite">Structure of a PMOS metal-gate transistor.</div></p> <p>The diagram below shows a closeup of one bit of storage in the TMS1000. The first die photo shows the yellowish metal layer. The metal layer both connects the circuitry and forms the gates of the transistors. The second photo shows the die after the metal has been dissolved with acid to reveal the silicon underneath. The conductive doped silicon appears pinkish, while the transistors are yellow squares. The black spot in the lower left is a via connecting the silicon to the metal above. Since the photo is hard to interpret, I created the diagram at the right, clarifying the components. The five white squares are the transistors, between pink silicon regions. There are also two capacitors (labeled) created by overlapping the metal and silicon.</p> <p><a href="https://static.righto.com/images/tms1000-ram/tms-1000-cell.jpg"><img alt="One bit of RAM storage. The first photo shows the metal layer, the second shows the underlying silicon, and the third illustrates the silicon structures. Die photos from Sean Riddle here." class="hilite" height="205" src="https://static.righto.com/images/tms1000-ram/tms-1000-cell-w600.jpg" title="One bit of RAM storage. The first photo shows the metal layer, the second shows the underlying silicon, and the third illustrates the silicon structures. Die photos from Sean Riddle here." width="600" /></a><div class="cite">One bit of RAM storage. The first photo shows the metal layer, the second shows the underlying silicon, and the third illustrates the silicon structures. Die photos from Sean Riddle <a href="https://seanriddle.com/sr16iiacid.jpg">here</a>.</div></p> <p>The schematic below corresponds to the above circuit, with the transistors in their approximate physical locations. To write a bit, the bit is placed on the data I/O line and the address line is activated.<span id="fnref:bit-discussion"><a class="ref" href="#fn:bit-discussion">8</a></span> This turns on transistor Q4 and allows the bit to flow to point A, where it is maintained (temporarily) by the capacitor there. The bit can be read out the same way, by activating the address line. In a typical dynamic RAM chip, each cell consists of just this transistor and capacitor, but the TMS1000 uses the additional transistors to refresh the voltage on the capacitor.</p> <p><a href="https://static.righto.com/images/tms1000-ram/tms-1000-schematic.jpg"><img alt="Schematic of a dynamic RAM storage cell in the TMS1000." class="hilite" height="252" src="https://static.righto.com/images/tms1000-ram/tms-1000-schematic-w300.jpg" title="Schematic of a dynamic RAM storage cell in the TMS1000." width="300" /></a><div class="cite">Schematic of a dynamic RAM storage cell in the TMS1000.</div></p> <p>The TMS1000 refresh circuit is driven by two clock signals, clock phase 1 (桅1) and clock phase 5 (桅5).<span id="fnref:clock"><a class="ref" href="#fn:clock">7</a></span> Activating clock phase 5 turns on Q3 and allows the bit to flow to point C, the gate of transistor Q1. Large transistor Q1 is the key component of the refresh circuit, as it amplifies the signal C. Next, during clock phase 1, the amplified signal at B flows through Q2, restoring the original bit stored at A. This circuit is repeated 256 times for the 256 bits of RAM storage in the chip. These clock signals are activated at about 80 kilohertz, ensuring the bit is refreshed before it can drain away.</p> <h2>The move to CMOS</h2> <p>CMOS (Complementary MOS) is a type of circuitry that combines NMOS and PMOS transistors to reduce power consumption. In 1978, TI began building CMOS calculator chips, starting with the TP0310 and TP0320 chips.<span id="fnref:datamath"><a class="ref" href="#fn:datamath">6</a></span> These chips were used in calculators such as the TI-30-II (below), TI-35, and TI-50. The switch to CMOS coincided with TI's switch from power-hungry LED or vacuum fluorescent displays (VFD) to low-power LCD (<a href="http://www.datamath.org/Story/Intel.htm">details</a>). These improvements led to better battery life. TI also used CMOS to implement "Constant Memory™", preserving calculator data even when the calculator was off; CMOS's low power consumption meant that the memory could be continuously powered without draining the battery.</p> <p><a href="https://static.righto.com/images/tms1000-ram/TI-30II.jpg"><img alt="The TI-30-II calculator used the TP0320 processor. Photo courtesy of Datamath Calculator Museum." class="hilite" height="380" src="https://static.righto.com/images/tms1000-ram/TI-30II-w220.jpg" title="The TI-30-II calculator used the TP0320 processor. Photo courtesy of Datamath Calculator Museum." width="220" /></a><div class="cite">The TI-30-II calculator used the TP0320 processor. Photo courtesy of <a href="http://www.datamath.org/Sci/Slimline/TI-30-II.htm">Datamath Calculator Museum</a>.</div></p> <p>CMOS has a long history, starting with its invention in <a href="https://www.computerhistory.org/siliconengine/complementary-mos-circuit-configuration-is-invented/">1963</a>. RCA did a lot of early development of CMOS, introducing the <a href="https://en.wikipedia.org/wiki/4000-series_integrated_circuits">4000-series</a> of integrated circuits in 1968 and the first CMOS processor, the <a href="https://spectrum.ieee.org/semiconductors/processors/chip-hall-of-fame-rca-cdp-1802">RCA 1802</a>, in 1974. RCA was unfortunately a decade too early for market success with CMOS; although CMOS's lower power consumption made it useful for niche aerospace markets, NMOS processors dominated the microprocessor industry. Eventually, however, mainstream microprocessors switched to CMOS with the Intel 80386 in 1985 and Motorola's 68030 in 1987, and CMOS is the dominant technology today.</p> <p>TI's move from metal-gate PMOS to CMOS in 1978 is unusual. Other manufacturers (such as Intel) switched from metal-gate transistors to the much superior <a href="http://intel4004.com/sgate.htm">silicon-gate</a> transistors around 1971, and then moved from PMOS to NMOS around 1974. It's unclear why Texas Instruments continued using inferior metal-gate PMOS circuitry for several years; perhaps calculators didn't need the improved performance so it wasn't cost-effective to switch. But then Texas Instruments skipped over the NMOS generation entirely, jumping to CMOS a decade before the mainstream microprocessor industry. This decision is easier to justify, since low-power CMOS was a clear advantage for battery-powered calculators. Curiously, TI continued to use inferior metal-gate transistors, even after moving to CMOS.</p> <p>This history illustrates that technological progress isn't a straightforward path with new and improved technologies replacing older technologies. Instead, a new technology like CMOS may take years to catch on, becoming successful in particular markets but being not making headway in other markets until economic factors and engineering tradeoffs changed.</p> <p>Getting back to the TP0320, the die photo below shows the <a href="https://seanriddle.com/tp0320.html">TP0320</a> die, zooming in on the RAM array. This 32×24 array holds 768 bits, a significant upgrade from the TMS1000. The closeup at the right zooms in on a single bit. The bit cell has a different layout from the TMS1000 RAM. The design switched from dynamic RAM to static RAM, eliminating the capacitors and the need for refresh. In this section, I'll explain how this RAM cell is implemented.</p> <p><a href="https://static.righto.com/images/tms1000-ram/tms-0320-zoom.jpg"><img alt="Die of the TMS-0320, zooming in on the 32×24 RAM array and a single storage cell. Original die photo from Sean Riddle." class="hilite" height="475" src="https://static.righto.com/images/tms1000-ram/tms-0320-zoom-w500.jpg" title="Die of the TMS-0320, zooming in on the 32×24 RAM array and a single storage cell. Original die photo from Sean Riddle." width="500" /></a><div class="cite">Die of the TMS-0320, zooming in on the 32×24 RAM array and a single storage cell. Original die photo from <a href="https://seanriddle.com/tibaiimetal.jpg">Sean Riddle</a>.</div></p> <p>The diagram below shows how two inverters can be connected in a loop to store either a 0 or a 1. If the upper signal is 1, the inverter on the right outputs a 0 on the bottom, and the inverter on the left outputs a 1 at the top, reinforcing the original signal. Alternatively, the top signal can be a 0 as shown on the righ. The key difference between this static circuit and the previous dynamic circuit is that the static circuit will hold a bit for an arbitrarily long time. The bit won't leak out of a capacitor as in a dynamic RAM, so refresh is not needed.</p> <p><a href="https://static.righto.com/images/tms1000-ram/inverters.jpg"><img alt="Two cross-coupled inverters can store either a 0 or a 1." class="hilite" height="138" src="https://static.righto.com/images/tms1000-ram/inverters-w300.jpg" title="Two cross-coupled inverters can store either a 0 or a 1." width="300" /></a><div class="cite">Two cross-coupled inverters can store either a 0 or a 1.</div></p> <p>To make a usable storage cell, an addressing mechanism is added to the inverter circuit above. When the address select line is activated, the transistors connect the inverters to the data lines. For a read, the value of the cell is read from the data line. For a write, the desired bit and its complement are applied to the data lines, overpowering the value stored in the inverters and switching them to the new bit value. This type of storage cell is used to implement registers in many processors, including the <a href="http://www.righto.com/2014/10/how-z80s-registers-are-implemented-down.html">Zilog Z80</a> and the <a href="http://www.righto.com/2013/03/register-file-8085.html">Intel 8085</a>.</p> <p><a href="https://static.righto.com/images/tms1000-ram/inverter-cell.jpg"><img alt="To make a usable storage cell, transistors are added to select the cell." class="hilite" height="277" src="https://static.righto.com/images/tms1000-ram/inverter-cell-w200.jpg" title="To make a usable storage cell, transistors are added to select the cell." width="200" /></a><div class="cite">To make a usable storage cell, transistors are added to select the cell.</div></p> <p>The diagram below shows how a CMOS inverter is constructed from two transistors. The upper transistor is a PMOS transistor, while the lower transistor is an NMOS transistor. With a 0 input, the PMOS transistor turns on, connecting the output to the positive voltage (1). With a 1 input, the NMOS transistor turns on, connecting the output to ground (0). Thus, the output is the opposite of the input, as you'd expect from an inverter.</p> <p><a href="https://static.righto.com/images/tms1000-ram/inverter.jpg"><img alt="A CMOS inverter is built from an NMOS transistor and a PMOS transistor." class="hilite" height="232" src="https://static.righto.com/images/tms1000-ram/inverter-w150.jpg" title="A CMOS inverter is built from an NMOS transistor and a PMOS transistor." width="150" /></a><div class="cite">A CMOS inverter is built from an NMOS transistor and a PMOS transistor.</div></p> <p>Putting this all together yields the schematic below. Transistors Q1 and Q3 implement one inverter, while transistors Q2 and Q4 implement the second inverter. Transistors Q5 and Q6 select the cell based on the address. The transistors are arranged on the schematic to match their physical locations.</p> <p><a href="https://static.righto.com/images/tms1000-ram/schematic-0320.jpg"><img alt="Schematic of one bit of storage in the TP0320 chip." class="hilite" height="407" src="https://static.righto.com/images/tms1000-ram/schematic-0320-w250.jpg" title="Schematic of one bit of storage in the TP0320 chip." width="250" /></a><div class="cite">Schematic of one bit of storage in the TP0320 chip.</div></p> <p>The die photos below show how the storage cell is implemented in the TP0320 processor. The first photo shows three vertical metal traces that wire the cell together. In the second photo, the metal was removed with acid to reveal the silicon underneath. The upper section holds the PMOS transistors (Q1 and Q2) while the lower section holds the NMOS transistors (Q3 to Q6). The transistors appear as whitish rectangles, while the doped silicon appears as greenish or reddish lines. The black spots are vias connecting the silicon to the metal above. The diagram can be compared with the schematic above.</p> <p><a href="https://static.righto.com/images/tms1000-ram/cell-0320.jpg"><img alt="One RAM cell in the TP0320. The first photo shows the metal layer. The second photo shows the underlying silicon. The diagram shows the combined layers. Die photos courtesy of Sean Riddle." class="hilite" height="317" src="https://static.righto.com/images/tms1000-ram/cell-0320-w500.jpg" title="One RAM cell in the TP0320. The first photo shows the metal layer. The second photo shows the underlying silicon. The diagram shows the combined layers. Die photos courtesy of Sean Riddle." width="500" /></a><div class="cite">One RAM cell in the TP0320. The first photo shows the metal layer. The second photo shows the underlying silicon. The diagram shows the combined layers. Die photos courtesy of <a href="https://seanriddle.com/tp0320.html">Sean Riddle</a>.</div></p> <p>The photo below zooms out a bit to show how the NMOS and PMOS transistors are arranged. Note the "P ring" that surrounds the NMOS transistors. This forms a tub of P-type silicon that holds the NMOS transistors. (This P ring is the horizontal green line below Q2 in the die photo above.) The chip contains many of these tubs, separating the PMOS and NMOS transistors.</p> <p><a href="https://static.righto.com/images/tms1000-ram/cmos-tub.jpg"><img alt="The NMOS transistors are located in a P-type "tub" surrounded by a ring of P-type silicon." class="hilite" height="233" src="https://static.righto.com/images/tms1000-ram/cmos-tub-w400.jpg" title="The NMOS transistors are located in a P-type "tub" surrounded by a ring of P-type silicon." width="400" /></a><div class="cite">The NMOS transistors are located in a P-type "tub" surrounded by a ring of P-type silicon.</div></p> <h2>TP0456</h2> <p>In 1981, Texas Instruments introduced a <a href="http://www.datamath.org/IC_List.htm#Enhanced%20C-MOS">more powerful architecture</a>, the TP0455, followed shortlly by the TP0456. The TP0456 chip was used in calculators such as the <a href="http://www.datamath.org/Sci/Slanted/TI-55-II.htm">TI-55-II</a> scientific calculator, TI-35, and TI-60, as well as educational toys such as <a href="http://www.datamath.org/Edu/Professor-82.htm">Little Professor</a> and <a href="http://www.datamath.org/Edu/SpellingB_LCD.htm">Spelling B</a>.</p> <p><a href="https://static.righto.com/images/tms1000-ram/Prof_82.jpg"><img alt="The Texas Instruments Little Professor. Photo courtesy of Datamath Calculator Museum." class="hilite" height="324" src="https://static.righto.com/images/tms1000-ram/Prof_82-w200.jpg" title="The Texas Instruments Little Professor. Photo courtesy of Datamath Calculator Museum." width="200" /></a><div class="cite">The Texas Instruments Little Professor. Photo courtesy of <a href="http://www.datamath.org/Edu/Professor-82.htm">Datamath Calculator Museum</a>.</div></p> <p>The die photo below shows the TP0456. The RAM array is in the lower-left corner of the die photo below, while the ROM is in the lower-right. The TP0456's RAM array is 32 cells wide and 16 cells tall, providing 512 bits of storage, less than the 768 bits of the TP0320.</p> <p><a href="https://static.righto.com/images/tms1000-ram/0456-56_metal.jpg"><img alt="Die photo of a TP0456 as used in the TI-55-II calculator; the calculator uses two TP0456 chips. Die photo courtesy of Sean Riddle." class="hilite" height="554" src="https://static.righto.com/images/tms1000-ram/0456-56_metal-w450.jpg" title="Die photo of a TP0456 as used in the TI-55-II calculator; the calculator uses two TP0456 chips. Die photo courtesy of Sean Riddle." width="450" /></a><div class="cite">Die photo of a TP0456 as used in the TI-55-II calculator; the calculator uses two TP0456 chips. Die photo courtesy of <a href="https://seanriddle.com/tp0456.html">Sean Riddle</a>.</div></p> <p>The TP0456 uses almost the same static cell structure as the earlier CMOS chips, but the layout was changed slightly. In particular, the select line runs between the two inverter lines, rather than on the side. I don't know why they made this change, as it doesn't appear to change the density. The static RAM circuit is same as the TP0320 described earlier, so I won't discuss it here.</p> <p><a href="https://static.righto.com/images/tms1000-ram/0456-cells.jpg"><img alt="Two RAM cells in the TP0456. The long vertical select lines run between the shorter inverter lines, unlike the layout of earlier cells." class="hilite" height="228" src="https://static.righto.com/images/tms1000-ram/0456-cells-w150.jpg" title="Two RAM cells in the TP0456. The long vertical select lines run between the shorter inverter lines, unlike the layout of earlier cells." width="150" /></a><div class="cite">Two RAM cells in the TP0456. The long vertical select lines run between the shorter inverter lines, unlike the layout of earlier cells.</div></p> <h2>Conclusion</h2> <p>While RAM storage may seem trivial, early microcontrollers required new ways to fit storage into the limited space on a die. Even just 256 bits took up a substantial fraction of the chip. Texas Instruments developed new dynamic RAM circuits for the TMS1000 microcontroller, followed by a completely different static circuit when they switched to CMOS microcontrollers.</p> <p>Decades later, microcontrollers still have limited memory capacity. The Arduino Uno, for example, has 32 kilobytes of flash for program storage and 2 kilobytes of RAM. Modern high-end microcontrollers can have megabytes for program storage and hundreds of kilobytes of RAM, but this is still orders of magnitude less than a typical microcomputer. The constraints of fitting everything onto a single chip still limit capacity and still require novel solutions, just as in the TMS1000.</p> <!-- It is interesting to compare the early processors of Texas Instruments and Intel since they started with very similar chips but then went in radically different directions. In 1971, Intel created the 4-bit 4004 processor as a calculator chip but then marketed it as "a micro-programmable computer on a chip" for control applications. Meanwhile, Texas Instruments created the TMS0100 (prior to the TMS1000) series of calculator/microcontroller chips. In 1970, a company called CTC asked both Texas Instruments and Intel to produce a single-chip 8-bit processor matching the architecture of their Datapoint 2200 desktop computer. Texas Instruments created the [mostly-forgotten TMX 1795](https://spectrum.ieee.org/tech-history/silicon-revolution/the-surprising-story-of-the-first-microprocessors), a few months before Intel came out with the 8008. Datapoint, however, decided not to use either chip. Texas Instruments couldn't find a customer for the TMX 1795 so they abandoned it to concentrate on the calculator and microcontroller markets.[tms9900] Intel, on the other hand, marketed the 8008 as a microprocessor, creating the microprocessor industry and eventually the now-dominant x86 architecture. Intel also produced popular microcontrollers such as the 8048 (1976) and 8051 (1980)[intel], but they weren't the focus of Intel's attention. [tms9900]: Texas Instruments made another attempt into the general-purpose microprocessor market in 1976. They produced the TMS9900, an early 16-bit processor, but it is [considered a failure](https://spectrum.ieee.org/tech-history/heroic-failures/the-inside-story-of-texas-instruments-biggest-blunder-the-tms9900-microprocessor). [intel]: Intel's microcontrollers were much more like standard 8-bit processors than Texas Instruments' 4-bit calculator-inspired microcontrollers. Unlike the TMS1000, the Intel microcontrollers had familiar features such as an 8-bit CPU, 8-bit I/O ports, interrupts, a stack, and a fixed instruction set with Boolean operations (AND, OR, XOR) and shifts. Looking at the TMS1000 instruction set, it seems slightly alien, while the 8048's instruction set is similar to microprocessors of the time. --> <p>I announce my latest blog posts on Twitter, so follow me at <a href="https://twitter.com/kenshirriff">kenshirriff</a>. I also have an <a href="http://www.righto.com/feeds/posts/default">RSS feed</a>. Thanks to Joerg Woerner at <a href="datamath.org">Datamath</a> for suggesting this topic and thanks to <a href="https://seanriddle.com/decap.html">Sean Riddle</a> for die photos.</p> <h2>Notes and references</h2> <div class="footnote"> <ol> <li id="fn:tms0100"> <p>Texas Instruments is considered the inventor of the microcontroller for developing the TMS0100 (different from the TMS1000) in 1971. While the TMS0100 has the characteristics of a microcontroller, it was marketed as a "calculator-on-a-chip". The TMS1000, however, was marketed as a "single-chip computer" for both calculator-type applications and small to medium control applications. <a class="footnote-backref" href="#fnref:tms0100" title="Jump back to footnote 1 in the text">↩</a></p> </li> <li id="fn:speakandspell"> <p>Some handheld games using the TMS1000 are listed <a href="https://seanriddle.com/tms1000.html">here</a>. <a class="footnote-backref" href="#fnref:speakandspell" title="Jump back to footnote 2 in the text">↩</a></p> </li> <li id="fn:architecture"> <p>The architecture of the TMS1000 is rather unusual due to its roots as a calculator chip. It has just four input lines, designed to be connected to a grid of buttons. The outputs are also unusual: it has 8 "O" output lines, but these are not individually controllable. Instead, a 5-bit value is converted to the eight outputs by a customizable PLA decoder. The motivation behind this is to drive a 7-segment display. The microcontroller also has 11 "R" outputs, which are typically used to multiplex the LED display and to scan the keyboard. Another curious feature of the TMS1000 is that the instruction set was somewhat customizable.</p> <p>In comparison, Intel's microcontrollers such as the popular 8048 (1976) and 8051 (1980) were much more like standard 8-bit microprocessors. Unlike the TMS1000, the Intel microcontrollers had familiar features such as an 8-bit CPU, 8-bit I/O ports, interrupts, a stack, and a fixed instruction set with Boolean operations (AND, OR, XOR) and shifts. Looking at the TMS1000 instruction set, it seems slightly alien, while the 8048's instruction set is similar to microprocessors of the time. <a class="footnote-backref" href="#fnref:architecture" title="Jump back to footnote 3 in the text">↩</a></p> </li> <li id="fn:manual"> <p>Detailed information on the TMS1000 is in the <a href="http://www.bitsavers.org/components/ti/TMS1000/TMS_1000_Series_Data_Manual_Dec76.pdf">TMS1000 manual</a>. <a class="footnote-backref" href="#fnref:manual" title="Jump back to footnote 4 in the text">↩</a></p> </li> <li id="fn:reg8008"> <p>Dynamic RAM is sometimes used for register storage in a processor, such as the <a href="http://www.righto.com/2017/03/analyzing-vintage-8008-processor-from.html">Intel 8008</a>, although static RAM is more common since it doesn't require refreshing. <a class="footnote-backref" href="#fnref:reg8008" title="Jump back to footnote 5 in the text">↩</a></p> </li> <li id="fn:datamath"> <p>The <a href="http://www.datamath.org/">Datamath Calculator Museum</a> has tons of information on Texas Instruments calculators. The <a href="http://www.datamath.org/IC_List.htm">list of ICs</a> is particularly relevant. <a class="footnote-backref" href="#fnref:datamath" title="Jump back to footnote 6 in the text">↩</a></p> </li> <li id="fn:clock"> <p>The TMS1000 is implemented with complex logic circuitry, using a five-phase clock. The TMS1000 uses a mixture of depletion loads, gated loads, or precharge logic, for power savings. <!-- patent US3991305 column 24 --> I'm not sure why the TMS1000 uses a five-phase clock. <a href="https://en.wikipedia.org/wiki/Four-phase_logic">Four-phase logic</a> was a logic design methodology at the time, but the TMS1000 circuitry doesn't appear to use four-phase principles. Among other things, the TMS1000 phases are irregular and 桅4 pulses twice per cycle. <a class="footnote-backref" href="#fnref:clock" title="Jump back to footnote 7 in the text">↩</a></p> </li> <li id="fn:bit-discussion"> <p>TI's <a href="https://patents.google.com/patent/US3876993A">Random access memory cell patent</a> (1974) describes the memory cell used in the TMS1000. The layout in the patent is similar but not identical to the actual layout. Transistor Q5 appears in the circuit but not the patent. It pulls point B to 0 when clock phase 5 is active, making sure that a 0 bit at C is restored to a stronger 0 bit.</p> <p><a href="https://static.righto.com/images/tms1000-ram/patent-diagram.jpg"><img alt="Diagram of a dynamic RAM cell, based on the Random Access Memory Cell Patent." class="hilite" height="371" src="https://static.righto.com/images/tms1000-ram/patent-diagram-w400.jpg" title="Diagram of a dynamic RAM cell, based on the Random Access Memory Cell Patent." width="400" /></a><div class="cite">Diagram of a dynamic RAM cell, based on the <a href="https://patents.google.com/patent/US3876993A">Random Access Memory Cell Patent</a>.</div></p> <p>While most patents don't provide much useful information, Texas Instruments' calculator patents are unusually detailed and informative, providing schematics, source code, and clear explanations; they seem like they were written by engineers. (I feel that I should give TI credit for the quality of their patents.) <a class="footnote-backref" href="#fnref:bit-discussion" title="Jump back to footnote 8 in the text">↩</a></p> </li> </ol> </div> <div style='clear: both;'></div> </div> <div class='post-footer'> <div class='post-footer-line post-footer-line-1'><span class='post-comment-link'> <a class='comment-link' href='https://www.blogger.com/comment/fullpage/post/6264947694886887540/7549419045871524985' onclick=''> 13 comments: </a> </span> <span class='post-icons'> <span class='item-action'> <a href='https://www.blogger.com/email-post/6264947694886887540/7549419045871524985' title='Email Post'> <img alt='' class='icon-action' height='13' src='http://img1.blogblog.com/img/icon18_email.gif' width='18'/> </a> </span> <span class='item-control blog-admin pid-1138732533'> <a href='https://www.blogger.com/post-edit.g?blogID=6264947694886887540&postID=7549419045871524985&from=pencil' title='Edit Post'> <img alt='' class='icon-action' height='18' src='https://resources.blogblog.com/img/icon18_edit_allbkg.gif' width='18'/> </a> </span> </span> <span class='post-backlinks post-comment-link'> </span> <div class='post-share-buttons goog-inline-block'> <a class='goog-inline-block share-button sb-email' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=7549419045871524985&target=email' target='_blank' title='Email This'><span class='share-button-link-text'>Email This</span></a><a class='goog-inline-block share-button sb-blog' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=7549419045871524985&target=blog' onclick='window.open(this.href, "_blank", "height=270,width=475"); return false;' target='_blank' title='BlogThis!'><span class='share-button-link-text'>BlogThis!</span></a><a class='goog-inline-block share-button sb-twitter' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=7549419045871524985&target=twitter' target='_blank' title='Share to X'><span class='share-button-link-text'>Share to X</span></a><a class='goog-inline-block share-button sb-facebook' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=7549419045871524985&target=facebook' onclick='window.open(this.href, "_blank", "height=430,width=640"); return false;' target='_blank' title='Share to Facebook'><span class='share-button-link-text'>Share to Facebook</span></a><a class='goog-inline-block share-button sb-pinterest' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=7549419045871524985&target=pinterest' target='_blank' title='Share to Pinterest'><span class='share-button-link-text'>Share to Pinterest</span></a> </div> </div> <div class='post-footer-line post-footer-line-2'><span class='post-labels'> Labels: <a href='http://www.righto.com/search/label/calculator' rel='tag'>calculator</a>, <a href='http://www.righto.com/search/label/chips' rel='tag'>chips</a>, <a href='http://www.righto.com/search/label/electronics' rel='tag'>electronics</a>, <a href='http://www.righto.com/search/label/reverse-engineering' rel='tag'>reverse-engineering</a> </span> </div> <div class='post-footer-line post-footer-line-3'></div> </div> </div> </div> </div></div> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://static.righto.com/images/mk4116/metal-rotated-w700.jpg' itemprop='image_url'/> <meta content='6264947694886887540' itemprop='blogId'/> <meta content='9178320223286625683' itemprop='postId'/> <a name='9178320223286625683'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='http://www.righto.com/2020/11/reverse-engineering-classic-mk4116-16.html'>Reverse-engineering the classic MK4116 16-kilobit DRAM chip</a> </h3> <div class='post-header'> <div class='post-header-line-1'></div> </div> <div class='post-body entry-content' id='post-body-9178320223286625683' itemprop='description articleBody'> <style> .hilite {cursor:zoom-in} a:link img.hilite, a:visited img.hilite { color: #fff;} </style> <p>Back in the late 1970s, the most popular memory chip was Mostek's MK4116, holding a whopping (for the time) 16 kilobits. <!-- Introduced 1977, most popular: https://books.google.com/books?id=zAsN0XCHbFsC&pg=PA97 1979, 1980, 1982--> It provided storage for computers such as the Apple II, TRS-80, ZX Spectrum, Commodore PET, IBM PC, and Xerox Alto <!-- Xerox Notetaker, Atari 800, TI 99/4a, --> as well as video games such as Defender and Missile Command. <!-- such as Colecovision, Defender, Joust, Missile Command, Qix, and Robotron. --> <!-- http://www.bitsavers.org/pdf/xerox/notetaker/schematics/19781013_Notetaker_Memory_Storage.pdf --> <!-- https://console5.com/store/16kb-x-1-bit-dram-mb8118-12.html --> <!-- https://www.arcadeshop.com/i/68/4116-ram-set-of-25.htm --> To see how the chip is implemented I opened one up and reverse-engineered it. I expected the circuitry to be similar to other chips of the era, using standard NMOS gates, but it was much more complex than I expected, built from low-power <a href="https://en.wikipedia.org/wiki/Dynamic_logic_(digital_electronics)">dynamic logic</a>. The MK4116 also used advanced manufacturing processes to fit 16,384 high-density memory cells on the chip.<span id="fnref:references"><a class="ref" href="#fn:references">1</a></span><span id="fnref:contacts"><a class="ref" href="#fn:contacts">2</a></span></p> <p>I created the die photo below from multiple microscope images. The white lines are the metal wiring on top of the chip, while the silicon underneath appears dark red. The two large rectangular regions are the 16,384 memory cells, arranged as a 128×128 matrix split in two. In between the two memory arrays are the amplifiers and selection circuits. The control and interface circuitry is at the left and right, connected to the external pins via tiny bond wires.</p> <p><a href="https://static.righto.com/images/mk4116/metal-rotated.jpg"><img alt="Die photo of the 4116 memory chip. Click for a larger image." class="hilite" height="390" src="https://static.righto.com/images/mk4116/metal-rotated-w700.jpg" title="Die photo of the 4116 memory chip. Click for a larger image." width="700" /></a><div class="cite">Die photo of the 4116 memory chip. Click for a larger image.</div></p> <p>In dynamic RAM, each bit is stored in a capacitor with the bit's value, 0 or 1, represented by the voltage on the capacitor.<span id="fnref:charge"><a class="ref" href="#fn:charge">3</a></span> The advantage of dynamic RAM is that each memory cell is very small, so a lot of data can be stored on one chip.<span id="fnref:cell"><a class="ref" href="#fn:cell">4</a></span> The downside of dynamic RAM is that the charge on a capacitor leaks away after a few milliseconds. To avoid losing data, dynamic RAM must be constantly refreshed: bits are read from the capacitors, amplified, and then written back to the capacitors. For the MK4116, all the data must be refreshed every two milliseconds.</p> <p>The diagram below illustrates four of the 16,384 memory cells. Each memory cell has a capacitor, along with a transistor that connects the capacitor to the associated bit line. To read or write data, a row select line is energized, turning on the transistors in that row. The row's capacitors are connected to the bit lines, allowing the bits in that row to be accessed.</p> <p><a href="https://static.righto.com/images/mk4116/patent-diagram.jpg"><img alt="Structure of the memory cells, based on the patent." class="hilite" height="289" src="https://static.righto.com/images/mk4116/patent-diagram-w400.jpg" title="Structure of the memory cells, based on the patent." width="400" /></a><div class="cite">Structure of the memory cells, based on <a href="https://patents.google.com/patent/US4392210A">the patent</a>.</div></p> <p>One of Mostek's key innovations was to multiplex the address pins.<span id="fnref:multiplex"><a class="ref" href="#fn:multiplex">6</a></span> Earlier memory chips used a separate pin for each address bit; as memory sizes increased, so did the number of address pins. This forced Intel's <a href="https://drive.google.com/file/d/0B9rh9tVI0J5mMWRkNzg0ZmEtZDdjNC00YzY5LWFlZGMtNzQ5ZmE3NDg3Mzc5/view">4096-bit memory chip</a>, for instance, to use a large, more costly 22-pin package.<span id="fnref:pins"><a class="ref" href="#fn:pins">5</a></span> Mostek cut the number of address pins in half by using each address pin twice, first for a "row" address, and then a "column" address. This approach became the industry standard, allowing memory chips to fit into inexpensive 16-pin packages.</p> <p>Externally, the chip stores a single bit for 16,384 different addresses. (Typically, eight of these chips were used in parallel to store bytes.) Internally, however, the chip is implemented as a 128×128 matrix of storage cells. The row address selects a row of 128 cells<span id="fnref:row"><a class="ref" href="#fn:row">7</a></span> and then the column address selects one of these 128 cells to read or write.<span id="fnref:efficiency"><a class="ref" href="#fn:efficiency">8</a></span> Meanwhile, the entire row of 128 cells is refreshed by amplifying the signals and storing them back in the capacitors.</p> <p><a href="https://static.righto.com/images/mk4116/die-labeled.jpg"><img alt="The 4116 die with key blocks labeled. Most of the memory cell area has been cut out." class="hilite" height="654" src="https://static.righto.com/images/mk4116/die-labeled-w600.jpg" title="The 4116 die with key blocks labeled. Most of the memory cell area has been cut out." width="600" /></a><div class="cite">The 4116 die with key blocks labeled. Most of the memory cell area has been cut out.</div></p> <p>The die image above is labeled with the main functional blocks.<span id="fnref:block"><a class="ref" href="#fn:block">9</a></span> The chip's 16 pins are labeled around the perimeter,<span id="fnref:power"><a class="ref" href="#fn:power">10</a></span> including the seven address pins (A0-A6). The Row Address Strobe pin (RAS) is used to indicate the row address is ready, while the Column Address Strobe pin (CAS) indicates that the column address is ready. The two memory arrays are in the center; I've cut out most of the cells to keep the diagram compact. The column select circuitry and sense amplifiers are between the two memory arrays. At the right, the row decode circuitry selects a row based on the address pins, while the column address circuitry buffers the address for the column select circuitry. At the left, the clock circuits generate the chip's timing pulses, triggered by the RAS, CAS, and WRITE pins. Finally, the Data Out and Data In pins provide access to the selected data bit.</p> <h2>Memory cell structure</h2> <p>The key to the DRAM chip is the memory storage cell, designed to be as compact as possible. The highly magnified photo below shows some of the storage cells, densely packed together. It's a bit hard to visualize what's going on because the chip is constructed from multiple layers. The bottom layer is the grayish silicon die. On top of the silicon are two layers of polysilicon, a special type of deposited silicon used for transistor gates, capacitors, and wiring. The top layer of the chip is the metal wiring, which was removed for this photo. The photo shows three bit lines in the silicon, with bulb-shaped storage cells connected on either side. Vertical strips of polysilicon (poly 1) over the storage cells implement capacitors: the silicon forms the lower plate, while the polysilicon forms the upper plate. The second layer of polysilicon (poly 2) is arranged in diagonal regions to implement the selection transistors, where square notches in the poly 1 layer allow the poly 2 layer to approach the silicon.</p> <p><a href="https://static.righto.com/images/mk4116/cell-diagram.jpg"><img alt="A closeup of the memory chip under the microscope, showing individual storage cells." class="hilite" height="337" src="https://static.righto.com/images/mk4116/cell-diagram-w500.jpg" title="A closeup of the memory chip under the microscope, showing individual storage cells." width="500" /></a><div class="cite">A closeup of the memory chip under the microscope, showing individual storage cells.</div></p> <p>The cross-section diagram below shows the three-dimensional, layered structure of a memory cell. At the bottom is the silicon (brown); the bit line (dark brown) is made from doped silicon. Above the silicon are the two polysilicon layers (red) and the metal layer (purple), separated by insulating silicon dioxide (gray). At the far left, the poly 1 layer and underlying silicon form a capacitor. In between the capacitor and the bit line, the poly 2 layer forms the gate of the transistor. At the left, the poly 2 layer is connected to the metal of the word line, which turns the transistor on, connecting the capacitor to the bit line.</p> <p><a href="https://static.righto.com/images/mk4116/cell-structure.jpg"><img alt="Cross-section structure of a storage cell. Based on 16K—The new generation dynamic RAM." class="hilite" height="434" src="https://static.righto.com/images/mk4116/cell-structure-w400.jpg" title="Cross-section structure of a storage cell. Based on 16K—The new generation dynamic RAM." width="400" /></a><div class="cite">Cross-section structure of a storage cell. Based on <a href="http://www.bitsavers.org/components/mostek/_dataBooks/1979_Mostek_Memory_Data_Book_and_Designers_Guide_Mar79.pdf">16K—The new generation dynamic RAM</a>.</div></p> <p>The diagram below illustrates how bits are addressed in the storage matrix. The arrangement is somewhat confusing because columns of cells are offset and interlocked like zippers. A row select line is connected to the centers of diagonal poly 2 regions, so each region controls two transistors on neighboring bit lines. (For instance, in the upper left, the poly region connected to row select 0 forms transistors 0A and 0B.) The result is that each row select line activates 128 cells, one for each bit line in a staggered arrangement.</p> <p><a href="https://static.righto.com/images/mk4116/cell-bits.jpg"><img alt="Arrangement of bits in the matrix. The transistors are labeled according to their corresponding row and bit line." class="hilite" height="288" src="https://static.righto.com/images/mk4116/cell-bits-w600.jpg" title="Arrangement of bits in the matrix. The transistors are labeled according to their corresponding row and bit line." width="600" /></a><div class="cite">Arrangement of bits in the matrix. The transistors are labeled according to their corresponding row and bit line.</div></p> <h2>Low-power circuitry</h2> <p>A key feature of the MK4116 memory chip is that it uses almost no power when it is sitting idle. Although it consumes 462 milliwatts when active, it uses just 20 milliwatts in standby mode. Although low-power circuitry is straightforward to build with modern CMOS technology, the 4116 used earlier NMOS transistors. Most NMOS integrated circuits constructed logic gates with <a href="https://en.wikipedia.org/wiki/Depletion-load_NMOS_logic">load transistors</a>, a simple technique with the disadvantage of wasting power. Instead, the MK4116 memory chip uses dynamic logic, which is considerably more complex but saves power while idle.</p> <!-- The diagram below shows the construction standard NMOS inverter. When the input is low, the transistor turns off and the load resistor pulls the output high. When the input is high, the transistor turns on and the load resistor pulls the output low. The problem with this inverter is that for a low output, there is constant current flow through the resistor, wasting power. Thus, Mostek needed to use different, low-power techniques for the circuitry. (The load resistor is actually constructed from a transistor for technical reasons.) Despite its power consumption, this circuit is used in handful of places in the 4116 chip, but only where necessary.  --> <p>A typical dynamic logic gate (below) operates in two phases. In the first phase, a clock signal turns on the upper transistor, precharging the output to +12 volts, the "1" state. The upper transistor then turns off, but the output remains high due to the capacitance of the wire. In the second phase, the lower transistors can pull the output low. In particular, if either input is 1, the corresponding transistor turns on and pulls the output low, so the circuit implements a NOR gate. This circuit doesn't consume any static power, just a small current to charge the wire capacitance when switching. (The inputs must be carefully timed so they don't overlap with the precharge clock.) <!-- Dynamic logic is widely used in the 4116 chip and is also used in modern CPUs as domino logic. --> The use of dynamic circuitry makes the 4116 much more complex than it would be otherwise since the gates are controlled by clock signals, which need to be generated.</p> <p><a href="https://static.righto.com/images/mk4116/nor.jpg"><img alt="A NOR gate using dynamic logic." class="hilite" height="181" src="https://static.righto.com/images/mk4116/nor-w200.jpg" title="A NOR gate using dynamic logic." width="200" /></a><div class="cite">A NOR gate using dynamic logic.</div></p> <!-- Another low-power technique a "CMOS-style" gate that uses one transistor to pull the output high and a second to pull the output low. Now, for a low output the upper transistor is off and there is no static current flow. (This circuit can also be used as a non-inverting buffer by switching the inputs.) This circuit has a large drawback: you need to have both non-inverted and inverted signals as inputs. In some cases, the circuitry can be designed to produce both signals, but in many cases this is a chicken-and-egg problem; you need something to invert the signal in the first case.  --> <h2>The row select circuitry</h2> <p>The purpose of the row-select circuitry is to decode the 7 address bits and energize the corresponding row select line (out of 128) to read one row of memory. In the first step, 32 5-input NOR gates decode address bits A0 through A4. These NOR gates are implemented in the compact circuit shown below. Each NOR gate takes a different combination of non-inverted and inverted address bits and matches a particular 5-bit address. These NOR gates use dynamic logic, first pulled high and then discharged to ground, except for the selected address which remains high. <!-- (Meanwhile, circuitry at the other side of the array discharges all the row select lines.) --> Next, each NOR output is split into four, based on A5 and A6. The result is that one of 128 row select lines is activated, turning on the transistors for that row in the matrix.</p> <p>The NOR gates are implemented in several compact blocks; one block of three NOR gates is shown below. Each NOR gate is a horizontal stripe of doped silicon, with ground above and below it. Each NOR gate has transistors (pink stripes) connected to ground alternating above and below it. A transistor will pull the NOR gate low if the connected address line is high. The precharge transistors at the left pull the NOR gates to +12 volts, while the output control transistors control the flow of the decoded outputs to the rest of the circuitry.</p> <p><a href="https://static.righto.com/images/mk4116/row-decoder.jpg"><img alt="Three NOR gates in the row decoder. The vertical yellow strips indicate metal wiring, removed for this photo." class="hilite" height="367" src="https://static.righto.com/images/mk4116/row-decoder-w700.jpg" title="Three NOR gates in the row decoder. The vertical yellow strips indicate metal wiring, removed for this photo." width="700" /></a><div class="cite">Three NOR gates in the row decoder. The vertical yellow strips indicate metal wiring, removed for this photo.</div></p> <p>The small greenish blobs at the end of a transistor gate (pink stripe) are connections (vias) between a transistor gate and an address line. The address lines are represented as vertical yellow stripes (since the metal layer was removed). Note that each transistor gate has an address line at the right and the inverted address line at the left; thus, the NOR gates all have the same basic layout, but with the contacts changed to match a particular address. For instance, the upper NOR gate has transistors connected to A0, A2, A1, A3, and A4, so it will be active for address 00000; any other address will pull it low.</p> <h2>The sense amplifiers</h2> <p>The sense amplifiers are one of the most challenging parts of designing a memory chip. The job of the sense amplifier is to take the tiny voltage from a capacitor and amplify it into a binary 0 or 1.<span id="fnref:voltage"><a class="ref" href="#fn:voltage">11</a></span> The challenge is that even though 12 volts is stored in a capacitor, the signal from the capacitor is very small, is only 100 millivolts or so. (Because the bit line is much larger than the tiny memory cell capacitor, the capacitor causes a very small voltage swing.)<span id="fnref:capacitance"><a class="ref" href="#fn:capacitance">12</a></span> It is critically important for the sense amplifier to operate accurately, even in the presence of noise or voltage fluctuations, because any error will corrupt the data. The sense amplifier circuit must also be compact and low power since there are 128 sense amplifiers.</p> <p><a href="https://static.righto.com/images/mk4116/die-amps-highlighted.jpg"><img alt="The 128 sense amplifiers are in the middle of the die, between the upper and lower memory arrays." class="hilite" height="270" src="https://static.righto.com/images/mk4116/die-amps-highlighted-w500.jpg" title="The 128 sense amplifiers are in the middle of the die, between the upper and lower memory arrays." width="500" /></a><div class="cite">The 128 sense amplifiers are in the middle of the die, between the upper and lower memory arrays.</div></p> <p>The chip's 128 sense amplifiers, one for each column, are located between the two memory arrays as shown above. During a read, 128 values in a row are accessed in parallel and amplified by the sense amplifiers. These 128 values are then written back to refresh the values in the capacitor. For a write operation, one of the bits is updated with the new value before they are written back.</p> <p><a href="https://static.righto.com/images/mk4116/sense-circuit.jpg"><img alt="The sense amplifier as it appears on the die, and corresponding schematic." class="hilite" height="374" src="https://static.righto.com/images/mk4116/sense-circuit-w450.jpg" title="The sense amplifier as it appears on the die, and corresponding schematic." width="450" /></a><div class="cite">The sense amplifier as it appears on the die, and corresponding schematic.</div></p> <p>Each sense amplifier (above) is a very simple circuit. It takes two inputs and compares them, pulling the lower one to 0.<span id="fnref:amplification"><a class="ref" href="#fn:amplification">13</a></span> It is built from two <a href="http://www.seas.ucla.edu/brweb/papers/Journals/BR_Magzine1.pdf">cross-coupled transistors</a>, each trying to pull the other one low. Whichever transistor has the higher voltage to start with will "win", forcing the other side low.<span id="fnref:sense-example"><a class="ref" href="#fn:sense-example">14</a></span> The sense amplifier is sensitive to very small voltage differentials, allowing it to distinguish the small signals from a storage cell.</p> <p>Locating the sense amplifiers between the two memory arrays isn't arbitrary, but the key to their operation: this is the "divided bit line" architecture introduced in 1972. The idea is that one input to the sense amp is the voltage from the desired memory cell, while the other input is a threshold voltage from a "dummy cell" in the opposite memory array. Dummy cells are constructed and precharged like real memory cells except the capacitor is half-sized, so they provide a voltage midway between a 0 bit and a 1 bit.<span id="fnref2:charge"><a class="ref" href="#fn:charge">3</a></span> If the voltage from the real memory cell is lower, the sense amp outputs a 0, and if higher, it outputs a 1.</p> <p><a href="https://static.righto.com/images/mk4116/dummy-diagram.jpg"><img alt="Dummy cells provide the threshold voltage for deciding if a bit is 0 or 1. The dummy cells are located at the top and bottom of the memory arrays. They are on the same bit lines as real memory cells." class="hilite" height="354" src="https://static.righto.com/images/mk4116/dummy-diagram-w500.jpg" title="Dummy cells provide the threshold voltage for deciding if a bit is 0 or 1. The dummy cells are located at the top and bottom of the memory arrays. They are on the same bit lines as real memory cells." width="500" /></a><div class="cite">Dummy cells provide the threshold voltage for deciding if a bit is 0 or 1. The dummy cells are located at the top and bottom of the memory arrays. They are on the same bit lines as real memory cells.</div></p> <p>The dummy cells are located on the edges of the memory arrays, as shown above. They consist of capacitors and transistors (similar to real memory cells), but with a separate line to charge them. The advantage of the dummy cell approach is that manufacturing differences or fluctuations during operation will (hopefully) affect the real cells and dummy cells equally, so the voltage from the dummy cell will remain at the correct level to distinguish beween a 0 and a 1. Address bit A0 controls which half of the array provides real data to the bit lines and which half connects dummy cells to the bit lines.</p> <h2>The column select circuitry</h2> <p>The purpose of the column select circuitry is to select one column out of the 128-bit row; this is the bit that is read or written. Each column select circuit is twice as wide as a memory cell, so they only decode one of 64 columns. The result is that two bits are selected at a time, and circuitry elsewhere selects one of the two bits. Like the row select circuitry, the column select circuitry is implemented by numerous NOR gates, each matching one address. For column select address bits A0 through A5 select one of 64 lines, selecting two columns at a time. These two bit lines are connected to data lines transmitting the signals to the I/O circuitry. (Since the bit lines for the upper and lower halves of the matrix are separate, there are actually four bit lines selected by the column select circuit.) As with the row select circuitry, dynamic logic is used, controlled by various timing signals. Note that each NOR gate is physically split into two parts with the sense amp in the middle.</p> <p>Footnote <span id="fnref:oral"><a class="ref" href="#fn:oral">15</a></span></p> <p><a href="https://static.righto.com/images/mk4116/column-decode-diagram.jpg"><img alt="Five of the column decoders, with one highlighted." class="hilite" height="508" src="https://static.righto.com/images/mk4116/column-decode-diagram-w400.jpg" title="Five of the column decoders, with one highlighted." width="400" /></a><div class="cite">Five of the column decoders, with one highlighted.</div></p> <p>The schematic below shows how the column decoder works with the sense amplifier. The diagram shows two bit lines and the top half of the column decoder and sense circuitry; it is mirrored for the lower array. At the top, the sense precharge circuit pulls all the bit lines high. At the bottom, the sense amplifiers amplify and refresh the signals as explained above. The column decoder matches a particular 6-bit address, so one of the 64 decoders will activate the associated sense select circuit, connecting the chip's I/O circuitry to four bit lines (two from the upper memory array as shown here and two from the lower memory array).</p> <p><a href="https://static.righto.com/images/mk4116/sense-decoder-schematic.jpg"><img alt="Schematic of half the column decoder and sense amplifier." class="hilite" height="818" src="https://static.righto.com/images/mk4116/sense-decoder-schematic-w500.jpg" title="Schematic of half the column decoder and sense amplifier." width="500" /></a><div class="cite">Schematic of half the column decoder and sense amplifier.</div></p> <p>At this point, four bit lines have been selected for use and their signals are passed to the input/output circuitry; the column select circuitry only decoded 1-of-64, while there are 128 columns, and each half of the array has separate bit lines. Column address bit A6 provides the final selection between the two columns. The selected bit is sent to the data-out pin for a read. For a write, the value on the data-in pin is sent back through the appropriate wire to overwrite the value in the sense amplifier. This circuitry is implemented using dynamic logic and latches, controlled by various timing signals. Much of the circuitry is duplicated, with one copy for the upper half of the memory array and one copy for the lower half. Row address bit A0 distinguishes which half of the matrix is active and which half is providing dummy data). (Note that row address bit A0 was already used to select a particular row, but the circuitry has "lost track" of which was the real row and which was the dummy row, so it must make the selection again.)</p> <h2>Clock generation</h2> <p>The chip requires many timing signals for the various steps in a memory operations. The memory chip doesn't use an external clock, unlike a CPU, but generates its own timing signals internally. The diagram below illustrates the clock generators, using buffers to create a delay between each successive clock output. The first set of timing signals is triggered by the row-access strobe (RAS), indicating that the computer has put the row address on the address pins. The next set of timing signals is triggered by the column-access strobe (CAS), indicating the column address is on the address pins. Other timing signals are triggered by the WRITE pin.</p> <p><a href="https://static.righto.com/images/mk4116/clock-diagram.jpg"><img alt="Conceptual diagram of the clock generation, from 16K—The new generation dynamic RAM." class="hilite" height="179" src="https://static.righto.com/images/mk4116/clock-diagram-w400.jpg" title="Conceptual diagram of the clock generation, from 16K—The new generation dynamic RAM." width="400" /></a><div class="cite">Conceptual diagram of the clock generation, from <a href="http://www.bitsavers.org/components/mostek/_dataBooks/1979_Mostek_Memory_Data_Book_and_Designers_Guide_Mar79.pdf">16K—The new generation dynamic RAM</a>.</div></p> <p>The real clock circuitry is much more complex than the diagram indicates, consisting of dozens of transistors in multiple chains, feeding back in complex ways to shape the pulses. (Among other things, using dynamic logic requires each buffer to have both an input that pulls it high and an input that pulls it low, forming almost a circular problem.) These gates are mostly built from large transistors, as shown below, to provide enough current to drive the circuitry, and to increase the gate delay sufficiently. The clock circuitry also uses many capacitors, probably <a href="https://www.righto.com/2020/10/how-bootstrap-load-made-historic-intel.html">bootstrap loads</a> to pull signals up sharper. I'm not going to describe the clocks in detail since it's a complicated mess.</p> <p><a href="https://static.righto.com/images/mk4116/clock-transistors.jpg"><img alt="A small part of the clock circuitry." class="hilite" height="393" src="https://static.righto.com/images/mk4116/clock-transistors-w600.jpg" title="A small part of the clock circuitry." width="600" /></a><div class="cite">A small part of the clock circuitry.</div></p> <h2>Input pins</h2> <p>The chip uses surprisingly complex circuits for the address pins and the data input pin. Mostek's earlier memory chip had problems due to noise margins on the inputs, so the MK4116 uses a complex circuit with an analog threshold, capacitor drive, and multiple controls and latches. <!-- 16K - The new generation dynamic RAM, Coker, http://www.bitsavers.org/components/mostek/_dataBooks/1979_Mostek_Memory_Data_Book_and_Designers_Guide_Mar79.pdf p255 --></p> <p>The diagram below shows the threshold generation circuit, which generates a 1.5-volt reference. It uses many tiny transistors in series to generate the voltage level. Conceptually, it is similar to a resistor divider between power and ground to produce an output voltage. However, resistors are both power-hungry and difficult to build in integrated circuits, so transistors are used instead. Since this circuit is always active, the designers needed to minimize its current; this was achieved by using many transistors in series.</p> <p><a href="https://static.righto.com/images/mk4116/voltage-ref-diagram.jpg"><img alt="The voltage reference used for the address pins. (×18 indicates 18 transistors in series, for instance.)" class="hilite" height="278" src="https://static.righto.com/images/mk4116/voltage-ref-diagram-w700.jpg" title="The voltage reference used for the address pins. (×18 indicates 18 transistors in series, for instance.)" width="700" /></a><div class="cite">The voltage reference used for the address pins. (×18 indicates 18 transistors in series, for instance.)</div></p> <p>The voltage on the input pin and the threshold voltage are fed into a differential amplifier/comparator, conceptually similar to the sense amplifiers. Each side tries to pull the other side low, ending up with a 1 for the "winning" side and 0 for the "losing" side. Thus, the input is converted into a binary value. The result from the comparator is stored in a latch. Multiple timing signals gate the input signal, precharge the circuitry, and control the latch. <!-- Each side of the comparator has large capacitors connected to help drive the latch. --></p> <p><a href="https://static.righto.com/images/mk4116/data-in.jpg"><img alt="The data-in circuitry: the pin, latch circuit, and voltage reference. This circuitry is in the lower-left corner of the die." class="hilite" height="208" src="https://static.righto.com/images/mk4116/data-in-w400.jpg" title="The data-in circuitry: the pin, latch circuit, and voltage reference. This circuitry is in the lower-left corner of the die." width="400" /></a><div class="cite">The data-in circuitry: the pin, latch circuit, and voltage reference. This circuitry is in the lower-left corner of the die.</div></p> <p>The photo above shows the input circuit for the data-in pin. Next to the pin's bond wire is the threshold circuit and latch; the two capacitors are the large rectangles of metal. The voltage reference circuit is next; the data-in voltage reference is similar to the address voltage reference described above. (I left the metal layer on for this photo; the polysilicon and silicon underneath is obscured by the oxide layer.)</p> <h2>Conclusion</h2> <p>This memory chip was much more complex than I expected. I studied a <a href="https://www.righto.com/2017/07/inside-intels-first-product-3101-ram.html">simple Intel memory chip</a> earlier so I assumed this DRAM would be larger but not much more complicated. Instead, the MK4116 has complex circuitry with over 1000 transistors controlling it, in addition to the 16,384 transistors for the memory cells and about 1500 transistors for the column selects and sense amps. A cause of the complexity is that the design needed to optimize multiple axes: density, speed, and power efficiency.<span id="fnref:2116"><a class="ref" href="#fn:2116">16</a></span></p> <!-- The clock generation circuitry in particular is complicated with long chains of transistor circuits generating the internal sequences of pulses that control the operation of the chip. The second factor that makes the chip complex is its use of low-power dynamic logic. As a result circuits are both more complicated than most chips and can't be broken down into simple gates. Even so, reverse-engineering the chip reveals its interesting construction and unusual circuits. Each bit is stored in a highly-optimized transistor/capacitor circuit, constructed from two layers of polysilicon with a compact and dense layout. --> <p>The table below shows that each generation of DRAM chips required substantial technological changes and new developments. Memory designers don't just sit around waiting for Moore's Law to increase the memory capacity; they have to constantly develop new techniques because DRAM storage cells are fundamentally analog. Fortunately, DRAM designers have continued to solve memory scaling problems; 16-gigabit DRAMs <a href="https://www.businesswire.com/news/home/20200831005214/en/Samsung-Begins-Mass-Production-of-16Gb-LPDDR5-DRAM-at-Worlds-Largest-Semiconductor-Line">recently went into production</a>, an amazing factor of a million larger than the 16-kilobit MK4116 DRAM chip of 1976.</p> <p><a href="https://static.righto.com/images/mk4116/dram-cell-evolution.jpg"><img alt="DRAM cell evolution from 4 kilobits to 16 megabits. From Impact of Processing Technology on DRAM Sense Amplifier Design (Gealow, 1990)." class="hilite" height="363" src="https://static.righto.com/images/mk4116/dram-cell-evolution-w400.jpg" title="DRAM cell evolution from 4 kilobits to 16 megabits. From Impact of Processing Technology on DRAM Sense Amplifier Design (Gealow, 1990)." width="400" /></a><div class="cite">DRAM cell evolution from 4 kilobits to 16 megabits. From <a href=https://core.ac.uk/download/pdf/4426308.pdf">Impact of Processing Technology on DRAM Sense Amplifier Design</a> (Gealow, 1990).</div></p> <p>I announce my latest blog posts on Twitter, so follow me <a href="https://twitter.com/kenshirriff">@kenshirriff</a> or my <a href="https://www.righto.com/feeds/posts/default">RSS feed</a>. Thanks to <a href="https://twitter.com/mibraden/status/1316808957739098114">Mike Braden</a> for suggesting the MK4332 chip to me.</p> <h2>Notes and references</h2> <div class="footnote"> <ol> <li id="fn:references"> <p>A brief history of memory innovations is <a href="https://ieeexplore.ieee.org/stamp/stamp.jsp?arnumber=1264036">here</a>. For detailed information on DRAM circuits, see <a href="https://core.ac.uk/download/pdf/4426308.pdf">this 1990 thesis</a> on sense amplifier design. For history, <a href="https://ieeexplore.ieee.org/document/1052889">Storage array and sense/refresh circuit for single-transistor memory cells</a> (1972) introduced the concepts of dummy cells and cross-coupled sense amplifiers. Intel's chip is discussed in <a href="https://ieeexplore.ieee.org/document/1050783">A 16 384-Bit Dynamic RAM</a> (1976) while Mostek's chip is discussed in <a href="https://ieeexplore.ieee.org/document/1155625">A 16K × 1 bit dynamic RAM</a> (1977) and <a href="http://www.bitsavers.org/components/mostek/_dataBooks/1979_Mostek_Memory_Data_Book_and_Designers_Guide_Mar79.pdf">16K - The new generation dynamic RAM</a> (1977). Inconveniently, I found most of these references after I had this blog post nearly completed. <a class="footnote-backref" href="#fnref:references" title="Jump back to footnote 1 in the text">↩</a></p> </li> <li id="fn:contacts"> <p>An unusual characteristic of the chip is that it doesn't use "buried contacts". The issue is how to connect a polysilicon wire to a silicon circuit. In integrated circuits of the 1960s, polysilicon couldn't be connected to silicon directly, so a via connected the polysilicon wire to the metal layer, which had a short connection to a second via that connected down to the silicon. In 1968 at Fairchild, Federico Faggin invented the <a href="https://sites.google.com/site/microprocessorintel4004/home/the-buried-contact">buried contact</a>, a way to connect the polysilicon and silicon directly. This was much more convenient, so all the NMOS chips that I have examined use buried contacts.</p> <p>However, the 4116 doesn't use buried contacts. Instead, it uses the obsolete connections through the metal layer. It's a mystery why they did this. Perhaps the metal wiring density was low enough that the additional segments weren't a problem and they could eliminate one masking and processing step. (Another theory is maybe there were patent issues, but I'm not aware of any patent on the buried contact.) But this illustrates that technological progress isn't consistently linear. Even an advanced chip like the 4116 can use obsolete techniques in some areas. <a class="footnote-backref" href="#fnref:contacts" title="Jump back to footnote 2 in the text">↩</a></p> </li> <li id="fn:charge"> <p>In the MK4116, a 0 bit is represented by storing 12 volts on the capacitor, while a 1 bit is represented by 0 volts on the capacitor. This is backward from what you might expect, but probably saved an inverter somewhere in the circuitry. To avoid confusion, I ignore this in the text. <a class="footnote-backref" href="#fnref:charge" title="Jump back to footnote 3 in the text">↩</a><a class="footnote-backref" href="#fnref2:charge" title="Jump back to footnote 3 in the text">↩</a></p> </li> <li id="fn:cell"> <p>Early dynamic RAMs such as the Intel 1103 used three transistors per cell and used separate lines for reading and writing data. Improvements in memory technology shrunk the circuit to a single transistor and a single data line. Static RAM, in comparison, often requires 6 transistors per bit, but has the advantage of not needing to be refreshed. <a class="footnote-backref" href="#fnref:cell" title="Jump back to footnote 4 in the text">↩</a></p> </li> <li id="fn:pins"> <p>For example, Intel's <a href="https://www.intel-vintage.info/intelmemory.htm">2107</a> 4096-bit DRAM required 22 pins, as did the 2101 256×4 static RAM chip. It's ironic that Intel used larger packages for these memory chips because a few years earlier, Intel had steadfastly refused to go beyond 16 pins, forcing the Intel 4004 microprocessor to use a 16-pin package. The 8008 microprocessor was barely allowed 18 pins, when 24 pins would have been more convenient. This made the 8008 slower and harder to use. <a class="footnote-backref" href="#fnref:pins" title="Jump back to footnote 5 in the text">↩</a></p> </li> <li id="fn:multiplex"> <p>Although multiplexing the address pins might seem trivial, Mostek claims that they <a href="https://www.cs.utexas.edu/~hunt/class/2016-spring/cs350c/documents/Robert-Proebsting.pdf">bet the company</a> <!-- p40 --> on this idea. The problem is how to implement multiplexing without making memory accesses wait while both parts of the address are loaded. (The time to read memory was a key factor in computer design, so every nanosecond counted.) In Mostek's solution, first the row address is put on the address pins, and the row-access strobe (RAS) is activated. While the chip is reading that row from memory, the computer puts the column address on the address pins and activates the column-access strobe (CAS). By the time the 128 bits of the storage row have been read, the column address is available and the desired bit is selected from the row of 128 bits. In other words, reading of the row is overlapped with loading of the column address, so multiplexing doesn't slow the system. However, careful timing is required to make this multiplexing work; much of the chip is devoted to clock circuitry to generate the necessary timing pulses. <a class="footnote-backref" href="#fnref:multiplex" title="Jump back to footnote 6 in the text">↩</a></p> </li> <li id="fn:row"> <p>The RAM chip operates on memory a row at a time, and then selects one entry from the row. This isn't the obvious way to access memory. In comparison, magnetic core memory also holds memory cells (cores) in a matrix, but accesses a single cell using X and Y select lines. A key reason for a DRAM to operate a row at a time is so the entire row can be refreshed at once, dramatically reducing the performance overhead from refresh operations. <a class="footnote-backref" href="#fnref:row" title="Jump back to footnote 7 in the text">↩</a></p> </li> <li id="fn:efficiency"> <p>You might wonder if it's possible to read multiple bits from a row without repeating the entire row-read operation. The chip designers thought of that and provided several techniques to boost efficiency. The page-read and page-write functions let you rapidly access multiple bits in a 128-bit page (i.e. row). A read-modify-write sequence lets you read a row, modify bits in it, and write it back without repeating the row-read. A RAS-only refresh operation lets you read and refresh a row without providing a column address. The point of this is that the chip designers implemented clever features so customers could squeeze as much performance out of their memory system as possible. See the datasheet for details. <a class="footnote-backref" href="#fnref:efficiency" title="Jump back to footnote 8 in the text">↩</a></p> </li> <li id="fn:block"> <p>The block diagram below shows the main functional blocks of the 4116. Many parts of this block diagram didn't make sense to me until after I had reverse-engineered the chip, such as the clock generator, dummy cells, and "1 of 2 data bus select". Many datasheets present a somewhat abstracted view of how the chip operates, but the 4116 datasheet accurately matches the implementation.</p> <p><a href="https://static.righto.com/images/mk4116/4116-block-diagram.jpg"><img alt="Block diagram of the 4116 memory chip, from the databook." class="hilite" height="459" src="https://static.righto.com/images/mk4116/4116-block-diagram-w600.jpg" title="Block diagram of the 4116 memory chip, from the databook." width="600" /></a><div class="cite">Block diagram of the 4116 memory chip, from the <a href="http://www.bitsavers.org/components/mostek/_dataBooks/1982_Mostek_Microelectronic_Data_Book.pdf">databook</a>.</div></p> <p><!-- --> <a class="footnote-backref" href="#fnref:block" title="Jump back to footnote 9 in the text">↩</a></p> </li> <li id="fn:power"> <p>One inconvenient feature of the memory chip is it requires three different voltages: +12 volts, +5 volts, and -5 volts. Almost all the circuitry runs on 12 volts. The 5-volt supply is used only to provide a standard TTL voltage level for the data out pin. The -5 volts is a substrate bias, connected to the underlying silicon die to improve the characteristics of the transistors. Later chips implemented a charge pump circuit to generate the bias voltage, eliminating the need for an external bias voltage. Later memory chips also eliminated the need for +12 volts. This simplified use of the chips, since only a single-voltage power supply was required. A less-obvious benefit is that this made two of the chip's 16 pins available for other uses. Specifically, these pins were used as additional address bits in the next two generations of memory chips, the 64-kilobit and 256-kilobit chips. As a side effect, the address pins are in a somewhat scrambled order, due to the location of the available pins. <a class="footnote-backref" href="#fnref:power" title="Jump back to footnote 10 in the text">↩</a></p> </li> <li id="fn:voltage"> <p>It's not a coincidence that the input to the sense amp is very small, just enough to be reliably amplified. This is a consequence of economics: if the DRAM produced a large voltage difference, the designers would shrink the cells to save money. But if the voltage difference was too small for reliability, the designers would need to increase the cells. The result is a design where the voltage difference is just barely large enough to be reliably amplified by advanced circuitry. (We noticed the same thing when using a vintage 1960s IBM core memory (<a href="https://www.youtube.com/watch?v=AwsInQLmjXc">video</a>); we were just barely able to read the core values. The cause is the same: if the cores had produced nice clean pulses, they were larger than they needed to be.) <a class="footnote-backref" href="#fnref:voltage" title="Jump back to footnote 11 in the text">↩</a></p> </li> <li id="fn:capacitance"> <p>When the capacitor is connected to the bit line, the resulting voltage will depend on the relative capacitances of the capacitor and the bit line. The bit line capacitance is said to be 800 fF, while the storage cell has 40 fF capacitance, for a 20:1 ratio. Thus, the resulting voltage will be very close to the +12V precharge voltage on the bit line, but perturbed a few hundred millivolts. <a class="footnote-backref" href="#fnref:capacitance" title="Jump back to footnote 12 in the text">↩</a></p> </li> <li id="fn:amplification"> <p>The sense amplifier can only pull a signal low, not raise it, so you might wonder where the amplification happens. Both sides are precharged to +12 volts and the memory cell capacitance only pulls the sides down by 100 millivolts or so. The "winning" side will remain very close to 12 volts, while the other side is pulled to 0 by the sense amp. Thus a 1 bit is pulled higher by the precharge, while a 0 bit is pulled lower by the sense amp. <a class="footnote-backref" href="#fnref:amplification" title="Jump back to footnote 13 in the text">↩</a></p> </li> <li id="fn:sense-example"> <p>The diagram below shows the sense amplifier voltages during operation of a prototype DRAM sense amp. First, the two sides of the sense amp are precharged to the same voltage. Next, a DRAM storage node is selected on one side and a dummy node on the other. Note that the voltage difference between the two sides is very small, maybe 200 millivolts. Finally, the difference is amplified, forcing the higher side up and the lower side down. In this case, the storage node held a 1 so it started slightly higher. If it held a 0, it would start slightly lower and the two lines would diverge in opposite directions. The point is that the sense amp takes a very small voltage differential and amplifies it into a large binary signal.</p> <p><a href="https://static.righto.com/images/mk4116/stein-voltage-diagram.jpg"><img alt="Voltage diagram for a prototype sense amp (not the 4116). Based on Storage Array and Sense/Refresh Circuit for Single-Transistor Memory Cells, 1972." class="hilite" height="340" src="https://static.righto.com/images/mk4116/stein-voltage-diagram-w500.jpg" title="Voltage diagram for a prototype sense amp (not the 4116). Based on Storage Array and Sense/Refresh Circuit for Single-Transistor Memory Cells, 1972." width="500" /></a><div class="cite">Voltage diagram for a prototype sense amp (not the 4116). Based on <a href="https://ieeexplore.ieee.org/document/1052889">Storage Array and Sense/Refresh Circuit for Single-Transistor Memory Cells</a>, 1972.</div></p> <p>One difference between this sense amp and the MK4116 is that this circuit is precharged to a midpoint voltage, while the MK4116's is precharged to +12 volts. In this sense amp, one signal must be pulled high, while in the MK4116 both signals start near +12V and one is forced low. <!-- --> <a class="footnote-backref" href="#fnref:sense-example" title="Jump back to footnote 14 in the text">↩</a></p> </li> <li id="fn:oral"> <p><a href="https://www.ithistory.org/honor-roll/dr-robert-bob-proebsting">Robert Proebsting</a>, co-founder of Mostek and developer of address multiplexing, has an <a href="https://www.cs.utexas.edu/~hunt/class/2016-spring/cs350c/documents/Robert-Proebsting.pdf">oral history</a> that provide some information on the 4116. He discusses why the column decoder selects one of 64 columns and the selection between the pair happens earlier. The reason is they wanted the noise from the address lines to be equal on both sides of the sense amp, so they have three address line pairs on each side. <!-- p48 --> <a class="footnote-backref" href="#fnref:oral" title="Jump back to footnote 15 in the text">↩</a></p> </li> <li id="fn:2116"> <p>Intel produced <a href="https://www.semanticscholar.org/paper/A-16-384-bit-dynamic-RAM-Ahlquist-Breivogel/2623f1732a39119a6d5825bc4eaa9f39d770cc47">16,384-bit DRAM chips</a> before Mostek, the <a href="https://www.intel-vintage.info/intelmemory.htm">2116</a> and others, but Mostek's chips <a href="http://smithsonianchips.si.edu/augarten/p50.htm">beat Intel in the marketplace</a>. Interestingly, the internal structure was completely different from the MK4116. The 2116 contained four memory arrays internally and was structured as two independent 8-kilobit memories. This saved on power since the unused half could be left unpowered during a memory access. Moreover, if a 2116 chip had a manufacturing flaw in one half, Intel repackaged it as an 8-kilobit <a href="https://drive.google.com/file/d/0B9rh9tVI0J5mMWM4MGNiMTQtZTk3Mi00YWJmLWI5NjAtMGU1NmUyMzhlM2Yz/view">2108</a> chip with either the upper or lower half operational. The user had to set address bit A6 appropriately to get the working half. <a class="footnote-backref" href="#fnref:2116" title="Jump back to footnote 16 in the text">↩</a></p> </li> </ol> </div> <div style='clear: both;'></div> </div> <div class='post-footer'> <div class='post-footer-line post-footer-line-1'><span class='post-comment-link'> <a class='comment-link' href='https://www.blogger.com/comment/fullpage/post/6264947694886887540/9178320223286625683' onclick=''> 16 comments: </a> </span> <span class='post-icons'> <span class='item-action'> <a href='https://www.blogger.com/email-post/6264947694886887540/9178320223286625683' title='Email Post'> <img alt='' class='icon-action' height='13' src='http://img1.blogblog.com/img/icon18_email.gif' width='18'/> </a> </span> <span class='item-control blog-admin pid-1138732533'> <a href='https://www.blogger.com/post-edit.g?blogID=6264947694886887540&postID=9178320223286625683&from=pencil' title='Edit Post'> <img alt='' class='icon-action' height='18' src='https://resources.blogblog.com/img/icon18_edit_allbkg.gif' width='18'/> </a> </span> </span> <span class='post-backlinks post-comment-link'> </span> <div class='post-share-buttons goog-inline-block'> <a class='goog-inline-block share-button sb-email' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=9178320223286625683&target=email' target='_blank' title='Email This'><span class='share-button-link-text'>Email This</span></a><a class='goog-inline-block share-button sb-blog' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=9178320223286625683&target=blog' onclick='window.open(this.href, "_blank", "height=270,width=475"); return false;' target='_blank' title='BlogThis!'><span class='share-button-link-text'>BlogThis!</span></a><a class='goog-inline-block share-button sb-twitter' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=9178320223286625683&target=twitter' target='_blank' title='Share to X'><span class='share-button-link-text'>Share to X</span></a><a class='goog-inline-block share-button sb-facebook' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=9178320223286625683&target=facebook' onclick='window.open(this.href, "_blank", "height=430,width=640"); return false;' target='_blank' title='Share to Facebook'><span class='share-button-link-text'>Share to Facebook</span></a><a class='goog-inline-block share-button sb-pinterest' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=9178320223286625683&target=pinterest' target='_blank' title='Share to Pinterest'><span class='share-button-link-text'>Share to Pinterest</span></a> </div> </div> <div class='post-footer-line post-footer-line-2'><span class='post-labels'> Labels: <a href='http://www.righto.com/search/label/chips' rel='tag'>chips</a>, <a href='http://www.righto.com/search/label/electronics' rel='tag'>electronics</a>, <a href='http://www.righto.com/search/label/reverse-engineering' rel='tag'>reverse-engineering</a> </span> </div> <div class='post-footer-line post-footer-line-3'></div> </div> </div> </div> </div></div> <div class="date-outer"> <div class="date-posts"> <div class='post-outer'> <div class='post hentry' itemprop='blogPost' itemscope='itemscope' itemtype='http://schema.org/BlogPosting'> <meta content='https://static.righto.com/images/8008-carry/die-labeled-w800.jpg' itemprop='image_url'/> <meta content='6264947694886887540' itemprop='blogId'/> <meta content='7957020708059918311' itemprop='postId'/> <a name='7957020708059918311'></a> <h3 class='post-title entry-title' itemprop='name'> <a href='http://www.righto.com/2020/11/reverse-engineering-carry-lookahead.html'>Reverse-engineering the carry-lookahead circuit in the Intel 8008 processor</a> </h3> <div class='post-header'> <div class='post-header-line-1'></div> </div> <div class='post-body entry-content' id='post-body-7957020708059918311' itemprop='description articleBody'> <style> .hilite {cursor:zoom-in} a:link img.hilite, a:visited img.hilite { color: #fff;} </style> The 8008 was Intel's first 8-bit microprocessor, introduced in 1972. While primitive by today's standards, the 8008 is historically important because it essentially started the <a href="https://spectrum.ieee.org/tech-history/silicon-revolution/the-surprising-story-of-the-first-microprocessors">microprocessor revolution</a> and is the ancestor of the modern x86 processor family. I've been studying the 8008's silicon die under the microscope and reverse-engineering its circuitry.</p> <p>The die photo below shows the main functional blocks<span id="fnref:functional"><a class="ref" href="#fn:functional">1</a></span> including the registers, instruction decoder, and <a href="http://www.righto.com/2017/03/analyzing-vintage-8008-processor-from.html">on-chip stack storage</a>. The 8-bit arithmetic logic unit (ALU) is on the left. Above the ALU is the carry-lookahead generator, which improves performance by computing the carries for addition, before the addition takes place. It's a bit surprising to see carry lookahead implemented in such an early microprocessor. This blog post explains how the carry circuit is implemented.</p> <p><a href="https://static.righto.com/images/8008-carry/die-labeled.jpg"><img alt="The Intel 8008 die with key functional blocks labeled. Click for a larger version." class="hilite" height="483" src="https://static.righto.com/images/8008-carry/die-labeled-w800.jpg" title="The Intel 8008 die with key functional blocks labeled. Click for a larger version." width="800" /></a><div class="cite">The Intel 8008 die with key functional blocks labeled. Click for a larger version.</div></p> <p>Most of what you see in the die photo is the greenish-white wiring of the metal layer on top. Underneath the metal is polysilicon wiring, providing more connections as well as implementing transistors. The chip contains about 3500 tiny transistors, which appear as brighter yellow. The underlying silicon substrate is mostly obscured; it is purplish-gray. Around the edges of the die are 18 rectangular pads; these are connected by tiny bond wires to the external pins of the integrated circuit package (below).</p> <p><a href="https://static.righto.com/images/8008-carry/8008-chip.jpg"><img alt="An 8008 integrated circuit in an 18-pin DIP (dual inline package). The package is very scratched, but I didn't see the point in paying for mint condition for a chip I was immediately going to decap." class="hilite" height="281" src="https://static.righto.com/images/8008-carry/8008-chip-w500.jpg" title="An 8008 integrated circuit in an 18-pin DIP (dual inline package). The package is very scratched, but I didn't see the point in paying for mint condition for a chip I was immediately going to decap." width="500" /></a><div class="cite">An 8008 integrated circuit in an 18-pin DIP (dual inline package). The package is very scratched, but I didn't see the point in paying for mint condition for a chip I was immediately going to decap.</div></p> <p>The 8008 was sold as a small 18-pin DIP (dual inline package) integrated circuit. 18 pins is an inconveniently small number of pins for a microprocessor, but Intel was committed to small packages at the time.<span id="fnref:18pins"><a class="ref" href="#fn:18pins">2</a></span> In comparison, other early microprocessors typically used 40 pins, making it much easier to connect the data bus, address bus, control signals, and power to the processor.</p> <h2>Addition</h2> <p>The heart of a processor is the arithmetic-logic unit (ALU), the functional block that performs arithmetic operations (such as addition or subtraction) and logical operations (such as AND, OR, and XOR). Addition was the most challenging operation to implement efficiently because of the need for carries.<span id="fnref:addition"><a class="ref" href="#fn:addition">3</a></span></p> <p>Consider how you add two decimal numbers such as 8888 and 1114, with long addition. Starting at the right, you add each pair of digits (8 and 4), write down the sum (2), and pass any carry (1) along to the left. In the next column, you add the pair of digits (8 and 1) along with the carry (1), writing down the sum (0) and passing the carry (1) to the next column. You repeat the process right-to-left, ending up with the result 10002. Note that you have to add each position before you can compute the next position.</p> <p>Binary numbers can be added in a similar way with a circuit called a <a href="https://en.wikipedia.org/wiki/Adder_(electronics)#Ripple-carry_adder">ripple-carry adder</a> that was used in many early microprocessors. Each bit is computed by a <a href="https://en.wikipedia.org/wiki/Adder_(electronics)#Full_adder">full adder</a>, which takes two input bits and a carry and produces the sum bit and a carry-out. For instance, adding binary 1 + 1 with no carry-in yields 10, for a sum bit of 0 and a carry-out of 1. Each carry-out is added to the bit position to the left, just like decimal long addition.</p> <p>The problem with ripple carry is if you add, say, 11111111 + 1, you need to wait as the carry "ripples" through the sum from right to left. This makes addition a slow serial operation instead of a parallel operation. Even though the 8008 only performs addition on 8-bit numbers, this delay would slow the processor too much. The solution was a <a href="https://en.wikipedia.org/wiki/Carry-lookahead_adder">carry lookahead</a> circuit that rapidly computes the carries for all eight bit positions. Then the sum can be calculated in parallel without waiting for carries to ripple through the bits. According to 8008 designer <a href="http://archive.computerhistory.org/resources/text/Oral_History/Feeney_Hal/102658338.05.01.pdf">Hal Feeney</a>, "We built the carry look-ahead logic because we needed the speed as far as the processor is concerned. So carry look ahead seemed like something we could integrate and have fairly low real estate overhead and, as you see, the whole carry look ahead is just a very small portion of the chip." <!-- p39 --></p> <h2>Implementing carry lookahead</h2> <p>The idea of carry lookahead is that if you can compute all the carry values in advance, then you can rapidly add all the bit positions in parallel. But how can you compute the carries without performing the addition? The solution in the 8008 was to build a separate circuit for each bit position to compute the carry based on the inputs.</p> <p>The diagram below zooms in on the carry lookahead circuitry and the arithmetic-logic unit (ALU). The two 8-bit arguments and a carry-in arrive at the top. These values flow vertically through the carry lookahead circuit, generating carry values for each bit along the way. Each ALU block receives two input bits and a carry bit and produces one output bit. The carry lookahead has a triangular layout because successive carry bits require more circuitry, as will be explained. The 8-bit ALU has an unusual layout in order to make the most of the triangular space. Almost all microprocessors arrange the ALU in a rectangular block; an 8-bit ALU would have 8 similar slices. But in the 8008, the slices of the ALU are scattered irregularly; some slices are even rotated sideways. I've written about the <a href="http://www.righto.com/2017/02/reverse-engineering-surprisingly.html">8008's ALU</a> before if you want more details.</p> <p><a href="https://static.righto.com/images/8008-carry/die-carry-alu.jpg"><img alt="Closeup of the 8008 die showing the carry lookahead circuitry and the ALU." class="hilite" height="606" src="https://static.righto.com/images/8008-carry/die-carry-alu-w600.jpg" title="Closeup of the 8008 die showing the carry lookahead circuitry and the ALU." width="600" /></a><div class="cite">Closeup of the 8008 die showing the carry lookahead circuitry and the ALU.</div></p> <p>To understand how carry lookahead works, consider three addition cases. First, adding 0+0 cannot generate a carry, even if there is a carry in; the sum is 0 (if there is no carry in) or 1 (with carry in). The second case is 0+1 or 1+0. In this case, there will be a carry out only if there is a carry in. (With no carry-in the result is 1, while with carry-in the result is 10.) This is the "propagate" case, since the carry-in is propagated to carry-out. The final case is 1+1. In this case, there will be a carry-out, regardless of the carry-in. This is the "generate" case, since a new carry is generated.</p> <p>The circuit below computes the carry-out when adding two bits (X and Y) along with a carry-in. This circuit is built from an OR gate on the left, two AND gates in the middle, and an OR gate on the right. (Although this circuit looks complex, it can be implemented efficiently in hardware.) To see how it operates, consider the three cases. If X and Y are both 0, the carry output will be 0. Otherwise, the first OR gate will output 1. If carry-in is 1, the upper AND gate will output 1 and the carry-out will be 1. (This is the propagate case.) Finally, if both X and Y are 1, the lower AND gate will output 1, and the carry-out will be 1. (This is the generate case.)</p> <p><a href="https://static.righto.com/images/8008-carry/carry-gate.jpg"><img alt="This circuit computes the carry-out given the carry-in and two input bits X and Y." class="hilite" height="180" src="https://static.righto.com/images/8008-carry/carry-gate-w350.jpg" title="This circuit computes the carry-out given the carry-in and two input bits X and Y." width="350" /></a><div class="cite">This circuit computes the carry-out given the carry-in and two input bits X and Y.</div></p> <p>To compute the carry into a higher-order position, multiple instances of this circuit can be chained together. For instance, the circuit below computes the carry into bit position 2 (C<sub>2</sub>). The gate block on the left computes C<sub>1</sub>, the carry into bit position 1, from the carry-in (C<sub>0</sub>) and low-order bits X<sub>0</sub> and Y<sub>0</sub>, as explained above. The gates on the right apply the same process to the next bits, generating the carry into position 2. For other bit positions, the same principle is used but with additional blocks of gates. For instance, the carry into position 7 is computed by a chain of seven blocks of gates. Since the circuit for each successive bit is one unit longer, the carry structure has the triangular structure seen on the die.</p> <p><a href="https://static.righto.com/images/8008-carry/carry-gates.jpg"><img alt="Computing the carry into position 2 requires two stages of carry prediction." class="hilite" height="182" src="https://static.righto.com/images/8008-carry/carry-gates-w600.jpg" title="Computing the carry into position 2 requires two stages of carry prediction." width="600" /></a><div class="cite">Computing the carry into position 2 requires two stages of carry prediction.</div></p> <p>The diagram below shows how the carry circuit for bit 2 is implemented on the die; the circuit for other bits is similar, but with more repeated blocks. In the photograph, the metal wiring on top of the die is silverish. Underneath this, the polysilicon wiring is yellow. At the bottom, the silicon is grayish. The transistors are brighter yellow; several are indicated. The schematic underneath shows the wiring of the transistors; the layout of the schematic is close to the physical layout.</p> <p><a href="https://static.righto.com/images/8008-carry/carry-die-diagram.jpg"><img alt="Implementation of the carry lookahead circuit for bit 2." class="hilite" height="518" src="https://static.righto.com/images/8008-carry/carry-die-diagram-w600.jpg" title="Implementation of the carry lookahead circuit for bit 2." width="600" /></a><div class="cite">Implementation of the carry lookahead circuit for bit 2.</div></p> <p>I'll give a brief outline of how the circuit works. The 8008 is implemented with a type of transistor called a PMOS transistor. You can think of a PMOS transistor as turning on if the input is 0, and off if the input is 1.<span id="fnref:pmos"><a class="ref" href="#fn:pmos">4</a></span> Instead of standard logic gates, this circuit uses a technique called <a href="https://en.wikipedia.org/wiki/Dynamic_logic_(digital_electronics)">dynamic logic</a>, which takes advantage of capacitance. In the first step, the precharge signal connects -9 volts to the circuitry, precharging it. In the second step, the input signals (top) are applied, turning on various transistors. If there is a path through the transistors from the +5 supply to the output, the output will be pulled high. Otherwise, the output remains at the precharge level; the capacitance of the wires holds the -9 volts. <!-- (Precharge logic has seen a resurgence in modern processors as <a href="https://en.wikipedia.org/wiki/Domino_logic">domino logic</a>.) --> I won't trace out the entire circuit, but the upper X/Y transistor pairs implement an OR gate since if either one is on, the carry can get through. The lower X/Y transistors implement an AND gate; if both are on, the +5 signal will get through, generating a 1.</p> <p>You might wonder why this carry lookahead circuit is any faster than a plain ripple-carry adder, since the carry signal has to go through up to seven large gates to generate the last carry bit. The trick is that the entire circuit is electrically a single large gate due to the dynamic design. All the transistors are activated in parallel, and then the 5-volt signal can pass through them all rapidly.<span id="fnref:timing"><a class="ref" href="#fn:timing">5</a></span> Although there is still a delay as this signal travels through the circuit, the circuit is faster than the standard ripple carry adder which activates transistors in sequence.</p> <!-- This circuit is implemented using a technique called [dynamic logic](https://en.wikipedia.org/wiki/Dynamic_logic_(digital_electronics)), which takes advantage of the circuit's capacitance to hold a value over a clock signal, unlike standard logic gates. In dynamic logic, the gates are first precharged (to -9V). In the next clock phase, the logic is evaluated by activating the transistors in the gates, which can pull values to +5V. Thus, instead of a regular "static" gate that has a pull-up resistor, dynamic logic uses two clock phases and capacitance. --> <h2>A brief history of carry circuits</h2> <p>The efficient handling of carries was an issue back to the earliest days of mechanical calculation. The mathematician Blaise Pascal created a <a href="https://en.wikipedia.org/wiki/Pascal%27s_calculator#Inner_mechanism">mechanical calculator</a> in 1645. This calculator used a mechanical ripple carry mechanism powered by gravity that rapidly propagated the carry from one digit to the next (<a href="https://youtu.be/3h71HAJWnVU?t=383">video</a>). <!-- The carry mechanism was powered by gravity. As a wheel advanced from 5 to 9, it lifted up an arm. When the wheel moved from 9 to 0, the arm was released, swinging down and advancing the next digit wheel one position. If that triggered another carry, the next arm fell down and advanced the next wheel. In this way, a carry propagated rapidly but sequentially through the digits. --> Almost two centuries later, Charles Babbage designed the famous <a href="https://en.wikipedia.org/wiki/Difference_engine">difference engine</a> (1819-1842). It used a slow ripple carry; after the addition cycle, spiral levers on a rotating shaft activated each digit's carry in sequence. Babbage spent years designing a better carry mechanism for his ambitious Analytical Engine (1837), developing an "anticipating carriage" to perform all carries in parallel. With the anticipating carriage, each digit wheel had a sliding shaft that moved into position when a digit was 9. When a digit triggered a carry by moving from 9 to 0, it raised the stack of shafts, incrementing all the appropriate digits in parallel (see <a href="https://www.youtube.com/watch?v=B2EDE8Srdcw">video</a>).</p> <p><a href="https://static.righto.com/images/8008-carry/babbage.jpg"><img alt="Detail of Babbage's diagram of the "anticipating carriage" that computes carries in the Analytical Engine. I'm not sure how this mechanism works. From The Babbage Papers at the Science Museum, London, CC BY-NC-SA 4.0." class="hilite" height="382" src="https://static.righto.com/images/8008-carry/babbage-w600.jpg" title="Detail of Babbage's diagram of the "anticipating carriage" that computes carries in the Analytical Engine. I'm not sure how this mechanism works. From The Babbage Papers at the Science Museum, London, CC BY-NC-SA 4.0." width="600" /></a><div class="cite">Detail of Babbage's diagram of the "anticipating carriage" that computes carries in the Analytical Engine. I'm not sure how this mechanism works. From <a href="https://collection.sciencemuseumgroup.org.uk/documents/aa110000451">The Babbage Papers at the Science Museum, London</a>, <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>.</div></p> <p>The first digital computers used ripple carry. The designer of the <a href="http://archive.computerhistory.org/resources/text/Knuth_Don_X4100/PDF_index/k-8-pdf/k-8-r5251-Relay-Bell-Labs.pdf">Bell Labs relay computer</a> (1939) states that "the carry circuit was complicated" due to the use of binary-coded decimal (BCD). The groundbreaking <a href="http://archive.computerhistory.org/resources/text/Knuth_Don_X4100/PDF_index/k-8-pdf/k-8-r5367-1-ENIAC-circuits.pdf">ENIAC</a> (1946) used decimal counters with ripple carry. Early binary electronic computers such as EDSAC (1949) and SEAC (1950) were serial, operating on one bit at a time, so they computed carries one bit at a time too. Early computers with parallel addition such as the 1950 SWAC (the fastest computer at the time) and the commercial IBM 701 (1952) used ripple carry. <!-- Proceedings of the IRE --></p> <p>As computers became faster in the 1950s, ripple carry limited performance so alternatives were developed. In 1956, the National Bureau of Standards <a href="https://patents.google.com/patent/US2879001A">patented</a> a 53-bit adder using vacuum tubes. This design introduced the important carry-lookahead concept, as well as the idea of using a hierarchy of carry lookahead (two levels in this case). The diagram below illustrates the complexity of this adder. <!-- X and Y are Generate and Propagate over four bits. Z is second-level generate over 16 bits, W is second-level propagate. --></p> <p><a href="https://static.righto.com/images/8008-carry/53-bit-adder.jpg"><img alt="Diagram of a 53-bit adder from A 1-microsecond adder using one-megacycle circuitry, 1956." class="hilite" height="306" src="https://static.righto.com/images/8008-carry/53-bit-adder-w750.jpg" title="Diagram of a 53-bit adder from A 1-microsecond adder using one-megacycle circuitry, 1956." width="750" /></a><div class="cite">Diagram of a 53-bit adder from <a href="https://ieeexplore.ieee.org/document/5219801">A 1-microsecond adder using one-megacycle circuitry</a>, 1956.</div></p> <p>The development of supercomputers led to new carry techniques. The transistorized <a href="https://en.wikipedia.org/wiki/Atlas_(computer)">Atlas</a> was built by the University of Manchester, Ferranti and Plessey in 1962. It used the influential Manchester carry chain technique, <a href="http://www.acsel-lab.com/Projects/fast_adder/references/papers/Kilburn-1959.pdf">described</a> in 1959. The Atlas vied with the <a href="http://www.textfiles.com/bitsavers/pdf/ibm/7030/Bloch_EngrDesOfStretch_1959.pdf">IBM Stretch</a> (1961) for the title of the world's fastest computer. The Stretch introduced <a href="https://www.ece.ucdavis.edu/~bbaas/281/papers/MacSorley.1961.pdf">high-speed techniques</a> including the <a href="https://ieeexplore.ieee.org/document/5407919">carry-select adder</a> and the <a href="https://patents.google.com/patent/US3253131">patented</a> <a href="https://en.wikipedia.org/wiki/Carry-save_adder">carry save</a> adder for multiplication.</p> <!-- The transistorized [IBM 7090](https://en.wikipedia.org/wiki/IBM_7090) used carry lookahead adders for its 36-bit words. --> <!-- In a [carry-select adder](https://en.wikipedia.org/wiki/Carry-select_adder), sub-blocks of, say, 5 bits are added twice, once with a carry-in and once without. Multiplexers then select the proper sums once the carries are determined. Stretch also used [patented](https://patents.google.com/patent/US3253131) [carry save](https://en.wikipedia.org/wiki/Carry-save_adder) adders for multiplication operations; a carry-save adder is optimized for a sequence of additions, as happens during multiplication. --> <!-- [High-speed arithmetic in binary computers](https://www.ece.ucdavis.edu/~bbaas/281/papers/MacSorley.1961.pdf) T (transmit) = propagate, D = generate, R = carry. uses generated, propagated --> <p>As with mainframes, microprocessors started with simple adders but required improved carry techniques as performance demands increased. Most early microprocessors used ripple carry, such as the 6502, <a href="http://www.righto.com/2013/09/the-z-80-has-4-bit-alu-heres-how-it.html">Z-80</a>, and <a href="https://daveshacks.blogspot.com/2015/12/inside-alu-of-armv1-first-arm.html">ARM1</a>. Carry-skip was often used for the program counter (as in the 6502 and Z-80); ripple carry was fast enough for 8-bit words but too slow for the 16-bit program counter. The ALU of the Intel <a href="http://www.righto.com/2020/08/reverse-engineering-8086s.html">8086</a> (1978) used a Manchester carry chain as well as carry skip. The large transistor counts of VLSI chips permitted more complex adders, fed by research in parallel-prefix adders. The DEC Alpha <a href="https://en.wikipedia.org/wiki/Alpha_21064">21064</a> (1992) combined multiple techniques: Manchester carry chain, carry lookahead, conditional sum, and carry select (<a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.94.1038&rep=rep1&type=pdf">details</a>). <!-- https://web.stanford.edu/class/archive/ee/ee371/ee371.1066/lectures/Old/lect_05_adder.pdf p13 --> The Hewlett-Packard <a href="https://en.wikipedia.org/wiki/PA-8000">PA_8000</a> (1995) contained over 20 adders for various purposes, including a <a href="https://en.wikipedia.org/wiki/Ling_adder">Ling adder</a>, a type developed at IBM in <a href="http://lap.epfl.ch/courses/comparith/Papers/Ling_adder-1966.pdf">1966</a> (<a href="https://web.stanford.edu/class/archive/ee/ee371/ee371.1066/handouts/adderSlides.pdf">details</a>). The Pentium II (1997) used a 72-bit <a href="https://en.wikipedia.org/wiki/Kogge%E2%80%93Stone_adder">Kogge-Stone</a> adder while the Pentium 4 (2000) used a Han-Carlson adder.<span id="fnref:notes"><a class="ref" href="#fn:notes">6</a></span></p> <!-- Adder design became an active research area with new designs such as Kogge-Stone adder (1973). Brent-Kung adder (1982), Ling adder (1966). In 1980, parallel-prefix adders were introduced by Ladner and Fischer, developing into the Brent-Kung adder (1982), PA8000 has over 20 adders, see slides. --> <p>This history shows that carry propagation was an important performance problem in the 1950s and remains an issue today with continuing research and improvements. Many different solutions have been developed, first in mainframes and later in microprocessors, growing more complex as technology advances. These approaches have tradeoffs of die area, cost, and speed, so different processors choose different implementations.</p> <p><a href="https://static.righto.com/images/8008-carry/die.jpg"><img alt="Die photo of the Intel 8008 processor. Click for a larger version." class="hilite" height="500" src="https://static.righto.com/images/8008-carry/die-w700.jpg" title="Die photo of the Intel 8008 processor. Click for a larger version." width="700" /></a><div class="cite">Die photo of the Intel 8008 processor. Click for a larger version.</div></p> <p>If you're interested in the 8008, I have other articles about it describing <a href="http://www.righto.com/2016/12/die-photos-and-analysis-of_24.html">its architecture</a>, <a href="http://www.righto.com/2017/02/reverse-engineering-surprisingly.html">its ALU</a>, <a href="http://www.righto.com/2017/03/analyzing-vintage-8008-processor-from.html">its on-chip stack</a>, <a href="http://www.righto.com/2020/10/how-bootstrap-load-made-historic-intel.html">bootstrap loads</a>, and its <a href="http://www.righto.com/2015/05/the-texas-instruments-tmx-1795-first.html">unusual history</a>. I announce my latest blog posts on Twitter, so follow me at <a href="https://twitter.com/kenshirriff">@kenshirriff</a>. I also have an <a href="http://www.righto.com/feeds/posts/default">RSS feed</a>.</p> <h2>Notes and references</h2> <div class="footnote"> <ol> <li id="fn:functional"> <p>The functional blocks of the 8008 processor are documented in the datasheet (below). The layout of this diagram closely matches the physical layout on the die. I've highlighted the carry lookahead block.</p> <p><a href="https://static.righto.com/images/8008-carry/functional-blocks.jpg"><img alt="Functional blocks of the 8008 processor. From the 8008 datasheet." class="hilite" height="460" src="https://static.righto.com/images/8008-carry/functional-blocks-w700.jpg" title="Functional blocks of the 8008 processor. From the 8008 datasheet." width="700" /></a><div class="cite">Functional blocks of the 8008 processor. From the <a href="http://www.classiccmp.org/8008/8008UM.pdf">8008 datasheet</a>.</div></p> <p><!-- --> <a class="footnote-backref" href="#fnref:functional" title="Jump back to footnote 1 in the text">↩</a></p> </li> <li id="fn:18pins"> <p>According to <a href="http://archive.computerhistory.org/resources/text/Oral_History/Faggin_Federico/Faggin_Federico_1_2_3.oral_history.2004.102658025.pdf">Federico Faggin's oral history</a>, the 8008 team was lucky to be allowed to even use an 18-pin package for the 8008. "It was a religion in Intel" to use 16-pin packages, even though other manufacturers commonly used 40- or 48-pin packages. When Intel was forced to move to 18-pin packages for the 1103 RAM chip, it "was like the sky had dropped from heaven. I never seen so [many] long faces at Intel". The move to 18 pins was beneficial for the 8008 team, which had been forced to use 16 pins for the earlier 4004. However, even 18 pins was impractically small considering the chip used 14-bit addresses. The result was address and data signals were multiplexed over 8 data pins. This both slowed the processor and made use of the chip more complicated. Intel soon gave up on small packages, using a standard 40-pin package for the 8080 processor in 1974. <a class="footnote-backref" href="#fnref:18pins" title="Jump back to footnote 2 in the text">↩</a></p> </li> <li id="fn:addition"> <p>I'm ignoring subtraction in this discussion because it was implemented by addition, adding a two's complement value. Multiplication and division were not implemented by early microprocessors. Interestingly, even the earliest mainframe computers implemented multiplication and division in hardware. <a class="footnote-backref" href="#fnref:addition" title="Jump back to footnote 3 in the text">↩</a></p> </li> <li id="fn:pmos"> <p>Most of the "classic" microprocessors were implemented with NMOS transistors. If you're familiar with NMOS gates, everything is backward with PMOS. Although PMOS has worse performance than NMOS, it was easier to manufacture at first, so the Intel 4004 and 8008 used PMOS. PMOS required fairly large negative voltages, which is why the diagram shows -9 volts and +5 volts. <a class="footnote-backref" href="#fnref:pmos" title="Jump back to footnote 4 in the text">↩</a></p> </li> <li id="fn:timing"> <p>I'm hand-waving over the timing of the carry lookahead circuit. An accurate analysis of the timing would require considering the capacitance of each stage, which might add an O(n<sup>2</sup>) term.</p> <p>Also note that this carry lookahead circuit is a bit unusual. A typical carry lookahead circuit (as in the <a href="http://www.righto.com/2017/01/die-photos-and-reverse-engineering.html">74181 ALU chip</a>) expands out the gates, yielding much larger but flatter circuits to minimize propagation delays. On the other hand, the 8008's circuit has a lot in common with a <a href="https://en.wikipedia.org/wiki/Carry-lookahead_adder#Manchester_carry_chain">Manchester carry chain</a>, which uses a similar technique of passing the incoming carry through a chain of pass transistors, or potentially generating a carry at each stage. A Manchester carry chain, however, uses a single N-stage chain rather than the 8008's triangle of separate chains for each bit. A Manchester carry chain can tap each bit's carry from each stage of the chain, so only one chain is required. The 8008's carry circuit, however, lacks the transistors that block a carry from propagating backwards, so its intermediate values may not be valid.</p> <p>In any case, the 8008's carry lookahead circuit was sufficiently fast for Intel's needs. <a class="footnote-backref" href="#fnref:timing" title="Jump back to footnote 5 in the text">↩</a></p> </li> <li id="fn:notes"> <p>For more information on various adders, see <a href="https://pdfs.semanticscholar.org/9da8/de2627aa0d4669995c430210c6ea9844ddf1.pdf">this presentation</a>, <a href="https://web.stanford.edu/class/archive/ee/ee371/ee371.1066/lectures/lect_04.2up.pdf">another presentation</a> and <a href="http://www.quadibloc.com/comp/cp0202.htm">Advanced Arithmetic Techniques</a>. <a class="footnote-backref" href="#fnref:notes" title="Jump back to footnote 6 in the text">↩</a></p> </li> </ol> </div> <div style='clear: both;'></div> </div> <div class='post-footer'> <div class='post-footer-line post-footer-line-1'><span class='post-comment-link'> <a class='comment-link' href='https://www.blogger.com/comment/fullpage/post/6264947694886887540/7957020708059918311' onclick=''> 10 comments: </a> </span> <span class='post-icons'> <span class='item-action'> <a href='https://www.blogger.com/email-post/6264947694886887540/7957020708059918311' title='Email Post'> <img alt='' class='icon-action' height='13' src='http://img1.blogblog.com/img/icon18_email.gif' width='18'/> </a> </span> <span class='item-control blog-admin pid-1138732533'> <a href='https://www.blogger.com/post-edit.g?blogID=6264947694886887540&postID=7957020708059918311&from=pencil' title='Edit Post'> <img alt='' class='icon-action' height='18' src='https://resources.blogblog.com/img/icon18_edit_allbkg.gif' width='18'/> </a> </span> </span> <span class='post-backlinks post-comment-link'> </span> <div class='post-share-buttons goog-inline-block'> <a class='goog-inline-block share-button sb-email' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=7957020708059918311&target=email' target='_blank' title='Email This'><span class='share-button-link-text'>Email This</span></a><a class='goog-inline-block share-button sb-blog' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=7957020708059918311&target=blog' onclick='window.open(this.href, "_blank", "height=270,width=475"); return false;' target='_blank' title='BlogThis!'><span class='share-button-link-text'>BlogThis!</span></a><a class='goog-inline-block share-button sb-twitter' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=7957020708059918311&target=twitter' target='_blank' title='Share to X'><span class='share-button-link-text'>Share to X</span></a><a class='goog-inline-block share-button sb-facebook' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=7957020708059918311&target=facebook' onclick='window.open(this.href, "_blank", "height=430,width=640"); return false;' target='_blank' title='Share to Facebook'><span class='share-button-link-text'>Share to Facebook</span></a><a class='goog-inline-block share-button sb-pinterest' href='https://www.blogger.com/share-post.g?blogID=6264947694886887540&postID=7957020708059918311&target=pinterest' target='_blank' title='Share to Pinterest'><span class='share-button-link-text'>Share to Pinterest</span></a> </div> </div> <div class='post-footer-line post-footer-line-2'><span class='post-labels'> Labels: <a href='http://www.righto.com/search/label/8008' rel='tag'>8008</a>, <a href='http://www.righto.com/search/label/electronics' rel='tag'>electronics</a>, <a href='http://www.righto.com/search/label/reverse-engineering' rel='tag'>reverse-engineering</a> </span> </div> <div class='post-footer-line post-footer-line-3'></div> </div> </div> </div> </div></div> </div> <div class='blog-pager' id='blog-pager'> <span id='blog-pager-newer-link'> <a class='blog-pager-newer-link' href='http://www.righto.com/search?updated-max=2021-02-22T11:32:00-08:00&max-results=7&reverse-paginate=true' id='Blog1_blog-pager-newer-link' title='Newer Posts'>Newer Posts</a> </span> <span id='blog-pager-older-link'> <a class='blog-pager-older-link' href='http://www.righto.com/search?updated-max=2020-11-08T10:40:00-08:00&max-results=7' id='Blog1_blog-pager-older-link' title='Older Posts'>Older Posts</a> </span> <a class='home-link' href='http://www.righto.com/'>Home</a> </div> <div class='clear'></div> </div></div> </div> </div> <div class='column-left-outer'> <div class='column-left-inner'> <aside> </aside> </div> </div> <div class='column-right-outer'> <div class='column-right-inner'> <aside> <div class='sidebar section' id='sidebar-right-1'><div class='widget HTML' data-version='1' id='HTML2'> <div class='widget-content'> <style> @import url('https://fonts.googleapis.com/css?family=Montserrat:300,400,500,700'); .form-preview { display: flex; flex-direction: column; justify-content: center; margin-top: 30px; padding: clamp(17px, 5%, 40px) clamp(17px, 7%, 50px); max-width: 350px; min-height: 200px; border-radius: 6px; box-shadow: 0 5px 25px rgba(34, 60, 47, 0.25); } .form-preview, .form-preview *{ box-sizing: border-box; } .form-preview .preview-heading { width: 100%; } .form-preview .preview-heading h5{ margin-top: 0; margin-bottom: 0; } .form-preview .preview-input-field { margin-top: 20px; width: 100%; } .form-preview .preview-input-field input { width: 100%; height: 40px; border-radius: 6px; border: 2px solid #e9e8e8; background-color: #fff; outline: none; } .form-preview .preview-input-field input::placeholder, .form-preview .preview-input-field input { opacity: 0.5; color: #000; font-family: "Montserrat"; font-size: 14px; font-weight: 500; line-height: 20px; text-align: center; } .form-preview .preview-submit-button { margin-top: 10px; width: 100%; } .form-preview .preview-submit-button button { width: 100%; height: 40px; border: 0; border-radius: 6px; line-height: 0px; } .form-preview .preview-submit-button button:hover { cursor: pointer; } </style><form data-v-4c58e686="" action="https://api.follow.it/subscription-form/U3NBTmZKVkI1YVpCa000a0RCZHFiQ3FYMko1cWRTZTN6K3hJdWM2QWxJbE1uVXdXUHZZVzJVQzVLZGh5Y0RCVXB2d2JSTzBobGhuY0FsZnlHbVdFZ2VTN2Q4Vy84RnIxUTgzVlcrbXNIR0Y0aW93d3REM2J6VS9RL0gxWURnV1d8ZWN0YStwUWdWWUFiOTIyWDVGWjdYYVdGZEVNcC9qODZacjlwWXRIcEJQRT0=/8" method="post"><div data-v-4c58e686="" class="form-preview" style="background-color: rgb(255, 255, 255); border-style: solid; border-width: 1px; border-color: rgb(204, 204, 204); position: relative;"><div data-v-4c58e686="" class="preview-heading"><h5 data-v-4c58e686="" style="font-family: Montserrat; font-weight: bold; color: rgb(0, 0, 0); font-size: 12px; text-align: center;">Get new posts by email:</h5></div> <div data-v-4c58e686="" class="preview-input-field"><input data-v-4c58e686="" type="email" name="email" placeholder="Enter your email" spellcheck="false" /></div> <div data-v-4c58e686="" class="preview-submit-button"><button data-v-4c58e686="" type="submit" style="font-family: Montserrat; font-weight: bold; color: rgb(255, 255, 255); font-size: 12px; text-align: center; background-color: rgb(0, 0, 0);">Subscribe</button></div></div></form> </div> <div class='clear'></div> </div><div class='widget HTML' data-version='1' id='HTML3'> <h2 class='title'>About the site</h2> <div class='widget-content'> <a href="https://www.righto.com/p/index.html">Contact info and site index</a> </div> <div class='clear'></div> </div><div class='widget PopularPosts' data-version='1' id='PopularPosts1'> <h2>Popular Posts</h2> <div class='widget-content popular-posts'> <ul> <li> <div class='item-thumbnail-only'> <div class='item-thumbnail'> <a href='http://www.righto.com/2025/03/mother-of-all-demos-usb-keyset-interface.html' target='_blank'> <img alt='' border='0' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_v1ZfKsOlNeg_fbUwAFU8kdGZPiI45jV2E7HIV1xVuGBHatvVEDOq5E4da73j4mge5A_8RSsC3x2lIHlJ_iEtj79q6BVavo9CL21lcLF7KXY1IpeQv6aNEcEvSTyR7b2gA=w72-h72-p-k-no-nu'/> </a> </div> <div class='item-title'><a href='http://www.righto.com/2025/03/mother-of-all-demos-usb-keyset-interface.html'>A USB interface to the "Mother of All Demos" keyset</a></div> </div> <div style='clear: both;'></div> </li> <li> <div class='item-thumbnail-only'> <div class='item-thumbnail'> <a href='http://www.righto.com/2025/03/pentium-microcde-rom-circuitry.html' target='_blank'> <img alt='' border='0' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_t-kTbP8N5T_Jtd5PuYbN-WQ3UbHZoKNC_qv2B7ydYr2_MZMsPanyfV15MU7cLkCEW7yux_0e16mhiEXwob-Zx2mNFjEbzYyvsvIHwmGvyrReOEPLznpp6TX0f69E5U5_LI6G-J8zVbWbfCjsutv6o=w72-h72-p-k-no-nu'/> </a> </div> <div class='item-title'><a href='http://www.righto.com/2025/03/pentium-microcde-rom-circuitry.html'>Notes on the Pentium's microcode circuitry</a></div> </div> <div style='clear: both;'></div> </li> <li> <div class='item-thumbnail-only'> <div class='item-thumbnail'> <a href='http://www.righto.com/2025/03/pentium-multiplier-adder-reverse-engineered.html' target='_blank'> <img alt='' border='0' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_v0Vud42Kzpe1HTFiEZrAIY-42bG-pvPddq-p8tKAKjLyPwG3p-Uhhazq92wGGZrf0yvqz-5fiPY5zvKVI98THxgE4Sg4CEVJ9Nqx3wmOq9qvlm_LmqfbTo-XsFVFCBypX5t8M4qLEtceap=w72-h72-p-k-no-nu'/> </a> </div> <div class='item-title'><a href='http://www.righto.com/2025/03/pentium-multiplier-adder-reverse-engineered.html'>The Pentium contains a complicated circuit to multiply by three</a></div> </div> <div style='clear: both;'></div> </li> <li> <div class='item-thumbnail-only'> <div class='item-thumbnail'> <a href='http://www.righto.com/2024/05/blog-post.html' target='_blank'> <img alt='' border='0' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_vSns2TTAvOxB74MA9AVW9wRGLVGGo2RBG1VfUx-k8PK1MA5yFuA7Q--XIYeHLrgYybqvk5ZIjYo4A3LW129O7fzIHP53Db9a7_6LyEOjSGowSwuIb5jRjFP_OXLSqT9t3DqGcp6X66MHDJ7cihvIQ2=w72-h72-p-k-no-nu'/> </a> </div> <div class='item-title'><a href='http://www.righto.com/2024/05/blog-post.html'>Inside a vintage aerospace navigation computer of uncertain purpose</a></div> </div> <div style='clear: both;'></div> </li> <li> <div class='item-thumbnail-only'> <div class='item-thumbnail'> <a href='http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html' target='_blank'> <img alt='' border='0' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_tLiP5C-86ZNfdf1WFgU6eQVecfv_9U-qO1Y3mFrlx-7xO1FmZ4IzgS301PaJmGswBI3xSFLgk7CgyKo3H4F7cV6BkzJwS6WGiBjZiu42bLabM=w72-h72-p-k-no-nu'/> </a> </div> <div class='item-title'><a href='http://www.righto.com/2009/08/multi-protocol-infrared-remote-library.html'>A Multi-Protocol Infrared Remote Library for the Arduino</a></div> </div> <div style='clear: both;'></div> </li> <li> <div class='item-thumbnail-only'> <div class='item-thumbnail'> <a href='http://www.righto.com/2012/10/a-dozen-usb-chargers-in-lab-apple-is.html' target='_blank'> <img alt='' border='0' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_umeD45r2CAlb3-XTu2yLEBo0qf5Q8n9YApSdp4b7jURPIGmbrOtMBJI5u0sAj4pn_k16n5QejFfWypVjf0nnN4GCtzPr8UIfpkex-O3RGZL2lEBJnmCyC9ZHr_baE=w72-h72-p-k-no-nu'/> </a> </div> <div class='item-title'><a href='http://www.righto.com/2012/10/a-dozen-usb-chargers-in-lab-apple-is.html'>A dozen USB chargers in the lab: Apple is very good, but not quite the best</a></div> </div> <div style='clear: both;'></div> </li> <li> <div class='item-thumbnail-only'> <div class='item-thumbnail'> <a href='http://www.righto.com/2012/05/apple-iphone-charger-teardown-quality.html' target='_blank'> <img alt='' border='0' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_tnuYlrU45VBMYN9g5Lomv2MhBJJulaF7fTPhIrmREzW8qeIseFxv6RFlK7BgnuVrIjOvIeF4QWd3gTdDmEQt6oN-cg-JrpuQgtUD4poCLkTlDEN-h7TaNVUZkJYpf7BIp9DKR7T2ppf1kadM6phsU_L2g=w72-h72-p-k-no-nu'/> </a> </div> <div class='item-title'><a href='http://www.righto.com/2012/05/apple-iphone-charger-teardown-quality.html'>Apple iPhone charger teardown: quality in a tiny expensive package</a></div> </div> <div style='clear: both;'></div> </li> <li> <div class='item-thumbnail-only'> <div class='item-thumbnail'> <a href='http://www.righto.com/2014/09/mining-bitcoin-with-pencil-and-paper.html' target='_blank'> <img alt='' border='0' src='https://lh3.googleusercontent.com/blogger_img_proxy/AEn0k_vV7jkPX0-NK829H4fPLIjBcSW5tghOGVeaCWzceYXZYtuX3-FHz9E43CpG4U-b2qaExTA4QmFMdFHOvjGsAXQ92Rc-jmz0I_f_vK9jV3wR_B1SOu5TYk5ykJlOPLmb9zLY=w72-h72-p-k-no-nu'/> </a> </div> <div class='item-title'><a href='http://www.righto.com/2014/09/mining-bitcoin-with-pencil-and-paper.html'>Mining Bitcoin with pencil and paper: 0.67 hashes per day</a></div> </div> <div style='clear: both;'></div> </li> </ul> <div class='clear'></div> </div> </div><div class='widget BlogSearch' data-version='1' id='BlogSearch1'> <h2 class='title'>Search This Blog</h2> <div class='widget-content'> <div id='BlogSearch1_form'> <form action='http://www.righto.com/search' class='gsc-search-box' target='_top'> <table cellpadding='0' cellspacing='0' class='gsc-search-box'> <tbody> <tr> <td class='gsc-input'> <input autocomplete='off' class='gsc-input' name='q' size='10' title='search' type='text' value=''/> </td> <td class='gsc-search-button'> <input class='gsc-search-button' title='search' type='submit' value='Search'/> </td> </tr> </tbody> </table> </form> </div> </div> <div class='clear'></div> </div><div class='widget Label' data-version='1' id='Label1'> <h2>Labels</h2> <div class='widget-content cloud-label-widget-content'> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/386'>386</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/6502'>6502</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/8008'>8008</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/8085'>8085</a> </span> <span class='label-size label-size-4'> <a dir='ltr' href='http://www.righto.com/search/label/8086'>8086</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/8087'>8087</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/8088'>8088</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/aerospace'>aerospace</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/alto'>alto</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/analog'>analog</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/Apollo'>Apollo</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/apple'>apple</a> </span> <span class='label-size label-size-4'> <a dir='ltr' href='http://www.righto.com/search/label/arc'>arc</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/arduino'>arduino</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/arm'>arm</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/beaglebone'>beaglebone</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/bitcoin'>bitcoin</a> </span> <span class='label-size label-size-1'> <a dir='ltr' href='http://www.righto.com/search/label/c%23'>c#</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/cadc'>cadc</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/calculator'>calculator</a> </span> <span class='label-size label-size-4'> <a dir='ltr' href='http://www.righto.com/search/label/chips'>chips</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/css'>css</a> </span> <span class='label-size label-size-1'> <a dir='ltr' href='http://www.righto.com/search/label/datapoint'>datapoint</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/dx7'>dx7</a> </span> <span class='label-size label-size-5'> <a dir='ltr' href='http://www.righto.com/search/label/electronics'>electronics</a> </span> <span class='label-size label-size-1'> <a dir='ltr' href='http://www.righto.com/search/label/f%23'>f#</a> </span> <span class='label-size label-size-1'> <a dir='ltr' href='http://www.righto.com/search/label/fairchild'>fairchild</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/fpga'>fpga</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/fractals'>fractals</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/genome'>genome</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/globus'>globus</a> </span> <span class='label-size label-size-1'> <a dir='ltr' href='http://www.righto.com/search/label/haskell'>haskell</a> </span> <span class='label-size label-size-1'> <a dir='ltr' href='http://www.righto.com/search/label/HP'>HP</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/html5'>html5</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/ibm'>ibm</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/ibm1401'>ibm1401</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/ibm360'>ibm360</a> </span> <span class='label-size label-size-4'> <a dir='ltr' href='http://www.righto.com/search/label/intel'>intel</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/ipv6'>ipv6</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/ir'>ir</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/java'>java</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/javascript'>javascript</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/math'>math</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/microcode'>microcode</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/oscilloscope'>oscilloscope</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/Pentium'>Pentium</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/photo'>photo</a> </span> <span class='label-size label-size-4'> <a dir='ltr' href='http://www.righto.com/search/label/power%20supply'>power supply</a> </span> <span class='label-size label-size-4'> <a dir='ltr' href='http://www.righto.com/search/label/random'>random</a> </span> <span class='label-size label-size-5'> <a dir='ltr' href='http://www.righto.com/search/label/reverse-engineering'>reverse-engineering</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/sheevaplug'>sheevaplug</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/snark'>snark</a> </span> <span class='label-size label-size-3'> <a dir='ltr' href='http://www.righto.com/search/label/space'>space</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/spanish'>spanish</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/synth'>synth</a> </span> <span class='label-size label-size-4'> <a dir='ltr' href='http://www.righto.com/search/label/teardown'>teardown</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/theory'>theory</a> </span> <span class='label-size label-size-1'> <a dir='ltr' href='http://www.righto.com/search/label/unicode'>unicode</a> </span> <span class='label-size label-size-2'> <a dir='ltr' href='http://www.righto.com/search/label/Z-80'>Z-80</a> </span> <div class='clear'></div> </div> </div><div class='widget BlogArchive' data-version='1' id='BlogArchive1'> <h2>Blog Archive</h2> <div class='widget-content'> <div id='ArchiveList'> <div id='BlogArchive1_ArchiveList'> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2025/'> 2025 </a> <span class='post-count' dir='ltr'>(8)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2025/03/'> March </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2025/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2025/01/'> January </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/'> 2024 </a> <span class='post-count' dir='ltr'>(21)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/12/'> December </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/11/'> November </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/09/'> September </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/08/'> August </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/07/'> July </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/06/'> June </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/02/'> February </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2024/01/'> January </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2023/'> 2023 </a> <span class='post-count' dir='ltr'>(35)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2023/12/'> December </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2023/11/'> November </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2023/10/'> October </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2023/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2023/08/'> August </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2023/07/'> July </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2023/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2023/04/'> April </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2023/03/'> March </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2023/02/'> February </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2023/01/'> January </a> <span class='post-count' dir='ltr'>(8)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2022/'> 2022 </a> <span class='post-count' dir='ltr'>(18)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2022/11/'> November </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2022/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2022/07/'> July </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2022/06/'> June </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2022/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2022/04/'> April </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2022/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2022/02/'> February </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2022/01/'> January </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2021/'> 2021 </a> <span class='post-count' dir='ltr'>(26)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2021/12/'> December </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2021/11/'> November </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2021/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2021/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2021/07/'> July </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2021/06/'> June </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2021/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2021/04/'> April </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2021/03/'> March </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2021/02/'> February </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2021/01/'> January </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> ▼  </span> </a> <a class='post-count-link' href='http://www.righto.com/2020/'> 2020 </a> <span class='post-count' dir='ltr'>(33)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2020/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate expanded'> <a class='toggle' href='javascript:void(0)'> <span class='zippy toggle-open'> ▼  </span> </a> <a class='post-count-link' href='http://www.righto.com/2020/11/'> November </a> <span class='post-count' dir='ltr'>(3)</span> <ul class='posts'> <li><a href='http://www.righto.com/2020/11/reverse-engineering-ram-storage-in.html'>Reverse engineering RAM storage in early Texas Ins...</a></li> <li><a href='http://www.righto.com/2020/11/reverse-engineering-classic-mk4116-16.html'>Reverse-engineering the classic MK4116 16-kilobit ...</a></li> <li><a href='http://www.righto.com/2020/11/reverse-engineering-carry-lookahead.html'>Reverse-engineering the carry-lookahead circuit in...</a></li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2020/10/'> October </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2020/09/'> September </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2020/08/'> August </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2020/07/'> July </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2020/06/'> June </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2020/05/'> May </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2020/04/'> April </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2020/03/'> March </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2020/01/'> January </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2019/'> 2019 </a> <span class='post-count' dir='ltr'>(18)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2019/11/'> November </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2019/10/'> October </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2019/09/'> September </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2019/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2019/07/'> July </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2019/04/'> April </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2019/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2019/01/'> January </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2018/'> 2018 </a> <span class='post-count' dir='ltr'>(17)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2018/12/'> December </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2018/09/'> September </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2018/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2018/06/'> June </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2018/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2018/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2018/03/'> March </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2018/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2018/01/'> January </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2017/'> 2017 </a> <span class='post-count' dir='ltr'>(21)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2017/12/'> December </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2017/11/'> November </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2017/10/'> October </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2017/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2017/07/'> July </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2017/06/'> June </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2017/04/'> April </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2017/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2017/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2017/01/'> January </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2016/'> 2016 </a> <span class='post-count' dir='ltr'>(34)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2016/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2016/10/'> October </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2016/09/'> September </a> <span class='post-count' dir='ltr'>(8)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2016/08/'> August </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2016/07/'> July </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2016/06/'> June </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2016/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2016/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2016/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2016/02/'> February </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2016/01/'> January </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2015/'> 2015 </a> <span class='post-count' dir='ltr'>(12)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2015/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2015/11/'> November </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2015/10/'> October </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2015/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2015/05/'> May </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2015/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2015/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2014/'> 2014 </a> <span class='post-count' dir='ltr'>(13)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2014/12/'> December </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2014/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2014/09/'> September </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2014/05/'> May </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2014/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2014/02/'> February </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2013/'> 2013 </a> <span class='post-count' dir='ltr'>(24)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2013/11/'> November </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2013/09/'> September </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2013/08/'> August </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2013/07/'> July </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2013/06/'> June </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2013/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2013/03/'> March </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2013/02/'> February </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2013/01/'> January </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2012/'> 2012 </a> <span class='post-count' dir='ltr'>(10)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2012/12/'> December </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2012/11/'> November </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2012/10/'> October </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2012/05/'> May </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2012/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2012/02/'> February </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2011/'> 2011 </a> <span class='post-count' dir='ltr'>(11)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2011/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2011/07/'> July </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2011/05/'> May </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2011/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2011/03/'> March </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2011/02/'> February </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2010/'> 2010 </a> <span class='post-count' dir='ltr'>(22)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2010/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2010/11/'> November </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2010/10/'> October </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2010/08/'> August </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2010/06/'> June </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2010/05/'> May </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2010/04/'> April </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2010/03/'> March </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2010/01/'> January </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2009/'> 2009 </a> <span class='post-count' dir='ltr'>(22)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2009/12/'> December </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2009/11/'> November </a> <span class='post-count' dir='ltr'>(5)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2009/09/'> September </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2009/08/'> August </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2009/07/'> July </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2009/06/'> June </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2009/04/'> April </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2009/03/'> March </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2009/02/'> February </a> <span class='post-count' dir='ltr'>(2)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2009/01/'> January </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2008/'> 2008 </a> <span class='post-count' dir='ltr'>(27)</span> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2008/07/'> July </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2008/06/'> June </a> <span class='post-count' dir='ltr'>(1)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2008/05/'> May </a> <span class='post-count' dir='ltr'>(3)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2008/04/'> April </a> <span class='post-count' dir='ltr'>(4)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2008/03/'> March </a> <span class='post-count' dir='ltr'>(10)</span> </li> </ul> <ul class='hierarchy'> <li class='archivedate collapsed'> <a class='toggle' href='javascript:void(0)'> <span class='zippy'> ►  </span> </a> <a class='post-count-link' href='http://www.righto.com/2008/02/'> February </a> <span class='post-count' dir='ltr'>(6)</span> </li> </ul> </li> </ul> </div> </div> <div class='clear'></div> </div> </div></div> </aside> </div> </div> </div> <div style='clear: both'></div> <!-- columns --> </div> <!-- main --> </div> </div> <div class='main-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> <footer> <div class='footer-outer'> <div class='footer-cap-top cap-top'> <div class='cap-left'></div> <div class='cap-right'></div> </div> <div class='fauxborder-left footer-fauxborder-left'> <div class='fauxborder-right footer-fauxborder-right'></div> <div class='region-inner footer-inner'> <div class='foot no-items section' id='footer-1'></div> <table border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'> <tbody> <tr> <td class='first columns-cell'> <div class='foot no-items section' id='footer-2-1'></div> </td> <td class='columns-cell'> <div class='foot no-items section' id='footer-2-2'></div> </td> </tr> </tbody> </table> <!-- outside of the include in order to lock Attribution widget --> <div class='foot section' id='footer-3'><div class='widget Attribution' data-version='1' id='Attribution1'> <div class='widget-content' style='text-align: center;'> Powered by <a href='https://www.blogger.com' target='_blank'>Blogger</a>. </div> <div class='clear'></div> </div></div> </div> </div> <div class='footer-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </footer> <!-- content --> </div> </div> <div class='content-cap-bottom cap-bottom'> <div class='cap-left'></div> <div class='cap-right'></div> </div> </div> </div> <script type='text/javascript'> window.setTimeout(function() { document.body.className = document.body.className.replace('loading', ''); }, 10); </script> <script type="text/javascript" src="https://www.blogger.com/static/v1/widgets/2806328968-widgets.js"></script> <script type='text/javascript'> window['__wavt'] = 'AOuZoY4CcxJPBXLzmOXgDc3smc4MEz1_UA:1743913062087';_WidgetManager._Init('//www.blogger.com/rearrange?blogID\x3d6264947694886887540','//www.righto.com/2020/11/','6264947694886887540'); _WidgetManager._SetDataContext([{'name': 'blog', 'data': {'blogId': '6264947694886887540', 'title': 'Ken Shirriff\x27s blog', 'url': 'http://www.righto.com/2020/11/', 'canonicalUrl': 'http://www.righto.com/2020/11/', 'homepageUrl': 'http://www.righto.com/', 'searchUrl': 'http://www.righto.com/search', 'canonicalHomepageUrl': 'http://www.righto.com/', 'blogspotFaviconUrl': 'http://www.righto.com/favicon.ico', 'bloggerUrl': 'https://www.blogger.com', 'hasCustomDomain': true, 'httpsEnabled': false, 'enabledCommentProfileImages': true, 'gPlusViewType': 'FILTERED_POSTMOD', 'adultContent': false, 'analyticsAccountNumber': 'UA-3782444-1', 'encoding': 'UTF-8', 'locale': 'en', 'localeUnderscoreDelimited': 'en', 'languageDirection': 'ltr', 'isPrivate': false, 'isMobile': false, 'isMobileRequest': false, 'mobileClass': '', 'isPrivateBlog': false, 'isDynamicViewsAvailable': true, 'feedLinks': '\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Ken Shirriff\x26#39;s blog - Atom\x22 href\x3d\x22http://www.righto.com/feeds/posts/default\x22 /\x3e\n\x3clink rel\x3d\x22alternate\x22 type\x3d\x22application/rss+xml\x22 title\x3d\x22Ken Shirriff\x26#39;s blog - RSS\x22 href\x3d\x22http://www.righto.com/feeds/posts/default?alt\x3drss\x22 /\x3e\n\x3clink rel\x3d\x22service.post\x22 type\x3d\x22application/atom+xml\x22 title\x3d\x22Ken Shirriff\x26#39;s blog - Atom\x22 href\x3d\x22https://www.blogger.com/feeds/6264947694886887540/posts/default\x22 /\x3e\n', 'meTag': '', 'adsenseHostId': 'ca-host-pub-1556223355139109', 'adsenseHasAds': false, 'adsenseAutoAds': false, 'boqCommentIframeForm': true, 'loginRedirectParam': '', 'view': '', 'dynamicViewsCommentsSrc': '//www.blogblog.com/dynamicviews/4224c15c4e7c9321/js/comments.js', 'dynamicViewsScriptSrc': '//www.blogblog.com/dynamicviews/c4ef6ff9ae7c94eb', 'plusOneApiSrc': 'https://apis.google.com/js/platform.js', 'disableGComments': true, 'interstitialAccepted': false, 'sharing': {'platforms': [{'name': 'Get link', 'key': 'link', 'shareMessage': 'Get link', 'target': ''}, {'name': 'Facebook', 'key': 'facebook', 'shareMessage': 'Share to Facebook', 'target': 'facebook'}, {'name': 'BlogThis!', 'key': 'blogThis', 'shareMessage': 'BlogThis!', 'target': 'blog'}, {'name': 'X', 'key': 'twitter', 'shareMessage': 'Share to X', 'target': 'twitter'}, {'name': 'Pinterest', 'key': 'pinterest', 'shareMessage': 'Share to Pinterest', 'target': 'pinterest'}, {'name': 'Email', 'key': 'email', 'shareMessage': 'Email', 'target': 'email'}], 'disableGooglePlus': true, 'googlePlusShareButtonWidth': 0, 'googlePlusBootstrap': '\x3cscript type\x3d\x22text/javascript\x22\x3ewindow.___gcfg \x3d {\x27lang\x27: \x27en\x27};\x3c/script\x3e'}, 'hasCustomJumpLinkMessage': false, 'jumpLinkMessage': 'Read more', 'pageType': 'archive', 'pageName': 'November 2020', 'pageTitle': 'Ken Shirriff\x27s blog: November 2020'}}, {'name': 'features', 'data': {}}, {'name': 'messages', 'data': {'edit': 'Edit', 'linkCopiedToClipboard': 'Link copied to clipboard!', 'ok': 'Ok', 'postLink': 'Post Link'}}, {'name': 'template', 'data': {'name': 'custom', 'localizedName': 'Custom', 'isResponsive': false, 'isAlternateRendering': false, 'isCustom': true}}, {'name': 'view', 'data': {'classic': {'name': 'classic', 'url': '?view\x3dclassic'}, 'flipcard': {'name': 'flipcard', 'url': '?view\x3dflipcard'}, 'magazine': {'name': 'magazine', 'url': '?view\x3dmagazine'}, 'mosaic': {'name': 'mosaic', 'url': '?view\x3dmosaic'}, 'sidebar': {'name': 'sidebar', 'url': '?view\x3dsidebar'}, 'snapshot': {'name': 'snapshot', 'url': '?view\x3dsnapshot'}, 'timeslide': {'name': 'timeslide', 'url': '?view\x3dtimeslide'}, 'isMobile': false, 'title': 'Ken Shirriff\x27s blog', 'description': 'Computer history, restoring vintage computers, IC reverse engineering, and whatever', 'url': 'http://www.righto.com/2020/11/', 'type': 'feed', 'isSingleItem': false, 'isMultipleItems': true, 'isError': false, 'isPage': false, 'isPost': false, 'isHomepage': false, 'isArchive': true, 'isLabelSearch': false, 'archive': {'year': 2020, 'month': 11, 'rangeMessage': 'Showing posts from November, 2020'}}}]); _WidgetManager._RegisterWidget('_HeaderView', new _WidgetInfo('Header1', 'header', document.getElementById('Header1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogView', new _WidgetInfo('Blog1', 'main', document.getElementById('Blog1'), {'cmtInteractionsEnabled': false}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML2', 'sidebar-right-1', document.getElementById('HTML2'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_HTMLView', new _WidgetInfo('HTML3', 'sidebar-right-1', document.getElementById('HTML3'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_PopularPostsView', new _WidgetInfo('PopularPosts1', 'sidebar-right-1', document.getElementById('PopularPosts1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogSearchView', new _WidgetInfo('BlogSearch1', 'sidebar-right-1', document.getElementById('BlogSearch1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_LabelView', new _WidgetInfo('Label1', 'sidebar-right-1', document.getElementById('Label1'), {}, 'displayModeFull')); _WidgetManager._RegisterWidget('_BlogArchiveView', new _WidgetInfo('BlogArchive1', 'sidebar-right-1', document.getElementById('BlogArchive1'), {'languageDirection': 'ltr', 'loadingMessage': 'Loading\x26hellip;'}, 'displayModeFull')); _WidgetManager._RegisterWidget('_AttributionView', new _WidgetInfo('Attribution1', 'footer-3', document.getElementById('Attribution1'), {}, 'displayModeFull')); </script> </body> </html>