BLOG ARTICLE 프로젝트 | 17 ARTICLE FOUND

  1. 2011.12.07 minios on ipad
  2. 2011.09.07 joint skeleton tracking
  3. 2011.09.02 [AS3] 세선화, Thinning (2)
  4. 2011.07.18 LowFlash - 플래쉬 품질 설정
  5. 2011.02.11 minios - real IU !! (1)
  6. 2010.12.08 microcode (2)
  7. 2009.01.15 VGA 테스트 성공! (2)
  8. 2009.01.14 cpu isa design issue
  9. 2008.12.22 address/data bus issue (2)
  10. 2008.12.13 compiler basic phase
  11. 2008.12.13 minios x86 homebrew os project
  12. 2008.12.13 IBM VGA programming
  13. 2008.12.13 minios mouse control
  14. 2008.12.10 minios on svga
  15. 2008.12.09 VGA programming (2)

아이패드에 bochs가 설치된다니 재미삼아서 예전에 만든 x86 os인 minios를 올려봤다.

음 아쉽게도 gui버전은 약간 설정에 문제있는지 화면이 깨진다.

일단 대충 콘솔버전으로 캡쳐함...

흐흐 아이패드 인증이라 가상키보드로 화면을 다 덮었넹...;

'프로젝트 > minios OS 개발' 카테고리의 다른 글

minios on ipad  (0) 2011.12.07
minios - real IU !!  (1) 2011.02.11
minios x86 homebrew os project  (0) 2008.12.13
IBM VGA programming  (0) 2008.12.13
minios mouse control  (0) 2008.12.13
minios on svga  (0) 2008.12.10
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



세선화를 하고 나면 이제 인체 뼈대 모델로 매핑할 수 있어야 한다..

아 어렵다는 느낌이 팍온다;;

일단 검색을 하니 Motion Capture Using Joint Skeleton Tracking and Surface Estimation라는 논문이 보였다.

뭔진 모르고 일단 다운 받아야지... --;; 

지금 생각에 이런 단계를 거쳐야 할거 같다..

1. 배경 제거
2. 색깔 단순화
3. 세선화
4. 뼈대 모델 적용
5. 뼈대 모델 트래킹

아.. 키넥트를 사면 개발자sdk를 이용해서 바로 될 수 있는 부분일텐데..
키넥트를 사야할거 같기도 하고 -_-.. 걍 한번 대충 만들어보고도 싶고..

고민된다 ㄷㄷ..


'프로젝트 > motion capture' 카테고리의 다른 글

joint skeleton tracking  (0) 2011.09.07
[AS3] 세선화, Thinning  (2) 2011.09.02
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



세선화는 그림을 실선화 시키는 알고리즘이다. 가장 잘 알려진 Zhang Suen 알고리즘을 선택하였다.
코드 작성은 action script를 사용하였으며 wonderfl.net을 사용하였다.

실행하면 왼편이 원본 이미지이고 이를 세선화 한것이 오른 편에 나타나도록 하였다.

thinning on 2011-8-24 - wonderfl build flash online



kevin님이 버그를 발견해주셔서 (감사합니다 ㅎㅎ) 버그를 수정하고 코드를 약간 간략하게 수정하였다.
아래는 코드다.
/*
    2011/09/01
    Kyungmin Cho
    broneri@gmail.com
    thinning test : Zhang Suen algorithm
    --------------------------------------
    2011-09-01 - initial code.
    2011-09-07 - bug fix. thanks to kevin.    
*/
package {
    import flash.display.Sprite;
    import flash.events.Event;
    import flash.display.*;
        
    
    
    public class FlashTest extends Sprite {

        private var img_width:int = 20;
        private var img_height:int = 20;
        private var img:Array = new Array (
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0],
        [0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
        [0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0],
        [0,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,1,1,0,0,0,1,1,1,0,0,0,0,0,0],
        [0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0],
        [0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0],
        [0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0],
        [0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0],
        [0,0,0,0,1,1,1,1,0,0,0,1,1,1,1,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
                 );        

        private var img_triangle:Array = new Array (
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,1,1,1,1,1,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,1,1,1,0,1,1,1,0,0,0,0,0,0,0],
        [0,0,0,0,0,1,1,1,0,0,0,1,1,1,0,0,0,0,0,0],
        [0,0,0,0,1,1,1,1,0,0,0,0,1,1,1,0,0,0,0,0],
        [0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,1,0,0,0,0],
        [0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0],
        [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0],
        [0,0,1,1,1,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0],
        [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
        [0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
        [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
                 );        


        private var _bitmap:BitmapData= new BitmapData(stage.stageWidth, stage.stageHeight,
                                   false, 0xff000000);
        private var _image:Bitmap= new Bitmap(_bitmap);

        private var org_img:Array;
        private var org_img_triangle:Array;
        
        public function FlashTest() {
            // write as3 code here..
            addChild( _image );
            
            org_img = make_bitmap_array( img_width, img_height );
            copy_bitmap_array( img, org_img, img_width, img_height );            
            thin_image ( img, img_width, img_height );

            org_img_triangle = make_bitmap_array( img_width, img_height );
            copy_bitmap_array( img_triangle, org_img_triangle, img_width, img_height );            
            thin_image ( img_triangle, img_width, img_height );

            addEventListener( Event.ENTER_FRAME, onEnterFrame );
        }
        
        public function onEnterFrame (event:Event) : void {
            // original image
             draw_image ( org_img, img_width, img_height, 100, 50 );
             // thining image
             draw_image ( img, img_width, img_height, 200, 50 );             

            // original image
             draw_image ( org_img_triangle, img_width, img_height, 100, 150 );
             // thining image
             draw_image ( img_triangle, img_width, img_height, 200, 150 );             
        }
        
        public function draw_image ( img_src:Array, w:int, h:int, xpos:int, ypos:int ) : void {
             for ( var x:int = 0 ; x < w; x ++ ) {             
                 for ( var y:int = 0 ; y < h; y ++ ) {                     
                     var col:int;
                     
                     if ( img_src[y][x] == 1 )
                         col = 0x00ffffff;
                     else
                         col = 0x00000000;

                     _bitmap.setPixel( xpos +x, ypos +y, col );
                 }
             }       
        }
        
        public function thin_pixel_common ( s:Array, x:int, y:int ) : int {
            // pixel removal condition
            // 1. pixel is black            
            if ( s[y][x] == 0 )
                return 0;
            
            var near:Array = new Array( 
            s[y-1][x-1], s[y-1][x], s[y-1][x+1], s[y][x+1], 
            s[y+1][x+1], s[y+1][x], s[y+1][x-1], s[y][x-1], s[y-1][x-1]
            );
 
            var count: int = 0;
            var connect:int = 0;
            for( var i:int = 0; i <= 7; i++ ) {
                if( near[i] == 1 ) count ++;
                if( near[i] == 1 && near[i+1] == 0 ) connect ++;
            }
            
             // 2. near pixels 
            // check black pixels are >=2 and <=6
            if ( count >= 2 && count <= 6 &&
             // 3. connectivity is 1 
                connect == 1 )
                return 1;
                
            return 0;
        }

        public function thin_pixel_loop1 ( s:Array, x:int, y:int ) : int {
             if ( thin_pixel_common ( s, x, y ) == 0 )
                 return 0;
             
             if ( (s[y][x-1] == 0 || s[y-1][x] == 0 || s[y][x+1] == 0) &&
                  (s[y-1][x] == 0 || s[y][x+1] == 0 || s[y+1][x] == 0) ) {
                 return 1;
             }
             return 0;
        }

        public function thin_pixel_loop2 ( s:Array, x:int, y:int ) : int {
             if ( thin_pixel_common ( s, x, y ) == 0 )
                 return 0;
             if ( (s[y][x-1] == 0 || s[y+1][x] == 0 || s[y][x+1] == 0) &&
                  (s[y-1][x] == 0 || s[y][x-1] == 0 || s[y+1][x] == 0) ) {
                 return 1;
            }
             return 0;
        }
        
        public function thin_loop1 ( img_src:Array, width:int, height:int ) : int {
            var del:Array;
            
            del = make_bitmap_array( width, height );
            
            var thin_flag:int = 0; 
            var y:int = 1;
            var x:int = 1;
            for ( y = 1; y < height-1; y++ ) {
                for ( x = 1; x < width-1; x++ ) {
                    if ( thin_pixel_loop1( img_src, x,y ) == 1 ) {
                        del [y][x] = 1;
                    }
                }
            }
            
            thin_flag = del_bitmap_array ( img_src, del, width, height );
            return thin_flag;
        }
        
        public function thin_loop2 ( img_src:Array, width:int, height:int ) : int {
            var del:Array;
            
            del = make_bitmap_array( width, height );
            
            var thin_flag:int = 0; 
            var y:int = 1;
            var x:int = 1;
            for ( y = 1; y < height-1; y++ ) {
                for ( x = 1; x < width-1; x++ ) {
                    if ( thin_pixel_loop2( img_src, x,y ) == 1 ) {
                        del [y][x] = 1;
                    }
                }
            }
            
            thin_flag = del_bitmap_array ( img_src, del, width, height );
            return thin_flag;
        }

        public function del_bitmap_array ( src:Array, del:Array, width:int, height:int ) : int {
            var thin_flag:int = 0; 
            var y:int = 1;
            var x:int = 1;
            for ( y = 1; y < height-1; y++ ) {
                for ( x = 1; x < width-1; x++ ) {
                    if ( del [y][x] == 1 ) {
                        src[y][x] = 0;
                        thin_flag = 1;
                    }
                }
            }
            return thin_flag;
        }
 
        public function make_bitmap_array ( width:int, height:int ) : Array {
            var y:int = 0;
            var x:int = 0;
            var arr:Array = new Array(height);
            for ( y = 0; y < height; y ++ ) {
                arr[y] = new Array(width);
                
                for ( x = 0; x < width; x ++ ) {
                    arr[y][x] = 0;
                }
            }
            
            return arr;
        }

       public function copy_bitmap_array ( s:Array, d:Array, width:int, height:int ) : void {
            var y:int = 0;
            var x:int = 0;
            for ( y = 0; y < height; y ++ ) {
                for ( x = 0; x < width; x ++ ) {
                    d[y][x] = s[y][x];
                }
            }
        }

       // thining algorithm : Zhang Suen
        public function thin_image ( img_src:Array, width:int, height:int ) : void {
            
            var cont : int = 1;
            while (cont) {
                cont = 0;
                if ( thin_loop1( img_src, width, height ) == 1 )
                    cont = 1;
                
                if ( thin_loop2( img_src, width, height ) == 1 )
                    cont = 1;
            }
        }
    }
}

'프로젝트 > motion capture' 카테고리의 다른 글

joint skeleton tracking  (0) 2011.09.07
[AS3] 세선화, Thinning  (2) 2011.09.02
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. BlogIcon kevin 2011.09.03 21:00 신고  댓글주소  수정/삭제  댓글쓰기

    안녕하세요. ^^ 글 잘 읽었습니다.
    위에 공개된 알고리즘을 사용해서 저도 실제로 한번 해봤는데요. 약간의 버그가 있는 것 같습니다. 제가 테스트 한 것은 다음의 배열이고요.

    http://www.sysnet.pe.kr/temp/triangle_before.txt

    그런데 변환은 다음과 같이 됩니다.

    http://www.sysnet.pe.kr/temp/triangle_after.txt

    이미지 상으로 보면, 굵은 테두리를 가진 삼각형인데 세선화 이후 밑변이 사라져버립니다. ^^

    • BlogIcon broneri 2011.09.06 15:51 신고  댓글주소  수정/삭제

      댓글 감사합니다. ^^
      코드를 보니 잘못 쓴 부분이 있군요 -_-;;

      일단 kevin님 블로그를 확인했구요 ^^
      http://blog.naver.com/PostView.nhn?blogId=techshare&logNo=100137156001

      여기에 있는 알고리즘 소스를 보니 하기와 같이 바탕색이 하나라도 있는 경우 조건을 처리하고 있고,..

      iteration 1, p1 = a[0] * a[2] * a[4], p2 = a[2] * a[4] * a[6]
      _o___o_
      o_o___o
      _____o_

      iteration 2, p1 = a[0] * a[2] * a[5], p2 = a[0] * a[4] * a[6]
      ______o
      o_o__o_
      _o____o

      제 코드에서는 오타가 나서 하기와 같이 iteration1용 조건이 잘못되어 있네요. ㅎㅎ

      __o____o_
      _o_o__o_o


      __o________
      ___o___o_o
      __o_____o_

      집에가서 한번 다시 확인해보겠습니다.

      덕분에 버그를 찾았네요 감사합니다 ^^





어도비 플래쉬 플레이어가 10.1로 업그레이드 되면서 안그래도 무거운데 TC1100에서 cpu 100은 쉽게 올라가죠...

 

그래서 플래쉬의 품질을 메뉴에서 낮음으로 설정하곤 하는데, 많은 사이트에서 이런 품질 설정 메뉴가 보이지

 

않더라구요.

 

그래서 플래쉬 품질을 낮음으로 설정하는 프로그램을 며칠 찾아봤습니다..

 

파이어 폭스의 경우 애드인 형식으로 존재하더군요.

 

https://addons.mozilla.org/en-US/firefox/addon/low-quality-flash/

 

그런데, 정작 인터넷 강의는 거의 익스플로러에서만 열려서;; 열심히 익스플로러용 플래쉬 품질 설정하는 툴을 찾다가

 

포기하고 직접 만들어 봤습니다.;

 

저사양 PC나 TC1100에서는 나름 유용할 거라 생각합니다.

 

일단 어플형태로 품질 설정하도록 했습니다.

 

한번 클릭하면 현재 띄어 있는 모든 익스플로러의 모든 플래쉬들의 품질을 한방에 설정 변경하도록 하였습니다.

 

무료로 사용, 재배포 가능하지만 사용하면서 발생될 수 있는 문제는 제가 책임지지 않습니다.

 

감사합니당..

'프로젝트' 카테고리의 다른 글

LowFlash - 플래쉬 품질 설정  (0) 2011.07.18
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST





2011년 2월 9일 - 그냥 만저봄2
-----------------------------------------------------
fat.img안의 FAT12 /data/wall.bmp (5:6:5) 640x480 이미지를 보여주려고 하는데,
아무래도 filesystem에서 읽는데 문제가 좀 있는듯하다.
END_OF_CLUSTER가 뜨는데, 확실한 에러는 filesystem만 따로 떼내서 디버깅해봐야할듯하다.

2011년 2월 11일 - 아이유 바탕화면
-----------------------------------------------------
드뎌 바탕화면이 나온다.
역시 minifat에 버그가 있었다... --;;
get_cluster_in_fat12() 함수에서 i번째 클러스터의 항목값 ( 다음 클러스터 값)을 읽어오는
부분에서 어이없는 버그가 숨어 있었다.

 int FATOffset = i + (i/2);
 int ThisFATEntOffset = (FATOffset % bpb->BPB_BytesPerSec );

// FAT12ClusEntryVal = *((WORD *) &fat[ThisFATEntOffset]); 버그 -_-
 FAT12ClusEntryVal = *((WORD *) &fat[FATOffset]);

512번째 클러스터를 넘어가는 부분에 있어서 오동작할 수 밖에 없게 작성했었다 -_-...
바탕화면이 640x480x16bpp다보니까 600k로 512 클러스터를 넘어가다보니 생긴 문제..
어쨋든 이젠 데이터가 다 읽힌다 ㅎㅎㅎ
김태희를 바탕화면으로 넣으려했으나, 2009년에나 대세여서 지금은 리얼 아이유가 대세니까
아이유로 급 변경했다.. ㅋㅋㅋ

 


'프로젝트 > minios OS 개발' 카테고리의 다른 글

minios on ipad  (0) 2011.12.07
minios - real IU !!  (1) 2011.02.11
minios x86 homebrew os project  (0) 2008.12.13
IBM VGA programming  (0) 2008.12.13
minios mouse control  (0) 2008.12.13
minios on svga  (0) 2008.12.10
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. 2011.04.13 20:22  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다



아기 보느라 개인 시간이 하나도 없네요.

요새 고민하고 있는 부분이 micro code입니다.

약간의 힌트와 지식을 얻어서 대충 공유(?) 해보려합니다. (지적 및 조언은 감사히 받구요 ^^ )

제가 micro code를 보려는 이유는 ttl로 cpu를 만들려는 개인 취미이고요.

문제 상황은 납땜을 극히 싫어하는 뼈소남 (뼈속 부터 소프트웨어 남자)이기에.. ㅋㅋㅋ

wire wrap방식으로 만들고자 하는 것이고요. ( 왜 있잖아요, homebewcpu.com 아저씨 처럼 ㅎㅎ;; )

isa를 해석하는 control 로직에 interconnect를 줄이기 위한 일환으로 microcode 방식의 control로직을 고민하게 되었고요.

대략적으로 다음과 같더군요. 

먼저 마이크로코드는 isa (instruction set architecture) 의 수많은 명령어를 모두 하드웨어 상에 설계를 하려면 귀찮으니

보다 저급한 프리미티브한 상세 동작으로 나누어보자는 거죠.

이를 구현하기 위해선 micro sequencer로직이 필요하게 됩니다. 한 명령어를 실행하기 위해서 내부적으로는 세부명령어
여러개로 나누기 때문에 한 명령어 당 여러 세부 cycle이 발생하게 되는거죠. 
(현재 x86 아키텍쳐는 내부적으로 이 microcode architecture를 쓰고 있습니다.)

구현측면에서 바라보면 

alu로 부터 결과를 얻은 flag register로 부터 c (carray), z (zero), v (overflow), n(minus) 이전 상태 값을 얻어온 후

micro sequence마다 해당 해야 할 control logic을 내뱉는 동작..

즉.. 예로 아래는 bmow의 microcode입니다.

// BEQ
// Branch if result is zero. If Z bit of the condition codes is 0, then interpret the
// next byte of the program as a signed offset from the next instruction's PC, and jump to that
// address.
opcode: F0
z=0: T <- X // brach taken
z=1: pc++ // branch not taken
z=0: X <- MEM(PC); PC++
z=1: nextop
*: PCLO <- X + PCLO; latchCC // add delta to low byte of PC; latch carry
//if no X7 available:
// *: X <- X; latchCC
//n=0: X <- 0
//n=1: X <- 0 - 1
//c=0: PCHI <- X + PCHI + 1
//c=1: PCHI <- X + PCHI
c=0: PCHI <- X7 + PCHI + 1 // carry flag == 0 means there was a carry
c=1: PCHI <- X7 + PCHI
*: X <- T; nextop

위는 BEQ 명령 (만일 어떤 수행의 결과로 zero flag가 설정될 경우 jump하라는 명령)을 기술한 것이고,
cpu개발자는 위와 같이 microcode를 위한 자체 언어를 만들고 이를 assemble 하는 툴을 만들어서
rom에 굽게 됩니다.

위의 경우 왼편에 flag condition이 존재하고 (z=0이나 c=1이런 것들) 오른편에 실제 마이크로 코드가 보입니다.
즉 첫번째 micro sequence 구간(하드웨어에선 clock이라고 말함) 동안 z=0이면 X레지스터값을 T로 복사합니다.
nextop은 마이크로 sequence를 초기화하고 다음 instruction을 fetch하라는 종결을 의미하는 키워드입니다.
(뭐 bmow개발자가 임의로 만든 언어기 때문에 중요한 것들은 아니지만요)

이렇게 마이크로 코드를 모두 작성한 후 자신의 마이크로코드 컴파일러를 개발하여 rom에 굽게 합니다.

여기서 재미있는 매직을 하는데요. 이를 테면

명령어가 놓여져 있는 메모리에서 한 명령어를 읽어온 후

opcode가 F0 (위 기술상 BEQ에 해당)가 읽히면 해당 opcode 값 F0가 마이크로 코드가 심어져 있는 rom의 
상위비트 주소로 연결되고, 중간 비트에 micro sequence값 0~16 차례로 증가되는 값, 그리고 마지막비트들에
zvcn flag값이 역시 rom의 어드레스로 들어가게 됩니다.

물론 이미 rom에는 해당 opcode에 대해 몇번째 micro sequence step일때 그리고 이전 flag가 무슨 값일때 
어떤 control signal을 생성해야 할지 정해져있는 거고요.

예를 들면, 실행할 opcode가 F0 (BEQ)이고 seq값이 1이고 z=1인 상태이라면 
microcode rom의 입력address pin에 F014 이런 어드레스가 들어갑니다. (상위 F0, 중간 1, 마지막 비트가 zcvn순이라면 ) 
그러면 pc++을 실행하기 위해서 내부적으로는 inc_pc라는 (가정) internal control signal이 발생되어야 한다면,
microcode rom의 F014 주소의 메모리 값을 읽으면 0x0001이라는 값을 얻게 되고 inc_pc 컨트롤 신호는 rom메모리 읽은 값의 
최하위 비트를 쓰는 식입니다.
마치 소프트웨어의 해쉬테이블 처럼 말이죠.

결국 마이크로코드를 지원하기 위해서 해야할 일

- 자신의 isa를 결정
- 지원할 microcode instruction 결정
- microcode 언어 개발
- microcode 컴파일러 개발
- microcode 롬에 굽기

일단 개략적으로 동작이나 만드는 방법이 정리되는 거 같군요..

결혼하고 애낳고 하느라 근 1년 넘게 개인 취미를 못했는데, 다시 시작하려니 설레네요.

'프로젝트 > CPU 설계' 카테고리의 다른 글

microcode  (2) 2010.12.08
VGA 테스트 성공!  (2) 2009.01.15
cpu isa design issue  (0) 2009.01.14
address/data bus issue  (2) 2008.12.22
compiler basic phase  (0) 2008.12.13
VGA programming  (2) 2008.12.09
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. BlogIcon FreeChild 2012.04.16 23:25 신고  댓글주소  수정/삭제  댓글쓰기

    환상적이군요...^^ 듣던 명성대로 대단하십니다... 저도 이런 경지에 이르고 싶습니다.^^




실 CPU 설계 부터 해야하지만, 뭔가 화면에 보이면 신나고 좋을거 같았다. 그래서 시작한 것이 VGA 잡기..
어차피 목표가 겜이 동작되는 거니까 (-- 일단 목표는 크게.. ) 언젠간 부딪혀야할 주변장치이긴 하다.
원래 VGA는 25.175MHz의 오실레이터가 필요하다만... 구하기 녹녹찮아서 20MHz를 사용하였다.;;;
물론 납땜인두도 없기 때문에 vga 커넥터를 wire wrap으로 하기로 했다.

목표 VGA Mode는 640x480x60Hz 16color (IBM VGA Mode중 12h이다)
실제 Horizontal Blank와 Vertical Blank구간을 합친 Total resolution은 800x525이다.
근데 20MHz밖에 없어서 Horizontal은 800대신 635로 쭐였다. 실제 active 해상도는 524x480정도 된다.

정말 쉬울줄 알았다.
근데 정말 어렵다. 오실로스코프가 없을때 그 암담함이란 ;;;;;;;
결국 오실로스코프를 미리 장만하게 하는 계기가 되었다 ㅡ,.ㅡ;
정말 일주일 넘게 이거만 붙들고 있었다. 정말 많은 삽질을 했다 --;

먼저 VGA 15pin 3열 d-sub female connector를 이쁘게 wire wrap 하였다. 난 땜쟁이가 아니니까..;

LG CYON | LGE LH2300 | Normal program | Center-weighted average | 2008:12:02 01:43:10

그리고 HSYNC를 위해서 4bit 74LS193P 듀얼카운터 3개를 할당하고; VSYNC를 위해서 역시 4비트 카운터 3개를 마련했다;
그리고 HSYNC, VSYNC및 카운터 리셋을 하는 신호를 20v8 GAL 2개를 사용하여 생성시켰다.
사실 삽질이다. GAL22v10 을 사용하면 4bit 카운터 안써도 된다. 20v8은 매크로셀이 8bit d-ff라서 너무 할것이 없다.
이거 하면서 xc9500 cpld쪽도 한번 발을 담궈야 겠다는 마음이 불끈들었다.;;

LG CYON | LGE LH2300 | Normal program | Center-weighted average | 2008:12:02 01:26:18

잘 동작하는지 이번에 산 100MHz ReadOut Kenwood 오실로스코프로 프로브를 했다.
LG CYON | LGE LH2300 | Normal program | Center-weighted average | 2008:12:02 01:29:04
음 대충 HSYNC를 위한 scan line인 31.77 us를 맞춘거 같다.
LG CYON | LGE LH2300 | Normal program | Center-weighted average | 2008:12:02 01:27:28

음 VSYNC역시 1 frame 인 16.68 ms을 대충 맞춘거 같다.
LG CYON | LGE LH2300 | Normal program | Center-weighted average | 2008:12:02 01:28:37

RGB 중 B를 HSYNC용 카운터의 적절한 비트(?)에 두고 화면에 출력! 오예 드뎌 ㅠㅠ...
LG CYON | LGE LH2300 | Normal program | Center-weighted average | 2008:12:02 01:26:06

신이난 나는 미친듯이 R,G,B를 꽂았다. 오 전혀 촌스럽지 않아..!!
LG CYON | LGE LH2300 | Normal program | Center-weighted average | 2008:12:02 01:40:53

이미지를 넣으려면 EEPROM이 있어야 겠다.. 또 사야겠네..;
VSYNC카운터 쪽에도 RGB를 물려봤다. 이 땐 330Ohm저항에 함께 놓았다.
LG CYON | LGE LH2300 | Normal program | Center-weighted average | 2008:12:02 23:39:08



삽질 내용
- wirewrap이 헐렁하다.. 잘쪼여 놓자 ;;; (이래서 납땜을 해야 하는 건가...)
- VGA Dsub connector 핀을 잘못 연결.. 이건 뭐..커넥터 매뉴얼도 없고 헤매다가 HSYNC 핀 female 구멍에 프로브로 꽂아보고 잘못된걸 알았다. -- 오실로스코프 만세. 이것이 되니까 겨우 일주일동안 본 Disconnected 화면을 벗어나고 행복한 Signal out of range 에러를 볼 수 있었다.. ㅠㅠ
- 나중에 보니 VSYNC카운트를 잘못하고 있었다.... 잘 맞추니 위처럼 나왔다. 근데 역시 25.175MHz 를 사용안하고 근사치로 20MHz로 맞추다보니 몇초 지나니까 VSYNC를 잠깐 잃어서 모니터가 잠깐 꺼져따가 다시 켜진다. ㅋㅋ 뭐... 그래도 넘 좋당..

배운내용
- 삽질한다고 될일이 아니다. 디버그 장비가 필요 ...
- 하드웨어는 타이밍맞는 놈 돈이 들어도 미리 갖고 있는게 정신건강에 좋다.
- 모니터 테스트할땐 전용 모니터 한대쯤은 마련하자. 스펙을 보고 있는 메인 PC의 모니터를 계속 빼따 꼈다하면 대략 정신건강 저하 및 의욕상실을 부른다. --;

더보기

'프로젝트 > CPU 설계' 카테고리의 다른 글

microcode  (2) 2010.12.08
VGA 테스트 성공!  (2) 2009.01.15
cpu isa design issue  (0) 2009.01.14
address/data bus issue  (2) 2008.12.22
compiler basic phase  (0) 2008.12.13
VGA programming  (2) 2008.12.09
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. BlogIcon 너굴팬더 2008.12.09 07:51 신고  댓글주소  수정/삭제  댓글쓰기

    저도 요즘 디스플레이관련 프로젝트를 준비중인게 있는데 솔직히 아는게 별로 없어서 고민입니다. 검색하면 원론적인 것만 나오고 VGA 출력시 타이밍관계, 신호생성방법, 출력신호레벨, 등등.... 이런 테크니컬한 부분은 찾기가 힘들어서 진도가 안나오네요. 힌트 좀 주시면 나중에 테스트보드 만들때 드리도록 하죠. ^^

  2. BlogIcon broneri 2008.12.09 08:11 신고  댓글주소  수정/삭제  댓글쓰기

    분명 잘하시리라 믿습니다 ^^ 만일 유명한 팬더님의 보드를 주신다면 낼름 받겠습니다 ^^!
    타이밍 관련해서 제가 도움받은 사이트는 다음과 같습니다.
    http://www.epanorama.net/documents/pc/vga_timing.html
    신호레벨은 RGB말고는 TTL 5v그대로 흘리면되고요. 저항은 Rx모니터 딴에 75Ohm termination resistor가 있고요. R,G,B 아날로그 신호는 0V가 검정, 0.7V가 full color intensity입니다 ^^ (약 460Ohm을 달면된거 같은데 안달아도 모니터에 문제되진 않더라고요 ㅎㅎ..)
    아는게 많지는 않지만, 도움받은 만큼 돌려드리고(?) 싶네요.




일단 isa (instruction set archiecture)는 8 bit를 1 word (하나의 최소 명령어 단위)로 잡아보았습니다. (아직은 많은 고민이 있네요.)

역시 아무래도 나중에 wire wrapping의 고통을 줄이기 위해서는 RISC (Reduced Instruction Set Computer) 방식을 사용해야 할것 같습니다.
RISC의 경우 CISC (Complex Instruction Set Computer)와는 다르게 1 instruction은 1 cycle에 끝나게 됩니다. 물론 RISC가 pipe line을 지원하면 총 pipeline stage를 거쳐야 명령어 처리가 되겠지만 말이에요. 뭐, 저에겐 pipe lining은 사치이니까요 ^^;

크게 현재는 최소한의 RISC instruction들로 구성한 후 software (assemble coding)에서 많은 구차한 (?) 일을 하도록 할 생각입니다. 아무래도 하드웨어 설계가 복잡해지는 것 보단 차라리 assembler simulator를 Windows용으로 하나 만들어서 거기서 코딩&디버깅 한 후 EEPROM에 올리는게 날것 같아서 말이지용...

대충 크게 one instruction은 다음의 모양을 할것 같습니다.
8bit word = 4bit OPCODE | 4bit register selector
                4bit OPCODE | 4bit #immediate

대충 잡은 최소 필요 Register file입니다.
Data Register : 4bit or 8bit Y, A, B
Addr Register : 16bit or 24bit PC, ADR
Flag Register : 1bit Fcmp

다음은 지원하려고 하고 있는 instruction set입니다. (Logic, Arith 관련 명령어는 74S181N을 이용하기 때문에 오른편엔 Mode, S0~S3, CARRYn, A==B핀의 설정값도 함께 적어보았습니다)

Logic
AND   Y = A & B : M=H, S=HHHL
OR    Y = A | B : M=H, S=HLHH
      Y = ~A    : M=H, S=LLLL

Arithmetic
ADD   Y = A + B : M=L, S=HLLH, Cn=L
SUB   Y = A - B : M=L, S=LHHL, Cn=H

INC   A = A + 1 : M=L, S=HHHH, Cn=H
DEC   A = A - 1 : M=L, S=LLLL, Cn=L
COM   Fcmp <- A == B : A=B


Register Move
MOV_Y2A      : A = Y
MOV_A2B      : B = A
MOV_B2A      : A = B

Immediate
SetADR #addr : ADR = #addr

Memory Load/Store
Load A       : A = [ADR]
Save A       : [ADR] = A

Jump Control
JMP          : PC = ADR
JMP_EQU      : if ( Fcmp ) PC = ADR
JMP_NEQ      : if ( !Fcmp ) PC = ADR

스택 명령을 지원할 것인지. 아니면 arm처럼 함수 호출후 돌아올 링크 레지스터 (lr)을 둘지 결정을 못했네요.  그리고 ~A 명령이나 INC, DEC는 과연 필요한 명령어 인지도 의심이 가네요 --;....

현재 ALU는 4bit 74S181N을 갖고 있어서 이를 활용하려는 계획인데 문제는 8bit ALU가 되기 위해서는 74S181N 두개를 연결해줄 74S182가 필요하다는 것입니다. Carray Lookahead를 지원하는 74칩인데, 이 역시 구하기 하늘에서 별따기 같네요.
그냥 몇 명령어에 대해서 직접 GAL을 이용하여 74S182를 흉내내는 식도 고려해 보고 있습니다.

겨울이 깊어지고 추워지니까 취미활동도 둔화되네요.

어쨋든 저에게 중요한 설계 isa design decision factor는 다음과 같습니다.
1. 가장 최소의 wire wrapping 선을 유지한다.
2. 가능하면 C 언어 지원을 고려한다 (함수 호출을 위한 stack지원, 포인터 지원을 위한 간접 주소 어드레싱 모드 지원)
3. 컴파일러에게 보다 수월한 backend register mapping이 가능토록 instruction들의 폭넓은 register selection 지원

일단 isa를 정하고, 그 후에 실제 timing budget을 계산해봐야 할것 같습니다.

'프로젝트 > CPU 설계' 카테고리의 다른 글

microcode  (2) 2010.12.08
VGA 테스트 성공!  (2) 2009.01.15
cpu isa design issue  (0) 2009.01.14
address/data bus issue  (2) 2008.12.22
compiler basic phase  (0) 2008.12.13
VGA programming  (2) 2008.12.09
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



Address/Data bus 설계

Big Mess O'Wire의 경우 data bus는 8 bit, address bus는 24bit를 사용하고 있습니다.
Magic1은 역시 address bus 24 bit (device select를 위해 2bit 사용, 한 device는 4M) data bus 8bit를 사용하고 있지요.

broneri cpu는 어드레스 버스는 적어도 24bit 이상은 만들어야 할 것 같군요. data bus는 8bit를 사용하는게 wiring을 줄이는 (wiring == pain ㅎㅎ; ) 방법이 될듯 합니다.

CISC or RISC 설계

BMOW의 경우 EEPROM에 BMOW microcode 실행 루틴이 들어 있습니다. 이렇게 함으로써 타 instruction set을 쉽게 포팅할 수 있게 설계되어 있습니다.


Magic1  역시 마이크로 코드 방식으로 동작하며 아래와 같은 블럭 다이어그램을 갖습니다.

저의 경우 RISC 방식 (사실 어떻게 보면 native microcode set)을 사용하기만 하면 될듯하군요. 향후 software 컴파일러 설계 시 risc 컴파일러를 만들게 되면 그만큼 cpu isa는 간단하지만 컴파일러의 컴파일 최적화 복잡도가 올라갈 수 있습니다. 그때 쯤 가면 기존의 micro code와 유사한 risc cpu에 cisc isa 해석기를 두면 될것 같다는 생각도 드네요.

CPU speed

BMOW는 2MHz로 동작하고 있습니다. 다소 느린편이지요. 또한 Magic1 역시 4.09MHz로 동작하고 있습니다. Magic1의 경우 MMU라고 할 수 있는 hardware page table을 지원하고 있어서 보다 소프트웨어에 대한 지원을 한다고 볼 수 있겠네요. 각 소프트웨어는 독립적인 주소 공간을 갖을 수 있으므로 보다 multi-tasking OS나 software flatform을 작성하기 용이 할 것 같습니다.

 저의 경우 VGA화면에서 게임이 동작되길 바라고 있기 때문에 최소 25.175MHz (for Video system)이상이어야 원활한 화면 재생이 될 것 같은데요. 문제는 사용하고 있는 74LS TTL 시리즈는 20MHz이상에 대해서는 동작이 제대로 되지 않기 때문에 cpu speed가 20MHz 이하로 결정된다는데 문제가 있습니다. 특히 ALU 부분은 74LS181N을 사용하고자 하고 있기에 이 speed constraint는 고정이라고 할 수 있겠네요.

만일 정말 제대로 된 화면 전환을 위해서는 video system을 따로 만들어서 accelerator 방식의 가속기 API를 제공함으로써 cpu system의 속도 제약에 대한 보상을 해줄 수 있을것 같습니다. 일단은 간단한 tile API와 sprite API를 제공하면 될것 같은데 뭐 아직 먼 얘기니까 ^^; 그때 가서 한번 해봐야겠지요

요 며칠동안 써든어택을 하면서 --; 놀기만 했네요. 어차피 개인적인 프로젝트니까, 쉬엄쉬엄 필 꽂힐때 천천히 진행해야 겠습니다. ^^


'프로젝트 > CPU 설계' 카테고리의 다른 글

VGA 테스트 성공!  (2) 2009.01.15
cpu isa design issue  (0) 2009.01.14
address/data bus issue  (2) 2008.12.22
compiler basic phase  (0) 2008.12.13
VGA programming  (2) 2008.12.09
VGA Smile Image!  (0) 2008.12.05
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. BlogIcon kkamagui 2008.12.23 12:50 신고  댓글주소  수정/삭제  댓글쓰기

    와우~ 멋지네요 ;)
    CPU라는 놈을 이렇게 만들 수도 있군요. ^^)/~
    기대하겠습니다. 멋진 녀석(?)을 만들어 주세요 ;)




작년에 컴파일러 사외 강의를 듣고 정리한 내용입니다.


frontend
-----------------------------------
lexical analysis
- word check [scanning]
   => fsm (not string tokenizer)

syntax analysis
- sentence(grammer) check [parsing]
   => parsor = fsm+stack

semantic analysis
- type checking 
   => symbol table

intermediate representation
- AST or 3-address code(Text) IR

syntax-directed translation


back end
-----------------------------------
optimization
- formulation (goal:size,speed)
- analysis
- transform, perf. estimation

CFA(Control Flow Analysis)
  - Build CFG (Basic Blocks)
     => DFS (Depth First Search) => DFT 생성 가능(Edge) => Unreachable code elimination 활용
  - Build Dominatance(Dominator Tree, postdominance) => CSE 활용
  - Find Loop (back edge with DFT)

DFA(Data Flow Analysis)
  - DFI
  - Local Data flow Analysis
  - Global Data flow Analysis
  - Def-Use/Use-Def chains

  DFA로 풀수 있는 문제
  1. available expression problem: 이전에 사용한 변수가 변경이 없었는지 확인
  2. reaching definition problem: 값 정의된 변수가 어디서 사용되는지
  3. aliasing problem: 어떤 변수가 같은 메모리를 가리키는지
  4. live variables problem.

대부분 DFA 기술은 DFI (Data)와 DFE (Data Flow Equations, SET의 수학표현, 함수, 필터)로 표현됨

Reaching Definition: Fs(in[S]) = gen[S] ∪ (in[S] - kill[S])
Available Expression: 
for each basic block B do
   out[B] = egen[B] ∪ (Universal - ekill[B])
od
while changes to any out[B] occur do
   for each segment X in DFS order do
     in[B] = ∩ out [Pb]; // all predecessors Pb of B
     out[B] = egen[B] ∪ (in[B] - ekill[B]);
   od
od

Dependency Analysis
- Read After Write: flow dependence(true dependency)
- Write After Read: anti dependence (false)
- Write After Write: output dependence (false)

Optimization
A. Elimination of redundancies
    a. Dead code (mark instruction essential results)
    b. Redundant computations or expressions
       - Value numbering and common subexpression elimination)
       - code motion and hoisting/sinking
       - partial redundancy elimination
       - algebraic transformations
      CSE (Common subexpression elimination)
perform DFA to compute in[B]; // available expression collect
for each expression e in in[B] of every block B do
   locate the evaluation of e at a statement s in B;
   if s = null or // if there is no statement in B that evaluates e
     e has been killed before s then continue;
   R <- a set of statements Si in all predecessors Pi of B
     such that e is evaluated in Si;
   substitute a new temporary Te for e in s;
   for each Si in R do
     insert 'Te = e' immediately before Si;
     substitute Te for e in Si;
   od
  od
B. Progpagation of data
   a. constants propagation
   b. constants folding
   c. copy propagation
C. Peephole Optimizations
   a. DAG(Directed Acyclic Graph)사용
   b. Machine idioms
   c. Peephole of control flow
     - Tail merging
     - Straightening : 불필요한 브렌치 제거
     - Branch simplifications : branch시 안가는 코드, 브렌치 전체 제거
D. Loop Optimizations
   a. Unswitching : loop안 branch를 loop 밖으로
   b. loop elimination: zero count loop 제거
   c. loop inversion: while -> do while
   d. strip mining 
   e. loop unrolling
   f. optimizations of induction variables

code generation
-----------------------------------
Instruction selection
a. macro expansion
b. L-R parsing
c. tree parsing(pattern matching)
d. machine description
Register allocation
a. Web (from DU chain)
b. Register coalescing (맞닿은 copy 변수 변수 없애기)
c. Graph coloring (with Interference graph)
Instruction cheduling

'프로젝트 > CPU 설계' 카테고리의 다른 글

cpu isa design issue  (0) 2009.01.14
address/data bus issue  (2) 2008.12.22
compiler basic phase  (0) 2008.12.13
VGA programming  (2) 2008.12.09
VGA Smile Image!  (0) 2008.12.05
about broneri homebrew computer  (0) 2008.12.04
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



2004년에 시작. ㅎㅎ;; (정말 생각날때 조금씩 하고 있습니다)
이전까지는 floppy상의 filesystem에서 pe exe를 로드해 4G 프로세스로 실행하는 protected mode console os였는데, 요즘 (2008-12-07) 문득, 이를 windows os로 만들고 싶어졌습니다.


현재 구현 현황
-----------------------------------------------

bootloader
protected mode
process management
soft task switch
system call : task yield
scheduling : round-robin 
interrupt
system timer
crt driver
keyboard driver
semaphore
memory management : mm_alloc(), mm_free()
key interrupted i/o : getch(), gets()
mini-shell : help, cls, ps, dump
paging : 4G virtual memory mangement per each process
file system : fat12/16
application executable format : PE
svga driver
mouse driver
windows system


'프로젝트 > minios OS 개발' 카테고리의 다른 글

minios on ipad  (0) 2011.12.07
minios - real IU !!  (1) 2011.02.11
minios x86 homebrew os project  (0) 2008.12.13
IBM VGA programming  (0) 2008.12.13
minios mouse control  (0) 2008.12.13
minios on svga  (0) 2008.12.10
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



오후 1:35 2008-12-08
IBM VGA programming
=========================================

IBM VGA프로그래밍은 다음 기능을 사용하여 하게 된다.
- VGA low-level register (vga i/o)
- VGA/VESA BIOS (int 10h)

참고: VGA는 거의 표준 호환되지만 SVGA부터는 비디오카드 벤더마다 각자 자신만의 3D가속이나 여러 함수를 추가하였다.

기본적으로 VGA BIOS 코드는 VGA low-level register를 사용하고 있다.
SVGA를 지원하기 위해 extended BIOS로 VESA BIOS기능으로 같은 10h인터럽트에 AL레지스터에 4Fh를 주어 동작된다.

모든 low-level register는 i/o port를 통해서 접근된다.
IBM PC는 메모리 버스와 I/O버스가 구분되어 있다.
따라서 low-level register는 IBM pc가 real mode이든 protected mode이든 i/o를 통해서
접근 가능하다.


low-level register에는 다음과 같은 군이 있다.
----------------------------------------------------
Graphic Register - CPU가 video RAM을 어떻게 접근할지 방법을 설정
Sequencer Register - video data를 DAC에게 어떻게 보낼지 설정
Attribute Controller Register - EGA/CGA compatibility를 위해사용되는 16/64 칼라 팔레트를 선택
CRT Controller Register - 어떻게 video가 display로 출력될지 방법을 설정
Color Register - 256 color palette 설정
External Register - video system 설정용 여러 레지스터


VGA BIOS를 이용
-----------------------------------------------------
이를 쉽게 프로그래밍할 수 있도록 BIOS에서 인터럽트 벡터로 제공하고 있다.
이를 사용하기 위해서 cpu레지스터에 파라미터를 넣고 int 10h를 호출하게 된다.
BIOS기능 호출은 real mode에서만 가능하다.

보호모드에서는 BIOS 호출을 할 수 없다. 
보호모드에서 BIOS를 사용해서 VGA를 설정하고 싶다면 다음과 같은 방법을 사용한다.
- real mode에서 video 설정을 끝내고 protected mode로 들어감.
- protected mode에서 unreal mode로 들어와서 video를 설정하고 다시 protected mode로 감.
- 보호모드에서 V86 Task를 생성해서 이 emulate된 real mode상에서 비디오 설정
- VBE (VESA Bios Extension)을 사용하여 보호모드에서 직접 VESA BIOS를 호출. (비디오카드에 따라 제공안할 수 있음)

참고사항
------------------------------------------------------
http://forum.osdev.org/viewtopic.php?f=1&t=18445
Note that you can use PMode <-> RMode switching or v86 for using BIOS calls, but the second method is generally not recommended for disk IO (cf. Windows 95!). PMode <-> RMode switching also needs to be done very carefully and can get messy. If you go to long mode, you will need drivers (there's no v86 mode).

참고
-------------------------------------------------------
FreeVGA (low-level VGA)
http://www.stanford.edu/class/cs140/projects/pintos/specs/freevga/freevga.htm

VBE3
http://www.vesa.org/vbe3.pdf

VESA/VGA BIOS emulation
http://unix.derkeiler.com/pdf/Newsgroups/comp.os.vms/2004-12/1177.pdf

Drawing In Protected Mode
http://wiki.osdev.org/Drawing_In_Protected_Mode

IBM BIOS
http://www.bioscentral.com/postcodes/ibmbios.htm

'프로젝트 > minios OS 개발' 카테고리의 다른 글

minios on ipad  (0) 2011.12.07
minios - real IU !!  (1) 2011.02.11
minios x86 homebrew os project  (0) 2008.12.13
IBM VGA programming  (0) 2008.12.13
minios mouse control  (0) 2008.12.13
minios on svga  (0) 2008.12.10
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


마우스 제어가 되네요!
어제 계속 마우스 인터럽트 (irq 12h)가 발생되지 않아서 알고 봤더니, PIC (programmable interrupt controller)를 잘못 짜고 있었네요..;

이 말이 나를 살렸습니다 ㅡㅡ;
Also remind that prior to receive IRQ12, you must enable this interrupt at
the slave PIC (will be #4, iirc) and the cascade interrupt at master PIC (#2).
You must also send a "end of interrupt" to both PICs at the end of your ISR
(i.e. "mov al, 20h; out 20h,al; out 0a0h, al").


아래는 640x480x16bpp상에서 minios를 실행한 화면입니다.
아쉽게도 --; minifat 파일시스템의 버그로 300K 쯤 넘는 부분을 읽다가 제대로 못읽는 경우가 생기는군요.. (으흑.. 다시 파일시스템 테스트를 잘 해봐야겠네요)

바탕화면으로 쓰려던것은 태희아가씨였는데.. ㅠㅠ 크헉.. 하필이면 이마만 나오냐고..

아직 마우스 버튼 제어가 어색해서 윈도우 창을 드래그 해서 이동시키는게 잘 안되고 있네요..

음.. 오늘까지 일단 이정도 해놓고.. cpu 설계 쪽으로 한번 해봐야겠네요.

더보기


 

'프로젝트 > minios OS 개발' 카테고리의 다른 글

minios on ipad  (0) 2011.12.07
minios - real IU !!  (1) 2011.02.11
minios x86 homebrew os project  (0) 2008.12.13
IBM VGA programming  (0) 2008.12.13
minios mouse control  (0) 2008.12.13
minios on svga  (0) 2008.12.10
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST


음.. broneri homebrew project에는 minios를 두지 않으려 했는데 블로그를 두개로 운영하려니 귀찮네요..; (http://minios.tistory.com 는 천천히 없애야겠네요 )



윈도우 시스템은 역시나 예전에 만들어두었던 minigui를 사용하였습니다. 4년이 넘은 코드에 의존하고 있다니 --;

아래는 mini gui가 최초(?)로 사용된 arm rtos 인 usys os의 화면입니다.
이 땐 LCD컨트롤러만 잡으면 기본적으로 linear한 frame buffer가 잡혔지요. 그리고 터치 드라이버를 작성해서 터치로 설정할 수 있게 했었습니다.

어쨋든 Mini-GUI 소스 헤더에  2004/10/18라는 타임 스탬프는 저를 놀라게 하는군요. -_- 세월은 참 빠르구나.. 드뎌 mini fat과 mini gui가 모두 mini os로 이식되는구낭. ㅠ.ㅠ (혼자 감회가 새로움) ㅋㅋ

다시 x86 mini os로 돌아와서.. 문제는 아직 마우스를 잡지 않아서 아무런 컨트롤도 할 수 없다는 것이었습니다. 뜨헉...
어서 마우스를 먼저 잡아야 할것 같네요.

아래는 svga vesa 114h, 800x600x16bpp 입니다.

아래는 svga vesa 111h, 640x480x16bpp입니다.

부팅 시 리얼 모드에서 아래와 같이 먼저 svga를 vesa bios를 이용하여 설정합니다.
;   mov    bx, 0x114 ; ok, 800x600 5:6:5
   mov    bx, 0x111 ; ok, 640x480 5:6:5
   or     bh, 0x40 ; want linear model, clear screen (LFB linear Frame buffer)
   mov   ax, 0x4F02 ; change mode
   int   0x10 ; go
이 때 LFB (linear frame buffer)의 주소가 어디서부터 시작하는지 알아내야 합니다. (VMWare의 경우 두 svga 모드 모두 0xF0000000 번지였습니다. )

따라서 꽁수(?)를 부려서 0x9000번지에 vbe_mode_info 정보를 담아두도록 했습니다.
   mov ax, 0x900
   mov es, ax ; save ModeInfoBlock to 900:0h = 0x9000
   mov ax, 4f01h ; get vbe_mode_info
  ; mov cx, 0x114 ; vbe mode (800x600 5:6:5)
   mov cx, 0x111 ; vbe mode (640x480 5:6:5)
   mov di, 0x0   
   int 0x10

그리곤 32 bit protected kernel의 시작 엔트리가 호출되면 잽싸게 0x9000번지의 소중한(?) 현재 svga설정 값들을 받아왔습니다.

VBEMode* p = (VBEMode*)0x9000;
lfb_width = p->bytes; // 한 줄 scan line의 바이트 수
lfb = p->lfbaddr; // lfb 시작 주소 (젤중요)
lfb_xres = p->xres;
lfb_yres = p->yres;

그리고 최초 kernel의 virtual memory mapping시 lfb 주소 공간도 매핑하도록 추가하였습니다.
void vmm_map_kernel( unsigned char* phys_page_directory )
{
vmm_maps( "boot", phys_page_directory, (unsigned char*)PHYS_BOOT_START, (unsigned char*)VIRT_BOOT_START, PHYS_BOOT_PAGES );
vmm_maps( "bios", phys_page_directory, (unsigned char*)PHYS_BIOS_START, (unsigned char*)VIRT_BIOS_START, PHYS_BIOS_PAGES );
vmm_maps( "kheap", phys_page_directory, (unsigned char*)PHYS_KHEAP_START, (unsigned char*)VIRT_KHEAP_START, PHYS_KHEAP_PAGES );
vmm_maps( "kernel", phys_page_directory, (unsigned char*)PHYS_KERNEL_START, (unsigned char*)VIRT_KERNEL_START, PHYS_KERNEL_PAGES );
vmm_maps( "vmm", phys_page_directory, (unsigned char*)PHYS_VMM_START, (unsigned char*)VIRT_VMM_START, PHYS_VMM_PAGES );

vmm_maps( "lfb", phys_page_directory, (unsigned char*)PHYS_LFB_START, (unsigned char*)VIRT_LFB_START, PHYS_LFB_PAGES );
}
아주 재미있는 것은 아까 받아온 0xF0000000라는 주소는 언뜻보기엔 가상주소같은데 physical 주소라는 것이지요! 

이제 점을 찍을 수 있습니다. 

void my_draw_setpixel( int x, int y, COLOR cr )
{
char* vmem = (char*)lfb;

*((unsigned short*)(vmem + (lfb_width*y) + x * 2)) = cr;

'프로젝트 > minios OS 개발' 카테고리의 다른 글

minios on ipad  (0) 2011.12.07
minios - real IU !!  (1) 2011.02.11
minios x86 homebrew os project  (0) 2008.12.13
IBM VGA programming  (0) 2008.12.13
minios mouse control  (0) 2008.12.13
minios on svga  (0) 2008.12.10
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST



VGA 프로그래밍을 위해서 먼저 VGA Rx인 Monitor와 연결하기 위해서는 VGA D-Sub 3열 female connector의 핀 배열에 대해서 알아봐야 할 것 같습니다.

Pin Description

VGA female pin 번호는 다음과 같습니다. [1]

15 pin highdensity D-SUB female connector layout
실제로는 아래처럼 생겼습니다. [3] (당연한 얘기겠지만요 ^^;)
 


사실 VGA의 핀의 기능은 그동안 조금씩 바뀌어 왔습니다. [2] 그러나 그런 것들은 대부분 Tx (Graphic card)와 Rx (Monitor)간의 DDC (Display Data Channel) 컨트롤 (예를들어 모니터의 메뉴를 누르면 OSD -On Screen Display-가 뜨게 되고 여러 설정을 하면 그것을 Tx에게 보내게 됩니다. 이 때 DDC 채널을 통해서 제어가 되게 됩니다. 또한 초기에 어떤 모니터이고 어떤 해상도와 Display Range를 지원하는지를 Rx가 Tx에게 알려주는데 이것이 EDID 정보입니다. 이때도 DDC를 통해서 조절되게 됩니다.)과 관련된 것들입니다. 


What is important for test

위의 그런 복잡한 핀들이 많습니다만, 사실 OSD나 DDC컨트롤을 위해서 생각할 만큼 초기에는 여유가 없습니다. 가장 기본적으로 동작되어야 할 핀들은 다음과 같습니다.
RED, BLUE, GREEN은 Analog신호로 0.7V가 가장 높은 Intensity로 모든 값이 0.7V라면 흰색이 나오겠죠? 물론 모두 0V라면 검정색이 나오게 됩니다. 
R,G,B의 Ground는 0V를 연결하면 됩니다.
GND도 역시 0V를 연결하고, +5V는 5V VCC를 연결합니다. SGND는 0V로 연결하고, 제일 중요한 VSYNC, HSYNC는 +5V, 0V로 TTL레벨 디지털 신호로 보내면 됩니다. 
VSYNC와 HSYNC는 대부분 1값 (5V)를 갖다가 특정 시간이 되면 0으로(0V)내려가게 됩니다. (active edge가 low라는 말이겠죠?)

VSYNC, HSYNC timing
VGA는 오실레이터를 25.175MHz를 쓰면 딱 맞습니다. [4]

먼저 HSYNC신호를 위한 타이밍은 아래와 같습니다.
Horizonal Dots         640     640     640        
Vertical Scan Lines    350     400     480
Horiz. Sync Polarity   POS     NEG     NEG
A (us)                 31.77   31.77   31.77     Scanline time
B (us)                 3.77    3.77    3.77      Sync pulse lenght 
C (us)                 1.89    1.89    1.89      Back porch
D (us)                 25.17   25.17   25.17     Active video time
E (us)                 0.94    0.94    0.94      Front porch
         ______________________          ________
________|        VIDEO         |________| VIDEO (next line)
    |-C-|----------D-----------|-E-|
__   ______________________________   ___________
  |_|                              |_|
  |B|
  |---------------A----------------|

그리고 VSYNC를 위한 타이밍은 아래와 같습니다.

Horizonal Dots         640     640     640
Vertical Scan Lines    350     400     480
Vert. Sync Polarity    NEG     POS     NEG      
Vertical Frequency     70Hz    70Hz    60Hz
O (ms)                 14.27   14.27   16.68     Total frame time
P (ms)                 0.06    0.06    0.06      Sync length
Q (ms)                 1.88    1.08    1.02      Back porch
R (ms)                 11.13   12.72   15.25     Active video time
S (ms)                 1.2     0.41    0.35      Front porch
         ______________________          ________
________|        VIDEO         |________|  VIDEO (next frame)
    |-Q-|----------R-----------|-S-|
__   ______________________________   ___________
  |_|                              |_|
  |P|
  |---------------O----------------|

Put it all

전체적인 흐름은 다음과 같이 볼 수 있습니다.
저 같은 경우는 VGA connector를 wire wrap을 했지만 납땜을 해도 되겠죠?

보드 상 VGA (RGB신호 핀) --> wire wrap ---> 460 ohm --> D-Sub 15F (connector) ---> VGA cable ---> LCD Monitor

Rx단에 75Ohm이 있기 때문에 Tx 5V 신호를 0.7V로 맞추기 위해서
          V1*R2
V2 = ---------
          R1+R2
이기 때문에
   5V
--------- => 0.7V 정도
460 + 75
즉 RGB 신호에 460Ohm를 달아야 0.7V가 Rx로 전달되겠죠? (사실 이부분은 제가 확실치는 않네요.. ^^; )

RAMDAC
RAMDAC 칩이 있다면 RGB Analog신호로 변환 할 수 있습니다.
RAMDAC는 다음에 리스트를 참고하여 골라야 합니다. [5] 만일 RAMDAC가 없다면 R,G,B 디지털 신호레벨을 R2R resistor ladder를 활용하여 DAC를 통하게 해야 할것입니다.

Example

제가 진행한 부분에 대해 블로그를 참고하시면 됩니다. [6]


Reference

[1]. VGA (VESA DDC) pinout, http://pinouts.ru/Video/VGAVesaDdc_pinout.shtml

[2]. Old VGA Pin description, http://pinouts.ru/Video/VGA15.shtml

[3]. VGA connector, http://en.wikipedia.org/wiki/VGA_connector, Wikipedia
[4]. VGA Timing, http://www.epanorama.net/documents/pc/vga_timing.html
[5]. ramdac list, http://www-user.tu-chemnitz.de/~kzs/tools/whatvga/ramdac.txt

[6]. VGA example, broneri.tistory.com

'프로젝트 > CPU 설계' 카테고리의 다른 글

cpu isa design issue  (0) 2009.01.14
address/data bus issue  (2) 2008.12.22
compiler basic phase  (0) 2008.12.13
VGA programming  (2) 2008.12.09
VGA Smile Image!  (0) 2008.12.05
about broneri homebrew computer  (0) 2008.12.04
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. BlogIcon kkamagui 2008.12.10 01:30 신고  댓글주소  수정/삭제  댓글쓰기

    완전 멋지군요. @0@)-b
    깜짝 놀랐습니다. ;) 기대할께요 ㅎㅎ



티스토리 툴바