Reputation:
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?
Upvotes: 2
Views: 212
Reputation: 39166
int 10h
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...
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.
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.
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.
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
Upvotes: 1