2

I want to read a character and its attribute with ah=8 int 10h interrupt.

It works on text mode, but not in graphical mode (16-color 640 x 480).

mov ax,0012h
int 10h       ;graphical mode
int 10h

mov ah,0Ah
mov al,'1'
mov cx,200    ;printing '1' 200 times
mov bx,0
int 10h

mov ah,2
mov dx,0      ;moving cursor to (0,0)
mov bx,0
int 10h

mov bh,0
mov ah,8      ;reading the character
int 10h

Code has to give AH=07h & AL=31h.

But this code always gives AH=07h & AL=00h.

So how can I use this method with graphical mode?

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • 1
    Reading text back in graphical mode is not sensible. It has pixels, not characters. You can still write characters, even though it is a graphical mode, but reading them back is not an option. – Hans Passant Jun 02 '19 at 17:14
  • So how can I make a word processor in graphics mode If I can not read any characters? –  Jun 02 '19 at 17:19
  • 4
    Just don't store the text of the document in video memory, it belongs in normal memory. Not just because you can't read it back, there will be more text than fits on the screen. – Hans Passant Jun 02 '19 at 17:23
  • Can you give me an idea with that? It would really help me a lot. –  Jun 02 '19 at 17:42
  • 1
    In its simplest form: allocate an array of characters, and define variables to keep track of cursor position. Upon every keypress, insert/delete character(s) in the array and/or update cursor position (whatever is appropriate for the key pressed). Refresh the screen based on the new array contents and cursor position. This can be done after every keypress, but typically, the program waits until a 'quiet' moment, and only refreshes areas that have changed. – Ruud Helderman Jun 02 '19 at 18:14
  • @RuudHelderman Thanks for the tip! But I wonder, how can I do a cursor like it is in irvine's masm. Do you have an opinion about this? –  Jun 02 '19 at 18:45
  • A cursor is just an index or pointer that points to a specific place in the array. (Though you may want to enrich this with row number and column number to facilitate cursor navigation.) On screen, cursor position is directly related to the way you display text content. For example, if the cursor is at the 123th character in the array, then obviously you should display the cursor at the exact same spot where you display the 123th character. – Ruud Helderman Jun 02 '19 at 19:14
  • @Roshan'sLastCheese: For a word processor, you'll have to deal with things like (e.g.) clipart, words flowing around pictures, tables, different fonts (and font sizes, colors and effects), different page and paragraph layouts (e.g. "N vertical columns" like a newspaper), word-wrap and left/right/center justification, headings and auto-generated contents and index sections, page headers and footers, embedding information from other sources (from spreadsheets, databases) and things like "mail merge". Are you sure you didn't mean "text editor"? – Brendan Jun 02 '19 at 20:50

1 Answers1

1

Problems in a nutshell

  • Writing a redundant int 10h
  • Requesting a replication count that is too big
  • Outputting black characters on a black background
  • Interpreting random register content

Explanations

...Writing a redundant int 10h

mov ax,0012h
int 10h       ;graphical mode
int 10h

It's never a good idea to call an api function without explicitely specifying the function number. You might think that in this example the AX register still holds 0012h (since function 00h is documented to return nothing), but that's not necessarily always the case.
I don't know why you wrote that second int 10h. Maybe you had removed some extra instructions and simply forgot to remove this one. Can happen...

...Requesting a replication count that is too big

From my VGA Programmer's Guide for BIOS.WriteCharacterOnly 0Ah:

In the graphics modes, the number of times to replicate the character, is limited to the number of remaining character positions to the right of the cursor position until the end of the line.

Your program specifies a replication count of 200 which is much more than the available 80 columns on the screen. Requesting too much results in unpredictable behaviour.
The screenshot for emu8086 from your previous question already shows this problem. Look very carefully at the upperleft corner of the picture.

Below is what my computer [1] shows when I request a replication count of 81. After having displayed 80 characters normally, the function wraps to the left edge of the screen but also descends a single scanline (is 1 pixel)! Now you can see that the 8x16 character box in the upperleft corner of the screen no longer holds a bitpattern that BIOS function 08h can recognize as a valid ASCII character and consequently function 08h will return with AL=0.

        x=0    x=7
        |      |
       .........................................
y=0 -  .                                        
       .                                        
       .           **      **      **      **   
       .   **     ***     ***     ***     ***   
       .  ***    ****    ****    ****    ****   
       . ****      **      **      **      **   
       .   **      **      **      **      **   
       .   **      **      **      **      **   
       .   **      **      **      **      **   
       .   **      **      **      **      **   
       .   **      **      **      **      **   
       .   **    ******  ******  ******  ****** 
       . ******                                 
       .                                        
       .                                        
y=15 - .                                        

See this comment by Michael Petch about possible implementation differences between BIOS'es. It's a wise programmer that makes sure his program runs fine on a wide variety of machines.

...Outputting black characters on a black background

When you invoke BIOS function 0Ah WriteCharacterOnly, the 'Only' applies exclusively to the alphanumeric video modes. In the graphics modes the value in the BL register is used for the character color. Your program passes 0 (black) as the character color and BIOS will use that on a black background. That's another reason for not being able to read something from the screen.

...Interpreting random register content

From my VGA Programmer's Guide for BIOS.ReadAttributeCharacterPair 08h:

No attribute code is returned when the display is in one of the graphics modes.

Your program is in a graphics mode (16-color 640x480). You should not interpret the value that is in the AH register. It is whatever happens to be in there, so treat it as garbage. On your computer this register held 7, on mine [1] it held 5.

Try this instead

You don't need to move the cursor to the topleft corner of the screen since the cursor position wasn't modified by function 0Ah.

mov     ax, 0012h  ; BIOS.SetVideoMode 16-color 640x480
int     10h
mov     cx, 80     ; Replication count
mov     bx, 000Eh  ; Display page 0, character color Yellow
mov     ax, 0A31h  ; BIOS.WriteCharacter(Only)
int     10h
mov     bh, 0      ; Display page 0
mov     ah, 08h    ; BIOS.Read(Attribute)Character(Pair)
int     10h        ; -> AL=31h

[1] Phoenix TrustedCore v1.23 VGA BIOS 1264

Sep Roland
  • 33,889
  • 7
  • 43
  • 76
  • I can't read characters, I can only read attribute which is ah=07h. –  Jun 03 '19 at 14:47
  • 1
    @Roshan'sLastCheese I finished a rewrite of my answer. I hope this new information helps you! – Sep Roland Jun 04 '19 at 12:33
  • Thanks for your answer, really helped me a lot! The reason why I wrote int10h twice is that there's a bug with it. If I don't write it twice emulator opens 700x400 resolution window. –  Jun 04 '19 at 12:52
  • 1
    @Roshan'sLastCheese That's indeed a strange error/bug. – Sep Roland Jun 04 '19 at 12:56