diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 23e43b4d..2deb3d3d 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -27,15 +27,15 @@ #include "paging.h" #include "pic.h" -static Bit8u VGA_NormalReadHandler(PhysPt start) { +static Bitu VGA_NormalReadHandler(PhysPt start) { vga.latch.d=vga.mem.latched[start].d; switch (vga.config.read_mode) { case 0: - return(vga.latch.b[vga.config.read_map_select]); + return (vga.latch.b[vga.config.read_map_select]); case 1: VGA_Latch templatch; templatch.d=(vga.latch.d & FillTable[vga.config.color_dont_care]) ^ FillTable[vga.config.color_compare & vga.config.color_dont_care]; - return ~(templatch.b[0] | templatch.b[1] | templatch.b[2] | templatch.b[3]); + return (Bit8u)~(templatch.b[0] | templatch.b[1] | templatch.b[2] | templatch.b[3]); } return 0; } @@ -84,7 +84,7 @@ INLINE static Bit32u ModeOperation(Bit8u val) { } static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { - val=(val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate)); + val=((val >> vga.config.data_rotate) | (val << (8-vga.config.data_rotate))); Bit32u data=ModeOperation(val); /* Update video memory and the pixel buffer */ VGA_Latch pixels; @@ -116,7 +116,6 @@ static void VGA_GFX_16_WriteHandler(PhysPt start,Bit8u val) { static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { Bit32u data=ModeOperation(val); -// Bit32u data=ExpandTable[val]; VGA_Latch pixels; pixels.d=vga.mem.latched[start].d; pixels.d&=vga.config.full_not_map_mask; @@ -125,72 +124,223 @@ static void VGA_GFX_256U_WriteHandler(PhysPt start,Bit8u val) { vga.mem.latched[start+64*1024].d=pixels.d; } -static void VGA_TEXT16_Write(PhysPt start,Bit8u val) { - /* Check for page 2 being enabled for writing */ - if (vga.seq.map_mask & 0x4) { - vga.draw.font[start]=val; - } - //TODO Check for writes to other pages with normal text characters/attributes +/* Gonna assume that whoever maps vga memory, maps it on 32/64kb boundary */ + +#define LINK_MAX 64 +#define VGA_PAGES (128/4) +#define VGA_PAGE_A0 (0xA0000/4096) +#define VGA_PAGE_B0 (0xB0000/4096) +#define VGA_PAGE_B8 (0xB8000/4096) + +static struct { + Bitu used_links; + Bit32u links[LINK_MAX]; + Bit8u ram_area[VGA_PAGES*4096]; + Bitu map_base; +} vgapages; + + +void VGA_ClearPageLinks(void) { + PAGING_ClearTLBEntries(vgapages.used_links,vgapages.links); + vgapages.used_links=0; } -static Bit8u VGA_TEXT16_Read(PhysPt start) { - return vga.draw.font[start]; -} +class VGA_PageHandler : public PageHandler { + void AddPageLink(Bitu lin_page, Bitu phys_page) { + if (vgapages.used_links> 0)); + } + void writew(PhysPt addr,Bitu val) { + addr&=0xffff; + VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); + VGA_GFX_16_WriteHandler(addr+1,(Bit8u)(val >> 8)); + } + void writed(PhysPt addr,Bitu val) { + addr&=0xffff; + VGA_GFX_16_WriteHandler(addr+0,(Bit8u)(val >> 0)); + VGA_GFX_16_WriteHandler(addr+1,(Bit8u)(val >> 8)); + VGA_GFX_16_WriteHandler(addr+2,(Bit8u)(val >> 16)); + VGA_GFX_16_WriteHandler(addr+3,(Bit8u)(val >> 24)); + } +}; + +class VGA_256_PageHandler : public VGARead_PageHandler { +public: + VGA_256_PageHandler() { + flags=PFLAG_NOCODE; + } + void writeb(PhysPt addr,Bitu val) { + addr&=0xffff; + VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); + } + void writew(PhysPt addr,Bitu val) { + addr&=0xffff; + VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); + VGA_GFX_256U_WriteHandler(addr+1,(Bit8u)(val >> 8)); + } + void writed(PhysPt addr,Bitu val) { + addr&=0xffff; + VGA_GFX_256U_WriteHandler(addr+0,(Bit8u)(val >> 0)); + VGA_GFX_256U_WriteHandler(addr+1,(Bit8u)(val >> 8)); + VGA_GFX_256U_WriteHandler(addr+2,(Bit8u)(val >> 16)); + VGA_GFX_256U_WriteHandler(addr+3,(Bit8u)(val >> 24)); + } +}; + +class VGA_TEXT_PageHandler : public VGA_PageHandler { +public: + VGA_TEXT_PageHandler() { + flags=PFLAG_NOCODE; + } + Bitu readb(PhysPt addr) { + addr&=0x7fff; + return vga.draw.font[addr]; + } + void writeb(PhysPt addr,Bitu val){ + addr&=0x7fff; + if (vga.seq.map_mask & 0x4) { + vga.draw.font[addr]=(Bit8u)val; + } + } +}; + + +class VGA_RAM_PageHandler : public VGA_PageHandler { +public: + VGA_RAM_PageHandler() { + flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; + } + HostPt GetHostPt(Bitu phys_page) { + phys_page-=VGA_PAGE_A0; + return &vgapages.ram_area[phys_page*4096]; + } +}; + +class VGA_MAP_PageHandler : public VGA_PageHandler { +public: + VGA_MAP_PageHandler() { + flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; + } + HostPt GetHostPt(Bitu phys_page) { + phys_page-=vgapages.map_base; + return &vga.mem.linear[vga.s3.bank*64*1024+phys_page*4096]; + } +}; + +class VGA_TANDY_PageHandler : public VGA_PageHandler { +public: + VGA_TANDY_PageHandler() { + flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; + } + HostPt GetHostPt(Bitu phys_page) { + phys_page-=vgapages.map_base; + return &vga.mem.linear[(vga.tandy.mem_bank << 14)+(phys_page * 4096)]; + } +}; + + +static struct { + VGA_RAM_PageHandler hram; + VGA_MAP_PageHandler hmap; + VGA_TEXT_PageHandler htext; + VGA_TANDY_PageHandler htandy; + VGA_256_PageHandler h256; + VGA_16_PageHandler h16; +} vgaph; + void VGA_SetupHandlers(void) { - HostPt where; + PageHandler * range_handler; switch (vga.mode) { case M_LIN8: - where=&vga.mem.linear[vga.s3.bank*64*1024]; + range_handler=&vgaph.hmap; break; case M_VGA: if (vga.config.chained) { - where=&vga.mem.linear[vga.s3.bank*64*1024]; + range_handler=&vgaph.hmap; } else { - vga.config.readhandler=&VGA_NormalReadHandler, - vga.config.writehandler=&VGA_GFX_256U_WriteHandler; - where=0; + range_handler=&vgaph.h256; } break; case M_EGA16: - vga.config.readhandler=&VGA_NormalReadHandler, - vga.config.writehandler=&VGA_GFX_16_WriteHandler; - where=0; + range_handler=&vgaph.h16; break; + case M_TEXT2: case M_TEXT16: /* Check if we're not in odd/even mode */ if (vga.gfx.miscellaneous & 0x2) { - where=&vga.mem.linear[0]; + range_handler=&vgaph.hmap; } else { - vga.config.readhandler=&VGA_TEXT16_Read; - vga.config.writehandler=&VGA_TEXT16_Write; - where=0; + range_handler=&vgaph.htext; } break; case M_TANDY16: - where=&vga.mem.linear[vga.tandy.mem_bank << 14]; + range_handler=&vgaph.htandy; break; + case M_CGA16: case M_CGA4: case M_CGA2: - where=&vga.mem.linear[0]; + case M_HERC: + range_handler=&vgaph.hmap; 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; + vgapages.map_base=VGA_PAGE_A0; + MEM_SetPageHandler(VGA_PAGE_A0,16,range_handler); + MEM_SetPageHandler(VGA_PAGE_B0,16,&vgaph.hram); break; case 2: - range=VGA_RANGE_B000; + vgapages.map_base=VGA_PAGE_B0; + MEM_SetPageHandler(VGA_PAGE_B0,8,range_handler); + MEM_SetPageHandler(VGA_PAGE_A0,16,&vgaph.hram); + MEM_SetPageHandler(VGA_PAGE_B8,8,&vgaph.hram); break; case 3: - range=VGA_RANGE_B800; + vgapages.map_base=VGA_PAGE_B8; + MEM_SetPageHandler(VGA_PAGE_B8,8,range_handler); + MEM_SetPageHandler(VGA_PAGE_A0,16,&vgaph.hram); + MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.hram); break; } - MEM_SetupVGA(range,where); + VGA_ClearPageLinks(); } bool lfb_update; @@ -209,7 +359,5 @@ void VGA_StartUpdateLFB(void) { void VGA_SetupMemory() { memset((void *)&vga.mem,0,512*1024*4); - /* Setup linear window to some initial value */ - vga.s3.la_window=0xc000; - VGA_DoUpdateLFB(); + vgapages.used_links=0; }