2010년 5월 16일 일요일

파라동-4SLOT #3 케이스 합체 및 테스트

꿈꾸는 소년님이 제작하신 아크릴 케이스가 도착했습니다. ㅎ.ㅎ

6각 너트 드라이버가 없어서, 소형 롱노즈-플라이어로 열심히 돌렸습니다. ㅋ

케이스가 반짝반짝 아름답군요~~~

 

일단 파나소닉 MSX 3형제에 연결해서 잠깐 테스트했습니다.

(MSX2: FS-A1, MSX2+: FS-A1WSX, MSXturboR: FS-A1GT)

 

이미 테스트 하신 분과 같이,

FS-A1에서 매퍼램을 켰을때, 제대로 부팅이 되지 않았습니다.

제가 프로토타입으로 만든 확장슬롯+1MB 보드로 돌렸을때는

서브슬롯0에 램, 서브슬롯1또는2에 MMC/SD 드라이브 상태에서 동작이 되었는데...으흑...

 

이게 뭔가 HW적인 타이밍 문제가 있는 것 같습니다.

확장슬롯 + 램 + MMC/SD 드라이브 세개를 한번에 쓸때만 나오는 문제 같네요.

혹시나해서 IQ2000에서도 해봤는데 무한 리부팅됩니다. ㅡ.ㅡ;

 

풀업저항은 제 프로토타입이랑 같고

차이는 어드레스 라인과 MERQ등의 컨트롤 신호가 74LS244를 경유 하는 것인데요. (버퍼링과 슬롯 스위치 역할)

근데 이게 WSX랑 GT는 괜찮고 A1이랑 IQ2000만 문제가 생기니... 이유를 잘 모르겠습니다.

 

일단 FS-A1이나 IQ2000, X-II, 소니 MSX등에서 확장슬롯 연결해보신 분, 결과 좀 알려주세요.

X-II에서도 안될 확률이 높겠지만... 소니 MSX에서도 안되면... 좀 난감하네요. ㅜ.ㅜ;

 

  

아래 사진들은 WSX에서 서브슬롯0에 1024KB램, 서브슬롯1에 MMC/SD 드라이브 꽂고 테스트하는 모습입니다.

왼쪽에 세워놓은 사라만다 케이스는 지난 오프모임때 유령군님이 선물로 주신거에요. ㅎ.ㅎ

(사진 찍다보니 갑자기 생각나서 배경으로 등장했습니다. 두둥~ㅎ )





파나소닉 FS-A1 파워 개조

얼마전에 전원 어댑터가 없는 FS-A1을 샀었습니다.

뚜껑만 한번 열어보곤, 별로 만지지는 못했었지요. (어댑터가 없으니 당연한 건지도...ㅋ)

 

전원부를 어떡하나 고민하다가, 모 쇼핑몰에서 소형 ATX 파워를 하나 샀습니다.

요건 220V에 바로 연결되는게아닌, DC 12V 입력을 받아서 5V, 3.3V, +12V, -12V 를 출력해줍니다.

 

혹시 관심있으신 분은 아래 링크에서 해당 제품을 보실수 있습니다요.

http://www.eleparts.co.kr/front/productdetail.php?productcode=022005015001000004

가격이 26,400원으로 후덜덜하지만, 용도에 딱맞는 녀석이라 보자마자 바로 구매했습니다. ㅋ

 

 

아래는 제 A1 뚜껑을 벗긴 모습입니다.

좀 어둡게 찍혔군요.




원래 A1의 전원 입력은 외장 어댑터로 부터 DC 9V, AC 18V를 받도록 되어있습니다.

이걸로 MSX에서 주로 쓰이는 DC 5V, +12V, -12V로 바꾸게 됩니다요.




일단 메인보드 좌측 상단의 전원쪽 부품을 들어냅니다. (보드를 뒤집으면 우측 상단이네요.)

기존의 전원 스위치는 그대로 사용할수 있도록 주변 정리(?)를 했습니다.




아래 사진의 조그만 보드가 ATX 파워 서플라이입니다.

원래 제작사에서는 카PC에 쓰일 목적으로 만든 것 같네요.

소형 저전력 PC에 쓰면 딱맞겠습니다. (사실 MSX에는 좀 과분하죠...ㅋ)

참고로, 사진에서는 ATX 보드에 연결되는 커넥터가 제거되어 있습니다.





새로 장착된 파워 서플라이와 보드의 기존 5V, +12V, -12V 라인에 연결된 모습입니다.

78L12, 79L12의 O라고 표시된 부분에 +12V, -12V 연결하면 되고요.

5V는 본체의 커다란 방열판에 연결된 5V 레귤레이터의 2번째 핀이 있던 곳에 연결하면됩니다.



 

ATX 전원은 RGB 및 카세트 커넥터 있는 부분에 글루건으로 고정했습니다.

원래 이부분을 방열판이 덮고 있던 곳이지요.

본체 덮개랑 공간이 많이 있는 곳이라 대충 고정해도 괜찮은 것 같습니다.

 

사진에서 빨강/검정 전선이 외부 12V(5A) 어댑터에서 들어오는 전원이고요.

노랑색으로 5V 출력, 두개의 회색선은 +12V, -12V입니다.




외부 12V 어댑터 연결부를 찍어봤습니다. (촛점이 엉뚱한데에 맞춰있군요. ㅎ.ㅎ)

기존 3핀 전원 커넥터를 제거하고, 둥근 모양의 어댑터 잭을 달았습니다. 위치가 딱 맞습니다요.




키보드를 얹은 모습입니다.




원래 있던 부품들이네요.

이걸 따로 보관해야할까요... 아님 그냥 버릴까요? 흠~




부팅시 MSX 로고가 나온 모습입니다.

A1은 원가절감을 너무한건지... 리셋 버튼도 없고 CAPS/KANA LED도 없고 참 심플하네요.

대신 외부 전원 어댑터를 쓰느라 본체는 상당히 작고 가볍습니다.

간단히 롬팩 게임을 즐길때는 딱 좋을 것 같네요. ㅎ.ㅎ



2010년 5월 11일 화요일

DOS2 Banking Library & Build tool 제작 #1

그냥 오래전부터 생각했던 프로젝트였는데, 이제서야 실천(!)에 옮기려고 진행하는 것인데요...

그게 뭐냐고요? ㅋ 으흠~ ㅎ.ㅎ



MSX에는 메모리 매퍼를 이용해 64KB 이상의 메모리를 사용할 수 있도록 설계되어있습니다.

이 메모리를 좀 더 효과적으로 사용하는 프로그램을 만들자라는 것이 목표이고요.

물론 기존에도 그냥 메모리 매퍼를 직접 액세스하거나 DOS2의 매퍼 루틴으로 잘 썼긴했습니다.

근데 솔직히, DOS2에 메모리도 넉넉하게 쓸수 있는 유저가 많지 않았었죠?

저도 이것 때문에 일반적으로 배포하려고 만드는 프로그램은,

메모리 매퍼를 쓰지않고 DOS1의 기본 메모리에서 구동되도록 했었습니다.

대신, 디스크 퍼포먼스는 DOS2 쪽이 좋기 때문에,

DOS2에서 실행되는 경우에는 DOS2의 시스템 콜을 쓰도록 만들었습니다.



최근에 저와 흥건남자님과 힘을 합쳐 확장슬롯+1MB램을 쓸수 있는 기기가 나오게 되었는데요,

이제 메모리를 활용할수 있는 프로그램을 본격적으로 만들어도 될때가 되지않았나 생각됩니다.

메모리가 많으면, 스크린7의 인터레이스 모드 그래픽을 쓰거나,

안티앨리어스 적용되는 한글 폰트룰 만든다던가...  재밌는걸 할수 있겠지요. ^^



일단 메모리 매퍼를 조금 설명드리면...

다른 대부분의 MSX기본 기기처럼, 메모리 매퍼도 IO 맵 I/O로 동작합니다.

근데 한가지 이상한 부분이 있죠.

MSX에서는 메모리 매퍼를 여러개 써도 되도록 규격이 만들어져 있습니다.

그러니까 슬롯1에는 1024KB, 슬롯3-0에는 512KB... 이런식으로 쓸 수 있다는 것이지요.



근데, 중요한건 메모리 매퍼용 IO 주소는 슬롯 제한을 받지 않는다는 사실인데요.

(IO 맵 방식이니까, 당연한 것이지만요.)

이게 SW 개발하는 사람한테는 참 머리아픈 문제입니다.

왜냐면, 예를 들어 현재 Page2 메모리(8000H~BFFFH)를 다른 세그먼트(뱅크 또는 페이지라고 보시면됩니다.)로

할당하게 되면, 모든 슬롯에 장착된 메모리 매퍼의 세그먼트가 같이 바뀝니다.



게다가 한가지 문제가 더 있는데요.

메모리 매퍼중에는 현재 세그먼트 번호를 읽을 수 있도록 만들어진게 대부분입니다.

MSX2 이상의 본체 내장된 건 아마 다 읽을 수 있을꺼에요.

문제는 Write 할때는 같은 주소에 연결된 기기가 한번에 동작은 하는데,

반대로 Read 할때는 램의 용량에 따라 세그먼트 최대 갯수가 다르니 읽은 값도 다를 수가 있겠죠?

이 때문에, 매퍼 레지스터를 읽는 것은... 법(!!)으로 금지되어 있습니다.



하지만 안타깝게도 MSX의 메인 바이오스는 메모리 매퍼에 관한 루틴이 하나도 없어서,

메모리 매퍼를 컨트롤하려면 SW 만드는 사람이 알아서 해야된다는 것이었죠.

이 때문에 많은 메모리 관련 호환성 문제가 발생하게 되었습니다.



어떤 슬롯에 얼마나 메모리가 장착되어 있는지, 확인하는 것이 쉽지가 않습니다.

아까 말했듯이 특정 세그먼트를 바꾸면, 원하지 않는 슬롯의 메모리도 변경이 되고...

용량을 확인하려면, 16KB 영역을 R/W 해보면서 램인지 일일이 체크를 해야하는데 쉽지 않죠.



그래서 많은 프로그래머들이 그냥 용량 체크는 세그먼트 값을 썼다가 읽은 값이 같아지는 숫자만을 인식하거나,

특성 슬롯만 메모리 확인을 하거나... 매퍼가 두개 이상일때는 메인(Primary) 매퍼만 사용하거나... 등의

방법을 썼습니다.



제 경우에도 터보알(A1GT)의 내장램을 1024KB로 확장하니까, 대부분 유럽산 프로그램들이 동작하지 않더군요.

보통 128KB~256KB 메모리를 요구하는 프로그램들입니다.

재밌게도 일본에서 만든 프로그램은 대부분 64KB 전용이라 크게 문제될게 없더군요.

국내 SW는 대우 MSX에 맞춰서 슬롯/메모리 등을 설정해서 또 문제가 됐었고요.



단지 일반 개발자 뿐만 아니라 유명한 게임들도 비슷한 제들이 있었습니다.

마이크로 캐빈의 FRAY는 메모리 확장된 터보알에서 부팅 안되는게 제일 유명한가요?



암튼 HW 설계상의 약점과 SW 개발의 어려움이 한데 뭉쳐져서 메모리 활용이 상당히 힘들었습니다.



이게 MSX-DOS2의 디스크 바이오스에서 메모리 매퍼를 지원하게 되어 이런 문제가 해결되었습니다.

바이오스 콜을 통해 메모리 세그먼트의 할당/해제/전환을 쉽게 할수 있게 되었지요.



Page3을 제외한 Page0,1,2 (0000H~BFFFH)의 메모리를 마음데로 바꿀수가 있습니다.

Page0의 경우는 인터럽트 사용시 주의해야겠지만... 암튼요.



방법은 DOS2 매뉴얼에 나오니 여기서 설명하진 않겠습니다.

다시 말씀드리지만, 메모리 매퍼 강좌를 하려는게 아니에요. ^^;



어쨋꺼나 DOS2 바이오스의 지원으로 메모리는 좀 더 사용이 쉬워졌지만,

개발자가 메모리 구성을 잘해서 SW를 만들어야 하는 것은 변함이 없습니다.

MSX용 개발 툴 중에서 DOS2 메모리 관련 루틴을 활용한 것이 따로 있는지는 잘 모르겠네요.

몇 종류의 어셈블리와 파스칼, C 정도의 컴파일러가 있지만, 대부분 CP/M용이라 (MSX-DOS1 겸용)

활용이 불가능 할 겁니다.



암튼, 서론이 길었는데요. ㅎ.ㅎ;

이번에 HI-TECH C에서 DOS2 메모리 매퍼 활용을 높일 수 있도록,

관련 라이브러리와 단일화된 메모리맵을 만들고 있습니다.



일단 컴파일러로 HI-TECH C를 고른 이유는...

라이브러리가 풀 소스로 제공되고, 인라인 어셈블리 사용도 편리한 편이고,

ANSI C를 풀로 지원한다거나 여러가지가 있겠지만,

제가 최근 수년간 쓰면서 많이 익숙하다는게 주 이유일 것 같네요.

함수 파라미터와 로컬 변수가 모두 스택에 할당되기 때문에

퍼포먼스가 좀 딸린다는 단점이 있지만, 대신 항상 함수의 Re-entrant(재진입)가 가능합니다.



메모리 관리는 DOS2의 확장 바이오스 루틴에 의존합니다.

메모리 세그먼트가 다른 함수 간의 호출은 별도의 뱅킹 루틴을 통해 이루어지는데요.

총 약4MB의 메모리를 사용할 수 있습니다.(DOS2와 터보알의 시스템 영역은 제외)

16KB 세그먼트 2개를 한개의 프로그램 뱅크로 사용합니다.

그러니까 최대 128개의 뱅크(32KB x 128 = 4096KB)를 프로그램으로 쓸수 있습니다.

일단 아래 메모리 맵을 보세요.



0000H~00FFH : DOS 시스템 콜 영역

0100H~7FFFH : 뱅킹 가능한 프로그램 영역(TEXT/DATA/BSS) (약 32KB)

8000H~8FFFH : 뱅킹(세그먼트 전환) 루틴, 뱅킹 스택 (4KB)

9000H~9FFFH : 공용 ISR 및 뱅크간 공유 DATA 영역 (4KB)

A000H~FFFFH : 스택 및 Work Area (24KB)


한동안 고민했던 메모리맵이었는데요,

함수 갯수가 많아지고 뱅킹간의 함수 콜도 왠만큼 하려면 스택이 많이 필요해지는데,

일단 현상태로 괜찮을지는 모르겠습니다.

부족하면 뱅크간 공유 DATA 영역을 줄여야겠지요. ^^



0100H~7FFFH 영역을 프로그램으로 할당한 것은,

Page1(4000H~7FFFH) 영역을 다른 슬롯에 있는 SW를 사용하거나,

메모리맵 IO를 쓰는 주변기기를 쉽게 액세스하기 위함입니다.

그리고, 실제 뱅킹은 Page0,1(0000H~7FFFH) 전체 영역이 바뀌게 되니까,

개별적인 인터럽트 루틴을 잠깐씩 쓸때도 유용하지 않을까 생각되네요.

아직 DOS2 시스템 콜을 사용시, Page0를 제대로 복구하는지는 테스트를 해봐야됩니다.



현재 뱅킹 루틴을 만들어서 테스트 중인데요.

HI-TECH C 컴파일 했을때 일반 함수에서 다른 뱅크로 잘 전환되는지 확인중입니다.



진행 상황은 가끔 글로 올리겠습니다.

혹시 질문 있으면 댓글로 달아주세요~




2010년 5월 4일 화요일

[강좌] 02. MSX의 주변기기 I/O

I/O라는 말을 처음 들어보셨나요?

I/O는 Input/Output의 준말로 CPU와 주변 기기와의 입출력의 의미합니다.

참고로, 자주 쓰는 말인 'BIOS'의 IO도 Input Output을 의미하고 있습니다.



만약 컴퓨터에 CPU와 ROM/RAM만 달려있으면, 별로 쓸만한 기기가 못되겠죠?

뭔가 사용자로 부터 입력(키보드/조이스틱 등)도 받고,

결과를 출력(모니터/프린터 등)도 하는 방법이 있어야겠습니다.

사운드를 듣고 싶다면 PSG 등의 사운드 칩을 제어할 수 있는 방법이 있어야하겠지요.



Z80 CPU와 주변 장치를 제어할 수 있는 방법은 크게 두가지가 있습니다.

Memory Mapped IO와 IO Mapped IO 인데요.



메모리맵 방식은 CPU가 보기엔 RAM 같은 메모리에 값을 읽기/쓰기를 하는 것 처럼 보이지만,

실제로는 주변 장치에 데이터를 입력/출력하는 방법입니다.



IO맵 방식은 CPU에서 주변기기 입출력을 위해 만들어진 별도의 명령으로,

데이터를 입력/출력하는 방법입니다.



MSX에서는 메모리를 슬롯이라는 것으로 여러개의 공간으로 관리한다고 그랬었죠?

메모리맵 방식의 IO를 쓸때는 특정 슬롯에 RAM 같은 메모리 아닌,

HW 기기를 연결하고 CPU의 /MERQ, /RD, /WR 신호에 맞춰 동작하게 구성합니다.

참고로 CPU의 /MERQ는 메모리 액세스 요청, /RD는 읽기 신호, /WR은 쓰기 신호입니다.



IO맵 방식의 IO를 쓸때는 슬롯의 메모리 공간과는 별도로,

특정 IO 주소에 HW 기기를 연결하고 CPU의 /IORQ, /RD, /WR 신호에 맞춰 동작하게 구성합니다.

참고로 CPU의 /IORQ는 IO 액세스 요청하는 신호입니다.



기억하실 부분은...

Z80 CPU에서 메모리 R/W와 IO R/W 관련된 명령이 따로 존재한다는 것.

MSX에서 메모리는 슬롯으로 관리되니까,

같은 주소에 메모리맵 IO를 만들더라도 선택된 슬롯에만 실제 IO가 이루어집니다.

IO맵 IO는 슬롯 상관없이 주소만 맞으면, IO가 이루어집니다.

만약 같은 주소의 IO맵 IO를 쓰는 기기를 2개가 연결되었다면 동시에 동작하게 됩니다.



그럼, 실제로 메모리맵 또는 IO맵 방식 사용시, 어떤 장단점이 있을까요?



장점을 먼저 생각해보면,



메모리맵 IO는 컨트롤 주소가 같은 기기를 여러개 쓰더라도,

슬롯 선택을 먼저 해야되니까 개별로 동작시키는 것이 가능합니다.

예)FDD 같은 디스크 장치는 기본적으로 메모리맵 IO방식입니다.

   여러개를 연결했을때 개별로 동작이 가능해야되니까요.

   코나미 메가롬팩 등의 카트리지 내에도 뱅킹을 위한 IO가 들어있습니다.

   그냥 롬 영역을 읽을 때는 롬의 코드가 읽혀지지만,

   IO 영역에 데이터를 쓰면 8KB 단위 등으로 페이지가 바뀌는 것이지요.

   물론, 해당 주소의 롬 데이터가 바뀌지는 않습니다.



IO맵 IO는 슬롯 선택에 관한 메모리 제한이 없으니, 쉽게 SW로 컨트롤이 가능합니다.

예)키보드, VDP, PSG 등의 경우가 대표적이죠.

  SW 구동 환경이 DOS이거나 BASIC이거나 32KB롬팩이거나 FDD의 디스크롬 상관없이,

  쉽게 키보드의 눌러진 키를 확인하거나 화면의 글자색을 바꾸는 것들을 할 수 있습니다.



그럼, 단점은 뭘까요? 각각의 장점이 서로의 단점이 됩니다. ^^



메모리맵 IO의 경우는 해당 기기가 장착된 슬롯으로 먼저 전환해야만 액세스가 가능하니까,

SW를 만들때 좀 복잡해지는 경우가 많습니다.

같은 기기가 몇개나 장착되어 있는지, 해당 기기는 메모리의 어떤 PAGE에서만 구동이 되는지 등등

인터럽트 또는 BIOS 구동시 제약은 없는지 상당히 고려를 해야합니다.

예) 도스에서 DIR C: 라고 명령했을때,

    해당 드라이브는 누구의 디스크 인터페이스가 처리하는지,

    그 인터페이스는 어느 슬롯에 있는지 미리 다 알고 있어야 하겠죠?

    김준성님의 MPX 카트리지도 메모리맵 IO방식이라서,

    저의 MPXP 프로그램을 구동하면 먼저 MPX가 어느 슬롯에 존재하는지 검색하게됩니다.



IO맵 IO의 경우는 같은 IO 주소에 한개의 기기(물론 예외도 있습니다)만 존재해야합니다.

예) FM 사운드 칩의 경우, FM-PAC, MSX-AUDIO, MOON-SOUND, turboR PCM, PPI 1BIT Sound 등

    MSX에서 여러가지 사운드를 쓸수 있는데요. 모두 주소가 다릅니다.

    MOON-SOUND의 경우 비교적 레어 기기인 MSX-AUDIO를 대체하기 위해서 같은 주소를 쓰지만,

    이 경우엔 두개의 사운드 기기를 동시에 사용하는 것은 불가능합니다.


    

이런 각각의 장단점으로 있으니 대개 주변기기 구현시는 아래 사항이 고려되겠지요.

자주 액세스가 필요하고 슬롯같은 메모리 제한을 받지않고 쉽게 액세스 가능해야되지만,

시스템에는 하나만 있으면 충분한 기기의 경우는 IO맵 IO를 쓰게 됩니다.

예) 키보드, VDP의 경우 왠만한 SW는 자주 컨트롤할 필요성이 높죠?

    하지만 컴퓨터에는 하나만 있으면 충분한 경우입니다.

반대로 여러개의 기기를 동시에 사용가능해야 하는 경우는,

컨트롤시 메모리의 슬롯 제한이나 여러가지 불편하더라도 메모리맵 IO방식을 쓰게 됩니다.



그 외, 메모리맵 방식은 특성상 IO 메모리 영역을 비교적 넓게 쓸수 있지만,

이건 HW 만들기 나름이라 IO맵 IO방식도 가능합니다.

예) V9938 칩은 IO맵 IO방식으로 만들어져 있는데, (몇개의 Port로만 컨트롤합니다.)

   128KB의 VRAM을 R/W 가능하도록 되어있습니다.



그럼 실제로는 어떤 명령어를 써야 하는지 보겠습니다.



-메모리맵 방식으로 B000H 주소에 'K'를 출력하는 경우.

(참고로 'K'는 ASCII 코드로 문자 A의 값을 의미합니다.)



어셈블리의 경우,

LD A,'K' ; CPU 레지스터 A에 'K'문자 값을 넣음.

LD (0B000H),A ; 메모리 주소 B000H에 레지스터 A의 내용을 출력.



BASIC의 경우,

A = ASC("K") ; A 변수에 'K'문자 값을 넣음.

POKE &HB000,A ; 메모리 주소 B000H에 변수 A의 내용을 출력.



너무 간단한가요? ㅋ

물론, 주소에 데이터를 출력하기 전에 해당 슬롯이 전환되어 있어야합니다.



-IO맵 방식으로 20H 주소에 'K'를 출력하는 경우.

(참고로, 원래 Z80은 IO맵 IO 사용시 16비트 주소를 쓸 수 있지만, MSX는 하위 8비트만 사용합니다.)



어셈블리의 경우,

LD A,'K' ; CPU 레지스터 A에 'K'문자 값을 넣음.

OUT (020H),A ; IO 주소 20H에 레지스터 A의 내용을 출력.



BASIC의 경우,

A = ASC("K") ; A 변수에 'K'문자 값을 넣음.

OUT &H20,A ; IO 주소 B000H에 변수 A의 내용을 출력.



어셈블리/BASIC 명령어가 거의 똑같죠?

근데, 코드가 별로 가슴에 와닿지 않죠? ^^



자~ 그럼, 실제 MSX에 존재하는 하드웨어를 제어해봅시다.

키보드를 보면 대문자 선택을 나타내는 CAPS LED가 있죠?

MSX의 기본 인터럽트 서비스 루틴(보통 ISR이라고 합니다)이 동작하는 동안에는,

메인 BIOS가 키의 상태를 주기적으로 스캔해서 저장해놓는데요,

이 때 CAPS LOCK 키가 눌러지면 CAPS LED를 켜고 끄는 일도 합니다.

이걸 수동으로 한번 해보는거에요.



그냥 LED만 켜고 끄면 재미없으니, PPI의 1BIT 사운드를 같이 ON/OFF하면서 소리도 들어봅시다.

MSX의 키보드와 1BIT 사운드 하드웨어는 8255라는 병렬 포트 칩으로 컨트롤하게 되어있습니다.

회로도를 보면서 설명해도 좋겠습니다만, 일단 실습부터 해보죠.



여기서 8255는 IO맵 방식으로 컨트롤하는데 AAH 주소에 값을 쓰게 되면,

키보드 신호 셀렉트, CAPS LED, 1BIT SOUND, 카세트 출력을 한번에 조작할 수 있습니다.

데이터는 아래처럼 사용할 수 있는데요.

비트0-3: 키보드 매트릭스의 ROW 선택

비트4: 카세트 모터 0:ON, 1:OFF

비트5: 카세트 출력 0:LOW, 1:HIGH

비트6: CAPS LED 0:ON, 1:OFF

비트7: 1BIT 사운드 출력 0:LOW, 1:HIGH



여기서 비트7,6을 한번에 바꿔서, 사운드 출력 주파수에 맞춰 LED가 반짝이도록 합니다.

카세트 포트도 바꿔주면 카세트 출력도 함께되겠지만 일단 비트7,6만 바꿔봅니다.

BASIC에서 아래 프로그램을 실행해보세요.



10 FOR L=0 TO 20

20 OUT &HAA,&B00110000

30 FOR I=0 TO L:NEXT

40 OUT &HAA,&B11110000

50 FOR I=0 TO L:NEXT

60 NEXT:GOTO 10



터보알 고속모드에서는 10 FOR L=0 TO 70 으로 하고 실행해보세요.

쀼~웅~ 소리와 함께 CAPS LED가 반짝이는 것을 볼수 있습니다.


위의 예처럼 간단한 하드웨어는, IO맵 방식으로 만들면 쉽게 조작할수 있습니다.

하지만 주소 공간이 256개 뿐이라 MSX에서는 이미 많은 주소가 할당(예약)되어 있지요.

궁금하신 분은 아래 싸이트에서 IO맵을 확인할 수 있습니다.

http://map.grauw.nl/resources/msx_io_ports.php



메모리맵 IO는 선택된 슬롯에서만 동작하니까, 다른 기기의 IO 주소가 겹칠수가 없겠죠.

MPXP 같은 메모리맵 IO로 된 기기를 두개를 장착하면,

두개의 MP3 파일을 동시에 소리나게 할수도 있겠습니다.