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