Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to the forum
Board view  Mix view

How to detect the text mode? (Developers)

posted by bretjohn Homepage E-mail, Rio Rancho, NM, 31.12.2020, 17:52
(edited by bretjohn on 31.12.2020, 18:16)

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

 

Complete thread:

Back to the forum
Board view  Mix view
22049 Postings in 2034 Threads, 396 registered users, 228 users online (1 registered, 227 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum