z8_vector.s

来自「這是一個實時嵌入式作業系統 實作了MCS51 ARM等MCU」· S 代码 · 共 874 行 · 第 1/2 页

S
874
字号
 * Description:
 *   Map individual interrupts into interrupt number and branch to common
 *   interrupt handling logic.  If higher interrupt handling performance
 *   for particular interrupts is required, then those interrupts should
 *   be picked off here and handled outside of the common logic.
 *
 *   On entry to any of these handlers, the stack contains the following:
 *
 *         TOS before interrupt
 *         PC[7:0]
 *         PC[15:8]
 *   SP -> Flags Register
 *
 **************************************************************************/

#if defined(ENCORE_VECTORS)
_z8_wdt_handler:
	ENTER(Z8_WDT_IRQ)
_z8_trap_handler:
	ENTER(Z8_TRAP_IRQ)
if EZ8_TIMER3=1
_z8_timer2_handler:
	ENTER(Z8_TIMER2_IRQ)
endif
_z8_timer1_handler:
	ENTER(Z8_TIMER1_IRQ)
_z8_timer0_handler:
	ENTER(Z8_TIMER0_IRQ)
if EZ8_UART0=1
_z8_uart0rx_handler:
	ENTER(Z8_UART0_RX_IRQ)
_z8_uart0tx_handler:
	ENTER(Z8_UART0_TX_IRQ)
endif
if EZ8_I2C=1
_z8_i2c_handler:
	ENTER(Z8_I2C_IRQ)
endif
if EZ8_SPI=1
_z8_spi_handler:
	ENTER(Z8_SPI_IRQ)
endif
if EZ8_ADC=1
_z8_adc_handler:
	ENTER(Z8_ADC_IRQ)
endif
_z8_p7ad_handler:
	ENTER(Z8_P7AD_IRQ)
_z8_p6ad_handler:
	ENTER(Z8_P6AD_IRQ)
_z8_p5ad_handler:
	ENTER(Z8_P5AD_IRQ)
_z8_p4ad_handler:
	ENTER(Z8_P4AD_IRQ)
_z8_p3ad_handler:
	ENTER(Z8_P3AD_IRQ)
_z8_p2ad_handler:
	ENTER(Z8_P2AD_IRQ)
_z8_p1ad_handler:
	ENTER(Z8_P1AD_IRQ)
_z8_p0ad_handler:
	ENTER(Z8_P0AD_IRQ)
if EZ8_TIMER4=1
_z8_timer3_handler:
	ENTER(Z8_TIMER3_IRQ)
endif
if EZ8_UART1=1
_z8_uart1rx_handler:
	ENTER(Z8_UART1_RX_IRQ)
_z8_uart1tx_handler:
	ENTER(Z8_UART1_TX_IRQ)
endif
if EZ8_DMA=1
_z8_dma_handler:
	ENTER(Z8_DMA_IRQ)
endif
if EZ8_PORT1=0
_z8_c3_handler:
	ENTER(Z8_C3_IRQ)
_z8_c2_handler:
	ENTER(Z8_C2_IRQ)
_z8_c1_handler:
	ENTER(Z8_C1_IRQ)
_z8_c0_handler:
	ENTER(Z8_C0_IRQ)
endif

/**************************************************************************/

#elif defined(ENCORE_XP_VECTORS)

_z8_wdt_handler:
	ENTER(Z8_WDT_IRQ)
_z8_trap_handler:
	ENTER(Z8_TRAP_IRQ)
if EZ8_TIMER3=1
_z8_timer2_handler:
	ENTER(Z8_TIMER2_IRQ)
endif
_z8_timer1_handler:
	ENTER(Z8_TIMER1_IRQ)
_z8_timer0_handler:
	ENTER(Z8_TIMER0_IRQ)
if EZ8_UART0=1
_z8_uart0rx_handler:
	ENTER(Z8_UART0_RX_IRQ)
_z8_uart0tx_handler:
	ENTER(Z8_UART0_TX_IRQ)
endif
if EZ8_I2C=1
_z8_i2c_handler:
	ENTER(Z8_I2C_IRQ)
endif
if EZ8_SPI=1
_z8_spi_handler:
	ENTER(Z8_SPI_IRQ)
endif
if (EZ8_ADC=1) || (EZ8_ADC_NEW=1)
_z8_adc_handler:
	ENTER(Z8_ADC_IRQ)
endif
_z8_p7ad_handler:
	ENTER(Z8_P7AD_IRQ)
_z8_p6ad_handler:
	ENTER(Z8_P6AD_IRQ)
_z8_p5ad_handler:
	ENTER(Z8_P5AD_IRQ)
_z8_p4ad_handler:
	ENTER(Z8_P4AD_IRQ)
_z8_p3ad_handler:
	ENTER(Z8_P3AD_IRQ)
_z8_p2ad_handler:
	ENTER(Z8_P2AD_IRQ)
_z8_p1ad_handler:
	ENTER(Z8_P1AD_IRQ)
_z8_p0ad_handler:
	ENTER(Z8_P0AD_IRQ)
if EZ8_TIMER4=1
_z8_timer3_handler:
	ENTER(Z8_TIMER3_IRQ)
endif
if EZ8_UART1=1
_z8_uart1rx_handler:
	ENTER(Z8_UART1_RX_IRQ)
_z8_uart1tx_handler:
	ENTER(Z8_UART1_TX_IRQ)
endif
if EZ8_DMA=1
_z8_dma_handler:
	ENTER(Z8_DMA_IRQ)
endif
if EZ8_PORT1=0
_z8_c3_handler:
	ENTER(Z8_C3_IRQ)
_z8_c2_handler:
	ENTER(Z8_C2_IRQ)
_z8_c1_handler:
	ENTER(Z8_C1_IRQ)
_z8_c0_handler:
	ENTER(Z8_C0_IRQ)
endif
_z8_potrap_handler:
	ENTER(Z8_POTRAP_IRQ)
_z8_wotrap_handler:
	ENTER(Z8_WOTRAP_IRQ)

/**************************************************************************/

#elif defined(ENCORE_XP16K_VECTORS)

_z8_wdt_handler:
	ENTER(Z8_WDT_IRQ)
_z8_trap_handler:
	ENTER(Z8_TRAP_IRQ)
if EZ8_TIMER3=1
_z8_timer2_handler:
	ENTER(Z8_TIMER2_IRQ)
endif
_z8_timer1_handler:
	ENTER(Z8_TIMER1_IRQ)
_z8_timer0_handler:
	ENTER(Z8_TIMER0_IRQ)
if EZ8_UART0=1
_z8_uart0rx_handler:
	ENTER(Z8_UART0_RX_IRQ)
_z8_uart0tx_handler:
	ENTER(Z8_UART0_TX_IRQ)
endif
if EZ8_I2C=1
_z8_i2c_handler:
	ENTER(Z8_I2C_IRQ)
endif
if EZ8_ESPI=1
_z8_spi_handler:
	ENTER(Z8_SPI_IRQ)
endif
if EZ8_ADC_NEW=1
_z8_adc_handler:
	ENTER(Z8_ADC_IRQ)
endif
_z8_p7ad_handler:
	ENTER(Z8_P7AD_IRQ)
_z8_p6ad_handler:
	ENTER(Z8_P6AD_IRQ)
_z8_p5ad_handler:
	ENTER(Z8_P5AD_IRQ)
_z8_p4ad_handler:
	ENTER(Z8_P4AD_IRQ)
_z8_p3ad_handler:
	ENTER(Z8_P3AD_IRQ)
_z8_p2ad_handler:
	ENTER(Z8_P2AD_IRQ)
_z8_p1ad_handler:
	ENTER(Z8_P1AD_IRQ)
_z8_p0ad_handler:
	ENTER(Z8_P0AD_IRQ)
if EZ8_MCT=1
_z8_mct_handler:
	ENTER(Z8_MCT_IRQ)
endif
if EZ8_UART1=1
_z8_uart1rx_handler:
	ENTER(Z8_UART1_RX_IRQ)
_z8_uart1tx_handler:
	ENTER(Z8_UART1_TX_IRQ)
endif
_z8_c3_handler:
	ENTER(Z8_C3_IRQ)
_z8_c2_handler:
	ENTER(Z8_C2_IRQ)
_z8_c1_handler:
	ENTER(Z8_C1_IRQ)
_z8_c0_handler:
	ENTER(Z8_C0_IRQ)
_z8_potrap_handler:
	ENTER(Z8_POTRAP_IRQ)
_z8_wotrap_handler:
	ENTER(Z8_WOTRAP_IRQ)

/**************************************************************************/

#elif defined(ENCORE_MC_VECTORS)

_z8_wdt_handler:
	ENTER(Z8_WDT_IRQ)
_z8_trap_handler:
	ENTER(Z8_TRAP_IRQ)
_z8_pwmtimer_handler:
	ENTER(Z8_PWMTIMER_IRQ)
_z8_pwmfault_handler:
	ENTER(Z8_PWMFAULT_IRQ)
if EZ8_ADC_NEW=1
_z8_adc_handler:
	ENTER(Z8_ADC_IRQ)
endif
_z8_cmp_handler:
	ENTER(Z8_CMP_IRQ)
_z8_timer0_handler:
	ENTER(Z8_TIMER0_IRQ)
if EZ8_UART0
_z8_uart0rx_handler:
	ENTER(Z8_UART0_RX_IRQ)
_z8_uart0tx_handler:
	ENTER(Z8_UART0_TX_IRQ)
endif
if EZ8_SPI=1
_z8_spi_handler:
	ENTER(Z8_SPI_IRQ)
endif
if EZ8_I2C=1
_z8_i2c_handler:
	ENTER(Z8_I2C_IRQ)
endif
_z8_c0_handler:
	ENTER(Z8_C0_IRQ)
_z8_pb_handler:
	ENTER(Z8_PB_IRQ)
_z8_p7ap3a_handler:
	ENTER(Z8_P7A_IRQ)
_z8_p6ap2a_handler:
	ENTER(Z8_P6AP2A_IRQ)
_z8_p5ap1a_handler:
	ENTER(Z8_P5AP1A_IRQ)
_z8_p4ap0a_handler:
	ENTER(Z8_P4AP0A_IRQ)
_z8_potrap_handler:
	ENTER(Z8_POTRAP_IRQ)
_z8_wotrap_handler:
	ENTER(Z8_WOTRAP_IRQ)
#endif 

/**************************************************************************
 * Name: _z16f_common_handler
 *
 * Description:
 *   Common IRQ handling logic
 *
 *   On entry, the stack contains the following:
 *
 *         TOS before interrupt
 *         PC[7:0]
 *         PC[15:8]
 *         Flags Register
 *   SP -> RP
 *
 *   R0 holds the IRQ number and the RP has been reset to %f0
 *
 **************************************************************************/

_z8_common_handler:
	/* Pass the address of the IRQ stack frame */

	ldx	r2, sph			/* rr2 = stack pointer */
	ldx	r3, spl
	push	r3			/* Pass as a parameter */
	push	r2

	/* Pass the IRQ number */

	push	r0
	
	/* Process the interrupt */

	call	_up_doirq		/* Call the IRQ handler */

	/* Release arguments from the stack */

	pop	r4			/* Discard the IRQ argument */
	pop	r2			/* Recover the stack pointer parameter */
	pop	r3

	/* If a interrupt level context switch occurred, then the
	 * return value will be the same as the input value
	 */

	cp	r0, r2			/* Same as the return value? */
	jr	nz, _z8_switch
	cp	r1, r3
	jr	z, _z8_noswitch

	/* A context switch occurs.  Restore the use context.
	 * rr0 = pointer to context structgure.
	 */

_z8_switch:

	/* Destroy the interrupt return information on the stack */
	
	pop	r4			/* Destroy saved RP */
	pop	r4			/* Destroy saved flags */
	pop	r4			/* Destroy saved return address */
	pop	r4

	/* Copy all registers into the user register area. */

	clr	r2			/* rr2 = destination address */
	ldx	r3, XCPT_RP_OFFS(rr0)
	ld	r4, r0			/* rr4 = source address */
	ld	r5, r1
	ld	r6, #16			/* r6 = number of bytes to copy */

_z8_restore:
	ldx	r7, @rr4
	ldx	@rr2, r7
	incw	rr2
	incw	rr4
	djnz	r6, _z8_restore

	/* Set the new stack pointer */

	ldx	r2, XCPT_SPH_OFFS(rr0)
	ldx	r3, XCPT_SPL_OFFS(rr0)
	ldx	sph, r2
	ldx	spl, r3

	/* Push the return address onto the stack */

	ldx	r2, XCPT_PCH_OFFS(rr0)
	ldx	r3, XCPT_PCL_OFFS(rr0)
	push	r3
	push	r2

	/* Recover the flags and RP settings.. but don't restore them yet */

	ldx	r3, XCPT_FLAGS_OFFS(rr0)
	ldx	r4, XCPT_RP_OFFS(rr0)
	
	/* Determine whether interrupts must be enabled on return.  This
	 * would be nicer to do below, but later we will need to preserve
	 * the condition codes in the flags.
	 */

	ldx	r2, XCPT_IRQCTL_OFFS(rr0)
	tm	r2, #%80
	jr	nz, _z8_returnenabled

	/* Restore the flag settings */

	ldx	flags, r3

	/* Restore the user register page and return with interrupts disabled.
	 * Note that we cannot use the iret instruction because it unconditionally
	 * re-enabled interrupts
	 */

	ldx	rp, r4				/* Does not effect flags */
	ret					/* Does not effect flags */

_z8_returnenabled:
	/* Restore the flag settings */

	ldx	flags, r1

	/* Restore the user register page, re-enable interrupts and return.
	 * Note that we cannot use the iret instruction because it unconditionally
	 * re-enabled interrupts
	 */

	ldx	rp, r4				/* Does not effect flags */
	ei					/* Does not effect flags */
	ret					/* Does not effect flags */

_z8_noswitch:
	LEAVE

/**************************************************************************
 * Data
 **************************************************************************/

	/* Set aside area for interrupt registers */

	define interruptreg, space=rdata, org=%f0
	segment interruptreg
	ds  %10

	end	_z8_common_handler

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?