Add support of other resets

git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@464 42af7a65-404d-4744-a932-0658087f49c3
This commit is contained in:
patacongo 2007-12-30 21:08:23 +00:00
parent 9a7e634a96
commit ba851701b2
4 changed files with 122 additions and 28 deletions

View File

@ -51,8 +51,17 @@
/* Z80 Interrupts */ /* Z80 Interrupts */
#define Z80_IRQ_SYSTIMER (0) #define Z80_RST0 (0)
#define NR_IRQS (1) #define Z80_RST1 (1)
#define Z80_RST2 (2)
#define Z80_RST3 (3)
#define Z80_RST4 (4)
#define Z80_RST5 (5)
#define Z80_RST6 (6)
#define Z80_RST7 (7)
#define Z80_IRQ_SYSTIMER Z80_RST7
#define NR_IRQS (8)
/* IRQ Stack Frame Format /* IRQ Stack Frame Format
* *

View File

@ -70,16 +70,12 @@
.area START (ABS) .area START (ABS)
.org 0x0000 .org 0x0000
.globl _os_start
di ; Disable interrupts di ; Disable interrupts
ld SP, #UP_STACK_END ; Set stack pointer
im 1 ; Set interrupt mode 1 im 1 ; Set interrupt mode 1
jp _os_start ; jump to the OS entry point jr _up_reset ; And boot the system
forever:
jp forever
;************************************************************************** ;**************************************************************************
; Interrupt handler ; Other reset handlers
; ;
; Interrupt mode 1 behavior: ; Interrupt mode 1 behavior:
; ;
@ -92,12 +88,99 @@ forever:
; ;
;************************************************************************** ;**************************************************************************
.org 0x0038 ; Int mode 1 .org 0x0008 ; RST 1
; Create a register frame. SP points to top of frame + 2, pushes ; Save AF on the stack, set the interrupt number and jump to the
; decrement the stack pointer. ; common reset handling logic.
; Offset 8: Return PC is already on the stack ; Offset 8: Return PC is already on the stack
push af ; Offset 7: AF (retaining flags) push af ; Offset 7: AF (retaining flags)
ld a, #1 ; 1 = Z80_RST1
jr _up_rstcommon ; Remaining RST handling is common
.org 0x0010 ; RST 2
; Save AF on the stack, set the interrupt number and jump to the
; common reset handling logic.
; Offset 8: Return PC is already on the stack
push af ; Offset 7: AF (retaining flags)
ld a, #2 ; 2 = Z80_RST2
jr _up_rstcommon ; Remaining RST handling is common
.org 0x0018 ; RST 3
; Save AF on the stack, set the interrupt number and jump to the
; common reset handling logic.
; Offset 8: Return PC is already on the stack
push af ; Offset 7: AF (retaining flags)
ld a, #3 ; 1 = Z80_RST3
jr _up_rstcommon ; Remaining RST handling is common
.org 0x0020 ; RST 4
; Save AF on the stack, set the interrupt number and jump to the
; common reset handling logic.
; Offset 8: Return PC is already on the stack
push af ; Offset 7: AF (retaining flags)
ld a, #4 ; 1 = Z80_RST4
jr _up_rstcommon ; Remaining RST handling is common
.org 0x0028 ; RST 5
; Save AF on the stack, set the interrupt number and jump to the
; common reset handling logic.
; Offset 8: Return PC is already on the stack
push af ; Offset 7: AF (retaining flags)
ld a, #5 ; 1 = Z80_RST5
jr _up_rstcommon ; Remaining RST handling is common
.org 0x0030 ; RST 6
; Save AF on the stack, set the interrupt number and jump to the
; common reset handling logic.
; Offset 8: Return PC is already on the stack
push af ; Offset 7: AF (retaining flags)
ld a, #6 ; 1 = Z80_RST6
jr _up_rstcommon ; Remaining RST handling is common
.org 0x0038 ; Int mode 1 / RST 7
; Save AF on the stack, set the interrupt number and jump to the
; common reset handling logic.
; Offset 8: Return PC is already on the stack
push af ; Offset 7: AF (retaining flags)
ld a, #7 ; 7 = Z80_RST7
jr _up_rstcommon ; Remaining RST handling is common
;**************************************************************************
; NMI interrupt handler
;**************************************************************************
.org 0x0066
retn
;**************************************************************************
; System start logic
;**************************************************************************
_up_reset:
ld SP, #UP_STACK_END ; Set stack pointer
jp _os_start ; jump to the OS entry point
forever:
jp forever
;**************************************************************************
; Common Interrupt handler
;**************************************************************************
_up_rstcommon:
; Create a register frame. SP points to top of frame + 4, pushes
; decrement the stack pointer. Already have
;
; Offset 8: Return PC is already on the stack
; Offset 7: AF (retaining flags)
;
; IRQ number is in A
push hl ; Offset 6: HL push hl ; Offset 6: HL
ld hl, #(3*2) ; HL is the value of the stack pointer before ld hl, #(3*2) ; HL is the value of the stack pointer before
add hl, sp ; the interrupt occurred add hl, sp ; the interrupt occurred
@ -107,21 +190,24 @@ forever:
push de ; Offset 2: DE push de ; Offset 2: DE
push bc ; Offset 1: BC push bc ; Offset 1: BC
ld b, a ; Save the reset number in B
ld a, i ; Carry bit holds interrupt state ld a, i ; Carry bit holds interrupt state
push af ; Offset 0: I with interrupt state in carry push af ; Offset 0: I with interrupt state in carry
di di
; Call the interrupt decode logic. SP points to the beggining of the reg structure ; Call the interrupt decode logic. SP points to the beggining of the reg structure
ld hl, #0 ; Argument is the beginning of the reg structure ld hl, #0 ; Argument #2 is the beginning of the reg structure
add hl, sp ; add hl, sp ;
push hl ; Place argument at the top of thest push hl ; Place argument #2 at the top of stack
push bc ; Argument #1 is the Reset number
inc sp ; (make byte sized)
call _up_decodeirq ; Decode the IRQ call _up_decodeirq ; Decode the IRQ
; On return, HL points to the beginning of the reg structure to restore ; On return, HL points to the beginning of the reg structure to restore
; Note that (1) the argument pushed on the stack is not popped, and (2) the ; Note that (1) the arguments pushed on the stack are not popped, and (2) the
; original stack pointer is lost. In the normal case (no context switch), ; original stack pointer is lost. In the normal case (no context switch),
; HL will contain the value of the SP before the argument was pushed. ; HL will contain the value of the SP before the arguments wer pushed.
ld sp, hl ; Use the new stack pointer ld sp, hl ; Use the new stack pointer
@ -129,21 +215,24 @@ forever:
ex af, af' ; Select alternate AF ex af, af' ; Select alternate AF
pop af ; Offset 0: AF' = I with interrupt state in carry pop af ; Offset 0: AF' = I with interrupt state in carry
ex af, af' ; Restore original AF
pop bc ; Offset 1: BC pop bc ; Offset 1: BC
pop de ; Offset 2: DE pop de ; Offset 2: DE
pop ix ; Offset 3: IX pop ix ; Offset 3: IX
pop iy ; Offset 4: IY pop iy ; Offset 4: IY
exx ; Use alternate BC/DE/HL exx ; Use alternate BC/DE/HL
pop hl ; Offset 5: HL' = Stack pointer at time of interrupt ld hl, #-2 ; Offset of SP to account for ret addr on stack
exx pop de ; Offset 5: HL' = Stack pointer after return
add hl, de ; HL = Stack pointer value before return
exx ; Restore original BC/DE/HL
pop hl ; Offset 6: HL pop hl ; Offset 6: HL
pop af ; Offset 7: AF pop af ; Offset 7: AF
; Restore the stack pointer ; Restore the stack pointer
exx exx ; Use alternate BC/DE/HL
ld sp, hl ld sp, hl ; Set SP = saved stack pointer value before return
exx exx ; Restore original BC/DE/HL
; Restore interrupt state ; Restore interrupt state
@ -156,11 +245,6 @@ nointenable:
ex af, af' ; Restore AF ex af, af' ; Restore AF
reti reti
;**************************************************************************
; NMI interrupt handler
;**************************************************************************
.org 0x0066
retn

View File

@ -43,6 +43,7 @@
#include <string.h> #include <string.h>
#include <nuttx/arch.h> #include <nuttx/arch.h>
#include "chip/chip.h"
#include "up_internal.h" #include "up_internal.h"
#include "up_arch.h" #include "up_arch.h"
@ -84,7 +85,7 @@ void up_initial_state(_TCB *tcb)
memset(xcp, 0, sizeof(struct xcptcontext)); memset(xcp, 0, sizeof(struct xcptcontext));
#ifndef CONFIG_SUPPRESS_INTERRUPTS #ifndef CONFIG_SUPPRESS_INTERRUPTS
xcp->regs[XCPT_I] = 0x0001; /* Carry flag will enable interrupts */ xcp->regs[XCPT_I] = Z80_C_FLAG; /* Carry flag will enable interrupts */
#endif #endif
xcp->regs[XCPT_SP] = (uint16)tcb->adj_stack_ptr; xcp->regs[XCPT_SP] = (uint16)tcb->adj_stack_ptr;
xcp->regs[XCPT_PC] = (uint16)tcb->start; xcp->regs[XCPT_PC] = (uint16)tcb->start;

View File

@ -107,7 +107,7 @@ extern int up_restoreusercontext(chipreg_t *regs);
/* Supplied by board-specific logic */ /* Supplied by board-specific logic */
extern FAR chipreg_t *up_decodeirq(FAR chipreg_t *regs); extern FAR chipreg_t *up_decodeirq(uint8 rstno, FAR chipreg_t *regs);
extern void up_irqinitialize(void); extern void up_irqinitialize(void);
extern int up_timerisr(int irq, FAR chipreg_t *regs); extern int up_timerisr(int irq, FAR chipreg_t *regs);
extern void up_lowputc(char ch) __naked; extern void up_lowputc(char ch) __naked;