mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-24 18:21:50 +01:00
end of restoration
This commit is contained in:
parent
ce72ddbbd0
commit
be12343e35
151
source/unused/fileio.c
Normal file
151
source/unused/fileio.c
Normal file
@ -0,0 +1,151 @@
|
||||
#include "shared.h"
|
||||
|
||||
/*
|
||||
Load a normal file, or ZIP/GZ archive.
|
||||
Returns NULL if an error occured.
|
||||
*/
|
||||
uint8 *load_archive(char *filename, int *file_size)
|
||||
{
|
||||
int size = 0;
|
||||
uint8 *buf = NULL;
|
||||
|
||||
if(check_zip(filename))
|
||||
{
|
||||
unzFile *fd = NULL;
|
||||
unz_file_info info;
|
||||
int ret = 0;
|
||||
|
||||
/* Attempt to open the archive */
|
||||
fd = unzOpen(filename);
|
||||
if(!fd) return (NULL);
|
||||
|
||||
/* Go to first file in archive */
|
||||
ret = unzGoToFirstFile(fd);
|
||||
if(ret != UNZ_OK)
|
||||
{
|
||||
unzClose(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ret = unzGetCurrentFileInfo(fd, &info, NULL, 0, NULL, 0, NULL, 0);
|
||||
if(ret != UNZ_OK)
|
||||
{
|
||||
unzClose(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Open the file for reading */
|
||||
ret = unzOpenCurrentFile(fd);
|
||||
if(ret != UNZ_OK)
|
||||
{
|
||||
unzClose(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Allocate file data buffer */
|
||||
size = info.uncompressed_size;
|
||||
buf = malloc(size);
|
||||
if(!buf)
|
||||
{
|
||||
unzClose(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Read (decompress) the file */
|
||||
ret = unzReadCurrentFile(fd, buf, info.uncompressed_size);
|
||||
if(ret != info.uncompressed_size)
|
||||
{
|
||||
free(buf);
|
||||
unzCloseCurrentFile(fd);
|
||||
unzClose(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Close the current file */
|
||||
ret = unzCloseCurrentFile(fd);
|
||||
if(ret != UNZ_OK)
|
||||
{
|
||||
free(buf);
|
||||
unzClose(fd);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Close the archive */
|
||||
ret = unzClose(fd);
|
||||
if(ret != UNZ_OK)
|
||||
{
|
||||
free(buf);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Update file size and return pointer to file data */
|
||||
*file_size = size;
|
||||
return (buf);
|
||||
}
|
||||
else
|
||||
{
|
||||
gzFile *gd = NULL;
|
||||
|
||||
/* Open file */
|
||||
gd = gzopen(filename, "rb");
|
||||
if(!gd) return (0);
|
||||
|
||||
/* Get file size */
|
||||
size = gzsize(gd);
|
||||
|
||||
/* Allocate file data buffer */
|
||||
buf = malloc(size);
|
||||
if(!buf)
|
||||
{
|
||||
gzclose(gd);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Read file data */
|
||||
gzread(gd, buf, size);
|
||||
|
||||
/* Close file */
|
||||
gzclose(gd);
|
||||
|
||||
/* Update file size and return pointer to file data */
|
||||
*file_size = size;
|
||||
return (buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Verifies if a file is a ZIP archive or not.
|
||||
Returns: 1= ZIP archive, 0= not a ZIP archive
|
||||
*/
|
||||
int check_zip(char *filename)
|
||||
{
|
||||
uint8 buf[2];
|
||||
FILE *fd = NULL;
|
||||
fd = fopen(filename, "rb");
|
||||
if(!fd) return (0);
|
||||
fread(buf, 2, 1, fd);
|
||||
fclose(fd);
|
||||
if(memcmp(buf, "PK", 2) == 0) return (1);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Returns the size of a GZ compressed file.
|
||||
*/
|
||||
int gzsize(gzFile *gd)
|
||||
{
|
||||
#define CHUNKSIZE (0x10000)
|
||||
int size = 0, length = 0;
|
||||
unsigned char buffer[CHUNKSIZE];
|
||||
gzrewind(gd);
|
||||
do {
|
||||
size = gzread(gd, buffer, CHUNKSIZE);
|
||||
if(size <= 0) break;
|
||||
length += size;
|
||||
} while (!gzeof(gd));
|
||||
gzrewind(gd);
|
||||
return (length);
|
||||
#undef CHUNKSIZE
|
||||
}
|
14
source/unused/fileio.h
Normal file
14
source/unused/fileio.h
Normal file
@ -0,0 +1,14 @@
|
||||
#ifndef _FILEIO_H_
|
||||
#define _FILEIO_H_
|
||||
|
||||
/* Global variables */
|
||||
extern int cart_size;
|
||||
extern char cart_name[0x100];
|
||||
|
||||
/* Function prototypes */
|
||||
uint8 *load_archive(char *filename, int *file_size);
|
||||
int load_cart(char *filename);
|
||||
int check_zip(char *filename);
|
||||
int gzsize(gzFile *gd);
|
||||
|
||||
#endif /* _FILEIO_H_ */
|
1
source/unused/make.bat
Normal file
1
source/unused/make.bat
Normal file
@ -0,0 +1 @@
|
||||
@make.exe -f makefile.mgw %1
|
111
source/unused/makefile.dj2
Normal file
111
source/unused/makefile.dj2
Normal file
@ -0,0 +1,111 @@
|
||||
# MekaDrive - Sega Mega Drive emulator
|
||||
# (c) 1999, 2000, 2001, 2002, 2003 Charles MacDonald
|
||||
|
||||
# -DLSB_FIRST - Leave undefined for big-endian processors.
|
||||
# -DDOS - Enable DOS/x86 specific code.
|
||||
# -DDEBUG - Enable debugging code
|
||||
# -DX86_ASM - Enable inline x86 assembly code in Z80 emulator
|
||||
|
||||
CC = gcc
|
||||
AS = nasm -f coff
|
||||
LDFLAGS =
|
||||
FLAGS = -I. -Icpu -Im68k -Idos -Isound -Icart_hw -Icart_hw\svp \
|
||||
-Werror -Wall \
|
||||
-O6 -mcpu=pentium -fomit-frame-pointer \
|
||||
-DLSB_FIRST -DX86_ASM -DDOS
|
||||
|
||||
LIBS = -lalleg -laudio -lz obj/m68k.oa
|
||||
|
||||
OBJ = obj/z80.oa \
|
||||
obj/genesis.o \
|
||||
obj/vdp.o \
|
||||
obj/render.o \
|
||||
obj/system.o \
|
||||
obj/io.o \
|
||||
obj/input.o \
|
||||
obj/mem68k.o \
|
||||
obj/memz80.o \
|
||||
obj/membnk.o \
|
||||
obj/memvdp.o \
|
||||
obj/state.o
|
||||
|
||||
OBJ += obj/sound.o \
|
||||
obj/fm.o \
|
||||
obj/sn76489.o \
|
||||
obj/ym2612.o
|
||||
|
||||
OBJ += obj/sram.o \
|
||||
obj/eeprom.o \
|
||||
obj/svp.o \
|
||||
obj/ssp16.o \
|
||||
obj/cart_hw.o
|
||||
|
||||
OBJ += obj/dos.o \
|
||||
obj/sealintf.o \
|
||||
obj/config.o \
|
||||
obj/error.o \
|
||||
obj/unzip.o \
|
||||
obj/fileio.o \
|
||||
obj/loadrom.o
|
||||
|
||||
EXE = gen.exe
|
||||
|
||||
all : $(EXE)
|
||||
|
||||
$(EXE) : $(OBJ)
|
||||
$(CC) -o $(EXE) $(OBJ) $(LIBS) $(LDFLAGS)
|
||||
|
||||
obj/%.oa : cpu/%.c cpu/%.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : %.c %.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : asm/%.s
|
||||
$(AS) $< -o $@
|
||||
|
||||
obj/%.o : sound/%.c sound/%.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
obj/%.o : sound/%.c
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : cart_hw/%.c cart_hw/%.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : cart_hw/svp/%.c
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : cart_hw/svp/%.c cart_hw/svp/%.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : cpu/%.c cpu/%.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : dos/%.c dos/%.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
pack :
|
||||
strip $(EXE)
|
||||
upx -1 $(EXE)
|
||||
|
||||
clean :
|
||||
rm -f obj/*.o
|
||||
rm -f *.bak
|
||||
rm -f *.exe
|
||||
rm -f *.log
|
||||
rm -f *.wav
|
||||
rm -f *.zip
|
||||
cleancpu :
|
||||
rm -f obj/z80.oa
|
||||
|
||||
makedir :
|
||||
mkdir obj
|
||||
|
||||
archive:
|
||||
pk -dir -add -max \
|
||||
-excl=rom -excl=test \
|
||||
mdsrc.zip *.*
|
||||
|
||||
#
|
||||
# end of makefile
|
||||
#
|
107
source/unused/makefile.mgw
Normal file
107
source/unused/makefile.mgw
Normal file
@ -0,0 +1,107 @@
|
||||
# Genesis Plus - Sega Mega Drive emulator
|
||||
# (c) 1999, 2000, 2001, 2002, 2003 Charles MacDonald
|
||||
|
||||
# -DLSB_FIRST - Leave undefined for big-endian processors.
|
||||
# -DDEBUG - Enable debugging code
|
||||
# -DX86_ASM - Enable inline x86 assembly code in Z80 emulator
|
||||
|
||||
CC = gcc
|
||||
AS = nasm -f coff
|
||||
LDFLAGS =
|
||||
FLAGS = -I. -Icpu -Im68k -Iwin -Isound -Icart_hw -Icart_hw\svp \
|
||||
-Ic:/SDL/include/SDL \
|
||||
-Werror -Wall \
|
||||
-DLSB_FIRST -DX86_ASM \
|
||||
-O6 -march=pentium -fomit-frame-pointer
|
||||
|
||||
LIBS = -lz -lm -lmingw32 -Ld:/sdl/lib -lSDLmain -lSDL obj/m68k.oa
|
||||
|
||||
OBJ = obj/z80.oa \
|
||||
obj/genesis.o \
|
||||
obj/vdp.o \
|
||||
obj/render.o \
|
||||
obj/system.o \
|
||||
obj/io.o \
|
||||
obj/input.o \
|
||||
obj/mem68k.o \
|
||||
obj/memz80.o \
|
||||
obj/membnk.o \
|
||||
obj/memvdp.o \
|
||||
obj/state.o
|
||||
|
||||
OBJ += obj/sound.o \
|
||||
obj/fm.o \
|
||||
obj/sn76489.o \
|
||||
obj/ym2612.o
|
||||
|
||||
OBJ += obj/sram.o \
|
||||
obj/eeprom.o \
|
||||
obj/svp.o \
|
||||
obj/ssp16.o \
|
||||
obj/cart_hw.o
|
||||
|
||||
OBJ += obj/main.o \
|
||||
obj/error.o \
|
||||
obj/fileio.o \
|
||||
obj/unzip.o \
|
||||
obj/loadrom.o
|
||||
|
||||
EXE = gen.exe
|
||||
|
||||
all : $(EXE)
|
||||
|
||||
$(EXE) : $(OBJ) shared.h
|
||||
$(CC) -o $(EXE) $(OBJ) $(LIBS) $(LDFLAGS)
|
||||
|
||||
obj/%.oa : cpu/%.c cpu/%.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : %.c %.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : win/%.s
|
||||
$(AS) $< -o $@
|
||||
|
||||
obj/%.o : sound/%.c sound/%.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : cpu/%.c cpu/%.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : win/%.c win/%.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : cart_hw/%.c cart_hw/%.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : cart_hw/svp/%.c
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
obj/%.o : cart_hw/svp/%.c cart_hw/svp/%.h
|
||||
$(CC) -c $< -o $@ $(FLAGS)
|
||||
|
||||
|
||||
pack :
|
||||
strip $(EXE)
|
||||
upx -1 $(EXE)
|
||||
|
||||
clean :
|
||||
rm -f obj/*.o
|
||||
rm -f *.bak
|
||||
rm -f *.exe
|
||||
rm -f *.log
|
||||
rm -f *.wav
|
||||
rm -f *.zip
|
||||
cleancpu :
|
||||
rm -f obj/z80.oa
|
||||
|
||||
makedir :
|
||||
mkdir obj
|
||||
|
||||
archive:
|
||||
pk -add -max -excl=bak -excl=out \
|
||||
-excl=test -excl=obj mdsrc.zip -dir=current
|
||||
|
||||
#
|
||||
# end of makefile
|
||||
#
|
1301
source/unused/unzip.c
Normal file
1301
source/unused/unzip.c
Normal file
File diff suppressed because it is too large
Load Diff
274
source/unused/unzip.h
Normal file
274
source/unused/unzip.h
Normal file
@ -0,0 +1,274 @@
|
||||
/* unzip.h -- IO for uncompress .zip files using zlib
|
||||
Version 0.15 beta, Mar 19th, 1998,
|
||||
|
||||
Copyright (C) 1998 Gilles Vollant
|
||||
|
||||
This unzip package allow extract file from .ZIP file, compatible with PKZip 2.04g
|
||||
WinZip, InfoZip tools and compatible.
|
||||
Encryption and multi volume ZipFile (span) are not supported.
|
||||
Old compressions used by old PKZip 1.x are not supported
|
||||
|
||||
THIS IS AN ALPHA VERSION. AT THIS STAGE OF DEVELOPPEMENT, SOMES API OR STRUCTURE
|
||||
CAN CHANGE IN FUTURE VERSION !!
|
||||
I WAIT FEEDBACK at mail info@winimage.com
|
||||
Visit also http://www.winimage.com/zLibDll/unzip.htm for evolution
|
||||
|
||||
Condition of use and distribution are the same than zlib :
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
/* for more info about .ZIP format, see
|
||||
ftp://ftp.cdrom.com/pub/infozip/doc/appnote-970311-iz.zip
|
||||
PkWare has also a specification at :
|
||||
ftp://ftp.pkware.com/probdesc.zip */
|
||||
|
||||
#ifndef _unz_H
|
||||
#define _unz_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _ZLIB_H
|
||||
#include "zlib.h"
|
||||
#endif
|
||||
|
||||
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
|
||||
/* like the STRICT of WIN32, we define a pointer that cannot be converted
|
||||
from (void*) without cast */
|
||||
typedef struct TagunzFile__ { int unused; } unzFile__;
|
||||
typedef unzFile__ *unzFile;
|
||||
#else
|
||||
typedef voidp unzFile;
|
||||
#endif
|
||||
|
||||
|
||||
#define UNZ_OK (0)
|
||||
#define UNZ_END_OF_LIST_OF_FILE (-100)
|
||||
#define UNZ_ERRNO (Z_ERRNO)
|
||||
#define UNZ_EOF (0)
|
||||
#define UNZ_PARAMERROR (-102)
|
||||
#define UNZ_BADZIPFILE (-103)
|
||||
#define UNZ_INTERNALERROR (-104)
|
||||
#define UNZ_CRCERROR (-105)
|
||||
|
||||
/* tm_unz contain date/time info */
|
||||
typedef struct tm_unz_s
|
||||
{
|
||||
uInt tm_sec; /* seconds after the minute - [0,59] */
|
||||
uInt tm_min; /* minutes after the hour - [0,59] */
|
||||
uInt tm_hour; /* hours since midnight - [0,23] */
|
||||
uInt tm_mday; /* day of the month - [1,31] */
|
||||
uInt tm_mon; /* months since January - [0,11] */
|
||||
uInt tm_year; /* years - [1980..2044] */
|
||||
} tm_unz;
|
||||
|
||||
/* unz_global_info structure contain global data about the ZIPfile
|
||||
These data comes from the end of central dir */
|
||||
typedef struct unz_global_info_s
|
||||
{
|
||||
uLong number_entry; /* total number of entries in
|
||||
the central dir on this disk */
|
||||
uLong size_comment; /* size of the global comment of the zipfile */
|
||||
} unz_global_info;
|
||||
|
||||
|
||||
/* unz_file_info contain information about a file in the zipfile */
|
||||
typedef struct unz_file_info_s
|
||||
{
|
||||
uLong version; /* version made by 2 bytes */
|
||||
uLong version_needed; /* version needed to extract 2 bytes */
|
||||
uLong flag; /* general purpose bit flag 2 bytes */
|
||||
uLong compression_method; /* compression method 2 bytes */
|
||||
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
|
||||
uLong crc; /* crc-32 4 bytes */
|
||||
uLong compressed_size; /* compressed size 4 bytes */
|
||||
uLong uncompressed_size; /* uncompressed size 4 bytes */
|
||||
uLong size_filename; /* filename length 2 bytes */
|
||||
uLong size_file_extra; /* extra field length 2 bytes */
|
||||
uLong size_file_comment; /* file comment length 2 bytes */
|
||||
|
||||
uLong disk_num_start; /* disk number start 2 bytes */
|
||||
uLong internal_fa; /* internal file attributes 2 bytes */
|
||||
uLong external_fa; /* external file attributes 4 bytes */
|
||||
|
||||
tm_unz tmu_date;
|
||||
} unz_file_info;
|
||||
|
||||
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
|
||||
const char* fileName2,
|
||||
int iCaseSensitivity));
|
||||
/*
|
||||
Compare two filename (fileName1,fileName2).
|
||||
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
|
||||
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
|
||||
or strcasecmp)
|
||||
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
|
||||
(like 1 on Unix, 2 on Windows)
|
||||
*/
|
||||
|
||||
|
||||
extern unzFile ZEXPORT unzOpen OF((const char *path));
|
||||
/*
|
||||
Open a Zip file. path contain the full pathname (by example,
|
||||
on a Windows NT computer "c:\\zlib\\zlib111.zip" or on an Unix computer
|
||||
"zlib/zlib111.zip".
|
||||
If the zipfile cannot be opened (file don't exist or in not valid), the
|
||||
return value is NULL.
|
||||
Else, the return value is a unzFile Handle, usable with other function
|
||||
of this unzip package.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzClose OF((unzFile file));
|
||||
/*
|
||||
Close a ZipFile opened with unzipOpen.
|
||||
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
|
||||
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
|
||||
return UNZ_OK if there is no problem. */
|
||||
|
||||
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
|
||||
unz_global_info *pglobal_info));
|
||||
/*
|
||||
Write info about the ZipFile in the *pglobal_info structure.
|
||||
No preparation of the structure is needed
|
||||
return UNZ_OK if there is no problem. */
|
||||
|
||||
|
||||
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
|
||||
char *szComment,
|
||||
uLong uSizeBuf));
|
||||
/*
|
||||
Get the global comment string of the ZipFile, in the szComment buffer.
|
||||
uSizeBuf is the size of the szComment buffer.
|
||||
return the number of byte copied or an error code <0
|
||||
*/
|
||||
|
||||
|
||||
/***************************************************************************/
|
||||
/* Unzip package allow you browse the directory of the zipfile */
|
||||
|
||||
extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
|
||||
/*
|
||||
Set the current file of the zipfile to the first file.
|
||||
return UNZ_OK if there is no problem
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzGoToNextFile OF((unzFile file));
|
||||
/*
|
||||
Set the current file of the zipfile to the next file.
|
||||
return UNZ_OK if there is no problem
|
||||
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzLocateFile OF((unzFile file,
|
||||
const char *szFileName,
|
||||
int iCaseSensitivity));
|
||||
/*
|
||||
Try locate the file szFileName in the zipfile.
|
||||
For the iCaseSensitivity signification, see unzStringFileNameCompare
|
||||
|
||||
return value :
|
||||
UNZ_OK if the file is found. It becomes the current file.
|
||||
UNZ_END_OF_LIST_OF_FILE if the file is not found
|
||||
*/
|
||||
|
||||
|
||||
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
|
||||
unz_file_info *pfile_info,
|
||||
char *szFileName,
|
||||
uLong fileNameBufferSize,
|
||||
void *extraField,
|
||||
uLong extraFieldBufferSize,
|
||||
char *szComment,
|
||||
uLong commentBufferSize));
|
||||
/*
|
||||
Get Info about the current file
|
||||
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
|
||||
the current file
|
||||
if szFileName!=NULL, the filemane string will be copied in szFileName
|
||||
(fileNameBufferSize is the size of the buffer)
|
||||
if extraField!=NULL, the extra field information will be copied in extraField
|
||||
(extraFieldBufferSize is the size of the buffer).
|
||||
This is the Central-header version of the extra field
|
||||
if szComment!=NULL, the comment string of the file will be copied in szComment
|
||||
(commentBufferSize is the size of the buffer)
|
||||
*/
|
||||
|
||||
/***************************************************************************/
|
||||
/* for reading the content of the current zipfile, you can open it, read data
|
||||
from it, and close it (you can close it before reading all the file)
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
|
||||
/*
|
||||
Open for reading data the current file in the zipfile.
|
||||
If there is no error, the return value is UNZ_OK.
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
|
||||
/*
|
||||
Close the file in zip opened with unzOpenCurrentFile
|
||||
Return UNZ_CRCERROR if all the file was read but the CRC is not good
|
||||
*/
|
||||
|
||||
|
||||
extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
|
||||
voidp buf,
|
||||
unsigned len));
|
||||
/*
|
||||
Read bytes from the current file (opened by unzOpenCurrentFile)
|
||||
buf contain buffer where data must be copied
|
||||
len the size of buf.
|
||||
|
||||
return the number of byte copied if somes bytes are copied
|
||||
return 0 if the end of file was reached
|
||||
return <0 with error code if there is an error
|
||||
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
|
||||
*/
|
||||
|
||||
extern z_off_t ZEXPORT unztell OF((unzFile file));
|
||||
/*
|
||||
Give the current position in uncompressed data
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzeof OF((unzFile file));
|
||||
/*
|
||||
return 1 if the end of file was reached, 0 elsewhere
|
||||
*/
|
||||
|
||||
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
|
||||
voidp buf,
|
||||
unsigned len));
|
||||
/*
|
||||
Read extra field from the current file (opened by unzOpenCurrentFile)
|
||||
This is the local-header version of the extra field (sometimes, there is
|
||||
more info in the local-header version than in the central-header)
|
||||
|
||||
if buf==NULL, it return the size of the local extra field
|
||||
|
||||
if buf!=NULL, len is the size of the buffer, the extra header is copied in
|
||||
buf.
|
||||
the return value is the number of bytes copied in buf, or (if <0)
|
||||
the error code
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _unz_H */
|
39
source/unused/win/error.c
Normal file
39
source/unused/win/error.c
Normal file
@ -0,0 +1,39 @@
|
||||
/*
|
||||
error.c --
|
||||
Error logging
|
||||
*/
|
||||
|
||||
#include "shared.h"
|
||||
|
||||
FILE *error_log;
|
||||
|
||||
struct {
|
||||
int enabled;
|
||||
int verbose;
|
||||
FILE *log;
|
||||
} t_error;
|
||||
|
||||
void error_init(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
error_log = fopen("error.log","w");
|
||||
#endif
|
||||
}
|
||||
|
||||
void error_shutdown(void)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if(error_log) fclose(error_log);
|
||||
#endif
|
||||
}
|
||||
|
||||
void error(char *format, ...)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
if(error_log) vfprintf(error_log, format, ap);
|
||||
va_end(ap);
|
||||
#endif
|
||||
}
|
||||
|
13
source/unused/win/error.h
Normal file
13
source/unused/win/error.h
Normal file
@ -0,0 +1,13 @@
|
||||
|
||||
#ifndef _ERROR_H_
|
||||
#define _ERROR_H_
|
||||
|
||||
/* Global variables */
|
||||
FILE *error_log;
|
||||
|
||||
/* Function prototypes */
|
||||
void error_init(void);
|
||||
void error_shutdown(void);
|
||||
void error(char *format, ...);
|
||||
|
||||
#endif /* _ERROR_H_ */
|
221
source/unused/win/main.c
Normal file
221
source/unused/win/main.c
Normal file
@ -0,0 +1,221 @@
|
||||
|
||||
#include <windows.h>
|
||||
#include <SDL.h>
|
||||
#include "shared.h"
|
||||
|
||||
int timer_count = 0;
|
||||
int old_timer_count = 0;
|
||||
int paused = 0;
|
||||
int frame_count = 0;
|
||||
|
||||
int update_input(void);
|
||||
unsigned char *keystate;
|
||||
|
||||
/* Options default */
|
||||
uint8 overscan = 1;
|
||||
uint8 use_480i = 1;
|
||||
uint8 FM_GENS = 1;
|
||||
uint8 hq_fm = 1;
|
||||
uint8 ssg_enabled = 0;
|
||||
double psg_preamp = 0.5;
|
||||
double fm_preamp = 1.0;
|
||||
uint8 boost = 1;
|
||||
uint8 region_detect = 0;
|
||||
uint8 sys_type[2] = {0,0};
|
||||
uint8 force_dtack = 0;
|
||||
uint8 dmatiming = 1;
|
||||
uint8 vdptiming = 1;
|
||||
|
||||
uint8 log_error = 1;
|
||||
uint8 debug_on = 0;
|
||||
|
||||
|
||||
Uint32 fps_callback(Uint32 interval)
|
||||
{
|
||||
if(paused) return 1000/60;
|
||||
timer_count++;
|
||||
if(timer_count % 60 == 0)
|
||||
{
|
||||
int fps = frame_count;
|
||||
char caption[32];
|
||||
sprintf(caption, "Genesis Plus/SDL FPS=%d", fps);
|
||||
SDL_WM_SetCaption(caption, NULL);
|
||||
frame_count = 0;
|
||||
}
|
||||
return 1000/60;
|
||||
}
|
||||
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int running = 1;
|
||||
|
||||
SDL_Rect viewport, src;
|
||||
SDL_Surface *bmp, *screen;
|
||||
SDL_Event event;
|
||||
|
||||
error_init();
|
||||
|
||||
/* Print help if no game specified */
|
||||
if(argc < 2)
|
||||
{
|
||||
char caption[256];
|
||||
sprintf(caption, "Genesis Plus\nby Charles MacDonald\nWWW: http://cgfm2.emuviews.com\nusage: %s gamename\n", argv[0]);
|
||||
MessageBox(NULL, caption, "Information", 0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Load game */
|
||||
if(!load_rom(argv[1]))
|
||||
{
|
||||
char caption[256];
|
||||
sprintf(caption, "Error loading file `%s'.", argv[1]);
|
||||
MessageBox(NULL, caption, "Error", 0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
viewport.x = 0;
|
||||
viewport.y = 0;
|
||||
viewport.w = 256;
|
||||
viewport.h = 224;
|
||||
|
||||
src.x = 32;
|
||||
src.y = 0;
|
||||
src.w = viewport.w;
|
||||
src.h = viewport.h;
|
||||
|
||||
if(SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0)
|
||||
{
|
||||
exit(1);
|
||||
}
|
||||
SDL_WM_SetCaption("Genesis Plus/SDL", NULL);
|
||||
|
||||
screen = SDL_SetVideoMode(viewport.w, viewport.h, 16, SDL_SWSURFACE);
|
||||
viewport.x = 0;
|
||||
viewport.y = 0;
|
||||
|
||||
bmp = SDL_CreateRGBSurface(SDL_SWSURFACE, 1024, 512, 16, 0xF800, 0x07E0, 0x001F, 0x0000);
|
||||
|
||||
|
||||
|
||||
memset(&bitmap, 0, sizeof(t_bitmap));
|
||||
bitmap.width = 1024;
|
||||
bitmap.height = 512;
|
||||
bitmap.depth = 16;
|
||||
bitmap.granularity = 2;
|
||||
bitmap.pitch = (bitmap.width * bitmap.granularity);
|
||||
bitmap.data = (unsigned char *)bmp->pixels;
|
||||
bitmap.viewport.w = 256;
|
||||
bitmap.viewport.h = 224;
|
||||
bitmap.viewport.x = 0x20;
|
||||
bitmap.viewport.y = 0x00;
|
||||
bitmap.remap = 1;
|
||||
|
||||
system_init();
|
||||
system_reset();
|
||||
|
||||
SDL_SetTimer(1000/60, fps_callback);
|
||||
|
||||
while(running)
|
||||
{
|
||||
running = update_input();
|
||||
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case SDL_QUIT: /* Windows was closed */
|
||||
running = 0;
|
||||
break;
|
||||
|
||||
case SDL_ACTIVEEVENT: /* Window focus changed or was minimized */
|
||||
if(event.active.state & (SDL_APPINPUTFOCUS | SDL_APPACTIVE))
|
||||
{
|
||||
paused = !event.active.gain;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!paused)
|
||||
{
|
||||
frame_count++;
|
||||
|
||||
update_input();
|
||||
|
||||
if(!system_frame(0))
|
||||
system_reset();
|
||||
|
||||
if(bitmap.viewport.changed)
|
||||
{
|
||||
bitmap.viewport.changed = 0;
|
||||
src.w = bitmap.viewport.w;
|
||||
src.h = bitmap.viewport.h;
|
||||
viewport.w = bitmap.viewport.w;
|
||||
viewport.h = bitmap.viewport.h;
|
||||
screen = SDL_SetVideoMode(bitmap.viewport.w, bitmap.viewport.h, 16, SDL_SWSURFACE);
|
||||
}
|
||||
|
||||
SDL_BlitSurface(bmp, &src, screen, &viewport);
|
||||
SDL_UpdateRect(screen, viewport.x, viewport.y, viewport.w, viewport.h);
|
||||
}
|
||||
}
|
||||
|
||||
system_shutdown();
|
||||
SDL_Quit();
|
||||
error_shutdown();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Check if a key is pressed */
|
||||
int check_key(int code)
|
||||
{
|
||||
static char lastbuf[0x100] = {0};
|
||||
|
||||
if((!keystate[code]) && (lastbuf[code] == 1))
|
||||
lastbuf[code] = 0;
|
||||
|
||||
if((keystate[code]) && (lastbuf[code] == 0))
|
||||
{
|
||||
lastbuf[code] = 1;
|
||||
return (1);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
int update_input(void)
|
||||
{
|
||||
int running = 1;
|
||||
|
||||
keystate = SDL_GetKeyState(NULL);
|
||||
|
||||
memset(&input, 0, sizeof(t_input));
|
||||
if(keystate[SDLK_UP]) input.pad[0] |= INPUT_UP;
|
||||
else
|
||||
if(keystate[SDLK_DOWN]) input.pad[0] |= INPUT_DOWN;
|
||||
if(keystate[SDLK_LEFT]) input.pad[0] |= INPUT_LEFT;
|
||||
else
|
||||
if(keystate[SDLK_RIGHT]) input.pad[0] |= INPUT_RIGHT;
|
||||
|
||||
if(keystate[SDLK_a]) input.pad[0] |= INPUT_A;
|
||||
if(keystate[SDLK_s]) input.pad[0] |= INPUT_B;
|
||||
if(keystate[SDLK_d]) input.pad[0] |= INPUT_C;
|
||||
if(keystate[SDLK_f]) input.pad[0] |= INPUT_START;
|
||||
if(keystate[SDLK_z]) input.pad[0] |= INPUT_X;
|
||||
if(keystate[SDLK_x]) input.pad[0] |= INPUT_Y;
|
||||
if(keystate[SDLK_c]) input.pad[0] |= INPUT_Z;
|
||||
if(keystate[SDLK_v]) input.pad[0] |= INPUT_MODE;
|
||||
|
||||
if(keystate[SDLK_TAB]) system_reset();
|
||||
|
||||
if(keystate[SDLK_ESCAPE]) running = 0;
|
||||
return (running);
|
||||
}
|
||||
|
||||
|
24
source/unused/win/main.h
Normal file
24
source/unused/win/main.h
Normal file
@ -0,0 +1,24 @@
|
||||
|
||||
#ifndef _MAIN_H_
|
||||
#define _MAIN_H_
|
||||
|
||||
/* options */
|
||||
extern uint8 overscan;
|
||||
extern uint8 use_480i;
|
||||
extern uint8 FM_GENS;
|
||||
extern uint8 hq_fm;
|
||||
extern uint8 ssg_enabled;
|
||||
extern double psg_preamp;
|
||||
extern double fm_preamp;
|
||||
extern uint8 boost;
|
||||
extern uint8 region_detect;
|
||||
extern uint8 sys_type[2];
|
||||
extern uint8 force_dtack;
|
||||
extern uint8 dmatiming;
|
||||
extern uint8 vdptiming;
|
||||
|
||||
extern uint8 debug_on;
|
||||
extern uint8 log_error;
|
||||
|
||||
|
||||
#endif /* _MAIN_H_ */
|
20
source/unused/win/osd.h
Normal file
20
source/unused/win/osd.h
Normal file
@ -0,0 +1,20 @@
|
||||
|
||||
#ifndef _OSD_H_
|
||||
#define _OSD_H_
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
#include <time.h>
|
||||
#include <conio.h>
|
||||
|
||||
#include "SDL.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "error.h"
|
||||
#include "shared.h"
|
||||
#include "main.h"
|
||||
#include "unzip.h"
|
||||
#include "fileio.h"
|
||||
|
||||
#endif /* _OSD_H_ */
|
880
source/vdp.c
Normal file
880
source/vdp.c
Normal file
@ -0,0 +1,880 @@
|
||||
/***************************************************************************************
|
||||
* Genesis Plus 1.2a
|
||||
* Video Display Processor (memory handlers)
|
||||
*
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
|
||||
* modified by Eke-Eke (compatibility fixes & additional code), GC/Wii port
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#include "shared.h"
|
||||
#include "hvc.h"
|
||||
|
||||
/* Pack and unpack CRAM data */
|
||||
#define PACK_CRAM(d) ((((d)&0xE00)>>9)|(((d)&0x0E0)>>2)|(((d)&0x00E)<<5))
|
||||
#define UNPACK_CRAM(d) ((((d)&0x1C0)>>5)|((d)&0x038)<<2|(((d)&0x007)<<9))
|
||||
|
||||
/* Mark a pattern as dirty */
|
||||
#define MARK_BG_DIRTY(addr) \
|
||||
{ \
|
||||
int name = (addr >> 5) & 0x7FF; \
|
||||
if(bg_name_dirty[name] == 0) bg_name_list[bg_list_index++] = name; \
|
||||
bg_name_dirty[name] |= (1 << ((addr >> 2) & 0x07)); \
|
||||
}
|
||||
|
||||
/* VDP context */
|
||||
uint8 sat[0x400]; /* Internal copy of sprite attribute table */
|
||||
uint8 vram[0x10000]; /* Video RAM (64Kx8) */
|
||||
uint8 cram[0x80]; /* On-chip color RAM (64x9) */
|
||||
uint8 vsram[0x80]; /* On-chip vertical scroll RAM (40x11) */
|
||||
uint8 reg[0x20]; /* Internal VDP registers (23x8) */
|
||||
uint16 addr; /* Address register */
|
||||
uint16 addr_latch; /* Latched A15, A14 of address */
|
||||
uint8 code; /* Code register */
|
||||
uint8 pending; /* Pending write flag */
|
||||
uint16 status; /* VDP status flags */
|
||||
uint8 dmafill; /* next VDP Write is DMA Fill */
|
||||
uint8 hint_pending; /* 0= Line interrupt is pending */
|
||||
uint8 vint_pending; /* 1= Frame interrupt is pending */
|
||||
uint8 vint_triggered; /* 1= Frame interrupt has been triggered */
|
||||
int8 hvint_updated; /* >= 0: Interrupt lines updated */
|
||||
|
||||
/* Global variables */
|
||||
uint16 ntab; /* Name table A base address */
|
||||
uint16 ntbb; /* Name table B base address */
|
||||
uint16 ntwb; /* Name table W base address */
|
||||
uint16 satb; /* Sprite attribute table base address */
|
||||
uint16 hscb; /* Horizontal scroll table base address */
|
||||
uint8 border; /* Border color index */
|
||||
uint8 bg_name_dirty[0x800]; /* 1= This pattern is dirty */
|
||||
uint16 bg_name_list[0x800]; /* List of modified pattern indices */
|
||||
uint16 bg_list_index; /* # of modified patterns in list */
|
||||
uint8 bg_pattern_cache[0x80000]; /* Cached and flipped patterns */
|
||||
uint8 playfield_shift; /* Width of planes A, B (in bits) */
|
||||
uint8 playfield_col_mask; /* Vertical scroll mask */
|
||||
uint16 playfield_row_mask; /* Horizontal scroll mask */
|
||||
uint32 y_mask; /* Name table Y-index bits mask */
|
||||
int16 h_counter; /* Raster counter */
|
||||
int16 hc_latch; /* latched HCounter (INT2) */
|
||||
uint16 v_counter; /* VDP scanline counter */
|
||||
uint8 im2_flag; /* 1= Interlace mode 2 is being used */
|
||||
uint32 dma_length; /* Current DMA remaining bytes */
|
||||
int32 fifo_write_cnt; /* VDP writes fifo count */
|
||||
uint32 fifo_lastwrite; /* last VDP write cycle */
|
||||
uint8 fifo_latency; /* VDP write cycles latency */
|
||||
uint8 vdp_pal = 0; /* 1: PAL , 0: NTSC (default) */
|
||||
|
||||
double vdp_timings[4][4];
|
||||
|
||||
/* Tables that define the playfield layout */
|
||||
static const uint8 shift_table[] = { 6, 7, 0, 8 };
|
||||
static const uint8 col_mask_table[] = { 0x0F, 0x1F, 0x0F, 0x3F };
|
||||
static const uint16 row_mask_table[] = { 0x0FF, 0x1FF, 0x2FF, 0x3FF };
|
||||
static const uint32 y_mask_table[] = { 0x1FC0, 0x1F80, 0x1FC0, 0x1F00 };
|
||||
|
||||
static uint16 sat_base_mask; /* Base bits of SAT */
|
||||
static uint16 sat_addr_mask; /* Index bits of SAT */
|
||||
static uint32 dma_endCycles; /* 68k cycles to DMA end */
|
||||
static uint8 dma_type; /* Type of DMA */
|
||||
|
||||
/* TODO: set as default */
|
||||
static uint8 dmatiming = 1;
|
||||
static uint8 vdptiming = 1;
|
||||
|
||||
/* DMA Timings
|
||||
|
||||
According to the manual, here's a table that describes the transfer
|
||||
rates of each of the three DMA types:
|
||||
|
||||
DMA Mode Width Display Transfer Count
|
||||
-----------------------------------------------------
|
||||
68K > VDP 32-cell Active 16
|
||||
Blanking 167
|
||||
40-cell Active 18
|
||||
Blanking 205
|
||||
VRAM Fill 32-cell Active 15
|
||||
Blanking 166
|
||||
40-cell Active 17
|
||||
Blanking 204
|
||||
VRAM Copy 32-cell Active 8
|
||||
Blanking 83
|
||||
40-cell Active 9
|
||||
Blanking 102
|
||||
|
||||
'Active' is the active display period, 'Blanking' is either the vertical
|
||||
blanking period or when the display is forcibly blanked via register #1.
|
||||
|
||||
The above transfer counts are all in bytes, unless the destination is
|
||||
CRAM or VSRAM for a 68K > VDP transfer, in which case it is in words.
|
||||
|
||||
*/
|
||||
static const uint8 dma_rates[16] = {
|
||||
8, 9, 83 , 102, /* 68K to VRAM */
|
||||
16, 18, 167, 205, /* 68K to CRAM or VSRAM */
|
||||
15, 17, 166, 204, /* DMA fill */
|
||||
8, 9, 83 , 102, /* DMA Copy */
|
||||
};
|
||||
|
||||
/* Function prototypes */
|
||||
static inline void data_write(unsigned int data);
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Init, reset, shutdown functions */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void vdp_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* reinitialize DMA timings table */
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
vdp_timings[0][i] = ((double)m68cycles_per_line) / ((double) dma_rates[i]);
|
||||
vdp_timings[1][i] = ((double)m68cycles_per_line) / ((double) dma_rates[i + 4]);
|
||||
vdp_timings[2][i] = ((double)m68cycles_per_line) / ((double) dma_rates[i + 8]);
|
||||
vdp_timings[3][i] = ((double)m68cycles_per_line) / ((double) dma_rates[i + 12]);
|
||||
}
|
||||
}
|
||||
|
||||
void vdp_reset(void)
|
||||
{
|
||||
memset ((char *) sat, 0, sizeof (sat));
|
||||
memset ((char *) vram, 0, sizeof (vram));
|
||||
memset ((char *) cram, 0, sizeof (cram));
|
||||
memset ((char *) vsram, 0, sizeof (vsram));
|
||||
memset ((char *) reg, 0, sizeof (reg));
|
||||
|
||||
addr = 0;
|
||||
addr_latch = 0;
|
||||
code = 0;
|
||||
pending = 0;
|
||||
|
||||
status = 0x200; /* fifo empty */
|
||||
|
||||
ntab = 0;
|
||||
ntbb = 0;
|
||||
ntwb = 0;
|
||||
satb = 0;
|
||||
hscb = 0;
|
||||
|
||||
sat_base_mask = 0xFE00;
|
||||
sat_addr_mask = 0x01FF;
|
||||
|
||||
border = 0x00;
|
||||
|
||||
memset ((char *) bg_name_dirty, 0, sizeof (bg_name_dirty));
|
||||
memset ((char *) bg_name_list, 0, sizeof (bg_name_list));
|
||||
bg_list_index = 0;
|
||||
memset ((char *) bg_pattern_cache, 0, sizeof (bg_pattern_cache));
|
||||
|
||||
playfield_shift = 6;
|
||||
playfield_col_mask = 0x0F;
|
||||
playfield_row_mask = 0x0FF;
|
||||
y_mask = 0x1FC0;
|
||||
|
||||
hint_pending = 0;
|
||||
vint_pending = 0;
|
||||
vint_triggered = 0;
|
||||
hvint_updated = -1;
|
||||
|
||||
h_counter = 0;
|
||||
hc_latch = -1;
|
||||
v_counter = 0;
|
||||
|
||||
dmafill = 0;
|
||||
dma_length = 0;
|
||||
dma_endCycles = 0;
|
||||
|
||||
im2_flag = 0;
|
||||
interlaced = 0;
|
||||
|
||||
fifo_write_cnt = 0;
|
||||
|
||||
/* reset HVC tables */
|
||||
vctab = (vdp_pal) ? vc_pal_224 : vc_ntsc_224;
|
||||
hctab = cycle2hc32;
|
||||
|
||||
/* reset display area */
|
||||
bitmap.viewport.w = 256;
|
||||
bitmap.viewport.h = 224;
|
||||
bitmap.viewport.oh = 256;
|
||||
bitmap.viewport.ow = 224;
|
||||
|
||||
/* reset border area */
|
||||
bitmap.viewport.x = config.overscan ? 12 : 0;
|
||||
bitmap.viewport.y = config.overscan ? (vdp_pal ? 32 : 8) : 0;
|
||||
bitmap.viewport.changed = 1;
|
||||
|
||||
/* initialize some registers (normally set by BIOS) */
|
||||
if (config.bios_enabled != 3)
|
||||
{
|
||||
vdp_reg_w(1 , 0x04); /* Mode 5 enabled */
|
||||
vdp_reg_w(10, 0xff); /* HINT disabled */
|
||||
vdp_reg_w(12, 0x81); /* H40 mode */
|
||||
vdp_reg_w(15, 0x02); /* auto increment */
|
||||
}
|
||||
|
||||
/* default latency */
|
||||
fifo_latency = 27;
|
||||
}
|
||||
|
||||
void vdp_shutdown(void)
|
||||
{}
|
||||
|
||||
void vdp_restore(uint8 *vdp_regs)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0;i<0x20;i++)
|
||||
{
|
||||
vdp_reg_w(i, vdp_regs[i]);
|
||||
}
|
||||
|
||||
/* reinitialize HVC tables */
|
||||
vctab = (vdp_pal) ? ((reg[1] & 8) ? vc_pal_240 : vc_pal_224) : vc_ntsc_224;
|
||||
hctab = (reg[12] & 1) ? cycle2hc40 : cycle2hc32;
|
||||
|
||||
/* reinitialize overscan area */
|
||||
bitmap.viewport.x = config.overscan ? ((reg[12] & 1) ? 16 : 12) : 0;
|
||||
bitmap.viewport.y = config.overscan ? (((reg[1] & 8) ? 0 : 8) + (vdp_pal ? 24 : 0)) : 0;
|
||||
bitmap.viewport.changed = 1;
|
||||
|
||||
/* restore VDP FIFO timings */
|
||||
if (vdptiming)
|
||||
{
|
||||
/* VDP timings:
|
||||
------------
|
||||
HDISP is 256*10/7 = approx. 366 cycles (same for both modes)
|
||||
this gives:
|
||||
H32: 16 accesses --> 366/16 = 23 cycles per access
|
||||
H40: 20 accesses --> 366/20 = 18 cycles per access
|
||||
|
||||
VRAM access are byte wide --> VRAM writes takes 2x CPU cycles
|
||||
*/
|
||||
fifo_latency = (reg[12] & 1) ? 27 : 30;
|
||||
if ((code & 0x0F) == 0x01) fifo_latency = fifo_latency * 2;
|
||||
}
|
||||
|
||||
/* remake cache */
|
||||
for (i=0;i<0x800;i++)
|
||||
{
|
||||
bg_name_list[i]=i;
|
||||
bg_name_dirty[i]=0xFF;
|
||||
}
|
||||
bg_list_index=0x800;
|
||||
|
||||
/* reinitialize palette */
|
||||
for(i = 0; i < 0x40; i += 1) color_update(i, *(uint16 *)&cram[i << 1]);
|
||||
color_update(0x00, *(uint16 *)&cram[border << 1]);
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* DMA Operations */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/* Update DMA timings (this is call on start of DMA and then at the start of each scanline) */
|
||||
void dma_update()
|
||||
{
|
||||
int32 left_cycles;
|
||||
uint32 dma_cycles, dma_bytes;
|
||||
uint8 index = 0;
|
||||
|
||||
if (!dmatiming) return;
|
||||
|
||||
/* get the appropriate tranfer rate (bytes/line) for this DMA operation */
|
||||
if ((status&8) || !(reg[1] & 0x40)) index = 2; /* VBLANK or Display OFF */
|
||||
index += (reg[12] & 1); /* 32 or 40 Horizontal Cells */
|
||||
|
||||
/* calculate transfer quantity for the remaining 68k cycles */
|
||||
left_cycles = aim_m68k - count_m68k;
|
||||
if (left_cycles < 0) left_cycles = 0;
|
||||
dma_bytes = (uint32)(((double)left_cycles / vdp_timings[dma_type][index]) + 0.5);
|
||||
|
||||
/* determinate DMA length in CPU cycles */
|
||||
if (dma_length < dma_bytes)
|
||||
{
|
||||
/* DMA will be finished during this line */
|
||||
dma_cycles = (uint32)(((double)dma_length * vdp_timings[dma_type][index]) + 0.5);
|
||||
dma_length = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* DMA can not be finished until next scanline */
|
||||
dma_cycles = left_cycles;
|
||||
dma_length -= dma_bytes;
|
||||
}
|
||||
|
||||
if (dma_type < 2)
|
||||
{
|
||||
/* 68K COPY to V-RAM */
|
||||
/* 68K is frozen during DMA operation */
|
||||
count_m68k += dma_cycles;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* VRAM Fill or VRAM Copy */
|
||||
/* set DMA end cyles count */
|
||||
dma_endCycles = count_m68k + dma_cycles;
|
||||
|
||||
/* set DMA Busy flag */
|
||||
status |= 0x0002;
|
||||
}
|
||||
}
|
||||
|
||||
/* DMA Copy
|
||||
Read byte from VRAM (source), write to VRAM (addr),
|
||||
bump source and add r15 to addr.
|
||||
|
||||
- see how source addr is affected
|
||||
(can it make high source byte inc?)
|
||||
*/
|
||||
static inline void dma_copy(void)
|
||||
{
|
||||
int length = (reg[20] << 8 | reg[19]) & 0xFFFF;
|
||||
int source = (reg[22] << 8 | reg[21]) & 0xFFFF;
|
||||
if (!length) length = 0x10000;
|
||||
|
||||
dma_type = 3;
|
||||
dma_length = length;
|
||||
dma_update();
|
||||
|
||||
/* proceed DMA */
|
||||
do
|
||||
{
|
||||
vram[addr] = vram[source];
|
||||
MARK_BG_DIRTY(addr);
|
||||
source = (source + 1) & 0xFFFF;
|
||||
addr += reg[15];
|
||||
} while (--length);
|
||||
|
||||
/* update length & source address registers */
|
||||
reg[19] = length & 0xFF;
|
||||
reg[20] = (length >> 8) & 0xFF;
|
||||
reg[21] = source & 0xFF; /* not sure */
|
||||
reg[22] = (source >> 8) & 0xFF;
|
||||
}
|
||||
|
||||
|
||||
/* 68K Copy to VRAM, VSRAM or CRAM */
|
||||
static inline void dma_vbus (void)
|
||||
{
|
||||
uint32 base, source = ((reg[23] & 0x7F) << 17 | reg[22] << 9 | reg[21] << 1) & 0xFFFFFE;
|
||||
uint32 length = (reg[20] << 8 | reg[19]) & 0xFFFF;
|
||||
|
||||
if (!length) length = 0x10000;
|
||||
base = source;
|
||||
|
||||
/* DMA timings */
|
||||
dma_type = (code & 0x06) ? 1 : 0;
|
||||
dma_length = length;
|
||||
dma_update();
|
||||
|
||||
/* proceed DMA */
|
||||
do
|
||||
{
|
||||
unsigned int temp = vdp_dma_r(source);
|
||||
source += 2;
|
||||
source = ((base & 0xFE0000) | (source & 0x1FFFF));
|
||||
data_write (temp);
|
||||
}
|
||||
while (--length);
|
||||
|
||||
/* update length & source address registers */
|
||||
reg[19] = length & 0xFF;
|
||||
reg[20] = (length >> 8) & 0xFF;
|
||||
reg[21] = (source >> 1) & 0xFF;
|
||||
reg[22] = (source >> 9) & 0xFF;
|
||||
reg[23] = (reg[23] & 0x80) | ((source >> 17) & 0x7F);
|
||||
}
|
||||
|
||||
/* VRAM FILL */
|
||||
static inline void dma_fill(unsigned int data)
|
||||
{
|
||||
int length = (reg[20] << 8 | reg[19]) & 0xFFFF;
|
||||
if (!length) length = 0x10000;
|
||||
|
||||
/* DMA timings */
|
||||
dma_type = 2;
|
||||
dma_length = length;
|
||||
dma_update();
|
||||
|
||||
/* proceed DMA */
|
||||
data_write(data);
|
||||
|
||||
/* write MSB */
|
||||
data = (data >> 8) & 0xff;
|
||||
|
||||
/* detect internal SAT modification */
|
||||
if ((addr & sat_base_mask) == satb)
|
||||
{
|
||||
do
|
||||
{
|
||||
/* update internal SAT (fix Battletech) */
|
||||
WRITE_BYTE(sat, (addr & sat_addr_mask)^1, data);
|
||||
|
||||
WRITE_BYTE(vram, addr^1, data);
|
||||
MARK_BG_DIRTY (addr);
|
||||
addr += reg[15];
|
||||
}
|
||||
while (--length);
|
||||
}
|
||||
else
|
||||
{
|
||||
do
|
||||
{
|
||||
WRITE_BYTE(vram, addr^1, data);
|
||||
MARK_BG_DIRTY (addr);
|
||||
addr += reg[15];
|
||||
}
|
||||
while (--length);
|
||||
}
|
||||
|
||||
/* update length register */
|
||||
reg[19] = length & 0xFF;
|
||||
reg[20] = (length >> 8) & 0xFF;
|
||||
dmafill = 0;
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* FIFO emulation */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static inline void fifo_update()
|
||||
{
|
||||
if (fifo_write_cnt > 0)
|
||||
{
|
||||
/* update FIFO reads */
|
||||
uint32 fifo_read = ((count_m68k - fifo_lastwrite) / fifo_latency);
|
||||
if (fifo_read > 0)
|
||||
{
|
||||
fifo_write_cnt -= fifo_read;
|
||||
if (fifo_write_cnt < 0) fifo_write_cnt = 0;
|
||||
|
||||
/* update cycle count */
|
||||
fifo_lastwrite += fifo_read*fifo_latency;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
/* Memory access functions */
|
||||
/*--------------------------------------------------------------------------*/
|
||||
static inline void data_write (unsigned int data)
|
||||
{
|
||||
switch (code & 0x0F)
|
||||
{
|
||||
case 0x01: /* VRAM */
|
||||
|
||||
/* Byte-swap data if A0 is set */
|
||||
if (addr & 1) data = (data >> 8) | (data << 8);
|
||||
|
||||
/* Copy SAT data to the internal SAT */
|
||||
if ((addr & sat_base_mask) == satb)
|
||||
{
|
||||
*(uint16 *) &sat[addr & sat_addr_mask & 0xFFFE] = data;
|
||||
}
|
||||
|
||||
/* Only write unique data to VRAM */
|
||||
if (data != *(uint16 *) &vram[addr & 0xFFFE])
|
||||
{
|
||||
/* Write data to VRAM */
|
||||
*(uint16 *) &vram[addr & 0xFFFE] = data;
|
||||
|
||||
/* Update the pattern cache */
|
||||
MARK_BG_DIRTY (addr);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03: /* CRAM */
|
||||
{
|
||||
uint16 *p = (uint16 *) &cram[(addr & 0x7E)];
|
||||
data = PACK_CRAM (data & 0x0EEE);
|
||||
if (data != *p)
|
||||
{
|
||||
int index = (addr >> 1) & 0x3F;
|
||||
*p = data;
|
||||
color_update (index, *p);
|
||||
color_update (0x00, *(uint16 *)&cram[border << 1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x05: /* VSRAM */
|
||||
*(uint16 *) &vsram[(addr & 0x7E)] = data;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Increment address register */
|
||||
addr += reg[15];
|
||||
}
|
||||
|
||||
|
||||
void vdp_ctrl_w(unsigned int data)
|
||||
{
|
||||
if (pending == 0)
|
||||
{
|
||||
if ((data & 0xC000) == 0x8000)
|
||||
{
|
||||
/* VDP register write */
|
||||
uint8 r = (data >> 8) & 0x1F;
|
||||
uint8 d = data & 0xFF;
|
||||
vdp_reg_w (r, d);
|
||||
}
|
||||
else pending = 1;
|
||||
|
||||
addr = ((addr_latch & 0xC000) | (data & 0x3FFF)) & 0xFFFF;
|
||||
code = ((code & 0x3C) | ((data >> 14) & 0x03)) & 0x3F;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Clear pending flag */
|
||||
pending = 0;
|
||||
|
||||
/* Update address and code registers */
|
||||
addr = ((addr & 0x3FFF) | ((data & 3) << 14)) & 0xFFFF;
|
||||
code = ((code & 0x03) | ((data >> 2) & 0x3C)) & 0x3F;
|
||||
|
||||
/* Save address bits A15 and A14 */
|
||||
addr_latch = (addr & 0xC000);
|
||||
|
||||
/* DMA operation */
|
||||
if ((code & 0x20) && (reg[1] & 0x10))
|
||||
{
|
||||
switch (reg[23] & 0xC0)
|
||||
{
|
||||
case 0x00: /* V bus to VDP DMA */
|
||||
case 0x40: /* V bus to VDP DMA */
|
||||
dma_vbus();
|
||||
break;
|
||||
|
||||
case 0x80: /* VRAM fill */
|
||||
dmafill = 1;
|
||||
break;
|
||||
|
||||
case 0xC0: /* VRAM copy */
|
||||
dma_copy();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* FIFO emulation */
|
||||
if (vdptiming)
|
||||
{
|
||||
/* VDP timings:
|
||||
------------
|
||||
HDISP is 256*10/7 = approx. 366 cycles (same for both modes)
|
||||
this gives:
|
||||
H32: 16 accesses --> 366/16 = 23 cycles per access
|
||||
H40: 20 accesses --> 366/20 = 18 cycles per access
|
||||
|
||||
VRAM access are byte wide --> VRAM writes takes 2x CPU cycles
|
||||
*/
|
||||
fifo_latency = (reg[12] & 1) ? 27 : 30;
|
||||
if ((code & 0x0F) == 0x01) fifo_latency = fifo_latency * 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
unsigned int vdp_ctrl_r(void)
|
||||
{
|
||||
/*
|
||||
* Return vdp status
|
||||
*
|
||||
* Bits are
|
||||
* 0 0:1 ntsc:pal
|
||||
* 1 DMA Busy
|
||||
* 2 During HBlank
|
||||
* 3 During VBlank
|
||||
* 4 Frame Interlace 0:even 1:odd
|
||||
* 5 Sprite collision
|
||||
* 6 Too many sprites per line
|
||||
* 7 v interrupt occurred
|
||||
* 8 Write FIFO full
|
||||
* 9 Write FIFO empty
|
||||
* 10 - 15 Next word on bus
|
||||
*/
|
||||
|
||||
/* update FIFO flags */
|
||||
if (vdptiming)
|
||||
{
|
||||
fifo_update();
|
||||
if (fifo_write_cnt < 4)
|
||||
{
|
||||
status &= 0xFEFF;
|
||||
if (fifo_write_cnt == 0) status |= 0x200;
|
||||
}
|
||||
}
|
||||
else status ^= 0x200;
|
||||
|
||||
/* update DMA Busy flag */
|
||||
if ((status & 2) && !dma_length && (count_m68k >= dma_endCycles))
|
||||
status &= 0xFFFD;
|
||||
|
||||
unsigned int temp = status | vdp_pal;
|
||||
|
||||
/* display OFF: VBLANK flag is set */
|
||||
if (!(reg[1] & 0x40)) temp |= 0x8;
|
||||
|
||||
/* HBLANK flag (Sonic 3 and Sonic 2 "VS Modes", Lemmings 2) */
|
||||
if (count_m68k <= line_m68k + 84) temp |= 0x4;
|
||||
|
||||
/* clear pending flag */
|
||||
pending = 0;
|
||||
|
||||
/* clear SPR/SCOL flags */
|
||||
status &= 0xFF9F;
|
||||
|
||||
return (temp);
|
||||
}
|
||||
|
||||
void vdp_data_w(unsigned int data)
|
||||
{
|
||||
/* Clear pending flag */
|
||||
pending = 0;
|
||||
|
||||
if (dmafill)
|
||||
{
|
||||
dma_fill(data);
|
||||
return;
|
||||
}
|
||||
|
||||
/* VDP latency (Chaos Engine, Soldiers of Fortune) */
|
||||
if (vdptiming && !(status&8) && (reg[1]&0x40))
|
||||
{
|
||||
fifo_update();
|
||||
if (fifo_write_cnt == 0)
|
||||
{
|
||||
fifo_lastwrite = count_m68k; /* reset cycle counter */
|
||||
status &= 0xFDFF; /* FIFO is not empty anymore */
|
||||
}
|
||||
|
||||
/* increase write counter */
|
||||
fifo_write_cnt ++;
|
||||
|
||||
/* is FIFO full ? */
|
||||
if (fifo_write_cnt >= 4)
|
||||
{
|
||||
status |= 0x100;
|
||||
if (fifo_write_cnt > 4) count_m68k = fifo_lastwrite + fifo_latency;
|
||||
}
|
||||
}
|
||||
|
||||
/* write data */
|
||||
data_write(data);
|
||||
}
|
||||
|
||||
unsigned int vdp_data_r(void)
|
||||
{
|
||||
uint16 temp = 0;
|
||||
|
||||
/* Clear pending flag */
|
||||
pending = 0;
|
||||
|
||||
switch (code & 0x0F)
|
||||
{
|
||||
case 0x00: /* VRAM */
|
||||
temp = *(uint16 *) & vram[(addr & 0xFFFE)];
|
||||
break;
|
||||
|
||||
case 0x08: /* CRAM */
|
||||
temp = *(uint16 *) & cram[(addr & 0x7E)];
|
||||
temp = UNPACK_CRAM (temp);
|
||||
break;
|
||||
|
||||
case 0x04: /* VSRAM */
|
||||
temp = *(uint16 *) & vsram[(addr & 0x7E)];
|
||||
break;
|
||||
}
|
||||
|
||||
/* Increment address register */
|
||||
addr += reg[15];
|
||||
|
||||
/* return data */
|
||||
return (temp);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
The reg[] array is updated at the *end* of this function, so the new
|
||||
register data can be compared with the previous data.
|
||||
*/
|
||||
void vdp_reg_w(unsigned int r, unsigned int d)
|
||||
{
|
||||
/* Check if Mode 4 (SMS mode) has been activated
|
||||
According to official doc, VDP registers #11 to #23 can not be written unless bit2 in register #1 is set
|
||||
Fix Captain Planet & Avengers (Alt version), Bass Master Classic Pro Edition (they incidentally activate Mode 4)
|
||||
*/
|
||||
if (!(reg[1] & 4) && (r > 10)) return;
|
||||
|
||||
switch(r)
|
||||
{
|
||||
case 0x00: /* CTRL #1 */
|
||||
if ((d&0x10) != (reg[0]&0x10)) hvint_updated = 0;
|
||||
break;
|
||||
|
||||
case 0x01: /* CTRL #2 */
|
||||
/* Sesame Street Counting Cafe need to execute one instruction */
|
||||
if ((d&0x20) != (reg[1]&0x20)) hvint_updated = 1;
|
||||
|
||||
/* Check if the viewport height has actually been changed */
|
||||
if((reg[1] & 8) != (d & 8))
|
||||
{
|
||||
/* Update the height of the viewport */
|
||||
bitmap.viewport.oh = bitmap.viewport.h;
|
||||
bitmap.viewport.h = (d & 8) ? 240 : 224;
|
||||
if (config.overscan) bitmap.viewport.y = ((vdp_pal ? 288 : 240) - bitmap.viewport.h) / 2;
|
||||
bitmap.viewport.changed = 1;
|
||||
|
||||
/* update VC table */
|
||||
if (vdp_pal) vctab = (d & 8) ? vc_pal_240 : vc_pal_224;
|
||||
}
|
||||
|
||||
/* DISPLAY switched ON/OFF during HBLANK */
|
||||
if ((v_counter < bitmap.viewport.h) && ((d&0x40) != (reg[1]&0x40)))
|
||||
{
|
||||
if (count_m68k <= (line_m68k + 128))
|
||||
{
|
||||
/* Redraw the current line :
|
||||
- Legend of Galahad, Lemmings 2, Nigel Mansell's World Championship Racing (set display OFF)
|
||||
- Deadly Moves aka Power Athlete (set display ON)
|
||||
*/
|
||||
reg[1] = d;
|
||||
render_line(v_counter,odd_frame);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x02: /* NTAB */
|
||||
ntab = (d << 10) & 0xE000;
|
||||
break;
|
||||
|
||||
case 0x03: /* NTWB */
|
||||
ntwb = (d << 10) & 0xF800;
|
||||
if(reg[12] & 1) ntwb &= 0xF000;
|
||||
break;
|
||||
|
||||
case 0x04: /* NTBB */
|
||||
ntbb = (d << 13) & 0xE000;
|
||||
break;
|
||||
|
||||
case 0x05: /* SATB */
|
||||
sat_base_mask = (reg[12] & 1) ? 0xFC00 : 0xFE00;
|
||||
sat_addr_mask = (reg[12] & 1) ? 0x03FF : 0x01FF;
|
||||
satb = (d << 9) & sat_base_mask;
|
||||
break;
|
||||
|
||||
case 0x07: /* Border Color index */
|
||||
/* Check if the border color has actually changed */
|
||||
d &= 0x3F;
|
||||
if(border != d)
|
||||
{
|
||||
/* Mark the border color as modified */
|
||||
border = d;
|
||||
color_update(0x00, *(uint16 *)&cram[(border << 1)]);
|
||||
|
||||
/* background color modified during HBLANK */
|
||||
if ((v_counter < bitmap.viewport.h) && (count_m68k <= (line_m68k + 84)))
|
||||
{
|
||||
/* remap current line (see Road Rash I,II,III) */
|
||||
reg[7] = d;
|
||||
remap_buffer(v_counter,bitmap.viewport.w + 2*bitmap.viewport.x);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0C:
|
||||
/* Check if the viewport width has actually been changed */
|
||||
if((reg[0x0C] & 1) != (d & 1))
|
||||
{
|
||||
/* Update the width of the viewport */
|
||||
bitmap.viewport.ow = bitmap.viewport.w;
|
||||
bitmap.viewport.w = (d & 1) ? 320 : 256;
|
||||
if (config.overscan) bitmap.viewport.x = (d & 1) ? 16 : 12;
|
||||
bitmap.viewport.changed = 1;
|
||||
|
||||
/* update HC table */
|
||||
hctab = (d & 1) ? cycle2hc40 : cycle2hc32;
|
||||
}
|
||||
|
||||
/* See if the S/TE mode bit has changed */
|
||||
if((reg[0x0C] & 8) != (d & 8))
|
||||
{
|
||||
int i;
|
||||
|
||||
/* The following color update check this value */
|
||||
reg[0x0C] = d;
|
||||
|
||||
/* Update colors */
|
||||
for (i = 0; i < 0x40; i += 1) color_update (i, *(uint16 *) & cram[i << 1]);
|
||||
color_update (0x00, *(uint16 *) & cram[border << 1]);
|
||||
}
|
||||
|
||||
/* The following register updates check this value */
|
||||
reg[0x0C] = d;
|
||||
|
||||
/* Update display-dependant registers */
|
||||
vdp_reg_w(0x03, reg[0x03]);
|
||||
vdp_reg_w(0x05, reg[0x05]);
|
||||
break;
|
||||
|
||||
case 0x0D: /* HSCB */
|
||||
hscb = (d << 10) & 0xFC00;
|
||||
break;
|
||||
|
||||
case 0x10: /* Playfield size */
|
||||
playfield_shift = shift_table[(d & 3)];
|
||||
playfield_col_mask = col_mask_table[(d & 3)];
|
||||
playfield_row_mask = row_mask_table[(d >> 4) & 3];
|
||||
y_mask = y_mask_table[(d & 3)];
|
||||
break;
|
||||
}
|
||||
|
||||
/* Write new register value */
|
||||
reg[r] = d;
|
||||
}
|
||||
|
||||
|
||||
unsigned int vdp_hvc_r(void)
|
||||
{
|
||||
uint8 hc = (hc_latch == -1) ? hctab[count_m68k%488] : (hc_latch & 0xFF);
|
||||
uint8 vc = vctab[v_counter];
|
||||
|
||||
/* interlace mode 2 */
|
||||
if (im2_flag) vc = (vc << 1) | ((vc >> 7) & 1);
|
||||
|
||||
return ((vc << 8) | hc);
|
||||
}
|
||||
|
||||
|
||||
void vdp_test_w(unsigned int value)
|
||||
{
|
||||
#ifdef LOGERROR
|
||||
error("Unused VDP Write 0x%x (%08x)", value, m68k_get_reg (NULL, M68K_REG_PC));
|
||||
#endif
|
||||
}
|
||||
|
||||
int vdp_int_ack_callback(int int_level)
|
||||
{
|
||||
if (vint_triggered)
|
||||
{
|
||||
vint_pending = 0;
|
||||
vint_triggered = 0;
|
||||
status &= ~0x0080; /* clear VINT flag */
|
||||
}
|
||||
else hint_pending = 0;
|
||||
hvint_updated = 0;
|
||||
return M68K_INT_ACK_AUTOVECTOR;
|
||||
}
|
93
source/vdp.h
Normal file
93
source/vdp.h
Normal file
@ -0,0 +1,93 @@
|
||||
/***************************************************************************************
|
||||
* Genesis Plus 1.2a
|
||||
* Video Display Processor (memory handlers)
|
||||
*
|
||||
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald (original code)
|
||||
* modified by Eke-Eke (compatibility fixes & additional code), GC/Wii port
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
****************************************************************************************/
|
||||
|
||||
#ifndef _VDP_H_
|
||||
#define _VDP_H_
|
||||
|
||||
/* VDP context */
|
||||
extern uint8 sat[0x400];
|
||||
extern uint8 vram[0x10000];
|
||||
extern uint8 cram[0x80];
|
||||
extern uint8 vsram[0x80];
|
||||
extern uint8 reg[0x20];
|
||||
extern uint16 addr;
|
||||
extern uint16 addr_latch;
|
||||
extern uint8 code;
|
||||
extern uint8 pending;
|
||||
extern uint16 status;
|
||||
extern uint8 dmafill;
|
||||
extern uint8 hint_pending;
|
||||
extern uint8 vint_pending;
|
||||
extern uint8 vint_triggered;
|
||||
extern int8 hvint_updated;
|
||||
|
||||
/* Global variables */
|
||||
extern uint16 ntab;
|
||||
extern uint16 ntbb;
|
||||
extern uint16 ntwb;
|
||||
extern uint16 satb;
|
||||
extern uint16 hscb;
|
||||
extern uint8 border;
|
||||
extern uint8 bg_name_dirty[0x800];
|
||||
extern uint16 bg_name_list[0x800];
|
||||
extern uint16 bg_list_index;
|
||||
extern uint8 bg_pattern_cache[0x80000];
|
||||
extern uint8 playfield_shift;
|
||||
extern uint8 playfield_col_mask;
|
||||
extern uint16 playfield_row_mask;
|
||||
extern uint32 y_mask;
|
||||
extern int16 h_counter;
|
||||
extern int16 hc_latch;
|
||||
extern uint16 v_counter;
|
||||
extern uint8 im2_flag;
|
||||
extern uint32 dma_length;
|
||||
extern int32 fifo_write_cnt;
|
||||
extern uint32 fifo_lastwrite;
|
||||
extern uint8 fifo_latency;
|
||||
extern uint8 vdp_pal;
|
||||
extern double vdp_timings[4][4];
|
||||
|
||||
extern uint8 *vctab;
|
||||
extern uint8 *hctab;
|
||||
extern uint8 vc_ntsc_224[262];
|
||||
extern uint8 vc_pal_224[313];
|
||||
extern uint8 vc_pal_240[313];
|
||||
extern uint8 cycle2hc32[488];
|
||||
extern uint8 cycle2hc40[488];
|
||||
|
||||
/* Function prototypes */
|
||||
extern void vdp_init(void);
|
||||
extern void vdp_reset(void);
|
||||
extern void vdp_shutdown(void);
|
||||
extern void vdp_restore(uint8 *vdp_regs);
|
||||
extern void vdp_ctrl_w(unsigned int data);
|
||||
extern unsigned int vdp_ctrl_r(void);
|
||||
extern void vdp_data_w(unsigned int data);
|
||||
extern unsigned int vdp_data_r(void);
|
||||
extern unsigned int vdp_hvc_r(void);
|
||||
extern void vdp_reg_w(unsigned int r, unsigned int d);
|
||||
extern void dma_update();
|
||||
extern void vdp_test_w(unsigned int value);
|
||||
|
||||
|
||||
#endif /* _VDP_H_ */
|
Loading…
Reference in New Issue
Block a user