- fixed timer IRQ handler with a callback function for the OUT pin (OUT pin of

the first timer is connected to IRQ line 0)
- code cleanup (indent mode, bool types, reset function, unused stuff)
This commit is contained in:
Volker Ruppert 2006-01-08 20:39:08 +00:00
parent 2795b66f28
commit e662318422
4 changed files with 145 additions and 160 deletions

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: pit82c54.cc,v 1.25 2004-06-19 15:20:13 sshwarts Exp $
// $Id: pit82c54.cc,v 1.26 2006-01-08 20:39:08 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
/*
@ -89,98 +89,101 @@ void pit_82C54::print_cnum(Bit8u cnum) {
}
}
void pit_82C54::set_OUT (counter_type & thisctr, bool data) {
//This will probably have a callback, so I put it here.
thisctr.OUTpin=data;
void pit_82C54::set_OUT (counter_type & thisctr, bx_bool data) {
if (thisctr.OUTpin != data) {
thisctr.OUTpin = data;
if (thisctr.out_handler != NULL) {
thisctr.out_handler(data);
}
}
}
void BX_CPP_AttrRegparmN(2)
pit_82C54::set_count (counter_type & thisctr, Bit32u data) {
thisctr.count=data & 0xFFFF;
set_binary_to_count(thisctr);
}
thisctr.count=data & 0xFFFF;
set_binary_to_count(thisctr);
}
void BX_CPP_AttrRegparmN(1)
pit_82C54::set_count_to_binary(counter_type & thisctr) {
if(thisctr.bcd_mode) {
thisctr.count=
(((thisctr.count_binary/1)%10)<<0) |
(((thisctr.count_binary/10)%10)<<4) |
(((thisctr.count_binary/100)%10)<<8) |
(((thisctr.count_binary/1000)%10)<<12)
;
} else {
thisctr.count=thisctr.count_binary;
}
if(thisctr.bcd_mode) {
thisctr.count=
(((thisctr.count_binary/1)%10)<<0) |
(((thisctr.count_binary/10)%10)<<4) |
(((thisctr.count_binary/100)%10)<<8) |
(((thisctr.count_binary/1000)%10)<<12);
} else {
thisctr.count=thisctr.count_binary;
}
}
void BX_CPP_AttrRegparmN(1)
pit_82C54::set_binary_to_count(counter_type & thisctr) {
if(thisctr.bcd_mode) {
thisctr.count_binary=
(1*((thisctr.count>>0)&0xF)) +
(10*((thisctr.count>>4)&0xF)) +
(100*((thisctr.count>>8)&0xF)) +
(1000*((thisctr.count>>12)&0xF))
;
} else {
thisctr.count_binary=thisctr.count;
}
if(thisctr.bcd_mode) {
thisctr.count_binary=
(1*((thisctr.count>>0)&0xF)) +
(10*((thisctr.count>>4)&0xF)) +
(100*((thisctr.count>>8)&0xF)) +
(1000*((thisctr.count>>12)&0xF));
} else {
thisctr.count_binary=thisctr.count;
}
}
void BX_CPP_AttrRegparmN(1)
pit_82C54::decrement (counter_type & thisctr) {
if(!thisctr.count) {
if(thisctr.bcd_mode) {
thisctr.count=0x9999;
thisctr.count_binary=9999;
} else {
thisctr.count=0xFFFF;
thisctr.count_binary=0xFFFF;
}
if(!thisctr.count) {
if(thisctr.bcd_mode) {
thisctr.count=0x9999;
thisctr.count_binary=9999;
} else {
thisctr.count_binary--;
set_count_to_binary(thisctr);
thisctr.count=0xFFFF;
thisctr.count_binary=0xFFFF;
}
} else {
thisctr.count_binary--;
set_count_to_binary(thisctr);
}
}
void pit_82C54::init (void) {
Bit8u i;
void pit_82C54::init (void) {
Bit8u i;
put("PIT81");
settype(PIT81LOG);
put("PIT81");
settype(PIT81LOG);
for(i=0;i<3;i++) {
BX_DEBUG(("Setting read_state to LSB"));
counter[i].read_state=LSByte;
counter[i].write_state=LSByte;
counter[i].GATE=1;
counter[i].OUTpin=1;
counter[i].triggerGATE=0;
counter[i].mode=4;
counter[i].first_pass=0;
counter[i].bcd_mode=0;
counter[i].count=0;
counter[i].count_binary=0;
counter[i].state_bit_1=0;
counter[i].state_bit_2=0;
counter[i].null_count=0;
counter[i].rw_mode=1;
counter[i].count_written=1;
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;
for(i=0;i<3;i++) {
BX_DEBUG(("Setting read_state to LSB"));
counter[i].read_state=LSByte;
counter[i].write_state=LSByte;
counter[i].GATE=1;
counter[i].OUTpin=1;
counter[i].triggerGATE=0;
counter[i].mode=4;
counter[i].first_pass=0;
counter[i].bcd_mode=0;
counter[i].count=0;
counter[i].count_binary=0;
counter[i].state_bit_1=0;
counter[i].state_bit_2=0;
counter[i].null_count=0;
counter[i].rw_mode=1;
counter[i].count_written=1;
counter[i].count_LSB_latched=0;
counter[i].count_MSB_latched=0;
counter[i].status_latched=0;
counter[i].next_change_time=0;
counter[i].out_handler=NULL;
}
seen_problems=0;
}
pit_82C54::pit_82C54 (void) {
init();
}
pit_82C54::pit_82C54 (void) {
init();
}
void pit_82C54::reset (unsigned type) {
}
void pit_82C54::reset (unsigned type) {
}
void BX_CPP_AttrRegparmN(2)
pit_82C54::decrement_multiple(counter_type & thisctr, Bit32u cycles) {
@ -753,18 +756,18 @@ pit_82C54::clock(Bit8u cnum) {
}
}
void pit_82C54::set_GATE(Bit8u cnum, bool data) {
if(cnum>MAX_COUNTER) {
BX_ERROR(("Counter number incorrect in 82C54 set_GATE"));
} else {
counter_type & thisctr = counter[cnum];
if(!( (thisctr.GATE&&data) || (!(thisctr.GATE||data)) )) {
BX_INFO(("Changing GATE %d to: %d",cnum,data));
thisctr.GATE=data;
if(thisctr.GATE) {
thisctr.triggerGATE=1;
}
switch(thisctr.mode) {
void pit_82C54::set_GATE(Bit8u cnum, bx_bool data) {
if(cnum>MAX_COUNTER) {
BX_ERROR(("Counter number incorrect in 82C54 set_GATE"));
} else {
counter_type & thisctr = counter[cnum];
if (!((thisctr.GATE&&data) || (!(thisctr.GATE||data)))) {
BX_INFO(("Changing GATE %d to: %d",cnum,data));
thisctr.GATE=data;
if (thisctr.GATE) {
thisctr.triggerGATE=1;
}
switch(thisctr.mode) {
case 0:
if(data && thisctr.count_written) {
if(thisctr.null_count) {
@ -845,29 +848,29 @@ pit_82C54::clock(Bit8u cnum) {
}
break;
default:
break;
}
break;
}
}
}
}
bool pit_82C54::read_OUT(Bit8u cnum) {
if(cnum>MAX_COUNTER) {
BX_ERROR(("Counter number incorrect in 82C54 read_OUT"));
return 0;
} else {
return counter[cnum].OUTpin;
}
bx_bool pit_82C54::read_OUT(Bit8u cnum) {
if(cnum>MAX_COUNTER) {
BX_ERROR(("Counter number incorrect in 82C54 read_OUT"));
return 0;
} else {
return counter[cnum].OUTpin;
}
}
bool pit_82C54::read_GATE(Bit8u cnum) {
if(cnum>MAX_COUNTER) {
BX_ERROR(("Counter number incorrect in 82C54 read_GATE"));
return 0;
} else {
return counter[cnum].GATE;
}
bx_bool pit_82C54::read_GATE(Bit8u cnum) {
if(cnum>MAX_COUNTER) {
BX_ERROR(("Counter number incorrect in 82C54 read_GATE"));
return 0;
} else {
return counter[cnum].GATE;
}
}
Bit32u pit_82C54::get_clock_event_time(Bit8u cnum) {
if(cnum>MAX_COUNTER) {
@ -893,5 +896,11 @@ Bit32u pit_82C54::get_next_event_time(void) {
}
Bit16u pit_82C54::get_inlatch(int counternum) {
return counter[counternum].inlatch;
return counter[counternum].inlatch;
}
void pit_82C54::set_OUT_handler(Bit8u counternum, out_handler_t outh)
{
counter[counternum].out_handler = outh;
}

View File

@ -1,20 +1,18 @@
/////////////////////////////////////////////////////////////////////////
// $Id: pit82c54.h,v 1.13 2004-01-16 16:30:46 danielg4 Exp $
// $Id: pit82c54.h,v 1.14 2006-01-08 20:39:08 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
/*
* Emulator of an Intel 8254/82C54 Programmable Interval Timer.
* Greg Alexander <yakovlev@usa.com>
*
* This code is not yet linked into Bochs, but has been included so
* that you can experiment with it. (bbd)
*/
#ifndef _PIT_82C54_H_
#define _PIT_82C54_H_ 1
#include "bochs.h"
//#include "bochs.h"
typedef void (*out_handler_t)(bx_bool value);
class pit_82C54 : public logfunctions {
@ -51,8 +49,8 @@ private:
struct counter_type {
//Chip IOs;
bool GATE; //GATE Input value at end of cycle
bool OUTpin; //OUT output this cycle
bx_bool GATE; //GATE Input value at end of cycle
bx_bool OUTpin; //OUT output this cycle
//Architected state;
Bit32u count; //Counter value this cycle
@ -63,25 +61,26 @@ private:
//Status Register data;
Bit8u rw_mode; //2-bit R/W mode from command word register.
Bit8u mode; //3-bit mode from command word register.
bool bcd_mode; //1-bit BCD vs. Binary setting.
bool null_count; //Null count bit of status register.
bx_bool bcd_mode; //1-bit BCD vs. Binary setting.
bx_bool null_count; //Null count bit of status register.
//Latch status data;
bool count_LSB_latched;
bool count_MSB_latched;
bool status_latched;
bx_bool count_LSB_latched;
bx_bool count_MSB_latched;
bx_bool status_latched;
//Miscelaneous State;
Bit32u count_binary; //Value of the count in binary.
bool triggerGATE; //Whether we saw GATE rise this cycle.
bx_bool triggerGATE; //Whether we saw GATE rise this cycle.
rw_status write_state; //Read state this cycle
rw_status read_state; //Read state this cycle
bool count_written; //Whether a count written since programmed
bool first_pass; //Whether or not this is the first loaded count.
bool state_bit_1; //Miscelaneous state bits.
bool state_bit_2;
bx_bool count_written; //Whether a count written since programmed
bx_bool first_pass; //Whether or not this is the first loaded count.
bx_bool state_bit_1; //Miscelaneous state bits.
bx_bool state_bit_2;
Bit32u next_change_time; //Next time something besides count changes.
//0 means never.
out_handler_t out_handler; // OUT pin callback (for IRQ0)
};
counter_type counter[3];
@ -92,7 +91,7 @@ private:
void latch_counter(counter_type & thisctr);
void set_OUT (counter_type & thisctr, bool data);
void set_OUT (counter_type & thisctr, bx_bool data);
void set_count (counter_type & thisctr, Bit32u data) BX_CPP_AttrRegparmN(2);
@ -119,10 +118,11 @@ public:
Bit8u read(Bit8u address);
void write(Bit8u address, Bit8u data);
void set_GATE(Bit8u cnum, bool data);
bool read_GATE(Bit8u cnum);
void set_GATE(Bit8u cnum, bx_bool data);
bx_bool read_GATE(Bit8u cnum);
bool read_OUT(Bit8u cnum);
bx_bool read_OUT(Bit8u cnum);
void set_OUT_handler(Bit8u cnum, out_handler_t outh);
Bit32u get_clock_event_time(Bit8u cnum);
Bit32u get_next_event_time(void);

View File

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////
// $Id: pit_wrap.cc,v 1.59 2005-06-04 17:44:58 vruppert Exp $
// $Id: pit_wrap.cc,v 1.60 2006-01-08 20:39:08 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2002 MandrakeSoft S.A.
@ -120,6 +120,7 @@ bx_pit_c::init( void )
BX_PIT_THIS s.refresh_clock_div2 = 0;
BX_PIT_THIS s.timer.init();
BX_PIT_THIS s.timer.set_OUT_handler(0, irq_handler);
Bit64u my_time_usec = bx_virt_timer.time_usec();
@ -154,6 +155,7 @@ bx_pit_c::init( void )
void
bx_pit_c::reset(unsigned type)
{
BX_PIT_THIS s.timer.reset(type);
}
void
@ -317,12 +319,8 @@ bx_pit_c::write( Bit32u address, Bit32u dvalue,
} else {
DEV_speaker_beep_off();
}
/*??? only on AT+ */
/* ??? only on AT+ */
BX_PIT_THIS s.timer.set_GATE(2, value & 0x01);
#if BX_CPU_LEVEL < 2
/* ??? XT: */
bx_kbd_port61h_write(value);
#endif
break;
default:
@ -330,12 +328,6 @@ bx_pit_c::write( Bit32u address, Bit32u dvalue,
(unsigned) address, (unsigned) value));
}
if ((BX_PIT_THIS s.timer.read_OUT(0))==1) {
DEV_pic_raise_irq(0);
} else {
DEV_pic_lower_irq(0);
}
if(time_passed ||
(BX_PIT_THIS s.last_next_event_time
!= BX_PIT_THIS s.timer.get_next_event_time())
@ -359,21 +351,8 @@ bx_pit_c::write( Bit32u address, Bit32u dvalue,
}
#if 0
void
bx_kbd_port61h_write(Bit8u value)
bx_bool bx_pit_c::periodic(Bit32u usec_delta)
{
// PcError("KBD_PORT61H_WRITE(): not implemented yet");
UNUSED( value );
}
#endif
bx_bool
bx_pit_c::periodic( Bit32u usec_delta )
{
bx_bool prev_timer0_out = BX_PIT_THIS s.timer.read_OUT(0);
bx_bool want_interrupt = 0;
Bit32u ticks_delta = 0;
#ifdef BX_SCHEDULED_DIE_TIME
@ -399,22 +378,19 @@ bx_pit_c::periodic( Bit32u usec_delta )
timedelta=ticks_delta;
}
BX_PIT_THIS s.timer.clock_all(timedelta);
if ( (prev_timer0_out==0) ) {
if ((BX_PIT_THIS s.timer.read_OUT(0))==1) {
DEV_pic_raise_irq(0);
prev_timer0_out=1;
}
} else {
if ((BX_PIT_THIS s.timer.read_OUT(0))==0) {
DEV_pic_lower_irq(0);
prev_timer0_out=0;
}
}
prev_timer0_out=BX_PIT_THIS s.timer.read_OUT(0);
ticks_delta-=timedelta;
}
return(want_interrupt);
return 0;
}
void bx_pit_c::irq_handler(bx_bool value)
{
if (value == 1) {
DEV_pic_raise_irq(0);
} else {
DEV_pic_lower_irq(0);
}
}
#endif // #if BX_USE_NEW_PIT

View File

@ -1,5 +1,5 @@
/////////////////////////////////////////////////////////////////////////
// $Id: pit_wrap.h,v 1.20 2004-12-13 19:10:38 vruppert Exp $
// $Id: pit_wrap.h,v 1.21 2006-01-08 20:39:08 vruppert Exp $
/////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2001 MandrakeSoft S.A.
@ -95,7 +95,7 @@ private:
BX_PIT_SMF void set_GATE(unsigned pit_id, unsigned value);
BX_PIT_SMF void start(unsigned timerid);
BX_PIT_SMF void second_update_data(void);
BX_PIT_SMF void irq_handler(bx_bool value);
};
extern bx_pit_c bx_pit;