10

I have read How to write directly to video memory using "debug.exe" in MS-DOS? and I know how to write text to video memory in mode 0x3 but I can't figure out how to write text to video memory in mode 0x13. First let me show how I write text in mode 0x3.

All steps given below are reproducible at https://copy.sh/v86/?profile=msdos.

C:\>debug
-a
1165:0100 mov ax, b800  ; video memory address
1165:0103 mov ds, ax    ; copy video memory address to ds
1165:0105 xor di, di    ; zero di
1165:0107 mov ah, f     ; bright white color
1165:0109 mov al, 41    ; the letter 'A'
1165:010B mov [di], ax  ; copy letter and color to video memory
1165:010D int 20
1165:010F
-g

Program terminated normally
-

The above debug session prints A in bright white color in the first row first column of the screen.

C:\>debug
-a
1165:0100 mov ah, 0     ; select 'set video mode' function of int 10
1165:0102 mov al, 13    ; select video mode 0x13
1165:0104 int 10        ; set the video mode now
1165:0106 mov ax, b800  ; THIS IS PROBABLY WRONG! NEED HELP WITH THIS.
1165:0109 mov ds, ax    ; copy the address to ds
1165:010B xor di, di    ; zero di
1165:010D mov ah, f     ; bright white color
1165:010F mov al, 41    ; the letter 'A'
1165:0111 mov [di], ax  ; copy letter and color to video memory
1165:0113 int 20
1165:0115
-g

After I execute g, mode 0x13 with 320x200 resolution is displayed and the following output is displayed.

Program terminated normally
-

But there is no text output. Is it possible to write text output by writing ASCII codes to some video memory address in mode 0x13?

Now I continue in this mode to run INT 10 (AH = F) to get current video state.

-a
1165:0115  mov ah, f
1165:0117  int 10
1165:0119  int 20
-g =115 119

AX=2813  BX=0000  CX=0000  DX=0000  SP=F
FEE  BP=0000  SI=0000  DI=0000
DS=1165  ES=1165  SS=1165  CS=1165  IP=0
119   NV UP EI PL NZ NA PO NC
1165:0119 CD20

The value 28 (hex) in AH tells that there are 40 screen columns which is correct. Yes, there are 40 columns of text in mode 13. You can see evidence of this in the above debug session output too where the output wraps after 40 columns (see SP=FFEE wrapped into two lines).

The value 13 (hex) in AL tells that we are in mode 0x13.

So this video mode does acknowledge that it is possible to write 40 columns of text per row but how do we write that text? Is there some video memory address for mode 0x13 where I can write the ASCII codes to make the text output appear?

5
  • 1
    Answers say you can't write characters to video memory. I don't have an active system any more, but I recall that text output through the BIOS interrupt functions is visible. There is even a character generator function at Int 10h function 11h where the user can define the character bitmapped fonts. Nov 9, 2022 at 19:13
  • @WeatherVane which is exactly what the answers say (interrupt 21h service 2 for example). Nov 9, 2022 at 19:17
  • 1
    @StephenKitt hmm perhaps they should have begun with "can" and not "can't" :) Nov 9, 2022 at 19:20
  • @WeatherVane That is technically correct. You can't write an ASCII character code to video memory in graphics mode like you do in text mode. You need to write the pixels that make up the character into video memory (or like you say let the BIOS do that).
    – Justme
    Nov 9, 2022 at 20:03
  • New to this community. In graphics modes the video address starts at a000, not b800, like said in the question's code comment. Nov 10, 2022 at 7:59

3 Answers 3

18

In mode 13h you can't write character codes to video memory because the card is not in text mode where it renders character codes to pixel data for you, it is in graphics mode where it just outputs pixel data.

You need to write all the pixels that make up a character if you want to write it yourself to video memory. So for letter 'A' with 8x8 font you would write all 64 pixels with colors you want, such as background and foreground.

Fortunately the video BIOS provides you with several functions which already do that to output characters and even strings in graphics mode with video interrupt 10h, for example subfunction 0Eh.

DOS uses these functions to print characters and text strings, which is why text prints from debug work.

So you can simply use DOS functions for printing, like int 21h subfunction 02h.

2
  • Thank you for the answer! Do you know why INT 10 (AH = F) reports 28 (hex) in AH? Why is it telling us that there are 40 screen columns if there is no concept of text or text columns in the card in mode 13h? Or is that something BIOS does for us? Does BIOS split the available video memory into 40 logical columns of text for its INT 10 services? Nov 9, 2022 at 10:40
  • 6
    That is because there is a concept of rows and columns in all modes, as the BIOS implements painting the pixels in graphics modes for you. If you write glyphs with 8x8 font in 320x200 mode, you have 40 columns and 25 rows of text.
    – Justme
    Nov 9, 2022 at 10:46
6

There are no such ram locations in graphics mode, you cannot write text bytes and expect it to be visible in graphic modes.

The text you see in debugger is painted by the BIOS. When you use the BIOS functions that prints the texts - those functions change their behavior depending on the current video mode. The BIOS is painting graphics for you, using the fonts stored in the rom.

In general if your application needs to draw some texts in graphic modes, you implement the text rendering yourself, using your desired fonts and layouts.

6

Graphics modes and text modes work entirely different to each other: In text modes, the contents of video memory is expected to be character codes and attribute bytes. The CRT controller fetches a byte, looks up that byte in its character ROM, then, in principle, sends the pixels of the resulting glyph to the screen.

In graphics modes, the contents of video memory is expected to be pixels. The CRT controller simply fetches those pixels and sends them to the screen, there is no byte-to-glyph translation involved here. When you change a byte in video memory, you thus change some pixels, but never a glyph. If you want to write a character in this mode, you need to put the individual pixels of the glyph to video memory (that's what the video BIOS does for you when you use one of the character output routines in a graphics mode).

In graphics modes, there is no "area of memory" where you could put characters and expect them to be displayed on the screen: You either use the video BIOS, or you implement the character->glyph->pixel translation yourself. What you put to screen memory is always pixels in these modes.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .