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 |