1 // license:BSD-3-Clause
2 // copyright-holders:Raphael Nabet
3 /*
4     smartmed.h: header file for smartmed.c
5 */
6 
7 #ifndef MAME_MACHINE_SMARTMEDIA_H
8 #define MAME_MACHINE_SMARTMEDIA_H
9 
10 #pragma once
11 
12 #include "formats/imageutl.h"
13 #include "softlist_dev.h"
14 
15 //#define SMARTMEDIA_IMAGE_SAVE
16 
17 
18 /***************************************************************************
19     TYPE DEFINITIONS
20 ***************************************************************************/
21 
22 // ======================> nand_device
23 class nand_device : public device_t
24 {
25 public:
26 	// "Sequential Row Read is available only on K9F5608U0D_Y,P,V,F or K9F5608D0D_Y,P"
27 	enum class chip
28 	{
29 		K9F5608U0D = 0,   // K9F5608U0D
30 		K9F5608U0D_J,     // K9F5608U0D-Jxxx
31 		K9F5608U0B,       // K9F5608U0B
32 		K9F1G08U0B,       // K9F1G08U0B
33 		K9LAG08U0M        // K9LAG08U0M
34 	};
35 
36 	// construction/destruction
37 	nand_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
38 
rnb_wr_callback()39 	auto rnb_wr_callback() { return m_write_rnb.bind(); }
40 
set_nand_type(chip type)41 	void set_nand_type(chip type)
42 	{
43 		switch (type)
44 		{
45 		case chip::K9F5608U0D:
46 			m_id_len = 2;
47 			m_id[0] = 0xec;
48 			m_id[1] = 0x75;
49 			m_page_data_size = 512;
50 			m_page_total_size = 512 + 16;
51 			m_log2_pages_per_block = compute_log2(32);
52 			m_num_pages = 32 * 2048;
53 			m_col_address_cycles = 1;
54 			m_row_address_cycles = 2;
55 			m_sequential_row_read = 1;
56 			break;
57 		case chip::K9F5608U0D_J:
58 		case chip::K9F5608U0B:
59 			m_id_len = 2;
60 			m_id[0] = 0xec;
61 			m_id[1] = 0x75;
62 			m_page_data_size = 512;
63 			m_page_total_size = 512 + 16;
64 			m_log2_pages_per_block = compute_log2(32);
65 			m_num_pages = 32 * 2048;
66 			m_col_address_cycles = 1;
67 			m_row_address_cycles = 2;
68 			m_sequential_row_read = 0;
69 			break;
70 		case chip::K9F1G08U0B:
71 			m_id_len = 5;
72 			m_id[0] = 0xec;
73 			m_id[1] = 0xf1;
74 			m_id[2] = 0x00;
75 			m_id[3] = 0x95;
76 			m_id[4] = 0x40;
77 			m_page_data_size = 2048;
78 			m_page_total_size = 2048 + 64;
79 			m_log2_pages_per_block = compute_log2(64);
80 			m_num_pages = 64 * 1024;
81 			m_col_address_cycles = 2;
82 			m_row_address_cycles = 2;
83 			m_sequential_row_read = 0;
84 			break;
85 		case chip::K9LAG08U0M:
86 			m_id_len = 5;
87 			m_id[0] = 0xec;
88 			m_id[1] = 0xd5;
89 			m_id[2] = 0x55;
90 			m_id[3] = 0x25;
91 			m_id[4] = 0x68;
92 			m_page_data_size = 2048;
93 			m_page_total_size = 2048 + 64;
94 			m_log2_pages_per_block = compute_log2(128);
95 			m_num_pages = 128 * 8192;
96 			m_col_address_cycles = 2;
97 			m_row_address_cycles = 3;
98 			m_sequential_row_read = 0;
99 			break;
100 		default:
101 			printf("Unknown NAND type!\n");
102 			m_id_len = 0;
103 			m_page_data_size = 0;
104 			m_page_total_size = 0;
105 			m_log2_pages_per_block = 0;
106 			m_num_pages = 0;
107 			m_col_address_cycles = 0;
108 			m_row_address_cycles = 0;
109 			m_sequential_row_read = 0;
110 			break;
111 		}
112 	}
113 
114 	int is_present();
115 	int is_protected();
116 	int is_busy();
117 
118 	uint8_t data_r();
119 	void command_w(uint8_t data);
120 	void address_w(uint8_t data);
121 	void data_w(uint8_t data);
122 
123 	void set_data_ptr(void *ptr);
124 
125 protected:
126 	enum sm_mode_t
127 	{
128 		SM_M_INIT,      // initial state
129 		SM_M_READ,      // read page data
130 		SM_M_PROGRAM,   // program page data
131 		SM_M_ERASE,     // erase block data
132 		SM_M_READSTATUS,// read status
133 		SM_M_READID,        // read ID
134 		SM_M_30,
135 		SM_M_RANDOM_DATA_INPUT,
136 		SM_M_RANDOM_DATA_OUTPUT
137 	};
138 
139 	enum pointer_sm_mode_t
140 	{
141 		SM_PM_A,        // accessing first 256-byte half of 512-byte data field
142 		SM_PM_B,        // accessing second 256-byte half of 512-byte data field
143 		SM_PM_C         // accessing spare field
144 	};
145 
146 	nand_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
147 
148 	// device-level overrides
149 	virtual void device_start() override;
150 	virtual void device_reset() override;
151 
152 	int m_page_data_size;   // 256 for a 2MB card, 512 otherwise
153 	int m_page_total_size;// 264 for a 2MB card, 528 otherwise
154 	int m_num_pages;        // 8192 for a 4MB card, 16184 for 8MB, 32768 for 16MB,
155 						// 65536 for 32MB, 131072 for 64MB, 262144 for 128MB...
156 						// 0 means no card loaded
157 	int m_log2_pages_per_block; // log2 of number of pages per erase block (usually 4 or 5)
158 
159 	uint8_t* m_data_ptr;  // FEEPROM data area
160 	std::unique_ptr<uint8_t[]> m_data_uid_ptr;
161 
162 	sm_mode_t m_mode;               // current operation mode
163 	pointer_sm_mode_t m_pointer_mode;       // pointer mode
164 
165 	unsigned int m_page_addr;       // page address pointer
166 	int m_byte_addr;        // byte address pointer
167 	int m_addr_load_ptr;    // address load pointer
168 
169 	int m_status;           // current status
170 	int m_accumulated_status;   // accumulated status
171 
172 	std::unique_ptr<uint8_t[]> m_pagereg;   // page register used by program command
173 	uint8_t m_id[5];      // chip ID
174 	uint8_t m_mp_opcode;  // multi-plane operation code
175 
176 	int m_mode_3065;
177 
178 	// Palm Z22 NAND has 512 + 16 byte pages but, for some reason, Palm OS writes 512 + 64 bytes when
179 	// programming a page, so we need to keep track of the number of bytes written so we can ignore the
180 	// last 48 (64 - 16) bytes or else the first 48 bytes get overwritten
181 	int m_program_byte_count;
182 
183 	int m_id_len;
184 	int m_col_address_cycles;
185 	int m_row_address_cycles;
186 	int m_sequential_row_read;
187 
188 	devcb_write_line m_write_rnb;
189 
190 #ifdef SMARTMEDIA_IMAGE_SAVE
191 	int m_image_format;
192 #endif
193 };
194 
195 
196 
197 class smartmedia_image_device : public nand_device, public device_image_interface
198 {
199 public:
200 	// construction/destruction
201 	smartmedia_image_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
202 
203 	// image-level overrides
image_type()204 	virtual iodevice_t image_type() const noexcept override { return IO_MEMCARD; }
205 
is_readable()206 	virtual bool is_readable()  const noexcept override { return true; }
is_writeable()207 	virtual bool is_writeable() const noexcept override { return true; }
is_creatable()208 	virtual bool is_creatable() const noexcept override { return false; }
must_be_loaded()209 	virtual bool must_be_loaded() const noexcept override { return false; }
is_reset_on_load()210 	virtual bool is_reset_on_load() const noexcept override { return false; }
image_interface()211 	virtual const char *image_interface() const noexcept override { return "sm_memc"; }
file_extensions()212 	virtual const char *file_extensions() const noexcept override { return "smc"; }
213 
214 	virtual image_init_result call_load() override;
215 	virtual void call_unload() override;
216 
217 protected:
get_software_list_loader()218 	virtual const software_list_loader &get_software_list_loader() const override { return image_software_list_loader::instance(); }
219 
220 	image_init_result smartmedia_format_1();
221 	image_init_result smartmedia_format_2();
222 	int detect_geometry(uint8_t id1, uint8_t id2);
223 };
224 
225 
226 // device type definition
227 DECLARE_DEVICE_TYPE(NAND,       nand_device)
228 DECLARE_DEVICE_TYPE(SMARTMEDIA, smartmedia_image_device)
229 
230 #endif // MAME_MACHINE_SMARTMEDIA_H
231