몇주 쉬다가 다시 작업 들어갔습니다. ㅎ
인터럽트 처리를 보완하기 위해 구상을 좀더 해봤습니다.
일단 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 기능입니다.)
댓글 없음:
댓글 쓰기