Search code examples
cvectordosinterruptturbo-c

Unable to get interrupt handlers to work in C


I am currently having trouble getting interrupt handlers to work in C. The idea with my code is to set a vector to IRQ 0, which is the PIT, and from what I can find is interrupt 8 (0x08), after setting the PIT to operate on about 40hz (which from what I can find this is by setting a value of 29829, or 0x7485.

The final intended result of the program is to count to a second, print something to screen, and then repeat that 20 times, at which point it uninstalls itself.

This program was compiled using Borland's Turbo C on an Am486-DX4-100 running at 120mhz with IBM's PC-DOS 2000. The board is the Socket 3 EXP-4045 by DataExpert, but I have the same results on DOSBox.

Here is the code:

#include <dos.h>
#include <stdio.h>
int a = 0;
int b = 0;
void interrupt clocktick(){
    if(a == 40){
        if(b == 20){
            setvect(8, NULL);
        }else b++;
    }else a++;
}
int main(void){
    /* set PIT mode*/
    outp(0x34, 0x43);
    outp(0x85,0x40); /* send low byte*/
    outp(0x74,0x40); /* send high byte*/
    setvect(0x08, clocktick);
    while(1==1){
        printf("a%i, b%i", a, b);
    }
    getchar();
    return 0;
}

The code compiles fine, and when ran, the while look does show that A has been incremented once, but doesn't fire again. Obviously something is generating an interrupt, and it may even be the PIT, but it's not doing it more than once.

I am trying to follow the 1987 user's manual for Turbo C, which tries to describe the method for installing interrupt vectors, but I've obviously done something wrong.

I also need to say I am sorry for not knowing this stuff. I don't mean to waste people's time, but I am in genuine need of a helping hand. My examples were vauge, and after some comments I do see there is stuff I could have done to try to figure out what was going on.


Solution

  • You'd need to tell the PIC that you've finished handling the interrupt, otherwise it won't signal it again. Typically this is done by sending an EOI (0x20) to the PIC base port (0x20), so it would essentially be something like outportb(0x20, 0x20);, preferably near the end of your handler.

    There's some information about the PIC at e.g. https://wiki.osdev.org/8259_PIC