Subversion Repositories shark

Rev

Rev 44 | Rev 522 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
44 pj 1
/* Project:     OSLib
2
 * Description: The OS Construction Kit
3
 * Date:                1.6.2000
4
 * Idea by:             Luca Abeni & Gerardo Lamastra
5
 *
6
 * OSLib is an SO project aimed at developing a common, easy-to-use
7
 * low-level infrastructure for developing OS kernels and Embedded
8
 * Applications; it partially derives from the HARTIK project but it
9
 * currently is independently developed.
10
 *
11
 * OSLib is distributed under GPL License, and some of its code has
12
 * been derived from the Linux kernel source; also some important
13
 * ideas come from studying the DJGPP go32 extender.
14
 *
15
 * We acknowledge the Linux Community, Free Software Foundation,
16
 * D.J. Delorie and all the other developers who believe in the
17
 * freedom of software and ideas.
18
 *
19
 * For legalese, check out the included GPL license.
20
 */
21
 
22
/*      Console output functions        */
23
 
24
#include <ll/i386/hw-data.h>
25
#include <ll/i386/hw-instr.h>
26
#include <ll/i386/cons.h>
27
/* #include <xsys.h>*/
28
#include <ll/i386/string.h>
29
#include <ll/i386/stdlib.h>
30
#include <ll/i386/stdio.h>
31
#include <ll/stdarg.h>
32
 
33
FILE(Cons1);
34
/* CGA compatible registers value */
35
 
36
#define CURSOR_POS_MSB          0x0E
37
#define CURSOR_POS_LSB          0x0F
38
#define CURSOR_START            0x0A
39
#define CURSOR_END              0x0B
40
 
41
/* CGA compatible registers */
42
 
43
#define CGA_INDEX_REG   0x3D4
44
#define CGA_DATA_REG    0x3D5
45
 
46
/* Standard tab size */
47
 
48
#define TAB_SIZE        8
49
 
50
/* Store bios settings */
51
 
52
static unsigned char bios_start,bios_end;
53
BYTE bios_x, bios_y, bios_attr;
54
 
55
/* MG */
56
extern int cons_columns; /* number of screen columns */
57
extern int cons_rows;    /* number of screen rows */
58
 
59
/* Access directly to video & BIOS memory through linear addressing */
60
 
61
/* Active video page-buffer */
62
#define PAGE_SIZE               2048
63
 
64
int active_page = 0;
65
int visual_page = 0;
66
 
67
void bios_save(void)
68
{
69
    /* This function must be called to init CONSole output */
70
#if 1
71
    /* MG */
72
    cons_columns=lmempeekw((LIN_ADDR)0x0044a);
73
    cons_rows=lmempeekb((LIN_ADDR)0x00484)+1;    
74
 
75
    bios_attr = lmempeekb((LIN_ADDR)0xB8000 + cons_columns * 2 -1);
76
    bios_x = lmempeekb((LIN_ADDR)0x00450);
77
    bios_y = lmempeekb((LIN_ADDR)0x00451);
78
    bios_end = lmempeekb((LIN_ADDR)0x00460);
79
    bios_start = lmempeekb((LIN_ADDR)0x00461);
80
    active_page = visual_page = 0;
81
#else
82
    LIN_ADDR p;
83
 
84
    p = (LIN_ADDR)(0xB8000 + 159);
85
    bios_attr = *p;
86
    p = (LIN_ADDR)0x00450;
87
    bios_x = *p;
88
    p = (LIN_ADDR)0x00451;
89
    bios_y = *p;
90
    p = (LIN_ADDR)0x00460;
91
    bios_end = *p;
92
    p = (LIN_ADDR)0x00461;
93
    bios_start = *p;
94
    active_page = visual_page = 0;
95
#endif
96
}
97
 
98
void cursor(int start,int end)
99
{
100
    /* Same thing as above; Set cursor scan line */
101
    outp(CGA_INDEX_REG, CURSOR_START);
102
    outp(CGA_DATA_REG, start);
103
    outp(CGA_INDEX_REG, CURSOR_END);
104
    outp(CGA_DATA_REG, end);
105
}
106
 
107
void bios_restore(void)
108
{
109
    lmempokeb((LIN_ADDR)0x00450,bios_x);
110
    lmempokeb((LIN_ADDR)0x00451,bios_y);
111
    place(bios_x,bios_y);
112
    cursor(bios_start, bios_end);
113
}
114
 
115
void place(int x,int y)
116
{
117
    unsigned short cursor_word = x + y*cons_columns + active_page*PAGE_SIZE;
118
    /* Set cursor position                                */
119
    /* CGA is programmed writing first the Index register */
120
    /* to specify what internal register we are accessing */
121
    /* Then we load the Data register with the wanted val */
122
    outp(CGA_INDEX_REG,CURSOR_POS_LSB);
123
    outp(CGA_DATA_REG,cursor_word & 0xFF);
124
    outp(CGA_INDEX_REG,CURSOR_POS_MSB);
125
    outp(CGA_DATA_REG,(cursor_word >> 8) & 0xFF);
126
    /* Adjust temporary cursor bios position */
127
    bios_x = x;
128
    bios_y = y;
129
}
130
 
131
 
132
void _scroll(char attr,int x1,int y1,int x2,int y2)
133
{
134
    register int x,y;
135
    WORD xattr = attr << 8,w;
136
    LIN_ADDR v = (LIN_ADDR)(0xB8000 + active_page*(2*PAGE_SIZE));
137
 
138
    for (y = y1+1; y <= y2; y++)
139
       for (x = x1; x <= x2; x++) {
140
           w = lmempeekw((LIN_ADDR)(v + 2*(y*cons_columns+x)));
141
           lmempokew((LIN_ADDR)(v + 2*((y-1)*cons_columns+x)),w);
142
    }
143
    for (x = x1; x <= x2; x++)
144
        lmempokew((LIN_ADDR)(v + 2*((y-1)*cons_columns+x)),xattr);
145
}
146
 
230 giacomo 147
#define OPTIMIZED
148
#ifdef OPTIMIZED
149
 
44 pj 150
void scroll(void)
151
{
230 giacomo 152
 
153
  int x;
154
  WORD xattr = bios_attr << 8;
155
  LIN_ADDR v = (LIN_ADDR)(0xB8000 + active_page*(2*PAGE_SIZE));
156
 
157
  memcpy((LIN_ADDR)(v),
158
         (LIN_ADDR)(v + 2*cons_columns),
159
         cons_columns*(cons_rows-1)*2);
160
 
161
  for (x = 0; x <= cons_columns-1; x++)
162
      lmempokew((LIN_ADDR)(v + 2*((cons_rows-1)*cons_columns+x)),xattr);
163
 
164
}
165
 
166
#else
167
 
168
void scroll(void)
169
{
44 pj 170
    _scroll(bios_attr,0,0,(cons_columns-1),(cons_rows-1));
171
}
172
 
230 giacomo 173
#endif
174
 
44 pj 175
void cputc(char c)
176
{
177
    static unsigned short scan_x,x,y;
178
    LIN_ADDR v = (LIN_ADDR)(0xB8000 + active_page*(2*PAGE_SIZE));
179
    x = bios_x;
180
    y = bios_y;
181
    switch (c) {
182
        case '\t' : x += 8;            
183
                    if (x >= cons_columns) {
184
                        x = 0;
185
                        if (y == (cons_rows-1)) scroll();
186
                        else y++;
187
                    } else {
188
                        scan_x = 0;
189
                        while ((scan_x+8) < x) scan_x += 8;
190
                        x = scan_x;
191
                    }
192
                    break;
193
        case '\n' : x = 0;
194
                    if (y == (cons_rows-1)) scroll();
195
                    else y++;
196
                    break;
197
        case '\b' : x--;
198
                    lmempokeb((LIN_ADDR)(v + 2*(x + y*cons_columns)),' ');
199
                    x++;
200
                    break;
201
        default   : lmempokeb((LIN_ADDR)(v + 2*(x + y*cons_columns)),c);
202
                    x++;
203
                    if (x > cons_columns) {
204
                        x = 0;
205
                        if (y == (cons_rows-1)) scroll();
206
                        else y++;
207
                    }
208
    }
209
    place(x,y);
210
}
211
 
212
void cputs(char *s)
213
{
214
    char c;
230 giacomo 215
 
44 pj 216
    while (*s != '\0') {
217
        c = *s++;
218
        cputc(c);
219
    }
230 giacomo 220
 
44 pj 221
}
222
 
223