mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-09-12 00:57:44 -04:00
z180 - initial commit
This commit is contained in:
parent
810dad5322
commit
efdf4a91fb
2 changed files with 714 additions and 0 deletions
281
portable/SDCC/Z180/port.c
Normal file
281
portable/SDCC/Z180/port.c
Normal file
|
@ -0,0 +1,281 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Phillip Stevens 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.
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#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. */
|
||||||
|
/* Make unitialised in BSS for RomWBW HBIOS (to ensure above 0x8000) */
|
||||||
|
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_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
|
433
portable/SDCC/Z180/portmacro.h
Normal file
433
portable/SDCC/Z180/portmacro.h
Normal file
|
@ -0,0 +1,433 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2020 Phillip Stevens 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.
|
||||||
|
*
|
||||||
|
* 1 tab == 4 spaces!
|
||||||
|
*
|
||||||
|
* This file is NOT part of the FreeRTOS distribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#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. */
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* Architecture specifics. */
|
||||||
|
|
||||||
|
#define portSTACK_GROWTH ( -1 )
|
||||||
|
#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ )
|
||||||
|
#define portBYTE_ALIGNMENT 1
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* 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
|
||||||
|
|
||||||
|
/*-----------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* 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 */
|
Loading…
Add table
Add a link
Reference in a new issue