• Please review our updated Terms and Rules here

Video mode 6 (640x200)

evildragon

Veteran Member
Joined
May 29, 2007
Messages
1,646
Location
Tampa Florida
This is going to be an odd request from me, but because my vision isn't as good as it used to be, I have been experimenting with some text modes, as VGA 80x25 mode on my model 25 is getting hard for me to see.

I was using a diagnostic disc and came across video mode 6, 640x200 80x25.. While the same ammount of text, it seemed much more legible to me.

Can this mode be activated on a DOS prompt? I couldn't figure out how to do it.. Using 40 column mode while largely readable, is not useable..
 
I'm guessing the difference is that you find the 8x8 character matrix more legible than the 9x16 one? If so, I think interrupt 10h function 12h (Video Subsystem Configuration) subfunction 30h (select scan lines for alphanumeric modes) should do what you want - try this (tiny!) program and see if it does what you want.
 
I'm guessing the difference is that you find the 8x8 character matrix more legible than the 9x16 one? If so, I think interrupt 10h function 12h (Video Subsystem Configuration) subfunction 30h (select scan lines for alphanumeric modes) should do what you want - try this (tiny!) program and see if it does what you want.
Hmm, didn't work, nothing changed at all, how does your application try to invoke mode 6? Remember, if you just tried to change the fonts, that won't work on MCGA chips, they can't be reprogrammed like VGA can.

I tried another app called VMODE too, but that just says VESA call not supported..
 
Select scan lines won't work on MCGA (not supported in BIOS). And mode 6 is not a text mode - it's a graphics mode. You can use it in programs that display text in graphic modes (you can use that mode in ROM Basic, for example). BUT you should be able to change the text mode font - the BIOS interface for that is mostly compatible between EGA/VGA/MCGA.

So: try some utilities that change the text mode fonts and see if they work.

http://s3.pirillo.com/wp-content/uploads/2006/09/DOSfonts.zip

PS I just made this for you:
 

Attachments

  • DUAL.zip
    1.8 KB · Views: 3
Last edited:
Does the MCGA support the load font extensions? You could maybe make a TSR that loads a scanline-doubled version of the 8x8 CGA font into memory if so.

It might also be possible to load the 8x8 font, enable scanline doubling in the CRTC and then reprogram the character height... netting you the same effect.

That all hinges though on what the MCGA can and cannot do... being it's a CGA with a couple VGA-ish modes tacked on, it's never entirely clear what's going to be supported and what's not.

Hang on, I just grabbed some of the PS/2 PDF's off bitsavers, I'll dig into the BIOS reference and see what I can see...
 
That makes no sense, it must be wrong, because nothing that has a normally customized fonts, work and instead just show garbage ASCII or just regular text mode equivalents.

For example, MS Degrag looks like a regular TUI, no customization to the interface. SB Mixer, all widgets show as standard ASCII characters instead of what they should be showing, control widgets.

I'll try those apps, but I'm going to be 99% certain it won't work..
 
Tried it.

Just as I thought, it did nothing.. After trying each of the programs recommended here, it just goes to the next line with another C: prompt, as if it "thinks" it loaded something, but the fonts are unaffected.

I'm telling you, it doesn't work. If it can, it's certainly not by any means in the same way it's done for VGA or anything else, and I'm not a programmer to really understand the technical reference manual. I'm a hardware guy, not a software guy.

EDIT: Actually, when I saw this page, I'm questioning the reference manuals accuracy. Apparently the XT-BUS riser slot is the keylock, and half the labels are wrong.

http://img.photobucket.com/albums/v395/Evilweredragon/ScreenShot2011-12-04at102538PM.png
 
Last edited:
I think I got it.

A block specifier command must be issued following any
character load command to make the loaded block an active
character set.
(Al) = 04H - ROM 8x16 font
(Bl) - Block to load

And this is how to do it:

Code:
     Listing 10-5.  Loading font pages on an MCGA.

                TITLE   'Listing 10-5'
                NAME    SetFontPages
                PAGE    55,132

;
; Name:         SetFontPages
;
;               Update MCGA Font Pages
;
; Caller:       Microsoft C:
;
;                       void SetFontPages(n0,n1);
;
;                       int     n0,n1;  /* font page values */
;

ARGn0           EQU     [bp+4]
ARGn1           EQU     [bp+6]

_TEXT           SEGMENT byte public 'CODE'
                ASSUME  cs:_TEXT

                PUBLIC  _SetFontPages
_SetFontPages   PROC    near

                push    bp              ; preserve caller registers
                mov     bp,sp

                mov     ax,1103h        ; AH := INT 10H function number
                                        ; AL := 3 (Set Block Specifier)
                mov     bl,ARGn1        ; BL := value for bits 2-3
                shl     bl,1
                shl     bl,1            ; BL bits 2-3 := n1
                or      bl,ARGn0        ; BL bits 0-1 := n0
                int     10h             ; load font pages

                pop     bp
                ret             

_SetFontPages   ENDP

_TEXT           ENDS

                END

The way I see it: this should be compiled to a com/exe (just add a line to call SetFontPages(0,0) ), and then you could try running this after running one of the com files posted in this thread.
 
Last edited:
I recognize that code; it's from Wilton's book. But the process is a bit more complicated than that. MCGA can indeed load new character fonts HOWEVER, since MCGA has no parallel memory maps like EGA/VGA does, the font definitions must be stored in the first 32K of display memory -- specifically in one of four locations: offset 0000, 2000, 4000, or 6000. But you can't just slam stuff there, the format in which they are stored is different than EGA/VGA, it's divided into 16 512-byte "lists". It was enough of a pain in the ass that not even Personic's Ultravision supported it. The only advantage of the above arrangement, that I can see, is that you can modify the font instantly by changing the data in video RAM.

For anyone who wants to give this a shot, I would first search a simtel or similar archive and try to find a program that can change MCGA fonts. If there are none, then I've attached Chapter 10 of Richard Wilton's Programmer's Guide to PC Video Systems for anyone who wants to take a stab at writing one. The attached chapter explains loading alternate font sets on EGA/VGA, as well as MCGA, HGC+, and Hercules InColor.
 

Attachments

  • V10.zip
    21.2 KB · Views: 1
@Trixter: yes, it is that book, and the last sentence from my post are my final thoughts of how it should be done after reading through the available material (the 8525 ref, the BIOS ref, and this chapter). The process of hand-making the changes (for speed) is different BUT the BIOS interface is the same. The only difference between doing it the BIOS way on MCGA vs other systems is the call in the listing which is needed as a final step to commit the change. I'm pretty certain that's what these manuals are trying to say.

Sooo, you could just compile that with whatever you have at hand (ASM/C/TP) and we'd be a step further - no need to hit the metal if a simple BIOS solution works (just to be clear: I'd happily do that myself, if I had the access to my 8086 gear).
 
Last edited:
read through everything posted so far and the PS/2 tech manual, and came up with this:

http://www.deathshadow.com/for_others/MCGAFNT8.RAR

The code:

Code:
program mcgaFnt8;

type
	tScanLines8=array[0..7] of byte;
	pChar8=^tChar8;
	tChar8=array[0..255] of tScanLines8;
	tMCGAScanLine=array[0..511] of byte;
	tCharMCGA=array[0..15] of tMCGAScanLine;

var	
	charSetMCGA:tCharMCGA absolute $A000:0000;
	
function getSystemFont(fontNumber:byte):pointer; assembler;
asm
	push bp
	mov  ax,$1130
	mov  bh,fontNumber
	int  $10
	mov  ax,bp
	mov  dx,es
	pop  bp
end;

var
	t,n:word;
	font8x8:pChar8;
	
begin
	font8x8:=getSystemFont(3);
	for n:=0 to 7 do begin
		for t:=0 to 255 do begin
			charSetMCGA[n*2][t]:=font8x8^[t][n];
			charSetMCGA[n*2+1][t]:=font8x8^[t][n];
		end;
	end;
	asm
		mov ax,$1103
		mov  bl,0
		int  $10
	end;
end.

That SHOULD work if I'm understanding all this properly. It occurred to me that arrays of type and absolute vars could all be combined to simplify turning the 8x8 font into 8x16 scanline doubled and MCGA scanline parsed.

COMPLETELY untested though, as I don't have a Model 25 or other MCGA equipped system to try it on... but if the documentation is correct (yeah, right) the concept is sound.

Thinking about it, you know the scanline interleave actually makes MORE sense from a hardware perspective -- since you can hardware index the character code without a multiply to get the bitmask for the current scanline. It's just harder to program for on the software side. (kinda, not really) - NOT that it couldn't be handled both ways by simply mapping the CRTC address lines different from the BUS ones.
 
Last edited:
for t:=0 to 255 do begin
charSetMCGA[n*2][t]:=font8x8^[t][n];
charSetMCGA[n*2+1][t]:=font8x8^[t][n];

Shouldn't it be:

charSetMCGA[n*2][t*2]:=font8x8^[t][n];
charSetMCGA[n*2+1][t*2]:=font8x8^[t][n];

?
 
Uhm... no, it's not byte interlaced... It's a 512 character possible set right? (re-reads) -- wait, it's character code interlaced? You're right, but there's even more to it... Oh that's confusing... AND a waste of memory... ok, correcting. It's actually THIS:

Code:
		for t:=0 to 255 do begin
			charSetMCGA[n*2][t*2]:=t;
			charSetMCGA[n*2+1][t*2]:=t;
			charSetMCGA[n*2][t*2+1]:=font8x8^[t][n];
			charSetMCGA[n*2+1][t*2+1]:=font8x8^[t][n];
		end;
Wow that's bad.

-- edit --

There, uploaded copy with that correction... Same addy as before
http://www.deathshadow.com/for_others/MCGAFNT8.RAR

That's a really weird way of handling it, wonder what purpose encoding the character code 16 times per character accomplishes, other than doubling the size for nothing.
 
Last edited:
I just uploaded yet again, this time I added some extra vars to speed it up by condensing redundant calculations and getting some of them out of the inner loop.

Code:
	for n:=0 to 7 do begin
		n2:=n*2;
		n2p1:=n2+1;
		for t:=0 to 255 do begin
			t2:=t*2;
			charSetMCGA[n2][t2]:=t;
			charSetMCGA[n2p1][t2]:=t;
			inc(t2);
			charSetMCGA[n2][t2]:=font8x8^[t][n];
			charSetMCGA[n2p1][t2]:=font8x8^[t][n];
		end;
	end;

Did I miss anything else?
 
Does DISPLAY.SYS work on an MCGA? If so, I'd think it would be simplest to use it and create a custom CPI file with the font you want.
 
I just uploaded yet again, this time I added some extra vars to speed it up by condensing redundant calculations and getting some of them out of the inner loop.

Code:
	for n:=0 to 7 do begin
		n2:=n*2;
		n2p1:=n2+1;
		for t:=0 to 255 do begin
			t2:=t*2;
			charSetMCGA[n2][t2]:=t;
			charSetMCGA[n2p1][t2]:=t;
			inc(t2);
			charSetMCGA[n2][t2]:=font8x8^[t][n];
			charSetMCGA[n2p1][t2]:=font8x8^[t][n];
		end;
	end;

Did I miss anything else?
Your previous one works. This one you don't have a link to it.

There seems to be one flaw though, whenever I open a app, like Edit, the font is lost, and when I get back to DOS I have to reload the app again.
 
Your previous one works. This one you don't have a link to it.
Cool... getting better at writing code for hardware I don't have...

There seems to be one flaw though, whenever I open a app, like Edit, the font is lost, and when I get back to DOS I have to reload the app again.
I didn't set it up to trap INT10h, so the font setting won't be pervasive. A more complete version would hook int 10h trapping function AH=00h... When some applications (like edit) start up, they call the video mode set... which resets the font back to default. To keep it pervasive an int 10h wrapper would look for when the mode set is called, then re-run the font copy and set afterwards.

Unfortunately I've never been able to get wrapping INT 10h to work on anything... I can trap any other ISR and call-back successfully, but doing it with the video ISR eludes me... there must be some trick to it that's different from other ISR's.
 
Back
Top