Just a Blog

MSX 실기와 OCM 클론에서 BASIC 프로그램 구문의 실행 결과 차이 발생 본문

IT, Computer

MSX 실기와 OCM 클론에서 BASIC 프로그램 구문의 실행 결과 차이 발생

wehong 2022. 8. 21. 16:55

*(이후 추가 분석 내용의 글은 여기에 있음)

 

 

얼마전 모 커뮤니티에서 MSX BASIC 프로그램(게임)이 실린 적이 있다. 예전에 프로그램 잡지에 공개되었던 코드였다. 당시 MSX가 없어 잡지를 보고 MSX BASIC 프로그램을 타이핑 한 경험은 없지만(대신 잡지에 실린 Apple II의 기계어 코드를 열심히 입력했던 추억(?)은 있다), 호기심이 생겨서 MSX 기기에서 입력해서 실행해 보고 싶은 마음이 생겼다.

프로그램 코드를 직접 입력하거나 커뮤니티에서 다운 받는 방법 모두 현재 컴퓨터에서 하는 것이 편리하므로, MSX 실기에서 직접 입력하는 것 보다는 PC에서 입력하고 OCM 클론으로 전송하는 방법이 편하겠다고 생각했다. 그래서 MiSTer의 MSX 코어에서 BASIC 코드 실행을 가장 먼저 시도해 보았다.

 

입력한 .BAS 파일을 VHD 파일 안에 복사하고 MSX 코어에서 BASIC을 실행했는데, 에러가 발생한 것은 아니지만 프로그램의 동작이 이상했다. 프로그램의 캐릭터가 계속 다른 방향으로 움직였던 것이다. 그래서 BASIC 코드 타이핑이 잘못된 것이거나 오리지널 프로그램 로직에 문제가 있는 것이 아닌가 의심했다.

 

그런데 프로그램 코드가 공유된 커뮤니티에서 문제를 얘기하는 사람이 없었고 오히려 잘 실행되는 화면이 게시가 되었다. 의아한 마음에 에뮬레이터 openMSX에서 해당 코드를 입력하고 실행해 보았다. 그런데 거기에서는 정상적으로 동작했다!

 

도대체 무슨 문제인지 궁금해서 코드를 살펴보았다. 잘 모르던 MSX BASIC의 기본적인 사항을 숙지하고 여러가지 방향으로 추적해 본 결과, MiSTer MSX 코어의 BASIC에서 'ON SPRITE GOSUB' 구문이 다르게 동작한다는 것을 확인할 수 있었다.

상황을 상세히 설명하면 다음과 같다. 'ON SPRITE GOSUB' 구문은 'SPRITE ON' 구문이 실행된 후 스프라이트 간에 겹치는 충돌(collision)이 발생하면 지정된 실행라인으로 분기를 실행하고 'RETURN' 구문으로 돌아오는 일종의 인터럽트 서비스 루틴을 지정하는 것이다. 실기 또는 에뮬레이터에서는 'SPRITE ON' 구문 후 스프라이트 간에 겹쳐짐이 발생할 때만 'ON SPRITE GOSUB' 분기문으로 들어가 정상적으로 처리되었는데, OCM 클론에서는 'SPRITE ON' 구문만 있으면 스프라이트 겹쳐짐과 관계없이 계속 'ON SPRITE GOSUB' 분기문이 실행되는 것이다. 이상현상이 발생한 대상을 MiSTer MSX 코어만이 아니라 OCM 클론이라고 칭한 이유는 'IQ 3000 큐티'에서도 동일한 현상이 발생했기 때문이다.

 

실기에서 해당 프로그램을 직접 입력하기는 버거워서 다른 예제를 사용해 확인해 봤다. 사용한 코드는 다음과 같이 'msx.org'의 'COLOR_SPRITE()' 설명란에 나오는 예시(example) 중 하나이다.

10 SCREEN5
15 ON SPRITE GOSUB 90: SPRITE ON
20 SPRITE$(0)=STRING$(8,255)
30 COLOR SPRITE(1)=38
40 PUTSPRITE 0,(50,50),10,0
50 PUTSPRITE 1,(54,54),,0
60 IF NOT STRIG(0) GOTO 60
70 COLOR SPRITE(1)=79
80 GOTO 80
90 SCREEN 0: PRINT"Sprite collision OK": BEEP: END

 

'X-II' 실기에서 다음의 코드를 입력하여 실행하면, 먼저 노란색/빨간색의 사각형이 나오고 스페이스바를 누르면 하얀색 사각형이 나온다(예상에는 스페이스바를 누르면 스프라이트 겹쳐짐이 생겨 'Sprite collisoin OK'를 찍고 소리를 낸 뒤 끝날 줄 알았는데 그렇지는 않았다). 이 현상은 에뮬레이터(여러 머신)에서도 동일했다. 결과적으로 'ON SPRITE GOSUB' 구문에 의한 90번으로의 분기는 발생하지 않은 것이다.

 

반면에 MiSTer MSX 코어에서 코드를 입력하고 실행하면, 그냥 'Sprite collision OK' 구문 및 소리와 함께 종료된다. 스페이스바를 입력하기도 전에 'SPRITE ON' 이후 바로 스프라이트 충돌이라고 판단하고 그냥 'ON SPRITE GOSUB' 구문에 의해 90번으로 분기해 버리는 것이다.

(업데이트: 신규 OCM BIOS를 통한 SD 이미지 재생성으로 문제 해결: 관련 글)

 

MiSTer MSX 코어 BASIC에서 코드 중 'SPRITE ON'을 'SPRITE OFF'로 바꾸면, 'ON SPRITE GOSUB' 분기가 일어나지 않으면서 사각형 도형이 보인다. 그런데 스페이바를 누르면 실기와 에뮬레이터와 다르게 흰 사각형이 정사각형으로 정확하게 보인다. 스프라이트가 잘리지 않은 이쪽이 실기쪽 결과보다 더 맞는 것 같은데, 아무튼 실기와 OCM 클론(MiSTer MSX 코어)의 결과가 이것도 다르다.

 

일단 OCM 클론에서 스프라이트 정보가 있고 'SPRITE ON' 구문이 실행되면 스프라이트의 충돌 여부와 관계없이 'ON SPRITE GOSUB'에 지정된 분기가 무조건 일어나는 것으로 보인다. 그것이 'ON SPRITE GOSUB' 및 'SPRITE ON' 처리 자체의 문제인지 SPRITE 관련 메모리의 오류 문제인지 OCM 클론 내 VDP 구현의 문제인지는 잘 모르겠다.

 

이런 현상의 원인을 두고 여러가지 가정과 생각을 해 보게 되었다. 'CPLD/FPGA 기반 OCM 클론들이 MSX 규격을 정확하게 모사하지 못하는가?', 'Disk BASIC 2.0(OCM 클론 사용)이 Disk BASIC 1.0(실기 및 에뮬레이터 사용)와 다르게 동작하는 것인가?', 'OCM 클론의 VDP 및 Video RAM 동작이 비정상적으로 구현되어 있는 것인가?', 'OCM 설정에 잘못이 있는 것인가?' 등의 생각들이 머리 속에 맴돌았다. 그 해답들은 아직 모르겠다.

 

BASIC 프로그램이 아닌 경우에도 이런 차이가 있다면, 특히 카트리지 롬이나 디스크 프로그램이 실기와 다르게 동작한다면 이미 여러가지 말들이 나왔을 것이라 생각한다. 그렇다면 OCM 및 클론 사용자들이 BASIC 프로그래밍을 하지 않는 것인지도 모르겠다.

 

개인적으로 OCM 클론에 대한 신뢰가 많이 무너졌다. 하드웨어적 구현의 충실도를 떠나 실행 결과가 실기와 다르기에 그렇다. 물론 이러한 판단이 마치 현대에 Java 프로그램 구동 결과의 차이를 JVM이 아닌 OS에 묻는 것 같이 레벨에 안 맞을 수도 있겠지만, OCM 클론들은 롬 바이오스, MSX-DOS 등과 한 패키지이므로 연대 책임(?)을 져야 한다고 본다.

Comments