2010년 7월 30일 금요일

DOS2 Banking Library & Build tool 제작 #5

이번에는 특정 슬롯의 메모리를 R/W 할수 있는 함수들을 만들어봤습니다.

MPX 또는 MMC/SD 드라이브, 메가플래시롬팩 등의 메모리맵 I/O를 쓰는 기기를 액세스시 사용할 수 있습니다.

 

1바이트 R/W는 MSX 메인 바이오스 루틴을 쓰면 페이지 제한없이 가능하니깐,

일단 메인 바이오스 콜을 기본으로 넣었습니다.

 

그 다음은 블럭 메모리 전송인데, 이 경우는 목적지 페이지1,2만 가능하도록 했습니다.

메모리 위치는 페이지 상관없지만, 목적지 페이지와 동일하면 안되겠지요.

물론 전송 사이즈가 커서 어드레스가 페이지를 가로지르면 문제가 됩니다요. ㅋ

안전하게 페이지0->1, 페이지1->2, 페이지2->1 등등으로 

 

테스트용으로 MPXP 프로그램을 뱅킹 라이브러리를 쓰도록 초간단 버전을 하나 만들었습니다.

이름은 MPXPS (마지막 S는 Simple을 의미합니다.ㅋ)

참고로, 뱅킹라이브러리 릴리즈할때, MPXPS 소스도 예제로 들어갈 예정입니다.

 

실행해보니, MMC/SD HW V2에서 128KBPS짜리가 겨우 돌아가는 정도는 되네요. ㅎ.ㅎ

사실 원본 MPXP는 전송루틴이 어셈으로 되어서 속도가 조금 빠른편인데요,

어셈 안쓰고 일반 C함수 콜만으로도 어느정도는 쓸만한 것 같습니다. ㅋ

  

그 외, 틈틈히 필요한 함수들 만들고 있습니다.

키보드 입력(RAW I/O)이나 터보알/파나소닉MSX2P CPU 모드 등등...

점점 라이브러리가 커지고 있네요. ㅋ

 

그래픽과 사운드(BGM?) 예제 두어개 만들면, 이대로 1차 릴리즈해야될거 같습니다.

생각날때마다 조금씩 진행하다보니 진도가 넘 느리네요. ㅎ.ㅎ

 

혹시 관심있으신분, 요청사항 있으면 댓글 달아주세요.


2010년 7월 18일 일요일

DOS2 Banking Library & Build tool 제작 #4

몇주 쉬다가 다시 작업 들어갔습니다. ㅎ

 

인터럽트 처리를 보완하기 위해 구상을 좀더 해봤습니다.

 

일단 DOS2 상태에서 인터럽트가 발생되면,

기존 SW의 ISR(Interrupt Servie Routine)을 구동하기 위해, 페이지0이 원래의 메인 BIOS로 변경이 됩니다.

 

결국, 이 때는 원래 프로그램 내의 루틴이 정상으로 돌아갈 수 있는 상태가 아닌 것이지요.

각 뱅크(페이지0,1) 내의 ISR을 처리하기 위해, 페이지0의 슬롯 처리 및 뱅킹 처리가 같이 되어야 합니다.

 

그외 BIOS의 ISR 처리는 여러가지 키보드 등의 입력 기기와 음악(PLAY) 루틴이 함께 들어가있는데,

필요 없는 코드를 그대로 실행할 필요는 없을 것 같고요.

여기에 추가로 KEYI와 TIMI 두개의 훅(HOOK) 으로 실행되는 유저 ISR도 옵션 처리가 가능하도록 바꿨습니다.

보통 TIMI 훅에는 디스크 드라이버의 타이머 루틴이나 그 외 타이머 류의 SW가 들어가게 되는데,

필요한 경우 멈출수 있도록 하는 것이지요.

 

이렇게 하려면, 메인 BIOS에서 첫 KEYI 훅으로 유저 ISR이 콜될때 강제로 스택의 리턴 주소를 지우고,

따로 필요한 ISR만 콜해주면 쉽게 됩니다.

기존 BIOS 루틴의 JIFFY 카운트도 따로 처리합니다.

 

VDP의 스프라이트 충돌, 스캔라인 인터럽트(H-Blank), V싱크 인터럽트(V-Blank) 3개의 인터럽트와

외부 인터럽트 8개를 사용할 수 있도록 했습니다. (좀 많나요? ㅋ)

 

일단 ISR 우선 순위는 아래처럼 해놨습니다.

EXT0,EXT1,HBLK,EXT2,EXT3,SPRT,VBLK,EXT4,EXT5,EXT6,EXT7

의 순으로 체크됩니다.

 

EXTn -> 외부 인터럽트

HBLK -> VDP H-Blank

VBLK -> VDP V-Blank

SPRT -> VDP Sprite 충돌

인데요.

여기서 스프라이트 충돌은 실제 VDP에서는 인터럽트가 아니라 단지 State만 알려주는 것인데,

V-Blank 때 같이 인터럽트로 ISR를 콜하도록 해놨습니다.

 

특별히 게임이나 음악 등 타이밍 처리를 위한 wait 함수들도 구현해봤습니다.

VDP의 60Hz V-Blank 인터럽트를 활용한 것인데요.

물론 기존의 JIFFY 값으로 처리해도 상관없지만 어셈으로 만든 라이브러리가 쓰기편할테니...ㅋ

wait_60hz(), wait_30hz() 이런식의 함수로, 타이밍 동기처리를 할 수 있습니다.

 

그리고, 게임 등 경우에 따라, 범용 키보드 I/O가 필요없을 때에는,

메인 BIOS의 키처리 루틴을 스킵할 수 있습니다.

물론 C라이브러리의 scanf 등으로 키입력을 쓸때는 켜놔야겠지요. (기본은 상태는 ON 입니다.)

 

실제로 모두 구현해서 테스트해보니,

DOS2의 매퍼 뱅킹 처리나, 슬롯 전환 등의 코드가 수행되느라 인터럽트 응답이 약간 느리긴한데요.

그래도 편리성을 생각하면, 이런식이 훨씬 쓰기 편한 것 같습니다요.

 

인터럽트 처리는 이정도로 마무리하고,

다음은 각 슬롯의 메모리맵 I/O를 위한 루틴을 만드려고 합니다. 

 

아래는 인터럽트 테스트를 위해 만든 코드가 돌아가는 모습인데요.

터보알에서 VDP의 스캔라인 인터럽트와 V-Blank의 타이밍 루틴을 이용해서,

화면이 좌우로 흔들리는 효과를 구현해봤습니다. (참고로 좌우 흔들림은 V9938의 ADJUST 기능입니다.)