2026년 10월 15일 목요일

21세기 DOS 프로그래밍 #5 - HV 한글 뷰어

그래픽 라이브러리는 인터레이스 모드에서 쓸 수 있도록 만들었습니다.

참고로, 인터레이스 관련된 기능은 BASIC에 구현이 안되어 있는데요.

이게 VDP의 인터레이스 출력은 단순히 두개의 VRAM 페이지를 홀짝 필드에 맞춰 전환하는 기능뿐이거든요.

따라서 VDP 커맨드도 인터레이스 출력과는 무관하게 VRAM에서만 동작합니다.

결국 소프트로 다 처리해야한다는 얘기죠.


사실 80,90년대에는 인터레이스 모드를 쓸 생각을 전혀 안했습니다.

2000년대 들어서니, 대부분의 TV/모니터에 디인터레이서가 탑재되고, 100Hz/120Hz 같은 기능도 들어갔죠.

이제는 GT에서 CALL KANJI2 등의 인터레이스 모드를 써도 깔끔하게 볼 수 있습니다.

480i를 활용해도 좋은 시절이 되었습니다요~ ㅎ.ㅎ


인터레이스 테스트용으로 한글 문서를 볼 수 있는 프로그램을 만들게 되었구요. 이름이 HV입니다.

한글 폰트는 844 조합형을 내장했습니다. 용량이 작으니까 부담이 없죠.

문제는 KS C 5601 전체를 지원하려면, 특수문자 37KB, 한자 153KB를 로딩하는 부담이 있었네요.


결국, HV는 아스키, 한글폰트만 내장하도록 했습니다.

대신 특수 문자와 한자 폰트가 메모리로 로딩되어 있으면 활용 할 수 있도록 구성했죠.

폰트는 메모리매퍼의 시스템 세그먼트로 로딩해서 계속 램상주가 되니,

다른 프로그램에서도 활용할 수 있는데요. M 파일매니저에서도 이용하고 있습니다 ㅎ.ㅎ


예전에 이걸 공개했을 때에도 관심을 보인 분이 1명도 없어서, 폰트 인터페이스는 따로 오픈안했어요ㅋ

지금은 폰트팩이 있으니 따로 로딩할 필요도 없어졌구요. SLT-Turbo는 폰트팩 V2가 내장이라~ ㅎ.ㅎ


암튼, 램상주 폰트는 아래 링크를 참고하세요.

순정 GT에 로딩하면 메인램 절반이 날아가는 마법! ㅎ.ㅎ


특수문자 폰트는 메모리매퍼 64KB를 점유합니다.

https://sharksym.blogspot.com/2014/10/ksspe-v10-ks5601.html


한자 폰트는 메모리매퍼 160KB를 점유합니다.

https://sharksym.blogspot.com/2014/10/kshanja-v10-ks5601.html


현재 HV는 폰트팩이 있으면, 해당 폰트를 우선으로 사용하구요.

폰트팩이 없으면 프로그램 내장 한글과 램상주 폰트(특수문자, 한자)를 사용합니다.

UTF-16 유니코드도 지원하니까, 예전 윈도에서 쓰이던 유니코드 문서를 활용할 때도 좋습니다.


아래는 최신 버전의 HV입니다.

https://sharksym.blogspot.com/2022/01/hv-v16-hangul-viewer-for-msx-dos2.html


그럼, 다음 편에서 이어집니다요~


2026년 10월 14일 수요일

21세기 DOS 프로그래밍 #4 - IMS 플레이어

이번 글 부터는 제가 만들었던 프로그램들과 그에 관련된 툴, 라이브러리 설명을 붙여보겠습니다.

대략 시간순으로 등장한다고 보시면 맞습니다~ ㅎ.ㅎ


그럼, 'IMS 플레이어'부터 시작합니다.


IMS 파일 아시죠? PC의 애드립, 사운드블라스터에서 OPL2를 이용한 음악파일인데요.

이걸 MSX-DOS2에서 연주해주는 프로그램을 만들어봤습니다.


기본적으로 MoonSound를 위해 만든 플레이어지만, OPLL만으로도 플레이 가능합니다.

BNK로 쓰이는 악기 이름과 비슷한 OPLL 내장 악기를 선택해주는 방식입니다.


이 프로그램은 메모리매퍼를 활용하는 가장 기본적인 프로그램입니다.

OPL4, OPLL을 위한 플레이어 루틴이 서로 다른 뱅크에 배치되어있습니다.

플레이 시, 어차피 하나의 칩만 사용할테니까 모든 코드를 하나의 뱅크에 넣으면 뱅크 용량만 커지겠죠?


일반적인 IMS 파일은 32KB ~ 128KB 정도입니다.

이 IMS 파일을 한번에 로딩하기 위해 메모리매퍼 세그먼트를 동적으로 할당하여 사용합니다.


만약 제가 90년대에 아이큐2000용으로 플레이어를 만들었다면?

아마 IMS 데이터를 VRAM에 로딩하는 방식을 썼을 것 같네요.

이제는 넉넉한 메모리로 편하게 프로그래밍을 할 수 있습니다. 역시 목마른 사람이 우물을 파는 게 좋아요.

그리고, turboR의 고속모드를 활용하려면 적극적으로 내장 메모리을 이용해야합니다!


아래는 IMSP 초기버전의 동작영상이니 구경하셔요~ ㅎ.ㅎ



아시다시피, M 파일매니저에 OPL4 전용의 IMSP 기능이 내장되어 있어서, 이젠 저도 안쓰는 프로그램이 됐지만...

만약 OPL4 사운드 카드가 없으시면 OPLL도 지원되니, 한번 트라이해보세요 ㅎ.ㅎ

아래 페이지에서 다운받을 수 있습니다.

https://sharksym.blogspot.com/2019/04/imsp-v06-ims-player-for-msx-dos2-2019.html




그럼, 다음 편에서 이어집니다요~


2026년 10월 12일 월요일

21세기 DOS 프로그래밍 #3 - DOS2 뱅킹

디스크롬의 뱅킹을 얘기하려는 것은 아니구요.

확장 BIOS로 지원되는 메모리매퍼의 뱅킹 이야기입니다~


메모리매퍼 세그먼트는 16KB입니다.

저의 프로그램에서 원하는 뱅킹은 Page 0,1의 32KB 영역입니다.


프로그래밍을 안해보셨으면 text, data, bss 등의 단어가 생소하실 수도 있는데요.

대충 보고 넘어가셔도 괜찮습니다요 ㅎ.ㅎ


메모리맵은 이런식으로 구성됩니다.

0000H ~ 00FFH = DOS2 Zero page

0100H ~ 7FFFH = text + data + bss + local heap

8000H ~ 93FFH = Mapper table, Banking stack, ISR 등의 Helper area

9400H ~ FFFFH = global var. + global bss + global heap + WORKAREA


전역변수(global var.)는 MAP파일에서는 comm으로 표시됩니다.

여러 뱅크에서 공통으로 접근하는 변수들을 쓸 때 필요합니다.


뱅킹 영역(0000H ~ 7FFFH)은 시스템 메모리매퍼 세그먼트 2개를 묶어서 사용합니다.

메모리매퍼 최대용량(4080KB)에서 127개의 뱅크를 사용할 수 있습니다.


프로그램 내에서 사용되는 뱅크번호는 논리(logical) 세그먼트가 되겠구요.

프로그램 로더는 필요한 용량만큼 실제 세그먼트를 할당 받아서 논리 뱅크와 연결합니다.

로더는 뱅크 0번으로 고정되고 실행파일(*.COM)으로 빌드됩니다.

나머지 뱅크들은 빌드 후 하나의 파일(*.OVL)로 묶여집니다.


malloc() 등의 heap을 사용하는 경우는 뱅킹 영역의 local heap이 사용됩니다.

bl_malloc() 등의 함수를 쓰면 global heap을 할당 받을 수 있습니다.

여러 뱅크에서 전역으로 접근이 필요한 경우에 쓰면 됩니다.


유저 ISR 루틴도 뱅킹이 지원됩니다.

따라서 외부 인터럽트, VDP H-Blank, V-Blank 등의 루틴을 여러 뱅크에 나눠 놓을 수 있어요.


뱅킹과 상관없이 매퍼 세그먼트를 이용하여, 대용량의 메모리를 할당할 수 있습니다.

bl_lmem_alloc() 등의 함수로 이루어져있습니다.

큰 데이터를 한번에 로딩할 때 쓰면 되겠습니다. (예: IMS 플레이어 등)


그 외,

시스템의 세그먼트가 부족한 경우는 특정 뱅크를 동적으로 로딩할 수도 있습니다.

설계 초기에는 디스크의 스왑파일(*.SWP)로 가상 메모리를 쓰는 것도 고려했는데,

거북이 MSX를 달팽이 속도로 만들 이유는 없어서, 가상 메모리는 제외되었어요 ㅎ.ㅎ


HI-TECH C 자체는 일반 CP/M의 TPA(64KB) 영역만 쓰는 프로그램만 컴파일이 가능합니다.

이걸 소스 파일을 뱅크로 나눠서 빌드 후 뱅킹 함수로 연결 하거나,

전역 변수를 처리 등의 부가 작업은 별도의 툴을 제작해서 썼습니다.


전체 툴체인은 로컬 git으로만 작업 후 릴리스 파일만 파라동 자료실에 올렸었는데요.

나중에는 귀찮아서 github에 그대로 올려버렸습니다. 흐...

아마 살짝 써보신 분들도 계실 듯요. 아래 링크는 참고만 하셔요 ㅎ.ㅎ

https://github.com/sharksym/CPMEMU_HI-TECH_C


그럼, 다음 편에서 이어집니다요~