summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/i386/go32
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1995-07-12 19:47:25 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1995-07-12 19:47:25 +0000
commit637df35f96d8023056369fcf2c9943419f1a1b74 (patch)
treea12bd461bf892ccaff6c67571432f0535eb03e96 /c/src/lib/libbsp/i386/go32
parentadded David Glessner's 68302 work. (diff)
downloadrtems-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.c135
-rw-r--r--c/src/lib/libbsp/i386/go32/clock/rtc.c213
-rw-r--r--c/src/lib/libbsp/i386/go32/console/console.c186
-rw-r--r--c/src/lib/libbsp/i386/go32/console/inch.c163
-rw-r--r--c/src/lib/libbsp/i386/go32/console/outch.c151
-rw-r--r--c/src/lib/libbsp/i386/go32/include/bsp.h157
-rw-r--r--c/src/lib/libbsp/i386/go32/include/coverhd.h104
-rw-r--r--c/src/lib/libbsp/i386/go32/startup/bspstart.c134
-rw-r--r--c/src/lib/libbsp/i386/go32/startup/exit.c30
-rw-r--r--c/src/lib/libbsp/i386/go32/startup/setvec.c67
-rw-r--r--c/src/lib/libbsp/i386/go32/timer/timer.c107
-rw-r--r--c/src/lib/libbsp/i386/go32/timer/timerisr.s39
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