Search
lxdream.org :: lxdream :: r342:850502f0e8de
lxdream 0.9.1
released Jun 29
Download Now
changeset342:850502f0e8de
parent341:924029ff95ea
child343:bf4bf0da94cc
authornkeynes
dateWed Jan 31 10:58:42 2007 +0000 (17 years ago)
Refactor gdrom module to be more conducive to real device support
src/Makefile.am
src/Makefile.in
src/asic.c
src/gdrom/cdi.c
src/gdrom/gdimage.c
src/gdrom/gdrom.c
src/gdrom/gdrom.h
src/gdrom/ide.c
src/gdrom/ide.h
src/gdrom/linux.c
src/gdrom/nrg.c
src/gdrom/packet.h
1.1 --- a/src/Makefile.am Wed Jan 31 10:32:25 2007 +0000
1.2 +++ b/src/Makefile.am Wed Jan 31 10:58:42 2007 +0000
1.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 +0000
2.2 +++ b/src/Makefile.in Wed Jan 31 10:58:42 2007 +0000
2.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.13
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.Po
2.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.Po
2.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.107
2.108 +gdimage.o: gdrom/gdimage.c
2.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@ fi
2.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.c
2.118 +
2.119 +gdimage.obj: gdrom/gdimage.c
2.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@ fi
2.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.c
2.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 +0000
3.2 +++ b/src/asic.c Wed Jan 31 10:58:42 2007 +0000
3.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 +0000
4.2 +++ b/src/gdrom/cdi.c Wed Jan 31 10:58:42 2007 +0000
4.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 support
4.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.20
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.28
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 +0000
5.2 +++ b/src/gdrom/gdimage.c Wed Jan 31 10:58:42 2007 +0000
5.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 modify
5.12 + * it under the terms of the GNU General Public License as published by
5.13 + * the Free Software Foundation; either version 2 of the License, or
5.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 of
5.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5.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_* methods
5.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 it
5.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 +0000
6.2 +++ b/src/gdrom/gdrom.c Wed Jan 31 10:58:42 2007 +0000
6.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.14
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.18
6.19 gdrom_image_class_t gdrom_image_classes[] = { &linux_device_class, &nrg_image_class, &cdi_image_class, NULL };
6.20
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.25
6.26 @@ -88,204 +86,11 @@
6.27 return NULL;
6.28 }
6.29
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 it
6.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.230
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.239
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 +0000
7.2 +++ b/src/gdrom/gdrom.h Wed Jan 31 10:58:42 2007 +0000
7.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-Rom
7.9 * disc driver. (ie, the modules that supply a CD image to be used by the
7.10 @@ -23,6 +23,8 @@
7.11
7.12 #include "dream.h"
7.13
7.14 +#define MAX_SECTOR_SIZE 2352
7.15 +
7.16 typedef uint16_t gdrom_error_t;
7.17
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.22
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 structure
7.27 + * @param lba logical address to read from
7.28 + * @param mode mode field from the read command
7.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-rom
7.40 + * format.
7.41 + * @param disc pointer to the disc structure
7.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.45
7.46 -typedef struct gdrom_disc {
7.47 + /**
7.48 + * Read the information for the specified sector and return it in the
7.49 + * supplied buffer.
7.50 + * @param disc pointer to the disc structure
7.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 sector
7.58 + * and return it in the supplied buffer. This method does not need to
7.59 + * write the first 4 bytes of the buffer.
7.60 + * @param disc pointer to the disc structure
7.61 + * @param lba sector to get position information for
7.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 the
7.68 + * IDE_DISC_* flags above.
7.69 + * @param disc pointer to the disc structure
7.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 operations
7.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 including
7.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.108
7.109 /**
7.110 *
8.1 --- a/src/gdrom/ide.c Wed Jan 31 10:32:25 2007 +0000
8.2 +++ b/src/gdrom/ide.c Wed Jan 31 10:58:42 2007 +0000
8.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 implementation
8.9 *
8.10 @@ -36,18 +36,21 @@
8.11
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.21
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.25
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.32
8.33 #define WRITE_BUFFER(x16) *((uint16_t *)(data_buffer + idereg.data_offset)) = x16
8.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.43
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.61
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.77
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.94
8.95 @@ -212,7 +212,7 @@
8.96 * Begin PIO read from the device. The data is assumed to already be
8.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.117
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.126
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.196
8.197 void ide_write_data_pio( uint16_t val ) {
8.198 @@ -405,6 +413,40 @@
8.199 }
8.200 }
8.201
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 any
8.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, &sector_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 parsing
8.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.244
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.248
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.286
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 dump
8.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 +0000
9.2 +++ b/src/gdrom/ide.h Wed Jan 31 10:58:42 2007 +0000
9.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 IDE
9.9 * port. Note that the register definitions are in asic.h, as the registers
9.10 @@ -55,12 +55,11 @@
9.11 int data_offset;
9.12 int data_length;
9.13
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.24
9.25 #define IDE_STATE_IDLE 0
9.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.32
9.33 void ide_write_command( uint8_t command );
10.1 --- a/src/gdrom/linux.c Wed Jan 31 10:32:25 2007 +0000
10.2 +++ b/src/gdrom/linux.c Wed Jan 31 10:58:42 2007 +0000
10.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 driver
10.9 + * Linux cd-rom device driver.
10.10 *
10.11 * Copyright (c) 2005 Nathan Keynes.
10.12 *
10.13 @@ -29,7 +29,7 @@
10.14
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 32
10.18 +#define MAX_SECTORS_PER_CALL 1
10.19
10.20 #define MSFTOLBA( m,s,f ) (f + (s*CD_FRAMES) + (m*CD_FRAMES*CD_SECS))
10.21
10.22 @@ -48,11 +48,10 @@
10.23
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.36
10.37
10.38 @@ -90,9 +89,9 @@
10.39 return NULL;
10.40 }
10.41
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.60
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.71
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.83
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.129
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.149
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, &sector_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.164
10.165 @@ -240,7 +205,7 @@
10.166 * @return 0 on success, -1 on an operating system error, or a sense error
10.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.182
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 +0000
11.2 +++ b/src/gdrom/nrg.c Wed Jan 31 10:58:42 2007 +0000
11.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 from
11.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.19
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.27
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 else
11.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.127
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.132
11.133 +
12.1 --- a/src/gdrom/packet.h Wed Jan 31 10:32:25 2007 +0000
12.2 +++ b/src/gdrom/packet.h Wed Jan 31 10:58:42 2007 +0000
12.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 the
12.9 * GD-Rom ATAPI packet commands.
12.10 @@ -52,7 +52,7 @@
12.11 #define PKT_CMD_READ_TOC 0x14
12.12 #define PKT_CMD_SESSION_INFO 0x15
12.13 #define PKT_CMD_READ_SECTOR 0x30
12.14 -#define PKT_CMD_PLAY_CD 0x20 /* ? */
12.15 +#define PKT_CMD_PLAY_AUDIO 0x20 /* ? */
12.16 #define PKT_CMD_STATUS 0x40
12.17 #define PKT_CMD_SPIN_UP 0x70 /* ??? */
12.18 #define PKT_CMD_71 0x71 /* ??? seems to return garbage */
.