Writing to the screen

More output in text modes

I am going to cover some more ways of outputting text in text modes. This first program is an example of how to move the cursor to display a string of text where you want it to go.

.model tiny 
.code
org 100h
start:
 
mov dh,12 			; cursor col 
mov dl,32 			; cursor row
mov ah,02h 			; move cursor to the right place
xor bh,bh 			; video page 0
int 10h 			; call bios service
 
mov dx,OFFSET Text		; DS:DX points to message
mov ah,9 			; function 9 - display string
int 21h 			; all dos service
 
mov ax,4C00h  			; exit to dos
int 21h
 
Text DB "This is some text$" 
 
end start

This next example demonstrates how to write to the screen using the file function 40h of interrupt 21h.

.model small
.stack
.code
 
mov ax,@data 		; set up ds as the segment for data
mov ds,ax 		
 
mov ah,40h 		; function 40h - write file
mov bx,1 		; handle = 1 (screen)
mov cx,17 		; length of string
mov dx,OFFSET Text 	; DS:DX points to string
int 21h 		; call DOS service
 
mov ax,4C00h 		; terminate program
int 21h
 
.data
 
Text DB "This is some text"
 
end

The next program shows how to set up and call function 13h of interrupt 10h - write string. This has the advantages of being able to write a string anywhere on the screen in a specified colour but it is hard to set up.

.model small
.stack
.code
 
mov ax,@data 		; set up ds as the segment for data
mov es,ax 		; put this in es
 
mov bp,OFFSET Text 	; ES:BP points to message
mov ah,13h 		; function 13 - write string
mov al,01h 		; attrib in bl,move cursor
xor bh,bh 		; video page 0
mov bl,5 		; attribute - magenta
mov cx,17 		; length of string
mov dh,5 		; row to put string
mov dl,5 		; column to put string
int 10h 		; call BIOS service
 
mov ax,4C00h 		; return to DOS
int 21h
 
.data
 
Text DB "This is some text"
 
end

The next program demonstrates how to write to the screen using rep stosw to put the writing in video memory.

.model small
.stack
.code
 
mov ax,0B800h 	; segment of video buffer
mov es,ax 	; put this into es
xor di,di 	; clear di, ES:DI points to video memory
mov ah,4 	; attribute - red
mov al,"G" 	; character to put there
mov cx,4000 	; amount of times to put it there 
cld 		; direction - forwards
rep stosw 	; output character at ES:[DI]
 
mov ax,4C00h 	; return to DOS
int 21h
 
end

The next program demonstrates how to write a string to video memory.

; write a string direct to video memory 
 
.model small
.stack
.code
 
mov ax,@data
mov ds,ax
 
mov ax,0B800h 		; segment of video buffer
mov es,ax 		; put this into es
mov ah,3 		; attribute - cyan
mov cx,17 		; length of string to print
mov si,OFFSET Text 	; DX:SI points to string
xor di,di
 
Wr_Char:
 
lodsb 			; put next character into al 
mov es:[di],al 		; output character to video memory
inc di 			; move along to next column
mov es:[di],ah 		; output attribute to video memory
inc di
 
loop Wr_Char 		; loop until done
 
mov ax,4C00h 		; return to DOS
int 21h
 
.data
 
Text DB "This is some text" 
 
end

It is left as an exercise to the reader to modify it so that only one write is made to video memory.

Mode 13h

Mode 13h is only available on VGA, MCGA cards and above. The reason that I am talking about this card is that it is very easy to use for graphics because of how the memory is arranged.

First check that mode 13h is possible

It would be polite to tell the user if their computer cannot support mode 13h instead of just crashing it computer without warning. This is how it is done.

.model small
.stack
.data
 
NoSupport db "Mode 13h is not supported on this computer."
	  db ,"You need either a MCGA or VGA video" 
	  db ,"card/monitor.$"
 
Supported db "Mode 13h is supported on this computer.$"
 
.code
 
mov ax,@data 		; set up DS to point to data segment
mov ds,ax 		; use ax 
 
call Check_Mode_13h 	; check if mode 13h is possible
 
jc Error 		; if cf=1 there is an error
 
mov ah,9 		; function 9 - display string
mov dx,OFFSET Supported ; DS:DX points to message
int 21h 		; call DOS service
 
jmp To_DOS 		; exit to DOS
 
Error:
mov ah,9 		; function 9 - display string
mov dx,OFFSET NoSupport ; DS:DX points to message
int 21h 		; call DOS service
 
To_DOS:
mov ax,4C00h 		; exit to DOS 
int 21h
 
Check_Mode_13h PROC 	; Returns: CF = 1 Mode 13h not possible
 
mov ax,1A00h 		; Request video info for VGA
int 10h 		; Get Display Combination Code
cmp al,1Ah 		; Is VGA or MCGA present?
je Mode_13h_OK 		; mode 13h is supported
stc 			; mode 13h isn't supported CF=1
 
Mode_13h_OK:
 
ret 
Check_Mode_13h ENDP
 
end

Just use this to check if mode 13h is supported at the beginning of your program to make sure that you can go into that mode.

Setting the Video Mode

It is very simple to set the mode. This is how it is done.

mov ax,13h 	; set mode 13h
int 10h 	; call BIOS service

Once we are in mode 13h and have finished what we are doing we need to we need to set it to the video mode that it was in previously.

This is done in two stages. Firstly we need to save the video mode and then reset it to that mode.

VideoMode db ?
.
.
mov ah,0Fh 	 ; function 0Fh - get current mode
int 10h 	 ; Bios video service call
mov VideoMode,al ; save current mode
 
; program code here
 
mov al,VideoMode ; set previous video mode
xor ah,ah 	 ; clear ah - set mode
int 10h 	 ; call bios service
 
mov ax,4C00h 	 ; exit to dos
int 21h 	 ; call dos function

Now that we can get into mode 13h lets do something. Firstly lets put some pixels on the screen.

Function 0Ch: Write Graphics Pixel

This makes a colour dot on the screen at the specified graphics coordinates.

Input

  • AH = 0Ch
  • AL = Color of the dot
  • CX = Screen column (x coordinate)
  • DX = Screen row (y coordinate)

Output

Nothing except pixel on screen.

Note: This function performs exclusive OR (XOR) with the new colour value and the current context of the pixel of bit 7 of AL is set.

This program demonstrates how to plot pixels. It should plot four red pixels into the middle of the screen.

; example of plotting pixels in mode 13 using bios services - 
; INT 10h
 
.model tiny
.code
org 100h
start:
 
mov ax,13 	; mode = 13h 
int 10h 	; call bios service
 
mov ah,0Ch 	; function 0Ch
mov al,4 	; color 4 - red
mov cx,160 	; x position = 160
mov dx,100 	; y position = 100
int 10h 	; call BIOS service
 
inc dx 		; plot pixel downwards
int 10h 	; call BIOS service
inc cx 		; plot pixel to right
int 10h 	; call BIOS service
dec dx 		; plot pixel up
int 10h 	; call BIOS service
 
xor ax,ax 	; function 00h - get a key
int 16h 	; call BIOS service
 
mov ax,3 	; mode = 3
int 10h 	; call BIOS service
 
mov ax,4C00h 	; exit to DOS
int 21h
 
end start

Some Optimizations

This method isn't too fast and we could make it a lot faster. How? By writing direct to video memory. This is done quite easily.

The VGA segment is 0A000h. To work out where each pixel goes you use this simple formula to get the offset.

Offset = X + ( Y * 320 ) 

All we do is to put a number at this location and there is now a pixel on the screen. The number is what colour it is. There are two instructions that we can use to put a pixel on the screen, firstly we could use stosb to put the value in AL to ES:DI or we can use a new form of the MOV instruction like this:

mov es:[di], color

Which should we use? When we are going to write pixels to the screen we need to do so as fast as it is possible.

Instruction Pentium 486 386 286 86
STOSB 3 5 4 3 11
MOV AL to SEG:OFF 1 1 4 3 10

If you use the MOV method you may need to increment DI (which STOSB does).

If we had a program which used sprites which need to be continuously draw, erased and then redraw you will have problems with flicker. To avoid this you can use a 'double buffer'. This is another part of memory which you write to and then copy all the information onto thescreen.

This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information
 
Jei nenurodyta kitaip, šio wiki turinys ginamas tokia licencija: CC Attribution-Noncommercial-Share Alike 4.0 International
Recent changes RSS feed Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki