Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


9455798971a8273a896541b319be2bf50971869a
[palacios.git] / palacios / src / devices / ramdisk.c
1 /*
2  * Zheng Cui
3  * cuizheng@cs.unm.edu
4  * July 2008
5  */
6
7 #include <devices/ramdisk.h>
8 #include <palacios/vmm.h>
9 #include <string.h>
10
11 #ifdef DEBUG_RAMDISK
12 #define Ramdisk_Print(_f, _a...) PrintTrace("\nramdisk.c(%d) " _f, __LINE__, ## _a)
13 #else 
14 #define Ramdisk_Print(_f, _a...)
15 #endif
16
17 #define RD_PANIC(_f, _a...)     \
18   do {                       \
19     PrintDebug("ramdisk.c(%d) " _f, __LINE__, ## _a);   \
20       while(1);              \
21     }                        \
22    while(0)                                                            
23     
24 #define RD_ERROR(_f, _a...) PrintTrace("\nramdisk.c(%d) " _f, __LINE__, ## _a)
25
26 /*
27  * Debug facilities
28  */
29
30 #define ATA_DETECT                     0xf0 //0X3E8
31 #define ATA_RESET                      0xf1 //0X3E9
32 #define ATA_CMD_DATA_IN                0xf2 //0X3EA
33 #define ATA_CMD_DATA_OUT               0xf3 //0X3EB
34 #define ATA_CMD_PACKET                 0xf4 //0X3EC
35 #define ATAPI_GET_SENSE                0xf5 //0X3ED
36 #define ATAPI_IS_READY                 0xf6 //0X3EE
37 #define ATAPI_IS_CDROM                 0xf7 //0X3EF
38
39 #define CDEMU_INIT                     0xf8 //0X2E8
40 #define CDEMU_ISACTIVE                 0xf9 //0X2E9
41 #define CDEMU_EMULATED_DRIVE           0xfa //0X2EA
42 #define CDROM_BOOT                     0xfb //0X2EB
43
44
45 #define HARD_DRIVE_POST                0xfc //0X2EC
46
47
48 #define ATA_DEVICE_NO                  0xfd //0X2ED
49 #define ATA_DEVICE_TYPE                0xfe //0X2ED
50
51 #define INT13_HARDDISK                 0xff //0x2ef
52 #define INT13_CDROM                    0xe0 //0x2f8
53 #define INT13_CDEMU                    0xe1 //0x2f9
54 #define INT13_ELTORITO                 0xe2 //0x2fa
55 #define INT13_DISKETTE_FUNCTION        0xe3 //0x2fb
56
57 // some packet handling macros
58 #define EXTRACT_FIELD(arr,byte,start,num_bits) (((arr)[(byte)] >> (start)) & ((1 << (num_bits)) - 1))
59 #define get_packet_field(c,b,s,n) (EXTRACT_FIELD((SELECTED_CONTROLLER((c)).buffer),(b),(s),(n)))
60 #define get_packet_byte(c,b) (SELECTED_CONTROLLER((c)).buffer[(b)])
61 #define get_packet_word(c,b) (((uint16)SELECTED_CONTROLLER((c)).buffer[(b)] << 8) | SELECTED_CONTROLLER((c)).buffer[(b)+1])
62
63
64 #define CONTROLLER(c,a) (channels[(c)].drives[(a)]).controller
65 #define DRIVE(c,a) (channels[(c)].drives[(a)])
66 #define SELECTED_CONTROLLER(c) (CONTROLLER((c), channels[(c)].drive_select))
67 #define SELECTED_DRIVE(c) (DRIVE((c), channels[(c)].drive_select))
68
69
70 #define DRIVE_IS_PRESENT(c,a) (channels[(c)].drives[(a)].device_type != IDE_NONE)
71 #define DRIVE_IS_HD(c,a) (channels[(c)].drives[(a)].device_type == IDE_DISK)
72 #define DRIVE_IS_CD(c,a) (channels[(c)].drives[(a)].device_type == IDE_CDROM)
73 #define SELECTED_MODEL(c) (channels[(c)].drives[channels[(c)].drive_select].model_no)
74
75 #define MASTER_SELECTED(c) (!channels[(c)].drive_select)
76 #define SLAVE_SELECTED(c)  (channels[(c)].drive_select)
77
78 #define SELECTED_IS_PRESENT(c) (DRIVE_IS_PRESENT((c),SLAVE_SELECTED((c))))
79 #define SELECTED_IS_HD(c) (DRIVE_IS_HD((c),SLAVE_SELECTED((c))))
80 #define SELECTED_IS_CD(c) (DRIVE_IS_CD((c),SLAVE_SELECTED((c))))
81
82 #define ANY_IS_PRESENT(c) (DRIVE_IS_PRESENT((c),0) || DRIVE_IS_PRESENT((c),1))
83 #define SELECTED_TYPE_STRING(channel) ((SELECTED_IS_CD(channel)) ? "CD-ROM" : "NONE")
84
85 #define WRITE_FEATURES(c,a) do { uint8 _a = a; CONTROLLER((c),0).features = _a; CONTROLLER((c),1).features = _a; } while(0)
86 #define WRITE_SECTOR_COUNT(c,a) do { uint8 _a = a; CONTROLLER((c),0).sector_count = _a; CONTROLLER((c),1).sector_count = _a; } while(0)
87 #define WRITE_SECTOR_NUMBER(c,a) do { uint8 _a = a; CONTROLLER((c),0).sector_no = _a; CONTROLLER((c),1).sector_no = _a; } while(0)
88 #define WRITE_CYLINDER_LOW(c,a) do { uint8 _a = a; CONTROLLER((c),0).cylinder_no = (CONTROLLER((c),0).cylinder_no & 0xff00) | _a; CONTROLLER((c),1).cylinder_no = (CONTROLLER((c),1).cylinder_no & 0xff00) | _a; } while(0)
89 #define WRITE_CYLINDER_HIGH(c,a) do { uint16 _a = a; CONTROLLER((c),0).cylinder_no = (_a << 8) | (CONTROLLER((c),0).cylinder_no & 0xff); CONTROLLER((c),1).cylinder_no = (_a << 8) | (CONTROLLER((c),1).cylinder_no & 0xff); } while(0)
90 #define WRITE_HEAD_NO(c,a) do { uint8 _a = a; CONTROLLER((c),0).head_no = _a; CONTROLLER((c),1).head_no = _a; } while(0)
91 #define WRITE_LBA_MODE(c,a) do { uint8 _a = a; CONTROLLER((c),0).lba_mode = _a; CONTROLLER((c),1).lba_mode = _a; } while(0)
92
93
94
95 #define GOTO_RETURN_VALUE  if(io_len==4){\
96                              goto return_value32;\
97                              }\
98                            else if(io_len==2){\
99                              value16=(Bit16u)value32;\
100                              goto return_value16;\
101                              }\
102                            else{\
103                              value8=(Bit8u)value32;\
104                              goto return_value8;\
105                              }
106
107 #define UNUSED(x) ((void)x)
108
109 #define PACKET_SIZE 12
110
111 static struct ramdisk_t *ramdisk_state;
112
113
114
115
116
117
118 ////////////////////////////////////////////////////////////////////////////
119
120 /*
121  * Static routines
122  */
123
124 static
125 uint_t ramdisk_read_port(ushort_t port,
126                          void *src,
127                          uint_t length,
128                          struct vm_device *dev);
129
130 static
131 uint_t ramdisk_write_port(ushort_t port,
132                           void *src,
133                           uint_t length,
134                           struct vm_device *dev);
135
136 static
137 uint_t ramdisk_read_port_ignore(ushort_t port,
138                                 void *src,
139                                 uint_t length,
140                                 struct vm_device *dev);
141
142 static
143 uint_t ramdisk_write_port_ignore(ushort_t port,
144                                  void *src,
145                                  uint_t length,
146                                  struct vm_device *dev);
147
148
149 static
150 Bit32u rd_read_handler(struct channel_t *channels, Bit32u address, unsigned io_len);
151
152 static
153 void rd_write_handler(struct channel_t *channels, Bit32u address, 
154                       Bit32u value, unsigned io_len);
155
156
157
158 /*
159  * ATAPI routines
160  */
161
162 static 
163 void rd_identify_ATAPI_drive(struct channel_t *channels, Bit8u channel);
164
165
166 static 
167 void rd_init_send_atapi_command(struct channel_t *channels, Bit8u channel, Bit8u command, int req_length, int alloc_length, bool lazy /*= false*/);
168
169 static 
170 void rd_ready_to_send_atapi(struct channel_t *channels, Bit8u channel);
171
172
173 static 
174 void rd_atapi_cmd_error(struct channel_t *channels, Bit8u channel, sense_t sense_key, asc_t asc);
175
176 static 
177 void rd_init_mode_sense_single(struct channel_t *channels, Bit8u channel, const void* src, int size);
178
179 static 
180 void rd_atapi_cmd_nop(struct channel_t *channels, Bit8u channel);
181
182 static
183 void rd_command_aborted(struct channel_t *channels, Bit8u channel, unsigned value);
184
185
186 /*
187  * Interrupt handling
188  */
189
190 static 
191 void rd_raise_interrupt(struct channel_t *channels, Bit8u channel);
192
193 static 
194 void rd_lower_irq(struct vm_device *dev, Bit32u irq);
195
196
197
198 /*
199  * Helper routines
200  */
201
202 uint16 rd_read_16bit(const uint8* buf) 
203 {
204   return (buf[0] << 8) | buf[1];
205 }
206
207
208
209 uint32 rd_read_32bit(const uint8* buf) 
210 {
211   return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
212 }
213
214 ////////////////////////////////////////////////////////////////////
215
216
217 void rd_print_state(struct ramdisk_t *ramdisk, 
218                          struct vm_device *dev)
219 //Bit32u   rd_init_harddrive(struct channel_t *channels)
220 {
221
222   uchar_t channel; 
223   uchar_t device;
224   struct channel_t *channels = (struct channel_t *)(&(ramdisk->channels));
225
226   for (channel = 0; channel < MAX_ATA_CHANNEL; channel++)
227     memset((char *)(channels + channel), 0, sizeof(struct channel_t));
228
229   Ramdisk_Print("sizeof(*channels) = %d\n", sizeof((*channels)));
230   Ramdisk_Print("sizeof(channles->drives[0].controller) = %d\n", sizeof((channels->drives[0].controller)));
231   Ramdisk_Print("sizeof(channles->drives[0].cdrom) = %d\n", sizeof((channels->drives[0].cdrom)));
232   Ramdisk_Print("sizeof(channles->drives[0].sense) = %d\n", sizeof((channels->drives[0].sense)));
233   Ramdisk_Print("sizeof(channles->drives[0].atapi) = %d\n", sizeof((channels->drives[0].atapi)));
234
235
236   Ramdisk_Print("sizeof(channles->drives[0].controller.status) = %d\n", sizeof((channels->drives[0].controller.status)));
237   Ramdisk_Print("sizeof(channles->drives[0].controller.sector_count) = %d\n", sizeof((channels->drives[0].controller.sector_count)));
238   Ramdisk_Print("sizeof(channles->drives[0].controller.interrupt_reason) = %d\n", sizeof((channels->drives[0].controller.interrupt_reason)));
239
240   Ramdisk_Print("sizeof(channles->drives[0].controller.cylinder_no) = %d\n", sizeof((channels->drives[0].controller.cylinder_no)));
241   Ramdisk_Print("sizeof(channles->drives[0].controller.byte_count) = %d\n", sizeof((channels->drives[0].controller.byte_count)));
242
243
244   Ramdisk_Print("sizeof(channles->drives[0].controller.control) = %d\n", sizeof((channels->drives[0].controller.control)));
245
246
247   for (channel = 0; channel < MAX_ATA_CHANNEL; channel++){
248   
249     for (device = 0; device < 2; device++){
250                   
251       // Initialize controller state, even if device is not present
252       Ramdisk_Print("channels[%d].drives[%d].controller.status.busy = %d\n",channel, device, channels[channel].drives[device].controller.status.busy);
253       Ramdisk_Print("channels[%d].drives[%d].controller.status.drive_ready = %d\n", channel, device, channels[channel].drives[device].controller.status.drive_ready);
254       Ramdisk_Print("channels[%d].drives[%d].controller.status.write_fault = %d\n", channel, device, channels[channel].drives[device].controller.status.write_fault);
255       Ramdisk_Print("channels[%d].drives[%d].controller.status.seek_complete = %d\n", channel, device, channels[channel].drives[device].controller.status.seek_complete);
256       Ramdisk_Print("channels[%d].drives[%d].controller.status.drq = %d\n", channel, device, channels[channel].drives[device].controller.status.drq);
257       Ramdisk_Print("channels[%d].drives[%d].controller.status.corrected_data = %d\n", channel, device, channels[channel].drives[device].controller.status.corrected_data);
258       Ramdisk_Print("channels[%d].drives[%d].controller.status.index_pulse = %d\n", channel, device, channels[channel].drives[device].controller.status.index_pulse);
259       Ramdisk_Print("channels[%d].drives[%d].controller.status.index_pulse_count = %d\n", channel, device, channels[channel].drives[device].controller.status.index_pulse_count);
260       Ramdisk_Print("channels[%d].drives[%d].controller.status.err = %d\n", channel, device, channels[channel].drives[device].controller.status.err);
261
262
263       Ramdisk_Print("channels[%d].drives[%d].controller.error_register = %d\n", channel, device, channels[channel].drives[device].controller.error_register);
264       Ramdisk_Print("channels[%d].drives[%d].controller.head_no = %d\n", channel, device, channels[channel].drives[device].controller.head_no);
265       Ramdisk_Print("channels[%d].drives[%d].controller.sector_count = %d\n", channel, device, channels[channel].drives[device].controller.sector_count);
266       Ramdisk_Print("channels[%d].drives[%d].controller.sector_no = %d\n", channel, device, channels[channel].drives[device].controller.sector_no);
267       Ramdisk_Print("channels[%d].drives[%d].controller.cylinder_no = %d\n", channel, device, channels[channel].drives[device].controller.cylinder_no);
268       Ramdisk_Print("channels[%d].drives[%d].controller.current_command = %02x\n", channel, device, channels[channel].drives[device].controller.current_command);
269       Ramdisk_Print("channels[%d].drives[%d].controller.buffer_index = %d\n", channel, device, channels[channel].drives[device].controller.buffer_index);
270
271
272       Ramdisk_Print("channels[%d].drives[%d].controller.control.reset = %d\n", channel, device, channels[channel].drives[device].controller.control.reset);
273       Ramdisk_Print("channels[%d].drives[%d].controller.control.disable_irq = %d\n", channel, device, channels[channel].drives[device].controller.control.disable_irq);
274
275
276       Ramdisk_Print("channels[%d].drives[%d].controller.reset_in_progress = %d\n", channel, device, channels[channel].drives[device].controller.reset_in_progress);
277       Ramdisk_Print("channels[%d].drives[%d].controller.sectors_per_block = %02x\n", channel, device, channels[channel].drives[device].controller.sectors_per_block); 
278       Ramdisk_Print("channels[%d].drives[%d].controller.lba_mode = %d\n", channel, device, channels[channel].drives[device].controller.lba_mode); 
279       Ramdisk_Print("channels[%d].drives[%d].controller.features = %d\n", channel, device, channels[channel].drives[device].controller.features); 
280
281
282       Ramdisk_Print("channels[%d].drives[%d].model_no = %s\n", channel, device, channels[channel].drives[device].model_no); 
283       Ramdisk_Print("channels[%d].drives[%d].device_type = %d\n", channel, device, channels[channel].drives[device].device_type); 
284       Ramdisk_Print("channels[%d].drives[%d].cdrom.locked = %d\n", channel, device, channels[channel].drives[device].cdrom.locked); 
285       Ramdisk_Print("channels[%d].drives[%d].sense.sense_key = %d\n", channel, device, channels[channel].drives[device].sense.sense_key); 
286       Ramdisk_Print("channels[%d].drives[%d].sense.asc = %d\n", channel, device, channels[channel].drives[device].sense.asc); 
287       Ramdisk_Print("channels[%d].drives[%d].sense.ascq = %d\n", channel, device, channels[channel].drives[device].sense.ascq); 
288
289
290
291       Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.c_d = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.c_d);
292
293       Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.i_o = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.i_o);
294
295       Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.rel = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.rel);
296
297       Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.tag = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.tag);
298
299       Ramdisk_Print("channels[%d].drives[%d].cdrom.ready = %d\n", channel, device, channels[channel].drives[device].cdrom.ready);
300       
301     }//for device
302   }//for channel
303   
304   return;
305 }
306
307
308 Bit32u rd_init_harddrive(struct ramdisk_t *ramdisk, 
309                          struct vm_device *dev)
310 {
311
312   
313   uchar_t channel; 
314   uchar_t device;
315   struct channel_t *channels = (struct channel_t *)(&(ramdisk->channels));
316
317   Ramdisk_Print("[rd_init_harddrive]\n");
318   for (channel = 0; channel < MAX_ATA_CHANNEL; channel++)
319     memset((char *)(channels + channel), 0, sizeof(struct channel_t));
320
321
322   for (channel = 0; channel < MAX_ATA_CHANNEL; channel++){
323   
324     channels[channel].ioaddr1 = 0x0;
325     channels[channel].ioaddr2 = 0x0;
326     channels[channel].irq = 0;
327
328     for (device = 0; device < 2; device++){
329       
330
331       CONTROLLER(channel,device).status.busy           = 0;
332       CONTROLLER(channel,device).status.drive_ready    = 1;
333       CONTROLLER(channel,device).status.write_fault    = 0;
334       CONTROLLER(channel,device).status.seek_complete  = 1;
335       CONTROLLER(channel,device).status.drq            = 0;
336       CONTROLLER(channel,device).status.corrected_data = 0;
337       CONTROLLER(channel,device).status.index_pulse    = 0;
338       CONTROLLER(channel,device).status.index_pulse_count = 0;
339       CONTROLLER(channel,device).status.err            = 0;
340
341       CONTROLLER(channel,device).error_register = 0x01; // diagnostic code: no error
342       CONTROLLER(channel,device).head_no        = 0;
343       CONTROLLER(channel,device).sector_count   = 1;
344       CONTROLLER(channel,device).sector_no      = 1;
345       CONTROLLER(channel,device).cylinder_no    = 0;
346       CONTROLLER(channel,device).current_command = 0x00;
347       CONTROLLER(channel,device).buffer_index = 0;
348
349       CONTROLLER(channel,device).control.reset       = 0;
350       CONTROLLER(channel,device).control.disable_irq = 0;
351       CONTROLLER(channel,device).reset_in_progress   = 0;
352
353       CONTROLLER(channel,device).sectors_per_block   = 0x80;
354       CONTROLLER(channel,device).lba_mode            = 0;
355       
356       CONTROLLER(channel,device).features            = 0;
357         
358           // If not present
359       channels[channel].drives[device].device_type           = IDE_NONE;
360
361       // Make model string
362       strncpy((char*)channels[channel].drives[device].model_no, 
363               "", 40);
364       while(strlen((char *)channels[channel].drives[device].model_no) < 40) {
365         strcat ((char*)channels[channel].drives[device].model_no, " ");
366       }
367
368 //      Ramdisk_Print("channels[%d].drives[%d].controller.current_command = %02x\n", channel, device, channels[channel].drives[device].controller.current_command);
369 //      Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.c_d = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.c_d);
370
371 //      Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.i_o = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.i_o);
372
373 //      Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.rel = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.rel);
374
375 //      Ramdisk_Print("channels[%d].drives[%d].controller.interrupt_reason.tag = %02x\n", channel, device, channels[channel].drives[device].controller.interrupt_reason.tag);
376       
377 //      Ramdisk_Print("channels[%d].drives[%d].controller.control.disable_irq = %d\n", channel, device, channels[channel].drives[device].controller.control.disable_irq);
378       
379       
380       
381       if (channel == 1) {
382
383         channels[channel].ioaddr1 = 0x170;
384         channels[channel].ioaddr2 = 0x370;
385         channels[channel].irq =  15;
386         channels[channel].drive_select = 0;
387        
388         if (device == 0) {
389           // Make model string
390           strncpy((char*)channels[channel].drives[device].model_no, 
391                   "Zheng's Ramdisk", 40);
392           while (strlen((char *)channels[channel].drives[device].model_no) < 40) {
393             strcat ((char*)channels[channel].drives[device].model_no, " ");
394           }
395
396           Ramdisk_Print("CDROM on target %d/%d\n", channel, device);
397           
398           channels[channel].drives[device].device_type = IDE_CDROM;
399           channels[channel].drives[device].cdrom.locked = 0;
400           channels[channel].drives[device].sense.sense_key = SENSE_NONE;
401           channels[channel].drives[device].sense.asc = 0;
402           channels[channel].drives[device].sense.ascq = 0;
403           
404
405           //Check bit fields
406           channels[channel].drives[device].controller.sector_count = 0;
407           channels[channel].drives[device].controller.interrupt_reason.c_d = 1;
408           if (channels[channel].drives[device].controller.sector_count != 0x01) {
409             Ramdisk_Print("interrupt reason bit field error\n");
410             return INTR_REASON_BIT_ERR;
411           }
412
413           channels[channel].drives[device].controller.sector_count = 0;
414           channels[channel].drives[device].controller.interrupt_reason.i_o = 1;
415           if (channels[channel].drives[device].controller.sector_count != 0x02) {
416             Ramdisk_Print("interrupt reason bit field error\n");
417             return INTR_REASON_BIT_ERR;
418           }
419           
420           channels[channel].drives[device].controller.sector_count = 0;
421           channels[channel].drives[device].controller.interrupt_reason.rel = 1;
422           if (channels[channel].drives[device].controller.sector_count != 0x04) {
423             Ramdisk_Print("interrupt reason bit field error\n");
424             return INTR_REASON_BIT_ERR;
425           }
426         
427           channels[channel].drives[device].controller.sector_count = 0;
428           channels[channel].drives[device].controller.interrupt_reason.tag = 3;
429           if (channels[channel].drives[device].controller.sector_count != 0x18) {
430             Ramdisk_Print("interrupt reason bit field error\n");
431             return INTR_REASON_BIT_ERR;
432           }
433           
434           
435           channels[channel].drives[device].controller.sector_count = 0;
436
437           // allocate low level driver
438           channels[channel].drives[device].cdrom.cd = (struct cdrom_interface*)V3_Malloc(sizeof(struct cdrom_interface));
439           Ramdisk_Print("cd = %x\n", channels[channel].drives[device].cdrom.cd);
440           V3_ASSERT(channels[channel].drives[device].cdrom.cd != NULL);
441           
442           struct cdrom_interface *cdif = channels[channel].drives[device].cdrom.cd;
443           memset(cdif, 0, sizeof(struct cdrom_interface));
444           init_cdrom(cdif);
445           cdif->ops.init(cdif);
446
447           Ramdisk_Print("\t\tCD on ata%d-%d: '%s'\n",channel, device, "");
448           
449           if((channels[channel].drives[device].cdrom.cd->ops).insert_cdrom(cdif, NULL)) {
450             Ramdisk_Print("\t\tMedia present in CD-ROM drive\n");
451             channels[channel].drives[device].cdrom.ready = 1;
452             channels[channel].drives[device].cdrom.capacity = channels[channel].drives[device].cdrom.cd->ops.capacity(cdif);
453           } else {                  
454             Ramdisk_Print("\t\tCould not locate CD-ROM, continuing with media not present\n");
455             channels[channel].drives[device].cdrom.ready = 0;
456           }
457           
458         }//if device = 0
459       }//if channel = 0
460     }//for device
461   }//for channel
462
463   ramdisk->private_data = dev;
464   ramdisk_state = ramdisk;
465   Ramdisk_Print("ramdisk_state = %x\n", ramdisk_state);
466   Ramdisk_Print("ramdisk = %x\n", ramdisk);
467   //  rd_print_state(ramdisk, dev);
468   return 0;
469 }
470
471
472 void   rd_reset_harddrive(struct ramdisk_t *ramdisk, unsigned type)
473 {
474   return;
475 }
476
477
478 void   rd_close_harddrive(struct ramdisk_t *ramdisk)
479 {
480   return;
481 }
482
483
484 ////////////////////////////////////////////////////////////////////
485
486
487 static
488 Bit32u rd_read_handler(struct channel_t *channels, Bit32u address, unsigned io_len)
489 {
490   Bit8u value8;
491   Bit16u value16;
492   Bit32u value32;
493
494   unsigned drive_select;
495   unsigned index;       
496   unsigned increment = 0;
497
498   Bit8u  channel = MAX_ATA_CHANNEL;
499   Bit32u port = 0xff; // undefined
500
501   Ramdisk_Print("[rd_read_handler]\n");
502
503   for (channel=0; channel<MAX_ATA_CHANNEL; channel++) {
504     if ((address & 0xfff8) == channels[channel].ioaddr1) {
505       port = address - channels[channel].ioaddr1;
506       break;
507       }
508     else if ((address & 0xfff8) == channels[channel].ioaddr2) {
509       port = address - channels[channel].ioaddr2 + 0x10;
510       break;
511       }
512     }
513
514   if (channel == MAX_ATA_CHANNEL) {
515     if ((address < 0x03f6) || (address > 0x03f7)) {
516       RD_PANIC("Error: read: unable to find ATA channel, ioport=0x%04x\n", address);
517       return 0;
518     } else {
519       channel = 0;
520       port = address - 0x03e0;
521     }
522   }
523
524   drive_select = channels[channel].drive_select;
525   if (port != 0x00){
526     Ramdisk_Print("[R_handler] IO read addr at %x, on drive %d/%d, curcmd = %02x\n", address, channel, drive_select, SELECTED_CONTROLLER(channel).current_command);
527   }else{
528     
529   }
530
531
532   struct cdrom_interface *cdif = channels[channel].drives[drive_select].cdrom.cd;
533   switch (port) {
534
535   case 0x00: // hard disk data (16bit) 0x1f0
536
537     switch (SELECTED_CONTROLLER(channel).current_command) {
538     case 0xec:    // IDENTIFY DEVICE
539     case 0xa1:
540
541       index = 0;
542       SELECTED_CONTROLLER(channel).status.busy = 0;
543       SELECTED_CONTROLLER(channel).status.drive_ready = 1;
544       SELECTED_CONTROLLER(channel).status.write_fault = 0;
545       SELECTED_CONTROLLER(channel).status.seek_complete = 1;
546       SELECTED_CONTROLLER(channel).status.corrected_data = 0;
547       SELECTED_CONTROLLER(channel).status.err = 0;
548         
549       index = SELECTED_CONTROLLER(channel).buffer_index;
550       value32 = SELECTED_CONTROLLER(channel).buffer[index];
551       index++;
552
553       if (io_len >= 2) {
554         value32 |= (SELECTED_CONTROLLER(channel).buffer[index] << 8);
555         index++;
556       }
557       if (io_len == 4) {
558         value32 |= (SELECTED_CONTROLLER(channel).buffer[index] << 16);
559         value32 |= (SELECTED_CONTROLLER(channel).buffer[index+1] << 24);
560         index += 2;
561       }
562       SELECTED_CONTROLLER(channel).buffer_index = index;
563       
564       if (SELECTED_CONTROLLER(channel).buffer_index >= 512) {
565         
566         SELECTED_CONTROLLER(channel).status.drq = 0;
567       }
568       GOTO_RETURN_VALUE;
569
570     case 0xa0: //send packet cmd 
571
572         index = SELECTED_CONTROLLER(channel).buffer_index;
573         increment = 0;
574         Ramdisk_Print("\t\tatapi.command(%02x), index(%d), cdrom.remaining_blocks(%d)\n", SELECTED_DRIVE(channel).atapi.command, index, SELECTED_DRIVE(channel).cdrom.remaining_blocks);
575         // Load block if necessary
576         if (index >= 2048) {
577           if (index > 2048)
578             RD_PANIC("\t\tindex > 2048 : 0x%x\n",index);
579           switch (SELECTED_DRIVE(channel).atapi.command) {
580           case 0x28: // read (10)
581           case 0xa8: // read (12)
582
583             if (!SELECTED_DRIVE(channel).cdrom.ready) {
584               RD_PANIC("\t\tRead with CDROM not ready\n");
585             } 
586             SELECTED_DRIVE(channel).cdrom.cd->ops.read_block(cdif, SELECTED_CONTROLLER(channel).buffer,
587                                                             SELECTED_DRIVE(channel).cdrom.next_lba);
588             SELECTED_DRIVE(channel).cdrom.next_lba++;
589             SELECTED_DRIVE(channel).cdrom.remaining_blocks--;
590             
591             
592             if (!SELECTED_DRIVE(channel).cdrom.remaining_blocks)
593               Ramdisk_Print("\t\tLast READ block loaded {CDROM}\n");
594             else
595               Ramdisk_Print("\t\tREAD block loaded (%d remaining) {CDROM}\n",
596                             SELECTED_DRIVE(channel).cdrom.remaining_blocks);
597             
598             // one block transfered, start at beginning
599             index = 0;
600             break;
601             
602           default: // no need to load a new block
603             break;
604           }
605         }
606
607         value32 = SELECTED_CONTROLLER(channel).buffer[index+increment];
608         increment++;
609         if (io_len >= 2) {
610           value32 |= (SELECTED_CONTROLLER(channel).buffer[index+increment] << 8);
611           increment++;
612         }
613         if (io_len == 4) {
614           value32 |= (SELECTED_CONTROLLER(channel).buffer[index+increment] << 16);
615           value32 |= (SELECTED_CONTROLLER(channel).buffer[index+increment+1] << 24);
616           increment += 2;
617         }
618         SELECTED_CONTROLLER(channel).buffer_index = index + increment;
619         SELECTED_CONTROLLER(channel).drq_index += increment;
620         
621         if (SELECTED_CONTROLLER(channel).drq_index >= (unsigned)SELECTED_DRIVE(channel).atapi.drq_bytes) {
622           SELECTED_CONTROLLER(channel).status.drq = 0;
623           SELECTED_CONTROLLER(channel).drq_index = 0;
624           
625           SELECTED_DRIVE(channel).atapi.total_bytes_remaining -= SELECTED_DRIVE(channel).atapi.drq_bytes;
626           
627           if (SELECTED_DRIVE(channel).atapi.total_bytes_remaining > 0) {
628             // one or more blocks remaining (works only for single block commands)
629
630             Ramdisk_Print("\t\tPACKET drq bytes read\n");
631             SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
632             SELECTED_CONTROLLER(channel).status.busy = 0;
633             SELECTED_CONTROLLER(channel).status.drq = 1;
634             SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 0;
635             
636             // set new byte count if last block
637             if (SELECTED_DRIVE(channel).atapi.total_bytes_remaining < SELECTED_CONTROLLER(channel).byte_count) {
638               SELECTED_CONTROLLER(channel).byte_count = SELECTED_DRIVE(channel).atapi.total_bytes_remaining;
639             }
640             SELECTED_DRIVE(channel).atapi.drq_bytes = SELECTED_CONTROLLER(channel).byte_count;
641             
642             rd_raise_interrupt(channels, channel);
643           } else {
644             // all bytes read
645             Ramdisk_Print("\t\tPACKET all bytes read\n");
646             SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
647             SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
648             SELECTED_CONTROLLER(channel).status.drive_ready = 1;
649             SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
650             SELECTED_CONTROLLER(channel).status.busy = 0;
651             SELECTED_CONTROLLER(channel).status.drq = 0;
652             SELECTED_CONTROLLER(channel).status.err = 0;
653             
654             rd_raise_interrupt(channels, channel);
655           }
656         }
657         GOTO_RETURN_VALUE;
658         break;
659       
660     default:
661       Ramdisk_Print("\t\tread need support more command: %02x\n", SELECTED_CONTROLLER(channel).current_command);
662       break;
663     }
664     ///////////////////////////////////////////
665
666   case 0x01: // hard disk error register 0x1f1
667
668     SELECTED_CONTROLLER(channel).status.err = 0;
669     value8 = (!SELECTED_IS_PRESENT(channel)) ? 0 : SELECTED_CONTROLLER(channel).error_register;
670     goto return_value8;
671     break;
672   case 0x02: // hard disk sector count / interrupt reason 0x1f2
673     value8 = (!SELECTED_IS_PRESENT(channel)) ? 0 : SELECTED_CONTROLLER(channel).sector_count;
674     goto return_value8;
675     break;
676   case 0x03: // sector number 0x1f3
677     value8 = (!SELECTED_IS_PRESENT(channel)) ? 0 : SELECTED_CONTROLLER(channel).sector_no;
678     goto return_value8;
679   case 0x04: // cylinder low 0x1f4  
680     // -- WARNING : On real hardware the controller registers are shared between drives. 
681     // So we must respond even if the select device is not present. Some OS uses this fact 
682     // to detect the disks.... minix2 for example
683     value8 = (!ANY_IS_PRESENT(channel)) ? 0 : (SELECTED_CONTROLLER(channel).cylinder_no & 0x00ff);
684     goto return_value8;
685   case 0x05: // cylinder high 0x1f5
686     // -- WARNING : On real hardware the controller registers are shared between drives. 
687     // So we must respond even if the select device is not present. Some OS uses this fact 
688     // to detect the disks.... minix2 for example
689     value8 = (!ANY_IS_PRESENT(channel)) ? 0 : SELECTED_CONTROLLER(channel).cylinder_no >> 8;
690     goto return_value8;
691     
692   case 0x06: // hard disk drive and head register 0x1f6
693     // b7 Extended data field for ECC
694     // b6/b5: Used to be sector size.  00=256,01=512,10=1024,11=128
695     //   Since 512 was always used, bit 6 was taken to mean LBA mode:
696     //     b6 1=LBA mode, 0=CHS mode
697     //     b5 1
698     // b4: DRV
699     // b3..0 HD3..HD0
700     value8 = (1 << 7) |
701       ((SELECTED_CONTROLLER(channel).lba_mode>0) << 6) |
702       (1 << 5) | // 01b = 512 sector size
703       (channels[channel].drive_select << 4) |
704       (SELECTED_CONTROLLER(channel).head_no << 0);
705     goto return_value8;
706     break;
707     //CONTROLLER(channel,0).lba_mode
708     
709   case 0x07: // Hard Disk Status 0x1f7
710   case 0x16: // Hard Disk Alternate Status 0x3f6
711     if (!ANY_IS_PRESENT(channel)) {
712       // (mch) Just return zero for these registers
713       value8 = 0;
714     } else {
715       value8 = (
716                 (SELECTED_CONTROLLER(channel).status.busy << 7) |
717                 (SELECTED_CONTROLLER(channel).status.drive_ready << 6) |
718                 (SELECTED_CONTROLLER(channel).status.write_fault << 5) |
719                 (SELECTED_CONTROLLER(channel).status.seek_complete << 4) |
720                 (SELECTED_CONTROLLER(channel).status.drq << 3) |
721                 (SELECTED_CONTROLLER(channel).status.corrected_data << 2) |
722                 (SELECTED_CONTROLLER(channel).status.index_pulse << 1) |
723                 (SELECTED_CONTROLLER(channel).status.err) );
724       SELECTED_CONTROLLER(channel).status.index_pulse_count++;
725       SELECTED_CONTROLLER(channel).status.index_pulse = 0;
726       if (SELECTED_CONTROLLER(channel).status.index_pulse_count >= INDEX_PULSE_CYCLE) {
727         SELECTED_CONTROLLER(channel).status.index_pulse = 1;
728         SELECTED_CONTROLLER(channel).status.index_pulse_count = 0;
729       }
730     }
731     if (port == 0x07) {
732       rd_lower_irq((struct vm_device *)(ramdisk_state->private_data), channels[channel].irq);
733     }
734     goto return_value8;
735     break;
736     
737   case 0x17: // Hard Disk Address Register 0x3f7
738     // Obsolete and unsupported register.  Not driven by hard
739     // disk controller.  Report all 1's.  If floppy controller
740     // is handling this address, it will call this function
741     // set/clear D7 (the only bit it handles), then return
742     // the combined value
743     value8 = 0xff;
744     goto return_value8;
745     break;
746     
747   default:
748     RD_PANIC("hard drive: io read to address %x unsupported\n",
749               (unsigned) address);
750     
751     
752     ////////////////////////////////////////////
753   }
754   
755   Ramdisk_Print("\t\tError: hard drive: shouldnt get here!\n");
756   return 0;
757   
758 return_value32:
759   Ramdisk_Print("\t\t32-bit read from %04x = %08x {%s}\n",
760             (unsigned) address, value32, SELECTED_TYPE_STRING(channel));
761   return value32;
762   
763  return_value16:
764   Ramdisk_Print("\t\t16-bit read from %04x = %04x {%s}\n",
765             (unsigned) address, value16, SELECTED_TYPE_STRING(channel));
766   return value16;
767   
768  return_value8:
769   Ramdisk_Print("\t\t8-bit read from %x = %02x {%s}\n",
770             (unsigned) address, value8, SELECTED_TYPE_STRING(channel));
771   return value8;
772 }
773
774
775 static
776 void rd_write_handler(struct channel_t *channels, Bit32u address, 
777                       Bit32u value, unsigned io_len)
778 {
779
780   //  off_t logical_sector;
781   //  off_t ret;
782   rd_bool prev_control_reset;
783
784   Bit32u id;
785   int toc_length;
786
787   Bit8u  channel = MAX_ATA_CHANNEL;
788   Bit32u port = 0xff; // undefined
789
790   Ramdisk_Print("[rd_write_handler]\n");
791   //  Bit8u atapi_command;
792   //int alloc_length;
793
794   for (channel=0; channel<MAX_ATA_CHANNEL; channel++) {
795     if ((address & 0xfff8) == channels[channel].ioaddr1) {
796       port = address - channels[channel].ioaddr1;
797       break;
798     }
799     else if ((address & 0xfff8) == channels[channel].ioaddr2) {
800       port = address - channels[channel].ioaddr2 + 0x10;
801       break;
802       }
803     }
804
805   if (channel == MAX_ATA_CHANNEL) {
806     if (address != 0x03f6) {
807       RD_PANIC("Panic: write: unable to find ATA channel, ioport=0x%04x\n", address);
808     } else {
809       channel = 0;
810       port = address - 0x03e0;
811     }
812   }
813
814   Ramdisk_Print("[W_handler] IO write to %x = %02x, channel = %d\n", (unsigned) address, (unsigned) value, channel);
815
816   struct cdrom_interface *cdif = SELECTED_DRIVE(channel).cdrom.cd;
817
818   switch (port) {
819
820   case 0x00: // 0x1f0
821     Ramdisk_Print("\t\twrite port 170\n");
822
823     //////////////////////////////////////////////////////////
824     switch (SELECTED_CONTROLLER(channel).current_command) {
825     case 0x30: // WRITE SECTORS
826       RD_PANIC("\t\tneed to implement 0x30(write sector) to port 0x170\n");
827       break;
828       
829     case 0xa0: // PACKET
830       if (SELECTED_CONTROLLER(channel).buffer_index >= PACKET_SIZE)
831         RD_PANIC("IO write(0x%04x): buffer_index >= PACKET_SIZE", address);
832       SELECTED_CONTROLLER(channel).buffer[SELECTED_CONTROLLER(channel).buffer_index] = value;
833       SELECTED_CONTROLLER(channel).buffer[SELECTED_CONTROLLER(channel).buffer_index+1] = (value >> 8);
834       SELECTED_CONTROLLER(channel).buffer_index += 2;
835       
836       /* if packet completely writtten */
837       if (SELECTED_CONTROLLER(channel).buffer_index >= PACKET_SIZE) {
838         // complete command received
839         Bit8u atapi_command = SELECTED_CONTROLLER(channel).buffer[0];
840         
841         Ramdisk_Print("\t\tcdrom: ATAPI command 0x%x started\n", atapi_command);
842
843         switch (atapi_command) {
844         case 0x00: // test unit ready
845           if (SELECTED_DRIVE(channel).cdrom.ready) {
846             rd_atapi_cmd_nop(channels, channel);
847           } else {
848             rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
849           }
850           rd_raise_interrupt(channels, channel);
851           break;
852           
853         case 0x03: { // request sense
854           int alloc_length = SELECTED_CONTROLLER(channel).buffer[4];
855           rd_init_send_atapi_command(channels, channel, atapi_command, 18, alloc_length, false);
856                                     
857           // sense data
858           SELECTED_CONTROLLER(channel).buffer[0] = 0x70 | (1 << 7);
859           SELECTED_CONTROLLER(channel).buffer[1] = 0;
860           SELECTED_CONTROLLER(channel).buffer[2] = SELECTED_DRIVE(channel).sense.sense_key;
861           SELECTED_CONTROLLER(channel).buffer[3] = SELECTED_DRIVE(channel).sense.information.arr[0];
862           SELECTED_CONTROLLER(channel).buffer[4] = SELECTED_DRIVE(channel).sense.information.arr[1];
863           SELECTED_CONTROLLER(channel).buffer[5] = SELECTED_DRIVE(channel).sense.information.arr[2];
864           SELECTED_CONTROLLER(channel).buffer[6] = SELECTED_DRIVE(channel).sense.information.arr[3];
865           SELECTED_CONTROLLER(channel).buffer[7] = 17-7;
866           SELECTED_CONTROLLER(channel).buffer[8] = SELECTED_DRIVE(channel).sense.specific_inf.arr[0];
867           SELECTED_CONTROLLER(channel).buffer[9] = SELECTED_DRIVE(channel).sense.specific_inf.arr[1];
868           SELECTED_CONTROLLER(channel).buffer[10] = SELECTED_DRIVE(channel).sense.specific_inf.arr[2];
869           SELECTED_CONTROLLER(channel).buffer[11] = SELECTED_DRIVE(channel).sense.specific_inf.arr[3];
870           SELECTED_CONTROLLER(channel).buffer[12] = SELECTED_DRIVE(channel).sense.asc;
871           SELECTED_CONTROLLER(channel).buffer[13] = SELECTED_DRIVE(channel).sense.ascq;
872           SELECTED_CONTROLLER(channel).buffer[14] = SELECTED_DRIVE(channel).sense.fruc;
873           SELECTED_CONTROLLER(channel).buffer[15] = SELECTED_DRIVE(channel).sense.key_spec.arr[0];
874           SELECTED_CONTROLLER(channel).buffer[16] = SELECTED_DRIVE(channel).sense.key_spec.arr[1];
875           SELECTED_CONTROLLER(channel).buffer[17] = SELECTED_DRIVE(channel).sense.key_spec.arr[2];
876           
877           rd_ready_to_send_atapi(channels, channel);
878         }
879           break;
880           
881         case 0x1b: { // start stop unit
882           //bx_bool Immed = (SELECTED_CONTROLLER(channel).buffer[1] >> 0) & 1;
883           rd_bool LoEj = (SELECTED_CONTROLLER(channel).buffer[4] >> 1) & 1;
884           rd_bool Start = (SELECTED_CONTROLLER(channel).buffer[4] >> 0) & 1;
885           
886           if (!LoEj && !Start) { // stop the disc
887             RD_ERROR("FIXME: Stop disc not implemented\n");
888             rd_atapi_cmd_nop(channels, channel);
889             rd_raise_interrupt(channels, channel);
890           } else if (!LoEj && Start) { // start (spin up) the disc
891
892             SELECTED_DRIVE(channel).cdrom.cd->ops.start_cdrom(cdif);
893
894             RD_ERROR("FIXME: ATAPI start disc not reading TOC\n");
895             rd_atapi_cmd_nop(channels, channel);
896             rd_raise_interrupt(channels, channel);
897           } else if (LoEj && !Start) { // Eject the disc
898             rd_atapi_cmd_nop(channels, channel);
899             
900             if (SELECTED_DRIVE(channel).cdrom.ready) {
901
902               SELECTED_DRIVE(channel).cdrom.cd->ops.eject_cdrom(cdif);
903
904               SELECTED_DRIVE(channel).cdrom.ready = 0;
905               //bx_options.atadevice[channel][SLAVE_SELECTED(channel)].Ostatus->set(EJECTED);
906               //bx_gui->update_drive_status_buttons();
907             }
908             rd_raise_interrupt(channels, channel);
909           } else { // Load the disc
910             // My guess is that this command only closes the tray, that's a no-op for us
911             rd_atapi_cmd_nop(channels, channel);
912             rd_raise_interrupt(channels, channel);
913           }
914         }
915           break;
916           
917         case 0xbd: { // mechanism status
918           uint16 alloc_length = rd_read_16bit(SELECTED_CONTROLLER(channel).buffer + 8);
919           
920           if (alloc_length == 0)
921             RD_PANIC("Zero allocation length to MECHANISM STATUS not impl.\n");
922           
923           rd_init_send_atapi_command(channels, channel, atapi_command, 8, alloc_length, false);
924           
925           SELECTED_CONTROLLER(channel).buffer[0] = 0; // reserved for non changers
926           SELECTED_CONTROLLER(channel).buffer[1] = 0; // reserved for non changers
927           
928           SELECTED_CONTROLLER(channel).buffer[2] = 0; // Current LBA (TODO!)
929           SELECTED_CONTROLLER(channel).buffer[3] = 0; // Current LBA (TODO!)
930           SELECTED_CONTROLLER(channel).buffer[4] = 0; // Current LBA (TODO!)
931           
932           SELECTED_CONTROLLER(channel).buffer[5] = 1; // one slot
933           
934           SELECTED_CONTROLLER(channel).buffer[6] = 0; // slot table length
935           SELECTED_CONTROLLER(channel).buffer[7] = 0; // slot table length
936           
937           rd_ready_to_send_atapi(channels, channel);
938         }
939           break;
940           
941         case 0x5a: { // mode sense
942           uint16 alloc_length = rd_read_16bit(SELECTED_CONTROLLER(channel).buffer + 7);
943           
944           Bit8u PC = SELECTED_CONTROLLER(channel).buffer[2] >> 6;
945           Bit8u PageCode = SELECTED_CONTROLLER(channel).buffer[2] & 0x3f;
946           
947           switch (PC) {
948           case 0x0: // current values
949             switch (PageCode) {
950             case 0x01: // error recovery
951               rd_init_send_atapi_command(channels, channel, atapi_command, sizeof(struct error_recovery_t) + 8, alloc_length, false);
952               
953               rd_init_mode_sense_single(channels, channel, &SELECTED_DRIVE(channel).cdrom.current.error_recovery,
954                                      sizeof(struct error_recovery_t));
955               rd_ready_to_send_atapi(channels, channel);
956               break;
957               
958             case 0x2a: // CD-ROM capabilities & mech. status
959               rd_init_send_atapi_command(channels, channel, atapi_command, 28, alloc_length, false);
960               rd_init_mode_sense_single(channels, channel, &SELECTED_CONTROLLER(channel).buffer[8], 28);
961               SELECTED_CONTROLLER(channel).buffer[8] = 0x2a;
962               SELECTED_CONTROLLER(channel).buffer[9] = 0x12;
963               SELECTED_CONTROLLER(channel).buffer[10] = 0x00;
964               SELECTED_CONTROLLER(channel).buffer[11] = 0x00;
965               // Multisession, Mode 2 Form 2, Mode 2 Form 1
966               SELECTED_CONTROLLER(channel).buffer[12] = 0x70; 
967               SELECTED_CONTROLLER(channel).buffer[13] = (3 << 5);
968               SELECTED_CONTROLLER(channel).buffer[14] = (unsigned char)
969                 (1 |
970                  (SELECTED_DRIVE(channel).cdrom.locked ? (1 << 1) : 0) |
971                  (1 << 3) |
972                  (1 << 5));
973               SELECTED_CONTROLLER(channel).buffer[15] = 0x00;
974               SELECTED_CONTROLLER(channel).buffer[16] = (706 >> 8) & 0xff;
975               SELECTED_CONTROLLER(channel).buffer[17] = 706 & 0xff;
976               SELECTED_CONTROLLER(channel).buffer[18] = 0;
977               SELECTED_CONTROLLER(channel).buffer[19] = 2;
978               SELECTED_CONTROLLER(channel).buffer[20] = (512 >> 8) & 0xff;
979               SELECTED_CONTROLLER(channel).buffer[21] = 512 & 0xff;
980               SELECTED_CONTROLLER(channel).buffer[22] = (706 >> 8) & 0xff;
981               SELECTED_CONTROLLER(channel).buffer[23] = 706 & 0xff;
982               SELECTED_CONTROLLER(channel).buffer[24] = 0;
983               SELECTED_CONTROLLER(channel).buffer[25] = 0;
984               SELECTED_CONTROLLER(channel).buffer[26] = 0;
985               SELECTED_CONTROLLER(channel).buffer[27] = 0;
986               rd_ready_to_send_atapi(channels, channel);
987               break;
988               
989             case 0x0d: // CD-ROM
990             case 0x0e: // CD-ROM audio control
991             case 0x3f: // all
992               RD_ERROR("cdrom: MODE SENSE (curr), code=%x not implemented yet\n",
993                         PageCode);
994             rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
995                             ASC_INV_FIELD_IN_CMD_PACKET);
996             rd_raise_interrupt(channels, channel);
997             break;
998               
999           default:
1000             // not implemeted by this device
1001             Ramdisk_Print("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
1002                      PC, PageCode);
1003             rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
1004                             ASC_INV_FIELD_IN_CMD_PACKET);
1005             rd_raise_interrupt(channels, channel);
1006             break;
1007           }
1008           break;
1009             
1010           case 0x1: // changeable values
1011             switch (PageCode) {
1012             case 0x01: // error recovery
1013             case 0x0d: // CD-ROM
1014             case 0x0e: // CD-ROM audio control
1015             case 0x2a: // CD-ROM capabilities & mech. status
1016             case 0x3f: // all
1017               RD_ERROR("cdrom: MODE SENSE (chg), code=%x not implemented yet\n",
1018                        PageCode);
1019             rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
1020                               ASC_INV_FIELD_IN_CMD_PACKET);
1021             rd_raise_interrupt(channels, channel);
1022             break;
1023             
1024           default:
1025               // not implemeted by this device
1026             Ramdisk_Print("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
1027                           PC, PageCode);
1028           rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
1029                              ASC_INV_FIELD_IN_CMD_PACKET);
1030           rd_raise_interrupt(channels, channel);
1031           break;
1032         }
1033           break;
1034           
1035         case 0x2: // default values
1036           switch (PageCode) {
1037           case 0x01: // error recovery
1038           case 0x0d: // CD-ROM
1039           case 0x0e: // CD-ROM audio control
1040           case 0x2a: // CD-ROM capabilities & mech. status
1041           case 0x3f: // all
1042             RD_PANIC("cdrom: MODE SENSE (dflt), code=%x\n",
1043                      PageCode);
1044             break;
1045             
1046             default:
1047               // not implemeted by this device
1048               Ramdisk_Print("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
1049                       PC, PageCode);
1050               rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
1051                                  ASC_INV_FIELD_IN_CMD_PACKET);
1052               rd_raise_interrupt(channels, channel);
1053               break;
1054           }
1055           break;
1056           
1057         case 0x3: // saved values not implemented
1058           rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
1059           rd_raise_interrupt(channels, channel);
1060           break;
1061           
1062         default:
1063           RD_PANIC("Should not get here!\n");
1064           break;
1065         }
1066       }
1067       break;
1068       
1069     case 0x12: { // inquiry
1070       uint8 alloc_length = SELECTED_CONTROLLER(channel).buffer[4];
1071       
1072       rd_init_send_atapi_command(channels, channel, atapi_command, 36, alloc_length, false);
1073       
1074       SELECTED_CONTROLLER(channel).buffer[0] = 0x05; // CD-ROM
1075       SELECTED_CONTROLLER(channel).buffer[1] = 0x80; // Removable
1076       SELECTED_CONTROLLER(channel).buffer[2] = 0x00; // ISO, ECMA, ANSI version
1077       SELECTED_CONTROLLER(channel).buffer[3] = 0x21; // ATAPI-2, as specified
1078       SELECTED_CONTROLLER(channel).buffer[4] = 31; // additional length (total 36)
1079       SELECTED_CONTROLLER(channel).buffer[5] = 0x00; // reserved
1080       SELECTED_CONTROLLER(channel).buffer[6] = 0x00; // reserved
1081       SELECTED_CONTROLLER(channel).buffer[7] = 0x00; // reserved
1082       
1083       // Vendor ID
1084       const char* vendor_id = "VTAB    ";
1085       int i;
1086       for (i = 0; i < 8; i++)
1087         SELECTED_CONTROLLER(channel).buffer[8+i] = vendor_id[i];
1088       
1089       // Product ID
1090       const char* product_id = "Turbo CD-ROM    ";
1091       for (i = 0; i < 16; i++)
1092         SELECTED_CONTROLLER(channel).buffer[16+i] = product_id[i];
1093       
1094       // Product Revision level
1095       const char* rev_level = "1.0 ";
1096       for (i = 0; i < 4; i++)
1097         SELECTED_CONTROLLER(channel).buffer[32+i] = rev_level[i];
1098       
1099       rd_ready_to_send_atapi(channels, channel);
1100     }
1101       break;
1102       
1103         case 0x25: { // read cd-rom capacity
1104           // no allocation length???
1105           rd_init_send_atapi_command(channels, channel, atapi_command, 8, 8, false);
1106       
1107           if (SELECTED_DRIVE(channel).cdrom.ready) {
1108             uint32 capacity = SELECTED_DRIVE(channel).cdrom.capacity;
1109             Ramdisk_Print("\t\tCapacity is %d sectors (%d bytes)\n", capacity, capacity * 2048);
1110             SELECTED_CONTROLLER(channel).buffer[0] = (capacity >> 24) & 0xff;
1111             SELECTED_CONTROLLER(channel).buffer[1] = (capacity >> 16) & 0xff;
1112             SELECTED_CONTROLLER(channel).buffer[2] = (capacity >> 8) & 0xff;
1113             SELECTED_CONTROLLER(channel).buffer[3] = (capacity >> 0) & 0xff;
1114             SELECTED_CONTROLLER(channel).buffer[4] = (2048 >> 24) & 0xff;
1115             SELECTED_CONTROLLER(channel).buffer[5] = (2048 >> 16) & 0xff;
1116             SELECTED_CONTROLLER(channel).buffer[6] = (2048 >> 8) & 0xff;
1117             SELECTED_CONTROLLER(channel).buffer[7] = (2048 >> 0) & 0xff;
1118             rd_ready_to_send_atapi(channels, channel);
1119           } else {
1120             rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1121             rd_raise_interrupt(channels, channel);
1122           }
1123         }
1124           break;
1125       
1126         case 0xbe: { // read cd
1127           if (SELECTED_DRIVE(channel).cdrom.ready) {
1128             RD_ERROR("Read CD with CD present not implemented\n");
1129             rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
1130             rd_raise_interrupt(channels, channel);
1131           } else {
1132             rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1133             rd_raise_interrupt(channels, channel);
1134           }
1135         }
1136           break;
1137       
1138         case 0x43: { // read toc
1139           if (SELECTED_DRIVE(channel).cdrom.ready) {
1140             
1141             bool msf = (SELECTED_CONTROLLER(channel).buffer[1] >> 1) & 1;
1142             uint8 starting_track = SELECTED_CONTROLLER(channel).buffer[6];
1143             
1144             uint16 alloc_length = rd_read_16bit(SELECTED_CONTROLLER(channel).buffer + 7);
1145             
1146             uint8 format = (SELECTED_CONTROLLER(channel).buffer[9] >> 6);
1147             int i;
1148             switch (format) {
1149             case 0:
1150               
1151               if (!(SELECTED_DRIVE(channel).cdrom.cd->ops.read_toc(cdif, SELECTED_CONTROLLER(channel).buffer,
1152                                                                &toc_length, msf, starting_track))) {
1153                 rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
1154                                    ASC_INV_FIELD_IN_CMD_PACKET);
1155                 rd_raise_interrupt(channels, channel);
1156               } else {
1157                 rd_init_send_atapi_command(channels, channel, atapi_command, toc_length, alloc_length, false);
1158                 rd_ready_to_send_atapi(channels, channel);
1159               }
1160               break;
1161               
1162             case 1:
1163               // multi session stuff. we ignore this and emulate a single session only
1164               rd_init_send_atapi_command(channels, channel, atapi_command, 12, alloc_length, false);
1165               
1166               SELECTED_CONTROLLER(channel).buffer[0] = 0;
1167               SELECTED_CONTROLLER(channel).buffer[1] = 0x0a;
1168               SELECTED_CONTROLLER(channel).buffer[2] = 1;
1169               SELECTED_CONTROLLER(channel).buffer[3] = 1;
1170               for (i = 0; i < 8; i++)
1171                 SELECTED_CONTROLLER(channel).buffer[4+i] = 0;
1172               
1173               rd_ready_to_send_atapi(channels, channel);
1174               break;
1175               
1176             case 2:
1177             default:
1178               RD_PANIC("(READ TOC) Format %d not supported\n", format);
1179               break;
1180             }
1181           } else {
1182             rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1183             rd_raise_interrupt(channels, channel);
1184           }
1185         }
1186           break;
1187       
1188         case 0x28: // read (10)
1189         case 0xa8: // read (12)
1190           { 
1191         
1192             uint32 transfer_length;
1193             if (atapi_command == 0x28)
1194               transfer_length = rd_read_16bit(SELECTED_CONTROLLER(channel).buffer + 7);
1195             else
1196               transfer_length = rd_read_32bit(SELECTED_CONTROLLER(channel).buffer + 6);
1197             
1198             uint32 lba = rd_read_32bit(SELECTED_CONTROLLER(channel).buffer + 2);
1199             
1200             if (!SELECTED_DRIVE(channel).cdrom.ready) {
1201               rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1202               rd_raise_interrupt(channels, channel);
1203               break;
1204             }
1205             
1206             if (transfer_length == 0) {
1207               rd_atapi_cmd_nop(channels, channel);
1208               rd_raise_interrupt(channels, channel);
1209               Ramdisk_Print("\t\tREAD(%d) with transfer length 0, ok\n", atapi_command==0x28?10:12);
1210               break;
1211             }
1212             
1213             if (lba + transfer_length > SELECTED_DRIVE(channel).cdrom.capacity) {
1214               rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
1215               rd_raise_interrupt(channels, channel);
1216               break;
1217             }
1218             
1219             Ramdisk_Print("\t\tcdrom: READ (%d) LBA=%d LEN=%d\n", atapi_command==0x28?10:12, lba, transfer_length);
1220             
1221             // handle command
1222             rd_init_send_atapi_command(channels, channel, atapi_command, transfer_length * 2048,
1223                                        transfer_length * 2048, true);
1224             SELECTED_DRIVE(channel).cdrom.remaining_blocks = transfer_length;
1225             SELECTED_DRIVE(channel).cdrom.next_lba = lba;
1226             rd_ready_to_send_atapi(channels, channel);
1227           }
1228           break;
1229           
1230         case 0x2b: { // seek
1231           uint32 lba = rd_read_32bit(SELECTED_CONTROLLER(channel).buffer + 2);
1232           if (!SELECTED_DRIVE(channel).cdrom.ready) {
1233             rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1234             rd_raise_interrupt(channels, channel);
1235             break;
1236           }
1237           
1238           if (lba > SELECTED_DRIVE(channel).cdrom.capacity) {
1239             rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
1240             rd_raise_interrupt(channels, channel);
1241             break;
1242           }
1243           Ramdisk_Print("\t\tcdrom: SEEK (ignored)\n");
1244           rd_atapi_cmd_nop(channels, channel);
1245           rd_raise_interrupt(channels, channel);
1246         }
1247           break;
1248       
1249         case 0x1e: { // prevent/allow medium removal
1250           if (SELECTED_DRIVE(channel).cdrom.ready) {
1251             SELECTED_DRIVE(channel).cdrom.locked = SELECTED_CONTROLLER(channel).buffer[4] & 1;
1252             rd_atapi_cmd_nop(channels, channel);
1253           } else {
1254             rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1255           }
1256           rd_raise_interrupt(channels, channel);
1257         }
1258           break;
1259       
1260         case 0x42: { // read sub-channel
1261           bool msf = get_packet_field(channel,1, 1, 1);
1262           bool sub_q = get_packet_field(channel,2, 6, 1);
1263           uint8 data_format = get_packet_byte(channel,3);
1264           uint8 track_number = get_packet_byte(channel,6);
1265           uint16 alloc_length = get_packet_word(channel,7);
1266           UNUSED(msf);
1267           UNUSED(data_format);
1268           UNUSED(track_number);
1269           
1270           if (!SELECTED_DRIVE(channel).cdrom.ready) {
1271             rd_atapi_cmd_error(channels, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1272             rd_raise_interrupt(channels, channel);
1273           } else {
1274             SELECTED_CONTROLLER(channel).buffer[0] = 0;
1275             SELECTED_CONTROLLER(channel).buffer[1] = 0; // audio not supported
1276             SELECTED_CONTROLLER(channel).buffer[2] = 0;
1277             SELECTED_CONTROLLER(channel).buffer[3] = 0;
1278         
1279             int ret_len = 4; // header size
1280         
1281             if (sub_q) { // !sub_q == header only
1282               RD_ERROR("Read sub-channel with SubQ not implemented\n");
1283               rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST,
1284                                  ASC_INV_FIELD_IN_CMD_PACKET);
1285               rd_raise_interrupt(channels, channel);
1286             }
1287         
1288             rd_init_send_atapi_command(channels, channel, atapi_command, ret_len, alloc_length, false);
1289             rd_ready_to_send_atapi(channels, channel);
1290           }
1291         }
1292           break;
1293       
1294         case 0x51: { // read disc info
1295           // no-op to keep the Linux CD-ROM driver happy
1296           rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
1297           rd_raise_interrupt(channels, channel);
1298         }
1299           break;
1300       
1301         case 0x55: // mode select
1302         case 0xa6: // load/unload cd
1303         case 0x4b: // pause/resume
1304         case 0x45: // play audio
1305         case 0x47: // play audio msf
1306         case 0xbc: // play cd
1307         case 0xb9: // read cd msf
1308         case 0x44: // read header
1309         case 0xba: // scan
1310         case 0xbb: // set cd speed
1311         case 0x4e: // stop play/scan
1312         case 0x46: // ???
1313         case 0x4a: // ???
1314           RD_ERROR("ATAPI command 0x%x not implemented yet\n",
1315                    atapi_command);
1316           rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
1317           rd_raise_interrupt(channels, channel);
1318           break;
1319         default:
1320           RD_PANIC("Unknown ATAPI command 0x%x (%d)\n",
1321                    atapi_command, atapi_command);
1322           // We'd better signal the error if the user chose to continue
1323           rd_atapi_cmd_error(channels, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
1324           rd_raise_interrupt(channels, channel);
1325           break;
1326         }
1327       }
1328       
1329       break;
1330       
1331       
1332     default:
1333       RD_PANIC("\t\tIO write(0x%x): current command is %02xh\n", address,
1334                (unsigned) SELECTED_CONTROLLER(channel).current_command);
1335     }
1336
1337 /////////////////////////////////////////////////////////
1338     break;
1339   case 0x01: // hard disk write precompensation 0x1f1
1340     WRITE_FEATURES(channel,value);
1341     break;
1342
1343   case 0x02: // hard disk sector count 0x1f2
1344     WRITE_SECTOR_COUNT(channel,value);
1345     break;
1346     
1347   case 0x03: // hard disk sector number 0x1f3
1348     WRITE_SECTOR_NUMBER(channel,value);
1349     break;
1350     
1351   case 0x04: // hard disk cylinder low 0x1f4
1352     WRITE_CYLINDER_LOW(channel,value);
1353     break;
1354     
1355   case 0x05: // hard disk cylinder high 0x1f5
1356     WRITE_CYLINDER_HIGH(channel,value);
1357     break;
1358     
1359   case 0x06: // hard disk drive and head register 0x1f6
1360     // b7 Extended data field for ECC
1361     // b6/b5: Used to be sector size.  00=256,01=512,10=1024,11=128
1362     //   Since 512 was always used, bit 6 was taken to mean LBA mode:
1363     //     b6 1=LBA mode, 0=CHS mode
1364     //     b5 1
1365     // b4: DRV
1366     // b3..0 HD3..HD0
1367     
1368     if ( (value & 0xa0) != 0xa0 ) // 1x1xxxxx
1369       Ramdisk_Print("\t\tIO write 0x%x (%02x): not 1x1xxxxxb\n", address, (unsigned) value);
1370     
1371     Bit32u drvsel = channels[channel].drive_select = (value >> 4) & 0x01;
1372     WRITE_HEAD_NO(channel,value & 0xf);
1373     if (SELECTED_CONTROLLER(channel).lba_mode == 0 && ((value >> 6) & 1) == 1){
1374       Ramdisk_Print("\t\tenabling LBA mode\n");
1375         }
1376     WRITE_LBA_MODE(channel,(value >> 6) & 1);
1377     SELECTED_DRIVE(channel).cdrom.cd->lba = (value >> 6) & 1;
1378     
1379     
1380     if (!SELECTED_IS_PRESENT(channel)) {
1381       Ramdisk_Print ("\t\tError: device set to %d which does not exist! channel = %d\n",drvsel, channel);
1382       SELECTED_CONTROLLER(channel).error_register = 0x04; // aborted
1383       SELECTED_CONTROLLER(channel).status.err = 1;
1384     }
1385     
1386     break;
1387     
1388     
1389   case 0x07: // hard disk command 0x1f7
1390
1391       switch (value) {
1392         // ATAPI commands
1393         case 0xa1: // IDENTIFY PACKET DEVICE
1394               if (SELECTED_IS_CD(channel)) {
1395                     SELECTED_CONTROLLER(channel).current_command = value;
1396                     SELECTED_CONTROLLER(channel).error_register = 0;
1397
1398                     SELECTED_CONTROLLER(channel).status.busy = 0;
1399                     SELECTED_CONTROLLER(channel).status.drive_ready = 1;
1400                     SELECTED_CONTROLLER(channel).status.write_fault = 0;
1401                     SELECTED_CONTROLLER(channel).status.drq   = 1;
1402                     SELECTED_CONTROLLER(channel).status.err   = 0;
1403
1404                     SELECTED_CONTROLLER(channel).status.seek_complete = 1;
1405                     SELECTED_CONTROLLER(channel).status.corrected_data = 0;
1406
1407                     SELECTED_CONTROLLER(channel).buffer_index = 0;
1408                     rd_raise_interrupt(channels, channel);
1409                     rd_identify_ATAPI_drive(channels, channel);
1410               } else {
1411                 rd_command_aborted(channels, channel, 0xa1);
1412               }
1413               break;
1414
1415         case 0xa0: // SEND PACKET (atapi)
1416               if (SELECTED_IS_CD(channel)) {
1417                     // PACKET
1418                     if (SELECTED_CONTROLLER(channel).features & (1 << 0))
1419                           RD_PANIC("\t\tPACKET-DMA not supported");
1420                     if (SELECTED_CONTROLLER(channel).features & (1 << 1))
1421                           RD_PANIC("\t\tPACKET-overlapped not supported");
1422
1423                     // We're already ready!
1424                     SELECTED_CONTROLLER(channel).sector_count = 1;
1425                     SELECTED_CONTROLLER(channel).status.busy = 0;
1426                     SELECTED_CONTROLLER(channel).status.write_fault = 0;
1427                     // serv bit??
1428                     SELECTED_CONTROLLER(channel).status.drq = 1;
1429                     SELECTED_CONTROLLER(channel).status.err = 0;
1430
1431                     // NOTE: no interrupt here
1432                     SELECTED_CONTROLLER(channel).current_command = value;
1433                     SELECTED_CONTROLLER(channel).buffer_index = 0;
1434               } else {
1435                 rd_command_aborted (channels, channel, 0xa0);
1436               }
1437               break;
1438
1439       default:
1440         Ramdisk_Print("\t\tneed translate command %2x\n", value);
1441         break;
1442       }//switch(value)
1443
1444     
1445   case 0x16: // hard disk adapter control 0x3f6 
1446     // (mch) Even if device 1 was selected, a write to this register
1447     // goes to device 0 (if device 1 is absent)
1448
1449     prev_control_reset = SELECTED_CONTROLLER(channel).control.reset;
1450     channels[channel].drives[0].controller.control.reset         = value & 0x04;
1451     channels[channel].drives[1].controller.control.reset         = value & 0x04;
1452     // CGS: was: SELECTED_CONTROLLER(channel).control.disable_irq    = value & 0x02;
1453     channels[channel].drives[0].controller.control.disable_irq = value & 0x02;
1454     channels[channel].drives[1].controller.control.disable_irq = value & 0x02;
1455     
1456     Ramdisk_Print("\t\tadpater control reg: reset controller = %d\n",
1457                   (unsigned) (SELECTED_CONTROLLER(channel).control.reset) ? 1 : 0);
1458     Ramdisk_Print("\t\tadpater control reg: disable_irq(X) = %d\n",
1459                   (unsigned) (SELECTED_CONTROLLER(channel).control.disable_irq) ? 1 : 0);
1460     
1461     if (!prev_control_reset && SELECTED_CONTROLLER(channel).control.reset) {
1462       // transition from 0 to 1 causes all drives to reset
1463       Ramdisk_Print("\t\thard drive: RESET\n");
1464       
1465       // (mch) Set BSY, drive not ready
1466       for (id = 0; id < 2; id++) {
1467         CONTROLLER(channel,id).status.busy           = 1;
1468         CONTROLLER(channel,id).status.drive_ready    = 0;
1469         CONTROLLER(channel,id).reset_in_progress     = 1;
1470         
1471         CONTROLLER(channel,id).status.write_fault    = 0;
1472         CONTROLLER(channel,id).status.seek_complete  = 1;
1473         CONTROLLER(channel,id).status.drq            = 0;
1474         CONTROLLER(channel,id).status.corrected_data = 0;
1475         CONTROLLER(channel,id).status.err            = 0;
1476         
1477         CONTROLLER(channel,id).error_register = 0x01; // diagnostic code: no error
1478         
1479         CONTROLLER(channel,id).current_command = 0x00;
1480         CONTROLLER(channel,id).buffer_index = 0;
1481         
1482         CONTROLLER(channel,id).sectors_per_block = 0x80;
1483         CONTROLLER(channel,id).lba_mode          = 0;
1484         
1485         CONTROLLER(channel,id).control.disable_irq = 0;
1486         rd_lower_irq((struct vm_device *)(ramdisk_state->private_data), channels[channel].irq);
1487       }
1488     } else if (SELECTED_CONTROLLER(channel).reset_in_progress &&
1489                !SELECTED_CONTROLLER(channel).control.reset) {
1490       // Clear BSY and DRDY
1491       Ramdisk_Print("\t\tReset complete {%s}\n", SELECTED_TYPE_STRING(channel));
1492       for (id = 0; id < 2; id++) {
1493         CONTROLLER(channel,id).status.busy           = 0;
1494         CONTROLLER(channel,id).status.drive_ready    = 1;
1495         CONTROLLER(channel,id).reset_in_progress     = 0;
1496         
1497         // Device signature
1498         if (DRIVE_IS_HD(channel,id)) {
1499           Ramdisk_Print("\t\tdrive %d/%d is harddrive\n", channel, id);
1500           CONTROLLER(channel,id).head_no        = 0;
1501           CONTROLLER(channel,id).sector_count   = 1;
1502           CONTROLLER(channel,id).sector_no      = 1;
1503           CONTROLLER(channel,id).cylinder_no    = 0;
1504         } else {
1505           CONTROLLER(channel,id).head_no        = 0;
1506           CONTROLLER(channel,id).sector_count   = 1;
1507           CONTROLLER(channel,id).sector_no      = 1;
1508           CONTROLLER(channel,id).cylinder_no    = 0xeb14;
1509         }
1510       }
1511     }
1512     Ramdisk_Print("\t\ts[0].controller.control.disable_irq = %02x\n", (channels[channel].drives[0]).controller.control.disable_irq);
1513     Ramdisk_Print("\t\ts[1].controller.control.disable_irq = %02x\n", (channels[channel].drives[1]).controller.control.disable_irq);
1514     break;
1515     
1516   default:
1517     RD_PANIC("\t\thard drive: io write to address %x = %02x\n",
1518                   (unsigned) address, (unsigned) value);
1519   }  
1520   
1521   return;
1522 }
1523
1524
1525 static 
1526 void rd_identify_ATAPI_drive(struct channel_t *channels, Bit8u channel)
1527 {
1528   unsigned i;
1529   const char* serial_number = " VT00001\0\0\0\0\0\0\0\0\0\0\0\0";
1530   const char* firmware = "ALPHA1  ";
1531
1532   SELECTED_DRIVE(channel).id_drive[0] = (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0); // Removable CDROM, 50us response, 12 byte packets
1533
1534   for (i = 1; i <= 9; i++)
1535         SELECTED_DRIVE(channel).id_drive[i] = 0;
1536
1537
1538   for (i = 0; i < 10; i++) {
1539         SELECTED_DRIVE(channel).id_drive[10+i] = (serial_number[i*2] << 8) |
1540               serial_number[i*2 + 1];
1541   }
1542
1543   for (i = 20; i <= 22; i++)
1544         SELECTED_DRIVE(channel).id_drive[i] = 0;
1545
1546
1547   for (i = 0; i < strlen(firmware)/2; i++) {
1548         SELECTED_DRIVE(channel).id_drive[23+i] = (firmware[i*2] << 8) |
1549               firmware[i*2 + 1];
1550   }
1551   V3_ASSERT((23+i) == 27);
1552   
1553   for (i = 0; i < strlen((char *) SELECTED_MODEL(channel))/2; i++) {
1554         SELECTED_DRIVE(channel).id_drive[27+i] = (SELECTED_MODEL(channel)[i*2] << 8) |
1555               SELECTED_MODEL(channel)[i*2 + 1];
1556   }
1557   V3_ASSERT((27+i) == 47);
1558
1559   SELECTED_DRIVE(channel).id_drive[47] = 0;
1560   SELECTED_DRIVE(channel).id_drive[48] = 1; // 32 bits access
1561
1562   SELECTED_DRIVE(channel).id_drive[49] = (1 << 9); // LBA supported
1563
1564   SELECTED_DRIVE(channel).id_drive[50] = 0;
1565   SELECTED_DRIVE(channel).id_drive[51] = 0;
1566   SELECTED_DRIVE(channel).id_drive[52] = 0;
1567
1568   SELECTED_DRIVE(channel).id_drive[53] = 3; // words 64-70, 54-58 valid
1569
1570   for (i = 54; i <= 62; i++)
1571         SELECTED_DRIVE(channel).id_drive[i] = 0;
1572
1573   // copied from CFA540A
1574   SELECTED_DRIVE(channel).id_drive[63] = 0x0103; // variable (DMA stuff)
1575   SELECTED_DRIVE(channel).id_drive[64] = 0x0001; // PIO
1576   SELECTED_DRIVE(channel).id_drive[65] = 0x00b4;
1577   SELECTED_DRIVE(channel).id_drive[66] = 0x00b4;
1578   SELECTED_DRIVE(channel).id_drive[67] = 0x012c;
1579   SELECTED_DRIVE(channel).id_drive[68] = 0x00b4;
1580
1581   SELECTED_DRIVE(channel).id_drive[69] = 0;
1582   SELECTED_DRIVE(channel).id_drive[70] = 0;
1583   SELECTED_DRIVE(channel).id_drive[71] = 30; // faked
1584   SELECTED_DRIVE(channel).id_drive[72] = 30; // faked
1585   SELECTED_DRIVE(channel).id_drive[73] = 0;
1586   SELECTED_DRIVE(channel).id_drive[74] = 0;
1587
1588   SELECTED_DRIVE(channel).id_drive[75] = 0;
1589
1590   for (i = 76; i <= 79; i++)
1591         SELECTED_DRIVE(channel).id_drive[i] = 0;
1592
1593   SELECTED_DRIVE(channel).id_drive[80] = 0x1e; // supports up to ATA/ATAPI-4
1594   SELECTED_DRIVE(channel).id_drive[81] = 0;
1595   SELECTED_DRIVE(channel).id_drive[82] = 0;
1596   SELECTED_DRIVE(channel).id_drive[83] = 0;
1597   SELECTED_DRIVE(channel).id_drive[84] = 0;
1598   SELECTED_DRIVE(channel).id_drive[85] = 0;
1599   SELECTED_DRIVE(channel).id_drive[86] = 0;
1600   SELECTED_DRIVE(channel).id_drive[87] = 0;
1601   SELECTED_DRIVE(channel).id_drive[88] = 0;
1602
1603   for (i = 89; i <= 126; i++)
1604         SELECTED_DRIVE(channel).id_drive[i] = 0;
1605
1606   SELECTED_DRIVE(channel).id_drive[127] = 0;
1607   SELECTED_DRIVE(channel).id_drive[128] = 0;
1608
1609   for (i = 129; i <= 159; i++)
1610         SELECTED_DRIVE(channel).id_drive[i] = 0;
1611
1612   for (i = 160; i <= 255; i++)
1613         SELECTED_DRIVE(channel).id_drive[i] = 0;
1614
1615   // now convert the id_drive array (native 256 word format) to
1616   // the controller buffer (512 bytes)
1617   Bit16u temp16;
1618   for (i = 0; i <= 255; i++) {
1619         temp16 = SELECTED_DRIVE(channel).id_drive[i];
1620         SELECTED_CONTROLLER(channel).buffer[i*2] = temp16 & 0x00ff;
1621         SELECTED_CONTROLLER(channel).buffer[i*2+1] = temp16 >> 8;
1622   }
1623
1624   return;
1625 }
1626
1627
1628
1629 static 
1630 void rd_raise_interrupt(struct channel_t *channels, Bit8u channel)
1631 {
1632   Bit32u irq;
1633   struct vm_device *dev;
1634
1635   Ramdisk_Print("[raise_interrupt] disable_irq = %02x\n", SELECTED_CONTROLLER(channel).control.disable_irq);
1636
1637   if (!SELECTED_CONTROLLER(channel).control.disable_irq) { 
1638     Ramdisk_Print("\t\traising interrupt\n"); 
1639   } else { 
1640     Ramdisk_Print("\t\tNot raising interrupt\n"); 
1641   }
1642   if (!SELECTED_CONTROLLER(channel).control.disable_irq) {
1643     irq = channels[channel].irq; 
1644     Ramdisk_Print("\t\tRaising interrupt %d {%s}\n\n", irq, SELECTED_TYPE_STRING(channel));
1645     //        DEV_pic_raise_irq(irq);
1646     dev = (struct vm_device*) ramdisk_state->private_data;
1647     Ramdisk_Print("\t\tdev = %x\n", dev);
1648     dev->vm->vm_ops.raise_irq(dev->vm, irq);
1649   } else {
1650     Ramdisk_Print("\t\tirq is disabled\n");
1651   }
1652   
1653   return;
1654 }
1655
1656 static
1657 void rd_lower_irq(struct vm_device *dev, Bit32u irq)// __attribute__(regparm(1))
1658 {
1659   Ramdisk_Print("[lower_irq] irq = %d\n", irq);
1660   dev->vm->vm_ops.lower_irq(dev->vm, irq);
1661 }
1662
1663
1664 /*
1665  * Public Routines
1666  */
1667 static
1668 uint_t ramdisk_read_port(ushort_t port,
1669                          void *src,
1670                          uint_t length,
1671                          struct vm_device *dev)
1672 {
1673   uint_t i;
1674   Ramdisk_Print("[ramdisk_read_port] port = %x, length = %d\n", port, length);
1675     switch (length) {
1676     case 1:
1677       ((uchar_t*)src)[0] = rd_read_handler(ramdisk_state->channels, port, length);
1678       break;
1679     case 2:
1680       ((ushort_t*)src)[0] = rd_read_handler(ramdisk_state->channels, port, length);
1681       break;
1682     case 4:
1683       ((uint_t*)src)[0] = rd_read_handler(ramdisk_state->channels, port, length);
1684       break;
1685     default:
1686       for (i = 0; i < length; i++) { 
1687         ((uchar_t*)src)[i] = rd_read_handler(ramdisk_state->channels, port, 1);
1688       }
1689     }//switch length
1690
1691   return length;
1692 }
1693
1694
1695 static
1696 uint_t ramdisk_write_port(ushort_t port,
1697                          void *src,
1698                          uint_t length,
1699                          struct vm_device *dev)
1700 {
1701   Ramdisk_Print("[ramdisk_write_port] port = %x, length = %d\n", port, length);
1702   /*
1703   uint_t i;
1704
1705   for (i = 0; i < length; i++)
1706     Ramdisk_Print("\t\tsrc[%d] = 0x%02x\n", i, ((uchar_t*)src)[i]);
1707   */
1708
1709   switch(length) {
1710   case 1:
1711     rd_write_handler(ramdisk_state->channels, port, *((uchar_t *)src), length);
1712     break;
1713   case 2:
1714     rd_write_handler(ramdisk_state->channels, port, *((ushort_t *)src), length);
1715     break;
1716   case 4:
1717     rd_write_handler(ramdisk_state->channels, port, *((uint_t *)src), length);
1718     break;
1719   default:
1720     rd_write_handler(ramdisk_state->channels, port, *((uchar_t *)src), length);
1721     break;
1722   }
1723
1724   return 1;
1725 }
1726
1727
1728 static void trace_info(ushort_t port, void *src, uint_t length)
1729 {
1730   switch(port){
1731
1732   case 0x3e8:
1733     if (length == 1 && *((uchar_t*) src) == ATA_DETECT)
1734       Ramdisk_Print("ata_dectect()\n");
1735     break;
1736
1737   case 0x3e9:
1738     if (length == 1 && *((uchar_t*) src) == ATA_RESET)
1739       Ramdisk_Print("ata_reset()\n");
1740     break;
1741
1742   case 0x3ea:
1743     if (length == 1 && *((uchar_t*) src) == ATA_CMD_DATA_IN)
1744       Ramdisk_Print("ata_cmd_data_in()\n");
1745     break;
1746
1747   case 0x3eb:
1748     if (length == 1 && *((uchar_t*) src) == ATA_CMD_DATA_OUT)
1749       Ramdisk_Print("ata_cmd_data_out()\n");
1750     break;
1751
1752   case 0x3ec:
1753     if (length == 1 && *((uchar_t*) src) == ATA_CMD_PACKET)
1754       Ramdisk_Print("ata_cmd_packet()\n");
1755     break;
1756
1757   case 0x3ed:
1758     if (length == 1 && *((uchar_t*) src) == ATAPI_GET_SENSE)
1759       Ramdisk_Print("atapi_get_sense()\n");
1760     break;
1761
1762   case 0x3ee:
1763     if (length == 1 && *((uchar_t*) src) == ATAPI_IS_READY)
1764       Ramdisk_Print("atapi_is_ready()\n");
1765     break;
1766
1767   case 0x3ef:
1768     if (length == 1 && *((uchar_t*) src) == ATAPI_IS_CDROM)
1769       Ramdisk_Print("atapi_is_cdrom()\n");
1770     break;
1771
1772
1773   case 0x2e8:
1774     if (length == 1 && *((uchar_t*) src) == CDEMU_INIT)
1775       Ramdisk_Print("cdemu_init()\n");
1776     break;
1777
1778   case 0x2e9:
1779     if (length == 1 && *((uchar_t*) src) == CDEMU_ISACTIVE)
1780       Ramdisk_Print("cdemu_isactive()\n");
1781     break;
1782
1783   case 0x2ea:
1784     if (length == 1 && *((uchar_t*) src) == CDEMU_EMULATED_DRIVE)
1785       Ramdisk_Print("cdemu_emulated_drive()\n");
1786     break;
1787
1788   case 0x2eb:
1789     if (length == 1 && *((uchar_t*) src) == CDROM_BOOT)
1790       Ramdisk_Print("cdrom_boot()\n");
1791     break;
1792
1793   case 0x2ec:
1794     if (length == 1 && *((uchar_t*) src) == HARD_DRIVE_POST)
1795       Ramdisk_Print("ata_hard_drive_post()\n");
1796     break;
1797
1798   case 0x2ed:
1799     if (length == 1)
1800       Ramdisk_Print("ata_device_no(%d)\n", *((uchar_t*) src));
1801     break;
1802
1803   case 0x2ee:
1804     if (length == 1)
1805       Ramdisk_Print("ata_device_type(%d)\n", *((uchar_t*) src));
1806     break;
1807
1808   case 0x2ef:
1809     if (length == 1 && *((uchar_t*) src) == INT13_HARDDISK)
1810       Ramdisk_Print("int13_harddrive()\n");
1811     break;
1812
1813   case 0x2f8:
1814     if (length == 1 && *((uchar_t*) src) == INT13_CDROM)
1815       Ramdisk_Print("int13_cdrom()\n");
1816     break;
1817
1818   case 0x2f9:
1819     if (length == 1 && *((uchar_t*) src) == INT13_CDEMU)
1820       Ramdisk_Print("int13_cdemu()\n");
1821     break;
1822
1823   case 0x2fa:
1824     if (length == 1 && *((uchar_t*) src) == INT13_ELTORITO)
1825       Ramdisk_Print("int13_eltorito()\n");
1826     break;
1827
1828   case 0x2fb:
1829     if (length == 1 && *((uchar_t*) src) == INT13_DISKETTE_FUNCTION)
1830       Ramdisk_Print("int13_diskette_function()\n");
1831     break;
1832
1833
1834   default:
1835     break;
1836   }
1837 }
1838
1839
1840 uint_t ramdisk_read_port_ignore(ushort_t port,
1841                          void *src,
1842                          uint_t length,
1843                          struct vm_device *dev)
1844 {
1845   //  Ramdisk_Print("[ramdisk_read_port_ignore] port = %x, length = %d\n", port, length);
1846   return 1;
1847 }
1848
1849 uint_t ramdisk_write_port_ignore(ushort_t port,
1850                          void *src,
1851                          uint_t length,
1852                          struct vm_device *dev)
1853 {
1854
1855   //  Ramdisk_Print("[ramdisk_write_port_ignore] port = %x, length = %d\n", port, length);
1856
1857   trace_info(port, src, length);
1858   return 1;
1859 }
1860
1861 //////////////////////////////////////////////////////////////////////////
1862
1863 /*
1864  * ATAPI subroutines
1865  */
1866
1867 static 
1868 void rd_init_send_atapi_command(struct channel_t *channels, Bit8u channel, Bit8u command, int req_length, int alloc_length, bool lazy)
1869 {
1870   // SELECTED_CONTROLLER(channel).byte_count is a union of SELECTED_CONTROLLER(channel).cylinder_no;
1871   // lazy is used to force a data read in the buffer at the next read.
1872   
1873   Ramdisk_Print("[rd_init_send_atapi_cmd]\n");
1874   if (SELECTED_CONTROLLER(channel).byte_count == 0xffff)
1875     SELECTED_CONTROLLER(channel).byte_count = 0xfffe;
1876   
1877   if ((SELECTED_CONTROLLER(channel).byte_count & 1)
1878       && !(alloc_length <= SELECTED_CONTROLLER(channel).byte_count)) {
1879     Ramdisk_Print("\t\tOdd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%x\n", 
1880                   SELECTED_CONTROLLER(channel).byte_count, command, SELECTED_CONTROLLER(channel).byte_count - 1);
1881     SELECTED_CONTROLLER(channel).byte_count -= 1;
1882   }
1883   
1884   if (SELECTED_CONTROLLER(channel).byte_count == 0)
1885     RD_PANIC("\t\tATAPI command with zero byte count\n");
1886   
1887   if (alloc_length < 0)
1888     RD_PANIC("\t\tAllocation length < 0\n");
1889   if (alloc_length == 0)
1890     alloc_length = SELECTED_CONTROLLER(channel).byte_count;
1891   
1892   SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
1893   SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 0;
1894   SELECTED_CONTROLLER(channel).status.busy = 0;
1895   SELECTED_CONTROLLER(channel).status.drq = 1;
1896   SELECTED_CONTROLLER(channel).status.err = 0;
1897   
1898   // no bytes transfered yet
1899   if (lazy)
1900     SELECTED_CONTROLLER(channel).buffer_index = 2048;
1901   else
1902     SELECTED_CONTROLLER(channel).buffer_index = 0;
1903   SELECTED_CONTROLLER(channel).drq_index = 0;
1904   
1905   if (SELECTED_CONTROLLER(channel).byte_count > req_length)
1906     SELECTED_CONTROLLER(channel).byte_count = req_length;
1907   
1908   if (SELECTED_CONTROLLER(channel).byte_count > alloc_length)
1909     SELECTED_CONTROLLER(channel).byte_count = alloc_length;
1910   
1911   SELECTED_DRIVE(channel).atapi.command = command;
1912   SELECTED_DRIVE(channel).atapi.drq_bytes = SELECTED_CONTROLLER(channel).byte_count;
1913   SELECTED_DRIVE(channel).atapi.total_bytes_remaining = (req_length < alloc_length) ? req_length : alloc_length;
1914   
1915   // if (lazy) {
1916   // // bias drq_bytes and total_bytes_remaining
1917   // SELECTED_DRIVE(channel).atapi.drq_bytes += 2048;
1918   // SELECTED_DRIVE(channel).atapi.total_bytes_remaining += 2048;
1919   // }
1920 }
1921
1922
1923 static 
1924 void rd_atapi_cmd_error(struct channel_t *channels, Bit8u channel, sense_t sense_key, asc_t asc)
1925 {
1926   Ramdisk_Print("[rd_atapi_cmd_error]\n");
1927   Ramdisk_Print("Error: atapi_cmd_error channel=%02x key=%02x asc=%02x\n", channel, sense_key, asc);
1928
1929   SELECTED_CONTROLLER(channel).error_register = sense_key << 4;
1930   SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
1931   SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
1932   SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
1933   SELECTED_CONTROLLER(channel).status.busy = 0;
1934   SELECTED_CONTROLLER(channel).status.drive_ready = 1;
1935   SELECTED_CONTROLLER(channel).status.write_fault = 0;
1936   SELECTED_CONTROLLER(channel).status.drq = 0;
1937   SELECTED_CONTROLLER(channel).status.err = 1;
1938   
1939   SELECTED_DRIVE(channel).sense.sense_key = sense_key;
1940   SELECTED_DRIVE(channel).sense.asc = asc;
1941   SELECTED_DRIVE(channel).sense.ascq = 0;
1942 }
1943
1944
1945 static 
1946 void rd_atapi_cmd_nop(struct channel_t *channels, Bit8u channel)
1947 {
1948   Ramdisk_Print("[rd_atapi_cmd_nop]\n");
1949   SELECTED_CONTROLLER(channel).interrupt_reason.i_o = 1;
1950   SELECTED_CONTROLLER(channel).interrupt_reason.c_d = 1;
1951   SELECTED_CONTROLLER(channel).interrupt_reason.rel = 0;
1952   SELECTED_CONTROLLER(channel).status.busy = 0;
1953   SELECTED_CONTROLLER(channel).status.drive_ready = 1;
1954   SELECTED_CONTROLLER(channel).status.drq = 0;
1955   SELECTED_CONTROLLER(channel).status.err = 0;
1956 }
1957
1958
1959 static 
1960 void rd_init_mode_sense_single(struct channel_t *channels, 
1961                                Bit8u channel, const void* src, int size)
1962 {
1963   Ramdisk_Print("[rd_init_mode_sense_single]\n");
1964   // Header
1965   SELECTED_CONTROLLER(channel).buffer[0] = (size+6) >> 8;
1966   SELECTED_CONTROLLER(channel).buffer[1] = (size+6) & 0xff;
1967   SELECTED_CONTROLLER(channel).buffer[2] = 0x70; // no media present
1968   SELECTED_CONTROLLER(channel).buffer[3] = 0; // reserved
1969   SELECTED_CONTROLLER(channel).buffer[4] = 0; // reserved
1970   SELECTED_CONTROLLER(channel).buffer[5] = 0; // reserved
1971   SELECTED_CONTROLLER(channel).buffer[6] = 0; // reserved
1972   SELECTED_CONTROLLER(channel).buffer[7] = 0; // reserved
1973   
1974   // Data
1975   memcpy(SELECTED_CONTROLLER(channel).buffer + 8, src, size);
1976 }
1977
1978
1979 static 
1980 void rd_ready_to_send_atapi(struct channel_t *channels, Bit8u channel)
1981 {
1982   Ramdisk_Print("[rd_ready_to_send_atapi]\n");
1983   rd_raise_interrupt(ramdisk_state->channels, channel);
1984 }
1985
1986
1987 static 
1988 void rd_command_aborted(struct channel_t *channels, 
1989                         Bit8u channel, unsigned value)
1990 {
1991   Ramdisk_Print("[rd_command_aborted]\n");
1992   Ramdisk_Print("\t\taborting on command 0x%02x {%s}\n", value, SELECTED_TYPE_STRING(channel));
1993   SELECTED_CONTROLLER(channel).current_command = 0;
1994   SELECTED_CONTROLLER(channel).status.busy = 0;
1995   SELECTED_CONTROLLER(channel).status.drive_ready = 1;
1996   SELECTED_CONTROLLER(channel).status.err = 1;
1997   SELECTED_CONTROLLER(channel).error_register = 0x04; // command ABORTED
1998   SELECTED_CONTROLLER(channel).status.drq = 0;
1999   SELECTED_CONTROLLER(channel).status.seek_complete = 0;
2000   SELECTED_CONTROLLER(channel).status.corrected_data = 0;
2001   SELECTED_CONTROLLER(channel).buffer_index = 0;
2002   rd_raise_interrupt(ramdisk_state->channels, channel);
2003 }
2004
2005
2006
2007 /*
2008  * Success: return 0; 
2009  * Failure: return integer greater than 0
2010  */
2011
2012 struct ramdisk_t * create_ramdisk()
2013 {
2014   struct ramdisk_t *ramdisk;
2015   ramdisk = (struct ramdisk_t *)V3_Malloc(sizeof(struct ramdisk_t));  
2016   V3_ASSERT(ramdisk != NULL);
2017   
2018   ramdisk->cops.init = &rd_init_harddrive;
2019   ramdisk->cops.close = &rd_close_harddrive;
2020   ramdisk->cops.reset = &rd_reset_harddrive;
2021
2022   ramdisk->eops.read_port = &ramdisk_read_port;
2023   ramdisk->eops.write_port = &ramdisk_write_port;
2024   ramdisk->eops.read_port_ignore = &ramdisk_read_port_ignore;
2025   ramdisk->eops.write_port_ignore = &ramdisk_write_port_ignore;
2026  
2027   return ramdisk;
2028 }