00001
00002
00003 #ifndef __pc_display_h
00004 #define __pc_display_h
00005
00006 #include <display.h>
00007 #include "uart.h"
00008
00009 __BEGIN_SYS
00010
00011
00012 class MC6845
00013 {
00014 public:
00015
00016 typedef CPU::IO_Port IO_Port;
00017 enum {
00018 ADDR_REG = 0x03d4,
00019 DATA_REG = 0x03d5,
00020 CTRL_REG = 0x03d8,
00021 COLOR_REG = 0x03d9,
00022 STAT_REG = 0x03da
00023 };
00024
00025
00026 typedef CPU::Reg8 Address;
00027 enum {
00028 ADDR_CUR_START = 0x0a,
00029 ADDR_CUR_END = 0x0b,
00030 ADDR_PAGE_HI = 0x0c,
00031 ADDR_PAGE_LO = 0x0d,
00032 ADDR_CUR_POS_HI = 0x0e,
00033 ADDR_CUR_POS_LO = 0x0f
00034 };
00035
00036 public:
00037 MC6845() {}
00038
00039 volatile int position() {
00040 CPU::out8(ADDR_REG, ADDR_CUR_POS_LO);
00041 int pos = CPU::in8(DATA_REG);
00042 CPU::out8(ADDR_REG, ADDR_CUR_POS_HI);
00043 pos |= CPU::in8(DATA_REG) << 8;
00044 return pos;
00045 }
00046 void position(int pos) {
00047 CPU::out8(ADDR_REG, ADDR_CUR_POS_LO);
00048 CPU::out8(DATA_REG, pos & 0xff);
00049 CPU::out8(ADDR_REG, ADDR_CUR_POS_HI);
00050 CPU::out8(DATA_REG, pos >> 8);
00051 }
00052 };
00053
00054 class PC_Display: protected Display_Common, public MC6845
00055 {
00056 private:
00057 typedef Traits<PC_Display> Traits;
00058 static const Type_Id TYPE = Type<PC_Display>::TYPE;
00059
00060 static const int FBA = Traits::FRAME_BUFFER_ADDRESS;
00061 static const int LINES = Traits::LINES;
00062 static const int COLUMNS = Traits::COLUMNS;
00063 static const int TAB_SIZE = Traits::TAB_SIZE;
00064
00065 public:
00066
00067 typedef unsigned short Cell;
00068 typedef Cell * Frame_Buffer;
00069
00070
00071 typedef Cell Attribute;
00072 enum {
00073 NORMAL = 0x0700
00074 };
00075
00076 public:
00077 PC_Display(Frame_Buffer fb = reinterpret_cast<Frame_Buffer>(FBA))
00078 : _frame_buffer(fb) {}
00079
00080 void clear() {
00081 for(unsigned int i = 0; i < LINES * COLUMNS; i++)
00082 _frame_buffer[i] = NORMAL | ' ';
00083 MC6845::position(0);
00084 }
00085
00086 void putc(char c){
00087 unsigned int pos = MC6845::position();
00088
00089 switch(c) {
00090 case '\n':
00091 pos = (pos + COLUMNS) / COLUMNS * COLUMNS;
00092 break;
00093 case '\t':
00094 pos = (pos + TAB_SIZE) / TAB_SIZE * TAB_SIZE;
00095 break;
00096 default:
00097 _frame_buffer[pos++] = NORMAL | c;
00098 }
00099 if(pos >= LINES * COLUMNS) {
00100 scroll();
00101 pos-= COLUMNS;
00102 }
00103 MC6845::position(pos);
00104 }
00105
00106 void puts(const char * s) {
00107 while(*s != '\0')
00108 putc(*s++);
00109 }
00110
00111 void position(int * line, int * column) {
00112 unsigned int pos = MC6845::position();
00113 *column = pos % COLUMNS;
00114 *line = pos / COLUMNS;
00115 }
00116
00117 void position(int line, int column) {
00118 if(line > LINES)
00119 line = LINES;
00120 if(column > COLUMNS)
00121 column = COLUMNS;
00122 if((line < 0) || (column < 0)) {
00123 int old_line, old_column;
00124 position(&old_line, &old_column);
00125 if(column < 0)
00126 column = old_column;
00127 if(line < 0)
00128 line = old_line;
00129 }
00130 MC6845::position(line * COLUMNS + column);
00131 }
00132
00133 void size(int * lines, int * columns) {
00134 *lines = LINES;
00135 *columns = COLUMNS;
00136 }
00137
00138 static int init(System_Info * si);
00139
00140 private:
00141 void scroll() {
00142 for(unsigned int i = 0; i < (LINES - 1) * COLUMNS; i++)
00143 _frame_buffer[i] = _frame_buffer[i + COLUMNS];
00144 for(unsigned int i = (LINES - 1) * COLUMNS; i < LINES * COLUMNS; i++)
00145 _frame_buffer[i] = NORMAL | ' ';
00146 }
00147
00148 private:
00149 Frame_Buffer _frame_buffer;
00150 };
00151
00152 class PC_Serial_Display: protected Display_Common
00153 {
00154 private:
00155 typedef Traits<PC_Display> Traits;
00156 static const Type_Id TYPE = Type<PC_Display>::TYPE;
00157
00158 public:
00159 PC_Serial_Display() {}
00160
00161 void clear() {}
00162
00163 void putc(char c){ _uart.put(c); }
00164
00165 void puts(const char * s) {
00166 while(*s != '\0')
00167 putc(*s++);
00168 }
00169
00170 void size(int * lines, int * columns) {
00171 *lines = Traits::LINES;
00172 *columns = Traits::COLUMNS;
00173 }
00174
00175 void position(int * line, int * column) {}
00176 void position(int line, int column) {}
00177
00178 static int init(System_Info * si);
00179
00180 private:
00181 PC_UART _uart;
00182 };
00183
00184 template <bool serial>
00185 class PC_Select_Display: public PC_Display {};
00186
00187 template <>
00188 class PC_Select_Display<true>: public PC_Serial_Display {};
00189
00190 typedef PC_Select_Display<Traits<PC_Display>::on_serial> Display;
00191
00192 __END_SYS
00193
00194 #endif
00195