News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Problem writing to a video page

Started by omdown, May 03, 2005, 09:35:36 PM

Previous topic - Next topic

omdown

I'm working on a program in which when the user presses Ctrl+F, it will highlight the word "File" at the top of a window in the program and drop down a menu.  The way I'm going about this is to move the cursor to the location of the word, and change to video page 1 (so I can switch back when they make their choice or hit ESC), however when I give the command to print the word (after coloring the area) the word doesn't print in the area I tell it to go to, but at the end of the line.  If that doesn't make sense (which I doubt it does, here's a copy of the code.  The general idea is a black menu bar with yellow text, which turns inverted (black on yellow) when selected.  I haven't written in the code that makes it happen when you press Ctrl+F, I'm only testing right now just to see what it looks like, try to make it work.

Quote.data
   file BYTE "File",0
   edit BYTE "Edit",0
   help BYTE "Help",0
   top_border BYTE "+--------+",0
   side_border BYTE "¦        ¦",0
   bottom_border BYTE "+--------+",0
   file_open BYTE "Open",0
   file_save BYTE "Save",0
   file_saveas BYTE "Save As",0
   edit_cut BYTE "Paste",0
   edit_copy BYTE "Copy",0
   edit_paste BYTE "Paste",0
   lc_file WORD 0201h
   lc_edit WORD 0209h

.code
main PROC
   mov ax,@data
   mov ds,ax

   ; create the window
   mov ax,0600h   ;scroll a window
   mov bh,00001110b   ;black bg, yellow txt
   mov cx,0000h   ;upper left hand corner
   mov dx,001Fh   ;lower right hand corner
   int 10h   ; i assume this means do it

   ; reposition the cursor
   mov ah,2   ;set cursor position function
   mov dx,0001h   ; row 0 col 1
   mov bh,0   ; video page 0
   int 10h   ; i assume this means do it again

   ; write the word file to the bar
   mov dx, OFFSET file
   call writestring

   ; move to the position of the next menu item
   mov ah,2   ; set cursor funciton
   mov dx,0009h   ; row 0 col 9
   mov bh,0   ; video page 0
   int 10h   ; make it so...

   ; write the edit option
   mov dx, OFFSET edit
   call writestring


   ; move to the position of the next menu item
   mov ah,2
   mov dx,0012h   ; row 0 col 18
   mov bh,0   ; video page 0
   int 10h   ; make it so...

   ; write the help option
   mov dx, OFFSET help
   call writestring

   ; okay, we now have the freakin bar. 
   ; set the editable area to be white on red.
   
   ; create the window
   mov ax,0600h   ; scroll a window
   mov bh,11000000b   ; red bg, white txt
   mov cx,0101h   ; row 1 col 1
   mov dx,153Fh   ; row 15 col 16
   int 10h



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

; *   THIS SECTION OF THE CODE IS FOR WHEN THE CTRL F BUTTON IS PRESSED      *

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


                   ; ************************       <  FILE  >       ****************************



; ***THE FIRST THING WE MUST DO IS GO TO THE WORD "FILE" AND COLOR IT TO SIGNIFY SELECTION***

   ; move to the file location
   mov ah,2   ; go to...
   mov dx,0001h   ; row 0 col 1
   mov bh,1   ; video page 1
   int 10h   ; make it so...

   ; now that we're in the right place, color the word File
   mov ax,0600h   ; draw a window
   mov bh,11100000b   ; invert the colors
   mov cx, 0001h   ; left hand side
   mov dx, 0004h   ; right hand side
   int 10h   ; make it so...

   ; move to the word file location
   mov ah,2
   mov dx,0001h
   mov bh,1
   int 10h

   ; write the word file in the right place
   mov dx, OFFSET file
   call writestring



exit

main ENDP
END main

If I change it to video page 0 when I try to write the word File again it works fine, but video page one prints it at the end of the line after the word "Help."  I can't figure out why, can anyone explain this?

MichaelW

I am assuming you intend to use display page swapping to effectively save and restore the background for your drop-down menu.

The display pages are separate areas of the display memory, only one page is visible at any time, and the VGA BIOS maintains separate cursor positions for each of the pages. The following description assumes that your drop down will be on display page 1, and everything else will be on display page 0 (the default). Basically, to open your drop down you must copy the contents of page 0 to page 1, draw the drop down on page 1, and then set the active (visible) page to page 1. To close the drop down you simply set the active page back to page 0.

To copy the contents of page 0 to page 1, I would use a REP MOVS_, with the largest move size that the processor can handle (for the default .8086 MOVSW, and for .386+ MOVSD). For the default VGA BIOS mode 3 (80x25 text), the display pages are 1000h (= 4096) bytes each. For the default mode the display buffer is in segment B800h. Page 0 starts at offset 0, page 1 at offset 1000h, etc. Each character occupies 1 byte, and the attribute for the character occupies the next byte.

The VGA BIOS provides a function for switching the active (visible) display page.

In your code where you attempt to invert the colors of "File", you are actually clearing the area so the characters are lost. To invert the colors without disturbing the characters you need to change only the attribute. The VGA BIOS provides a function to do this, or you can easily code your own.

If I were doing this I would encapsulate the BIOS calls and any other necessary routines in procedures with suitably named parameters, and create prototypes for the procedures so I could use INVOKE to call the procedures.
eschew obfuscation

omdown

I thought video page 1 would be on top of the other page . . . man I need to learn this stuff better.  I'm still really new at all of this . . . I need to figure out that REP MOVS_ thing . . . thanks for getting me in the right direction . . . any additional words of wisdom would be greatly appreciated . . .

rea

Some references...

rep
movs
movsb
movsw


If you see a "." between expresion, normally mean become. And "(", ")" like the content of the address at... this 'case' specially when reading the "logic" part.

by example:

Quote
Logic:    (ES:DI) . (DS:SI)
                    if DF = 0
                        SI . SI + 1
                        DI . DI + 1
                    else
                        SI . SI - 1
                        DI . DI - 1

Mean than the content at the address ES:DI become the contents at the address DS:SI and, if direction flag is clear (0) si and di are incremented by 1, if not decremented by 1.

omdown

Okay, I'll work on trying to figure that out.  One question I can't seem to figure out anywhere is how to make it respond to Ctrl + F.  I know how to make it respond to Ctrl, and to F, but not only both at once.  At first I thought it would be something I could define in the top of the file but I can't seem to figure it out.

raymond

Quote from: omdown on May 05, 2005, 01:23:51 AM
Okay, I'll work on trying to figure that out.  One question I can't seem to figure out anywhere is how to make it respond to Ctrl + F.  I know how to make it respond to Ctrl, and to F, but not only both at once.  At first I thought it would be something I could define in the top of the file but I can't seem to figure it out.

That is great if you can respond to either of them.

When you respond to the F, simply check if the Ctrl is also pressed. Then take whatever action is required.

Raymond
When you assume something, you risk being wrong half the time
http://www.ray.masmcode.com

omdown

Well, I thought I was STARTING to get it, but so far I don't think I'm getting it that well because my program sure isn't working.  I've put the full code up as a .txt file if anyone wants to view it and help me understand what to do to get back to page 0.  I've tried what I could think of and (not surprisingly) it doesn't work.   :(

http://www.geocities.com/nextbeatle/Project.txt

I really appreciate all you guys' help, I'm really lost on all of this.   :dazzled:

MichaelW

You can set the visible display page by calling Interrupt 10h, Function 5 with the number of the page you wish to make visible in AL. A short demonstration:

;--------------------------------------------------------------
; Toggles between display page 0 and display page 1, swapping
; pages each time the user presses a key, continuing until the
; user presses escape. Under Windows 2000 and probably XP, to
; see the contents of page 1 you must set the program
; properties so the program opens in full screen mode.
;--------------------------------------------------------------
.model small
.386
.stack
.data
    visiblepage db 0
.code
.startup
  @@:
    mov   ah,5                ; set visible page
    mov   al,visiblepage      ; specify page number
    int   10h
    mov   ah,0eh              ; write teletype
    mov   al,visiblepage      ; load number of visible page
    add   al,'0'              ; convert to decimal digit
    mov   bh,visiblepage      ; write to visible page
    int   10h
    mov   ah,0                ; get keystroke (will wait)
    int   16h
    cmp   al,27               ; exit if escape
    je    @F
    xor   visiblepage,1       ; toggle visible page
    jmp   @B                  ; continue
  @@:
.exit
end


In your code you have multiple code blocks that call Interrupt 10h, Function 2 to set the cursor position. You generally should place frequently repeated code blocks in a procedure. The Irvine16 library includes a procedure that sets the cursor position, but the procedure is hard coded for display page 0. From Irvine16.asm:

;---------------------------------------------------
Gotoxy PROC
;
; Sets the cursor position on video page 0.
; display page.
; Receives: DH,DL = row, column
; Returns: nothing
;---------------------------------------------------
pusha
mov ah,2
mov bh,0
int 10h
popa
ret
Gotoxy ENDP

Obviously, this procedure could be easily altered to take a page argument in BH (if you do so note that you must rename the procedure so the name will not conflict with the name in the library).

Rather than writing the whole program and then trying to debug it, I think it would be easier and ultimately faster to develop the program progressively, testing each block of code as you go and eliminating any errors before you go on to the next block. The Irvine16 library includes procedures (DumpRegs and DumpMem) to help you do this.

If you are having problems with the overall logic of the program, you could try working out the logic by implementing the program in a high-level language (QBasic, for example).
eschew obfuscation

omdown

MichaelW: 

You
Are
Awesome

Thanks so much for helping, you guys are all my best friends forever and I shall bake you cookies (though I'm about as good in the kitchen as I am at programming  :eek )

Thanks again guys, I'll check in again if I get really stuck.