Added testing method and app for tranZPUter memory testing.

This commit is contained in:
Philip Smart
2021-05-15 19:56:18 +01:00
parent 5cc23498bd
commit fbd691a5f5
31 changed files with 798 additions and 22 deletions

View File

@@ -64,7 +64,7 @@ MISC_SUBDIRS := help time
APP_SUBDIRS := tbasic mbasic kilo ed
ifeq ($(__K64F__),1)
ifeq ($(__TRANZPUTER__),1)
TZPU_SUBDIRS := tzpu tzload tzdump tzclear tzclk tzreset tzio tzflupd
TZPU_SUBDIRS := tzpu tzload tzdump tzclear tzclk tzreset tzio tzflupd tzmtest
endif
else
TZPU_SUBDIRS :=

85
apps/tzmtest/Makefile Executable file
View File

@@ -0,0 +1,85 @@
#########################################################################################################
##
## Name: Makefile
## Created: July 2019
## Author(s): Philip Smart
## Description: App Makefile - Build an App for the ZPU Test Application (zputa) or the zOS
## operating system.
## This makefile builds an app which is stored on an SD card and called by ZPUTA/zOS
## The app is for testing some component where the code is not built into ZPUTA or
## a user application for zOS.
##
## Credits:
## Copyright: (c) 2019-20 Philip Smart <philip.smart@net2net.org>
##
## History: July 2019 - Initial Makefile created for template use.
## April 2020 - Added K64F as an additional target and resplit ZPUTA into zOS.
##
## Notes: Optional component enables:
## USELOADB - The Byte write command is implemented in hw#sw so use it.
## USE_BOOT_ROM - The target is ROM so dont use initialised data.
## MINIMUM_FUNTIONALITY - Minimise functionality to limit code size.
##
#########################################################################################################
## 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/>.
#########################################################################################################
APP_NAME = tzmtest
APP_DIR = $(CURDIR)/..
APP_COMMON_DIR = $(CURDIR)/../common
COMMON_DIR = $(CURDIR)/../../common
BASEDIR = ../../..
TEENSYDIR = ../../teensy3/
# Override values given by parent make for this application as its memory usage differs from the standard app.
ifeq ($(__K64F__),1)
#override HEAPADDR = 0x2002f000
#override HEAPSIZE = 0x00000000
#override STACKADDR = 0x2002f000
#override STACKSIZE = 0x00000000
# Modules making up tzpu.
#APP_C_SRC = $(APP_COMMON_DIR)/pins_teensy.c $(APP_COMMON_DIR)/analog.c $(COMMON_DIR)/tranzputer.c
APP_C_SRC = $(COMMON_DIR)/tranzputer.c
CFLAGS =
CPPFLAGS =
LDFLAGS =
LIBS =
else
# Modules making up tcpu.
APP_C_SRC = #$(APP_COMMON_DIR)/sysutils.c $(APP_COMMON_DIR)/ctypelocal.c
CFLAGS =
CPPFLAGS =
LDFLAGS = -nostdlib
LIBS = -lumansi-zpu -limath-zpu
endif
# Filter out the standard HEAP address and size, replacing with the ones required for this application.
# Useful for sub-makes
FILTER1 = $(filter-out $(filter HEAPADDR=%,$(MAKEFLAGS)), $(MAKEFLAGS))
FILTER2 = $(filter-out $(filter HEAPSIZE=%,$(FILTER1)), $(FILTER1))
NEWMAKEFLAGS = $(FILTER2) HEAPADDR=$(HEADADDR) HEAPSIZE=$(HEAPSIZE)
ifeq ($(__K64F__),1)
include $(APP_DIR)/Makefile.k64f
else
# There currently is no code for the ZPU, all development being done on the K64F for this app.
all:
clean:
install:
endif

338
apps/tzmtest/tzmtest.c Executable file
View File

@@ -0,0 +1,338 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Name: tzmtest.c
// Created: July 2019
// Author(s): Philip Smart
// Description: A TranZPUter helper utility, allowing the realtime display of the tranZPUter
// or host mainboard memory. Code originates from the original zputa mtest application.
//
// Credits:
// Copyright: (c) 2019-2020 Philip Smart <philip.smart@net2net.org>
//
// History: May 2021 - Initial framework creation.
//
// Notes: See Makefile to enable/disable conditional components
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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/>.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__K64F__)
#include <stdio.h>
#include <ctype.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <stdarg.h>
#include <usb_serial.h>
#include <core_pins.h>
#include <Arduino.h>
#include "k64f_soc.h"
#include <../../libraries/include/stdmisc.h>
#elif defined(__ZPU__)
#include <stdint.h>
#include <stdio.h>
#include "zpu_soc.h"
#include <stdlib.h>
#include <ctype.h>
#include <stdmisc.h>
#else
#error "Target CPU not defined, use __ZPU__ or __K64F__"
#endif
#include "interrupts.h"
#include "ff.h" /* Declarations of FatFs API */
#include "utils.h"
//
#if defined __ZPUTA__
#include "zputa_app.h"
#elif defined __ZOS__
#include "zOS_app.h"
#else
#error OS not defined, use __ZPUTA__ or __ZOS__
#endif
// Getopt_long is buggy so we use optparse.
#define OPTPARSE_IMPLEMENTATION
#define OPTPARSE_API static
#include <optparse.h>
//
#include "app.h"
#include <tranzputer.h>
#include "tzmtest.h"
// Utility functions.
#include "tools.c"
// Version info.
#define VERSION "v1.0"
#define VERSION_DATE "15/05/2021"
#define APP_NAME "TZMTEST"
// Simple help screen to remmber how this utility works!!
//
void usage(void)
{
printf("%s %s\n", APP_NAME, VERSION);
printf("\nCommands:-\n");
printf(" -h | --help This help text.\n");
printf(" -a | --start Start address.\n");
printf("\nOptions:-\n");
printf(" -e | --end End address (alternatively use --size).\n");
printf(" -s | --size Size of memory block to test (alternatively use --end).\n");
printf(" -f | --fpga Operations will take place in the FPGA memory. Default without this flag is to target the tranZPUter memory.\n");
printf(" -i | --iter Number of test iterations, default = 1.\n");
printf(" -t | --test Specify test as a bit value, bit 0 = R/W inc ascending test, 1 = R/W inc walking test, 2 = W ascending then R,\n");
printf(" bit 3 = W walking then R, bit 4 = echo and stick bit test.\n");
//printf(" -w " --width Specify memory width tests reqd as a bit value, bit 0 = 8 bit, bit 1 = 16 bit, bit 2 = 32 bit.\n");
printf(" -v | --verbose Output more messages.\n");
printf("\nExamples:\n");
printf(" tzmtest -a 0x000000 -s 0x20000 # Test 128K tranZPUter memory from 0x000000 to 0x020000.\n");
}
// Main entry and start point of a zOS/ZPUTA Application. Only 2 parameters are catered for and a 32bit return code, additional parameters can be added by changing the appcrt0.s
// startup code to add them to the stack prior to app() call.
//
// Return code for the ZPU is saved in _memreg by the C compiler, this is transferred to _memreg in zOS/ZPUTA in appcrt0.s prior to return.
// The K64F ARM processor uses the standard register passing conventions, return code is stored in R0.
//
uint32_t app(uint32_t param1, uint32_t param2)
{
// Initialisation.
//
uint32_t startAddr = 0xFFFFFFFF;
uint32_t endAddr = 0xFFFFFFFF;
uint32_t memSize = 0xFFFFFFFF;
uint32_t iter = 1; // Default to 1 iteration.
uint16_t test = 0x00FF; // Default to all tests.
uint16_t width = 0x0007; // Default to all widths.
uint32_t testsToDo;
uint8_t retCode = 0;
int argc = 0;
int help_flag = 0;
int fpga_flag = 0;
int mainboard_flag = 0;
//int mempage_flag = 0;
int verbose_flag = 0;
int opt;
long val = 0;
char *argv[20];
char *ptr = strtok((char *)param1, " ");
// Initialisation.
// If the invoking command is given, add it to argv at the start.
//
if(param2 != 0)
{
argv[argc++] = (char *)param2;
}
// Now convert the parameter line into argc/argv suitable for getopt to use.
while (ptr && argc < 20-1)
{
argv[argc++] = ptr;
ptr = strtok(0, " ");
}
argv[argc] = 0;
// Define parameters to be processed.
struct optparse options;
static struct optparse_long long_options[] =
{
{"help", 'h', OPTPARSE_NONE},
{"start", 'a', OPTPARSE_REQUIRED},
{"end", 'e', OPTPARSE_REQUIRED},
{"size", 's', OPTPARSE_REQUIRED},
{"fpga", 'f', OPTPARSE_NONE},
{"mainboard", 'm', OPTPARSE_NONE},
{"iter", 'i', OPTPARSE_REQUIRED},
{"test", 't', OPTPARSE_REQUIRED},
//{"width", 'w', OPTPARSE_REQUIRED},
{"verbose", 'v', OPTPARSE_NONE},
{0}
};
// Parse the command line options.
//
optparse_init(&options, argv);
while((opt = optparse_long(&options, long_options, NULL)) != -1)
{
switch(opt)
{
case 'h':
help_flag = 1;
break;
case 'f':
fpga_flag = 1;
break;
case 'm':
mainboard_flag = 1;
break;
case 'a':
if(xatoi(&options.optarg, &val) == 0)
{
printf("Illegal numeric (-a):%s\n", options.optarg);
return(5);
}
startAddr = (uint32_t)val;
break;
case 'e':
if(xatoi(&options.optarg, &val) == 0)
{
printf("Illegal numeric (-e):%s\n", options.optarg);
return(6);
}
endAddr = (uint32_t)val;
break;
case 's':
if(xatoi(&options.optarg, &val) == 0)
{
printf("Illegal numeric (-s):%s\n", options.optarg);
return(7);
}
memSize = (uint32_t)val;
break;
case 'i':
if(xatoi(&options.optarg, &val) == 0)
{
printf("Illegal numeric (-i):%s\n", options.optarg);
return(8);
}
iter = (uint32_t)val;
break;
case 't':
if(xatoi(&options.optarg, &val) == 0)
{
printf("Illegal numeric (-t):%s\n", options.optarg);
return(8);
}
test = (uint32_t)val;
break;
//case 'w':
// if(xatoi(&options.optarg, &val) == 0)
// {
// printf("Illegal numeric (-w):%s\n", options.optarg);
// return(8);
// }
// width = (uint32_t)val;
// break;
case 'v':
verbose_flag = 1;
break;
case '?':
printf("%s: %s\n", argv[0], options.errmsg);
return(1);
}
}
// Validate the input.
if(help_flag == 1)
{
usage();
return(0);
}
if(startAddr == 0xFFFFFFFF)
{
printf("Please define the start address, size will default to 0x100.\n");
return(10);
}
if(endAddr == 0xFFFFFFFF && memSize == 0xFFFFFFFF)
{
endAddr = startAddr + 0x100;
} else if(endAddr == 0xFFFFFFFF)
{
endAddr = startAddr + memSize;
}
if(endAddr < startAddr)
{
printf("Start Address must be greater than End Address.\n");
return(11);
}
if(mainboard_flag == 1 && fpga_flag == 1)
{
printf("Please specify only one target, --mainboard, --fpga or default to tranZPUter memory.\n");
return(12);
}
if(mainboard_flag == 1 && (startAddr > 0x10000 || endAddr > 0x10000))
{
printf("Mainboard only has 64K, please change the address or size.\n");
return(13);
}
if(fpga_flag == 1 && (startAddr >= TZ_MAX_FPGA_MEM || endAddr > TZ_MAX_FPGA_MEM))
{
printf("FPGA only has a %dM window, please change the address or size.\n", TZ_MAX_FPGA_MEM/1024000);
return(14);
}
if(mainboard_flag == 0 && fpga_flag == 0 && (startAddr >= TZ_MAX_Z80_MEM || endAddr > TZ_MAX_Z80_MEM))
{
printf("tranZPUter board only has %dK, please change the address or size.\n", TZ_MAX_Z80_MEM/1024);
return(15);
}
// Setup the test/width indicator flag.
testsToDo = (width << 16) | test;
// A very simple test, this needs to be updated with a thorough bit pattern and location test.
if(verbose_flag)
printf( "Check memory addr 0x%08lX to 0x%08lX over %ld iteration(s).\n", startAddr, endAddr, iter );
// Perform test for given number of iterations.
for(uint32_t idx=0; idx < iter && retCode == 0; idx++)
{
if(testsToDo & 0x00010000)
{
retCode = testZ80Memory(startAddr, endAddr, testsToDo, verbose_flag, mainboard_flag == 1 ? MAINBOARD : fpga_flag == 1 ? FPGA : TRANZPUTER);
}
//if(testsToDo & 0x00020000)
//{
// test16bit(startAddr, endAddr, testsToDo);
//}
//if(testsToDo & 0x00040000)
//{
// test32bit(startAddr, endAddr, testsToDo);
//}
}
// Terminate output if in verbose mode.
if(verbose_flag)
printf("\n");
// Indicate any failure if we are in silent mode.
if(retCode != 0 && verbose_flag == 0)
printf("Memory test failed with return code:%d, use --verbose flag for more detail.\n", retCode);
return(0);
}
#ifdef __cplusplus
}
#endif

50
apps/tzmtest/tzmtest.h Executable file
View File

@@ -0,0 +1,50 @@
/////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Name: tzmtest.h
// Created: May 2021
// Author(s): Philip Smart
// Description: A TranZPUter helper utility, allowing to test the onboard tranZPUter card memory
// or externally accessible FPGA BRAM.
// Credits:
// Copyright: (c) 2019-2020 Philip Smart <philip.smart@net2net.org>
//
// History: July 2019 - Initial framework creation.
// April 2020 - Updates to function with the K64F processor and zOS.
//
// Notes: See Makefile to enable/disable conditional components
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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/>.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
#ifndef TZMTEST_H
#define TZMTEST_H
#ifdef __cplusplus
extern "C" {
#endif
// Constants.
// Application execution constants.
//
// Components to be embedded in the program.
//
// Memory components to be embedded in the program.
#define BUILTIN_MEM_TEST 1
#ifdef __cplusplus
}
#endif
#endif // TZMTEST_H

View File

@@ -61,6 +61,7 @@
// The bug occurs due to an interaction between the heap management
// and threads.
// v1.7 May 2021 - Changes to use 512K-1Mbyte Z80 Static RAM, build time configurable.
// Added memory test routines to validate tranZPUter memory.
//
// Notes: See Makefile to enable/disable conditional components
//
@@ -1619,6 +1620,298 @@ void fillZ80Memory(uint32_t addr, uint32_t size, uint8_t data, enum TARGETS targ
return;
}
// A memory test method extracted from the base zputa code for use with the tranZPUter card.
//
uint8_t testZ80Memory(uint32_t start, uint32_t end, uint32_t testsToDo, int verbose, enum TARGETS target)
{
// Locals.
uint32_t memPtr;
uint32_t memPtr2;
unsigned long count;
unsigned long count2;
uint8_t data;
uint8_t readBack;
uint8_t retCode = 0;
uint32_t errCnt = 0;
// Sanity checks.
//
if((target == MAINBOARD && (start > 0x10000 || end > 0x10000)) || (target == TRANZPUTER && (start > TZ_MAX_Z80_MEM || end > TZ_MAX_Z80_MEM)) || (target == FPGA && (start > TZ_MAX_FPGA_MEM || end > TZ_MAX_FPGA_MEM)) )
return(1);
// If the Z80 is in RUN mode, request the bus.
// This mechanism allows for the Z80 BUS to remain under the tranZPUter control for multiple transactions.
//
if(z80Control.ctrlMode == Z80_RUN)
{
// Request the board according to the target flag, target = MAINBOARD then the mainboard is controlled otherwise the tranZPUter board.
if(target == TRANZPUTER || target == FPGA)
{
reqTranZPUterBus(DEFAULT_BUSREQ_TIMEOUT, target);
} else
{
reqMainboardBus(DEFAULT_BUSREQ_TIMEOUT);
}
// If successful, setup the control pins for upload mode.
//
if(z80Control.ctrlMode != Z80_RUN)
{
// Setup the pins to perform a write operation.
//
setZ80Direction(WRITE);
// Setup the control latch to the required starting configuration.
writeCtrlLatch(z80Control.curCtrlLatch);
}
} else
{
// See if the bus needs changing.
//
enum CTRL_MODE newMode = (target == MAINBOARD) ? MAINBOARD_ACCESS : TRANZPUTER_ACCESS;
reqZ80BusChange(newMode);
}
// Ensure we dont close the bus connection during the tests.
z80Control.holdZ80 = 1;
// If we have bus control, complete the task,
//
if( z80Control.ctrlMode != Z80_RUN )
{
// Setup the pins to perform a write operation (after setting the latch to starting value).
//
writeCtrlLatch(z80Control.curCtrlLatch);
// Ascending value test write with readback.
if(testsToDo & 0x00000001 && retCode == 0)
{
if(verbose)
printf( "\rR/W 8bit ascending test pattern... " );
memPtr = start;
data = 0x00;
count = end - start;
while( count-- && errCnt <= 20)
{
setZ80Direction(WRITE);
writeZ80Memory(memPtr, data, target);
setZ80Direction(READ);
if( (readBack=readZ80Memory(memPtr)) != data )
{
if(verbose)
printf( "\rError (8bit rwap) at 0x%08lX (%02x:%02x)\n", memPtr, readBack, data );
if(errCnt++ == 20)
{
if(verbose)
printf( "\rError count (8bit rwap) > 20, stopping test.\n");
retCode = 10;
}
}
memPtr++;
data++;
if( data >= 0xFF )
data = 0x00;
}
}
// Walking value test write with readback.
if(testsToDo & 0x00000002 && retCode == 0)
{
if(verbose)
printf( "\rR/W 8bit walking test pattern... " );
memPtr = start;
data = 0x55;
count = end - start;
errCnt = 0;
while( count-- && errCnt <= 20)
{
setZ80Direction(WRITE);
writeZ80Memory(memPtr, data, target);
setZ80Direction(READ);
if( (readBack=readZ80Memory(memPtr)) != data )
{
if(verbose)
printf( "\rError (8bit rwwp) at 0x%08lX (%02x:%02x)\n", memPtr, readBack, data );
if(errCnt++ == 20)
{
if(verbose)
printf( "\rError count (8bit rwwp) > 20, stopping test.\n");
retCode = 20;
}
}
memPtr++;
if( data == 0x55 )
data = 0xAA;
else
data = 0x55;
}
}
// Ascending value test write block then verify block.
if(testsToDo & 0x00000004 && retCode == 0)
{
if(verbose)
printf( "\rWrite 8bit ascending test pattern... " );
memPtr = start;
data = 0x00;
count = end - start;
while( count-- )
{
setZ80Direction(WRITE);
writeZ80Memory(memPtr, data, target);
setZ80Direction(READ);
if( (readBack=readZ80Memory(memPtr)) != data )
{
if(verbose)
printf( "\rError (8bit wap) at 0x%08lX (%02x:%02x)\n", memPtr, readBack, data );
if(errCnt++ == 20)
{
if(verbose)
printf( "\rError count (8bit rwwp) > 20, stopping test.\n");
retCode = 30;
}
}
memPtr++;
data++;
if( data >= 0xFF )
data = 0x00;
}
if(verbose)
printf( "\rRead 8bit ascending test pattern... " );
memPtr = start;
data = 0x00;
count = end - start;
errCnt = 0;
while( count-- && errCnt <= 20)
{
setZ80Direction(WRITE);
writeZ80Memory(memPtr, data, target);
setZ80Direction(READ);
if( (readBack=readZ80Memory(memPtr)) != data )
{
if(verbose)
printf( "\rError (8bit ap) at 0x%08lX (%02x:%02x)\n", memPtr, readBack, data );
if(errCnt++ == 20)
{
if(verbose)
printf( "\rError count (8bit ap) > 20, stopping test.\n");
retCode = 40;
}
}
memPtr++;
data++;
if( data >= 0xFF )
data = 0x00;
}
}
// Walking value test write block then verify block.
if(testsToDo & 0x00000008 && retCode == 0)
{
if(verbose)
printf( "\rWrite 8bit walking test pattern... " );
memPtr = start;
data = 0x55;
count = end - start;
setZ80Direction(WRITE);
while( count-- )
{
writeZ80Memory(memPtr, data, target);
if( data == 0x55 )
data = 0xAA;
else
data = 0x55;
memPtr++;
}
if(verbose)
printf( "\rRead 8bit walking test pattern... " );
memPtr = start;
data = 0x55;
count = end - start;
errCnt = 0;
setZ80Direction(READ);
while( count-- && errCnt <= 20)
{
if( (readBack=readZ80Memory(memPtr)) != data )
{
if(verbose)
printf( "\rError (8bit wp) at 0x%08lX (%02x:%02x)\n", memPtr, readBack, data );
if(errCnt++ == 20)
{
if(verbose)
printf( "\rError count (8bit wp) > 20, stopping test.\n");
retCode = 50;
}
}
memPtr++;
if( data == 0x55 )
data = 0xAA;
else
data = 0x55;
}
}
// Echo and sticky bit test, more complex as the array has to be scanned for each set to see if any bit in the memory array
// has been set with a write to 1 location or bits are staying stuck.
if(testsToDo & 0x00000010 && retCode == 0)
{
if(verbose)
printf( "\r8bit echo and sticky bit test... " );
memPtr = start;
count = end - start;
errCnt = 0;
fillZ80Memory(start, end - start, 0x00, target);
while( count-- && errCnt <= 20)
{
setZ80Direction(WRITE);
writeZ80Memory(memPtr, 0xFF, target);
memPtr2 = start;
count2 = end - start;
while( count2-- && errCnt <= 20)
{
setZ80Direction(READ);
readBack=readZ80Memory(memPtr2);
if( readBack != 0x00 && readBack != readZ80Memory(memPtr))
{
if(verbose)
printf( "\rError (8bit es) at 0x%08lx:0x%08lX (%02x:%02x)\n", memPtr, memPtr2, readBack, 0x00 );
setZ80Direction(WRITE);
writeZ80Memory(memPtr2, 0x00, target);
if(errCnt++ == 20)
{
if(verbose)
printf( "\rError count (8bit es) > 20, stopping test.\n");
retCode = 60;
}
}
memPtr2++;
}
setZ80Direction(WRITE);
writeZ80Memory(memPtr, 0x00, target);
memPtr++;
}
}
}
// Release the bus if it is not being held for further transations.
//
z80Control.holdZ80 = 1;
if(z80Control.holdZ80 == 0 && z80Control.ctrlMode != Z80_RUN)
{
// Restore the control latch to its original configuration.
//
writeCtrlLatch(z80Control.runCtrlLatch);
releaseZ80();
}
// Return completion code.
return(retCode);
}
// A method to read the full video frame buffer from the Sharp MZ80A and store it in local memory (control structure).
// No refresh cycles are needed as we grab the frame but between frames a full refresh is performed.
//
@@ -4217,7 +4510,7 @@ uint32_t getServiceAddr(void)
// zOS
addr = TZSVC_CMD_STRUCT_ADDR_ZOS;
}
printf("getServiceAddr:%02x,%02x,%02x,%01x,%08lx,%02x\n", z80Control.runCtrlLatch, z80Control.curCtrlLatch, memoryMode, cpuConfig, addr, svcControl.cmd);
//printf("getServiceAddr:%02x,%02x,%02x,%01x,%08lx,%02x\n", z80Control.runCtrlLatch, z80Control.curCtrlLatch, memoryMode, cpuConfig, addr, svcControl.cmd);
return(addr);
}

View File

@@ -10,6 +10,7 @@
// Copyright: (c) 2019-21 Philip Smart <philip.smart@net2net.org>
//
// History: January 2019 - Initial script written.
// May 2021 - Added memory test tz command.
//
/////////////////////////////////////////////////////////////////////////////////////////////////////////
// This source file is free software: you can redistribute it and#or modify
@@ -113,6 +114,7 @@ extern "C" {
#define CMD_TZ_RESET 155 // tranZPUter memory reset tool.
#define CMD_TZ_IO 156 // tranZPUter memory IO read/write tool.
#define CMD_TZ_FLUPD 157 // tranZPUter K64F FlashRAM update tool.
#define CMD_TZ_MTEST 158 // tranZPUter memory test tool.
#define CMD_BADKEY -1
#define CMD_NOKEY 0
#define CMD_GROUP_DISK 1
@@ -391,24 +393,25 @@ static t_cmdstruct cmdTable[] = {
#if (defined(BUILTIN_MISC_TEST) && BUILTIN_MISC_TEST == 1) || (defined(BUILTIN_MISC_HELP) == 1 && BUILTIN_MISC_HELP == 1)
{ "test", BUILTIN_MISC_TEST, CMD_MISC_TEST, CMD_GROUP_MISC },
#endif
#if defined __SHARPMZ__
#if (defined(BUILTIN_MISC_CLS) && BUILTIN_MISC_CLS == 1) || (defined(BUILTIN_MISC_HELP) == 1 && BUILTIN_MISC_HELP == 1)
{ "cls", BUILTIN_DEFAULT, CMD_MISC_CLS, CMD_GROUP_MISC },
#endif
#if (defined(BUILTIN_MISC_Z80) && BUILTIN_MISC_Z80 == 1) || (defined(BUILTIN_MISC_HELP) == 1 && BUILTIN_MISC_HELP == 1)
{ "z80", BUILTIN_DEFAULT, CMD_MISC_Z80, CMD_GROUP_MISC },
#endif
#endif
// Applications - most are not built in so dont need to be in this table or just placed here commented out for reference.
{ "tbasic", BUILTIN_DEFAULT, CMD_APP_TBASIC, CMD_GROUP_APP },
{ "mbasic", BUILTIN_DEFAULT, CMD_APP_MBASIC, CMD_GROUP_APP },
{ "kilo", BUILTIN_DEFAULT, CMD_APP_KILO, CMD_GROUP_APP },
{ "ed", BUILTIN_DEFAULT, CMD_APP_ED, CMD_GROUP_APP },
#if defined __SHARPMZ__
#endif
#if defined __TRANZPUTER__
{ "tzpu", BUILTIN_DEFAULT, CMD_TZ_TZPU, CMD_GROUP_TZ },
{ "tzload", BUILTIN_DEFAULT, CMD_TZ_LOAD, CMD_GROUP_TZ },
{ "tzdump", BUILTIN_DEFAULT, CMD_TZ_DUMP, CMD_GROUP_TZ },
{ "tzclear", BUILTIN_DEFAULT, CMD_TZ_CLEAR, CMD_GROUP_TZ },
{ "tzmtest", BUILTIN_DEFAULT, CMD_TZ_MTEST, CMD_GROUP_TZ },
{ "tzclk", BUILTIN_DEFAULT, CMD_TZ_CLK, CMD_GROUP_TZ },
{ "tzreset", BUILTIN_DEFAULT, CMD_TZ_RESET, CMD_GROUP_TZ },
{ "tzio", BUILTIN_DEFAULT, CMD_TZ_IO, CMD_GROUP_TZ },
@@ -528,6 +531,7 @@ static t_helpstruct helpTable[] = {
{ CMD_TZ_LOAD, "--help", "Memory load/save tool" },
{ CMD_TZ_DUMP, "--help", "Memory dump tool" },
{ CMD_TZ_CLEAR, "--help", "Memory clearing tool" },
{ CMD_TZ_MTEST, "--help", "Memory testing tool" },
{ CMD_TZ_CLK, "--help", "CPU Freq set tool" },
{ CMD_TZ_RESET, "--help", "Remote reset tool" },
{ CMD_TZ_IO, "--help", "I/O read/write tool" },

View File

@@ -836,6 +836,7 @@ uint8_t inZ80IO(uint32_t);
uint8_t writeZ80IO(uint32_t, uint8_t, enum TARGETS);
uint8_t readZ80IO(uint32_t, enum TARGETS);
void fillZ80Memory(uint32_t, uint32_t, uint8_t, enum TARGETS);
uint8_t testZ80Memory(uint32_t, uint32_t, uint32_t, int, enum TARGETS);
void captureVideoFrame(enum VIDEO_FRAMES, uint8_t);
void refreshVideoFrame(enum VIDEO_FRAMES, uint8_t, uint8_t);
FRESULT loadVideoFrameBuffer(char *, enum VIDEO_FRAMES);

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -16010,11 +16010,11 @@ shared variable ram : ram_type :=
16972 => x"7a4f5300",
16973 => x"2a2a2025",
16974 => x"73202800",
16975 => x"31312f30",
16975 => x"31352f30",
16976 => x"352f3230",
16977 => x"32310000",
16978 => x"76312e33",
16979 => x"62000000",
16979 => x"00000000",
16980 => x"205a5055",
16981 => x"2c207265",
16982 => x"76202530",

View File

@@ -62249,7 +62249,7 @@ architecture arch of DualPort3264BootBRAM is
7460 => x"20",
7461 => x"00",
7462 => x"2a",
7463 => x"31",
7463 => x"35",
7464 => x"31",
7465 => x"00",
7466 => x"20",
@@ -71369,7 +71369,7 @@ architecture arch of DualPort3264BootBRAM is
7462 => x"2a",
7463 => x"31",
7464 => x"32",
7465 => x"62",
7465 => x"00",
7466 => x"2c",
7467 => x"32",
7468 => x"73",

View File

@@ -51457,7 +51457,7 @@ architecture arch of DualPortBootBRAM is
14924 => x"4f",
14925 => x"2a",
14926 => x"20",
14927 => x"31",
14927 => x"35",
14928 => x"2f",
14929 => x"31",
14930 => x"31",
@@ -69692,7 +69692,7 @@ architecture arch of DualPortBootBRAM is
14928 => x"35",
14929 => x"32",
14930 => x"76",
14931 => x"62",
14931 => x"00",
14932 => x"20",
14933 => x"2c",
14934 => x"76",

View File

@@ -51452,7 +51452,7 @@ architecture arch of SinglePortBootBRAM is
14924 => x"4f",
14925 => x"2a",
14926 => x"20",
14927 => x"31",
14927 => x"35",
14928 => x"2f",
14929 => x"31",
14930 => x"31",
@@ -69687,7 +69687,7 @@ architecture arch of SinglePortBootBRAM is
14928 => x"35",
14929 => x"32",
14930 => x"76",
14931 => x"62",
14931 => x"00",
14932 => x"20",
14933 => x"2c",
14934 => x"76",

View File

@@ -14989,11 +14989,11 @@ shared variable ram : ram_type :=
14924 => x"7a4f5300",
14925 => x"2a2a2025",
14926 => x"73202800",
14927 => x"31312f30",
14927 => x"31352f30",
14928 => x"352f3230",
14929 => x"32310000",
14930 => x"76312e33",
14931 => x"62000000",
14931 => x"00000000",
14932 => x"205a5055",
14933 => x"2c207265",
14934 => x"76202530",

View File

@@ -62249,7 +62249,7 @@ architecture arch of DualPort3264BootBRAM is
7460 => x"20",
7461 => x"00",
7462 => x"2a",
7463 => x"31",
7463 => x"35",
7464 => x"31",
7465 => x"00",
7466 => x"20",
@@ -71369,7 +71369,7 @@ architecture arch of DualPort3264BootBRAM is
7462 => x"2a",
7463 => x"31",
7464 => x"32",
7465 => x"62",
7465 => x"00",
7466 => x"2c",
7467 => x"32",
7468 => x"73",

View File

@@ -51457,7 +51457,7 @@ architecture arch of DualPortBootBRAM is
14924 => x"4f",
14925 => x"2a",
14926 => x"20",
14927 => x"31",
14927 => x"35",
14928 => x"2f",
14929 => x"31",
14930 => x"31",
@@ -69692,7 +69692,7 @@ architecture arch of DualPortBootBRAM is
14928 => x"35",
14929 => x"32",
14930 => x"76",
14931 => x"62",
14931 => x"00",
14932 => x"20",
14933 => x"2c",
14934 => x"76",

View File

@@ -51452,7 +51452,7 @@ architecture arch of SinglePortBootBRAM is
14924 => x"4f",
14925 => x"2a",
14926 => x"20",
14927 => x"31",
14927 => x"35",
14928 => x"2f",
14929 => x"31",
14930 => x"31",
@@ -69687,7 +69687,7 @@ architecture arch of SinglePortBootBRAM is
14928 => x"35",
14929 => x"32",
14930 => x"76",
14931 => x"62",
14931 => x"00",
14932 => x"20",
14933 => x"2c",
14934 => x"76",

View File

@@ -346,6 +346,8 @@ BSS_END: .word __bss_section_end__
.equ funcAddr, funcAddr+funcNext;
defapifunc fillZ80Memory funcAddr
.equ funcAddr, funcAddr+funcNext;
defapifunc testZ80Memory funcAddr
.equ funcAddr, funcAddr+funcNext;
defapifunc captureVideoFrame funcAddr
.equ funcAddr, funcAddr+funcNext;
defapifunc refreshVideoFrame funcAddr

View File

@@ -346,6 +346,8 @@ BSS_END: .word __bss_section_end__
.equ funcAddr, funcAddr+funcNext;
defapifunc fillZ80Memory funcAddr
.equ funcAddr, funcAddr+funcNext;
defapifunc testZ80Memory funcAddr
.equ funcAddr, funcAddr+funcNext;
defapifunc captureVideoFrame funcAddr
.equ funcAddr, funcAddr+funcNext;
defapifunc refreshVideoFrame funcAddr

View File

@@ -1009,6 +1009,7 @@ void _ZPUTA_Vectors(void)
__asm__ volatile ("b copyFromZ80");
__asm__ volatile ("b copyToZ80");
__asm__ volatile ("b fillZ80Memory");
__asm__ volatile ("b testZ80Memory");
__asm__ volatile ("b captureVideoFrame");
__asm__ volatile ("b refreshVideoFrame");
__asm__ volatile ("b loadVideoFrameBuffer");

View File

@@ -121,8 +121,8 @@
#endif
// Version info.
#define VERSION "v1.3b"
#define VERSION_DATE "11/05/2021"
#define VERSION "v1.3"
#define VERSION_DATE "15/05/2021"
#define PROGRAM_NAME "zOS"
// Utility functions.