Added compiler define to use the new PIT.
Also added a hack to keep the OpenBSD timer problem from filling the log. The new PIT seems to work, but until some enhancements are made to the way the timers and devices.cc work, it'll be slower than the old one.
This commit is contained in:
parent
0359f17c64
commit
fc0ee2dc3e
@ -153,6 +153,7 @@ private:
|
||||
#include "iodev/parallel.h"
|
||||
#include "iodev/pic.h"
|
||||
#include "iodev/pit.h"
|
||||
#include "iodev/pit_wrap.h"
|
||||
#include "iodev/serial.h"
|
||||
#if BX_SUPPORT_SB16
|
||||
# include "iodev/sb16.h"
|
||||
|
@ -23,6 +23,9 @@
|
||||
|
||||
|
||||
#include "bochs.h"
|
||||
|
||||
#ifndef BX_USE_NEW_PIT
|
||||
|
||||
#define LOG_THIS bx_pit.
|
||||
|
||||
|
||||
@ -857,3 +860,5 @@ bx_pit_c::periodic( Bit32u usec_delta )
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
||||
#endif // #ifndef BX_USE_NEW_PIT
|
||||
|
@ -23,6 +23,9 @@
|
||||
#ifndef _BX_PIT_H
|
||||
#define _BX_PIT_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifndef BX_USE_NEW_PIT
|
||||
|
||||
#if BX_USE_PIT_SMF
|
||||
# define BX_PIT_SMF static
|
||||
@ -93,4 +96,5 @@ private:
|
||||
|
||||
extern bx_pit_c bx_pit;
|
||||
|
||||
#endif // #ifndef BX_USE_NEW_PIT
|
||||
#endif // #ifndef _BX_PIT_H
|
||||
|
@ -45,7 +45,11 @@
|
||||
thisctr.count_LSB_latched=1;
|
||||
thisctr.count_MSB_latched=1;
|
||||
case MSByte_multiple:
|
||||
BX_ERROR(("Unknown behavior when latching during 2-part read."));
|
||||
if(!(seen_problems & UNL_2P_READ)) {
|
||||
seen_problems|=UNL_2P_READ;
|
||||
BX_ERROR(("Unknown behavior when latching during 2-part read."));
|
||||
BX_ERROR((" This message will not be repeated."));
|
||||
}
|
||||
//I guess latching and resetting to LSB first makes sense;
|
||||
thisctr.read_state=LSByte_multiple;
|
||||
thisctr.outlatch=thisctr.count & 0xFFFF;
|
||||
@ -131,7 +135,9 @@
|
||||
counter[i].count_LSB_latched=0;
|
||||
counter[i].count_MSB_latched=0;
|
||||
counter[i].status_latched=0;
|
||||
counter[i].next_change_time=0;
|
||||
}
|
||||
seen_problems=0;
|
||||
}
|
||||
|
||||
pit_82C54::pit_82C54 (void) {
|
||||
|
@ -6,6 +6,9 @@
|
||||
* that you can experiment with it. (bbd)
|
||||
*/
|
||||
|
||||
#ifndef _PIT_82C54_H_
|
||||
#define _PIT_82C54_H_ 1
|
||||
|
||||
#include "bochs.h"
|
||||
|
||||
#ifdef OUT
|
||||
@ -42,6 +45,10 @@ private:
|
||||
BOTH_real=3
|
||||
};
|
||||
|
||||
enum problem_type {
|
||||
UNL_2P_READ=1
|
||||
};
|
||||
|
||||
struct counter_type {
|
||||
//Chip IOs;
|
||||
bool GATE; //GATE Input value at end of cycle
|
||||
@ -81,6 +88,8 @@ private:
|
||||
|
||||
Bit8u controlword;
|
||||
|
||||
int seen_problems;
|
||||
|
||||
void latch_counter(counter_type & thisctr);
|
||||
|
||||
void set_OUT (counter_type & thisctr, bool data);
|
||||
@ -116,3 +125,5 @@ public:
|
||||
Bit32u get_next_event_time(void);
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -23,20 +23,22 @@
|
||||
|
||||
|
||||
#include "bochs.h"
|
||||
#include "pit82c54.h"
|
||||
#include "pit_wrap.h"
|
||||
#define LOG_THIS bx_pit2.
|
||||
|
||||
bx_pit2_c bx_pit2;
|
||||
#ifdef BX_USE_NEW_PIT
|
||||
|
||||
#include "pit_wrap.h"
|
||||
#define LOG_THIS bx_pit.
|
||||
|
||||
bx_pit_c bx_pit;
|
||||
#if BX_USE_PIT_SMF
|
||||
#define this (&bx_pit2)
|
||||
#define this (&bx_pit)
|
||||
#endif
|
||||
|
||||
#ifdef OUT
|
||||
# undef OUT
|
||||
#endif
|
||||
|
||||
bx_pit2_c::bx_pit2_c( void )
|
||||
bx_pit_c::bx_pit_c( void )
|
||||
{
|
||||
put("PIT");
|
||||
settype(PITLOG);
|
||||
@ -44,36 +46,36 @@ bx_pit2_c::bx_pit2_c( void )
|
||||
|
||||
/* 8254 PIT (Programmable Interval Timer) */
|
||||
|
||||
BX_PIT2_THIS s.timer_handle[1] = BX_NULL_TIMER_HANDLE;
|
||||
BX_PIT2_THIS s.timer_handle[2] = BX_NULL_TIMER_HANDLE;
|
||||
BX_PIT_THIS s.timer_handle[1] = BX_NULL_TIMER_HANDLE;
|
||||
BX_PIT_THIS s.timer_handle[2] = BX_NULL_TIMER_HANDLE;
|
||||
}
|
||||
|
||||
bx_pit2_c::~bx_pit2_c( void )
|
||||
bx_pit_c::~bx_pit_c( void )
|
||||
{
|
||||
}
|
||||
|
||||
int
|
||||
bx_pit2_c::init( bx_devices_c *d )
|
||||
bx_pit_c::init( bx_devices_c *d )
|
||||
{
|
||||
BX_PIT2_THIS devices = d;
|
||||
BX_PIT_THIS devices = d;
|
||||
|
||||
BX_PIT2_THIS devices->register_irq(0, "8254 PIT");
|
||||
BX_PIT2_THIS devices->register_io_read_handler(this, read_handler, 0x0040, "8254 PIT");
|
||||
BX_PIT2_THIS devices->register_io_read_handler(this, read_handler, 0x0041, "8254 PIT");
|
||||
BX_PIT2_THIS devices->register_io_read_handler(this, read_handler, 0x0042, "8254 PIT");
|
||||
BX_PIT2_THIS devices->register_io_read_handler(this, read_handler, 0x0043, "8254 PIT");
|
||||
BX_PIT2_THIS devices->register_io_read_handler(this, read_handler, 0x0061, "8254 PIT");
|
||||
BX_PIT_THIS devices->register_irq(0, "8254 PIT");
|
||||
BX_PIT_THIS devices->register_io_read_handler(this, read_handler, 0x0040, "8254 PIT");
|
||||
BX_PIT_THIS devices->register_io_read_handler(this, read_handler, 0x0041, "8254 PIT");
|
||||
BX_PIT_THIS devices->register_io_read_handler(this, read_handler, 0x0042, "8254 PIT");
|
||||
BX_PIT_THIS devices->register_io_read_handler(this, read_handler, 0x0043, "8254 PIT");
|
||||
BX_PIT_THIS devices->register_io_read_handler(this, read_handler, 0x0061, "8254 PIT");
|
||||
|
||||
BX_PIT2_THIS devices->register_io_write_handler(this, write_handler, 0x0040, "8254 PIT");
|
||||
BX_PIT2_THIS devices->register_io_write_handler(this, write_handler, 0x0041, "8254 PIT");
|
||||
BX_PIT2_THIS devices->register_io_write_handler(this, write_handler, 0x0042, "8254 PIT");
|
||||
BX_PIT2_THIS devices->register_io_write_handler(this, write_handler, 0x0043, "8254 PIT");
|
||||
BX_PIT2_THIS devices->register_io_write_handler(this, write_handler, 0x0061, "8254 PIT");
|
||||
BX_PIT_THIS devices->register_io_write_handler(this, write_handler, 0x0040, "8254 PIT");
|
||||
BX_PIT_THIS devices->register_io_write_handler(this, write_handler, 0x0041, "8254 PIT");
|
||||
BX_PIT_THIS devices->register_io_write_handler(this, write_handler, 0x0042, "8254 PIT");
|
||||
BX_PIT_THIS devices->register_io_write_handler(this, write_handler, 0x0043, "8254 PIT");
|
||||
BX_PIT_THIS devices->register_io_write_handler(this, write_handler, 0x0061, "8254 PIT");
|
||||
|
||||
BX_PIT2_THIS s.speaker_data_on = 0;
|
||||
BX_PIT2_THIS s.refresh_clock_div2 = 0;
|
||||
BX_PIT_THIS s.speaker_data_on = 0;
|
||||
BX_PIT_THIS s.refresh_clock_div2 = 0;
|
||||
|
||||
BX_PIT2_THIS s.timer.init();
|
||||
BX_PIT_THIS s.timer.init();
|
||||
|
||||
return(1);
|
||||
}
|
||||
@ -84,17 +86,17 @@ bx_pit2_c::init( bx_devices_c *d )
|
||||
// redirects to non-static class handler to avoid virtual functions
|
||||
|
||||
Bit32u
|
||||
bx_pit2_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
|
||||
bx_pit_c::read_handler(void *this_ptr, Bit32u address, unsigned io_len)
|
||||
{
|
||||
#if !BX_USE_PIT_SMF
|
||||
bx_pit2_c *class_ptr = (bx_pit2_c *) this_ptr;
|
||||
bx_pit_c *class_ptr = (bx_pit_c *) this_ptr;
|
||||
|
||||
return( class_ptr->read(address, io_len) );
|
||||
}
|
||||
|
||||
|
||||
Bit32u
|
||||
bx_pit2_c::read( Bit32u address, unsigned int io_len )
|
||||
bx_pit_c::read( Bit32u address, unsigned int io_len )
|
||||
{
|
||||
#else
|
||||
UNUSED(this_ptr);
|
||||
@ -109,25 +111,25 @@ bx_pit2_c::read( Bit32u address, unsigned int io_len )
|
||||
switch (address) {
|
||||
|
||||
case 0x40: /* timer 0 - system ticks */
|
||||
return(BX_PIT2_THIS s.timer.read(0));
|
||||
return(BX_PIT_THIS s.timer.read(0));
|
||||
break;
|
||||
case 0x41: /* timer 1 read */
|
||||
return(BX_PIT2_THIS s.timer.read(1));
|
||||
return(BX_PIT_THIS s.timer.read(1));
|
||||
break;
|
||||
case 0x42: /* timer 2 read */
|
||||
return(BX_PIT2_THIS s.timer.read(2));
|
||||
return(BX_PIT_THIS s.timer.read(2));
|
||||
break;
|
||||
case 0x43: /* timer 1 read */
|
||||
return(BX_PIT2_THIS s.timer.read(3));
|
||||
return(BX_PIT_THIS s.timer.read(3));
|
||||
break;
|
||||
|
||||
case 0x61:
|
||||
/* AT, port 61h */
|
||||
BX_PIT2_THIS s.refresh_clock_div2 = !BX_PIT2_THIS s.refresh_clock_div2;
|
||||
return( (BX_PIT2_THIS s.timer.read_OUT(2)<<5) |
|
||||
(BX_PIT2_THIS s.refresh_clock_div2<<4) |
|
||||
(BX_PIT2_THIS s.speaker_data_on<<1) |
|
||||
(BX_PIT2_THIS s.timer.read_GATE(2)) );
|
||||
BX_PIT_THIS s.refresh_clock_div2 = !BX_PIT_THIS s.refresh_clock_div2;
|
||||
return( (BX_PIT_THIS s.timer.read_OUT(2)<<5) |
|
||||
(BX_PIT_THIS s.refresh_clock_div2<<4) |
|
||||
(BX_PIT_THIS s.speaker_data_on<<1) |
|
||||
(BX_PIT_THIS s.timer.read_GATE(2)) );
|
||||
break;
|
||||
|
||||
default:
|
||||
@ -141,16 +143,16 @@ bx_pit2_c::read( Bit32u address, unsigned int io_len )
|
||||
// redirects to non-static class handler to avoid virtual functions
|
||||
|
||||
void
|
||||
bx_pit2_c::write_handler(void *this_ptr, Bit32u address, Bit32u dvalue, unsigned io_len)
|
||||
bx_pit_c::write_handler(void *this_ptr, Bit32u address, Bit32u dvalue, unsigned io_len)
|
||||
{
|
||||
#if !BX_USE_PIT_SMF
|
||||
bx_pit2_c *class_ptr = (bx_pit2_c *) this_ptr;
|
||||
bx_pit_c *class_ptr = (bx_pit_c *) this_ptr;
|
||||
|
||||
class_ptr->write(address, dvalue, io_len);
|
||||
}
|
||||
|
||||
void
|
||||
bx_pit2_c::write( Bit32u address, Bit32u dvalue,
|
||||
bx_pit_c::write( Bit32u address, Bit32u dvalue,
|
||||
unsigned int io_len )
|
||||
{
|
||||
#else
|
||||
@ -170,24 +172,24 @@ bx_pit2_c::write( Bit32u address, Bit32u dvalue,
|
||||
|
||||
switch (address) {
|
||||
case 0x40: /* timer 0: write count register */
|
||||
BX_PIT2_THIS s.timer.write(0,value);
|
||||
BX_PIT_THIS s.timer.write(0,value);
|
||||
break;
|
||||
|
||||
case 0x41: /* timer 1: write count register */
|
||||
BX_PIT2_THIS s.timer.write( 1,value );
|
||||
BX_PIT_THIS s.timer.write( 1,value );
|
||||
break;
|
||||
|
||||
case 0x42: /* timer 2: write count register */
|
||||
BX_PIT2_THIS s.timer.write( 2,value );
|
||||
BX_PIT_THIS s.timer.write( 2,value );
|
||||
break;
|
||||
|
||||
case 0x43: /* timer 0-2 mode control */
|
||||
BX_PIT2_THIS s.timer.write( 3,value );
|
||||
BX_PIT_THIS s.timer.write( 3,value );
|
||||
|
||||
case 0x61:
|
||||
BX_PIT2_THIS s.speaker_data_on = (value >> 1) & 0x01;
|
||||
BX_PIT_THIS s.speaker_data_on = (value >> 1) & 0x01;
|
||||
/*??? only on AT+ */
|
||||
BX_PIT2_THIS s.timer.set_GATE(2, value & 0x01);
|
||||
BX_PIT_THIS s.timer.set_GATE(2, value & 0x01);
|
||||
#if BX_CPU_LEVEL < 2
|
||||
/* ??? XT: */
|
||||
bx_kbd_port61h_write(value);
|
||||
@ -204,20 +206,20 @@ bx_pit2_c::write( Bit32u address, Bit32u dvalue,
|
||||
|
||||
|
||||
int
|
||||
bx_pit2_c::SaveState( class state_file *fd )
|
||||
bx_pit_c::SaveState( class state_file *fd )
|
||||
{
|
||||
fd->write_check ("8254 start");
|
||||
fd->write (&BX_PIT2_THIS s, sizeof (BX_PIT2_THIS s));
|
||||
fd->write (&BX_PIT_THIS s, sizeof (BX_PIT_THIS s));
|
||||
fd->write_check ("8254 end");
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
bx_pit2_c::LoadState( class state_file *fd )
|
||||
bx_pit_c::LoadState( class state_file *fd )
|
||||
{
|
||||
fd->read_check ("8254 start");
|
||||
fd->read (&BX_PIT2_THIS s, sizeof (BX_PIT2_THIS s));
|
||||
fd->read (&BX_PIT_THIS s, sizeof (BX_PIT_THIS s));
|
||||
fd->read_check ("8254 end");
|
||||
return(0);
|
||||
}
|
||||
@ -234,25 +236,27 @@ bx_kbd_port61h_write(Bit8u value)
|
||||
|
||||
|
||||
Boolean
|
||||
bx_pit2_c::periodic( Bit32u usec_delta )
|
||||
bx_pit_c::periodic( Bit32u usec_delta )
|
||||
{
|
||||
Bit32u i=0;
|
||||
Boolean prev_timer0_out = BX_PIT2_THIS s.timer.read_OUT(0);
|
||||
Boolean prev_timer0_out = BX_PIT_THIS s.timer.read_OUT(0);
|
||||
Boolean want_interrupt = 0;
|
||||
|
||||
while(usec_delta>0) {
|
||||
Bit32u maxchange=BX_PIT2_THIS s.timer.get_next_event_time();
|
||||
Bit32u maxchange=BX_PIT_THIS s.timer.get_next_event_time();
|
||||
Bit32u timedelta=maxchange;
|
||||
if((maxchange==0) || (maxchange>usec_delta)) {
|
||||
timedelta=usec_delta;
|
||||
}
|
||||
BX_PIT2_THIS s.timer.clock_all(timedelta);
|
||||
if ( (prev_timer0_out==0) && ((BX_PIT2_THIS s.timer.read_OUT(0))==1) ) {
|
||||
BX_PIT_THIS s.timer.clock_all(timedelta);
|
||||
if ( (prev_timer0_out==0) && ((BX_PIT_THIS s.timer.read_OUT(0))==1) ) {
|
||||
want_interrupt=1;
|
||||
}
|
||||
prev_timer0_out=BX_PIT2_THIS s.timer.read_OUT(0);
|
||||
prev_timer0_out=BX_PIT_THIS s.timer.read_OUT(0);
|
||||
usec_delta-=timedelta;
|
||||
}
|
||||
|
||||
return(want_interrupt);
|
||||
}
|
||||
|
||||
#endif // #ifdef BX_USE_NEW_PIT
|
||||
|
@ -23,23 +23,28 @@
|
||||
#ifndef _BX_PIT_WRAP_H
|
||||
#define _BX_PIT_WRAP_H
|
||||
|
||||
#include "bochs.h"
|
||||
|
||||
#ifdef BX_USE_NEW_PIT
|
||||
|
||||
#include "pit82c54.h"
|
||||
|
||||
#if BX_USE_PIT_SMF
|
||||
# define BX_PIT_SMF static
|
||||
# define BX_PIT2_THIS bx_pit2.
|
||||
# define BX_PIT_THIS bx_pit.
|
||||
#else
|
||||
# define BX_PIT_SMF
|
||||
# define BX_PIT2_THIS this->
|
||||
# define BX_PIT_THIS this->
|
||||
#endif
|
||||
|
||||
#ifdef OUT
|
||||
# undef OUT
|
||||
#endif
|
||||
|
||||
class bx_pit2_c : public logfunctions {
|
||||
class bx_pit_c : public logfunctions {
|
||||
public:
|
||||
bx_pit2_c( void );
|
||||
~bx_pit2_c( void );
|
||||
bx_pit_c( void );
|
||||
~bx_pit_c( void );
|
||||
BX_PIT_SMF int init( bx_devices_c *);
|
||||
BX_PIT_SMF Boolean periodic( Bit32u usec_delta );
|
||||
|
||||
@ -71,6 +76,7 @@ private:
|
||||
BX_PIT_SMF void start(unsigned timerid);
|
||||
};
|
||||
|
||||
extern bx_pit2_c bx_pit2;
|
||||
extern bx_pit_c bx_pit;
|
||||
|
||||
#endif // #ifdef BX_USE_NEW_PIT
|
||||
#endif // #ifndef _BX_PIT_WRAP_H
|
||||
|
Loading…
Reference in New Issue
Block a user