Subversion Repositories shark

Rev

Rev 230 | 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));
522 mauro 179
 
44 pj 180
    x = bios_x;
181
    y = bios_y;
182
    switch (c) {
183
        case '\t' : x += 8;            
522 mauro 184
                    if (x == (cons_columns-1)) {
44 pj 185
                        x = 0;
522 mauro 186
                        if (y >= (cons_rows-1)) scroll();
44 pj 187
                        else y++;
188
                    } else {
189
                        scan_x = 0;
190
                        while ((scan_x+8) < x) scan_x += 8;
191
                        x = scan_x;
192
                    }
193
                    break;
194
        case '\n' : x = 0;
522 mauro 195
                    if (y >= (cons_rows-1)) scroll();
44 pj 196
                    else y++;
197
                    break;
198
        case '\b' : x--;
199
                    lmempokeb((LIN_ADDR)(v + 2*(x + y*cons_columns)),' ');
200
                    x++;
201
                    break;
202
        default   : lmempokeb((LIN_ADDR)(v + 2*(x + y*cons_columns)),c);
203
                    x++;
522 mauro 204
                    if (x == (cons_columns-1)) {
44 pj 205
                        x = 0;
522 mauro 206
                        if (y >= (cons_rows-1)) scroll();
44 pj 207
                        else y++;
208
                    }
209
    }
210
    place(x,y);
522 mauro 211
 
44 pj 212
}
213
 
214
void cputs(char *s)
215
{
216
    char c;
230 giacomo 217
 
44 pj 218
    while (*s != '\0') {
219
        c = *s++;
220
        cputc(c);
221
    }
230 giacomo 222
 
44 pj 223
}