From 4d26f08a37a611079013be4fe9dc75c722693e5f Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Mon, 14 Jul 2003 08:39:40 +0000 Subject: [PATCH] Support for setting linear frame buffer base. New way of setting up vga read/write handler or frame buffer. No longer use HostPt memory for certain video modes. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1122 --- src/hardware/vga.h | 15 ++++++- src/hardware/vga_crtc.cpp | 8 ++++ src/hardware/vga_draw.cpp | 12 ++--- src/hardware/vga_gfx.cpp | 14 +----- src/hardware/vga_memory.cpp | 89 ++++++++++++++++++++----------------- 5 files changed, 76 insertions(+), 62 deletions(-) diff --git a/src/hardware/vga.h b/src/hardware/vga.h index c3a7f9b0..6f928bbb 100644 --- a/src/hardware/vga.h +++ b/src/hardware/vga.h @@ -48,6 +48,10 @@ enum VGAModes { #define MH_SETRESET 0x0002; #define MH_BITMASK 0x0004; + +typedef Bit8u VGA_ReadHandler(PhysPt off); +typedef void VGA_WriteHandler(PhysPt off,Bit8u val); + typedef struct { bool attrindex; } VGA_Internal; @@ -78,7 +82,10 @@ typedef struct { Bit8u bytes_skip; /* Specific stuff memory write/read handling */ - PhysPt mem_base; + + VGA_ReadHandler * readhandler; + VGA_WriteHandler * writehandler; + Bit8u read_mode; Bit8u write_mode; Bit8u read_map_select; @@ -128,6 +135,7 @@ typedef struct { Bit8u reg_55; Bit8u ex_hor_overflow; Bit8u ex_ver_overflow; + Bit16u la_window; struct { Bit8u r; Bit8u n; @@ -262,13 +270,15 @@ typedef struct { VGA_Memory mem; } VGA_Type; + + /* Functions for different resolutions */ void VGA_SetMode(VGAModes mode); void VGA_SetupHandlers(void); void VGA_StartResize(void); void VGA_SetupDrawing(void); -/* Some support functions */ +/* Some DAC/Attribute functions */ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal); void VGA_ATTR_SetPalette(Bit8u index,Bit8u val); @@ -285,6 +295,7 @@ void VGA_SetupSEQ(void); void VGA_SetClock(Bitu which,Bitu target); void VGA_DACSetEntirePalette(void); void VGA_StartRetrace(void); +void VGA_StartUpdateLFB(void); extern VGA_Type vga; diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index fe704ed2..13280529 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -422,6 +422,14 @@ void write_p3d5(Bit32u port,Bit8u val) { 7 (928) RAS 6-MCLK. If set the random read/write cycle time is 6MCLKs, if clear 7MCLKs */ + case 0x59: /* Linear Address Window Position Low */ + vga.s3.la_window=(vga.s3.la_window&0xff00) | val; + VGA_StartUpdateLFB(); + break; + case 0x5a: /* Linear Address Window Position High */ + vga.s3.la_window=(vga.s3.la_window&0x00ff) | (val << 8); + VGA_StartUpdateLFB(); + break; case 0x5D: /* Extended Horizontal Overflow */ if ((val & vga.s3.ex_hor_overflow) ^ 3) { vga.s3.ex_hor_overflow=val; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index ca517d30..59ae43ec 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -26,8 +26,8 @@ //TODO Make the full draw like the vga really does from video memory. static void VGA_CGA2_Draw(Bit8u * bitdata,Bitu pitch) { - Bit8u * reader=HostMake(0xB800,0); - Bit8u * flip=HostMake(0xB800,8*1024); + Bit8u * reader=&vga.mem.linear[0]; + Bit8u * flip=&vga.mem.linear[8*1024]; Bit8u * draw; for (Bitu y=0;y> 2) & 3) { - case 0: - case 1: - vga.config.mem_base=0xa0000; - break; - case 2: - vga.config.mem_base=0xb0000; - break; - case 3: - vga.config.mem_base=0xb8000; - break; - } - if (vga.mode==M_TEXT16) VGA_SetupHandlers(); + VGA_SetupHandlers(); /* 0 Indicates Graphics Mode if set, Alphanumeric mode else. 1 Enables Odd/Even mode if set. diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index f87385d2..5f8fe67e 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -24,10 +24,10 @@ #include "dosbox.h" #include "mem.h" #include "vga.h" - +#include "paging.h" +#include "pic.h" static Bit8u VGA_NormalReadHandler(PhysPt start) { - start-=0xa0000; vga.latch.d=vga.mem.latched[start].d; switch (vga.config.read_mode) { case 0: @@ -56,7 +56,6 @@ INLINE static Bit32u RasterOp(Bit32u input,Bit32u mask) { return 0; } - INLINE static Bit32u ModeOperation(Bit8u val) { Bit32u full; switch (vga.config.write_mode) { @@ -84,26 +83,7 @@ INLINE static Bit32u ModeOperation(Bit8u val) { return full; } -static Bit8u VGA_CGA_4_ReadHandler(PhysPt start) { - return vga.mem.linear[start-0xb8000]; -} - -static void VGA_CGA_4_WriteHandler(PhysPt start,Bit8u val) { - start-=0xb8000; - vga.mem.linear[start]=val; - Bitu off; - if (start>0x2000) off=320*(((start-0x2000)/80)*2+1)+((start-0x2000) % 80)*4; - else off=320*(((start)/80)*2)+(start % 80)*4; - Bit32u * draw=(Bit32u *)&vga.mem.linear[512*1024+off]; - /* TODO Could also use a Bit32u lookup table for this */ - *draw=CGA_4_Table[val]; - draw=(Bit32u *)&vga.mem.linear[512*1024+off+0x4000*4]; - *draw=CGA_4_Table[val]; - -} - static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { - start-=0xa0000; val=(val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate)); Bit32u data=ModeOperation(val); /* Update video memory and the pixel buffer */ @@ -135,7 +115,6 @@ static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { } static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { - start-=0xa0000; Bit32u data=ModeOperation(val); // Bit32u data=ExpandTable[val]; VGA_Latch pixels; @@ -147,7 +126,6 @@ static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { } static void VGA_TEXT16_Write(PhysPt start,Bit8u val) { - start-=vga.config.mem_base; /* Check for page 2 being enabled for writing */ if (vga.seq.map_mask & 0x4) { vga.draw.font[start]=val; @@ -156,53 +134,82 @@ static void VGA_TEXT16_Write(PhysPt start,Bit8u val) { } static Bit8u VGA_TEXT16_Read(PhysPt start) { - start-=vga.config.mem_base; return vga.draw.font[start]; } void VGA_SetupHandlers(void) { - /* Sets up the correct memory handler from the vga.mode setting */ - MEM_ClearPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x20000)); + HostPt where; switch (vga.mode) { case M_LIN8: - MEM_SetupMapping(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),&vga.mem.linear[vga.s3.bank*64*1024]); + where=&vga.mem.linear[vga.s3.bank*64*1024]; break; case M_VGA: if (vga.config.chained) { - MEM_SetupMapping(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),&vga.mem.linear[vga.s3.bank*64*1024]); + where=&vga.mem.linear[vga.s3.bank*64*1024]; } else { - MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000), - &VGA_NormalReadHandler,&VGA_GFX_256U_WriteHandler); + vga.config.readhandler=&VGA_NormalReadHandler, + vga.config.writehandler=&VGA_GFX_256U_WriteHandler; + where=0; } break; case M_EGA16: - MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000), - &VGA_NormalReadHandler,&VGA_GFX_16_WriteHandler); + vga.config.readhandler=&VGA_NormalReadHandler, + vga.config.writehandler=&VGA_GFX_16_WriteHandler; + where=0; break; case M_TEXT16: /* Check if we're not in odd/even mode */ - if (vga.gfx.miscellaneous & 0x2) break; - MEM_SetupPageHandlers(PAGE_COUNT(0xa0000),PAGE_COUNT(0x10000),&VGA_TEXT16_Read,&VGA_TEXT16_Write); - //Could also do it using 0xb8000, let's double map - MEM_SetupPageHandlers(PAGE_COUNT(0xb8000),PAGE_COUNT(0x8000),&VGA_TEXT16_Read,&VGA_TEXT16_Write); + if (vga.gfx.miscellaneous & 0x2) { + where=&vga.mem.linear[0]; + } else { + vga.config.readhandler=&VGA_TEXT16_Read; + vga.config.writehandler=&VGA_TEXT16_Write; + where=0; + } break; case M_TANDY16: - MEM_SetupMapping(PAGE_COUNT(0xb8000),PAGE_COUNT(0x8000),&vga.mem.linear[vga.tandy.mem_bank << 14]); + where=&vga.mem.linear[vga.tandy.mem_bank << 14]; break; case M_CGA4: case M_CGA2: + where=&vga.mem.linear[0]; break; default: LOG_MSG("Unhandled vga mode %X",vga.mode); } + VGA_RANGES range; + switch ((vga.gfx.miscellaneous >> 2) & 3) { + case 0: + case 1: + range=VGA_RANGE_A000; + break; + case 2: + range=VGA_RANGE_B000; + break; + case 3: + range=VGA_RANGE_B800; + break; + } + MEM_SetupVGA(range,where); } +bool lfb_update; +static void VGA_DoUpdateLFB(void) { + lfb_update=false; + MEM_SetLFB(vga.s3.la_window << 4,sizeof(vga.mem.linear)/4096,&vga.mem.linear[0]); +} - +void VGA_StartUpdateLFB(void) { + if (!lfb_update) { + lfb_update=true; + PIC_AddEvent(VGA_DoUpdateLFB,2000); //2 milliseconds later + } +} void VGA_SetupMemory() { memset((void *)&vga.mem,0,512*1024*4); - /* Map linear frame buffer at 32 mb */ - MEM_SetupMapping(PAGE_COUNT(32*1024*1024),PAGE_COUNT(2*1024*1024),&vga.mem); + /* Setup linear window to some initial value */ + vga.s3.la_window=0xc000; + VGA_DoUpdateLFB(); }