Displaying a character on two consecutive lines

Started by zak100, August 28, 2009, 05:34:37 AM

Previous topic - Next topic

zak100

Hi,
I have a simple program which should display two As on two consecutive lines (line 1 and line 2) but its not working.
The code is given below:


.model tiny
.386
.code
start:

    jmp test1
test1:
    cld
    mov cx,2
    mov ax,0B800h
    next: mov es,ax
    push ax
    xor di,di
    mov ax,4A41h
    stosw
    pop ax
    add ax, 50h
    Loop next
loop1:
    jmp loop1

org 510

    dw 0AA55h

end start



It prints the next 'A' after four or five lines. Can somebody plz help me with this program??

Zulfi.

dedndave

#1
mov ax,0b800h and mov ds,ax
those instructions sould be before the loop
once you have the ES register set to B800h, leave it alone

you want to add to DI, instead
and, i think you have to add 0A0h for each line - not 50h
that is because each character is 2 bytes (char and attribute)

zak100

Hi,
I have changed the code to following but still its not printing the next 'A' at the start of next line:


.model tiny
.386
.code
start:

    jmp test1
test1:
    cld
    mov cx,2
    xor di,di
    mov ax,0B800h
    mov es,ax
    mov ax,4A41h
next:stosw
    add di, 50h
    Loop next
loop1:
    jmp loop1

org 510

    dw 0AA55h

end start



My logic is to add 80D to B800H so that I would be at the start of next line. Note each line can have 80 characters.  At this point I dont want to use 0AH. However it can be done through it also.

Zulfi.

dedndave

Quotejmp test1
test1:
what is that ? - lol
get rid of those lines

        cld
        mov     ax,0B800h
        mov     es,ax
        xor     di,di

        mov     ax,4A41h
        mov     cx,2

next:   stosw
        add     di,158         ;160-2
        loop    next

loop1:  jmp loop1




MichaelW

Quote from: zak100 on August 28, 2009, 10:10:38 AM
My logic is to add 80D to B800H so that I would be at the start of next line. Note each line can have 80 characters.  At this point I dont want to use 0AH. However it can be done through it also.

Adding 80 to the segment address will shift the absolute address 80 * 16 = 1280 bytes = 8 lines further down in the buffer. Before you decide to use segment indexing for this, you should first learn how segment addressing works:

absolute address = (segment address SHL 4) + offset address

In general, when dealing with a buffer that will fit in a single segment, you should leave the segment address fixed and manipulate the offset address.
eschew obfuscation

zak100

Hi,
Thanks for the help. I am able to print 25 As, one one on each line.

Zulfi.

dedndave

ok Zulfi
you should be able to display whatever you like, and in multiple colors, too - lol

zak100

I have not checked but I want to know can we display images also using BIOS?

Zulfi.

dedndave

sure - set the video mode and put pixels in the buffer, rather than characters
the simplest graphics modes are:
320 x 200, 4 color
640 x 400, 16 color
320 x 200, 256 color
all other graphics modes are very tricky to program

FORTRANS

#9
Hi Zulfi.,

QuoteI have not checked but I want to know can we display images also using BIOS?

   Yes, INT 10H is the video BIOS interrupt.

   Use function 0 (zero) to set the video mode.


        MOV     AH,0    ; Function 0
        MOV     AL,13H  ; set 320 x 200 256 color mode
        INT     10H     ; Video BIOS Call


   Use function 0CH to write a pixel.


        MOV     AH,0CH  ; function 0CH
        MOV     BH,0    ; page number
        MOV     CX,100  ; X or column
        MOV     DX,100  ; Y or row
        MOV     AL,15   ; Color value
        INT     10H     ; Video BIOS Call


   Or some such.

'Luck,

Steve

Edit, fix wrong function 0B => 0C.

SRN

MichaelW

Zulfi,

The BIOS SetPixel function is easy to use, but it's slow. For mode 13h (320x200, 256-color), drawing pixels by accessing the display buffer directly is simple and easy to do, and much faster than using the BIOS.
eschew obfuscation

dedndave

i'm with Michael on that one
320 x 200, 256 color mode is simple to program
the pixels are a little too large for detailed work like pictures, though
but, you can make some fun stuff with that mode, nonetheless
each pixel is represented by a byte, which makes it very easy to do lines and circles and all that
i think it is an ideal mode for beginners to start out on graphics

FORTRANS

Hi,

   Actually, Micheal is right.  Once you have done it a few
times, BIOS calls are less convenient (easy) than doing it
directly in mode 13H.  However, that wasn't the question
asked (nit pick!).  And I think it is a good way to start out.
Modes 4, 6, 12H, and 13H for instance use the same form
with the BIOS function, but are quite different with direct
memory writes.

   Dave is right that mode 13H is a bit coarse, so try 11H
and 12H for finer detail.  Less colors though, so images
need to be selected carefully to look good.

Cheers,

Steve N.

dedndave

the problem with larger resolutions is, the buffer no longer fits into a single segment
for those video modes, you either have to use BIOS calls to place pixels (slow) or get fancy with the video CRT registers
for mode 13h, the entire screen fits into a single segment and you can calculate the address of a pixel:
Address = 320 * Y + X
(X,Y = 0,0 is the upper left corner of the display)
you have a palette of 256 colors from 262,144 possible values

FORTRANS

Hi,

   All of the standard VGA modes are addressed in a single
segment.  Only when you use SVGA or VESA modes does
that require more than one segment's address range.

   And yes, while 640 x 480 = 307,200, which would seem
to require more than one 65,536 byte segment, it doesn't.
You multiplex 8 pixels per byte, and start playing with
color "planes".  And getting used to that is a whole 'nother
kettle of fish.  Talk about ignoring the man behind the curtain.

   Starting with BIOS functions may be the first step on a
fairly interesting journey.  But it is a fairly easy step to take.

Cheers,

Steve N.