Building the S100 Computers Z80 SBC

The S100 Computers site (www.s100computers.com) has a range of new S100 bus designs and from time to time, PCB's are made available to the site community.

I ordered their Z80 Single Board Computer PCB (www.s100computers.com/My%20System%20Pages/SBC%20Z80%20Board/SBC%20Z80%20CPU%20Board.htm) when it was first made available in 2015 and it sat patiently in the pile of "to be completed" projects.  Finally, in July 2018 the construction was finally kick-started by the need for an S-100 Bus Master to help in the bring up of the new PDP11 V2 board (www.s100computers.com/My%20System%20Pages/PDP11%20V2%20Board/PDP11%20Board%20V2.htm).

The Z80 Single Board Computer project page has a pretty comprehensive set of steps for the board assembly. 

Key to this is completing and validating operation at build checkpoints before moving to the next.  I had built plenty of boards over the years and was confident in kit assembly so was pretty sure that those steps didn't apply to me....

Pity because I was wrong.  On first power up the board did absolutely nothing.

One thing is sure, debugging a board forces to you learn a lot more about the design than if it works first time.

The first problem I discovered was a bad solder joint on U10 Pin 7.  U10 is one of the wait state generators so this bad solder join would cause Z80 /WAIT to be continually asserted. 

The second was another soldering problem but this had some really interesting symptoms.

Despite the /WAIT issue being fixed, the Z80 would not clock.  There was no activity on M1, /MREQ or /INT and /HALT was not asserted by the Z80.  At first investigation, the 4MHz clock signal into the Z80 looked correct but when compared with the buffered output from the clock module, the clock was only transitioning between 5v and 2.5v, not 5v and 0v as would be expected.

Equally strange was that this would only happen with the Z80 installed on the board.  If Z80 was removed from the board then the clock was perfect.  Changing the Z80 to alternative, known good parts did not help.

Clock Trace from Oscillator and U36 Pin 4 (Good)

Clock Trace from U36 Pin 2 with Z80 installed (Bad)

The problem..... a bad solder join on the Z80 GND pin so it was floating.

My take away from this was that S-100 board ground-planes are large and they suck a lot of heat from the iron which makes bad joints a lot more likely.  Even under a microscope, the joint did not look bad but the multimeter confirmed no continuity to ground and reworking it fixed this.

After fixing the two solder joints the Z80 was now running.... activity was visible on the M1 and /MREQ lines but still no monitor prompt on the terminal.

On my board, I used the DLP-USB1232H rather than the earlier DLP-USB245M (both from DLP Design www.dlpdesign) to provide the serial interface.

The SBC design powers the DLP-USB1232H from the SBC regulated 5V supply.  It is not powered by the USB host.  The effect of this is that there is some time required after the S100 Bus Power is applied before the DLP-USB1232H is powered up and has established a connection with the PC host.  This wasn’t my initial problem but it is something to be aware of.  If using the USB serial connection, you will need to press reset on your S100 motherboard after power is applied to get power on messages to appear.

After some research on the DLP-USB1232H I discovered the following: 

  • The onboard FTDI chip is the FT2232H.
  • The FT2232H provides two ports for connection by the USB host.
  • Only PORTA is used on the DLP-USB1232H in the 245 FIFO mode as used on the Z80 SBC.
  • There is a Windows utility called FTPROG (available from www.ftdichip.com/Support/Utilities.htm#FT_PROG) that allows the configuration of the FT2232H to be adjusted.
  • The following configuration is required to work with the SBC hardware (245FIFO) and to appear as a COM port on the USB Host for connection by applications such as PUTTY or TERRATERM:
    • Hardware Specific/Port_A/Hardware = 245FIFO
    • Hardware Specific/Port_A/Driver = Virtual COM Port

To update the configuration without relying on S100 Bus Power:

  • Remove the DLP-USB1232H from the SBC.
  • Use a jumper to connect pins 8 (EXTVCC) and 9 (PORTVCC).
  • Connect the USB cable and run FTPROG to adjust the configuration.
  • Remove the jumper when done.
  • Reinstall the DLP-USB1232H in the SBC.

After reconfiguration and restart..... the Z80 appeared to be running but still nothing on the terminal, even after S100 Bus reset.

As a builder of Z80 projects, one of the most useful tools you can have is the Tauntek Z80 ICE (www.tauntek.com/z80-in-circuit-emulator.htm).

With the ICE installed in place of the onboard Z80, it is possible to read and write memory and IO ports, perform memory tests and to step through executing code.  It was this last feature, stepping through code that helped solve my problem.

The cold boot code in the Z80 Monitor for the board is as follows:

COLD: 

; LD A,'#' ;For quick hardware diagnostic test

; OUT (S100_CONSOL_OUT),A ;Force a "#" on the CRT if ROM access is active

; OUT (USB_DATA),A ;Force a "#" on the CRT if ROM access is active


CALL INIT_LBA ;Zero in LBA paramaters after a reset


BEGIN: ;Can use the next 3 lines initially to debug hardware

DI ;No interrupts

XOR A ;SET INTERUPT TO PAGE 0H

LD I,A ;Z80 Interrupt page 0

OUT (SW_TMAX),A ;Make sure TMA0*,TMA1*,TMA2* & TMA3* S100 lines are high on V2 SMB


SETUP_STACK:

LD SP,AHEAD-4 ;SETUP A FAKE STACK

JP MEMSZ1 ;RETURNS WITH TOP OF RAM IN [HL]

DW AHEAD ;A Return opcode will pick up this address

AHEAD: LD SP,HL ;[HL] CONTAINS TOP OF RAM - WORK AREA


PUSH HL

POP IX ;Store stack pointer for below in [IX]
 

When I stepped through I could see the call to INIT_LBA jumping to the correct code but things went wrong on the RET and the Z80 would execute an RST and jump to address 0x0038.

It was obvious why when looking at the code and understanding how the SBC hardware works.

  • The SBC has a ROM in the memory block 0xE000 to 0xFFFF.
  • The Z80 default stack pointer is 0xFFFF if not initialized.
  • The call to INIT_LBA would push the return address onto the stack at bytes 0xFFFE and 0xFFFF.
  • When executing the RET from INIT_LBA the Z80 would take the return address from 0xFFFE and 0xFFFF.
  • Because these addresses are ROM on the SBC the value returned is not the pushed return address and will be what is in these ROM locations.
  • The Z80 SBC Monitor does not completely fill the 0xE000 to 0xFFFF address block so bytes 0xFFFE and 0xFFFF will depend on your programmer. In my case they were set to 0xFF.
  • The RET at the end of LBA_INIT would receive 0xFFFF as the return address.
  • Address 0xFFFF contained the byte 0xFF which is the Z80 op-code for RST 0x38.
  • The Z80 would jump to address 0x0038.
  • Address 0x0038 is RAM in the SBC. At this point, the contents would be unknown.
  • The Z80 proceeds to execute “random” op-codes from RAM and disappears into the weeds….

So the cause was that the stack pointer had not been initialized prior to the call to INIT_LBA in the SBC Monitor code.

As of 22 July 2018 there is an updated SBC Monitor available (www.s100computers.com/My%20System%20Pages/SBC%20Z80%20Board/SBC%20Z80%20CPU%20Board.htm) which fixes this by removing the LBA_INIT subroutine, removes the call to LBA_INIT and inserts the code from LBA_INIT into the COLD boot subroutine.  This certainly works.  My approach was to relocate the call to LBA_INIT until after the stack pointer has been initialized and keep the IDE functions intact.

With the monitor changes in place, the S100 Computers Z80 SBC works well.

A fun and educational experience.

On to the PDP11…..

 

Powered by Easytagcloud v2.1

Contact Andrew Quinn

jaquinn@ihug.co.nz http://twitter.com/jaquinn