머리속으로 끼워맞춘 것들을 실제로 구현해보았습니다.
아주 일부분이지만요. ㅎ.ㅎㅋ
문득 아이언맨 1편의 대사가 떠오르네요.
"걸음마 떼려면, 뜀박질부터 해야할 수도 있어!!"
일단 테스트 용으로 쓸만한 보드가 있어야 하는데...음~
작년에 폰트팩 개발할 때 썼던걸로 재활용합니다.
램이 32KB 밖에 없지만 아이큐1000 정도는 괜찮겠죠? ㅋ
CPLD는 EPM3128 박혀있어요~
그럼, 재료(?)는 준비됐고 설명 들어갑니다!!
지난번 paraMSX-R 구상에 관한 글에서는, 실제 동작이 어떻게 이루어지는지 자세한 내용은 없었어요.
이부분을 조금 더 설명드립니다.
일반적으로 MSX 같은 구시대 8BIT PC는 CPU, 메모리 등 각종 로직들이 대게 보드 한장에 들어있습니다.
만약 현재 구성된 본체 상태가 아닌 다른 모양(?)으로 쓰고 싶다면 어떻게 하는게 좋을까요?
완전히 다른 모양 말구요. 동일한 MSX 머신 테두리 안에서요~ ㅋ
예를 들어 "turboR을 대우 IQ-1000 처럼 쓰고 싶다" 정도가 되겠네요.
물론 조건이 있습니다.
기존 보드에 박힌 CPU는 그대로 써야합니다.
PC에서 가장 중요한 부분이 CPU인데, 다른 CPU를 외부에 달면 기존 본체는 노예(Slave)가 되겠죠?
이런식의 구동은 제외합니다.
현재 CPU를 그대로 써서 내 맘대로 MSX를 조작하려면 어떻게 해야할까요?
가장 쉬운 방법은 CPU와 CPU주변의 BUS를 끊고 내가 만든 보드를 끼워넣는겁니다.
모든 신호를 중간에서 잘라먹고 맘대로 변형을 하는거죠.
근데, 이 방법은 후기형 MSX2,2+,turboR의 경우는 사용이 불가능합니다.
왜냐면요...
MSX-ENGINE이라는 큼지막한 원칩안에 CPU, PPI, PSG, 등등 왠만한 칩/로직들이 다 숨어있어요.
중간에 끼어들 공간이 없습니다.
그럼, 차선책이 필요하겠군요.
방법은 하나 S/W에 변형을 가하는 것입니다.
음... 뭔가 이상한가요?
네, 이상하죠? ㅋ
MSX 슬롯에 존재하는 모든 S/W를 변형(패치)를 하는 것은 사실 불가능합니다.
롬 뽑고 교체하는 것도 생각해볼 수 있겠지만, 범용적으로 적용하기는 힘든 방법이겠죠.
그럼, 내가 외부 슬롯에 존재하는 S/W만으로 뭔가 구현을 해야하는데 어떻게 하면 될까요?
paraMSX-R에서 사용한 방법은 본체 내장된 슬롯의 S/W를 몽땅 외부로 옮기는 것입니다.
"어... 외부로 옮겨도 슬롯 구조가 바뀌는건 아니잖아요?"
"그게 어떻게 구동이 되나요?" 라는 생각이 바로 떠올랐다면, 당신은 이미 MSX 전문가~ ㅎ.ㅎㅋ
만약 CPU가 보는 슬롯을 속이면 가능할까요?
예를 들어 CPU(S/W)는 슬롯0-2의 FM BIOS를 구동(read)하고 있지만,
실제로는 FM BIOS가 카트리지 슬롯1에 들어있고, S/W 혼자 슬롯0-2라고 속고 있다면??
이런 상황이 가능할까요?
일단 이걸 구현하려면, MSX가 구동하고 있는 모든 S/W를 실기간으로 간섭할 수 있어야합니다.
결국 MSX의 슬롯 전체를 외부 카트리지로 구현을 해야한다는 얘기겠죠?
예를 들어 본체의 슬롯1에 카트리지가 장착되겠지만,
카트리지 내부는 슬롯0,1,2,3 모두 구현하고 필요한 부분은 서브슬롯 확장이 되어야겠지요.
MSX의 슬롯처리는 PPI의 GPIO를 사용하는데, PPI 슬롯 I/O 주소(port)는 A8H 입니다.
주로 Z80 명령 LD A,N 및 OUT (0A8H),A을 사용합니다.
카트리지에 구현된 슬롯은 기존 PPI와 주소가 겹치면 안되겠죠?
일단 22H 포트를 사용해서 구현해봅니다.
음... 왜 계속 슬롯얘기만 하나요?
그러게요...ㅋ
그럼, CPU(S/W)를 속이는 방법을 생각해보죠.
카트리지에 MSX 슬롯 전체를 구현해서 S/W가 동작할 공간은 만들었지만...
어떻게 내부 슬롯을 액세스 못하게 만들수 있을까요?
예를 들어 LD A, 0 및 OUT (0A8H), A 명령이 실행되면 슬롯0으로 제어가 넘어가겠지요.
이걸 막기 위해, 약간(?)의 H/W 를 추가합니다.
CPU가 명령어 fetch를 하게 되면, 메모리에서 바이트 단위로 BUS를 접근하게 되는데요.
이걸 단계를 나눠서 머신 사이클이라고 표현합니다.
각 사이클을 M1, M2, M3 이런식으로 이름 붙여서 부르고 있어요.
각각의 M 사이클은 CPU clock 카운트에 따라 T1, T2,... 이렇게 T state로 쪼개집니다.
암튼! ㅋ 이렇게 명령어를 메모리에서 읽어갈 때,
paraMSX-R 카트리지는 누가 슬롯을 전환하는지 매번 체크합니다.
M1, M2 사이클의 DATA BUS를 훔쳐보다가...
"어라~ 이거 슬롯 전환하려는건가?" 싶으면 DATA를 변경합니다.
예를 들어 OUT (0A8H),A 명령이 OUT (022H),A 명령으로 바뀌는것이죠.
이때 DATA는 BUS 상에서만 변경되니까, 실제 메모리의 S/W 코드는 그대로 유지됩니다.
결국 이렇게 명령어가 바뀌면(해킹 ㅋ), 본체 내의 슬롯의 여전히 카트리지 슬롯1 설정이 유지되구요.
paraMSX-R 카트리지 내의 슬롯 설정만 바뀌게 됩니다.
여기까지가 슬롯 처리에 관한 내용이었습니다.
그림을 그리면 설명이 더 쉽겠지만, 밤이 늦었으니 이해해주셔요. ㅎ.ㅎㅋ
머리속에서 그림을 그리시면 아마 쉽게 이해되실겁니다.
그럼, 슬롯처리만 구현해서 한번 테스트해볼까요?
폰트팩 보드를 이용해서 VHDL 삽질을 해봅니다~ㅋ
CPLD 용량이 크지 않으니,
슬롯0-0, 슬롯0-1, 슬롯0-2, 슬롯0-3, 슬롯2를 우선 구현하구요.
플래쉬롬에 IQ-1000, IQ-2000 등의 BIOS롬을 정리해서 올렸습니다.
그럼 동작 테스트~ ㅎ.ㅎ
SRAM이 32KB뿐이라 일단 이상태로 구동해봅니다.
1차 IQ-2000 고고고~
결과는 실패ㅋ 부팅로고까지 진입을 못하고, 뺑뺑이 돌고 있네요.
화면에 요상한 글자를 찍으면서..ㄷㄷㄷ
2차 IQ-1000 고고고~
결과는? 오홍~ 뭔가 나오는구나! 제대로 부팅이 되네요.
큐닉스 한글 메시지가 저를 반겨주는군요~ ㅎ.ㅎ
실제로 구동하는 모습을 동영상으로 찍었습니다.
제 turboR에서 실행한 모습입니다요~
음... 겨우 이정도 구현하는데 CPLD(EPM3128) 용량이 FULL입니다. ㅎ.ㅎ;;
X-II 한글롬 테스트 하려면 보드 한장을 더 꽂아야되겠네요.ㅋ
그럼, 또 다음편에서 뵙겠습니다.