747 lines
16 KiB
C
747 lines
16 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
|
|
*
|
|
*
|
|
*
|
|
* Main O2 machine emulation
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <time.h>
|
|
#include "audio.h"
|
|
#include "types.h"
|
|
#include "cpu.h"
|
|
#include "keyboard.h"
|
|
#include "config.h"
|
|
#include "vdc.h"
|
|
#include "vpp.h"
|
|
#include "voice.h"
|
|
#include "vmachine.h"
|
|
|
|
static Byte x_latch, y_latch;
|
|
static int romlatch = 0;
|
|
static Byte line_count;
|
|
static int fps = FPS_NTSC;
|
|
|
|
static Byte snapedlines[MAXLINES + 2 * MAXSNAP][256][2];
|
|
|
|
int evblclk = EVBLCLK_NTSC;
|
|
|
|
struct resource app_data;
|
|
int frame = 0;
|
|
|
|
int int_clk; /* counter for length of /INT pulses */
|
|
int master_clk; /* Master clock */
|
|
int h_clk; /* horizontal clock */
|
|
unsigned long clk_counter;
|
|
int last_line;
|
|
int key2vcnt = 0;
|
|
int mstate;
|
|
|
|
int pendirq = 0;
|
|
int enahirq = 1;
|
|
int useforen = 0;
|
|
long regionoff = 0xffff;
|
|
int mxsnap = 2;
|
|
int sproff = 0;
|
|
int tweakedaudio = 0;
|
|
|
|
Byte rom_table[8][4096];
|
|
|
|
Byte intRAM[64];
|
|
Byte extRAM[256];
|
|
Byte extROM[1024];
|
|
Byte VDCwrite[256];
|
|
Byte ColorVector[MAXLINES];
|
|
Byte AudioVector[MAXLINES];
|
|
Byte *rom;
|
|
Byte *megarom;
|
|
|
|
int key2[128];
|
|
|
|
static void do_kluges(void);
|
|
static void setvideomode(int t);
|
|
|
|
void handle_vbl(void)
|
|
{
|
|
update_audio();
|
|
update_voice();
|
|
draw_region();
|
|
ext_IRQ();
|
|
mstate = 1;
|
|
}
|
|
|
|
void handle_evbl(void)
|
|
{
|
|
static long last = 0;
|
|
int i;
|
|
|
|
last_line = 0;
|
|
master_clk -= evblclk;
|
|
frame++;
|
|
finish_display();
|
|
|
|
if (app_data.crc == 0xA7344D1F)
|
|
{
|
|
for (i = 0; i < 140; i++)
|
|
{
|
|
ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (p1 & 0x80);
|
|
AudioVector[i] = VDCwrite[0xAA];
|
|
}
|
|
} /*Atlantis*/
|
|
else
|
|
{
|
|
for (i = 0; i < MAXLINES; i++)
|
|
{
|
|
ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (p1 & 0x80);
|
|
AudioVector[i] = VDCwrite[0xAA];
|
|
}
|
|
}
|
|
if (key2vcnt++ > 10)
|
|
{
|
|
key2vcnt = 0;
|
|
for (i = 0; i < 128; i++)
|
|
key2[i] = 0;
|
|
}
|
|
mstate = 0;
|
|
}
|
|
|
|
void handle_evbll(void)
|
|
{
|
|
static long last = 0;
|
|
int i;
|
|
|
|
/******************* 150 */
|
|
|
|
for (i = 150; i < MAXLINES; i++)
|
|
{
|
|
ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (p1 & 0x80);
|
|
AudioVector[i] = VDCwrite[0xAA];
|
|
}
|
|
|
|
if (key2vcnt++ > 10)
|
|
{
|
|
key2vcnt = 0;
|
|
for (i = 0; i < 128; i++)
|
|
key2[i] = 0;
|
|
}
|
|
mstate = 0;
|
|
}
|
|
|
|
void init_system(void)
|
|
{
|
|
int i, j, k;
|
|
|
|
last_line = 0;
|
|
mstate = 0;
|
|
master_clk = 0;
|
|
h_clk = 0;
|
|
line_count = 0;
|
|
itimer = 0;
|
|
clk_counter = 0;
|
|
init_roms();
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
VDCwrite[i] = 0;
|
|
extRAM[i] = 0;
|
|
}
|
|
for (i = 0; i < 64; i++)
|
|
{
|
|
intRAM[i] = 0;
|
|
}
|
|
for (i = 0; i < MAXLINES; i++)
|
|
AudioVector[i] = ColorVector[i] = 0;
|
|
|
|
for (i = 0; i < MAXLINES + 2 * MAXSNAP; i++)
|
|
for (j = 0; j < 256; j++)
|
|
for (k = 0; k < 2; k++)
|
|
snapedlines[i][j][k] = 0;
|
|
|
|
for (i = 0; i < 128; i++)
|
|
key2[i] = 0;
|
|
key2vcnt = 0;
|
|
if (app_data.euro)
|
|
setvideomode(1);
|
|
else
|
|
setvideomode(0);
|
|
do_kluges();
|
|
init_vpp();
|
|
clear_collision();
|
|
}
|
|
|
|
void init_roms(void)
|
|
{
|
|
rom = rom_table[0];
|
|
romlatch = 0;
|
|
}
|
|
|
|
Byte read_t1(void)
|
|
{
|
|
/*17*/
|
|
if ((h_clk > 16) || (master_clk > VBLCLK))
|
|
return 1;
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
void write_p1(Byte d)
|
|
{
|
|
if ((d & 0x80) != (p1 & 0x80))
|
|
{
|
|
int i, l;
|
|
l = snapline((int)((float)master_clk / 22.0 + 0.1), VDCwrite[0xA3],
|
|
1);
|
|
for (i = l; i < MAXLINES; i++)
|
|
ColorVector[i] = (VDCwrite[0xA3] & 0x7f) | (d & 0x80);
|
|
}
|
|
p1 = d;
|
|
if (app_data.bank == 2)
|
|
{
|
|
rom = rom_table[~p1 & 0x01];
|
|
}
|
|
else if (app_data.bank == 3)
|
|
{
|
|
rom = rom_table[~p1 & 0x03];
|
|
}
|
|
else if (app_data.bank == 4)
|
|
{
|
|
rom = rom_table[(p1 & 1) ? 0 : romlatch];
|
|
}
|
|
}
|
|
|
|
Byte read_P2(void)
|
|
{
|
|
int i, si, so, km;
|
|
|
|
return 0xff;
|
|
// TODO
|
|
/*if (NeedsPoll)
|
|
poll_keyboard();
|
|
|
|
if (!(p1 & 0x04))
|
|
{
|
|
si = (p2 & 7);
|
|
so = 0xff;
|
|
if (si < 6)
|
|
{
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
km = key_map[si][i];
|
|
if ((key[km] && ((!joykeystab[km]) || (key_shifts & KB_CAPSLOCK_FLAG))) || (key2[km]))
|
|
{
|
|
so = i ^ 0x07;
|
|
}
|
|
}
|
|
}
|
|
if (so != 0xff)
|
|
{
|
|
p2 = p2 & 0x0F;
|
|
p2 = p2 | (so << 5);
|
|
}
|
|
else
|
|
{
|
|
p2 = p2 | 0xF0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
p2 = p2 | 0xF0;
|
|
}
|
|
return (p2);*/
|
|
}
|
|
|
|
Byte ext_read(ADDRESS adr)
|
|
{
|
|
Byte d;
|
|
Byte si;
|
|
Byte m;
|
|
int i;
|
|
|
|
if (!(p1 & 0x08) && !(p1 & 0x40))
|
|
{
|
|
/* Handle VDC Read */
|
|
switch (adr)
|
|
{
|
|
case 0xA1:
|
|
d = VDCwrite[0xA0] & 0x02;
|
|
if (master_clk > VBLCLK)
|
|
d = d | 0x08;
|
|
if (h_clk < (LINECNT - 7))
|
|
d = d | 0x01;
|
|
if (sound_IRQ)
|
|
d = d | 0x04;
|
|
sound_IRQ = 0;
|
|
return d;
|
|
case 0xA2:
|
|
si = VDCwrite[0xA2];
|
|
m = 0x01;
|
|
d = 0;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
if (si & m)
|
|
{
|
|
if (coltab[1] & m)
|
|
d = d | (coltab[1] & (m ^ 0xFF));
|
|
if (coltab[2] & m)
|
|
d = d | (coltab[2] & (m ^ 0xFF));
|
|
if (coltab[4] & m)
|
|
d = d | (coltab[4] & (m ^ 0xFF));
|
|
if (coltab[8] & m)
|
|
d = d | (coltab[8] & (m ^ 0xFF));
|
|
if (coltab[0x10] & m)
|
|
d = d | (coltab[0x10] & (m ^ 0xFF));
|
|
if (coltab[0x20] & m)
|
|
d = d | (coltab[0x20] & (m ^ 0xFF));
|
|
if (coltab[0x80] & m)
|
|
d = d | (coltab[0x80] & (m ^ 0xFF));
|
|
}
|
|
m = m << 1;
|
|
}
|
|
clear_collision();
|
|
return d;
|
|
case 0xA5:
|
|
if (!(VDCwrite[0xA0] & 0x02))
|
|
{
|
|
return x_latch;
|
|
}
|
|
else
|
|
{
|
|
x_latch = h_clk * 12;
|
|
return x_latch;
|
|
}
|
|
case 0xA4:
|
|
if (!(VDCwrite[0xA0] & 0x02))
|
|
{
|
|
return y_latch;
|
|
}
|
|
else
|
|
{
|
|
y_latch = master_clk / 22;
|
|
if (y_latch > 241)
|
|
y_latch = 0xFF;
|
|
return y_latch;
|
|
}
|
|
default:
|
|
return VDCwrite[adr];
|
|
}
|
|
}
|
|
else if (!(p1 & 0x10))
|
|
{
|
|
/* Handle ext RAM Read */
|
|
if (app_data.megaxrom && (adr >= 0x80))
|
|
{
|
|
/* MegaCART registers are mirrored every 4 bytes */
|
|
if ((adr & 0x83) == 0x83)
|
|
{
|
|
/* TODO: emulate EEPROM data in */
|
|
return 0xff;
|
|
}
|
|
else
|
|
return extRAM[adr & 0x83];
|
|
}
|
|
else
|
|
return extRAM[adr & 0xFF];
|
|
}
|
|
else if (!(p1 & 0x20))
|
|
{
|
|
/* Read a Videopac+ register */
|
|
return vpp_read(adr);
|
|
}
|
|
else if (app_data.exrom && (p1 & 0x02))
|
|
{
|
|
/* Handle read from exrom */
|
|
return extROM[(p2 << 8) | (adr & 0xFF)];
|
|
}
|
|
else if (app_data.megaxrom && !(p1 & 0x02) && !(p1 & 0x40))
|
|
{
|
|
/* Handle data read from MegaCART */
|
|
return megarom[(extRAM[0x81] << 12) | ((p2 & 0x0f) << 8) | (adr & 0xff)];
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
Byte in_bus(void)
|
|
{
|
|
Byte si = 0, d = 0, mode = 0, jn = 0, sticknum = 0;
|
|
|
|
if ((p1 & 0x08) && (p1 & 0x10))
|
|
{
|
|
/* Handle joystick read */
|
|
if (!(p1 & 0x04))
|
|
{
|
|
si = (p2 & 7);
|
|
}
|
|
d = 0xFF;
|
|
// si == 1 => joystick 0
|
|
// si != 1 => joystick 1
|
|
// &= 0xfe up
|
|
// &= 0xfd right
|
|
// &= 0xfb down
|
|
// &= 0xf7 left
|
|
// &= 0xef both (?) buttons
|
|
}
|
|
return d;
|
|
}
|
|
|
|
void ext_write(Byte dat, ADDRESS adr)
|
|
{
|
|
int i;
|
|
|
|
if (!(p1 & 0x08))
|
|
{
|
|
/* Handle VDC Write */
|
|
if (adr == 0xA0)
|
|
{
|
|
if ((VDCwrite[0xA0] & 0x02) && !(dat & 0x02))
|
|
{
|
|
y_latch = master_clk / 22;
|
|
x_latch = h_clk * 12;
|
|
if (y_latch > 241)
|
|
y_latch = 0xFF;
|
|
}
|
|
if ((master_clk <= VBLCLK) && (VDCwrite[0xA0] != dat))
|
|
{
|
|
draw_region();
|
|
}
|
|
}
|
|
else if (adr == 0xA3)
|
|
{
|
|
int l;
|
|
l = snapline((int)((float)master_clk / 22.0 + 0.5), dat, 1);
|
|
for (i = l; i < MAXLINES; i++)
|
|
ColorVector[i] = (dat & 0x7f) | (p1 & 0x80);
|
|
}
|
|
else if (adr == 0xAA)
|
|
{
|
|
for (i = master_clk / 22; i < MAXLINES; i++)
|
|
AudioVector[i] = dat;
|
|
}
|
|
else if ((adr >= 0x40) && (adr <= 0x7f) && ((adr & 2) == 0))
|
|
{
|
|
/* simulate quad: all 4 sub quad position registers
|
|
* are mapped to the same internal register */
|
|
adr = adr & 0x71;
|
|
/* Another minor thing: the y register always returns
|
|
* bit 0 as 0 */
|
|
if ((adr & 1) == 0)
|
|
dat = dat & 0xfe;
|
|
VDCwrite[adr] = VDCwrite[adr + 4] = VDCwrite[adr + 8] = VDCwrite[adr + 12] = dat;
|
|
}
|
|
VDCwrite[adr] = dat;
|
|
}
|
|
else if (!(p1 & 0x10) && !(p1 & 0x40))
|
|
{
|
|
adr = adr & 0xFF;
|
|
|
|
if (adr < 0x80)
|
|
{
|
|
/* Handle ext RAM Write */
|
|
extRAM[adr] = dat;
|
|
}
|
|
else
|
|
{
|
|
if (app_data.bank == 4)
|
|
{
|
|
romlatch = (~dat) & 7;
|
|
rom = rom_table[(p1 & 1) ? 0 : romlatch];
|
|
}
|
|
|
|
/* Handle The Voice */
|
|
if (!(dat & 0x20))
|
|
reset_voice();
|
|
else
|
|
{
|
|
if (adr == 0xE4)
|
|
set_voice_bank(0);
|
|
else if ((adr >= 0xE8) && (adr <= 0xEF))
|
|
set_voice_bank(adr - 0xE7);
|
|
else if (((adr >= 0x80) && (adr <= 0xDF)) || ((adr >= 0xF0) && (adr <= 0xFF)))
|
|
trigger_voice(adr);
|
|
}
|
|
}
|
|
}
|
|
else if (!(p1 & 0x20))
|
|
{
|
|
/* Write to a Videopac+ register */
|
|
vpp_write(dat, adr);
|
|
}
|
|
}
|
|
|
|
static void do_kluges(void)
|
|
{
|
|
if (app_data.crc == 0xA7344D1F)
|
|
pendirq = 1; /* Atlantis */
|
|
if (app_data.crc == 0xFB83171E)
|
|
pendirq = 1; /* Blockout */
|
|
if (app_data.crc == 0xD38153F6)
|
|
pendirq = 1; /* Blockout (french) */
|
|
if (app_data.crc == 0x881CEAE4)
|
|
pendirq = 1; /* Wall Street */
|
|
|
|
if (app_data.crc == 0x9E42E766)
|
|
useforen = 1; /* Turtles */
|
|
if (app_data.crc == 0x1C750349)
|
|
useforen = 1; /* Turtles (European version) */
|
|
if (app_data.crc == 0x202F2749)
|
|
useforen = 1; /* Q*bert */
|
|
if (app_data.crc == 0x06861A9C)
|
|
useforen = 1; /* Flashpoint 5 (Videopac adaption) */
|
|
|
|
if (app_data.crc == 0xFB83171E)
|
|
enahirq = 0; /* Blockout*/
|
|
if (app_data.crc == 0xD38153F6)
|
|
enahirq = 0; /* Blockout (french) */
|
|
|
|
if (app_data.crc == 0xFB83171E)
|
|
regionoff = 1; /* Blockout*/
|
|
if (app_data.crc == 0xD38153F6)
|
|
regionoff = 1; /* Blockout (french) */
|
|
if (app_data.crc == 0x202F2749)
|
|
regionoff = 0; /* Q*bert */
|
|
if (app_data.crc == 0x5216771A)
|
|
regionoff = 1; /* Popeye */
|
|
if (app_data.crc == 0x0C2E4811)
|
|
regionoff = 11; /* Out of this World! / Helicopter Rescue! */
|
|
if (app_data.crc == 0x67069924)
|
|
regionoff = 11; /* Smithereens! */
|
|
if (app_data.crc == 0x44D1A8A5)
|
|
regionoff = 11; /* Smithereens! (European version) */
|
|
if (app_data.crc == 0x2391C2FB)
|
|
regionoff = 11; /* Smithereens! + */
|
|
if (app_data.crc == 0xBB4AD548)
|
|
regionoff = 11; /* Smithereens! modified 1 */
|
|
if (app_data.crc == 0x25057C11)
|
|
regionoff = 11; /* Smithereens! modified 2 */
|
|
if (app_data.crc == 0xB936BD78)
|
|
regionoff = 12; /* Type & Tell */
|
|
if (app_data.crc == 0xAD8B9AE0)
|
|
regionoff = 2; /* Type & Tell modified 1 */
|
|
if (app_data.crc == 0x5C02BEE6)
|
|
regionoff = 2; /* Type & Tell modified 2 */
|
|
if (app_data.crc == 0xDC30AD3D)
|
|
regionoff = 10; /* Dynasty! */
|
|
if (app_data.crc == 0x7810BAD5)
|
|
regionoff = 8; /* Dynasty! (European) */
|
|
if (app_data.crc == 0xA7344D1F)
|
|
regionoff = 0; /* Atlantis */
|
|
if (app_data.crc == 0xD0BC4EE6)
|
|
regionoff = 12; /* Frogger */
|
|
if (app_data.crc == 0xA57D84F3)
|
|
regionoff = 8; /* Frogger BR */
|
|
if (app_data.crc == 0x825976A9)
|
|
regionoff = 0; /* Mousing Cat 8kb */
|
|
if (app_data.crc == 0xF390BFEC)
|
|
regionoff = 0; /* Mousing Cat 4kb */
|
|
if (app_data.crc == 0x61A350E6)
|
|
regionoff = 0; /* Mousing Cat (french) */
|
|
if (app_data.crc == 0x3BFEF56B)
|
|
regionoff = 1; /* Four in 1 Row! */
|
|
if (app_data.crc == 0x7C747245)
|
|
regionoff = 1; /* Four in 1 Row! modified */
|
|
if (app_data.crc == 0x9B5E9356)
|
|
regionoff = 1; /* Four in 1 Row! (french) */
|
|
|
|
if (app_data.crc == 0x6CEBAB74)
|
|
regionoff = 12; /* P.T. Barnum's Acrobats! (European version) */
|
|
if (app_data.crc == 0xE7B26A56)
|
|
regionoff = 12; /* P.T. Barnum's Acrobats! (European version - Extra keys) */
|
|
|
|
if (app_data.crc == 0xFB83171E)
|
|
mxsnap = 3; /* Blockout*/
|
|
if (app_data.crc == 0xD38153F6)
|
|
mxsnap = 3; /* Blockout (french) */
|
|
if (app_data.crc == 0xA57E1724)
|
|
mxsnap = 12; /* Catch the Ball / Noughts and Crosses */
|
|
if (app_data.crc == 0xBE4FF48E)
|
|
mxsnap = 12; /* Catch the Ball / Noughts and Crosses modified */
|
|
if (app_data.crc == 0xFD179F6D)
|
|
mxsnap = 3; /* Clay Pigeon! */
|
|
if (app_data.crc == 0x9C9DDDF9)
|
|
mxsnap = 3; /* Verkehr */
|
|
if (app_data.crc == 0x95936B07)
|
|
mxsnap = 3; /* Super Cobra */
|
|
if (app_data.crc == 0x881CEAE4)
|
|
mxsnap = 3; /* Wall Street */
|
|
if (app_data.crc == 0x9E42E766)
|
|
mxsnap = 0; /* Turtles */
|
|
if (app_data.crc == 0x1C750349)
|
|
mxsnap = 0; /* Turtles (European version) */
|
|
if (app_data.crc == 0xD0BC4EE6)
|
|
mxsnap = 3; /* Frogger */
|
|
if (app_data.crc == 0xA57D84F3)
|
|
mxsnap = 3; /* Frogger BR */
|
|
if (app_data.crc == 0x3BFEF56B)
|
|
mxsnap = 6; /* Four in 1 Row! */
|
|
if (app_data.crc == 0x9B5E9356)
|
|
mxsnap = 6; /* Four in 1 Row! (french) */
|
|
if (app_data.crc == 0x7C747245)
|
|
mxsnap = 6; /* Four in 1 Row! modified */
|
|
|
|
if (app_data.crc == 0xA7344D1F)
|
|
setvideomode(1); /* Atlantis */
|
|
if (app_data.crc == 0x39E31BF0)
|
|
setvideomode(1); /* Jake */
|
|
if (app_data.crc == 0x92D0177B)
|
|
setvideomode(1); /* Jake (hack) */
|
|
if (app_data.crc == 0x3351FEDA)
|
|
setvideomode(1); /* Power Lords */
|
|
if (app_data.crc == 0x40AE062D)
|
|
setvideomode(1); /* Power Lords (alternate) */
|
|
if (app_data.crc == 0xD158EEBA)
|
|
setvideomode(1); /* Labirinth */
|
|
if (app_data.crc == 0x26B0FF5B)
|
|
setvideomode(1); /* Nightmare */
|
|
if (app_data.crc == 0xDF36683F)
|
|
setvideomode(1); /* Shark Hunter */
|
|
if (app_data.crc == 0xAF307559)
|
|
setvideomode(1); /* Super Bee 8Kb */
|
|
if (app_data.crc == 0x9585D511)
|
|
setvideomode(1); /* Super Bee 4Kb */
|
|
if (app_data.crc == 0x58FA6766)
|
|
setvideomode(1); /* War of the Nerves */
|
|
if (app_data.crc == 0x58FA6766)
|
|
setvideomode(1); /* War of the Nerves */
|
|
if (app_data.crc == 0x39989464)
|
|
setvideomode(1); /* Hockey! / Soccer! */
|
|
if (app_data.crc == 0x3BFEF56B)
|
|
setvideomode(1); /* Four in 1 Row! */
|
|
if (app_data.crc == 0x9B5E9356)
|
|
setvideomode(1); /* Four in 1 Row! (french) */
|
|
if (app_data.crc == 0x7C747245)
|
|
setvideomode(1); /* Four in 1 Row! modified */
|
|
if (app_data.crc == 0x68560DC7)
|
|
setvideomode(1); /* Jopac Moto Crash */
|
|
if (app_data.crc == 0x020FCA15)
|
|
setvideomode(1); /* Jopac Moto Crash modified (non VP+) */
|
|
if (app_data.crc == 0xC4134DF8)
|
|
setvideomode(1); /* Helicopter Rescue + */
|
|
if (app_data.crc == 0x0D2D721D)
|
|
setvideomode(1); /* Trans American Rally + */
|
|
if (app_data.crc == 0x9D72D4E9)
|
|
setvideomode(1); /* Blobbers */
|
|
if (app_data.crc == 0xB2F0F0B4)
|
|
setvideomode(1); /* Le Tresor Englouti + */
|
|
if (app_data.crc == 0x0B2DEB61)
|
|
setvideomode(1); /* Tutankham */
|
|
if (app_data.crc == 0x313547EB)
|
|
setvideomode(1); /* VP53 */
|
|
if (app_data.crc == 0x06861A9C)
|
|
setvideomode(1); /* Flashpoint 5 (Videopac adaption) */
|
|
if (app_data.crc == 0xA57E1724)
|
|
setvideomode(0); /* Catch the Ball / Noughts and Crosses */
|
|
if (app_data.crc == 0xBE4FF48E)
|
|
setvideomode(0); /* Catch the Ball / Noughts and Crosses modified */
|
|
if (app_data.crc == 0xFB83171E)
|
|
setvideomode(0); /* Blockout*/
|
|
if (app_data.crc == 0xD38153F6)
|
|
setvideomode(0); /* Blockout (french) */
|
|
if (app_data.crc == 0x9BFC3E01)
|
|
setvideomode(0); /* Demon Attack */
|
|
if (app_data.crc == 0x50AF9D45)
|
|
setvideomode(0); /* Demon Attack + */
|
|
if (app_data.crc == 0x9884EF36)
|
|
setvideomode(0); /* Demon Attack + modified */
|
|
if (app_data.crc == 0x4A578DFE)
|
|
setvideomode(0); /* Restaurant ntsc */
|
|
if (app_data.crc == 0x863D5E2D)
|
|
setvideomode(0); /* Shark Hunter ntsc */
|
|
|
|
if (app_data.crc == 0xD62814A3)
|
|
evblclk = 12000; /* Pick Axe Pete */
|
|
if (app_data.crc == 0xB2FFB353)
|
|
evblclk = 12000; /* Pick Axe Pete + */
|
|
if (app_data.crc == 0x81C20196)
|
|
evblclk = 12000; /* Pick Axe Pete + (modified) */
|
|
|
|
if ((app_data.crc == 0xF390BFEC) || (app_data.crc == 0x825976A9) || (app_data.crc == 0x61A350E6))
|
|
{ /* Mousing Cat */
|
|
setvideomode(1);
|
|
evblclk = 7642;
|
|
}
|
|
|
|
if (app_data.crc == 0xD0BC4EE6)
|
|
{ /* Frogger */
|
|
setvideomode(1);
|
|
evblclk = 7642;
|
|
}
|
|
if (app_data.crc == 0x26517E77)
|
|
{ /* Commando Noturno */
|
|
setvideomode(1);
|
|
evblclk = 6100;
|
|
regionoff = 12;
|
|
}
|
|
if (app_data.crc == 0xA57E1724)
|
|
{ /* Catch the ball*/
|
|
regionoff = 5;
|
|
sproff = 1;
|
|
}
|
|
|
|
if ((app_data.crc == 0x2DCB77F0) || (app_data.crc == 0xF6882734))
|
|
{ /* Depth Charge / Marksman */
|
|
setvideomode(1);
|
|
evblclk = 8000;
|
|
}
|
|
if (app_data.crc == 0x881CEAE4)
|
|
{ /* Wall Street */
|
|
setvideomode(1);
|
|
evblclk = 6100;
|
|
}
|
|
if (app_data.crc == 0xD0BC4EE6)
|
|
tweakedaudio = 1; /* Frogger */
|
|
if (app_data.crc == 0xA57D84F3)
|
|
tweakedaudio = 1; /* Frogger BR */
|
|
if (app_data.crc == 0x5216771A)
|
|
tweakedaudio = 1; /* Popeye */
|
|
if (app_data.crc == 0xAFB23F89)
|
|
tweakedaudio = 1; /* Musician */
|
|
if (app_data.crc == 0xC4134DF8)
|
|
tweakedaudio = 1; /* Helicopter Rescue + */
|
|
if (app_data.crc == 0x0D2D721D)
|
|
tweakedaudio = 1; /* Trans American Rally + */
|
|
|
|
if (app_data.crc == 0xD3B09FEC)
|
|
sproff = 1; /* Volleyball! */
|
|
if (app_data.crc == 0x551E38A2)
|
|
sproff = 1; /* Volleyball! (french) */
|
|
}
|
|
|
|
int snapline(int pos, Byte reg, int t)
|
|
{
|
|
int i;
|
|
if (pos < MAXLINES + MAXSNAP + MAXSNAP)
|
|
{
|
|
for (i = 0; i < mxsnap; i++)
|
|
{
|
|
if (snapedlines[pos + MAXSNAP - i][reg][t])
|
|
return pos - i;
|
|
if (snapedlines[pos + MAXSNAP + i][reg][t])
|
|
return pos + i;
|
|
}
|
|
snapedlines[pos + MAXSNAP][reg][t] = 1;
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
static void setvideomode(int t)
|
|
{
|
|
if (t)
|
|
{
|
|
evblclk = EVBLCLK_PAL;
|
|
fps = FPS_PAL;
|
|
}
|
|
else
|
|
{
|
|
evblclk = EVBLCLK_NTSC;
|
|
fps = FPS_NTSC;
|
|
}
|
|
}
|