1
0
Fork 0

hercules updates by hal (herc mode/status reg, herc textmode drawing), fixes blockout

Imported-from: https://svn.code.sf.net/p/dosbox/code-0/dosbox/trunk@3256
This commit is contained in:
Sebastian Strohhäcker 2009-01-11 18:22:59 +00:00
parent a5e74da117
commit a9f0ec5b10
6 changed files with 166 additions and 82 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
* Copyright (C) 2002-2009 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
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_draw.cpp,v 1.104 2008-12-28 20:22:12 c2woody Exp $ */
/* $Id: vga_draw.cpp,v 1.105 2009-01-11 18:22:59 c2woody Exp $ */
#include <string.h>
#include <math.h>
@ -373,6 +373,55 @@ skip_cursor:
return TempLine;
}
static Bit8u * VGA_TEXT_Herc_Draw_Line(Bitu vidstart, Bitu line) {
Bits font_addr;
Bit32u * draw=(Bit32u *)TempLine;
const Bit8u *vidmem = &vga.tandy.draw_base[vidstart];
for (Bitu cx=0;cx<vga.draw.blocks;cx++) {
Bitu chr=vidmem[cx*2];
Bitu attrib=vidmem[cx*2+1];
if (!(attrib&0x77)) {
// 00h, 80h, 08h, 88h produce black space
*draw++=0;
*draw++=0;
} else {
Bit32u bg, fg;
bool underline=false;
if ((attrib&0x77)==0x70) {
bg = TXT_BG_Table[0x7];
if (attrib&0x8) fg = TXT_FG_Table[0xf];
else fg = TXT_FG_Table[0x0];
} else {
if (((Bitu)(vga.crtc.underline_location&0x1f)==line) && ((attrib&0x77)==0x1)) underline=true;
bg = TXT_BG_Table[0x0];
if (attrib&0x8) fg = TXT_FG_Table[0xf];
else fg = TXT_FG_Table[0x7];
}
Bit32u mask1, mask2;
if (GCC_UNLIKELY(underline)) mask1 = mask2 = FontMask[attrib >> 7];
else {
Bitu font=vga.draw.font_tables[0][chr*32+line];
mask1=TXT_Font_Table[font>>4] & FontMask[attrib >> 7]; // blinking
mask2=TXT_Font_Table[font&0xf] & FontMask[attrib >> 7];
}
*draw++=(fg&mask1) | (bg&~mask1);
*draw++=(fg&mask2) | (bg&~mask2);
}
}
if (!vga.draw.cursor.enabled || !(vga.draw.cursor.count&0x8)) goto skip_cursor;
font_addr = (vga.draw.cursor.address-vidstart) >> 1;
if (font_addr>=0 && font_addr<(Bits)vga.draw.blocks) {
if (line<vga.draw.cursor.sline) goto skip_cursor;
if (line>vga.draw.cursor.eline) goto skip_cursor;
draw=(Bit32u *)&TempLine[font_addr*8];
Bit32u att=TXT_FG_Table[vga.tandy.draw_base[vga.draw.cursor.address+1]&0xf];
*draw++=att;*draw++=att;
}
skip_cursor:
return TempLine;
}
static Bit8u * VGA_TEXT_Xlat16_Draw_Line(Bitu vidstart, Bitu line) {
Bits font_addr;
Bit16u * draw=(Bit16u *)TempLine;
@ -987,8 +1036,8 @@ void VGA_SetupDrawing(Bitu /*val*/) {
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;
if (vga.herc.mode_control & 0x2) clock=16000000/16;
else clock=16000000/8;
break;
default:
clock = 14318180;
@ -1245,16 +1294,22 @@ void VGA_SetupDrawing(Bitu /*val*/) {
break;
case M_TANDY_TEXT:
doublewidth=(vga.tandy.mode_control & 0x1)==0;
case M_HERC_TEXT:
aspect_ratio=1;
doubleheight=(vga.mode!=M_HERC_TEXT);
doubleheight=true;
vga.draw.blocks=width;
width<<=3;
VGA_DrawLine=VGA_TEXT_Draw_Line;
break;
case M_HERC_TEXT:
aspect_ratio=1;
vga.draw.blocks=width;
width<<=3;
VGA_DrawLine=VGA_TEXT_Herc_Draw_Line;
break;
default:
LOG(LOG_VGA,LOG_ERROR)("Unhandled VGA mode %d while checking for resolution",vga.mode);
};
break;
}
VGA_CheckScanLength();
if (vga.draw.double_scan) {
if (IS_VGA_ARCH) height/=2;

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
* Copyright (C) 2002-2009 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
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_misc.cpp,v 1.37 2008-06-03 18:35:32 c2woody Exp $ */
/* $Id: vga_misc.cpp,v 1.38 2009-01-11 18:22:59 c2woody Exp $ */
#include "dosbox.h"
#include "inout.h"
@ -39,40 +39,46 @@ Bitu vga_read_p3da(Bitu port,Bitu iolen) {
vga.internal.attrindex=false;
vga.tandy.pcjr_flipflop=false;
switch (machine) {
case MCH_HERC:
{
// 3BAh (R): Status Register
// bit 0 Horizontal sync
// 3 Video signal
// 7 Vertical sync
if(timeInFrame >= vga.draw.delay.vrstart &&
timeInFrame <= vga.draw.delay.vrend)
retval |= 0x80;
double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal);
if(timeInLine >= vga.draw.delay.hrstart &&
timeInLine <= vga.draw.delay.hrend)
retval |= 1;
retval |= 0x10; //Hercules ident
break;
}
default:
if (machine!=MCH_HERC) {
// 3DAh (R): Status Register
// bit 0 Horizontal or Vertical blanking
// 3 Vertical sync
if(timeInFrame >= vga.draw.delay.vrstart &&
if (timeInFrame >= vga.draw.delay.vrstart &&
timeInFrame <= vga.draw.delay.vrend)
retval |= 8;
if(timeInFrame >= vga.draw.delay.vdend)
if (timeInFrame >= vga.draw.delay.vdend) {
retval |= 1;
else {
} else {
double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal);
if(timeInLine >= (vga.draw.delay.hblkstart) &&
timeInLine <= vga.draw.delay.hblkend){
if (timeInLine >= vga.draw.delay.hblkstart &&
timeInLine <= vga.draw.delay.hblkend) {
retval |= 1;
}
}
} else {
// 3BAh (R): Status Register
// bit 0 Horizontal sync
// 1 Light pen status (only some cards)
// 3 Video signal
// 4-6 000: Hercules
// 001: Hercules Plus
// 101: Hercules InColor
// 111: Unknown clone
// 7 Vertical sync inverted
retval=0x72; // Hercules ident; from a working card (Winbond W86855AF)
// Another known working card has 0x76 ("KeysoGood", full-length)
if (timeInFrame < vga.draw.delay.vrstart ||
timeInFrame > vga.draw.delay.vrend) retval |= 0x80;
double timeInLine=fmod(timeInFrame,vga.draw.delay.htotal);
if (timeInLine >= vga.draw.delay.hrstart &&
timeInLine <= vga.draw.delay.hrend) retval |= 0x1;
// 688 Attack sub checks bit 3 - as a workaround have the bit enabled
// if no sync active (corresponds to a completely white screen)
if ((retval&0x81)==0x80) retval |= 0x8;
}
return retval;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
* Copyright (C) 2002-2009 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
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: vga_other.cpp,v 1.23 2008-08-06 18:32:35 c2woody Exp $ */
/* $Id: vga_other.cpp,v 1.24 2009-01-11 18:22:59 c2woody Exp $ */
#include <string.h>
#include <math.h>
@ -432,26 +432,40 @@ static void write_pcjr(Bitu port,Bitu val,Bitu iolen) {
static void write_hercules(Bitu port,Bitu val,Bitu iolen) {
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 {
case 0x3b8: {
// the protected bits can always be cleared but only be set if the
// protection bits are set
if (vga.herc.mode_control&0x2) {
// already set
if (!(val&0x2)) {
vga.herc.mode_control &= ~0x2;
VGA_SetMode(M_HERC_TEXT);
}
} else {
// not set, can only set if protection bit is set
if ((val & 0x2) && (vga.herc.enable_bits & 0x1)) {
vga.herc.mode_control |= 0x2;
VGA_SetMode(M_HERC_GFX);
}
}
if ((vga.herc.enable_bits & 0x2) && ((vga.herc.mode_control ^ val)&0x80)) {
vga.herc.mode_control^=0x80;
if (vga.herc.mode_control&0x80) {
if (!(val&0x80)) {
vga.herc.mode_control &= ~0x80;
vga.tandy.draw_base = &vga.mem.linear[0];
}
} else {
if ((val & 0x80) && (vga.herc.enable_bits & 0x2)) {
vga.herc.mode_control |= 0x80;
vga.tandy.draw_base = &vga.mem.linear[32*1024];
}
}
vga.tandy.draw_base = &vga.mem.linear[(vga.herc.mode_control & 0x80 ) ? 32*1024 : 0];
vga.draw.blinking = (val&0x20)!=0;
vga.herc.mode_control &= 0x82;
vga.herc.mode_control |= val & ~0x82;
break;
case 0x3bf:
if ( vga.herc.enable_bits ^ val) {
vga.herc.enable_bits=val;
VGA_SetupHandlers();
}
case 0x3bf:
vga.herc.enable_bits=val;
break;
}
}
@ -488,12 +502,6 @@ void VGA_SetupOther(void) {
MAPPER_AddHandler(IncreaseHue,MK_f11,MMOD2,"inchue","Inc Hue");
MAPPER_AddHandler(DecreaseHue,MK_f11,0,"dechue","Dec Hue");
}
if (machine==MCH_HERC) {
vga.herc.enable_bits=0;
vga.herc.mode_control=0x8;
IO_RegisterWriteHandler(0x3b8,write_hercules,IO_MB);
IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB);
}
if (machine==MCH_TANDY) {
write_tandy( 0x3df, 0x0, 0 );
IO_RegisterWriteHandler(0x3d8,write_tandy,IO_MB);
@ -509,6 +517,22 @@ void VGA_SetupOther(void) {
IO_RegisterWriteHandler(0x3da,write_pcjr,IO_MB);
IO_RegisterWriteHandler(0x3df,write_pcjr,IO_MB);
}
if (machine==MCH_HERC) {
Bitu base=0x3b0;
for (Bitu i = 0; i < 4; i++) {
// The registers are repeated as the address is not decoded properly;
// The official ports are 3b4, 3b5
IO_RegisterWriteHandler(base+i*2,write_crtc_index_other,IO_MB);
IO_RegisterWriteHandler(base+i*2+1,write_crtc_data_other,IO_MB);
IO_RegisterReadHandler(base+i*2,read_crtc_index_other,IO_MB);
IO_RegisterReadHandler(base+i*2+1,read_crtc_data_other,IO_MB);
}
vga.herc.enable_bits=0;
vga.herc.mode_control=0xa; // first mode written will be text mode
vga.crtc.underline_location = 13;
IO_RegisterWriteHandler(0x3b8,write_hercules,IO_MB);
IO_RegisterWriteHandler(0x3bf,write_hercules,IO_MB);
}
if (machine==MCH_CGA) {
Bitu base=0x3d0;
for (Bitu port_ct=0; port_ct<4; port_ct++) {
@ -518,8 +542,8 @@ void VGA_SetupOther(void) {
IO_RegisterReadHandler(base+port_ct*2+1,read_crtc_data_other,IO_MB);
}
}
if (machine==MCH_HERC || IS_TANDY_ARCH) {
Bitu base=machine==MCH_HERC ? 0x3b4 : 0x3d4;
if (IS_TANDY_ARCH) {
Bitu base=0x3d4;
IO_RegisterWriteHandler(base,write_crtc_index_other,IO_MB);
IO_RegisterWriteHandler(base+1,write_crtc_data_other,IO_MB);
IO_RegisterReadHandler(base,read_crtc_index_other,IO_MB);

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
* Copyright (C) 2002-2009 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
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: int10_modes.cpp,v 1.83 2009-01-02 19:30:53 c2woody Exp $ */
/* $Id: int10_modes.cpp,v 1.84 2009-01-11 18:22:59 c2woody Exp $ */
#include <string.h>
@ -368,13 +368,11 @@ static void FinishSetMode(bool clearmem) {
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);
}
case M_TEXT: {
Bit16u seg = (CurMode->mode==7)?0xb000:0xb800;
for (i=0;i<16*1024;i++) real_writew(seg,i*2,0x0720);
break;
}
case M_EGA:
case M_VGA:
case M_LIN8:
@ -436,8 +434,7 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
case MCH_HERC:
if (mode!=7) {
//Just the text memory, most games seem to use any random mode to clear the screen
for (i=0;i<16*1024;i++)
real_writew(0xb000,i*2,0x0120);
for (i=0;i<16*1024;i++) real_writew(0xb000,i*2,0x0720);
return false;
}
CurMode=&Hercules_Mode;
@ -504,12 +501,14 @@ bool INT10_SetVideoMode_OTHER(Bitu mode,bool clearmem) {
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);
IO_WriteB(0x3b8,0x28); // TEXT mode and blinking characters
VGA_DAC_CombineColor(0,0);
for ( i = 1; i < 15;i++)
VGA_DAC_CombineColor(i,0xf);
VGA_DAC_CombineColor(8,0);
for ( i = 1; i < 8;i++) {
VGA_DAC_CombineColor(i,0x7);
VGA_DAC_CombineColor(i+8,0xf);
}
break;
case MCH_CGA:
mode_control=mode_control_list[CurMode->mode];

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
* Copyright (C) 2002-2009 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
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: shell.cpp,v 1.95 2008-09-20 14:51:53 c2woody Exp $ */
/* $Id: shell.cpp,v 1.96 2009-01-11 18:22:59 c2woody Exp $ */
#include <stdlib.h>
#include <stdarg.h>
@ -297,14 +297,12 @@ void DOS_Shell::Run(void) {
return;
}
/* Start a normal shell and check for a first command init */
if(machine != MCH_HERC) { //Hide it for hercules as that looks too weird
WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION);
WriteOut(MSG_Get("SHELL_STARTUP_BEGIN"),VERSION);
#if C_DEBUG
WriteOut(MSG_Get("SHELL_STARTUP_DEBUG"));
WriteOut(MSG_Get("SHELL_STARTUP_DEBUG"));
#endif
if(machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA"));
WriteOut(MSG_Get("SHELL_STARTUP_END"));
}
if (machine == MCH_CGA) WriteOut(MSG_Get("SHELL_STARTUP_CGA"));
WriteOut(MSG_Get("SHELL_STARTUP_END"));
if (cmd->FindString("/INIT",line,true)) {
strcpy(input_line,line.c_str());

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2002-2008 The DOSBox Team
* Copyright (C) 2002-2009 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
@ -16,7 +16,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/* $Id: shell_cmds.cpp,v 1.84 2008-09-07 10:55:16 c2woody Exp $ */
/* $Id: shell_cmds.cpp,v 1.85 2009-01-11 18:22:59 c2woody Exp $ */
#include "dosbox.h"
#include "shell.h"
@ -167,7 +167,9 @@ void DOS_Shell::DoCommand(char * line) {
void DOS_Shell::CMD_CLS(char * args) {
HELP("CLS");
reg_ax=0x0003;
// 3 is not good for hercules as it 'forgets' to reset the cursor position
if (machine==MCH_HERC) reg_ax=0x0007;
else reg_ax=0x0003;
CALLBACK_RunRealInt(0x10);
}