From f7c4b4699159a66faa0275aedde185d1fa8b8317 Mon Sep 17 00:00:00 2001 From: Sjoerd van der Berg Date: Sun, 29 Feb 2004 22:18:24 +0000 Subject: [PATCH] Added MC6845 display controller support for hercules,cga,tandy machine modes. Added cga,tandy,text modes. Added some new tandy modes. Added better tandy register support. Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@1691 --- include/vga.h | 38 ++- src/hardware/Makefile.am | 2 +- src/hardware/vga.cpp | 56 ++++- src/hardware/vga_attr.cpp | 19 +- src/hardware/vga_crtc.cpp | 11 +- src/hardware/vga_dac.cpp | 36 ++- src/hardware/vga_draw.cpp | 283 +++++++++++++--------- src/hardware/vga_gfx.cpp | 27 ++- src/hardware/vga_memory.cpp | 47 ++-- src/hardware/vga_misc.cpp | 270 ++------------------- src/hardware/vga_other.cpp | 308 ++++++++++++++++++++++++ src/hardware/vga_seq.cpp | 11 +- src/ints/int10.cpp | 2 +- src/ints/int10.h | 3 +- src/ints/int10_char.cpp | 19 +- src/ints/int10_memory.cpp | 6 +- src/ints/int10_misc.cpp | 4 +- src/ints/int10_modes.cpp | 464 +++++++++++++++++++++--------------- src/ints/int10_vesa.cpp | 14 +- 19 files changed, 953 insertions(+), 667 deletions(-) create mode 100644 src/hardware/vga_other.cpp diff --git a/include/vga.h b/include/vga.h index 9046683a..ad35b712 100644 --- a/include/vga.h +++ b/include/vga.h @@ -23,13 +23,13 @@ #include "dosbox.h" enum VGAModes { - M_TEXT2,M_TEXT16, - M_HERC, - M_CGA2,M_CGA4,M_CGA16, - M_TANDY16, - M_EGA2,M_EGA4,M_EGA16, + M_TEXT, + M_HERC_GFX,M_HERC_TEXT, + M_CGA2,M_CGA4, + M_EGA16, M_VGA, M_LIN8, + M_CGA16,M_TANDY2,M_TANDY4,M_TANDY16,M_TANDY_TEXT, M_ERROR, }; @@ -161,18 +161,28 @@ typedef struct { } VGA_HERC; typedef struct { - Bit8u mode_control; - Bit8u color_select; -} VGA_CGA; + Bit8u index; + Bit8u htotal; + Bit8u hdend; + Bit8u hsyncp; + Bit8u hsyncw; + Bit8u vtotal; + Bit8u vdend; + Bit8u vadjust; + Bit8u vsyncp; + Bit8u vsyncw; + Bit8u max_scanline; +} VGA_OTHER; typedef struct { + Bit8u mode_control; + Bit8u color_select; Bit8u mem_bank; Bit8u disp_bank; Bit8u reg_index; - Bit8u mode_control1; + Bit8u gfx_control; Bit8u palette_mask; Bit8u border_color; - Bit8u mode_control2; } VGA_TANDY; typedef struct { @@ -255,7 +265,6 @@ typedef struct { Bit8u read_index; Bitu first_changed; RGBEntry rgb[0x100]; - Bit8u attr[16]; } VGA_Dac; union VGA_Latch { @@ -284,8 +293,8 @@ typedef struct { VGA_Latch latch; VGA_S3 s3; VGA_HERC herc; - VGA_CGA cga; VGA_TANDY tandy; + VGA_OTHER other; VGA_Memory mem; } VGA_Type; @@ -293,6 +302,7 @@ typedef struct { /* Functions for different resolutions */ void VGA_SetMode(VGAModes mode); +void VGA_DetermineMode(void); void VGA_SetupHandlers(void); void VGA_StartResize(void); void VGA_SetupDrawing(Bitu val); @@ -300,6 +310,7 @@ void VGA_CheckScanLength(void); /* Some DAC/Attribute functions */ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal); +void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue); void VGA_ATTR_SetPalette(Bit8u index,Bit8u val); /* The VGA Subfunction startups */ @@ -310,6 +321,7 @@ void VGA_SetupCRTC(void); void VGA_SetupMisc(void); void VGA_SetupGFX(void); void VGA_SetupSEQ(void); +void VGA_SetupOther(void); /* Some Support Functions */ void VGA_SetClock(Bitu which,Bitu target); @@ -317,6 +329,8 @@ void VGA_DACSetEntirePalette(void); void VGA_StartRetrace(void); void VGA_StartUpdateLFB(void); void VGA_SetBlinking(Bitu enabled); +void VGA_SetCGA2Table(Bit8u val0,Bit8u val1); +void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3); extern VGA_Type vga; diff --git a/src/hardware/Makefile.am b/src/hardware/Makefile.am index ccc692d2..6335846b 100644 --- a/src/hardware/Makefile.am +++ b/src/hardware/Makefile.am @@ -6,7 +6,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.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 font-switch.h ega-switch.h 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 3b9c3255..bf06e9e3 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -48,6 +48,20 @@ void VGA_SetMode(VGAModes mode) { VGA_StartResize(); } +void VGA_DetermineMode(void) { + /* Test for graphics or alphanumeric mode */ + if (vga.attr.mode_control & 1) { + if (!(vga.crtc.mode_control & 0x1)) { + if (vga.gfx.mode & 0x20) VGA_SetMode(M_CGA4); + else VGA_SetMode(M_CGA2); + } else if (vga.attr.mode_control & 0x40) { + VGA_SetMode(M_VGA); + } else VGA_SetMode(M_EGA16); + } else { + VGA_SetMode(M_TEXT); + } +} + void VGA_StartResize(void) { if (!vga.draw.resizing) { vga.draw.resizing=true; @@ -88,34 +102,56 @@ void VGA_SetClock(Bitu which,Bitu target) { VGA_StartResize(); } +void VGA_SetCGA2Table(Bit8u val0,Bit8u val1) { + Bit8u total[2]={ val0,val1}; + for (Bitu i=0;i<16;i++) { + CGA_2_Table[i]= +#ifdef WORDS_BIGENDIAN + (total[(i >> 0) & 1] << 0 ) | (total[(i >> 1) & 1] << 8 ) | + (total[(i >> 2) & 1] << 16 ) | (total[(i >> 3) & 1] << 24 ); +#else + (total[(i >> 3) & 1] << 0 ) | (total[(i >> 2) & 1] << 8 ) | + (total[(i >> 1) & 1] << 16 ) | (total[(i >> 0) & 1] << 24 ); +#endif + } +} + +void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3) { + Bit8u total[4]={ val0,val1,val2,val3}; + for (Bitu i=0;i<256;i++) { + CGA_4_Table[i]= +#ifdef WORDS_BIGENDIAN + (total[(i >> 0) & 3] << 0 ) | (total[(i >> 2) & 3] << 8 ) | + (total[(i >> 4) & 3] << 16 ) | (total[(i >> 6) & 3] << 24 ); +#else + (total[(i >> 6) & 3] << 0 ) | (total[(i >> 4) & 3] << 8 ) | + (total[(i >> 2) & 3] << 16 ) | (total[(i >> 0) & 3] << 24 ); +#endif + } +} void VGA_Init(Section* sec) { vga.draw.resizing=false; + vga.mode=M_ERROR; //For first init VGA_SetupMemory(); VGA_SetupMisc(); VGA_SetupDAC(); VGA_SetupGFX(); VGA_SetupSEQ(); VGA_SetupAttr(); + VGA_SetupOther(); VGA_SetClock(0,CLK_25); VGA_SetClock(1,CLK_28); /* Generate tables */ + VGA_SetCGA2Table(0,1); + VGA_SetCGA4Table(0,1,2,3); Bitu i,j; for (i=0;i<256;i++) { ExpandTable[i]=i | (i << 8)| (i <<16) | (i << 24); -#ifdef WORDS_BIGENDIAN - CGA_4_Table[i]=((i>>0)&3) | (((i>>2)&3) << 8)| (((i>>4)&3) <<16) | (((i>>6)&3) << 24); -#else - CGA_4_Table[i]=((i>>6)&3) | (((i>>4)&3) << 8)| (((i>>2)&3) <<16) | (((i>>0)&3) << 24); - - -#endif } for (i=0;i<16;i++) { TXT_FG_Table[i]=i | (i << 8)| (i <<16) | (i << 24); TXT_BG_Table[i]=i | (i << 8)| (i <<16) | (i << 24); - #ifdef WORDS_BIGENDIAN - CGA_2_Table[i]=((i>>0)&1) | (((i>>1)&1) << 8)| (((i>>1)&1) <<16) | (((i>>3)&1) << 24); FillTable[i]= ((i & 1) ? 0xff000000 : 0) | ((i & 2) ? 0x00ff0000 : 0) | @@ -127,7 +163,6 @@ void VGA_Init(Section* sec) { ((i & 4) ? 0x00ff0000 : 0) | ((i & 8) ? 0xff000000 : 0) ; #else - CGA_2_Table[i]=((i>>3)&1) | (((i>>2)&1) << 8)| (((i>>1)&1) <<16) | (((i>>0)&1) << 24); FillTable[i]= ((i & 1) ? 0x000000ff : 0) | ((i & 2) ? 0x0000ff00 : 0) | @@ -138,7 +173,6 @@ void VGA_Init(Section* sec) { ((i & 2) ? 0x00ff0000 : 0) | ((i & 4) ? 0x0000ff00 : 0) | ((i & 8) ? 0x000000ff : 0) ; - #endif } for (j=0;j<4;j++) { diff --git a/src/hardware/vga_attr.cpp b/src/hardware/vga_attr.cpp index a486344e..b57e9ca4 100644 --- a/src/hardware/vga_attr.cpp +++ b/src/hardware/vga_attr.cpp @@ -23,7 +23,6 @@ #define attr(blah) vga.attr.blah void VGA_ATTR_SetPalette(Bit8u index,Bit8u val) { - vga.attr.palette[index]=val; if (vga.attr.mode_control & 0x80) val=(val&0xf) | (vga.attr.color_select << 4); else val|=(vga.attr.color_select & 0xc) << 4; VGA_DAC_CombineColor(index,val); @@ -69,16 +68,9 @@ void write_p3c0(Bit32u port,Bit8u val) { Doesn't work if they program EGA16 themselves, but haven't encountered that yet */ - if (val&0x40) { - if (vga.mode0x7) vga.config.pel_panning=0; else vga.config.pel_panning=val+1; @@ -196,8 +187,10 @@ Bit8u read_p3c1(Bit32u port) { void VGA_SetupAttr(void) { - IO_RegisterWriteHandler(0x3c0,write_p3c0,"VGA Attribute controller"); - IO_RegisterReadHandler(0x3c1,read_p3c1,"VGA Attribute Read"); + if (machine==MCH_VGA) { + IO_RegisterWriteHandler(0x3c0,write_p3c0,"VGA Attribute controller"); + IO_RegisterReadHandler(0x3c1,read_p3c1,"VGA Attribute Read"); + } } diff --git a/src/hardware/vga_crtc.cpp b/src/hardware/vga_crtc.cpp index 23ca0959..d9f0b1fb 100644 --- a/src/hardware/vga_crtc.cpp +++ b/src/hardware/vga_crtc.cpp @@ -22,19 +22,17 @@ #include "debug.h" #include "cpu.h" - #define crtc(blah) vga.crtc.blah -void write_p3d4(Bit32u port,Bit8u val) { +void write_p3d4_vga(Bit32u port,Bit8u val) { crtc(index)=val; } -Bit8u read_p3d4(Bit32u port) { +Bit8u read_p3d4_vga(Bit32u port) { return crtc(index); } - -void write_p3d5(Bit32u port,Bit8u val) { +void write_p3d5_vga(Bit32u port,Bit8u val) { // if (crtc(index)>0x18) LOG_MSG("VGA CRCT write %X to reg %X",val,crtc(index)); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ @@ -256,6 +254,7 @@ void write_p3d5(Bit32u port,Bit8u val) { break; case 0x17: /* Mode Control Register */ crtc(mode_control)=val; + VGA_DetermineMode(); /* 0 If clear use CGA compatible memory addressing system by substituting character row scan counter bit 0 for address bit 13, @@ -495,7 +494,7 @@ void write_p3d5(Bit32u port,Bit8u val) { } } -Bit8u read_p3d5(Bit32u port) { +Bit8u read_p3d5_vga(Bit32u port) { // LOG_MSG("VGA CRCT read from reg %X",crtc(index)); switch(crtc(index)) { case 0x00: /* Horizontal Total Register */ diff --git a/src/hardware/vga_dac.cpp b/src/hardware/vga_dac.cpp index 1c8c1250..bddd699c 100644 --- a/src/hardware/vga_dac.cpp +++ b/src/hardware/vga_dac.cpp @@ -105,7 +105,7 @@ static void write_p3c9(Bit32u port,Bit8u val) { default: /* Check for attributes and DAC entry link */ for (Bitu i=0;i<16;i++) { - if (vga.dac.attr[i]==vga.dac.write_index) { + if (vga.attr.palette[i]==vga.dac.write_index) { RENDER_SetPal(i, vga.dac.rgb[vga.dac.write_index].red << 2, vga.dac.rgb[vga.dac.write_index].green << 2, @@ -145,7 +145,7 @@ static Bit8u read_p3c9(Bit32u port) { void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { /* Check if this is a new color */ - vga.dac.attr[attr]=pal; + vga.attr.palette[attr]=pal; switch (vga.mode) { case M_VGA: case M_LIN8: @@ -159,6 +159,20 @@ void VGA_DAC_CombineColor(Bit8u attr,Bit8u pal) { } } +void VGA_DAC_SetEntry(Bitu entry,Bit8u red,Bit8u green,Bit8u blue) { + vga.dac.rgb[entry].red=red; + vga.dac.rgb[entry].green=green; + vga.dac.rgb[entry].blue=blue; + switch (vga.mode) { + case M_VGA: + case M_LIN8: + return; + } + for (Bitu i=0;i<16;i++) + if (vga.attr.palette[i]==entry) + RENDER_SetPal(i,red << 2,green << 2,blue << 2); +} + void VGA_SetupDAC(void) { vga.dac.first_changed=256; vga.dac.bits=6; @@ -167,14 +181,16 @@ void VGA_SetupDAC(void) { vga.dac.state=DAC_READ; vga.dac.read_index=0; vga.dac.write_index=0; - /* Setup the DAC IO port Handlers */ - IO_RegisterWriteHandler(0x3c6,write_p3c6,"PEL Mask"); - IO_RegisterReadHandler(0x3c6,read_p3c6,"PEL Mask"); - IO_RegisterWriteHandler(0x3c7,write_p3c7,"PEL Read Mode"); - IO_RegisterReadHandler(0x3c7,read_p3c7,"PEL Status Mode"); - IO_RegisterWriteHandler(0x3c8,write_p3c8,"PEL Write Mode"); - IO_RegisterWriteHandler(0x3c9,write_p3c9,"PEL Data"); - IO_RegisterReadHandler(0x3c9,read_p3c9,"PEL Data"); + if (machine==MCH_VGA) { + /* Setup the DAC IO port Handlers */ + IO_RegisterWriteHandler(0x3c6,write_p3c6,"PEL Mask"); + IO_RegisterReadHandler(0x3c6,read_p3c6,"PEL Mask"); + IO_RegisterWriteHandler(0x3c7,write_p3c7,"PEL Read Mode"); + IO_RegisterReadHandler(0x3c7,read_p3c7,"PEL Status Mode"); + IO_RegisterWriteHandler(0x3c8,write_p3c8,"PEL Write Mode"); + IO_RegisterWriteHandler(0x3c9,write_p3c9,"PEL Data"); + IO_RegisterReadHandler(0x3c9,read_p3c9,"PEL Data"); + } }; diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index 90c65a91..85308500 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -30,18 +30,8 @@ typedef Bit8u * (* VGA_Line_Handler)(Bitu vidstart,Bitu panning,Bitu line); static VGA_Line_Handler VGA_DrawLine; -static Bit8u * VGA_HERC_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { - Bit8u * reader=&vga.mem.linear[vidstart+(line * 8 * 1024)]; - Bit32u * draw=(Bit32u *)RENDER_TempLine; - for (Bitu x=vga.draw.blocks;x>0;x--) { - Bitu val=*reader++; - *draw++=CGA_2_Table[val >> 4]; - *draw++=CGA_2_Table[val & 0xf]; - } - return RENDER_TempLine; -} -static Bit8u * VGA_CGA2_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { +static Bit8u * VGA_Draw_1BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)RENDER_TempLine; for (Bitu x=vga.draw.blocks;x>0;x--) { Bitu val=vga.mem.linear[vidstart+line];vidstart=(vidstart+1)&0x1fff; @@ -51,7 +41,7 @@ static Bit8u * VGA_CGA2_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { return RENDER_TempLine; } -static Bit8u * VGA_CGA4_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { +static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { line*=8*1024;Bit32u * draw=(Bit32u *)RENDER_TempLine; for (Bitu x=0;x> 4] | convert16[val & 0xf] << 16; - *draw++=full|=full<<8; - } - return RENDER_TempLine; -} - -static Bit8u * VGA_TANDY16_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { +static Bit8u * VGA_Draw_4BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { Bit8u * reader=&vga.mem.linear[(vga.tandy.disp_bank << 14) + vidstart + (line * 8 * 1024)]; Bit32u * draw=(Bit32u *)RENDER_TempLine; for (Bitu x=0;x> 4 | + (val2 & 0x0f) << 24 | + (val2 & 0xf0) << 12; + } + return RENDER_TempLine; +} + + +static Bit8u * VGA_Draw_EGA_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[512*1024+vidstart*8+panning]; } -static Bit8u * VGA_VGA_Draw_Line(Bitu vidstart,Bitu panning,Bitu line) { +static Bit8u * VGA_Draw_VGA_Line(Bitu vidstart,Bitu panning,Bitu line) { return &vga.mem.linear[vidstart*4+panning]; } @@ -163,11 +156,11 @@ void VGA_SetBlinking(Bitu enabled) { if (enabled) { b=0;vga.draw.blinking=1; //used to -1 but blinking is unsigned vga.attr.mode_control|=0x08; - vga.cga.mode_control&=~0x20; + vga.tandy.mode_control&=~0x20; } else { b=8;vga.draw.blinking=0; vga.attr.mode_control&=~0x08; - vga.cga.mode_control|=0x20; + vga.tandy.mode_control|=0x20; } for (Bitu i=0;i<8;i++) TXT_BG_Table[i+8]=(b+i) | ((b+i) << 8)| ((b+i) <<16) | ((b+i) << 24); } @@ -183,7 +176,7 @@ static void VGA_VerticalTimer(Bitu val) { vga.draw.split_line=vga.draw.lines_total-(vga.config.line_compare/vga.draw.lines_scaled); vga.draw.panning=vga.config.pel_panning; switch (vga.mode) { - case M_TEXT2:case M_TEXT16: + case M_TEXT: vga.draw.cursor.count++; /* check for blinking and blinking change delay */ FontMask[1]=(vga.attr.mode_control & (vga.draw.cursor.count >> 1) & 0x8) ? @@ -206,57 +199,98 @@ void VGA_CheckScanLength(void) { case M_LIN8: vga.draw.address_add=vga.config.scan_len*2; break; - case M_CGA2:case M_CGA4:case M_CGA16: - vga.draw.address_add=80; - break; - case M_TANDY16: - vga.draw.address_add=160; - break; - case M_TEXT16: - case M_TEXT2: + case M_TEXT: vga.draw.address_add=vga.config.scan_len*4; break; - case M_HERC: + case M_CGA2: + case M_CGA4: + vga.draw.address_add=80; + return; + case M_TANDY2: + vga.draw.address_add=vga.draw.blocks/4; + break; + case M_TANDY4: + vga.draw.address_add=vga.draw.blocks/2; + break; + case M_CGA16: + vga.draw.address_add=vga.draw.blocks/2; + return; + case M_TANDY16: + vga.draw.address_add=vga.draw.blocks; + break; + case M_TANDY_TEXT: + vga.draw.address_add=vga.draw.blocks*2; + break; + case M_HERC_TEXT: + vga.draw.address_add=vga.draw.blocks*2; + break; + case M_HERC_GFX: vga.draw.address_add=vga.draw.blocks; break; } } void VGA_SetupDrawing(Bitu val) { - /* Calculate the FPS for this screen */ - double fps; - Bitu vtotal=2 + vga.crtc.vertical_total | - ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4); - Bitu htotal=5 + vga.crtc.horizontal_total; - Bitu vdispend = 1 + (vga.crtc.vertical_display_end | - ((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) | - ((vga.s3.ex_ver_overflow & 0x2) << 9)); - Bitu hdispend = 1 + (vga.crtc.horizontal_display_end); - - Bitu hbstart = vga.crtc.start_horizontal_blanking; - Bitu vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5) | - ((vga.crtc.maximum_scan_line & 0x20) << 4) ; - - Bitu hrstart = vga.crtc.start_horizontal_retrace; - Bitu vrstart = vga.crtc.vertical_retrace_start + ((vga.crtc.overflow & 0x04) << 6) | - ((vga.crtc.overflow & 0x80) << 2); - - if (hbstart> 2) & 3; - clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); - /* Check for 8 for 9 character clock mode */ - if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9; - /* Check for pixel doubling, master clock/2 */ - if (vga.seq.clocking_mode & 0x8) { - htotal*=2; + if (vga.mode==M_ERROR) { + PIC_RemoveEvents(VGA_VerticalTimer); + PIC_RemoveEvents(VGA_VerticalDisplayEnd); + return; + } + /* Calculate the FPS for this screen */ + double fps;Bitu clock; + Bitu htotal,hdispend,hbstart,hrstart; + Bitu vtotal,vdispend,vbstart,vrstart; + if (machine==MCH_VGA) { + vtotal=2 + vga.crtc.vertical_total | + ((vga.crtc.overflow & 1) << 8) | ((vga.crtc.overflow & 0x20) << 4); + htotal=5 + vga.crtc.horizontal_total; + vdispend = 1 + (vga.crtc.vertical_display_end | + ((vga.crtc.overflow & 2)<<7) | ((vga.crtc.overflow & 0x40) << 3) | + ((vga.s3.ex_ver_overflow & 0x2) << 9)); + hdispend = 1 + (vga.crtc.horizontal_display_end); + hbstart = vga.crtc.start_horizontal_blanking; + vbstart = vga.crtc.start_vertical_blanking | ((vga.crtc.overflow & 0x08) << 5) | + ((vga.crtc.maximum_scan_line & 0x20) << 4) ; + hrstart = vga.crtc.start_horizontal_retrace; + vrstart = vga.crtc.vertical_retrace_start + ((vga.crtc.overflow & 0x04) << 6) | + ((vga.crtc.overflow & 0x80) << 2); + if (hbstart> 2) & 3; + clock=1000*S3_CLOCK(vga.s3.clk[clock].m,vga.s3.clk[clock].n,vga.s3.clk[clock].r); + /* Check for 8 for 9 character clock mode */ + if (vga.seq.clocking_mode & 1 ) clock/=8; else clock/=9; + /* Check for pixel doubling, master clock/2 */ + if (vga.seq.clocking_mode & 0x8) { + htotal*=2; + } + vga.draw.font_height=(vga.crtc.maximum_scan_line&0xf)+1; + /* Check for dual transfer whatever thing,master clock/2 */ + if (vga.s3.pll.cmd & 0x10) clock/=2; + } else { + vga.draw.font_height=vga.other.max_scanline+1; + htotal=vga.other.htotal; + hdispend=vga.other.hdend; + hrstart=vga.other.hsyncp; + vtotal=vga.draw.font_height*vga.other.vtotal+vga.other.vadjust; + vdispend=vga.draw.font_height*vga.other.vdend; + vrstart=vga.draw.font_height*vga.other.vsyncp; + switch (machine) { + case MCH_CGA: + case MCH_TANDY: + clock=((vga.tandy.mode_control & 1) ? 14318180 : (14318180/2))/8; + break; + case MCH_HERC: + if (vga.herc.mode_control & 0x2) clock=14318180/16; + else clock=14318180/8; + break; + } } - /* Check for dual transfer whatever thing,master clock/2 */ - if (vga.s3.pll.cmd & 0x10) clock/=2; - LOG(LOG_VGA,LOG_NORMAL)("H total %d, V Total %d",htotal,vtotal); LOG(LOG_VGA,LOG_NORMAL)("H D End %d, V D End %d",hdispend,vdispend); + if (!htotal) return; + if (!vtotal) return; fps=clock/(vtotal*htotal); double linemicro=(1000000/fps); vga.draw.parts_total=VGA_PARTS; @@ -279,86 +313,103 @@ void VGA_SetupDrawing(Bitu val) { width=hdispend; height=vdispend; vga.draw.double_scan=false; - vga.draw.font_height=(vga.crtc.maximum_scan_line&0xf)+1; switch (vga.mode) { case M_VGA: - scalew=2; - scaleh*=vga.draw.font_height; + scalew=2;scaleh*=vga.draw.font_height; if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; vga.draw.lines_scaled=scaleh; - height/=scaleh; - width<<=2; vga.draw.address_line_total=1; - VGA_DrawLine=VGA_VGA_Draw_Line; + height/=scaleh;width<<=2; + VGA_DrawLine=VGA_Draw_VGA_Line; break; case M_LIN8: - width<<=3; scaleh*=vga.draw.font_height; vga.draw.lines_scaled=scaleh; vga.draw.address_line_total=1; - VGA_DrawLine=VGA_VGA_Draw_Line; + width<<=3; + VGA_DrawLine=VGA_Draw_VGA_Line; break; case M_EGA16: - width<<=3; scaleh*=vga.draw.font_height; if (vga.crtc.maximum_scan_line&0x80) scaleh*=2; vga.draw.lines_scaled=scaleh; - height/=scaleh; if (vga.seq.clocking_mode & 0x8) scalew*=2; + width<<=3;height/=scaleh; vga.draw.address_line_total=1; - VGA_DrawLine=VGA_EGA_Draw_Line; + VGA_DrawLine=VGA_Draw_EGA_Line; break; case M_CGA4: - case M_CGA16: //Let is use 320x200 res and double pixels myself - scaleh=2;scalew=2; - vga.draw.blocks=width; - width<<=2; - height/=2; + scaleh=2;scalew*=2; + vga.draw.blocks=width*2; vga.draw.lines_scaled=1; vga.draw.address_line_total=2; - VGA_DrawLine=(vga.mode == M_CGA4) ? VGA_CGA4_Draw_Line : VGA_CGA16_Draw_Line; + width<<=3;height/=2; + VGA_DrawLine=VGA_Draw_2BPP_Line; break; case M_CGA2: - scaleh=2;height/=2; - vga.draw.address_line_total=2; + scaleh=2; vga.draw.blocks=width; - width<<=3; + vga.draw.lines_scaled=1; vga.draw.address_line_total=2; - vga.draw.lines_scaled=1; - VGA_DrawLine=VGA_CGA2_Draw_Line; + width<<=4;height/=2; + VGA_DrawLine=VGA_Draw_1BPP_Line; break; - case M_HERC: - vga.draw.address_line_total=4; - width*=9; - vga.draw.blocks=width/8; - vga.draw.lines_scaled=1; - height=348; - aspect_ratio=1.5; - VGA_DrawLine=VGA_HERC_Draw_Line; - break; - case M_TANDY16: - scaleh=2;scalew=2; - vga.draw.blocks=width*2; - vga.draw.address_line_total=4; - vga.draw.lines_scaled=1; - width<<=2;height/=2; - VGA_DrawLine=VGA_TANDY16_Draw_Line; - break; - case M_TEXT2: - case M_TEXT16: + case M_TEXT: aspect_ratio=1.0; - if (vga.draw.font_height<4 && (machine640) width=640; - if (height>480) height=480; + VGA_DrawLine=VGA_TEXT_Draw_Line; + break; + case M_HERC_GFX: + aspect_ratio=1.5; + vga.draw.address_line_total=vga.draw.font_height; + vga.draw.blocks=width*2; + vga.draw.lines_scaled=1; + width*=16; + VGA_DrawLine=VGA_Draw_1BPP_Line; + break; + case M_TANDY2: + scaleh=2;aspect_ratio=1.2; + scalew=(vga.tandy.mode_control & 0x10) ? 1 : 2; + vga.draw.blocks=width*8/scalew; + vga.draw.address_line_total=vga.draw.font_height; + vga.draw.lines_scaled=1; + width=vga.draw.blocks*2; + VGA_DrawLine=VGA_Draw_1BPP_Line; + break; + case M_TANDY4: + scaleh=2;aspect_ratio=1.2; + scalew=(vga.tandy.mode_control & 0x10) ? 1 : 2; + vga.draw.blocks=width*8/scalew; + vga.draw.address_line_total=vga.draw.font_height; + vga.draw.lines_scaled=1; + width=vga.draw.blocks*2; + VGA_DrawLine=VGA_Draw_2BPP_Line; + break; + case M_TANDY16: + scaleh=2;aspect_ratio=1.2; + scalew=(vga.tandy.mode_control & 0x10) ? 1 : 2; + vga.draw.blocks=width*4/scalew; + vga.draw.address_line_total=vga.draw.font_height; + vga.draw.lines_scaled=1; + width=vga.draw.blocks*2; + VGA_DrawLine=VGA_Draw_4BPP_Line; + break; + case M_TANDY_TEXT: + scalew=(vga.tandy.mode_control & 0x1) ? 1 : 2; + case M_HERC_TEXT: + aspect_ratio=1; + scaleh=(vga.mode==M_HERC_TEXT) ? 1 : 2; + vga.draw.lines_scaled=1; + vga.draw.address_line_total=vga.draw.font_height; + vga.draw.blocks=width; + vga.draw.lines_scaled=1; + width<<=3; VGA_DrawLine=VGA_TEXT_Draw_Line; break; default: diff --git a/src/hardware/vga_gfx.cpp b/src/hardware/vga_gfx.cpp index 2498c26f..3af56b43 100644 --- a/src/hardware/vga_gfx.cpp +++ b/src/hardware/vga_gfx.cpp @@ -20,19 +20,18 @@ #include "inout.h" #include "vga.h" - #define gfx(blah) vga.gfx.blah static bool index9warned=false; -void write_p3ce(Bit32u port,Bit8u val) { +static void write_p3ce(Bit32u port,Bit8u val) { gfx(index)=val & 0x0f; } -Bit8u read_p3ce(Bit32u port) { +static Bit8u read_p3ce(Bit32u port) { return gfx(index); } -void write_p3cf(Bit32u port,Bit8u val) { +static void write_p3cf(Bit32u port,Bit8u val) { switch (gfx(index)) { case 0: /* Set/Reset Register */ gfx(set_reset)=val & 0x0f; @@ -92,8 +91,11 @@ void write_p3cf(Bit32u port,Bit8u val) { vga.config.read_map_select=val & 0x03; // LOG_DEBUG("Read Map %2X",val); break; - case 5: /* Mode Register */ /* Important one very */ - gfx(mode)=val; + case 5: /* Mode Register */ + if ((gfx(mode) ^ val) & 0xf0) { + gfx(mode)=val; + VGA_DetermineMode(); + } else gfx(mode)=val; vga.config.write_mode=val & 3; vga.config.read_mode=(val >> 3) & 1; // LOG_DEBUG("Write Mode %d Read Mode %d val %d",vga.config.write_mode,vga.config.read_mode,val); @@ -134,7 +136,6 @@ void write_p3cf(Bit32u port,Bit8u val) { 4 Enables Odd/Even mode if set (See 3C4h index 4 bit 2). 5 Enables CGA style 4 color pixels using even/odd bit pairs if set. 6 Enables 256 color mode if set. - */ break; case 6: /* Miscellaneous Register */ @@ -183,7 +184,7 @@ void write_p3cf(Bit32u port,Bit8u val) { } } -Bit8u read_p3cf(Bit32u port) { +static Bit8u read_p3cf(Bit32u port) { switch (gfx(index)) { case 0: /* Set/Reset Register */ return gfx(set_reset); @@ -212,10 +213,12 @@ Bit8u read_p3cf(Bit32u port) { void VGA_SetupGFX(void) { - IO_RegisterWriteHandler(0x3ce,write_p3ce,"VGA Graphics Index"); - IO_RegisterWriteHandler(0x3cf,write_p3cf,"VGA Graphics Data"); - IO_RegisterReadHandler(0x3ce,read_p3ce,"Vga Graphics Index"); - IO_RegisterReadHandler(0x3cf,read_p3cf,"Vga Graphics Data"); + if (machine==MCH_VGA) { + IO_RegisterWriteHandler(0x3ce,write_p3ce,"VGA Graphics Index"); + IO_RegisterWriteHandler(0x3cf,write_p3cf,"VGA Graphics Data"); + IO_RegisterReadHandler(0x3ce,read_p3ce,"Vga Graphics Index"); + IO_RegisterReadHandler(0x3cf,read_p3cf,"Vga Graphics Data"); + } } diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index a0ade8be..b26679b8 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -247,11 +247,17 @@ public: class VGA_TANDY_PageHandler : public PageHandler { public: VGA_TANDY_PageHandler() { - flags=PFLAG_READABLE|PFLAG_WRITEABLE|PFLAG_NOCODE; + 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)]; + if (phys_page>=0xb8) { + phys_page-=0xb8; + return &vga.mem.linear[(vga.tandy.mem_bank << 14)+(phys_page * 4096)]; + } else { + phys_page-=0x80; + return &vga.mem.linear[phys_page * 4096]; + } } }; @@ -268,7 +274,22 @@ static struct { void VGA_SetupHandlers(void) { PageHandler * range_handler; + switch (machine) { + case MCH_CGA: + range_handler=&vgaph.hmap; + goto range_b800; + case MCH_HERC: + range_handler=&vgaph.hmap; + if (vga.herc.mode_control&0x80) goto range_b800; + else goto range_b000; + case MCH_TANDY: + range_handler=&vgaph.htandy; + MEM_SetPageHandler(0x80,32,range_handler); + goto range_b800; + } switch (vga.mode) { + case M_ERROR: + return; case M_LIN8: range_handler=&vgaph.hmap; break; @@ -282,29 +303,15 @@ void VGA_SetupHandlers(void) { case M_EGA16: range_handler=&vgaph.h16; break; - case M_TEXT2: - case M_TEXT16: + case M_TEXT: /* Check if we're not in odd/even mode */ - if (vga.gfx.miscellaneous & 0x2) { - range_handler=&vgaph.hmap; - } else { - range_handler=&vgaph.htext; - } + if (vga.gfx.miscellaneous & 0x2) range_handler=&vgaph.hmap; + else range_handler=&vgaph.htext; break; - case M_TANDY16: - range_handler=&vgaph.htandy; - break; - case M_CGA16: case M_CGA4: case M_CGA2: range_handler=&vgaph.hmap; break; - case M_HERC: - range_handler=&vgaph.hmap; - if (vga.herc.mode_control&0x80) goto range_b800; - else goto range_b000; - default: - LOG_MSG("Unhandled vga mode %X",vga.mode); } switch ((vga.gfx.miscellaneous >> 2) & 3) { case 0: diff --git a/src/hardware/vga_misc.cpp b/src/hardware/vga_misc.cpp index 9ee6148f..012647ca 100644 --- a/src/hardware/vga_misc.cpp +++ b/src/hardware/vga_misc.cpp @@ -20,26 +20,25 @@ #include "inout.h" #include "pic.h" #include "vga.h" -#include "../ints/int10.h" static Bit8u flip=0; -void write_p3d4(Bit32u port,Bit8u val); -Bit8u read_p3d4(Bit32u port); -void write_p3d5(Bit32u port,Bit8u val); -Bit8u read_p3d5(Bit32u port); +void write_p3d4_vga(Bit32u port,Bit8u val); +Bit8u read_p3d4_vga(Bit32u port); +void write_p3d5_vga(Bit32u port,Bit8u val); +Bit8u read_p3d5_vga(Bit32u port); -static void write_p3d9(Bit32u port,Bit8u val); +void write_p3d4_cga(Bit32u port,Bit8u val); +Bit8u read_p3d4_cga(Bit32u port); +void write_p3d5_cga(Bit32u port,Bit8u val); +Bit8u read_p3d5_cga(Bit32u port); static Bit8u read_p3da(Bit32u port) { vga.internal.attrindex=false; if (vga.config.retrace) { - switch (vga.mode) { - case M_HERC: + switch (machine) { + case MCH_HERC: return 0x81; - case M_TEXT2: - if (machine==MCH_HERC) return 0x81; - if (machine==MCH_AUTO) return 0x89; default: return 9; } @@ -54,182 +53,14 @@ static Bit8u read_p3da(Bit32u port) { */ } -static void write_p3d8(Bit32u port,Bit8u val) { - /* Check if someone changes the blinking/hi intensity bit */ - switch (machine) { - case MCH_AUTO: - VGA_SetBlinking((val & 0x20)); - switch (vga.mode) { - case M_CGA2: - case M_CGA4: - case M_CGA16: - goto m_cga; - } - break; - case MCH_CGA: - VGA_SetBlinking((val & 0x20)); -m_cga: - if (val & 0x2) { - if (val & 0x10) { - if (val & 0x8) { - VGA_SetMode(M_CGA16); //Video burst 16 160x200 color mode - } else { - VGA_SetMode(M_CGA2); - } - } else VGA_SetMode(M_CGA4); - write_p3d9(0x3d9,vga.cga.color_select); //Setup the correct palette - } else { - VGA_SetMode(M_TEXT16); - } - vga.cga.mode_control=val; - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Write %2X to 3d8 in mode %d",val,vga.mode); - } - /* - 3 Vertical Sync Select. If set Vertical Sync to the monitor is the - logical OR of the vertical sync and the vertical display enable. - */ -} - -static void write_p3d9(Bit32u port,Bit8u val) { - Bitu i; - vga.cga.color_select=val; - switch (vga.mode) { - case M_CGA2: - /* changes attribute 1 */ - VGA_ATTR_SetPalette(0,0); - VGA_ATTR_SetPalette(1,val & 0xf); - break; - case M_CGA4: - /* changes attribute 0 */ - { - VGA_ATTR_SetPalette(0,(val & 0xf)); - Bit8u pal_base=(val & 0x10) ? 0x08 : 0; - /* Check for BW Mode */ - if (vga.cga.mode_control & 0x4) { - if (val & 0x20) { - VGA_ATTR_SetPalette(1,0x03+pal_base); - VGA_ATTR_SetPalette(2,0x04+pal_base); - VGA_ATTR_SetPalette(3,0x07+pal_base); - } else { - //TODO Maybe? will anyone ever use, - //will also need to setup a BW palette,but could put it behind normal cga... - VGA_ATTR_SetPalette(1,0x02+pal_base); - VGA_ATTR_SetPalette(2,0x04+pal_base); - VGA_ATTR_SetPalette(3,0x06+pal_base); - } - } else { - if (val & 0x20) { - VGA_ATTR_SetPalette(1,0x03+pal_base); - VGA_ATTR_SetPalette(2,0x05+pal_base); - VGA_ATTR_SetPalette(3,0x07+pal_base); - } else { - VGA_ATTR_SetPalette(1,0x02+pal_base); - VGA_ATTR_SetPalette(2,0x04+pal_base); - VGA_ATTR_SetPalette(3,0x06+pal_base); - } - } - } - break; - case M_CGA16: - for(i=0;i<0x10;i++) VGA_ATTR_SetPalette(i,i); - break; - case M_TEXT16: - /* Assume a normal text palette has been set */ -// VGA_ATTR_SetPalette(0,(val & 0x8) ? ((val & 7)+32) : (val &7)); - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); - } -} - -static void write_p3da(Bit32u port,Bit8u val) { - if (machine==MCH_TANDY) goto tandy_3da; - switch (vga.mode) { - case M_TANDY16: -tandy_3da: - vga.tandy.reg_index=val; - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); - break; - - } -} - - -static void write_p3de(Bit32u port,Bit8u val) { - if (machine==MCH_TANDY) goto tandy_3de; - switch (vga.mode) { - case M_TANDY16: -tandy_3de: - switch (vga.tandy.reg_index) { - case 0x2: /* Border color */ - vga.tandy.border_color=val; - break; - /* palette colors */ - case 0x10: case 0x11: case 0x12: case 0x13: - case 0x14: case 0x15: case 0x16: case 0x17: - case 0x18: case 0x19: case 0x1a: case 0x1b: - case 0x1c: case 0x1d: case 0x1e: case 0x1f: - VGA_ATTR_SetPalette(vga.tandy.reg_index-0x10,val & 0xf); - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index); - } - break; - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); - break; - } -} - -static void write_p3df(Bit32u port,Bit8u val) { - if (machine==MCH_TANDY) goto tandy_3df; - switch (vga.mode) { - case M_TANDY16: -tandy_3df: - vga.tandy.disp_bank=val & ((val & 0x80) ? 0x6 : 0x7); - vga.tandy.mem_bank=(val >> 3) & ((val & 0x80) ? 0x6 : 0x7); - VGA_SetupHandlers(); - break; - /* - 0-2 Identifies the page of main memory being displayed in units of 16K. - 0: 0K, 1: 16K...7: 112K. In 32K modes (bits 6-7 = 2) only 0,2,4 and - 6 are valid, as the next page will also be used. - 3-5 Identifies the page of main memory that can be read/written at B8000h - in units of 16K. 0: 0K, 1: 16K...7: 112K. In 32K modes (bits 6-7 = 2) - only 0,2,4 and 6 are valid, as the next page will also be used. - 6-7 Display mode. 0: Text, 1: 16K graphics mode (4,5,6,8) - 2: 32K graphics mode (9,Ah) - */ - default: - LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to %X in mode %d",val,port,vga.mode); - break; - } -} - -static Bit8u read_p3d9(Bit32u port) { - switch (machine) { - case MCH_AUTO: - case MCH_CGA: - case MCH_TANDY: - return vga.cga.color_select; - default: - return 0xff; - }; -} - static void write_p3c2(Bit32u port,Bit8u val) { vga.misc_output=val; - if (val & 0x1) { - IO_RegisterWriteHandler(0x3d4,write_p3d4,"VGA:CRTC Index Select"); - IO_RegisterReadHandler(0x3d4,read_p3d4,"VGA:CRTC Index Select"); - IO_RegisterWriteHandler(0x3d5,write_p3d5,"VGA:CRTC Data Register"); - IO_RegisterReadHandler(0x3d5,read_p3d5,"VGA:CRTC Data Register"); + IO_RegisterWriteHandler(0x3d4,write_p3d4_vga,"VGA:CRTC Index Select"); + IO_RegisterReadHandler(0x3d4,read_p3d4_vga,"VGA:CRTC Index Select"); + IO_RegisterWriteHandler(0x3d5,write_p3d5_vga,"VGA:CRTC Data Register"); + IO_RegisterReadHandler(0x3d5,read_p3d5_vga,"VGA:CRTC Data Register"); IO_RegisterReadHandler(0x3da,read_p3da,"VGA Input Status 1"); IO_FreeWriteHandler(0x3b4); @@ -238,10 +69,10 @@ static void write_p3c2(Bit32u port,Bit8u val) { IO_FreeReadHandler(0x3b5); IO_FreeReadHandler(0x3ba); } else { - IO_RegisterWriteHandler(0x3b4,write_p3d4,"VGA:CRTC Index Select"); - IO_RegisterReadHandler(0x3b4,read_p3d4,"VGA:CRTC Index Select"); - IO_RegisterWriteHandler(0x3b5,write_p3d5,"VGA:CRTC Data Register"); - IO_RegisterReadHandler(0x3b5,read_p3d5,"VGA:CRTC Data Register"); + IO_RegisterWriteHandler(0x3b4,write_p3d4_vga,"VGA:CRTC Index Select"); + IO_RegisterReadHandler(0x3b4,read_p3d4_vga,"VGA:CRTC Index Select"); + IO_RegisterWriteHandler(0x3b5,write_p3d5_vga,"VGA:CRTC Data Register"); + IO_RegisterReadHandler(0x3b5,read_p3d5_vga,"VGA:CRTC Data Register"); IO_RegisterReadHandler(0x3ba,read_p3da,"VGA Input Status 1"); IO_FreeWriteHandler(0x3d4); @@ -269,67 +100,16 @@ static Bit8u read_p3cc(Bit32u port) { } -static void write_hercules(Bit32u port,Bit8u val) { - switch (port) { - case 0x3b8: - vga.herc.mode_control=(vga.herc.mode_control & ~0x7d) | (val&0x7d); - if ((vga.herc.enable_bits & 1) && ((vga.herc.mode_control ^ val)&0x2)) { - vga.herc.mode_control^=0x2; - if (vga.mode != M_HERC || vga.mode != M_TEXT2) { - VGA_ATTR_SetPalette(0,0x00); - VGA_ATTR_SetPalette(1,0x07); - - /* Force 0x3b4/5 registers */ - if (vga.misc_output & 1) write_p3c2(0,vga.misc_output & ~1); - } - if (val & 0x2) { - if (vga.mode != M_HERC) VGA_SetMode(M_HERC); - } else { - if (vga.mode != M_TEXT2) VGA_SetMode(M_TEXT2); - } - } - if ((vga.herc.enable_bits & 0x2) && ((vga.herc.mode_control ^ val)&0x80)) { - vga.herc.mode_control^=0x80; - VGA_SetupHandlers(); - } - break; - case 0x3bf: - vga.herc.enable_bits=val; - break; - default: - LOG_MSG("write %x to Herc port %x",val,port); - } -} - -static Bit8u read_hercules(Bit32u port) { - switch (port) { - case 0x3b8: - default: - LOG_MSG("read from Herc port %x",port); - } - return 0; -} - - - void VGA_SetupMisc(void) { - vga.herc.enable_bits=0; - IO_RegisterWriteHandler(0x3d8,write_p3d8,"VGA Feature Control Register"); - IO_RegisterWriteHandler(0x3d9,write_p3d9,"CGA Color Select Register"); - IO_RegisterReadHandler(0x3d9,read_p3d9,"CGA Color Select Register"); - - IO_RegisterWriteHandler(0x3c2,write_p3c2,"VGA Misc Output"); - IO_RegisterReadHandler(0x3cc,read_p3cc,"VGA Misc Output"); - - if (machine==MCH_HERC || machine==MCH_AUTO) { - vga.herc.mode_control=0x8; - IO_RegisterWriteHandler(0x3b8,write_hercules,"Hercules"); - IO_RegisterWriteHandler(0x3bf,write_hercules,"Hercules"); + if (machine==MCH_VGA) { + IO_RegisterWriteHandler(0x3c2,write_p3c2,"VGA Misc Output"); + IO_RegisterReadHandler(0x3cc,read_p3cc,"VGA Misc Output"); + } else if (machine==MCH_CGA || machine==MCH_TANDY) { + IO_RegisterReadHandler(0x3da,read_p3da,"VGA Input Status 1"); + } else if (machine==MCH_HERC) { + IO_RegisterReadHandler(0x3ba,read_p3da,"VGA Input Status 1"); } - IO_RegisterWriteHandler(0x3de,write_p3de,"PCJR Reg Write"); - IO_RegisterWriteHandler(0x3df,write_p3df,"PCJR Bank Select"); - IO_RegisterWriteHandler(0x3da,write_p3da,"PCJR Reg Select"); } diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp new file mode 100644 index 00000000..da3fe693 --- /dev/null +++ b/src/hardware/vga_other.cpp @@ -0,0 +1,308 @@ +/* + * 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" + +static void write_crtc_index_other(Bit32u port,Bit8u val) { + vga.other.index=val; +} + +static Bit8u read_crtc_index_other(Bit32u port) { + return vga.other.index; +} + +static void write_crtc_data_other(Bit32u port,Bit8u val) { + switch (vga.other.index) { + case 0x00: //Horizontal total + if (vga.other.htotal ^ val) VGA_StartResize(); + vga.other.htotal=val; + break; + case 0x01: //Horizontal displayed chars + if (vga.other.hdend ^ val) VGA_StartResize(); + vga.other.hdend=val; + break; + case 0x02: //Horizontal sync position + vga.other.hsyncp=val; + break; + case 0x03: //Horizontal sync width + vga.other.hsyncw=val; + break; + case 0x04: //Vertical total + if (vga.other.vtotal ^ val) VGA_StartResize(); + vga.other.vtotal=val; + break; + case 0x05: //Vertical display adjust + if (vga.other.vadjust ^ val) VGA_StartResize(); + vga.other.vadjust=val; + break; + case 0x06: //Vertical rows + if (vga.other.vdend ^ val) VGA_StartResize(); + vga.other.vdend=val; + break; + case 0x07: //Vertical sync position + vga.other.vsyncp=val; + break; + case 0x09: //Max scanline + if (vga.other.max_scanline ^ val) VGA_StartResize(); + vga.other.max_scanline=val; + break; + vga.config.display_start=(vga.config.display_start & 0xFF00FF)| (val << 8); + break; + case 0x0C: /* Start Address High Register */ + vga.config.display_start=(vga.config.display_start & 0xFF00FF)| (val << 8); + break; + case 0x0D: /* Start Address Low Register */ + vga.config.display_start=(vga.config.display_start & 0xFFFF00)| val; + break; + case 0x0E: /*Cursor Location High Register */ + vga.config.cursor_start&=0xff00ff; + vga.config.cursor_start|=val << 8; + break; + case 0x0F: /* Cursor Location Low Register */ + vga.config.cursor_start&=0xffff00; + vga.config.cursor_start|=val; + break; + default: + LOG_MSG("Write %X to illgal index %x",val,vga.other.index); + } +} +static Bit8u read_crtc_data_other(Bit32u port) { + switch (vga.other.index) { + case 0x00: //Horizontal total + return vga.other.htotal; + case 0x01: //Horizontal displayed chars + return vga.other.hdend; + case 0x02: //Horizontal sync position + return vga.other.hsyncp; + case 0x03: //Horizontal sync width + return vga.other.hsyncw; + case 0x04: //Vertical total + return vga.other.vtotal; + case 0x05: //Vertical display adjust + return vga.other.vadjust; + case 0x06: //Vertical rows + return vga.other.vdend; + case 0x07: //Vertical sync position + return vga.other.vsyncp; + case 0x09: //Max scanline + return vga.other.max_scanline; + case 0x0C: /* Start Address High Register */ + return vga.config.display_start >> 8; + case 0x0D: /* Start Address Low Register */ + return vga.config.display_start; + case 0x0E: /*Cursor Location High Register */ + return vga.config.cursor_start>>8; + case 0x0F: /* Cursor Location Low Register */ + return vga.config.cursor_start; + default: + LOG_MSG("Read from illgal index %x",vga.other.index); + } +} + +static void write_color_select(Bit8u val) { + vga.tandy.color_select=val; + switch (vga.mode) { + case M_TANDY2: + VGA_SetCGA2Table(0,val & 0xf); + break; + case M_TANDY4: + { + if (machine == MCH_TANDY && (vga.tandy.gfx_control & 0x8)) { + VGA_SetCGA4Table(0,1,2,3); + return; + } + Bit8u base=(val & 0x10) ? 0x08 : 0; + /* Check for BW Mode */ + if (vga.tandy.mode_control & 0x4) { + if (val & 0x20) VGA_SetCGA4Table(val & 0xf,3+base,4+base,7+base); + else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base); + } else { + if (val & 0x20) VGA_SetCGA4Table(val & 0xf,3+base,5+base,7+base); + else VGA_SetCGA4Table(val & 0xf,2+base,4+base,6+base); + } + } + break; + case M_CGA16: + case M_TEXT: + case M_TANDY16: + break; + } +} + +static void write_mode_control(Bit8u val) { + /* Check if someone changes the blinking/hi intensity bit */ + vga.tandy.mode_control=val; + VGA_SetBlinking((val & 0x20)); + if (val & 0x2) { + if (val & 0x10) { + if (val & 0x8) { + VGA_SetMode(M_CGA16); //Video burst 16 160x200 color mode + } else { + VGA_SetMode(M_CGA2); + } + } else VGA_SetMode(M_CGA4); + write_color_select(vga.tandy.color_select); //Setup the correct palette + } else { + VGA_SetMode(M_TEXT); + } +} + +static void TANDY_FindMode(void) { + if (vga.tandy.mode_control & 0x2) { + if (vga.tandy.gfx_control & 0x10) VGA_SetMode(M_TANDY16); + else if (vga.tandy.gfx_control & 0x08) VGA_SetMode(M_TANDY4); + else if (vga.tandy.mode_control & 0x10) VGA_SetMode(M_TANDY2); + else VGA_SetMode(M_TANDY4); + write_color_select(vga.tandy.color_select); + } else { + VGA_SetMode(M_TANDY_TEXT); + } +} + +static void write_tandy_reg(Bit8u val) { + switch (vga.tandy.reg_index) { + case 0x2: /* Border color */ + vga.tandy.border_color=val; + break; + case 0x3: /* More control */ + vga.tandy.gfx_control=val; + TANDY_FindMode(); + break; + /* palette colors */ + case 0x10: case 0x11: case 0x12: case 0x13: + case 0x14: case 0x15: case 0x16: case 0x17: + case 0x18: case 0x19: case 0x1a: case 0x1b: + case 0x1c: case 0x1d: case 0x1e: case 0x1f: + VGA_ATTR_SetPalette(vga.tandy.reg_index-0x10,val & 0xf); + break; + default: + LOG(LOG_VGAMISC,LOG_NORMAL)("Unhandled Write %2X to tandy reg %X",val,vga.tandy.reg_index); + } +} + +static void write_cga(Bit32u port,Bit8u val) { + switch (port) { + case 0x3d8: + vga.tandy.mode_control=val; + if (vga.tandy.mode_control & 0x2) { + if (vga.tandy.mode_control & 0x10) { + VGA_SetMode(M_TANDY2); + } else VGA_SetMode(M_TANDY4); + write_color_select(vga.tandy.color_select); + } else { + VGA_SetMode(M_TANDY_TEXT); + } + break; + case 0x3d9: + write_color_select(val); + break; + } +} + +static void write_tandy(Bit32u port,Bit8u val) { + switch (port) { + case 0x3d8: + vga.tandy.mode_control=val; + TANDY_FindMode(); + break; + case 0x3d9: + write_color_select(val); + break; + case 0x3da: + vga.tandy.reg_index=val; + break; + case 0x3de: + write_tandy_reg(val); + break; + case 0x3df: + vga.tandy.disp_bank=val & ((val & 0x80) ? 0x6 : 0x7); + vga.tandy.mem_bank=(val >> 3) & ((val & 0x80) ? 0x6 : 0x7); + VGA_SetupHandlers(); + break; + } +} + +static void write_hercules(Bit32u port,Bit8u val) { + switch (port) { + case 0x3b8: + if (vga.herc.enable_bits & 1) { + vga.herc.mode_control&=~0x2; + vga.herc.mode_control|=(val&0x2); + if (val & 0x2) { + VGA_SetMode(M_HERC_GFX); + } else { + VGA_SetMode(M_HERC_TEXT); + } + } + if ((vga.herc.enable_bits & 0x2) && ((vga.herc.mode_control ^ val)&0x80)) { + vga.herc.mode_control^=0x80; + VGA_SetupHandlers(); + } + break; + case 0x3bf: + vga.herc.enable_bits=val; + break; + } +} + +static Bit8u read_hercules(Bit32u port) { + LOG_MSG("read from Herc port %x",port); + return 0; +} + + +void VGA_SetupOther(void) { + Bitu i; + if (machine==MCH_CGA || machine==MCH_TANDY) { + extern Bit8u int10_font_08[256 * 8]; + for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_08[i*8],8); + } + if (machine==MCH_HERC) { + extern Bit8u int10_font_14[256 * 14]; + for (i=0;i<256;i++) memcpy(&vga.draw.font[i*32],&int10_font_14[i*14],14); + } + if (machine==MCH_CGA) { + IO_RegisterWriteBHandler(0x3d8,write_cga); + IO_RegisterWriteBHandler(0x3d9,write_cga); + } + if (machine==MCH_HERC) { + vga.herc.enable_bits=0; + vga.herc.mode_control=0x8; + IO_RegisterWriteBHandler(0x3b8,write_hercules); + IO_RegisterWriteBHandler(0x3bf,write_hercules); + } + if (machine==MCH_TANDY) { + IO_RegisterWriteBHandler(0x3d8,write_tandy); + IO_RegisterWriteBHandler(0x3d9,write_tandy); + IO_RegisterWriteBHandler(0x3de,write_tandy); + IO_RegisterWriteBHandler(0x3df,write_tandy); + IO_RegisterWriteBHandler(0x3da,write_tandy); + } + if (machine==MCH_CGA || machine==MCH_HERC || machine==MCH_TANDY) { + Bitu base=machine==MCH_HERC ? 0x3b4 : 0x3d4; + IO_RegisterWriteBHandler(base,write_crtc_index_other); + IO_RegisterWriteBHandler(base+1,write_crtc_data_other); + IO_RegisterReadBHandler(base,read_crtc_index_other); + IO_RegisterReadBHandler(base+1,read_crtc_data_other); + } + +} + diff --git a/src/hardware/vga_seq.cpp b/src/hardware/vga_seq.cpp index 1ab8cc1a..53b284a4 100644 --- a/src/hardware/vga_seq.cpp +++ b/src/hardware/vga_seq.cpp @@ -167,10 +167,11 @@ Bit8u read_p3c5(Bit32u port) { void VGA_SetupSEQ(void) { - IO_RegisterWriteHandler(0x3c4,write_p3c4,"VGA:Sequencer Index"); - IO_RegisterWriteHandler(0x3c5,write_p3c5,"VGA:Sequencer Data"); - IO_RegisterReadHandler(0x3c4,read_p3c4,"VGA:Sequencer Index"); - IO_RegisterReadHandler(0x3c5,read_p3c5,"VGA:Sequencer Data"); - + if (machine==MCH_VGA) { + IO_RegisterWriteHandler(0x3c4,write_p3c4,"VGA:Sequencer Index"); + IO_RegisterWriteHandler(0x3c5,write_p3c5,"VGA:Sequencer Data"); + IO_RegisterReadHandler(0x3c4,read_p3c4,"VGA:Sequencer Index"); + IO_RegisterReadHandler(0x3c5,read_p3c5,"VGA:Sequencer Data"); + } } diff --git a/src/ints/int10.cpp b/src/ints/int10.cpp index 0e5bc636..2c362415 100644 --- a/src/ints/int10.cpp +++ b/src/ints/int10.cpp @@ -445,7 +445,7 @@ static void SetupTandyBios(void) { void INT10_Init(Section* sec) { INT10_InitVGA(); - if (machine==MCH_TANDY || machine==MCH_AUTO) SetupTandyBios(); + if (machine==MCH_TANDY) SetupTandyBios(); /* Setup the INT 10 vector */ call_10=CALLBACK_Allocate(); CALLBACK_Setup(call_10,&INT10_Handler,CB_IRET); diff --git a/src/ints/int10.h b/src/ints/int10.h index 417def0c..3172fe38 100644 --- a/src/ints/int10.h +++ b/src/ints/int10.h @@ -104,11 +104,10 @@ struct VideoModeBlock { Bitu htotal,vtotal; Bitu hdispend,vdispend; - Bitu rate; Bitu special; }; -extern VideoModeBlock ModeList[]; +extern VideoModeBlock ModeList_VGA[]; extern VideoModeBlock * CurMode; typedef struct { diff --git a/src/ints/int10_char.cpp b/src/ints/int10_char.cpp index 4a4e97b3..64e2a0f2 100644 --- a/src/ints/int10_char.cpp +++ b/src/ints/int10_char.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_char.cpp,v 1.22 2004-01-28 18:04:18 harekiet Exp $ */ +/* $Id: int10_char.cpp,v 1.23 2004-02-29 22:18:24 harekiet Exp $ */ /* Character displaying moving functions */ @@ -174,7 +174,7 @@ static INLINE void TEXT_FillRow(Bit8u cleft,Bit8u cright,Bit8u row,PhysPt base,B void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit8u attr,Bit8u page) { /* Do some range checking */ - if (CurMode->type>M_TEXT16) page=0xff; + if (CurMode->type!=M_TEXT) page=0xff; BIOS_NCOLS;BIOS_NROWS; if(rul>rlr) return; if(cul>clr) return; @@ -204,8 +204,7 @@ void INT10_ScrollWindow(Bit8u rul,Bit8u cul,Bit8u rlr,Bit8u clr,Bit8s nlines,Bit while (start!=end) { start+=next; switch (CurMode->type) { - case M_TEXT2: - case M_TEXT16: + case M_TEXT: TEXT_CopyRow(cul,clr,start,start+nlines,base);break; case M_CGA2: CGA2_CopyRow(cul,clr,start,start+nlines,base);break; @@ -229,8 +228,7 @@ filling: } for (;nlines>0;nlines--) { switch (CurMode->type) { - case M_TEXT2: - case M_TEXT16: + case M_TEXT: TEXT_FillRow(cul,clr,start,base,attr);break; case M_CGA2: CGA2_FillRow(cul,clr,start,base,attr);break; @@ -363,8 +361,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool Bitu x,y; Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT); switch (CurMode->type) { - case M_TEXT2: - case M_TEXT16: + case M_TEXT: { // Compute the address Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE); @@ -410,7 +407,7 @@ static void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool void INT10_WriteChar(Bit8u chr,Bit8u attr,Bit8u page,Bit16u count,bool showattr) { //TODO Check if this page thing is correct - if (CurMode->type>M_TEXT16) page=0xff; + if (CurMode->type!=M_TEXT) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); Bit8u cur_row=CURSOR_POS_ROW(page); Bit8u cur_col=CURSOR_POS_COL(page); @@ -474,12 +471,12 @@ void INT10_TeletypeOutputAttr(Bit8u chr,Bit8u attr,bool useattr) { void INT10_TeletypeOutput(Bit8u chr,Bit8u attr) { - INT10_TeletypeOutputAttr(chr,attr,CurMode->type>M_TEXT16); + INT10_TeletypeOutputAttr(chr,attr,CurMode->type!=M_TEXT); } void INT10_WriteString(Bit8u row,Bit8u col,Bit8u flag,Bit8u attr,PhysPt string,Bit16u count,Bit8u page) { //TODO Check if this page thing is correct - if (CurMode->type>M_TEXT16) page=0xff; + if (CurMode->type!=M_TEXT) page=0xff; if(page==0xFF) page=real_readb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAGE); BIOS_NCOLS;BIOS_NROWS; diff --git a/src/ints/int10_memory.cpp b/src/ints/int10_memory.cpp index ceb725f6..fc686fda 100644 --- a/src/ints/int10_memory.cpp +++ b/src/ints/int10_memory.cpp @@ -80,8 +80,10 @@ void INT10_SetupRomMemory(void) { PhysPt rom_base=PhysMake(0xc000,0); Bitu i; int10.rom.used=3; // int10.rom.used=2; Size of ROM added - phys_writew(rom_base+0,0xaa55); - phys_writeb(rom_base+2,0x40); // Size of ROM: 64 512-blocks = 32KB + if (machine==MCH_VGA) { + phys_writew(rom_base+0,0xaa55); + phys_writeb(rom_base+2,0x40); // Size of ROM: 64 512-blocks = 32KB + } int10.rom.font_8_first=RealMake(0xC000,int10.rom.used); for (i=0;i<128*8;i++) { phys_writeb(rom_base+int10.rom.used++,int10_font_08[i]); diff --git a/src/ints/int10_misc.cpp b/src/ints/int10_misc.cpp index 3afefc06..b6a25ec9 100644 --- a/src/ints/int10_misc.cpp +++ b/src/ints/int10_misc.cpp @@ -91,10 +91,8 @@ void INT10_GetFuncStateInformation(PhysPt save) { mem_writeb(save+0x25,real_readb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX)); Bit16u col_count=0; switch (CurMode->type) { - case M_TEXT16: + case M_TEXT: col_count=16;break; - case M_TEXT2: - col_count=2;break; // ?? case M_CGA2: col_count=2;break; case M_CGA4: diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index d0a4d475..afb07a62 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -5,6 +5,7 @@ #include "inout.h" #include "int10.h" #include "mouse.h" +#include "vga.h" #define _EGA_HALF_CLOCK 0x0001 #define _EGA_LINE_DOUBLE 0x0002 @@ -13,41 +14,55 @@ #define GFX_REGS 0x09 #define ATT_REGS 0x15 -VideoModeBlock ModeList[]={ -/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde ,rate,special flags */ -{ 0x000 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,70 ,_EGA_HALF_CLOCK }, -{ 0x001 ,M_TEXT16 ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,70 ,_EGA_HALF_CLOCK }, -{ 0x002 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, -{ 0x003 ,M_TEXT16 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, -{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,60 ,0 }, -{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,60 ,0}, -{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,100 ,449 ,80 ,400 ,60 ,0 }, -{ 0x007 ,M_TEXT2 ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,70 ,0 }, -/* 8,9,0xa are tandy modes */ -{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,100 ,449 ,80 ,400 ,60 ,0}, - -{ 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,70 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, -{ 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,70 ,_EGA_LINE_DOUBLE }, -{ 0x00F ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,70 ,0 },/*was EGA_2*/ -{ 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,70 ,0 }, -{ 0x011 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,70 ,0 },/*was EGA_2 */ -{ 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,70 ,0 }, -{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,70 ,0 }, +VideoModeBlock ModeList_VGA[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde special flags */ +{ 0x000 ,M_TEXT ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x001 ,M_TEXT ,320 ,400 ,40 ,25 ,9 ,16 ,8 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x002 ,M_TEXT ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x003 ,M_TEXT ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB8000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK }, +{ 0x007 ,M_TEXT ,640 ,400 ,80 ,25 ,9 ,16 ,4 ,0xB0000 ,0x1000 ,100 ,449 ,80 ,400 ,0 }, -{ 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 ,0 }, -{ 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 ,0 }, -{ 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,70 ,0 }, +{ 0x00D ,M_EGA16 ,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xA0000 ,0x2000 ,50 ,449 ,40 ,400 ,_EGA_HALF_CLOCK | _EGA_LINE_DOUBLE }, +{ 0x00E ,M_EGA16 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xA0000 ,0x4000 ,100 ,449 ,80 ,400 ,_EGA_LINE_DOUBLE }, +{ 0x00F ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,2 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,400 ,0 },/*was EGA_2*/ +{ 0x010 ,M_EGA16 ,640 ,350 ,80 ,25 ,8 ,14 ,1 ,0xA0000 ,0x8000 ,100 ,449 ,80 ,350 ,0 }, +{ 0x011 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,449 ,80 ,480 ,0 },/*was EGA_2 */ +{ 0x012 ,M_EGA16 ,640 ,480 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0xA000 ,100 ,525 ,80 ,480 ,0 }, +{ 0x013 ,M_VGA ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x0000 ,100 ,449 ,80 ,400 ,0 }, +{ 0x100 ,M_LIN8 ,640 ,400 ,80 ,25 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,0 }, +{ 0x101 ,M_LIN8 ,640 ,480 ,80 ,30 ,8 ,16 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,0 }, +{ 0x103 ,M_LIN8 ,800 ,600 ,100,37 ,8 ,16 ,1 ,0xA0000 ,0x10000,128 ,663 ,100,600 ,0 }, -{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 , 0}, -{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 , 0}, -{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 ,70 , 0 }, -{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 ,70 , 0 }, - -{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 ,0 }, +{ 0x150 ,M_LIN8 ,320 ,200 ,40 ,25 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , 0}, +{ 0x151 ,M_LIN8 ,320 ,240 ,40 ,30 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , 0}, +{ 0x152 ,M_LIN8 ,320 ,400 ,40 ,50 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,449 ,80 ,400 , 0 }, +{ 0x153 ,M_LIN8 ,320 ,480 ,40 ,60 ,8 ,8 ,1 ,0xA0000 ,0x10000,100 ,525 ,80 ,480 , 0 }, +{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, }; +VideoModeBlock ModeList_OTHER[]={ +/* mode ,type ,sw ,sh ,tw ,th ,cw,ch ,pt,pstart ,plength,htot,vtot,hde,vde ,special flags */ +{ 0x000 ,M_TEXT ,320 ,400 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x0800 ,56 ,31 ,40 ,25 ,0 }, +{ 0x001 ,M_TEXT ,320 ,400 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x0800 ,56 ,31 ,40 ,25 ,0 }, +{ 0x002 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x1000 ,113 ,31 ,80 ,25 ,0 }, +{ 0x003 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x1000 ,113 ,31 ,80 ,25 ,0 }, +{ 0x004 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,56 ,127 ,40 ,100 ,0 }, +{ 0x005 ,M_CGA4 ,320 ,200 ,40 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,56 ,127 ,40 ,100 ,0 }, +{ 0x006 ,M_CGA2 ,640 ,200 ,80 ,25 ,8 ,8 ,4 ,0xB8000 ,0x0800 ,56 ,127 ,40 ,100 ,0 }, +{ 0x008 ,M_TANDY16,160 ,200 ,20 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,56 ,127 ,40 ,100 ,0 }, +{ 0x009 ,M_TANDY16,320 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 }, +{ 0x00A ,M_CGA4 ,640 ,200 ,40 ,25 ,8 ,8 ,8 ,0xB8000 ,0x2000 ,113 ,63 ,80 ,50 ,0 }, +{0xFFFF ,M_ERROR ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0x00000 ,0x0000 ,0 ,0 ,0 ,0 ,0 }, +}; + +VideoModeBlock Hercules_Mode= +{ 0x007 ,M_TEXT ,640 ,400 ,80 ,25 ,8 ,14 ,4 ,0xB0000 ,0x1000 ,97 ,25 ,80 ,25 ,0 }; + static Bit8u text_palette[64][3]= { {0x00,0x00,0x00},{0x00,0x00,0x2a},{0x00,0x2a,0x00},{0x00,0x2a,0x2a},{0x2a,0x00,0x00},{0x2a,0x00,0x2a},{0x2a,0x2a,0x00},{0x2a,0x2a,0x2a}, @@ -72,18 +87,10 @@ static Bit8u ega_palette[64][3]= {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f} }; -#if 0 -static Bit8u cga_palette[64][3]= { - {0x00,0x00,0x00}, {0x00,0x00,0x1f}, {0x00,0x1f,0x00}, {0x00,0x1f,0x1f}, {0x1f,0x00,0x00}, {0x1f,0x00,0x1f}, {0x1f,0x1f,0x00}, {0x1f,0x1f,0x1f}, - {0x0f,0x0f,0x0f}, {0x00,0x00,0x3f}, {0x00,0x3f,0x00}, {0x00,0x3f,0x3f}, {0x3f,0x00,0x00}, {0x3f,0x00,0x3f}, {0x3f,0x3f,0x00}, {0x3f,0x3f,0x3f}, -}; -#else static Bit8u cga_palette[16][3]= { {0x00,0x00,0x00}, {0x00,0x00,0x2a}, {0x00,0x2a,0x00}, {0x00,0x2a,0x2a}, {0x2a,0x00,0x00}, {0x2a,0x00,0x2a}, {0x2a,0x15,0x00}, {0x2a,0x2a,0x2a}, {0x15,0x15,0x15}, {0x15,0x15,0x3f}, {0x15,0x3f,0x15}, {0x15,0x3f,0x3f}, {0x3f,0x15,0x15}, {0x3f,0x15,0x3f}, {0x3f,0x3f,0x15}, {0x3f,0x3f,0x3f}, }; -#endif - static Bit8u vga_palette[256][3]= { @@ -126,31 +133,205 @@ static Bit8u vga_palette[256][3]= VideoModeBlock * CurMode; -bool INT10_SetVideoMode(Bitu mode) { - - - bool clearmem=true; - Bit8u modeset_ctl,video_ctl,vga_switches; - - if (mode<256) { - if (mode & 128) { - clearmem=false; - mode-=128; - } - } else { - /* Check for special vesa mode bits */ - mode&=0xfff; - } - LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); +static bool SetCurMode(VideoModeBlock modeblock[],Bitu mode) { Bitu i=0; - while (ModeList[i].mode!=0xffff) { - if (ModeList[i].mode==mode) goto foundmode; + while ( modeblock[i].mode!=0xffff) { + if ( modeblock[i].mode==mode) goto foundmode; i++; } - LOG(LOG_INT10,LOG_ERROR)("Trying to set illegal mode %X",mode); return false; foundmode: - CurMode=&ModeList[i]; + CurMode=&modeblock[i]; + return true; +} + + +static void FinishSetMode(bool clearmem) { + Bitu i; + /* Clear video memory if needs be */ + if (clearmem) { + switch (CurMode->type) { + case M_CGA4: + case M_CGA2: + for (i=0;i<16*1024;i++) { + real_writew(0xb800,i*2,0x0000); + } + break; + case M_TEXT: + if (CurMode->mode==7) for (i=0;i<16*1024;i++) { + real_writew(0xb000,i*2,0x0120); + } else for (i=0;i<16*1024;i++) { + real_writew(0xb800,i*2,0x0720); + } + break; + case M_EGA16: + case M_VGA: + case M_LIN8: + /* Just clear the whole 2 mb of memory */ + for (i=0;i<2*1024*1024/4;i++) { + mem_writed(S3_LFB_BASE+i*4,0); + } + } + } + /* Setup the BIOS */ + if (CurMode->mode<128) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,CurMode->mode); + else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,CurMode->mode-0x98); //Looks like the s3 bios + real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,CurMode->twidth); + real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,CurMode->plength); + real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,CurMode->mode==7 ? 0x3b4 : 0x3d4); + real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight-1); + real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,CurMode->cheight); + real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem << 7))); + real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); + real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); + + // FIXME We nearly have the good tables. to be reworked + real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now + real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER,0x00); + real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2,0x00); + + // Set cursor shape + if(CurMode->type==M_TEXT) { + INT10_SetCursorShape(0x06,07); + } + // Set cursor pos for page 0..7 + for(i=0;i<8;i++) INT10_SetCursorPos(0,0,(Bit8u)i); + // Set active page 0 + INT10_SetActivePage(0); + /* Set some interrupt vectors */ + switch (CurMode->cheight) { + case 8:RealSetVec(0x43,int10.rom.font_8_first);break; + case 14:RealSetVec(0x43,int10.rom.font_14);break; + case 16:RealSetVec(0x43,int10.rom.font_16);break; + } + /* Tell mouse resolution change */ + Mouse_NewVideoMode(); +} + +bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) { + Bitu i; + switch (machine) { + case MCH_CGA: + if (mode>6) return false; + case MCH_TANDY: + if (mode>0xa) return false; + if (!SetCurMode(ModeList_OTHER,mode)) { + LOG(LOG_INT10,LOG_ERROR)("Trying to set illegal mode %X",mode); + return false; + } + break; + case MCH_HERC: + if (mode!=7) return false; + CurMode=&Hercules_Mode; + break; + } + LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); + + /* Setup the VGA to the correct mode */ +// VGA_SetMode(CurMode->type); + /* Setup the CRTC */ + Bitu crtc_base=machine==MCH_HERC ? 0x3b4 : 0x3d4; + //Horizontal total + IO_WriteW(crtc_base,0x00 | (CurMode->htotal) << 8); + //Horizontal displayed + IO_WriteW(crtc_base,0x01 | (CurMode->hdispend) << 8); + //Horizontal sync position + IO_WriteW(crtc_base,0x02 | (CurMode->hdispend+1) << 8); + //Horizontal sync width, seems to be fixed to 0xa, for cga at least, hercules has 0xf + IO_WriteW(crtc_base,0x03 | (0xa) << 8); + ////Vertical total + IO_WriteW(crtc_base,0x04 | (CurMode->vtotal) << 8); + //Vertical total adjust, 6 for cga,hercules,tandy + IO_WriteW(crtc_base,0x05 | (6) << 8); + //Vertical displayed + IO_WriteW(crtc_base,0x06 | (CurMode->vdispend) << 8); + //Vertical sync position + IO_WriteW(crtc_base,0x07 | (CurMode->vdispend+1) << 8); + //Maximum scanline + Bit8u scanline; + switch(CurMode->type) { + case M_TEXT: + if (machine==MCH_HERC) scanline=14; + else scanline=8; + break; + case M_CGA2: + scanline=2; + case M_CGA4: + if (CurMode->mode!=0xa) scanline=2; + else scanline=4; + case M_TANDY16: + if (CurMode->mode!=0x9) scanline=2; + else scanline=4; + break; + } + IO_WriteW(crtc_base,0x09 | (scanline-1) << 8); + //Setup the CGA palette using VGA DAC palette + for (i=0;i<16;i++) VGA_DAC_SetEntry(i,cga_palette[i][0],cga_palette[i][1],cga_palette[i][2]); + //Setup the tandy palette + for (i=0;i<16;i++) VGA_DAC_CombineColor(i,i); + //Setup the special registers for each machine type + Bit8u mode_control_list[0xa+1]={ + 0x2c,0x28,0x2d,0x29, //0-3 + 0x2a,0x2e,0x1e,0x29, //4-7 + 0x2a,0x2b,0x3b //8-a + }; + Bit8u mode_control,color_select; + switch (machine) { + case MCH_HERC: + IO_WriteB(0x3bf,0x3); //Enable changing all bits + IO_WriteB(0x3b8,0x8); //TEXT mode and non-blinking characters + IO_WriteB(0x3bf,0x0); //Disable changing all bits + VGA_DAC_CombineColor(1,0xf); + break; + case MCH_CGA: + mode_control=mode_control_list[CurMode->mode]; + if (CurMode->mode == 0x6) color_select=0x3f; + else color_select=0x30; + IO_WriteB(0x3d8,mode_control); + IO_WriteB(0x3d9,color_select); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,mode_control); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); + break; + case MCH_TANDY: + /* Init some registers */ + IO_WriteB(0x3da,0x1);IO_WriteB(0x3de,0xf); //Palette mask always 0xf + IO_WriteB(0x3da,0x2);IO_WriteB(0x3de,0x0); //block border + IO_WriteB(0x3da,0x3); //Tandy color overrides? + switch (CurMode->mode) { + case 0x8: case 0x9: + IO_WriteB(0x3de,0x14);break; + case 0xa: + IO_WriteB(0x3de,0x0c);break; + default: + IO_WriteB(0x3de,0x0);break; + } + mode_control=mode_control_list[CurMode->mode]; + if (CurMode->mode == 0x6 || CurMode->mode==0xa) color_select=0x3f; + else color_select=0x30; + IO_WriteB(0x3d8,mode_control); + IO_WriteB(0x3d9,color_select); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,mode_control); + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); + break; + } + FinishSetMode(clearmem); + return true; +} + + +bool INT10_SetVideoMode(Bitu mode) { + bool clearmem=true;Bitu i; + if ((mode<256) && (mode & 128)) { + clearmem=false; + mode-=128; + } + LOG(LOG_INT10,LOG_NORMAL)("Set Video Mode %X",mode); + if (machine!=MCH_VGA) return INT10_SetVideoMode_OTHER(mode,clearmem); + Bit8u modeset_ctl,video_ctl,vga_switches; + if (!SetCurMode(ModeList_VGA,mode)){ + LOG(LOG_INT10,LOG_ERROR)("Trying to set illegal mode %X",mode); + return false; + } /* First read mode setup settings from bios area */ video_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL); @@ -158,15 +339,12 @@ foundmode: modeset_ctl=real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL); /* Setup the VGA to the correct mode */ - VGA_SetMode(CurMode->type); +// VGA_SetMode(CurMode->type); Bit16u crtc_base; - bool mono_mode=CurMode->type == M_TEXT2; - if (mono_mode) { - crtc_base=0x3b4; - } else { - crtc_base=0x3d4; - } + bool mono_mode=(CurMode->type == M_TEXT && machine==MCH_HERC); + if (mono_mode) crtc_base=0x3b4; + else crtc_base=0x3d4; /* Setup MISC Output Register */ Bit8u misc_output=0x2 | (mono_mode ? 0x0 : 0x1); IO_Write(0x3c2,misc_output); //Setup for 3b4 or 3d4 @@ -178,8 +356,7 @@ foundmode: (CurMode->special & _EGA_HALF_CLOCK) ? 0x08 : 0x00; seq_data[4]|=0x02; //More than 64kb switch (CurMode->type) { - case M_TEXT2: - case M_TEXT16: + case M_TEXT: seq_data[2]|=0x3; //Enable plane 0 and 1 seq_data[4]|=0x05; //Alpanumeric and odd/even enabled break; @@ -223,28 +400,17 @@ foundmode: blank_end = (CurMode->htotal-2) & 0x7f; } IO_Write(crtc_base,0x03);IO_Write(crtc_base+1,0x80|(blank_end & 0x1f)); -// hor_overflow|=(blank_end & 0x40) >> 3; - /* Start Horizontal Retrace */ Bitu ret_start; - if (CurMode->special & _EGA_HALF_CLOCK) { - ret_start = (CurMode->hdispend+2); - } else { - ret_start = (CurMode->hdispend+4); - } + if (CurMode->special & _EGA_HALF_CLOCK) ret_start = (CurMode->hdispend+2); + else ret_start = (CurMode->hdispend+4); IO_Write(crtc_base,0x04);IO_Write(crtc_base+1,ret_start); hor_overflow|=(ret_start & 0x100) >> 4; /* End Horizontal Retrace */ Bitu ret_end; - if (CurMode->special & _EGA_HALF_CLOCK) { - ret_end = (CurMode->htotal-2) & 0x3f; - } else { - ret_end = (CurMode->htotal-4) & 0x3f; - } + if (CurMode->special & _EGA_HALF_CLOCK) ret_end = (CurMode->htotal-2) & 0x3f; + else ret_end = (CurMode->htotal-4) & 0x3f; IO_Write(crtc_base,0x05);IO_Write(crtc_base+1,(ret_end & 0x1f) | (blank_end & 0x20) << 2); -// hor_overflow|=(ret_end & 0x20); -//TODO Be sure about these ending values in extended overflow of s3 - /* Vertical Total */ IO_Write(crtc_base,0x06);IO_Write(crtc_base+1,(CurMode->vtotal-2)); overflow|=((CurMode->vtotal-2) & 0x100) >> 8; @@ -286,8 +452,7 @@ foundmode: /* Maximum scanline / Underline Location */ if (CurMode->special & _EGA_LINE_DOUBLE) max_scanline|=0x80; switch (CurMode->type) { - case M_TEXT2: - case M_TEXT16: + case M_TEXT: max_scanline|=CurMode->cheight-1; underline=0x1f; break; @@ -297,7 +462,6 @@ foundmode: break; case M_LIN8: underline=0x60; //Seems to enable the every 4th clock on my s3 -// if (CurMode->special & _VGA_LINE_DOUBLE) max_scanline|=1; break; } IO_Write(crtc_base,0x09);IO_Write(crtc_base+1,max_scanline); @@ -328,8 +492,7 @@ foundmode: case M_EGA16: mode_control=0xe3; break; - case M_TEXT2: - case M_TEXT16: + case M_TEXT: case M_VGA: mode_control=0xa3; break; @@ -342,16 +505,9 @@ foundmode: IO_Write(crtc_base,0x11); IO_Write(crtc_base+1,IO_Read(crtc_base+1)|0x80); /* Setup the correct clock */ - switch (CurMode->type) { - case M_VGA: - case M_TEXT2: - case M_TEXT16: - case M_EGA16: - //Stick to 25mhz clock for now - break; - default: + if (CurMode->mode>=0x100) { misc_output|=0xef; //Select clock 3 - Bitu clock=CurMode->vtotal*8*CurMode->htotal*CurMode->rate; + Bitu clock=CurMode->vtotal*8*CurMode->htotal*70; VGA_SetClock(3,clock/1000); } /* Write Misc Output */ @@ -363,13 +519,9 @@ foundmode: gfx_data[0x7]=0xf; /* Color don't care */ gfx_data[0x8]=0xff; /* BitMask */ switch (CurMode->type) { - case M_TEXT2: + case M_TEXT: gfx_data[0x5]|=0x10; //Odd-Even Mode - gfx_data[0x6]|=0x0a; //alphanumeric mode at 0xb000=0x7fff - break; - case M_TEXT16: - gfx_data[0x5]|=0x10; //Odd-Even Mode - gfx_data[0x6]|=0x0e; //alphanumeric mode at 0xb800=0xbfff + gfx_data[0x6]|=mono_mode ? 0x0a : 0x0e; //Either b800 or b000 break; case M_LIN8: case M_VGA: @@ -393,7 +545,7 @@ foundmode: Bit8u att_data[ATT_REGS]; memset(att_data,0,ATT_REGS); att_data[0x12]=0xf; //Always have all color planes enabled - /* Porgram Attribute Controller */ + /* Program Attribute Controller */ switch (CurMode->type) { case M_EGA16: if (CurMode->mode>0xe) goto att_text16; @@ -401,15 +553,13 @@ foundmode: att_data[i]=i; att_data[i+8]=i+0x10; } + att_data[0x10]=0x01; //Color Graphics break; case M_TANDY16: att_data[0x10]=0x01; //Color Graphics - for (i=0;i<16;i++) { - att_data[i]=i; - } + for (i=0;i<16;i++) att_data[i]=i; break; - case M_TEXT2: - case M_TEXT16: + case M_TEXT: att_data[0x13]=0x08; //Pel panning on 8, although we don't have 9 dot text mode att_data[0x10]=0x0C; //Color Text with blinking att_text16: @@ -419,30 +569,31 @@ att_text16: } break; case M_CGA2: - IO_Write(0x3d9,0x7); //Setup using CGA color select register - real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x7); - goto skipatt; + att_data[0x10]=0x01; //Color Graphics + att_data[0]=0x0; + att_data[1]=0xf; + att_data[0x12]=0x1; //Only enable 1 plane + real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x3f); + break; case M_CGA4: - //Set Bit 2 in black/white mode 0x5 - IO_Write(0x3d8,0xa+(CurMode->mode==0x5) ? 0x4 : 0); - IO_Write(0x3d9,0x30); //Setup using CGA color select register + att_data[0x10]=0x01; //Color Graphics + att_data[0]=0x0; + att_data[1]=0x3; + att_data[2]=0x5; + att_data[3]=0x7; real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,0x30); - goto skipatt; + break; case M_VGA: case M_LIN8: - for (i=0;i<16;i++) { - att_data[i]=i; - } + for (i=0;i<16;i++) att_data[i]=i; att_data[0x10]=0x41; //Color Graphics 8-bit break; } - IO_Read(mono_mode ? 0x3ba : 0x3da); for (i=0;itype) { @@ -463,8 +614,7 @@ skipatt: IO_Write(0x3c9,cga_palette[i][2]); } break; - case M_TEXT2: - case M_TEXT16: + case M_TEXT: dac_text16: for (i=0;i<64;i++) { IO_Write(0x3c9,text_palette[i][0]); @@ -486,22 +636,16 @@ dac_text16: switch (CurMode->type) { case M_CGA2: feature=(feature&~0x30)|0x20; - IO_Write(0x3d8,0x12); //Setup using CGA color select register real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x12); break; case M_CGA4: feature=(feature&~0x30)|0x20; - IO_Write(0x3d8,0x2); //Setup using CGA color select register real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,0x2); break; case M_TANDY16: feature=(feature&~0x30)|0x20; - IO_Write(0x3df,0x80); //Enter 32k mode and banks on 0 break; - case M_TEXT2: - feature=(feature&~0x30)|0x30; - break; - case M_TEXT16: + case M_TEXT: feature=(feature&~0x30)|0x20; break; case M_EGA16: @@ -527,70 +671,10 @@ dac_text16: IO_Write(crtc_base,0x39);IO_Write(crtc_base+1,0xa5); //Register lock 2 /* Load text mode font */ - if (CurMode->type<=M_TEXT16) { + if (CurMode->type==M_TEXT) { INT10_LoadFont(Real2Phys(int10.rom.font_16),true,256,0,0,16); } - /* Clear video memory if needs be */ - if (clearmem) { - switch (CurMode->type) { - case M_CGA4: - case M_CGA2: - for (i=0;i<16*1024;i++) { - real_writew(0xb800,i*2,0x0000); - } - break; - case M_TEXT2: - for (i=0;i<16*1024;i++) { - real_writew(0xb000,i*2,0x0120); - } - break; - case M_TEXT16: - for (i=0;i<16*1024;i++) { - real_writew(0xb800,i*2,0x0720); - } - break; - case M_EGA16: - case M_VGA: - case M_LIN8: - /* Just clear the whole 2 mb of memory */ - for (i=0;i<2*1024*1024/4;i++) { - mem_writed(S3_LFB_BASE+i*4,0); - } - } - } - /* Setup the BIOS */ - if (mode<128) real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode); - else real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MODE,mode-0x98); //Looks like the s3 bios - real_writew(BIOSMEM_SEG,BIOSMEM_NB_COLS,CurMode->twidth); - real_writew(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE,CurMode->plength); - real_writew(BIOSMEM_SEG,BIOSMEM_CRTC_ADDRESS,crtc_base); - real_writeb(BIOSMEM_SEG,BIOSMEM_NB_ROWS,CurMode->theight-1); - real_writew(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT,CurMode->cheight); - real_writeb(BIOSMEM_SEG,BIOSMEM_VIDEO_CTL,(0x60|(clearmem << 7))); - real_writeb(BIOSMEM_SEG,BIOSMEM_SWITCHES,0x09); - real_writeb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL,real_readb(BIOSMEM_SEG,BIOSMEM_MODESET_CTL)&0x7f); - - // FIXME We nearly have the good tables. to be reworked - real_writeb(BIOSMEM_SEG,BIOSMEM_DCC_INDEX,0x08); // 8 is VGA should be ok for now - real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER,0x00); - real_writew(BIOSMEM_SEG,BIOSMEM_VS_POINTER+2,0x00); - - // Set cursor shape - if(CurMode->type<=M_TEXT16) { - INT10_SetCursorShape(0x06,07); - } - // Set cursor pos for page 0..7 - for(i=0;i<8;i++) INT10_SetCursorPos(0,0,(Bit8u)i); - // Set active page 0 - INT10_SetActivePage(0); - /* Set some interrupt vectors */ - switch (CurMode->cheight) { - case 8:RealSetVec(0x43,int10.rom.font_8_first);break; - case 14:RealSetVec(0x43,int10.rom.font_14);break; - case 16:RealSetVec(0x43,int10.rom.font_16);break; - } - /* Tell mouse resolution change */ - Mouse_NewVideoMode(); + FinishSetMode(clearmem); return true; } diff --git a/src/ints/int10_vesa.cpp b/src/ints/int10_vesa.cpp index 358c4e2b..64c9c13b 100644 --- a/src/ints/int10_vesa.cpp +++ b/src/ints/int10_vesa.cpp @@ -16,7 +16,7 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -/* $Id: int10_vesa.cpp,v 1.7 2004-01-11 09:27:52 harekiet Exp $ */ +/* $Id: int10_vesa.cpp,v 1.8 2004-02-29 22:18:24 harekiet Exp $ */ #include #include @@ -125,12 +125,12 @@ Bit8u VESA_GetSVGAModeInformation(Bit16u mode,Bit16u seg,Bit16u off) { Bitu i=0; if (mode<0x100) return 0x01; - while (ModeList[i].mode!=0xffff) { - if (mode==ModeList[i].mode) goto foundit; else i++; + while (ModeList_VGA[i].mode!=0xffff) { + if (mode==ModeList_VGA[i].mode) goto foundit; else i++; } return 0x01; foundit: - VideoModeBlock * mblock=&ModeList[i]; + VideoModeBlock * mblock=&ModeList_VGA[i]; switch (mblock->type) { case M_LIN8: //Linear 8-bit WLE(minfo.ModeAttributes,0x9b); @@ -310,9 +310,9 @@ void INT10_SetupVESA(void) { i=0; int10.rom.vesa_modes=RealMake(0xc000,int10.rom.used); //TODO Maybe add normal vga modes too, but only seems to complicate things - while (ModeList[i].mode!=0xffff) { - if (ModeList[i].mode>=0x100){ - phys_writew(PhysMake(0xc000,int10.rom.used),ModeList[i].mode); + while (ModeList_VGA[i].mode!=0xffff) { + if (ModeList_VGA[i].mode>=0x100){ + phys_writew(PhysMake(0xc000,int10.rom.used),ModeList_VGA[i].mode); int10.rom.used+=2; } i++;