diff --git a/src/hardware/vga_memory.cpp b/src/hardware/vga_memory.cpp index 9a3167ae..ecb2f5cd 100644 --- a/src/hardware/vga_memory.cpp +++ b/src/hardware/vga_memory.cpp @@ -700,6 +700,7 @@ public: // |PFLAG_NOCODE; } HostPt GetHostReadPt(Bitu phys_page) { + // Odd banks are limited to 16kB and repeated if (vga.tandy.mem_bank & 1) phys_page&=0x03; else @@ -719,9 +720,9 @@ public: } HostPt GetHostReadPt(Bitu phys_page) { phys_page-=0xb8; - //test for a unaliged bank, then replicate 2x16kb - if (vga.tandy.mem_bank & 1) - phys_page&=0x03; + // The 16kB map area is repeated in the 32kB range + // On CGA CPU A14 is not decoded so it repeats there too + phys_page&=0x03; return vga.tandy.mem_base + (phys_page * 4096); } HostPt GetHostWritePt(Bitu phys_page) { diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 61f92be4..51b98ed3 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -83,7 +83,9 @@ static void write_crtc_data_other(Bitu /*port*/,Bitu val,Bitu /*iolen*/) { vga.draw.cursor.eline = (Bit8u)(val&0x1f); break; case 0x0C: /* Start Address High Register */ - vga.config.display_start=(vga.config.display_start & 0x00FF) | (val << 8); + // Bit 12 (depending on video mode) and 13 are actually masked too, + // but so far no need to implement it. + vga.config.display_start=(vga.config.display_start & 0x00FF) | ((val&0x3F) << 8); break; case 0x0D: /* Start Address Low Register */ vga.config.display_start=(vga.config.display_start & 0xFF00) | val; @@ -491,10 +493,18 @@ static void write_tandy(Bitu port,Bitu val,Bitu /*iolen*/) { write_tandy_reg((Bit8u)val); break; case 0x3df: + // CRT/processor page register + // See the comments on the PCJr version of this register. + // A difference to it is: + // Bit 3-5: Processor page CPU_PG + // The remapped range is 32kB instead of 16. Therefore CPU_PG bit 0 + // appears to be ORed with CPU A14 (to preserve some sort of + // backwards compatibility?), resulting in odd pages being mapped + // as 2x16kB. Implemeted in vga_memory.cpp Tandy handler. + vga.tandy.line_mask = (Bit8u)(val >> 6); vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); - if(vga.tandy.line_mask==3) vga.tandy.draw_bank &= ~1; // LSB unused in 32k modes - vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); + vga.tandy.mem_bank = (val >> 3) & 7; TandyCheckLineMask(); VGA_SetupHandlers(); break; @@ -514,9 +524,38 @@ static void write_pcjr(Bitu port,Bitu val,Bitu /*iolen*/) { vga.tandy.pcjr_flipflop=!vga.tandy.pcjr_flipflop; break; case 0x3df: + // CRT/processor page register + + // Bit 0-2: CRT page PG0-2 + // In one- and two bank modes, bit 0-2 select the 16kB memory + // area of system RAM that is displayed on the screen. + // In 4-banked modes, bit 1-2 select the 32kB memory area. + // Bit 2 only has effect when the PCJR upgrade to 128k is installed. + + // Bit 3-5: Processor page CPU_PG + // Selects the 16kB area of system RAM that is mapped to + // the B8000h IBM PC video memory window. Since A14-A16 of the + // processor are unconditionally replaced with these bits when + // B8000h is accessed, the 16kB area is mapped to the 32kB + // range twice in a row. (Scuba Venture writes across the boundary) + + // Bit 6-7: Video Address mode + // 0: CRTC addresses A0-12 directly, accessing 8k characters + // (+8k attributes). Used in text modes (one bank). + // PG0-2 in effect. 16k range. + // 1: CRTC A12 is replaced with CRTC RA0 (see max_scanline). + // This results in the even/odd scanline two bank system. + // PG0-2 in effect. 16k range. + // 2: Documented as unused. CRTC addresses A0-12, PG0 is replaced + // with RA1. Looks like nonsense. + // PG1-2 in effect. 32k range which cannot be used completely. + // 3: CRTC A12 is replaced with CRTC RA0, PG0 is replaced with + // CRTC RA1. This results in the 4-bank mode. + // PG1-2 in effect. 32k range. + vga.tandy.line_mask = (Bit8u)(val >> 6); vga.tandy.draw_bank = val & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); - vga.tandy.mem_bank = (val >> 3) & ((vga.tandy.line_mask&2) ? 0x6 : 0x7); + vga.tandy.mem_bank = (val >> 3) & 7; vga.tandy.draw_base = &MemBase[vga.tandy.draw_bank * 16 * 1024]; vga.tandy.mem_base = &MemBase[vga.tandy.mem_bank * 16 * 1024]; TandyCheckLineMask(); @@ -674,6 +713,9 @@ void VGA_SetupOther(void) { write_pcjr( 0x3df, 0x7 | (0x7 << 3), 0 ); IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB); IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB); + // additional CRTC access documented + IO_RegisterWriteHandler(0x3d0,write_crtc_index_other,IO_MB); + IO_RegisterWriteHandler(0x3d1,write_crtc_data_other,IO_MB); } if (machine==MCH_HERC) { Bitu base=0x3b0;