Author:
Klaus P. Gerlicher
+ Reactos Port by Eugene Ingerman
Revision History:
////////////////////////////////////////////////////
// PROTOTYPES
////
+extern void pice_save_current_registers(void);
+extern void pice_restore_current_registers(void);
+extern void pice_set_mode_3_80x50(void);
+extern void pice_set_mode_3_80x25(void);
+
+extern UCHAR cGraphTable[8*256];
+
+// storage for original VGA font
+UCHAR cGraphTable2[16*256];
////////////////////////////////////////////////////
// DEFINES
////
-#define LOCAL_CONSOLE // undefine this to get text only hercules version
+#define VGA_EXTENDED // define this for 80x50 console mode
+
+#ifndef VGA_EXTENDED
+#define SCREEN_BUFFER_SIZE (80*25*2)
+#else
+#define SCREEN_BUFFER_SIZE (80*50*2)
+#endif
+
+/* Port addresses of control regs */
+#define MISCOUTPUT 0x3c2
+#define FEATURECONTROL 0x3da
+#define SEQUENCER 0x3c4
+#define CRTC 0x03d4
+#define GRAPHICS 0x3ce
+#define ATTRIBS 0x03c0
+#define PELADDRESSWRITE 0x3c8
+#define PELDATAREG 0x3c9
+
+/* Number of regs on the various controllers */
+
+#define MAXSEQ 5
+#define MAXCRTC 0x19
+#define MAXGRAPH 0x9
+#define MAXATTRIB 0x015
////////////////////////////////////////////////////
// GLOBALS
////
-// used for HERCUELS text and VGA text mode
-/*
+// used for HERCULES text and VGA text mode
WINDOW wWindowVga[4]=
+#ifndef VGA_EXTENDED
{
{1,3,1,0,FALSE},
{5,4,1,0,FALSE},
{10,9,1,0,FALSE},
{20,4,1,0,FALSE}
};
-*/
-
-WINDOW wWindowVga[4]=
+#else // VGA_EXTENDED
{
{1,3,1,0,FALSE},
- {5,7,1,0,FALSE},
- {14,15,1,0,FALSE},
- {30,14,1,0,FALSE}
+ {5,4,1,0,FALSE},
+ {10,24,1,0,FALSE},
+ {35,14,1,0,FALSE}
};
-
-// 25 line text mode
-UCHAR MGATable25[]={97,80,82,15,25, 6,25,25, 2,13,11,12, 0, 0, 0, 0};
+#endif // VGA_EXTENDED
PUCHAR pScreenBufferVga;
PUCHAR pScreenBufferSaveVga = NULL;
PUCHAR pScreenBufferTempVga;
PUCHAR pScreenBufferHardwareVga;
+PUCHAR pFontBufferVga = NULL;
UCHAR offset_a = 0;
UCHAR offset_c = 0,offset_d = 0;
}u;
}attr;
+unsigned char oldgraphicsmode;
+unsigned char oldgraphicsmisc;
+unsigned char oldsqregmapmask;
+unsigned char oldsqregmemory;
+unsigned char oldgraphicssetresetenable;
+unsigned char oldgraphicsreadmapsel;
+
+unsigned char read_vga_reg(int port, int reg)
+{
+ outportb(port,reg);
+ return(inportb(port+1));
+}
+
+void write_vga_reg(int port, unsigned char reg, unsigned char value)
+{
+ outportb(port,reg);
+ outportb(port+1,value);
+}
+
+/* Registers within controllers */
+#define VREND 0x11
+#define GRREGSETRESET 0
+#define GRREGENABLESETRESET 1
+#define GRREGREADMAPSEL 4
+#define SQREGMAPMASK 2
+#define SQREGMEMORY 4
+#define GRREGWRMODE 5
+#define GRREGMISC 6
+
+void map_font_memory(void)
+{
+ oldgraphicssetresetenable = read_vga_reg(GRAPHICS, GRREGENABLESETRESET);
+ oldgraphicsmode = read_vga_reg(GRAPHICS, GRREGWRMODE);
+ oldgraphicsmisc = read_vga_reg(GRAPHICS, GRREGMISC);
+ oldgraphicsreadmapsel = read_vga_reg(GRAPHICS, GRREGREADMAPSEL);
+ oldsqregmapmask = read_vga_reg(SEQUENCER, SQREGMAPMASK);
+ oldsqregmemory = read_vga_reg(SEQUENCER, SQREGMEMORY);
+
+
+ /* Make sure set/reset enable is off */
+ write_vga_reg(GRAPHICS,GRREGENABLESETRESET,0);
+ /* Select read plane 2 */
+ write_vga_reg(GRAPHICS,GRREGREADMAPSEL,0x02);
+ /* Make sure write and read mode = 0 */
+ write_vga_reg(GRAPHICS,GRREGWRMODE,0x00);
+ /* Set mapping to 64K at a000:0 & turn off odd/even at the graphics reg */
+ write_vga_reg(GRAPHICS,GRREGMISC, 0x04);
+ /* Set sequencer plane to 2 */
+ write_vga_reg(SEQUENCER,SQREGMAPMASK, 0x04);
+ /* Turn off odd/even at the sequencer */
+ write_vga_reg(SEQUENCER,SQREGMEMORY, 0x07);
+}
+
+void unmap_font_memory(void)
+{
+ write_vga_reg(GRAPHICS,GRREGENABLESETRESET,oldgraphicssetresetenable);
+ write_vga_reg(GRAPHICS,GRREGWRMODE,oldgraphicsmode);
+ write_vga_reg(GRAPHICS,GRREGREADMAPSEL,oldgraphicsreadmapsel);
+ write_vga_reg(GRAPHICS,GRREGMISC, oldgraphicsmisc);
+ write_vga_reg(SEQUENCER,SQREGMAPMASK, oldsqregmapmask);
+ write_vga_reg(SEQUENCER,SQREGMEMORY, oldsqregmemory);
+}
+
+/* Font and palette constants */
+#define BYTESPERFONT 8
+#define FONTENTRIES 256
+#define FONTBUFFERSIZE 8192
+
+void save_font(UCHAR* graph_table)
+{
+ PUCHAR FontBase = pFontBufferVga;
+ int i,j;
+ map_font_memory();
+
+ for (i=0; i < FONTENTRIES; i++)
+ for (j=0; j < 16; j++)
+ graph_table[i*16+j] = FontBase[i*32+j];
+
+ unmap_font_memory();
+}
+
+void load_font(UCHAR* graph_table,int bEnter)
+{
+ PUCHAR FontBase = pFontBufferVga;
+ int i,j;
+ map_font_memory();
+
+ if(bEnter)
+ {
+#ifdef VGA_EXTENDED
+ for (i=0; i < FONTENTRIES; i++)
+ for (j=0; j < 8; j++)
+ FontBase[i*32+j] = graph_table[i*BYTESPERFONT+j];
+#else // VGA_EXTENDED
+ for (i=0; i < FONTENTRIES; i++)
+ for (j=0; j < 16; j++)
+ FontBase[i*32+j] = graph_table[i*BYTESPERFONT+(j/2)] << (j&1);
+#endif // VGA_EXTENDED
+ }
+ else
+ {
+ for (i=0; i < FONTENTRIES; i++)
+ for (j=0; j < 16; j++)
+ FontBase[i*32+j] = graph_table[i*16+j];
+ }
+
+ unmap_font_memory();
+}
+
//*************************************************************************
// SetForegroundColorVga()
//
bCursorEnabled=TRUE;
-#ifdef LOCAL_CONSOLE
outb_p(0x0a,0x3d4);
outb_p(inb_p(0x3d5)&~0x20,0x3d5);
-#else
- outb_p(0x0a,0x3b4);
- outb_p(inb_p(0x3b5)&~0x20,0x3b5);
-#endif
LEAVE_FUNC();
}
ENTER_FUNC();
bCursorEnabled=FALSE;
-#ifdef LOCAL_CONSOLE
outb_p(0x0a,0x3d4);
outb_p(inb_p(0x3d5)|0x20,0x3d5);
-#else
- outb_p(0x0a,0x3b4);
- outb_p(inb_p(0x3b5)|0x20,0x3b5);
-#endif
LEAVE_FUNC();
}
//*************************************************************************
void CopyLineToVga(USHORT dest,USHORT src)
{
- USHORT i;
PUSHORT p = (PUSHORT)pScreenBufferVga;
ENTER_FUNC();
- for(i=0;i<GLOBAL_SCREEN_WIDTH;i++)
- p[dest*GLOBAL_SCREEN_WIDTH+i] = p[src*GLOBAL_SCREEN_WIDTH+i];
+ PICE_memcpy(&p[dest*GLOBAL_SCREEN_WIDTH],&p[src*GLOBAL_SCREEN_WIDTH],GLOBAL_SCREEN_WIDTH*sizeof(USHORT));
LEAVE_FUNC();
}
{
ULONG i;
PUSHORT p = (PUSHORT)pScreenBufferVga;
-#ifdef LOCAL_CONSOLE
USHORT attr;
-#endif
- if(line<25)
+ if(line < GLOBAL_SCREEN_HEIGHT)
{
-#ifdef LOCAL_CONSOLE
attr = p[line*GLOBAL_SCREEN_WIDTH]>>8;
attr = ((attr & 0x07)<<4) | ((attr & 0xF0)>>4);
attr <<= 8;
for(i=0;i<GLOBAL_SCREEN_WIDTH;i++)
p[line*GLOBAL_SCREEN_WIDTH + i] = (p[line*GLOBAL_SCREEN_WIDTH + i] & 0x00FF) | attr;
-#else
- for(i=0;i<GLOBAL_SCREEN_WIDTH;i++)
- p[line*GLOBAL_SCREEN_WIDTH + i] = p[line*GLOBAL_SCREEN_WIDTH + i] ^ 0xFF00;
-#endif
}
}
ULONG i;
PUSHORT p = (PUSHORT)pScreenBufferVga;
- if(line<GLOBAL_SCREEN_HEIGHT)
+ if(line < GLOBAL_SCREEN_HEIGHT)
{
for(i=0;i<GLOBAL_SCREEN_WIDTH;i++)
p[line*GLOBAL_SCREEN_WIDTH + i] = (p[line*GLOBAL_SCREEN_WIDTH + i] & 0xF0FF) | 0x0c00;
ULONG i;
PUSHORT p = (PUSHORT)pScreenBufferVga;
- if(line<GLOBAL_SCREEN_HEIGHT)
+ if(line < GLOBAL_SCREEN_HEIGHT)
{
for(i=0;i<GLOBAL_SCREEN_WIDTH;i++)
p[line*GLOBAL_SCREEN_WIDTH + i] = (USHORT)((attr.u.Asuchar<<8) | 0x20);
charoffset = (y* GLOBAL_SCREEN_WIDTH + x);
-#ifndef LOCAL_CONSOLE
- outb_p(0x0e,0x3b4);
- data=(UCHAR)((charoffset>>8)&0xFF);
- outb_p(data,0x3b5);
-
- outb_p(0x0d,0x3b4);
- data=(UCHAR)(charoffset & 0xFF);
- outb_p(data,0x3b5);
-#else
outb_p(0x0e,0x3d4);
data=(UCHAR)((charoffset>>8)&0xFF);
outb_p(data,0x3d5);
outb_p(0x0f,0x3d4);
data=(UCHAR)(charoffset & 0xFF);
outb_p(data,0x3d5);
-#endif
}
}
//*************************************************************************
void SaveGraphicsStateVga(void)
{
-#ifdef LOCAL_CONSOLE
- // copy the screen content to temp area
- PICE_memcpy(pScreenBufferTempVga,pScreenBufferHardwareVga,FRAMEBUFFER_SIZE);
+ UCHAR data;
+
+ // save current regs
+ pice_save_current_registers();
+
+ // unprotect crtc regs 0-7
+ outb_p(0x11,0x3d4);
+ data = inb_p(0x3d5);
+ outb_p(data & 0x7F,0x3d5);
+
+ // save current font
+ save_font(cGraphTable2);
+
+ // restore original regs
+#ifdef VGA_EXTENDED
+ pice_set_mode_3_80x50();
+#else
+ pice_set_mode_3_80x25();
+#endif
+
+ // load a font
+ load_font(cGraphTable,1);
+
+ // copy the screen content to temp area
+ PICE_memcpy(pScreenBufferTempVga,pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE);
// copy the console to the screen
- PICE_memcpy(pScreenBufferHardwareVga,pScreenBufferVga,FRAMEBUFFER_SIZE);
+ PICE_memcpy(pScreenBufferHardwareVga,pScreenBufferVga,SCREEN_BUFFER_SIZE);
// save original pointer
pScreenBufferSaveVga = pScreenBufferVga;
// pScreenBufferVga now points to screen
pScreenBufferVga = pScreenBufferHardwareVga;
-
- // save video RAM start address
- outb_p(0xc,0x3d4);
- offset_c = inb_p(0x3d5);
- outb_p(0x0,0x3d5);
- outb_p(0xd,0x3d4);
- offset_d = inb_p(0x3d5);
- outb_p(0x0,0x3d5);
-
- // cursor state
- outb_p(0x0a,0x3d4);
- offset_a = inb_p(0x3d5);
- // cursor position
- outb_p(0x0e,0x3d4);
- offset_e = inb_p(0x3d5);
- outb_p(0x0f,0x3d4);
- offset_f = inb_p(0x3d5);
-#endif
}
//*************************************************************************
//*************************************************************************
void RestoreGraphicsStateVga(void)
{
-#ifdef LOCAL_CONSOLE
+ UCHAR data;
+
+ // unprotect crtc regs 0-7
+ outb_p(0x11,0x3d4);
+ data = inb_p(0x3d5);
+ outb_p(data & 0x7F,0x3d5);
+
+ // restore original regs
+ pice_restore_current_registers();
+
+ // load a font
+ load_font(cGraphTable2,0);
+
pScreenBufferVga = pScreenBufferSaveVga;
// copy screen to the console
- PICE_memcpy(pScreenBufferVga,pScreenBufferHardwareVga,FRAMEBUFFER_SIZE);
+ PICE_memcpy(pScreenBufferVga,pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE);
// copy the temp area to the screen
- PICE_memcpy(pScreenBufferHardwareVga,pScreenBufferTempVga,FRAMEBUFFER_SIZE);
-
- // restore video RAM start address
- outb_p(0xc,0x3d4);
- outb_p(offset_c,0x3d5);
- outb_p(0xd,0x3d4);
- outb_p(offset_d,0x3d5);
-
- // cursor state
- outb_p(0x0a,0x3d4);
- outb_p(offset_a,0x3d5);
- // cursor position
- outb_p(0x0e,0x3d4);
- outb_p(offset_e,0x3d5);
- outb_p(0x0f,0x3d4);
- outb_p(offset_f,0x3d5);
-#endif
+ PICE_memcpy(pScreenBufferHardwareVga,pScreenBufferTempVga,SCREEN_BUFFER_SIZE);
}
//*************************************************************************
BOOLEAN ConsoleInitVga(void)
{
BOOLEAN bResult = FALSE;
-#ifndef LOCAL_CONSOLE
- PUCHAR pMGATable = MGATable25;
- UCHAR i,reg,data;
-#endif
PUSHORT p;
PHYSICAL_ADDRESS FrameBuffer;
+ PHYSICAL_ADDRESS FontBuffer;
ENTER_FUNC();
SetWindowGeometry(wWindowVga);
GLOBAL_SCREEN_WIDTH = 80;
- GLOBAL_SCREEN_HEIGHT = 45;
+#ifndef VGA_EXTENDED
+ GLOBAL_SCREEN_HEIGHT = 25;
+#else // VGA_EXTENDED
+ GLOBAL_SCREEN_HEIGHT = 50;
+#endif // VGA_EXTENDED
attr.u.Asuchar = 0x07;
-#ifdef LOCAL_CONSOLE
// the real framebuffer
FrameBuffer.u.LowPart = 0xB8000;
- pScreenBufferHardwareVga = MmMapIoSpace(FrameBuffer,FRAMEBUFFER_SIZE,FALSE);
+ pScreenBufferHardwareVga = MmMapIoSpace(FrameBuffer,SCREEN_BUFFER_SIZE,FALSE);
+
+ //The real font buffer
+ FontBuffer.u.LowPart = 0xA0000;
+ pFontBufferVga = MmMapIoSpace(FontBuffer,FONTBUFFERSIZE,FALSE);
+
// the console
- pScreenBufferVga = PICE_malloc(FRAMEBUFFER_SIZE,NONPAGEDPOOL);
+ pScreenBufferVga = PICE_malloc(SCREEN_BUFFER_SIZE,NONPAGEDPOOL);
// the save area
- pScreenBufferTempVga = PICE_malloc(FRAMEBUFFER_SIZE,NONPAGEDPOOL);
-#else
- outb_p(0,0x3b8);
- outb_p(0,0x3bf);
- for(i=0;i<sizeof(MGATable25);i++)
- {
- reg=i;
- outb_p(reg,0x3b4);
- data=pMGATable[i];
- outb_p(data,0x3b5);
- }
- outb_p(0x08,0x3b8);
+ pScreenBufferTempVga = PICE_malloc(SCREEN_BUFFER_SIZE,NONPAGEDPOOL);
- pScreenBufferVga=MmMapIoSpace(0xB0000,FRAMEBUFFER_SIZE,MmWriteCombined);
-#endif
if(pScreenBufferVga)
{
DPRINT((0,"VGA memory phys. 0x000b0000 mapped to virt. 0x%x\n",pScreenBufferVga));
p = (PUSHORT)pScreenBufferVga;
- PICE_memset(pScreenBufferVga,0x0,FRAMEBUFFER_SIZE);
+ PICE_memset(pScreenBufferVga,0x0,SCREEN_BUFFER_SIZE);
DPRINT((0,"VGA memory cleared!\n"));
{
ENTER_FUNC();
-#ifdef LOCAL_CONSOLE
if(pScreenBufferVga)
{
PICE_free(pScreenBufferVga);
PICE_free(pScreenBufferTempVga);
- MmUnmapIoSpace(pScreenBufferHardwareVga,FRAMEBUFFER_SIZE);
+ MmUnmapIoSpace(pScreenBufferHardwareVga,SCREEN_BUFFER_SIZE);
+ MmUnmapIoSpace(pFontBufferVga,FONTBUFFERSIZE);
}
-#else
- // HERC video off
- outb_p(0,0x3b8);
- outb_p(0,0x3bf);
-
- if(pScreenBufferVga)
- MmUnmapIoSpace(pScreenBufferVga,FRAMEBUFFER_SIZE);
-#endif
LEAVE_FUNC();
}
+
+
--- /dev/null
+;/*++
+;
+;Copyright (c) 1998-2001 Klaus P. Gerlicher
+;
+;Module Name:
+;
+; vga_utils.asm
+;
+;Abstract:
+;
+; assembler function for directly programming standard VGA
+;
+;Environment:
+;
+; LINUX 2.2.X
+; Kernel mode only
+;
+;Author:
+;
+; Klaus P. Gerlicher
+; Reactos Port by Eugene Ingerman
+;
+;Revision History:
+;
+; 30-Oct-2001: created
+;
+;Copyright notice:
+;
+; This file may be distributed under the terms of the GNU Public License.
+;
+;--*/
+
+global _pice_save_current_registers
+global _pice_restore_current_registers
+global _pice_set_mode_3_80x50
+global _pice_set_mode_3_80x25
+
+;****************************************************************************
+;* some assign's ************************************************************
+;****************************************************************************
+%assign VGA_CRT_REGISTERS 24
+%assign VGA_ATTRIBUTE_REGISTERS 21
+%assign VGA_GRAPHIC_REGISTERS 9
+%assign VGA_SEQUENCER_REGISTERS 5
+%assign VGA_MISC_REGISTERS 1
+
+%assign VGA_IO_BASE 03c0h
+%assign VGA_IO_SIZE 020h
+
+%assign VGA_ATTRIBUTE_INDEX 03c0h
+%assign VGA_ATTRIBUTE_DATA_WRITE 03c0h
+%assign VGA_ATTRIBUTE_DATA_READ 03c1h
+%assign VGA_MISC_DATA_WRITE 03c2h
+%assign VGA_SEQUENCER_INDEX 03c4h
+%assign VGA_SEQUENCER_DATA 03c5h
+%assign VGA_PEL_MASK 03c6h
+%assign VGA_PEL_INDEX_READ 03c7h
+%assign VGA_PEL_INDEX_WRITE 03c8h
+%assign VGA_PEL_DATA 03c9h
+%assign VGA_MISC_DATA_READ 03cch
+%assign VGA_GRAPHIC_INDEX 03ceh
+%assign VGA_GRAPHIC_DATA 03cfh
+%assign VGA_CRT_INDEX 03d4h
+%assign VGA_CRT_DATA 03d5h
+%assign VGA_INPUT_STATUS 03dah
+
+section .data
+pice_mode3_80x50_registers:
+; offsets 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18
+.crt: db 0x5f,0x4f,0x50,0x82,0x55,0x80,0xbf,0x1f,0x00,0x67,0x06,0x07,0x00,0x00,0x00,0x00,0x9c,0x8f,0x8f,0x28,0x1f,0x96,0xb9,0xa3,0xff
+.attribute db 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x08,0x00,0x0f,0x00,0x00
+.graphic: db 0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,0xff
+.sequencer: db 0x03,0x00,0x03,0x00,0x02 ; 9 bits per char
+;.sequencer: db 0x03,0x01,0x03,0x00,0x02 ; 8 bits per char
+.misc: db 0x67
+
+pice_mode3_80x25_registers:
+; offsets 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18
+.crt: db 0x5f,0x4f,0x50,0x82,0x55,0x81,0xbf,0x1f,0x00,0x4f,0x0d,0x0e,0x00,0x00,0x30,0xe8,0x9c,0x0e,0x8f,0x28,0x1f,0x96,0xb9,0xa3
+.attribute db 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x0c,0x00,0x0f,0x08,0x00
+.graphic: db 0x00,0x00,0x00,0x00,0x00,0x10,0x0e,0x00,0xff
+.sequencer: db 0x03,0x00,0x03,0x00,0x02
+.misc: db 0x67
+
+
+
+section .bss
+pice_current_registers:
+.crt: resb VGA_CRT_REGISTERS
+.attribute: resb VGA_ATTRIBUTE_REGISTERS
+.graphic: resb VGA_GRAPHIC_REGISTERS
+.sequencer: resb VGA_SEQUENCER_REGISTERS
+.misc: resb VGA_MISC_REGISTERS
+ align 4
+.colormap: resd 256
+
+;****************************************************************************
+;* pice_save_current_charset ************************************************
+;****************************************************************************
+section .text
+pice_address dd 0xc00a0000
+pice_save_current_charset:
+ xor dword ebx, ebx
+ call pice_select_read_plane
+ mov dword ecx, 04000h
+ mov dword esi, [pice_address]
+ mov dword edi, pice_charset_saved
+ cld
+ rep movsd
+ mov dword ebx, 00100h
+ call pice_select_read_plane
+ mov dword ecx, 04000h
+ mov dword esi, [pice_address]
+ mov dword edi, (pice_charset_saved + 010000h)
+ cld
+ rep movsd
+ mov dword ebx, 00200h
+ call pice_select_read_plane
+ mov dword ecx, 04000h
+ mov dword esi, [pice_address]
+ mov dword edi, (pice_charset_saved + 020000h)
+ cld
+ rep movsd
+ mov dword ebx, 00300h
+ call pice_select_read_plane
+ mov dword ecx, 04000h
+ mov dword esi, [pice_address]
+ mov dword edi, (pice_charset_saved + 030000h)
+ cld
+ rep movsd
+.end: ret
+
+
+
+;****************************************************************************
+;* pice_restore_current_charset ****************************************************
+;****************************************************************************
+section .text
+pice_restore_current_charset:
+ mov dword ebx, 00100h
+ call pice_select_write_plane
+ mov dword ecx, 04000h
+ mov dword esi, pice_charset_saved
+ mov dword edi, [pice_address]
+ cld
+ rep movsd
+ mov dword ebx, 00200h
+ call pice_select_write_plane
+ mov dword ecx, 04000h
+ mov dword esi, (pice_charset_saved + 010000h)
+ mov dword edi, [pice_address]
+ cld
+ rep movsd
+ mov dword ebx, 00400h
+ call pice_select_write_plane
+ mov dword ecx, 04000h
+ mov dword esi, (pice_charset_saved + 020000h)
+ mov dword edi, [pice_address]
+ cld
+ rep movsd
+ mov dword ebx, 00800h
+ call pice_select_write_plane
+ mov dword ecx, 04000h
+ mov dword esi, (pice_charset_saved + 030000h)
+ mov dword edi, [pice_address]
+ cld
+ rep movsd
+.end: ret
+
+;****************************************************************************
+;* pice_get_crt_registers **************************************************
+;****************************************************************************
+;* ebx=> pointer where to store crt registers
+;****************************************************************************
+section .text
+pice_get_crt_registers:
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_CRT_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_CRT_DATA
+ in byte al, dx
+ mov byte [ebx + ecx], al
+ inc dword ecx
+ cmp dword ecx, VGA_CRT_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_get_attribute_registers ********************************************
+;****************************************************************************
+;* ebx=> pointer where to store attribute registers
+;****************************************************************************
+section .text
+pice_get_attribute_registers:
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_INPUT_STATUS
+ in byte al, dx
+ mov dword edx, VGA_ATTRIBUTE_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_ATTRIBUTE_DATA_READ
+ in byte al, dx
+ mov byte [ebx + ecx], al
+ inc dword ecx
+ cmp dword ecx, VGA_ATTRIBUTE_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_get_graphic_registers **********************************************
+;****************************************************************************
+;* ebx=> pointer where to store graphics registers
+;****************************************************************************
+section .text
+pice_get_graphic_registers:
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ in byte al, dx
+ mov byte [ebx + ecx], al
+ inc dword ecx
+ cmp dword ecx, VGA_GRAPHIC_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_get_sequencer_registers ********************************************
+;****************************************************************************
+;* ebx=> pointer where to store sequencer registers
+;****************************************************************************
+section .text
+pice_get_sequencer_registers:
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_SEQUENCER_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ in byte al, dx
+ mov byte [ebx + ecx], al
+ inc dword ecx
+ cmp dword ecx, VGA_SEQUENCER_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_get_misc_registers *************************************************
+;****************************************************************************
+;* ebx=> pointer where to store misc register
+;****************************************************************************
+section .text
+pice_get_misc_registers:
+ mov dword edx, VGA_MISC_DATA_READ
+ in byte al, dx
+ mov byte [ebx], al
+ ret
+
+
+
+;****************************************************************************
+;* pice_get_colormap *******************************************************
+;****************************************************************************
+;* ebx=> pointer where to store colormap
+;****************************************************************************
+section .text
+pice_get_colormap:
+ xor dword ecx, ecx
+ xor dword eax, eax
+ mov dword edx, VGA_PEL_INDEX_READ
+ out word dx, al
+ mov dword edx, VGA_PEL_DATA
+.loop: in byte al, dx
+ shl dword eax, 8
+ in byte al, dx
+ shl dword eax, 8
+ in byte al, dx
+ mov dword [ebx + 4 * ecx], eax
+ inc dword ecx
+ test byte cl, cl
+ jnz .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_set_crt_registers **************************************************
+;****************************************************************************
+;* ebx=> pointer to stored crt registers
+;****************************************************************************
+section .text
+pice_set_crt_registers:
+
+ ;deprotect CRT registers 0 - 7
+
+ mov dword edx, VGA_CRT_INDEX
+ mov byte al, 011h
+ out word dx, al
+ mov dword edx, VGA_CRT_DATA
+ in byte al, dx
+ and byte al, 07fh
+ out word dx, al
+
+ ;write to the registers
+
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_CRT_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_CRT_DATA
+ mov byte al, [ebx + ecx]
+ out word dx, al
+ inc dword ecx
+ cmp dword ecx, VGA_CRT_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_set_attribute_registers ********************************************
+;****************************************************************************
+;* ebx=> pointer to stored attibute registers
+;****************************************************************************
+section .text
+pice_set_attribute_registers:
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_INPUT_STATUS
+ in byte al, dx
+ mov dword edx, VGA_ATTRIBUTE_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_ATTRIBUTE_DATA_WRITE
+ mov byte al, [ebx + ecx]
+ out word dx, al
+ inc dword ecx
+ cmp dword ecx, VGA_ATTRIBUTE_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_set_graphic_registers **********************************************
+;****************************************************************************
+;* ebx=> pointer to stored graphic registers
+;****************************************************************************
+section .text
+pice_set_graphic_registers:
+ xor dword ecx, ecx
+.loop: mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ mov byte al, [ebx + ecx]
+ out word dx, al
+ inc dword ecx
+ cmp dword ecx, VGA_GRAPHIC_REGISTERS
+ jb .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_set_sequencer_registers ********************************************
+;****************************************************************************
+;* ebx=> pointer to stored sequencer registers
+;****************************************************************************
+section .text
+pice_set_sequencer_registers:
+
+ ;synchronous reset on
+
+ mov dword edx, VGA_SEQUENCER_INDEX
+ xor dword eax, eax
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ inc dword eax
+ out word dx, al
+
+ ;write to the registers
+
+ mov dword edx, VGA_SEQUENCER_INDEX
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ mov byte al, [ebx + 1]
+ or byte al, 020h
+ out word dx, al
+ mov dword ecx, 2
+.loop: mov dword edx, VGA_SEQUENCER_INDEX
+ mov byte al, cl
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ mov byte al, [ebx + ecx]
+ out word dx, al
+ inc dword ecx
+ cmp dword ecx, VGA_SEQUENCER_REGISTERS
+ jb .loop
+
+ ;synchronous reset off
+
+ mov dword edx, VGA_SEQUENCER_INDEX
+ xor dword eax, eax
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ mov byte al, 3
+ out word dx, al
+ ret
+
+
+
+;****************************************************************************
+;* pice_set_misc_registers *************************************************
+;****************************************************************************
+;* ebx=> pointer to stored misc register
+;****************************************************************************
+section .text
+pice_set_misc_registers:
+ mov dword edx, VGA_MISC_DATA_WRITE
+ mov byte al, [ebx]
+ out word dx, al
+ ret
+
+
+
+;****************************************************************************
+;* pice_set_colormap *******************************************************
+;****************************************************************************
+;* ebx=> pointer to stored colormap
+;****************************************************************************
+section .text
+pice_set_colormap:
+ xor dword ecx, ecx
+ xor dword eax, eax
+ mov dword edx, VGA_PEL_INDEX_WRITE
+ out word dx, al
+ mov dword edx, VGA_PEL_DATA
+.loop: mov dword eax, [ebx + 4 * ecx]
+ rol dword eax, 16
+ out word dx, al
+ rol dword eax, 8
+ out word dx, al
+ rol dword eax, 8
+ out word dx, al
+ inc dword ecx
+ test byte cl, cl
+ jnz .loop
+ ret
+
+
+
+;****************************************************************************
+;* pice_screen_on **********************************************************
+;****************************************************************************
+section .text
+pice_screen_on:
+
+ ;turn on the screen
+
+ mov dword edx, VGA_SEQUENCER_INDEX
+ mov byte al, 1
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ in byte al, dx
+ and byte al, 0dfh
+ out word dx, al
+
+ ;enable video output
+
+ mov dword edx, VGA_INPUT_STATUS
+ in byte al, dx
+ mov dword edx, VGA_ATTRIBUTE_DATA_WRITE
+ mov byte al, 020h
+ out word dx, al
+ ret
+
+;****************************************************************************
+;* pice_select_write_plane *************************************************
+;****************************************************************************
+;* bl==> write mode
+;* bh==> write plane
+;****************************************************************************
+section .text
+pice_select_write_plane:
+ and dword ebx, 00f03h
+
+ ;enable set/reset = 0
+
+ mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, 1
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ xor dword eax, eax
+ out word dx, al
+
+ ;logical operation = none, rotate = 0
+
+ mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, 3
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ xor dword eax, eax
+ out word dx, al
+
+ ;select write mode
+
+ mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, 5
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ in byte al, dx
+ and byte al, 0fch
+ or byte al, bl
+ out word dx, al
+
+ ;bitmask = 0ffh
+
+ mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, 8
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ mov byte al, 0ffh
+ out word dx, al
+
+ ;select write plane
+
+ mov dword edx, VGA_SEQUENCER_INDEX
+ mov byte al, 2
+ out word dx, al
+ mov dword edx, VGA_SEQUENCER_DATA
+ mov byte al, bh
+ out word dx, al
+ ret
+
+
+
+;****************************************************************************
+;* pice_select_read_plane **************************************************
+;****************************************************************************
+;* bl==> read mode
+;* bh==> read plane
+;****************************************************************************
+section .text
+pice_select_read_plane:
+ and dword ebx, 00301h
+ shl byte bl, 3
+
+ ;select read mode
+
+ mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, 5
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ in byte al, dx
+ and byte al, 0f7h
+ or byte al, bl
+ out word dx, al
+
+ ;select read plane
+
+ mov dword edx, VGA_GRAPHIC_INDEX
+ mov byte al, 4
+ out word dx, al
+ mov dword edx, VGA_GRAPHIC_DATA
+ mov byte al, bh
+ out word dx, al
+ ret
+
+
+
+;****************************************************************************
+;* pice_save_current_registers **********************************************
+;****************************************************************************
+section .text
+_pice_save_current_registers:
+ push esi
+ push edi
+ push ebx
+
+; call pice_save_current_charset
+
+.crt: mov dword ebx, pice_current_registers.crt
+ call pice_get_crt_registers
+
+.attribute: mov dword ebx, pice_current_registers.attribute
+ call pice_get_attribute_registers
+
+.graphic: mov dword ebx, pice_current_registers.graphic
+ call pice_get_graphic_registers
+
+.sequencer: mov dword ebx, pice_current_registers.sequencer
+ call pice_get_sequencer_registers
+
+.misc: mov dword ebx, pice_current_registers.misc
+ call pice_get_misc_registers
+
+.colormap: mov dword ebx, pice_current_registers.colormap
+ call pice_get_colormap
+
+ pop ebx
+ pop edi
+ pop esi
+.end: ret
+
+;****************************************************************************
+;* pice_restore_current_registers *******************************************
+;****************************************************************************
+section .text
+_pice_restore_current_registers:
+ push esi
+ push edi
+ push ebx
+
+; call pice_restore_current_charset
+
+.misc: mov dword ebx, pice_current_registers.misc
+ call pice_set_misc_registers
+
+.crt: mov dword ebx, pice_current_registers.crt
+ call pice_set_crt_registers
+
+.attribute: mov dword ebx, pice_current_registers.attribute
+ call pice_set_attribute_registers
+
+.graphic: mov dword ebx, pice_current_registers.graphic
+ call pice_set_graphic_registers
+
+.sequencer: mov dword ebx, pice_current_registers.sequencer
+ call pice_set_sequencer_registers
+
+.screen_on: call pice_screen_on
+
+.colormap: mov dword ebx, pice_current_registers.colormap
+ call pice_set_colormap
+
+ pop ebx
+ pop edi
+ pop esi
+
+.end: ret
+
+
+;****************************************************************************
+;* pice_set_mode_3_80x50*****************************************************
+;****************************************************************************
+section .text
+_pice_set_mode_3_80x50:
+ push esi
+ push edi
+ push ebx
+
+.crt: mov dword ebx, pice_mode3_80x50_registers.crt
+ call pice_set_crt_registers
+
+.attribute: mov dword ebx, pice_mode3_80x50_registers.attribute
+ call pice_set_attribute_registers
+
+.graphic: mov dword ebx, pice_mode3_80x50_registers.graphic
+ call pice_set_graphic_registers
+
+.sequencer: mov dword ebx, pice_mode3_80x50_registers.sequencer
+ call pice_set_sequencer_registers
+
+.misc: mov dword ebx, pice_mode3_80x50_registers.misc
+ call pice_set_misc_registers
+
+.screen_on: call pice_screen_on
+
+;.colormap: mov dword ebx, pice_current_registers.colormap
+; call pice_set_colormap
+
+ pop ebx
+ pop edi
+ pop esi
+
+.end: ret
+
+;****************************************************************************
+;* pice_set_mode_3_80x25*****************************************************
+;****************************************************************************
+section .text
+_pice_set_mode_3_80x25:
+ push esi
+ push edi
+ push ebx
+
+.crt: mov dword ebx, pice_mode3_80x25_registers.crt
+ call pice_set_crt_registers
+
+.attribute: mov dword ebx, pice_mode3_80x25_registers.attribute
+ call pice_set_attribute_registers
+
+.graphic: mov dword ebx, pice_mode3_80x25_registers.graphic
+ call pice_set_graphic_registers
+
+.sequencer: mov dword ebx, pice_mode3_80x25_registers.sequencer
+ call pice_set_sequencer_registers
+
+.misc: mov dword ebx, pice_mode3_80x25_registers.misc
+ call pice_set_misc_registers
+
+.screen_on: call pice_screen_on
+
+;.colormap: mov dword ebx, pice_current_registers.colormap
+; call pice_set_colormap
+
+ pop ebx
+ pop edi
+ pop esi
+
+.end: ret
+
+;****************************************************************************
+;* uninitialized data *******************************************************
+;****************************************************************************
+section .bss
+ alignb 4
+pice_charset_saved: resb 040000h
+
+