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)