www.pudn.com > ngcd080s.zip > CDROM.C


/************************************** 
****    CDROM.C  -  File reading   **** 
**************************************/ 
 
//-- Include files ----------------------------------------------------------- 
#include  
#include  
#include  
#include  
#include  
#include  
#include "../cdaudio/cdaudio.h" 
#include "../video/video.h" 
#include "../memory/memory.h" 
#include "../mc68000/68kregs.h" 
#include "../z80/z80intrf.h" 
#include "../ym2610/adpcm.h" 
 
//-- Definitions ------------------------------------------------------------- 
#define	BUFFER_SIZE	131072 
#define PRG_TYPE	0 
#define FIX_TYPE	1 
#define SPR_TYPE	2 
#define Z80_TYPE	3 
#define PAT_TYPE	4 
#define PCM_TYPE	5 
 
//-- Imported Variables ------------------------------------------------------ 
extern	char			global_error[]; 
extern	char			*neogeo_prg_memory; 
extern	char			*neogeo_spr_memory; 
extern	char			*neogeo_fix_memory; 
extern	char			*neogeo_pcm_memory; 
extern	Registers68K	regs; 
extern	int				video_mode; 
extern	int				config_scanlines; 
 
//-- Imported Functions ------------------------------------------------------ 
extern void			extract8(char *, char *); 
extern unsigned int	motorola_peek(int); 
extern void			motorola_poke(int, int); 
extern void			neogeo_fast_copy(void *, void *, int, int, int, int, int,  
						int); 
extern void			neogeo_fast_copy_scanlines(void *, void *, int, int, int,  
						int, int, int); 
//-- Exported Functions ------------------------------------------------------ 
int		cdrom_init(void); 
int		cdrom_load_prg_file(char *, unsigned int); 
int		cdrom_load_z80_file(char *, unsigned int); 
int		cdrom_load_fix_file(char *, unsigned int); 
int		cdrom_load_spr_file(char *, unsigned int); 
int		cdrom_load_pcm_file(char *, unsigned int); 
int		cdrom_load_pat_file(char *, unsigned int, unsigned int); 
void	cdrom_load_files(void); 
int		cdrom_process_ipl(void); 
void	cdrom_shutdown(void); 
void	fix_conv(unsigned char *, unsigned char *, int, unsigned char *); 
void	spr_conv(unsigned char *, unsigned char *, int, unsigned char *); 
void	neogeo_upload(void); 
void	cdrom_load_title(void); 
void	cdrom_apply_patch(short *source, int offset, int bank); 
 
//-- Private Variables ------------------------------------------------------- 
static char	cdrom_buffer[BUFFER_SIZE]; 
 
//-- Private Function -------------------------------------------------------- 
static	int	recon_filetype(char *); 
 
//-- Exported Variables ------------------------------------------------------ 
int		cdrom_current_drive; 
BITMAP	*loading_pict; 
int		img_display = 1; 
 
//-- Defines ----------------------------------------------------------------- 
#define	min(a, b)	((a) < (b)) ? (a) : (b) 
 
//---------------------------------------------------------------------------- 
int	cdrom_init(void) 
{ 
	PACKFILE	*fp; 
	int			toto; 
	 
	fp = pack_fopen("loading.img", "rp"); 
	pack_fread(loading_pict->line[0], 153600L, fp); 
	pack_fclose(fp); 
	 
	return 1; 
} 
 
//---------------------------------------------------------------------------- 
void	cdrom_shutdown(void) 
{ 
} 
 
//---------------------------------------------------------------------------- 
int	cdrom_load_prg_file(char *FileName, unsigned int Offset) 
{ 
	FILE	*fp; 
	char	Path[16]; 
	char	*Ptr; 
	int		Readed; 
 
	strcpy(Path, "X:\\"); 
	Path[0] = cdrom_current_drive + 65; 
	strcat(Path, FileName); 
	 
	fp = fopen(Path, "rb"); 
	if (fp==NULL) { 
		sprintf(global_error, "Could not open %s", Path); 
		return 0; 
	} 
	 
	if (video_mode <= 0) 
		printf("CDROM: Loading PRG: %s, %08x...\n", Path, Offset); 
	 
	Ptr = neogeo_prg_memory + Offset; 
	 
	do { 
		Readed = fread(cdrom_buffer, 1, BUFFER_SIZE, fp); 
		swab(cdrom_buffer, Ptr, Readed); 
		Ptr += Readed; 
	} while( Readed==BUFFER_SIZE ); 
	 
	fclose(fp); 
	 
	return 1; 
} 
 
//---------------------------------------------------------------------------- 
int	cdrom_load_z80_file(char *FileName, unsigned int Offset) 
{ 
	FILE	*fp; 
	char	Path[16]; 
	char	*Ptr; 
	int		Readed; 
 
	strcpy(Path, "X:\\"); 
	Path[0] = cdrom_current_drive + 65; 
	strcat(Path, FileName); 
	 
	fp = fopen(Path, "rb"); 
	if (fp==NULL) { 
		sprintf(global_error, "Could not open %s", Path); 
		return 0; 
	} 
 
	if (video_mode <= 0) 
		printf("CDROM: Loading Z80: %s, %08x...\n", Path, Offset); 
 
	fread( &subcpu_memspace, 1, 65536, fp); 
 
	fclose(fp); 
 
	return 1; 
} 
 
//---------------------------------------------------------------------------- 
int	cdrom_load_fix_file(char *FileName, unsigned int Offset) 
{ 
	FILE	*fp; 
	char	Path[16]; 
	char	*Ptr, *Src; 
	int		Readed; 
 
	strcpy(Path, "X:\\"); 
	Path[0] = cdrom_current_drive + 65; 
	strcat(Path, FileName); 
	 
	fp = fopen(Path, "rb"); 
	if (fp==NULL) { 
		sprintf(global_error, "Could not open %s", Path); 
		return 0; 
	} 
	 
	if (video_mode <= 0) 
		printf("CDROM: Loading FIX: %s, %08x...\n", Path, Offset); 
	 
	Ptr = neogeo_fix_memory + Offset; 
	 
	do { 
		memset(cdrom_buffer, 0, BUFFER_SIZE); 
		Readed = fread(cdrom_buffer, 1, BUFFER_SIZE, fp); 
		Src = cdrom_buffer; 
		fix_conv(Src, Ptr, Readed, video_fix_usage + (Offset>>5)); 
		Ptr += Readed; 
		Offset += Readed; 
	} while( Readed == BUFFER_SIZE ); 
	 
	fclose(fp); 
	 
	return 1; 
} 
 
//---------------------------------------------------------------------------- 
int	cdrom_load_spr_file(char *FileName, unsigned int Offset) 
{ 
	FILE	*fp; 
	char	Path[16]; 
	char	*Ptr; 
	int		Readed; 
 
	strcpy(Path, "X:\\"); 
	Path[0] = cdrom_current_drive + 65; 
	strcat(Path, FileName); 
	 
	fp = fopen(Path, "rb"); 
	if (fp==NULL) { 
		sprintf(global_error, "Could not open %s", Path); 
		return 0; 
	} 
	 
	if (video_mode <= 0) 
		printf("CDROM: Loading SPR: %s, %08x...\n", Path, Offset); 
	 
	Ptr = neogeo_spr_memory + Offset; 
	 
	do { 
		memset(cdrom_buffer, 0, BUFFER_SIZE); 
		Readed = fread(cdrom_buffer, 1, BUFFER_SIZE, fp); 
		spr_conv(cdrom_buffer, Ptr, Readed, video_spr_usage + (Offset>>7)); 
		Offset += Readed; 
		Ptr += Readed; 
	} while( Readed == BUFFER_SIZE ); 
	 
	fclose(fp); 
	 
	return 1; 
} 
 
//---------------------------------------------------------------------------- 
int	cdrom_load_pcm_file(char *FileName, unsigned int Offset) 
{ 
	FILE		*fp; 
	char		Path[16]; 
	char		*Ptr, *Src; 
	int			Readed; 
 
	strcpy(Path, "X:\\"); 
	Path[0] = cdrom_current_drive + 65; 
	strcat(Path, FileName); 
	 
	fp = fopen(Path, "rb"); 
	if (fp==NULL) { 
		sprintf(global_error, "Could not open %s", Path); 
		return 0; 
	} 
	 
	if (video_mode <= 0) 
		printf("CDROM: Loading PCM: %s, %08x...\n", Path, Offset); 
 
	Ptr = neogeo_pcm_memory + Offset; 
	fread(Ptr, 1, 0x100000, fp); 
 
	fclose(fp); 
 
	return 1; 
} 
 
//---------------------------------------------------------------------------- 
int	cdrom_load_pat_file(char *FileName, unsigned int Offset, unsigned int Bank) 
{ 
	FILE	*fp; 
	char	Path[16]; 
	char	*Ptr, *Src; 
	int		Readed; 
 
	strcpy(Path, "X:\\"); 
	Path[0] = cdrom_current_drive + 65; 
	strcat(Path, FileName); 
	 
	fp = fopen(Path, "rb"); 
	if (fp==NULL) { 
		sprintf(global_error, "Could not open %s", Path); 
		return 0; 
	} 
	 
	if (video_mode <= 0) 
		printf("CDROM: Loading PAT: %s, %08x...\n", Path, Offset); 
 
 
	Readed = fread(cdrom_buffer, 1, BUFFER_SIZE, fp); 
	swab(cdrom_buffer, cdrom_buffer, Readed); 
	cdrom_apply_patch((short*)cdrom_buffer, Offset, Bank); 
 
	fclose(fp); 
 
	return 1; 
} 
 
//---------------------------------------------------------------------------- 
int	cdrom_process_ipl(void) 
{ 
	FILE	*fp; 
	char	Path[16]; 
	char	Line[32]; 
	char	FileName[16]; 
	char	Bank[4]; 
	char	Offset[8]; 
	int		FileType; 
	int		Bnk; 
	int		Off; 
	int		i, j; 
 
	strcpy(Path, "X:\\"); 
	Path[0] = cdrom_current_drive + 65; 
	strcat(Path, "IPL.TXT"); 
	 
	fp = fopen(Path, "rb"); 
	 
	if (fp==NULL) { 
		strcpy(global_error, "Could not open IPL.TXT!"); 
		return 0; 
	} 
	while (fgets(Line, 32, fp)!=NULL) 
	{ 
		i=0; 
		j=0; 
		while((Line[i] != ',')&&(Line[i]!=0)) 
			FileName[j++] = toupper(Line[i++]); 
		FileName[j]=0; 
 
		j -= 3; 
		if (j>0) { 
			FileType = recon_filetype(&FileName[j]); 
			i++; 
			j=0; 
			while(Line[i] != ',') 
				Bank[j++] = Line[i++]; 
			Bank[j]=0; 
			i++; 
			j=0; 
			while(Line[i] != 0x0D) 
				Offset[j++] = Line[i++]; 
			Offset[j] = 0; 
	 
			sscanf(Bank, "%d", &Bnk); 
			sscanf(Offset, "%08x", &Off); 
	 
			switch( FileType ) { 
			case PRG_TYPE: 
				if (!cdrom_load_prg_file(FileName, Off)) { 
					fclose(fp); 
					return 0; 
				} 
				break; 
			case FIX_TYPE: 
				if (!cdrom_load_fix_file(FileName, (Off>>1))) { 
					fclose(fp); 
					return 0; 
				} 
				break; 
			case SPR_TYPE: 
				if (!cdrom_load_spr_file(FileName, (Bnk*0x100000) + Off)) { 
					fclose(fp); 
					return 0; 
				} 
				break; 
			case Z80_TYPE: 
				if (!cdrom_load_z80_file(FileName, Off)) { 
					fclose(fp); 
					return 0; 
				} 
				break; 
			case PAT_TYPE: 
				if (!cdrom_load_pat_file(FileName, Off, Bnk)) { 
					fclose(fp); 
					return 0; 
				} 
				break; 
			case PCM_TYPE: 
				if (!cdrom_load_pcm_file(FileName, (Bnk*0x80000) + (Off>>1))) { 
					fclose(fp); 
					return 0; 
				} 
				break; 
			} 
		} 
	} 
	 
	fclose(fp); 
	 
	return 1; 
} 
 
//---------------------------------------------------------------------------- 
int	recon_filetype(char *ext) 
{	 
	if (strcmp(ext, "PRG")==0) 
		return PRG_TYPE; 
	 
	if (strcmp(ext, "FIX")==0) 
		return FIX_TYPE; 
	 
	if (strcmp(ext, "SPR")==0) 
		return SPR_TYPE; 
		 
	if (strcmp(ext, "Z80")==0) 
		return Z80_TYPE; 
		 
	if (strcmp(ext, "PAT")==0) 
		return PAT_TYPE; 
	 
	if (strcmp(ext, "PCM")==0) 
		return PCM_TYPE; 
		 
	return	-1; 
} 
 
//---------------------------------------------------------------------------- 
void	cdrom_load_files(void) 
{ 
	char	Entry[32], FileName[13], Ext[4]; 
	char	*Ptr; 
	int		i, j, Bnk, Off, Type, Reliquat; 
	 
	sound_mute(); 
 
	if (cpu_readmem24(regs.a0)==0) 
		return; 
 
	if (cdda_playing) 
	{ 
		cdda_stop(); 
		cdda_current_track = 0; 
	} 
 
	cpu_writemem24_dword(0x10F68C, 0x00000000); 
	cpu_writemem24(0x10F6C3, 0x00); 
	cpu_writemem24(0x10F6D9, 0x01); 
	cpu_writemem24(0x10F6DB, 0x01); 
	cpu_writemem24_dword(0x10F742, 0x00000000); 
	cpu_writemem24_dword(0x10F746, 0x00000000); 
	cpu_writemem24(0x10FDC2, 0x01); 
	cpu_writemem24(0x10FDDC, 0x00); 
	cpu_writemem24(0x10FDDD, 0x00); 
	cpu_writemem24(0x10FE85, 0x01); 
	cpu_writemem24(0x10FE88, 0x00); 
	cpu_writemem24(0x10FEC4, 0x01); 
 
	//video_set_txt_mode(); 
 
	if (video_mode <= 0) 
		printf("Load list at : %08x\n", regs.a0); 
	else if (img_display == 1) 
	{ 
		if (config_scanlines) 
			neogeo_fast_copy_scanlines(loading_pict, screen, 0, 0, 0, 0, 320, 
				240); 
		else 
			neogeo_fast_copy(loading_pict, screen, 0, 0, 0, 0, 320, 240); 
	} 
 
	Ptr = neogeo_prg_memory + regs.a0; 
	 
	do { 
		Reliquat = ((int)Ptr)&1; 
 
		if (Reliquat) 
			Ptr--; 
 
		swab(Ptr, Entry, 32); 
		i=Reliquat; 
//		while(i<32) 
//			printf("%02x ", (unsigned char)Ptr[i++]); 
//		printf("\n"); 
 
		while((Entry[i]!=0)&&(Entry[i]!=';')) 
			FileName[i-Reliquat] = toupper(Entry[i++]); 
		 
		FileName[i-Reliquat] = 0; 
 
		if (Entry[i]==';')	/* 01/05/99 MSLUG2 FIX */ 
			i += 2; 
 
		i++; 
 
		Bnk = Entry[i++]; 
		 
		if (i&1) 
			i++; 
		 
		Off = motorola_peek((unsigned int)&Entry[i]); 
		i += 4; 
		Ptr += i; 
		 
//		printf(" %s %02x %08x\n", FileName, Bnk, Off); 
 
		j=0; 
		 
		while(FileName[j] != 0x2e) 
			j++; 
		 
		j++; 
		Ext[0] = FileName[j++]; 
		Ext[1] = FileName[j++]; 
		Ext[2] = FileName[j]; 
		Ext[3] = 0; 
 
		Type = recon_filetype(Ext); 
 
		switch( Type ) { 
		case PRG_TYPE: 
			cdrom_load_prg_file(FileName, Off); 
			break; 
		case FIX_TYPE: 
			cdrom_load_fix_file(FileName, Off>>1); 
			break; 
		case SPR_TYPE: 
			cdrom_load_spr_file(FileName, (Bnk*0x100000) + Off); 
			break; 
		case Z80_TYPE: 
			cdrom_load_z80_file(FileName, Off); 
			break; 
		case PAT_TYPE: 
			cdrom_load_pat_file(FileName, Off, Bnk); 
			break; 
		case PCM_TYPE: 
			cdrom_load_pcm_file(FileName, (Bnk*0x80000) + (Off>>1)); 
			break; 
		} 
 
	} while( Entry[i] != 0); 
 
//	clear_keybuf(); 
//	readkey(); 
//	video_set_gfx_mode(); 
 
	if (img_display == 1) 
		clear(screen); 
} 
 
//---------------------------------------------------------------------------- 
void	fix_conv(unsigned char *Src, unsigned char *Ptr, int Taille,  
	unsigned char *usage_ptr) 
{ 
	int		i; 
	unsigned char	usage; 
	 
	for(i=Taille;i>0;i-=32) { 
		usage = 0; 
		*Ptr++ = *(Src+16); 
		usage |= *(Src+16); 
		*Ptr++ = *(Src+24); 
		usage |= *(Src+24); 
		*Ptr++ = *(Src); 
		usage |= *(Src); 
		*Ptr++ = *(Src+8); 
		usage |= *(Src+8); 
		Src++; 
		*Ptr++ = *(Src+16); 
		usage |= *(Src+16); 
		*Ptr++ = *(Src+24); 
		usage |= *(Src+24); 
		*Ptr++ = *(Src); 
		usage |= *(Src); 
		*Ptr++ = *(Src+8); 
		usage |= *(Src+8); 
		Src++; 
		*Ptr++ = *(Src+16); 
		usage |= *(Src+16); 
		*Ptr++ = *(Src+24); 
		usage |= *(Src+24); 
		*Ptr++ = *(Src); 
		usage |= *(Src); 
		*Ptr++ = *(Src+8); 
		usage |= *(Src+8); 
		Src++; 
		*Ptr++ = *(Src+16); 
		usage |= *(Src+16); 
		*Ptr++ = *(Src+24); 
		usage |= *(Src+24); 
		*Ptr++ = *(Src); 
		usage |= *(Src); 
		*Ptr++ = *(Src+8); 
		usage |= *(Src+8); 
		Src++; 
		*Ptr++ = *(Src+16); 
		usage |= *(Src+16); 
		*Ptr++ = *(Src+24); 
		usage |= *(Src+24); 
		*Ptr++ = *(Src); 
		usage |= *(Src); 
		*Ptr++ = *(Src+8); 
		usage |= *(Src+8); 
		Src++; 
		*Ptr++ = *(Src+16); 
		usage |= *(Src+16); 
		*Ptr++ = *(Src+24); 
		usage |= *(Src+24); 
		*Ptr++ = *(Src); 
		usage |= *(Src); 
		*Ptr++ = *(Src+8); 
		usage |= *(Src+8); 
		Src++; 
		*Ptr++ = *(Src+16); 
		usage |= *(Src+16); 
		*Ptr++ = *(Src+24); 
		usage |= *(Src+24); 
		*Ptr++ = *(Src); 
		usage |= *(Src); 
		*Ptr++ = *(Src+8); 
		usage |= *(Src+8); 
		Src++; 
		*Ptr++ = *(Src+16); 
		usage |= *(Src+16); 
		*Ptr++ = *(Src+24); 
		usage |= *(Src+24); 
		*Ptr++ = *(Src); 
		usage |= *(Src); 
		*Ptr++ = *(Src+8); 
		usage |= *(Src+8); 
		Src+=25; 
		*usage_ptr++ = usage; 
	}	 
} 
 
//---------------------------------------------------------------------------- 
void spr_conv(unsigned char *Src1, unsigned char *Ptr, int Taille, 
	unsigned char *usage_ptr) 
{ 
	unsigned char	*Src2; 
	unsigned char	reference[128]; 
	register int	i; 
 
	memset(reference, 0, 128); 
	Src2 = Src1 + 64; 
 
	for(i=Taille;i>0;i-=128) { 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		extract8(Src2, Ptr); 
		Src2 += 4; 
		Ptr  += 4; 
		extract8(Src1, Ptr); 
		Src1 += 4; 
		Ptr  += 4; 
		 
		Src1 += 64; 
		Src2 += 64; 
		 
		if (memcmp(reference, Ptr-128, 128)==0) 
			*usage_ptr++ = 0; 
		else 
			*usage_ptr++ = 1; 
	} 
} 
 
//---------------------------------------------------------------------------- 
void	neogeo_upload(void) 
{ 
	int		Zone; 
	int		Taille; 
	int		Banque; 
	int		Offset = 0; 
	unsigned char	*Source; 
	unsigned char	*Dest; 
	FILE			*fp; 
	 
	Zone = cpu_readmem24(0x10FEDA); 
	 
/*	fp = fopen("C:\\TMP\\UPLOAD.LOG", "at"); 
	 
	fprintf(fp, "%02x: %06x, %06x:%02x, %08x\n", 
		Zone, 
		cpu_readmem24_dword(0x10FEF8), 
		cpu_readmem24_dword(0x10FEF4), 
		cpu_readmem24(0x10FEDB), 
		cpu_readmem24_dword(0x10FEFC)); 
	 
	fclose(fp);*/ 
 
	switch( Zone&0x0F ) 
	{ 
	case	0:	// PRG 
 
		Source = neogeo_prg_memory + cpu_readmem24_dword(0x10FEF8); 
		Dest = neogeo_prg_memory + cpu_readmem24_dword(0x10FEF4); 
		Taille = cpu_readmem24_dword(0x10FEFC); 
		 
		memcpy(Dest, Source, Taille); 
		 
		cpu_writemem24_dword( 0x10FEF4, cpu_readmem24_dword(0x10FEF4) + Taille ); 
 
		break;		 
 
	case	2:	// SPR 
		Banque = cpu_readmem24(0x10FEDB); 
		Source = neogeo_prg_memory + cpu_readmem24_dword(0x10FEF8); 
		Offset = cpu_readmem24_dword(0x10FEF4) + (Banque<<20); 
		Dest = neogeo_spr_memory + Offset; 
		Taille = cpu_readmem24_dword(0x10FEFC); 
		 
		do { 
			memset(cdrom_buffer, 0, BUFFER_SIZE); 
			swab(Source, cdrom_buffer, min(BUFFER_SIZE, Taille)); 
			spr_conv(cdrom_buffer, Dest, min(BUFFER_SIZE, Taille),  
				video_spr_usage + (Offset>>7)); 
			Source += min(BUFFER_SIZE, Taille); 
			Dest += min(BUFFER_SIZE, Taille); 
			Offset += min(BUFFER_SIZE, Taille); 
			Taille -= min(BUFFER_SIZE, Taille); 
		} while(Taille!=0); 
		 
		 
		// Mise à jour des valeurs 
		Offset = cpu_readmem24_dword( 0x10FEF4 ); 
		Banque = cpu_readmem24( 0x10FEDB ); 
		Taille = cpu_readmem24( 0x10FEFC ); 
		 
		Offset += Taille; 
		 
		while (Offset > 0x100000 ) 
		{ 
			Banque++; 
			Offset -= 0x100000; 
		} 
		 
		cpu_writemem24_dword( 0x10FEF4, Offset ); 
		cpu_writemem24_word( 0x10FEDB, Banque ); 
		 
		break; 
 
	case	1:	// FIX 
		Source = neogeo_prg_memory + cpu_readmem24_dword(0x10FEF8); 
		Offset = cpu_readmem24_dword(0x10FEF4)>>1; 
		Dest = neogeo_fix_memory + Offset; 
		Taille = cpu_readmem24_dword(0x10FEFC); 
 
		do { 
			memset(cdrom_buffer, 0, BUFFER_SIZE); 
			swab(Source, cdrom_buffer, min(BUFFER_SIZE, Taille)); 
			fix_conv(cdrom_buffer, Dest, min(BUFFER_SIZE, Taille),  
				video_fix_usage + (Offset>>5)); 
			Source += min(BUFFER_SIZE, Taille); 
			Dest += min(BUFFER_SIZE, Taille); 
			Offset += min(BUFFER_SIZE, Taille); 
			Taille -= min(BUFFER_SIZE, Taille); 
		} while(Taille!=0); 
		 
		Offset = cpu_readmem24_dword( 0x10FEF4 ); 
		Taille = cpu_readmem24_dword( 0x10FEFC ); 
		 
		Offset += (Taille<<1); 
		 
		cpu_writemem24_dword( 0x10FEF4, Offset); 
		 
		break; 
 
	case	3:	// Z80 
 
		Source = neogeo_prg_memory + cpu_readmem24_dword(0x10FEF8); 
		Dest = subcpu_memspace + (cpu_readmem24_dword(0x10FEF4)>>1); 
		Taille = cpu_readmem24_dword(0x10FEFC); 
		 
		swab(Source, Dest, Taille); 
 
		cpu_writemem24_dword( 0x10FEF4, cpu_readmem24_dword(0x10FEF4) + (Taille<<1) ); 
 
		break;		 
 
	case	5:	// Z80 patch 
 
		Source = neogeo_prg_memory + cpu_readmem24_dword(0x10FEF8); 
		cdrom_apply_patch((short*)Source, cpu_readmem24_dword(0x10FEF4), cpu_readmem24(0x10FEDB)); 
 
		break; 
	 
	case	4:	// PCM 
		Banque = cpu_readmem24(0x10FEDB); 
		Source = neogeo_prg_memory + cpu_readmem24_dword(0x10FEF8); 
		Offset = (cpu_readmem24_dword(0x10FEF4)>>1) + (Banque<<19); 
		Dest = neogeo_pcm_memory + Offset; 
		Taille = cpu_readmem24_dword(0x10FEFC); 
		 
		swab( Source, Dest, Taille);		 
		 
		// Mise à jour des valeurs 
		Offset = cpu_readmem24_dword( 0x10FEF4 ); 
		Banque = cpu_readmem24( 0x10FEDB ); 
		Taille = cpu_readmem24( 0x10FEFC ); 
		 
		Offset += (Taille<<1); 
		 
		while (Offset > 0x100000 ) 
		{ 
			Banque++; 
			Offset -= 0x100000; 
		} 
		 
		cpu_writemem24_dword( 0x10FEF4, Offset ); 
		cpu_writemem24_word( 0x10FEDB, Banque ); 
 
		break;	 
		 
	} 
} 
 
//---------------------------------------------------------------------------- 
void cdrom_load_title(void) 
{ 
	static char		*jue = "JUE"; 
	static char		*file = "X:\\TITLE_X.SYS"; 
	FILE			*fp; 
	char			*Ptr; 
	int				Readed; 
	int				x, y; 
 
	file[9] = jue[cpu_readmem24(0x10FD83)&3]; 
	file[0] = cdrom_current_drive + 65; 
 
	 
	fp = fopen(file, "rb"); 
	if (fp==NULL) 
	{ 
		clear(game_title); 
		return; 
	} 
	 
	fread(video_paletteram_pc, 1, 0x5A0, fp); 
	swab(video_paletteram_pc, video_paletteram_pc, 0x5A0); 
	 
	for(Readed=0;Readed<720;Readed++) 
		video_paletteram_pc[Readed] = video_color_lut[video_paletteram_pc[Readed]]; 
	 
	Ptr = neogeo_spr_memory; 
	 
	Readed = fread(cdrom_buffer, 1, BUFFER_SIZE, fp); 
	spr_conv(cdrom_buffer, Ptr, Readed, video_spr_usage); 
	fclose(fp); 
 
	Readed = 0; 
	for(y=0;y<80;y+=16) 
	{ 
		for(x=0;x<144;x+=16) 
		{ 
			video_draw_spr(Readed, Readed, 0, 0, x, y, 15, 16); 
			Readed++; 
		} 
	} 
 
	blit(video_buffer, game_title, 8, 0, 0, 0, 144, 80); 
	scare_mouse(); 
	blit(video_buffer, screen, 8, 0, 35, 30, 144, 80); 
	unscare_mouse(); 
	 
	memset(neogeo_spr_memory, 0, 4194304); 
	memset(neogeo_fix_memory, 0, 131072); 
	memset(video_spr_usage, 0, 32768); 
	memset(video_fix_usage, 0, 4096); 
} 
 
#define PATCH_Z80(a, b) { \ 
							subcpu_memspace[(a)] = (b)&0xFF; \ 
							subcpu_memspace[(a+1)] = ((b)>>8)&0xFF; \ 
						} 
 
void cdrom_apply_patch(short *source, int offset, int bank) 
{ 
	int master_offset; 
	 
	master_offset = (((bank*1048576) + offset)/256)&0xFFFF; 
	 
	while(*source != 0) 
	{ 
		PATCH_Z80( source[0], ((source[1] + master_offset)>>1) ); 
		PATCH_Z80( source[0] + 2, (((source[2] + master_offset)>>1) - 1) ); 
		 
		if ((source[3])&&(source[4])) 
		{ 
			PATCH_Z80( source[0] + 5, ((source[3] + master_offset)>>1) ); 
			PATCH_Z80( source[0] + 7, (((source[4] + master_offset)>>1) - 1) ); 
		} 
			 
		source += 5; 
	} 
}