Search
lxdream.org :: lxdream :: r138:afabd7e6d26d
lxdream 0.9.1
released Jun 29
Download Now
changeset138:afabd7e6d26d
parent137:41907543d890
child139:128f569e004e
authornkeynes
dateSun Apr 30 01:51:08 2006 +0000 (14 years ago)
Add Nero file format handler and general gdrom disc hooks
src/Makefile.am
src/Makefile.in
src/gdrom/gdrom.c
src/gdrom/gdrom.h
src/gdrom/ide.c
src/gdrom/ide.h
src/gdrom/nrg.c
1.1 --- a/src/Makefile.am Sun Apr 30 01:50:15 2006 +0000
1.2 +++ b/src/Makefile.am Sun Apr 30 01:51:08 2006 +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 \
1.8 + gdrom/ide.c gdrom/ide.h gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c\
1.9 dreamcast.c dreamcast.h \
1.10 sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \
1.11 sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \
2.1 --- a/src/Makefile.in Sun Apr 30 01:50:15 2006 +0000
2.2 +++ b/src/Makefile.in Sun Apr 30 01:51:08 2006 +0000
2.3 @@ -140,7 +140,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 \
2.8 + gdrom/ide.c gdrom/ide.h gdrom/gdrom.c gdrom/gdrom.h gdrom/nrg.c\
2.9 dreamcast.c dreamcast.h \
2.10 sh4/intc.c sh4/intc.h sh4/sh4mem.c sh4/timer.c sh4/dmac.c \
2.11 sh4/sh4core.c sh4/sh4core.h sh4/sh4dasm.c sh4/sh4dasm.h \
2.12 @@ -176,18 +176,19 @@
2.13
2.14 am_dream_OBJECTS = main.$(OBJEXT) mem.$(OBJEXT) watch.$(OBJEXT) \
2.15 asic.$(OBJEXT) syscall.$(OBJEXT) bios.$(OBJEXT) \
2.16 - dcload.$(OBJEXT) ide.$(OBJEXT) dreamcast.$(OBJEXT) \
2.17 - intc.$(OBJEXT) sh4mem.$(OBJEXT) timer.$(OBJEXT) dmac.$(OBJEXT) \
2.18 - sh4core.$(OBJEXT) sh4dasm.$(OBJEXT) sh4mmio.$(OBJEXT) \
2.19 - scif.$(OBJEXT) armcore.$(OBJEXT) armdasm.$(OBJEXT) \
2.20 - armmem.$(OBJEXT) aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) \
2.21 - ta.$(OBJEXT) render.$(OBJEXT) texcache.$(OBJEXT) \
2.22 - maple.$(OBJEXT) controller.$(OBJEXT) support.$(OBJEXT) \
2.23 - interface.$(OBJEXT) callbacks.$(OBJEXT) gui.$(OBJEXT) \
2.24 - mmr_win.$(OBJEXT) debug_win.$(OBJEXT) dump_win.$(OBJEXT) \
2.25 - loader.$(OBJEXT) bootstrap.$(OBJEXT) util.$(OBJEXT) \
2.26 - audio_null.$(OBJEXT) audio_esd.$(OBJEXT) video_null.$(OBJEXT) \
2.27 - video_gtk.$(OBJEXT) video_x11.$(OBJEXT)
2.28 + dcload.$(OBJEXT) ide.$(OBJEXT) gdrom.$(OBJEXT) nrg.$(OBJEXT) \
2.29 + dreamcast.$(OBJEXT) intc.$(OBJEXT) sh4mem.$(OBJEXT) \
2.30 + timer.$(OBJEXT) dmac.$(OBJEXT) sh4core.$(OBJEXT) \
2.31 + sh4dasm.$(OBJEXT) sh4mmio.$(OBJEXT) scif.$(OBJEXT) \
2.32 + armcore.$(OBJEXT) armdasm.$(OBJEXT) armmem.$(OBJEXT) \
2.33 + aica.$(OBJEXT) audio.$(OBJEXT) pvr2.$(OBJEXT) ta.$(OBJEXT) \
2.34 + render.$(OBJEXT) texcache.$(OBJEXT) maple.$(OBJEXT) \
2.35 + controller.$(OBJEXT) support.$(OBJEXT) interface.$(OBJEXT) \
2.36 + callbacks.$(OBJEXT) gui.$(OBJEXT) mmr_win.$(OBJEXT) \
2.37 + debug_win.$(OBJEXT) dump_win.$(OBJEXT) loader.$(OBJEXT) \
2.38 + bootstrap.$(OBJEXT) util.$(OBJEXT) audio_null.$(OBJEXT) \
2.39 + audio_esd.$(OBJEXT) video_null.$(OBJEXT) video_gtk.$(OBJEXT) \
2.40 + video_x11.$(OBJEXT)
2.41 dream_OBJECTS = $(am_dream_OBJECTS)
2.42 dream_DEPENDENCIES =
2.43 dream_LDFLAGS =
2.44 @@ -203,11 +204,12 @@
2.45 @AMDEP_TRUE@ ./$(DEPDIR)/callbacks.Po ./$(DEPDIR)/controller.Po \
2.46 @AMDEP_TRUE@ ./$(DEPDIR)/dcload.Po ./$(DEPDIR)/debug_win.Po \
2.47 @AMDEP_TRUE@ ./$(DEPDIR)/dmac.Po ./$(DEPDIR)/dreamcast.Po \
2.48 -@AMDEP_TRUE@ ./$(DEPDIR)/dump_win.Po ./$(DEPDIR)/gui.Po \
2.49 -@AMDEP_TRUE@ ./$(DEPDIR)/ide.Po ./$(DEPDIR)/intc.Po \
2.50 -@AMDEP_TRUE@ ./$(DEPDIR)/interface.Po ./$(DEPDIR)/loader.Po \
2.51 -@AMDEP_TRUE@ ./$(DEPDIR)/main.Po ./$(DEPDIR)/maple.Po \
2.52 -@AMDEP_TRUE@ ./$(DEPDIR)/mem.Po ./$(DEPDIR)/mmr_win.Po \
2.53 +@AMDEP_TRUE@ ./$(DEPDIR)/dump_win.Po ./$(DEPDIR)/gdrom.Po \
2.54 +@AMDEP_TRUE@ ./$(DEPDIR)/gui.Po ./$(DEPDIR)/ide.Po \
2.55 +@AMDEP_TRUE@ ./$(DEPDIR)/intc.Po ./$(DEPDIR)/interface.Po \
2.56 +@AMDEP_TRUE@ ./$(DEPDIR)/loader.Po ./$(DEPDIR)/main.Po \
2.57 +@AMDEP_TRUE@ ./$(DEPDIR)/maple.Po ./$(DEPDIR)/mem.Po \
2.58 +@AMDEP_TRUE@ ./$(DEPDIR)/mmr_win.Po ./$(DEPDIR)/nrg.Po \
2.59 @AMDEP_TRUE@ ./$(DEPDIR)/pvr2.Po ./$(DEPDIR)/render.Po \
2.60 @AMDEP_TRUE@ ./$(DEPDIR)/scif.Po ./$(DEPDIR)/sh4core.Po \
2.61 @AMDEP_TRUE@ ./$(DEPDIR)/sh4dasm.Po ./$(DEPDIR)/sh4mem.Po \
2.62 @@ -285,6 +287,7 @@
2.63 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dmac.Po@am__quote@
2.64 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dreamcast.Po@am__quote@
2.65 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dump_win.Po@am__quote@
2.66 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gdrom.Po@am__quote@
2.67 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/gui.Po@am__quote@
2.68 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ide.Po@am__quote@
2.69 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/intc.Po@am__quote@
2.70 @@ -294,6 +297,7 @@
2.71 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/maple.Po@am__quote@
2.72 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mem.Po@am__quote@
2.73 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmr_win.Po@am__quote@
2.74 +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/nrg.Po@am__quote@
2.75 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pvr2.Po@am__quote@
2.76 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/render.Po@am__quote@
2.77 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/scif.Po@am__quote@
2.78 @@ -356,6 +360,50 @@
2.79 @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.80 @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.81
2.82 +gdrom.o: gdrom/gdrom.c
2.83 +@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.84 +@am__fastdepCC_TRUE@ -c -o gdrom.o `test -f 'gdrom/gdrom.c' || echo '$(srcdir)/'`gdrom/gdrom.c; \
2.85 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gdrom.Tpo" "$(DEPDIR)/gdrom.Po"; \
2.86 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/gdrom.Tpo"; exit 1; \
2.87 +@am__fastdepCC_TRUE@ fi
2.88 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gdrom/gdrom.c' object='gdrom.o' libtool=no @AMDEPBACKSLASH@
2.89 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gdrom.Po' tmpdepfile='$(DEPDIR)/gdrom.TPo' @AMDEPBACKSLASH@
2.90 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.91 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gdrom.o `test -f 'gdrom/gdrom.c' || echo '$(srcdir)/'`gdrom/gdrom.c
2.92 +
2.93 +gdrom.obj: gdrom/gdrom.c
2.94 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT gdrom.obj -MD -MP -MF "$(DEPDIR)/gdrom.Tpo" \
2.95 +@am__fastdepCC_TRUE@ -c -o gdrom.obj `if test -f 'gdrom/gdrom.c'; then $(CYGPATH_W) 'gdrom/gdrom.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/gdrom.c'; fi`; \
2.96 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/gdrom.Tpo" "$(DEPDIR)/gdrom.Po"; \
2.97 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/gdrom.Tpo"; exit 1; \
2.98 +@am__fastdepCC_TRUE@ fi
2.99 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gdrom/gdrom.c' object='gdrom.obj' libtool=no @AMDEPBACKSLASH@
2.100 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/gdrom.Po' tmpdepfile='$(DEPDIR)/gdrom.TPo' @AMDEPBACKSLASH@
2.101 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.102 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o gdrom.obj `if test -f 'gdrom/gdrom.c'; then $(CYGPATH_W) 'gdrom/gdrom.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/gdrom.c'; fi`
2.103 +
2.104 +nrg.o: gdrom/nrg.c
2.105 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nrg.o -MD -MP -MF "$(DEPDIR)/nrg.Tpo" \
2.106 +@am__fastdepCC_TRUE@ -c -o nrg.o `test -f 'gdrom/nrg.c' || echo '$(srcdir)/'`gdrom/nrg.c; \
2.107 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/nrg.Tpo" "$(DEPDIR)/nrg.Po"; \
2.108 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/nrg.Tpo"; exit 1; \
2.109 +@am__fastdepCC_TRUE@ fi
2.110 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gdrom/nrg.c' object='nrg.o' libtool=no @AMDEPBACKSLASH@
2.111 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/nrg.Po' tmpdepfile='$(DEPDIR)/nrg.TPo' @AMDEPBACKSLASH@
2.112 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.113 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nrg.o `test -f 'gdrom/nrg.c' || echo '$(srcdir)/'`gdrom/nrg.c
2.114 +
2.115 +nrg.obj: gdrom/nrg.c
2.116 +@am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT nrg.obj -MD -MP -MF "$(DEPDIR)/nrg.Tpo" \
2.117 +@am__fastdepCC_TRUE@ -c -o nrg.obj `if test -f 'gdrom/nrg.c'; then $(CYGPATH_W) 'gdrom/nrg.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/nrg.c'; fi`; \
2.118 +@am__fastdepCC_TRUE@ then mv -f "$(DEPDIR)/nrg.Tpo" "$(DEPDIR)/nrg.Po"; \
2.119 +@am__fastdepCC_TRUE@ else rm -f "$(DEPDIR)/nrg.Tpo"; exit 1; \
2.120 +@am__fastdepCC_TRUE@ fi
2.121 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='gdrom/nrg.c' object='nrg.obj' libtool=no @AMDEPBACKSLASH@
2.122 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ depfile='$(DEPDIR)/nrg.Po' tmpdepfile='$(DEPDIR)/nrg.TPo' @AMDEPBACKSLASH@
2.123 +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
2.124 +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o nrg.obj `if test -f 'gdrom/nrg.c'; then $(CYGPATH_W) 'gdrom/nrg.c'; else $(CYGPATH_W) '$(srcdir)/gdrom/nrg.c'; fi`
2.125 +
2.126 intc.o: sh4/intc.c
2.127 @am__fastdepCC_TRUE@ if $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT intc.o -MD -MP -MF "$(DEPDIR)/intc.Tpo" \
2.128 @am__fastdepCC_TRUE@ -c -o intc.o `test -f 'sh4/intc.c' || echo '$(srcdir)/'`sh4/intc.c; \
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/src/gdrom/gdrom.c Sun Apr 30 01:51:08 2006 +0000
3.3 @@ -0,0 +1,138 @@
3.4 +/**
3.5 + * $Id: gdrom.c,v 1.1 2006-04-30 01:51:08 nkeynes Exp $
3.6 + *
3.7 + * GD-Rom access functions.
3.8 + *
3.9 + * Copyright (c) 2005 Nathan Keynes.
3.10 + *
3.11 + * This program is free software; you can redistribute it and/or modify
3.12 + * it under the terms of the GNU General Public License as published by
3.13 + * the Free Software Foundation; either version 2 of the License, or
3.14 + * (at your option) any later version.
3.15 + *
3.16 + * This program is distributed in the hope that it will be useful,
3.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.19 + * GNU General Public License for more details.
3.20 + */
3.21 +
3.22 +#include <stdio.h>
3.23 +
3.24 +#include "gdrom/ide.h"
3.25 +#include "gdrom/gdrom.h"
3.26 +#include "dream.h"
3.27 +
3.28 +static void gdrom_image_destroy( gdrom_disc_t );
3.29 +static uint32_t gdrom_image_read_sectors( gdrom_disc_t, uint32_t, uint32_t, char * );
3.30 +
3.31 +
3.32 +gdrom_disc_t gdrom_disc = NULL;
3.33 +
3.34 +char *gdrom_mode_names[] = { "Mode1", "Mode2", "XA 1", "XA2", "Audio", "GD-Rom" };
3.35 +uint32_t gdrom_sector_size[] = { 2048, 2336, 2048, 2324, 2352, 2336 };
3.36 +
3.37 +gdrom_disc_t gdrom_image_open( const gchar *filename )
3.38 +{
3.39 + return nrg_image_open( filename );
3.40 +}
3.41 +
3.42 +
3.43 +gdrom_disc_t gdrom_image_new( FILE *file )
3.44 +{
3.45 + struct gdrom_disc *disc = (struct gdrom_disc *)calloc(1, sizeof(struct gdrom_disc));
3.46 + if( disc == NULL )
3.47 + return NULL;
3.48 + disc->read_sectors = gdrom_image_read_sectors;
3.49 + disc->close = gdrom_image_destroy;
3.50 + disc->disc_type = IDE_DISC_CDROM;
3.51 + disc->file = file;
3.52 + return disc;
3.53 +}
3.54 +
3.55 +static void gdrom_image_destroy( gdrom_disc_t disc )
3.56 +{
3.57 + if( disc->file != NULL ) {
3.58 + fclose(disc->file);
3.59 + disc->file = NULL;
3.60 + }
3.61 + free( disc );
3.62 +}
3.63 +
3.64 +static uint32_t gdrom_image_read_sectors( gdrom_disc_t disc, uint32_t sector,
3.65 + uint32_t sector_count, char *buf )
3.66 +{
3.67 + int i, track = -1, track_offset, read_len;
3.68 +
3.69 + for( i=0; i<disc->track_count; i++ ) {
3.70 + if( disc->track[i].lba <= sector &&
3.71 + disc->track[i].lba + disc->track[i].sector_count <= sector + sector_count ) {
3.72 + track = i;
3.73 + break;
3.74 + }
3.75 + }
3.76 + if( track == -1 )
3.77 + return 0;
3.78 +
3.79 + track_offset = disc->track[track].sector_size * (sector - disc->track[track].lba);
3.80 + read_len = disc->track[track].sector_size * sector_count;
3.81 + fseek( disc->file, disc->track[track].offset + track_offset, SEEK_SET );
3.82 + fread( buf, disc->track[track].sector_size, sector_count, disc->file );
3.83 + return read_len;
3.84 +}
3.85 +
3.86 +uint32_t gdrom_read_sectors( uint32_t sector, uint32_t sector_count,
3.87 + char *buf )
3.88 +{
3.89 + if( gdrom_disc == NULL )
3.90 + return 0; /* No media */
3.91 + return gdrom_disc->read_sectors( gdrom_disc, sector, sector_count, buf );
3.92 +}
3.93 +
3.94 +
3.95 +void gdrom_dump_disc( gdrom_disc_t disc ) {
3.96 + int i;
3.97 + INFO( "Disc ID: %s, %d tracks in %d sessions", disc->mcn, disc->track_count,
3.98 + disc->track[disc->track_count-1].session + 1 );
3.99 + for( i=0; i<disc->track_count; i++ ) {
3.100 + INFO( "Sess %d Trk %d: Start %06X Length %06X, %s",
3.101 + disc->track[i].session+1, i+1, disc->track[i].lba,
3.102 + disc->track[i].sector_count, gdrom_mode_names[disc->track[i].mode] );
3.103 + }
3.104 +}
3.105 +
3.106 +gboolean gdrom_get_toc( char *buf )
3.107 +{
3.108 + if( gdrom_disc == NULL )
3.109 + return FALSE;
3.110 + return TRUE;
3.111 +}
3.112 +
3.113 +void gdrom_mount_disc( gdrom_disc_t disc )
3.114 +{
3.115 + gdrom_unmount_disc();
3.116 + gdrom_disc = disc;
3.117 + idereg.disc = disc->disc_type | IDE_DISC_READY;
3.118 + gdrom_dump_disc( disc );
3.119 +}
3.120 +
3.121 +gdrom_disc_t gdrom_mount_image( const gchar *filename )
3.122 +{
3.123 + gdrom_disc_t disc = gdrom_image_open(filename);
3.124 + if( disc != NULL )
3.125 + gdrom_mount_disc( disc );
3.126 + return disc;
3.127 +}
3.128 +
3.129 +void gdrom_unmount_disc( )
3.130 +{
3.131 + if( gdrom_disc != NULL ) {
3.132 + gdrom_disc->close(gdrom_disc);
3.133 + }
3.134 + gdrom_disc = NULL;
3.135 + idereg.disc = IDE_DISC_NONE;
3.136 +}
3.137 +
3.138 +gboolean gdrom_is_mounted( void )
3.139 +{
3.140 + return gdrom_disc != NULL;
3.141 +}
4.1 --- a/src/gdrom/gdrom.h Sun Apr 30 01:50:15 2006 +0000
4.2 +++ b/src/gdrom/gdrom.h Sun Apr 30 01:51:08 2006 +0000
4.3 @@ -1,5 +1,5 @@
4.4 /**
4.5 - * $Id: gdrom.h,v 1.1 2006-03-22 14:29:02 nkeynes Exp $
4.6 + * $Id: gdrom.h,v 1.2 2006-04-30 01:51:08 nkeynes Exp $
4.7 *
4.8 * This file defines the structures and functions used by the GD-Rom
4.9 * disc driver. (ie, the modules that supply a CD image to be used by the
4.10 @@ -23,22 +23,87 @@
4.11
4.12 #include "dream.h"
4.13
4.14 -typedef struct gdrom_toc {
4.15 +struct gdrom_toc {
4.16 uint32_t tracks[99];
4.17 uint32_t first, last, leadout;
4.18 -} *gdrom_toc_t;
4.19 +};
4.20 +
4.21 +#define GDROM_PREGAP 150 /* Sectors */
4.22 +
4.23 +extern uint32_t gdrom_sector_size[];
4.24 +#define GDROM_SECTOR_SIZE(x) gdrom_sector_size[x]
4.25 +typedef enum {
4.26 + GDROM_MODE1,
4.27 + GDROM_MODE2,
4.28 + GDROM_MODE2_XA1,
4.29 + GDROM_MODE2_XA2,
4.30 + GDROM_CDDA,
4.31 + GDROM_GD
4.32 +} gdrom_track_mode_t;
4.33 +
4.34 +/* The disc register indicates the current contents of the drive. When open
4.35 + * contains 0x06.
4.36 + */
4.37 +#define IDE_DISC_AUDIO 0x00
4.38 +#define IDE_DISC_NONE 0x06
4.39 +#define IDE_DISC_CDROM 0x20
4.40 +#define IDE_DISC_GDROM 0x80
4.41 +#define IDE_DISC_READY 0x01 /* ored with above */
4.42 +#define IDE_DISC_IDLE 0x02 /* ie spun-down */
4.43 +
4.44 +struct gdrom_track {
4.45 + gdrom_track_mode_t mode;
4.46 + int session; /* session # containing this track */
4.47 + uint32_t lba; /* start sector address */
4.48 + uint32_t sector_size; /* For convenience, determined by mode */
4.49 + uint32_t sector_count;
4.50 + uint32_t offset; /* File offset of start of track - image files only */
4.51 +};
4.52
4.53
4.54 typedef struct gdrom_disc {
4.55 -
4.56 - gboolean (*read_toc)( gdrom_toc_t toc );
4.57 -
4.58 - gboolean (*read_data_sectors)( uint32_t lba, uint32_t sector_count,
4.59 - char *buf );
4.60 + int disc_type;
4.61 + int track_count;
4.62 + struct gdrom_track track[99];
4.63 + gchar mcn[14]; /* Media catalogue number */
4.64 + const gchar *filename; /* Image filename */
4.65 + FILE *file; /* Stream, for image files */
4.66 + uint32_t (*read_sectors)( struct gdrom_disc *disc,
4.67 + uint32_t lba, uint32_t sector_count,
4.68 + char *buf );
4.69 + void (*close)( struct gdrom_disc *disc );
4.70 } *gdrom_disc_t;
4.71
4.72 -void gdrom_mount( gdrom_disc_t disc );
4.73 +/**
4.74 + * Construct a new image file using the default methods.
4.75 + */
4.76 +gdrom_disc_t gdrom_image_new( FILE *file );
4.77
4.78 -void gdrom_unmount( void );
4.79 +/**
4.80 + * Open an image file
4.81 + */
4.82 +gdrom_disc_t gdrom_image_open( const gchar *filename );
4.83 +gdrom_disc_t nrg_image_open( const gchar *filename );
4.84 +
4.85 +/**
4.86 + * Retrieve the disc table of contents, and write it into the buffer in the
4.87 + * format expected by the DC.
4.88 + * @return TRUE on success, FALSE on failure (eg no disc mounted)
4.89 + */
4.90 +gboolean gdrom_get_toc( char *buf );
4.91 +
4.92 +/**
4.93 + * Shortcut to open and mount an image file
4.94 + */
4.95 +gdrom_disc_t gdrom_mount_image( const gchar *filename );
4.96 +
4.97 +void gdrom_mount_disc( gdrom_disc_t disc );
4.98 +
4.99 +void gdrom_unmount_disc( void );
4.100 +
4.101 +gboolean gdrom_is_mounted( void );
4.102 +
4.103 +uint32_t gdrom_read_sectors( uint32_t sector, uint32_t sector_count,
4.104 + char *buf );
4.105
4.106 #endif
5.1 --- a/src/gdrom/ide.c Sun Apr 30 01:50:15 2006 +0000
5.2 +++ b/src/gdrom/ide.c Sun Apr 30 01:51:08 2006 +0000
5.3 @@ -1,5 +1,5 @@
5.4 /**
5.5 - * $Id: ide.c,v 1.8 2006-03-22 14:29:02 nkeynes Exp $
5.6 + * $Id: ide.c,v 1.9 2006-04-30 01:51:08 nkeynes Exp $
5.7 *
5.8 * IDE interface implementation
5.9 *
5.10 @@ -18,23 +18,32 @@
5.11
5.12 #define MODULE ide_module
5.13
5.14 +#include <assert.h>
5.15 #include <stdlib.h>
5.16 #include "dream.h"
5.17 #include "asic.h"
5.18 #include "gdrom/ide.h"
5.19 #include "gdrom/gdrom.h"
5.20
5.21 -#define MAX_WRITE_BUF 4096;
5.22 +#define MAX_WRITE_BUF 4096
5.23 +#define MAX_SECTOR_SIZE 2352 /* Audio sector */
5.24 +#define DEFAULT_DATA_SECTORS 8
5.25
5.26 -void ide_init( void );
5.27 -void ide_init( void );
5.28 +static void ide_init( void );
5.29 +static void ide_reset( void );
5.30 +static void ide_save_state( FILE *f );
5.31 +static int ide_load_state( FILE *f );
5.32 +static void ide_raise_interrupt( void );
5.33 +static void ide_clear_interrupt( void );
5.34
5.35 struct dreamcast_module ide_module = { "IDE", ide_init, ide_reset, NULL, NULL,
5.36 - NULL, NULL, NULL };
5.37 + NULL, ide_save_state, ide_load_state };
5.38
5.39 struct ide_registers idereg;
5.40
5.41 static unsigned char command_buffer[12];
5.42 +unsigned char *data_buffer = NULL;
5.43 +uint32_t data_buffer_len = 0;
5.44
5.45 /* "\0\0\0\0\xb4\x19\0\0\x08SE REV 6.42990316" */
5.46 unsigned char gdrom_ident[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0xb4, 0x19, 0x00,
5.47 @@ -43,7 +52,38 @@
5.48 0x34, 0x32, 0x39, 0x39, 0x30, 0x33, 0x31, 0x36 };
5.49
5.50
5.51 -gdrom_disc_t gdrom_disc = NULL;
5.52 +static void ide_init( void )
5.53 +{
5.54 + ide_reset();
5.55 + data_buffer_len = DEFAULT_DATA_SECTORS;
5.56 + data_buffer = malloc( MAX_SECTOR_SIZE * data_buffer_len );
5.57 + assert( data_buffer != NULL );
5.58 +}
5.59 +
5.60 +static void ide_reset( void )
5.61 +{
5.62 + ide_clear_interrupt();
5.63 + idereg.error = 0x01;
5.64 + idereg.count = 0x01;
5.65 + idereg.lba0 = /* 0x21; */ 0x81;
5.66 + idereg.lba1 = 0x14;
5.67 + idereg.lba2 = 0xeb;
5.68 + idereg.feature = 0; /* Indeterminate really */
5.69 + idereg.status = 0x00;
5.70 + idereg.device = 0x00;
5.71 + idereg.disc = gdrom_is_mounted() ? IDE_DISC_NONE : (IDE_DISC_CDROM|IDE_DISC_READY);
5.72 +}
5.73 +
5.74 +static void ide_save_state( FILE *f )
5.75 +{
5.76 +
5.77 +
5.78 +}
5.79 +
5.80 +static int ide_load_state( FILE *f )
5.81 +{
5.82 + return 0;
5.83 +}
5.84
5.85 static void ide_set_write_buffer( unsigned char *buf, int len )
5.86 {
5.87 @@ -90,25 +130,6 @@
5.88 idereg.error = error_code;
5.89 }
5.90
5.91 -void ide_init( void )
5.92 -{
5.93 -
5.94 -}
5.95 -
5.96 -void ide_reset( void )
5.97 -{
5.98 - ide_clear_interrupt();
5.99 - idereg.error = 0x01;
5.100 - idereg.count = 0x01;
5.101 - idereg.lba0 = /* 0x21; */ 0x81;
5.102 - idereg.lba1 = 0x14;
5.103 - idereg.lba2 = 0xeb;
5.104 - idereg.feature = 0; /* Indeterminate really */
5.105 - idereg.status = 0x00;
5.106 - idereg.device = 0x00;
5.107 - idereg.disc = (gdrom_disc == NULL ? IDE_DISC_NONE : (IDE_DISC_CDROM|IDE_DISC_READY));
5.108 -}
5.109 -
5.110 uint8_t ide_read_status( void )
5.111 {
5.112 if( (idereg.status & IDE_ST_BUSY) == 0 )
5.113 @@ -200,7 +221,7 @@
5.114
5.115 void ide_packet_command( unsigned char *cmd )
5.116 {
5.117 - uint32_t length;
5.118 + uint32_t length, datalen;
5.119 uint32_t lba;
5.120 int blocksize = idereg.lba1 + (idereg.lba2<<8);
5.121
5.122 @@ -219,22 +240,28 @@
5.123 ide_set_read_buffer(gdrom_ident, length, blocksize);
5.124 break;
5.125 case PKT_CMD_READ_TOC:
5.126 -
5.127 + if( !gdrom_get_toc( data_buffer ) ) {
5.128 + ide_set_error( 0x50 );
5.129 + return;
5.130 + }
5.131 + ide_set_read_buffer( data_buffer, sizeof( struct gdrom_toc ), blocksize );
5.132 break;
5.133 case PKT_CMD_READ_SECTOR:
5.134 lba = cmd[2] << 16 | cmd[3] << 8 | cmd[4];
5.135 length = cmd[8] << 16 | cmd[9] << 8 | cmd[10]; /* blocks */
5.136 - if( gdrom_disc == NULL ) {
5.137 + if( length > data_buffer_len ) {
5.138 + do {
5.139 + data_buffer_len = data_buffer_len << 1;
5.140 + } while( data_buffer_len < length );
5.141 + data_buffer = realloc( data_buffer, data_buffer_len );
5.142 + }
5.143 +
5.144 + datalen = gdrom_read_sectors( lba, length, data_buffer );
5.145 + if( datalen == 0 ) {
5.146 ide_set_error( 0x50 );
5.147 return;
5.148 }
5.149 - /*
5.150 - if( gdrom_disc->read_data_sectors( lba, length ) == FALSE ) {
5.151 - ide_set_error( 0x50 );
5.152 - return;
5.153 - }
5.154 -
5.155 - */
5.156 + ide_set_read_buffer( data_buffer, datalen, blocksize );
5.157 break;
5.158 }
5.159 }
6.1 --- a/src/gdrom/ide.h Sun Apr 30 01:50:15 2006 +0000
6.2 +++ b/src/gdrom/ide.h Sun Apr 30 01:51:08 2006 +0000
6.3 @@ -1,5 +1,5 @@
6.4 /**
6.5 - * $Id: ide.h,v 1.4 2006-03-22 14:29:02 nkeynes Exp $
6.6 + * $Id: ide.h,v 1.5 2006-04-30 01:51:08 nkeynes Exp $
6.7 *
6.8 * This file defines the interface and structures of the dreamcast's IDE
6.9 * port. Note that the register definitions are in asic.h, as the registers
6.10 @@ -37,7 +37,8 @@
6.11 uint8_t lba2; /* A05F7094 Read/Write 10101 */
6.12 uint8_t device; /* A05F7098 Read/Write 10110 */
6.13 uint8_t command; /* A05F709C Write-only 10111 */
6.14 -
6.15 + uint8_t intrq_pending; /* Flag to indicate if the INTRQ line is active */
6.16 +
6.17 /* We don't keep the data register per se, rather the currently pending
6.18 * data is kept here and read out a byte at a time (in PIO mode) or all at
6.19 * once (in DMA mode). The IDE routines are responsible for managing this
6.20 @@ -48,7 +49,6 @@
6.21 int datalen;
6.22 int blocksize; /* Used to determine the transfer unit size */
6.23 int blockleft; /* Bytes remaining in the current block */
6.24 - uint8_t intrq_pending; /* Flag to indicate if the INTRQ line is active */
6.25 };
6.26
6.27 #define IDE_ST_BUSY 0x80
6.28 @@ -67,21 +67,12 @@
6.29 #define IDE_CMD_SET_FEATURE 0xEF
6.30
6.31 #define IDE_FEAT_SET_TRANSFER_MODE 0x03
6.32 -
6.33 #define IDE_XFER_PIO 0x00
6.34 #define IDE_XFER_PIO_FLOW 0x08
6.35 #define IDE_XFER_MULTI_DMA 0x20
6.36 #define IDE_XFER_ULTRA_DMA 0x40
6.37
6.38 -/* The disc register indicates the current contents of the drive. When open
6.39 - * contains 0x06.
6.40 - */
6.41 -#define IDE_DISC_AUDIO 0x00
6.42 -#define IDE_DISC_NONE 0x06
6.43 -#define IDE_DISC_CDROM 0x20
6.44 -#define IDE_DISC_GDROM 0x80
6.45 -#define IDE_DISC_READY 0x01 /* ored with above */
6.46 -#define IDE_DISC_IDLE 0x02 /* ie spun-down */
6.47 +
6.48
6.49 #define PKT_CMD_RESET 0x00 /* Wild-ass guess */
6.50 #define PKT_CMD_IDENTIFY 0x11
6.51 @@ -97,7 +88,6 @@
6.52 #define ide_can_write_regs() ((idereg.status&0x88)==0)
6.53 #define IS_IDE_IRQ_ENABLED() ((idereg.control&0x02)==0)
6.54
6.55 -void ide_reset(void);
6.56
6.57 uint16_t ide_read_data_pio(void);
6.58 uint8_t ide_read_status(void);
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/src/gdrom/nrg.c Sun Apr 30 01:51:08 2006 +0000
7.3 @@ -0,0 +1,258 @@
7.4 +/**
7.5 + * $Id: nrg.c,v 1.1 2006-04-30 01:51:08 nkeynes Exp $
7.6 + *
7.7 + * Nero (NRG) CD file format. File information stolen shamelessly from
7.8 + * libcdio.
7.9 + *
7.10 + * Copyright (c) 2005 Nathan Keynes.
7.11 + *
7.12 + * This program is free software; you can redistribute it and/or modify
7.13 + * it under the terms of the GNU General Public License as published by
7.14 + * the Free Software Foundation; either version 2 of the License, or
7.15 + * (at your option) any later version.
7.16 + *
7.17 + * This program is distributed in the hope that it will be useful,
7.18 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
7.19 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
7.20 + * GNU General Public License for more details.
7.21 + */
7.22 +
7.23 +#include <assert.h>
7.24 +#include <stdio.h>
7.25 +#include <errno.h>
7.26 +#include "gdrom/gdrom.h"
7.27 +#include "dream.h"
7.28 +
7.29 +#define NERO_V55_ID 0x4e455235
7.30 +#define NERO_V50_ID 0x4e45524f
7.31 +
7.32 +/* Courtesy of libcdio */
7.33 +/* 5.0 or earlier */
7.34 +#define NERO_ID 0x4e45524f /* Nero pre 5.5.x */
7.35 +#define CUES_ID 0x43554553 /* Nero pre version 5.5.x-6.x */
7.36 +#define DAOI_ID 0x44414f49
7.37 +#define ETNF_ID 0x45544e46
7.38 +#define SINF_ID 0x53494e46 /* Session information */
7.39 +#define END_ID 0x454e4421
7.40 +/* 5.5+ only */
7.41 +#define NER5_ID 0x4e455235 /* Nero version 5.5.x */
7.42 +#define CDTX_ID 0x43445458 /* CD TEXT */
7.43 +#define CUEX_ID 0x43554558 /* Nero version 5.5.x-6.x */
7.44 +#define DAOX_ID 0x44414f58 /* Nero version 5.5.x-6.x */
7.45 +#define ETN2_ID 0x45544e32
7.46 +#define MTYP_ID 0x4d545950 /* Disc Media type? */
7.47 +
7.48 +
7.49 +union nrg_footer {
7.50 + struct nrg_footer_v50 {
7.51 + uint32_t dummy;
7.52 + uint32_t id;
7.53 + uint32_t offset;
7.54 + } v50;
7.55 + struct nrg_footer_v55 {
7.56 + uint32_t id;
7.57 + uint64_t offset;
7.58 + } v55;
7.59 +};
7.60 +
7.61 +struct nrg_chunk {
7.62 + uint32_t id;
7.63 + uint32_t length;
7.64 +};
7.65 +
7.66 +struct nrg_etnf {
7.67 + uint32_t offset;
7.68 + uint32_t length;
7.69 + uint32_t mode;
7.70 + uint32_t lba;
7.71 + uint32_t padding;
7.72 +};
7.73 +
7.74 +struct nrg_cues {
7.75 + uint8_t type;
7.76 + uint8_t track;
7.77 + uint8_t control;
7.78 + uint8_t pad;
7.79 + uint32_t addr;
7.80 +};
7.81 +
7.82 +struct nrg_daoi {
7.83 + uint32_t length;
7.84 + char mcn[14];
7.85 + uint8_t disc_mode;
7.86 + uint8_t unknown[2]; /* always 01 01? */
7.87 + uint8_t track_count;
7.88 + struct nrg_daoi_track {
7.89 + char unknown[10];
7.90 + uint32_t sector_size __attribute__((packed)); /* Always 0? */
7.91 + uint8_t mode;
7.92 + uint8_t unknown2[3]; /* Always 00 00 01? */
7.93 + uint32_t pregap __attribute__((packed));
7.94 + uint32_t offset __attribute__((packed));
7.95 + uint32_t end __attribute__((packed));
7.96 + } track[0];
7.97 +} __attribute__((packed));
7.98 +
7.99 +/**
7.100 + * Convert an 8-bit BCD number to normal integer form.
7.101 + * Eg, 0x79 => 79
7.102 + */
7.103 +uint8_t static bcd_to_uint8( uint8_t bcd )
7.104 +{
7.105 + return (bcd & 0x0F) + (((bcd & 0xF0)>>4)*10);
7.106 +}
7.107 +
7.108 +
7.109 +/**
7.110 + * Convert a 32 bit MSF address (BCD coded) to the
7.111 + * equivalent LBA form.
7.112 + * Eg, 0x
7.113 + */
7.114 +uint32_t static msf_to_lba( uint32_t msf )
7.115 +{
7.116 + msf = ntohl(msf);
7.117 + int f = bcd_to_uint8(msf);
7.118 + int s = bcd_to_uint8(msf>>8);
7.119 + int m = bcd_to_uint8(msf>>16);
7.120 + return (m * 60 + s) * 75 + f;
7.121 +
7.122 +}
7.123 +
7.124 +uint32_t static nrg_track_mode( uint8_t mode )
7.125 +{
7.126 + switch( mode ) {
7.127 + case 0: return GDROM_MODE1;
7.128 + case 2: return GDROM_MODE2_XA1;
7.129 + case 3: return GDROM_MODE2;
7.130 + case 7: return GDROM_CDDA;
7.131 + default:
7.132 + ERROR( "Unrecognized track mode %d in Nero image", mode );
7.133 + return -1;
7.134 + }
7.135 +}
7.136 +
7.137 +gdrom_disc_t nrg_image_open( const gchar *filename )
7.138 +{
7.139 + FILE *f = fopen( filename, "ro" );
7.140 + union nrg_footer footer;
7.141 + struct nrg_chunk chunk;
7.142 + struct nrg_daoi *dao;
7.143 + gdrom_disc_t disc;
7.144 + gboolean end = FALSE;
7.145 + int session_id = 0;
7.146 + int session_track_id = 0;
7.147 + int track_id = 0;
7.148 + int cue_track_id = 0, cue_track_count = 0;
7.149 + int i;
7.150 +
7.151 + if( f == NULL ) {
7.152 + ERROR( "Unable to open file '%s': %s", filename, strerror(errno) );
7.153 + return NULL;
7.154 + }
7.155 +
7.156 + fseek( f, -12, SEEK_END );
7.157 + fread( &footer, sizeof(footer), 1, f );
7.158 + if( ntohl(footer.v50.id) == NERO_V50_ID ) {
7.159 + INFO( "Loading Nero 5.0 image" );
7.160 + fseek( f, ntohl(footer.v50.offset), SEEK_SET );
7.161 + } else if( ntohl(footer.v55.id) == NERO_V55_ID ) {
7.162 + INFO( "Loading Nero 5.5+ image" );
7.163 + fseek( f, ntohl(footer.v55.offset), SEEK_SET );
7.164 + } else {
7.165 + ERROR("Unable to understand file '%s' as a Nero image", filename );
7.166 + return NULL;
7.167 + }
7.168 +
7.169 + disc = gdrom_image_new(f);
7.170 + if( disc == NULL ) {
7.171 + ERROR("Unable to allocate memory!");
7.172 + fclose(f);
7.173 + return NULL;
7.174 + }
7.175 +
7.176 + do {
7.177 + fread( &chunk, sizeof(chunk), 1, f );
7.178 + chunk.length = ntohl(chunk.length);
7.179 + char data[chunk.length];
7.180 + fread( data, chunk.length, 1, f );
7.181 + switch( ntohl(chunk.id) ) {
7.182 + case CUES_ID:
7.183 + cue_track_id = track_id;
7.184 + cue_track_count = ((chunk.length / sizeof(struct nrg_cues)) >> 1) - 1;
7.185 + track_id += cue_track_count;
7.186 + for( i=0; i<chunk.length; i+= sizeof(struct nrg_cues) ) {
7.187 + struct nrg_cues *cue = (struct nrg_cues *)(data+i);
7.188 + int track = 0;
7.189 + if( cue->track == 0 )
7.190 + continue; /* Track 0. Leadin? always 0? */
7.191 + if( cue->track == 0xAA ) { /* end of disc */
7.192 + disc->track[track_id-1].sector_count =
7.193 + msf_to_lba( cue->addr ) - disc->track[track_id-1].lba;
7.194 + } else {
7.195 + track = cue_track_id + bcd_to_uint8(cue->track) - 1;
7.196 + if( (cue->control & 0x01) == 0 ) {
7.197 + /* Pre-gap address. */
7.198 + if( track != 0 ) {
7.199 + disc->track[track-1].sector_count =
7.200 + msf_to_lba( cue->addr ) - disc->track[track-1].lba;
7.201 + }
7.202 + } else { /* Track-start address */
7.203 + disc->track[track].lba = msf_to_lba( cue->addr );
7.204 +
7.205 + }
7.206 + }
7.207 + }
7.208 + break;
7.209 + case DAOI_ID:
7.210 + dao = (struct nrg_daoi *)data;
7.211 + memcpy( disc->mcn, dao->mcn, 13 );
7.212 + disc->mcn[13] = '\0';
7.213 + assert( dao->track_count * 30 + 22 == chunk.length );
7.214 + assert( dao->track_count == cue_track_count );
7.215 + for( i=0; i<dao->track_count; i++ ) {
7.216 + disc->track[cue_track_id].sector_size = ntohl(dao->track[i].sector_size);
7.217 + disc->track[cue_track_id].offset = ntohl(dao->track[i].offset);
7.218 + disc->track[cue_track_id].mode = nrg_track_mode( dao->track[i].mode );
7.219 + assert( disc->track[cue_track_id].sector_count ==
7.220 + (ntohl(dao->track[i].end) - ntohl(dao->track[i].offset))/
7.221 + ntohl(dao->track[i].sector_size) );
7.222 + cue_track_id++;
7.223 + }
7.224 + break;
7.225 + case SINF_ID:
7.226 + /* Data is a single 32-bit number representing number of tracks in session */
7.227 + i = ntohl( *(uint32_t *)data );
7.228 + while( i-- > 0 )
7.229 + disc->track[session_track_id++].session = session_id;
7.230 + session_id++;
7.231 + break;
7.232 + case ETNF_ID:
7.233 + for( i=0; i < chunk.length; i+= 0x14 ) {
7.234 + struct nrg_etnf *etnf = (struct nrg_etnf *)(data+i);
7.235 + disc->track[track_id].offset = ntohl(etnf->offset);
7.236 + disc->track[track_id].lba = ntohl(etnf->lba) + (i+1)*GDROM_PREGAP;
7.237 + disc->track[track_id].mode = nrg_track_mode( ntohl(etnf->mode) );
7.238 + if( disc->track[track_id].mode == -1 ) {
7.239 + disc->close(disc);
7.240 + return NULL;
7.241 + }
7.242 + disc->track[track_id].sector_size = GDROM_SECTOR_SIZE(disc->track[track_id].mode);
7.243 + disc->track[track_id].sector_count = ntohl(etnf->length) /
7.244 + disc->track[track_id].sector_size;
7.245 + track_id++;
7.246 + }
7.247 + break;
7.248 + case END_ID:
7.249 + end = TRUE;
7.250 + break;
7.251 + }
7.252 + } while( !end );
7.253 + disc->track_count = track_id;
7.254 + return disc;
7.255 +}
7.256 +
7.257 +gboolean nrg_read_sectors( struct gdrom_disc *disc, uint32_t lba, uint32_t count, char *buf )
7.258 +{
7.259 + return FALSE;
7.260 +}
7.261 +
.