Tool to create the memory decoder bit map
This commit is contained in:
2
software/READ.ME
Normal file
2
software/READ.ME
Normal file
@@ -0,0 +1,2 @@
|
||||
Please see the zSoft repository for the main software components of the tranZPUter/tranZPUterSW. This tree contains software tools to aid
|
||||
in the development and configuration of the tranZPUter only.
|
||||
121
software/src/tools/Makefile
Normal file
121
software/src/tools/Makefile
Normal file
@@ -0,0 +1,121 @@
|
||||
#########################################################################################################
|
||||
##
|
||||
## Name: Makefile
|
||||
## Created: May 2020
|
||||
## Author(s): Philip Smart
|
||||
## Description: Helper tools for the MZ80A tranZPUter / tranZPUterSW upgrades.
|
||||
## This makefile builds tools written in C which help with building/setting up the
|
||||
## tranZPUter/tranZPUterSW and configuration images.
|
||||
##
|
||||
## Credits:
|
||||
## Copyright: (c) 2020 Philip Smart <philip.smart@net2net.org>
|
||||
##
|
||||
## History: May 2020 - Initial Makefile creation
|
||||
##
|
||||
## Notes:
|
||||
##
|
||||
#########################################################################################################
|
||||
## This source file is free software: you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published
|
||||
## by the Free Software Foundation, either version 3 of the License, or
|
||||
## (at your option) any later version.
|
||||
##
|
||||
## This source file is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#########################################################################################################
|
||||
BASE =
|
||||
CC = $(BASE)gcc
|
||||
LD = $(BASE)gcc
|
||||
AS = $(BASE)as
|
||||
CP = $(BASE)objcopy
|
||||
DUMP = $(BASE)objdump
|
||||
|
||||
BASEDIR = ../../..
|
||||
SWDIR = $(BASEDIR)/software/src
|
||||
INSTALLDIR = $(BASEDIR)/software/tools
|
||||
|
||||
# we use printf from here
|
||||
COMMON_DIR = $(SWDIR)/common
|
||||
INCLUDE_DIR = $(SWDIR)/include
|
||||
|
||||
# Working directory to build object files.
|
||||
BUILD_DIR = tools_obj
|
||||
|
||||
COMMON_SRC =
|
||||
COMMON_OBJ = $(patsubst $(COMMON_DIR)/%.c,$(BUILD_DIR)/%.o,$(COMMON_SRC))
|
||||
|
||||
FLASHMMCFG_PRJ = flashmmcfg
|
||||
FLASHMMCFG_SRC = flashmmcfg.c
|
||||
FLASHMMCFG_OBJ = $(COMMON_OBJ) $(patsubst %.c,$(BUILD_DIR)/%.o,$(FLASHMMCFG_SRC))
|
||||
|
||||
# Commandline options for each tool.
|
||||
OPTS =
|
||||
|
||||
CFLAGS = -I. -I$(COMMON_DIR) -I$(INCLUDE_DIR) -O3
|
||||
# Enable debug output.
|
||||
OFLAGS += -DDEBUG
|
||||
LFLAGS = -Wl,--gc-sections -Wl,--relax -Os
|
||||
#
|
||||
# Assembler flags.
|
||||
ASFLAGS = -I. -I$(COMMON_DIR) -I$(INCLUDE_DIR) -I$(STARTUP_DIR)
|
||||
#
|
||||
|
||||
# Our target.
|
||||
all: clean $(BUILD_DIR) $(FLASHMMCFG_PRJ)
|
||||
|
||||
install: all
|
||||
cp $(FLASHMMCFG_PRJ) $(INSTALLDIR)
|
||||
|
||||
clean:
|
||||
rm -f $(BUILD_DIR)/*.o *.hex *.lss *.elf *.map *.lst *.srec *~ */*.o *.bin *.srec *.dmp *.vhd *.rpt $(FLASHMMCFG_PRJ)
|
||||
|
||||
$(FLASHMMCFG_PRJ): $(FLASHMMCFG_PRJ).elf $(FLASHMMCFG_PRJ).dmp $(FLASHMMCFG_PRJ).lss
|
||||
|
||||
# Convert ELF binary to bin file.
|
||||
%.bin: %.elf
|
||||
@$(CP) -O binary $< $@
|
||||
|
||||
# Convert ELF to srec format for serial upload.
|
||||
%.srec: %.elf
|
||||
@$(CP) -O srec $< $@
|
||||
|
||||
%.dmp: %.elf
|
||||
@$(DUMP) -x $< >>$@
|
||||
|
||||
# Create extended listing file from ELF output file.
|
||||
# testing: option -C
|
||||
%.lss: %.elf
|
||||
@echo
|
||||
@$(DUMP) -h -S -C $< > $@
|
||||
|
||||
$(FLASHMMCFG_PRJ): $(FLASHMMCFG_OBJ)
|
||||
$(CC) $(LFLAGS) $(FLASHMMCFG_OBJ) -o $@ $(LIBS)
|
||||
chmod +x $@
|
||||
|
||||
# Link - this produces an ELF binary.
|
||||
$(FLASHMMCFG_PRJ).elf: $(FLASHMMCFG_OBJ)
|
||||
$(LD) $(LFLAGS) -o $@ $+ $(LIBS)
|
||||
|
||||
$(BUILD_DIR)/%.o: %.c Makefile
|
||||
$(CC) $(CFLAGS) $(OFLAGS) -o $@ -c $<
|
||||
|
||||
$(BUILD_DIR)/%.o: %.cpp Makefile
|
||||
$(CC) $(CFLAGS) $(OFLAGS) -o $@ -c $<
|
||||
|
||||
$(BUILD_DIR)/%.o: $(COMMON_DIR)/%.c Makefile
|
||||
$(CC) $(CFLAGS) $(OFLAGS) -o $@ -c $<
|
||||
|
||||
$(BUILD_DIR)/%.o: %.s
|
||||
$(AS) $(ASFLAGS) -o $@ $<
|
||||
|
||||
$(BUILD_DIR)/%.o: $(STARTUP_DIR)/%.s
|
||||
$(AS) $(ASFLAGS) -o $@ $<
|
||||
|
||||
$(BUILD_DIR):
|
||||
mkdir $(BUILD_DIR)
|
||||
|
||||
501
software/src/tools/flashmmcfg.c
Normal file
501
software/src/tools/flashmmcfg.c
Normal file
@@ -0,0 +1,501 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Name: flashmmcfg.c
|
||||
// Created: May 2020
|
||||
// Author(s): Philip Smart
|
||||
// Description: tranZPUter SW Memory Map Configuration Tool
|
||||
// This program creates the 512KB array which forms the tranZPUterSW memory decoder.
|
||||
// The 512KB Flash has 19 inputs and 8 outputs, the outputs selecting or enabling
|
||||
// a function on the tranZPUter SW design.
|
||||
//
|
||||
// Inputs:
|
||||
// A0 - Z80_MEM0 = MEM[4:0] for the latched configuration selection.
|
||||
// A1 - Z80_MEM1 Based on these bits the decoder operates in a
|
||||
// A2 - Z80_MEM2 differing manner. Basically it will allow areas
|
||||
// A3 - Z80_MEM3 of the Z80 Memory to use the onboard 512K Static RAM
|
||||
// A4 - Z80_MEM4 at a 64Byte granularity or the Sharp MZ80A mainboard.
|
||||
// A5 - Z80_WR = Z80 Write Signal
|
||||
// A6 - Z80_RD = Z80 Read Signal
|
||||
// A7 - Z80_IORQ = Z80 IORQ Signal, an IO operation is taking place.
|
||||
// A8 - Z80_MREQ = Z80 MREQ Signal, a memory operation is taking place.
|
||||
// A9 - Z80_A6 = A[15:6] Z80 address lines of IO or Memory target.
|
||||
// A10 - Z80_A7
|
||||
// A11 - Z80_A8
|
||||
// A12 - Z80_A9
|
||||
// A13 - Z80_A10
|
||||
// A14 - Z80_A11
|
||||
// A15 - Z80_A12
|
||||
// A16 - Z80_A13
|
||||
// A17 - Z80_A14
|
||||
// A18 - Z80_A15
|
||||
//
|
||||
// Memory Modes: 0 - Default, normal Sharp MZ80A operating mode, all memory and IO (except tranZPUter control IO block) are on the mainboard
|
||||
// 1 - As 0 except Floppy ROM and User ROM are mapped to tranZPUter RAM.
|
||||
// 31 - tranZPUter, all memory and IO are exclusively to the devices on the tranZPUter board, no mainboard access is made.
|
||||
//
|
||||
//
|
||||
// Credits:
|
||||
// Copyright: (c) 2020 Philip Smart <philip.smart@net2net.org>
|
||||
//
|
||||
// History: May 2020 - Initial program written.
|
||||
//
|
||||
// Notes:
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// This source file is free software: you can redistribute it and#or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <math.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#define VERSION "1.0"
|
||||
#define FLASHRAMBITS 19
|
||||
#define FLASHRAMSIZE 1 << FLASHRAMBITS
|
||||
#define CFGBITS 5
|
||||
#define CFGSETS (1 << CFGBITS)
|
||||
#define TRANCHESIZE (FLASHRAMSIZE) / (CFGSETS)
|
||||
|
||||
#define CFG_IO_CONTROL_ADDR 0x60
|
||||
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
uint8_t DISABLE_BUS : 1;
|
||||
uint8_t ENABLE_BUS : 1;
|
||||
uint8_t reserved2 : 1;
|
||||
uint8_t reserved3 : 1;
|
||||
uint8_t reserved4 : 1;
|
||||
uint8_t IODECODE : 1;
|
||||
uint8_t RAM_WE : 1;
|
||||
uint8_t RAM_OE : 1;
|
||||
} t_map_output;
|
||||
|
||||
// Structure to represent one of the 32 possible memory map configurations as set by the MEM[4:0] latch.
|
||||
//
|
||||
typedef struct __attribute__((__packed__)) {
|
||||
t_map_output tranche[TRANCHESIZE];
|
||||
} t_memmap_tranche;
|
||||
|
||||
static t_memmap_tranche flashRAM[CFGSETS];
|
||||
static int verbose_flag = 0;
|
||||
static uint32_t ioAddr = CFG_IO_CONTROL_ADDR;
|
||||
|
||||
|
||||
// Simple help screen to remmber how this utility works!!
|
||||
//
|
||||
void usage(void)
|
||||
{
|
||||
printf("FLASHMMCFG v%s\n", VERSION);
|
||||
printf("\nOptions:-\n");
|
||||
printf(" -h | --help This help test.\n");
|
||||
printf(" -i | --io-addr <addr> Base address for the IO Control Registers.\n");
|
||||
printf(" -o | --output <file> Output the final binary image to the given file. This file is programmed into the Flash RAM.\n");
|
||||
printf(" -v | --verbose Output more messages.\n");
|
||||
|
||||
printf("\nExamples:\n");
|
||||
printf(" flashmmcfg --output Decode1.bin --io-addr 0x20 Create the mapping binary using 0x20 as the base address for the IO Control Registers.\n");
|
||||
|
||||
}
|
||||
|
||||
// Method to convert a little endian <-> big endian 32bit unsigned.
|
||||
//
|
||||
uint32_t swap_endian(uint32_t value)
|
||||
{
|
||||
uint32_t b[4];
|
||||
b[0] = ((value & 0x000000ff) << 24u);
|
||||
b[1] = ((value & 0x0000ff00) << 8u);
|
||||
b[2] = ((value & 0x00ff0000) >> 8u);
|
||||
b[3] = ((value & 0xff000000) >> 24u);
|
||||
|
||||
return(b[0] | b[1] | b[2] | b[3]);
|
||||
}
|
||||
|
||||
// Method to initialise the structures which represent the output binary image for uploading into the decoder Flash RAM.
|
||||
// There are a fixed number of 'sets' of configurations which are selected by the MEM[4:0] latch bits, each set gives a
|
||||
// different decoding action so that different memory maps and IO maps can be realised by the Z80 dependent upon its task
|
||||
// or machine it is emulating.
|
||||
//
|
||||
void initMap(void)
|
||||
{
|
||||
for(uint8_t idx=0; idx < CFGSETS; idx++)
|
||||
{
|
||||
for(uint32_t idx2=0; idx2 < TRANCHESIZE; idx2++)
|
||||
{
|
||||
flashRAM[idx].tranche[idx2].DISABLE_BUS = 1;
|
||||
flashRAM[idx].tranche[idx2].ENABLE_BUS = 1;
|
||||
flashRAM[idx].tranche[idx2].reserved2 = 1;
|
||||
flashRAM[idx].tranche[idx2].reserved3 = 1;
|
||||
flashRAM[idx].tranche[idx2].reserved4 = 1;
|
||||
flashRAM[idx].tranche[idx2].IODECODE = 1;
|
||||
flashRAM[idx].tranche[idx2].RAM_WE = 1;
|
||||
flashRAM[idx].tranche[idx2].RAM_OE = 1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// This method takes the internal array, organised as sets and tranches and manipulates them to fit the actual hardware
|
||||
// definition. As the configuration bits MEM[4:0] operate the lowest address select bits of the Flash RAM the output needs
|
||||
// to be sliced into CFGSETS where byte 0 = byte 0 of config set 0 ..... byte n = byte n of config set n, n = 31 for the
|
||||
// current hardware design. This slice is repeated for all TRANCHESIZE bytes in each tranche.
|
||||
//
|
||||
void outputMap(FILE *fp)
|
||||
{
|
||||
// Locals.
|
||||
uint32_t idx;
|
||||
uint8_t idx2;
|
||||
uint8_t outbuf[CFGSETS];
|
||||
|
||||
// As the configuration bits MEM[4:0] operate the lowest address select bits of the Flash RAM the output needs to be
|
||||
//
|
||||
//
|
||||
for(idx=0; idx < TRANCHESIZE; idx++)
|
||||
{
|
||||
for(idx2=0; idx2 < CFGSETS; idx2++)
|
||||
{
|
||||
outbuf[idx2] = flashRAM[idx2].tranche[idx].RAM_OE << 7 |
|
||||
flashRAM[idx2].tranche[idx].RAM_WE << 6 |
|
||||
flashRAM[idx2].tranche[idx].IODECODE << 5 |
|
||||
flashRAM[idx2].tranche[idx].reserved4 << 4 |
|
||||
flashRAM[idx2].tranche[idx].reserved3 << 3 |
|
||||
flashRAM[idx2].tranche[idx].reserved2 << 2 |
|
||||
flashRAM[idx2].tranche[idx].ENABLE_BUS << 1 |
|
||||
flashRAM[idx2].tranche[idx].DISABLE_BUS;
|
||||
}
|
||||
if(fwrite(outbuf, 1, CFGSETS, fp) != CFGSETS)
|
||||
{
|
||||
printf("Write Error: Failed to write %d bytes of set:tranche %u:%u\n", CFGSETS, idx2, idx);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// This method looks at the input signals for a given set and updates the output bits accordingly.
|
||||
//
|
||||
void setMap(uint8_t set, uint32_t inSignals)
|
||||
{
|
||||
// Decode the input signals into there components.
|
||||
uint8_t Z80_WR = (inSignals & 0b00000000000001);
|
||||
uint8_t Z80_RD = (inSignals & 0b00000000000010) >> 1;
|
||||
uint8_t Z80_IORQ = (inSignals & 0b00000000000100) >> 2;
|
||||
uint8_t Z80_MREQ = (inSignals & 0b00000000001000) >> 3;
|
||||
uint8_t Z80_A6 = (inSignals & 0b00000000010000) >> 4;
|
||||
uint8_t Z80_A7 = (inSignals & 0b00000000100000) >> 5;
|
||||
uint8_t Z80_A8 = (inSignals & 0b00000001000000) >> 6;
|
||||
uint8_t Z80_A9 = (inSignals & 0b00000010000000) >> 7;
|
||||
uint8_t Z80_A10 = (inSignals & 0b00000100000000) >> 8;
|
||||
uint8_t Z80_A11 = (inSignals & 0b00001000000000) >> 9;
|
||||
uint8_t Z80_A12 = (inSignals & 0b00010000000000) >> 10;
|
||||
uint8_t Z80_A13 = (inSignals & 0b00100000000000) >> 11;
|
||||
uint8_t Z80_A14 = (inSignals & 0b01000000000000) >> 12;
|
||||
uint8_t Z80_A15 = (inSignals & 0b10000000000000) >> 13;
|
||||
uint32_t Z80_ADDR = (inSignals & 0b11111111110000) << 2; // 16 bit memory address.
|
||||
uint32_t Z80_IO_ADDR = ((inSignals & 0b00000000110000) << 2) | 0b00100000; // 8 bit IO address, bit 5 is hardwired to 1, bit 4 is hardwired to 0.
|
||||
uint8_t Z80_MEM_WRITE = (Z80_WR == 0 && Z80_MREQ == 0 && Z80_RD == 1 && Z80_IORQ == 1) ? 1 : 0;
|
||||
uint8_t Z80_MEM_READ = (Z80_RD == 0 && Z80_MREQ == 0 && Z80_WR == 1 && Z80_IORQ == 1) ? 1 : 0;
|
||||
uint8_t Z80_IO_WRITE = (Z80_WR == 0 && Z80_IORQ == 0 && Z80_RD == 1 && Z80_MREQ == 1) ? 1 : 0;
|
||||
uint8_t Z80_IO_READ = (Z80_RD == 0 && Z80_IORQ == 0 && Z80_WR == 1 && Z80_MREQ == 1) ? 1 : 0;
|
||||
|
||||
//printf("Signals(%u): Z80_WR=%u, Z80_RD=%u, Z80_IORQ=%u, Z80_MREQ=%u, Z80_ADDR=%u, Z80_IO_ADDR=%u\n", inSignals, Z80_WR, Z80_RD, Z80_IORQ, Z80_MREQ, Z80_ADDR, Z80_IO_ADDR);
|
||||
//printf("MEMWR=%u, MEMRD=%u, IOWR=%u, IORD=%u\n", Z80_MEM_WRITE, Z80_MEM_READ, Z80_IO_WRITE, Z80_IO_WRITE);
|
||||
|
||||
// Defaults for IO operations, can be overriden for a specific set but should be present in all other sets.
|
||||
//
|
||||
if(Z80_IO_WRITE || Z80_IO_READ)
|
||||
{
|
||||
// If the address is within configured IO control register range, activate the IODECODE signal.
|
||||
if(Z80_IO_ADDR == ioAddr)
|
||||
{
|
||||
flashRAM[set].tranche[inSignals].DISABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].IODECODE = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// If the non-standard case of Z80 RD and Z80 WR being set low occurs, enable the ENABLE_BUS signal as the K64F is requesting access to the MZ80A motherboard.
|
||||
// This signal is not set dependent, it can occur at any time and with any set.
|
||||
//
|
||||
if(Z80_RD == 0 && Z80_WR == 0 && Z80_MREQ == 1 && Z80_IORQ == 1)
|
||||
{
|
||||
flashRAM[set].tranche[inSignals].DISABLE_BUS = 1;
|
||||
flashRAM[set].tranche[inSignals].ENABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].RAM_OE = 1;
|
||||
flashRAM[set].tranche[inSignals].RAM_WE = 1;
|
||||
flashRAM[set].tranche[inSignals].IODECODE = 1;
|
||||
}
|
||||
|
||||
// Specific mapping for Memory Writes.
|
||||
if(Z80_MEM_WRITE)
|
||||
{
|
||||
switch(set)
|
||||
{
|
||||
// Set 0 - default, the Z80 uses the motherboard so no special signal activation is needed.
|
||||
case 0:
|
||||
flashRAM[set].tranche[inSignals].ENABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].DISABLE_BUS = 1;
|
||||
flashRAM[set].tranche[inSignals].RAM_OE = 1;
|
||||
flashRAM[set].tranche[inSignals].RAM_WE = 1;
|
||||
break;
|
||||
|
||||
// Set 1 - A standard MZ80A.the tranZPUter maps in RAM to the User and Floppy drive slots but otherwise all standard.
|
||||
case 1:
|
||||
// Place a bank of RAM into the floppy disk bios area.
|
||||
if( (Z80_ADDR >= 0xF000 && Z80_ADDR < 0x10000) //||
|
||||
// Place RAM into the User ROM socket.
|
||||
// (Z80_ADDR >= 0xE800 && Z80_ADDR < 0xF000)
|
||||
)
|
||||
{
|
||||
flashRAM[set].tranche[inSignals].DISABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].RAM_WE = 0;
|
||||
} else
|
||||
{
|
||||
flashRAM[set].tranche[inSignals].ENABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].RAM_OE = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
// Set 31 - All memory and IO are on the tranZPUter board.
|
||||
case 31:
|
||||
flashRAM[set].tranche[inSignals].DISABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].RAM_WE = 0;
|
||||
break;
|
||||
|
||||
// For default, do nothing.
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Specific mapping for Memory Reads.
|
||||
else if(Z80_MEM_READ)
|
||||
{
|
||||
switch(set)
|
||||
{
|
||||
// Set 0 - default, the Z80 uses the motherboard so no signal activation is needed.
|
||||
case 0:
|
||||
flashRAM[set].tranche[inSignals].ENABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].DISABLE_BUS = 1;
|
||||
flashRAM[set].tranche[inSignals].RAM_OE = 1;
|
||||
flashRAM[set].tranche[inSignals].RAM_WE = 1;
|
||||
break;
|
||||
|
||||
// Set 1 - A standard MZ80A.the tranZPUter maps in RAM to the User and Floppy drive slots but otherwise all standard.
|
||||
case 1:
|
||||
// Place a bank of RAM into the floppy disk bios area.
|
||||
if( (Z80_ADDR >= 0xF000 && Z80_ADDR < 0x10000) //||
|
||||
// Place RAM into the User ROM socket.
|
||||
// (Z80_ADDR >= 0xE800 && Z80_ADDR < 0xF000)
|
||||
)
|
||||
{
|
||||
flashRAM[set].tranche[inSignals].DISABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].RAM_OE = 0;
|
||||
} else
|
||||
{
|
||||
flashRAM[set].tranche[inSignals].ENABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].RAM_OE = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
// Set 31 - All memory and IO are on the tranZPUter board.
|
||||
case 31:
|
||||
flashRAM[set].tranche[inSignals].DISABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].RAM_OE = 0;
|
||||
break;
|
||||
|
||||
// For default, do nothing.
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Specific mapping for IO Writes.
|
||||
else if(Z80_IO_WRITE)
|
||||
{
|
||||
switch(set)
|
||||
{
|
||||
case 0:
|
||||
if(Z80_IO_ADDR != ioAddr)
|
||||
{
|
||||
flashRAM[set].tranche[inSignals].ENABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].DISABLE_BUS = 1;
|
||||
flashRAM[set].tranche[inSignals].RAM_OE = 1;
|
||||
flashRAM[set].tranche[inSignals].RAM_WE = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
// Set 31 - All memory and IO are on the tranZPUter board.
|
||||
case 31:
|
||||
flashRAM[set].tranche[inSignals].DISABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].IODECODE = 0;
|
||||
break;
|
||||
|
||||
// For default, do nothing.
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Specific mapping for IO Reads.
|
||||
else if(Z80_IO_READ)
|
||||
{
|
||||
switch(set)
|
||||
{
|
||||
case 0:
|
||||
if(Z80_IO_ADDR != ioAddr)
|
||||
{
|
||||
flashRAM[set].tranche[inSignals].ENABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].DISABLE_BUS = 1;
|
||||
flashRAM[set].tranche[inSignals].RAM_OE = 1;
|
||||
flashRAM[set].tranche[inSignals].RAM_WE = 1;
|
||||
}
|
||||
break;
|
||||
|
||||
// Set 31 - All memory and IO are on the tranZPUter board.
|
||||
case 31:
|
||||
flashRAM[set].tranche[inSignals].DISABLE_BUS = 0;
|
||||
flashRAM[set].tranche[inSignals].IODECODE = 0;
|
||||
break;
|
||||
|
||||
// For default, do nothing.
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Actions which generally arent a valid Z80 transaction.
|
||||
else
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// A method to create each set definition. At the moment this is manually coded, if I think of a suitable algorithm then this set of
|
||||
// procedures will change.
|
||||
//
|
||||
void createMap(void)
|
||||
{
|
||||
for(uint8_t idx=0; idx < CFGSETS; idx++)
|
||||
{
|
||||
for(uint32_t idx2=0; idx2 < TRANCHESIZE; idx2++)
|
||||
{
|
||||
setMap(idx, idx2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Main program, to be split up into methods at a later date!! Just quick write as Im concentrating on the tranZPUterSW!!
|
||||
//
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
// Locals.
|
||||
char outputFile[1024];
|
||||
FILE *fpOutput;
|
||||
int help_flag = 0;
|
||||
int opt;
|
||||
int option_index = 0;
|
||||
|
||||
// Initialise any other variables as needed.
|
||||
//
|
||||
outputFile[0] = '\0';
|
||||
|
||||
// Modes of operation.
|
||||
// flashmmcfg --output file
|
||||
// flashmmcfg --help
|
||||
static struct option long_options[] =
|
||||
{
|
||||
{"help", no_argument, 0, 'h'},
|
||||
{"ioaddr", required_argument, 0, 'i'},
|
||||
{"output", required_argument, 0, 'o'},
|
||||
{"verbose", no_argument, 0, 'v'},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
// Parse the command line options.
|
||||
//
|
||||
while((opt = getopt_long(argc, argv, ":hvo;", long_options, &option_index)) != -1)
|
||||
{
|
||||
switch(opt)
|
||||
{
|
||||
case 'h':
|
||||
help_flag = 1;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
ioAddr = atoi(argv[optind]);
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
strcpy(outputFile, argv[optind]);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
verbose_flag = 1;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
printf("Option %s needs a value\n", argv[optind-1]);
|
||||
break;
|
||||
case '?':
|
||||
printf("Unknown option: %s, ignoring!\n", argv[optind-1]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Validate the input.
|
||||
if(help_flag == 1)
|
||||
{
|
||||
usage();
|
||||
exit(0);
|
||||
}
|
||||
if(strlen(outputFile) == 0 )
|
||||
{
|
||||
printf("Output file not specified, please use --output <file>.\n");
|
||||
exit(10);
|
||||
}
|
||||
|
||||
// Open the output file for read/write operations to store the final Flash RAM binary byte image.
|
||||
fpOutput = fopen(outputFile, "w+");
|
||||
if(fpOutput == NULL)
|
||||
{
|
||||
printf("Couldnt open the output file:%s.\n", outputFile);
|
||||
exit(20);
|
||||
}
|
||||
if(ioAddr != 0x20 && ioAddr != 0x60 && ioAddr != 0xA0 && ioAddr != 0xF0)
|
||||
{
|
||||
printf("IO Control Register Base address is illegal:%04x, it should be one of 0x20, 0x60, 0xA0, 0xF0.\n", ioAddr);
|
||||
exit(30);
|
||||
}
|
||||
|
||||
// Initialise the flash map to default unused state.
|
||||
//
|
||||
initMap();
|
||||
|
||||
// Create the required map.
|
||||
//
|
||||
createMap();
|
||||
|
||||
// Output the binary image for flashing into the FlashRAM to perform required decoding.
|
||||
//
|
||||
outputMap(fpOutput);
|
||||
|
||||
// Tidy up, close and finish.
|
||||
fclose(fpOutput);
|
||||
if(verbose_flag)
|
||||
printf("Output file created.\n");
|
||||
}
|
||||
BIN
software/tools/flashmmcfg
Executable file
BIN
software/tools/flashmmcfg
Executable file
Binary file not shown.
Reference in New Issue
Block a user