ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [OS] 17. Video Scroll
    OS/OS from Scratch 2021. 7. 2. 22:34

    서론

    이번 강의에서는 화면에서 스크롤을 구현해보겠습니다. 해당 Github 강의는 다음과 같습니다.

    https://github.com/cfenollosa/os-tutorial/tree/master/17-video-scroll

     

    cfenollosa/os-tutorial

    How to create an OS from scratch. Contribute to cfenollosa/os-tutorial development by creating an account on GitHub.

    github.com


    코드

    이번 강의에서 구현할 기능은 Scroll 기능입니다. 본 강의에서의 Scroll은 화면에 문자열이 마지막 행까지 가득 찬 상태에서 문자열을 더 출력하려는 경우, 스크린의 행들을 이전 행으로 하나씩 밀어 마지막 행에 빈 행을 만드는 것을 의미합니다.

    이번 강의의 코드들도 비교적 간단하여, 주석으로 설명을 대체하겠습니다.

    util.h

    void memory_copy(char *source, char *dest, int nbytes);
    void int_to_ascii(int n, char str[]);

    util.c

    // 메모리 복사 (stdlib의 memcpy)
    void memory_copy(char *source, char *dest, int nbytes) {
        int i;
        for(i=0; i<nbytes; i++) {
            *(dest + i) = *(source + i); 
        }
    }
    
    // 정수를 문자로 변환 (stdlib의 itoa)
    void int_to_ascii(int n, char str[]) {
        int i, sign = n;
        if(sign<0) {
            n = -n;
        }
        i = 0;
        while(n>0) {
            str[i++] = n%10+'0';
            n /= 10;
        }
    
        if(sign<0) {
            str[i++] = '-';
        }
        str[i] = '\0';
        
        // str 뒤집기
        int str_len = i;
        for(i=0; i<str_len/2; i++) {
            char tmp = str[i];
            str[i] = str[str_len-1-i];
            str[str_len-1-i] = tmp;
        }
    }

    screen.c

    screen.c의 print_char 함수에 offset이 화면 크기보다 큰 경우를 처리해 줍니다.

    // VGA 직접 접근해 문자 출력
    // col, row 음수이면 현재 커서 위치에 출력
    // attr 0이면 white on black
    // 다음 문자의 offset 리턴
    // 커서를 리턴된 offset위치로 이동
    int print_char(char c, int col, int row, char attr) {
        unsigned char *vidmem = (unsigned char*) VIDEO_ADDRESS;
        if(!attr) {
            attr = WHITE_ON_BLACK;
        }
    
        // 좌표가 범위 밖일 때 경고 문자 출력
        if(col>=MAX_COLS || row>=MAX_ROWS) {
            vidmem[2*(MAX_COLS)*(MAX_ROWS)-2] = 'E';
            vidmem[2*(MAX_COLS)*(MAX_ROWS)-1] = RED_ON_WHITE;
            return get_offset(col, row);
        }
    
        int offset;
        if(col>=0 && row>=0) {
            offset = get_offset(col, row);
        } else {
            offset = get_cursor_offset();
        }
    
        // 줄바꿈일때는 현재 row에 +1
        if(c=='\n') {
            row = get_offset_row(offset);
            offset = get_offset(0, row+1);
        } else {
            vidmem[offset] = c;
            vidmem[offset+1] = attr;
            offset += 2;
        }
    
        // offset이 화면 크기보다 크면 스크롤함
        if(offset>=MAX_ROWS*MAX_COLS*2) {
            int i;
            // 현재 라인을 이전 라인으로 하나씩 밀음 
            for(i=1; i<MAX_ROWS; i++) {
                memory_copy(get_offset(0, i)+VIDEO_ADDRESS, get_offset(0, i-1)+VIDEO_ADDRESS, MAX_COLS*2);
            }
            // 마지막 줄을 빈칸으로
            char *last_line = get_offset(0, MAX_ROWS-1) + VIDEO_ADDRESS;
            for(i=0; i<MAX_COLS*2; i++) {
                last_line[i] = 0;
            }
            // 범위 넘은 offset을 스크롤 다음 줄로 밀음
            offset -= 2*MAX_COLS;
        }
    
        set_cursor_offset(offset);
        return offset;
    }

    kernel.c

    Scroll 기능을 테스트할 수 있도록 kernel을 설정합니다.

    #include "../drivers/screen.h"
    
    void main() {
        clear_screen();
        
        int i;
        for(i=0; i<24; i++) {
            char str[255];
            int_to_ascii(i, str);
            kprint_at(str, 0, i);
        }
    
        kprint_at("This text forces the kernel to scroll, Row 0 will get disapperad.", 60, 24);
        kprint("By this text, the kernel will scroll again, and row 1 will disapper.");
    }

    실행 결과

    화면에 0부터 23까지 출력되다가, "This text forces..." 문자열에 의해 Scroll이 발생하면서 첫 번째 행이 밀리고, "By this text... "  문자열에 의해 Scroll이 발생하면서 두 번째 행이 밀리는 것을 관찰할 수 있습니다.

    실행결과

    'OS > OS from Scratch' 카테고리의 다른 글

    [OS] 19. Interrupt-irqs  (0) 2021.07.12
    [OS] 18. Interrupts  (0) 2021.07.03
    [OS] 16. Video Driver  (0) 2021.07.02
    [OS] 15. Video Ports  (0) 2021.06.30
    [OS] 14. Checkpoint  (0) 2021.06.28
Designed by Tistory.