Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 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
 
147
void scroll(void)
148
{
149
    _scroll(bios_attr,0,0,(cons_columns-1),(cons_rows-1));
150
}
151
 
152
void cputc(char c)
153
{
154
    static unsigned short scan_x,x,y;
155
    LIN_ADDR v = (LIN_ADDR)(0xB8000 + active_page*(2*PAGE_SIZE));
156
    x = bios_x;
157
    y = bios_y;
158
    switch (c) {
159
        case '\t' : x += 8;            
160
                    if (x >= cons_columns) {
161
                        x = 0;
162
                        if (y == (cons_rows-1)) scroll();
163
                        else y++;
164
                    } else {
165
                        scan_x = 0;
166
                        while ((scan_x+8) < x) scan_x += 8;
167
                        x = scan_x;
168
                    }
169
                    break;
170
        case '\n' : x = 0;
171
                    if (y == (cons_rows-1)) scroll();
172
                    else y++;
173
                    break;
174
        case '\b' : x--;
175
                    lmempokeb((LIN_ADDR)(v + 2*(x + y*cons_columns)),' ');
176
                    x++;
177
                    break;
178
        default   : lmempokeb((LIN_ADDR)(v + 2*(x + y*cons_columns)),c);
179
                    x++;
180
                    if (x > cons_columns) {
181
                        x = 0;
182
                        if (y == (cons_rows-1)) scroll();
183
                        else y++;
184
                    }
185
    }
186
    place(x,y);
187
}
188
 
189
void cputs(char *s)
190
{
191
    char c;
192
    while (*s != '\0') {
193
        c = *s++;
194
        cputc(c);
195
    }
196
}
197
 
198