Closed likearome closed 7 months ago
우선 가장 쉽게 고려해볼 만한 것은 인터럽트 번호 1Ah / AH:06 명령어인 CMOS의 RTC 타이머 콜백인데, DOSBOX에서는 이 인터럽트 기능이 구현돼 있지 않다.
따라서 호환성 이슈가 있을 것으로 보인다.
그 다음 고려해볼만한 요소는 비디오 IRQ 혹은 마우스/키보드 IRQ를 통한 접근이다.
둘 모두 정확성도 떨어지고, 게임의 반응성에 영향을 줄 수 있기 때문에 썩 내키지는 않는다.
인터럽트 70번 핸들러가 열쇠가 될 수 있을 것 같다.
인터럽트 70번은 인터럽트 15번/AX:8300을 발동시키면 매 초 1024개의 인터럽트를 발생시킨다.
따라서 70번 후킹 뒤, 인터럽트 15번을 1초 걸어놓고 70번을 틱 인터럽트처럼 참조하다가 1초가 지나면 또 15번을 걸어두고 하는 식이면 게임 내내 반복 연주를 감시할 수 있을 것 같다.
70번으로 코드를 구성하고 VIDE-CDD.SYS를 올려보았더니 예전 이슈처럼 멈춘다.
결국 70번도 ~08번에서 호출된다는 사실을 알 수 있었다.~ (아래 설명. 8번에서 호출돼서 그런게 아님)
70번은 해결책이 되지 않았다.
https://www.[compuphase.com/int70.txt](https://www.compuphase.com/int70.txt)
위 문서를 살펴보면 인터럽트 15/AX:8300 없이도 70번 실시간 인터럽트를 발생시킬 수 있는 것으로 보인다. 이 경우 8번과 관계없이 동작할 수 있을지도 모르겠다.
위 과정대로 hz를 변경하고 해봤는데 VIDE-CDD를 설치하면 역시 먹통이 된다.
이 코드는 참조를 위해 브랜치를 따로 따기로 한다.
70번 핸들러를 사용하고도 문제가 안 생기는 방법을 찾았다.
70번 핸들러 발동시 바로 End of Interrupt부터 날려놓고 시작하면, 핸들러 구동중 CD에 접근하더라도 문제가 발생하지 않는다.
이를 여러 곳에서 테스트할 예정이다.
테스트를 잠정 완료하였다.
DOSBOX 성공 DOSBOX + VIDE-CDD.SYS 성공 86Box 성공 실기기 성공
이 이슈를 완료처리한다.
문제의 원인 및 해결방식을 간략히 설명한다.
IRQ에 의해 동작하는 이른바 하드웨어 인터럽트 콜백들(틱, RTC 등 포함)은 모두 IBM의 PIC 장치(Programmable Interrupt Controller)에 의해 발행된다. 이 PIC들은 한번에 하나의 하드웨어 인터럽트를 발행하는데, PIC의 0x20 (Primary), 0xA0(Secondary) 포트에 0x20(End of Interrupt)를 전달하지 않는 동안에는 PIC의 하드웨어 인터럽트가 더 이상 발행되지 않는다. 따라서 PIC를 통해 발행된 하드웨어 인터럽트들은 반드시 빠르게 0x20, 0xA0에 0x20값을 전달하여 원활한 하드웨어 인터럽트 발행이 될 수 있도록 해 주어야 한다.
IRQ 0 번에 설정되어 PIC가 발행하는 하드웨어 틱 인터럽트(Int 8h)의 BIOS 기본 핸들러는 여러가지 일을 수행하는데, 그 중 하나가 BIOS의 0040:006C (일반주소 0x46C)에 있는 Tick Counter를 증가시키는 것이다. OAKCDROM이나 VIDE-CDD등의 도스 드라이버들은 CD장치에 명령을 전달한 후, 이 Tick Counter의 증감을 관찰하여 CD장치의 타임아웃(먹통여부)를 체크한다. 이 때 이 카운터가 증가하지 않으면 도스 드라이버가 무한루프에 빠지는 문제가 발생한다.
기존 이슈에서 먹통이 발생한 원인: 우리가 Tick 인터럽트에서 CD 장치에 접근하면, Tick 인터럽트가 막혀있는 상태에서 CD 장치에 접근하기 때문에 0x46C의 값을 올려줄 프로세스가 잠겨버려서 무한루프를 도는 것이다.
70번 RTC 하드웨어 인터럽트는 기본적으로는 Tick 인터럽트와 관계없으나, 70번 역시 PIC를 통해 올라오는 하드웨어 인터럽트이기 때문에 PIC를 클리어해주지 않으면 Tick 인터럽트도 영향을 받게 된다.
따라서 70번 인터럽트 수신시 OwnFMDRV의 정상 동작을 위해서는, 70번 인터럽트 핸들러 내에서 CD장치에 접근하기 전에 먼저 Primary와 Secondary에 0x20(EOI)을 전달하여 Tick 인터럽트가 정상동작하도록 만들어주고 CD 장치에 접근하여야 한다.
개요
FMDRV.COM들 중 가장 오래된 버전인 1991년 버전을 사용하는 게임들의 CD 음악 반복 연주가 되지 않는 현상
대상 게임
공통점
상세한 문제 설명
현재 OwnFMDRV는 타이머 인터럽트에서 노래를 재생할 수 없는 제약을 안고 있기 때문에, 지금 구현은 FMDRV로 들어오는 66h / AH = F0또는F1 인터럽트에 의존하여 반복 연주를 진행하고 있다.
그러나 91년 버전 FMDRV.COM은 66h/ AH=F0/F1 인터럽트가 존재하지 않고, 66h/ AX=0401 을 보내고 나면 게임 측에서 FMDRV로 아무런 신호도 보내주지 않는다.
이로 인해 노래가 종료되었음을 알았어도 이를 다시 재생해줄 방법이 없다.
OwnFMDRV는 본 게임이 CPU 제어권을 주지 않으면 직접 CPU제어권을 얻어서 CD장치 제어를 할 수 없기 때문이다.
이를 극복하기 위한 방안을 모색한다.