Skip to content

Commit

Permalink
Add cga_mono machine
Browse files Browse the repository at this point in the history
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 <basic@vogons.org>
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 <mzijlstra@gmail.com>
Signed-off-by: Patryk Obara <dreamer.tan@gmail.com>

Imported-from: https://www.vogons.org/viewtopic.php?p=238045#p238045
  • Loading branch information
VileRancour authored and dreamer committed Jan 29, 2020
1 parent 46e5fde commit ffe3c5a
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 10 deletions.
1 change: 1 addition & 0 deletions include/dosbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
3 changes: 3 additions & 0 deletions include/vga.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
7 changes: 5 additions & 2 deletions src/dosbox.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ Bit32u ticksScheduled;
bool ticksLocked;
void increaseticks();

bool mono_cga=false;

static Bitu Normal_Loop(void) {
Bits ret;
while (1) {
Expand Down Expand Up @@ -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; }
Expand Down Expand Up @@ -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);
Expand Down
83 changes: 76 additions & 7 deletions src/hardware/vga_other.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
}
Expand All @@ -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;
Expand Down Expand Up @@ -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 );
Expand Down
1 change: 1 addition & 0 deletions src/ints/int10_modes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
8 changes: 7 additions & 1 deletion src/shell/shell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"));

Expand Down Expand Up @@ -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"
);
Expand Down

0 comments on commit ffe3c5a

Please sign in to comment.