delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1994/04/16/21:24:53

From: "Gordon Hogenson" <gordon AT yrd DOT chem DOT washington DOT edu>
Date: Sat, 16 Apr 1994 17:33:50 -0700
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Subject: Unsupported Interrupt -- Success, but still some questions

I have been following the discussions about unsupported
interrupts and DOS memory for a while now, knowing that
eventually my programming project would lead me in that
direction.  Let me just say that, after a couple of hours
of fiddling, consulting info, and going back my archive
of this list, I was able to get my first unsupported
interrupt to work!

(there's still a rather interesting mystery in this
article, so even if you're an expert at this, read on)

This consisted of setting the palette registers using
the Video Bios INT 0x10, function 0x10, subfunction 0x02.

I'll share my experiences with you because I have certainly
appreciated hearing about other people's adventures into this
area.

The interrupt is supposed to use data from a buffer at
ES:DX to set the palette registers.  It's an unsupported
interrupt, and it's a good example of what you need to do
when your INT is expecting a segment/offset .

First, I tried this:

void write_palette(unsigned char* table)
{
        _go32_dpmi_registers r;
        r.x.ax = 0x1002;
        r.d.edx = (unsigned long) table;
        _go32_dpmi_simulate_int(0x10, &r);
}

The above is a complete failure.  It was changing my palette,
but not very predictably.  I concluded that something was wrong
with the memory I was trying to give it.

Then I tried this, which uses a different BIOS function
to load each palette register individually:

void write_palette_regs(unsigned char * table)
{
        unsigned char i;
        union REGS r;
        r.x.bx = 0;
        for (i=0; i < 17; i++)
          {
            r.h.ah = 0x10;  /* BIOS function 10, subfunction 0: */
            r.h.al = 0x00;  /* set a single palette reg. */
            r.h.bl = i;
            r.h.bh = table[i];
            int86(0x10, &r, &r);
         }
}

This did change the palette as expected, but it also
corrupted the 9th bit of each character that was displayed
on the screen (I was in VGA text mode, 9x16 char set).
I don't know why this didn't work...

Then I went back through and looked at old messages, and
realized that I needed to call upon the services of the
infamous dosmemget and dosmemput, along with
_go32_dpmi_allocate_dos_memory to set up the ES:DX pointer.
I did this, and the palette change works perfectly:


void write_palette(unsigned char* table)
{
        _go32_dpmi_registers r;
        _go32_dpmi_seginfo info;
        info.size = 2; /* number of paragraphs (16-bytes) to allocate */
        _go32_dpmi_allocate_dos_memory(&info);
        dosmemput(table, 17, info.rm_segment*16 + info.rm_offset);
        r.x.es = info.rm_segment;
        r.x.dx = info.rm_offset;
        r.x.ax = 0x1002; /* BIOS function 0x10, subfunction 02 */
        _go32_dpmi_simulate_int(0x10, &r);
        dosmemget(info.rm_segment*16 + info.rm_offset, 17, table);
        _go32_dpmi_free_dos_memory(&info);
}

(I wonder, though, if there isn't a more efficient way of doing what
I've just done using the far pointer module?)

Thanks to DJ and Bob Babcock, whose messages have proved
very useful sorting out these things...

Gordon Hogenson


--


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019