cd.c

// imWare
// Wednesday, February 14, 1990
// James Beninghaus
 
#include    <ToolUtils.h>
#include    <Memory.h>
#include    <Errors.h>
#include    <cd.h>
 
pascal  Byte Decimal2BCD(Byte n) {
    return ((n / 10) << 4) + (n % 10); 
}
 
pascal  Byte BCD2Decimal(Byte n) {
    return ((n >> 4) * 10) + (n & 0x0f);
}
 
pascal  OSErr OpenCD(Byte CDDrive, short *ioRefNum) {
 
    auto    OSErr           osErr;
    auto    short           ioRefNumTemp,
                            CDDriveCount,
                            SCSIID;
    static  WhoIsThereRec   *pb;
 
    pb = (WhoIsThereRec *) NewPtrClear(sizeof (*pb));
    osErr = MemError();
    if (0 != pb && noErr == osErr) {
        osErr = OpenDriver("\p.AppleCD", &ioRefNumTemp);
        if (noErr == osErr) {
            (*pb).ioRefNum      = ioRefNumTemp;
            (*pb).csCode        = csWhoIsThere;
            osErr = PBStatus((ParmBlkPtr)pb, false);
            if (noErr == osErr) {
                CDDriveCount = 0;
                for (SCSIID = 0; SCSIID < 7; ++SCSIID) {
                    if (BitTst(&(*pb).csParam.SCSIMask, 7 - SCSIID)) {
                        ++CDDriveCount;
                        if (CDDrive == CDDriveCount) {
                            *ioRefNum = -(32 + SCSIID) - 1;
                            DisposPtr((Ptr) pb);
                            return noErr;
                        }
                    }
                }
                osErr = paramErr;
            }
        }
        DisposPtr((Ptr) pb);
    }
    return osErr;
}
 
pascal  OSErr EjectCD(short ioRefNum) {
 
    auto    OSErr           osErr;
    auto    Str255          ioName;
    static  HVolumeParam    *pb;
    
    pb = (HVolumeParam *) NewPtrClear(sizeof (*pb));
    osErr = MemError();
    if (0 != pb && noErr == osErr) {
        (*pb).ioNamePtr = ioName;
        (*pb).ioVolIndex = 0;
        do {
            ++(*pb).ioVolIndex;
            osErr = PBHGetVInfo((HParmBlkPtr)pb, false);
            if (noErr != osErr) {
                DisposPtr((Ptr) pb);
                return osErr;
            }
        } while ((*pb).ioVDRefNum != ioRefNum);
        osErr = PBEject((ParmBlkPtr)pb);
        if (noErr == osErr)
             osErr = PBUnmountVol((ParmBlkPtr)pb);
        DisposPtr((Ptr) pb);
    }
    return osErr;
}
 
pascal  OSErr APlay(short ioRefNum, Byte startTrack, Byte playMode) {
 
    auto    OSErr           osErr;
    static  APlayRec        *pb;    
 
    pb = (APlayRec *) NewPtrClear(sizeof (*pb));
    osErr = MemError();
    if (0 != pb && noErr == osErr) {
        (*pb).ioRefNum          = ioRefNum;
        (*pb).csCode            = csAPlay;
        (*pb).csParam.type      = TRACKADDR;
        (*pb).csParam.addr[3]   = Decimal2BCD(startTrack);
        (*pb).csParam.startStop = START;
        (*pb).csParam.fill      = 0;
        (*pb).csParam.playMode  = playMode;
        osErr = PBControl((ParmBlkPtr)pb, false);
        DisposPtr((Ptr) pb);
    }
    return osErr;
}
 
pascal  OSErr AStop(short ioRefNum, Byte stopTrack) {
 
    auto    OSErr           osErr;
    static  AStopRec        *pb;    
 
    pb = (AStopRec *) NewPtrClear(sizeof (*pb));
    osErr = MemError();
    if (0 != pb && noErr == osErr) {
        (*pb).ioRefNum          = ioRefNum;
        (*pb).csCode            = csAStop;
        (*pb).csParam.type      = 0 == stopTrack ? BLOCKADDR : TRACKADDR; 
        (*pb).csParam.addr[3]   = Decimal2BCD(stopTrack);
        osErr = PBControl((ParmBlkPtr)pb, false);
        DisposPtr((Ptr) pb);
    }
    return osErr;
}
 
pascal  OSErr APause(short ioRefNum, Long state) { 
 
    auto    OSErr           osErr;
    static  APauseRec       *pb;
 
    pb = (APauseRec *) NewPtrClear(sizeof (*pb));
    osErr = MemError();
    if (0 != pb && noErr == osErr) {
        (*pb).ioRefNum          = ioRefNum;
        (*pb).csCode            = csAPause;
        (*pb).csParam.state     = state;
        osErr = PBControl((ParmBlkPtr)pb, false);
        DisposPtr((Ptr) pb);
    }
    return osErr;
}
 
pascal  OSErr TrackCount(short ioRefNum, Byte *stopTrack) {
 
    auto    OSErr           osErr;
    static  ReadTOCRec      *pb;
 
    pb = (ReadTOCRec *) NewPtrClear(sizeof (*pb));
    osErr = MemError();
    if (0 != pb && noErr == osErr) {
        (*pb).ioRefNum          = ioRefNum;
        (*pb).csCode            = csReadTOC;
        (*pb).csParam.type      = 1;
        osErr = PBControl((ParmBlkPtr)pb, false);
        if (noErr == osErr) {
            *stopTrack          = BCD2Decimal((*pb).csParam.addr[1]);
        }
        DisposPtr((Ptr) pb);
    }
    return osErr;
}
 
pascal  OSErr TrackInfo(short ioRefNum, Byte track, Byte *cntlField, Byte *minutes, Byte *seconds, Byte *frames) {
 
    auto    OSErr           osErr;
    static  ReadTOCRec      *pb;
    
    pb = (ReadTOCRec *) NewPtrClear(sizeof (*pb));
    osErr = MemError();
    if (0 != pb && noErr == osErr) {
        (*pb).ioRefNum                  = ioRefNum;
        (*pb).csCode                    = csReadTOC;
        (*pb).csParam.type              = 3;
        (*pb).csParam.buffer.data       = (Long) NewPtrClear(sizeof (StartAddrRec));
        osErr = MemError();
        if (0 != (*pb).csParam.buffer.data && noErr == osErr) {
            (*pb).csParam.buffer.length     = sizeof(StartAddrRec);
            (*pb).csParam.buffer.track      = Decimal2BCD(track);
            osErr = PBControl((ParmBlkPtr)pb, false);
            if (noErr == osErr) {
                *cntlField      = (*(StartAddrRec *)(*pb).csParam.buffer.data).cntlField;
                *minutes        = BCD2Decimal((*(StartAddrRec *)(*pb).csParam.buffer.data).minutes);
                *seconds        = BCD2Decimal((*(StartAddrRec *)(*pb).csParam.buffer.data).seconds);
                *frames         = BCD2Decimal((*(StartAddrRec *)(*pb).csParam.buffer.data).frames);
            }
            DisposPtr((Ptr) (*pb).csParam.buffer.data);
        }
        DisposPtr((Ptr) pb);
    }
    return osErr;
}
 
pascal  OSErr ATrkSearch(short ioRefNum, Byte track, Byte playFlag, Byte playMode) {
 
    auto    OSErr           osErr;
    static  ATrkSearchRec   *pb;    
 
    pb = (ATrkSearchRec *) NewPtrClear(sizeof (*pb));
    osErr = MemError();
    if (0 != pb && noErr == osErr) {
        (*pb).ioRefNum          = ioRefNum;
        (*pb).csCode            = csATrkSearch;
        (*pb).csParam.type      = TRACKADDR;
        (*pb).csParam.addr[3]   = Decimal2BCD(track);
        (*pb).csParam.playFlag  = playFlag;
        (*pb).csParam.playMode  = playMode;
        osErr = PBControl((ParmBlkPtr)pb, false);
        DisposPtr((Ptr) pb);
    }
    return osErr;
}
 
pascal  OSErr AStatus(short ioRefNum, Byte *audioStatus, Byte *playMode, Byte *cntlField, Byte *minutes, Byte *seconds, Byte *frames) {
 
    auto    OSErr           osErr;
    static  AStatusRec      *pb;
 
    pb = (AStatusRec *) NewPtrClear(sizeof (*pb));
    osErr = MemError();
    if (0 != pb && noErr == osErr) {
        (*pb).ioRefNum              = ioRefNum;
        (*pb).csCode                = csAStatus;
        osErr = PBControl((ParmBlkPtr)pb, false);
        if (noErr == osErr) {
            *audioStatus        = (*pb).csParam.audioStatus;
            *playMode           = (*pb).csParam.playMode;
            *cntlField          = (*pb).csParam.cntlField;
            *minutes            = BCD2Decimal((*pb).csParam.minutes);
            *seconds            = BCD2Decimal((*pb).csParam.seconds);
            *frames             = BCD2Decimal((*pb).csParam.frames);
        }
        DisposPtr((Ptr) pb);
    }
    return osErr;
}