/**************************************************************************//**
 * @item     CosyOS-III Port
 * @file     port_8051.h
 * @brief    8051 Core Port File
 * @author   迟凯峰
 * @version  v3.0.0
 * @date     2026.07.21
 ******************************************************************************/

#ifndef __PORT_8051_H
#define __PORT_8051_H

/* INCLUDE */
#include "port_x51.h"
#include "mcucfg_8051.h"
#include SYSCFG_STANDARDHEAD
#include "os_cmsis.h"
#include "os_stack.h"


/* Memory */
#define _SYS_MEM_    data
#define _CODE_MEM_   code
#define _CONST_MEM_  code
#define _STACK_MEM_  idata
#define _XDATA_MEM_  xdata
#define _STATIC_MEM_ xdata
#ifndef _MALLOC_MEM_
#define _MALLOC_MEM_ xdata
#endif
#define _OBJ_MEM_    xdata
/*
 * 用户自定义内存
 * 用户可自定义下方的内存，以寻求在性能和资源之间取得平衡。默认为未定义，由内存MODEL决定。
 * 在 os_var.c、os_var.h 中，用户也可逐个查看及调整对应定义内存的变量，以实现极致的优化。
 */
#define _RTC_MEM_    /* 软件RTC相关系统变量的内存 */
#define _DEBUG_MEM_  /* DEBUG相关系统变量的内存 */


/* Register */
#define _SYS_REG_    _SYS_MEM_


/* Typedef */
#define m_boolvoid_tf (s_boolvoid_tf)
typedef s_u8_t   m_sp_t;
typedef s_u16_t  m_pc_t;
typedef s_u16_t  m_tick_t;
typedef s_u8_t   m_fetion_t;
typedef s_u8_t   m_tqcount_t;
typedef s_u8_t   m_stacklen_t;
#if (MCUCFG_XBPSTACK == __ENABLED__)
typedef s_u16_t  m_stacksize_t;
#else
typedef s_u8_t   m_stacksize_t;
#endif


/* Extern */
#if (SYSCFG_PENDSVFIFO_DEPTH > 0)
extern  s_u16_t  mPendSV_FIFO_0[SYSCFG_PENDSVFIFO_DEPTH];
extern  s_u16_t  mPendSV_FIFO_1[SYSCFG_PENDSVFIFO_DEPTH];
extern  void     mPendSV_FIFOLoader(s_u16_t sv);
#endif


/* CONST & ATTRIBUTE */
#define MCUCFG_PCLEN              2
#if (MCUCFG_TASK_VECTOR)
#define MCUCFG_TASK_ATTRIBUTE     interrupt MCUCFG_TASK_VECTOR using MCUCFG_TASK_REGBANK
#else
#define MCUCFG_TASK_ATTRIBUTE
#endif
#if (MCUCFG_TASK_REGBANK != MCUCFG_OSIT_REGBANK)
#define MCUCFG_OSIT_ATTRIBUTE     using MCUCFG_OSIT_REGBANK
#else
#define MCUCFG_OSIT_ATTRIBUTE
#endif
#define MCUCFG_TERNARY_MASK       false;
#define MCUCFG_TASKSTACK_REALLOC  __ENABLED__
/** 1: \PUSH {PC,A,B,DPH,DPL,PSW}, \SAVE {TASK-REGBANK:R0-R7,[USERREG(ASM)],[?C_XBP]} */
/** 2: \PUSH {PC,A,B,DPH,DPL,PSW,[USERREG(ASM)]}, \SAVE {TASK-REGBANK:R0-R7,[?C_XBP]} */
/** 3: \PUSH {PC,A,B,DPH,DPL,PSW,TASK-REGBANK:R0-R7}, \SAVE {[USERREG(ASM)],[?C_XBP]} */
/** 4: \PUSH {PC,A,B,DPH,DPL,PSW,TASK-REGBANK:R0-R7,[USERREG(ASM)]}, \SAVE {[?C_XBP]} */
#define MCUCFG_BASICSTACKSIZE     (15 + MCUCFG_USERREGSIZE + (MCUCFG_XBPSTACK == __ENABLED__ ? 2 : 0))


/* TaskCtrl */
#define mTaskCtrl_Head_           m_stacksize_t stacklen;
#define mTaskCtrl_Tail_           mUserReg_DEFc_


/* SysTick */
#if (MCUCFG_SYSTICK_COUNT1CYC > (MCUCFG_SYSTICK_LIMITVALUE - 1))
#error 系统滴答定时器溢出。
#endif

////////////////////////////////////////////////////////////////////////////////

/* 用户定义 */// 默认用定时器0做为系统滴答

#define mSysTick_INIT() /*!< 系统滴答初始化 */\
do{ \
	IPH &=~PT0H; PT0 = 0; /*!< 系统滴答中断优先级，必须为最低级 */\
	AUXR = /*!< 定时器频率源 */\
	( \
		(MCUCFG_SYSTICK_CLKDIV == 1) /* 这一行不要动 */\
	  ? (AUXR | 0x80) /*!< 定时器频率源自系统时钟 */\
	  : (AUXR &~0x80) /*!< 定时器频率源自系统时钟/12 */\
	); \
	TMOD &= 0xF0; /*!< 用做定时器，16位自动重装载模式 */\
	TL0 = (s_u8_t)(MCUCFG_SYSTICK_LOADVALUE);      /*!< 重装载值低8位 */\
	TH0 = (s_u8_t)(MCUCFG_SYSTICK_LOADVALUE >> 8); /*!< 重装载值高8位 */\
	TR0 = 1;      /*!< 开启定时器 */\
}while(false)

#define MCUCFG_SYSTICK_CURRVALUE  ((TH0 << 8) | TL0) // 获取系统滴答当前值
#define MCUCFG_SYSTICK_ATTRIBUTE  interrupt 1 MCUCFG_OSIT_ATTRIBUTE // 系统滴答中断属性
#define mSysTick_Disable()  ET0 = 0 // 关闭系统滴答中断
#define mSysTick_Enable()   ET0 = 1 // 开启系统滴答中断
#define mSysTick_Clear()            // 清滴答中断标志位

////////////////////////////////////////////////////////////////////////////////

/* 中断FIFO服务-装载 */
#define mPendSV_FIFOLoad() \
do{ \
	mPendSV_FIFOLoader((s_u16_t)&u_psv); \
	mPendSV_Set(); \
}while(false)

/* 中断FIFO服务-处理 */
#define mPendSV_FIFOHandle() if(!m_sign_fifo_0_0) mPendSV_FIFOHandler()

/* 事件标志组-中断中写多标志位 */
#define miWriteFlagBits() \
	static bit u_f = false; \
	if(!u_f){ \
		u_f = true

/*----------------------------------------------------------------------------*/

/* XBPSTACK */
#if (MCUCFG_XBPSTACK == __ENABLED__)
#define mXBP_INIT() \
	*(s_u16_t *)(node_news->bsp + 15 + MCUCFG_USERREGSIZE) \
	  = node_news->bsp + node_news->stacksize
#else
#define mXBP_INIT()
#endif


/* 任务栈 */
#define MCUCFG_TASKSTACK_MODE __MSP__

#define mTaskStack_Reset() \
do{ \
	node_news->stacklen = ( \
	   (MCUCFG_TASK_REGBANK == MCUCFG_OSIT_REGBANK ? 15 : 7) \
	 + (MCUCFG_USERREGCONFIG == 1 ? MCUCFG_USERREGSIZE : 0) \
	); \
	*(s_u16_t *)node_news->bsp = ( \
	   ((s_u16_t)node_news->entry << 8) \
	 | ((s_u16_t)node_news->entry >> 8) \
	); \
	*(s_u8_t *)(node_news->bsp + 7 - 1) = MCUCFG_TASK_REGBANK * 8; \
	mUserReg_INITa(); \
	mXBP_INIT(); \
	mUserReg_INITc(); \
}while(false)

#define mTaskStack_Init() \
do{ \
	mTaskStack_Reset(); \
}while(false)


/* 栈监控 */
#if (SYSCFG_DEBUGGING == __ENABLED__)

extern s_u8_t m_msp;
extern s_u8_t m_stacksize;
extern s_u8_t m_stacklen_max;
extern s_u8_t data m_taskstacklen;

#define mMainStack_CheckInit() \
do{ \
	m_msp = SP; \
	m_stacksize = 0xFF - SP; \
	s_stack_check_init((s_u8_t idata *)(m_msp + 8), m_stacksize - 8); \
}while(false)

#define mMainStack_Check()     s_stack_check((s_u8_t idata *)m_msp, m_stacksize)
#define mTaskStack_Check0()    m_taskstacklen
#endif


#endif
