Removed zOS sub-directory as it is part of zSoft
This commit is contained in:
1
zOS/MZ2000/apps
vendored
1
zOS/MZ2000/apps
vendored
@@ -1 +0,0 @@
|
|||||||
/dvlp/Projects/zSoft/apps
|
|
||||||
@@ -1,763 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
#========================================================================================================
|
|
||||||
# NAME
|
|
||||||
# build.sh - Shell script to build a ZPU/K64F/M68K program or OS.
|
|
||||||
#
|
|
||||||
# SYNOPSIS
|
|
||||||
# build.sh [-CIOoMBAsTZdxh]
|
|
||||||
#
|
|
||||||
# DESCRIPTION
|
|
||||||
#
|
|
||||||
# OPTIONS
|
|
||||||
# -C <CPU> = Small, Medium, Flex, Evo, EvoMin, K64F, M68K - defaults to Evo.
|
|
||||||
# -I <iocp ver> = 0 - Full, 1 - Medium, 2 - Minimum, 3 - Tiny (bootstrap only)
|
|
||||||
# -O <os> = zputa, zos
|
|
||||||
# -o <os ver> = 0 - Standalone, 1 - As app with IOCP Bootloader,
|
|
||||||
# 2 - As app with tiny IOCP Bootloader, 3 - As app in RAM
|
|
||||||
# -M <size> = Max size of the boot ROM/BRAM (needed for setting Stack).
|
|
||||||
# -B <addr> = Base address of <os>, default -o == 0 : 0x00000 else 0x01000
|
|
||||||
# -A <addr> = App address of <os>, default 0x0C000
|
|
||||||
# -N <size> = Required size of heap
|
|
||||||
# -n <size> = Required size of application heap
|
|
||||||
# -S <size> = Required size of stack
|
|
||||||
# -s <size> = Required size of application stack
|
|
||||||
# -a <size> = Maximum size of an app, defaults to (BRAM SIZE - App Start Address - Stack Size)
|
|
||||||
# if the App Start is located within BRAM otherwise defaults to 0x10000.
|
|
||||||
# -T = TranZPUter specific build, adds initialisation and setup code.
|
|
||||||
# -Z = Sharp MZ series ZPU build, zOS runs as an OS host on Sharp MZ hardware.
|
|
||||||
# -d = Debug mode.
|
|
||||||
# -x = Shell trace mode.
|
|
||||||
# -h = This help screen.
|
|
||||||
#
|
|
||||||
# EXAMPLES
|
|
||||||
# build.sh -O zputa -B 0x00000 -A 0x50000
|
|
||||||
#
|
|
||||||
# EXIT STATUS
|
|
||||||
# 0 The command ran successfully
|
|
||||||
#
|
|
||||||
# >0 An error ocurred.
|
|
||||||
#
|
|
||||||
#EndOfUsage <- do not remove this line
|
|
||||||
#========================================================================================================
|
|
||||||
# History:
|
|
||||||
# v1.00 : Initial version (C) P. Smart January 2019.
|
|
||||||
# v1.10 : Changes to better calculate mode and addresses and setup linker scripts.
|
|
||||||
# v1.11 : Added CPU as it is clear certain features must be disabled in the original
|
|
||||||
# CPU's, ie. small where the emulated mul and div arent working as they should.
|
|
||||||
# v1.2 : Added more zOS logic and the K64F processor target for the tranZPUter board.
|
|
||||||
# v1.21 : Additional changes to manage heap.
|
|
||||||
# v1.22 : Added code to build the libraries.
|
|
||||||
# v1.23 : Added flags for Sharp MZ series specific build.
|
|
||||||
# v1.24 : Added M68000 support
|
|
||||||
#========================================================================================================
|
|
||||||
# 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/>.
|
|
||||||
#========================================================================================================
|
|
||||||
|
|
||||||
PROG=${0##*/}
|
|
||||||
#PARAMS="`basename ${PROG} '.sh'`.params"
|
|
||||||
ARGS=$*
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
# Load program specific variables
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
# VERSION of this RELEASE.
|
|
||||||
#
|
|
||||||
VERSION="1.23"
|
|
||||||
|
|
||||||
# Constants.
|
|
||||||
BUILDPATH=`pwd`
|
|
||||||
|
|
||||||
# Temporary files.
|
|
||||||
TMP_DIR=/tmp
|
|
||||||
TMP_OUTPUT_FILE=${TMP_DIR}/tmpoutput_$$.log
|
|
||||||
TMP_STDERR_FILE=${TMP_DIR}/tmperror_$$.log
|
|
||||||
|
|
||||||
# Log mechanism setup.
|
|
||||||
#
|
|
||||||
LOG="/tmp/${PROG}_`date +"%Y_%m_%d"`.log"
|
|
||||||
LOGTIMEWIDTH=40
|
|
||||||
LOGMODULE="MAIN"
|
|
||||||
|
|
||||||
# Mutex's - prevent multiple threads entering a sensitive block at the same time.
|
|
||||||
#
|
|
||||||
MUTEXDIR="/var/tmp"
|
|
||||||
|
|
||||||
##############################################################################
|
|
||||||
# Utility procedures
|
|
||||||
##############################################################################
|
|
||||||
|
|
||||||
# Function to output Usage instructions, which is soley a copy of this script header.
|
|
||||||
#
|
|
||||||
function Usage
|
|
||||||
{
|
|
||||||
# Output the lines at the start of this script from NAME to EndOfUsage
|
|
||||||
cat $0 | nawk 'BEGIN {s=0} /EndOfUsage/ { exit } /NAME/ {s=1} { if (s==1) print substr( $0, 3 ) }'
|
|
||||||
exit 1
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to output a message in Log format, ie. includes date, time and issuing module.
|
|
||||||
#
|
|
||||||
function Log
|
|
||||||
{
|
|
||||||
DATESTR=`date "+%d/%m/%Y %H:%M:%S"`
|
|
||||||
PADLEN=`expr ${LOGTIMEWIDTH} + -${#DATESTR} + -1 + -${#LOGMODULE} + -15`
|
|
||||||
printf "%s %-${PADLEN}s %s\n" "${DATESTR} [$LOGMODULE]" " " "$*"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to terminate the script after logging an error message.
|
|
||||||
#
|
|
||||||
function Fatal
|
|
||||||
{
|
|
||||||
Log "ERROR: $*"
|
|
||||||
Log "$PROG aborted"
|
|
||||||
exit 2
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to output the Usage, then invoke Fatal to exit with a terminal message.
|
|
||||||
#
|
|
||||||
function FatalUsage
|
|
||||||
{
|
|
||||||
# Output the lines at the start of this script from NAME to EndOfUsage
|
|
||||||
cat $0 | nawk 'BEGIN {s=0} /EndOfUsage/ { exit } /NAME/ {s=1} { if (s==1) print substr( $0, 3 ) }'
|
|
||||||
echo " "
|
|
||||||
echo "ERROR: $*"
|
|
||||||
echo "$PROG aborted"
|
|
||||||
exit 3
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to output a message if DEBUG mode is enabled. Primarily to see debug messages should a
|
|
||||||
# problem occur.
|
|
||||||
#
|
|
||||||
function Debug
|
|
||||||
{
|
|
||||||
if [ $DEBUGMODE -eq 1 ]; then
|
|
||||||
Log "$*"
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to output a file if DEBUG mode is enabled.
|
|
||||||
#
|
|
||||||
function DebugFile
|
|
||||||
{
|
|
||||||
if [ $DEBUGMODE -eq 1 ]; then
|
|
||||||
cat $1
|
|
||||||
fi
|
|
||||||
}
|
|
||||||
|
|
||||||
# Take an input value to be hex, validate it and format correctly.
|
|
||||||
function getHex
|
|
||||||
{
|
|
||||||
local __resultvar=$2
|
|
||||||
local inputHex=`echo $1 | tr 'a-z' 'A-Z'|sed 's/0X//g'`
|
|
||||||
TEST=$(( 16#$inputHex )) 2> /dev/null
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
FatalUsage "Value:$1 is not hexadecimal."
|
|
||||||
fi
|
|
||||||
local decimal=`echo "16 i $inputHex p" | dc`
|
|
||||||
local outputHex=`printf '0x%08X' "$((10#$decimal))"`
|
|
||||||
eval $__resultvar="'$outputHex'"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Add two hexadecimal values of the form result = 0xAAAAAA + 0xBBBBBB
|
|
||||||
function addHex
|
|
||||||
{
|
|
||||||
local __resultvar=$3
|
|
||||||
local inputHex1=`echo $1 | tr 'a-z' 'A-Z'|sed 's/0X//g'`
|
|
||||||
TEST=$(( 16#$inputHex1 )) 2> /dev/null
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
FatalUsage "Param 1:$1/$inputHex1 is not hexadecimal."
|
|
||||||
fi
|
|
||||||
local inputHex2=`echo $2 | tr 'a-z' 'A-Z'|sed 's/0X//g'`
|
|
||||||
TEST=$(( 16#$inputHex2 )) 2> /dev/null
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
FatalUsage "Param 2:$2/$inputHex2 is not hexadecimal."
|
|
||||||
fi
|
|
||||||
local sumDecimal=`echo "16 i $inputHex1 $inputHex2 + p" | dc`
|
|
||||||
local outputHex=`printf '0x%08X' "$((10#$sumDecimal))"`
|
|
||||||
eval $__resultvar="'$outputHex'"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Subtract two hexadecimal values of the form result = 0xAAAAAA - 0xBBBBBB
|
|
||||||
function subHex
|
|
||||||
{
|
|
||||||
local __resultvar=$3
|
|
||||||
local inputHex1=`echo $1 | tr 'a-z' 'A-Z'|sed 's/0X//g'`
|
|
||||||
TEST=$(( 16#$inputHex1 )) 2> /dev/null
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
FatalUsage "Param 1:$1/$inputHex1 is not hexadecimal."
|
|
||||||
fi
|
|
||||||
local inputHex2=`echo $2 | tr 'a-z' 'A-Z'|sed 's/0X//g'`
|
|
||||||
TEST=$(( 16#$inputHex2 )) 2> /dev/null
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
FatalUsage "Param 2:$2/$inputHex2 is not hexadecimal."
|
|
||||||
fi
|
|
||||||
local sumDecimal=`echo "16 i $inputHex1 $inputHex2 - p" | dc`
|
|
||||||
local outputHex=`printf '0x%08X' "$((10#$sumDecimal))"`
|
|
||||||
eval $__resultvar="'$outputHex'"
|
|
||||||
}
|
|
||||||
|
|
||||||
# Function to round, via masking, a hex value with another value.
|
|
||||||
# ie. 0x20028932 & 0x2002F000 = 0x20028000
|
|
||||||
function roundHex
|
|
||||||
{
|
|
||||||
local __resultvar=$3
|
|
||||||
local inputHex1=`echo $1 | tr 'a-z' 'A-Z'|sed 's/0X//g'`
|
|
||||||
TEST=$(( 16#$inputHex1 )) 2> /dev/null
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
FatalUsage "Param 1:$1/$inputHex1 is not hexadecimal."
|
|
||||||
fi
|
|
||||||
local inputHex2=`echo $2 | tr 'a-z' 'A-Z'|sed 's/0X//g'`
|
|
||||||
TEST=$(( 16#$inputHex2 )) 2> /dev/null
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
FatalUsage "Param 2:$2/$inputHex2 is not hexadecimal."
|
|
||||||
fi
|
|
||||||
local outputHex=`printf '0x%08X' "$((16#$inputHex1 & 16#$inputHex2))"`
|
|
||||||
eval $__resultvar="'$outputHex'"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#########################################################################################
|
|
||||||
# Check enviroment
|
|
||||||
#########################################################################################
|
|
||||||
|
|
||||||
# Correct directory to start.
|
|
||||||
cd ${BUILDPATH}
|
|
||||||
|
|
||||||
# Preload default values into parameter/control variables.
|
|
||||||
#
|
|
||||||
DEBUGMODE=0;
|
|
||||||
TRACEMODE=0;
|
|
||||||
CPU=EVO;
|
|
||||||
OS=ZPUTA;
|
|
||||||
IOCP_VERSION=3;
|
|
||||||
BRAM_SIZE=0x10000;
|
|
||||||
getHex 0x01000 OS_BASEADDR;
|
|
||||||
getHex 0x0C000 APP_BASEADDR;
|
|
||||||
APP_LEN=0x02000;
|
|
||||||
APP_BOOTLEN=0x20; # Fixed size as this is the jump table to make calls within ZPUTA.
|
|
||||||
APP_HEAP_SIZE=0x1000;
|
|
||||||
APP_STACK_SIZE=0x400;
|
|
||||||
OS_HEAP_SIZE=0x4000;
|
|
||||||
OS_STACK_SIZE=0x1000;
|
|
||||||
TRANZPUTER=0
|
|
||||||
SHARPMZ=0
|
|
||||||
OSVER=2;
|
|
||||||
|
|
||||||
# Process parameters, loading up variables as necessary.
|
|
||||||
#
|
|
||||||
if [ $# -gt 0 ]; then
|
|
||||||
while getopts ":hC:I:O:o:M:B:A:N:n:S:s:da:xTZ" opt; do
|
|
||||||
case $opt in
|
|
||||||
d) DEBUGMODE=1;;
|
|
||||||
C) CPU=`echo ${OPTARG} | tr 'a-z' 'A-Z'`;;
|
|
||||||
I) IOCP_VERSION=${OPTARG};;
|
|
||||||
O) OS=`echo ${OPTARG} | tr 'a-z' 'A-Z'`;;
|
|
||||||
o) OSVER=${OPTARG};;
|
|
||||||
M) getHex ${OPTARG} BRAM_SIZE;;
|
|
||||||
B) getHex ${OPTARG} OS_BASEADDR;;
|
|
||||||
A) getHex ${OPTARG} APP_BASEADDR;;
|
|
||||||
N) getHex ${OPTARG} OS_HEAP_SIZE;;
|
|
||||||
n) getHex ${OPTARG} APP_HEAP_SIZE;;
|
|
||||||
S) getHex ${OPTARG} OS_STACK_SIZE;;
|
|
||||||
s) getHex ${OPTARG} APP_STACK_SIZE;;
|
|
||||||
a) getHex ${OPTARG} APP_LEN;;
|
|
||||||
T) TRANZPUTER=1;;
|
|
||||||
Z) SHARPMZ=1;;
|
|
||||||
x) set -x; TRACEMODE=1;;
|
|
||||||
h) Usage;;
|
|
||||||
\?) FatalUsage "Unknown option: -${OPTARG}";;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
shift $(($OPTIND - 1 ))
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check the program to build is correct
|
|
||||||
if [ "${OS}" != "ZPUTA" -a "${OS}" != "ZOS" ]; then
|
|
||||||
FatalUsage "Given <os> is not valid, must be 'zputa' or 'zos'"
|
|
||||||
fi
|
|
||||||
if [ "${OS}" = "ZPUTA" ]; then
|
|
||||||
OSTYPE="__ZPUTA__"
|
|
||||||
else
|
|
||||||
OSTYPE="__ZOS__"
|
|
||||||
fi
|
|
||||||
OSNAME=`echo ${OS} | tr 'A-Z' 'a-z'`
|
|
||||||
|
|
||||||
# -C <CPU> = Small, Medium, Flex, Evo, K64F - defaults to Evo.
|
|
||||||
# Check the CPU is correctly defined.
|
|
||||||
if [ "${CPU}" != "SMALL" -a "${CPU}" != "MEDIUM" -a "${CPU}" != "FLEX" -a "${CPU}" != "EVO" -a "${CPU}" != "EVOMIN" -a "${CPU}" != "K64F" -a "${CPU}" != "M68K" ]; then
|
|
||||||
FatalUsage "Given <cpu> is not valid, must be one of 'Small', 'Medium', 'Flex', 'Evo', 'K64F', 'M68K'"
|
|
||||||
fi
|
|
||||||
if [ ${CPU} = "K64F" ]; then
|
|
||||||
CPUTYPE="__K64F__"
|
|
||||||
elif [ ${CPU} = "M68K" ]; then
|
|
||||||
CPUTYPE="__M68K__"
|
|
||||||
else
|
|
||||||
CPUTYPE="__ZPU__"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check the addresses for K64F, cannot use the default ZPU values.
|
|
||||||
if [ "${CPU}" = "K64F" -a "${OS_BASEADDR}" = "0x00001000" -a "${APP_BASEADDR}" = "0x0000C000" ]; then
|
|
||||||
getHex 0x00000000 OS_BASEADDR;
|
|
||||||
getHex 0x1fff0000 APP_BASEADDR;
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check IOCP_VERSION which has no meaning for the K64F/M68K processors.
|
|
||||||
if [ "${CPU}" = "K64F" -a "${IOCP_VERSION}" != "3" ]; then
|
|
||||||
Fatal "-I < iocp ver> has no meaning for the K64F, there is no version or indeed no need for IOCP on this processor."
|
|
||||||
elif [ "${CPU}" = "M68K" -a "${IOCP_VERSION}" != "3" ]; then
|
|
||||||
Fatal "-I < iocp ver> has no meaning for the M68K, there is no version or indeed no need for IOCP on this processor."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Check OSVER which has no meaning for the K64F/M68K processors.
|
|
||||||
if [ "${CPU}" = "K64F" -a "${OSVER}" != "2" ]; then
|
|
||||||
Fatal "-o <os ver> has no meaning for the K64F, base is in Flash RAM and applications, if SD card enabled, are in RAM."
|
|
||||||
elif [ "${CPU}" = "M68K" -a "${OSVER}" != "2" ]; then
|
|
||||||
Fatal "-o <os ver> has no meaning for the M68K, base is in Flash RAM and applications, if SD card enabled, are in RAM."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Setup any specific build options.
|
|
||||||
if [ ${TRANZPUTER} -eq 1 ]; then
|
|
||||||
if [ "${CPU}" = "K64F" -a "${OS}" = "ZOS" ]; then
|
|
||||||
BUILDFLAGS="__TRANZPUTER__=1"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Setup any specific build options.
|
|
||||||
if [ ${SHARPMZ} -eq 1 ]; then
|
|
||||||
if [[ "${CPU}" != "EVO" && "${CPU}" != "M68K" ]] || [[ "${OS}" != "ZOS" ]]; then
|
|
||||||
Fatal "-Z only valid for zOS build on ZPU hardware."
|
|
||||||
fi
|
|
||||||
if [[ "${CPU}" = "EVO" || "${CPU}" = "M68K" ]] && [[ "${OS}" = "ZOS" ]]; then
|
|
||||||
BUILDFLAGS="__SHARPMZ__=1"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Clear out the build target directory.
|
|
||||||
rm -fr ${BUILDPATH}/build
|
|
||||||
mkdir -p ${BUILDPATH}/build
|
|
||||||
mkdir -p ${BUILDPATH}/build/SD
|
|
||||||
|
|
||||||
# Build message according to CPU Type
|
|
||||||
if [ "${CPUTYPE}" = "__ZPU__" ]; then
|
|
||||||
Log "Building: ${OS}, OS_BASEADDR=${OS_BASEADDR}, APP_BASEADDR=${APP_BASEADDR} ..."
|
|
||||||
elif [ "${CPUTYPE}" = "__K64F__" ]; then
|
|
||||||
Log "Building: ${OS} ..."
|
|
||||||
elif [ "${CPUTYPE}" = "__M68K__" ]; then
|
|
||||||
Log "Building: ${OS} ..."
|
|
||||||
else
|
|
||||||
Fatal "Internal error, unrecognised CPUTYPE at Build Info"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Stack start address (at the moment) is top of BRAM less 8 bytes (2 words), standard for the ZPU. There is
|
|
||||||
# no reason though why this cant be a fixed address determined by the developer in any memory location.
|
|
||||||
subHex ${BRAM_SIZE} 8 STACK_STARTADDR
|
|
||||||
|
|
||||||
# Build the libraries for this platform.
|
|
||||||
cd ${BUILDPATH}/libraries
|
|
||||||
make ${CPUTYPE}=1 CPU=${CPU} all
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
Fatal "Aborting, failed to build the libraries for the ${CPUTYPE} processor."
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Setup the bootloader if the OS is not standalone.
|
|
||||||
#
|
|
||||||
#if [ "${OSVER}" -ne 0 ]; then
|
|
||||||
|
|
||||||
# IOCP is only needed by the ZPU family.
|
|
||||||
if [ "${CPUTYPE}" = "__ZPU__" ]; then
|
|
||||||
|
|
||||||
# Setup variables to meet the required IOCP configuration.
|
|
||||||
#
|
|
||||||
FUNCTIONALITY=${IOCP_VERSION}
|
|
||||||
if [ ${IOCP_VERSION} = 0 ]; then
|
|
||||||
IOCP_BASEADDR=0x000000;
|
|
||||||
IOCP_BOOTLEN=0x000400;
|
|
||||||
IOCP_STARTADDR=0x000400;
|
|
||||||
IOCP_LEN=0x003700;
|
|
||||||
OS_SD_TARGET="BOOT.ROM"
|
|
||||||
elif [ ${IOCP_VERSION} = 1 ]; then
|
|
||||||
IOCP_BASEADDR=0x000000;
|
|
||||||
IOCP_BOOTLEN=0x000400;
|
|
||||||
IOCP_STARTADDR=0x000400;
|
|
||||||
IOCP_LEN=0x002000;
|
|
||||||
OS_SD_TARGET="BOOT.ROM"
|
|
||||||
elif [ ${IOCP_VERSION} = 2 ]; then
|
|
||||||
IOCP_BASEADDR=0x000000;
|
|
||||||
IOCP_BOOTLEN=0x000400;
|
|
||||||
IOCP_STARTADDR=0x000400;
|
|
||||||
IOCP_LEN=0x002000;
|
|
||||||
OS_SD_TARGET="BOOT.ROM"
|
|
||||||
elif [ ${IOCP_VERSION} = 3 ]; then
|
|
||||||
IOCP_BASEADDR=0x000000;
|
|
||||||
IOCP_BOOTLEN=0x000400;
|
|
||||||
IOCP_STARTADDR=0x000400;
|
|
||||||
IOCP_LEN=0x001000;
|
|
||||||
OS_SD_TARGET="BOOTTINY.ROM"
|
|
||||||
else
|
|
||||||
FatalUsage "Illegal IOCP Version."
|
|
||||||
fi
|
|
||||||
IOCP_SD_TARGET="IOCP_${FUNCTIONALITY}_${IOCP_BASEADDR}.bin"
|
|
||||||
addHex ${IOCP_BASEADDR} ${IOCP_LEN} IOCP_APPADDR
|
|
||||||
|
|
||||||
if [ $DEBUGMODE -eq 1 ]; then
|
|
||||||
Log "IOCP_BASEADDR=${IOCP_BASEADDR}, IOCP_BOOTLEN=${IOCP_BOOTLEN}, IOCP_STARTADDR=${IOCP_STARTADDR}, IOCP_LEN=${IOCP_LEN}, OS_SD_TARGET=${OS_SD_TARGET}"
|
|
||||||
fi
|
|
||||||
|
|
||||||
Log "Building IOCP version - ${IOCP_VERSION}"
|
|
||||||
cat ${BUILDPATH}/startup/iocp_bram.tmpl | sed -e "s/BOOTADDR/${IOCP_BASEADDR}/g" \
|
|
||||||
-e "s/BOOTLEN/${IOCP_BOOTLEN}/g" \
|
|
||||||
-e "s/IOCPSTART/${IOCP_STARTADDR}/g" \
|
|
||||||
-e "s/IOCPLEN/${IOCP_LEN}/g" \
|
|
||||||
-e "s/STACK_SIZE/${STACK_SIZE}/g" \
|
|
||||||
-e "s/STACK_ADDR/${STACK_STARTADDR}/g" > ${BUILDPATH}/startup/iocp_bram_${IOCP_BASEADDR}.ld
|
|
||||||
cd ${BUILDPATH}/iocp
|
|
||||||
make ${CPUTYPE}=1 clean
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
Fatal "Aborting, failed to clean IOCP build environment!"
|
|
||||||
fi
|
|
||||||
|
|
||||||
Log "make ${CPUTYPE}=1 IOCP_BASEADDR=${IOCP_BASEADDR} IOCP_APPADDR=${IOCP_APPADDR} FUNCTIONALITY=${FUNCTIONALITY} CPU=${CPU}"
|
|
||||||
make ${CPUTYPE}=1 IOCP_BASEADDR=${IOCP_BASEADDR} IOCP_APPADDR=${IOCP_APPADDR} FUNCTIONALITY=${FUNCTIONALITY} CPU=${CPU}
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
Fatal "Aborting, failed to build IOCP!"
|
|
||||||
fi
|
|
||||||
cp ${BUILDPATH}/iocp/iocp.bin ${BUILDPATH}/build/${IOCP_SD_TARGET}
|
|
||||||
fi
|
|
||||||
#fi
|
|
||||||
|
|
||||||
# Setup variables to meet the required zOS/ZPUTA configuration.
|
|
||||||
# 0 - Standalone, 1 - As app with IOCP Bootloader, 2 - As app with tiny IOCP Bootloader, 3 - As app in RAM
|
|
||||||
# For CPU Type K64F all parameters are static.
|
|
||||||
if [ "${CPUTYPE}" = "__K64F__" ]; then
|
|
||||||
OSBUILDSTR="${OSNAME}_k64f"
|
|
||||||
OS_BOOTADDR=0x000000;
|
|
||||||
OS_BASEADDR=0x000000;
|
|
||||||
OS_BOOTLEN=0x000000;
|
|
||||||
|
|
||||||
elif [ "${CPUTYPE}" = "__ZPU__" ]; then
|
|
||||||
if [ ${OSVER} = 0 ]; then
|
|
||||||
OSBUILDSTR="${OSNAME}_standalone_boot_in_bram"
|
|
||||||
OS_BOOTADDR=0x000000;
|
|
||||||
OS_BASEADDR=0x000000;
|
|
||||||
OS_BOOTLEN=0x000600;
|
|
||||||
elif [ ${OSVER} = 1 ]; then
|
|
||||||
OSBUILDSTR="${OSNAME}_with_iocp_in_bram"
|
|
||||||
OS_BOOTADDR=${OS_BASEADDR};
|
|
||||||
OS_BOOTLEN=0x000200;
|
|
||||||
elif [ ${OSVER} = 2 ]; then
|
|
||||||
OSBUILDSTR="${OSNAME}_with_tiny_iocp_in_bram"
|
|
||||||
OS_BOOTADDR=${OS_BASEADDR};
|
|
||||||
OS_BOOTLEN=0x000200;
|
|
||||||
elif [ ${OSVER} = 3 ]; then
|
|
||||||
OSBUILDSTR="${OSNAME}_as_app_in_ram"
|
|
||||||
OS_BOOTADDR=${OS_BASEADDR};
|
|
||||||
OS_BOOTLEN=0x000200;
|
|
||||||
else
|
|
||||||
FatalUsage "Illegal OS Version."
|
|
||||||
fi
|
|
||||||
elif [ "${CPUTYPE}" = "__M68K__" ]; then
|
|
||||||
#OSBUILDSTR="${OSNAME}_m68k"
|
|
||||||
OSBUILDSTR="${OSNAME}_standalone_boot_in_bram"
|
|
||||||
OS_BOOTADDR=0x000000;
|
|
||||||
OS_BASEADDR=0x000000;
|
|
||||||
OS_BOOTLEN=0x000000;
|
|
||||||
fi
|
|
||||||
|
|
||||||
# For the ZPU, the start of the Boot loader, OS and application can change so need to calculate the Boot start and len, OS start and len, application Start and len.
|
|
||||||
if [ "${CPUTYPE}" = "__ZPU__" ]; then
|
|
||||||
# Calculate the Start address of the OS. The OS has a Boot Address followed by a reserved space for microcode and hooks before the main OS code.
|
|
||||||
addHex ${OS_BOOTLEN} ${OS_BASEADDR} OS_STARTADDR
|
|
||||||
|
|
||||||
# Calculate the Start address of the Application. An Application has a Boot Address, a reserved space for OS Hooks and then the application start.
|
|
||||||
addHex ${APP_BOOTLEN} ${APP_BASEADDR} APP_STARTADDR
|
|
||||||
|
|
||||||
# Calculate the maximum Application length by subtracting the size of the BRAM - Application Start - Stack Space
|
|
||||||
if [ "${APP_LEN}" = "" -a $(( 16#`echo ${APP_STARTADDR} | tr 'a-z' 'A-Z'|sed 's/0X//g'` )) -lt $(( 16#`echo ${BRAM_SIZE} | tr 'a-z' 'A-Z'|sed 's/0X//g'` )) ]; then
|
|
||||||
subHex ${BRAM_SIZE} ${APP_STARTADDR} APP_LEN
|
|
||||||
subHex ${APP_LEN} 0x20 APP_LEN
|
|
||||||
|
|
||||||
# If the APPLEN isnt set, give it a meaningful default.
|
|
||||||
elif [ $(( 16#`echo ${APP_LEN} | tr 'a-z' 'A-Z'|sed 's/0X//g'` )) -eq 0 ]; then
|
|
||||||
APP_LEN=0x10000;
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Calculate the start of the Operating system code as the first section from the boot address is reserved.
|
|
||||||
addHex ${OS_BOOTADDR} ${OS_BOOTLEN} OS_STARTADDR
|
|
||||||
|
|
||||||
# Calculate the length of the OS which is the start address of the App less the Boot address of the OS.
|
|
||||||
subHex ${APP_BASEADDR} ${OS_BOOTADDR} OS_LEN
|
|
||||||
subHex ${OS_LEN} ${OS_BOOTLEN} OS_LEN
|
|
||||||
|
|
||||||
# Calculate the heap and stack vars.
|
|
||||||
subHex ${BRAM_SIZE} 8 OS_STACK_ENDADDR
|
|
||||||
subHex ${OS_STACK_ENDADDR} ${OS_STACK_SIZE} OS_STACK_STARTADDR
|
|
||||||
subHex ${OS_STACK_STARTADDR} 4 OS_HEAP_ENDADDR
|
|
||||||
subHex ${OS_HEAP_ENDADDR} ${OS_HEAP_SIZE} OS_HEAP_STARTADDR
|
|
||||||
|
|
||||||
# Stack start address for the APP. Normally this isnt used as the stack from zOS/ZPUTA is maintained, but available incase of
|
|
||||||
# need for a local stack.
|
|
||||||
addHex ${APP_STARTADDR} ${APP_LEN} APP_ENDADDR
|
|
||||||
#subHex ${APP_ENDADDR} ${OS_STACK_SIZE} APP_ENDADDR
|
|
||||||
subHex ${APP_ENDADDR} 8 APP_STACK_ENDADDR
|
|
||||||
subHex ${APP_STACK_ENDADDR} ${APP_STACK_SIZE} APP_STACK_STARTADDR
|
|
||||||
|
|
||||||
# Calculate the heap start and end.
|
|
||||||
subHex ${APP_STACK_STARTADDR} 4 APP_HEAP_ENDADDR
|
|
||||||
subHex ${APP_HEAP_ENDADDR} ${APP_HEAP_SIZE} APP_HEAP_STARTADDR
|
|
||||||
|
|
||||||
elif [ "${CPUTYPE}" = "__K64F__" ]; then
|
|
||||||
|
|
||||||
# For the K64F the OS location and size is the 512K Flash RAM, this can be changed if a bootloader is installed before zOS.
|
|
||||||
OS_STARTADDR=0x00000000
|
|
||||||
addHex ${OS_STARTADDR} 0x00080000 OS_LEN
|
|
||||||
|
|
||||||
# Calculate the heap, stack and RAM start address vars.
|
|
||||||
OS_RAM_ENDADDR=0x20030000
|
|
||||||
OS_RAM_MASK=0x3FFFF000
|
|
||||||
OS_RAM_OSMEM=0x010000
|
|
||||||
subHex ${OS_RAM_ENDADDR} 8 OS_STACK_ENDADDR
|
|
||||||
subHex ${OS_RAM_ENDADDR} ${OS_STACK_SIZE} OS_STACK_STARTADDR
|
|
||||||
roundHex ${OS_STACK_STARTADDR} ${OS_RAM_MASK} OS_STACK_STARTADDR
|
|
||||||
subHex ${OS_STACK_STARTADDR} 4 OS_HEAP_ENDADDR
|
|
||||||
subHex ${OS_HEAP_ENDADDR} ${OS_HEAP_SIZE} OS_HEAP_STARTADDR
|
|
||||||
roundHex ${OS_HEAP_STARTADDR} ${OS_RAM_MASK} OS_HEAP_STARTADDR
|
|
||||||
subHex ${OS_HEAP_STARTADDR} ${OS_RAM_OSMEM} OS_RAM_STARTADDR
|
|
||||||
roundHex ${OS_RAM_STARTADDR} ${OS_RAM_MASK} OS_RAM_STARTADDR
|
|
||||||
subHex ${OS_RAM_ENDADDR} ${OS_RAM_STARTADDR} OS_RAM_LEN
|
|
||||||
|
|
||||||
# For the K64F, the APP address start is as given on the command line or inbuilt default. The APPLEN is MAX RAM - APP Start Address.
|
|
||||||
APP_STARTADDR=${APP_BASEADDR}
|
|
||||||
APP_ENDADDR=${OS_RAM_STARTADDR}
|
|
||||||
APP_RAM_MASK=0xFFFFF000
|
|
||||||
subHex ${APP_ENDADDR} ${APP_BASEADDR} APP_LEN
|
|
||||||
|
|
||||||
# Stack start address for the APP. Normally this isnt used as the stack from zOS/ZPUTA is maintained, but available incase of
|
|
||||||
# need for a local stack.
|
|
||||||
subHex ${APP_ENDADDR} 8 APP_STACK_ENDADDR
|
|
||||||
subHex ${APP_STACK_ENDADDR} ${APP_STACK_SIZE} APP_STACK_STARTADDR
|
|
||||||
roundHex ${APP_STACK_STARTADDR} ${APP_RAM_MASK} APP_STACK_STARTADDR
|
|
||||||
|
|
||||||
# Calculate the heap start and end.
|
|
||||||
subHex ${APP_STACK_STARTADDR} 0 APP_HEAP_ENDADDR
|
|
||||||
subHex ${APP_HEAP_ENDADDR} ${APP_HEAP_SIZE} APP_HEAP_STARTADDR
|
|
||||||
roundHex ${APP_HEAP_STARTADDR} ${APP_RAM_MASK} APP_HEAP_STARTADDR
|
|
||||||
|
|
||||||
#subHex ${APP_STACK_STARTADDR} ${APP_STARTADDR} APP_STACK_STARTADDR
|
|
||||||
# subHex ${APP_HEAP_STARTADDR} ${APP_STARTADDR} APP_HEAP_STARTADDR
|
|
||||||
|
|
||||||
elif [ "${CPUTYPE}" = "__M68K__" ]; then
|
|
||||||
|
|
||||||
# Calculate the Start address of the OS. The OS has a Boot Address followed by a reserved space for microcode and hooks before the main OS code.
|
|
||||||
addHex ${OS_BOOTLEN} ${OS_BASEADDR} OS_STARTADDR
|
|
||||||
|
|
||||||
# Calculate the Start address of the Application. An Application has a Boot Address, a reserved space for OS Hooks and then the application start.
|
|
||||||
addHex ${APP_BOOTLEN} ${APP_BASEADDR} APP_STARTADDR
|
|
||||||
|
|
||||||
# Calculate the maximum Application length by subtracting the size of the BRAM - Application Start - Stack Space
|
|
||||||
if [ "${APP_LEN}" = "" -a $(( 16#`echo ${APP_STARTADDR} | tr 'a-z' 'A-Z'|sed 's/0X//g'` )) -lt $(( 16#`echo ${BRAM_SIZE} | tr 'a-z' 'A-Z'|sed 's/0X//g'` )) ]; then
|
|
||||||
subHex ${BRAM_SIZE} ${APP_STARTADDR} APP_LEN
|
|
||||||
subHex ${APP_LEN} 0x20 APP_LEN
|
|
||||||
|
|
||||||
# If the APPLEN isnt set, give it a meaningful default.
|
|
||||||
elif [ $(( 16#`echo ${APP_LEN} | tr 'a-z' 'A-Z'|sed 's/0X//g'` )) -eq 0 ]; then
|
|
||||||
APP_LEN=0x10000;
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Calculate the start of the Operating system code as the first section from the boot address is reserved.
|
|
||||||
addHex ${OS_BOOTADDR} ${OS_BOOTLEN} OS_STARTADDR
|
|
||||||
|
|
||||||
# Calculate the length of the OS which is the start address of the App less the Boot address of the OS.
|
|
||||||
subHex ${APP_BASEADDR} ${OS_BOOTADDR} OS_LEN
|
|
||||||
subHex ${OS_LEN} ${OS_BOOTLEN} OS_LEN
|
|
||||||
|
|
||||||
# Calculate the heap and stack vars.
|
|
||||||
subHex ${BRAM_SIZE} 8 OS_STACK_ENDADDR
|
|
||||||
subHex ${OS_STACK_ENDADDR} ${OS_STACK_SIZE} OS_STACK_STARTADDR
|
|
||||||
subHex ${OS_STACK_STARTADDR} 4 OS_HEAP_ENDADDR
|
|
||||||
subHex ${OS_HEAP_ENDADDR} ${OS_HEAP_SIZE} OS_HEAP_STARTADDR
|
|
||||||
|
|
||||||
# Stack start address for the APP. Normally this isnt used as the stack from zOS/ZPUTA is maintained, but available incase of
|
|
||||||
# need for a local stack.
|
|
||||||
addHex ${APP_STARTADDR} ${APP_LEN} APP_ENDADDR
|
|
||||||
#subHex ${APP_ENDADDR} ${OS_STACK_SIZE} APP_ENDADDR
|
|
||||||
subHex ${APP_ENDADDR} 8 APP_STACK_ENDADDR
|
|
||||||
subHex ${APP_STACK_ENDADDR} ${APP_STACK_SIZE} APP_STACK_STARTADDR
|
|
||||||
|
|
||||||
# Calculate the heap start and end.
|
|
||||||
subHex ${APP_STACK_STARTADDR} 4 APP_HEAP_ENDADDR
|
|
||||||
subHex ${APP_HEAP_ENDADDR} ${APP_HEAP_SIZE} APP_HEAP_STARTADDR
|
|
||||||
|
|
||||||
else
|
|
||||||
Fatal "Internal error, unrecognised CPUTYPE at calcblock"
|
|
||||||
fi
|
|
||||||
|
|
||||||
Debug "OS_BASEADDR=${OS_BASEADDR}, OS_BOOTLEN=${OS_BOOTLEN}, OS_STARTADDR=${OS_STARTADDR}, OS_LEN=${OS_LEN}"
|
|
||||||
Debug "OS_RAM_STARTADDR=${OS_RAM_STARTADDR}, OS_RAM_ENDADDR=${OS_RAM_ENDADDR}, OS_RAM_LEN=${OS_RAM_LEN}, OS_RAM_MASK=${OS_RAM_MASK}, OS_RAM_OSMEM=${OS_RAM_OSMEM}"
|
|
||||||
Debug "OS_STACK_STARTADDR=${OS_STACK_STARTADDR}, OS_STACK_ENDADDR=${OS_STACK_ENDADDR}, OS_STACK_SIZE=${OS_STACK_SIZE}, OS_HEAP_STARTADDR=${OS_HEAP_STARTADDR}, OS_HEAP_ENDADDR=${OS_HEAP_ENDADDR} OS_HEAP_SIZE=${OS_HEAP_SIZE}"
|
|
||||||
Debug "APP_BASEADDR=${APP_BASEADDR}, APP_BOOTLEN=${APP_BOOTLEN}, APP_STARTADDR=${APP_STARTADDR}, APP_ENDADDR=${APP_ENDADDR}, APP_RAM_MASK=${APP_RAM_MASK}, APP_LEN=${APP_LEN}"
|
|
||||||
Debug "APP_STACK_STARTADDR=${APP_STACK_STARTADDR}, APP_STACK_ENDADDR=${APP_STACK_ENDADDR}, APP_STACK_SIZE=${APP_STACK_SIZE}, APP_HEAP_STARTADDR=${APP_HEAP_STARTADDR}, APP_HEAP_ENDADDR=${APP_HEAP_ENDADDR}, APP_HEAP_SIZE=${APP_HEAP_SIZE}"
|
|
||||||
|
|
||||||
# Build according to desired OS and target processor.
|
|
||||||
if [ "${OS}" = "ZPUTA" ]; then
|
|
||||||
|
|
||||||
# Build the ZPUTA link script based on given and calculated values.
|
|
||||||
Log "ZPUTA - ${OSBUILDSTR}"
|
|
||||||
if [ "${CPUTYPE}" = "__ZPU__" ]; then
|
|
||||||
TMPLFILE=${BUILDPATH}/startup/zputa_zpu.tmpl
|
|
||||||
elif [ "${CPUTYPE}" = "__ZPU__" ]; then
|
|
||||||
TMPLFILE=${BUILDPATH}/startup/zputa_k64f.tmpl
|
|
||||||
elif [ "${CPUTYPE}" = "__M68K__" ]; then
|
|
||||||
TMPLFILE=${BUILDPATH}/startup/zputa_m68k.tmpl
|
|
||||||
else
|
|
||||||
Fatal "Internal error, unrecognised CPUTYPE at zputa cfg"
|
|
||||||
fi
|
|
||||||
cat ${TMPLFILE} | sed -e "s/BOOTADDR/${OS_BOOTADDR}/g" \
|
|
||||||
-e "s/BOOTLEN/${OS_BOOTLEN}/g" \
|
|
||||||
-e "s/OS_START/${OS_STARTADDR}/g" \
|
|
||||||
-e "s/OS_LEN/${OS_LEN}/g" \
|
|
||||||
-e "s/OS_RAM_STARTADDR/${OS_RAM_STARTADDR}/g" \
|
|
||||||
-e "s/OS_RAM_LEN/${OS_RAM_LEN}/g" \
|
|
||||||
-e "s/HEAP_SIZE/${OS_HEAP_SIZE}/g" \
|
|
||||||
-e "s/HEAP_STARTADDR/${OS_HEAP_STARTADDR}/g" \
|
|
||||||
-e "s/HEAP_ENDADDR/${OS_HEAP_ENDADDR}/g" \
|
|
||||||
-e "s/STACK_SIZE/${OS_STACK_SIZE}/g" \
|
|
||||||
-e "s/STACK_STARTADDR/${OS_STACK_STARTADDR}/g" \
|
|
||||||
-e "s/STACK_ENDADDR/${OS_STACK_ENDADDR}/g" \
|
|
||||||
-e "s/STACK_ADDR/${OS_STACK_STARTADDR}/g" > ${BUILDPATH}/startup/${OSBUILDSTR}.ld
|
|
||||||
|
|
||||||
cd ${BUILDPATH}/zputa
|
|
||||||
make ${CPUTYPE}=1 ${OSTYPE}=1 ${BUILDFLAGS} clean
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
Fatal "Aborting, failed to clean ZPUTA build environment!"
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${CPUTYPE}" = "__ZPU__" ]; then
|
|
||||||
Log "make ${OSBUILDSTR} ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} ${BUILDFLAGS}"
|
|
||||||
make ${OSBUILDSTR} ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} ${BUILDFLAGS}
|
|
||||||
elif [ "${CPUTYPE}" = "__K64F__" ]; then
|
|
||||||
Log "make ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} ${BUILDFLAGS}"
|
|
||||||
make ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} ${BUILDFLAGS}
|
|
||||||
elif [ "${CPUTYPE}" = "__M68K__" ]; then
|
|
||||||
Log "make ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} ${BUILDFLAGS}"
|
|
||||||
make ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} ${BUILDFLAGS}
|
|
||||||
else
|
|
||||||
Fatal "Internal error, unrecognised CPUTYPE at ZPUTA Make"
|
|
||||||
fi
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
Fatal "Aborting, failed to build ZPUTA!"
|
|
||||||
fi
|
|
||||||
cp ${BUILDPATH}/zputa/${OSBUILDSTR}.bin ${BUILDPATH}/build/SD/${OS_SD_TARGET}
|
|
||||||
|
|
||||||
elif [ "${OS}" = "ZOS" ]; then
|
|
||||||
|
|
||||||
# Build the zOS link script based on given and calculated values.
|
|
||||||
Log "zOS - ${OSBUILDSTR}"
|
|
||||||
if [ "${CPUTYPE}" = "__ZPU__" ]; then
|
|
||||||
TMPLFILE=${BUILDPATH}/startup/zos_zpu.tmpl
|
|
||||||
elif [ "${CPUTYPE}" = "__K64F__" ]; then
|
|
||||||
TMPLFILE=${BUILDPATH}/startup/zos_k64f.tmpl
|
|
||||||
elif [ "${CPUTYPE}" = "__M68K__" ]; then
|
|
||||||
TMPLFILE=${BUILDPATH}/startup/zos_m68k.tmpl
|
|
||||||
else
|
|
||||||
Fatal "Internal error, unrecognised CPUTYPE at zos cfg"
|
|
||||||
fi
|
|
||||||
cat ${TMPLFILE} | sed -e "s/BOOTADDR/${OS_BOOTADDR}/g" \
|
|
||||||
-e "s/BOOTLEN/${OS_BOOTLEN}/g" \
|
|
||||||
-e "s/OS_START/${OS_STARTADDR}/g" \
|
|
||||||
-e "s/OS_LEN/${OS_LEN}/g" \
|
|
||||||
-e "s/OS_RAM_STARTADDR/${OS_RAM_STARTADDR}/g" \
|
|
||||||
-e "s/OS_RAM_LEN/${OS_RAM_LEN}/g" \
|
|
||||||
-e "s/HEAP_SIZE/${OS_HEAP_SIZE}/g" \
|
|
||||||
-e "s/HEAP_STARTADDR/${OS_HEAP_STARTADDR}/g" \
|
|
||||||
-e "s/HEAP_ENDADDR/${OS_HEAP_ENDADDR}/g" \
|
|
||||||
-e "s/STACK_SIZE/${OS_STACK_SIZE}/g" \
|
|
||||||
-e "s/STACK_STARTADDR/${OS_STACK_STARTADDR}/g" \
|
|
||||||
-e "s/STACK_ENDADDR/${OS_STACK_ENDADDR}/g" \
|
|
||||||
-e "s/STACK_ADDR/${OS_STACK_STARTADDR}/g" > ${BUILDPATH}/startup/${OSBUILDSTR}.ld
|
|
||||||
|
|
||||||
cd ${BUILDPATH}/zOS
|
|
||||||
make ${CPUTYPE}=1 ${OSTYPE}=1 clean
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
Fatal "Aborting, failed to clean zOS build environment!"
|
|
||||||
fi
|
|
||||||
if [ "${CPUTYPE}" = "__ZPU__" ]; then
|
|
||||||
Log "make ${OSBUILDSTR} ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} HEAPADDR=${OS_HEAP_STARTADDR} HEAPSIZE=${OS_HEAP_SIZE} STACKADDR=${OS_STACK_STARTADDR} STACKENDADDR=${OS_STACK_ENDADDR} STACKSIZE=${OS_STACK_SIZE} ${BUILDFLAGS}"
|
|
||||||
make ${OSBUILDSTR} ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} HEAPADDR=${OS_HEAP_STARTADDR} HEAPSIZE=${OS_HEAP_SIZE} STACKADDR=${OS_STACK_STARTADDR} STACKENDADDR=${OS_STACK_ENDADDR} STACKSIZE=${OS_STACK_SIZE} ${BUILDFLAGS}
|
|
||||||
elif [ "${CPUTYPE}" = "__K64F__" ]; then
|
|
||||||
Log "make ${OSBUILDSTR} ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} HEAPADDR=${OS_HEAP_STARTADDR} HEAPSIZE=${OS_HEAP_SIZE} STACKADDR=${OS_STACK_STARTADDR} STACKENDADDR=${OS_STACK_ENDADDR} STACKSIZE=${OS_STACK_SIZE} ${BUILDFLAGS}"
|
|
||||||
Log "make ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} HEAPADDR=${OS_HEAP_STARTADDR} HEAPSIZE=${OS_HEAP_SIZE} STACKADDR=${OS_STACK_STARTADDR} STACKENDADDR=${OS_STACK_ENDADDR} STACKSIZE=${OS_STACK_SIZE} ${BUILDFLAGS}"
|
|
||||||
make ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} HEAPADDR=${OS_HEAP_STARTADDR} HEAPSIZE=${OS_HEAP_SIZE} STACKADDR=${OS_STACK_STARTADDR} STACKENDADDR=${OS_STACK_ENDADDR} STACKSIZE=${OS_STACK_SIZE} ${BUILDFLAGS}
|
|
||||||
elif [ "${CPUTYPE}" = "__M68K__" ]; then
|
|
||||||
Log "make ${OSBUILDSTR} ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} HEAPADDR=${OS_HEAP_STARTADDR} HEAPSIZE=${OS_HEAP_SIZE} STACKADDR=${OS_STACK_STARTADDR} STACKENDADDR=${OS_STACK_ENDADDR} STACKSIZE=${OS_STACK_SIZE} ${BUILDFLAGS}"
|
|
||||||
make ${OSBUILDSTR} ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} HEAPADDR=${OS_HEAP_STARTADDR} HEAPSIZE=${OS_HEAP_SIZE} STACKADDR=${OS_STACK_STARTADDR} STACKENDADDR=${OS_STACK_ENDADDR} STACKSIZE=${OS_STACK_SIZE} ${BUILDFLAGS}
|
|
||||||
else
|
|
||||||
Fatal "Internal error, unrecognised CPUTYPE at ZOS Make"
|
|
||||||
fi
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
Fatal "Aborting, failed to build zOS!"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Also create a copy of the OS for use by the tranZPUter SW-700 project.
|
|
||||||
mkdir -p ${BUILDPATH}/build/SD/ZOS
|
|
||||||
if [ "${CPUTYPE}" = "__ZPU__" ]; then
|
|
||||||
cp ${BUILDPATH}/zOS/${OSBUILDSTR}.bin ${BUILDPATH}/build/SD/${OS_SD_TARGET}
|
|
||||||
cp ${BUILDPATH}/zOS/${OSBUILDSTR}.bin ${BUILDPATH}/build/SD/ZOS/ZOS.ROM
|
|
||||||
elif [ "${CPUTYPE}" = "__K64F__" ]; then
|
|
||||||
cp ${BUILDPATH}/zOS/main.bin ${BUILDPATH}/build/SD/${OS_SD_TARGET}
|
|
||||||
cp ${BUILDPATH}/zOS/main.bin ${BUILDPATH}/build/SD/ZOS/ZOS.K64F.ROM
|
|
||||||
elif [ "${CPUTYPE}" = "__M68K__" ]; then
|
|
||||||
cp ${BUILDPATH}/zOS/main.bin ${BUILDPATH}/build/SD/${OS_SD_TARGET}
|
|
||||||
cp ${BUILDPATH}/zOS/main.bin ${BUILDPATH}/build/SD/ZOS/ZOS.M68K.ROM
|
|
||||||
else
|
|
||||||
Fatal "Internal error, unrecognised CPUTYPE at ZOS Copy"
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Build the apps and install into the build tree.
|
|
||||||
# For ZPU the location and size depends on FPGA resources so create a dynamic linker template. For K64F it is a static design but the heap size is variable so we also
|
|
||||||
# need to generate a dynamic linker template. This is now performed within the Makefile passing necessary variables to Make.
|
|
||||||
#
|
|
||||||
if [ "${CPUTYPE}" = "__ZPU__" ]; then
|
|
||||||
TMPLFILE=${BUILDPATH}/startup/app_${OSNAME}_zpu.tmpl
|
|
||||||
LDFILE=${BUILDPATH}/startup/app_zpu_${OS_BOOTADDR}_${APP_BASEADDR}.ld
|
|
||||||
elif [ "${CPUTYPE}" = "__K64F__" ]; then
|
|
||||||
TMPLFILE=${BUILDPATH}/startup/app_${OSNAME}_k64f.tmpl
|
|
||||||
LDFILE=${BUILDPATH}/startup/app_k64f_${OS_BOOTADDR}_${APP_BASEADDR}.ld
|
|
||||||
elif [ "${CPUTYPE}" = "__M68K__" ]; then
|
|
||||||
TMPLFILE=${BUILDPATH}/startup/app_${OSNAME}_m68k.tmpl
|
|
||||||
LDFILE=${BUILDPATH}/startup/app_m68k_${OS_BOOTADDR}_${APP_BASEADDR}.ld
|
|
||||||
else
|
|
||||||
Fatal "Internal error, unrecognised CPUTYPE at LD tmpl setup"
|
|
||||||
fi
|
|
||||||
|
|
||||||
cd ${BUILDPATH}/apps
|
|
||||||
Log "make ${CPUTYPE}=1 ${OSTYPE}=1 ${BUILDFLAGS} clean"
|
|
||||||
make ${CPUTYPE}=1 ${OSTYPE}=1 ${BUILDFLAGS} clean
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
Fatal "Aborting, failed to clean Apps build environment!"
|
|
||||||
fi
|
|
||||||
Log "make ${CPUTYPE} ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} TMPLFILE=${TMPLFILE} BASEADDR=${APP_BASEADDR} BASELEN=${APP_BOOTLEN} HEAPADDR=${APP_HEAP_STARTADDR} HEAPSIZE=${APP_HEAP_SIZE} STACKADDR=${APP_STACK_STARTADDR} STACKENDADDR=${APP_STACK_ENDADDR} STACKSIZE=${APP_STACK_SIZE} APPSTART=${APP_STARTADDR} APPSIZE=${APP_LEN} ${BUILDFLAGS}"
|
|
||||||
make ${CPUTYPE}=1 ${OSTYPE}=1 OS_BASEADDR=${OS_BOOTADDR} OS_APPADDR=${APP_BASEADDR} CPU=${CPU} TMPLFILE=${TMPLFILE} BASEADDR=${APP_BASEADDR} BASELEN=${APP_BOOTLEN} HEAPADDR=${APP_HEAP_STARTADDR} HEAPSIZE=${APP_HEAP_SIZE} STACKADDR=${APP_STACK_STARTADDR} STACKENDADDR=${APP_STACK_ENDADDR} STACKSIZE=${APP_STACK_SIZE} APPSTART=${APP_STARTADDR} APPSIZE=${APP_LEN} ${BUILDFLAGS}
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
Fatal "Aborting, failed to build Apps!"
|
|
||||||
fi
|
|
||||||
mkdir -p bin
|
|
||||||
rm -f bin/*
|
|
||||||
Log "make ${CPUTYPE}=1 ${OSTYPE}=1 ${BUILDFLAGS} install"
|
|
||||||
make ${CPUTYPE}=1 ${OSTYPE}=1 ${BUILDFLAGS} install
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
Fatal "Aborting, failed to install generated binaries!"
|
|
||||||
fi
|
|
||||||
cp -r ${BUILDPATH}/apps/bin ${BUILDPATH}/build/SD/bin
|
|
||||||
165
zOS/MZ2000/buildall
vendored
165
zOS/MZ2000/buildall
vendored
@@ -1,165 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Not used: Target machine, used to select the right software for the SD card.
|
|
||||||
# TARGET=MZ-700
|
|
||||||
# TARGET=MZ-80A
|
|
||||||
TARGET=MZ-2000
|
|
||||||
|
|
||||||
ZPU_SHARPMZ_BUILD=0
|
|
||||||
#ZPU_SHARPMZ_APPADDR=0x100000
|
|
||||||
#ZPU_SHARPMZ_APPSIZE=0x70000
|
|
||||||
#ZPU_SHARPMZ_HEAPSIZE=0x8000
|
|
||||||
#ZPU_SHARPMZ_STACKSIZE=0x3D80
|
|
||||||
|
|
||||||
ZPU_SHARPMZ_APPADDR=0x100000
|
|
||||||
ZPU_SHARPMZ_APPSIZE=0x70000
|
|
||||||
ZPU_SHARPMZ_HEAPSIZE=0x8000
|
|
||||||
ZPU_SHARPMZ_STACKSIZE=0x3D80
|
|
||||||
|
|
||||||
ZPU_E115_BUILD=0
|
|
||||||
ZPU_E115_APPADDR=0x10000
|
|
||||||
ZPU_E115_APPSIZE=0x8000
|
|
||||||
ZPU_E115_HEAPSIZE=0x4000
|
|
||||||
ZPU_E115_STACKSIZE=0x3D80
|
|
||||||
|
|
||||||
echo "Build target: ${TARGET}"
|
|
||||||
|
|
||||||
# NB: When setting this variable, see lower section creating the SD card image which uses a hard coded value and will need updating.
|
|
||||||
ROOT_DIR=/dvlp/Projects/dev/github/
|
|
||||||
# NB: This clean out is intentionally hard coded as -fr is dangerous, if a variable failed to be set if could see your source base wiped out.
|
|
||||||
rm -fr /dvlp/Projects/dev/github/zSoft/SD/K64F/*
|
|
||||||
|
|
||||||
(
|
|
||||||
# Ensure the zOS target directories exist.
|
|
||||||
cd ${ROOT_DIR}/zSoft
|
|
||||||
mkdir -p SD/SharpMZ
|
|
||||||
mkdir -p SD/Dev
|
|
||||||
mkdir -p SD/K64F/ZOS
|
|
||||||
|
|
||||||
if [ "${ZPU_SHARPMZ_BUILD}x" != "x" -a ${ZPU_SHARPMZ_BUILD} = 1 ]; then
|
|
||||||
echo "Building ZPU for Sharp MZ"
|
|
||||||
./build.sh -C EVO -O zos -o 0 -M 0x1FD80 -B 0x0000 -S ${ZPU_SHARPMZ_STACKSIZE} -N ${ZPU_SHARPMZ_HEAPSIZE} -A ${ZPU_SHARPMZ_APPADDR} -a ${ZPU_SHARPMZ_APPSIZE} -n 0x0000 -s 0x0000 -d -Z
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "Error building Sharp MZ Distribution..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Copy the BRAM ROM templates to the build area for the FPGA.
|
|
||||||
cp rtl/TZSW_* ../tranZPUter/FPGA/SW700/v1.3/devices/sysbus/BRAM/
|
|
||||||
# Copy the newly built files into the staging area ready for copying to an SD card.
|
|
||||||
cp -r build/SD/* SD/SharpMZ/
|
|
||||||
# The K64F needs a copy of the zOS ROM for the ZPU so that it can load it into the FPGA.
|
|
||||||
cp build/SD/ZOS/* SD/K64F/ZOS/
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${ZPU_E115_BUILD}x" != "x" -a ${ZPU_E115_BUILD} = 1 ]; then
|
|
||||||
echo "Building ZPU for Dev board"
|
|
||||||
./build.sh -C EVO -O zos -o 0 -M 0x1FD80 -B 0x0000 -S ${ZPU_E115_STACKSIZE} -N ${ZPU_E115_HEAPSIZE} -A ${ZPU_E115_APPADDR} -a ${ZPU_E115_APPSIZE} -n 0x0000 -s 0x0000 -d
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "Error building Dev board Distribution..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
cp rtl/zOS_* rtl/IOCP* rtl/ZPUTA* ../zpu/devices/sysbus/BRAM/
|
|
||||||
cp -r build/SD/* SD/Dev/
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [ "${TARGET}x" != "x" -a "${TARGET}" = "MZ-80A" ]; then
|
|
||||||
echo "Building for K64F on MZ-80A"
|
|
||||||
./build.sh -C K64F -O zos -N 0x10000 -d -T
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "Error building K64F Distribution..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
elif [ "${TARGET}x" != "x" -a "${TARGET}" = "MZ-2000" ]; then
|
|
||||||
echo "Building for K64F on MZ-2000"
|
|
||||||
./build.sh -C K64F -O zos -N 0x10000 -d -T
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "Error building K64F Distribution..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Building for K64F"
|
|
||||||
./build.sh -C K64F -O zos -N 0x18000 -d -T
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "Error building K64F Distribution..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
cp -r build/SD/* SD/K64F/
|
|
||||||
|
|
||||||
# Ensure the TZFS target directories exist
|
|
||||||
k64fsddir=${ROOT_DIR}/zSoft/SD/K64F
|
|
||||||
tzfsdir=${ROOT_DIR}/tranZPUter/software
|
|
||||||
#mkdir -p $k64fsddir/TZFS/
|
|
||||||
#mkdir -p $k64fsddir/MZF/
|
|
||||||
#mkdir -p $k64fsddir/CPM/
|
|
||||||
#mkdir -p $k64fsddir/BAS
|
|
||||||
#mkdir -p $k64fsddir/CAS
|
|
||||||
|
|
||||||
(
|
|
||||||
cd $tzfsdir
|
|
||||||
tools/assemble_tzfs.sh
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "TZFS assembly failed..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
tools/assemble_roms.sh
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "ROMS assembly failed..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
tools/assemble_cpm.sh
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "CPM assembly failed..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
tools/make_cpmdisks.sh
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "CPM disks assembly failed..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
)
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Copy the files to the remote build server.
|
|
||||||
cd ${ROOT_DIR}/zSoft
|
|
||||||
rsync -avh * psmart@192.168.15.205:${ROOT_DIR}/zSoft/
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "Error syncing K64F Distribution..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Simple mechanism to prevent remote build and programming of the K64F.
|
|
||||||
diff ${ROOT_DIR}/zSoft/zOS/main.bin ${ROOT_DIR}/zSoft/zOS/main.bak
|
|
||||||
if [ $? -ne 0 ]; then
|
|
||||||
cd ${ROOT_DIR}/zSoft
|
|
||||||
echo "GO" > ${ROOT_DIR}/zSoft/.dobuild
|
|
||||||
rsync -avh .dobuild psmart@192.168.15.205:${ROOT_DIR}/zSoft/
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "Error syncing K64F Distribution..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
cp ${ROOT_DIR}/zSoft/zOS/main.bin ${ROOT_DIR}/zSoft/zOS/main.bak
|
|
||||||
)
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Use copytosd.sh to transfer files to an SD card. Still need to copy the k64F files manually.
|
|
||||||
# ---------------
|
|
||||||
# Copy across all the Z80/TZFS software into the target, keep it in one place for placing onto an SD card!
|
|
||||||
#cp $tzfsdir/roms/tzfs.rom $k64fsddir/TZFS/
|
|
||||||
#cp $tzfsdir/roms/monitor_SA1510.rom $k64fsddir/TZFS/SA1510.rom
|
|
||||||
#cp $tzfsdir/roms/monitor_80c_SA1510.rom $k64fsddir/TZFS/SA1510-8.rom
|
|
||||||
#cp $tzfsdir/roms/monitor_1Z-013A.rom $k64fsddir/TZFS/1Z-013A.rom
|
|
||||||
#cp $tzfsdir/roms/monitor_80c_1Z-013A.rom $k64fsddir/TZFS/1Z-013A-8.rom
|
|
||||||
#cp $tzfsdir/roms/monitor_1Z-013A-KM.rom $k64fsddir/TZFS/1Z-013A-KM.rom
|
|
||||||
#cp $tzfsdir/roms/monitor_80c_1Z-013A-KM.rom $k64fsddir/TZFS/1Z-013A-KM-8.rom
|
|
||||||
#cp $tzfsdir/roms/MZ80B_IPL.rom $k64fsddir/TZFS/MZ80B_IPL.rom
|
|
||||||
#cp $tzfsdir/roms/cpm22.bin $k64fsddir/CPM/
|
|
||||||
#cp $tzfsdir/CPM/SDC16M/RAW/* $k64fsddir/CPM/
|
|
||||||
#cp $tzfsdir/MZF/Common/*.MZF $k64fsddir/MZF/
|
|
||||||
#cp $tzfsdir/MZF/${TARGET}/* $k64fsddir/MZF/
|
|
||||||
#cp $tzfsdir/BAS/* $k64fsddir/BAS/
|
|
||||||
#cp $tzfsdir/CAS/* $k64fsddir/CAS/
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
|
|
||||||
# Not used: Target machine, used to select the right software for the SD card.
|
|
||||||
# TARGET=MZ-700
|
|
||||||
# TARGET=MZ-80A
|
|
||||||
|
|
||||||
M68K_SHARPMZ_BUILD=1
|
|
||||||
M68K_SHARPMZ_APPADDR=0x100000
|
|
||||||
M68K_SHARPMZ_APPSIZE=0x70000
|
|
||||||
M68K_SHARPMZ_HEAPSIZE=0x8000
|
|
||||||
M68K_SHARPMZ_STACKSIZE=0x3D80
|
|
||||||
|
|
||||||
|
|
||||||
# NB: When setting this variable, see lower section creating the SD card image which uses a hard coded value and will need updating.
|
|
||||||
ROOT_DIR=/dvlp/Projects/dev/github/
|
|
||||||
# NB: This clean out is intentionally hard coded as -fr is dangerous, if a variable failed to be set if could see your source base wiped out.
|
|
||||||
rm -fr /dvlp/Projects/dev/github/zSoft/SD/M68K/*
|
|
||||||
|
|
||||||
(
|
|
||||||
# Ensure the zOS target directories exist.
|
|
||||||
cd ${ROOT_DIR}/zSoft
|
|
||||||
mkdir -p SD/SharpMZ
|
|
||||||
mkdir -p SD/Dev
|
|
||||||
mkdir -p SD/M68K/ZOS
|
|
||||||
|
|
||||||
if [ "${M68K_SHARPMZ_BUILD}x" != "x" -a ${M68K_SHARPMZ_BUILD} = 1 ]; then
|
|
||||||
echo "Building M68K for Sharp MZ"
|
|
||||||
./build.sh -C M68K -O zos -M 0x1FD80 -B 0x0000 -S ${M68K_SHARPMZ_STACKSIZE} -N ${M68K_SHARPMZ_HEAPSIZE} -A ${M68K_SHARPMZ_APPADDR} -a ${M68K_SHARPMZ_APPSIZE} -n 0x0000 -s 0x0000 -d -Z
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
echo "Error building Sharp MZ Distribution..."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
# Copy the BRAM ROM templates to the build area for the FPGA.
|
|
||||||
# cp rtl/TZSW_* ../tranZPUter/FPGA/SW700/v1.3/devices/sysbus/BRAM/
|
|
||||||
# Copy the newly built files into the staging area ready for copying to an SD card.
|
|
||||||
# cp -r build/SD/* SD/SharpMZ/
|
|
||||||
# The K64F needs a copy of the zOS ROM for the ZPU so that it can load it into the FPGA.
|
|
||||||
# cp build/SD/ZOS/* SD/K64F/ZOS/
|
|
||||||
fi
|
|
||||||
|
|
||||||
)
|
|
||||||
if [ $? != 0 ]; then
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
@@ -1,494 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
Original Author: Shay Gal-on
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "coremark.h"
|
|
||||||
/*
|
|
||||||
Topic: Description
|
|
||||||
Benchmark using a linked list.
|
|
||||||
|
|
||||||
Linked list is a common data structure used in many applications.
|
|
||||||
|
|
||||||
For our purposes, this will excercise the memory units of the processor.
|
|
||||||
In particular, usage of the list pointers to find and alter data.
|
|
||||||
|
|
||||||
We are not using Malloc since some platforms do not support this library.
|
|
||||||
|
|
||||||
Instead, the memory block being passed in is used to create a list,
|
|
||||||
and the benchmark takes care not to add more items then can be
|
|
||||||
accomodated by the memory block. The porting layer will make sure
|
|
||||||
that we have a valid memory block.
|
|
||||||
|
|
||||||
All operations are done in place, without using any extra memory.
|
|
||||||
|
|
||||||
The list itself contains list pointers and pointers to data items.
|
|
||||||
Data items contain the following:
|
|
||||||
|
|
||||||
idx - An index that captures the initial order of the list.
|
|
||||||
data - Variable data initialized based on the input parameters. The 16b are divided as follows:
|
|
||||||
o Upper 8b are backup of original data.
|
|
||||||
o Bit 7 indicates if the lower 7 bits are to be used as is or calculated.
|
|
||||||
o Bits 0-2 indicate type of operation to perform to get a 7b value.
|
|
||||||
o Bits 3-6 provide input for the operation.
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* local functions */
|
|
||||||
|
|
||||||
list_head *core_list_find(list_head *list,list_data *info);
|
|
||||||
list_head *core_list_reverse(list_head *list);
|
|
||||||
list_head *core_list_remove(list_head *item);
|
|
||||||
list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified);
|
|
||||||
list_head *core_list_insert_new(list_head *insert_point
|
|
||||||
, list_data *info, list_head **memblock, list_data **datablock
|
|
||||||
, list_head *memblock_end, list_data *datablock_end);
|
|
||||||
typedef ee_s32(*list_cmp)(list_data *a, list_data *b, core_results *res);
|
|
||||||
list_head *core_list_mergesort(list_head *list, list_cmp cmp, core_results *res);
|
|
||||||
|
|
||||||
ee_s16 calc_func(ee_s16 *pdata, core_results *res) {
|
|
||||||
ee_s16 data=*pdata;
|
|
||||||
ee_s16 retval;
|
|
||||||
ee_u8 optype=(data>>7) & 1; /* bit 7 indicates if the function result has been cached */
|
|
||||||
if (optype) /* if cached, use cache */
|
|
||||||
return (data & 0x007f);
|
|
||||||
else { /* otherwise calculate and cache the result */
|
|
||||||
ee_s16 flag=data & 0x7; /* bits 0-2 is type of function to perform */
|
|
||||||
ee_s16 dtype=((data>>3) & 0xf); /* bits 3-6 is specific data for the operation */
|
|
||||||
dtype |= dtype << 4; /* replicate the lower 4 bits to get an 8b value */
|
|
||||||
switch (flag) {
|
|
||||||
case 0:
|
|
||||||
if (dtype<0x22) /* set min period for bit corruption */
|
|
||||||
dtype=0x22;
|
|
||||||
retval=core_bench_state(res->size,res->memblock[3],res->seed1,res->seed2,dtype,res->crc);
|
|
||||||
if (res->crcstate==0)
|
|
||||||
res->crcstate=retval;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
retval=core_bench_matrix(&(res->mat),dtype,res->crc);
|
|
||||||
if (res->crcmatrix==0)
|
|
||||||
res->crcmatrix=retval;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
retval=data;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
res->crc=crcu16(retval,res->crc);
|
|
||||||
retval &= 0x007f;
|
|
||||||
*pdata = (data & 0xff00) | 0x0080 | retval; /* cache the result */
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Function: cmp_complex
|
|
||||||
Compare the data item in a list cell.
|
|
||||||
|
|
||||||
Can be used by mergesort.
|
|
||||||
*/
|
|
||||||
ee_s32 cmp_complex(list_data *a, list_data *b, core_results *res) {
|
|
||||||
ee_s16 val1=calc_func(&(a->data16),res);
|
|
||||||
ee_s16 val2=calc_func(&(b->data16),res);
|
|
||||||
return val1 - val2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: cmp_idx
|
|
||||||
Compare the idx item in a list cell, and regen the data.
|
|
||||||
|
|
||||||
Can be used by mergesort.
|
|
||||||
*/
|
|
||||||
ee_s32 cmp_idx(list_data *a, list_data *b, core_results *res) {
|
|
||||||
if (res==NULL) {
|
|
||||||
a->data16 = (a->data16 & 0xff00) | (0x00ff & (a->data16>>8));
|
|
||||||
b->data16 = (b->data16 & 0xff00) | (0x00ff & (b->data16>>8));
|
|
||||||
}
|
|
||||||
return a->idx - b->idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
void copy_info(list_data *to,list_data *from) {
|
|
||||||
to->data16=from->data16;
|
|
||||||
to->idx=from->idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Benchmark for linked list:
|
|
||||||
- Try to find multiple data items.
|
|
||||||
- List sort
|
|
||||||
- Operate on data from list (crc)
|
|
||||||
- Single remove/reinsert
|
|
||||||
* At the end of this function, the list is back to original state
|
|
||||||
*/
|
|
||||||
ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx) {
|
|
||||||
ee_u16 retval=0;
|
|
||||||
ee_u16 found=0,missed=0;
|
|
||||||
list_head *list=res->list;
|
|
||||||
ee_s16 find_num=res->seed3;
|
|
||||||
list_head *this_find;
|
|
||||||
list_head *finder, *remover;
|
|
||||||
list_data info;
|
|
||||||
ee_s16 i;
|
|
||||||
|
|
||||||
info.idx=finder_idx;
|
|
||||||
/* find <find_num> values in the list, and change the list each time (reverse and cache if value found) */
|
|
||||||
for (i=0; i<find_num; i++) {
|
|
||||||
info.data16= (i & 0xff) ;
|
|
||||||
this_find=core_list_find(list,&info);
|
|
||||||
list=core_list_reverse(list);
|
|
||||||
if (this_find==NULL) {
|
|
||||||
missed++;
|
|
||||||
retval+=(list->next->info->data16 >> 8) & 1;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
found++;
|
|
||||||
if (this_find->info->data16 & 0x1) /* use found value */
|
|
||||||
retval+=(this_find->info->data16 >> 9) & 1;
|
|
||||||
/* and cache next item at the head of the list (if any) */
|
|
||||||
if (this_find->next != NULL) {
|
|
||||||
finder = this_find->next;
|
|
||||||
this_find->next = finder->next;
|
|
||||||
finder->next=list->next;
|
|
||||||
list->next=finder;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (info.idx>=0)
|
|
||||||
info.idx++;
|
|
||||||
#if CORE_DEBUG
|
|
||||||
ee_printf("List find %d: [%d,%d,%d]\n",i,retval,missed,found);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
retval+=found*4-missed;
|
|
||||||
/* sort the list by data content and remove one item*/
|
|
||||||
if (finder_idx>0)
|
|
||||||
list=core_list_mergesort(list,cmp_complex,res);
|
|
||||||
remover=core_list_remove(list->next);
|
|
||||||
/* CRC data content of list from location of index N forward, and then undo remove */
|
|
||||||
finder=core_list_find(list,&info);
|
|
||||||
if (!finder)
|
|
||||||
finder=list->next;
|
|
||||||
while (finder) {
|
|
||||||
retval=crc16(list->info->data16,retval);
|
|
||||||
finder=finder->next;
|
|
||||||
}
|
|
||||||
#if CORE_DEBUG
|
|
||||||
ee_printf("List sort 1: %04x\n",retval);
|
|
||||||
#endif
|
|
||||||
remover=core_list_undo_remove(remover,list->next);
|
|
||||||
/* sort the list by index, in effect returning the list to original state */
|
|
||||||
list=core_list_mergesort(list,cmp_idx,NULL);
|
|
||||||
/* CRC data content of list */
|
|
||||||
finder=list->next;
|
|
||||||
while (finder) {
|
|
||||||
retval=crc16(list->info->data16,retval);
|
|
||||||
finder=finder->next;
|
|
||||||
}
|
|
||||||
#if CORE_DEBUG
|
|
||||||
ee_printf("List sort 2: %04x\n",retval);
|
|
||||||
#endif
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
/* Function: core_list_init
|
|
||||||
Initialize list with data.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
blksize - Size of memory to be initialized.
|
|
||||||
memblock - Pointer to memory block.
|
|
||||||
seed - Actual values chosen depend on the seed parameter.
|
|
||||||
The seed parameter MUST be supplied from a source that cannot be determined at compile time
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Pointer to the head of the list.
|
|
||||||
|
|
||||||
*/
|
|
||||||
list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed) {
|
|
||||||
/* calculated pointers for the list */
|
|
||||||
ee_u32 per_item=16+sizeof(struct list_data_s);
|
|
||||||
ee_u32 size=(blksize/per_item)-2; /* to accomodate systems with 64b pointers, and make sure same code is executed, set max list elements */
|
|
||||||
list_head *memblock_end=memblock+size;
|
|
||||||
list_data *datablock=(list_data *)(memblock_end);
|
|
||||||
list_data *datablock_end=datablock+size;
|
|
||||||
/* some useful variables */
|
|
||||||
ee_u32 i;
|
|
||||||
list_head *finder,*list=memblock;
|
|
||||||
list_data info;
|
|
||||||
/* create a fake items for the list head and tail */
|
|
||||||
list->next=NULL;
|
|
||||||
list->info=datablock;
|
|
||||||
list->info->idx=0x0000;
|
|
||||||
list->info->data16=(ee_s16)0x8080;
|
|
||||||
memblock++;
|
|
||||||
datablock++;
|
|
||||||
info.idx=0x7fff;
|
|
||||||
info.data16=(ee_s16)0xffff;
|
|
||||||
core_list_insert_new(list,&info,&memblock,&datablock,memblock_end,datablock_end);
|
|
||||||
|
|
||||||
/* then insert size items */
|
|
||||||
for (i=0; i<size; i++) {
|
|
||||||
ee_u16 datpat=((ee_u16)(seed^i) & 0xf);
|
|
||||||
ee_u16 dat=(datpat<<3) | (i&0x7); /* alternate between algorithms */
|
|
||||||
info.data16=(dat<<8) | dat; /* fill the data with actual data and upper bits with rebuild value */
|
|
||||||
core_list_insert_new(list,&info,&memblock,&datablock,memblock_end,datablock_end);
|
|
||||||
}
|
|
||||||
/* and now index the list so we know initial seed order of the list */
|
|
||||||
finder=list->next;
|
|
||||||
i=1;
|
|
||||||
while (finder->next!=NULL) {
|
|
||||||
if (i<size/5) /* first 20% of the list in order */
|
|
||||||
finder->info->idx=i++;
|
|
||||||
else {
|
|
||||||
ee_u16 pat=(ee_u16)(i++ ^ seed); /* get a pseudo random number */
|
|
||||||
finder->info->idx=0x3fff & (((i & 0x07) << 8) | pat); /* make sure the mixed items end up after the ones in sequence */
|
|
||||||
}
|
|
||||||
finder=finder->next;
|
|
||||||
}
|
|
||||||
list = core_list_mergesort(list,cmp_idx,NULL);
|
|
||||||
#if CORE_DEBUG
|
|
||||||
ee_printf("Initialized list:\n");
|
|
||||||
finder=list;
|
|
||||||
while (finder) {
|
|
||||||
ee_printf("[%04x,%04x]",finder->info->idx,(ee_u16)finder->info->data16);
|
|
||||||
finder=finder->next;
|
|
||||||
}
|
|
||||||
ee_printf("\n");
|
|
||||||
#endif
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: core_list_insert
|
|
||||||
Insert an item to the list
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
insert_point - where to insert the item.
|
|
||||||
info - data for the cell.
|
|
||||||
memblock - pointer for the list header
|
|
||||||
datablock - pointer for the list data
|
|
||||||
memblock_end - end of region for list headers
|
|
||||||
datablock_end - end of region for list data
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Pointer to new item.
|
|
||||||
*/
|
|
||||||
list_head *core_list_insert_new(list_head *insert_point, list_data *info, list_head **memblock, list_data **datablock
|
|
||||||
, list_head *memblock_end, list_data *datablock_end) {
|
|
||||||
list_head *newitem;
|
|
||||||
|
|
||||||
if ((*memblock+1) >= memblock_end)
|
|
||||||
return NULL;
|
|
||||||
if ((*datablock+1) >= datablock_end)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
newitem=*memblock;
|
|
||||||
(*memblock)++;
|
|
||||||
newitem->next=insert_point->next;
|
|
||||||
insert_point->next=newitem;
|
|
||||||
|
|
||||||
newitem->info=*datablock;
|
|
||||||
(*datablock)++;
|
|
||||||
copy_info(newitem->info,info);
|
|
||||||
|
|
||||||
return newitem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: core_list_remove
|
|
||||||
Remove an item from the list.
|
|
||||||
|
|
||||||
Operation:
|
|
||||||
For a singly linked list, remove by copying the data from the next item
|
|
||||||
over to the current cell, and unlinking the next item.
|
|
||||||
|
|
||||||
Note:
|
|
||||||
since there is always a fake item at the end of the list, no need to check for NULL.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Removed item.
|
|
||||||
*/
|
|
||||||
list_head *core_list_remove(list_head *item) {
|
|
||||||
list_data *tmp;
|
|
||||||
list_head *ret=item->next;
|
|
||||||
/* swap data pointers */
|
|
||||||
tmp=item->info;
|
|
||||||
item->info=ret->info;
|
|
||||||
ret->info=tmp;
|
|
||||||
/* and eliminate item */
|
|
||||||
item->next=item->next->next;
|
|
||||||
ret->next=NULL;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: core_list_undo_remove
|
|
||||||
Undo a remove operation.
|
|
||||||
|
|
||||||
Operation:
|
|
||||||
Since we want each iteration of the benchmark to be exactly the same,
|
|
||||||
we need to be able to undo a remove.
|
|
||||||
Link the removed item back into the list, and switch the info items.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
item_removed - Return value from the <core_list_remove>
|
|
||||||
item_modified - List item that was modified during <core_list_remove>
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
The item that was linked back to the list.
|
|
||||||
|
|
||||||
*/
|
|
||||||
list_head *core_list_undo_remove(list_head *item_removed, list_head *item_modified) {
|
|
||||||
list_data *tmp;
|
|
||||||
/* swap data pointers */
|
|
||||||
tmp=item_removed->info;
|
|
||||||
item_removed->info=item_modified->info;
|
|
||||||
item_modified->info=tmp;
|
|
||||||
/* and insert item */
|
|
||||||
item_removed->next=item_modified->next;
|
|
||||||
item_modified->next=item_removed;
|
|
||||||
return item_removed;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: core_list_find
|
|
||||||
Find an item in the list
|
|
||||||
|
|
||||||
Operation:
|
|
||||||
Find an item by idx (if not 0) or specific data value
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
list - list head
|
|
||||||
info - idx or data to find
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Found item, or NULL if not found.
|
|
||||||
*/
|
|
||||||
list_head *core_list_find(list_head *list,list_data *info) {
|
|
||||||
if (info->idx>=0) {
|
|
||||||
while (list && (list->info->idx != info->idx))
|
|
||||||
list=list->next;
|
|
||||||
return list;
|
|
||||||
} else {
|
|
||||||
while (list && ((list->info->data16 & 0xff) != info->data16))
|
|
||||||
list=list->next;
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Function: core_list_reverse
|
|
||||||
Reverse a list
|
|
||||||
|
|
||||||
Operation:
|
|
||||||
Rearrange the pointers so the list is reversed.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
list - list head
|
|
||||||
info - idx or data to find
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Found item, or NULL if not found.
|
|
||||||
*/
|
|
||||||
|
|
||||||
list_head *core_list_reverse(list_head *list) {
|
|
||||||
list_head *next=NULL, *tmp;
|
|
||||||
while (list) {
|
|
||||||
tmp=list->next;
|
|
||||||
list->next=next;
|
|
||||||
next=list;
|
|
||||||
list=tmp;
|
|
||||||
}
|
|
||||||
return next;
|
|
||||||
}
|
|
||||||
/* Function: core_list_mergesort
|
|
||||||
Sort the list in place without recursion.
|
|
||||||
|
|
||||||
Description:
|
|
||||||
Use mergesort, as for linked list this is a realistic solution.
|
|
||||||
Also, since this is aimed at embedded, care was taken to use iterative rather then recursive algorithm.
|
|
||||||
The sort can either return the list to original order (by idx) ,
|
|
||||||
or use the data item to invoke other other algorithms and change the order of the list.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
list - list to be sorted.
|
|
||||||
cmp - cmp function to use
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
New head of the list.
|
|
||||||
|
|
||||||
Note:
|
|
||||||
We have a special header for the list that will always be first,
|
|
||||||
but the algorithm could theoretically modify where the list starts.
|
|
||||||
|
|
||||||
*/
|
|
||||||
list_head *core_list_mergesort(list_head *list, list_cmp cmp, core_results *res) {
|
|
||||||
list_head *p, *q, *e, *tail;
|
|
||||||
ee_s32 insize, nmerges, psize, qsize, i;
|
|
||||||
|
|
||||||
insize = 1;
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
p = list;
|
|
||||||
list = NULL;
|
|
||||||
tail = NULL;
|
|
||||||
|
|
||||||
nmerges = 0; /* count number of merges we do in this pass */
|
|
||||||
|
|
||||||
while (p) {
|
|
||||||
nmerges++; /* there exists a merge to be done */
|
|
||||||
/* step `insize' places along from p */
|
|
||||||
q = p;
|
|
||||||
psize = 0;
|
|
||||||
for (i = 0; i < insize; i++) {
|
|
||||||
psize++;
|
|
||||||
q = q->next;
|
|
||||||
if (!q) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* if q hasn't fallen off end, we have two lists to merge */
|
|
||||||
qsize = insize;
|
|
||||||
|
|
||||||
/* now we have two lists; merge them */
|
|
||||||
while (psize > 0 || (qsize > 0 && q)) {
|
|
||||||
|
|
||||||
/* decide whether next element of merge comes from p or q */
|
|
||||||
if (psize == 0) {
|
|
||||||
/* p is empty; e must come from q. */
|
|
||||||
e = q; q = q->next; qsize--;
|
|
||||||
} else if (qsize == 0 || !q) {
|
|
||||||
/* q is empty; e must come from p. */
|
|
||||||
e = p; p = p->next; psize--;
|
|
||||||
} else if (cmp(p->info,q->info,res) <= 0) {
|
|
||||||
/* First element of p is lower (or same); e must come from p. */
|
|
||||||
e = p; p = p->next; psize--;
|
|
||||||
} else {
|
|
||||||
/* First element of q is lower; e must come from q. */
|
|
||||||
e = q; q = q->next; qsize--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add the next element to the merged list */
|
|
||||||
if (tail) {
|
|
||||||
tail->next = e;
|
|
||||||
} else {
|
|
||||||
list = e;
|
|
||||||
}
|
|
||||||
tail = e;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* now p has stepped `insize' places along, and q has too */
|
|
||||||
p = q;
|
|
||||||
}
|
|
||||||
|
|
||||||
tail->next = NULL;
|
|
||||||
|
|
||||||
/* If we have done only one merge, we're finished. */
|
|
||||||
if (nmerges <= 1) /* allow for nmerges==0, the empty list case */
|
|
||||||
return list;
|
|
||||||
|
|
||||||
/* Otherwise repeat, merging lists twice the size */
|
|
||||||
insize *= 2;
|
|
||||||
}
|
|
||||||
#if COMPILER_REQUIRES_SORT_RETURN
|
|
||||||
return list;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
@@ -1,356 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
Original Author: Shay Gal-on
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* File: core_main.c
|
|
||||||
This file contains the framework to acquire a block of memory, seed initial parameters, tun t he benchmark and report the results.
|
|
||||||
*/
|
|
||||||
#include "coremark.h"
|
|
||||||
|
|
||||||
/* Function: iterate
|
|
||||||
Run the benchmark for a specified number of iterations.
|
|
||||||
|
|
||||||
Operation:
|
|
||||||
For each type of benchmarked algorithm:
|
|
||||||
a - Initialize the data block for the algorithm.
|
|
||||||
b - Execute the algorithm N times.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
NULL.
|
|
||||||
*/
|
|
||||||
static ee_u16 list_known_crc[] = {(ee_u16)0xd4b0,(ee_u16)0x3340,(ee_u16)0x6a79,(ee_u16)0xe714,(ee_u16)0xe3c1};
|
|
||||||
static ee_u16 matrix_known_crc[] = {(ee_u16)0xbe52,(ee_u16)0x1199,(ee_u16)0x5608,(ee_u16)0x1fd7,(ee_u16)0x0747};
|
|
||||||
static ee_u16 state_known_crc[] = {(ee_u16)0x5e47,(ee_u16)0x39bf,(ee_u16)0xe5a4,(ee_u16)0x8e3a,(ee_u16)0x8d84};
|
|
||||||
void *iterate(void *pres) {
|
|
||||||
ee_u32 i;
|
|
||||||
ee_u16 crc;
|
|
||||||
core_results *res=(core_results *)pres;
|
|
||||||
ee_u32 iterations=res->iterations;
|
|
||||||
res->crc=0;
|
|
||||||
res->crclist=0;
|
|
||||||
res->crcmatrix=0;
|
|
||||||
res->crcstate=0;
|
|
||||||
|
|
||||||
for (i=0; i<iterations; i++) {
|
|
||||||
crc=core_bench_list(res,1);
|
|
||||||
res->crc=crcu16(crc,res->crc);
|
|
||||||
crc=core_bench_list(res,-1);
|
|
||||||
res->crc=crcu16(crc,res->crc);
|
|
||||||
if (i==0) res->crclist=res->crc;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (SEED_METHOD==SEED_ARG)
|
|
||||||
ee_s32 get_seed_args(int i, int argc, char *argv[]);
|
|
||||||
#define get_seed(x) (ee_s16)get_seed_args(x,argc,argv)
|
|
||||||
#define get_seed_32(x) get_seed_args(x,argc,argv)
|
|
||||||
#else /* via function or volatile */
|
|
||||||
ee_s32 get_seed_32(int i);
|
|
||||||
#define get_seed(x) (ee_s16)get_seed_32(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (MEM_METHOD==MEM_STATIC)
|
|
||||||
ee_u8 static_memblk[TOTAL_DATA_SIZE];
|
|
||||||
#endif
|
|
||||||
char *mem_name[3] = {"Static","Heap","Stack"};
|
|
||||||
/* Function: main
|
|
||||||
Main entry routine for the benchmark.
|
|
||||||
This function is responsible for the following steps:
|
|
||||||
|
|
||||||
1 - Initialize input seeds from a source that cannot be determined at compile time.
|
|
||||||
2 - Initialize memory block for use.
|
|
||||||
3 - Run and time the benchmark.
|
|
||||||
4 - Report results, testing the validity of the output if the seeds are known.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
1 - first seed : Any value
|
|
||||||
2 - second seed : Must be identical to first for iterations to be identical
|
|
||||||
3 - third seed : Any value, should be at least an order of magnitude less then the input size, but bigger then 32.
|
|
||||||
4 - Iterations : Special, if set to 0, iterations will be automatically determined such that the benchmark will run between 10 to 100 secs
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if MAIN_HAS_NOARGC
|
|
||||||
MAIN_RETURN_TYPE main(void) {
|
|
||||||
int argc=0;
|
|
||||||
char *argv[1];
|
|
||||||
#else
|
|
||||||
MAIN_RETURN_TYPE main(int argc, char *argv[]) {
|
|
||||||
#endif
|
|
||||||
ee_u16 i,j=0,num_algorithms=0;
|
|
||||||
ee_s16 known_id=-1,total_errors=0;
|
|
||||||
ee_u16 seedcrc=0;
|
|
||||||
CORE_TICKS total_time;
|
|
||||||
core_results results[MULTITHREAD];
|
|
||||||
#if (MEM_METHOD==MEM_STACK)
|
|
||||||
ee_u8 stack_memblock[TOTAL_DATA_SIZE*MULTITHREAD];
|
|
||||||
#endif
|
|
||||||
/* first call any initializations needed */
|
|
||||||
portable_init(&(results[0].port), &argc, argv);
|
|
||||||
/* First some checks to make sure benchmark will run ok */
|
|
||||||
if (sizeof(struct list_head_s)>128) {
|
|
||||||
ee_printf("list_head structure too big for comparable data!\n");
|
|
||||||
return MAIN_RETURN_VAL;
|
|
||||||
}
|
|
||||||
results[0].seed1=get_seed(1);
|
|
||||||
results[0].seed2=get_seed(2);
|
|
||||||
results[0].seed3=get_seed(3);
|
|
||||||
results[0].iterations=get_seed_32(4);
|
|
||||||
#if CORE_DEBUG
|
|
||||||
results[0].iterations=1;
|
|
||||||
#endif
|
|
||||||
results[0].execs=get_seed_32(5);
|
|
||||||
if (results[0].execs==0) { /* if not supplied, execute all algorithms */
|
|
||||||
results[0].execs=ALL_ALGORITHMS_MASK;
|
|
||||||
}
|
|
||||||
/* put in some default values based on one seed only for easy testing */
|
|
||||||
if ((results[0].seed1==0) && (results[0].seed2==0) && (results[0].seed3==0)) { /* validation run */
|
|
||||||
results[0].seed1=0;
|
|
||||||
results[0].seed2=0;
|
|
||||||
results[0].seed3=0x66;
|
|
||||||
}
|
|
||||||
if ((results[0].seed1==1) && (results[0].seed2==0) && (results[0].seed3==0)) { /* perfromance run */
|
|
||||||
results[0].seed1=0x3415;
|
|
||||||
results[0].seed2=0x3415;
|
|
||||||
results[0].seed3=0x66;
|
|
||||||
}
|
|
||||||
#if (MEM_METHOD==MEM_STATIC)
|
|
||||||
results[0].memblock[0]=(void *)static_memblk;
|
|
||||||
results[0].size=TOTAL_DATA_SIZE;
|
|
||||||
results[0].err=0;
|
|
||||||
#if (MULTITHREAD>1)
|
|
||||||
#error "Cannot use a static data area with multiple contexts!"
|
|
||||||
#endif
|
|
||||||
#elif (MEM_METHOD==MEM_MALLOC)
|
|
||||||
for (i=0 ; i<MULTITHREAD; i++) {
|
|
||||||
ee_s32 malloc_override=get_seed(7);
|
|
||||||
if (malloc_override != 0)
|
|
||||||
results[i].size=malloc_override;
|
|
||||||
else
|
|
||||||
results[i].size=TOTAL_DATA_SIZE;
|
|
||||||
results[i].memblock[0]=portable_malloc(results[i].size);
|
|
||||||
results[i].seed1=results[0].seed1;
|
|
||||||
results[i].seed2=results[0].seed2;
|
|
||||||
results[i].seed3=results[0].seed3;
|
|
||||||
results[i].err=0;
|
|
||||||
results[i].execs=results[0].execs;
|
|
||||||
}
|
|
||||||
#elif (MEM_METHOD==MEM_STACK)
|
|
||||||
for (i=0 ; i<MULTITHREAD; i++) {
|
|
||||||
results[i].memblock[0]=stack_memblock+i*TOTAL_DATA_SIZE;
|
|
||||||
results[i].size=TOTAL_DATA_SIZE;
|
|
||||||
results[i].seed1=results[0].seed1;
|
|
||||||
results[i].seed2=results[0].seed2;
|
|
||||||
results[i].seed3=results[0].seed3;
|
|
||||||
results[i].err=0;
|
|
||||||
results[i].execs=results[0].execs;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#error "Please define a way to initialize a memory block."
|
|
||||||
#endif
|
|
||||||
/* Data init */
|
|
||||||
/* Find out how space much we have based on number of algorithms */
|
|
||||||
for (i=0; i<NUM_ALGORITHMS; i++) {
|
|
||||||
if ((1<<(ee_u32)i) & results[0].execs)
|
|
||||||
num_algorithms++;
|
|
||||||
}
|
|
||||||
for (i=0 ; i<MULTITHREAD; i++)
|
|
||||||
results[i].size=results[i].size/num_algorithms;
|
|
||||||
/* Assign pointers */
|
|
||||||
for (i=0; i<NUM_ALGORITHMS; i++) {
|
|
||||||
ee_u32 ctx;
|
|
||||||
if ((1<<(ee_u32)i) & results[0].execs) {
|
|
||||||
for (ctx=0 ; ctx<MULTITHREAD; ctx++)
|
|
||||||
results[ctx].memblock[i+1]=(char *)(results[ctx].memblock[0])+results[0].size*j;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* call inits */
|
|
||||||
for (i=0 ; i<MULTITHREAD; i++) {
|
|
||||||
if (results[i].execs & ID_LIST) {
|
|
||||||
results[i].list=core_list_init(results[0].size,results[i].memblock[1],results[i].seed1);
|
|
||||||
}
|
|
||||||
if (results[i].execs & ID_MATRIX) {
|
|
||||||
core_init_matrix(results[0].size, results[i].memblock[2], (ee_s32)results[i].seed1 | (((ee_s32)results[i].seed2) << 16), &(results[i].mat) );
|
|
||||||
}
|
|
||||||
if (results[i].execs & ID_STATE) {
|
|
||||||
core_init_state(results[0].size,results[i].seed1,results[i].memblock[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* automatically determine number of iterations if not set */
|
|
||||||
if (results[0].iterations==0) {
|
|
||||||
secs_ret secs_passed=0;
|
|
||||||
ee_u32 divisor;
|
|
||||||
results[0].iterations=1;
|
|
||||||
while (secs_passed < (secs_ret)1) {
|
|
||||||
results[0].iterations*=10;
|
|
||||||
start_time();
|
|
||||||
iterate(&results[0]);
|
|
||||||
stop_time();
|
|
||||||
secs_passed=time_in_secs(get_time());
|
|
||||||
}
|
|
||||||
/* now we know it executes for at least 1 sec, set actual run time at about 10 secs */
|
|
||||||
divisor=(ee_u32)secs_passed;
|
|
||||||
if (divisor==0) /* some machines cast float to int as 0 since this conversion is not defined by ANSI, but we know at least one second passed */
|
|
||||||
divisor=1;
|
|
||||||
results[0].iterations*=1+10/divisor;
|
|
||||||
}
|
|
||||||
/* perform actual benchmark */
|
|
||||||
start_time();
|
|
||||||
#if (MULTITHREAD>1)
|
|
||||||
if (default_num_contexts>MULTITHREAD) {
|
|
||||||
default_num_contexts=MULTITHREAD;
|
|
||||||
}
|
|
||||||
for (i=0 ; i<default_num_contexts; i++) {
|
|
||||||
results[i].iterations=results[0].iterations;
|
|
||||||
results[i].execs=results[0].execs;
|
|
||||||
core_start_parallel(&results[i]);
|
|
||||||
}
|
|
||||||
for (i=0 ; i<default_num_contexts; i++) {
|
|
||||||
core_stop_parallel(&results[i]);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
iterate(&results[0]);
|
|
||||||
#endif
|
|
||||||
stop_time();
|
|
||||||
total_time=get_time();
|
|
||||||
/* get a function of the input to report */
|
|
||||||
seedcrc=crc16(results[0].seed1,seedcrc);
|
|
||||||
seedcrc=crc16(results[0].seed2,seedcrc);
|
|
||||||
seedcrc=crc16(results[0].seed3,seedcrc);
|
|
||||||
seedcrc=crc16(results[0].size,seedcrc);
|
|
||||||
|
|
||||||
switch (seedcrc) { /* test known output for common seeds */
|
|
||||||
case 0x8a02: /* seed1=0, seed2=0, seed3=0x66, size 2000 per algorithm */
|
|
||||||
known_id=0;
|
|
||||||
ee_printf("6k performance run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
case 0x7b05: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 2000 per algorithm */
|
|
||||||
known_id=1;
|
|
||||||
ee_printf("6k validation run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
case 0x4eaf: /* seed1=0x8, seed2=0x8, seed3=0x8, size 400 per algorithm */
|
|
||||||
known_id=2;
|
|
||||||
ee_printf("Profile generation run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
case 0xe9f5: /* seed1=0, seed2=0, seed3=0x66, size 666 per algorithm */
|
|
||||||
known_id=3;
|
|
||||||
ee_printf("2K performance run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
case 0x18f2: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 666 per algorithm */
|
|
||||||
known_id=4;
|
|
||||||
ee_printf("2K validation run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
total_errors=-1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (known_id>=0) {
|
|
||||||
for (i=0 ; i<default_num_contexts; i++) {
|
|
||||||
results[i].err=0;
|
|
||||||
if ((results[i].execs & ID_LIST) &&
|
|
||||||
(results[i].crclist!=list_known_crc[known_id])) {
|
|
||||||
ee_printf("[%u]ERROR! list crc 0x%04x - should be 0x%04x\n",i,results[i].crclist,list_known_crc[known_id]);
|
|
||||||
results[i].err++;
|
|
||||||
}
|
|
||||||
if ((results[i].execs & ID_MATRIX) &&
|
|
||||||
(results[i].crcmatrix!=matrix_known_crc[known_id])) {
|
|
||||||
ee_printf("[%u]ERROR! matrix crc 0x%04x - should be 0x%04x\n",i,results[i].crcmatrix,matrix_known_crc[known_id]);
|
|
||||||
results[i].err++;
|
|
||||||
}
|
|
||||||
if ((results[i].execs & ID_STATE) &&
|
|
||||||
(results[i].crcstate!=state_known_crc[known_id])) {
|
|
||||||
ee_printf("[%u]ERROR! state crc 0x%04x - should be 0x%04x\n",i,results[i].crcstate,state_known_crc[known_id]);
|
|
||||||
results[i].err++;
|
|
||||||
}
|
|
||||||
total_errors+=results[i].err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
total_errors+=check_data_types();
|
|
||||||
/* and report results */
|
|
||||||
ee_printf("CoreMark Size : %lu\n", (long unsigned) results[0].size);
|
|
||||||
ee_printf("Total ticks : %lu\n", (long unsigned) total_time);
|
|
||||||
#if HAS_FLOAT
|
|
||||||
ee_printf("Total time (secs): %f\n",time_in_secs(total_time));
|
|
||||||
if (time_in_secs(total_time) > 0)
|
|
||||||
ee_printf("Iterations/Sec : %f\n",default_num_contexts*results[0].iterations/time_in_secs(total_time));
|
|
||||||
#else
|
|
||||||
ee_printf("Total time (secs): %d\n",time_in_secs(total_time));
|
|
||||||
if (time_in_secs(total_time) > 0)
|
|
||||||
ee_printf("Iterations/Sec : %d\n",default_num_contexts*results[0].iterations/time_in_secs(total_time));
|
|
||||||
#endif
|
|
||||||
if (time_in_secs(total_time) < 10) {
|
|
||||||
ee_printf("ERROR! Must execute for at least 10 secs for a valid result!\n");
|
|
||||||
total_errors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ee_printf("Iterations : %lu\n", (long unsigned) default_num_contexts*results[0].iterations);
|
|
||||||
ee_printf("Compiler version : %s\n",COMPILER_VERSION);
|
|
||||||
ee_printf("Compiler flags : %s\n",COMPILER_FLAGS);
|
|
||||||
#if (MULTITHREAD>1)
|
|
||||||
ee_printf("Parallel %s : %d\n",PARALLEL_METHOD,default_num_contexts);
|
|
||||||
#endif
|
|
||||||
ee_printf("Memory location : %s\n",MEM_LOCATION);
|
|
||||||
/* output for verification */
|
|
||||||
ee_printf("seedcrc : 0x%04x\n",seedcrc);
|
|
||||||
if (results[0].execs & ID_LIST)
|
|
||||||
for (i=0 ; i<default_num_contexts; i++)
|
|
||||||
ee_printf("[%d]crclist : 0x%04x\n",i,results[i].crclist);
|
|
||||||
if (results[0].execs & ID_MATRIX)
|
|
||||||
for (i=0 ; i<default_num_contexts; i++)
|
|
||||||
ee_printf("[%d]crcmatrix : 0x%04x\n",i,results[i].crcmatrix);
|
|
||||||
if (results[0].execs & ID_STATE)
|
|
||||||
for (i=0 ; i<default_num_contexts; i++)
|
|
||||||
ee_printf("[%d]crcstate : 0x%04x\n",i,results[i].crcstate);
|
|
||||||
for (i=0 ; i<default_num_contexts; i++)
|
|
||||||
ee_printf("[%d]crcfinal : 0x%04x\n",i,results[i].crc);
|
|
||||||
if (total_errors==0) {
|
|
||||||
ee_printf("Correct operation validated. See README.md for run and reporting rules.\n");
|
|
||||||
#if HAS_FLOAT
|
|
||||||
if (known_id==3) {
|
|
||||||
ee_printf("CoreMark 1.0 : %f / %s %s",default_num_contexts*results[0].iterations/time_in_secs(total_time),COMPILER_VERSION,COMPILER_FLAGS);
|
|
||||||
#if defined(MEM_LOCATION) && !defined(MEM_LOCATION_UNSPEC)
|
|
||||||
ee_printf(" / %s",MEM_LOCATION);
|
|
||||||
#else
|
|
||||||
ee_printf(" / %s",mem_name[MEM_METHOD]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (MULTITHREAD>1)
|
|
||||||
ee_printf(" / %d:%s",default_num_contexts,PARALLEL_METHOD);
|
|
||||||
#endif
|
|
||||||
ee_printf("\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (total_errors>0)
|
|
||||||
ee_printf("Errors detected\n");
|
|
||||||
if (total_errors<0)
|
|
||||||
ee_printf("Cannot validate operation for these seed values, please compare with results on a known platform.\n");
|
|
||||||
|
|
||||||
#if (MEM_METHOD==MEM_MALLOC)
|
|
||||||
for (i=0 ; i<MULTITHREAD; i++)
|
|
||||||
portable_free(results[i].memblock[0]);
|
|
||||||
#endif
|
|
||||||
/* And last call any target specific code for finalizing */
|
|
||||||
portable_fini(&(results[0].port));
|
|
||||||
|
|
||||||
return MAIN_RETURN_VAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,369 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
Original Author: Shay Gal-on
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* File: core_main_embedded.c
|
|
||||||
This file contains the framework to acquire a block of memory, seed initial parameters, tun t he benchmark and report the results.
|
|
||||||
*/
|
|
||||||
#include "coremark.h"
|
|
||||||
|
|
||||||
/* Function: iterate
|
|
||||||
Run the benchmark for a specified number of iterations.
|
|
||||||
|
|
||||||
Operation:
|
|
||||||
For each type of benchmarked algorithm:
|
|
||||||
a - Initialize the data block for the algorithm.
|
|
||||||
b - Execute the algorithm N times.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
NULL.
|
|
||||||
*/
|
|
||||||
static ee_u16 list_known_crc[] = {(ee_u16)0xd4b0,(ee_u16)0x3340,(ee_u16)0x6a79,(ee_u16)0xe714,(ee_u16)0xe3c1};
|
|
||||||
static ee_u16 matrix_known_crc[] = {(ee_u16)0xbe52,(ee_u16)0x1199,(ee_u16)0x5608,(ee_u16)0x1fd7,(ee_u16)0x0747};
|
|
||||||
static ee_u16 state_known_crc[] = {(ee_u16)0x5e47,(ee_u16)0x39bf,(ee_u16)0xe5a4,(ee_u16)0x8e3a,(ee_u16)0x8d84};
|
|
||||||
void *iterate(void *pres) {
|
|
||||||
ee_u32 i;
|
|
||||||
ee_u16 crc;
|
|
||||||
core_results *res=(core_results *)pres;
|
|
||||||
ee_u32 iterations=res->iterations;
|
|
||||||
res->crc=0;
|
|
||||||
res->crclist=0;
|
|
||||||
res->crcmatrix=0;
|
|
||||||
res->crcstate=0;
|
|
||||||
|
|
||||||
for (i=0; i<iterations; i++) {
|
|
||||||
crc=core_bench_list(res,1);
|
|
||||||
res->crc=crcu16(crc,res->crc);
|
|
||||||
crc=core_bench_list(res,-1);
|
|
||||||
res->crc=crcu16(crc,res->crc);
|
|
||||||
if (i==0) res->crclist=res->crc;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if (SEED_METHOD==SEED_ARG)
|
|
||||||
ee_s32 get_seed_args(int i, int argc, char *argv[]);
|
|
||||||
#define get_seed(x) (ee_s16)get_seed_args(x,argc,argv)
|
|
||||||
#define get_seed_32(x) get_seed_args(x,argc,argv)
|
|
||||||
#else /* via function or volatile */
|
|
||||||
ee_s32 get_seed_32(int i);
|
|
||||||
#define get_seed(x) (ee_s16)get_seed_32(x)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (MEM_METHOD==MEM_STATIC)
|
|
||||||
ee_u8 static_memblk[TOTAL_DATA_SIZE];
|
|
||||||
#endif
|
|
||||||
char *mem_name[3] = {"Static","Heap","Stack"};
|
|
||||||
/* Function: main
|
|
||||||
Main entry routine for the benchmark.
|
|
||||||
This function is responsible for the following steps:
|
|
||||||
|
|
||||||
1 - Initialize input seeds from a source that cannot be determined at compile time.
|
|
||||||
2 - Initialize memory block for use.
|
|
||||||
3 - Run and time the benchmark.
|
|
||||||
4 - Report results, testing the validity of the output if the seeds are known.
|
|
||||||
|
|
||||||
Arguments:
|
|
||||||
1 - first seed : Any value
|
|
||||||
2 - second seed : Must be identical to first for iterations to be identical
|
|
||||||
3 - third seed : Any value, should be at least an order of magnitude less then the input size, but bigger then 32.
|
|
||||||
4 - Iterations : Special, if set to 0, iterations will be automatically determined such that the benchmark will run between 10 to 100 secs
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
//#if MAIN_HAS_NOARGC
|
|
||||||
//MAIN_RETURN_TYPE main(void) {
|
|
||||||
// int argc=0;
|
|
||||||
// char *argv[1];
|
|
||||||
//#else
|
|
||||||
//MAIN_RETURN_TYPE main(int argc, char *argv[]) {
|
|
||||||
//#endif
|
|
||||||
MAIN_RETURN_TYPE CoreMarkTest(void) {
|
|
||||||
ee_u16 i,j=0,num_algorithms=0;
|
|
||||||
ee_s16 known_id=-1,total_errors=0;
|
|
||||||
ee_u16 seedcrc=0;
|
|
||||||
CORE_TICKS total_time;
|
|
||||||
core_results results[MULTITHREAD];
|
|
||||||
#if (MEM_METHOD==MEM_STACK)
|
|
||||||
ee_u8 stack_memblock[TOTAL_DATA_SIZE*MULTITHREAD];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* first call any initializations needed */
|
|
||||||
//portable_init(&(results[0].port), &argc, argv);
|
|
||||||
portable_init(&(results[0].port));
|
|
||||||
/* First some checks to make sure benchmark will run ok */
|
|
||||||
if (sizeof(struct list_head_s)>128) {
|
|
||||||
ee_printf("list_head structure too big for comparable data!\n");
|
|
||||||
return MAIN_RETURN_VAL;
|
|
||||||
}
|
|
||||||
results[0].seed1=get_seed(1);
|
|
||||||
results[0].seed2=get_seed(2);
|
|
||||||
results[0].seed3=get_seed(3);
|
|
||||||
results[0].iterations=get_seed_32(4);
|
|
||||||
#if CORE_DEBUG
|
|
||||||
results[0].iterations=1;
|
|
||||||
#endif
|
|
||||||
results[0].execs=get_seed_32(5);
|
|
||||||
if (results[0].execs==0) { /* if not supplied, execute all algorithms */
|
|
||||||
results[0].execs=ALL_ALGORITHMS_MASK;
|
|
||||||
}
|
|
||||||
/* put in some default values based on one seed only for easy testing */
|
|
||||||
if ((results[0].seed1==0) && (results[0].seed2==0) && (results[0].seed3==0)) { /* validation run */
|
|
||||||
results[0].seed1=0;
|
|
||||||
results[0].seed2=0;
|
|
||||||
results[0].seed3=0x66;
|
|
||||||
}
|
|
||||||
if ((results[0].seed1==1) && (results[0].seed2==0) && (results[0].seed3==0)) { /* perfromance run */
|
|
||||||
results[0].seed1=0x3415;
|
|
||||||
results[0].seed2=0x3415;
|
|
||||||
results[0].seed3=0x66;
|
|
||||||
}
|
|
||||||
#if (MEM_METHOD==MEM_STATIC)
|
|
||||||
results[0].memblock[0]=(void *)static_memblk;
|
|
||||||
results[0].size=TOTAL_DATA_SIZE;
|
|
||||||
results[0].err=0;
|
|
||||||
#if (MULTITHREAD>1)
|
|
||||||
#error "Cannot use a static data area with multiple contexts!"
|
|
||||||
#endif
|
|
||||||
#elif (MEM_METHOD==MEM_MALLOC)
|
|
||||||
for (i=0 ; i<MULTITHREAD; i++) {
|
|
||||||
ee_s32 malloc_override=get_seed(7);
|
|
||||||
if (malloc_override != 0)
|
|
||||||
results[i].size=malloc_override;
|
|
||||||
else
|
|
||||||
results[i].size=TOTAL_DATA_SIZE;
|
|
||||||
results[i].memblock[0]=portable_malloc(results[i].size);
|
|
||||||
results[i].seed1=results[0].seed1;
|
|
||||||
results[i].seed2=results[0].seed2;
|
|
||||||
results[i].seed3=results[0].seed3;
|
|
||||||
results[i].err=0;
|
|
||||||
results[i].execs=results[0].execs;
|
|
||||||
}
|
|
||||||
#elif (MEM_METHOD==MEM_STACK)
|
|
||||||
for (i=0 ; i<MULTITHREAD; i++) {
|
|
||||||
results[i].memblock[0]=stack_memblock+i*TOTAL_DATA_SIZE;
|
|
||||||
results[i].size=TOTAL_DATA_SIZE;
|
|
||||||
results[i].seed1=results[0].seed1;
|
|
||||||
results[i].seed2=results[0].seed2;
|
|
||||||
results[i].seed3=results[0].seed3;
|
|
||||||
results[i].err=0;
|
|
||||||
results[i].execs=results[0].execs;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#error "Please define a way to initialize a memory block."
|
|
||||||
#endif
|
|
||||||
/* Data init */
|
|
||||||
/* Find out how space much we have based on number of algorithms */
|
|
||||||
for (i=0; i<NUM_ALGORITHMS; i++) {
|
|
||||||
if ((1<<(ee_u32)i) & results[0].execs)
|
|
||||||
num_algorithms++;
|
|
||||||
}
|
|
||||||
for (i=0 ; i<MULTITHREAD; i++)
|
|
||||||
{
|
|
||||||
// Check for divisor bug, ZPU compilation or hardware misconfiguration issue.
|
|
||||||
if(results[i].size/num_algorithms < 10)
|
|
||||||
{
|
|
||||||
ee_printf("Hardware/Software build Bug! Divide %d by %d result = :%d\n", results[i].size, num_algorithms, results[i].size/num_algorithms);
|
|
||||||
return MAIN_RETURN_VAL;
|
|
||||||
}
|
|
||||||
results[i].size=results[i].size/num_algorithms;
|
|
||||||
}
|
|
||||||
/* Assign pointers */
|
|
||||||
for (i=0; i<NUM_ALGORITHMS; i++) {
|
|
||||||
ee_u32 ctx;
|
|
||||||
if ((1<<(ee_u32)i) & results[0].execs) {
|
|
||||||
for (ctx=0 ; ctx<MULTITHREAD; ctx++)
|
|
||||||
results[ctx].memblock[i+1]=(char *)(results[ctx].memblock[0])+results[0].size*j;
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* call inits */
|
|
||||||
for (i=0 ; i<MULTITHREAD; i++) {
|
|
||||||
if (results[i].execs & ID_LIST) {
|
|
||||||
results[i].list=core_list_init(results[0].size,results[i].memblock[1],results[i].seed1);
|
|
||||||
}
|
|
||||||
if (results[i].execs & ID_MATRIX) {
|
|
||||||
core_init_matrix(results[0].size, results[i].memblock[2], (ee_s32)results[i].seed1 | (((ee_s32)results[i].seed2) << 16), &(results[i].mat) );
|
|
||||||
}
|
|
||||||
if (results[i].execs & ID_STATE) {
|
|
||||||
core_init_state(results[0].size,results[i].seed1,results[i].memblock[3]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* automatically determine number of iterations if not set */
|
|
||||||
if (results[0].iterations==0) {
|
|
||||||
secs_ret secs_passed=0;
|
|
||||||
ee_u32 divisor;
|
|
||||||
results[0].iterations=1;
|
|
||||||
while (secs_passed < (secs_ret)1) {
|
|
||||||
results[0].iterations*=10;
|
|
||||||
start_time();
|
|
||||||
iterate(&results[0]);
|
|
||||||
stop_time();
|
|
||||||
secs_passed=time_in_secs(get_time());
|
|
||||||
}
|
|
||||||
/* now we know it executes for at least 1 sec, set actual run time at about 10 secs */
|
|
||||||
divisor=(ee_u32)secs_passed;
|
|
||||||
if (divisor==0) /* some machines cast float to int as 0 since this conversion is not defined by ANSI, but we know at least one second passed */
|
|
||||||
divisor=1;
|
|
||||||
results[0].iterations*=1+10/divisor;
|
|
||||||
}
|
|
||||||
/* perform actual benchmark */
|
|
||||||
start_time();
|
|
||||||
#if (MULTITHREAD>1)
|
|
||||||
if (default_num_contexts>MULTITHREAD) {
|
|
||||||
default_num_contexts=MULTITHREAD;
|
|
||||||
}
|
|
||||||
for (i=0 ; i<default_num_contexts; i++) {
|
|
||||||
results[i].iterations=results[0].iterations;
|
|
||||||
results[i].execs=results[0].execs;
|
|
||||||
core_start_parallel(&results[i]);
|
|
||||||
}
|
|
||||||
for (i=0 ; i<default_num_contexts; i++) {
|
|
||||||
core_stop_parallel(&results[i]);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
iterate(&results[0]);
|
|
||||||
#endif
|
|
||||||
stop_time();
|
|
||||||
total_time=get_time();
|
|
||||||
/* get a function of the input to report */
|
|
||||||
seedcrc=crc16(results[0].seed1,seedcrc);
|
|
||||||
seedcrc=crc16(results[0].seed2,seedcrc);
|
|
||||||
seedcrc=crc16(results[0].seed3,seedcrc);
|
|
||||||
seedcrc=crc16(results[0].size,seedcrc);
|
|
||||||
|
|
||||||
switch (seedcrc) { /* test known output for common seeds */
|
|
||||||
case 0x8a02: /* seed1=0, seed2=0, seed3=0x66, size 2000 per algorithm */
|
|
||||||
known_id=0;
|
|
||||||
ee_printf("6k performance run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
case 0x7b05: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 2000 per algorithm */
|
|
||||||
known_id=1;
|
|
||||||
ee_printf("6k validation run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
case 0x4eaf: /* seed1=0x8, seed2=0x8, seed3=0x8, size 400 per algorithm */
|
|
||||||
known_id=2;
|
|
||||||
ee_printf("Profile generation run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
case 0xe9f5: /* seed1=0, seed2=0, seed3=0x66, size 666 per algorithm */
|
|
||||||
known_id=3;
|
|
||||||
ee_printf("2K performance run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
case 0x18f2: /* seed1=0x3415, seed2=0x3415, seed3=0x66, size 666 per algorithm */
|
|
||||||
known_id=4;
|
|
||||||
ee_printf("2K validation run parameters for coremark.\n");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
total_errors=-1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (known_id>=0) {
|
|
||||||
for (i=0 ; i<default_num_contexts; i++) {
|
|
||||||
results[i].err=0;
|
|
||||||
if ((results[i].execs & ID_LIST) &&
|
|
||||||
(results[i].crclist!=list_known_crc[known_id])) {
|
|
||||||
ee_printf("[%u]ERROR! list crc 0x%04x - should be 0x%04x\n",i,results[i].crclist,list_known_crc[known_id]);
|
|
||||||
results[i].err++;
|
|
||||||
}
|
|
||||||
if ((results[i].execs & ID_MATRIX) &&
|
|
||||||
(results[i].crcmatrix!=matrix_known_crc[known_id])) {
|
|
||||||
ee_printf("[%u]ERROR! matrix crc 0x%04x - should be 0x%04x\n",i,results[i].crcmatrix,matrix_known_crc[known_id]);
|
|
||||||
results[i].err++;
|
|
||||||
}
|
|
||||||
if ((results[i].execs & ID_STATE) &&
|
|
||||||
(results[i].crcstate!=state_known_crc[known_id])) {
|
|
||||||
ee_printf("[%u]ERROR! state crc 0x%04x - should be 0x%04x\n",i,results[i].crcstate,state_known_crc[known_id]);
|
|
||||||
results[i].err++;
|
|
||||||
}
|
|
||||||
total_errors+=results[i].err;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
total_errors+=check_data_types();
|
|
||||||
/* and report results */
|
|
||||||
ee_printf("CoreMark Size : %lu\n", (long unsigned) results[0].size);
|
|
||||||
ee_printf("Total ticks : %lu\n", (long unsigned) total_time);
|
|
||||||
#if HAS_FLOAT
|
|
||||||
ee_printf("Total time (secs): %f\n",time_in_secs(total_time));
|
|
||||||
if (time_in_secs(total_time) > 0)
|
|
||||||
ee_printf("Iterations/Sec : %f\n",default_num_contexts*results[0].iterations/time_in_secs(total_time));
|
|
||||||
#else
|
|
||||||
ee_printf("Total time (secs): %d\n",time_in_secs(total_time));
|
|
||||||
if (time_in_secs(total_time) > 0)
|
|
||||||
ee_printf("Iterations/Sec : %d.%d\n",
|
|
||||||
default_num_contexts*results[0].iterations / time_in_secs(total_time),
|
|
||||||
default_num_contexts*results[0].iterations % time_in_secs(total_time));
|
|
||||||
#endif
|
|
||||||
if (time_in_secs(total_time) < 10) {
|
|
||||||
ee_printf("ERROR! Must execute for at least 10 secs for a valid result!\n");
|
|
||||||
total_errors++;
|
|
||||||
}
|
|
||||||
|
|
||||||
ee_printf("Iterations : %lu\n", (long unsigned) default_num_contexts*results[0].iterations);
|
|
||||||
ee_printf("Compiler version : %s\n",COMPILER_VERSION);
|
|
||||||
ee_printf("Compiler flags : %s\n",COMPILER_FLAGS);
|
|
||||||
#if (MULTITHREAD>1)
|
|
||||||
ee_printf("Parallel %s : %d\n",PARALLEL_METHOD,default_num_contexts);
|
|
||||||
#endif
|
|
||||||
ee_printf("Memory location : %s\n",MEM_LOCATION);
|
|
||||||
/* output for verification */
|
|
||||||
ee_printf("seedcrc : 0x%04x\n",seedcrc);
|
|
||||||
if (results[0].execs & ID_LIST)
|
|
||||||
for (i=0 ; i<default_num_contexts; i++)
|
|
||||||
ee_printf("[%d]crclist : 0x%04x\n",i,results[i].crclist);
|
|
||||||
if (results[0].execs & ID_MATRIX)
|
|
||||||
for (i=0 ; i<default_num_contexts; i++)
|
|
||||||
ee_printf("[%d]crcmatrix : 0x%04x\n",i,results[i].crcmatrix);
|
|
||||||
if (results[0].execs & ID_STATE)
|
|
||||||
for (i=0 ; i<default_num_contexts; i++)
|
|
||||||
ee_printf("[%d]crcstate : 0x%04x\n",i,results[i].crcstate);
|
|
||||||
for (i=0 ; i<default_num_contexts; i++)
|
|
||||||
ee_printf("[%d]crcfinal : 0x%04x\n",i,results[i].crc);
|
|
||||||
if (total_errors==0) {
|
|
||||||
ee_printf("Correct operation validated. See README.md for run and reporting rules.\n");
|
|
||||||
#if HAS_FLOAT
|
|
||||||
if (known_id==3) {
|
|
||||||
ee_printf("CoreMark 1.0 : %f / %s %s",default_num_contexts*results[0].iterations/time_in_secs(total_time),COMPILER_VERSION,COMPILER_FLAGS);
|
|
||||||
#if defined(MEM_LOCATION) && !defined(MEM_LOCATION_UNSPEC)
|
|
||||||
ee_printf(" / %s",MEM_LOCATION);
|
|
||||||
#else
|
|
||||||
ee_printf(" / %s",mem_name[MEM_METHOD]);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (MULTITHREAD>1)
|
|
||||||
ee_printf(" / %d:%s",default_num_contexts,PARALLEL_METHOD);
|
|
||||||
#endif
|
|
||||||
ee_printf("\n");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
if (total_errors>0)
|
|
||||||
ee_printf("Errors detected\n");
|
|
||||||
if (total_errors<0)
|
|
||||||
ee_printf("Cannot validate operation for these seed values, please compare with results on a known platform.\n");
|
|
||||||
|
|
||||||
#if (MEM_METHOD==MEM_MALLOC)
|
|
||||||
for (i=0 ; i<MULTITHREAD; i++)
|
|
||||||
portable_free(results[i].memblock[0]);
|
|
||||||
#endif
|
|
||||||
/* And last call any target specific code for finalizing */
|
|
||||||
portable_fini(&(results[0].port));
|
|
||||||
|
|
||||||
return MAIN_RETURN_VAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,308 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
Original Author: Shay Gal-on
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "coremark.h"
|
|
||||||
/*
|
|
||||||
Topic: Description
|
|
||||||
Matrix manipulation benchmark
|
|
||||||
|
|
||||||
This very simple algorithm forms the basis of many more complex algorithms.
|
|
||||||
|
|
||||||
The tight inner loop is the focus of many optimizations (compiler as well as hardware based)
|
|
||||||
and is thus relevant for embedded processing.
|
|
||||||
|
|
||||||
The total available data space will be divided to 3 parts:
|
|
||||||
NxN Matrix A - initialized with small values (upper 3/4 of the bits all zero).
|
|
||||||
NxN Matrix B - initialized with medium values (upper half of the bits all zero).
|
|
||||||
NxN Matrix C - used for the result.
|
|
||||||
|
|
||||||
The actual values for A and B must be derived based on input that is not available at compile time.
|
|
||||||
*/
|
|
||||||
ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val);
|
|
||||||
ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval);
|
|
||||||
void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val);
|
|
||||||
void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
|
|
||||||
void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
|
|
||||||
void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B);
|
|
||||||
void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val);
|
|
||||||
|
|
||||||
#define matrix_test_next(x) (x+1)
|
|
||||||
#define matrix_clip(x,y) ((y) ? (x) & 0x0ff : (x) & 0x0ffff)
|
|
||||||
#define matrix_big(x) (0xf000 | (x))
|
|
||||||
#define bit_extract(x,from,to) (((x)>>(from)) & (~(0xffffffff << (to))))
|
|
||||||
|
|
||||||
#if CORE_DEBUG
|
|
||||||
void printmat(MATDAT *A, ee_u32 N, char *name) {
|
|
||||||
ee_u32 i,j;
|
|
||||||
ee_printf("Matrix %s [%dx%d]:\n",name,N,N);
|
|
||||||
for (i=0; i<N; i++) {
|
|
||||||
for (j=0; j<N; j++) {
|
|
||||||
if (j!=0)
|
|
||||||
ee_printf(",");
|
|
||||||
ee_printf("%d",A[i*N+j]);
|
|
||||||
}
|
|
||||||
ee_printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void printmatC(MATRES *C, ee_u32 N, char *name) {
|
|
||||||
ee_u32 i,j;
|
|
||||||
ee_printf("Matrix %s [%dx%d]:\n",name,N,N);
|
|
||||||
for (i=0; i<N; i++) {
|
|
||||||
for (j=0; j<N; j++) {
|
|
||||||
if (j!=0)
|
|
||||||
ee_printf(",");
|
|
||||||
ee_printf("%d",C[i*N+j]);
|
|
||||||
}
|
|
||||||
ee_printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/* Function: core_bench_matrix
|
|
||||||
Benchmark function
|
|
||||||
|
|
||||||
Iterate <matrix_test> N times,
|
|
||||||
changing the matrix values slightly by a constant amount each time.
|
|
||||||
*/
|
|
||||||
ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc) {
|
|
||||||
ee_u32 N=p->N;
|
|
||||||
MATRES *C=p->C;
|
|
||||||
MATDAT *A=p->A;
|
|
||||||
MATDAT *B=p->B;
|
|
||||||
MATDAT val=(MATDAT)seed;
|
|
||||||
|
|
||||||
crc=crc16(matrix_test(N,C,A,B,val),crc);
|
|
||||||
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: matrix_test
|
|
||||||
Perform matrix manipulation.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
N - Dimensions of the matrix.
|
|
||||||
C - memory for result matrix.
|
|
||||||
A - input matrix
|
|
||||||
B - operator matrix (not changed during operations)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
A CRC value that captures all results calculated in the function.
|
|
||||||
In particular, crc of the value calculated on the result matrix
|
|
||||||
after each step by <matrix_sum>.
|
|
||||||
|
|
||||||
Operation:
|
|
||||||
|
|
||||||
1 - Add a constant value to all elements of a matrix.
|
|
||||||
2 - Multiply a matrix by a constant.
|
|
||||||
3 - Multiply a matrix by a vector.
|
|
||||||
4 - Multiply a matrix by a matrix.
|
|
||||||
5 - Add a constant value to all elements of a matrix.
|
|
||||||
|
|
||||||
After the last step, matrix A is back to original contents.
|
|
||||||
*/
|
|
||||||
ee_s16 matrix_test(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B, MATDAT val) {
|
|
||||||
ee_u16 crc=0;
|
|
||||||
MATDAT clipval=matrix_big(val);
|
|
||||||
|
|
||||||
matrix_add_const(N,A,val); /* make sure data changes */
|
|
||||||
#if CORE_DEBUG
|
|
||||||
printmat(A,N,"matrix_add_const");
|
|
||||||
#endif
|
|
||||||
matrix_mul_const(N,C,A,val);
|
|
||||||
crc=crc16(matrix_sum(N,C,clipval),crc);
|
|
||||||
#if CORE_DEBUG
|
|
||||||
printmatC(C,N,"matrix_mul_const");
|
|
||||||
#endif
|
|
||||||
matrix_mul_vect(N,C,A,B);
|
|
||||||
crc=crc16(matrix_sum(N,C,clipval),crc);
|
|
||||||
#if CORE_DEBUG
|
|
||||||
printmatC(C,N,"matrix_mul_vect");
|
|
||||||
#endif
|
|
||||||
matrix_mul_matrix(N,C,A,B);
|
|
||||||
crc=crc16(matrix_sum(N,C,clipval),crc);
|
|
||||||
#if CORE_DEBUG
|
|
||||||
printmatC(C,N,"matrix_mul_matrix");
|
|
||||||
#endif
|
|
||||||
matrix_mul_matrix_bitextract(N,C,A,B);
|
|
||||||
crc=crc16(matrix_sum(N,C,clipval),crc);
|
|
||||||
#if CORE_DEBUG
|
|
||||||
printmatC(C,N,"matrix_mul_matrix_bitextract");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
matrix_add_const(N,A,-val); /* return matrix to initial value */
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function : matrix_init
|
|
||||||
Initialize the memory block for matrix benchmarking.
|
|
||||||
|
|
||||||
Parameters:
|
|
||||||
blksize - Size of memory to be initialized.
|
|
||||||
memblk - Pointer to memory block.
|
|
||||||
seed - Actual values chosen depend on the seed parameter.
|
|
||||||
p - pointers to <mat_params> containing initialized matrixes.
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
Matrix dimensions.
|
|
||||||
|
|
||||||
Note:
|
|
||||||
The seed parameter MUST be supplied from a source that cannot be determined at compile time
|
|
||||||
*/
|
|
||||||
ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p) {
|
|
||||||
ee_u32 N=0;
|
|
||||||
MATDAT *A;
|
|
||||||
MATDAT *B;
|
|
||||||
ee_s32 order=1;
|
|
||||||
MATDAT val;
|
|
||||||
ee_u32 i=0,j=0;
|
|
||||||
if (seed==0)
|
|
||||||
seed=1;
|
|
||||||
while (j<blksize) {
|
|
||||||
i++;
|
|
||||||
j=i*i*2*4;
|
|
||||||
}
|
|
||||||
N=i-1;
|
|
||||||
A=(MATDAT *)align_mem(memblk);
|
|
||||||
B=A+N*N;
|
|
||||||
|
|
||||||
for (i=0; i<N; i++) {
|
|
||||||
for (j=0; j<N; j++) {
|
|
||||||
seed = ( ( order * seed ) % 65536 );
|
|
||||||
val = (seed + order);
|
|
||||||
val=matrix_clip(val,0);
|
|
||||||
B[i*N+j] = val;
|
|
||||||
val = (val + order);
|
|
||||||
val=matrix_clip(val,1);
|
|
||||||
A[i*N+j] = val;
|
|
||||||
order++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
p->A=A;
|
|
||||||
p->B=B;
|
|
||||||
p->C=(MATRES *)align_mem(B+N*N);
|
|
||||||
p->N=N;
|
|
||||||
#if CORE_DEBUG
|
|
||||||
printmat(A,N,"A");
|
|
||||||
printmat(B,N,"B");
|
|
||||||
#endif
|
|
||||||
return N;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: matrix_sum
|
|
||||||
Calculate a function that depends on the values of elements in the matrix.
|
|
||||||
|
|
||||||
For each element, accumulate into a temporary variable.
|
|
||||||
|
|
||||||
As long as this value is under the parameter clipval,
|
|
||||||
add 1 to the result if the element is bigger then the previous.
|
|
||||||
|
|
||||||
Otherwise, reset the accumulator and add 10 to the result.
|
|
||||||
*/
|
|
||||||
ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) {
|
|
||||||
MATRES tmp=0,prev=0,cur=0;
|
|
||||||
ee_s16 ret=0;
|
|
||||||
ee_u32 i,j;
|
|
||||||
for (i=0; i<N; i++) {
|
|
||||||
for (j=0; j<N; j++) {
|
|
||||||
cur=C[i*N+j];
|
|
||||||
tmp+=cur;
|
|
||||||
if (tmp>clipval) {
|
|
||||||
ret+=10;
|
|
||||||
tmp=0;
|
|
||||||
} else {
|
|
||||||
ret += (cur>prev) ? 1 : 0;
|
|
||||||
}
|
|
||||||
prev=cur;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: matrix_mul_const
|
|
||||||
Multiply a matrix by a constant.
|
|
||||||
This could be used as a scaler for instance.
|
|
||||||
*/
|
|
||||||
void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val) {
|
|
||||||
ee_u32 i,j;
|
|
||||||
for (i=0; i<N; i++) {
|
|
||||||
for (j=0; j<N; j++) {
|
|
||||||
C[i*N+j]=(MATRES)A[i*N+j] * (MATRES)val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: matrix_add_const
|
|
||||||
Add a constant value to all elements of a matrix.
|
|
||||||
*/
|
|
||||||
void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val) {
|
|
||||||
ee_u32 i,j;
|
|
||||||
for (i=0; i<N; i++) {
|
|
||||||
for (j=0; j<N; j++) {
|
|
||||||
A[i*N+j] += val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: matrix_mul_vect
|
|
||||||
Multiply a matrix by a vector.
|
|
||||||
This is common in many simple filters (e.g. fir where a vector of coefficients is applied to the matrix.)
|
|
||||||
*/
|
|
||||||
void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
|
|
||||||
ee_u32 i,j;
|
|
||||||
for (i=0; i<N; i++) {
|
|
||||||
C[i]=0;
|
|
||||||
for (j=0; j<N; j++) {
|
|
||||||
C[i]+=(MATRES)A[i*N+j] * (MATRES)B[j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: matrix_mul_matrix
|
|
||||||
Multiply a matrix by a matrix.
|
|
||||||
Basic code is used in many algorithms, mostly with minor changes such as scaling.
|
|
||||||
*/
|
|
||||||
void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
|
|
||||||
ee_u32 i,j,k;
|
|
||||||
for (i=0; i<N; i++) {
|
|
||||||
for (j=0; j<N; j++) {
|
|
||||||
C[i*N+j]=0;
|
|
||||||
for(k=0;k<N;k++)
|
|
||||||
{
|
|
||||||
C[i*N+j]+=(MATRES)A[i*N+k] * (MATRES)B[k*N+j];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: matrix_mul_matrix_bitextract
|
|
||||||
Multiply a matrix by a matrix, and extract some bits from the result.
|
|
||||||
Basic code is used in many algorithms, mostly with minor changes such as scaling.
|
|
||||||
*/
|
|
||||||
void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) {
|
|
||||||
ee_u32 i,j,k;
|
|
||||||
for (i=0; i<N; i++) {
|
|
||||||
for (j=0; j<N; j++) {
|
|
||||||
C[i*N+j]=0;
|
|
||||||
for(k=0;k<N;k++)
|
|
||||||
{
|
|
||||||
MATRES tmp=(MATRES)A[i*N+k] * (MATRES)B[k*N+j];
|
|
||||||
C[i*N+j]+=bit_extract(tmp,2,4)*bit_extract(tmp,5,7);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
Original Author: Shay Gal-on
|
|
||||||
*/
|
|
||||||
#include "coremark.h"
|
|
||||||
#include "core_portme.h"
|
|
||||||
|
|
||||||
#if defined __K64F__
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "k64f_soc.h"
|
|
||||||
extern uint32_t milliseconds(void);
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if VALIDATION_RUN
|
|
||||||
volatile ee_s32 seed1_volatile=0x3415;
|
|
||||||
volatile ee_s32 seed2_volatile=0x3415;
|
|
||||||
volatile ee_s32 seed3_volatile=0x66;
|
|
||||||
#endif
|
|
||||||
#if PERFORMANCE_RUN
|
|
||||||
volatile ee_s32 seed1_volatile=0x0;
|
|
||||||
volatile ee_s32 seed2_volatile=0x0;
|
|
||||||
volatile ee_s32 seed3_volatile=0x66;
|
|
||||||
#endif
|
|
||||||
#if PROFILE_RUN
|
|
||||||
volatile ee_s32 seed1_volatile=0x8;
|
|
||||||
volatile ee_s32 seed2_volatile=0x8;
|
|
||||||
volatile ee_s32 seed3_volatile=0x8;
|
|
||||||
#endif
|
|
||||||
//volatile ee_s32 seed4_volatile=ITERATIONS;
|
|
||||||
volatile ee_s32 seed4_volatile=2000;
|
|
||||||
volatile ee_s32 seed5_volatile=0;
|
|
||||||
|
|
||||||
/* Porting : Timing functions
|
|
||||||
How to capture time and convert to seconds must be ported to whatever is supported by the platform.
|
|
||||||
e.g. Read value from on board RTC, read value from cpu clock cycles performance counter etc.
|
|
||||||
Sample implementation for standard time.h and windows.h definitions included.
|
|
||||||
*/
|
|
||||||
CORETIMETYPE barebones_clock() {
|
|
||||||
|
|
||||||
// Read SoC RTC in microseconds.
|
|
||||||
#if defined __ZPU__
|
|
||||||
CORETIMETYPE clockInuS = TIMER_MILLISECONDS_UP;
|
|
||||||
#elif defined(__K64F__) && defined(__APP__)
|
|
||||||
CORETIMETYPE clockInuS = milliseconds();
|
|
||||||
#elif defined(__K64F__) && (defined(__ZPUTA__) || defined(__ZOS__))
|
|
||||||
uint32_t millis(void);
|
|
||||||
CORETIMETYPE clockInuS = millis();
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__ or __K64F__"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
// For debug, output the time components.
|
|
||||||
ee_printf("Time(ms): clock=%u\n", clockInuS);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Return clock in microseconds.
|
|
||||||
return(clockInuS);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Define : TIMER_RES_DIVIDER
|
|
||||||
Divider to trade off timer resolution and total time that can be measured.
|
|
||||||
|
|
||||||
Use lower values to increase resolution, but make sure that overflow does not occur.
|
|
||||||
If there are issues with the return value overflowing, increase this value.
|
|
||||||
*/
|
|
||||||
#define GETMYTIME(_t) (*_t=barebones_clock())
|
|
||||||
#define MYTIMEDIFF(fin,ini) ((fin)-(ini))
|
|
||||||
#define TIMER_RES_DIVIDER 1
|
|
||||||
#define SAMPLE_TIME_IMPLEMENTATION 1
|
|
||||||
#define CLOCKS_PER_SEC 1000
|
|
||||||
#define EE_TICKS_PER_SEC (CLOCKS_PER_SEC / TIMER_RES_DIVIDER)
|
|
||||||
|
|
||||||
/** Define Host specific (POSIX), or target specific global time variables. */
|
|
||||||
static CORETIMETYPE start_time_val, stop_time_val;
|
|
||||||
|
|
||||||
/* Function : start_time
|
|
||||||
This function will be called right before starting the timed portion of the benchmark.
|
|
||||||
|
|
||||||
Implementation may be capturing a system timer (as implemented in the example code)
|
|
||||||
or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0.
|
|
||||||
*/
|
|
||||||
void start_time(void) {
|
|
||||||
GETMYTIME(&start_time_val );
|
|
||||||
}
|
|
||||||
/* Function : stop_time
|
|
||||||
This function will be called right after ending the timed portion of the benchmark.
|
|
||||||
|
|
||||||
Implementation may be capturing a system timer (as implemented in the example code)
|
|
||||||
or other system parameters - e.g. reading the current value of cpu cycles counter.
|
|
||||||
*/
|
|
||||||
void stop_time(void) {
|
|
||||||
GETMYTIME(&stop_time_val );
|
|
||||||
}
|
|
||||||
/* Function : get_time
|
|
||||||
Return an abstract "ticks" number that signifies time on the system.
|
|
||||||
|
|
||||||
Actual value returned may be cpu cycles, milliseconds or any other value,
|
|
||||||
as long as it can be converted to seconds by <time_in_secs>.
|
|
||||||
This methodology is taken to accomodate any hardware or simulated platform.
|
|
||||||
The sample implementation returns millisecs by default,
|
|
||||||
and the resolution is controlled by <TIMER_RES_DIVIDER>
|
|
||||||
*/
|
|
||||||
CORE_TICKS get_time(void) {
|
|
||||||
CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val));
|
|
||||||
return elapsed;
|
|
||||||
}
|
|
||||||
/* Function : time_in_secs
|
|
||||||
Convert the value returned by get_time to seconds.
|
|
||||||
|
|
||||||
The <secs_ret> type is used to accomodate systems with no support for floating point.
|
|
||||||
Default implementation implemented by the EE_TICKS_PER_SEC macro above.
|
|
||||||
*/
|
|
||||||
secs_ret time_in_secs(CORE_TICKS ticks) {
|
|
||||||
secs_ret retval=((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC;
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
ee_u32 default_num_contexts=1;
|
|
||||||
|
|
||||||
/* Function : portable_init
|
|
||||||
Target specific initialization code
|
|
||||||
Test for some common mistakes.
|
|
||||||
*/
|
|
||||||
void portable_init(core_portable *p)
|
|
||||||
{
|
|
||||||
if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) {
|
|
||||||
ee_printf("ERROR! Please define ee_ptr_int to a type that holds a pointer!\n");
|
|
||||||
}
|
|
||||||
if (sizeof(ee_u32) != 4) {
|
|
||||||
ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type!\n");
|
|
||||||
}
|
|
||||||
p->portable_id=1;
|
|
||||||
}
|
|
||||||
/* Function : portable_fini
|
|
||||||
Target specific final code
|
|
||||||
*/
|
|
||||||
void portable_fini(core_portable *p)
|
|
||||||
{
|
|
||||||
p->portable_id=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
207
zOS/MZ2000/common/CoreMark/core_portme.h
vendored
207
zOS/MZ2000/common/CoreMark/core_portme.h
vendored
@@ -1,207 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
Original Author: Shay Gal-on
|
|
||||||
*/
|
|
||||||
/* Topic : Description
|
|
||||||
This file contains configuration constants required to execute on different platforms
|
|
||||||
*/
|
|
||||||
#ifndef CORE_PORTME_H
|
|
||||||
#define CORE_PORTME_H
|
|
||||||
|
|
||||||
// ZPU compiler requires wchar.h to define size_t
|
|
||||||
#include <wchar.h>
|
|
||||||
|
|
||||||
/************************/
|
|
||||||
/* Data types and settings */
|
|
||||||
/************************/
|
|
||||||
/* Configuration : HAS_FLOAT
|
|
||||||
Define to 1 if the platform supports floating point.
|
|
||||||
*/
|
|
||||||
#ifndef HAS_FLOAT
|
|
||||||
#define HAS_FLOAT 0
|
|
||||||
#endif
|
|
||||||
/* Configuration : HAS_TIME_H
|
|
||||||
Define to 1 if platform has the time.h header file,
|
|
||||||
and implementation of functions thereof.
|
|
||||||
*/
|
|
||||||
#ifndef HAS_TIME_H
|
|
||||||
#define HAS_TIME_H 1
|
|
||||||
#endif
|
|
||||||
/* Configuration : USE_CLOCK
|
|
||||||
Define to 1 if platform has the time.h header file,
|
|
||||||
and implementation of functions thereof.
|
|
||||||
*/
|
|
||||||
#ifndef USE_CLOCK
|
|
||||||
#define USE_CLOCK 1
|
|
||||||
#endif
|
|
||||||
/* Configuration : HAS_STDIO
|
|
||||||
Define to 1 if the platform has stdio.h.
|
|
||||||
*/
|
|
||||||
#ifndef HAS_STDIO
|
|
||||||
#define HAS_STDIO 1
|
|
||||||
#endif
|
|
||||||
/* Configuration : HAS_PRINTF
|
|
||||||
Define to 1 if the platform has stdio.h and implements the printf function.
|
|
||||||
*/
|
|
||||||
#ifndef HAS_PRINTF
|
|
||||||
#define HAS_PRINTF 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION
|
|
||||||
Initialize these strings per platform
|
|
||||||
*/
|
|
||||||
#ifndef COMPILER_VERSION
|
|
||||||
#ifdef __GNUC__
|
|
||||||
#define COMPILER_VERSION "GCC" __VERSION__
|
|
||||||
#else
|
|
||||||
#define COMPILER_VERSION "Compiler version not set, please define"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
#ifndef COMPILER_FLAGS
|
|
||||||
#define COMPILER_FLAGS "Compiler flags not set, please define"
|
|
||||||
#endif
|
|
||||||
#ifndef MEM_LOCATION
|
|
||||||
#define MEM_LOCATION "STACK"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Data Types :
|
|
||||||
To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in <core_portme.h>.
|
|
||||||
|
|
||||||
*Imprtant* :
|
|
||||||
ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!!
|
|
||||||
*/
|
|
||||||
typedef signed short ee_s16;
|
|
||||||
typedef unsigned short ee_u16;
|
|
||||||
typedef signed int ee_s32;
|
|
||||||
typedef double ee_f32;
|
|
||||||
typedef unsigned char ee_u8;
|
|
||||||
typedef unsigned int ee_u32;
|
|
||||||
typedef ee_u32 ee_ptr_int;
|
|
||||||
typedef size_t ee_size_t;
|
|
||||||
|
|
||||||
// ZPU compiler already defines NULL
|
|
||||||
//#define NULL ((void *)0)
|
|
||||||
|
|
||||||
/* align_mem :
|
|
||||||
This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks.
|
|
||||||
*/
|
|
||||||
#define align_mem(x) (void *)(4 + (((ee_ptr_int)(x) - 1) & ~3))
|
|
||||||
|
|
||||||
/* Configuration : CORE_TICKS
|
|
||||||
Define type of return from the timing functions.
|
|
||||||
*/
|
|
||||||
#define CORETIMETYPE ee_u32
|
|
||||||
typedef ee_u32 CORE_TICKS;
|
|
||||||
|
|
||||||
/* Configuration : SEED_METHOD
|
|
||||||
Defines method to get seed values that cannot be computed at compile time.
|
|
||||||
|
|
||||||
Valid values :
|
|
||||||
SEED_ARG - from command line.
|
|
||||||
SEED_FUNC - from a system function.
|
|
||||||
SEED_VOLATILE - from volatile variables.
|
|
||||||
*/
|
|
||||||
#ifndef SEED_METHOD
|
|
||||||
#define SEED_METHOD SEED_VOLATILE
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Configuration : MEM_METHOD
|
|
||||||
Defines method to get a block of memry.
|
|
||||||
|
|
||||||
Valid values :
|
|
||||||
MEM_MALLOC - for platforms that implement malloc and have malloc.h.
|
|
||||||
MEM_STATIC - to use a static memory array.
|
|
||||||
MEM_STACK - to allocate the data block on the stack (NYI).
|
|
||||||
*/
|
|
||||||
#ifndef MEM_METHOD
|
|
||||||
#define MEM_METHOD MEM_STACK
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Configuration : MULTITHREAD
|
|
||||||
Define for parallel execution
|
|
||||||
|
|
||||||
Valid values :
|
|
||||||
1 - only one context (default).
|
|
||||||
N>1 - will execute N copies in parallel.
|
|
||||||
|
|
||||||
Note :
|
|
||||||
If this flag is defined to more then 1, an implementation for launching parallel contexts must be defined.
|
|
||||||
|
|
||||||
Two sample implementations are provided. Use <USE_PTHREAD> or <USE_FORK> to enable them.
|
|
||||||
|
|
||||||
It is valid to have a different implementation of <core_start_parallel> and <core_end_parallel> in <core_portme.c>,
|
|
||||||
to fit a particular architecture.
|
|
||||||
*/
|
|
||||||
#ifndef MULTITHREAD
|
|
||||||
#define MULTITHREAD 1
|
|
||||||
#define USE_PTHREAD 0
|
|
||||||
#define USE_FORK 0
|
|
||||||
#define USE_SOCKET 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Configuration : MAIN_HAS_NOARGC
|
|
||||||
Needed if platform does not support getting arguments to main.
|
|
||||||
|
|
||||||
Valid values :
|
|
||||||
0 - argc/argv to main is supported
|
|
||||||
1 - argc/argv to main is not supported
|
|
||||||
|
|
||||||
Note :
|
|
||||||
This flag only matters if MULTITHREAD has been defined to a value greater then 1.
|
|
||||||
*/
|
|
||||||
#ifndef MAIN_HAS_NOARGC
|
|
||||||
#define MAIN_HAS_NOARGC 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Configuration : MAIN_HAS_NORETURN
|
|
||||||
Needed if platform does not support returning a value from main.
|
|
||||||
|
|
||||||
Valid values :
|
|
||||||
0 - main returns an int, and return value will be 0.
|
|
||||||
1 - platform does not support returning a value from main
|
|
||||||
*/
|
|
||||||
#ifndef MAIN_HAS_NORETURN
|
|
||||||
#define MAIN_HAS_NORETURN 0
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Variable : default_num_contexts
|
|
||||||
Not used for this simple port, must cintain the value 1.
|
|
||||||
*/
|
|
||||||
extern ee_u32 default_num_contexts;
|
|
||||||
|
|
||||||
typedef struct CORE_PORTABLE_S {
|
|
||||||
ee_u8 portable_id;
|
|
||||||
} core_portable;
|
|
||||||
|
|
||||||
/* target specific init/fini */
|
|
||||||
//void portable_init(core_portable *p, int *argc, char *argv[]);
|
|
||||||
void portable_init(core_portable *p);
|
|
||||||
void portable_fini(core_portable *p);
|
|
||||||
|
|
||||||
#if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN)
|
|
||||||
#if (TOTAL_DATA_SIZE==1200)
|
|
||||||
#define PROFILE_RUN 1
|
|
||||||
#elif (TOTAL_DATA_SIZE==2000)
|
|
||||||
#define PERFORMANCE_RUN 1
|
|
||||||
#else
|
|
||||||
#define VALIDATION_RUN 1
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int ee_printf(const char *fmt, ...);
|
|
||||||
|
|
||||||
#endif /* CORE_PORTME_H */
|
|
||||||
87
zOS/MZ2000/common/CoreMark/core_portme.mak
vendored
87
zOS/MZ2000/common/CoreMark/core_portme.mak
vendored
@@ -1,87 +0,0 @@
|
|||||||
# Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
|
||||||
#
|
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
# you may not use this file except in compliance with the License.
|
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
#
|
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
# See the License for the specific language governing permissions and
|
|
||||||
# limitations under the License.
|
|
||||||
#
|
|
||||||
# Original Author: Shay Gal-on
|
|
||||||
|
|
||||||
#File : core_portme.mak
|
|
||||||
|
|
||||||
# Flag : OUTFLAG
|
|
||||||
# Use this flag to define how to to get an executable (e.g -o)
|
|
||||||
OUTFLAG= -o
|
|
||||||
# Flag : CC
|
|
||||||
# Use this flag to define compiler to use
|
|
||||||
CC = gcc
|
|
||||||
# Flag : LD
|
|
||||||
# Use this flag to define compiler to use
|
|
||||||
LD = gld
|
|
||||||
# Flag : AS
|
|
||||||
# Use this flag to define compiler to use
|
|
||||||
AS = gas
|
|
||||||
# Flag : CFLAGS
|
|
||||||
# Use this flag to define compiler options. Note, you can add compiler options from the command line using XCFLAGS="other flags"
|
|
||||||
PORT_CFLAGS = -O0 -g
|
|
||||||
FLAGS_STR = "$(PORT_CFLAGS) $(XCFLAGS) $(XLFLAGS) $(LFLAGS_END)"
|
|
||||||
CFLAGS = $(PORT_CFLAGS) -I$(PORT_DIR) -I. -DFLAGS_STR=\"$(FLAGS_STR)\"
|
|
||||||
#Flag : LFLAGS_END
|
|
||||||
# Define any libraries needed for linking or other flags that should come at the end of the link line (e.g. linker scripts).
|
|
||||||
# Note : On certain platforms, the default clock_gettime implementation is supported but requires linking of librt.
|
|
||||||
SEPARATE_COMPILE=1
|
|
||||||
# Flag : SEPARATE_COMPILE
|
|
||||||
# You must also define below how to create an object file, and how to link.
|
|
||||||
OBJOUT = -o
|
|
||||||
LFLAGS =
|
|
||||||
ASFLAGS =
|
|
||||||
OFLAG = -o
|
|
||||||
COUT = -c
|
|
||||||
|
|
||||||
LFLAGS_END =
|
|
||||||
# Flag : PORT_SRCS
|
|
||||||
# Port specific source files can be added here
|
|
||||||
# You may also need cvt.c if the fcvt functions are not provided as intrinsics by your compiler!
|
|
||||||
PORT_SRCS = $(PORT_DIR)/core_portme.c $(PORT_DIR)/ee_printf.c
|
|
||||||
vpath %.c $(PORT_DIR)
|
|
||||||
vpath %.s $(PORT_DIR)
|
|
||||||
|
|
||||||
# Flag : LOAD
|
|
||||||
# For a simple port, we assume self hosted compile and run, no load needed.
|
|
||||||
|
|
||||||
# Flag : RUN
|
|
||||||
# For a simple port, we assume self hosted compile and run, simple invocation of the executable
|
|
||||||
|
|
||||||
LOAD = echo "Please set LOAD to the process of loading the executable to the flash"
|
|
||||||
RUN = echo "Please set LOAD to the process of running the executable (e.g. via jtag, or board reset)"
|
|
||||||
|
|
||||||
OEXT = .o
|
|
||||||
EXE = .bin
|
|
||||||
|
|
||||||
$(OPATH)$(PORT_DIR)/%$(OEXT) : %.c
|
|
||||||
$(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@
|
|
||||||
|
|
||||||
$(OPATH)%$(OEXT) : %.c
|
|
||||||
$(CC) $(CFLAGS) $(XCFLAGS) $(COUT) $< $(OBJOUT) $@
|
|
||||||
|
|
||||||
$(OPATH)$(PORT_DIR)/%$(OEXT) : %.s
|
|
||||||
$(AS) $(ASFLAGS) $< $(OBJOUT) $@
|
|
||||||
|
|
||||||
# Target : port_pre% and port_post%
|
|
||||||
# For the purpose of this simple port, no pre or post steps needed.
|
|
||||||
|
|
||||||
.PHONY : port_prebuild port_postbuild port_prerun port_postrun port_preload port_postload
|
|
||||||
port_pre% port_post% :
|
|
||||||
|
|
||||||
# FLAG : OPATH
|
|
||||||
# Path to the output folder. Default - current folder.
|
|
||||||
OPATH = ./
|
|
||||||
MKDIR = mkdir -p
|
|
||||||
|
|
||||||
@@ -1,277 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
Original Author: Shay Gal-on
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "coremark.h"
|
|
||||||
/* local functions */
|
|
||||||
enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count);
|
|
||||||
|
|
||||||
/*
|
|
||||||
Topic: Description
|
|
||||||
Simple state machines like this one are used in many embedded products.
|
|
||||||
|
|
||||||
For more complex state machines, sometimes a state transition table implementation is used instead,
|
|
||||||
trading speed of direct coding for ease of maintenance.
|
|
||||||
|
|
||||||
Since the main goal of using a state machine in CoreMark is to excercise the switch/if behaviour,
|
|
||||||
we are using a small moore machine.
|
|
||||||
|
|
||||||
In particular, this machine tests type of string input,
|
|
||||||
trying to determine whether the input is a number or something else.
|
|
||||||
(see core_state.png).
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Function: core_bench_state
|
|
||||||
Benchmark function
|
|
||||||
|
|
||||||
Go over the input twice, once direct, and once after introducing some corruption.
|
|
||||||
*/
|
|
||||||
ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock,
|
|
||||||
ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc)
|
|
||||||
{
|
|
||||||
ee_u32 final_counts[NUM_CORE_STATES];
|
|
||||||
ee_u32 track_counts[NUM_CORE_STATES];
|
|
||||||
ee_u8 *p=memblock;
|
|
||||||
ee_u32 i;
|
|
||||||
|
|
||||||
|
|
||||||
#if CORE_DEBUG
|
|
||||||
ee_printf("State Bench: %d,%d,%d,%04x\n",seed1,seed2,step,crc);
|
|
||||||
#endif
|
|
||||||
for (i=0; i<NUM_CORE_STATES; i++) {
|
|
||||||
final_counts[i]=track_counts[i]=0;
|
|
||||||
}
|
|
||||||
/* run the state machine over the input */
|
|
||||||
while (*p!=0) {
|
|
||||||
enum CORE_STATE fstate=core_state_transition(&p,track_counts);
|
|
||||||
final_counts[fstate]++;
|
|
||||||
#if CORE_DEBUG
|
|
||||||
ee_printf("%d,",fstate);
|
|
||||||
}
|
|
||||||
ee_printf("\n");
|
|
||||||
#else
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
p=memblock;
|
|
||||||
while (p < (memblock+blksize)) { /* insert some corruption */
|
|
||||||
if (*p!=',')
|
|
||||||
*p^=(ee_u8)seed1;
|
|
||||||
p+=step;
|
|
||||||
}
|
|
||||||
p=memblock;
|
|
||||||
/* run the state machine over the input again */
|
|
||||||
while (*p!=0) {
|
|
||||||
enum CORE_STATE fstate=core_state_transition(&p,track_counts);
|
|
||||||
final_counts[fstate]++;
|
|
||||||
#if CORE_DEBUG
|
|
||||||
ee_printf("%d,",fstate);
|
|
||||||
}
|
|
||||||
ee_printf("\n");
|
|
||||||
#else
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
p=memblock;
|
|
||||||
while (p < (memblock+blksize)) { /* undo corruption is seed1 and seed2 are equal */
|
|
||||||
if (*p!=',')
|
|
||||||
*p^=(ee_u8)seed2;
|
|
||||||
p+=step;
|
|
||||||
}
|
|
||||||
/* end timing */
|
|
||||||
for (i=0; i<NUM_CORE_STATES; i++) {
|
|
||||||
crc=crcu32(final_counts[i],crc);
|
|
||||||
crc=crcu32(track_counts[i],crc);
|
|
||||||
}
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Default initialization patterns */
|
|
||||||
static ee_u8 *intpat[4] ={(ee_u8 *)"5012",(ee_u8 *)"1234",(ee_u8 *)"-874",(ee_u8 *)"+122"};
|
|
||||||
static ee_u8 *floatpat[4]={(ee_u8 *)"35.54400",(ee_u8 *)".1234500",(ee_u8 *)"-110.700",(ee_u8 *)"+0.64400"};
|
|
||||||
static ee_u8 *scipat[4] ={(ee_u8 *)"5.500e+3",(ee_u8 *)"-.123e-2",(ee_u8 *)"-87e+832",(ee_u8 *)"+0.6e-12"};
|
|
||||||
static ee_u8 *errpat[4] ={(ee_u8 *)"T0.3e-1F",(ee_u8 *)"-T.T++Tq",(ee_u8 *)"1T3.4e4z",(ee_u8 *)"34.0e-T^"};
|
|
||||||
|
|
||||||
/* Function: core_init_state
|
|
||||||
Initialize the input data for the state machine.
|
|
||||||
|
|
||||||
Populate the input with several predetermined strings, interspersed.
|
|
||||||
Actual patterns chosen depend on the seed parameter.
|
|
||||||
|
|
||||||
Note:
|
|
||||||
The seed parameter MUST be supplied from a source that cannot be determined at compile time
|
|
||||||
*/
|
|
||||||
void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p) {
|
|
||||||
ee_u32 total=0,next=0,i;
|
|
||||||
ee_u8 *buf=0;
|
|
||||||
#if CORE_DEBUG
|
|
||||||
ee_u8 *start=p;
|
|
||||||
ee_printf("State: %d,%d\n",size,seed);
|
|
||||||
#endif
|
|
||||||
size--;
|
|
||||||
next=0;
|
|
||||||
while ((total+next+1)<size) {
|
|
||||||
if (next>0) {
|
|
||||||
for(i=0;i<next;i++)
|
|
||||||
*(p+total+i)=buf[i];
|
|
||||||
*(p+total+i)=',';
|
|
||||||
total+=next+1;
|
|
||||||
}
|
|
||||||
seed++;
|
|
||||||
switch (seed & 0x7) {
|
|
||||||
case 0: /* int */
|
|
||||||
case 1: /* int */
|
|
||||||
case 2: /* int */
|
|
||||||
buf=intpat[(seed>>3) & 0x3];
|
|
||||||
next=4;
|
|
||||||
break;
|
|
||||||
case 3: /* float */
|
|
||||||
case 4: /* float */
|
|
||||||
buf=floatpat[(seed>>3) & 0x3];
|
|
||||||
next=8;
|
|
||||||
break;
|
|
||||||
case 5: /* scientific */
|
|
||||||
case 6: /* scientific */
|
|
||||||
buf=scipat[(seed>>3) & 0x3];
|
|
||||||
next=8;
|
|
||||||
break;
|
|
||||||
case 7: /* invalid */
|
|
||||||
buf=errpat[(seed>>3) & 0x3];
|
|
||||||
next=8;
|
|
||||||
break;
|
|
||||||
default: /* Never happen, just to make some compilers happy */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
size++;
|
|
||||||
while (total<size) { /* fill the rest with 0 */
|
|
||||||
*(p+total)=0;
|
|
||||||
total++;
|
|
||||||
}
|
|
||||||
#if CORE_DEBUG
|
|
||||||
ee_printf("State Input: %s\n",start);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static ee_u8 ee_isdigit(ee_u8 c) {
|
|
||||||
ee_u8 retval;
|
|
||||||
retval = ((c>='0') & (c<='9')) ? 1 : 0;
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function: core_state_transition
|
|
||||||
Actual state machine.
|
|
||||||
|
|
||||||
The state machine will continue scanning until either:
|
|
||||||
1 - an invalid input is detcted.
|
|
||||||
2 - a valid number has been detected.
|
|
||||||
|
|
||||||
The input pointer is updated to point to the end of the token, and the end state is returned (either specific format determined or invalid).
|
|
||||||
*/
|
|
||||||
|
|
||||||
enum CORE_STATE core_state_transition( ee_u8 **instr , ee_u32 *transition_count) {
|
|
||||||
ee_u8 *str=*instr;
|
|
||||||
ee_u8 NEXT_SYMBOL;
|
|
||||||
enum CORE_STATE state=CORE_START;
|
|
||||||
for( ; *str && state != CORE_INVALID; str++ ) {
|
|
||||||
NEXT_SYMBOL = *str;
|
|
||||||
if (NEXT_SYMBOL==',') /* end of this input */ {
|
|
||||||
str++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
switch(state) {
|
|
||||||
case CORE_START:
|
|
||||||
if(ee_isdigit(NEXT_SYMBOL)) {
|
|
||||||
state = CORE_INT;
|
|
||||||
}
|
|
||||||
else if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
|
|
||||||
state = CORE_S1;
|
|
||||||
}
|
|
||||||
else if( NEXT_SYMBOL == '.' ) {
|
|
||||||
state = CORE_FLOAT;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
state = CORE_INVALID;
|
|
||||||
transition_count[CORE_INVALID]++;
|
|
||||||
}
|
|
||||||
transition_count[CORE_START]++;
|
|
||||||
break;
|
|
||||||
case CORE_S1:
|
|
||||||
if(ee_isdigit(NEXT_SYMBOL)) {
|
|
||||||
state = CORE_INT;
|
|
||||||
transition_count[CORE_S1]++;
|
|
||||||
}
|
|
||||||
else if( NEXT_SYMBOL == '.' ) {
|
|
||||||
state = CORE_FLOAT;
|
|
||||||
transition_count[CORE_S1]++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
state = CORE_INVALID;
|
|
||||||
transition_count[CORE_S1]++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CORE_INT:
|
|
||||||
if( NEXT_SYMBOL == '.' ) {
|
|
||||||
state = CORE_FLOAT;
|
|
||||||
transition_count[CORE_INT]++;
|
|
||||||
}
|
|
||||||
else if(!ee_isdigit(NEXT_SYMBOL)) {
|
|
||||||
state = CORE_INVALID;
|
|
||||||
transition_count[CORE_INT]++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CORE_FLOAT:
|
|
||||||
if( NEXT_SYMBOL == 'E' || NEXT_SYMBOL == 'e' ) {
|
|
||||||
state = CORE_S2;
|
|
||||||
transition_count[CORE_FLOAT]++;
|
|
||||||
}
|
|
||||||
else if(!ee_isdigit(NEXT_SYMBOL)) {
|
|
||||||
state = CORE_INVALID;
|
|
||||||
transition_count[CORE_FLOAT]++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CORE_S2:
|
|
||||||
if( NEXT_SYMBOL == '+' || NEXT_SYMBOL == '-' ) {
|
|
||||||
state = CORE_EXPONENT;
|
|
||||||
transition_count[CORE_S2]++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
state = CORE_INVALID;
|
|
||||||
transition_count[CORE_S2]++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CORE_EXPONENT:
|
|
||||||
if(ee_isdigit(NEXT_SYMBOL)) {
|
|
||||||
state = CORE_SCIENTIFIC;
|
|
||||||
transition_count[CORE_EXPONENT]++;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
state = CORE_INVALID;
|
|
||||||
transition_count[CORE_EXPONENT]++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case CORE_SCIENTIFIC:
|
|
||||||
if(!ee_isdigit(NEXT_SYMBOL)) {
|
|
||||||
state = CORE_INVALID;
|
|
||||||
transition_count[CORE_INVALID]++;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*instr=str;
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
@@ -1,210 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
Original Author: Shay Gal-on
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "coremark.h"
|
|
||||||
/* Function: get_seed
|
|
||||||
Get a values that cannot be determined at compile time.
|
|
||||||
|
|
||||||
Since different embedded systems and compilers are used, 3 different methods are provided:
|
|
||||||
1 - Using a volatile variable. This method is only valid if the compiler is forced to generate code that
|
|
||||||
reads the value of a volatile variable from memory at run time.
|
|
||||||
Please note, if using this method, you would need to modify core_portme.c to generate training profile.
|
|
||||||
2 - Command line arguments. This is the preferred method if command line arguments are supported.
|
|
||||||
3 - System function. If none of the first 2 methods is available on the platform,
|
|
||||||
a system function which is not a stub can be used.
|
|
||||||
|
|
||||||
e.g. read the value on GPIO pins connected to switches, or invoke special simulator functions.
|
|
||||||
*/
|
|
||||||
#if (SEED_METHOD==SEED_VOLATILE)
|
|
||||||
extern volatile ee_s32 seed1_volatile;
|
|
||||||
extern volatile ee_s32 seed2_volatile;
|
|
||||||
extern volatile ee_s32 seed3_volatile;
|
|
||||||
extern volatile ee_s32 seed4_volatile;
|
|
||||||
extern volatile ee_s32 seed5_volatile;
|
|
||||||
ee_s32 get_seed_32(int i) {
|
|
||||||
ee_s32 retval;
|
|
||||||
switch (i) {
|
|
||||||
case 1:
|
|
||||||
retval=seed1_volatile;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
retval=seed2_volatile;
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
retval=seed3_volatile;
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
retval=seed4_volatile;
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
retval=seed5_volatile;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
retval=0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
#elif (SEED_METHOD==SEED_ARG)
|
|
||||||
ee_s32 parseval(char *valstring) {
|
|
||||||
ee_s32 retval=0;
|
|
||||||
ee_s32 neg=1;
|
|
||||||
int hexmode=0;
|
|
||||||
if (*valstring == '-') {
|
|
||||||
neg=-1;
|
|
||||||
valstring++;
|
|
||||||
}
|
|
||||||
if ((valstring[0] == '0') && (valstring[1] == 'x')) {
|
|
||||||
hexmode=1;
|
|
||||||
valstring+=2;
|
|
||||||
}
|
|
||||||
/* first look for digits */
|
|
||||||
if (hexmode) {
|
|
||||||
while (((*valstring >= '0') && (*valstring <= '9')) || ((*valstring >= 'a') && (*valstring <= 'f'))) {
|
|
||||||
ee_s32 digit=*valstring-'0';
|
|
||||||
if (digit>9)
|
|
||||||
digit=10+*valstring-'a';
|
|
||||||
retval*=16;
|
|
||||||
retval+=digit;
|
|
||||||
valstring++;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
while ((*valstring >= '0') && (*valstring <= '9')) {
|
|
||||||
ee_s32 digit=*valstring-'0';
|
|
||||||
retval*=10;
|
|
||||||
retval+=digit;
|
|
||||||
valstring++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* now add qualifiers */
|
|
||||||
if (*valstring=='K')
|
|
||||||
retval*=1024;
|
|
||||||
if (*valstring=='M')
|
|
||||||
retval*=1024*1024;
|
|
||||||
|
|
||||||
retval*=neg;
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
|
|
||||||
ee_s32 get_seed_args(int i, int argc, char *argv[]) {
|
|
||||||
if (argc>i)
|
|
||||||
return parseval(argv[i]);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
#elif (SEED_METHOD==SEED_FUNC)
|
|
||||||
/* If using OS based function, you must define and implement the functions below in core_portme.h and core_portme.c ! */
|
|
||||||
ee_s32 get_seed_32(int i) {
|
|
||||||
ee_s32 retval;
|
|
||||||
switch (i) {
|
|
||||||
case 1:
|
|
||||||
retval=portme_sys1();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
retval=portme_sys2();
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
retval=portme_sys3();
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
retval=portme_sys4();
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
retval=portme_sys5();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
retval=0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Function: crc*
|
|
||||||
Service functions to calculate 16b CRC code.
|
|
||||||
|
|
||||||
*/
|
|
||||||
ee_u16 crcu8(ee_u8 data, ee_u16 crc )
|
|
||||||
{
|
|
||||||
ee_u8 i=0,x16=0,carry=0;
|
|
||||||
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
x16 = (ee_u8)((data & 1) ^ ((ee_u8)crc & 1));
|
|
||||||
data >>= 1;
|
|
||||||
|
|
||||||
if (x16 == 1)
|
|
||||||
{
|
|
||||||
crc ^= 0x4002;
|
|
||||||
carry = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
carry = 0;
|
|
||||||
crc >>= 1;
|
|
||||||
if (carry)
|
|
||||||
crc |= 0x8000;
|
|
||||||
else
|
|
||||||
crc &= 0x7fff;
|
|
||||||
}
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
ee_u16 crcu16(ee_u16 newval, ee_u16 crc) {
|
|
||||||
crc=crcu8( (ee_u8) (newval) ,crc);
|
|
||||||
crc=crcu8( (ee_u8) ((newval)>>8) ,crc);
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
ee_u16 crcu32(ee_u32 newval, ee_u16 crc) {
|
|
||||||
crc=crc16((ee_s16) newval ,crc);
|
|
||||||
crc=crc16((ee_s16) (newval>>16) ,crc);
|
|
||||||
return crc;
|
|
||||||
}
|
|
||||||
ee_u16 crc16(ee_s16 newval, ee_u16 crc) {
|
|
||||||
return crcu16((ee_u16)newval, crc);
|
|
||||||
}
|
|
||||||
|
|
||||||
ee_u8 check_data_types() {
|
|
||||||
ee_u8 retval=0;
|
|
||||||
if (sizeof(ee_u8) != 1) {
|
|
||||||
ee_printf("ERROR: ee_u8 is not an 8b datatype!\n");
|
|
||||||
retval++;
|
|
||||||
}
|
|
||||||
if (sizeof(ee_u16) != 2) {
|
|
||||||
ee_printf("ERROR: ee_u16 is not a 16b datatype!\n");
|
|
||||||
retval++;
|
|
||||||
}
|
|
||||||
if (sizeof(ee_s16) != 2) {
|
|
||||||
ee_printf("ERROR: ee_s16 is not a 16b datatype!\n");
|
|
||||||
retval++;
|
|
||||||
}
|
|
||||||
if (sizeof(ee_s32) != 4) {
|
|
||||||
ee_printf("ERROR: ee_s32 is not a 32b datatype!\n");
|
|
||||||
retval++;
|
|
||||||
}
|
|
||||||
if (sizeof(ee_u32) != 4) {
|
|
||||||
ee_printf("ERROR: ee_u32 is not a 32b datatype!\n");
|
|
||||||
retval++;
|
|
||||||
}
|
|
||||||
if (sizeof(ee_ptr_int) != sizeof(int *)) {
|
|
||||||
ee_printf("ERROR: ee_ptr_int is not a datatype that holds an int pointer!\n");
|
|
||||||
retval++;
|
|
||||||
}
|
|
||||||
if (retval>0) {
|
|
||||||
ee_printf("ERROR: Please modify the datatypes in core_portme.h!\n");
|
|
||||||
}
|
|
||||||
return retval;
|
|
||||||
}
|
|
||||||
184
zOS/MZ2000/common/CoreMark/coremark.h
vendored
184
zOS/MZ2000/common/CoreMark/coremark.h
vendored
@@ -1,184 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
|
|
||||||
Original Author: Shay Gal-on
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Topic: Description
|
|
||||||
This file contains declarations of the various benchmark functions.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Configuration: TOTAL_DATA_SIZE
|
|
||||||
Define total size for data algorithms will operate on
|
|
||||||
*/
|
|
||||||
#ifndef TOTAL_DATA_SIZE
|
|
||||||
#define TOTAL_DATA_SIZE 2*1000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SEED_ARG 0
|
|
||||||
#define SEED_FUNC 1
|
|
||||||
#define SEED_VOLATILE 2
|
|
||||||
|
|
||||||
#define MEM_STATIC 0
|
|
||||||
#define MEM_MALLOC 1
|
|
||||||
#define MEM_STACK 2
|
|
||||||
|
|
||||||
#include "core_portme.h"
|
|
||||||
|
|
||||||
#if HAS_STDIO
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif
|
|
||||||
#if defined HAS_PRINTF && HAS_PRINTF == 1
|
|
||||||
#define ee_printf printf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Actual benchmark execution in iterate */
|
|
||||||
void *iterate(void *pres);
|
|
||||||
|
|
||||||
/* Typedef: secs_ret
|
|
||||||
For machines that have floating point support, get number of seconds as a double.
|
|
||||||
Otherwise an unsigned int.
|
|
||||||
*/
|
|
||||||
#if HAS_FLOAT
|
|
||||||
typedef double secs_ret;
|
|
||||||
#else
|
|
||||||
typedef ee_u32 secs_ret;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if MAIN_HAS_NORETURN
|
|
||||||
#define MAIN_RETURN_VAL
|
|
||||||
#define MAIN_RETURN_TYPE void
|
|
||||||
#else
|
|
||||||
#define MAIN_RETURN_VAL 0
|
|
||||||
#define MAIN_RETURN_TYPE int
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void start_time(void);
|
|
||||||
void stop_time(void);
|
|
||||||
CORE_TICKS get_time(void);
|
|
||||||
secs_ret time_in_secs(CORE_TICKS ticks);
|
|
||||||
|
|
||||||
/* Misc useful functions */
|
|
||||||
ee_u16 crcu8(ee_u8 data, ee_u16 crc);
|
|
||||||
ee_u16 crc16(ee_s16 newval, ee_u16 crc);
|
|
||||||
ee_u16 crcu16(ee_u16 newval, ee_u16 crc);
|
|
||||||
ee_u16 crcu32(ee_u32 newval, ee_u16 crc);
|
|
||||||
ee_u8 check_data_types();
|
|
||||||
void *portable_malloc(ee_size_t size);
|
|
||||||
void portable_free(void *p);
|
|
||||||
ee_s32 parseval(char *valstring);
|
|
||||||
|
|
||||||
/* Algorithm IDS */
|
|
||||||
#define ID_LIST (1<<0)
|
|
||||||
#define ID_MATRIX (1<<1)
|
|
||||||
#define ID_STATE (1<<2)
|
|
||||||
#define ALL_ALGORITHMS_MASK (ID_LIST|ID_MATRIX|ID_STATE)
|
|
||||||
#define NUM_ALGORITHMS 3
|
|
||||||
|
|
||||||
/* list data structures */
|
|
||||||
typedef struct list_data_s {
|
|
||||||
ee_s16 data16;
|
|
||||||
ee_s16 idx;
|
|
||||||
} list_data;
|
|
||||||
|
|
||||||
typedef struct list_head_s {
|
|
||||||
struct list_head_s *next;
|
|
||||||
struct list_data_s *info;
|
|
||||||
} list_head;
|
|
||||||
|
|
||||||
|
|
||||||
/*matrix benchmark related stuff */
|
|
||||||
#define MATDAT_INT 1
|
|
||||||
#if MATDAT_INT
|
|
||||||
typedef ee_s16 MATDAT;
|
|
||||||
typedef ee_s32 MATRES;
|
|
||||||
#else
|
|
||||||
typedef ee_f16 MATDAT;
|
|
||||||
typedef ee_f32 MATRES;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef struct MAT_PARAMS_S {
|
|
||||||
int N;
|
|
||||||
MATDAT *A;
|
|
||||||
MATDAT *B;
|
|
||||||
MATRES *C;
|
|
||||||
} mat_params;
|
|
||||||
|
|
||||||
/* state machine related stuff */
|
|
||||||
/* List of all the possible states for the FSM */
|
|
||||||
typedef enum CORE_STATE {
|
|
||||||
CORE_START=0,
|
|
||||||
CORE_INVALID,
|
|
||||||
CORE_S1,
|
|
||||||
CORE_S2,
|
|
||||||
CORE_INT,
|
|
||||||
CORE_FLOAT,
|
|
||||||
CORE_EXPONENT,
|
|
||||||
CORE_SCIENTIFIC,
|
|
||||||
NUM_CORE_STATES
|
|
||||||
} core_state_e ;
|
|
||||||
|
|
||||||
|
|
||||||
/* Helper structure to hold results */
|
|
||||||
typedef struct RESULTS_S {
|
|
||||||
/* inputs */
|
|
||||||
ee_s16 seed1; /* Initializing seed */
|
|
||||||
ee_s16 seed2; /* Initializing seed */
|
|
||||||
ee_s16 seed3; /* Initializing seed */
|
|
||||||
void *memblock[4]; /* Pointer to safe memory location */
|
|
||||||
ee_u32 size; /* Size of the data */
|
|
||||||
ee_u32 iterations; /* Number of iterations to execute */
|
|
||||||
ee_u32 execs; /* Bitmask of operations to execute */
|
|
||||||
struct list_head_s *list;
|
|
||||||
mat_params mat;
|
|
||||||
/* outputs */
|
|
||||||
ee_u16 crc;
|
|
||||||
ee_u16 crclist;
|
|
||||||
ee_u16 crcmatrix;
|
|
||||||
ee_u16 crcstate;
|
|
||||||
ee_s16 err;
|
|
||||||
/* ultithread specific */
|
|
||||||
core_portable port;
|
|
||||||
} core_results;
|
|
||||||
|
|
||||||
/* Multicore execution handling */
|
|
||||||
#if (MULTITHREAD>1)
|
|
||||||
ee_u8 core_start_parallel(core_results *res);
|
|
||||||
ee_u8 core_stop_parallel(core_results *res);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* list benchmark functions */
|
|
||||||
list_head *core_list_init(ee_u32 blksize, list_head *memblock, ee_s16 seed);
|
|
||||||
ee_u16 core_bench_list(core_results *res, ee_s16 finder_idx);
|
|
||||||
|
|
||||||
/* state benchmark functions */
|
|
||||||
void core_init_state(ee_u32 size, ee_s16 seed, ee_u8 *p);
|
|
||||||
ee_u16 core_bench_state(ee_u32 blksize, ee_u8 *memblock,
|
|
||||||
ee_s16 seed1, ee_s16 seed2, ee_s16 step, ee_u16 crc);
|
|
||||||
|
|
||||||
/* matrix benchmark functions */
|
|
||||||
ee_u32 core_init_matrix(ee_u32 blksize, void *memblk, ee_s32 seed, mat_params *p);
|
|
||||||
ee_u16 core_bench_matrix(mat_params *p, ee_s16 seed, ee_u16 crc);
|
|
||||||
|
|
||||||
/* Embedded entry point, when using CoreMark as part of a test suite and not a standalone program */
|
|
||||||
MAIN_RETURN_TYPE CoreMarkTest(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,117 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
#include <math.h>
|
|
||||||
#define CVTBUFSIZE 80
|
|
||||||
static char CVTBUF[CVTBUFSIZE];
|
|
||||||
|
|
||||||
static char *cvt(double arg, int ndigits, int *decpt, int *sign, char *buf, int eflag)
|
|
||||||
{
|
|
||||||
int r2;
|
|
||||||
double fi, fj;
|
|
||||||
char *p, *p1;
|
|
||||||
|
|
||||||
if (ndigits < 0) ndigits = 0;
|
|
||||||
if (ndigits >= CVTBUFSIZE - 1) ndigits = CVTBUFSIZE - 2;
|
|
||||||
r2 = 0;
|
|
||||||
*sign = 0;
|
|
||||||
p = &buf[0];
|
|
||||||
if (arg < 0)
|
|
||||||
{
|
|
||||||
*sign = 1;
|
|
||||||
arg = -arg;
|
|
||||||
}
|
|
||||||
arg = modf(arg, &fi);
|
|
||||||
p1 = &buf[CVTBUFSIZE];
|
|
||||||
|
|
||||||
if (fi != 0)
|
|
||||||
{
|
|
||||||
p1 = &buf[CVTBUFSIZE];
|
|
||||||
while (fi != 0)
|
|
||||||
{
|
|
||||||
fj = modf(fi / 10, &fi);
|
|
||||||
*--p1 = (int)((fj + .03) * 10) + '0';
|
|
||||||
r2++;
|
|
||||||
}
|
|
||||||
while (p1 < &buf[CVTBUFSIZE]) *p++ = *p1++;
|
|
||||||
}
|
|
||||||
else if (arg > 0)
|
|
||||||
{
|
|
||||||
while ((fj = arg * 10) < 1)
|
|
||||||
{
|
|
||||||
arg = fj;
|
|
||||||
r2--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
p1 = &buf[ndigits];
|
|
||||||
if (eflag == 0) p1 += r2;
|
|
||||||
*decpt = r2;
|
|
||||||
if (p1 < &buf[0])
|
|
||||||
{
|
|
||||||
buf[0] = '\0';
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
while (p <= p1 && p < &buf[CVTBUFSIZE])
|
|
||||||
{
|
|
||||||
arg *= 10;
|
|
||||||
arg = modf(arg, &fj);
|
|
||||||
*p++ = (int) fj + '0';
|
|
||||||
}
|
|
||||||
if (p1 >= &buf[CVTBUFSIZE])
|
|
||||||
{
|
|
||||||
buf[CVTBUFSIZE - 1] = '\0';
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
p = p1;
|
|
||||||
*p1 += 5;
|
|
||||||
while (*p1 > '9')
|
|
||||||
{
|
|
||||||
*p1 = '0';
|
|
||||||
if (p1 > buf)
|
|
||||||
++*--p1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*p1 = '1';
|
|
||||||
(*decpt)++;
|
|
||||||
if (eflag == 0)
|
|
||||||
{
|
|
||||||
if (p > buf) *p = '0';
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*p = '\0';
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *ecvt(double arg, int ndigits, int *decpt, int *sign)
|
|
||||||
{
|
|
||||||
return cvt(arg, ndigits, decpt, sign, CVTBUF, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf)
|
|
||||||
{
|
|
||||||
return cvt(arg, ndigits, decpt, sign, buf, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *fcvt(double arg, int ndigits, int *decpt, int *sign)
|
|
||||||
{
|
|
||||||
return cvt(arg, ndigits, decpt, sign, CVTBUF, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
char *fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf)
|
|
||||||
{
|
|
||||||
return cvt(arg, ndigits, decpt, sign, buf, 0);
|
|
||||||
}
|
|
||||||
@@ -1,606 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright 2018 Embedded Microprocessor Benchmark Consortium (EEMBC)
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <coremark.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
|
|
||||||
#if defined HAS_PRINTF && HAS_PRINTF == 0
|
|
||||||
|
|
||||||
#if defined __K64F__
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#undef stdout
|
|
||||||
#undef stdin
|
|
||||||
#undef stderr
|
|
||||||
extern FILE *stdout;
|
|
||||||
extern FILE *stdin;
|
|
||||||
extern FILE *stderr;
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define ZEROPAD (1<<0) /* Pad with zero */
|
|
||||||
#define SIGN (1<<1) /* Unsigned/signed long */
|
|
||||||
#define PLUS (1<<2) /* Show plus */
|
|
||||||
#define SPACE (1<<3) /* Spacer */
|
|
||||||
#define LEFT (1<<4) /* Left justified */
|
|
||||||
#define HEX_PREP (1<<5) /* 0x */
|
|
||||||
#define UPPERCASE (1<<6) /* 'ABCDEF' */
|
|
||||||
|
|
||||||
#define is_digit(c) ((c) >= '0' && (c) <= '9')
|
|
||||||
|
|
||||||
static char *digits = "0123456789abcdefghijklmnopqrstuvwxyz";
|
|
||||||
static char *upper_digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
||||||
static ee_size_t strnlen(const char *s, ee_size_t count);
|
|
||||||
|
|
||||||
static ee_size_t strnlen(const char *s, ee_size_t count)
|
|
||||||
{
|
|
||||||
const char *sc;
|
|
||||||
for (sc = s; *sc != '\0' && count--; ++sc);
|
|
||||||
return sc - s;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int skip_atoi(const char **s)
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
while (is_digit(**s)) i = i*10 + *((*s)++) - '0';
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *number(char *str, long num, int base, int size, int precision, int type)
|
|
||||||
{
|
|
||||||
char c, sign, tmp[66];
|
|
||||||
char *dig = digits;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (type & UPPERCASE) dig = upper_digits;
|
|
||||||
if (type & LEFT) type &= ~ZEROPAD;
|
|
||||||
if (base < 2 || base > 36) return 0;
|
|
||||||
|
|
||||||
c = (type & ZEROPAD) ? '0' : ' ';
|
|
||||||
sign = 0;
|
|
||||||
if (type & SIGN)
|
|
||||||
{
|
|
||||||
if (num < 0)
|
|
||||||
{
|
|
||||||
sign = '-';
|
|
||||||
num = -num;
|
|
||||||
size--;
|
|
||||||
}
|
|
||||||
else if (type & PLUS)
|
|
||||||
{
|
|
||||||
sign = '+';
|
|
||||||
size--;
|
|
||||||
}
|
|
||||||
else if (type & SPACE)
|
|
||||||
{
|
|
||||||
sign = ' ';
|
|
||||||
size--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (type & HEX_PREP)
|
|
||||||
{
|
|
||||||
if (base == 16)
|
|
||||||
size -= 2;
|
|
||||||
else if (base == 8)
|
|
||||||
size--;
|
|
||||||
}
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
|
|
||||||
if (num == 0)
|
|
||||||
tmp[i++] = '0';
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while (num != 0)
|
|
||||||
{
|
|
||||||
tmp[i++] = dig[((unsigned long) num) % (unsigned) base];
|
|
||||||
num = ((unsigned long) num) / (unsigned) base;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i > precision) precision = i;
|
|
||||||
size -= precision;
|
|
||||||
if (!(type & (ZEROPAD | LEFT))) while (size-- > 0) *str++ = ' ';
|
|
||||||
if (sign) *str++ = sign;
|
|
||||||
|
|
||||||
if (type & HEX_PREP)
|
|
||||||
{
|
|
||||||
if (base == 8)
|
|
||||||
*str++ = '0';
|
|
||||||
else if (base == 16)
|
|
||||||
{
|
|
||||||
*str++ = '0';
|
|
||||||
*str++ = digits[33];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(type & LEFT)) while (size-- > 0) *str++ = c;
|
|
||||||
while (i < precision--) *str++ = '0';
|
|
||||||
while (i-- > 0) *str++ = tmp[i];
|
|
||||||
while (size-- > 0) *str++ = ' ';
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *eaddr(char *str, unsigned char *addr, int size, int precision, int type)
|
|
||||||
{
|
|
||||||
char tmp[24];
|
|
||||||
char *dig = digits;
|
|
||||||
int i, len;
|
|
||||||
|
|
||||||
if (type & UPPERCASE) dig = upper_digits;
|
|
||||||
len = 0;
|
|
||||||
for (i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
if (i != 0) tmp[len++] = ':';
|
|
||||||
tmp[len++] = dig[addr[i] >> 4];
|
|
||||||
tmp[len++] = dig[addr[i] & 0x0F];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(type & LEFT)) while (len < size--) *str++ = ' ';
|
|
||||||
for (i = 0; i < len; ++i) *str++ = tmp[i];
|
|
||||||
while (len < size--) *str++ = ' ';
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *iaddr(char *str, unsigned char *addr, int size, int precision, int type)
|
|
||||||
{
|
|
||||||
char tmp[24];
|
|
||||||
int i, n, len;
|
|
||||||
|
|
||||||
len = 0;
|
|
||||||
for (i = 0; i < 4; i++)
|
|
||||||
{
|
|
||||||
if (i != 0) tmp[len++] = '.';
|
|
||||||
n = addr[i];
|
|
||||||
|
|
||||||
if (n == 0)
|
|
||||||
tmp[len++] = digits[0];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (n >= 100)
|
|
||||||
{
|
|
||||||
tmp[len++] = digits[n / 100];
|
|
||||||
n = n % 100;
|
|
||||||
tmp[len++] = digits[n / 10];
|
|
||||||
n = n % 10;
|
|
||||||
}
|
|
||||||
else if (n >= 10)
|
|
||||||
{
|
|
||||||
tmp[len++] = digits[n / 10];
|
|
||||||
n = n % 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
tmp[len++] = digits[n];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(type & LEFT)) while (len < size--) *str++ = ' ';
|
|
||||||
for (i = 0; i < len; ++i) *str++ = tmp[i];
|
|
||||||
while (len < size--) *str++ = ' ';
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if HAS_FLOAT
|
|
||||||
|
|
||||||
char *ecvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
|
|
||||||
char *fcvtbuf(double arg, int ndigits, int *decpt, int *sign, char *buf);
|
|
||||||
static void ee_bufcpy(char *d, char *s, int count);
|
|
||||||
|
|
||||||
void ee_bufcpy(char *pd, char *ps, int count) {
|
|
||||||
char *pe=ps+count;
|
|
||||||
while (ps!=pe)
|
|
||||||
*pd++=*ps++;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void parse_float(double value, char *buffer, char fmt, int precision)
|
|
||||||
{
|
|
||||||
int decpt, sign, exp, pos;
|
|
||||||
char *digits = NULL;
|
|
||||||
char cvtbuf[80];
|
|
||||||
int capexp = 0;
|
|
||||||
int magnitude;
|
|
||||||
|
|
||||||
if (fmt == 'G' || fmt == 'E')
|
|
||||||
{
|
|
||||||
capexp = 1;
|
|
||||||
fmt += 'a' - 'A';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fmt == 'g')
|
|
||||||
{
|
|
||||||
digits = ecvtbuf(value, precision, &decpt, &sign, cvtbuf);
|
|
||||||
magnitude = decpt - 1;
|
|
||||||
if (magnitude < -4 || magnitude > precision - 1)
|
|
||||||
{
|
|
||||||
fmt = 'e';
|
|
||||||
precision -= 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
fmt = 'f';
|
|
||||||
precision -= decpt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fmt == 'e')
|
|
||||||
{
|
|
||||||
digits = ecvtbuf(value, precision + 1, &decpt, &sign, cvtbuf);
|
|
||||||
|
|
||||||
if (sign) *buffer++ = '-';
|
|
||||||
*buffer++ = *digits;
|
|
||||||
if (precision > 0) *buffer++ = '.';
|
|
||||||
ee_bufcpy(buffer, digits + 1, precision);
|
|
||||||
buffer += precision;
|
|
||||||
*buffer++ = capexp ? 'E' : 'e';
|
|
||||||
|
|
||||||
if (decpt == 0)
|
|
||||||
{
|
|
||||||
if (value == 0.0)
|
|
||||||
exp = 0;
|
|
||||||
else
|
|
||||||
exp = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
exp = decpt - 1;
|
|
||||||
|
|
||||||
if (exp < 0)
|
|
||||||
{
|
|
||||||
*buffer++ = '-';
|
|
||||||
exp = -exp;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
*buffer++ = '+';
|
|
||||||
|
|
||||||
buffer[2] = (exp % 10) + '0';
|
|
||||||
exp = exp / 10;
|
|
||||||
buffer[1] = (exp % 10) + '0';
|
|
||||||
exp = exp / 10;
|
|
||||||
buffer[0] = (exp % 10) + '0';
|
|
||||||
buffer += 3;
|
|
||||||
}
|
|
||||||
else if (fmt == 'f')
|
|
||||||
{
|
|
||||||
digits = fcvtbuf(value, precision, &decpt, &sign, cvtbuf);
|
|
||||||
if (sign) *buffer++ = '-';
|
|
||||||
if (*digits)
|
|
||||||
{
|
|
||||||
if (decpt <= 0)
|
|
||||||
{
|
|
||||||
*buffer++ = '0';
|
|
||||||
*buffer++ = '.';
|
|
||||||
for (pos = 0; pos < -decpt; pos++) *buffer++ = '0';
|
|
||||||
while (*digits) *buffer++ = *digits++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
pos = 0;
|
|
||||||
while (*digits)
|
|
||||||
{
|
|
||||||
if (pos++ == decpt) *buffer++ = '.';
|
|
||||||
*buffer++ = *digits++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*buffer++ = '0';
|
|
||||||
if (precision > 0)
|
|
||||||
{
|
|
||||||
*buffer++ = '.';
|
|
||||||
for (pos = 0; pos < precision; pos++) *buffer++ = '0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*buffer = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
static void decimal_point(char *buffer)
|
|
||||||
{
|
|
||||||
while (*buffer)
|
|
||||||
{
|
|
||||||
if (*buffer == '.') return;
|
|
||||||
if (*buffer == 'e' || *buffer == 'E') break;
|
|
||||||
buffer++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*buffer)
|
|
||||||
{
|
|
||||||
int n = strnlen(buffer,256);
|
|
||||||
while (n > 0)
|
|
||||||
{
|
|
||||||
buffer[n + 1] = buffer[n];
|
|
||||||
n--;
|
|
||||||
}
|
|
||||||
|
|
||||||
*buffer = '.';
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*buffer++ = '.';
|
|
||||||
*buffer = '\0';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void cropzeros(char *buffer)
|
|
||||||
{
|
|
||||||
char *stop;
|
|
||||||
|
|
||||||
while (*buffer && *buffer != '.') buffer++;
|
|
||||||
if (*buffer++)
|
|
||||||
{
|
|
||||||
while (*buffer && *buffer != 'e' && *buffer != 'E') buffer++;
|
|
||||||
stop = buffer--;
|
|
||||||
while (*buffer == '0') buffer--;
|
|
||||||
if (*buffer == '.') buffer--;
|
|
||||||
while (buffer!=stop)
|
|
||||||
*++buffer=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *flt(char *str, double num, int size, int precision, char fmt, int flags)
|
|
||||||
{
|
|
||||||
char tmp[80];
|
|
||||||
char c, sign;
|
|
||||||
int n, i;
|
|
||||||
|
|
||||||
// Left align means no zero padding
|
|
||||||
if (flags & LEFT) flags &= ~ZEROPAD;
|
|
||||||
|
|
||||||
// Determine padding and sign char
|
|
||||||
c = (flags & ZEROPAD) ? '0' : ' ';
|
|
||||||
sign = 0;
|
|
||||||
if (flags & SIGN)
|
|
||||||
{
|
|
||||||
if (num < 0.0)
|
|
||||||
{
|
|
||||||
sign = '-';
|
|
||||||
num = -num;
|
|
||||||
size--;
|
|
||||||
}
|
|
||||||
else if (flags & PLUS)
|
|
||||||
{
|
|
||||||
sign = '+';
|
|
||||||
size--;
|
|
||||||
}
|
|
||||||
else if (flags & SPACE)
|
|
||||||
{
|
|
||||||
sign = ' ';
|
|
||||||
size--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Compute the precision value
|
|
||||||
if (precision < 0)
|
|
||||||
precision = 6; // Default precision: 6
|
|
||||||
|
|
||||||
// Convert floating point number to text
|
|
||||||
parse_float(num, tmp, fmt, precision);
|
|
||||||
|
|
||||||
if ((flags & HEX_PREP) && precision == 0) decimal_point(tmp);
|
|
||||||
if (fmt == 'g' && !(flags & HEX_PREP)) cropzeros(tmp);
|
|
||||||
|
|
||||||
n = strnlen(tmp,256);
|
|
||||||
|
|
||||||
// Output number with alignment and padding
|
|
||||||
size -= n;
|
|
||||||
if (!(flags & (ZEROPAD | LEFT))) while (size-- > 0) *str++ = ' ';
|
|
||||||
if (sign) *str++ = sign;
|
|
||||||
if (!(flags & LEFT)) while (size-- > 0) *str++ = c;
|
|
||||||
for (i = 0; i < n; i++) *str++ = tmp[i];
|
|
||||||
while (size-- > 0) *str++ = ' ';
|
|
||||||
|
|
||||||
return str;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static int ee_vsprintf(char *buf, const char *fmt, va_list args)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
unsigned long num;
|
|
||||||
int i, base;
|
|
||||||
char *str;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
int flags; // Flags to number()
|
|
||||||
|
|
||||||
int field_width; // Width of output field
|
|
||||||
int precision; // Min. # of digits for integers; max number of chars for from string
|
|
||||||
int qualifier; // 'h', 'l', or 'L' for integer fields
|
|
||||||
|
|
||||||
for (str = buf; *fmt; fmt++)
|
|
||||||
{
|
|
||||||
if (*fmt != '%')
|
|
||||||
{
|
|
||||||
*str++ = *fmt;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Process flags
|
|
||||||
flags = 0;
|
|
||||||
repeat:
|
|
||||||
fmt++; // This also skips first '%'
|
|
||||||
switch (*fmt)
|
|
||||||
{
|
|
||||||
case '-': flags |= LEFT; goto repeat;
|
|
||||||
case '+': flags |= PLUS; goto repeat;
|
|
||||||
case ' ': flags |= SPACE; goto repeat;
|
|
||||||
case '#': flags |= HEX_PREP; goto repeat;
|
|
||||||
case '0': flags |= ZEROPAD; goto repeat;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get field width
|
|
||||||
field_width = -1;
|
|
||||||
if (is_digit(*fmt))
|
|
||||||
field_width = skip_atoi(&fmt);
|
|
||||||
else if (*fmt == '*')
|
|
||||||
{
|
|
||||||
fmt++;
|
|
||||||
field_width = va_arg(args, int);
|
|
||||||
if (field_width < 0)
|
|
||||||
{
|
|
||||||
field_width = -field_width;
|
|
||||||
flags |= LEFT;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the precision
|
|
||||||
precision = -1;
|
|
||||||
if (*fmt == '.')
|
|
||||||
{
|
|
||||||
++fmt;
|
|
||||||
if (is_digit(*fmt))
|
|
||||||
precision = skip_atoi(&fmt);
|
|
||||||
else if (*fmt == '*')
|
|
||||||
{
|
|
||||||
++fmt;
|
|
||||||
precision = va_arg(args, int);
|
|
||||||
}
|
|
||||||
if (precision < 0) precision = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the conversion qualifier
|
|
||||||
qualifier = -1;
|
|
||||||
if (*fmt == 'l' || *fmt == 'L')
|
|
||||||
{
|
|
||||||
qualifier = *fmt;
|
|
||||||
fmt++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Default base
|
|
||||||
base = 10;
|
|
||||||
|
|
||||||
switch (*fmt)
|
|
||||||
{
|
|
||||||
case 'c':
|
|
||||||
if (!(flags & LEFT)) while (--field_width > 0) *str++ = ' ';
|
|
||||||
*str++ = (unsigned char) va_arg(args, int);
|
|
||||||
while (--field_width > 0) *str++ = ' ';
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 's':
|
|
||||||
s = va_arg(args, char *);
|
|
||||||
if (!s) s = "<NULL>";
|
|
||||||
len = strnlen(s, precision);
|
|
||||||
if (!(flags & LEFT)) while (len < field_width--) *str++ = ' ';
|
|
||||||
for (i = 0; i < len; ++i) *str++ = *s++;
|
|
||||||
while (len < field_width--) *str++ = ' ';
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'p':
|
|
||||||
if (field_width == -1)
|
|
||||||
{
|
|
||||||
field_width = 2 * sizeof(void *);
|
|
||||||
flags |= ZEROPAD;
|
|
||||||
}
|
|
||||||
str = number(str, (unsigned long) va_arg(args, void *), 16, field_width, precision, flags);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case 'A':
|
|
||||||
flags |= UPPERCASE;
|
|
||||||
|
|
||||||
case 'a':
|
|
||||||
if (qualifier == 'l')
|
|
||||||
str = eaddr(str, va_arg(args, unsigned char *), field_width, precision, flags);
|
|
||||||
else
|
|
||||||
str = iaddr(str, va_arg(args, unsigned char *), field_width, precision, flags);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Integer number formats - set up the flags and "break"
|
|
||||||
case 'o':
|
|
||||||
base = 8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'X':
|
|
||||||
flags |= UPPERCASE;
|
|
||||||
|
|
||||||
case 'x':
|
|
||||||
base = 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'd':
|
|
||||||
case 'i':
|
|
||||||
flags |= SIGN;
|
|
||||||
|
|
||||||
case 'u':
|
|
||||||
break;
|
|
||||||
|
|
||||||
#if HAS_FLOAT
|
|
||||||
|
|
||||||
case 'f':
|
|
||||||
str = flt(str, va_arg(args, double), field_width, precision, *fmt, flags | SIGN);
|
|
||||||
continue;
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
if (*fmt != '%') *str++ = '%';
|
|
||||||
if (*fmt)
|
|
||||||
*str++ = *fmt;
|
|
||||||
else
|
|
||||||
--fmt;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (qualifier == 'l')
|
|
||||||
num = va_arg(args, unsigned long);
|
|
||||||
else if (flags & SIGN)
|
|
||||||
num = va_arg(args, int);
|
|
||||||
else
|
|
||||||
num = va_arg(args, unsigned int);
|
|
||||||
|
|
||||||
str = number(str, num, base, field_width, precision, flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
*str = '\0';
|
|
||||||
return str - buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uart_send_char(char c) {
|
|
||||||
#if defined __K64F__
|
|
||||||
fputc(c, stdout);
|
|
||||||
#else
|
|
||||||
putchar(c);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int ee_printf(const char *fmt, ...)
|
|
||||||
{
|
|
||||||
char buf[256],*p;
|
|
||||||
va_list args;
|
|
||||||
int n=0;
|
|
||||||
|
|
||||||
va_start(args, fmt);
|
|
||||||
ee_vsprintf(buf, fmt, args);
|
|
||||||
va_end(args);
|
|
||||||
p=buf;
|
|
||||||
while (*p) {
|
|
||||||
uart_send_char(*p);
|
|
||||||
n++;
|
|
||||||
p++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
446
zOS/MZ2000/common/Dhrystone/dhry.h
vendored
446
zOS/MZ2000/common/Dhrystone/dhry.h
vendored
@@ -1,446 +0,0 @@
|
|||||||
/*
|
|
||||||
****************************************************************************
|
|
||||||
*
|
|
||||||
* "DHRYSTONE" Benchmark Program
|
|
||||||
* -----------------------------
|
|
||||||
*
|
|
||||||
* Version: C, Version 2.1
|
|
||||||
*
|
|
||||||
* File: dhry.h (part 1 of 3)
|
|
||||||
*
|
|
||||||
* Date: May 25, 1988
|
|
||||||
*
|
|
||||||
* Author: Reinhold P. Weicker
|
|
||||||
* Siemens AG, AUT E 51
|
|
||||||
* Postfach 3220
|
|
||||||
* 8520 Erlangen
|
|
||||||
* Germany (West)
|
|
||||||
* Phone: [+49]-9131-7-20330
|
|
||||||
* (8-17 Central European Time)
|
|
||||||
* Usenet: ..!mcsun!unido!estevax!weicker
|
|
||||||
*
|
|
||||||
* Original Version (in Ada) published in
|
|
||||||
* "Communications of the ACM" vol. 27., no. 10 (Oct. 1984),
|
|
||||||
* pp. 1013 - 1030, together with the statistics
|
|
||||||
* on which the distribution of statements etc. is based.
|
|
||||||
*
|
|
||||||
* In this C version, the following C library functions are used:
|
|
||||||
* - strcpy, strcmp (inside the measurement loop)
|
|
||||||
* - printf, scanf (outside the measurement loop)
|
|
||||||
* In addition, Berkeley UNIX system calls "times ()" or "time ()"
|
|
||||||
* are used for execution time measurement. For measurements
|
|
||||||
* on other systems, these calls have to be changed.
|
|
||||||
*
|
|
||||||
* Collection of Results:
|
|
||||||
* Reinhold Weicker (address see above) and
|
|
||||||
*
|
|
||||||
* Rick Richardson
|
|
||||||
* PC Research. Inc.
|
|
||||||
* 94 Apple Orchard Drive
|
|
||||||
* Tinton Falls, NJ 07724
|
|
||||||
* Phone: (201) 389-8963 (9-17 EST)
|
|
||||||
* Usenet: ...!uunet!pcrat!rick
|
|
||||||
*
|
|
||||||
* Please send results to Rick Richardson and/or Reinhold Weicker.
|
|
||||||
* Complete information should be given on hardware and software used.
|
|
||||||
* Hardware information includes: Machine type, CPU, type and size
|
|
||||||
* of caches; for microprocessors: clock frequency, memory speed
|
|
||||||
* (number of wait states).
|
|
||||||
* Software information includes: Compiler (and runtime library)
|
|
||||||
* manufacturer and version, compilation switches, OS version.
|
|
||||||
* The Operating System version may give an indication about the
|
|
||||||
* compiler; Dhrystone itself performs no OS calls in the measurement loop.
|
|
||||||
*
|
|
||||||
* The complete output generated by the program should be mailed
|
|
||||||
* such that at least some checks for correctness can be made.
|
|
||||||
*
|
|
||||||
***************************************************************************
|
|
||||||
*
|
|
||||||
* History: This version C/2.1 has been made for two reasons:
|
|
||||||
*
|
|
||||||
* 1) There is an obvious need for a common C version of
|
|
||||||
* Dhrystone, since C is at present the most popular system
|
|
||||||
* programming language for the class of processors
|
|
||||||
* (microcomputers, minicomputers) where Dhrystone is used most.
|
|
||||||
* There should be, as far as possible, only one C version of
|
|
||||||
* Dhrystone such that results can be compared without
|
|
||||||
* restrictions. In the past, the C versions distributed
|
|
||||||
* by Rick Richardson (Version 1.1) and by Reinhold Weicker
|
|
||||||
* had small (though not significant) differences.
|
|
||||||
*
|
|
||||||
* 2) As far as it is possible without changes to the Dhrystone
|
|
||||||
* statistics, optimizing compilers should be prevented from
|
|
||||||
* removing significant statements.
|
|
||||||
*
|
|
||||||
* This C version has been developed in cooperation with
|
|
||||||
* Rick Richardson (Tinton Falls, NJ), it incorporates many
|
|
||||||
* ideas from the "Version 1.1" distributed previously by
|
|
||||||
* him over the UNIX network Usenet.
|
|
||||||
* I also thank Chaim Benedelac (National Semiconductor),
|
|
||||||
* David Ditzel (SUN), Earl Killian and John Mashey (MIPS),
|
|
||||||
* Alan Smith and Rafael Saavedra-Barrera (UC at Berkeley)
|
|
||||||
* for their help with comments on earlier versions of the
|
|
||||||
* benchmark.
|
|
||||||
*
|
|
||||||
* Changes: In the initialization part, this version follows mostly
|
|
||||||
* Rick Richardson's version distributed via Usenet, not the
|
|
||||||
* version distributed earlier via floppy disk by Reinhold Weicker.
|
|
||||||
* As a concession to older compilers, names have been made
|
|
||||||
* unique within the first 8 characters.
|
|
||||||
* Inside the measurement loop, this version follows the
|
|
||||||
* version previously distributed by Reinhold Weicker.
|
|
||||||
*
|
|
||||||
* At several places in the benchmark, code has been added,
|
|
||||||
* but within the measurement loop only in branches that
|
|
||||||
* are not executed. The intention is that optimizing compilers
|
|
||||||
* should be prevented from moving code out of the measurement
|
|
||||||
* loop, or from removing code altogether. Since the statements
|
|
||||||
* that are executed within the measurement loop have NOT been
|
|
||||||
* changed, the numbers defining the "Dhrystone distribution"
|
|
||||||
* (distribution of statements, operand types and locality)
|
|
||||||
* still hold. Except for sophisticated optimizing compilers,
|
|
||||||
* execution times for this version should be the same as
|
|
||||||
* for previous versions.
|
|
||||||
*
|
|
||||||
* Since it has proven difficult to subtract the time for the
|
|
||||||
* measurement loop overhead in a correct way, the loop check
|
|
||||||
* has been made a part of the benchmark. This does have
|
|
||||||
* an impact - though a very minor one - on the distribution
|
|
||||||
* statistics which have been updated for this version.
|
|
||||||
*
|
|
||||||
* All changes within the measurement loop are described
|
|
||||||
* and discussed in the companion paper "Rationale for
|
|
||||||
* Dhrystone version 2".
|
|
||||||
*
|
|
||||||
* Because of the self-imposed limitation that the order and
|
|
||||||
* distribution of the executed statements should not be
|
|
||||||
* changed, there are still cases where optimizing compilers
|
|
||||||
* may not generate code for some statements. To a certain
|
|
||||||
* degree, this is unavoidable for small synthetic benchmarks.
|
|
||||||
* Users of the benchmark are advised to check code listings
|
|
||||||
* whether code is generated for all statements of Dhrystone.
|
|
||||||
*
|
|
||||||
* Version 2.1 is identical to version 2.0 distributed via
|
|
||||||
* the UNIX network Usenet in March 1988 except that it corrects
|
|
||||||
* some minor deficiencies that were found by users of version 2.0.
|
|
||||||
* The only change within the measurement loop is that a
|
|
||||||
* non-executed "else" part was added to the "if" statement in
|
|
||||||
* Func_3, and a non-executed "else" part removed from Proc_3.
|
|
||||||
*
|
|
||||||
***************************************************************************
|
|
||||||
*
|
|
||||||
* Defines: The following "Defines" are possible:
|
|
||||||
* -DREG=register (default: Not defined)
|
|
||||||
* As an approximation to what an average C programmer
|
|
||||||
* might do, the "register" storage class is applied
|
|
||||||
* (if enabled by -DREG=register)
|
|
||||||
* - for local variables, if they are used (dynamically)
|
|
||||||
* five or more times
|
|
||||||
* - for parameters if they are used (dynamically)
|
|
||||||
* six or more times
|
|
||||||
* Note that an optimal "register" strategy is
|
|
||||||
* compiler-dependent, and that "register" declarations
|
|
||||||
* do not necessarily lead to faster execution.
|
|
||||||
* -DNOSTRUCTASSIGN (default: Not defined)
|
|
||||||
* Define if the C compiler does not support
|
|
||||||
* assignment of structures.
|
|
||||||
* -DNOENUMS (default: Not defined)
|
|
||||||
* Define if the C compiler does not support
|
|
||||||
* enumeration types.
|
|
||||||
* -DTIMES (default)
|
|
||||||
* -DTIME
|
|
||||||
* The "times" function of UNIX (returning process times)
|
|
||||||
* or the "time" function (returning wallclock time)
|
|
||||||
* is used for measurement.
|
|
||||||
* For single user machines, "time ()" is adequate. For
|
|
||||||
* multi-user machines where you cannot get single-user
|
|
||||||
* access, use the "times ()" function. If you have
|
|
||||||
* neither, use a stopwatch in the dead of night.
|
|
||||||
* "printf"s are provided marking the points "Start Timer"
|
|
||||||
* and "Stop Timer". DO NOT use the UNIX "time(1)"
|
|
||||||
* command, as this will measure the total time to
|
|
||||||
* run this program, which will (erroneously) include
|
|
||||||
* the time to allocate storage (malloc) and to perform
|
|
||||||
* the initialization.
|
|
||||||
* -DHZ=nnn
|
|
||||||
* In Berkeley UNIX, the function "times" returns process
|
|
||||||
* time in 1/HZ seconds, with HZ = 60 for most systems.
|
|
||||||
* CHECK YOUR SYSTEM DESCRIPTION BEFORE YOU JUST APPLY
|
|
||||||
* A VALUE.
|
|
||||||
*
|
|
||||||
***************************************************************************
|
|
||||||
*
|
|
||||||
* Compilation model and measurement (IMPORTANT):
|
|
||||||
*
|
|
||||||
* This C version of Dhrystone consists of three files:
|
|
||||||
* - dhry.h (this file, containing global definitions and comments)
|
|
||||||
* - dhry_1.c (containing the code corresponding to Ada package Pack_1)
|
|
||||||
* - dhry_2.c (containing the code corresponding to Ada package Pack_2)
|
|
||||||
*
|
|
||||||
* The following "ground rules" apply for measurements:
|
|
||||||
* - Separate compilation
|
|
||||||
* - No procedure merging
|
|
||||||
* - Otherwise, compiler optimizations are allowed but should be indicated
|
|
||||||
* - Default results are those without register declarations
|
|
||||||
* See the companion paper "Rationale for Dhrystone Version 2" for a more
|
|
||||||
* detailed discussion of these ground rules.
|
|
||||||
*
|
|
||||||
* For 16-Bit processors (e.g. 80186, 80286), times for all compilation
|
|
||||||
* models ("small", "medium", "large" etc.) should be given if possible,
|
|
||||||
* together with a definition of these models for the compiler system used.
|
|
||||||
*
|
|
||||||
**************************************************************************
|
|
||||||
*
|
|
||||||
* Dhrystone (C version) statistics:
|
|
||||||
*
|
|
||||||
* [Comment from the first distribution, updated for version 2.
|
|
||||||
* Note that because of language differences, the numbers are slightly
|
|
||||||
* different from the Ada version.]
|
|
||||||
*
|
|
||||||
* The following program contains statements of a high level programming
|
|
||||||
* language (here: C) in a distribution considered representative:
|
|
||||||
*
|
|
||||||
* assignments 52 (51.0 %)
|
|
||||||
* control statements 33 (32.4 %)
|
|
||||||
* procedure, function calls 17 (16.7 %)
|
|
||||||
*
|
|
||||||
* 103 statements are dynamically executed. The program is balanced with
|
|
||||||
* respect to the three aspects:
|
|
||||||
*
|
|
||||||
* - statement type
|
|
||||||
* - operand type
|
|
||||||
* - operand locality
|
|
||||||
* operand global, local, parameter, or constant.
|
|
||||||
*
|
|
||||||
* The combination of these three aspects is balanced only approximately.
|
|
||||||
*
|
|
||||||
* 1. Statement Type:
|
|
||||||
* ----------------- number
|
|
||||||
*
|
|
||||||
* V1 = V2 9
|
|
||||||
* (incl. V1 = F(..)
|
|
||||||
* V = Constant 12
|
|
||||||
* Assignment, 7
|
|
||||||
* with array element
|
|
||||||
* Assignment, 6
|
|
||||||
* with record component
|
|
||||||
* --
|
|
||||||
* 34 34
|
|
||||||
*
|
|
||||||
* X = Y +|-|"&&"|"|" Z 5
|
|
||||||
* X = Y +|-|"==" Constant 6
|
|
||||||
* X = X +|- 1 3
|
|
||||||
* X = Y *|/ Z 2
|
|
||||||
* X = Expression, 1
|
|
||||||
* two operators
|
|
||||||
* X = Expression, 1
|
|
||||||
* three operators
|
|
||||||
* --
|
|
||||||
* 18 18
|
|
||||||
*
|
|
||||||
* if .... 14
|
|
||||||
* with "else" 7
|
|
||||||
* without "else" 7
|
|
||||||
* executed 3
|
|
||||||
* not executed 4
|
|
||||||
* for ... 7 | counted every time
|
|
||||||
* while ... 4 | the loop condition
|
|
||||||
* do ... while 1 | is evaluated
|
|
||||||
* switch ... 1
|
|
||||||
* break 1
|
|
||||||
* declaration with 1
|
|
||||||
* initialization
|
|
||||||
* --
|
|
||||||
* 34 34
|
|
||||||
*
|
|
||||||
* P (...) procedure call 11
|
|
||||||
* user procedure 10
|
|
||||||
* library procedure 1
|
|
||||||
* X = F (...)
|
|
||||||
* function call 6
|
|
||||||
* user function 5
|
|
||||||
* library function 1
|
|
||||||
* --
|
|
||||||
* 17 17
|
|
||||||
* ---
|
|
||||||
* 103
|
|
||||||
*
|
|
||||||
* The average number of parameters in procedure or function calls
|
|
||||||
* is 1.82 (not counting the function values as implicit parameters).
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 2. Operators
|
|
||||||
* ------------
|
|
||||||
* number approximate
|
|
||||||
* percentage
|
|
||||||
*
|
|
||||||
* Arithmetic 32 50.8
|
|
||||||
*
|
|
||||||
* + 21 33.3
|
|
||||||
* - 7 11.1
|
|
||||||
* * 3 4.8
|
|
||||||
* / (int div) 1 1.6
|
|
||||||
*
|
|
||||||
* Comparison 27 42.8
|
|
||||||
*
|
|
||||||
* == 9 14.3
|
|
||||||
* /= 4 6.3
|
|
||||||
* > 1 1.6
|
|
||||||
* < 3 4.8
|
|
||||||
* >= 1 1.6
|
|
||||||
* <= 9 14.3
|
|
||||||
*
|
|
||||||
* Logic 4 6.3
|
|
||||||
*
|
|
||||||
* && (AND-THEN) 1 1.6
|
|
||||||
* | (OR) 1 1.6
|
|
||||||
* ! (NOT) 2 3.2
|
|
||||||
*
|
|
||||||
* -- -----
|
|
||||||
* 63 100.1
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 3. Operand Type (counted once per operand reference):
|
|
||||||
* ---------------
|
|
||||||
* number approximate
|
|
||||||
* percentage
|
|
||||||
*
|
|
||||||
* Integer 175 72.3 %
|
|
||||||
* Character 45 18.6 %
|
|
||||||
* Pointer 12 5.0 %
|
|
||||||
* String30 6 2.5 %
|
|
||||||
* Array 2 0.8 %
|
|
||||||
* Record 2 0.8 %
|
|
||||||
* --- -------
|
|
||||||
* 242 100.0 %
|
|
||||||
*
|
|
||||||
* When there is an access path leading to the final operand (e.g. a record
|
|
||||||
* component), only the final data type on the access path is counted.
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* 4. Operand Locality:
|
|
||||||
* -------------------
|
|
||||||
* number approximate
|
|
||||||
* percentage
|
|
||||||
*
|
|
||||||
* local variable 114 47.1 %
|
|
||||||
* global variable 22 9.1 %
|
|
||||||
* parameter 45 18.6 %
|
|
||||||
* value 23 9.5 %
|
|
||||||
* reference 22 9.1 %
|
|
||||||
* function result 6 2.5 %
|
|
||||||
* constant 55 22.7 %
|
|
||||||
* --- -------
|
|
||||||
* 242 100.0 %
|
|
||||||
*
|
|
||||||
*
|
|
||||||
* The program does not compute anything meaningful, but it is syntactically
|
|
||||||
* and semantically correct. All variables have a value assigned to them
|
|
||||||
* before they are used as a source operand.
|
|
||||||
*
|
|
||||||
* There has been no explicit effort to account for the effects of a
|
|
||||||
* cache, or to balance the use of long or short displacements for code or
|
|
||||||
* data.
|
|
||||||
*
|
|
||||||
***************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Compiler and system dependent definitions: */
|
|
||||||
|
|
||||||
#ifndef TIME
|
|
||||||
#define TIMES
|
|
||||||
#endif
|
|
||||||
/* Use times(2) time function unless */
|
|
||||||
/* explicitly defined otherwise */
|
|
||||||
|
|
||||||
#ifdef TIMES
|
|
||||||
#include <sys/types.h>
|
|
||||||
|
|
||||||
#if defined __K64F__
|
|
||||||
#include <sys/times.h> /* for "times" */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define Mic_secs_Per_Second 1000000
|
|
||||||
/* Berkeley UNIX C returns process times in seconds/HZ */
|
|
||||||
|
|
||||||
#ifdef NOSTRUCTASSIGN
|
|
||||||
#define structassign(d, s) memcpy(&(d), &(s), sizeof(d))
|
|
||||||
#else
|
|
||||||
#define structassign(d, s) d = s
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NOENUM
|
|
||||||
#define Ident_1 0
|
|
||||||
#define Ident_2 1
|
|
||||||
#define Ident_3 2
|
|
||||||
#define Ident_4 3
|
|
||||||
#define Ident_5 4
|
|
||||||
typedef int Enumeration;
|
|
||||||
#else
|
|
||||||
typedef enum {Ident_1, Ident_2, Ident_3, Ident_4, Ident_5}
|
|
||||||
Enumeration;
|
|
||||||
#endif
|
|
||||||
/* for boolean and enumeration types in Ada, Pascal */
|
|
||||||
|
|
||||||
/* General definitions: */
|
|
||||||
|
|
||||||
//#include <stdio.h>
|
|
||||||
/* for strcpy, strcmp */
|
|
||||||
|
|
||||||
#define Null 0
|
|
||||||
/* Value of a Null pointer */
|
|
||||||
#define true 1
|
|
||||||
#define false 0
|
|
||||||
|
|
||||||
typedef int One_Thirty;
|
|
||||||
typedef int One_Fifty;
|
|
||||||
typedef char Capital_Letter;
|
|
||||||
typedef int Boolean;
|
|
||||||
typedef char Str_30 [31];
|
|
||||||
typedef int Arr_1_Dim [50];
|
|
||||||
typedef int Arr_2_Dim [50] [50];
|
|
||||||
|
|
||||||
typedef struct record
|
|
||||||
{
|
|
||||||
struct record *Ptr_Comp;
|
|
||||||
Enumeration Discr;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
Enumeration Enum_Comp;
|
|
||||||
int Int_Comp;
|
|
||||||
char Str_Comp [31];
|
|
||||||
} var_1;
|
|
||||||
struct {
|
|
||||||
Enumeration E_Comp_2;
|
|
||||||
char Str_2_Comp [31];
|
|
||||||
} var_2;
|
|
||||||
struct {
|
|
||||||
char Ch_1_Comp;
|
|
||||||
char Ch_2_Comp;
|
|
||||||
} var_3;
|
|
||||||
} variant;
|
|
||||||
} Rec_Type, *Rec_Pointer;
|
|
||||||
|
|
||||||
// Prototypes.
|
|
||||||
int main_dhry();
|
|
||||||
void Proc_1(Rec_Pointer);
|
|
||||||
void Proc_2(One_Fifty *);
|
|
||||||
void Proc_3(Rec_Pointer *);
|
|
||||||
void Proc_4(void);
|
|
||||||
void Proc_5(void);
|
|
||||||
void Proc_6 (Enumeration, Enumeration *);
|
|
||||||
void Proc_7 (One_Fifty, One_Fifty, One_Fifty *);
|
|
||||||
void Proc_8 (Arr_1_Dim, Arr_2_Dim, int, int);
|
|
||||||
Enumeration Func_1 (Capital_Letter, Capital_Letter);
|
|
||||||
Boolean Func_2 (Str_30, Str_30);
|
|
||||||
Boolean Func_3 (Enumeration);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,453 +0,0 @@
|
|||||||
/*
|
|
||||||
****************************************************************************
|
|
||||||
*
|
|
||||||
* "DHRYSTONE" Benchmark Program
|
|
||||||
* -----------------------------
|
|
||||||
*
|
|
||||||
* Version: C, Version 2.1
|
|
||||||
*
|
|
||||||
* File: dhry_1.c (part 2 of 3)
|
|
||||||
*
|
|
||||||
* Date: May 25, 1988
|
|
||||||
*
|
|
||||||
* Author: Reinhold P. Weicker
|
|
||||||
*
|
|
||||||
****************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#if defined __K64F__
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "k64f_soc.h"
|
|
||||||
extern uint32_t milliseconds(void);
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include "dhry.h"
|
|
||||||
|
|
||||||
/* Global Variables: */
|
|
||||||
|
|
||||||
Rec_Pointer Ptr_Glob,
|
|
||||||
Next_Ptr_Glob;
|
|
||||||
int Int_Glob;
|
|
||||||
Boolean Bool_Glob;
|
|
||||||
char Ch_1_Glob,
|
|
||||||
Ch_2_Glob;
|
|
||||||
int Arr_1_Glob [50];
|
|
||||||
int Arr_2_Glob [50] [50];
|
|
||||||
|
|
||||||
/* forward declaration necessary since Enumeration may not simply be int */
|
|
||||||
|
|
||||||
#ifndef REG
|
|
||||||
Boolean Reg = false;
|
|
||||||
#define REG
|
|
||||||
/* REG becomes defined as empty */
|
|
||||||
/* i.e. no register variables */
|
|
||||||
#else
|
|
||||||
Boolean Reg = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* variables for time measurement: */
|
|
||||||
|
|
||||||
#ifdef TIMES
|
|
||||||
struct tms time_info;
|
|
||||||
/* see library function "times" */
|
|
||||||
#define Too_Small_Time 120
|
|
||||||
/* Measurements should last at least about 2 seconds */
|
|
||||||
#endif
|
|
||||||
#ifdef TIME
|
|
||||||
extern long time();
|
|
||||||
/* see library function "time" */
|
|
||||||
#define Too_Small_Time 2
|
|
||||||
/* Measurements should last at least 2 seconds */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
long Begin_Time,
|
|
||||||
End_Time,
|
|
||||||
User_Time;
|
|
||||||
long Microseconds,
|
|
||||||
Dhrystones_Per_Second,
|
|
||||||
Vax_Mips;
|
|
||||||
|
|
||||||
/* end of variables for time measurement */
|
|
||||||
|
|
||||||
int Number_Of_Runs = 50000;
|
|
||||||
|
|
||||||
//long _readMilliseconds()
|
|
||||||
//{
|
|
||||||
// return(TIMER_MILLISECONDS + (TIMER_SECONDS*1000) + (TIMER_MINUTES);
|
|
||||||
//}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define strcpy _strcpy
|
|
||||||
|
|
||||||
_strcpy(char *dst,const char *src)
|
|
||||||
{
|
|
||||||
while(*dst++=*src++);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Rec_Type rec1;
|
|
||||||
Rec_Type rec2;
|
|
||||||
|
|
||||||
|
|
||||||
// Keep anything remotely large off the stack...
|
|
||||||
Str_30 Str_1_Loc;
|
|
||||||
Str_30 Str_2_Loc;
|
|
||||||
|
|
||||||
int main_dhry ()
|
|
||||||
/*****/
|
|
||||||
|
|
||||||
/* main program, corresponds to procedures */
|
|
||||||
/* Main and Proc_0 in the Ada version */
|
|
||||||
{
|
|
||||||
One_Fifty Int_1_Loc;
|
|
||||||
REG One_Fifty Int_2_Loc;
|
|
||||||
One_Fifty Int_3_Loc;
|
|
||||||
REG char Ch_Index;
|
|
||||||
Enumeration Enum_Loc;
|
|
||||||
REG int Run_Index;
|
|
||||||
|
|
||||||
/* Initializations */
|
|
||||||
|
|
||||||
// Next_Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
|
|
||||||
// Ptr_Glob = (Rec_Pointer) malloc (sizeof (Rec_Type));
|
|
||||||
|
|
||||||
Next_Ptr_Glob = &rec1;
|
|
||||||
Ptr_Glob = &rec2;
|
|
||||||
|
|
||||||
Ptr_Glob->Ptr_Comp = Next_Ptr_Glob;
|
|
||||||
Ptr_Glob->Discr = Ident_1;
|
|
||||||
Ptr_Glob->variant.var_1.Enum_Comp = Ident_3;
|
|
||||||
Ptr_Glob->variant.var_1.Int_Comp = 40;
|
|
||||||
strcpy (Ptr_Glob->variant.var_1.Str_Comp,
|
|
||||||
"DHRYSTONE PROGRAM, SOME STRING");
|
|
||||||
strcpy (Str_1_Loc, "DHRYSTONE PROGRAM, 1'ST STRING");
|
|
||||||
|
|
||||||
Arr_2_Glob [8][7] = 10;
|
|
||||||
/* Was missing in published program. Without this statement, */
|
|
||||||
/* Arr_2_Glob [8][7] would have an undefined value. */
|
|
||||||
/* Warning: With 16-Bit processors and Number_Of_Runs > 32000, */
|
|
||||||
/* overflow may occur for this array element. */
|
|
||||||
printf ("Dhrystone Benchmark, Version 2.1 (Language: C)\r\n");
|
|
||||||
printf ("\r\n");
|
|
||||||
if (Reg)
|
|
||||||
{
|
|
||||||
printf ("Program compiled with 'register' attribute\r\n");
|
|
||||||
printf ("\r\n");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf ("Program compiled without 'register' attribute\r\n");
|
|
||||||
printf ("\r\n");
|
|
||||||
}
|
|
||||||
//Number_Of_Runs;
|
|
||||||
|
|
||||||
printf ("Execution starts, %d runs through Dhrystone\r\n", Number_Of_Runs);
|
|
||||||
|
|
||||||
/***************/
|
|
||||||
/* Start timer */
|
|
||||||
/***************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#ifdef TIMES
|
|
||||||
times (&time_info);
|
|
||||||
Begin_Time = (long) time_info.tms_utime;
|
|
||||||
#endif
|
|
||||||
#ifdef TIME
|
|
||||||
Begin_Time = time ( (long *) 0);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
//Begin_Time = _readMilliseconds();
|
|
||||||
#if defined __ZPU__
|
|
||||||
TIMER_MILLISECONDS_UP = 0;
|
|
||||||
Begin_Time = 0;
|
|
||||||
#elif defined(__K64F__) && defined(__APP__)
|
|
||||||
Begin_Time = milliseconds();
|
|
||||||
#elif defined(__K64F__) && (defined(__ZPUTA__) || defined(__ZOS__))
|
|
||||||
uint32_t millis(void);
|
|
||||||
Begin_Time = millis();
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__ or __K64F__"
|
|
||||||
#endif
|
|
||||||
printf("Begin time : %08ld\n", Begin_Time);
|
|
||||||
#endif
|
|
||||||
for (Run_Index = 1; Run_Index <= Number_Of_Runs; ++Run_Index)
|
|
||||||
{
|
|
||||||
Proc_5();
|
|
||||||
Proc_4();
|
|
||||||
/* Ch_1_Glob == 'A', Ch_2_Glob == 'B', Bool_Glob == true */
|
|
||||||
Int_1_Loc = 2;
|
|
||||||
Int_2_Loc = 3;
|
|
||||||
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 2'ND STRING");
|
|
||||||
Enum_Loc = Ident_2;
|
|
||||||
Bool_Glob = ! Func_2 (Str_1_Loc, Str_2_Loc);
|
|
||||||
/* Bool_Glob == 1 */
|
|
||||||
while (Int_1_Loc < Int_2_Loc) /* loop body executed once */
|
|
||||||
{
|
|
||||||
Int_3_Loc = 5 * Int_1_Loc - Int_2_Loc;
|
|
||||||
/* Int_3_Loc == 7 */
|
|
||||||
Proc_7 (Int_1_Loc, Int_2_Loc, &Int_3_Loc);
|
|
||||||
/* Int_3_Loc == 7 */
|
|
||||||
Int_1_Loc += 1;
|
|
||||||
} /* while */
|
|
||||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
|
||||||
Proc_8 (Arr_1_Glob, Arr_2_Glob, Int_1_Loc, Int_3_Loc);
|
|
||||||
/* Int_Glob == 5 */
|
|
||||||
Proc_1 (Ptr_Glob);
|
|
||||||
for (Ch_Index = 'A'; Ch_Index <= Ch_2_Glob; ++Ch_Index)
|
|
||||||
/* loop body executed twice */
|
|
||||||
{
|
|
||||||
if (Enum_Loc == Func_1 (Ch_Index, 'C'))
|
|
||||||
/* then, not executed */
|
|
||||||
{
|
|
||||||
Proc_6 (Ident_1, &Enum_Loc);
|
|
||||||
strcpy (Str_2_Loc, "DHRYSTONE PROGRAM, 3'RD STRING");
|
|
||||||
Int_2_Loc = Run_Index;
|
|
||||||
Int_Glob = Run_Index;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Int_1_Loc == 3, Int_2_Loc == 3, Int_3_Loc == 7 */
|
|
||||||
Int_2_Loc = Int_2_Loc * Int_1_Loc;
|
|
||||||
Int_1_Loc = Int_2_Loc / Int_3_Loc;
|
|
||||||
Int_2_Loc = 7 * (Int_2_Loc - Int_3_Loc) - Int_1_Loc;
|
|
||||||
/* Int_1_Loc == 1, Int_2_Loc == 13, Int_3_Loc == 7 */
|
|
||||||
Proc_2 (&Int_1_Loc);
|
|
||||||
/* Int_1_Loc == 5 */
|
|
||||||
|
|
||||||
} /* loop "for Run_Index" */
|
|
||||||
|
|
||||||
/**************/
|
|
||||||
/* Stop timer */
|
|
||||||
/**************/
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#ifdef TIMES
|
|
||||||
times (&time_info);
|
|
||||||
End_Time = (long) time_info.tms_utime;
|
|
||||||
#endif
|
|
||||||
#ifdef TIME
|
|
||||||
End_Time = time ( (long *) 0);
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
//End_Time = _readMilliseconds();
|
|
||||||
#if defined __ZPU__
|
|
||||||
End_Time = TIMER_MILLISECONDS_UP;
|
|
||||||
#elif defined(__K64F__) && defined(__APP__)
|
|
||||||
End_Time = milliseconds();
|
|
||||||
#elif defined(__K64F__) && (defined(__ZPUTA__) || defined(__ZOS__))
|
|
||||||
End_Time = millis();
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__ or __K64F__"
|
|
||||||
#endif
|
|
||||||
printf("End time : %08ld\n", End_Time);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
printf ("Execution ends\r\n");
|
|
||||||
printf ("\r\n");
|
|
||||||
printf ("Final values of the variables used in the benchmark:\r\n");
|
|
||||||
printf ("\r\n");
|
|
||||||
printf ("Int_Glob: %d\r\n", Int_Glob);
|
|
||||||
printf (" should be: %d\r\n", 5);
|
|
||||||
printf ("Bool_Glob: %d\r\n", Bool_Glob);
|
|
||||||
printf (" should be: %d\r\n", 1);
|
|
||||||
printf ("Ch_1_Glob: %c\r\n", Ch_1_Glob);
|
|
||||||
printf (" should be: %c\r\n", 'A');
|
|
||||||
printf ("Ch_2_Glob: %c\r\n", Ch_2_Glob);
|
|
||||||
printf (" should be: %c\r\n", 'B');
|
|
||||||
printf ("Arr_1_Glob[8]: %d\r\n", Arr_1_Glob[8]);
|
|
||||||
printf (" should be: %d\r\n", 7);
|
|
||||||
printf ("Arr_2_Glob[8][7]: %d\r\n", Arr_2_Glob[8][7]);
|
|
||||||
printf (" should be: Number_Of_Runs + 10\r\n");
|
|
||||||
printf ("Ptr_Glob->\r\n");
|
|
||||||
printf (" Ptr_Comp: %d\r\n", (int) Ptr_Glob->Ptr_Comp);
|
|
||||||
printf (" should be: (implementation-dependent)\r\n");
|
|
||||||
printf (" Discr: %d\r\n", Ptr_Glob->Discr);
|
|
||||||
printf (" should be: %d\r\n", 0);
|
|
||||||
printf (" Enum_Comp: %d\r\n", Ptr_Glob->variant.var_1.Enum_Comp);
|
|
||||||
printf (" should be: %d\r\n", 2);
|
|
||||||
printf (" Int_Comp: %d\r\n", Ptr_Glob->variant.var_1.Int_Comp);
|
|
||||||
printf (" should be: %d\r\n", 17);
|
|
||||||
printf (" Str_Comp: %s\r\n", Ptr_Glob->variant.var_1.Str_Comp);
|
|
||||||
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\r\n");
|
|
||||||
printf ("Next_Ptr_Glob->\r\n");
|
|
||||||
printf (" Ptr_Comp: %d\r\n", (int) Next_Ptr_Glob->Ptr_Comp);
|
|
||||||
printf (" should be: (implementation-dependent), same as above\r\n");
|
|
||||||
printf (" Discr: %d\r\n", Next_Ptr_Glob->Discr);
|
|
||||||
printf (" should be: %d\r\n", 0);
|
|
||||||
printf (" Enum_Comp: %d\r\n", Next_Ptr_Glob->variant.var_1.Enum_Comp);
|
|
||||||
printf (" should be: %d\r\n", 1);
|
|
||||||
printf (" Int_Comp: %d\r\n", Next_Ptr_Glob->variant.var_1.Int_Comp);
|
|
||||||
printf (" should be: %d\r\n", 18);
|
|
||||||
printf (" Str_Comp: %s\r\n",
|
|
||||||
Next_Ptr_Glob->variant.var_1.Str_Comp);
|
|
||||||
printf (" should be: DHRYSTONE PROGRAM, SOME STRING\r\n");
|
|
||||||
printf ("Int_1_Loc: %d\r\n", Int_1_Loc);
|
|
||||||
printf (" should be: %d\r\n", 5);
|
|
||||||
printf ("Int_2_Loc: %d\r\n", Int_2_Loc);
|
|
||||||
printf (" should be: %d\r\n", 13);
|
|
||||||
printf ("Int_3_Loc: %d\r\n", Int_3_Loc);
|
|
||||||
printf (" should be: %d\r\n", 7);
|
|
||||||
printf ("Enum_Loc: %d\r\n", Enum_Loc);
|
|
||||||
printf (" should be: %d\r\n", 1);
|
|
||||||
printf ("Str_1_Loc: %s\r\n", Str_1_Loc);
|
|
||||||
printf (" should be: DHRYSTONE PROGRAM, 1'ST STRING\r\n");
|
|
||||||
printf ("Str_2_Loc: %s\r\n", Str_2_Loc);
|
|
||||||
printf (" should be: DHRYSTONE PROGRAM, 2'ND STRING\r\n");
|
|
||||||
printf ("\r\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
User_Time = End_Time - Begin_Time;
|
|
||||||
printf ("User time : %d\r\n", (int)User_Time);
|
|
||||||
|
|
||||||
if (User_Time < Too_Small_Time)
|
|
||||||
{
|
|
||||||
printf ("Measured time too small to obtain meaningful results\r\n");
|
|
||||||
printf ("Please increase number of runs\r\n");
|
|
||||||
printf ("\r\n");
|
|
||||||
}
|
|
||||||
/* else */
|
|
||||||
{
|
|
||||||
#if 0
|
|
||||||
#ifdef TIME
|
|
||||||
Microseconds = (User_Time * Mic_secs_Per_Second )
|
|
||||||
/ Number_Of_Runs;
|
|
||||||
Dhrystones_Per_Second = Number_Of_Runs / User_Time;
|
|
||||||
Vax_Mips = (Number_Of_Runs*1000) / (1757*User_Time);
|
|
||||||
#else
|
|
||||||
Microseconds = (float) User_Time * Mic_secs_Per_Second
|
|
||||||
/ ((float) HZ * ((float) Number_Of_Runs));
|
|
||||||
Dhrystones_Per_Second = ((float) HZ * (float) Number_Of_Runs)
|
|
||||||
/ (float) User_Time;
|
|
||||||
Vax_Mips = Dhrystones_Per_Second / 1757.0;
|
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
Microseconds = (1000*User_Time) / Number_Of_Runs;
|
|
||||||
Dhrystones_Per_Second = (Number_Of_Runs*1000) / User_Time;
|
|
||||||
Vax_Mips = (Number_Of_Runs*569) / User_Time;
|
|
||||||
#endif
|
|
||||||
printf ("Microseconds for one run through Dhrystone: ");
|
|
||||||
printf ("%ld \r\n", (int32_t)Microseconds);
|
|
||||||
printf ("Dhrystones per Second: ");
|
|
||||||
printf ("%ld \r\n", (int32_t)Dhrystones_Per_Second);
|
|
||||||
printf ("VAX MIPS rating * 1000 = %d \r\n",(int)Vax_Mips);
|
|
||||||
printf ("\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Proc_1 (Ptr_Val_Par)
|
|
||||||
/******************/
|
|
||||||
|
|
||||||
REG Rec_Pointer Ptr_Val_Par;
|
|
||||||
/* executed once */
|
|
||||||
{
|
|
||||||
REG Rec_Pointer Next_Record = Ptr_Val_Par->Ptr_Comp;
|
|
||||||
/* == Ptr_Glob_Next */
|
|
||||||
/* Local variable, initialized with Ptr_Val_Par->Ptr_Comp, */
|
|
||||||
/* corresponds to "rename" in Ada, "with" in Pascal */
|
|
||||||
|
|
||||||
structassign (*Ptr_Val_Par->Ptr_Comp, *Ptr_Glob);
|
|
||||||
Ptr_Val_Par->variant.var_1.Int_Comp = 5;
|
|
||||||
Next_Record->variant.var_1.Int_Comp
|
|
||||||
= Ptr_Val_Par->variant.var_1.Int_Comp;
|
|
||||||
Next_Record->Ptr_Comp = Ptr_Val_Par->Ptr_Comp;
|
|
||||||
Proc_3 (&Next_Record->Ptr_Comp);
|
|
||||||
/* Ptr_Val_Par->Ptr_Comp->Ptr_Comp
|
|
||||||
== Ptr_Glob->Ptr_Comp */
|
|
||||||
if (Next_Record->Discr == Ident_1)
|
|
||||||
/* then, executed */
|
|
||||||
{
|
|
||||||
Next_Record->variant.var_1.Int_Comp = 6;
|
|
||||||
Proc_6 (Ptr_Val_Par->variant.var_1.Enum_Comp,
|
|
||||||
&Next_Record->variant.var_1.Enum_Comp);
|
|
||||||
Next_Record->Ptr_Comp = Ptr_Glob->Ptr_Comp;
|
|
||||||
Proc_7 (Next_Record->variant.var_1.Int_Comp, 10,
|
|
||||||
&Next_Record->variant.var_1.Int_Comp);
|
|
||||||
}
|
|
||||||
else /* not executed */
|
|
||||||
structassign (*Ptr_Val_Par, *Ptr_Val_Par->Ptr_Comp);
|
|
||||||
} /* Proc_1 */
|
|
||||||
|
|
||||||
|
|
||||||
void Proc_2 (Int_Par_Ref)
|
|
||||||
/******************/
|
|
||||||
/* executed once */
|
|
||||||
/* *Int_Par_Ref == 1, becomes 4 */
|
|
||||||
|
|
||||||
One_Fifty *Int_Par_Ref;
|
|
||||||
{
|
|
||||||
One_Fifty Int_Loc;
|
|
||||||
Enumeration Enum_Loc;
|
|
||||||
|
|
||||||
Int_Loc = *Int_Par_Ref + 10;
|
|
||||||
do /* executed once */
|
|
||||||
if (Ch_1_Glob == 'A')
|
|
||||||
/* then, executed */
|
|
||||||
{
|
|
||||||
Int_Loc -= 1;
|
|
||||||
*Int_Par_Ref = Int_Loc - Int_Glob;
|
|
||||||
Enum_Loc = Ident_1;
|
|
||||||
} /* if */
|
|
||||||
while (Enum_Loc != Ident_1); /* true */
|
|
||||||
} /* Proc_2 */
|
|
||||||
|
|
||||||
|
|
||||||
void Proc_3 (Ptr_Ref_Par)
|
|
||||||
/******************/
|
|
||||||
/* executed once */
|
|
||||||
/* Ptr_Ref_Par becomes Ptr_Glob */
|
|
||||||
|
|
||||||
Rec_Pointer *Ptr_Ref_Par;
|
|
||||||
|
|
||||||
{
|
|
||||||
if (Ptr_Glob != Null)
|
|
||||||
/* then, executed */
|
|
||||||
*Ptr_Ref_Par = Ptr_Glob->Ptr_Comp;
|
|
||||||
Proc_7 (10, Int_Glob, &Ptr_Glob->variant.var_1.Int_Comp);
|
|
||||||
} /* Proc_3 */
|
|
||||||
|
|
||||||
|
|
||||||
void Proc_4 () /* without parameters */
|
|
||||||
/*******/
|
|
||||||
/* executed once */
|
|
||||||
{
|
|
||||||
Boolean Bool_Loc;
|
|
||||||
|
|
||||||
Bool_Loc = Ch_1_Glob == 'A';
|
|
||||||
Bool_Glob = Bool_Loc | Bool_Glob;
|
|
||||||
Ch_2_Glob = 'B';
|
|
||||||
} /* Proc_4 */
|
|
||||||
|
|
||||||
|
|
||||||
void Proc_5 () /* without parameters */
|
|
||||||
/*******/
|
|
||||||
/* executed once */
|
|
||||||
{
|
|
||||||
Ch_1_Glob = 'A';
|
|
||||||
Bool_Glob = false;
|
|
||||||
} /* Proc_5 */
|
|
||||||
|
|
||||||
|
|
||||||
/* Procedure for the assignment of structures, */
|
|
||||||
/* if the C compiler doesn't support this feature */
|
|
||||||
#ifdef NOSTRUCTASSIGN
|
|
||||||
memcpy (d, s, l)
|
|
||||||
register char *d;
|
|
||||||
register char *s;
|
|
||||||
register int l;
|
|
||||||
{
|
|
||||||
while (l--) *d++ = *s++;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,222 +0,0 @@
|
|||||||
/*
|
|
||||||
****************************************************************************
|
|
||||||
*
|
|
||||||
* "DHRYSTONE" Benchmark Program
|
|
||||||
* -----------------------------
|
|
||||||
*
|
|
||||||
* Version: C, Version 2.1
|
|
||||||
*
|
|
||||||
* File: dhry_2.c (part 3 of 3)
|
|
||||||
*
|
|
||||||
* Date: May 25, 1988
|
|
||||||
*
|
|
||||||
* Author: Reinhold P. Weicker
|
|
||||||
*
|
|
||||||
****************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#if defined __K64F__
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "k64f_soc.h"
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
#endif
|
|
||||||
#include <string.h>
|
|
||||||
#include "dhry.h"
|
|
||||||
|
|
||||||
#ifndef REG
|
|
||||||
#define REG
|
|
||||||
/* REG becomes defined as empty */
|
|
||||||
/* i.e. no register variables */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern int Int_Glob;
|
|
||||||
extern char Ch_1_Glob;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
#define strcmp _strcmp
|
|
||||||
|
|
||||||
int _strcmp(const char *s1,const char *s2)
|
|
||||||
{
|
|
||||||
char t,u;
|
|
||||||
while(1)
|
|
||||||
{
|
|
||||||
t=*s1++;
|
|
||||||
u=*s2++;
|
|
||||||
if(t>u)
|
|
||||||
return(1);
|
|
||||||
if(t<u)
|
|
||||||
return(-1);
|
|
||||||
if(!t)
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void Proc_6 (Enum_Val_Par, Enum_Ref_Par)
|
|
||||||
/*********************************/
|
|
||||||
/* executed once */
|
|
||||||
/* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */
|
|
||||||
|
|
||||||
Enumeration Enum_Val_Par;
|
|
||||||
Enumeration *Enum_Ref_Par;
|
|
||||||
{
|
|
||||||
*Enum_Ref_Par = Enum_Val_Par;
|
|
||||||
if (! Func_3 (Enum_Val_Par))
|
|
||||||
/* then, not executed */
|
|
||||||
*Enum_Ref_Par = Ident_4;
|
|
||||||
switch (Enum_Val_Par)
|
|
||||||
{
|
|
||||||
case Ident_1:
|
|
||||||
*Enum_Ref_Par = Ident_1;
|
|
||||||
break;
|
|
||||||
case Ident_2:
|
|
||||||
if (Int_Glob > 100)
|
|
||||||
/* then */
|
|
||||||
*Enum_Ref_Par = Ident_1;
|
|
||||||
else *Enum_Ref_Par = Ident_4;
|
|
||||||
break;
|
|
||||||
case Ident_3: /* executed */
|
|
||||||
*Enum_Ref_Par = Ident_2;
|
|
||||||
break;
|
|
||||||
case Ident_4: break;
|
|
||||||
case Ident_5:
|
|
||||||
*Enum_Ref_Par = Ident_3;
|
|
||||||
break;
|
|
||||||
} /* switch */
|
|
||||||
} /* Proc_6 */
|
|
||||||
|
|
||||||
|
|
||||||
void Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref)
|
|
||||||
/**********************************************/
|
|
||||||
/* executed three times */
|
|
||||||
/* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */
|
|
||||||
/* Int_Par_Ref becomes 7 */
|
|
||||||
/* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */
|
|
||||||
/* Int_Par_Ref becomes 17 */
|
|
||||||
/* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */
|
|
||||||
/* Int_Par_Ref becomes 18 */
|
|
||||||
One_Fifty Int_1_Par_Val;
|
|
||||||
One_Fifty Int_2_Par_Val;
|
|
||||||
One_Fifty *Int_Par_Ref;
|
|
||||||
{
|
|
||||||
One_Fifty Int_Loc;
|
|
||||||
|
|
||||||
Int_Loc = Int_1_Par_Val + 2;
|
|
||||||
*Int_Par_Ref = Int_2_Par_Val + Int_Loc;
|
|
||||||
} /* Proc_7 */
|
|
||||||
|
|
||||||
|
|
||||||
void Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val)
|
|
||||||
/*********************************************************************/
|
|
||||||
/* executed once */
|
|
||||||
/* Int_Par_Val_1 == 3 */
|
|
||||||
/* Int_Par_Val_2 == 7 */
|
|
||||||
Arr_1_Dim Arr_1_Par_Ref;
|
|
||||||
Arr_2_Dim Arr_2_Par_Ref;
|
|
||||||
int Int_1_Par_Val;
|
|
||||||
int Int_2_Par_Val;
|
|
||||||
{
|
|
||||||
REG One_Fifty Int_Index;
|
|
||||||
REG One_Fifty Int_Loc;
|
|
||||||
|
|
||||||
Int_Loc = Int_1_Par_Val + 5;
|
|
||||||
Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val;
|
|
||||||
Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc];
|
|
||||||
Arr_1_Par_Ref [Int_Loc+30] = Int_Loc;
|
|
||||||
for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index)
|
|
||||||
Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc;
|
|
||||||
Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1;
|
|
||||||
Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc];
|
|
||||||
Int_Glob = 5;
|
|
||||||
} /* Proc_8 */
|
|
||||||
|
|
||||||
|
|
||||||
Enumeration Func_1 (Ch_1_Par_Val, Ch_2_Par_Val)
|
|
||||||
/*************************************************/
|
|
||||||
/* executed three times */
|
|
||||||
/* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */
|
|
||||||
/* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */
|
|
||||||
/* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */
|
|
||||||
|
|
||||||
Capital_Letter Ch_1_Par_Val;
|
|
||||||
Capital_Letter Ch_2_Par_Val;
|
|
||||||
{
|
|
||||||
Capital_Letter Ch_1_Loc;
|
|
||||||
Capital_Letter Ch_2_Loc;
|
|
||||||
|
|
||||||
Ch_1_Loc = Ch_1_Par_Val;
|
|
||||||
Ch_2_Loc = Ch_1_Loc;
|
|
||||||
if (Ch_2_Loc != Ch_2_Par_Val)
|
|
||||||
/* then, executed */
|
|
||||||
return (Ident_1);
|
|
||||||
else /* not executed */
|
|
||||||
{
|
|
||||||
Ch_1_Glob = Ch_1_Loc;
|
|
||||||
return (Ident_2);
|
|
||||||
}
|
|
||||||
} /* Func_1 */
|
|
||||||
|
|
||||||
|
|
||||||
Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref)
|
|
||||||
/*************************************************/
|
|
||||||
/* executed once */
|
|
||||||
/* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */
|
|
||||||
/* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */
|
|
||||||
|
|
||||||
Str_30 Str_1_Par_Ref;
|
|
||||||
Str_30 Str_2_Par_Ref;
|
|
||||||
{
|
|
||||||
REG One_Thirty Int_Loc;
|
|
||||||
Capital_Letter Ch_Loc;
|
|
||||||
|
|
||||||
Int_Loc = 2;
|
|
||||||
while (Int_Loc <= 2) /* loop body executed once */
|
|
||||||
if (Func_1 (Str_1_Par_Ref[Int_Loc],
|
|
||||||
Str_2_Par_Ref[Int_Loc+1]) == Ident_1)
|
|
||||||
/* then, executed */
|
|
||||||
{
|
|
||||||
Ch_Loc = 'A';
|
|
||||||
Int_Loc += 1;
|
|
||||||
} /* if, while */
|
|
||||||
if (Ch_Loc >= 'W' && Ch_Loc < 'Z')
|
|
||||||
/* then, not executed */
|
|
||||||
Int_Loc = 7;
|
|
||||||
if (Ch_Loc == 'R')
|
|
||||||
/* then, not executed */
|
|
||||||
return (true);
|
|
||||||
else /* executed */
|
|
||||||
{
|
|
||||||
if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0)
|
|
||||||
/* then, not executed */
|
|
||||||
{
|
|
||||||
Int_Loc += 7;
|
|
||||||
Int_Glob = Int_Loc;
|
|
||||||
return (true);
|
|
||||||
}
|
|
||||||
else /* executed */
|
|
||||||
return (false);
|
|
||||||
} /* if Ch_Loc */
|
|
||||||
} /* Func_2 */
|
|
||||||
|
|
||||||
|
|
||||||
Boolean Func_3 (Enum_Par_Val)
|
|
||||||
/***************************/
|
|
||||||
/* executed once */
|
|
||||||
/* Enum_Par_Val == Ident_3 */
|
|
||||||
Enumeration Enum_Par_Val;
|
|
||||||
{
|
|
||||||
Enumeration Enum_Loc;
|
|
||||||
|
|
||||||
Enum_Loc = Enum_Par_Val;
|
|
||||||
if (Enum_Loc == Ident_3)
|
|
||||||
/* then, executed */
|
|
||||||
return (true);
|
|
||||||
else /* not executed */
|
|
||||||
return (false);
|
|
||||||
} /* Func_3 */
|
|
||||||
|
|
||||||
@@ -1,229 +0,0 @@
|
|||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Low level disk I/O module skeleton for FatFs (C)ChaN, 2016 */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* If a working storage control module is available, it should be */
|
|
||||||
/* attached to the FatFs via a glue function rather than modifying it. */
|
|
||||||
/* This is an example of glue functions to attach various exsisting */
|
|
||||||
/* storage control modules to the FatFs module with a defined API. */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "ff.h" /* Obtains integer types */
|
|
||||||
#include "diskio.h" /* Declarations of disk functions */
|
|
||||||
|
|
||||||
/* Definitions of physical drive number for each drive */
|
|
||||||
#define DEV_RAM 0 /* Example: Map Ramdisk to physical drive 0 */
|
|
||||||
#define DEV_MMC 1 /* Example: Map MMC/SD card to physical drive 1 */
|
|
||||||
#define DEV_USB 2 /* Example: Map USB MSD to physical drive 2 */
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Get Drive Status */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DSTATUS disk_status (
|
|
||||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DSTATUS stat;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case DEV_RAM :
|
|
||||||
result = RAM_disk_status();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
case DEV_MMC :
|
|
||||||
result = MMC_disk_status();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
case DEV_USB :
|
|
||||||
result = USB_disk_status();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
}
|
|
||||||
return STA_NOINIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Inidialize a Drive */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DSTATUS disk_initialize (
|
|
||||||
BYTE pdrv /* Physical drive nmuber to identify the drive */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DSTATUS stat;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case DEV_RAM :
|
|
||||||
result = RAM_disk_initialize();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
case DEV_MMC :
|
|
||||||
result = MMC_disk_initialize();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
|
|
||||||
case DEV_USB :
|
|
||||||
result = USB_disk_initialize();
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
}
|
|
||||||
return STA_NOINIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DRESULT disk_read (
|
|
||||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
|
||||||
BYTE *buff, /* Data buffer to store read data */
|
|
||||||
DWORD sector, /* Start sector in LBA */
|
|
||||||
UINT count /* Number of sectors to read */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DRESULT res;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case DEV_RAM :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = RAM_disk_read(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case DEV_MMC :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = MMC_disk_read(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case DEV_USB :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = USB_disk_read(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RES_PARERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Write Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if FF_FS_READONLY == 0
|
|
||||||
|
|
||||||
DRESULT disk_write (
|
|
||||||
BYTE pdrv, /* Physical drive nmuber to identify the drive */
|
|
||||||
const BYTE *buff, /* Data to be written */
|
|
||||||
DWORD sector, /* Start sector in LBA */
|
|
||||||
UINT count /* Number of sectors to write */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DRESULT res;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case DEV_RAM :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = RAM_disk_write(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case DEV_MMC :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = MMC_disk_write(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case DEV_USB :
|
|
||||||
// translate the arguments here
|
|
||||||
|
|
||||||
result = USB_disk_write(buff, sector, count);
|
|
||||||
|
|
||||||
// translate the reslut code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RES_PARERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Miscellaneous Functions */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DRESULT disk_ioctl (
|
|
||||||
BYTE pdrv, /* Physical drive nmuber (0..) */
|
|
||||||
BYTE cmd, /* Control code */
|
|
||||||
void *buff /* Buffer to send/receive control data */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DRESULT res;
|
|
||||||
int result;
|
|
||||||
|
|
||||||
switch (pdrv) {
|
|
||||||
case DEV_RAM :
|
|
||||||
|
|
||||||
// Process of the command for the RAM drive
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case DEV_MMC :
|
|
||||||
|
|
||||||
// Process of the command for the MMC/SD card
|
|
||||||
|
|
||||||
return res;
|
|
||||||
|
|
||||||
case DEV_USB :
|
|
||||||
|
|
||||||
// Process of the command the USB drive
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
return RES_PARERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
89
zOS/MZ2000/common/FatFS/diskio.h
vendored
89
zOS/MZ2000/common/FatFS/diskio.h
vendored
@@ -1,89 +0,0 @@
|
|||||||
/*-----------------------------------------------------------------------
|
|
||||||
/ Low level disk interface modlue include file (C)ChaN, 2014
|
|
||||||
/-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "ff.h"
|
|
||||||
#ifndef _DISKIO_DEFINED
|
|
||||||
#define _DISKIO_DEFINED
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Status of Disk Functions */
|
|
||||||
typedef BYTE DSTATUS;
|
|
||||||
|
|
||||||
/* Results of Disk Functions */
|
|
||||||
typedef enum {
|
|
||||||
RES_OK = 0, /* 0: Successful */
|
|
||||||
RES_ERROR, /* 1: R/W Error */
|
|
||||||
RES_WRPRT, /* 2: Write Protected */
|
|
||||||
RES_NOTRDY, /* 3: Not Ready */
|
|
||||||
RES_PARERR /* 4: Invalid Parameter */
|
|
||||||
} DRESULT;
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------*/
|
|
||||||
/* Prototypes for disk control functions */
|
|
||||||
|
|
||||||
|
|
||||||
DSTATUS disk_initialize (BYTE pdrv, BYTE cardtype);
|
|
||||||
DSTATUS disk_status (BYTE pdrv);
|
|
||||||
DRESULT disk_read (BYTE pdrv, BYTE* buff, DWORD sector, UINT count);
|
|
||||||
DRESULT disk_write (BYTE pdrv, const BYTE* buff, DWORD sector, UINT count);
|
|
||||||
DRESULT disk_ioctl (BYTE pdrv, BYTE cmd, void* buff);
|
|
||||||
|
|
||||||
|
|
||||||
/* Disk Status Bits (DSTATUS) */
|
|
||||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
|
||||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
|
||||||
#define STA_PROTECT 0x04 /* Write protected */
|
|
||||||
|
|
||||||
|
|
||||||
/* Command code for disk_ioctrl fucntion */
|
|
||||||
|
|
||||||
/* Generic command (Used by FatFs) */
|
|
||||||
#define CTRL_SYNC 0 /* Complete pending write process (needed at _FS_READONLY == 0) */
|
|
||||||
#define GET_SECTOR_COUNT 1 /* Get media size (needed at _USE_MKFS == 1) */
|
|
||||||
#define GET_SECTOR_SIZE 2 /* Get sector size (needed at _MAX_SS != _MIN_SS) */
|
|
||||||
#define GET_BLOCK_SIZE 3 /* Get erase block size (needed at _USE_MKFS == 1) */
|
|
||||||
#define CTRL_TRIM 4 /* Inform device that the data on the block of sectors is no longer used (needed at _USE_TRIM == 1) */
|
|
||||||
|
|
||||||
/* Generic command (Not used by FatFs) */
|
|
||||||
#define CTRL_FORMAT 5 /* Create physical format on the media */
|
|
||||||
#define CTRL_POWER_IDLE 6 /* Put the device idle state */
|
|
||||||
#define CTRL_POWER_OFF 7 /* Put the device off state */
|
|
||||||
#define CTRL_LOCK 8 /* Lock media removal */
|
|
||||||
#define CTRL_UNLOCK 9 /* Unlock media removal */
|
|
||||||
#define CTRL_EJECT 10 /* Eject media */
|
|
||||||
#define CTRL_GET_SMART 11 /* Read SMART information */
|
|
||||||
|
|
||||||
/* MMC/SDC specific command (Not used by FatFs) */
|
|
||||||
#define MMC_GET_TYPE 50 /* Get card type */
|
|
||||||
#define MMC_GET_CSD 51 /* Read CSD */
|
|
||||||
#define MMC_GET_CID 52 /* Read CID */
|
|
||||||
#define MMC_GET_OCR 53 /* Read OCR */
|
|
||||||
#define MMC_GET_SDSTAT 54 /* Read SD status */
|
|
||||||
#define ISDIO_READ 55 /* Read data form SD iSDIO register */
|
|
||||||
#define ISDIO_WRITE 56 /* Write data to SD iSDIO register */
|
|
||||||
#define ISDIO_MRITE 57 /* Masked write data to SD iSDIO register */
|
|
||||||
|
|
||||||
/* ATA/CF specific command (Not used by FatFs) */
|
|
||||||
#define ATA_GET_REV 60 /* Get F/W revision */
|
|
||||||
#define ATA_GET_MODEL 61 /* Get model name */
|
|
||||||
#define ATA_GET_SN 62 /* Get serial number */
|
|
||||||
|
|
||||||
|
|
||||||
/* MMC card type flags (MMC_GET_TYPE) */
|
|
||||||
#define CT_MMC 0x01 /* MMC ver 3 */
|
|
||||||
#define CT_SD1 0x02 /* SD ver 1 */
|
|
||||||
#define CT_SD2 0x04 /* SD ver 2 */
|
|
||||||
#define CT_SDC (CT_SD1|CT_SD2) /* SD */
|
|
||||||
#define CT_BLOCK 0x08 /* Block addressing */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
File diff suppressed because it is too large
Load Diff
408
zOS/MZ2000/common/FatFS/ff.h
vendored
408
zOS/MZ2000/common/FatFS/ff.h
vendored
@@ -1,408 +0,0 @@
|
|||||||
/*----------------------------------------------------------------------------/
|
|
||||||
/ FatFs - Generic FAT Filesystem module R0.13c /
|
|
||||||
/-----------------------------------------------------------------------------/
|
|
||||||
/
|
|
||||||
/ Copyright (C) 2018, ChaN, all right reserved.
|
|
||||||
/
|
|
||||||
/ FatFs module is an open source software. Redistribution and use of FatFs in
|
|
||||||
/ source and binary forms, with or without modification, are permitted provided
|
|
||||||
/ that the following condition is met:
|
|
||||||
|
|
||||||
/ 1. Redistributions of source code must retain the above copyright notice,
|
|
||||||
/ this condition and the following disclaimer.
|
|
||||||
/
|
|
||||||
/ This software is provided by the copyright holder and contributors "AS IS"
|
|
||||||
/ and any warranties related to this software are DISCLAIMED.
|
|
||||||
/ The copyright owner or contributors be NOT LIABLE for any damages caused
|
|
||||||
/ by use of this software.
|
|
||||||
/
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef FF_DEFINED
|
|
||||||
#define FF_DEFINED 86604 /* Revision ID */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "ffconf.h" /* FatFs configuration options */
|
|
||||||
|
|
||||||
#if FF_DEFINED != FFCONF_DEF
|
|
||||||
#error Wrong configuration file (ffconf.h).
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Integer types used for FatFs API */
|
|
||||||
|
|
||||||
#if defined(_WIN32) /* Main development platform */
|
|
||||||
#define FF_INTDEF 2
|
|
||||||
#include <windows.h>
|
|
||||||
typedef unsigned __int64 QWORD;
|
|
||||||
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
|
|
||||||
#define FF_INTDEF 2
|
|
||||||
//#if defined __K64F__
|
|
||||||
#include <stdint.h>
|
|
||||||
//#endif
|
|
||||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
|
||||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
|
||||||
typedef uint16_t WORD; /* 16-bit unsigned integer */
|
|
||||||
typedef uint16_t WCHAR; /* 16-bit unsigned integer */
|
|
||||||
typedef uint32_t DWORD; /* 32-bit unsigned integer */
|
|
||||||
typedef uint64_t QWORD; /* 64-bit unsigned integer */
|
|
||||||
#else /* Earlier than C99 */
|
|
||||||
#define FF_INTDEF 1
|
|
||||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
|
||||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
|
||||||
typedef unsigned short WORD; /* 16-bit unsigned integer */
|
|
||||||
typedef unsigned short WCHAR; /* 16-bit unsigned integer */
|
|
||||||
typedef unsigned long DWORD; /* 32-bit unsigned integer */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Definitions of volume management */
|
|
||||||
|
|
||||||
#if FF_MULTI_PARTITION /* Multiple partition configuration */
|
|
||||||
typedef struct {
|
|
||||||
BYTE pd; /* Physical drive number */
|
|
||||||
BYTE pt; /* Partition: 0:Auto detect, 1-4:Forced partition) */
|
|
||||||
} PARTITION;
|
|
||||||
extern PARTITION VolToPart[]; /* Volume - Partition resolution table */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if FF_STR_VOLUME_ID
|
|
||||||
#ifndef FF_VOLUME_STRS
|
|
||||||
extern const char* VolumeStr[FF_VOLUMES]; /* User defied volume ID */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Type of path name strings on FatFs API */
|
|
||||||
|
|
||||||
#ifndef _INC_TCHAR
|
|
||||||
#define _INC_TCHAR
|
|
||||||
|
|
||||||
#if FF_USE_LFN && FF_LFN_UNICODE == 1 /* Unicode in UTF-16 encoding */
|
|
||||||
typedef WCHAR TCHAR;
|
|
||||||
#define _T(x) L ## x
|
|
||||||
#define _TEXT(x) L ## x
|
|
||||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 2 /* Unicode in UTF-8 encoding */
|
|
||||||
typedef char TCHAR;
|
|
||||||
#define _T(x) u8 ## x
|
|
||||||
#define _TEXT(x) u8 ## x
|
|
||||||
#elif FF_USE_LFN && FF_LFN_UNICODE == 3 /* Unicode in UTF-32 encoding */
|
|
||||||
typedef DWORD TCHAR;
|
|
||||||
#define _T(x) U ## x
|
|
||||||
#define _TEXT(x) U ## x
|
|
||||||
#elif FF_USE_LFN && (FF_LFN_UNICODE < 0 || FF_LFN_UNICODE > 3)
|
|
||||||
#error Wrong FF_LFN_UNICODE setting
|
|
||||||
#else /* ANSI/OEM code in SBCS/DBCS */
|
|
||||||
typedef char TCHAR;
|
|
||||||
#define _T(x) x
|
|
||||||
#define _TEXT(x) x
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Type of file size variables */
|
|
||||||
|
|
||||||
#if FF_FS_EXFAT
|
|
||||||
#if FF_INTDEF != 2
|
|
||||||
#error exFAT feature wants C99 or later
|
|
||||||
#endif
|
|
||||||
typedef QWORD FSIZE_t;
|
|
||||||
#else
|
|
||||||
typedef DWORD FSIZE_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Filesystem object structure (FATFS) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
BYTE fs_type; /* Filesystem type (0:not mounted) */
|
|
||||||
BYTE pdrv; /* Associated physical drive */
|
|
||||||
BYTE n_fats; /* Number of FATs (1 or 2) */
|
|
||||||
BYTE wflag; /* win[] flag (b0:dirty) */
|
|
||||||
BYTE fsi_flag; /* FSINFO flags (b7:disabled, b0:dirty) */
|
|
||||||
WORD id; /* Volume mount ID */
|
|
||||||
WORD n_rootdir; /* Number of root directory entries (FAT12/16) */
|
|
||||||
WORD csize; /* Cluster size [sectors] */
|
|
||||||
#if FF_MAX_SS != FF_MIN_SS
|
|
||||||
WORD ssize; /* Sector size (512, 1024, 2048 or 4096) */
|
|
||||||
#endif
|
|
||||||
#if FF_USE_LFN
|
|
||||||
WCHAR* lfnbuf; /* LFN working buffer */
|
|
||||||
#endif
|
|
||||||
#if FF_FS_EXFAT
|
|
||||||
BYTE* dirbuf; /* Directory entry block scratchpad buffer for exFAT */
|
|
||||||
#endif
|
|
||||||
#if FF_FS_REENTRANT
|
|
||||||
FF_SYNC_t sobj; /* Identifier of sync object */
|
|
||||||
#endif
|
|
||||||
#if !FF_FS_READONLY
|
|
||||||
DWORD last_clst; /* Last allocated cluster */
|
|
||||||
DWORD free_clst; /* Number of free clusters */
|
|
||||||
#endif
|
|
||||||
#if FF_FS_RPATH
|
|
||||||
DWORD cdir; /* Current directory start cluster (0:root) */
|
|
||||||
#if FF_FS_EXFAT
|
|
||||||
DWORD cdc_scl; /* Containing directory start cluster (invalid when cdir is 0) */
|
|
||||||
DWORD cdc_size; /* b31-b8:Size of containing directory, b7-b0: Chain status */
|
|
||||||
DWORD cdc_ofs; /* Offset in the containing directory (invalid when cdir is 0) */
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
DWORD n_fatent; /* Number of FAT entries (number of clusters + 2) */
|
|
||||||
DWORD fsize; /* Size of an FAT [sectors] */
|
|
||||||
DWORD volbase; /* Volume base sector */
|
|
||||||
DWORD fatbase; /* FAT base sector */
|
|
||||||
DWORD dirbase; /* Root directory base sector/cluster */
|
|
||||||
DWORD database; /* Data base sector */
|
|
||||||
#if FF_FS_EXFAT
|
|
||||||
DWORD bitbase; /* Allocation bitmap base sector */
|
|
||||||
#endif
|
|
||||||
DWORD winsect; /* Current sector appearing in the win[] */
|
|
||||||
BYTE win[FF_MAX_SS]; /* Disk access window for Directory, FAT (and file data at tiny cfg) */
|
|
||||||
} FATFS;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Object ID and allocation information (FFOBJID) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FATFS* fs; /* Pointer to the hosting volume of this object */
|
|
||||||
WORD id; /* Hosting volume mount ID */
|
|
||||||
BYTE attr; /* Object attribute */
|
|
||||||
BYTE stat; /* Object chain status (b1-0: =0:not contiguous, =2:contiguous, =3:fragmented in this session, b2:sub-directory stretched) */
|
|
||||||
DWORD sclust; /* Object data start cluster (0:no cluster or root directory) */
|
|
||||||
FSIZE_t objsize; /* Object size (valid when sclust != 0) */
|
|
||||||
#if FF_FS_EXFAT
|
|
||||||
DWORD n_cont; /* Size of first fragment - 1 (valid when stat == 3) */
|
|
||||||
DWORD n_frag; /* Size of last fragment needs to be written to FAT (valid when not zero) */
|
|
||||||
DWORD c_scl; /* Containing directory start cluster (valid when sclust != 0) */
|
|
||||||
DWORD c_size; /* b31-b8:Size of containing directory, b7-b0: Chain status (valid when c_scl != 0) */
|
|
||||||
DWORD c_ofs; /* Offset in the containing directory (valid when file object and sclust != 0) */
|
|
||||||
#endif
|
|
||||||
#if FF_FS_LOCK
|
|
||||||
UINT lockid; /* File lock ID origin from 1 (index of file semaphore table Files[]) */
|
|
||||||
#endif
|
|
||||||
} FFOBJID;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File object structure (FIL) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FFOBJID obj; /* Object identifier (must be the 1st member to detect invalid object pointer) */
|
|
||||||
BYTE flag; /* File status flags */
|
|
||||||
BYTE err; /* Abort flag (error code) */
|
|
||||||
FSIZE_t fptr; /* File read/write pointer (Zeroed on file open) */
|
|
||||||
DWORD clust; /* Current cluster of fpter (invalid when fptr is 0) */
|
|
||||||
DWORD sect; /* Sector number appearing in buf[] (0:invalid) */
|
|
||||||
#if !FF_FS_READONLY
|
|
||||||
DWORD dir_sect; /* Sector number containing the directory entry (not used at exFAT) */
|
|
||||||
BYTE* dir_ptr; /* Pointer to the directory entry in the win[] (not used at exFAT) */
|
|
||||||
#endif
|
|
||||||
#if FF_USE_FASTSEEK
|
|
||||||
DWORD* cltbl; /* Pointer to the cluster link map table (nulled on open, set by application) */
|
|
||||||
#endif
|
|
||||||
#if !FF_FS_TINY
|
|
||||||
BYTE buf[FF_MAX_SS]; /* File private data read/write window */
|
|
||||||
#endif
|
|
||||||
} FIL;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Directory object structure (DIR) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FFOBJID obj; /* Object identifier */
|
|
||||||
DWORD dptr; /* Current read/write offset */
|
|
||||||
DWORD clust; /* Current cluster */
|
|
||||||
DWORD sect; /* Current sector (0:Read operation has terminated) */
|
|
||||||
BYTE* dir; /* Pointer to the directory item in the win[] */
|
|
||||||
BYTE fn[12]; /* SFN (in/out) {body[8],ext[3],status[1]} */
|
|
||||||
#if FF_USE_LFN
|
|
||||||
DWORD blk_ofs; /* Offset of current entry block being processed (0xFFFFFFFF:Invalid) */
|
|
||||||
#endif
|
|
||||||
#if FF_USE_FIND
|
|
||||||
const TCHAR* pat; /* Pointer to the name matching pattern */
|
|
||||||
#endif
|
|
||||||
} DIR;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File information structure (FILINFO) */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
FSIZE_t fsize; /* File size */
|
|
||||||
WORD fdate; /* Modified date */
|
|
||||||
WORD ftime; /* Modified time */
|
|
||||||
BYTE fattrib; /* File attribute */
|
|
||||||
#if FF_USE_LFN
|
|
||||||
TCHAR altname[FF_SFN_BUF + 1];/* Altenative file name */
|
|
||||||
TCHAR fname[FF_LFN_BUF + 1]; /* Primary file name */
|
|
||||||
#else
|
|
||||||
TCHAR fname[12 + 1]; /* File name */
|
|
||||||
#endif
|
|
||||||
} FILINFO;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File function return code (FRESULT) */
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FR_OK = 0, /* (0) Succeeded */
|
|
||||||
FR_DISK_ERR, /* (1) A hard error occurred in the low level disk I/O layer */
|
|
||||||
FR_INT_ERR, /* (2) Assertion failed */
|
|
||||||
FR_NOT_READY, /* (3) The physical drive cannot work */
|
|
||||||
FR_NO_FILE, /* (4) Could not find the file */
|
|
||||||
FR_NO_PATH, /* (5) Could not find the path */
|
|
||||||
FR_INVALID_NAME, /* (6) The path name format is invalid */
|
|
||||||
FR_DENIED, /* (7) Access denied due to prohibited access or directory full */
|
|
||||||
FR_EXIST, /* (8) Access denied due to prohibited access */
|
|
||||||
FR_INVALID_OBJECT, /* (9) The file/directory object is invalid */
|
|
||||||
FR_WRITE_PROTECTED, /* (10) The physical drive is write protected */
|
|
||||||
FR_INVALID_DRIVE, /* (11) The logical drive number is invalid */
|
|
||||||
FR_NOT_ENABLED, /* (12) The volume has no work area */
|
|
||||||
FR_NO_FILESYSTEM, /* (13) There is no valid FAT volume */
|
|
||||||
FR_MKFS_ABORTED, /* (14) The f_mkfs() aborted due to any problem */
|
|
||||||
FR_TIMEOUT, /* (15) Could not get a grant to access the volume within defined period */
|
|
||||||
FR_LOCKED, /* (16) The operation is rejected according to the file sharing policy */
|
|
||||||
FR_NOT_ENOUGH_CORE, /* (17) LFN working buffer could not be allocated */
|
|
||||||
FR_TOO_MANY_OPEN_FILES, /* (18) Number of open files > FF_FS_LOCK */
|
|
||||||
FR_INVALID_PARAMETER /* (19) Given parameter is invalid */
|
|
||||||
} FRESULT;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------*/
|
|
||||||
/* FatFs module application interface */
|
|
||||||
|
|
||||||
FRESULT f_open (FIL* fp, const TCHAR* path, BYTE mode); /* Open or create a file */
|
|
||||||
FRESULT f_close (FIL* fp); /* Close an open file object */
|
|
||||||
FRESULT f_read (FIL* fp, void* buff, UINT btr, UINT* br); /* Read data from the file */
|
|
||||||
FRESULT f_write (FIL* fp, const void* buff, UINT btw, UINT* bw); /* Write data to the file */
|
|
||||||
FRESULT f_lseek (FIL* fp, FSIZE_t ofs); /* Move file pointer of the file object */
|
|
||||||
FRESULT f_truncate (FIL* fp); /* Truncate the file */
|
|
||||||
FRESULT f_sync (FIL* fp); /* Flush cached data of the writing file */
|
|
||||||
FRESULT f_opendir (DIR* dp, const TCHAR* path); /* Open a directory */
|
|
||||||
FRESULT f_closedir (DIR* dp); /* Close an open directory */
|
|
||||||
FRESULT f_readdir (DIR* dp, FILINFO* fno); /* Read a directory item */
|
|
||||||
FRESULT f_findfirst (DIR* dp, FILINFO* fno, const TCHAR* path, const TCHAR* pattern); /* Find first file */
|
|
||||||
FRESULT f_findnext (DIR* dp, FILINFO* fno); /* Find next file */
|
|
||||||
FRESULT f_mkdir (const TCHAR* path); /* Create a sub directory */
|
|
||||||
FRESULT f_unlink (const TCHAR* path); /* Delete an existing file or directory */
|
|
||||||
FRESULT f_rename (const TCHAR* path_old, const TCHAR* path_new); /* Rename/Move a file or directory */
|
|
||||||
FRESULT f_stat (const TCHAR* path, FILINFO* fno); /* Get file status */
|
|
||||||
FRESULT f_chmod (const TCHAR* path, BYTE attr, BYTE mask); /* Change attribute of a file/dir */
|
|
||||||
FRESULT f_utime (const TCHAR* path, const FILINFO* fno); /* Change timestamp of a file/dir */
|
|
||||||
FRESULT f_chdir (const TCHAR* path); /* Change current directory */
|
|
||||||
FRESULT f_chdrive (const TCHAR* path); /* Change current drive */
|
|
||||||
FRESULT f_getcwd (TCHAR* buff, UINT len); /* Get current directory */
|
|
||||||
FRESULT f_getfree (const TCHAR* path, DWORD* nclst, FATFS** fatfs); /* Get number of free clusters on the drive */
|
|
||||||
FRESULT f_getlabel (const TCHAR* path, TCHAR* label, DWORD* vsn); /* Get volume label */
|
|
||||||
FRESULT f_setlabel (const TCHAR* label); /* Set volume label */
|
|
||||||
FRESULT f_forward (FIL* fp, UINT(*func)(const BYTE*,UINT), UINT btf, UINT* bf); /* Forward data to the stream */
|
|
||||||
FRESULT f_expand (FIL* fp, FSIZE_t szf, BYTE opt); /* Allocate a contiguous block to the file */
|
|
||||||
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt); /* Mount/Unmount a logical drive */
|
|
||||||
FRESULT f_mkfs (const TCHAR* path, BYTE opt, DWORD au, void* work, UINT len); /* Create a FAT volume */
|
|
||||||
FRESULT f_fdisk (BYTE pdrv, const DWORD* szt, void* work); /* Divide a physical drive into some partitions */
|
|
||||||
FRESULT f_setcp (WORD cp); /* Set current code page */
|
|
||||||
int f_putc (TCHAR c, FIL* fp); /* Put a character to the file */
|
|
||||||
int f_puts (const TCHAR* str, FIL* cp); /* Put a string to the file */
|
|
||||||
int f_printf (FIL* fp, const TCHAR* str, ...); /* Put a formatted string to the file */
|
|
||||||
TCHAR* f_gets (TCHAR* buff, int len, FIL* fp); /* Get a string from the file */
|
|
||||||
|
|
||||||
#define f_eof(fp) ((int)((fp)->fptr == (fp)->obj.objsize))
|
|
||||||
#define f_error(fp) ((fp)->err)
|
|
||||||
#define f_tell(fp) ((fp)->fptr)
|
|
||||||
#define f_size(fp) ((fp)->obj.objsize)
|
|
||||||
#define f_rewind(fp) f_lseek((fp), 0)
|
|
||||||
#define f_rewinddir(dp) f_readdir((dp), 0)
|
|
||||||
#define f_rmdir(path) f_unlink(path)
|
|
||||||
#define f_unmount(path) f_mount(0, path, 0)
|
|
||||||
|
|
||||||
#ifndef EOF
|
|
||||||
#define EOF (-1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------*/
|
|
||||||
/* Additional user defined functions */
|
|
||||||
|
|
||||||
/* RTC function */
|
|
||||||
#if !FF_FS_READONLY && !FF_FS_NORTC
|
|
||||||
DWORD get_fattime (void);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* LFN support functions */
|
|
||||||
#if FF_USE_LFN >= 1 /* Code conversion (defined in unicode.c) */
|
|
||||||
WCHAR ff_oem2uni (WCHAR oem, WORD cp); /* OEM code to Unicode conversion */
|
|
||||||
WCHAR ff_uni2oem (DWORD uni, WORD cp); /* Unicode to OEM code conversion */
|
|
||||||
DWORD ff_wtoupper (DWORD uni); /* Unicode upper-case conversion */
|
|
||||||
#endif
|
|
||||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
|
||||||
void* ff_memalloc (UINT msize); /* Allocate memory block */
|
|
||||||
void ff_memfree (void* mblock); /* Free memory block */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Sync functions */
|
|
||||||
#if FF_FS_REENTRANT
|
|
||||||
int ff_cre_syncobj (BYTE vol, FF_SYNC_t* sobj); /* Create a sync object */
|
|
||||||
int ff_req_grant (FF_SYNC_t sobj); /* Lock sync object */
|
|
||||||
void ff_rel_grant (FF_SYNC_t sobj); /* Unlock sync object */
|
|
||||||
int ff_del_syncobj (FF_SYNC_t sobj); /* Delete a sync object */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------*/
|
|
||||||
/* Flags and offset address */
|
|
||||||
|
|
||||||
|
|
||||||
/* File access mode and open method flags (3rd argument of f_open) */
|
|
||||||
#define FA_READ 0x01
|
|
||||||
#define FA_WRITE 0x02
|
|
||||||
#define FA_OPEN_EXISTING 0x00
|
|
||||||
#define FA_CREATE_NEW 0x04
|
|
||||||
#define FA_CREATE_ALWAYS 0x08
|
|
||||||
#define FA_OPEN_ALWAYS 0x10
|
|
||||||
#define FA_OPEN_APPEND 0x30
|
|
||||||
|
|
||||||
/* Fast seek controls (2nd argument of f_lseek) */
|
|
||||||
#define CREATE_LINKMAP ((FSIZE_t)0 - 1)
|
|
||||||
|
|
||||||
/* Format options (2nd argument of f_mkfs) */
|
|
||||||
#define FM_FAT 0x01
|
|
||||||
#define FM_FAT32 0x02
|
|
||||||
#define FM_EXFAT 0x04
|
|
||||||
#define FM_ANY 0x07
|
|
||||||
#define FM_SFD 0x08
|
|
||||||
|
|
||||||
/* Filesystem type (FATFS.fs_type) */
|
|
||||||
#define FS_FAT12 1
|
|
||||||
#define FS_FAT16 2
|
|
||||||
#define FS_FAT32 3
|
|
||||||
#define FS_EXFAT 4
|
|
||||||
|
|
||||||
/* File attribute bits for directory entry (FILINFO.fattrib) */
|
|
||||||
#define AM_RDO 0x01 /* Read only */
|
|
||||||
#define AM_HID 0x02 /* Hidden */
|
|
||||||
#define AM_SYS 0x04 /* System */
|
|
||||||
#define AM_DIR 0x10 /* Directory */
|
|
||||||
#define AM_ARC 0x20 /* Archive */
|
|
||||||
|
|
||||||
#define SECTOR_SIZE 512
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* FF_DEFINED */
|
|
||||||
295
zOS/MZ2000/common/FatFS/ffconf.h
vendored
295
zOS/MZ2000/common/FatFS/ffconf.h
vendored
@@ -1,295 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ FatFs - Configuration file
|
|
||||||
/---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define FFCONF_DEF 86604 /* Revision ID */
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Function Configurations
|
|
||||||
/---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define FF_FS_READONLY 0
|
|
||||||
/* This option switches read-only configuration. (0:Read/Write or 1:Read-only)
|
|
||||||
/ Read-only configuration removes writing API functions, f_write(), f_sync(),
|
|
||||||
/ f_unlink(), f_mkdir(), f_chmod(), f_rename(), f_truncate(), f_getfree()
|
|
||||||
/ and optional writing functions as well. */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_FS_MINIMIZE 0
|
|
||||||
/* This option defines minimization level to remove some basic API functions.
|
|
||||||
/
|
|
||||||
/ 0: Basic functions are fully enabled.
|
|
||||||
/ 1: f_stat(), f_getfree(), f_unlink(), f_mkdir(), f_truncate() and f_rename()
|
|
||||||
/ are removed.
|
|
||||||
/ 2: f_opendir(), f_readdir() and f_closedir() are removed in addition to 1.
|
|
||||||
/ 3: f_lseek() function is removed in addition to 2. */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_STRFUNC 2
|
|
||||||
/* This option switches string functions, f_gets(), f_putc(), f_puts() and f_printf().
|
|
||||||
/
|
|
||||||
/ 0: Disable string functions.
|
|
||||||
/ 1: Enable without LF-CRLF conversion.
|
|
||||||
/ 2: Enable with LF-CRLF conversion. */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_FIND 0
|
|
||||||
/* This option switches filtered directory read functions, f_findfirst() and
|
|
||||||
/ f_findnext(). (0:Disable, 1:Enable 2:Enable with matching altname[] too) */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_MKFS 1
|
|
||||||
/* This option switches f_mkfs() function. (0:Disable or 1:Enable) */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_FASTSEEK 0
|
|
||||||
/* This option switches fast seek function. (0:Disable or 1:Enable) */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_EXPAND 1
|
|
||||||
/* This option switches f_expand function. (0:Disable or 1:Enable) */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_CHMOD 1
|
|
||||||
/* This option switches attribute manipulation functions, f_chmod() and f_utime().
|
|
||||||
/ (0:Disable or 1:Enable) Also FF_FS_READONLY needs to be 0 to enable this option. */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_LABEL 1
|
|
||||||
/* This option switches volume label functions, f_getlabel() and f_setlabel().
|
|
||||||
/ (0:Disable or 1:Enable) */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_FORWARD 0
|
|
||||||
/* This option switches f_forward() function. (0:Disable or 1:Enable) */
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Locale and Namespace Configurations
|
|
||||||
/---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define FF_CODE_PAGE 437
|
|
||||||
/* This option specifies the OEM code page to be used on the target system.
|
|
||||||
/ Incorrect code page setting can cause a file open failure.
|
|
||||||
/
|
|
||||||
/ 437 - U.S.
|
|
||||||
/ 720 - Arabic
|
|
||||||
/ 737 - Greek
|
|
||||||
/ 771 - KBL
|
|
||||||
/ 775 - Baltic
|
|
||||||
/ 850 - Latin 1
|
|
||||||
/ 852 - Latin 2
|
|
||||||
/ 855 - Cyrillic
|
|
||||||
/ 857 - Turkish
|
|
||||||
/ 860 - Portuguese
|
|
||||||
/ 861 - Icelandic
|
|
||||||
/ 862 - Hebrew
|
|
||||||
/ 863 - Canadian French
|
|
||||||
/ 864 - Arabic
|
|
||||||
/ 865 - Nordic
|
|
||||||
/ 866 - Russian
|
|
||||||
/ 869 - Greek 2
|
|
||||||
/ 932 - Japanese (DBCS)
|
|
||||||
/ 936 - Simplified Chinese (DBCS)
|
|
||||||
/ 949 - Korean (DBCS)
|
|
||||||
/ 950 - Traditional Chinese (DBCS)
|
|
||||||
/ 0 - Include all code pages above and configured by f_setcp()
|
|
||||||
*/
|
|
||||||
|
|
||||||
// zOS running on the tranZPUter uses LFN.
|
|
||||||
//
|
|
||||||
//#if defined __TRANZPUTER__
|
|
||||||
#define FF_USE_LFN 1
|
|
||||||
//#else
|
|
||||||
//#define FF_USE_LFN 0
|
|
||||||
//#endif
|
|
||||||
|
|
||||||
#define FF_MAX_LFN 255
|
|
||||||
/* The FF_USE_LFN switches the support for LFN (long file name).
|
|
||||||
/
|
|
||||||
/ 0: Disable LFN. FF_MAX_LFN has no effect.
|
|
||||||
/ 1: Enable LFN with static working buffer on the BSS. Always NOT thread-safe.
|
|
||||||
/ 2: Enable LFN with dynamic working buffer on the STACK.
|
|
||||||
/ 3: Enable LFN with dynamic working buffer on the HEAP.
|
|
||||||
/
|
|
||||||
/ To enable the LFN, ffunicode.c needs to be added to the project. The LFN function
|
|
||||||
/ requiers certain internal working buffer occupies (FF_MAX_LFN + 1) * 2 bytes and
|
|
||||||
/ additional (FF_MAX_LFN + 44) / 15 * 32 bytes when exFAT is enabled.
|
|
||||||
/ The FF_MAX_LFN defines size of the working buffer in UTF-16 code unit and it can
|
|
||||||
/ be in range of 12 to 255. It is recommended to be set 255 to fully support LFN
|
|
||||||
/ specification.
|
|
||||||
/ When use stack for the working buffer, take care on stack overflow. When use heap
|
|
||||||
/ memory for the working buffer, memory management functions, ff_memalloc() and
|
|
||||||
/ ff_memfree() in ffsystem.c, need to be added to the project. */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_LFN_UNICODE 0
|
|
||||||
/* This option switches the character encoding on the API when LFN is enabled.
|
|
||||||
/
|
|
||||||
/ 0: ANSI/OEM in current CP (TCHAR = char)
|
|
||||||
/ 1: Unicode in UTF-16 (TCHAR = WCHAR)
|
|
||||||
/ 2: Unicode in UTF-8 (TCHAR = char)
|
|
||||||
/ 3: Unicode in UTF-32 (TCHAR = DWORD)
|
|
||||||
/
|
|
||||||
/ Also behavior of string I/O functions will be affected by this option.
|
|
||||||
/ When LFN is not enabled, this option has no effect. */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_LFN_BUF 255
|
|
||||||
#define FF_SFN_BUF 12
|
|
||||||
/* This set of options defines size of file name members in the FILINFO structure
|
|
||||||
/ which is used to read out directory items. These values should be suffcient for
|
|
||||||
/ the file names to read. The maximum possible length of the read file name depends
|
|
||||||
/ on character encoding. When LFN is not enabled, these options have no effect. */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_STRF_ENCODE 3
|
|
||||||
/* When FF_LFN_UNICODE >= 1 with LFN enabled, string I/O functions, f_gets(),
|
|
||||||
/ f_putc(), f_puts and f_printf() convert the character encoding in it.
|
|
||||||
/ This option selects assumption of character encoding ON THE FILE to be
|
|
||||||
/ read/written via those functions.
|
|
||||||
/
|
|
||||||
/ 0: ANSI/OEM in current CP
|
|
||||||
/ 1: Unicode in UTF-16LE
|
|
||||||
/ 2: Unicode in UTF-16BE
|
|
||||||
/ 3: Unicode in UTF-8
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_FS_RPATH 2
|
|
||||||
/* This option configures support for relative path.
|
|
||||||
/
|
|
||||||
/ 0: Disable relative path and remove related functions.
|
|
||||||
/ 1: Enable relative path. f_chdir() and f_chdrive() are available.
|
|
||||||
/ 2: f_getcwd() function is available in addition to 1.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Drive/Volume Configurations
|
|
||||||
/---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define FF_VOLUMES 4
|
|
||||||
/* Number of volumes (logical drives) to be used. (1-10) */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_STR_VOLUME_ID 1
|
|
||||||
//#define FF_VOLUME_STRS "RAM","NAND","CF","SD","SD2","USB","USB2","USB3"
|
|
||||||
#define FF_VOLUME_STRS "SD"
|
|
||||||
/* FF_STR_VOLUME_ID switches support for volume ID in arbitrary strings.
|
|
||||||
/ When FF_STR_VOLUME_ID is set to 1 or 2, arbitrary strings can be used as drive
|
|
||||||
/ number in the path name. FF_VOLUME_STRS defines the volume ID strings for each
|
|
||||||
/ logical drives. Number of items must not be less than FF_VOLUMES. Valid
|
|
||||||
/ characters for the volume ID strings are A-Z, a-z and 0-9, however, they are
|
|
||||||
/ compared in case-insensitive. If FF_STR_VOLUME_ID >= 1 and FF_VOLUME_STRS is
|
|
||||||
/ not defined, a user defined volume string table needs to be defined as:
|
|
||||||
/
|
|
||||||
/ const char* VolumeStr[FF_VOLUMES] = {"ram","flash","sd","usb",...
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_MULTI_PARTITION 1
|
|
||||||
/* This option switches support for multiple volumes on the physical drive.
|
|
||||||
/ By default (0), each logical drive number is bound to the same physical drive
|
|
||||||
/ number and only an FAT volume found on the physical drive will be mounted.
|
|
||||||
/ When this function is enabled (1), each logical drive number can be bound to
|
|
||||||
/ arbitrary physical drive and partition listed in the VolToPart[]. Also f_fdisk()
|
|
||||||
/ funciton will be available. */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_MIN_SS 512
|
|
||||||
#define FF_MAX_SS 512
|
|
||||||
/* This set of options configures the range of sector size to be supported. (512,
|
|
||||||
/ 1024, 2048 or 4096) Always set both 512 for most systems, generic memory card and
|
|
||||||
/ harddisk. But a larger value may be required for on-board flash memory and some
|
|
||||||
/ type of optical media. When FF_MAX_SS is larger than FF_MIN_SS, FatFs is configured
|
|
||||||
/ for variable sector size mode and disk_ioctl() function needs to implement
|
|
||||||
/ GET_SECTOR_SIZE command. */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_USE_TRIM 0
|
|
||||||
/* This option switches support for ATA-TRIM. (0:Disable or 1:Enable)
|
|
||||||
/ To enable Trim function, also CTRL_TRIM command should be implemented to the
|
|
||||||
/ disk_ioctl() function. */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_FS_NOFSINFO 0
|
|
||||||
/* If you need to know correct free space on the FAT32 volume, set bit 0 of this
|
|
||||||
/ option, and f_getfree() function at first time after volume mount will force
|
|
||||||
/ a full FAT scan. Bit 1 controls the use of last allocated cluster number.
|
|
||||||
/
|
|
||||||
/ bit0=0: Use free cluster count in the FSINFO if available.
|
|
||||||
/ bit0=1: Do not trust free cluster count in the FSINFO.
|
|
||||||
/ bit1=0: Use last allocated cluster number in the FSINFO if available.
|
|
||||||
/ bit1=1: Do not trust last allocated cluster number in the FSINFO.
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ System Configurations
|
|
||||||
/---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define FF_FS_TINY 0
|
|
||||||
/* This option switches tiny buffer configuration. (0:Normal or 1:Tiny)
|
|
||||||
/ At the tiny configuration, size of file object (FIL) is shrinked FF_MAX_SS bytes.
|
|
||||||
/ Instead of private sector buffer eliminated from the file object, common sector
|
|
||||||
/ buffer in the filesystem object (FATFS) is used for the file data transfer. */
|
|
||||||
|
|
||||||
#define FF_FS_EXFAT 0
|
|
||||||
/* This option switches support for exFAT filesystem. (0:Disable or 1:Enable)
|
|
||||||
/ To enable exFAT, also LFN needs to be enabled.
|
|
||||||
/ Note that enabling exFAT discards ANSI C (C89) compatibility. */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_FS_NORTC 1
|
|
||||||
#define FF_NORTC_MON 1
|
|
||||||
#define FF_NORTC_MDAY 1
|
|
||||||
#define FF_NORTC_YEAR 2018
|
|
||||||
/* The option FF_FS_NORTC switches timestamp functiton. If the system does not have
|
|
||||||
/ any RTC function or valid timestamp is not needed, set FF_FS_NORTC = 1 to disable
|
|
||||||
/ the timestamp function. Every object modified by FatFs will have a fixed timestamp
|
|
||||||
/ defined by FF_NORTC_MON, FF_NORTC_MDAY and FF_NORTC_YEAR in local time.
|
|
||||||
/ To enable timestamp function (FF_FS_NORTC = 0), get_fattime() function need to be
|
|
||||||
/ added to the project to read current time form real-time clock. FF_NORTC_MON,
|
|
||||||
/ FF_NORTC_MDAY and FF_NORTC_YEAR have no effect.
|
|
||||||
/ These options have no effect at read-only configuration (FF_FS_READONLY = 1). */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_FS_LOCK 0
|
|
||||||
/* The option FF_FS_LOCK switches file lock function to control duplicated file open
|
|
||||||
/ and illegal operation to open objects. This option must be 0 when FF_FS_READONLY
|
|
||||||
/ is 1.
|
|
||||||
/
|
|
||||||
/ 0: Disable file lock function. To avoid volume corruption, application program
|
|
||||||
/ should avoid illegal open, remove and rename to the open objects.
|
|
||||||
/ >0: Enable file lock function. The value defines how many files/sub-directories
|
|
||||||
/ can be opened simultaneously under file lock control. Note that the file
|
|
||||||
/ lock control is independent of re-entrancy. */
|
|
||||||
|
|
||||||
|
|
||||||
#define FF_FS_REENTRANT 0
|
|
||||||
#define FF_FS_TIMEOUT 1000
|
|
||||||
#define FF_SYNC_t HANDLE
|
|
||||||
/* The option FF_FS_REENTRANT switches the re-entrancy (thread safe) of the FatFs
|
|
||||||
/ module itself. Note that regardless of this option, file access to different
|
|
||||||
/ volume is always re-entrant and volume control functions, f_mount(), f_mkfs()
|
|
||||||
/ and f_fdisk() function, are always not re-entrant. Only file/directory access
|
|
||||||
/ to the same volume is under control of this function.
|
|
||||||
/
|
|
||||||
/ 0: Disable re-entrancy. FF_FS_TIMEOUT and FF_SYNC_t have no effect.
|
|
||||||
/ 1: Enable re-entrancy. Also user provided synchronization handlers,
|
|
||||||
/ ff_req_grant(), ff_rel_grant(), ff_del_syncobj() and ff_cre_syncobj()
|
|
||||||
/ function, must be added to the project. Samples are available in
|
|
||||||
/ option/syscall.c.
|
|
||||||
/
|
|
||||||
/ The FF_FS_TIMEOUT defines timeout period in unit of time tick.
|
|
||||||
/ The FF_SYNC_t defines O/S dependent sync object type. e.g. HANDLE, ID, OS_EVENT*,
|
|
||||||
/ SemaphoreHandle_t and etc. A header file for O/S definitions needs to be
|
|
||||||
/ included somewhere in the scope of ff.h. */
|
|
||||||
|
|
||||||
/* #include <windows.h> // O/S definitions */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--- End of configuration options ---*/
|
|
||||||
@@ -1,170 +0,0 @@
|
|||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Sample Code of OS Dependent Functions for FatFs */
|
|
||||||
/* (C)ChaN, 2018 */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
#include "ff.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if FF_USE_LFN == 3 /* Dynamic memory allocation */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Allocate a memory block */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void* ff_memalloc ( /* Returns pointer to the allocated memory block (null if not enough core) */
|
|
||||||
UINT msize /* Number of bytes to allocate */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
return malloc(msize); /* Allocate a new memory block with POSIX API */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Free a memory block */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void ff_memfree (
|
|
||||||
void* mblock /* Pointer to the memory block to free (nothing to do if null) */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
free(mblock); /* Free the memory block with POSIX API */
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#if FF_FS_REENTRANT /* Mutal exclusion */
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Create a Synchronization Object */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* This function is called in f_mount() function to create a new
|
|
||||||
/ synchronization object for the volume, such as semaphore and mutex.
|
|
||||||
/ When a 0 is returned, the f_mount() function fails with FR_INT_ERR.
|
|
||||||
*/
|
|
||||||
|
|
||||||
//const osMutexDef_t Mutex[FF_VOLUMES]; /* Table of CMSIS-RTOS mutex */
|
|
||||||
|
|
||||||
|
|
||||||
int ff_cre_syncobj ( /* 1:Function succeeded, 0:Could not create the sync object */
|
|
||||||
BYTE vol, /* Corresponding volume (logical drive number) */
|
|
||||||
FF_SYNC_t* sobj /* Pointer to return the created sync object */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
/* Win32 */
|
|
||||||
*sobj = CreateMutex(NULL, FALSE, NULL);
|
|
||||||
return (int)(*sobj != INVALID_HANDLE_VALUE);
|
|
||||||
|
|
||||||
/* uITRON */
|
|
||||||
// T_CSEM csem = {TA_TPRI,1,1};
|
|
||||||
// *sobj = acre_sem(&csem);
|
|
||||||
// return (int)(*sobj > 0);
|
|
||||||
|
|
||||||
/* uC/OS-II */
|
|
||||||
// OS_ERR err;
|
|
||||||
// *sobj = OSMutexCreate(0, &err);
|
|
||||||
// return (int)(err == OS_NO_ERR);
|
|
||||||
|
|
||||||
/* FreeRTOS */
|
|
||||||
// *sobj = xSemaphoreCreateMutex();
|
|
||||||
// return (int)(*sobj != NULL);
|
|
||||||
|
|
||||||
/* CMSIS-RTOS */
|
|
||||||
// *sobj = osMutexCreate(&Mutex[vol]);
|
|
||||||
// return (int)(*sobj != NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Delete a Synchronization Object */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* This function is called in f_mount() function to delete a synchronization
|
|
||||||
/ object that created with ff_cre_syncobj() function. When a 0 is returned,
|
|
||||||
/ the f_mount() function fails with FR_INT_ERR.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ff_del_syncobj ( /* 1:Function succeeded, 0:Could not delete due to an error */
|
|
||||||
FF_SYNC_t sobj /* Sync object tied to the logical drive to be deleted */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
/* Win32 */
|
|
||||||
return (int)CloseHandle(sobj);
|
|
||||||
|
|
||||||
/* uITRON */
|
|
||||||
// return (int)(del_sem(sobj) == E_OK);
|
|
||||||
|
|
||||||
/* uC/OS-II */
|
|
||||||
// OS_ERR err;
|
|
||||||
// OSMutexDel(sobj, OS_DEL_ALWAYS, &err);
|
|
||||||
// return (int)(err == OS_NO_ERR);
|
|
||||||
|
|
||||||
/* FreeRTOS */
|
|
||||||
// vSemaphoreDelete(sobj);
|
|
||||||
// return 1;
|
|
||||||
|
|
||||||
/* CMSIS-RTOS */
|
|
||||||
// return (int)(osMutexDelete(sobj) == osOK);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Request Grant to Access the Volume */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* This function is called on entering file functions to lock the volume.
|
|
||||||
/ When a 0 is returned, the file function fails with FR_TIMEOUT.
|
|
||||||
*/
|
|
||||||
|
|
||||||
int ff_req_grant ( /* 1:Got a grant to access the volume, 0:Could not get a grant */
|
|
||||||
FF_SYNC_t sobj /* Sync object to wait */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
/* Win32 */
|
|
||||||
return (int)(WaitForSingleObject(sobj, FF_FS_TIMEOUT) == WAIT_OBJECT_0);
|
|
||||||
|
|
||||||
/* uITRON */
|
|
||||||
// return (int)(wai_sem(sobj) == E_OK);
|
|
||||||
|
|
||||||
/* uC/OS-II */
|
|
||||||
// OS_ERR err;
|
|
||||||
// OSMutexPend(sobj, FF_FS_TIMEOUT, &err));
|
|
||||||
// return (int)(err == OS_NO_ERR);
|
|
||||||
|
|
||||||
/* FreeRTOS */
|
|
||||||
// return (int)(xSemaphoreTake(sobj, FF_FS_TIMEOUT) == pdTRUE);
|
|
||||||
|
|
||||||
/* CMSIS-RTOS */
|
|
||||||
// return (int)(osMutexWait(sobj, FF_FS_TIMEOUT) == osOK);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* Release Grant to Access the Volume */
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
/* This function is called on leaving file functions to unlock the volume.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void ff_rel_grant (
|
|
||||||
FF_SYNC_t sobj /* Sync object to be signaled */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
/* Win32 */
|
|
||||||
ReleaseMutex(sobj);
|
|
||||||
|
|
||||||
/* uITRON */
|
|
||||||
// sig_sem(sobj);
|
|
||||||
|
|
||||||
/* uC/OS-II */
|
|
||||||
// OSMutexPost(sobj);
|
|
||||||
|
|
||||||
/* FreeRTOS */
|
|
||||||
// xSemaphoreGive(sobj);
|
|
||||||
|
|
||||||
/* CMSIS-RTOS */
|
|
||||||
// osMutexRelease(sobj);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,255 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: sdmmc_teensy.c
|
|
||||||
// Created: June 2019 - April 2020
|
|
||||||
// Author(s): ChaN (framework), Philip Smart (K64F SoC customisation)
|
|
||||||
// Description: Functionality to enable connectivity between the FatFS ((C) ChaN) and the Teensy K64F
|
|
||||||
// for SD drives. The majority of SD logic exists in the class provided by NXP and
|
|
||||||
// updated by PJRC, this module provides the public interfaces to interface to the NXP
|
|
||||||
// module.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (C) 2013 ChaN, all rights reserved - framework.
|
|
||||||
// Copyright: (C) 2019-20 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: January 2019 - Initial script written for the STORM processor then changed to the ZPU.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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 <SPI.h>
|
|
||||||
#include <ioreg.h>
|
|
||||||
#include <Sd2PinMap.h>
|
|
||||||
#include <SdInfo.h>
|
|
||||||
#include "NXP_SDHC.h"
|
|
||||||
#define BUILTIN_SDCARD 254
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "ff.h" /* Obtains integer types for FatFs */
|
|
||||||
#include "diskio.h" /* Common include file for FatFs and disk I/O layer */
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
/* Platform dependent macros and functions needed to be modified */
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#define uint32_t __uint32_t
|
|
||||||
#define uint16_t __uint16_t
|
|
||||||
#define uint8_t __uint8_t
|
|
||||||
#define int32_t __int32_t
|
|
||||||
#define int16_t __int16_t
|
|
||||||
#define int8_t __int8_t
|
|
||||||
|
|
||||||
#include "k64f_soc.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
Module Private Functions
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* MMC/SD command (SPI mode) */
|
|
||||||
#define CMD0 (0) /* GO_IDLE_STATE */
|
|
||||||
#define CMD1 (1) /* SEND_OP_COND */
|
|
||||||
#define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
|
|
||||||
#define CMD8 (8) /* SEND_IF_COND */
|
|
||||||
#define CMD9 (9) /* SEND_CSD */
|
|
||||||
#define CMD10 (10) /* SEND_CID */
|
|
||||||
#define CMD12 (12) /* STOP_TRANSMISSION */
|
|
||||||
#define CMD13 (13) /* SEND_STATUS */
|
|
||||||
#define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
|
|
||||||
#define CMD16 (16) /* SET_BLOCKLEN */
|
|
||||||
#define CMD17 (17) /* READ_SINGLE_BLOCK */
|
|
||||||
#define CMD18 (18) /* READ_MULTIPLE_BLOCK */
|
|
||||||
#define CMD23 (23) /* SET_BLOCK_COUNT */
|
|
||||||
#define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
|
|
||||||
#define CMD24 (24) /* WRITE_BLOCK */
|
|
||||||
#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
|
|
||||||
#define CMD32 (32) /* ERASE_ER_BLK_START */
|
|
||||||
#define CMD33 (33) /* ERASE_ER_BLK_END */
|
|
||||||
#define CMD38 (38) /* ERASE */
|
|
||||||
#define CMD55 (55) /* APP_CMD */
|
|
||||||
#define CMD58 (58) /* READ_OCR */
|
|
||||||
#define SECTOR_SIZE 512 /* Default size of an SD Sector */
|
|
||||||
|
|
||||||
static
|
|
||||||
DSTATUS Stat[SD_DEVICE_CNT] = { STA_NOINIT }; /* Disk status */
|
|
||||||
uint8_t card_type;
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
Public Functions
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
// Volume to partiion map. This map specifies which Volume resides on which disk/partition.
|
|
||||||
// NB. When using the ZPU as a host on the Sharp MZ computers, the K64F hosts the SD card so the first volume will be the second on the actual physical SD card.
|
|
||||||
//
|
|
||||||
PARTITION VolToPart[FF_VOLUMES] = {
|
|
||||||
{0, 1}, /* "0:" ==> 1st partition on physical drive 0 */
|
|
||||||
{0, 2}, /* "1:" ==> 2nd partition on physical drive 0 */
|
|
||||||
{0, 3}, /* "2:" ==> 3rd partition on physical drive 0 */
|
|
||||||
{1, 0} /* "3:" ==> Physical drive 1 */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Get Disk Status */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DSTATUS disk_status ( BYTE drv ) /* Drive number */
|
|
||||||
{
|
|
||||||
// Ignore any drives which havent been implemented.
|
|
||||||
if (drv > SD_DEVICE_CNT) return STA_NOINIT;
|
|
||||||
|
|
||||||
// Check parameters, only 1 drive allowed.
|
|
||||||
if(drv > 0) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// Return the status of the drive.
|
|
||||||
return Stat[drv];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Initialize Disk Drive */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DSTATUS disk_initialize ( BYTE drv, /* Physical drive nmuber */
|
|
||||||
BYTE cardType ) /* 0 = SD, 1 = SDHC */
|
|
||||||
{
|
|
||||||
uint8_t ret;
|
|
||||||
|
|
||||||
// Ignore any drives which havent been implemented.
|
|
||||||
if (drv > SD_DEVICE_CNT) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// Check parameters, only 1 drive allowed.
|
|
||||||
if(drv > 0) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// Call the methods in the NXP_SDHC class to initialise and obtain the
|
|
||||||
// card type. Chip Select is embedded within this module so we dont
|
|
||||||
// need to seperately enable/disable it.
|
|
||||||
//
|
|
||||||
ret = SDHC_CardInit();
|
|
||||||
card_type = SDHC_CardGetType();
|
|
||||||
|
|
||||||
// Activate the drive within the Fat module if an OK result was obtained.
|
|
||||||
if(ret == 0)
|
|
||||||
Stat[drv] = 0;
|
|
||||||
|
|
||||||
// Return the status of the drive.
|
|
||||||
return Stat[drv];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DRESULT disk_read ( BYTE drv, /* Physical drive nmuber (0) */
|
|
||||||
BYTE *buff, /* Pointer to the data buffer to store read data */
|
|
||||||
DWORD sector, /* Start sector number (LBA) */
|
|
||||||
UINT count ) /* Sector count (1..128) */
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
|
|
||||||
// Check the drive, if it hasnt been initialised then exit.
|
|
||||||
if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// Check parameters, only 1 drive catered for and count must be >= 1
|
|
||||||
if(drv > 0) return RES_NOTRDY;
|
|
||||||
if(count == 0) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// call the NXP method to read in a sector, loop for required number of sectors.
|
|
||||||
do {
|
|
||||||
status = SDHC_CardReadBlock(buff, sector);
|
|
||||||
|
|
||||||
buff += 512;
|
|
||||||
sector++;
|
|
||||||
} while(status == 0 && --count);
|
|
||||||
|
|
||||||
// Any status other than OK results in a FAT ERROR.
|
|
||||||
return status == 0 ? RES_OK : RES_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Write Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DRESULT disk_write ( BYTE drv, /* Physical drive nmuber (0) */
|
|
||||||
const BYTE *buff, /* Pointer to the data to be written */
|
|
||||||
DWORD sector, /* Start sector number (LBA) */
|
|
||||||
UINT count ) /* Sector count (1..128) */
|
|
||||||
{
|
|
||||||
int status;
|
|
||||||
printf("Disk write:%02x,%08lx,%08lx,%d\n", drv, buff, sector, count);
|
|
||||||
// Check the drive, if it hasnt been initialised then exit.
|
|
||||||
if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// Check parameters, only 1 drive catered for and count must be >= 1
|
|
||||||
if(drv > 0) return RES_NOTRDY;
|
|
||||||
if(count == 0) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// call the NXP method to write a sector, loop for required number of sectors.
|
|
||||||
do {
|
|
||||||
status = SDHC_CardWriteBlock(buff, sector);
|
|
||||||
buff += 512;
|
|
||||||
sector++;
|
|
||||||
} while(status == 0 && --count);
|
|
||||||
|
|
||||||
// Any status other than OK results in a FAT ERROR.
|
|
||||||
return status == 0 ? RES_OK : RES_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Miscellaneous Functions */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DRESULT disk_ioctl ( BYTE drv, /* Physical drive nmuber (0) */
|
|
||||||
BYTE ctrl, /* Control code */
|
|
||||||
void *buff ) /* Buffer to send/receive control data */
|
|
||||||
{
|
|
||||||
DRESULT res = RES_ERROR;
|
|
||||||
|
|
||||||
// Check the drive, if it hasnt been initialised then exit.
|
|
||||||
if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// Check parameters, only 1 drive catered allowed.
|
|
||||||
if(drv > 0) return RES_NOTRDY;
|
|
||||||
|
|
||||||
res = RES_ERROR;
|
|
||||||
switch (ctrl)
|
|
||||||
{
|
|
||||||
case CTRL_SYNC : // Make sure that no pending write process
|
|
||||||
res = RES_OK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GET_SECTOR_COUNT : // Get number of sectors on the disk (DWORD)
|
|
||||||
|
|
||||||
// Temporary.
|
|
||||||
*(DWORD*)buff = 16777216; // 16Gb.
|
|
||||||
res = RES_OK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GET_BLOCK_SIZE : // Get erase block size in unit of sector (DWORD)
|
|
||||||
*(DWORD*)buff = 128;
|
|
||||||
res = RES_OK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
res = RES_PARERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,376 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: sdmmc.c
|
|
||||||
// Created: June 2019
|
|
||||||
// Author(s): ChaN (framework), Philip Smart (zpu SoC customisation)
|
|
||||||
// Description: Functionality to enable connectivity between the FatFS ((C) ChaN) and the ZPU SoC
|
|
||||||
// for SD drives. The majority of SD logic exists in hardware, this module provides
|
|
||||||
// the public interfaces to interact with the hardware.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (C) 2013, ChaN, all rights reserved - framework.
|
|
||||||
// Copyright: (C) 2019 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: January 2019 - Initial script written for the STORM processor then changed to the ZPU.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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 "ff.h" /* Obtains integer types for FatFs */
|
|
||||||
#include "diskio.h" /* Common include file for FatFs and disk I/O layer */
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
/* Platform dependent macros and functions needed to be modified */
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
#if defined __K64F__
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#define uint32_t __uint32_t
|
|
||||||
#define uint16_t __uint16_t
|
|
||||||
#define uint8_t __uint8_t
|
|
||||||
#define int32_t __int32_t
|
|
||||||
#define int16_t __int16_t
|
|
||||||
#define int8_t __int8_t
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#if defined __SHARPMZ__
|
|
||||||
#include "sharpmz.h"
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
#include "uart.h"
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
Module Private Functions
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* MMC/SD command (SPI mode) */
|
|
||||||
#define CMD0 (0) /* GO_IDLE_STATE */
|
|
||||||
#define CMD1 (1) /* SEND_OP_COND */
|
|
||||||
#define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
|
|
||||||
#define CMD8 (8) /* SEND_IF_COND */
|
|
||||||
#define CMD9 (9) /* SEND_CSD */
|
|
||||||
#define CMD10 (10) /* SEND_CID */
|
|
||||||
#define CMD12 (12) /* STOP_TRANSMISSION */
|
|
||||||
#define CMD13 (13) /* SEND_STATUS */
|
|
||||||
#define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
|
|
||||||
#define CMD16 (16) /* SET_BLOCKLEN */
|
|
||||||
#define CMD17 (17) /* READ_SINGLE_BLOCK */
|
|
||||||
#define CMD18 (18) /* READ_MULTIPLE_BLOCK */
|
|
||||||
#define CMD23 (23) /* SET_BLOCK_COUNT */
|
|
||||||
#define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
|
|
||||||
#define CMD24 (24) /* WRITE_BLOCK */
|
|
||||||
#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
|
|
||||||
#define CMD32 (32) /* ERASE_ER_BLK_START */
|
|
||||||
#define CMD33 (33) /* ERASE_ER_BLK_END */
|
|
||||||
#define CMD38 (38) /* ERASE */
|
|
||||||
#define CMD55 (55) /* APP_CMD */
|
|
||||||
#define CMD58 (58) /* READ_OCR */
|
|
||||||
#define SECTOR_SIZE 512 /* Default size of an SD Sector */
|
|
||||||
|
|
||||||
static
|
|
||||||
DSTATUS Stat[SD_DEVICE_CNT] = { STA_NOINIT }; /* Disk status */
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
Public Functions
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#if defined __SHARPMZ__
|
|
||||||
// Volume to partiion map. This map specifies which Volume resides on which disk/partition.
|
|
||||||
// NB. When using the ZPU as a host on the Sharp MZ computers, the K64F hosts the SD card so the first volume will be the second on the actual physical SD card.
|
|
||||||
//
|
|
||||||
PARTITION VolToPart[FF_VOLUMES] = {
|
|
||||||
{0, 2}, /* "0:" ==> 1st partition on physical drive 0 */
|
|
||||||
{0, 3}, /* "1:" ==> 2nd partition on physical drive 0 */
|
|
||||||
{0, 4}, /* "2:" ==> 3rd partition on physical drive 0 */
|
|
||||||
{1, 1}, /* "4:" ==> Physical drive 1, 1st partition */
|
|
||||||
#if FF_VOLUMES > 4
|
|
||||||
{1, 2}, /* "5:" ==> Physical drive 1, 2nd partition */
|
|
||||||
{1, 3}, /* "6:" ==> Physical drive 1, 3rd partition */
|
|
||||||
{1, 4}, /* "7:" ==> Physical drive 1, 4th partition */
|
|
||||||
{2, 1}, /* "8:" ==> Physical drive 2, 1st partition */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
PARTITION VolToPart[FF_VOLUMES] = {
|
|
||||||
{0, 1}, /* "0:" ==> 1st partition on physical drive 0 */
|
|
||||||
{0, 2}, /* "1:" ==> 2nd partition on physical drive 0 */
|
|
||||||
{0, 3}, /* "2:" ==> 3rd partition on physical drive 0 */
|
|
||||||
{0, 4}, /* "3:" ==> 3rd partition on physical drive 0 */
|
|
||||||
#if FF_VOLUMES > 4
|
|
||||||
{1, 1}, /* "4:" ==> Physical drive 1, 1st partition */
|
|
||||||
{1, 2}, /* "5:" ==> Physical drive 1, 2nd partition */
|
|
||||||
{1, 3}, /* "6:" ==> Physical drive 1, 3rd partition */
|
|
||||||
{1, 4}, /* "7:" ==> Physical drive 1, 4th partition */
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Get Disk Status */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DSTATUS disk_status ( BYTE drv ) /* Drive number */
|
|
||||||
{
|
|
||||||
// Ignore any drives which havent been implemented.
|
|
||||||
if (drv > SD_DEVICE_CNT) return STA_NOINIT;
|
|
||||||
|
|
||||||
return Stat[drv];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Initialize Disk Drive */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DSTATUS disk_initialize ( BYTE drv, /* Physical drive nmuber */
|
|
||||||
BYTE cardType ) /* 0 = SD, 1 = SDHC */
|
|
||||||
{
|
|
||||||
//uint32_t status;
|
|
||||||
// Ignore any drives which havent been implemented.
|
|
||||||
if (drv > SD_DEVICE_CNT) return RES_NOTRDY;
|
|
||||||
|
|
||||||
#if defined __SHARPMZ__
|
|
||||||
if(mzSDInit(drv) == 0)
|
|
||||||
Stat[drv] = 0;
|
|
||||||
#else
|
|
||||||
// Set the card type.
|
|
||||||
SD_CMD(drv) = (cardType == 0 ? SD_CMD_CARDTYPE_SD : SD_CMD_CARDTYPE_SDHC );
|
|
||||||
|
|
||||||
// Issue the reset command to initialise the drive.
|
|
||||||
SD_CMD(drv) = SD_CMD_RESET;
|
|
||||||
|
|
||||||
// Setup a 5 second delay count, if this timer expires then initialisation failed.
|
|
||||||
TIMER_SECONDS_DOWN = 5;
|
|
||||||
|
|
||||||
// Wait until the drive becomes ready.
|
|
||||||
while(IS_SD_BUSY(drv) && TIMER_SECONDS_DOWN > 0);
|
|
||||||
|
|
||||||
// If there is an error code, then the drive didnt initialise.
|
|
||||||
if(!(SD_STATUS(drv) & SD_STATUS_ERROR) && TIMER_SECONDS_DOWN > 0)
|
|
||||||
Stat[drv] = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return Stat[drv];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DRESULT disk_read ( BYTE drv, /* Physical drive nmuber (0) */
|
|
||||||
BYTE *buff, /* Pointer to the data buffer to store read data */
|
|
||||||
DWORD sector, /* Start sector number (LBA) */
|
|
||||||
UINT count ) /* Sector count (1..128) */
|
|
||||||
{
|
|
||||||
uint8_t idx;
|
|
||||||
uint32_t status;
|
|
||||||
uint32_t retry = 3;
|
|
||||||
uint32_t rxCount;
|
|
||||||
|
|
||||||
// Check the drive, if it hasnt been initialised then exit.
|
|
||||||
if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// For multiple blocks we have to issue single block reads so loop for count blocks.
|
|
||||||
idx = 0;
|
|
||||||
rxCount = 0;
|
|
||||||
do {
|
|
||||||
// Setup a 5 second delay count, if this timer expires then reset and retry.
|
|
||||||
TIMER_SECONDS_DOWN = 5;
|
|
||||||
|
|
||||||
#if defined __SHARPMZ__
|
|
||||||
// When running on the Sharp MZ host, we send an SD request to the I/O processor and await the results!
|
|
||||||
do {
|
|
||||||
status = mzSDRead(drv, sector, buff);
|
|
||||||
} while(status != 0 && TIMER_SECONDS_DOWN > 0);
|
|
||||||
|
|
||||||
if(status == 0)
|
|
||||||
{
|
|
||||||
sector = sector + SECTOR_SIZE;
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Set the sector to retrieve.
|
|
||||||
SD_ADDR(drv) = sector;
|
|
||||||
SD_CMD(drv) = SD_CMD_READ;
|
|
||||||
|
|
||||||
// Receive all bytes until Busy goes inactive or timer timesout.
|
|
||||||
do {
|
|
||||||
status = SD_STATUS(drv);
|
|
||||||
if(status & SD_STATUS_DATA_VALID)
|
|
||||||
{
|
|
||||||
*(BYTE *)(buff) = (uint8_t)SD_DATA(drv);
|
|
||||||
buff++;
|
|
||||||
rxCount++;
|
|
||||||
}
|
|
||||||
} while((status & (SD_STATUS_BUSY|SD_STATUS_DATA_VALID)) != 0 && rxCount < SECTOR_SIZE && TIMER_SECONDS_DOWN > 0);
|
|
||||||
|
|
||||||
// If we exitted due to a timeout, retry. If no more retries available, exit with last error.
|
|
||||||
if(TIMER_SECONDS_DOWN == 0 || rxCount != SECTOR_SIZE)
|
|
||||||
{
|
|
||||||
// Issue the reset command to initialise the drive.
|
|
||||||
SD_CMD(drv) = SD_CMD_RESET;
|
|
||||||
|
|
||||||
// Wait until the drive becomes ready.
|
|
||||||
while(IS_SD_BUSY(drv));
|
|
||||||
|
|
||||||
retry--;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
sector = sector + SECTOR_SIZE;
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(retry == 0) break;
|
|
||||||
if(status & SD_STATUS_ERROR) break;
|
|
||||||
#endif
|
|
||||||
} while( idx < count );
|
|
||||||
|
|
||||||
// Return error if the last read failed.
|
|
||||||
return status & SD_STATUS_ERROR ? RES_ERROR : RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Write Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DRESULT disk_write ( BYTE drv, /* Physical drive nmuber (0) */
|
|
||||||
const BYTE *buff, /* Pointer to the data to be written */
|
|
||||||
DWORD sector, /* Start sector number (LBA) */
|
|
||||||
UINT count ) /* Sector count (1..128) */
|
|
||||||
{
|
|
||||||
uint8_t idx;
|
|
||||||
uint32_t status;
|
|
||||||
uint32_t retry = 3;
|
|
||||||
uint32_t txCount = 0;
|
|
||||||
|
|
||||||
// Check the drive, if it hasnt been initialised then exit.
|
|
||||||
if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// For multiple blocks we have to issue single block writes so loop for count blocks.
|
|
||||||
idx = 0;
|
|
||||||
do {
|
|
||||||
// Setup a 5 second delay count, if this timer expires then reset and retry.
|
|
||||||
TIMER_SECONDS_DOWN = 5;
|
|
||||||
|
|
||||||
#if defined __SHARPMZ__
|
|
||||||
// When running on the Sharp MZ host, we send an SD request to the I/O processor and await the results!
|
|
||||||
do {
|
|
||||||
status = mzSDWrite(drv, sector, buff);
|
|
||||||
} while(status != 0 && TIMER_SECONDS_DOWN > 0);
|
|
||||||
|
|
||||||
if(status == 0)
|
|
||||||
{
|
|
||||||
sector = sector + SECTOR_SIZE;
|
|
||||||
idx++;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
// Set the sector to retrieve.
|
|
||||||
SD_ADDR(drv) = sector;
|
|
||||||
SD_CMD(drv) = SD_CMD_WRITE;
|
|
||||||
|
|
||||||
// Send bytes upto sector limit or until busy goes inactive or timer times out.
|
|
||||||
txCount = 0;
|
|
||||||
do {
|
|
||||||
status = SD_STATUS(drv);
|
|
||||||
|
|
||||||
if(status & SD_STATUS_DATA_REQ)
|
|
||||||
{
|
|
||||||
SD_DATA(drv) = *buff;
|
|
||||||
buff++;
|
|
||||||
txCount++;
|
|
||||||
}
|
|
||||||
} while((status & SD_STATUS_BUSY) && TIMER_SECONDS_DOWN > 0);
|
|
||||||
|
|
||||||
// If we exitted due to a timeout, retry. If no more retries available, exit with last error.
|
|
||||||
if(TIMER_SECONDS_DOWN == 0 || txCount != SECTOR_SIZE)
|
|
||||||
{
|
|
||||||
// Issue the reset command to initialise the drive.
|
|
||||||
SD_CMD(drv) = SD_CMD_RESET;
|
|
||||||
|
|
||||||
// Wait until the drive becomes ready.
|
|
||||||
while(IS_SD_BUSY(drv));
|
|
||||||
retry--;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
idx++;
|
|
||||||
sector = sector + SECTOR_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(retry == 0) break;
|
|
||||||
if(status & SD_STATUS_ERROR) break;
|
|
||||||
#endif
|
|
||||||
} while (idx < count);
|
|
||||||
|
|
||||||
// Return error if the last write failed.
|
|
||||||
return status & SD_STATUS_ERROR ? RES_ERROR : RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Miscellaneous Functions */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DRESULT disk_ioctl ( BYTE drv, /* Physical drive nmuber (0) */
|
|
||||||
BYTE ctrl, /* Control code */
|
|
||||||
void *buff ) /* Buffer to send/receive control data */
|
|
||||||
{
|
|
||||||
DRESULT res;
|
|
||||||
uint32_t status;
|
|
||||||
|
|
||||||
// Check the drive, if it hasnt been initialised then exit.
|
|
||||||
if (disk_status(drv) & STA_NOINIT) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// Setup a 5 second delay count, if this timer expires then we have an error.
|
|
||||||
TIMER_SECONDS_DOWN = 5;
|
|
||||||
|
|
||||||
res = RES_ERROR;
|
|
||||||
switch (ctrl)
|
|
||||||
{
|
|
||||||
case CTRL_SYNC : /* Make sure that no pending write process */
|
|
||||||
// Wait until the drive becomes available or we timeout.
|
|
||||||
do {
|
|
||||||
status = SD_STATUS(drv);
|
|
||||||
} while((status & SD_STATUS_BUSY) && TIMER_SECONDS_DOWN > 0);
|
|
||||||
|
|
||||||
// If we timed out then an error has occurred, so reset the drive and return error code.
|
|
||||||
if(TIMER_SECONDS_DOWN == 0)
|
|
||||||
{
|
|
||||||
// Issue the reset command to initialise the drive.
|
|
||||||
SD_CMD(drv) = SD_CMD_RESET;
|
|
||||||
|
|
||||||
// Wait until the drive becomes ready.
|
|
||||||
while(IS_SD_BUSY(drv));
|
|
||||||
} else
|
|
||||||
res = RES_OK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GET_SECTOR_COUNT : /* Get number of sectors on the disk (DWORD) */
|
|
||||||
|
|
||||||
// Temporary.
|
|
||||||
*(DWORD*)buff = 2097152; // 1Gb.
|
|
||||||
res = RES_OK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GET_BLOCK_SIZE : /* Get erase block size in unit of sector (DWORD) */
|
|
||||||
*(DWORD*)buff = 128;
|
|
||||||
res = RES_OK;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
res = RES_PARERR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
53
zOS/MZ2000/common/PetitFS/00readme.txt
vendored
53
zOS/MZ2000/common/PetitFS/00readme.txt
vendored
@@ -1,53 +0,0 @@
|
|||||||
Petit FatFs Module Source Files R0.03a (C)ChaN, 2019
|
|
||||||
|
|
||||||
|
|
||||||
FILES
|
|
||||||
|
|
||||||
pff.h Common include file for Petit FatFs and application module.
|
|
||||||
pff.c Petit FatFs module.
|
|
||||||
diskio.h Common include file for Petit FatFs and disk I/O module.
|
|
||||||
diskio.c Skeleton of low level disk I/O module.
|
|
||||||
|
|
||||||
Low level disk I/O module is not included in this archive because the Petit
|
|
||||||
FatFs module is only a generic file system layer and not depend on any
|
|
||||||
specific storage device. You have to provide a low level disk I/O module that
|
|
||||||
written to control your storage device.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
AGREEMENTS
|
|
||||||
|
|
||||||
Petit FatFs module is an open source software to implement FAT file system to
|
|
||||||
small embedded systems. This is a free software and is opened for education,
|
|
||||||
research and commercial developments under license policy of following trems.
|
|
||||||
|
|
||||||
Copyright (C) 2019, ChaN, all right reserved.
|
|
||||||
|
|
||||||
* The Petit FatFs module is a free software and there is NO WARRANTY.
|
|
||||||
* No restriction on use. You can use, modify and redistribute it for
|
|
||||||
personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
|
|
||||||
* Redistributions of source code must retain the above copyright notice.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
REVISION HISTORY
|
|
||||||
|
|
||||||
Jun 15, 2009 R0.01a First release (Branched from FatFs R0.07b)
|
|
||||||
|
|
||||||
Dec 14, 2009 R0.02 Added multiple code page support.
|
|
||||||
Added write funciton.
|
|
||||||
Changed stream read mode interface.
|
|
||||||
|
|
||||||
Dec 07,'2010 R0.02a Added some configuration options.
|
|
||||||
Fixed fails to open objects with DBCS character.
|
|
||||||
|
|
||||||
Jun 10, 2014 R0.03 Separated out configuration options to pffconf.h.
|
|
||||||
Added _USE_LCC option.
|
|
||||||
Added _FS_FAT16 option.
|
|
||||||
|
|
||||||
Jan 30, 2019 R0.03a Supported stdint.h for C99 and later.
|
|
||||||
Removed _WORD_ACCESS option.
|
|
||||||
Changed prefix of configuration options, _ to PF_.
|
|
||||||
Added some code pages.
|
|
||||||
Removed some code pages actually not valid.
|
|
||||||
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Low level disk I/O module skeleton for Petit FatFs (C)ChaN, 2014 */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "diskio.h"
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Initialize Disk Drive */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DSTATUS disk_initialize (void)
|
|
||||||
{
|
|
||||||
DSTATUS stat;
|
|
||||||
|
|
||||||
// Put your code here
|
|
||||||
|
|
||||||
return stat;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read Partial Sector */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DRESULT disk_readp (
|
|
||||||
BYTE* buff, /* Pointer to the destination object */
|
|
||||||
DWORD sector, /* Sector number (LBA) */
|
|
||||||
UINT offset, /* Offset in the sector */
|
|
||||||
UINT count /* Byte count (bit15:destination) */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DRESULT res;
|
|
||||||
|
|
||||||
// Put your code here
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Write Partial Sector */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DRESULT disk_writep (
|
|
||||||
BYTE* buff, /* Pointer to the data to be written, NULL:Initiate/Finalize write operation */
|
|
||||||
DWORD sc /* Sector number (LBA) or Number of bytes to send */
|
|
||||||
)
|
|
||||||
{
|
|
||||||
DRESULT res;
|
|
||||||
|
|
||||||
|
|
||||||
if (!buff) {
|
|
||||||
if (sc) {
|
|
||||||
|
|
||||||
// Initiate write process
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Finalize write process
|
|
||||||
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
|
|
||||||
// Send data to the disk
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
42
zOS/MZ2000/common/PetitFS/diskio.h
vendored
42
zOS/MZ2000/common/PetitFS/diskio.h
vendored
@@ -1,42 +0,0 @@
|
|||||||
/*-----------------------------------------------------------------------
|
|
||||||
/ PFF - Low level disk interface modlue include file (C)ChaN, 2014
|
|
||||||
/-----------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef _DISKIO_DEFINED
|
|
||||||
#define _DISKIO_DEFINED
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pff.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* Status of Disk Functions */
|
|
||||||
typedef BYTE DSTATUS;
|
|
||||||
|
|
||||||
|
|
||||||
/* Results of Disk Functions */
|
|
||||||
typedef enum {
|
|
||||||
RES_OK = 0, /* 0: Function succeeded */
|
|
||||||
RES_ERROR, /* 1: Disk error */
|
|
||||||
RES_NOTRDY, /* 2: Not ready */
|
|
||||||
RES_PARERR /* 3: Invalid parameter */
|
|
||||||
} DRESULT;
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------*/
|
|
||||||
/* Prototypes for disk control functions */
|
|
||||||
|
|
||||||
DSTATUS disk_initialize (void);
|
|
||||||
DRESULT disk_readp (BYTE* buff, DWORD sector, UINT offser, UINT count);
|
|
||||||
DRESULT disk_writep (const BYTE* buff, DWORD sc);
|
|
||||||
|
|
||||||
#define STA_NOINIT 0x01 /* Drive not initialized */
|
|
||||||
#define STA_NODISK 0x02 /* No medium in the drive */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _DISKIO_DEFINED */
|
|
||||||
File diff suppressed because it is too large
Load Diff
163
zOS/MZ2000/common/PetitFS/pff.h
vendored
163
zOS/MZ2000/common/PetitFS/pff.h
vendored
@@ -1,163 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Petit FatFs - FAT file system module include file R0.03a
|
|
||||||
/----------------------------------------------------------------------------/
|
|
||||||
/ Petit FatFs module is an open source software to implement FAT file system to
|
|
||||||
/ small embedded systems. This is a free software and is opened for education,
|
|
||||||
/ research and commercial developments under license policy of following trems.
|
|
||||||
/
|
|
||||||
/ Copyright (C) 2019, ChaN, all right reserved.
|
|
||||||
/
|
|
||||||
/ * The Petit FatFs module is a free software and there is NO WARRANTY.
|
|
||||||
/ * No restriction on use. You can use, modify and redistribute it for
|
|
||||||
/ personal, non-profit or commercial use UNDER YOUR RESPONSIBILITY.
|
|
||||||
/ * Redistributions of source code must retain the above copyright notice.
|
|
||||||
/
|
|
||||||
/----------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef PF_DEFINED
|
|
||||||
#define PF_DEFINED 8088 /* Revision ID */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "pffconf.h"
|
|
||||||
|
|
||||||
#if PF_DEFINED != PFCONF_DEF
|
|
||||||
#error Wrong configuration file (pffconf.h).
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* Integer types used for FatFs API */
|
|
||||||
|
|
||||||
#if defined(_WIN32) /* Main development platform */
|
|
||||||
#include <windows.h>
|
|
||||||
#elif (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || defined(__cplusplus) /* C99 or later */
|
|
||||||
#include <stdint.h>
|
|
||||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
|
||||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
|
||||||
typedef uint16_t WORD; /* 16-bit unsigned integer */
|
|
||||||
typedef uint16_t WCHAR; /* 16-bit unsigned integer */
|
|
||||||
typedef uint32_t DWORD; /* 32-bit unsigned integer */
|
|
||||||
#else /* Earlier than C99 */
|
|
||||||
typedef unsigned int UINT; /* int must be 16-bit or 32-bit */
|
|
||||||
typedef unsigned char BYTE; /* char must be 8-bit */
|
|
||||||
typedef unsigned short WORD; /* 16-bit unsigned integer */
|
|
||||||
typedef unsigned short WCHAR; /* 16-bit unsigned integer */
|
|
||||||
typedef unsigned long DWORD; /* 32-bit unsigned integer */
|
|
||||||
#endif
|
|
||||||
#define PF_INTDEF 1
|
|
||||||
|
|
||||||
|
|
||||||
#if PF_FS_FAT32
|
|
||||||
#define CLUST DWORD
|
|
||||||
#else
|
|
||||||
#define CLUST WORD
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
/* File system object structure */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
BYTE fs_type; /* FAT sub type */
|
|
||||||
BYTE flag; /* File status flags */
|
|
||||||
BYTE csize; /* Number of sectors per cluster */
|
|
||||||
BYTE pad1;
|
|
||||||
WORD n_rootdir; /* Number of root directory entries (0 on FAT32) */
|
|
||||||
CLUST n_fatent; /* Number of FAT entries (= number of clusters + 2) */
|
|
||||||
DWORD fatbase; /* FAT start sector */
|
|
||||||
DWORD dirbase; /* Root directory start sector (Cluster# on FAT32) */
|
|
||||||
DWORD database; /* Data start sector */
|
|
||||||
DWORD fptr; /* File R/W pointer */
|
|
||||||
DWORD fsize; /* File size */
|
|
||||||
CLUST org_clust; /* File start cluster */
|
|
||||||
CLUST curr_clust; /* File current cluster */
|
|
||||||
DWORD dsect; /* File current data sector */
|
|
||||||
} FATFS;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* Directory object structure */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
WORD index; /* Current read/write index number */
|
|
||||||
BYTE* fn; /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
|
|
||||||
CLUST sclust; /* Table start cluster (0:Static table) */
|
|
||||||
CLUST clust; /* Current cluster */
|
|
||||||
DWORD sect; /* Current sector */
|
|
||||||
} DIR;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File status structure */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
DWORD fsize; /* File size */
|
|
||||||
WORD fdate; /* Last modified date */
|
|
||||||
WORD ftime; /* Last modified time */
|
|
||||||
BYTE fattrib; /* Attribute */
|
|
||||||
char fname[13]; /* File name */
|
|
||||||
} FILINFO;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* File function return code (FRESULT) */
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
FR_OK = 0, /* 0 */
|
|
||||||
FR_DISK_ERR, /* 1 */
|
|
||||||
FR_NOT_READY, /* 2 */
|
|
||||||
FR_NO_FILE, /* 3 */
|
|
||||||
FR_NOT_OPENED, /* 4 */
|
|
||||||
FR_NOT_ENABLED, /* 5 */
|
|
||||||
FR_NO_FILESYSTEM /* 6 */
|
|
||||||
} FRESULT;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------*/
|
|
||||||
/* Petit FatFs module application interface */
|
|
||||||
|
|
||||||
FRESULT pf_mount (FATFS* fs); /* Mount/Unmount a logical drive */
|
|
||||||
FRESULT pf_open (const char* path); /* Open a file */
|
|
||||||
FRESULT pf_read (void* buff, UINT btr, UINT* br); /* Read data from the open file */
|
|
||||||
FRESULT pf_write (const void* buff, UINT btw, UINT* bw); /* Write data to the open file */
|
|
||||||
FRESULT pf_lseek (DWORD ofs); /* Move file pointer of the open file */
|
|
||||||
FRESULT pf_opendir (DIR* dj, const char* path); /* Open a directory */
|
|
||||||
FRESULT pf_readdir (DIR* dj, FILINFO* fno); /* Read a directory item from the open directory */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------*/
|
|
||||||
/* Flags and offset address */
|
|
||||||
|
|
||||||
|
|
||||||
/* File status flag (FATFS.flag) */
|
|
||||||
#define FA_OPENED 0x01
|
|
||||||
#define FA_WPRT 0x02
|
|
||||||
#define FA__WIP 0x40
|
|
||||||
|
|
||||||
|
|
||||||
/* FAT sub type (FATFS.fs_type) */
|
|
||||||
#define FS_FAT12 1
|
|
||||||
#define FS_FAT16 2
|
|
||||||
#define FS_FAT32 3
|
|
||||||
|
|
||||||
|
|
||||||
/* File attribute bits for directory entry */
|
|
||||||
|
|
||||||
#define AM_RDO 0x01 /* Read only */
|
|
||||||
#define AM_HID 0x02 /* Hidden */
|
|
||||||
#define AM_SYS 0x04 /* System */
|
|
||||||
#define AM_VOL 0x08 /* Volume label */
|
|
||||||
#define AM_LFN 0x0F /* LFN entry */
|
|
||||||
#define AM_DIR 0x10 /* Directory */
|
|
||||||
#define AM_ARC 0x20 /* Archive */
|
|
||||||
#define AM_MASK 0x3F /* Mask of defined bits */
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _PFATFS */
|
|
||||||
58
zOS/MZ2000/common/PetitFS/pffconf.h
vendored
58
zOS/MZ2000/common/PetitFS/pffconf.h
vendored
@@ -1,58 +0,0 @@
|
|||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Petit FatFs - Configuration file
|
|
||||||
/---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#ifndef PFCONF_DEF
|
|
||||||
#define PFCONF_DEF 8088 /* Revision ID */
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Function Configurations (0:Disable, 1:Enable)
|
|
||||||
/---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define PF_USE_READ 1 /* pf_read() function */
|
|
||||||
#define PF_USE_DIR 1 /* pf_opendir() and pf_readdir() function */
|
|
||||||
#define PF_USE_LSEEK 1 /* pf_lseek() function */
|
|
||||||
#define PF_USE_WRITE 1 /* pf_write() function */
|
|
||||||
|
|
||||||
#define PF_FS_FAT12 0 /* FAT12 */
|
|
||||||
#define PF_FS_FAT16 1 /* FAT16 */
|
|
||||||
#define PF_FS_FAT32 1 /* FAT32 */
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------/
|
|
||||||
/ Locale and Namespace Configurations
|
|
||||||
/---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#define PF_USE_LCC 0 /* Allow lower case ASCII and non-ASCII chars */
|
|
||||||
|
|
||||||
#define PF_CODE_PAGE 437
|
|
||||||
/* The PF_CODE_PAGE specifies the code page to be used on the target system.
|
|
||||||
/ SBCS code pages with PF_USE_LCC == 1 requiers a 128 byte of case conversion
|
|
||||||
/ table. It might occupy RAM on some platforms, e.g. avr-gcc.
|
|
||||||
/ When PF_USE_LCC == 0, PF_CODE_PAGE has no effect.
|
|
||||||
/
|
|
||||||
/ 437 - U.S.
|
|
||||||
/ 720 - Arabic
|
|
||||||
/ 737 - Greek
|
|
||||||
/ 771 - KBL
|
|
||||||
/ 775 - Baltic
|
|
||||||
/ 850 - Latin 1
|
|
||||||
/ 852 - Latin 2
|
|
||||||
/ 855 - Cyrillic
|
|
||||||
/ 857 - Turkish
|
|
||||||
/ 860 - Portuguese
|
|
||||||
/ 861 - Icelandic
|
|
||||||
/ 862 - Hebrew
|
|
||||||
/ 863 - Canadian French
|
|
||||||
/ 864 - Arabic
|
|
||||||
/ 865 - Nordic
|
|
||||||
/ 866 - Russian
|
|
||||||
/ 869 - Greek 2
|
|
||||||
/ 932 - Japanese (DBCS)
|
|
||||||
/ 936 - Simplified Chinese (DBCS)
|
|
||||||
/ 949 - Korean (DBCS)
|
|
||||||
/ 950 - Traditional Chinese (DBCS)
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
#endif /* PF_CONF */
|
|
||||||
@@ -1,219 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: sdmmc.c
|
|
||||||
// Created: June 2019
|
|
||||||
// Author(s): ChaN (framework), Philip Smart (zpu SoC customisation)
|
|
||||||
// Description: Functionality to enable connectivity between the PetitFS ((C) ChaN) and the ZPU SoC
|
|
||||||
// for SD drives. The majority of SD logic exists in hardware, this module provides
|
|
||||||
// the public interfaces to interact with the hardware.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (C) 2013, ChaN, all rights reserved - framework.
|
|
||||||
// Copyright: (C) 2019 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: January 2019 - Initial script written for the STORM processor then changed to the ZPU.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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 "pff.h" /* Obtains integer types for Petit FatFs */
|
|
||||||
#include "diskio.h" /* Common include file for FatFs and disk I/O layer */
|
|
||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
/* Platform dependent macros and functions needed to be modified */
|
|
||||||
/*-------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
#if defined __K64F__
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#define uint32_t __uint32_t
|
|
||||||
#define uint16_t __uint16_t
|
|
||||||
#define uint8_t __uint8_t
|
|
||||||
#define int32_t __int32_t
|
|
||||||
#define int16_t __int16_t
|
|
||||||
#define int8_t __int8_t
|
|
||||||
#else
|
|
||||||
#include <zpu-types.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
#include "uart.h"
|
|
||||||
//#include "utils.h"
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
Module Private Functions
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* MMC/SD command (SPI mode) */
|
|
||||||
#define CMD0 (0) /* GO_IDLE_STATE */
|
|
||||||
#define CMD1 (1) /* SEND_OP_COND */
|
|
||||||
#define ACMD41 (0x80+41) /* SEND_OP_COND (SDC) */
|
|
||||||
#define CMD8 (8) /* SEND_IF_COND */
|
|
||||||
#define CMD9 (9) /* SEND_CSD */
|
|
||||||
#define CMD10 (10) /* SEND_CID */
|
|
||||||
#define CMD12 (12) /* STOP_TRANSMISSION */
|
|
||||||
#define CMD13 (13) /* SEND_STATUS */
|
|
||||||
#define ACMD13 (0x80+13) /* SD_STATUS (SDC) */
|
|
||||||
#define CMD16 (16) /* SET_BLOCKLEN */
|
|
||||||
#define CMD17 (17) /* READ_SINGLE_BLOCK */
|
|
||||||
#define CMD18 (18) /* READ_MULTIPLE_BLOCK */
|
|
||||||
#define CMD23 (23) /* SET_BLOCK_COUNT */
|
|
||||||
#define ACMD23 (0x80+23) /* SET_WR_BLK_ERASE_COUNT (SDC) */
|
|
||||||
#define CMD24 (24) /* WRITE_BLOCK */
|
|
||||||
#define CMD25 (25) /* WRITE_MULTIPLE_BLOCK */
|
|
||||||
#define CMD32 (32) /* ERASE_ER_BLK_START */
|
|
||||||
#define CMD33 (33) /* ERASE_ER_BLK_END */
|
|
||||||
#define CMD38 (38) /* ERASE */
|
|
||||||
#define CMD55 (55) /* APP_CMD */
|
|
||||||
#define CMD58 (58) /* READ_OCR */
|
|
||||||
#define SECTOR_SIZE 512 /* Default size of an SD Sector */
|
|
||||||
|
|
||||||
static
|
|
||||||
DSTATUS Stat = STA_NOINIT; /* Disk status */
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------
|
|
||||||
Public Functions
|
|
||||||
---------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Initialize Disk Drive */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DSTATUS disk_initialize ( void )
|
|
||||||
{
|
|
||||||
uint32_t status;
|
|
||||||
//puts("In disk init\n");
|
|
||||||
// Set the card type.
|
|
||||||
SD_CMD(0) = SD_CMD_CARDTYPE_SDHC;
|
|
||||||
|
|
||||||
//puts("In disk init 1\n");
|
|
||||||
// Issue the reset command to initialise the drive.
|
|
||||||
SD_CMD(0) = SD_CMD_RESET;
|
|
||||||
|
|
||||||
//puts("In disk init 2\n");
|
|
||||||
// Setup a 5 second delay count, if this timer expires then initialisation failed.
|
|
||||||
TIMER_SECONDS_DOWN = 5;
|
|
||||||
|
|
||||||
//puts("In disk init 3\n");
|
|
||||||
// Wait until the drive becomes ready.
|
|
||||||
while(IS_SD_BUSY(0) && TIMER_SECONDS_DOWN > 0);
|
|
||||||
|
|
||||||
//puts("In disk init 4\n");
|
|
||||||
// If there is an error code, then the drive didnt initialise.
|
|
||||||
if(!(SD_STATUS(0) & SD_STATUS_ERROR) && TIMER_SECONDS_DOWN > 0)
|
|
||||||
Stat = 0;
|
|
||||||
|
|
||||||
//puts("In disk init 5\n");
|
|
||||||
return Stat;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Read Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DRESULT disk_readp( BYTE *buff, /* Pointer to the data buffer to store read data */
|
|
||||||
DWORD sector, /* Start sector number (LBA) */
|
|
||||||
UINT offset, /* Byte offset to read from (0..511) */
|
|
||||||
UINT count ) /* Number of bytes to read (ofs + cnt mus be <= 512) */
|
|
||||||
{
|
|
||||||
BYTE data;
|
|
||||||
uint32_t status;
|
|
||||||
uint32_t rxCount = 0;
|
|
||||||
|
|
||||||
// Check the drive, if it hasnt been initialised then exit.
|
|
||||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// Setup a 5 second delay count, if this timer expires then reset and retry.
|
|
||||||
TIMER_SECONDS_DOWN = 5;
|
|
||||||
|
|
||||||
// Set the sector to retrieve.
|
|
||||||
SD_ADDR(0) = sector;
|
|
||||||
SD_CMD(0) = SD_CMD_READ;
|
|
||||||
|
|
||||||
// Receive all bytes until Busy goes inactive or timer timesout.
|
|
||||||
do {
|
|
||||||
status = SD_STATUS(0);
|
|
||||||
if(status & SD_STATUS_DATA_VALID)
|
|
||||||
{
|
|
||||||
data = (uint8_t)SD_DATA(0);
|
|
||||||
if(rxCount >= offset && count > 0)
|
|
||||||
{
|
|
||||||
*(BYTE *)(buff) = data;
|
|
||||||
buff++;
|
|
||||||
count--;
|
|
||||||
}
|
|
||||||
rxCount++;
|
|
||||||
}
|
|
||||||
} while((status & (SD_STATUS_BUSY|SD_STATUS_DATA_VALID)) != 0 && TIMER_SECONDS_DOWN > 0);
|
|
||||||
|
|
||||||
// If we exitted due to a timeout reset and exit with last error.
|
|
||||||
if(TIMER_SECONDS_DOWN == 0)
|
|
||||||
{
|
|
||||||
// Issue the reset command to initialise the drive.
|
|
||||||
SD_CMD(0) = SD_CMD_RESET;
|
|
||||||
|
|
||||||
// Wait until the drive becomes ready.
|
|
||||||
while(IS_SD_BUSY(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return error if the last read failed.
|
|
||||||
return status & SD_STATUS_ERROR ? RES_ERROR : TIMER_SECONDS_DOWN == 0 ? RES_ERROR : RES_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
/* Write Sector(s) */
|
|
||||||
/*-----------------------------------------------------------------------*/
|
|
||||||
DRESULT disk_writep( const BYTE *buff, /* Pointer to the data to be written */
|
|
||||||
DWORD sector ) /* Start sector number (LBA) or Number of bytes to send */
|
|
||||||
{
|
|
||||||
uint32_t status;
|
|
||||||
uint32_t txCount = 0;
|
|
||||||
|
|
||||||
// Check the drive, if it hasnt been initialised then exit.
|
|
||||||
if (Stat & STA_NOINIT) return RES_NOTRDY;
|
|
||||||
|
|
||||||
// Setup a 5 second delay count, if this timer expires then reset and retry.
|
|
||||||
TIMER_SECONDS_DOWN = 5;
|
|
||||||
|
|
||||||
// Set the sector to retrieve.
|
|
||||||
SD_ADDR(0) = sector;
|
|
||||||
SD_CMD(0) = SD_CMD_WRITE;
|
|
||||||
|
|
||||||
// Send bytes upto sector limit or until busy goes inactive or timer times out.
|
|
||||||
txCount = 0;
|
|
||||||
do {
|
|
||||||
status = SD_STATUS(0);
|
|
||||||
|
|
||||||
if(status & SD_STATUS_DATA_REQ)
|
|
||||||
{
|
|
||||||
SD_DATA(0) = *buff;
|
|
||||||
buff++;
|
|
||||||
txCount++;
|
|
||||||
}
|
|
||||||
} while((status & SD_STATUS_BUSY) && TIMER_SECONDS_DOWN > 0);
|
|
||||||
|
|
||||||
// If we exitted due to a timeout reset and exit with last error.
|
|
||||||
if(TIMER_SECONDS_DOWN == 0)
|
|
||||||
{
|
|
||||||
// Issue the reset command to initialise the drive.
|
|
||||||
SD_CMD(0) = SD_CMD_RESET;
|
|
||||||
|
|
||||||
// Wait until the drive becomes ready.
|
|
||||||
while(IS_SD_BUSY(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return error if the last write failed.
|
|
||||||
return status & SD_STATUS_ERROR ? RES_ERROR : TIMER_SECONDS_DOWN == 0 ? RES_ERROR : RES_OK;
|
|
||||||
}
|
|
||||||
@@ -1,73 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: bitmaps.c
|
|
||||||
// Created: May 2021
|
|
||||||
// Version: v1.0
|
|
||||||
// Author(s): Philip Smart
|
|
||||||
// Description: The Bitmap Library.
|
|
||||||
// This is a bitmap definition and manipulation library.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2018-2021 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: v1.0 May 2021 - Initial write of the font software.
|
|
||||||
//
|
|
||||||
// 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 <core_pins.h>
|
|
||||||
#include <usb_serial.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 "ff.h" /* Declarations of FatFs API */
|
|
||||||
#include "diskio.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include <bitmaps.h>
|
|
||||||
|
|
||||||
#ifndef __APP__ // Protected methods which should only reside in the kernel on zOS.
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
/*
|
|
||||||
* argo128x64.c
|
|
||||||
*
|
|
||||||
* Sharp Argo logo (medium).
|
|
||||||
*
|
|
||||||
* Created: 8/7/2021
|
|
||||||
* Author: Philip Smart
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <core_pins.h>
|
|
||||||
#include <usb_serial.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 "bitmaps.h"
|
|
||||||
|
|
||||||
#define BITMAP_WIDTH 128
|
|
||||||
#define BITMAP_HEIGHT 64
|
|
||||||
|
|
||||||
static const uint8_t argo128x64Data[((BITMAP_WIDTH * BITMAP_HEIGHT)/8)+1]= {
|
|
||||||
0x00,0x00,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xc0
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xf0,0x00,0x00,0x00,0x00,0x03,0xe7,0xff,0xe0
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0x80,0x00,0x00,0x00,0x00,0x07,0xfc,0x0f,0xe0
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xc0,0x00,0x00,0x00,0x00,0x03,0xf0,0x3d,0x80
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x1d,0xc0,0x00,0x00,0x00,0x00,0x00,0x18,0xf1,0x80
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x1d,0xe0,0x00,0x00,0x00,0x07,0x00,0x07,0xc1,0x80
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0xf0,0x00,0x00,0x00,0x7f,0xcf,0x0f,0xc3,0x80
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0xb0,0x00,0x00,0x00,0xff,0xcf,0xe0,0x77,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0xd8,0x00,0x00,0x03,0x8f,0x8f,0xe0,0x1f,0x80
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0xd8,0xdc,0x00,0x00,0x0f,0xe6,0x38,0x0e,0x1f,0x80
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x01,0xd8,0xee,0x00,0x00,0x0f,0xec,0x63,0xff,0x02,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x01,0xd8,0xe6,0x00,0x00,0x0f,0xe0,0xfe,0x0f,0x80,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x03,0x98,0x67,0x00,0x00,0x00,0x27,0xff,0x93,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x03,0xb8,0x73,0x80,0x00,0x03,0x8f,0xff,0xee,0x80,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x07,0x38,0x73,0xc0,0x00,0x03,0xcf,0x83,0xe7,0x80,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x0f,0x38,0x71,0xc0,0x00,0x01,0xef,0xc3,0xe7,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x0e,0x78,0x38,0xe0,0x00,0x00,0x07,0xff,0xe0,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x1e,0x78,0x38,0xf0,0x00,0x07,0x81,0xff,0x80,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x3c,0x78,0x3c,0x78,0x00,0x1e,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x3c,0x78,0x1c,0x38,0x00,0xf8,0x00,0x7f,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x78,0xf0,0x1c,0x3c,0x03,0xe0,0x00,0xff,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0xf8,0xf0,0x1e,0x1e,0x0f,0x80,0x03,0xff,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0xf0,0xf0,0x1e,0x3f,0x3e,0x00,0x0f,0xff,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x01,0xf0,0xf0,0x3f,0xff,0xf8,0x00,0x7f,0xff,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x03,0xe3,0xff,0xff,0xc1,0xf0,0x07,0xff,0xff,0x00,0x00,0x00
|
|
||||||
,0x00,0x3f,0xe0,0x00,0x1f,0xff,0xfe,0x00,0x00,0x7f,0xff,0xff,0xff,0x00,0x00,0x00
|
|
||||||
,0x00,0x7f,0xff,0xff,0xff,0xfc,0x00,0x00,0x07,0xff,0xff,0xff,0xff,0x00,0x00,0x00
|
|
||||||
,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00
|
|
||||||
,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00
|
|
||||||
,0x03,0xfe,0x00,0xff,0x00,0x3f,0xc0,0x1f,0xf0,0x07,0xff,0xff,0xfe,0x00,0x00,0x00
|
|
||||||
,0x03,0xf8,0xfe,0x3c,0x3f,0x1f,0x0f,0xc7,0xc3,0xe1,0xff,0xff,0xfc,0x00,0x00,0x00
|
|
||||||
,0x03,0xf1,0xff,0x1c,0xff,0xcf,0x3f,0xf3,0x8f,0xf8,0xff,0xff,0xfc,0x00,0x00,0x00
|
|
||||||
,0x03,0xf1,0xff,0x1c,0x7f,0xc6,0x3f,0xf3,0x8f,0xf8,0xff,0xff,0xf8,0x00,0x00,0x00
|
|
||||||
,0x03,0xf8,0xff,0x1c,0x7f,0x8f,0x1f,0xe3,0xc7,0xf8,0xff,0xff,0xf0,0x00,0x00,0x00
|
|
||||||
,0x01,0xfc,0x0e,0x3e,0x0f,0x9f,0x83,0xf3,0xe1,0xfe,0x7f,0xff,0xe0,0x00,0x00,0x00
|
|
||||||
,0x01,0xff,0x87,0x7f,0xc1,0xcf,0xf0,0x39,0xf8,0x07,0xbf,0xff,0xc0,0x00,0x00,0x00
|
|
||||||
,0x01,0xff,0xf3,0x3f,0xfc,0xe7,0xff,0xce,0x7f,0xf9,0xcf,0xff,0x00,0x00,0x00,0x00
|
|
||||||
,0x01,0xff,0xfb,0x9f,0xff,0x73,0xff,0xe7,0x3f,0xfe,0x73,0xfc,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0xff,0xf9,0xcf,0xff,0x9c,0xff,0xf9,0xcf,0xff,0x3d,0xf0,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0xff,0xfc,0xcf,0xff,0xce,0x7f,0xfc,0xf3,0xff,0x9e,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0xff,0xfc,0xe7,0xff,0xe7,0x3f,0xfe,0x79,0xff,0xcf,0x80,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0xff,0xfc,0xf3,0xff,0xf3,0x9f,0xff,0x3e,0x7f,0xe7,0xe0,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0xff,0xfc,0xf3,0xff,0xf9,0xe7,0xff,0x9f,0x3e,0x03,0xf0,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x7f,0xfc,0xf9,0xff,0xf9,0xf3,0xff,0xcf,0xc0,0x01,0xfc,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x7f,0xfc,0xfc,0xff,0xfc,0xf9,0xff,0xc7,0xf0,0x00,0x7f,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0xfe,0xff,0xfc,0xfe,0x00,0x03,0xf8,0x00,0x3f,0xc0,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x7e,0x00,0x00,0x7f,0x00,0x01,0xfe,0x00,0x0f,0xe0,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x7f,0x00,0x00,0x7f,0x80,0x00,0xff,0x80,0x07,0xf8,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x7f,0x80,0x00,0x3f,0xc0,0x00,0x3f,0xc0,0x01,0xf8,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x3f,0x80,0x00,0x1f,0xf0,0x00,0x1f,0xf0,0x00,0x70,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x3f,0xc0,0x00,0x0f,0xf8,0x00,0x07,0xf0,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x1f,0xc0,0x00,0x03,0xfc,0x00,0x03,0xf0,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x1f,0xe0,0x00,0x01,0xfe,0x00,0x00,0xc0,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x0f,0xf0,0x00,0x00,0x7e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x07,0xf0,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x07,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x03,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bitmap Size: 128x64
|
|
||||||
*/
|
|
||||||
const bitmapStruct argo128x64 = {
|
|
||||||
(byte *) argo128x64Data,
|
|
||||||
BITMAP_WIDTH,
|
|
||||||
BITMAP_HEIGHT
|
|
||||||
};
|
|
||||||
@@ -1,176 +0,0 @@
|
|||||||
/*
|
|
||||||
* argo256x128.c
|
|
||||||
*
|
|
||||||
* Sharp Argo logo (large).
|
|
||||||
*
|
|
||||||
* Created: 8/7/2021
|
|
||||||
* Author: Philip Smart
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <core_pins.h>
|
|
||||||
#include <usb_serial.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 "bitmaps.h"
|
|
||||||
|
|
||||||
#define BITMAP_WIDTH 256
|
|
||||||
#define BITMAP_HEIGHT 128
|
|
||||||
|
|
||||||
static const uint8_t argo256x128Data[((BITMAP_WIDTH * BITMAP_HEIGHT)/8)+1]= {
|
|
||||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xf8,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xc0,0x00,0x7f,0xff,0xfe,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0xfe,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0xff,0xc0,0xff,0xfc,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0x00,0x01,0xff,0xf8,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0x00,0x07,0xff,0xe0,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xff,0x00,0x1f,0xe1,0xe0,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x80,0x7f,0x81,0xc0,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xf3,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xf1,0xfe,0x03,0xc0,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xf3,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xf8,0x03,0xc0,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xf3,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xc0,0x00,0x00,0x3f,0xe0,0x07,0x80,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf3,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0xf0,0x7e,0x00,0xff,0xc0,0x07,0x80,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf3,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0xf8,0x7f,0xc0,0xff,0xf8,0x07,0x80,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xe1,0xef,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xf8,0x7f,0xf8,0x38,0x3e,0x0f,0x80,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xe1,0xef,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0xf8,0x7f,0xfc,0x00,0x0f,0xff,0x80,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3d,0xe0,0xe7,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xf0,0xff,0xfc,0x00,0x03,0xff,0xc0,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7d,0xe0,0xf3,0xc0,0x00,0x00,0x00,0x00,0x00,0x3f,0xf0,0xff,0xc1,0xff,0xf8,0x00,0x03,0xff,0xe0,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf9,0xe0,0xf1,0xe0,0x00,0x00,0x00,0x00,0x00,0x7f,0xf8,0x7f,0x07,0xff,0xc0,0xf8,0x03,0xff,0xe0,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf9,0xe0,0xf1,0xf0,0x00,0x00,0x00,0x00,0x00,0xff,0xfc,0x78,0x1f,0x80,0x01,0xfe,0x00,0xff,0xe0,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xf1,0xe0,0x78,0xf8,0x00,0x00,0x00,0x00,0x01,0xff,0xfc,0x78,0x7f,0x0f,0xff,0xff,0x00,0x7f,0x80,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xf1,0xe0,0x78,0xfc,0x00,0x00,0x00,0x00,0x01,0xff,0xfc,0xf8,0x00,0x1f,0xff,0xff,0x80,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xe3,0xe0,0x7c,0x7c,0x00,0x00,0x00,0x00,0x00,0xff,0xf8,0x70,0x7f,0xe0,0x01,0xff,0xc0,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xe3,0xe0,0x7c,0x3e,0x00,0x00,0x00,0x00,0x00,0xff,0xfc,0x03,0xff,0xfe,0x0c,0x7f,0xc0,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xc7,0xc0,0x3c,0x3f,0x00,0x00,0x00,0x00,0x00,0x20,0x7e,0x1f,0xff,0xff,0xc6,0x3f,0x80,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xc7,0xc0,0x3e,0x1f,0x80,0x00,0x00,0x00,0x00,0x00,0x0c,0x3f,0xff,0xff,0xf3,0x80,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x87,0xe0,0x3e,0x1f,0x80,0x00,0x00,0x00,0x00,0x0f,0x80,0x7f,0xff,0xff,0xf8,0xe0,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x8f,0xc0,0x3e,0x0f,0xc0,0x00,0x00,0x00,0x00,0x1f,0xe0,0xff,0xf8,0x7f,0xfc,0x7f,0xe0,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0x0f,0xc0,0x3f,0x0f,0xe0,0x00,0x00,0x00,0x00,0x1f,0xe0,0xff,0xc0,0x0f,0xfc,0x7f,0xc0,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x0f,0xc0,0x1f,0x07,0xf0,0x00,0x00,0x00,0x00,0x1f,0xf8,0xff,0xc0,0x07,0xfe,0x3f,0x80,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x0f,0xc0,0x1f,0x83,0xf8,0x00,0x00,0x00,0x00,0x0f,0xfc,0xff,0xe0,0x07,0xfe,0x3f,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x1f,0xc0,0x1f,0x81,0xf8,0x00,0x00,0x00,0x00,0x01,0xfc,0x7f,0xf8,0x1f,0xfe,0x30,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xfc,0x1f,0xc0,0x0f,0x81,0xfc,0x00,0x00,0x00,0x00,0x00,0x3e,0x3f,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xfc,0x1f,0x80,0x0f,0xc0,0xfe,0x00,0x00,0x00,0x00,0x06,0x00,0x1f,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xf8,0x3f,0x80,0x0f,0xc0,0xff,0x00,0x00,0x00,0x00,0x3f,0xe0,0x07,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xf8,0x3f,0x80,0x0f,0xc0,0x7f,0x80,0x00,0x00,0x00,0xff,0xc0,0x00,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x3f,0x80,0x0f,0xe0,0x3f,0x80,0x00,0x00,0x03,0xff,0x00,0x00,0x03,0xf0,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xf0,0x7f,0x80,0x0f,0xe0,0x3f,0xc0,0x00,0x00,0x0f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xe0,0x7f,0x80,0x07,0xf0,0x1f,0xc0,0x00,0x00,0x3f,0xf0,0x00,0x00,0x0f,0xff,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xe0,0x7f,0x80,0x07,0xf0,0x0f,0xe0,0x00,0x00,0xff,0xc0,0x00,0x00,0x3f,0xff,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xc0,0x7f,0x80,0x07,0xf0,0x0f,0xf0,0x00,0x03,0xff,0x00,0x00,0x00,0x7f,0xff,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xc0,0x7f,0x00,0x07,0xf8,0x07,0xf8,0x00,0x0f,0xfc,0x00,0x00,0x01,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x80,0x7f,0x00,0x03,0xf8,0x03,0xf8,0x00,0x3f,0xe0,0x00,0x00,0x07,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x80,0xff,0x00,0x03,0xf8,0x03,0xfc,0x00,0xff,0x80,0x00,0x00,0x1f,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0x00,0xff,0x00,0x03,0xfc,0x03,0xfe,0x07,0xfe,0x00,0x00,0x00,0x7f,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0x00,0xff,0x00,0x03,0xff,0xff,0xff,0x9f,0xf8,0x00,0x00,0x03,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0x01,0xff,0x00,0x07,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x1f,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xfe,0x01,0xff,0x80,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xfc,0x03,0xff,0xff,0xff,0xff,0xff,0x8f,0xff,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x01,0xff,0x80,0x01,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x07,0xff,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x7f,0xe0,0x7f,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x1f,0xff,0xff,0xf8,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x1f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x3f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x7f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x03,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x07,0xff,0xff,0xf0,0x3f,0xff,0xff,0xff,0x9f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x0f,0xff,0xfe,0x00,0x00,0xff,0xff,0xc0,0x00,0x3f,0xff,0xfc,0x00,0x07,0xff,0xff,0x80,0x01,0xff,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x0f,0xff,0xf8,0x00,0x00,0x3f,0xfe,0x00,0x00,0x0f,0xff,0xe0,0x00,0x00,0xff,0xfe,0x00,0x00,0x3f,0xff,0xff,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x0f,0xff,0xe0,0x3f,0xfc,0x0f,0xf8,0x07,0xfe,0x03,0xff,0x80,0x7f,0xe0,0x3f,0xf8,0x07,0xf0,0x07,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x0f,0xff,0xc0,0xff,0xfe,0x07,0xf0,0x1f,0xff,0x81,0xff,0x01,0xff,0xf8,0x1f,0xf0,0x3f,0xfe,0x03,0xff,0xff,0xff,0xff,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x0f,0xff,0x83,0xff,0xff,0x03,0xf0,0x7f,0xff,0xe0,0xfe,0x07,0xff,0xfe,0x0f,0xe0,0x7f,0xff,0x81,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x0f,0xff,0x03,0xff,0xff,0x81,0xe0,0x7f,0xff,0xe0,0x7e,0x0f,0xff,0xfe,0x07,0xc0,0xff,0xff,0xc0,0xff,0xff,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x07,0xff,0x03,0xff,0xff,0x81,0xe0,0x7f,0xff,0xe0,0x7e,0x0f,0xff,0xff,0x07,0xc0,0xff,0xff,0xc0,0xff,0xff,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x07,0xff,0x83,0xff,0xff,0x83,0xe0,0x7f,0xff,0xe0,0x7e,0x07,0xff,0xfe,0x07,0xc0,0xff,0xff,0xe0,0x7f,0xff,0xff,0xff,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x07,0xff,0x81,0xff,0xff,0x03,0xf0,0x3f,0xff,0xe0,0x7f,0x07,0xff,0xfe,0x07,0xe0,0x7f,0xff,0xc0,0xff,0xff,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x07,0xff,0xc0,0x7f,0xfe,0x07,0xf8,0x1f,0xff,0x80,0xff,0x01,0xff,0xfc,0x0f,0xf0,0x3f,0xff,0xe0,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x07,0xff,0xe0,0x1f,0xfc,0x0f,0xfc,0x03,0xff,0x81,0xff,0xc0,0x7f,0xfc,0x1f,0xf8,0x0f,0xff,0xf8,0xff,0xff,0xff,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x07,0xff,0xf8,0x00,0x7c,0x1f,0xff,0x00,0x0f,0xc3,0xff,0xe0,0x00,0x7f,0x0f,0xfc,0x00,0x00,0xfe,0x3f,0xff,0xff,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x03,0xff,0xff,0x80,0x3e,0x3f,0xff,0xc0,0x07,0xe1,0xff,0xfc,0x00,0x1f,0x87,0xff,0x80,0x00,0x3f,0x0f,0xff,0xff,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x03,0xff,0xff,0xfc,0x3f,0x1f,0xff,0xfe,0x03,0xf0,0xff,0xff,0xc0,0x07,0xe1,0xff,0xf0,0x00,0x1f,0xc7,0xff,0xff,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x03,0xff,0xff,0xff,0x1f,0x0f,0xff,0xff,0xf0,0xfc,0x3f,0xff,0xff,0xc3,0xf0,0x7f,0xff,0xff,0x87,0xf1,0xff,0xff,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x01,0xff,0xff,0xff,0x0f,0x87,0xff,0xff,0xf8,0x7e,0x1f,0xff,0xff,0xf0,0xfc,0x3f,0xff,0xff,0xe1,0xf8,0x7f,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x01,0xff,0xff,0xff,0x87,0x87,0xff,0xff,0xfc,0x3f,0x0f,0xff,0xff,0xfc,0x3f,0x0f,0xff,0xff,0xf0,0xfe,0x3f,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x01,0xff,0xff,0xff,0xc7,0xc3,0xff,0xff,0xff,0x1f,0x87,0xff,0xff,0xfe,0x0f,0x83,0xff,0xff,0xfc,0x3f,0x8f,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x01,0xff,0xff,0xff,0xc3,0xe1,0xff,0xff,0xff,0x87,0xe1,0xff,0xff,0xff,0x87,0xe1,0xff,0xff,0xff,0x0f,0xc3,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x01,0xff,0xff,0xff,0xe1,0xf0,0xff,0xff,0xff,0xc3,0xf0,0xff,0xff,0xff,0xc1,0xf8,0x7f,0xff,0xff,0x87,0xf0,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0xff,0xff,0xff,0xf1,0xf8,0xff,0xff,0xff,0xe1,0xf8,0x7f,0xff,0xff,0xf0,0xfc,0x3f,0xff,0xff,0xc3,0xfc,0x78,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0xff,0xff,0xff,0xf0,0xf8,0x7f,0xff,0xff,0xf8,0xfc,0x1f,0xff,0xff,0xf8,0x7f,0x0f,0xff,0xff,0xe1,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0xff,0xff,0xff,0xf0,0xfc,0x7f,0xff,0xff,0xfc,0x3e,0x0f,0xff,0xff,0xfc,0x3f,0xc3,0xff,0xff,0xf0,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0xff,0xff,0xff,0xf0,0xfe,0x3f,0xff,0xff,0xfe,0x1f,0x87,0xff,0xff,0xfe,0x1f,0xe1,0xff,0xff,0xf8,0x7f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0xff,0xff,0xff,0xf0,0xfe,0x1f,0xff,0xff,0xff,0x0f,0xc3,0xff,0xff,0xff,0x0f,0xf8,0x7f,0xff,0xfc,0x3f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0xff,0xff,0xff,0xf0,0xff,0x1f,0xff,0xff,0xff,0x87,0xf1,0xff,0xff,0xff,0x87,0xfe,0x1f,0xff,0xf8,0x1f,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x7f,0xff,0xff,0xf0,0xff,0x8f,0xff,0xff,0xff,0x87,0xf8,0x7f,0xff,0xff,0xc3,0xff,0x0f,0xff,0x80,0x0f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x7f,0xff,0xff,0xf0,0xff,0x87,0xff,0xff,0xff,0xc3,0xfc,0x3f,0xff,0xff,0xe1,0xff,0xc3,0xf0,0x00,0x07,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x7f,0xff,0xff,0xf0,0xff,0xc7,0xff,0xff,0xff,0xc3,0xfe,0x1f,0xff,0xff,0xe0,0xff,0xe0,0x00,0x00,0x03,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x7f,0xff,0xff,0xf0,0xff,0xe3,0xff,0xff,0xff,0xc3,0xff,0x8f,0xff,0xff,0xf8,0x7f,0xf8,0x00,0x00,0x01,0xff,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x7f,0xff,0xff,0xf8,0xff,0xe1,0xff,0xff,0xff,0xe1,0xff,0xc3,0xff,0xff,0xf8,0x7f,0xfe,0x00,0x00,0x00,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x1f,0xff,0xff,0xf8,0x7f,0xf1,0xff,0xff,0xff,0xe1,0xff,0xe1,0xff,0xff,0xc0,0x3f,0xff,0x00,0x00,0x00,0x3f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x0f,0xf8,0x7f,0xf8,0xff,0xff,0xff,0xf0,0xff,0xf8,0xf8,0x00,0x00,0x1f,0xff,0xc0,0x00,0x00,0x1f,0xff,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xf8,0x7f,0xff,0xff,0xf0,0x7f,0xfc,0x00,0x00,0x00,0x0f,0xff,0xf0,0x00,0x00,0x07,0xff,0xf0,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xfc,0x00,0x00,0x00,0x00,0x7f,0xfe,0x00,0x00,0x00,0x07,0xff,0xf8,0x00,0x00,0x01,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xfe,0x00,0x00,0x00,0x00,0x3f,0xff,0x00,0x00,0x00,0x01,0xff,0xfe,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xfe,0x00,0x00,0x00,0x00,0x3f,0xff,0xc0,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x3f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x00,0x00,0x00,0x00,0x1f,0xff,0xe0,0x00,0x00,0x00,0x3f,0xff,0xc0,0x00,0x00,0x0f,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xff,0x80,0x00,0x00,0x00,0x0f,0xff,0xf0,0x00,0x00,0x00,0x1f,0xff,0xf0,0x00,0x00,0x03,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0x80,0x00,0x00,0x00,0x07,0xff,0xfc,0x00,0x00,0x00,0x07,0xff,0xf8,0x00,0x00,0x01,0xff,0xc0,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xff,0xc0,0x00,0x00,0x00,0x03,0xff,0xfc,0x00,0x00,0x00,0x03,0xff,0xfe,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xc0,0x00,0x00,0x00,0x01,0xff,0xff,0x00,0x00,0x00,0x01,0xff,0xff,0x00,0x00,0x00,0x1c,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xe0,0x00,0x00,0x00,0x00,0xff,0xff,0x80,0x00,0x00,0x00,0x7f,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x0f,0xff,0xf0,0x00,0x00,0x00,0x00,0x7f,0xff,0xc0,0x00,0x00,0x00,0x3f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xff,0xf0,0x00,0x00,0x00,0x00,0x1f,0xff,0xf0,0x00,0x00,0x00,0x0f,0xff,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xf8,0x00,0x00,0x00,0x00,0x0f,0xff,0xf8,0x00,0x00,0x00,0x07,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xfc,0x00,0x00,0x00,0x00,0x07,0xff,0xfc,0x00,0x00,0x00,0x01,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0xff,0xfe,0x00,0x00,0x00,0x00,0x03,0xff,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0xff,0xfe,0x00,0x00,0x00,0x00,0x01,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0xff,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x1f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xff,0x00,0x00,0x00,0x00,0x00,0x0f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0xfe,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3f,0xf8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bitmap Size: 256x128
|
|
||||||
*/
|
|
||||||
const bitmapStruct argo256x128 = {
|
|
||||||
(byte *) argo256x128Data,
|
|
||||||
BITMAP_WIDTH,
|
|
||||||
BITMAP_HEIGHT
|
|
||||||
};
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
* argo64x32.c
|
|
||||||
*
|
|
||||||
* Sharp Argo logo (small).
|
|
||||||
*
|
|
||||||
* Created: 8/7/2021
|
|
||||||
* Author: Philip Smart
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <core_pins.h>
|
|
||||||
#include <usb_serial.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 "bitmaps.h"
|
|
||||||
|
|
||||||
#define BITMAP_WIDTH 64
|
|
||||||
#define BITMAP_HEIGHT 32
|
|
||||||
|
|
||||||
static const uint8_t argo64x32Data[((BITMAP_WIDTH * BITMAP_HEIGHT)/8)+1]= {
|
|
||||||
0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x01,0xfc,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x38
|
|
||||||
,0x00,0x00,0x00,0x38,0x00,0x00,0x1c,0x78
|
|
||||||
,0x00,0x00,0x00,0x38,0x00,0x00,0x03,0x90
|
|
||||||
,0x00,0x00,0x00,0x6c,0x00,0x0f,0xbb,0x90
|
|
||||||
,0x00,0x00,0x00,0xee,0x00,0x3b,0x3a,0x38
|
|
||||||
,0x00,0x00,0x00,0xab,0x00,0x3a,0xd7,0x00
|
|
||||||
,0x00,0x00,0x01,0x6d,0x00,0x13,0xfb,0x00
|
|
||||||
,0x00,0x00,0x03,0x45,0x80,0x1b,0x9f,0x00
|
|
||||||
,0x00,0x00,0x02,0x46,0xc0,0x11,0xf8,0x00
|
|
||||||
,0x00,0x00,0x06,0xc6,0x60,0x60,0x70,0x00
|
|
||||||
,0x00,0x00,0x0c,0xc6,0x61,0x80,0xf0,0x00
|
|
||||||
,0x00,0x00,0x0c,0xc7,0xfe,0x07,0xf0,0x00
|
|
||||||
,0x02,0x00,0x1f,0xfc,0x0e,0x7f,0xf0,0x00
|
|
||||||
,0x0f,0xff,0xff,0x87,0xff,0xff,0xf0,0x00
|
|
||||||
,0x1f,0x1f,0x8f,0xc7,0xe7,0xff,0xf0,0x00
|
|
||||||
,0x1c,0xf6,0x73,0x39,0xbc,0xff,0xe0,0x00
|
|
||||||
,0x1c,0xf2,0xfb,0x7d,0xbe,0xff,0xc0,0x00
|
|
||||||
,0x1f,0x37,0x1b,0x85,0xc3,0xff,0x80,0x00
|
|
||||||
,0x0f,0xd7,0xed,0xfb,0x7e,0xff,0x00,0x00
|
|
||||||
,0x0f,0xeb,0xfa,0xfe,0xbf,0x7c,0x00,0x00
|
|
||||||
,0x0f,0xed,0xfd,0x7f,0x6f,0xb8,0x00,0x00
|
|
||||||
,0x0f,0xed,0xfd,0xdf,0xb8,0x1e,0x00,0x00
|
|
||||||
,0x01,0xee,0xfe,0xee,0x1c,0x07,0x00,0x00
|
|
||||||
,0x00,0x0f,0x00,0xf0,0x0f,0x03,0xc0,0x00
|
|
||||||
,0x00,0x07,0x00,0x7c,0x07,0x80,0xc0,0x00
|
|
||||||
,0x00,0x07,0x80,0x1e,0x01,0xc0,0x00,0x00
|
|
||||||
,0x00,0x03,0xc0,0x0f,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x03,0xc0,0x06,0x00,0x00,0x00,0x00
|
|
||||||
,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bitmap Size: 64x32
|
|
||||||
*/
|
|
||||||
const bitmapStruct argo64x32 = {
|
|
||||||
(byte *) argo64x32Data,
|
|
||||||
BITMAP_WIDTH,
|
|
||||||
BITMAP_HEIGHT
|
|
||||||
};
|
|
||||||
5916
zOS/MZ2000/common/diffme
vendored
5916
zOS/MZ2000/common/diffme
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
4762
zOS/MZ2000/common/emumz.c.bak.27122021
vendored
4762
zOS/MZ2000/common/emumz.c.bak.27122021
vendored
File diff suppressed because it is too large
Load Diff
4817
zOS/MZ2000/common/emumz.c.bak.28122021
vendored
4817
zOS/MZ2000/common/emumz.c.bak.28122021
vendored
File diff suppressed because it is too large
Load Diff
@@ -1,77 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: fonts.c
|
|
||||||
// Created: May 2021
|
|
||||||
// Version: v1.0
|
|
||||||
// Author(s): Baron Williams, Philip Smart
|
|
||||||
// Description: The Font Library.
|
|
||||||
// This is a font definition and manipulation library, the fonts being based on
|
|
||||||
// Baron Williams (https://github.com/BaronWilliams) font definitions and modified
|
|
||||||
// for use with the Sharp MZ Series OSD.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2015 Baron Williams, (c) 2018-2021 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: v1.0 May 2021 - Initial write of the font software.
|
|
||||||
//
|
|
||||||
// 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 <core_pins.h>
|
|
||||||
#include <usb_serial.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 "ff.h" /* Declarations of FatFs API */
|
|
||||||
#include "diskio.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include <fonts.h>
|
|
||||||
|
|
||||||
#ifndef __APP__ // Protected methods which should only reside in the kernel on zOS.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
/*
|
|
||||||
* font11x16.c
|
|
||||||
*
|
|
||||||
* Created: 4/8/2015 11:31:21 AM
|
|
||||||
* Author: Baron Williams
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <core_pins.h>
|
|
||||||
#include <usb_serial.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 "fonts.h"
|
|
||||||
|
|
||||||
#define FONT_CHAR_FIRST 32
|
|
||||||
#define FONT_CHAR_LAST 126
|
|
||||||
#define FONT_CHARS 95
|
|
||||||
#define FONT_WIDTH 11
|
|
||||||
#define FONT_HEIGHT 16
|
|
||||||
#define FONT_SPACING 1
|
|
||||||
|
|
||||||
const uint16_t fontData11x16[FONT_CHARS][FONT_WIDTH] ={
|
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, // ' ' 32
|
|
||||||
{ 0, 0, 0, 124, 13311, 13311, 124, 0, 0, 0, 0, }, // '!' 33
|
|
||||||
{ 0, 0, 60, 60, 0, 0, 60, 60, 0, 0, 0, }, // '"' 34
|
|
||||||
{ 512, 7696, 8080, 1008, 638, 7710, 8080, 1008, 638, 30, 16, }, // '#' 35
|
|
||||||
{ 0, 1144, 3324, 3276, 16383, 16383, 3276, 4044, 1928, 0, 0, }, // '$' 36
|
|
||||||
{ 12288, 14392, 7224, 3640, 1792, 896, 448, 14560, 14448, 14392, 28, }, // '%' 37
|
|
||||||
{ 0, 7936, 16312, 12796, 8646, 14306, 7742, 7196, 13824, 8704, 0, }, // '&' 38
|
|
||||||
{ 0, 0, 0, 39, 63, 31, 0, 0, 0, 0, 0, }, // ''' 39
|
|
||||||
{ 0, 0, 1008, 4092, 8190, 14343, 8193, 8193, 0, 0, 0, }, // '(' 40
|
|
||||||
{ 0, 0, 8193, 8193, 14343, 8190, 4092, 1008, 0, 0, 0, }, // ')' 41
|
|
||||||
{ 0, 3224, 3768, 992, 4088, 4088, 992, 3768, 3224, 0, 0, }, // '*' 42
|
|
||||||
{ 0, 384, 384, 384, 4080, 4080, 384, 384, 384, 0, 0, }, // '+' 43
|
|
||||||
{ 0, 0, 0, 47104, 63488, 30720, 0, 0, 0, 0, 0, }, // ',' 44
|
|
||||||
{ 0, 384, 384, 384, 384, 384, 384, 384, 384, 0, 0, }, // '-' 45
|
|
||||||
{ 0, 0, 0, 14336, 14336, 14336, 0, 0, 0, 0, 0, }, // '.' 46
|
|
||||||
{ 6144, 7168, 3584, 1792, 896, 448, 224, 112, 56, 28, 14, }, // '/' 47
|
|
||||||
{ 2040, 8190, 7686, 13059, 12675, 12483, 12387, 12339, 6174, 8190, 2040, }, // '0' 48
|
|
||||||
{ 0, 0, 12300, 12300, 12302, 16383, 16383, 12288, 12288, 12288, 0, }, // '1' 49
|
|
||||||
{ 12316, 14366, 15367, 15875, 14083, 13187, 12739, 12515, 12407, 12350, 12316, }, // '2' 50
|
|
||||||
{ 3084, 7182, 14343, 12483, 12483, 12483, 12483, 12483, 14823, 8062, 3644, }, // '3' 51
|
|
||||||
{ 960, 992, 880, 824, 796, 782, 775, 16383, 16383, 768, 768, }, // '4' 52
|
|
||||||
{ 3135, 7295, 14435, 12387, 12387, 12387, 12387, 12387, 14563, 8131, 3971, }, // '5' 53
|
|
||||||
{ 4032, 8176, 14840, 12508, 12494, 12487, 12483, 12483, 14787, 8064, 3840, }, // '6' 54
|
|
||||||
{ 3, 3, 3, 12291, 15363, 3843, 963, 243, 63, 15, 3, }, // '7' 55
|
|
||||||
{ 3840, 8124, 14846, 12519, 12483, 12483, 12483, 12519, 14846, 8124, 3840, }, // '8' 56
|
|
||||||
{ 60, 126, 12519, 12483, 12483, 14531, 7363, 3779, 2023, 1022, 252, }, // '9' 57
|
|
||||||
{ 0, 0, 0, 7280, 7280, 7280, 0, 0, 0, 0, 0, }, // ':' 58
|
|
||||||
{ 0, 0, 0, 40048, 64624, 31856, 0, 0, 0, 0, 0, }, // ';' 59
|
|
||||||
{ 0, 192, 480, 1008, 1848, 3612, 7182, 14343, 12291, 0, 0, }, // '<' 60
|
|
||||||
{ 0, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 1632, 0, }, // '=' 61
|
|
||||||
{ 0, 12291, 14343, 7182, 3612, 1848, 1008, 480, 192, 0, 0, }, // '>' 62
|
|
||||||
{ 28, 30, 7, 3, 14211, 14275, 227, 119, 62, 28, 0, }, // '?' 63
|
|
||||||
{ 4088, 8190, 6151, 13299, 14331, 13851, 14331, 14331, 13831, 1022, 504, }, // '@' 64
|
|
||||||
{ 14336, 16128, 2016, 1788, 1567, 1567, 1788, 2016, 16128, 14336, 0, }, // 'A' 65
|
|
||||||
{ 16383, 16383, 12483, 12483, 12483, 12483, 12519, 14846, 8124, 3840, 0, }, // 'B' 66
|
|
||||||
{ 1008, 4092, 7182, 14343, 12291, 12291, 12291, 14343, 7182, 3084, 0, }, // 'C' 67
|
|
||||||
{ 16383, 16383, 12291, 12291, 12291, 12291, 14343, 7182, 4092, 1008, 0, }, // 'D' 68
|
|
||||||
{ 16383, 16383, 12483, 12483, 12483, 12483, 12483, 12483, 12291, 12291, 0, }, // 'E' 69
|
|
||||||
{ 16383, 16383, 195, 195, 195, 195, 195, 195, 3, 3, 0, }, // 'F' 70
|
|
||||||
{ 1008, 4092, 7182, 14343, 12291, 12483, 12483, 12483, 16327, 16326, 0, }, // 'G' 71
|
|
||||||
{ 16383, 16383, 192, 192, 192, 192, 192, 192, 16383, 16383, 0, }, // 'H' 72
|
|
||||||
{ 0, 0, 12291, 12291, 16383, 16383, 12291, 12291, 0, 0, 0, }, // 'I' 73
|
|
||||||
{ 3584, 7680, 14336, 12288, 12288, 12288, 12288, 14336, 8191, 2047, 0, }, // 'J' 74
|
|
||||||
{ 16383, 16383, 192, 480, 1008, 1848, 3612, 7182, 14343, 12291, 0, }, // 'K' 75
|
|
||||||
{ 16383, 16383, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 12288, 0, }, // 'L' 76
|
|
||||||
{ 16383, 16383, 30, 120, 480, 480, 120, 30, 16383, 16383, 0, }, // 'M' 77
|
|
||||||
{ 16383, 16383, 14, 56, 240, 960, 1792, 7168, 16383, 16383, 0, }, // 'N' 78
|
|
||||||
{ 1008, 4092, 7182, 14343, 12291, 12291, 14343, 7182, 4092, 1008, 0, }, // 'O' 79
|
|
||||||
{ 16383, 16383, 387, 387, 387, 387, 387, 455, 254, 124, 0, }, // 'P' 80
|
|
||||||
{ 1008, 4092, 7182, 14343, 12291, 13827, 15879, 7182, 16380, 13296, 0, }, // 'Q' 81
|
|
||||||
{ 16383, 16383, 387, 387, 899, 1923, 3971, 7623, 14590, 12412, 0, }, // 'R' 82
|
|
||||||
{ 3132, 7294, 14567, 12483, 12483, 12483, 12483, 14791, 8078, 3852, 0, }, // 'S' 83
|
|
||||||
{ 0, 3, 3, 3, 16383, 16383, 3, 3, 3, 0, 0, }, // 'T' 84
|
|
||||||
{ 2047, 8191, 14336, 12288, 12288, 12288, 12288, 14336, 8191, 2047, 0, }, // 'U' 85
|
|
||||||
{ 7, 63, 504, 4032, 15872, 15872, 4032, 504, 63, 7, 0, }, // 'V' 86
|
|
||||||
{ 16383, 16383, 7168, 1536, 896, 896, 1536, 7168, 16383, 16383, 0, }, // 'W' 87
|
|
||||||
{ 12291, 15375, 3612, 816, 480, 480, 816, 3612, 15375, 12291, 0, }, // 'X' 88
|
|
||||||
{ 3, 15, 60, 240, 16320, 16320, 240, 60, 15, 3, 0, }, // 'Y' 89
|
|
||||||
{ 12291, 15363, 15875, 13059, 12739, 12515, 12339, 12319, 12303, 12291, 0, }, // 'Z' 90
|
|
||||||
{ 0, 0, 16383, 16383, 12291, 12291, 12291, 12291, 0, 0, 0, }, // '[' 91
|
|
||||||
{ 14, 28, 56, 112, 224, 448, 896, 1792, 3584, 7168, 6144, }, // '\' 92
|
|
||||||
{ 0, 0, 12291, 12291, 12291, 12291, 16383, 16383, 0, 0, 0, }, // ']' 93
|
|
||||||
{ 96, 112, 56, 28, 14, 7, 14, 28, 56, 112, 96, }, // '^' 94
|
|
||||||
{ 49152, 49152, 49152, 49152, 49152, 49152, 49152, 49152, 49152, 49152, 49152, }, // '_' 95
|
|
||||||
{ 0, 0, 0, 0, 62, 126, 78, 0, 0, 0, 0, }, // '`' 96
|
|
||||||
{ 7168, 15936, 13152, 13152, 13152, 13152, 13152, 13152, 16352, 16320, 0, }, // 'a' 97
|
|
||||||
{ 16383, 16383, 12480, 12384, 12384, 12384, 12384, 14560, 8128, 3968, 0, }, // 'b' 98
|
|
||||||
{ 3968, 8128, 14560, 12384, 12384, 12384, 12384, 12384, 6336, 2176, 0, }, // 'c' 99
|
|
||||||
{ 3968, 8128, 14560, 12384, 12384, 12384, 12512, 12480, 16383, 16383, 0, }, // 'd' 100
|
|
||||||
{ 3968, 8128, 15328, 13152, 13152, 13152, 13152, 13152, 5056, 384, 0, }, // 'e' 101
|
|
||||||
{ 192, 192, 16380, 16382, 199, 195, 195, 3, 0, 0, 0, }, // 'f' 102
|
|
||||||
{ 896, 51136, 52960, 52320, 52320, 52320, 52320, 58976, 32736, 16352, 0, }, // 'g' 103
|
|
||||||
{ 16383, 16383, 192, 96, 96, 96, 224, 16320, 16256, 0, 0, }, // 'h' 104
|
|
||||||
{ 0, 0, 12288, 12384, 16364, 16364, 12288, 12288, 0, 0, 0, }, // 'i' 105
|
|
||||||
{ 0, 0, 24576, 57344, 49152, 49248, 65516, 32748, 0, 0, 0, }, // 'j' 106
|
|
||||||
{ 0, 16383, 16383, 768, 1920, 4032, 7392, 14432, 12288, 0, 0, }, // 'k' 107
|
|
||||||
{ 0, 0, 12288, 12291, 16383, 16383, 12288, 12288, 0, 0, 0, }, // 'l' 108
|
|
||||||
{ 16352, 16320, 224, 224, 16320, 16320, 224, 224, 16320, 16256, 0, }, // 'm' 109
|
|
||||||
{ 0, 16352, 16352, 96, 96, 96, 96, 224, 16320, 16256, 0, }, // 'n' 110
|
|
||||||
{ 3968, 8128, 14560, 12384, 12384, 12384, 12384, 14560, 8128, 3968, 0, }, // 'o' 111
|
|
||||||
{ 65504, 65504, 3168, 6240, 6240, 6240, 6240, 7392, 4032, 1920, 0, }, // 'p' 112
|
|
||||||
{ 1920, 4032, 7392, 6240, 6240, 6240, 6240, 3168, 65504, 65504, 0, }, // 'q' 113
|
|
||||||
{ 0, 16352, 16352, 192, 96, 96, 96, 96, 224, 192, 0, }, // 'r' 114
|
|
||||||
{ 4544, 13280, 13152, 13152, 13152, 13152, 16224, 7744, 0, 0, 0, }, // 's' 115
|
|
||||||
{ 96, 96, 8190, 16382, 12384, 12384, 12384, 12288, 0, 0, 0, }, // 't' 116
|
|
||||||
{ 4064, 8160, 14336, 12288, 12288, 12288, 12288, 6144, 16352, 16352, 0, }, // 'u' 117
|
|
||||||
{ 96, 480, 1920, 7680, 14336, 14336, 7680, 1920, 480, 96, 0, }, // 'v' 118
|
|
||||||
{ 2016, 8160, 14336, 7168, 4064, 4064, 7168, 14336, 8160, 2016, 0, }, // 'w' 119
|
|
||||||
{ 12384, 14560, 7616, 3968, 1792, 3968, 7616, 14560, 12384, 0, 0, }, // 'x' 120
|
|
||||||
{ 0, 96, 33248, 59264, 32256, 7680, 1920, 480, 96, 0, 0, }, // 'y' 121
|
|
||||||
{ 12384, 14432, 15456, 13920, 13152, 12768, 12512, 12384, 12320, 0, 0, }, // 'z' 122
|
|
||||||
{ 0, 128, 448, 8188, 16254, 28679, 24579, 24579, 24579, 0, 0, }, // '{' 123
|
|
||||||
{ 0, 0, 0, 0, 16383, 16383, 0, 0, 0, 0, 0, }, // '|' 124
|
|
||||||
{ 0, 24579, 24579, 24579, 28679, 16254, 8188, 448, 128, 0, 0, }, // '}' 125
|
|
||||||
{ 16, 24, 12, 4, 12, 24, 16, 24, 12, 4, 0 }, // '~' 126
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Font Size: 11x16
|
|
||||||
* Characters: 96 (ASCII 32-126).
|
|
||||||
* Bit format: vertical
|
|
||||||
* Memory: 2112 bytes (96x11x2)
|
|
||||||
*/
|
|
||||||
const fontStruct font11x16 = {
|
|
||||||
(byte *) fontData11x16,
|
|
||||||
FONT_CHARS,
|
|
||||||
FONT_CHAR_FIRST,
|
|
||||||
FONT_CHAR_LAST,
|
|
||||||
FONT_WIDTH,
|
|
||||||
FONT_HEIGHT,
|
|
||||||
FONT_SPACING,
|
|
||||||
true
|
|
||||||
};
|
|
||||||
@@ -1,164 +0,0 @@
|
|||||||
/*
|
|
||||||
* font3x6.c
|
|
||||||
*
|
|
||||||
* Created: 4/8/2015 11:31:21 AM
|
|
||||||
* Author: Baron Williams
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <core_pins.h>
|
|
||||||
#include <usb_serial.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 "fonts.h"
|
|
||||||
|
|
||||||
#define FONT_CHAR_FIRST 32
|
|
||||||
#define FONT_CHAR_LAST 127
|
|
||||||
#define FONT_CHARS 96
|
|
||||||
#define FONT_WIDTH 3
|
|
||||||
#define FONT_HEIGHT 6
|
|
||||||
#define FONT_SPACING 1
|
|
||||||
|
|
||||||
static const uint8_t fontData3x6[FONT_CHARS][FONT_WIDTH]= {
|
|
||||||
{ 0x00, 0x00, 0x00, }, // ' ' 32
|
|
||||||
{ 0x00, 0x17, 0x00, }, // '!' 33
|
|
||||||
{ 0x03, 0x00, 0x03, }, // '"' 34
|
|
||||||
{ 0x1F, 0x0A, 0x1F, }, // '#' 35
|
|
||||||
{ 0x16, 0x1F, 0x0D, }, // '$' 36
|
|
||||||
{ 0x19, 0x04, 0x13, }, // '%' 37
|
|
||||||
{ 0x1A, 0x15, 0x0A, }, // '&' 38
|
|
||||||
{ 0x00, 0x03, 0x00, }, // ''' 39
|
|
||||||
{ 0x0E, 0x11, 0x00, }, // '(' 40
|
|
||||||
{ 0x00, 0x11, 0x0E, }, // ')' 41
|
|
||||||
{ 0x0A, 0x04, 0x0A, }, // '*' 42
|
|
||||||
{ 0x04, 0x0E, 0x04, }, // '+' 43
|
|
||||||
{ 0x10, 0x08, 0x00, }, // ',' 44
|
|
||||||
{ 0x04, 0x04, 0x04, }, // '-' 45
|
|
||||||
{ 0x00, 0x10, 0x00, }, // '.' 46
|
|
||||||
{ 0x18, 0x04, 0x03, }, // '/' 47
|
|
||||||
{ 0x1F, 0x11, 0x1F, }, // '0' 48
|
|
||||||
{ 0x12, 0x1F, 0x10, }, // '1' 49
|
|
||||||
{ 0x1D, 0x15, 0x17, }, // '2' 50
|
|
||||||
{ 0x11, 0x15, 0x1F, }, // '3' 51
|
|
||||||
{ 0x07, 0x04, 0x1F, }, // '4' 52
|
|
||||||
{ 0x17, 0x15, 0x1D, }, // '5' 53
|
|
||||||
{ 0x1F, 0x15, 0x1D, }, // '6' 54
|
|
||||||
{ 0x19, 0x05, 0x03, }, // '7' 55
|
|
||||||
{ 0x1F, 0x15, 0x1F, }, // '8' 56
|
|
||||||
{ 0x17, 0x15, 0x1F, }, // '9' 57
|
|
||||||
{ 0x00, 0x0A, 0x00, }, // ':' 58
|
|
||||||
{ 0x10, 0x0A, 0x00, }, // ';' 59
|
|
||||||
{ 0x04, 0x0A, 0x11, }, // '<' 60
|
|
||||||
{ 0x0A, 0x0A, 0x0A, }, // '=' 61
|
|
||||||
{ 0x11, 0x0A, 0x04, }, // '>' 62
|
|
||||||
{ 0x01, 0x15, 0x03, }, // '?' 63
|
|
||||||
{ 0x0E, 0x11, 0x16, }, // '@' 64
|
|
||||||
{ 0x1F, 0x05, 0x1F, }, // 'A' 65
|
|
||||||
{ 0x1F, 0x15, 0x1B, }, // 'B' 66
|
|
||||||
{ 0x0E, 0x11, 0x11, }, // 'C' 67
|
|
||||||
{ 0x1F, 0x11, 0x0E, }, // 'D' 68
|
|
||||||
{ 0x1F, 0x15, 0x15, }, // 'E' 69
|
|
||||||
{ 0x1F, 0x05, 0x05, }, // 'F' 70
|
|
||||||
{ 0x0E, 0x11, 0x1D, }, // 'G' 71
|
|
||||||
{ 0x1F, 0x04, 0x1F, }, // 'H' 72
|
|
||||||
{ 0x11, 0x1F, 0x11, }, // 'I' 73
|
|
||||||
{ 0x08, 0x11, 0x0F, }, // 'J' 74
|
|
||||||
{ 0x1F, 0x04, 0x1B, }, // 'K' 75
|
|
||||||
{ 0x1F, 0x10, 0x10, }, // 'L' 76
|
|
||||||
{ 0x1F, 0x02, 0x1F, }, // 'M' 77
|
|
||||||
{ 0x1F, 0x01, 0x1E, }, // 'N' 78
|
|
||||||
{ 0x0E, 0x11, 0x0E, }, // 'O' 79
|
|
||||||
{ 0x1F, 0x05, 0x06, }, // 'P' 80
|
|
||||||
{ 0x0E, 0x19, 0x1F, }, // 'Q' 81
|
|
||||||
{ 0x1F, 0x05, 0x1B, }, // 'R' 82
|
|
||||||
{ 0x12, 0x15, 0x09, }, // 'S' 83
|
|
||||||
{ 0x01, 0x1F, 0x01, }, // 'T' 84
|
|
||||||
{ 0x0F, 0x10, 0x1F, }, // 'U' 85
|
|
||||||
{ 0x0F, 0x10, 0x0F, }, // 'V' 86
|
|
||||||
{ 0x1F, 0x0C, 0x1F, }, // 'W' 87
|
|
||||||
{ 0x1B, 0x04, 0x1B, }, // 'X' 88
|
|
||||||
{ 0x03, 0x1C, 0x03, }, // 'Y' 89
|
|
||||||
{ 0x19, 0x15, 0x13, }, // 'Z' 90
|
|
||||||
{ 0x00, 0x1F, 0x11, }, // '[' 91
|
|
||||||
{ 0x03, 0x04, 0x18, }, // '\' 92
|
|
||||||
{ 0x11, 0x1F, 0x00, }, // ']' 93
|
|
||||||
{ 0x02, 0x01, 0x02, }, // '^' 94
|
|
||||||
{ 0x10, 0x10, 0x10, }, // '_' 95
|
|
||||||
{ 0x01, 0x02, 0x00, }, // '`' 96
|
|
||||||
{ 0x0C, 0x12, 0x1E, }, // 'a' 97
|
|
||||||
{ 0x1F, 0x12, 0x0C, }, // 'b' 98
|
|
||||||
{ 0x0C, 0x12, 0x12, }, // 'c' 99
|
|
||||||
{ 0x0C, 0x12, 0x1F, }, // 'd' 100
|
|
||||||
{ 0x0C, 0x1A, 0x16, }, // 'e' 101
|
|
||||||
{ 0x1E, 0x09, 0x02, }, // 'f' 102
|
|
||||||
{ 0x24, 0x2A, 0x1E, }, // 'g' 103
|
|
||||||
{ 0x1F, 0x04, 0x18, }, // 'h' 104
|
|
||||||
{ 0x00, 0x1D, 0x00, }, // 'i' 105
|
|
||||||
{ 0x20, 0x20, 0x1D, }, // 'j' 106
|
|
||||||
{ 0x1F, 0x04, 0x1A, }, // 'k' 107
|
|
||||||
{ 0x00, 0x0F, 0x10, }, // 'l' 108
|
|
||||||
{ 0x1E, 0x04, 0x1E, }, // 'm' 109
|
|
||||||
{ 0x1E, 0x02, 0x1C, }, // 'n' 110
|
|
||||||
{ 0x0C, 0x12, 0x0C, }, // 'o' 111
|
|
||||||
{ 0x3E, 0x0A, 0x04, }, // 'p' 112
|
|
||||||
{ 0x04, 0x0A, 0x3E, }, // 'q' 113
|
|
||||||
{ 0x1E, 0x04, 0x02, }, // 'r' 114
|
|
||||||
{ 0x14, 0x16, 0x1A, }, // 's' 115
|
|
||||||
{ 0x02, 0x0F, 0x12, }, // 't' 116
|
|
||||||
{ 0x0E, 0x10, 0x1E, }, // 'u' 117
|
|
||||||
{ 0x0E, 0x10, 0x0E, }, // 'v' 118
|
|
||||||
{ 0x1E, 0x08, 0x1E, }, // 'w' 119
|
|
||||||
{ 0x1A, 0x04, 0x1A, }, // 'x' 120
|
|
||||||
{ 0x26, 0x28, 0x1E, }, // 'y' 121
|
|
||||||
{ 0x1A, 0x1E, 0x16, }, // 'z' 122
|
|
||||||
{ 0x04, 0x1F, 0x11, }, // '{' 123
|
|
||||||
{ 0x00, 0x1F, 0x00, }, // '|' 124
|
|
||||||
{ 0x11, 0x1F, 0x04, }, // '}' 125
|
|
||||||
{ 0x01, 0x03, 0x02, }, // '~' 126
|
|
||||||
{ 0x0E, 0x09, 0x0E }, // delete 127
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
*
|
|
||||||
* Font: font3x6
|
|
||||||
* Set: ASCII printable characters (codes 32-127)
|
|
||||||
* Size: 3x6
|
|
||||||
* Spacing: required horizontally
|
|
||||||
* Format: Vertical, 1 byte per column, top bit is 0
|
|
||||||
*
|
|
||||||
* The extended ASCII codes (character code 128-255) are
|
|
||||||
* not included because they contain many characters that
|
|
||||||
* not possible to represent using a 3x6 grid.
|
|
||||||
*
|
|
||||||
* Characters: 96 (ASCII 32-127).
|
|
||||||
* Bit format: vertical
|
|
||||||
* Memory: 288 bytes (96x3)
|
|
||||||
*/
|
|
||||||
const fontStruct font3x6 = {
|
|
||||||
(byte *) fontData3x6,
|
|
||||||
FONT_CHARS,
|
|
||||||
FONT_CHAR_FIRST,
|
|
||||||
FONT_CHAR_LAST,
|
|
||||||
FONT_WIDTH,
|
|
||||||
FONT_HEIGHT,
|
|
||||||
FONT_SPACING,
|
|
||||||
true
|
|
||||||
};
|
|
||||||
@@ -1,125 +0,0 @@
|
|||||||
/*
|
|
||||||
* font3x6limited.c
|
|
||||||
*
|
|
||||||
* Created: 4/8/2015 11:31:21 AM
|
|
||||||
* Author: Baron Williams
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <core_pins.h>
|
|
||||||
#include <usb_serial.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 "fonts.h"
|
|
||||||
|
|
||||||
#define FONT_CHAR_FIRST 32
|
|
||||||
#define FONT_CHAR_LAST 96
|
|
||||||
#define FONT_CHARS 65
|
|
||||||
#define FONT_WIDTH 3
|
|
||||||
#define FONT_HEIGHT 6
|
|
||||||
#define FONT_SPACING 1
|
|
||||||
|
|
||||||
static const uint8_t font3x6limitedData[FONT_CHARS][FONT_WIDTH] ={
|
|
||||||
{ 0x00,0x00,0x00, }, // ' ' 32
|
|
||||||
{ 0x00,0x5C,0x00, }, // '!' 33
|
|
||||||
{ 0x0C,0x00,0x0C, }, // '"' 34
|
|
||||||
{ 0x7C,0x28,0x7C, }, // '#' 35
|
|
||||||
{ 0x7C,0x44,0x7C, }, // '$' 36
|
|
||||||
{ 0x24,0x10,0x48, }, // '%' 37
|
|
||||||
{ 0x28,0x54,0x08, }, // '&' 38
|
|
||||||
{ 0x00,0x0C,0x00, }, // ''' 39
|
|
||||||
{ 0x38,0x44,0x00, }, // '(' 40
|
|
||||||
{ 0x44,0x38,0x00, }, // ')' 41
|
|
||||||
{ 0x20,0x10,0x08, }, // '*' 42
|
|
||||||
{ 0x10,0x38,0x10, }, // '+' 43
|
|
||||||
{ 0x80,0x40,0x00, }, // ',' 44
|
|
||||||
{ 0x10,0x10,0x10, }, // '-' 45
|
|
||||||
{ 0x00,0x40,0x00, }, // '.' 46
|
|
||||||
{ 0x20,0x10,0x08, }, // '/' 47
|
|
||||||
{ 0x38,0x44,0x38, }, // '0' 48
|
|
||||||
{ 0x00,0x7C,0x00, }, // '1' 49
|
|
||||||
{ 0x64,0x54,0x48, }, // '2' 50
|
|
||||||
{ 0x44,0x54,0x28, }, // '3' 51
|
|
||||||
{ 0x1C,0x10,0x7C, }, // '4' 52
|
|
||||||
{ 0x4C,0x54,0x24, }, // '5' 53
|
|
||||||
{ 0x38,0x54,0x20, }, // '6' 54
|
|
||||||
{ 0x04,0x74,0x0C, }, // '7' 55
|
|
||||||
{ 0x28,0x54,0x28, }, // '8' 56
|
|
||||||
{ 0x08,0x54,0x38, }, // '9' 57
|
|
||||||
{ 0x00,0x50,0x00, }, // ':' 58
|
|
||||||
{ 0x80,0x50,0x00, }, // ';' 59
|
|
||||||
{ 0x10,0x28,0x44, }, // '<' 60
|
|
||||||
{ 0x28,0x28,0x28, }, // '=' 61
|
|
||||||
{ 0x44,0x28,0x10, }, // '>' 62
|
|
||||||
{ 0x04,0x54,0x08, }, // '?' 63
|
|
||||||
{ 0x38,0x4C,0x5C, }, // '@' 64
|
|
||||||
{ 0x78,0x14,0x78, }, // 'A' 65
|
|
||||||
{ 0x7C,0x54,0x28, }, // 'B' 66
|
|
||||||
{ 0x38,0x44,0x44, }, // 'C' 67
|
|
||||||
{ 0x7C,0x44,0x38, }, // 'D' 68
|
|
||||||
{ 0x7C,0x54,0x44, }, // 'E' 69
|
|
||||||
{ 0x7C,0x14,0x04, }, // 'F' 70
|
|
||||||
{ 0x38,0x44,0x34, }, // 'G' 71
|
|
||||||
{ 0x7C,0x10,0x7C, }, // 'H' 72
|
|
||||||
{ 0x00,0x7C,0x00, }, // 'I' 73
|
|
||||||
{ 0x20,0x40,0x3C, }, // 'J' 74
|
|
||||||
{ 0x7C,0x10,0x6C, }, // 'K' 75
|
|
||||||
{ 0x7C,0x40,0x40, }, // 'L' 76
|
|
||||||
{ 0x7C,0x08,0x7C, }, // 'M' 77
|
|
||||||
{ 0x7C,0x04,0x7C, }, // 'N' 78
|
|
||||||
{ 0x7C,0x44,0x7C, }, // 'O' 79
|
|
||||||
{ 0x7C,0x14,0x08, }, // 'P' 80
|
|
||||||
{ 0x38,0x44,0x78, }, // 'Q' 81
|
|
||||||
{ 0x7C,0x14,0x68, }, // 'R' 82
|
|
||||||
{ 0x48,0x54,0x24, }, // 'S' 83
|
|
||||||
{ 0x04,0x7C,0x04, }, // 'T' 84
|
|
||||||
{ 0x7C,0x40,0x7C, }, // 'U' 85
|
|
||||||
{ 0x3C,0x40,0x3C, }, // 'V' 86
|
|
||||||
{ 0x7C,0x20,0x7C, }, // 'W' 87
|
|
||||||
{ 0x6C,0x10,0x6C, }, // 'X' 88
|
|
||||||
{ 0x1C,0x60,0x1C, }, // 'Y' 89
|
|
||||||
{ 0x64,0x54,0x4C, }, // 'Z' 90
|
|
||||||
{ 0x7C,0x44,0x00, }, // '[' 91
|
|
||||||
{ 0x08,0x10,0x20, }, // '\' 92
|
|
||||||
{ 0x44,0x7C,0x00, }, // ']' 93
|
|
||||||
{ 0x08,0x04,0x08, }, // '^' 94
|
|
||||||
{ 0x80,0x80,0x80, }, // '_' 95
|
|
||||||
{ 0x04,0x08,0x00 }, // '`' 96
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Font Size: 3x6 (no horizontal space, use as 4x6)
|
|
||||||
* Characters: 65 (ASCII 32-96). No lowercase, missing everything above 96
|
|
||||||
* Bit format: vertical
|
|
||||||
* Memory: 195 bytes (65x3)
|
|
||||||
*/
|
|
||||||
const fontStruct font3x6limited = {
|
|
||||||
(byte *) font3x6limitedData,
|
|
||||||
FONT_CHARS,
|
|
||||||
FONT_CHAR_FIRST,
|
|
||||||
FONT_CHAR_LAST,
|
|
||||||
FONT_WIDTH,
|
|
||||||
FONT_HEIGHT,
|
|
||||||
FONT_SPACING,
|
|
||||||
true
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,154 +0,0 @@
|
|||||||
/*
|
|
||||||
* font5x7.c
|
|
||||||
*
|
|
||||||
* Created: 4/8/2015 11:31:21 AM
|
|
||||||
* Author: Baron Williams
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <core_pins.h>
|
|
||||||
#include <usb_serial.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 "fonts.h"
|
|
||||||
|
|
||||||
#define FONT_CHAR_FIRST 32
|
|
||||||
#define FONT_CHAR_LAST 126
|
|
||||||
#define FONT_CHARS 95
|
|
||||||
#define FONT_WIDTH 5
|
|
||||||
#define FONT_HEIGHT 7
|
|
||||||
#define FONT_SPACING 1
|
|
||||||
|
|
||||||
static const uint8_t font5x7data[FONT_CHARS][FONT_WIDTH] ={
|
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, }, // ' ' 32
|
|
||||||
{ 0x00, 0x00, 0x5F, 0x00, 0x00, }, // '!' 33
|
|
||||||
{ 0x00, 0x03, 0x00, 0x03, 0x00, }, // '"' 34
|
|
||||||
{ 0x14, 0x3E, 0x14, 0x3E, 0x14, }, // '#' 35
|
|
||||||
{ 0x24, 0x2A, 0x7F, 0x2A, 0x12, }, // '$' 36
|
|
||||||
{ 0x43, 0x33, 0x08, 0x66, 0x61, }, // '%' 37
|
|
||||||
{ 0x36, 0x49, 0x55, 0x22, 0x50, }, // '&' 38
|
|
||||||
{ 0x00, 0x05, 0x03, 0x00, 0x00, }, // ''' 39
|
|
||||||
{ 0x00, 0x1C, 0x22, 0x41, 0x00, }, // '(' 40
|
|
||||||
{ 0x00, 0x41, 0x22, 0x1C, 0x00, }, // ')' 41
|
|
||||||
{ 0x14, 0x08, 0x3E, 0x08, 0x14, }, // '*' 42
|
|
||||||
{ 0x08, 0x08, 0x3E, 0x08, 0x08, }, // '+' 43
|
|
||||||
{ 0x00, 0x50, 0x30, 0x00, 0x00, }, // ',' 44
|
|
||||||
{ 0x08, 0x08, 0x08, 0x08, 0x08, }, // '-' 45
|
|
||||||
{ 0x00, 0x60, 0x60, 0x00, 0x00, }, // '.' 46
|
|
||||||
{ 0x20, 0x10, 0x08, 0x04, 0x02, }, // '/' 47
|
|
||||||
{ 0x3E, 0x51, 0x49, 0x45, 0x3E, }, // '0' 48
|
|
||||||
{ 0x04, 0x02, 0x7F, 0x00, 0x00, }, // '1' 49
|
|
||||||
{ 0x42, 0x61, 0x51, 0x49, 0x46, }, // '2' 50
|
|
||||||
{ 0x22, 0x41, 0x49, 0x49, 0x36, }, // '3' 51
|
|
||||||
{ 0x18, 0x14, 0x12, 0x7F, 0x10, }, // '4' 52
|
|
||||||
{ 0x27, 0x45, 0x45, 0x45, 0x39, }, // '5' 53
|
|
||||||
{ 0x3E, 0x49, 0x49, 0x49, 0x32, }, // '6' 54
|
|
||||||
{ 0x01, 0x01, 0x71, 0x09, 0x07, }, // '7' 55
|
|
||||||
{ 0x36, 0x49, 0x49, 0x49, 0x36, }, // '8' 56
|
|
||||||
{ 0x26, 0x49, 0x49, 0x49, 0x3E, }, // '9' 57
|
|
||||||
{ 0x00, 0x36, 0x36, 0x00, 0x00, }, // ':' 58
|
|
||||||
{ 0x00, 0x56, 0x36, 0x00, 0x00, }, // ';' 59
|
|
||||||
{ 0x08, 0x14, 0x22, 0x41, 0x00, }, // '<' 60
|
|
||||||
{ 0x14, 0x14, 0x14, 0x14, 0x14, }, // '=' 61
|
|
||||||
{ 0x00, 0x41, 0x22, 0x14, 0x08, }, // '>' 62
|
|
||||||
{ 0x02, 0x01, 0x51, 0x09, 0x06, }, // '?' 63
|
|
||||||
{ 0x3E, 0x41, 0x59, 0x55, 0x5E, }, // '@' 64
|
|
||||||
{ 0x7E, 0x09, 0x09, 0x09, 0x7E, }, // 'A' 65
|
|
||||||
{ 0x7F, 0x49, 0x49, 0x49, 0x36, }, // 'B' 66
|
|
||||||
{ 0x3E, 0x41, 0x41, 0x41, 0x22, }, // 'C' 67
|
|
||||||
{ 0x7F, 0x41, 0x41, 0x41, 0x3E, }, // 'D' 68
|
|
||||||
{ 0x7F, 0x49, 0x49, 0x49, 0x41, }, // 'E' 69
|
|
||||||
{ 0x7F, 0x09, 0x09, 0x09, 0x01, }, // 'F' 70
|
|
||||||
{ 0x3E, 0x41, 0x41, 0x49, 0x3A, }, // 'G' 71
|
|
||||||
{ 0x7F, 0x08, 0x08, 0x08, 0x7F, }, // 'H' 72
|
|
||||||
{ 0x00, 0x41, 0x7F, 0x41, 0x00, }, // 'I' 73
|
|
||||||
{ 0x30, 0x40, 0x40, 0x40, 0x3F, }, // 'J' 74
|
|
||||||
{ 0x7F, 0x08, 0x14, 0x22, 0x41, }, // 'K' 75
|
|
||||||
{ 0x7F, 0x40, 0x40, 0x40, 0x40, }, // 'L' 76
|
|
||||||
{ 0x7F, 0x02, 0x0C, 0x02, 0x7F, }, // 'M' 77
|
|
||||||
{ 0x7F, 0x02, 0x04, 0x08, 0x7F, }, // 'N' 78
|
|
||||||
{ 0x3E, 0x41, 0x41, 0x41, 0x3E, }, // 'O' 79
|
|
||||||
{ 0x7F, 0x09, 0x09, 0x09, 0x06, }, // 'P' 80
|
|
||||||
{ 0x1E, 0x21, 0x21, 0x21, 0x5E, }, // 'Q' 81
|
|
||||||
{ 0x7F, 0x09, 0x09, 0x09, 0x76, }, // 'R' 82
|
|
||||||
{ 0x26, 0x49, 0x49, 0x49, 0x32, }, // 'S' 83
|
|
||||||
{ 0x01, 0x01, 0x7F, 0x01, 0x01, }, // 'T' 84
|
|
||||||
{ 0x3F, 0x40, 0x40, 0x40, 0x3F, }, // 'U' 85
|
|
||||||
{ 0x1F, 0x20, 0x40, 0x20, 0x1F, }, // 'V' 86
|
|
||||||
{ 0x7F, 0x20, 0x10, 0x20, 0x7F, }, // 'W' 87
|
|
||||||
{ 0x41, 0x22, 0x1C, 0x22, 0x41, }, // 'X' 88
|
|
||||||
{ 0x07, 0x08, 0x70, 0x08, 0x07, }, // 'Y' 89
|
|
||||||
{ 0x61, 0x51, 0x49, 0x45, 0x43, }, // 'Z' 90
|
|
||||||
{ 0x00, 0x7F, 0x41, 0x00, 0x00, }, // '[' 91
|
|
||||||
{ 0x02, 0x04, 0x08, 0x10, 0x20, }, // '\' 92
|
|
||||||
{ 0x00, 0x00, 0x41, 0x7F, 0x00, }, // ']' 93
|
|
||||||
{ 0x04, 0x02, 0x01, 0x02, 0x04, }, // '^' 94
|
|
||||||
{ 0x40, 0x40, 0x40, 0x40, 0x40, }, // '_' 95
|
|
||||||
{ 0x00, 0x01, 0x02, 0x04, 0x00, }, // '`' 96
|
|
||||||
{ 0x20, 0x54, 0x54, 0x54, 0x78, }, // 'a' 97
|
|
||||||
{ 0x7F, 0x44, 0x44, 0x44, 0x38, }, // 'b' 98
|
|
||||||
{ 0x38, 0x44, 0x44, 0x44, 0x44, }, // 'c' 99
|
|
||||||
{ 0x38, 0x44, 0x44, 0x44, 0x7F, }, // 'd' 100
|
|
||||||
{ 0x38, 0x54, 0x54, 0x54, 0x18, }, // 'e' 101
|
|
||||||
{ 0x04, 0x04, 0x7E, 0x05, 0x05, }, // 'f' 102
|
|
||||||
{ 0x08, 0x54, 0x54, 0x54, 0x3C, }, // 'g' 103
|
|
||||||
{ 0x7F, 0x08, 0x04, 0x04, 0x78, }, // 'h' 104
|
|
||||||
{ 0x00, 0x44, 0x7D, 0x40, 0x00, }, // 'i' 105
|
|
||||||
{ 0x20, 0x40, 0x44, 0x3D, 0x00, }, // 'j' 106
|
|
||||||
{ 0x7F, 0x10, 0x28, 0x44, 0x00, }, // 'k' 107
|
|
||||||
{ 0x00, 0x41, 0x7F, 0x40, 0x00, }, // 'l' 108
|
|
||||||
{ 0x7C, 0x04, 0x78, 0x04, 0x78, }, // 'm' 109
|
|
||||||
{ 0x7C, 0x08, 0x04, 0x04, 0x78, }, // 'n' 110
|
|
||||||
{ 0x38, 0x44, 0x44, 0x44, 0x38, }, // 'o' 111
|
|
||||||
{ 0x7C, 0x14, 0x14, 0x14, 0x08, }, // 'p' 112
|
|
||||||
{ 0x08, 0x14, 0x14, 0x14, 0x7C, }, // 'q' 113
|
|
||||||
{ 0x00, 0x7C, 0x08, 0x04, 0x04, }, // 'r' 114
|
|
||||||
{ 0x48, 0x54, 0x54, 0x54, 0x20, }, // 's' 115
|
|
||||||
{ 0x04, 0x04, 0x3F, 0x44, 0x44, }, // 't' 116
|
|
||||||
{ 0x3C, 0x40, 0x40, 0x20, 0x7C, }, // 'u' 117
|
|
||||||
{ 0x1C, 0x20, 0x40, 0x20, 0x1C, }, // 'v' 118
|
|
||||||
{ 0x3C, 0x40, 0x30, 0x40, 0x3C, }, // 'w' 119
|
|
||||||
{ 0x44, 0x28, 0x10, 0x28, 0x44, }, // 'x' 120
|
|
||||||
{ 0x0C, 0x50, 0x50, 0x50, 0x3C, }, // 'y' 121
|
|
||||||
{ 0x44, 0x64, 0x54, 0x4C, 0x44, }, // 'z' 122
|
|
||||||
{ 0x00, 0x08, 0x36, 0x41, 0x41, }, // '{' 123
|
|
||||||
{ 0x00, 0x00, 0x7F, 0x00, 0x00, }, // '|' 124
|
|
||||||
{ 0x41, 0x41, 0x36, 0x08, 0x00, }, // '}' 125
|
|
||||||
{ 0x02, 0x01, 0x02, 0x04, 0x02 }, // '~' 126
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Font Size: 5x7 (+space=6x7)
|
|
||||||
* Spacing: requires vertical spacing
|
|
||||||
* Characters: 95 (ASCII 32-126).
|
|
||||||
* Bit format: vertical
|
|
||||||
* Memory: 475 bytes (95x5)
|
|
||||||
*/
|
|
||||||
const fontStruct font5x7 = {
|
|
||||||
(byte *) font5x7data,
|
|
||||||
FONT_CHARS,
|
|
||||||
FONT_CHAR_FIRST,
|
|
||||||
FONT_CHAR_LAST,
|
|
||||||
FONT_WIDTH,
|
|
||||||
FONT_HEIGHT,
|
|
||||||
FONT_SPACING,
|
|
||||||
true
|
|
||||||
};
|
|
||||||
@@ -1,313 +0,0 @@
|
|||||||
/*
|
|
||||||
* font5x7extended.c
|
|
||||||
*
|
|
||||||
* Created: 4/8/2015 11:31:21 AM
|
|
||||||
* Author: Baron Williams
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <core_pins.h>
|
|
||||||
#include <usb_serial.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 "fonts.h"
|
|
||||||
|
|
||||||
#define FONT_CHAR_FIRST 0
|
|
||||||
#define FONT_CHAR_LAST 255
|
|
||||||
#define FONT_CHARS 255
|
|
||||||
#define FONT_WIDTH 5
|
|
||||||
#define FONT_HEIGHT 7
|
|
||||||
#define FONT_SPACING 1
|
|
||||||
|
|
||||||
static const uint8_t fontData5x7extended[FONT_CHARS][FONT_WIDTH] ={
|
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, },
|
|
||||||
{ 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, },
|
|
||||||
{ 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, },
|
|
||||||
{ 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, },
|
|
||||||
{ 0x18, 0x3C, 0x7E, 0x3C, 0x18, },
|
|
||||||
{ 0x1C, 0x57, 0x7D, 0x57, 0x1C, },
|
|
||||||
{ 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, },
|
|
||||||
{ 0x00, 0x18, 0x3C, 0x18, 0x00, },
|
|
||||||
{ 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, },
|
|
||||||
{ 0x00, 0x18, 0x24, 0x18, 0x00, },
|
|
||||||
{ 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, },
|
|
||||||
{ 0x30, 0x48, 0x3A, 0x06, 0x0E, },
|
|
||||||
{ 0x26, 0x29, 0x79, 0x29, 0x26, },
|
|
||||||
{ 0x40, 0x7F, 0x05, 0x05, 0x07, },
|
|
||||||
{ 0x40, 0x7F, 0x05, 0x25, 0x3F, },
|
|
||||||
{ 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, },
|
|
||||||
{ 0x7F, 0x3E, 0x1C, 0x1C, 0x08, },
|
|
||||||
{ 0x08, 0x1C, 0x1C, 0x3E, 0x7F, },
|
|
||||||
{ 0x14, 0x22, 0x7F, 0x22, 0x14, },
|
|
||||||
{ 0x5F, 0x5F, 0x00, 0x5F, 0x5F, },
|
|
||||||
{ 0x06, 0x09, 0x7F, 0x01, 0x7F, },
|
|
||||||
{ 0x00, 0x66, 0x89, 0x95, 0x6A, },
|
|
||||||
{ 0x60, 0x60, 0x60, 0x60, 0x60, },
|
|
||||||
{ 0x94, 0xA2, 0xFF, 0xA2, 0x94, },
|
|
||||||
{ 0x08, 0x04, 0x7E, 0x04, 0x08, },
|
|
||||||
{ 0x10, 0x20, 0x7E, 0x20, 0x10, },
|
|
||||||
{ 0x08, 0x08, 0x2A, 0x1C, 0x08, },
|
|
||||||
{ 0x08, 0x1C, 0x2A, 0x08, 0x08, },
|
|
||||||
{ 0x1E, 0x10, 0x10, 0x10, 0x10, },
|
|
||||||
{ 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, },
|
|
||||||
{ 0x30, 0x38, 0x3E, 0x38, 0x30, },
|
|
||||||
{ 0x06, 0x0E, 0x3E, 0x0E, 0x06, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, }, // ' ' 32
|
|
||||||
{ 0x00, 0x00, 0x5F, 0x00, 0x00, }, // '!' 33
|
|
||||||
{ 0x00, 0x07, 0x00, 0x07, 0x00, }, // '"' 34
|
|
||||||
{ 0x14, 0x7F, 0x14, 0x7F, 0x14, }, // '#' 35
|
|
||||||
{ 0x24, 0x2A, 0x7F, 0x2A, 0x12, }, // '$' 36
|
|
||||||
{ 0x23, 0x13, 0x08, 0x64, 0x62, }, // '%' 37
|
|
||||||
{ 0x36, 0x49, 0x56, 0x20, 0x50, }, // '&' 38
|
|
||||||
{ 0x00, 0x08, 0x07, 0x03, 0x00, }, // ''' 39
|
|
||||||
{ 0x00, 0x1C, 0x22, 0x41, 0x00, }, // '(' 40
|
|
||||||
{ 0x00, 0x41, 0x22, 0x1C, 0x00, }, // ')' 41
|
|
||||||
{ 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, }, // '*' 42
|
|
||||||
{ 0x08, 0x08, 0x3E, 0x08, 0x08, }, // '+' 43
|
|
||||||
{ 0x00, 0x80, 0x70, 0x30, 0x00, }, // ',' 44
|
|
||||||
{ 0x08, 0x08, 0x08, 0x08, 0x08, }, // '-' 45
|
|
||||||
{ 0x00, 0x00, 0x60, 0x60, 0x00, }, // '.' 46
|
|
||||||
{ 0x20, 0x10, 0x08, 0x04, 0x02, }, // '/' 47
|
|
||||||
{ 0x3E, 0x51, 0x49, 0x45, 0x3E, }, // '0' 48
|
|
||||||
{ 0x00, 0x42, 0x7F, 0x40, 0x00, }, // '1' 49
|
|
||||||
{ 0x72, 0x49, 0x49, 0x49, 0x46, }, // '2' 50
|
|
||||||
{ 0x21, 0x41, 0x49, 0x4D, 0x33, }, // '3' 51
|
|
||||||
{ 0x18, 0x14, 0x12, 0x7F, 0x10, }, // '4' 52
|
|
||||||
{ 0x27, 0x45, 0x45, 0x45, 0x39, }, // '5' 53
|
|
||||||
{ 0x3C, 0x4A, 0x49, 0x49, 0x31, }, // '6' 54
|
|
||||||
{ 0x41, 0x21, 0x11, 0x09, 0x07, }, // '7' 55
|
|
||||||
{ 0x36, 0x49, 0x49, 0x49, 0x36, }, // '8' 56
|
|
||||||
{ 0x46, 0x49, 0x49, 0x29, 0x1E, }, // '9' 57
|
|
||||||
{ 0x00, 0x00, 0x14, 0x00, 0x00, }, // ':' 58
|
|
||||||
{ 0x00, 0x40, 0x34, 0x00, 0x00, }, // ';' 59
|
|
||||||
{ 0x00, 0x08, 0x14, 0x22, 0x41, }, // '<' 60
|
|
||||||
{ 0x14, 0x14, 0x14, 0x14, 0x14, }, // '=' 61
|
|
||||||
{ 0x00, 0x41, 0x22, 0x14, 0x08, }, // '>' 62
|
|
||||||
{ 0x02, 0x01, 0x59, 0x09, 0x06, }, // '?' 63
|
|
||||||
{ 0x3E, 0x41, 0x5D, 0x59, 0x4E, }, // '@' 64
|
|
||||||
{ 0x7C, 0x12, 0x11, 0x12, 0x7C, }, // 'A' 65
|
|
||||||
{ 0x7F, 0x49, 0x49, 0x49, 0x36, }, // 'B' 66
|
|
||||||
{ 0x3E, 0x41, 0x41, 0x41, 0x22, }, // 'C' 67
|
|
||||||
{ 0x7F, 0x41, 0x41, 0x41, 0x3E, }, // 'D' 68
|
|
||||||
{ 0x7F, 0x49, 0x49, 0x49, 0x41, }, // 'E' 69
|
|
||||||
{ 0x7F, 0x09, 0x09, 0x09, 0x01, }, // 'F' 70
|
|
||||||
{ 0x3E, 0x41, 0x41, 0x51, 0x73, }, // 'G' 71
|
|
||||||
{ 0x7F, 0x08, 0x08, 0x08, 0x7F, }, // 'H' 72
|
|
||||||
{ 0x00, 0x41, 0x7F, 0x41, 0x00, }, // 'I' 73
|
|
||||||
{ 0x20, 0x40, 0x41, 0x3F, 0x01, }, // 'J' 74
|
|
||||||
{ 0x7F, 0x08, 0x14, 0x22, 0x41, }, // 'K' 75
|
|
||||||
{ 0x7F, 0x40, 0x40, 0x40, 0x40, }, // 'L' 76
|
|
||||||
{ 0x7F, 0x02, 0x1C, 0x02, 0x7F, }, // 'M' 77
|
|
||||||
{ 0x7F, 0x04, 0x08, 0x10, 0x7F, }, // 'N' 78
|
|
||||||
{ 0x3E, 0x41, 0x41, 0x41, 0x3E, }, // 'O' 79
|
|
||||||
{ 0x7F, 0x09, 0x09, 0x09, 0x06, }, // 'P' 80
|
|
||||||
{ 0x3E, 0x41, 0x51, 0x21, 0x5E, }, // 'Q' 81
|
|
||||||
{ 0x7F, 0x09, 0x19, 0x29, 0x46, }, // 'R' 82
|
|
||||||
{ 0x26, 0x49, 0x49, 0x49, 0x32, }, // 'S' 83
|
|
||||||
{ 0x03, 0x01, 0x7F, 0x01, 0x03, }, // 'T' 84
|
|
||||||
{ 0x3F, 0x40, 0x40, 0x40, 0x3F, }, // 'U' 85
|
|
||||||
{ 0x1F, 0x20, 0x40, 0x20, 0x1F, }, // 'V' 86
|
|
||||||
{ 0x3F, 0x40, 0x38, 0x40, 0x3F, }, // 'W' 87
|
|
||||||
{ 0x63, 0x14, 0x08, 0x14, 0x63, }, // 'X' 88
|
|
||||||
{ 0x03, 0x04, 0x78, 0x04, 0x03, }, // 'Y' 89
|
|
||||||
{ 0x61, 0x59, 0x49, 0x4D, 0x43, }, // 'Z' 90
|
|
||||||
{ 0x00, 0x7F, 0x41, 0x41, 0x41, }, // '[' 91
|
|
||||||
{ 0x02, 0x04, 0x08, 0x10, 0x20, }, // '\' 92
|
|
||||||
{ 0x00, 0x41, 0x41, 0x41, 0x7F, }, // ']' 93
|
|
||||||
{ 0x04, 0x02, 0x01, 0x02, 0x04, }, // '^' 94
|
|
||||||
{ 0x40, 0x40, 0x40, 0x40, 0x40, }, // '_' 95
|
|
||||||
{ 0x00, 0x03, 0x07, 0x08, 0x00, }, // '`' 96
|
|
||||||
{ 0x20, 0x54, 0x54, 0x78, 0x40, }, // 'a' 97
|
|
||||||
{ 0x7F, 0x28, 0x44, 0x44, 0x38, }, // 'b' 98
|
|
||||||
{ 0x38, 0x44, 0x44, 0x44, 0x28, }, // 'c' 99
|
|
||||||
{ 0x38, 0x44, 0x44, 0x28, 0x7F, }, // 'd' 100
|
|
||||||
{ 0x38, 0x54, 0x54, 0x54, 0x18, }, // 'e' 101
|
|
||||||
{ 0x00, 0x08, 0x7E, 0x09, 0x02, }, // 'f' 102
|
|
||||||
{ 0x18, 0xA4, 0xA4, 0x9C, 0x78, }, // 'g' 103
|
|
||||||
{ 0x7F, 0x08, 0x04, 0x04, 0x78, }, // 'h' 104
|
|
||||||
{ 0x00, 0x44, 0x7D, 0x40, 0x00, }, // 'i' 105
|
|
||||||
{ 0x20, 0x40, 0x40, 0x3D, 0x00, }, // 'j' 106
|
|
||||||
{ 0x7F, 0x10, 0x28, 0x44, 0x00, }, // 'k' 107
|
|
||||||
{ 0x00, 0x41, 0x7F, 0x40, 0x00, }, // 'l' 108
|
|
||||||
{ 0x7C, 0x04, 0x78, 0x04, 0x78, }, // 'm' 109
|
|
||||||
{ 0x7C, 0x08, 0x04, 0x04, 0x78, }, // 'n' 110
|
|
||||||
{ 0x38, 0x44, 0x44, 0x44, 0x38, }, // 'o' 111
|
|
||||||
{ 0xFC, 0x18, 0x24, 0x24, 0x18, }, // 'p' 112
|
|
||||||
{ 0x18, 0x24, 0x24, 0x18, 0xFC, }, // 'q' 113
|
|
||||||
{ 0x7C, 0x08, 0x04, 0x04, 0x08, }, // 'r' 114
|
|
||||||
{ 0x48, 0x54, 0x54, 0x54, 0x24, }, // 's' 115
|
|
||||||
{ 0x04, 0x04, 0x3F, 0x44, 0x24, }, // 't' 116
|
|
||||||
{ 0x3C, 0x40, 0x40, 0x20, 0x7C, }, // 'u' 117
|
|
||||||
{ 0x1C, 0x20, 0x40, 0x20, 0x1C, }, // 'v' 118
|
|
||||||
{ 0x3C, 0x40, 0x30, 0x40, 0x3C, }, // 'w' 119
|
|
||||||
{ 0x44, 0x28, 0x10, 0x28, 0x44, }, // 'x' 120
|
|
||||||
{ 0x4C, 0x90, 0x90, 0x90, 0x7C, }, // 'y' 121
|
|
||||||
{ 0x44, 0x64, 0x54, 0x4C, 0x44, }, // 'z' 122
|
|
||||||
{ 0x00, 0x08, 0x36, 0x41, 0x00, }, // '{' 123
|
|
||||||
{ 0x00, 0x00, 0x77, 0x00, 0x00, }, // '|' 124
|
|
||||||
{ 0x00, 0x41, 0x36, 0x08, 0x00, }, // '}' 125
|
|
||||||
{ 0x02, 0x01, 0x02, 0x04, 0x02, }, // '~' 126
|
|
||||||
{ 0x3C, 0x26, 0x23, 0x26, 0x3C, },
|
|
||||||
{ 0x1E, 0xA1, 0xA1, 0x61, 0x12, },
|
|
||||||
{ 0x3A, 0x40, 0x40, 0x20, 0x7A, },
|
|
||||||
{ 0x38, 0x54, 0x54, 0x55, 0x59, },
|
|
||||||
{ 0x21, 0x55, 0x55, 0x79, 0x41, },
|
|
||||||
{ 0x22, 0x54, 0x54, 0x78, 0x42, }, // a-umlaut
|
|
||||||
{ 0x21, 0x55, 0x54, 0x78, 0x40, },
|
|
||||||
{ 0x20, 0x54, 0x55, 0x79, 0x40, },
|
|
||||||
{ 0x0C, 0x1E, 0x52, 0x72, 0x12, },
|
|
||||||
{ 0x39, 0x55, 0x55, 0x55, 0x59, },
|
|
||||||
{ 0x39, 0x54, 0x54, 0x54, 0x59, },
|
|
||||||
{ 0x39, 0x55, 0x54, 0x54, 0x58, },
|
|
||||||
{ 0x00, 0x00, 0x45, 0x7C, 0x41, },
|
|
||||||
{ 0x00, 0x02, 0x45, 0x7D, 0x42, },
|
|
||||||
{ 0x00, 0x01, 0x45, 0x7C, 0x40, },
|
|
||||||
{ 0x7D, 0x12, 0x11, 0x12, 0x7D, }, // A-umlaut
|
|
||||||
{ 0xF0, 0x28, 0x25, 0x28, 0xF0, },
|
|
||||||
{ 0x7C, 0x54, 0x55, 0x45, 0x00, },
|
|
||||||
{ 0x20, 0x54, 0x54, 0x7C, 0x54, },
|
|
||||||
{ 0x7C, 0x0A, 0x09, 0x7F, 0x49, },
|
|
||||||
{ 0x32, 0x49, 0x49, 0x49, 0x32, },
|
|
||||||
{ 0x3A, 0x44, 0x44, 0x44, 0x3A, }, // o-umlaut
|
|
||||||
{ 0x32, 0x4A, 0x48, 0x48, 0x30, },
|
|
||||||
{ 0x3A, 0x41, 0x41, 0x21, 0x7A, },
|
|
||||||
{ 0x3A, 0x42, 0x40, 0x20, 0x78, },
|
|
||||||
{ 0x00, 0x9D, 0xA0, 0xA0, 0x7D, },
|
|
||||||
{ 0x3D, 0x42, 0x42, 0x42, 0x3D, }, // O-umlaut
|
|
||||||
{ 0x3D, 0x40, 0x40, 0x40, 0x3D, },
|
|
||||||
{ 0x3C, 0x24, 0xFF, 0x24, 0x24, },
|
|
||||||
{ 0x48, 0x7E, 0x49, 0x43, 0x66, },
|
|
||||||
{ 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, },
|
|
||||||
{ 0xFF, 0x09, 0x29, 0xF6, 0x20, },
|
|
||||||
{ 0xC0, 0x88, 0x7E, 0x09, 0x03, },
|
|
||||||
{ 0x20, 0x54, 0x54, 0x79, 0x41, },
|
|
||||||
{ 0x00, 0x00, 0x44, 0x7D, 0x41, },
|
|
||||||
{ 0x30, 0x48, 0x48, 0x4A, 0x32, },
|
|
||||||
{ 0x38, 0x40, 0x40, 0x22, 0x7A, },
|
|
||||||
{ 0x00, 0x7A, 0x0A, 0x0A, 0x72, },
|
|
||||||
{ 0x7D, 0x0D, 0x19, 0x31, 0x7D, },
|
|
||||||
{ 0x26, 0x29, 0x29, 0x2F, 0x28, },
|
|
||||||
{ 0x26, 0x29, 0x29, 0x29, 0x26, },
|
|
||||||
{ 0x30, 0x48, 0x4D, 0x40, 0x20, },
|
|
||||||
{ 0x38, 0x08, 0x08, 0x08, 0x08, },
|
|
||||||
{ 0x08, 0x08, 0x08, 0x08, 0x38, },
|
|
||||||
{ 0x2F, 0x10, 0xC8, 0xAC, 0xBA, },
|
|
||||||
{ 0x2F, 0x10, 0x28, 0x34, 0xFA, },
|
|
||||||
{ 0x00, 0x00, 0x7B, 0x00, 0x00, },
|
|
||||||
{ 0x08, 0x14, 0x2A, 0x14, 0x22, },
|
|
||||||
{ 0x22, 0x14, 0x2A, 0x14, 0x08, },
|
|
||||||
{ 0xAA, 0x00, 0x55, 0x00, 0xAA, },
|
|
||||||
{ 0xAA, 0x55, 0xAA, 0x55, 0xAA, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0xFF, 0x00, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0xFF, 0x00, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0xFF, 0x00, },
|
|
||||||
{ 0x10, 0x10, 0xFF, 0x00, 0xFF, },
|
|
||||||
{ 0x10, 0x10, 0xF0, 0x10, 0xF0, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0xFC, 0x00, },
|
|
||||||
{ 0x14, 0x14, 0xF7, 0x00, 0xFF, },
|
|
||||||
{ 0x00, 0x00, 0xFF, 0x00, 0xFF, },
|
|
||||||
{ 0x14, 0x14, 0xF4, 0x04, 0xFC, },
|
|
||||||
{ 0x14, 0x14, 0x17, 0x10, 0x1F, },
|
|
||||||
{ 0x10, 0x10, 0x1F, 0x10, 0x1F, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0x1F, 0x00, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0xF0, 0x00, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0x1F, 0x10, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0x1F, 0x10, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0xF0, 0x10, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0xFF, 0x10, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0x10, 0x10, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0xFF, 0x10, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0xFF, 0x14, },
|
|
||||||
{ 0x00, 0x00, 0xFF, 0x00, 0xFF, },
|
|
||||||
{ 0x00, 0x00, 0x1F, 0x10, 0x17, },
|
|
||||||
{ 0x00, 0x00, 0xFC, 0x04, 0xF4, },
|
|
||||||
{ 0x14, 0x14, 0x17, 0x10, 0x17, },
|
|
||||||
{ 0x14, 0x14, 0xF4, 0x04, 0xF4, },
|
|
||||||
{ 0x00, 0x00, 0xFF, 0x00, 0xF7, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0x14, 0x14, },
|
|
||||||
{ 0x14, 0x14, 0xF7, 0x00, 0xF7, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0x17, 0x14, },
|
|
||||||
{ 0x10, 0x10, 0x1F, 0x10, 0x1F, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0xF4, 0x14, },
|
|
||||||
{ 0x10, 0x10, 0xF0, 0x10, 0xF0, },
|
|
||||||
{ 0x00, 0x00, 0x1F, 0x10, 0x1F, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0x1F, 0x14, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0xFC, 0x14, },
|
|
||||||
{ 0x00, 0x00, 0xF0, 0x10, 0xF0, },
|
|
||||||
{ 0x10, 0x10, 0xFF, 0x10, 0xFF, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0xFF, 0x14, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0x1F, 0x00, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0xF0, 0x10, },
|
|
||||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, },
|
|
||||||
{ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, },
|
|
||||||
{ 0xFF, 0xFF, 0xFF, 0x00, 0x00, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0xFF, 0xFF, },
|
|
||||||
{ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, },
|
|
||||||
{ 0x38, 0x44, 0x44, 0x38, 0x44, },
|
|
||||||
{ 0xFC, 0x4A, 0x4A, 0x4A, 0x34, }, // sharp-s or beta
|
|
||||||
{ 0x7E, 0x02, 0x02, 0x06, 0x06, },
|
|
||||||
{ 0x02, 0x7E, 0x02, 0x7E, 0x02, },
|
|
||||||
{ 0x63, 0x55, 0x49, 0x41, 0x63, },
|
|
||||||
{ 0x38, 0x44, 0x44, 0x3C, 0x04, },
|
|
||||||
{ 0x40, 0x7E, 0x20, 0x1E, 0x20, },
|
|
||||||
{ 0x06, 0x02, 0x7E, 0x02, 0x02, },
|
|
||||||
{ 0x99, 0xA5, 0xE7, 0xA5, 0x99, },
|
|
||||||
{ 0x1C, 0x2A, 0x49, 0x2A, 0x1C, },
|
|
||||||
{ 0x4C, 0x72, 0x01, 0x72, 0x4C, },
|
|
||||||
{ 0x30, 0x4A, 0x4D, 0x4D, 0x30, },
|
|
||||||
{ 0x30, 0x48, 0x78, 0x48, 0x30, },
|
|
||||||
{ 0xBC, 0x62, 0x5A, 0x46, 0x3D, },
|
|
||||||
{ 0x3E, 0x49, 0x49, 0x49, 0x00, },
|
|
||||||
{ 0x7E, 0x01, 0x01, 0x01, 0x7E, },
|
|
||||||
{ 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, },
|
|
||||||
{ 0x44, 0x44, 0x5F, 0x44, 0x44, },
|
|
||||||
{ 0x40, 0x51, 0x4A, 0x44, 0x40, },
|
|
||||||
{ 0x40, 0x44, 0x4A, 0x51, 0x40, },
|
|
||||||
{ 0x00, 0x00, 0xFF, 0x01, 0x03, },
|
|
||||||
{ 0xE0, 0x80, 0xFF, 0x00, 0x00, },
|
|
||||||
{ 0x08, 0x08, 0x6B, 0x6B, 0x08, },
|
|
||||||
{ 0x36, 0x12, 0x36, 0x24, 0x36, },
|
|
||||||
{ 0x06, 0x0F, 0x09, 0x0F, 0x06, },
|
|
||||||
{ 0x00, 0x00, 0x18, 0x18, 0x00, },
|
|
||||||
{ 0x00, 0x00, 0x10, 0x10, 0x00, },
|
|
||||||
{ 0x30, 0x40, 0xFF, 0x01, 0x01, },
|
|
||||||
{ 0x00, 0x1F, 0x01, 0x01, 0x1E, },
|
|
||||||
{ 0x00, 0x19, 0x1D, 0x17, 0x12, },
|
|
||||||
{ 0x00, 0x3C, 0x3C, 0x3C, 0x3C, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00 },
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Font Size: 5x7 (no horizontal space, use as 6x7)
|
|
||||||
* Characters: 256 (ASCII 0-255).
|
|
||||||
* Bit format: vertical
|
|
||||||
* Memory: 1280 bytes (256x5)
|
|
||||||
*/
|
|
||||||
const fontStruct font5x7extended = {
|
|
||||||
(byte *) fontData5x7extended,
|
|
||||||
FONT_CHARS,
|
|
||||||
FONT_CHAR_FIRST,
|
|
||||||
FONT_CHAR_LAST,
|
|
||||||
FONT_WIDTH,
|
|
||||||
FONT_HEIGHT,
|
|
||||||
FONT_SPACING,
|
|
||||||
true
|
|
||||||
};
|
|
||||||
@@ -1,153 +0,0 @@
|
|||||||
/*
|
|
||||||
* font7x8.c
|
|
||||||
*
|
|
||||||
* Created: 4/8/2015 11:31:21 AM
|
|
||||||
* Author: Baron Williams
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <core_pins.h>
|
|
||||||
#include <usb_serial.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 "fonts.h"
|
|
||||||
|
|
||||||
#define FONT_CHAR_FIRST 32
|
|
||||||
#define FONT_CHAR_LAST 126
|
|
||||||
#define FONT_CHARS 95
|
|
||||||
#define FONT_WIDTH 7
|
|
||||||
#define FONT_HEIGHT 8
|
|
||||||
#define FONT_SPACING 1
|
|
||||||
|
|
||||||
static const uint8_t fontData7x8[FONT_CHARS][FONT_WIDTH]= {
|
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, }, // ' ' 32
|
|
||||||
{ 0, 6, 95, 95, 6, 0, 0, }, // '!' 33
|
|
||||||
{ 0, 7, 7, 0, 7, 7, 0, }, // '"' 34
|
|
||||||
{ 20, 127, 127, 20, 127, 127, 20, }, // '#' 35
|
|
||||||
{ 36, 46, 107, 107, 58, 18, 0, }, // '$' 36
|
|
||||||
{ 70, 102, 48, 24, 12, 102, 98, }, // '%' 37
|
|
||||||
{ 48, 122, 79, 93, 55, 122, 72, }, // '&' 38
|
|
||||||
{ 4, 7, 3, 0, 0, 0, 0, }, // ''' 39
|
|
||||||
{ 0, 28, 62, 99, 65, 0, 0, }, // '(' 40
|
|
||||||
{ 0, 65, 99, 62, 28, 0, 0, }, // ')' 41
|
|
||||||
{ 8, 42, 62, 28, 28, 62, 42, }, // '*' 42
|
|
||||||
{ 8, 8, 62, 62, 8, 8, 0, }, // '+' 43
|
|
||||||
{ 0, 128, 224, 96, 0, 0, 0, }, // ',' 44
|
|
||||||
{ 8, 8, 8, 8, 8, 8, 0, }, // '-' 45
|
|
||||||
{ 0, 0, 96, 96, 0, 0, 0, }, // '.' 46
|
|
||||||
{ 96, 48, 24, 12, 6, 3, 1, }, // '/' 47
|
|
||||||
{ 62, 127, 113, 89, 77, 127, 62, }, // '0' 48
|
|
||||||
{ 64, 66, 127, 127, 64, 64, 0, }, // '1' 49
|
|
||||||
{ 98, 115, 89, 73, 111, 102, 0, }, // '2' 50
|
|
||||||
{ 34, 99, 73, 73, 127, 54, 0, }, // '3' 51
|
|
||||||
{ 24, 28, 22, 83, 127, 127, 80, }, // '4' 52
|
|
||||||
{ 39, 103, 69, 69, 125, 57, 0, }, // '5' 53
|
|
||||||
{ 60, 126, 75, 73, 121, 48, 0, }, // '6' 54
|
|
||||||
{ 3, 3, 113, 121, 15, 7, 0, }, // '7' 55
|
|
||||||
{ 54, 127, 73, 73, 127, 54, 0, }, // '8' 56
|
|
||||||
{ 6, 79, 73, 105, 63, 30, 0, }, // '9' 57
|
|
||||||
{ 0, 0, 102, 102, 0, 0, 0, }, // ':' 58
|
|
||||||
{ 0, 128, 230, 102, 0, 0, 0, }, // ';' 59
|
|
||||||
{ 8, 28, 54, 99, 65, 0, 0, }, // '<' 60
|
|
||||||
{ 36, 36, 36, 36, 36, 36, 0, }, // '=' 61
|
|
||||||
{ 0, 65, 99, 54, 28, 8, 0, }, // '>' 62
|
|
||||||
{ 2, 3, 81, 89, 15, 6, 0, }, // '?' 63
|
|
||||||
{ 62, 127, 65, 93, 93, 31, 30, }, // '@' 64
|
|
||||||
{ 124,126, 19, 19, 126, 124, 0, }, // 'A' 65
|
|
||||||
{ 65, 127, 127, 73, 73, 127, 54, }, // 'B' 66
|
|
||||||
{ 28, 62, 99, 65, 65, 99, 34, }, // 'C' 67
|
|
||||||
{ 65, 127, 127, 65, 99, 62, 28, }, // 'D' 68
|
|
||||||
{ 65, 127, 127, 73, 93, 65, 99, }, // 'E' 69
|
|
||||||
{ 65, 127, 127, 73, 29, 1, 3, }, // 'F' 70
|
|
||||||
{ 28, 62, 99, 65, 81, 115, 114, }, // 'G' 71
|
|
||||||
{ 127,127, 8, 8, 127, 127, 0, }, // 'H' 72
|
|
||||||
{ 0, 65, 127, 127, 65, 0, 0, }, // 'I' 73
|
|
||||||
{ 48, 112, 64, 65, 127, 63, 1, }, // 'J' 74
|
|
||||||
{ 65, 127, 127, 8, 28, 119, 99, }, // 'K' 75
|
|
||||||
{ 65, 127, 127, 65, 64, 96, 112, }, // 'L' 76
|
|
||||||
{ 127,127, 14, 28, 14, 127, 127, }, // 'M' 77
|
|
||||||
{ 127,127, 6, 12, 24, 127, 127, }, // 'N' 78
|
|
||||||
{ 28, 62, 99, 65, 99, 62, 28, }, // 'O' 79
|
|
||||||
{ 65, 127, 127, 73, 9, 15, 6, }, // 'P' 80
|
|
||||||
{ 30, 63, 33, 113, 127, 94, 0, }, // 'Q' 81
|
|
||||||
{ 65, 127, 127, 9, 25, 127, 102, }, // 'R' 82
|
|
||||||
{ 38, 111, 77, 89, 115, 50, 0, }, // 'S' 83
|
|
||||||
{ 3, 65, 127, 127, 65, 3, 0, }, // 'T' 84
|
|
||||||
{ 127,127, 64, 64, 127, 127, 0, }, // 'U' 85
|
|
||||||
{ 31, 63, 96, 96, 63, 31, 0, }, // 'V' 86
|
|
||||||
{ 127,127, 48, 24, 48, 127, 127, }, // 'W' 87
|
|
||||||
{ 67, 103, 60, 24, 60, 103, 67, }, // 'X' 88
|
|
||||||
{ 7, 79, 120, 120, 79, 7, 0, }, // 'Y' 89
|
|
||||||
{ 71, 99, 113, 89, 77, 103, 115, }, // 'Z' 90
|
|
||||||
{ 0, 127, 127, 65, 65, 0, 0, }, // '[' 91
|
|
||||||
{ 1, 3, 6, 12, 24, 48, 96, }, // '\' 92
|
|
||||||
{ 0, 65, 65, 127, 127, 0, 0, }, // ']' 93
|
|
||||||
{ 8, 12, 6, 3, 6, 12, 8, }, // '^' 94
|
|
||||||
{ 128,128, 128, 128, 128, 128, 128, }, // '_' 95
|
|
||||||
{ 0, 0, 3, 7, 4, 0, 0, }, // '`' 96
|
|
||||||
{ 32, 116, 84, 84, 60, 120, 64, }, // 'a' 97
|
|
||||||
{ 65, 127, 63, 72, 72, 120, 48, }, // 'b' 98
|
|
||||||
{ 56, 124, 68, 68, 108, 40, 0, }, // 'c' 99
|
|
||||||
{ 48, 120, 72, 73, 63, 127, 64, }, // 'd' 100
|
|
||||||
{ 56, 124, 84, 84, 92, 24, 0, }, // 'e' 101
|
|
||||||
{ 72, 126, 127, 73, 3, 2, 0, }, // 'f' 102
|
|
||||||
{ 56, 188, 164, 164, 252, 120, 0, }, // 'g' 103
|
|
||||||
{ 65, 127, 127, 8, 4, 124, 120, }, // 'h' 104
|
|
||||||
{ 0, 68, 125, 125, 64, 0, 0, }, // 'i' 105
|
|
||||||
{ 96, 224, 128, 128, 253, 125, 0, }, // 'j' 106
|
|
||||||
{ 65, 127, 127, 16, 56, 108, 68, }, // 'k' 107
|
|
||||||
{ 0, 65, 127, 127, 64, 0, 0, }, // 'l' 108
|
|
||||||
{ 120,124, 28, 56, 28, 124, 120, }, // 'm' 109
|
|
||||||
{ 124,124, 4, 4, 124, 120, 0, }, // 'n' 110
|
|
||||||
{ 56, 124, 68, 68, 124, 56, 0, }, // 'o' 111
|
|
||||||
{ 0, 252, 252, 164, 36, 60, 24, }, // 'p' 112
|
|
||||||
{ 24, 60, 36, 164, 248, 252, 132, }, // 'q' 113
|
|
||||||
{ 68, 124, 120, 76, 4, 28, 24, }, // 'r' 114
|
|
||||||
{ 72, 92, 84, 84, 116, 36, 0, }, // 's' 115
|
|
||||||
{ 0, 4, 62, 127, 68, 36, 0, }, // 't' 116
|
|
||||||
{ 60, 124, 64, 64, 60, 124, 64, }, // 'u' 117
|
|
||||||
{ 28, 60, 96, 96, 60, 28, 0, }, // 'v' 118
|
|
||||||
{ 60, 124, 112, 56, 112, 124, 60, }, // 'w' 119
|
|
||||||
{ 68, 108, 56, 16, 56, 108, 68, }, // 'x' 120
|
|
||||||
{ 60, 188, 160, 160, 252, 124, 0, }, // 'y' 121
|
|
||||||
{ 76, 100, 116, 92, 76, 100, 0, }, // 'z' 122
|
|
||||||
{ 8, 8, 62, 119, 65, 65, 0, }, // '{' 123
|
|
||||||
{ 0, 0, 0, 119, 119, 0, 0, }, // '|' 124
|
|
||||||
{ 65, 65, 119, 62, 8, 8, 0, }, // '}' 125
|
|
||||||
{ 2, 3, 1, 3, 2, 3, 1, }, // '~' 126
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Font Size: 7x8 (+spacing=8x8)
|
|
||||||
* Characters: 95 (ASCII 32-126).
|
|
||||||
* Bit format: vertical
|
|
||||||
* Memory: 665 bytes (95x7)
|
|
||||||
*/
|
|
||||||
const fontStruct font7x8 = {
|
|
||||||
(byte *) fontData7x8,
|
|
||||||
FONT_CHARS,
|
|
||||||
FONT_CHAR_FIRST,
|
|
||||||
FONT_CHAR_LAST,
|
|
||||||
FONT_WIDTH,
|
|
||||||
FONT_HEIGHT,
|
|
||||||
FONT_SPACING,
|
|
||||||
true
|
|
||||||
};
|
|
||||||
@@ -1,317 +0,0 @@
|
|||||||
/*
|
|
||||||
* font7x8.c
|
|
||||||
*
|
|
||||||
* Created: 4/8/2015 11:31:21 AM
|
|
||||||
* Author: Philip Smart / Baron Williams
|
|
||||||
* This is an amalgamation of the extended portions of 5x7 with the 7x8 font, needed fonts are widened as required so most extended may
|
|
||||||
* still be in 5x7 format.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <core_pins.h>
|
|
||||||
#include <usb_serial.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 "fonts.h"
|
|
||||||
|
|
||||||
#define FONT_CHAR_FIRST 0
|
|
||||||
#define FONT_CHAR_LAST 255
|
|
||||||
#define FONT_CHARS 255
|
|
||||||
#define FONT_WIDTH 7
|
|
||||||
#define FONT_HEIGHT 8
|
|
||||||
#define FONT_SPACING 1
|
|
||||||
|
|
||||||
static const uint8_t fontData7x8extended[FONT_CHARS][FONT_WIDTH]= {
|
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0, 0, },
|
|
||||||
{ 0x3E, 0x5B, 0x4F, 0x5B, 0x3E, 0, 0, },
|
|
||||||
{ 0x3E, 0x6B, 0x4F, 0x6B, 0x3E, 0, 0, },
|
|
||||||
{ 0x1C, 0x3E, 0x7C, 0x3E, 0x1C, 0, 0, },
|
|
||||||
{ 0x18, 0x3C, 0x7E, 0x3C, 0x18, 0, 0, },
|
|
||||||
{ 0x1C, 0x57, 0x7D, 0x57, 0x1C, 0, 0, },
|
|
||||||
{ 0x1C, 0x5E, 0x7F, 0x5E, 0x1C, 0, 0, },
|
|
||||||
{ 0x00, 0x18, 0x3C, 0x18, 0x00, 0, 0, },
|
|
||||||
{ 0xFF, 0xE7, 0xC3, 0xE7, 0xFF, 0, 0, },
|
|
||||||
{ 0x00, 0x18, 0x24, 0x18, 0x00, 0, 0, },
|
|
||||||
{ 0xFF, 0xE7, 0xDB, 0xE7, 0xFF, 0, 0, },
|
|
||||||
{ 0x30, 0x48, 0x3A, 0x06, 0x0E, 0, 0, },
|
|
||||||
{ 0x26, 0x29, 0x79, 0x29, 0x26, 0, 0, },
|
|
||||||
{ 0x40, 0x7F, 0x05, 0x05, 0x07, 0, 0, },
|
|
||||||
{ 0x40, 0x7F, 0x05, 0x25, 0x3F, 0, 0, },
|
|
||||||
{ 0x5A, 0x3C, 0xE7, 0x3C, 0x5A, 0, 0, },
|
|
||||||
{ 0x7F, 0x3E, 0x1C, 0x1C, 0x08, 0, 0, },
|
|
||||||
{ 0x08, 0x1C, 0x1C, 0x3E, 0x7F, 0, 0, },
|
|
||||||
{ 0x14, 0x22, 0x7F, 0x22, 0x14, 0, 0, },
|
|
||||||
{ 0x5F, 0x5F, 0x00, 0x5F, 0x5F, 0, 0, },
|
|
||||||
{ 0x06, 0x09, 0x7F, 0x01, 0x7F, 0, 0, },
|
|
||||||
{ 0x00, 0x66, 0x89, 0x95, 0x6A, 0, 0, },
|
|
||||||
{ 0x60, 0x60, 0x60, 0x60, 0x60, 0, 0, },
|
|
||||||
{ 0x94, 0xA2, 0xFF, 0xA2, 0x94, 0, 0, },
|
|
||||||
{ 0x08, 0x04, 0x7E, 0x04, 0x08, 0, 0, },
|
|
||||||
{ 0x10, 0x20, 0x7E, 0x20, 0x10, 0, 0, },
|
|
||||||
{ 0x08, 0x08, 0x2A, 0x1C, 0x08, 0, 0, },
|
|
||||||
{ 0x08, 0x1C, 0x2A, 0x08, 0x08, 0, 0, },
|
|
||||||
{ 0x1E, 0x10, 0x10, 0x10, 0x10, 0, 0, },
|
|
||||||
{ 0x0C, 0x1E, 0x0C, 0x1E, 0x0C, 0, 0, },
|
|
||||||
{ 0x30, 0x38, 0x3E, 0x38, 0x30, 0, 0, },
|
|
||||||
{ 0x06, 0x0E, 0x3E, 0x0E, 0x06, 0, 0, },
|
|
||||||
//
|
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, }, // ' ' 32
|
|
||||||
{ 0, 6, 95, 95, 6, 0, 0, }, // '!' 33
|
|
||||||
{ 0, 7, 7, 0, 7, 7, 0, }, // '"' 34
|
|
||||||
{ 20, 127, 127, 20, 127, 127, 20, }, // '#' 35
|
|
||||||
{ 36, 46, 107, 107, 58, 18, 0, }, // '$' 36
|
|
||||||
{ 70, 102, 48, 24, 12, 102, 98, }, // '%' 37
|
|
||||||
{ 48, 122, 79, 93, 55, 122, 72, }, // '&' 38
|
|
||||||
{ 4, 7, 3, 0, 0, 0, 0, }, // ''' 39
|
|
||||||
{ 0, 28, 62, 99, 65, 0, 0, }, // '(' 40
|
|
||||||
{ 0, 65, 99, 62, 28, 0, 0, }, // ')' 41
|
|
||||||
{ 8, 42, 62, 28, 28, 62, 42, }, // '*' 42
|
|
||||||
{ 8, 8, 62, 62, 8, 8, 0, }, // '+' 43
|
|
||||||
{ 0, 128, 224, 96, 0, 0, 0, }, // ',' 44
|
|
||||||
{ 8, 8, 8, 8, 8, 8, 0, }, // '-' 45
|
|
||||||
{ 0, 0, 96, 96, 0, 0, 0, }, // '.' 46
|
|
||||||
{ 96, 48, 24, 12, 6, 3, 1, }, // '/' 47
|
|
||||||
{ 62, 127, 113, 89, 77, 127, 62, }, // '0' 48
|
|
||||||
{ 64, 66, 127, 127, 64, 64, 0, }, // '1' 49
|
|
||||||
{ 98, 115, 89, 73, 111, 102, 0, }, // '2' 50
|
|
||||||
{ 34, 99, 73, 73, 127, 54, 0, }, // '3' 51
|
|
||||||
{ 24, 28, 22, 83, 127, 127, 80, }, // '4' 52
|
|
||||||
{ 39, 103, 69, 69, 125, 57, 0, }, // '5' 53
|
|
||||||
{ 60, 126, 75, 73, 121, 48, 0, }, // '6' 54
|
|
||||||
{ 3, 3, 113, 121, 15, 7, 0, }, // '7' 55
|
|
||||||
{ 54, 127, 73, 73, 127, 54, 0, }, // '8' 56
|
|
||||||
{ 6, 79, 73, 105, 63, 30, 0, }, // '9' 57
|
|
||||||
{ 0, 0, 102, 102, 0, 0, 0, }, // ':' 58
|
|
||||||
{ 0, 128, 230, 102, 0, 0, 0, }, // ';' 59
|
|
||||||
{ 8, 28, 54, 99, 65, 0, 0, }, // '<' 60
|
|
||||||
{ 36, 36, 36, 36, 36, 36, 0, }, // '=' 61
|
|
||||||
{ 0, 65, 99, 54, 28, 8, 0, }, // '>' 62
|
|
||||||
{ 2, 3, 81, 89, 15, 6, 0, }, // '?' 63
|
|
||||||
{ 62, 127, 65, 93, 93, 31, 30, }, // '@' 64
|
|
||||||
{ 124, 126, 19, 19, 126, 124, 0, }, // 'A' 65
|
|
||||||
{ 65, 127, 127, 73, 73, 127, 54, }, // 'B' 66
|
|
||||||
{ 28, 62, 99, 65, 65, 99, 34, }, // 'C' 67
|
|
||||||
{ 65, 127, 127, 65, 99, 62, 28, }, // 'D' 68
|
|
||||||
{ 65, 127, 127, 73, 93, 65, 99, }, // 'E' 69
|
|
||||||
{ 65, 127, 127, 73, 29, 1, 3, }, // 'F' 70
|
|
||||||
{ 28, 62, 99, 65, 81, 115, 114, }, // 'G' 71
|
|
||||||
{ 127, 127, 8, 8, 127, 127, 0, }, // 'H' 72
|
|
||||||
{ 0, 65, 127, 127, 65, 0, 0, }, // 'I' 73
|
|
||||||
{ 48, 112, 64, 65, 127, 63, 1, }, // 'J' 74
|
|
||||||
{ 65, 127, 127, 8, 28, 119, 99, }, // 'K' 75
|
|
||||||
{ 65, 127, 127, 65, 64, 96, 112, }, // 'L' 76
|
|
||||||
{ 127, 127, 14, 28, 14, 127, 127, }, // 'M' 77
|
|
||||||
{ 127, 127, 6, 12, 24, 127, 127, }, // 'N' 78
|
|
||||||
{ 28, 62, 99, 65, 99, 62, 28, }, // 'O' 79
|
|
||||||
{ 65, 127, 127, 73, 9, 15, 6, }, // 'P' 80
|
|
||||||
{ 30, 63, 33, 113, 127, 94, 0, }, // 'Q' 81
|
|
||||||
{ 65, 127, 127, 9, 25, 127, 102, }, // 'R' 82
|
|
||||||
{ 38, 111, 77, 89, 115, 50, 0, }, // 'S' 83
|
|
||||||
{ 3, 65, 127, 127, 65, 3, 0, }, // 'T' 84
|
|
||||||
{ 127, 127, 64, 64, 127, 127, 0, }, // 'U' 85
|
|
||||||
{ 31, 63, 96, 96, 63, 31, 0, }, // 'V' 86
|
|
||||||
{ 127, 127, 48, 24, 48, 127, 127, }, // 'W' 87
|
|
||||||
{ 67, 103, 60, 24, 60, 103, 67, }, // 'X' 88
|
|
||||||
{ 7, 79, 120, 120, 79, 7, 0, }, // 'Y' 89
|
|
||||||
{ 71, 99, 113, 89, 77, 103, 115, }, // 'Z' 90
|
|
||||||
{ 0, 127, 127, 65, 65, 0, 0, }, // '[' 91
|
|
||||||
{ 1, 3, 6, 12, 24, 48, 96, }, // '\' 92
|
|
||||||
{ 0, 65, 65, 127, 127, 0, 0, }, // ']' 93
|
|
||||||
{ 8, 12, 6, 3, 6, 12, 8, }, // '^' 94
|
|
||||||
{ 128, 128, 128, 128, 128, 128, 128, }, // '_' 95
|
|
||||||
{ 0, 0, 3, 7, 4, 0, 0, }, // '`' 96
|
|
||||||
{ 32, 116, 84, 84, 60, 120, 64, }, // 'a' 97
|
|
||||||
{ 65, 127, 63, 72, 72, 120, 48, }, // 'b' 98
|
|
||||||
{ 56, 124, 68, 68, 108, 40, 0, }, // 'c' 99
|
|
||||||
{ 48, 120, 72, 73, 63, 127, 64, }, // 'd' 100
|
|
||||||
{ 56, 124, 84, 84, 92, 24, 0, }, // 'e' 101
|
|
||||||
{ 72, 126, 127, 73, 3, 2, 0, }, // 'f' 102
|
|
||||||
{ 56, 188, 164, 164, 252, 120, 0, }, // 'g' 103
|
|
||||||
{ 65, 127, 127, 8, 4, 124, 120, }, // 'h' 104
|
|
||||||
{ 0, 68, 125, 125, 64, 0, 0, }, // 'i' 105
|
|
||||||
{ 96, 224, 128, 128, 253, 125, 0, }, // 'j' 106
|
|
||||||
{ 65, 127, 127, 16, 56, 108, 68, }, // 'k' 107
|
|
||||||
{ 0, 65, 127, 127, 64, 0, 0, }, // 'l' 108
|
|
||||||
{ 120, 124, 28, 56, 28, 124, 120, }, // 'm' 109
|
|
||||||
{ 124, 124, 4, 4, 124, 120, 0, }, // 'n' 110
|
|
||||||
{ 56, 124, 68, 68, 124, 56, 0, }, // 'o' 111
|
|
||||||
{ 0, 252, 252, 164, 36, 60, 24, }, // 'p' 112
|
|
||||||
{ 24, 60, 36, 164, 248, 252, 132, }, // 'q' 113
|
|
||||||
{ 68, 124, 120, 76, 4, 28, 24, }, // 'r' 114
|
|
||||||
{ 72, 92, 84, 84, 116, 36, 0, }, // 's' 115
|
|
||||||
{ 0, 4, 62, 127, 68, 36, 0, }, // 't' 116
|
|
||||||
{ 60, 124, 64, 64, 60, 124, 64, }, // 'u' 117
|
|
||||||
{ 28, 60, 96, 96, 60, 28, 0, }, // 'v' 118
|
|
||||||
{ 60, 124, 112, 56, 112, 124, 60, }, // 'w' 119
|
|
||||||
{ 68, 108, 56, 16, 56, 108, 68, }, // 'x' 120
|
|
||||||
{ 60, 188, 160, 160, 252, 124, 0, }, // 'y' 121
|
|
||||||
{ 76, 100, 116, 92, 76, 100, 0, }, // 'z' 122
|
|
||||||
{ 8, 8, 62, 119, 65, 65, 0, }, // '{' 123
|
|
||||||
{ 0, 0, 0, 119, 119, 0, 0, }, // '|' 124
|
|
||||||
{ 65, 65, 119, 62, 8, 8, 0, }, // '}' 125
|
|
||||||
{ 2, 3, 1, 3, 2, 3, 1, }, // '~' 126
|
|
||||||
//
|
|
||||||
{ 0x3C, 0x26, 0x23, 0x26, 0x3C, 0, 0, },
|
|
||||||
{ 0x1E, 0xA1, 0xA1, 0x61, 0x12, 0, 0, },
|
|
||||||
{ 0x3A, 0x40, 0x40, 0x20, 0x7A, 0, 0, },
|
|
||||||
{ 0x38, 0x54, 0x54, 0x55, 0x59, 0, 0, },
|
|
||||||
{ 0x21, 0x55, 0x55, 0x79, 0x41, 0, 0, },
|
|
||||||
{ 0x22, 0x54, 0x54, 0x78, 0x42, 0, 0, }, // a-umlaut
|
|
||||||
{ 0x21, 0x55, 0x54, 0x78, 0x40, 0, 0, },
|
|
||||||
{ 0x20, 0x54, 0x55, 0x79, 0x40, 0, 0, },
|
|
||||||
{ 0x0C, 0x1E, 0x52, 0x72, 0x12, 0, 0, },
|
|
||||||
{ 0x39, 0x55, 0x55, 0x55, 0x59, 0, 0, },
|
|
||||||
{ 0x39, 0x54, 0x54, 0x54, 0x59, 0, 0, },
|
|
||||||
{ 0x39, 0x55, 0x54, 0x54, 0x58, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x45, 0x7C, 0x41, 0, 0, },
|
|
||||||
{ 0x00, 0x02, 0x45, 0x7D, 0x42, 0, 0, },
|
|
||||||
{ 0x00, 0x01, 0x45, 0x7C, 0x40, 0, 0, },
|
|
||||||
{ 0x7D, 0x12, 0x11, 0x12, 0x7D, 0, 0, }, // A-umlaut
|
|
||||||
{ 0xF0, 0x28, 0x25, 0x28, 0xF0, 0, 0, },
|
|
||||||
{ 0x7C, 0x54, 0x55, 0x45, 0x00, 0, 0, },
|
|
||||||
{ 0x20, 0x54, 0x54, 0x7C, 0x54, 0, 0, },
|
|
||||||
{ 0x7C, 0x0A, 0x09, 0x7F, 0x49, 0, 0, },
|
|
||||||
{ 0x32, 0x49, 0x49, 0x49, 0x32, 0, 0, },
|
|
||||||
{ 0x3A, 0x44, 0x44, 0x44, 0x3A, 0, 0, }, // o-umlaut
|
|
||||||
{ 0x32, 0x4A, 0x48, 0x48, 0x30, 0, 0, },
|
|
||||||
{ 0x3A, 0x41, 0x41, 0x21, 0x7A, 0, 0, },
|
|
||||||
{ 0x3A, 0x42, 0x40, 0x20, 0x78, 0, 0, },
|
|
||||||
{ 0x00, 0x9D, 0xA0, 0xA0, 0x7D, 0, 0, },
|
|
||||||
{ 0x3D, 0x42, 0x42, 0x42, 0x3D, 0, 0, }, // O-umlaut
|
|
||||||
{ 0x3D, 0x40, 0x40, 0x40, 0x3D, 0, 0, },
|
|
||||||
{ 0x3C, 0x24, 0xFF, 0x24, 0x24, 0, 0, },
|
|
||||||
{ 0x48, 0x7E, 0x49, 0x43, 0x66, 0, 0, },
|
|
||||||
{ 0x2B, 0x2F, 0xFC, 0x2F, 0x2B, 0, 0, },
|
|
||||||
{ 0xFF, 0x09, 0x29, 0xF6, 0x20, 0, 0, },
|
|
||||||
{ 0xC0, 0x88, 0x7E, 0x09, 0x03, 0, 0, },
|
|
||||||
{ 0x20, 0x54, 0x54, 0x79, 0x41, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x44, 0x7D, 0x41, 0, 0, },
|
|
||||||
{ 0x30, 0x48, 0x48, 0x4A, 0x32, 0, 0, },
|
|
||||||
{ 0x38, 0x40, 0x40, 0x22, 0x7A, 0, 0, },
|
|
||||||
{ 0x00, 0x7A, 0x0A, 0x0A, 0x72, 0, 0, },
|
|
||||||
{ 0x7D, 0x0D, 0x19, 0x31, 0x7D, 0, 0, },
|
|
||||||
{ 0x26, 0x29, 0x29, 0x2F, 0x28, 0, 0, },
|
|
||||||
{ 0x26, 0x29, 0x29, 0x29, 0x26, 0, 0, },
|
|
||||||
{ 0x30, 0x48, 0x4D, 0x40, 0x20, 0, 0, },
|
|
||||||
{ 0x38, 0x08, 0x08, 0x08, 0x08, 0, 0, },
|
|
||||||
{ 0x08, 0x08, 0x08, 0x08, 0x38, 0, 0, },
|
|
||||||
{ 0x2F, 0x10, 0xC8, 0xAC, 0xBA, 0, 0, },
|
|
||||||
{ 0x2F, 0x10, 0x28, 0x34, 0xFA, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x7B, 0x00, 0x00, 0, 0, },
|
|
||||||
{ 0x08, 0x14, 0x2A, 0x14, 0x22, 0, 0, },
|
|
||||||
{ 0x22, 0x14, 0x2A, 0x14, 0x08, 0, 0, },
|
|
||||||
{ 0xAA, 0x00, 0x55, 0x00, 0xAA, 0, 0, },
|
|
||||||
{ 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0xFF, 0x00, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0xFF, 0x00, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0xFF, 0x00, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0xFF, 0x00, 0xFF, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0xF0, 0x10, 0xF0, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0xFC, 0x00, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0xF7, 0x00, 0xFF, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0xF4, 0x04, 0xFC, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0x17, 0x10, 0x1F, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0x1F, 0x10, 0x1F, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0x1F, 0x00, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0xF0, 0x00, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0x1F, 0x10, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0x1F, 0x10, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0xF0, 0x10, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0xFF, 0x10, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0x10, 0x10, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0xFF, 0x10, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0xFF, 0x14, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0xFF, 0x00, 0xFF, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x1F, 0x10, 0x17, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0xFC, 0x04, 0xF4, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0x17, 0x10, 0x17, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0xF4, 0x04, 0xF4, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0xFF, 0x00, 0xF7, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0x14, 0x14, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0xF7, 0x00, 0xF7, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0x17, 0x14, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0x1F, 0x10, 0x1F, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0xF4, 0x14, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0xF0, 0x10, 0xF0, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x1F, 0x10, 0x1F, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0x1F, 0x14, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0xFC, 0x14, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0xF0, 0x10, 0xF0, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0xFF, 0x10, 0xFF, 0, 0, },
|
|
||||||
{ 0x14, 0x14, 0x14, 0xFF, 0x14, 0, 0, },
|
|
||||||
{ 0x10, 0x10, 0x10, 0x1F, 0x00, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0xF0, 0x10, 0, 0, },
|
|
||||||
{ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0, 0, },
|
|
||||||
{ 0xF0, 0xF0, 0xF0, 0xF0, 0xF0, 0, 0, },
|
|
||||||
{ 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0xFF, 0xFF, 0, 0, },
|
|
||||||
{ 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0, 0, },
|
|
||||||
{ 0x38, 0x44, 0x44, 0x38, 0x44, 0, 0, },
|
|
||||||
{ 0xFC, 0x4A, 0x4A, 0x4A, 0x34, 0, 0, }, // sharp-s or beta
|
|
||||||
{ 0x7E, 0x02, 0x02, 0x06, 0x06, 0, 0, },
|
|
||||||
{ 0x02, 0x7E, 0x02, 0x7E, 0x02, 0, 0, },
|
|
||||||
{ 0x63, 0x55, 0x49, 0x41, 0x63, 0, 0, },
|
|
||||||
{ 0x38, 0x44, 0x44, 0x3C, 0x04, 0, 0, },
|
|
||||||
{ 0x40, 0x7E, 0x20, 0x1E, 0x20, 0, 0, },
|
|
||||||
{ 0x06, 0x02, 0x7E, 0x02, 0x02, 0, 0, },
|
|
||||||
{ 0x99, 0xA5, 0xE7, 0xA5, 0x99, 0, 0, },
|
|
||||||
{ 0x1C, 0x2A, 0x49, 0x2A, 0x1C, 0, 0, },
|
|
||||||
{ 0x4C, 0x72, 0x01, 0x72, 0x4C, 0, 0, },
|
|
||||||
{ 0x30, 0x4A, 0x4D, 0x4D, 0x30, 0, 0, },
|
|
||||||
{ 0x30, 0x48, 0x78, 0x48, 0x30, 0, 0, },
|
|
||||||
{ 0xBC, 0x62, 0x5A, 0x46, 0x3D, 0, 0, },
|
|
||||||
{ 0x3E, 0x49, 0x49, 0x49, 0x00, 0, 0, },
|
|
||||||
{ 0x7E, 0x01, 0x01, 0x01, 0x7E, 0, 0, },
|
|
||||||
{ 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0, 0, },
|
|
||||||
{ 0x44, 0x44, 0x5F, 0x44, 0x44, 0, 0, },
|
|
||||||
{ 0x40, 0x51, 0x4A, 0x44, 0x40, 0, 0, },
|
|
||||||
{ 0x40, 0x44, 0x4A, 0x51, 0x40, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0xFF, 0x01, 0x03, 0, 0, },
|
|
||||||
{ 0xE0, 0x80, 0xFF, 0x00, 0x00, 0, 0, },
|
|
||||||
{ 0x08, 0x08, 0x6B, 0x6B, 0x08, 0, 0, },
|
|
||||||
{ 0x36, 0x12, 0x36, 0x24, 0x36, 0, 0, },
|
|
||||||
{ 0x06, 0x0F, 0x09, 0x0F, 0x06, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x18, 0x18, 0x00, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x10, 0x10, 0x00, 0, 0, },
|
|
||||||
{ 0x30, 0x40, 0xFF, 0x01, 0x01, 0, 0, },
|
|
||||||
{ 0x00, 0x1F, 0x01, 0x01, 0x1E, 0, 0, },
|
|
||||||
{ 0x00, 0x19, 0x1D, 0x17, 0x12, 0, 0, },
|
|
||||||
{ 0x00, 0x3C, 0x3C, 0x3C, 0x3C, 0, 0, },
|
|
||||||
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0, 0, }
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Font Size: 7x8 (+spacing=8x8)
|
|
||||||
* Characters: 95 (ASCII 0-255).
|
|
||||||
* Bit format: vertical
|
|
||||||
* Memory: 1792 bytes (256)
|
|
||||||
*/
|
|
||||||
const fontStruct font7x8extended = {
|
|
||||||
(byte *) fontData7x8extended,
|
|
||||||
FONT_CHARS,
|
|
||||||
FONT_CHAR_FIRST,
|
|
||||||
FONT_CHAR_LAST,
|
|
||||||
FONT_WIDTH,
|
|
||||||
FONT_HEIGHT,
|
|
||||||
FONT_SPACING,
|
|
||||||
true
|
|
||||||
};
|
|
||||||
@@ -1,158 +0,0 @@
|
|||||||
/*
|
|
||||||
* font9x16.c
|
|
||||||
*
|
|
||||||
* Created: 4/8/2015 11:31:21 AM
|
|
||||||
* Author: Baron Williams
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <core_pins.h>
|
|
||||||
#include <usb_serial.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 "fonts.h"
|
|
||||||
|
|
||||||
#define FONT_CHAR_FIRST 32
|
|
||||||
#define FONT_CHAR_LAST 126
|
|
||||||
#define FONT_CHARS 95
|
|
||||||
#define FONT_WIDTH 9
|
|
||||||
#define FONT_HEIGHT 16
|
|
||||||
#define FONT_SPACING 1
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 9x16 font. 95 characters from 32-126.
|
|
||||||
* Bit format: vertical
|
|
||||||
* Memory: 1710 bytes (95x9x2)
|
|
||||||
*/
|
|
||||||
const uint16_t fontData9x16[FONT_CHARS][FONT_WIDTH] ={
|
|
||||||
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, }, // ' ' 32
|
|
||||||
{ 0, 0, 62, 13311, 13311, 62, 0, 0, 0, }, // '!' 33
|
|
||||||
{ 0, 7, 7, 0, 0, 7, 7, 0, 0, }, // '"' 34
|
|
||||||
{ 288, 8190, 8190, 288, 288, 8190, 8190, 288, 0, }, // '#' 35
|
|
||||||
{ 1592, 3644, 2148, 16383, 16383, 2436, 3868, 1816, 0, }, // '$' 36
|
|
||||||
{ 12318, 7219, 1822, 448, 112, 7708, 13063, 7681, 0, }, // '%' 37
|
|
||||||
{ 7966, 12723, 8417, 8417, 12723, 7966, 6912, 12672, 0, }, // '&' 38
|
|
||||||
{ 0, 0, 0, 11, 7, 0, 0, 0, 0, }, // ''' 39
|
|
||||||
{ 0, 0, 2032, 16382, 30735, 16385, 0, 0, 0, }, // '(' 40
|
|
||||||
{ 0, 0, 16385, 30735, 16382, 2032, 0, 0, 0, }, // ')' 41
|
|
||||||
{ 128, 672, 992, 448, 448, 992, 672, 128, 0, }, // '*' 42
|
|
||||||
{ 128, 128, 128, 992, 992, 128, 128, 128, 0, }, // '+' 43
|
|
||||||
{ 0, 0, 0, 45056, 28672, 0, 0, 0, 0, }, // ',' 44
|
|
||||||
{ 128, 128, 128, 128, 128, 128, 128, 128, 0, }, // '-' 45
|
|
||||||
{ 0, 0, 0, 12288, 12288, 0, 0, 0, 0, }, // '.' 46
|
|
||||||
{ 12288, 15360, 3840, 960, 240, 60, 15, 3, 0, }, // '/' 47
|
|
||||||
{ 4092, 8190, 13827, 8577, 8289, 12315, 8190, 4092, 0, }, // '0' 48
|
|
||||||
{ 8196, 8196, 8198, 16383, 16383, 8192, 8192, 8192, 0, }, // '1' 49
|
|
||||||
{ 14348, 15374, 9731, 8961, 8577, 8387, 8318, 8252, 0, }, // '2' 50
|
|
||||||
{ 3084, 7182, 12355, 8257, 8257, 12355, 8190, 4028, 0, }, // '3' 51
|
|
||||||
{ 3840, 4064, 2300, 2079, 16259, 16256, 2048, 2048, 0, }, // '4' 52
|
|
||||||
{ 3135, 7231, 12321, 8225, 8225, 12385, 8129, 3969, 0, }, // '5' 53
|
|
||||||
{ 4064, 8184, 12380, 8262, 8259, 12481, 8065, 3841, 0, }, // '6' 54
|
|
||||||
{ 1, 1, 1, 15361, 16257, 1009, 127, 15, 0, }, // '7' 55
|
|
||||||
{ 3868, 8126, 12515, 8257, 8257, 12515, 8126, 3868, 0, }, // '8' 56
|
|
||||||
{ 8252, 8318, 8387, 12417, 6273, 3715, 2046, 508, 0, }, // '9' 57
|
|
||||||
{ 0, 0, 0, 12384, 12384, 0, 0, 0, 0, }, // ':' 58
|
|
||||||
{ 0, 0, 0, 45152, 28768, 0, 0, 0, 0, }, // ';' 59
|
|
||||||
{ 128, 448, 864, 1584, 3096, 6156, 4100, 0, 0, }, // '<' 60
|
|
||||||
{ 288, 288, 288, 288, 288, 288, 288, 288, 0, }, // '=' 61
|
|
||||||
{ 4100, 6156, 3096, 1584, 864, 448, 128, 0, 0, }, // '>' 62
|
|
||||||
{ 6, 7, 3, 13057, 13249, 243, 63, 30, 0, }, // '?' 63
|
|
||||||
{ 4092, 8190, 12291, 8673, 9201, 8721, 8467, 13310, 5116, }, // '@' 64
|
|
||||||
{ 16380, 16382, 259, 257, 257, 259, 16382, 16380, 0, }, // 'A' 65
|
|
||||||
{ 16383, 16383, 8257, 8257, 8257, 12515, 8126, 3868, 0, }, // 'B' 66
|
|
||||||
{ 4092, 8190, 12291, 8193, 8193, 12291, 7182, 3084, 0, }, // 'C' 67
|
|
||||||
{ 16383, 16383, 8193, 8193, 8193, 14343, 8190, 2040, 0, }, // 'D' 68
|
|
||||||
{ 16383, 16383, 8257, 8257, 8257, 8257, 8257, 8193, 0, }, // 'E' 69
|
|
||||||
{ 16383, 16383, 129, 129, 129, 129, 129, 1, 0, }, // 'F' 70
|
|
||||||
{ 4092, 8190, 12291, 8193, 8321, 12419, 8078, 3980, 0, }, // 'G' 71
|
|
||||||
{ 16383, 16383, 64, 64, 64, 64, 16383, 16383, 0, }, // 'H' 72
|
|
||||||
{ 8193, 8193, 8193, 16383, 16383, 8193, 8193, 8193, 0, }, // 'I' 73
|
|
||||||
{ 3072, 7168, 12288, 8192, 8192, 12288, 8191, 4095, 0, }, // 'J' 74
|
|
||||||
{ 16383, 16383, 192, 480, 1848, 3612, 15375, 12291, 0, }, // 'K' 75
|
|
||||||
{ 16383, 16383, 8192, 8192, 8192, 8192, 8192, 8192, 0, }, // 'L' 76
|
|
||||||
{ 16383, 16383, 120, 960, 960, 120, 16383, 16383, 0, }, // 'M' 77
|
|
||||||
{ 16383, 16383, 28, 112, 448, 1792, 16383, 16383, 0, }, // 'N' 78
|
|
||||||
{ 4092, 8190, 12291, 8193, 8193, 12291, 8190, 4092, 0, }, // 'O' 79
|
|
||||||
{ 16383, 16383, 129, 129, 129, 195, 126, 60, 0, }, // 'P' 80
|
|
||||||
{ 4092, 8190, 12291, 8193, 24577, 61443, 40958, 4092, 0, }, // 'Q' 81
|
|
||||||
{ 16383, 16383, 129, 129, 385, 8131, 15998, 8252, 0, }, // 'R' 82
|
|
||||||
{ 3132, 7294, 12387, 8417, 8641, 12675, 8078, 3852, 0, }, // 'S' 83
|
|
||||||
{ 1, 1, 1, 16383, 16383, 1, 1, 1, 0, }, // 'T' 84
|
|
||||||
{ 4095, 8191, 12288, 8192, 8192, 12288, 8191, 4095, 0, }, // 'U' 85
|
|
||||||
{ 63, 511, 4032, 15360, 15360, 4032, 511, 63, 0, }, // 'V' 86
|
|
||||||
{ 511, 16383, 15872, 448, 448, 15872, 16383, 511, 0, }, // 'W' 87
|
|
||||||
{ 15375, 16191, 1008, 192, 192, 1008, 16191, 15375, 0, }, // 'X' 88
|
|
||||||
{ 63, 255, 448, 16256, 16256, 448, 255, 63, 0, }, // 'Y' 89
|
|
||||||
{ 14337, 15873, 10113, 8641, 8289, 8249, 8223, 8199, 0, }, // 'Z' 90
|
|
||||||
{ 0, 0, 16383, 16383, 8193, 8193, 0, 0, 0, }, // '[' 91
|
|
||||||
{ 3, 15, 60, 240, 960, 3840, 15360, 12288, 0, }, // '\' 92
|
|
||||||
{ 0, 0, 8193, 8193, 16383, 16383, 0, 0, 0, }, // ']' 93
|
|
||||||
{ 4, 4, 6, 3, 3, 6, 6, 4, 0, }, // '^' 94
|
|
||||||
{ 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, 32768, }, // '_' 95
|
|
||||||
{ 0, 0, 0, 7, 11, 0, 0, 0, 0, }, // '`' 96
|
|
||||||
{ 7680, 16192, 8480, 8480, 8480, 4384, 16352, 16320, 0, }, // 'a' 97
|
|
||||||
{ 16383, 16383, 4160, 8224, 8224, 12384, 8128, 3968, 0, }, // 'b' 98
|
|
||||||
{ 3968, 8128, 12384, 8224, 8224, 8224, 12384, 4160, 0, }, // 'c' 99
|
|
||||||
{ 3968, 8128, 12384, 8224, 8224, 4160, 16383, 16383, 0, }, // 'd' 100
|
|
||||||
{ 3968, 8128, 12896, 8736, 8736, 8800, 13248, 4992, 0, }, // 'e' 101
|
|
||||||
{ 32, 32, 16382, 16383, 33, 33, 35, 2, 0, }, // 'f' 102
|
|
||||||
{ 18304, 20416, 55392, 36896, 36896, 51264, 32736, 16352, 0, }, // 'g' 103
|
|
||||||
{ 16383, 16383, 64, 32, 32, 96, 16320, 16256, 0, }, // 'h' 104
|
|
||||||
{ 0, 8224, 8224, 16355, 16355, 8192, 8192, 0, 0, }, // 'i' 105
|
|
||||||
{ 0, 16384, 49184, 32800, 65507, 32739, 0, 0, 0, }, // 'j' 106
|
|
||||||
{ 16383, 16383, 1536, 1792, 3456, 6336, 12384, 8224, 0, }, // 'k' 107
|
|
||||||
{ 0, 8193, 8193, 16383, 16383, 8192, 8192, 0, 0, }, // 'l' 108
|
|
||||||
{ 16352, 16352, 96, 8128, 8128, 96, 16352, 16320, 0, }, // 'm' 109
|
|
||||||
{ 16352, 16352, 64, 32, 32, 96, 16320, 16256, 0, }, // 'n' 110
|
|
||||||
{ 3968, 8128, 12384, 8224, 8224, 12384, 8128, 3968, 0, }, // 'o' 111
|
|
||||||
{ 65504, 65504, 4160, 8224, 8224, 12384, 8128, 3968, 0, }, // 'p' 112
|
|
||||||
{ 3968, 8128, 8224, 8224, 8224, 4160, 65504, 65504, 0, }, // 'q' 113
|
|
||||||
{ 16352, 16352, 192, 64, 96, 96, 96, 64, 0, }, // 'r' 114
|
|
||||||
{ 4288, 12768, 8480, 8992, 9760, 9248, 15456, 6208, 0, }, // 's' 115
|
|
||||||
{ 0, 32, 32, 8190, 16382, 8224, 8224, 0, 0, }, // 't' 116
|
|
||||||
{ 8160, 16352, 8192, 8192, 8192, 4096, 16352, 16352, 0, }, // 'u' 117
|
|
||||||
{ 992, 2016, 7168, 12288, 12288, 7168, 2016, 992, 0, }, // 'v' 118
|
|
||||||
{ 2016, 16352, 14336, 1984, 1984, 14336, 16352, 2016, 0, }, // 'w' 119
|
|
||||||
{ 12384, 15840, 3456, 1792, 1792, 3456, 15840, 12384, 0, }, // 'x' 120
|
|
||||||
{ 33760, 36832, 56320, 28672, 12288, 7168, 4064, 992, 0, }, // 'y' 121
|
|
||||||
{ 12320, 14368, 11296, 9760, 8992, 8608, 8416, 8288, 0, }, // 'z' 122
|
|
||||||
{ 0, 0, 128, 16382, 32639, 16385, 16385, 0, 0, }, // '{' 123
|
|
||||||
{ 0, 0, 0, 65407, 65407, 0, 0, 0, 0, }, // '|' 124
|
|
||||||
{ 0, 16385, 16385, 32639, 16382, 128, 0, 0, 0, }, // '}' 125
|
|
||||||
{ 2, 2, 1, 1, 2, 2, 1, 1, 0 } // '~' 126
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 9x16 font.
|
|
||||||
* Characters: 95 (ASCII 32-126).
|
|
||||||
* Bit format: vertical
|
|
||||||
* Memory: 1710 bytes (95x9x2)
|
|
||||||
*/
|
|
||||||
const fontStruct font9x16 = {
|
|
||||||
(byte *) fontData9x16,
|
|
||||||
FONT_CHARS,
|
|
||||||
FONT_CHAR_FIRST,
|
|
||||||
FONT_CHAR_LAST,
|
|
||||||
FONT_WIDTH,
|
|
||||||
FONT_HEIGHT,
|
|
||||||
FONT_SPACING,
|
|
||||||
true
|
|
||||||
};
|
|
||||||
@@ -1,106 +0,0 @@
|
|||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined __K64F__
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#define uint32_t __uint32_t
|
|
||||||
#define uint16_t __uint16_t
|
|
||||||
#define uint8_t __uint8_t
|
|
||||||
#define int32_t __int32_t
|
|
||||||
#define int16_t __int16_t
|
|
||||||
#define int8_t __int8_t
|
|
||||||
#include "k64f_soc.h"
|
|
||||||
#elif defined __ZPU__
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
#elif defined __M68K__
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "interrupts.h"
|
|
||||||
|
|
||||||
extern void (*_inthandler_fptr)();
|
|
||||||
|
|
||||||
#if defined __K64F__
|
|
||||||
void SetIntHandler(void(*handler)())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#elif defined __ZPU__
|
|
||||||
void SetIntHandler(void(*handler)())
|
|
||||||
{
|
|
||||||
_inthandler_fptr=handler;
|
|
||||||
}
|
|
||||||
#elif defined __M68K__
|
|
||||||
void SetIntHandler(void(*handler)())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__, __K64F__ or M68K"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(FUNCTIONALITY) || FUNCTIONALITY <= 2
|
|
||||||
// Method to enable individual interrupts.
|
|
||||||
//
|
|
||||||
static uint32_t intrSetting = 0;
|
|
||||||
void EnableInterrupt(uint32_t intrMask)
|
|
||||||
{
|
|
||||||
#if defined __ZPU__
|
|
||||||
uint32_t currentIntr = INTERRUPT_CTRL(INTR0);
|
|
||||||
INTERRUPT_CTRL(INTR0) = 0;
|
|
||||||
currentIntr &= ~intrMask;
|
|
||||||
currentIntr |= intrMask;
|
|
||||||
intrSetting = currentIntr;
|
|
||||||
INTERRUPT_CTRL(INTR0) = intrSetting;
|
|
||||||
#elif defined __K64F__
|
|
||||||
intrSetting = 0;
|
|
||||||
#elif defined __M68K__
|
|
||||||
intrSetting = 0;
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__, __K64F__ or M68K"
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to disable individual interrupts.
|
|
||||||
//
|
|
||||||
void DisableInterrupt(uint32_t intrMask)
|
|
||||||
{
|
|
||||||
#if defined __ZPU__
|
|
||||||
intrSetting = INTERRUPT_CTRL(INTR0);
|
|
||||||
INTERRUPT_CTRL(INTR0) = 0;
|
|
||||||
intrSetting &= ~intrMask;
|
|
||||||
INTERRUPT_CTRL(INTR0) = intrSetting;
|
|
||||||
#elif defined __K64F__
|
|
||||||
#elif defined __M68K__
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__, __K64F__ or M68K"
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to disable interrupts.
|
|
||||||
//
|
|
||||||
inline void DisableInterrupts(void)
|
|
||||||
{
|
|
||||||
#if defined __ZPU__
|
|
||||||
INTERRUPT_CTRL(INTR0) = 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to enable interrupts.
|
|
||||||
//
|
|
||||||
inline void EnableInterrupts(void)
|
|
||||||
{
|
|
||||||
#if defined __ZPU__
|
|
||||||
INTERRUPT_CTRL(INTR0) = intrSetting;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // Functionality.
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: k64f_soc.c
|
|
||||||
// Created: January 2019 - April 2020
|
|
||||||
// Author(s): Philip Smart
|
|
||||||
// Description: K64F System On a Chip utilities.
|
|
||||||
// A set of utilities specific to interaction with the K64F SoC hardware.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2019 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: January 2019 - Initial script written.
|
|
||||||
// April 2020 - Duplicated the zpu_soc for the Freescale K64F used in the Teensy3.5
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#define uint32_t __uint32_t
|
|
||||||
#define uint16_t __uint16_t
|
|
||||||
#define uint8_t __uint8_t
|
|
||||||
#define int32_t __int32_t
|
|
||||||
#define int16_t __int16_t
|
|
||||||
#define int8_t __int8_t
|
|
||||||
#include "k64f_soc.h"
|
|
||||||
|
|
||||||
// Global scope variables.
|
|
||||||
#ifdef USE_BOOT_ROM
|
|
||||||
SOC_CONFIG cfgSoC;
|
|
||||||
#else
|
|
||||||
SOC_CONFIG cfgSoC = { .addrRAM = RAM_ADDR,
|
|
||||||
.sizeRAM = RAM_SIZE,
|
|
||||||
.addrFRAM = FRAM_ADDR,
|
|
||||||
.sizeFRAM = FRAM_SIZE,
|
|
||||||
.addrFRAMNV = FRAMNV_ADDR,
|
|
||||||
.sizeFRAMNV = FRAMNV_SIZE,
|
|
||||||
.addrFRAMNVC = FRAMNVC_ADDR,
|
|
||||||
.sizeFRAMNVC = FRAMNVC_SIZE,
|
|
||||||
.resetVector = 0,
|
|
||||||
.cpuMemBaseAddr = 0,
|
|
||||||
.stackStartAddr = 0,
|
|
||||||
.sysFreq = CLK_FREQ,
|
|
||||||
.memFreq = CLK_FREQ,
|
|
||||||
.implRAM = RAM_IMPL,
|
|
||||||
.implFRAM = FRAM_IMPL,
|
|
||||||
.implFRAMNV = FRAMNV_IMPL,
|
|
||||||
.implFRAMNVC = FRAMNVC_IMPL,
|
|
||||||
.implPS2 = 0,
|
|
||||||
.implSPI = 0,
|
|
||||||
.implSD = 0,
|
|
||||||
.sdCardNo = 0,
|
|
||||||
.implIntrCtl = 0,
|
|
||||||
.intrChannels = 0,
|
|
||||||
.implTimer1 = 0,
|
|
||||||
.timer1No = 0 };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Method to populate the Configuration structure, using in-built values as the K64F has a static design
|
|
||||||
// and components are well known.
|
|
||||||
void setupSoCConfig(void)
|
|
||||||
{
|
|
||||||
uint32_t pnt = 0x0;
|
|
||||||
// Teensy 3.5 uses the Freescale K64FX512 which has fixed hardware definitions.
|
|
||||||
cfgSoC.addrRAM = RAM_ADDR;
|
|
||||||
cfgSoC.sizeRAM = RAM_SIZE;
|
|
||||||
cfgSoC.addrFRAM = FRAM_ADDR;
|
|
||||||
cfgSoC.sizeFRAM = FRAM_SIZE;
|
|
||||||
cfgSoC.addrFRAMNV = FRAMNV_ADDR;
|
|
||||||
cfgSoC.sizeFRAMNV = FRAMNV_SIZE;
|
|
||||||
cfgSoC.addrFRAMNVC = FRAMNVC_ADDR;
|
|
||||||
cfgSoC.sizeFRAMNVC = FRAMNVC_SIZE;
|
|
||||||
cfgSoC.resetVector = *(uint32_t *)(pnt+4);
|
|
||||||
cfgSoC.cpuMemBaseAddr = 0;
|
|
||||||
// Reading location 0x00000000 just after reset seems to lock up the CPU, hence this convoluted method!!
|
|
||||||
cfgSoC.stackStartAddr = *(uint8_t *)(pnt+3) << 24 | *(uint8_t *)(pnt+2) << 16 | *(uint8_t *)(pnt+1) << 8 | 0xF8;
|
|
||||||
cfgSoC.sysFreq = CLK_FREQ;
|
|
||||||
cfgSoC.memFreq = CLK_FREQ;
|
|
||||||
cfgSoC.implFRAM = FRAM_IMPL;
|
|
||||||
cfgSoC.implFRAMNV = FRAMNV_IMPL;
|
|
||||||
cfgSoC.implFRAMNVC = FRAMNVC_IMPL;
|
|
||||||
cfgSoC.implRAM = RAM_IMPL;
|
|
||||||
cfgSoC.implPS2 = PS2_IMPL;
|
|
||||||
cfgSoC.implSPI = SPI_IMPL;
|
|
||||||
cfgSoC.implSD = SD_IMPL;
|
|
||||||
cfgSoC.sdCardNo = SD_DEVICE_CNT;
|
|
||||||
cfgSoC.implIntrCtl = 0;
|
|
||||||
cfgSoC.intrChannels = 0;
|
|
||||||
cfgSoC.implTimer1 = 0;
|
|
||||||
cfgSoC.timer1No = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to show the current configuration via the primary uart channel.
|
|
||||||
//
|
|
||||||
#if !defined(FUNCTIONALITY) || FUNCTIONALITY <= 1
|
|
||||||
void showSoCConfig(void)
|
|
||||||
{
|
|
||||||
puts("K64F SoC Configuration:");
|
|
||||||
puts("On-board Devices:");
|
|
||||||
if(cfgSoC.implFRAM) { printf(" FRAM (%08lX:%08lX).\n", cfgSoC.addrFRAM, cfgSoC.addrFRAM + cfgSoC.sizeFRAM); }
|
|
||||||
if(cfgSoC.implFRAM) { printf(" FRAMNV (%08lX:%08lX).\n", cfgSoC.addrFRAMNV, cfgSoC.addrFRAMNV + cfgSoC.sizeFRAMNV); }
|
|
||||||
if(cfgSoC.implFRAM) { printf(" FRAMNVC (%08lX:%08lX).\n", cfgSoC.addrFRAMNVC, cfgSoC.addrFRAMNVC + cfgSoC.sizeFRAMNVC); }
|
|
||||||
if(cfgSoC.implRAM) { printf(" RAM (%08lX:%08lX).\n", cfgSoC.addrRAM, cfgSoC.addrRAM + cfgSoC.sizeRAM); }
|
|
||||||
if(cfgSoC.implSD) { printf(" SD CARD (Devices =%02d).\n", (uint8_t)cfgSoC.sdCardNo); }
|
|
||||||
if(cfgSoC.implTimer1) { printf(" TIMER1 (Timers =%02d).\n", (uint8_t)cfgSoC.timer1No); }
|
|
||||||
if(cfgSoC.implIntrCtl) { printf(" INTR CTRL (Channels=%02d).\n", (uint8_t)cfgSoC.intrChannels); }
|
|
||||||
if(cfgSoC.implPS2) { puts(" PS2"); }
|
|
||||||
if(cfgSoC.implSPI) { puts(" SPI"); }
|
|
||||||
puts("Addresses:");
|
|
||||||
printf(" CPU Reset Vector Address = %08lX\n", cfgSoC.resetVector);
|
|
||||||
printf(" CPU Memory Start Address = %08lX\n", cfgSoC.cpuMemBaseAddr);
|
|
||||||
printf(" Stack Start Address = %08lX\n", cfgSoC.stackStartAddr);
|
|
||||||
puts("Misc:");
|
|
||||||
printf(" System Clock Freq = %lu.%04luMHz\n", (cfgSoC.sysFreq / 1000000), cfgSoC.sysFreq - ((cfgSoC.sysFreq / 1000000) * 1000000));
|
|
||||||
#ifdef DRV_CFC
|
|
||||||
printf(" CFC = %08lX\n", DRV_CFC);
|
|
||||||
#endif
|
|
||||||
#ifdef DRV_MMC
|
|
||||||
printf(" MMC = %08lX\n", DRV_MMC);
|
|
||||||
#endif
|
|
||||||
//puts("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to print out the ZPU Id in text form.
|
|
||||||
void printCPU(void)
|
|
||||||
{
|
|
||||||
printf("K64FX512");
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,160 +0,0 @@
|
|||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "keyboard.h"
|
|
||||||
#include "ps2.h"
|
|
||||||
|
|
||||||
// FIXME - create another ring buffer for ASCII keystrokes
|
|
||||||
|
|
||||||
unsigned char kblookup[2][128] =
|
|
||||||
{
|
|
||||||
{
|
|
||||||
0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,'\t',0,0,
|
|
||||||
0,0,0,0,0,'q','1',0,
|
|
||||||
0,0,'z','s','a','w','2',0,
|
|
||||||
0,'c','x','d','e','4','3',0,
|
|
||||||
0,' ','v','f','t','r','5',0,
|
|
||||||
0,'n','b','h','g','y','6',0,
|
|
||||||
0,0,'m','j','u','7','8',0,
|
|
||||||
0,',','k','i','o','0','9',0,
|
|
||||||
0,'.','/','l',';','p','-',0,
|
|
||||||
0,0,'\'',0,'[','=',0,0,
|
|
||||||
0,0,'\n',']',0,'#',0,0,
|
|
||||||
0,0,0,0,0,0,'\b',0,
|
|
||||||
0,'1',0,'4','7',0,0,0,
|
|
||||||
'0','.','2','5','6','8',27,0,
|
|
||||||
0,'+','3',0,'*','9',0,0
|
|
||||||
},
|
|
||||||
{
|
|
||||||
0,0,0,0,0,0,0,0,
|
|
||||||
0,0,0,0,0,8,0,0,
|
|
||||||
0,0,0,0,0,'Q','!',0,
|
|
||||||
0,0,'Z','S','A','W','"',0,
|
|
||||||
0,'C','X','D','E','$','£',0,
|
|
||||||
0,' ','V','F','T','R','%',0,
|
|
||||||
0,'N','B','H','G','Y','^',0,
|
|
||||||
0,0,'M','J','U','&','*',0,
|
|
||||||
0,'<','K','I','O',')','(',0,
|
|
||||||
0,'>','?','L',':','P','_',0,
|
|
||||||
0,0,'?',0,'{','+',0,0,
|
|
||||||
0,0,'\n','}',0,'~',0,0,
|
|
||||||
0,0,0,0,0,0,9,0,
|
|
||||||
0,'1',0,'4','7',0,0,0,
|
|
||||||
'0','.','2','5','6','8',27,0,
|
|
||||||
0,'+','3',0,'*','9',0,0
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
// Only need 2 bits per key in the keytable,
|
|
||||||
// so we'll use 32-bit ints to store the key statuses
|
|
||||||
// since that's more convienent for the ZPU.
|
|
||||||
// Keycode (0-255)>>4 -> Index
|
|
||||||
// Shift each 2-bit tuple by (keycode & 15)*2.
|
|
||||||
unsigned int keytable[16]={0};
|
|
||||||
|
|
||||||
#define QUAL_SHIFT 0
|
|
||||||
|
|
||||||
static int qualifiers=0;
|
|
||||||
static int leds=0;
|
|
||||||
static int fkeys=0;
|
|
||||||
|
|
||||||
int HandlePS2RawCodes()
|
|
||||||
{
|
|
||||||
int result=0;
|
|
||||||
static int keyup=0;
|
|
||||||
static int extkey=0;
|
|
||||||
int updateleds=0;
|
|
||||||
int key;
|
|
||||||
|
|
||||||
while((key=PS2KeyboardRead())>-1)
|
|
||||||
{
|
|
||||||
if(key==KEY_KEYUP)
|
|
||||||
keyup=1;
|
|
||||||
else if(key==KEY_EXT)
|
|
||||||
extkey=1;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// if(key<128)
|
|
||||||
// {
|
|
||||||
int keyidx=extkey ? 128+key : key;
|
|
||||||
if(keyup)
|
|
||||||
keytable[keyidx>>4]&=~(1<<((keyidx&15)*2)); // Mask off the "currently pressed" bit.
|
|
||||||
else
|
|
||||||
keytable[keyidx>>4]|=3<<((keyidx&15)*2); // Currently pressed and pressed since last test.
|
|
||||||
// }
|
|
||||||
if(keyup==0)
|
|
||||||
{
|
|
||||||
int a=0;
|
|
||||||
// printf("key %d, qual %d\n",key,qualifiers);
|
|
||||||
if(!extkey)
|
|
||||||
{
|
|
||||||
a=kblookup[ (leds & 4) ? qualifiers | 1 : qualifiers][key];
|
|
||||||
// printf("code %d\n",a);
|
|
||||||
if(a)
|
|
||||||
return(a);
|
|
||||||
}
|
|
||||||
switch(key)
|
|
||||||
{
|
|
||||||
case 0x58: // Caps lock
|
|
||||||
leds^=0x04;
|
|
||||||
updateleds=1;
|
|
||||||
break;
|
|
||||||
case 0x7e: // Scroll lock
|
|
||||||
leds^=0x01;
|
|
||||||
updateleds=1;
|
|
||||||
break;
|
|
||||||
case 0x77: // Num lock
|
|
||||||
leds^=0x02;
|
|
||||||
updateleds=1;
|
|
||||||
break;
|
|
||||||
case 0x12:
|
|
||||||
case 0x59:
|
|
||||||
qualifiers|=(1<<QUAL_SHIFT);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch(key)
|
|
||||||
{
|
|
||||||
case 0x12:
|
|
||||||
case 0x59:
|
|
||||||
qualifiers&=~(1<<QUAL_SHIFT);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
extkey=0;
|
|
||||||
keyup=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(updateleds)
|
|
||||||
{
|
|
||||||
PS2KeyboardWrite(0xed);
|
|
||||||
PS2KeyboardWrite(leds);
|
|
||||||
}
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ClearKeyboard()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for(i=0;i<16;++i)
|
|
||||||
keytable[i]=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int TestKey(int rawcode)
|
|
||||||
{
|
|
||||||
int result;
|
|
||||||
DisableInterrupts(); // Make sure a new character doesn't arrive halfway through the read
|
|
||||||
result=3&(keytable[rawcode>>4]>>((rawcode&15)*2));
|
|
||||||
keytable[rawcode>>4]&=~(2<<((rawcode&15)*2)); // Mask off the "pressed since last test" bit.
|
|
||||||
EnableInterrupts();
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,269 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: m68k_soc.c
|
|
||||||
// Created: January 2019
|
|
||||||
// Author(s): Philip Smart
|
|
||||||
// Description: M68000 System On a Chip utilities.
|
|
||||||
// A set of utilities specific to interaction with the ZPU SoC hardware.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2019-2021 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: January 2019 - Initial script written.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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
|
|
||||||
|
|
||||||
//#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
//#include <stdlib.h>
|
|
||||||
#include "uart.h"
|
|
||||||
#include "m68k_soc.h"
|
|
||||||
|
|
||||||
// Global scope variables.
|
|
||||||
#ifdef USE_BOOT_ROM
|
|
||||||
SOC_CONFIG cfgSoC;
|
|
||||||
#else
|
|
||||||
SOC_CONFIG cfgSoC = { .addrInsnBRAM = INSN_BRAM_ADDR,
|
|
||||||
.sizeInsnBRAM = INSN_BRAM_SIZE,
|
|
||||||
.addrBRAM = BRAM_ADDR,
|
|
||||||
.sizeBRAM = BRAM_SIZE,
|
|
||||||
.addrRAM = RAM_ADDR,
|
|
||||||
.sizeRAM = RAM_SIZE,
|
|
||||||
.addrSDRAM = SDRAM_ADDR,
|
|
||||||
.sizeSDRAM = SDRAM_SIZE,
|
|
||||||
.addrWBSDRAM = WB_SDRAM_ADDR,
|
|
||||||
.sizeWBSDRAM = WB_SDRAM_SIZE,
|
|
||||||
.resetVector = CPU_RESET_ADDR,
|
|
||||||
.cpuMemBaseAddr = CPU_MEM_START,
|
|
||||||
.stackStartAddr = STACK_BRAM_ADDR,
|
|
||||||
.m68kId = M68K_ID,
|
|
||||||
.sysFreq = CLK_FREQ,
|
|
||||||
.memFreq = CLK_FREQ,
|
|
||||||
.wbMemFreq = CLK_FREQ,
|
|
||||||
.implSoCCFG = 0,
|
|
||||||
.implWB = WB_IMPL,
|
|
||||||
.implWBSDRAM = WB_SDRAM_IMPL,
|
|
||||||
.implWBI2C = WB_I2C_IMPL,
|
|
||||||
.implInsnBRAM = INSN_BRAM_IMPL,
|
|
||||||
.implBRAM = BRAM_IMPL,
|
|
||||||
.implRAM = RAM_IMPL,
|
|
||||||
.implSDRAM = SDRAM_IMPL,
|
|
||||||
.implIOCTL = IOCTL_IMPL,
|
|
||||||
.implPS2 = PS2_IMPL,
|
|
||||||
.implSPI = SPI_IMPL,
|
|
||||||
.implSD = SD_IMPL,
|
|
||||||
.sdCardNo = SD_DEVICE_CNT,
|
|
||||||
.implIntrCtl = INTRCTL_IMPL,
|
|
||||||
.intrChannels = INTRCTL_CHANNELS,
|
|
||||||
.implTimer1 = TIMER1_IMPL,
|
|
||||||
.timer1No = TIMER1_TIMERS_CNT };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Method to populate the Configuration structure, initially using in-built values from compile time
|
|
||||||
// which are overriden with values stored in the SoC if available.
|
|
||||||
void setupSoCConfig(void)
|
|
||||||
{
|
|
||||||
// If the SoC Configuration register is implemented in the SoC, overwrite the compiled constants with those in the chip register.
|
|
||||||
if( IS_IMPL_SOCCFG )
|
|
||||||
{
|
|
||||||
cfgSoC.addrInsnBRAM = SOCCFG(SOCCFG_BRAMINSNADDR);
|
|
||||||
cfgSoC.sizeInsnBRAM = SOCCFG(SOCCFG_BRAMINSNSIZE);
|
|
||||||
cfgSoC.addrBRAM = SOCCFG(SOCCFG_BRAMADDR);
|
|
||||||
cfgSoC.sizeBRAM = SOCCFG(SOCCFG_BRAMSIZE);
|
|
||||||
cfgSoC.addrRAM = SOCCFG(SOCCFG_RAMADDR);
|
|
||||||
cfgSoC.sizeRAM = SOCCFG(SOCCFG_RAMSIZE);
|
|
||||||
cfgSoC.addrSDRAM = SOCCFG(SOCCFG_SDRAMADDR);
|
|
||||||
cfgSoC.sizeSDRAM = SOCCFG(SOCCFG_SDRAMSIZE);
|
|
||||||
cfgSoC.addrWBSDRAM = SOCCFG(SOCCFG_WBSDRAMADDR);
|
|
||||||
cfgSoC.sizeWBSDRAM = SOCCFG(SOCCFG_WBSDRAMSIZE);
|
|
||||||
cfgSoC.resetVector = SOCCFG(SOCCFG_CPURSTADDR);
|
|
||||||
cfgSoC.cpuMemBaseAddr = SOCCFG(SOCCFG_CPUMEMSTART);
|
|
||||||
cfgSoC.stackStartAddr = SOCCFG(SOCCFG_STACKSTART);
|
|
||||||
cfgSoC.m68kId = SOCCFG(SOCCFG_M68K_ID);
|
|
||||||
cfgSoC.sysFreq = SOCCFG(SOCCFG_SYSFREQ);
|
|
||||||
cfgSoC.memFreq = SOCCFG(SOCCFG_MEMFREQ);
|
|
||||||
cfgSoC.wbMemFreq = SOCCFG(SOCCFG_WBMEMFREQ);
|
|
||||||
cfgSoC.implSoCCFG = 1;
|
|
||||||
cfgSoC.implWB = IS_IMPL_WB != 0;
|
|
||||||
cfgSoC.implWBSDRAM = IS_IMPL_WB_SDRAM != 0;
|
|
||||||
cfgSoC.implWBI2C = IS_IMPL_WB_I2C != 0;
|
|
||||||
cfgSoC.implInsnBRAM = IS_IMPL_INSN_BRAM != 0;
|
|
||||||
cfgSoC.implBRAM = IS_IMPL_BRAM != 0;
|
|
||||||
cfgSoC.implRAM = IS_IMPL_RAM != 0;
|
|
||||||
cfgSoC.implSDRAM = IS_IMPL_SDRAM != 0;
|
|
||||||
cfgSoC.implIOCTL = IS_IMPL_IOCTL != 0;
|
|
||||||
cfgSoC.implPS2 = IS_IMPL_PS2 != 0;
|
|
||||||
cfgSoC.implSPI = IS_IMPL_SPI != 0;
|
|
||||||
cfgSoC.implSD = IS_IMPL_SD != 0;
|
|
||||||
cfgSoC.sdCardNo = (uint8_t)(SOCCFG_SD_DEVICES);
|
|
||||||
cfgSoC.implIntrCtl = IS_IMPL_INTRCTL != 0;
|
|
||||||
cfgSoC.intrChannels = (uint8_t)(SOCCFG_INTRCTL_CHANNELS);
|
|
||||||
cfgSoC.implTimer1 = IS_IMPL_TIMER1 != 0;
|
|
||||||
cfgSoC.timer1No = (uint8_t)(SOCCFG_TIMER1_TIMERS);
|
|
||||||
#ifndef USE_BOOT_ROM
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// Store builtin constants into structure which will be used when the SoC configuration module isnt implemented.
|
|
||||||
cfgSoC.addrInsnBRAM = INSN_BRAM_ADDR;
|
|
||||||
cfgSoC.sizeInsnBRAM = INSN_BRAM_SIZE;
|
|
||||||
cfgSoC.addrBRAM = BRAM_ADDR;
|
|
||||||
cfgSoC.sizeBRAM = BRAM_SIZE;
|
|
||||||
cfgSoC.addrRAM = RAM_ADDR;
|
|
||||||
cfgSoC.sizeRAM = RAM_SIZE;
|
|
||||||
cfgSoC.addrSDRAM = SDRAM_ADDR;
|
|
||||||
cfgSoC.sizeSDRAM = SDRAM_SIZE;
|
|
||||||
cfgSoC.addrWBSDRAM = WB_SDRAM_ADDR;
|
|
||||||
cfgSoC.sizeWBSDRAM = WB_SDRAM_SIZE;
|
|
||||||
cfgSoC.resetVector = CPU_RESET_ADDR;
|
|
||||||
cfgSoC.cpuMemBaseAddr = CPU_MEM_START;
|
|
||||||
cfgSoC.stackStartAddr = STACK_BRAM_ADDR;
|
|
||||||
cfgSoC.m68kId = M68K_ID;
|
|
||||||
cfgSoC.sysFreq = CLK_FREQ;
|
|
||||||
cfgSoC.memFreq = CLK_FREQ;
|
|
||||||
cfgSoC.wbMemFreq = CLK_FREQ;
|
|
||||||
cfgSoC.implSoCCFG = 0;
|
|
||||||
cfgSoC.implWB = WB_IMPL;
|
|
||||||
cfgSoC.implWBSDRAM = WB_SDRAM_IMPL;
|
|
||||||
cfgSoC.implWBI2C = WB_I2C_IMPL;
|
|
||||||
cfgSoC.implInsnBRAM = INSN_BRAM_IMPL;
|
|
||||||
cfgSoC.implBRAM = BRAM_IMPL ;
|
|
||||||
cfgSoC.implRAM = RAM_IMPL;
|
|
||||||
cfgSoC.implSDRAM = SDRAM_IMPL;;
|
|
||||||
cfgSoC.implIOCTL = IOCTL_IMPL;;
|
|
||||||
cfgSoC.implPS2 = PS2_IMPL;
|
|
||||||
cfgSoC.implSPI = SPI_IMPL;
|
|
||||||
cfgSoC.implSD = IMPL_SD;
|
|
||||||
cfgSoC.sdCardNo = SD_DEVICE_CNT;
|
|
||||||
cfgSoC.implIntrCtl = INTRCTL_IMPL;
|
|
||||||
cfgSoC.intrChannels = INTRCTL_CHANNELS;
|
|
||||||
cfgSoC.implTimer1 = TIMER1_IMPL;
|
|
||||||
cfgSoC.timer1No = TIMER1_TIMERS_CNT;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to show the current configuration via the primary uart channel.
|
|
||||||
//
|
|
||||||
#if !defined(FUNCTIONALITY) || FUNCTIONALITY <= 1
|
|
||||||
void showSoCConfig(void)
|
|
||||||
{
|
|
||||||
#if defined(__ZOS__) || defined(__ZPUTA__)
|
|
||||||
printf("SoC Configuration");
|
|
||||||
if(cfgSoC.implSoCCFG) { printf(" (from SoC config)"); }
|
|
||||||
printf(":\nDevices implemented:\n");
|
|
||||||
if(cfgSoC.implWBSDRAM) { printf(" WB SDRAM (%08X:%08X).\n", cfgSoC.addrWBSDRAM, cfgSoC.addrWBSDRAM + cfgSoC.sizeWBSDRAM); }
|
|
||||||
if(cfgSoC.implSDRAM) { printf(" SDRAM (%08X:%08X).\n", cfgSoC.addrSDRAM, cfgSoC.addrSDRAM + cfgSoC.sizeSDRAM); }
|
|
||||||
if(cfgSoC.implInsnBRAM) { printf(" INSN BRAM (%08X:%08X).\n", cfgSoC.addrInsnBRAM, cfgSoC.addrInsnBRAM + cfgSoC.sizeInsnBRAM); }
|
|
||||||
if(cfgSoC.implBRAM) { printf(" BRAM (%08X:%08X).\n", cfgSoC.addrBRAM, cfgSoC.addrBRAM + cfgSoC.sizeBRAM); }
|
|
||||||
if(cfgSoC.implRAM) { printf(" RAM (%08X:%08X).\n", cfgSoC.addrRAM, cfgSoC.addrRAM + cfgSoC.sizeRAM); }
|
|
||||||
if(cfgSoC.implSD) { printf(" SD CARD (Devices =%02d).\n", (uint8_t)cfgSoC.sdCardNo); }
|
|
||||||
if(cfgSoC.implTimer1) { printf(" TIMER1 (Timers =%02d).\n", (uint8_t)cfgSoC.timer1No); }
|
|
||||||
if(cfgSoC.implIntrCtl) { printf(" INTR CTRL (Channels=%02d).\n", (uint8_t)cfgSoC.intrChannels); }
|
|
||||||
if(cfgSoC.implWB) { printf(" WISHBONE BUS\n"); }
|
|
||||||
if(cfgSoC.implWBI2C) { printf(" WB I2C\n"); }
|
|
||||||
if(cfgSoC.implIOCTL) { printf(" IOCTL\n"); }
|
|
||||||
if(cfgSoC.implPS2) { printf(" PS2\n"); }
|
|
||||||
if(cfgSoC.implSPI) { printf(" SPI\n"); }
|
|
||||||
printf("Addresses:\n");
|
|
||||||
printf(" CPU Reset Vector Address = %08X\n", cfgSoC.resetVector);
|
|
||||||
printf(" CPU Memory Start Address = %08X\n", cfgSoC.cpuMemBaseAddr);
|
|
||||||
printf(" Stack Start Address = %08X\n", cfgSoC.stackStartAddr);
|
|
||||||
printf("Misc:\n");
|
|
||||||
printf(" M68K Id = %04X\n", cfgSoC.m68kId);
|
|
||||||
printf(" System Clock Freq = %d.%04dMHz\n", (cfgSoC.sysFreq / 1000000), cfgSoC.sysFreq - ((cfgSoC.sysFreq / 1000000) * 1000000));
|
|
||||||
if(cfgSoC.implSDRAM)
|
|
||||||
printf(" SDRAM Clock Freq = %d.%04dMHz\n", (cfgSoC.memFreq / 1000000), cfgSoC.memFreq - ((cfgSoC.memFreq / 1000000) * 1000000));
|
|
||||||
if(cfgSoC.implWBSDRAM)
|
|
||||||
printf(" Wishbone SDRAM Clock Freq= %d.%04dMHz\n", (cfgSoC.wbMemFreq / 1000000), cfgSoC.wbMemFreq - ((cfgSoC.wbMemFreq / 1000000) * 1000000));
|
|
||||||
#ifdef DRV_CFC
|
|
||||||
printf(" CFC = %08X\n", DRV_CFC);
|
|
||||||
#endif
|
|
||||||
#ifdef DRV_MMC
|
|
||||||
printf(" MMC = %08X\n", DRV_MMC);
|
|
||||||
#endif
|
|
||||||
//printf("\n");
|
|
||||||
#else
|
|
||||||
puts("SoC Configuration");
|
|
||||||
if(cfgSoC.implSoCCFG) { puts(" (from SoC config)"); }
|
|
||||||
puts(":\nDevices implemented:\n");
|
|
||||||
if(cfgSoC.implWBSDRAM) { puts(" WB SDRAM ("); printdhex(cfgSoC.addrWBSDRAM); puts(":"); printdhex(cfgSoC.addrWBSDRAM + cfgSoC.sizeWBSDRAM); puts(").\n"); }
|
|
||||||
if(cfgSoC.implSDRAM) { puts(" SDRAM ("); printdhex(cfgSoC.addrSDRAM); puts(":"); printdhex(cfgSoC.addrSDRAM + cfgSoC.sizeSDRAM); puts(").\n"); }
|
|
||||||
if(cfgSoC.implInsnBRAM) { puts(" INSN BRAM ("); printdhex(cfgSoC.addrInsnBRAM); puts(":"); printdhex(cfgSoC.addrInsnBRAM + cfgSoC.sizeInsnBRAM); puts(").\n"); }
|
|
||||||
if(cfgSoC.implBRAM) { puts(" BRAM ("); printdhex(cfgSoC.addrBRAM); puts(":"); printdhex(cfgSoC.addrBRAM + cfgSoC.sizeBRAM); puts(").\n"); }
|
|
||||||
if(cfgSoC.implRAM) { puts(" RAM ("); printdhex(cfgSoC.addrRAM); puts(":"); printdhex(cfgSoC.addrRAM + cfgSoC.sizeRAM); puts(").\n"); }
|
|
||||||
if(cfgSoC.implSD) { puts(" SD CARD (Devices ="); printhexbyte((uint8_t)cfgSoC.sdCardNo); puts(").\n"); }
|
|
||||||
if(cfgSoC.implTimer1) { puts(" TIMER1 (Timers ="); printnibble( (uint8_t)cfgSoC.timer1No); puts(").\n"); }
|
|
||||||
if(cfgSoC.implIntrCtl) { puts(" INTR CTRL (Channels="); printhexbyte((uint8_t)cfgSoC.intrChannels); puts(").\n"); }
|
|
||||||
if(cfgSoC.implWB) { puts(" WISHBONE BUS\n"); }
|
|
||||||
if(cfgSoC.implWB) { puts(" WB I2C\n"); }
|
|
||||||
if(cfgSoC.implIOCTL) { puts(" IOCTL\n"); }
|
|
||||||
if(cfgSoC.implPS2) { puts(" PS2\n"); }
|
|
||||||
if(cfgSoC.implSPI) { puts(" SPI\n"); }
|
|
||||||
puts("Addresses:\n");
|
|
||||||
puts(" CPU Reset Vector Address = "); printdhex(cfgSoC.resetVector); puts("\n");
|
|
||||||
puts(" CPU Memory Start Address = "); printdhex(cfgSoC.cpuMemBaseAddr); puts("\n");
|
|
||||||
puts(" Stack Start Address = "); printdhex(cfgSoC.stackStartAddr); puts("\n");
|
|
||||||
puts("Misc:\n");
|
|
||||||
puts(" M68K Id = "); printhex((uint16_t)cfgSoC.m68kId); puts("\n");
|
|
||||||
puts(" System Clock Freq = "); printdhex(cfgSoC.sysFreq); puts("\n");
|
|
||||||
if(cfgSoC.implSDRAM)
|
|
||||||
puts(" SDRAM Clock Freq = "); printdhex(cfgSoC.memFreq); puts("\n");
|
|
||||||
if(cfgSoC.implWBSDRAM)
|
|
||||||
puts(" Wishbone SDRAM Clock Freq= "); printdhex(cfgSoC.wbMemFreq); puts("\n");
|
|
||||||
#ifdef DRV_CFC
|
|
||||||
puts(" CFC = "); printdhex(DRV_CFC); puts("\n");
|
|
||||||
#endif
|
|
||||||
#ifdef DRV_MMC
|
|
||||||
puts(" MMC = "); printdhex(DRV_MMC); puts("\n");
|
|
||||||
#endif
|
|
||||||
puts("\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to print out the M68000 Id in text form.
|
|
||||||
void printM68KId(uint32_t m68kId)
|
|
||||||
{
|
|
||||||
switch((uint8_t)(m68kId >> 8))
|
|
||||||
{
|
|
||||||
case M68K_ID_M68008:
|
|
||||||
printf("M68008");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case M68K_ID_M68000:
|
|
||||||
printf("M68000");
|
|
||||||
break;
|
|
||||||
|
|
||||||
case M68K_ID_M68020:
|
|
||||||
printf("M68020");
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
printf("Unknown");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,319 +0,0 @@
|
|||||||
/*
|
|
||||||
* malloc.c
|
|
||||||
*
|
|
||||||
* Very simple linked-list based malloc()/free().
|
|
||||||
*
|
|
||||||
* Simplified even further by Alastair M. Robinson for TG68 project.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "stdio.h"
|
|
||||||
#include "malloc.h"
|
|
||||||
|
|
||||||
/* Both the arena list and the free memory list are double linked
|
|
||||||
list with head node. This the head node. Note that the arena list
|
|
||||||
is sorted in order of address. */
|
|
||||||
static struct free_arena_header __malloc_head = {
|
|
||||||
{
|
|
||||||
ARENA_TYPE_HEAD,
|
|
||||||
0,
|
|
||||||
&__malloc_head,
|
|
||||||
&__malloc_head,
|
|
||||||
},
|
|
||||||
&__malloc_head,
|
|
||||||
&__malloc_head
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline void mark_block_dead(struct free_arena_header *ah)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG_MALLOC
|
|
||||||
ah->a.type = ARENA_TYPE_DEAD;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void remove_from_main_chain(struct free_arena_header *ah)
|
|
||||||
{
|
|
||||||
struct free_arena_header *ap, *an;
|
|
||||||
|
|
||||||
mark_block_dead(ah);
|
|
||||||
|
|
||||||
ap = ah->a.prev;
|
|
||||||
an = ah->a.next;
|
|
||||||
ap->a.next = an;
|
|
||||||
an->a.prev = ap;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void remove_from_free_chain(struct free_arena_header *ah)
|
|
||||||
{
|
|
||||||
struct free_arena_header *ap, *an;
|
|
||||||
|
|
||||||
ap = ah->prev_free;
|
|
||||||
an = ah->next_free;
|
|
||||||
ap->next_free = an;
|
|
||||||
an->prev_free = ap;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void remove_from_chains(struct free_arena_header *ah)
|
|
||||||
{
|
|
||||||
remove_from_free_chain(ah);
|
|
||||||
remove_from_main_chain(ah);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *__malloc_from_block(struct free_arena_header *fp, size_t size)
|
|
||||||
{
|
|
||||||
size_t fsize;
|
|
||||||
struct free_arena_header *nfp, *na, *fpn, *fpp;
|
|
||||||
|
|
||||||
fsize = fp->a.size;
|
|
||||||
/* We need the 2* to account for the larger requirements of a
|
|
||||||
free block */
|
|
||||||
if (fsize >= (size + 2 * sizeof(struct arena_header))) {
|
|
||||||
/* Bigger block than required -- split block */
|
|
||||||
nfp = (struct free_arena_header *)((char *)fp + size);
|
|
||||||
na = fp->a.next;
|
|
||||||
|
|
||||||
nfp->a.type = ARENA_TYPE_FREE;
|
|
||||||
nfp->a.size = fsize - size;
|
|
||||||
fp->a.type = ARENA_TYPE_USED;
|
|
||||||
fp->a.size = size;
|
|
||||||
|
|
||||||
|
|
||||||
/* Insert into all-block chain */
|
|
||||||
nfp->a.prev = fp;
|
|
||||||
nfp->a.next = na;
|
|
||||||
na->a.prev = nfp;
|
|
||||||
fp->a.next = nfp;
|
|
||||||
|
|
||||||
/* Replace current block on free chain */
|
|
||||||
nfp->next_free = fpn = fp->next_free;
|
|
||||||
nfp->prev_free = fpp = fp->prev_free;
|
|
||||||
fpn->prev_free = nfp;
|
|
||||||
fpp->next_free = nfp;
|
|
||||||
} else {
|
|
||||||
fp->a.type = ARENA_TYPE_USED; /* Allocate the whole block */
|
|
||||||
remove_from_free_chain(fp);
|
|
||||||
}
|
|
||||||
return (void *)(&fp->a + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct free_arena_header *__free_block(struct free_arena_header *ah)
|
|
||||||
{
|
|
||||||
struct free_arena_header *pah, *nah;
|
|
||||||
|
|
||||||
pah = ah->a.prev;
|
|
||||||
nah = ah->a.next;
|
|
||||||
if (pah->a.type == ARENA_TYPE_FREE &&
|
|
||||||
(char *)pah + pah->a.size == (char *)ah) {
|
|
||||||
/* Coalesce into the previous block */
|
|
||||||
pah->a.size += ah->a.size;
|
|
||||||
pah->a.next = nah;
|
|
||||||
nah->a.prev = pah;
|
|
||||||
mark_block_dead(ah);
|
|
||||||
|
|
||||||
ah = pah;
|
|
||||||
pah = ah->a.prev;
|
|
||||||
} else {
|
|
||||||
/* Need to add this block to the free chain */
|
|
||||||
ah->a.type = ARENA_TYPE_FREE;
|
|
||||||
|
|
||||||
ah->next_free = __malloc_head.next_free;
|
|
||||||
ah->prev_free = &__malloc_head;
|
|
||||||
__malloc_head.next_free = ah;
|
|
||||||
ah->next_free->prev_free = ah;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* In either of the previous cases, we might be able to merge
|
|
||||||
with the subsequent block... */
|
|
||||||
if (nah->a.type == ARENA_TYPE_FREE &&
|
|
||||||
(char *)ah + ah->a.size == (char *)nah) {
|
|
||||||
ah->a.size += nah->a.size;
|
|
||||||
|
|
||||||
/* Remove the old block from the chains */
|
|
||||||
remove_from_chains(nah);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Return the block that contains the called block */
|
|
||||||
return ah;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void malloc_add(void *p,size_t size)
|
|
||||||
{
|
|
||||||
struct free_arena_header *fp;
|
|
||||||
struct free_arena_header *pah;
|
|
||||||
fp=(struct free_arena_header *)p;
|
|
||||||
fp->a.type = ARENA_TYPE_FREE;
|
|
||||||
fp->a.size = size & ~MALLOC_CHUNK_MASK; // Round down size to fit chunk mask
|
|
||||||
|
|
||||||
//printf("Adding %d bytes at %d to the memory pool\n",size,p);
|
|
||||||
|
|
||||||
/* We need to insert this into the main block list in the proper
|
|
||||||
place -- this list is required to be sorted. Since we most likely
|
|
||||||
get memory assignments in ascending order, search backwards for
|
|
||||||
the proper place. */
|
|
||||||
for (pah = __malloc_head.a.prev; pah->a.type != ARENA_TYPE_HEAD;
|
|
||||||
pah = pah->a.prev) {
|
|
||||||
if (pah < fp)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now pah points to the node that should be the predecessor of
|
|
||||||
the new node */
|
|
||||||
fp->a.next = pah->a.next;
|
|
||||||
fp->a.prev = pah;
|
|
||||||
pah->a.next = fp;
|
|
||||||
fp->a.next->a.prev = fp;
|
|
||||||
|
|
||||||
/* Insert into the free chain and coalesce with adjacent blocks */
|
|
||||||
fp = __free_block(fp);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void *malloc(size_t size)
|
|
||||||
{
|
|
||||||
struct free_arena_header *fp;
|
|
||||||
struct free_arena_header *pah;
|
|
||||||
size_t fsize;
|
|
||||||
|
|
||||||
//printf("Custom malloc asking for 0x%x bytes\n",size);
|
|
||||||
|
|
||||||
if (size == 0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Add the obligatory arena header, and round up */
|
|
||||||
size = (size + 2 * sizeof(struct arena_header) - 1) & ARENA_SIZE_MASK;
|
|
||||||
for (fp = __malloc_head.next_free; fp->a.type != ARENA_TYPE_HEAD;
|
|
||||||
fp = fp->next_free) {
|
|
||||||
|
|
||||||
if (fp->a.size >= size) {
|
|
||||||
/* Found fit -- allocate out of this block */
|
|
||||||
return __malloc_from_block(fp, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Nothing found... need to request a block from the kernel */
|
|
||||||
|
|
||||||
fsize = (size + MALLOC_CHUNK_MASK) & ~MALLOC_CHUNK_MASK;
|
|
||||||
|
|
||||||
#if 0 // AMR - using a fixed arena.
|
|
||||||
|
|
||||||
fp = (struct free_arena_header *)
|
|
||||||
mmap(NULL, fsize, PROT_READ | PROT_WRITE,
|
|
||||||
MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
|
|
||||||
|
|
||||||
if (fp == (struct free_arena_header *)MAP_FAILED) {
|
|
||||||
return NULL; /* Failed to get a block */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
fp = (struct free_arena_header *)_sbrk(fsize);
|
|
||||||
if(fp==0 || fp == -1)
|
|
||||||
return(NULL);
|
|
||||||
|
|
||||||
/* Insert the block into the management chains. We need to set
|
|
||||||
up the size and the main block list pointer, the rest of
|
|
||||||
the work is logically identical to free(). */
|
|
||||||
fp->a.type = ARENA_TYPE_FREE;
|
|
||||||
fp->a.size = fsize;
|
|
||||||
|
|
||||||
/* We need to insert this into the main block list in the proper
|
|
||||||
place -- this list is required to be sorted. Since we most likely
|
|
||||||
get memory assignments in ascending order, search backwards for
|
|
||||||
the proper place. */
|
|
||||||
for (pah = __malloc_head.a.prev; pah->a.type != ARENA_TYPE_HEAD;
|
|
||||||
pah = pah->a.prev) {
|
|
||||||
if (pah < fp)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Now pah points to the node that should be the predecessor of
|
|
||||||
the new node */
|
|
||||||
fp->a.next = pah->a.next;
|
|
||||||
fp->a.prev = pah;
|
|
||||||
pah->a.next = fp;
|
|
||||||
fp->a.next->a.prev = fp;
|
|
||||||
|
|
||||||
/* Insert into the free chain and coalesce with adjacent blocks */
|
|
||||||
fp = __free_block(fp);
|
|
||||||
|
|
||||||
/* Now we can allocate from this block */
|
|
||||||
return __malloc_from_block(fp, size);
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void free(void *ptr)
|
|
||||||
{
|
|
||||||
struct free_arena_header *ah;
|
|
||||||
|
|
||||||
if (!ptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ah = (struct free_arena_header *)
|
|
||||||
((struct arena_header *)ptr - 1);
|
|
||||||
/* Merge into adjacent free blocks */
|
|
||||||
ah = __free_block(ah);
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* See if it makes sense to return memory to the system */
|
|
||||||
{
|
|
||||||
size_t page_size = getpagesize();
|
|
||||||
size_t page_mask = page_size - 1;
|
|
||||||
size_t head_portion = -(size_t)ah & page_mask;
|
|
||||||
size_t tail_portion = ((size_t)ah + ah->a.size) & page_mask;
|
|
||||||
size_t adj_size;
|
|
||||||
|
|
||||||
/* Careful here... an individual chunk of memory must have
|
|
||||||
a minimum size if it exists at all, so if either the
|
|
||||||
head or the tail is below the minimum, then extend
|
|
||||||
that chunk by a page. */
|
|
||||||
|
|
||||||
if (head_portion &&
|
|
||||||
head_portion < 2*sizeof(struct arena_header))
|
|
||||||
head_portion += page_size;
|
|
||||||
|
|
||||||
if (tail_portion &&
|
|
||||||
tail_portion < 2*sizeof(struct arena_header))
|
|
||||||
tail_portion += page_size;
|
|
||||||
|
|
||||||
adj_size = ah->a.size - head_portion - tail_portion;
|
|
||||||
|
|
||||||
/* Worth it? This is written the way it is to guard
|
|
||||||
against overflows... */
|
|
||||||
if (ah->a.size >= head_portion+tail_portion+
|
|
||||||
_KLIBC_MALLOC_CHUNK_SIZE) {
|
|
||||||
struct free_arena_header *tah, *tan, *tap;
|
|
||||||
|
|
||||||
if (tail_portion) {
|
|
||||||
/* Make a new header, and insert into chains
|
|
||||||
immediately after the current block */
|
|
||||||
tah = (struct free_arena_header *)
|
|
||||||
((char *)ah + head_portion + adj_size);
|
|
||||||
tah->a.type = ARENA_TYPE_FREE;
|
|
||||||
tah->a.size = tail_portion;
|
|
||||||
tah->a.next = tan = ah->a.next;
|
|
||||||
tan->a.prev = tah;
|
|
||||||
tah->a.prev = ah;
|
|
||||||
ah->a.next = tah;
|
|
||||||
tah->prev_free = tap = ah->prev_free;
|
|
||||||
tap->next_free = tah;
|
|
||||||
tah->next_free = ah;
|
|
||||||
ah->prev_free = tah;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (head_portion)
|
|
||||||
ah->a.size = head_portion;
|
|
||||||
else
|
|
||||||
remove_from_chains(ah);
|
|
||||||
|
|
||||||
munmap((char *)ah + head_portion, adj_size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
long udivmodsi4 ();
|
|
||||||
|
|
||||||
long
|
|
||||||
__divsi3 (long a, long b)
|
|
||||||
{
|
|
||||||
int neg = 0;
|
|
||||||
long res;
|
|
||||||
|
|
||||||
if (a < 0)
|
|
||||||
{
|
|
||||||
a = -a;
|
|
||||||
neg = !neg;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b < 0)
|
|
||||||
{
|
|
||||||
b = -b;
|
|
||||||
neg = !neg;
|
|
||||||
}
|
|
||||||
|
|
||||||
res = udivmodsi4 (a, b, 0);
|
|
||||||
|
|
||||||
if (neg)
|
|
||||||
res = -res;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
long
|
|
||||||
__modsi3 (long a, long b)
|
|
||||||
{
|
|
||||||
int neg = 0;
|
|
||||||
long res;
|
|
||||||
|
|
||||||
if (a < 0)
|
|
||||||
{
|
|
||||||
a = -a;
|
|
||||||
neg = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (b < 0)
|
|
||||||
b = -b;
|
|
||||||
|
|
||||||
res = udivmodsi4 (a, b, 1);
|
|
||||||
|
|
||||||
if (neg)
|
|
||||||
res = -res;
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
@@ -1,377 +0,0 @@
|
|||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#if defined __K64F__
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "k64f_soc.h"
|
|
||||||
#define uint32_t __uint32_t
|
|
||||||
#define uint16_t __uint16_t
|
|
||||||
#define uint8_t __uint8_t
|
|
||||||
#define int32_t __int32_t
|
|
||||||
#define int16_t __int16_t
|
|
||||||
#define int8_t __int8_t
|
|
||||||
#else
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
#endif
|
|
||||||
#include "spi.h"
|
|
||||||
|
|
||||||
int SDHCtype;
|
|
||||||
|
|
||||||
#define cmd_reset(d) cmd_write(d, 0x950040,0) // Use SPI mode
|
|
||||||
#define cmd_init(d) cmd_write(d, 0xff0041,0)
|
|
||||||
#define cmd_read(d, x) cmd_write(d, 0xff0051,x)
|
|
||||||
#define cmd_CMD8(d) cmd_write(d, 0x870048,0x1AA)
|
|
||||||
#define cmd_CMD16(d, x) cmd_write(d, 0xFF0050,x)
|
|
||||||
#define cmd_CMD41(d) cmd_write(d, 0x870069,0x40000000)
|
|
||||||
#define cmd_CMD55(d) cmd_write(d, 0xff0077,0)
|
|
||||||
#define cmd_CMD58(d) cmd_write(d, 0xff007A,0)
|
|
||||||
|
|
||||||
#ifdef SPI_DEBUG
|
|
||||||
#define DBG(x) puts(x)
|
|
||||||
#else
|
|
||||||
#define DBG(X)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned char SPI_R1[6];
|
|
||||||
|
|
||||||
|
|
||||||
int SPI_GET_PUMP(uint32_t device)
|
|
||||||
{
|
|
||||||
#if defined __ZPU__
|
|
||||||
int r=0;
|
|
||||||
SPI_DATA(device) = 0xFF;
|
|
||||||
r=SPI_DATA(device);
|
|
||||||
SPI_DATA(device) = 0xFF;
|
|
||||||
r=(r<<8)|SPI_DATA(device);
|
|
||||||
SPI_DATA(device) = 0xFF;
|
|
||||||
r=(r<<8)|SPI_DATA(device);
|
|
||||||
SPI_DATA(device) = 0xFF;
|
|
||||||
r=(r<<8)|SPI_DATA(device);
|
|
||||||
return(r);
|
|
||||||
#elif defined __K64F__
|
|
||||||
debugf("SPI_GET_PUMP not yet implemented.\n");
|
|
||||||
return(0);
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__ or __K64F__"
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int cmd_write(uint32_t device, unsigned long cmd, unsigned long lba)
|
|
||||||
{
|
|
||||||
int result=0xff;
|
|
||||||
|
|
||||||
#if defined __ZPU__
|
|
||||||
int ctr;
|
|
||||||
|
|
||||||
DBG("In cmd_write\n");
|
|
||||||
|
|
||||||
SPI_DATA(device) = cmd & 255;
|
|
||||||
|
|
||||||
DBG("Command sent\n");
|
|
||||||
|
|
||||||
if(!SDHCtype) // If normal SD then we have to use byte offset rather than LBA offset.
|
|
||||||
lba<<=9;
|
|
||||||
|
|
||||||
DBG("Sending LBA!\n");
|
|
||||||
|
|
||||||
SPI_DATA(device) = (lba>>24)&255;
|
|
||||||
DBG("Sent 1st byte\n");
|
|
||||||
SPI_DATA(device) = (lba>>16)&255;
|
|
||||||
DBG("Sent 2nd byte\n");
|
|
||||||
SPI_DATA(device) = (lba>>8)&255;
|
|
||||||
DBG("Sent 3rd byte\n");
|
|
||||||
SPI_DATA(device) = lba&255;
|
|
||||||
DBG("Sent 4th byte\n");
|
|
||||||
|
|
||||||
DBG("Sending CRC - if any\n");
|
|
||||||
|
|
||||||
SPI_DATA(device) = (cmd>>16)&255; // CRC, if any
|
|
||||||
|
|
||||||
ctr=40000;
|
|
||||||
|
|
||||||
result=SPI_DATA(device);
|
|
||||||
while(--ctr && (result==0xff))
|
|
||||||
{
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
result=SPI_DATA(device);
|
|
||||||
}
|
|
||||||
#ifdef SPI_DEBUG
|
|
||||||
putc('0'+(result>>4));
|
|
||||||
putc('0'+(result&15));
|
|
||||||
#endif
|
|
||||||
// printf("Got result %d \n",result);
|
|
||||||
|
|
||||||
#elif defined __K64F__
|
|
||||||
debugf("cmd_write not yet implemented.\n");
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__ or __K64F__"
|
|
||||||
#endif
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void spi_spin(uint32_t device)
|
|
||||||
{
|
|
||||||
// puts("SPIspin");
|
|
||||||
#if defined __ZPU__
|
|
||||||
int i;
|
|
||||||
for(i=0;i<200;++i)
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
#elif defined __K64F__
|
|
||||||
debugf("spi_spin not yet implemented.\n");
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__ or __K64F__"
|
|
||||||
#endif
|
|
||||||
// puts("Done");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int wait_initV2(uint32_t device)
|
|
||||||
{
|
|
||||||
#if defined __ZPU__
|
|
||||||
int i=20000;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
spi_spin(device);
|
|
||||||
while(--i)
|
|
||||||
{
|
|
||||||
if((r=cmd_CMD55(device))==1)
|
|
||||||
{
|
|
||||||
// printf("CMD55 %d\n",r);
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
if((r=cmd_CMD41(device))==0)
|
|
||||||
{
|
|
||||||
// printf("CMD41 %d\n",r);
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
// else
|
|
||||||
// printf("CMD41 %d\n",r);
|
|
||||||
spi_spin(device);
|
|
||||||
}
|
|
||||||
// else
|
|
||||||
// printf("CMD55 %d\n",r);
|
|
||||||
}
|
|
||||||
#elif defined __K64F__
|
|
||||||
debugf("wait_initV2 not yet implemented.\n");
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__ or __K64F__"
|
|
||||||
#endif
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int wait_init(uint32_t device)
|
|
||||||
{
|
|
||||||
#if defined __ZPU__
|
|
||||||
int i=20;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
puts("Cmd_init");
|
|
||||||
while(--i)
|
|
||||||
{
|
|
||||||
if((r=cmd_init(device))==0)
|
|
||||||
{
|
|
||||||
// printf("init %d\n ",r);
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
// else
|
|
||||||
// printf("init %d\n ",r);
|
|
||||||
spi_spin(device);
|
|
||||||
}
|
|
||||||
#elif defined __K64F__
|
|
||||||
debugf("wait_init not yet implemented.\n");
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__ or __K64F__"
|
|
||||||
#endif
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int is_sdhc(uint32_t device)
|
|
||||||
{
|
|
||||||
#if defined __ZPU__
|
|
||||||
int i,r;
|
|
||||||
|
|
||||||
spi_spin(device);
|
|
||||||
|
|
||||||
r=cmd_CMD8(device); // test for SDHC capability
|
|
||||||
printf("cmd_CMD8 response: %d\n",r);
|
|
||||||
if(r!=1)
|
|
||||||
{
|
|
||||||
wait_init(device);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
r=SPI_GET_PUMP(device);
|
|
||||||
if((r&0xffff)!=0x01aa)
|
|
||||||
{
|
|
||||||
printf("CMD8_4 response: %d\n",r);
|
|
||||||
wait_init(device);
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
|
|
||||||
// If we get this far we have a V2 card, which may or may not be SDHC...
|
|
||||||
|
|
||||||
i=50;
|
|
||||||
while(--i)
|
|
||||||
{
|
|
||||||
if(wait_initV2(device))
|
|
||||||
{
|
|
||||||
if((r=cmd_CMD58(device))==0)
|
|
||||||
{
|
|
||||||
printf("CMD58 %d\n ",r);
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
r=SPI_DATA(device);
|
|
||||||
printf("CMD58_2 %d\n ",r);
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
if(r&0x40)
|
|
||||||
return(1);
|
|
||||||
else
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
printf("CMD58 %d\n ",r);
|
|
||||||
}
|
|
||||||
if(i==2)
|
|
||||||
{
|
|
||||||
printf("SDHC Initialization error!\n");
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#elif defined __K64F__
|
|
||||||
debugf("is_sdhc not yet implemented.\n");
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__ or __K64F__"
|
|
||||||
#endif
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int spi_init(uint32_t device)
|
|
||||||
{
|
|
||||||
#if defined __ZPU__
|
|
||||||
int i;
|
|
||||||
//int r;
|
|
||||||
|
|
||||||
SDHCtype=1;
|
|
||||||
SPI_SET_CS(device, 0); // Disable CS
|
|
||||||
spi_spin(device);
|
|
||||||
puts("SPI Init()");
|
|
||||||
DBG("Activating CS\n");
|
|
||||||
SPI_SET_CS(device, 1);
|
|
||||||
i=8;
|
|
||||||
while(--i)
|
|
||||||
{
|
|
||||||
if(cmd_reset(device)==1) // Enable SPI mode
|
|
||||||
i=1;
|
|
||||||
DBG("Sent reset command\n");
|
|
||||||
if(i==2)
|
|
||||||
{
|
|
||||||
DBG("SD card initialization error!\n");
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DBG("Card responded to reset\n");
|
|
||||||
SDHCtype=is_sdhc(device);
|
|
||||||
if(SDHCtype)
|
|
||||||
DBG("SDHC card detected\n");
|
|
||||||
else // If not SDHC, Set blocksize to 512 bytes
|
|
||||||
{
|
|
||||||
DBG("Sending cmd16 (blocksize)\n");
|
|
||||||
cmd_CMD16(device,1);
|
|
||||||
}
|
|
||||||
SPI_DATA(device) = 0xFF;
|
|
||||||
SPI_SET_CS(device, 0);
|
|
||||||
SPI_DATA(device) = 0xFF;
|
|
||||||
DBG("Init done\n");
|
|
||||||
#elif defined __K64F__
|
|
||||||
debugf("spi_init not yet implemented.\n");
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__ or __K64F__"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int sd_write_sector(uint32_t device, unsigned long lba,unsigned char *buf) // FIXME - Stub
|
|
||||||
{
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern void spi_readsector(long *buf);
|
|
||||||
|
|
||||||
|
|
||||||
int sd_read_sector(uint32_t device, unsigned long lba,unsigned char *buf)
|
|
||||||
{
|
|
||||||
int result=0;
|
|
||||||
#if defined __ZPU__
|
|
||||||
int i;
|
|
||||||
int r;
|
|
||||||
|
|
||||||
// printf("sd_read_sector %d, %d\n",lba,buf);
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
SPI_SET_CS(device, 1|(1<<SPI_FAST));
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
|
|
||||||
r=cmd_read(device, lba);
|
|
||||||
if(r!=0)
|
|
||||||
{
|
|
||||||
printf("Read command failed at %ld (%d)\n",lba,r);
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
i=1500000;
|
|
||||||
while(--i)
|
|
||||||
{
|
|
||||||
int v;
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
// SPI_WAIT();
|
|
||||||
v=SPI_DATA(device);
|
|
||||||
if(v==0xfe)
|
|
||||||
{
|
|
||||||
// puts("Reading sector data");
|
|
||||||
// spi_readsector((long *)buf);
|
|
||||||
int j;
|
|
||||||
// SPI_DATA(device) = 0xff;
|
|
||||||
|
|
||||||
for(j=0;j<128;++j)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
|
|
||||||
t=SPI_GET_PUMP(device);
|
|
||||||
*(int *)buf=t;
|
|
||||||
// printf("%d: %d\n",buf,t);
|
|
||||||
buf+=4;
|
|
||||||
}
|
|
||||||
|
|
||||||
i=1; // break out of the loop
|
|
||||||
result=1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
SPI_DATA(device) = 0xff;
|
|
||||||
SPI_SET_CS(device, 0);
|
|
||||||
#elif defined __K64F__
|
|
||||||
debugf("sd_read_sector not yet implemented.\n");
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__ or __K64F__"
|
|
||||||
#endif
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
unsigned int SwapBBBB(unsigned int i)
|
|
||||||
{
|
|
||||||
unsigned int result=(i>>24)&0xff;
|
|
||||||
result|=(i>>8)&0xff00;
|
|
||||||
result|=(i<<8)&0xff0000;
|
|
||||||
result|=(i<<24)&0xff00000;
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int SwapBB(unsigned int i)
|
|
||||||
{
|
|
||||||
unsigned short result=(i>>8)&0xff;
|
|
||||||
result|=(i<<8)&0xff00;
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned long SwapWW(unsigned long i)
|
|
||||||
{
|
|
||||||
unsigned int result=(i>>16)&0xffff;
|
|
||||||
result|=(i<<16)&0xffff0000;
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
long udivmodsi4 ();
|
|
||||||
|
|
||||||
long
|
|
||||||
__udivsi3 (long a, long b)
|
|
||||||
{
|
|
||||||
return udivmodsi4 (a, b, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
long
|
|
||||||
__umodsi3 (long a, long b)
|
|
||||||
{
|
|
||||||
return udivmodsi4 (a, b, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
unsigned long
|
|
||||||
udivmodsi4(unsigned long num, unsigned long den, int modwanted)
|
|
||||||
{
|
|
||||||
unsigned long bit = 1;
|
|
||||||
unsigned long res = 0;
|
|
||||||
|
|
||||||
while (den < num && bit && !(den & (1L<<31)))
|
|
||||||
{
|
|
||||||
den <<=1;
|
|
||||||
bit <<=1;
|
|
||||||
}
|
|
||||||
while (bit)
|
|
||||||
{
|
|
||||||
if (num >= den)
|
|
||||||
{
|
|
||||||
num -= den;
|
|
||||||
res |= bit;
|
|
||||||
}
|
|
||||||
bit >>=1;
|
|
||||||
den >>=1;
|
|
||||||
}
|
|
||||||
if (modwanted) return num;
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -1,907 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: osd.c
|
|
||||||
// Created: May 2021
|
|
||||||
// Version: v1.0
|
|
||||||
// Author(s): Philip Smart
|
|
||||||
// Description: The On Screen Display library.
|
|
||||||
// This source file contains the On Screen Display definitions and methods.
|
|
||||||
// The OSD is a popup area on the video controller which can be used to display
|
|
||||||
// text/menus and accept user input. Notably this is intended to be instantiated
|
|
||||||
// inside an I/O processor onboard the FPGA hosting the Sharp MZ Series emulation
|
|
||||||
// and provide a user interface in order to configure/interact with the emulation.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2019-2021 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: v1.0 May 2021 - Initial write of the OSD software.
|
|
||||||
//
|
|
||||||
// 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 <core_pins.h>
|
|
||||||
#include <usb_serial.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 "ff.h" /* Declarations of FatFs API */
|
|
||||||
#include "diskio.h"
|
|
||||||
#include "utils.h"
|
|
||||||
#include <fonts.h>
|
|
||||||
#include <bitmaps.h>
|
|
||||||
#include <tranzputer.h>
|
|
||||||
#include <osd.h>
|
|
||||||
|
|
||||||
#ifndef __APP__ // Protected methods which should only reside in the kernel on zOS.
|
|
||||||
static t_OSDWindow osdWindow = {.mode=MENU, .params={ {.attr=0, .row=0, .col=0, .maxCol=0, .maxRow=0, .lineWrap=1, .maxX=VC_STATUS_MAX_X_PIXELS, .maxY=VC_STATUS_MAX_Y_PIXELS},
|
|
||||||
{.attr=0, .row=0, .col=0, .maxCol=0, .maxRow=0, .lineWrap=1, .maxX=VC_MENU_MAX_X_PIXELS, .maxY=VC_MENU_MAX_Y_PIXELS} },
|
|
||||||
.debug=0, .inDebug=0, .display=NULL};
|
|
||||||
|
|
||||||
// Method to get internal public member values. This module ideally should be written in C++ but with the limitations of the GNU C Compiler for the ZPU (v3.4.2) and the performance penalty on
|
|
||||||
// an embedded processor, it was decided to write it in C but the methodology and naming conventions (ie. OSDDrawLine = OSD.DrawLine, OSDInit = OSD::OSD constructor) are kept loosly
|
|
||||||
// associated with C++. Ideally for this getter method function overloading is required!
|
|
||||||
//
|
|
||||||
uint32_t OSDGet(enum OSDPARAMS param)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
//
|
|
||||||
uint32_t result;
|
|
||||||
|
|
||||||
switch(param)
|
|
||||||
{
|
|
||||||
case ACTIVE_MAX_X:
|
|
||||||
result = (uint32_t)osdWindow.params[osdWindow.mode].maxX;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ACTIVE_MAX_Y:
|
|
||||||
result = (uint32_t)osdWindow.params[osdWindow.mode].maxY;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
result = 0xFFFFFFFF;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to retrieve a font definition structure based on the enumeration.
|
|
||||||
//
|
|
||||||
fontStruct *OSDGetFont(enum FONTS font)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
//
|
|
||||||
fontStruct *fontptr;
|
|
||||||
|
|
||||||
// Obtain the font structure based on the provided type.
|
|
||||||
switch(font)
|
|
||||||
{
|
|
||||||
case FONT_3X6:
|
|
||||||
fontptr = &font3x6;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FONT_7X8:
|
|
||||||
fontptr = &font7x8extended;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FONT_9X16:
|
|
||||||
fontptr = &font9x16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FONT_11X16:
|
|
||||||
fontptr = &font11x16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FONT_5X7:
|
|
||||||
default:
|
|
||||||
fontptr = &font5x7extended;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return(fontptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to retrieve a bitmap definition structure based on the enumeration.
|
|
||||||
//
|
|
||||||
bitmapStruct *OSDGetBitmap(enum BITMAPS bitmap)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
//
|
|
||||||
fontStruct *bitmapptr;
|
|
||||||
|
|
||||||
// Obtain the bitmap structure based on the provided type.
|
|
||||||
switch(bitmap)
|
|
||||||
{
|
|
||||||
case BITMAP_ARGO:
|
|
||||||
default:
|
|
||||||
bitmapptr = & argo;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return(bitmapptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// External method to set a pixel in the active framebuffer.
|
|
||||||
//
|
|
||||||
void OSDSetPixel(uint16_t x, uint16_t y, enum COLOUR colour)
|
|
||||||
{
|
|
||||||
if(y >= 0 && y < osdWindow.params[osdWindow.mode].maxY && x >= 0 && x < osdWindow.params[osdWindow.mode].maxX)
|
|
||||||
{
|
|
||||||
for(uint8_t c=0; c < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); c++)
|
|
||||||
{
|
|
||||||
if(colour & (1 << c))
|
|
||||||
{
|
|
||||||
osdWindow.display[c][((y * osdWindow.params[osdWindow.mode].maxX) + x)/8] |= 0x80 >> x%8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// External method to clear a pixel in the active framebuffer.
|
|
||||||
//
|
|
||||||
void OSDClearPixel(uint16_t x, uint16_t y, enum COLOUR colour)
|
|
||||||
{
|
|
||||||
if(y >= 0 && y < osdWindow.params[osdWindow.mode].maxY && x >= 0 && x < osdWindow.params[osdWindow.mode].maxX)
|
|
||||||
{
|
|
||||||
for(uint8_t c=0; c < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); c++)
|
|
||||||
{
|
|
||||||
if(colour & (1 << c))
|
|
||||||
{
|
|
||||||
osdWindow.display[c][((y * osdWindow.params[osdWindow.mode].maxX) + x)/8] &= ~(0x80 >> x%8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// External method to change the colour of a pixel
|
|
||||||
void OSDChangePixelColour(uint16_t x, uint16_t y, enum COLOUR fg, enum COLOUR bg)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
uint8_t isPixelSet = 0;
|
|
||||||
|
|
||||||
if(y >= 0 && y < osdWindow.params[osdWindow.mode].maxY && x >= 0 && x < osdWindow.params[osdWindow.mode].maxX)
|
|
||||||
{
|
|
||||||
// See if a pixel is set at this co-ordinate independent of colour.
|
|
||||||
for(uint8_t c=0; c < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); c++)
|
|
||||||
{
|
|
||||||
isPixelSet |= osdWindow.display[c][((y * osdWindow.params[osdWindow.mode].maxX) + x)/8];
|
|
||||||
// Clear out the pixel as it will be redefined.
|
|
||||||
osdWindow.display[c][((y * osdWindow.params[osdWindow.mode].maxX) + x)/8] &= ~(0x80 >> x%8);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Go through all the colours and set the new colour.
|
|
||||||
for(uint8_t c=0; c < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); c++)
|
|
||||||
{
|
|
||||||
// Active pixels take on the foreground colour.
|
|
||||||
if(fg & (1 << c) && (isPixelSet & (0x80 >> x%8)))
|
|
||||||
{
|
|
||||||
osdWindow.display[c][((y * osdWindow.params[osdWindow.mode].maxX) + x)/8] |= 0x80 >> x%8;
|
|
||||||
|
|
||||||
// Inactive pixels take on the background colour.
|
|
||||||
} else if(bg & (1 << c) && !(isPixelSet & (0x80 >> x%8)))
|
|
||||||
{
|
|
||||||
osdWindow.display[c][((y * osdWindow.params[osdWindow.mode].maxX) + x)/8] |= 0x80 >> x%8;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Internal method to write a single character into the status/menu framebuffer. The X/Y location is specified in font units, also the orientation,
|
|
||||||
// colour and required font.
|
|
||||||
//
|
|
||||||
void _OSDwrite(uint8_t x, uint8_t y, int8_t xoff, int8_t yoff, uint8_t xpad, uint8_t ypad, enum ORIENTATION orientation, uint8_t chr, enum COLOUR fg, enum COLOUR bg, fontStruct *font)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
uint16_t startX;
|
|
||||||
uint16_t startY;
|
|
||||||
uint16_t addr;
|
|
||||||
uint16_t height;
|
|
||||||
uint16_t width;
|
|
||||||
uint16_t spacing;
|
|
||||||
uint8_t vChrRow;
|
|
||||||
uint8_t bytesInChar;
|
|
||||||
uint8_t bitStartOffset;
|
|
||||||
uint8_t bitOffset;
|
|
||||||
uint8_t bitPos;
|
|
||||||
uint8_t chrByteSize;
|
|
||||||
uint8_t chrByteOffset;
|
|
||||||
|
|
||||||
// Check bounds of character.
|
|
||||||
if(chr < font->start || chr > font->end)
|
|
||||||
{
|
|
||||||
if(osdWindow.debug)
|
|
||||||
printf("Character out of bounds:%02x(%d,%d)\n", chr, font->start, font->end);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate the starting byte.
|
|
||||||
switch(orientation)
|
|
||||||
{
|
|
||||||
case DEG90:
|
|
||||||
width = font->height;
|
|
||||||
height = font->width;
|
|
||||||
spacing = font->spacing;
|
|
||||||
startX = osdWindow.params[osdWindow.mode].maxX - ((y+1) * (width + spacing)) - yoff;
|
|
||||||
startY = x * (height + spacing) + xoff;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEG180:
|
|
||||||
width = font->width;
|
|
||||||
height = font->height;
|
|
||||||
spacing = font->spacing;
|
|
||||||
startX = osdWindow.params[osdWindow.mode].maxX - ((x+1) * (width + spacing)) - xoff;
|
|
||||||
startY = osdWindow.params[osdWindow.mode].maxY - ((y+1) * (height + spacing)) - yoff;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEG270:
|
|
||||||
width = font->height;
|
|
||||||
height = font->width;
|
|
||||||
spacing = font->spacing;
|
|
||||||
startX = (y * (width + spacing)) + yoff;
|
|
||||||
startY = osdWindow.params[osdWindow.mode].maxY - ((x+1) * (height + spacing)) - xoff;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NORMAL:
|
|
||||||
default:
|
|
||||||
width = font->width;
|
|
||||||
height = font->height;
|
|
||||||
spacing = font->spacing;
|
|
||||||
startX = (x * (width + spacing + 2*xpad)) + xpad + xoff;
|
|
||||||
startY = (y * (height + spacing + 2*ypad)) + ypad + yoff;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cant write if out of bounds.
|
|
||||||
if(startX > osdWindow.params[osdWindow.mode].maxX || startY > osdWindow.params[osdWindow.mode].maxY || startX+width > osdWindow.params[osdWindow.mode].maxX || startY+height > osdWindow.params[osdWindow.mode].maxY)
|
|
||||||
{
|
|
||||||
if(osdWindow.debug)
|
|
||||||
printf("Position out of bounds:%d,%d(%d,%d)\n", startX, startY, x, y);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write according to orientation.
|
|
||||||
switch(orientation)
|
|
||||||
{
|
|
||||||
case DEG90:
|
|
||||||
for(int16_t row=-ypad; row < height+ypad; row++)
|
|
||||||
{
|
|
||||||
for(int16_t col=-xpad; col < width+spacing+xpad; col++)
|
|
||||||
{
|
|
||||||
for(uint8_t colourMode = 0; colourMode < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); colourMode++)
|
|
||||||
{
|
|
||||||
// Work out positional information.
|
|
||||||
bytesInChar = (width/8) + 1;
|
|
||||||
bitStartOffset = ((width%8) != 0 ? (8-(width%8)) : 0);
|
|
||||||
bitPos = (col+bitStartOffset)/8 == 0 ? bitStartOffset + (col%8) : col%8;
|
|
||||||
chrByteSize = (width < 8 ? 1 : width/8);
|
|
||||||
chrByteOffset = (abs(width - col - 1)/8);
|
|
||||||
|
|
||||||
// When 'in the money', get an 8bit part row of the font based on the row/col.
|
|
||||||
vChrRow = (row < 0 || row >= height || col < 0 || col >= width) ? 0 : font->bitmap[((chr - font->start) * (height * chrByteSize)) + (row * chrByteSize) + chrByteOffset ];
|
|
||||||
|
|
||||||
// Calculate destination address.
|
|
||||||
// <- Start pos based on Y -> <- Offset to X ->
|
|
||||||
addr=((startY + row) * (osdWindow.params[osdWindow.mode].maxX/8)) + (startX + col)/8;
|
|
||||||
|
|
||||||
// Calculate the bit offset in the targetted byte according to the font width.
|
|
||||||
bitOffset = (startX+col)%8;
|
|
||||||
|
|
||||||
// Test to see if a foreground or background pixel is set and update the framebuffer accordingly.
|
|
||||||
if(vChrRow & 0x80 >> bitPos)
|
|
||||||
{
|
|
||||||
if(fg & (1 << colourMode))
|
|
||||||
osdWindow.display[colourMode][addr] |= 0x80 >> bitOffset;
|
|
||||||
else
|
|
||||||
osdWindow.display[colourMode][addr] &= ~(0x80 >> bitOffset);
|
|
||||||
if(osdWindow.debug && colourMode == 0) { printf("*"); }
|
|
||||||
} else if(bg & (1 << colourMode))
|
|
||||||
{
|
|
||||||
osdWindow.display[colourMode][addr] |= 0x80 >> bitOffset;
|
|
||||||
if(osdWindow.debug && colourMode == 0) { printf(" "); }
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
osdWindow.display[colourMode][addr] &= ~(0x80 >> bitOffset);
|
|
||||||
if(osdWindow.debug && colourMode == 0) { printf(" "); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if(osdWindow.debug)
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEG180:
|
|
||||||
for(int16_t row=-ypad; row < height+ypad; row++)
|
|
||||||
{
|
|
||||||
for(int16_t col=-xpad; col < width+spacing+xpad; col++)
|
|
||||||
{
|
|
||||||
for(uint8_t colourMode = 0; colourMode < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); colourMode++)
|
|
||||||
{
|
|
||||||
chrByteSize = (height < 8 ? 1 : height/8);
|
|
||||||
bitStartOffset = ((height%8) != 0 ? (8-(height%8)) : 0);
|
|
||||||
bitPos = (row+bitStartOffset)/8 == 0 ? bitStartOffset + (row%8) : row%8;
|
|
||||||
|
|
||||||
// Calculate destination address.
|
|
||||||
// <- Start pos based on Y -> <- Offset to X ->
|
|
||||||
addr=((startY + row) * (osdWindow.params[osdWindow.mode].maxX/8)) + ((startX + width + spacing - col - 1)/8);
|
|
||||||
|
|
||||||
// When 'in the money', get an 8bit part row of the font based on the row/col.
|
|
||||||
vChrRow = (row < 0 || row >= height || col < 0 || col >= width) ? 0 : font->bitmap[((chr - font->start) * (width * chrByteSize)) + (height > 8 ? col*2 : col) + (height-row-1)/8];
|
|
||||||
|
|
||||||
// Calculate the bit offset in the targetted byte according to the font width.
|
|
||||||
bitOffset = 8 - ((startX+(width-col))%8) - 1;
|
|
||||||
|
|
||||||
if(vChrRow & 0x80 >> bitPos)
|
|
||||||
{
|
|
||||||
if(fg & (1 << colourMode))
|
|
||||||
osdWindow.display[colourMode][addr] |= 1 << bitOffset;
|
|
||||||
else
|
|
||||||
osdWindow.display[colourMode][addr] &= ~(1 << bitOffset);
|
|
||||||
if(osdWindow.debug && colourMode == 0) { printf("*"); }
|
|
||||||
}
|
|
||||||
else if(bg & (1 << colourMode))
|
|
||||||
{
|
|
||||||
osdWindow.display[colourMode][addr] |= 1 << bitOffset;
|
|
||||||
if(osdWindow.debug && colourMode == 0) { printf(" "); }
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
osdWindow.display[colourMode][addr] &= ~(1 << bitOffset);
|
|
||||||
if(osdWindow.debug && colourMode == 0) { printf(" "); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(osdWindow.debug)
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEG270:
|
|
||||||
for(int16_t row=-ypad; row < height+ypad; row++)
|
|
||||||
{
|
|
||||||
for(int16_t col=-xpad; col < width+spacing+xpad; col++)
|
|
||||||
{
|
|
||||||
for(uint8_t colourMode = 0; colourMode < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); colourMode++)
|
|
||||||
{
|
|
||||||
// Work out positional information.
|
|
||||||
bytesInChar = (width/8) + 1;
|
|
||||||
bitStartOffset = ((width%8) != 0 ? (8-(width%8)) : 0);
|
|
||||||
bitPos = col%8;
|
|
||||||
chrByteSize = (width < 8 ? 1 : width/8);
|
|
||||||
chrByteOffset = (col/8);
|
|
||||||
|
|
||||||
// When 'in the money', get an 8bit part row of the font based on the row/col.
|
|
||||||
vChrRow = (row < 0 || row >= height || col < 0 || col >= width) ? 0 : font->bitmap[((chr - font->start) * (height * chrByteSize)) + ((height-row-1) * chrByteSize) + chrByteOffset ];
|
|
||||||
|
|
||||||
// Calculate destination address.
|
|
||||||
// <- Start pos based on Y -> <- Offset to X ->
|
|
||||||
addr=((startY + row) * (osdWindow.params[osdWindow.mode].maxX/8)) + (startX + col)/8;
|
|
||||||
|
|
||||||
// Calculate the bit offset in the targetted byte according to the font width.
|
|
||||||
bitOffset = (startX+col)%8;
|
|
||||||
|
|
||||||
// Test to see if a pixel is set and update the framebuffer accordingly.
|
|
||||||
if(vChrRow & 1 << bitPos)
|
|
||||||
{
|
|
||||||
if(fg & (1 << colourMode))
|
|
||||||
osdWindow.display[colourMode][addr] |= 0x80 >> bitOffset;
|
|
||||||
else
|
|
||||||
osdWindow.display[colourMode][addr] &= ~(0x80 >> bitOffset);
|
|
||||||
if(osdWindow.debug && colourMode == 0) { printf("*"); }
|
|
||||||
}
|
|
||||||
else if(bg & (1 << colourMode))
|
|
||||||
{
|
|
||||||
osdWindow.display[colourMode][addr] |= 0x80 >> bitOffset;
|
|
||||||
if(osdWindow.debug && colourMode == 0) { printf(" "); }
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
osdWindow.display[colourMode][addr] &= ~(0x80 >> bitOffset);
|
|
||||||
if(osdWindow.debug && colourMode == 0)
|
|
||||||
{
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if(osdWindow.debug)
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NORMAL:
|
|
||||||
default:
|
|
||||||
// Trace out the bitmap into the framebuffer.
|
|
||||||
for(int16_t row=-ypad; row < height+ypad; row++)
|
|
||||||
{
|
|
||||||
for(int16_t col=-xpad; col < width+spacing+xpad; col++)
|
|
||||||
{
|
|
||||||
for(uint8_t colourMode = 0; colourMode < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); colourMode++)
|
|
||||||
{
|
|
||||||
// Calculate destination address.
|
|
||||||
// <- Start pos based on Y -> <- Offset to X ->
|
|
||||||
addr=((startY + row) * (osdWindow.params[osdWindow.mode].maxX/8)) + ((startX + col)/8);
|
|
||||||
|
|
||||||
// When 'in the money', get an 8bit part row of the font based on the row/col.
|
|
||||||
vChrRow = (row < 0 || row >= height || col < 0 || col >= width) ? 0 : font->bitmap[((chr - font->start) * (width * (height < 8 ? 1 : height/8))) + (height > 8 ? col*2 : col) + row/8];
|
|
||||||
|
|
||||||
// Calculate the bit offset in the targetted byte according to the font width.
|
|
||||||
bitOffset = (startX+col)%8;
|
|
||||||
|
|
||||||
if(vChrRow & (1 << (row % 8)))
|
|
||||||
{
|
|
||||||
if(fg & (1 << colourMode))
|
|
||||||
osdWindow.display[colourMode][addr] |= 0x80 >> bitOffset;
|
|
||||||
else
|
|
||||||
osdWindow.display[colourMode][addr] &= ~(0x80 >> bitOffset);
|
|
||||||
if(osdWindow.debug && colourMode == 0) { printf("*"); }
|
|
||||||
}
|
|
||||||
else if(bg & (1 << colourMode))
|
|
||||||
{
|
|
||||||
osdWindow.display[colourMode][addr] |= 0x80 >> bitOffset;
|
|
||||||
if(osdWindow.debug && colourMode == 0) { printf(" "); }
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
osdWindow.display[colourMode][addr] &= ~(0x80 >> bitOffset);
|
|
||||||
if(osdWindow.debug && colourMode == 0)
|
|
||||||
{
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(osdWindow.debug)
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to draw a stored bitmap onto the OSD display.
|
|
||||||
void OSDWriteBitmap(uint16_t x, uint16_t y, double xscale, double yscale, enum BITMAPS bitmap, enum COLOUR fg, enum COLOUR bg)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
bitmapStruct *bmptr = OSDGetBitmap(bitmap);
|
|
||||||
uint16_t addr;
|
|
||||||
uint16_t height = bmptr->height;
|
|
||||||
uint16_t width = bmptr->width;
|
|
||||||
uint8_t bytesPerRow = width % 8 == 0 ? width/8 : (width/8)+1;
|
|
||||||
uint8_t vChrRow;
|
|
||||||
uint8_t bitOffset;
|
|
||||||
|
|
||||||
uint16_t endRow = (int)((y+height)*yscale) > osdWindow.params[osdWindow.mode].maxY ? osdWindow.params[osdWindow.mode].maxY : (int)((y+height)*yscale);
|
|
||||||
uint16_t endCol = (int)((x+width)*xscale) > osdWindow.params[osdWindow.mode].maxX ? osdWindow.params[osdWindow.mode].maxX : (int)((x+width)*xscale);
|
|
||||||
|
|
||||||
// Check parameters.
|
|
||||||
if(x >= osdWindow.params[osdWindow.mode].maxX || y >= osdWindow.params[osdWindow.mode].maxY)
|
|
||||||
{
|
|
||||||
if(osdWindow.debug)
|
|
||||||
printf("Bitmap coordinates out of range:(%d,%d)\n", x, y);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Trace out the bitmap into the framebuffer.
|
|
||||||
for(int16_t row=y; row < endRow; row++)
|
|
||||||
{
|
|
||||||
for(int16_t col=x; col < endCol; col++)
|
|
||||||
{
|
|
||||||
uint16_t bmAddr = (uint16_t)((((int)(col-x)/xscale)/8) + ((int)((row - y)/yscale) * bytesPerRow));
|
|
||||||
|
|
||||||
for(uint8_t colourMode = 0; colourMode < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); colourMode++)
|
|
||||||
{
|
|
||||||
// Calculate destination address.
|
|
||||||
// <- Start pos based on Y -> <- Offset to X ->
|
|
||||||
addr=((row * osdWindow.params[osdWindow.mode].maxX)+ ((uint16_t)(col/xscale)))/8;
|
|
||||||
|
|
||||||
// When 'in the money', get an 8bit part row of the bitmap based on the row/col.
|
|
||||||
//vChrRow = (row < 0 || row >= y+height || col < 0 || col >= x+width) ? 0 : bmptr->bitmap[(uint16_t)((((int)(col-x)/t)/8) + ((int)((row - y)/t) * bytesPerRow))];
|
|
||||||
vChrRow = bmptr->bitmap[bmAddr];
|
|
||||||
|
|
||||||
// Calculate the bit offset in the targetted byte according to the bmptr width.
|
|
||||||
bitOffset = (uint8_t)((col-x)/xscale)%8;
|
|
||||||
//if(colourMode == 0)
|
|
||||||
// printf("(%d,%d)%02x,%02x,%d,%d,%d,%d,%d\n", row, col, bmptr->bitmap[(uint16_t)((((int)(col-x)/t)/8) + ((int)((row - y)/t) * bytesPerRow))], vChrRow, bitOffset, (col/8) + (row * bytesPerRow), bytesPerRow, height, width);
|
|
||||||
|
|
||||||
if(vChrRow & (0x80 >> bitOffset))
|
|
||||||
{
|
|
||||||
if(fg & (1 << colourMode))
|
|
||||||
osdWindow.display[colourMode][addr] |= 0x80 >> bitOffset;
|
|
||||||
else
|
|
||||||
osdWindow.display[colourMode][addr] &= ~(0x80 >> bitOffset);
|
|
||||||
//if(osdWindow.debug && colourMode == 0) { printf("*"); }
|
|
||||||
if(colourMode == 0) { printf("*"); }
|
|
||||||
}
|
|
||||||
else if(bg & (1 << colourMode))
|
|
||||||
{
|
|
||||||
osdWindow.display[colourMode][addr] |= 0x80 >> bitOffset;
|
|
||||||
//if(osdWindow.debug && colourMode == 0) { printf(" "); }
|
|
||||||
if(colourMode == 0) { printf(" "); }
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
osdWindow.display[colourMode][addr] &= ~(0x80 >> bitOffset);
|
|
||||||
//if(osdWindow.debug && colourMode == 0)
|
|
||||||
if(colourMode == 0)
|
|
||||||
{
|
|
||||||
printf(" ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// if(osdWindow.debug)
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// External method to write a single character onto the required framebuffer. Font, orientation and colour can be specified. The X/Y co-ordinates
|
|
||||||
// are at the character level and suitably adjusted based on the font selected.
|
|
||||||
//
|
|
||||||
void OSDWriteChar(uint8_t x, uint8_t y, uint8_t xoff, uint8_t yoff, uint8_t xpad, uint8_t ypad, enum FONTS font, enum ORIENTATION orientation, uint8_t chr, enum COLOUR fg, enum COLOUR bg)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
//
|
|
||||||
|
|
||||||
_OSDwrite(x, y, xoff, yoff, xpad, ypad, orientation, chr, fg, bg, OSDGetFont(font));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to write a string to the required framebuffer. The X/Y co-ordinates are relative to the orientation, ie. start - NORMAL=0/0, DEG90 = maxX-font width/0,
|
|
||||||
// DEG180 = maxX-font width/maxY-font height, DEG270 = 0/maxY-font height.
|
|
||||||
//
|
|
||||||
void OSDWriteString(uint8_t x, uint8_t y, int8_t xoff, int8_t yoff, uint8_t xpad, uint8_t ypad, enum FONTS font, enum ORIENTATION orientation, uint8_t *str, enum COLOUR fg, enum COLOUR bg)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
//
|
|
||||||
fontStruct *fontptr;
|
|
||||||
uint8_t startX;
|
|
||||||
uint8_t startY;
|
|
||||||
uint8_t maxX;
|
|
||||||
uint8_t maxY;
|
|
||||||
uint8_t xpos = x;
|
|
||||||
uint8_t ypos = y;
|
|
||||||
|
|
||||||
// Obtain the font structure based on the provided type.
|
|
||||||
fontptr = OSDGetFont(font);
|
|
||||||
|
|
||||||
// Use the orientation to set the physical start and maxim coordinates for the given font.
|
|
||||||
switch(orientation)
|
|
||||||
{
|
|
||||||
case DEG90:
|
|
||||||
startX=osdWindow.params[osdWindow.mode].maxX/(fontptr->height + fontptr->spacing);
|
|
||||||
startY=0;
|
|
||||||
maxX=osdWindow.params[osdWindow.mode].maxX/(fontptr->height + fontptr->spacing);
|
|
||||||
maxY=osdWindow.params[osdWindow.mode].maxY/(fontptr->width + fontptr->spacing);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEG180:
|
|
||||||
startX=osdWindow.params[osdWindow.mode].maxX/(fontptr->width + fontptr->spacing);
|
|
||||||
startY=osdWindow.params[osdWindow.mode].maxY/(fontptr->height + fontptr->spacing);
|
|
||||||
maxX=osdWindow.params[osdWindow.mode].maxX/(fontptr->width + fontptr->spacing);
|
|
||||||
maxY=osdWindow.params[osdWindow.mode].maxY/(fontptr->height + fontptr->spacing);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEG270:
|
|
||||||
startX=0;
|
|
||||||
startY=osdWindow.params[osdWindow.mode].maxY/(fontptr->width + fontptr->spacing);
|
|
||||||
maxX=osdWindow.params[osdWindow.mode].maxX/(fontptr->height + fontptr->spacing);
|
|
||||||
maxY=osdWindow.params[osdWindow.mode].maxY/(fontptr->width + fontptr->spacing);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NORMAL:
|
|
||||||
default:
|
|
||||||
startX=0;
|
|
||||||
startY=0;
|
|
||||||
maxX=osdWindow.params[osdWindow.mode].maxX/(fontptr->width + fontptr->spacing);
|
|
||||||
maxY=osdWindow.params[osdWindow.mode].maxY/(fontptr->height + fontptr->spacing);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Output the string.
|
|
||||||
for(uint8_t *ptr=str; *ptr != 0x00; ptr++)
|
|
||||||
{
|
|
||||||
_OSDwrite(xpos++, ypos, xoff, yoff, xpad, ypad, orientation, (*ptr), fg, bg, fontptr);
|
|
||||||
|
|
||||||
if(xpos > maxX)
|
|
||||||
{
|
|
||||||
if(!osdWindow.params[osdWindow.mode].lineWrap)
|
|
||||||
xpos--;
|
|
||||||
else if(ypos < maxY)
|
|
||||||
{
|
|
||||||
ypos++;
|
|
||||||
xpos=0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to refresh the active screen from the buffer contents.
|
|
||||||
void OSDRefreshScreen(void)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
//
|
|
||||||
uint32_t addr = VIDEO_OSD_BLUE_ADDR;
|
|
||||||
|
|
||||||
// Loop through the colour buffers and write contents out to the FPGA memory.
|
|
||||||
for(uint8_t c=0; c < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); c++)
|
|
||||||
{
|
|
||||||
writeZ80Array(addr, osdWindow.display[c], (VC_MENU_BUFFER_SIZE > VC_STATUS_BUFFER_SIZE ? VC_MENU_BUFFER_SIZE : VC_STATUS_BUFFER_SIZE), FPGA);
|
|
||||||
addr += 0x10000;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Simple screen clear method using memset to erase all pixels to inactive state.
|
|
||||||
//
|
|
||||||
void OSDClearScreen(enum COLOUR colour)
|
|
||||||
{
|
|
||||||
// Clear the buffer memory to effect a blank screen.
|
|
||||||
for(uint8_t c=0; c < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); c++)
|
|
||||||
{
|
|
||||||
memset(osdWindow.display[c], (colour & 1 << c ? 0xFF : 0x00), VC_MENU_BUFFER_SIZE > VC_STATUS_BUFFER_SIZE ? VC_MENU_BUFFER_SIZE : VC_STATUS_BUFFER_SIZE);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear a portion of the screen and set to a fixed colour.
|
|
||||||
//
|
|
||||||
void OSDClearArea(int16_t startX, int16_t startY, int16_t endX, int16_t endY, enum COLOUR colour)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
int16_t sx = (startX == -1 ? 0 : startX);
|
|
||||||
int16_t sy = (startY == -1 ? 0 : startY);
|
|
||||||
int16_t ex = (endX == -1 ? osdWindow.params[osdWindow.mode].maxX-1 : endX);
|
|
||||||
int16_t ey = (endY == -1 ? osdWindow.params[osdWindow.mode].maxY-1 : endY);
|
|
||||||
|
|
||||||
// Sanity check.
|
|
||||||
if(sx < 0 || ex >= osdWindow.params[osdWindow.mode].maxX || sx > ex || sy < 0 || ey >= osdWindow.params[osdWindow.mode].maxY || sy > ey)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Not the most efficient but speed not essential, go through the entire pixel area and clear or set the required colour bit for each pixel.
|
|
||||||
//
|
|
||||||
for(uint16_t row=0; row < osdWindow.params[osdWindow.mode].maxY; row++)
|
|
||||||
{
|
|
||||||
for(uint16_t col=0; col < osdWindow.params[osdWindow.mode].maxX; col++)
|
|
||||||
{
|
|
||||||
for(uint8_t c=0; c < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); c++)
|
|
||||||
{
|
|
||||||
if(row >= sy && row <= ey && col >= sx && col <= ex)
|
|
||||||
{
|
|
||||||
if(colour & (1 << c))
|
|
||||||
{
|
|
||||||
osdWindow.display[c][((row * osdWindow.params[osdWindow.mode].maxX) + col)/8] |= 0x80 >> col%8;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
osdWindow.display[c][((row * osdWindow.params[osdWindow.mode].maxX) + col)/8] &= ~(0x80 >> col%8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to draw a line on the active window.
|
|
||||||
//
|
|
||||||
void OSDDrawLine(int16_t startX, int16_t startY, int16_t endX, int16_t endY, enum COLOUR colour)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
int16_t sx = (startX == -1 ? osdWindow.params[osdWindow.mode].maxX-1 : startX);
|
|
||||||
int16_t sy = (startY == -1 ? osdWindow.params[osdWindow.mode].maxY-1 : startY);
|
|
||||||
int16_t ex = (endX == -1 ? osdWindow.params[osdWindow.mode].maxX-1 : endX);
|
|
||||||
int16_t ey = (endY == -1 ? osdWindow.params[osdWindow.mode].maxY-1 : endY);
|
|
||||||
int dx = abs (ex - sx), stx = sx < ex ? 1 : -1;
|
|
||||||
int dy = -abs (ey - sy), sty = sy < ey ? 1 : -1;
|
|
||||||
int err = dx + dy, e2; /* error value e_xy */
|
|
||||||
int16_t x = sx;
|
|
||||||
int16_t y = sy;
|
|
||||||
|
|
||||||
// Sanity check.
|
|
||||||
if(sx < 0 || ex >= osdWindow.params[osdWindow.mode].maxX || sx > ex || ey < 0 || ey >= osdWindow.params[osdWindow.mode].maxY || sy > ey)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (;;)
|
|
||||||
{
|
|
||||||
setPixel(sx, sy, colour);
|
|
||||||
|
|
||||||
if (sx == ex && sy == ey) break;
|
|
||||||
e2 = 2 * err;
|
|
||||||
if (e2 >= dy) { err += dy; sx += stx; } /* e_xy+e_x > 0 */
|
|
||||||
if (e2 <= dx) { err += dx; sy += sty; } /* e_xy+e_y < 0 */
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to draw a circle in the active window.
|
|
||||||
//
|
|
||||||
void OSDDrawCircle(int16_t startX, int16_t startY, int16_t radius, enum COLOUR colour)
|
|
||||||
{
|
|
||||||
int16_t sx = (startX == -1 ? osdWindow.params[osdWindow.mode].maxX-1 : startX);
|
|
||||||
int16_t sy = (startY == -1 ? osdWindow.params[osdWindow.mode].maxY-1 : startY);
|
|
||||||
int16_t x = -radius;
|
|
||||||
int16_t y = 0;
|
|
||||||
int16_t err = 2-2*radius;
|
|
||||||
|
|
||||||
do {
|
|
||||||
setPixel(((sx-x)/VC_OSD_X_CORRECTION), ((sy+y)/VC_OSD_Y_CORRECTION), colour); /* I. Quadrant */
|
|
||||||
setPixel(((sx-y)/VC_OSD_X_CORRECTION), ((sy-x)/VC_OSD_Y_CORRECTION), colour); /* II. Quadrant */
|
|
||||||
setPixel(((sx+x)/VC_OSD_X_CORRECTION), ((sy-y)/VC_OSD_Y_CORRECTION), colour); /* III. Quadrant */
|
|
||||||
setPixel(((sx+y)/VC_OSD_X_CORRECTION), ((sy+x)/VC_OSD_Y_CORRECTION), colour); /* IV. Quadrant */
|
|
||||||
|
|
||||||
radius = err;
|
|
||||||
if (radius > x) err += ++x*2+1; /* e_xy+e_x > 0 */
|
|
||||||
if (radius <= y) err += ++y*2+1; /* e_xy+e_y < 0 */
|
|
||||||
} while (x < 0);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A brute force method to create a filled circle in the active window.
|
|
||||||
//
|
|
||||||
void OSDDrawFilledCircle(int16_t startX, int16_t startY, int16_t radius, enum COLOUR colour)
|
|
||||||
{
|
|
||||||
int16_t sx = (startX == -1 ? osdWindow.params[osdWindow.mode].maxX-1 : startX);
|
|
||||||
int16_t sy = (startY == -1 ? osdWindow.params[osdWindow.mode].maxY-1 : startY);
|
|
||||||
int16_t r2 = radius * radius;
|
|
||||||
|
|
||||||
for(int y=-radius; y<=radius; y++)
|
|
||||||
{
|
|
||||||
for(int x=-radius; x<=radius; x++)
|
|
||||||
{
|
|
||||||
if(x*x+y*y <= r2)
|
|
||||||
{
|
|
||||||
setPixel(((sx+x)/VC_OSD_X_CORRECTION), ((sy+y)/VC_OSD_Y_CORRECTION), colour);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Method to draw an ellipse in the active window.
|
|
||||||
//
|
|
||||||
void OSDDrawEllipse(int16_t startX, int16_t startY, int16_t endX, int16_t endY, enum COLOUR colour)
|
|
||||||
{
|
|
||||||
int16_t sx = (startX == -1 ? osdWindow.params[osdWindow.mode].maxX-1 : startX);
|
|
||||||
int16_t sy = (startY == -1 ? osdWindow.params[osdWindow.mode].maxY-1 : startY);
|
|
||||||
int16_t ex = (endX == -1 ? osdWindow.params[osdWindow.mode].maxX-1 : endX);
|
|
||||||
int16_t ey = (endY == -1 ? osdWindow.params[osdWindow.mode].maxY-1 : endY);
|
|
||||||
uint16_t a = abs(ex - sx);
|
|
||||||
uint16_t b = abs(ey - sy);
|
|
||||||
uint16_t b1 = b & 1; /* values of diameter */
|
|
||||||
long dx = 4 * (1 - a) * b * b;
|
|
||||||
long dy = 4 * (b1 + 1) * a * a; /* error increment */
|
|
||||||
long err = dx + dy + b1 * a * a;
|
|
||||||
long e2; /* error of 1.step */
|
|
||||||
|
|
||||||
if (sx > ex) { sx = ex; ex += a; } /* if called with swapped points */
|
|
||||||
if (sy > ey) sy = ey; /* .. exchange them */
|
|
||||||
sy += (b + 1) / 2;
|
|
||||||
ey = sy-b1; /* starting pixel */
|
|
||||||
a *= 8 * a; b1 = 8 * b * b;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
setPixel((ex/VC_OSD_X_CORRECTION), (sy/VC_OSD_Y_CORRECTION), colour); /* I. Quadrant */
|
|
||||||
setPixel((sx/VC_OSD_X_CORRECTION), (sy/VC_OSD_Y_CORRECTION), colour); /* II. Quadrant */
|
|
||||||
setPixel((sx/VC_OSD_X_CORRECTION), (ey/VC_OSD_Y_CORRECTION), colour); /* III. Quadrant */
|
|
||||||
setPixel((ex/VC_OSD_X_CORRECTION), (ey/VC_OSD_Y_CORRECTION), colour); /* IV. Quadrant */
|
|
||||||
e2 = 2 * err;
|
|
||||||
|
|
||||||
/* x step */
|
|
||||||
if (e2 >= dx)
|
|
||||||
{
|
|
||||||
sx++;
|
|
||||||
ex--;
|
|
||||||
err += dx += b1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* y step */
|
|
||||||
if (e2 <= dy)
|
|
||||||
{
|
|
||||||
sy++;
|
|
||||||
ey--;
|
|
||||||
err += dy += a;
|
|
||||||
}
|
|
||||||
} while (sx <= ex);
|
|
||||||
|
|
||||||
/* too early stop of flat ellipses a=1 */
|
|
||||||
while (sy-ey < b)
|
|
||||||
{
|
|
||||||
setPixel(((sx-1)/VC_OSD_X_CORRECTION), (sy/VC_OSD_Y_CORRECTION), colour); /* I. Quadrant */
|
|
||||||
setPixel(((ex+1)/VC_OSD_X_CORRECTION), (sy/VC_OSD_Y_CORRECTION), colour); /* I. Quadrant */
|
|
||||||
sy++;
|
|
||||||
setPixel(((sx-1)/VC_OSD_X_CORRECTION), (ey/VC_OSD_Y_CORRECTION), colour); /* I. Quadrant */
|
|
||||||
setPixel(((ex+1)/VC_OSD_X_CORRECTION), (ey/VC_OSD_Y_CORRECTION), colour); /* I. Quadrant */
|
|
||||||
ey--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to change the active window used by the OSD routines. Only one window can be active at a time as they share underlying resources
|
|
||||||
// (ie. FPGA BRAM, OSD display buffer etc).
|
|
||||||
void OSDSetActiveWindow(enum WINDOWS window)
|
|
||||||
{
|
|
||||||
// Set the starting default window.
|
|
||||||
osdWindow.mode = window;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialise the OSD subsystem. This method only needs to be called once, calling subsequent times will free and reallocate memory.
|
|
||||||
//
|
|
||||||
uint8_t OSDInit(enum WINDOWS window)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
//
|
|
||||||
uint8_t result = 0;
|
|
||||||
|
|
||||||
// Allocate heap for the OSD display buffers. The size is set to the maximum required buffer.
|
|
||||||
if(osdWindow.display != NULL)
|
|
||||||
{
|
|
||||||
if(osdWindow.debug)
|
|
||||||
printf("Freeing OSD display framebuffer:%08lx\n", osdWindow.display);
|
|
||||||
free(osdWindow.display);
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// Allocate largest required block on the heap which will act as the OSD window framebuffer - this is necessary as updating the physical display is time consuming due to control overhead.
|
|
||||||
//
|
|
||||||
osdWindow.display = malloc(VC_MENU_RGB_BITS * VC_MENU_BUFFER_SIZE > VC_STATUS_RGB_BITS * VC_STATUS_BUFFER_SIZE ? VC_MENU_RGB_BITS * VC_MENU_BUFFER_SIZE : VC_STATUS_RGB_BITS * VC_STATUS_BUFFER_SIZE);
|
|
||||||
if(osdWindow.display == NULL)
|
|
||||||
{
|
|
||||||
printf("Failed to allocate heap for the OSD display framebuffer, %d bytes\n", VC_MENU_RGB_BITS * VC_MENU_BUFFER_SIZE > VC_STATUS_RGB_BITS * VC_STATUS_BUFFER_SIZE ? VC_MENU_RGB_BITS * VC_MENU_BUFFER_SIZE : VC_STATUS_RGB_BITS * VC_STATUS_BUFFER_SIZE);
|
|
||||||
result = 1;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
if(osdWindow.debug)
|
|
||||||
printf("OSD window framebuffer allocated: %dBytes@%08lx\n", VC_MENU_RGB_BITS * VC_MENU_BUFFER_SIZE > VC_STATUS_RGB_BITS * VC_STATUS_BUFFER_SIZE ? VC_MENU_RGB_BITS * VC_MENU_BUFFER_SIZE : VC_STATUS_RGB_BITS * VC_STATUS_BUFFER_SIZE, osdWindow.display);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clear screen ready for use.
|
|
||||||
OSDClearScreen(BLACK);
|
|
||||||
|
|
||||||
// Set the starting default window.
|
|
||||||
OSDSetActiveWindow(window);
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,133 +0,0 @@
|
|||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined __K64F__
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#define uint32_t __uint32_t
|
|
||||||
#define uint16_t __uint16_t
|
|
||||||
#define uint8_t __uint8_t
|
|
||||||
#define int32_t __int32_t
|
|
||||||
#define int16_t __int16_t
|
|
||||||
#define int8_t __int8_t
|
|
||||||
#include "k64f_soc.h"
|
|
||||||
#elif defined __ZPU__
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
#elif defined __M68K__
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "m68k_soc.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "ps2.h"
|
|
||||||
#include "interrupts.h"
|
|
||||||
#include "keyboard.h"
|
|
||||||
|
|
||||||
void ps2_ringbuffer_init(struct ps2_ringbuffer *r)
|
|
||||||
{
|
|
||||||
r->in_hw=0;
|
|
||||||
r->in_cpu=0;
|
|
||||||
r->out_hw=0;
|
|
||||||
r->out_cpu=0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ps2_ringbuffer_write(struct ps2_ringbuffer *r,int in)
|
|
||||||
{
|
|
||||||
while(r->out_hw==((r->out_cpu+1)&(PS2_RINGBUFFER_SIZE-1)))
|
|
||||||
;
|
|
||||||
// printf("w: %d, %d\n, %d\n",r->out_hw,r->out_cpu,in);
|
|
||||||
DisableInterrupts();
|
|
||||||
r->outbuf[r->out_cpu]=in;
|
|
||||||
r->out_cpu=(r->out_cpu+1) & (PS2_RINGBUFFER_SIZE-1);
|
|
||||||
PS2Handler();
|
|
||||||
EnableInterrupts();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int ps2_ringbuffer_read(struct ps2_ringbuffer *r)
|
|
||||||
{
|
|
||||||
unsigned char result;
|
|
||||||
if(r->in_hw==r->in_cpu)
|
|
||||||
return(-1); // No characters ready
|
|
||||||
result=r->inbuf[r->in_cpu];
|
|
||||||
r->in_cpu=(r->in_cpu+1) & (PS2_RINGBUFFER_SIZE-1);
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ps2_ringbuffer_count(struct ps2_ringbuffer *r)
|
|
||||||
{
|
|
||||||
if(r->in_hw>=r->in_cpu)
|
|
||||||
return(r->in_hw-r->in_cpu);
|
|
||||||
return(r->in_hw+PS2_RINGBUFFER_SIZE-r->in_cpu);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ps2_ringbuffer kbbuffer;
|
|
||||||
struct ps2_ringbuffer mousebuffer;
|
|
||||||
|
|
||||||
|
|
||||||
#if defined __ZPU__
|
|
||||||
void PS2Handler()
|
|
||||||
{
|
|
||||||
int kbd;
|
|
||||||
int mouse;
|
|
||||||
|
|
||||||
DisableInterrupts();
|
|
||||||
|
|
||||||
kbd=PS2_KEYBOARD(PS2_0);
|
|
||||||
mouse=PS2_MOUSE(PS2_0);
|
|
||||||
|
|
||||||
if(kbd & (1<<BIT_PS2_RECV))
|
|
||||||
{
|
|
||||||
kbbuffer.inbuf[kbbuffer.in_hw]=kbd&0xff;
|
|
||||||
kbbuffer.in_hw=(kbbuffer.in_hw+1) & (PS2_RINGBUFFER_SIZE-1);
|
|
||||||
}
|
|
||||||
if(kbd & (1<<BIT_PS2_CTS))
|
|
||||||
{
|
|
||||||
if(kbbuffer.out_hw!=kbbuffer.out_cpu)
|
|
||||||
{
|
|
||||||
PS2_KEYBOARD(PS2_0)=kbbuffer.outbuf[kbbuffer.out_hw];
|
|
||||||
kbbuffer.out_hw=(kbbuffer.out_hw+1) & (PS2_RINGBUFFER_SIZE-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(mouse & (1<<BIT_PS2_RECV))
|
|
||||||
{
|
|
||||||
mousebuffer.inbuf[mousebuffer.in_hw]=mouse&0xff;
|
|
||||||
mousebuffer.in_hw=(mousebuffer.in_hw+1) & (PS2_RINGBUFFER_SIZE-1);
|
|
||||||
}
|
|
||||||
if(mouse & (1<<BIT_PS2_CTS))
|
|
||||||
{
|
|
||||||
if(mousebuffer.out_hw!=mousebuffer.out_cpu)
|
|
||||||
{
|
|
||||||
PS2_MOUSE(PS2_0)=mousebuffer.outbuf[mousebuffer.out_hw];
|
|
||||||
mousebuffer.out_hw=(mousebuffer.out_hw+1) & (PS2_RINGBUFFER_SIZE-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//GetInterrupts(); // Clear interrupt bit
|
|
||||||
EnableInterrupts();
|
|
||||||
}
|
|
||||||
#elif defined __K64F__
|
|
||||||
void PS2Handler()
|
|
||||||
{
|
|
||||||
EnableInterrupts();
|
|
||||||
}
|
|
||||||
#elif defined __M68K__
|
|
||||||
void PS2Handler()
|
|
||||||
{
|
|
||||||
EnableInterrupts();
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__, __K64F__ or __M68K__"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void PS2Init()
|
|
||||||
{
|
|
||||||
ps2_ringbuffer_init(&kbbuffer);
|
|
||||||
ps2_ringbuffer_init(&mousebuffer);
|
|
||||||
SetIntHandler(&PS2Handler);
|
|
||||||
ClearKeyboard();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,817 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: readline.c
|
|
||||||
// Created: April 2020
|
|
||||||
// Author(s): Alfred Klomp (www.alfredklomp.com) - original readline.c
|
|
||||||
// Philip Smart - Port to K64f/ZPU and many upgrades, ie. additions of history buffer logic.
|
|
||||||
// Description: A readline module for embedded systems without the overhead of GNU readline or the
|
|
||||||
// need to use > C99 standard as the ZPU version of GCC doesnt support it!
|
|
||||||
// The readline modules originally came from Alfred Klomp's Raduino project and whilst
|
|
||||||
// I was searching for an alternative to GNU after failing to compile it with the ZPU
|
|
||||||
// version of GCC (as well as the size), I came across RADUINO and this readline
|
|
||||||
// module was very well written and easily portable to this project.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) -> 2016 - Alfred Klomp (www.alfredklomp.com) original code
|
|
||||||
// (C) 2020 - Philip Smart <philip.smart@net2net.org> porting, history buf.
|
|
||||||
// local commands and updates.
|
|
||||||
//
|
|
||||||
// History: April 2020 - With the advent of the tranZPUter SW, I needed a better command
|
|
||||||
// line module for entering, recalling and editting commands. This
|
|
||||||
// module after adding history buffer mechanism is the ideal
|
|
||||||
// solution.
|
|
||||||
// features of zOS where applicable.
|
|
||||||
//
|
|
||||||
// Notes: See Makefile to enable/disable conditional components
|
|
||||||
// __SD_CARD__ - Add the SDCard logic.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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 <string.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <../libraries/include/stdmisc.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#elif defined __ZPU__
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdmisc.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#elif defined __M68K__
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined __SD_CARD__
|
|
||||||
#include <ff.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#if defined __APP__
|
|
||||||
#if defined __K64F__
|
|
||||||
#undef stdin
|
|
||||||
#undef stdout
|
|
||||||
#undef stderr
|
|
||||||
extern FILE *stdout;
|
|
||||||
extern FILE *stdin;
|
|
||||||
extern FILE *stderr;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define malloc sys_malloc
|
|
||||||
#define realloc sys_realloc
|
|
||||||
#define calloc sys_calloc
|
|
||||||
#define free sys_free
|
|
||||||
void *sys_malloc(size_t); // Allocate memory managed by the OS.
|
|
||||||
void *sys_realloc(void *, size_t); // Reallocate a block of memory managed by the OS.
|
|
||||||
void *sys_calloc(size_t, size_t); // Allocate and zero a block of memory managed by the OS.
|
|
||||||
void sys_free(void *); // Free memory managed by the OS.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// List of local commands processed by readline.
|
|
||||||
#define CMD_HISTORY 0x01
|
|
||||||
#define CMD_RECALL 0x02
|
|
||||||
|
|
||||||
// Special key codes recognised by readline.
|
|
||||||
#define CTRL_A 0x01
|
|
||||||
#define CTRL_B 0x02
|
|
||||||
#define CTRL_C 0x03
|
|
||||||
#define CTRL_D 0x04
|
|
||||||
#define CTRL_E 0x05
|
|
||||||
#define CTRL_F 0x06
|
|
||||||
#define BACKSPACE 0x08
|
|
||||||
#define CTRL_K 0x0b
|
|
||||||
#define ENTER 0x0d
|
|
||||||
#define CTRL_P 0x10
|
|
||||||
#define RIGHTBRACKET 0x5b
|
|
||||||
#define TILDA 0x7e
|
|
||||||
#define CTRL_N 0x0e
|
|
||||||
#define ESC 0x1b
|
|
||||||
|
|
||||||
// Line buffer control variables.
|
|
||||||
static uint8_t llen, lpos;
|
|
||||||
|
|
||||||
#define MAX_HISTORY_LINES 20
|
|
||||||
static char *history[MAX_HISTORY_LINES] = {};
|
|
||||||
static uint8_t histFreeSlot = 0;
|
|
||||||
|
|
||||||
#if defined __SD_CARD__
|
|
||||||
static FIL *histFp = NULL;
|
|
||||||
static uint8_t histDisabled = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Keys we distinguish:
|
|
||||||
enum keytype {
|
|
||||||
KEY_REGULAR,
|
|
||||||
KEY_BKSP,
|
|
||||||
KEY_CTRL_A,
|
|
||||||
KEY_CTRL_B,
|
|
||||||
KEY_CTRL_C,
|
|
||||||
KEY_CTRL_D,
|
|
||||||
KEY_CTRL_E,
|
|
||||||
KEY_CTRL_F,
|
|
||||||
KEY_CTRL_K,
|
|
||||||
KEY_CTRL_N,
|
|
||||||
KEY_CTRL_P,
|
|
||||||
KEY_ENTER,
|
|
||||||
KEY_INSERT,
|
|
||||||
KEY_HOME,
|
|
||||||
KEY_DEL,
|
|
||||||
KEY_END,
|
|
||||||
KEY_PGUP,
|
|
||||||
KEY_PGDN,
|
|
||||||
KEY_ARROWUP,
|
|
||||||
KEY_ARROWDN,
|
|
||||||
KEY_ARROWRT,
|
|
||||||
KEY_ARROWLT,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Scancodes for special keys, sorted lexicographically:
|
|
||||||
static const uint8_t key_ctrl_a[] = { CTRL_A };
|
|
||||||
static const uint8_t key_ctrl_b[] = { CTRL_B };
|
|
||||||
static const uint8_t key_ctrl_c[] = { CTRL_C };
|
|
||||||
static const uint8_t key_ctrl_d[] = { CTRL_D };
|
|
||||||
static const uint8_t key_ctrl_e[] = { CTRL_E };
|
|
||||||
static const uint8_t key_ctrl_f[] = { CTRL_F };
|
|
||||||
static const uint8_t key_bksp[] = { BACKSPACE };
|
|
||||||
static const uint8_t key_ctrl_k[] = { CTRL_K };
|
|
||||||
static const uint8_t key_enter[] = { ENTER };
|
|
||||||
static const uint8_t key_ctrl_n[] = { CTRL_N };
|
|
||||||
static const uint8_t key_ctrl_p[] = { CTRL_P };
|
|
||||||
static const uint8_t key_home[] = { ESC, RIGHTBRACKET, '1', TILDA };
|
|
||||||
static const uint8_t key_insert[] = { ESC, RIGHTBRACKET, '2', TILDA };
|
|
||||||
static const uint8_t key_del[] = { ESC, RIGHTBRACKET, '3', TILDA };
|
|
||||||
static const uint8_t key_end_1[] = { ESC, '0', 'F' };
|
|
||||||
static const uint8_t key_end_2[] = { ESC, RIGHTBRACKET, '4', TILDA };
|
|
||||||
static const uint8_t key_pgup[] = { ESC, RIGHTBRACKET, '5', TILDA };
|
|
||||||
static const uint8_t key_pgdn[] = { ESC, RIGHTBRACKET, '6', TILDA };
|
|
||||||
static const uint8_t key_arrowup[] = { ESC, RIGHTBRACKET, 'A' };
|
|
||||||
static const uint8_t key_arrowdn[] = { ESC, RIGHTBRACKET, 'B' };
|
|
||||||
static const uint8_t key_arrowrt[] = { ESC, RIGHTBRACKET, 'C' };
|
|
||||||
static const uint8_t key_arrowlt[] = { ESC, RIGHTBRACKET, 'D' };
|
|
||||||
|
|
||||||
// Table of special keys. We could store this in PROGMEM, but we don't,
|
|
||||||
// because the code to retrieve the data is much larger than the savings.
|
|
||||||
static const struct key {
|
|
||||||
const uint8_t *code;
|
|
||||||
uint8_t len;
|
|
||||||
enum keytype type;
|
|
||||||
}
|
|
||||||
// Table is order sensitive.
|
|
||||||
keys[] = {
|
|
||||||
{ key_ctrl_a, sizeof(key_ctrl_a), KEY_CTRL_A },
|
|
||||||
{ key_ctrl_b, sizeof(key_ctrl_b), KEY_CTRL_B },
|
|
||||||
{ key_ctrl_c, sizeof(key_ctrl_c), KEY_CTRL_C },
|
|
||||||
{ key_ctrl_d, sizeof(key_ctrl_d), KEY_CTRL_D },
|
|
||||||
{ key_ctrl_e, sizeof(key_ctrl_e), KEY_CTRL_E },
|
|
||||||
{ key_ctrl_f, sizeof(key_ctrl_f), KEY_CTRL_F },
|
|
||||||
{ key_bksp, sizeof(key_bksp), KEY_BKSP },
|
|
||||||
{ key_ctrl_k, sizeof(key_ctrl_k), KEY_CTRL_K },
|
|
||||||
{ key_enter, sizeof(key_enter), KEY_ENTER },
|
|
||||||
{ key_ctrl_n, sizeof(key_ctrl_n), KEY_CTRL_N },
|
|
||||||
{ key_ctrl_p, sizeof(key_ctrl_p), KEY_CTRL_P },
|
|
||||||
{ key_home, sizeof(key_home), KEY_HOME },
|
|
||||||
{ key_insert, sizeof(key_insert), KEY_INSERT },
|
|
||||||
{ key_del, sizeof(key_del), KEY_DEL },
|
|
||||||
{ key_end_1, sizeof(key_end_1), KEY_END },
|
|
||||||
{ key_end_2, sizeof(key_end_2), KEY_END },
|
|
||||||
{ key_pgup, sizeof(key_pgup), KEY_PGUP },
|
|
||||||
{ key_pgdn, sizeof(key_pgdn), KEY_PGDN },
|
|
||||||
{ key_arrowup, sizeof(key_arrowup), KEY_ARROWUP },
|
|
||||||
{ key_arrowdn, sizeof(key_arrowdn), KEY_ARROWDN },
|
|
||||||
{ key_arrowrt, sizeof(key_arrowrt), KEY_ARROWRT },
|
|
||||||
{ key_arrowlt, sizeof(key_arrowlt), KEY_ARROWLT },
|
|
||||||
};
|
|
||||||
|
|
||||||
// Local command list.
|
|
||||||
//
|
|
||||||
typedef struct {
|
|
||||||
const char *cmd;
|
|
||||||
uint8_t key;
|
|
||||||
} t_cmdstruct;
|
|
||||||
|
|
||||||
// Table of supported local commands. The table contains the command and the case value to act on for the command.
|
|
||||||
static t_cmdstruct cmdTable[] = {
|
|
||||||
{ "history", CMD_HISTORY },
|
|
||||||
{ "hist", CMD_HISTORY },
|
|
||||||
{ "!", CMD_RECALL },
|
|
||||||
};
|
|
||||||
|
|
||||||
// Define the number of local commands in the array.
|
|
||||||
#define NCMDKEYS (sizeof(cmdTable)/sizeof(t_cmdstruct))
|
|
||||||
|
|
||||||
static bool
|
|
||||||
key_matches (const uint8_t c, const int8_t idx, const int8_t pos)
|
|
||||||
{
|
|
||||||
// If key is too short, skip:
|
|
||||||
if (pos >= keys[idx].len)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// Character must match:
|
|
||||||
return (c == keys[idx].code[pos]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool find_key (const uint8_t c, int8_t *idx, const int8_t pos)
|
|
||||||
{
|
|
||||||
int8_t i;
|
|
||||||
|
|
||||||
// If character matches current index, return:
|
|
||||||
if (c == keys[*idx].code[pos])
|
|
||||||
return true;
|
|
||||||
|
|
||||||
// If character is less than current index, seek up:
|
|
||||||
if (c < keys[*idx].code[pos])
|
|
||||||
{
|
|
||||||
for (i = *idx - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if (key_matches(c, i, pos))
|
|
||||||
{
|
|
||||||
*idx = i;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If character is greater than current index, seek down:
|
|
||||||
else {
|
|
||||||
for (i = *idx + 1; i < sizeof(keys) / sizeof(keys[0]); i++) {
|
|
||||||
if (key_matches(c, i, pos)) {
|
|
||||||
*idx = i;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get next character from serial port.
|
|
||||||
static bool next_char (enum keytype *type, uint8_t *val, void (*fn)())
|
|
||||||
{
|
|
||||||
static int8_t idx, pos;
|
|
||||||
int8_t keyIn;
|
|
||||||
|
|
||||||
// Process all available bytes from the serial port.
|
|
||||||
do {
|
|
||||||
keyIn = getKey(0);
|
|
||||||
if(keyIn != -1)
|
|
||||||
{
|
|
||||||
// Try to find a matching key from the special keys table:
|
|
||||||
if (find_key(keyIn, &idx, pos))
|
|
||||||
{
|
|
||||||
|
|
||||||
// If we are at max length, we're done:
|
|
||||||
if (++pos == keys[idx].len)
|
|
||||||
{
|
|
||||||
*type = keys[idx].type;
|
|
||||||
idx = pos = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, need more input to be certain:
|
|
||||||
continue;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// No matching special key: it's a regular character:
|
|
||||||
idx = pos = 0;
|
|
||||||
*val = keyIn;
|
|
||||||
*type = KEY_REGULAR;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// Calling the idle function whilst no data present.
|
|
||||||
if(fn != NULL)
|
|
||||||
fn();
|
|
||||||
}
|
|
||||||
} while(true);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Short method to scrub previous line contents off screen and replace with new contents.
|
|
||||||
void refreshLine(uint8_t *line, uint8_t llen, uint8_t *lpos)
|
|
||||||
{
|
|
||||||
while (*lpos)
|
|
||||||
{
|
|
||||||
fputc('\b', stdout);
|
|
||||||
fputc(' ', stdout);
|
|
||||||
fputc('\b', stdout);
|
|
||||||
(*lpos)--;
|
|
||||||
}
|
|
||||||
printf((char *)line);
|
|
||||||
*lpos = llen;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Short method to add a command line onto the end of the history list. If the SD Card is enabled, add the command
|
|
||||||
// to the end of the history file as well.
|
|
||||||
//
|
|
||||||
void addToHistory(char *buf, uint8_t bytes, uint8_t addHistFile)
|
|
||||||
{
|
|
||||||
// If the slot in history is already being used, free the memory before allocating a new block suitable to the new line size.
|
|
||||||
if((char *)history[histFreeSlot] != NULL)
|
|
||||||
free((char *)history[histFreeSlot]);
|
|
||||||
history[histFreeSlot] = malloc(bytes+1);
|
|
||||||
printf("History buffer@%08lx\n", history[histFreeSlot]);
|
|
||||||
|
|
||||||
// If malloc was successful, populate the memory with the command entered.
|
|
||||||
if((char *)history[histFreeSlot] != NULL)
|
|
||||||
{
|
|
||||||
// Copy the command into history and update the pointer, wrap around if needed.
|
|
||||||
memcpy((char *)history[histFreeSlot], buf, bytes+1);
|
|
||||||
histFreeSlot++;
|
|
||||||
if(histFreeSlot >= MAX_HISTORY_LINES)
|
|
||||||
histFreeSlot = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add the command to the history file if selected and the SD Card is enabled.
|
|
||||||
//
|
|
||||||
if(addHistFile)
|
|
||||||
{
|
|
||||||
#if defined __SD_CARD__
|
|
||||||
unsigned int writeBytes;
|
|
||||||
|
|
||||||
if(histFp != NULL && histDisabled == 0)
|
|
||||||
{
|
|
||||||
// Write out the line into the history file.
|
|
||||||
f_write(histFp, buf, bytes, &writeBytes);
|
|
||||||
f_putc('\n', histFp);
|
|
||||||
f_sync(histFp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to clear out the history buffer and return used memory back to the heap.
|
|
||||||
//
|
|
||||||
void clearHistory(void)
|
|
||||||
{
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
// Simply loop through and free used memory, reset pointer to the start.
|
|
||||||
//
|
|
||||||
for(idx = 0; idx < MAX_HISTORY_LINES; idx++)
|
|
||||||
{
|
|
||||||
if((char *)history[idx] != NULL)
|
|
||||||
{
|
|
||||||
free((char *)history[idx]);
|
|
||||||
history[idx] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
histFreeSlot = 0;
|
|
||||||
|
|
||||||
// If the history file is being used, close it and free up its memory.
|
|
||||||
#if defined __SD_CARD__
|
|
||||||
if(histFp != NULL)
|
|
||||||
{
|
|
||||||
f_close(histFp);
|
|
||||||
free(histFp);
|
|
||||||
histFp = NULL;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Local command to display the history contents.
|
|
||||||
void cmdPrintHistory(void)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
char buf[120];
|
|
||||||
FRESULT fr;
|
|
||||||
int bytes;
|
|
||||||
uint32_t lineCnt = 1;
|
|
||||||
|
|
||||||
// Rewind the history file to the beginning.
|
|
||||||
//
|
|
||||||
fr = f_lseek(histFp, 0);
|
|
||||||
if(!fr)
|
|
||||||
{
|
|
||||||
// Simply loop from start to end adding to buffer, if the file history is larger than the memory buffer we just loop round.
|
|
||||||
do {
|
|
||||||
bytes = -1;
|
|
||||||
if(f_gets(buf, sizeof(buf), histFp) != NULL)
|
|
||||||
{
|
|
||||||
// Get number of bytes read.
|
|
||||||
bytes = strlen(buf);
|
|
||||||
if(bytes > 0)
|
|
||||||
{
|
|
||||||
// Remove the CR/newline terminator.
|
|
||||||
bytes -= 1;
|
|
||||||
buf[bytes] = 0x0;
|
|
||||||
|
|
||||||
// Print it out.
|
|
||||||
printf("%06lu %s\n", lineCnt++, buf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while(bytes != -1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Local command to load a specific command into the line buffer.
|
|
||||||
uint8_t cmdRecallHistory(uint8_t *line, uint8_t *llen, uint32_t lineNo)
|
|
||||||
{
|
|
||||||
// Locals.
|
|
||||||
char buf[120];
|
|
||||||
FRESULT fr;
|
|
||||||
int bytes;
|
|
||||||
uint32_t lineCnt = 1;
|
|
||||||
uint8_t retCode = 1;
|
|
||||||
|
|
||||||
// Rewind the history file to the beginning.
|
|
||||||
//
|
|
||||||
fr = f_lseek(histFp, 0);
|
|
||||||
if(!fr)
|
|
||||||
{
|
|
||||||
// Simply loop from start to end until we reach the required line, load it into the line buffer and forward to the end of file.
|
|
||||||
do {
|
|
||||||
bytes = -1;
|
|
||||||
if(f_gets(buf, sizeof(buf), histFp) != NULL)
|
|
||||||
{
|
|
||||||
// Get number of bytes read.
|
|
||||||
bytes = strlen(buf);
|
|
||||||
lineCnt++;
|
|
||||||
if(bytes > 0)
|
|
||||||
{
|
|
||||||
// Remove the CR/newline terminator.
|
|
||||||
buf[--bytes] = 0x0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while(bytes != -1 && lineNo != lineCnt);
|
|
||||||
|
|
||||||
// Go to end of file.
|
|
||||||
fr = f_lseek(histFp, f_size(histFp));
|
|
||||||
if(fr)
|
|
||||||
{
|
|
||||||
printf("Failed to reset the history file to EOF.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if(lineNo == lineCnt)
|
|
||||||
{
|
|
||||||
strcpy((char *)line, buf);
|
|
||||||
*llen = strlen((char *)line);
|
|
||||||
printf(">%s\n", buf);
|
|
||||||
retCode = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(retCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Check to see if the given command is local and process as necessary.
|
|
||||||
//
|
|
||||||
uint8_t localCommand(uint8_t *line, uint8_t *lineSize)
|
|
||||||
{
|
|
||||||
uint8_t idx;
|
|
||||||
char *paramptr = (char *)line;
|
|
||||||
long lineNo;
|
|
||||||
|
|
||||||
// Skip leading whitespace.
|
|
||||||
while(*paramptr == ' ' && paramptr < (char *)line + *lineSize) paramptr++;
|
|
||||||
|
|
||||||
// Loop through all the commands and try to find a match.
|
|
||||||
for (idx=0; idx < NCMDKEYS; idx++)
|
|
||||||
{
|
|
||||||
t_cmdstruct *sym = &cmdTable[idx];
|
|
||||||
if (strncmp(sym->cmd, paramptr,strlen(sym->cmd)) == 0)
|
|
||||||
{
|
|
||||||
// Process the command
|
|
||||||
switch(sym->key)
|
|
||||||
{
|
|
||||||
// Print out the history buffer.
|
|
||||||
//
|
|
||||||
case CMD_HISTORY:
|
|
||||||
cmdPrintHistory();
|
|
||||||
return(1);
|
|
||||||
|
|
||||||
// Recall a command from the history buffer.
|
|
||||||
//
|
|
||||||
case CMD_RECALL:
|
|
||||||
paramptr++;
|
|
||||||
if(xatoi(¶mptr, &lineNo))
|
|
||||||
{
|
|
||||||
if(cmdRecallHistory(line, lineSize, lineNo-1) == 0)
|
|
||||||
{
|
|
||||||
// Return no local command result as we want the caller to process the newly filled line buffer.
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// This case shouldnt exist as a handler for each command should exist.
|
|
||||||
// If this case is triggered then fall through as though there was no command.
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Not a local command.
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Take characters from the Rx FIFO and create a line
|
|
||||||
uint8_t *readline (uint8_t *line, int lineSize, int disableHistSave, const char *histFile, void (*fn)())
|
|
||||||
{
|
|
||||||
enum keytype type;
|
|
||||||
uint8_t val = 0;
|
|
||||||
int8_t i;
|
|
||||||
uint8_t histPnt = histFreeSlot;
|
|
||||||
|
|
||||||
#if defined __SD_CARD__
|
|
||||||
char buf[120];
|
|
||||||
FRESULT fr;
|
|
||||||
int bytes;
|
|
||||||
|
|
||||||
// Update the history save to disk feature.
|
|
||||||
histDisabled = disableHistSave;
|
|
||||||
|
|
||||||
// If we havent opened the history file and read the contents AND file based history hasnt been disabled, open the history file and read
|
|
||||||
// the contents.
|
|
||||||
if(histFp == NULL && histDisabled == 0 && histFile != NULL)
|
|
||||||
{
|
|
||||||
// Allocate a file control block on the heap and open the history file.
|
|
||||||
histFp = malloc(sizeof(FIL));
|
|
||||||
printf("History heap:%08lx\n", histFp);
|
|
||||||
if(histFp != NULL)
|
|
||||||
{
|
|
||||||
fr = f_open(histFp, histFile, FA_OPEN_ALWAYS | FA_WRITE | FA_READ);
|
|
||||||
if(fr != FR_OK)
|
|
||||||
{
|
|
||||||
printf("Cannot open/create history file, disabling.\n");
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// Simply loop from start to end adding to buffer, if the file history is larger than the memory buffer we just loop round.
|
|
||||||
histPnt = 0;
|
|
||||||
do {
|
|
||||||
bytes = -1;
|
|
||||||
if(f_gets(buf, sizeof(buf), histFp) == buf)
|
|
||||||
{
|
|
||||||
// Get number of bytes read.
|
|
||||||
bytes = strlen(buf);
|
|
||||||
if(bytes > 0)
|
|
||||||
{
|
|
||||||
// Remove the CR/newline terminator.
|
|
||||||
bytes -= 1;
|
|
||||||
buf[bytes] = 0x0;
|
|
||||||
|
|
||||||
// Add the line into our history list.
|
|
||||||
addToHistory(buf, bytes, false);
|
|
||||||
|
|
||||||
// Update the pointer, if it overflows, wrap around.
|
|
||||||
if(++histPnt >= MAX_HISTORY_LINES)
|
|
||||||
histPnt = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} while(bytes != -1);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
histDisabled = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// If the history filename hasnt been provided and it was previously being used, this is a signal to close and stop using history, free it up.
|
|
||||||
//
|
|
||||||
if(histFile == NULL && histFp != NULL)
|
|
||||||
{
|
|
||||||
clearHistory();
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
while (next_char(&type, &val, fn))
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case KEY_REGULAR:
|
|
||||||
// Refuse insert if we are at the end of the line:
|
|
||||||
if (lpos == lineSize)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// If there is string to the right, move it over one place:
|
|
||||||
if (llen > lpos)
|
|
||||||
for (i = llen; i >= lpos; i--)
|
|
||||||
line[i + 1] = line[i];
|
|
||||||
|
|
||||||
// Insert character:
|
|
||||||
line[lpos++] = val;
|
|
||||||
|
|
||||||
// Increase line length, if possible:
|
|
||||||
if (llen < lineSize)
|
|
||||||
llen++;
|
|
||||||
|
|
||||||
// Paint new string:
|
|
||||||
for (i = lpos - 1; i < llen; i++)
|
|
||||||
fputc(line[i], stdout);
|
|
||||||
|
|
||||||
// Backtrack to current position:
|
|
||||||
for (i = lpos; i < llen; i++)
|
|
||||||
fputc('\b', stdout);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_CTRL_C:
|
|
||||||
// Ctrl-c means abort current line, return CTRL_C in the first character of the buffer.
|
|
||||||
line[0] = CTRL_C;
|
|
||||||
line[1] = '\0';
|
|
||||||
refreshLine((uint8_t *)"", 0, &lpos);
|
|
||||||
llen = lpos = 0;
|
|
||||||
return line;
|
|
||||||
|
|
||||||
case KEY_CTRL_D:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_BKSP:
|
|
||||||
// Nothing to do if we are at the start of the line:
|
|
||||||
if (lpos == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Line becomes one character shorter:
|
|
||||||
llen--;
|
|
||||||
lpos--;
|
|
||||||
|
|
||||||
fputc('\b', stdout);
|
|
||||||
|
|
||||||
// Move characters one over to the left:
|
|
||||||
for (i = lpos; i < llen; i++) {
|
|
||||||
line[i] = line[i + 1];
|
|
||||||
fputc(line[i], stdout);
|
|
||||||
}
|
|
||||||
fputc(' ', stdout);
|
|
||||||
|
|
||||||
// Backtrack to current position:
|
|
||||||
for (i = lpos; i <= llen; i++)
|
|
||||||
fputc('\b', stdout);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_ENTER:
|
|
||||||
// Null-terminate the line and return pointer:
|
|
||||||
line[llen] = '\0';
|
|
||||||
fputc('\n', stdout);
|
|
||||||
|
|
||||||
// See if this is a local readline command, if so process otherwise return buffer to caller.
|
|
||||||
if(localCommand(line, &llen) == 0)
|
|
||||||
{
|
|
||||||
// If a command is entered, add to history.
|
|
||||||
if(llen > 0)
|
|
||||||
{
|
|
||||||
// Add the line into our history list.
|
|
||||||
addToHistory((char *)line, llen, true);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// Return an empty buffer so caller can make any necessary updates.
|
|
||||||
line[0] = '\0';
|
|
||||||
}
|
|
||||||
llen = lpos = 0;
|
|
||||||
return line;
|
|
||||||
|
|
||||||
case KEY_CTRL_A:
|
|
||||||
case KEY_HOME:
|
|
||||||
while (lpos) {
|
|
||||||
fputc('\b', stdout);
|
|
||||||
lpos--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_DEL:
|
|
||||||
// Nothing to do if we are at the end of the line:
|
|
||||||
if (lpos == llen)
|
|
||||||
break;
|
|
||||||
|
|
||||||
llen--;
|
|
||||||
|
|
||||||
// Move characters one over to the left:
|
|
||||||
for (i = lpos; i < llen; i++) {
|
|
||||||
line[i] = line[i + 1];
|
|
||||||
fputc(line[i], stdout);
|
|
||||||
}
|
|
||||||
fputc(' ', stdout);
|
|
||||||
|
|
||||||
// Backtrack to current position:
|
|
||||||
for (i = lpos; i <= llen; i++)
|
|
||||||
fputc('\b', stdout);
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_INSERT:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_CTRL_E:
|
|
||||||
case KEY_END:
|
|
||||||
while (lpos < llen)
|
|
||||||
fputc(line[lpos++], stdout);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_PGUP:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_PGDN:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_CTRL_K:
|
|
||||||
// Clear the buffer.
|
|
||||||
refreshLine((uint8_t *)"", 0, &lpos);
|
|
||||||
llen = lpos = 0;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_CTRL_P:
|
|
||||||
case KEY_ARROWUP:
|
|
||||||
// Go to the previous history buffer.
|
|
||||||
if(histPnt == 0 && (char *)history[MAX_HISTORY_LINES-1] != NULL)
|
|
||||||
{
|
|
||||||
llen = strlen((char *)history[MAX_HISTORY_LINES-1]);
|
|
||||||
memcpy(line, (char *)history[MAX_HISTORY_LINES-1], llen+1);
|
|
||||||
histPnt = MAX_HISTORY_LINES-1;
|
|
||||||
refreshLine(line, llen, &lpos);
|
|
||||||
} else
|
|
||||||
if(histPnt > 0 && histPnt < MAX_HISTORY_LINES && (char *)history[histPnt-1] != NULL)
|
|
||||||
{
|
|
||||||
llen = strlen((char *)history[histPnt-1]);
|
|
||||||
memcpy(line, (char *)history[histPnt-1], llen+1);
|
|
||||||
histPnt--;
|
|
||||||
refreshLine(line, llen, &lpos);
|
|
||||||
} else
|
|
||||||
if(histPnt >=0 && histPnt < MAX_HISTORY_LINES && (char *)history[histPnt] != NULL)
|
|
||||||
{
|
|
||||||
llen = strlen((char *)history[histPnt]);
|
|
||||||
memcpy(line, (char *)history[histPnt], llen+1);
|
|
||||||
refreshLine(line, llen, &lpos);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_CTRL_N:
|
|
||||||
case KEY_ARROWDN:
|
|
||||||
// Go to the next history buffer.
|
|
||||||
if(histPnt == MAX_HISTORY_LINES-1 && (char *)history[0] != NULL)
|
|
||||||
{
|
|
||||||
llen = strlen((char *)history[0]);
|
|
||||||
memcpy(line, (char *)history[0], llen+1);
|
|
||||||
histPnt = MAX_HISTORY_LINES-1;
|
|
||||||
refreshLine(line, llen, &lpos);
|
|
||||||
} else
|
|
||||||
if(histPnt < MAX_HISTORY_LINES-1 && (char *)history[histPnt+1] != NULL)
|
|
||||||
{
|
|
||||||
llen = strlen((char *)history[histPnt+1]);
|
|
||||||
memcpy(line, (char *)history[histPnt+1], llen+1);
|
|
||||||
histPnt++;
|
|
||||||
refreshLine(line, llen, &lpos);
|
|
||||||
} else
|
|
||||||
// if(history[histPnt] != NULL)
|
|
||||||
{
|
|
||||||
llen = 0; //strlen((char *)history[histPnt]);
|
|
||||||
line[0] = '\0';
|
|
||||||
//memcpy(line, history[histPnt], llen+1);
|
|
||||||
refreshLine(line, llen, &lpos);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_CTRL_F:
|
|
||||||
case KEY_ARROWRT:
|
|
||||||
if (lpos < llen)
|
|
||||||
fputc(line[lpos++], stdout);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case KEY_CTRL_B:
|
|
||||||
case KEY_ARROWLT:
|
|
||||||
if (lpos == 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
fputc('\b', stdout);
|
|
||||||
lpos--;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
line[0] = 0x00;
|
|
||||||
return(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
5945
zOS/MZ2000/common/savme
vendored
5945
zOS/MZ2000/common/savme
vendored
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,168 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: simple_utils.c
|
|
||||||
// Created: January 2019
|
|
||||||
// Author(s): Philip Smart
|
|
||||||
// Description: ZPU boottime simple utilities.
|
|
||||||
// A set of utilities to be used in the IOCP (or other minimalist application) which
|
|
||||||
// assume a minimum compile environment (ie. no printf)such that the smallest code
|
|
||||||
// size is created.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2019 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: January 2019 - Initial script written.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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 "zpu-types.h"
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
#include "uart.h"
|
|
||||||
|
|
||||||
// Functions, in the absense of printf, to output a value as hex.
|
|
||||||
// Nibble :- a single digit 0-f
|
|
||||||
void printnibble(uint8_t c)
|
|
||||||
{
|
|
||||||
c&=0xf;
|
|
||||||
if (c>9)
|
|
||||||
putchar(c+'a'-10);
|
|
||||||
else
|
|
||||||
putchar(c+'0');
|
|
||||||
}
|
|
||||||
// Byte: 8 bits represented by 2 digits, <0-f><0-f>
|
|
||||||
void printhexbyte(uint8_t c)
|
|
||||||
{
|
|
||||||
printnibble(c>>4);
|
|
||||||
printnibble(c);
|
|
||||||
}
|
|
||||||
// Half Word: 16 bits represented by 4 digits.
|
|
||||||
void printhex(uint32_t c)
|
|
||||||
{
|
|
||||||
printhexbyte((uint8_t)(c>>8));
|
|
||||||
printhexbyte((uint8_t)(c));
|
|
||||||
}
|
|
||||||
// Word: 32 bits represented by 8 digits.
|
|
||||||
void printdhex(uint32_t c)
|
|
||||||
{
|
|
||||||
printhexbyte((uint8_t)(c>>24));
|
|
||||||
printhexbyte((uint8_t)(c>>16));
|
|
||||||
printhexbyte((uint8_t)(c>>8));
|
|
||||||
printhexbyte((uint8_t)(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Function to dump out a given section of memory via the currently selected UART.
|
|
||||||
//
|
|
||||||
#if !defined(FUNCTIONALITY) || FUNCTIONALITY <= 1
|
|
||||||
int memoryDump(uint32_t memaddr, uint32_t memsize)
|
|
||||||
{
|
|
||||||
uint32_t pnt = memaddr;
|
|
||||||
uint32_t i = 0;
|
|
||||||
uint32_t data;
|
|
||||||
char c = 0;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
printdhex(pnt); // print address
|
|
||||||
puts(": ");
|
|
||||||
|
|
||||||
// print hexadecimal data
|
|
||||||
for (i=0; i < 32; i++) {
|
|
||||||
printhexbyte(*(uint8_t *)(pnt+i));
|
|
||||||
putchar((char)' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
// print ascii data
|
|
||||||
puts(" |");
|
|
||||||
|
|
||||||
// print single ascii char
|
|
||||||
for (i=0; i < 32; i++) {
|
|
||||||
c = (char)*(uint8_t *)(pnt+i);
|
|
||||||
if ((c >= ' ') && (c <= '~'))
|
|
||||||
putchar((char)c);
|
|
||||||
else
|
|
||||||
putchar((char)' ');
|
|
||||||
}
|
|
||||||
|
|
||||||
puts("|\n");
|
|
||||||
|
|
||||||
// Move on one row.
|
|
||||||
pnt += 16;
|
|
||||||
|
|
||||||
// user abort or all done?
|
|
||||||
if ((getserial_nonblocking() != -1) || (pnt >= (memaddr + memsize)))
|
|
||||||
{
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// Normal exit, return -1 to show no key pressed.
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Function to setup the CRC polynomial table prior to use.
|
|
||||||
//
|
|
||||||
#if !defined(FUNCTIONALITY) || FUNCTIONALITY == 0
|
|
||||||
static unsigned int crc32table[256];
|
|
||||||
unsigned int crc32_init(void)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
unsigned int byte, crc, mask;
|
|
||||||
|
|
||||||
for(byte = 0; byte <= 255; byte++)
|
|
||||||
{
|
|
||||||
crc = byte;
|
|
||||||
for (j = 7; j >= 0; j--)
|
|
||||||
{
|
|
||||||
mask = -(crc & 1);
|
|
||||||
crc = (crc >> 1) ^ (0xEDB88320 & mask);
|
|
||||||
}
|
|
||||||
crc32table[byte] = crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Starting value for CRC calculation.
|
|
||||||
//
|
|
||||||
return 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to add a word into the CRC sum.
|
|
||||||
//
|
|
||||||
unsigned int crc32_addword(unsigned int crc_in, unsigned int word)
|
|
||||||
{
|
|
||||||
crc_in = (crc_in >> 8) ^ crc32table[(crc_in ^ ((word >> 24)&0xFF)) & 0xFF];
|
|
||||||
crc_in = (crc_in >> 8) ^ crc32table[(crc_in ^ ((word >> 16)&0xFF)) & 0xFF];
|
|
||||||
crc_in = (crc_in >> 8) ^ crc32table[(crc_in ^ ((word >> 8)&0xFF)) & 0xFF];
|
|
||||||
crc_in = (crc_in >> 8) ^ crc32table[(crc_in ^ (word &0xFF)) & 0xFF];
|
|
||||||
|
|
||||||
return crc_in;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to read a 32bit word from the active serial port.
|
|
||||||
//
|
|
||||||
unsigned int get_dword(void)
|
|
||||||
{
|
|
||||||
unsigned int temp = 0;
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
for(idx=0; idx < 4; idx++)
|
|
||||||
{
|
|
||||||
temp = (temp << 8) | (unsigned int)getserial();
|
|
||||||
}
|
|
||||||
|
|
||||||
return(temp);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,459 +0,0 @@
|
|||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "syscalls.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include "fileio.h"
|
|
||||||
|
|
||||||
#define SYS_ftruncate 3000
|
|
||||||
#define SYS_isatty 3001
|
|
||||||
|
|
||||||
#define outbyte putchar
|
|
||||||
#define inbyte getserial
|
|
||||||
|
|
||||||
/* Set to 1 if we are running on hardware. The config instruction is
|
|
||||||
* always emulated on the simulator. The emulation code pokes this
|
|
||||||
* variable to 1.
|
|
||||||
*/
|
|
||||||
extern int _hardware;
|
|
||||||
|
|
||||||
/* _cpu_config==0 => Abel
|
|
||||||
* _cpu_config==1 => Zeta
|
|
||||||
* _cpu_config==2 => Phi
|
|
||||||
*/
|
|
||||||
extern int _cpu_config;
|
|
||||||
|
|
||||||
int _use_syscall;
|
|
||||||
|
|
||||||
extern char _end; // Defined by the linker script
|
|
||||||
extern char *heap_ptr;
|
|
||||||
extern int __bss_start__;
|
|
||||||
extern int __bss_end__;
|
|
||||||
extern int __ctors_start__;
|
|
||||||
extern int __ctors_end__;
|
|
||||||
extern int __dtors_start__;
|
|
||||||
extern int __dtors_end__;
|
|
||||||
|
|
||||||
extern int _syscall(int *foo, int ID, ...);
|
|
||||||
|
|
||||||
extern int main(int argc, char **argv);
|
|
||||||
|
|
||||||
static char *args[]={"dummy.exe"};
|
|
||||||
|
|
||||||
extern void _init(void);
|
|
||||||
void _initIO(void);
|
|
||||||
void _break();
|
|
||||||
|
|
||||||
void __attribute__ ((weak)) _premain()
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int *ctors;
|
|
||||||
char *ramtop;
|
|
||||||
|
|
||||||
/* we only use syscalls w/Zeta */
|
|
||||||
_use_syscall=(_cpu_config==1);
|
|
||||||
|
|
||||||
// Clear BSS data
|
|
||||||
int *bss=&__bss_start__;
|
|
||||||
while(bss<&__bss_end__)
|
|
||||||
*bss++=0;
|
|
||||||
|
|
||||||
ramtop=(char *)addresscheck((volatile int *)&_end,0);
|
|
||||||
malloc_add(&_end,ramtop-&_end); // Add the entire RAM to the free memory pool
|
|
||||||
|
|
||||||
// Run global constructors...
|
|
||||||
ctors=&__ctors_start__;
|
|
||||||
while(ctors<&__ctors_end__)
|
|
||||||
{
|
|
||||||
printf(".");
|
|
||||||
void (*fp)();
|
|
||||||
fp=(void (*)())(*ctors);
|
|
||||||
fp();
|
|
||||||
++ctors;
|
|
||||||
}
|
|
||||||
t=main(1, args);
|
|
||||||
|
|
||||||
// Run global destructors...
|
|
||||||
ctors=&__dtors_start__;
|
|
||||||
while(ctors<&__dtors_end__)
|
|
||||||
{
|
|
||||||
void (*fp)();
|
|
||||||
fp=(void (*)())(*ctors);
|
|
||||||
fp();
|
|
||||||
++ctors;
|
|
||||||
}
|
|
||||||
_exit(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* NOTE!!!! compiled with -fomit-frame-pointer to make sure that 'status' has the
|
|
||||||
* correct value when breakpointing at _exit
|
|
||||||
*/
|
|
||||||
void __attribute__ ((weak)) _exit (int status)
|
|
||||||
{
|
|
||||||
/* end of the universe, cause memory fault */
|
|
||||||
__asm("breakpoint");
|
|
||||||
for (;;);
|
|
||||||
_break;
|
|
||||||
}
|
|
||||||
|
|
||||||
void __attribute__ ((weak)) _zpu_interrupt(void)
|
|
||||||
{
|
|
||||||
/* not implemented in libgloss */
|
|
||||||
__asm("breakpoint");
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (write, (fd, buf, nbytes),
|
|
||||||
int fd _AND
|
|
||||||
char *buf _AND
|
|
||||||
int nbytes)
|
|
||||||
{
|
|
||||||
if (_use_syscall)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int result;
|
|
||||||
result=_syscall(&t, SYS_write, fd, buf, nbytes);
|
|
||||||
errno=t;
|
|
||||||
return result;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < nbytes; i++) {
|
|
||||||
if (*(buf + i) == '\n') {
|
|
||||||
outbyte ('\r');
|
|
||||||
}
|
|
||||||
outbyte (*(buf + i));
|
|
||||||
}
|
|
||||||
return (nbytes);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* read -- read bytes from the serial port. Ignore fd, since
|
|
||||||
* we only have stdin.
|
|
||||||
*/
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (read, (fd, buf, nbytes),
|
|
||||||
int fd _AND
|
|
||||||
char *buf _AND
|
|
||||||
int nbytes)
|
|
||||||
{
|
|
||||||
if (_use_syscall)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int result;
|
|
||||||
result=_syscall(&t, SYS_read, fd, buf, nbytes);
|
|
||||||
errno=t;
|
|
||||||
return result;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < nbytes; i++) {
|
|
||||||
char t=inbyte();
|
|
||||||
|
|
||||||
if ((t!='\r')&&(t!='\n'))
|
|
||||||
{
|
|
||||||
*(buf + i) = t;
|
|
||||||
outbyte(t); // echo
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// terminate the line in the way expected by the libraries
|
|
||||||
*(buf + i) = '\n';
|
|
||||||
i++;
|
|
||||||
outbyte('\r');
|
|
||||||
outbyte('\n');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return (i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* open -- open a file descriptor. We don't have a filesystem, so
|
|
||||||
* we return an error.
|
|
||||||
*/
|
|
||||||
int __attribute__ ((weak)) open(const char *buf,
|
|
||||||
int flags,
|
|
||||||
int mode,
|
|
||||||
...)
|
|
||||||
{
|
|
||||||
if (_use_syscall)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int result;
|
|
||||||
result=_syscall(&t, SYS_open, buf, strlen(buf)+1, flags, mode);
|
|
||||||
errno=t;
|
|
||||||
return result;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
errno = EIO;
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* close -- We don't need to do anything, but pretend we did.
|
|
||||||
*/
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (close ,(fd),
|
|
||||||
int fd)
|
|
||||||
{
|
|
||||||
if (_use_syscall)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int result;
|
|
||||||
result=_syscall(&t, SYS_close, fd);
|
|
||||||
errno=t;
|
|
||||||
return result;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
ftruncate (int file, off_t length)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if (_use_syscall)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int result;
|
|
||||||
result=_syscall(&t, SYS_ftruncate, file, length);
|
|
||||||
errno=t;
|
|
||||||
return result;
|
|
||||||
} else
|
|
||||||
*/
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* unlink -- since we have no file system,
|
|
||||||
* we just return an error.
|
|
||||||
*/
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (unlink, (path),
|
|
||||||
char * path)
|
|
||||||
{
|
|
||||||
if (_use_syscall)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int result;
|
|
||||||
result=_syscall(&t, SYS_unlink, path, strlen(path)+1);
|
|
||||||
errno=t;
|
|
||||||
return result;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
errno = EIO;
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* lseek -- Since a serial port is non-seekable, we return an error.
|
|
||||||
*/
|
|
||||||
off_t __attribute__ ((weak))
|
|
||||||
_DEFUN (lseek, (fd, offset, whence),
|
|
||||||
int fd _AND
|
|
||||||
off_t offset _AND
|
|
||||||
int whence)
|
|
||||||
{
|
|
||||||
if (_use_syscall)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int result;
|
|
||||||
result=_syscall(&t, SYS_lseek, fd, offset, whence);
|
|
||||||
errno=t;
|
|
||||||
return result;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
errno = ESPIPE;
|
|
||||||
return ((off_t)-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* we convert from bigendian to smallendian*/
|
|
||||||
static long conv(char *a, int len)
|
|
||||||
{
|
|
||||||
long t=0;
|
|
||||||
int i;
|
|
||||||
for (i=0; i<len; i++)
|
|
||||||
{
|
|
||||||
t|=(((int)a[i])&0xff)<<((len-1-i)*8);
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void convert(struct fio_stat *gdb_stat, struct stat *buf)
|
|
||||||
{
|
|
||||||
memset(buf, 0, sizeof(*buf));
|
|
||||||
buf->st_dev=conv(gdb_stat->fst_dev, sizeof(gdb_stat->fst_dev));
|
|
||||||
buf->st_ino=conv(gdb_stat->fst_ino, sizeof(gdb_stat->fst_ino));
|
|
||||||
buf->st_mode=conv(gdb_stat->fst_mode, sizeof(gdb_stat->fst_mode));
|
|
||||||
buf->st_nlink=conv(gdb_stat->fst_nlink, sizeof(gdb_stat->fst_nlink));
|
|
||||||
buf->st_uid=conv(gdb_stat->fst_uid, sizeof(gdb_stat->fst_uid));
|
|
||||||
buf->st_gid=conv(gdb_stat->fst_gid, sizeof(gdb_stat->fst_gid));
|
|
||||||
buf->st_rdev=conv(gdb_stat->fst_rdev, sizeof(gdb_stat->fst_rdev));
|
|
||||||
buf->st_size=conv(gdb_stat->fst_size, sizeof(gdb_stat->fst_size));
|
|
||||||
#if 0
|
|
||||||
conv_64(fio_ulong_t, &gdb_stat->fst_blksize);
|
|
||||||
conv_64(fio_ulong_t, &gdb_stat->fst_blocks);
|
|
||||||
#endif
|
|
||||||
#if 0
|
|
||||||
conv_time(fst_atime;
|
|
||||||
conv_time(fst_mtime;
|
|
||||||
conv_time(fst_ctime;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (fstat, (fd, buf),
|
|
||||||
int fd _AND
|
|
||||||
struct stat *buf)
|
|
||||||
{
|
|
||||||
if (_use_syscall)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int result;
|
|
||||||
struct fio_stat gdb_stat;
|
|
||||||
result=_syscall(&t, SYS_fstat, fd, &gdb_stat);
|
|
||||||
convert(&gdb_stat, buf);
|
|
||||||
errno=t;
|
|
||||||
return result;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* fstat -- Since we have no file system, we just return an error.
|
|
||||||
*/
|
|
||||||
buf->st_mode = S_IFCHR; /* Always pretend to be a tty */
|
|
||||||
buf->st_blksize = 0;
|
|
||||||
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (stat, (path, buf),
|
|
||||||
const char *path _AND
|
|
||||||
struct stat *buf)
|
|
||||||
{
|
|
||||||
if (_use_syscall)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int result;
|
|
||||||
struct fio_stat gdb_stat;
|
|
||||||
result=_syscall(&t, SYS_stat, path, strlen(path)+1, &gdb_stat);
|
|
||||||
convert(&gdb_stat, buf);
|
|
||||||
errno=t;
|
|
||||||
return result;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
errno = EIO;
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (isatty, (fd),
|
|
||||||
int fd)
|
|
||||||
{
|
|
||||||
if (_use_syscall)
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int result;
|
|
||||||
result=_syscall(&t, SYS_isatty, fd);
|
|
||||||
errno=t;
|
|
||||||
return result;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* isatty -- returns 1 if connected to a terminal device,
|
|
||||||
* returns 0 if not. Since we're hooked up to a
|
|
||||||
* serial port, we'll say yes _AND return a 1.
|
|
||||||
*/
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extern unsigned long _stext;
|
|
||||||
extern unsigned long _etext;
|
|
||||||
extern unsigned long _sdata;
|
|
||||||
extern unsigned long _edata;
|
|
||||||
extern unsigned long _sbss;
|
|
||||||
extern unsigned long _ebss;
|
|
||||||
extern unsigned long _estack;
|
|
||||||
|
|
||||||
#ifndef STACK_MARGIN
|
|
||||||
#define STACK_MARGIN 8192
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//char *__brkval = (char *)&_ebss;
|
|
||||||
//
|
|
||||||
//void * _sbrk(int incr)
|
|
||||||
//{
|
|
||||||
// char *prev, *stack;
|
|
||||||
//
|
|
||||||
// prev = __brkval;
|
|
||||||
// if (incr != 0) {
|
|
||||||
// #if defined __K64F__
|
|
||||||
// __asm__ volatile("mov %0, sp" : "=r" (stack) ::);
|
|
||||||
// #endif
|
|
||||||
// if (prev + incr >= stack - STACK_MARGIN) {
|
|
||||||
//// errno = ENOMEM;
|
|
||||||
// return (void *)-1;
|
|
||||||
// }
|
|
||||||
// __brkval = prev + incr;
|
|
||||||
// }
|
|
||||||
// return prev;
|
|
||||||
//}
|
|
||||||
|
|
||||||
extern char __HeapBase; /**< Defined by the linker */
|
|
||||||
extern char __HeapLimit; /**< Defined by the linker */
|
|
||||||
void * _sbrk(int incr)
|
|
||||||
{
|
|
||||||
static char *heap_end;
|
|
||||||
char *prev_heap_end;
|
|
||||||
|
|
||||||
if (heap_end == 0)
|
|
||||||
{
|
|
||||||
heap_end = &__HeapBase;
|
|
||||||
}
|
|
||||||
|
|
||||||
prev_heap_end = heap_end;
|
|
||||||
if ((heap_end + incr) > (char*) &__HeapLimit)
|
|
||||||
{
|
|
||||||
//errno = ENOMEM;
|
|
||||||
return ((void*)-1); // error - no more memory
|
|
||||||
}
|
|
||||||
heap_end += incr;
|
|
||||||
return prev_heap_end;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
523
zOS/MZ2000/common/syscalls.c.old
vendored
523
zOS/MZ2000/common/syscalls.c.old
vendored
@@ -1,523 +0,0 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
|
|
||||||
#include "zpu-types.h"
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
//#include "uart.h"
|
|
||||||
#include "spi.h"
|
|
||||||
#include "fat.h"
|
|
||||||
#include "rafile.h"
|
|
||||||
|
|
||||||
|
|
||||||
#include "malloc.h"
|
|
||||||
#include "fileio.h"
|
|
||||||
|
|
||||||
#include "xprintf.h"
|
|
||||||
//#include "small_printf.h"
|
|
||||||
|
|
||||||
#define DISABLE_FILESYSTEM 1
|
|
||||||
#define SYS_ftruncate 3000
|
|
||||||
#define SYS_isatty 3001
|
|
||||||
|
|
||||||
/* Set to 1 if we are running on hardware. The config instruction is
|
|
||||||
* always emulated on the simulator. The emulation code pokes this
|
|
||||||
* variable to 1.
|
|
||||||
*/
|
|
||||||
extern int _hardware;
|
|
||||||
|
|
||||||
/* _cpu_config==0 => Abel
|
|
||||||
* _cpu_config==1 => Zeta
|
|
||||||
* _cpu_config==2 => Phi
|
|
||||||
*/
|
|
||||||
extern int _cpu_config;
|
|
||||||
|
|
||||||
extern int main(int argc, char **argv);
|
|
||||||
|
|
||||||
static char *args[]={"dummy.exe"};
|
|
||||||
|
|
||||||
// File table
|
|
||||||
|
|
||||||
#define MAX_FILES 8
|
|
||||||
static RAFile *Files[MAX_FILES];
|
|
||||||
#define File(x) Files[(x)-2]
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// FIXME - bring these in.
|
|
||||||
extern void _init(void);
|
|
||||||
|
|
||||||
// Hardware initialisation
|
|
||||||
// Sets up RS232 baud rate and attempts to initialise the SD card, if present.
|
|
||||||
|
|
||||||
static int sdcard_present;
|
|
||||||
uint32_t sdcard_id;
|
|
||||||
static int filesystem_present;
|
|
||||||
|
|
||||||
static int _init_sd()
|
|
||||||
{
|
|
||||||
filesystem_present=0;
|
|
||||||
#ifdef DISABLE_FILESYSTEM
|
|
||||||
xprintf("Filesystem disabled\n");
|
|
||||||
#else
|
|
||||||
|
|
||||||
if(spi_init(SPI0))
|
|
||||||
{
|
|
||||||
sdcard_present = 1;
|
|
||||||
sdcard_id = SPI0;
|
|
||||||
}
|
|
||||||
else if(spi_init(SPI1))
|
|
||||||
{
|
|
||||||
sdcard_present = 1;
|
|
||||||
sdcard_id = SPI1;
|
|
||||||
}
|
|
||||||
else if(spi_init(SPI2))
|
|
||||||
{
|
|
||||||
sdcard_present = 1;
|
|
||||||
sdcard_id = SPI2;
|
|
||||||
}
|
|
||||||
else if(spi_init(SPI3))
|
|
||||||
{
|
|
||||||
sdcard_present = 1;
|
|
||||||
sdcard_id = SPI3;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
xprintf("No SD card found\n");
|
|
||||||
|
|
||||||
if(sdcard_present)
|
|
||||||
{
|
|
||||||
xprintf("SD card %d successfully initialised\n", sdcard_id);
|
|
||||||
filesystem_present=FindDrive();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return(filesystem_present);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void _initIO(void)
|
|
||||||
{
|
|
||||||
// HW_PER(PER_UART_CLKDIV)=1250000/1152;
|
|
||||||
_init_sd();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
extern char _end; // Defined by the linker script
|
|
||||||
extern char *heap_ptr;
|
|
||||||
int _stack;
|
|
||||||
|
|
||||||
extern int __bss_start__;
|
|
||||||
extern int __bss_end__;
|
|
||||||
extern int __ctors_start__;
|
|
||||||
extern int __ctors_end__;
|
|
||||||
extern int __dtors_start__;
|
|
||||||
extern int __dtors_end__;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Identify RAM size by searching for aliases - up to a maximum of 64 megabytes
|
|
||||||
|
|
||||||
#define ADDRCHECKWORD 0x55aa44bb
|
|
||||||
#define ADDRCHECKWORD2 0xf0e1d2c3
|
|
||||||
|
|
||||||
static unsigned int addresscheck(volatile int *base,int cachesize)
|
|
||||||
{
|
|
||||||
int i,j,k;
|
|
||||||
int a1,a2;
|
|
||||||
int aliases=0;
|
|
||||||
unsigned int size=64;
|
|
||||||
// Seed the RAM;
|
|
||||||
a1=19;
|
|
||||||
*base=ADDRCHECKWORD;
|
|
||||||
for(j=18;j<25;++j)
|
|
||||||
{
|
|
||||||
base[a1]=ADDRCHECKWORD;
|
|
||||||
a1<<=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have a cache we need to flush it here.
|
|
||||||
|
|
||||||
// Now check for aliases
|
|
||||||
a1=1;
|
|
||||||
*base=ADDRCHECKWORD2;
|
|
||||||
for(j=1;j<25;++j)
|
|
||||||
{
|
|
||||||
if(base[a1]==ADDRCHECKWORD2)
|
|
||||||
aliases|=a1;
|
|
||||||
a1<<=1;
|
|
||||||
}
|
|
||||||
|
|
||||||
aliases<<=2;
|
|
||||||
|
|
||||||
while(aliases)
|
|
||||||
{
|
|
||||||
aliases=(aliases<<1)&0x3ffffff; // Test currently supports up to 16m longwords = 64 megabytes.
|
|
||||||
size>>=1;
|
|
||||||
}
|
|
||||||
xprintf("SDRAM size (assuming no address faults) is 0x%d megabytes\n",size);
|
|
||||||
|
|
||||||
return(size*(1<<20));
|
|
||||||
}
|
|
||||||
|
|
||||||
void _break();
|
|
||||||
void __attribute__ ((weak)) _premain()
|
|
||||||
{
|
|
||||||
int t;
|
|
||||||
int *ctors;
|
|
||||||
char *ramtop;
|
|
||||||
// Clear BSS data
|
|
||||||
int *bss=&__bss_start__;
|
|
||||||
while(bss<&__bss_end__)
|
|
||||||
*bss++=0;
|
|
||||||
|
|
||||||
_initIO();
|
|
||||||
xprintf("Initialising files\n");
|
|
||||||
for(t=0;t<MAX_FILES;++t)
|
|
||||||
Files[t]=0;
|
|
||||||
// xprintf("_end is %d, RAMTOP is %d\n",&_end,RAMTOP);
|
|
||||||
// malloc_add(&_end,(char *)RAMTOP-&_end); // Add the entire RAM to the free memory pool
|
|
||||||
ramtop=(char *)addresscheck((volatile int *)&_end,0);
|
|
||||||
malloc_add(&_end,ramtop-&_end); // Add the entire RAM to the free memory pool
|
|
||||||
// _init();
|
|
||||||
|
|
||||||
// Run global constructors...
|
|
||||||
ctors=&__ctors_start__;
|
|
||||||
xprintf("Running global constructors");
|
|
||||||
while(ctors<&__ctors_end__)
|
|
||||||
{
|
|
||||||
xprintf(".");
|
|
||||||
void (*fp)();
|
|
||||||
fp=(void (*)())(*ctors);
|
|
||||||
fp();
|
|
||||||
++ctors;
|
|
||||||
}
|
|
||||||
xprintf("\n");
|
|
||||||
t=main(1, args);
|
|
||||||
// Run global destructors...
|
|
||||||
ctors=&__dtors_start__;
|
|
||||||
while(ctors<&__dtors_end__)
|
|
||||||
{
|
|
||||||
void (*fp)();
|
|
||||||
fp=(void (*)())(*ctors);
|
|
||||||
fp();
|
|
||||||
++ctors;
|
|
||||||
}
|
|
||||||
_exit(t);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Re-implement sbrk, since the libgloss version doesn't know about our memory map.
|
|
||||||
char *_sbrk(int nbytes)
|
|
||||||
{
|
|
||||||
// Since we add the entire memory in _premain() we can skip this.
|
|
||||||
xprintf("Custom sbrk asking for %d bytes\n",nbytes);
|
|
||||||
return(0);
|
|
||||||
#if 0
|
|
||||||
char *base;
|
|
||||||
|
|
||||||
if (!heap_ptr)
|
|
||||||
heap_ptr = (char *)&_end;
|
|
||||||
base = heap_ptr;
|
|
||||||
|
|
||||||
heap_ptr += nbytes;
|
|
||||||
|
|
||||||
if ((int)heap_ptr>RAMTOP)
|
|
||||||
return (char *)-1;
|
|
||||||
|
|
||||||
return base;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
//char *sbrk(int nbytes)
|
|
||||||
//{
|
|
||||||
// return(_sbrk(nbytes));
|
|
||||||
//}
|
|
||||||
|
|
||||||
/* NOTE!!!! compiled with -fomit-frame-pointer to make sure that 'status' has the
|
|
||||||
* correct value when breakpointing at _exit
|
|
||||||
*/
|
|
||||||
void __attribute__ ((weak)) _exit (int status)
|
|
||||||
{
|
|
||||||
/* end of the universe, cause memory fault */
|
|
||||||
__asm("breakpoint");
|
|
||||||
for(;;);
|
|
||||||
// _break();
|
|
||||||
}
|
|
||||||
|
|
||||||
void __attribute__ ((weak)) _zpu_interrupt(void)
|
|
||||||
{
|
|
||||||
/* not implemented in libgloss */
|
|
||||||
// __asm("breakpoint");
|
|
||||||
for (;;);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Rudimentary filesystem support
|
|
||||||
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (write, (fd, buf, nbytes),
|
|
||||||
int fd _AND
|
|
||||||
char *buf _AND
|
|
||||||
int nbytes)
|
|
||||||
{
|
|
||||||
if((fd==1) || (fd==2)) // stdout/stderr
|
|
||||||
{
|
|
||||||
int c=nbytes;
|
|
||||||
// Write to UART
|
|
||||||
// FIXME - need to save any received bytes in a ring buffer.
|
|
||||||
// FIXME - ultimately need to use interrupts here.
|
|
||||||
|
|
||||||
while(nbytes--)
|
|
||||||
{
|
|
||||||
putchar(*buf++);
|
|
||||||
//while(!(HW_UART(REG_UART)&(1<<REG_UART_TXREADY)))
|
|
||||||
// ;
|
|
||||||
//HW_UART(REG_UART)=*buf++;
|
|
||||||
}
|
|
||||||
return(nbytes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(File(fd))
|
|
||||||
{
|
|
||||||
// We have a file - but we don't yet support writing.
|
|
||||||
errno=EACCES;
|
|
||||||
}
|
|
||||||
errno=EBADF;
|
|
||||||
}
|
|
||||||
return (nbytes);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* read -- read bytes from the serial port if fd==0, otherwise try and read from SD card
|
|
||||||
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (read, (fd, buf, nbytes),
|
|
||||||
int fd _AND
|
|
||||||
char *buf _AND
|
|
||||||
int nbytes)
|
|
||||||
{
|
|
||||||
xprintf("Reading %d bytes from fd %d\n",nbytes,fd);
|
|
||||||
if(fd==0) // stdin
|
|
||||||
{
|
|
||||||
// Read from UART
|
|
||||||
while(nbytes--)
|
|
||||||
{
|
|
||||||
int in;
|
|
||||||
//while(!((in=HW_UART(REG_UART))&(1<<REG_UART_RXINT)))
|
|
||||||
// ;
|
|
||||||
//*buf++=in&0xff;
|
|
||||||
*buf++=getserial()&0xff;
|
|
||||||
}
|
|
||||||
return(nbytes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
#ifndef DISABLE_FILESYSTEM
|
|
||||||
// Handle reading from SD card
|
|
||||||
if(File(fd))
|
|
||||||
{
|
|
||||||
if(RARead(File(fd),buf,nbytes))
|
|
||||||
return(nbytes);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errno=EIO;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
#endif
|
|
||||||
errno=EBADF;
|
|
||||||
}
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* open -- open a file descriptor.
|
|
||||||
int __attribute__ ((weak)) open(const char *buf,
|
|
||||||
int flags,
|
|
||||||
...)
|
|
||||||
{
|
|
||||||
// FIXME - Take mode from the first varargs argument
|
|
||||||
xprintf("in open()\n");
|
|
||||||
if(filesystem_present) // Only support reads at present.
|
|
||||||
{
|
|
||||||
#ifndef DISABLE_FILESYSTEM
|
|
||||||
// Find a free FD
|
|
||||||
int fd=3;
|
|
||||||
while((fd-2)<MAX_FILES)
|
|
||||||
{
|
|
||||||
if(!File(fd))
|
|
||||||
{
|
|
||||||
xprintf("Found spare fd: %d\n",fd);
|
|
||||||
File(fd)=malloc(sizeof(RAFile));
|
|
||||||
if(File(fd))
|
|
||||||
{
|
|
||||||
if(RAOpen(File(fd),buf))
|
|
||||||
return(fd);
|
|
||||||
else
|
|
||||||
free(File(fd));
|
|
||||||
errno = ENOENT;
|
|
||||||
return(-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
++fd;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
xprintf("open() - no filesystem present\n");
|
|
||||||
errno = EIO;
|
|
||||||
}
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* close
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (close ,(fd),
|
|
||||||
int fd)
|
|
||||||
{
|
|
||||||
if(fd>2 && File(fd))
|
|
||||||
free(File(fd));
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
ftruncate (int file, off_t length)
|
|
||||||
{
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* unlink -- we just return an error since we don't support writes yet.
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (unlink, (path),
|
|
||||||
char * path)
|
|
||||||
{
|
|
||||||
errno = EIO;
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* lseek -- Since a serial port is non-seekable, we return an error.
|
|
||||||
off_t __attribute__ ((weak))
|
|
||||||
_DEFUN (lseek, (fd, offset, whence),
|
|
||||||
int fd _AND
|
|
||||||
off_t offset _AND
|
|
||||||
int whence)
|
|
||||||
{
|
|
||||||
if(fd<3)
|
|
||||||
{
|
|
||||||
errno = ESPIPE;
|
|
||||||
return ((off_t)-1);
|
|
||||||
}
|
|
||||||
else if(File(fd))
|
|
||||||
{
|
|
||||||
switch(whence)
|
|
||||||
{
|
|
||||||
case SEEK_SET:
|
|
||||||
case SEEK_CUR:
|
|
||||||
#ifndef DISABLE_FILESYSTEM
|
|
||||||
RASeek(File(fd),offset,whence);
|
|
||||||
#endif
|
|
||||||
return((off_t)File(fd)->ptr);
|
|
||||||
break;
|
|
||||||
case SEEK_END:
|
|
||||||
errno = EINVAL;
|
|
||||||
xprintf("SEEK_END not yet supported\n");
|
|
||||||
return((off_t)-1);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* we convert from bigendian to smallendian*/
|
|
||||||
static long conv(char *a, int len)
|
|
||||||
{
|
|
||||||
long t=0;
|
|
||||||
int i;
|
|
||||||
for (i=0; i<len; i++)
|
|
||||||
{
|
|
||||||
t|=(((int)a[i])&0xff)<<((len-1-i)*8);
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void convert(struct fio_stat *gdb_stat, struct stat *buf)
|
|
||||||
{
|
|
||||||
memset(buf, 0, sizeof(*buf));
|
|
||||||
buf->st_dev=conv(gdb_stat->fst_dev, sizeof(gdb_stat->fst_dev));
|
|
||||||
buf->st_ino=conv(gdb_stat->fst_ino, sizeof(gdb_stat->fst_ino));
|
|
||||||
buf->st_mode=conv(gdb_stat->fst_mode, sizeof(gdb_stat->fst_mode));
|
|
||||||
buf->st_nlink=conv(gdb_stat->fst_nlink, sizeof(gdb_stat->fst_nlink));
|
|
||||||
buf->st_uid=conv(gdb_stat->fst_uid, sizeof(gdb_stat->fst_uid));
|
|
||||||
buf->st_gid=conv(gdb_stat->fst_gid, sizeof(gdb_stat->fst_gid));
|
|
||||||
buf->st_rdev=conv(gdb_stat->fst_rdev, sizeof(gdb_stat->fst_rdev));
|
|
||||||
buf->st_size=conv(gdb_stat->fst_size, sizeof(gdb_stat->fst_size));
|
|
||||||
}
|
|
||||||
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (fstat, (fd, buf),
|
|
||||||
int fd _AND
|
|
||||||
struct stat *buf)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* fstat -- Since we have no file system, we just return an error.
|
|
||||||
*/
|
|
||||||
memset(buf,0,sizeof(struct stat));
|
|
||||||
if(fd<3)
|
|
||||||
{
|
|
||||||
buf->st_mode = S_IFCHR; /* Always pretend to be a tty */
|
|
||||||
buf->st_blksize = 0;
|
|
||||||
}
|
|
||||||
else if(File(fd))
|
|
||||||
{
|
|
||||||
buf->st_size = File(fd)->size;
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (stat, (path, buf),
|
|
||||||
const char *path _AND
|
|
||||||
struct stat *buf)
|
|
||||||
{
|
|
||||||
errno = EIO;
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int __attribute__ ((weak))
|
|
||||||
_DEFUN (isatty, (fd),
|
|
||||||
int fd)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* isatty -- returns 1 if connected to a terminal device,
|
|
||||||
* returns 0 if not. Since we're hooked up to a
|
|
||||||
* serial port, we'll say yes and return a 1.
|
|
||||||
*/
|
|
||||||
return (1);
|
|
||||||
}
|
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,183 +0,0 @@
|
|||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined __K64F__
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#define uint32_t __uint32_t
|
|
||||||
#define uint16_t __uint16_t
|
|
||||||
#define uint8_t __uint8_t
|
|
||||||
#define int32_t __int32_t
|
|
||||||
#define int16_t __int16_t
|
|
||||||
#define int8_t __int8_t
|
|
||||||
#else
|
|
||||||
#include <stdint.h>
|
|
||||||
#if !defined(FUNCTIONALITY)
|
|
||||||
#include <stdio.h>
|
|
||||||
#endif
|
|
||||||
#include <string.h>
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "uart.h"
|
|
||||||
|
|
||||||
static uint8_t uart_channel = 0;
|
|
||||||
|
|
||||||
inline int _putchar(unsigned char c)
|
|
||||||
{
|
|
||||||
uint32_t status;
|
|
||||||
|
|
||||||
do {
|
|
||||||
status = UART_STATUS(uart_channel == 0 ? UART0 : UART1);
|
|
||||||
} while((UART_IS_TX_FIFO_ENABLED(status) && UART_IS_TX_FIFO_FULL(status)) || (UART_IS_TX_FIFO_DISABLED(status) && UART_IS_TX_DATA_LOADED(status)));
|
|
||||||
UART_DATA(uart_channel == 0 ? UART0 : UART1) = (int)c;
|
|
||||||
|
|
||||||
return(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void set_serial_output(uint8_t c)
|
|
||||||
{
|
|
||||||
uart_channel = (c == 0 ? 0 : 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#if !defined(FUNCTIONALITY)
|
|
||||||
// Stream version of putchar for stdio.
|
|
||||||
//
|
|
||||||
int uart_putchar(char c, FILE *stream)
|
|
||||||
{
|
|
||||||
uint32_t status;
|
|
||||||
|
|
||||||
// Add CR when NL detected.
|
|
||||||
if (c == '\n')
|
|
||||||
uart_putchar('\r', stream);
|
|
||||||
|
|
||||||
// Wait for a slot to become available in UART buffer and then send character.
|
|
||||||
do {
|
|
||||||
status = UART_STATUS(uart_channel == 0 ? UART0 : UART1);
|
|
||||||
} while((UART_IS_TX_FIFO_ENABLED(status) && UART_IS_TX_FIFO_FULL(status)) || (UART_IS_TX_FIFO_DISABLED(status) && UART_IS_TX_DATA_LOADED(status)));
|
|
||||||
UART_DATA(uart_channel == 0 ? UART0 : UART1) = c;
|
|
||||||
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(FUNCTIONALITY) || FUNCTIONALITY <= 2
|
|
||||||
inline int dbgputchar(int c)
|
|
||||||
{
|
|
||||||
uart_channel = 1;
|
|
||||||
_putchar(c);
|
|
||||||
uart_channel = 0;
|
|
||||||
|
|
||||||
return(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void _dbgputchar(unsigned char c)
|
|
||||||
{
|
|
||||||
dbgputchar(c);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef USELOADB
|
|
||||||
int uart_puts(const char *msg)
|
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
while (*msg) {
|
|
||||||
_putchar(*msg++);
|
|
||||||
++result;
|
|
||||||
}
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
int uart_puts(const char *msg)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
int result=0;
|
|
||||||
// Because we haven't implemented loadb from ROM yet, we can't use *<char*>++.
|
|
||||||
// Therefore we read the source data in 32-bit chunks and shift-and-split accordingly.
|
|
||||||
int *s2=(int*)msg;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
int cs=*s2++;
|
|
||||||
for(i=0;i<4;++i)
|
|
||||||
{
|
|
||||||
c=(cs>>24)&0xff;
|
|
||||||
cs<<=8;
|
|
||||||
if(c==0)
|
|
||||||
return(result);
|
|
||||||
_putchar(c);
|
|
||||||
++result;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(c);
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !defined(FUNCTIONALITY) || FUNCTIONALITY <= 1
|
|
||||||
char getserial(void)
|
|
||||||
{
|
|
||||||
uint32_t reg;
|
|
||||||
|
|
||||||
do {
|
|
||||||
reg = UART_STATUS(uart_channel == 0 ? UART0 : UART1);
|
|
||||||
} while(!UART_IS_RX_DATA_READY(reg));
|
|
||||||
reg=UART_DATA(uart_channel == 0 ? UART0 : UART1);
|
|
||||||
|
|
||||||
return((char)reg & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !defined(FUNCTIONALITY)
|
|
||||||
// Stream version of getchar for stdio.
|
|
||||||
//
|
|
||||||
int uart_getchar(FILE *stream)
|
|
||||||
{
|
|
||||||
return((int)getserial());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int8_t getserial_nonblocking(void)
|
|
||||||
{
|
|
||||||
int8_t reg;
|
|
||||||
|
|
||||||
reg = UART_STATUS(uart_channel == 0 ? UART0 : UART1);
|
|
||||||
if(!UART_IS_RX_DATA_READY(reg))
|
|
||||||
{
|
|
||||||
reg = -1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
reg = UART_DATA(uart_channel == 0 ? UART0 : UART1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(reg);
|
|
||||||
}
|
|
||||||
|
|
||||||
char getdbgserial()
|
|
||||||
{
|
|
||||||
int32_t reg = 0;
|
|
||||||
|
|
||||||
set_serial_output(1);
|
|
||||||
reg = getserial();
|
|
||||||
set_serial_output(0);
|
|
||||||
return((char)reg & 0xFF);
|
|
||||||
}
|
|
||||||
|
|
||||||
int8_t getdbgserial_nonblocking()
|
|
||||||
{
|
|
||||||
int8_t reg = 0;
|
|
||||||
|
|
||||||
set_serial_output(1);
|
|
||||||
reg = getserial_nonblocking();
|
|
||||||
set_serial_output(0);
|
|
||||||
return(reg);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
110
zOS/MZ2000/common/umm/dbglog.h
vendored
110
zOS/MZ2000/common/umm/dbglog.h
vendored
@@ -1,110 +0,0 @@
|
|||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* dbglog.h - A set of macros that cleans up code that needs to produce debug
|
|
||||||
* or log information.
|
|
||||||
*
|
|
||||||
* Many embedded systems still put a premium on code space and therefore need
|
|
||||||
* a way to conditionally compile in debug code. Yes, it can lead to code that
|
|
||||||
* runs differently depending on whether the debug code is cmpiled in or not
|
|
||||||
* but you need to be able to evaluate the tradeoff.
|
|
||||||
*
|
|
||||||
* See copyright notice in LICENSE.TXT
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* NOTE WELL that this file may be included multiple times - this allows you
|
|
||||||
* to set the trace level #define DBGLOG_LEVEL x
|
|
||||||
*
|
|
||||||
* To update which of the DBGLOG macros are compiled in, you must redefine the
|
|
||||||
* DBGLOG_LEVEL macro and the inlcude the dbglog.h file again, like this:
|
|
||||||
*
|
|
||||||
* #undef DBGLOG_LEVEL
|
|
||||||
* #define DBGLOG_LEVEL 6
|
|
||||||
* #include "dbglog/dbglog.txt"
|
|
||||||
*
|
|
||||||
* To handle multiple inclusion, we need to first undefine any macros we define
|
|
||||||
* so that the compiler does not warn us that we are changing a macro.
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* The DBGLOG_LEVEL and DBGLOG_FUNCTION should be defined BEFORE this
|
|
||||||
* file is included or else the following defaults are used:
|
|
||||||
*
|
|
||||||
* #define DBGLOG_LEVEL 0
|
|
||||||
* #define DBGLOG_FUNCTION printf
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
* There are macros to handle the following decreasing levels of detail:
|
|
||||||
*
|
|
||||||
* 6 = TRACE
|
|
||||||
* 5 = DEBUG
|
|
||||||
* 4 = CRITICAL
|
|
||||||
* 3 = ERROR
|
|
||||||
* 2 = WARNING
|
|
||||||
* 1 = INFO
|
|
||||||
* 0 = FORCE - The DBGLOG_FUNCTION is always compiled in and is called only when
|
|
||||||
* the first parameter to the macro is non-0
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __DBGLOG_H__
|
|
||||||
#define __DBGLOG_H__
|
|
||||||
#define DBGLOG_LEVEL_TRACE (6)
|
|
||||||
#define DBGLOG_LEVEL_DEBUG (5)
|
|
||||||
#define DBGLOG_LEVEL_CRITICAL (4)
|
|
||||||
#define DBGLOG_LEVEL_ERROR (3)
|
|
||||||
#define DBGLOG_LEVEL_WARNING (2)
|
|
||||||
#define DBGLOG_LEVEL_INFO (1)
|
|
||||||
#define DBGLOG_LEVEL_FORCE (0)
|
|
||||||
//#else
|
|
||||||
#undef DBGLOG_TRACE
|
|
||||||
#undef DBGLOG_DEBUG
|
|
||||||
#undef DBGLOG_CRITICAL
|
|
||||||
#undef DBGLOG_ERROR
|
|
||||||
#undef DBGLOG_WARNING
|
|
||||||
#undef DBGLOG_INFO
|
|
||||||
#undef DBGLOG_FORCE
|
|
||||||
|
|
||||||
#ifndef DBGLOG_LEVEL
|
|
||||||
# define DBGLOG_LEVEL 6
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef DBGLOG_FUNCTION
|
|
||||||
# define DBGLOG_FUNCTION printf
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#if DBGLOG_LEVEL >= 6
|
|
||||||
# define DBGLOG_TRACE(format, ...) DBGLOG_FUNCTION(format, ## __VA_ARGS__);
|
|
||||||
#else
|
|
||||||
# define DBGLOG_TRACE(format, ...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DBGLOG_LEVEL >= 5
|
|
||||||
# define DBGLOG_DEBUG(format, ...) DBGLOG_FUNCTION(format, ## __VA_ARGS__);
|
|
||||||
#else
|
|
||||||
# define DBGLOG_DEBUG(format, ...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DBGLOG_LEVEL >= 4
|
|
||||||
# define DBGLOG_CRITICAL(format, ...) DBGLOG_FUNCTION(format, ## __VA_ARGS__);
|
|
||||||
#else
|
|
||||||
# define DBGLOG_CRITICAL(format, ...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DBGLOG_LEVEL >= 3
|
|
||||||
# define DBGLOG_ERROR(format, ...) DBGLOG_FUNCTION(format, ## __VA_ARGS__);
|
|
||||||
#else
|
|
||||||
# define DBGLOG_ERROR(format, ...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DBGLOG_LEVEL >= 2
|
|
||||||
# define DBGLOG_WARNING(format, ...) DBGLOG_FUNCTION(format, ## __VA_ARGS__);
|
|
||||||
#else
|
|
||||||
# define DBGLOG_WARNING(format, ...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if DBGLOG_LEVEL >= 1
|
|
||||||
# define DBGLOG_INFO(format, ...) DBGLOG_FUNCTION(format, ## __VA_ARGS__);
|
|
||||||
#else
|
|
||||||
# define DBGLOG_INFO(format, ...)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define DBGLOG_FORCE(force, format, ...) {if(force) {DBGLOG_FUNCTION(format, ## __VA_ARGS__);}};
|
|
||||||
//#define DBGLOG_FORCE(force, format, ...)
|
|
||||||
#endif /* __DBGLOG_H__ */
|
|
||||||
@@ -1,211 +0,0 @@
|
|||||||
#ifdef UMM_INFO
|
|
||||||
|
|
||||||
//#include <math.h> // Disabled as you need to include stdlib to obtain maths functions.
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#elif defined(__ZPU__)
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#elif defined(__M68K__)
|
|
||||||
#include <stdint.h>
|
|
||||||
// #include <stdlib.h>
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__, __K64F__ or M68K"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* One of the coolest things about this little library is that it's VERY
|
|
||||||
* easy to get debug information about the memory heap by simply iterating
|
|
||||||
* through all of the memory blocks.
|
|
||||||
*
|
|
||||||
* As you go through all the blocks, you can check to see if it's a free
|
|
||||||
* block by looking at the high order bit of the next block index. You can
|
|
||||||
* also see how big the block is by subtracting the next block index from
|
|
||||||
* the current block number.
|
|
||||||
*
|
|
||||||
* The umm_info function does all of that and makes the results available
|
|
||||||
* in the ummHeapInfo structure.
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
UMM_HEAP_INFO ummHeapInfo;
|
|
||||||
|
|
||||||
void *umm_info( void *ptr, bool force ) {
|
|
||||||
if(umm_heap == NULL) {
|
|
||||||
umm_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t blockNo = 0;
|
|
||||||
|
|
||||||
/* Protect the critical section... */
|
|
||||||
UMM_CRITICAL_ENTRY();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Clear out all of the entries in the ummHeapInfo structure before doing
|
|
||||||
* any calculations..
|
|
||||||
*/
|
|
||||||
memset( &ummHeapInfo, 0, sizeof( ummHeapInfo ) );
|
|
||||||
|
|
||||||
DBGLOG_FORCE( force, "\n" );
|
|
||||||
DBGLOG_FORCE( force, "+ Address + Block +--------+--------+-------+--------+--------+\n" );
|
|
||||||
DBGLOG_FORCE( force, "+----------+-------+--------+--------+-------+--------+--------+\n" );
|
|
||||||
DBGLOG_FORCE( force, "|0x%08x|B %5x|NB %5x|PB %5x|Z %5x|NF %5x|PF %5x|\n",
|
|
||||||
(void *)(&UMM_BLOCK(blockNo)),
|
|
||||||
blockNo,
|
|
||||||
UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK,
|
|
||||||
UMM_PBLOCK(blockNo),
|
|
||||||
(UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK )-blockNo,
|
|
||||||
UMM_NFREE(blockNo),
|
|
||||||
UMM_PFREE(blockNo) );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now loop through the block lists, and keep track of the number and size
|
|
||||||
* of used and free blocks. The terminating condition is an nb pointer with
|
|
||||||
* a value of zero...
|
|
||||||
*/
|
|
||||||
|
|
||||||
blockNo = UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK;
|
|
||||||
|
|
||||||
while( UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK ) {
|
|
||||||
size_t curBlocks = (UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK )-blockNo;
|
|
||||||
|
|
||||||
++ummHeapInfo.totalEntries;
|
|
||||||
ummHeapInfo.totalBlocks += curBlocks;
|
|
||||||
|
|
||||||
/* Is this a free block? */
|
|
||||||
|
|
||||||
if( UMM_NBLOCK(blockNo) & UMM_FREELIST_MASK ) {
|
|
||||||
++ummHeapInfo.freeEntries;
|
|
||||||
ummHeapInfo.freeBlocks += curBlocks;
|
|
||||||
ummHeapInfo.freeBlocksSquared += (curBlocks * curBlocks);
|
|
||||||
|
|
||||||
if (ummHeapInfo.maxFreeContiguousBlocks < curBlocks) {
|
|
||||||
ummHeapInfo.maxFreeContiguousBlocks = curBlocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBGLOG_FORCE( force, "|0x%08x|B %5x|NB %5x|PB %5x|Z %5x|NF %5x|PF %5x|\n",
|
|
||||||
(void *)(&UMM_BLOCK(blockNo)),
|
|
||||||
blockNo,
|
|
||||||
UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK,
|
|
||||||
UMM_PBLOCK(blockNo),
|
|
||||||
(uint16_t)curBlocks,
|
|
||||||
UMM_NFREE(blockNo),
|
|
||||||
UMM_PFREE(blockNo) );
|
|
||||||
|
|
||||||
/* Does this block address match the ptr we may be trying to free? */
|
|
||||||
|
|
||||||
if( ptr == &UMM_BLOCK(blockNo) ) {
|
|
||||||
|
|
||||||
/* Release the critical section... */
|
|
||||||
UMM_CRITICAL_EXIT();
|
|
||||||
|
|
||||||
return( ptr );
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
++ummHeapInfo.usedEntries;
|
|
||||||
ummHeapInfo.usedBlocks += curBlocks;
|
|
||||||
|
|
||||||
DBGLOG_FORCE( force, "|0x%08x|B %5x|NB %5x|PB %5x|Z %5x|\n",
|
|
||||||
(void *)(&UMM_BLOCK(blockNo)),
|
|
||||||
blockNo,
|
|
||||||
UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK,
|
|
||||||
UMM_PBLOCK(blockNo),
|
|
||||||
(uint16_t)curBlocks );
|
|
||||||
}
|
|
||||||
|
|
||||||
blockNo = UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The very last block is used as a placeholder to indicate that
|
|
||||||
* there are no more blocks in the heap, so it cannot be used
|
|
||||||
* for anything - at the same time, the size of this block must
|
|
||||||
* ALWAYS be exactly 1 !
|
|
||||||
*/
|
|
||||||
|
|
||||||
DBGLOG_FORCE( force, "|0x%08x|B %5x|NB %5x|PB %5x|Z %5x|NF %5x|PF %5x|\n",
|
|
||||||
(void *)(&UMM_BLOCK(blockNo)),
|
|
||||||
blockNo,
|
|
||||||
UMM_NBLOCK(blockNo) & UMM_BLOCKNO_MASK,
|
|
||||||
UMM_PBLOCK(blockNo),
|
|
||||||
UMM_NUMBLOCKS-blockNo,
|
|
||||||
UMM_NFREE(blockNo),
|
|
||||||
UMM_PFREE(blockNo) );
|
|
||||||
|
|
||||||
DBGLOG_FORCE( force, "+----------+-------+--------+--------+-------+--------+--------+\n" );
|
|
||||||
|
|
||||||
DBGLOG_FORCE( force, "Total Entries %5x Used Entries %5x Free Entries %xi\n",
|
|
||||||
ummHeapInfo.totalEntries,
|
|
||||||
ummHeapInfo.usedEntries,
|
|
||||||
ummHeapInfo.freeEntries );
|
|
||||||
|
|
||||||
DBGLOG_FORCE( force, "Total Blocks %5x Used Blocks %5x Free Blocks %5x\n",
|
|
||||||
ummHeapInfo.totalBlocks,
|
|
||||||
ummHeapInfo.usedBlocks,
|
|
||||||
ummHeapInfo.freeBlocks );
|
|
||||||
|
|
||||||
DBGLOG_FORCE( force, "+--------------------------------------------------------------+\n" );
|
|
||||||
|
|
||||||
// DBGLOG_FORCE( force, "Usage Metric: %5i\n", umm_usage_metric());
|
|
||||||
// DBGLOG_FORCE( force, "Fragmentation Metric: %5i\n", umm_fragmentation_metric());
|
|
||||||
|
|
||||||
DBGLOG_FORCE( force, "+--------------------------------------------------------------+\n" );
|
|
||||||
|
|
||||||
/* Release the critical section... */
|
|
||||||
UMM_CRITICAL_EXIT();
|
|
||||||
|
|
||||||
return( NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
size_t umm_free_heap_size( void ) {
|
|
||||||
umm_info(NULL, 0);
|
|
||||||
return (size_t)ummHeapInfo.freeBlocks * sizeof(umm_block);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t umm_max_free_block_size( void ) {
|
|
||||||
umm_info(NULL, 0);
|
|
||||||
return ummHeapInfo.maxFreeContiguousBlocks * sizeof(umm_block);
|
|
||||||
}
|
|
||||||
|
|
||||||
//int umm_usage_metric( void ) {
|
|
||||||
// DBGLOG_DEBUG( "usedBlocks %i totalBlocks %i\n", umm_metrics.usedBlocks, ummHeapInfo.totalBlocks);
|
|
||||||
//
|
|
||||||
// return (int)((ummHeapInfo.usedBlocks * 100)/(ummHeapInfo.freeBlocks));
|
|
||||||
//}
|
|
||||||
|
|
||||||
//int umm_fragmentation_metric( void ) {
|
|
||||||
// DBGLOG_DEBUG( "freeBlocks %i freeBlocksSquared %i\n", umm_metrics.freeBlocks, ummHeapInfo.freeBlocksSquared);
|
|
||||||
// if (0 == ummHeapInfo.freeBlocks) {
|
|
||||||
// return 0;
|
|
||||||
// } else {
|
|
||||||
// return (100 - (((uint32_t)(sqrtf(ummHeapInfo.freeBlocksSquared)) * 100)/(ummHeapInfo.freeBlocks)));
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
#ifdef UMM_INLINE_METRICS
|
|
||||||
static void umm_fragmentation_metric_init( void ) {
|
|
||||||
ummHeapInfo.freeBlocks = UMM_NUMBLOCKS - 2;
|
|
||||||
ummHeapInfo.freeBlocksSquared = ummHeapInfo.freeBlocks * ummHeapInfo.freeBlocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void umm_fragmentation_metric_add( uint16_t c ) {
|
|
||||||
uint16_t blocks = (UMM_NBLOCK(c) & UMM_BLOCKNO_MASK) - c;
|
|
||||||
DBGLOG_DEBUG( "Add block %x size %x to free metric\n", c, blocks);
|
|
||||||
ummHeapInfo.freeBlocks += blocks;
|
|
||||||
ummHeapInfo.freeBlocksSquared += (blocks * blocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void umm_fragmentation_metric_remove( uint16_t c ) {
|
|
||||||
uint16_t blocks = (UMM_NBLOCK(c) & UMM_BLOCKNO_MASK) - c;
|
|
||||||
DBGLOG_DEBUG( "Remove block %x size %x from free metric\n", c, blocks);
|
|
||||||
ummHeapInfo.freeBlocks -= blocks;
|
|
||||||
ummHeapInfo.freeBlocksSquared -= (blocks * blocks);
|
|
||||||
}
|
|
||||||
#endif // UMM_INLINE_METRICS
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
#endif
|
|
||||||
@@ -1,136 +0,0 @@
|
|||||||
/* integrity check (UMM_INTEGRITY_CHECK) {{{ */
|
|
||||||
#ifdef UMM_INTEGRITY_CHECK
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Perform integrity check of the whole heap data. Returns 1 in case of
|
|
||||||
* success, 0 otherwise.
|
|
||||||
*
|
|
||||||
* First of all, iterate through all free blocks, and check that all backlinks
|
|
||||||
* match (i.e. if block X has next free block Y, then the block Y should have
|
|
||||||
* previous free block set to X).
|
|
||||||
*
|
|
||||||
* Additionally, we check that each free block is correctly marked with
|
|
||||||
* `UMM_FREELIST_MASK` on the `next` pointer: during iteration through free
|
|
||||||
* list, we mark each free block by the same flag `UMM_FREELIST_MASK`, but
|
|
||||||
* on `prev` pointer. We'll check and unmark it later.
|
|
||||||
*
|
|
||||||
* Then, we iterate through all blocks in the heap, and similarly check that
|
|
||||||
* all backlinks match (i.e. if block X has next block Y, then the block Y
|
|
||||||
* should have previous block set to X).
|
|
||||||
*
|
|
||||||
* But before checking each backlink, we check that the `next` and `prev`
|
|
||||||
* pointers are both marked with `UMM_FREELIST_MASK`, or both unmarked.
|
|
||||||
* This way, we ensure that the free flag is in sync with the free pointers
|
|
||||||
* chain.
|
|
||||||
*/
|
|
||||||
bool umm_integrity_check(void) {
|
|
||||||
bool ok = true;
|
|
||||||
uint16_t prev;
|
|
||||||
uint16_t cur;
|
|
||||||
|
|
||||||
if (umm_heap == NULL) {
|
|
||||||
umm_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Iterate through all free blocks */
|
|
||||||
prev = 0;
|
|
||||||
while(1) {
|
|
||||||
cur = UMM_NFREE(prev);
|
|
||||||
|
|
||||||
/* Check that next free block number is valid */
|
|
||||||
if (cur >= UMM_NUMBLOCKS) {
|
|
||||||
printf("heap integrity broken: too large next free num: %d "
|
|
||||||
"(in block %d, addr 0x%lx)\n", cur, prev,
|
|
||||||
(void *)&UMM_NBLOCK(prev));
|
|
||||||
ok = false;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
if (cur == 0) {
|
|
||||||
/* No more free blocks */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check if prev free block number matches */
|
|
||||||
if (UMM_PFREE(cur) != prev) {
|
|
||||||
printf("heap integrity broken: free links don't match: "
|
|
||||||
"%d -> %d, but %d -> %d\n",
|
|
||||||
prev, cur, cur, UMM_PFREE(cur));
|
|
||||||
ok = false;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
UMM_PBLOCK(cur) |= UMM_FREELIST_MASK;
|
|
||||||
|
|
||||||
prev = cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Iterate through all blocks */
|
|
||||||
prev = 0;
|
|
||||||
while(1) {
|
|
||||||
cur = UMM_NBLOCK(prev) & UMM_BLOCKNO_MASK;
|
|
||||||
|
|
||||||
/* Check that next block number is valid */
|
|
||||||
if (cur >= UMM_NUMBLOCKS) {
|
|
||||||
printf("heap integrity broken: too large next block num: %d "
|
|
||||||
"(in block %d, addr 0x%lx)\n", cur, prev,
|
|
||||||
(void *)&UMM_NBLOCK(prev));
|
|
||||||
ok = false;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
if (cur == 0) {
|
|
||||||
/* No more blocks */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure the free mark is appropriate, and unmark it */
|
|
||||||
if ((UMM_NBLOCK(cur) & UMM_FREELIST_MASK)
|
|
||||||
!= (UMM_PBLOCK(cur) & UMM_FREELIST_MASK))
|
|
||||||
{
|
|
||||||
printf("heap integrity broken: mask wrong at addr 0x%lx: n=0x%x, p=0x%x\n",
|
|
||||||
(void *)&UMM_NBLOCK(cur),
|
|
||||||
(UMM_NBLOCK(cur) & UMM_FREELIST_MASK),
|
|
||||||
(UMM_PBLOCK(cur) & UMM_FREELIST_MASK)
|
|
||||||
);
|
|
||||||
ok = false;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* make sure the block list is sequential */
|
|
||||||
if (cur <= prev ) {
|
|
||||||
printf("heap integrity broken: next block %d is before prev this one "
|
|
||||||
"(in block %d, addr 0x%lx)\n", cur, prev,
|
|
||||||
(void *)&UMM_NBLOCK(prev));
|
|
||||||
ok = false;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* unmark */
|
|
||||||
UMM_PBLOCK(cur) &= UMM_BLOCKNO_MASK;
|
|
||||||
|
|
||||||
/* Check if prev block number matches */
|
|
||||||
if (UMM_PBLOCK(cur) != prev) {
|
|
||||||
printf("heap integrity broken: block links don't match: "
|
|
||||||
"%d -> %d, but %d -> %d\n",
|
|
||||||
prev, cur, cur, UMM_PBLOCK(cur));
|
|
||||||
ok = false;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
prev = cur;
|
|
||||||
}
|
|
||||||
|
|
||||||
clean:
|
|
||||||
if (!ok){
|
|
||||||
UMM_HEAP_CORRUPTION_CB();
|
|
||||||
}
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,725 +0,0 @@
|
|||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* umm_malloc.c - a memory allocator for embedded systems (microcontrollers)
|
|
||||||
*
|
|
||||||
* See LICENSE for copyright notice
|
|
||||||
* See README.md for acknowledgements and description of internals
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* R.Hempel 2007-09-22 - Original
|
|
||||||
* R.Hempel 2008-12-11 - Added MIT License biolerplate
|
|
||||||
* - realloc() now looks to see if previous block is free
|
|
||||||
* - made common operations functions
|
|
||||||
* R.Hempel 2009-03-02 - Added macros to disable tasking
|
|
||||||
* - Added function to dump heap and check for valid free
|
|
||||||
* pointer
|
|
||||||
* R.Hempel 2009-03-09 - Changed name to umm_malloc to avoid conflicts with
|
|
||||||
* the mm_malloc() library functions
|
|
||||||
* - Added some test code to assimilate a free block
|
|
||||||
* with the very block if possible. Complicated and
|
|
||||||
* not worth the grief.
|
|
||||||
* D.Frank 2014-04-02 - Fixed heap configuration when UMM_TEST_MAIN is NOT set,
|
|
||||||
* added user-dependent configuration file umm_malloc_cfg.h
|
|
||||||
* R.Hempel 2016-12-04 - Add support for Unity test framework
|
|
||||||
* - Reorganize source files to avoid redundant content
|
|
||||||
* - Move integrity and poison checking to separate file
|
|
||||||
* R.Hempel 2017-12-29 - Fix bug in realloc when requesting a new block that
|
|
||||||
* results in OOM error - see Issue 11
|
|
||||||
* R.Hempel 2019-09-07 - Separate the malloc() and free() functionality into
|
|
||||||
* wrappers that use critical section protection macros
|
|
||||||
* and static core functions that assume they are
|
|
||||||
* running in a protected con text. Thanks @devyte
|
|
||||||
* R.Hempel 2020-01-07 - Add support for Fragmentation metric - See Issue 14
|
|
||||||
* R.Hempel 2020-01-12 - Use explicitly sized values from stdint.h - See Issue 15
|
|
||||||
* R.Hempel 2020-01-20 - Move metric functions back to umm_info - See Issue 29
|
|
||||||
* R.Hempel 2020-02-01 - Macro functions are uppercased - See Issue 34
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__K64F__)
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#elif defined(__ZPU__)
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#elif defined(__M68K__)
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
// #include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__, __K64F__ or M68K"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "umm_malloc_cfg.h" /* user-dependent */
|
|
||||||
#include "umm_malloc.h"
|
|
||||||
|
|
||||||
/* Use the default DBGLOG_LEVEL and DBGLOG_FUNCTION */
|
|
||||||
|
|
||||||
#define DBGLOG_LEVEL UMM_DBG_LOG_LEVEL
|
|
||||||
|
|
||||||
#include "dbglog.h"
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
#define umm_free free
|
|
||||||
#define umm_malloc malloc
|
|
||||||
#define umm_realloc realloc
|
|
||||||
#define umm_calloc calloc
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
UMM_H_ATTPACKPRE typedef struct umm_ptr_t {
|
|
||||||
uint16_t next;
|
|
||||||
uint16_t prev;
|
|
||||||
} UMM_H_ATTPACKSUF umm_ptr;
|
|
||||||
|
|
||||||
|
|
||||||
UMM_H_ATTPACKPRE typedef struct umm_block_t {
|
|
||||||
union {
|
|
||||||
umm_ptr used;
|
|
||||||
} header;
|
|
||||||
union {
|
|
||||||
umm_ptr free;
|
|
||||||
uint8_t data[4];
|
|
||||||
} body;
|
|
||||||
} UMM_H_ATTPACKSUF umm_block;
|
|
||||||
|
|
||||||
#define UMM_FREELIST_MASK (0x8000)
|
|
||||||
#define UMM_BLOCKNO_MASK (0x7FFF)
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
umm_block *umm_heap = NULL;
|
|
||||||
uint16_t umm_numblocks = 0;
|
|
||||||
|
|
||||||
#define UMM_NUMBLOCKS (umm_numblocks)
|
|
||||||
#define UMM_BLOCK_LAST (UMM_NUMBLOCKS - 1)
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#define UMM_BLOCK(b) (umm_heap[b])
|
|
||||||
|
|
||||||
#define UMM_NBLOCK(b) (UMM_BLOCK(b).header.used.next)
|
|
||||||
#define UMM_PBLOCK(b) (UMM_BLOCK(b).header.used.prev)
|
|
||||||
#define UMM_NFREE(b) (UMM_BLOCK(b).body.free.next)
|
|
||||||
#define UMM_PFREE(b) (UMM_BLOCK(b).body.free.prev)
|
|
||||||
#define UMM_DATA(b) (UMM_BLOCK(b).body.data)
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------
|
|
||||||
* There are additional files that may be included here - normally it's
|
|
||||||
* not a good idea to include .c files but in this case it keeps the
|
|
||||||
* main umm_malloc file clear and prevents issues with exposing internal
|
|
||||||
* data structures to other programs.
|
|
||||||
* -------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "umm_integrity.c"
|
|
||||||
#include "umm_poison.c"
|
|
||||||
#include "umm_info.c"
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
static uint16_t umm_blocks( size_t size ) {
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The calculation of the block size is not too difficult, but there are
|
|
||||||
* a few little things that we need to be mindful of.
|
|
||||||
*
|
|
||||||
* When a block removed from the free list, the space used by the free
|
|
||||||
* pointers is available for data. That's what the first calculation
|
|
||||||
* of size is doing.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( size <= (sizeof(((umm_block *)0)->body)) )
|
|
||||||
return( 1 );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If it's for more than that, then we need to figure out the number of
|
|
||||||
* additional whole blocks the size of an umm_block are required.
|
|
||||||
*/
|
|
||||||
|
|
||||||
size -= ( 1 + (sizeof(((umm_block *)0)->body)) );
|
|
||||||
|
|
||||||
return( 2 + size/(sizeof(umm_block)) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
/*
|
|
||||||
* Split the block `c` into two blocks: `c` and `c + blocks`.
|
|
||||||
*
|
|
||||||
* - `new_freemask` should be `0` if `c + blocks` used, or `UMM_FREELIST_MASK`
|
|
||||||
* otherwise.
|
|
||||||
*
|
|
||||||
* Note that free pointers are NOT modified by this function.
|
|
||||||
*/
|
|
||||||
static void umm_split_block( uint16_t c,
|
|
||||||
uint16_t blocks,
|
|
||||||
uint16_t new_freemask ) {
|
|
||||||
|
|
||||||
UMM_NBLOCK(c+blocks) = (UMM_NBLOCK(c) & UMM_BLOCKNO_MASK) | new_freemask;
|
|
||||||
UMM_PBLOCK(c+blocks) = c;
|
|
||||||
|
|
||||||
UMM_PBLOCK(UMM_NBLOCK(c) & UMM_BLOCKNO_MASK) = (c+blocks);
|
|
||||||
UMM_NBLOCK(c) = (c+blocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
static void umm_disconnect_from_free_list( uint16_t c ) {
|
|
||||||
/* Disconnect this block from the FREE list */
|
|
||||||
|
|
||||||
UMM_NFREE(UMM_PFREE(c)) = UMM_NFREE(c);
|
|
||||||
UMM_PFREE(UMM_NFREE(c)) = UMM_PFREE(c);
|
|
||||||
|
|
||||||
/* And clear the free block indicator */
|
|
||||||
|
|
||||||
UMM_NBLOCK(c) &= (~UMM_FREELIST_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
|
||||||
* The umm_assimilate_up() function does not assume that UMM_NBLOCK(c)
|
|
||||||
* has the UMM_FREELIST_MASK bit set. It only assimilates up if the
|
|
||||||
* next block is free.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void umm_assimilate_up( uint16_t c ) {
|
|
||||||
|
|
||||||
if( UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_FREELIST_MASK ) {
|
|
||||||
|
|
||||||
UMM_FRAGMENTATION_METRIC_REMOVE( UMM_NBLOCK(c) );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The next block is a free block, so assimilate up and remove it from
|
|
||||||
* the free list
|
|
||||||
*/
|
|
||||||
|
|
||||||
DBGLOG_DEBUG( "Assimilate up to next block, which is FREE\n" );
|
|
||||||
|
|
||||||
/* Disconnect the next block from the FREE list */
|
|
||||||
|
|
||||||
umm_disconnect_from_free_list( UMM_NBLOCK(c) );
|
|
||||||
|
|
||||||
/* Assimilate the next block with this one */
|
|
||||||
|
|
||||||
UMM_PBLOCK(UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_BLOCKNO_MASK) = c;
|
|
||||||
UMM_NBLOCK(c) = UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_BLOCKNO_MASK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
|
||||||
* The umm_assimilate_down() function assumes that UMM_NBLOCK(c) does NOT
|
|
||||||
* have the UMM_FREELIST_MASK bit set. In other words, try to assimilate
|
|
||||||
* up before assimilating down.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static uint16_t umm_assimilate_down( uint16_t c, uint16_t freemask ) {
|
|
||||||
|
|
||||||
// We are going to assimilate down to the previous block because
|
|
||||||
// it was free, so remove it from the fragmentation metric
|
|
||||||
|
|
||||||
UMM_FRAGMENTATION_METRIC_REMOVE(UMM_PBLOCK(c));
|
|
||||||
|
|
||||||
UMM_NBLOCK(UMM_PBLOCK(c)) = UMM_NBLOCK(c) | freemask;
|
|
||||||
UMM_PBLOCK(UMM_NBLOCK(c)) = UMM_PBLOCK(c);
|
|
||||||
|
|
||||||
if (freemask) {
|
|
||||||
// We are going to free the entire assimilated block
|
|
||||||
// so add it to the fragmentation metric. A good
|
|
||||||
// compiler will optimize away the empty if statement
|
|
||||||
// when UMM_INFO is not defined, so don't worry about
|
|
||||||
// guarding it.
|
|
||||||
|
|
||||||
UMM_FRAGMENTATION_METRIC_ADD(UMM_PBLOCK(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
return( UMM_PBLOCK(c) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
void umm_init( void ) {
|
|
||||||
/* init heap pointer and size, and memset it to 0 */
|
|
||||||
umm_heap = (umm_block *)__HEAPADDR__;
|
|
||||||
umm_numblocks = (__HEAPSIZE__ / sizeof(umm_block));
|
|
||||||
memset(umm_heap, 0x00, __HEAPSIZE__);
|
|
||||||
|
|
||||||
/* setup initial blank heap structure */
|
|
||||||
UMM_FRAGMENTATION_METRIC_INIT();
|
|
||||||
|
|
||||||
/* Set up umm_block[0], which just points to umm_block[1] */
|
|
||||||
UMM_NBLOCK(0) = 1;
|
|
||||||
UMM_NFREE(0) = 1;
|
|
||||||
UMM_PFREE(0) = 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now, we need to set the whole heap space as a huge free block. We should
|
|
||||||
* not touch umm_block[0], since it's special: umm_block[0] is the head of
|
|
||||||
* the free block list. It's a part of the heap invariant.
|
|
||||||
*
|
|
||||||
* See the detailed explanation at the beginning of the file.
|
|
||||||
*
|
|
||||||
* umm_block[1] has pointers:
|
|
||||||
*
|
|
||||||
* - next `umm_block`: the last one umm_block[n]
|
|
||||||
* - prev `umm_block`: umm_block[0]
|
|
||||||
*
|
|
||||||
* Plus, it's a free `umm_block`, so we need to apply `UMM_FREELIST_MASK`
|
|
||||||
*
|
|
||||||
* And it's the last free block, so the next free block is 0 which marks
|
|
||||||
* the end of the list. The previous block and free block pointer are 0
|
|
||||||
* too, there is no need to initialize these values due to the init code
|
|
||||||
* that memsets the entire umm_ space to 0.
|
|
||||||
*/
|
|
||||||
UMM_NBLOCK(1) = UMM_BLOCK_LAST | UMM_FREELIST_MASK;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Last umm_block[n] has the next block index at 0, meaning it's
|
|
||||||
* the end of the list, and the previous block is umm_block[1].
|
|
||||||
*
|
|
||||||
* The last block is a special block and can never be part of the
|
|
||||||
* free list, so its pointers are left at 0 too.
|
|
||||||
*/
|
|
||||||
|
|
||||||
UMM_PBLOCK(UMM_BLOCK_LAST) = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
|
||||||
* Must be called only from within critical sections guarded by
|
|
||||||
* UMM_CRITICAL_ENTRY() and UMM_CRITICAL_EXIT().
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void umm_free_core( void *ptr ) {
|
|
||||||
|
|
||||||
uint16_t c;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* FIXME: At some point it might be a good idea to add a check to make sure
|
|
||||||
* that the pointer we're being asked to free up is actually within
|
|
||||||
* the umm_heap!
|
|
||||||
*
|
|
||||||
* NOTE: See the new umm_info() function that you can use to see if a ptr is
|
|
||||||
* on the free list!
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Figure out which block we're in. Note the use of truncated division... */
|
|
||||||
|
|
||||||
c = (((void *)ptr)-(void *)(&(umm_heap[0])))/sizeof(umm_block);
|
|
||||||
|
|
||||||
DBGLOG_DEBUG( "Freeing block %6x\n", c );
|
|
||||||
|
|
||||||
/* Now let's assimilate this block with the next one if possible. */
|
|
||||||
|
|
||||||
umm_assimilate_up( c );
|
|
||||||
|
|
||||||
/* Then assimilate with the previous block if possible */
|
|
||||||
|
|
||||||
if( UMM_NBLOCK(UMM_PBLOCK(c)) & UMM_FREELIST_MASK ) {
|
|
||||||
|
|
||||||
DBGLOG_DEBUG( "Assimilate down to previous block, which is FREE\n" );
|
|
||||||
|
|
||||||
c = umm_assimilate_down(c, UMM_FREELIST_MASK);
|
|
||||||
} else {
|
|
||||||
/*
|
|
||||||
* The previous block is not a free block, so add this one to the head
|
|
||||||
* of the free list
|
|
||||||
*/
|
|
||||||
UMM_FRAGMENTATION_METRIC_ADD(c);
|
|
||||||
|
|
||||||
DBGLOG_DEBUG( "Just add to head of free list\n" );
|
|
||||||
|
|
||||||
UMM_PFREE(UMM_NFREE(0)) = c;
|
|
||||||
UMM_NFREE(c) = UMM_NFREE(0);
|
|
||||||
UMM_PFREE(c) = 0;
|
|
||||||
UMM_NFREE(0) = c;
|
|
||||||
|
|
||||||
UMM_NBLOCK(c) |= UMM_FREELIST_MASK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
void umm_free( void *ptr ) {
|
|
||||||
|
|
||||||
if (umm_heap == NULL) {
|
|
||||||
umm_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we're being asked to free a NULL pointer, well that's just silly! */
|
|
||||||
|
|
||||||
if( (void *)0 == ptr ) {
|
|
||||||
DBGLOG_DEBUG( "free a null pointer -> do nothing\n" );
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free the memory withing a protected critical section */
|
|
||||||
|
|
||||||
UMM_CRITICAL_ENTRY();
|
|
||||||
|
|
||||||
umm_free_core( ptr );
|
|
||||||
|
|
||||||
UMM_CRITICAL_EXIT();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------
|
|
||||||
* Must be called only from within critical sections guarded by
|
|
||||||
* UMM_CRITICAL_ENTRY() and UMM_CRITICAL_EXIT().
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void *umm_malloc_core( size_t size ) {
|
|
||||||
uint16_t blocks;
|
|
||||||
uint16_t blockSize = 0;
|
|
||||||
|
|
||||||
uint16_t bestSize;
|
|
||||||
uint16_t bestBlock;
|
|
||||||
|
|
||||||
uint16_t cf;
|
|
||||||
|
|
||||||
blocks = umm_blocks( size );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now we can scan through the free list until we find a space that's big
|
|
||||||
* enough to hold the number of blocks we need.
|
|
||||||
*
|
|
||||||
* This part may be customized to be a best-fit, worst-fit, or first-fit
|
|
||||||
* algorithm
|
|
||||||
*/
|
|
||||||
|
|
||||||
cf = UMM_NFREE(0);
|
|
||||||
|
|
||||||
bestBlock = UMM_NFREE(0);
|
|
||||||
bestSize = 0x7FFF;
|
|
||||||
|
|
||||||
while( cf ) {
|
|
||||||
blockSize = (UMM_NBLOCK(cf) & UMM_BLOCKNO_MASK) - cf;
|
|
||||||
|
|
||||||
DBGLOG_TRACE( "Looking at block %6x size %6x\n", cf, blockSize );
|
|
||||||
|
|
||||||
#if defined UMM_BEST_FIT
|
|
||||||
if( (blockSize >= blocks) && (blockSize < bestSize) ) {
|
|
||||||
bestBlock = cf;
|
|
||||||
bestSize = blockSize;
|
|
||||||
}
|
|
||||||
#elif defined UMM_FIRST_FIT
|
|
||||||
/* This is the first block that fits! */
|
|
||||||
if( (blockSize >= blocks) )
|
|
||||||
break;
|
|
||||||
#else
|
|
||||||
# error "No UMM_*_FIT is defined - check umm_malloc_cfg.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
cf = UMM_NFREE(cf);
|
|
||||||
}
|
|
||||||
|
|
||||||
if( 0x7FFF != bestSize ) {
|
|
||||||
cf = bestBlock;
|
|
||||||
blockSize = bestSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( UMM_NBLOCK(cf) & UMM_BLOCKNO_MASK && blockSize >= blocks ) {
|
|
||||||
|
|
||||||
UMM_FRAGMENTATION_METRIC_REMOVE(cf);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This is an existing block in the memory heap, we just need to split off
|
|
||||||
* what we need, unlink it from the free list and mark it as in use, and
|
|
||||||
* link the rest of the block back into the freelist as if it was a new
|
|
||||||
* block on the free list...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( blockSize == blocks ) {
|
|
||||||
/* It's an exact fit and we don't neet to split off a block. */
|
|
||||||
DBGLOG_DEBUG( "Allocating %6i blocks starting at %6x - exact\n", blocks, cf );
|
|
||||||
|
|
||||||
/* Disconnect this block from the FREE list */
|
|
||||||
|
|
||||||
umm_disconnect_from_free_list( cf );
|
|
||||||
} else {
|
|
||||||
|
|
||||||
/* It's not an exact fit and we need to split off a block. */
|
|
||||||
DBGLOG_DEBUG( "Allocating %6x blocks starting at %6x - existing\n", blocks, cf );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* split current free block `cf` into two blocks. The first one will be
|
|
||||||
* returned to user, so it's not free, and the second one will be free.
|
|
||||||
*/
|
|
||||||
umm_split_block( cf, blocks, UMM_FREELIST_MASK /*new block is free*/ );
|
|
||||||
|
|
||||||
UMM_FRAGMENTATION_METRIC_ADD(UMM_NBLOCK(cf));
|
|
||||||
|
|
||||||
/*
|
|
||||||
* `umm_split_block()` does not update the free pointers (it affects
|
|
||||||
* only free flags), but effectively we've just moved beginning of the
|
|
||||||
* free block from `cf` to `cf + blocks`. So we have to adjust pointers
|
|
||||||
* to and from adjacent free blocks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* previous free block */
|
|
||||||
UMM_NFREE( UMM_PFREE(cf) ) = cf + blocks;
|
|
||||||
UMM_PFREE( cf + blocks ) = UMM_PFREE(cf);
|
|
||||||
|
|
||||||
/* next free block */
|
|
||||||
UMM_PFREE( UMM_NFREE(cf) ) = cf + blocks;
|
|
||||||
UMM_NFREE( cf + blocks ) = UMM_NFREE(cf);
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
/* Out of memory */
|
|
||||||
|
|
||||||
DBGLOG_DEBUG( "Can't allocate %5x blocks\n", blocks );
|
|
||||||
|
|
||||||
return( (void *)NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
return( (void *)&UMM_DATA(cf) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
void *umm_malloc( size_t size ) {
|
|
||||||
|
|
||||||
void *ptr = NULL;
|
|
||||||
|
|
||||||
if (umm_heap == NULL) {
|
|
||||||
umm_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* the very first thing we do is figure out if we're being asked to allocate
|
|
||||||
* a size of 0 - and if we are we'll simply return a null pointer. if not
|
|
||||||
* then reduce the size by 1 byte so that the subsequent calculations on
|
|
||||||
* the number of blocks to allocate are easier...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( 0 == size ) {
|
|
||||||
DBGLOG_DEBUG( "malloc a block of 0 bytes -> do nothing\n" );
|
|
||||||
|
|
||||||
return( ptr );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate the memory withing a protected critical section */
|
|
||||||
|
|
||||||
UMM_CRITICAL_ENTRY();
|
|
||||||
|
|
||||||
ptr = umm_malloc_core( size );
|
|
||||||
|
|
||||||
UMM_CRITICAL_EXIT();
|
|
||||||
|
|
||||||
return( ptr );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
void *umm_realloc( void *ptr, size_t size ) {
|
|
||||||
|
|
||||||
uint16_t blocks;
|
|
||||||
uint16_t blockSize;
|
|
||||||
uint16_t prevBlockSize = 0;
|
|
||||||
uint16_t nextBlockSize = 0;
|
|
||||||
|
|
||||||
uint16_t c;
|
|
||||||
|
|
||||||
size_t curSize;
|
|
||||||
|
|
||||||
if (umm_heap == NULL) {
|
|
||||||
umm_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This code looks after the case of a NULL value for ptr. The ANSI C
|
|
||||||
* standard says that if ptr is NULL and size is non-zero, then we've
|
|
||||||
* got to work the same a malloc(). If size is also 0, then our version
|
|
||||||
* of malloc() returns a NULL pointer, which is OK as far as the ANSI C
|
|
||||||
* standard is concerned.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( ((void *)NULL == ptr) ) {
|
|
||||||
DBGLOG_DEBUG( "realloc the NULL pointer - call malloc()\n" );
|
|
||||||
|
|
||||||
return( umm_malloc(size) );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Now we're sure that we have a non_NULL ptr, but we're not sure what
|
|
||||||
* we should do with it. If the size is 0, then the ANSI C standard says that
|
|
||||||
* we should operate the same as free.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( 0 == size ) {
|
|
||||||
DBGLOG_DEBUG( "realloc to 0 size, just free the block\n" );
|
|
||||||
|
|
||||||
umm_free( ptr );
|
|
||||||
|
|
||||||
return( (void *)NULL );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Otherwise we need to actually do a reallocation. A naiive approach
|
|
||||||
* would be to malloc() a new block of the correct size, copy the old data
|
|
||||||
* to the new block, and then free the old block.
|
|
||||||
*
|
|
||||||
* While this will work, we end up doing a lot of possibly unnecessary
|
|
||||||
* copying. So first, let's figure out how many blocks we'll need.
|
|
||||||
*/
|
|
||||||
|
|
||||||
blocks = umm_blocks( size );
|
|
||||||
|
|
||||||
/* Figure out which block we're in. Note the use of truncated division... */
|
|
||||||
|
|
||||||
c = (((void *)ptr)-(void *)(&(umm_heap[0])))/sizeof(umm_block);
|
|
||||||
|
|
||||||
/* Figure out how big this block is ... the free bit is not set :-) */
|
|
||||||
|
|
||||||
blockSize = (UMM_NBLOCK(c) - c);
|
|
||||||
|
|
||||||
/* Figure out how many bytes are in this block */
|
|
||||||
|
|
||||||
curSize = (blockSize*sizeof(umm_block))-(sizeof(((umm_block *)0)->header));
|
|
||||||
|
|
||||||
/* Protect the critical section... */
|
|
||||||
UMM_CRITICAL_ENTRY();
|
|
||||||
|
|
||||||
/* Now figure out if the previous and/or next blocks are free as well as
|
|
||||||
* their sizes - this will help us to minimize special code later when we
|
|
||||||
* decide if it's possible to use the adjacent blocks.
|
|
||||||
*
|
|
||||||
* We set prevBlockSize and nextBlockSize to non-zero values ONLY if they
|
|
||||||
* are free!
|
|
||||||
*/
|
|
||||||
|
|
||||||
if ((UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_FREELIST_MASK)) {
|
|
||||||
nextBlockSize = (UMM_NBLOCK(UMM_NBLOCK(c)) & UMM_BLOCKNO_MASK) - UMM_NBLOCK(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((UMM_NBLOCK(UMM_PBLOCK(c)) & UMM_FREELIST_MASK)) {
|
|
||||||
prevBlockSize = (c - UMM_PBLOCK(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
DBGLOG_DEBUG( "realloc blocks %x blockSize %x nextBlockSize %x prevBlockSize %x\n", blocks, blockSize, nextBlockSize, prevBlockSize );
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Ok, now that we're here we know how many blocks we want and the current
|
|
||||||
* blockSize. The prevBlockSize and nextBlockSize are set and we can figure
|
|
||||||
* out the best strategy for the new allocation as follows:
|
|
||||||
*
|
|
||||||
* 1. If the new block is the same size or smaller than the current block do
|
|
||||||
* nothing.
|
|
||||||
* 2. If the next block is free and adding it to the current block gives us
|
|
||||||
* EXACTLY enough memory, assimilate the next block. This avoids unwanted
|
|
||||||
* fragmentation of free memory.
|
|
||||||
*
|
|
||||||
* The following cases may be better handled with memory copies to reduce
|
|
||||||
* fragmentation
|
|
||||||
*
|
|
||||||
* 3. If the previous block is NOT free and the next block is free and
|
|
||||||
* adding it to the current block gives us enough memory, assimilate
|
|
||||||
* the next block. This may introduce a bit of fragmentation.
|
|
||||||
* 4. If the prev block is free and adding it to the current block gives us
|
|
||||||
* enough memory, remove the previous block from the free list, assimilate
|
|
||||||
* it, copy to the new block.
|
|
||||||
* 5. If the prev and next blocks are free and adding them to the current
|
|
||||||
* block gives us enough memory, assimilate the next block, remove the
|
|
||||||
* previous block from the free list, assimilate it, copy to the new block.
|
|
||||||
* 6. Otherwise try to allocate an entirely new block of memory. If the
|
|
||||||
* allocation works free the old block and return the new pointer. If
|
|
||||||
* the allocation fails, return NULL and leave the old block intact.
|
|
||||||
*
|
|
||||||
* TODO: Add some conditional code to optimise for less fragmentation
|
|
||||||
* by simply allocating new memory if we need to copy anyways.
|
|
||||||
*
|
|
||||||
* All that's left to do is decide if the fit was exact or not. If the fit
|
|
||||||
* was not exact, then split the memory block so that we use only the requested
|
|
||||||
* number of blocks and add what's left to the free list.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Case 1 - block is same size or smaller
|
|
||||||
if (blockSize >= blocks) {
|
|
||||||
DBGLOG_DEBUG( "realloc the same or smaller size block - %x, do nothing\n", blocks );
|
|
||||||
/* This space intentionally left blank */
|
|
||||||
DBGLOG_DEBUG("Returning 1 alloc address:%08lx#n", ptr);
|
|
||||||
|
|
||||||
// Case 2 - block + next block fits EXACTLY
|
|
||||||
} else if ((blockSize + nextBlockSize) == blocks) {
|
|
||||||
DBGLOG_DEBUG( "exact realloc using next block - %x\n", blocks );
|
|
||||||
umm_assimilate_up( c );
|
|
||||||
blockSize += nextBlockSize;
|
|
||||||
|
|
||||||
// Case 3 - prev block NOT free and block + next block fits
|
|
||||||
} else if ((0 == prevBlockSize) && (blockSize + nextBlockSize) >= blocks) {
|
|
||||||
DBGLOG_DEBUG( "realloc using next block - %x\n", blocks );
|
|
||||||
umm_assimilate_up( c );
|
|
||||||
blockSize += nextBlockSize;
|
|
||||||
|
|
||||||
// Case 4 - prev block + block fits
|
|
||||||
} else if ((prevBlockSize + blockSize) >= blocks) {
|
|
||||||
DBGLOG_DEBUG( "realloc using prev block - %i\n", blocks );
|
|
||||||
umm_disconnect_from_free_list( UMM_PBLOCK(c) );
|
|
||||||
c = umm_assimilate_down(c, 0);
|
|
||||||
memmove( (void *)&UMM_DATA(c), ptr, curSize );
|
|
||||||
ptr = (void *)&UMM_DATA(c);
|
|
||||||
blockSize += prevBlockSize;
|
|
||||||
|
|
||||||
// Case 5 - prev block + block + next block fits
|
|
||||||
} else if ((prevBlockSize + blockSize + nextBlockSize) >= blocks) {
|
|
||||||
DBGLOG_DEBUG( "realloc using prev and next block - %x\n", blocks );
|
|
||||||
umm_assimilate_up( c );
|
|
||||||
umm_disconnect_from_free_list( UMM_PBLOCK(c) );
|
|
||||||
c = umm_assimilate_down(c, 0);
|
|
||||||
memmove( (void *)&UMM_DATA(c), ptr, curSize );
|
|
||||||
ptr = (void *)&UMM_DATA(c);
|
|
||||||
blockSize += (prevBlockSize + nextBlockSize);
|
|
||||||
|
|
||||||
// Case 6 - default is we need to realloc a new block
|
|
||||||
} else {
|
|
||||||
DBGLOG_DEBUG( "realloc a completely new block %x\n", blocks );
|
|
||||||
void *oldptr = ptr;
|
|
||||||
if( (ptr = umm_malloc_core( size )) ) {
|
|
||||||
DBGLOG_DEBUG( "realloc %x to a bigger block %i, copy, and free the old\n", blockSize, blocks );
|
|
||||||
memcpy( ptr, oldptr, curSize );
|
|
||||||
umm_free_core( oldptr );
|
|
||||||
} else {
|
|
||||||
DBGLOG_DEBUG( "realloc %x to a bigger block %i failed - return NULL and leave the old block!\n", blockSize, blocks );
|
|
||||||
/* This space intentionally left blnk */
|
|
||||||
}
|
|
||||||
blockSize = blocks;
|
|
||||||
}
|
|
||||||
|
|
||||||
DBGLOG_DEBUG("Returning 2 alloc address:%08lx#n", ptr);
|
|
||||||
/* Now all we need to do is figure out if the block fit exactly or if we
|
|
||||||
* need to split and free ...
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (blockSize > blocks ) {
|
|
||||||
DBGLOG_DEBUG( "split and free %x blocks from %x\n", blocks, blockSize );
|
|
||||||
umm_split_block( c, blocks, 0 );
|
|
||||||
umm_free_core( (void *)&UMM_DATA(c+blocks) );
|
|
||||||
}
|
|
||||||
|
|
||||||
DBGLOG_DEBUG("Returning 3 alloc address:%08lx#n", ptr);
|
|
||||||
/* Release the critical section... */
|
|
||||||
UMM_CRITICAL_EXIT();
|
|
||||||
|
|
||||||
DBGLOG_DEBUG("Returning 4 alloc address:%08lx#n", ptr);
|
|
||||||
return( ptr );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
void *umm_calloc( size_t num, size_t item_size ) {
|
|
||||||
void *ret;
|
|
||||||
|
|
||||||
ret = umm_malloc((size_t)(item_size * num));
|
|
||||||
|
|
||||||
if (ret)
|
|
||||||
memset(ret, 0x00, (size_t)(item_size * num));
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
29
zOS/MZ2000/common/umm/umm_malloc.h
vendored
29
zOS/MZ2000/common/umm/umm_malloc.h
vendored
@@ -1,29 +0,0 @@
|
|||||||
/* ----------------------------------------------------------------------------
|
|
||||||
* umm_malloc.h - a memory allocator for embedded systems (microcontrollers)
|
|
||||||
*
|
|
||||||
* See copyright notice in LICENSE.TXT
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef UMM_MALLOC_H
|
|
||||||
#define UMM_MALLOC_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
extern void umm_init( void );
|
|
||||||
extern void *umm_malloc( size_t size );
|
|
||||||
extern void *umm_calloc( size_t num, size_t size );
|
|
||||||
extern void *umm_realloc( void *ptr, size_t size );
|
|
||||||
extern void umm_free( void *ptr );
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* UMM_MALLOC_H */
|
|
||||||
232
zOS/MZ2000/common/umm/umm_malloc_cfg.h
vendored
232
zOS/MZ2000/common/umm/umm_malloc_cfg.h
vendored
@@ -1,232 +0,0 @@
|
|||||||
/*
|
|
||||||
* Configuration for umm_malloc - DO NOT EDIT THIS FILE BY HAND!
|
|
||||||
*
|
|
||||||
* Refer to the notes below for how to configure the build at compile time
|
|
||||||
* using -D to define non-default values
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _UMM_MALLOC_CFG_H
|
|
||||||
#define _UMM_MALLOC_CFG_H
|
|
||||||
|
|
||||||
#include <stdbool.h>
|
|
||||||
|
|
||||||
/*
|
|
||||||
* There are a number of defines you can set at compile time that affect how
|
|
||||||
* the memory allocator will operate.
|
|
||||||
*
|
|
||||||
* Unless otherwise noted, the default state of these values is #undef-ined!
|
|
||||||
*
|
|
||||||
* If you set them via the -D option on the command line (preferred method)
|
|
||||||
* then this file handles all the configuration automagically and warns if
|
|
||||||
* there is an incompatible configuration.
|
|
||||||
*
|
|
||||||
* UMM_TEST_BUILD
|
|
||||||
*
|
|
||||||
* Set this if you want to compile in the test suite
|
|
||||||
*
|
|
||||||
* UMM_BEST_FIT (default)
|
|
||||||
*
|
|
||||||
* Set this if you want to use a best-fit algorithm for allocating new blocks.
|
|
||||||
* On by default, turned off by UMM_FIRST_FIT
|
|
||||||
*
|
|
||||||
* UMM_FIRST_FIT
|
|
||||||
*
|
|
||||||
* Set this if you want to use a first-fit algorithm for allocating new blocks.
|
|
||||||
* Faster than UMM_BEST_FIT but can result in higher fragmentation.
|
|
||||||
*
|
|
||||||
* UMM_INFO
|
|
||||||
*
|
|
||||||
* Set if you want the ability to calculate metrics on demand
|
|
||||||
*
|
|
||||||
* UMM_INLINE_METRICS
|
|
||||||
*
|
|
||||||
* Set this if you want to have access to a minimal set of heap metrics that
|
|
||||||
* can be used to gauge heap health.
|
|
||||||
* Setting this at compile time will automatically set UMM_INFO.
|
|
||||||
* Note that enabling this define will add a slight runtime penalty.
|
|
||||||
*
|
|
||||||
* UMM_INTEGRITY_CHECK
|
|
||||||
*
|
|
||||||
* Set if you want to be able to verify that the heap is semantically correct
|
|
||||||
* before or after any heap operation - all of the block indexes in the heap
|
|
||||||
* make sense.
|
|
||||||
* Slows execution dramatically but catches errors really quickly.
|
|
||||||
*
|
|
||||||
* UMM_POISON_CHECK
|
|
||||||
*
|
|
||||||
* Set if you want to be able to leave a poison buffer around each allocation.
|
|
||||||
* Note this uses an extra 8 bytes per allocation, but you get the benefit of
|
|
||||||
* being able to detect if your program is writing past an allocated buffer.
|
|
||||||
*
|
|
||||||
* UMM_DBG_LOG_LEVEL=n
|
|
||||||
*
|
|
||||||
* Set n to a value from 0 to 6 depending on how verbose you want the debug
|
|
||||||
* log to be
|
|
||||||
*
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*
|
|
||||||
* Support for this library in a multitasking environment is provided when
|
|
||||||
* you add bodies to the UMM_CRITICAL_ENTRY and UMM_CRITICAL_EXIT macros
|
|
||||||
* (see below)
|
|
||||||
*
|
|
||||||
* ----------------------------------------------------------------------------
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef UMM_TEST_BUILD
|
|
||||||
extern char test_umm_heap[];
|
|
||||||
|
|
||||||
/* Start addresses and the size of the heap */
|
|
||||||
#define UMM_MALLOC_CFG_HEAP_ADDR (test_umm_heap)
|
|
||||||
#define UMM_MALLOC_CFG_HEAP_SIZE (0x10000)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* A couple of macros to make packing structures less compiler dependent */
|
|
||||||
|
|
||||||
#define UMM_H_ATTPACKPRE
|
|
||||||
#define UMM_H_ATTPACKSUF __attribute__((__packed__))
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#ifdef UMM_BEST_FIT
|
|
||||||
#ifdef UMM_FIRST_FIT
|
|
||||||
#error Both UMM_BEST_FIT and UMM_FIRST_FIT are defined - pick one!
|
|
||||||
#endif
|
|
||||||
#else /* UMM_BEST_FIT is not defined */
|
|
||||||
#ifndef UMM_FIRST_FIT
|
|
||||||
#define UMM_BEST_FIT
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#ifdef UMM_INLINE_METRICS
|
|
||||||
#define UMM_FRAGMENTATION_METRIC_INIT() umm_fragmentation_metric_init()
|
|
||||||
#define UMM_FRAGMENTATION_METRIC_ADD(c) umm_fragmentation_metric_add(c)
|
|
||||||
#define UMM_FRAGMENTATION_METRIC_REMOVE(c) umm_fragmentation_metric_remove(c)
|
|
||||||
#else
|
|
||||||
#define UMM_FRAGMENTATION_METRIC_INIT()
|
|
||||||
#define UMM_FRAGMENTATION_METRIC_ADD(c)
|
|
||||||
#define UMM_FRAGMENTATION_METRIC_REMOVE(c)
|
|
||||||
#endif // UMM_INLINE_METRICS
|
|
||||||
|
|
||||||
/* -------------------------------------------------------------------------- */
|
|
||||||
|
|
||||||
#ifdef UMM_INFO
|
|
||||||
typedef struct UMM_HEAP_INFO_t {
|
|
||||||
unsigned int totalEntries;
|
|
||||||
unsigned int usedEntries;
|
|
||||||
unsigned int freeEntries;
|
|
||||||
|
|
||||||
unsigned int totalBlocks;
|
|
||||||
unsigned int usedBlocks;
|
|
||||||
unsigned int freeBlocks;
|
|
||||||
unsigned int freeBlocksSquared;
|
|
||||||
|
|
||||||
unsigned int maxFreeContiguousBlocks;
|
|
||||||
}
|
|
||||||
UMM_HEAP_INFO;
|
|
||||||
|
|
||||||
extern UMM_HEAP_INFO ummHeapInfo;
|
|
||||||
|
|
||||||
extern void *umm_info( void *ptr, bool force );
|
|
||||||
extern size_t umm_free_heap_size( void );
|
|
||||||
extern size_t umm_max_free_block_size( void );
|
|
||||||
extern int umm_usage_metric( void );
|
|
||||||
extern int umm_fragmentation_metric( void );
|
|
||||||
#else
|
|
||||||
#define umm_info(p,b)
|
|
||||||
#define umm_free_heap_size() (0)
|
|
||||||
#define umm_max_free_block_size() (0)
|
|
||||||
#define umm_fragmentation_metric() (0)
|
|
||||||
#define umm_in_use_metric() (0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* A couple of macros to make it easier to protect the memory allocator
|
|
||||||
* in a multitasking system. You should set these macros up to use whatever
|
|
||||||
* your system uses for this purpose. You can disable interrupts entirely, or
|
|
||||||
* just disable task switching - it's up to you
|
|
||||||
*
|
|
||||||
* NOTE WELL that these macros MUST be allowed to nest, because umm_free() is
|
|
||||||
* called from within umm_malloc()
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef UMM_TEST_BUILD
|
|
||||||
extern int umm_critical_depth;
|
|
||||||
extern int umm_max_critical_depth;
|
|
||||||
#define UMM_CRITICAL_ENTRY() {\
|
|
||||||
++umm_critical_depth; \
|
|
||||||
if (umm_critical_depth > umm_max_critical_depth) { \
|
|
||||||
umm_max_critical_depth = umm_critical_depth; \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
#define UMM_CRITICAL_EXIT() (umm_critical_depth--)
|
|
||||||
#else
|
|
||||||
#define UMM_CRITICAL_ENTRY()
|
|
||||||
#define UMM_CRITICAL_EXIT()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enables heap integrity check before any heap operation. It affects
|
|
||||||
* performance, but does NOT consume extra memory.
|
|
||||||
*
|
|
||||||
* If integrity violation is detected, the message is printed and user-provided
|
|
||||||
* callback is called: `UMM_HEAP_CORRUPTION_CB()`
|
|
||||||
*
|
|
||||||
* Note that not all buffer overruns are detected: each buffer is aligned by
|
|
||||||
* 4 bytes, so there might be some trailing "extra" bytes which are not checked
|
|
||||||
* for corruption.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef UMM_INTEGRITY_CHECK
|
|
||||||
extern bool umm_integrity_check( void );
|
|
||||||
# define INTEGRITY_CHECK() umm_integrity_check()
|
|
||||||
extern void umm_corruption(void);
|
|
||||||
# define UMM_HEAP_CORRUPTION_CB() printf( "Heap Corruption!" )
|
|
||||||
#else
|
|
||||||
# define INTEGRITY_CHECK() (1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enables heap poisoning: add predefined value (poison) before and after each
|
|
||||||
* allocation, and check before each heap operation that no poison is
|
|
||||||
* corrupted.
|
|
||||||
*
|
|
||||||
* Other than the poison itself, we need to store exact user-requested length
|
|
||||||
* for each buffer, so that overrun by just 1 byte will be always noticed.
|
|
||||||
*
|
|
||||||
* Customizations:
|
|
||||||
*
|
|
||||||
* UMM_POISON_SIZE_BEFORE:
|
|
||||||
* Number of poison bytes before each block, e.g. 4
|
|
||||||
* UMM_POISON_SIZE_AFTER:
|
|
||||||
* Number of poison bytes after each block e.g. 4
|
|
||||||
* UMM_POISONED_BLOCK_LEN_TYPE
|
|
||||||
* Type of the exact buffer length, e.g. `uint16_t`
|
|
||||||
*
|
|
||||||
* NOTE: each allocated buffer is aligned by 4 bytes. But when poisoning is
|
|
||||||
* enabled, actual pointer returned to user is shifted by
|
|
||||||
* `(sizeof(UMM_POISONED_BLOCK_LEN_TYPE) + UMM_POISON_SIZE_BEFORE)`.
|
|
||||||
* It's your responsibility to make resulting pointers aligned appropriately.
|
|
||||||
*
|
|
||||||
* If poison corruption is detected, the message is printed and user-provided
|
|
||||||
* callback is called: `UMM_HEAP_CORRUPTION_CB()`
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef UMM_POISON_CHECK
|
|
||||||
#define UMM_POISON_SIZE_BEFORE (4)
|
|
||||||
#define UMM_POISON_SIZE_AFTER (4)
|
|
||||||
#define UMM_POISONED_BLOCK_LEN_TYPE uint16_t
|
|
||||||
|
|
||||||
void *umm_poison_malloc( size_t size );
|
|
||||||
void *umm_poison_calloc( size_t num, size_t size );
|
|
||||||
void *umm_poison_realloc( void *ptr, size_t size );
|
|
||||||
void umm_poison_free( void *ptr );
|
|
||||||
bool umm_poison_check( void );
|
|
||||||
|
|
||||||
#define POISON_CHECK() umm_poison_check()
|
|
||||||
#else
|
|
||||||
#define POISON_CHECK() (1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* _UMM_MALLOC_CFG_H */
|
|
||||||
@@ -1,230 +0,0 @@
|
|||||||
/* poisoning (UMM_POISON_CHECK) {{{ */
|
|
||||||
#if defined(UMM_POISON_CHECK)
|
|
||||||
#define POISON_BYTE (0xa5)
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Yields a size of the poison for the block of size `s`.
|
|
||||||
* If `s` is 0, returns 0.
|
|
||||||
*/
|
|
||||||
static size_t poison_size(size_t s) {
|
|
||||||
return(s ? (UMM_POISON_SIZE_BEFORE +
|
|
||||||
sizeof(UMM_POISONED_BLOCK_LEN_TYPE) +
|
|
||||||
UMM_POISON_SIZE_AFTER)
|
|
||||||
: 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Print memory contents starting from given `ptr`
|
|
||||||
*/
|
|
||||||
static void dump_mem ( const void *ptr, size_t len ) {
|
|
||||||
while (len--) {
|
|
||||||
DBGLOG_ERROR(" 0x%.2x", (*(uint8_t *)ptr++));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Put poison data at given `ptr` and `poison_size`
|
|
||||||
*/
|
|
||||||
static void put_poison( void *ptr, size_t poison_size ) {
|
|
||||||
memset(ptr, POISON_BYTE, poison_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check poison data at given `ptr` and `poison_size`. `where` is a pointer to
|
|
||||||
* a string, either "before" or "after", meaning, before or after the block.
|
|
||||||
*
|
|
||||||
* If poison is there, returns 1.
|
|
||||||
* Otherwise, prints the appropriate message, and returns 0.
|
|
||||||
*/
|
|
||||||
static bool check_poison( const void *ptr, size_t poison_size,
|
|
||||||
const void *where) {
|
|
||||||
size_t i;
|
|
||||||
bool ok = true;
|
|
||||||
|
|
||||||
for (i = 0; i < poison_size; i++) {
|
|
||||||
if (((uint8_t *)ptr)[i] != POISON_BYTE) {
|
|
||||||
ok = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ok) {
|
|
||||||
DBGLOG_ERROR( "No poison %s block at: 0x%lx, actual data:", where, (void *)ptr);
|
|
||||||
dump_mem(ptr, poison_size);
|
|
||||||
DBGLOG_ERROR( "\n" );
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check if a block is properly poisoned. Must be called only for non-free
|
|
||||||
* blocks.
|
|
||||||
*/
|
|
||||||
static bool check_poison_block( umm_block *pblock ) {
|
|
||||||
int ok = true;
|
|
||||||
|
|
||||||
if (pblock->header.used.next & UMM_FREELIST_MASK) {
|
|
||||||
DBGLOG_ERROR( "check_poison_block is called for free block 0x%lx\n", (void *)pblock);
|
|
||||||
} else {
|
|
||||||
/* the block is used; let's check poison */
|
|
||||||
void *pc = (void *)pblock->body.data;
|
|
||||||
void *pc_cur;
|
|
||||||
|
|
||||||
pc_cur = pc + sizeof(UMM_POISONED_BLOCK_LEN_TYPE);
|
|
||||||
if (!check_poison(pc_cur, UMM_POISON_SIZE_BEFORE, "before")) {
|
|
||||||
ok = false;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
|
|
||||||
pc_cur = pc + *((UMM_POISONED_BLOCK_LEN_TYPE *)pc) - UMM_POISON_SIZE_AFTER;
|
|
||||||
if (!check_poison(pc_cur, UMM_POISON_SIZE_AFTER, "after")) {
|
|
||||||
ok = false;
|
|
||||||
goto clean;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
clean:
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Takes a pointer returned by actual allocator function (`umm_malloc` or
|
|
||||||
* `umm_realloc`), puts appropriate poison, and returns adjusted pointer that
|
|
||||||
* should be returned to the user.
|
|
||||||
*
|
|
||||||
* `size_w_poison` is a size of the whole block, including a poison.
|
|
||||||
*/
|
|
||||||
static void *get_poisoned( void *ptr, size_t size_w_poison ) {
|
|
||||||
if (size_w_poison != 0 && ptr != NULL) {
|
|
||||||
|
|
||||||
/* Poison beginning and the end of the allocated chunk */
|
|
||||||
put_poison(ptr + sizeof(UMM_POISONED_BLOCK_LEN_TYPE),
|
|
||||||
UMM_POISON_SIZE_BEFORE);
|
|
||||||
put_poison(ptr + size_w_poison - UMM_POISON_SIZE_AFTER,
|
|
||||||
UMM_POISON_SIZE_AFTER);
|
|
||||||
|
|
||||||
/* Put exact length of the user's chunk of memory */
|
|
||||||
*(UMM_POISONED_BLOCK_LEN_TYPE *)ptr = (UMM_POISONED_BLOCK_LEN_TYPE)size_w_poison;
|
|
||||||
|
|
||||||
/* Return pointer at the first non-poisoned byte */
|
|
||||||
return ptr + sizeof(UMM_POISONED_BLOCK_LEN_TYPE) + UMM_POISON_SIZE_BEFORE;
|
|
||||||
} else {
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Takes "poisoned" pointer (i.e. pointer returned from `get_poisoned()`),
|
|
||||||
* and checks that the poison of this particular block is still there.
|
|
||||||
*
|
|
||||||
* Returns unpoisoned pointer, i.e. actual pointer to the allocated memory.
|
|
||||||
*/
|
|
||||||
static void *get_unpoisoned( void *ptr ) {
|
|
||||||
if (ptr != NULL) {
|
|
||||||
uint8_t c;
|
|
||||||
|
|
||||||
ptr -= (sizeof(UMM_POISONED_BLOCK_LEN_TYPE) + UMM_POISON_SIZE_BEFORE);
|
|
||||||
|
|
||||||
/* Figure out which block we're in. Note the use of truncated division... */
|
|
||||||
c = (((void *)ptr)-(void *)(&(umm_heap[0])))/sizeof(umm_block);
|
|
||||||
|
|
||||||
check_poison_block(&UMM_BLOCK(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* }}} */
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
void *umm_poison_malloc( size_t size ) {
|
|
||||||
void *ret;
|
|
||||||
|
|
||||||
size += poison_size(size);
|
|
||||||
|
|
||||||
ret = umm_malloc( size );
|
|
||||||
|
|
||||||
ret = get_poisoned(ret, size);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
void *umm_poison_calloc( size_t num, size_t item_size ) {
|
|
||||||
void *ret;
|
|
||||||
size_t size = item_size * num;
|
|
||||||
|
|
||||||
size += poison_size(size);
|
|
||||||
|
|
||||||
ret = umm_malloc(size);
|
|
||||||
|
|
||||||
if (NULL != ret)
|
|
||||||
memset(ret, 0x00, size);
|
|
||||||
|
|
||||||
ret = get_poisoned(ret, size);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
void *umm_poison_realloc( void *ptr, size_t size ) {
|
|
||||||
void *ret;
|
|
||||||
|
|
||||||
ptr = get_unpoisoned(ptr);
|
|
||||||
|
|
||||||
size += poison_size(size);
|
|
||||||
ret = umm_realloc( ptr, size );
|
|
||||||
|
|
||||||
ret = get_poisoned(ret, size);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
void umm_poison_free( void *ptr ) {
|
|
||||||
|
|
||||||
ptr = get_unpoisoned(ptr);
|
|
||||||
|
|
||||||
umm_free( ptr );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Iterates through all blocks in the heap, and checks poison for all used
|
|
||||||
* blocks.
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool umm_poison_check(void) {
|
|
||||||
bool ok = true;
|
|
||||||
unsigned short int cur;
|
|
||||||
|
|
||||||
if (umm_heap == NULL) {
|
|
||||||
umm_init();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Now iterate through the blocks list */
|
|
||||||
cur = UMM_NBLOCK(0) & UMM_BLOCKNO_MASK;
|
|
||||||
|
|
||||||
while( UMM_NBLOCK(cur) & UMM_BLOCKNO_MASK ) {
|
|
||||||
if ( !(UMM_NBLOCK(cur) & UMM_FREELIST_MASK) ) {
|
|
||||||
/* This is a used block (not free), so, check its poison */
|
|
||||||
ok = check_poison_block(&UMM_BLOCK(cur));
|
|
||||||
if (!ok){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
cur = UMM_NBLOCK(cur) & UMM_BLOCKNO_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ok;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* ------------------------------------------------------------------------ */
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -1,301 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: utils.c
|
|
||||||
// Created: January 2019
|
|
||||||
// Author(s): Philip Smart
|
|
||||||
// Description: ZPU boottime utilities.
|
|
||||||
// A set of utilities to be used by ZPU applications which can assume that most C
|
|
||||||
// functionality is available, such as printf.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2019 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: January 2019 - Initial script written.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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 <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "usb_serial.h"
|
|
||||||
#include "k64f_soc.h"
|
|
||||||
#include <../libraries/include/stdmisc.h>
|
|
||||||
#elif defined __ZPU__
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdmisc.h>
|
|
||||||
#include "uart.h"
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
#if defined __SHARPMZ__
|
|
||||||
#include "sharpmz.h"
|
|
||||||
#endif
|
|
||||||
#elif defined __M68K__
|
|
||||||
#include <stdio.h>
|
|
||||||
// #include <stdint.h>
|
|
||||||
// #include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__SD_CARD__)
|
|
||||||
#include "ff.h"
|
|
||||||
#endif
|
|
||||||
#include "utils.h"
|
|
||||||
|
|
||||||
#if defined(__ZPU__)
|
|
||||||
// Functions, in the absense of printf, to output a value as hex.
|
|
||||||
// Nibble :- a single digit 0-f
|
|
||||||
void printnibble(uint8_t c)
|
|
||||||
{
|
|
||||||
c&=0xf;
|
|
||||||
if (c>9)
|
|
||||||
fputc(c+'a'-10, stdout);
|
|
||||||
else
|
|
||||||
fputc(c+'0', stdout);
|
|
||||||
}
|
|
||||||
// Byte: 8 bits represented by 2 digits, <0-f><0-f>
|
|
||||||
void printhexbyte(uint8_t c)
|
|
||||||
{
|
|
||||||
printnibble(c>>4);
|
|
||||||
printnibble(c);
|
|
||||||
}
|
|
||||||
// Half Word: 16 bits represented by 4 digits.
|
|
||||||
void printhex(uint32_t c)
|
|
||||||
{
|
|
||||||
printhexbyte((uint8_t)(c>>8));
|
|
||||||
printhexbyte((uint8_t)(c));
|
|
||||||
}
|
|
||||||
// Word: 32 bits represented by 8 digits.
|
|
||||||
void printdhex(uint32_t c)
|
|
||||||
{
|
|
||||||
printhexbyte((uint8_t)(c>>24));
|
|
||||||
printhexbyte((uint8_t)(c>>16));
|
|
||||||
printhexbyte((uint8_t)(c>>8));
|
|
||||||
printhexbyte((uint8_t)(c));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#if defined(ABCD)
|
|
||||||
// Function to setup the CRC polynomial table prior to use.
|
|
||||||
//
|
|
||||||
static unsigned int crc32table[256];
|
|
||||||
unsigned int crc32_init(void)
|
|
||||||
{
|
|
||||||
int j;
|
|
||||||
unsigned int byte, crc, mask;
|
|
||||||
|
|
||||||
for(byte = 0; byte <= 255; byte++)
|
|
||||||
{
|
|
||||||
crc = byte;
|
|
||||||
for (j = 7; j >= 0; j--)
|
|
||||||
{
|
|
||||||
mask = -(crc & 1);
|
|
||||||
crc = (crc >> 1) ^ (0xEDB88320 & mask);
|
|
||||||
}
|
|
||||||
crc32table[byte] = crc;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Starting value for CRC calculation.
|
|
||||||
//
|
|
||||||
return 0xFFFFFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to add a word into the CRC sum.
|
|
||||||
//
|
|
||||||
unsigned int crc32_addword(unsigned int crc_in, unsigned int word)
|
|
||||||
{
|
|
||||||
crc_in = (crc_in >> 8) ^ crc32table[(crc_in ^ ((word >> 24)&0xFF)) & 0xFF];
|
|
||||||
crc_in = (crc_in >> 8) ^ crc32table[(crc_in ^ ((word >> 16)&0xFF)) & 0xFF];
|
|
||||||
crc_in = (crc_in >> 8) ^ crc32table[(crc_in ^ ((word >> 8)&0xFF)) & 0xFF];
|
|
||||||
crc_in = (crc_in >> 8) ^ crc32table[(crc_in ^ (word &0xFF)) & 0xFF];
|
|
||||||
|
|
||||||
return crc_in;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Function to read a 32bit word from the active serial port.
|
|
||||||
//
|
|
||||||
unsigned int get_dword(void)
|
|
||||||
{
|
|
||||||
unsigned int temp = 0;
|
|
||||||
int idx;
|
|
||||||
|
|
||||||
for(idx=0; idx < 4; idx++)
|
|
||||||
{
|
|
||||||
temp = (temp << 8) | (unsigned int)getKey(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
return(temp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to parse a buffer and return a pointer to the first string encountered. The string will be null terminated
|
|
||||||
// and the callers pointer advanced to the next argument.
|
|
||||||
char *getStrParam(char **ptr)
|
|
||||||
{
|
|
||||||
char *paramptr = (*ptr);
|
|
||||||
char *spaceptr;
|
|
||||||
uint8_t inQuotes = 0;
|
|
||||||
|
|
||||||
// If no parameter available, exit.
|
|
||||||
if(*ptr == 0x0)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
// Find the end of the command and terminate it.
|
|
||||||
while(*paramptr == ' ') paramptr++;
|
|
||||||
if(*paramptr == '"') { paramptr++; inQuotes=1; }
|
|
||||||
spaceptr = paramptr;
|
|
||||||
if(inQuotes == 1)
|
|
||||||
{
|
|
||||||
while(*spaceptr != '"' && *spaceptr != 0x00) spaceptr++;
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
while(*spaceptr != ' ' && *spaceptr != 0x00) spaceptr++;
|
|
||||||
}
|
|
||||||
if(*spaceptr == ' ' || *spaceptr == '"') { (*spaceptr) = 0x00; spaceptr++; }
|
|
||||||
|
|
||||||
// Callers pointer is advanced to the next argument or end of string.
|
|
||||||
(*ptr) = spaceptr;
|
|
||||||
|
|
||||||
// Return the pointer to the start of the argument.
|
|
||||||
return(paramptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to parse a buffer and extract a 32bit unsigned integer. The callers pointer is then
|
|
||||||
// advanced to the next argument.
|
|
||||||
// 0 is returned if any error encountered and the callers pointed remains unchanged.
|
|
||||||
uint32_t getUintParam(char **ptr)
|
|
||||||
{
|
|
||||||
uint32_t result;
|
|
||||||
|
|
||||||
// If no parameter available, exit.
|
|
||||||
if(*ptr == 0x0 || !uxatoi(ptr, &result))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to set the RTC.
|
|
||||||
//
|
|
||||||
uint8_t rtcSet(RTC *time)
|
|
||||||
{
|
|
||||||
// Validate the incoming data.
|
|
||||||
//
|
|
||||||
if(time->month < 1 || time->month > 12) return(1);
|
|
||||||
if(time->day < 1 || time->day > 31) return(2);
|
|
||||||
if(time->hour > 23) return(3);
|
|
||||||
if(time->min > 59) return(4);
|
|
||||||
if(time->sec > 59) return(5);
|
|
||||||
if(time->msec > 999) return(6);
|
|
||||||
if(time->usec > 999) return(7);
|
|
||||||
|
|
||||||
#if defined __ZPU__
|
|
||||||
// Stop the clock, update the values and restart.
|
|
||||||
RTC_CONTROL = RTC_CTRL_HALT;
|
|
||||||
RTC_YEAR = time->year;
|
|
||||||
RTC_MONTH = time->month;
|
|
||||||
RTC_DAY = time->day;
|
|
||||||
RTC_HOUR = time->hour;
|
|
||||||
RTC_MINUTE = time->min;
|
|
||||||
RTC_SECOND = time->sec;
|
|
||||||
RTC_MILLISECONDS = time->msec;
|
|
||||||
RTC_MICROSECONDS = time->usec;
|
|
||||||
RTC_CONTROL = 0;
|
|
||||||
#endif
|
|
||||||
#if defined __K64F__
|
|
||||||
dbg_puts("RTC Not yet implemented.\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Success.
|
|
||||||
return(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to read from the RTC.
|
|
||||||
//
|
|
||||||
void rtcGet(RTC *time)
|
|
||||||
{
|
|
||||||
#if defined __ZPU__
|
|
||||||
// Read directly into the static RTC record.
|
|
||||||
RTC_CONTROL = RTC_CTRL_HALT;
|
|
||||||
time->year = RTC_YEAR;
|
|
||||||
time->month = RTC_MONTH;
|
|
||||||
time->day = RTC_DAY;
|
|
||||||
time->hour = RTC_HOUR;
|
|
||||||
time->min = RTC_MINUTE;
|
|
||||||
time->sec = RTC_SECOND;
|
|
||||||
time->msec = RTC_MILLISECONDS;
|
|
||||||
time->usec = RTC_MICROSECONDS;
|
|
||||||
RTC_CONTROL = 0;
|
|
||||||
#endif
|
|
||||||
#if defined __K64F__
|
|
||||||
dbg_puts("RTC Not yet implemented.\n");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
printf("%d/%d/%d %d:%d:%d.%d%d\n",time->year, time->month, time->day, time->hour, time->min, time->sec, time->msec, time->usec);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to get a key from the input device (serial port/keyboard) according to the host for which this code is compiled.
|
|
||||||
// Input: mode = 0 - No blocking, standard keyboard.
|
|
||||||
// 1 - blocking, standard keyboard.
|
|
||||||
// 2 - No blocking, ansi keyboard. -- Sharp MZ build only.
|
|
||||||
// 3 - blocking, ansi keyboard. -- Sharp MZ build only.
|
|
||||||
// Return: -1 = no key pressed.
|
|
||||||
// ASCII value when key pressed.
|
|
||||||
//
|
|
||||||
int8_t getKey(uint8_t mode)
|
|
||||||
{
|
|
||||||
int8_t keyIn;
|
|
||||||
|
|
||||||
do {
|
|
||||||
#if defined __K64F__
|
|
||||||
int usb_serial_getchar(void);
|
|
||||||
keyIn = usb_serial_getchar();
|
|
||||||
#elif defined __ZPU__
|
|
||||||
#if defined __SHARPMZ__
|
|
||||||
|
|
||||||
keyIn = mzGetKey(mode);
|
|
||||||
#else
|
|
||||||
if(mode == 1 || mode == 3)
|
|
||||||
{
|
|
||||||
keyIn = getserial();
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
keyIn = getserial_nonblocking();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#elif defined __M68K__
|
|
||||||
#else
|
|
||||||
#error "Target CPU not defined, use __ZPU__ or __K64F__"
|
|
||||||
#endif
|
|
||||||
} while(keyIn == -1 && (mode == 1 || mode == 3));
|
|
||||||
|
|
||||||
return(keyIn);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method as above but non blocking.
|
|
||||||
//
|
|
||||||
int8_t getKeyNonBlocking(void)
|
|
||||||
{
|
|
||||||
return(getKey(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
@@ -1,301 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: zpu_soc.c
|
|
||||||
// Created: January 2019
|
|
||||||
// Author(s): Philip Smart
|
|
||||||
// Description: ZPU System On a Chip utilities.
|
|
||||||
// A set of utilities specific to interaction with the ZPU SoC hardware.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2019 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: January 2019 - Initial script written.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "uart.h"
|
|
||||||
#include "zpu_soc.h"
|
|
||||||
|
|
||||||
// Global scope variables.
|
|
||||||
#ifdef USE_BOOT_ROM
|
|
||||||
SOC_CONFIG cfgSoC;
|
|
||||||
#else
|
|
||||||
SOC_CONFIG cfgSoC = { .addrInsnBRAM = INSN_BRAM_ADDR,
|
|
||||||
.sizeInsnBRAM = INSN_BRAM_SIZE,
|
|
||||||
.addrBRAM = BRAM_ADDR,
|
|
||||||
.sizeBRAM = BRAM_SIZE,
|
|
||||||
.addrRAM = RAM_ADDR,
|
|
||||||
.sizeRAM = RAM_SIZE,
|
|
||||||
.addrSDRAM = SDRAM_ADDR,
|
|
||||||
.sizeSDRAM = SDRAM_SIZE,
|
|
||||||
.addrWBSDRAM = WB_SDRAM_ADDR,
|
|
||||||
.sizeWBSDRAM = WB_SDRAM_SIZE,
|
|
||||||
.resetVector = CPU_RESET_ADDR,
|
|
||||||
.cpuMemBaseAddr = CPU_MEM_START,
|
|
||||||
.stackStartAddr = STACK_BRAM_ADDR,
|
|
||||||
.zpuId = ZPU_ID,
|
|
||||||
.sysFreq = CLK_FREQ,
|
|
||||||
.memFreq = CLK_FREQ,
|
|
||||||
.wbMemFreq = CLK_FREQ,
|
|
||||||
.implSoCCFG = 0,
|
|
||||||
.implWB = WB_IMPL,
|
|
||||||
.implWBSDRAM = WB_SDRAM_IMPL,
|
|
||||||
.implWBI2C = WB_I2C_IMPL,
|
|
||||||
.implInsnBRAM = INSN_BRAM_IMPL,
|
|
||||||
.implBRAM = BRAM_IMPL,
|
|
||||||
.implRAM = RAM_IMPL,
|
|
||||||
.implSDRAM = SDRAM_IMPL,
|
|
||||||
.implIOCTL = IOCTL_IMPL,
|
|
||||||
.implPS2 = PS2_IMPL,
|
|
||||||
.implSPI = SPI_IMPL,
|
|
||||||
.implSD = SD_IMPL,
|
|
||||||
.sdCardNo = SD_DEVICE_CNT,
|
|
||||||
.implIntrCtl = INTRCTL_IMPL,
|
|
||||||
.intrChannels = INTRCTL_CHANNELS,
|
|
||||||
.implTimer1 = TIMER1_IMPL,
|
|
||||||
.timer1No = TIMER1_TIMERS_CNT };
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Method to populate the Configuration structure, initially using in-built values from compile time
|
|
||||||
// which are overriden with values stored in the SoC if available.
|
|
||||||
void setupSoCConfig(void)
|
|
||||||
{
|
|
||||||
// If the SoC Configuration register is implemented in the SoC, overwrite the compiled constants with those in the chip register.
|
|
||||||
if( IS_IMPL_SOCCFG )
|
|
||||||
{
|
|
||||||
cfgSoC.addrInsnBRAM = SOCCFG(SOCCFG_BRAMINSNADDR);
|
|
||||||
cfgSoC.sizeInsnBRAM = SOCCFG(SOCCFG_BRAMINSNSIZE);
|
|
||||||
cfgSoC.addrBRAM = SOCCFG(SOCCFG_BRAMADDR);
|
|
||||||
cfgSoC.sizeBRAM = SOCCFG(SOCCFG_BRAMSIZE);
|
|
||||||
cfgSoC.addrRAM = SOCCFG(SOCCFG_RAMADDR);
|
|
||||||
cfgSoC.sizeRAM = SOCCFG(SOCCFG_RAMSIZE);
|
|
||||||
cfgSoC.addrSDRAM = SOCCFG(SOCCFG_SDRAMADDR);
|
|
||||||
cfgSoC.sizeSDRAM = SOCCFG(SOCCFG_SDRAMSIZE);
|
|
||||||
cfgSoC.addrWBSDRAM = SOCCFG(SOCCFG_WBSDRAMADDR);
|
|
||||||
cfgSoC.sizeWBSDRAM = SOCCFG(SOCCFG_WBSDRAMSIZE);
|
|
||||||
cfgSoC.resetVector = SOCCFG(SOCCFG_CPURSTADDR);
|
|
||||||
cfgSoC.cpuMemBaseAddr = SOCCFG(SOCCFG_CPUMEMSTART);
|
|
||||||
cfgSoC.stackStartAddr = SOCCFG(SOCCFG_STACKSTART);
|
|
||||||
cfgSoC.zpuId = SOCCFG(SOCCFG_ZPU_ID);
|
|
||||||
cfgSoC.sysFreq = SOCCFG(SOCCFG_SYSFREQ);
|
|
||||||
cfgSoC.memFreq = SOCCFG(SOCCFG_MEMFREQ);
|
|
||||||
cfgSoC.wbMemFreq = SOCCFG(SOCCFG_WBMEMFREQ);
|
|
||||||
cfgSoC.implSoCCFG = 1;
|
|
||||||
cfgSoC.implWB = IS_IMPL_WB != 0;
|
|
||||||
cfgSoC.implWBSDRAM = IS_IMPL_WB_SDRAM != 0;
|
|
||||||
cfgSoC.implWBI2C = IS_IMPL_WB_I2C != 0;
|
|
||||||
cfgSoC.implInsnBRAM = IS_IMPL_INSN_BRAM != 0;
|
|
||||||
cfgSoC.implBRAM = IS_IMPL_BRAM != 0;
|
|
||||||
cfgSoC.implRAM = IS_IMPL_RAM != 0;
|
|
||||||
cfgSoC.implSDRAM = IS_IMPL_SDRAM != 0;
|
|
||||||
cfgSoC.implIOCTL = IS_IMPL_IOCTL != 0;
|
|
||||||
cfgSoC.implPS2 = IS_IMPL_PS2 != 0;
|
|
||||||
cfgSoC.implSPI = IS_IMPL_SPI != 0;
|
|
||||||
cfgSoC.implSD = IS_IMPL_SD != 0;
|
|
||||||
cfgSoC.sdCardNo = (uint8_t)(SOCCFG_SD_DEVICES);
|
|
||||||
cfgSoC.implIntrCtl = IS_IMPL_INTRCTL != 0;
|
|
||||||
cfgSoC.intrChannels = (uint8_t)(SOCCFG_INTRCTL_CHANNELS);
|
|
||||||
cfgSoC.implTimer1 = IS_IMPL_TIMER1 != 0;
|
|
||||||
cfgSoC.timer1No = (uint8_t)(SOCCFG_TIMER1_TIMERS);
|
|
||||||
#ifndef USE_BOOT_ROM
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
// Store builtin constants into structure which will be used when the SoC configuration module isnt implemented.
|
|
||||||
cfgSoC.addrInsnBRAM = INSN_BRAM_ADDR;
|
|
||||||
cfgSoC.sizeInsnBRAM = INSN_BRAM_SIZE;
|
|
||||||
cfgSoC.addrBRAM = BRAM_ADDR;
|
|
||||||
cfgSoC.sizeBRAM = BRAM_SIZE;
|
|
||||||
cfgSoC.addrRAM = RAM_ADDR;
|
|
||||||
cfgSoC.sizeRAM = RAM_SIZE;
|
|
||||||
cfgSoC.addrSDRAM = SDRAM_ADDR;
|
|
||||||
cfgSoC.sizeSDRAM = SDRAM_SIZE;
|
|
||||||
cfgSoC.addrWBSDRAM = WB_SDRAM_ADDR;
|
|
||||||
cfgSoC.sizeWBSDRAM = WB_SDRAM_SIZE;
|
|
||||||
cfgSoC.resetVector = CPU_RESET_ADDR;
|
|
||||||
cfgSoC.cpuMemBaseAddr = CPU_MEM_START;
|
|
||||||
cfgSoC.stackStartAddr = STACK_BRAM_ADDR;
|
|
||||||
cfgSoC.zpuId = ZPU_ID;
|
|
||||||
cfgSoC.sysFreq = CLK_FREQ;
|
|
||||||
cfgSoC.memFreq = CLK_FREQ;
|
|
||||||
cfgSoC.wbMemFreq = CLK_FREQ;
|
|
||||||
cfgSoC.implSoCCFG = 0;
|
|
||||||
cfgSoC.implWB = WB_IMPL;
|
|
||||||
cfgSoC.implWBSDRAM = WB_SDRAM_IMPL;
|
|
||||||
cfgSoC.implWBI2C = WB_I2C_IMPL;
|
|
||||||
cfgSoC.implInsnBRAM = INSN_BRAM_IMPL;
|
|
||||||
cfgSoC.implBRAM = BRAM_IMPL ;
|
|
||||||
cfgSoC.implRAM = RAM_IMPL;
|
|
||||||
cfgSoC.implSDRAM = SDRAM_IMPL;;
|
|
||||||
cfgSoC.implIOCTL = IOCTL_IMPL;;
|
|
||||||
cfgSoC.implPS2 = PS2_IMPL;
|
|
||||||
cfgSoC.implSPI = SPI_IMPL;
|
|
||||||
cfgSoC.implSD = IMPL_SD;
|
|
||||||
cfgSoC.sdCardNo = SD_DEVICE_CNT;
|
|
||||||
cfgSoC.implIntrCtl = INTRCTL_IMPL;
|
|
||||||
cfgSoC.intrChannels = INTRCTL_CHANNELS;
|
|
||||||
cfgSoC.implTimer1 = TIMER1_IMPL;
|
|
||||||
cfgSoC.timer1No = TIMER1_TIMERS_CNT;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to show the current configuration via the primary uart channel.
|
|
||||||
//
|
|
||||||
#if !defined(FUNCTIONALITY) || FUNCTIONALITY <= 1
|
|
||||||
void showSoCConfig(void)
|
|
||||||
{
|
|
||||||
#if defined(__ZOS__) || defined(__ZPUTA__)
|
|
||||||
printf("SoC Configuration");
|
|
||||||
if(cfgSoC.implSoCCFG) { printf(" (from SoC config)"); }
|
|
||||||
printf(":\nDevices implemented:\n");
|
|
||||||
if(cfgSoC.implWBSDRAM) { printf(" WB SDRAM (%08X:%08X).\n", cfgSoC.addrWBSDRAM, cfgSoC.addrWBSDRAM + cfgSoC.sizeWBSDRAM); }
|
|
||||||
if(cfgSoC.implSDRAM) { printf(" SDRAM (%08X:%08X).\n", cfgSoC.addrSDRAM, cfgSoC.addrSDRAM + cfgSoC.sizeSDRAM); }
|
|
||||||
if(cfgSoC.implInsnBRAM) { printf(" INSN BRAM (%08X:%08X).\n", cfgSoC.addrInsnBRAM, cfgSoC.addrInsnBRAM + cfgSoC.sizeInsnBRAM); }
|
|
||||||
if(cfgSoC.implBRAM) { printf(" BRAM (%08X:%08X).\n", cfgSoC.addrBRAM, cfgSoC.addrBRAM + cfgSoC.sizeBRAM); }
|
|
||||||
if(cfgSoC.implRAM) { printf(" RAM (%08X:%08X).\n", cfgSoC.addrRAM, cfgSoC.addrRAM + cfgSoC.sizeRAM); }
|
|
||||||
if(cfgSoC.implSD) { printf(" SD CARD (Devices =%02d).\n", (uint8_t)cfgSoC.sdCardNo); }
|
|
||||||
if(cfgSoC.implTimer1) { printf(" TIMER1 (Timers =%02d).\n", (uint8_t)cfgSoC.timer1No); }
|
|
||||||
if(cfgSoC.implIntrCtl) { printf(" INTR CTRL (Channels=%02d).\n", (uint8_t)cfgSoC.intrChannels); }
|
|
||||||
if(cfgSoC.implWB) { printf(" WISHBONE BUS\n"); }
|
|
||||||
if(cfgSoC.implWBI2C) { printf(" WB I2C\n"); }
|
|
||||||
if(cfgSoC.implIOCTL) { printf(" IOCTL\n"); }
|
|
||||||
if(cfgSoC.implPS2) { printf(" PS2\n"); }
|
|
||||||
if(cfgSoC.implSPI) { printf(" SPI\n"); }
|
|
||||||
printf("Addresses:\n");
|
|
||||||
printf(" CPU Reset Vector Address = %08X\n", cfgSoC.resetVector);
|
|
||||||
printf(" CPU Memory Start Address = %08X\n", cfgSoC.cpuMemBaseAddr);
|
|
||||||
printf(" Stack Start Address = %08X\n", cfgSoC.stackStartAddr);
|
|
||||||
printf("Misc:\n");
|
|
||||||
printf(" ZPU Id = %04X\n", cfgSoC.zpuId);
|
|
||||||
printf(" System Clock Freq = %d.%04dMHz\n", (cfgSoC.sysFreq / 1000000), cfgSoC.sysFreq - ((cfgSoC.sysFreq / 1000000) * 1000000));
|
|
||||||
if(cfgSoC.implSDRAM)
|
|
||||||
printf(" SDRAM Clock Freq = %d.%04dMHz\n", (cfgSoC.memFreq / 1000000), cfgSoC.memFreq - ((cfgSoC.memFreq / 1000000) * 1000000));
|
|
||||||
if(cfgSoC.implWBSDRAM)
|
|
||||||
printf(" Wishbone SDRAM Clock Freq= %d.%04dMHz\n", (cfgSoC.wbMemFreq / 1000000), cfgSoC.wbMemFreq - ((cfgSoC.wbMemFreq / 1000000) * 1000000));
|
|
||||||
#ifdef DRV_CFC
|
|
||||||
printf(" CFC = %08X\n", DRV_CFC);
|
|
||||||
#endif
|
|
||||||
#ifdef DRV_MMC
|
|
||||||
printf(" MMC = %08X\n", DRV_MMC);
|
|
||||||
#endif
|
|
||||||
//printf("\n");
|
|
||||||
#else
|
|
||||||
puts("SoC Configuration");
|
|
||||||
if(cfgSoC.implSoCCFG) { puts(" (from SoC config)"); }
|
|
||||||
puts(":\nDevices implemented:\n");
|
|
||||||
if(cfgSoC.implWBSDRAM) { puts(" WB SDRAM ("); printdhex(cfgSoC.addrWBSDRAM); puts(":"); printdhex(cfgSoC.addrWBSDRAM + cfgSoC.sizeWBSDRAM); puts(").\n"); }
|
|
||||||
if(cfgSoC.implSDRAM) { puts(" SDRAM ("); printdhex(cfgSoC.addrSDRAM); puts(":"); printdhex(cfgSoC.addrSDRAM + cfgSoC.sizeSDRAM); puts(").\n"); }
|
|
||||||
if(cfgSoC.implInsnBRAM) { puts(" INSN BRAM ("); printdhex(cfgSoC.addrInsnBRAM); puts(":"); printdhex(cfgSoC.addrInsnBRAM + cfgSoC.sizeInsnBRAM); puts(").\n"); }
|
|
||||||
if(cfgSoC.implBRAM) { puts(" BRAM ("); printdhex(cfgSoC.addrBRAM); puts(":"); printdhex(cfgSoC.addrBRAM + cfgSoC.sizeBRAM); puts(").\n"); }
|
|
||||||
if(cfgSoC.implRAM) { puts(" RAM ("); printdhex(cfgSoC.addrRAM); puts(":"); printdhex(cfgSoC.addrRAM + cfgSoC.sizeRAM); puts(").\n"); }
|
|
||||||
if(cfgSoC.implSD) { puts(" SD CARD (Devices ="); printhexbyte((uint8_t)cfgSoC.sdCardNo); puts(").\n"); }
|
|
||||||
if(cfgSoC.implTimer1) { puts(" TIMER1 (Timers ="); printnibble( (uint8_t)cfgSoC.timer1No); puts(").\n"); }
|
|
||||||
if(cfgSoC.implIntrCtl) { puts(" INTR CTRL (Channels="); printhexbyte((uint8_t)cfgSoC.intrChannels); puts(").\n"); }
|
|
||||||
if(cfgSoC.implWB) { puts(" WISHBONE BUS\n"); }
|
|
||||||
if(cfgSoC.implWB) { puts(" WB I2C\n"); }
|
|
||||||
if(cfgSoC.implIOCTL) { puts(" IOCTL\n"); }
|
|
||||||
if(cfgSoC.implPS2) { puts(" PS2\n"); }
|
|
||||||
if(cfgSoC.implSPI) { puts(" SPI\n"); }
|
|
||||||
puts("Addresses:\n");
|
|
||||||
puts(" CPU Reset Vector Address = "); printdhex(cfgSoC.resetVector); puts("\n");
|
|
||||||
puts(" CPU Memory Start Address = "); printdhex(cfgSoC.cpuMemBaseAddr); puts("\n");
|
|
||||||
puts(" Stack Start Address = "); printdhex(cfgSoC.stackStartAddr); puts("\n");
|
|
||||||
puts("Misc:\n");
|
|
||||||
puts(" ZPU Id = "); printhex((uint16_t)cfgSoC.zpuId); puts("\n");
|
|
||||||
puts(" System Clock Freq = "); printdhex(cfgSoC.sysFreq); puts("\n");
|
|
||||||
if(cfgSoC.implSDRAM)
|
|
||||||
puts(" SDRAM Clock Freq = "); printdhex(cfgSoC.memFreq); puts("\n");
|
|
||||||
if(cfgSoC.implWBSDRAM)
|
|
||||||
puts(" Wishbone SDRAM Clock Freq= "); printdhex(cfgSoC.wbMemFreq); puts("\n");
|
|
||||||
#ifdef DRV_CFC
|
|
||||||
puts(" CFC = "); printdhex(DRV_CFC); puts("\n");
|
|
||||||
#endif
|
|
||||||
#ifdef DRV_MMC
|
|
||||||
puts(" MMC = "); printdhex(DRV_MMC); puts("\n");
|
|
||||||
#endif
|
|
||||||
puts("\n");
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// Function to print out the ZPU Id in text form.
|
|
||||||
void printZPUId(uint32_t zpuId)
|
|
||||||
{
|
|
||||||
switch((uint8_t)(zpuId >> 8))
|
|
||||||
{
|
|
||||||
case ZPU_ID_SMALL:
|
|
||||||
#if defined __IOCP__
|
|
||||||
puts("Small");
|
|
||||||
#else
|
|
||||||
printf("Small");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZPU_ID_MEDIUM:
|
|
||||||
#if defined __IOCP__
|
|
||||||
puts("Medium");
|
|
||||||
#else
|
|
||||||
printf("Medium");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZPU_ID_FLEX:
|
|
||||||
#if defined __IOCP__
|
|
||||||
puts("Flex");
|
|
||||||
#else
|
|
||||||
printf("Flex");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZPU_ID_EVO:
|
|
||||||
#if defined __IOCP__
|
|
||||||
puts("EVO");
|
|
||||||
#else
|
|
||||||
printf("EVO");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ZPU_ID_EVO_MINIMAL:
|
|
||||||
#if defined __IOCP__
|
|
||||||
puts("EVOm");
|
|
||||||
#else
|
|
||||||
printf("EVOm");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
#if defined __IOCP__
|
|
||||||
puts("Unknown");
|
|
||||||
#else
|
|
||||||
printf("Unknown");
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
1
zOS/MZ2000/docs
vendored
1
zOS/MZ2000/docs
vendored
@@ -1 +0,0 @@
|
|||||||
/dvlp/Projects/zSoft/docs
|
|
||||||
63
zOS/MZ2000/include/bitmaps.h
vendored
63
zOS/MZ2000/include/bitmaps.h
vendored
@@ -1,63 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: bitmaps.h
|
|
||||||
// Created: May 2021
|
|
||||||
// Version: v1.0
|
|
||||||
// Author(s): Williams, Philip Smart
|
|
||||||
// Description: The Bitmap Library.
|
|
||||||
// This is a bitmap definition and manipulation library.
|
|
||||||
// for use with the Sharp MZ Series OSD./
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2019-2021 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: May 2021 - Initial write of the OSD software.
|
|
||||||
//
|
|
||||||
// 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 BITMAPS_H
|
|
||||||
#define BITMAPS_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Supported bitmaps.
|
|
||||||
enum BITMAPS {
|
|
||||||
BITMAP_ARGO = 0x00, // Large Argo logo.
|
|
||||||
BITMAP_ARGO_MEDIUM = 0x01, // Medium Argo logo.
|
|
||||||
BITMAP_ARGO_SMALL = 0x02 // Small Argo logo.
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t *bitmap; // The bitmap data to represent the image
|
|
||||||
uint16_t width; // The width of the font in pixels
|
|
||||||
uint16_t height; // The height of the font in pixels
|
|
||||||
} bitmapStruct;
|
|
||||||
|
|
||||||
extern const bitmapStruct argo256x128;
|
|
||||||
extern const bitmapStruct argo128x64;
|
|
||||||
extern const bitmapStruct argo64x32;
|
|
||||||
|
|
||||||
|
|
||||||
// Prototypes.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // BITMAPS_H
|
|
||||||
1092
zOS/MZ2000/include/emumz.h
vendored
1092
zOS/MZ2000/include/emumz.h
vendored
File diff suppressed because it is too large
Load Diff
139
zOS/MZ2000/include/fat.h
vendored
139
zOS/MZ2000/include/fat.h
vendored
@@ -1,139 +0,0 @@
|
|||||||
#ifndef _FAT16_H_INCLUDED
|
|
||||||
#define _FAT16_H_INCLUDED
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MAXDIRENTRIES 8
|
|
||||||
|
|
||||||
// FIXME - derive CHS address from FAT boot sector for card and partition mount modes.
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned int sector;
|
|
||||||
unsigned int index;
|
|
||||||
} entryTYPE;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
char name[11]; /* name of file */
|
|
||||||
unsigned char attributes; /* file attributes */
|
|
||||||
entryTYPE entry; /* file entry location */
|
|
||||||
unsigned int sector; /* sector index in file */
|
|
||||||
unsigned int size; /* file size */
|
|
||||||
unsigned int cluster; /* current cluster */
|
|
||||||
unsigned int start_cluster; /* first cluster of file */
|
|
||||||
char long_name[261];
|
|
||||||
} fileTYPE;
|
|
||||||
|
|
||||||
struct PartitionEntry
|
|
||||||
{
|
|
||||||
unsigned char geometry[8]; // ignored
|
|
||||||
unsigned long startlba;
|
|
||||||
unsigned long sectors;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct MasterBootRecord
|
|
||||||
{
|
|
||||||
unsigned char bootcode[446]; // ignored
|
|
||||||
struct PartitionEntry Partition[4]; // We copy these (and byteswap if need be)
|
|
||||||
unsigned short Signature; // This lets us detect an MBR (and the need for byteswapping).
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
extern struct PartitionEntry partitions[4]; // FirstBlock and LastBlock will be byteswapped as necessary
|
|
||||||
extern int partitioncount;
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
unsigned char Name[8]; /* filename, blank filled */
|
|
||||||
#define SLOT_EMPTY 0x00 /* slot has never been used */
|
|
||||||
#define SLOT_E5 0x05 /* the real value is 0xe5 */
|
|
||||||
#define SLOT_DELETED 0xe5 /* file in this slot deleted */
|
|
||||||
unsigned char Extension[3]; /* extension, blank filled */
|
|
||||||
unsigned char Attributes; /* file attributes */
|
|
||||||
#define ATTR_NORMAL 0x00 /* normal file */
|
|
||||||
#define ATTR_READONLY 0x01 /* file is readonly */
|
|
||||||
#define ATTR_HIDDEN 0x02 /* file is hidden */
|
|
||||||
#define ATTR_SYSTEM 0x04 /* file is a system file */
|
|
||||||
#define ATTR_VOLUME 0x08 /* entry is a volume label */
|
|
||||||
#define ATTR_DIRECTORY 0x10 /* entry is a directory name */
|
|
||||||
#define ATTR_ARCHIVE 0x20 /* file is new or modified */
|
|
||||||
#define ATTR_LFN 0x0F /* long file name entry */
|
|
||||||
unsigned char LowerCase; /* NT VFAT lower case flags */
|
|
||||||
#define LCASE_BASE 0x08 /* filename base in lower case */
|
|
||||||
#define LCASE_EXT 0x10 /* filename extension in lower case */
|
|
||||||
unsigned char CreateHundredth; /* hundredth of seconds in CTime */
|
|
||||||
unsigned short CreateTime; /* create time */
|
|
||||||
unsigned short CreateDate; /* create date */
|
|
||||||
unsigned short AccessDate; /* access date */
|
|
||||||
unsigned short HighCluster; /* high bytes of cluster number */
|
|
||||||
unsigned short ModifyTime; /* last update time */
|
|
||||||
unsigned short ModifyDate; /* last update date */
|
|
||||||
unsigned short StartCluster; /* starting cluster of file */
|
|
||||||
unsigned long FileSize; /* size of file in bytes */
|
|
||||||
} __attribute__((packed)) DIRENTRY;
|
|
||||||
|
|
||||||
typedef union {
|
|
||||||
unsigned short fat16[256];
|
|
||||||
unsigned long fat32[128];
|
|
||||||
} FATBUFFER;
|
|
||||||
|
|
||||||
#define FILETIME(h,m,s) (((h<<11)&0xF800)|((m<<5)&0x7E0)|((s/2)&0x1F))
|
|
||||||
#define FILEDATE(y,m,d) ((((y-1980)<<9)&0xFE00)|((m<<5)&0x1E0)|(d&0x1F))
|
|
||||||
|
|
||||||
// global sector buffer, data for read/write actions is stored here.
|
|
||||||
// BEWARE, this buffer is also used and thus trashed by all other functions
|
|
||||||
extern unsigned char sector_buffer[1024]; // sector buffer - room for 2 sectors, to ease reading data not sector-aligned...
|
|
||||||
extern char longfilename[260];
|
|
||||||
extern unsigned char cluster_size;
|
|
||||||
extern unsigned long cluster_mask;
|
|
||||||
extern unsigned char fat32;
|
|
||||||
|
|
||||||
// constants
|
|
||||||
#define DIRECTORY_ROOT 0
|
|
||||||
|
|
||||||
// file seeking
|
|
||||||
#define SEEK_SET 0
|
|
||||||
#define SEEK_CUR 1
|
|
||||||
|
|
||||||
// scanning flags
|
|
||||||
#define SCAN_INIT 0 // start search from beginning of directory
|
|
||||||
#define SCAN_NEXT 1 // find next file in directory
|
|
||||||
#define SCAN_PREV -1 // find previous file in directory
|
|
||||||
#define SCAN_NEXT_PAGE 2 // find next 8 files in directory
|
|
||||||
#define SCAN_PREV_PAGE -2 // find previous 8 files in directory
|
|
||||||
#define SCAN_INIT_FIRST 3 // search for an entry with given cluster number
|
|
||||||
#define SCAN_INIT_NEXT 4 // search for entries higher than the first one
|
|
||||||
|
|
||||||
// options flags
|
|
||||||
#define SCAN_DIR 1 // include subdirectories
|
|
||||||
#define SCAN_LFN 2 // include long file names
|
|
||||||
#define FIND_DIR 4 // find first directory beginning with given charater
|
|
||||||
#define FIND_FILE 8 // find first file entry beginning with given charater
|
|
||||||
|
|
||||||
|
|
||||||
// functions
|
|
||||||
unsigned int FindDrive(void);
|
|
||||||
unsigned long GetFATLink(unsigned long cluster);
|
|
||||||
unsigned int FileNextSector(fileTYPE *file);
|
|
||||||
unsigned int FileOpen(fileTYPE *file, const char *name);
|
|
||||||
unsigned int FileSeek(fileTYPE *file, unsigned long offset, unsigned long origin);
|
|
||||||
unsigned int FileRead(fileTYPE *file, unsigned char *pBuffer);
|
|
||||||
unsigned int FileWrite(fileTYPE *file, unsigned char *pBuffer);
|
|
||||||
//unsigned char FileReadEx(fileTYPE *file, unsigned char *pBuffer, unsigned long nSize);
|
|
||||||
|
|
||||||
unsigned int FileCreate(unsigned long iDirectory, fileTYPE *file);
|
|
||||||
unsigned int UpdateEntry(fileTYPE *file);
|
|
||||||
|
|
||||||
int ScanDirectory(unsigned long mode, char *extension, unsigned char options);
|
|
||||||
void ChangeDirectory(DIRENTRY *p);
|
|
||||||
|
|
||||||
DIRENTRY *NextDirEntry(int prev); // Must be called in ascending sequence, starting with 0
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
146
zOS/MZ2000/include/fileio.h
vendored
146
zOS/MZ2000/include/fileio.h
vendored
@@ -1,146 +0,0 @@
|
|||||||
/* Hosted File I/O interface definitions, for GDB, the GNU Debugger.
|
|
||||||
|
|
||||||
Copyright 2003 Free Software Foundation, Inc.
|
|
||||||
|
|
||||||
This program 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 2 of the
|
|
||||||
License, or (at your option) any later version.
|
|
||||||
|
|
||||||
This program 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, write to the Free Software
|
|
||||||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
|
|
||||||
02111-1307, USA. */
|
|
||||||
|
|
||||||
#ifndef GDB_FILEIO_H_
|
|
||||||
#define GDB_FILEIO_H_
|
|
||||||
|
|
||||||
/* The following flags are defined to be independent of the host
|
|
||||||
as well as the target side implementation of these constants.
|
|
||||||
All constants are defined with a leading FILEIO_ in the name
|
|
||||||
to allow the usage of these constants together with the
|
|
||||||
corresponding implementation dependent constants in one module. */
|
|
||||||
|
|
||||||
/* open(2) flags */
|
|
||||||
#define FILEIO_O_RDONLY 0x0
|
|
||||||
#define FILEIO_O_WRONLY 0x1
|
|
||||||
#define FILEIO_O_RDWR 0x2
|
|
||||||
#define FILEIO_O_APPEND 0x8
|
|
||||||
#define FILEIO_O_CREAT 0x200
|
|
||||||
#define FILEIO_O_TRUNC 0x400
|
|
||||||
#define FILEIO_O_EXCL 0x800
|
|
||||||
#define FILEIO_O_SUPPORTED (FILEIO_O_RDONLY | FILEIO_O_WRONLY| \
|
|
||||||
FILEIO_O_RDWR | FILEIO_O_APPEND| \
|
|
||||||
FILEIO_O_CREAT | FILEIO_O_TRUNC| \
|
|
||||||
FILEIO_O_EXCL)
|
|
||||||
|
|
||||||
/* mode_t bits */
|
|
||||||
#define FILEIO_S_IFREG 0100000
|
|
||||||
#define FILEIO_S_IFDIR 040000
|
|
||||||
#define FILEIO_S_IFCHR 020000
|
|
||||||
#define FILEIO_S_IRUSR 0400
|
|
||||||
#define FILEIO_S_IWUSR 0200
|
|
||||||
#define FILEIO_S_IXUSR 0100
|
|
||||||
#define FILEIO_S_IRWXU 0700
|
|
||||||
#define FILEIO_S_IRGRP 040
|
|
||||||
#define FILEIO_S_IWGRP 020
|
|
||||||
#define FILEIO_S_IXGRP 010
|
|
||||||
#define FILEIO_S_IRWXG 070
|
|
||||||
#define FILEIO_S_IROTH 04
|
|
||||||
#define FILEIO_S_IWOTH 02
|
|
||||||
#define FILEIO_S_IXOTH 01
|
|
||||||
#define FILEIO_S_IRWXO 07
|
|
||||||
#define FILEIO_S_SUPPORTED (FILEIO_S_IFREG|FILEIO_S_IFDIR| \
|
|
||||||
FILEIO_S_IRWXU|FILEIO_S_IRWXG| \
|
|
||||||
FILEIO_S_IRWXO)
|
|
||||||
|
|
||||||
/* lseek(2) flags */
|
|
||||||
#define FILEIO_SEEK_SET 0
|
|
||||||
#define FILEIO_SEEK_CUR 1
|
|
||||||
#define FILEIO_SEEK_END 2
|
|
||||||
|
|
||||||
/* errno values */
|
|
||||||
#define FILEIO_EPERM 1
|
|
||||||
#define FILEIO_ENOENT 2
|
|
||||||
#define FILEIO_EINTR 4
|
|
||||||
#define FILEIO_EIO 5
|
|
||||||
#define FILEIO_EBADF 9
|
|
||||||
#define FILEIO_EACCES 13
|
|
||||||
#define FILEIO_EFAULT 14
|
|
||||||
#define FILEIO_EBUSY 16
|
|
||||||
#define FILEIO_EEXIST 17
|
|
||||||
#define FILEIO_ENODEV 19
|
|
||||||
#define FILEIO_ENOTDIR 20
|
|
||||||
#define FILEIO_EISDIR 21
|
|
||||||
#define FILEIO_EINVAL 22
|
|
||||||
#define FILEIO_ENFILE 23
|
|
||||||
#define FILEIO_EMFILE 24
|
|
||||||
#define FILEIO_EFBIG 27
|
|
||||||
#define FILEIO_ENOSPC 28
|
|
||||||
#define FILEIO_ESPIPE 29
|
|
||||||
#define FILEIO_EROFS 30
|
|
||||||
#define FILEIO_ENOSYS 88
|
|
||||||
#define FILEIO_ENAMETOOLONG 91
|
|
||||||
#define FILEIO_EUNKNOWN 9999
|
|
||||||
|
|
||||||
/* limits */
|
|
||||||
#define FILEIO_INT_MIN -2147483648L
|
|
||||||
#define FILEIO_INT_MAX 2147483647L
|
|
||||||
#define FILEIO_UINT_MAX 4294967295UL
|
|
||||||
#define FILEIO_LONG_MIN -9223372036854775808LL
|
|
||||||
#define FILEIO_LONG_MAX 9223372036854775807LL
|
|
||||||
#define FILEIO_ULONG_MAX 18446744073709551615ULL
|
|
||||||
|
|
||||||
/* Integral types as used in protocol. */
|
|
||||||
#if 0
|
|
||||||
typedef __int32_t fio_int_t;
|
|
||||||
typedef __uint32_t fio_uint_t, fio_mode_t, fio_time_t;
|
|
||||||
typedef __int64_t fio_long_t;
|
|
||||||
typedef __uint64_t fio_ulong_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define FIO_INT_LEN 4
|
|
||||||
#define FIO_UINT_LEN 4
|
|
||||||
#define FIO_MODE_LEN 4
|
|
||||||
#define FIO_TIME_LEN 4
|
|
||||||
#define FIO_LONG_LEN 8
|
|
||||||
#define FIO_ULONG_LEN 8
|
|
||||||
|
|
||||||
typedef char fio_int_t[FIO_INT_LEN];
|
|
||||||
typedef char fio_uint_t[FIO_UINT_LEN];
|
|
||||||
typedef char fio_mode_t[FIO_MODE_LEN];
|
|
||||||
typedef char fio_time_t[FIO_TIME_LEN];
|
|
||||||
typedef char fio_long_t[FIO_LONG_LEN];
|
|
||||||
typedef char fio_ulong_t[FIO_ULONG_LEN];
|
|
||||||
|
|
||||||
/* Struct stat as used in protocol. For complete independence
|
|
||||||
of host/target systems, it's defined as an array with offsets
|
|
||||||
to the members. */
|
|
||||||
|
|
||||||
struct fio_stat {
|
|
||||||
fio_uint_t fst_dev;
|
|
||||||
fio_uint_t fst_ino;
|
|
||||||
fio_mode_t fst_mode;
|
|
||||||
fio_uint_t fst_nlink;
|
|
||||||
fio_uint_t fst_uid;
|
|
||||||
fio_uint_t fst_gid;
|
|
||||||
fio_uint_t fst_rdev;
|
|
||||||
fio_ulong_t fst_size;
|
|
||||||
fio_ulong_t fst_blksize;
|
|
||||||
fio_ulong_t fst_blocks;
|
|
||||||
fio_time_t fst_atime;
|
|
||||||
fio_time_t fst_mtime;
|
|
||||||
fio_time_t fst_ctime;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fio_timeval {
|
|
||||||
fio_time_t ftv_sec;
|
|
||||||
fio_long_t ftv_usec;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* GDB_FILEIO_H_ */
|
|
||||||
78
zOS/MZ2000/include/fonts.h
vendored
78
zOS/MZ2000/include/fonts.h
vendored
@@ -1,78 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: fonts.h
|
|
||||||
// Created: May 2021
|
|
||||||
// Version: v1.0
|
|
||||||
// Author(s): Baron Williams, Philip Smart
|
|
||||||
// Description: The Font Library.
|
|
||||||
// This is a font definition and manipulation library, the fonts being based on
|
|
||||||
// Baron Williams (https://github.com/BaronWilliams) font definitions and modified
|
|
||||||
// for use with the Sharp MZ Series OSD./
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2015 Baron Williams, (c) 2019-2021 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: May 2021 - Initial write of the OSD software.
|
|
||||||
//
|
|
||||||
// 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 FONTS_H
|
|
||||||
#define FONTS_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Supported fonts.
|
|
||||||
enum FONTS {
|
|
||||||
FONT_3X6 = 0x00, // 3x6 small font.
|
|
||||||
FONT_5X7 = 0x01, // 5x7 default font.
|
|
||||||
FONT_7X8 = 0x02, // 7X8 large default font.
|
|
||||||
FONT_9X16 = 0x03, // 9X16 large font for titles.
|
|
||||||
FONT_11X16 = 0x04 // 11X16 large font for titles.
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct fontStruct {
|
|
||||||
uint8_t *bitmap; // The bitmap data to represent the font
|
|
||||||
uint16_t characters; // The number of valid characters in a font
|
|
||||||
uint8_t start; // The first valid character in a font
|
|
||||||
uint8_t end; // The last valid character in a font
|
|
||||||
uint8_t width; // The width of the font in pixels
|
|
||||||
uint8_t height; // The height of the font in pixels
|
|
||||||
uint8_t spacing; // The horizontal spacing required for a font
|
|
||||||
bool bitAlignVertical; // True if the data is stored vertically
|
|
||||||
} fontStruct;
|
|
||||||
|
|
||||||
extern const fontStruct font11x16;
|
|
||||||
extern const fontStruct font3x6;
|
|
||||||
extern const fontStruct font3x6limited;
|
|
||||||
extern const fontStruct font5x7extended;
|
|
||||||
extern const fontStruct font5x7;
|
|
||||||
extern const fontStruct font7x8;
|
|
||||||
extern const fontStruct font7x8extended;
|
|
||||||
extern const fontStruct font9x16;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Prototypes.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // FONTS_H
|
|
||||||
20
zOS/MZ2000/include/interrupts.h
vendored
20
zOS/MZ2000/include/interrupts.h
vendored
@@ -1,20 +0,0 @@
|
|||||||
#ifndef INTERRUPTS_H
|
|
||||||
#define INTERRUPTS_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Prototypes.
|
|
||||||
void SetIntHandler(void(*handler)());
|
|
||||||
void EnableInterrupt(uint32_t);
|
|
||||||
void DisableInterrupt(uint32_t);
|
|
||||||
extern void DisableInterrupts(void);
|
|
||||||
extern void EnableInterrupts(void);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
139
zOS/MZ2000/include/k64f_soc.h
vendored
139
zOS/MZ2000/include/k64f_soc.h
vendored
@@ -1,139 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: k64f_soc.h
|
|
||||||
// Created: January 2019 - April 2020
|
|
||||||
// Author(s): Philip Smart
|
|
||||||
// Description: K64F System On a Chip utilities.
|
|
||||||
// A set of utilities specific to interaction with the K64F SoC hardware.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2019 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: January 2019 - Initial script written.
|
|
||||||
// April 2020 - Duplicated the zpu_soc for the Freescale K64F used in the Teensy3.5
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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 __K64FSOC_H__
|
|
||||||
#define __K64FSOC_H__
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// Macro to omit code if deemed optional and the compile time flag MINIMUM_FUNCTIONALITY is defined.
|
|
||||||
#ifdef MINIMUM_FUNCTIONALITY
|
|
||||||
#define OPTIONAL(a)
|
|
||||||
#else
|
|
||||||
#define OPTIONAL(a) a
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// System settings.
|
|
||||||
#define CLK_FREQ 120000000UL // Default frequency of the Teensy3.5 K64F CPU
|
|
||||||
|
|
||||||
// Memory sizes and devices implemented - these can be ignored if the SoC Configuration register is implemented as this provides the exact build configuration.
|
|
||||||
#define FRAM_IMPL 1
|
|
||||||
#define FRAMNV_IMPL 1
|
|
||||||
#define FRAMNVC_IMPL 1
|
|
||||||
#define RAM_IMPL 1
|
|
||||||
#define PS2_IMPL 1
|
|
||||||
#define SPI_IMPL 1
|
|
||||||
#define SD_IMPL 1
|
|
||||||
#define SD_DEVICE_CNT 1
|
|
||||||
#define INTRCTL_IMPL 1
|
|
||||||
#define INTRCTL_CHANNELS 16
|
|
||||||
#define TIMER1_IMPL 1
|
|
||||||
#define TIMER1_TIMERS_CNT 1
|
|
||||||
|
|
||||||
#define FRAM_ADDR 0x00000000
|
|
||||||
#define FRAM_SIZE 0x0007FFFF
|
|
||||||
#define FRAMNV_ADDR 0x10000000
|
|
||||||
#define FRAMNV_SIZE 0x0001FFFF
|
|
||||||
#define FRAMNVC_ADDR 0x14000000
|
|
||||||
#define FRAMNVC_SIZE 0x00000FFF
|
|
||||||
#define RAM_ADDR 0x1FFF0000
|
|
||||||
#define RAM_SIZE 0x0003FFFF
|
|
||||||
#define STACK_BRAM_ADDR 0x00007800
|
|
||||||
#define STACK_BRAM_SIZE 0x000007FF
|
|
||||||
#define CPU_RESET_ADDR 0x00000000
|
|
||||||
#define CPU_MEM_START 0x00000000
|
|
||||||
#define BRAM_APP_START_ADDR 0x2000
|
|
||||||
|
|
||||||
// Debug only macros which dont generate code when debugging disabled.
|
|
||||||
#ifdef DEBUG
|
|
||||||
|
|
||||||
// Macro to print to the debug channel.
|
|
||||||
//
|
|
||||||
#define debugf(a, ...) ({\
|
|
||||||
printf(a, ##__VA_ARGS__);\
|
|
||||||
})
|
|
||||||
#define dbg_putchar(a) ({\
|
|
||||||
putc(a);\
|
|
||||||
})
|
|
||||||
#define dbg_puts(a) ({\
|
|
||||||
puts(a);\
|
|
||||||
})
|
|
||||||
#define dbg_breadcrumb(x) putc(x);
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#define dbg_putchar(a)
|
|
||||||
#define dbg_puts(a)
|
|
||||||
#define debugf(a, ...)
|
|
||||||
#define dbg_breadcrumb(x)
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Prototypes.
|
|
||||||
void setupSoCConfig(void);
|
|
||||||
void showSoCConfig(void);
|
|
||||||
void printCPU(void);
|
|
||||||
|
|
||||||
// Configuration values.
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t addrFRAM;
|
|
||||||
uint32_t sizeFRAM;
|
|
||||||
uint32_t addrFRAMNV;
|
|
||||||
uint32_t sizeFRAMNV;
|
|
||||||
uint32_t addrFRAMNVC;
|
|
||||||
uint32_t sizeFRAMNVC;
|
|
||||||
uint32_t addrRAM;
|
|
||||||
uint32_t sizeRAM;
|
|
||||||
uint32_t resetVector;
|
|
||||||
uint32_t cpuMemBaseAddr;
|
|
||||||
uint32_t stackStartAddr;
|
|
||||||
uint32_t sysFreq;
|
|
||||||
uint32_t memFreq;
|
|
||||||
uint8_t implRAM;
|
|
||||||
uint8_t implFRAM;
|
|
||||||
uint8_t implFRAMNV;
|
|
||||||
uint8_t implFRAMNVC;
|
|
||||||
uint8_t implPS2;
|
|
||||||
uint8_t implSPI;
|
|
||||||
uint8_t implSD;
|
|
||||||
uint8_t sdCardNo;
|
|
||||||
uint8_t implIntrCtl;
|
|
||||||
uint8_t intrChannels;
|
|
||||||
uint8_t implTimer1;
|
|
||||||
uint8_t timer1No;
|
|
||||||
} SOC_CONFIG;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
50
zOS/MZ2000/include/keyboard.h
vendored
50
zOS/MZ2000/include/keyboard.h
vendored
@@ -1,50 +0,0 @@
|
|||||||
#ifndef KEYBOARD_H
|
|
||||||
#define KEYBOARD_H
|
|
||||||
|
|
||||||
#define KEY_EXT 0xe0
|
|
||||||
#define KEY_KEYUP 0xf0
|
|
||||||
|
|
||||||
#define KEY_F1 0x5
|
|
||||||
#define KEY_F2 0x6
|
|
||||||
#define KEY_F3 0x4
|
|
||||||
#define KEY_F4 0x0C
|
|
||||||
#define KEY_F5 0x3
|
|
||||||
#define KEY_F6 0x0B
|
|
||||||
#define KEY_F7 0x83
|
|
||||||
#define KEY_F8 0x0A
|
|
||||||
#define KEY_F9 0x1
|
|
||||||
#define KEY_F10 0x9
|
|
||||||
#define KEY_F11 0x78
|
|
||||||
#define KEY_F12 0x7
|
|
||||||
|
|
||||||
#define KEY_CAPSLOCK 0x58
|
|
||||||
#define KEY_NUMLOCK 0x77
|
|
||||||
#define KEY_SCROLLLOCK 0x7e
|
|
||||||
#define KEY_LEFTARROW 0xeb
|
|
||||||
#define KEY_RIGHTARROW 0xf4
|
|
||||||
#define KEY_UPARROW 0xf5
|
|
||||||
#define KEY_DOWNARROW 0xf2
|
|
||||||
#define KEY_ENTER 0x5a
|
|
||||||
#define KEY_PAGEUP 0xfd
|
|
||||||
#define KEY_PAGEDOWN 0xfa
|
|
||||||
#define KEY_SPACE 0x29
|
|
||||||
#define KEY_ESC 0x76
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int HandlePS2RawCodes();
|
|
||||||
void ClearKeyboard();
|
|
||||||
|
|
||||||
int TestKey(int rawcode);
|
|
||||||
|
|
||||||
// Each keytable entry has two bits: bit 0 - currently pressed, bit 1 - pressed since last test
|
|
||||||
extern unsigned int keytable[16];
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
518
zOS/MZ2000/include/m68k_soc.h
vendored
518
zOS/MZ2000/include/m68k_soc.h
vendored
@@ -1,518 +0,0 @@
|
|||||||
////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: m68k_soc.h
|
|
||||||
// Created: January 2019
|
|
||||||
// Author(s): Philip Smart
|
|
||||||
// Description: M68K System On a Chip utilities.
|
|
||||||
// A set of utilities specific to interaction with the M68000 SoC hardware.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2019-2021 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: January 2019 - Initial script written.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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 __M68KSOC_H__
|
|
||||||
#define __M68KSOC_H__
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef ASSEMBLY
|
|
||||||
typedef volatile unsigned int* register_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Macro to omit code if deemed optional and the compile time flag MINIMUM_FUNCTIONALITY is defined.
|
|
||||||
#ifdef MINIMUM_FUNCTIONALITY
|
|
||||||
#define OPTIONAL(a)
|
|
||||||
#else
|
|
||||||
#define OPTIONAL(a) a
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// System settings.
|
|
||||||
#define CLK_FREQ 100000000UL // Default frequency used to configure SoC if not present.
|
|
||||||
|
|
||||||
// Memory sizes and devices implemented - these can be ignored if the SoC Configuration register is implemented as this provides the exact build configuration.
|
|
||||||
#define M68K_ID 0x0000
|
|
||||||
#define WB_IMPL 0
|
|
||||||
#define WB_SDRAM_IMPL 0
|
|
||||||
#define WB_I2C_IMPL 0
|
|
||||||
#define BRAM_IMPL 1
|
|
||||||
#define RAM_IMPL 1
|
|
||||||
#define INSN_BRAM_IMPL 1
|
|
||||||
#define SDRAM_IMPL 1
|
|
||||||
#define IOCTL_IMPL 1
|
|
||||||
#define PS2_IMPL 1
|
|
||||||
#define SPI_IMPL 1
|
|
||||||
#define SD_IMPL 1
|
|
||||||
#define SD_DEVICE_CNT 1
|
|
||||||
#define INTRCTL_IMPL 1
|
|
||||||
#define INTRCTL_CHANNELS 16
|
|
||||||
#define TIMER1_IMPL 1
|
|
||||||
#define TIMER1_TIMERS_CNT 1
|
|
||||||
#define SDRAM_ADDR 0x00010000
|
|
||||||
#define SDRAM_SIZE 0x00810000
|
|
||||||
#define WB_SDRAM_ADDR 0x01000000
|
|
||||||
#define WB_SDRAM_SIZE 0x017FFFFF
|
|
||||||
#define BRAM_ADDR 0x00000000
|
|
||||||
#define BRAM_SIZE 0x00007FFF
|
|
||||||
#define INSN_BRAM_ADDR 0x00000000
|
|
||||||
#define INSN_BRAM_SIZE 0x00007FFF
|
|
||||||
#define RAM_ADDR 0x00010000
|
|
||||||
#define RAM_SIZE 0x00007FFF
|
|
||||||
#define STACK_BRAM_ADDR 0x00007800
|
|
||||||
#define STACK_BRAM_SIZE 0x000007FF
|
|
||||||
#define CPU_RESET_ADDR 0x00000000
|
|
||||||
#define CPU_MEM_START 0x00000000
|
|
||||||
#define BRAM_APP_START_ADDR 0x2000
|
|
||||||
|
|
||||||
//
|
|
||||||
#define SPIISBLOCKING 1
|
|
||||||
#define BIT(x) (1<<(x))
|
|
||||||
#define MEMIO32 *(volatile unsigned int *)
|
|
||||||
|
|
||||||
// M68000 Id definitions.
|
|
||||||
//
|
|
||||||
#define M68K_ID_M68008 0x01
|
|
||||||
#define M68K_ID_M68000 0x02
|
|
||||||
#define M68K_ID_M68020 0x03
|
|
||||||
|
|
||||||
// IO base address.
|
|
||||||
//#define IO_ADDR_PERIPHERALS 0xFFFFF000
|
|
||||||
#define IO_ADDR_PERIPHERALS 0x0F00000
|
|
||||||
#define IO_ADDR_WB_PERIPHERALS 0x1F00000
|
|
||||||
|
|
||||||
// Baud rate computation for UART
|
|
||||||
#define BAUDRATEGEN(b,x,y) (((UART_SYSCLK(b)/(x))) << 16) | (((UART_SYSCLK(b)/(y))))
|
|
||||||
|
|
||||||
// ----------------------------------
|
|
||||||
// CPU Bus I/O Peripheral definition.
|
|
||||||
// ----------------------------------
|
|
||||||
|
|
||||||
// TCPU Processor Controller.
|
|
||||||
//
|
|
||||||
#define TCPU_BASE IO_ADDR_PERIPHERALS + 0x700
|
|
||||||
#define ADDR_REGISTER 0x00
|
|
||||||
#define DATA_REGISTER 0x04
|
|
||||||
#define TCPU_ADDR (MEMIO32 (TCPU_BASE + ADDR_REGISTER))
|
|
||||||
#define TCPU_DATA (MEMIO32 (TCPU_BASE + DATA_REGISTER))
|
|
||||||
|
|
||||||
// IO Processor Controller.
|
|
||||||
#define IOCTL_BASE IO_ADDR_PERIPHERALS + 0x800
|
|
||||||
#define CMDADDR_REGISTER 0x00
|
|
||||||
#define DATA_REGISTER 0x04
|
|
||||||
#define CHRCOLS_REGISTER 0x08
|
|
||||||
#define CGADDR_REGISTER 0x0C
|
|
||||||
#define IOCTL_CMDADDR (MEMIO32 (IOCTL_BASE + CMDADDR_REGISTER))
|
|
||||||
#define IOCTL_DOUT (MEMIO32 (IOCTL_BASE + DATA_REGISTER))
|
|
||||||
#define IOCTL_DIN (MEMIO32 (IOCTL_BASE + DATA_REGISTER))
|
|
||||||
#define IOCTL_CHRCOLS (MEMIO32 (IOCTL_BASE + CHRCOLS_REGISTER))
|
|
||||||
#define IOCTL_CGADDR (MEMIO32 (IOCTL_BASE + CGADDR_REGISTER))
|
|
||||||
|
|
||||||
// SD Card Controller.
|
|
||||||
#define SD_BASE IO_ADDR_PERIPHERALS + 0x900
|
|
||||||
#define SD0 0
|
|
||||||
#define SD1 1
|
|
||||||
#define SD2 2
|
|
||||||
#define SD3 3
|
|
||||||
#define SD_SPACING 0x10
|
|
||||||
#define SD_ADDR_REGISTER 0x00
|
|
||||||
#define SD_DATA_REGISTER 0x04
|
|
||||||
#define SD_STATUS_REGISTER 0x0c
|
|
||||||
#define SD_CMD_REGISTER 0x0c
|
|
||||||
#define SD_CMD_RESET 0x00000001
|
|
||||||
#define SD_CMD_WRITE 0x00000002
|
|
||||||
#define SD_CMD_READ 0x00000004
|
|
||||||
#define SD_CMD_CARDTYPE 0x00000008
|
|
||||||
#define SD_CMD_CARDTYPE_SD 0x00000008
|
|
||||||
#define SD_CMD_CARDTYPE_SDHC 0x00000088
|
|
||||||
#define SD_STATUS_CONTINUE 0x00000001
|
|
||||||
#define SD_STATUS_BUSY 0x00000002
|
|
||||||
#define SD_STATUS_HNDSHK_OUT 0x00000004
|
|
||||||
#define SD_STATUS_HNDSHK_IN 0x00000008
|
|
||||||
#define SD_STATUS_DATA_REQ 0x00000010
|
|
||||||
#define SD_STATUS_DATA_VALID 0x00000020
|
|
||||||
#define SD_STATUS_OVERRUN 0x00000040
|
|
||||||
#define SD_STATUS_IDLESTATE 0x00010000
|
|
||||||
#define SD_STATUS_ERASERESET 0x00020000
|
|
||||||
#define SD_STATUS_ILLEGALCMD 0x00040000
|
|
||||||
#define SD_STATUS_CRCERROR 0x00080000
|
|
||||||
#define SD_STATUS_ERASESEQ 0x00100000
|
|
||||||
#define SD_STATUS_ADDRERR 0x00200000
|
|
||||||
#define SD_STATUS_PARAMERR 0x00400000
|
|
||||||
#define SD_STATUS_ERROR 0xFFFF0000
|
|
||||||
#define SD(x, y) (MEMIO32 (SD_BASE+(x*SD_SPACING) + y))
|
|
||||||
#define SD_ADDR(x) (MEMIO32 (SD_BASE+(x*SD_SPACING) + SD_ADDR_REGISTER))
|
|
||||||
#define SD_DATA(x) (MEMIO32 (SD_BASE+(x*SD_SPACING) + SD_DATA_REGISTER))
|
|
||||||
#define SD_CMD(x) (MEMIO32 (SD_BASE+(x*SD_SPACING) + SD_CMD_REGISTER))
|
|
||||||
#define SD_STATUS(x) (MEMIO32 (SD_BASE+(x*SD_SPACING) + SD_STATUS_REGISTER))
|
|
||||||
#define IS_SD_BUSY(x) ((MEMIO32 (SD_BASE+(x*SD_SPACING) + SD_STATUS_REGISTER)) & SD_STATUS_BUSY) >> 1
|
|
||||||
#define IS_SD_ERROR(x) ((MEMIO32 (SD_BASE+(x*SD_SPACING) + SD_STATUS_REGISTER)) & SD_STATUS_ERROR) >> 16
|
|
||||||
|
|
||||||
// UART definitions.
|
|
||||||
#define UART_BASE IO_ADDR_PERIPHERALS + 0xA00
|
|
||||||
#define UART0 0
|
|
||||||
#define UART1 1
|
|
||||||
#define UART_SPACING 0x10 // Address spacing between UART modules.
|
|
||||||
// UART Registers and macros to read/write them.
|
|
||||||
#define UART_DATA_REGISTER 0x00
|
|
||||||
#define UART_CTRL_REGISTER 0x04
|
|
||||||
#define UART_STATUS_REGISTER 0x04
|
|
||||||
#define UART_FIFO_REGISTER 0x08
|
|
||||||
#define UART_BAUDRATE_REGISTER 0x0C
|
|
||||||
#define UART_SYSCLK_REGISTER 0x0C
|
|
||||||
#define UART_DATA(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_DATA_REGISTER))
|
|
||||||
#define UART_STATUS(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_STATUS_REGISTER))
|
|
||||||
#define UART_FIFO_STATUS(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_FIFO_REGISTER))
|
|
||||||
#define UART_CTRL(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_CTRL_REGISTER))
|
|
||||||
#define UART_BRGEN(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_BAUDRATE_REGISTER))
|
|
||||||
#define UART_SYSCLK(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_SYSCLK_REGISTER))
|
|
||||||
// UART Status flags.
|
|
||||||
#define UART_RX_FIFO_EMPTY 0x00000001
|
|
||||||
#define UART_RX_FIFO_FULL 0x00000002
|
|
||||||
#define UART_RX_DATA_READY 0x00000004
|
|
||||||
#define UART_RX_OVERRUN 0x00000008
|
|
||||||
#define UART_RX_INTERRUPT 0x00000010
|
|
||||||
#define UART_RX_FIFO_ENABLED 0x00000020
|
|
||||||
#define UART_RX_ENABLED 0x00000040
|
|
||||||
#define UART_RX_IN_RESET 0x00000080
|
|
||||||
#define UART_TX_FIFO_EMPTY 0x00010000
|
|
||||||
#define UART_TX_FIFO_FULL 0x00020000
|
|
||||||
#define UART_TX_BUSY 0x00040000
|
|
||||||
#define UART_TX_DATA_LOADED 0x00080000
|
|
||||||
#define UART_TX_OVERRUN 0x00100000
|
|
||||||
#define UART_TX_INTERRUPT 0x00200000
|
|
||||||
#define UART_TX_FIFO_ENABLED 0x00400000
|
|
||||||
#define UART_TX_ENABLED 0x00800000
|
|
||||||
#define UART_TX_IN_RESET 0x01000000
|
|
||||||
// UART Control flags.
|
|
||||||
#define UART_RX_ENABLE 0x00000001
|
|
||||||
#define UART_RX_FIFO_ENABLE 0x00000002
|
|
||||||
#define UART_RX_RESET 0x00000004
|
|
||||||
#define UART_TX_ENABLE 0x00010000
|
|
||||||
#define UART_TX_FIFO_ENABLE 0x00020000
|
|
||||||
#define UART_TX_RESET 0x00040000
|
|
||||||
// UART macros to test 32bit status register value.
|
|
||||||
#define UART_IS_TX_FIFO_ENABLED(x) ((x & UART_TX_FIFO_ENABLED) != 0)
|
|
||||||
#define UART_IS_TX_FIFO_DISABLED(x) ((x & UART_TX_FIFO_ENABLED) == 0)
|
|
||||||
#define UART_IS_TX_FIFO_FULL(x) ((x & UART_TX_FIFO_FULL) != 0)
|
|
||||||
#define UART_IS_TX_BUSY(x) ((x & UART_TX_BUSY) != 0)
|
|
||||||
#define UART_IS_TX_DATA_LOADED(x) ((x & UART_TX_DATA_LOADED) != 0)
|
|
||||||
#define UART_IS_RX_FIFO_ENABLED(x) ((x & UART_RX_FIFO_ENABLED) != 0)
|
|
||||||
#define UART_IS_RX_FIFO_DISABLED(x) ((x & UART_RX_FIFO_ENABLED) == 0)
|
|
||||||
#define UART_IS_RX_FIFO_EMPTY(x) ((x & UART_RX_FIFO_EMPTY) != 0)
|
|
||||||
#define UART_IS_RX_DATA_READY(x) ((x & UART_RX_DATA_READY) != 0)
|
|
||||||
// UART macros to test for a specific flag.
|
|
||||||
#define UART_STATUS_RX_FIFO_EMPTY(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_RX_REGISTER)) & UART_RX_FIFO_EMPTY
|
|
||||||
#define UART_STATUS_RX_FIFO_FULL(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_RX_REGISTER)) & UART_RX_FIFO_FULL
|
|
||||||
#define UART_STATUS_RX_DATA_READY(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_RX_REGISTER)) & UART_RX_DATA_READY
|
|
||||||
#define UART_STATUS_RX_OVERRUN(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_RX_REGISTER)) & UART_RX_OVERRUN
|
|
||||||
#define UART_STATUS_RX_INTR(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_RX_REGISTER)) & UART_RX_INTERRUPT
|
|
||||||
#define UART_STATUS_RX_FIFO_ENABLED(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_RX_REGISTER)) & UART_RX_FIFO_ENABLED
|
|
||||||
#define UART_STATUS_RX_ENABLED(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_RX_REGISTER)) & UART_RX_ENABLED
|
|
||||||
#define UART_STATUS_RX_IN_RESET(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_RX_REGISTER)) & UART_IN_RESET
|
|
||||||
#define UART_STATUS_TX_FIFO_EMPTY(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_TX_REGISTER)) & UART_TX_FIFO_EMPTY
|
|
||||||
#define UART_STATUS_TX_FIFO_FULL(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_TX_REGISTER)) & UART_TX_FIFO_FULL
|
|
||||||
#define UART_STATUS_TX_BUSY(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_TX_REGISTER)) & UART_TX_BUSY
|
|
||||||
#define UART_STATUS_TX_DATA_LOADED(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_TX_REGISTER)) & UART_TX_DATA_LOADED
|
|
||||||
#define UART_STATUS_TX_OVERRUN(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_TX_REGISTER)) & UART_TX_OVERRUN
|
|
||||||
#define UART_STATUS_TX_INTR(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_TX_REGISTER)) & UART_TX_INTERRUPT
|
|
||||||
#define UART_STATUS_TX_FIFO_ENABLED(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_TX_REGISTER)) & UART_TX_FIFO_ENABLED
|
|
||||||
#define UART_STATUS_TX_ENABLED(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_TX_REGISTER)) & UART_TX_ENABLED
|
|
||||||
#define UART_STATUS_TX_IN_RESET(x) (MEMIO32 (UART_BASE+(x*UART_SPACING)+UART_TX_REGISTER)) & UART_IN_RESET
|
|
||||||
|
|
||||||
// Interrupt Controller.
|
|
||||||
#define INTERRUPT_BASE IO_ADDR_PERIPHERALS + 0xB00
|
|
||||||
#define INTR0 0
|
|
||||||
#define INTERRUPT_SPACING 0x10
|
|
||||||
#define INTERRUPT_STATUS_REGISTER 0x0
|
|
||||||
#define INTERRUPT_CTRL_REGISTER 0x4
|
|
||||||
#define INTERRUPT(x,y) (MEMIO32 (INTERRUPT_BASE+(x*INTERRUPT_SPACING)+y))
|
|
||||||
#define INTERRUPT_STATUS(x) (MEMIO32 (INTERRUPT_BASE+(x*INTERRUPT_SPACING)+INTERRUPT_STATUS_REGISTER))
|
|
||||||
#define INTERRUPT_CTRL(x) (MEMIO32 (INTERRUPT_BASE+(x*INTERRUPT_SPACING)+INTERRUPT_CTRL_REGISTER))
|
|
||||||
// Interrupt bit locations.
|
|
||||||
#define INTR_TIMER 0x00000002
|
|
||||||
#define INTR_PS2 0x00000004
|
|
||||||
#define INTR_IOCTL_RD 0x00000008
|
|
||||||
#define INTR_IOCTL_WR 0x00000010
|
|
||||||
#define INTR_UART0_RX 0x00000020
|
|
||||||
#define INTR_UART0_TX 0x00000040
|
|
||||||
#define INTR_UART1_RX 0x00000080
|
|
||||||
#define INTR_UART1_TX 0x00000100
|
|
||||||
// Macros to test a specific interrupt, ignoring others.
|
|
||||||
#define INTR_TEST_TIMER(x) (MEMIO32 (INTERRUPT_BASE+(x*INTERRUPT_SPACING))) & INTR_TIMER
|
|
||||||
#define INTR_TEST_PS2(x) (MEMIO32 (INTERRUPT_BASE+(x*INTERRUPT_SPACING))) & INTR_PS2
|
|
||||||
#define INTR_TEST_IOCTL_RD(x) (MEMIO32 (INTERRUPT_BASE+(x*INTERRUPT_SPACING))) & INTR_IOCTL_RD
|
|
||||||
#define INTR_TEST_IOCTL_WR(x) (MEMIO32 (INTERRUPT_BASE+(x*INTERRUPT_SPACING))) & INTR_IOCTL_WR
|
|
||||||
#define INTR_TEST_UART0_RX(x) (MEMIO32 (INTERRUPT_BASE+(x*INTERRUPT_SPACING))) & INTR_UART0_RX
|
|
||||||
#define INTR_TEST_UART0_TX(x) (MEMIO32 (INTERRUPT_BASE+(x*INTERRUPT_SPACING))) & INTR_UART0_TX
|
|
||||||
#define INTR_TEST_UART1_RX(x) (MEMIO32 (INTERRUPT_BASE+(x*INTERRUPT_SPACING))) & INTR_UART1_RX
|
|
||||||
#define INTR_TEST_UART1_TX(x) (MEMIO32 (INTERRUPT_BASE+(x*INTERRUPT_SPACING))) & INTR_UART1_TX
|
|
||||||
// Macros to test a variable for a specific interrupt.
|
|
||||||
#define INTR_IS_TIMER(x) (x) & INTR_TIMER
|
|
||||||
#define INTR_IS_PS2(x) (x) & INTR_PS2
|
|
||||||
#define INTR_IS_IOCTL_RD(x) (x) & INTR_IOCTL_RD
|
|
||||||
#define INTR_IS_IOCTL_WR(x) (x) & INTR_IOCTL_WR
|
|
||||||
#define INTR_IS_UART0_RX(x) (x) & INTR_UART0_RX
|
|
||||||
#define INTR_IS_UART0_TX(x) (x) & INTR_UART0_TX
|
|
||||||
#define INTR_IS_UART1_RX(x) (x) & INTR_UART1_RX
|
|
||||||
#define INTR_IS_UART1_TX(x) (x) & INTR_UART1_TX
|
|
||||||
|
|
||||||
// Timer.
|
|
||||||
// TIMER0 -> An RTC down to microsecond resolution and 3 delay counters, 1x uS and 1x mS down counters and 1x mS up counter.
|
|
||||||
// TIMER1-> are standard timers.
|
|
||||||
#define TIMER_BASE IO_ADDR_PERIPHERALS + 0xC00
|
|
||||||
#define TIMER_SPACING 0x40
|
|
||||||
#define TIMER0 0
|
|
||||||
#define TIMER1 1
|
|
||||||
#define TIMER_ENABLE_REG 0x00
|
|
||||||
#define TIMER_INDEX_REG 0x04
|
|
||||||
#define TIMER_COUNTER_REG 0x08
|
|
||||||
#define TIMER_MICROSEC_DOWN_REG 0x00
|
|
||||||
#define TIMER_MILLISEC_DOWN_REG 0x04
|
|
||||||
#define TIMER_MILLISEC_UP_REG 0x08
|
|
||||||
#define TIMER_SECONDS_DOWN_REG 0x0C
|
|
||||||
#define RTC_CTRL_HALT 0x00000001
|
|
||||||
#define RTC_CONTROL_REG 0x1C
|
|
||||||
#define RTC_MILLISECONDS_EPOCH_REG 0x1C
|
|
||||||
#define RTC_MICROSECONDS_REG 0x20
|
|
||||||
#define RTC_MILLISECONDS_REG 0x24
|
|
||||||
#define RTC_SECOND_REG 0x28
|
|
||||||
#define RTC_MINUTE_REG 0x2C
|
|
||||||
#define RTC_HOUR_REG 0x30
|
|
||||||
#define RTC_DAY_REG 0x34
|
|
||||||
#define RTC_MONTH_REG 0x38
|
|
||||||
#define RTC_YEAR_REG 0x3C
|
|
||||||
#define TIMER(x, y) (MEMIO32 (TIMER_BASE+(x*TIMER_SPACING) + y))
|
|
||||||
#define TIMER_ENABLE(x) (MEMIO32 (TIMER_BASE+(x*TIMER_SPACING) + TIMER_ENABLE_REG))
|
|
||||||
#define TIMER_INDEX(x) (MEMIO32 (TIMER_BASE+(x*TIMER_SPACING) + TIMER_INDEX_REG))
|
|
||||||
#define TIMER_COUNTER(x) (MEMIO32 (TIMER_BASE+(x*TIMER_SPACING) + TIMER_COUNTER_REG))
|
|
||||||
#define TIMER_MICROSECONDS_DOWN (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + TIMER_MICROSEC_DOWN_REG))
|
|
||||||
#define TIMER_MILLISECONDS_DOWN (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + TIMER_MILLISEC_DOWN_REG))
|
|
||||||
#define TIMER_MILLISECONDS_UP (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + TIMER_MILLISEC_UP_REG))
|
|
||||||
#define TIMER_SECONDS_DOWN (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + TIMER_SECONDS_DOWN_REG))
|
|
||||||
#define RTC_CONTROL (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + RTC_CONTROL_REG))
|
|
||||||
#define RTC_MICROSECONDS (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + RTC_MICROSECONDS_REG))
|
|
||||||
#define RTC_MILLISECONDS_EPOCH (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + RTC_MILLISECONDS_EPOCH_REG))
|
|
||||||
#define RTC_MILLISECONDS (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + RTC_MILLISECONDS_REG))
|
|
||||||
#define RTC_SECOND (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + RTC_SECOND_REG))
|
|
||||||
#define RTC_MINUTE (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + RTC_MINUTE_REG))
|
|
||||||
#define RTC_HOUR (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + RTC_HOUR_REG))
|
|
||||||
#define RTC_DAY (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + RTC_DAY_REG))
|
|
||||||
#define RTC_MONTH (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + RTC_MONTH_REG))
|
|
||||||
#define RTC_YEAR (MEMIO32 (TIMER_BASE+(TIMER0*TIMER_SPACING) + RTC_YEAR_REG))
|
|
||||||
|
|
||||||
// SPI Controller.
|
|
||||||
#define SPI_BASE IO_ADDR_PERIPHERALS + 0xD00
|
|
||||||
#define SPI0 0
|
|
||||||
#define SPI1 1
|
|
||||||
#define SPI2 2
|
|
||||||
#define SPI3 3
|
|
||||||
#define SPI_SPACING 0x10
|
|
||||||
#define CS_REGISTER 0x00
|
|
||||||
#define DATA_REGISTER 0x04
|
|
||||||
#define PUMP_REGISTER 0x08
|
|
||||||
#define SPI(x, y) (MEMIO32 (SPI_BASE+(x*SPI_SPACING) + y))
|
|
||||||
#define SPI_CS(x) (MEMIO32 (SPI_BASE+(x*SPI_SPACING) + CS_REGISTER)) /* CS bits are write-only, but bit 15 reads as the SPI busy signal */
|
|
||||||
#define SPI_DATA(x) (MEMIO32 (SPI_BASE+(x*SPI_SPACING) + DATA_REGISTER)) /* Blocks on both reads and writes, making BUSY signal redundant. */
|
|
||||||
#define SPI_PUMP(x) (MEMIO32 (SPI_BASE+(x*SPI_SPACING) + PUMP_REGISTER)) /* Push 16-bits through SPI in one instruction */
|
|
||||||
#define SPI_SET_CS(x,y) {while((SPI_CS(x)&(1<<SPI_BUSY))); SPI_CS(x)=(y);}
|
|
||||||
#define SPI_CS_SD 0
|
|
||||||
#define SPI_FAST 8
|
|
||||||
#define SPI_BUSY 15
|
|
||||||
|
|
||||||
// PS2
|
|
||||||
#define PS2_BASE IO_ADDR_PERIPHERALS + 0xE00
|
|
||||||
#define PS2_0 0
|
|
||||||
#define PS2_1 1
|
|
||||||
#define PS2_SPACING 0x10
|
|
||||||
#define PS2_KEYBOARD_REGISTER 0
|
|
||||||
#define PS2_MOUSE_REGISTER 0x4
|
|
||||||
#define PS2(x, y) (MEMIO32 (PS2_BASE+(x*0x10) + y))
|
|
||||||
#define PS2_KEYBOARD(x) (MEMIO32 (PS2_BASE+(x*0x10) + PS2_KEYBOARD_REGISTER))
|
|
||||||
#define PS2_MOUSE(x) (MEMIO32 (PS2_BASE+(x*0x10) + PS2_MOUSE_REGISTER))
|
|
||||||
#define BIT_PS2_RECV 11
|
|
||||||
#define BIT_PS2_CTS 10
|
|
||||||
|
|
||||||
// SoC Configuration registers.
|
|
||||||
#define SOCCFG_BASE IO_ADDR_PERIPHERALS + 0xF00
|
|
||||||
// Registers
|
|
||||||
#define SOCCFG_M68K_ID 0x00 // ID of the instantiated M68000
|
|
||||||
#define SOCCFG_SYSFREQ 0x04 // System Clock Frequency in MHz x 10 (ie. 100MHz = 1000)
|
|
||||||
#define SOCCFG_MEMFREQ 0x08 // Sysbus SDRAM Clock Frequency in MHz x 10 (ie. 100MHz = 1000)
|
|
||||||
#define SOCCFG_WBMEMFREQ 0x0c // Wishbone SDRAM Clock Frequency in MHz x 10 (ie. 100MHz = 1000)
|
|
||||||
#define SOCCFG_DEVIMPL 0x10 // Bit map of devices implemented in SOC.
|
|
||||||
#define SOCCFG_BRAMADDR 0x14 // Address of Block RAM.
|
|
||||||
#define SOCCFG_BRAMSIZE 0x18 // Size of Block RAM.
|
|
||||||
#define SOCCFG_RAMADDR 0x1c // Address of RAM (additional BRAM, DRAM etc).
|
|
||||||
#define SOCCFG_RAMSIZE 0x20 // Size of RAM.
|
|
||||||
#define SOCCFG_BRAMINSNADDR 0x24 // Address of dedicated instruction Block RAM.
|
|
||||||
#define SOCCFG_BRAMINSNSIZE 0x28 // Size of dedicated instruction Block RAM.
|
|
||||||
#define SOCCFG_SDRAMADDR 0x2c // Address of SDRAM.
|
|
||||||
#define SOCCFG_SDRAMSIZE 0x30 // Size of SDRAM.
|
|
||||||
#define SOCCFG_WBSDRAMADDR 0x34 // Address of Wishbone SDRAM.
|
|
||||||
#define SOCCFG_WBSDRAMSIZE 0x38 // Size of Wishbone SDRAM.
|
|
||||||
#define SOCCFG_CPURSTADDR 0x3c // Address CPU executes after a RESET.
|
|
||||||
#define SOCCFG_CPUMEMSTART 0x40 // Start address of Memory containing BIOS/Microcode for CPU.
|
|
||||||
#define SOCCFG_STACKSTART 0x44 // Start address of Memory for Stack use.
|
|
||||||
// Implementation bits.
|
|
||||||
#define IMPL_WB 0x00400000
|
|
||||||
#define IMPL_WB_SDRAM 0x00200000
|
|
||||||
#define IMPL_WB_I2C 0x00100000
|
|
||||||
#define IMPL_BRAM 0x00080000
|
|
||||||
#define IMPL_RAM 0x00040000
|
|
||||||
#define IMPL_INSN_BRAM 0x00020000
|
|
||||||
#define IMPL_SDRAM 0x00010000
|
|
||||||
#define IMPL_IOCTL 0x00008000
|
|
||||||
#define IMPL_PS2 0x00004000
|
|
||||||
#define IMPL_SPI 0x00002000
|
|
||||||
#define IMPL_SD 0x00001000
|
|
||||||
#define IMPL_SD_DEVICE_CNT 0x00000C00
|
|
||||||
#define IMPL_INTRCTL 0x00000200
|
|
||||||
#define IMPL_INTRCTL_CNT 0x000001F0
|
|
||||||
#define IMPL_TIMER1 0x00000008
|
|
||||||
#define IMPL_TIMER1_TIMER_CNT 0x00000007
|
|
||||||
#define IMPL_SOCCFG 0x0000000a
|
|
||||||
// Test macros
|
|
||||||
#define IS_IMPL_WB ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_WB) >> 22
|
|
||||||
#define IS_IMPL_WB_SDRAM ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_WB_SDRAM) >> 21
|
|
||||||
#define IS_IMPL_WB_I2C ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_WB_I2C) >> 20
|
|
||||||
#define IS_IMPL_BRAM ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_BRAM) >> 19
|
|
||||||
#define IS_IMPL_RAM ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_RAM) >> 18
|
|
||||||
#define IS_IMPL_INSN_BRAM ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_INSN_BRAM) >> 17
|
|
||||||
#define IS_IMPL_SDRAM ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_SDRAM) >> 16
|
|
||||||
#define IS_IMPL_IOCTL ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_IOCTL) >> 15
|
|
||||||
#define IS_IMPL_PS2 ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_PS2) >> 14
|
|
||||||
#define IS_IMPL_SPI ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_SPI) >> 13
|
|
||||||
#define IS_IMPL_SD ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_SD) >> 12
|
|
||||||
#define SOCCFG_SD_DEVICES ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_SD_DEVICE_CNT) >> 10
|
|
||||||
#define IS_IMPL_INTRCTL ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_INTRCTL) >> 9
|
|
||||||
#define SOCCFG_INTRCTL_CHANNELS ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_INTRCTL_CNT) >> 4
|
|
||||||
#define IS_IMPL_TIMER1 ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_TIMER1) >> 3
|
|
||||||
#define SOCCFG_TIMER1_TIMERS ((MEMIO32 (SOCCFG_BASE + SOCCFG_DEVIMPL)) & IMPL_TIMER1_TIMER_CNT)
|
|
||||||
#define IS_IMPL_SOCCFG (MEMIO32 (SOCCFG_BASE + SOCCFG_M68K_ID)) >> 28 & IMPL_SOCCFG
|
|
||||||
#define SOCCFG(x) (MEMIO32 (SOCCFG_BASE + x))
|
|
||||||
|
|
||||||
// -------------------------------
|
|
||||||
// Wishbone Peripheral definition.
|
|
||||||
// -------------------------------
|
|
||||||
|
|
||||||
// I2C Master Controller.
|
|
||||||
#define I2C_BASE IO_ADDR_WB_PERIPHERALS + 0x000
|
|
||||||
#define I2C0 0
|
|
||||||
#define I2C1 1
|
|
||||||
#define I2C2 2
|
|
||||||
#define I2C3 3
|
|
||||||
#define I2C_SPACING 0x10
|
|
||||||
#define I2C_PRE_LOW_REGISTER 0x00 // Low byte clock prescaler register
|
|
||||||
#define I2C_PRE_HI_REGISTER 0x01 // High byte clock prescaler register
|
|
||||||
#define I2C_CTRL_REGISTER 0x02 // Control register
|
|
||||||
#define I2C_TX_REGISTER 0x03 // Transmit byte register
|
|
||||||
#define I2C_CMD_REGISTER 0x04 // Command register
|
|
||||||
#define I2C_RX_REGISTER 0x03 // Receive byte register
|
|
||||||
#define I2C_STATUS_REGISTER 0x04 // Status register
|
|
||||||
#define I2C(x, y) (MEMIO32 (I2C_BASE+(x*I2C_SPACING) + y))
|
|
||||||
#define I2C_PRE_LOW(x) (MEMIO32 (I2C_BASE+(x*I2C_SPACING) + I2C_PRE_LOW_REGISTER))
|
|
||||||
#define I2C_PRE_HI(x) (MEMIO32 (I2C_BASE+(x*I2C_SPACING) + I2C_PRE_HI_REGISTER))
|
|
||||||
#define I2C_CTRL(x) (MEMIO32 (I2C_BASE+(x*I2C_SPACING) + I2C_CTRL_REGISTER))
|
|
||||||
#define I2C_TX(x) (MEMIO32 (I2C_BASE+(x*I2C_SPACING) + I2C_TX_REGISTER))
|
|
||||||
#define I2C_CMD(x) (MEMIO32 (I2C_BASE+(x*I2C_SPACING) + I2C_CMD_REGISTER))
|
|
||||||
#define I2C_RX(x) (MEMIO32 (I2C_BASE+(x*I2C_SPACING) + I2C_RX_REGISTER))
|
|
||||||
#define I2C_STATUS(x) (MEMIO32 (I2C_BASE+(x*I2C_SPACING) + I2C_STATUS_REGISTER))
|
|
||||||
#define I2C_EN (1<<7) // Core enable bit:
|
|
||||||
// 1 - core is enabled
|
|
||||||
// 0 - core is disabled
|
|
||||||
#define OC_I2C_IEN (1<<6) // Interrupt enable bit
|
|
||||||
// 1 - Interrupt enabled
|
|
||||||
// 0 - Interrupt disabled
|
|
||||||
// Other bits in CR are reserved
|
|
||||||
#define I2C_STA (1<<7) // Generate (repeated) start condition
|
|
||||||
#define I2C_STO (1<<6) // Generate stop condition
|
|
||||||
#define I2C_RD (1<<5) // Read from slave
|
|
||||||
#define I2C_WR (1<<4) // Write to slave
|
|
||||||
#define I2C_ACK (1<<3) // Acknowledge from slave
|
|
||||||
// 1 - ACK
|
|
||||||
// 0 - NACK
|
|
||||||
#define I2C_IACK (1<<0) // Interrupt acknowledge
|
|
||||||
#define I2C_RXACK (1<<7) // ACK received from slave
|
|
||||||
// 1 - ACK
|
|
||||||
// 0 - NACK
|
|
||||||
#define I2C_BUSY (1<<6) // Busy bit
|
|
||||||
#define I2C_TIP (1<<1) // Transfer in progress
|
|
||||||
#define I2C_IF (1<<0) // Interrupt flag
|
|
||||||
#define I2C_IS_SET(reg,bitmask) ((reg)&(bitmask))
|
|
||||||
#define I2C_IS_CLEAR(reg,bitmask) (!(I2C_IS_SET(reg,bitmask)))
|
|
||||||
#define I2C_BITSET(reg,bitmask) ((reg)|(bitmask))
|
|
||||||
#define I2C_BITCLEAR(reg,bitmask) ((reg)|(~(bitmask)))
|
|
||||||
#define I2C_BITTOGGLE(reg,bitmask) ((reg)^(bitmask))
|
|
||||||
#define I2C_REGMOVE(reg,value) ((reg)=(value))
|
|
||||||
|
|
||||||
// State definitions.
|
|
||||||
#define INPUT 1
|
|
||||||
#define OUTPUT 0
|
|
||||||
#define HIGH 1
|
|
||||||
#define LOW 0
|
|
||||||
|
|
||||||
// Prototypes.
|
|
||||||
void setupSoCConfig(void);
|
|
||||||
void showSoCConfig(void);
|
|
||||||
void printM68KId(uint32_t);
|
|
||||||
|
|
||||||
// Configuration values.
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint32_t addrInsnBRAM;
|
|
||||||
uint32_t sizeInsnBRAM;
|
|
||||||
uint32_t addrBRAM;
|
|
||||||
uint32_t sizeBRAM;
|
|
||||||
uint32_t addrRAM;
|
|
||||||
uint32_t sizeRAM;
|
|
||||||
uint32_t addrSDRAM;
|
|
||||||
uint32_t sizeSDRAM;
|
|
||||||
uint32_t addrWBSDRAM;
|
|
||||||
uint32_t sizeWBSDRAM;
|
|
||||||
uint32_t resetVector;
|
|
||||||
uint32_t cpuMemBaseAddr;
|
|
||||||
uint32_t stackStartAddr;
|
|
||||||
uint16_t m68kId;
|
|
||||||
uint32_t sysFreq;
|
|
||||||
uint32_t memFreq;
|
|
||||||
uint32_t wbMemFreq;
|
|
||||||
uint8_t implSoCCFG;
|
|
||||||
uint8_t implWB;
|
|
||||||
uint8_t implWBSDRAM;
|
|
||||||
uint8_t implWBI2C;
|
|
||||||
uint8_t implInsnBRAM;
|
|
||||||
uint8_t implBRAM;
|
|
||||||
uint8_t implRAM;
|
|
||||||
uint8_t implSDRAM;
|
|
||||||
uint8_t implIOCTL;
|
|
||||||
uint8_t implPS2;
|
|
||||||
uint8_t implSPI;
|
|
||||||
uint8_t implSD;
|
|
||||||
uint8_t sdCardNo;
|
|
||||||
uint8_t implIntrCtl;
|
|
||||||
uint8_t intrChannels;
|
|
||||||
uint8_t implTimer1;
|
|
||||||
uint8_t timer1No;
|
|
||||||
} SOC_CONFIG;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
||||||
66
zOS/MZ2000/include/malloc.h
vendored
66
zOS/MZ2000/include/malloc.h
vendored
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
* malloc.h
|
|
||||||
*
|
|
||||||
* Internals for the memory allocator
|
|
||||||
*/
|
|
||||||
|
|
||||||
// #include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
// #include <klibc/sysconfig.h>
|
|
||||||
#define _KLIBC_MALLOC_CHUNK_SIZE 65536
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This structure should be a power of two. This becomes the
|
|
||||||
* alignment unit.
|
|
||||||
*/
|
|
||||||
struct free_arena_header;
|
|
||||||
|
|
||||||
struct arena_header {
|
|
||||||
size_t type;
|
|
||||||
size_t size;
|
|
||||||
struct free_arena_header *next, *prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef DEBUG_MALLOC
|
|
||||||
#define ARENA_TYPE_USED 0x64e69c70
|
|
||||||
#define ARENA_TYPE_FREE 0x012d610a
|
|
||||||
#define ARENA_TYPE_HEAD 0x971676b5
|
|
||||||
#define ARENA_TYPE_DEAD 0xeeeeeeee
|
|
||||||
#else
|
|
||||||
#define ARENA_TYPE_USED 0
|
|
||||||
#define ARENA_TYPE_FREE 1
|
|
||||||
#define ARENA_TYPE_HEAD 2
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define MALLOC_CHUNK_MASK (_KLIBC_MALLOC_CHUNK_SIZE-1)
|
|
||||||
|
|
||||||
#define ARENA_SIZE_MASK (~(sizeof(struct arena_header)-1))
|
|
||||||
|
|
||||||
/*
|
|
||||||
* This structure should be no more than twice the size of the
|
|
||||||
* previous structure.
|
|
||||||
*/
|
|
||||||
struct free_arena_header {
|
|
||||||
struct arena_header a;
|
|
||||||
struct free_arena_header *next_free, *prev_free;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern char heap_low, heap_top; // Take the addresses of these.
|
|
||||||
|
|
||||||
void malloc_add(void *p,size_t size);
|
|
||||||
|
|
||||||
void *malloc(size_t);
|
|
||||||
void free(void *m);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Internal variable used by brk/sbrk
|
|
||||||
*/
|
|
||||||
// extern char *__current_brk;
|
|
||||||
102
zOS/MZ2000/include/oc_i2c_master.h
vendored
102
zOS/MZ2000/include/oc_i2c_master.h
vendored
@@ -1,102 +0,0 @@
|
|||||||
/*
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
|
||||||
//// ////
|
|
||||||
//// Include file for OpenCores I2C Master core ////
|
|
||||||
//// ////
|
|
||||||
//// File : oc_i2c_master.h ////
|
|
||||||
//// Function: c-include file ////
|
|
||||||
//// ////
|
|
||||||
//// Authors: Richard Herveille (richard@asics.ws) ////
|
|
||||||
//// Filip Miletic ////
|
|
||||||
//// ////
|
|
||||||
//// www.opencores.org ////
|
|
||||||
//// ////
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
|
||||||
//// ////
|
|
||||||
//// Copyright (C) 2001 Richard Herveille ////
|
|
||||||
//// Filip Miletic ////
|
|
||||||
//// ////
|
|
||||||
//// This source file may be used and distributed without ////
|
|
||||||
//// restriction provided that this copyright statement is not ////
|
|
||||||
//// removed from the file and that any derivative work contains ////
|
|
||||||
//// the original copyright notice and the associated disclaimer.////
|
|
||||||
//// ////
|
|
||||||
//// THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ////
|
|
||||||
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ////
|
|
||||||
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ////
|
|
||||||
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ////
|
|
||||||
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ////
|
|
||||||
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ////
|
|
||||||
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ////
|
|
||||||
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ////
|
|
||||||
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ////
|
|
||||||
//// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ////
|
|
||||||
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ////
|
|
||||||
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ////
|
|
||||||
//// POSSIBILITY OF SUCH DAMAGE. ////
|
|
||||||
//// ////
|
|
||||||
/////////////////////////////////////////////////////////////////////
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Definitions for the Opencores i2c master core
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* --- Definitions for i2c master's registers --- */
|
|
||||||
|
|
||||||
/* ----- Read-write access */
|
|
||||||
|
|
||||||
#define OC_I2C_PRER_LO 0x00 /* Low byte clock prescaler register */
|
|
||||||
#define OC_I2C_PRER_HI 0x01 /* High byte clock prescaler register */
|
|
||||||
#define OC_I2C_CTR 0x02 /* Control register */
|
|
||||||
|
|
||||||
/* ----- Write-only registers */
|
|
||||||
|
|
||||||
#define OC_I2C_TXR 0x03 /* Transmit byte register */
|
|
||||||
#define OC_I2C_CR 0x04 /* Command register */
|
|
||||||
|
|
||||||
/* ----- Read-only registers */
|
|
||||||
|
|
||||||
#define OC_I2C_RXR 0x03 /* Receive byte register */
|
|
||||||
#define OC_I2C_SR 0x04 /* Status register */
|
|
||||||
|
|
||||||
/* ----- Bits definition */
|
|
||||||
|
|
||||||
/* ----- Control register */
|
|
||||||
|
|
||||||
#define OC_I2C_EN (1<<7) /* Core enable bit: */
|
|
||||||
/* 1 - core is enabled */
|
|
||||||
/* 0 - core is disabled */
|
|
||||||
#define OC_I2C_IEN (1<<6) /* Interrupt enable bit */
|
|
||||||
/* 1 - Interrupt enabled */
|
|
||||||
/* 0 - Interrupt disabled */
|
|
||||||
/* Other bits in CR are reserved */
|
|
||||||
|
|
||||||
/* ----- Command register bits */
|
|
||||||
|
|
||||||
#define OC_I2C_STA (1<<7) /* Generate (repeated) start condition*/
|
|
||||||
#define OC_I2C_STO (1<<6) /* Generate stop condition */
|
|
||||||
#define OC_I2C_RD (1<<5) /* Read from slave */
|
|
||||||
#define OC_I2C_WR (1<<4) /* Write to slave */
|
|
||||||
#define OC_I2C_ACK (1<<3) /* Acknowledge from slave */
|
|
||||||
/* 1 - ACK */
|
|
||||||
/* 0 - NACK */
|
|
||||||
#define OC_I2C_IACK (1<<0) /* Interrupt acknowledge */
|
|
||||||
|
|
||||||
/* ----- Status register bits */
|
|
||||||
|
|
||||||
#define OC_I2C_RXACK (1<<7) /* ACK received from slave */
|
|
||||||
/* 1 - ACK */
|
|
||||||
/* 0 - NACK */
|
|
||||||
#define OC_I2C_BUSY (1<<6) /* Busy bit */
|
|
||||||
#define OC_I2C_TIP (1<<1) /* Transfer in progress */
|
|
||||||
#define OC_I2C_IF (1<<0) /* Interrupt flag */
|
|
||||||
|
|
||||||
/* bit testing and setting macros */
|
|
||||||
|
|
||||||
#define OC_ISSET(reg,bitmask) ((reg)&(bitmask))
|
|
||||||
#define OC_ISCLEAR(reg,bitmask) (!(OC_ISSET(reg,bitmask)))
|
|
||||||
#define OC_BITSET(reg,bitmask) ((reg)|(bitmask))
|
|
||||||
#define OC_BITCLEAR(reg,bitmask) ((reg)|(~(bitmask)))
|
|
||||||
#define OC_BITTOGGLE(reg,bitmask) ((reg)^(bitmask))
|
|
||||||
#define OC_REGMOVE(reg,value) ((reg)=(value))
|
|
||||||
680
zOS/MZ2000/include/osd.h
vendored
680
zOS/MZ2000/include/osd.h
vendored
@@ -1,680 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: osd.h
|
|
||||||
// Created: May 2021
|
|
||||||
// Version: v1.0
|
|
||||||
// Author(s): Philip Smart
|
|
||||||
// Description: The On Screen Display library.
|
|
||||||
// This source file contains the On Screen Display Class definitions and methods.
|
|
||||||
// The OSD is a popup area on the video controller which can be used to display
|
|
||||||
// text/menus and accept user input. Notably this class is intended to be instantiated
|
|
||||||
// inside an I/O processor onboard the FPGA hosting the Sharp MZ Series emulation
|
|
||||||
// and provide a user interface in order to configure/interact with the emulation.
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) 2019-2020 Philip Smart <philip.smart@net2net.org>
|
|
||||||
//
|
|
||||||
// History: May 2020 - Initial write of the OSD software.
|
|
||||||
//
|
|
||||||
// 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 OSD_H
|
|
||||||
#define OSD_H
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Video display constants.
|
|
||||||
#define VC_STATUS_MAX_X_PIXELS 640 // Maximum number of X pixels in the Status window.
|
|
||||||
#define VC_STATUS_MAX_Y_PIXELS 80 // Maximum number of Y pixels in the Status window.
|
|
||||||
#define VC_STATUS_RGB_BITS 3 // Number of colour bits in the Status window. (/3 per colour).
|
|
||||||
#define VC_MENU_MAX_X_PIXELS 512 // Maximum number of X pixels in the Menu window.
|
|
||||||
#define VC_MENU_MAX_Y_PIXELS 128 // Maximum number of Y pixels in the Menu window.
|
|
||||||
#define VC_MENU_RGB_BITS 3 // Number of colour bits in the Menu window. (/3 per colour).
|
|
||||||
#define VC_STATUS_BUFFER_SIZE (VC_STATUS_MAX_X_PIXELS * VC_STATUS_MAX_Y_PIXELS) / 8
|
|
||||||
#define VC_MENU_BUFFER_SIZE (VC_MENU_MAX_X_PIXELS * VC_MENU_MAX_Y_PIXELS) / 8
|
|
||||||
#define VC_OSD_X_CORRECTION 1 // Correction factor to be applied to horizontal to compensate for pixel multiplication.
|
|
||||||
#define VC_OSD_Y_CORRECTION 2 // Correction factor to be applied to vertical to compensate for pixel multiplication.
|
|
||||||
|
|
||||||
// Base addresses and sizes within the FPGA/Video Controller.
|
|
||||||
#define VIDEO_BASE_ADDR 0x200000 // Base address of the Video Controller.
|
|
||||||
#define VIDEO_VRAM_BASE_ADDR VIDEO_BASE_ADDR + 0x01D000 // Base address of the character video RAM using direct addressing.
|
|
||||||
#define VIDEO_VRAM_SIZE 0x800 // Size of the video RAM.
|
|
||||||
#define VIDEO_ARAM_BASE_ADDR VIDEO_BASE_ADDR + 0x01D800 // Base address of the character attribute RAM using direct addressing.
|
|
||||||
#define VIDEO_ARAM_SIZE 0x800 // Size of the attribute RAM.
|
|
||||||
#define VIDEO_IO_BASE_ADDR VIDEO_BASE_ADDR + 0x000000
|
|
||||||
#define MZ_EMU_BASE_ADDR 0x300000 // Base address of the Sharp MZ Series Emulator control registers/memory.
|
|
||||||
#define VIDEO_OSD_BLUE_ADDR 0x270000 // Base address of the OSD Menu/Status buffer, Blue colour.
|
|
||||||
#define VIDEO_OSD_RED_ADDR 0x280000 // Base address of the OSD Menu/Status buffer, Red colour.
|
|
||||||
#define VIDEO_OSD_GREEN_ADDR 0x290000 // Base address of the OSD Menu/Status buffer, Green colour.
|
|
||||||
#define VIDEO_OSD_WHITE_ADDR 0x2a0000 // Base address of the OSD Menu/Status buffer, all colours (White).
|
|
||||||
|
|
||||||
// Memory addresses of I/O and Memory mapped I/O in the Video Controller which are mapped to direct memory accessed addresses.
|
|
||||||
//
|
|
||||||
#define VC_8BIT_BASE_ADDR VIDEO_BASE_ADDR + 0x000000
|
|
||||||
#define VC_32BIT_BASE_ADDR VIDEO_BASE_ADDR + 0x000000
|
|
||||||
// 8 Bit access addresses - used for writing, read can only be on a 32bit boundary with lower address lines set to 00. Writing can write upto 4 consecutive addresses if desired.
|
|
||||||
#define VCADDR_8BIT_PALSLCTOFF VC_8BIT_BASE_ADDR + 0xA3 // Set the palette slot Off position to be adjusted.
|
|
||||||
#define VCADDR_8BIT_PALSLCTON VC_8BIT_BASE_ADDR + 0xA4 // Set the palette slot On position to be adjusted.
|
|
||||||
#define VCADDR_8BIT_PALSETRED VC_8BIT_BASE_ADDR + 0xA5 // Set the red palette value according to the PALETTE_PARAM_SEL address.
|
|
||||||
#define VCADDR_8BIT_PALSETGREEN VC_8BIT_BASE_ADDR + 0xA6 // Set the green palette value according to the PALETTE_PARAM_SEL address.
|
|
||||||
#define VCADDR_8BIT_PALSETBLUE VC_8BIT_BASE_ADDR + 0xA7 // Set the blue palette value according to the PALETTE_PARAM_SEL address.
|
|
||||||
#define VCADDR_8BIT_OSDMNU_SZX VC_8BIT_BASE_ADDR + 0xA8 // Get OSD Menu Horizontal Size (X).
|
|
||||||
#define VCADDR_8BIT_OSDMNU_SZY VC_8BIT_BASE_ADDR + 0xA9 // Get OSD Menu Vertical Size (Y).
|
|
||||||
#define VCADDR_8BIT_OSDHDR_SZX VC_8BIT_BASE_ADDR + 0xAA // Get OSD Status Header Horizontal Size (X).
|
|
||||||
#define VCADDR_8BIT_OSDHDR_SZY VC_8BIT_BASE_ADDR + 0xAB // Get OSD Status Header Vertical Size (Y).
|
|
||||||
#define VCADDR_8BIT_OSDFTR_SZX VC_8BIT_BASE_ADDR + 0xAC // Get OSD Status Footer Horizontal Size (X).
|
|
||||||
#define VCADDR_8BIT_OSDFTR_SZY VC_8BIT_BASE_ADDR + 0xAD // Get OSD Status Footer Vertical Size (Y).
|
|
||||||
#define VCADDR_8BIT_VMPALETTE VC_8BIT_BASE_ADDR + 0xB0 // Sets the palette. The Video Module supports 4 bit per colour output but there is only enough RAM for 1 bit per colour so the pallette is used to change the colours output.
|
|
||||||
// Bits [7:0] defines the pallete number. This indexes a lookup table which contains the required 4bit output per 1bit input.
|
|
||||||
#define VCADDR_8BIT_GPUPARAM VC_8BIT_BASE_ADDR + 0xB2 // Set parameters. Store parameters in a long word to be used by the graphics command processor.
|
|
||||||
// The parameter word is 128 bit and each write to the parameter word shifts left by 8 bits and adds the new byte at bits 7:0.
|
|
||||||
#define VCADDR_8BIT_GPUCMD VC_8BIT_BASE_ADDR + 0xB3 // Set the graphics processor unit commands.
|
|
||||||
// Bits [5:0] - 0 = Reset parameters.
|
|
||||||
// 1 = Clear to val. Start Location (16 bit), End Location (16 bit), Red Filter, Green Filter, Blue Filter
|
|
||||||
#define VCADDR_8BIT_VMCTRL VC_8BIT_BASE_ADDR + 0xB8 // Video Module control register. [2:0] - 000 (default) = MZ80A, 001 = MZ-700, 010 = MZ800, 011 = MZ80B, 100 = MZ80K, 101 = MZ80C, 110 = MZ1200, 111 = MZ2000. [3] = 0 - 40 col, 1 - 80 col.
|
|
||||||
#define VCADDR_8BIT_VMGRMODE VC_8BIT_BASE_ADDR + 0xB9 // Video Module graphics mode. 7/6 = Operator (00=OR,01=AND,10=NAND,11=XOR), 5=GRAM Output Enable, 4 = VRAM Output Enable, 3/2 = Write mode (00=Page 1:Red, 01=Page 2:Green, 10=Page 3:Blue, 11=Indirect), 1/0=Read mode (00=Page 1:Red, 01=Page2:Green, 10=Page 3:Blue, 11=Not used).
|
|
||||||
#define VCADDR_8BIT_VMREDMASK VC_8BIT_BASE_ADDR + 0xBA // Video Module Red bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
|
||||||
#define VCADDR_8BIT_VMGREENMASK VC_8BIT_BASE_ADDR + 0xBB // Video Module Green bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
|
||||||
#define VCADDR_8BIT_VMBLUEMASK VC_8BIT_BASE_ADDR + 0xBC // Video Module Blue bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
|
||||||
#define VCADDR_8BIT_VMPAGE VC_8BIT_BASE_ADDR + 0xBD // Video Module memory page register. [1:0] switches in 1 16Kb page (3 pages) of graphics ram to C000 - FFFF. Bits [1:0] = page, 00 = off, 01 = Red, 10 = Green, 11 = Blue. This overrides all MZ700/MZ80B page switching functions. [7] 0 - normal, 1 - switches in CGROM for upload at D000:DFFF.
|
|
||||||
#define VCADDR_8BIT_VMVGATTR VC_8BIT_BASE_ADDR + 0xBE // Select VGA Border colour and attributes. Bit 2 = Red, 1 = Green, 0 = Blue, 4:3 = VGA Mode, 00 = Off, 01 = 640x480, 10 = 800x600, 11 = 50Hz Internal
|
|
||||||
#define VCADDR_8BIT_VMVGAMODE VC_8BIT_BASE_ADDR + 0xBF // Select VGA Output mode. [3:0] - required output resolution/frequency.
|
|
||||||
#define VCADDR_8BIT_SYSCTRL VC_8BIT_BASE_ADDR + 0xF0 // System board control register. [2:0] - 000 MZ80A Mode, 2MHz CPU/Bus, 001 MZ80B Mode, 4MHz CPU/Bus, 010 MZ700 Mode, 3.54MHz CPU/Bus.
|
|
||||||
#define VCADDR_8BIT_GRAMMODE VC_8BIT_BASE_ADDR + 0xF4 // MZ80B Graphics mode. Bit 0 = 0, Write to Graphics RAM I, Bit 0 = 1, Write to Graphics RAM II. Bit 1 = 1, blend Graphics RAM I output on display, Bit 2 = 1, blend Graphics RAM II output on display.
|
|
||||||
#define VCADDR_8BIT_VMPALETTE VC_8BIT_BASE_ADDR + 0xF5 // Select Palette:
|
|
||||||
// 0xF5 sets the palette. The Video Module supports 4 bit per colour output but there is only enough RAM for 1 bit per colour so the pallette is used to change the colours output.
|
|
||||||
// Bits [7:0] defines the pallete number. This indexes a lookup table which contains the required 4bit output per 1bit input.
|
|
||||||
|
|
||||||
#define VCADDR_8BIT_KEYPA VC_8BIT_BASE_ADDR + 0xE000 // VideoModule 8255 Port A
|
|
||||||
#define VCADDR_8BIT_KEYPB VC_8BIT_BASE_ADDR + 0xE001 // VideoModule 8255 Port B
|
|
||||||
#define VCADDR_8BIT_KEYPC VC_8BIT_BASE_ADDR + 0xE002 // VideoModule 8255 Port C
|
|
||||||
#define VCADDR_8BIT_KEYPF VC_8BIT_BASE_ADDR + 0xE003 // VideoModule 8255 Mode Control
|
|
||||||
#define VCADDR_8BIT_CSTR VC_8BIT_BASE_ADDR + 0xE002 // VideoModule 8255 Port C
|
|
||||||
#define VCADDR_8BIT_CSTPT VC_8BIT_BASE_ADDR + 0xE003 // VideoModule 8255 Mode Control
|
|
||||||
#define VCADDR_8BIT_CONT0 VC_8BIT_BASE_ADDR + 0xE004 // VideoModule 8253 Counter 0
|
|
||||||
#define VCADDR_8BIT_CONT1 VC_8BIT_BASE_ADDR + 0xE005 // VideoModule 8253 Counter 1
|
|
||||||
#define VCADDR_8BIT_CONT2 VC_8BIT_BASE_ADDR + 0xE006 // VideoModule 8253 Counter 1
|
|
||||||
#define VCADDR_8BIT_CONTF VC_8BIT_BASE_ADDR + 0xE007 // VideoModule 8253 Mode Control
|
|
||||||
#define VCADDR_8BIT_SUNDG VC_8BIT_BASE_ADDR + 0xE008 // Register for reading the tempo timer status (cursor flash). horizontal blank and switching sound on/off.
|
|
||||||
#define VCADDR_8BIT_TEMP VC_8BIT_BASE_ADDR + 0xE008 // As above, different name used in original source when writing.
|
|
||||||
#define VCADDR_8BIT_MEMSW VC_8BIT_BASE_ADDR + 0xE00C // Memory swap, 0000->C000, C000->0000
|
|
||||||
#define VCADDR_8BIT_MEMSWR VC_8BIT_BASE_ADDR + 0xE010 // Reset memory swap.
|
|
||||||
#define VCADDR_8BIT_INVDSP VC_8BIT_BASE_ADDR + 0xE014 // Invert display.
|
|
||||||
#define VCADDR_8BIT_NRMDSP VC_8BIT_BASE_ADDR + 0xE015 // Return display to normal.
|
|
||||||
#define VCADDR_8BIT_SCLDSP VC_8BIT_BASE_ADDR + 0xE200 // Hardware scroll, a read to each location adds 8 to the start of the video access address therefore creating hardware scroll. 00 - reset to power up
|
|
||||||
#define VCADDR_8BIT_SCLBASE VC_8BIT_BASE_ADDR + 0xE2 // High byte scroll base.
|
|
||||||
|
|
||||||
// Memory addresses of Sharp MZ Series emulator registers and memory.
|
|
||||||
//
|
|
||||||
#define MZ_EMU_REG_INTR_ADDR MZ_EMU_BASE_ADDR + 0x020 // Base address of the interrupt generator.
|
|
||||||
#define MZ_EMU_REG_KEYB_ADDR MZ_EMU_BASE_ADDR + 0x200 // Base address of the keyboard register and map table.
|
|
||||||
#define MZ_EMU_ADDR_REG_MODEL MZ_EMU_BASE_ADDR + 0 // Address of the machine MODEL configuration register.
|
|
||||||
#define MZ_EMU_ADDR_REG_DISPLAY MZ_EMU_BASE_ADDR + 1 // Address of the DISPLAY configuration register 1.
|
|
||||||
#define MZ_EMU_ADDR_REG_DISPLAY2 MZ_EMU_BASE_ADDR + 2 // Address of the DISPLAY configuration register 2.
|
|
||||||
#define MZ_EMU_ADDR_REG_DISPLAY3 MZ_EMU_BASE_ADDR + 3 // Address of the DISPLAY configuration register 3.
|
|
||||||
#define MZ_EMU_ADDR_REG_CPU MZ_EMU_BASE_ADDR + 4 // Address of the CPU configuration register.
|
|
||||||
#define MZ_EMU_ADDR_REG_AUDIO MZ_EMU_BASE_ADDR + 5 // Address of the AUDIO configuration register.
|
|
||||||
#define MZ_EMU_ADDR_REG_CMT MZ_EMU_BASE_ADDR + 6 // Address of the CMT (tape drive) configuration register 1.
|
|
||||||
#define MZ_EMU_ADDR_REG_CMT2 MZ_EMU_BASE_ADDR + 7 // Address of the CMT (tape drive) configuration register 2.
|
|
||||||
#define MZ_EMU_ADDR_REG_CMT3 MZ_EMU_BASE_ADDR + 8 // Address of the CMT (tape drive) configuration register 3.
|
|
||||||
#define MZ_EMU_ADDR_REG_FDD MZ_EMU_BASE_ADDR + 9 // Address of the Floppy Disk Drive configuration register 1.
|
|
||||||
#define MZ_EMU_ADDR_REG_FDD2 MZ_EMU_BASE_ADDR + 10 // Address of the Floppy Disk Drive configuration register 2.
|
|
||||||
#define MZ_EMU_ADDR_REG_FDD3 MZ_EMU_BASE_ADDR + 11 // Address of the Floppy Disk Drive configuration register 3.
|
|
||||||
#define MZ_EMU_ADDR_REG_FDD4 MZ_EMU_BASE_ADDR + 12 // Address of the Floppy Disk Drive configuration register 4.
|
|
||||||
#define MZ_EMU_ADDR_REG_ROMS MZ_EMU_BASE_ADDR + 13 // Address of the optional ROMS configuration register.
|
|
||||||
#define MZ_EMU_ADDR_REG_SWITCHES MZ_EMU_BASE_ADDR + 14 // Address of the Hardware configuration switches.
|
|
||||||
#define MZ_EMU_ADDR_REG_CTRL MZ_EMU_BASE_ADDR + 15 // Address of the Control reigster.
|
|
||||||
#define MZ_EMU_INTR_ISR 0x00 // Interupt service reason register, define what caused the interupt.
|
|
||||||
#define MZ_EMU_KEYB_KEY_MATRIX 0x00 // Key matrix array current scan.
|
|
||||||
#define MZ_EMU_KEYB_KEY_MATRIX_LAST 0x10 // Key matrix array previous scan.
|
|
||||||
#define MZ_EMU_KEYB_CTRL_REG 0x20 // Keyboard control register.
|
|
||||||
#define MZ_EMU_KEYB_KEYD_REG 0x21 // Keyboard key data register.
|
|
||||||
#define MZ_EMU_KEYB_KEYC_REG 0x22 // Keyboard control data register.
|
|
||||||
#define MZ_EMU_KEYB_KEY_POS_REG 0x23 // Keyboard mapped character mapping position.
|
|
||||||
#define MZ_EMU_KEYB_KEY_POS_LAST_REG 0x24 // Keyboard mapped character previous mapping position.
|
|
||||||
|
|
||||||
#define MZ_EMU_INTR_MAX_REGISTERS 1 // Maximum number of registers in the interrupt generator.
|
|
||||||
#define MZ_EMU_KEYB_MAX_REGISTERS 37 // Maximum number of registers in the keyboard interface.
|
|
||||||
|
|
||||||
#define MZ_EMU_REG_MODEL 0 // Machine MODEL configuration register.
|
|
||||||
#define MZ_EMU_REG_DISPLAY 1 // DISPLAY configuration register 1.
|
|
||||||
#define MZ_EMU_REG_DISPLAY2 2 // DISPLAY configuration register 2.
|
|
||||||
#define MZ_EMU_REG_DISPLAY3 3 // DISPLAY configuration register 3.
|
|
||||||
#define MZ_EMU_REG_CPU 4 // CPU configuration register.
|
|
||||||
#define MZ_EMU_REG_AUDIO 5 // AUDIO configuration register.
|
|
||||||
#define MZ_EMU_REG_CMT 6 // CMT (tape drive) configuration register 1.
|
|
||||||
#define MZ_EMU_REG_CMT2 7 // CMT (tape drive) configuration register 2.
|
|
||||||
#define MZ_EMU_REG_CMT3 8 // CMT (tape drive) configuration register 2.
|
|
||||||
#define MZ_EMU_REG_FDD 9 // Floppy Disk Drive configuration register 1.
|
|
||||||
#define MZ_EMU_REG_FDD2 10 // Floppy Disk Drive configuration register 2.
|
|
||||||
#define MZ_EMU_REG_FDD3 11 // Floppy Disk Drive configuration register 3.
|
|
||||||
#define MZ_EMU_REG_FDD4 12 // Floppy Disk Drive configuration register 4.
|
|
||||||
#define MZ_EMU_REG_ROMS 13 // Options ROMS configuration
|
|
||||||
#define MZ_EMU_REG_SWITCHES 14 // Hardware switches, MZ800 = 3:0
|
|
||||||
#define MZ_EMU_REG_CTRL 15 // Emulation control register.
|
|
||||||
#define MZ_EMU_MAX_REGISTERS 16 // Maximum number of registers on the emulator.
|
|
||||||
#define MZ_EMU_KEYB_DISABLE_EMU 0x01 // Disable keyboard scan codes being sent to the emulation.
|
|
||||||
#define MZ_EMU_KEYB_ENABLE_INTR 0x02 // Enable interrupt on every key press.
|
|
||||||
|
|
||||||
#define MZ_EMU_DISPLAY_MONO 0x00 // Monochrome display.
|
|
||||||
#define MZ_EMU_DISPLAY_MONO80 0x01 // Monochrome 80 column display.
|
|
||||||
#define MZ_EMU_DISPLAY_COLOUR 0x02 // Colour display.
|
|
||||||
#define MZ_EMU_DISPLAY_COLOUR80 0x03 // Colour 80 column display.
|
|
||||||
#define MZ_EMU_DISPLAY_VRAM_ON 0x00 // Video RAM enable.
|
|
||||||
#define MZ_EMU_DISPLAY_VRAM_OFF 0x04 // Video RAM disable.
|
|
||||||
#define MZ_EMU_DISPLAY_GRAM_ON 0x00 // Graphics RAM enable.
|
|
||||||
#define MZ_EMU_DISPLAY_GRAM_OFF 0x08 // Graphics RAM disable.
|
|
||||||
#define MZ_EMU_DISPLAY_VIDWAIT_ON 0x10 // Enable Video Wait States
|
|
||||||
#define MZ_EMU_DISPLAY_VIDWAIT_OFF 0x00 // Disable Video Wait States
|
|
||||||
#define MZ_EMU_DISPLAY_PCG_ON 0x80 // Enable the Programmable Character Generator.
|
|
||||||
#define MZ_EMU_DISPLAY_PCG_OFF 0x00 // Disable the Programmable Character Generator.
|
|
||||||
#define MZ_EMU_B_CPU_SPEED_4M 0x00 // CPU Freq for the MZ80B group machines.
|
|
||||||
#define MZ_EMU_B_CPU_SPEED_8M 0x01 // CPU Freq for the MZ80B group machines.
|
|
||||||
#define MZ_EMU_B_CPU_SPEED_16M 0x02 // CPU Freq for the MZ80B group machines.
|
|
||||||
#define MZ_EMU_B_CPU_SPEED_32M 0x03 // CPU Freq for the MZ80B group machines.
|
|
||||||
#define MZ_EMU_B_CPU_SPEED_64M 0x04 // CPU Freq for the MZ80B group machines.
|
|
||||||
#define MZ_EMU_C_CPU_SPEED_2M 0x00 // CPU Freq for the MZ80C group machines.
|
|
||||||
#define MZ_EMU_C_CPU_SPEED_4M 0x01 // CPU Freq for the MZ80C group machines.
|
|
||||||
#define MZ_EMU_C_CPU_SPEED_8M 0x02 // CPU Freq for the MZ80C group machines.
|
|
||||||
#define MZ_EMU_C_CPU_SPEED_16M 0x03 // CPU Freq for the MZ80C group machines.
|
|
||||||
#define MZ_EMU_C_CPU_SPEED_32M 0x04 // CPU Freq for the MZ80C group machines.
|
|
||||||
#define MZ_EMU_C_CPU_SPEED_64M 0x05 // CPU Freq for the MZ80C group machines.
|
|
||||||
#define MZ_EMU_78_CPU_SPEED_3M5 0x00 // CPU Freq for the MZ80/700/800 group machines.
|
|
||||||
#define MZ_EMU_78_CPU_SPEED_7M 0x01 // CPU Freq for the MZ80/700/800 group machines.
|
|
||||||
#define MZ_EMU_78_CPU_SPEED_14M 0x02 // CPU Freq for the MZ80/700/800 group machines.
|
|
||||||
#define MZ_EMU_78_CPU_SPEED_28M 0x03 // CPU Freq for the MZ80/700/800 group machines.
|
|
||||||
#define MZ_EMU_78_CPU_SPEED_56M 0x04 // CPU Freq for the MZ80/700/800 group machines.
|
|
||||||
#define MZ_EMU_78_CPU_SPEED_112M 0x05 // CPU Freq for the MZ80/700/800 group machines.
|
|
||||||
#define MZ_EMU_CMT_SPEED_NORMAL 0x00 // CMT runs at normal speed for the selected model.
|
|
||||||
#define MZ_EMU_CMT_SPEED_2X 0x01 // CMT runs at 2x speed.
|
|
||||||
#define MZ_EMU_CMT_SPEED_4X 0x02 // CMT runs at 4x speed.
|
|
||||||
#define MZ_EMU_CMT_SPEED_8X 0x03 // CMT runs at 8x speed.
|
|
||||||
#define MZ_EMU_CMT_SPEED_16X 0x04 // CMT runs at 16x speed.
|
|
||||||
#define MZ_EMU_CMT_SPEED_32X 0x05 // CMT runs at 32x speed.
|
|
||||||
#define MZ_EMU_CMT_BUTTON_OFF 0x00 // CMT keys are off.
|
|
||||||
#define MZ_EMU_CMT_BUTTON_PLAY 0x08 // CMT PLAY button is pressed.
|
|
||||||
#define MZ_EMU_CMT_BUTTON_RECORD 0x10 // CMT RECORD button is pressed.
|
|
||||||
#define MZ_EMU_CMT_BUTTON_AUTO 0x18 // CMT auto logic enabled to select button according to state.
|
|
||||||
#define MZ_EMU_CMT_ASCIIIN 0x20 // Enable ASCII translation of filenames going into the CMT.
|
|
||||||
#define MZ_EMU_CMT_ASCIIOUT 0x40 // Enable ASCII translation of filenames output by the CMT.
|
|
||||||
#define MZ_EMU_CMT_HARDWARE 0x80 // Enable use of the physical host cassette drive instead of the CMT emulation.
|
|
||||||
|
|
||||||
// IO addresses on the tranZPUter or mainboard.
|
|
||||||
//
|
|
||||||
#define IO_TZ_CTRLLATCH 0x60 // Control latch which specifies the Memory Model/mode.
|
|
||||||
#define IO_TZ_SETXMHZ 0x62 // Switch to alternate CPU frequency provided by K64F.
|
|
||||||
#define IO_TZ_SET2MHZ 0x64 // Switch to system CPU frequency.
|
|
||||||
#define IO_TZ_CLKSELRD 0x66 // Read the status of the clock select, ie. which clock is connected to the CPU.
|
|
||||||
#define IO_TZ_SVCREQ 0x68 // Service request from the Z80 to be provided by the K64F.
|
|
||||||
#define IO_TZ_SYSREQ 0x6A // System request from the Z80 to be provided by the K64F.
|
|
||||||
#define IO_TZ_CPLDSTATUS 0x6B // Version 2.1 CPLD status register.
|
|
||||||
#define IO_TZ_CPUCFG 0x6C // Version 2.2 CPU configuration register.
|
|
||||||
#define IO_TZ_CPUSTATUS 0x6C // Version 2.2 CPU runtime status register.
|
|
||||||
#define IO_TZ_CPUINFO 0x6D // Version 2.2 CPU information register.
|
|
||||||
#define IO_TZ_CPLDCFG 0x6E // Version 2.1 CPLD configuration register.
|
|
||||||
#define IO_TZ_CPLDINFO 0x6F // Version 2.1 CPLD version information register.
|
|
||||||
#define IO_TZ_CPLDINFO 0x6F // Version 2.1 CPLD version information register.
|
|
||||||
#define IO_TZ_PALSLCTOFF 0xA3 // Set the palette slot (PALETTE_PARAM_SEL) Off position to be adjusted.
|
|
||||||
#define IO_TZ_PALSLCTON 0xA4 // Set the palette slot (PALETTE_PARAM_SEL) On position to be adjusted.
|
|
||||||
#define IO_TZ_PALSETRED 0xA5 // Set the red palette value according to the PALETTE_PARAM_SEL address.
|
|
||||||
#define IO_TZ_PALSETGREEN 0xA6 // Set the green palette value according to the PALETTE_PARAM_SEL address.
|
|
||||||
#define IO_TZ_PALSETBLUE 0xA7 // Set the blue palette value according to the PALETTE_PARAM_SEL address.
|
|
||||||
#define IO_TZ_OSDMNU_SZX 0xA8 // Get OSD Menu Horizontal Size (X).
|
|
||||||
#define IO_TZ_OSDMNU_SZY 0xA9 // Get OSD Menu Vertical Size (Y).
|
|
||||||
#define IO_TZ_OSDHDR_SZX 0xAA // Get OSD Status Header Horizontal Size (X).
|
|
||||||
#define IO_TZ_OSDHDR_SZY 0xAB // Get OSD Status Header Vertical Size (Y).
|
|
||||||
#define IO_TZ_OSDFTR_SZX 0xAC // Get OSD Status Footer Horizontal Size (X).
|
|
||||||
#define IO_TZ_OSDFTR_SZY 0xAD // Get OSD Status Footer Vertical Size (Y).
|
|
||||||
#define IO_TZ_PALETTE 0xB0 // Sets the palette. The Video Module supports 4 bit per colour output but there is only enough RAM for 1 bit per colour so the pallette is used to change the colours output.
|
|
||||||
// Bits [7:0] defines the pallete number. This indexes a lookup table which contains the required 4bit output per 1bit input.
|
|
||||||
#define IO_TZ_GPUPARAM 0xB2 // Set parameters. Store parameters in a long word to be used by the graphics command processor.
|
|
||||||
// The parameter word is 128 bit and each write to the parameter word shifts left by 8 bits and adds the new byte at bits 7:0.
|
|
||||||
#define IO_TZ_GPUCMD 0xB3 // Set the graphics processor unit commands.
|
|
||||||
// Bits [5:0] - 0 = Reset parameters.
|
|
||||||
// 1 = Clear to val. Start Location (16 bit), End Location (16 bit), Red Filter, Green Filter, Blue Filter
|
|
||||||
#define IO_TZ_VMCTRL 0xB8 // Video Module control register. [2:0] - 000 (default) = MZ80A, 001 = MZ-700, 010 = MZ800, 011 = MZ80B, 100 = MZ80K, 101 = MZ80C, 110 = MZ1200, 111 = MZ2000. [3] = 0 - 40 col, 1 - 80 col.
|
|
||||||
#define IO_TZ_VMGRMODE 0xB9 // Video Module graphics mode. 7/6 = Operator (00=OR,01=AND,10=NAND,11=XOR), 5=GRAM Output Enable, 4 = VRAM Output Enable, 3/2 = Write mode (00=Page 1:Red, 01=Page 2:Green, 10=Page 3:Blue, 11=Indirect), 1/0=Read mode (00=Page 1:Red, 01=Page2:Green, 10=Page 3:Blue, 11=Not used).
|
|
||||||
#define IO_TZ_VMREDMASK 0xBA // Video Module Red bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
|
||||||
#define IO_TZ_VMGREENMASK 0xBB // Video Module Green bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
|
||||||
#define IO_TZ_VMBLUEMASK 0xBC // Video Module Blue bit mask (1 bit = 1 pixel, 8 pixels per byte).
|
|
||||||
#define IO_TZ_VMPAGE 0xBD // Video Module memory page register. [1:0] switches in 1 16Kb page (3 pages) of graphics ram to C000 - FFFF. Bits [1:0] = page, 00 = off, 01 = Red, 10 = Green, 11 = Blue. This overrides all MZ700/MZ80B page switching functions. [7] 0 - normal, 1 - switches in CGROM for upload at D000:DFFF.
|
|
||||||
#define IO_TZ_VMVGATTR 0xBE // Select VGA Border colour and attributes. Bit 2 = Red, 1 = Green, 0 = Blue, 4:3 = VGA Mode, 00 = Off, 01 = 640x480, 10 = 800x600, 11 = 50Hz Internal
|
|
||||||
#define IO_TZ_VMVGAMODE 0xBF // Select VGA Output mode. [3:0] - required output resolution/frequency.
|
|
||||||
#define IO_TZ_GDGWF 0xCC // MZ-800 write format register
|
|
||||||
#define IO_TZ_GDGRF 0xCD // MZ-800 read format register
|
|
||||||
#define IO_TZ_GDCMD 0xCE // MZ-800 CRTC Mode register
|
|
||||||
#define IO_TZ_GDCMD 0xCF // MZ-800 CRTC control register
|
|
||||||
#define IO_TZ_MMIO0 0xE0 // MZ-700/MZ-800 Memory management selection ports.
|
|
||||||
#define IO_TZ_MMIO1 0xE1 // ""
|
|
||||||
#define IO_TZ_MMIO2 0xE2 // ""
|
|
||||||
#define IO_TZ_MMIO3 0xE3 // ""
|
|
||||||
#define IO_TZ_MMIO4 0xE4 // ""
|
|
||||||
#define IO_TZ_MMIO5 0xE5 // ""
|
|
||||||
#define IO_TZ_MMIO6 0xE6 // ""
|
|
||||||
#define IO_TZ_MMIO7 0xE7 // MZ-700/MZ-800 Memory management selection ports.
|
|
||||||
#define IO_TZ_PPIA 0xE0 // MZ80B/MZ2000 8255 PPI Port A
|
|
||||||
#define IO_TZ_PPIB 0xE1 // MZ80B/MZ2000 8255 PPI Port B
|
|
||||||
#define IO_TZ_PPIC 0xE2 // MZ80B/MZ2000 8255 PPI Port C
|
|
||||||
#define IO_TZ_PPICTL 0xE3 // MZ80B/MZ2000 8255 PPI Control Register
|
|
||||||
#define IO_TZ_PIT0 0xE4 // MZ80B/MZ2000 8253 PIT Timer 0
|
|
||||||
#define IO_TZ_PIT1 0xE5 // MZ80B/MZ2000 8253 PIT Timer 1
|
|
||||||
#define IO_TZ_PIT2 0xE6 // MZ80B/MZ2000 8253 PIT Timer 2
|
|
||||||
#define IO_TZ_PITCTL 0xE7 // MZ80B/MZ2000 8253 PIT Control Register
|
|
||||||
#define IO_TZ_PIOA 0xE8 // MZ80B/MZ2000 Z80 PIO Port A
|
|
||||||
#define IO_TZ_PIOCTLA 0xE9 // MZ80B/MZ2000 Z80 PIO Port A Control Register
|
|
||||||
#define IO_TZ_PIOB 0xEA // MZ80B/MZ2000 Z80 PIO Port B
|
|
||||||
#define IO_TZ_PIOCTLB 0xEB // MZ80B/MZ2000 Z80 PIO Port B Control Register
|
|
||||||
#define IO_TZ_SYSCTRL 0xF0 // System board control register. [2:0] - 000 MZ80A Mode, 2MHz CPU/Bus, 001 MZ80B Mode, 4MHz CPU/Bus, 010 MZ700 Mode, 3.54MHz CPU/Bus.
|
|
||||||
#define IO_TZ_GRAMMODE 0xF4 // MZ80B Graphics mode. Bit 0 = 0, Write to Graphics RAM I, Bit 0 = 1, Write to Graphics RAM II. Bit 1 = 1, blend Graphics RAM I output on display, Bit 2 = 1, blend Graphics RAM II output on display.
|
|
||||||
//#define IO_TZ_GRAMOPT 0xF4 // MZ80B/MZ2000 GRAM configuration option.
|
|
||||||
#define IO_TZ_CRTGRPHPRIO 0xF5 // MZ2000 Graphics priority register, character or a graphics colour has front display priority.
|
|
||||||
#define IO_TZ_CRTGRPHSEL 0xF6 // MZ2000 Graphics output select on CRT or external CRT
|
|
||||||
#define IO_TZ_GRAMCOLRSEL 0xF7 // MZ2000 Graphics RAM colour bank select.
|
|
||||||
|
|
||||||
|
|
||||||
// IO register constants.
|
|
||||||
//
|
|
||||||
#define CPUMODE_SET_Z80 0x00 // Set the CPU to the hard Z80.
|
|
||||||
#define CPUMODE_SET_T80 0x01 // Set the CPU to the soft T80.
|
|
||||||
#define CPUMODE_SET_ZPU_EVO 0x02 // Set the CPU to the soft ZPU Evolution.
|
|
||||||
#define CPUMODE_SET_AAA 0x04 // Place holder for a future soft CPU.
|
|
||||||
#define CPUMODE_SET_BBB 0x08 // Place holder for a future soft CPU.
|
|
||||||
#define CPUMODE_SET_CCC 0x10 // Place holder for a future soft CPU.
|
|
||||||
#define CPUMODE_SET_DDD 0x20 // Place holder for a future soft CPU.
|
|
||||||
#define CPUMODE_IS_Z80 0x00 // Status value to indicate if the hard Z80 available.
|
|
||||||
#define CPUMODE_IS_T80 0x01 // Status value to indicate if the soft T80 available.
|
|
||||||
#define CPUMODE_IS_ZPU_EVOL 0x02 // Status value to indicate if the soft ZPU Evolution available.
|
|
||||||
#define CPUMODE_IS_AAA 0x04 // Place holder to indicate if a future soft CPU is available.
|
|
||||||
#define CPUMODE_IS_BBB 0x08 // Place holder to indicate if a future soft CPU is available.
|
|
||||||
#define CPUMODE_IS_CCC 0x10 // Place holder to indicate if a future soft CPU is available.
|
|
||||||
#define CPUMODE_IS_DDD 0x20 // Place holder to indicate if a future soft CPU is available.
|
|
||||||
#define CPUMODE_RESET_CPU 0x80 // Reset the soft CPU. Active high, when high the CPU is held in RESET, when low the CPU runs.
|
|
||||||
#define CPUMODE_IS_SOFT_AVAIL 0x040 // Marker to indicate if the underlying FPGA can support soft CPU's.
|
|
||||||
#define CPUMODE_IS_SOFT_MASK 0x0C0 // Mask to filter out the Soft CPU availability flags.
|
|
||||||
|
|
||||||
// Video Module control bits.
|
|
||||||
#define SYSMODE_MZ80A 0x00 // System board mode MZ80A, 2MHz CPU/Bus.
|
|
||||||
#define SYSMODE_MZ80B 0x01 // System board mode MZ80B, 4MHz CPU/Bus.
|
|
||||||
#define SYSMODE_MZ700 0x02 // System board mode MZ700, 3.54MHz CPU/Bus.
|
|
||||||
#define VMMODE_MASK 0xF8 // Mask to mask out video mode.
|
|
||||||
#define VMMODE_MZ80K 0x00 // Video mode = MZ80K
|
|
||||||
#define VMMODE_MZ80C 0x01 // Video mode = MZ80C
|
|
||||||
#define VMMODE_MZ1200 0x02 // Video mode = MZ1200
|
|
||||||
#define VMMODE_MZ80A 0x03 // Video mode = MZ80A
|
|
||||||
#define VMMODE_MZ700 0x04 // Video mode = MZ700
|
|
||||||
#define VMMODE_MZ800 0x05 // Video mode = MZ800
|
|
||||||
#define VMMODE_MZ1500 0x06 // Video mode = MZ1500
|
|
||||||
#define VMMODE_MZ80B 0x07 // Video mode = MZ80B
|
|
||||||
#define VMMODE_MZ2000 0x08 // Video mode = MZ2000
|
|
||||||
#define VMMODE_MZ2200 0x09 // Video mode = MZ2200
|
|
||||||
#define VMMODE_MZ2500 0x0A // Video mode = MZ2500
|
|
||||||
#define VMMODE_80CHAR 0x10 // Enable 80 character display.
|
|
||||||
#define VMMODE_80CHAR_MASK 0xEF // Mask to filter out display width control bit.
|
|
||||||
#define VMMODE_COLOUR 0x20 // Enable colour display.
|
|
||||||
#define VMMODE_COLOUR_MASK 0xDF // Mask to filter out colour control bit.
|
|
||||||
#define VMMODE_PCGRAM 0x40 // Enable PCG RAM.
|
|
||||||
#define VMMODE_VGA_MASK 0xF0 // Mask to filter out the VGA output mode bits.
|
|
||||||
#define VMMODE_VGA_OFF 0x00 // Set VGA mode off, external monitor is driven by standard internal 60Hz signals.
|
|
||||||
#define VMMODE_VGA_INT 0x00 // Set VGA mode off, external monitor is driven by standard internal 60Hz signals.
|
|
||||||
#define VMMODE_VGA_INT50 0x01 // Set VGA mode off, external monitor is driven by standard internal 50Hz signals.
|
|
||||||
#define VMMODE_VGA_640x480 0x02 // Set external monitor to VGA 640x480 @ 60Hz mode.
|
|
||||||
#define VMMODE_VGA_800x600 0x03 // Set external monitor to VGA 800x600 @ 60Hz mode.
|
|
||||||
|
|
||||||
// VGA mode border control constants.
|
|
||||||
//
|
|
||||||
#define VMBORDER_BLACK 0x00 // VGA has a black border.
|
|
||||||
#define VMBORDER_BLUE 0x01 // VGA has a blue border.
|
|
||||||
#define VMBORDER_RED 0x02 // VGA has a red border.
|
|
||||||
#define VMBORDER_PURPLE 0x03 // VGA has a purple border.
|
|
||||||
#define VMBORDER_GREEN 0x04 // VGA has a green border.
|
|
||||||
#define VMBORDER_CYAN 0x05 // VGA has a cyan border.
|
|
||||||
#define VMBORDER_YELLOW 0x06 // VGA has a yellow border.
|
|
||||||
#define VMBORDER_WHITE 0x07 // VGA has a white border.
|
|
||||||
#define VMBORDER_MASK 0xF8 // Mask to filter out current border setting.
|
|
||||||
|
|
||||||
// Sharp MZ colour attributes.
|
|
||||||
#define VMATTR_FG_BLACK 0x00 // Foreground black character attribute.
|
|
||||||
#define VMATTR_FG_BLUE 0x10 // Foreground blue character attribute.
|
|
||||||
#define VMATTR_FG_RED 0x20 // Foreground red character attribute.
|
|
||||||
#define VMATTR_FG_PURPLE 0x30 // Foreground purple character attribute.
|
|
||||||
#define VMATTR_FG_GREEN 0x40 // Foreground green character attribute.
|
|
||||||
#define VMATTR_FG_CYAN 0x50 // Foreground cyan character attribute.
|
|
||||||
#define VMATTR_FG_YELLOW 0x60 // Foreground yellow character attribute.
|
|
||||||
#define VMATTR_FG_WHITE 0x70 // Foreground white character attribute.
|
|
||||||
#define VMATTR_FG_MASKOUT 0x8F // Mask to filter out foreground attribute.
|
|
||||||
#define VMATTR_FG_MASKIN 0x70 // Mask to filter out foreground attribute.
|
|
||||||
#define VMATTR_BG_BLACK 0x00 // Background black character attribute.
|
|
||||||
#define VMATTR_BG_BLUE 0x01 // Background blue character attribute.
|
|
||||||
#define VMATTR_BG_RED 0x02 // Background red character attribute.
|
|
||||||
#define VMATTR_BG_PURPLE 0x03 // Background purple character attribute.
|
|
||||||
#define VMATTR_BG_GREEN 0x04 // Background green character attribute.
|
|
||||||
#define VMATTR_BG_CYAN 0x05 // Background cyan character attribute.
|
|
||||||
#define VMATTR_BG_YELLOW 0x06 // Background yellow character attribute.
|
|
||||||
#define VMATTR_BG_WHITE 0x07 // Background white character attribute.
|
|
||||||
#define VMATTR_BG_MASKOUT 0xF8 // Mask to filter out background attribute.
|
|
||||||
#define VMATTR_BG_MASKIN 0x07 // Mask to filter out background attribute.
|
|
||||||
|
|
||||||
// Sharp MZ constants.
|
|
||||||
//
|
|
||||||
#define MZ_MROM_ADDR 0x0000 // Monitor ROM start address.
|
|
||||||
#define MZ_MROM_STACK_ADDR 0x1000 // Monitor ROM start stack address.
|
|
||||||
#define MZ_MROM_STACK_SIZE 0x0200 // Monitor ROM stack size.
|
|
||||||
#define MZ_UROM_ADDR 0xE800 // User ROM start address.
|
|
||||||
#define MZ_BANKRAM_ADDR 0xF000 // Floppy API address which is used in TZFS as the paged RAM for additional functionality.
|
|
||||||
#define MZ_CMT_ADDR 0x10F0 // Address of the CMT (tape) header record.
|
|
||||||
#define MZ_CMT_DEFAULT_LOAD_ADDR 0x1200 // The default load address for a CMT, anything below this is normally illegal.
|
|
||||||
#define MZ_VID_RAM_ADDR 0xD000 // Start of Video RAM
|
|
||||||
#define MZ_VID_RAM_SIZE 2048 // Size of Video RAM.
|
|
||||||
#define MZ_VID_DFLT_BYTE 0x00 // Default character (SPACE) for video RAM.
|
|
||||||
#define MZ_ATTR_RAM_ADDR 0xD800 // On machines with the upgrade, the start of the Attribute RAM.
|
|
||||||
#define MZ_ATTR_RAM_SIZE 2048 // Size of the attribute RAM.
|
|
||||||
#define MZ_ATTR_DFLT_BYTE 0x07 // Default colour (White on Black) for the attribute.
|
|
||||||
#define MZ_SCROL_BASE 0xE200 // Base address of the hardware scroll registers.
|
|
||||||
#define MZ_SCROL_END 0xE2FF // End address of the hardware scroll registers.
|
|
||||||
#define MZ_MEMORY_SWAP 0xE00C // Address when read swaps the memory from 0000-0FFF -> C000-CFFF
|
|
||||||
#define MZ_MEMORY_RESET 0xE010 // Address when read resets the memory to the default location 0000-0FFF.
|
|
||||||
#define MZ_CRT_NORMAL 0xE014 // Address when read sets the CRT to normal display mode.
|
|
||||||
#define MZ_CRT_INVERSE 0xE018 // Address when read sets the CRT to inverted display mode.
|
|
||||||
#define MZ_80A_CPU_FREQ 2000000 // CPU Speed of the Sharp MZ-80A
|
|
||||||
#define MZ_700_CPU_FREQ 3580000 // CPU Speed of the Sharp MZ-700
|
|
||||||
#define MZ_80B_CPU_FREQ 4000000 // CPU Speed of the Sharp MZ-80B
|
|
||||||
|
|
||||||
// Constants for the Sharp MZ80A MZF file format.
|
|
||||||
#define MZF_HEADER_SIZE 128 // Size of the MZF header.
|
|
||||||
#define MZF_ATTRIBUTE 0x00 // Code Type, 01 = Machine Code.
|
|
||||||
#define MZF_FILENAME 0x01 // Title/Name (17 bytes).
|
|
||||||
#define MZF_FILENAME_LEN 17 // Length of the filename, it is not NULL terminated, generally a CR can be taken as terminator but not guaranteed.
|
|
||||||
#define MZF_FILESIZE 0x12 // Size of program.
|
|
||||||
#define MZF_LOADADDR 0x14 // Load address of program.
|
|
||||||
#define MZF_EXECADDR 0x16 // Exec address of program.
|
|
||||||
#define MZF_COMMENT 0x18 // Comment, used for details of the file or startup code.
|
|
||||||
#define MZF_COMMENT_LEN 104 // Length of the comment field.
|
|
||||||
|
|
||||||
|
|
||||||
//Common character definitions.
|
|
||||||
#define SCROLL 0x01 // Set scroll direction UP.
|
|
||||||
#define BELL 0x07
|
|
||||||
#define SPACE 0x20
|
|
||||||
#define TAB 0x09 // TAB ACROSS (8 SPACES FOR SD-BOARD)
|
|
||||||
#define CR 0x0D
|
|
||||||
#define LF 0x0A
|
|
||||||
#define FF 0x0C
|
|
||||||
#define DELETE 0x7F
|
|
||||||
#define BACKS 0x08
|
|
||||||
#define SOH 0x01 // For XModem etc.
|
|
||||||
#define EOT 0x04
|
|
||||||
#define ACK 0x06
|
|
||||||
#define NAK 0x15
|
|
||||||
#define NUL 0x00
|
|
||||||
//#define NULL 0x00
|
|
||||||
#define CTRL_A 0x01
|
|
||||||
#define CTRL_B 0x02
|
|
||||||
#define CTRL_C 0x03
|
|
||||||
#define CTRL_D 0x04
|
|
||||||
#define CTRL_E 0x05
|
|
||||||
#define CTRL_F 0x06
|
|
||||||
#define CTRL_G 0x07
|
|
||||||
#define CTRL_H 0x08
|
|
||||||
#define CTRL_I 0x09
|
|
||||||
#define CTRL_J 0x0A
|
|
||||||
#define CTRL_K 0x0B
|
|
||||||
#define CTRL_L 0x0C
|
|
||||||
#define CTRL_M 0x0D
|
|
||||||
#define CTRL_N 0x0E
|
|
||||||
#define CTRL_O 0x0F
|
|
||||||
#define CTRL_P 0x10
|
|
||||||
#define CTRL_Q 0x11
|
|
||||||
#define CTRL_R 0x12
|
|
||||||
#define CTRL_S 0x13
|
|
||||||
#define CTRL_T 0x14
|
|
||||||
#define CTRL_U 0x15
|
|
||||||
#define CTRL_V 0x16
|
|
||||||
#define CTRL_W 0x17
|
|
||||||
#define CTRL_X 0x18
|
|
||||||
#define CTRL_Y 0x19
|
|
||||||
#define CTRL_Z 0x1A
|
|
||||||
#define ESC 0x1B
|
|
||||||
#define CTRL_SLASH 0x1C
|
|
||||||
#define CTRL_LB 0x1B
|
|
||||||
#define CTRL_RB 0x1D
|
|
||||||
#define CTRL_CAPPA 0x1E
|
|
||||||
#define CTRL_UNDSCR 0x1F
|
|
||||||
#define CTRL_AT 0x00
|
|
||||||
#define FUNC1 0x80
|
|
||||||
#define FUNC2 0x81
|
|
||||||
#define FUNC3 0x82
|
|
||||||
#define FUNC4 0x83
|
|
||||||
#define FUNC5 0x84
|
|
||||||
#define FUNC6 0x85
|
|
||||||
#define FUNC7 0x86
|
|
||||||
#define FUNC8 0x87
|
|
||||||
#define FUNC9 0x88
|
|
||||||
#define FUNC10 0x89
|
|
||||||
#define PAGEUP 0xE0
|
|
||||||
#define PAGEDOWN 0xE1
|
|
||||||
#define CURHOMEKEY 0xE2
|
|
||||||
#define NOKEY 0xF0
|
|
||||||
#define CURSRIGHT 0xF1
|
|
||||||
#define CURSLEFT 0xF2
|
|
||||||
#define CURSUP 0xF3
|
|
||||||
#define CURSDOWN 0xF4
|
|
||||||
#define DBLZERO 0xF5
|
|
||||||
#define INSERT 0xF6
|
|
||||||
#define CLRKEY 0xF7
|
|
||||||
#define HOMEKEY 0xF8
|
|
||||||
#define ENDKEY 0xF9
|
|
||||||
#define ANSITGLKEY 0xFA
|
|
||||||
#define BREAKKEY 0xFB
|
|
||||||
#define GRAPHKEY 0xFC
|
|
||||||
#define ALPHAKEY 0xFD
|
|
||||||
#define DEBUGKEY 0xFE // Special key to enable debug features such as the ANSI emulation.
|
|
||||||
|
|
||||||
// Macros.
|
|
||||||
//
|
|
||||||
// Convert big endiam to little endian.
|
|
||||||
#define convBigToLittleEndian(num) ((num>>24)&0xff) | ((num<<8)&0xff0000) | ((num>>8)&0xff00) | ((num<<24)&0xff000000)
|
|
||||||
#define setPixel(x,y,colour) if(y >= 0 && y < osdWindow.params[osdWindow.mode].maxY && x >= 0 && x < osdWindow.params[osdWindow.mode].maxX) \
|
|
||||||
{ \
|
|
||||||
for(uint8_t c=0; c < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); c++) \
|
|
||||||
{ \
|
|
||||||
if(colour & (1 << c)) \
|
|
||||||
{ \
|
|
||||||
osdWindow.display[c][((y * osdWindow.params[osdWindow.mode].maxX) + x)/8] |= 0x80 >> x%8; \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
#define clearPixel(x,y,colour) if(y >= 0 && y < osdWindow.params[osdWindow.mode].maxY && x >= 0 && x < osdWindow.params[osdWindow.mode].maxX) \
|
|
||||||
{ \
|
|
||||||
for(uint8_t c=0; c < (VC_MENU_RGB_BITS > VC_STATUS_RGB_BITS ? VC_MENU_RGB_BITS : VC_STATUS_RGB_BITS); c++) \
|
|
||||||
{ \
|
|
||||||
if(colour & (1 << c)) \
|
|
||||||
{ \
|
|
||||||
osdWindow.display[c][((y * osdWindow.params[osdWindow.mode].maxX) + x)/8] &= ~(0x80 >> x%8); \
|
|
||||||
} \
|
|
||||||
} \
|
|
||||||
}
|
|
||||||
|
|
||||||
// Supported windows.
|
|
||||||
enum WINDOWS {
|
|
||||||
STATUS = 0x00, // Status Window
|
|
||||||
MENU = 0x01 // Menu Window
|
|
||||||
};
|
|
||||||
|
|
||||||
// Supported orientation.
|
|
||||||
enum ORIENTATION {
|
|
||||||
NORMAL = 0x00, // Normal character orientation.
|
|
||||||
DEG90 = 0x01, // 90 degree rotation
|
|
||||||
DEG180 = 0x02, // 180 degree rotation
|
|
||||||
DEG270 = 0x03 // 270 degree rotation
|
|
||||||
};
|
|
||||||
|
|
||||||
// Supported colours.
|
|
||||||
enum COLOUR {
|
|
||||||
BLACK = 0x00, // No pixels active.
|
|
||||||
BLUE = 0x01, // Blue pixel active.
|
|
||||||
RED = 0x02, // Red pixel active.
|
|
||||||
PURPLE = 0x03, // Red and Blue pixels active.
|
|
||||||
GREEN = 0x04, // Green pixel active.
|
|
||||||
CYAN = 0x05, // Green and Blue pixels active.
|
|
||||||
YELLOW = 0x06, // Green and Red pixels active.
|
|
||||||
WHITE = 0x07 // Green, Red and Blue pixels active.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Supported attriutes/
|
|
||||||
enum ATTRIBUTES {
|
|
||||||
NOATTR = 0x0000, // No attributes.
|
|
||||||
HILIGHT_FG_ACTIVE = 0x0008, // Highlight flag.
|
|
||||||
HILIGHT_FG_BLACK = 0x0008 + 0x00, // Highlight the character foreground in black.
|
|
||||||
HILIGHT_FG_BLUE = 0x0008 + 0x01, // Highlight "" "" "" "" blue.
|
|
||||||
HILIGHT_FG_RED = 0x0008 + 0x02, // Highlight "" "" "" "" red.
|
|
||||||
HILIGHT_FG_PURPLE = 0x0008 + 0x03, // Highlight "" "" "" "" purple.
|
|
||||||
HILIGHT_FG_GREEN = 0x0008 + 0x04, // Highlight "" "" "" "" green.
|
|
||||||
HILIGHT_FG_CYAN = 0x0008 + 0x05, // Highlight "" "" "" "" cyan.
|
|
||||||
HILIGHT_FG_YELLOW = 0x0008 + 0x06, // Highlight "" "" "" "" yellow.
|
|
||||||
HILIGHT_FG_WHITE = 0x0008 + 0x07, // Highlight "" "" "" "" white.
|
|
||||||
HILIGHT_BG_ACTIVE = 0x0010, // Highlight flag.
|
|
||||||
HILIGHT_BG_BLACK = 0x0010 + 0x00, // Highlight the character background in black.
|
|
||||||
HILIGHT_BG_BLUE = 0x0010 + 0x01, // Highlight "" "" "" "" blue.
|
|
||||||
HILIGHT_BG_RED = 0x0010 + 0x02, // Highlight "" "" "" "" red.
|
|
||||||
HILIGHT_BG_PURPLE = 0x0010 + 0x03, // Highlight "" "" "" "" purple.
|
|
||||||
HILIGHT_BG_GREEN = 0x0010 + 0x04, // Highlight "" "" "" "" green.
|
|
||||||
HILIGHT_BG_CYAN = 0x0010 + 0x05, // Highlight "" "" "" "" cyan.
|
|
||||||
HILIGHT_BG_YELLOW = 0x0010 + 0x06, // Highlight "" "" "" "" yellow.
|
|
||||||
HILIGHT_BG_WHITE = 0x0010 + 0x07 // Highlight "" "" "" "" white.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Public settings, accessed via enumerated value.
|
|
||||||
enum OSDPARAMS {
|
|
||||||
ACTIVE_MAX_X = 0x00, // Width in pixels of the active framebuffer.
|
|
||||||
ACTIVE_MAX_Y = 0x01 // Depth in pixels of the active framebuffer.
|
|
||||||
};
|
|
||||||
|
|
||||||
// Structure to maintain data relevant to flashing a cursor at a given location.
|
|
||||||
//
|
|
||||||
typedef struct {
|
|
||||||
// Attributes to be used when cursor is showing.
|
|
||||||
uint16_t attr;
|
|
||||||
|
|
||||||
// Colour of the character,
|
|
||||||
enum COLOUR fg;
|
|
||||||
enum COLOUR bg;
|
|
||||||
|
|
||||||
// Location in the framebuffer where the character commences.
|
|
||||||
uint8_t row;
|
|
||||||
uint8_t col;
|
|
||||||
|
|
||||||
// Offset in pixels to the given row/col. Allows for finer placing within mixed fonts.
|
|
||||||
uint8_t ofrow;
|
|
||||||
uint8_t ofcol;
|
|
||||||
|
|
||||||
// Font used for the underlying character.
|
|
||||||
enum FONTS font;
|
|
||||||
|
|
||||||
// Flash speed of the cursor in ms.
|
|
||||||
unsigned long speed;
|
|
||||||
|
|
||||||
// Character being displayed.
|
|
||||||
uint8_t dispChar;
|
|
||||||
|
|
||||||
// Switch to enable/disable the cursor.
|
|
||||||
uint8_t enabled;
|
|
||||||
|
|
||||||
// Flash State.
|
|
||||||
uint8_t flashing;
|
|
||||||
} t_CursorFlash;
|
|
||||||
|
|
||||||
// Structure to maintain the OSD Menu and Status display output parameters and data.
|
|
||||||
//
|
|
||||||
typedef struct {
|
|
||||||
// Attributes for output data.
|
|
||||||
uint8_t attr;
|
|
||||||
|
|
||||||
// Location in the framebuffer to output data.
|
|
||||||
uint8_t row;
|
|
||||||
uint8_t col;
|
|
||||||
|
|
||||||
// Maxims, dynamic to allow for changes due to selected font.
|
|
||||||
uint8_t maxCol;
|
|
||||||
uint8_t maxRow;
|
|
||||||
|
|
||||||
// Window Features.
|
|
||||||
uint8_t lineWrap; // Wrap line at status window edge (1) else stop printing at status window edge.
|
|
||||||
uint16_t maxX; // Maximum X plane pixels.
|
|
||||||
uint16_t maxY; // Maximum Y plane pixels.
|
|
||||||
|
|
||||||
// Cursor data.
|
|
||||||
t_CursorFlash cursor; // Data for enabling a flashing cursor at a given screen coordinate.
|
|
||||||
} t_WindowParams;
|
|
||||||
|
|
||||||
// Structure to maintain the OSD window data.
|
|
||||||
typedef struct {
|
|
||||||
// Mode in which the OSD is operating.
|
|
||||||
enum WINDOWS mode;
|
|
||||||
|
|
||||||
// Per window parameters, currently a MENU and STATUS window exist.
|
|
||||||
t_WindowParams params[sizeof(enum WINDOWS)+1];
|
|
||||||
|
|
||||||
// Global features.
|
|
||||||
uint8_t debug; // Enable debugging features.
|
|
||||||
uint8_t inDebug; // Prevent recursion when outputting debug information.
|
|
||||||
|
|
||||||
// Framebuffer backing store. Data for display is assembled in this buffer prior to bulk copy into the FPGA memory.
|
|
||||||
uint8_t (*display)[VC_MENU_BUFFER_SIZE > VC_STATUS_BUFFER_SIZE ? VC_MENU_BUFFER_SIZE : VC_STATUS_BUFFER_SIZE];
|
|
||||||
} t_OSDWindow;
|
|
||||||
|
|
||||||
// Application execution constants.
|
|
||||||
//
|
|
||||||
|
|
||||||
// Prototypes.
|
|
||||||
//
|
|
||||||
|
|
||||||
uint32_t OSDGet(enum OSDPARAMS);
|
|
||||||
fontStruct *OSDGetFont(enum FONTS);
|
|
||||||
bitmapStruct *OSDGetBitmap(enum BITMAPS);
|
|
||||||
void OSDSetPixel(uint16_t, uint16_t, enum COLOUR);
|
|
||||||
void OSDClearPixel(uint16_t, uint16_t, enum COLOUR);
|
|
||||||
void OSDChangePixelColour(uint16_t, uint16_t, enum COLOUR, enum COLOUR);
|
|
||||||
void _OSDwrite(uint8_t, uint8_t, int8_t, int8_t, uint8_t, uint8_t, enum ORIENTATION, uint8_t, uint16_t, enum COLOUR, enum COLOUR, fontStruct *);
|
|
||||||
void OSDWriteBitmap(uint16_t, uint16_t, enum BITMAPS, enum COLOUR, enum COLOUR);
|
|
||||||
void OSDWriteChar(uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, uint8_t, enum FONTS, enum ORIENTATION, char, enum COLOUR, enum COLOUR);
|
|
||||||
void OSDWriteString(uint8_t, uint8_t, int8_t, int8_t, uint8_t, uint8_t, enum FONTS, enum ORIENTATION, char *, uint16_t *, enum COLOUR, enum COLOUR);
|
|
||||||
void OSDUpdateScreenSize(void);
|
|
||||||
void OSDRefreshScreen(void);
|
|
||||||
void OSDClearScreen(enum COLOUR);
|
|
||||||
void OSDClearArea(int16_t, int16_t, int16_t, int16_t, enum COLOUR);
|
|
||||||
void OSDDrawLine(int16_t, int16_t, int16_t, int16_t, enum COLOUR);
|
|
||||||
void OSDDrawCircle(int16_t, int16_t, int16_t, enum COLOUR);
|
|
||||||
void OSDDrawFilledCircle(int16_t, int16_t, int16_t, enum COLOUR);
|
|
||||||
void OSDDrawEllipse(int16_t, int16_t, int16_t, int16_t, enum COLOUR);
|
|
||||||
void OSDSetActiveWindow(enum WINDOWS);
|
|
||||||
void OSDSetCursorFlash(uint8_t, uint8_t, uint8_t, uint8_t, enum FONTS, uint8_t, enum COLOUR, enum COLOUR, uint16_t, unsigned long);
|
|
||||||
void OSDClearCursorFlash(void);
|
|
||||||
void OSDCursorFlash(void);
|
|
||||||
void OSDService(void);
|
|
||||||
uint8_t OSDInit(enum WINDOWS);
|
|
||||||
|
|
||||||
// Getter/Setter methods!
|
|
||||||
|
|
||||||
|
|
||||||
// Prototypes.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif // OSD_H
|
|
||||||
46
zOS/MZ2000/include/ps2.h
vendored
46
zOS/MZ2000/include/ps2.h
vendored
@@ -1,46 +0,0 @@
|
|||||||
#ifndef PS2_H
|
|
||||||
#define PS2_H
|
|
||||||
|
|
||||||
// Private
|
|
||||||
#define PS2_RINGBUFFER_SIZE 16 // 32 bytes
|
|
||||||
struct ps2_ringbuffer
|
|
||||||
{
|
|
||||||
volatile int in_hw;
|
|
||||||
volatile int in_cpu;
|
|
||||||
volatile int out_hw;
|
|
||||||
volatile int out_cpu;
|
|
||||||
unsigned int inbuf[PS2_RINGBUFFER_SIZE]; // Int is much easier than char for ZPU to deal with
|
|
||||||
unsigned int outbuf[PS2_RINGBUFFER_SIZE];
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ps2_ringbuffer_init(struct ps2_ringbuffer *r);
|
|
||||||
void ps2_ringbuffer_write(struct ps2_ringbuffer *r,int in);
|
|
||||||
int ps2_ringbuffer_read(struct ps2_ringbuffer *r);
|
|
||||||
int ps2_ringbuffer_count(struct ps2_ringbuffer *r);
|
|
||||||
extern struct ps2_ringbuffer kbbuffer;
|
|
||||||
extern struct ps2_ringbuffer mousebuffer;
|
|
||||||
void PS2Handler();
|
|
||||||
|
|
||||||
// Public interface
|
|
||||||
|
|
||||||
void PS2Init();
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PS2KeyboardRead(x) ps2_ringbuffer_read(&kbbuffer)
|
|
||||||
#define PS2KeyboardBytesReady(x) ps2_ringbuffer_count(&kbbuffer)
|
|
||||||
#define PS2KeyboardWrite(x) ps2_ringbuffer_write(&kbbuffer,x);
|
|
||||||
|
|
||||||
#define PS2MouseRead(x) ps2_ringbuffer_read(&mousebuffer)
|
|
||||||
#define PS2MouseBytesReady(x) ps2_ringbuffer_count(&mousebuffer)
|
|
||||||
#define PS2MouseWrite(x) ps2_ringbuffer_write(&mousebuffer,x);
|
|
||||||
|
|
||||||
#define PS2_INT 4
|
|
||||||
|
|
||||||
#endif
|
|
||||||
51
zOS/MZ2000/include/readline.h
vendored
51
zOS/MZ2000/include/readline.h
vendored
@@ -1,51 +0,0 @@
|
|||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Name: readline.h
|
|
||||||
// Created: April 2020
|
|
||||||
// Author(s): Alfred Klomp (www.alfredklomp.com) - original readline.c
|
|
||||||
// Philip Smart - Port to K64f/ZPU and additions of history buffer logic.
|
|
||||||
// Description: A readline module for embedded systems without the overhead of GNU readline or the
|
|
||||||
// need to use > C99 standard as the ZPU version of GCC doesnt support it!
|
|
||||||
// The readline modules originally came from Alfred Klomp's Raduino project and whilst
|
|
||||||
// I was searching for an alternative to GNU after failing to compile it with the ZPU
|
|
||||||
// version of GCC (as well as the size), I came across RADUINO and this readline
|
|
||||||
// module was very well written and easily portable to this project.
|
|
||||||
//
|
|
||||||
// Credits:
|
|
||||||
// Copyright: (c) -> 2016 - Alfred Klomp (www.alfredklomp.com)
|
|
||||||
// (C) 2020 - Philip Smart <philip.smart@net2net.org> porting and history buf.
|
|
||||||
//
|
|
||||||
// History: April 2020 - With the advent of the tranZPUter SW, I needed a better command
|
|
||||||
// line module for entering, recalling and editting commands. This
|
|
||||||
// module after adding history buffer mechanism is the ideal
|
|
||||||
// solution.
|
|
||||||
// features of zOS where applicable.
|
|
||||||
//
|
|
||||||
// Notes: See Makefile to enable/disable conditional components
|
|
||||||
// __SD_CARD__ - Add the SDCard logic.
|
|
||||||
//
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
||||||
// 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
|
|
||||||
|
|
||||||
uint8_t *readline (uint8_t *, int, int, const char *, void (*)());
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
185
zOS/MZ2000/include/register.h
vendored
185
zOS/MZ2000/include/register.h
vendored
@@ -1,185 +0,0 @@
|
|||||||
#ifndef __ZPUINO_REGISTER_H__
|
|
||||||
#define __ZPUINO_REGISTER_H__
|
|
||||||
|
|
||||||
#if defined( __ZPUINO_DE0NANO__ )
|
|
||||||
# include "board_de0nano.h"
|
|
||||||
#else
|
|
||||||
# error Unknown board.
|
|
||||||
# endif
|
|
||||||
|
|
||||||
#ifndef ASSEMBLY
|
|
||||||
typedef volatile unsigned int* register_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define SPIISBLOCKING 1
|
|
||||||
|
|
||||||
#define BIT(x) (1<<(x))
|
|
||||||
|
|
||||||
#define IO_SLOT(x) (IOBASE + ((x)<<IO_SLOT_OFFSET_BIT))
|
|
||||||
|
|
||||||
#define REGISTER(SLOT, y) *(volatile unsigned int*)(SLOT + ((y)<<2))
|
|
||||||
|
|
||||||
#define SYSCTLBASE IO_SLOT(0)
|
|
||||||
#define SPIBASE IO_SLOT(4)
|
|
||||||
#define UARTBASE IO_SLOT(1)
|
|
||||||
#define GPIOBASE IO_SLOT(2)
|
|
||||||
#define TIMERSBASE IO_SLOT(3)
|
|
||||||
#define SIGMADELTABASE IO_SLOT(5)
|
|
||||||
#define USERSPIBASE IO_SLOT(6)
|
|
||||||
#define CRC16BASE IO_SLOT(7)
|
|
||||||
|
|
||||||
#define ROFF_UARTDATA 0
|
|
||||||
#define ROFF_UARTCTL 1
|
|
||||||
#define ROFF_UARTSTATUS 1
|
|
||||||
|
|
||||||
#define UARTDATA REGISTER(UARTBASE,ROFF_UARTDATA)
|
|
||||||
#define UARTCTL REGISTER(UARTBASE,ROFF_UARTCTL)
|
|
||||||
#define UARTSTATUS REGISTER(UARTBASE,ROFF_UARTSTATUS)
|
|
||||||
|
|
||||||
#define ROFF_SPICTL 0
|
|
||||||
#define ROFF_SPIDATA 1
|
|
||||||
|
|
||||||
#define SPICTL REGISTER(SPIBASE,ROFF_SPICTL)
|
|
||||||
#define SPIDATA REGISTER(SPIBASE,ROFF_SPIDATA)
|
|
||||||
|
|
||||||
#define GPIODATA(x) REGISTER(GPIOBASE,x)
|
|
||||||
#define GPIOTRIS(x) REGISTER(GPIOBASE,4+x)
|
|
||||||
#define GPIOPPSMODE(x) REGISTER(GPIOBASE,8+x)
|
|
||||||
|
|
||||||
#define GPIOPPSOUT(x) REGISTER(GPIOBASE,128 + x)
|
|
||||||
#define GPIOPPSIN(x) REGISTER(GPIOBASE,256 + x)
|
|
||||||
|
|
||||||
// for direct pin access
|
|
||||||
#define GPIOSET(x) REGISTER(GPIOBASE,16+x)
|
|
||||||
#define GPIOCLR(x) REGISTER(GPIOBASE,20+x)
|
|
||||||
#define GPIOTGL(x) REGISTER(GPIOBASE,24+x)
|
|
||||||
|
|
||||||
#define PINSET(x) GPIOSET((x>>5))=(1<<(x&0x1F))
|
|
||||||
#define PINCLR(x) GPIOCLR((x>>5))=(1<<(x&0x1F))
|
|
||||||
#define PINTGL(x) GPIOTGL((x>>5))=(1<<(x&0x1F))
|
|
||||||
|
|
||||||
|
|
||||||
#define ROFF_TMR0CTL 0
|
|
||||||
#define ROFF_TMR0CNT 1
|
|
||||||
#define ROFF_TMR0CMP 2
|
|
||||||
#define ROFF_TIMERTSC 3
|
|
||||||
//#define ROFF_TMR0OCR 3
|
|
||||||
#define ROFF_TMR1CTL 64
|
|
||||||
#define ROFF_TMR1CNT 65
|
|
||||||
#define ROFF_TMR1CMP 66
|
|
||||||
//#define ROFF_TMR1OCR 67
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define TMR0CTL REGISTER(TIMERSBASE,0)
|
|
||||||
#define TMR0CNT REGISTER(TIMERSBASE,1)
|
|
||||||
#define TMR0CMP REGISTER(TIMERSBASE,2)
|
|
||||||
#define TIMERTSC REGISTER(TIMERSBASE,3)
|
|
||||||
|
|
||||||
#define MILLISL REGISTER(TIMERSBASE,4)
|
|
||||||
#define MILLISH REGISTER(TIMERSBASE,5)
|
|
||||||
|
|
||||||
// PWM for timer 0
|
|
||||||
#define TMR0PWMLOW(x) REGISTER(TIMERSBASE, 32+(4*x))
|
|
||||||
#define TMR0PWMHIGH(x) REGISTER(TIMERSBASE, 33+(4*x))
|
|
||||||
#define TMR0PWMCTL(x) REGISTER(TIMERSBASE, 34+(4*x))
|
|
||||||
|
|
||||||
#define TMR1CTL REGISTER(TIMERSBASE,64)
|
|
||||||
#define TMR1CNT REGISTER(TIMERSBASE,65)
|
|
||||||
#define TMR1CMP REGISTER(TIMERSBASE,66)
|
|
||||||
|
|
||||||
// PWM for timer 1
|
|
||||||
#define TMR1PWMLOW(x) REGISTER(TIMERSBASE, 96+(4*x))
|
|
||||||
#define TMR1PWMHIGH(x) REGISTER(TIMERSBASE, 97+(4*x))
|
|
||||||
#define TMR1PWMCTL(x) REGISTER(TIMERSBASE, 98+(4*x))
|
|
||||||
|
|
||||||
#define INTRCTL REGISTER(SYSCTLBASE,0)
|
|
||||||
#define INTRMASK REGISTER(SYSCTLBASE,1)
|
|
||||||
#define INTRLEVEL REGISTER(SYSCTLBASE,2)
|
|
||||||
|
|
||||||
#define SIGMADELTACTL REGISTER(SIGMADELTABASE,0)
|
|
||||||
#define SIGMADELTADATA REGISTER(SIGMADELTABASE,1)
|
|
||||||
|
|
||||||
#define USPICTL REGISTER(USERSPIBASE,0)
|
|
||||||
#define USPIDATA REGISTER(USERSPIBASE,1)
|
|
||||||
|
|
||||||
#define ROFF_CRC16ACC 0
|
|
||||||
#define ROFF_CRC16POLY 1
|
|
||||||
#define ROFF_CRC16APP 2
|
|
||||||
#define ROFF_CRC16AM1 4
|
|
||||||
#define ROFF_CRC16AM2 5
|
|
||||||
|
|
||||||
#define CRC16ACC REGISTER(CRC16BASE,0)
|
|
||||||
#define CRC16POLY REGISTER(CRC16BASE,1)
|
|
||||||
#define CRC16APP REGISTER(CRC16BASE,2)
|
|
||||||
#define CRC16AM1 REGISTER(CRC16BASE,4)
|
|
||||||
#define CRC16AM2 REGISTER(CRC16BASE,5)
|
|
||||||
|
|
||||||
#define UARTEN 16 /* Uart enable */
|
|
||||||
|
|
||||||
/* Timer CTL bits */
|
|
||||||
|
|
||||||
#define TCTLENA 0 /* Timer Enable */
|
|
||||||
#define TCTLCCM 1 /* Clear on Compare Match */
|
|
||||||
#define TCTLDIR 2 /* Direction */
|
|
||||||
#define TCTLIEN 3 /* Interrupt enable */
|
|
||||||
#define TCTLCP0 4 /* Clock prescaler bit 0 */
|
|
||||||
#define TCTLCP1 5 /* Clock prescaler bit 1 */
|
|
||||||
#define TCTLCP2 6 /* Clock prescaler bit 2 */
|
|
||||||
#define TCTLIF 7 /* Interrupt flag */
|
|
||||||
#define TCTUPDP0 9 /* Update policy */
|
|
||||||
#define TCTUPDP1 10 /* Update policy */
|
|
||||||
|
|
||||||
#define TPWMEN 0 /* PWM enabled */
|
|
||||||
|
|
||||||
#define TCTL_UPDATE_NOW (0<<TCTUPDP0)
|
|
||||||
#define TCTL_UPDATE_ZERO_SYNC (1<<TCTUPDP0)
|
|
||||||
#define TCTL_UPDATE_LATER (2<<TCTUPDP0)
|
|
||||||
|
|
||||||
/* SPI bits */
|
|
||||||
#define SPIREADY 0 /* SPI ready */
|
|
||||||
#define SPICP0 1 /* Clock prescaler bit 0 */
|
|
||||||
#define SPICP1 2 /* Clock prescaler bit 1 */
|
|
||||||
#define SPICP2 3 /* Clock prescaler bit 2 */
|
|
||||||
#define SPICPOL 4 /* Clock polarity */
|
|
||||||
#define SPISRE 5 /* Sample on Rising Edge */
|
|
||||||
#define SPIEN 6 /* SPI Enabled (gpio acquire) */
|
|
||||||
#define SPIBLOCK 7
|
|
||||||
#define SPITS0 8
|
|
||||||
#define SPITS1 9
|
|
||||||
|
|
||||||
/* Sigma-Delta bits */
|
|
||||||
#define SDENA0 0 /* Sigma-delta enable */
|
|
||||||
#define SDENA1 1
|
|
||||||
#define SDLE 2 /* Little-endian */
|
|
||||||
|
|
||||||
/* Baud rate computation */
|
|
||||||
|
|
||||||
#define BAUDRATEGEN(x) (((CLK_FREQ/(x))/16)-1)
|
|
||||||
|
|
||||||
#define INPUT 1
|
|
||||||
#define OUTPUT 0
|
|
||||||
|
|
||||||
#define HIGH 1
|
|
||||||
#define LOW 0
|
|
||||||
|
|
||||||
/* PPS configuration - output */
|
|
||||||
|
|
||||||
#define IOPIN_SIGMADELTA0 0
|
|
||||||
#define IOPIN_TIMER0_OC 1
|
|
||||||
#define IOPIN_TIMER1_OC 2
|
|
||||||
#define IOPIN_USPI_MOSI 3
|
|
||||||
#define IOPIN_USPI_SCK 4
|
|
||||||
#define IOPIN_SIGMADELTA1 5
|
|
||||||
|
|
||||||
/* PPS configuration - input */
|
|
||||||
#define IOPIN_USPI_MISO 0
|
|
||||||
|
|
||||||
/* Current interrupts (might not be implemented) */
|
|
||||||
|
|
||||||
#define INTRLINE_TIMER0 3
|
|
||||||
#define INTRLINE_TIMER1 4
|
|
||||||
#define INTRLINE_EXT1 16
|
|
||||||
#define INTRLINE_EXT2 17
|
|
||||||
|
|
||||||
#endif
|
|
||||||
1107
zOS/MZ2000/include/sharpmz.h
vendored
1107
zOS/MZ2000/include/sharpmz.h
vendored
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user