313 lines
6.7 KiB
C
313 lines
6.7 KiB
C
/*
|
|
* O2EM Free Odyssey2 / Videopac+ Emulator
|
|
*
|
|
* Created by Daniel Boris <dboris@comcast.net> (c) 1997,1998
|
|
*
|
|
* Developed by Andre de la Rocha <adlroc@users.sourceforge.net>
|
|
* Arlindo M. de Oliveira <dgtec@users.sourceforge.net>
|
|
*
|
|
* http://o2em.sourceforge.net
|
|
*
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <ctype.h>
|
|
#include "crc32.h"
|
|
#include "audio.h"
|
|
#include "vmachine.h"
|
|
#include "config.h"
|
|
#include "vdc.h"
|
|
#include "cpu.h"
|
|
#include "keyboard.h"
|
|
#include "voice.h"
|
|
#include "score.h"
|
|
|
|
#include "../emulibc/emulibc.h"
|
|
#include "../emulibc/waterboxcore.h"
|
|
|
|
char name_f, rom_f, c_j;
|
|
char pathx, *k, identify;
|
|
static int load_bios(const char *data, int size);
|
|
static int load_cart(const char *data, int size);
|
|
int parse_option(char *attr, char *val);
|
|
|
|
ECL_EXPORT int Init(const char *rom, int romlen, const char *bios, int bioslen)
|
|
{
|
|
int i, cnt, cnt2;
|
|
|
|
app_data.bank = 0;
|
|
app_data.voice = 1;
|
|
app_data.exrom = 0;
|
|
app_data.three_k = 0;
|
|
app_data.crc = 0;
|
|
app_data.euro = 0;
|
|
app_data.openb = 0;
|
|
app_data.vpp = 0;
|
|
app_data.bios = 0;
|
|
app_data.scoretype = 0;
|
|
app_data.scoreaddress = 0;
|
|
app_data.default_highscore = 0;
|
|
app_data.megaxrom = 0;
|
|
|
|
init_audio();
|
|
|
|
if (!load_bios(bios, bioslen))
|
|
return 0;
|
|
|
|
if (!load_cart(rom, romlen))
|
|
return 0;
|
|
|
|
//if (app_data.voice)
|
|
//load_voice_samples(NULL);
|
|
init_display();
|
|
init_cpu();
|
|
init_system();
|
|
//set_score(app_data.scoretype, app_data.scoreaddress, app_data.default_highscore);
|
|
|
|
//run();
|
|
//if (app_data.scoretype != 0)
|
|
//save_highscore(get_score(app_data.scoretype, app_data.scoreaddress),
|
|
//scorefile);
|
|
|
|
return 1;
|
|
}
|
|
|
|
ECL_EXPORT void FrameAdvance(FrameInfo* f)
|
|
{
|
|
cpu_exec(6026);
|
|
f->Samples = 735;
|
|
f->Width = 320;
|
|
f->Height = 240;
|
|
blit(f->VideoBuffer);
|
|
}
|
|
ECL_EXPORT void GetMemoryAreas(MemoryArea* m)
|
|
{
|
|
m[0].Data = intRAM;
|
|
m[0].Name = "RAM";
|
|
m[0].Size = 64;
|
|
m[0].Flags = MEMORYAREA_FLAGS_WRITABLE | MEMORYAREA_FLAGS_PRIMARY | MEMORYAREA_FLAGS_WORDSIZE1;
|
|
}
|
|
|
|
ECL_EXPORT void SetInputCallback(void (*callback)(void))
|
|
{
|
|
// TODO
|
|
}
|
|
|
|
int parse_option(char *attr, char *val)
|
|
{
|
|
int control_scheme;
|
|
if (!strcmp(attr, "nolimit"))
|
|
{
|
|
}
|
|
else if (!strcmp(attr, "novoice"))
|
|
{
|
|
app_data.voice = !(val[0] != '0');
|
|
}
|
|
else if ((!strcmp(attr, "s1")) || (!strcmp(attr, "s2")))
|
|
{
|
|
}
|
|
else if (!strcmp(attr, "fullscreen"))
|
|
{
|
|
}
|
|
else if (!strcmp(attr, "euro"))
|
|
{
|
|
app_data.euro = (val[0] != '0');
|
|
}
|
|
else if (!strcmp(attr, "exrom"))
|
|
{
|
|
app_data.exrom = (val[0] != '0');
|
|
}
|
|
else if (!strcmp(attr, "3k"))
|
|
{
|
|
app_data.three_k = (val[0] != '0');
|
|
}
|
|
else if (!strcmp(attr, "g7400"))
|
|
{
|
|
}
|
|
else if (!strcmp(attr, "scoreadr"))
|
|
{
|
|
control_scheme = -1;
|
|
sscanf(val, "%d", &control_scheme);
|
|
if ((control_scheme >= 0) && (control_scheme <= 255))
|
|
app_data.scoreaddress = control_scheme;
|
|
else
|
|
{
|
|
fprintf(stderr, "Invalid value for option %s\n", attr);
|
|
return 0;
|
|
}
|
|
}
|
|
else if (!strcmp(attr, "scoretype"))
|
|
{
|
|
control_scheme = -1;
|
|
sscanf(val, "%d", &control_scheme);
|
|
if ((control_scheme >= 0) && (control_scheme <= 9999))
|
|
app_data.scoretype = control_scheme;
|
|
else
|
|
{
|
|
fprintf(stderr, "Invalid value for option %s\n", attr);
|
|
return 0;
|
|
}
|
|
}
|
|
else if (!strcmp(attr, "score"))
|
|
{
|
|
control_scheme = -1;
|
|
sscanf(val, "%d", &control_scheme);
|
|
if ((control_scheme >= 0) && (control_scheme <= 999999))
|
|
app_data.default_highscore = control_scheme;
|
|
else
|
|
{
|
|
fprintf(stderr, "Invalid value for option %s\n", attr);
|
|
return 0;
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int load_bios(const char *data, int size)
|
|
{
|
|
if (size != 1024)
|
|
return 0;
|
|
|
|
for (int i = 0; i < 8; i++)
|
|
{
|
|
memcpy(rom_table[i], data, 1024);
|
|
}
|
|
uint32_t crc = crc32_buf(rom_table[0], 1024);
|
|
if (crc == 0x8016A315)
|
|
{
|
|
printf("Odyssey2 bios ROM loaded\n");
|
|
app_data.vpp = 0;
|
|
app_data.bios = ROM_O2;
|
|
}
|
|
else if (crc == 0xE20A9F41)
|
|
{
|
|
printf("Videopac+ G7400 bios ROM loaded\n");
|
|
app_data.vpp = 1;
|
|
app_data.bios = ROM_G7400;
|
|
}
|
|
else if (crc == 0xA318E8D6)
|
|
{
|
|
printf("C52 bios ROM loaded\n");
|
|
app_data.vpp = 0;
|
|
app_data.bios = ROM_C52;
|
|
}
|
|
else if (crc == 0x11647CA5)
|
|
{
|
|
printf("Jopac bios ROM loaded\n");
|
|
app_data.vpp = 1;
|
|
app_data.bios = ROM_JOPAC;
|
|
}
|
|
else
|
|
{
|
|
printf("Bios ROM loaded (unknown version)\n");
|
|
app_data.vpp = 0;
|
|
app_data.bios = ROM_UNKNOWN;
|
|
return 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
static int load_cart(const char *data, int size)
|
|
{
|
|
app_data.crc = crc32_buf(data, size);
|
|
if (app_data.crc == 0xAFB23F89)
|
|
app_data.exrom = 1; /* Musician */
|
|
if (app_data.crc == 0x3BFEF56B)
|
|
app_data.exrom = 1; /* Four in 1 Row! */
|
|
if (app_data.crc == 0x9B5E9356)
|
|
app_data.exrom = 1; /* Four in 1 Row! (french) */
|
|
|
|
if (app_data.crc == 0x975AB8DA || app_data.crc == 0xE246A812)
|
|
{
|
|
fprintf(stderr, "Error: file is an incomplete ROM dump\n");
|
|
return 0;
|
|
}
|
|
|
|
if (size & 1023)
|
|
{
|
|
fprintf(stderr, "Error: file is an invalid ROM dump\n");
|
|
return 0;
|
|
}
|
|
|
|
const int l = size;
|
|
int nb, i;
|
|
|
|
/* special MegaCART design by Soeren Gust */
|
|
if ((l == 32768) || (l == 65536) || (l == 131072) || (l == 262144) || (l == 524288) || (l == 1048576))
|
|
{
|
|
app_data.megaxrom = 1;
|
|
app_data.bank = 1;
|
|
megarom = malloc(1048576);
|
|
memcpy(megarom, data, size);
|
|
|
|
/* mirror shorter files into full megabyte */
|
|
if (l < 65536)
|
|
memcpy(megarom + 32768, megarom, 32768);
|
|
if (l < 131072)
|
|
memcpy(megarom + 65536, megarom, 65536);
|
|
if (l < 262144)
|
|
memcpy(megarom + 131072, megarom, 131072);
|
|
if (l < 524288)
|
|
memcpy(megarom + 262144, megarom, 262144);
|
|
if (l < 1048576)
|
|
memcpy(megarom + 524288, megarom, 524288);
|
|
/* start in bank 0xff */
|
|
memcpy(&rom_table[0][1024], megarom + 4096 * 255 + 1024, 3072);
|
|
printf("MegaCart %ldK", l / 1024);
|
|
nb = 1;
|
|
}
|
|
else if (((l % 3072) == 0))
|
|
{
|
|
app_data.three_k = 1;
|
|
nb = l / 3072;
|
|
|
|
for (int offset = 0, i = nb - 1; i >= 0; i--, offset += 3072)
|
|
{
|
|
memcpy(&rom_table[i][1024], data + offset, 3072);
|
|
}
|
|
printf("%dK", nb * 3);
|
|
}
|
|
else
|
|
{
|
|
nb = l / 2048;
|
|
if ((nb == 2) && (app_data.exrom))
|
|
{
|
|
memcpy(&extROM[0], data, 1024);
|
|
memcpy(&rom_table[0][1024], data + 1024, 3072);
|
|
printf("3K EXROM");
|
|
}
|
|
else
|
|
{
|
|
for (int offset = 0, i = nb - 1; i >= 0; i--, offset += 2048)
|
|
{
|
|
memcpy(&rom_table[i][1024], data + offset, 2048);
|
|
memcpy(&rom_table[i][3072], &rom_table[i][2048], 1024); /* simulate missing A10 */
|
|
}
|
|
printf("%dK", nb * 2);
|
|
}
|
|
}
|
|
|
|
rom = rom_table[0];
|
|
if (nb == 1)
|
|
app_data.bank = 1;
|
|
else if (nb == 2)
|
|
app_data.bank = app_data.exrom ? 1 : 2;
|
|
else if (nb == 4)
|
|
app_data.bank = 3;
|
|
else
|
|
app_data.bank = 4;
|
|
|
|
if ((rom_table[nb - 1][1024 + 12] == 'O') && (rom_table[nb - 1][1024 + 13] == 'P') && (rom_table[nb - 1][1024 + 14] == 'N') && (rom_table[nb - 1][1024 + 15] == 'B'))
|
|
app_data.openb = 1;
|
|
|
|
printf(" CRC: %08lX\n", app_data.crc);
|
|
return 1;
|
|
}
|
|
|
|
int main(void)
|
|
{
|
|
return 0;
|
|
}
|