;*******************************************************************************
;* @item     CosyOS-III Port
;* @file     startup_80251.s
;* @brief    80251 Core Startup File
;* @author   迟凯峰
;* @version  v3.0.0
;* @date     2026.07.21
;*******************************************************************************
;
IF __A251__
$INCLUDE (mcucfg_80251.h)
;
;///////////////////////////////////////////////////////////////////////////////
;
;  251 Configuration Bytes Definition for off-chip (external) config bytes
;
$SET (CONFIGB = 0)   ; Set this variable if you want to set external config
;                    ; bytes at address FF:FFF8 and FF:FFF9.
;
; Wait State for PSEN#/RD#/WR# signal except region 01:xxxx (WSA1 & WSA0 Bits)
; WSA        Val  Description
; ---        ---  -----------
WSA  EQU 3  ; 3 = 0 wait state for all regions except region 01:xxxx
;           ; 2 = extended to 1 wait state  for all regions except 01:xxxx
;           ; 1 = extended to 2 wait states for all regions except 01:xxxx
;           ; 0 = extended to 3 wait states for all regions except 01:xxxx
;
; Extend ALE pulse
; XALE       Val  Description
; ----       ---  -----------
XALE EQU 1  ; 1 = ALE pulse is one TOSC
;           ; 0 = ALE pulse is three TOSC, this adds one external wait state
;
; RD# and PSEN# Function Select  (RD1 and RD0 Bits)
; RD         Val  RD Range   PSEN Range  P1.7 Func  Features
; --         ---  --------   ----------  ---------  --------
RDRG EQU 3  ; 3 = <=7F:FFFF  >=80:FFFF   P1.7/CEX4  Compatible with 8051
;           ; 2 = P3.7 only  All address P1.7/CEX4  One additional port pin
;           ; 1 = RD#=A16    All address P1.7/CEX4  128K External Address space
;           ; 0 = RD#=A16    All address P1.7=A17   256K External Address space
;
; Page Mode Select
; PAGE       Val  Description
; ----       ---  -----------
PAGM EQU 1  ; 1 = Non-page Mode (A15:8 on P2, A7:0/D7:0 on P0, 8051 compatible)
;           ; 0 = Page Mode (A15:8/D7:0 on P2, A7:0 on P0)
;
; Interrupt Mode Select
; INTR       Val  Description
; ----       ---  -----------
INTR EQU 1  ; 1 = Interrupt pushes 4 bytes onto the stack (PC & PSW1)
;           ; 0 = Interrupt pushes 2 bytes onto the stack (PCL & PCH only)
;
; Extended Data Float (EDF) Timing Feature
; EDF        Val  Description
; ----       ---  -----------
EDF  EQU 1  ; 1 = Standard (Compatibility) Mode
;           ; 0 = extend data float timing for slow memory devices
;
; Wait State for PSEN#/RD#/WR# signal for region 01:xxxx (WSB1 & WSB0 Bits)
; WSB        Val  Description
; ---        ---  -----------
WSB  EQU 3  ; 3 = 0 wait state for region 01:xxxx
;           ; 2 = extended to 1 wait state  for regions 01:xxxx
;           ; 1 = extended to 2 wait states for regions 01:xxxx
;           ; 0 = extended to 3 wait states for regions 01:xxxx
;
; EPROM/ROM Mapping
; WSA        Val  Description
; ---        ---  -----------
EMAP EQU 1 ;  1 = Map internal ROM only to region FF:xxxx
;          ;  0 = Map higher 8KB of internal ROM to region 00:E000 - 00:FFFF
;
;  Note:  the bit SRC is defined with the A251 directive MODSRC/MODBIN 
; 
;-------------------------------------------------------------------------------
;  基于 START251.A51 修改，摒弃了一些不常用的或用不到的功能，并添加中文注释。
;
;  *** <<< Use Configuration Wizard in Context Menu >>> ***
;-------------------------------------------------------------------------------
; <o> 硬件栈大小 <1-0x10000>
; <i> 硬件栈的初始化大小
; <i> 建议定义足够大的数值保留给硬件栈，这样可以有效的防止编译时栈溢出。
;
STACKSIZE       EQU     100H
;
;-------------------------------------------------------------------------------
; <h> 内存零安装
; <i> 内存零安装
;
; <o> EDATA内存大小 <0-0x10000>
; <i> EDATA内存大小，应定义为4的整数倍。
; <i> EDATA内存的绝对开始地址总是0，无需设置。
; <i> EDATA内存空间覆盖了物理DATA、IDATA、BIT和EBIT区域。
EDATALEN        EQU     1000H
;
; <o> XDATA内存开始地址 <0x10000-0x7FFFFF>
; <i> XDATA内存的绝对开始地址。
XDATASTART      EQU     10000H
;
; <o> XDATA内存大小 <0-0x7F0000>
; <i> XDATA内存大小，应定义为4的整数倍。
XDATALEN        EQU     2000H
;
; </h>
;-------------------------------------------------------------------------------

$IF ROMHUGE
Prefix	LIT '?'
Model   LIT 'FAR'
PRSeg	LIT 'ECODE'
$ELSE
Prefix  LIT ''
Model   LIT 'NEAR'
PRSeg	LIT 'CODE'
$ENDIF

DPXL	DATA	84H

;///////////////////////////////////////////////////////////////////////////////

				NAME	?C_START{Prefix}

;///////////////////////////////////////////////////////////////////////////////

$IF (CONFIGB)
SRCM		EQU		1  ; Select Source Mode
CONFIG0		EQU		(WSA*20H)+(XALE*10H)+(RDRG*4)+(PAGM*2)+SRCM+080H
CONFIG1		EQU		(INTR*10H)+(EDF*8)+(WSB*2)+EMAP+0E0H
			CSEG	AT	0FFF8H
			DB		CONFIG0		; Config Byte 0
			DB		CONFIG1		; Config Byte 1
$ENDIF

?C_C51STARTUP	SEGMENT   CODE
?C_C51STARTUP?3 SEGMENT   CODE
?STACK			SEGMENT   EDATA

			RSEG	?STACK
IF MCUCFG_TASKSTACK_MODE == __MSP__
			DS		STACKSIZE
ELSE
			DS		1
ENDIF

			EXTRN	PRSeg (MAIN{Prefix})
			EXTRN	NUMBER(?C?XDATASEG)		; Start of XDATA Segment
			PUBLIC	?C_STARTUP{Prefix}
			PUBLIC	?C?STARTUP{Prefix}

			CSEG	AT	0
?C?STARTUP{Prefix}:
?C_STARTUP{Prefix}:
			LJMP	STARTUP1

			RSEG	?C_C51STARTUP
STARTUP1:	MOV		DPXL, #?C?XDATASEG

IF EDATALEN <> 0
			MOV		WR10, #EDATALEN/4
			MOV		DR60, #0xFFFF
			MOV		DR12, #0
EDATALOOP:	PUSH	DR12
			DEC		WR10, #1
			JNE		EDATALOOP
ENDIF

IF XDATALEN <> 0
			MOV		DR12, #WORD0 XDATASTART
			MOV		WR12, #WORD2 XDATASTART
			MOV		DR16, #WORD0 XDATALEN/4
			MOV		WR16, #WORD2 XDATALEN/4
			MOV		WR20, #0
XDATALOOP:	MOV		@DR12+0, WR20
			MOV		@DR12+2, WR20
			INC		DR12, #4
			DEC		DR16, #1
			JNE		XDATALOOP
ENDIF

IF MCUCFG_TASKSTACK_MODE == __MSP__
			MOV		DR60, #WORD0 (?STACK-1)
ELSE
			MOV		DR60, #EDATALEN-STACKSIZE-1
ENDIF

			RSEG	?C_C51STARTUP?3
			JMP		Model MAIN{Prefix}

;///////////////////////////////////////////////////////////////////////////////

ENDIF
			END
