Fix a bug in the code used to retrieve the OEM strings
[v86d.git] / v86_common.c
bloba876eb47060b9c8149db6837b7a5b35e438bddda
1 #include "v86.h"
3 #define addr(t) (((t & 0xffff0000) >> 12) + (t & 0x0000ffff))
5 #define vbeib_get_string(name) \
6 { \
7 int l; \
8 t = addr(ib->name); \
9 if (t < bufend) { \
10 ib->name = t - (u32)lbuf; \
11 } else if (t > 0xa0000 && fsize > 0) { \
12 strncpy((char*)buf, (char*)t, fsize); \
13 ib->name = tsk->buf_len - fsize; \
14 l = strlen((char*)t); \
15 fsize -= l; \
16 buf += l; \
17 if (fsize < 0) \
18 fsize = 0; \
19 } else { \
20 ib->name = 0; \
21 } \
24 int v86_task(struct uvesafb_task *tsk, u8 *buf)
26 u8 *lbuf = NULL;
28 /* Get the VBE Info Block */
29 if (tsk->flags & TF_VBEIB) {
30 struct vbe_ib *ib;
31 int fsize;
32 u32 t, bufend;
33 u16 *ts, *td;
35 lbuf = v86_mem_alloc(tsk->buf_len);
36 memcpy(lbuf, buf, tsk->buf_len);
37 tsk->regs.es = (u32)lbuf >> 4;
38 tsk->regs.edi = 0x0000;
40 if (v86_int(0x10, &tsk->regs) || (tsk->regs.eax & 0xffff) != 0x004f)
41 goto out_vbeib;
43 ib = (struct vbe_ib*)buf;
44 bufend = (u32)(lbuf + sizeof(*ib));
45 memcpy(buf, lbuf, tsk->buf_len);
47 /* The original VBE Info Block is 512 bytes long. */
48 fsize = tsk->buf_len - 512;
50 t = addr(ib->mode_list_ptr);
51 /* Mode list is in the buffer, we're good. */
52 if (t < bufend) {
53 ib->mode_list_ptr = t - (u32)lbuf;
55 /* Mode list is in the ROM. We copy as much of it as we can
56 * to the task buffer. */
57 } else if (t > 0xa0000) {
58 ts = (u16*) t;
59 td = (u16*) (buf + 512);
61 while (fsize > 2 && *ts != 0xffff) {
62 fsize -= 2;
63 *td = *ts;
64 ts++;
65 td++;
68 ib->mode_list_ptr = 512;
69 *td = 0xffff;
71 /* Mode list is somewhere else. We're seriously screwed. */
72 } else {
73 ulog("Can't retrieve mode list from %x\n", t);
74 ib->mode_list_ptr = 0;
77 buf += 512;
79 vbeib_get_string(oem_string_ptr);
80 vbeib_get_string(oem_vendor_name_ptr);
81 vbeib_get_string(oem_product_name_ptr);
82 vbeib_get_string(oem_product_rev_ptr);
83 out_vbeib:
84 v86_mem_free(lbuf);
85 } else {
86 if (tsk->buf_len) {
87 lbuf = v86_mem_alloc(tsk->buf_len);
88 memcpy(lbuf, buf, tsk->buf_len);
91 if (tsk->flags & TF_BUF_ESDI) {
92 tsk->regs.es = (u32)lbuf >> 4;
93 tsk->regs.edi = 0x0000;
96 if (tsk->flags & TF_BUF_ESBX) {
97 tsk->regs.es = (u32)lbuf >> 4;
98 tsk->regs.ebx = 0x0000;
101 if (v86_int(0x10, &tsk->regs) || (tsk->regs.eax & 0xffff) != 0x004f)
102 goto out;
104 if (tsk->buf_len && tsk->flags & TF_BUF_RET) {
105 memcpy(buf, lbuf, tsk->buf_len);
107 out:
108 if (tsk->buf_len)
109 v86_mem_free(lbuf);
112 return 0;