BlueSCSI_mode.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159
  1. /**
  2. * Copyright (C) 2013 Michael McMaster <michael@codesrc.com>
  3. * Copyright (C) 2014 Doug Brown <doug@downtowndougbrown.com>
  4. * Copyright (C) 2019 Landon Rodgers <g.landon.rodgers@gmail.com>
  5. * ZuluSCSI™ - Copyright (c) 2023 Rabbit Hole Computing™
  6. *
  7. * ZuluSCSI™ firmware is licensed under the GPL version 3 or any later version. 
  8. *
  9. * https://www.gnu.org/licenses/gpl-3.0.html
  10. * ----
  11. * This program is free software: you can redistribute it and/or modify
  12. * it under the terms of the GNU General Public License as published by
  13. * the Free Software Foundation, either version 3 of the License, or
  14. * (at your option) any later version. 
  15. *
  16. * This program 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
  19. * GNU General Public License for more details. 
  20. *
  21. * You should have received a copy of the GNU General Public License
  22. * along with this program.  If not, see <https://www.gnu.org/licenses/>.
  23. **/
  24. #include <stdint.h>
  25. #include <string.h>
  26. #ifdef ENABLE_AUDIO_OUTPUT
  27. #include "BlueSCSI_audio.h"
  28. #endif
  29. #include "BlueSCSI_cdrom.h"
  30. #include "BlueSCSI_log.h"
  31. extern "C" {
  32. #include "BlueSCSI_mode.h"
  33. }
  34. static const uint8_t CDROMCDParametersPage[] =
  35. {
  36. 0x0D, // page code
  37. 0x06, // page length
  38. 0x00, // reserved
  39. 0x0D, // reserved, inactivity time 8 min
  40. 0x00, 0x3C, // 60 seconds per MSF M unit
  41. 0x00, 0x4B // 75 frames per MSF S unit
  42. };
  43. #ifdef ENABLE_AUDIO_OUTPUT
  44. static const uint8_t CDROMAudioControlParametersPage[] =
  45. {
  46. 0x0E, // page code
  47. 0x0E, // page length
  48. 0x04, // 'Immed' bit set, 'SOTC' bit not set
  49. 0x00, // reserved
  50. 0x00, // reserved
  51. 0x80, // 1 LBAs/sec multip
  52. 0x00, 0x4B, // 75 LBAs/sec
  53. 0x01, 0xFF, // output port 0 active, max volume
  54. 0x02, 0xFF, // output port 1 active, max volume
  55. 0x00, 0x00, // output port 2 inactive
  56. 0x00, 0x00 // output port 3 inactive
  57. };
  58. #endif
  59. static void pageIn(int pc, int dataIdx, const uint8_t* pageData, int pageLen)
  60. {
  61. memcpy(&scsiDev.data[dataIdx], pageData, pageLen);
  62. if (pc == 0x01) // Mask out (un)changable values
  63. {
  64. memset(&scsiDev.data[dataIdx+2], 0, pageLen - 2);
  65. }
  66. }
  67. extern "C"
  68. int modeSenseCDDevicePage(int pc, int idx, int pageCode, int* pageFound)
  69. {
  70. if ((scsiDev.target->cfg->deviceType == S2S_CFG_OPTICAL)
  71. && (pageCode == 0x0D || pageCode == 0x3F))
  72. {
  73. *pageFound = 1;
  74. pageIn(
  75. pc,
  76. idx,
  77. CDROMCDParametersPage,
  78. sizeof(CDROMCDParametersPage));
  79. return sizeof(CDROMCDParametersPage);
  80. }
  81. else
  82. {
  83. return 0;
  84. }
  85. }
  86. extern "C"
  87. int modeSenseCDAudioControlPage(int pc, int idx, int pageCode, int* pageFound)
  88. {
  89. #ifdef ENABLE_AUDIO_OUTPUT
  90. if ((scsiDev.target->cfg->deviceType == S2S_CFG_OPTICAL)
  91. && (pageCode == 0x0E || pageCode == 0x3F))
  92. {
  93. *pageFound = 1;
  94. pageIn(
  95. pc,
  96. idx,
  97. CDROMAudioControlParametersPage,
  98. sizeof(CDROMAudioControlParametersPage));
  99. if (pc == 0x00)
  100. {
  101. // report current volume level
  102. uint16_t vol = audio_get_volume(scsiDev.target->targetId);
  103. scsiDev.data[idx+9] = vol & 0xFF;
  104. scsiDev.data[idx+11] = vol >> 8;
  105. }
  106. else if (pc == 0x01)
  107. {
  108. // report bits that can be set
  109. scsiDev.data[idx+9] = 0xFF;
  110. scsiDev.data[idx+11] = 0xFF;
  111. }
  112. else
  113. {
  114. // report defaults for 0x02
  115. // also report same for 0x03, though we are actually supposed
  116. // to terminate with CHECK CONDITION and SAVING PARAMETERS NOT SUPPORTED
  117. scsiDev.data[idx+9] = DEFAULT_VOLUME_LEVEL & 0xFF;
  118. scsiDev.data[idx+11] = DEFAULT_VOLUME_LEVEL >> 8;
  119. }
  120. return sizeof(CDROMAudioControlParametersPage);
  121. }
  122. else
  123. {
  124. return 0;
  125. }
  126. #else
  127. return 0;
  128. #endif
  129. }
  130. extern "C"
  131. int modeSelectCDAudioControlPage(int pageLen, int idx)
  132. {
  133. #ifdef ENABLE_AUDIO_OUTPUT
  134. if (scsiDev.target->cfg->deviceType == S2S_CFG_OPTICAL)
  135. {
  136. if (pageLen != 0x0E) return 0;
  137. uint16_t vol = (scsiDev.data[idx+11] << 8) + scsiDev.data[idx+9];
  138. debuglog("------ CD audio control page volume (", vol, ")");
  139. audio_set_volume(scsiDev.target->targetId, vol);
  140. return 1;
  141. }
  142. else
  143. {
  144. return 0;
  145. }
  146. #else
  147. return 0;
  148. #endif
  149. }