{"id":276,"date":"2022-11-21T10:22:23","date_gmt":"2022-11-21T15:22:23","guid":{"rendered":"https:\/\/robertweatherford.com\/wordpress\/?page_id=276"},"modified":"2023-12-03T15:52:27","modified_gmt":"2023-12-03T20:52:27","slug":"omni-1","status":"publish","type":"page","link":"https:\/\/robertweatherford.com\/index.php\/professional-life\/closed-projects\/1980s\/omni-1\/","title":{"rendered":"OMNI-1"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" src=\"https:\/\/i0.wp.com\/robertweatherford.com\/wordpress\/wp-content\/uploads\/2022\/11\/OMNI-1-front.jpg?resize=1024%2C582&#038;ssl=1\" alt=\"\" class=\"wp-image-595\" data-recalc-dims=\"1\"\/><figcaption class=\"wp-element-caption\">1984 \u2014&nbsp;Megasys (A Robert E. Weatherford D\/B\/A)<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Overview<\/h2>\n\n\n\n<p>The idea for the OMNI-1 originally started out as a memory manager for banked CP\/M 3. Then I found this wonderful Burroughs keyboard monstrosity that used hall-effect key switches. I had heard of the hall-effect before, and thought it would make a great keyboard that would never wear out. So I added the serial keyboard interface to the design. Oh, and a parallel printer port, too. As I neared the point of committing this to an actual prototype design, I thought, \u201cWhat else do I need?\u201d After changing the question to \u201cWhat do I want?\u201d I thought that a PROM programmer timing generator would get me one step closer to finally building a universal programmer. So I added that. Classic scope creep in retrospect.<\/p>\n\n\n\n<p>The OMNI-1 has a PROM programmer controller, serial keyboard interface, and a programmable bank switched memory mapper with 20 bit addressing for the new S-100 bus specification (IEEE 696).&nbsp;A design innovation was the use of a pair of 74F283s as an ultra fast 8 bit magnitude comparator for the memory mapper.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Serial Keyboard Interface<\/h3>\n\n\n\n<p>The serial keyboard interface is specific to the Burroughs keyboard I had found at a surplus store. It came with schematics and specifications for the serial interface.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Parallel Printer Port<\/h3>\n\n\n\n<p>The parallel printer port is a classis write-only Centronics-compatible printer port. Nothing fancy.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Memory Manager<\/h3>\n\n\n\n<p>The memory manager was designed to be exactly what CP\/M 3 wanted. A 20-bit address space of 16 64k banks, with an assignable window in the 16-bit address space for global memory. This global memory was always addressed as bank 0 and was the space where ISRs, BIOS, and part of the BDOS resided. The rest was switchable. CP\/M\u2019s usage of the banked memory was pretty much limited to one other bank for the bulk of the BDOS. The rest of the banks was used in my BIOS for disk caches and printer buffers.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">PROM Programmer Interface<\/h3>\n\n\n\n<p>The PROM programmer interface is an 8-bit bidirectional parallel port with a single pulse generator. The actual PROM programmer was to contain all the level shifters, buffers, and latches necessary to implement the programmer. The pulse generator eliminated the need for software-driven timers.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Port Assignments<\/h2>\n\n\n\n<p>Click here to see the\u00a0<a href=\"https:\/\/robertweatherford.com\/wordpress\/wp-content\/uploads\/2022\/11\/omni-1_schematic.pdf\" data-type=\"attachment\" data-id=\"222\" target=\"_blank\" rel=\"noreferrer noopener\">OMNI-1 schematic<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Port Offset<\/strong><\/td><td><strong>Function<\/strong><\/td><\/tr><tr><td>&nbsp;0<\/td><td><a href=\"#port_0\">Serial Keyboard Data<\/a><\/td><\/tr><tr><td>&nbsp;1<\/td><td><a href=\"#port_1\">Serial Keyboard Status<\/a><\/td><\/tr><tr><td>&nbsp;2<\/td><td><a href=\"#port_2\">Parallel Printer Data<\/a><\/td><\/tr><tr><td>&nbsp;3<\/td><td><a href=\"#port_3\">Parallel Printer Status<\/a><\/td><\/tr><tr><td>&nbsp;4<\/td><td><a href=\"#port_4\">Extended Address Global Memory Bounds Register&nbsp;<\/a><\/td><\/tr><tr><td>&nbsp;5<\/td><td><a href=\"#port_5\">Extended Address Page Register<\/a><\/td><\/tr><tr><td>&nbsp;6<\/td><td><a href=\"#port_6\">PROM Programmer Data Register<\/a><\/td><\/tr><tr><td>&nbsp;7<\/td><td><a href=\"#port_7\">PROM Programmer Command Register<\/a><\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">OMNI-1 Port Assignments<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"port_0\">PORT 0: Serial Keyboard Data<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Input<\/h4>\n\n\n\n<p>This port contains the eight bits returned from the serial keyboard after an Invitation to Interrupt or Get Command.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Output<\/h4>\n\n\n\n<p>This port is used to contain the eight bit data that is sent after a Select or Send Command. Note: This register is self-clearing, that is, the contents of the register is left zero after a command is issued. Therefore, it is not necessary to initialize this register to zero for the Invitation to interrupt or Get Commands.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"port_1\">PORT 1: Serial Keyboard Status<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Input<\/h4>\n\n\n\n<p>Bit 0 of this port shall be true if the serial keyboard port is ready.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Output<\/h4>\n\n\n\n<p>Bits 0 through 3 specify the three bit command to be sent to the keyboard. The command, along with the data in the data register is then sent serially to the keyboard.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"port_2\">PORT 2: Parallel Printer Data<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Output<\/h4>\n\n\n\n<p>Data output to this port is sent immediately to the printer. It is the responsibility of the driver program to insure that the printer is ready to accept the data.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"port_3\">PORT 3: Parallel Printer Status<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Input<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Bit<\/strong><\/td><td><strong>Function<\/strong><\/td><\/tr><tr><td>0<\/td><td>Zero after data is output to the data port, Goes to One after the printer sends the ACK* signal.<\/td><\/tr><tr><td>1<\/td><td>The printer BUSY signal.<\/td><\/tr><tr><td>2<\/td><td>The printer PAPEND signal.<\/td><\/tr><tr><td>3<\/td><td>The printer SELECT signal.<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Parallel Printer Status Input Port Bit Functions<\/figcaption><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Output<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Bit<\/strong><\/td><td><strong>Function<\/strong><\/td><\/tr><tr><td>0<\/td><td>Sets the printer&#8217;s FAULT* signal.<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Parallel Printer Status Output Port Bit Functions<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"port_4\">PORT 4: Extended Address Global Memory Bounds Register<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Output<\/h4>\n\n\n\n<p>The low nibble (bits 0 through 3) sets the starting address of global memory, in 4096 byte increments. For example, a value of 1100 sets the beginning of global memory at C000 hex. The high nibble (bits 4 through 7) Sets the ending address of global memory. For example:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Value<\/strong><\/td><td><strong>Global Memory Range<\/strong><\/td><\/tr><tr><td>FF hex<\/td><td>F000 &#8211; FFFF<\/td><\/tr><tr><td>8D hex<\/td><td>8000 &#8211; DFFF<\/td><\/tr><tr><td>10 hex<\/td><td>1000 &#8211; 0FFF (no global memory)<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Extended Address Global Memory Bounds Register Output Port Bit Functions<\/figcaption><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"port_5\">PORT 5: Extended Address Page Register<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Output<\/h4>\n\n\n\n<p>Data output to this port is sent immediately to the printer. It is the responsibility of the driver program to insure that the printer is ready to accept the data.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"port_6\">PORT: 6 PROM Programmer Data Register<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Input<\/h4>\n\n\n\n<p>This port contains the eight data bus lines to the PROM programmer.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Output<\/h4>\n\n\n\n<p>Data written to this port is always written to the data bus output register. However, this port is used to write to the time delay register and to the time delay scalar register, and may be enabled to do so by bits in the PROM Programmer Command Register.<\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Time Delay Scalar Register<\/h5>\n\n\n\n<p>Bits 0 through 3 specify one of eight time constants to be used in the time delay count.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Value<\/strong><\/td><td><strong>Delay per count<\/strong><\/td><td><strong>Range of delay<\/strong><\/td><\/tr><tr><td>000<\/td><td>Infinite Delay<\/td><td><\/td><\/tr><tr><td>001<\/td><td>1 microsecond<\/td><td>1\u00b5s to 255\u00b5s<\/td><\/tr><tr><td>010<\/td><td>10 microseconds<\/td><td>10\u00b5s to 2.55ms<\/td><\/tr><tr><td>011<\/td><td>100 microseconds<\/td><td>100\u00b5s to 25.5ms<\/td><\/tr><tr><td>100<\/td><td>1 millisecond<\/td><td>1ms to 255ms<\/td><\/tr><tr><td>101<\/td><td>10 milliseconds<\/td><td>10ms to 2.55s<\/td><\/tr><tr><td>110<\/td><td>100 milliseconds<\/td><td>100ms to 25.5s<\/td><\/tr><tr><td>111<\/td><td>1 second<\/td><td>1s to 255s<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">Time Delay Scalar Register Output Port Bit Functions<\/figcaption><\/figure>\n\n\n\n<h5 class=\"wp-block-heading\">Time Delay Register<\/h5>\n\n\n\n<p>The eight bit value sent to this port should contain the ones-complement representation of the delay count. A value of zero (FF hex) will result in no time delay; a value of 255 (00 hex) will result in the maximum delay count.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"port_7\">PORT 7: PROM Programmer Command Register<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\">Input<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Bit<\/strong><\/td><td><strong>Function<\/strong><\/td><\/tr><tr><td>0-2<\/td><td>Returns the contents of the scalar register.<\/td><\/tr><tr><td>7<\/td><td>One if Time delay is active, zero if inactive.<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">PROM Programmer Command Register Input Port Bit Functions<\/figcaption><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Output<\/h4>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>Bit<\/strong><\/td><td><strong>Function<\/strong><\/td><\/tr><tr><td>0<\/td><td>Low order address bit. Used with bit 1 below<\/td><\/tr><tr><td>1<\/td><td>High order address bit. Used with address bit 0 to address one of four eight-bit registers in the PROM Programmer.<\/td><\/tr><tr><td>2<\/td><td>Bus Direction bit. Zero for output to PROM Programmer, One for input from PROM Programmer.<\/td><\/tr><tr><td>3<\/td><td>Write bit. Positive edge causes PROM Programmer to write the data present on the data bus into the currently addressed internal register. Bus Direction bit must be zero.<\/td><\/tr><tr><td>4<\/td><td>Delay Register Enable. Setting this bit to a One causes data written to the data port to be written to the delay count register.<\/td><\/tr><tr><td>5<\/td><td>Scalar Register Enable. Setting this bit to a One causes data written to the data port to be written to the delay count scalar register.<\/td><\/tr><tr><td>7<\/td><td>Setting this bit to a One causes the time delay one-shot to trigger. The time delay register itself is destructive, meaning it will have to be written every time before a time delay event can take place. The time delay one-shot is non-retriggerable.<\/td><\/tr><\/tbody><\/table><figcaption class=\"wp-element-caption\">PROM Programmer Command Register Output Port Bit Functions<\/figcaption><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Status<\/h2>\n\n\n\n<p>Between 1984 and 2022, the ONMI-1 prototype board existed in its original form as shown in these photographs. When I started the IMSAI Development System resurrection in 2022, I discovered that the Burroughs keyboard had developed a few bad keys, one of which was the Return key. After many hours of trying to fix it, I gave up and donated it to the recycling bin. I had also recently built and purchased device programmers that eliminated the need for the PROM programmer interface.<\/p>\n\n\n\n<p>In 2022, the OMNI-1 underwent a radical keyboard\/prom interfacectomy. The keyboard interface no longer had a keyboard to talk to. The PROM programmer interface had always just sat there generating heat. So these components were ripped out, leaving the memory mapper and the parallel printer port. The first goal is for the board to recover from the interfacectomy and function in the IMSAI Development System as it once did. The second goal is to free up room for newer additions such as a PS\/2 keyboard interface, and finally spin it into a real board.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Wiring Side<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"565\" src=\"https:\/\/i0.wp.com\/robertweatherford.com\/wordpress\/wp-content\/uploads\/2022\/11\/OMNI-1-back.jpg?resize=1024%2C565&#038;ssl=1\" alt=\"\" class=\"wp-image-598\" srcset=\"https:\/\/i0.wp.com\/robertweatherford.com\/wordpress\/wp-content\/uploads\/2022\/11\/OMNI-1-back-scaled.jpg?resize=1024%2C565&amp;ssl=1 1024w, https:\/\/i0.wp.com\/robertweatherford.com\/wordpress\/wp-content\/uploads\/2022\/11\/OMNI-1-back-scaled.jpg?resize=300%2C166&amp;ssl=1 300w, https:\/\/i0.wp.com\/robertweatherford.com\/wordpress\/wp-content\/uploads\/2022\/11\/OMNI-1-back-scaled.jpg?resize=768%2C424&amp;ssl=1 768w, https:\/\/i0.wp.com\/robertweatherford.com\/wordpress\/wp-content\/uploads\/2022\/11\/OMNI-1-back-scaled.jpg?resize=1536%2C848&amp;ssl=1 1536w, https:\/\/i0.wp.com\/robertweatherford.com\/wordpress\/wp-content\/uploads\/2022\/11\/OMNI-1-back-scaled.jpg?resize=2048%2C1131&amp;ssl=1 2048w\" sizes=\"(max-width: 1000px) 100vw, 1000px\" data-recalc-dims=\"1\" \/><figcaption class=\"wp-element-caption\">OMNI-1 Wiring Side<\/figcaption><\/figure>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Overview The idea for the OMNI-1 originally started out as a memory manager for banked CP\/M 3. Then I found this wonderful Burroughs keyboard monstrosity that used hall-effect key switches. I had heard of the hall-effect before, and thought it would make a great keyboard that would never wear out. So I added the serial [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":136,"menu_order":1984,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"jetpack_sharing_enabled":true,"jetpack-related-posts":[],"_links":{"self":[{"href":"https:\/\/robertweatherford.com\/index.php\/wp-json\/wp\/v2\/pages\/276"}],"collection":[{"href":"https:\/\/robertweatherford.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/robertweatherford.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/robertweatherford.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/robertweatherford.com\/index.php\/wp-json\/wp\/v2\/comments?post=276"}],"version-history":[{"count":6,"href":"https:\/\/robertweatherford.com\/index.php\/wp-json\/wp\/v2\/pages\/276\/revisions"}],"predecessor-version":[{"id":672,"href":"https:\/\/robertweatherford.com\/index.php\/wp-json\/wp\/v2\/pages\/276\/revisions\/672"}],"up":[{"embeddable":true,"href":"https:\/\/robertweatherford.com\/index.php\/wp-json\/wp\/v2\/pages\/136"}],"wp:attachment":[{"href":"https:\/\/robertweatherford.com\/index.php\/wp-json\/wp\/v2\/media?parent=276"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}