aboutsummaryrefslogtreecommitdiffstats
path: root/tools/ioemu/iodev/pit82c54.h
blob: bae2c2b8acfe2e68a49ae7e027cb28bcdcc49887 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
/////////////////////////////////////////////////////////////////////////
// $Id: pit82c54.h,v 1.12 2003/03/02 23:59:11 cbothamy 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"


class pit_82C54 : public logfunctions {

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
  };

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
  };

  enum problem_type {
    UNL_2P_READ=1
  };

  struct counter_type {
    //Chip IOs;
    bool GATE; //GATE Input value at end of cycle
    bool OUTpin; //OUT output this cycle

    //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.
    bool bcd_mode; //1-bit BCD vs. Binary setting.
    bool null_count; //Null count bit of status register.

    //Latch status data;
    bool count_LSB_latched;
    bool count_MSB_latched;
    bool status_latched;

    //Miscelaneous State;
    Bit32u count_binary; //Value of the count in binary.
    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;
    Bit32u next_change_time; //Next time something besides count changes.
                             //0 means never.
  };

  counter_type counter[3];

  Bit8u controlword;

  int seen_problems;

  void latch_counter(counter_type & thisctr);

  void set_OUT (counter_type & thisctr, bool data);

  void set_count (counter_type & thisctr, Bit32u data) BX_CPP_AttrRegparmN(2);

  void set_count_to_binary (counter_type & thisctr) BX_CPP_AttrRegparmN(1);

  void set_binary_to_count (counter_type & thisctr) BX_CPP_AttrRegparmN(1);

  void decrement (counter_type & thisctr) BX_CPP_AttrRegparmN(1);

  void decrement_multiple(counter_type & thisctr, Bit32u cycles) BX_CPP_AttrRegparmN(2);

  void clock(Bit8u cnum) BX_CPP_AttrRegparmN(1);

  void print_counter(counter_type & thisctr);

public:
  void init (void);
  void reset (unsigned type);
  pit_82C54 (void);

  void clock_all(Bit32u cycles);
  void clock_multiple(Bit8u cnum, Bit32u cycles);

  Bit8u read(Bit8u address);
  void write(Bit8u address, Bit8u data);

  void set_GATE(Bit8u cnum, bool data);
  bool read_GATE(Bit8u cnum);

  bool read_OUT(Bit8u cnum);

  Bit32u get_clock_event_time(Bit8u cnum);
  Bit32u get_next_event_time(void);

  void print_cnum(Bit8u cnum);

};

#endif