Laaca
Czech republic, 14.11.2020, 11:00 |
How to detect the text mode? (Developers) |
It was slightly mentioned in the DWED text editor thread - the cooperation with various text modes.
I like when the text mode program can cooperate with the already set text mode and does not try to change it into own mode. My beloved Volkoc commander works in this way.
But, when the graphic mode is present, it is not more possible to use the standard videomemory access scheme (segment B800h, even addresses chars, odd addresses attributes).
So the question is, how to easily distinguish between text mode and graphic mode.
I might thing that I am idiot, but I am looking for scheme working in various tweaked modes (like 90x28), SVGA text modes and special tweaked modes set by utility SVGATextMode which are basicaly graphic modes but somehow modified to be allowed the text mode videomemory access scheme. --- DOS-u-akbar! |
Japheth
Germany (South), 14.11.2020, 16:01
@ Laaca
|
How to detect the text mode? |
> So the question is, how to easily distinguish between text mode and graphic
> mode.
If the graphics card is VGA compatible, there are at least 2 options:
1. graphics controller, port 3CEh, index 6: if bit 0=1, graphics mode active
2. attribute controller, port 3C0h, index 10h: if bit 0=1, graphics mode. --- MS-DOS forever! |
tkchia
15.11.2020, 08:01
@ Japheth
|
How to detect the text mode? |
Hello Laaca, hello Japheth,
> > So the question is, how to easily distinguish between text mode and
> graphic
> > mode.
> If the graphics card is VGA compatible, there are at least 2 options:
> 1. graphics controller, port 3CEh, index 6: if bit 0=1, graphics mode
> active
> 2. attribute controller, port 3C0h, index 10h: if bit 0=1, graphics mode.
Is there anything that will also work with MDA or CGA graphics cards?
I think a good way to test specifically whether one can directly peek and poke 0xb800:0 or 0xb000:0, etc., would be to query the mode number. To do this, what my libi86 project currently does is to call int 0x10, ax = 0x4f03, and if that fails, fall back on int 0x10, ah = 0x0f.
I expect that most if not all tweaked 80×__ modes will have a mode number of 0x0003, except with differing numbers of text rows.
(To spot for text modes in general, for my libi86, I currently use bit 1 of 0x40:0x65 (see Ralf Brown's Interrupt List). I am not sure how reliable that is though.)
Thank you! --- https://gitlab.com/tkchia · https://codeberg.org/tkchia · 😴 "MOV AX,0D500H+CMOS_REG_D+NMI" |
DosWorld
15.11.2020, 15:12
@ Laaca
|
How to detect the text mode? |
I want join to thread, but in another direction.
Howto detect text-mode segment 0xB000 ? (instead 0xB800)
This is case for MDA and Hercules (not sure).
Is it enough - 0040:0065 bit 3 ? (2 in RBIL notation)
When i was a child - i known it, but forgot it now. :( --- Make DOS great again!
Carthago delenda est, Ceterum censeo Carthaginem delendam esse. |
Japheth
Germany (South), 15.11.2020, 17:13
@ DosWorld
|
How to detect the text mode? |
> Howto detect text-mode segment 0xB000 ? (instead 0xB800)
> This is case for MDA and Hercules (not sure).
> Is it enough - 0040:0065 bit 3 ? (2 in RBIL notation)
Checking BIOS variables is ok in most cases. Usually if word at 40h:63h is 3D4h, it's meant a "color" mode starting at 0B800h, and 3B4h means "monochrome" mode at 0B000h
What's more fun is to check the graphics controller, "miscellaneous" register 6, bits 2-3:
3 2 Addressing Assignment
0 0 A0000 for 128KB
0 1 A0000 for 64KB
1 0 B0000 for 32 KB
1 1 B8000 for 32 KB
So you can even set your text mode buffer to A000, size 128 KB. However, I'm not sure if all VGA-compatible cards will accept this.
http://www.o3one.org/hwdocs/vga/vga_app.html --- MS-DOS forever! |
DosWorld
15.11.2020, 18:49
@ Japheth
|
How to detect the text mode? |
Thank you!
PS: I pickup one "MDA/Hercules adapter" (unknown which one) on ebay and will play with it and check to be sure (when arrive, expecting - next year). --- Make DOS great again!
Carthago delenda est, Ceterum censeo Carthaginem delendam esse. |
jassenna
Campinas,SP,Brazil, 30.12.2020, 17:56
@ Japheth
|
How to detect the text mode? |
> > So the question is, how to easily distinguish between text mode and
> graphic
> > mode.
>
> If the graphics card is VGA compatible, there are at least 2 options:
>
> 1. graphics controller, port 3CEh, index 6: if bit 0=1, graphics mode
> active
> 2. attribute controller, port 3C0h, index 10h: if bit 0=1, graphics mode.
There is a third that I use:
INT10 function 1Bh . This function is well documented both in RBIL
and in "PC Video Systems".
It returns a 64 byte data structure containing, among other info,
video mode, number of characters/line, number of lines/screen. |
tkchia
31.12.2020, 08:16
@ jassenna
|
How to detect the text mode? |
Hello jassenna,
> There is a third that I use:
> INT10 function 1Bh . This function is well documented both in RBIL
> and in "PC Video Systems".
> It returns a 64 byte data structure containing, among other info,
> video mode, number of characters/line, number of lines/screen.
Thanks, interesting. But I see that, like int 0x10, ax = 0x4f03, it is not supported by all BIOSes, so one will need to fall back on one of the other detection methods (e.g. int 0x10, ah = 0x0f), in any case...
Thank you! --- https://gitlab.com/tkchia · https://codeberg.org/tkchia · 😴 "MOV AX,0D500H+CMOS_REG_D+NMI" |
bretjohn
Rio Rancho, NM, 31.12.2020, 17:52 (edited by bretjohn, 31.12.2020, 18:16)
@ Laaca
|
How to detect the text mode? |
Below is some code I use in my TSR programs that "write" to the screen (CLOCK, SERIAL, and some others I'm working on). It may help with what you're trying to do, or somebody may be able to tell me what I'm doing wrong.
This is the code I call to detect what type of monitor there is (VGA, EGA, CGA, or MDA) and whether it is color or monochrome:
;------------------------------------------------------------------------------
;FIND OUT THE TYPE OF DISPLAY ADAPTER INSTALLED
;Inputs: DS = ES = Local and TSR Data Area
; (This is done before TSR is installed)
; [ProgFlags],InMemory
;Outputs: [VideoType] = MDA, CGA, EGA, or VGA
; [VideoSegment] = B000h (if mono) or B800h (if color)
;Changes:
;------------------------------------------------------------------------------
GetVideoType:
PUSH AX,BX,CX,DI,SI,ES ;Save used registers
TEST [ProgFlags],InMemory ;Are we already installed in memory?
JNZ >V90 ;If so, we've already done this
MOV AX,40h ;ES =
MOV ES,AX ; BIOS data area
MOV DI,OFFSET VideoType ;Point [DI] at VideoType
MOV SI,OFFSET VideoSegment ;Point [SI] at VideoSegment
MOV B [DI],VGA ;Assume
MOV W [SI],VSegColor ; VGA
V10: ;Test for VGA
MOV AX,1C00h ;Function 1Ch (get VGA save state size)
MOV CX,1 ;SubFunction 1 (Get Size of BIOS Data Area)
MOV BX,-1 ;Preset unrealistic return value (BX)
INT 10h ;Do it
CMP AL,1Ch ;Is the function supported?
JNE >V20 ;If not, it can't be VGA
CMP BX,-1 ;Is the return value valid?
JNE >V30 ;If so, it's VGA
V20: ;Test for EGA
MOV B [DI],EGA ;Assume EGA
MOV AH,12h ;Function 12h (EGA Alternate Select)
MOV BX,0FF10h ;Subfunction (BL) 10h (Return EGA information)
;Preset unrealistic return value (BH)
INT 10h ;Do it
CMP BL,10h ;Is the function supported?
JE >V40 ;If not, it can't be EGA
CMP BH,-1 ;Is the return value valid?
JE >V40 ;If not, it can't be EGA
V30: ;Test if EGA/VGA Active, and for Mono Display
MOV AL,ES:[87h] ;Get the EGA/VGA Information byte
TEST AL,08h ;Is the EGA/VGA Active?
JNZ >V40 ;If not, find the Active Display
CMP B ES:[49h],7 ;Is it Video Mode 7 (Mono Text Mode)?
JNE >V35 ;If not, continue
MOV W [SI],VSegMono ;If so, the EGA/VGA is emulating MDA
V35: ;Mono emulation handled
TEST AL,02h ;Is it a Monochrome Monitor?
JZ >V90 ;If not, we're done
OR [EMSFlags2],MonoMonitor ;If so, mark it as Monochrome
JMP >V90 ;Done
V40: ;Test for CGA
MOV B [DI],CGA ;Assume CGA
CMP W ES:[63h],03B4h ;Is the CRT Controller Base I/O Address MDA?
JNE >V90 ;If not, we're done
V50: ;MDA
MOV B [DI],MDA ;Mark as MDA
MOV W [SI],VSegMono ; and set mono video segment
V90: ;Done
POP ES,SI,DI,CX,BX,AX ;Restore used registers
RET
This is the part of the program that detects whether the program is currently in text or graphics mode. In the part of the program that calls this code, I set ES to the BIOS data area (0040h) and put the current Video Mode (at ES:[49h]) in AL and then call this (this is A86 source code -- you'll need to tweak it a little if you're not using A86):
;------------------------------------------------------------------------------
;TEST AND SEE IF THE CUIRRENT VIDEO MODE IS TEXT OR GRAPHICS
;Inputs: DS = EMS/DPMS Segment/Selector
; ES = BDA Segment/Selector (0040h or Equivalent Selector)
; AL = Current Video Mode
;Outputs: [EMSFlags].GraphicsMode
;Changes:
;NOTES: Determining whether or not the screen is currently in a graphics mode
; or a text mode can be very tricky. There have been so many
; proprietary video modes over the years, particularly in the early
; days of PC's (before VESA), that it is just about impossible
; to handle all of the different possibilities. It would be hard
; enough just to be able to correctly recognize all of the different
; video cards, much less keep track of all the different modes they
; can operate in.
; Modern PC's can be a little bit easier to handle, particularly if
; they follow the VESA standards. However, not even all modern
; video cards are 100% compatible with VESA (if they were, Windows
; would only need one video Driver which could handle every
; modern video card, no matter who made it).
; The methodology we use to determine whether the current mode
; is text or graphics is not 100% foolproof, but works pretty well.
; First of all, we just check the VideoMode byte in the BIOS. If it's
; one of the common, standard ones (less than 14h), we know what it is.
; If it's more than 13h, it's not "standard", we do some further
; testing.
; The "complicated" test we perform is to try and read some text
; from the screen using INT 10h, Function 8. This function
; will read "text" from the screen, even if the screen is in
; graphics mode. That is, it will compare the pixels on the screen
; at the current cursor position and compare them to the bitmaps
; it has of what each ASCII character is supposed to look like.
; If there is a match, the function will return the ASCII code
; associated with the character. If there is no match,
; it returns ASCII 0. We check a total of 12 "characters" on the
; screen, and if any of them return a 0, we assume the screen is
; in a graphics mode. While this methodology can return both
; false positives and false negatives, it seems to be pretty
; reliable. Most of the time, the video mode is one of the
; "standard" ones anyway, especially with DOS programs.
;------------------------------------------------------------------------------
TestGraphicsMode:
PUSH AX,BX,CX,DX ;Save used registers
AND [EMSFlags],(NOT GraphicsMode) ;Assume Text mode
CMP AL,4 ;Is it mode 0-3?
JB >G90 ;If so, it's Text
CMP AL,7 ;Is it mode 7?
JE >G90 ;If so, it's Text
CMP AL,13h ;If not, is it mode 4-6 or 8-13h?
JBE >G70 ;If so, it's Graphics
CMP W ES:[4Ch],8000h ;Is a page more than 32,768 bytes long?
JA >G70 ;If so, it's Graphics
G10: ;Need to do "special" graphics test
MOV BH,ES:[62h] ;Put video page number in BH
CALL GetCursor ;Get cursor position (DX)
PUSH DX ;Save cursor position
MOV CX,12 ;Test 12 characters
XOR DX,DX ;Put cursor in upper left-hand corner
G20: ;Loop to here to test each character
CALL PutCursor ;Set cursor position (DX)
ADD DX,0101 ;Move the cursor down and to the right
MOV AH,8 ;Function 8 (Read character and attribute)
INT 10h ;Do it
OR AL,AL ;Is it a legitimate character?
LOOPNZ G20 ;If legitimate, keep testing
POP DX ;Get the original cursor position back again
CALL PutCursor ;Restore original cursor position
JCXZ >G90 ;If we got 12 legitimate characters, assume Text
G70: ;Is Graphics mode
OR [EMSFlags],GraphicsMode ;Mark as Graphics
G90: ;Done
POP DX,CX,BX,AX ;Restore used registers
RET
;------------------------------------------------------------------------------
;READ OR SET CURSOR POSITION
;Inputs: DH = Cursor Row (if setting position)
; DL = Cursor Column (if setting position)
;Outputs: DH = Cursor Row
; DL = Cursor Column
;Changes:
;------------------------------------------------------------------------------
GetCursor:
PUSH AX ;Save used register
XOR AH,AH ;Flag for Get Cursor
JMP >C00 ;Do it
PutCursor:
PUSH AX ;Save used register
MOV AH,-1 ;Flag for PutCursor
; JMP >C00 ;Do it
C00:
PUSH BX,CX,DS ;Save used registers
PUSHF ;Save flags
CLI ;Disable interrupts
CALL GetBDASegDS ;DS = BIOS Data Area
MOV BX,50h ;Offset of the cursor locations
XOR CX,CX ;Compensate
MOV CL,[62h] ; for the
ADD BX,CX ; video
ADD BX,CX ; page
OR AH,AH ;Are we getting the cursor?
JNZ >C90 ;If not, just store it
MOV DX,[BX] ;Get the cursor location
C90: ;DX = New cursor location
MOV [BX],DX ;Store the cursor location
POPF ;Restore flags
POP DS,CX,BX ;Restore used registers
POP AX ;Restore used register
RET |
jassenna
Campinas,SP,Brazil, 01.02.2021, 00:02
@ tkchia
|
How to detect the text mode? |
tkchia said:
> Thanks, interesting. But I see that, like int 0x10, ax = 0x4f03, it is not
> supported by all BIOSes, so one will need to fall back on one of the other
> detection methods (e.g. int 0x10, ah = 0x0f), in any case...
Do you know any (EGA ir later) video adapter that
does not support this function ? I am interested
because I have used few adapters and all did work,
but design of a fallback would depend on how often
one shall find an incompatible video BIOS. |
tkchia
01.02.2021, 14:26
@ jassenna
|
How to detect the text mode? |
Hello jassenna,
> Do you know any (EGA ir later) video adapter that
> does not support this function [int 0x10,
> ah = 0x1b]? I am interested
> because I have used few adapters and all did work,
> but design of a fallback would depend on how often
> one shall find an incompatible video BIOS.
I am not very sure about that myself. But RBIL lists the function as "PS, VGA/MCGA", so my guess is that not all EGA cards actually support it.
Thank you! --- https://gitlab.com/tkchia · https://codeberg.org/tkchia · 😴 "MOV AX,0D500H+CMOS_REG_D+NMI" |
rr
Berlin, Germany, 01.02.2021, 17:56
@ tkchia
|
How to detect the text mode? |
> > Do you know any (EGA ir later) video adapter that
> > does not support this function [int 0x10,
> > ah = 0x1b]? I am interested
> > because I have used few adapters and all did work,
> > but design of a fallback would depend on how often
> > one shall find an incompatible video BIOS.
>
> I am not very sure about that myself. But RBIL lists the function as "PS,
> VGA/MCGA", so my guess is that not all EGA cards actually support it.
I had a quick look to my physical copies of the books "VGA-Kompendium" (German) und "Programmer's Guide to the EGA, VGA, and Super VGA Cards". Both say nothing about function 1Bh on the EGA card. So expect, that RBIL is right with saying "PS,VGA/MCGA".
If one of the late EGA cards supports this call: fine. --- Forum admin |