aboutsummaryrefslogtreecommitdiffstats
path: root/vgasrc/vbe.c
diff options
context:
space:
mode:
Diffstat (limited to 'vgasrc/vbe.c')
-rw-r--r--vgasrc/vbe.c58
1 files changed, 58 insertions, 0 deletions
diff --git a/vgasrc/vbe.c b/vgasrc/vbe.c
index 20437dba..d7ce9413 100644
--- a/vgasrc/vbe.c
+++ b/vgasrc/vbe.c
@@ -377,6 +377,63 @@ fail:
}
static void
+vbe_104f09(struct bregs *regs)
+{
+ if (!CONFIG_VGA_STDVGA_PORTS) {
+ // DAC palette support only available on devices with stdvga ports
+ regs->ax = 0x0100;
+ return;
+ }
+
+ struct vgamode_s *vmode_g = get_current_mode();
+ if (! vmode_g)
+ goto fail;
+ u8 memmodel = GET_GLOBAL(vmode_g->memmodel);
+ u8 depth = GET_GLOBAL(vmode_g->depth);
+ if (memmodel == MM_DIRECT || memmodel == MM_YUV || depth > 8) {
+ regs->ax = 0x034f;
+ return;
+ }
+ if (regs->dh)
+ goto fail;
+ u8 start = regs->dl;
+ int count = regs->cx;
+ int max_colors = 1 << depth;
+ if (start + count > max_colors)
+ goto fail;
+ u16 seg = regs->es;
+ u8 *data_far = (void*)(regs->di+0);
+ u8 rgb[3];
+ int i;
+ switch (regs->bl) {
+ case 0x80:
+ case 0x00:
+ for (i = 0; i < count; i++) {
+ rgb[0] = GET_FARVAR(seg, data_far[i*4 + 2]);
+ rgb[1] = GET_FARVAR(seg, data_far[i*4 + 1]);
+ rgb[2] = GET_FARVAR(seg, data_far[i*4 + 0]);
+ stdvga_dac_write(GET_SEG(SS), rgb, start + i, 1);
+ }
+ break;
+ case 0x01:
+ for (i = 0; i < count; i++) {
+ stdvga_dac_read(GET_SEG(SS), rgb, start + i, 1);
+ SET_FARVAR(seg, data_far[i*4 + 0], rgb[2]);
+ SET_FARVAR(seg, data_far[i*4 + 1], rgb[1]);
+ SET_FARVAR(seg, data_far[i*4 + 2], rgb[0]);
+ SET_FARVAR(seg, data_far[i*4 + 3], 0);
+ }
+ break;
+ default:
+ goto fail;
+ }
+ regs->ax = 0x004f;
+ return;
+fail:
+ regs->ax = 0x014f;
+}
+
+static void
vbe_104f0a(struct bregs *regs)
{
debug_stub(regs);
@@ -456,6 +513,7 @@ handle_104f(struct bregs *regs)
case 0x06: vbe_104f06(regs); break;
case 0x07: vbe_104f07(regs); break;
case 0x08: vbe_104f08(regs); break;
+ case 0x09: vbe_104f09(regs); break;
case 0x0a: vbe_104f0a(regs); break;
case 0x10: vbe_104f10(regs); break;
case 0x15: vbe_104f15(regs); break;