레이블이 HI-TECH C인 게시물을 표시합니다. 모든 게시물 표시
레이블이 HI-TECH C인 게시물을 표시합니다. 모든 게시물 표시

2024년 6월 12일 수요일

HI-TECH C v3.09 - Win32 Recompiled version test

모두(?)가 아시는 그 하이테크 C 컴파일러의 Win32 버전이 나왔습니다.

무슨 개소리냐구요? ㅎ.ㅎ


.

.

.


제가 20년 전에 처음 HI-TECH C를 쓸 때는 MSX 에뮬(paraMSX)을 이용했었습니다.

뭐, turboR 실기에서도 소스 컴파일을 할 수 있습니다만...

당시 GT + MMC/SD 조합으로도 긴~긴~ 빌드 타임을 기다리는 건 무리였죠ㅋ


암튼 그렇게 쓰다가, 2008년 부터는 성능이 괜찮은 윈도용 CP/M 에뮬을 발견해서 지금까지 활용했습니다.

커맨드 프롬프트에서 직접 실행 할 수 있어야, MAKE 등의 기타 툴을 활용하기 좋으니까요.

참고로 CP/M 에뮬은 일본 아자씨가 만든 CP/M EXEcutor입니다.


그러다가 개인 프로젝트의 소스가 점점 커지고 윈도에서도 작업 효율이 점점 안좋아졌는데요.

시간이 지나면 PC 성능도 함께 올라가니까 그럭저럭 에뮬로 버틸만 했습니다요.


시간은 흘러~ 1년, 5년, 10년, 15년...

어느날(며칠 전) HI-TECH C가 디컴파일이 되었다는 소식을 듣게 되었습니다 ㅎ.ㅎ


원래 HI-TECH C CP/M 버전은 ANSI C를 지원하는 상용 컴파일러입니다.

근데 20년 전에 제작사가 사후지원을 종료하면서, 프로그램을 공개(free)로 풀어버렸죠.

저도 옵티마이저, 뱅킹 툴 등을 만들고 짜깁기해서 지금껏 잘 쓰고 있는데요.


최근 이 CP/M용 실행파일을 디컴파일해서 활용가능한 수준의 C 소스로 만든 분이 나왔더라구요.

대충 히스토리를 보니...


먼저 CPP, P1, CGEN, ZAS, LINK 등의 기본 컴파일러, 어셈블러가 만들어졌구요.

https://github.com/nikitinprior?tab=repositories


다른분이 LIBR(라이브러리안)을 추가하고, 소스를 모두 묶어서 빌드할 수 있게 만들어놨네요.

https://github.com/ogdenpm/hitech


오~~ 필요한 거 다 있네요? ㄷㄷㄷ

궁금해서 바로 받아서 빌드해봤습니다 ㅎ.ㅎ

참고로, 최종 커밋은 지난 5월 31일에 들어갔네요.

https://github.com/ogdenpm/hitech/commit/6c762963ce7ab16fef74b7551588411abbc6e69a



간단한 Hello World 프로그램을 컴파일해서 비교해보니, 출력물이 오리지널과 똑같습니다. 굿굿!!


모든 툴이 진짜 다 괜찮은지 확인하려면, 큰 소스를 빌드해보는 방법뿐이겠죠?

M 파일매니저를 빌드해봅시다!


먼저, CP/M 에뮬을 쓰는 MAKEFILE을 뜯어고쳐서 Win32 리컴파일 버전을 쓰도록 수정했습니다.

참고로 CP/M은 서브디렉토리 개념이 없어서, 편하게 쓰려면 Tool, LIB, Source 등을 모두 개별 드라이브로 분리해야하는데요.

다행하게도 CP/M EXEcutor는 윈도의 폴더를 에뮬의 드라이브로 매핑해주는 기능이 있습니다.

그래서 제가 쓰는 툴들은 가상의 드라이브(A: B: C: D:)를 쓰도록 환경을 구성했었죠.


Win32 리컴파일 버전은 파일명에 디렉토리 패쓰를 쓸 수 있고, 긴파일명도 당근 지원됩니다.

M 파일매니저를 빌드해보니, 출력물은 거의 똑같네요.

바이너리에서 차이나는 부분은 사실 CP/M의 레코드 사이즈(128 바이트)로 인한 거였구요.

실제 동작하는 영역은 똑같았습니다. 완벽하네요!! ㅎ.ㅎb


아래의 M.COM 실행파일(멀티뱅크 로더)를 비교해보면, 끝부분의 dummy 영역만 차이가 나는 것을 볼 수 있습니다.




아래는 긴파일명(LFN)을 테스트해 본 모습입니다.

MPXFW.C였던 파일명을 길게~~ 30글자 넘게 만들어도 잘 컴파일됩니다.



링커의 MAP파일에서도 아래처럼 정상적으로 표시됩니다.

라이브러리도 디렉토리 패쓰를 지정할 수 있어서 좋아요.



아래는 MAP파일에서 조금 동작이 달랐던 부분인데요.

같은 오브젝트 내의 심볼을 이름으로 정렬하느냐, 주소로 정렬하느냐 정도의 차이였습니다.

어차피 사람이 인식하는데엔 별 문제없는 수준입니다요 ㅎ.ㅎ




그리고, 가장 중요한 빌드 타임을 비교해보아요~


CP/M 에뮬 + Z80 바이너리 VS Win32 네이티브 프로그램

얼마나 빨라졌을까 궁금하시죠? ㅎ.ㅎ


# M 파일매니저 빌드

CP/M 에뮬 조합 환경 -> 약 55초

Win32 리컴파일 버전 -> 약 16초


# C LIB x 8개 빌드

CP/M 에뮬 조합 환경 -> 약 10분

Win32 리컴파일 버전 -> 약 1분 15초


속도가 많이~많이~ 빨라졌네요!

참고로, C 라이브러리는 멀티코어로 8개 동시에 빌드한 상태였습니다.

이거 순차적으로 빌드하면 1시간 걸립니다요. (아마 MSX로 빌드하면 하루종일ㅋ)

제 PC는 라이젠5 7600입니다. 참고하셔요~



그럼, 이만...


2024년 3월 23일 토요일

PSG 3채널로 BGM과 효과음 공유

PSG 3채널로 BGM과 효과음 공유


아시다시피 PSG에는 3채널(Ch.A, Ch.B, Ch.C)의 출력단이 들어있는데요.

이 3채널만으로 배경음악(BGM)과 효과음을 함께 출력할 때는 보통 2가지 선택지에 놓이게 됩니다.

1) 배경음 2채널, 효과음 1채널 각각 할당

2) 배경음 3채널 기본 사용. 효과음 출력 시 배경음 1채널을 대신 사용


1)은 코나미 게임에서 종종 보이는 형태입니다.

게임 시작할 때는 3채널로 멋지구리하게 음악이 나온 후,

스테이지가 나오고 주인공이 움직이기 시작하면 배경음악은 2채널로 고정되는거죠.

효과음은 따로 1채널을 독점하구요.


BGM 2채널이라 단조롭게 들릴 수는 있지만, 멜로디가 잘 들리니까 뇌리에 팍팍 꽂히는 장점도 있어요 ㅎ.ㅎ



2)는 평소에 3채널로 BGM을 우렁차게(ㅋ) 출력합니다.

만약 효과음 출력이 필요하게 되면, BGM의 채널 1개를 삭제(출력 MUTE)하고 여기에 효과음을 넣게 되는거죠.

보통 BGM의 주 멜로디의 출력은 유지한 상태에서 베이스 또는 드럼 출력 용 채널을 삭제하게 됩니다.

아무래도 멜로디가 끊어지면 좀 어색하니까요 ㅎ.ㅎ


조금 특이한 경우로는 THEXDER가 있는데요.

일단 BGM은 3채널로 출력합니다.

여기서 효과음이 추가되면, BGM 채널 한개를 그냥 삭제하는 것이 아니라, BGM 채널 2개를 교대로 삭제하더라구요.

효과음를 PSG의 Ch.B, Ch.C으로 빠르게 전환하면서 출력합니다.

결국 해당 채널의 BGM도 빠르게 끊어졌다 출력했다 반복되겠죠.

실제로 들어보면 BGM이 살짝 끊어지듯 들리지만, 채널이 완전히 사라지는 게 아니라서 배경 음악이 대충 들립니다 ㅎ.ㅎ


참고로, 제가 예전 만든 그래픽/사운드 데모용 프로그램(테트리스)에서는.

BGM의 베이스 라인과 효과음이 하나의 채널(Ch.C)을 공유해서 출력합니다.

아래는 2016년에 찍은 영상인데, 심심하시면 구경하셔요 ㅎ.ㅎ



.

.

.


사실 이 글을 쓰게 된 이유가....

최근 토시탈드님이 공유해주신 남코의 사운드 관련 인터뷰 내용 때문이었습니다요~


BGM과 효과음이 PSG 채널을 공유해야 한다면 어떻게 해야될까?

저는 BGM의 멜로디가 사라지면 동시(BGM + 효과음)출력의 의미가 없지않을까? 싶었거든요.

뭐, 지극히 공돌이의 마인드라고 볼 수 있겠네요ㅋㅋ


근데 남코의 인터뷰를 보면 아래의 내용이 나옵니다. (한글 번역기의 출력이라 조금 어색할 수 있어요.)


나카가타:「효과음에 몇 음 사용할 수 있어」라고 하는 이야기도 하고 있었지요. 나는 SE(효과음)에 채널이 먹히는 경우는 항상 BGM은 베이스와 드럼(리듬)이 남는 조립으로 하고 있었습니다.


오자와: 그것도 스스로 결정 되었습니다. BGM 안의 어느 소리를 지워 효과음을 태울 수 있을까 하는 것도 사운드 크리에이터 측에서 조립하고 있었습니다.


케이노: 항상 퍼즐처럼…


오쿠보 : (케이노 씨가 다룬) '팩랜드'에서는 효과음에 따라 멜로디와 채널이 쓰여 있고, 효과음이 울릴 때에는 BGM이 베이스와 리듬대만이 되는군요. 효과음이 울리고 끝나면 멜로디의 소리가 곧바로 복귀하고 울리기 시작할 때는 MIDI 제어로는 할 수 없는 사양이므로, 인터랙티브에 특화한 게임만이 가능한 사운드 시스템이 인상적이었고, 그것을 엄청 잘 사용하고 있었습니다 그래.


케이노 : 비행기가 나오고 호퍼가 나와서… 에서 하고, 물건에 따라서는 BGM의 멜로디 라인을 마스킹하고 있었습니다.


오자와:플레이 스테이션 이후(CD로부터의 스트리밍 재생을 할 수 있게 됨) BGM이 사라지지 않고 울리게 되고 나서도, 「일부와 멜로디를 지운다」라고 하는 연출상의 효과는 사용하고 싶었네요.


케이노: 음소거(=무음)하는 것으로 소리가 서, 소리가 빛난다고 하는 것이 있기 때문에.


나카가타: 정말 그렇네요.


오자와: 지울 때 어떤 것을 깎는지에 따라 연출이 바뀌기 때문에…



요약하면, 효과음 출력 시 채널이 부족하면 BGM의 멜로디를 지운다는거죠.

저의 생각 -> BGM과 효과음을 어울리게 출력한다 -> 베이스/드럼 삭제하고 효과음을 출력

남코 생각 -> 효과음이 더 잘 들리도록 BGM의 멜로디를 삭제하고 베이스/드럼을 살린다 -> 멜로디를 지우는 것도 연출


재밌는 인터뷰였습니다 ㅎ.ㅎ


그럼, 즐거운 주말되세요~


2020년 7월 21일 화요일

GitHub 계정에 'Arctic Code Vault Contributor' 배지 획득

제 GitHub의 메인 화면에 이런 알림이 하나 뜨더라구요.


https://github.com/sharksym






구글링해보니, GitHub 블로그에 내용이 나오네요! ㅎ.ㅎ

GitHub Archive Program에 관련된 것이군요.


https://github.blog/2020-07-16-github-archive-program-the-journey-of-the-worlds-open-source-code-to-the-arctic/






암튼 제가 올린 코드들은 북극 저장소로 들어갔네요ㅋ


그럼, 즐거운 하루 되세요!


2016년 12월 17일 토요일

HI-TECH C 용 BGM 라이브러리 만들기 #4 - FM 지원

기존 BGM 루틴에 FM 사운드도 추가하였습니다.

여기서 FM은 MSX-MUSIC(YM2413-OPLL) 칩을 의미합니다요.

왠만한 후기형 MSX2/2+에는 MSX-MUSIC이 내장되어있어요.

물론 turbo R에서도 지원되구요.


MSX-MUSIC은 두가지 동작 모드가 있어요. 멜로디/리듬 모드인데요.

멜로디 모드는 9채널 모두 멜로디 악기로 동작하는 모드이고,

리듬 모드는 마지막 3채널(7,8,9번)을 리듬 악기(5가지)로 구동하는 모드입니다.


아마 20여년전에 BASIC으로 구동해보셨던 분 많으시죠? ㅎ.ㅎ

이제 C로 한번 해보셔요~ㅋㅋ


그리고 라이브러리 내에서 CPU 모드를 체크해서, 칩 액세스 타이밍을 적절하게 세팅합니다.

Z80 일반모드, R800 고속모드 상관없이 자동으로 처리되니까 참고하세요.



그럼, 이쯤에서 1편에서 나왔던 요구사항을 점검해봅니다.


1. 배경음악 재생

2. 효과음 등의 사운드 믹스

3. PSG 구동

4. OPLL 구동

5. MML 사용


오홍~ 대충 완성이군요. ㅎ.ㅎ

유X군님께, 올 연말까지 라이브러리 정리해드리기로 약속했는데...

미션 성공이네요. 만세~!



백문이불여일견! 소리를 들어보겠습니다요! (쓰고보니 반대네요~. 백견이불여일문? ㅋ)

듣기전에 기존 테트리스 프로그램의 PSG, FM 채널 설정부분의 코드를 잠깐 보시지요.




BGM 채널 0,1,2는 PSG로 출력이 되구요.

채널 3,4,...,11은 FM으로 출력이 됩니다.


만약 FM 리듬모드를 켜면,

채널 3,4,...,8는 FM 멜로디 출력

채널 9는 FM 리듬 출력으로 처리됩니다.



그럼, 동작 영상 나갑니다~

PSG/FM 테스트 프로그램과 테트리스 구동 모습입니다.





그럼, 즐거운 주말되세요!


2016년 12월 9일 금요일

HI-TECH C 용 BGM 라이브러리 만들기 #3 - 소리가 나는 테트리스?

2011년이니까 5년전이군요.

그래픽 라이브러리 데모용으로 테트리스를 만들었는데요.

아마 기억하시는 분 계시리라 생각됩니다. ㅋ




드디어! 조용한 테트리스 게임에 소리를 넣을 수 있게 되었습니다~ 오예~

무려 5년이 흘렀지만요 ㅋ


음악을 넣으려고 구글에서 악보 검색을 하다보니, 문득 생각이 나더라구요.

워낙 유명한 게임인데, 이거 MML로 만든사람 있지않을까?


역시나, 검색하니 딱 나오네요. ㅎ.ㅎb

감사히 쓰겠습니다~ 




C 코드로 복사해서 넣고 돌렸어요. 음~ 소리 잘나오네요!




배경음악만 있으면 심심하니까, 효과음도 몇개 넣어봅니다.

블럭 이동/회전/낙하/라인삭제, 4가지 효과음을 넣었습니다.

저의 실력으로는 이정도가 한계군요. ㅎ.ㅎ




전체 소스는 github에서 받으시면 되겠구요.

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


게임만 구동해보실 분은 첨부파일 받으시면 되겠습니다

Download: TETRIS_20161209.zip



그럼 돌아가는 모습을 한번 볼까요?

모니터가 밝아서 그런지, 폰 영상이 춤을 추는군요! ㅋ





그럼, 즐거운 밤되셔요~


2016년 12월 6일 화요일

HI-TECH C 용 BGM 라이브러리 만들기 #2 - 소리가 날까?

MML이 뭔지 아시죠?

Music Macro Language 인데요. 음악을 표현하는 언어(?) 정도로 생각하시면 되겠습니다.

BASIC의 PLAY 명령에서 사용되는 문법이 대표적인 MML이라고 보시면 되겠습니다.


더 궁금하시면 wiki 문서를 찾아보셔요~ ㅎ.ㅎ

https://en.wikipedia.org/wiki/Music_Macro_Language


아래는 MSX-MUSIC BASIC 매뉴얼에 나오는 샘플곡입니다.

채널 2개로 출력하는 프로그램이네요.




OPLL 악기 설정만 빼면, 일반 PSG용 MML과 같은 구조로 되어있습니다.

요걸 C 코드로 옮기면 아래처럼 됩니다.




BASIC 코드와 C 코드의 MML 문자열이 똑같은걸 볼수가 있지요?

"BASIC에서 PLAY 코딩하던 것처럼 배경음악을 만들 수 있다"를 기억하시면 되겠습니다~


xxx_enqueue()가 모두 끝나면, xxx_play()로 배경음악을 시작하고 xxx_stop()으로 멈출 수 있습니다.

음악이 재생완료되었는지는, xxx_get_stat() 함수로 상태확인이 가능합니다.


위의 코드에서는 음악 연주를 가만히 기다리고 있으면 심심하니까,

놀고있는 PSG 채널로 짧은 효과음을 출력해봅니다.

shot() 함수는 아래처럼 구현되어있습니다.




총알소리에 쓰인 MML에 Z 명령어가 보이시죠?

요건 BASIC MML에서는 없던건데, PSG 노이즈 주파수 설정하는 용도로 사용됩니다.

참고하셔요.


실행하면 아래처럼 현재 버퍼 상태를 확인할 수 있구요.

스페이스 키 누르면 총소리가 나게됩니다~ ㅎ.ㅎ

PSG 두개 채널은 배경음악 용, 나머지 한개 채널은 총소리 출력으로 사용됩니다.




그럼 이번엔 3채널 모두 사용하는 BGM을 연주해봅니다.

베토벤 할아버지께서 작곡하신 "환희의 송가"가 되겠습니다요~




3개 채널이 모두 사용되니까, 스페이스 눌러서 총소리를 출력하게 되면,

PSG 마지막 채널은 배경음악과 총소리로 번갈아서 출력됩니다.

일단 설명만 드리고 넘어갑니다.

이 글 마지막에 동영상이 있으니까 그걸로 확인하셔요! ㅎ.ㅎ



라이브러리가 어떻게 사용되는지 대충 아시겠죠?


마지막으로 MML 데이터를 연속으로 enqueue()해서, 배경음악을 무한으로 연주해봅시다~

코드는 아래처럼 만들었습니다.

템포 240으로 "학교종이 땡땡땡~"을 연주해보았어요 ㅋㅋ




처음 enqueue()를 한번 해주고 play() 시작합니다.

그 후, 버퍼에 여유가 있으면 계속 데이터를 enqueue()합니다.

ESC 누르면 종료하도록 해주고요. 간단하죠? ㅎ.ㅎㅋ



그럼, 실제 동작하는 모습을 영상으로 보시겠습니다.

보기전에 약간의 설명들어갑니다 ㅋ

영상에 보시면 아래처럼 나오는데요.

화면의 빨간색 띠는 배경음악 처리에 사용되는 CPU 점유율입니다.

터보알 고속모드랑 Z80 3.58MHz 모드 두번 구동하니까 한번 비교해보셔요~





마지막으로 영상 나갑니다~




그럼, 즐거운 하루 되세요!


HI-TECH C 용 BGM 라이브러리 만들기 #1 - 플레이어 함수

오랜만에 라이브러리를 추가하고 있습니다.


사실 올해초에 만들다가 잠시 쳐박아둔 코드였는데요. (딴짓 하느라 바빠서요~ㅋ)

올해가 넘어가기 전에 PSG 용 BGM 루틴이라도 마무리해야될 것 같아서, 지난 주에는 코딩을 좀 했습니다. ㅎ.ㅎ


암튼, 글을 쓴다는 것도 까먹고 있다가... 대충 완성이 되고나서야 올리는 글이 되었습니다!



대강의 요구사항은 이렇습니다.


1. 배경음악 재생

2. 효과음 등의 사운드 믹스

3. PSG 구동

4. OPLL 구동

5. MML 사용



간단한 게임 프로그램에서 쓸 수 있도록 만드는 것이 목표입니다.

기능이 복잡하게 될 필요는 없고, 배경음악 + 효과음을 쉽게 처리할 수 있는 방식이면 충분합니다.


각 요구사항들을 자세히 만들어 보았습니다.


먼저 1번 배경음악 재생과 5번 MML 사용에 관한 내용입니다.

- 음악 데이터 양이 많은 경우, 동적으로 데이터를 버퍼에 enqueue 할수 있어야 함.

  양이 적은 경우는 몽땅 enqueue 후 반복 재생도 가능해야 함.

- 음악 데이터는 버퍼 enqueue 시점에 일부분 MML 번역을 하여, BGM 코드의 CPU 부담을 줄임

- BASIC MML과 비슷한 문법의 MML 데이터를 사용. (별도의 PSG 트래커 필요없음)


2번 효과음 믹스에 관한 내용입니다.

- 배경음악 및 효과음은 PSG 3채널 모두 활용가능해야함

- 배경음악과 효과음 동시 출력 시, 효과음 우선으로 출력함


3번 PSG 및 4번 OPLL 구동

- PSG only 또는 OPLL only 또는 PSG + OPLL 동시 사용 시나리오 가능해야 함.

- PSG H/W 엔빌롭 대신 S/W 볼륨 방식의 엔빌롭 사용. (실제 악기와 유사한 패턴)

- PSG 노이즈 설정 가능해야함.

- OPLL 내장 보이스 및 사용자 보이스 설정 가능해야 함.



대충 감이 오시지요? ㅎ.ㅎ

PSG만 사용하는 게임들을 살펴보면, 빈약한 3채널만으로도 배경음악과 효과음을 잘 처리하고 있는데요.

그런 게임들처럼 비슷하게 구현할 수 있는 방법으로 만들어갑니다.



그럼, 실제로 코드를 만들어봐야겠네요.


배경음악처럼 메인 코드에 영향받지 않고, 정확한 타이밍으로 출력하려면 인터럽트가 필수겠습니다.

주기적인 인터럽트 처리는 VDP의 V-Blank 인터럽트를 활용하면 되겠죠?

메인 BIOS의 TIMI 훅 사용과 비슷하게 만들어줍니다.


아래는 BLSTDINT.H 파일에 선언된 인터럽트 리스트입니다.




"어... MSX는 Z80 IM 1 모드라서 인터럽트 여러개 처리가 안될텐데요?"

라고 생각하시는 분도 계시겠죠?


제 라이브러리를 예전부터 쓰셨으면 이미 알고 계시겠지만~ ㅎ.ㅎ

모두 S/W 로 구동됩니다.

메인 인터럽트 핸들러는 뱅킹 라이브러리 내에 이미 포함이 되어있구요.

프로그래머가 사용하기 편하도록, 특정 조건에 따라 콜백함수를 호출하는 방식입니다.

(참고로 IRQ 번호는 작은 숫자가 우선순위가 높습니다.)


배경음악 재생을 위해, IRQ_SND_CYCL IRQ가 사용됩니다.

실제로는 VDP V-Blank 주파수에 따라, 60Hz 또는 50Hz 주기로 호출이 되겠습니다.


음... 그러고보니 V-Blank 주기에 따라 배경음악 Tempo를 조절하는 기능도 필요할지 모르겠네요. ㅎ.ㅎ

60Hz/50Hz 바뀔 때, 음악 속도가 영향받지 않으면 좋겠지요?

.

.

하지만 실제로 게임 만들게 되면, V-Blank 주기를 하나로 고정하니까... 별로 의미없을 수도 있어요.

실제로 코나미 게임들을 보면, VDP 신경 안씁니다요~ㅋ

유럽산 MSX에서 게임 구동하면, V-Blank 50Hz에 맞춰서 게임전체가 느려져요.

원래 60Hz 기준으로 만든 게임들이라 그렇습니다.


암튼 그렇구요.

이제 함수들을 대충 만들어봅시다~ ㅎ.ㅎ





초기화하고 데이터 밀어넣고(enqueue) 재생!

경우에 따라 잠시 멈춤이라든가 효과음 섞어 출력!

"효과음을 섞는다"라는 표현을 쓰긴 했지만...

실제로 PSG에서 배경음악과 효과음 소리가 믹스되어 동시에 나오는건 아니구요.

효과음 출력을 넣으면, 그 시점의 배경음악 소리가 잠시 들리지 않게 처리가 됩니다.


만약 배경음악 3채널을 쓰고, 효과음을 넣어야한다면...

주 멜로디가 되는 채널을 피해서 효과음을 넣어야겠지요?

효과음이 두개라면?? 채널 우선순위를 잘 정하시면 됩니다. 누가? 프로그래머가요 ㅋㅋ

어쨌거나 라이브러리는 배경음악, 효과음 모두 3채널 활용가능합니다.


배경음악은 xxx_enqueue() 함수로 데이터 처리가 되구요.

내부적으로 512바이트 버퍼를 갖고 있습니다. (더블 버퍼 방식으로 되어있어요.)

미리 버퍼를 채울 수 있어요.

그리고 버퍼 상태는 xxx_get_pos(), xxx_get_avail() 함수를 쓰면 됩니다.


효과음은 xxx_overlay() 함수로 데이터를 밀어넣습니다.

소리가 나야하는 시점에 xxx_overlay() 함수를 호출하면 즉시 데이터가 출력됩니다.

이전에 출력되던 효과음 데이터가 남아있다면 지우고 새로운 데이터로 교체됩니다.

총알을 빠르게 쏘면, "다다다다~아~" 식으로 소리가 들리겠네요. ㅎ.ㅎ


글이 너무 길어지면 읽기 힘드니까 1편은 여기서 줄입니다.


그럼, 이만...

2015년 4월 3일 금요일

HI-TECH C 개발 툴을 GitHub에 올려봤습니다

이제껏 HI-TECH C 툴 작업하면서, git repository를 로컬PC에 저장하고 있었습니다.

사실 혼자 작업하는거라서 굳이 git을 쓸 필요는 없지만, 그냥 쓰고 있었죠ㅋㅋ


GitHub는 git 서버를 제공하는 싸이트인데요.

https://github.com


public repo는 무료로 생성이 가능합니다. 무제한으로요~ ㄷㄷㄷ


암튼 GitHub 테스트 겸해서, 기존 HI-TECH_C git을 올려보았습니다.


먼저 GitHub에 new repo를 하나 만들고 git remote에 추가합니다.

아래처럼 github와 제 로컬PC의 remote 두개가 보입니다.




remote github에 push한 모습입니다.

gitk를 실행해보면, origin / github 모두 최신 commit으로 올라간걸 볼 수 있어요.




github 싸이트에서는 아래 URL로 가시면 확인이 가능합니다.

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




commits 탭을 누르면 아래처럼 log 확인이 가능합니다.

프로필 사진도 붙어나오네요.ㅋ




아래는 commits 갯수 그래프입니다.

참고로 HI-TECH C 툴작업은 2009년부터 했지만, git은 2011년부터 사용했습니다.

2013년말~2014년말 사이는 commit 하나도 없네요. 

회사가 암울했던 시기라... 퇴근하면 바로 취침 ㅋ




Punch Card라는 메뉴탭을 눌러보았습니다.

commit 양을 날짜/시간 별로 모아서 보여주네요.

역시나 주말 작업이 많았군요. 평일은 밤12시 전후로~ ㅎ.ㅎ




그럼, 오늘도 즐거운 밤 되셔요~ㅋ


 

2013년 6월 24일 월요일

HI-TECH C - R800 곱셈 명령 테스트

R800은 파나소닉의 MSXturboR 모델에 들어가는 CPU 이름입니다.

Z80 호환 CPU이긴 하지만 속도가 무지빠르다는 장점을 갖고 있지요.


이번에는 R800 추가된 명령어인 MULUW 를 테스트해봤습니다.


사실 R800에 추가된 명령은 아래 딱 두개뿐인데요.

8BIT 곱셈명령 MULUB, 16BIT 곰셈명령 MULUW 


아래 그림에서 처럼,

16BIT x 16BIT 곱셈은 MULUW HL,BC밖에 못쓰는걸 알수있어요.




실제 C 코딩에서 활용할 수 있도록,

HI-TECH C의 16BIT 곱셈 루틴을 바꿔서 돌려보았습니다.

IMUL.AS 파일의 소스코드입니다.

파랗게 선택된 부분이 r800only가 선언된 LIB에서 동작하게 됩니다.

전체 코드가 MULUW HL,BC 명령으로 대체된걸 볼수 있습니다.




실제로 C로 코딩해서 테스트해봅니다~

아래처럼 간단 곱셈 루프를 돌려보는거죠! ㅎ.ㅎ




아래는 MAKEFILE용 CFG설정입니다.

뱅크2번은 LIBCMSXT.LIB로 링크되는걸 볼수 있습니다.

일반 LIBCMSX2.LIB와는 IMUL 루틴이 차이가 납니다.




아래는 제 터보알에서 구동해본 모습입니다.

CPU는 R800 DRAM인 고속 모드 상태로 동작중입니다.




실제로 테스트 해보실 분은 첨부파일 받아보셔요.

소스도 들어있습니다.

Download: R800_MUL_20130624.zip

Download: R800_MUL_SRC_20130624.zip


2011년 4월 9일 토요일

HI-TECH C - 그래픽 데모 및 테트리스 추가

작업 중이던 그래픽 라이브러리가 툴에 추가되었습니다.

 

아직 텍스트 모드와 패턴맵 모드는 지원이 안되지만,

비트맵 모드(스크린 5,6,7,8)은 어느정도 활용이 가능합니다. ㅎ.ㅎ

 

데모 프로그램에 DEMO_GRP 및 TETRIS 소스가 추가되었습니다.

 

쓰다가 궁금한 부분이 있으시면, 댓글 주셔요~~


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


2011년 4월 4일 월요일

HI-TECH C - 그래픽 라이브러리 데모 용 테트리스

테.트.리.스

 

설명이 필요없는 게임이겠군요. ㅎ.ㅎ

참고로, 그래픽 라이브러리 데모용 프로그램입니다.


DOS2 에서 실행가능하며, 추가 메모리 64KB 필요합니다.

메인램 256KB 이상인 시스템이면 충분하겠습니다.


심심하신 분들은 한번 실행해보세요. ㅎ.ㅎㅋ

Download: TETRIS_20110404.zip



아래는 에뮬에서 실행해본 모습입니다.

ESC 키를 누르면 도스로 복귀합니다.




작대기가 연속으로 세개가 등장하는군요 !!

음... 라인 10개 없앨때 레벨 하나씩 올라갑니다. 그냥 블럭 떨어지는 속도만 빨라져요.




바닥에 떨어질 위치에 점선으로 표시해줍니다~ ㅎ




아래는 터보알에서 세운 기록~~ 짜잔~~ 레벨10에서 95점 !!



2011년 3월 21일 월요일

HI-TECH C 용 GRP 라이브러리 만들기 #3 - 라인, 박스, 폰트

이제 뭔가 좀 갖추어진 듯 한데용...

 

Line, Box, Boxfill 및 폰트 그리는 기능이 추가되었습니다.

Line은 VDP 커맨드를 그대로 사용하고,

Box, Boxfill은 Line을 여러개 그리는 식으로 구현되어있습니다.

 

폰트는 일단 MSX BIOS에 내장된 8x8 데이터를 내장했습니다.

출력은 8x8 또는 6x8 등으로 가능합니다.

 

RAM과 VRAM간 많은 양의 데이터 전송이 가능하고,

팔레트 함수들을 추가했습니다. 


 

 

아래는 라이브러리 테스트용 프로그램이 동작하는 모습인데요, 잠시 구경해보세요~ ㅎ

간단한 비트맵 모드 그래픽은 어느정도 완성됐으니,

다음은 패턴맵 모드 쪽으로 구현하려고 합니다.




2011년 3월 7일 월요일

HI-TECH C 용 GRP 라이브러리 만들기 #2 - 스프라이트, VRAM 카피

주말을 맞아 작업이 좀더 진행이 됐습니다.

스프라이트 기본기능과 VDP 커맨드를 이용한 메모리 copy 정도를 넣어봤습니다.

 

 

아래는 라이브러리 테스트용 프로그램이 동작하는 모습인데요, 잠시 구경해보세요~ ㅎ




2011년 3월 2일 수요일

HI-TECH C 용 GRP 라이브러리 만들기 #1 - 구상

요즘 틈틈히 DOS2뱅킹 라이브러리와 함께 쓸수 있는, 그래픽 라이브러리를 만들고 있습니다.

시작이 반이니까... 50% 완성이라고 보시면 되겠네요. ㅎ.ㅎㅋ

 

라이브러리 구동 환경은,

제가 만든 DOS2 뱅킹 라이브러리가 필수이고 가능하면 2뱅크(32KB x 2)이내로 만들 생각입니다.

BIOS 내의 스크린 모드 전환 및 VDP 관련 루틴 없이 동작하도록 되어있습니다.

최소 사양은 V9938 + VRAM 128KB 이고, V9958 기능들도 지원합니다.

 

구현은 아래 처럼 진행중입니다. 순서는 좀 바뀔수 있어요 ㅎ.ㅎ

 

1. VDP I/O

   - VDP control 레지스터 쓰기, status 레지스터 읽기

   - VRAM 읽기/쓰기

   - VRAM 페이지(16KB 단위) clear

   - 디스크, VRAM 간의 Load/Save

 

2. 비트맵 모드 (스크린 5,6,7,8)

   - 페이징

   - VRAM R/W 이용한 픽셀 그리기

   - HW 수직 스크롤(V9938)

   - HW 수평 스크롤(V9958, 1페이지, 2페이지 모드)

   - VDP 커맨드

   - 폰트

   - Circle

   - 인터레이스 모드 DRAW: Line, Box

 

3. 스프라이트

   - 스프라이트 모드2

   - 스프라이트 모드1

   - 패턴 애니메이션

 

4. 패턴맵 모드 (스크린 2,4)

   - 페이징

   - 패턴 애니메이션

   - Line, Box, Circle

   - SW 스크롤

 

5. 팔레트

   - 팔레트 애니메이션

 

6. 텍스트 패턴맵 모드 (스크린 0,1)

   - 페이징

   - 폰트

   - Line, Box (특수 문자)

 

7. 비트맵 모드 (스크린 10,11,12)

   - 2번에서 중복 기능 외...

 

 

에... 사실 처음에는 VDP 기본 라이브러리랑 게임용 라이브러리를 따로 만들까 생각도 했었는데요.

일단은 짬뽕해서 진행하고, 상황봐서 게임용은 따로 나누던지 할 생각입니다.

 

조금씩 만드는거라, 언제 완성될지는 모르겠지만, 라이브러리는 진행중 가끔 릴리즈 될 예정입니다.

 

PS. 혹시 요청사항 있으시면 댓글 달아주셔요. ㅎ.ㅎ


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 기능입니다.)




2010년 6월 16일 수요일

DOS2 Banking Library & Build tool 제작 #3

지난번까지 기본적인 뱅킹 라이브러리와 관련 툴을 만들었는데요.

조금씩 개선하면서 진행중입니다.

 

기본 C 라이브러리에서 빠져있던 getenv(), setenv() 함수를 DOS2 기준으로 쓸수 있도록 추가되었습니다.

현재 뱅킹 툴로 소스 빌드를 하면,

로딩 프로그램(*.COM)과 별도의 뱅크에 로드되는 코드(*.OVL)가 생기는데,

로더가 구동시 같은 디렉토리에 존재하는 OVL을 읽을수 있도록 했습니다.

(이때 getenv()가 필수가 되지요.)

 

계획되었던 뱅크간 공유 메모리용 함수들도 만들었습니다.

요건 간단하게 malloc(), free() 같은 기존 함수에 wrapper로 구현했습니다.

메모리 영역 9000H~ 부터가 공유 힙이 되는 것이지요.

참고로, 뱅크 내의 코드에서 malloc()을 쓰는 경우는 해당 뱅크 메모리(0000H~7FFFH)가 사용됩니다.

 

뱅크간 함수로 파라미터 전달은 기본적으로 스택이 쓰입니다.

큰 메모리를 포인터만 전달하거나, 공유용으로 쓸때만 이 영역이 사용되는 것이고요.

 

다음은, ISR(인터럽트 서비스 루틴) 처리인데...

일단 0038H의 Z80 인터럽트 벡터는 DOS2와 메인 BIOS가 서로 다르게 세팅해서 사용하고 있기 때문에

이걸 직접 수정하면 안됩니다.

 

메인 BIOS에서 제공하는 KEYI 훅과, 타이머용 TIMI 훅을 쓰도록 만들었습니다.

(사실 타이머는 VDP의 V Sync 인터럽트지요.)

 

실제로 훅 동작시에는 이미 Page0가 메인 BIOS로 변경이 되는데요. (DOS2에 의해)

유저 ISR이나 메모리를 Page0에서 쓸수도 있으니,

기본적으로 슬롯 세팅 및 뱅크 전환도 함께 되도록 구현할 생각입니다.

ISR의 뱅크 위치와 상관없이 구동 되도록 합니다.

 

아직은 간단한 카운트만 하는 ISR(외부 인터럽트 및 타이머 인터럽트)이 동작하는지 테스트했습니다.

최종적으로는 외부 ISR은 8개정도, 타이머 ISR은 1개를 등록하도록 만들 생각입니다.

 

아래 스크린샷을 보세요.




DOS2 환경 변수를 몇개 출력해보았고,

9000H~ 에 위치하는 공유 버퍼를 할당 받은 것도 표시해보았습니다.

(뱅크1에서 한개, 뱅크2에서 한개 할당했네요.)


맨 아래쪽 라인에서는,

0CE1, 0CE0, 0CE0 세개의 카운터가 올라가는 것을 출력하는 중인데요.

왼쪽은 메인 BIOS의 JIFFY 값,

중앙은 유저의 외부 ISR의 카운터

오른쪽은 유저의 타이머 ISR의 카운터 입니다.


2010년 6월 1일 화요일

DOS2 Banking Library & Build tool 제작 #2

얼마전부터 만들던 HI-TECH C용 뱅킹 라이브러리가 기본 틀이 완성되었습니다.

 

Makefile에서 소스 파일들을 뱅크 별로 목록만 만들면,

뱅크간 참조되는 함수 콜을 생성해서, DOS2의 세그먼트 전환으로 실행되도록 구현했습니다.

 

빌드가 완료되면, 실행파일(*.COM)과 각 뱅크의 코드 묶음(*.OVL)이 생성됩니다.

DOS2에서 실행하면 *.OVL 파일 크기에 따라 필요한 메모리 세그먼트를 할당 하고 파일을 로딩합니다.

로딩이 완료되면 main() 함수가 실행됩니다.


뱅크 내의 각 함수(main 함수 포함)들은 크기 제한(32KB)외에는 자유롭게 뱅크를 선택해서 만들수 있습니다.

 

뱅크간 참조 함수 처리는 빌드시, 특정 프로그램으로 생성되는데요. 아래의 순서로 진행됩니다.

 

1. 각 뱅크별로 소스들을 컴파일 하고, 임시로 라이브러리와 링크를 수행합니다.

    이 때, 링크 시 없는 함수들은 따로 리스트를 만들어 놓습니다. (*.LST 파일)

 

2. 각 뱅크별로 소스들만 컴파일/링크해서, 존재하는 함수 목록을 만듭니다. (링크 시 생성된 *.MAP 사용)

 

3. 모든 소스의 함수들의 실제 엔트리 주소와 뱅크 번호를 모아서 목록을 만듭니다. (*.REF 파일)

 

4. 1번 리스트에 등록된 함수와 3번의 전체 함수 목록을 참조해서,

    뱅크 전환 후 점프되는 가짜 함수를 만듭니다. (어셈블리 *.AS 생성)

 

5. 각 뱅크별 소스와 가짜 함수 코드를 같이 컴파일해서 링크합니다.

    참고로 가짜 함수는 콜을 하는 소스와 같은 뱅크에 존재하지만,

    실제 실행되면 진짜 함수가 존재하는 뱅크로 메모리 전환 후 콜됩니다.

    함수에서 리턴시, 원래 뱅크로 복귀.

 

6. 뱅크0의 코드는 Loader프로그램과 함해져서 실행파일(*.COM)로 생성되고,

   나머지 뱅크들은 1개의 *.OVL 파일로 합쳐집니다.

 

 

아래는 MSX 에뮬레이터에서 MSX-DOS2 환경으로 실행된 모습입니다.

뱅크가 3개인 프로그램(TESTAPP)를 실행한 모습입니다.

뱅크0는 기본으로 로딩되기 때문에 2개 뱅크(4개 메모리 세그먼트)가 추가로 할당되는 모습을 볼수 있습니다.




라이브러리 및 빌드시 필요한 프로그램은 좀 더 정리되면, 자료실에 업로드하겠습니다.

 

어셈블리 코드로 만들 필요가 없으니,

앞으로 메모리 걱정없이 편하게 C로 코딩할수 있게 되었습니다. ㅎ.ㅎ

2010년 5월 11일 화요일

DOS2 Banking Library & Build tool 제작 #1

그냥 오래전부터 생각했던 프로젝트였는데, 이제서야 실천(!)에 옮기려고 진행하는 것인데요...

그게 뭐냐고요? ㅋ 으흠~ ㅎ.ㅎ



MSX에는 메모리 매퍼를 이용해 64KB 이상의 메모리를 사용할 수 있도록 설계되어있습니다.

이 메모리를 좀 더 효과적으로 사용하는 프로그램을 만들자라는 것이 목표이고요.

물론 기존에도 그냥 메모리 매퍼를 직접 액세스하거나 DOS2의 매퍼 루틴으로 잘 썼긴했습니다.

근데 솔직히, DOS2에 메모리도 넉넉하게 쓸수 있는 유저가 많지 않았었죠?

저도 이것 때문에 일반적으로 배포하려고 만드는 프로그램은,

메모리 매퍼를 쓰지않고 DOS1의 기본 메모리에서 구동되도록 했었습니다.

대신, 디스크 퍼포먼스는 DOS2 쪽이 좋기 때문에,

DOS2에서 실행되는 경우에는 DOS2의 시스템 콜을 쓰도록 만들었습니다.



최근에 저와 흥건남자님과 힘을 합쳐 확장슬롯+1MB램을 쓸수 있는 기기가 나오게 되었는데요,

이제 메모리를 활용할수 있는 프로그램을 본격적으로 만들어도 될때가 되지않았나 생각됩니다.

메모리가 많으면, 스크린7의 인터레이스 모드 그래픽을 쓰거나,

안티앨리어스 적용되는 한글 폰트룰 만든다던가...  재밌는걸 할수 있겠지요. ^^



일단 메모리 매퍼를 조금 설명드리면...

다른 대부분의 MSX기본 기기처럼, 메모리 매퍼도 IO 맵 I/O로 동작합니다.

근데 한가지 이상한 부분이 있죠.

MSX에서는 메모리 매퍼를 여러개 써도 되도록 규격이 만들어져 있습니다.

그러니까 슬롯1에는 1024KB, 슬롯3-0에는 512KB... 이런식으로 쓸 수 있다는 것이지요.



근데, 중요한건 메모리 매퍼용 IO 주소는 슬롯 제한을 받지 않는다는 사실인데요.

(IO 맵 방식이니까, 당연한 것이지만요.)

이게 SW 개발하는 사람한테는 참 머리아픈 문제입니다.

왜냐면, 예를 들어 현재 Page2 메모리(8000H~BFFFH)를 다른 세그먼트(뱅크 또는 페이지라고 보시면됩니다.)로

할당하게 되면, 모든 슬롯에 장착된 메모리 매퍼의 세그먼트가 같이 바뀝니다.



게다가 한가지 문제가 더 있는데요.

메모리 매퍼중에는 현재 세그먼트 번호를 읽을 수 있도록 만들어진게 대부분입니다.

MSX2 이상의 본체 내장된 건 아마 다 읽을 수 있을꺼에요.

문제는 Write 할때는 같은 주소에 연결된 기기가 한번에 동작은 하는데,

반대로 Read 할때는 램의 용량에 따라 세그먼트 최대 갯수가 다르니 읽은 값도 다를 수가 있겠죠?

이 때문에, 매퍼 레지스터를 읽는 것은... 법(!!)으로 금지되어 있습니다.



하지만 안타깝게도 MSX의 메인 바이오스는 메모리 매퍼에 관한 루틴이 하나도 없어서,

메모리 매퍼를 컨트롤하려면 SW 만드는 사람이 알아서 해야된다는 것이었죠.

이 때문에 많은 메모리 관련 호환성 문제가 발생하게 되었습니다.



어떤 슬롯에 얼마나 메모리가 장착되어 있는지, 확인하는 것이 쉽지가 않습니다.

아까 말했듯이 특정 세그먼트를 바꾸면, 원하지 않는 슬롯의 메모리도 변경이 되고...

용량을 확인하려면, 16KB 영역을 R/W 해보면서 램인지 일일이 체크를 해야하는데 쉽지 않죠.



그래서 많은 프로그래머들이 그냥 용량 체크는 세그먼트 값을 썼다가 읽은 값이 같아지는 숫자만을 인식하거나,

특성 슬롯만 메모리 확인을 하거나... 매퍼가 두개 이상일때는 메인(Primary) 매퍼만 사용하거나... 등의

방법을 썼습니다.



제 경우에도 터보알(A1GT)의 내장램을 1024KB로 확장하니까, 대부분 유럽산 프로그램들이 동작하지 않더군요.

보통 128KB~256KB 메모리를 요구하는 프로그램들입니다.

재밌게도 일본에서 만든 프로그램은 대부분 64KB 전용이라 크게 문제될게 없더군요.

국내 SW는 대우 MSX에 맞춰서 슬롯/메모리 등을 설정해서 또 문제가 됐었고요.



단지 일반 개발자 뿐만 아니라 유명한 게임들도 비슷한 제들이 있었습니다.

마이크로 캐빈의 FRAY는 메모리 확장된 터보알에서 부팅 안되는게 제일 유명한가요?



암튼 HW 설계상의 약점과 SW 개발의 어려움이 한데 뭉쳐져서 메모리 활용이 상당히 힘들었습니다.



이게 MSX-DOS2의 디스크 바이오스에서 메모리 매퍼를 지원하게 되어 이런 문제가 해결되었습니다.

바이오스 콜을 통해 메모리 세그먼트의 할당/해제/전환을 쉽게 할수 있게 되었지요.



Page3을 제외한 Page0,1,2 (0000H~BFFFH)의 메모리를 마음데로 바꿀수가 있습니다.

Page0의 경우는 인터럽트 사용시 주의해야겠지만... 암튼요.



방법은 DOS2 매뉴얼에 나오니 여기서 설명하진 않겠습니다.

다시 말씀드리지만, 메모리 매퍼 강좌를 하려는게 아니에요. ^^;



어쨋꺼나 DOS2 바이오스의 지원으로 메모리는 좀 더 사용이 쉬워졌지만,

개발자가 메모리 구성을 잘해서 SW를 만들어야 하는 것은 변함이 없습니다.

MSX용 개발 툴 중에서 DOS2 메모리 관련 루틴을 활용한 것이 따로 있는지는 잘 모르겠네요.

몇 종류의 어셈블리와 파스칼, C 정도의 컴파일러가 있지만, 대부분 CP/M용이라 (MSX-DOS1 겸용)

활용이 불가능 할 겁니다.



암튼, 서론이 길었는데요. ㅎ.ㅎ;

이번에 HI-TECH C에서 DOS2 메모리 매퍼 활용을 높일 수 있도록,

관련 라이브러리와 단일화된 메모리맵을 만들고 있습니다.



일단 컴파일러로 HI-TECH C를 고른 이유는...

라이브러리가 풀 소스로 제공되고, 인라인 어셈블리 사용도 편리한 편이고,

ANSI C를 풀로 지원한다거나 여러가지가 있겠지만,

제가 최근 수년간 쓰면서 많이 익숙하다는게 주 이유일 것 같네요.

함수 파라미터와 로컬 변수가 모두 스택에 할당되기 때문에

퍼포먼스가 좀 딸린다는 단점이 있지만, 대신 항상 함수의 Re-entrant(재진입)가 가능합니다.



메모리 관리는 DOS2의 확장 바이오스 루틴에 의존합니다.

메모리 세그먼트가 다른 함수 간의 호출은 별도의 뱅킹 루틴을 통해 이루어지는데요.

총 약4MB의 메모리를 사용할 수 있습니다.(DOS2와 터보알의 시스템 영역은 제외)

16KB 세그먼트 2개를 한개의 프로그램 뱅크로 사용합니다.

그러니까 최대 128개의 뱅크(32KB x 128 = 4096KB)를 프로그램으로 쓸수 있습니다.

일단 아래 메모리 맵을 보세요.



0000H~00FFH : DOS 시스템 콜 영역

0100H~7FFFH : 뱅킹 가능한 프로그램 영역(TEXT/DATA/BSS) (약 32KB)

8000H~8FFFH : 뱅킹(세그먼트 전환) 루틴, 뱅킹 스택 (4KB)

9000H~9FFFH : 공용 ISR 및 뱅크간 공유 DATA 영역 (4KB)

A000H~FFFFH : 스택 및 Work Area (24KB)


한동안 고민했던 메모리맵이었는데요,

함수 갯수가 많아지고 뱅킹간의 함수 콜도 왠만큼 하려면 스택이 많이 필요해지는데,

일단 현상태로 괜찮을지는 모르겠습니다.

부족하면 뱅크간 공유 DATA 영역을 줄여야겠지요. ^^



0100H~7FFFH 영역을 프로그램으로 할당한 것은,

Page1(4000H~7FFFH) 영역을 다른 슬롯에 있는 SW를 사용하거나,

메모리맵 IO를 쓰는 주변기기를 쉽게 액세스하기 위함입니다.

그리고, 실제 뱅킹은 Page0,1(0000H~7FFFH) 전체 영역이 바뀌게 되니까,

개별적인 인터럽트 루틴을 잠깐씩 쓸때도 유용하지 않을까 생각되네요.

아직 DOS2 시스템 콜을 사용시, Page0를 제대로 복구하는지는 테스트를 해봐야됩니다.



현재 뱅킹 루틴을 만들어서 테스트 중인데요.

HI-TECH C 컴파일 했을때 일반 함수에서 다른 뱅크로 잘 전환되는지 확인중입니다.



진행 상황은 가끔 글로 올리겠습니다.

혹시 질문 있으면 댓글로 달아주세요~




2009년 4월 2일 목요일

HI-TECH C v3.09 - MSX 라이브러리

개인적으로 관리하면서 사용하는 HI-TECH C용 라이브러리를 올려봅니다.

언젠가 정리되면 업로드하려고 했는데, 미루다보니 시간이 많이 지났네요. ㅎ.ㅎ;


참고로, HI-TECH C가

ANSI-C 및 부동소수점 지원 되는 유일한 MSX용 C 컴파일러로 알고있는데요.

인라인 어셈도 쓸수 있고 좋긴한데, 실행속도가 좀 느리다는 단점이 있습니다.


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


------------------------------------------------------------------------------

    HI-TECH C v3.09 Library (2009.04.02)

        By 서영만 (E-mail:sharksym@hitel.net)

------------------------------------------------------------------------------

 - CP/M용 C Compiler인 HI-TECH C v3.09를 위한

   LIBC 및 LIBF 라이브러리와 CRT.O 파일입니다. (소스 포함입니다.)


 - CP/M 및 MSX-DOS1, MSX-DOS2 모두 지원하도록 만들어져있습니다.

   CRT.O에서 구동시 BDOS 버전을 체크하여, 각 OS에 최적화된 함수가 실행됩니다.

   기타 MSX에서 사용가능한 함수가 다수 포함되어있습니다.

   (관련 헤더파일을 확인하세요.)


 - LIBCGEN.LIB : CP/M, MSX-DOS1, MSX-DOS2 공용 LIBC

   LIBCMSX.LIB : MSX-DOS1, MSX-DOS2 전용 LIBC

   LIBFGEN.LIB : CP/M, MSX-DOS1, MSX-DOS2 공용 LIBF (Floating Point 함수 포함)

   LIBFMSX.LIB : MSX-DOS1, MSX-DOS2 전용 LIBF (Floating Point 함수 포함)


 - 코드 대부분은 HI-TECH C의 원본 라이브러리 소스가 사용되었으며,

   Arnold Metselaar씨 및 Tatsuhiko Syoji씨의 수정/추가된 소스도 사용하였습니다.

   기타 다른 분의 코드도 일부 포함되어있고, 나머지는 제가 직접 수정/추가한

   것입니다.


 - 소스 빌드를 위해 윈도용 CP/M 에뮬레이터인

   CP/M-80 program EXEcutor for Win32 V0.2 프로그램이 사용되었습니다.

   MAKE는 GNU MAKE를 사용하면됩니다.

   (실제 CP/M, MSX-DOS에서 사용가능한 MAKE가 있는지는 모르겠습니다.

    현재는 윈도용 CP/M에뮬레이터만 사용중입니다.)


 - CP/M 및 C Compiler에서 서브 디렉토리를 지원하지 않으므로,

   대신 CP/M 에뮬레이터의 가상 드라이브 매핑 기능을 활용했습니다.


 - CPMEMU_HI-TECH_C 디렉토리에는 HI-TECH C 패키지와 CP/M 에뮬레이터 및

   HI-TECH C 원본 라이브러리인 LIBC.LIB, LIBF.LIB와

   ASCII C의 그래픽 라이브러리 호환인 LIBG.LIB도 포함되어있습니다.

   소스 빌드시에도 CPMEMU_HI-TECH_C 디렉토리가 그대로 사용됩니다.


 - MAKE_ALL.BAT를 실행하면 4개 LIB를 생성하며,

   TESTCODE의 프로그램으로 동작 확인이 가능합니다.