end of restoration

This commit is contained in:
ekeeke31 2008-08-07 12:43:17 +00:00
parent ce72ddbbd0
commit be12343e35
14 changed files with 3249 additions and 0 deletions

151
source/unused/fileio.c Normal file
View 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
View 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
View File

@ -0,0 +1 @@
@make.exe -f makefile.mgw %1

111
source/unused/makefile.dj2 Normal file
View 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
View 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

File diff suppressed because it is too large Load Diff

274
source/unused/unzip.h Normal file
View 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
View 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
View 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
View 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
View 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
View 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
View 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
View 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_ */