From c9111b22a2e95f1cef7280c5ce182fdcf4c337d9 Mon Sep 17 00:00:00 2001 From: TomW Date: Mon, 4 Apr 2016 15:15:08 +0100 Subject: [PATCH] Updates and fixes to Linux IOCTL CD-ROM code. Based on patch from Battler --- src/Makefile.in | 73 ++++++++++++++++----------- src/allegro-gui.c | 4 +- src/cdrom-ioctl-linux.c | 108 ++++++++++++++++++++++++++++------------ src/thread-pthread.c | 5 +- 4 files changed, 127 insertions(+), 63 deletions(-) diff --git a/src/Makefile.in b/src/Makefile.in index 032b532..81830c0 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -39,7 +39,8 @@ build_triplet = @build@ host_triplet = @host@ bin_PROGRAMS = pcem$(EXEEXT) @CPU_I386_TRUE@am__append_1 = codegen_x86.c -@CPU_X86_64_TRUE@am__append_2 = codegen_x86-64.c +@CPU_I386_TRUE@am__append_2 = -msse2 +@CPU_X86_64_TRUE@am__append_3 = codegen_x86-64.c subdir = src DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -74,10 +75,10 @@ am__pcem_SOURCES_DIST = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ timer.c um8669f.c um8881f.c vid_ati_eeprom.c vid_ati_mach64.c \ vid_ati18800.c vid_ati28800.c vid_ati68860_ramdac.c vid_cga.c \ vid_cl5429.c vid_ega.c vid_et4000.c vid_et4000w32.c \ - vid_hercules.c vid_icd2061.c vid_ics2595.c vid_mda.c \ - vid_olivetti_m24.c vid_oti067.c vid_paradise.c vid_pc200.c \ - vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_s3.c vid_s3_virge.c \ - vid_sdac_ramdac.c vid_stg_ramdac.c vid_svga.c \ + vid_hercules.c vid_icd2061.c vid_ics2595.c vid_incolor.c \ + vid_mda.c vid_olivetti_m24.c vid_oti067.c vid_paradise.c \ + vid_pc200.c vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_s3.c \ + vid_s3_virge.c vid_sdac_ramdac.c vid_stg_ramdac.c vid_svga.c \ vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \ vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c \ vid_voodoo.c video.c wd76c10.c x86seg.c x87.c xtide.c \ @@ -146,23 +147,24 @@ am_pcem_OBJECTS = pcem-386.$(OBJEXT) pcem-386_dynarec.$(OBJEXT) \ pcem-vid_ega.$(OBJEXT) pcem-vid_et4000.$(OBJEXT) \ pcem-vid_et4000w32.$(OBJEXT) pcem-vid_hercules.$(OBJEXT) \ pcem-vid_icd2061.$(OBJEXT) pcem-vid_ics2595.$(OBJEXT) \ - pcem-vid_mda.$(OBJEXT) pcem-vid_olivetti_m24.$(OBJEXT) \ - pcem-vid_oti067.$(OBJEXT) pcem-vid_paradise.$(OBJEXT) \ - pcem-vid_pc200.$(OBJEXT) pcem-vid_pc1512.$(OBJEXT) \ - pcem-vid_pc1640.$(OBJEXT) pcem-vid_pcjr.$(OBJEXT) \ - pcem-vid_s3.$(OBJEXT) pcem-vid_s3_virge.$(OBJEXT) \ - pcem-vid_sdac_ramdac.$(OBJEXT) pcem-vid_stg_ramdac.$(OBJEXT) \ - pcem-vid_svga.$(OBJEXT) pcem-vid_svga_render.$(OBJEXT) \ - pcem-vid_tandy.$(OBJEXT) pcem-vid_tandysl.$(OBJEXT) \ - pcem-vid_tgui9440.$(OBJEXT) pcem-vid_tkd8001_ramdac.$(OBJEXT) \ - pcem-vid_tvga.$(OBJEXT) pcem-vid_unk_ramdac.$(OBJEXT) \ - pcem-vid_vga.$(OBJEXT) pcem-vid_voodoo.$(OBJEXT) \ - pcem-video.$(OBJEXT) pcem-wd76c10.$(OBJEXT) \ - pcem-x86seg.$(OBJEXT) pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) \ - sound_dbopl.$(OBJEXT) sound_resid.$(OBJEXT) dbopl.$(OBJEXT) \ - convolve.$(OBJEXT) convolve-sse.$(OBJEXT) envelope.$(OBJEXT) \ - extfilt.$(OBJEXT) filter.$(OBJEXT) pot.$(OBJEXT) sid.$(OBJEXT) \ - voice.$(OBJEXT) wave6581_PS_.$(OBJEXT) wave6581_PST.$(OBJEXT) \ + pcem-vid_incolor.$(OBJEXT) pcem-vid_mda.$(OBJEXT) \ + pcem-vid_olivetti_m24.$(OBJEXT) pcem-vid_oti067.$(OBJEXT) \ + pcem-vid_paradise.$(OBJEXT) pcem-vid_pc200.$(OBJEXT) \ + pcem-vid_pc1512.$(OBJEXT) pcem-vid_pc1640.$(OBJEXT) \ + pcem-vid_pcjr.$(OBJEXT) pcem-vid_s3.$(OBJEXT) \ + pcem-vid_s3_virge.$(OBJEXT) pcem-vid_sdac_ramdac.$(OBJEXT) \ + pcem-vid_stg_ramdac.$(OBJEXT) pcem-vid_svga.$(OBJEXT) \ + pcem-vid_svga_render.$(OBJEXT) pcem-vid_tandy.$(OBJEXT) \ + pcem-vid_tandysl.$(OBJEXT) pcem-vid_tgui9440.$(OBJEXT) \ + pcem-vid_tkd8001_ramdac.$(OBJEXT) pcem-vid_tvga.$(OBJEXT) \ + pcem-vid_unk_ramdac.$(OBJEXT) pcem-vid_vga.$(OBJEXT) \ + pcem-vid_voodoo.$(OBJEXT) pcem-video.$(OBJEXT) \ + pcem-wd76c10.$(OBJEXT) pcem-x86seg.$(OBJEXT) \ + pcem-x87.$(OBJEXT) pcem-xtide.$(OBJEXT) sound_dbopl.$(OBJEXT) \ + sound_resid.$(OBJEXT) dbopl.$(OBJEXT) convolve.$(OBJEXT) \ + convolve-sse.$(OBJEXT) envelope.$(OBJEXT) extfilt.$(OBJEXT) \ + filter.$(OBJEXT) pot.$(OBJEXT) sid.$(OBJEXT) voice.$(OBJEXT) \ + wave6581_PS_.$(OBJEXT) wave6581_PST.$(OBJEXT) \ wave6581_P_T.$(OBJEXT) wave6581__ST.$(OBJEXT) \ wave8580_PS_.$(OBJEXT) wave8580_PST.$(OBJEXT) \ wave8580_P_T.$(OBJEXT) wave8580__ST.$(OBJEXT) wave.$(OBJEXT) \ @@ -289,7 +291,7 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_SCRIPTS = ../pcem CLEANFILES = $(noinst_SCRIPTS) -pcem_CFLAGS = $(allegro_CFLAGS) +pcem_CFLAGS = $(allegro_CFLAGS) $(am__append_2) pcem_LDADD = $(allegro_LIBS) -lopenal -lalut pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ acer386sx.c ali1429.c allegro-gui.c allegro-gui-configure.c \ @@ -314,10 +316,10 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ timer.c um8669f.c um8881f.c vid_ati_eeprom.c vid_ati_mach64.c \ vid_ati18800.c vid_ati28800.c vid_ati68860_ramdac.c vid_cga.c \ vid_cl5429.c vid_ega.c vid_et4000.c vid_et4000w32.c \ - vid_hercules.c vid_icd2061.c vid_ics2595.c vid_mda.c \ - vid_olivetti_m24.c vid_oti067.c vid_paradise.c vid_pc200.c \ - vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_s3.c vid_s3_virge.c \ - vid_sdac_ramdac.c vid_stg_ramdac.c vid_svga.c \ + vid_hercules.c vid_icd2061.c vid_ics2595.c vid_incolor.c \ + vid_mda.c vid_olivetti_m24.c vid_oti067.c vid_paradise.c \ + vid_pc200.c vid_pc1512.c vid_pc1640.c vid_pcjr.c vid_s3.c \ + vid_s3_virge.c vid_sdac_ramdac.c vid_stg_ramdac.c vid_svga.c \ vid_svga_render.c vid_tandy.c vid_tandysl.c vid_tgui9440.c \ vid_tkd8001_ramdac.c vid_tvga.c vid_unk_ramdac.c vid_vga.c \ vid_voodoo.c video.c wd76c10.c x86seg.c x87.c xtide.c \ @@ -329,7 +331,7 @@ pcem_SOURCES = 386.c 386_dynarec.c 386_dynarec_ops.c 808x.c \ resid-fp/wave6581_P_T.cc resid-fp/wave6581__ST.cc \ resid-fp/wave8580_PS_.cc resid-fp/wave8580_PST.cc \ resid-fp/wave8580_P_T.cc resid-fp/wave8580__ST.cc \ - resid-fp/wave.cc $(am__append_1) $(am__append_2) + resid-fp/wave.cc $(am__append_1) $(am__append_3) all: all-am .SUFFIXES: @@ -532,6 +534,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_hercules.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_icd2061.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_ics2595.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_incolor.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_mda.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_olivetti_m24.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pcem-vid_oti067.Po@am__quote@ @@ -2170,6 +2173,20 @@ pcem-vid_ics2595.obj: vid_ics2595.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_ics2595.obj `if test -f 'vid_ics2595.c'; then $(CYGPATH_W) 'vid_ics2595.c'; else $(CYGPATH_W) '$(srcdir)/vid_ics2595.c'; fi` +pcem-vid_incolor.o: vid_incolor.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_incolor.o -MD -MP -MF $(DEPDIR)/pcem-vid_incolor.Tpo -c -o pcem-vid_incolor.o `test -f 'vid_incolor.c' || echo '$(srcdir)/'`vid_incolor.c +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_incolor.Tpo $(DEPDIR)/pcem-vid_incolor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_incolor.c' object='pcem-vid_incolor.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_incolor.o `test -f 'vid_incolor.c' || echo '$(srcdir)/'`vid_incolor.c + +pcem-vid_incolor.obj: vid_incolor.c +@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_incolor.obj -MD -MP -MF $(DEPDIR)/pcem-vid_incolor.Tpo -c -o pcem-vid_incolor.obj `if test -f 'vid_incolor.c'; then $(CYGPATH_W) 'vid_incolor.c'; else $(CYGPATH_W) '$(srcdir)/vid_incolor.c'; fi` +@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_incolor.Tpo $(DEPDIR)/pcem-vid_incolor.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='vid_incolor.c' object='pcem-vid_incolor.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -c -o pcem-vid_incolor.obj `if test -f 'vid_incolor.c'; then $(CYGPATH_W) 'vid_incolor.c'; else $(CYGPATH_W) '$(srcdir)/vid_incolor.c'; fi` + pcem-vid_mda.o: vid_mda.c @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(pcem_CFLAGS) $(CFLAGS) -MT pcem-vid_mda.o -MD -MP -MF $(DEPDIR)/pcem-vid_mda.Tpo -c -o pcem-vid_mda.o `test -f 'vid_mda.c' || echo '$(srcdir)/'`vid_mda.c @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/pcem-vid_mda.Tpo $(DEPDIR)/pcem-vid_mda.Po diff --git a/src/allegro-gui.c b/src/allegro-gui.c index 70bf83d..5868e58 100644 --- a/src/allegro-gui.c +++ b/src/allegro-gui.c @@ -156,14 +156,14 @@ static int cdrom_dev() if (cdrom_enabled) { atapi->exit(); - cdrom_drive = 0; + cdrom_drive = 1; ioctl_open(cdrom_drive); return D_O_K; } if (alert("This will reset PCem!", "Okay to continue?", NULL, "OK", "Cancel", 0, 0) == 1) { - cdrom_drive = 0; + cdrom_drive = 1; cdrom_enabled = 1; ioctl_open(cdrom_drive); saveconfig(); diff --git a/src/cdrom-ioctl-linux.c b/src/cdrom-ioctl-linux.c index 4283087..5ced89b 100644 --- a/src/cdrom-ioctl-linux.c +++ b/src/cdrom-ioctl-linux.c @@ -3,6 +3,7 @@ #include #include #include +#include #include "ibm.h" #include "ide.h" #include "cdrom-ioctl.h" @@ -10,6 +11,7 @@ static ATAPI ioctl_atapi; static uint32_t last_block = 0; +static uint32_t cdrom_capacity = 0; static int ioctl_inited = 0; static char ioctl_path[8]; static int tocvalid = 0; @@ -29,7 +31,6 @@ enum static int ioctl_cd_state = CD_STOPPED; static uint32_t ioctl_cd_pos = 0, ioctl_cd_end = 0; - #define BUF_SIZE 32768 static int16_t cd_buffer[BUF_SIZE]; static int cd_buflen = 0; @@ -56,7 +57,7 @@ void ioctl_audio_callback(int16_t *output, int len) { if (ioctl_cd_pos < ioctl_cd_end) { - read_audio.addr.lba = ioctl_cd_pos; + read_audio.addr.lba = ioctl_cd_pos - 150; read_audio.addr_format = CDROM_LBA; read_audio.nframes = 1; read_audio.buf = (__u8 *)&cd_buffer[cd_buflen]; @@ -162,6 +163,8 @@ static void ioctl_playaudio(uint32_t pos, uint32_t len, int ismsf) ioctl_cd_pos = pos;// + 150; ioctl_cd_end = pos+len;// + 150; ioctl_cd_state = CD_PLAYING; + if (ioctl_cd_pos < 150) + ioctl_cd_pos = 150; // pclog("Audio start %08X %08X %i %i %i\n", ioctl_cd_pos, ioctl_cd_end, ioctl_cd_state, 0, len); } @@ -189,7 +192,7 @@ static void ioctl_seek(uint32_t pos) ioctl_cd_state = CD_STOPPED; } -static int read_toc(int fd) +static int read_toc(int fd, struct cdrom_tocentry *btoc) { struct cdrom_tochdr toc_hdr; int track, err; @@ -204,13 +207,13 @@ static int read_toc(int fd) first_track = toc_hdr.cdth_trk0; last_track = toc_hdr.cdth_trk1; //pclog("read_toc: first_track=%i last_track=%i\n", first_track, last_track); - memset(toc, 0, sizeof(toc)); + memset(btoc, 0, sizeof(btoc)); for (track = toc_hdr.cdth_trk0; track <= toc_hdr.cdth_trk1; track++) { - toc[track].cdte_track = track; - toc[track].cdte_format = CDROM_MSF; - err = ioctl(fd, CDROMREADTOCENTRY, &toc[track]); + btoc[track].cdte_track = track; + btoc[track].cdte_format = CDROM_MSF; + err = ioctl(fd, CDROMREADTOCENTRY, &btoc[track]); if (err == -1) { // pclog("read_toc: CDROMREADTOCENTRY failed on track %i\n", track); @@ -257,7 +260,7 @@ static int ioctl_ready(void) int track; ioctl_cd_state = CD_STOPPED; - tocvalid = read_toc(fd); + tocvalid = read_toc(fd, toc); close(fd); return 1; } @@ -265,6 +268,37 @@ static int ioctl_ready(void) return 1; } +static int ioctl_get_last_block(unsigned char starttrack, int msf, int maxlen, int single) +{ + int c; + int lb = 0; + int tv = 0; + struct cdrom_tocentry lbtoc[100]; + int fd = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + + if (fd <= 0) + return 0; + + ioctl_cd_state = CD_STOPPED; + + tv = read_toc(fd, lbtoc); + + close(fd); + + if (!tv) + return 0; + + last_block = 0; + for (c = 0; c <= last_track; c++) + { + uint32_t address; + address = MSFtoLBA(toc[c].cdte_addr.msf.minute, toc[c].cdte_addr.msf.second, toc[c].cdte_addr.msf.frame); + if (address > last_block) + lb = address; + } + return lb; +} + static int ioctl_medium_changed(void) { long size; @@ -296,6 +330,7 @@ static int ioctl_medium_changed(void) (toc_entry.cdte_addr.msf.second != toc[toc_hdr.cdth_trk1].cdte_addr.msf.second) || (toc_entry.cdte_addr.msf.frame != toc[toc_hdr.cdth_trk1].cdte_addr.msf.frame )) { + cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); return 1; } return 0; @@ -378,6 +413,8 @@ static void ioctl_load(void) ioctl(fd, CDROMEJECT); close(fd); + + cdrom_capacity = ioctl_get_last_block(0, 0, 4096, 0); } static void ioctl_readsector(uint8_t *b, int sector) @@ -390,33 +427,44 @@ static void ioctl_readsector(uint8_t *b, int sector) close(cdrom); } -static void lba_to_msf(uint8_t *buf, int lba) +union { - lba += 150; - buf[0] = (lba / 75) / 60; - buf[1] = (lba / 75) % 60; - buf[2] = lba % 75; + struct cdrom_msf *msf; + char b[CD_FRAMESIZE_RAW]; +} raw_read_params; + +static int lba_to_msf(int lba) +{ + return (((lba / 75) / 60) << 16) + (((lba / 75) % 60) << 8) + (lba % 75); } static void ioctl_readsector_raw(uint8_t *b, int sector) { + int err; + int imsf = lba_to_msf(sector); int cdrom = open("/dev/cdrom", O_RDONLY|O_NONBLOCK); + if (cdrom <= 0) return; - lseek(cdrom, sector*2048, SEEK_SET); - read(cdrom, b+16, 2048); + + raw_read_params.msf = malloc(sizeof(struct cdrom_msf)); + raw_read_params.msf->cdmsf_frame0 = imsf & 0xff; + raw_read_params.msf->cdmsf_sec0 = (imsf >> 8) & 0xff; + raw_read_params.msf->cdmsf_min0 = (imsf >> 16) & 0xff; + + /* This will read the actual raw sectors from the disc. */ + err = ioctl(cdrom, CDROMREADRAW, (void *) &raw_read_params); + if (err == -1) + { + pclog("read_toc: CDROMREADTOCHDR failed\n"); + return; + } + + memcpy(b, raw_read_params.b, 2352); + close(cdrom); - /* sync bytes */ - b[0] = 0; - memset(b + 1, 0xff, 10); - b[11] = 0; - b += 12; - lba_to_msf(b, sector); - b[3] = 1; /* mode 1 data */ - b += 4; - b += 2048; - memset(b, 0, 288); + free(raw_read_params.msf); } static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, int maxlen, int single) @@ -432,7 +480,7 @@ static int ioctl_readtoc(unsigned char *b, unsigned char starttrack, int msf, in ioctl_cd_state = CD_STOPPED; - tocvalid = read_toc(fd); + tocvalid = read_toc(fd, toc); close(fd); @@ -604,11 +652,7 @@ static int ioctl_readtoc_raw(unsigned char *b, int maxlen) static uint32_t ioctl_size() { - unsigned char b[4096]; - - atapi->readtoc(b, 0, 0, 4096, 0); - - return last_block; + return cdrom_capacity; } static int ioctl_status() @@ -634,7 +678,7 @@ void ioctl_reset() if (fd <= 0) return; - tocvalid = read_toc(fd); + tocvalid = read_toc(fd, toc); close(fd); } diff --git a/src/thread-pthread.c b/src/thread-pthread.c index 78b5968..51d7d8a 100644 --- a/src/thread-pthread.c +++ b/src/thread-pthread.c @@ -67,7 +67,10 @@ int thread_wait_event(event_t *handle, int timeout) } pthread_mutex_lock(&event->mutex); - pthread_cond_timedwait(&event->cond, &event->mutex, &abstime); + if (timeout == -1) + pthread_cond_wait(&event->cond, &event->mutex); + else + pthread_cond_timedwait(&event->cond, &event->mutex, &abstime); pthread_mutex_unlock(&event->mutex); return 0;