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.


reformatted device source files
[palacios.git] / palacios / src / devices / ramdisk.c
1 /* 
2  *
3  *   Copyright (C) 2002  MandrakeSoft S.A.
4  *
5  *     MandrakeSoft S.A.
6  *     43, rue d'Aboukir
7  *     75002 Paris - France
8  *     http://www.linux-mandrake.com/
9  *     http://www.mandrakesoft.com/
10  *
11  *   This library is free software; you can redistribute it and/or
12  *   modify it under the terms of the GNU Lesser General Public
13  *   License as published by the Free Software Foundation; either
14  *   version 2 of the License, or (at your option) any later version.
15  *
16  *   This library is distributed in the hope that it will be useful,
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19  *   Lesser General Public License for more details.
20  *
21  *  You should have received a copy of the GNU Lesser General Public
22  *  License along with this library; if not, write to the Free Software
23  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
24  *
25  * Major modifications made for the V3VEE project
26  * 
27  * The V3VEE Project is a joint project between Northwestern University
28  * and the University of New Mexico.  You can find out more at 
29  * http://www.v3vee.org
30  * 
31  * Copyright (c) 2008, Zheng Cui <cuizheng@cs.unm.edu>
32  * Copyright (c) 2008, Jack Lange <jarusl@cs.northwestern.edu>
33  * Copyright (c) 2008, The V3VEE Project <http://www.v3vee.org> 
34  * All rights reserved for original changes
35  * 
36  */
37
38
39 #include <devices/ramdisk.h>
40 #include <palacios/vmm.h>
41 #include <devices/cdrom.h>
42 #include <devices/ide.h>
43
44
45 #ifndef TRACE_RAMDISK
46 #undef PrintTrace
47 #define PrintTrace(fmt, args...)
48 #endif
49
50
51 #ifndef DEBUG_RAMDISK
52 #undef PrintDebug
53 #define PrintDebug(fmt, args...)
54 #endif
55
56
57
58
59
60 /*
61  * Data type definitions
62  *
63  */
64 #define INDEX_PULSE_CYCLE 10
65
66
67
68
69 #define INTR_REASON_BIT_ERR           0x01
70 #define UNABLE_FIND_TAT_CHANNEL_ERR   0x02
71 #define DRQ_ERR                       0x03
72 #define READ_BUF_GT_512               0x04
73
74
75
76 #define PRI_DATA_PORT         0x1f0
77 #define PRI_FEATURES_PORT     0x1f1
78 #define PRI_SECT_CNT_PORT     0x1f2
79 #define PRI_SECT_ADDR1_PORT   0x1f3
80 #define PRI_SECT_ADDR2_PORT   0x1f4
81 #define PRI_SECT_ADDR3_PORT   0x1f5
82 #define PRI_DRV_SEL_PORT      0x1f6
83 #define PRI_CMD_PORT          0x1f7
84 #define PRI_CTRL_PORT         0x3f6
85 #define PRI_ADDR_REG_PORT     0x3f7
86
87 #define SEC_DATA_PORT         0x170
88 #define SEC_FEATURES_PORT     0x171
89 #define SEC_SECT_CNT_PORT     0x172
90 #define SEC_SECT_ADDR1_PORT   0x173
91 #define SEC_SECT_ADDR2_PORT   0x174
92 #define SEC_SECT_ADDR3_PORT   0x175
93 #define SEC_DRV_SEL_PORT      0x176
94 #define SEC_CMD_PORT          0x177
95 #define SEC_CTRL_PORT         0x376
96 #define SEC_ADDR_REG_PORT     0x377
97
98
99 #define PACKET_SIZE 12
100
101
102
103 static const char cdrom_str[] = "CD-ROM";
104 static const char harddisk_str[] = "HARDDISK";
105 static const char none_str[] = "NONE";
106
107
108 static inline const char * device_type_to_str(device_type_t type) {
109     switch (type) {
110         case IDE_DISK:
111             return harddisk_str;
112         case IDE_CDROM:
113             return cdrom_str;
114         case IDE_NONE:
115             return none_str;
116         default:
117             return NULL;
118     }
119 }
120
121
122 static inline void write_features(struct channel_t * channel, uchar_t value) {
123     channel->drives[0].controller.features = value;
124     channel->drives[1].controller.features = value;
125 }
126
127
128 static inline void write_sector_count(struct channel_t * channel, uchar_t value) {
129     channel->drives[0].controller.sector_count = value;
130     channel->drives[1].controller.sector_count = value;
131 }
132
133 static inline void write_sector_number(struct channel_t * channel, uchar_t value) {
134     channel->drives[0].controller.sector_no = value;
135     channel->drives[1].controller.sector_no = value;
136 }
137
138
139 static inline void write_cylinder_low(struct channel_t * channel, uchar_t value) {
140     channel->drives[0].controller.cylinder_no &= 0xff00;
141     channel->drives[0].controller.cylinder_no |= value;
142     channel->drives[1].controller.cylinder_no &= 0xff00;
143     channel->drives[1].controller.cylinder_no |= value;
144 }
145
146 static inline void write_cylinder_high(struct channel_t * channel, uchar_t value) {
147     ushort_t val2 = value;
148     val2 = val2 << 8;
149     channel->drives[0].controller.cylinder_no &= 0x00ff;
150     channel->drives[0].controller.cylinder_no |= (val2 & 0xff00);
151
152     channel->drives[1].controller.cylinder_no &= 0x00ff;
153     channel->drives[1].controller.cylinder_no |= (val2 & 0xff00);
154 }
155
156 static inline void write_head_no(struct channel_t * channel, uchar_t value) {
157     channel->drives[0].controller.head_no = value;
158     channel->drives[1].controller.head_no = value;
159 }
160
161 static inline void write_lba_mode(struct channel_t * channel, uchar_t value) {
162     channel->drives[0].controller.lba_mode = value;
163     channel->drives[1].controller.lba_mode = value;
164 }
165
166
167 static inline uint_t get_channel_no(struct ramdisk_t * ramdisk, struct channel_t * channel) {
168     return (((uchar_t *)channel - (uchar_t *)(ramdisk->channels)) / sizeof(struct channel_t));
169 }
170
171 static inline uint_t get_drive_no(struct channel_t * channel, struct drive_t * drive) {
172     return (((uchar_t *)drive - (uchar_t*)(channel->drives)) /  sizeof(struct drive_t));
173 }
174
175 static inline struct drive_t * get_selected_drive(struct channel_t * channel) {
176     return &(channel->drives[channel->drive_select]);
177 }
178
179
180 static inline int is_primary_port(struct ramdisk_t * ramdisk, ushort_t port) {
181     switch(port) 
182         {
183             case PRI_DATA_PORT:
184             case PRI_FEATURES_PORT:
185             case PRI_SECT_CNT_PORT:
186             case PRI_SECT_ADDR1_PORT:
187             case PRI_SECT_ADDR2_PORT:
188             case PRI_SECT_ADDR3_PORT:
189             case PRI_DRV_SEL_PORT:
190             case PRI_CMD_PORT:
191             case PRI_CTRL_PORT:
192                 return 1;
193             default:
194                 return 0;
195         }
196 }
197
198
199
200 static inline int is_secondary_port(struct ramdisk_t * ramdisk, ushort_t port) {
201     switch(port) 
202         {
203             case SEC_DATA_PORT:
204             case SEC_FEATURES_PORT:
205             case SEC_SECT_CNT_PORT:
206             case SEC_SECT_ADDR1_PORT:
207             case SEC_SECT_ADDR2_PORT:
208             case SEC_SECT_ADDR3_PORT:
209             case SEC_DRV_SEL_PORT:
210             case SEC_CMD_PORT:
211             case SEC_CTRL_PORT:
212                 return 1;
213             default:
214                 return 0;
215         }
216 }
217
218 static inline int num_drives_on_channel(struct channel_t * channel) {
219     if ((channel->drives[0].device_type == IDE_NONE) &&
220         (channel->drives[1].device_type == IDE_NONE)) {
221         return 0;
222     } else if ((channel->drives[0].device_type != IDE_NONE) &&
223                (channel->drives[1].device_type != IDE_NONE)) {
224         return 2;
225     } else {
226         return 1;
227     }
228 }
229
230
231
232 static inline uchar_t extract_bits(uchar_t * buf, uint_t buf_offset, uint_t bit_offset, uint_t num_bits) {
233     uchar_t val = buf[buf_offset];
234     val = val >> bit_offset;
235     val &= ((1 << num_bits) -1);
236     return val;
237 }
238
239
240 static inline uchar_t get_packet_field(struct channel_t * channel, uint_t packet_offset, uint_t bit_offset, uint_t num_bits) {
241     struct drive_t * drive = get_selected_drive(channel);
242     return extract_bits(drive->controller.buffer, packet_offset, bit_offset, num_bits);
243 }
244
245
246 static inline uchar_t get_packet_byte(struct channel_t * channel, uint_t offset) {
247     struct drive_t * drive = get_selected_drive(channel);
248     return drive->controller.buffer[offset];
249 }
250
251 static inline uint16_t get_packet_word(struct channel_t * channel, uint_t offset) {
252     struct drive_t * drive = get_selected_drive(channel);
253     uint16_t val = drive->controller.buffer[offset];
254     val = val << 8;
255     val |= drive->controller.buffer[offset + 1];
256     return val;
257 }
258
259
260 static inline uint16_t rd_read_16bit(const uint8_t* buf) {
261     return (buf[0] << 8) | buf[1];
262 }
263
264
265
266 static inline uint32_t rd_read_32bit(const uint8_t* buf) {
267     return (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
268 }
269
270 ////////////////////////////////////////////////////////////////////////////
271
272
273 /*
274  * ATAPI routines
275  */
276
277
278 static void rd_init_mode_sense_single(struct vm_device * dev, struct channel_t * channel, const void * src, int size);
279
280 static void rd_command_aborted(struct vm_device * dev, struct channel_t * channel, unsigned value);
281
282
283
284
285 static int handle_atapi_packet_command(struct vm_device * dev, 
286                                        struct channel_t * channel, 
287                                        ushort_t val);
288
289 static int rd_init_send_atapi_command(struct vm_device * dev, 
290                                       struct channel_t * channel, 
291                                       Bit8u command, int req_length, 
292                                       int alloc_length, bool lazy);
293
294 static void rd_ready_to_send_atapi(struct vm_device * dev, 
295                                    struct channel_t * channel);
296
297 static void rd_atapi_cmd_error(struct vm_device * dev, 
298                                struct channel_t * channel, 
299                                sense_t sense_key, asc_t asc);
300
301 static void rd_atapi_cmd_nop(struct vm_device * dev, struct channel_t * channel);
302 static void rd_identify_ATAPI_drive(struct vm_device * dev, struct channel_t * channel);
303
304
305
306 /*
307  * Interrupt handling
308  */
309 static void rd_raise_interrupt(struct vm_device * dev, struct channel_t * channel);
310 static void rd_lower_irq(struct vm_device *dev, struct channel_t * channel);
311
312
313
314 /*
315  * Helper routines
316  */
317
318
319
320 #ifdef DEBUG_RAMDISK
321 static void rd_print_state(struct ramdisk_t *ramdisk);
322 static int check_bit_fields(struct controller_t * controller);
323 #endif
324
325
326 ////////////////////////////////////////////////////////////////////
327
328
329
330
331
332 int v3_ramdisk_register_cdrom(struct vm_device * dev, uint_t busID, uint_t driveID, struct cdrom_ops* cd, void * private_data) {
333     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
334     struct channel_t * channel = &(ramdisk->channels[busID]);
335     struct drive_t * drive = &(channel->drives[driveID]);
336     struct controller_t * controller = &(drive->controller);
337
338
339   
340     if (drive->device_type != IDE_NONE) {
341         PrintError("Device already registered at this location\n");
342         return -1;
343     }
344
345
346     channel->irq =  15;
347
348     // Make model string
349     strncpy((char*)(drive->model_no), "V3VEE Ramdisk", 40);
350
351     while (strlen((char *)(drive->model_no)) < 40) {
352         strcat ((char*)(drive->model_no), " ");
353     }
354   
355     PrintDebug("CDROM on target %d/%d\n", busID, driveID);
356   
357     drive->device_type = IDE_CDROM;
358     drive->cdrom.locked = 0;
359     drive->sense.sense_key = SENSE_NONE;
360     drive->sense.asc = 0;
361     drive->sense.ascq = 0;
362   
363     drive->private_data = private_data;
364
365
366 #ifdef DEBUG_RAMDISK
367     if (check_bit_fields(controller) == INTR_REASON_BIT_ERR) {
368         PrintError("interrupt reason: bit field error\n");
369         return INTR_REASON_BIT_ERR;
370     }
371 #endif
372   
373     controller->sector_count = 0;
374
375     drive->cdrom.cd = cd;
376   
377     PrintDebug("\t\tCD on ata%d-%d: '%s'\n", 
378                busID, 
379                driveID, "");
380   
381     if(drive->cdrom.cd->insert_cdrom(drive->private_data)) {
382         PrintDebug("\t\tMedia present in CD-ROM drive\n");
383         drive->cdrom.ready = 1;
384         drive->cdrom.capacity = drive->cdrom.cd->capacity(drive->private_data);
385         PrintDebug("\t\tCDROM capacity is %d\n", drive->cdrom.capacity);
386     } else {                
387         PrintDebug("\t\tCould not locate CD-ROM, continuing with media not present\n");
388         drive->cdrom.ready = 0;
389     }
390   
391     return 0;
392 }
393
394
395 static Bit32u rd_init_hardware(struct ramdisk_t *ramdisk) {
396     uint_t channel_num; 
397     uint_t device;
398     struct channel_t *channels = (struct channel_t *)(&(ramdisk->channels));
399
400     PrintDebug("[rd_init_harddrive]\n");
401
402     for (channel_num = 0; channel_num < MAX_ATA_CHANNEL; channel_num++) {
403         memset((char *)(channels + channel_num), 0, sizeof(struct channel_t));
404     }
405
406     for (channel_num = 0; channel_num < MAX_ATA_CHANNEL; channel_num++){
407         struct channel_t * channel = &(channels[channel_num]);
408
409         channel->ioaddr1 = 0x0;
410         channel->ioaddr2 = 0x0;
411         channel->irq = 0;
412
413         for (device = 0; device < 2; device++){
414             struct drive_t * drive = &(channel->drives[device]);
415             struct controller_t * controller = &(drive->controller);
416
417             controller->status.busy = 0;
418             controller->status.drive_ready = 1;
419             controller->status.write_fault = 0;
420             controller->status.seek_complete = 1;
421             controller->status.drq = 0;
422             controller->status.corrected_data = 0;
423             controller->status.index_pulse = 0;
424             controller->status.index_pulse_count = 0;
425             controller->status.err = 0;
426
427             controller->error_register = 0x01; // diagnostic code: no error
428             controller->head_no = 0;
429             controller->sector_count = 1;
430             controller->sector_no = 1;
431             controller->cylinder_no = 0;
432             controller->current_command = 0x00;
433             controller->buffer_index = 0;
434
435             controller->control.reset = 0;
436             controller->control.disable_irq = 0;
437             controller->reset_in_progress = 0;
438
439             controller->sectors_per_block = 0x80;
440             controller->lba_mode = 0;
441       
442       
443             controller->features = 0;
444         
445             // If not present
446             drive->device_type = IDE_NONE;
447
448             // Make model string
449             strncpy((char*)(drive->model_no), "", 40);
450             while(strlen((char *)(drive->model_no)) < 40) {
451                 strcat ((char*)(drive->model_no), " ");
452             }
453
454         }//for device
455     }//for channel
456
457 #ifdef DEBUG_RAMDISK
458     rd_print_state(ramdisk);
459 #endif
460     return 0;
461 }
462
463
464 /*
465   static void rd_reset_harddrive(struct ramdisk_t *ramdisk, unsigned type) {
466   return;
467   }
468
469 */
470 static void rd_close_harddrive(struct ramdisk_t *ramdisk) {
471     return;
472 }
473
474
475 ////////////////////////////////////////////////////////////////////
476
477
478
479 static int read_data_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
480     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
481     struct channel_t * channel = NULL;
482     struct drive_t * drive = NULL;
483     struct controller_t * controller = NULL;
484
485
486
487     if (is_primary_port(ramdisk, port)) {
488         channel = &(ramdisk->channels[0]);
489     } else if (is_secondary_port(ramdisk, port)) {
490         channel = &(ramdisk->channels[1]);
491     } else {
492         PrintError("Invalid Port: %d\n", port);
493         return -1;
494     }
495   
496     drive = get_selected_drive(channel);
497     controller = &(drive->controller);
498
499
500     PrintTrace("[read_data_handler] IO Read at 0x%x, on drive %d/%d current cmd=0x%x\n", 
501                port, 
502                get_channel_no(ramdisk, channel),
503                get_drive_no(channel, drive), 
504                controller->current_command);
505
506     switch (controller->current_command) {
507         case 0xec:    // IDENTIFY DEVICE
508         case 0xa1:
509             {
510
511
512                 controller->status.busy = 0;
513                 controller->status.drive_ready = 1;
514                 controller->status.write_fault = 0;
515                 controller->status.seek_complete = 1;
516                 controller->status.corrected_data = 0;
517                 controller->status.err = 0;
518       
519                 /*
520                   value32 = controller->buffer[index];
521                   index++;
522         
523                   if (io_len >= 2) {
524                   value32 |= (controller->buffer[index] << 8);
525                   index++;
526                   }
527         
528                   if (io_len == 4) {
529                   value32 |= (controller->buffer[index] << 16);
530                   value32 |= (controller->buffer[index+1] << 24);
531                   index += 2;
532                   }
533         
534                   controller->buffer_index = index;
535                 */
536                 /* JRL */
537                 memcpy(dst, controller->buffer + controller->buffer_index, length);
538                 controller->buffer_index += length;
539       
540                 if (controller->buffer_index >= 512) {
541                     controller->status.drq = 0;
542                 }
543       
544                 return length;
545             }
546         case 0xa0: //send packet cmd 
547             {
548                 uint_t index = controller->buffer_index;
549
550       
551                 PrintTrace("\t\tatapi.command(%02x), index(%d), cdrom.remaining_blocks(%d)\n", 
552                            drive->atapi.command, 
553                            index, 
554                            drive->cdrom.remaining_blocks);
555       
556                 // Load block if necessary
557                 if (index >= 2048) {
558         
559                     if (index > 2048) {
560                         PrintError("\t\tindex > 2048 : 0x%x\n", index);
561                         return -1;
562                     }
563         
564                     switch (drive->atapi.command) {
565                         case 0x28: // read (10)
566                         case 0xa8: // read (12)
567                             {
568     
569                                 if (!(drive->cdrom.ready)) {
570                                     PrintError("\t\tRead with CDROM not ready\n");
571                                     return -1;
572                                 } 
573             
574                                 drive->cdrom.cd->read_block(drive->private_data, controller->buffer,
575                                                             drive->cdrom.next_lba);
576                                 drive->cdrom.next_lba++;
577                                 drive->cdrom.remaining_blocks--;
578             
579             
580                                 if (!(drive->cdrom.remaining_blocks)) {
581                                     PrintDebug("\t\tLast READ block loaded {CDROM}\n");
582                                 } else {
583                                     PrintDebug("\t\tREAD block loaded (%d remaining) {CDROM}\n",
584                                                drive->cdrom.remaining_blocks);
585                                 }
586             
587                                 // one block transfered, start at beginning
588                                 index = 0;
589                                 break;
590                             }
591                         default: // no need to load a new block
592                             break;
593                     }
594                 }
595     
596
597                 /*
598                   increment = 0;
599                   value32 = controller->buffer[index + increment];
600                   increment++;
601         
602                   if (io_len >= 2) {
603                   value32 |= (controller->buffer[index + increment] << 8);
604                   increment++;
605                   }
606         
607                   if (io_len == 4) {
608                   value32 |= (controller->buffer[index + increment] << 16);
609                   value32 |= (controller->buffer[index + increment + 1] << 24);
610                   increment += 2;
611                   }
612
613                   controller->buffer_index = index + increment;
614                   controller->drq_index += increment;
615
616                 */
617                 /* JRL: CHECK THAT there is enough data in the buffer to copy.... */
618                 {      
619                     memcpy(dst, controller->buffer + index, length);
620         
621                     controller->buffer_index  = index + length;
622                     controller->drq_index += length;
623                 }
624       
625                 /* *** */
626       
627                 if (controller->drq_index >= (unsigned)drive->atapi.drq_bytes) {
628                     controller->status.drq = 0;
629                     controller->drq_index = 0;
630         
631                     drive->atapi.total_bytes_remaining -= drive->atapi.drq_bytes;
632         
633                     if (drive->atapi.total_bytes_remaining > 0) {
634                         // one or more blocks remaining (works only for single block commands)
635           
636                         PrintDebug("\t\tPACKET drq bytes read\n");
637                         controller->interrupt_reason.i_o = 1;
638                         controller->status.busy = 0;
639                         controller->status.drq = 1;
640                         controller->interrupt_reason.c_d = 0;
641           
642                         // set new byte count if last block
643                         if (drive->atapi.total_bytes_remaining < controller->byte_count) {
644                             controller->byte_count = drive->atapi.total_bytes_remaining;
645                         }
646                         drive->atapi.drq_bytes = controller->byte_count;
647           
648                         rd_raise_interrupt(dev, channel);
649                     } else {
650                         // all bytes read
651                         PrintDebug("\t\tPACKET all bytes read\n");
652           
653                         controller->interrupt_reason.i_o = 1;
654                         controller->interrupt_reason.c_d = 1;
655                         controller->status.drive_ready = 1;
656                         controller->interrupt_reason.rel = 0;
657                         controller->status.busy = 0;
658                         controller->status.drq = 0;
659                         controller->status.err = 0;
660           
661                         rd_raise_interrupt(dev, channel);
662                     }
663                 }
664                 return length;
665                 break;
666             }
667
668         default:
669             PrintError("\t\tunsupported command: %02x\n", controller->current_command);
670             break;
671     }
672
673     return -1;
674 }
675
676
677
678
679 static int write_data_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
680     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
681     struct channel_t * channel = NULL;
682     struct drive_t * drive = NULL;
683     struct controller_t * controller = NULL;
684
685     if (is_primary_port(ramdisk, port)) {
686         channel = &(ramdisk->channels[0]);
687     } else if (is_secondary_port(ramdisk, port)) {
688         channel = &(ramdisk->channels[1]);
689     } else {
690         PrintError("Invalid Port: %d\n", port);
691         return -1;
692     }
693   
694     drive = get_selected_drive(channel);
695     controller = &(drive->controller);
696
697
698     PrintDebug("[write_data_handler] IO write at 0x%x, current_cmd = 0x%02x\n", 
699                port, controller->current_command);
700
701  
702
703     //PrintDebug("[write_data_handler]\n");
704     switch (controller->current_command) {
705         case 0x30: // WRITE SECTORS
706             PrintError("\t\tneed to implement 0x30(write sector) to port 0x%x\n", port);
707             return -1;
708     
709         case 0xa0: // PACKET
710     
711             if (handle_atapi_packet_command(dev, channel, *(ushort_t *)src) == -1) {
712                 PrintError("Error sending atapi packet command in PACKET write to data port\n");
713                 return -1;
714             }
715
716             return length;
717     
718         default:
719             PrintError("\t\tIO write(0x%x): current command is %02xh\n", 
720                        port, controller->current_command);
721
722             return -1;
723     }
724
725
726     return -1;
727 }
728
729
730
731
732
733
734
735 static int read_status_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
736     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
737     struct channel_t * channel = NULL;
738     struct drive_t * drive = NULL;
739     struct controller_t * controller = NULL;
740
741
742
743
744     if (is_primary_port(ramdisk, port)) {
745         channel = &(ramdisk->channels[0]);
746     } else if (is_secondary_port(ramdisk, port)) {
747         channel = &(ramdisk->channels[1]);
748     } else {
749         PrintError("Invalid Port: %d\n", port);
750         return -1;
751     }
752   
753     drive = get_selected_drive(channel);
754     controller = &(drive->controller);
755
756  
757     PrintDebug("[read_status_handler] IO read at 0x%x, on drive %d/%d\n", 
758                port, get_channel_no(ramdisk, channel), 
759                channel->drive_select);
760
761
762     if (num_drives_on_channel(channel) == 0) {
763         PrintDebug("Setting value to zero because 0 devices on channel\n");
764         // (mch) Just return zero for these registers
765         memset(dst, 0, length);
766
767     } else {
768         uchar_t val = (
769                        (controller->status.busy << 7)            |
770                        (controller->status.drive_ready << 6)     |
771                        (controller->status.write_fault << 5)     |
772                        (controller->status.seek_complete << 4)   |
773                        (controller->status.drq << 3)             |
774                        (controller->status.corrected_data << 2)  |
775                        (controller->status.index_pulse << 1)     |
776                        (controller->status.err) );
777
778
779         memcpy(dst, &val, length);
780
781         controller->status.index_pulse_count++;
782         controller->status.index_pulse = 0;
783     
784         if (controller->status.index_pulse_count >= INDEX_PULSE_CYCLE) {
785             controller->status.index_pulse = 1;
786             controller->status.index_pulse_count = 0;
787         }
788     }
789   
790     if ((port == SEC_CMD_PORT) || (port == PRI_CMD_PORT)) {
791         rd_lower_irq(dev, channel);
792     }
793   
794     PrintDebug("\t\tRead STATUS = 0x%x\n", *(uchar_t *)dst);
795
796     return length;
797   
798 }
799
800
801 static int write_cmd_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
802     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
803     struct channel_t * channel = NULL;
804     struct drive_t * drive = NULL;
805     struct controller_t * controller = NULL;
806     uchar_t value = *(uchar_t *)src;
807
808     if (length != 1) {
809         PrintError("Invalid Command port write length: %d (port=%d)\n", length, port);
810         return -1;
811     }
812
813     if (is_primary_port(ramdisk, port)) {
814         channel = &(ramdisk->channels[0]);
815     } else if (is_secondary_port(ramdisk, port)) {
816         channel = &(ramdisk->channels[1]);
817     } else {
818         PrintError("Invalid Port: %d\n", port);
819         return -1;
820     }
821   
822     drive = get_selected_drive(channel);
823     controller = &(drive->controller);
824
825
826     PrintDebug("[write_command_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n", 
827                port, get_channel_no(ramdisk, channel), 
828                get_drive_no(channel, drive), 
829                value);
830
831     switch (value) {
832 #if 0
833         case 0xec: // IDENTIFY DEVICE
834             {
835
836                 if (drive->device_type == IDE_NONE) {
837                     PrintError("\t\tError: disk ata%d-%d not present, aborting\n", 
838                                get_channel_no(ramdisk, channel), 
839                                get_drive_no(channel, drive));
840                     rd_command_aborted(dev, channel, value);
841                     break;
842                 } else if (drive->device_type == IDE_CDROM) {
843                     PrintDebug("Identifying CDROM...Going to abort????\n");
844                     controller->head_no        = 0;
845                     controller->sector_count   = 1;
846                     controller->sector_no      = 1;
847                     controller->cylinder_no    = 0xeb14;
848                     rd_command_aborted(dev, channel, 0xec);
849                 } else {
850                     PrintError("\t\tError: Want to identify HDD!!\n");
851                     /*
852                       SELECTED_CONTROLLER(channel).current_command = value;
853                       SELECTED_CONTROLLER(channel).error_register = 0;
854           
855                       // See ATA/ATAPI-4, 8.12
856                       SELECTED_CONTROLLER(channel).status.busy  = 0;
857                       SELECTED_CONTROLLER(channel).status.drive_ready = 1;
858                       SELECTED_CONTROLLER(channel).status.write_fault = 0;
859                       SELECTED_CONTROLLER(channel).status.drq   = 1;
860                       SELECTED_CONTROLLER(channel).status.err   = 0;
861           
862                       SELECTED_CONTROLLER(channel).status.seek_complete = 1;
863                       SELECTED_CONTROLLER(channel).status.corrected_data = 0;
864           
865                       SELECTED_CONTROLLER(channel).buffer_index = 0;
866                       raise_interrupt(channel);
867                       identify_drive(channel);
868                     */
869                 }
870
871                 break;
872             }
873 #endif
874             // ATAPI commands
875         case 0xa1: // IDENTIFY PACKET DEVICE
876             {
877                 if (drive->device_type == IDE_CDROM) {
878                     controller->current_command = value;
879                     controller->error_register = 0;
880         
881                     controller->status.busy = 0;
882                     controller->status.drive_ready = 1;
883                     controller->status.write_fault = 0;
884                     controller->status.drq   = 1;
885                     controller->status.err   = 0;
886         
887                     controller->status.seek_complete = 1;
888                     controller->status.corrected_data = 0;
889         
890                     controller->buffer_index = 0;
891                     rd_raise_interrupt(dev, channel);
892                     rd_identify_ATAPI_drive(dev, channel);
893                 } else {
894                     PrintError("Identifying non cdrom device not supported - ata %d/%d\n", 
895                                get_channel_no(ramdisk, channel),
896                                get_drive_no(channel, drive));
897                     rd_command_aborted(dev, channel, 0xa1);
898                 }
899                 break;
900             }
901         case 0xa0: // SEND PACKET (atapi)
902             {
903                 if (drive->device_type == IDE_CDROM) {
904                     // PACKET
905         
906                     if (controller->features & (1 << 0)) {
907                         PrintError("\t\tPACKET-DMA not supported");
908                         return -1;
909                     }
910         
911                     if (controller->features & (1 << 1)) {
912                         PrintError("\t\tPACKET-overlapped not supported");
913                         return -1;
914                     }
915         
916                     // We're already ready!
917                     controller->sector_count = 1;
918                     controller->status.busy = 0;
919                     controller->status.write_fault = 0;
920
921                     // serv bit??
922                     controller->status.drq = 1;
923                     controller->status.err = 0;
924         
925                     // NOTE: no interrupt here
926                     controller->current_command = value;
927                     controller->buffer_index = 0;
928                 } else {
929                     PrintError("Sending packet to non cdrom device not supported\n");
930                     rd_command_aborted (dev, channel, 0xa0);
931                 }
932                 break;
933             }
934         default:
935             PrintError("\t\tneed translate command %2x - ata %d\%d\n", value, 
936                        get_channel_no(ramdisk, channel), 
937                        get_drive_no(channel, drive));
938             //return -1;
939             /* JRL THIS NEEDS TO CHANGE */
940             return length;
941
942     }
943     return length;
944 }
945
946
947 static int write_ctrl_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
948     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
949     struct channel_t * channel = NULL;
950     struct drive_t * master_drive = NULL;
951     struct drive_t * slave_drive = NULL;
952     struct controller_t * controller = NULL;
953     uchar_t value = *(uchar_t *)src;
954     rd_bool prev_control_reset;
955
956     if (length != 1) {
957         PrintError("Invalid Status port read length: %d (port=%d)\n", length, port);
958         return -1;
959     }
960
961     if (is_primary_port(ramdisk, port)) {
962         channel = &(ramdisk->channels[0]);
963     } else if (is_secondary_port(ramdisk, port)) {
964         channel = &(ramdisk->channels[1]);
965     } else {
966         PrintError("Invalid Port: %d\n", port);
967         return -1;
968     }
969
970     master_drive = &(channel->drives[0]);
971     slave_drive = &(channel->drives[1]);
972
973     controller = &(get_selected_drive(channel)->controller);
974
975
976     PrintDebug("[write_control_handler] IO write at 0x%x, on drive %d/%d (val = 0x%x)\n", 
977                port, get_channel_no(ramdisk, channel), 
978                channel->drive_select, 
979                value);
980
981     // (mch) Even if device 1 was selected, a write to this register
982     // goes to device 0 (if device 1 is absent)
983   
984     prev_control_reset = controller->control.reset;
985
986
987     if (value & 0x04) {
988         PrintDebug("RESET Signaled\n");
989     }
990
991     master_drive->controller.control.reset         = value & 0x04;
992     slave_drive->controller.control.reset         = value & 0x04;
993
994     // CGS: was: SELECTED_CONTROLLER(channel).control.disable_irq    = value & 0x02;
995     master_drive->controller.control.disable_irq = value & 0x02;
996     slave_drive->controller.control.disable_irq = value & 0x02;
997   
998     PrintDebug("\t\tadpater control reg: reset controller = %d\n",
999                (unsigned) (controller->control.reset) ? 1 : 0);
1000     PrintDebug("\t\tadpater control reg: disable_irq(X) = %d\n",
1001                (unsigned) (controller->control.disable_irq) ? 1 : 0);
1002   
1003     if ((!prev_control_reset) && (controller->control.reset)) {
1004         uint_t id = 0;
1005
1006         // transition from 0 to 1 causes all drives to reset
1007         PrintDebug("\t\thard drive: RESET\n");
1008     
1009         // (mch) Set BSY, drive not ready
1010         for (id = 0; id < 2; id++) {
1011             struct controller_t * ctrl = NULL;
1012
1013             if (id == 0) {
1014                 ctrl = &(master_drive->controller);
1015             } else if (id == 1) {
1016                 ctrl = &(slave_drive->controller);
1017             }
1018
1019             ctrl->status.busy           = 1;
1020             ctrl->status.drive_ready    = 0;
1021             ctrl->reset_in_progress     = 1;
1022       
1023             ctrl->status.write_fault    = 0;
1024             ctrl->status.seek_complete  = 1;
1025             ctrl->status.drq            = 0;
1026             ctrl->status.corrected_data = 0;
1027             ctrl->status.err            = 0;
1028       
1029             ctrl->error_register = 0x01; // diagnostic code: no error
1030       
1031             ctrl->current_command = 0x00;
1032             ctrl->buffer_index = 0;
1033       
1034             ctrl->sectors_per_block = 0x80;
1035             ctrl->lba_mode          = 0;
1036       
1037             ctrl->control.disable_irq = 0;
1038         }
1039
1040         rd_lower_irq(dev, channel);
1041
1042     } else if ((controller->reset_in_progress) &&
1043                (!controller->control.reset)) {
1044         uint_t id;
1045         // Clear BSY and DRDY
1046         PrintDebug("\t\tReset complete {%s}\n", device_type_to_str(get_selected_drive(channel)->device_type));
1047
1048         for (id = 0; id < 2; id++) {
1049             struct controller_t * ctrl = NULL;
1050             struct drive_t * drv = NULL;
1051
1052             if (id == 0) {
1053                 ctrl = &(master_drive->controller);
1054                 drv = master_drive;
1055             } else if (id == 1) {
1056                 ctrl = &(slave_drive->controller);
1057                 drv = slave_drive;
1058             }
1059
1060             ctrl->status.busy           = 0;
1061             ctrl->status.drive_ready    = 1;
1062             ctrl->reset_in_progress     = 0;
1063       
1064             // Device signature
1065             if (drv->device_type == IDE_DISK) {
1066                 PrintDebug("\t\tdrive %d/%d is harddrive\n", get_channel_no(ramdisk, channel), id);
1067                 ctrl->head_no        = 0;
1068                 ctrl->sector_count   = 1;
1069                 ctrl->sector_no      = 1;
1070                 ctrl->cylinder_no    = 0;
1071             } else {
1072                 ctrl->head_no        = 0;
1073                 ctrl->sector_count   = 1;
1074                 ctrl->sector_no      = 1;
1075                 ctrl->cylinder_no    = 0xeb14;
1076             }
1077         }
1078     }
1079
1080     PrintDebug("\t\ts[0].controller.control.disable_irq = %02x\n", 
1081                master_drive->controller.control.disable_irq);
1082     PrintDebug("\t\ts[1].controller.control.disable_irq = %02x\n", 
1083                slave_drive->controller.control.disable_irq);
1084     return length;
1085 }
1086
1087
1088 static int read_general_port(ushort_t port, void * dst, uint_t length, struct vm_device * dev) {
1089     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
1090     struct channel_t * channel = NULL;
1091     struct drive_t * drive = NULL;
1092     struct controller_t * controller = NULL;
1093
1094
1095     if (length != 1) {
1096         PrintError("Invalid Status port read length: %d (port=%d)\n", length, port);
1097         return -1;
1098     }
1099
1100     if (is_primary_port(ramdisk, port)) {
1101         channel = &(ramdisk->channels[0]);
1102     } else if (is_secondary_port(ramdisk, port)) {
1103         channel = &(ramdisk->channels[1]);
1104     } else {
1105         PrintError("Invalid Port: %d\n", port);
1106         return -1;
1107     }
1108   
1109     drive = get_selected_drive(channel);
1110     controller = &(drive->controller);
1111
1112
1113     PrintDebug("[read_general_handler] IO read addr at %x, on drive %d/%d, curcmd = %02x\n", 
1114                port, get_channel_no(ramdisk, channel), 
1115                channel->drive_select, 
1116                controller->current_command);
1117   
1118
1119     switch (port) {
1120         case PRI_FEATURES_PORT:
1121         case SEC_FEATURES_PORT: // hard disk error register 0x1f1
1122             {    
1123                 uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->error_register;
1124       
1125                 controller->status.err = 0;
1126       
1127                 PrintDebug("\t\tRead FEATURES = 0x%x\n", val);
1128
1129                 *(uchar_t *)dst = val;
1130                 return length;
1131       
1132                 break;
1133             }
1134
1135         case PRI_SECT_CNT_PORT:
1136         case SEC_SECT_CNT_PORT:  // hard disk sector count / interrupt reason 0x1f2
1137             {
1138                 uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->sector_count;
1139                 PrintDebug("\t\tRead SECTOR COUNT = 0x%x\n", val);
1140                 *(uchar_t *)dst = val;
1141                 return length;
1142
1143                 break;
1144             }
1145         case PRI_SECT_ADDR1_PORT:
1146         case SEC_SECT_ADDR1_PORT: // sector number 0x1f3
1147             { 
1148                 uchar_t val = (drive->device_type == IDE_NONE) ? 0 : controller->sector_no;
1149
1150                 PrintDebug("\t\tRead SECTOR ADDR1 = 0x%x\n", val);
1151
1152                 *(uchar_t *)dst = val;
1153                 return length;
1154
1155                 break;
1156             }
1157
1158         case PRI_SECT_ADDR2_PORT:
1159         case SEC_SECT_ADDR2_PORT:  // cylinder low 0x1f4  
1160             {
1161                 // -- WARNING : On real hardware the controller registers are shared between drives. 
1162                 // So we must respond even if the select device is not present. Some OS uses this fact 
1163                 // to detect the disks.... minix2 for example
1164                 uchar_t val = (num_drives_on_channel(channel) == 0) ? 0 : (controller->cylinder_no & 0x00ff);
1165
1166                 PrintDebug("\t\tRead SECTOR ADDR2 = 0x%x\n", val);
1167
1168                 *(uchar_t *)dst = val;
1169                 return length;
1170
1171                 break;      
1172             }
1173
1174         case PRI_SECT_ADDR3_PORT:
1175         case SEC_SECT_ADDR3_PORT: // cylinder high 0x1f5
1176             {
1177                 // -- WARNING : On real hardware the controller registers are shared between drives. 
1178                 // So we must respond even if the select device is not present. Some OS uses this fact 
1179                 // to detect the disks.... minix2 for example
1180                 uchar_t val = (num_drives_on_channel(channel) == 0) ? 0 : (controller->cylinder_no >> 8);
1181
1182                 PrintDebug("\t\tRead SECTOR ADDR3 = 0x%x\n", val);
1183
1184                 *(uchar_t *)dst = val;
1185                 return length;
1186
1187                 break;    
1188             }
1189         case PRI_DRV_SEL_PORT:
1190         case SEC_DRV_SEL_PORT:  // hard disk drive and head register 0x1f6
1191             {
1192                 // b7 Extended data field for ECC
1193                 // b6/b5: Used to be sector size.  00=256,01=512,10=1024,11=128
1194                 //   Since 512 was always used, bit 6 was taken to mean LBA mode:
1195                 //     b6 1=LBA mode, 0=CHS mode
1196                 //     b5 1
1197                 // b4: DRV
1198                 // b3..0 HD3..HD0
1199                 uchar_t val = ((1 << 7)                          |
1200                                ((controller->lba_mode > 0) << 6) |
1201                                (1 << 5)                          |            // 01b = 512 sector size
1202                                (channel->drive_select << 4)      |
1203                                (controller->head_no << 0));
1204       
1205                 PrintDebug("\t\tRead DRIVE SELECT = 0x%x\n", val);
1206                 *(uchar_t *)dst = val;
1207                 return length;
1208
1209                 break;
1210             }
1211         case PRI_ADDR_REG_PORT:
1212         case SEC_ADDR_REG_PORT: // Hard Disk Address Register 0x3f7
1213             {
1214                 // Obsolete and unsupported register.  Not driven by hard
1215                 // disk controller.  Report all 1's.  If floppy controller
1216                 // is handling this address, it will call this function
1217                 // set/clear D7 (the only bit it handles), then return
1218                 // the combined value
1219                 *(uchar_t *)dst = 0xff;
1220                 return length;
1221             }
1222
1223         default:
1224             PrintError("Invalid Port: %d\n", port);
1225             return -1;
1226     }
1227 }
1228
1229
1230
1231
1232 static int write_general_port(ushort_t port, void * src, uint_t length, struct vm_device * dev) {
1233     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
1234     struct channel_t * channel = NULL;
1235     struct drive_t * drive = NULL;
1236     struct controller_t * controller = NULL;
1237     uchar_t value = *(uchar_t *)src;
1238
1239     if (length != 1) {
1240         PrintError("Invalid Status port read length: %d (port=%d)\n", length, port);
1241         return -1;
1242     }
1243
1244     if (is_primary_port(ramdisk, port)) {
1245         channel = &(ramdisk->channels[0]);
1246     } else if (is_secondary_port(ramdisk, port)) {
1247         channel = &(ramdisk->channels[1]);
1248     } else {
1249         PrintError("Invalid Port: %d\n", port);
1250         return -1;
1251     }
1252   
1253     drive = get_selected_drive(channel);
1254     controller = &(drive->controller);
1255
1256
1257     PrintDebug("[write_general_handler] IO write to port %x (val=0x%02x), channel = %d\n", 
1258                port, value, get_channel_no(ramdisk, channel));
1259
1260     switch (port) {
1261
1262         case PRI_FEATURES_PORT:
1263         case SEC_FEATURES_PORT: // hard disk write precompensation 0x1f1
1264             {
1265                 write_features(channel, value);
1266                 break;
1267             }
1268         case PRI_SECT_CNT_PORT:
1269         case SEC_SECT_CNT_PORT: // hard disk sector count 0x1f2
1270             {
1271                 write_sector_count(channel, value);
1272                 break;
1273             }
1274         case PRI_SECT_ADDR1_PORT:
1275         case SEC_SECT_ADDR1_PORT: // hard disk sector number 0x1f3
1276             {
1277                 write_sector_number(channel, value);
1278                 break;
1279             }
1280         case PRI_SECT_ADDR2_PORT:
1281         case SEC_SECT_ADDR2_PORT: // hard disk cylinder low 0x1f4
1282             {
1283                 write_cylinder_low(channel, value);
1284                 break;
1285             }
1286         case PRI_SECT_ADDR3_PORT:
1287         case SEC_SECT_ADDR3_PORT: // hard disk cylinder high 0x1f5
1288             {
1289                 write_cylinder_high(channel, value);
1290                 break;
1291             }
1292         case PRI_DRV_SEL_PORT:
1293         case SEC_DRV_SEL_PORT: // hard disk drive and head register 0x1f6
1294             {
1295                 // b7 Extended data field for ECC
1296                 // b6/b5: Used to be sector size.  00=256,01=512,10=1024,11=128
1297                 //   Since 512 was always used, bit 6 was taken to mean LBA mode:
1298                 //     b6 1=LBA mode, 0=CHS mode
1299                 //     b5 1
1300                 // b4: DRV
1301                 // b3..0 HD3..HD0
1302
1303                 // 1x1xxxxx
1304
1305                 PrintDebug("\tDrive Select value=%x\n", value);
1306
1307                 if ((value & 0xa0) != 0xa0) { 
1308                     PrintDebug("\t\tIO write 0x%x (%02x): not 1x1xxxxxb\n", port, (unsigned) value);
1309                 }
1310       
1311                 write_head_no(channel, value & 0xf);
1312                 if ((controller->lba_mode == 0) && (((value >> 6) & 1) == 1)) {
1313                     PrintDebug("\t\tenabling LBA mode\n");
1314                 }
1315
1316                 write_lba_mode(channel, (value >> 6) & 1);
1317
1318
1319
1320                 if (drive->cdrom.cd) {
1321                     PrintDebug("\t\tSetting LBA on CDROM: %d\n", (value >> 6) & 1);
1322                     drive->cdrom.cd->set_LBA(drive->private_data, (value >> 6) & 1);
1323                 }
1324       
1325
1326                 channel->drive_select = (value >> 4) & 0x01;
1327                 drive = get_selected_drive(channel);
1328
1329                 if (drive->device_type == IDE_NONE) {
1330                     PrintError("\t\tError: device set to %d which does not exist! channel = 0x%x\n",
1331                                channel->drive_select, get_channel_no(ramdisk, channel));
1332
1333                     controller->error_register = 0x04; // aborted
1334                     controller->status.err = 1;
1335                 }
1336       
1337                 break;
1338             }
1339         default:
1340             PrintError("\t\thard drive: io write to unhandled port 0x%x  (value = %c)\n", port, value);
1341             //return -1;
1342     }
1343
1344     return length;
1345 }
1346
1347
1348  
1349
1350
1351 static void rd_raise_interrupt(struct vm_device * dev, struct channel_t * channel) {
1352     //  struct ramdisk_t * ramdisk = (struct ramdisk_t *)(dev->private_data);
1353     struct drive_t * drive = get_selected_drive(channel);
1354     struct controller_t * controller = &(drive->controller);
1355
1356     PrintDebug("[raise_interrupt] disable_irq = 0x%02x\n", controller->control.disable_irq);
1357
1358     if (!(controller->control.disable_irq)) {
1359  
1360         PrintDebug("\t\tRaising interrupt %d {%s}\n\n", channel->irq, device_type_to_str(drive->device_type));
1361
1362         v3_raise_irq(dev->vm, channel->irq);
1363     } else {
1364         PrintDebug("\t\tRaising irq but irq is disabled\n");
1365     }
1366   
1367     return;
1368 }
1369
1370 static void rd_lower_irq(struct vm_device *dev, struct channel_t * channel) {
1371     PrintDebug("[lower_irq] irq = %d\n", channel->irq);
1372     v3_lower_irq(dev->vm, channel->irq);
1373 }
1374
1375
1376
1377
1378
1379
1380
1381 //////////////////////////////////////////////////////////////////////////
1382
1383 /*
1384  * ATAPI subroutines
1385  */
1386
1387
1388
1389 int handle_atapi_packet_command(struct vm_device * dev, struct channel_t * channel, ushort_t value) {
1390     struct ramdisk_t * ramdisk  = (struct ramdisk_t *)(dev->private_data);
1391     struct drive_t * drive = get_selected_drive(channel);
1392     struct controller_t * controller = &(drive->controller);
1393
1394     if (controller->buffer_index >= PACKET_SIZE) {
1395         PrintError("ATAPI packet exceeded maximum length: buffer_index (%d) >= PACKET_SIZE\n", 
1396                    controller->buffer_index);
1397         return -1;
1398     }
1399
1400     controller->buffer[controller->buffer_index] = value;
1401     controller->buffer[controller->buffer_index + 1] = (value >> 8);
1402     controller->buffer_index += 2;
1403   
1404   
1405     /* if packet completely writtten */
1406     if (controller->buffer_index >= PACKET_SIZE) {
1407         // complete command received
1408         Bit8u atapi_command = controller->buffer[0];
1409     
1410         PrintDebug("\t\tcdrom: ATAPI command 0x%x started\n", atapi_command);
1411     
1412         switch (atapi_command) {
1413             case 0x00: // test unit ready
1414                 {
1415                     PrintDebug("Testing unit ready\n");
1416                     if (drive->cdrom.ready) {
1417                         rd_atapi_cmd_nop(dev, channel);
1418                     } else {
1419                         PrintError("CDROM not ready in test unit ready\n");
1420                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1421                     }
1422         
1423                     rd_raise_interrupt(dev, channel);
1424         
1425                     break;
1426                 }
1427             case 0x03:  // request sense
1428                 {
1429                     int alloc_length = controller->buffer[4];
1430
1431                     if (rd_init_send_atapi_command(dev, channel, atapi_command, 18, alloc_length, false) == -1) {
1432                         PrintError("Error sending atapi command in Request Sense\n");
1433                         return -1;
1434                     }
1435         
1436                     // sense data
1437                     controller->buffer[0] = 0x70 | (1 << 7);
1438                     controller->buffer[1] = 0;
1439                     controller->buffer[2] = drive->sense.sense_key;
1440                     controller->buffer[3] = drive->sense.information.arr[0];
1441                     controller->buffer[4] = drive->sense.information.arr[1];
1442                     controller->buffer[5] = drive->sense.information.arr[2];
1443                     controller->buffer[6] = drive->sense.information.arr[3];
1444                     controller->buffer[7] = 17 - 7;
1445                     controller->buffer[8] = drive->sense.specific_inf.arr[0];
1446                     controller->buffer[9] = drive->sense.specific_inf.arr[1];
1447                     controller->buffer[10] = drive->sense.specific_inf.arr[2];
1448                     controller->buffer[11] = drive->sense.specific_inf.arr[3];
1449                     controller->buffer[12] = drive->sense.asc;
1450                     controller->buffer[13] = drive->sense.ascq;
1451                     controller->buffer[14] = drive->sense.fruc;
1452                     controller->buffer[15] = drive->sense.key_spec.arr[0];
1453                     controller->buffer[16] = drive->sense.key_spec.arr[1];
1454                     controller->buffer[17] = drive->sense.key_spec.arr[2];
1455         
1456                     rd_ready_to_send_atapi(dev, channel);
1457                     break;
1458                 }
1459             case 0x1b:  // start stop unit
1460                 {
1461                     //bx_bool Immed = (controller->buffer[1] >> 0) & 1;
1462                     rd_bool LoEj = (controller->buffer[4] >> 1) & 1;
1463                     rd_bool Start = (controller->buffer[4] >> 0) & 1;
1464
1465                     // stop the disc
1466                     if ((!LoEj) && (!Start)) { 
1467                         PrintError("FIXME: Stop disc not implemented\n");
1468
1469                         rd_atapi_cmd_nop(dev, channel);
1470                         rd_raise_interrupt(dev, channel);
1471
1472                     } else if (!LoEj && Start) { // start (spin up) the disc
1473           
1474                         drive->cdrom.cd->start_cdrom(drive->private_data);
1475           
1476                         PrintError("FIXME: ATAPI start disc not reading TOC\n");
1477                         rd_atapi_cmd_nop(dev, channel);
1478                         rd_raise_interrupt(dev, channel);
1479
1480                     } else if (LoEj && !Start) { // Eject the disc
1481                         rd_atapi_cmd_nop(dev, channel);
1482                         PrintDebug("Ejecting Disk\n");
1483                         if (drive->cdrom.ready) {
1484             
1485                             drive->cdrom.cd->eject_cdrom(drive->private_data);
1486             
1487                             drive->cdrom.ready = 0;
1488                             //bx_options.atadevice[channel][SLAVE_SELECTED(channel)].Ostatus->set(EJECTED);
1489                             //bx_gui->update_drive_status_buttons();
1490                         }
1491                         rd_raise_interrupt(dev, channel);
1492
1493                     } else { // Load the disc
1494                         // My guess is that this command only closes the tray, that's a no-op for us
1495                         rd_atapi_cmd_nop(dev, channel);
1496                         rd_raise_interrupt(dev, channel);
1497                     }
1498                     break;
1499                 }
1500             case 0xbd: // mechanism status
1501                 {
1502                     uint16_t alloc_length = rd_read_16bit(controller->buffer + 8);
1503         
1504                     if (alloc_length == 0) {
1505                         PrintError("Zero allocation length to MECHANISM STATUS not impl.\n");
1506                         return -1;
1507                     }
1508         
1509                     if (rd_init_send_atapi_command(dev, channel, atapi_command, 8, alloc_length, false) == -1) {
1510                         PrintError("Error sending atapi command in mechanism status\n");
1511                         return -1;
1512                     }
1513         
1514                     controller->buffer[0] = 0; // reserved for non changers
1515                     controller->buffer[1] = 0; // reserved for non changers
1516         
1517                     controller->buffer[2] = 0; // Current LBA (TODO!)
1518                     controller->buffer[3] = 0; // Current LBA (TODO!)
1519                     controller->buffer[4] = 0; // Current LBA (TODO!)
1520         
1521                     controller->buffer[5] = 1; // one slot
1522         
1523                     controller->buffer[6] = 0; // slot table length
1524                     controller->buffer[7] = 0; // slot table length
1525         
1526                     rd_ready_to_send_atapi(dev, channel);
1527                     break;
1528                 }
1529             case 0x5a:  // mode sense
1530                 {
1531                     uint16_t alloc_length = rd_read_16bit(controller->buffer + 7);
1532         
1533                     Bit8u PC = controller->buffer[2] >> 6;
1534                     Bit8u PageCode = controller->buffer[2] & 0x3f;
1535         
1536                     switch (PC) {
1537                         case 0x0: // current values
1538                             {
1539                                 switch (PageCode) {
1540                                     case 0x01: // error recovery
1541                                         {
1542                 
1543                                             if (rd_init_send_atapi_command(dev, channel, atapi_command, sizeof(struct error_recovery_t) + 8, alloc_length, false) == -1) {
1544                                                 PrintError("Error sending atapi command in mode sense error recovery\n");
1545                                                 return -1;
1546                                             }
1547                 
1548                                             rd_init_mode_sense_single(dev, channel, &(drive->cdrom.current.error_recovery),
1549                                                                       sizeof(struct error_recovery_t));
1550                                             rd_ready_to_send_atapi(dev, channel);
1551                                             break;
1552                                         }
1553                                     case 0x2a: // CD-ROM capabilities & mech. status
1554                                         {
1555
1556                                             if (rd_init_send_atapi_command(dev, channel, atapi_command, 28, alloc_length, false) == -1) {
1557                                                 PrintError("Error sending atapi command in CDROM caps/mech mode-sense\n");
1558                                                 return -1;
1559                                             }
1560
1561                                             rd_init_mode_sense_single(dev, channel, &(controller->buffer[8]), 28);
1562                 
1563                                             controller->buffer[8] = 0x2a;
1564                                             controller->buffer[9] = 0x12;
1565                                             controller->buffer[10] = 0x00;
1566                                             controller->buffer[11] = 0x00;
1567                                             // Multisession, Mode 2 Form 2, Mode 2 Form 1
1568                                             controller->buffer[12] = 0x70; 
1569                                             controller->buffer[13] = (3 << 5);
1570                                             controller->buffer[14] = (unsigned char) (1 |
1571                                                                                       (drive->cdrom.locked ? (1 << 1) : 0) |
1572                                                                                       (1 << 3) |
1573                                                                                       (1 << 5));
1574                                             controller->buffer[15] = 0x00;
1575                                             controller->buffer[16] = (706 >> 8) & 0xff;
1576                                             controller->buffer[17] = 706 & 0xff;
1577                                             controller->buffer[18] = 0;
1578                                             controller->buffer[19] = 2;
1579                                             controller->buffer[20] = (512 >> 8) & 0xff;
1580                                             controller->buffer[21] = 512 & 0xff;
1581                                             controller->buffer[22] = (706 >> 8) & 0xff;
1582                                             controller->buffer[23] = 706 & 0xff;
1583                                             controller->buffer[24] = 0;
1584                                             controller->buffer[25] = 0;
1585                                             controller->buffer[26] = 0;
1586                                             controller->buffer[27] = 0;
1587                                             rd_ready_to_send_atapi(dev, channel);
1588                                             break;
1589                                         }
1590                                     case 0x0d: // CD-ROM
1591                                     case 0x0e: // CD-ROM audio control
1592                                     case 0x3f: // all
1593                                         {
1594                                             PrintError("Ramdisk: cdrom: MODE SENSE (curr), code=%x not implemented yet\n",
1595                                                        PageCode);
1596                                             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1597                                                                ASC_INV_FIELD_IN_CMD_PACKET);
1598                                             rd_raise_interrupt(dev, channel);
1599                                             break;
1600                                         }
1601                                     default:
1602                                         {
1603                                             // not implemeted by this device
1604                                             PrintError("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
1605                                                        PC, PageCode);
1606                                             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1607                                                                ASC_INV_FIELD_IN_CMD_PACKET);
1608                                             rd_raise_interrupt(dev, channel);
1609                                             break;
1610                                         }
1611                                 }
1612                                 break;
1613                             }
1614                         case 0x1: // changeable values
1615                             {
1616                                 switch (PageCode) {
1617                                     case 0x01: // error recovery
1618                                     case 0x0d: // CD-ROM
1619                                     case 0x0e: // CD-ROM audio control
1620                                     case 0x2a: // CD-ROM capabilities & mech. status
1621                                     case 0x3f: // all
1622                                         {
1623                                             PrintError("cdrom: MODE SENSE (chg), code=%x not implemented yet\n",
1624                                                        PageCode);
1625                                             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1626                                                                ASC_INV_FIELD_IN_CMD_PACKET);
1627                                             rd_raise_interrupt(dev, channel);
1628                                             break;
1629                                         }
1630                                     default:
1631                                         {
1632                                             // not implemeted by this device
1633                                             PrintError("Changeable values of mode sense not supported by cdrom\n");
1634                                             PrintDebug("\t\tcdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
1635                                                        PC, PageCode);
1636                                             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1637                                                                ASC_INV_FIELD_IN_CMD_PACKET);
1638                                             rd_raise_interrupt(dev, channel);
1639                                             break;
1640                                         }
1641                                 }
1642                                 break;
1643                             }
1644                         case 0x2: // default values
1645                             {
1646                                 switch (PageCode) {
1647                                     case 0x01: // error recovery
1648                                     case 0x0d: // CD-ROM
1649                                     case 0x0e: // CD-ROM audio control
1650                                     case 0x2a: // CD-ROM capabilities & mech. status
1651                                     case 0x3f: // all
1652                                         PrintError("Default values of mode sense not supported by cdrom\n");
1653                                         PrintDebug("cdrom: MODE SENSE (dflt), code=%x\n",
1654                                                    PageCode);
1655                                         return -1;
1656               
1657                                     default:
1658                                         {
1659                                             PrintError("Default values of mode sense not implemented in cdrom\n");
1660                                             // not implemeted by this device
1661                                             PrintDebug("cdrom: MODE SENSE PC=%x, PageCode=%x, not implemented by device\n",
1662                                                        PC, PageCode);
1663                                             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1664                                                                ASC_INV_FIELD_IN_CMD_PACKET);
1665                                             rd_raise_interrupt(dev, channel);
1666                                             break;
1667                                         }
1668                                 }
1669                                 break;
1670                             }
1671                         case 0x3: // saved values not implemented
1672                             {
1673                                 PrintError("\t\tSaved values not implemented in mode sense\n");
1674                                 rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_SAVING_PARAMETERS_NOT_SUPPORTED);
1675                                 rd_raise_interrupt(dev, channel);
1676                                 break;
1677                             }
1678                         default:
1679                             {
1680                                 PrintError("Unsupported Mode sense value\n");
1681                                 return -1;
1682                                 break;
1683                             }
1684                     }
1685                     break;
1686                 }
1687             case 0x12: // inquiry
1688                 { 
1689                     uint8_t alloc_length = controller->buffer[4];
1690         
1691                     if (rd_init_send_atapi_command(dev, channel, atapi_command, 36, alloc_length, false) == -1) {
1692                         PrintError("Error sending atapi command in inquiry\n");
1693                         return -1;
1694                     }
1695         
1696                     controller->buffer[0] = 0x05; // CD-ROM
1697                     controller->buffer[1] = 0x80; // Removable
1698                     controller->buffer[2] = 0x00; // ISO, ECMA, ANSI version
1699                     controller->buffer[3] = 0x21; // ATAPI-2, as specified
1700                     controller->buffer[4] = 31; // additional length (total 36)
1701                     controller->buffer[5] = 0x00; // reserved
1702                     controller->buffer[6] = 0x00; // reserved
1703                     controller->buffer[7] = 0x00; // reserved
1704         
1705                     // Vendor ID
1706                     const char* vendor_id = "VTAB    ";
1707                     int i;
1708                     for (i = 0; i < 8; i++) {
1709                         controller->buffer[8+i] = vendor_id[i];
1710                     }
1711
1712                     // Product ID
1713                     const char* product_id = "Turbo CD-ROM    ";
1714                     for (i = 0; i < 16; i++) {
1715                         controller->buffer[16+i] = product_id[i];
1716                     }
1717
1718                     // Product Revision level
1719                     const char* rev_level = "1.0 ";     
1720                     for (i = 0; i < 4; i++) {
1721                         controller->buffer[32 + i] = rev_level[i];
1722                     }
1723
1724                     rd_ready_to_send_atapi(dev, channel);
1725                     break;
1726                 }
1727             case 0x25:  // read cd-rom capacity
1728                 {
1729                     // no allocation length???
1730                     if (rd_init_send_atapi_command(dev, channel, atapi_command, 8, 8, false) == -1) {
1731                         PrintError("Error sending atapi command in read cdrom capacity\n");
1732                         return -1;
1733                     }
1734         
1735                     if (drive->cdrom.ready) {
1736                         uint32_t capacity = drive->cdrom.capacity;
1737
1738                         PrintDebug("\t\tCapacity is %d sectors (%d bytes)\n", capacity, capacity * 2048);
1739
1740                         controller->buffer[0] = (capacity >> 24) & 0xff;
1741                         controller->buffer[1] = (capacity >> 16) & 0xff;
1742                         controller->buffer[2] = (capacity >> 8) & 0xff;
1743                         controller->buffer[3] = (capacity >> 0) & 0xff;
1744                         controller->buffer[4] = (2048 >> 24) & 0xff;
1745                         controller->buffer[5] = (2048 >> 16) & 0xff;
1746                         controller->buffer[6] = (2048 >> 8) & 0xff;
1747                         controller->buffer[7] = (2048 >> 0) & 0xff;
1748
1749                         rd_ready_to_send_atapi(dev, channel);
1750                     } else {
1751                         PrintError("CDROM not ready in read cdrom capacity\n");
1752                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1753                         rd_raise_interrupt(dev, channel);
1754                     }
1755                     break;
1756                 }
1757       
1758       
1759             case 0xbe:  // read cd
1760                 {
1761                     if (drive->cdrom.ready) {
1762                         PrintError("Read CD with CD present not implemented\n");
1763                         rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
1764                         rd_raise_interrupt(dev, channel);
1765                     } else {
1766                         PrintError("Drive not ready in read cd with CD present\n");
1767                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1768                         rd_raise_interrupt(dev, channel);
1769                     }
1770                     break;
1771                 }
1772             case 0x43: // read toc
1773                 { 
1774                     if (drive->cdrom.ready) {
1775                         int toc_length = 0;  
1776                         bool msf = (controller->buffer[1] >> 1) & 1;
1777                         uint8_t starting_track = controller->buffer[6];
1778           
1779                         uint16_t alloc_length = rd_read_16bit(controller->buffer + 7);
1780           
1781                         uint8_t format = (controller->buffer[9] >> 6);
1782                         int i;
1783
1784                         PrintDebug("Reading CDROM TOC: Format=%d (byte count=%d) (toc length:%d)\n", 
1785                                    format, controller->byte_count, toc_length);
1786
1787                         switch (format) {
1788                             case 0:
1789                                 if (!(drive->cdrom.cd->read_toc(drive->private_data, controller->buffer,
1790                                                                 &toc_length, msf, starting_track))) {
1791                                     PrintError("CDROM: Reading Table of Contents Failed\n");
1792                                     rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1793                                                        ASC_INV_FIELD_IN_CMD_PACKET);
1794                                     rd_raise_interrupt(dev, channel);
1795                                     break;
1796                                 }
1797
1798               
1799                                 if (rd_init_send_atapi_command(dev, channel, atapi_command, toc_length, alloc_length, false) == -1) {
1800                                     PrintError("Failed to init send atapi command in read toc (fmt=%d)\n", format);
1801                                     return -1;
1802                                 }
1803
1804                                 rd_ready_to_send_atapi(dev, channel);    
1805
1806                                 break;
1807
1808                             case 1:
1809                                 // multi session stuff. we ignore this and emulate a single session only
1810
1811                                 if (rd_init_send_atapi_command(dev, channel, atapi_command, 12, alloc_length, false) == -1) {
1812                                     PrintError("Failed to init send atapi command in read toc (fmt=%d)\n", format);
1813                                     return -1;
1814                                 }
1815             
1816                                 controller->buffer[0] = 0;
1817                                 controller->buffer[1] = 0x0a;
1818                                 controller->buffer[2] = 1;
1819                                 controller->buffer[3] = 1;
1820
1821                                 for (i = 0; i < 8; i++) {
1822                                     controller->buffer[4 + i] = 0;
1823                                 }
1824
1825                                 rd_ready_to_send_atapi(dev, channel);
1826                                 break;
1827             
1828                             case 2:
1829                             default:
1830                                 PrintError("(READ TOC) Format %d not supported\n", format);
1831                                 return -1;
1832                         }
1833                     } else {
1834                         PrintError("CDROM not ready in read toc\n");
1835                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1836                         rd_raise_interrupt(dev, channel);
1837                     }
1838                     break;
1839                 }
1840             case 0x28: // read (10)
1841             case 0xa8: // read (12)
1842                 { 
1843         
1844                     uint32_t transfer_length;
1845                     if (atapi_command == 0x28) {
1846                         transfer_length = rd_read_16bit(controller->buffer + 7);
1847                     } else {
1848                         transfer_length = rd_read_32bit(controller->buffer + 6);
1849                     }
1850
1851                     uint32_t lba = rd_read_32bit(controller->buffer + 2);
1852         
1853                     if (!(drive->cdrom.ready)) {
1854                         PrintError("CDROM Error: Not Ready (ATA%d/%d)\n", 
1855                                    get_channel_no(ramdisk, channel), get_drive_no(channel, drive));
1856                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1857                         rd_raise_interrupt(dev, channel);
1858                         break;
1859                     }
1860         
1861                     if (transfer_length == 0) {
1862                         PrintError("READ(%d) with transfer length 0, ok\n", 
1863                                    (atapi_command == 0x28) ? 10 : 12);
1864                         rd_atapi_cmd_nop(dev, channel);
1865                         rd_raise_interrupt(dev, channel);
1866                         break;
1867                     }
1868         
1869                     if (lba + transfer_length > drive->cdrom.capacity) {
1870                         PrintError("CDROM Error: Capacity exceeded [capacity=%d] (ATA%d/%d)\n",
1871                                    drive->cdrom.capacity,
1872                                    get_channel_no(ramdisk, channel), get_drive_no(channel, drive));
1873                         rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
1874                         rd_raise_interrupt(dev, channel);
1875                         break;
1876                     }
1877         
1878                     PrintDebug("\t\tcdrom: READ (%d) LBA=%d LEN=%d\n", 
1879                                (atapi_command == 0x28) ? 10 : 12, 
1880                                lba, transfer_length);
1881         
1882                     // handle command
1883                     if (rd_init_send_atapi_command(dev, channel, atapi_command, transfer_length * 2048,
1884                                                    transfer_length * 2048, true) == -1) {
1885                         PrintError("CDROM Error: Atapi command send error\n");
1886                         return -1;
1887                     }
1888
1889                     drive->cdrom.remaining_blocks = transfer_length;
1890                     drive->cdrom.next_lba = lba;
1891                     rd_ready_to_send_atapi(dev, channel);
1892                     break;
1893                 }
1894             case 0x2b:  // seek
1895                 {
1896                     uint32_t lba = rd_read_32bit(controller->buffer + 2);
1897
1898                     if (!(drive->cdrom.ready)) {
1899                         PrintError("CDROM not ready in seek\n");
1900                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1901                         rd_raise_interrupt(dev, channel);
1902                         break;
1903                     }
1904         
1905                     if (lba > drive->cdrom.capacity) {
1906                         PrintError("LBA is greater than CDROM capacity in seek\n");
1907                         rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_LOGICAL_BLOCK_OOR);
1908                         rd_raise_interrupt(dev, channel);
1909                         break;
1910                     }
1911         
1912                     PrintError("\t\tcdrom: SEEK (ignored)\n");
1913
1914                     rd_atapi_cmd_nop(dev, channel);
1915                     rd_raise_interrupt(dev, channel);
1916
1917                     break;
1918                 }
1919             case 0x1e:  // prevent/allow medium removal
1920                 {
1921
1922                     if (drive->cdrom.ready) {
1923                         drive->cdrom.locked = controller->buffer[4] & 1;
1924                         rd_atapi_cmd_nop(dev, channel);
1925                     } else {
1926                         PrintError("CD not ready in prevent/allow medium removal\n");
1927                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1928                     }
1929
1930                     rd_raise_interrupt(dev, channel);
1931
1932                     break;
1933                 }
1934             case 0x42:  // read sub-channel
1935                 {
1936                     //bool msf = get_packet_field(channel,1, 1, 1);
1937                     bool sub_q = get_packet_field(channel,2, 6, 1);
1938                     //uint8_t data_format = get_packet_byte(channel,3);
1939                     //uint8_t track_number = get_packet_byte(channel,6);
1940                     uint16_t alloc_length = get_packet_word(channel,7);
1941         
1942
1943                     /*
1944                       UNUSED(msf);
1945                       UNUSED(data_format);
1946                       UNUSED(track_number);
1947                     */
1948                     if (!(drive->cdrom.ready)) {
1949                         PrintError("CDROM not ready in read sub-channel\n");
1950                         rd_atapi_cmd_error(dev, channel, SENSE_NOT_READY, ASC_MEDIUM_NOT_PRESENT);
1951                         rd_raise_interrupt(dev, channel);
1952                     } else {
1953                         controller->buffer[0] = 0;
1954                         controller->buffer[1] = 0; // audio not supported
1955                         controller->buffer[2] = 0;
1956                         controller->buffer[3] = 0;
1957           
1958                         int ret_len = 4; // header size
1959           
1960                         if (sub_q) { // !sub_q == header only
1961                             PrintError("Read sub-channel with SubQ not implemented\n");
1962                             rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST,
1963                                                ASC_INV_FIELD_IN_CMD_PACKET);
1964                             rd_raise_interrupt(dev, channel);
1965                         }
1966           
1967                         if (rd_init_send_atapi_command(dev, channel, atapi_command, ret_len, alloc_length, false) == -1) {
1968                             PrintError("Error sending atapi command in read sub-channel\n");
1969                             return -1;
1970                         }
1971                         rd_ready_to_send_atapi(dev, channel);
1972                     }
1973                     break;
1974                 }
1975             case 0x51:  // read disc info
1976                 {
1977                     // no-op to keep the Linux CD-ROM driver happy
1978                     PrintError("Error: Read disk info no-op to keep the Linux CD-ROM driver happy\n");
1979                     rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
1980                     rd_raise_interrupt(dev, channel);
1981                     break;
1982                 }
1983             case 0x55: // mode select
1984             case 0xa6: // load/unload cd
1985             case 0x4b: // pause/resume
1986             case 0x45: // play audio
1987             case 0x47: // play audio msf
1988             case 0xbc: // play cd
1989             case 0xb9: // read cd msf
1990             case 0x44: // read header
1991             case 0xba: // scan
1992             case 0xbb: // set cd speed
1993             case 0x4e: // stop play/scan
1994             case 0x46: // ???
1995             case 0x4a: // ???
1996                 PrintError("ATAPI command 0x%x not implemented yet\n",
1997                            atapi_command);
1998                 rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
1999                 rd_raise_interrupt(dev, channel);
2000                 break;
2001             default:
2002                 PrintError("Unknown ATAPI command 0x%x (%d)\n",
2003                            atapi_command, atapi_command);
2004                 // We'd better signal the error if the user chose to continue
2005                 rd_atapi_cmd_error(dev, channel, SENSE_ILLEGAL_REQUEST, ASC_INV_FIELD_IN_CMD_PACKET);
2006                 rd_raise_interrupt(dev, channel);
2007                 break;
2008         }
2009     }
2010        
2011               
2012     return 0;
2013 }
2014
2015
2016
2017
2018 int rd_init_send_atapi_command(struct vm_device * dev, struct channel_t * channel, Bit8u command, int req_length, int alloc_length, bool lazy)
2019 {
2020     struct drive_t * drive = &(channel->drives[channel->drive_select]);
2021     struct controller_t * controller = &(drive->controller);
2022
2023     // controller->byte_count is a union of controller->cylinder_no;
2024     // lazy is used to force a data read in the buffer at the next read.
2025   
2026     PrintDebug("[rd_init_send_atapi_cmd]\n");
2027
2028     if (controller->byte_count == 0xffff) {
2029         controller->byte_count = 0xfffe;
2030     }
2031
2032     if ((controller->byte_count & 1) && 
2033         !(alloc_length <= controller->byte_count)) {
2034       
2035         PrintDebug("\t\tOdd byte count (0x%04x) to ATAPI command 0x%02x, using 0x%x\n", 
2036                    controller->byte_count, 
2037                    command, 
2038                    controller->byte_count - 1);
2039     
2040         controller->byte_count -= 1;
2041     }
2042   
2043     if (controller->byte_count == 0) {
2044         PrintError("\t\tATAPI command with zero byte count\n");
2045         return -1;
2046     }
2047
2048     if (alloc_length < 0) {
2049         PrintError("\t\tAllocation length < 0\n");
2050         return -1;
2051     }
2052
2053     if (alloc_length == 0) {
2054         alloc_length = controller->byte_count;
2055     }
2056   
2057     controller->interrupt_reason.i_o = 1;
2058     controller->interrupt_reason.c_d = 0;
2059     controller->status.busy = 0;
2060     controller->status.drq = 1;
2061     controller->status.err = 0;
2062   
2063     // no bytes transfered yet
2064     if (lazy) {
2065         controller->buffer_index = 2048;
2066     } else {
2067         controller->buffer_index = 0;
2068     }
2069
2070     controller->drq_index = 0;
2071   
2072     if (controller->byte_count > req_length) {
2073         controller->byte_count = req_length;
2074     }
2075
2076     if (controller->byte_count > alloc_length) {
2077         controller->byte_count = alloc_length;
2078     }  
2079
2080     drive->atapi.command = command;
2081     drive->atapi.drq_bytes = controller->byte_count;
2082     drive->atapi.total_bytes_remaining = (req_length < alloc_length) ? req_length : alloc_length;
2083   
2084     // if (lazy) {
2085     // // bias drq_bytes and total_bytes_remaining
2086     // SELECTED_DRIVE(channel).atapi.drq_bytes += 2048;
2087     // SELECTED_DRIVE(channel).atapi.total_bytes_remaining += 2048;
2088     // }
2089
2090     return 0;
2091 }
2092
2093
2094
2095 void rd_ready_to_send_atapi(struct vm_device * dev, struct channel_t * channel) {
2096     PrintDebug("[rd_ready_to_send_atapi]\n");
2097   
2098     rd_raise_interrupt(dev, channel);
2099 }
2100
2101
2102
2103
2104
2105 void rd_atapi_cmd_error(struct vm_device * dev, struct channel_t * channel, sense_t sense_key, asc_t asc)
2106 {
2107     struct drive_t * drive = &(channel->drives[channel->drive_select]);
2108     struct controller_t * controller = &(drive->controller);
2109
2110
2111     struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data);
2112     PrintError("[rd_atapi_cmd_error]\n");
2113     PrintError("Error: atapi_cmd_error channel=%02x key=%02x asc=%02x\n", 
2114                get_channel_no(ramdisk, channel), sense_key, asc);
2115   
2116
2117     controller->error_register = sense_key << 4;
2118     controller->interrupt_reason.i_o = 1;
2119     controller->interrupt_reason.c_d = 1;
2120     controller->interrupt_reason.rel = 0;
2121     controller->status.busy = 0;
2122     controller->status.drive_ready = 1;
2123     controller->status.write_fault = 0;
2124     controller->status.drq = 0;
2125     controller->status.err = 1;
2126   
2127     drive->sense.sense_key = sense_key;
2128     drive->sense.asc = asc;
2129     drive->sense.ascq = 0;
2130 }
2131
2132
2133
2134 void rd_atapi_cmd_nop(struct vm_device * dev, struct channel_t * channel)
2135 {
2136     struct drive_t * drive = &(channel->drives[channel->drive_select]);
2137     struct controller_t * controller = &(drive->controller);
2138
2139     PrintDebug("[rd_atapi_cmd_nop]\n");
2140     controller->interrupt_reason.i_o = 1;
2141     controller->interrupt_reason.c_d = 1;
2142     controller->interrupt_reason.rel = 0;
2143     controller->status.busy = 0;
2144     controller->status.drive_ready = 1;
2145     controller->status.drq = 0;
2146     controller->status.err = 0;
2147 }
2148
2149
2150
2151
2152 void rd_identify_ATAPI_drive(struct vm_device * dev, struct channel_t * channel)
2153 {
2154     struct drive_t * drive = &(channel->drives[channel->drive_select]);
2155     struct controller_t * controller = &(drive->controller);
2156
2157
2158     uint_t i;
2159     const char* serial_number = " VT00001\0\0\0\0\0\0\0\0\0\0\0\0";
2160     const char* firmware = "ALPHA1  ";
2161
2162     drive->id_drive[0] = (2 << 14) | (5 << 8) | (1 << 7) | (2 << 5) | (0 << 0); // Removable CDROM, 50us response, 12 byte packets
2163
2164     for (i = 1; i <= 9; i++) {
2165         drive->id_drive[i] = 0;
2166     }
2167
2168     for (i = 0; i < 10; i++) {
2169         drive->id_drive[10 + i] = ((serial_number[i * 2] << 8) |
2170                                    (serial_number[(i * 2) + 1]));
2171     }
2172
2173     for (i = 20; i <= 22; i++) {
2174         drive->id_drive[i] = 0;
2175     }
2176
2177     for (i = 0; i < strlen(firmware)/2; i++) {
2178         drive->id_drive[23 + i] = ((firmware[i * 2] << 8) |
2179                                    (firmware[(i * 2) + 1]));
2180     }
2181     V3_ASSERT((23 + i) == 27);
2182   
2183     for (i = 0; i < strlen((char *)(drive->model_no)) / 2; i++) {
2184         drive->id_drive[27 + i] = ((drive->model_no[i * 2] << 8) |
2185                                    (drive->model_no[(i * 2) + 1]));
2186     }
2187     V3_ASSERT((27 + i) == 47);
2188
2189     drive->id_drive[47] = 0;
2190     drive->id_drive[48] = 1; // 32 bits access
2191
2192     drive->id_drive[49] = (1 << 9); // LBA supported
2193
2194     drive->id_drive[50] = 0;
2195     drive->id_drive[51] = 0;
2196     drive->id_drive[52] = 0;
2197
2198     drive->id_drive[53] = 3; // words 64-70, 54-58 valid
2199
2200     for (i = 54; i <= 62; i++) {
2201         drive->id_drive[i] = 0;
2202     }
2203
2204     // copied from CFA540A
2205     drive->id_drive[63] = 0x0103; // variable (DMA stuff)
2206     drive->id_drive[64] = 0x0001; // PIO
2207     drive->id_drive[65] = 0x00b4;
2208     drive->id_drive[66] = 0x00b4;
2209     drive->id_drive[67] = 0x012c;
2210     drive->id_drive[68] = 0x00b4;
2211
2212     drive->id_drive[69] = 0;
2213     drive->id_drive[70] = 0;
2214     drive->id_drive[71] = 30; // faked
2215     drive->id_drive[72] = 30; // faked
2216     drive->id_drive[73] = 0;
2217     drive->id_drive[74] = 0;
2218
2219     drive->id_drive[75] = 0;
2220
2221     for (i = 76; i <= 79; i++) {
2222         drive->id_drive[i] = 0;
2223     }
2224
2225     drive->id_drive[80] = 0x1e; // supports up to ATA/ATAPI-4
2226     drive->id_drive[81] = 0;
2227     drive->id_drive[82] = 0;
2228     drive->id_drive[83] = 0;
2229     drive->id_drive[84] = 0;
2230     drive->id_drive[85] = 0;
2231     drive->id_drive[86] = 0;
2232     drive->id_drive[87] = 0;
2233     drive->id_drive[88] = 0;
2234
2235     for (i = 89; i <= 126; i++) {
2236         drive->id_drive[i] = 0;
2237     }
2238
2239     drive->id_drive[127] = 0;
2240     drive->id_drive[128] = 0;
2241
2242     for (i = 129; i <= 159; i++) {
2243         drive->id_drive[i] = 0;
2244     }
2245
2246     for (i = 160; i <= 255; i++) {
2247         drive->id_drive[i] = 0;
2248     }
2249
2250     // now convert the id_drive array (native 256 word format) to
2251     // the controller buffer (512 bytes)
2252     Bit16u temp16;
2253     for (i = 0; i <= 255; i++) {
2254         temp16 = drive->id_drive[i];
2255         controller->buffer[i * 2] = temp16 & 0x00ff;
2256         controller->buffer[i * 2 + 1] = temp16 >> 8;
2257     }
2258
2259     return;
2260 }
2261
2262
2263
2264
2265
2266
2267
2268 static 
2269 void rd_init_mode_sense_single(struct vm_device * dev, 
2270                                struct channel_t * channel, const void* src, int size)
2271 {
2272     struct drive_t * drive = &(channel->drives[channel->drive_select]);
2273     struct controller_t * controller = &(drive->controller);
2274
2275     PrintDebug("[rd_init_mode_sense_single]\n");
2276
2277     // Header
2278     controller->buffer[0] = (size + 6) >> 8;
2279     controller->buffer[1] = (size + 6) & 0xff;
2280     controller->buffer[2] = 0x70; // no media present
2281     controller->buffer[3] = 0; // reserved
2282     controller->buffer[4] = 0; // reserved
2283     controller->buffer[5] = 0; // reserved
2284     controller->buffer[6] = 0; // reserved
2285     controller->buffer[7] = 0; // reserved
2286   
2287     // Data
2288     memcpy(controller->buffer + 8, src, size);
2289 }
2290
2291
2292
2293 static void rd_command_aborted(struct vm_device * dev, 
2294                                struct channel_t * channel, unsigned value) {
2295     struct drive_t * drive = &(channel->drives[channel->drive_select]);
2296     struct controller_t * controller = &(drive->controller);
2297
2298     PrintError("[rd_command_aborted]\n");
2299     PrintError("\t\taborting on command 0x%02x {%s}\n", value, device_type_to_str(drive->device_type));
2300
2301     controller->current_command = 0;
2302     controller->status.busy = 0;
2303     controller->status.drive_ready = 1;
2304     controller->status.err = 1;
2305     controller->error_register = 0x04; // command ABORTED
2306     controller->status.drq = 0;
2307     controller->status.seek_complete = 0;
2308     controller->status.corrected_data = 0;
2309     controller->buffer_index = 0;
2310
2311     rd_raise_interrupt(dev, channel);
2312 }
2313
2314
2315 static int ramdisk_init_device(struct vm_device *dev) {
2316     struct ramdisk_t *ramdisk= (struct ramdisk_t *)dev->private_data;
2317
2318     PrintDebug("Initializing Ramdisk\n");
2319
2320
2321     rd_init_hardware(ramdisk);
2322
2323
2324     v3_dev_hook_io(dev, PRI_CTRL_PORT, 
2325                    &read_status_port, &write_ctrl_port);
2326
2327     v3_dev_hook_io(dev, PRI_DATA_PORT, 
2328                    &read_data_port, &write_data_port);
2329     v3_dev_hook_io(dev, PRI_FEATURES_PORT, 
2330                    &read_general_port, &write_general_port);
2331     v3_dev_hook_io(dev, PRI_SECT_CNT_PORT, 
2332                    &read_general_port, &write_general_port);
2333     v3_dev_hook_io(dev, PRI_SECT_ADDR1_PORT, 
2334                    &read_general_port, &write_general_port);
2335     v3_dev_hook_io(dev, PRI_SECT_ADDR2_PORT, 
2336                    &read_general_port, &write_general_port);
2337     v3_dev_hook_io(dev, PRI_SECT_ADDR3_PORT, 
2338                    &read_general_port, &write_general_port);
2339     v3_dev_hook_io(dev, PRI_DRV_SEL_PORT, 
2340                    &read_general_port, &write_general_port);
2341     v3_dev_hook_io(dev, PRI_CMD_PORT, 
2342                    &read_status_port, &write_cmd_port);
2343
2344
2345     v3_dev_hook_io(dev, SEC_CTRL_PORT, 
2346                    &read_status_port, &write_ctrl_port);
2347
2348     v3_dev_hook_io(dev, SEC_DATA_PORT, 
2349                    &read_data_port, &write_data_port);
2350     v3_dev_hook_io(dev, SEC_FEATURES_PORT, 
2351                    &read_general_port, &write_general_port);
2352     v3_dev_hook_io(dev, SEC_SECT_CNT_PORT, 
2353                    &read_general_port, &write_general_port);
2354     v3_dev_hook_io(dev, SEC_SECT_ADDR1_PORT, 
2355                    &read_general_port, &write_general_port);
2356     v3_dev_hook_io(dev, SEC_SECT_ADDR2_PORT, 
2357                    &read_general_port, &write_general_port);
2358     v3_dev_hook_io(dev, SEC_SECT_ADDR3_PORT, 
2359                    &read_general_port, &write_general_port);
2360     v3_dev_hook_io(dev, SEC_DRV_SEL_PORT, 
2361                    &read_general_port, &write_general_port);
2362     v3_dev_hook_io(dev, SEC_CMD_PORT, 
2363                    &read_status_port, &write_cmd_port);
2364   
2365   
2366
2367     v3_dev_hook_io(dev, SEC_ADDR_REG_PORT, 
2368                    &read_general_port, &write_general_port);
2369
2370     v3_dev_hook_io(dev, PRI_ADDR_REG_PORT, 
2371                    &read_general_port, &write_general_port);
2372
2373
2374
2375     return 0;
2376
2377 }
2378
2379
2380 static int ramdisk_deinit_device(struct vm_device *dev) {
2381     struct ramdisk_t *ramdisk = (struct ramdisk_t *)(dev->private_data);
2382     rd_close_harddrive(ramdisk);
2383     return 0;
2384 }
2385
2386 static struct vm_device_ops dev_ops = {
2387     .init = ramdisk_init_device,
2388     .deinit = ramdisk_deinit_device,
2389     .reset = NULL,
2390     .start = NULL,
2391     .stop = NULL,
2392 };
2393
2394
2395
2396
2397 struct vm_device * v3_create_ramdisk()
2398 {
2399
2400     struct ramdisk_t *ramdisk;
2401     ramdisk = (struct ramdisk_t *)V3_Malloc(sizeof(struct ramdisk_t));  
2402     V3_ASSERT(ramdisk != NULL);  
2403
2404     PrintDebug("[create_ramdisk]\n");
2405
2406     struct vm_device * device = v3_create_device("RAMDISK", &dev_ops, ramdisk);
2407
2408     return device;
2409 }
2410
2411
2412
2413
2414 #ifdef DEBUG_RAMDISK
2415
2416 static void rd_print_state(struct ramdisk_t * ramdisk) {
2417     uchar_t channel; 
2418     uchar_t device;
2419     struct channel_t * channels = (struct channel_t *)(&(ramdisk->channels));
2420
2421     /*
2422       for (channel = 0; channel < MAX_ATA_CHANNEL; channel++) {
2423       memset((char *)(channels + channel), 0, sizeof(struct channel_t));
2424       }
2425     */
2426     PrintDebug("sizeof(*channels) = %d\n", sizeof(*channels));
2427     PrintDebug("sizeof(channles->drives[0].controller) = %d\n", sizeof((channels->drives[0].controller)));
2428     PrintDebug("sizeof(channles->drives[0].cdrom) = %d\n", sizeof((channels->drives[0].cdrom)));
2429     PrintDebug("sizeof(channles->drives[0].sense) = %d\n", sizeof((channels->drives[0].sense)));
2430     PrintDebug("sizeof(channles->drives[0].atapi) = %d\n", sizeof((channels->drives[0].atapi)));
2431
2432
2433     PrintDebug("sizeof(channles->drives[0].controller.status) = %d\n", 
2434                sizeof((channels->drives[0].controller.status)));
2435     PrintDebug("sizeof(channles->drives[0].controller.sector_count) = %d\n", 
2436                sizeof((channels->drives[0].controller.sector_count)));
2437     PrintDebug("sizeof(channles->drives[0].controller.interrupt_reason) = %d\n", 
2438                sizeof((channels->drives[0].controller.interrupt_reason)));
2439
2440     PrintDebug("sizeof(channles->drives[0].controller.cylinder_no) = %d\n", 
2441                sizeof((channels->drives[0].controller.cylinder_no)));
2442     PrintDebug("sizeof(channles->drives[0].controller.byte_count) = %d\n", 
2443                sizeof((channels->drives[0].controller.byte_count)));
2444
2445
2446     PrintDebug("sizeof(channles->drives[0].controller.control) = %d\n", 
2447                sizeof((channels->drives[0].controller.control)));
2448
2449
2450     for (channel = 0; channel < MAX_ATA_CHANNEL; channel++){
2451   
2452         for (device = 0; device < 2; device++){
2453                   
2454             // Initialize controller state, even if device is not present
2455             PrintDebug("channels[%d].drives[%d].controller.status.busy = %d\n",
2456                        channel, device, 
2457                        channels[channel].drives[device].controller.status.busy);
2458             PrintDebug("channels[%d].drives[%d].controller.status.drive_ready = %d\n", 
2459                        channel, device, 
2460                        channels[channel].drives[device].controller.status.drive_ready);
2461             PrintDebug("channels[%d].drives[%d].controller.status.write_fault = %d\n", 
2462                        channel, device, 
2463                        channels[channel].drives[device].controller.status.write_fault);
2464             PrintDebug("channels[%d].drives[%d].controller.status.seek_complete = %d\n", 
2465                        channel, device, 
2466                        channels[channel].drives[device].controller.status.seek_complete);
2467             PrintDebug("channels[%d].drives[%d].controller.status.drq = %d\n", 
2468                        channel, device, 
2469                        channels[channel].drives[device].controller.status.drq);
2470             PrintDebug("channels[%d].drives[%d].controller.status.corrected_data = %d\n", 
2471                        channel, device, 
2472                        channels[channel].drives[device].controller.status.corrected_data);
2473             PrintDebug("channels[%d].drives[%d].controller.status.index_pulse = %d\n", 
2474                        channel, device, 
2475                        channels[channel].drives[device].controller.status.index_pulse);
2476             PrintDebug("channels[%d].drives[%d].controller.status.index_pulse_count = %d\n", 
2477                        channel, device, 
2478                        channels[channel].drives[device].controller.status.index_pulse_count);
2479             PrintDebug("channels[%d].drives[%d].controller.status.err = %d\n", 
2480                        channel, device, 
2481                        channels[channel].drives[device].controller.status.err);
2482
2483
2484             PrintDebug("channels[%d].drives[%d].controller.error_register = %d\n", 
2485                        channel, device, 
2486                        channels[channel].drives[device].controller.error_register);
2487             PrintDebug("channels[%d].drives[%d].controller.head_no = %d\n", 
2488                        channel, device, 
2489                        channels[channel].drives[device].controller.head_no);
2490             PrintDebug("channels[%d].drives[%d].controller.sector_count = %d\n", 
2491                        channel, device, 
2492                        channels[channel].drives[device].controller.sector_count);
2493             PrintDebug("channels[%d].drives[%d].controller.sector_no = %d\n", 
2494                        channel, device, 
2495                        channels[channel].drives[device].controller.sector_no);
2496             PrintDebug("channels[%d].drives[%d].controller.cylinder_no = %d\n", 
2497                        channel, device, 
2498                        channels[channel].drives[device].controller.cylinder_no);
2499             PrintDebug("channels[%d].drives[%d].controller.current_command = %02x\n", 
2500                        channel, device, 
2501                        channels[channel].drives[device].controller.current_command);
2502             PrintDebug("channels[%d].drives[%d].controller.buffer_index = %d\n", 
2503                        channel, device, 
2504                        channels[channel].drives[device].controller.buffer_index);
2505
2506
2507             PrintDebug("channels[%d].drives[%d].controller.control.reset = %d\n", 
2508                        channel, device, 
2509                        channels[channel].drives[device].controller.control.reset);
2510             PrintDebug("channels[%d].drives[%d].controller.control.disable_irq = %d\n", 
2511                        channel, device, 
2512                        channels[channel].drives[device].controller.control.disable_irq);
2513
2514
2515             PrintDebug("channels[%d].drives[%d].controller.reset_in_progress = %d\n", 
2516                        channel, device, 
2517                        channels[channel].drives[device].controller.reset_in_progress);
2518             PrintDebug("channels[%d].drives[%d].controller.sectors_per_block = %02x\n", 
2519                        channel, device, 
2520                        channels[channel].drives[device].controller.sectors_per_block); 
2521             PrintDebug("channels[%d].drives[%d].controller.lba_mode = %d\n", 
2522                        channel, device, 
2523                        channels[channel].drives[device].controller.lba_mode); 
2524             PrintDebug("channels[%d].drives[%d].controller.features = %d\n", 
2525                        channel, device, 
2526                        channels[channel].drives[device].controller.features); 
2527
2528
2529             PrintDebug("channels[%d].drives[%d].model_no = %s\n", 
2530                        channel, device, 
2531                        channels[channel].drives[device].model_no); 
2532             PrintDebug("channels[%d].drives[%d].device_type = %d\n", 
2533                        channel, device, 
2534                        channels[channel].drives[device].device_type); 
2535             PrintDebug("channels[%d].drives[%d].cdrom.locked = %d\n", 
2536                        channel, device, 
2537                        channels[channel].drives[device].cdrom.locked); 
2538             PrintDebug("channels[%d].drives[%d].sense.sense_key = %d\n", 
2539                        channel, device, 
2540                        channels[channel].drives[device].sense.sense_key); 
2541             PrintDebug("channels[%d].drives[%d].sense.asc = %d\n", 
2542                        channel, device, 
2543                        channels[channel].drives[device].sense.asc); 
2544             PrintDebug("channels[%d].drives[%d].sense.ascq = %d\n", 
2545                        channel, device, 
2546                        channels[channel].drives[device].sense.ascq); 
2547
2548
2549
2550             PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.c_d = %02x\n", 
2551                        channel, device, 
2552                        channels[channel].drives[device].controller.interrupt_reason.c_d);
2553
2554             PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.i_o = %02x\n", 
2555                        channel, device, 
2556                        channels[channel].drives[device].controller.interrupt_reason.i_o);
2557
2558             PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.rel = %02x\n", 
2559                        channel, device, 
2560                        channels[channel].drives[device].controller.interrupt_reason.rel);
2561
2562             PrintDebug("channels[%d].drives[%d].controller.interrupt_reason.tag = %02x\n", 
2563                        channel, device, 
2564                        channels[channel].drives[device].controller.interrupt_reason.tag);
2565
2566             PrintDebug("channels[%d].drives[%d].cdrom.ready = %d\n", 
2567                        channel, device, 
2568                        channels[channel].drives[device].cdrom.ready);
2569       
2570         }  //for device
2571     }  //for channel
2572   
2573     return;
2574 }
2575
2576
2577
2578
2579 static int check_bit_fields(struct controller_t * controller) {
2580     //Check bit fields
2581     controller->sector_count = 0;
2582     controller->interrupt_reason.c_d = 1;
2583     if (controller->sector_count != 0x01) {
2584         return INTR_REASON_BIT_ERR;
2585     }
2586   
2587     controller->sector_count = 0;
2588     controller->interrupt_reason.i_o = 1;
2589     if (controller->sector_count != 0x02) {
2590         return INTR_REASON_BIT_ERR;
2591     }
2592   
2593     controller->sector_count = 0;
2594     controller->interrupt_reason.rel = 1;
2595     if (controller->sector_count != 0x04) {
2596         return INTR_REASON_BIT_ERR;
2597     }
2598   
2599     controller->sector_count = 0;
2600     controller->interrupt_reason.tag = 3;
2601     if (controller->sector_count != 0x18) {
2602         return INTR_REASON_BIT_ERR;
2603     }
2604   
2605     return 0;
2606 }
2607
2608 #endif