LAB‎ > ‎

Lab 15

DMA - Polling & Interrupt

1) [프로그램 1]을 실행해서 CPU 싸이클을 관찰하시오.
- Lab 12에 있는 Programmed IO 기반 프로그램과 싸이클을 비교해 보시오.

2) [프로그램 2]는 [프로그램 1]을 수정한 것이다.
- 8개 문자를 4개 씩 두번에 보내는 것으로 수정함
- 첫 4개를 DMA로 보내고 두번 째 4개를 또 DMA로 보내는데 이 때 앞선 DMA 명령이 완료된 것을 기다려야 한다. (Polling)
- DMA는 끝나면 인터럽트를 보내는데 이를 Interrupt Handler로 반드시 처리하거나 아니면 CPU로 전달되지 못하도록 차단(Masking) 한다. PIC에서 모든 장치의 인터럽트를 차단하도록 하는 것으로  처리하였다.

3) Polling 기반의 [프로그램 2]를 Interrupt 기반으로 수정하여 실행하시오.

+++++++++++++++++++++++++++++++++++++++
[프로그램 1]
// 7 segments IO, DMA
//$DEV SEVEN-SEGMENT-D 10 10 1
SEG_IO START 0
JMP MAIN
IO_BRIDGE EQU 0
PIC_IRR EQU 96
PIC_ISR EQU 97
PIC_CMD EQU 98
PIC_IMR EQU 99
MMIO_BASE EQU 100
MMIO_SEG_DATA EQU MMIO_BASE+10 // IO Address for 7 segments
MMIO_SEG_STATE EQU MMIO_BASE+11
MMIO_SEG_CMD EQU MMIO_BASE+12
MMIO_SEG_DMASRC EQU MMIO_BASE+13
MMIO_SEG_DMADST EQU MMIO_BASE+14
ORG 200
MAIN
LD A MASK_READY
MOV C A
LOOP_READY1 LD A MMIO_SEG_STATE
AND A C
SKNE
JMP LOOP_READY1 // wait until ready
LD A SEG_ON_ALL // Turn on 7 segments device
ST A MMIO_SEG_CMD
LD A ="0"
MOV D2 A
LD A ="9"
MOV D3 A
LD A #0
MOV X A // i=0
DO_WHILE
LD  A MSG_LENGTH
CMP X A // i < MSG_LENGTH
SKN
JMP END_WHILE
// IF
LD A @MSG // A <- *MSG (or MSG[i])
MOV D0 A
CMP D0 D2 // Char >= BASE
SKZP
JMP ELSE
CMP D0 D3 // Char <= END
SKZN
JMP ELSE
// THEN
MOV A D2
NEG A
ADD A D0 // A <- Char-BASE
MOV D1 A
LD A P_SEG_CONV
ADD D1 A // D1 <- &SEG_CONV+(Char-BASE)
MOV D0 *D1 // D0 <- SEG_CONV[Char-BASE]
JMP END_IF
ELSE
LD A =0b01000000 // 하이픈 '-'
MOV D0 A
END_IF
MOV A D0
ST A @CONV_MSG
INC X // i++
JMP DO_WHILE
END_WHILE
// Using DMA
LD A MASK_READY
MOV C A
LOOP_READY2 LD A MMIO_SEG_STATE
AND A C
SKNE
JMP LOOP_READY2 // wait until ready
LD A P_CONV_MSG
ST A MMIO_SEG_DMASRC
CLR A // 7segment 장치의 buffer 주소는 0에서 시작
ST A MMIO_SEG_DMADST
LD A #8
ST A MMIO_SEG_DATA
LD A SEG_DMA_WRITE
ST A MMIO_SEG_CMD
COB
P_SEG_CONV BOX SEG_CONV
SEG_CONV BOX 0b00111111 //0
BOX 0b00000110 //1
BOX 0b01011011 //2
BOX 0b01001111 //3
BOX 0b01100110 //4
BOX 0b01101101 //5
BOX 0b01111101 //6
BOX 0b00000111 //7
BOX 0b01111111 //8
BOX 0b01101111 //9
P_MSG BOX MSG
MSG BOX "20181015"
MSG_LENGTH BOX $-MSG
P_CONV_MSG BOX CONV_MSG
CONV_MSG RESBOX 8
// 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
SEG_DMA_WRITE BOX 0991
SEG_DMA_READ BOX 0994
SEG_DMA_RESET BOX 0999
MASK_READY BOX 0009 // Mask bits 
SEG_DMA_READY BOX 0301
LTORG
END

+++++++++++++++++++++++++++++++++++++++
[프로그램 2]
// 7 segments IO, DMA & Polling
//$DEV SEVEN-SEGMENT-D 10 10 1
SEG_IO START 0
JMP MAIN
IO_BRIDGE EQU 0
PIC_IRR EQU 96
PIC_ISR EQU 97
PIC_CMD EQU 98
PIC_IMR EQU 99
MMIO_BASE EQU 100
MMIO_SEG_DATA EQU MMIO_BASE+10 // IO Address for 7 segments
MMIO_SEG_STATE EQU MMIO_BASE+11
MMIO_SEG_CMD EQU MMIO_BASE+12
MMIO_SEG_DMASRC EQU MMIO_BASE+13
MMIO_SEG_DMADST EQU MMIO_BASE+14
ORG 200
MAIN
LD  A =0x3F // ignore interrupt
MOV C A
LD  A PIC_MASKSET
ADD A C
OUT PIC_CMD
LD A MASK_READY
MOV C A
LOOP_READY1 LD A MMIO_SEG_STATE
AND A C
SKNE
JMP LOOP_READY1 // wait until ready
LD A SEG_ON_ALL // Turn on 7 segments device
ST A MMIO_SEG_CMD
LD A ="0"
MOV D2 A
LD A ="9"
MOV D3 A
LD A #0
MOV X A // i=0
DO_WHILE
LD  A MSG_LENGTH
CMP X A // i < MSG_LENGTH
SKN
JMP END_WHILE
// IF
LD A @MSG // A <- *MSG (or MSG[i])
MOV D0 A
CMP D0 D2 // Char >= BASE
SKZP
JMP ELSE
CMP D0 D3 // Char <= END
SKZN
JMP ELSE
// THEN
MOV A D2
NEG A
ADD A D0 // A <- Char-BASE
MOV D1 A
LD A P_SEG_CONV
ADD D1 A // D1 <- &SEG_CONV+(Char-BASE)
MOV D0 *D1 // D0 <- SEG_CONV[Char-BASE]
JMP END_IF
ELSE
LD A =0b01000000 // 하이픈 '-'
MOV D0 A
END_IF
MOV A D0
ST A @CONV_MSG
INC X // i++
JMP DO_WHILE
END_WHILE
// Using DMA
LD A MASK_READY
MOV C A
LOOP_READY2 LD A MMIO_SEG_STATE
AND A C
SKNE
JMP LOOP_READY2 // wait until ready
LD A P_CONV_MSG
ST A MMIO_SEG_DMASRC
CLR A // 7segment 장치의 buffer 주소는 0에서 시작
ST A MMIO_SEG_DMADST
LD A #4
ST A MMIO_SEG_DATA
LD A SEG_DMA_WRITE
ST A MMIO_SEG_CMD
// Polling
// LD A MASK_READY
// MOV C A
// LOOP_READY3
LD A SEG_DMA_READY
MOV C A
LOOP_READY3 LD A MMIO_SEG_STATE
CMP A C
SKZ
JMP LOOP_READY3 // wait until DMA ready
LD A P_CONV_MSG4
ST A MMIO_SEG_DMASRC
LD A #4 // 7segment 장치의 buffer 주소는 0에서 시작
ST A MMIO_SEG_DMADST
LD A #4
ST A MMIO_SEG_DATA
LD A SEG_DMA_WRITE
ST A MMIO_SEG_CMD
COB
P_SEG_CONV BOX SEG_CONV
SEG_CONV BOX 0b00111111 //0
BOX 0b00000110 //1
BOX 0b01011011 //2
BOX 0b01001111 //3
BOX 0b01100110 //4
BOX 0b01101101 //5
BOX 0b01111101 //6
BOX 0b00000111 //7
BOX 0b01111111 //8
BOX 0b01101111 //9
P_MSG BOX MSG
MSG BOX "20181015"
MSG_LENGTH BOX $-MSG
P_CONV_MSG BOX CONV_MSG
P_CONV_MSG4 BOX CONV_MSG+4
CONV_MSG RESBOX 8
// 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
SEG_DMA_WRITE BOX 0991
SEG_DMA_READ BOX 0994
SEG_DMA_RESET BOX 0999
MASK_READY BOX 0009 // Mask bits 
SEG_DMA_READY BOX 0301
LTORG
END

Comments