PCem
changeset 95:da4d97ca11cf
Return sane values for absolute & relative addresses in CD-ROM Get Subchannel command. Fixes display in Windows 9x CD player.
| author | TomW |
|---|---|
| date | Tue Apr 08 20:45:09 2014 +0100 |
| parents | a956082bfaf9 |
| children | 30de9361da9a |
| files | src/cdrom-ioctl.c |
| diffstat | 1 files changed, 83 insertions(+), 38 deletions(-) [+] |
line diff
1.1 --- a/src/cdrom-ioctl.c Sat Mar 29 17:35:50 2014 +0000 1.2 +++ b/src/cdrom-ioctl.c Tue Apr 08 20:45:09 2014 +0100 1.3 @@ -97,6 +97,26 @@ 1.4 ioctl_cd_state = CD_STOPPED; 1.5 } 1.6 1.7 +static int get_track_nr(uint32_t pos) 1.8 +{ 1.9 + int c; 1.10 + int track = 0; 1.11 + 1.12 + if (!tocvalid) 1.13 + return 0; 1.14 + 1.15 + for (c = toc.FirstTrack; c < toc.LastTrack; c++) 1.16 + { 1.17 + uint32_t track_address = toc.TrackData[c].Address[3] + 1.18 + (toc.TrackData[c].Address[2] * 75) + 1.19 + (toc.TrackData[c].Address[1] * 75 * 60); 1.20 + 1.21 + if (track_address <= pos) 1.22 + track = c; 1.23 + } 1.24 + return track; 1.25 +} 1.26 + 1.27 static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf) 1.28 { 1.29 if (!cdrom_drive) return; 1.30 @@ -225,59 +245,84 @@ 1.31 SUB_Q_CHANNEL_DATA sub; 1.32 long size; 1.33 int pos=0; 1.34 - uint32_t cdpos; 1.35 if (!cdrom_drive) return 0; 1.36 + 1.37 insub.Format = IOCTL_CDROM_CURRENT_POSITION; 1.38 ioctl_open(0); 1.39 DeviceIoControl(hIOCTL,IOCTL_CDROM_READ_Q_CHANNEL,&insub,sizeof(insub),&sub,sizeof(sub),&size,NULL); 1.40 ioctl_close(); 1.41 + 1.42 + if (ioctl_cd_state == CD_PLAYING || ioctl_cd_state == CD_PAUSED) 1.43 + { 1.44 + uint32_t cdpos = ioctl_cd_pos; 1.45 + int track = get_track_nr(cdpos); 1.46 + uint32_t track_address = toc.TrackData[track].Address[3] + 1.47 + (toc.TrackData[track].Address[2] * 75) + 1.48 + (toc.TrackData[track].Address[1] * 75 * 60); 1.49 + 1.50 + b[pos++] = sub.CurrentPosition.Control; 1.51 + b[pos++] = track + 1; 1.52 + b[pos++] = sub.CurrentPosition.IndexNumber; 1.53 + 1.54 + if (msf) 1.55 + { 1.56 + uint32_t dat = cdpos; 1.57 + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; 1.58 + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; 1.59 + b[pos + 1] = (uint8_t)dat; 1.60 + b[pos] = 0; 1.61 + pos += 4; 1.62 + dat = cdpos - track_address; 1.63 + b[pos + 3] = (uint8_t)(dat % 75); dat /= 75; 1.64 + b[pos + 2] = (uint8_t)(dat % 60); dat /= 60; 1.65 + b[pos + 1] = (uint8_t)dat; 1.66 + b[pos] = 0; 1.67 + pos += 4; 1.68 + } 1.69 + else 1.70 + { 1.71 + b[pos++] = (cdpos >> 24) & 0xff; 1.72 + b[pos++] = (cdpos >> 16) & 0xff; 1.73 + b[pos++] = (cdpos >> 8) & 0xff; 1.74 + b[pos++] = cdpos & 0xff; 1.75 + cdpos -= track_address; 1.76 + b[pos++] = (cdpos >> 24) & 0xff; 1.77 + b[pos++] = (cdpos >> 16) & 0xff; 1.78 + b[pos++] = (cdpos >> 8) & 0xff; 1.79 + b[pos++] = cdpos & 0xff; 1.80 + } 1.81 + 1.82 + if (ioctl_cd_state == CD_PLAYING) return 0x11; 1.83 + return 0x12; 1.84 + } 1.85 + 1.86 b[pos++]=sub.CurrentPosition.Control; 1.87 b[pos++]=sub.CurrentPosition.TrackNumber; 1.88 b[pos++]=sub.CurrentPosition.IndexNumber; 1.89 -/* pclog("Read subchannel %02X %02X %02X %02X%02X%02X%02X %02X%02X%02X%02X\n",sub.CurrentPosition.Control,sub.CurrentPosition.TrackNumber,sub.CurrentPosition.IndexNumber, 1.90 - sub.CurrentPosition.AbsoluteAddress[0],sub.CurrentPosition.AbsoluteAddress[1],sub.CurrentPosition.AbsoluteAddress[2],sub.CurrentPosition.AbsoluteAddress[3], 1.91 - sub.CurrentPosition.TrackRelativeAddress[0],sub.CurrentPosition.TrackRelativeAddress[1],sub.CurrentPosition.TrackRelativeAddress[2],sub.CurrentPosition.TrackRelativeAddress[3]);*/ 1.92 - cdpos = ioctl_cd_pos; 1.93 + 1.94 if (msf) 1.95 { 1.96 - b[pos++] = (uint8_t)(cdpos % 75); cdpos /= 75; 1.97 - b[pos++] = (uint8_t)(cdpos % 60); cdpos /= 60; 1.98 - b[pos++] = (uint8_t)cdpos; 1.99 - b[pos++] = 0; 1.100 - b[pos++] = (uint8_t)(cdpos % 75); cdpos /= 75; 1.101 - b[pos++] = (uint8_t)(cdpos % 60); cdpos /= 60; 1.102 - b[pos++] = (uint8_t)cdpos; 1.103 - b[pos++] = 0; 1.104 - 1.105 - 1.106 -// for (c=0;c<4;c++) b[pos++]=sub.CurrentPosition.AbsoluteAddress[c]; 1.107 -// for (c=0;c<4;c++) b[pos++]=sub.CurrentPosition.TrackRelativeAddress[c]; 1.108 + int c; 1.109 + for (c = 0; c < 4; c++) 1.110 + b[pos++] = sub.CurrentPosition.AbsoluteAddress[c]; 1.111 + for (c = 0; c < 4; c++) 1.112 + b[pos++] = sub.CurrentPosition.TrackRelativeAddress[c]; 1.113 } 1.114 else 1.115 { 1.116 - b[pos++] = cdpos & 0xff; 1.117 - b[pos++] = (cdpos >> 8) & 0xff; 1.118 - b[pos++] = (cdpos >> 16) & 0xff; 1.119 - b[pos++] = (cdpos >> 24) & 0xff; 1.120 - b[pos++] = cdpos & 0xff; 1.121 - b[pos++] = (cdpos >> 8) & 0xff; 1.122 - b[pos++] = (cdpos >> 16) & 0xff; 1.123 - b[pos++] = (cdpos >> 24) & 0xff; 1.124 -/* temp=MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1],sub.CurrentPosition.AbsoluteAddress[2],sub.CurrentPosition.AbsoluteAddress[3]); 1.125 - b[pos++]=temp>>24; 1.126 - b[pos++]=temp>>16; 1.127 - b[pos++]=temp>>8; 1.128 - b[pos++]=temp; 1.129 - temp=MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1],sub.CurrentPosition.TrackRelativeAddress[2],sub.CurrentPosition.TrackRelativeAddress[3]); 1.130 - b[pos++]=temp>>24; 1.131 - b[pos++]=temp>>16; 1.132 - b[pos++]=temp>>8; 1.133 - b[pos++]=temp;*/ 1.134 + uint32_t temp = MSFtoLBA(sub.CurrentPosition.AbsoluteAddress[1], sub.CurrentPosition.AbsoluteAddress[2], sub.CurrentPosition.AbsoluteAddress[3]); 1.135 + b[pos++] = temp >> 24; 1.136 + b[pos++] = temp >> 16; 1.137 + b[pos++] = temp >> 8; 1.138 + b[pos++] = temp; 1.139 + temp = MSFtoLBA(sub.CurrentPosition.TrackRelativeAddress[1], sub.CurrentPosition.TrackRelativeAddress[2], sub.CurrentPosition.TrackRelativeAddress[3]); 1.140 + b[pos++] = temp >> 24; 1.141 + b[pos++] = temp >> 16; 1.142 + b[pos++] = temp >> 8; 1.143 + b[pos++] = temp; 1.144 } 1.145 - if (ioctl_cd_state == CD_PLAYING) return 0x11; 1.146 - if (ioctl_cd_state == CD_PAUSED) return 0x12; 1.147 + 1.148 return 0x13; 1.149 -// return sub.CurrentPosition.Header.AudioStatus; 1.150 } 1.151 1.152 static void ioctl_eject(void)
