revision 342:850502f0e8de
summary |
tree |
shortlog |
changelog |
graph |
changeset |
raw | bz2 | zip | gz changeset | 342:850502f0e8de |
parent | 341:924029ff95ea |
child | 343:bf4bf0da94cc |
author | nkeynes |
date | Wed Jan 31 10:58:42 2007 +0000 (17 years ago) |
Refactor gdrom module to be more conducive to real device support
src/Makefile.am | view | annotate | diff | log | ||
src/Makefile.in | view | annotate | diff | log | ||
src/asic.c | view | annotate | diff | log | ||
src/gdrom/cdi.c | view | annotate | diff | log | ||
src/gdrom/gdimage.c | view | annotate | diff | log | ||
src/gdrom/gdrom.c | view | annotate | diff | log | ||
src/gdrom/gdrom.h | view | annotate | diff | log | ||
src/gdrom/ide.c | view | annotate | diff | log | ||
src/gdrom/ide.h | view | annotate | diff | log | ||
src/gdrom/linux.c | view | annotate | diff | log | ||
src/gdrom/nrg.c | view | annotate | diff | log | ||
src/gdrom/packet.h | view | annotate | diff | log |
1.1 --- a/src/Makefile.am Wed Jan 31 10:32:25 2007 +00001.2 +++ b/src/Makefile.am Wed Jan 31 10:58:42 2007 +00001.3 @@ -13,7 +13,7 @@1.4 mem.c mem.h mmio.h watch.c \1.5 asic.c asic.h \1.6 syscall.c syscall.h bios.c dcload.c \1.7 - gdrom/ide.c gdrom/ide.h gdrom/packet.h \1.8 + gdrom/ide.c gdrom/ide.h gdrom/packet.h gdrom/gdimage.c \1.9 gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c gdrom/linux.c \1.10 dreamcast.c dreamcast.h eventq.c eventq.h \1.11 sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \
2.1 --- a/src/Makefile.in Wed Jan 31 10:32:25 2007 +00002.2 +++ b/src/Makefile.in Wed Jan 31 10:58:42 2007 +00002.3 @@ -147,7 +147,7 @@2.4 mem.c mem.h mmio.h watch.c \2.5 asic.c asic.h \2.6 syscall.c syscall.h bios.c dcload.c \2.7 - gdrom/ide.c gdrom/ide.h gdrom/packet.h \2.8 + gdrom/ide.c gdrom/ide.h gdrom/packet.h gdrom/gdimage.c \2.9 gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c gdrom/cdi.c gdrom/linux.c \2.10 dreamcast.c dreamcast.h eventq.c eventq.h \2.11 sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \2.12 @@ -186,22 +186,23 @@2.14 am_lxdream_OBJECTS = main.$(OBJEXT) mem.$(OBJEXT) watch.$(OBJEXT) \2.15 asic.$(OBJEXT) syscall.$(OBJEXT) bios.$(OBJEXT) \2.16 - dcload.$(OBJEXT) ide.$(OBJEXT) gdrom.$(OBJEXT) nrg.$(OBJEXT) \2.17 - cdi.$(OBJEXT) linux.$(OBJEXT) dreamcast.$(OBJEXT) \2.18 - eventq.$(OBJEXT) intc.$(OBJEXT) sh4mem.$(OBJEXT) \2.19 - timer.$(OBJEXT) dmac.$(OBJEXT) sh4core.$(OBJEXT) \2.20 - sh4dasm.$(OBJEXT) sh4mmio.$(OBJEXT) scif.$(OBJEXT) \2.21 - armcore.$(OBJEXT) armdasm.$(OBJEXT) armmem.$(OBJEXT) \2.22 - aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) pvr2mem.$(OBJEXT) \2.23 - tacore.$(OBJEXT) render.$(OBJEXT) rendcore.$(OBJEXT) \2.24 - rendbkg.$(OBJEXT) rendsort.$(OBJEXT) texcache.$(OBJEXT) \2.25 - yuv.$(OBJEXT) rendsave.$(OBJEXT) maple.$(OBJEXT) \2.26 - controller.$(OBJEXT) support.$(OBJEXT) interface.$(OBJEXT) \2.27 - callbacks.$(OBJEXT) gui.$(OBJEXT) mmr_win.$(OBJEXT) \2.28 - debug_win.$(OBJEXT) dump_win.$(OBJEXT) loader.$(OBJEXT) \2.29 - bootstrap.$(OBJEXT) util.$(OBJEXT) display.$(OBJEXT) \2.30 - audio_null.$(OBJEXT) audio_esd.$(OBJEXT) video_null.$(OBJEXT) \2.31 - video_gtk.$(OBJEXT) video_x11.$(OBJEXT) video_gl.$(OBJEXT)2.32 + dcload.$(OBJEXT) ide.$(OBJEXT) gdimage.$(OBJEXT) \2.33 + gdrom.$(OBJEXT) nrg.$(OBJEXT) cdi.$(OBJEXT) linux.$(OBJEXT) \2.34 + dreamcast.$(OBJEXT) eventq.$(OBJEXT) intc.$(OBJEXT) \2.35 + sh4mem.$(OBJEXT) timer.$(OBJEXT) dmac.$(OBJEXT) \2.36 + sh4core.$(OBJEXT) sh4dasm.$(OBJEXT) sh4mmio.$(OBJEXT) \2.37 + scif.$(OBJEXT) armcore.$(OBJEXT) armdasm.$(OBJEXT) \2.38 + armmem.$(OBJEXT) aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) \2.39 + pvr2mem.$(OBJEXT) tacore.$(OBJEXT) render.$(OBJEXT) \2.40 + rendcore.$(OBJEXT) rendbkg.$(OBJEXT) rendsort.$(OBJEXT) \2.41 + texcache.$(OBJEXT) yuv.$(OBJEXT) rendsave.$(OBJEXT) \2.42 + maple.$(OBJEXT) controller.$(OBJEXT) support.$(OBJEXT) \2.43 + interface.$(OBJEXT) callbacks.$(OBJEXT) gui.$(OBJEXT) \2.44 + mmr_win.$(OBJEXT) debug_win.$(OBJEXT) dump_win.$(OBJEXT) \2.45 + loader.$(OBJEXT) bootstrap.$(OBJEXT) util.$(OBJEXT) \2.46 + display.$(OBJEXT) audio_null.$(OBJEXT) audio_esd.$(OBJEXT) \2.47 + video_null.$(OBJEXT) video_gtk.$(OBJEXT) video_x11.$(OBJEXT) \2.48 + video_gl.$(OBJEXT)2.49 lxdream_OBJECTS = $(am_lxdream_OBJECTS)2.50 lxdream_DEPENDENCIES =2.51 lxdream_LDFLAGS =2.52 @@ -219,24 +220,25 @@2.53 @AMDEP_TRUE@ ./$(DEPDIR)/debug_win.Po ./$(DEPDIR)/display.Po \2.54 @AMDEP_TRUE@ ./$(DEPDIR)/dmac.Po ./$(DEPDIR)/dreamcast.Po \2.55 @AMDEP_TRUE@ ./$(DEPDIR)/dump_win.Po ./$(DEPDIR)/eventq.Po \2.56 -@AMDEP_TRUE@ ./$(DEPDIR)/gdrom.Po ./$(DEPDIR)/gui.Po \2.57 -@AMDEP_TRUE@ ./$(DEPDIR)/ide.Po ./$(DEPDIR)/intc.Po \2.58 -@AMDEP_TRUE@ ./$(DEPDIR)/interface.Po ./$(DEPDIR)/linux.Po \2.59 -@AMDEP_TRUE@ ./$(DEPDIR)/loader.Po ./$(DEPDIR)/main.Po \2.60 -@AMDEP_TRUE@ ./$(DEPDIR)/maple.Po ./$(DEPDIR)/mem.Po \2.61 -@AMDEP_TRUE@ ./$(DEPDIR)/mmr_win.Po ./$(DEPDIR)/nrg.Po \2.62 -@AMDEP_TRUE@ ./$(DEPDIR)/pvr2.Po ./$(DEPDIR)/pvr2mem.Po \2.63 -@AMDEP_TRUE@ ./$(DEPDIR)/rendbkg.Po ./$(DEPDIR)/rendcore.Po \2.64 -@AMDEP_TRUE@ ./$(DEPDIR)/render.Po ./$(DEPDIR)/rendsave.Po \2.65 -@AMDEP_TRUE@ ./$(DEPDIR)/rendsort.Po ./$(DEPDIR)/scif.Po \2.66 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4core.Po ./$(DEPDIR)/sh4dasm.Po \2.67 -@AMDEP_TRUE@ ./$(DEPDIR)/sh4mem.Po ./$(DEPDIR)/sh4mmio.Po \2.68 -@AMDEP_TRUE@ ./$(DEPDIR)/support.Po ./$(DEPDIR)/syscall.Po \2.69 -@AMDEP_TRUE@ ./$(DEPDIR)/tacore.Po ./$(DEPDIR)/texcache.Po \2.70 -@AMDEP_TRUE@ ./$(DEPDIR)/timer.Po ./$(DEPDIR)/util.Po \2.71 -@AMDEP_TRUE@ ./$(DEPDIR)/video_gl.Po ./$(DEPDIR)/video_gtk.Po \2.72 -@AMDEP_TRUE@ ./$(DEPDIR)/video_null.Po ./$(DEPDIR)/video_x11.Po \2.73 -@AMDEP_TRUE@ ./$(DEPDIR)/watch.Po ./$(DEPDIR)/yuv.Po2.74 +@AMDEP_TRUE@ ./$(DEPDIR)/gdimage.Po ./$(DEPDIR)/gdrom.Po \2.75 +@AMDEP_TRUE@ ./$(DEPDIR)/gui.Po ./$(DEPDIR)/ide.Po \2.76 +@AMDEP_TRUE@ ./$(DEPDIR)/intc.Po ./$(DEPDIR)/interface.Po \2.77 +@AMDEP_TRUE@ ./$(DEPDIR)/linux.Po ./$(DEPDIR)/loader.Po \2.78 +@AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/maple.Po \2.79 +@AMDEP_TRUE@ ./$(DEPDIR)/mem.Po ./$(DEPDIR)/mmr_win.Po \2.80 +@AMDEP_TRUE@ ./$(DEPDIR)/nrg.Po ./$(DEPDIR)/pvr2.Po \2.81 +@AMDEP_TRUE@ ./$(DEPDIR)/pvr2mem.Po ./$(DEPDIR)/rendbkg.Po \2.82 +@AMDEP_TRUE@ ./$(DEPDIR)/rendcore.Po ./$(DEPDIR)/render.Po \2.83 +@AMDEP_TRUE@ ./$(DEPDIR)/rendsave.Po ./$(DEPDIR)/rendsort.Po \2.84 +@AMDEP_TRUE@ ./$(DEPDIR)/scif.Po ./$(DEPDIR)/sh4core.Po \2.85 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4dasm.Po ./$(DEPDIR)/sh4mem.Po \2.86 +@AMDEP_TRUE@ ./$(DEPDIR)/sh4mmio.Po ./$(DEPDIR)/support.Po \2.87 +@AMDEP_TRUE@ ./$(DEPDIR)/syscall.Po ./$(DEPDIR)/tacore.Po \2.88 +@AMDEP_TRUE@ ./$(DEPDIR)/texcache.Po ./$(DEPDIR)/timer.Po \2.89 +@AMDEP_TRUE@ ./$(DEPDIR)/util.Po ./$(DEPDIR)/video_gl.Po \2.90 +@AMDEP_TRUE@ ./$(DEPDIR)/video_gtk.Po ./$(DEPDIR)/video_null.Po \2.91 +@AMDEP_TRUE@ ./$(DEPDIR)/video_x11.Po ./$(DEPDIR)/watch.Po \2.92 +@AMDEP_TRUE@ ./$(DEPDIR)/yuv.Po2.93 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \2.94 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)2.95 CCLD = $(CC)2.96 @@ -308,6 +310,7 @@2.97 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dreamcast.Po@am__quote@2.98 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_win.Po@am__quote@2.99 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eventq.Po@am__quote@2.100 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdimage.Po@am__quote@2.101 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdrom.Po@am__quote@2.102 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui.Po@am__quote@2.103 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ide.Po@am__quote@2.104 @@ -389,6 +392,28 @@2.105 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.106 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ide.obj `if test -f 'gdrom/ide.c'; then $(CYGPATH_W) 'gdrom/ide.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/ide.c'; fi`2.108 +gdimage.o: gdrom/gdimage.c2.109 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gdimage.o -MD -MP -MF "$(DEPDIR)/gdimage.Tpo" \2.110 +@am__fastdepCC_TRUE@ -c -o gdimage.o `test -f 'gdrom/gdimage.c' || echo '$(srcdir)/'`gdrom/gdimage.c; \2.111 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gdimage.Tpo" "$(DEPDIR)/gdimage.Po"; \2.112 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/gdimage.Tpo"; exit 1; \2.113 +@am__fastdepCC_TRUE@ fi2.114 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gdrom/gdimage.c' object='gdimage.o' libtool=no @AMDEPBACKSLASH@2.115 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gdimage.Po' tmpdepfile='$(DEPDIR)/gdimage.TPo' @AMDEPBACKSLASH@2.116 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.117 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gdimage.o `test -f 'gdrom/gdimage.c' || echo '$(srcdir)/'`gdrom/gdimage.c2.118 +2.119 +gdimage.obj: gdrom/gdimage.c2.120 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gdimage.obj -MD -MP -MF "$(DEPDIR)/gdimage.Tpo" \2.121 +@am__fastdepCC_TRUE@ -c -o gdimage.obj `if test -f 'gdrom/gdimage.c'; then $(CYGPATH_W) 'gdrom/gdimage.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/gdimage.c'; fi`; \2.122 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gdimage.Tpo" "$(DEPDIR)/gdimage.Po"; \2.123 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/gdimage.Tpo"; exit 1; \2.124 +@am__fastdepCC_TRUE@ fi2.125 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gdrom/gdimage.c' object='gdimage.obj' libtool=no @AMDEPBACKSLASH@2.126 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gdimage.Po' tmpdepfile='$(DEPDIR)/gdimage.TPo' @AMDEPBACKSLASH@2.127 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@2.128 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gdimage.obj `if test -f 'gdrom/gdimage.c'; then $(CYGPATH_W) 'gdrom/gdimage.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/gdimage.c'; fi`2.129 +2.130 gdrom.o: gdrom/gdrom.c2.131 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gdrom.o -MD -MP -MF "$(DEPDIR)/gdrom.Tpo" \2.132 @am__fastdepCC_TRUE@ -c -o gdrom.o `test -f 'gdrom/gdrom.c' || echo '$(srcdir)/'`gdrom/gdrom.c; \
3.1 --- a/src/asic.c Wed Jan 31 10:32:25 2007 +00003.2 +++ b/src/asic.c Wed Jan 31 10:58:42 2007 +00003.3 @@ -1,5 +1,5 @@3.4 /**3.5 - * $Id: asic.c,v 1.27 2007-01-27 12:02:54 nkeynes Exp $3.6 + * $Id: asic.c,v 1.28 2007-01-31 10:58:42 nkeynes Exp $3.7 *3.8 * Support for the miscellaneous ASIC functions (Primarily event multiplexing,3.9 * and DMA).3.10 @@ -532,7 +532,7 @@3.11 case IDEDATA: return ide_read_data_pio( );3.12 case IDEFEAT: return idereg.error;3.13 case IDECOUNT:return idereg.count;3.14 - case IDELBA0: return idereg.disc;3.15 + case IDELBA0: return ide_get_drive_status();3.16 case IDELBA1: return idereg.lba1;3.17 case IDELBA2: return idereg.lba2;3.18 case IDEDEV: return idereg.device;
4.1 --- a/src/gdrom/cdi.c Wed Jan 31 10:32:25 2007 +00004.2 +++ b/src/gdrom/cdi.c Wed Jan 31 10:58:42 2007 +00004.3 @@ -1,5 +1,5 @@4.4 /**4.5 - * $Id: cdi.c,v 1.4 2006-12-14 11:58:18 nkeynes Exp $4.6 + * $Id: cdi.c,v 1.5 2007-01-31 10:58:42 nkeynes Exp $4.7 *4.8 * CDI CD-image file support4.9 *4.10 @@ -74,6 +74,7 @@4.11 gdrom_disc_t cdi_image_open( const gchar *filename, FILE *f )4.12 {4.13 gdrom_disc_t disc = NULL;4.14 + gdrom_image_t image;4.15 int fd = -1, i,j, tmp;4.16 uint16_t session_count;4.17 uint16_t track_count;4.18 @@ -100,6 +101,12 @@4.19 fread( &session_count, sizeof(session_count), 1, f );4.21 disc = gdrom_image_new(f);4.22 + if( disc == NULL ) {4.23 + fclose(f);4.24 + ERROR("Unable to allocate memory!");4.25 + return NULL;4.26 + }4.27 + image = (gdrom_image_t)disc;4.29 for( i=0; i< session_count; i++ ) {4.30 fread( &track_count, sizeof(track_count), 1, f );4.31 @@ -114,63 +121,63 @@4.32 fread( marker, 20, 1, f );4.33 if( memcmp( marker, track_start_marker, 20) != 0 ) {4.34 ERROR( "Track start marker not found, error reading cdi image\n" );4.35 - free(disc);4.36 + disc->close(disc);4.37 return NULL;4.38 }4.39 fseek( f, 4, SEEK_CUR );4.40 fread( &fnamelen, 1, 1, f );4.41 fseek( f, (int)fnamelen, SEEK_CUR ); /* skip over the filename */4.42 fread( &trk, sizeof(trk), 1, f );4.43 - disc->track[total_tracks].session = i;4.44 - disc->track[total_tracks].lba = trk.start_lba + 150;4.45 - disc->track[total_tracks].sector_count = trk.length;4.46 + image->track[total_tracks].session = i;4.47 + image->track[total_tracks].lba = trk.start_lba + 150;4.48 + image->track[total_tracks].sector_count = trk.length;4.49 switch( trk.mode ) {4.50 case 0:4.51 - disc->track[total_tracks].mode = GDROM_CDDA;4.52 - disc->track[total_tracks].sector_size = 2352;4.53 - disc->track[total_tracks].flags = 0x01;4.54 + image->track[total_tracks].mode = GDROM_CDDA;4.55 + image->track[total_tracks].sector_size = 2352;4.56 + image->track[total_tracks].flags = 0x01;4.57 if( trk.sector_size != 2 ) {4.58 ERROR( "Invalid combination of mode %d with size %d", trk.mode, trk.sector_size );4.59 - free(disc);4.60 + disc->close(disc);4.61 return NULL;4.62 }4.63 break;4.64 case 1:4.65 - disc->track[total_tracks].mode = GDROM_MODE1;4.66 - disc->track[total_tracks].sector_size = 2048;4.67 - disc->track[total_tracks].flags = 0x41;4.68 + image->track[total_tracks].mode = GDROM_MODE1;4.69 + image->track[total_tracks].sector_size = 2048;4.70 + image->track[total_tracks].flags = 0x41;4.71 if( trk.sector_size != 0 ) {4.72 ERROR( "Invalid combination of mode %d with size %d", trk.mode, trk.sector_size );4.73 - free(disc);4.74 + disc->close(disc);4.75 return NULL;4.76 }4.77 break;4.78 case 2:4.79 - disc->track[total_tracks].flags = 0x41;4.80 + image->track[total_tracks].flags = 0x41;4.81 switch( trk.sector_size ) {4.82 case 0:4.83 - disc->track[total_tracks].mode = GDROM_MODE2_XA1;4.84 - disc->track[total_tracks].sector_size = 2048;4.85 + image->track[total_tracks].mode = GDROM_MODE2_XA1;4.86 + image->track[total_tracks].sector_size = 2048;4.87 break;4.88 case 1:4.89 - disc->track[total_tracks].mode = GDROM_MODE2;4.90 - disc->track[total_tracks].sector_size = 2336;4.91 + image->track[total_tracks].mode = GDROM_MODE2;4.92 + image->track[total_tracks].sector_size = 2336;4.93 break;4.94 case 2:4.95 default:4.96 ERROR( "Invalid combination of mode %d with size %d", trk.mode, trk.sector_size );4.97 - free(disc);4.98 + disc->close(disc);4.99 return NULL;4.100 }4.101 break;4.102 default:4.103 ERROR( "Unsupported track mode %d", trk.mode );4.104 - free(disc);4.105 + disc->close(disc);4.106 return NULL;4.107 }4.108 - disc->track[total_tracks].offset = posn +4.109 - trk.pregap_length * disc->track[total_tracks].sector_size ;4.110 - posn += trk.total_length * disc->track[total_tracks].sector_size;4.111 + image->track[total_tracks].offset = posn +4.112 + trk.pregap_length * image->track[total_tracks].sector_size ;4.113 + posn += trk.total_length * image->track[total_tracks].sector_size;4.114 total_tracks++;4.115 lseek( fd, 12, SEEK_CUR );4.116 if( new_fmt ) {4.117 @@ -180,8 +187,7 @@4.118 }4.119 }4.120 }4.121 - disc->track_count = total_tracks;4.122 - disc->file = f;4.123 - disc->filename = filename;4.124 + image->track_count = total_tracks;4.125 + image->filename = filename;4.126 return disc;4.127 }
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00005.2 +++ b/src/gdrom/gdimage.c Wed Jan 31 10:58:42 2007 +00005.3 @@ -0,0 +1,233 @@5.4 +/**5.5 + * $Id: gdimage.c,v 1.1 2007-01-31 10:58:42 nkeynes Exp $5.6 + *5.7 + * GD-Rom image-file common functions.5.8 + *5.9 + * Copyright (c) 2005 Nathan Keynes.5.10 + *5.11 + * This program is free software; you can redistribute it and/or modify5.12 + * it under the terms of the GNU General Public License as published by5.13 + * the Free Software Foundation; either version 2 of the License, or5.14 + * (at your option) any later version.5.15 + *5.16 + * This program is distributed in the hope that it will be useful,5.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of5.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the5.19 + * GNU General Public License for more details.5.20 + */5.21 +5.22 +#include "gdrom/gdrom.h"5.23 +#include "gdrom/packet.h"5.24 +5.25 +static void gdrom_image_destroy( gdrom_disc_t disc );5.26 +static gdrom_error_t gdrom_image_read_sector( gdrom_disc_t disc, uint32_t lba, int mode,5.27 + char *buf, uint32_t *readlength );5.28 +static gdrom_error_t gdrom_image_read_toc( gdrom_disc_t disc, char *buf );5.29 +static gdrom_error_t gdrom_image_read_session( gdrom_disc_t disc, int session, char *buf );5.30 +static gdrom_error_t gdrom_image_read_position( gdrom_disc_t disc, uint32_t lba, char *buf );5.31 +static int gdrom_image_drive_status( gdrom_disc_t disc );5.32 +5.33 +5.34 +/**5.35 + * Initialize a gdrom_disc structure with the gdrom_image_* methods5.36 + */5.37 +void gdrom_image_init( gdrom_disc_t disc )5.38 +{5.39 + memset( disc, 0, sizeof(struct gdrom_disc) ); /* safety */5.40 + disc->read_sector = gdrom_image_read_sector;5.41 + disc->read_toc = gdrom_image_read_toc;5.42 + disc->read_session = gdrom_image_read_session;5.43 + disc->read_position = gdrom_image_read_position;5.44 + disc->drive_status = gdrom_image_drive_status;5.45 + disc->play_audio = NULL; /* not supported yet */5.46 + disc->run_time_slice = NULL; /* not needed */5.47 + disc->close = gdrom_image_destroy;5.48 +}5.49 +5.50 +gdrom_disc_t gdrom_image_new( FILE *f )5.51 +{5.52 + gdrom_image_t image = (gdrom_image_t)calloc(sizeof(struct gdrom_image), 1);5.53 + if( image == NULL ) {5.54 + return NULL;5.55 + }5.56 + image->disc_type = IDE_DISC_CDROM;5.57 + image->file = f;5.58 +5.59 + gdrom_disc_t disc = (gdrom_disc_t)image;5.60 + gdrom_image_init(disc);5.61 + return disc;5.62 +}5.63 +5.64 +static void gdrom_image_destroy( gdrom_disc_t disc )5.65 +{5.66 + gdrom_image_t img = (gdrom_image_t)disc;5.67 + if( img->file != NULL ) {5.68 + fclose(img->file);5.69 + img->file = NULL;5.70 + }5.71 + free( disc );5.72 +}5.73 +5.74 +static int gdrom_image_get_track_by_lba( gdrom_image_t image, uint32_t lba )5.75 +{5.76 + int i;5.77 + for( i=0; i<image->track_count; i++ ) {5.78 + if( image->track[i].lba <= lba &&5.79 + lba < (image->track[i].lba + image->track[i].sector_count) ) {5.80 + return i+1;5.81 + }5.82 + }5.83 + return -1;5.84 +}5.85 +5.86 +static gdrom_error_t gdrom_image_read_sector( gdrom_disc_t disc, uint32_t lba,5.87 + int mode, char *buf, uint32_t *length )5.88 +{5.89 + gdrom_image_t image = (gdrom_image_t)disc;5.90 + int i, file_offset, read_len, track_no;5.91 +5.92 + track_no = gdrom_image_get_track_by_lba( image, lba );5.93 + if( track_no == -1 ) {5.94 + return PKT_ERR_BADREAD;5.95 + }5.96 + struct gdrom_track *track = &image->track[track_no-1];5.97 + file_offset = track->offset + track->sector_size * (lba - track->lba);5.98 + read_len = track->sector_size;5.99 +5.100 + switch( mode ) {5.101 + case 0x24:5.102 + case 0x28:5.103 + switch( track->mode ) {5.104 + case GDROM_MODE1:5.105 + case GDROM_MODE2_XA1:5.106 + fseek( image->file, file_offset, SEEK_SET );5.107 + fread( buf, track->sector_size, 1, image->file );5.108 + break;5.109 + case GDROM_MODE2:5.110 + read_len = 2048;5.111 + file_offset += 8; /* skip the subheader */5.112 + fseek( image->file, file_offset, SEEK_SET );5.113 + fread( buf, 2048, 1, image->file );5.114 + break;5.115 + default:5.116 + return PKT_ERR_BADREADMODE;5.117 + }5.118 + break;5.119 + default:5.120 + return PKT_ERR_BADREADMODE;5.121 + }5.122 +5.123 + *length = read_len;5.124 + return PKT_ERR_OK;5.125 +5.126 +}5.127 +5.128 +static gdrom_error_t gdrom_image_read_toc( gdrom_disc_t disc, char *buf )5.129 +{5.130 + gdrom_image_t image = (gdrom_image_t)disc;5.131 + struct gdrom_toc *toc = (struct gdrom_toc *)buf;5.132 + int i;5.133 +5.134 + for( i=0; i<image->track_count; i++ ) {5.135 + toc->track[i] = htonl( image->track[i].lba ) | image->track[i].flags;5.136 + }5.137 + toc->first = 0x0100 | image->track[0].flags;5.138 + toc->last = (image->track_count<<8) | image->track[i-1].flags;5.139 + toc->leadout = htonl(image->track[i-1].lba + image->track[i-1].sector_count) |5.140 + image->track[i-1].flags;5.141 + for( ;i<99; i++ )5.142 + toc->track[i] = 0xFFFFFFFF;5.143 + return PKT_ERR_OK;5.144 +}5.145 +5.146 +static gdrom_error_t gdrom_image_read_session( gdrom_disc_t disc, int session, char *buf )5.147 +{5.148 + gdrom_image_t image = (gdrom_image_t)disc;5.149 + struct gdrom_track *last_track = &image->track[image->track_count-1];5.150 + unsigned int end_of_disc = last_track->lba + last_track->sector_count;5.151 + int i;5.152 + buf[0] = 0x01; /* Disc status? */5.153 + buf[1] = 0;5.154 +5.155 + if( session == 0 ) {5.156 + buf[2] = last_track->session+1; /* last session */5.157 + buf[3] = (end_of_disc >> 16) & 0xFF;5.158 + buf[4] = (end_of_disc >> 8) & 0xFF;5.159 + buf[5] = end_of_disc & 0xFF;5.160 + return PKT_ERR_OK;5.161 + } else {5.162 + session--;5.163 + for( i=0; i<image->track_count; i++ ) {5.164 + if( image->track[i].session == session ) {5.165 + buf[2] = i+1; /* first track of session */5.166 + buf[3] = (image->track[i].lba >> 16) & 0xFF;5.167 + buf[4] = (image->track[i].lba >> 8) & 0xFF;5.168 + buf[5] = image->track[i].lba & 0xFF;5.169 + return PKT_ERR_OK;5.170 + }5.171 + }5.172 + return PKT_ERR_BADFIELD; /* No such session */5.173 + }5.174 +}5.175 +5.176 +static gdrom_error_t gdrom_image_read_position( gdrom_disc_t disc, uint32_t lba, char *buf )5.177 +{5.178 + gdrom_image_t image = (gdrom_image_t)disc;5.179 + int track_no = gdrom_image_get_track_by_lba( image, lba );5.180 + if( track_no == -1 ) {5.181 + track_no = 1;5.182 + lba = 150;5.183 + }5.184 + struct gdrom_track *track = &image->track[track_no-1];5.185 + uint32_t offset = lba - track->lba;5.186 + buf[4] = track->flags;5.187 + buf[5] = track_no;5.188 + buf[6] = 0x01; /* ?? */5.189 + buf[7] = (offset >> 16) & 0xFF;5.190 + buf[8] = (offset >> 8) & 0xFF;5.191 + buf[9] = offset & 0xFF;5.192 + buf[10] = 0;5.193 + buf[11] = (lba >> 16) & 0xFF;5.194 + buf[12] = (lba >> 8) & 0xFF;5.195 + buf[13] = lba & 0xFF;5.196 +}5.197 +5.198 +static int gdrom_image_drive_status( gdrom_disc_t disc )5.199 +{5.200 + gdrom_image_t image = (gdrom_image_t)disc;5.201 + return image->disc_type | IDE_DISC_READY;5.202 +}5.203 +5.204 +void gdrom_image_dump_info( gdrom_disc_t d ) {5.205 + gdrom_image_t disc = (gdrom_image_t)d;5.206 + int i;5.207 + int last_session = disc->track[disc->track_count-1].session;5.208 + gboolean is_bootable = FALSE;5.209 +5.210 + INFO( "Disc ID: %s, %d tracks in %d sessions", disc->mcn, disc->track_count,5.211 + disc->track[disc->track_count-1].session + 1 );5.212 + if( last_session > 0 ) {5.213 + /* Boot track is the first data track of the last session, provided that it5.214 + * cannot be a single-session disc.5.215 + */5.216 + int boot_track = -1;5.217 + for( i=disc->track_count-1; i>=0 && disc->track[i].session == last_session; i-- ) {5.218 + if( disc->track[i].flags & TRACK_DATA ) {5.219 + boot_track = i;5.220 + }5.221 + }5.222 + if( boot_track != -1 ) {5.223 + char boot_sector[MAX_SECTOR_SIZE];5.224 + uint32_t length = sizeof(boot_sector);5.225 + if( d->read_sector( d, disc->track[boot_track].lba, 0x28,5.226 + boot_sector, &length ) == PKT_ERR_OK ) {5.227 + bootstrap_dump(boot_sector, FALSE);5.228 + is_bootable = TRUE;5.229 + }5.230 + }5.231 + }5.232 + if( !is_bootable ) {5.233 + WARN( "Disc does not appear to be bootable" );5.234 + }5.235 +}5.236 +
6.1 --- a/src/gdrom/gdrom.c Wed Jan 31 10:32:25 2007 +00006.2 +++ b/src/gdrom/gdrom.c Wed Jan 31 10:58:42 2007 +00006.3 @@ -1,5 +1,6 @@6.4 +6.5 /**6.6 - * $Id: gdrom.c,v 1.11 2006-12-19 09:52:56 nkeynes Exp $6.7 + * $Id: gdrom.c,v 1.12 2007-01-31 10:58:42 nkeynes Exp $6.8 *6.9 * GD-Rom access functions.6.10 *6.11 @@ -24,13 +25,10 @@6.12 #include "gdrom/packet.h"6.13 #include "dream.h"6.15 -static void gdrom_image_destroy( gdrom_disc_t );6.16 -static gdrom_error_t gdrom_image_read_sectors( gdrom_disc_t, uint32_t, uint32_t, int, char *, uint32_t * );6.17 +extern gdrom_disc_t gdrom_disc;6.19 gdrom_image_class_t gdrom_image_classes[] = { &linux_device_class, &nrg_image_class, &cdi_image_class, NULL };6.21 -gdrom_disc_t gdrom_disc = NULL;6.22 -6.23 char *gdrom_mode_names[] = { "Mode1", "Mode2", "XA 1", "XA2", "Audio", "GD-Rom" };6.24 uint32_t gdrom_sector_size[] = { 2048, 2336, 2048, 2324, 2352, 2336 };6.26 @@ -88,204 +86,11 @@6.27 return NULL;6.28 }6.30 -6.31 -gdrom_disc_t gdrom_image_new( FILE *file )6.32 -{6.33 - struct gdrom_disc *disc = (struct gdrom_disc *)calloc(1, sizeof(struct gdrom_disc));6.34 - if( disc == NULL )6.35 - return NULL;6.36 - disc->read_sectors = gdrom_image_read_sectors;6.37 - disc->close = gdrom_image_destroy;6.38 - disc->disc_type = IDE_DISC_CDROM;6.39 - disc->file = file;6.40 - return disc;6.41 -}6.42 -6.43 -static void gdrom_image_destroy( gdrom_disc_t disc )6.44 -{6.45 - if( disc->file != NULL ) {6.46 - fclose(disc->file);6.47 - disc->file = NULL;6.48 - }6.49 - free( disc );6.50 -}6.51 -6.52 -static gdrom_error_t gdrom_image_read_sectors( gdrom_disc_t disc, uint32_t sector,6.53 - uint32_t sector_count, int mode, char *buf,6.54 - uint32_t *length )6.55 -{6.56 - int i, file_offset, read_len;6.57 - struct gdrom_track *track = NULL;6.58 -6.59 - for( i=0; i<disc->track_count; i++ ) {6.60 - if( disc->track[i].lba <= sector &&6.61 - (sector + sector_count) <= (disc->track[i].lba + disc->track[i].sector_count) ) {6.62 - track = &disc->track[i];6.63 - break;6.64 - }6.65 - }6.66 - if( track == NULL )6.67 - return PKT_ERR_BADREAD;6.68 -6.69 - file_offset = track->offset + track->sector_size * (sector - track->lba);6.70 - read_len = track->sector_size * sector_count;6.71 -6.72 - switch( mode ) {6.73 - case GDROM_GD:6.74 - // Temporarily comment this out - it's wrong, but...6.75 - // if( track->mode != GDROM_GD )6.76 - // return PKT_ERR_BADREADMODE;6.77 - // break;6.78 - case GDROM_MODE1:6.79 - case GDROM_MODE2_XA1:6.80 - switch( track->mode ) {6.81 - case GDROM_MODE1:6.82 - case GDROM_MODE2_XA1:6.83 - fseek( disc->file, file_offset, SEEK_SET );6.84 - fread( buf, track->sector_size, sector_count, disc->file );6.85 - break;6.86 - case GDROM_MODE2:6.87 - read_len = sector_count * 2048;6.88 - file_offset += 8; /* skip the subheader */6.89 - while( sector_count > 0 ) {6.90 - fseek( disc->file, file_offset, SEEK_SET );6.91 - fread( buf, 2048, 1, disc->file );6.92 - file_offset += track->sector_size;6.93 - buf += 2048;6.94 - sector_count--;6.95 - }6.96 - break;6.97 - default:6.98 - return PKT_ERR_BADREADMODE;6.99 - }6.100 - break;6.101 - default:6.102 - return PKT_ERR_BADREADMODE;6.103 - }6.104 -6.105 - *length = read_len;6.106 - return PKT_ERR_OK;6.107 -}6.108 -6.109 -uint32_t gdrom_read_sectors( uint32_t sector, uint32_t sector_count,6.110 - int mode, char *buf, uint32_t *length )6.111 -{6.112 - if( gdrom_disc == NULL )6.113 - return PKT_ERR_NODISC; /* No media */6.114 - return gdrom_disc->read_sectors( gdrom_disc, sector, sector_count, mode, buf, length );6.115 -}6.116 -6.117 -6.118 -void gdrom_dump_disc_info( gdrom_disc_t disc ) {6.119 - int i;6.120 - int last_session = disc->track[disc->track_count-1].session;6.121 - gboolean is_bootable = FALSE;6.122 -6.123 - INFO( "Disc ID: %s, %d tracks in %d sessions", disc->mcn, disc->track_count,6.124 - disc->track[disc->track_count-1].session + 1 );6.125 - if( last_session > 0 ) {6.126 - /* Boot track is the first data track of the last session, provided that it6.127 - * cannot be a single-session disc.6.128 - */6.129 - int boot_track = -1;6.130 - for( i=disc->track_count-1; i>=0 && disc->track[i].session == last_session; i-- ) {6.131 - if( disc->track[i].flags & TRACK_DATA ) {6.132 - boot_track = i;6.133 - }6.134 - }6.135 - if( boot_track != -1 ) {6.136 - char boot_sector[2048];6.137 - uint32_t length = sizeof(boot_sector);6.138 - if( disc->read_sectors( disc, disc->track[boot_track].lba, 1, GDROM_MODE1,6.139 - boot_sector, &length ) == PKT_ERR_OK ) {6.140 - bootstrap_dump(boot_sector, FALSE);6.141 - is_bootable = TRUE;6.142 - }6.143 - }6.144 - }6.145 - if( !is_bootable )6.146 - WARN( "Disc does not appear to be bootable" );6.147 -}6.148 -6.149 -gdrom_error_t gdrom_get_toc( char *buf )6.150 -{6.151 - struct gdrom_toc *toc = (struct gdrom_toc *)buf;6.152 - int i;6.153 -6.154 - if( gdrom_disc == NULL )6.155 - return PKT_ERR_NODISC;6.156 -6.157 - for( i=0; i<gdrom_disc->track_count; i++ ) {6.158 - toc->track[i] = htonl( gdrom_disc->track[i].lba ) | gdrom_disc->track[i].flags;6.159 - }6.160 - toc->first = 0x0100 | gdrom_disc->track[0].flags;6.161 - toc->last = (gdrom_disc->track_count<<8) | gdrom_disc->track[i-1].flags;6.162 - toc->leadout = htonl(gdrom_disc->track[i-1].lba + gdrom_disc->track[i-1].sector_count) |6.163 - gdrom_disc->track[i-1].flags;6.164 - for( ;i<99; i++ )6.165 - toc->track[i] = 0xFFFFFFFF;6.166 - return PKT_ERR_OK;6.167 -}6.168 -6.169 -gdrom_error_t gdrom_get_info( char *buf, int session )6.170 -{6.171 - if( gdrom_disc == NULL )6.172 - return PKT_ERR_NODISC;6.173 - struct gdrom_track *last_track = &gdrom_disc->track[gdrom_disc->track_count-1];6.174 - unsigned int end_of_disc = last_track->lba + last_track->sector_count;6.175 - int i;6.176 - buf[0] = 0x01; /* Disc status? */6.177 - buf[1] = 0;6.178 -6.179 - if( session == 0 ) {6.180 - buf[2] = last_track->session+1; /* last session */6.181 - buf[3] = (end_of_disc >> 16) & 0xFF;6.182 - buf[4] = (end_of_disc >> 8) & 0xFF;6.183 - buf[5] = end_of_disc & 0xFF;6.184 - return PKT_ERR_OK;6.185 - } else {6.186 - session--;6.187 - for( i=0; i<gdrom_disc->track_count; i++ ) {6.188 - if( gdrom_disc->track[i].session == session ) {6.189 - buf[2] = i+1; /* first track of session */6.190 - buf[3] = (gdrom_disc->track[i].lba >> 16) & 0xFF;6.191 - buf[4] = (gdrom_disc->track[i].lba >> 8) & 0xFF;6.192 - buf[5] = gdrom_disc->track[i].lba & 0xFF;6.193 - return PKT_ERR_OK;6.194 - }6.195 - }6.196 - return PKT_ERR_BADFIELD; /* No such session */6.197 - }6.198 -6.199 -}6.200 -6.201 -gdrom_track_t gdrom_get_track( int trackno ) {6.202 - if( gdrom_disc == NULL || trackno < 1 || trackno > 99 ) {6.203 - return NULL;6.204 - } else {6.205 - return &gdrom_disc->track[trackno-1];6.206 - }6.207 -}6.208 -6.209 -uint8_t gdrom_get_track_no_by_lba( uint32_t lba ) {6.210 - int i;6.211 - if( gdrom_disc != NULL ) {6.212 - for( i=0; i<gdrom_disc->track_count; i++ ) {6.213 - if( gdrom_disc->track[i].lba <= lba &&6.214 - lba <= (gdrom_disc->track[i].lba + gdrom_disc->track[i].sector_count) ) {6.215 - return i+1;6.216 - }6.217 - }6.218 - }6.219 - return -1;6.220 -}6.221 -6.222 void gdrom_mount_disc( gdrom_disc_t disc )6.223 {6.224 gdrom_unmount_disc();6.225 gdrom_disc = disc;6.226 - idereg.disc = disc->disc_type | IDE_DISC_READY;6.227 - gdrom_dump_disc_info( disc );6.228 + gdrom_image_dump_info( disc );6.229 }6.231 gdrom_disc_t gdrom_mount_image( const gchar *filename )6.232 @@ -302,10 +107,6 @@6.233 gdrom_disc->close(gdrom_disc);6.234 }6.235 gdrom_disc = NULL;6.236 - idereg.disc = IDE_DISC_NONE;6.237 +6.238 }6.240 -gboolean gdrom_is_mounted( void )6.241 -{6.242 - return gdrom_disc != NULL;6.243 -}
7.1 --- a/src/gdrom/gdrom.h Wed Jan 31 10:32:25 2007 +00007.2 +++ b/src/gdrom/gdrom.h Wed Jan 31 10:58:42 2007 +00007.3 @@ -1,5 +1,5 @@7.4 /**7.5 - * $Id: gdrom.h,v 1.9 2006-12-19 09:52:56 nkeynes Exp $7.6 + * $Id: gdrom.h,v 1.10 2007-01-31 10:58:42 nkeynes Exp $7.7 *7.8 * This file defines the structures and functions used by the GD-Rom7.9 * disc driver. (ie, the modules that supply a CD image to be used by the7.10 @@ -23,6 +23,8 @@7.12 #include "dream.h"7.14 +#define MAX_SECTOR_SIZE 23527.15 +7.16 typedef uint16_t gdrom_error_t;7.18 struct gdrom_toc {7.19 @@ -69,19 +71,84 @@7.20 uint32_t offset; /* File offset of start of track - image files only */7.21 } *gdrom_track_t;7.23 +typedef struct gdrom_disc {7.24 + /**7.25 + * Read a single sector from the disc at the specified logical address.7.26 + * @param disc pointer to the disc structure7.27 + * @param lba logical address to read from7.28 + * @param mode mode field from the read command7.29 + * @param buf buffer to receive data (at least MAX_SECTOR_SIZE bytes)7.30 + * @param length unsigned int to receive the number of bytes actually read.7.31 + * @return PKT_ERR_OK on success, or another PKT_ERR_* code on failure.7.32 + */7.33 + gdrom_error_t (*read_sector)( struct gdrom_disc *disc,7.34 + uint32_t lba, int mode,7.35 + char *buf, uint32_t *length );7.36 +7.37 + /**7.38 + * Read the TOC from the disc and write it into the specified buffer.7.39 + * The method is responsible for returning the data in gd-rom7.40 + * format.7.41 + * @param disc pointer to the disc structure7.42 + * @param buf buffer to receive data (0x198 bytes long)7.43 + */7.44 + gdrom_error_t (*read_toc)(struct gdrom_disc *disc, char *buf);7.46 -typedef struct gdrom_disc {7.47 + /**7.48 + * Read the information for the specified sector and return it in the7.49 + * supplied buffer.7.50 + * @param disc pointer to the disc structure7.51 + * @param session of interest. If 0, return end of disc information.7.52 + * @param buf buffer to receive data (6 bytes)7.53 + */7.54 + gdrom_error_t (*read_session)(struct gdrom_disc *disc, int session, char *buf);7.55 +7.56 + /**7.57 + * Read the position information (subchannel) for the specified sector7.58 + * and return it in the supplied buffer. This method does not need to7.59 + * write the first 4 bytes of the buffer.7.60 + * @param disc pointer to the disc structure7.61 + * @param lba sector to get position information for7.62 + * @param buf buffer to receive data (14 bytes)7.63 + */7.64 + gdrom_error_t (*read_position)(struct gdrom_disc *disc, uint32_t lba, char *buf);7.65 +7.66 + /**7.67 + * Return the current disc status, expressed as a combination of the7.68 + * IDE_DISC_* flags above.7.69 + * @param disc pointer to the disc structure7.70 + * @return an integer status value.7.71 + */7.72 + int (*drive_status)(struct gdrom_disc *disc);7.73 +7.74 + /**7.75 + * Begin playing audio from the given lba address on the disc.7.76 + */7.77 + gdrom_error_t (*play_audio)(struct gdrom_disc *disc, uint32_t lba);7.78 +7.79 + /**7.80 + * Executed once per time slice to perform house-keeping operations7.81 + * (checking disc status, media changed, etc).7.82 + */7.83 + uint32_t (*run_time_slice)( struct gdrom_disc *disc, uint32_t nanosecs );7.84 +7.85 + /**7.86 + * Close the disc and release any storage or resources allocated including7.87 + * the disc structure itself.7.88 + */7.89 + void (*close)( struct gdrom_disc *disc );7.90 +} *gdrom_disc_t;7.91 +7.92 +7.93 +typedef struct gdrom_image {7.94 + struct gdrom_disc disc;7.95 int disc_type;7.96 int track_count;7.97 struct gdrom_track track[99];7.98 gchar mcn[14]; /* Media catalogue number */7.99 const gchar *filename; /* Image filename */7.100 - FILE *file; /* Stream, for image files */7.101 - gdrom_error_t (*read_sectors)( struct gdrom_disc *disc,7.102 - uint32_t lba, uint32_t sector_count,7.103 - int mode, char *buf, uint32_t *length );7.104 - void (*close)( struct gdrom_disc *disc );7.105 -} *gdrom_disc_t;7.106 + FILE *file; /* Open file stream */7.107 +} *gdrom_image_t;7.109 /**7.110 *
8.1 --- a/src/gdrom/ide.c Wed Jan 31 10:32:25 2007 +00008.2 +++ b/src/gdrom/ide.c Wed Jan 31 10:58:42 2007 +00008.3 @@ -1,5 +1,5 @@8.4 /**8.5 - * $Id: ide.c,v 1.22 2006-12-29 00:23:13 nkeynes Exp $8.6 + * $Id: ide.c,v 1.23 2007-01-31 10:58:42 nkeynes Exp $8.7 *8.8 * IDE interface implementation8.9 *8.10 @@ -36,18 +36,21 @@8.12 static void ide_init( void );8.13 static void ide_reset( void );8.14 +static uint32_t ide_run_slice( uint32_t nanosecs );8.15 static void ide_save_state( FILE *f );8.16 static int ide_load_state( FILE *f );8.17 static void ide_raise_interrupt( void );8.18 static void ide_clear_interrupt( void );8.19 static void ide_packet_command( unsigned char *data );8.20 +static void ide_read_next_sector(void);8.22 -struct dreamcast_module ide_module = { "IDE", ide_init, ide_reset, NULL, NULL,8.23 +struct dreamcast_module ide_module = { "IDE", ide_init, ide_reset, NULL, ide_run_slice,8.24 NULL, ide_save_state, ide_load_state };8.26 struct ide_registers idereg;8.27 -unsigned char *data_buffer = NULL;8.28 -uint32_t data_buffer_len = 0;8.29 +gdrom_disc_t gdrom_disc = NULL;8.30 +8.31 +unsigned char data_buffer[MAX_SECTOR_SIZE];8.33 #define WRITE_BUFFER(x16) *((uint16_t *)(data_buffer + idereg.data_offset)) = x168.34 #define READ_BUFFER() *((uint16_t *)(data_buffer + idereg.data_offset))8.35 @@ -129,9 +132,6 @@8.36 static void ide_init( void )8.37 {8.38 ide_reset();8.39 - data_buffer_len = DEFAULT_DATA_SECTORS;8.40 - data_buffer = malloc( MAX_SECTOR_SIZE * data_buffer_len );8.41 - assert( data_buffer != NULL );8.42 }8.44 static void ide_reset( void )8.45 @@ -145,36 +145,36 @@8.46 idereg.feature = 0; /* Indeterminate really */8.47 idereg.status = 0x00;8.48 idereg.device = 0x00;8.49 - idereg.disc = gdrom_is_mounted() ? (IDE_DISC_CDROM|IDE_DISC_READY) : IDE_DISC_NONE;8.50 idereg.state = IDE_STATE_IDLE;8.51 memset( idereg.gdrom_sense, '\0', 10 );8.52 idereg.data_offset = -1;8.53 idereg.data_length = -1;8.54 idereg.last_read_track = 1;8.55 - idereg.last_read_lba = 150;8.56 + idereg.read_lba = 150;8.57 + idereg.read_mode = 0x28;8.58 + idereg.sectors_left = 0;8.59 idereg.was_reset = TRUE;8.60 }8.62 +static uint32_t ide_run_slice( uint32_t nanosecs )8.63 +{8.64 + if( gdrom_disc != NULL && gdrom_disc->run_time_slice != NULL ) {8.65 + gdrom_disc->run_time_slice(gdrom_disc, nanosecs);8.66 + }8.67 + return nanosecs;8.68 +}8.69 +8.70 static void ide_save_state( FILE *f )8.71 {8.72 fwrite( &idereg, sizeof(idereg), 1, f );8.73 - fwrite( &data_buffer_len, sizeof(data_buffer_len), 1, f );8.74 - fwrite( data_buffer, MAX_SECTOR_SIZE, data_buffer_len, f );8.75 + fwrite( data_buffer, MAX_SECTOR_SIZE, 1, f );8.76 }8.78 static int ide_load_state( FILE *f )8.79 {8.80 uint32_t length;8.81 fread( &idereg, sizeof(idereg), 1, f );8.82 - fread( &length, sizeof(uint32_t), 1, f );8.83 - if( length > data_buffer_len ) {8.84 - if( data_buffer != NULL )8.85 - free( data_buffer );8.86 - data_buffer = malloc( MAX_SECTOR_SIZE * length );8.87 - assert( data_buffer != NULL );8.88 - data_buffer_len = length;8.89 - }8.90 - fread( data_buffer, MAX_SECTOR_SIZE, length, f );8.91 + fread( data_buffer, MAX_SECTOR_SIZE, 1, f );8.92 return 0;8.93 }8.95 @@ -212,7 +212,7 @@8.96 * Begin PIO read from the device. The data is assumed to already be8.97 * in the buffer at this point.8.98 */8.99 -static void ide_start_read( int length, int blocksize, gboolean dma )8.100 +static void ide_start_read( int length, gboolean dma )8.101 {8.102 idereg.count = IDE_COUNT_IO;8.103 idereg.data_length = length;8.104 @@ -223,18 +223,17 @@8.105 } else {8.106 idereg.state = IDE_STATE_PIO_READ;8.107 idereg.status = 0x58;8.108 - idereg.lba1 = blocksize & 0xFF;8.109 - idereg.lba2 = blocksize >> 8;8.110 - idereg.block_length = blocksize;8.111 - idereg.block_left = blocksize;8.112 + idereg.lba1 = length & 0xFF;8.113 + idereg.lba2 = length >> 8;8.114 ide_raise_interrupt( );8.115 }8.116 }8.118 -static void ide_start_packet_read( int length, int blocksize )8.119 +static void ide_start_packet_read( int length, int sector_count )8.120 {8.121 + idereg.sectors_left = sector_count;8.122 ide_set_packet_result( PKT_ERR_OK );8.123 - ide_start_read( length, blocksize, (idereg.feature & IDE_FEAT_DMA) ? TRUE : FALSE );8.124 + ide_start_read( length, (idereg.feature & IDE_FEAT_DMA) ? TRUE : FALSE );8.125 }8.127 static void ide_raise_interrupt( void )8.128 @@ -272,16 +271,15 @@8.129 if( idereg.state == IDE_STATE_PIO_READ ) {8.130 uint16_t rv = READ_BUFFER();8.131 idereg.data_offset += 2;8.132 - idereg.block_left -= 2;8.133 if( idereg.data_offset >= idereg.data_length ) {8.134 idereg.state = IDE_STATE_IDLE;8.135 idereg.status &= ~IDE_STATUS_DRQ;8.136 idereg.data_offset = -1;8.137 idereg.count = 3; /* complete */8.138 ide_raise_interrupt();8.139 - } else if( idereg.block_left <= 0 ) {8.140 - idereg.block_left = idereg.block_length;8.141 - ide_raise_interrupt();8.142 + if( idereg.sectors_left > 0 ) {8.143 + ide_read_next_sector();8.144 + }8.145 }8.146 return rv;8.147 } else {8.148 @@ -301,24 +299,34 @@8.149 */8.150 uint32_t ide_read_data_dma( uint32_t addr, uint32_t length )8.151 {8.152 + uint32_t xfercount = 0;8.153 if( idereg.state == IDE_STATE_DMA_READ ) {8.154 - int xferlen = length;8.155 - int remaining = idereg.data_length - idereg.data_offset;8.156 - if( xferlen > remaining )8.157 - xferlen = remaining;8.158 - mem_copy_to_sh4( addr, data_buffer + idereg.data_offset, xferlen );8.159 - idereg.data_offset += xferlen;8.160 - if( idereg.data_offset >= idereg.data_length ) {8.161 - idereg.data_offset = -1;8.162 - idereg.state = IDE_STATE_IDLE;8.163 - idereg.status = 0x50;8.164 - idereg.count = 0x03;8.165 - ide_raise_interrupt();8.166 - asic_event( EVENT_IDE_DMA );8.167 + while( xfercount < length ) {8.168 + int xferlen = length - xfercount;8.169 + int remaining = idereg.data_length - idereg.data_offset;8.170 + if( xferlen > remaining ) {8.171 + xferlen = remaining;8.172 + }8.173 + mem_copy_to_sh4( addr, data_buffer + idereg.data_offset, xferlen );8.174 + xfercount += xferlen;8.175 + addr += xferlen;8.176 + idereg.data_offset += xferlen;8.177 + if( idereg.data_offset >= idereg.data_length ) {8.178 + if( idereg.sectors_left > 0 ) {8.179 + ide_read_next_sector();8.180 + } else {8.181 + idereg.data_offset = -1;8.182 + idereg.state = IDE_STATE_IDLE;8.183 + idereg.status = 0x50;8.184 + idereg.count = 0x03;8.185 + ide_raise_interrupt();8.186 + asic_event( EVENT_IDE_DMA );8.187 + break;8.188 + }8.189 + }8.190 }8.191 - return xferlen;8.192 }8.193 - return 0;8.194 + return xfercount;8.195 }8.197 void ide_write_data_pio( uint16_t val ) {8.198 @@ -405,6 +413,40 @@8.199 }8.200 }8.202 +uint8_t ide_get_drive_status( void )8.203 +{8.204 + if( gdrom_disc == NULL ) {8.205 + return IDE_DISC_NONE;8.206 + } else {8.207 + return gdrom_disc->drive_status(gdrom_disc);8.208 + }8.209 +}8.210 +8.211 +#define REQUIRE_DISC() if( gdrom_disc == NULL ) { ide_set_packet_result( PKT_ERR_NODISC ); return; }8.212 +8.213 +/**8.214 + * Read the next sector from the active read, if any8.215 + */8.216 +static void ide_read_next_sector( void )8.217 +{8.218 + int sector_size;8.219 + REQUIRE_DISC();8.220 + gdrom_error_t status =8.221 + gdrom_disc->read_sector( gdrom_disc, idereg.read_lba, idereg.read_mode,8.222 + data_buffer, §or_size );8.223 + if( status != PKT_ERR_OK ) {8.224 + ide_set_packet_result( status );8.225 + idereg.gdrom_sense[5] = (idereg.read_lba >> 16) & 0xFF;8.226 + idereg.gdrom_sense[6] = (idereg.read_lba >> 8) & 0xFF;8.227 + idereg.gdrom_sense[7] = idereg.read_lba & 0xFF;8.228 + WARN( " => Read CD returned sense key %02X, %02X", status & 0xFF, status >> 8 );8.229 + } else {8.230 + idereg.read_lba++;8.231 + idereg.sectors_left--;8.232 + ide_start_read( sector_size, (idereg.feature & IDE_FEAT_DMA) ? TRUE : FALSE );8.233 + }8.234 +}8.235 +8.236 /**8.237 * Execute a packet command. This particular method is responsible for parsing8.238 * the command buffers (12 bytes), and generating the appropriate responses,8.239 @@ -415,7 +457,6 @@8.240 uint32_t length, datalen;8.241 uint32_t lba, status;8.242 int mode;8.243 - int blocksize = idereg.lba1 + (idereg.lba2<<8);8.245 /* Okay we have the packet in the command buffer */8.246 INFO( "ATAPI packet: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",8.247 @@ -430,13 +471,10 @@8.249 switch( cmd[0] ) {8.250 case PKT_CMD_TEST_READY:8.251 - if( !gdrom_is_mounted() ) {8.252 - ide_set_packet_result( PKT_ERR_NODISC );8.253 - } else {8.254 - ide_set_packet_result( 0 );8.255 - ide_raise_interrupt();8.256 - idereg.status = 0x50;8.257 - }8.258 + REQUIRE_DISC();8.259 + ide_set_packet_result( 0 );8.260 + ide_raise_interrupt();8.261 + idereg.status = 0x50;8.262 break;8.263 case PKT_CMD_IDENTIFY:8.264 lba = cmd[2];8.265 @@ -447,7 +485,7 @@8.266 if( lba+length > sizeof(gdrom_ident) )8.267 length = sizeof(gdrom_ident) - lba;8.268 memcpy( data_buffer, gdrom_ident + lba, length );8.269 - ide_start_packet_read( length, length );8.270 + ide_start_packet_read( length, 0 );8.271 }8.272 break;8.273 case PKT_CMD_SENSE:8.274 @@ -455,112 +493,74 @@8.275 if( length > 10 )8.276 length = 10;8.277 memcpy( data_buffer, idereg.gdrom_sense, length );8.278 - ide_start_packet_read( length, length );8.279 + ide_start_packet_read( length, 0 );8.280 break;8.281 case PKT_CMD_READ_TOC:8.282 + REQUIRE_DISC();8.283 length = (cmd[3]<<8) | cmd[4];8.284 if( length > sizeof(struct gdrom_toc) )8.285 length = sizeof(struct gdrom_toc);8.287 - status = gdrom_get_toc( data_buffer );8.288 + status = gdrom_disc->read_toc( gdrom_disc, data_buffer );8.289 if( status != PKT_ERR_OK ) {8.290 ide_set_packet_result( status );8.291 } else {8.292 - ide_start_packet_read( length, length );8.293 + ide_start_packet_read( length, 0 );8.294 }8.295 break;8.296 case PKT_CMD_SESSION_INFO:8.297 + REQUIRE_DISC();8.298 length = cmd[4];8.299 if( length > 6 )8.300 length = 6;8.301 - status = gdrom_get_info( data_buffer, cmd[2] );8.302 + status = gdrom_disc->read_session( gdrom_disc, cmd[2], data_buffer );8.303 if( status != PKT_ERR_OK ) {8.304 ide_set_packet_result( status );8.305 } else {8.306 - ide_start_packet_read( length, length );8.307 + ide_start_packet_read( length, 0 );8.308 }8.309 break;8.310 - case PKT_CMD_PLAY_CD:8.311 + case PKT_CMD_PLAY_AUDIO:8.312 + REQUIRE_DISC();8.313 ide_set_packet_result( 0 );8.314 ide_raise_interrupt();8.315 idereg.status = 0x50;8.316 break;8.317 case PKT_CMD_READ_SECTOR:8.318 - lba = cmd[2] << 16 | cmd[3] << 8 | cmd[4];8.319 - length = cmd[8] << 16 | cmd[9] << 8 | cmd[10]; /* blocks */8.320 - switch( cmd[1] ) {8.321 - case 0x20: mode = GDROM_MODE1; break; /* TODO - might be unchecked? */8.322 - case 0x24: mode = GDROM_GD; break;8.323 - case 0x28: mode = GDROM_MODE2_XA1; break; /* ??? */8.324 - case 0x30: mode = GDROM_RAW; break;8.325 - default:8.326 - ERROR( "Unrecognized read mode '%02X' in GD-Rom read request", cmd[1] );8.327 - ide_set_packet_result( PKT_ERR_BADFIELD );8.328 - return;8.329 - }8.330 -8.331 - if( length > data_buffer_len ) {8.332 - do {8.333 - data_buffer_len = data_buffer_len << 1;8.334 - } while( data_buffer_len < length );8.335 - data_buffer = realloc( data_buffer, MAX_SECTOR_SIZE * data_buffer_len );8.336 - }8.337 -8.338 - datalen = data_buffer_len;8.339 - status = gdrom_read_sectors( lba, length, mode, data_buffer, &datalen );8.340 - if( status != 0 ) {8.341 - ide_set_packet_result( status );8.342 - idereg.gdrom_sense[5] = (lba >> 16) & 0xFF;8.343 - idereg.gdrom_sense[6] = (lba >> 8) & 0xFF;8.344 - idereg.gdrom_sense[7] = lba & 0xFF;8.345 - WARN( " => Read CD returned sense key %02X, %02X", status & 0xFF, status >> 8 );8.346 - } else {8.347 - idereg.last_read_lba = lba + length;8.348 - idereg.last_read_track = gdrom_get_track_no_by_lba( idereg.last_read_lba );8.349 - ide_start_packet_read( datalen, 0x0800 );8.350 - }8.351 + REQUIRE_DISC();8.352 + idereg.read_lba = cmd[2] << 16 | cmd[3] << 8 | cmd[4];8.353 + idereg.sectors_left = cmd[8] << 16 | cmd[9] << 8 | cmd[10]; /* blocks */8.354 + idereg.read_mode = cmd[1];8.355 + ide_read_next_sector();8.356 break;8.357 case PKT_CMD_SPIN_UP:8.358 + REQUIRE_DISC();8.359 /* do nothing? */8.360 ide_set_packet_result( PKT_ERR_OK );8.361 ide_raise_interrupt();8.362 break;8.363 case PKT_CMD_STATUS:8.364 + REQUIRE_DISC();8.365 length = cmd[4];8.366 - if( !gdrom_is_mounted() ) {8.367 - ide_set_packet_result( PKT_ERR_NODISC );8.368 - } else {8.369 - switch( cmd[1] ) {8.370 - case 0:8.371 - if( length > sizeof(gdrom_status) ) {8.372 - length = sizeof(gdrom_status);8.373 - }8.374 - memcpy( data_buffer, gdrom_status, length );8.375 - ide_start_packet_read( length, length );8.376 - break;8.377 - case 1:8.378 - if( length > 14 ) {8.379 - length = 14;8.380 - }8.381 - gdrom_track_t track = gdrom_get_track(idereg.last_read_track);8.382 - int offset = idereg.last_read_lba - track->lba;8.383 - data_buffer[0] = 0x00;8.384 - data_buffer[1] = 0x15; /* ??? */8.385 - data_buffer[2] = 0x00;8.386 - data_buffer[3] = 0x0E;8.387 - data_buffer[4] = track->flags;8.388 - data_buffer[5] = idereg.last_read_track;8.389 - data_buffer[6] = 0x01; /* ?? */8.390 - data_buffer[7] = (offset >> 16) & 0xFF;8.391 - data_buffer[8] = (offset >> 8) & 0xFF;8.392 - data_buffer[9] = offset & 0xFF;8.393 - data_buffer[10] = (idereg.last_read_lba >> 24) & 0xFF;8.394 - data_buffer[11] = (idereg.last_read_lba >> 16) & 0xFF;8.395 - data_buffer[12] = (idereg.last_read_lba >> 8) & 0xFF;8.396 - data_buffer[13] = idereg.last_read_lba & 0xFF;8.397 - ide_start_packet_read( length, length );8.398 - break;8.399 + switch( cmd[1] ) {8.400 + case 0:8.401 + if( length > sizeof(gdrom_status) ) {8.402 + length = sizeof(gdrom_status);8.403 }8.404 + memcpy( data_buffer, gdrom_status, length );8.405 + ide_start_packet_read( length, 0 );8.406 + break;8.407 + case 1:8.408 + if( length > 14 ) {8.409 + length = 14;8.410 + }8.411 + gdrom_disc->read_position( gdrom_disc, idereg.read_lba, data_buffer );8.412 + data_buffer[0] = 0x00;8.413 + data_buffer[1] = 0x15; /* audio status ? */8.414 + data_buffer[2] = 0x00;8.415 + data_buffer[3] = 0x0E;8.416 + ide_start_packet_read( length, 0 );8.417 + break;8.418 }8.419 break;8.420 case PKT_CMD_71:8.421 @@ -568,8 +568,9 @@8.422 * (and not even the same length each time, never mind the same data).8.423 * For sake of something to do, it returns the results from a test dump8.424 */8.425 + REQUIRE_DISC();8.426 memcpy( data_buffer, gdrom_71, sizeof(gdrom_71) );8.427 - ide_start_packet_read( sizeof(gdrom_71), sizeof(gdrom_71) );8.428 + ide_start_packet_read( sizeof(gdrom_71), 0 );8.429 break;8.430 default:8.431 ide_set_packet_result( PKT_ERR_BADCMD ); /* Invalid command */
9.1 --- a/src/gdrom/ide.h Wed Jan 31 10:32:25 2007 +00009.2 +++ b/src/gdrom/ide.h Wed Jan 31 10:58:42 2007 +00009.3 @@ -1,5 +1,5 @@9.4 /**9.5 - * $Id: ide.h,v 1.12 2006-12-29 00:21:46 nkeynes Exp $9.6 + * $Id: ide.h,v 1.13 2007-01-31 10:58:42 nkeynes Exp $9.7 *9.8 * This file defines the interface and structures of the dreamcast's IDE9.9 * port. Note that the register definitions are in asic.h, as the registers9.10 @@ -55,12 +55,11 @@9.11 int data_offset;9.12 int data_length;9.14 - int block_length; /* Used to determine the transfer unit size */9.15 - int block_left; /* Bytes remaining in the current block */9.16 -9.17 /* Status reporting information */9.18 uint8_t last_read_track;9.19 - uint32_t last_read_lba;9.20 + uint32_t read_lba;9.21 + uint32_t read_mode;9.22 + uint32_t sectors_left; /* sectors left after current read */9.23 };9.25 #define IDE_STATE_IDLE 09.26 @@ -116,6 +115,7 @@9.27 void ide_write_data_pio( uint16_t value );9.28 uint32_t ide_read_data_dma( uint32_t addr, uint32_t length );9.29 uint8_t ide_read_status(void);9.30 +uint8_t ide_get_drive_status(void);9.31 void ide_write_buffer( unsigned char *data, int length );9.33 void ide_write_command( uint8_t command );
10.1 --- a/src/gdrom/linux.c Wed Jan 31 10:32:25 2007 +000010.2 +++ b/src/gdrom/linux.c Wed Jan 31 10:58:42 2007 +000010.3 @@ -1,7 +1,7 @@10.4 /**10.5 - * $Id: linux.c,v 1.2 2006-12-29 00:24:43 nkeynes Exp $10.6 + * $Id: linux.c,v 1.3 2007-01-31 10:58:42 nkeynes Exp $10.7 *10.8 - * Linux cd-rom device driver10.9 + * Linux cd-rom device driver.10.10 *10.11 * Copyright (c) 2005 Nathan Keynes.10.12 *10.13 @@ -29,7 +29,7 @@10.15 #define MAXTOCENTRIES 600 /* This is a fairly generous overestimate really */10.16 #define MAXTOCSIZE 4 + (MAXTOCENTRIES*11)10.17 -#define MAX_SECTORS_PER_CALL 3210.18 +#define MAX_SECTORS_PER_CALL 110.20 #define MSFTOLBA( m,s,f ) (f + (s*CD_FRAMES) + (m*CD_FRAMES*CD_SECS))10.22 @@ -48,11 +48,10 @@10.24 static gboolean linux_image_is_valid( FILE *f );10.25 static gdrom_disc_t linux_open_device( const gchar *filename, FILE *f );10.26 -static gdrom_error_t linux_read_disc_toc( gdrom_disc_t disc );10.27 -static gdrom_error_t linux_read_sectors( gdrom_disc_t disc, uint32_t sector,10.28 - uint32_t sector_count, int mode, char *buf,10.29 - uint32_t *length );10.30 -static gdrom_error_t linux_send_command( int fd, char *cmd, char *buffer, size_t buflen,10.31 +static gdrom_error_t linux_read_disc_toc( gdrom_image_t disc );10.32 +static gdrom_error_t linux_read_sector( gdrom_disc_t disc, uint32_t sector,10.33 + int mode, char *buf, uint32_t *length );10.34 +static gdrom_error_t linux_send_command( int fd, char *cmd, char *buffer, size_t *buflen,10.35 int direction );10.38 @@ -90,9 +89,9 @@10.39 return NULL;10.40 }10.42 - gdrom_error_t status = linux_read_disc_toc( disc );10.43 + gdrom_error_t status = linux_read_disc_toc( (gdrom_image_t)disc );10.44 if( status != 0 ) {10.45 - free(disc);10.46 + disc->close(disc);10.47 if( status == 0xFFFF ) {10.48 ERROR("Unable to load disc table of contents (%s)", strerror(errno));10.49 } else {10.50 @@ -101,24 +100,25 @@10.51 }10.52 return NULL;10.53 }10.54 - disc->read_sectors = linux_read_sectors;10.55 - disc->disc_type = IDE_DISC_CDROM;10.56 + disc->read_sector = linux_read_sector;10.57 + ((gdrom_image_t)disc)->disc_type = IDE_DISC_CDROM;10.58 return disc;10.59 }10.61 /**10.62 * Read the full table of contents into the disc from the device.10.63 */10.64 -static gdrom_error_t linux_read_disc_toc( gdrom_disc_t disc )10.65 +static gdrom_error_t linux_read_disc_toc( gdrom_image_t disc )10.66 {10.67 int fd = fileno(disc->file);10.68 unsigned char buf[MAXTOCSIZE];10.69 + int buflen = sizeof(buf);10.70 char cmd[12] = { 0x43, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };10.72 cmd[7] = (sizeof(buf))>>8;10.73 cmd[8] = (sizeof(buf))&0xFF;10.74 memset( buf, 0, sizeof(buf) );10.75 - gdrom_error_t status = linux_send_command( fd, cmd, buf, sizeof(buf), CGC_DATA_READ );10.76 + gdrom_error_t status = linux_send_command( fd, cmd, buf, &buflen, CGC_DATA_READ );10.77 if( status != 0 ) {10.78 return status;10.79 }10.80 @@ -172,66 +172,31 @@10.81 return 0;10.82 }10.84 -static gdrom_error_t linux_read_sectors_ioctl( gdrom_disc_t disc, uint32_t sector,10.85 - uint32_t sector_count, int mode, char *buf,10.86 - uint32_t *length )10.87 +static gdrom_error_t linux_read_sector( gdrom_disc_t disc, uint32_t sector,10.88 + int mode, char *buf, uint32_t *length )10.89 {10.90 - int fd = fileno(disc->file);10.91 - int call;10.92 - struct cdrom_read read;10.93 - read.cdread_lba = LBATOMSF(sector);10.94 - read.cdread_bufaddr = buf;10.95 - switch(mode) {10.96 - case GDROM_MODE1:10.97 - call = CDROMREADMODE1;10.98 - read.cdread_buflen = sector_count * 2048;10.99 - break;10.100 - case GDROM_MODE2:10.101 - call = CDROMREADMODE2;10.102 - read.cdread_buflen = sector_count * 2336;10.103 - break;10.104 - default:10.105 - return PKT_ERR_BADREADMODE;10.106 - }10.107 -10.108 - if( ioctl( fd, call, &read ) == -1 ) {10.109 - ERROR( "Error reading disc (%s)", strerror(errno) );10.110 - return PKT_ERR_BADREAD;10.111 - }10.112 - *length = read.cdread_buflen;10.113 - return PKT_ERR_OK;10.114 -}10.115 -10.116 -static gdrom_error_t linux_read_sectors( gdrom_disc_t disc, uint32_t sector,10.117 - uint32_t sector_count, int mode, char *buf,10.118 - uint32_t *length )10.119 -{10.120 - int fd = fileno(disc->file);10.121 + gdrom_image_t image = (gdrom_image_t)disc;10.122 + int fd = fileno(image->file);10.123 uint32_t real_sector = sector - CD_MSF_OFFSET;10.124 - uint32_t sector_size = 2048;10.125 - int buflen = sector_count * sector_size;10.126 + uint32_t sector_size = MAX_SECTOR_SIZE;10.127 int i;10.128 char cmd[12] = { 0xBE, 0x10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };10.130 - for( i=0; i<sector_count; i += MAX_SECTORS_PER_CALL ) {10.131 - int count = MIN(MAX_SECTORS_PER_CALL, sector_count);10.132 - cmd[2] = (real_sector >> 24) & 0xFF;10.133 - cmd[3] = (real_sector >> 16) & 0xFF;10.134 - cmd[4] = (real_sector >> 8) & 0xFF;10.135 - cmd[5] = real_sector & 0xFF;10.136 - cmd[6] = (count >> 16) & 0xFF;10.137 - cmd[7] = (count >> 8) & 0xFF;10.138 - cmd[8] = count & 0xFF;10.139 - cmd[9] = 0x10;10.140 + cmd[1] = (mode & 0x0E) << 1;10.141 + cmd[2] = (real_sector >> 24) & 0xFF;10.142 + cmd[3] = (real_sector >> 16) & 0xFF;10.143 + cmd[4] = (real_sector >> 8) & 0xFF;10.144 + cmd[5] = real_sector & 0xFF;10.145 + cmd[6] = 0;10.146 + cmd[7] = 0;10.147 + cmd[8] = 1;10.148 + cmd[9] = 0x10;10.150 - gdrom_error_t status = linux_send_command( fd, cmd, buf, count * sector_size, CGC_DATA_READ );10.151 - if( status != 0 ) {10.152 - return status;10.153 - }10.154 - real_sector += count;10.155 - buf += count * sector_size;10.156 + gdrom_error_t status = linux_send_command( fd, cmd, buf, §or_size, CGC_DATA_READ );10.157 + if( status != 0 ) {10.158 + return status;10.159 }10.160 - *length = buflen;10.161 + *length = 2048;10.162 return 0;10.163 }10.165 @@ -240,7 +205,7 @@10.166 * @return 0 on success, -1 on an operating system error, or a sense error10.167 * code on a device error.10.168 */10.169 -static gdrom_error_t linux_send_command( int fd, char *cmd, char *buffer, size_t buflen,10.170 +static gdrom_error_t linux_send_command( int fd, char *cmd, char *buffer, size_t *buflen,10.171 int direction )10.172 {10.173 struct request_sense sense;10.174 @@ -250,7 +215,7 @@10.175 memset( &sense, 0, sizeof(sense) );10.176 memcpy( cgc.cmd, cmd, 12 );10.177 cgc.buffer = buffer;10.178 - cgc.buflen = buflen;10.179 + cgc.buflen = *buflen;10.180 cgc.sense = &sense;10.181 cgc.data_direction = direction;10.183 @@ -258,9 +223,11 @@10.184 if( sense.sense_key == 0 ) {10.185 return -1;10.186 } else {10.187 + /* TODO: Map newer codes back to the ones used by the gd-rom. */10.188 return sense.sense_key | (sense.asc<<8);10.189 }10.190 } else {10.191 + *buflen = cgc.buflen;10.192 return 0;10.193 }10.194 }
11.1 --- a/src/gdrom/nrg.c Wed Jan 31 10:32:25 2007 +000011.2 +++ b/src/gdrom/nrg.c Wed Jan 31 10:58:42 2007 +000011.3 @@ -1,5 +1,5 @@11.4 /**11.5 - * $Id: nrg.c,v 1.3 2006-06-26 10:30:42 nkeynes Exp $11.6 + * $Id: nrg.c,v 1.4 2007-01-31 10:58:42 nkeynes Exp $11.7 *11.8 * Nero (NRG) CD file format. File information stolen shamelessly from11.9 * libcdio.11.10 @@ -156,6 +156,7 @@11.11 struct nrg_chunk chunk;11.12 struct nrg_daoi *dao;11.13 gdrom_disc_t disc;11.14 + gdrom_image_t image;11.15 gboolean end = FALSE;11.16 int session_id = 0;11.17 int session_track_id = 0;11.18 @@ -178,9 +179,11 @@11.20 disc = gdrom_image_new(f);11.21 if( disc == NULL ) {11.22 + fclose(f);11.23 ERROR("Unable to allocate memory!");11.24 return NULL;11.25 }11.26 + image = (gdrom_image_t)disc;11.28 do {11.29 fread( &chunk, sizeof(chunk), 1, f );11.30 @@ -198,36 +201,36 @@11.31 if( cue->track == 0 )11.32 continue; /* Track 0. Leadin? always 0? */11.33 if( cue->track == 0xAA ) { /* end of disc */11.34 - disc->track[track_id-1].sector_count =11.35 - msf_to_lba( cue->addr ) - disc->track[track_id-1].lba;11.36 + image->track[track_id-1].sector_count =11.37 + msf_to_lba( cue->addr ) - image->track[track_id-1].lba;11.38 } else {11.39 track = cue_track_id + bcd_to_uint8(cue->track) - 1;11.40 if( (cue->control & 0x01) == 0 ) {11.41 /* Pre-gap address. */11.42 if( track != 0 ) {11.43 - disc->track[track-1].sector_count =11.44 - msf_to_lba( cue->addr ) - disc->track[track-1].lba;11.45 + image->track[track-1].sector_count =11.46 + msf_to_lba( cue->addr ) - image->track[track-1].lba;11.47 }11.48 } else { /* Track-start address */11.49 - disc->track[track].lba = msf_to_lba( cue->addr );11.50 - disc->track[track].flags = cue->type;11.51 + image->track[track].lba = msf_to_lba( cue->addr );11.52 + image->track[track].flags = cue->type;11.53 }11.54 }11.55 }11.56 break;11.57 case DAOI_ID:11.58 dao = (struct nrg_daoi *)data;11.59 - memcpy( disc->mcn, dao->mcn, 13 );11.60 - disc->mcn[13] = '\0';11.61 + memcpy( image->mcn, dao->mcn, 13 );11.62 + image->mcn[13] = '\0';11.63 assert( dao->track_count * 30 + 22 == chunk.length );11.64 assert( dao->track_count == cue_track_count );11.65 for( i=0; i<dao->track_count; i++ ) {11.66 - disc->track[cue_track_id].sector_size = ntohl(dao->track[i].sector_size);11.67 - disc->track[cue_track_id].offset = ntohl(dao->track[i].offset);11.68 - disc->track[cue_track_id].mode = nrg_track_mode( dao->track[i].mode );11.69 - assert( disc->track[cue_track_id].sector_count ==11.70 - (ntohl(dao->track[i].end) - ntohl(dao->track[i].offset))/11.71 - ntohl(dao->track[i].sector_size) );11.72 + image->track[cue_track_id].sector_size = ntohl(dao->track[i].sector_size);11.73 + image->track[cue_track_id].offset = ntohl(dao->track[i].offset);11.74 + image->track[cue_track_id].mode = nrg_track_mode( dao->track[i].mode );11.75 + image->track[cue_track_id].sector_count =11.76 + (ntohl(dao->track[i].end) - ntohl(dao->track[i].offset))/11.77 + ntohl(dao->track[i].sector_size);11.78 cue_track_id++;11.79 }11.80 break;11.81 @@ -235,26 +238,26 @@11.82 /* Data is a single 32-bit number representing number of tracks in session */11.83 i = ntohl( *(uint32_t *)data );11.84 while( i-- > 0 )11.85 - disc->track[session_track_id++].session = session_id;11.86 + image->track[session_track_id++].session = session_id;11.87 session_id++;11.88 break;11.89 case ETNF_ID:11.90 for( i=0; i < chunk.length; i+= 0x14 ) {11.91 struct nrg_etnf *etnf = (struct nrg_etnf *)(data+i);11.92 - disc->track[track_id].offset = ntohl(etnf->offset);11.93 - disc->track[track_id].lba = ntohl(etnf->lba) + (i+1)*GDROM_PREGAP;11.94 - disc->track[track_id].mode = nrg_track_mode( ntohl(etnf->mode) );11.95 - if( disc->track[track_id].mode == -1 ) {11.96 + image->track[track_id].offset = ntohl(etnf->offset);11.97 + image->track[track_id].lba = ntohl(etnf->lba) + (i+1)*GDROM_PREGAP;11.98 + image->track[track_id].mode = nrg_track_mode( ntohl(etnf->mode) );11.99 + if( image->track[track_id].mode == -1 ) {11.100 disc->close(disc);11.101 return NULL;11.102 }11.103 - if( disc->track[track_id].mode == GDROM_CDDA )11.104 - disc->track[track_id].flags = 0x01;11.105 + if( image->track[track_id].mode == GDROM_CDDA )11.106 + image->track[track_id].flags = 0x01;11.107 else11.108 - disc->track[track_id].flags = 0x01 | TRACK_DATA;11.109 - disc->track[track_id].sector_size = GDROM_SECTOR_SIZE(disc->track[track_id].mode);11.110 - disc->track[track_id].sector_count = ntohl(etnf->length) /11.111 - disc->track[track_id].sector_size;11.112 + image->track[track_id].flags = 0x01 | TRACK_DATA;11.113 + image->track[track_id].sector_size = GDROM_SECTOR_SIZE(image->track[track_id].mode);11.114 + image->track[track_id].sector_count = ntohl(etnf->length) /11.115 + image->track[track_id].sector_size;11.116 track_id++;11.117 }11.118 break;11.119 @@ -263,12 +266,9 @@11.120 break;11.121 }11.122 } while( !end );11.123 - disc->track_count = track_id;11.124 + image->track_count = track_id;11.125 return disc;11.126 }11.128 -gboolean nrg_read_sectors( struct gdrom_disc *disc, uint32_t lba, uint32_t count, char *buf )11.129 -{11.130 - return FALSE;11.131 -}11.133 +
12.1 --- a/src/gdrom/packet.h Wed Jan 31 10:32:25 2007 +000012.2 +++ b/src/gdrom/packet.h Wed Jan 31 10:58:42 2007 +000012.3 @@ -1,5 +1,5 @@12.4 /**12.5 - * $Id: packet.h,v 1.6 2006-12-21 10:15:02 nkeynes Exp $12.6 + * $Id: packet.h,v 1.7 2007-01-31 10:58:42 nkeynes Exp $12.7 *12.8 * This file defines the command codes and any other flags used by the12.9 * GD-Rom ATAPI packet commands.12.10 @@ -52,7 +52,7 @@12.11 #define PKT_CMD_READ_TOC 0x1412.12 #define PKT_CMD_SESSION_INFO 0x1512.13 #define PKT_CMD_READ_SECTOR 0x3012.14 -#define PKT_CMD_PLAY_CD 0x20 /* ? */12.15 +#define PKT_CMD_PLAY_AUDIO 0x20 /* ? */12.16 #define PKT_CMD_STATUS 0x4012.17 #define PKT_CMD_SPIN_UP 0x70 /* ??? */12.18 #define PKT_CMD_71 0x71 /* ??? seems to return garbage */
.