Hey all,
Im working on a simple, text mode, single screen program where I would like to be able to pop up an overlaping window or text for a "yes/no" kinda prompt and when it is satisfied I would like to return the screen to whatever it was before. Is this a movsb kinda thing for the whole screen into maybe the page 1 buffer and then reverse it to page 0 when done?
jon
HAPPY NEW YEAR.. a touch in advance..!!
The method I would use would be to preserve the current image by leaving it intact on the current page and display the new window on the next page. I would first copy the current page to the next page so the window background would appear unchanged when that page was made visible. I would complete as much of the next page as possible before I made it visible. Doing so would avoid problems with flicker/tearing by taking advantage of the automatic synchronization with vertical retrace that AFAIK all recent adapters perform before switching the visible page. To clear the window you would just switch the visible page back to the previous page.
Ok,
How do I determine the starting address of the pages?
2000bytes each, right? 80x25
Use direct memory transfer to copy the page and then I can use BIOS or whatever to do my
page 1 generation and BIOS to display the page. Ok?
mov ax, es ;same seg, keep it simple
mov ds, ax
mov si, page1_adr ; 0B800h ? something like this
mov di, page2_adr ; 0BFD0h ? something like this
mov cx, 2000 ; 2000 bytes per page
rep movsb ; copy ds:si to es:di until cx = 0
mov ah, 0eh ; teletype 20 Z's
mov bh, 01h ; to the hidden page 1
mov al, 'Z'
mov cx, 20
int 10h
mov ah, 05h ; change page and wait for keypress
mov bl, 01h ; page 1
int 10h
; key is pressed
mov ah, 05h ; after keypress switch
mov al, 00h ; back to page 0
int 10h
looks ok? Michael, I like the idea of modifying the saved page (hidden) and then displaying it when it's "ready" instead of
making a scanning mess, as well as a delay, on the current page. jon
daah! 2000 words / page!
mov si, 0b000h ; 4000 bytes / page
mov di, 0b8FA0h
mov cx, 2000
movsw rep
In the 80x25 character-mode there are 2000 character bytes (at the even addresses) and 2000 attribute bytes (at the odd addresses), but each page actually occupies 4096 bytes, with 96 unused bytes at the end of the page. So the starting offset address for page N would be computed as N*4096.
> So the starting offset address for page N would be computed as N*4096
this might not work for all BIOSes. The start of current video page should be read from location 40h:4Eh
If you want to be 100% safe, the CRT must be read directly (3D4h/3B4h, index 0Ch+0Dh). This is VGA standard and is emulated correctly in all DOS boxes I know of. The value read from these ports must be multiplied by 2 for the standard text modes.
Quotethis might not work for all BIOSes
Yes, I should have qualified my statement with "For a standard VGA". I have never encountered an adapter where the pages were a non-standard size, but I know that during the transition from EGA to VGA there were many non-standard adapters produced.
> Yes, I should have qualified my statement with "For a standard VGA".
Even with VGA it might be a problem assuming a page size of 1000h. What about other modes than 80x25:
80x50 (720x400, 8 pixel font)
80x34 (640x480, 14 pixel font)
80x60 (640x480, 8 pixel font)
all three modes require more than 4096 bytes for a page. All are perfectly legal with standard VGA.
Quote
80x50 (720x400, 8 pixel font)
80x34 (640x480, 14 pixel font)
80x60 (640x480, 8 pixel font)
I specified 80x25 character-mode, meaning 80x25, 720x400, with a 9x16 character box. Programming at a register level there is probably some way to bastardize these specs, but AFAIK a "standard" VGA BIOS only does these specs one way. In any case, I doubt that these details are of any use to the OP.
In 80x25/28/43/50 modes, 0000:044c has the screen memory length in bytes and 0000:044e has the screen memory offset (b800:xxxx).
The memory length seems to be the length of chars+attrs plus one line (e.g. 80x26), presumably for scrolling cleanly.
80x60 is usually(?) a VESA mode, so getting the VESA mode info should tell you addresses, although the BDA addresses above should be correct.
> In any case, I doubt that these details are of any use to the OP.
Yes, might be, but then it won't be the first thread which slightly gets off topic.
> I specified 80x25 character-mode, meaning 80x25, 720x400, with a 9x16 character box
I see, sorry, I overlooked that.
> Programming at a register level there is probably some way to bastardize these specs
No, 80x50 can be set at the BIOS level: set video mode 3, then choose 8x8 font.
> 80x60 is usually(?) a VESA mode
No, it works on any VGA: setting 640x480 resolution, 8 pixel character width and 14 pixel font size.
Ok gentlemen,
I took a stab at the screen swap. I wrote 2 subs, one swaps to page 1 the other swaps from page 1 back to 0. Scramble!! Im not sure what happened.
ScrnSwap1: push regs
ds:si 0b800:0000
es:di 0b800:1000h ; 4096 bytes
mov cx, 2047 ; 4096 words starting at 0
rep movsw
pop regs
The screen gets a little funky but when I run sub 2 (opposite of sub 1) the screen comes back and looks fine. Then I get some strange results after that. I must be close here?
jon
by the way, i pulled my BIOS 40:4c and it shows 1000h, good. I pulled also my BIOS 40:4e and it shows 0000h. So page 0 is addressed as 0b800:0000 - 0b800:1000. And page 1 should be 0b800:1000 - 0b800:2000... ok?
Everything looks OK, except the 2047 should be 2048. The instruction will move CX words independent of the starting address.
FWIW, on my Windows 2000 system the BIOS functions (tested 0A and 0F only) can write only to page zero. I suspect that this is a limitation of the NTVDM, and that it probably also affects XP.
Quote
> Programming at a register level there is probably some way to bastardize these specs
No, 80x50 can be set at the BIOS level: set video mode 3, then choose 8x8 font.
By "bastardize" I meant some way to implement 80x25, 720x400, 9x16 character box with a non-standard page size and/or starting address.
I figured it out yesterday!
I scrambled because I forgot to push/pop my ds & es when I did the screen swap procedures. The program got to my string print procedure using losdb and it was printing chars from way off in left field (video memory somewhere). Silly mistake, but I am glad that I was able to resolve it. My application has cheesy windows popping up all over the place now. Works well. Hmm, whats next?
jon