Visit the GitHub Repo for all project artifacts and the GitHub Wiki for documentation.
Kits are available on Tindie.
AVR-based bootloader and IO card for RC2014 retrocomputer
To make the experience fit your profile, pick a username and tell us what interests you.
We found and based on your interests.
Visit the GitHub Repo for all project artifacts and the GitHub Wiki for documentation.
Kits are available on Tindie.
z80ctrl-REV4-b825d1a.hexhex - 175.04 kB - 02/09/2021 at 03:59 |
|
|
z80ram_rev2_gerber.zipZip Archive - 133.80 kB - 10/05/2020 at 02:11 |
|
|
z80ctrl_rev6_gerber.zipZip Archive - 158.35 kB - 10/05/2020 at 02:11 |
|
|
z80ctrl-iox_rev2_gerbers.zipx-zip-compressed - 165.47 kB - 01/12/2019 at 19:39 |
|
This project has been a multi-year labor of love. I haven't had much time to work on it since last year but it suits this challenge to a tee. I'm combining a retro Z80 with peripherals emulated on a modern AVR microcontroller to run CP/M, MSX software, ColecoVision games, and more. Check out the linked YouTube video for an overview and peruse the project log for the history of the project and a lot of ideas for what it can do.
I've just put the final touches on a new revision of z80ctrl, plus a new companion module that combines a Z80 CPU, 512KB bankable RAM, and and RTC on a single board.
I expect kits for the new CPU board will be sold on Tindie and z80ctrl kits will be updated to Rev 6 once the current inventory of Rev 4 boards is sold out. The timing will be up to Michael Kamprath who is selling the kits. The current Rev 3 and Rev 4 boards will continue to be supported by the firmware, and the revision to build for will be configurable via a Makefile option.
The z80ctrl plus the CPU board comprise a fully functional RC2014-compatible Z80 system in only two modules. The z80ctrl, CPU/RAM/RTC board, TMS9918 video, SN76489 sound, and ColecoVision controller boards, plus Ed Brindley's YM2149 sound board all fit in Steven Cousin's 6 slot SC112 backplane, making for quite a compact package which has everything needed to run CP/M, ColecoVision, and MSX software.
This board is intended to use the Zilog Z84C0010PEG 10MHz Z80 CPU. Other pin-compatible Z80 chips may work, but the z80ctrl can generate a clock signal up to 10MHz, so the CPU should be fast enough to handle this. The CPU is connected to the RAM and RC2014 bus. There are pullup resistors for the NMI, WAIT, BUSRQ, and INT lines to prevent false triggering. The RESET line is expected to be pulled up on the backplane.
The 512KB RAM is divided into 16 32KB banks, any of which can be mapped into the upper and lower halves of the Z80's 64KB address space. The two 4-bit bank addresses are stored in an 8-bit register accessible at I/O addresses 70-7FH. All 16 addresses are mirrors of the same register. The bank register is write-only so software must independently keep track of the current bank addresses. The lower nybble specifies the bank for the lower 32K and the upper nybble specifies the bank for the upper 32K. Therefore a value of 10H maps the first 64K of physical RAM to the Z80's 64K address space. The bank register is not initialized on power up so random banks will be selected until the z80ctrl initializes it.
The DS1302+ RTC chip is connected to the SPI signals that the z80ctrl exposes on the user lines of the RC2014 bus. The SCK, MISO, and AUXCS1 lines from the z80ctrl board are used. The MISO line handles both inbound and outbound traffic since the RTC uses a three-wire protocol instead of true SPI. When the z80ctrl wants to access the RTC, it disables SPI, asserts the AUXCS1 line, and bit-bangs the three-wire protocol using the SCK and MISO lines. The CPU is not directly connected to the RTC chip, so the z80ctrl board is required to access it. The z80ctrl exposes the RTC to the Z80 on I/O ports 00-02H. A value of 0 should be written to port 0 to select the RTC (other values may be used to select different SPI peripherals on other boards). Port 1 should be set to the address of the desired RTC register from the datasheet. The selected value can then be read or written on port 2.
All revisions of z80ctrl have a jumper that controls which I/O addresses wait states are generated for: none, all, or a configurable block of 32 addresses (00-1FH, 20-3FH, 40-7FH, 80-FFH). Unfortunately in REV3 and REV4, setting the jumper to any setting other than all addresses did not work because the wait signal was not connected to the AVR so it could not tell whether the Z80 was waiting for it to respond to an I/O request. Because of this, the AVR might try to respond to the IORQ signal when the Z80 had already moved on, resulting in I/O timing issues. Rev 6 fixes this by connecting the wait signal to the AVR.
IORQ was moved to the IO expander to make room for the WAIT signal and MREQ was moved to make room for the IO expander's interrupt signal on the...
Read more »It's been a long time since my last update. I took a break from the project for the first half of the year, and for the last few months I've been quietly working on some new features that I think are ready to announce. First, check out the video overview, then read on below to find out more.
The headline feature is a BDOS emulation layer that allows unmodified CP/M programs to seamlessly integrate with z80ctrl and access files on the SD card's FAT filesystem directly without using disk images. In addition, the z80ctrl monitor can now run .COM files directly. This means you can copy CP/M .COM programs and their associated files directly to your SD card and run them from the z80ctrl> prompt without booting into CP/M first.
In order for CP/M programs to work, z80ctrl needs to load some Z80 runtime support into memory that allows the programs to access the FAT filesystem via BDOS calls. This runtime is automatically loaded from a file called BDOS.BIN in either your root directory or the current directory. The BDOS.BIN file should be assembled using sjasm from the bdos.asm file in the examples directory.
The CP/M program will be able to transparently access any files located in the current directory when the program was launched. I plan to also add support for mounting additional directories on drives so it will be possible to access files in multiple directories at the same time, but that's not done yet.
The current status of the BDOS emulation is pretty complete. I have been able to successfully run many programs including Turbo Pascal 3.0, Microsoft BASIC-80 (MBASIC.COM), Microsoft M80 assembler, BBC BASIC, Hi-Tech C, SuperZAP file manager, WordMaster, WordStar, Zork, Catchum, Ladder and more. Currently the ZDE editor is the only program I am aware of that does not work. I still need to investigate why.
For the curious, the code for the BDOS emulation is in bdosemu.c. Credit is due to the RunCPM project for showing me that it is possible to emulate BDOS calls on a FAT filesystem and for serving as a sanity check to understand BDOS behavior when I was having trouble understanding the BDOS assembly code. However, none of my code has been copied from RunCPM.
The general concept of the emulation is that the BDOS runtime code establishes a DMA mailbox where the FCB address, DMA address, return code and other pertinent information can be exchanged between the Z80 and the z80ctrl. The Z80 initiates a BDOS command by writing to port 0xC. The z80ctrl will then pick up the command, perform the necessary FAT filesystem operations, and read or write the file or directory data at the specified DMA address in the format that CP/M expects. z80ctrl then returns control to the Z80 and the CP/M program is none the wiser that the data it requested came from a FAT filesystem.
For programs written especially for the z80ctrl, I have also provided a way to make FatFS API calls directly from Z80 code. The DMA interface code is in filedma.c, and an assembly library to access the DMA interface from the Z80 is available in filedma.asm. An example filecopy.asm program that copies a file on the FAT filesystem is also provided.
Using the FatFS API is more performant and full featured than using the BDOS emulation. Almost all FatFS API functions can be called directly from the Z80 and FAT-native features like subdirectories are therefore available. In addition, DMA transfers are not limited to 128 bytes at a time like they are when using BDOS emulation.
z80ctrl now automatically loads and executes files with a .PRG extension as a bare-metal program. I borrowed the idea of .PRG files from the C64, where the first two bytes of the file encode the load address. z80ctrl automatically loads...
Read more »z80ctrl Kits are now available on Tindie. Get 'em while they're hot!
These kits are sold by Michael Kamprath with my permission. I do not offer any warranty or guarantee of support.
Around this time last year, I started bread boarding what would become the z80ctrl. In honor of its first birthday, I've decided to take a little trip down memory lane.
I made my first commit to GitHub on January 6. It didn't do a lot back then. It had a hard-coded program that added two numbers together and then went into an infinite loop, while the AVR printed out a trace of the signals on the Z80 bus. But it was enough to prove that my design worked. A day later, I had the AVR doing serial I/O and the Z80 printing "hello, world".
The first real program it ran was the Altair Turn Key Monitor a few days later. That was followed in quick succession by a more advanced monitor, which allowed me to paste in Intel Hex programs for the Z80 to run. By January 12, I had the SD card working and could load hex files directly from it. For the next few days, the z80ctrl monitor started to take shape. The dump and fill commands made their debut and the debugging features started to take shape. The monitor from back then is still recognizable now (although with a much longer list of commands).
On January 15, I got Altair disk emulation working and achieved what felt like the Holy Grail: running CP/M. On January 21, I posted my first two videos to YouTube. One detailed the Hardware:
And the other detailed the software:
Around this time, I started getting the idea that I wanted to design my own PCB. I started work on a SBC that would include the Z80, memory, and AVR all on one board, but then I came across the RC2014. I really liked the modularity of the RC2014 backplane and the community surrounding the RC2014. So on January 20, I ordered a RC2014 Pro kit, and the next day I introduced myself to the RC2014 community. I started working on an RC2014 module in KiCad and had a first draft by January 23.
My RC2014 arrived on February 1, and to prove to myself it would work, I hooked up my breadboarded circuit to the RC2014 backplane. It worked, an after a few weeks of polishing, I finally mustered the courage to place my order from OSH Park on February 16. After 10 long days, the boards arrived, and... they didn't work. I couldn't even get the SD card to work, and I was completely stumped.
I felt so defeated by the failure of my first PCB design that I took a break from the project for two months, until two members of the RC2014 mailing list, Rodney and Jay, encouraged me keep working on it. By April 23, both had their boards working but mine was still a no go. Rodney offered to send me one of his boards to test, and when I got it, I found that it didn't work either. Finally, on May 4, I figured out that it wasn't a problem with my board at all, but two lines shorted together on the RC2014 backplane. After figuring this out, my enthusiasm returned and I made a video going over the board's design and discussing some of the problems I ran into:
I spent the next few weeks helping people on the mailing list to solve problems with their boards and making a new revision to fix the issues I had identified with the first board. Also during this time, I got serious about documenting the project and squashed a few bugs.
On May 20, I started this Hackaday page. The next few weeks were my most productive period since starting the project in January. I added many... new... sofware... features. I also designed REV3 of the board that had some major optimizations and new features.
Also during this time, I started working on my other project, TMS9918A video card, which was the first of my game boards for RC2014. I ordered both the video card and z80ctrl rev3 at the same time. When I got the rev3 boards built, they worked the first time. By mid-July, I was pretty happy with the point I had gotten the z80ctrl to, and I turned my attention to learning to code...
Read more »I've gotten MSX-BASIC to run on the RC2014 with my TMS9918A video card and my z80ctrl card emulating the MSX keyboard.
I have checked the keyboard emulation code into GitHub. It takes ASCII characters from the z80ctrl UART and converts them into MSX keyboard scan codes using a table. Currently it doesn't support some of the control keys on the MSX keyboard such as stop and the arrow keys. I will keep working on this, but it's usable as is.
The MSX-BASIC ROM can be obtained from the blueMSX emulator. Copy MSX.rom from the Machines\Shared Roms directory of your blueMSX installation to your z80ctrl SD card. Once you've copied it, load and run it from z80ctrl:
z80ctrl>clkdiv 5 z80ctrl>loadbin 0 msx.rom z80ctrl>run 0
One of the nice things about MSX-BASIC is that it has built-in graphics primitives for the TMS9918A video card, unlike, say, MBASIC on CP/M. I have used these primitives to draw an analog clock using the time pulled from the RTC chip on my z80ctrl IO expander, which is shown in the video. The BASIC source code is available on GitHub.
Currently, there is no support for MSX tape or disk drives, so you can't save your program once you have typed it in. The way I worked around this was to edit the program on my PC and then paste it into TeraTerm. I had to set a 50 ms per-character delay in order to get the program to reliably type in when pasted. A faster brute force method of saving your program once you have typed it in is to press the halt button on the z80ctrl and run
z80ctrl>savebin 8000 ffff image.bin
This will save the complete state of your BASIC interpreter so that you can load it back up the next time using and pick up where you left off. Next time, to pick up where you left off, run
z80ctrl>loadbin 0 msx.rom z80ctrl>run 0 *press the halt button* z80ctrl>loadbin 8000 image.bin z80ctrl>run
Your program should now be in exactly the same state as it was before. You can list it to verify it is there, then run it.
Here are some good references I have found for MSX-BASIC.
I've added a few examples for interfacing a character LCD with the z80ctrl IO expander board. The specific LCD I am using was purchased from Amazon. However, almost every character LCD you can find will use a standard interface based on the HD44780 chip, and my examples should work with any of them.
Since the LCD has a parallel interface to begin with, one could argue that it's a bit convoluted having the Z80 talk to the AVR over the parallel bus, which converts it to a serial signal to send to the IO expander, which converts it back into a parallel signal to send to the LCD. To that, I say: Shut up, one! It's my project and I'll do what I want!
The pinout for a character LCD is also fairly standardized. This is from the LCD I bought:
Hooking up the LCD to the IO expander board is straightforward:
Once it's hooked up, I wrote a simple MBASIC program that prints "hello, world" on the LCD:
10 GOSUB 1000 50 C=&H33:GOSUB 3000: REM RESET SEQUENCE, PART 1 60 C=&H32:GOSUB 3000: REM RESET SEQUENCE, PART 2 70 C=&H28:GOSUB 3000: REM 4-BIT MODE, 2 LINES, 5x8 CHARS 80 C=&HD:GOSUB 3000: REM DISPLAY ON, BLINKING BLOCK CURSOR 90 C=&H1:GOSUB 3000: REM CLEAR DISPLAY 100 INPUT "STRING TO PRINT"; S$ 110 GOSUB 5000 120 END 1000 REM INITIALIZE GPIO PORT 1010 OUT 0, 1: REM GPIO CHIP 1 1020 OUT 1, 0: REM DATA DIRECTION REGISTER A 1030 OUT 2, 0: REM ALL OUTPUT 1040 OUT 1, &H12: REM GPIO REGISTER A 1050 RETURN 2000 REM SEND BYTE IN C TO LCD 2010 OUT 2, &H40 OR M OR (C\16) : REM TOP NYBBLE WITH ENABLE HIGH 2020 OUT 2, M OR (C\16) : REM TOP NYBBLE WITH ENABLE LOW 2030 OUT 2, &H40 OR M OR (C AND &HF): REM BOTTOM NYBBLE WITH ENABLE HIGH 2040 OUT 2, M OR (C AND &HF): REM BOTTOM NYBBLE WITH ENABLE LOW 2050 RETURN 3000 REM SEND COMMAND IN C TO LCD 3010 M=0 3020 GOSUB 2000 3030 RETURN 4000 REM SEND CHAR IN C TO LCD 4010 M=&H10 4020 GOSUB 2000 4030 RETURN 5000 REM SEND STRING IN S$ TO LCD 5010 FOR I = 1 TO LEN(S$) 5020 C=ASC(MID$(S$,I,1)) 5030 GOSUB 4000 5040 NEXT 5050 RETURN
The BASIC program has several subroutines that illustrate how to interface the LCD:
I have also written an assembly program to retrieve the date and time from the RTC and display it on the LCD. Since it's quite long, I won't reproduce...
Read more »I've recently pushed an update to the z80ctrl repo which makes my new IO expander board accessible to the Z80.
To access these features, you'll need to pull the latest code from the Github repo, and then uncomment the IOX_BASE variables in the Makefile. After doing so, run 'make clean' and then 'make install' to rebuild and flash the new code. You can change the IOX_BASE if desired, but you must modify any code that will access the ports accordingly.
The board is exposed to the Z80 on 3 consecutive ports starting from IOX_BASE:
Here is a simple MBASIC program to flash an LED on the first GPIO port 10 times:
10 OUT 0, 1: REM select chip address 1 20 OUT 1, 0: REM select register IODIRA0 (0x00) 30 OUT 2, 0: REM set register value to 0 (all pins outputs) 40 OUT 1, &H12: REM select register GPIOA0 (0x12) 50 FOR I = 1 TO 10 60 OUT 2, 0: REM turn all pins on GPIOA off 70 FOR J = 1 TO 1000:NEXT 80 OUT 2, &HFF: REM turn all pins on GPIOA on 90 FOR J = 1 TO 1000:NEXT 100 NEXT
First, we select the IO direction register on the IO expander configured at address 1, and set all pins to outputs. Then we select the GPIO register. Within a loop, we toggle all of the pins on and then off, pausing between each transition.
Here is an MBASIC program demonstrating how to read the time from the RTC:
10 REM CONVERT VALUES FROM BCD 20 DEF FNBCD(V)=(V AND &HF0)/16*10+(V AND &HF) 30 OUT 0,0: REM SELECT RTC CHIP 40 REM READ DATE/TIME FROM RTC REGISTERS 50 OUT 1,6: YR=FNBCD(INP(2))+2000 60 OUT 1,5: MO=FNBCD(INP(2)) 70 OUT 1,4: DY=FNBCD(INP(2)) 80 OUT 1,2: HR=INP(2) 90 OUT 1,1: MI=FNBCD(INP(2)) 100 OUT 1,0: S=FNBCD(INP(2)) 110 REM HANDLE AM/PM 120 AMPM$="" 130 IF (HR AND &H40)=0 THEN 160: REM SKIP IF 24-HR FORMAT 140 IF HR AND &H20 THEN AMPM$="PM" ELSE AMPM$="AM" 150 HR=HR AND &H1F: REM GET RID OF AM/PM AND 12-HR BITS 160 HR=FNBCD(HR) 170 PRINT USING "The time is ##:##:##& on ##/##/####"; HR, MI, S, AMPM$, MO, DY, YR
First, we select the RTC device, then read the year, month, day, hour, minute, and second from the corresponding register on the chip. Next, we check to see if the 12 hour bit is set. If so, we check whether the time is currently AM or PM and then mask off those bits. Now, we convert all the values from BCD (as they are returned by the RTC) into binary so that BASIC can print them properly. Finally, we output the date and time in a standardized format.
I have completed REV4 of the z80ctrl board. This revision makes the following changes:
Adds a diode on the /WAIT line to convert it to an open drain output. This is necessary to prevent contention when other boards (such as my SN76489 sound card) need to use the /WAIT line also. If you plan to use a REV3 board with the SN76489 board, you must cut the wait trace and solder a diode in its place to prevent contention.
Updates the wait state generator to allow debugging with an external clock. Previously, z80ctrl only generated wait states for IORQ and when debugging, it single stepped the Z80's clock in software. Now it can optionally also generate wait states for MREQ so that execution of the Z80 can be paused for each memory fetch to allow debugging when the clock cannot be manually controlled. A jumper (J9) is provided to select between CLK and WAIT modes. In CLK mode, pin 20 of the AVR is connected to the CLK line on the RC2014 bus, and the z80ctrl provides the Z80's clock like it has in all previous revisions. In WAIT mode, an external clock must be used and pin 20 is instead used to enable and disable wait states for MREQs. I have not yet written the software to support this mode of operation but the REV4 board will work the same way as REV3 and earlier when the CLK jumper is shorted. Important Note: U3 is now a 74HCT02 quad NOR gate instead of a 74HCT74 dual flip-flop used on previous revisions.
Adds a jumper to optionally connect the AVR reset pin to the D15 line on the RC2014 bus, which is normally unused. This line can also optionally be connected to the I/O expander's reset pins on the new I/O expander board, allowing the I/O expanders to be reset to a known state whenever the z80ctrl is reset.
I've recently designed an I/O expander companion board for the z80ctrl that adds an RTC, up to 4 8-bit GPIO ports, and 4 SPI ports.
The board makes use of the same MCP23S17 I/O Expander used on the z80ctrl. All of the I/O expanders share the same chip select line and are addressed by a configurable 3-bit address, allowing a total of 8 I/O expanders to share a chip select line. Jumpers are provided to set the address, so up to 3 I/O expander boards can be added to the RC2014 if desired, giving a maximum of 24 8-bit GPIO ports. The I/O expander on the z80ctrl board which interfaces with the RC2014 bus is hard-coded to address 0, so only address 1 and higher should be configured for the I/O expanders on this board.
The board also contains a DS1306+ SPI RTC with a battery backup and 32 kHz crystal. This allows the AVR to keep track of the time in order to correctly timestamp files on the SD Card. It can also share the RTC over the Z80's parallel bus so that the RTC is accessible to CP/M, FUZIX, or other operating systems running on the Z80.
The board allows for up to 4 additional SPI chip selects to connect other SPI peripherals to the board. This is done by ORing the upper 4 bits of the GPIO_B port with the AUX2_CS line from the AVR. The additional chip select will only become active when both corresponding the GPIO_B line and the AUX2_CS line are set low. This way, the AVR can communciate with the I/O expander to enable the additional chip selects, but they will only become active once communication with the I/O expander is complete.
An inverter was also required because the RTC uses an active high chip select whereas most SPI peripherals use active low. Since I had 5 additional inverters in the package, I also inverted the outputs of the OR gate and exported both the active high and active low chip selects on each of the 4 SPI ports.
The KiCad design files for the board are available in the GitHub Repo and further details are provided on the GitHub Wiki.
I have updated the z80ctrl firmware to use the RTC to set the timestamp when creating new files on the SD card. The date can also be viewed and set using the new date monitor command.
I have also added ioxwrite and ioxread monitor commands that directly write or read I/O expander registers. This allows low-level configuration of each I/O expander. The commands take the address of the I/O expander configured via the jumper, and the hex address of the register that you want to interact with. Refer to the MCP23S17 datasheet for information about the specific registers. Additional high-level commands can be added to the firmware if a specific function for the I/O expanders is desired.
Many thanks to JLCPCB for sponsoring the prototypes of this board. Whether you want to manufacture my boards for your RC2014, or you need to prototype your own electronic project, JLCPCB is an excellent choice. They produce top quality PCBs for an incredibly low price and their service is fast. I routinely get 5 day or quicker turnaround on my projects, order placed to board in hand.
Visit the Board Assembly Instructions on the GitHub Wiki.
Visit the I/O Expander Page on the GitHub Wiki.
Create an account to leave a comment. Already have an account? Log In.
What do I need to do to give ROMWBW a try ?
Load an image from ROMWBW into the memory using the SD card and start it?
Could you provide an SD card image on github with the minimum tools and information such as the intro of the video ?
That would be helpful.
Hi! These boards are excellent - a friend gave me a demo a few weeks ago, and I bought kits from you for both. Both boards are assembled, but the z80ctrl board is acting weird. It sees the boot loader, and shows the z80ctrl ASCII art logo, and the z80ctrl:/> prompt. That said, I can’t type anything. No interaction at all. I’m seeing pulses from my logic probe at the connector for serial port 1 on the board, but nothing shows up in the terminal emulator. The backplane is an RC2014 Backplane Pro with the enhanced bus, and the only cards currencly plugged in are the z80ctrl and the CPU/RAM/RTC card that goes with it. The z80ctrl is rev 4, and the CPU/RAM/RTC card is rev 2. The firmware is built with only the RTC and the page base options set. The build was clean. Any ideas about what might be causing this? Thanks!
Also, the bootloader is b825d1a. I have also checked continuity between ports 4 & 5 and 14 & 15 (respectively) of the ATMEGA1284P-PU. The problem also exists whether the CPU/RAM/RTC card is plugged in or not. This ATMEGA1284P-PU from the kit didn’t appear to be new. Maybe it’s bad?
Check your terminal settings and make sure that flow control is set to none. The AVR doesn't support hardware flow control and if your terminal has flow control enabled, it won't send anything because it expects to see a DTR signal from the device, which the AVR does not have.
Wow! That was quick! I'm all set now!
Thanks so much for the quick response!
Jamie
Thanks for the z80-ctrl kit! There were no problems with the assembly.
Tell me how to work with RomWBW in 512 RAM/ROM RC2014 module? Compiled the firmware with #BANK_PORT = 0x78 disabled and BANK_BASE = 0x78 enabled. Example programm hello.hex can not load and start. From address 0x0000, ROM page is always on.
I tried to turn on the RAM bank from address 0, it does not work:
out 7C 1
out 78 20
dump 0 - show always ROM page.
I try run CP/M:
boot cpm2.dsk
But always starts RomWBW. When does the question "Boot Selection?" RomWBW does not respond to the keyboard.
How to start hello.hex form 0x0100 address and mount and start images disk?
Thanks.
Hi, I modified your project to work with w65c02, which I named '6502ctrl'. I placed the project code at https://github.com/kuwatay/6502ctrl. I designed PCB to use Arduino Mega. I could run OSI-(MS) BASIC and woz monitor with it.
Thank you for your code.
I have extra PCB. I'm happy to send you a PCB. Please contact me if you are interested in it.
Hi, I hope to adapt this project to work with a hitachi 63c09ep. Would it be hard to have a 2-phase CPU clock that ran at 3.58MHz?
Hi, am I able to use the RC2014 Raspberry PI Terminal in conjunction with the z80ctrl ?
Greetings Axel Ahlborn
z80ctrl puts its serial signals on the bus on the same pins as the SIO module, so in theory it should work with the RPi Terminal. I have never tested it though. Note: you need to remove the SIO module if you install z80ctrl because otherwise you will have two devices trying to control the same serial bus.
Check your fuse settings of the Atmel chip. The fuse for the JTAG interface must by off. The JTAG interface messes up some pin's of the ATMEGA
I'm pretty sure the makefile uses 'avrdude -P usb -c avrispmkii -p atmega1284p -U lfuse:w:0xf7:m hfuse:w:0xd6 efuse:w:0xfd' but I went and flashed that again just to be sure and it did not help. http://eleccelerator.com/fusecalc/fusecalc.php?chip=atmega1284p shows 0xd6 high fuse does not include JTAGEN
He wouldn't have gotten this far if the fuses were wrong.
I just built the Kamprath-sold rev4 board and can't get it to actually work with the companion z80ram CPU RAM RTC Board. At the monitor z80ctrl:/> prompt CLK sits steady at 5V, and when 'run' is executed it drops down to a noisy zero volts. I can run a simple pin toggling program for pin 20 and it shows up on CLK nicely on my scope, but that's it. I've re-installed the mighty 1284p bootloader with the settings given in the assembly instructions and 'make install' is able to upload the monitor. No idea if there's other issues, but I figure without CLK it's not going anywhere.
Do you have the CLK/WAIT jumper in the CLK position?
Yes. I have also tried it on 'WAIT' and in that position I get 'bus request timed out'
That jumper should always be set to CLK. Software support for the WAIT mode is not done. If you've got it set to CLK, then I'm not sure what's wrong. The clock is generated by a PWM output and should be 10MHz by default. Is your oscilloscope able to sample signals that fast? Reason I ask is some cheap scopes like the DSO nano can't go that high. You could try using the clkdiv command to set it to a much slower clock and see if works. "clkdiv 200" should output a 100 kHz clock. Are you connecting the scope directly to the clock output on the z80ctrl? Is there anything else on the bus that could be pulling it down?
(not sure why I can't reply below this one)
Even with the board removed from the backplane and powered via the USB serial adapter, there's no clock signal on the RC2014 pins or physical pin 20 of the 1284p. On both my z80ctrl and z80 RAM/ROM/RTC all pins have continuity to the CPU/RAM/MCU as they should, so I'm confident there's no solder issues.
Only way I've been able to get anything to show up on hardware pin 20 is to run a simple program which software toggles the pin.
Is it possible there's something broken with MIghty 1284p in it's current form? I'll try flashing the supplied bootloader hex file and see if that works.
Flashed the bootloader with "avrdude -P usb -c avrispmkii -p atmega1284p -U optiboot_flash_atmega1284p_UART0_115200_20000000L_B0_BIGBOOT.hex" and then ran a 'make install' to load the firmware. Same result though, no CLK.
I have a 60 MHz scope, so no issues with looking at a 10 MHz signal.
Do you have your fuse bits set appropriately? See the last bullet here: https://github.com/jblang/z80ctrl/wiki/Board-Assembly-Instructions#installing-a-bootloader
If that doesn't work, I don't know. I can't think of any reason why manually toggling the pin would work when outputting the PWM signal on it wouldn't. This is the code that generates the signal: https://github.com/jblang/z80ctrl/blob/master/firmware/bus.c#L54-L61
You could try that in a standalone program and see if it works. You'll also need to set the pin to an output:
DDRD |= (1 << 6);
I tried the suggested code. With
OCR2A = (4);
OCR2B = (4) >> 1;
I get 31.25 KHz on CLK per the scope. I have also set the fuse bits manually as suggested, but this didn't make the z80ctrl code work with regards to CLK.
Here's some info about the git commit I have:
$ git log
commit b825d1a6b06b3fab9ced50fe321f78a82c897402 (HEAD -> master, origin/master, origin/HEAD)
Author: J.B. Langston <jb.langston@gmail.com>
Date: Thu Nov 26 20:32:17 2020 -0600
Fix delay between files
commit 2394ac0e62ad55c0b558e3b5ae3f561170369bb6
Author: J.B. Langston <jb.langston@gmail.com>
Date: Thu Nov 26 20:28:11 2020 -0600
Add Xmodem prompt back
commit 466d6baf21e84658cd577b9ff4ae17ce1cf89e82
Author: J.B. Langston <jb.langston@gmail.com>
Date: Thu Nov 26 19:42:29 2020 -0600
Update graphical clock example to work with both DS1306 and DS1302
commit 45d1bc6fdd7e1e4119afcd7a0af1088aaf52f2e9
Author: J.B. Langston <jb.langston@gmail.com>
Date: Thu Nov 26 19:31:17 2020 -0600
Update RTC example to work with both DS1306 and DS1302
commit 6caf0c18aa9d184e5a779a9800fe62edf5965fb8
Author: J.B. Langston <jb.langston@gmail.com>
Date: Thu Nov 26 18:33:45 2020 -0600
Add CPU/RAM/RTC board schematic
commit cfd0b77ddb5cb2ef8eb5d371c0673b9228468312
Author: J.B. Langston <jb.langston@gmail.com>
Date: Tue Nov 24 19:01:33 2020 -0600
You have the latest commit. Do you have the right BOARD_REV set to 4 in your Makefile? Needs to match the hardware you have.
Yes.. Here's what I have set:
# Hardware revision (Important: must be set to correct value)
BOARD_REV?=4
# Bank address for z80ctrl-style banked RAM; comment out to disable support
BANK_PORT=0x78
# Base address for RomWBW-style banked RAM; comment out to disable support
# BANK_BASE=0x78
# Uncomment to enable support for SST39F0x0 flash chips on RomWBW boards
# SST_FLASH=1
# Uncomment to enable DS1306 RTC support (used on IOX board)
# DS1306_RTC=1
# Uncomment to enable DS1302 RTC support (used on CPU/RAM/RTC board)
DS1302_RTC=1
# Base address TMS9918A chip; comment out to disable support
TMS_BASE=0xBE
# Port assigned to SN76489 sound chip
SN76489_PORT=0xFF
# Base port on which to expose I/O expander card to Z80
# IOX_BASE=0x00
# Base port for MSX keyboard
#MSX_KEY_BASE=0xA9
# Current git hash
GITVERSION:= $(shell git log -1 --pretty='%h')
# MCU type and frequency
MCU?=atmega1284p
F_CPU?=20000000L
# Programmer options
PROGRAMMER?=arduino
PORT?=/dev/ttyUSB0
BAUD?=115200
AVRCC?=avr-gcc
OBJCOPY?=avr-objcopy
AVRDUDE?=avrdude
That all looks fine. Sorry, I am stumped as to what the problem could be...
When the z80ctrl is running at the serial input prompt, is CLK being generated or is this only when the 'run' command is issued? If only when 'run', is is checking for some status from the z80? I don't have a good way to test the z80 board by itself as I don't have a separate serial I/O board. My other setups are all Z180 or Z280, so they have serial on the CPU card.
It only generates the clock while run is issued. Another thing you could try is to use debug instead. That manually generates the clock by toggling the pin using normal GPIO instead of using the PWM signal. It's too slow to run complex software but it would work for testing with hello world.
You can see exactly what the run command does here: https://github.com/jblang/z80ctrl/blob/master/firmware/z80.c#L83-L134
It does a bus_release, which checks for the BUSACK signal from the Z80 to go high after it releases the BUSREQ signal: https://github.com/jblang/z80ctrl/blob/master/firmware/bus.c#L103-L123.
However, if that doesn't happen after 256 clock cycles it will time out and print a message that it did so.There are some #ifdefs there for the different board revisions because REV4 doesn't a way to quickly check the halt and reset signals so some of the logic I use there is different. I am usually developing with REV6 so it's possible I have made a mistake here, but I'm 99% sure I tested this code on REV4 before I checked it in. I will try it again once I get a chance to be sure. However, even if there is a mistake in that logic, I would still expect the clock to be started because that happens outside of any ifdefs.
On 'run 100' I see BUSACK and BUSREQ high.
I thought I might see if you had a release specific to rev4 of the hardware and found this: https://github.com/jblang/z80ctrl/releases/tag/REV4 but it won't compile with BOARD_REV=4.
The REV4 tag is for the hardware, not the firmware. The latest firmware maintains compatibility with REV3 later.
I've just tried the latest commit, b825d1a, on my REV4 board and it works fine. I'm truly baffled what could be wrong with your board. As a sanity check, I have added z80ctrl-REV4-b825d1a.hex to the downloads here on my project page. This is the exact same image I flashed to my REV4 board. Try flashing that and see if it makes any difference, though I don't see how it would.
Also, please do try the debug test I suggested. In case you missed that reply what I said was:
Another thing you could try is to use the debug command instead. That manually generates the clock by toggling the pin using normal GPIO instead of using the PWM signal. It's too slow to run complex software but it would work for testing with hello world.
Running via 'debug 100' hangs as well, as with the new firmware file. Here are some photos of my boards: https://www.matrixwide.com/wp/2021/02/troubeshooting-z80ctrl-board/
I am sure this is something very simple but I'm unable to see it. Thanks for hanging in there with me.
Here's what I get running the ctrl board without the CPU board - there's no error message:
z80ctrl:/>loadhex hello.hex
loading from hello.hex
loaded 45 bytes total from 0100-012c
z80ctrl:/>run 100
z80ctrl:/>
OK interesting. With the CPU board out, running via 'debug 100' gives 1.249 MHz on CLK. No CLK if I just use 'run 100' and with the CPU board in, no CLK either way.
I don't see anything obviously wrong with your board, but if you're seeing a clock with the CPU board out that makes me think either the CPU is bad or there is a short between the CLK line and something else somewhere on the CPU board. I would check for continuity between CLK and any other pins near it both on the CPU and the bus header.
With the CPU board out, I'm not surprised that run doesn't work, but if debug is able to produce a clock signal without the CPU that definitely seems like a fault on the CPU board.
Zooming in on the photos I see a few things on both the CPU and z80ctrl boards that could be errant solder blobs, or they could just be reflections in the flux--it's hard to tell. Getting the flux off would make it easier to tell if there are any actual solder bridges, and flux itself can be mildly conductive.
I would take a toothbrush with some isopropyl and remove the flux. It will make a sticky mess when you do, so it may take a few passes, rinsing the toothbrush in clean isopropyl between them. Once you got it mostly clean, take an old tshirt, place it over the back of the board, dampen your toothbrush in alcohol, and run it over the shirt while it's pressed against the board. The idea is to get the shirt in between the pins so it can wick up any flux/isopropyl mixture that is going to be sticky when it dries. It may take a few tries, but I've been able to get my boards pretty clean with this method.
I've cleaned the boards and don't see any solder bridges under a 10x loupe. Continuity is good on the pins near CLK. So far, I have swapped everything on the board except the 74HCT574 as I don't have a DIP version of that on hand. I'll either order one or craft an adapter for an SOIC size one I do have.
Never say never, but I see no way that the 74HCT574, or any of the logic chips for that matter, could affect the clock signal. They are not connected to it, and they are only used to set the memory bank address.
By everything, I guess that means you tested a different Z80 too?
Yes, I have a Zilog Z0840006PSC Z80.
I also swapped my backplanes. No luck with that either.
Also I tried the fill command below to test the RAM and at least starting at 0x0100 it looks good:
z80ctrl:/>dump 0100
ADDR +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F 0123456789ABCDEF
00100 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F ................
00110 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F ................
00120 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F !"#$%&'()*+,-./
00130 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F 0123456789:;<=>?
00140 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F @ABCDEFGHIJKLMNO
00150 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F PQRSTUVWXYZ[\]^_
00160 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F `abcdefghijklmno
00170 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F pqrstuvwxyz{|}~.
The CPU card has continuity for every pin on the CPU to either a logic chip or the RC2014 bus pins.
I swapped the mcp23s17-e/sp port expander. I now at least get returned to a prompt, though no expected 'hello world' output:
type help to list available commands
z80ctrl:/>bus
0009 87 busrq busack
z80ctrl:/>loadhex hello.hex
loading from hello.hex
loaded 45 bytes total from 0100-012c
z80ctrl:/>run 100
z80ctrl:/>bus
0000 02 busrq busack halt
What happens if you run `watch opfetch` followed by `debug 100`?
z80ctrl:/>loadhex hello.hex
loading from hello.hex
loaded 45 bytes total from 0100-012c
z80ctrl:/>watch opfetch
z80ctrl:/>debug 100
00100 31 ff ff 1.. ld sp, 0ffffh
00102 ff . rst 38h
00106 cd 0a 01 ... call 010ah
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
0010c c8 . ret z
00112 f7 . rst 30h
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011a f1 . pop af
0011c 11 c9 68 ..h ld de, 68c9h
00110 23 # inc hl
00110 23 # inc hl
0010a 7e ~ ld a, (hl)
0010a 7e ~ ld a, (hl)
0010c c8 . ret z
00108 01 76 7e .v~ ld bc, 7e76h
It does look like it is at least running the program, but something is weird. Every instruction is listed twice and there are some extra instructions there that shouldn't be. This is what the output is supposed to look like (done on my REV6 board). I'll double check on REV4 and make sure that I get the same output there.
z80ctrl:/>debug 100
00100 31 ff ff 1.. ld sp, 0ffffh
00103 21 1e 01 !.. ld hl, 011eh
00106 cd 0a 01 ... call 010ah
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
h0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
e0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
l0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
l0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
o0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
,0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
w0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
o0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
r0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
l0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
d0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
0010d cd 13 01 ... call 0113h
00113 f5 . push af
00114 db 10 .. in a, (10h)
00116 cb 4f .O bit 1, a
00118 28 fa (. jr z, -6
0011a f1 . pop af
0011b d3 11 .. out (11h), a
0011d c9 . ret
00110 23 # inc hl
00111 18 f7 .. jr -9
0010a 7e ~ ld a, (hl)
0010b a7 . and a
0010c c8 . ret z
00109 76 v halt
I confirmed that it works correctly on REV4 as well. It's like something with the clock is still off, or the Z80 isn't moving on to the next instruction every cycle like it should be.
You said you checked continuity on each bus line from one board to the other, but did you check for shorts between pins? At this point I'm less inclined to think there's something that's not connected, but rather that something is connected that shouldn't be. That's why I asked you to test the adjacent pins and make sure there were no shorts between them. Also check your backplane for solder bridges. When I first designed these boards I had a weird issue that took me forever to figure out where the SD card would not work when i had it plugged into the bus, but it worked fine when I took it out. It turned out I had a short between one of the SPI lines and an adjacent line on my bus. I couldn't see any solder bridges anywhere, but the continuity tester showed a short. Eventually I cut those traces around the socket where the short was occurring. I never did find the source of it-- I just don't use that socket anymore. Maybe there is a solder bridge underneath the socket where I can't see it... who knows? Anyway the moral of that story is that very unexpected things can happen and even if you believe there's no way something could happen, it always pays to test every connection very methodically.
Yeah some sort of solder bridge under a socket seems likely. I'll pull all the chips and test between pins.
I pulled the chips on both cards and found no shorts between bus pins or chip pins (except in the few places where they're supposed to be).
I'm running out of ideas. Maybe something is putting a capacitive load on the clock line. That could explain you can see a signal at lower frequencies and not higher ones, and possibly could explain the doubled instructions if it makes the clock transition too slowly.
CLK looks fine at higher speeds.
I'm picking up an HP 1630D logic analyzer tomorrow. This should help figure out what's really going on.
EDIT: Unfortunately without CLK the analyzer isn't able to capture anything other than a simple state condition. CLK is still sitting there as HIGH.
OK one final thing. I pulled the MCP23S17, stuck it on a breadboard, and ran some simple code to sequence through all 16 outputs to light LEDs. That works fine on all three of my MCP23S17. So... that was the final thing to swap and I'm out of ideas. I'll see if the tindie seller is willing to do a board swap.
Huh... I did not suspect that because of the original issue you reported was with the CLK signal, and the RAM isn't connected to the clock. Just goes to show you should never rule anything out because it seems impossible ;). I'm glad you figured it out. Everything working as it should now?
I can get hello.hex to return 'hello, world' but only if run via 'debug 100'.
For CLK, isn't there a check from the CPU before the clock is started? I tested the SRAM in my TL866 II, it failed on A0, so that could prevent the z80ctrl from talking to the CPU.
Before it starts a program, z80ctrl sets BUSREQ high and waits for BUSACK to go high. If it doesn't within 255 clock cycles it will print "bus release timed out". This happens regardless of whether you use debug or run. So I'm not sure why it's still not working when you use run. Maybe there is a problem with the clock at full speed. You could try setting "clkdiv 200" before you type run. That would cause the clock to run at 100 kHz instead of 10MHz, which should be slow enough to work if the problem is related to the clock speed.
'clkdiv 7' is as fast as I can go and still have it return 'hello, world'.
Given that you can run it at lower speeds, it makes me think there is some parasitic capacitive load on the clock line. Not sure what would cause that, but basically, there is something acting like a low pass filter on your clock line so that lower frequencies can get through and higher frequencies are either so attenuated or so distorted that the Z80 doesn't recognize it as a valid clock signal.
Looking on the scope, there's no evidence of roll-off happening, even with clkdiv set to '2'. I see some ringing and overshoot, but I'm measuring at the end of the bus and using protoboard jumpers to connect the scope probe. It's nothing that I feel would cause TTL or CMOS triggering issues.
What's interesting is that despite what clkdiv is set to, there's always a 'preamble' of 5 MHz CLK before it switches to the actual clkdiv setting.
I don't know then... have you tried with a different Z80 since fixing the memory issues?
The 5MHz signal you see is probably during the bus release phase where the code manually toggles the clock line. The clkdiv doesn't have any effect there.
I've got an old one which is probably 4 MHz I can try. I've tried that one before I swapped the SRAM so it's worth another shot. Would the RC2014 bus benefit from some termination resistance?
My pull Z80 is actually a 6 MHz part. So far, I can't make it fail, even multiple times with clkdiv = 2. I guess the kit cpu is faulty.
I'm sure that termination resistance couldn't hurt but I have never had any problems without it. My RC2014 has been super stable for the most part both with the SC112 and RC2014 pro backplanes, with the stock RC2014 boards, and with Z80ctrl running the Z80 up to 10MHz.
Huh, it's really strange that both chips had issues... maybe they got zapped with static?
Found it. RAM was flaky due to a bit of crud on the contacts. Replaced the bad jumper, and everything works. Great board. I'm glad I ordered two of them, I have a second backplane that I will bring up as soon as I get the CPU and RAM boards built for it. Thanks for the support and the wonderful board. I think you may have a second board, some kind of I/O am I right or confused?
I'm glad you got everything working and that you are enjoying the board. Yes, I have a SPI I/O expander board that adds a RTC and up to 4 8-bit GPIOs. If you look at some of the project blog entries, you can see a few examples of what it can do. I also have the game boards (video, sound, controller), but those aren't directly tied in with z80ctrl.
Error is that I see physical sector size must be 128 and the software kicks back to the monitor.
I am pretty sure the problem is not with the sector size unless you are using some other disk format. Are you trying to use the cpm2.dsk image from SIMH? If so, it should work. The disk emulation code has not changed in a very long time and I have not had any problems with it.
J.B. J4 is to the far right and J9 is to the left (CLK) but am still unable to get cpm to boot.
The behavior sounds to me like the wait state generator isn't working properly.
For U3, are you using a 74HCT02? This part changed in REV4; previously it was a 74HCT74.
[this comment has been deleted]
Which position do you have jumpered for J4? Try putting it on the far right.
[this comment has been deleted]
I'm glad you figured that out. And you're right about the typo in ihex.c. I have pushed a fix to Github. Thanks for letting me know!
[this comment has been deleted]
Do you get an error when you run loadhex, or it just doesn't have any effect?
Can you also try "fill 0 ffff asc"? It should fill the memory with values 0-FF ascending, over and over. This is a little more complex pattern that would be a better test than filling with 0, but still rule of some of the complexity of loadhex.
Fully understand - likewise!!!
At some point it would be good to have (as outlined in your possible expansion)
to 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.
Hi JB
Are you going to be adding any further work to this project?
Colin
Probably at some point, but I have been focused on other stuff lately. Is there something specific you are hoping I would work on?
Become a member to follow this project and never miss any updates
By using our website and services, you expressly agree to the placement of our performance, functionality, and advertising cookies. Learn More
I'm looking for the schematic for Rev 6. The link on the github wiki is not found:
https://github.com/jblang/z80ctrl/blob/master/hardware/z80ctrl_schematic_REV6.pdf
Any suggestions?