0

I'm trying to reverse engineer an old DOS game. At the moment I'm stuck at a function that implements some functionality of VGA running in mode X. My issue is that any of the available sample codes on how to use mode X are often very similar to the one of interest, but never identical. That's why I'm having trouble putting all the pieces together and understanding the context of the function. Reading about all the different registers/ports gave me a basic understanding, but still I can not figure out the actual intention of the function as a whole. Maybe someone with more experience on that topic could help me figure it out, even if it's just some hints on where to get the right pieces of information.

Thanks a lot in advance! Here is the function in question:

void __cdecl mode12_init_maybe(int width, int height)
{
  unsigned __int8 v2; // al
  char *v3; // esi
  unsigned __int16 v4; // ax
  signed int v5; // ecx
  unsigned __int8 v6; // al
  unsigned __int8 inbyteData; // al
  unsigned __int8 v8; // al

  if ( width == 320 )
  {
    if ( height == 200 )                      
    {
      __outbyte(0x3C4u, 4u);                    // set memory mode
      inbyteData = __inbyte(0x3C5u);
      __outbyte(0x3C5u, inbyteData & 0xF7);
      __outword(0x3C4u, 0xF02u);                // set map mask to all 4 planes
      memset((void *)0xA0000, 0, 0xFFFCu);
      __outbyte(0x3D4u, 0x11u);                 // Vertical Retrace End
      v8 = __inbyte(0x3D5u);
      __outbyte(0x3D5u, v8 & 0x7F);
      __outword(0x3D4u, 0xC317u);               // turn on byte mode
      __outword(0x3D4u, 0x14u);                 // Underline Location; turn off long mode
    }
  }
  else if ( width == 360 && height == 240 )
  {
    __outbyte(0x3D4u, 0x11u);
    v2 = __inbyte(0x3D5u);
    __outbyte(0x3D5u, v2 & 0x7F);
    __outbyte(0x3C4u, 4u);
    __outbyte(0x3C5u, 6u);
    _disable();
    __outbyte(0x3C4u, 0);
    __outbyte(0x3C5u, 1u);
    __outbyte(0x3C2u, 0xE7u);
    __outbyte(0x3C4u, 0);
    __outbyte(0x3C5u, 3u);
    _enable();
    __outword(0x3C4u, 0xF02u);
    memset((void *)0xA0000, 0, 65532u);
    v3 = &byte_318EF;
    LOBYTE(v4) = 0;
    v5 = 24;
    do
    {
      if ( *v3 != -1 )
      {
        HIBYTE(v4) = *v3;
        __outword(0x3D4u, v4);
      }
      ++v3;
      LOBYTE(v4) = v4 + 1;
      --v5;
    }
    while ( v5 );
    __outbyte(0x3D4u, 0x11u);
    v6 = __inbyte(0x3D5u);
    __outbyte(0x3D5u, v6 | 0x80);
  }
}

The content of byte_318EF is as follows:

cseg02:000318EF     byte_318EF      db 6Bh, 59h, 5Ah, 8Eh, 5Eh, 8Ah, 0Dh, 3Eh, 0FFh, 0C0h
cseg02:000318EF                     db 6 dup(0FFh), 0EAh, 0ACh, 0DFh, 2Dh, 0, 0E7h, 6, 0E3h
1

It seems it’s simply performing initialization of the VGA registers and clearing the screen buffer. The array at 318EF contains the values of the CRT controller indexed registers (ports 3D4/3D5).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.