Guidance with 16bit MASM in directly write to video RAM using int 21h

Started by Shayaan_Mustafa, June 08, 2014, 01:48:13 AM

Previous topic - Next topic

Shayaan_Mustafa

Where is my discussion??

Please tell me why did we use extra segment to set text mode? Why not data segment? Can we use data segment too?
for example;
mov ax, 0b800h
mov ds, ax

?????????????

Gunther

Hi Mustafa,

Quote from: Shayaan_Mustafa on June 08, 2014, 08:17:46 PM
Please tell me why did we use extra segment to set text mode? Why not data segment? Can we use data segment too?
for example;
mov ax, 0b800h
mov ds, ax

?????????????

the ds register should point to your data. I would use register es for your screen manipulation (see also reply #6 by Fortrans).

Gunther
You have to know the facts before you can distort them.

dedndave

Gunther is correct
generally, we use DS to point to source data and ES to point to destination data
however, that isn't a hard and fast rule
you could use DS to point to the video buffer segment
just remember that, when DS points to something other than local data, you cannot access it

also, if you use DI (or EDI), and string instructions like STOSx or MOVSx, you must use ES as the destination segment register

Shayaan_Mustafa

Yes I read Fortrans' reply. I wan to talk on the dedndave's post
Quotejust remember that, when DS points to something other than local data, you cannot access it
Please explain this quote sir.

dedndave

this code accesses the graphics buffer - not the text mode buffer
but - the idea is the same

        .MODEL  Small
        .STACK  4096
        .DOSSEG
        .386
        OPTION  CaseMap:None

;####################################################################################

        .DATA

s$Msg   db 'Press Alt-Enter to Exit Full Screen',13,10,24h

;************************************************************************************

        .DATA?

;####################################################################################

        .CODE

;************************************************************************************

_main   PROC    FAR

        mov     dx,@data
        mov     ds,dx

        mov     ax,13h
        int     10h

        mov     ax,0A000h
        mov     es,ax

        xor     di,di
        mov     cx,64000

loop00: mov     es:[di],cl
        inc     di
        dec     cx
        jnz     loop00

        mov     ah,0
        int     16h

        mov     ax,3
        int     10h

        mov     dx,offset s$Msg
        mov     ah,9
        int     21h

        mov     ax,4C00h
        int     21h

_main   ENDP

;####################################################################################

        END     _main


notice that, at the beginning of the program, DS is set to @data (the data segment where the message string is located)
ES is set to the video buffer segment

i could set DS to the video buffer segment, rather than ES
but, then, i would have to set it back to the local data segment before displaying the text message
INT 21h, function AH=9, requires that DS:DX points to the string

dedndave

the above code is actually a poor example of segment register management
that's because the ES:[DI] segment override is required, which slows it down
i used ES:[DI] because, in 16-bit code, it is common to use STOSB or MOVSB to set video buffer byte values

STOSB is similar to
    mov     es:[di],al
    inc     di      ;assuming the direction flag is cleared


MOVSB is similar to
    mov     al,ds:[si]
    mov     es:[di],al
    inc     si
    inc     di

except that it does not use AL   :P

STOS and MOVS always use ES as the destination segment

Shayaan_Mustafa

I understand all of this now.

.model small
.stack 32h

.code
mov ax, 0b800h
mov es, ax
mov di, 820
mov al, 'N'
cld
mov ah, 01001001b
stosw
mov ah, 4ch
int 21h
end

Again, di is used to set position right?

And I have few more examples to ask. May I post it here in this thread?

dedndave

yes - you can calculate the position, based on screen dimensions
for example, let's say you are using 80x25 16-color text mode
each character cell uses 2 bytes, 1 for the character, 1 for the attribute
to calculate the DI value for the character byte

DI = 160*Y + 2*X
or
DI = 2*(80*Y + X)

where X and Y are zero-based values (0-79 and 0-24)

dedndave

try this program
you can' see some of the characters because foreground color = background color

Shayaan_Mustafa

I tried your program and it is a rainbow  :biggrin:

Here is my another program

.model small
.stack 32h

.data
msg db 'D',14,'i',12,'r',11,'e',10,'c',9,'t',8

.code
mov ax, @data
mov ds, ax
mov si, offset msg
mov ax, 0b800h
mov es, ax
mov di, 1920
mov cx, 18
rep movsw
mov ah, 4ch
int 21h
end


This is another example we did but sir didn't make us understand how all this works.

I want to know this time why did we use "mov si, offset msg"? Because in order programs we had in class we write this "mov dx, offset msg"
I think due to movsw we used "mov si, offset msg". Right?

And in the .data segment see the message format. It is "msg db 'D',14,'i',12,'r',11,'e',10,'c',9,'t',8". I tried "msg db Direct,0dh,0ah" but it didn't work. Why?

And we didn't set attribute in above code any where but still the word Direct is colored on the screen. Why and How?

dedndave

well - in their example, they interlaced the attribute bytes with the character bytes
that means you can use REP MOVSW, which can be faster than other methods

if you want to simplify the data definition (like "Direct"), then you have to use a slower method of moving the data
you might be able to use a macro to help you interlace attributes with characters
i'm not very good at writing macros, but maybe someone else can help on that one

Shayaan_Mustafa

I know how to write macros. But I am 100% sure it can be done without macros.

I know you can help me.

dedndave

well - of course it can be done
but - let's imagine we had a macro that converted this
   INTERLACE msg, "Direct",14,12,11,10,9,8
into this
msg db 'D',14,'i',12,'r',11,'e',10,'c',9,'t',8

it would just make it easier to write the program

Shayaan_Mustafa

And again I want to know why did we use si for offset msg? Why not ds?

Because mostly we use these statements;
mov ax, @data
mov ds, ax
mov dx, offset msg

But this time we used si. Can't we use dx again?

Wannabe

Quote from: Shayaan_Mustafa on June 09, 2014, 08:58:51 PM

I think due to movsw we used "mov si, offset msg". Right?
That is correct.
Look here:
http://www.electronics.dit.ie/staff/tscarff/8086_instruction_set/8086_instruction_set.html#MOVSW