1 // license:BSD-3-Clause
2 // copyright-holders:smf
3 #include "emu.h"
4 #include "omti5100.h"
5 
6 #define OMTI_STATUS_SEEK_FAIL 0x02
7 #define OMTI_STATUS_NOT_READY 0x04
8 #define OMTI_CHECK_TRACK_FORMAT 0x05
9 #define OMTI_FORMAT_TRACK 0x06
10 #define OMTI_READ_DATA_BUFFER 0xec
11 #define OMTI_ASSIGN_DISK_PARAM 0xc2
12 
13 DEFINE_DEVICE_TYPE(OMTI5100, omti5100_device, "omti5100", "OMTI 5100")
14 
15 #if 0
16 ROM_START( omti5100 )
17 	ROM_REGION(0x1000, "mcu", 0) // Hitachi Z8
18 	ROM_LOAD("100240-n.7a", 0x0000, 0x1000, CRC(d227d6cb) SHA1(3d6140764d3d043428c941826370ebf1597c63bd))
19 ROM_END
20 
21 const tiny_rom_entry *omti5100_device::device_rom_region() const
22 {
23 	return ROM_NAME( omti5100 );
24 }
25 #endif
26 
omti5100_device(const machine_config & mconfig,const char * tag,device_t * owner,uint32_t clock)27 omti5100_device::omti5100_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
28 	: scsihd_device(mconfig, OMTI5100, tag, owner, clock)
29 	, m_image0(*this, "image0")
30 	, m_image1(*this, "image1")
31 {
32 }
33 
device_start()34 void omti5100_device::device_start()
35 {
36 	if(!m_image0->get_hard_disk_file())
37 		m_image = m_image1;
38 	m_image = m_image0;
39 	scsihle_device::device_start();
40 }
41 
ExecCommand()42 void omti5100_device::ExecCommand()
43 {
44 	int drive = (command[1] >> 5) & 1;
45 	hard_disk_file *image = (drive ? m_image1 : m_image0)->get_hard_disk_file();
46 	if(!image)
47 	{
48 		if(command[0] == T10SPC_CMD_REQUEST_SENSE)
49 			return scsihd_device::ExecCommand();
50 
51 		m_phase = SCSI_PHASE_STATUS;
52 		m_status_code = SCSI_STATUS_CODE_CHECK_CONDITION;
53 		m_sense_asc = OMTI_STATUS_NOT_READY;
54 		m_transfer_length = 0;
55 		return;
56 	}
57 	hard_disk_info *info = hard_disk_get_info(image);
58 	switch(command[0])
59 	{
60 		case OMTI_READ_DATA_BUFFER:
61 			m_phase = SCSI_PHASE_DATAIN;
62 			m_status_code = SCSI_STATUS_CODE_GOOD;
63 			m_transfer_length = 512;
64 			break;
65 		case OMTI_ASSIGN_DISK_PARAM:
66 			m_phase = SCSI_PHASE_DATAOUT;
67 			m_status_code = SCSI_STATUS_CODE_GOOD;
68 			m_transfer_length = 10;
69 			break;
70 		case OMTI_CHECK_TRACK_FORMAT:
71 			m_phase = SCSI_PHASE_STATUS;
72 			m_status_code = SCSI_STATUS_CODE_GOOD;
73 			m_transfer_length = 0;
74 			break;
75 
76 		case T10SBC_CMD_READ_6:
77 		{
78 			int track = ((command[1]&0x1f)<<16 | command[2]<<8 | command[3]) / (m_param[drive].sectors ? m_param[drive].sectors : 1);
79 			int heads = m_param[drive].heads ? m_param[drive].heads : 1;
80 			if(((track % heads) > info->heads) || (track >= (info->cylinders * heads)))
81 			{
82 				m_phase = SCSI_PHASE_STATUS;
83 				m_status_code = SCSI_STATUS_CODE_CHECK_CONDITION;
84 				m_sense_asc = OMTI_STATUS_SEEK_FAIL;
85 				m_transfer_length = 0;
86 			}
87 			else
88 			{
89 				SetDevice(image);
90 				scsihd_device::ExecCommand();
91 			}
92 			break;
93 		}
94 		case OMTI_FORMAT_TRACK:
95 		{
96 			int track = ((command[1]&0x1f)<<16 | command[2]<<8 | command[3]) / m_param[drive].sectors;
97 			if(((track % m_param[drive].heads) <= info->heads) && (track < (info->cylinders * m_param[drive].heads)))
98 			{
99 				std::vector<uint8_t> sector(info->sectorbytes);
100 				memset(&sector[0], 0xe5, info->sectorbytes);
101 				m_phase = SCSI_PHASE_STATUS;
102 				m_status_code = SCSI_STATUS_CODE_GOOD;
103 				m_transfer_length = 0;
104 				for(int i = 0; i < info->sectors; i++)
105 					hard_disk_write(image, track * info->sectors + i, &sector[0]);
106 			}
107 			else
108 			{
109 				m_phase = SCSI_PHASE_STATUS;
110 				m_status_code = SCSI_STATUS_CODE_CHECK_CONDITION;
111 				m_sense_asc = OMTI_STATUS_SEEK_FAIL;
112 				m_transfer_length = 0;
113 			}
114 			break;
115 		}
116 		default:
117 			SetDevice(image);
118 			scsihd_device::ExecCommand();
119 			break;
120 	}
121 }
122 
ReadData(uint8_t * data,int dataLength)123 void omti5100_device::ReadData( uint8_t *data, int dataLength )
124 {
125 	switch( command[ 0 ] )
126 	{
127 		case OMTI_READ_DATA_BUFFER:
128 			data[0] = '5';
129 			data[1] = '1';
130 			data[2] = '0';
131 			data[3] = '0';
132 			break;
133 
134 		default:
135 			scsihd_device::ReadData( data, dataLength );
136 			break;
137 	}
138 }
139 
WriteData(uint8_t * data,int dataLength)140 void omti5100_device::WriteData( uint8_t *data, int dataLength )
141 {
142 	switch( command[ 0 ] )
143 	{
144 		case OMTI_ASSIGN_DISK_PARAM:
145 		{
146 			int drive = ((command[1] >> 5) & 1);
147 			hard_disk_file *image = (drive ? m_image1 : m_image0)->get_hard_disk_file();
148 			m_param[drive].heads = data[3] + 1;
149 			m_param[drive].cylinders = ((data[4] << 8) | data[5]) + 1;
150 			if(!data[8] && image)
151 			{
152 				switch(hard_disk_get_info(image)->sectorbytes)
153 				{
154 					case 128:
155 						m_param[drive].sectors = 53;
156 						break;
157 					case 256:
158 						m_param[drive].sectors = 32;
159 						break;
160 					case 512:
161 						m_param[drive].sectors = 18; // XXX: check this!
162 						break;
163 					case 1024:
164 						m_param[drive].sectors = 9;
165 						break;
166 				}
167 			}
168 			else
169 				m_param[drive].sectors = data[8] + 1;
170 			break;
171 		}
172 
173 		default:
174 			scsihd_device::WriteData( data, dataLength );
175 			break;
176 	}
177 }
178 
device_add_mconfig(machine_config & config)179 void omti5100_device::device_add_mconfig(machine_config &config)
180 {
181 	HARDDISK(config, m_image0);
182 	HARDDISK(config, m_image1);
183 }
184