From ffe3c5ab7fb5e28bae78f07ea987904f391a7cf8 Mon Sep 17 00:00:00 2001 From: VileRancour Date: Thu, 15 May 2003 11:45:38 +0200 Subject: [PATCH] Add cga_mono machine Emulates the user using a CGA card with a monochrome monitor. Monochrome monitor options are: green, amber, white or paperwhite. The color can be changed at runtime with F11. Include paperwhite color by Basic https://www.vogons.org/viewtopic.php?p=587382#p587382 Vogons thread: https://www.vogons.org/viewtopic.php?f=41&t=29101 Signed-off-by: Michael Zijlstra Signed-off-by: Patryk Obara Imported-from: https://www.vogons.org/viewtopic.php?p=238045#p238045 --- include/dosbox.h | 1 + include/vga.h | 3 ++ src/dosbox.cpp | 7 +++- src/hardware/vga_other.cpp | 83 ++++++++++++++++++++++++++++++++++---- src/ints/int10_modes.cpp | 1 + src/shell/shell.cpp | 8 +++- 6 files changed, 93 insertions(+), 10 deletions(-) diff --git a/include/dosbox.h b/include/dosbox.h index 2816f250..5b95407d 100644 --- a/include/dosbox.h +++ b/include/dosbox.h @@ -62,6 +62,7 @@ enum SVGACards { extern SVGACards svgaCard; extern MachineType machine; extern bool SDLNetInited; +extern bool mono_cga; #define IS_TANDY_ARCH ((machine==MCH_TANDY) || (machine==MCH_PCJR)) #define IS_EGAVGA_ARCH ((machine==MCH_EGA) || (machine==MCH_VGA)) diff --git a/include/vga.h b/include/vga.h index e204105b..b4e637aa 100644 --- a/include/vga.h +++ b/include/vga.h @@ -413,6 +413,9 @@ typedef struct { /* Hercules Palette function */ void Herc_Palette(void); +/* CGA Mono Palette function */ +void Mono_CGA_Palette(void); + /* Functions for different resolutions */ void VGA_SetMode(VGAModes mode); void VGA_DetermineMode(void); diff --git a/src/dosbox.cpp b/src/dosbox.cpp index 44f95515..33e39635 100644 --- a/src/dosbox.cpp +++ b/src/dosbox.cpp @@ -130,6 +130,8 @@ Bit32u ticksScheduled; bool ticksLocked; void increaseticks(); +bool mono_cga=false; + static Bitu Normal_Loop(void) { Bits ret; while (1) { @@ -364,7 +366,8 @@ static void DOSBOX_RealInit(Section * sec) { machine = MCH_VGA; int10.vesa_nolfb = false; int10.vesa_oldvbe = false; - if (mtype == "cga") { machine = MCH_CGA; } + if (mtype == "cga") { machine = MCH_CGA; mono_cga = false; } + else if (mtype == "cga_mono") { machine = MCH_CGA; mono_cga = true; } else if (mtype == "tandy") { machine = MCH_TANDY; } else if (mtype == "pcjr") { machine = MCH_PCJR; } else if (mtype == "hercules") { machine = MCH_HERC; } @@ -403,7 +406,7 @@ void DOSBOX_Init(void) { /* Setup all the different modules making up DOSBox */ const char* machines[] = { - "hercules", "cga", "tandy", "pcjr", "ega", + "hercules", "cga", "cga_mono", "tandy", "pcjr", "ega", "vgaonly", "svga_s3", "svga_et3000", "svga_et4000", "svga_paradise", "vesa_nolfb", "vesa_oldvbe", 0 }; secprop=control->AddSection_prop("dosbox",&DOSBOX_RealInit); diff --git a/src/hardware/vga_other.cpp b/src/hardware/vga_other.cpp index 63be10a6..e9ca7af8 100644 --- a/src/hardware/vga_other.cpp +++ b/src/hardware/vga_other.cpp @@ -182,6 +182,43 @@ static bool new_cga = 0; static Bit8u cga16_val = 0; static void update_cga16_color(void); static Bit8u herc_pal = 0; +static Bit8u mono_cga_pal = 0; +static Bit8u mono_cga_bright = 0; +static Bit8u mono_cga_palettes[8][16][3] = +{ + { // 0 - green, 4-color-optimized contrast + {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x17,0x05},{0x01,0x1a,0x06},{0x02,0x28,0x09},{0x02,0x2c,0x0a},{0x03,0x39,0x0d},{0x03,0x3c,0x0e}, + {0x00,0x07,0x01},{0x01,0x13,0x04},{0x01,0x1f,0x07},{0x01,0x23,0x08},{0x02,0x31,0x0b},{0x02,0x35,0x0c},{0x05,0x3f,0x11},{0x0d,0x3f,0x17}, + }, + { // 1 - green, 16-color-optimized contrast + {0x00,0x00,0x00},{0x00,0x0d,0x03},{0x01,0x15,0x05},{0x01,0x17,0x05},{0x01,0x21,0x08},{0x01,0x24,0x08},{0x02,0x2e,0x0b},{0x02,0x31,0x0b}, + {0x01,0x22,0x08},{0x02,0x28,0x09},{0x02,0x30,0x0b},{0x02,0x32,0x0c},{0x03,0x39,0x0d},{0x03,0x3b,0x0e},{0x09,0x3f,0x14},{0x0d,0x3f,0x17}, + }, + { // 2 - amber, 4-color-optimized contrast + {0x00,0x00,0x00},{0x15,0x05,0x00},{0x20,0x0b,0x00},{0x24,0x0d,0x00},{0x33,0x18,0x00},{0x37,0x1b,0x00},{0x3f,0x26,0x01},{0x3f,0x2b,0x06}, + {0x0b,0x02,0x00},{0x1b,0x08,0x00},{0x29,0x11,0x00},{0x2e,0x14,0x00},{0x3b,0x1e,0x00},{0x3e,0x21,0x00},{0x3f,0x32,0x0a},{0x3f,0x38,0x0d}, + }, + { // 3 - amber, 16-color-optimized contrast + {0x00,0x00,0x00},{0x15,0x05,0x00},{0x1e,0x09,0x00},{0x21,0x0b,0x00},{0x2b,0x12,0x00},{0x2f,0x15,0x00},{0x38,0x1c,0x00},{0x3b,0x1e,0x00}, + {0x2c,0x13,0x00},{0x32,0x17,0x00},{0x3a,0x1e,0x00},{0x3c,0x1f,0x00},{0x3f,0x27,0x01},{0x3f,0x2a,0x04},{0x3f,0x36,0x0c},{0x3f,0x38,0x0d}, + }, + { // 4 - grey, 4-color-optimized contrast + {0x00,0x00,0x00},{0x0d,0x0d,0x0d},{0x15,0x15,0x15},{0x18,0x18,0x18},{0x24,0x24,0x24},{0x27,0x27,0x27},{0x33,0x33,0x33},{0x37,0x37,0x37}, + {0x08,0x08,0x08},{0x10,0x10,0x10},{0x1c,0x1c,0x1c},{0x20,0x20,0x20},{0x2c,0x2c,0x2c},{0x2f,0x2f,0x2f},{0x3b,0x3b,0x3b},{0x3f,0x3f,0x3f}, + }, + { // 5 - grey, 16-color-optimized contrast + {0x00,0x00,0x00},{0x0d,0x0d,0x0d},{0x12,0x12,0x12},{0x15,0x15,0x15},{0x1e,0x1e,0x1e},{0x20,0x20,0x20},{0x29,0x29,0x29},{0x2c,0x2c,0x2c}, + {0x1f,0x1f,0x1f},{0x23,0x23,0x23},{0x2b,0x2b,0x2b},{0x2d,0x2d,0x2d},{0x34,0x34,0x34},{0x36,0x36,0x36},{0x3d,0x3d,0x3d},{0x3f,0x3f,0x3f}, + }, + { // 6 - paper-white, 4-color-optimized contrast + {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x15,0x17,0x18},{0x18,0x1a,0x1b},{0x24,0x25,0x25},{0x27,0x28,0x28},{0x33,0x34,0x32},{0x37,0x38,0x35}, + {0x09,0x0a,0x0b},{0x11,0x12,0x13},{0x1c,0x1e,0x1e},{0x20,0x22,0x22},{0x2c,0x2d,0x2c},{0x2f,0x30,0x2f},{0x3c,0x3c,0x38},{0x3f,0x3f,0x3b}, + }, + { // 7 - paper-white, 16-color-optimized contrast + {0x00,0x00,0x00},{0x0e,0x0f,0x10},{0x13,0x14,0x15},{0x15,0x17,0x18},{0x1e,0x20,0x20},{0x20,0x22,0x22},{0x29,0x2a,0x2a},{0x2c,0x2d,0x2c}, + {0x1f,0x21,0x21},{0x23,0x25,0x25},{0x2b,0x2c,0x2b},{0x2d,0x2e,0x2d},{0x34,0x35,0x33},{0x37,0x37,0x34},{0x3e,0x3e,0x3a},{0x3f,0x3f,0x3b}, + }, +}; static void cga16_color_select(Bit8u val) { cga16_val = val; @@ -393,7 +430,7 @@ static void write_cga(Bitu port,Bitu val,Bitu /*iolen*/) { vga.attr.disabled = (val&0x8)? 0: 1; if (vga.tandy.mode_control & 0x2) { // graphics mode if (vga.tandy.mode_control & 0x10) {// highres mode - if (cga_comp==1 || (cga_comp==0 && !(val&0x4))) { // composite display + if (cga_comp==1 || ((cga_comp==0 && !(val&0x4)) && !mono_cga)) { // composite display VGA_SetMode(M_CGA16); // composite ntsc 640x200 16 color mode } else { VGA_SetMode(M_TANDY2); @@ -686,9 +723,32 @@ static void write_pcjr(Bitu port,Bitu val,Bitu /*iolen*/) { } } +static void CycleMonoCGAPal(bool pressed) { + if (!pressed) return; + if (++mono_cga_pal>3) mono_cga_pal=0; + Mono_CGA_Palette(); +} + +static void CycleMonoCGABright(bool pressed) { + if (!pressed) return; + if (++mono_cga_bright>1) mono_cga_bright=0; + Mono_CGA_Palette(); +} + +void Mono_CGA_Palette(void) { + for (Bit8u ct=0;ct<16;ct++) { + VGA_DAC_SetEntry(ct, + mono_cga_palettes[2*mono_cga_pal+mono_cga_bright][ct][0], + mono_cga_palettes[2*mono_cga_pal+mono_cga_bright][ct][1], + mono_cga_palettes[2*mono_cga_pal+mono_cga_bright][ct][2] + ); + VGA_DAC_CombineColor(ct,ct); + } +} + static void CycleHercPal(bool pressed) { if (!pressed) return; - if (++herc_pal>2) herc_pal=0; + if (++herc_pal>3) herc_pal=0; Herc_Palette(); VGA_DAC_CombineColor(1,7); } @@ -703,7 +763,11 @@ void Herc_Palette(void) { VGA_DAC_SetEntry(0x7,0x34,0x20,0x00); VGA_DAC_SetEntry(0xf,0x3f,0x34,0x00); break; - case 2: // Green + case 2: // Paper-white + VGA_DAC_SetEntry(0x7,0x2c,0x2d,0x2c); + VGA_DAC_SetEntry(0xf,0x3f,0x3f,0x3b); + break; + case 3: // Green VGA_DAC_SetEntry(0x7,0x00,0x26,0x00); VGA_DAC_SetEntry(0xf,0x00,0x3f,0x00); break; @@ -819,10 +883,15 @@ void VGA_SetupOther(void) { if (machine==MCH_CGA) { IO_RegisterWriteHandler(0x3d8,write_cga,IO_MB); IO_RegisterWriteHandler(0x3d9,write_cga,IO_MB); - MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD2,"inchue","Inc Hue"); - MAPPER_AddHandler(DecreaseHue,MK_f11,0,"dechue","Dec Hue"); - MAPPER_AddHandler(CGAModel,MK_f11,MMOD1|MMOD2,"cgamodel","CGA Model"); - MAPPER_AddHandler(Composite,MK_f12,0,"cgacomp","CGA Comp"); + if(!mono_cga) { + MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD2,"inchue","Inc Hue"); + MAPPER_AddHandler(DecreaseHue,MK_f11,0,"dechue","Dec Hue"); + MAPPER_AddHandler(CGAModel,MK_f11,MMOD1|MMOD2,"cgamodel","CGA Model"); + MAPPER_AddHandler(Composite,MK_f12,0,"cgacomp","CGA Comp"); + } else { + MAPPER_AddHandler(CycleMonoCGAPal,MK_f11,0,"monocgapal","Mono CGA Pal"); + MAPPER_AddHandler(CycleMonoCGABright,MK_f11,MMOD2,"monocgabright","Mono CGA Bright"); + } } if (machine==MCH_TANDY) { write_tandy( 0x3df, 0x0, 0 ); diff --git a/src/ints/int10_modes.cpp b/src/ints/int10_modes.cpp index f11eaf5b..22e3507e 100644 --- a/src/ints/int10_modes.cpp +++ b/src/ints/int10_modes.cpp @@ -620,6 +620,7 @@ static bool INT10_SetVideoMode_OTHER(Bit16u mode, bool clearmem) IO_WriteB(0x3d9,color_select); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_MSR,mode_control); real_writeb(BIOSMEM_SEG,BIOSMEM_CURRENT_PAL,color_select); + if (mono_cga) Mono_CGA_Palette(); break; case MCH_TANDY: /* Init some registers */ diff --git a/src/shell/shell.cpp b/src/shell/shell.cpp index 3b44fdbf..9130d37f 100644 --- a/src/shell/shell.cpp +++ b/src/shell/shell.cpp @@ -344,7 +344,10 @@ void DOS_Shell::Run(void) { #if C_DEBUG WriteOut(MSG_Get("SHELL_STARTUP_DEBUG")); #endif - if (machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA")); + if (machine == MCH_CGA) { + if (mono_cga) WriteOut(MSG_Get("SHELL_STARTUP_CGA_MONO")); + else WriteOut(MSG_Get("SHELL_STARTUP_CGA")); + } if (machine == MCH_HERC) WriteOut(MSG_Get("SHELL_STARTUP_HERC")); WriteOut(MSG_Get("SHELL_STARTUP_END")); @@ -630,6 +633,9 @@ void SHELL_Init() { "\xBA \033[31m(Alt-)F11\033[37m changes hue; \033[31mctrl-alt-F11\033[37m selects early/late CGA model. \xBA\n" "\xBA \xBA\n" ); + MSG_Add("SHELL_STARTUP_CGA_MONO","\xBA Use \033[31mF11\033[37m to cycle through green, amber, white and paper-white mode, \xBA\n" + "\xBA and \033[31mAlt-F11\033[37m to change contrast/brightness settings. \xBA\n" + ); MSG_Add("SHELL_STARTUP_HERC","\xBA Use \033[31mF11\033[37m to cycle through white, amber, and green monochrome color. \xBA\n" "\xBA \xBA\n" );