1 //
2 // The Motorola 68681 DUART
3 //
4 
5 #ifndef M68K_DEVICES_M68681_HPP_
6 #define M68K_DEVICES_M68681_HPP_
7 
8 #include <string>
9 #include <sys/types.h>
10 
11 #include "Framework/BasicDevice.hpp"
12 
13 class M68681 : public BasicDevice {
14 public:
15   M68681(const std::string &args, BasicCPU &cpu);
16   ~M68681();
17 
18   // Returns true iff the address maps into the device
19   bool CheckMapped(Address addr) const override;
20 
21   // Returns the lowest address used by the device
LowestAddress() const22   Address LowestAddress() const override { return base_address; }
23 
24   // Returns the highest address used by the device
HighestAddress() const25   Address HighestAddress() const override {
26     return base_address + offset_to_first_register +
27            15 * offset_between_registers;
28   }
29 
30   // Gets a byte from the device
31   Byte Peek(Address addr) override;
32 
33   // Puts a byte into the device
34   void Poke(Address addr, Byte c) override;
35 
36   // Resets the DUART.
37   void Reset() override;
38 
39   // The BasicDevice's InterruptAcknowledge does not handle vectored
40   // interrupts so we'll have to change it.
41   int InterruptAcknowledge(unsigned int level) override;
42 
43   // Handles the DUART's events.
44   void EventCallback(int type, void *pointer) override;
45 
46 private:
47   Byte MR1A; // Mode register 1 A
48   Byte MR2A; // Mode register 2 A
49 
50   Byte SRA;  // Status register A
51   Byte CSRA; // Clock-select register A
52 
53   // No readable register at this address..
54   Byte CRA;  // Command register A
55 
56   Byte RBA;  // Receiver buffer A
57   Byte TBA;  // Transmitter buffer A
58 
59   Byte IPCR; // Input port change register
60   Byte ACR;  // Auxiliary control register
61 
62   Byte ISR;  // Interrupt status register
63   Byte IMR;  // Interrupt mask register
64 
65   Byte CUR;  // Counter mode: counter MSB
66   Byte CTUR; // Counter/timer uppper register
67 
68   Byte CLR;  // Counter mode: counter LSB
69   Byte CTLR; // Counter/timer lower register
70 
71   Byte MR1B; // Mode register 1 B
72   Byte MR2B; // Mode register 2 B
73   Byte SRB;  // Status register B
74   Byte CSRB; // Clock-select register B
75   Byte CRB;  // Command register B
76   Byte RBB;  // Receiver buffer B
77   Byte TBB;  // Transmitter buffer B
78 
79   Byte IVR; // Interrupt-vector register
80 
81   Byte mr1a_pointer; // Determines MR1A/MR2A
82   Byte mr1b_pointer; // Determines MR1B/MR2B
83 
84   Byte receiver_a_state;    // State of receiver A
85   Byte transmitter_a_state; // State of transmitter A
86   Byte receiver_b_state;    // State of receiver B
87   Byte transmitter_b_state; // State of transmitter B
88 
89   static long baudrate_table[32]; // Table of times for baud rates
90 
91   int coma_read_id;  // Pipe to command for port a
92   int coma_write_id; // Pipe to command for port a
93   int comb_read_id;  // Pipe to command for port b
94   int comb_write_id; // Pipe to command for port b
95   pid_t coma_pid;    // Proccess ID for port a command
96   pid_t comb_pid;    // Proccess ID for port b command
97 
98   Address base_address;             // Base address of the DUART
99   size_t offset_to_first_register;  // Offset to the first registers
100   size_t offset_between_registers;  // Offset to between registers
101   unsigned long interrupt_level;    // The interrupt level sent to CPU
102 
103   bool StartPortCommand(const std::string &command, bool std_flag, int &read,
104                         int &write, pid_t &pid);
105 
106   void SetInterruptStatusRegister();
107 };
108 
109 #endif  // M68K_DEVICES_M68681_HPP_
110