Add info about supported arches.
[v86d.git] / v86_common.c
blob132b230e0acf3f38aa1012da22d52a1352a0dd7d
1 #include <string.h>
2 #include "v86.h"
4 #define addr(t) (((t & 0xffff0000) >> 12) + (t & 0x0000ffff))
6 #define vbeib_get_string(name) \
7 { \
8 int l; \
9 t = addr(ib->name); \
10 if (t < bufend) { \
11 ib->name = t - lbuf; \
12 } else if (t > 0xa0000 && fsize > 0) { \
13 strncpy((char*)buf, vptr(t), fsize); \
14 ib->name = tsk->buf_len - fsize; \
15 l = strlen((char*)buf); \
16 fsize -= l; \
17 buf += l; \
18 if (fsize < 0) \
19 fsize = 0; \
20 } else { \
21 ib->name = 0; \
22 } \
25 int v86_task(struct uvesafb_task *tsk, u8 *buf)
27 u32 lbuf = 0;
29 /* Get the VBE Info Block */
30 if (tsk->flags & TF_VBEIB) {
31 struct vbe_ib *ib;
32 int fsize;
33 u32 t, bufend;
34 u16 *td;
36 lbuf = v86_mem_alloc(tsk->buf_len);
37 memcpy(vptr(lbuf), buf, tsk->buf_len);
38 tsk->regs.es = lbuf >> 4;
39 tsk->regs.edi = 0x0000;
41 if (v86_int(0x10, &tsk->regs) || (tsk->regs.eax & 0xffff) != 0x004f)
42 goto out_vbeib;
44 ib = (struct vbe_ib*)buf;
45 bufend = lbuf + sizeof(*ib);
46 memcpy(buf, vptr(lbuf), tsk->buf_len);
48 /* The original VBE Info Block is 512 bytes long. */
49 fsize = tsk->buf_len - 512;
51 t = addr(ib->mode_list_ptr);
52 /* Mode list is in the buffer, we're good. */
53 if (t < bufend) {
54 ib->mode_list_ptr = t - lbuf;
56 /* Mode list is in the ROM. We copy as much of it as we can
57 * to the task buffer. */
58 } else if (t > 0xa0000) {
59 u16 tmp;
61 td = (u16*) (buf + 512);
63 while (fsize > 2 && (tmp = v_rdw(t)) != 0xffff) {
64 fsize -= 2;
65 *td = tmp;
66 t += 2;
67 td++;
70 ib->mode_list_ptr = 512;
71 *td = 0xffff;
73 /* Mode list is somewhere else. We're seriously screwed. */
74 } else {
75 ulog("Can't retrieve mode list from %x\n", t);
76 ib->mode_list_ptr = 0;
79 buf += 512;
81 vbeib_get_string(oem_string_ptr);
82 vbeib_get_string(oem_vendor_name_ptr);
83 vbeib_get_string(oem_product_name_ptr);
84 vbeib_get_string(oem_product_rev_ptr);
85 out_vbeib:
86 v86_mem_free(lbuf);
87 } else {
88 if (tsk->buf_len) {
89 lbuf = v86_mem_alloc(tsk->buf_len);
90 memcpy(vptr(lbuf), buf, tsk->buf_len);
93 if (tsk->flags & TF_BUF_ESDI) {
94 tsk->regs.es = lbuf >> 4;
95 tsk->regs.edi = 0x0000;
98 if (tsk->flags & TF_BUF_ESBX) {
99 tsk->regs.es = lbuf >> 4;
100 tsk->regs.ebx = 0x0000;
103 if (v86_int(0x10, &tsk->regs) || (tsk->regs.eax & 0xffff) != 0x004f)
104 goto out;
106 if (tsk->buf_len && tsk->flags & TF_BUF_RET) {
107 memcpy(buf, vptr(lbuf), tsk->buf_len);
109 out:
110 if (tsk->buf_len)
111 v86_mem_free(lbuf);
114 return 0;