ModeQ is one of the undocumented VGA modes, very similar to ModeX. It sported a resolution of 256x256, with 256 colors and optional scanlines.

The reason for its popularity is that 256x256 is the resolution closest to many game systems (such as the NES and the Super NES) and many arcade games.

The following assembly language program will enter ModeQ (haven't tested this code in a long time, but it should work). It is written using NASM syntax. I am sorry that I do not remember where I got that actual data tables of register read/writes required (I think I modified some values laying around the Internet). The Allegro graphics package does it a slightly different way, but they work out to be the same. It requires MMX, because I use MMX to clear the screen very fast, and it assumes it is running in 386 protected mode.

; These are some macros I use in the program to save some writing.

%macro startop 1
%if %1==1
    pushad
    pushf
%else
    push ebp
    mov ebp, esp
    pushad
    pushf
%endif
%endmacro
%macro endop 1
%if %1==1
    popf
    popad
    retn
%else
    popf
    popad
    pop ebp
    retn
%endif
%endmacro
;--------------- END MACROS
;--------------- BEGIN DATA
byte_0      dw 0,0,0,0
modeq_regs
            dw 0x3c2, 0x00, 0xe3
            dw 0x3d4, 0x00, 0x5f
            dw 0x3d4, 0x01, 0x3f
            dw 0x3d4, 0x02, 0x40
            dw 0x3d4, 0x03, 0x82
            dw 0x3d4, 0x04, 0x4A
            dw 0x3d4, 0x05, 0x9A
            dw 0x3d4, 0x06, 0x23
            dw 0x3d4, 0x07, 0xb2
            dw 0x3d4, 0x08, 0x00
            dw 0x3d4, 0x09, 0x61
            dw 0x3d4, 0x10, 0x0a
            dw 0x3d4, 0x11, 0xac
            dw 0x3d4, 0x12, 0xff
            dw 0x3d4, 0x13, 0x20
            dw 0x3d4, 0x14, 0x40
            dw 0x3d4, 0x15, 0x07
            dw 0x3d4, 0x16, 0x1a
            dw 0x3d4, 0x17, 0xa3
            dw 0x3c4, 0x01, 0x01
            dw 0x3c4, 0x04, 0x0e
            dw 0x3ce, 0x05, 0x40
            dw 0x3ce, 0x06, 0x05
            dw 0x3c0, 0x10, 0x41
            dw 0x3c0, 0x13, 0x00
;--------------- END DATA
;--------------- BEGIN CODE
set_modeq
                        startop 1

                        mov    eax, 0x13
                        int    0x10

                        mov    edx,0x3D4
                        mov    eax,0x11
                        out    dx,al
                        inc    edx
                        in     al,dx
                        and    eax,0x7F
                        mov    ebx,eax
                        dec    edx
                        mov    eax,0x11
                        out    dx,al
                        inc    edx
                        mov    eax, ebx
                        out    dx,al

                        mov    ecx, 25
                        mov    ebx, modeq_regs
go_thru_till_finished
                        xor    edx, edx
                        mov    dx, [ebx]
                        cmp    dx, 0x3C0
                        jz     do3C0
                        cmp    dx, 0x3C2
                        jz     do3C2
                        cmp    dx, 0x3C3
                        jz     do3C2

                        mov    edx,[ebx]
                        mov    eax,[ebx+2]
                        out    dx,al
                        inc    edx
                        mov    eax,[ebx+4]
                        out    dx,al
                        add    ebx, 6
                        dec    ecx
                        jz     endoutq
                        jmp    go_thru_till_finished

do3C0
                        mov    edx,0x3DA
                        in     al,dx

                        mov    eax, [ebx+2]
                        or     eax,32
                        mov    edx,0x3C0
                        out    dx,al
                        mov    eax,[ebx+4]
                        out    dx,al
                        add    ebx, 6
                        dec    ecx
                        jz     endoutq
                        jmp    go_thru_till_finished

do3C2
                        mov    edx, [ebx]
                        mov    eax,[ebx+4]
                        out    dx,al
                        add    ebx, 6
                        dec    ecx
                        jz     endoutq
                        jmp    go_thru_till_finished

endoutq
                        call   clsq
                        endop  1


; This is the Clear Screen function
clsq
                        startop 1

                        movq   mm7, [byte_0]
                        mov    ecx, 8192
                        mov    edi, 0xA0000
removq
                        movq   [edi], mm7
                        dec    ecx
                        jnz    removq
                        
                        endop  1

I vaguely recall how this code works, as I wrote it in 1998 or 1999 for a NES emulator I was writing (that I never finished beyond writing everything I needed for Arkanoid or Super Mario Brothers to work). Basically, it reads a series of 3-tuples, indicated the I/O port and two values to write to it (the first value is a register number, I believe, and the second is the actual value).

Log in or register to write something here or to contact authors.