1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#ifndef MT24LC256_HXX
19#define MT24LC256_HXX
20
21class System;
22
23#include "Control.hxx"
24#include "bspf.hxx"
25
26/**
27 Emulates a Microchip Technology Inc. 24LC256, a 32KB Serial Electrically
28 Erasable PROM accessed using the I2C protocol. Thanks to J. Payson
29 (aka Supercat) for the bulk of this code.
30
31 @author Stephen Anthony & J. Payson
32*/
33class MT24LC256
34{
35 public:
36 /**
37 Create a new 24LC256 with its data stored in the given file
38
39 @param filename Data file containing the EEPROM data
40 @param system The system using the controller of this device
41 @param callback Called to pass messages back to the parent controller
42 */
43 MT24LC256(const string& filename, const System& system,
44 Controller::onMessageCallback callback);
45 ~MT24LC256();
46
47 public:
48 // Sizes of the EEPROM
49 static constexpr uInt32 FLASH_SIZE = 32_KB;
50 static constexpr uInt32 PAGE_SIZE = 64;
51 static constexpr uInt32 PAGE_NUM = FLASH_SIZE / PAGE_SIZE;
52
53 // Initial state value of flash EEPROM
54 static constexpr uInt8 INIT_VALUE = 0xff;
55
56 /** Read boolean data from the SDA line */
57 bool readSDA() const { return jpee_mdat && jpee_sdat; }
58
59 /** Write boolean data to the SDA and SCL lines */
60 void writeSDA(bool state);
61 void writeSCL(bool state);
62
63 /** Called when the system is being reset */
64 void systemReset();
65
66 /** Erase entire EEPROM to known state ($FF) */
67 void eraseAll();
68
69 /** Erase the pages used by the current ROM to known state ($FF) */
70 void eraseCurrent();
71
72 /** Returns true if the page is used by the current ROM */
73 bool isPageUsed(uInt32 page) const;
74
75 private:
76 // I2C access code provided by Supercat
77 void jpee_init();
78 void jpee_data_start();
79 void jpee_data_stop();
80 void jpee_clock_fall();
81 bool jpee_timercheck(int mode);
82 void jpee_logproc(const char* const st) { cerr << " " << st << endl; }
83
84 void update();
85
86 private:
87 // The system of the parent controller
88 const System& mySystem;
89
90 // Sends messages back to the parent class
91 // Currently used for indicating read/write access
92 Controller::onMessageCallback myCallback;
93
94 // The EEPROM data
95 std::array<uInt8, FLASH_SIZE> myData;
96
97 // Track which pages are used
98 std::array<bool, PAGE_NUM> myPageHit;
99
100 // Cached state of the SDA and SCL pins on the last write
101 bool mySDA, mySCL;
102
103 // Indicates that a timer has been set and hasn't expired yet
104 bool myTimerActive;
105
106 // Indicates when the timer was set
107 uInt64 myCyclesWhenTimerSet;
108
109 // Indicates when the SDA and SCL pins were set/written
110 uInt64 myCyclesWhenSDASet, myCyclesWhenSCLSet;
111
112 // The file containing the EEPROM data
113 string myDataFile;
114
115 // Indicates if a valid EEPROM data file exists/was successfully loaded
116 bool myDataFileExists;
117
118 // Indicates if the EEPROM has changed since class invocation
119 bool myDataChanged;
120
121 // Required for I2C functionality
122 Int32 jpee_mdat, jpee_sdat, jpee_mclk;
123 Int32 jpee_sizemask, jpee_pagemask, jpee_smallmode, jpee_logmode;
124 Int32 jpee_pptr, jpee_state, jpee_nb;
125 uInt32 jpee_address, jpee_ad_known;
126 std::array<uInt8, 70> jpee_packet;
127
128 private:
129 // Following constructors and assignment operators not supported
130 MT24LC256() = delete;
131 MT24LC256(const MT24LC256&) = delete;
132 MT24LC256(MT24LC256&&) = delete;
133 MT24LC256& operator=(const MT24LC256&) = delete;
134 MT24LC256& operator=(MT24LC256&&) = delete;
135};
136
137#endif
138