VOGONS


First post, by jefferl

User metadata
Rank Newbie
Rank
Newbie

Dear sir:

I find somegame message destroy the graphic screen.

I find graphic mode 06 (cga 640*200)
using the WRITE CHAR at cursor , Only do the overwrite

Like below code

mov ah,0ah
mov al,'3'
mov bh,0
mov bl,80h ; expect x'or current graphic screen
mov cx,1
int 10h

In real hardware (CGA/VGA card)
It will do an xor ,But in dosbox0.63 and cvs compile build
It only do the overwrite(black background) @@"

May someone can take care this small issue .

below is BIOS int10 a little document sanpshot.

INT 10 - VIDEO - WRITE CHARACTER ONLY AT CURSOR POSITION
AH = 0Ah
AL = character to display
BH = page number (00h to number of pages - 1) (see #00010)
background color in 256-color graphics modes (ET4000)
BL = attribute (PCjr, Tandy 1000 only) or color (graphics mode)
if bit 7 set in <256-color graphics mode, character is XOR'ed
onto screen
CX = number of times to write character

Reply 2 of 26, by jal

User metadata
Rank Oldbie
Rank
Oldbie
wd wrote:

What game is affected by this?

That's a non-issue. Yes, DOSbox is mainly for emulating games, but for getting such a trivial BIOS-call straight it shouldn't matter whether any game actually uses it.

JAL

Reply 3 of 26, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

Uh it's just that i'd like to have something to test before changing
anything, and for a cga-game it is likely that it really worked on a
cga-card+bios as well as on a vga-card+bios, thus wouldn't
require looking up how the stuff worked on the various bioses.

Reply 4 of 26, by jal

User metadata
Rank Oldbie
Rank
Oldbie
wd wrote:
Uh it's just that i'd like to have something to test before changing anything, and for a cga-game it is likely that it really wo […]
Show full quote

Uh it's just that i'd like to have something to test before changing
anything, and for a cga-game it is likely that it really worked on a
cga-card+bios as well as on a vga-card+bios, thus wouldn't
require looking up how the stuff worked on the various bioses.

See attachments. TESTXOR.EXE shows a capital letter 'X' XORed with 4 horizontal bars. XORED.GIF is the output in a Windows 2000 dosbox. Since I only have DOSbox 0.63, which corrupts the mode 6 screen, I cannot test what DOSbox does. The CVS however should be able to display correctly, safe perhaps from the bug that is reported here.

Update: I got hold of a CVS-build, the result is shown in XORED2.GIF.

Greetings,

JAL

Attachments

  • xored2.gif
    Filename
    xored2.gif
    File size
    1.73 KiB
    Views
    3344 views
    File comment
    Incorrect output of the DOSbox CVS.
    File license
    Fair use/fair dealing exception
  • Filename
    TESTXOR.EXE
    File size
    2.08 KiB
    Downloads
    206 downloads
    File comment
    Program showing an XORed 'X' with
    File license
    Fair use/fair dealing exception
  • xored.gif
    Filename
    xored.gif
    File size
    1.72 KiB
    Views
    3350 views
    File comment
    Correct output of program.
    File license
    Fair use/fair dealing exception

Reply 6 of 26, by jefferl

User metadata
Rank Newbie
Rank
Newbie

My opionion about dosbox is major for dosgame play,
But If dosbox can perfectly simulate a real pc(real mode)
in every aspect , It is more great !

After I try a while , I find the soultion to fix this problem.

If anyone interesting What game is relative this issue,I had 2 chinese chess game

below is code chage in int10_char.cpp

void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) {
/* Externally used by the mouse routine */
PhysPt fontdata;
Bitu x,y;
Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
switch (CurMode->type) {
case M_TEXT:
{
// Compute the address
Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE);
address+=(row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+col)*2;
// Write the char
PhysPt where = CurMode->pstart+address;
mem_writeb(where,chr);
if (useattr) {
mem_writeb(where+1,attr);
}
}
return;
case M_CGA4:
case M_CGA2:
case M_TANDY16:
if (chr<128) fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight;
else {
chr-=128;
fontdata=Real2Phys(RealGetVec(0x1F))+(chr)*cheight;
}
break;
default:
fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight;
break;
}

if(GCC_UNLIKELY(!useattr)) { //Set attribute(color) to a sensible value
static bool warned_use = false;
if(GCC_UNLIKELY(!warned_use)){
LOG(LOG_INT10,LOG_ERROR)("writechar used without attribute in non-textmode");
warned_use = true;
}
switch(CurMode->type) {
case M_CGA4:
case M_CGA2:
// attr = 0x1; // ***delete***
break;
case M_TANDY16:
case M_EGA16:
default:
attr = 0xf;
break;
}
}

x=8*col;
y=cheight*row;Bit8u xor_mask=(CurMode->type == M_VGA) ? 0x0 : 0x80;
//TODO Check for out of bounds
if (CurMode->type==M_EGA16) {
/* enable all planes for EGA modes (Ultima 1 colour bug) */
/* might be put into INT10_PutPixel but different vga bios
implementations have different opinions about this */
IO_Write(0x3c4,0x2);IO_Write(0x3c5,0xf);
}
for (Bit8u h=0;h<cheight;h++) {
Bit8u bitsel=128;
Bit8u bitline=mem_readb(fontdata++);
Bit16u tx=x;
while (bitsel) {
switch (CurMode->type) { // ****new add***
case M_CGA4:
case M_CGA2:
if(attr & xor_mask)
{
if(bitline&bitsel) INT10_PutPixel(tx,y,page,0x81);
}
else
{
if(bitline&bitsel) INT10_PutPixel(tx,y,page,attr&1);
else INT10_PutPixel(tx,y,page,0 );
}
break;
default:
if (bitline&bitsel) INT10_PutPixel(tx,y,page,attr);
else INT10_PutPixel(tx,y,page,attr & xor_mask);
break;
}
tx++;
bitsel>>=1;
}
y++;
}
}[code][/code]

Reply 7 of 26, by jefferl

User metadata
Rank Newbie
Rank
Newbie

The png file is wrong screen snapshot

Attachments

Reply 8 of 26, by jefferl

User metadata
Rank Newbie
Rank
Newbie

Below is after correction snapshot.
and the screen don't corrupt , when moving cursor.

Attachments

Reply 9 of 26, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

> After I try a while , I find the soultion to fix this problem.

But your solution will make some other games' output incorrect (the
current xor-functionality in dosbox is correct btw).

I suppose the tty functions should be using
(CurMode->type!=M_TEXT) && (CurMode->mode!=6)
as mode6 did ignore the attr as well when i tested it.

Reply 10 of 26, by jefferl

User metadata
Rank Newbie
Rank
Newbie

int int10 bios function call
BL = attribute or color (graphics mode)
if bit 7 set in <256-color graphics mode,character is XOR'ed onto screen

Seems the bios can accept
both attr 0x80 , or 0x81 to do , xor char on graphic screen,

But current source code will corrupt if application assign attribute 0x80

                switch(CurMode->type) {       
case M_CGA4:
case M_CGA2:
// ccccccV ***** don't modify xor_bit
attr |= 0x1;
// cccccc^
break;
case M_TANDY16:
case M_EGA16:
default:
attr = 0xf;
break;
}
        //  +++++++v ********  workaround for                                           
if( (CurMode->mode==6) && (attr==0x80) )
attr=0x81;
// +++++++^
for (Bit8u h=0;h<cheight;h++) {
Bit8u bitsel=128;
Bit8u bitline=mem_readb(fontdata++);
Bit16u tx=x;
while (bitsel) {
if (bitline&bitsel) INT10_PutPixel(tx,y,page,attr);
else INT10_PutPixel(tx,y,page,attr & xor_mask);
tx++;
bitsel>>=1;
}
y++;
}

Reply 11 of 26, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

> But current source code will corrupt if application assign attribute 0x80

That's right, but it's not the xoring that is wrong, but how
colour=0 is handled in the tty functions.
You can test it quite easily by adjusting INT10_TeletypeOutput in
int10_char.cpp as posted above.

Reply 12 of 26, by jefferl

User metadata
Rank Newbie
Rank
Newbie

Do you mean change like below code ?
But It's not work.

void INT10_TeletypeOutput(Bit8u chr,Bit8u attr) {
// INT10_TeletypeOutputAttr(chr,attr,CurMode->type!=M_TEXT);
INT10_TeletypeOutputAttr(chr,attr,(CurMode->type!=M_TEXT) && (CurMode->mode!=6) );
}

and If above change add or attr modify

switch(CurMode->type) {
case M_CGA4:
case M_CGA2:
// ccccccV ***** don't modify xor_bit
attr |= 0x1;
// cccccc^
break;
case M_TANDY16:
case M_EGA16:
default:
attr = 0xf;
break;
}

It's work fine.

Reply 13 of 26, by jefferl

User metadata
Rank Newbie
Rank
Newbie

There is existing pc bios source code
and pc/xt bios code, this will help us to find what's the real work
in pc-bios interrupt .

below is bios_source for pc
http://www.programmersheaven.com/d/click.aspx?ID=F15830

below is bios_xt_source for pc
http://www.programmersheaven.com/d/click.aspx?ID=F15869

I'v successful compile it by masm4.0

I have seen Technical referce manual book publish by IBM
(when you purchase their PC,pay some fee can get the manual)
In the original IBM PC/XT /AT 's

Long ago I've a bios listing copy for PC ,But unfortunately,It's lost.
Today I find the source code downloadable , IT's very excited...
Happy !

Reply 14 of 26, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

I think i have the same bios listings, but thanks for the links.

> But It's not work.

Yes, you're right, it's not sufficient. Both things can be merged into
"if (CurMode->type==M_CGA2) attr=(attr&0x80)|1;"
(put it before the loop in WriteChar).

Thanks for noticing it 😀

Reply 15 of 26, by jefferl

User metadata
Rank Newbie
Rank
Newbie

> "if (CurMode->type==M_CGA2) attr=(attr&0x80)|1;"
this work , but I can't figure out

why both solution work ...
<solution 1>
if (CurMode->type==M_CGA2) attr=attr|1;

<solution 2>
if (CurMode->type==M_CGA2) attr=(attr&0x80)|1;

In your version , It always get rid of xor_mask bit (0x80) ...
It's an odd behavior.

Reply 16 of 26, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

> In your version , It always get rid of xor_mask bit (0x80) ...

No, it preserves the bit (and only this bit!), it's an &0x80 and not &(~0x80).
It should correctly reproduce the behaviour of the tty functions in
mode6, that is they completely ignore any colour value (always use 1),
and xor the complete character onto the screen (instead of the
foreground colour only) if the xor-bit is set.

Reply 17 of 26, by jefferl

User metadata
Rank Newbie
Rank
Newbie

Ah~ I see.
This change make the IBM alley cat Menu select string "Pause Message" display correct.

Attachments

Reply 18 of 26, by wd

User metadata
Rank DOSBox Author
Rank
DOSBox Author

In some of the code snippets you posted, you had something like

switch(CurMode->type) { 
case M_CGA4:
case M_CGA2:
// ccccccV ***** don't modify xor_bit
attr |= 0x1;

which affects 4-colour cga modes (cat) as well, which it shouldn't.
Separating those cases (CGA2/4) it should work fine as well.

Reply 19 of 26, by jefferl

User metadata
Rank Newbie
Rank
Newbie

I have test alleycat , pcman , digger , chinese chess , jbird , revenge,
all bios draw message ok, May someone can report fault game.

void WriteChar(Bit16u col,Bit16u row,Bit8u page,Bit8u chr,Bit8u attr,bool useattr) {
/* Externally used by the mouse routine */
PhysPt fontdata;
Bitu x,y;
Bit8u cheight = real_readb(BIOSMEM_SEG,BIOSMEM_CHAR_HEIGHT);
switch (CurMode->type) {
case M_TEXT:
{
// Compute the address
Bit16u address=page*real_readw(BIOSMEM_SEG,BIOSMEM_PAGE_SIZE);
address+=(row*real_readw(BIOSMEM_SEG,BIOSMEM_NB_COLS)+col)*2;
// Write the char
PhysPt where = CurMode->pstart+address;
mem_writeb(where,chr);
if (useattr) {
mem_writeb(where+1,attr);
}
}
return;
case M_CGA4:
case M_CGA2:
case M_TANDY16:
if (chr<128) fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight;
else {
chr-=128;
fontdata=Real2Phys(RealGetVec(0x1F))+(chr)*cheight;
}
break;
default:
fontdata=Real2Phys(RealGetVec(0x43))+chr*cheight;
break;
}

if(GCC_UNLIKELY(!useattr)) { //Set attribute(color) to a sensible value
static bool warned_use = false;
if(GCC_UNLIKELY(!warned_use)){
LOG(LOG_INT10,LOG_ERROR)("writechar used without attribute in non-textmode");
warned_use = true;
}
attr |= 0x0f; // *****
}

x=8*col;
y=cheight*row; // ****
//TODO Check for out of bounds
if (CurMode->type==M_EGA16) {
/* enable all planes for EGA modes (Ultima 1 colour bug) */
/* might be put into INT10_PutPixel but different vga bios
implementations have different opinions about this */
IO_Write(0x3c4,0x2);IO_Write(0x3c5,0xf);
}
for (Bit8u h=0;h<cheight;h++) {
Bit8u bitsel=128;
Bit8u bitline=mem_readb(fontdata++);
Bit16u tx=x;
while (bitsel) {
// ****
if((attr&0x80) && (CurMode->type != M_VGA))
{
if (bitline&bitsel) INT10_PutPixel(tx,y,page,0x8f);
Show last 13 lines
						}
else
{
if(bitline&bitsel) INT10_PutPixel(tx,y,page,attr);
else INT10_PutPixel(tx,y,page,0);
}
tx++;
bitsel>>=1;
}
y++;
}
}