LAB‎ > ‎

Lab 14

14. Exception & SW trap

1) [프로그램 1]을 실행하면서 PIC의 ISR과 CPU의 EX 레지스터 값을 관찰하시오.
- Interrupt Handler가 호출되는 이유가 몇가지 인가?
- 각각의 경우를 어떻게 구별할 수 있는가?

2) [프로그램 1] 인터럽트 핸들러의 출력 부분을 각 원인을 출력하는 것으로 바꾸시오.

3) [프로그램 2]를 실행하는 도중 버튼을 누르면 그 횟수를 세어 출력한다. 
- 실제 누른 횟수대로 잘 출력 하는지 관찰하고 그렇지 않은 경우 설명해보시오.
   PIC의 IRR, ISR의 변화를 관찰

4) [프로그램 2]에서 인터럽트 핸들러가 실행될 때는 User Stack(4000) 대신 System Stack(1000)을 사용하도록 바꾸시오
- 인터럽트핸들러에 진입하고 바로 SP를 변경해야 함.
- 이 때 PUSHALL 전에는 어떤 레지스터 값도 손상되면 안된다. (A, B, C, X, D0, D1, D2, D3)
- PC, SP, PSR은 각각 iRTN, iPSR, iSP에 잘 저장되어 있다.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[프로그램 1]

// V09 Exception, SW Trap, Interrupt
//$DEV SIMPLE-BUTTON 20
//$DEV SIMPLE-BUTTON 25
IO_BRIDGE EQU 0
PIC_IRR EQU 96
PIC_ISR EQU 97
PIC_CMD EQU 98
PIC_IMR EQU 99
SIMPLE_INT START 0
  LD   A P_IHENTRY // initialize IH register
LD IH A
LOOP    
CLR D0
IDIV A D0
INC D0
DEC D0
INT 5
INC D0
DEC D0
CLR D0
IDIV A D0
INT 8
COB
JMP  LOOP
        
ORG  50
IHENTRY INC X
MOV A X
OUT IO_BRIDGE
         LD  A PIC_EOI
     OUT PIC_CMD
IRET
        
P_IHENTRY  BOX  IHENTRY
// Commands for PIC(Programmerble Interrupt Handler)
PIC_MASKON BOX 100
PIC_MASKOFF BOX 200
PIC_MASKSET BOX 300
PIC_ICL BOX 997
PIC_ICE BOX 998
PIC_EOI  BOX  999

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
[프로그램 2]

// Rec3, V09, Execution Stack, Activation records
//$DEV SIMPLE-BUTTON 05
// Segment0 - Initialize after booting
// Segment1 - Interrupt Handler
// Segment2 - User Program
// Segment3 - User Stack
IO_BRIDGE EQU 0
PIC_IRR EQU 96
PIC_ISR EQU 97
PIC_CMD EQU 98
PIC_IMR EQU 99
INIT START 0 // Segment 0
SGMT // set PSR to current segment
LD A P_IHENTRY
MOV IH A
LD A P_RUNTIME
JMP *A
COB // will not come back here
P_IHENTRY BOX IHENTRY
P_RUNTIME BOX RUNTIME
ORG 1000 // Segment 1
IHENTRY // PC, ST, PSR are saved in iRTN, iST, iPSR
// Interrupt Mask is ON in PSR
SGMT // set PSR to current segment

// PUSHALL 하기 전에 visible register(SP 제외)를 손상하면 안됨
PUSHALL // save context info(visible registers) of interrupted program
IN PIC_ISR // find out reason
MOV C A
LD  A =1 // IRQ==1?
CMP A C
SKZ
JMP NEAR INT_EOI
LD  A BUTTON_CNT
INC A
ST A BUTTON_CNT
INT_EOI
LD  A PIC_EOI
OUT PIC_CMD
POPALL // restore context info
IRET // restore PC, ST, PSR from iRTN, iST, iPSR
LTORG
S_STACK_BTM BOX 1000 // Segment 0
BUTTON_CNT BOX 0
// Commands for PIC(Programmerble Interrupt Handler
PIC_MASKON BOX 100
PIC_MASKOFF BOX 200
PIC_MASKSET BOX 300
PIC_ICL BOX 997
PIC_ICE BOX 998
PIC_EOI  BOX  999
// Command for 7 segments
SEG_WRITE BOX 0100
SEG_ON BOX 0200
SEG_OFF BOX 0300
SEG_ON_ALL BOX 0992
SEG_OFF_ALL BOX 0993
ORG 2000 // Segment 2
RUNTIME
SGMT // set PSR to current segment
LD A BOTTOM // SP <-- BOTTOM
MOV SP A
CLR B // LD B #0
DEC  SP // room for return value of MAIN
SETRTN NEAR RTN0 // CALL MAIN
PUSH R
JMP MAIN
RTN0 COB
MAIN PUSH B
MOV B SP
PUSHALL // save visible registers
DEC SP // room for return value of F_RECADD
IN IO_BRIDGE
PUSH A // pass parameter, (n)
SETRTN NEAR RTN1 // CALL F_RECADD
PUSH R
JMP F_RECADD
RTN1 INC SP // remove used arguments
POP A // get return value
OUT IO_BRIDGE
SGMT 1 // BUTTON_CNT is located in segment 1 in this program
LD A BUTTON_CNT
SGMT // restore segment #
OUT IO_BRIDGE
POPALL // restore visible registers
MOV SP B
POP B
POP R // RETURN
JMP *R
F_RECADD PUSH B // PUSH B
MOV B SP // MOV B SP
DEC SP // room for local variable
PUSHALL // save visible registers
LD A %2 // get parameter
CLR C
CMP A C // if (n==0)
SKZ
JMP ELSE
LD A #0 // return 0;
ST A %3 // put return value
POPALL // restore visible registers
MOV SP B
POP B
POP R // RETURN
JMP *R
ELSE
DEC SP // room for return value of F_RECADD
LD A %2 // get n
DEC A // n-1
PUSH A // pass parameter
SETRTN NEAR RTN2 // CALL F_RECADD
PUSH R
JMP F_RECADD
RTN2 INC SP // remove used arguments
POP A // get return value, recadd(n-1)
ADD A %2 // recadd(n-1) + n
ST A %-1 // r = …
LD A %-1 // return r;
ST A %3 // put return value
POPALL // restore visible registers
MOV SP B
POP B
POP R // RETURN
JMP *R
BOTTOM BOX 4000 // Segment 3 for Stack
END
Comments