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);