{"id":25701530,"url":"https://github.com/mengstr/discrete-ay-3-8910","last_synced_at":"2026-01-31T03:02:45.445Z","repository":{"id":137838552,"uuid":"503509170","full_name":"mengstr/Discrete-AY-3-8910","owner":"mengstr","description":"AY-3-8910 made out of discrete 74-series logic ICs","archived":false,"fork":false,"pushed_at":"2022-07-15T09:31:42.000Z","size":10263,"stargazers_count":24,"open_issues_count":0,"forks_count":1,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-06-10T16:09:17.147Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mengstr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-06-14T20:22:36.000Z","updated_at":"2025-04-24T15:49:51.000Z","dependencies_parsed_at":null,"dependency_job_id":"5cf04e1a-6b4e-4f62-99eb-437170a47fba","html_url":"https://github.com/mengstr/Discrete-AY-3-8910","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/mengstr/Discrete-AY-3-8910","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mengstr%2FDiscrete-AY-3-8910","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mengstr%2FDiscrete-AY-3-8910/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mengstr%2FDiscrete-AY-3-8910/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mengstr%2FDiscrete-AY-3-8910/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mengstr","download_url":"https://codeload.github.com/mengstr/Discrete-AY-3-8910/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mengstr%2FDiscrete-AY-3-8910/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28927773,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-31T02:59:34.861Z","status":"ssl_error","status_checked_at":"2026-01-31T02:59:05.369Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-25T04:17:39.172Z","updated_at":"2026-01-31T03:02:45.433Z","avatar_url":"https://github.com/mengstr.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Discrete AY-3-8910\n\nThis is a WIP project to make a complete and fully compatible AY-3-8910 out of discrete and readily avaiable 74-series logic ICs.\n\n## Background\n\nWhilst there are many software implementations both for PC and microcontrollers like an AVR as well as implemntations in Verilog to be used in a FPGA I haven't seen any real hardware level implementations of it yet.\n\nThe chip is fairly well analyzed and documented and even had its die analysed and a schematic of it on the transistor-level has been made. More info about that can be found github.com/lvd2/ay-3-8910_reverse_engineered\n\n## Digital simulation\n\nBeing a fan of Helmut Hneemanns project _Digital_ which is a circuit simulator for digital designs (much like Logisim) I started by making a design of the AY-3-8910 using it ending up in just a bit over 104 ICs.\n\nThis sounds like a lot of ICs and also quite complicated to build, but my design is modular and most of the modules are\nnot too complex or hard to understand. With the exeption o the most complex module - the envelope generator that\ngenerates the  eight different envelopes  used to vary the volume of the tones over time. \nI've split this into two separate modules, one for the rate genaration and\none for generating the actual envalope shapes.\n\nI have a copy of the shape module as a separate module in Digtial with testcases in order to verify the correct function of each mode.\n\nBelow is a shrunk and blurry overview of the entire schematic - click here for a [highres version](https://raw.githubusercontent.com/mengstr/Discrete-AY-3-8910/main/Images/AY-3-8910-full-large.png) of it.\n\n![reduced overall schematic](Images/AY-3-8910-full-small.png)\n\n### Module Block diagram\n\nThe is a block diragram showing how the modules are interconnected. Since the envelope genarator is fairly complex it is split into two parts. One for generating the clock that affects the rate of the envelope and one that actually creates the 4-bit digital values of the envelope. \n\nThe complete build is spread out on separate modules that are hooked up together using some common signals like the databus, reset and clock that are generated by the ~Control module~ and also connects separate ReadEnable and WriteEnable signals to each modules. \n\nThe R-numbers in the boxes shows which registers that is controlling the functions in it.\n\nThick lines are busses of 4 or 8 bits, and the thin lines are single wires. This means that both the three tone genarator as well as the noise generator are just single 1-bit streams.\n\n![block diagram](Images/Module%20Block%20Diagram.png)\n\n### Registers\n\nThere are 16 registers, each register can be written to and then read back. Unused bits reads back as zeros in the AY-3-8910, but in the pin compatible \"almost-clone\" YM2149 all bits can be written and read back even if they're not used for any chip functions.\n\nTo write to a specific register you first write the register number to special ~Address register~, then all following reads and writes will be directed to that register until the Address register is changed.\n\n- R0 Channel A tone period - Fine (8 bit)\n- R1 Channel A tone period - Coarse (4 bit)\n- R2 Channel B tone period - Fine (8 bit)\n- R3 Channel B tone period - Coarse (4 bit)\n- R4 Channel C tone period - Fine (8 bit)\n- R5 Channel C tone period - Coarse (4 bit)\n- R6 Noise period (5 bit)\n- R7 Enables (inverted) for I/O, Noise, Tone (8 bit)\n- R8 Channel A amplitude (5 bit)\n- R9 Channel B amplitude (5 bit)\n- R10 Channel C amplitude (5 bit)\n- R11 Envelope period - Fine (8bit)\n- R12 Envelope period - Coarse (8bit)\n- R13 Envelope shape (4bit)\n- R14 Port A data (8bit)\n- R15 Port B data (8bit)\n\n## Modules\n\n### Control and clock\nThis module handles the interface towards the MCU that is controlling the AY-3-8910. It is also generating the enable signals for the other modules as well as generating the clock/16 and clock/256 used by the modules for frequencies and timings.\n\nIt is also holding the Address register.\n\nThe complexity level of this module is very low. It's bascially nothin more than a latch and 4-to-16 decoder connected to the latch. The only slighly hart to understand aspect is the quite horrible way the designers made the BDIR, BC1 and BC2 inputs. It's a mess. But it turns out one can just ignore the BC2 (and tie it high) and still have access to all the different modes.\n\n**The inputs are:**\n- DataBus - 8 bits of bi-directional data\n- \u003cspan style=\"text-decoration:overline\"\u003eReset\u003c/span\u003e - clear most registers to all zeros\n- Clock - An approx 50% duty clock input between 1 and 2.5MHz\n- A8 - Address line 8 used as an active high Chip Enable\n- \u003cspan style=\"text-decoration:overline\"\u003eA9\u003c/span\u003e - Address line 8 used as an active low Chip Enable\n- BDIR - Used togehther with BC1 to select chip functions (see below)\n- BC1 - Used together with BDIR to select chip functions (see below)\n\n| BDIR | BC1 | Action |\n| :------: | :-----: |--------|\n|0|0|Idle/Inactive|\n|0|1|Read data from register|\n|1|0|Write data to register|\n|1|1|Write data to Address register|\n\n**The outputs are:**\n- DA0..7 - 8 bits of bi-directional data\n- \u003cspan style=\"text-decoration:overline\"\u003eWrXxxxxx\u003c/span\u003e - Read signals to the registers in the other modules\n- \u003cspan style=\"text-decoration:overline\"\u003eRdXxxxxx\u003c/span\u003e - Write signals to the registers in the other modules\n- Clk/16 - The input clock divided by 16, used for frequency and timing generation in modules\n- Clk/256 - The input clock divided by 256, used for timing generation specifically in the Envelope module\n- \u003cspan style=\"text-decoration:overline\"\u003eRes\u003c/span\u003e - Inverted reset signal to modules\n- Res - Non-invertet reset signal to modules\n\n![Control Module](Images/Module-Control.png)\n\n### Tone Generator (three copies)\n#### (Registers R0/R1, R2/R3, R4/R5)\n\nThe AY-3-8910 have three of these modules which each outputs a square wave at a frequency controlled by two registers (12 bits in total).\n\nThe module have a 12 bit up-counter that is reset whenever the count value is larger than the value from the combined register value.\n\nThe square wave really should be at a 50% duty cycle, but in order to at least optimize the chip count a bit the 7474 \"divide-by-two\" IC is moved to the Mixer module, saving one full IC since each 7474 contains two separate dividers. But since the savings is so small I might move them back to the Tone Module if there's space enough on them. \n\nSince the 744040 counter used here is a Ripple Carry counter the outputs of them will not change synchronously the output of the Magnitude Comparators is ANDed with the incoming clock to not reset the counter until the second phase of the clock when all the bits have settled.\n\n**The inputs are:**\n- DA0..7 - 8 bits of bi-directional data\n- \u003cspan style=\"text-decoration:overline\"\u003eReset\u003c/span\u003e - Clear register and counter to zero\n- CLK/16 - The master clock divided by 16 \n- \u003cspan style=\"text-decoration:overline\"\u003eWrToneX-Fine\u003c/span\u003e - Latches the least sigificant 8 bits of data\n- \u003cspan style=\"text-decoration:overline\"\u003eWrToneX-Coarse\u003c/span\u003e - Latches the most significate 4 bit of data\n- \u003cspan style=\"text-decoration:overline\"\u003eRdToneX-Fine\u003c/span\u003e - Enables read-back of the least sigificant 8 bits of data\n- \u003cspan style=\"text-decoration:overline\"\u003eRdToneX-Coarse\u003c/span\u003e - Enables read-back of the most significate 4 bit of data\n\nAll signals are received from the Control \u0026 Clock module\n\n**The outputs are:**\n- Out - The generated square wave sent to the Mixer module\n\n![Tone Generator Module](Images/Module-ToneGen.png)\n\n### Noise Generator\n#### (Register R6)\n\nThe AY-3-8910 have a single noise channel that can be mixed into one or more (or none) of the tone generators.\n\nThe noise is generated by a 17 stage LSFR that is clocked by a 8-bit counter/divider that divides the clock coming into the module. \n\nThe counter and magnitude comparators are in the same configuration as in the rest of the modules, but here we only have a 8 bit counter.\n\n**The inputs are:**\n- DA0..7 - 8 bits of bi-directional data\n- \u003cspan style=\"text-decoration:overline\"\u003eReset\u003c/span\u003e - Clear register and counter to zero\n- CLK/16 - The master clock divided by 16 \n- \u003cspan style=\"text-decoration:overline\"\u003eWrNoise\u003c/span\u003e - Latches 8 bits of data\n- \u003cspan style=\"text-decoration:overline\"\u003eRdNoise\u003c/span\u003e - Enables read-back of the data\n\nAll signals are received from the Control \u0026 Clock module\n\n**The outputs are:**\n- Out - The generated single bit noise send to the Mixer module\n\n![Noise Generator Module](Images/Module-NoiseGen.png)\n\n### Mixer\n#### (Register R7)\n\nThis module handles the enabling and mixing of the three tone- , and the single noise- channels.  In the real AY-3-8910 it also handles the direction of the two 8-bit I/O ports, but this version doesn't implement the ports - just like physically smaller AY-3-8913.\n\nThe lowest three bits in the register are \u003cspan style=\"text-decoration:overline\"\u003eTone Enable\u003c/span\u003e for the three tone channels. Since they are inverted a zero in a bit means the channel is open, and a one bit is a silet channel.  When set to one the the output bit is permamently high giving the possibility to use the Amplitude settings to manually vary the analog output for a DAC-like effect.\n\nThe next three bits in the register are \u003cspan style=\"text-decoration:overline\"\u003eNoise Enables\u003c/span\u003e for the noise channel and controls whether the noise steam is injected (ORed) into the the tone stream.\n\nSo this module output three bit streams with either a permanent high level, tone only, noise only or the two ixed together.  These streams are sent into the Aplitude-modules causing the analoge output of the DACs to toggle between zero and the value set by the Amplitude generators.\n\n**The inputs are:**\n- DA0..7 - 8 bits of bi-directional data\n- \u003cspan style=\"text-decoration:overline\"\u003eReset\u003c/span\u003e - Clear register to zero\n- \u003cspan style=\"text-decoration:overline\"\u003eWrMixer\u003c/span\u003e - Latches 6 bits of data\n- \u003cspan style=\"text-decoration:overline\"\u003eRdMixer\u003c/span\u003e - Enables read-back of the data\n- ToneA - Square wave from the Tone Generator A module\n- ToneB - Square wave from the Tone Generator A module\n- ToneC - Square wave from the Tone Generator A module\n- Noise - Random pulse train from the Noise Genarator module\n\n**The outputs are:**\n- MixA - Mixed Tone A and Noise bitstream, or always high if not enabled \n- MixB - Mixed Tone B and Noise bitstream, or always high if not enabled \n- MixC - Mixed Tone B and Noise bitstream, or always high if not enabled \n\n![Mixer Module](Images/Module-Mixer.png)\n\n### Amplitude (three copies)\n#### (Register R8,R9,R10)\n\nThis is one of the simpler modules consisting of onlye the latch and a multiplexer.\n\nThe least four sigificant bits of the register holds a fixed amplitude value and is used when the fifth bit is set high. What the fifth bit iw low the amplitude value is routed from the output of the Envelope generator\n\n**The inputs are:**\n- DA0..7 - 8 bits of bi-directional data\n- \u003cspan style=\"text-decoration:overline\"\u003eReset\u003c/span\u003e - Clear register to zero\n- \u003cspan style=\"text-decoration:overline\"\u003eWrAmplitude\u003c/span\u003e - Latches 5 bits of data\n- \u003cspan style=\"text-decoration:overline\"\u003eRdAmplitude\u003c/span\u003e - Enables read-back of the data\n- EnvelopeX - 4 bit value from the Envelope generator\n\n**The outputs are:**\n- LvlX - a 4-bit value determined by the Mix-input and the Amplitude register \n\n![Mixer Module](Images/Module-Amplitude.png)\n\n### Envelope Rate  \n#### (Register R11,R12)\n\nThe Envelope Rate module is very similar to the three Tone Generator modules, except there's a 16 bit counter instead of the 12-bit the Tone Genarator uses. The input frequency is the master clock divided by 256 instead of 16 as the rest of the modules uses. This gives the envelopes a cycle rate between 8 seconds and 0.1 milliseconds.\n\n**The inputs are:**\n- DA0..7 - 8 bits of bi-directional data\n- \u003cspan style=\"text-decoration:overline\"\u003eReset\u003c/span\u003e - Clear register to zero\n- \u003cspan style=\"text-decoration:overline\"\u003eWrEnvelope-Fine\u003c/span\u003e - Latches the low byte of the rate value\n- \u003cspan style=\"text-decoration:overline\"\u003eWrEnvelope-Coarse\u003c/span\u003e - Latches the high byte of the rate value\n- \u003cspan style=\"text-decoration:overline\"\u003eRdEnvelope-Fine\u003c/span\u003e - Enables read-back of the low byte \n- \u003cspan style=\"text-decoration:overline\"\u003eRdEnvelope-Coarse\u003c/span\u003e - Enables read-back of high byte\n- CLK/256 - The master clock divided by 256 \n\n**The outputs are:**\n- ClkEnv - Clock for the Evnvelope Generator \n\n![Mixer Module](Images/Module-EnvelopeRate.png)\n\n### Envelope Shape Generator\n#### (Register R13)\n\n\u003cimg src=\"/Images/WaveForms.png\" width=300\u003e\n\n**The inputs are:**\n- DA0..7 - 8 bits of bi-directional data\n- \u003cspan style=\"text-decoration:overline\"\u003eReset\u003c/span\u003e - Clear register to zero\n- \u003cspan style=\"text-decoration:overline\"\u003eWrEnvShape\u003c/span\u003e - Latches 4 bit into the register\n- \u003cspan style=\"text-decoration:overline\"\u003eRdEnvShape\u003c/span\u003e -  Enables read-back of the register \n- ClkEnv - Clock generated by the Envelope Rate module \n\n**The outputs are:**\n- Envelope - A 4 bit value of the current level of the envelope shape controlling the Amplitude modules\n\n\n![Mixer Module](Images/Module-Envelope.png)\n\n![Mixer Module](Images/Module-Envelope-Alternate.png)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmengstr%2Fdiscrete-ay-3-8910","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmengstr%2Fdiscrete-ay-3-8910","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmengstr%2Fdiscrete-ay-3-8910/lists"}