diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 1995-07-12 19:47:25 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 1995-07-12 19:47:25 +0000 |
commit | 637df35f96d8023056369fcf2c9943419f1a1b74 (patch) | |
tree | a12bd461bf892ccaff6c67571432f0535eb03e96 /c/src/lib/libbsp/i386/go32 | |
parent | added David Glessner's 68302 work. (diff) | |
download | rtems-637df35f96d8023056369fcf2c9943419f1a1b74.tar.bz2 |
Ada95, gnat, go32
Diffstat (limited to 'c/src/lib/libbsp/i386/go32')
-rw-r--r-- | c/src/lib/libbsp/i386/go32/clock/ckinit.c | 135 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/clock/rtc.c | 213 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/console/console.c | 186 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/console/inch.c | 163 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/console/outch.c | 151 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/include/bsp.h | 157 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/include/coverhd.h | 104 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/startup/bspstart.c | 134 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/startup/exit.c | 30 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/startup/setvec.c | 67 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/timer/timer.c | 107 | ||||
-rw-r--r-- | c/src/lib/libbsp/i386/go32/timer/timerisr.s | 39 |
12 files changed, 1486 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/i386/go32/clock/ckinit.c b/c/src/lib/libbsp/i386/go32/clock/ckinit.c new file mode 100644 index 0000000000..5ac1c10d98 --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/clock/ckinit.c @@ -0,0 +1,135 @@ +/* Clock_initialize + * + * This routine initializes the 8254 timer under GO32. + * The tick frequency is 1 millisecond. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * $Id$ + */ + +#include <bsp.h> +#include <clockdrv.h> +#include <stdlib.h> + +volatile rtems_unsigned32 Clock_driver_ticks; +rtems_unsigned32 Clock_isrs_per_tick; /* ISRs per tick */ +rtems_unsigned32 Clock_isrs; /* ISRs until next tick */ +rtems_isr_entry Old_ticker; + +rtems_device_driver Clock_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *pargp, + rtems_id tid, + rtems_unsigned32 *rval +) +{ + Install_clock( Clock_isr ); +} + +void ReInstall_clock( + rtems_isr_entry clock_isr +) +{ + rtems_unsigned32 isrlevel = 0; + + rtems_interrupt_disable( isrlevel ); + (void) set_vector( clock_isr, 0x8, 1 ); + rtems_interrupt_enable( isrlevel ); +} + +void Install_clock( + rtems_isr_entry clock_isr +) +{ + unsigned int microseconds_per_isr; + +#if 0 + /* Initialize clock from on-board real time clock. This breaks the */ + /* test code which assumes which assumes the application will do it. */ + { + rtems_time_of_day Now; + extern void init_rtc( void ); + extern long rtc_read( rtems_time_of_day * tod ); + init_rtc(); + if ( rtc_read( &Now ) >= 0 ) + clock_set( &Now ); + } +#endif + + /* Start by assuming hardware counter is large enough, then */ + /* scale it until it actually fits. */ + Clock_driver_ticks = 0; + Clock_isrs_per_tick = 1; + + if ( BSP_Configuration.microseconds_per_tick == 0 ) + microseconds_per_isr = 10000; /* default 10 ms */ + else + microseconds_per_isr = BSP_Configuration.microseconds_per_tick; + while ( US_TO_TICK(microseconds_per_isr) > 65535 ) { + Clock_isrs_per_tick *= 10; + microseconds_per_isr /= 10; + } + + /* Initialize count in ckisr.c */ + Clock_isrs = Clock_isrs_per_tick; + +#if 0 + /* This was dropped in the last revision. Its a nice thing to know. */ + TICKS_PER_SECOND = 1000000 / (Clock_isrs_per_tick * microseconds_per_isr); +#endif + + if ( BSP_Configuration.ticks_per_timeslice ) { + /* 105/88 approximates TIMER_TICK*1e-6 */ + unsigned int count = US_TO_TICK( microseconds_per_isr ); + + Old_ticker = (rtems_isr_entry) set_vector( clock_isr, 0x8, 1 ); + outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN ); + outport_byte( TIMER_CNTR0, count >> 0 & 0xff ); + outport_byte( TIMER_CNTR0, count >> 8 & 0xff ); + } + atexit( Clock_exit ); +} + +void Clock_exit( void ) +{ + if ( BSP_Configuration.ticks_per_timeslice ) { + extern void rtc_set_dos_date( void ); + + /* reset to DOS value: */ + outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN ); + outport_byte( TIMER_CNTR0, 0 ); + outport_byte( TIMER_CNTR0, 0 ); + + /* reset time-of-day */ + rtc_set_dos_date(); + + /* re-enable old handler: assume it was one of ours */ + set_vector( (rtems_isr_entry)Old_ticker, 0x8, 1 ); + } +} + + +#if 0 && defined(pentium) +/* This can be used to get extremely accurate timing on a pentium. */ +/* It isn't supported. [bryce] */ +#define HZ 90.0 +volatile long long Last_RDTSC; +#define RDTSC()\ + ({ long long _now; __asm __volatile (".byte 0x0F,0x31":"=A"(_now)); _now; }) +long long Kernel_Time_ns( void ) +{ + extern rtems_unsigned32 _TOD_Ticks_per_second; + unsigned isrs_per_second = Clock_isrs_per_tick * _TOD_Ticks_per_second; + long long now; + int flags; + disable_intr( flags ); + now = 1e9 * Clock_driver_ticks / isrs_per_second + + (RDTSC() - Last_RDTSC) * (1000.0/HZ); + enable_intr( flags ); + return now; +} +#endif diff --git a/c/src/lib/libbsp/i386/go32/clock/rtc.c b/c/src/lib/libbsp/i386/go32/clock/rtc.c new file mode 100644 index 0000000000..3dd2cb8f07 --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/clock/rtc.c @@ -0,0 +1,213 @@ +/* + * $Id$ + */ + +#define IO_RTC 0x70 /* RTC */ + +#define RTC_SEC 0x00 /* seconds */ +#define RTC_SECALRM 0x01 /* seconds alarm */ +#define RTC_MIN 0x02 /* minutes */ +#define RTC_MINALRM 0x03 /* minutes alarm */ +#define RTC_HRS 0x04 /* hours */ +#define RTC_HRSALRM 0x05 /* hours alarm */ +#define RTC_WDAY 0x06 /* week day */ +#define RTC_DAY 0x07 /* day of month */ +#define RTC_MONTH 0x08 /* month of year */ +#define RTC_YEAR 0x09 /* month of year */ +#define RTC_STATUSA 0x0a /* status register A */ +#define RTCSA_TUP 0x80 /* time update, don't look now */ + +#define RTC_STATUSB 0x0b /* status register B */ + +#define RTC_INTR 0x0c /* status register C (R) interrupt source */ +#define RTCIR_UPDATE 0x10 /* update intr */ +#define RTCIR_ALARM 0x20 /* alarm intr */ +#define RTCIR_PERIOD 0x40 /* periodic intr */ +#define RTCIR_INT 0x80 /* interrupt output signal */ + +#define RTC_STATUSD 0x0d /* status register D (R) Lost Power */ +#define RTCSD_PWR 0x80 /* clock lost power */ + +#define RTC_DIAG 0x0e /* status register E - bios diagnostic */ +#define RTCDG_BITS "\020\010clock_battery\007ROM_cksum\006config_unit\005memory_size\004fixed_disk\003invalid_time" + +#define RTC_CENTURY 0x32 /* current century - increment in Dec99 */ + + + +#include <rtems.h> +#include <cpu.h> +#include <memory.h> + +void init_rtc( void ) +{ + int s; + + /* initialize brain-dead battery powered clock */ + outport_byte( IO_RTC, RTC_STATUSA ); + outport_byte( IO_RTC+1, 0x26 ); + outport_byte( IO_RTC, RTC_STATUSB ); + outport_byte( IO_RTC+1, 2 ); + + outport_byte( IO_RTC, RTC_DIAG ); + inport_byte( IO_RTC+1, s ); +#if 0 + if (s) printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS); +#endif +} + + +/* convert 2 digit BCD number */ +static int bcd( unsigned int i ) +{ + return ((i/16)*10 + (i%16)); +} + +/* convert years to seconds (from 1970) */ +static unsigned long ytos( int y ) +{ + int i; + unsigned long ret; + + ret = 0; + for(i = 1970; i < y; i++) { + if (i % 4) ret += 365*24*60*60; + else ret += 366*24*60*60; + } + return ret; +} + +/* convert months to seconds */ +static unsigned long mtos( int m, int leap ) +{ + int i; + unsigned long ret; + + ret = 0; + for(i=1;i<m;i++) { + switch(i){ + case 1: case 3: case 5: case 7: case 8: case 10: case 12: + ret += 31*24*60*60; + break; + case 4: case 6: case 9: case 11: + ret += 30*24*60*60; + break; + case 2: + if (leap) + ret += 29*24*60*60; + else + ret += 28*24*60*60; + } + } + return ret; +} + + +static inline unsigned int rtcin( unsigned int what ) +{ + unsigned int r; + outport_byte( IO_RTC, what ); + inport_byte( IO_RTC+1, r ); + return r; +} + + +/* + * Initialize the time of day register, based on the time base which is, e.g. + * from a filesystem. + */ +long rtc_read( rtems_time_of_day * tod ) +{ + int sa; + unsigned long sec = 0; + + memset( tod, 0, sizeof *tod ); + + /* do we have a realtime clock present? (otherwise we loop below) */ + sa = rtcin(RTC_STATUSA); + if (sa == 0xff || sa == 0) + return -1; + + /* ready for a read? */ + while ((sa&RTCSA_TUP) == RTCSA_TUP) + sa = rtcin(RTC_STATUSA); + + tod->year = bcd(rtcin(RTC_YEAR)) + 1900; /* year */ + if (tod->year < 1970) tod->year += 100; + tod->month = bcd(rtcin(RTC_MONTH)); /* month */ + tod->day = bcd(rtcin(RTC_DAY)); /* day */ + (void) bcd(rtcin(RTC_WDAY)); /* weekday */ + tod->hour = bcd(rtcin(RTC_HRS)); /* hour */ + tod->minute = bcd(rtcin(RTC_MIN)); /* minutes */ + tod->second = bcd(rtcin(RTC_SEC)); /* seconds */ + tod->ticks = 0; +#if 0 + sec = ytos( tod->year ); + sec += mtos( tod->month, tod->year % 4 == 0 ); + sec += tod->day * 24*60*60; + sec += tod->hour * 60*60; /* hour */ + sec += tod->minute * 60; /* minutes */ + sec += tod->second; /* seconds */ +#else + sec = 0; +#endif + return sec; +} + + + +/* from djgpp: include before rtems.h to avoid conflicts */ +#undef delay +#include <dos.h> + +void rtc_set_dos_date( void ) +{ + int s; + struct date date; + struct time time; + + /* initialize brain-dead battery powered clock */ + outport_byte( IO_RTC, RTC_STATUSA ); + outport_byte( IO_RTC+1, 0x26 ); + outport_byte( IO_RTC, RTC_STATUSB ); + outport_byte( IO_RTC+1, 2 ); + + outport_byte( IO_RTC, RTC_DIAG ); + inport_byte( IO_RTC+1, s ); + if (s) { +#if 0 + printf("RTC BIOS diagnostic error %b\n", s, RTCDG_BITS); +#else + return; +#endif + } + + /* check for presence of clock */ + s = rtcin(RTC_STATUSA); + if ( s == 0xff || s == 0 ) { +#if 0 + printf( "Real-time clock not found\n" ); +#endif + return; + } + + /* ready for a read? */ + while ((s & RTCSA_TUP) == RTCSA_TUP) + s = rtcin(RTC_STATUSA); + + date.da_year = bcd(rtcin(RTC_YEAR)) + 1900; /* year */ + if ( date.da_year < 1970) date.da_year += 100; + date.da_year -= 1980; + date.da_mon = bcd(rtcin(RTC_MONTH)); /* month */ + date.da_day = bcd(rtcin(RTC_DAY)); /* day */ + + (void)bcd(rtcin(RTC_WDAY)); /* weekday */ + + time.ti_hour = bcd(rtcin(RTC_HRS)); /* hour */ + time.ti_min = bcd(rtcin(RTC_MIN)); /* minutes */ + time.ti_sec = bcd(rtcin(RTC_SEC)); /* seconds */ + time.ti_hund = 0; + + setdate( & date ); + settime( & time ); +} diff --git a/c/src/lib/libbsp/i386/go32/console/console.c b/c/src/lib/libbsp/i386/go32/console/console.c new file mode 100644 index 0000000000..d7e5641e22 --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/console/console.c @@ -0,0 +1,186 @@ +/* + * This file contains the go32 console IO package. + * + * $Id$ + */ + +#define IBMPC_INIT + +#include <stdlib.h> + +#include <rtems.h> +#include "console.h" +#include "bsp.h" + +#include <dpmi.h> +#include <go32.h> + +/* console_cleanup + * + * This routine is called at exit to clean up the console hardware. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +void console_cleanup( void ) +{ + /* nothing */ +} + +/* console_initialize + * + * This routine initializes the console IO driver. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +/* Set this if console I/O should use go32 (DOS) read/write calls. */ +/* Otherwise, direct hardware accesses will be used. */ +int _IBMPC_Use_Go32_IO = 0; + +static rtems_isr_entry old_keyboard_isr = NULL; +extern void _IBMPC_keyboard_isr( rtems_unsigned32 interrupt ); + + +rtems_device_driver console_initialize( + rtems_device_major_number major, + rtems_device_minor_number minor, + void *arg, + rtems_id self, + rtems_unsigned32 *status +) +{ + if ( _IBMPC_Use_Go32_IO ) { + /* Nothing. We let DOS and go32 do all the work. */ + } else { + /* Grap the keyboard interrupt so DOS doesn't steal our */ + /* keystrokes. */ + rtems_status_code status; + status = rtems_interrupt_catch( _IBMPC_keyboard_isr, 9, + &old_keyboard_isr ); + if ( status ) { + int write( int, void *, int ); + void exit( int ); + char msg[] = "error initializing keyboard\n"; + write( 2, msg, sizeof msg - 1 ); + exit( 1 ); + } + } + + atexit( console_cleanup ); +} + + +/* is_character_ready + * + * This routine returns TRUE if a character is available. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + */ + +rtems_boolean is_character_ready( + char *ch +) +{ + return _IBMPC_chrdy( ch ) ? TRUE : FALSE; +} + +/* inbyte + * + * This routine reads a character from the UART. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * Return values: + * character read from UART + */ + +char inbyte( void ) +{ + char ch = _IBMPC_inch(); +#if 1 + /* Echo character to screen */ + void outbyte( char ch ); + outbyte( ch ); + if ( ch == '\r' ) + outbyte( '\n' ); +#endif + return ch; +} + +/* outbyte + * + * This routine transmits a character out the port. + * + * Input parameters: + * ch - character to be transmitted + * + * Output parameters: NONE + */ + +void outbyte( char ch ) +{ + _IBMPC_outch( ch ); +} + +/* + * __read -- read bytes from the console. Ignore fd, since + * we only have stdin. + */ + +int __read( + int fd, + char *buf, + int nbytes +) +{ + int i = 0; + + for ( i = 0; i < nbytes; i++ ) { + buf[i] = inbyte(); + if ( buf[i] == '\r' ) { + /* What if this goes past the end of the buffer? We're hosed. [bhc] */ + buf[i++] = '\n'; + buf[i] = '\0'; + break; + } + } + return i; +} + +/* + * __write -- write bytes to the console. Ignore fd, since + * stdout and stderr are the same. Since we have no filesystem, + * open will only return an error. + */ + +int __write( + int fd, + char *buf, + int nbytes +) +{ + int i; + + for (i = 0; i < nbytes; i++) { + if (*(buf + i) == '\n') { + outbyte ('\r'); + } + outbyte (*(buf + i)); + } + return (nbytes); +} diff --git a/c/src/lib/libbsp/i386/go32/console/inch.c b/c/src/lib/libbsp/i386/go32/console/inch.c new file mode 100644 index 0000000000..992723a4a0 --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/console/inch.c @@ -0,0 +1,163 @@ +/* + * $Id$ + */ + +#include <pc.h> +#include <go32.h> +#include <bsp.h> +#include <cpu.h> + +/* + * Ports for PC keyboard + */ +#define KBD_CTL 0x61 +#define KBD_DATA 0x60 +#define KBD_STATUS 0x64 + +static char key_map[] = { +0,033,'1','2','3','4','5','6','7','8','9','0','-','=','\b','\t', +'q','w','e','r','t','y','u','i','o','p','[',']',015,0x80, +'a','s','d','f','g','h','j','k','l',';',047,0140,0x80, +0134,'z','x','c','v','b','n','m',',','.','/',0x80, +'*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +0x80,0x80,0x80,'0',0177 +}; + +static char shift_map[] = { +0,033,'!','@','#','$','%','^','&','*','(',')','_','+','\b','\t', +'Q','W','E','R','T','Y','U','I','O','P','{','}',015,0x80, +'A','S','D','F','G','H','J','K','L',':',042,'~',0x80, +'|','Z','X','C','V','B','N','M','<','>','?',0x80, +'*',0x80,' ',0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, +0x80,0x80,0x80,0x80,'7','8','9',0x80,'4','5','6',0x80, +'1','2','3','0',177 +}; + +extern int _IBMPC_Use_Go32_IO; + +#define KBD_BUF_SIZE 256 +static char kbd_buffer[ KBD_BUF_SIZE ]; +static unsigned int kbd_first = 0; +static unsigned int kbd_last = 0; + +/* This function can be called during a poll for input, or by an ISR. */ +/* Basically any time you want to process a keypress. */ +int _IBMPC_scankey( char * ch ) +{ + unsigned char c; + unsigned char outch; + static int shift_pressed = 0; + static int ctrl_pressed = 0; + static int caps_pressed = 0; + + /* Read keyboard controller, toggle enable */ + inport_byte( KBD_CTL, c ); + outport_byte( KBD_CTL, c & ~0x80 ); + outport_byte( KBD_CTL, c | 0x80 ); + outport_byte( KBD_CTL, c & ~0x80 ); + + /* See if it has data */ + inport_byte( KBD_STATUS, c ); + if ( ( c & 0x01 ) == 0 ) + return 0; + + /* Read the data. Handle nonsense with shift, control, etc. */ + inport_byte( KBD_DATA, c ); + switch ( c ) { + case 0x36: + case 0x2a: + shift_pressed = 1; + return 0; + case 0x3a: + caps_pressed = 1; + return 0; + case 0x1d: + ctrl_pressed = 1; + return 0; + case 0xb6: + case 0xaa: + shift_pressed = 0; + return 0; + case 0xba: + caps_pressed = 0; + return 0; + case 0x9d: + ctrl_pressed = 0; + return 0; + /* + * Ignore unrecognized keys--usually arrow and such + */ + default: + if ( c & 0x80 ) + /* High-bit on means key is being released, not pressed */ + return 0; + if ( c == 88 ) + /* F12 - abort */ + exit( 1 ); + if ( c > 0x39 ) { + return 0; + } + } + + /* Strip high bit, look up in our map */ + c &= 127; + if ( ctrl_pressed ) { + outch = key_map[c]; + outch &= 037; + } else { + outch = shift_pressed ? shift_map[c] : key_map[c]; + if ( caps_pressed ) { + if ( outch >= 'A' && outch <= 'Z' ) outch += 'a' - 'A'; + else if ( outch >= 'a' && outch <= 'z' ) outch -= 'a' - 'A'; + } + } + + *ch = outch; + return 1; +} + + +void _IBMPC_keyboard_isr( rtems_unsigned32 interrupt ) +{ + if ( _IBMPC_scankey( & kbd_buffer[ kbd_last ] ) ) { + /* Got one; save it if there is enough room in buffer. */ + unsigned int next = (kbd_last + 1) % KBD_BUF_SIZE; + if ( next != kbd_first ) + kbd_last = next; + } + + /* Mark interrupt as handled */ + outport_byte( 0x20, 0x20 ); +} + + +int _IBMPC_chrdy( char * ch ) +{ + if ( _IBMPC_Use_Go32_IO ) { + /* Read keyboard via BIOS: raw mode. */ + if ( kbhit() ) { + *ch = getkey(); + return 1; + } else { + return 0; + } + } else { + /* Check buffer our ISR builds */ + if ( kbd_first != kbd_last ) { + *ch = kbd_buffer[ kbd_first ]; + kbd_first = (kbd_first + 1) % KBD_BUF_SIZE; + return 1; + } else { + return 0; + } + } +} + +int _IBMPC_inch( void ) +{ + char Ch; + while ( ! _IBMPC_chrdy( & Ch ) ) + continue; + return Ch; +} diff --git a/c/src/lib/libbsp/i386/go32/console/outch.c b/c/src/lib/libbsp/i386/go32/console/outch.c new file mode 100644 index 0000000000..190baea168 --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/console/outch.c @@ -0,0 +1,151 @@ +/* + * $Id$ + */ + +#include <go32.h> +#include <bsp.h> +#include <cpu.h> + +#include <memory.h> + +#define MAX_COL 80 +#define MAX_ROW 50 + +static unsigned nrow = 25; +static unsigned ncol = 80; +static unsigned short * tvram = TVRAM; +static unsigned char current_col = 0; +static unsigned char current_row = 0; +static unsigned short screen_copy[ MAX_ROW*MAX_COL ]; + +static void init_cons( void ); + +/* + * set_cursor_pos() + * Set cursor position based on current absolute screen offset + */ +static void +set_cursor_pos(void) +{ + register unsigned short gdc_pos = current_row * ncol + current_col; + outport_byte( GDC_REG_PORT, 0xe ); + outport_byte( GDC_VAL_PORT, (gdc_pos >> 8) & 0xff ); + outport_byte( GDC_REG_PORT, 0xf ); + outport_byte( GDC_VAL_PORT, gdc_pos & 0xff ); +} + +/* + * scroll_up() + * Scroll screen up one line + */ +static void +scroll_up( unsigned short * tv, unsigned short * copy, unsigned int lines ) +{ + if ( lines > nrow ) + lines = nrow; + + /* move everything up */ + memmove( copy, copy+ncol*lines, (nrow-lines)*ncol*sizeof copy[0] ); + + /* fill bottom with blanks */ + { + int loop = ncol*lines; + unsigned short * ptr = copy + ncol*(nrow-lines); + while ( --loop >= 0 ) + *ptr++ = (WHITE<<8) | ' '; + } + + /* copy new screen to video buffer */ + dosmemput( copy, nrow*ncol*sizeof copy[0], (int)tv ); +} + + +/* + * PUT() + * Write character at current screen location + */ +inline static void PUT( char c ) +{ + unsigned short loc = current_row*ncol+current_col; + unsigned short val = (WHITE<<8) | c; + screen_copy[loc] = val; + dosmemput( &screen_copy[loc], sizeof screen_copy[0], (int)(tvram+loc) ); +} + +/* + * cons_putc() + * Place a character on next screen position + */ +static void +cons_putc( unsigned char c ) +{ + static int first = 1; + if ( first ) { + init_cons(); + first = 0; + } + + switch (c) { + case '\t': + while ( current_row % 8 ) + cons_putc(' '); + break; + case '\r': + current_col = 0; + break; + case '\n': + if ( ++current_row >= nrow ) { + scroll_up( tvram, screen_copy, 1 ); + current_row -= 1; + } + break; + case '\b': + if ( current_col > 0 ) { + --current_col; + PUT(' '); + } + break; + default: + PUT(c); + current_col += 1; + if ( current_col >= ncol ) { + current_col = 0; + current_row += 1; + if ( current_row >= nrow ) { + scroll_up( tvram, screen_copy, 1 ); + current_row -= 1; + } + } + }; + set_cursor_pos(); +} + + +/* + * init_cons() + * Hook for any early setup + */ +static void +init_cons( void ) +{ +#if 0 + /* Get a copy of original screen */ + dosmemget( (int)tvram, nrow*ncol*sizeof *tvram, screen_copy ); +#else + /* Clear entire screen */ + scroll_up( tvram, screen_copy, nrow ); +#endif +} + + + +void _IBMPC_outch( unsigned char ch ) +{ + extern int _IBMPC_Use_Go32_IO; + + if ( _IBMPC_Use_Go32_IO ) { + write( 1, &ch, 1 ); + } else { + cons_putc( ch ); + } +} diff --git a/c/src/lib/libbsp/i386/go32/include/bsp.h b/c/src/lib/libbsp/i386/go32/include/bsp.h new file mode 100644 index 0000000000..a9cfa8a987 --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/include/bsp.h @@ -0,0 +1,157 @@ +/* bsp.h + * + * This include file definitions related to the ibm386 (go32) board. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __IBMPC_h +#define __IBMPC_h + +#ifdef __cplusplus +extern "C" { +#endif + +#include <rtems.h> +#include <cpu.h> +#include <iosupp.h> + +/* + * Define the time limits for RTEMS Test Suite test durations. + * Long test and short test duration limits are provided. These + * values are in seconds and need to be converted to ticks for the + * application. + * + */ + +#define MAX_LONG_TEST_DURATION 300 /* 5 minutes = 300 seconds */ +#define MAX_SHORT_TEST_DURATION 3 /* 3 seconds */ + + +/* + * Define the interrupt mechanism for Time Test 27 + * + * NOTE: Use a software interrupt for the i386. + */ +#define MUST_WAIT_FOR_INTERRUTPT 0 +#define Install_tm27_vector( handler ) set_vector( (handler), 0x90, 1 ) +#define Cause_tm27_intr() asm volatile( "int $0x90" : : ); +#define Clear_tm27_intr() +#define Lower_tm27_intr() + + +/* + * Simple spin delay in microsecond units for device drivers. + * This is very dependent on the clock speed of the target. + */ + +#define delay( _microseconds ) { \ + rtems_unsigned32 _cnt = (_microseconds); \ + asm volatile ("0: nop; mov %0,%0; loop 0b" : "=c"(_cnt) : "0"(_cnt) ); \ +} + + +/* Constants */ + +/* Assume color console */ +#define COLOR 1 +#if COLOR +# define GDC_REG_PORT 0x3d4 +# define GDC_VAL_PORT 0x3d5 +# define TVRAM ((unsigned short *)0xb8000L) +#else +# define GDC_REG_PORT 0x3b4 +# define GDC_VAL_PORT 0x3b5 +# define TVRAM ((unsigned short *)0xb0000L) +#endif + +/* White character attribute--works for MGA and CGA */ +#define WHITE 0x07 + +/* Ports for PC keyboard */ +#define KBD_CTL 0x61 +#define KBD_DATA 0x60 +#define KBD_STATUS 0x64 + +/* Constants relating to the 8254 (or 8253) programmable interval timers */ + /* Port address of the control port and timer channels */ +/* + * Macros for specifying values to be written into a mode register. + */ +#define IO_TIMER1 0x40 +#define TIMER_CNTR0 (IO_TIMER1 + 0) /* timer 0 counter port */ +#define TIMER_CNTR1 (IO_TIMER1 + 1) /* timer 1 counter port */ +#define TIMER_CNTR2 (IO_TIMER1 + 2) /* timer 2 counter port */ +#define TIMER_MODE (IO_TIMER1 + 3) /* timer mode port */ +#define TIMER_SEL0 0x00 /* select counter 0 */ +#define TIMER_SEL1 0x40 /* select counter 1 */ +#define TIMER_SEL2 0x80 /* select counter 2 */ +#define TIMER_INTTC 0x00 /* mode 0, intr on terminal cnt */ +#define TIMER_ONESHOT 0x02 /* mode 1, one shot */ +#define TIMER_RATEGEN 0x04 /* mode 2, rate generator */ +#define TIMER_SQWAVE 0x06 /* mode 3, square wave */ +#define TIMER_SWSTROBE 0x08 /* mode 4, s/w triggered strobe */ +#define TIMER_HWSTROBE 0x0a /* mode 5, h/w triggered strobe */ +#define TIMER_LATCH 0x00 /* latch counter for reading */ +#define TIMER_LSB 0x10 /* r/w counter LSB */ +#define TIMER_MSB 0x20 /* r/w counter MSB */ +#define TIMER_16BIT 0x30 /* r/w counter 16 bits, LSB first */ +#define TIMER_BCD 0x01 /* count in BCD */ + +/* The internal tick rate in ticks per second */ +#define TIMER_TICK 1193182 +#define US_TO_TICK(us) (((us)*105+44)/88) +#define TICK_TO_US(tk) (((tk)*88+52)/105) + +/* Structures */ + +#ifdef IBMPC_INIT +#undef BSP_EXTERN +#define BSP_EXTERN +#else +#undef BSP_EXTERN +#define BSP_EXTERN extern +#endif + +/* functions */ + +int _IBMPC_chrdy( char * ch ); +int _IBMPC_inch( void ); +void _IBMPC_outch( unsigned char ); + +/* miscellaneous stuff assumed to exist */ + +extern rtems_configuration_table BSP_Configuration; + +#if 0 +extern i386_IDT_slot Interrupt_descriptor_table[ 256 ]; +extern i386_GDT_slot Global_descriptor_table[ 8192 ]; +BSP_EXTERN unsigned short Idt[3]; /* Interrupt Descriptor Table Address */ +BSP_EXTERN unsigned short Gdt[3]; /* Global Descriptor Table Address */ +BSP_EXTERN unsigned int Idt_base; +BSP_EXTERN unsigned int Gdt_base; +#endif + +/* routines */ + +i386_isr set_vector( + rtems_isr_entry handler, + rtems_vector_number vector, + int type +); + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ + diff --git a/c/src/lib/libbsp/i386/go32/include/coverhd.h b/c/src/lib/libbsp/i386/go32/include/coverhd.h new file mode 100644 index 0000000000..ab65a05107 --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/include/coverhd.h @@ -0,0 +1,104 @@ +/* coverhd.h + * + * This include file has defines to represent the overhead associated + * with calling a particular directive from C on this target. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#ifndef __COVERHD_h +#define __COVERHD_h + +#ifdef __cplusplus +extern "C" { +#endif + +#define CALLING_OVERHEAD_INITIALIZE_EXECUTIVE 0 +#define CALLING_OVERHEAD_SHUTDOWN_EXECUTIVE 0 +#define CALLING_OVERHEAD_TASK_CREATE 0 +#define CALLING_OVERHEAD_TASK_IDENT 0 +#define CALLING_OVERHEAD_TASK_START 0 +#define CALLING_OVERHEAD_TASK_RESTART 0 +#define CALLING_OVERHEAD_TASK_DELETE 0 +#define CALLING_OVERHEAD_TASK_SUSPEND 0 +#define CALLING_OVERHEAD_TASK_RESUME 0 +#define CALLING_OVERHEAD_TASK_SET_PRIORITY 0 +#define CALLING_OVERHEAD_TASK_MODE 0 +#define CALLING_OVERHEAD_TASK_GET_NOTE 0 +#define CALLING_OVERHEAD_TASK_SET_NOTE 0 +#define CALLING_OVERHEAD_TASK_WAKE_WHEN 0 +#define CALLING_OVERHEAD_TASK_WAKE_AFTER 0 +#define CALLING_OVERHEAD_INTERRUPT_CATCH 0 +#define CALLING_OVERHEAD_CLOCK_GET 0 +#define CALLING_OVERHEAD_CLOCK_SET 0 +#define CALLING_OVERHEAD_CLOCK_TICK 0 + +#define CALLING_OVERHEAD_TIMER_CREATE 0 +#define CALLING_OVERHEAD_TIMER_IDENT 0 +#define CALLING_OVERHEAD_TIMER_DELETE 0 +#define CALLING_OVERHEAD_TIMER_FIRE_AFTER 0 +#define CALLING_OVERHEAD_TIMER_FIRE_WHEN 0 +#define CALLING_OVERHEAD_TIMER_RESET 0 +#define CALLING_OVERHEAD_TIMER_CANCEL 0 +#define CALLING_OVERHEAD_SEMAPHORE_CREATE 0 +#define CALLING_OVERHEAD_SEMAPHORE_DELETE 0 +#define CALLING_OVERHEAD_SEMAPHORE_IDENT 0 +#define CALLING_OVERHEAD_SEMAPHORE_OBTAIN 0 +#define CALLING_OVERHEAD_SEMAPHORE_RELEASE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_CREATE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_IDENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_DELETE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_SEND 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_URGENT 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_BROADCAST 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_RECEIVE 0 +#define CALLING_OVERHEAD_MESSAGE_QUEUE_FLUSH 0 + +#define CALLING_OVERHEAD_EVENT_SEND 0 +#define CALLING_OVERHEAD_EVENT_RECEIVE 0 +#define CALLING_OVERHEAD_SIGNAL_CATCH 0 +#define CALLING_OVERHEAD_SIGNAL_SEND 0 +#define CALLING_OVERHEAD_PARTITION_CREATE 0 +#define CALLING_OVERHEAD_PARTITION_IDENT 0 +#define CALLING_OVERHEAD_PARTITION_DELETE 0 +#define CALLING_OVERHEAD_PARTITION_GET_BUFFER 0 +#define CALLING_OVERHEAD_PARTITION_RETURN_BUFFER 0 +#define CALLING_OVERHEAD_REGION_CREATE 0 +#define CALLING_OVERHEAD_REGION_IDENT 0 +#define CALLING_OVERHEAD_REGION_DELETE 0 +#define CALLING_OVERHEAD_REGION_GET_SEGMENT 0 +#define CALLING_OVERHEAD_REGION_RETURN_SEGMENT 0 +#define CALLING_OVERHEAD_PORT_CREATE 0 +#define CALLING_OVERHEAD_PORT_IDENT 0 +#define CALLING_OVERHEAD_PORT_DELETE 0 +#define CALLING_OVERHEAD_PORT_EXTERNAL_TO_INTERNAL 0 +#define CALLING_OVERHEAD_PORT_INTERNAL_TO_EXTERNAL 0 + +#define CALLING_OVERHEAD_IO_INITIALIZE 0 +#define CALLING_OVERHEAD_IO_OPEN 0 +#define CALLING_OVERHEAD_IO_CLOSE 0 +#define CALLING_OVERHEAD_IO_READ 0 +#define CALLING_OVERHEAD_IO_WRITE 0 +#define CALLING_OVERHEAD_IO_CONTROL 0 +#define CALLING_OVERHEAD_FATAL_ERROR_OCCURRED 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CREATE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_IDENT 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_DELETE 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_CANCEL 0 +#define CALLING_OVERHEAD_RATE_MONOTONIC_PERIOD 0 +#define CALLING_OVERHEAD_MULTIPROCESSING_ANNOUNCE 0 + +#ifdef __cplusplus +} +#endif + +#endif +/* end of include file */ diff --git a/c/src/lib/libbsp/i386/go32/startup/bspstart.c b/c/src/lib/libbsp/i386/go32/startup/bspstart.c new file mode 100644 index 0000000000..6478ab1bec --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/startup/bspstart.c @@ -0,0 +1,134 @@ +/* bsp_start() + * + * This routine starts the application. It includes application, + * board, and monitor specific initialization and configuration. + * The generic CPU dependent initialization has been performed + * before this routine is invoked. + * + * INPUT: NONE + * + * OUTPUT: NONE + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include <rtems.h> +#include <bsp.h> +#include <cpu.h> +#include <libcsupport.h> + +#include <stackchk.h> + +/* + * The original table from the application and our copy of it with + * some changes. + */ + +extern rtems_configuration_table Configuration; +rtems_configuration_table BSP_Configuration; + +rtems_cpu_table Cpu_table; + +/* Initialize whatever libc we are using + * called from postdriver hook + */ + +void bsp_libc_init() +{ + rtems_unsigned32 heap_start; + +#if 0 + extern int end; + heap_start = (rtems_unsigned32) &end; +#else + void * sbrk( int ); + heap_start = (rtems_unsigned32) sbrk( 64 * 1024 + CPU_ALIGNMENT ); +#endif + if (heap_start & (CPU_ALIGNMENT-1)) + heap_start = (heap_start + CPU_ALIGNMENT) & ~(CPU_ALIGNMENT-1); + + RTEMS_Malloc_Initialize((void *) heap_start, 64 * 1024, 0); + + /* + * Set up for the libc handling. + */ + + if (BSP_Configuration.ticks_per_timeslice > 0) + libc_init(1); /* reentrant if possible */ + else + libc_init(0); /* non-reentrant */ + + /* + * Initialize the stack bounds checker + */ + +#ifdef STACK_CHECKER_ON + Stack_check_Initialize(); +#endif + +} + +void bsp_start() +{ + extern void * sbrk( int ); + + Cpu_table.pretasking_hook = NULL; + Cpu_table.predriver_hook = bsp_libc_init; /* RTEMS resources available */ + Cpu_table.postdriver_hook = NULL; /* Call our main() for constructors */ + Cpu_table.idle_task = NULL; /* do not override system IDLE task */ + Cpu_table.do_zero_of_workspace = TRUE; + Cpu_table.interrupt_table_segment = 0;/* get_ds(); */ + Cpu_table.interrupt_table_offset = (void *)0; + Cpu_table.interrupt_stack_size = 4096; + Cpu_table.extra_system_initialization_stack = 0; + + /* + * Copy the table + */ + BSP_Configuration = Configuration; + + BSP_Configuration.work_space_start = sbrk( Configuration.work_space_size ); + if ( BSP_Configuration.work_space_start == 0 ) { + /* Big trouble */ + int write( int, void *, int ); + void _exit( int ); + char msg[] = "bsp_start() couldn't sbrk() RTEMS work space\n"; + write( 2, msg, sizeof msg - 1 ); + _exit( 1 ); + } + + /* + * Add 1 region for Malloc in libc_low + */ + + BSP_Configuration.maximum_regions++; + + /* + * Add 1 extension for newlib libc + */ + +#ifdef RTEMS_NEWLIB + BSP_Configuration.maximum_extensions++; +#endif + + /* + * Add another extension if using the stack checker + */ + +#ifdef STACK_CHECKER_ON + BSP_Configuration.maximum_extensions++; +#endif + + rtems_initialize_executive( &BSP_Configuration, &Cpu_table ); + /* does not return */ + + /* no cleanup necessary for GO32 */ +} diff --git a/c/src/lib/libbsp/i386/go32/startup/exit.c b/c/src/lib/libbsp/i386/go32/startup/exit.c new file mode 100644 index 0000000000..a7c81df0c7 --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/startup/exit.c @@ -0,0 +1,30 @@ +/* + * exit + * + * This routine returns control to DOS. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include <rtems.h> +#include <bsp.h> +#include <clockdrv.h> +#include <iodrv.h> + +#if 0 +/* Prefer to pick up _exit() in djgcc */ +void _exit( ) +{ + Io_cleanup(); + bsp_cleanup(); +} +#endif + diff --git a/c/src/lib/libbsp/i386/go32/startup/setvec.c b/c/src/lib/libbsp/i386/go32/startup/setvec.c new file mode 100644 index 0000000000..42ed99ca3c --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/startup/setvec.c @@ -0,0 +1,67 @@ +/* set_vector + * + * This routine installs an interrupt vector under go32. + * + * INPUT: + * handler - interrupt handler entry point + * vector - vector number + * type - 0 indicates raw hardware connect + * 1 indicates RTEMS interrupt connect + * + * RETURNS: + * address of previous interrupt handler + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + +#include <rtems.h> +#include <bsp.h> + +#include <dpmi.h> +#include <go32.h> + +i386_isr set_vector( /* returns old vector */ + rtems_isr_entry handler, /* isr routine */ + rtems_vector_number vector, /* vector number */ + int type /* RTEMS or RAW intr */ +) +{ + i386_isr previous_isr; + + if ( type ) { + rtems_interrupt_catch( handler, vector, + (rtems_isr_entry *) &previous_isr ); + } else { + /* Interrupt goes straight to the supplied ISR. This code is */ + /* slightly different than that in _CPU_ISR_install_vector */ + /* (which is eventually called by the above) in that this code */ + /* returns the raw entry point as the old handler, while the */ + /* other version returns the old entry point pointed at by the */ + /* rtems ISR table. */ + _go32_dpmi_seginfo handler_info; + + /* get the address of the old handler */ + _go32_dpmi_get_protected_mode_interrupt_vector( vector, &handler_info); + + /* Notice how we're failing to save the pm_segment portion of the */ + /* structure here? That means we might crash the system if we */ + /* try to restore the ISR. Can't fix this until i386_isr is */ + /* redefined. XXX [BHC]. */ + previous_isr = (i386_isr) handler_info.pm_offset; + + /* install the IDT entry */ + handler_info.pm_offset = (int)handler; + handler_info.pm_selector = _go32_my_cs(); + _go32_dpmi_set_protected_mode_interrupt_vector( vector, &handler_info); + } + return previous_isr; +} + diff --git a/c/src/lib/libbsp/i386/go32/timer/timer.c b/c/src/lib/libbsp/i386/go32/timer/timer.c new file mode 100644 index 0000000000..08bf2c86de --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/timer/timer.c @@ -0,0 +1,107 @@ +/* Timer_init() + * + * This routine initializes the timer on the IBM 386. + * + * Input parameters: NONE + * + * Output parameters: NONE + * + * NOTE: It is important that the timer start/stop overhead be + * determined when porting or modifying this code. + * + * COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. + * On-Line Applications Research Corporation (OAR). + * All rights assigned to U.S. Government, 1994. + * + * This material may be reproduced by or for the U.S. Government pursuant + * to the copyright license under the clause at DFARS 252.227-7013. This + * notice must appear in all copies of this file and its derivatives. + * + * $Id$ + */ + + +#include <rtems.h> +#include <cpu.h> +#include <bsp.h> + +volatile rtems_unsigned32 Ttimer_val; +rtems_boolean Timer_driver_Find_average_overhead; + +#if defined(pentium) +static inline unsigned long long rdtsc( void ) +{ + /* Return the value of the on-chip cycle counter. */ + unsigned long long result; + __asm __volatile( ".byte 0x0F, 0x31" : "=A" (result) ); + return result; +} +#else /* pentium */ +rtems_isr timerisr(); +#endif /* pentium */ + +void Timer_initialize() +{ +#if defined(pentium) + Ttimer_val = rdtsc(); +#else /* pentium */ + static int First = 1; + if ( First ) { + /* install ISR */ + set_vector( timerisr, 0x8, 0 ); + + /* Wait for ISR to be called at least once */ + Ttimer_val = 0; + while ( Ttimer_val == 0 ) + continue; + + /* load timer for 250 microsecond period */ + outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_16BIT|TIMER_RATEGEN ); + outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 0 & 0xff); + outport_byte( TIMER_CNTR0, US_TO_TICK(250) >> 8 & 0xff); + + First = 0; + } + Ttimer_val = 0; /* clear timer ISR count */ +#endif /* PENTIUM */ +} + +#define AVG_OVERHEAD 0 /* 0.1 microseconds to start/stop timer. */ +#define LEAST_VALID 1 /* Don't trust a value lower than this */ + + +int Read_timer() +{ + register rtems_unsigned32 total; +#if defined(pentium) + total = rdtsc() - Ttimer_val; +#else /* pentium */ + register rtems_unsigned8 lsb, msb; + register rtems_unsigned32 clicks; + outport_byte( TIMER_MODE, TIMER_SEL0|TIMER_LATCH ); + inport_byte( TIMER_CNTR0, lsb ); + inport_byte( TIMER_CNTR0, msb ); + clicks = msb << 8 | lsb; + total = Ttimer_val + 250 - TICK_TO_US( clicks ); +#endif /* pentium */ + + if ( Timer_driver_Find_average_overhead == 1 ) + return total; + else if ( total < LEAST_VALID ) + return 0; /* below timer resolution */ + else + return total - AVG_OVERHEAD; +} + +rtems_status_code Empty_function( void ) +{ + return RTEMS_SUCCESSFUL; +} + + +void Set_find_average_overhead( + rtems_boolean find_flag +) +{ + Timer_driver_Find_average_overhead = find_flag; +} diff --git a/c/src/lib/libbsp/i386/go32/timer/timerisr.s b/c/src/lib/libbsp/i386/go32/timer/timerisr.s new file mode 100644 index 0000000000..d68c3a7940 --- /dev/null +++ b/c/src/lib/libbsp/i386/go32/timer/timerisr.s @@ -0,0 +1,39 @@ +# timer_isr() +# +# This routine provides the ISR for the timer. The timer is set up +# to generate an interrupt at maximum intervals. +# +# Input parameters: NONE +# +# Output parameters: NONE +# +# COPYRIGHT (c) 1989, 1990, 1991, 1992, 1993, 1994. +# On-Line Applications Research Corporation (OAR). +# All rights assigned to U.S. Government, 1994. +# +# This material may be reproduced by or for the U.S. Government pursuant +# to the copyright license under the clause at DFARS 252.227-7013. This +# notice must appear in all copies of this file and its derivatives. +# +# $Id$ +# + +#include "asm.h" + + BEGIN_CODE + + EXTERN(_Ttimer_val) + +SYM (_timerisr): + addl $250,_Ttimer_val # another 250 microseconds + push edx + push eax + movw $0x20,dx + mov edx,eax + outb al,(dx) # touch interrupt controller + pop eax + pop edx + iret + +END_CODE +END |