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

Date: Thu, 09 Mar 1995 16:23:32 EST
From: THE MASKED PROGRAMMER <badcoe AT bsa DOT bristol DOT ac DOT uk>
To: djgpp AT sun DOT soe DOT clarkson DOT edu
Cc: badcoe AT bsa DOT bristol DOT ac DOT uk
Subject: May I interrupt ?

Hi,
	A have a problem with the following test program.

	It supposed to demonstrate increasing the clock-tick and redirecting
int 8 into a routine that only calls the original routine when necessary.


** 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);
    tics -= 0x10000;
  }
}

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
  
  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"
    puts("Hi");
    count = 0;
    while(count < 50) {
			   ## Line "Y"
      if (my_tics > oldtics) {
        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