1 /////////////////////////////////////////////////////////////////////////
2 // $Id: pit82c54.h 14109 2021-01-30 23:55:24Z vruppert $
3 /////////////////////////////////////////////////////////////////////////
4 //
5 //  Copyright (C) 2001-2021  The Bochs Project
6 //
7 //  This library is free software; you can redistribute it and/or
8 //  modify it under the terms of the GNU Lesser General Public
9 //  License as published by the Free Software Foundation; either
10 //  version 2 of the License, or (at your option) any later version.
11 //
12 //  This library is distributed in the hope that it will be useful,
13 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
14 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 //  Lesser General Public License for more details.
16 //
17 //  You should have received a copy of the GNU Lesser General Public
18 //  License along with this library; if not, write to the Free Software
19 //  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
20 
21 /*
22  * Emulator of an Intel 8254/82C54 Programmable Interval Timer.
23  * Greg Alexander <yakovlev@usa.com>
24  */
25 
26 #ifndef _PIT_82C54_H_
27 #define _PIT_82C54_H_ 1
28 
29 typedef void (*out_handler_t)(bool value);
30 
31 class pit_82C54 : public logfunctions {
32 public:
33   //Please do not use these.  They are public because they have to be
34   // to compile on some platforms.  They are not to be used by other
35   // classes.
36 
37   enum rw_status {
38     LSByte=0,
39     MSByte=1,
40     LSByte_multiple=2,
41     MSByte_multiple=3
42   };
43 
44 private:
45 
46   enum {
47     MAX_COUNTER=2,
48     MAX_ADDRESS=3,
49     CONTROL_ADDRESS=3,
50     MAX_MODE=5
51   };
52 
53   enum real_RW_status {
54     LSB_real=1,
55     MSB_real=2,
56     BOTH_real=3
57   };
58 
59   enum problem_type {
60     UNL_2P_READ=1
61   };
62 
63   struct counter_type {
64     //Chip IOs;
65     bool GATE; //GATE Input value at end of cycle
66     bool OUTpin; //OUT output this cycle
67 
68     //Architected state;
69     Bit32u count; //Counter value this cycle
70     Bit16u outlatch; //Output latch this cycle
71     Bit16u inlatch; //Input latch this cycle
72     Bit8u status_latch;
73 
74     //Status Register data;
75     Bit8u rw_mode; //2-bit R/W mode from command word register.
76     Bit8u mode; //3-bit mode from command word register.
77     bool bcd_mode; //1-bit BCD vs. Binary setting.
78     bool null_count; //Null count bit of status register.
79 
80     //Latch status data;
81     bool count_LSB_latched;
82     bool count_MSB_latched;
83     bool status_latched;
84 
85     //Miscelaneous State;
86     Bit32u count_binary; //Value of the count in binary.
87     bool triggerGATE; //Whether we saw GATE rise this cycle.
88     rw_status write_state; //Read state this cycle
89     rw_status read_state; //Read state this cycle
90     bool count_written; //Whether a count written since programmed
91     bool first_pass; //Whether or not this is the first loaded count.
92     bool state_bit_1; //Miscelaneous state bits.
93     bool state_bit_2;
94     Bit32u next_change_time; //Next time something besides count changes.
95                              //0 means never.
96     out_handler_t out_handler; // OUT pin callback (for IRQ0)
97   };
98 
99   counter_type counter[3];
100 
101   Bit8u controlword;
102 
103   int seen_problems;
104 
105   void latch_counter(counter_type & thisctr);
106 
107   void set_OUT (counter_type & thisctr, bool data);
108 
109   void set_count (counter_type & thisctr, Bit32u data) BX_CPP_AttrRegparmN(2);
110 
111   void set_count_to_binary (counter_type & thisctr) BX_CPP_AttrRegparmN(1);
112 
113   void set_binary_to_count (counter_type & thisctr) BX_CPP_AttrRegparmN(1);
114 
115   void decrement (counter_type & thisctr) BX_CPP_AttrRegparmN(1);
116 
117   void decrement_multiple(counter_type & thisctr, Bit32u cycles) BX_CPP_AttrRegparmN(2);
118 
119   void clock(Bit8u cnum) BX_CPP_AttrRegparmN(1);
120 
121   void print_counter(counter_type & thisctr);
122 
123 public:
124   pit_82C54 (void);
125   void init (void);
126   void reset (unsigned type);
127   void register_state(bx_param_c *parent);
128 
129   void clock_all(Bit32u cycles);
130   void clock_multiple(Bit8u cnum, Bit32u cycles);
131 
132   Bit8u read(Bit8u address);
133   void write(Bit8u address, Bit8u data);
134 
135   void set_GATE(Bit8u cnum, bool data);
136   bool read_GATE(Bit8u cnum);
137 
138   bool read_OUT(Bit8u cnum);
139   void set_OUT_handler(Bit8u cnum, out_handler_t outh);
140 
141   Bit32u get_clock_event_time(Bit8u cnum);
142   Bit32u get_next_event_time(void);
143   Bit16u get_inlatch(int countnum);
144   bool new_count_ready(int countnum);
145   Bit8u  get_mode(int countnum);
146 
147   void print_cnum(Bit8u cnum);
148 };
149 
150 #endif
151