/* CDP plays arbitrary segment of a Music CD */ #include #include #include #include #include #include #define FALSE 0 #define TRUE 1 int cdrom_loaded, cdrom_drive; struct ioctl_struc ioctl_block; struct diskinfo_struc diskinfo_block; struct trackinfo_struc trackinfo_block[100]; unsigned long red2hsg(unsigned long redval); main(int argc, char *argv[]) { int drive, i; unsigned long start_sect, end_sect, leadout_sect, num_sect; unsigned char filename[80]; FILE *outfp; int track, start_min, start_sec, start_frame, end_min, end_sec, end_frame; char local_buffer[132]; char c = ':'; if(argc > 1) { if (! check_cd2f()){ printf("MSCDEX NOT LOADED\n"); exit(1); } Stop(); if((argv[1][0] == 's') || (argv[1][0] == 'S')) exit(1); while(get_diskinfo() != STAT_DONE); for(i = diskinfo_block.low_track; i <= diskinfo_block.high_track; i++) get_trackinfo(i); leadout_sect = red2hsg(diskinfo_block.start_leadout); track = atoi(argv[1]); if( (track < 1) || (track > diskinfo_block.high_track)) { printf("Error: Track must be between %d and %d\n", diskinfo_block.low_track, diskinfo_block.high_track); errexit(); } start_min = 0; start_sec = 0; start_frame = 0; end_min = 0; end_sec = 0; end_frame = 0; if(argc > 2) { strcpy(local_buffer, argv[2]); start_min = atoi(strtok(local_buffer, ":")); start_sec = atoi(strtok(NULL,":")); start_frame = atoi(&local_buffer[strrchr(argv[2],c)+1-local_buffer]); } start_sect = red2hsg(trackinfo_block[track].start_point)+(start_min*60L+((long)start_sec))*75L+((long)start_frame) -150L; if(argc > 3) { strcpy(local_buffer, argv[3]); end_min = atoi(strtok(local_buffer, ":")); end_sec = atoi(strtok(NULL, ":")); end_frame = atoi(&local_buffer[strrchr(argv[3],c)+1-local_buffer]); end_sect = red2hsg(trackinfo_block[track].start_point)+(end_min*60L+((long)end_sec))*75L+((long)end_frame) -150L; } else end_sect = leadout_sect; num_sect = end_sect-start_sect; printf("Start sector : %lu\n", start_sect); printf("End sector : %lu\n", end_sect); printf("Number of sectors: %lu\n", num_sect); printf("CDDA data size : %lu bytes\n", num_sect * 2352L); play(start_sect, num_sect); } else { printf("CDP Plays an arbitrary section of a CD\n"); printf("usage: cdp [] []\n"); printf(" \"cdp s\" stops playing\n"); } } check_cd2f() { union REGS regs; regs.x.ax = INIT_MP_INT; int86(MULTIPLEX_INT,®s,®s); cdrom_loaded = regs.x.bx; cdrom_drive = regs.x.cx; } get_diskinfo() { union REGS regs; struct SREGS sregs; diskinfo_block.cntrl_code = GET_AUDIO_DISKINFO; ioctl_block.req_hdr.param_length = 13; ioctl_block.req_hdr.sub_unit = 0; ioctl_block.req_hdr.command_code = READ_IOCTL_COMMAND; ioctl_block.req_hdr.status = 0; ioctl_block.med_descr = 0; ioctl_block.transf_addr = (unsigned long)&diskinfo_block; ioctl_block.num_bytes = 7; ioctl_block.start_sect = 0; ioctl_block.vol_id = 0; regs.x.ax = CDREQ_MP_INT; regs.x.bx = FP_OFF(&ioctl_block); regs.x.cx = cdrom_drive; sregs.es = FP_SEG(&ioctl_block); int86x(MULTIPLEX_INT,®s,®s,&sregs); return(ioctl_block.req_hdr.status); } get_trackinfo(unsigned char trk) { union REGS regs; struct SREGS sregs; trackinfo_block[trk].cntrl_code = GET_AUDIO_TRACKINFO; trackinfo_block[trk].track_num = trk; ioctl_block.req_hdr.param_length = 13; ioctl_block.req_hdr.sub_unit = 0; ioctl_block.req_hdr.command_code = READ_IOCTL_COMMAND; ioctl_block.req_hdr.status = 0; ioctl_block.med_descr = 0; ioctl_block.transf_addr = (unsigned long)&(trackinfo_block[trk]); ioctl_block.num_bytes = 7; ioctl_block.start_sect = 0; ioctl_block.vol_id = 0; regs.x.ax = CDREQ_MP_INT; regs.x.bx = FP_OFF(&ioctl_block); regs.x.cx = cdrom_drive; sregs.es = FP_SEG(&ioctl_block); int86x(MULTIPLEX_INT,®s,®s,&sregs); return(ioctl_block.req_hdr.status); } play(unsigned long ssec,unsigned long numsecs) { union REGS regs; struct SREGS sregs; struct play_struc play_block; struct qinfo_struc qinfo_block; play_block.req_hdr.param_length = 13; play_block.req_hdr.sub_unit = 0; play_block.req_hdr.command_code = CD_PLAY_AUDIO; play_block.req_hdr.status = 0; play_block.address_mode = ADDR_HSG; play_block.start_sect = ssec; play_block.num_sect = numsecs; regs.x.ax = CDREQ_MP_INT; regs.x.bx = FP_OFF(&play_block); regs.x.cx = cdrom_drive; sregs.es = FP_SEG(&play_block); int86x(MULTIPLEX_INT,®s,®s,&sregs); /* do { qinfo_block.cntrl_code = GET_QCHAN_INFO; ioctl_block.req_hdr.param_length = 13; ioctl_block.req_hdr.sub_unit = 0; ioctl_block.req_hdr.command_code = READ_IOCTL_COMMAND; ioctl_block.req_hdr.status = 0; ioctl_block.med_descr = 0; ioctl_block.transf_addr = (unsigned long)&qinfo_block; ioctl_block.num_bytes = 11; ioctl_block.start_sec = 0; ioctl_block.vol_id = 0; regs.x.ax = CDREQ_MP_INT; regs.x.bx = FP_OFF(&ioctl_block); regs.x.cx = cdrom_drive; sregs.es = FP_SEG(&ioctl_block); int86x(MULTIPLEX_INT,®s,®s,&sregs); if(kbhit()){ getch(); Stop(); break; } } while (ioctl_block.req_hdr.status & STAT_BUSY); */ } Stop() { union REGS regs; struct SREGS sregs; struct reqhdr_struc stop_block; stop_block.param_length = 13; stop_block.sub_unit = 0; stop_block.command_code = CD_STOP_AUDIO; stop_block.status = 0; regs.x.ax = CDREQ_MP_INT; regs.x.bx = FP_OFF(&stop_block); regs.x.cx = cdrom_drive; sregs.es = FP_SEG(&stop_block); int86x(MULTIPLEX_INT,®s,®s,&sregs); return(stop_block.status); } unsigned long red2hsg(unsigned long redval) { unsigned long mins; unsigned long secs; unsigned long plus_frames; plus_frames = redval & 0x000000ffL; secs = ((redval & 0x0000ff00L) >> 8); mins = ((redval & 0x00ff0000L) >> 16); return((mins*60+secs)*75+plus_frames); } errexit() { exit(1); } .