操作系统与网络实现 之二十(乙)

来源:互联网 发布:淘宝店铺没东西 编辑:程序博客网 时间:2024/05/21 07:52

kernel.asm

[BITS 32]

[GLOBAL start]     ;我们必须导出start这个入口,以便让链接器识别,

[EXTERN _ya_main]  ;用到本文件外定义的函数 在kernel.c

jmp                 start

start:

call _ya_main       ;调用C

jmp $

 

 

kernel.c

#include "..\include\graph.h"

#include "..\include\pciprobe.h"

 

unsigned short color ;

void ya_main()

{

//写字的颜色

color= rgb_mix( 0 , 255 , 255 ) ;

unsigned int x = 250 ;

unsigned int y = 50 ;

if(PciBusProbe()){

ya_draw_chars( 250, 5, "北桥存在" , color) ;

}

//ya_draw_chars(  250, 50, "北桥存在" , color) ;

PciProbe() ;

//ya_draw_4bit_bmp(500 , 20 , 0x68400) ;

netcardprobe() ;

//显示内存中0x400120开始的数值,16进制0x显示,每行八个,共三行

char *b= (char *) 0x400120; 

show_data(  b , 8 , 0 , 40 , color );

b= b+0x20; //下一行八个双字8X4 = 32 = 0x20

show_data(  b , 8 , 0 , 60 , color );

netinitial();

 

 

}

 

 

graph.c

#include "..\include\graph.h"

unsigned int * addr = (int *)0x10050 ;

 

 

//颜色合成函数

unsigned short rgb_mix( unsigned char r , unsigned char g , unsigned char b )

{

 union{

   unsigned int color ;

   struct{

     unsigned char b : 5 ;

     unsigned char g : 6 ;

     unsigned char r : 5 ;

   }sa;

 }ua;

  ua.sa.r= r>> 3 ;

  ua.sa.g= g>> 2 ;

  ua.sa.b= b>> 3 ;

 return ua.color;

}

 

//画点函数

void draw_dot( unsigned int x , unsigned int y , unsigned short color )

{

 //取得显卡地址

 //unsigned short *video_addr ;

 unsigned int mid = *addr;

 unsigned short * video_addr = (unsigned int *)mid;

 

 //计算点的偏移量

 unsigned int offset = y* 800 + x ; 

//  *( video + offset ) = color ;

*( video_addr+ offset) = color ;

}

 

 

 

//显示英文

void ya_draw_english( unsigned int x , unsigned int y , unsigned int addr_in_font , unsigned short color )

{

unsigned char *english_font= ( unsigned char * )(0x10400 + addr_in_font * 16) ;

int ta = y;

int tb = x;

unsigned char font_char ;

for (int tc = 0; tc < 16; tc++) { //一个英文 16

       for (int td = 7; td >= 0; td--) { //一行一个字节 八位

            tb++ ;

           if ((font_char= english_font[ tc ] & (1 << td))) {

                draw_dot(tb, ta, color);

}

       }

        ta++; //显示下一行

        tb= x;

   }

}

 

//显示汉字

void ya_draw_chinese( unsigned int x , unsigned int y , unsigned int addr_in_font , unsigned short color )

{

unsigned char *chinese_font= ( unsigned char * )(0x11400 + addr_in_font * 32) ;

int ta = y;

int tb = x;

unsigned char font_char ;

for (int tc = 0; tc < 16; tc++) { //一个汉字16

   for (int te =0 ; te < 2; te++){ //一行两个字节 十六位

for (int td = 7; td >= 0; td--) {

tb++ ;

if ((font_char= chinese_font[ tc*2 + te ] & (1 << td))) {

                draw_dot(tb, ta, color);

}

           }

   }

        ta++; //显示下一行

        tb= x;

   }

}

 

//显示字符串

void ya_draw_chars( int x, int y, char *chars, unsigned short color)

{

while (*chars){

char ch = *chars++ ;

if (ch& 0x80){ //是中文

char cl = *chars++ ;

cl-= 0xa1;

ch-= 0xa1;

int addr = 94*ch+ cl; 

ya_draw_chinese( x , y, addr, color);

x+= 16 ;

}

else{ //是英文

int addr = ch; 

ya_draw_english(x, y, addr, color);

x+= 8 ;

}

}

}

 

 

 

void ya_draw_4bit_bmp(unsigned int x ,unsigned int y ,unsigned int addr)

{

int color [16] = {0x0,0x8000,0x400,0x8400,0x10,0x8010,0x410,0x8410,0xc618,0xf800,0x7e0,0xffe0,0x1f,0xf81f,0x7ff,0xffff} ;//调色板值

int lx = x;                         //每行要从这里开始,保留这个值

int * ta = (int *)(addr+0xa) ;       //位图数据开始偏移量 在第0xa字节共四字节

int * tb = (int *)(addr+0x22) ;      //位图数据长 在第0x22字节共四字节

int * width = (int *)(addr+0x12) ;   //位图宽  在第0x12字节共四字节

int * height = (int *)(addr+0x16) ;  //位图高 在第0x16字节共四字节

int td ; //一行要读的字节数

int te ; //补几个字节

int tf ; //图宽

tf= * width;

switch(tf%8){  //计算一行要读的字节数td 要补的字节数te

case 0:

td= tf/2 ; 

te= 0 ;

break ;

case 1:

td= (tf+1)/2 ; 

te= 3 ;

break ;

case 2:

td= tf/2 ; 

te= 3 ;

break ;

case 3:

td= (tf+1)/2 ; 

te= 2 ;

break ;

case 4:

td= tf/2 ; 

te= 2 ;

break ;

case 5:

td= (tf+1)/2 ; 

te= 1 ;

break ;

case 6:

td= tf/2 ; 

te= 1 ;

break ;

case 7:

td= (tf+1)/2 ; 

te= 0 ;

break ;

}

int tc = td+ te;

char * string = (char *)(addr+*ta+*tb-tc) ; //数据从最末端-32字节处开始

for(int i=0 ; i< *height;i++){

for(int j=0 ; j<td;j++){

unsigned char ch = *string;   //一个字符有八位,要分别取得其高四位和低四位

           unsigned char c1 = ch>>4;      //取得高四位

unsigned int pa = color[c1] ;  //取得调色板的对应颜色值

if(pa!=0xffff){                //如果是白色,跳过不显示

draw_dot(x, y, pa) ;

}

       unsigned char c2 = ch& 0xf;   //取得低四位

pa= color[c2] ;               //取得调色板的对应颜色值

if(pa!=0xffff){

draw_dot(x, y, pa) ;

}

string++ ;

x++ ;

}

string= string+ te-tc*2;  //必须是四个字节宽,X个字节,然后后退XX字节

x= lx;

y++;

}

}

 

//读内存值,n是要显示的个数

void show_data( char *string,int n , int x , int y , unsigned short color )

{

 unsigned int pos ;

 for( int j = 0 ; j < n; ++j){

  ya_draw_chars( x , y,"0x", color ) ; //0x开关表示16进制值

  x+= 16;

 for( int i = 0 ; i < 4 ; ++i){

   unsigned char ch = *(string+3) ; //32位存放顺序是颠倒的

unsigned char lo4,hi4;

hi4= (ch& 0xf0) >> 4;

lo4= ch& 0x0f; 

   if ( hi4 <0xa )

{pos= hi4+0x30 ; }  //0ASCII值为0x30

   else

{ pos = hi4+0x57 ; }  //a+0x57 = 0x61,正是小a的值

ya_draw_english( x , y, pos, color) ;

    x+= 8 ;

   if ( lo4 <0xa )

{pos= lo4+0x30 ; }  //0ASCII值为0x30

   else

{ pos = lo4+0x57 ; }  //a+0x57 = 0x61,正是小a的值

    ya_draw_english( x , y, pos, color) ;

    x+= 8 ;

*string--;

 }

 

x+= 16 ; //多加一个8,中间有空格好看

string= string+ 8; //前面减了4再加8相当于加4,指向下一个双字,*string = *string + 8 是向其指向的值加8

 }

}

 

0 0