图形显示[ExpOS]开发经验2保护模式中不依赖bios

导读:
  保护模式中不依赖bios才是重点.
  原理: 显示到屏幕上的字母和符号统统存在于一段叫做 framebuffer 的显存中. 至于其出现于内存的物理地址,要看VGA板的工作模式. VGA
  的两种模式是: monochrome (单色?) emulation,或者color emulation.
  emulation---|--framebuffer linear address--|--framebuffer real-mode address--|--I/O address of CRTC
  color-------|--B8000h----------------------|--B800h:0000 --------------------|--3D4h
  monochrome--|--B0000h----------------------|--B000h:0000 --------------------|--3B4h
  CRTC 是VGA的一个功能单元,待会再讨论有关CRTC的小编. 一般来说,应该是 color emulation,记得大一的时候我们的实验室倒是有几台386
  上有 monochrome 的古董.
  备注1 的c代码可以检测VGA是处于那种工作模式.
  如果能够看懂,拿来用用应该不成问题.
  不会弄代码的格式,大家拷贝后自己整理吧.
  这里给一个简单的.
  /* video card mono/colour detection by Dark Fiber
  * returns 0=mono,1=colour
  */
  int detect_video_type(void)
  {
  int rc;
  char c=(*(USHORT*)0x410&0x30
  /* C can be 0x00 or 0x20 for colour,0x30 for mono
  if(c==0x30)
  rc=0; // mono
  else
  rc=1; // colour
  return rc;
  }
  字符及属性
  在framebuffer中的每个字符都占用两个字节: ASCII 码值在地址 N 的话,N+1 就是他的属性字节.
  属性字节的各个位的含义如下.
  b7 ----- 闪烁
  b6:b4 -- 背景色(0-7)
  b3:b0 -- 前景色(0-15)
  color value -- color -- color value -- color
  0 ------------ 黑色------ 8 ---------- 暗灰
  1 ------------ 蓝色------ 9 ---------- 亮蓝
  2 ------------ green ---- 10 --------- bright green
  3 ------------ cyan ----- 11 --------- bright cyan
  4 ------------ red ------ 12 --------- pink
  5 ------------ magenta -- 13 --------- bright magenta
  6 ------------ brown ---- 14 --------- yellow
  7 ------------ white ---- 15 --------- bright white
  假定使用color模式:
  Turbo C 代码的例子(cpu 工作于 16-bit real mode),把白色的 'H' 以蓝色背景放到屏幕左上角.
  #include /* pokeb() */
  pokeb(0xB800,'H');
  pokeb(0xB800,1,0x1F);
  NASM 汇编中这么写(16-bit real mode):
  mov bx,0B800h
  mov es,bx
  mov byte [es:0],'H'
  mov byte [es:1],1Fh
  DJGPP 代码(32-bit pmode),有所不同. 把黄的 'H' 以红色背景放到屏幕右上角.因为处于保护模式,我们使用far指针.
  #include /* _farpokeb() */
  #include /* _dos_ds */
  _farpokeb(_dos_ds,0xB8000 + 79 * 2 + 0,'*');
  _farpokeb(_dos_ds,0xB8000 + 79 * 2 + 1,0x4E);
  非得用 near 指针?
  #include
  #include
  #include
  unsigned char *fb;
  if(!(_crt0_startup_flags &_CRT0_FLAG_NEARPTR))
  { if(!__djgpp_nearptr_enable())
  { printf("Could not enable nearptr access/n");
  return -1; } } /* probably Windows NT DOS Box */
  fb = (unsigned char *)0xB8000 + __djgpp_conventional_base;
  fb[79 * 2 + 0] = '*';
  fb[79 * 2 + 1] = 0x4E;
  Scrolling(滚屏)
  BIOS 滚屏就算了吧?!
  如果使用 movedata(),也算简单. 与memcpy() 不同的地方在于movedata对于源和目的都使用 far指针.
  Turbo C 代码: 在 80x25 的方式下上滚一行(color emulation):
  #include /* movedata() */
  movedata(0xB800,80 * 2,
  0xB800,
  80 * (25 - 1) * 2);
  DJGPP 代码 scroll 80x25 display up one line (color emulation):
  #include /* movedata() */
  #include /* _dos_ds */
  movedata(_dos_ds,0xB8000L + 80 * 2,
  _dos_ds,0xB8000L,
  80 * (25 - 1) * 2);
  使用 movedata() 的的话,如果 src   作.
  hardware scrolling
  硬件来做滚动就比较快了. 把VGA配置成使用不同地址的framebuffer 就可以实现快速滚屏. CRTC 寄存器 12 号13号 分别包含framebuffer
  相对于B0000h,B8000h,or A0000h 之偏移(offset) 的MSB 与 LSB .
  /* scroll up one line */
  #include   unsigned short crtc_adr = 0x3D4; /* 0x3B4 for monochrome */
  unsigned short offset = 80;
  /* the CRTC index is at crtc_adr + 0
  select register 12 */
  outportb(crtc_adr + 0,12);
  /* the selected CRTC register appears at crtc_adr + 1 */
  outportb(crtc_adr + 1,offset >>8);
  outportb(crtc_adr + 0,13);
  outportb(crtc_adr + 1,offset &0xFF);
  硬件滚屏的缺陷在于不能够持续无限的滚动. 因为最终 framebuffer 会超过 video memory 的上(下)限.
  可以用作 framebuffer 的那段内存可以分成几个虚拟控制台(virtual consoles (VCs)). 32K 的 video memory 可以被分成8 个80x25的VCs.
  console 译作控制台我认为不妥,这里的console无非就是虚拟的几个屏幕.上面的代码就可以选择把那个虚拟屏呈现给用户. (Linux 的 VCs
  使用了不同的管理方法,我不知道.)
  Moving the cursor
  CRTC 寄存器14号和 15 号,包含光标位置的 MSB LSB . 光标的位置用相对B8000h 或 B0000h的偏移来表示.
  #include /* outportb() */
  unsigned short crtc_adr = 0x3D4; /* 0x3B4 for monochrome */
  unsigned short offset;
  unsigned short x = 20,y = 3;
  offset = x + y * 80; /* 80 characters per line */
  outportb(crtc_adr + 0,14); /* MSB of offset to CRTC reg 14 */
  outportb(crtc_adr + 1,offset >>8);
  outportb(crtc_adr + 0,15); /* LSB of offset to CRTC reg 15 */
  outportb(crtc_adr + 1,offset);
  [i] 不要告诉我,你不知道outportb 那里去找! [/i]
  推荐网站
  pc-hardware
  VGADOC
  一个vag包
  execpc的控制台代码
   备注1
  /*****************************************************************************
  Determines if VGA board is set for monochrome or color emulation.
  Uses 3 different algorithms.
  This code is public domain (no copyright).
  You can do whatever you want with it.
  *****************************************************************************/
  #include /* atoi() */
  #include /* printf() */
  //#include "../port.c" /* inportb(),peekw() */
  /********************************* TURBO C **********************************/
  #if defined(__TURBOC__)
  #include /* inportb(),peek() */
  #define peekw(S,O) peek(S,O)
  /********************************* DJGPP ************************************/
  #elif defined(__DJGPP__)
  #include /* _CRT0_FLAG_LOCK_MEMORY */
  #include /* inportb() */
  //#define NEARPTR 1
  /* near pointers; not supported in Windows NT/2k/XP DOS Box
  Must call __djgpp_nearptr_enable() before using these functions */
  #if defined(NEARPTR)
  #include /* __djgpp_conventional_base,__djgpp_nearptr_enable() */
  #include /* printf() */
  #include /* _CRT0_FLAG_NEARPTR,_crt0_startup_flags */
  #define peekw(S,O) *(unsigned short *)(16uL * (S) + (O) + /
  __djgpp_conventional_base)
  /* far pointers */
  #else
  #include /* _farpeekw() */
  #include /* _dos_ds */
  #define peekw(S,O) _farpeekw(_dos_ds,16uL * (S) + (O))
  #endif
  /******************************** WATCOM C **********************************/
  #elif defined(__WATCOMC__)
  #include /* inp() */
  #if defined(__386__)
  /* CauseWay DOS extender only */
  #define peekw(S,O) *(unsigned short *)(16uL * (S) + (O))
  #else
  #include /* MK_FP() */
  #define peekw(S,O) *(unsigned short far *)MK_FP(S,O)
  #endif
  #define inportb(P) inp(P)
  #else
  #error Not Turbo C,not DJGPP,not Watcom C. Sorry.
  #endif
  static unsigned short g_crtc_base_adr;
  /*****************************************************************************
  Pentium 486 Bochs
  method color color (color) mono
  ------ ------- ----- ------- -------
  1 pass pass pass UNTESTED
  2 pass pass pass UNTESTED
  3 pass pass pass UNTESTED
  *****************************************************************************/
  int main(int arg_c,char *arg_v[])
  {
  int method;
  #if defined(__DJGPP__)&&defined(NEARPTR)
  if(!(_crt0_startup_flags &_CRT0_FLAG_NEARPTR))
  {
  if(!__djgpp_nearptr_enable())
  {
  printf("Could not enable nearptr access "
  "(Windows NT/2k/XP?)/nUn-define NEARPTR "
  "in source code and re-compile/n");
  return 1;
  }
  }
  #endif
  if(arg_c <2)
  {
  printf("attempt to detect monochrome/color VGA emulation "
  "using one of three methods/n"
  "specify 1,2,or 3 on the command line/n");
  return 1;
  }
  method = atoi(arg_v[1]);
  switch(method)
  {
  case 1:
  /* this method cobbled from info in Finn Thoegersen's VGADOC4 */
  #define VGA_MISC_READ 0x3CC
  if((inportb(VGA_MISC_READ) &0x01) == 0)
  g_crtc_base_adr = 0x3B4; /* mono */
  else
  g_crtc_base_adr = 0x3D4; /* color */
  break;
  case 2:
  /* I forgot where this came from:
  "The word at low memory address 0040:0063 (or 0000:0463) contains the
  I/O address of the CRTC which can be used to determine whether the video
  system is colour or monochrome. A value of 3B4 hex indicates monochrome."
  (I presume 3D4 hex means color; my Pentium system has that value at 0463.) */
  g_crtc_base_adr = peekw(0x40,0x63);
  break;
  case 3:
  /* Dark Fiber's method,from the OS FAQ
  [url=www.mega-tokyo.com/os]http://www.mega-tokyo.com/os[/url]
  from MEMORY.LST of Ralf brown's Interrupt List
  0040:0010 is Installed Hardware word,b5:b4 indicate video hardware:
  00 EGA,VGA,PGA,or other with on-board video BIOS
  01 40x25 CGA color
  10 80x25 CGA color
  11 80x25 mono text
  whoa,this won't work with DJGPP -- OK,I will make a slight change here
  if((*(unsigned short *)0x410 &30) == 0x30) */
  if((peekw(0x40,0x10) &30) == 0x30)
  g_crtc_base_adr = 0x3B4; /* mono */
  else
  g_crtc_base_adr = 0x3D4; /* color */
  break;
  default:
  printf("didn't find 1,or 3 on the command line,sorry/n");
  return 1;
  }
  /* what've we got? */
  if(g_crtc_base_adr <0x3C0)
  printf("MONOCHROME emulation detected/n");
  else
  printf("color emulation detected/n");
  return 0;
  }

本文转自
http://www.cnblogs.com/huqingyu/archive/2005/02/17/105365.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


迭代器模式(Iterator)迭代器模式(Iterator)[Cursor]意图:提供一种方法顺序访问一个聚合对象中的每个元素,而又不想暴露该对象的内部表示。应用:STL标准库迭代器实现、Java集合类型迭代器等模式结构:心得:迭代器模式的目的是在不获知集合对象内部细节的同时能对集合元素进行遍历操作
高性能IO模型浅析服务器端编程经常需要构造高性能的IO模型,常见的IO模型有四种:(1)同步阻塞IO(BlockingIO):即传统的IO模型。(2)同步非阻塞IO(Non-blockingIO):默认创建的socket都是阻塞的,非阻塞IO要求socket被设置为NONBLOCK。注意这里所说的N
策略模式(Strategy)策略模式(Strategy)[Policy]意图:定义一系列算法,把他们封装起来,并且使他们可以相互替换,使算法可以独立于使用它的客户而变化。应用:排序的比较方法、封装针对类的不同的算法、消除条件判断、寄存器分配算法等。模式结构:心得:对对象(Context)的处理操作可
访问者模式(Visitor)访问者模式(Visitor)意图:表示一个作用于某对象结构中的各元素的操作,它使你在不改变各元素的类的前提下定义作用于这些元素的新操作。应用:作用于编译器语法树的语义分析算法。模式结构:心得:访问者模式是要解决对对象添加新的操作和功能时候,如何尽可能不修改对象的类的一种方
命令模式(Command)命令模式(Command)[Action/Transaction]意图:将一个请求封装为一个对象,从而可用不同的请求对客户参数化。对请求排队或记录请求日志,以及支持可撤消的操作。应用:用户操作日志、撤销恢复操作。模式结构:心得:命令对象的抽象接口(Command)提供的两个
生成器模式(Builder)生成器模式(Builder)意图:将一个对象的构建和它的表示分离,使得同样的构建过程可以创建不同的表示。 应用:编译器词法分析器指导生成抽象语法树、构造迷宫等。模式结构:心得:和工厂模式不同的是,Builder模式需要详细的指导产品的生产。指导者(Director)使用C
设计模式学习心得《设计模式:可复用面向对象软件的基础》一书以更贴近读者思维的角度描述了GOF的23个设计模式。按照书中介绍的每个设计模式的内容,结合网上搜集的资料,我将对设计模式的学习心得总结出来。网络上关于设计模式的资料和文章汗牛充栋,有些文章对设计模式介绍生动形象。但是我相信“一千个读者,一千个
工厂方法模式(Factory Method)工厂方法模式(Factory Method)[Virtual Constructor]意图:定义一个用于创建对象的接口,让子类决定实例化哪一个类,使一个类的实力化延迟到子类。应用:多文档应用管理不同类型的文档。模式结构:心得:面对同一继承体系(Produc
单例模式(Singleton)单例模式(Singleton)意图:保证一个类只有一个实例,并提供一个访问它的全局访问点。应用:Session或者控件的唯一示例等。模式结构:心得:单例模式应该是设计模式中最简单的结构了,它的目的很简单,就是保证自身的实例只有一份。实现这种目的的方式有很多,在Java中
装饰者模式(Decorator)装饰者模式(Decorator)[Wrapper]意图:动态的给一个对象添加一些额外的职责,就增加功能来说,比生成子类更为灵活。应用:给GUI组件添加功能等。模式结构:心得:装饰器(Decorator)和被装饰的对象(ConcreteComponent)拥有统一的接口
抽象工厂模式(Abstract Factory)抽象工厂模式(Abstract Factory)[Kit]意图:提供一个创建一系列相关或相互依赖对象的接口,而无须指定他们具体的类。应用:用户界面工具包。模式结构:心得:工厂方法把生产产品的方式封装起来了,但是一个工厂只能生产一类对象,当一个工厂需要生
桥接模式(Bridge)桥接模式(Bridge)[Handle/Body]意图:将抽象部分与它的实现部分分离,使他们都可以独立的变化。应用:不同系统平台的Windows界面。模式结构:心得:用户所见类体系结构(Window派生)提供了一系列用户的高层操作的接口,但是这些接口的实现是基于具体的底层实现
适配器模式(Adapter)适配器模式(Adapter)[Wrapper]意图:将类的一个接口转换成用户希望的另一个接口,使得原本由于接口不兼容而不能一起工作的类可以一起工作。应用:将图形类接口适配到用户界面组件类中。模式结构:心得:适配器模式一般应用在具有相似接口可复用的条件下。目标接口(Targ
组合模式(Composition)组合模式(Composition)意图:将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。应用:组合图形、文件目录、GUI容器等。模式结构:心得: 用户(Client)通过抽象类(Component)提供的公用接口统一
原型模式(Prototype)原型模式(Prototype)意图:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象。应用:Java/C#中的Clonable和IClonable接口等。模式结构:心得:原型模式本质上就是对象的拷贝,使用对象拷贝代替对象创建的原因有很多。比如对象的初始化构
什么是设计模式一套被反复使用、多数人知晓的、经过分类编目的、代码 设计经验 的总结;使用设计模式是为了 可重用 代码、让代码 更容易 被他人理解、保证代码 可靠性;设计模式使代码编制  真正工程化;设计模式使软件工程的 基石脉络, 如同大厦的结构一样;并不直接用来完成代码的编写,而是 描述 在各种不同情况下,要怎么解决问题的一种方案;能使不稳定依赖于相对稳定、具体依赖于相对抽象,避免引
单一职责原则定义(Single Responsibility Principle,SRP)一个对象应该只包含 单一的职责,并且该职责被完整地封装在一个类中。Every  Object should have  a single responsibility, and that responsibility should be entirely encapsulated by t
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强烈推荐。原文截图*************************************************************************************************************************原文文本************
适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以相互合作。
策略模式定义了一系列算法族,并封装在类中,它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。