Page 1 of 1

Alphanumeric mode disable and VMWare

Posted: Sat Jul 12, 2008 8:37 am
by DustWolf
Hello,

I am writing a kernel with everything that goes with it (boot loader, etc) and I am testing it in vmware. My environment is a 64bit linux, fasm. I have a confusing situation where my documentation (FreeVGA stuff at standford.edu) says a bit flip should make the graphics card go into graphics mode but I don't see it happening (text mode remains functional). Other operations also present in the same byte work fine.

I'm sure this has been asked a million times, but please help me. I don't know what's wrong. Is this a problem with vmware or with my code? Should I be testing in something else?

Here is my code (it runs in 64bit mode, but is probably portable down anyway):

Code: Select all

;Disable graphics mode
        mov     dx,3CEh 	;Address Register port
	mov	al,06h		;Select index 6: Miscellaneous Graphics Register
@@:
	out	dx,al
	in	al,dx		;Set it again if it didn't get trough
	cmp	al,06h
	jne	@b

	inc	dx		;Data Register port
	in	al,dx		;Read current data
;FIXME this doesnt work (only in vmware?)
	or	al,00000001b	;Set Alphanumeric Mode Disable to 1
;
	and	al,11110011b	;Set Memory Map Select to A0000h-BFFFFh
	mov	bl,al		;Backup value
@@:
	out	dx,al
	in	al,dx		;Set it again if it didn't get trough
	cmp	al,bl
	jne	@b

;Set 16 color mode
        mov     dx,3CEh         ;Address Register port
        mov     al,05h          ;Select index 5: Graphics Mode Register
@@:
        out     dx,al
        in      al,dx           ;Set it again if it didn't get trough
        cmp     al,05h
        jne     @b

        inc	dx		;Data Register port
        in      al,dx           ;Read current data
        and     al,10011111b    ;Set Shift256 and Shift Reg. to 0
        mov     bl,al           ;Backup value
@@:
        out     dx,al
        in      al,dx           ;Set it again if it didn't get trough
        cmp     al,bl
        jne     @b
After this ends, the memory map is obviously at 0xA0000h, but text mode is still functioning. Why?

Thanks for any assistance you can offer. And no, I don't want to use INT 10h instead.

Re: Alphanumeric mode disable and VMWare

Posted: Sat Jul 12, 2008 11:35 am
by kscguru
Just dug through some code...

There are TWO ways of controlling graphics / alphanumeric mode.
- Attribute Mode Control Register (10h), Attribute Control Graphics Enable (bit 0)
"When set to 1, this bit selects the graphics mode of operation."
- Misc. Graphics Register (6h), Alphanumeric Mode Disable (bit 0)
"This bit controls alphanumeric mode addressing. When set to 1, this bit selects graphics modes, which also disables the character generator latches."

There's actually a third way I see ...
3C4h index 4 (R/W): Sequencer: Memory Mode Register
bit 0 Set if in an alphanumeric mode, clear in graphics modes.
but I see comments in the VMware code saying real VGA hardware appears to not care about this bit.

VMware's VGA device uses AMCR:ACGE to control character generation. MGR:AMD flushes the display but does not affect character generation.

(Is this a bug? Maybe; more likely, this is some obscure corner of "undefined behavior" about whether setting one bit implicitly sets several other bits or what to do when control bits disagree.)

Re: Alphanumeric mode disable and VMWare

Posted: Sun Jul 13, 2008 5:24 am
by DustWolf
Hi,

Thanks for the help, but I have set all these bits and text mode still works fine. I will mention that the screen does not clear either.

I am looking into svgalib for more help but C code is hard to decode. Anywhere else I could look?

Re: Alphanumeric mode disable and VMWare

Posted: Mon Jul 14, 2008 4:57 am
by jal
DustWolf wrote:C code is hard to decode
You make this as a general statement, but it shows a complete lack of skills. C code is quite easy to 'decode' (I'd say read) if it's decently formatted and written, and especially hardware programming stuff, as that's mainly a bunch of outb-s and outw-s anyway.

EDIT: Having said that, I remember an article on the Wiki on how to set VGA modes without the BIOS, you may want to take a look there (or Google, there's plenty of information available).

JAL

Re: Alphanumeric mode disable and VMWare

Posted: Mon Jul 14, 2008 8:52 am
by Combuster
1) Setting the decode range to A0000-BFFFF is asking for trouble. The window should be 64k @(A0000-AFFFF)
2) There is no reason to check VGA register writes unless you are trying to see if its VGA compatible. A single read/write is enough. Besides, its broken
3) alphanumeric mode is 16 colors.
4) the character clock is 9 in most text modes, it should normally be 8
5) you will need to set up the correct addressing mode (planar or chain-4, not odd-even mode)
6) google for working example code, or grab your desired register dump from VGA Hardware
7) VMware sucks

Re: Alphanumeric mode disable and VMWare

Posted: Mon Jul 14, 2008 9:23 am
by DustWolf
jal wrote:
DustWolf wrote:C code is hard to decode
You make this as a general statement, but it shows a complete lack of skills. C code is quite easy to 'decode' (I'd say read) if it's decently formatted and written, and especially hardware programming stuff, as that's mainly a bunch of outb-s and outw-s anyway.

EDIT: Having said that, I remember an article on the Wiki on how to set VGA modes without the BIOS, you may want to take a look there (or Google, there's plenty of information available).

JAL
Hi, JAL...

I realize you're the guy who sits here and criticizes whatever anyone says but, being the wiseguy that you are, you might assume that if the rules explicitly state that everybody should try the wiki and google afirst, that people who ask questions here actually have.

Simmilarly, being the really smart guy that you obvioulsy are, you might conclude that if somebody states that C code is hard to read, and you know that properly written C code is easy to read, that the C code in question ISN'T properly written. ...at least for the intention the OP had in mind.

Thank you for your attention.

Re: Alphanumeric mode disable and VMWare

Posted: Mon Jul 14, 2008 9:28 am
by DustWolf
Combuster wrote:1) Setting the decode range to A0000-BFFFF is asking for trouble. The window should be 64k @(A0000-AFFFF)
2) There is no reason to check VGA register writes unless you are trying to see if its VGA compatible. A single read/write is enough. Besides, its broken
3) alphanumeric mode is 16 colors.
4) the character clock is 9 in most text modes, it should normally be 8
5) you will need to set up the correct addressing mode (planar or chain-4, not odd-even mode)
6) google for working example code, or grab your desired register dump from VGA Hardware
7) VMware sucks
Thanks for the hints.

I have a few comments:
1) This setting worked just fine for me. What problems should I look out for?
2) The documentation I found before (using the link you pointed out in #6 and some googling of my own) indicated that the VGA hardware might not respond quickly enough, which makes a lot of sense to me considering the speed of the CPU compared to the speed of the interface; checking the value simply meant that the CPU hangs on waiting and re-setting the registers until the hardware is ready for the next command.
7) I know... But my question from above remains. What else should I use? Bochs doesn't even emulate the hardware I am using (panics and dies).

Re: Alphanumeric mode disable and VMWare

Posted: Mon Jul 14, 2008 11:36 am
by Combuster
Re: #1
There are two things with the 128k window
a) It tells that the author has no clue as to how the VGA works really: Each bank is 64k, there's no need to allocate more.
b) The behaviour is undefined as to what happens when you write outside the first 64k. Better be safe to ignore what's above that than crashing your card when you do something there.
c) The VGA itself never sets it that way.
d) As per above, nobody uses this setting in production code, hence the chance that some device does not support it is not unlikely.

Re: #2
Many written sources claim that you should sync, and that its potentially dangerous. All code sources including top selling games (read: quake) do not ever rewrite registers. Boards that do need that are strictly speaking not VGA compatible.
And it probably has to do with the fact that those comments come from the time where VGA had not yet become the de-facto standard and things like EGA were still around a lot.

Re: #7
Bochs emulates a VGA to the extent where you can use it like you normally would on any other machine. It does not emulate every detail (see aforementioned link for known differences between bochs and hardware), but it *never* panics when being sent data that is meaningful to a real VGA. If it does, your code is wrong. No problem, you can always post about it here to see what it is that goes wrong. Actually, I even expect it has nothing to do with the VGA part of your code.
If you however want an emulator that is pretty much spot on when it comes to the VGA, try MS VirtualPC. However bochs is superior when it comes to debugging features, and you most likely want to use that.

Re: Alphanumeric mode disable and VMWare

Posted: Mon Jul 14, 2008 12:04 pm
by jal
Combuster wrote:There are two things with the 128k window
a) It tells that the author has no clue as to how the VGA works really: Each bank is 64k, there's no need to allocate more.
b) The behaviour is undefined as to what happens when you write outside the first 64k. Better be safe to ignore what's above that than crashing your card when you do something there.
I don't fully agree. One could use the 128K window for double buffering in mode 13h (320x200x256). In fact, I've even seen BIOSes that support page flipping in mode 13h using this trick.


JAL

Re: Alphanumeric mode disable and VMWare

Posted: Mon Jul 14, 2008 12:17 pm
by jal
DustWolf wrote:I realize you're the guy who sits here and criticizes whatever anyone says but, being the wiseguy that you are,
Ah, you've been keeping track of me. I'm flattered.
you might assume that if the rules explicitly state that everybody should try the wiki and google afirst, that people who ask questions here actually have.
That would be the same as assuming that nobody is a thief, and therefore you can leave your windows open - quite stupid. The fact is, most people asking questions here do not Google, and do not search the Wiki.
Simmilarly, being the really smart guy that you obvioulsy are, you might conclude that if somebody states that C code is hard to read, and you know that properly written C code is easy to read, that the C code in question ISN'T properly written. ...at least for the intention the OP had in mind.
I do not conclude, other than that someone who makes a general statement about C being hard to read is not that skilled.
Thank you for your attention.
You're most welcome.


JAL

Re: Alphanumeric mode disable and VMWare

Posted: Mon Jul 14, 2008 1:49 pm
by Combuster
jal wrote:
Combuster wrote:There are two things with the 128k window
a) It tells that the author has no clue as to how the VGA works really: Each bank is 64k, there's no need to allocate more.
b) The behaviour is undefined as to what happens when you write outside the first 64k. Better be safe to ignore what's above that than crashing your card when you do something there.
I don't fully agree. One could use the 128K window for double buffering in mode 13h (320x200x256). In fact, I've even seen BIOSes that support page flipping in mode 13h using this trick.
Well then, there must be some undocumented trick to flip pages in such a fashion. Mode 13 works with chain-4 and doubleword mode enabled. That means that for successive addresses in the video range the addresses in VRAM become this:
+00000 -> byte 0 plane 0
+00001 -> byte 0 plane 1
+00002 -> byte 0 plane 2
+00003 -> byte 0 plane 3
+00004 -> byte 4 plane 0
+00005 -> byte 4 plane 1
And so forth, in increments of four.
+0FFFF -> byte 0xfffc plane 3

That means that at the end of the 64K, you are also at the end of VRAM. If you are really able to access more of video memory then you need to have a behaviour like
+10000 -> byte 1/2/3 plane 0
+10001 -> byte 1/2/3 plane 1
However, there is absolutely no mention of such behaviour in any of the VGA documentation around, so most likely this is a chipset specific feature. I.e. not part of the VGA standard, and hence not to be relied on to be present everywhere.

In bochs at least, writes above the 64k are sent to memory areas the VGA does not have, only which later SVGA cards do.