When you say without the auto-reset section, I think you mean the reset diode for the Z80 (D3) and not the AVR auto-reset capacitor (C7), correct? That may be something specific to the non-standard RAM board you are using; I haven't had that problem with the standard 64K RAM board I got from Spencer. Next time I place an order to Mouser, I will get the necessary parts for the RAM/ROM boards you sent me so I can check this out.
I ask about the AVR auto-reset because I actually found a problem with it last night on the first board I built. The DTR pad of the Serial 1 connector (J5) was shorted to the GND pad. The symptom was that the AVR would not automatically reset for programming (I had to hold down the reset button and let i up after I started avrdude). I'm sure it was also not good for the FTDI chip to have DTR constantly shorted; I'm surprised it didn't burn it out, frankly. I fixed it by cutting the DTR trace on either side of the GND pad, and then soldering a bodge wire from the DTR pad to the DTR side of C7.
I think I caused a manufacturing defect by running the DTR trace between the Serial 1 pin holes and the edge of the board. There was not really enough space to comfortably do this and it turns out the solder mask for the ground pin did not cover the DTR trace, so when I soldered it, I created a solder bridge between the two. I verified this on the first OSH park board I built as well as the third unbuilt board, but it is not the case on the second one that I partially built. I think the tolerance is close enough that it could vary from board to board. This doesn't seem to affect any of the boards you sent me; in fact the solder mask tolerances on those boards seem better than the ones from OSH park in general.
When I get time, I am going to update the README with (among other things) a list of known issues with the REV1 board, so if you find anything else do let me know. All the known issues at this point:
- I accidentally swapped the position of the CTS and VCC pin on the serial connectors. This doesn't affect anything unless you try to power the board from the serial connector by jumpering JP1 or JP2. You can work around it, as you found out, by crossing the CTS and VCC wires running from the FTDI adapter to the Serial connector on the board. I simply left JP1 and JP2 unpopulated on my board so it doesn't matter.
- I accidentally swapped the position of SPIA0 and SPIA1 on the 74HCT139N. As we discovered earlier, this can be fixed in software by swapping the definitions for SD_SEL and .AUX1_SEL in defines.h.
- The aforementioned problem with the DTR line in the AVR reset circuitry.
- Although it turned out not to be an issue at the 10MHz top speed of the SPI bus, the layout of the SCK track is not optimal. SCK runs to the SD card first and then back to the IO expander, whereas MISO and MOSI run to the IO expander and then to the SD card. At higher frequencies, the differences in length could cause signal skew and interfere with the operation of SPI.
- Mislabeled/mismatched values for C2 and C3, which you pointed out in the private email we exchanged. (They should both be 18 pf, at least for the crystal I used, but the value doesn't really seem critical.)
In addition to documenting these, I have checked in a new revision of the PCB to Github that fixes these problems. I probably won't bother to get another run of boards made until I have some other PCBs to order at the same time though.
Yes, the clock rate output by the AVR is determined by the settings in clk_run in bus.c. First, it is affected by the clock source bits (CS20, CS21, CS22) assigned to TCCR2B. The default value is prescaler of 1. Selecting a higher prescaler will result in a slower clock. The other values are documented in the AVR datasheet if you search for CS20. Secondly it is affected by the values assigned to OCR2A and OCR2B. The clock output is toggled on when the counter reaches OCR2A and toggled off when the counter reaches OCR2B. The counter also resets itself to 0 when it reaches OCR2A. With the default settings of 1 and 0, respectively, it toggles the Z80 clock on and off for every other AVR clock cycle (the fastest possible clock rate via PWM). Increasing the values of OCR2A and OCR2B will also result in a slower clock. To keep the duty cycle of the clock near 50%, it is necessary to maintain a ratio OCR2A+1 = 2*(OCR2B+1). When I get a chance I will work on a monitor command to make changing this easier.
My todo list at this point (just in the order they occurred to me, not necessarily the order I'll work on them):
- Monitor command to control Z80 clock rate.
- Monitor command to load and save binary files to and from memory.
- Monitor command to disassemble data in memory
- autoexec.bat file to be run by monitor at startup.
- Disk convenience commands for the monitor (erase files, create blank disk images, change directory, etc.)
- Improve Z80 debugger to decode assembly operands and output them in opfetch watch mode (mostly done; just needs more testing before checkin).
- Improve Z80 debugger to allow single stepping of individual instructions rather requiring multiple and varying steps per instruction due to the differing number of clock cycles for different instructions.
- Implement DMA for disk emulation so that the AVR will copy an entire sector of data to memory at a time instead of one byte at a time. This should speed up the disk performance dramatically. It will also require a custom CP/M BIOS so it will be a considerable effort.
- Implement pass-through timer interrupts for the Z80. This will allow more accurate timing e.g., for playing music on Ed Brindley's sound board. Due to the INT pin being on the IO expander, the minimum timing resolution will be limited, but sub-millisecond resolution should be doable. Microsecond resolution is probably not.
- Implement interrupt-driven serial with a ring buffer and software flow control (XON/XOFF). The AVR doesn't support hardware flow control, and currently it's easy to overrun the buffer by sending data too fast (e.g., via copy/paste or XMODEM).
- Implement a second serial port so that debugging can be on a separate console from Z80 program output.
- Possibly implement PS/2 keyboard interface on Serial 2 header (mutually exclusive with above, configured via compile-time or run-time configuration).
- Fix bug that causes monitor CLI to go into an infinite loop spewing z80ctrl> repeatedly when the HALT button is pressed while the Z80 is outputting something.
- Add other SPI peripherals and implement I/O port interfaces to them for the Z80. Examples: real-time clock, GPIO, 7-segment display, LCD display, etc.
- Possibly emulate other disk formats or peripherals.
- Investigate RomWBW support.
I will add this list to the README too when I update it. I would welcome suggestions for additional features (although I don't promise I will implement them myself). I would also be thrilled with pull requests, but if you're interested in working on anything, let's coordinate so we don't duplicate efforts.
Now that I have this working, I also want to build my TMS9918 video board prototype on a breadboard (I already have the parts), and if it works, have the PCB I've designed manufactured. See
https://github.com/jblang/rc9918.
Thanks again guys!