2a09cb66d7d53281fd3433a67e68828ec7850eef
[dragonfly.git] / usr.bin / doscmd / bios.c
1 /*
2  * Copyright (c) 1992, 1993, 1996
3  *      Berkeley Software Design, Inc.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *      This product includes software developed by Berkeley Software
16  *      Design, Inc.
17  *
18  * THIS SOFTWARE IS PROVIDED BY Berkeley Software Design, Inc. ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL Berkeley Software Design, Inc. BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  *      BSDI bios.c,v 2.3 1996/04/08 19:32:19 bostic Exp
31  *
32  * $FreeBSD: src/usr.bin/doscmd/bios.c,v 1.5.2.1 2002/04/25 11:04:50 tg Exp $
33  * $DragonFly: src/usr.bin/doscmd/bios.c,v 1.2 2003/06/17 04:29:25 dillon Exp $
34  */
35
36 #include "doscmd.h"
37 #include "mouse.h"
38 #include "com.h"
39
40 #define BIOS_copyright         0xfe000
41 #define BIOS_reset             0xfe05b
42 #define BIOS_nmi               0xfe2c3
43 #define BIOS_hdisk_table       0xfe401
44 #define BIOS_boot              0xfe6f2
45 #define BIOS_comm_table        0xfe729
46 #define BIOS_comm_io           0xfe739
47 #define BIOS_keyboard_io       0xfe82e
48 #define BIOS_keyboard_isr      0xfe987
49 #define BIOS_fdisk_io          0xfec59
50 #define BIOS_fdisk_isr         0xfef57
51 #define BIOS_disk_parms        0xfefc7
52 #define BIOS_printer_io        0xfefd2
53 #define BIOS_video_io          0xff065
54 #define BIOS_video_parms       0xff0a4
55 #define BIOS_mem_size          0xff841
56 #define BIOS_equipment         0xff84d
57 #define BIOS_cassette_io       0xff859
58 #define BIOS_video_font        0xffa6e
59 #define BIOS_time_of_day       0xffe6e
60 #define BIOS_timer_int         0xffea5
61 #define BIOS_vector            0xffef3
62 #define BIOS_dummy_iret        0xfff53
63 #define BIOS_print_screen      0xfff54
64 #define BIOS_hard_reset        0xffff0
65 #define BIOS_date_stamp        0xffff5
66 #define BIOS_hardware_id       0xffffe
67
68 static u_char disk_params[] = {
69     0xdf, 2, 0x25, 2, 0x0f, 0x1b, 0xff, 0x54, 0xf6, 0x0f, 8,
70 };
71
72 static u_short comm_table[] = {
73     1047, 768, 384, 192, 96, 48, 24, 12,
74 };
75
76 /* exports */
77
78 int              nfloppies = 0;
79 int              ndisks = 0;
80 int              nserial = 0;
81 int              nparallel = 0;
82 unsigned long   rom_config;
83
84 /*
85 ** BIOS equipment list
86 */
87 static void
88 int11(regcontext_t *REGS)
89 {
90     R_AX = 
91         (nfloppies ? 1:0) |     /* do we have any floppydisks? */
92         (0x2 << 4) |            /* 80x25 colour */
93         ((nfloppies-1) << 6) |  /* how many floppies? */
94         (nserial << 9) |        /* serial ports? */
95         (nparallel << 14);      /* parallel ports? */
96 }
97
98 /*
99 ** get installed memory
100 */
101 static void
102 int12(regcontext_t *REGS)
103 {
104     R_AX = 640;
105 }
106
107 /*
108 ** assorted oddments
109 */
110 static void
111 int15(regcontext_t *REGS)
112 {
113     R_FLAGS &= ~PSL_C;
114
115     switch (R_AH) {
116     case 0x00:                  /* Get Cassette Status */
117         R_AH = 0x86;
118         R_FLAGS |= PSL_C;       /* We don't support a cassette */
119         break;
120     case 0x04:                  /* Set ABIOS table */
121         R_FLAGS |= PSL_C;       /* We don't support it */
122         break;
123     case 0x4f:                  /* Keyboard intercept */
124         debug(D_TRAPS | 0x15, "BIOS: Keyboard intercept\n");
125         /* Don't translate scan code. */
126         break;
127     case 0x88:
128         get_raw_extmemory_info(REGS);
129         break;
130     case 0xc0:                  /* Get configuration */
131         debug(D_TRAPS | 0x15, "BIOS: Get configuration\n");
132         PUTVEC(R_ES, R_BX, rom_config);
133         R_AH = 0;
134         break;
135     case 0xc1:                  /* Get extended BIOS data area */
136         R_FLAGS |= PSL_C;
137         break;
138     case 0xc2:                  /* Pointing device */
139         debug(D_TRAPS | 0x15, "BIOS: Pointing device?\n");
140         R_FLAGS |= PSL_C;
141         R_AH = 5;       /* No pointer */
142         break;
143     default:
144         unknown_int2(0x15, R_AX, REGS);
145         break;
146     }
147 }
148
149 void
150 bios_init(void)
151 {
152     int i, j, k;
153     u_char *jtab;
154     struct timeval tv;
155     time_t tv_sec;
156     struct timezone tz;
157     struct tm tm;
158     u_long vec;
159
160     strcpy((char *)BIOS_copyright,
161            "Copyright (C) 1993 Krystal Technologies/BSDI");
162
163     *(u_short *)BIOS_reset = 0xffcd;
164     *(u_short *)BIOS_nmi = 0xffcd;
165     *(u_short *)BIOS_boot = 0xffcd;
166     *(u_short *)BIOS_comm_io = 0xffcd;
167     *(u_short *)BIOS_keyboard_io = 0xffcd;
168     *(u_short *)BIOS_keyboard_isr = 0xffcd;
169     *(u_short *)BIOS_fdisk_io = 0xffcd;
170     *(u_short *)BIOS_fdisk_isr = 0xffcd;
171     *(u_short *)BIOS_printer_io = 0xffcd;
172     *(u_short *)BIOS_video_io = 0xffcd;
173     *(u_short *)BIOS_cassette_io = 0xffcd;
174     *(u_short *)BIOS_time_of_day = 0xffcd;
175     *(u_short *)BIOS_timer_int = 0xffcd;
176     *(u_short *)BIOS_dummy_iret = 0xffcd;
177     *(u_short *)BIOS_print_screen = 0xffcd;
178     *(u_short *)BIOS_hard_reset = 0xffcd;
179     *(u_short *)BIOS_mem_size = 0xffcd;
180     *(u_short *)BIOS_equipment = 0xffcd;
181     *(u_short *)BIOS_vector = 0xffcd;
182     *(u_char *)0xffff2 = 0xcf;                  /* IRET */
183
184     memcpy((u_char *)BIOS_disk_parms, disk_params, sizeof(disk_params));
185     memcpy((u_char *)BIOS_comm_table, comm_table, sizeof(comm_table));
186
187     *(u_short *)BIOS_video_font = 0xffcd;
188         
189     jtab = (u_char *)BIOS_date_stamp;
190     *jtab++ = '1';
191     *jtab++ = '0';
192     *jtab++ = '/';
193     *jtab++ = '3';
194     *jtab++ = '1';
195     *jtab++ = '/';
196     *jtab++ = '9';
197     *jtab++ = '3';
198
199     *(u_char *)BIOS_hardware_id = 0xfc;           /* Identify as a PC/AT */
200
201     /*
202      * Interrupt revectors F000:0000 - F000:03ff
203      */
204     for (i = 0, j = 0, k = 0; i < 0x100; ++i) {
205         if ((i >= 0x60 && i < 0x68) ||
206             (i >= 0x78 && i < 0xe2))
207             continue;
208         if ((i >= 0x00 && i < 0x2f) ||
209             (i >= 0x30 && i < 0xfe)) {
210             ivec[i] = 0xF0300000L | (k * 1);
211             jtab = (u_char *)VECPTR(ivec[i]);
212             *jtab++ = 0xf4;     /* HLT */
213             ++k;
214         } else {
215             ivec[i] = 0xF0000000L | (j * 6);
216             jtab = (u_char *)VECPTR(ivec[i]);
217             *jtab++ = 0xcd;     /* INT i */
218             *jtab++ = i;
219             *jtab++ = 0xca;     /* RETF 2 */
220             *jtab++ = 2;
221             *jtab++ = 0;
222             ++j;
223         }
224     }
225
226     /*
227      * Misc variables from F000:0400 - F000:0fff
228      */
229     rom_config = 0xF0000400;
230     jtab = (u_char *)VECPTR(rom_config);
231     *jtab++ = 20;           /* length of entry */
232     *jtab++ = 0;
233     *jtab++ = *(u_char *)BIOS_hardware_id;
234     *jtab++ = 0x00;         /* Sub model */
235     *jtab++ = 0x01;         /* Bios Rev Enhanced kbd w/3.5" floppy */
236     *jtab++ = 0x20;         /* real time clock present */
237     *jtab++ = 0;            /* Reserved */
238     *jtab++ = 0;
239     *jtab++ = 0;
240     *jtab++ = 0;
241     strcpy((char *)jtab, "BSDI BIOS");
242     *jtab += 10;
243
244     InDOS = jtab++;
245     *InDOS = 0;
246
247     mouse_area = jtab;
248     jtab += 0x10;
249
250     *(u_short *)&BIOSDATA[0x10] = 
251         (1 << 0) |              /* Diskette avail for boot */
252         (1 << 1) |              /* Math co-processor */
253         (nmice << 2) |          /* No pointing device */
254         (2 << 4) |              /* Initial video (80 x 25 C) */
255         ((nfloppies - 1) << 6) |        /* Number of floppies - 1 */
256         (nserial << 9) |        /* Number of serial devices */
257         (nparallel << 14);      /* Number of parallel devices */
258
259
260     *(u_short *)&BIOSDATA[0x13] = 640;  /* Amount of memory */
261     BIOSDATA[0x75] = ndisks;            /* number of fixed disks */
262     
263     BIOSDATA[0x8F] = 0;
264     if (nfloppies >= 1) {
265         BIOSDATA[0x8F] |= 0x04;
266         BIOSDATA[0x90] = 0x40;
267     }
268     if (nfloppies >= 2) {
269         BIOSDATA[0x8F] |= 0x40;
270         BIOSDATA[0x91] = 0x40;
271     }
272
273     gettimeofday(&tv, &tz);
274     tv_sec = tv.tv_sec;
275     tm = *localtime(&tv_sec);
276     *(u_long *)&BIOSDATA[0x6c] =
277         (((tm.tm_hour * 60 + tm.tm_min) * 60) + tm.tm_sec) * 182 / 10; 
278
279     vec = insert_softint_trampoline();
280     ivec[0x11] = vec;
281     register_callback(vec, int11, "int 11");
282     
283     vec = insert_softint_trampoline();
284     ivec[0x12] = vec;
285     register_callback(vec, int12, "int 12");
286
287     vec = insert_softint_trampoline();
288     ivec[0x14] = vec;
289     register_callback(vec, int14, "int 14");
290
291     vec = insert_softint_trampoline();
292     ivec[0x15] = vec;
293     register_callback(vec, int15, "int 15");
294
295     vec = insert_softint_trampoline();
296     ivec[0x16] = vec;
297     register_callback(vec, int16, "int 16");
298
299     vec = insert_softint_trampoline();
300     ivec[0x17] = vec;
301     register_callback(vec, int17, "int 17");
302
303     vec = insert_softint_trampoline();
304     ivec[0x1a] = vec;
305     register_callback(vec, int1a, "int 1a");
306 }