From ae2dd7711e0468f1fb46349ad3485149702a92f7 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Thu, 10 Jun 2004 07:21:02 +0000 Subject: [PATCH] Slight change in vga to support the new rendering Added some hardware acceleration functionality Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1818 --- src/hardware/Makefile.am | 2 +- src/hardware/vga.cpp | 1 + src/hardware/vga_crtc.cpp | 76 +++++- src/hardware/vga_draw.cpp | 99 +++++-- src/hardware/vga_gfx.cpp | 2 +- src/hardware/vga_memory.cpp | 81 +++++- src/hardware/vga_xga.cpp | 530 ++++++++++++++++++++++++++++++++++++ 7 files changed, 761 insertions(+), 30 deletions(-) create mode 100644 src/hardware/vga_xga.cpp diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index 4259ac3c..c4201d96 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -7,7 +7,7 @@ noinst_LIBRARIES = libhardware.a libhardware_a_SOURCES = adlib.cpp dma.cpp gameblaster.cpp hardware.cpp iohandler.cpp joystick.cpp keyboard.cpp \ memory.cpp mixer.cpp pcspeaker.cpp pic.cpp sblaster.cpp tandy_sound.cpp timer.cpp \ vga.cpp vga_attr.cpp vga_crtc.cpp vga_dac.cpp vga_draw.cpp vga_gfx.cpp vga_other.cpp \ - vga_memory.cpp vga_misc.cpp vga_seq.cpp cmos.cpp disney.cpp \ + vga_memory.cpp vga_misc.cpp vga_seq.cpp vga_xga.cpp cmos.cpp disney.cpp \ gus.cpp mpu401.cpp serialport.cpp softmodem.cpp ipx.cpp ipxserver.cpp diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 536af5e5..706d89a2 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -144,6 +144,7 @@ void VGA_Init(Section* sec) { VGA_SetupSEQ(); VGA_SetupAttr(); VGA_SetupOther(); + VGA_SetupXGA(); VGA_SetClock(0,CLK_25); VGA_SetClock(1,CLK_28); /* Generate tables */ diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 2becbde4..29dceccf 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -24,6 +24,13 @@ #define crtc(blah) vga.crtc.blah + +void VGA_MapMMIO(void); +void VGA_UnmapMMIO(void); + +void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen); +Bitu DEBUG_EnableDebugger(void); + void write_p3d4_vga(Bitu port,Bitu val,Bitu iolen) { crtc(index)=val; } @@ -325,6 +332,9 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { case 0x39: /* CR39 Register Lock 2 */ vga.s3.reg_lock2=val; break; + case 0x40: /* CR40 System Config */ + vga.s3.reg_40 = val; + break; case 0x43: /* CR43 Extended Mode */ vga.s3.reg_43=val & ~0x4; if (((val & 0x4) ^ (vga.config.scan_len >> 6)) & 0x4) { @@ -338,6 +348,43 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { (3d4h index 13h). (801/5,928) Only active if 3d4h index 51h bits 4-5 are 0 */ + case 0x45: /* Hardware cursor mode */ + vga.s3.hgc.curmode = val; + break; + case 0x46: + vga.s3.hgc.originx = (vga.s3.hgc.originx & 0x00ff) | (val << 8); + break; + case 0x47: /* HGC orgX */ + vga.s3.hgc.originx = (vga.s3.hgc.originx & 0xff00) | val; + break; + case 0x48: + vga.s3.hgc.originy = (vga.s3.hgc.originy & 0x00ff) | (val << 8); + break; + case 0x49: /* HGC orgY */ + vga.s3.hgc.originy = (vga.s3.hgc.originy & 0xff00) | val; + break; + case 0x4A: /* HGC foreground stack */ + if (vga.s3.hgc.fstackpos > 2) vga.s3.hgc.fstackpos = 0; + vga.s3.hgc.forestack[vga.s3.hgc.fstackpos] = val; + vga.s3.hgc.fstackpos++; + break; + case 0x4B: /* HGC background stack */ + if (vga.s3.hgc.bstackpos > 2) vga.s3.hgc.bstackpos = 0; + vga.s3.hgc.backstack[vga.s3.hgc.bstackpos] = val; + vga.s3.hgc.bstackpos++; + break; + case 0x4c: /* HGC start address high byte*/ + vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | ((val & 0xff) << 8); + break; + case 0x4d: /* HGC start address low byte*/ + vga.s3.hgc.startaddr = vga.s3.hgc.startaddr | (val & 0xff); + break; + case 0x4e: /* HGC pattern start X */ + vga.s3.hgc.posx = val; + break; + case 0x4f: /* HGC pattern start X */ + vga.s3.hgc.posy = val; + break; case 0x51: /* Extended System Control 2 */ vga.s3.reg_51=val & 0xc0; //Only store bits 6,7 //TODO Display start @@ -374,6 +421,18 @@ void write_p3d5_vga(Bitu port,Bitu val,Bitu iolen) { 7 (not 864/964) Enable EPROM Write. If set enables flash memory write control to the BIOS ROM address */ + case 0x53: + if((val & 0x10) != (vga.s3.ext_mem_ctrl & 0x10)) { + /* Map or unmap MMIO */ + if ((val & 0x10) != 0) { + LOG_MSG("VGA: Mapping Memory Mapped I/O to 0xA0000"); + VGA_MapMMIO(); + } else { + VGA_UnmapMMIO(); + } + } + vga.s3.ext_mem_ctrl = val; + break; case 0x55: /* Extended Video DAC Control */ vga.s3.reg_55=val; break; @@ -572,7 +631,7 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen) { return 0x11; //Trio 64 id case 0x2f: /* Revision */ - return 0x80; + return 0x00; case 0x30: /* CR30 Chip ID/REV register */ return 0xe0; //Trio+ dual byte // Trio32/64 has 0xe0. extended @@ -582,7 +641,8 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen) { case 0x35: /* CR35 CRT Register Lock */ return vga.s3.reg_35|(vga.s3.bank & 0xf); case 0x36: /* CR36 Reset State Read 1 */ - return 0x8f; + //return 0x8f; + return 0x8e; /* PCI version */ //2 Mb PCI and some bios settings case 0x37: /* Reset state read 2 */ return 0x2b; @@ -590,17 +650,29 @@ Bitu read_p3d5_vga(Bitu port,Bitu iolen) { return vga.s3.reg_lock1; case 0x39: /* CR39 Register Lock 2 */ return vga.s3.reg_lock2; + case 0x40: /* CR40 system config */ + return vga.s3.reg_40; case 0x43: /* CR43 Extended Mode */ return vga.s3.reg_43|((vga.config.scan_len>>6)&0x4); + case 0x45: /* Hardware cursor mode */ + vga.s3.hgc.bstackpos = 0; + vga.s3.hgc.fstackpos = 0; + return vga.s3.hgc.curmode; case 0x51: /* Extended System Control 2 */ return ((vga.config.display_start >> 16) & 3 ) | ((vga.s3.bank & 0x30) >> 2) | ((vga.config.scan_len & 0x300) >> 4) | vga.s3.reg_51; + case 0x53: + return vga.s3.ext_mem_ctrl; case 0x55: /* Extended Video DAC Control */ return vga.s3.reg_55; case 0x58: /* Linear Address Window Control */ return vga.s3.reg_58; + case 0x59: /* Linear Address Window Position High */ + return (vga.s3.la_window >> 8); + case 0x5a: /* Linear Address Window Position Low */ + return (vga.s3.la_window & 0xff); case 0x5D: /* Extended Horizontal Overflow */ return vga.s3.ex_hor_overflow; case 0x5e: /* Extended Vertical Overflow */ diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 5625f626..8d1c9036 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -29,25 +29,26 @@ typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart,Bitu panning,Bitu line); static VGA_Line_Handler VGA_DrawLine; +static Bit8u TempLine[1280]; static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { - line*=8*1024;Bit32u * draw=(Bit32u *)RENDER_TempLine; + line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=vga.draw.blocks;x>0;x--) { Bitu val=vga.mem.linear[vidstart+line];vidstart=(vidstart+1)&0x1fff; *draw++=CGA_2_Table[val >> 4]; *draw++=CGA_2_Table[val & 0xf]; } - return RENDER_TempLine; + return TempLine; } static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { - line*=8*1024;Bit32u * draw=(Bit32u *)RENDER_TempLine; + line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; for (Bitu x=0;x (vga.s3.hgc.originy + 63))) { + return VGA_Draw_VGA_Line(vidstart, panning, line); + } else { + memcpy(TempLine, VGA_Draw_VGA_Line(vidstart, panning, line), 640); + /* Draw mouse cursor */ + Bits moff = ((Bits)lineat - (Bits)vga.s3.hgc.originy) + (Bits)vga.s3.hgc.posy; + if(moff>63) moff=moff-64; + if(moff<0) moff+=64; + Bitu xat = vga.s3.hgc.originx; + Bitu m, mat; + mat = vga.s3.hgc.posx; + + for(m=0;m<64;m++) { + switch(vga.s3.hgc.mc[moff][mat]) { + case 0: + TempLine[xat] = vga.s3.hgc.backstack[0]; + break; + case 1: + TempLine[xat] = vga.s3.hgc.forestack[0]; + break; + case 2: + //Transparent + break; + case 3: + break; + } + xat++; + mat++; + if(mat>63) mat=0; + } + return TempLine; + } + } else { + /* HW Mouse not enabled, use the tried and true call */ + return VGA_Draw_VGA_Line(vidstart, panning, line); + } +} + + static Bit32u FontMask[2]={0xffffffff,0x0}; static Bit8u * VGA_TEXT_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { - Bit32u * draw=(Bit32u *)RENDER_TempLine; + Bit32u * draw=(Bit32u *)TempLine; Bit8u * vidmem=&vga.mem.linear[vidstart]; for (Bitu cx=0;cx=0 && font_addrvga.draw.cursor.eline) goto skip_cursor; - draw=(Bit32u *)&RENDER_TempLine[font_addr*8]; + draw=(Bit32u *)&TempLine[font_addr*8]; Bit32u att=TXT_FG_Table[vga.mem.linear[vga.config.cursor_start*2+1]&0xf]; *draw++=att;*draw++=att; } skip_cursor: - return RENDER_TempLine; + return TempLine; } static void VGA_VerticalDisplayEnd(Bitu val) { @@ -128,11 +171,11 @@ static void VGA_HorizontalTimer(void) { } -static void VGA_DrawPart(void) { +static void VGA_DrawPart(Bitu lines) { Bitu subline=0;Bitu vidofs=vga.config.real_start; Bit8u * draw=0; - while (vga.draw.lines_left) { - vga.draw.lines_left--; + while (lines--) { + vga.draw.lines_done++; Bit8u * data=VGA_DrawLine(vga.draw.address,vga.draw.panning,vga.draw.address_line); RENDER_DrawLine(data); vga.draw.address_line++; @@ -140,14 +183,15 @@ static void VGA_DrawPart(void) { vga.draw.address_line=0; vga.draw.address+=vga.draw.address_add; } - if (vga.draw.split_line==vga.draw.lines_left) { + if (vga.draw.split_line==vga.draw.lines_done) { vga.draw.address=0;vga.draw.panning=0; vga.draw.address_line=0; } } - RENDER_EndUpdate(); -// vga.draw.parts_left--; -// if (vga.draw.parts_left) PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts); + vga.draw.parts_left--; + if (vga.draw.parts_left) { + PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts,vga.draw.parts_lines); + } else RENDER_EndUpdate(); } void VGA_SetBlinking(Bitu enabled) { @@ -169,11 +213,11 @@ static void VGA_VerticalTimer(Bitu val) { vga.config.retrace=false; PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); PIC_AddEvent(VGA_VerticalDisplayEnd,vga.draw.micro.vend); - vga.draw.parts_left=4; - vga.draw.lines_left=vga.draw.lines_total; + vga.draw.parts_left=vga.draw.parts_total; + vga.draw.lines_done=0; vga.draw.address=vga.config.real_start; vga.draw.address_line=vga.config.hlines_skip; - vga.draw.split_line=vga.draw.lines_total-(vga.config.line_compare/vga.draw.lines_scaled); + vga.draw.split_line=(vga.config.line_compare/vga.draw.lines_scaled); vga.draw.panning=vga.config.pel_panning; switch (vga.mode) { case M_TEXT: @@ -189,7 +233,7 @@ static void VGA_VerticalTimer(Bitu val) { break; } if (RENDER_StartUpdate()) { - VGA_DrawPart(); + PIC_AddEvent(VGA_DrawPart,vga.draw.micro.parts,vga.draw.parts_lines); } } @@ -310,7 +354,6 @@ void VGA_SetupDrawing(Bitu val) { Bitu width,height; Bitu scalew=1; Bitu scaleh=1; - width=hdispend; height=vdispend; vga.draw.double_scan=false; @@ -329,7 +372,12 @@ void VGA_SetupDrawing(Bitu val) { vga.draw.lines_scaled=scaleh; vga.draw.address_line_total=1; height/=scaleh;width<<=3; - VGA_DrawLine=VGA_Draw_VGA_Line; + /* Use HW mouse cursor drawer if enabled */ + if(vga.s3.hgc.curmode & 0x1) { + VGA_DrawLine=VGA_Draw_VGA_Line_HWMouse; + } else { + VGA_DrawLine=VGA_Draw_VGA_Line; + } break; case M_EGA16: scaleh*=vga.draw.font_height; @@ -419,6 +467,7 @@ void VGA_SetupDrawing(Bitu val) { }; VGA_CheckScanLength(); vga.draw.lines_total=height; + vga.draw.parts_lines=vga.draw.lines_total/vga.draw.parts_total; if (( width != vga.draw.width) || (height != vga.draw.height)) { PIC_RemoveEvents(VGA_VerticalTimer); PIC_RemoveEvents(VGA_VerticalDisplayEnd); @@ -428,7 +477,7 @@ void VGA_SetupDrawing(Bitu val) { LOG(LOG_VGA,LOG_NORMAL)("Width %d, Height %d, fps %f",width,height,fps); LOG(LOG_VGA,LOG_NORMAL)("Scalew %d, Scaleh %d aspect %f",scalew,scaleh,aspect_ratio); - RENDER_SetSize(width,height,8,aspect_ratio,scalew,scaleh); + RENDER_SetSize(width,height,8,aspect_ratio,scalew>1,scaleh>1); PIC_AddEvent(VGA_VerticalTimer,vga.draw.micro.vtotal); } }; diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 1e3415ae..cddd3ea9 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -93,7 +93,7 @@ static void write_p3cf(Bitu port,Bitu val,Bitu iolen) { break; case 5: /* Mode Register */ if ((gfx(mode) ^ val) & 0xf0) { - gfx(mode)=val; + gfx(mode)=val; VGA_DetermineMode(); } else gfx(mode)=val; vga.config.write_mode=val & 3; diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index b26679b8..df8d4b41 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -26,6 +26,9 @@ #include "vga.h" #include "paging.h" #include "pic.h" +#include "inout.h" + +void VGA_MapMMIO(void); static Bitu VGA_NormalReadHandler(PhysPt start) { vga.latch.d=vga.mem.latched[start].d; @@ -233,6 +236,7 @@ public: } }; + class VGA_MAP_PageHandler : public PageHandler { public: VGA_MAP_PageHandler() { @@ -244,6 +248,66 @@ public: } }; +class VGA_MMIO_PageHandler : public PageHandler { +public: + Bit16u regmem[16384]; + + VGA_MMIO_PageHandler() { + flags=PFLAG_NOCODE; + //memset(®mem[0], 0, sizeof(regmem)); + } + void writeb(PhysPt addr,Bitu val) { + Bitu port = addr & 0xffff; + if(port >= 0x82E8) IO_WriteB(port, val); + LOG_MSG("MMIO: Write byte to %x with %x", addr, val); + } + void writew(PhysPt addr,Bitu val) { + Bitu port = addr & 0xffff; + if(port >= 0x82E8) IO_WriteW(port, val); + if(port == 0x8118) IO_WriteW(0x9ae8, val); + if(port <= 0x0020) { + IO_WriteW(0xe2e8, val); + } + + LOG_MSG("MMIO: Write word to %x with %x", addr, val); + } + void writed(PhysPt addr,Bitu val) { + Bitu port = addr & 0xffff; + if(port >= 0x82E8) IO_WriteD(port, val); + if(port == 0x8100) { + IO_WriteW(0x86e8, (val >> 16)); + IO_WriteW(0x82e8, (val & 0xffff)); + } + if(port == 0x8148) { + IO_WriteW(0x96e8, (val >> 16)); + IO_WriteW(0xbee8, (val & 0xffff)); + } + if(port <= 0x0020) { + IO_WriteW(0xe2e8, (val & 0xffff)); + IO_WriteW(0xe2e8, (val >> 16)); + } + + LOG_MSG("MMIO: Write dword to %x with %x", addr, val); + } + + Bitu readb(PhysPt addr) { + LOG_MSG("MMIO: Read byte from %x", addr); + + return 0x00; + } + Bitu readw(PhysPt addr) { + Bitu port = addr & 0xffff; + if(port >= 0x82E8) return IO_ReadW(port); + LOG_MSG("MMIO: Read word from %x", addr); + return 0x00; + } + Bitu readd(PhysPt addr) { + LOG_MSG("MMIO: Read dword from %x", addr); + return 0x00; + } + +}; + class VGA_TANDY_PageHandler : public PageHandler { public: VGA_TANDY_PageHandler() { @@ -262,13 +326,14 @@ public: }; -static struct { +static struct vg { VGA_RAM_PageHandler hram; VGA_MAP_PageHandler hmap; VGA_TEXT_PageHandler htext; VGA_TANDY_PageHandler htandy; VGA_256_PageHandler h256; VGA_16_PageHandler h16; + VGA_MMIO_PageHandler mmio; } vgaph; @@ -338,6 +403,9 @@ range_b800: MEM_SetPageHandler(VGA_PAGE_B0,8,&vgaph.hram); break; } + + if(((vga.s3.ext_mem_ctrl & 0x10) != 0x00) && (vga.mode == M_LIN8)) MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); + PAGING_ClearTLB(); } @@ -346,6 +414,7 @@ bool lfb_update; static void VGA_DoUpdateLFB(Bitu val) { lfb_update=false; MEM_SetLFB(vga.s3.la_window << 4 ,sizeof(vga.mem.linear)/4096,&vga.mem.linear[0]); + LOG_MSG("LIN: Reconfiguing linear page address"); } void VGA_StartUpdateLFB(void) { @@ -355,6 +424,16 @@ void VGA_StartUpdateLFB(void) { } } +void VGA_MapMMIO(void) { + MEM_SetPageHandler(VGA_PAGE_A0, 16, &vgaph.mmio); + +} + +void VGA_UnmapMMIO(void) { + //MEM_SetPageHandler(VGA_PAGE_A0, &ram_page_handler); +} + + void VGA_SetupMemory() { memset((void *)&vga.mem,0,512*1024*4); } diff --git a/src/hardware/vga_xga.cpp b/src/hardware/vga_xga.cpp new file mode 100644 index 00000000..6440b500 --- /dev/null +++ b/src/hardware/vga_xga.cpp @@ -0,0 +1,530 @@ +/* + * Copyright (C) 2002-2004 The DOSBox Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include "dosbox.h" +#include "inout.h" +#include "vga.h" +#include + +struct XGAStatus { + struct scissorreg { + Bit16u x1, y1, x2, y2; + } scissors; + + Bit32u readmask; + Bit32u writemask; + + Bit32u forecolor; + Bit32u backcolor; + + Bit16u foremix; + + Bit16u curx, cury; + Bit16u destx, desty; + + Bit16u MIPcount; + Bit16u MAPcount; + + Bit16u pix_cntl; + Bit16u read_sel; + + struct XGA_WaitCmd { + bool wait; + Bit16u cmd; + Bit16u curx, cury; + Bit16u x1, y1, x2, y2; + } waitcmd; + +} xga; + +Bit8u tmpvram[2048 * 1024]; + +void XGA_Write_Multifunc(Bitu val, Bitu len) { + Bitu regselect = val >> 12; + Bitu dataval = val & 0xfff; + switch(regselect) { + case 0: + xga.MIPcount = dataval; + break; + case 1: + xga.scissors.y1 = dataval; + break; + case 2: + xga.scissors.x1 = dataval; + break; + case 3: + xga.scissors.y2 = dataval; + break; + case 4: + xga.scissors.x2 = dataval; + break; + case 0xa: + xga.pix_cntl = dataval; + break; + case 0xf: + xga.read_sel = dataval; + break; + default: + LOG_MSG("XGA: Unhandled multifunction command %x", regselect); + break; + } +} + +void XGA_DrawPoint8(Bitu x, Bitu y, Bit8u c) { + Bit32u memaddr = (y * 640) + x; + vga.mem.linear[memaddr] = c; + +} + +Bit8u XGA_GetPoint8(Bitu x, Bitu y) { + Bit32u memaddr = (y * 640) + x; + return vga.mem.linear[memaddr]; + + +} + +void XGA_DrawPoint16(Bitu x, Bitu y, Bit16u c) { + Bit16u *memptr; + Bit32u memaddr = (y * 640) + x; + memptr = (Bit16u *)&vga.mem.linear[memaddr]; + *memptr = c; +} + +void XGA_DrawRectangle(Bitu x1, Bitu y1, Bitu x2, Bitu y2) { + Bit32u xat, yat; + Bit32u xmass, xmod, xdist; + Bit32u *memptr; + Bit8u *smallptr; + Bit32u c; + Bit8u smallc; + + xdist = (x2 -x1); + xmass = (xdist) & 0xfffffffb; + xmod = (xdist) & 0x3; + + smallc = (xga.forecolor & 0xff); + c = (smallc) | ((smallc) << 8) | ((smallc) << 16) | ((smallc) << 24); + + for(yat=y1;yat<=y2;yat++) { + Bit32u memaddr = (yat * (Bit32u)640) + x1; + smallptr = &vga.mem.linear[memaddr]; + for(xat=0;xat xga.waitcmd.x2) { + xga.waitcmd.curx = xga.waitcmd.x1; + xga.waitcmd.cury++; + newline = true; + if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false; + } + return newline; +} + +void XGA_DrawWait(Bitu val, Bitu len) { + if(!xga.waitcmd.wait) return; + Bitu mixmode = (xga.pix_cntl >> 6) & 0x3; + + switch(xga.waitcmd.cmd) { + case 2: /* Rectangle */ + if(mixmode == 0) { /* FOREMIX always used */ + switch(len) { + case 1: + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, val); + break; + case 2: + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, (val & 0xff)); + XGA_CheckX(); + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, (val >> 8)); + break; + case 4: + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, (val & 0xff)); + XGA_CheckX(); + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, ((val >> 8) & 0xff)); + XGA_CheckX(); + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, ((val >> 16) & 0xff)); + XGA_CheckX(); + XGA_DrawPoint8(xga.waitcmd.curx++, xga.waitcmd.cury, ((val >> 24) & 0xff)); + break; + } + XGA_CheckX(); + } + if(mixmode == 2) { /* Data from PIX_TRANS selects the mix */ + Bitu bitcount; + int i; + switch(len) { + case 1: + bitcount = 8; + break; + case 2: + bitcount = 16; + val = ((val & 0xff) << 8) | ((val >> 8) & 0xff); + break; + case 4: + bitcount = 32; + break; + } + + + Bits bitneed = ((Bits)xga.waitcmd.x2 - (Bits)xga.waitcmd.x1) + 1; + xga.waitcmd.curx = xga.waitcmd.x1; + i = 15; + for(;bitneed>=0;--bitneed) { + Bitu bitval = (val >> i) & 0x1; + //XGA_DrawPoint8(xga.waitcmd.curx, xga.waitcmd.cury, i); + if(bitval != 0) XGA_DrawPoint8(xga.waitcmd.curx, xga.waitcmd.cury, xga.forecolor); + --i; + xga.waitcmd.curx++; + } + xga.waitcmd.cury++; + + + if(xga.waitcmd.cury > xga.waitcmd.y2) xga.waitcmd.wait = false; + } + break; + default: + LOG_MSG("XGA: Unhandled draw command %x", xga.waitcmd.cmd); + break; + } + +} + +void XGA_BlitRect(Bitu val) { + Bit32u xat, yat; + Bit32u xmass, xmod, xdist, memrec; + Bit8u *srcptr; + Bit8u *destptr; + Bit8u *destline; + Bit8u *srcline; + + Bit32u c; + Bit8u smallc; + Bit8u tmpclr; + bool incx = false; + bool incy = false; + + if((val >> 5) != 0) incx = true; + if((val >> 7) != 0) incy = true; + + xdist = xga.MAPcount; + + smallc = (xga.forecolor & 0xff); + memrec = 0; + Bit32u srcaddr = (xga.cury * (Bit32u)640) + xga.curx; + Bit32u destaddr = (xga.desty * (Bit32u)640) + xga.destx; + + srcptr = &vga.mem.linear[srcaddr]; + destptr = &vga.mem.linear[destaddr]; + + /* Copy source to video ram */ + for(yat=0;yat<=xga.MIPcount ;yat++) { + srcline = srcptr; + destline = destptr; + for(xat=0;xat7) addx=0; + } + addy++; + if(addy>7) addy=0; + } + +} + +void XGA_DrawCmd(Bitu val, Bitu len) { + Bit16u cmd; + cmd = val >> 13; + LOG_MSG("XGA: Draw command %x", cmd); + switch(cmd) { + case 2: /* Rectangle fill */ + if((val & 0x100) == 0) { + xga.waitcmd.wait = false; + XGA_DrawRectangle(xga.curx, xga.cury, xga.curx + xga.MAPcount, xga.cury + xga.MIPcount); + } else { + xga.waitcmd.wait = true; + xga.waitcmd.curx = xga.curx; + xga.waitcmd.cury = xga.cury; + xga.waitcmd.x1 = xga.curx; + xga.waitcmd.y1 = xga.cury; + xga.waitcmd.x2 = xga.curx + xga.MAPcount; + xga.waitcmd.y2 = xga.cury + xga.MIPcount; + xga.waitcmd.cmd = 2; + LOG_MSG("XGA: Draw wait rect (%d, %d)-(%d, %d)", xga.waitcmd.x1, xga.waitcmd.y1, xga.waitcmd.x2, xga.waitcmd.y2); + } + break; + case 6: /* BitBLT */ + XGA_BlitRect(val); + break; + case 7: /* Pattern fill */ + XGA_DrawPattern(); + LOG_MSG("XGA: Pattern fill (%d, %d)-(%d, %d) to (%d, %d)-(%d, %d)", xga.curx, xga.cury, xga.curx + 8, xga.cury + 8, xga.destx, xga.desty, xga.destx + xga.MAPcount, xga.desty + xga.MIPcount); + break; + default: + LOG_MSG("XGA: Unhandled draw command %x", cmd); + break; + + } +} + +void XGA_Write(Bitu port, Bitu val, Bitu len) { + switch(port) { + case 0x96e8: + xga.MAPcount = val; + break; + case 0x9ae8: + XGA_DrawCmd(val, len); + break; + case 0xa2e8: + xga.backcolor = val; + break; + case 0xa6e8: + xga.forecolor = val; + break; + case 0xaae8: + xga.writemask = val; + break; + case 0xaee8: + xga.readmask = val; + break; + case 0x82e8: + xga.cury = val; + break; + case 0x86e8: + xga.curx = val; + break; + case 0x8ae8: + xga.desty = val; + break; + case 0x8ee8: + xga.destx = val; + break; + case 0xbae8: + xga.foremix = val; + break; + case 0xbee8: + XGA_Write_Multifunc(val, len); + break; + case 0xe2e8: + XGA_DrawWait(val, len); + break; + default: + LOG_MSG("XGA: Wrote to port %x with %x, len %x", port, val, len); + break; + } + +} + +Bitu XGA_Read(Bitu port, Bitu len) { + LOG_MSG("XGA: Read from port %x, len %x", port, len); + switch(port) { + case 0x9ae8: + return 0x0; + case 0x9ae9: + if(xga.waitcmd.wait) { + return 0x4; + } else { + return 0x0; + } + case 0xa2e8: + return xga.backcolor; + default: + LOG_MSG("XGA: Read from port %x, len %x", port, len); + return 0x0; + } +} + +void XGA_UpdateHWC(void) { + Bitu mouseaddr = (Bit32u)vga.s3.hgc.startaddr * (Bit32u)1024; + Bits x, y, t, m, xat, r, z; + x = vga.s3.hgc.originx; + y = vga.s3.hgc.originy; + Bit16u bitsA, bitsB; + Bit16u ab, bb; + + /* Read mouse cursor */ + for(t=0;t<64;t++) { + xat = 0; + for(m=0;m<4;m++) { + bitsA = *(Bit16u *)&vga.mem.linear[mouseaddr]; + mouseaddr+=2; + bitsB = *(Bit16u *)&vga.mem.linear[mouseaddr]; + mouseaddr+=2; + z = 7; + for(r=15;r>=0;--r) { + vga.s3.hgc.mc[t][xat] = (((bitsA >> z) & 0x1) << 1) | ((bitsB >> z) & 0x1); + xat++; + --z; + if(z<0) z=15; + } + } + } + +} + +void VGA_SetupXGA(void) { + if (machine!=MCH_VGA) return; + + memset(&xga, 0, sizeof(XGAStatus)); + + IO_RegisterWriteHandler(0x42e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x42e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x46e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x4ae8,&XGA_Write,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x82e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x82e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x82e9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x82e9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x86e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x86e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x86e9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x86e9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x8ae8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x8ae8,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x8ee8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x8ee8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x8ee9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x8ee9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x92e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x92e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x92e9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x92e9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x96e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x96e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x96e9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x96e9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x9ae8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x9ae8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x9ae9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x9ae9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0x9ee8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x9ee8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0x9ee9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0x9ee9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xa2e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xa2e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xa6e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xa6e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xa6e9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xa6e9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xaae8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xaae8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xaae9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xaae9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xaee8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xaee8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xaee9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xaee9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xb2e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xb2e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xb2e9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xb2e9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xb6e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xb6e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xbee8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xbee8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xbee9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xbee9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xbae8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xbae8,&XGA_Read,IO_MB | IO_MW | IO_MD); + IO_RegisterWriteHandler(0xbae9,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xbae9,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xe2e8,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xe2e8,&XGA_Read,IO_MB | IO_MW | IO_MD); + + IO_RegisterWriteHandler(0xe2ea,&XGA_Write,IO_MB | IO_MW | IO_MD); + IO_RegisterReadHandler(0xe2ea,&XGA_Read,IO_MB | IO_MW | IO_MD); + + + +} +