First post, by WhiteFalcon
- Rank
- Member
So I have been trying to create my first TSR that actually takes control instead of just doing something quick in the background. It is hooked to INT 0x09 and when it detects ALT + F being pressed, it is supposed to show a window (or at the moment just a Hello world message and wait for the user to press Esc). This part works.
But now I am trying to store the text screen (it will only be called from text mode 0x03) and then restore it again. And this works too, but only in the command line of DOSBox. Repeatedly, so its probably not breaking anything. Whenever I try to run it in Borland C++ 3.1 (which is the goal) or even MS-DOS EDIT, it does print the message, but then it hangs and I have to restart DOSBox.
I have narrowed it down to the commands that actually do the copying (MOVSW), it does not matter which direction (from the screen to the buffer or the opposite way), it causes the TSR to break something. As it works seemingly fine in the command line, I suppose I am not saving/restoring something. I have tried puttin CLI/STI in there, saving DS just before the copy loop, but no luck... Any idea what I may be missing here?
EDIT: I added the CLD command before both copy blocks as recommended.
#include <stdio.h>
#include <conio.h>
#include <dos.h>
#include <alloc.h>
void mainTSR(void);
void interrupt (*oldKeyHandler)(...);
unsigned char *screen_state, oldx, oldy;
void interrupt newKeyHandler(...)
{
asm cli
asm {
mov ax, 0x0040 // Check if ALT is pressed
mov es, ax
mov di, 0x0017
mov al, es:[di]
test al, 8
jz nothing
in al, 0x60 // Check if J is pressed
cmp al, 0x24
jnz nothing
}
mainTSR();
nothing:
oldKeyHandler();
asm sti
}
void StoreScreen(void)
{
asm {
push ds
push es
pusha
pushf
mov ah, 0x03 // Store cursor position
xor bh, bh
int 0x10
mov [oldx], dl
mov [oldy], dh
les di, screen_state // Store video memory
mov cx, 80 * 25
mov ax, 0xB800
mov ds, ax
xor si, si
cld
rep movsw
popf
popa
pop es
pop ds
}
}
void RestoreScreen(void)
{
asm {
push ds
push es
pusha
pushf
mov ah, 0x02 // Restore cursor position
xor bh, bh
mov dl, [oldx]
mov dh, [oldy]
int 0x10
mov ax, 0xB800 // Restore video memory
mov es, ax
xor di, di
lds si, screen_state
mov cx, 80 * 25
cld
rep movsw
popf
popa
pop es
pop ds
}
}
void mainTSR(void)
{
StoreScreen();
gotoxy(1, 1);
directvideo = 1;
cprintf("Hello world!\r\n");
directvideo = 0;
while (inportb(0x60) != 1) oldKeyHandler();
RestoreScreen();
}
void main(void)
{
screen_state = (unsigned char *) malloc(80 * 25 * 2);
if (screen_state == NULL) return;
oldKeyHandler = getvect(0x09);
setvect(0x09, newKeyHandler);
keep(0, _SS + (_SP/16) + 1 - _psp);
}
Olivetti M4 P75, 32MB RAM, 4GB HDD, 8GB CF, CD-ROM, SoundBlaster AWE 64, Gravis Ultrasound MAX, Roland SCC-1, Roland MT-32, Roland CM-64
Intel 486DX2/66Mhz, 16MB RAM, VGA Trident 512kB, 1.6GB HDD WD, CD-ROM, 256MB CF, SoundBlaster 16 Pro (CT2910)