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:
parent
a5e74da117
commit
a9f0ec5b10
6 changed files with 166 additions and 82 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue