Subversion Repositories shark

Rev

Rev 1618 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
42 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
/* Access directly to video & BIOS memory through linear addressing */
56
 
57
/* Active video page-buffer */
58
#define PAGE_SIZE               2048
59
 
60
int active_page = 0;
61
int visual_page = 0;
62
 
63
void bios_save(void)
64
{
65
    /* This function must be called to init CONSole output */
66
#if 1
67
    bios_attr = lmempeekb((LIN_ADDR)0xB8000 + 159);
68
    bios_x = lmempeekb((LIN_ADDR)0x00450);
69
    bios_y = lmempeekb((LIN_ADDR)0x00451);
70
    bios_end = lmempeekb((LIN_ADDR)0x00460);
71
    bios_start = lmempeekb((LIN_ADDR)0x00461);
72
    active_page = visual_page = 0;
73
#else
74
    LIN_ADDR p;
75
 
76
    p = (LIN_ADDR)(0xB8000 + 159);
77
    bios_attr = *p;
78
    p = (LIN_ADDR)0x00450;
79
    bios_x = *p;
80
    p = (LIN_ADDR)0x00451;
81
    bios_y = *p;
82
    p = (LIN_ADDR)0x00460;
83
    bios_end = *p;
84
    p = (LIN_ADDR)0x00461;
85
    bios_start = *p;
86
    active_page = visual_page = 0;
87
#endif
88
}
89
 
90
void getcursorxy(int *x, int *y)
91
{
92
  *x = bios_x;
93
  *y = bios_y;
94
}
95
 
96
int get_attr(void)
97
{
98
  return bios_attr;
99
}
100
 
101
void cursor(int start,int end)
102
{
103
    /* Same thing as above; Set cursor scan line */
104
    outp(CGA_INDEX_REG, CURSOR_START);
105
    outp(CGA_DATA_REG, start);
106
    outp(CGA_INDEX_REG, CURSOR_END);
107
    outp(CGA_DATA_REG, end);
108
}
109
 
110
void bios_restore(void)
111
{
112
    lmempokeb((LIN_ADDR)0x00450,bios_x);
113
    lmempokeb((LIN_ADDR)0x00451,bios_y);
114
    place(bios_x,bios_y);
115
    cursor(bios_start, bios_end);
116
}
117
 
118
void place(int x,int y)
119
{
120
    unsigned short cursor_word = x + y*80 + active_page*PAGE_SIZE;
121
    /* Set cursor position                                */
122
    /* CGA is programmed writing first the Index register */
123
    /* to specify what internal register we are accessing */
124
    /* Then we load the Data register with the wanted val */
125
    outp(CGA_INDEX_REG,CURSOR_POS_LSB);
126
    outp(CGA_DATA_REG,cursor_word & 0xFF);
127
    outp(CGA_INDEX_REG,CURSOR_POS_MSB);
128
    outp(CGA_DATA_REG,(cursor_word >> 8) & 0xFF);
129
    /* Adjust temporary cursor bios position */
130
    bios_x = x;
131
    bios_y = y;
132
}
133
 
134
 
135
void _scroll(char attr,int x1,int y1,int x2,int y2)
136
{
137
    register int x,y;
138
    WORD xattr = (((WORD)attr) << 8) + ' ',w;
139
    LIN_ADDR v = (LIN_ADDR)(0xB8000 + active_page*(2*PAGE_SIZE));
140
 
141
    for (y = y1+1; y <= y2; y++)
142
       for (x = x1; x <= x2; x++) {
143
           w = lmempeekw((LIN_ADDR)(v + 2*(y*80+x)));
144
           lmempokew((LIN_ADDR)(v + 2*((y-1)*80+x)),w);
145
    }
146
    for (x = x1; x <= x2; x++)
147
        lmempokew((LIN_ADDR)(v + 2*((y-1)*80+x)),xattr);
148
}
149
 
150
void scroll(void)
151
{
152
    _scroll(bios_attr,0,0,79,24);
153
}
154
 
155
void cputc(char c)
156
{
157
    static unsigned short scan_x,x,y;
158
    LIN_ADDR v = (LIN_ADDR)(0xB8000 + active_page*(2*PAGE_SIZE));
159
    x = bios_x;
160
    y = bios_y;
161
    switch (c) {
162
        case '\t' : x += 8;            
163
                    if (x >= 80) {
164
                        x = 0;
165
                        if (y == 24) scroll();
166
                        else y++;
167
                    } else {
168
                        scan_x = 0;
169
                        while ((scan_x+8) < x) scan_x += 8;
170
                        x = scan_x;
171
                    }
172
                    break;
173
        case '\n' : x = 0;
174
                    if (y == 24) scroll();
175
                    else y++;
176
                    break;
177
        case '\b' : x--;
178
                    lmempokeb((LIN_ADDR)(v + 2*(x + y*80)),' ');
179
                    x++;
180
                    break;
181
        default   : lmempokeb((LIN_ADDR)(v + 2*(x + y*80)),c);
182
                    x++;
183
                    if (x > 80) {
184
                        x = 0;
185
                        if (y == 24) scroll();
186
                        else y++;
187
                    }
188
    }
189
    place(x,y);
190
}
191
 
192
void cputs(char *s)
193
{
194
    char c;
195
    while (*s != '\0') {
196
        c = *s++;
197
        cputc(c);
198
    }
199
}
200
 
201