diff --git a/include/vga.h b/include/vga.h index 2674aeee..abd1d296 100644 --- a/include/vga.h +++ b/include/vga.h @@ -356,6 +356,7 @@ extern Bit32u ExpandTable[256]; extern Bit32u FillTable[16]; extern Bit32u CGA_2_Table[16]; extern Bit32u CGA_4_Table[256]; +extern Bit32u CGA_4_HiRes_Table[256]; extern Bit32u CGA_16_Table[256]; extern Bit32u TXT_Font_Table[16]; extern Bit32u TXT_FG_Table[16]; diff --git a/src/hardware/vga.cpp b/src/hardware/vga.cpp index 67fa0ba1..d56735d2 100644 --- a/src/hardware/vga.cpp +++ b/src/hardware/vga.cpp @@ -26,6 +26,7 @@ VGA_Type vga; Bit32u CGA_2_Table[16]; Bit32u CGA_4_Table[256]; +Bit32u CGA_4_HiRes_Table[256]; Bit32u CGA_16_Table[256]; Bit32u TXT_Font_Table[16]; Bit32u TXT_FG_Table[16]; @@ -132,9 +133,18 @@ void VGA_SetCGA4Table(Bit8u val0,Bit8u val1,Bit8u val2,Bit8u val3) { #else (total[(i >> 6) & 3] << 0 ) | (total[(i >> 4) & 3] << 8 ) | (total[(i >> 2) & 3] << 16 ) | (total[(i >> 0) & 3] << 24 ); +#endif + CGA_4_HiRes_Table[i]= +#ifdef WORDS_BIGENDIAN + (total[((i >> 0) & 1) | ((i >> 3) & 2)] << 0 ) | (total[((i >> 1) & 1) | ((i >> 4) & 2)] << 8 ) | + (total[((i >> 2) & 1) | ((i >> 5) & 2)] << 16 ) | (total[((i >> 3) & 1) | ((i >> 6) & 2)] << 24 ); +#else + (total[((i >> 3) & 1) | ((i >> 6) & 2)] << 0 ) | (total[((i >> 2) & 1) | ((i >> 5) & 2)] << 8 ) | + (total[((i >> 1) & 1) | ((i >> 4) & 2)] << 16 ) | (total[((i >> 0) & 1) | ((i >> 3) & 2)] << 24 ); #endif } } + void VGA_Init(Section* sec) { vga.draw.resizing=false; vga.mode=M_ERROR; //For first init diff --git a/src/hardware/vga_draw.cpp b/src/hardware/vga_draw.cpp index fb54ce9c..b8f07a84 100644 --- a/src/hardware/vga_draw.cpp +++ b/src/hardware/vga_draw.cpp @@ -58,6 +58,20 @@ static Bit8u * VGA_Draw_2BPP_Line(Bitu vidstart,Bitu panning,Bitu line) { return TempLine; } +static Bit8u * VGA_Draw_2BPPHiRes_Line(Bitu vidstart,Bitu panning,Bitu line) { + line*=8*1024;Bit32u * draw=(Bit32u *)TempLine; + for (Bitu x=0;x<(vga.draw.blocks>>1);x++) { + Bitu val1=vga.mem.linear[vidstart+line]; + Bitu val2=vga.mem.linear[vidstart+1+line]; + vidstart+=2; + if((vga.crtc.mode_control & 0x01) == 0) // CGA compatible addressing + vidstart &= 0x1dfff; + *draw++=CGA_4_HiRes_Table[(val1>>4)|(val2&0xf0)]; + *draw++=CGA_4_HiRes_Table[(val1&0x0f)|((val2&0x0f)<<4)]; + } + return TempLine; +} + static Bitu temp[643]={0}; static Bit8u * VGA_Draw_CGA16_Line(Bitu vidstart,Bitu panning,Bitu line) { @@ -513,9 +527,12 @@ void VGA_SetupDrawing(Bitu val) { doubleheight=true; if (machine==MCH_TANDY) doublewidth=(vga.tandy.mode_control & 0x10)==0; else doublewidth=(vga.tandy.gfx_control & 0x8)==0x00; - vga.draw.blocks=width * (doublewidth ? 4:8); +// vga.draw.blocks=width * (doublewidth ? 4:8); + vga.draw.blocks=width * 4; width=vga.draw.blocks*2; - VGA_DrawLine=VGA_Draw_2BPP_Line; + if ((machine==MCH_TANDY && (vga.tandy.gfx_control & 0x8)) || + (machine==MCH_PCJR && (vga.tandy.mode_control==0x0b))) VGA_DrawLine=VGA_Draw_2BPPHiRes_Line; + else VGA_DrawLine=VGA_Draw_2BPP_Line; break; case M_TANDY16: aspect_ratio=1.2; diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 3453c73b..0d35895f 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -191,7 +191,8 @@ static void write_color_select(Bit8u val) { break; case M_TANDY4: { - if (IS_TANDY_ARCH && (vga.tandy.gfx_control & 0x8)) { + if ((machine==MCH_TANDY && (vga.tandy.gfx_control & 0x8)) || + (machine==MCH_PCJR && (vga.tandy.mode_control==0x0b))) { VGA_SetCGA4Table(0,1,2,3); return; } diff --git a/src/ints/int10_put_pixel.cpp b/src/ints/int10_put_pixel.cpp index 241d8d35..5992a059 100644 --- a/src/ints/int10_put_pixel.cpp +++ b/src/ints/int10_put_pixel.cpp @@ -28,16 +28,32 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { switch (CurMode->type) { case M_CGA4: { - Bit16u off=(y>>1)*80+(x>>2); - if (y&1) off+=8*1024; - Bit8u old=real_readb(0xb800,off); - if (color & 0x80) { - color&=3; - old^=color << (2*(3-(x&3))); + IO_Write(0x3d4,0x09); + if (IO_Read(0x3d5)==1) { + Bit16u off=(y>>1)*80+(x>>2); + if (y&1) off+=8*1024; + + Bit8u old=real_readb(0xb800,off); + if (color & 0x80) { + color&=3; + old^=color << (2*(3-(x&3))); + } else { + old=old&cga_masks[x&3]|((color&3) << (2*(3-(x&3)))); + } + real_writeb(0xb800,off,old); } else { - old=old&cga_masks[x&3]|((color&3) << (2*(3-(x&3)))); + Bit16u off=(y>>2)*160+((x>>2)&(~1)); + off+=(8*1024) * (y & 3); + + Bit16u old=real_readw(0xb800,off); + if (color & 0x80) { + old^=(color&1) << (7-(x&7)); + old^=((color&2)>>1) << ((7-(x&7))+8); + } else { + old=old&(~(0x101<<(7-(x&7)))) | ((color&1) << (7-(x&7))) | (((color&2)>>1) << ((7-(x&7))+8)); + } + real_writew(0xb800,off,old); } - real_writeb(0xb800,off,old); } break; case M_CGA2: @@ -56,8 +72,10 @@ void INT10_PutPixel(Bit16u x,Bit16u y,Bit8u page,Bit8u color) { break; case M_TANDY16: { - Bit16u off=(y>>2)*160+(x>>1); - off+=(8*1024) * (y & 3); + IO_Write(0x3d4,0x09); + Bit8u scanlines_m1=IO_Read(0x3d5); + Bit16u off=(y>>((scanlines_m1==1)?1:2))*(CurMode->swidth>>1)+(x>>1); + off+=(8*1024) * (y & scanlines_m1); Bit8u old=real_readb(0xb800,off); Bit8u p[2]; p[1] = (old >> 4) & 0xf;