cdrom.c 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. /*
  2. * QEMU ATAPI CD-ROM Emulator
  3. *
  4. * Copyright (c) 2006 Fabrice Bellard
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. /* ??? Most of the ATAPI emulation is still in ide.c. It should be moved
  25. here. */
  26. #include "qemu-common.h"
  27. #include "scsi-disk.h"
  28. static void lba_to_msf(uint8_t *buf, int lba)
  29. {
  30. lba += 150;
  31. buf[0] = (lba / 75) / 60;
  32. buf[1] = (lba / 75) % 60;
  33. buf[2] = lba % 75;
  34. }
  35. /* same toc as bochs. Return -1 if error or the toc length */
  36. /* XXX: check this */
  37. int cdrom_read_toc(int nb_sectors, uint8_t *buf, int msf, int start_track)
  38. {
  39. uint8_t *q;
  40. int len;
  41. if (start_track > 1 && start_track != 0xaa)
  42. return -1;
  43. q = buf + 2;
  44. *q++ = 1; /* first session */
  45. *q++ = 1; /* last session */
  46. if (start_track <= 1) {
  47. *q++ = 0; /* reserved */
  48. *q++ = 0x14; /* ADR, control */
  49. *q++ = 1; /* track number */
  50. *q++ = 0; /* reserved */
  51. if (msf) {
  52. *q++ = 0; /* reserved */
  53. lba_to_msf(q, 0);
  54. q += 3;
  55. } else {
  56. /* sector 0 */
  57. cpu_to_be32wu((uint32_t *)q, 0);
  58. q += 4;
  59. }
  60. }
  61. /* lead out track */
  62. *q++ = 0; /* reserved */
  63. *q++ = 0x16; /* ADR, control */
  64. *q++ = 0xaa; /* track number */
  65. *q++ = 0; /* reserved */
  66. if (msf) {
  67. *q++ = 0; /* reserved */
  68. lba_to_msf(q, nb_sectors);
  69. q += 3;
  70. } else {
  71. cpu_to_be32wu((uint32_t *)q, nb_sectors);
  72. q += 4;
  73. }
  74. len = q - buf;
  75. cpu_to_be16wu((uint16_t *)buf, len - 2);
  76. return len;
  77. }
  78. /* mostly same info as PearPc */
  79. int cdrom_read_toc_raw(int nb_sectors, uint8_t *buf, int msf, int session_num)
  80. {
  81. uint8_t *q;
  82. int len;
  83. q = buf + 2;
  84. *q++ = 1; /* first session */
  85. *q++ = 1; /* last session */
  86. *q++ = 1; /* session number */
  87. *q++ = 0x14; /* data track */
  88. *q++ = 0; /* track number */
  89. *q++ = 0xa0; /* lead-in */
  90. *q++ = 0; /* min */
  91. *q++ = 0; /* sec */
  92. *q++ = 0; /* frame */
  93. *q++ = 0;
  94. *q++ = 1; /* first track */
  95. *q++ = 0x00; /* disk type */
  96. *q++ = 0x00;
  97. *q++ = 1; /* session number */
  98. *q++ = 0x14; /* data track */
  99. *q++ = 0; /* track number */
  100. *q++ = 0xa1;
  101. *q++ = 0; /* min */
  102. *q++ = 0; /* sec */
  103. *q++ = 0; /* frame */
  104. *q++ = 0;
  105. *q++ = 1; /* last track */
  106. *q++ = 0x00;
  107. *q++ = 0x00;
  108. *q++ = 1; /* session number */
  109. *q++ = 0x14; /* data track */
  110. *q++ = 0; /* track number */
  111. *q++ = 0xa2; /* lead-out */
  112. *q++ = 0; /* min */
  113. *q++ = 0; /* sec */
  114. *q++ = 0; /* frame */
  115. if (msf) {
  116. *q++ = 0; /* reserved */
  117. lba_to_msf(q, nb_sectors);
  118. q += 3;
  119. } else {
  120. cpu_to_be32wu((uint32_t *)q, nb_sectors);
  121. q += 4;
  122. }
  123. *q++ = 1; /* session number */
  124. *q++ = 0x14; /* ADR, control */
  125. *q++ = 0; /* track number */
  126. *q++ = 1; /* point */
  127. *q++ = 0; /* min */
  128. *q++ = 0; /* sec */
  129. *q++ = 0; /* frame */
  130. if (msf) {
  131. *q++ = 0;
  132. lba_to_msf(q, 0);
  133. q += 3;
  134. } else {
  135. *q++ = 0;
  136. *q++ = 0;
  137. *q++ = 0;
  138. *q++ = 0;
  139. }
  140. len = q - buf;
  141. cpu_to_be16wu((uint16_t *)buf, len - 2);
  142. return len;
  143. }