0

I intended to call BIOS interrupt function to detect the position of mouse and I thought it would work if I recover the original area of the mouse displayed on the screen and then "draw" it in its new location.

But here is the result of my program:the image of mouse will be dispayed on the screen and the image will move in response just for one time.Then the program will be stuck until I end it forcibly.

I was using dosbox to simulate dos environment.My develop environment is turbo c 3.0.I was programing under vesa vbe to support svga mode(which turbo c does not totally support).code:

    #define MOUSEX 200
    #define MOUSEY 200
    int MouseInit() // checking if the driver of mouse is installed
    {
        int retcode;
        asm{
            mov AX,0
            INT 33h
            mov retcode,AX
        }

        if(retcode==0) // uninstalled
            return 0;

        return retcode;
    }

    void SetXY() // set range of mouse movement
    {
        asm{
            mov AX,7
            mov CX,0
            mov DX,639 // range of x:0-639
            INT 33h
            mov AX,8
            mov CX,0
            mov DX,479 // range of y:0-479
            INT 33h 
        }
    }

    void setmouse(INT16 x,INT16 y) // set the location of mouse
    {
        asm{
            MOV CX,x
            MOV DX,y
            MOV AX,4
            INT 33H
        }
        xpos = x;
        ypos = y;
    }
    /*
    INT 33H:
    AX = 000Ch // go to user's function when certain acts of the mouse occur
    CX = call mask // define the conditions that will trigger user's interrupt function
      bit 0 call if mouse moves 
      bit 1 call if left button pressed 
      bit 2 call if left button released 
      bit 3 call if right button pressed 
      bit 4 call if right button released 
      bit 5 call if middle button pressed (Mouse Systems/Logitech
              mouse)
      bit 6 call if middle button released (Mouse Sys/Logitech mouse)
    ES:DX -> FAR routine
    Notes:  when the subroutine is called, it is passed the following values
    AX = condition mask (same bit assignments as call mask 
    BX = button state 
    CX = cursor column 
    DX = cursor row
    SI = horizontal mickey count 
    DI = vertical mickey count
   */
void interrupt mousehandler()
{
    int newevent,newxpos,newypos;
    int i,j;
    asm{
        MOV newevent,AX
        MOV newxpos,CX
        MOV newypos,DX
    }
    switch(_AX){
    case 0x01:
        ConcealMouse(xpos,ypos,origin); //clear former mouse image 
        xpos=newxpos;ypos=newypos; // obtain new location of mouse
        for(i=0;i<16;i++)   // save original image of the screen in that new location
           for(j=0;j<16;j++)
               origin[i*16+j]= GetPixel(xpos+j,ypos+i);
        DrawMouse(xpos,ypos); // display mouse in new location(draw the 16*16 lattice on the screen)
 }

}
void installtask(INT16 mask)
{
    asm{
        MOV AX,0CH
        MOV CX,mask
        MOV BX,SEG mousehandler
        MOV ES,BX
        LEA DX,mousehandler
        INT 33H
    }
}

void ShowMouse()
{
    int i,j;

    if(MouseInit()==0){
        SetSVGAMode(3);
        printf("no mouse available!\n");
        exit(1);
    }
   SetXY(); 
   setmouse(MOUSEX,MOUSEY);

   for(i=0;i<16;i++)    // save original image of the screen
       for(j=0;j<16;j++)
           origin[i*16+j]= GetPixel(xpos+j,ypos+i);
   DrawMouse(xpos,ypos); // draw mouse in the given location
   installtask(0x007f);  // waiting for interruption
}

I am pretty sure that the function of drawing mouse and concealing it is correct as I have tested it. Was the interrupt function the cause of failure? Wish for your answer,many thanks.

programforjoy
  • 391
  • 3
  • 12
  • 1
    You were born 20 years too late. – Jabberwocky Aug 13 '15 at 08:21
  • haha,it's a homework from my werid teacher... – programforjoy Aug 13 '15 at 11:37
  • 1. as you do not add the `ConcealMouse` and `DrawMouse` then we can just guess 2. my bet is you are changing some register values inside interrupt handler try to add `pusha,popa` (not sure if old borland C++ do this on its own for all registers or just for the ones used with its C++ engine). 3. have you try debugging? is the interrupt firing on mouse move? does the handler work without interrupt (call it from for loop with predefined mouse movement simulation) if the handler works as a function and not as an interrupt then you have messed up some CPU state – Spektre Aug 14 '15 at 06:16
  • 4. are you sure your VESA programing is OK? have you tried text mode and output just mouse coordinates to check if rest of the code is working? – Spektre Aug 14 '15 at 06:20
  • @Spektre fantastic idea! I checked my code over and solved the problem by adjusting my VESA-related function. I also found it necessary to declare the handler this way: void _saveregs far mousehandler()---Saves and Restores Registers on Entry and Exit. I also found my dosbox tend to crash if I repeatedly run this mouse program but it works the first few times I run it in dosbox. Many thanks to you! – programforjoy Aug 15 '15 at 12:56
  • @programforjoy as you found the solution you should write it as an answer and accept it for others to see quickly... if the repetitive call to ISR handler is causing problems check if stack is not overflowed ... also I am not sure that you got the stack access set from ISR (segment registers may be differently set) or you have some shared variable access problem ... – Spektre Aug 15 '15 at 14:10

0 Answers0