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

kernel.asm

[BITS 32]

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

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

jmp                 start

start:

call _ya_main       ;调用C  ->kernel.c

jmp $

 

kernel.c

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

 

unsigned short color ;

void ya_main()

{

//写字的颜色

color = rgb_mix( 0 , 255 , 255 ) ;

ya_draw_chars(  250, 50, "请键盘输入" , color) ;

addin();

for(;;)  //等待键入

{ 

}

}

 

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

  }

}

 

graph.h

#ifndef _GRAPH_H_

#define _GRAPH_H_

 

 

// 色调合成函数

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

 

// 画点函数

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

 

// 显示英文

void ya_draw_english( unsigned int x , unsigned int y , unsigned int pos_in_font , unsigned short color ) ;

 

// 显示汉字

void ya_draw_chinese( unsigned int x , unsigned int y , unsigned int pos_in_font , unsigned short color ) ;

 

// 显示字符串

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

 

 

// 显示四位bmp图片

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

 

#endif

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值