구석에 짱박혀 있던 NDS를 발견하고 간만에 게임을 좀 해봤습니다. 작년 이맘때쯤 후배들과 작당해서 샀던 NDS인데… 사실 게임보다는 홈브루 만드는데 더 많이 썼군요. ㅎㅎ 그때는 밤이 새도록 홈브루를 만들었는데…  ^^;;; 그때 만든 NDS 홈브루는 http://kkamagui.tistory.com/category/NDS%20홈브루(Homebrew) 에서 보실 수 있습니다.

근래 PSP만 하다가 NDS를 하니 느낌이 많이 다르네요. 그때는 몰랐는데 역시 캐주얼한 게임은 NDS가 쵝오인 것 같습니다. PSP는 게임이 굉장히 화려하지만 뭐랄까요… 잠깐 잠깐 즐기기에는 좀… ^^;;; 그런 부분이 있더군요.

아아~ 이거 또 게임만 죽어라 하는 거 아닌가 모르겠습니다(설마?). 여튼 NDS 만세~!!!

 아이쿠... 원래 계획은 좀 더 진도를 나가는 거였는데... 그 동안 무리를 좀 했더니 저녁에 잠깐 졸았습니다. 한 40분 잤으니 존거 치고는 시간이 좀 길군요. ^^;;;; 아무리 피곤해도 존적은 별로 없는데... 몸이 좀 피곤하긴 한가 봅니다. 그러거나 말거나 할꺼는 해야하니 세수 한판하고 또 진도 나갔습니다.

 일단 어제 대충 만든 테트리스를 좀 수정해서 블럭 색깔하고, 내부 알고리즘을 좀 정리했습니다. 원래 테트리스가 그리 복잡한 알고리즘이 필요없는 게임이라... 알고리즘이라는 말을 쓰기도 부끄럽습니다만... ㅡ_ㅡa... 발로 짜다보니 도저히 안되겠더군요. ㅎㅎ 내일쯤 정리되면 한번 올리겠습니다. ^^;;;;

 테트리스를 수정한 뒤에 한참을 고민했습니다. 이제 더 뭘 구현해야 하는가.... 가만히 보니 3개 정도가 더 남았더군요. 디지털 시계, 텍스트 뷰어, 이미지 뷰어 정도 남았던데... 디지털 시계는 텍스트로 날짜와 시간만 표시해줄 생각이니 크게 어렵지는 않을 것 같고... 텍스트 뷰어는 말 그대로 뷰어니까 그냥 텍스트만 출력해주면되니 이것도 별로 어렵지 않을 것 같았습니다.

 그렇다면 남은 것은 이미지 뷰어인데, 어떤 파일 포맷을 사용할 것인가가 문제더군요. 가장 쉽게 처리할 수 있는게 BMP 파일 형식인데... BMP도 다양한 버전이 있기 때문에 어떤걸 해야할지 고민이 됬습니다. 그러다가 문득 NDS 홈브루를 개발할때 만들었던 KNG(kkamagui NDS Graphic) 파일 포맷이 생각나서 그걸 사용하기로 했습니다. NDS 홈브루도 16bit Color로 설정되어있고, 마침 지금 만드는 OS도 16bit Color로 설정되어있으니 큰 수정없이 사용할 수 있을 것 같았습니다. KNG를 사용하는 NDS 홈브루는 http://kkamagui.tistory.com/49http://kkamagui.tistory.com/468 에서 보실 수 있습니다.


 위의 화면은 수정된 테트리스와 그 뒤로 이미지 뷰어가 실행된 화면입니다. 이미지는 KNG로 변환해서 OS에 시리얼로 전송하는 방식으로 했습니다. KNG를 사용한 덕분에 작업이 상당히 빨리 끝났습니다. ^^;;; 이것 저것 많이 만들다보니 이런 날도 오는군요~ 좋구로 ㅎㅎ

 작업을 진행하면서 느끼는 QEMU의 장점은 TCPIP로 가상 시리얼을 연결할 수 있어서 굉장히 편리하게 시리얼 통신을 할 수 있는 점입니다. 속도도 굉장히 빠르고 QEMU 내부적으로 버퍼 관리도 해주니 OS에서 구현된 허접한 시리얼 드라이버로도 잘 됩니다. 덕분에 귀찮은 작업이 얼마나 줄었는지... ㅠㅠ)-b QEMU 만세~!!!

 아아... 벌써 또 시간이 이렇게 됬군요. ㅠㅠ 언제쯤 일찍 자려나... 그러려면 집에 굉징히 일찍오던지... 아니면 컴퓨터를 안켜야하는데, 둘다 실현 가능성이 낮군요. ㅠㅠ 거의 다 완료될때까지 잠을 줄이는 수 밖에는 없을 것 같습니다. 아흑....

 그럼 다들 좋은 밤 되세요. ^^)/~

ps) 헛... 이런 잠결에 만들다보니 화면에 있는 이미지 뷰어에 스펠링이 틀렸군요. 이런 ㅠㅠ

공지사항
많은 분들이 닌텐도 DS용 한글 입력 메모장을 쓰고 계시는데,
주의사항이 있어서 알려드립니다.

한글 입력 메모장은 기존 버전과 호환성을 위해 한 페이지에 쓸 수 있는 글 량이 제한되어 있습니다.
스크롤이 없는 이전 버전은 쓸 수 있는 최대 길이가 한 페이지를 꽉 채우는 정도 였습니다.

따라서 한글로 가득 채운다면 220자 정도, 영문으로 가득 채운다면 440자 정도가 최대이니

적당히 채우시고(?) 다음 페이지로 이동하시기 바랍니다. ㅠㅠ

나중에 시간이 나면 업데이트할 때 이를 표시해주는 기능을 넣을 예정이니
불편하시더라도 주의해서 쓰시기 바랍니다.


 드디어 닌텐도 DS(NDS)용 한글 입력 메모장 프로그램 v1.2가 나왔습니다. 많은 분들이 건의하셨던 커서 이동 기능과 메모 스크롤 기능이 추가되었습니다. 이제 메모를 수정하기위해 전체를 수정하지 않아도 됩니다. ^^)/~

 데이터 파일은 기존의 1.1 버전과 호환되므로 NDS 파일만 교체하시면 정상적으로 수행됩니다. ^^
사용자 삽입 이미지

 다만 에디트 박스 컨트롤이 완전하지가 않아서 커서 이동 시에 한글 처리가 미흡합니다. ^^;;; 그 때문에 한글을 삭제하실 때 주의하실 점이 있습니다.

 1. 한글을 지우실 때 커서를 한글 뒤쪽에 위치시킨다음 백스페이스를 2번 눌러주셔야합니다. 만약 한번만 누르시면 글자가 깨어집니다. 깨어졌을 경우 한번 더 백스페이스를 눌러주시면 정상적으로 표시됩니다.

 2. 커서가 한글의 가운데에 위치했을 때 백스페이스를 누르시면 역시 글자가 깨어집니다. 물론 이때 커서를 오른쪽으로 한칸 이동한 다음 다시 백스페이스를 누르면 깨끗하게 지워집니다.

 한글이 원래 2자리를 차지하기때문에 발생하는 문제인데, 다음 버전에 수정할 계획입니다. 급히 릴리즈하느라 소프트웨어 리셋 부분 또한 완전히 처리하지 못했는데, 다음 버전에 같이 수정하여 릴리즈하겠습니다. ^^;;;

 아래는 홈브루 파일입니다.
DLDI 패치는 필수입니다 ^^ http://kkamagui.tistory.com/469 를 참고하세요 ^^;;


================ Version History ================
Version 1.2 - http://kkamagui.tistory.com/468 참고
1. 커서 표시 및 이동 기능 : 내용을 수정하려면 백스페이스를 이용해서 데이터를 모두 지웠던 불편함 때문에 추가. 윈도우의 에디트박스와 같이 커서를 표시하고 커서 위치를 통해 추가/수정/삭제하도록 변경함. 커서 이동은 왼쪽 방향키로 가능
2. 메모장 스크롤 기능 : 메모를 최대 한 페이지까지 밖에 입력하지 못했던 불편함 때문에 추가. 커서를 이용해서 스크롤 가능하도록 변경함


Version 1.1 - http://kkamagui.tistory.com/410 참고
1. 소프트웨어 리셋 기능 : "START" 버튼을 클릭하여 펌웨어 시작화면으로 돌아가는 기능 추가. 파워를 껏다가 켜야했던 기존의 불편함을 줄임
2. TXT 추가 기능 : 메모 페이지에서 "A"버튼을 누르면 루트 디렉토리에 DATA + 페이지번호 +.txt 형식으로 txt 파일을 생성. PC에서 데이터 파일 공유 가능
사용자 삽입 이미지
3. 메모 페이지 확장 : 메모장의 페이지를 40 페이지를 확장. 기존의 20 페이지용 데이터 파일의 경우, 안전한 사용을 위해 모든 데이터를 백업해 놓고 루트 디렉토리에 있는 NOTEDATA.DAT 파일을 삭제하길 권장

Version 1.0 - http://kkamagui.tistory.com/238 참고
1. 완성형 한글/영문/숫자 입력 기능 : 완성형 한글 오토마타를 이용하여 한글 조합 및 출력 가능. 실제 키보드와 거의 동일하게 자판을 배열하고 구성함. Shift 키와 Delete 키를 지원하고 Space바 좌측의 모드 변환 키를 통해서 키보드의 타입 변경 가능.
2. 메모 입력 기능 : 1줄당 최대 영문 42자 or 한글 21자 입력 가능. 최대 10줄까지 입력가능.
3. 메모 페이지 이동 기능 : 메모 페이지를 최대 20장까지 지원. 키보드 상단의 "<<" or ">>" 버튼으로 메모 페이지 이동가능. 최상단에 현재 페이지 번호 표시.
4. 메모 내용 저장 기능 : 페이지 이동 시 or ""저장" 버튼 클릭 시 메모를 저장하는 기능. NDS 재시작 후에도 이전 메모 기록 확인 가능


 버그는 블로그의 덧글로 부탁드립니다. ^^)/~

 그럼 좋은 하루 되세요 ^^)/~


 ㅜ_ㅜ... 한시간 내내 여자친구랑 디자인했습니다. 어찌 될지는 모르겠지만 좀더 손 본 다음에 올리겠습니다. ㅜ_ㅜ)/~

 화면 구성만 한시간 내내 했네요. ㅜ_ㅜ... 천지 이런... 흑흑... ㅜ_ㅜ

 왠지 허무한듯한... ㅠ_ㅠ 아우...

사용자 삽입 이미지



 드디어 새로 만든 에디트 박스를 한글 입력 메모장 홈브루에 적용했습니다. 기본적인 기능은 1.1 버전과 거의 동일하니 기본 기능에 대한 내용은 http://kkamagui.tistory.com/410 을 참고하시면 됩니다.

 아래 화면에서 붉은 색으로 표시된 것이 커서이고, NDS의 왼쪽 방향키를 이용해서 움직일 수 있습니다. 물론 스크롤 또한 가능합니다. ^^)/~
사용자 삽입 이미지


 
주의해야 할 것은 삭제 단위가 한글 단위가 아닌 영어 단위라서 한글을 삭제할 때는 2번 Backspace를 눌러줘야 한다는 것입니다. 한번만 누르실 경우, 이상한 글자가 표시되는데 당황하지 마시고 한번 더 누르시면 깨끗하게 지워집니다.

 지울 부분의 데이터를 분석해서 한글이면 2자를 지우게 하는 것도 가능하지만 커서의 위치와 밀접한 관련이 있어서 손보기가 쉽지 않더군요. ㅜ_ㅜ 일단 어느 정도 안정화된 뒤에 처리할 생각입니다. ^^;;;

 현재 테스트 버전에서는 입력 한계가 없으나 저장할 때 잘려서 저장되니 너무 많이 입력하시면... 잘려서 나올지도... ㅜ_ㅜ;;;;

 혹시 버그가 있으면 덧글로 제보 부탁드립니다. ^^)/~
 그럼 좋은 하루 되세요 ;)



 원래 계획은 오늘 NDS로 포팅을 시작하는 것이었는데, 시험을 치다보니 시간이 늦어서 결국 포기했습니다. ㅜ_ㅜ 요즘 잠도 잘 못자서 얼굴이 뒤집어졌는데, 포팅을 시작하게 되면 끝날 때까지 안잘 것 같아서... ^^;;;

 대신 어느 정도 완성된 에디트 박스(Edit Box)를 올립니다. Version은 아직 버그가 좀 있을 수 있기 때문에 0.9로 했습니다. ^^ 아래는 직접 키보드를 이용해서 메모를 변경하고 추가한 화면입니다.
사용자 삽입 이미지 사용자 삽입 이미지

 방향키로 커서 이동이 가능하고 키보드로 알파벳, 스페이스, 엔터 그리고 백스페이스를 사용할 수 있습니다.

 내일까지 테스트 해본 후에 큰 버그가 없으면 함수 좀 정리해서 NDS에 포팅해야겠습니다. ^^)/~ 별 문제 없이 끝났으면 좋겠네요. ㅎㅎ 이제 커서 이동까지 가능해지면 그동안 빗발쳤던(??) 요구사항을 어느정도 수렴한듯 하니까요. ^^;;;;

 엇~ 벌써 시간이 이렇게나... 이만 자야겠습니다. ^^)/~
 다들 좋은 밤 되세요 >ㅁ<)/~


 휴가를 틈타 NDS 메모장 홈브루를 손보려고 집에 PC 뒤졌는데, 옛날 소스 밖에는 없더군요. ㅜ_ㅜ 그래서 제 스프링노트(http://kkamagui.springnote.com)와 블로그(http://kkamagui.tistory.com)를 검색했더니 역시나... ㅜ_ㅜ

 다른 소스는 다 올려놨으면서 이 소스는 왜 안올려 놓은건지... 하는 수 없이 윈도우 환경에서 구현하기로 했습니다. NDS를 하다말고 갑자기 왠 윈도우냐 하시는 분이 계실지 모르겠습니다. ^^;;;
 
 NDS용 메모장 홈브루는 제가 틈틈이 만든 NDS 윈도우 라이브러리(http://kkamagui.tistory.com/37)를 기반으로 작성되었기 때문에, 윈도우 환경(MFC)과 매우 유사하기 때문에 가능한 것이지요. 개발을 편하게 진행하기 위해서 필요한 부분만 최대한 비슷하게 구현했습니다.

 현재 커서와 데이터 출력, 스크롤 부분까지 처리가 끝났고 이제 남은 것은 커서가 있는 부분을 위주로 추가/수정/삭제하는 부분만 추가하면 되는데... NDS의 한정된 메모리를 사용해야 하기 때문에, 어떻게 하는 것이 좋을지 상당히 고민스럽습니다. 일단은 좀 더 생각해봐야겠습니다. ^^;;;;

 아래는 실제 구현된 에디트 박스의 모습입니다. 글자 사이에 있는 빨간 선이 커서를 나타내고 제일 바깥쪽에 있는 붉은 색 선은 NDS의 LCD 영역을 나타냅니다.

사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지


 


























 아래에 첨부된 압축파일을 풀어서 실행하면 간단한 테스트 해볼 수 있으니, 심심하시면 한번... ^^)/~ 키보드의 화살표 키로 커서를 이동할 수 있으며, 그에 따른 커서 위치 처리와 스크롤에 관한 처리를 테스트 할 수 있습니다. ^^


 아아~ 생각보다 진도가 안나가는 군요. ㅜ_ㅜ)/~
 그럼 다들 좋은 밤 되시길~



 대박 연휴를 맞아 집에 내려오게됬습니다. 집에서 인터넷으로 열차시간을 확인한 뒤, 역으로 왔더니 고새 매진이더군요. ㅡ_ㅡa... 어쩔 수 없어 한시간 뒤 기차를 예매하고 서점으로 갔습니다. 역에 갈때마다 한번씩 들리는 버릇이 생겼거든요. ^^;;;;

 제일 먼저 마이크로소프트웨어 5월호를 들었습니다. 하는 일이 응용 프로그램과 거리가 멀다보니, 위쪽(?) 소식이 많이 궁금합니다(좋은 소식 덧글로 많이 전해주세요 ㅜ_ㅜ...). 마소 기사 목록을 죽 훓어보다보니 블로그 관리를 위한 툴에 대한 기사가 있던데, 갑자기 뭔가 번득하더군요. @0@)/~

 블로그에 수시로 들러서 글쓰고 답글을 달지만, "블로그"에서 그 일을 해야한다는 고정관념 같은게 있었습니다. ㅡ_ㅡa. 그런데 저 기사 제목을 보고 나니 당장 툴을 만들어야겠다는 생각이 들더군요. 일일이 덧글 목록을 살펴서 답글을 달다보면 보지 못하고 넘어가는 덧글이 종종있거든요. ^^;;;;(혹시 제가 덧글에 답글을 달지 않았다면, 이 자리를 빌어 죄송하다는 말씀을 드립니다. (__) 일부러 안단게 아니니 용서해주세요 ㅜ_ㅜ)

 연휴 기간에 덧글을 검색하는 테스트 프로그램부터 간단히 만들어볼까 생각중입니다. Python으로 만들면 간단히 할 수 있을 듯도 한데, 원체 오래되서 기억이 가물가물하네요. ^^;;; 이번에는 OpenAPI를 사용해서 덧글 리스트를 뽑아봐야겠습니다. ^^)/~

 그리고 이전에 만들었던 NDS용 한글 메모장(http://kkamagui.tistory.com/410)PSP에 포팅할까 생각중인데, 그 이전에 한글 메모장부터 손볼 생각입니다. 메모장의 가장 큰 문제였던 커서 이동이 안되는 부분을 방향키를 이용해서 이동할 수 있도록 할까 합니다. 물론 커서도 추가해야겠지요. ^^)/~

 연휴에 푹 쉬나 했더니 이번 연휴도 바쁘겠군요. ^^)/~ 역시 천성이 개발자인듯 합니다. ㅎㅎ
 그럼 다들 좋은밤 되시길~ ^^

 얼마전에 제 블로그에 태용님께서 조그만 선물을 해주시겠다는 댓글을 남기셨습니다. 재미있는 장난감이라고 하시길래, 게임 시디나 괜찮은 셈플 어플리케이션이겠거니 생각하고 있었는데.... NDS용 닥터를... 그것도 무려 3종류나 기부해 주셨습니다. 태용님께서 홈브루 개발자를 지원하는 프로젝트를 진행하시는데, 제가 거기에 포함된 모양입니다. ㅜ_ㅜ... 이런 영광이.... ㅜ_ㅜ

 아래는 기부해주신 닥터의 사진입니다. DSTT, Acekard2, Acekard R.P.G 3종류입니다.
사용자 삽입 이미지
사용자 삽입 이미지
사용자 삽입 이미지

 제가 쓴 글이 다른 분에게 도움이 되고, 그걸로 인해 제가 다시 도움을 받게 될 줄은 몰랐습니다. 왠지 얼떨떨한 기분이군요. ^^;;;; 뭐랄까... 마치 외국에서만 가능할꺼라고 생각했던 일이 저한테 닥치니... 기분이 굉장히 좋습니다. 안그래도 가지고 있는 구형 NDS에 오래된 M3 SD가 달려있어서 동생이 고생하곤했는데, 이제는 그럴 일이 없겠군요. ^^)/~

 태용님께서 기부해주신 닥터는 더 열심히 개발하고, 홈브루 릴리즈할 때 테스트를 열심히 하라는 뜻인 것 같습니다(맞는가요? ㅎㅎ ^^;;;;). 열심히 하겠습니다. >ㅁ<)/~ 그리고 나중에 시간나면 제가 갖고있는 닥터와 비교해서 리뷰도 하나 쓰겠습니다.

 마지막으로 얼굴도 모르는 저에게 이런 멋진 선물을 주신 태용님께 다시 한번 깊은 감사를 드립니다. ^ㅡ^)/~

 그럼 다들 좋은밤 되세요~


 블로그를 돌다가 Firejun님의 블로그(http://firejune.com/1306)에서 재미있는 글을 봤습니다. 바로 아이폰과 아이팟 터치용 드럼 홈브루입니다. 밤늦은 새벽에 졸면서 봤는데, 보는 순간 잠이 확 깨더군요.




 홈브루를 유심히 보니, NDS로도 간단히 만들 수 있을 것 같습니다. NDS도 역시 터치 패널을 가지고 있으니 드럼 소리만 잘 추출해서 저장하면 그 뒤에 연결하는 것은 어렵지 않거든요. ^^;;;; 주말에 시간을 조금 할애해서 테스트용으로 하나 만들어 봐야겠습니다. ^^)/~

 그럼 좋은 밤 되시길~ ;)

 테스트용으로 만든 한글 입력 메모장에 대해서 많은 분들의 문의가 있으셔서, 오늘 드디어 구석에 박아두었던 소스를 꺼냈습니다. 일단 전체적인 수정을 하기 보다는 많은 분이 필요로 하셨던 TXT 저장 기능과 리셋기능을 먼저 추가했습니다. ^^

 대부분의 기능은 기존의 1.0 버전(http://kkamagui.tistory.com/238)과 크게 차이가 없습니다. 특별히 이번에 추가된 기능만 나열하면 아래와 같습니다.
1. 소프트웨어 리셋 기능 : "START" 버튼을 클릭하여 펌웨어 시작화면으로 돌아가는 기능 추가. 파워를 껏다가 켜야했던 기존의 불편함을 줄임
2. TXT 추가 기능 : 메모 페이지에서 "A"버튼을 누르면 루트 디렉토리에 DATA + 페이지번호 +.txt 형식으로 txt 파일을 생성. PC에서 데이터 파일 공유 가능
사용자 삽입 이미지
3. 메모 페이지 확장 : 메모장의 페이지를 40 페이지를 확장. 기존의 20 페이지용 데이터 파일의 경우, 안전한 사용을 위해 모든 데이터를 백업해 놓고 루트 디렉토리에 있는 NOTEDATA.DAT 파일을 삭제하길 권장

 아래는 실행 화면을 캡쳐한 것입니다.
사용자 삽입 이미지

 추가 요구사항이나 기타 건의사항은 http://kkamagui.tistory.com으로 부탁드립니다. ^^
 그럼 좋은 하루 되세요 >ㅁ<)/~



 틈틈히 만든 닌텐도 DS(이하 NDS)용 한글 입력기와 간단한 메모장 프로그램을 공개합니다. 생각보다 일이 많아서 릴리즈가 조금 늦어졌습니다. NDS용 홈브루(Homebrew)는 많이 있습니다만, 한글 입력이 가능한 홈브루가 없어서 만들어야겠다고 생각만하다가 이제서야 만들었네요. ^^;;;

 프로그램은 아래와 같이 최상단의 페이지 번호와 그 아래의 메모입력 화면, 마지막으로 한글/영문/숫자 키보드로 이루어져있습니다. NDS의 듀얼 스크린의 장점이 여기서 나오더군요. ^^
사용자 삽입 이미지

사용자 삽입 이미지 사용자 삽입 이미지

 이 프로그램이 제공하는 기능은 아래와 같습니다.
1. 완성형 한글/영문/숫자 입력 기능 : 완성형 한글 오토마타를 이용하여 한글 조합 및 출력 가능. 실제 키보드와 거의 동일하게 자판을 배열하고 구성함. Shift 키와 Delete 키를 지원하고 Space바 좌측의 모드 변환 키를 통해서 키보드의 타입 변경 가능.
2. 메모 입력 기능 : 1줄당 최대 영문 42자 or 한글 21자 입력 가능. 최대 10줄까지 입력가능.
3. 메모 페이지 이동 기능 : 메모 페이지를 최대 20장까지 지원. 키보드 상단의 "<<" or ">>" 버튼으로 메모 페이지 이동가능. 최상단에 현재 페이지 번호 표시.
4. 메모 내용 저장 기능 : 페이지 이동 시 or ""저장" 버튼 클릭 시 메모를 저장하는 기능. NDS 재시작 후에도 이전 메모 기록 확인 가능

 프로그램의 기능은 굉장히 간단한데, 글로 쓸려니 길어집니다. ^^ 한번 써보시면 더 쉽게 이해하실 수 있을 겁니다. 아래는 실제 사용하는 동영상입니다.



그럼 좋은하루 되시길~ ^ㅡ^)/~
ps) 아래는 실행파일입니다.


 약 이틀간의 작업끝에 한글 오토마타의 수정을 끝내고 아래와 같은 메모장 프로토타입을 만들었습니다. 이제 상단에 기능 버튼(오늘 일자 표시 및 삭제 기능)만 추가하면 릴리즈해도 괜찮겠군요. 시연 동영상이라도 하나 찍어서 올려야겠습니다. 물론 실행파일도 같이요 ^^)/~
사용자 삽입 이미지

메모장 프로토 타입




 제가 만든 홈브루가 굉장히 많은데, 이번 것 만큼 손이 많이가는 것도 처음인것 같네요. 여튼 진행상태로 보면 오늘 내일 안에 메모장 프로토타입을 완성할 수 있을 것 같습니다. 파일로 저장하고 여러 메모를 관리할 수 있도록 하면 간단한 Todo List 메모용으로 사용해도 되겠네요 ^^;;;

 여유가 좀 된다면 메모 검색화면이나 기타 기능도 넣으면 좋겠는데, 일단 고민을 좀 해봐야겠습니다. 일단은 1차 릴리즈에서 버그가 없는 것이 더 중요하니까요 ^^)/~~


예전에 NDS 한글 출력할때 참고했던 완성형 한글 코드입니다. 이제 확장 완성형으로 가야하는데, 참고삼아 이글루스 블로그에서 옮겨옵니다. ^^

실제 한글코드는 아래와 같이 블럭단위로 나누어서 표시되는데 블럭의 제일 첫 부분 xxx0와 블럭의 가장 마지막 부분 xxxF 부분은 사용하지 않으니 맵핑할때 주의해야 합니다.

사용자 삽입 이미지
한글 코드 배치

아래는 전체 2350자의 코드입니다. ^^

KSC5601-1987 한글코드 총 2350자

자음.... 
----------------- 
ㄱ 0xA4A1    ㄲ 0xA4A2    ㄳ 0xA4A3    ㄴ 0xA4A4    ㄵ 0xA4A5 
ㄶ 0xA4A6    ㄷ 0xA4A7    ㄸ 0xA4A8    ㄹ 0xA4A9    ㄺ 0xA4AA 
ㄻ 0xA4AB    ㄼ 0xA4AC    ㄽ 0xA4AD    ㄾ 0xA4AE    ㄿ 0xA4AF 
ㅀ 0xA4B0    ㅁ 0xA4B1    ㅂ 0xA4B2    ㅃ 0xA4B3    ㅄ 0xA4B4 
ㅅ 0xA4B5    ㅆ 0xA4B6    ㅇ 0xA4B7    ㅈ 0xA4B8    ㅉ 0xA4B9 
ㅊ 0xA4BA    ㅋ 0xA4BB    ㅌ 0xA4BC    ㅍ 0xA4BD    ㅎ 0xA4BE


모음... 
----------------- 
ㅏ 0xA4BF    ㅐ 0xA4C0    ㅑ 0xA4C1    ㅒ 0xA4C2    ㅓ 0xA4C3 
ㅔ 0xA4C4    ㅕ 0xA4C5    ㅖ 0xA4C6    ㅗ 0xA4C7    ㅘ 0xA4C8 
ㅙ 0xA4C9    ㅚ 0xA4CA    ㅛ 0xA4CB    ㅜ 0xA4CC    ㅝ 0xA4CD 
ㅞ 0xA4CE    ㅟ 0xA4CF    ㅠ 0xA4D0    ㅡ 0xA4D1    ㅢ 0xA4D2 
ㅣ 0xA4D3

[#M_== 전체 코드 보기(클릭) ==|== 전체 코드 닫기(클릭) ==|
------------------------------------------------------------------------- 
가 0xB0A1    각 0xB0A2    간 0xB0A3    갇 0xB0A4    갈 0xB0A5     
갉 0xB0A6    갊 0xB0A7    감 0xB0A8    갑 0xB0A9    값 0xB0AA 
갓 0xB0AB    갔 0xB0AC    강 0xB0AD    갖 0xB0AE    갗 0xB0AF 
같 0xB0B0    갚 0xB0B1    갛 0xB0B2    개 0xB0B3    객 0xB0B4 
갠 0xB0B5    갤 0xB0B6    갬 0xB0B7    갭 0xB0B8    갯 0xB0B9 
갰 0xB0BA    갱 0xB0BB    갸 0xB0BC    갹 0xB0BD    갼 0xB0BE 
걀 0xB0BF    걋 0xB0C0    걍 0xB0C1    걔 0xB0C2    걘 0xB0C3 
걜 0xB0C4    거 0xB0C5    걱 0xB0C6    건 0xB0C7    걷 0xB0C8 
걸 0xB0C9    걺 0xB0CA    검 0xB0CB    겁 0xB0CC    것 0xB0CD 
겄 0xB0CE    겅 0xB0CF    겆 0xB0D0    겉 0xB0D1    겊 0xB0D2 
겋 0xB0D3    게 0xB0D4    겐 0xB0D5    겔 0xB0D6    겜 0xB0D7 
겝 0xB0D8    겟 0xB0D9    겠 0xB0DA    겡 0xB0DB    겨 0xB0DC 
격 0xB0DD    겪 0xB0DE    견 0xB0DF    겯 0xB0E0    결 0xB0E1 
겸 0xB0E2    겹 0xB0E3    겻 0xB0E4    겼 0xB0E5    경 0xB0E6 
곁 0xB0E7    계 0xB0E8    곈 0xB0E9    곌 0xB0EA    곕 0xB0EB 
곗 0xB0EC    고 0xB0ED    곡 0xB0EE    곤 0xB0EF    곧 0xB0F0 
골 0xB0F1    곪 0xB0F2    곬 0xB0F3    곯 0xB0F4    곰 0xB0F5 
곱 0xB0F6    곳 0xB0F7    공 0xB0F8    곶 0xB0F9    과 0xB0FA 
곽 0xB0FB    관 0xB0FC    괄 0xB0FD    괆 0xB0FE    괌 0xB1A1 
괍 0xB1A2    괏 0xB1A3    광 0xB1A4    괘 0xB1A5    괜 0xB1A6 
괠 0xB1A7    괩 0xB1A8    괬 0xB1A9    괭 0xB1AA    괴 0xB1AB 
괵 0xB1AC    괸 0xB1AD    괼 0xB1AE    굄 0xB1AF    굅 0xB1B0 
굇 0xB1B1    굉 0xB1B2    교 0xB1B3    굔 0xB1B4    굘 0xB1B5 
굡 0xB1B6    굣 0xB1B7    구 0xB1B8    국 0xB1B9    군 0xB1BA 
굳 0xB1BB    굴 0xB1BC    굵 0xB1BD    굶 0xB1BE    굻 0xB1BF 
굼 0xB1C0    굽 0xB1C1    굿 0xB1C2    궁 0xB1C3    궂 0xB1C4 
궈 0xB1C5    궉 0xB1C6    권 0xB1C7    궐 0xB1C8    궜 0xB1C9 
궝 0xB1CA    궤 0xB1CB    궷 0xB1CC    귀 0xB1CD    귁 0xB1CE 
귄 0xB1CF    귈 0xB1D0    귐 0xB1D1    귑 0xB1D2    귓 0xB1D3 
규 0xB1D4    균 0xB1D5    귤 0xB1D6    그 0xB1D7    극 0xB1D8 
근 0xB1D9    귿 0xB1DA    글 0xB1DB    긁 0xB1DC    금 0xB1DD 
급 0xB1DE    긋 0xB1DF    긍 0xB1E0    긔 0xB1E1    기 0xB1E2 
긱 0xB1E3    긴 0xB1E4    긷 0xB1E5    길 0xB1E6    긺 0xB1E7 
김 0xB1E8    깁 0xB1E9    깃 0xB1EA    깅 0xB1EB    깆 0xB1EC 
깊 0xB1ED    까 0xB1EE    깍 0xB1EF    깎 0xB1F0    깐 0xB1F1 
깔 0xB1F2    깖 0xB1F3    깜 0xB1F4    깝 0xB1F5    깟 0xB1F6 
깠 0xB1F7    깡 0xB1F8    깥 0xB1F9    깨 0xB1FA    깩 0xB1FB 
깬 0xB1FC    깰 0xB1FD    깸 0xB1FE    깹 0xB2A1    깻 0xB2A2 
깼 0xB2A3    깽 0xB2A4    꺄 0xB2A5    꺅 0xB2A6    꺌 0xB2A7 
꺼 0xB2A8    꺽 0xB2A9    꺾 0xB2AA    껀 0xB2AB    껄 0xB2AC 
껌 0xB2AD    껍 0xB2AE    껏 0xB2AF    껐 0xB2B0    껑 0xB2B1 
께 0xB2B2    껙 0xB2B3    껜 0xB2B4    껨 0xB2B5    껫 0xB2B6 
껭 0xB2B7    껴 0xB2B8    껸 0xB2B9    껼 0xB2BA    꼇 0xB2BB 
꼈 0xB2BC    꼍 0xB2BD    꼐 0xB2BE    꼬 0xB2BF    꼭 0xB2C0 
꼰 0xB2C1    꼲 0xB2C2    꼴 0xB2C3    꼼 0xB2C4    꼽 0xB2C5 
꼿 0xB2C6    꽁 0xB2C7    꽂 0xB2C8    꽃 0xB2C9    꽈 0xB2CA 
꽉 0xB2CB    꽐 0xB2CC    꽜 0xB2CD    꽝 0xB2CE    꽤 0xB2CF 
꽥 0xB2D0    꽹 0xB2D1    꾀 0xB2D2    꾄 0xB2D3    꾈 0xB2D4 
꾐 0xB2D5    꾑 0xB2D6    꾕 0xB2D7    꾜 0xB2D8    꾸 0xB2D9 
꾹 0xB2DA    꾼 0xB2DB    꿀 0xB2DC    꿇 0xB2DD    꿈 0xB2DE 
꿉 0xB2DF    꿋 0xB2E0    꿍 0xB2E1    꿎 0xB2E2    꿔 0xB2E3 
꿜 0xB2E4    꿨 0xB2E5    꿩 0xB2E6    꿰 0xB2E7    꿱 0xB2E8 
꿴 0xB2E9    꿸 0xB2EA    뀀 0xB2EB    뀁 0xB2EC    뀄 0xB2ED 
뀌 0xB2EE    뀐 0xB2EF    뀔 0xB2F0    뀜 0xB2F1    뀝 0xB2F2 
뀨 0xB2F3    끄 0xB2F4    끅 0xB2F5    끈 0xB2F6    끊 0xB2F7 
끌 0xB2F8    끎 0xB2F9    끓 0xB2FA    끔 0xB2FB    끕 0xB2FC 
끗 0xB2FD    끙 0xB2FE    끝 0xB3A1    끼 0xB3A2    끽 0xB3A3 
낀 0xB3A4    낄 0xB3A5    낌 0xB3A6    낍 0xB3A7    낏 0xB3A8 
낑 0xB3A9    나 0xB3AA    낙 0xB3AB    낚 0xB3AC    난 0xB3AD 
낟 0xB3AE    날 0xB3AF    낡 0xB3B0    낢 0xB3B1    남 0xB3B2 
납 0xB3B3    낫 0xB3B4    났 0xB3B5    낭 0xB3B6    낮 0xB3B7 
낯 0xB3B8    낱 0xB3B9    낳 0xB3BA    내 0xB3BB    낵 0xB3BC 
낸 0xB3BD    낼 0xB3BE    냄 0xB3BF    냅 0xB3C0    냇 0xB3C1 
냈 0xB3C2    냉 0xB3C3    냐 0xB3C4    냑 0xB3C5    냔 0xB3C6 
냘 0xB3C7    냠 0xB3C8    냥 0xB3C9    너 0xB3CA    넉 0xB3CB 
넋 0xB3CC    넌 0xB3CD    널 0xB3CE    넒 0xB3CF    넓 0xB3D0 
넘 0xB3D1    넙 0xB3D2    넛 0xB3D3    넜 0xB3D4    넝 0xB3D5 
넣 0xB3D6    네 0xB3D7    넥 0xB3D8    넨 0xB3D9    넬 0xB3DA 
넴 0xB3DB    넵 0xB3DC    넷 0xB3DD    넸 0xB3DE    넹 0xB3DF 
녀 0xB3E0    녁 0xB3E1    년 0xB3E2    녈 0xB3E3    념 0xB3E4 
녑 0xB3E5    녔 0xB3E6    녕 0xB3E7    녘 0xB3E8    녜 0xB3E9 
녠 0xB3EA    노 0xB3EB    녹 0xB3EC    논 0xB3ED    놀 0xB3EE 
놂 0xB3EF    놈 0xB3F0    놉 0xB3F1    놋 0xB3F2    농 0xB3F3 
높 0xB3F4    놓 0xB3F5    놔 0xB3F6    놘 0xB3F7    놜 0xB3F8 
놨 0xB3F9    뇌 0xB3FA    뇐 0xB3FB    뇔 0xB3FC    뇜 0xB3FD 
뇝 0xB3FE    뇟 0xB4A1    뇨 0xB4A2    뇩 0xB4A3    뇬 0xB4A4 
뇰 0xB4A5    뇹 0xB4A6    뇻 0xB4A7    뇽 0xB4A8    누 0xB4A9 
눅 0xB4AA    눈 0xB4AB    눋 0xB4AC    눌 0xB4AD    눔 0xB4AE 
눕 0xB4AF    눗 0xB4B0    눙 0xB4B1    눠 0xB4B2    눴 0xB4B3 
눼 0xB4B4    뉘 0xB4B5    뉜 0xB4B6    뉠 0xB4B7    뉨 0xB4B8 
뉩 0xB4B9    뉴 0xB4BA    뉵 0xB4BB    뉼 0xB4BC    늄 0xB4BD 
늅 0xB4BE    늉 0xB4BF    느 0xB4C0    늑 0xB4C1    는 0xB4C2 
늘 0xB4C3    늙 0xB4C4    늚 0xB4C5    늠 0xB4C6    늡 0xB4C7 
늣 0xB4C8    능 0xB4C9    늦 0xB4CA    늪 0xB4CB    늬 0xB4CC 
늰 0xB4CD    늴 0xB4CE    니 0xB4CF    닉 0xB4D0    닌 0xB4D1 
닐 0xB4D2    닒 0xB4D3    님 0xB4D4    닙 0xB4D5    닛 0xB4D6 
닝 0xB4D7    닢 0xB4D8    다 0xB4D9    닥 0xB4DA    닦 0xB4DB 
단 0xB4DC    닫 0xB4DD    달 0xB4DE    닭 0xB4DF    닮 0xB4E0 
닯 0xB4E1    닳 0xB4E2    담 0xB4E3    답 0xB4E4    닷 0xB4E5 
닸 0xB4E6    당 0xB4E7    닺 0xB4E8    닻 0xB4E9    닿 0xB4EA 
대 0xB4EB    댁 0xB4EC    댄 0xB4ED    댈 0xB4EE    댐 0xB4EF 
댑 0xB4F0    댓 0xB4F1    댔 0xB4F2    댕 0xB4F3    댜 0xB4F4 
더 0xB4F5    덕 0xB4F6    덖 0xB4F7    던 0xB4F8    덛 0xB4F9 
덜 0xB4FA    덞 0xB4FB    덟 0xB4FC    덤 0xB4FD    덥 0xB4FE 
덧 0xB5A1    덩 0xB5A2    덫 0xB5A3    덮 0xB5A4    데 0xB5A5 
덱 0xB5A6    덴 0xB5A7    델 0xB5A8    뎀 0xB5A9    뎁 0xB5AA 
뎃 0xB5AB    뎄 0xB5AC    뎅 0xB5AD    뎌 0xB5AE    뎐 0xB5AF 
뎔 0xB5B0    뎠 0xB5B1    뎡 0xB5B2    뎨 0xB5B3    뎬 0xB5B4 
도 0xB5B5    독 0xB5B6    돈 0xB5B7    돋 0xB5B8    돌 0xB5B9 
돎 0xB5BA    돐 0xB5BB    돔 0xB5BC    돕 0xB5BD    돗 0xB5BE 
동 0xB5BF    돛 0xB5C0    돝 0xB5C1    돠 0xB5C2    돤 0xB5C3 
돨 0xB5C4    돼 0xB5C5    됐 0xB5C6    되 0xB5C7    된 0xB5C8 
될 0xB5C9    됨 0xB5CA    됩 0xB5CB    됫 0xB5CC    됴 0xB5CD 
두 0xB5CE    둑 0xB5CF    둔 0xB5D0    둘 0xB5D1    둠 0xB5D2 
둡 0xB5D3    둣 0xB5D4    둥 0xB5D5    둬 0xB5D6    뒀 0xB5D7 
뒈 0xB5D8    뒝 0xB5D9    뒤 0xB5DA    뒨 0xB5DB    뒬 0xB5DC 
뒵 0xB5DD    뒷 0xB5DE    뒹 0xB5DF    듀 0xB5E0    듄 0xB5E1 
듈 0xB5E2    듐 0xB5E3    듕 0xB5E4    드 0xB5E5    득 0xB5E6 
든 0xB5E7    듣 0xB5E8    들 0xB5E9    듦 0xB5EA    듬 0xB5EB 
듭 0xB5EC    듯 0xB5ED    등 0xB5EE    듸 0xB5EF    디 0xB5F0 
딕 0xB5F1    딘 0xB5F2    딛 0xB5F3    딜 0xB5F4    딤 0xB5F5 
딥 0xB5F6    딧 0xB5F7    딨 0xB5F8    딩 0xB5F9    딪 0xB5FA 
따 0xB5FB    딱 0xB5FC    딴 0xB5FD    딸 0xB5FE    땀 0xB6A1 
땁 0xB6A2    땃 0xB6A3    땄 0xB6A4    땅 0xB6A5    땋 0xB6A6 
때 0xB6A7    땍 0xB6A8    땐 0xB6A9    땔 0xB6AA    땜 0xB6AB 
땝 0xB6AC    땟 0xB6AD    땠 0xB6AE    땡 0xB6AF    떠 0xB6B0 
떡 0xB6B1    떤 0xB6B2    떨 0xB6B3    떪 0xB6B4    떫 0xB6B5 
떰 0xB6B6    떱 0xB6B7    떳 0xB6B8    떴 0xB6B9    떵 0xB6BA 
떻 0xB6BB    떼 0xB6BC    떽 0xB6BD    뗀 0xB6BE    뗄 0xB6BF 
뗌 0xB6C0    뗍 0xB6C1    뗏 0xB6C2    뗐 0xB6C3    뗑 0xB6C4 
뗘 0xB6C5    뗬 0xB6C6    또 0xB6C7    똑 0xB6C8    똔 0xB6C9 
똘 0xB6CA    똥 0xB6CB    똬 0xB6CC    똴 0xB6CD    뙈 0xB6CE 
뙤 0xB6CF    뙨 0xB6D0    뚜 0xB6D1    뚝 0xB6D2    뚠 0xB6D3 
뚤 0xB6D4    뚫 0xB6D5    뚬 0xB6D6    뚱 0xB6D7    뛔 0xB6D8 
뛰 0xB6D9    뛴 0xB6DA    뛸 0xB6DB    뜀 0xB6DC    뜁 0xB6DD 
뜅 0xB6DE    뜨 0xB6DF    뜩 0xB6E0    뜬 0xB6E1    뜯 0xB6E2 
뜰 0xB6E3    뜸 0xB6E4    뜹 0xB6E5    뜻 0xB6E6    띄 0xB6E7 
띈 0xB6E8    띌 0xB6E9    띔 0xB6EA    띕 0xB6EB    띠 0xB6EC 
띤 0xB6ED    띨 0xB6EE    띰 0xB6EF    띱 0xB6F0    띳 0xB6F1 
띵 0xB6F2    라 0xB6F3    락 0xB6F4    란 0xB6F5    랄 0xB6F6 
람 0xB6F7    랍 0xB6F8    랏 0xB6F9    랐 0xB6FA    랑 0xB6FB 
랒 0xB6FC    랖 0xB6FD    랗 0xB6FE    래 0xB7A1    랙 0xB7A2 
랜 0xB7A3    랠 0xB7A4    램 0xB7A5    랩 0xB7A6    랫 0xB7A7 
랬 0xB7A8    랭 0xB7A9    랴 0xB7AA    략 0xB7AB    랸 0xB7AC 
럇 0xB7AD    량 0xB7AE    러 0xB7AF    럭 0xB7B0    런 0xB7B1 
럴 0xB7B2    럼 0xB7B3    럽 0xB7B4    럿 0xB7B5    렀 0xB7B6 
렁 0xB7B7    렇 0xB7B8    레 0xB7B9    렉 0xB7BA    렌 0xB7BB 
렐 0xB7BC    렘 0xB7BD    렙 0xB7BE    렛 0xB7BF    렝 0xB7C0 
려 0xB7C1    력 0xB7C2    련 0xB7C3    렬 0xB7C4    렴 0xB7C5 
렵 0xB7C6    렷 0xB7C7    렸 0xB7C8    령 0xB7C9    례 0xB7CA 
롄 0xB7CB    롑 0xB7CC    롓 0xB7CD    로 0xB7CE    록 0xB7CF 
론 0xB7D0    롤 0xB7D1    롬 0xB7D2    롭 0xB7D3    롯 0xB7D4 
롱 0xB7D5    롸 0xB7D6    롼 0xB7D7    뢍 0xB7D8    뢨 0xB7D9 
뢰 0xB7DA    뢴 0xB7DB    뢸 0xB7DC    룀 0xB7DD    룁 0xB7DE 
룃 0xB7DF    룅 0xB7E0    료 0xB7E1    룐 0xB7E2    룔 0xB7E3 
룝 0xB7E4    룟 0xB7E5    룡 0xB7E6    루 0xB7E7    룩 0xB7E8 
룬 0xB7E9    룰 0xB7EA    룸 0xB7EB    룹 0xB7EC    룻 0xB7ED 
룽 0xB7EE    뤄 0xB7EF    뤘 0xB7F0    뤠 0xB7F1    뤼 0xB7F2 
뤽 0xB7F3    륀 0xB7F4    륄 0xB7F5    륌 0xB7F6    륏 0xB7F7 
륑 0xB7F8    류 0xB7F9    륙 0xB7FA    륜 0xB7FB    률 0xB7FC 
륨 0xB7FD    륩 0xB7FE    륫 0xB8A1    륭 0xB8A2    르 0xB8A3 
륵 0xB8A4    른 0xB8A5    를 0xB8A6    름 0xB8A7    릅 0xB8A8 
릇 0xB8A9    릉 0xB8AA    릊 0xB8AB    릍 0xB8AC    릎 0xB8AD 
리 0xB8AE    릭 0xB8AF    린 0xB8B0    릴 0xB8B1    림 0xB8B2 
립 0xB8B3    릿 0xB8B4    링 0xB8B5    마 0xB8B6    막 0xB8B7 
만 0xB8B8    많 0xB8B9    맏 0xB8BA    말 0xB8BB    맑 0xB8BC 
맒 0xB8BD    맘 0xB8BE    맙 0xB8BF    맛 0xB8C0    망 0xB8C1 
맞 0xB8C2    맡 0xB8C3    맣 0xB8C4    매 0xB8C5    맥 0xB8C6 
맨 0xB8C7    맬 0xB8C8    맴 0xB8C9    맵 0xB8CA    맷 0xB8CB 
맸 0xB8CC    맹 0xB8CD    맺 0xB8CE    먀 0xB8CF    먁 0xB8D0 
먈 0xB8D1    먕 0xB8D2    머 0xB8D3    먹 0xB8D4    먼 0xB8D5 
멀 0xB8D6    멂 0xB8D7    멈 0xB8D8    멉 0xB8D9    멋 0xB8DA 
멍 0xB8DB    멎 0xB8DC    멓 0xB8DD    메 0xB8DE    멕 0xB8DF 
멘 0xB8E0    멜 0xB8E1    멤 0xB8E2    멥 0xB8E3    멧 0xB8E4 
멨 0xB8E5    멩 0xB8E6    며 0xB8E7    멱 0xB8E8    면 0xB8E9 
멸 0xB8EA    몃 0xB8EB    몄 0xB8EC    명 0xB8ED    몇 0xB8EE 
몌 0xB8EF    모 0xB8F0    목 0xB8F1    몫 0xB8F2    몬 0xB8F3 
몰 0xB8F4    몲 0xB8F5    몸 0xB8F6    몹 0xB8F7    못 0xB8F8 
몽 0xB8F9    뫄 0xB8FA    뫈 0xB8FB    뫘 0xB8FC    뫙 0xB8FD 
뫼 0xB8FE    묀 0xB9A1    묄 0xB9A2    묍 0xB9A3    묏 0xB9A4 
묑 0xB9A5    묘 0xB9A6    묜 0xB9A7    묠 0xB9A8    묩 0xB9A9 
묫 0xB9AA    무 0xB9AB    묵 0xB9AC    묶 0xB9AD    문 0xB9AE 
묻 0xB9AF    물 0xB9B0    묽 0xB9B1    묾 0xB9B2    뭄 0xB9B3 
뭅 0xB9B4    뭇 0xB9B5    뭉 0xB9B6    뭍 0xB9B7    뭏 0xB9B8 
뭐 0xB9B9    뭔 0xB9BA    뭘 0xB9BB    뭡 0xB9BC    뭣 0xB9BD 
뭬 0xB9BE    뮈 0xB9BF    뮌 0xB9C0    뮐 0xB9C1    뮤 0xB9C2 
뮨 0xB9C3    뮬 0xB9C4    뮴 0xB9C5    뮷 0xB9C6    므 0xB9C7 
믄 0xB9C8    믈 0xB9C9    믐 0xB9CA    믓 0xB9CB    미 0xB9CC 
믹 0xB9CD    민 0xB9CE    믿 0xB9CF    밀 0xB9D0    밂 0xB9D1 
밈 0xB9D2    밉 0xB9D3    밋 0xB9D4    밌 0xB9D5    밍 0xB9D6 
및 0xB9D7    밑 0xB9D8    바 0xB9D9    박 0xB9DA    밖 0xB9DB 
밗 0xB9DC    반 0xB9DD    받 0xB9DE    발 0xB9DF    밝 0xB9E0 
밞 0xB9E1    밟 0xB9E2    밤 0xB9E3    밥 0xB9E4    밧 0xB9E5 
방 0xB9E6    밭 0xB9E7    배 0xB9E8    백 0xB9E9    밴 0xB9EA 
밸 0xB9EB    뱀 0xB9EC    뱁 0xB9ED    뱃 0xB9EE    뱄 0xB9EF 
뱅 0xB9F0    뱉 0xB9F1    뱌 0xB9F2    뱍 0xB9F3    뱐 0xB9F4 
뱝 0xB9F5    버 0xB9F6    벅 0xB9F7    번 0xB9F8    벋 0xB9F9 
벌 0xB9FA    벎 0xB9FB    범 0xB9FC    법 0xB9FD    벗 0xB9FE 
벙 0xBAA1    벚 0xBAA2    베 0xBAA3    벡 0xBAA4    벤 0xBAA5 
벧 0xBAA6    벨 0xBAA7    벰 0xBAA8    벱 0xBAA9    벳 0xBAAA 
벴 0xBAAB    벵 0xBAAC    벼 0xBAAD    벽 0xBAAE    변 0xBAAF 
별 0xBAB0    볍 0xBAB1    볏 0xBAB2    볐 0xBAB3    병 0xBAB4 
볕 0xBAB5    볘 0xBAB6    볜 0xBAB7    보 0xBAB8    복 0xBAB9 
볶 0xBABA    본 0xBABB    볼 0xBABC    봄 0xBABD    봅 0xBABE 
봇 0xBABF    봉 0xBAC0    봐 0xBAC1    봔 0xBAC2    봤 0xBAC3 
봬 0xBAC4    뵀 0xBAC5    뵈 0xBAC6    뵉 0xBAC7    뵌 0xBAC8 
뵐 0xBAC9    뵘 0xBACA    뵙 0xBACB    뵤 0xBACC    뵨 0xBACD 
부 0xBACE    북 0xBACF    분 0xBAD0    붇 0xBAD1    불 0xBAD2 
붉 0xBAD3    붊 0xBAD4    붐 0xBAD5    붑 0xBAD6    붓 0xBAD7 
붕 0xBAD8    붙 0xBAD9    붚 0xBADA    붜 0xBADB    붤 0xBADC 
붰 0xBADD    붸 0xBADE    뷔 0xBADF    뷕 0xBAE0    뷘 0xBAE1 
뷜 0xBAE2    뷩 0xBAE3    뷰 0xBAE4    뷴 0xBAE5    뷸 0xBAE6 
븀 0xBAE7    븃 0xBAE8    븅 0xBAE9    브 0xBAEA    븍 0xBAEB 
븐 0xBAEC    블 0xBAED    븜 0xBAEE    븝 0xBAEF    븟 0xBAF0 
비 0xBAF1    빅 0xBAF2    빈 0xBAF3    빌 0xBAF4    빎 0xBAF5 
빔 0xBAF6    빕 0xBAF7    빗 0xBAF8    빙 0xBAF9    빚 0xBAFA 
빛 0xBAFB    빠 0xBAFC    빡 0xBAFD    빤 0xBAFE    빨 0xBBA1 
빪 0xBBA2    빰 0xBBA3    빱 0xBBA4    빳 0xBBA5    빴 0xBBA6 
빵 0xBBA7    빻 0xBBA8    빼 0xBBA9    빽 0xBBAA    뺀 0xBBAB 
뺄 0xBBAC    뺌 0xBBAD    뺍 0xBBAE    뺏 0xBBAF    뺐 0xBBB0 
뺑 0xBBB1    뺘 0xBBB2    뺙 0xBBB3    뺨 0xBBB4    뻐 0xBBB5 
뻑 0xBBB6    뻔 0xBBB7    뻗 0xBBB8    뻘 0xBBB9    뻠 0xBBBA 
뻣 0xBBBB    뻤 0xBBBC    뻥 0xBBBD    뻬 0xBBBE    뼁 0xBBBF 
뼈 0xBBC0    뼉 0xBBC1    뼘 0xBBC2    뼙 0xBBC3    뼛 0xBBC4 
뼜 0xBBC5    뼝 0xBBC6    뽀 0xBBC7    뽁 0xBBC8    뽄 0xBBC9 
뽈 0xBBCA    뽐 0xBBCB    뽑 0xBBCC    뽕 0xBBCD    뾔 0xBBCE 
뾰 0xBBCF    뿅 0xBBD0    뿌 0xBBD1    뿍 0xBBD2    뿐 0xBBD3 
뿔 0xBBD4    뿜 0xBBD5    뿟 0xBBD6    뿡 0xBBD7    쀼 0xBBD8 
쁑 0xBBD9    쁘 0xBBDA    쁜 0xBBDB    쁠 0xBBDC    쁨 0xBBDD 
쁩 0xBBDE    삐 0xBBDF    삑 0xBBE0    삔 0xBBE1    삘 0xBBE2 
삠 0xBBE3    삡 0xBBE4    삣 0xBBE5    삥 0xBBE6    사 0xBBE7 
삭 0xBBE8    삯 0xBBE9    산 0xBBEA    삳 0xBBEB    살 0xBBEC 
삵 0xBBED    삶 0xBBEE    삼 0xBBEF    삽 0xBBF0    삿 0xBBF1 
샀 0xBBF2    상 0xBBF3    샅 0xBBF4    새 0xBBF5    색 0xBBF6 
샌 0xBBF7    샐 0xBBF8    샘 0xBBF9    샙 0xBBFA    샛 0xBBFB 
샜 0xBBFC    생 0xBBFD    샤 0xBBFE    샥 0xBCA1    샨 0xBCA2 
샬 0xBCA3    샴 0xBCA4    샵 0xBCA5    샷 0xBCA6    샹 0xBCA7 
섀 0xBCA8    섄 0xBCA9    섈 0xBCAA    섐 0xBCAB    섕 0xBCAC 
서 0xBCAD    석 0xBCAE    섞 0xBCAF    섟 0xBCB0    선 0xBCB1 
섣 0xBCB2    설 0xBCB3    섦 0xBCB4    섧 0xBCB5    섬 0xBCB6 
섭 0xBCB7    섯 0xBCB8    섰 0xBCB9    성 0xBCBA    섶 0xBCBB 
세 0xBCBC    섹 0xBCBD    센 0xBCBE    셀 0xBCBF    셈 0xBCC0 
셉 0xBCC1    셋 0xBCC2    셌 0xBCC3    셍 0xBCC4    셔 0xBCC5 
셕 0xBCC6    션 0xBCC7    셜 0xBCC8    셤 0xBCC9    셥 0xBCCA 
셧 0xBCCB    셨 0xBCCC    셩 0xBCCD    셰 0xBCCE    셴 0xBCCF 
셸 0xBCD0    솅 0xBCD1    소 0xBCD2    속 0xBCD3    솎 0xBCD4 
손 0xBCD5    솔 0xBCD6    솖 0xBCD7    솜 0xBCD8    솝 0xBCD9 
솟 0xBCDA    송 0xBCDB    솥 0xBCDC    솨 0xBCDD    솩 0xBCDE 
솬 0xBCDF    솰 0xBCE0    솽 0xBCE1    쇄 0xBCE2    쇈 0xBCE3 
쇌 0xBCE4    쇔 0xBCE5    쇗 0xBCE6    쇘 0xBCE7    쇠 0xBCE8 
쇤 0xBCE9    쇨 0xBCEA    쇰 0xBCEB    쇱 0xBCEC    쇳 0xBCED 
쇼 0xBCEE    쇽 0xBCEF    숀 0xBCF0    숄 0xBCF1    숌 0xBCF2 
숍 0xBCF3    숏 0xBCF4    숑 0xBCF5    수 0xBCF6    숙 0xBCF7 
순 0xBCF8    숟 0xBCF9    술 0xBCFA    숨 0xBCFB    숩 0xBCFC 
숫 0xBCFD    숭 0xBCFE    숯 0xBDA1    숱 0xBDA2    숲 0xBDA3 
숴 0xBDA4    쉈 0xBDA5    쉐 0xBDA6    쉑 0xBDA7    쉔 0xBDA8 
쉘 0xBDA9    쉠 0xBDAA    쉥 0xBDAB    쉬 0xBDAC    쉭 0xBDAD 
쉰 0xBDAE    쉴 0xBDAF    쉼 0xBDB0    쉽 0xBDB1    쉿 0xBDB2 
슁 0xBDB3    슈 0xBDB4    슉 0xBDB5    슐 0xBDB6    슘 0xBDB7 
슛 0xBDB8    슝 0xBDB9    스 0xBDBA    슥 0xBDBB    슨 0xBDBC 
슬 0xBDBD    슭 0xBDBE    슴 0xBDBF    습 0xBDC0    슷 0xBDC1 
승 0xBDC2    시 0xBDC3    식 0xBDC4    신 0xBDC5    싣 0xBDC6 
실 0xBDC7    싫 0xBDC8    심 0xBDC9    십 0xBDCA    싯 0xBDCB 
싱 0xBDCC    싶 0xBDCD    싸 0xBDCE    싹 0xBDCF    싻 0xBDD0 
싼 0xBDD1    쌀 0xBDD2    쌈 0xBDD3    쌉 0xBDD4    쌌 0xBDD5 
쌍 0xBDD6    쌓 0xBDD7    쌔 0xBDD8    쌕 0xBDD9    쌘 0xBDDA 
쌜 0xBDDB    쌤 0xBDDC    쌥 0xBDDD    쌨 0xBDDE    쌩 0xBDDF 
썅 0xBDE0    써 0xBDE1    썩 0xBDE2    썬 0xBDE3    썰 0xBDE4 
썲 0xBDE5    썸 0xBDE6    썹 0xBDE7    썼 0xBDE8    썽 0xBDE9 
쎄 0xBDEA    쎈 0xBDEB    쎌 0xBDEC    쏀 0xBDED    쏘 0xBDEE 
쏙 0xBDEF    쏜 0xBDF0    쏟 0xBDF1    쏠 0xBDF2    쏢 0xBDF3 
쏨 0xBDF4    쏩 0xBDF5    쏭 0xBDF6    쏴 0xBDF7    쏵 0xBDF8 
쏸 0xBDF9    쐈 0xBDFA    쐐 0xBDFB    쐤 0xBDFC    쐬 0xBDFD 
쐰 0xBDFE    쐴 0xBEA1    쐼 0xBEA2    쐽 0xBEA3    쑈 0xBEA4 
쑤 0xBEA5    쑥 0xBEA6    쑨 0xBEA7    쑬 0xBEA8    쑴 0xBEA9 
쑵 0xBEAA    쑹 0xBEAB    쒀 0xBEAC    쒔 0xBEAD    쒜 0xBEAE 
쒸 0xBEAF    쒼 0xBEB0    쓩 0xBEB1    쓰 0xBEB2    쓱 0xBEB3 
쓴 0xBEB4    쓸 0xBEB5    쓺 0xBEB6    쓿 0xBEB7    씀 0xBEB8 
씁 0xBEB9    씌 0xBEBA    씐 0xBEBB    씔 0xBEBC    씜 0xBEBD 
씨 0xBEBE    씩 0xBEBF    씬 0xBEC0    씰 0xBEC1    씸 0xBEC2 
씹 0xBEC3    씻 0xBEC4    씽 0xBEC5    아 0xBEC6    악 0xBEC7 
안 0xBEC8    앉 0xBEC9    않 0xBECA    알 0xBECB    앍 0xBECC 
앎 0xBECD    앓 0xBECE    암 0xBECF    압 0xBED0    앗 0xBED1 
았 0xBED2    앙 0xBED3    앝 0xBED4    앞 0xBED5    애 0xBED6 
액 0xBED7    앤 0xBED8    앨 0xBED9    앰 0xBEDA    앱 0xBEDB 
앳 0xBEDC    앴 0xBEDD    앵 0xBEDE    야 0xBEDF    약 0xBEE0 
얀 0xBEE1    얄 0xBEE2    얇 0xBEE3    얌 0xBEE4    얍 0xBEE5 
얏 0xBEE6    양 0xBEE7    얕 0xBEE8    얗 0xBEE9    얘 0xBEEA 
얜 0xBEEB    얠 0xBEEC    얩 0xBEED    어 0xBEEE    억 0xBEEF 
언 0xBEF0    얹 0xBEF1    얻 0xBEF2    얼 0xBEF3    얽 0xBEF4 
얾 0xBEF5    엄 0xBEF6    업 0xBEF7    없 0xBEF8    엇 0xBEF9 
었 0xBEFA    엉 0xBEFB    엊 0xBEFC    엌 0xBEFD    엎 0xBEFE 
에 0xBFA1    엑 0xBFA2    엔 0xBFA3    엘 0xBFA4    엠 0xBFA5 
엡 0xBFA6    엣 0xBFA7    엥 0xBFA8    여 0xBFA9    역 0xBFAA 
엮 0xBFAB    연 0xBFAC    열 0xBFAD    엶 0xBFAE    엷 0xBFAF 
염 0xBFB0    엽 0xBFB1    엾 0xBFB2    엿 0xBFB3    였 0xBFB4 
영 0xBFB5    옅 0xBFB6    옆 0xBFB7    옇 0xBFB8    예 0xBFB9 
옌 0xBFBA    옐 0xBFBB    옘 0xBFBC    옙 0xBFBD    옛 0xBFBE 
옜 0xBFBF    오 0xBFC0    옥 0xBFC1    온 0xBFC2    올 0xBFC3 
옭 0xBFC4    옮 0xBFC5    옰 0xBFC6    옳 0xBFC7    옴 0xBFC8 
옵 0xBFC9    옷 0xBFCA    옹 0xBFCB    옻 0xBFCC    와 0xBFCD 
왁 0xBFCE    완 0xBFCF    왈 0xBFD0    왐 0xBFD1    왑 0xBFD2 
왓 0xBFD3    왔 0xBFD4    왕 0xBFD5    왜 0xBFD6    왝 0xBFD7 
왠 0xBFD8    왬 0xBFD9    왯 0xBFDA    왱 0xBFDB    외 0xBFDC 
왹 0xBFDD    왼 0xBFDE    욀 0xBFDF    욈 0xBFE0    욉 0xBFE1 
욋 0xBFE2    욍 0xBFE3    요 0xBFE4    욕 0xBFE5    욘 0xBFE6 
욜 0xBFE7    욤 0xBFE8    욥 0xBFE9    욧 0xBFEA    용 0xBFEB 
우 0xBFEC    욱 0xBFED    운 0xBFEE    울 0xBFEF    욹 0xBFF0 
욺 0xBFF1    움 0xBFF2    웁 0xBFF3    웃 0xBFF4    웅 0xBFF5 
워 0xBFF6    웍 0xBFF7    원 0xBFF8    월 0xBFF9    웜 0xBFFA 
웝 0xBFFB    웠 0xBFFC    웡 0xBFFD    웨 0xBFFE    웩 0xC0A1 
웬 0xC0A2    웰 0xC0A3    웸 0xC0A4    웹 0xC0A5    웽 0xC0A6 
위 0xC0A7    윅 0xC0A8    윈 0xC0A9    윌 0xC0AA    윔 0xC0AB 
윕 0xC0AC    윗 0xC0AD    윙 0xC0AE    유 0xC0AF    육 0xC0B0 
윤 0xC0B1    율 0xC0B2    윰 0xC0B3    윱 0xC0B4    윳 0xC0B5 
융 0xC0B6    윷 0xC0B7    으 0xC0B8    윽 0xC0B9    은 0xC0BA 
을 0xC0BB    읊 0xC0BC    음 0xC0BD    읍 0xC0BE    읏 0xC0BF 
응 0xC0C0    읒 0xC0C1    읓 0xC0C2    읔 0xC0C3    읕 0xC0C4 
읖 0xC0C5    읗 0xC0C6    의 0xC0C7    읜 0xC0C8    읠 0xC0C9 
읨 0xC0CA    읫 0xC0CB    이 0xC0CC    익 0xC0CD    인 0xC0CE 
일 0xC0CF    읽 0xC0D0    읾 0xC0D1    잃 0xC0D2    임 0xC0D3 
입 0xC0D4    잇 0xC0D5    있 0xC0D6    잉 0xC0D7    잊 0xC0D8 
잎 0xC0D9    자 0xC0DA    작 0xC0DB    잔 0xC0DC    잖 0xC0DD 
잗 0xC0DE    잘 0xC0DF    잚 0xC0E0    잠 0xC0E1    잡 0xC0E2 
잣 0xC0E3    잤 0xC0E4    장 0xC0E5    잦 0xC0E6    재 0xC0E7 
잭 0xC0E8    잰 0xC0E9    잴 0xC0EA    잼 0xC0EB    잽 0xC0EC 
잿 0xC0ED    쟀 0xC0EE    쟁 0xC0EF    쟈 0xC0F0    쟉 0xC0F1 
쟌 0xC0F2    쟎 0xC0F3    쟐 0xC0F4    쟘 0xC0F5    쟝 0xC0F6 
쟤 0xC0F7    쟨 0xC0F8    쟬 0xC0F9    저 0xC0FA    적 0xC0FB 
전 0xC0FC    절 0xC0FD    젊 0xC0FE    점 0xC1A1    접 0xC1A2 
젓 0xC1A3    정 0xC1A4    젖 0xC1A5    제 0xC1A6    젝 0xC1A7 
젠 0xC1A8    젤 0xC1A9    젬 0xC1AA    젭 0xC1AB    젯 0xC1AC 
젱 0xC1AD    져 0xC1AE    젼 0xC1AF    졀 0xC1B0    졈 0xC1B1 
졉 0xC1B2    졌 0xC1B3    졍 0xC1B4    졔 0xC1B5    조 0xC1B6 
족 0xC1B7    존 0xC1B8    졸 0xC1B9    졺 0xC1BA    좀 0xC1BB 
좁 0xC1BC    좃 0xC1BD    종 0xC1BE    좆 0xC1BF    좇 0xC1C0 
좋 0xC1C1    좌 0xC1C2    좍 0xC1C3    좔 0xC1C4    좝 0xC1C5 
좟 0xC1C6    좡 0xC1C7    좨 0xC1C8    좼 0xC1C9    좽 0xC1CA 
죄 0xC1CB    죈 0xC1CC    죌 0xC1CD    죔 0xC1CE    죕 0xC1CF 
죗 0xC1D0    죙 0xC1D1    죠 0xC1D2    죡 0xC1D3    죤 0xC1D4 
죵 0xC1D5    주 0xC1D6    죽 0xC1D7    준 0xC1D8    줄 0xC1D9 
줅 0xC1DA    줆 0xC1DB    줌 0xC1DC    줍 0xC1DD    줏 0xC1DE 
중 0xC1DF    줘 0xC1E0    줬 0xC1E1    줴 0xC1E2    쥐 0xC1E3 
쥑 0xC1E4    쥔 0xC1E5    쥘 0xC1E6    쥠 0xC1E7    쥡 0xC1E8 
쥣 0xC1E9    쥬 0xC1EA    쥰 0xC1EB    쥴 0xC1EC    쥼 0xC1ED 
즈 0xC1EE    즉 0xC1EF    즌 0xC1F0    즐 0xC1F1    즘 0xC1F2 
즙 0xC1F3    즛 0xC1F4    증 0xC1F5    지 0xC1F6    직 0xC1F7 
진 0xC1F8    짇 0xC1F9    질 0xC1FA    짊 0xC1FB    짐 0xC1FC 
집 0xC1FD    짓 0xC1FE    징 0xC2A1    짖 0xC2A2    짙 0xC2A3 
짚 0xC2A4    짜 0xC2A5    짝 0xC2A6    짠 0xC2A7    짢 0xC2A8 
짤 0xC2A9    짧 0xC2AA    짬 0xC2AB    짭 0xC2AC    짯 0xC2AD 
짰 0xC2AE    짱 0xC2AF    째 0xC2B0    짹 0xC2B1    짼 0xC2B2 
쨀 0xC2B3    쨈 0xC2B4    쨉 0xC2B5    쨋 0xC2B6    쨌 0xC2B7 
쨍 0xC2B8    쨔 0xC2B9    쨘 0xC2BA    쨩 0xC2BB    쩌 0xC2BC 
쩍 0xC2BD    쩐 0xC2BE    쩔 0xC2BF    쩜 0xC2C0    쩝 0xC2C1 
쩟 0xC2C2    쩠 0xC2C3    쩡 0xC2C4    쩨 0xC2C5    쩽 0xC2C6 
쪄 0xC2C7    쪘 0xC2C8    쪼 0xC2C9    쪽 0xC2CA    쫀 0xC2CB 
쫄 0xC2CC    쫌 0xC2CD    쫍 0xC2CE    쫏 0xC2CF    쫑 0xC2D0 
쫓 0xC2D1    쫘 0xC2D2    쫙 0xC2D3    쫠 0xC2D4    쫬 0xC2D5 
쫴 0xC2D6    쬈 0xC2D7    쬐 0xC2D8    쬔 0xC2D9    쬘 0xC2DA 
쬠 0xC2DB    쬡 0xC2DC    쭁 0xC2DD    쭈 0xC2DE    쭉 0xC2DF 
쭌 0xC2E0    쭐 0xC2E1    쭘 0xC2E2    쭙 0xC2E3    쭝 0xC2E4 
쭤 0xC2E5    쭸 0xC2E6    쭹 0xC2E7    쮜 0xC2E8    쮸 0xC2E9 
쯔 0xC2EA    쯤 0xC2EB    쯧 0xC2EC    쯩 0xC2ED    찌 0xC2EE 
찍 0xC2EF    찐 0xC2F0    찔 0xC2F1    찜 0xC2F2    찝 0xC2F3 
찡 0xC2F4    찢 0xC2F5    찧 0xC2F6    차 0xC2F7    착 0xC2F8 
찬 0xC2F9    찮 0xC2FA    찰 0xC2FB    참 0xC2FC    찹 0xC2FD 
찻 0xC2FE    찼 0xC3A1    창 0xC3A2    찾 0xC3A3    채 0xC3A4 
책 0xC3A5    챈 0xC3A6    챌 0xC3A7    챔 0xC3A8    챕 0xC3A9 
챗 0xC3AA    챘 0xC3AB    챙 0xC3AC    챠 0xC3AD    챤 0xC3AE 
챦 0xC3AF    챨 0xC3B0    챰 0xC3B1    챵 0xC3B2    처 0xC3B3 
척 0xC3B4    천 0xC3B5    철 0xC3B6    첨 0xC3B7    첩 0xC3B8 
첫 0xC3B9    첬 0xC3BA    청 0xC3BB    체 0xC3BC    첵 0xC3BD 
첸 0xC3BE    첼 0xC3BF    쳄 0xC3C0    쳅 0xC3C1    쳇 0xC3C2 
쳉 0xC3C3    쳐 0xC3C4    쳔 0xC3C5    쳤 0xC3C6    쳬 0xC3C7 
쳰 0xC3C8    촁 0xC3C9    초 0xC3CA    촉 0xC3CB    촌 0xC3CC 
촐 0xC3CD    촘 0xC3CE    촙 0xC3CF    촛 0xC3D0    총 0xC3D1 
촤 0xC3D2    촨 0xC3D3    촬 0xC3D4    촹 0xC3D5    최 0xC3D6 
쵠 0xC3D7    쵤 0xC3D8    쵬 0xC3D9    쵭 0xC3DA    쵯 0xC3DB 
쵱 0xC3DC    쵸 0xC3DD    춈 0xC3DE    추 0xC3DF    축 0xC3E0 
춘 0xC3E1    출 0xC3E2    춤 0xC3E3    춥 0xC3E4    춧 0xC3E5 
충 0xC3E6    춰 0xC3E7    췄 0xC3E8    췌 0xC3E9    췐 0xC3EA 
취 0xC3EB    췬 0xC3EC    췰 0xC3ED    췸 0xC3EE    췹 0xC3EF 
췻 0xC3F0    췽 0xC3F1    츄 0xC3F2    츈 0xC3F3    츌 0xC3F4 
츔 0xC3F5    츙 0xC3F6    츠 0xC3F7    측 0xC3F8    츤 0xC3F9 
츨 0xC3FA    츰 0xC3FB    츱 0xC3FC    츳 0xC3FD    층 0xC3FE 
치 0xC4A1    칙 0xC4A2    친 0xC4A3    칟 0xC4A4    칠 0xC4A5 
칡 0xC4A6    침 0xC4A7    칩 0xC4A8    칫 0xC4A9    칭 0xC4AA 
카 0xC4AB    칵 0xC4AC    칸 0xC4AD    칼 0xC4AE    캄 0xC4AF 
캅 0xC4B0    캇 0xC4B1    캉 0xC4B2    캐 0xC4B3    캑 0xC4B4 
캔 0xC4B5    캘 0xC4B6    캠 0xC4B7    캡 0xC4B8    캣 0xC4B9 
캤 0xC4BA    캥 0xC4BB    캬 0xC4BC    캭 0xC4BD    컁 0xC4BE 
커 0xC4BF    컥 0xC4C0    컨 0xC4C1    컫 0xC4C2    컬 0xC4C3 
컴 0xC4C4    컵 0xC4C5    컷 0xC4C6    컸 0xC4C7    컹 0xC4C8 
케 0xC4C9    켁 0xC4CA    켄 0xC4CB    켈 0xC4CC    켐 0xC4CD 
켑 0xC4CE    켓 0xC4CF    켕 0xC4D0    켜 0xC4D1    켠 0xC4D2 
켤 0xC4D3    켬 0xC4D4    켭 0xC4D5    켯 0xC4D6    켰 0xC4D7 
켱 0xC4D8    켸 0xC4D9    코 0xC4DA    콕 0xC4DB    콘 0xC4DC 
콜 0xC4DD    콤 0xC4DE    콥 0xC4DF    콧 0xC4E0    콩 0xC4E1 
콰 0xC4E2    콱 0xC4E3    콴 0xC4E4    콸 0xC4E5    쾀 0xC4E6 
쾅 0xC4E7    쾌 0xC4E8    쾡 0xC4E9    쾨 0xC4EA    쾰 0xC4EB 
쿄 0xC4EC    쿠 0xC4ED    쿡 0xC4EE    쿤 0xC4EF    쿨 0xC4F0 
쿰 0xC4F1    쿱 0xC4F2    쿳 0xC4F3    쿵 0xC4F4    쿼 0xC4F5 
퀀 0xC4F6    퀄 0xC4F7    퀑 0xC4F8    퀘 0xC4F9    퀭 0xC4FA 
퀴 0xC4FB    퀵 0xC4FC    퀸 0xC4FD    퀼 0xC4FE    큄 0xC5A1 
큅 0xC5A2    큇 0xC5A3    큉 0xC5A4    큐 0xC5A5    큔 0xC5A6 
큘 0xC5A7    큠 0xC5A8    크 0xC5A9    큭 0xC5AA    큰 0xC5AB 
클 0xC5AC    큼 0xC5AD    큽 0xC5AE    킁 0xC5AF    키 0xC5B0 
킥 0xC5B1    킨 0xC5B2    킬 0xC5B3    킴 0xC5B4    킵 0xC5B5 
킷 0xC5B6    킹 0xC5B7    타 0xC5B8    탁 0xC5B9    탄 0xC5BA 
탈 0xC5BB    탉 0xC5BC    탐 0xC5BD    탑 0xC5BE    탓 0xC5BF 
탔 0xC5C0    탕 0xC5C1    태 0xC5C2    택 0xC5C3    탠 0xC5C4 
탤 0xC5C5    탬 0xC5C6    탭 0xC5C7    탯 0xC5C8    탰 0xC5C9 
탱 0xC5CA    탸 0xC5CB    턍 0xC5CC    터 0xC5CD    턱 0xC5CE 
턴 0xC5CF    털 0xC5D0    턺 0xC5D1    텀 0xC5D2    텁 0xC5D3 
텃 0xC5D4    텄 0xC5D5    텅 0xC5D6    테 0xC5D7    텍 0xC5D8 
텐 0xC5D9    텔 0xC5DA    템 0xC5DB    텝 0xC5DC    텟 0xC5DD 
텡 0xC5DE    텨 0xC5DF    텬 0xC5E0    텼 0xC5E1    톄 0xC5E2 
톈 0xC5E3    토 0xC5E4    톡 0xC5E5    톤 0xC5E6    톨 0xC5E7 
톰 0xC5E8    톱 0xC5E9    톳 0xC5EA    통 0xC5EB    톺 0xC5EC 
톼 0xC5ED    퇀 0xC5EE    퇘 0xC5EF    퇴 0xC5F0    퇸 0xC5F1 
툇 0xC5F2    툉 0xC5F3    툐 0xC5F4    투 0xC5F5    툭 0xC5F6 
툰 0xC5F7    툴 0xC5F8    툼 0xC5F9    툽 0xC5FA    툿 0xC5FB 
퉁 0xC5FC    퉈 0xC5FD    퉜 0xC5FE    퉤 0xC6A1    튀 0xC6A2 
튁 0xC6A3    튄 0xC6A4    튈 0xC6A5    튐 0xC6A6    튑 0xC6A7 
튕 0xC6A8    튜 0xC6A9    튠 0xC6AA    튤 0xC6AB    튬 0xC6AC 
튱 0xC6AD    트 0xC6AE    특 0xC6AF    튼 0xC6B0    튿 0xC6B1 
틀 0xC6B2    틂 0xC6B3    틈 0xC6B4    틉 0xC6B5    틋 0xC6B6 
틔 0xC6B7    틘 0xC6B8    틜 0xC6B9    틤 0xC6BA    틥 0xC6BB 
티 0xC6BC    틱 0xC6BD    틴 0xC6BE    틸 0xC6BF    팀 0xC6C0 
팁 0xC6C1    팃 0xC6C2    팅 0xC6C3    파 0xC6C4    팍 0xC6C5 
팎 0xC6C6    판 0xC6C7    팔 0xC6C8    팖 0xC6C9    팜 0xC6CA 
팝 0xC6CB    팟 0xC6CC    팠 0xC6CD    팡 0xC6CE    팥 0xC6CF 
패 0xC6D0    팩 0xC6D1    팬 0xC6D2    팰 0xC6D3    팸 0xC6D4 
팹 0xC6D5    팻 0xC6D6    팼 0xC6D7    팽 0xC6D8    퍄 0xC6D9 
퍅 0xC6DA    퍼 0xC6DB    퍽 0xC6DC    펀 0xC6DD    펄 0xC6DE 
펌 0xC6DF    펍 0xC6E0    펏 0xC6E1    펐 0xC6E2    펑 0xC6E3 
페 0xC6E4    펙 0xC6E5    펜 0xC6E6    펠 0xC6E7    펨 0xC6E8 
펩 0xC6E9    펫 0xC6EA    펭 0xC6EB    펴 0xC6EC    편 0xC6ED 
펼 0xC6EE    폄 0xC6EF    폅 0xC6F0    폈 0xC6F1    평 0xC6F2 
폐 0xC6F3    폘 0xC6F4    폡 0xC6F5    폣 0xC6F6    포 0xC6F7 
폭 0xC6F8    폰 0xC6F9    폴 0xC6FA    폼 0xC6FB    폽 0xC6FC 
폿 0xC6FD    퐁 0xC6FE    퐈 0xC7A1    퐝 0xC7A2    푀 0xC7A3 
푄 0xC7A4    표 0xC7A5    푠 0xC7A6    푤 0xC7A7    푭 0xC7A8 
푯 0xC7A9    푸 0xC7AA    푹 0xC7AB    푼 0xC7AC    푿 0xC7AD 
풀 0xC7AE    풂 0xC7AF    품 0xC7B0    풉 0xC7B1    풋 0xC7B2 
풍 0xC7B3    풔 0xC7B4    풩 0xC7B5    퓌 0xC7B6    퓐 0xC7B7 
퓔 0xC7B8    퓜 0xC7B9    퓟 0xC7BA    퓨 0xC7BB    퓬 0xC7BC 
퓰 0xC7BD    퓸 0xC7BE    퓻 0xC7BF    퓽 0xC7C0    프 0xC7C1 
픈 0xC7C2    플 0xC7C3    픔 0xC7C4    픕 0xC7C5    픗 0xC7C6 
피 0xC7C7    픽 0xC7C8    핀 0xC7C9    필 0xC7CA    핌 0xC7CB 
핍 0xC7CC    핏 0xC7CD    핑 0xC7CE    하 0xC7CF    학 0xC7D0 
한 0xC7D1    할 0xC7D2    핥 0xC7D3    함 0xC7D4    합 0xC7D5 
핫 0xC7D6    항 0xC7D7    해 0xC7D8    핵 0xC7D9    핸 0xC7DA 
핼 0xC7DB    햄 0xC7DC    햅 0xC7DD    햇 0xC7DE    했 0xC7DF 
행 0xC7E0    햐 0xC7E1    향 0xC7E2    허 0xC7E3    헉 0xC7E4 
헌 0xC7E5    헐 0xC7E6    헒 0xC7E7    험 0xC7E8    헙 0xC7E9 
헛 0xC7EA    헝 0xC7EB    헤 0xC7EC    헥 0xC7ED    헨 0xC7EE 
헬 0xC7EF    헴 0xC7F0    헵 0xC7F1    헷 0xC7F2    헹 0xC7F3 
혀 0xC7F4    혁 0xC7F5    현 0xC7F6    혈 0xC7F7    혐 0xC7F8 
협 0xC7F9    혓 0xC7FA    혔 0xC7FB    형 0xC7FC    혜 0xC7FD 
혠 0xC7FE    혤 0xC8A1    혭 0xC8A2    호 0xC8A3    혹 0xC8A4 
혼 0xC8A5    홀 0xC8A6    홅 0xC8A7    홈 0xC8A8    홉 0xC8A9 
홋 0xC8AA    홍 0xC8AB    홑 0xC8AC    화 0xC8AD    확 0xC8AE 
환 0xC8AF    활 0xC8B0    홧 0xC8B1    황 0xC8B2    홰 0xC8B3 
홱 0xC8B4    홴 0xC8B5    횃 0xC8B6    횅 0xC8B7    회 0xC8B8 
획 0xC8B9    횐 0xC8BA    횔 0xC8BB    횝 0xC8BC    횟 0xC8BD 
횡 0xC8BE    효 0xC8BF    횬 0xC8C0    횰 0xC8C1    횹 0xC8C2 
횻 0xC8C3    후 0xC8C4    훅 0xC8C5    훈 0xC8C6    훌 0xC8C7 
훑 0xC8C8    훔 0xC8C9    훗 0xC8CA    훙 0xC8CB    훠 0xC8CC 
훤 0xC8CD    훨 0xC8CE    훰 0xC8CF    훵 0xC8D0    훼 0xC8D1 
훽 0xC8D2    휀 0xC8D3    휄 0xC8D4    휑 0xC8D5    휘 0xC8D6 
휙 0xC8D7    휜 0xC8D8    휠 0xC8D9    휨 0xC8DA    휩 0xC8DB 
휫 0xC8DC    휭 0xC8DD    휴 0xC8DE    휵 0xC8DF    휸 0xC8E0 
휼 0xC8E1    흄 0xC8E2    흇 0xC8E3    흉 0xC8E4    흐 0xC8E5 
흑 0xC8E6    흔 0xC8E7    흖 0xC8E8    흗 0xC8E9    흘 0xC8EA 
흙 0xC8EB    흠 0xC8EC    흡 0xC8ED    흣 0xC8EE    흥 0xC8EF 
흩 0xC8F0    희 0xC8F1    흰 0xC8F2    흴 0xC8F3    흼 0xC8F4 
흽 0xC8F5    힁 0xC8F6    히 0xC8F7    힉 0xC8F8    힌 0xC8F9 
힐 0xC8FA    힘 0xC8FB    힙 0xC8FC    힛 0xC8FD    힝 0xC8FE
 아이팟 터치(iPod Touch)의 한글 지원 소식에 감명받아서 새벽에 잠깐 짬을내서 Nintendo DS( NDS )용 한글 입력기를 만들어봤습니다. ^^;;; 아직은 테스트 상태라서 많이 불안정한데, 일단 동작은 하니까 스크린 샷을 올려봅니다. ^^

사용자 삽입 이미지

한글 입력 테스트


 

 아이팟 터치의 키보드가 너무 예뻐서 그대로 올려봤는데, NDS에 올리니 약간 포스가 떨어지는군요. ^^;;;
 
 오늘 테스트 덕분에 한글 출력에 한가지 문제를 발견했습니다. 제가 NDS에 올린 폰트는 완성형이었는데, 윈도우에서는 확장 완성형 폰트를 사용했습니다. @0@)/!!! 왠지 '틍'과 같은 단어를 입력할때 깨어진다 싶었더니... 확장 완성형에서 지원하는 문자라서 그랬습니다.

 확장 완성형 폰트를 만들어 넣는 것은 큰 문제가 안되지만.... 폰트 데이터가 너무 커지면 용량의 한계때문에 문제가 발생할 소지가 있어서 상당히 조심스럽습니다. 이 문제는 좀더 고민해본 다음 결정해야겠습니다. ^^;;;

 벌써 해가뜨네요... ㅜ_ㅜ... 오늘도 일찍 일어나기는 힘들 것 같습니다. ㅜ_ㅜ...
 
=== 2007/11/26 추가 ===

 너무 많은 분들이 이 글을 보러 오셔서, 오늘까지 진행상황을 더 추가했습니다. ^^ 폰트를 더 추가할까 하다가 NDS의 용량이 그리 크지 않아서 포기하고 한글을 조합하는 오토마타를 조금 손봐서 2360자용 한글 입력기를 만들었습니다.

 현재 한글/영어 대소문자/숫자 및 특수문자 모두 입력 가능하며 특수문자는 자판 숫자 및 배열 때문에 빠진 것이 좀 있습니다. 추후 작업을 조금 더 진행하여 특수문자를 다 추가해야 할 예정입니다. (혹시 아이팟 가지고 계신분 있으시면 특수문자쪽 키보드 자판 배열 좀 알려주세요 ^^;;;)

 완성형 한글 입력 및 영어, 숫자 입력을 캡쳐한 화면입니다. 다음에 작업이 완료되면 새글을 통해 릴리즈하겠습니다. ^^
사용자 삽입 이미지

영어 대문자 입력

사용자 삽입 이미지

영어 소문자 입력



사용자 삽입 이미지

한글 입력

사용자 삽입 이미지

한글 및 숫자/특수문자 입력


 ps) 작업을 하다보니 어느새 날이 밝아오는군요. ㅜ_ㅜ...


=== 2007/12/01 추가 ===

 프로토타입 개발을 완료했습니다. ^^ 자세한 내용은 http://kkamagui.tistory.com/238 에서 확인하실 수 있습니다. 동영상과 프로그램을 포함하고 있습니다. ^^
 애플 iPod 터치용 한글 입력기가 나왔답니다. ^ㅡ^)/~!! 일반 유저인 서성진씨(http://coryas.com/ipod)가 만들었다니 대단하군요. 아래는 시연 동영상입니다. ^^

 
 저도 NDS에 비슷한 방식의 한글 입력기를 생각하고 있었는데, 오토마타쪽에 약해서 도중에 포기했습니다. 이 동영상을 보니 왠지 저도 하나 해야할듯한 기분이 드는군요. 오늘부터 한글입력기 제작에 들어가야겠습니다. ^^

 같은 한국인으로써 왠지 뿌듯하네요 ^^)/~
 아는 후배에게 방금 들었습니다. POC 2007 세미나에서 NDS를 이용한 해킹을 주제로 "Hacking with Nintendo DS" 를 발표하셨던 i3eat 님께서 제 사이트를 참고하셨다더군요. 세미나에 참석했던 후배가 물어봤는데 그렇게 말씀하셨답니다.

 POC 2007에 직접 가지 못해서 자세한 내용은 알지 못하지만, 왠지 큰 세미나에 제가 한몫 한 것 같아서 기분이 좋군요.(사실 많이 뿌듯하다는 ^ㅡ^). 나중에 기회가되면 POC 2007 세미나 자료를 봐야겠군요.

 NDS 홈브루(Homebrew) 개발에 대한 내용은 http://kkamagui.tistory.com/category/NDS%20홈브루(Homebrew)에서 보실 수 있습니다. ^^

 나중에 i3eat 님을 만나게되면 인사라도 드려야겠습니다. ^^  
 왠지 오늘은 잠이 잘 올것 같네요~ 다들 좋은밤 되시길~ ^^
 티스토리에 글을 쓰다가 문득 위에 "동영상" 이라는 버튼이 보였습니다. 이게 뭘까? 한참을 고민하다가 설마하는 생각에 제가 가지고 있는 동영상을 올려보니 블로그에 표시되는 것이 아니겠습니까? @0@ 이글루스에서는 상상도 할 수 없던 것이 티스토리로 옮기니까 가능해 지는군요.

 생각난 김에 예전에 만들어 뒀던 닌텐도 DS( NDS )용 작은 커널(Kernel) 시연 동영상을 올립니다. ^^ 커널은 OS(Operating System)의 핵심적인 부분으로 주변기기 제어에 필요한 잡다한 코드들을 제외한 핵심이라고 보시면 되는데요, 어차피 닌텐도 DS( NDS )는 그렇게 주변기기가 많지 않고 마이크 말고는 다 지원하고 있으니 작은 OS라고 해도 괜찮을 것 같습니다.
 
 아래에서 시연 동영상을 보실 수 있습니다. 시작 화면이 시커멓게 나와서 조금 안타깝군요. ㅡ_ㅜ... 운영체제답게 멀티 태스킹을 지원하고 사운드 및 키패드를 이용해서 게임(??)을 Play 할 수 있습니다. 정겨운 버블버블 음악이 게임 내내 흘러나오고 @$를 다 먹으면 게임이 끝납니다. ^^;;;

 구현에 관한 자세한 내용은 제 티스토리의 http://kkamagui.tistory.com/40 에서 보실 수 있고 NDS 홈브루 개발에 대한 내용은 제 티스토리의 홈브루 개발 카테고리 http://kkamagui.tistory.com/category/NDS%20홈브루(Homebrew) 에서 보실 수 있습니다.

 그럼 화질은 좀 떨어지지만 즐겁게 감상하시길 바랍니다. ^^;;;;

 


 NDS로 재미있게 했던 나노스트레이(Nanostray)의 후속작이 나온다는 군요. 1편은 정말 재미있게 했었는데, 2편이 나온다느 구매 욕구가 마구 솟구칩니다. @0@)/~ 아래는 플레이 동영상인데 그래픽이 상당이 깔끔해지고 속도도 더 빨라진 것 같네요. 많은 발전을 한 듯합니다. ^^
 
 어서 빨리 나왔으면 좋겠네요~ 기대됩니다. 나노스트레이(Nanostray) 2 !!

참고. 터치스크린(Touch Screen)의 튐 현상 해결방안

들어가기 전에...

0.2007/09/27 터치 문제 해결

  • Z 값을 이용해서 터치 스크린의 문제를 해결함
  • GBA Tek에 있는 소스와 PALib 쪽의 ARM7 함수를 섞어서 해결
    • sPressure = (((( touch.px + 1 ) * touch.z2) >> 6) / touch.z1) - (touch.px >> 6);
    • 위 식의 문제는 펜으로 강하게 터치했을 때 터치 스크린의 좌측의 값은 0이고 우측의 값은 3이 나온다는 것임
    • 터치 스크린의 X 좌표를 이용하게 되어있으므로 좌측의 경우 X 좌표가 0에 가까워져서 분해능이 떨어지는 문제도 발생(좌측의 경우 강약에 따라서 01, 우측의 경우 330 정도의 범위)
    • sPressure1 = ( touch.z2/( touch.z1 - 1 ) );
    • 위 식의 문제는 강하게 터치했을때 터치 스크린의 좌측 일정 범위를 넘어서면 값이 튀는 것임(X좌표의 범위가 0~20 정도일때 값이 급격하게 변함)
    • 그외의 범위에서는 세게 눌렀을 때 값이 우측에서 좌측으로 갈때 3->2->1->0 정도로 변함
  • 결국 두 값의 MIN을 취해서 해결
  • 어느정도 세기의 문제와 X 축 좌표에 따른 압력값 편차의 문제를 해결함
  • 압력값은 5정도 보다 작도록 설정하면 안튀는 것 같음
  • 아래는 사용한 코드
    // 압력계산 코드  
    sPressure = (((( touch.px + 1 ) \* touch.z2) >> 6) / touch.z1) - (touch.px >> 6);  
    sPressure1 = ( touch.z2/( touch.z1 - 1 ) );  
    if( sPressure1 < sPressure )  
    {  
        sPressure2 = sPressure1;  
    }  
    else  
    {  
        sPressure2 = sPressure;  
    }

    // 아래의 Touch와 XY버튼은 특별한 케이스이다.  
    // Touch Down  
    // Down 메시지는 계속 보낸다.  
    if( ( usSpecial & ( 0x01 << 6 ) ) && ( touch.x != 0 ) && ( touch.y != 0 ) && **( sPressure2 < 5 )** )

0.2007/09/22 터치 문제 발견

  • 아직 확실하게 터치 스크린 튀는 문제가 해결이 안됬음
    • 아무래도 확실하게 해결하기는 어려운 문제인듯 함... 약간의 기교로 처리할 수는 있는데... 그것 또한 완전하지 않음
  • 결국 원래의 Touch 함수를 사용하고 Z축 값을 입력 받아서 사용하도록 만듬
  • PALib 쪽의 ARM7 의 Main 함수를 참고
  • 아래는 수정된 VcountHandler() 함수
    /**  
        VCount Handler 함수  
            템플릿의 기본 소스를 아주 간단한 로직으로 수정  
    */  
    void VcountHandler()  
    {  
        touchPosition tempPos;  
        unsigned short usButton;  
        unsigned long ulTemp;  
        int a, b;  

        ulTemp = \_touchReadTemperature( &a, &b );  
        usButton = REG\_KEYXY;  

        // 만약 Touch가 되었으면 좌표를 읽어서 설정한다.  
        if( ( usButton & ( 1 << 6 ) ) == 0x00 )  
        {  
            tempPos = touchReadXY();
            if( tempPos.x == 0 || tempPos.y == 0 )  
            {  
                IPC->mailBusy = 1;  
                IPC->buttons = usButton | (1 << 6);  
                IPC->temperature = ulTemp;  
                IPC->mailBusy = 0;  
            }  
            else  
            {     
                IPC->mailBusy = 1;  
                IPC->touchX         = tempPos.x;  
                IPC->touchY   = tempPos.y;  
                IPC->touchXpx  = tempPos.px;  
                IPC->touchYpx  = tempPos.py;  
                IPC->touchZ1  = tempPos.z1;  
                IPC->touchZ2  = tempPos.z2;  
                IPC->temperature    = ulTemp;  
                IPC->buttons        = usButton;  
                IPC->mailBusy = 0;  
            }  
        }  
        else  
        {  
            IPC->mailBusy = 1;  
            IPC->buttons = usButton;  
            IPC->temperature = ulTemp;  
            IPC->mailBusy = 0;  
        }  

        g\_iVCount ^= (80 ^ 130);  
        SetYtrigger(g\_iVCount);  
    } 
  • 아래는 사용하는 소스다
        // Button의 상태를 읽는다.  
        // Mail이 Busy이면 대기한다.  
        while( IPC->mailBusy );  
        usSpecial = ~( IPC->buttons );  
        touch.x = IPC->touchX;  
        touch.y = IPC->touchY;  
        touch.px = IPC->touchXpx;  
        touch.py = IPC->touchYpx;  
        touch.z1 = IPC->touchZ1;  
        touch.z2 = IPC->touchZ2;  
        sPressure = (((IPC->touchXpx \* IPC->touchZ2) >> 6) / IPC->touchZ1) - (IPC->touchXpx >> 6);  

        // Z축 테스트 용  
        DrawBox( ( void\* ) 0x06000000, 16, 16, 256, 32, BIT( 15 ), TRUE );  
        sprintf( vcBuffer, "%d %d %d", touch.z1, touch.z2, sPressure );  

        HanPutStr(( void\* ) 0x06000000, 16, 16, RGB15( 0x1F, 0x1F, 0x1F ) | BIT( 15 ), vcBuffer );   
        ... 
        if( ( usSpecial & ( 0x01 << 6 ) ) &&  
            ( touch.x != 0 ) && ( touch.y != 0 ) && **( sPressure < 9 )** )

0.시작하면서... 2007/09/22 이전...

문쉘의 터치 스크린 관련 소스를 분석해보면 아주 간단하게 되어있음을 알 수 있다. 문서를 읽어보면 터치 스크린에서 값을 읽는 데는 어느정도 시간이 걸리고 또한 정확한 값을 읽기 위해서는 여러번 반복해서 읽어줘야 한다는 것을 알 수 있다. 문쉘의 터치스크린 소스 분석 부분은 07 문쉘(Moon shell)의 터치스크린(Touch Screen) 소스를 참고하고 터치스크린 제어에 대한 부분은 06 키패드(KeyPad) 및 터치스크린(Touch Screen) 제어 부분을 참고하도록 하자.

왜 터치스크린의 값이 이토록 튀는 것일까? 아래와 같은 문제점때문이 아닐까 추측하고 이것을 해결하려 노력했다.

  • X의 좌표값을 읽고 Y의 좌표값을 읽었을 때 SPI를 통해서 값을 읽고 이것을 몇변 반복하는 동안 시간이 걸린다.
  • 터치스크린으로 부터 값을 읽는 동안 언제든지 사용자의 동작에 따라 펜이 Release 될 수 있다.
  • ARM7에서 값을 쓰고 ARM9에서 값을 읽을 때 동기화의 문제

이제 위의 문제에 대해서 하나하나 살펴보도록 하자.

1.X/Y 좌표 값을 읽는 타이밍(Timing) 문제

터치스크린쪽 스펙을 보면 터치스크린의 값이 유효하지 않을 수 있으니, 여러번 읽어서 사용하라고 되어있다. 실제 코드도 그것을 증명하듯 libnds도 그렇고 문쉘의 소스도 여러번 읽게 되어있다. 실제로 유효하지 않은 값인지를 판단하는 부분은 양쪽이 다 다르지만...

여러번 읽어서 유효한 값을 찾는 것도 중요하지만, 여기에는 큰 문제가 있다. 일단 SPI를 통해서 읽기 때문에 메모리에서 바로 읽는 것 보다는 더 큰 시간이 걸리고(스펙을 보라... 클럭이 1~3MHz 정도다.. ㅡ_ㅡ;;;) X의 좌표를 여러번 읽게 되므로 Y의 좌표를 읽을 때 쯤에는 상당한 시간이 지나있다. 반복하는 회수에 따라서 차이가 있긴 하겠지만 많이 읽으면 읽을 수록 갭은 커친다.

문쉘의 경우에는 5번을 반복하되 읽은 값이 처음 읽은 값과 비교하여 오차범위가 30 내외이면 유효한 값이라 판단하고 그 값을 사용하게 된다. 5번 반복하는 것도 좋지만 어차피 유효한 값을 체크하는 것이라면 3번 정도도 충분하고 오차범위도 30은 큰편이라 생각되어 10으로 줄였다.

물론 오차범위를 줄이면 유효한 값이라 판단되는 범위가 줄어들어서 펜이 Release가 되었다고 인식될 확률이 높지만, 펜이 자주 릴리즈되는 문제는 타이머를 사용하면 해결 할 수 있기 때문에 될 수 있으면 최대한 유효한 정보를 얻는데 초첨을 두었다.

2.펜 릴리즈(Pen Release) 문제

값을 반복해서 읽다 보면 도중에 펜이 릴리즈되어 값이 유효하지 않는 경우가 생긴다. 이때 값은 문서에 보면 X 축의 유효하지 않은 값은 0으로 송신한다. 하지만 Y의 경우는 0이 아니라 0xFFF로 온다. Y 값 같은 경우 0xFFF가 수신되면 0으로 변경하여 값을 넣게 하고 응용 프로그램에서 터치스크린의 Touch.X, Touch.Y의 값이 둘다 0이 아닐때만 사용하도록 하여 정확도를 높였다.

3. ARM9과 ARM7의 동기화(Syncronization) 문제

사실 이 부분은 가상 IPC 구조체에 Busy 플래그를 1로 설정하는 것으로 처리하고 굳이 신경쓰지 않았다. 그 이유는 ARM7에서 터치스크린에 값을 읽는 시간은 디스플레이의 V Count를 이용하여 80번째 스캔라인에서 읽도록 했기 때문이다. ARM9의 경우 가상 IPC에서 값을 읽는 시간은 VBlank 때이므로 시간적 차이가 좀 있다. 따라서 크게 신경쓰지 않았다. 추후 더 자주 읽어야하거나 어떤 문제가 발생하면 좀 더 동기화에 세밀한 신경을 써야 할지도 모르겠다.

4.구현

아래는 실제 코드인 _touch.c 파일의 내부이다. 첨부 파일로도 추가해 놓았다.

#include "_touch.h"
#include <nds.h>  
#include <nds/jtypes.h>  
#include <nds/system.h>  
#include <nds/arm7/touch.h>  
#include <nds/registers_alt.h>
#include <stdlib.h>

// 글로벌 변수들  
static bool gs_bTouchInit = false;  
static long gs_lXScale, gs_lYScale;  
static long gs_lXOffset, gs_lYOffset;
/**  
    문쉘에서 사용하는 touchRead 함수  
        libnds 함수랑 크게 차이 없음  
*/  
__attribute__((noinline)) static uint16 _touchRead(uint32 command) {  
 uint16 result;  
 SerialWaitBusy();
 // Write the command and wait for it to complete  
 REG_SPICNT = SPI_ENABLE | SPI_BAUD_2MHz | SPI_DEVICE_TOUCH | SPI_CONTINUOUS; //0x0A01;  
 REG_SPIDATA = command;  
 SerialWaitBusy();
 // Write the second command and clock in part of the data  
 REG_SPIDATA = 0;  
 SerialWaitBusy();  
 result = REG_SPIDATA;
 // Clock in the rest of the data (last transfer)  
 REG_SPICNT = SPI_ENABLE | 0x201;  
 REG_SPIDATA = 0;  
 SerialWaitBusy();
 // Return the result  
 return ((result & 0x7F) << 5) | (REG_SPIDATA >> 3);  
}

/**  
    온도를 읽는 함수  
        libnds와 크게 차이 없음  
*/  
uint32 _touchReadTemperature(int * t1, int * t2) {  
 *t1 = _touchRead(TSC_MEASURE_TEMP1);  
 *t2 = _touchRead(TSC_MEASURE_TEMP2);  
 return 8490 * (*t2 - *t1) - 273*4096;  
}
 /**  
    TOUCH의 값을 읽어서 유효성을 체크하여 값을 리턴하는 함수  
*/  
__attribute__((noinline)) static s32 readTouchValue(int measure, int retry, int range)  
{  
    int i;  
    s32 this_value=0, this_range;
    s32 last_value = _touchRead(measure | 1);
    for ( i=0; i < retry; i++)  
    {  
        this_value = _touchRead(measure | 1);
        this_range = abs(last_value - this_value);  
        if (this_range <= range) break;  
    }  

   if ( i >= retry ) this_value = 0;
   return this_value;  
}

/**  
    터치 스크린 사용에 관련된 변수값을 설정하고 초기화 하는 함수  
*/  
void _touchReadXY_AutoDetect(void)  
{  
    gs_lXScale = ((PersonalData->calX2px - PersonalData->calX1px) << 19) / ((PersonalData->calX2) - (PersonalData->calX1));
    gs_lYScale = ((PersonalData->calY2px - PersonalData->calY1px) << 19) / ((PersonalData->calY2) - (PersonalData->calY1));

    gs_lXOffset = ((PersonalData->calX1 + PersonalData->calX2) * gs_lXScale  - ((PersonalData->calX1px + PersonalData->calX2px) << 19) ) / 2;
    gs_lYOffset = ((PersonalData->calY1 + PersonalData->calY2) * gs_lYScale  - ((PersonalData->calY1px + PersonalData->calY2px) << 19) ) / 2;
    gs_bTouchInit = true;  
}

/**  
    외부에서 사용하는 함수  
        실제 Pixel 좌표와 Raw 좌표를 리턴  
*/  
touchPosition _touchReadXY()  
{
    touchPosition touchPos; 
    if(gs_bTouchInit==false)
    {
        REG_IME=0;
        while(1);
    }

    // 매크로를 사용하지 않고 그냥 hex 값으로 사용함
    touchPos.x = readTouchValue(0xD4 | 1, 2, 10);
    touchPos.y = readTouchValue(0x94 | 1, 2, 10);
    touchPos.z1 = readTouchValue(0xB4 | 1, 2, 30);
    touchPos.z2 = readTouchValue(0xC4 | 1, 2, 30);  

    // x의 값은 0이면 Release이지만 y는 0xfff이면 Release다. 따라서 처리 로직 추가  
    if( touchPos.y == 0xFFF )  
    {  
        touchPos.y = 0;  
    }  

    s16 px = ( touchPos.x * gs_lXScale - gs_lXOffset + gs_lXScale/2 ) >>19;
    s16 py = ( touchPos.y * gs_lYScale - gs_lYOffset + gs_lYScale/2 ) >>19;
    if ( px < 0) px = 0;
    if ( py < 0) py = 0;
    if ( px > (SCREEN_WIDTH -1)) px = SCREEN_WIDTH -1;
    if ( py > (SCREEN_HEIGHT -1)) py = SCREEN_HEIGHT -1;
    touchPos.px = px;
    touchPos.py = py;
    return touchPos;  
}

5.마치며...

실제 위의 코드를 적용하여 새로운 버전의 KKAMAGUI Notepad를 구현하였는데, 튀는 문제가 없어졌다. 앞으로 저 소스를 libfat 대신 이용해야 겠다.

6.첨부

179533__touch.h
0.00MB
180156__touch.c
0.01MB

26 윈도우 라이브러리(Window Library) 사용을 위한 프로젝트(Project) 만들기

원문 :  http://kkamagui.springnote.com/pages/579125


들어가기 전에...

0.시작하면서...

 윈도우 라이브러리(Window Library)를 이용해서 개발을 편리하게 할 수 있도록 만든 윈도우 라이브러리용 커스텀 프로젝트이다. 소프트웨어 리셋 라이브러리(Reset Library)도 같이 링크하도록 되어있으니 두 라이브러리 모두 필요하다.

 윈도우 라이브러리에 대한 내용은 02 NDS 윈도우 시스템(Windows System) 문서를 참조하면 되고, 소프트웨어 리셋 라이브러리(Soft Reset Library)에 대한 내용은 06 소프트웨어 리셋 라이브러리(Software Reset Library) 문서를 참조하면 된다.


1.첨부



이 글은 스프링노트에서 작성되었습니다.

25 ARM7/ARM9 라이브러리 프로젝트(Library Project) 만들기(작성중)


들어가기 전에...

0.시작하면서...



1.사용법



2.마치면서...



3.첨부



이 글은 스프링노트에서 작성되었습니다.

08 NDS 홈브루(Homebrew) - KKAMAGUI NDS Shell

원문 : http://kkamagui.springnote.com/pages/566470


들어가기 전에...

0.시작하면서...

 NDS 사용자라면 문쉘(MoonShell)을 모르는 사람이 없을 것이다. 스킨 기능과 동영상 재생기능, MP3 Play기능 및 파일 보기 기능 등등~ 상당히 많은 기능들을 포함하고 있는 무시무시한 쉘이다. 시간 날때마다 문쉘의 소스를 뒤져보고 있지만, 어떻게 이렇게 복잡한 소스를 관리하는지 의문이 들 정도로 소스가 빼곡히 들어 차있다.

 KKAMAGUI NDS Shell은 문쉘의 기능에서 필요한 기능만 추려내고 내가 필요한 기능을 넣어서 사용하기위한 간단한 NDS용 쉘(Shell) 프로그램이다. 문쉘이 비하면 아직 기능이 많이 부족하지만, 시간 날때마다 짬짬히 기능을 추가하고 있으니 언젠가는 문쉘처럼 될 수 있을 것이라 생각한다. ^^;;;

 그럼 이제부터 KKAMAGUI NDS Shell에 대해서 알아보자.


1.프로그램 기능

 오늘(2007/11/01 05:38:07)까지 구현된 기능은 아래와 같다.

  • 듀얼 스크린 기능 : R 키를 통해 상하 스크린을 플립할 수 있는 기능. A키를 이용하여 Program Manager를 이동시켜 두 화면 모두 프로그램을 실행할 수 있음
  • 파일 브라우징 기능 및 텍스트 뷰어 기능: File & Text Viewer를 이용하여 파일 리스트를 표시하고 L 키와 파일 리스트의 항목을 클릭함으로써 파일을 볼 수 있는 기능
  • 한글 출력 기능 : 윈도우 타이틀 및 텍스트 뷰어에 한글을 출력하는 기능. 유니코드는 아직 미지원
  • 달력 기능 : 현재 날짜와 시간을 표시하는 달력 기능
  • 리셋 기능 : 홈브루를 종료하고 Firmware로 이동하는 기능. 자세한 내용은 06 소프트웨어 리셋 라이브러리(Software Reset Library)의 문서 참고

2.프로그램 컴파일 및 링크 방법

 KKAMAGUI NDS Shell은 FAT Library, Window Library, Reset Library를 사용한다. 각각의 library에 대한 내용은 아래를 참고하여 설치하면 된다.

  • FAT Library : libfat는 devkitPro를 사용하면 기본으로 깔려있기 때문에 굳이 손댈 필요는 없음. 다만 링크 후에 실행하기위해서는DLDI 패치를 수행해야 함. 새로 libfat를 컴파일해서 DLDI를 하는 불편함을 줄이고 싶은 사람은 01 libfat 업그레이드 문서를 참고
  • Window Library : 자작한 윈도우 라이브러리. NDS에서 MFC와 같은 스타일의 윈도우 프로그래밍을 하기위해서 만듬. 02 NDS 윈도우 시스템(Windows System) 문서를 참고
  • Reset Library : 문쉘(MoonShell)의 Reset.MSE 플러그인을 분석해서 만든 소프트웨어 리셋 라이브러리. 06 소프트웨어 리셋 라이브러리(Software Reset Library) 문서를 참고

 위의 라이브러리중 하나라도 빠지면 컴파일 또는 링크가 되지 않으므로 빠짐없이 설치하도록 하자.


3.소스 구성

 KKAMAGUI NDS Shell의 대부분의 소스는 윈도우 라이브러리(Window Library)의 기본 윈도우와 리스트 윈도우, 스킨 윈도우를 상속받아서 커스터마이징(Customizing)하는 형태로 만들어졌다. 거의 윈도우 라이브러리를 테스트하기위한 프로젝트라고 해도 과언이 아닌데, 소스를 전부 설명하기는 어려우므로 첨부에 있는 소스 파일을 참고하도록 하자.

 윈도우 라이브러리 사용에 대한 자세한 내용은 추후에 별도의 문서로 올릴 예정이니, 구조만 참고하면 될 듯하다. ^^;;;


4.사용방법 및 실행화면

 버튼별 역할은 아래와 같다.

  • R 버튼:

    • 스크린 전환 기능. 상하 LCD를 바꿔서 모든 스크린을 터치로 제어 가능하게 만듬
  • L 버튼:

    • File & Text Viewer에서 파일 or 디렉토리 선택 모드로 전환
    • 선택 모드 사용 시 리스트의 항목 중에 터치 스크린으로 클릭된 부분이 붉은 색으로 변하고 터치를 때면 해당 항목의 파일이 Text Viewer로 표시되거나 해당 디렉토리로 이동
  • 화면 터치:

    • 윈도우 타이틀을 터치하는 경우 윈도우 이동
    • 닫기 버튼인 경우 윈도우 닫기. 리스트 윈도우의 경우 스크롤 또는 항목 선택
    • Text Viewer의 경우 스크롤
  • A 버튼:

    • Program Manager 표시
    • 화면 전환이 일어나서 Program Manager를 표시해야 하거나 Program Manager를 닫은 경우 다시 화면 가운데 표시

 아래는 실행화면이다.

 KNS1.PNGKNS2.pngKNS3.png

<실행화면>


5.마치면서...

 몇가지 기능밖에 없는 허접한 쉘(Shell)이지만 NDS에서 쉘을 만들려고 고민하는 사람들에게는 좋은 예제라 생각한다. 앞으로 MP3 Play 정도는 추가할 예정인데, 어떻게 될지 모르겠다. ^^;;;;


6.첨부




이 글은 스프링노트에서 작성되었습니다.

04 NDS 홈브루(Homebrew) - NDS 커널(Kernel) 만들기

들어가기 전에...

0.시작하면서...

NDS 커널 플레이 동영상

libnds를 이용해서 프로그램을 작성하는 예제는 충분히 많이 있다. 하지만 이것만 가지고는 무엇인가 부족하다. NDS에서 멀티 태스킹을 지원할 수 는 없을까? NDS는 타이머를 4개나 가지고 있기 때문에 시분할 멀티 태스킹을 하는데 전혀 문제가 없다.

커널이 되기위해서는 빠질 수 없는 기능이 멀티 태스킹이고 하니, NDS에 태스크 스위칭(Task Swithcing) 기능을 넣어보도록 하자. 컨텍스트 저장에 사용되는 곳은 OS 프레임워크와 동일하게 각 태스크 스택의 가장 아래부분(0 쪽에 가까운 부분)에 저장되고 아래의 순서로 총 16개의 값이 저장된다.

스택에 저장되는 레지스터 정보

위의 그림은 아래에서 설명할 소스코드를 이해하는데 도움이 되므로 꼭 봐두도록 하자

1.System/User 모드에서 태스크 스위칭(Task Switching)

유저모드에서 간단히 태스크 스위칭 하는 방법은 스택에다가 레지스터를 전부 넣고 스택을 스위칭 한 뒤에 전부 빼면된다. 저장하는 방식은 스택의 Bottom에서 레지스터의 갯수만큼을 저장하고 다시 복원하면 간단히 해결할 수 있다.

    태스크 스위치를 수행하는 함수  
    SwitchTask: // 0x0000 -> 0xFFFF로 올라가니까 넣고 증가시켜야 한다.  
    STMIA R0, { R0-R14 }  
    LDMIA R1, { R0-R13, pc}

2.타이머 인터럽트(Timer Interrupt)를 통한 태스크 스위칭(Task Swithcing)

2.1 인터럽트 핸들러(Interrupt Handler) 코드와 스택(Stack)

타이머 인터럽트를 통해 태스트스위칭을 할때 User/System 모드와 다른 점은 모드가 User/System 모드에서 IRQ 모드로 바뀐다는 것이다. 프로세서의 모드에 대한 내용은 참고. ARM Processor Overview의 내용을 참고하도록 하고 실질적인 문제에 대해서 알아보자.

가장 큰 문제는 레지스터가 뱅크되어 IRQ 모드의 R13(sp)R14(lr), 그리고 SPSR을 가진다는 것이다. 따라서 정상적인 태스트 스위칭을 위해서는 현재 태스크를 저장할 때 User/System 모드의 레지스터 및 SPSR을 저장해야 하며 복원할 태스크 또한 유저모드의 R13R14를 잘 복원해주고 유저모드의 CPSR에SPSR에 넣어준 다음 리턴해야 한다.

문제는 이것만이 아니다. 더 큰 문제는 NDS BIOS 라이브러리에 있는 인터럽트 처리 루틴을 통과한 후에 내가 제어를 이어받는 다는 것인데, NDS BIOS에서 인터럽트 선행 처리를 위해 무슨 일을 하는지 모르면 컨텍스트(Context)를 정확하게 저장할 수 없다. 상당히 충격적인 내용인데... BIOS와 동작 호환을 위해서는 이 부분에 대한 처리를 해줘야.. ㅜ_ㅜ...

일단 NDS의 인터럽트 디스패처(Interrupt Dispatcher) 소스는 \devkitPro\libnds\source\source\common 폴더의 interruptDispatcher.s 파일에서 찾을 수 있고 아래와 같다.

    #ifdef ARM7  
    .text  
    #endif

    #ifdef ARM9  
    .section .itcm,"ax",%progbits  
    #endif

    .extern irqTable  
    .code 32

    .global IntrMain

    @---------------------------------------------------------------------------------  
    IntrMain:
    @---------------------------------------------------------------------------------  
    mov r3, #0x4000000 @ REG_BASE

    ldr r1, [r3, #0x208] @ r1 = IME  
    str r3, [r3, #0x208] @ disable IME  
    mrs r0, spsr  
    stmfd sp!, {r0-r1,r3} @ {spsr, IME, REG_BASE}

    ldr r1, [r3,#0x210] @ REG_IE  
    ldr r2, [r3,#0x214] @ REG_IF  
    and r1,r1,r2

    ldr r0,=__irq_flags @ defined by linker script

    ldr r2,[r0]  
    orr r2,r2,r1  
    str r2,[r0]

    ldr r2,=irqTable

    @---------------------------------------------------------------------------------  
    findIRQ:  
    @---------------------------------------------------------------------------------  
    ldr r0, [r2, #4]  
    cmp r0,#0  
    beq no_handler  
    ands r0, r0, r1  
    bne jump_intr  
    add r2, r2, #8  
    b findIRQ

    @---------------------------------------------------------------------------------  
    no_handler:  
    @---------------------------------------------------------------------------------  
    str r1, [r3, #0x0214] @ IF Clear  
    ldmfd sp!, {r0-r1,r3} @ {spsr, IME, REG_BASE}  
    str r1, [r3, #0x208] @ restore REG_IME  
    mov pc,lr

    @---------------------------------------------------------------------------------  
    jump_intr:  
    @---------------------------------------------------------------------------------  
    ldr r1, [r2] @ user IRQ handler address  
    cmp r1, #0  
    bne got_handler  
    mov r1, r0  
    b no_handler

    @---------------------------------------------------------------------------------  
    got_handler:  
    @---------------------------------------------------------------------------------

    mrs r2, cpsr  
    bic r2, r2, #0xdf @ __  
    orr r2, r2, #0x1f @ / --> Enable IRQ & FIQ. Set CPU mode to System.  
    msr cpsr,r2

    str r0, [r3, #0x0214] @ IF Clear 
    push {lr}

    adr lr, IntrRet  
    bx r1

    @---------------------------------------------------------------------------------  
    IntrRet:  
    @---------------------------------------------------------------------------------  
    pop {lr}  
    mov r3, #0x4000000 @ REG_BASE  
    str r3, [r3, #0x208] @ disable IME

    mrs r3, cpsr  
    bic r3, r3, #0xdf @ __  
    orr r3, r3, #0x92 @ / --> Disable IRQ. Enable FIQ. Set CPU mode to IRQ.  
    msr cpsr, r3**

    ldmfd sp!, {r0-r1,r3} @ {spsr, IME, REG_BASE}

    str r1, [r3, #0x208] @ restore REG_IME  
    msr spsr, r0 @ restore spsr  
    mov pc,lr

    .pool  
    .end

코드의 중요부분은 IRQ Table에서 해당 처리 루틴을 찾아서 IRQ 모드에서 System 모드로 변경한 다음 함수를 호출하는 부분이다. 즉 타이머 인터럽트가 발생하면 내가 만든 타미어 핸들러를 호출하고 이 타이머 핸들러에서 리턴을 하면 정상적인 루트를 통해 다시 복구하도록 되어있다.

그렇다면 IntrMain 이라는 코드는 NDS의 BIOS가 불러준다는 이야긴데... 어떻게 찾아서 저 함수를 불러주는 것일까?

답은 아래는 \devkitPro\libnds\source\source\common 폴더에 있는 Interrupts.c 소스에서 찾을 수 있다. irqInit() 함수에서 위의 IntrMain 함수를 BIOS에서 호출해 줄 핸들러로 등록한다.

     ........ 생략 ........

    //---------------------------------------------------------------------------------  
    void irqInit() {  
    //---------------------------------------------------------------------------------  
    int i;

    // Set all interrupts to dummy functions.  
    for(i = 0; i < MAX_INTERRUPTS; i ++)  
    {  
    irqTable[i].handler = irqDummy;  
    irqTable[i].mask = 0;  
    }

    **IRQ_HANDLER = IntrMain;**

    REG_IE = 0; // disable all interrupts  
    REG_IF = IRQ_ALL; // clear all pending interrupts  
    REG_IME = 1; // enable global interrupt

    }

    ........ 생략 ........

여기서 잠깐.... 뭔가 이상한 점이 느껴지지 않는가? 보통 인터럽트가 발생하면 컨텍스트(Context)를 다 저장해 주고 인터럽트 처리 함수를 호출하여 인터럽트에 대한 처리를 한다음 다시 컨텍스트를 복구하는 절차를 거친다. 그런데 위의 InterruptDispatcher.s 소스에서는 그런 루틴이 보이지 않는다.

ARM 같은 경우라면 ldmfd sp!, {r0-r13} 등과 같은 코드가 있어야 할터인데... 이로보아 IntrMain 코드는 NDS의 BIOS에 의해 불려지는 코드임을 추측할 수 있다.

결국 BIOS의 인터럽트 핸들러 함수(인터럽트 처리의 최고 앞단)에 대해서 알아야 태스크 스위칭같은 문제를 해결할 수 있다는 것인데... ARM9 BIOS의 인터럽트 처리 코드는 어떤 형태일까? 한참을 뒤적이다가 http://www.bottledlight.com/ds/index.php/Main/Interrupts 에서 그 내용을 찾았다.

ARM7 Interrupt handler:

  1. stmdb sp!, {r0-r3, r12, lr}mov r0, #0x04000000
    add lr, pc, #0x0
    ldr pc, [r0, #-0x4]

    ldmia sp!, {r0-r3, r12, lr}

    subs pc, lr, #0x4

The user ARM7 interrupt vector is thus 0x03FFFFFC (mirrors down into ARM7 work RAM)

ARM9 Interrupt handler:

  • stmdb sp!, {r0-r3, r12, lr}
    mrc p15, 0, r0, c9, c1 @ r0 = DTCM_BaseAddress + 0x4000
    mov r0, r0, lsr #12
    mov r0, r0, lsl #12
    add r0, r0, #0x4000
    add lr, pc, #0x0
    ldr pc, [r0, #-0x4] @ bl [DTCM_BaseAddress + 0x3FFC]
    ldmia sp!, {r0-r3, r12, lr}
    subs pc, lr, #0x4

The user ARM9 interrupt vector is thus at DTCM+0x3FFC

In both cases, the BIOS flag word used in swi 0x4 and 0x5 is 4 bytes before the interrupt vector.

위에서 보면 알 수 있듯이 R0, R1, R2, R3, R12, lr을 저장하고 핸들러를 부른다음 IntrMain(붉은 색으로 표시된 부분)을 부르는 것을 알 수 있다. 그 뒤 다시 스택에서 레지스터를 다 복원한 다음 리턴한다. 모드 전환과 같은 코드가 없는 걸 봐서 libnds의 interruptDispatcher.s 파일에 있는 IntrMain 함수를 호출할때는 IRQ 스택을 사용하는 상태이다.

System 모드의 스택은 태스크마다 분리되어있기 때문에 저장해도 별 문제가 없지만 IRQ 레벨의 스택은 공통적으로 사용하기 때문에 만약 타이머 IRQ에서 다시 다른 IRQ가 발생하여 IRQ 스택에 데이터를 PUSH나 POP하면 문제가 발생한다.

일단 위험에 대해서는 위에서 많이 설명했으니 Interrupt가 발생하여 BIOS -> libnds의 IntrMain -> MyTimerHandler 순서로 호출되었을 때 System모드의 스택과 IRQ 모드의 스택 내용을 한번 보자.


<사용자 인터럽트 처리 함수까지 왔을 때의 스택의 모습>

위에서 IRQ 스택과 System 스택 2개로 나누어 진 것은 libndsHandler함수(IntrMain)에 의해서 System 모드로 전환되기 때문이다.

사용자 핸들러 함수(My Handler)가 불린 시점은 이미 System 모드로 전환된 상태이며 스택에 System 모드의 LR(R14) 레지스터의 값이 스택에 저장되어있다. 태스크 스위칭을 이 상황에서 수행하려면 저장하는 컨택스트는 IRQ 스택에서 SPSR과 R0~R3, R12, IRQ_LR을 빼서 저장해야 하고 System 스택에서는 SYSEM_LR을 빼서 저장해야 한다.

2.2 ARM 모드와 THUMB 모드

그런데 이것이 끝이 아니었다. 근 3일 정도를 스택을 계속 보면서 고민했는데, 그냥 리턴을 해서는 정상적으로 동작하지 않았다.

뭐가 문제일까? 그렇게 3일을 고민한 끝에 ARM 모드와 THUMB 모드의 전환... 이라는 내용이 머리를 스쳤다. 컴파일 옵션을 보면 우리가 C로 만든 태스크는 컴파일 옵션에 의해 THUMB 모드로 동작하게 되어있다. 그리고 ARM 모드로 컴파일된 코드를 호출할 수 있도록 Interwork 라는 옵션도 같이 들어있다. 이 말은 ARM 모드와 THUMB 모드를 넘나들며 함수를 호출할 때 중간에 Proxy 함수를 이용해서 호출해서 자동으로 처리해 준다는 이야긴데.... 일반적인 함수 호출에는 큰 문제가 없는 것 같았다. 하지만... 컨텍스트 스위칭의 경우에는 다르다. 레지스터 하나라도 복구가 잘못되면 그냥 크래쉬.. ㅜ_ㅜ...

주의할 점을 하나하나 집어보도록 하자.

2.2.1 CPSR의 설정

C 코드로 태스크 함수를 작성할 경우는 THUMB 모드 코드가 나오므로 태스크를 실행할때 당연히 CPU가 THUMB 모드로 설정되어야 한다. 따라서 복원할 CPSR의 상태를 THUMB Bit1을 키고 SYSTEM 모드(0x1F)로 설정해야 한다. 그런데 만약 어셈블리어 코드로 태스크 함수를 작성하는 경우는 어셈블리어 코드의 생성 옵션(.ARM or .THUMB) 같은 옵션에 맞게 설정해 주어야 한다.

2.2.2 ARM 모드 코드와 THUMB 모드 코드

C 코드(THUMB 코드)에서 어셈블리어 코드(ARM 코드)를 호출하면 어떻게 될까? 컴파일러가 자동적으로 Proxy 함수를 생성하여 C 함수 코드(THUMB 코드) -> THUMB/ARM 변경 코드 -> 어셈블리어 코드(ARM 코드)의 순서로 호출되게 된다. 여기서 잠깐 생각해 볼 것이 Proxy 함수를 거치면 상태 값이 살짝 바뀐다는 것이다. 여기에 대한 자세한 내용은 참고. THUMB 코드와 ARM 코드 및 상호 호출(Interwork) 부분을 참고 하도록 하자. 따라서 이 부분에 대한 처리도 해줘야 하므로 상당히 복잡해 진다.

어셈블리어 코드는 .ARM 모드에서 작성되어 모든 레지스터를 다 저장하고 복구하도록 되어있다. 하지만 타이머 인터럽트에 의해 불리어지는 C 함수는 THUMB 모드로 컴파일 되었고, 이 C 함수를 불러주는 인터럽트 함수는 ARM 모드에서 컴파일 된 핸들러 루틴이다.

이쯤되면 골치가 지끈 아파지고 쉽지 않을꺼라는 생각이 들텐데... 이 문제 때문에 3일을 고생했다. 결국은 요령으로 해결하긴 했지만... ARM 모드와 THUMB 모드를 번갈아가며 사용할 때 태스크 스위칭이 이렇게 힘든 줄 몰랐다.

2.2.3 태스크 스위칭(Task Switching) 코드

한참을 고생한 뒤에 나온 소스가 아래의 태스크 스위칭 코드이다.

@---------------------------------------------------------------------------------

.section ".text"  
.global SwitchTask  
.global SwitchTask2  
.global isrTimerInAsm  
.extern isrTimerInC  
.global g_dwCurTask  
.global g_dwNextTask  

@---------------------------------------------------------------------------------

.align  4  
.arm

@ Timer Interrupt에서 바로 호출해 주는 함수  
isrTimerInAsm:

PUSH { LR }  
BL isrTimerInC      

 LDR R0, g_dwCurTask

LDR R1, g_dwNextTask

 CMP R1, #0

BEQ TIMEREND  
    ADD R2, SP, #0x04  
    bl SwitchTask2

 TIMEREND:

    POP { LR }  
    BX LR   

/*

Switch Task  
    SYSTEM_R0-R14(LR), IRQ_R14, SPSR 순서로 저장한다.  
    IME가 불가된 상태에서 호출하면 안된다.  
    이 함수가 끝나면 가능상태로 바뀌기 때문이다.    

*/  
SwitchTask2:

// 인터럽트 불가 설정  
MOV R3, #0x4000000  
STR R3, [ R3, #0x208 ]    

MOV SP, R2  
POP { LR }  

// System 모드 레지스터를 저장한다.  
// R4-R14 저장  
ADD R3, R0, #16  
STMIA R3, { R4-R14 }^

MRS R3, CPSR  
BIC R3, R3, #0xDF  
ORR R3, R3, #0x92 // ISR 모드로 변경  
MSR CPSR, R3

LDMFD SP!, { R5-R6, R7 }  
//STR R6, [ R7, #0x208 ]  
// SPSR 저장  
//MSR SPSR, R0  
STR R5, [ R0, #64 ]

// R0-R3, R12, IRQ_LR 저장  
LDMFD SP!, { R5-R8, R12, LR }  
STMIA R0, { R5-R8 }  
STR R12, [ R0, #48 ]  
SUB LR, LR, #0x04  
STR LR, [ R0, #60 ]  
// 여기까지 오면 저장 끝...

// 여기서 부터는 복원 시작..

// SPSR 복원  
LDR R5, [ R1, #64 ]  
MSR SPSR, R5  
LDR LR, [ R1, #60 ]

// 인터럽트 가능 설정  
MOV R3, #0x4000001  
STR R3, [ R3, #0x207 ]

 LDMIA R1, { R0-R14 }^

//SUBS PC, LR, #0x00  
 MOVS PC, LR

/*  
Task Switch용 데이터를 저장하는 공간  
*/  
g_dwCurTask: nop  
nop  
g_dwNextTask:  
nop  
nop

간단한 아이디어는 아래와 같다.

  • libnds에 의해 호출되는 타이머 인터럽트 핸들러ARM 코드로 작성한다.
  • 스케줄링을 통해 스위칭할 태스크의 변수를 설정하고 기타 처리를하는 함수는 C로 작성한다.(THUMB 코드가 된다.)
  • 스케줄링 함수에서는 전역 변수 g_dwCurTask, g_dwNextTask 변수에 태스크 스위칭할 태스크 구조체를 넣어서 리턴한다.
  • 타이머 핸들러 함수(ARM 코드)에서에 전역 변수 g_dwCurTask, g_dwNextTask를 이용하여** 태스크 스위칭 함수(ARM 코드)**를 호출한다.
    • 태스크 스위칭 함수로 들어오면 스택 구조는 위 그림에서 보는 것과 같은 형태로 되어있으므로 IRQ 모드 및 SYSTEM 모드를 오가면서 태스크를 저장하고 복원한다.
    • THUMB 모드에서 이 함수를 호출 할 경우에는 Proxy 함수(THUMB에서 ARM 모드로 변경하는 함수)를 통해 호출되므로 모드가 변경되어 호출된다. 따라서 이 THUMB 모드 함수에서 태스크 스위칭 함수(ARM 코드)를 부르게 되면 모드 전환같은 곤란한 문제가 생기므로 약간 곤란하다. 이를 피하기 위해 내가 만든 타이머 인터럽트 핸들러 함수(ARM 코드)에서 태스크 스위칭 함수를 호출하여준다.
  • 만약 스케줄러가 NULL 값을 전역 변수 g_dwNextTask로 설정하면 태스크 스위칭을 호출하지 않고 정상적인 루트로 리턴을 하여 돌아간다. THUMB 모드에서 ARM 모드로 이동했을때 Proxy를 사용한다는 것은 알고 있었지만... 그게 이렇게 큰 문제를 일으킬줄은 몰랐다. 단순한 함수의 호출같은 문제는 크게 관계 없지만... 컨텍스트 스위칭의 경우는 세세한 부분까지 신경을 써줘야 하는 부분인데... 이렇게 되니 완전 눈물이 나는... ㅜ_ㅜ

3.스케줄러(Scheduler) 및 태스크(Task) 함수들...

스케줄러의 기본형태는 OS 프레임워크의 소스를 그대로 따르고 있다. 스케줄링 알고리즘은 라운드 로빈의 형태를 띄고 있고 지금 최대 5개까지 생성 가능하도록 되어있다. 스케줄러에 대한 자세한 내용은 Part14. Tutorial2-멀티 태스킹(Multi Tasking) 기능을 추가해 보자의 내용을 살펴보면 된다.

3.1 태스크 등록 및 타이머의 처리

ARM9의 main.cpp 파일을 보면 타이머를 설정하고 타이머 핸들러를 등록하는 부분이 있다.

// Timer의 Tick Interval 20ms  
#define TIMER_TICKINTERVAL_MS 20
/**
Timer의 핸들러  
*/  
extern "C" DWORD isrTimerInC( void )  
{
    char vcBuffer[ 2 ];  

    REG_IF |= IRQ_TIMER0;  
    VBLANK_INTR_WAIT_FLAGS |= IRQ_TIMER0;  

    g_uiTimerCount++;

    vcBuffer[ 1 ] = 0;  
    vcBuffer[ 0 ] = g_uiTimerCount & 0x7F;  
    // 타이머가 돌아가고 있다는 것을 표시한다.  
    SUBPRINT( 41, 0, vcBuffer );

    // 스케줄러를 호출한다.
    Scheduler();  

    return 0;  
}

/**  
IRQ를 설정한다.
  신버전.. libnds의 루틴을 사용하도록 수정  
*/  
void SetIrq( void )  
{  
    // 인터럽트 불가 설정
    REG_IME = 0;

    irqInit();
    irqSet( IRQ_VBLANK, isrVBlank );
    irqEnable( IRQ_VBLANK );  
    irqSet( IRQ_TIMER0, isrTimerInAsm );  
    irqEnable( IRQ_TIMER0 ); 

    // 20 ms 마다 한번씩 튀도록 한다.
    TIMER0_DATA = TIMER_FREQ_256( 1000 / TIMER_TICKINTERVAL_MS );  

    // 테스트 용으로 분주를 좀 늘려서 천천히 튀게 했다. 
    TIMER0_CR = TIMER_ENABLE | TIMER_IRQ_REQ | TIMER_DIV_256;
    REG_IF |= 0xFFFFFFFF;  
    REG_IME = 1;  
}

단순히 타이머를 20ms 마다 튀도록 설정해 놓고 isrTimerInC 함수에서 스케줄러 함수를 부르는 것을 볼 수 있다. 스케줄러 함수는 g_dwCurTask 및 g_dwNextTask 에 스위칭 할 태스크들을 설정해서 리턴한다. isrTimerInC 함수가 리턴되고 나면 위에서 설명했던 isrTimerInAsm 함수에서 실제로 스위칭하는 함수를 부르게 된다.

3.2 Snake 게임

원래 Snake 게임은 꼬리가 길어지고 점점 사과가 늘어나고 그래야 하지만.... 내가 만든 Snake 게임은... 꼬리도 안 길어지고 사과만 먹으면 된다. 사과(녹색 $ 표시)를 다 먹으면 먹은 사과의 개수와 Play하는데 걸린 시간이 표시된다. 사과를 다 먹기 전에 벽(하얀색 #)에 부딪히게되면 게임이 종료되므로 주의해야 한다. 게임이 종료되면 A 버튼을 누르면 다시 게임을 제개할 수 있다.

제일 주의할 점은.... 중독성이 있으니 자제를 해야한다는 것이다. 시간 갱신에 힘쓰다보면 큰일이 생기니 적당히 하도록 하자. @0@)/~~

3.3 기타 테스크

다른 테스크들은 매우 간단한 일만 하는 테스크이므로 굳이 설명을 하지 않겠다. 소스를 보면 쉽게 이해가 될터이니...(하는 일도 별로 없고.. ㅡ_ㅡ;;;)

4.실행화면


<NDS 커널의 실행화면>

NDS 커널을 실행하면 위와 같은 화면이 나온다. 총 5개의 태스크가 돌아가는 화면이며 각 태스크는 아래와 같은 위치에 있다.

NDS 커널의 테스트 동작 화면

위의 붉은 색 사각형 하나하나가 다 개별적인 태스크로 동작하며 시분할 스케줄링 기법을 이용하여 동시(??)에 동작한다. 특히 Task3번의 경우는 2초마다 사운드를 출력하도록 되어있기 때문에 주기적으로 울리는 소리를 들을 수 있다.

5.추가사항

5.1 2007/08/29 추가 사항

  • Snake 게임에 보글보글 배경음악 추가
  • Task3은 배경음악을 반복하는 주기를 50초로 설정함. 보글 보글 배경음악이 47초 가량이라서 2~3초 Delay가 생김
  • Snake가 움직일 때 움직이는 소리 추가
  • Snake가 죽을 때 죽는 소리 추가

5.첨부

186343_NDSKernel.zip
2.5 MB

03 NDS 홈브루(Homebrew) - Advanced KKAMAGUI Notepad

 

들어가기 전에...

64비트 멀티코어 OS 원리와 구조

0.2007/09/28 추가

 

0.시작하면서...

 처음 NDS 홈브루를 개발하면서 libfat의 능력 및 libnds의 테스트 용으로 간단한 메모장 프로그램인 KKAMAGUI Notepad를 개발하였다(자세한 내용은 00 KKAMAGUI Notepad 참조). 테스트 결과 libfat가 약간 불안함을 발견하였고, 터치스크린의 경우 튀는 문제가 발생하였다.

 하지만 분석 결과 튀는 순간이 처음 터치스크린을 찍는 부분과 터치스크린에서 펜을 때어낼 때임을 발견하였고 이를 버퍼와 범위 체크를 통해 어느정도 완화시켜서 그렇게 큰 문제는 되지 않았다.

 그후 5개월이 지난 지금... NDS에 대한 분석이 진행되면서 ARM7 코드도 같이 삽입하고 테스트 할 수 있게 되어 터치스크린 문제를 해결하고 기존에 부족했던 기능을 추가하여 새롭게 업그레이드를 했다. 그것이 바로 Advanced KKAMAGUI Notepad이다.

 

1.터치스크린(Touch Screen) 튐 현상 해결

 터치스크린의 튐 현상은 libnds의 고질적인 문제였다. 여러 홈브루를 테스트해봐도 터치가 튀는 현상을 발견할 수 있다. 이 부분을 해결하려면 ARM7 코드를 손을 대어야 했는데, 결국 해냈다( 장하다 KKAMAGUI @0@)/~~).

 자세한 내용은 참고. 터치스크린(Touch Screen)의 튐 현상 해결방안 문서를 참고하도록 하자.

 

2.파워 컨트롤(Power Control) 기능 추가

 기존의 KAMAGUI Notepad는 NDS가 접혔을 때... 즉 폴딩(Folding) 되었을 때 LCD를 끄는 처리만 되어있었다. 다른 게임들을 보면 알겠지만 NDS의 LED가 깜빡이면서 대기중인 것을 표시한다. Advanced KKAMAGUI Notepad 또한 그 기능을 추가하여 폴딩 되었을때 LED를 깜빡이도록 했다.

 

3.사운드(Sound) 기능 추가

 해당 버튼을 클릭하면 사운드가 출력되도록 하여 약간의 즐거움을 추가했다. 사운드 출력에 대한 내용은 08 사운드(Sound) 제어 와 참고. 롬 파일에 데이터(사운드, 이미지 등등) 파일 포함 방법 문서를 참고하자.

 

4.기타

  • 화면 색깔을 약간 바꾸고 직선 그리는 알고리즘을 이상한 알고리즘에서 Bresenham 알고리즘으로 변경했다. 대각선 같은 경우 기존의 알고리즘보다 훨씬 더 자연스럽다. 알고리즘에 대한 자세한 내용은 http://tong.nate.com/lovebridge/33470715를 참고하자.
  • 새 메모를 남기는 화면에서 "지우개" 버튼을 클릭하면 "연필"로 바뀌어서 클릭하면 연필 모드가 된다는 것을 추가했다.

 나머지 기능들은 거의 동일하니 00 KKAMAGUI Notepad를 참고하도록 하자.

 

5.화면 및 실행방법

 롬파일을 DLDI 패치하여 메모리에 담은 다음 실행하면 된다. 아래는 실행한 화면이다.

메인 화면
연필로 그리기 화면

 좌측에 보면 연필로 표시된 것을 확인할 수 있다.

 

6.마치며...

 이제야 NDS에 대해서 좀 알 것 같다. 3월에 처음 홈브루를 개발하면서 막연한 지식으로 덤벼들었는데, 요즘 상세하게 분석하고 Notepad에 추가 기능까지 넣고나니 약간 감이 잡히는 듯....

 역시 NDS 최고~ >ㅁ<)/~~!!

 

7.첨부

 

참고. NDS 동영상 인코딩(BatchDpg)

 원문 :  http://kkamagui.springnote.com/pages/492909


들어가기 전에...

0.시작하면서...

 NDS로 동영상을 보려면 문쉘과 DPG 파일 포맷으로 인코딩해주는 툴이 필요하다. 물론 NDS의 사양이 그렇게 좋지 않기 때문에 인코딩시에 질을 많이 떨어뜨려야 하는 문제가 있지만... 나름 볼만하므로 통근시간이 길거나 학교까지 거리가 먼 사람들은 인코딩을 시도해 볼만하다.


 DPG 파일 포맷은 간단한 헤더와 MP2 Audio 그리고 MPEG1 Video 파일로 구성된다. 쉽게 이야기하면 오디오 파일 따로 비디오 파일 따로 생성하여 그냥 묶어놓은 것 뿐이다. 프로그램에 능한 사람이라면 인코딩 라이브러리를 사용해서 인코딩하여 DPG 파일을 생성하는 것도 가능할 것이다. 일반인들은 인코딩 프로그램을 사용하면 되는데, 많이 쓰는 인코딩 툴은 BatchDPG가 있다.

 BatchDPG를 이용해서 인코딩 하는 방법을 알아보도록 하자.


1.BatchDPG 설치

 BatchDPG 파일은 구글에서 검색하면 많이 나오는데, 거의 영문판이다. 다행이도 한글화시켜놓은 프로그램이 있으니 BatchDPG 1.2K 버전이다. 현재( 2007/09/23 20:16:34 )까지 1.3 Beta 버전까지 나와있는데, 구버전을 쓰기가 좀 그렇다고 느끼는 사람은  BatchDPG12KNew.zip 를 받으면 된다. 1.2K 버전에 1.3 Beta 버전의 Libary를 덮어씌운 버전이다.


 BatchDPG가 정상적으로 동작하려면 추가적으로 아래와 같은 것들이 더 필요하다.


2.BatchDPG 사용

 위의 두 프로그램을 다운받아 설치한 후 BatchDPG를 실행하면 아래와 같은 화면이 표시된다.

 화면.PNG


 사용방법은 아래와 같다.

  1. 동영상과 자막을 설정하고 맨 아래에 추가 버튼을 이용하여 작업을 추가한다.
  2. 작업할 동영상을 계속 반복하여 추가한다.
  3. 작업 추가가 끝났으면 맨 아래에 실행 버튼을 클릭하여 인코딩 작업을 수행한다.

 작업이 완료되면 해당 폴더에 DPG 파일이 생성된다.


3.마치면서...

 간단히 DPG로 인코딩하는 방법을 알아보았다. 이제 DPG의 세계로 빠져보자. @0@)/~~!!



이 글은 스프링노트에서 작성되었습니다.

지난번에 발견한 문쉘의 리부팅 플러그인 (reset.mse) 소스를 뒤지다가

혹시나 실행이 되지 않으면 어쩌나 걱정스러운 마음에 소스를 좀 수정해서

적당히 만든 다음 컴파일 하니 _BOOT_MP.NDS 파일이 나왔다.

약간 걱정이 되었지만 테스트 결과는 대성공 @0@)/~~

다만 약간 문제는 구버전의 fat 라이브러리를 사용하는데,

이것이 FAT Raw 데이터를 이용하는 부분이어서 현재 쓰고있는 fat 라이브러리로는 힘들꺼 같았다.

그렇다고 중복으로 fat 라이브러리를 다 링크하자니 쓸데없이 코드가 커지는 문제가 생기고... ㅡ_ㅡa...

결국 libfat에서 FAT Raw 데이터를 뽑기로 결심했는데, 얼래...

구버전의 데이터가 거의 그대로 libfat에 살아있었다.

얼쑤~!!! @0@)/~~

이런 대박이~!!!

쫌만 손보면 간단히 라이브러리 정도는 만들 수 있겠다.

앗싸~ 좋구나~ >ㅁ<)/~!!!!
쿨럭..;;; 처음에 후배가 준 라이브러리를 그냥 사용했다가 접속이 안되는 낭패를 겪고...

혹시나 해서 새로 컴파일한 후 사용하니 나름 괜찮게 동작했다.

하지만 역시나... 약간 불안정하고 간혹 먹통이 되는 상황이 생겨서 이거 원.... ㅡ_ㅡ;;;;;

한참을 테스트 하다보니

얼래??

이번에는 AP 쪽에서 내 접속을 막았나 보다.

AP 관리자 한테 가서 다시 열어달라 그래야지... ㅜ_ㅜ

아아... 역시나 아직 동작이 좀 불안하구나... ㅜ_ㅜ...
NDS 과제를 하는 후배가 발견했던데, 지난달(9월)에 릴리즈된 버전이란다.

후배 말로는 AP 랑 접속해서 통신이 잘된다 그러던데...

정말 그렇다면 완전 감동이 아닐 수 없다. @0@)/~~

시간나면 테스트를 한번 해봐야 할듯...

앗싸~ 좋구나~ >ㅁ<)/~

dswifi-src-0.3.3.zip
요즘 MP3 Decoder에 열을 올리고 있는지라...... 오늘도 어김없이 포기 못하고 소스를 뒤지고 있었다.

Helix 라는 녀석이 자꾸 눈이가길래... 이걸로 해보자 싶어서 삽질을 계속하다가 결국 올렸다.

이제 실제로 사용해서 Play가 되는지 확인하는 길만 남았는데....

학교를 가야하는 관계로 갔다와서 해야겠다...

아놔... thumb 모드로 코드가 컴파일 되게 해놨더니만 arm 모드 명령에서 자꾸 에러가 발생하는 걸 제대로 이해 못해서... ㅜ_ㅜ...

또 하루종일 삽질했다는... ㅜ_ㅜ...

내가 미쵸.... ㅜ_ㅜ...

+ Recent posts