화면에 그리기위해

vram에 뭔가 써야함.

naskfunc.nas에 write_mem8 함수 추가

;naskfunc
;TAB=4

[FORMAT "WCOFF"]        ;오브젝트 파일 만드는 모드
[INSTRSET "i486p"]       ;486명령사용하고싶다 작성
[BITS 32]               ;32비트모드용 기계어 만듬

;오브젝트 파일 위한 정보
[FILE "naskfunc.nas"]   ;소스파일명 정보
    GLOBAL  _io_hlt,_write_mem8     ;이프로그램에 포함된 함수명

; 실제 함수

[SECTION .text]         ;오브젝트 파일에서는 이것을 쓴후에 프로그램을 쓴다.
_io_hlt:        ;void io_hlt(void);
    HLT
    RET

_write_mem8:    ; void write_mem8(int addr, int data);
    MOV ECX, [ESP+4]    ; [esp+4]에 addr이 들어있으니 ecx에 읽어들임
    MOV AL, [ESP+8]     ; [ESP+8]에 data가 있으니 al에 읽어들임
    MOV [ECX], AL
    RET

 

 

 

nask에 instrset으로 486용임을 알림

cpu를 32비트 모드로 사용중이라 32비트 레지스터 사용 ecx

vram 구간 전체에 15를 써서 하얗게 됨

 

bootpack.c

void io_hlt(void);
void write_mem8(int addr, int data);

void HariMain(void)
{
    int i;
    
    for (i = 0xa0000; i<= 0xaffff; i++)
    {
        write_mem8(i, 15);  //move byte [i], 15
    }

fin:
    io_hlt();     //naskfunc.nas의 _io_hlt가 실행됨.
    goto fin;
}

 

* vram이 0xa0000에서 시작하는 이유

haribote.nas에서 vram에 0x000a0000으로 지정

 

 

 

 

줄무늬 만들기

i와 0x0f and 연산으로 줄무늬 만들기

void io_hlt(void);
void write_mem8(int addr, int data);

void HariMain(void)
{
    int i;
    
    for (i = 0xa0000; i<= 0xaffff; i++)
    {
        write_mem8(i, i & 0x0f);  //move byte [i], 15
    }

fin:
    io_hlt();     //naskfunc.nas의 _io_hlt가 실행됨.
    goto fin;
}

 

 

 

포인터 사용하기

write_mem8대신 포인터사용해줘도 지정가능

void io_hlt(void);
void write_mem8(int addr, int data);

void HariMain(void)
{
    int i;
    char *p;

    
    for (i = 0xa0000; i<= 0xaffff; i++)
    {
        p = i;
        *p = i & 0x0f;
        //write_mem8(i, i & 0x0f);  //move byte [i], 15
    }

fin:
    io_hlt();     //naskfunc.nas의 _io_hlt가 실행됨.
    goto fin;
}

 

 

 

색상 사용하기

색상 쓰기위해 rgb table 준비해서 팔레트 설정하는 내용

어셈블리 함수가 여러개 추가됨.

void io_hlt(void);
void io_cli(void);
void io_out8(int prot, int data);
int io_load_eflags(void);
void io_store_eflags(int eflags);

void init_palette(void);
void set_palette(int start, int end, unsigned char *rgb);

void HariMain(void)
{
    int i;
    char *p; //p라는 변수는 byte[]용 번지
    
    init_palette();

    p = (char *)0xa0000;

    for (i=0; i <= 0xffff; i++)
    {
        p[i] = i & 0x0f;
    }

    for(;;)
    {
        io_hlt();
    }
}

void init_palette(void)
{
    static unsigned char table_rgb[16 * 3] = {
        0x00, 0x00, 0x00,
        0xff, 0x00, 0x00,
        0x00, 0xff, 0x00,
        0xff, 0xff, 0x00,
        0x00, 0x00, 0xff,
        0xff, 0x00, 0xff,
        0x00, 0xff, 0xff,
        0xff, 0xff, 0xff,
        0xc6, 0xc6, 0xc6,
        0x84, 0x00, 0x00,
        0x00, 0x84, 0x00,
        0x84, 0x84, 0x00,
        0x00, 0x00, 0x84,
        0x84, 0x00, 0x84,
        0x00, 0x84, 0x84,
        0x84, 0x84, 0x84
    };

    set_palette(0, 15, table_rgb);
    return;
}

void set_palette(int start, int end, unsigned char *rgb)
{
    int i, eflags;
    eflags = io_load_eflags();  // 인터럽트 허가 플래그 값 가져옴
    io_cli();                   // 허가 플래그를 0으로 하여 인터럽트 금지
    io_out8(0x03c8, start);
    for (i=start;i<=end;i++)
    {
        io_out8(0x03c9, rgb[0] / 4);
        io_out8(0x03c9, rgb[1] / 4);
        io_out8(0x03c9, rgb[2] / 4);
        rgb += 3;
    }
    io_store_eflags(eflags);    // 인터럽트 허가 플래그를 본래 값으로 되돌림.
    return;
}

 

 

 

추가된 함수들

; naskfunc
; TAB=4

[FORMAT "WCOFF"]				; 오브젝트 파일을 만드는 모드	
[INSTRSET "i486p"]				; 486명령까지 사용하고 싶다고 하는 기술
[BITS 32]					; 32비트 모드용의 기계어를 만든다
[FILE "naskfunc.nas"]				; 원시 파일명 정보

		GLOBAL	_io_hlt, _io_cli, _io_sti, io_stihlt
		GLOBAL	_io_in8,  _io_in16,  _io_in32
		GLOBAL	_io_out8, _io_out16, _io_out32
		GLOBAL	_io_load_eflags, _io_store_eflags

[SECTION .text]

_io_hlt:	; void io_hlt(void);
		HLT
		RET

_io_cli:	; void io_cli(void);
		CLI
		RET

_io_sti:	; void io_sti(void);
		STI
		RET

_io_stihlt:	; void io_stihlt(void);
		STI
		HLT
		RET

_io_in8:	; int io_in8(int port);
		MOV		EDX,[ESP+4]		; port
		MOV		EAX,0
		IN		AL,DX
		RET

_io_in16:	; int io_in16(int port);
		MOV		EDX,[ESP+4]		; port
		MOV		EAX,0
		IN		AX,DX
		RET

_io_in32:	; int io_in32(int port);
		MOV		EDX,[ESP+4]		; port
		IN		EAX,DX
		RET

_io_out8:	; void io_out8(int port, int data);
		MOV		EDX,[ESP+4]		; port
		MOV		AL,[ESP+8]		; data
		OUT		DX,AL
		RET

_io_out16:	; void io_out16(int port, int data);
		MOV		EDX,[ESP+4]		; port
		MOV		EAX,[ESP+8]		; data
		OUT		DX,AX
		RET

_io_out32:	; void io_out32(int port, int data);
		MOV		EDX,[ESP+4]		; port
		MOV		EAX,[ESP+8]		; data
		OUT		DX,EAX
		RET

_io_load_eflags:	; int io_load_eflags(void);
		PUSHFD		; PUSH EFLAGS의 의미
		POP		EAX
		RET

_io_store_eflags:	; void io_store_eflags(int eflags);
		MOV		EAX,[ESP+4]
		PUSH	EAX
		POPFD		; POP EFLAGS의 의미
		RET

 

 

 

이전보다 더 다양한 색상으로 줄무늬가 그려짐.

 

 

박스 그리기

boxfill8 함수 만들어 박스 띄움

void io_hlt(void);
void io_cli(void);
void io_out8(int prot, int data);
int io_load_eflags(void);
void io_store_eflags(int eflags);

void init_palette(void);
void set_palette(int start, int end, unsigned char *rgb);
void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1);

#define COL8_000000     0
#define COL8_FF0000     1
#define COL8_00FF00     2
#define COL8_FFFF00     3
#define COL8_0000FF     4
#define COL8_FF00FF     5
#define COL8_00FFFF     6
#define COL8_FFFFFF     7
#define COL8_C6C6C6     8
#define COL8_840000     9
#define COL8_008400     10
#define COL8_848400     11
#define COL8_000084     12
#define COL8_840084     13
#define COL8_008484     14
#define COL8_848484     15

void HariMain(void)
{
    int i;
    char *p; //p라는 변수는 byte[]용 번지
    
    init_palette();

    p = (char *)0xa0000;

    boxfill8(p, 320, COL8_FF0000, 20, 20, 120, 120);
    boxfill8(p, 320, COL8_00FF00, 70, 50, 170, 150);
    boxfill8(p, 320, COL8_0000FF, 120, 80, 220, 180);

    for(;;)
    {
        io_hlt();
    }
}

void init_palette(void)
{
    static unsigned char table_rgb[16 * 3] = {
        0x00, 0x00, 0x00,
        0xff, 0x00, 0x00,
        0x00, 0xff, 0x00,
        0xff, 0xff, 0x00,
        0x00, 0x00, 0xff,
        0xff, 0x00, 0xff,
        0x00, 0xff, 0xff,
        0xff, 0xff, 0xff,
        0xc6, 0xc6, 0xc6,
        0x84, 0x00, 0x00,
        0x00, 0x84, 0x00,
        0x84, 0x84, 0x00,
        0x00, 0x00, 0x84,
        0x84, 0x00, 0x84,
        0x00, 0x84, 0x84,
        0x84, 0x84, 0x84
    };

    set_palette(0, 15, table_rgb);
    return;
}

void set_palette(int start, int end, unsigned char *rgb)
{
    int i, eflags;
    eflags = io_load_eflags();  // 인터럽트 허가 플래그 값 가져옴
    io_cli();                   // 허가 플래그를 0으로 하여 인터럽트 금지
    io_out8(0x03c8, start);
    for (i=start;i<=end;i++)
    {
        io_out8(0x03c9, rgb[0] / 4);
        io_out8(0x03c9, rgb[1] / 4);
        io_out8(0x03c9, rgb[2] / 4);
        rgb += 3;
    }
    io_store_eflags(eflags);    // 인터럽트 허가 플래그를 본래 값으로 되돌림.
    return;
}

void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, int x1, int y1)
{
    int x, y;
    for(y = y0; y <= y1; y++)
    {
        for (x=x0; x<=x1; x++)
            vram[y *xsize + x] = c;
    }
    return;
}

 

 

 

바탕화면 만들기

 

일단 박스필 4개만하면 이런식으로 화면이 만들어진다.

 

void HariMain(void)
{
    char *vram;
    int xsize, ysize;
    init_palette();
    vram = (char *) 0xa0000;
    xsize = 320;
    ysize = 200;

    boxfill8(vram, xsize, COL8_008484, 0, 0, xsize-1, ysize-29);    //녹하늘색 화면
    boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize-28, xsize-1, ysize-28); // 바닥 표시줄구분선
    boxfill8(vram, xsize, COL8_FFFFFF, 0, ysize-27, xsize-1, ysize-27); //바닥 표시줄 구분선
    boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize-26, xsize-1, ysize-1); //바닥 표시줄


    for(;;)
    {
        io_hlt();
    }
}

 

 

 

 

 

박스필 몇개 더 추가하면

옛날 윈도우 화면 느낌으로 만들어진다.

void HariMain(void)
{
    char *vram;
    int xsize, ysize;
    init_palette();
    vram = (char *) 0xa0000;
    xsize = 320;
    ysize = 200;

    boxfill8(vram, xsize, COL8_008484, 0, 0, xsize-1, ysize-29);    //녹하늘색 화면
    boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize-28, xsize-1, ysize-28); // 바닥 작업표시줄구분선
    boxfill8(vram, xsize, COL8_FFFFFF, 0, ysize-27, xsize-1, ysize-27); //바닥 작업표시줄 구분선
    boxfill8(vram, xsize, COL8_C6C6C6, 0, ysize-26, xsize-1, ysize-1); //작업 표시줄


	boxfill8(vram, xsize, COL8_FFFFFF,  3,         ysize - 24, 59,         ysize - 24);
	boxfill8(vram, xsize, COL8_FFFFFF,  2,         ysize - 24,  2,         ysize -  4);
	boxfill8(vram, xsize, COL8_848484,  3,         ysize -  4, 59,         ysize -  4);
	boxfill8(vram, xsize, COL8_848484, 59,         ysize - 23, 59,         ysize -  5);
	boxfill8(vram, xsize, COL8_000000,  2,         ysize -  3, 59,         ysize -  3);
	boxfill8(vram, xsize, COL8_000000, 60,         ysize - 24, 60,         ysize -  3);

	boxfill8(vram, xsize, COL8_848484, xsize - 47, ysize - 24, xsize -  4, ysize - 24);
	boxfill8(vram, xsize, COL8_848484, xsize - 47, ysize - 23, xsize - 47, ysize -  4);
	boxfill8(vram, xsize, COL8_FFFFFF, xsize - 47, ysize -  3, xsize -  4, ysize -  3);
	boxfill8(vram, xsize, COL8_FFFFFF, xsize -  3, ysize - 24, xsize -  3, ysize -  3);

    for(;;)
    {
        io_hlt();
    }
}

 

 

 

day04.zip
0.01MB

+ Recent posts