www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/03/09/14:49:23

Date: Thu, 9 Mar 1995 13:14:49 +0500
From: ld AT netrix DOT com
To: badcoe AT bsa DOT bris DOT ac DOT uk
Subject: Re: May I interrupt ?
Cc: djgpp AT sun DOT soe DOT clarkson DOT edu

My comments begin with ***.
Hope they help, 
Long.

> ** CODE BEGINS *************
> 
> #include <pc.h>
> #include <time.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <dpmi.h>
> #include <go32.h>
> 
> #define CLOCK_RATE 1193181
> 
> volatile unsigned int tics = 0;
> volatile unsigned int my_tics = 0;
> unsigned int Clock_Count=0x10000, CCL=0, CCH=0;
> 
> _go32_dpmi_seginfo old_pm_handler, old_rm_handler;
> _go32_dpmi_seginfo new_pm_handler, new_rm_handler;
> _go32_dpmi_registers dummy, old;
> 
> void set_count_one(unsigned int freq) {
>   Clock_Count = CLOCK_RATE / freq;
>   printf("f:%i CC:%i\n", freq, Clock_Count);
>   fflush(stdout);
>                                                 ## Section "J"
> /*  outportb(0x43, 0x34);			##  this is the bit that changes
>   outportb(0x40, (CCL = Clock_Count & 0xff));   ##  the rate of the PIT the
>   outportb(0x40, (CCH = Clock_Count >> 8));*/   ##  program crashes whether this
>                                                 ##  is commented or not.
>   printf("CCL:%i CCH:%i\n", CCL, CCH);
>   fflush(stdout);
> }
> 
> void cleanup() {
>   outportb(0x43, 0x34);
>   outportb(0x40, 0x00);
>   outportb(0x40, 0x00);
>   
>   _go32_dpmi_set_protected_mode_interrupt_vector(8, &old_pm_handler);
>   _go32_dpmi_set_real_mode_interrupt_vector(8, &old_rm_handler);
>   puts("CleanUp");
> }
> 
> void timer_handler() {
>   my_tics++;
>   tics += Clock_Count;
>   if (tics >= 0x10000) {
>     _go32_dpmi_simulate_fcall_iret(&old);

*** When you finish this call, old.x.cs, old.x.ip, old.x.sp, old.x.ss, old.x.bp
*** are changed, and the next time this you make this call, something ought to
*** break.

>     tics -= 0x10000;
>   }

*** The Interrupt Controller does not recieve an ACK here, so it will wait
*** for one (which nobody seems to care to send...:-<)

> }
> 
> int main() {
>   int oldtics = 0, count = 0, speed;
> 
>   _go32_dpmi_get_protected_mode_interrupt_vector(8, &old_pm_handler);
>   _go32_dpmi_get_real_mode_interrupt_vector(8, &old_rm_handler);
>   old.x.cs = old_rm_handler.rm_segment;
>   old.x.ip = old_rm_handler.rm_offset;
>   old.x.ss = old.x.sp = 0;
> 
>   printf("%x %x\n", old_pm_handler.pm_offset,   ## This is odd too, pm_handler
>                     old_rm_handler.rm_offset);  ## seems to have an offset=0

*** No, pm_handler has a value of (If I remember right) a0:00000000 because
*** it is _NOT_ a interrupt gate, but a task gate. That's why the program will
*** crash if you do _go32_dpmi_set_..._p..._vector (8, &old_pm_handler) and
*** keep running the program.
  
>   atexit(cleanup);
>   new_pm_handler.pm_offset = (int)timer_handler;
>   new_pm_handler.pm_selector = _go32_my_cs();
>   new_rm_handler.pm_offset = (int)timer_handler;
>   new_rm_handler.pm_selector = _go32_my_cs();
>   _go32_dpmi_allocate_real_mode_callback_iret(&new_rm_handler, &dummy);
>   _go32_dpmi_allocate_iret_wrapper(&new_pm_handler);
>   _go32_dpmi_set_protected_mode_interrupt_vector(8, &new_pm_handler);
>   _go32_dpmi_set_real_mode_interrupt_vector(8, &new_rm_handler);
> 
>   puts("Entering");
>   fflush(stdout);
> 
>   for(speed = 30; speed < 121; speed *= 2) {
>     set_count_one(speed);  ## Line "X"

*** You should clear the interrupt enable flag before programming the chip,
*** or change the IDT. (Applicaple inside set_count_one and the code above.)

>     puts("Hi");
>     count = 0;
>     while(count < 50) {
> 			   ## Line "Y"
>       if (my_tics > oldtics) {

*** This is due to the interrupt handler (see above.) After it got hit, it NEVER
*** pass control back.

>         oldtics++;
>         count++;
>         printf("%i %i %li\n", my_tics, tics, time(0));
>         fflush(stdout);
>       }
>     }
>   }
> 
>   return 0;
> }
> 
> 
> ** CODE ENDS *********************
> 
> The problem is as follows:
> 
> If line "X" is commented out, the program runs as expected (with my routine
> and the original clock running at 18.3 times per second.
> 
> If line "X" is present then the program seems to hang.  A print at line "Y"
> gets printed but the print inside the "if() {}" doesn't (I did have some
> fflush(stdout)'s in there as well).
> 
> This happens whether or not section "J" is present.
> 
> I read in a FAQ document, that the return values from
> _go32_dpmi_get_protected_mode_interrupt_vector were corrupt and this does
> seem to be the case.  Is their any truth in that ?  Is it related to my
> problem ?
> 
> Any help appreciated, I have looked in the FAQ and didn't see any relevant
> help.
> 
> 	Badders
> 
> 
> 

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019