레이블이 emulator인 게시물을 표시합니다. 모든 게시물 표시
레이블이 emulator인 게시물을 표시합니다. 모든 게시물 표시

2014년 11월 27일 목요일

Mini vMac

초기 Macintosh에 대한 에뮬레이터로 종종 언급되는 것이 바로 이 Mini vMac이다.

그런데 어찌된 일인지 사용하기가 무지 까다롭다.

정확히 말하자면 내.가. 사용하기에 무지 까다로왔다.

아직까지도 제대로 써 보질 못했으며, 써 보려고 시도한 것도 수차례이며, 같은 삽질이 반복되고 있다는 것은 정말 화가 날 지경이다.

그래서 더 이상은 삽질하지 말자는 의미로 여기에 정리해 두려 한다.



1. Mini vMac
공식적인 홈페이지가 sourceforge에 있었는데 이번에 방문해 보니 다른 곳으로 옮겼다고 한다.
http://www.gryphel.com/c/minivmac/index.html
여기에서 Mini vMac 바이너리를 다운로드 받을 수 있다.

2. ROM
어디에서 구했는지 기억은 나지 않지만, Macintosh Plus용 ROM을 가지고 있으며 여기에 저장해 둔다.
Mac_Plus_ROM.zip
압축을 풀면 vMac.ROM 이름의 파일이 나온다. 이 이름 그대로 사용하면 된다.

3. System 6 OS
위의 Mini vMac 사이트에서 설명한대로라면 Apple 사이트에서 이 오래된 OS의 디스크 이미지를 받을 수 있어야 하는데, 어찌된 일인지 지금은 링크가 사라진 듯 보인다.
그래서 이것도 여기에 보관해 두었다.
SSW_6.0.8_Disk 1 of 2
SSW_6.0.8_Disk 2 of 2

4. Stuff-it Expander
위의 디스크 이미지를 그대로 사용하려고 하면 작동하지 않는다는 것을 알게 된다.
확장자도 .bin이라서 더 이상 뭐가 있겠나 싶었는데, Macintosh에서 사용되는 Stuff-it이라는 압축 프로그램으로 압축이 되어 있으니 이걸 풀어야 한다고 한다.
그런데 이게 뭐 유명하지도 않고 Macintosh에서나 사용되는 프로그램이라 구하기가 녹녹하지는 않아 보인다.
일단은 Linux용의 Stuff-it 압축 프로그램을 찾아냈다.
혹시 모르니 이것도 보관.
Stuffit520.611linux.tar.gz

5. System 6 디스크 이미지 풀어내기
4번의 Stuff-it으로 3번의 System 6 디스크 이미지를 풀면 되지 않는가?
그것만으로는 안되더라는....ㅠㅠ
먼저 디스크 1번의 압축을 풀어보면, *.info, *.rsrc, *.data 세개의 파일이 나온다.
여기에서 *.data 파일을 다시 압축을 풀면 System Startup이라는 파일이 나온다.
이 파일이 1.44MB의 디스크 이미지이고, Mini vMac에서 인식할 수 있는 파일이다.
혹시 모르니 이것도 여기에 보관.
System Startup
디스크 2의 압축을 풀어서 나온 이미지도 여기에 보관.
System Additions

System 6 디스크 압축 풀기

2013년 7월 7일 일요일

Appler 디버깅하기 ___ 4

터보디버거가 어째 좀 불안해서 디버깅을 하다가 새로 시작하곤 해야 하는 문제가 있었기에 의욕이 급속히 감소 되었더랬습니다. (지난 포스팅 말미에 썼던 문제점입니다.)

거기에 레퍼런스로 사용하던 Oracle의 VirtualBox도 말썽을 부렸습니다.
4.2.14 버전으로 업데이트하고 나니 키보드도 제대로 작동하지 않는 문제가 발생하더군요.
처음엔 제가 사용하는 리눅스의 사양이 너무 딸려서 시스템의 오작동이 아닌가 생각 했는데, 윈도우즈용도 마찬가지인 것을 확인하고는 참...어이가 없었습니다.
Oracle이 겨우 이런 회사인가....
며칠후에 4.2.16으로 업뎃하고 나니 다행히 정상으로 돌아오긴 했습니다.

암튼 이래저래 시간은 흘러가고 디버깅은 지연되고....하다가 겨우 다시 붙잡았습니다.

첫번째 디버깅 타겟으로 잡은 것은 Path&Filter 부분이었습니다.
Path&Filter 부분에서 Path와 Filter 사이에 backslash가 없었던 문제부터 디버깅을 해 보기로 했습니다.

찾아보니 Path, Filter, PathFilter라는 변수가 있었고, 이 변수를 채우는 프로시져로 ReadDirectory가 있었습니다.

먼저 VirtualBox에서 이 부분을 디버깅하면서 나온 정상적인 결과를 보겠습니다.
int 21h(ah=60h)를 호출한 후

Path 변수를 확인해 보니 문자열의 마지막에 Backslash가 있습니다.
터보디버거에서는 어쩐 일인지 Path 문자열을 Watch에 등록했는데, 앞 두글자만 보여주더군요. 그래서 Data Inspecting으로 주소를 확인하고 View-Dump로 메모리를 확인해 보니 문자열 모두를 볼 수 있었습니다.
VirtualBox에서는 정상으로 작동하고 있었기에 이걸 정상적인 결과로 가정했습니다.

소스에서 보는 DOS interrupt인 int 21h에 대한 자료를 찾아보았습니다.
Ralf Brown이라는 분이 정리한 자료가 있는데, 얼핏 보았는데 상당히 자세한 듯 합니다.

우선 2개의 interrupt에 대한 것만 보면,
INT 21h(AH=60h) TRUENAME

INT 21h(AH=1Ah) Set DTA

그러면 같은 부분을 DOSBox에서 실행했을 때는,
DOSBox에서 디버깅한 경우, Backslash 없음.

어느쪽이 맞는건지 모르겠지만 VirtualBox와 DOSBox가 서로 다르게 작동한다는 것은 확실합니다. 그리고 Appler가 실제 MS-DOS를 기반으로 개발된 것을 감안한다면 VirtualBox의 작동방식이 맞다고 보는 것이 타당할 것입니다.

근본적으로 저 문제를 해결하려면 DOSBox를 수정하는 것이 맞을테고, 수정의 용이함이나 Side Effect를 최소화하면서 Appler를 제대로 구동하려면 Appler를 수정하면 될 것입니다.


어셈블리 프로그래밍에 능숙하지 않은 관계로 소스의 수정은 뒤로 미루고,
다음 문제를 디버깅해 보기로 했습니다.
디렉토리 내의 파일이름들 리스팅에도 문제가 있었고, 사실은 이게 제일 큰 문제였습니다.

처음엔 조금 막막했지만, 흔히들 디렉토리 내의 파일 이름들을 얻어 오는 C의 함수로 FindFirst()와 FindNext()를 사용했던 기억이 났습니다.
그리고 소스내에서 동일한 이름의 매크로가 있는 것을 찾아냈습니다.
FindFirst, FindNext 매크로
매크로 무지 간단합니다.
그냥 DOS Interrupt 호출이네요.
아까 보았던 자료에서 위의 Interrupt에 관한 부분을 찾아 보았습니다.
INT 21h(AH=4Eh) FindFirst

INT 21h(AH=4Fh) FindNext

그런데...정말 혹시나 하는 생각이 들었습니다.
앞서 디버깅한 Path&Filter의 문제로 디렉토리의 파일 이름들도 문제가 생긴게 아닐까 하고..

그래서 디버깅 하면서 바로 수정해서 확인 해 보았습니다.
Path의 마지막에 Backslash(5Ch) 넣어주기

Backslash가 들어갔습니다.

Path&Filter 뿐 아니라 Directory 부분도 정상적으로 나옵니다.

Disk Manager 화면으로 진입하면 ReadDirectory라는 프로시져가 2번 호출이 됩니다.
두번 모두 마지막에 Backslash(5Ch)를 넣어주면 모든게 정상이 됩니다.

이젠 DOSBox의 개발진에게 이 문제를 리포트하든지,
내가 직접 DOSBox를 수정하든지, Appler를 수정하든지...하면 되겠네요.

2013년 6월 8일 토요일

Appler 디버깅하기 ___ 3

이제 빌드가 다 되었으니 디버깅을 하기 전에, 정상적으로 작동을 하는지는 확인해 봐야겠죠?
필요한 파일들(*.rom, *.dsk 등등)을 빌드한 폴더에 복사해 넣고서 확인해 보았습니다.


초기화면

데모화면

로드런너

디스크매니저. 문제도 그대로...

디버거

2013년 6월 6일 목요일

Appler 디버깅하기 ___ 2

일단 빌드해서 startup.asm은 무사히 넘어갔지만,
다음으로 걸린 부분은 floppy.inc 입니다.

emulate.asm을 컴파일하다가 floppy.inc에서 에러가 났습니다.

에러가 난 부분입니다. 역시 잘 모르겠지만 뭔가 기묘하네요.

CurrentDrive와 OtherDrive를 찾아보니 저렇게 선언되어 있는데 이것도 기묘합니다.OTL

우선은 xchg라는 인스트럭션이 뭔지 몰라서, 다시 터보 어셈블러 퀵 레퍼런스를 참조했습니다.
xchg는 값을 바꿔주는 거군요. 일종의 swap이네요.

그런데 이번에 문제가 되는 부분은 앞서보다 복잡하네요.
CurrentDrive/OtherDrive가 사용되는 곳이 많아서 종잡기도 힘들고,
선언된 곳의 저 모양새는 대체 무엇인지 이해가 되질 않습니다.

Drive_S가 배열인걸까요?
그래서 0번은 CurrentDrive, 1번은 OtherDrive로 사용되는 거...
이건 매뉴얼을 다시 찾아 보기로 하고...

Drive_S라는 걸 찾아보니 일종의 structure로군요.
Globals.inc에 선언되어 있습니다.

위에서 보았던 CurrentDrive와 OtherDrive의 선언 부분의 의미를 알아냈습니다.
CurrentDrive    Drive_S    <0>
Drive_S 타입으로 변수 CurrentDrive를 선언하면서, 초기값 0을 할당한 것입니다.
Drive_S는 스트럭쳐로 여러개의 값을 가져야 하지만 ?로 표시되어 있는 ID에 대한 것만 초기화 해 주는 것인 듯 합니다.

터보 어셈블러의 User's Guide 12장에 있는 해당 부분은 다음과 같습니다.



그런데, 아직도 에러가 난 부분의 의미가 뭔지 모르겠습니다.
CS:OtherDrive[SI-1]-CurrentDrive

각 부분의 의미도 정확히 파악이 되지 않으니 전체가 뭘 의미하는지도 모르겠고,
[]이 배열인 듯 하면서도, 선언된걸로 보면 배열이 아니었고...상상력이 부족한걸까요?

좀 크게 보겠습니다.
DeviceSelect 프로시져
하나의 프로시져 였습니다. DeviceSelect라는...
경우에 따라 DeviceSelect10 혹은 DeviceSelect20을 수행하는데, 문제가 되는 부분은 DeviceSelect10인 경우입니다.

이 프로시져를 호출하는 경우를 좀 봐야겠습니다.
ResetFloppy 프로시져

C0EBr/C0EBw 레이블

아래쪽의 C0EBr/C0EBw는 레이블 이름도 이상하고, 시작이 어디서부터인지도 명확하지도 않고 헷갈립니다.
반면에 위쪽의 ResetFloppy는 뜻이 비교적 명료합니다.

좀 더 자세히 분석해 보기 전에 몇가지 모르는 것들을 찾아보았습니다.

Save/Restore 매크로

자주 나오는 Save/Restore는 매크로였고 간단하게 push, pop으로 구현되어 있습니다.

IRP 지시어

IFNB 지시어
매크로에서 사용된 IRP와 IFNB 지시어에 대한 설명이구요,
IRP로 Repeat를 하는데, 인자들 리스트를 r로 정의하였고 IFNB에서 리스트가 비어있는지 검사하면서 반복하는 듯 합니다.

even 지시어
프로시져의 시작부분에 있던 even이라는 지시어에 대한 설명입니다.
16 bit memory alignment를 위해서 짝수번지에 맞추라는 의미인 듯 합니다.

lods 인스트럭션
메모리에 있는 것을 읽어서 al(혹은ax, eax)에 넣는 작업을 합니다.
REP 혹은 LOOP로 반복구간을 정하나 봅니다.


다시 소스를 확인해 보겠습니다.

호출시 al에 담긴 값이 CurrentDrive의 ID와 일치하면 DeviceSelect20을 수행하고 프로시져를 마칩니다. 즉, 바꿀 필요가 없다는 의미이겠죠.
그렇지 않고 바뀌어야 한다면 WriteTrack을 호출하고 돌아와서 CurrentDrive의 값을 하나씩 읽어와서 OtherDrive에 있는 값과 바꿔치고, OtherDrive의 값을 다시 CurrentDrive에 넣습니다.
여기에서 [SI-1]이 사용된 이유는 그 위에서 lods byte ptr CS:[SI]를 수행하면서 si의 값이 증가되었기 때문인 듯 합니다.
그렇다면 어째서 CS:OtherDrive[SI-1]-CurrentDrive일까요?
CurrentDrive를 왜 뺀걸까요?

사실 모르겠습니다. 그리고 CurrentDrive를 빼지 않는게 맞는 것 같습니다만....
일단 저 부분을 제 생각대로 고치고, 나중에 확인해 보겠습니다.
-CurrentDrive 제거

뜨악...그래도 에러?
대충 메시지 보고 찍어서 다시 수정해 보았습니다.
두번째 에러는 실수로 건드렸나 봅니다.
byte ptr 추가

이제야 빌드 완료입니다.

음...디버깅을 한다고 했는데, 겨우 빌드까지만 다 했습니다.
빌드만 했는데 진이 다 빠진 느낌입니다.
오늘은 여기까지만....

Appler 디버깅하기 ___ 1

앞선 게시물에서 언급했던 Appler라는 에뮬레이터를 디버깅해 보기로 했습니다.
http://re-coder.blogspot.kr/2013/06/dosbox-ms-dos.html

소스가 온통 어셈블러 뿐이고, 틀림없이 MS-DOS의 System Call을 사용할 것이 불을 보듯 뻔하지만, 인터넷에 널린 자료들을 이용해서 한번 도전해 보겠습니다.

일단 디버깅을 하기 위해서,
소스를 빌드해야겠지요.
(이를 위해서 터보 어셈블러 5를 구해서 설치했습니다.)

에러가 발생하네요

소스를 보았지만 뭐가 잘못된 건지 모르겠습니다.

다시 인터넷에서 터보 어셈블러의 매뉴얼을 구해서 "Illegal immediate"에 대해서 찾아 보았습니다.
도움이 안되는군요

이젠 맨땅에 헤딩하기...트라이얼 앤 에러...시행착오...

일단 의심스러운 SlotLen을 지워 봤습니다.

startup.asm은 컴파일 성공입니다. 그러니까 SlotLen이 문제라는 의미군요.

혹시나 []안에서 덧셈이 문제일지도 모르니 상수로 더했을 경우엔?

역시 덧셈은 문제 없습니다. SlotLen이 문제임이 더 확실해 집니다.

만약에 SlotLen 하나면 쓴다면?

역시 안됩니다. 결론은 SlotLen

하지만 어떻게 해야 할까요?
SlotLen을 무시할 수는 없고, 값의 의미와 변경여부를 따져서 상수로 대체하거나 다른 레지스터를 사용할 수도 있겠지만 무언가 방법이 있지 않겠냐 싶습니다.
터보 어셈블러에 종속적인 표기 방법의 문제처럼 보이니까요...

몇줄 위에 보이는 것처럼 offset을 붙여보았습니다.

소용이 없습니다.

WORD라는 type으로 지정을 해주면 될까요?

안되는군요.

혹시 앞에 ds: 세그먼트 때문일까요?

아니군요. 

좀 기괴하지만 혹시 이건....

역시 안됩니다. 되면 이상한건가요?

이것도 기괴하지만 매뉴얼에서 얼핏 본 표기방법의 변형

안되구요.

역시 매뉴얼에서 얼핏 본 표기방법의 변형 2번째

마찬가지로 안됩니다.

혹시나 해서 어디서 많이 본 듯한 식으로 고쳐 보았습니다.

헐...되네요.

그럼 원래의 소스와 의미가 맞도록 고쳐서는...

역시 됩니다.

실제로 저렇게 표기했을 때, 실행시에도 정말 같은 효과가 나타나는지는 확인해 봐야하지만 일단은 방법을 찾았습니다.
의외로 어셈블러에서 이런 부분때문에 어려움을 겪게 되는군요.
오히려 하드웨어적인 부분이나, 인스트럭션과 레지스터의 사용 조건이 어려울거라 생각했는데 말입니다.

잠깐 앞서 수정했던 부분을 조금 더 살펴 보겠습니다.
문제가 되었던 SlotLen이라는 것이 어떻게 사용되는지 살펴보았습니다.

SlotLen이 선언된 부분

SlotLen이 사용된 곳은 여기가 전부입니다. 단 2줄.
음... 잘은 모르겠지만 SlotPrg의 길이를 보관하는게 SlotLen이구요,
하나는 C700h에 SlotPrg를 복사할 때 길이를 세는 용도로 SlotLen이 사용되구,
또 하나는 C700h에 복사한 SlotPrg의 다음에 값을 넣을 때 SlotPrg의 길이를 더해주는 용도로 SLotLen을 사용합니다.
결국 SlotLen은 SlotPrg의 길이를 보관하는, 그 값이 바뀌지 않는 상수입니다.
만일 앞서 수정한 부분에서 문제가 생긴다면 상수 9로 대체해도 되지 않을까 싶습니다.

마지막으로 앞에서 수정했던 WORD PTR과 mov에 대한, 터보 어셈블러의 퀵 레퍼런스 가이드의 내용을 참고 삼아 소개하는 것으로 이번 포스팅을 마치겠습니다.

그런데 WORD와 WORD PTR이 뭐가 다른걸까요?