Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/FreeRTOS/FreeRTOS-Kernel-Community-Supported-Ports.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPhillip Stevens <phillip.stevens@gmail.com>2021-12-08 00:41:11 +0300
committerGaurav Aggarwal <aggarg@amazon.com>2021-12-08 23:00:55 +0300
commit3d14f8d0339053394bae9859b530e317e43a60c2 (patch)
tree0d238cf58d1623de5164e51403ce3efa70547a6a
parent7f6ba1d6ef5b14f92ef878d160c8b859a9900a9a (diff)
Add z180 port - sdcc & sccz80 compiler support (#5)
This was originally contributed here - https://github.com/FreeRTOS/FreeRTOS-Kernel/pull/52 Signed-off-by: Gaurav Aggarwal <aggarg@amazon.com>
-rw-r--r--Z88DK/Z180/port.c283
-rw-r--r--Z88DK/Z180/portmacro.h431
-rw-r--r--Z88DK/Z180/readme.md13
3 files changed, 727 insertions, 0 deletions
diff --git a/Z88DK/Z180/port.c b/Z88DK/Z180/port.c
new file mode 100644
index 0000000..59a815f
--- /dev/null
+++ b/Z88DK/Z180/port.c
@@ -0,0 +1,283 @@
+/*
+ * FreeRTOS Kernel V10.4.3
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+
+
+#include <stdlib.h>
+
+#include "include/FreeRTOS.h"
+
+#if __SDCC
+#include "include/sdcc/task.h"
+#elif __SCCZ80
+#include "include/sccz80/task.h"
+#endif
+
+/*-----------------------------------------------------------*/
+
+/* We require the address of the pxCurrentTCB variable, but don't want to know
+any details of its type. */
+
+typedef void TCB_t;
+extern volatile TCB_t * volatile pxCurrentTCB;
+/*-----------------------------------------------------------*/
+
+/*
+ * Macro to save all the general purpose registers, the save the stack pointer
+ * into the TCB.
+ *
+ * The first thing we do is save the flags then disable interrupts. This is to
+ * guard our stack against having a context switch interrupt after we have already
+ * pushed the registers onto the stack.
+ *
+ * The interrupts will have been disabled during the call to portSAVE_CONTEXT()
+ * so we need not worry about reading/writing to the stack pointer.
+ */
+
+#define configTICK_RATE_HZ (256) /* Timer configured */
+#define configISR_ORG ASMPC /* ISR relocation */
+#define configISR_IVT 0xFFE6 /* PRT1 address */
+
+#ifdef __SCCZ80
+
+#define configSETUP_TIMER_INTERRUPT() \
+ do{ \
+ asm( \
+ "EXTERN __CPU_CLOCK \n" \
+ "EXTERN RLDR1L, RLDR1H \n" \
+ "EXTERN TCR, TCR_TIE1, TCR_TDE1 \n" \
+ "ld de,_timer_isr \n" \
+ "ld hl,"string(configISR_IVT)" ; PRT1 address \n" \
+ "ld (hl),e \n" \
+ "inc hl \n" \
+ "ld (hl),d \n" \
+ "; we do configTICK_RATE_HZ ticks per second \n" \
+ "ld hl,__CPU_CLOCK/"string(configTICK_RATE_HZ)"/20-1 \n" \
+ "out0(RLDR1L),l \n" \
+ "out0(RLDR1H),h \n" \
+ "in0 a,(TCR) \n" \
+ "or TCR_TIE1|TCR_TDE1 \n" \
+ "out0 (TCR),a \n" \
+ ); \
+ }while(0)
+
+#define configRESET_TIMER_INTERRUPT() \
+ do{ \
+ asm( \
+ "EXTERN TCR, TMDR1L \n" \
+ "in0 a,(TCR) \n" \
+ "in0 a,(TMDR1L) \n" \
+ ); \
+ }while(0)
+
+#define configSTOP_TIMER_INTERRUPT() \
+ do{ \
+ asm( \
+ "EXTERN TCR, TCR_TIE1, TCR_TDE1 \n" \
+ "; disable down counting and interrupts for PRT1\n" \
+ "in0 a,(TCR) \n" \
+ "xor TCR_TIE1|TCR_TDE1 \n" \
+ "out0 (TCR),a \n" \
+ ); \
+ }while(0)
+
+#endif
+
+#ifdef __SDCC
+
+#define configSETUP_TIMER_INTERRUPT() \
+ do{ \
+ __asm \
+ EXTERN __CPU_CLOCK \
+ EXTERN RLDR1L, RLDR1H \
+ EXTERN TCR, TCR_TIE1, TCR_TDE1 \
+ ; address of ISR \
+ ld de,_timer_isr \
+ ld hl,configISR_IVT ; PRT1 address \
+ ld (hl),e \
+ inc hl \
+ ld (hl),d \
+ ; we do configTICK_RATE_HZ ticks per second \
+ ld hl,__CPU_CLOCK/configTICK_RATE_HZ/20-1 \
+ out0(RLDR1L),l \
+ out0(RLDR1H),h \
+ ; enable down counting and interrupts for PRT1 \
+ in0 a,(TCR) \
+ or TCR_TIE1|TCR_TDE1 \
+ out0 (TCR),a \
+ __endasm; \
+ }while(0)
+
+#define configRESET_TIMER_INTERRUPT() \
+ do{ \
+ __asm \
+ EXTERN TCR, TMDR1L \
+ ; reset interrupt for PRT1 \
+ in0 a,(TCR) \
+ in0 a,(TMDR1L) \
+ __endasm; \
+ }while(0)
+
+#define configSTOP_TIMER_INTERRUPT() \
+ do{ \
+ __asm \
+ EXTERN TCR, TCR_TIE1, TCR_TDE1 \
+ ; disable down counting and interrupts for PRT1 \
+ in0 a,(TCR) \
+ xor TCR_TIE1|TCR_TDE1 \
+ out0 (TCR),a \
+ __endasm; \
+ }while(0)
+
+#endif
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Perform hardware setup to enable ticks from Timer.
+ */
+static void prvSetupTimerInterrupt( void ) __preserves_regs(iyh,iyl);
+/*-----------------------------------------------------------*/
+
+/*
+ * See header file for description.
+ */
+StackType_t *pxPortInitialiseStack( StackType_t *pxTopOfStack, TaskFunction_t pxCode, void *pvParameters )
+{
+ /* Place the parameter on the stack in the expected location. */
+ *pxTopOfStack-- = ( StackType_t ) pvParameters;
+
+ /* Place the task return address on stack. Not used */
+ *pxTopOfStack-- = ( StackType_t ) 0;
+
+ /* The start of the task code will be popped off the stack last, so place
+ it on first. */
+ *pxTopOfStack-- = ( StackType_t ) pxCode;
+
+ /* Now the registers. */
+ *pxTopOfStack-- = ( StackType_t ) 0xAFAF; /* AF */
+ *pxTopOfStack-- = ( StackType_t ) 0x0404; /* IF */
+ *pxTopOfStack-- = ( StackType_t ) 0xBCBC; /* BC */
+ *pxTopOfStack-- = ( StackType_t ) 0xDEDE; /* DE */
+ *pxTopOfStack-- = ( StackType_t ) 0xEFEF; /* HL */
+ *pxTopOfStack-- = ( StackType_t ) 0xFAFA; /* AF' */
+ *pxTopOfStack-- = ( StackType_t ) 0xCBCB; /* BC' */
+ *pxTopOfStack-- = ( StackType_t ) 0xEDED; /* DE' */
+ *pxTopOfStack-- = ( StackType_t ) 0xFEFE; /* HL' */
+ *pxTopOfStack-- = ( StackType_t ) 0xCEFA; /* IX */
+ *pxTopOfStack = ( StackType_t ) 0xADDE; /* IY */
+
+ return pxTopOfStack;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xPortStartScheduler( void ) __preserves_regs(a,b,c,d,e,iyh,iyl) __naked
+{
+ /* Setup the relevant timer hardware to generate the tick. */
+ prvSetupTimerInterrupt();
+
+ /* Restore the context of the first task that is going to run. */
+ portRESTORE_CONTEXT();
+
+ /* Should not get here. */
+ return pdFALSE;
+}
+/*-----------------------------------------------------------*/
+
+void vPortEndScheduler( void ) __preserves_regs(b,c,d,e,h,l,iyh,iyl)
+{
+ /*
+ * It is unlikely that the Z80 port will get stopped.
+ * If required simply disable the tick interrupt here.
+ */
+ configSTOP_TIMER_INTERRUPT();
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Manual context switch. The first thing we do is save the registers so we
+ * can use a naked attribute. This is called by the application, so we don't have
+ * to check which bank is loaded.
+ */
+void vPortYield( void ) __preserves_regs(a,b,c,d,e,h,l,iyh,iyl) __naked
+{
+ portSAVE_CONTEXT();
+ vTaskSwitchContext();
+ portRESTORE_CONTEXT();
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Manual context switch callable from ISRs. The first thing we do is save
+ * the registers so we can use a naked attribute.
+ */
+void vPortYieldFromISR(void) __preserves_regs(a,b,c,d,e,h,l,iyh,iyl) __naked
+void vPortYieldFromISR(void)
+{
+ portSAVE_CONTEXT_IN_ISR();
+ vTaskSwitchContext();
+ portRESTORE_CONTEXT_IN_ISR();
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Initialize Timer (PRT1 for YAZ180, and SCZ180 HBIOS).
+ */
+void prvSetupTimerInterrupt( void ) __preserves_regs(iyh,iyl)
+{
+ configSETUP_TIMER_INTERRUPT();
+}
+/*-----------------------------------------------------------*/
+
+void timer_isr(void) __preserves_regs(a,b,c,d,e,h,l,iyh,iyl) __naked
+{
+#if configUSE_PREEMPTION == 1
+ /*
+ * Tick ISR for preemptive scheduler. We can use a naked attribute as
+ * the context is saved at the start of timer_isr(). The tick
+ * count is incremented after the context is saved.
+ *
+ * Context switch function used by the tick. This must be identical to
+ * vPortYield() from the call to vTaskSwitchContext() onwards. The only
+ * difference from vPortYield() is the tick count is incremented as the
+ * call comes from the tick ISR.
+ */
+ portSAVE_CONTEXT_IN_ISR();
+ configRESET_TIMER_INTERRUPT();
+ xTaskIncrementTick();
+ vTaskSwitchContext();
+ portRESTORE_CONTEXT_IN_ISR();
+#else
+ /*
+ * Tick ISR for the cooperative scheduler. All this does is increment the
+ * tick count. We don't need to switch context, this can only be done by
+ * manual calls to taskYIELD();
+ */
+ portSAVE_CONTEXT_IN_ISR();
+ configRESET_TIMER_INTERRUPT();
+ xTaskIncrementTick();
+ portRESTORE_CONTEXT_IN_ISR();
+#endif
+} // configUSE_PREEMPTION
diff --git a/Z88DK/Z180/portmacro.h b/Z88DK/Z180/portmacro.h
new file mode 100644
index 0000000..f8f2f02
--- /dev/null
+++ b/Z88DK/Z180/portmacro.h
@@ -0,0 +1,431 @@
+/*
+ * FreeRTOS Kernel V10.4.3
+ * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * https://www.FreeRTOS.org
+ * https://github.com/FreeRTOS
+ *
+ */
+
+#ifndef PORTMACRO_H
+#define PORTMACRO_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*-----------------------------------------------------------
+ * Port specific definitions.
+ *
+ * The settings in this file configure FreeRTOS correctly for the
+ * given Z80 (Z180, Z80N) hardware and SCCZ80 or SDCC compiler.
+ *
+ * These settings should not be altered.
+ *-----------------------------------------------------------
+ */
+
+/* Type definitions. */
+#define portCHAR char
+#define portFLOAT float
+#define portDOUBLE double
+#define portLONG long
+#define portSHORT int
+
+typedef uint16_t StackType_t;
+typedef int8_t BaseType_t;
+typedef uint8_t UBaseType_t;
+
+#if configUSE_16_BIT_TICKS == 1
+ typedef uint16_t TickType_t;
+ #define portMAX_DELAY ( TickType_t ) 0xffff
+#else
+ typedef uint32_t TickType_t;
+ #define portMAX_DELAY ( TickType_t ) 0xffffffffUL
+#endif
+/*-----------------------------------------------------------*/
+
+/* General purpose stringify macros. */
+
+#define string(a) __string(a)
+#define __string(a) #a
+/*-----------------------------------------------------------*/
+
+/* Critical section management using sccz80 compiler. */
+
+#ifdef __SCCZ80
+
+#define portENTER_CRITICAL() \
+ do{ \
+ asm( \
+ "ld a,i \n" \
+ "di \n" \
+ "push af \n" \
+ ); \
+ }while(0)
+
+#define portEXIT_CRITICAL() \
+ do{ \
+ asm( \
+ "pop af \n" \
+ "; di ; unneeded \n" \
+ "jp PO,ASMPC+4 \n" \
+ "ei \n" \
+ ); \
+ }while(0)
+
+#define portDISABLE_INTERRUPTS() \
+ do{ \
+ asm( \
+ "di \n" \
+ ); \
+ }while(0)
+
+#define portENABLE_INTERRUPTS() \
+ do{ \
+ asm( \
+ "ei \n" \
+ ); \
+ }while(0)
+
+#define portNOP() \
+ do{ \
+ asm( \
+ "nop \n" \
+ ); \
+ }while(0)
+
+/*
+ * Macros to save all the registers, and save the stack pointer into the TCB.
+ */
+
+#define portSAVE_CONTEXT() \
+ do{ \
+ asm( \
+ "push af \n" \
+ "ld a,i \n" \
+ "di \n" \
+ "push af ; iff1:iff2\n" \
+ "push bc \n" \
+ "push de \n" \
+ "push hl \n" \
+ "exx \n" \
+ "ex af,af \n" \
+ "push af \n" \
+ "push bc \n" \
+ "push de \n" \
+ "push hl \n" \
+ "push ix \n" \
+ "push iy \n" \
+ "ld hl,0 \n" \
+ "add hl,sp \n" \
+ "ld de,(_pxCurrentTCB) \n"\
+ "ex de,hl \n" \
+ "ld (hl),e \n" \
+ "inc hl \n" \
+ "ld (hl),d \n" \
+ ); \
+ }while(0)
+
+#define portRESTORE_CONTEXT() \
+ do{ \
+ asm( \
+ "ld hl,(_pxCurrentTCB) \n" \
+ "ld e,(hl) \n" \
+ "inc hl \n" \
+ "ld d,(hl) \n" \
+ "ex de,hl \n" \
+ "ld sp,hl \n" \
+ "pop iy \n" \
+ "pop ix \n" \
+ "pop hl \n" \
+ "pop de \n" \
+ "pop bc \n" \
+ "pop af \n" \
+ "ex af,af \n" \
+ "exx \n" \
+ "pop hl \n" \
+ "pop de \n" \
+ "pop bc \n" \
+ "pop af ; iff1:iff2\n" \
+ "; di ; unneeded \n" \
+ "jp PO,ASMPC+4 \n" \
+ "ei \n" \
+ "pop af \n" \
+ "ret \n" \
+ ); \
+ }while(0)
+
+#define portSAVE_CONTEXT_IN_ISR() \
+ do{ \
+ asm( \
+ "PHASE "string(configISR_ORG)" \n" \
+ "._timer_isr_start \n" \
+ "push af \n" \
+ "ld a,0x7F \n" \
+ "inc a ; set PE \n" \
+ "push af ; iff1:iff2\n" \
+ "push bc \n" \
+ "push de \n" \
+ "push hl \n" \
+ "exx \n" \
+ "ex af,af \n" \
+ "push af \n" \
+ "push bc \n" \
+ "push de \n" \
+ "push hl \n" \
+ "push ix \n" \
+ "push iy \n" \
+ "ld hl,0 \n" \
+ "add hl,sp \n" \
+ "ld de,(_pxCurrentTCB) \n" \
+ "ex de,hl \n" \
+ "ld (hl),e \n" \
+ "inc hl \n" \
+ "ld (hl),d \n" \
+ ); \
+ }while(0)
+
+#define portRESTORE_CONTEXT_IN_ISR()\
+ do{ \
+ asm( \
+ "ld hl,(_pxCurrentTCB) \n" \
+ "ld e,(hl) \n" \
+ "inc hl \n" \
+ "ld d,(hl) \n" \
+ "ex de,hl \n" \
+ "ld sp,hl \n" \
+ "pop iy \n" \
+ "pop ix \n" \
+ "pop hl \n" \
+ "pop de \n" \
+ "pop bc \n" \
+ "pop af \n" \
+ "ex af,af \n" \
+ "exx \n" \
+ "pop hl \n" \
+ "pop de \n" \
+ "pop bc \n" \
+ "pop af ; iff1:iff2\n" \
+ "; di ; unneeded \n" \
+ "jp PO,ASMPC+4 \n" \
+ "ei \n" \
+ "pop af \n" \
+ "reti \n" \
+ "._timer_isr_end \n" \
+ "DEPHASE \n" \
+ ); \
+ }while(0)
+
+#endif
+/*-----------------------------------------------------------*/
+
+/* Critical section management using sdcc compiler. */
+
+#ifdef __SDCC
+
+#define portENTER_CRITICAL() \
+ do{ \
+ __asm \
+ ld a,i \
+ di \
+ push af \
+ __endasm; \
+ }while(0)
+
+#define portEXIT_CRITICAL() \
+ do{ \
+ __asm \
+ pop af \
+ ; di ; unneeded \
+ jp PO,ASMPC+4 \
+ ei \
+ __endasm; \
+ }while(0)
+
+#define portDISABLE_INTERRUPTS() \
+ do{ \
+ __asm \
+ di \
+ __endasm; \
+ }while(0)
+
+#define portENABLE_INTERRUPTS() \
+ do{ \
+ __asm \
+ ei \
+ __endasm; \
+ }while(0)
+
+#define portNOP() \
+ do{ \
+ __asm \
+ nop \
+ __endasm; \
+ }while(0)
+
+/*
+ * Macros to save all the registers, and save the stack pointer into the TCB.
+ */
+
+#define portSAVE_CONTEXT() \
+ do{ \
+ __asm \
+ push af \
+ ld a,i \
+ di \
+ push af ; iff1:iff2 \
+ push bc \
+ push de \
+ push hl \
+ exx \
+ ex af,af \
+ push af \
+ push bc \
+ push de \
+ push hl \
+ push ix \
+ push iy \
+ ld hl,0 \
+ add hl,sp \
+ ld de,(_pxCurrentTCB) \
+ ex de,hl \
+ ld (hl),e \
+ inc hl \
+ ld (hl),d \
+ __endasm; \
+ }while(0)
+
+#define portRESTORE_CONTEXT() \
+ do{ \
+ __asm \
+ ld hl,(_pxCurrentTCB) \
+ ld e,(hl) \
+ inc hl \
+ ld d,(hl) \
+ ex de,hl \
+ ld sp,hl \
+ pop iy \
+ pop ix \
+ pop hl \
+ pop de \
+ pop bc \
+ pop af \
+ ex af,af \
+ exx \
+ pop hl \
+ pop de \
+ pop bc \
+ pop af ; iff1:iff2 \
+ ; di ; unneeded \
+ jp PO,ASMPC+4 \
+ ei \
+ pop af \
+ ret \
+ __endasm; \
+ }while(0)
+
+#define portSAVE_CONTEXT_IN_ISR() \
+ do{ \
+ __asm \
+ PHASE configISR_ORG \
+ _timer_isr_start: \
+ push af \
+ ld a,0x7F \
+ inc a ; set PE \
+ push af ; iff1:iff2 \
+ push bc \
+ push de \
+ push hl \
+ exx \
+ ex af,af \
+ push af \
+ push bc \
+ push de \
+ push hl \
+ push ix \
+ push iy \
+ ld hl,0 \
+ add hl,sp \
+ ld de,(_pxCurrentTCB) \
+ ex de,hl \
+ ld (hl),e \
+ inc hl \
+ ld (hl),d \
+ __endasm; \
+ }while(0)
+
+#define portRESTORE_CONTEXT_IN_ISR()\
+ do{ \
+ __asm \
+ ld hl,(_pxCurrentTCB) \
+ ld e,(hl) \
+ inc hl \
+ ld d,(hl) \
+ ex de,hl \
+ ld sp,hl \
+ pop iy \
+ pop ix \
+ pop hl \
+ pop de \
+ pop bc \
+ pop af \
+ ex af,af \
+ exx \
+ pop hl \
+ pop de \
+ pop bc \
+ pop af ; iff1:iff2 \
+ ; di ; unneeded \
+ jp PO,ASMPC+4 \
+ ei \
+ pop af \
+ reti \
+ _timer_isr_end: \
+ DEPHASE \
+ __endasm; \
+ }while(0)
+
+#endif
+/*-----------------------------------------------------------*/
+
+/* Architecture specifics. */
+
+#define portSTACK_GROWTH ( -1 )
+#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
+#define portBYTE_ALIGNMENT 1
+/*-----------------------------------------------------------*/
+
+/* Kernel utilities. */
+extern void vPortYield( void );
+#define portYIELD() vPortYield()
+
+extern void vPortYieldFromISR( void );
+#define portYIELD_FROM_ISR() vPortYieldFromISR()
+/*-----------------------------------------------------------*/
+
+/* Task function macros as described on the FreeRTOS.org WEB site. */
+#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void *pvParameters )
+#define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void *pvParameters )
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* PORTMACRO_H */
diff --git a/Z88DK/Z180/readme.md b/Z88DK/Z180/readme.md
new file mode 100644
index 0000000..89af17a
--- /dev/null
+++ b/Z88DK/Z180/readme.md
@@ -0,0 +1,13 @@
+<h1>z180 support</h1>
+
+Description
+-----------
+This PR establishes support for a Zilog z180 port, using the Programmable Reload Timer 1, configured at 256 Hz.
+
+Because of the generality of the z180, the address of the Interrupt Vector for PRT1 is configurable, and must be configured by the `crt0.asm` outside of this port. A configuration assumption has been made.
+
+The two compilers ([used by the z88dk](https://github.com/z88dk/z88dk)) are supported. The sccz80 compiler and the sdcc compiler. The PR is located under Z88dk.
+
+Background
+-----------
+This PR is based on running code for the [SC130](https://smallcomputercentral.wordpress.com/sc130-z180-motherboard/)/[SC131](https://smallcomputercentral.wordpress.com/sc131-z180-pocket-computer/) and [YAZ180](https://github.com/feilipu/yaz180) platforms, and is maintained by the z88dk team in this [z88dk-libraries](https://github.com/feilipu/z88dk-libraries/tree/master/freertos) repository.