Preallocate buffers for palette and state. Do not save DAC registers as
we reset DAC mode and restore palette data while we are resuming always.
This commit is contained in:
parent
736b931958
commit
917b850dce
@ -73,9 +73,16 @@ struct adp_state {
|
||||
};
|
||||
typedef struct adp_state adp_state_t;
|
||||
|
||||
static void *vesa_state_buf = NULL;
|
||||
static uint32_t vesa_state_buf_offs = 0;
|
||||
static ssize_t vesa_state_buf_size = 0;
|
||||
|
||||
static u_char *vesa_palette = NULL;
|
||||
static uint32_t vesa_palette_offs = 0;
|
||||
#define VESA_PALETTE_SIZE (256 * 4)
|
||||
|
||||
/* VESA video adapter */
|
||||
static video_adapter_t *vesa_adp = NULL;
|
||||
static ssize_t vesa_state_buf_size = -1;
|
||||
|
||||
/* VESA functions */
|
||||
#if 0
|
||||
@ -188,7 +195,7 @@ static int vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g,
|
||||
#define STATE_MOST (STATE_HW | STATE_DATA | STATE_REG)
|
||||
#define STATE_ALL (STATE_HW | STATE_DATA | STATE_DAC | STATE_REG)
|
||||
static ssize_t vesa_bios_state_buf_size(void);
|
||||
static int vesa_bios_save_restore(int code, void *p, size_t size);
|
||||
static int vesa_bios_save_restore(int code, void *p);
|
||||
#ifdef MODE_TABLE_BROKEN
|
||||
static int vesa_bios_get_line_length(void);
|
||||
#endif
|
||||
@ -363,37 +370,28 @@ static int
|
||||
vesa_bios_save_palette(int start, int colors, u_char *palette, int bits)
|
||||
{
|
||||
x86regs_t regs;
|
||||
uint32_t offs;
|
||||
u_char *p;
|
||||
int i;
|
||||
|
||||
p = (u_char *)x86bios_alloc(&offs, colors * 4, M_NOWAIT);
|
||||
if (p == NULL)
|
||||
return (1);
|
||||
|
||||
x86bios_init_regs(®s);
|
||||
regs.R_AX = 0x4f09;
|
||||
regs.R_BL = 1;
|
||||
regs.R_CX = colors;
|
||||
regs.R_DX = start;
|
||||
|
||||
regs.R_ES = X86BIOS_PHYSTOSEG(offs);
|
||||
regs.R_DI = X86BIOS_PHYSTOOFF(offs);
|
||||
regs.R_ES = X86BIOS_PHYSTOSEG(vesa_palette_offs);
|
||||
regs.R_DI = X86BIOS_PHYSTOOFF(vesa_palette_offs);
|
||||
|
||||
x86bios_intr(®s, 0x10);
|
||||
|
||||
if (regs.R_AX != 0x004f) {
|
||||
x86bios_free(p, colors * 4);
|
||||
if (regs.R_AX != 0x004f)
|
||||
return (1);
|
||||
}
|
||||
|
||||
bits = 8 - bits;
|
||||
for (i = 0; i < colors; ++i) {
|
||||
palette[i * 3] = p[i * 4 + 2] << bits;
|
||||
palette[i * 3 + 1] = p[i * 4 + 1] << bits;
|
||||
palette[i * 3 + 2] = p[i * 4] << bits;
|
||||
palette[i * 3] = vesa_palette[i * 4 + 2] << bits;
|
||||
palette[i * 3 + 1] = vesa_palette[i * 4 + 1] << bits;
|
||||
palette[i * 3 + 2] = vesa_palette[i * 4] << bits;
|
||||
}
|
||||
x86bios_free(p, colors * 4);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -403,37 +401,28 @@ vesa_bios_save_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
|
||||
int bits)
|
||||
{
|
||||
x86regs_t regs;
|
||||
uint32_t offs;
|
||||
u_char *p;
|
||||
int i;
|
||||
|
||||
p = (u_char *)x86bios_alloc(&offs, colors * 4, M_NOWAIT);
|
||||
if (p == NULL)
|
||||
return (1);
|
||||
|
||||
x86bios_init_regs(®s);
|
||||
regs.R_AX = 0x4f09;
|
||||
regs.R_BL = 1;
|
||||
regs.R_CX = colors;
|
||||
regs.R_DX = start;
|
||||
|
||||
regs.R_ES = X86BIOS_PHYSTOSEG(offs);
|
||||
regs.R_DI = X86BIOS_PHYSTOOFF(offs);
|
||||
regs.R_ES = X86BIOS_PHYSTOSEG(vesa_palette_offs);
|
||||
regs.R_DI = X86BIOS_PHYSTOOFF(vesa_palette_offs);
|
||||
|
||||
x86bios_intr(®s, 0x10);
|
||||
|
||||
if (regs.R_AX != 0x004f) {
|
||||
x86bios_free(p, colors * 4);
|
||||
if (regs.R_AX != 0x004f)
|
||||
return (1);
|
||||
}
|
||||
|
||||
bits = 8 - bits;
|
||||
for (i = 0; i < colors; ++i) {
|
||||
r[i] = p[i * 4 + 2] << bits;
|
||||
g[i] = p[i * 4 + 1] << bits;
|
||||
b[i] = p[i * 4] << bits;
|
||||
r[i] = vesa_palette[i * 4 + 2] << bits;
|
||||
g[i] = vesa_palette[i * 4 + 1] << bits;
|
||||
b[i] = vesa_palette[i * 4] << bits;
|
||||
}
|
||||
x86bios_free(p, colors * 4);
|
||||
|
||||
return (0);
|
||||
}
|
||||
@ -442,32 +431,25 @@ static int
|
||||
vesa_bios_load_palette(int start, int colors, u_char *palette, int bits)
|
||||
{
|
||||
x86regs_t regs;
|
||||
uint32_t offs;
|
||||
u_char *p;
|
||||
int i;
|
||||
|
||||
p = (u_char *)x86bios_alloc(&offs, colors * 4, M_NOWAIT);
|
||||
if (p == NULL)
|
||||
return (1);
|
||||
|
||||
x86bios_init_regs(®s);
|
||||
regs.R_AX = 0x4f09;
|
||||
/* regs.R_BL = 0; */
|
||||
regs.R_CX = colors;
|
||||
regs.R_DX = start;
|
||||
|
||||
regs.R_ES = X86BIOS_PHYSTOSEG(offs);
|
||||
regs.R_DI = X86BIOS_PHYSTOOFF(offs);
|
||||
regs.R_ES = X86BIOS_PHYSTOSEG(vesa_palette_offs);
|
||||
regs.R_DI = X86BIOS_PHYSTOOFF(vesa_palette_offs);
|
||||
|
||||
bits = 8 - bits;
|
||||
for (i = 0; i < colors; ++i) {
|
||||
p[i * 4] = palette[i * 3 + 2] >> bits;
|
||||
p[i * 4 + 1] = palette[i * 3 + 1] >> bits;
|
||||
p[i * 4 + 2] = palette[i * 3] >> bits;
|
||||
p[i * 4 + 3] = 0;
|
||||
vesa_palette[i * 4] = palette[i * 3 + 2] >> bits;
|
||||
vesa_palette[i * 4 + 1] = palette[i * 3 + 1] >> bits;
|
||||
vesa_palette[i * 4 + 2] = palette[i * 3] >> bits;
|
||||
vesa_palette[i * 4 + 3] = 0;
|
||||
}
|
||||
x86bios_intr(®s, 0x10);
|
||||
x86bios_free(p, colors * 4);
|
||||
|
||||
return (regs.R_AX != 0x004f);
|
||||
}
|
||||
@ -477,32 +459,25 @@ vesa_bios_load_palette2(int start, int colors, u_char *r, u_char *g, u_char *b,
|
||||
int bits)
|
||||
{
|
||||
x86regs_t regs;
|
||||
uint32_t offs;
|
||||
u_char *p;
|
||||
int i;
|
||||
|
||||
p = (u_char *)x86bios_alloc(&offs, colors * 4, M_NOWAIT);
|
||||
if (p == NULL)
|
||||
return (1);
|
||||
|
||||
x86bios_init_regs(®s);
|
||||
regs.R_AX = 0x4f09;
|
||||
/* regs.R_BL = 0; */
|
||||
regs.R_CX = colors;
|
||||
regs.R_DX = start;
|
||||
|
||||
regs.R_ES = X86BIOS_PHYSTOSEG(offs);
|
||||
regs.R_DI = X86BIOS_PHYSTOOFF(offs);
|
||||
regs.R_ES = X86BIOS_PHYSTOSEG(vesa_palette_offs);
|
||||
regs.R_DI = X86BIOS_PHYSTOOFF(vesa_palette_offs);
|
||||
|
||||
bits = 8 - bits;
|
||||
for (i = 0; i < colors; ++i) {
|
||||
p[i * 4] = b[i] >> bits;
|
||||
p[i * 4 + 1] = g[i] >> bits;
|
||||
p[i * 4 + 2] = r[i] >> bits;
|
||||
p[i * 4 + 3] = 0;
|
||||
vesa_palette[i * 4] = b[i] >> bits;
|
||||
vesa_palette[i * 4 + 1] = g[i] >> bits;
|
||||
vesa_palette[i * 4 + 2] = r[i] >> bits;
|
||||
vesa_palette[i * 4 + 3] = 0;
|
||||
}
|
||||
x86bios_intr(®s, 0x10);
|
||||
x86bios_free(p, colors * 4);
|
||||
|
||||
return (regs.R_AX != 0x004f);
|
||||
}
|
||||
@ -515,7 +490,7 @@ vesa_bios_state_buf_size(void)
|
||||
x86bios_init_regs(®s);
|
||||
regs.R_AX = 0x4f04;
|
||||
/* regs.R_DL = STATE_SIZE; */
|
||||
regs.R_CX = STATE_ALL;
|
||||
regs.R_CX = STATE_MOST;
|
||||
|
||||
x86bios_intr(®s, 0x10);
|
||||
|
||||
@ -526,38 +501,31 @@ vesa_bios_state_buf_size(void)
|
||||
}
|
||||
|
||||
static int
|
||||
vesa_bios_save_restore(int code, void *p, size_t size)
|
||||
vesa_bios_save_restore(int code, void *p)
|
||||
{
|
||||
x86regs_t regs;
|
||||
uint32_t offs;
|
||||
void *buf;
|
||||
|
||||
if (code != STATE_SAVE && code != STATE_LOAD)
|
||||
return (1);
|
||||
|
||||
buf = x86bios_alloc(&offs, size, M_NOWAIT);
|
||||
if (buf == NULL)
|
||||
return (1);
|
||||
|
||||
x86bios_init_regs(®s);
|
||||
regs.R_AX = 0x4f04;
|
||||
regs.R_DL = code;
|
||||
regs.R_CX = STATE_ALL;
|
||||
regs.R_CX = STATE_MOST;
|
||||
|
||||
regs.R_ES = X86BIOS_PHYSTOSEG(offs);
|
||||
regs.R_BX = X86BIOS_PHYSTOOFF(offs);
|
||||
regs.R_ES = X86BIOS_PHYSTOSEG(vesa_state_buf_offs);
|
||||
regs.R_BX = X86BIOS_PHYSTOOFF(vesa_state_buf_offs);
|
||||
|
||||
switch (code) {
|
||||
case STATE_SAVE:
|
||||
x86bios_intr(®s, 0x10);
|
||||
bcopy(buf, p, size);
|
||||
bcopy(vesa_state_buf, p, vesa_state_buf_size);
|
||||
break;
|
||||
case STATE_LOAD:
|
||||
bcopy(p, buf, size);
|
||||
bcopy(p, vesa_state_buf, vesa_state_buf_size);
|
||||
x86bios_intr(®s, 0x10);
|
||||
break;
|
||||
}
|
||||
x86bios_free(buf, size);
|
||||
|
||||
return (regs.R_AX != 0x004f);
|
||||
}
|
||||
@ -1017,6 +985,15 @@ vesa_bios_init(void)
|
||||
goto fail;
|
||||
|
||||
x86bios_free(vmbuf, sizeof(*buf));
|
||||
|
||||
vesa_palette = x86bios_alloc(&vesa_palette_offs,
|
||||
VESA_PALETTE_SIZE + vesa_state_buf_size, M_WAITOK);
|
||||
vesa_state_buf_size = vesa_bios_state_buf_size();
|
||||
if (vesa_state_buf_size > 0) {
|
||||
vesa_state_buf = vesa_palette + VESA_PALETTE_SIZE;
|
||||
vesa_state_buf_offs = vesa_palette_offs + VESA_PALETTE_SIZE;
|
||||
}
|
||||
|
||||
return (0);
|
||||
|
||||
fail:
|
||||
@ -1414,20 +1391,16 @@ vesa_save_state(video_adapter_t *adp, void *p, size_t size)
|
||||
if (adp != vesa_adp)
|
||||
return ((*prevvidsw->save_state)(adp, p, size));
|
||||
|
||||
if (vesa_state_buf_size == -1) {
|
||||
vesa_state_buf_size = vesa_bios_state_buf_size();
|
||||
if (vesa_state_buf_size == 0)
|
||||
return (1);
|
||||
}
|
||||
if (vesa_state_buf_size == 0)
|
||||
return (1);
|
||||
if (size == 0)
|
||||
return (offsetof(adp_state_t, regs) + vesa_state_buf_size);
|
||||
else if (size < (offsetof(adp_state_t, regs) + vesa_state_buf_size))
|
||||
if (size < (offsetof(adp_state_t, regs) + vesa_state_buf_size))
|
||||
return (1);
|
||||
|
||||
((adp_state_t *)p)->sig = V_STATE_SIG;
|
||||
bzero(((adp_state_t *)p)->regs, vesa_state_buf_size);
|
||||
return (vesa_bios_save_restore(STATE_SAVE, ((adp_state_t *)p)->regs,
|
||||
vesa_state_buf_size));
|
||||
return (vesa_bios_save_restore(STATE_SAVE, ((adp_state_t *)p)->regs));
|
||||
}
|
||||
|
||||
static int
|
||||
@ -1437,7 +1410,7 @@ vesa_load_state(video_adapter_t *adp, void *p)
|
||||
if ((adp != vesa_adp) || (((adp_state_t *)p)->sig != V_STATE_SIG))
|
||||
return ((*prevvidsw->load_state)(adp, p));
|
||||
|
||||
if (vesa_state_buf_size <= 0)
|
||||
if (vesa_state_buf_size == 0)
|
||||
return (1);
|
||||
|
||||
/* Try BIOS POST to restore a sane state. */
|
||||
@ -1445,8 +1418,7 @@ vesa_load_state(video_adapter_t *adp, void *p)
|
||||
(void)int10_set_mode(adp->va_initial_bios_mode);
|
||||
(void)vesa_set_mode(adp, adp->va_mode);
|
||||
|
||||
return (vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs,
|
||||
vesa_state_buf_size));
|
||||
return (vesa_bios_save_restore(STATE_LOAD, ((adp_state_t *)p)->regs));
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -1892,6 +1864,9 @@ vesa_unload(void)
|
||||
free(vesa_revstr, M_DEVBUF);
|
||||
if (vesa_vmode != &vesa_vmode_empty)
|
||||
free(vesa_vmode, M_DEVBUF);
|
||||
if (vesa_palette != NULL)
|
||||
x86bios_free(vesa_palette,
|
||||
VESA_PALETTE_SIZE + vesa_state_buf_size);
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user