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?
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.
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 . . .
Some references...
rep (http://www.clipx.net/ng/asm/ng15a5f.php)
movs (http://www.clipx.net/ng/asm/ng11996.php)
movsb (http://www.clipx.net/ng/asm/ng12076.php)
movsw (http://www.clipx.net/ng/asm/ng124fd.php)
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.
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.
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
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:
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).
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.