Followed the datasheet and still, I cannot write even a single bit into the AT28C256 EEPROM I searched online and found everyone having the same problem was trying to make a homebrew computer, either Z80, 6502 or 8088. So I'm the latest victim in #retrocomputing ? 🤣
The general conclusion seems to be that there's either a hidden timing issue somewhere (but I don't have a 32-channel logic analyzer to spot it...), or the chips are Shenzhen counterfeit... .
And now here's the Eureka moment! In the AT28C256 datasheet I've just noticed this humble and inconspicuous line.
> All command sequences must conform to the PAGE WRITE timing specifications.
Unlocking the chip requires a PAGE WRITE timing sequence, but I was doing all the debugging based on the more commonly used BYTE WRITE timing sequence! 😱
I just improved the timing up to the datasheet's standard for page write, but I'm still unable to write a single byte and keep getting 0xFF, perhaps the chips I got from two different vendors actually were coming from the same upstream, and are all fake?! 😡😡
1. Get some more chips directly from Microchip.
2. Use the logic analyzer to probe every single pin...
2. Use the logic analyzer to probe every single pin... ✅
Case closed! Original chips are real and working. But two jumper wires on the address bus were broken! When I was trying to check them on the scope, the probe would bend and reconnect them
Lesson learned: Do NOT attempt to debug a parallel bus without a logic analyzer (if not possible, even downclocking the bus and using a program to sample from devboard GPIOs may still be better than a scope along), or you'll waste days of time!
I've just written the first test program in Z80 assembly. I hope it would blink some LEDs after I finish building the I/O logic on breadboards tomorrow... #retrocomputing
Using the data bus to light the LED when there's no I/O controller (yet) turned out to be a bad idea. I modified the program to poke the high memory address instead. #retrocomputing
After running the initial test, it's time to add proper address decoding logic. Before doing so, I decided to fully buffer the address/data bus to make them robust.
Now both buses have been fully buffered, but I'm now running out of wires... Need to order several hundreds more to build the decoder... 🤣 #retrocomputing
The address decoding logic is complete! Now my Z80 computer has 16 KiB of RAM (but untested). A latch is added to the data bus as a temporary I/O interface.Time to create a console by bitbanging some UART traffic for further development...
Found two bugs that prevented memory access. I've written down the wrong truth table that was responsible for the missing chip select, and I discovered an ENABLE pin was floating, that explained the random results.
But now the memtest routine would reports ~500 bytes of good RAM, then it suddenly freezes the Z80 CPU mysteriously . No M1 opcode fetch, no memory refresh, nothing at all...
Well, at least 500 bytes are more than enough to write a better diagnostic program.
My breadboard Z80 was freezing randomly after reading ~500 bytes of RAM. I probed the power supply, and saw THIS... No wonder why the system was crashing.
I knew breadboards have all sorts of problems, but you can never imagine how crazy it can become until you've built a computer on it. 🤣
Added some capacitors. Now the random crashes have disappeared. Decoupling is serious business!
Meanwhile, I'm now having predictable crashes instead... Must be another bug in my decoder.
I saw my Z80 was still glitching, and I found the NMI input was floating... Hard to keep track of every single pin on a breadboard. Presumably, spurious interrupts messed it up, simply pull it high has solved the problem.
I polished the test a bit as well. Finally, my Z80 has passed the complete memtest, full 16 KiB (*) of RAM is now operational! Next step is adding a TMS9928A video output.
(*) it only shows 16368 bytes, 16 bytes of RAM was reserved for the test routine itself.
The TI TMS9918/28 video chip needs a 10.738 MHz (± 0.005 MHz) clock... Those weird NTSC frequency multiples from the analog days. Good luck finding a crystal of this frequency in the toolbox nowadays (it's #retrocomputing, no PLL/DSS synthesizer cheating ). I was able to find some vendors of this frequency but I doubt it has stocked for immediate shipping. Easier to just buy a 21.477 MHz crystal with a CD4017 counter to divide it by two.
I spent some time moving all the vintage chips to ESD-safe tubes for the peace of mind in future handling.
Most of them are older than me, here they are,
* TMS9928 video chip, NMOS, from Texas Instruments, made in 1982.
* Z80 CPU, CMOS 6 MHz version, 1999; PIO, 2002; SIO, revision 2, 1998, CTC, 1986.
* Yamaha 2608 sound chip w/ YM3016 DAC, 1993.
* M5M5165P 16-KiB SRAM, from Mitsubishi, production date unclear, but possibly from mid-80s before the Japaneses economic bubble burst.
I'm still waiting for more parts needed for the video chip, meanwhile it's a good idea to draw a schematic for the existing breadboard... And it seems drawing a simple buffered address/data bus already requires one to click the mouse 😵 few hundreds times and has taken 2/3 of an entire page. Time to reconsider to purchasing a trackball?
I'm reviewing the datasheet of YM2608 as I cannot understand what's the huge DIP-64 package doing here.
And... The SOUND CHIP has two groups of 8-pin GPIOs?! WTF?
So I can throw my Z80-PIO away now?
Well, I guess the decision was to reduce system integration costs and make it easier to add things like an audio interface to music synthesizers. But still looks unusual.
tired: control LEDs with Arudino
retired: flashing LEDs with a Z80.
inspired: flashing LEDs with a Yamaha sound chip.
Not dead yet, my breadboard Z80 project is still ongoing. Now I'm trying to code some example programs, and struggling to learn the proper way to crunch 24-bit numbers.
Z80 does not have an effective (base+offset) nor (pointer+offset) addressing mode. Even "uint16_t tmp = array[i]" is a challenge to C compiler in itself. In asm, to walk through a bunch of numbers, one has to arrange the order of computation carefully so that the crunching and looping can be done simultaneously. 🤔🤔🤔
I'm about to finish the first program for my #Z80 computer - a π calculating program, this naive algorithm based on arctan() series should be able to calculate π to 1000 digits and more. I'm not a 1337 assembly writer, the subroutine takes ~3500000 T-states (~1 second) to calculate a ONE decimal digit. I also need to implement a ring-buffer to handle repeated carry if the digit exceeds 10, so the actual program will be even slower, well, better to make it work first...
I loaded the π program to my breadboard #Z80, and the computer gives a different result on each run, none is correct... It must mean there's a hardware-level memory issue that corrupted some bytes, then got amplified by the algorithm. Let's hope the issue has a direct fix and not due to the signal integrity of the breadboard wiring, or I have to start making PCBs...
My π program accomplished its intended purpose at least, "uncover hardware issues", so it's a "successive failure"?
Okay, the breadboard #Z80 is now completely impossible to debug. Even my design was divided to different functional blocks, with the board at the center being the "backplane", but now it's essentially unreachable for any probes as the bus wires are everywhere. Now I understand why was the S-100 bus invented, which meant to solve precisely this problem... Time to rewire everything to let the bus spreads vertically, not horizontally...
And no PCBs yet as the design is not complete.
“Once, while hacking on a dedicated #Z80 system, I was testing code by blowing EPROMs and plugging them in the system, then seeing what happened. One time, I plugged one in backwards. I only discovered that after I realized that Intel didn't put power-on lights under the quartz windows on the tops of their EPROMs — the die was glowing white-hot. Amazingly, the EPROM worked fine [...] Of course, this is because the magic smoke didn't get let out.” - Jay Maynard
I suddenly noticed the logic analyzer already includes a Z80 decoder in it 🤩 Great for debugging. #retrocomputing
Thanks the Z80 decoder module in the logic analyzer, I was finally able to identify the true problem within a minute: the Write signal to the RAM was unconnected, and CPU always reads 0xFF.
Finally, I probably found the culprit of memory corruption: a timing violation.
A write operation to SRAM can be initialized by pulling WRITE low, then ENABLE the chip, so I thought it's not necessary disable the output via OE before writing. But this mode works if and only if WRITE comes before ENABLE.
The #Z80 CPU (and probably most others) always set an address and ENABLE the SRAM chip first, if OE is not pulled high at this point, it's an illegal operation, the result is undefined.
After fixing the "memory write" timing violation, my breadboard #Z80 completed the π calculation program flawlessly, and was able to calculate π to 500+ digits.
In the troubleshooting process, boards were rewired based on a "bus-centric" approach - always use a row of rightmost boards as the system bus, so new modules can be daisy-chained, and the bus can be probed easily.
The Arduino board is only used as a PSU & USB serial, no cheating here.
TODO: in-system EEPROM programmer, video.
Once I connect the in-system programmer to the system bus, the #Z80 computer would start acting up. But the strangest problem is, even if the 74xx595 bus driver on the programmer is disabled (essentially disconnected from the bus), the programmer circuit still interferes with the Z80. The interference only stops if I unplug the 595 chips... Weird. If it's crosstalk or reflection, the problem should still exhibit itself after unplugging the chip and leaving the wiring in-place, but no?
Breadboard #Z80 status update: it appears that I've fried my EEPROM due to bus contention while trying to troubleshoot the in-system programmer.... Now it always reads 0x00 regardless of control signals, as if all the outputs are in high-impedance (well, it is, and it's permanent!). Perhaps the output stage is fried, but more likely, I killed the ENABLE signal, which is backed by a transistor, must be a lot of current here... On the bright side, programmer should be operational now.
Breadboard #Z80 status update: there are still some minor glitches, but the wirewrapped in-system programmer is now operational. It uses DMA to access and reprogram the EEPROM directly, on-the-fly. Now I'm able to reprogram the computer without turning the power off, physically swapping the EEPROM or changing wires. The ZIF socket also protects the EEPROM pins from damage.
The noise level on the lines is slighter stronger after this modification, but so far still within tolerance.
#FailOfTheWeek TI TMS9918/28 video chip uses a 10.738 MHz clock from the analog days, which is just awkward today, PLL/DDS is cheating, easier to use a 21.477 MHz crystal with a CD4017 to divide it by two.
And here's my epic fail: I've assumed all 40xx/74xx were the same, and forgotten the speed here is 21 MHz! So I ordered random CD4017s, and only to discover today that they would cease to work above 5 MHz
Only the HCT family can handle that well.
The proper 74HCT4017 divider I wanted for generating the video clock is still on its way. But sometimes, one can just be a bit creative to arrange some ad-hoc solutions before the proper parts arrive. 🤔
One can make a divide-by-2 counter from a D flip-flop, and a flip-flop can be made from NAND gates, problem solved!
Now I can continue building the video output for my breadboard #Z80.
#retrocomputing Started routing the PCB of my #Z80 computer in my spare time, still has a long way to go. It's only the CPU board, the memory board probably needs as much work as this one. The bright side is, the routing is not that difficult as I initially thought, all it needs was some pinout adjustments.
@EdS Cool, with this ICE, one can debug everything . While I don't feel that I need it for now, but I'll definitely add it to my toolbox. Thanks.
@unused0 I'm seriously considering to purchase some wirewrapping tools. It's not the first time I was suggested to construct a wirewrap project. If bad connections and parasitic capacitance on the breadboards become intolerable, I guess I'll take this route.
@rick_777 @unused0 These are useful but they only work if your connections are arranged in a "nice" order, which is something I don't have... Now I'm rewiring the boards as I mentioned here: https://cybre.space/@niconiconi/102111574074339521
...so that's why we don't have circular microchips; there's not just plugging them backwards... we could have dozens of ways to plug them wrong! 😅
@rick_777 It would also be a nightmare for PCB designers and automatic pick-and-place machines. But depending on how you see them, in fact there are circular ones. Just look at this Soviet NMOS chip. But ofc the pins are still rectangular.
The circular shape is the least disturbing thing on that.
Where's the plastic? Why on Earth... I can't even...
🤢 This is like watching an HR Giger horror movie but with electronics.
Now I feel the need to bath and scrub thoroughly. 😰
@ghost Yes, it's in decimal. I know it's not usual, but it's easier to reuse the existing binary-to-ASCII DEC routine than writing a new hexadecimal one in assembly...
> programmers who can not provide some kind of f^%$g compatibility
well, on the other hand, if compatibility is retained, people would say "programmers who can not get rid of those kind of f^%$g legacy garbage".
@yrabbit IMHO, I believe in additional to the "never break userspace" princple, which is crucial, we also need to have a group of people that moves fast and breaks the API every 6 months, whether justified or not, to foster innovation, and it is one of the reason of being FOSS.
> start from scratch, call this language the name of another snake,
Still waiting for Perl 6.
@yrabbit I have a few boards sitting in my cupboard but I've never used them... I think I need to do a few test runs to figure out a way to accurately align both layers of the board.
@niconiconi you should get your Z80 running Z80 BBC Basic. https://www.osnews.com/story/130145/r-t-russells-z80-bbc-basic-is-now-open-source/
@yrabbit Routing on single-layer is kind of like low-level programming. Writing a macro and expanding the code to a hundred times of repetition is always an option in desperate, just like adding a dozen of brute-force jumpers on-board. But a true guru can max out the last remaining system resources, or board space...
the mastodon instance at cybre.space is retiring
see the end-of-life plan for details: https://cybre.space/~chr/cybre-space-eol