2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
2011-02-25 01:05:47 +03:00
|
|
|
// $Id$
|
2001-10-03 17:10:38 +04:00
|
|
|
/////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
2021-01-31 02:55:24 +03:00
|
|
|
// Copyright (C) 2001-2021 The Bochs Project
|
2009-02-08 12:05:52 +03:00
|
|
|
//
|
|
|
|
// This library is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU Lesser General Public
|
|
|
|
// License as published by the Free Software Foundation; either
|
|
|
|
// version 2 of the License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This library is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
|
|
// License along with this library; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
|
2001-06-11 04:16:24 +04:00
|
|
|
/*
|
|
|
|
* Emulator of an Intel 8254/82C54 Programmable Interval Timer.
|
|
|
|
* Greg Alexander <yakovlev@usa.com>
|
|
|
|
*/
|
|
|
|
|
2001-07-02 00:49:46 +04:00
|
|
|
#ifndef _PIT_82C54_H_
|
|
|
|
#define _PIT_82C54_H_ 1
|
|
|
|
|
2021-01-31 02:55:24 +03:00
|
|
|
typedef void (*out_handler_t)(bool value);
|
2001-06-28 05:36:11 +04:00
|
|
|
|
2001-06-11 04:16:24 +04:00
|
|
|
class pit_82C54 : public logfunctions {
|
2001-06-13 03:55:53 +04:00
|
|
|
public:
|
|
|
|
//Please do not use these. They are public because they have to be
|
|
|
|
// to compile on some platforms. They are not to be used by other
|
|
|
|
// classes.
|
|
|
|
|
|
|
|
enum rw_status {
|
|
|
|
LSByte=0,
|
|
|
|
MSByte=1,
|
|
|
|
LSByte_multiple=2,
|
|
|
|
MSByte_multiple=3
|
|
|
|
};
|
|
|
|
|
2001-06-11 04:16:24 +04:00
|
|
|
private:
|
|
|
|
|
|
|
|
enum {
|
|
|
|
MAX_COUNTER=2,
|
|
|
|
MAX_ADDRESS=3,
|
|
|
|
CONTROL_ADDRESS=3,
|
|
|
|
MAX_MODE=5
|
|
|
|
};
|
|
|
|
|
|
|
|
enum real_RW_status {
|
|
|
|
LSB_real=1,
|
|
|
|
MSB_real=2,
|
|
|
|
BOTH_real=3
|
|
|
|
};
|
|
|
|
|
2001-07-02 00:49:46 +04:00
|
|
|
enum problem_type {
|
|
|
|
UNL_2P_READ=1
|
|
|
|
};
|
|
|
|
|
2001-06-11 04:16:24 +04:00
|
|
|
struct counter_type {
|
|
|
|
//Chip IOs;
|
2021-01-31 02:55:24 +03:00
|
|
|
bool GATE; //GATE Input value at end of cycle
|
|
|
|
bool OUTpin; //OUT output this cycle
|
2001-06-11 04:16:24 +04:00
|
|
|
|
|
|
|
//Architected state;
|
|
|
|
Bit32u count; //Counter value this cycle
|
|
|
|
Bit16u outlatch; //Output latch this cycle
|
|
|
|
Bit16u inlatch; //Input latch this cycle
|
|
|
|
Bit8u status_latch;
|
|
|
|
|
|
|
|
//Status Register data;
|
|
|
|
Bit8u rw_mode; //2-bit R/W mode from command word register.
|
|
|
|
Bit8u mode; //3-bit mode from command word register.
|
2021-01-31 02:55:24 +03:00
|
|
|
bool bcd_mode; //1-bit BCD vs. Binary setting.
|
|
|
|
bool null_count; //Null count bit of status register.
|
2001-06-11 04:16:24 +04:00
|
|
|
|
|
|
|
//Latch status data;
|
2021-01-31 02:55:24 +03:00
|
|
|
bool count_LSB_latched;
|
|
|
|
bool count_MSB_latched;
|
|
|
|
bool status_latched;
|
2001-06-11 04:16:24 +04:00
|
|
|
|
|
|
|
//Miscelaneous State;
|
2001-06-13 03:55:53 +04:00
|
|
|
Bit32u count_binary; //Value of the count in binary.
|
2021-01-31 02:55:24 +03:00
|
|
|
bool triggerGATE; //Whether we saw GATE rise this cycle.
|
2001-06-11 04:16:24 +04:00
|
|
|
rw_status write_state; //Read state this cycle
|
|
|
|
rw_status read_state; //Read state this cycle
|
2021-01-31 02:55:24 +03:00
|
|
|
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;
|
2001-06-28 02:25:24 +04:00
|
|
|
Bit32u next_change_time; //Next time something besides count changes.
|
|
|
|
//0 means never.
|
2006-01-08 23:39:08 +03:00
|
|
|
out_handler_t out_handler; // OUT pin callback (for IRQ0)
|
2001-06-11 04:16:24 +04:00
|
|
|
};
|
|
|
|
|
|
|
|
counter_type counter[3];
|
|
|
|
|
|
|
|
Bit8u controlword;
|
|
|
|
|
2001-07-02 00:49:46 +04:00
|
|
|
int seen_problems;
|
|
|
|
|
2001-06-11 04:16:24 +04:00
|
|
|
void latch_counter(counter_type & thisctr);
|
|
|
|
|
2021-01-31 02:55:24 +03:00
|
|
|
void set_OUT (counter_type & thisctr, bool data);
|
2001-06-11 04:16:24 +04:00
|
|
|
|
2003-03-03 02:59:12 +03:00
|
|
|
void set_count (counter_type & thisctr, Bit32u data) BX_CPP_AttrRegparmN(2);
|
2001-06-13 03:55:53 +04:00
|
|
|
|
2003-03-03 02:59:12 +03:00
|
|
|
void set_count_to_binary (counter_type & thisctr) BX_CPP_AttrRegparmN(1);
|
2001-06-13 03:55:53 +04:00
|
|
|
|
2003-03-03 02:59:12 +03:00
|
|
|
void set_binary_to_count (counter_type & thisctr) BX_CPP_AttrRegparmN(1);
|
2001-06-13 03:55:53 +04:00
|
|
|
|
2003-03-03 02:59:12 +03:00
|
|
|
void decrement (counter_type & thisctr) BX_CPP_AttrRegparmN(1);
|
2001-06-11 04:16:24 +04:00
|
|
|
|
2003-03-03 02:59:12 +03:00
|
|
|
void decrement_multiple(counter_type & thisctr, Bit32u cycles) BX_CPP_AttrRegparmN(2);
|
2001-06-28 02:25:24 +04:00
|
|
|
|
2003-03-03 02:59:12 +03:00
|
|
|
void clock(Bit8u cnum) BX_CPP_AttrRegparmN(1);
|
2001-06-28 02:25:24 +04:00
|
|
|
|
2001-08-18 07:28:23 +04:00
|
|
|
void print_counter(counter_type & thisctr);
|
|
|
|
|
2001-06-11 04:16:24 +04:00
|
|
|
public:
|
2007-09-28 23:52:08 +04:00
|
|
|
pit_82C54 (void);
|
2001-06-11 04:16:24 +04:00
|
|
|
void init (void);
|
2002-08-27 23:54:46 +04:00
|
|
|
void reset (unsigned type);
|
2006-05-27 19:54:49 +04:00
|
|
|
void register_state(bx_param_c *parent);
|
2001-06-11 04:16:24 +04:00
|
|
|
|
2001-06-28 02:25:24 +04:00
|
|
|
void clock_all(Bit32u cycles);
|
|
|
|
void clock_multiple(Bit8u cnum, Bit32u cycles);
|
2001-06-11 04:16:24 +04:00
|
|
|
|
|
|
|
Bit8u read(Bit8u address);
|
|
|
|
void write(Bit8u address, Bit8u data);
|
|
|
|
|
2021-01-31 02:55:24 +03:00
|
|
|
void set_GATE(Bit8u cnum, bool data);
|
|
|
|
bool read_GATE(Bit8u cnum);
|
2001-06-11 04:16:24 +04:00
|
|
|
|
2021-01-31 02:55:24 +03:00
|
|
|
bool read_OUT(Bit8u cnum);
|
2006-01-08 23:39:08 +03:00
|
|
|
void set_OUT_handler(Bit8u cnum, out_handler_t outh);
|
2001-06-11 04:16:24 +04:00
|
|
|
|
2001-06-28 02:25:24 +04:00
|
|
|
Bit32u get_clock_event_time(Bit8u cnum);
|
|
|
|
Bit32u get_next_event_time(void);
|
2004-01-16 19:30:46 +03:00
|
|
|
Bit16u get_inlatch(int countnum);
|
2021-01-31 02:55:24 +03:00
|
|
|
bool new_count_ready(int countnum);
|
2018-05-14 21:17:04 +03:00
|
|
|
Bit8u get_mode(int countnum);
|
2001-06-11 04:16:24 +04:00
|
|
|
|
2002-02-21 22:22:42 +03:00
|
|
|
void print_cnum(Bit8u cnum);
|
2001-06-11 04:16:24 +04:00
|
|
|
};
|
2001-07-02 00:49:46 +04:00
|
|
|
|
|
|
|
#endif
|