Close

Supporting Other Software Builds

A project log for 3-Chip Z80 Design

Combining a Z80 retro design with a modern PSoC CPU.

land-boardscomland-boards.com 10/20/2019 at 13:110 Comments

I want to be able to support any software build I find "out there". I started with Grant Searle's 9-chip Z80 design and got that working well.

The next step is to make it easy to add other builds. I could just spawn a new PSoC project but that means any improvements to the basic code itself need to get propagated into the previous builds and that's painful.

Instead, I added conditional compilation using #define, #ifdef to select the different options.

Here's how it's layed out. I put all of the conditional directives into one single file, Hardware_Config.h. This file breaks into separate sections.

The first section contains global hardware #defines. These map to the hardware used on the card itself. If there's no front panel it gets removed from the compilation. Same for the expansion MCP23017 I2C expander.

// Global choices based on hardware used/not used
// To include the function comment out the undef and use the include
//#undef USING_FRONT_PANEL        // Assume no front panel
#define USING_FRONT_PANEL     // Use front panel
//#undef USING_EXP_MCCP23017      // Assume no MCP23017 I2C I/O expansion part
#define USING_EXP_MCCP23017   // Use MCP23017 I2C I/O expansion part

 The next section is a set of #undef for the hardware that has been emulated. For now, this is the SIO which works and the PIO which is a work in progress. This is where new emulation would be added. They are specifically included (undoing then undef) if they are in the software build used.

// These are the Z80 peripherals
// Assume none of the supported I/O peripheral chips are used
// They are included in the specific builds if the build software uses them
#undef USING_PIO
#undef USING_SIO

The next section defines which software build is being used. So far, only Grant's 9-chip software is included. Only one image can be selected at a time. To add another build #undef the other builds and #define the new build.

// Select the build here. 
//  Only 1 build at a time is supported.
//  All other builds are set to undef
//#undef GRANT_9_CHIP_Z80
#define GRANT_9_CHIP_Z80

 The next section is specific to the software build itself. This is the values for Grant's 9-chip design. Similar sections need to be added for new builds. This breaks down into two sections. The first is the memory map of the program and the second is the I/O space memory map.

// defines for building Grant Searle's 9-chip Z80 design
#ifdef GRANT_9_CHIP_Z80
    #define MONITOR_START       0x00000000      // EEPROM loads to address 0
    #define MONITOR_LENGTH      0x00004000      // 16K build
    // I/O Space Address Map follow
    #define USING_SIO
        #define SIOA_D              0x00
        #define SIOA_C              0x02
        #define SIOB_D              0x01
        #define SIOB_C              0x03
    #ifdef USING_FRONT_PANEL
        #define FR_PNL_IO_LO        0x18    // decimal 24
        #define FR_PNL_IO_LO_MID    0x19    // decimal 25
        #define FR_PNL_IO_HI_MID    0x1A    // decimal 26
        #define FR_PNL_IO_HI        0x1B    // decimal 27
    #endif
    #ifdef USING_EXP_MCCP23017
        #define PIOA_D              0x20
        #define PIOA_C              0x22
        #define PIOB_D              0x21
        #define PIOB_C              0x23
    #endif
#endif

Notice that the SIO uses a #define which undos the previous #undef. But, the Front Panel was a global value set at the start section.

Adding in Support for Grant's 7-Chip Build

Grant has a build with 7-chips. It uses less memory space for the program. Grant's 9-chip design has an 8K monitor and an 8K BASIC leaving 48K of RAM for programs. Grant's 7-chip design has an 8K ROM which just has BASIC (no monitor or CP/M support). 

Let's make the changes/additions to the config file to support Grant's 7-Chip build.

The first complication is that Grant's 7-Chip build uses a 6850 UART in place of the SIO. We don't currently have an emulator for the 6850, but let's ignore that for the moment. The 6850 UART is much simpler to emulate than the SIO chip since it only has a single control and single status register so it should be easy to emulate the part.

For now, let's just find the address map for Grant's 7-chip design.  The 6850 has three chip select lines and one address select line. Here's the piece of Grant's schematic which has the Z80 and 68B50 UART.

From this we can see that:

M1* determines if the Z80 is doing an I/O operation or an interrupt acknowledge. This is set up to not do interrupt acknowledgements from the Z80 peripheral. This makes sense since the 6850 is a 6800 family member and doesn't do interrupts in the Z80 style where the peripheral chip drives the Interrupt vector.  At first glance this implies that Grant's code must be polled instead of interrupt driven. However, Grant hooks up the IRQ* line to the Z80 INT* line. So he may be using the default vector of 0xFF that the Z80 uses when there's no interrupt acknowledgement. We'll have to look at his code closer to see. 

Grant's memory map leaves off quite a few address lines so it's necessary to look into his memory map to see what addresses he uses for the 6850. From Grant's page:

I/O Map

00-7F   Free (128 input and 128 output ports)
80-81   SERIAL INTERFACE (minimally decoded, actually covers locations 80 to BF)
C0-FF  Free (64 input and 64 output ports)

So this is relatively simple and matches the schematic (of course, since Grant is careful in his documentation). 

First, let's start assuming we are not using the 6850 (since it is software specific):

// These are the Z80 peripherals
// Assume none of the supported I/O peripheral chips are used
// They are included in the specific builds if the build software uses them
#undef USING_PIO
#undef USING_SIO
#undef USING_6850

Then let's #undef the 9-chip design and add a build option for the 7-chip version of the software: 

// Select the build here. 
//  Only 1 build at a time is supported.
//  All other builds are set to undef
//#undef GRANT_9_CHIP_Z80
//#define GRANT_9_CHIP_Z80
#define GRANT_7_CHIP_Z80

 Next, clone the 9-chip specifics and modify them for the 7-chip build. 

Grant's Memory Map (program space) for the Z80 is:

Memory Map

0000-1FFF   8K ROM
2000-FFFF   RAM (56K)

The 6850 Register Select line is connected to the CPU A0 line. The data sheet shows:

So address 0x80 is the control/status address and 0x81 is the data registers.

The #define block looks like this:

// defines for building Grant Searle's 7-chip Z80 design
// http://zx80.netai.net/grant/z80/SimpleZ80.htm
#ifdef GRANT_7_CHIP_Z80
    #define MONITOR_START       0x00000000      // EEPROM loads to address 0
    #define MONITOR_LENGTH      0x00002000      // 8K build
    // I/O Space Address Map follow
    #define USING_6850
        #define M6850_C              0x80       // Control/Status register
        #define M6850_D              0x81       // Data
    #ifdef USING_FRONT_PANEL
        #define FR_PNL_IO_LO        0x18    // decimal 24
        #define FR_PNL_IO_LO_MID    0x19    // decimal 25
        #define FR_PNL_IO_HI_MID    0x1A    // decimal 26
        #define FR_PNL_IO_HI        0x1B    // decimal 27
    #endif
    #ifdef USING_EXP_MCCP23017
        #define PIOA_D              0x20
        #define PIOA_C              0x22
        #define PIOB_D              0x21
        #define PIOB_C              0x23
    #endif
#endif

This builds in PSOC Creator but we are missing two pieces. The first is the new ROM image. The second is the 6850 emulator. We'll do these two in following logs but for now we've added the basic pieces we need to have multiple builds and haven't broken the 9-chip design software build.

Discussions