V25 CPU 설명

O V25+ (uPD70325)

- 16비트 원칩마이크로프로세서 (8비트의 외부데이타버스)

- INTEL 8086 CPU와 100% 소프트웨어 호환성

-  내부 CPU코어

- 32비트의 범용 디지탈입출력포트

- 3체널 하드웨어 인터럽트

- DMA, 그리고 2체널의 시리얼포트

O V25 마이크로프로세서의 특징 (<그림 3-2> V25의 핀배치도)

- 8086과 100% 소프트웨어호환

- 내부 16비트/외부 8비트 데이타버스

- 어드레스버스/데이타버스가 분리

- 2체널의 시리얼포트

- 32비트의 입출력포트

- 3개의 타이머 (2개의 16비트 타이머와 20비트의 타임베이스 타이머)

- 8 세트의 레지스터 뱅크 (범용내부램, 레지스터뱅크전환식 인터럽트처리)

- 하드웨어 인터럽트콘트롤러 내장 (3개의 하드웨어 인터럽트를 처리)

O V25의 내부구조 (<그림 3-1> V25의 내부 블럭도 , <표 3-1> V25의 단자기능 )

- 명령읽기/해독/실행 등을 담당하는 16비트 CPU코어

- DMA,직렬포트,타이머,인터럽트,범용 입출력 등의 내장주변장치

- 두종류의 내부 16비트 데이터버스

- 6바이트의 프리페치큐(prefetch Queue)를 이용 (파이프라인 동작)

- 8개의 레지스터뱅크(1뱅크=16워드)

- 주변장치 하드웨어

* 클럭제네레이터

* 3체널 외부 하드웨어 인터럽트콘트롤러

* 2체널의 시리얼 콘트롤러

* 2체널의 16비트의 타이머, 20비트의 타임 베이스 카운터

* 256바이트로 구성된 특수기능레지스터(Special Function Register,SFR)

O V25의  메모리 맵 (<그림 3-4> V25의 메모리맵)

- 20비트(1MB)의 어드레스 공간

- 16bit 세그먼트 레지스터 + 옵셋 레지스터 ==> 20비트 어드레스 생성 (<그림 3-3> 어드레스 계산)

- 인터럽트 벡터테이블 : 1MB 메모리 공간의 하위 1KB(1024바이트)

* 256개의 인터럽트벡터 (각각 4바이트 크기)

- 512바이트 내장데이타영역(IDA,Internal Data Area)

* IDB(Internal Data Base)라는 레지스터에 의해 1M바이트	공간내에 재배치 가능

* 256바이트의 내장 RAM + 256바이트의 특수기능레지스터(SFR) (<표 3-3> 특수기능레지터)

* 어드레스 지정 방식 (IDB 이용)

. IDB 레지스터 set : FFFFFh번지(고정)와 xxFFFh번지(xx는 IDB 레지스터 값) 에 write

. 내장 데이터 영역 어드레스 : xxE00h ~ xxFFFh (xx 는 IDB 레지스터 값)

. 예 (터보-C)

poke(0xFF00,0x0FFF,0x12);   즉 IDB 레지스터 = 12h

내장 데이터 영역 : 12E00h ~ 12FFFh

O V25의 입출력포트맵

- 64K 바이트의 포트어드레스

- 메모리맵 방식으로 관리

- 예

* V25의 내장 입출력포트인 포트0 (약호=P0)을 출력모드로 만들고, P0에 0xFF를 출력하는 프로그램

#include <dos.h>   /*pokeb()함수가 선언된 헤더화일*/

#define V25REG   (0xFD00) /*상위 8비트=IDB레지스터의 값*/

#define V25_P0   (0xF00) /*P0(포트0)의 최종위치는 IDB레지스터로 결정*/

#define V25_PM0  (0xF01) /*특수기능레지스터(표1-1) 참조)*/

#define V25_PMC0 (0xF02)

void test_P0(void)

{

/*IDB(Internal Data Base)에 의해 내장데이타영역의 위치결정*/

/*내장데이타영역의 번지를 0xFDE00h~0xFDFFFh로 변경시킨다*/

pokeb(0xFF00,0x0FFF,0xFD);  /*IDB레지스터의 값을 0xFD로 변경*/

/*V25 port 0를 출력 모드로 한다.*/

pokeb(V25REG,V25_PMC0,0x0);/*port0의 기능은 PMC0,PM0에 의해 결정*/

pokeb(V25REG,V25_PM0,0x0); /*V25REG의 상위 8비트는 IDB레지스터의 값*/

/*port 0의 모든 비트를 1로 만든다*/

pokeb(V25REG,V25_P0,0xFF);

}/*end of test_P0*/

입출력명령 프로그램

#include <dos.h>

void my_extern(void)

{

char in_data,out_data;

/*확장 입출력포트 1000H번지의 데이타를 읽는다.*/

in_data = inportb(0x1000);

/*확장 입출력포트 1000H번지의 모든 비트를 1로 만든다*/

out_data=0xFF;

outportb(0x1000,out_data);

}

O V25의  레지스터 세트

- 8086과 동일한 범용레지스터 8세트

- 내장데이타영역에 메모리로서 매핑

- 레지스터 조작명령뿐 아니라 메모리 조작 명령으로도 억세스

- 뱅크전환식 인터럽트서비스에 사용, 범용램으로 사용

- 한순간에 하나의 뱅크만이 기본레지스터로 설정 (리셋시 7번)

O V25의 외부버스 사이클 (<그림 3-5> 외부버스 타이밍)

- 외부 버스 제어신호는 /READ,/WRITE,/MREQ,/IOSTB,/MSTB

O V25의 인터럽트 처리방식

- i8086 호환 벡터 인터럽트

- 뱅크전환식 인터럽트 처리방식을 지원

- 19개 인터럽트 (표 3-4)

- 인터럽트 처리방식: 인터럽트 요구제어 레지스터(IRC)로 결정 (<그림 3-6> 인터럽트 요구제어 레지스터)

- IRC는 각각의 하드웨어 인터럽트마다 하나씩 할당 (특수기능레지스터(SFR)영역에 있음)

- 모든 인터럽트루틴은 FINT(하드웨어 인터럽트종료)명령어로 종료

- 인터럽트처리방식: 벡터방식, 레지스터뱅크전환 방식, 매크로서비스 방식

- 각 인터럽트의 처리방법, 우선순위, MASK(활성/비활성) 지정은 IRC로 지정

- 리셋시

* 모든 인터럽트의 우선순위는 7로 되고(레지스터뱅크=7)

* 벡터방식의 인터럽트

* 인터럽트 금지상태로 설정

- 벡터방식 인터럽트처리 (<그림 3-7> 벡터인터럽트)

* 벡터식 인터럽트는 x86계열이나 i8051등에서 사용하는 방식

* 벡터테이블 참조 해당 번지로 프로그램을 분기

* 인터럽트벡터 테이블은 i8086과 동일 (00000h ~ 00300h(1024바이트)에 할당)

* 인터럽트가 걸리면 현재의 프로그램위치를 스택에 저장

--> (CS,IP,FLAG 레지스터 3워드 (6바이트)와 인터럽트서비스루틴에서 사용되는 모든 레지스터

* 모두 256종류의 인터럽트를 처리

- 레지스터뱅크전환식 인터럽트 (<그림 3-8> 레지스터뱅크전환식 인터럽트)

* 해당 인터럽트 요구제어 레지스터(IRC) MS/ENCS비트를 "01"로 만듬

* 현재의 프로그램위치와 인터럽트서비스루틴에서 사용되는 레지스터를 새로운 레지스터에 저장

* 인터럽트의 처리과정 (그림 3-8)

* 인터럽트가 발생

. CPU의 IP가 레지스터뱅크의 IP저장

. 벡터 IP(VECTOR IP)레지스터에 기록된 값이 새로운 IP에 로드

. 플레그 레지스터 FLAG 저장영역에 세이브

. 새로운 뱅크의 CS와 IP(VECTOR IP)로부터 계산된 번지부터 실행

. 새로운 뱅크의 IE(FLAG레지스터에 소속)가 0으로 클리어 되어 인터럽트 금지

. 처리루틴 끝 : RETBI 명령어를 실행

- 매크로 서비스

* 인터럽트처리방법의 하나라기 보다는 소프트웨어적인 DMA처리

- V25의 인터럽트 벡터테이블 (<표 3-5> PC/XT, TBDOS,V25 인터럽트 비교)<그림 3-11>

O V25의 콘트롤 레지스터

- PRC 레지스터 (<그림 3-9> 프로세서 콘트롤 레시스터(PRC))

- 웨이트 제어 레지스터(WTC) (<그림 3-10> 웨이트 콘트롤 레시스터(WTC))

- 리프레쉬 제어 레지스터(RFM): 내장형제어기에서 그다시 사용되지 않음

O V25의  내장주변장치

- 입출력포트

* 각각 8비트의 P1,P2,P3의 범용 디지탈입출력 포트(24비트)

* 8비트의 비교입력포트(PT)

* 포트제어레지스터 PMCn, PMn (n=0-2)로 제어

* 리셋시 모두 입력포트(하이임피던스)로 설정됩니다.

* 포트 0 (<표 3-6> 입출력 포트의 동작설정 레지스터(PMC,PM))

. PMC0,PM0 레지스터(SFR에 포함)의 조합에 의해 비트단위로 지정

. 예 : P0의 P00,P01,P02,P03을 입력포트, P04,P05,P06을 출력포트, P07을 CLOCK 출력핀 설정

poke(V25REG,V25_PCM0,0x80); /*콘트롤/범용디지탈입출력결정*/

poke(V25REG,V25_PM0,0x0F);  /*범용디지탈입출력의 입출력결정(비트단위)*/

* 포트1 (외부 인터럽트 모드레지스터(INTM))

. NMI,INTP0,INTP1,INTP2 의 에지 모드 선택 : 인터럽트모드 레지스터(INTM)

* 포트2

. 콘트롤기능(PMC2의 해당비트가 "1"일 경우)은 주로 DMA와 버스관련

* 포트 T (PT0 - PT7) (<그림 3-12> 포트T 모드레지스터(PMT))

O 타이머 (<그림 3-13> 타이머 콘트롤 레지스터(TMC)

- 2개의 16비트 타이머와 1개의 20비트 프리런닝타이머(타임베이스타이머)를 내장

O 시리얼 인터페이스 (<그림 3-14>SCC,SCM 레지스터)

- 2채널의 시리얼포트 (<그림 3-15> 직력포트 비동기모드 내부 블럭도(체널0,1))

- 채널1은 일반적인 비동기통신(스타트비트+데이타비트+스톱비트)을 행하는 비동기모드 전용

- 채널0은 비동기모드로 사용하거나 클록동기의 입출력 인터페이스 모드로 이용가능

B.G = 106 X fCLK/2m+1

B : 전송 보오 레이트[bps]

G : BRGn레지스터의 설정치( 2 <=  G <=  255 )

fCLK : 시스템 클록 주파수[MHz]

m : SCCn레지스터의 설정치( 0 <=  m <=  8)

O DMA

- 주변장치와  대량의 데이타를 고속으로 주고 받을 때 사용

- 주변장치와 메모리간 메모리와 메모리사이의 데이터전송에 이용

- CPU의 개입없이 DMA제어기에 의해 주변장치의 데이터를 직접 메로리로 옮김

O V25의 80X86 비호환 추가명령

- 8086/8088의 명령어를 전부 포함하며, 80186/80188의 명령어도 포함

- 자신의 고유명령어를 추가 (8086/8088과의 소프트웨어호환성이 상실)

- FINT: 내장 하드웨어 인터럽트 콘트롤러에게 인터럽트처리가 완료되었다는 것을 통보

- RETRBI: 뱅크전환식 인터럽트처리루틴이 종료되었을 때 원래의 레지스터뱅크로 전환

- MOVSPA: 인터럽트 실행전의 스택을 레지스터 뱅크 전환후 연속해서 사용하기 위한 것

새로운 뱅크에서 해당 뱅크의 스택을 사용하기 전에 이명령이 수행되어야 함

- MOVSPB reg16: MOVSPA 명령어와 반대동작

TB-V250 보드

O TB-V250보드의 구성 (<그림 4-1> TB-V250보드의 구성)

- V25+(uPD70325) 프로세서

- 256K 바이트의 메모리

- 24비트의 디지탈입출력

- 8비트 디지탈입력

- 2개의 시리얼 포트

- 92핀 확장버스

- 밧데리 백업기능

- TBDOS-V25(MSDOS호환)를 탑재할 수 있는 도스머신(DOS-MACHINE)

O TB-V250보드의 규격 (<표4-1>  TB-V250보드의 규격)

O TB-V250보드 구성 부품의 위치 (<그림 4-2> TB-V250보드 부품위치)

O TB-V250보드의 메모리 맵 (<그림 4-3> TB-V250 보드의 메모리 맵)

- 128KB(1메가 비트) 롬(ROM): V25BIOS,TBDOS-V25,프로그램저장용 롬디스크

- 128KB 램(SRAM): 벡터테이블,바이오스 데이타, 도스 데이타, 작업영역 그리고 램디스크

O TB-V250보드의 동작

- PC에서 준비해야 할 프로그램  : k232.EXE (TB-V250 보드와 통신 프로그램)

- PC와 TB-V250보드 사이에 연결해햐 할 것 : RS-232용 케이블

- k232 에서 통신 포트 및 속도 설정

O TB-DOS

- 대상 CPU : INTEL 8086호환 CPU (I8086/88,186,286,386,486,V30,V40,F8680,V25 등)

- MSDOS와 호환되는 부분

INT 20H, INT 25H, INT 26H

INT 21H중 다음 기능 (16진법)

0,      1,      2,      3,      6,      7,      8,      9

A,      B,      C,      F,     14,     19,     1A,     1B

1C,     21,     25,     26,     27,     29,     2A,     2B

2	C,     2D,     2E,     2F,     30,     31,     35,     36

37,     3B,     3C,     3D,     3F,     40,     41,     42

43,     44(00), 47,     48,     49,     4A,     4B,     4C

4D,     4E,     4F,     50,     51,     56,     57

- V25MODEM,T232을 이용하여 RAM에 업로딩/다운로딩 실행.

O TBDOS의 동작개요

- 프로그램 작성 : (예: TEST.EXE)

- 보드와의 통신 프로그램 구동 : k232.exe

- 포트 및 보드레이트 설정 : COM1, COM2 에 맞춰 세팅, 보드레이트는 9600

- A: drive 에서 B: ram drive 설정 : vformat 메모리양(Kbyte 단위) y

(예: vformat 40 y --> B: drive 를 SRAM 40Kbyte 크기로 만듬)

- 프로그램 다운로드

* A drive 에 있는 k25modem 을 구동 (받기 준비)

* Escape 를 누르면 k232 memu 가 나옴 (다운로드 선택)

* 다운로드할 파일 이름 입력 (예 : TEST.EXE)

- B: 드리이브로 감

- dir : 다운로드 프로그램의 파일이 보임

- 실행 : (예, B:TEST return)

O TBDOS의 ROM/RAM 디스크

- A: ROM DISK  사용번지 E000:0-F300:0 (76KB)

- B: RAM DISK  사용번지/용량은 가변 (48KB) -V25FMT로 결정

O TBDOS-V25 내장명령

- HELP = 사용가능한 명령어 리스트를 보여줌

- VER  = TBDOS의 버전번호 표시

- DIR   = 디렉토리 리스트

- DEL  = 화일지움 (TBDOS-V2.0에는 포함되지 않음)

- CD   = 디렉토리 변경

- A:, B: = 드라이브 변경

O K232사용법

- IBM-PC와 TB-V250보드사이에 연결된 RS-232 직렬통신 프로그램

- 문자전송/수신, 화일전송/수신 등의 기능을 수행

- IBM-PC에서 동작하는 프로그램

- K232의 동작모드

* 메뉴모드: K232의 사용포트,보레이트 등의 동작환경을 선정

* 콘솔모드: IBM-PC를 TB-V250의 콘솔(CONSOLE, 문자 입출력장치)로 사용하는 모드

* 메뉴모드 와 콘솔모드의 전환:  <ESC>키를 누를 때마다 수행

- 메뉴 모드

* 통신설정 : 사용포트와 통신속도 설정

* 파일송/수신 : 보드로 파일 정송 (다운로드) 및 보드에서 파일 받음 (업 로드)

. 전송파일 : Alt-D 로 수신화일 결정함

. 수신파일 : B: drive 에 있어야함

. 전송시 : A:\> Alt-D 하여 수신화일 결정

. 수신시 : B:\> HM 파일 이름

* 실행

. 현재의 드라이브를 B: 드라이브로 전환 (B: enter)

. DIR (다운로드된 파일을 봄)

. 다운로드된 파일 enter

-  콘솔모드

* IBM-PC와 TB-V250보드가 1:1로 통신하는 모드

* TB-V250보드D의 직렬포트는 38400보레이트,1스타트비트,8데이타비트,1스톱비트

* T232 메뉴모드에서 이것과 동일하게 선정해야 함

* IBM-PC의 키보드가 직접 TB-V250보드에 연결되었다고 생각하면 됨

O 다운로드 (<다운로드 동작순서>)

- IBM-PC의 프로그램이나 데이타화일을 RS-232 직렬통신라인을 통하여 TB-V250 보드의 B드라이브

(램디스크)로 전송하는 작업

- IBM-PC 쪽 데이터 전송 : k232.exe

- TB-V250 쪽 데이터 수신 : hm.exe

O 프로그램 개발전에 알아두어야 할 일.

- IBM-PC 호환기종의 호환성

* BIOS를 통해서 접근하는 프로그램은 IBM-PC와 동일하게 동작

* BIOS를 이용하지 않거나, V25BIOS에서 지원하지 않는 BIOS를 사용하는 경우, 호환성을 유지할 수	없음

* 비데오램(VIDEO RAM)이 장착 않음

* 비데오램을 직접 조작하는 프로그램은 TB-V250보드에서 동작하지 않음

- TB-V250보드의 문자 출력

* IBM-PC의 BIOS 인터럽트 10H 텔레타이프모드(기능 0EH)를 지원

* 터보-C의 printf,putch,puts,cputs,scanf 등의 함수는 사용할 수 없음

* getch, bioskey, kbhit함수 등은 TB-V250보드에서 자유롭게 사용

O 프로그램 예제

- 문자 출력 (BIOS 인터럽트 10H, 기능 0EH를 사용) (터보-C)

/*비데오 인터럽트(10H-기능 0EH)를 이용한 문자 출력함수*/

#include <dos.h>

void V25putch(char ch)

{

_AH=0xE ; /*텔레타이프 모드*/

_AL=ch ;  /*전송할 문자*/

geninterrupt(0x10);   /*비데오 인터럽트 10h를 건다*/

}

- V25BIOS 지원 인터럽트 (IBM-PC와 호환)

INTERRUPT 10H - 비데오 인터럽트 기능 0EH

INTERRUPT 12H - 메모리 크기

INTERRUPT 13H - 디스크

INTERRUPT 16H - 키보드 인터럽트

O TB-V250보드에서의 프로그램 개발

-  IBM-PC에서의 프로그램 작업과 비슷

- IBM-PC와 호환성이 없는 부분은 TB-V250보드 상에서 점검

- IBM-PC에서 프로그램/디버깅 작업을 완료

- 최종적인 실행화일이 완성되면 이것을 TB-V250보드로 이식

* 실행화일을 롬에 굽는 것 (현장에서 사용)

* 실행화일을 TB-V250보드의 RAM디스크(B: 드라이브)로 다운로드 (개발시)

O 예제 프로그램

- 키보드를 누를 때까지 점차 LED를 어둡게 하다가, 사용자가 키보들르 누르면 LED를 수차례 깜빡이	는 동작

- 사용되는 함수

* V25putch() : 한 문자(ASCII)를 RS-232포트로 출력 (출력된 문자는 T232의 수신 화면에 표시됨)

* V25puts() : 문자열을 RS-232포트로 출력하는 함수입니다.

* main()   : 인터럽트함수설치, 제거, LED TEST문 처리

* pokeb(segment,offset,data): Turbo-C의 함수로 segment:offset번지에 data를 씀

* peekb(segment,offset): segment:offset에서 데이타를 읽는 함수

프로그램 리스트 1. V25INTRO.C

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

/**  함수이름 : v25intro.c                                      **/

/**  사용컴파일러 : Turbo-C V2.0                              **/

/**  메모리 모델  : small model (다른모델도 관계 없음)         **/

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

#include <stdio.h>

#include <dos.h>

#include <conio.h>

#include <float.h>

#include <math.h>

#include <stdlib.h>

#include "v25c.h"     /*v25용 헤더화일*/

#define  YES  1

#define  NO   0

/*[]--------------------------------------------------------------[]*/

/*[] Turbo-C의 CRT관련함수는 VIDEO MEMORY를 직접조작하거나 비데오 []*/

/*[] 관련정보를 요구하기 때문에 TB-V250 응용에는 적합하지 않다    []*/

/*[] 따라서 TB-V250보드에서는 CRT관련함수를 직접 만들어 사용한다  []*/

/*[]--------------------------------------------------------------[]*/

/*한문자를 출력하는 함수 <Interrupt 10h - 기능0Eh(텔레타이프 모드)>*/

/*V25BIOS에는 int 10h-기능 0Eh가 RS-232포트로 한 문자를 출력하도록 */

/*            설계되어 있다.                                       */

void V25putch(char ch)

{

_AH=0xE ; /*텔레타이프 모드*/

_AL=ch ;  /*전송할 문자*/

geninterrupt(0x10); /*video interrupt*/

}

/*문자열 출력함수-V25putch를 이용*/

void V25puts(char *buff)

{

int i;

/*buff의 끝은 0으로 끝나기 때문에, buff끝까지 문자를 출력한다*/

for(i=0;buff[i];i++)

{

/*출력할 문자가 '\n'일 경우 <CR>,<LF>를 출력한다*/

if(buff[i]=='\n')

{

V25putch('\r');

V25putch('\n');

continue; /*다음문자를 처리한다*/

}

V25putch(buff[i]);  /*한문자를 출력한다*/

}

}

/*가변인자 함수.. TB-V250보드용 printf()함수*/

void V25printf(char *format, ... )

{

char buffer[100];

va_list  argptr;              /* 인자 리스트 포인터*/

va_start( argptr, format );   /* va_ 함수를 초기화 한다*/

/* format의 양식대로 buffer 문자열을 만든다*/

vsprintf(buffer, format, argptr );

V25puts(buffer);              /* 문자열을 출력한다*/

va_end( argptr );             /* va_ 함수를 종료한다*/

}

/*약간의 지연시간을 두는 함수*/

void  delay_10(void)

{

int i,j;

for (i=0;i<12;i++)

for(j=0;j<5000;j++);

}

/*V25 port 테스트 함수*/

void  V25port_test(void)

{

int i;

V25puts("\nLED점등을 실험하겠습니다.");

delay_10();

/*V25 port 0를 출력 모드로 한다.*/

/*V25 port 데이타북을 참조*/

pokeb(V25REG,V25_PMC0,0x0);

pokeb(V25REG,V25_PM0,0x0);

V25puts("\n");

/*LED ON/OFF를 7회 반복한다*/

for(i=0;i<7;i++)

{

V25puts("LED ON    ");

pokeb(V25REG,V25_P0,0xFF);

delay_10();

V25puts("LED OFF   ");

pokeb(V25REG,V25_P0,0x00);

delay_10();

}

V25puts("\n");

}

/*실수연산 테스트 함수*/

void float_test(void)

{

float x=1.994,y=0.727;

V25printf("\n실수연산을 테스트합니다.");

V25printf("\nx=%-3.3f  y=%-3.3f  x+y=%-3.3f     x*y=%-3.3f",

x,y,x+y,x*y);

V25printf("\n                  sin(x)=%-3.3f  cos(y)=%-3.3f\n",

sin(x),cos(y));

delay_10();

}

void  intro(void)

{

V25puts("\n\n---< (c)1994-1995 태백엔지니어링(TEBEK ENGINEERING) >---");

V25puts("\n태백엔지니어링의 TB-V250보드를 구입해주셔서 감사합니다.\n");

V25puts("\n지금 이글을 보내는 프로그램은 TBDOS(MS-DOS호환) 환경의");

V25puts("\nTB-V250보드에서 동작되는 V25INTRO.EXE 라는 프로그램입니다.");

V25puts("\nIBM-PC 에서 Turbo-C로 실행화일을 만든 후 아무런 수정없이 ");

V25puts("\nTB-V250 보드로 옮겨서 실행시키고 있는 중입니다.\n");

}

volatile int interval_flag; /*인터럽트에 의해 바뀔 경우를 대비해서 이렇게 선언*/

volatile int bright_count;  /*레지스터변수로 사용되는 것을 막는다*/

void bright_control(void)

{

int i;

V25puts("\n아무키나 누르면 중지합니다.");

interval_flag=NO;

for(i=0;i<200;i++)

{

/*새로운 타이머 인터럽트(new_int1Ch)에서 한주기플래그를 세울때까지*/

/*기다린다. 한주기플래그(interval_flag)는 50ms마다 갱신된다*/

/*new_int1Ch()루틴을 참조*/

V25printf("\n1Ch count=%d",i);

while(interval_flag!=YES);  /*한주기가 될 때까지 기다린다*/

disable();  /*인터럽트를 금지시킨다*/

interval_flag=NO;

/*bright_count값은 0에서 10까지의 값을 가진다.*/

/*0이 가장 밝고, 10은 가장 어둡다(OFF)*/

bright_count=i/20;

enable();   /*인터럽트를 허가한다*/

/*밝기 조절 중간에 아무키나 누르면 중단한다*/

/*kbhit함수 (Turbo-C의 함수) 참조*/

if(kbhit())

{

getch();  /*키보드에서 한문자를 읽는다*/

break; /*키보드가 눌리면 루프를 탈출한다*/

}

}/*200회 루프*/

}

/*새로운 타이머 인터럽트 루틴을 만든다*/

/*TB-V250보드이 타이머 인터럽트(int 1Ch)는 하드웨어 인터럽트이며*/

/*10ms마다 인터럽트가 발생한다*/

void interrupt new_int1Ch(void)

{

/*Turbo-C에서는 interrupt 함수를 사용할 경우, DS의 값을 초기화시켜준다*/

/*즉 mov bp,xxxx;  mov ds,bp; 와 같이 xxxx라는 현재의 DS값을 다시 한번*/

/*인터럽트루틴의 초기부분에서 써준다.*/

static int timer_count=0;   /*처음 함수가 수행될 때의 초기값*/

enable();                   /*또다른 인터럽트를 허가한다*/

timer_count++;    /*인터럽트가 걸릴 때마다 timer_count값을*/

/*증가시킨다*/

/*한주기(50ms)가 완료되면 timer_count를 0으로 만들고*/

/*한주기플래그(interval_flag)를 세운다*/

if(timer_count>=10)

{

timer_count=0;

interval_flag=YES;

}

/*timer_count가 bright_count보다 작으면 LED를 켠다*/

/*아닐 경우는 LED를 끈다*/

if(timer_count<bright_count)

pokeb(V25REG,V25_P0,0x00);

else

pokeb(V25REG,V25_P0,0xFF);

}

void main(void)

{

void interrupt (*old_int1Ch)();  /*인터럽트함수 포인터*/

intro();        /*초기설명*/

float_test();   /*실수연산 테스트*/

V25puts("\nLED 밝기를 점검합니다. 아무키나 누르세요.");

getch();

old_int1Ch = getvect(0x1C);  /*원래의 인터럽트를 저장한다*/

setvect(0x1C,new_int1Ch); /*새로운 타이머 인터럽트를 설치한다*/

bright_control();

setvect(0x1C,old_int1Ch); /*원래의 타이머 인터럽트를 복구한다*/

V25port_test();   /*V25 port 동작 테스트*/

}