📄 btime.c
字号:
/***************************************************************************
Burger Time hardware description:
Actually Lock'n'Chase is (C)1981 while Burger Time is (C)1982, so it might
be more accurate to say 'Lock'n'Chase hardware'.
The bootleg called Cook Race runs on hardware similar but different. The fact
that it addresses the program ROMs in the range 0500-3fff instead of the usual
c000-ffff makes me suspect that it is a bootleg of the *tape system* version.
Little is known about that system, but it is quite likely that it would have
RAM in the range 0000-3fff and load the program there from tape.
This hardware is pretty straightforward, but has a couple of interesting
twists. There are two ports to the video and color RAMs, one normal access,
and one with X and Y coordinates swapped. The sprite RAM occupies the
first row of the swapped area, so it appears in the regular video RAM as
the first column of on the left side.
These games don't have VBLANK interrupts, but instead an IRQ or NMI
(depending on the particular board) is generated when a coin is inserted.
Some of the games also have a background playfield which, in the
case of Bump 'n' Jump and Zoar, can be scrolled vertically.
These boards use two 8910's for sound, controlled by a dedicated 6502 (except
in Eggs, where the main processor handles the sound). The main processor
triggers an IRQ request when writing a command to the sound CPU.
Main clock: XTAL = 12 MHz
Horizontal video frequency: HSYNC = XTAL/768?? = 15.625 kHz ??
Video frequency: VSYNC = HSYNC/272 = 57.44 Hz ?
VBlank duration: 1/VSYNC * (24/272) = 1536 us ?
Note on Lock'n'Chase:
The watchdog test prints "WATCHDOG TEST ER". Just by looking at the code,
I can't see how it could print anything else, there is only one path it
can take. Should the game reset????
***************************************************************************/
#include "driver.h"
#include "vidhrdw/generic.h"
#include "M6502/m6502.h"
extern unsigned char *lnc_charbank;
extern unsigned char *bnj_backgroundram;
extern int bnj_backgroundram_size;
extern unsigned char *zoar_scrollram;
void btime_vh_convert_color_prom (unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);
void lnc_vh_convert_color_prom (unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);
void zoar_vh_convert_color_prom(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom);
void lnc_init_machine (void);
int bnj_vh_start (void);
void bnj_vh_stop (void);
void btime_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
void cookrace_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
void bnj_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
void lnc_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
void eggs_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
void zoar_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh);
void btime_paletteram_w(int offset,int data);
void bnj_background_w(int offset, int data);
void bnj_scroll1_w(int offset, int data);
void bnj_scroll2_w(int offset, int data);
int btime_mirrorvideoram_r(int offset);
void btime_mirrorvideoram_w(int offset,int data);
int btime_mirrorcolorram_r(int offset);
void btime_mirrorcolorram_w(int offset,int data);
void lnc_videoram_w(int offset,int data);
void lnc_mirrorvideoram_w(int offset,int data);
void zoar_video_control_w(int offset,int data);
void btime_video_control_w(int offset,int data);
void bnj_video_control_w(int offset,int data);
void lnc_video_control_w(int offset,int data);
int lnc_sound_interrupt(void);
static void sound_command_w(int offset,int data);
static void btime_decrypt(void)
{
int A,A1;
extern unsigned char *RAM;
/* the encryption is a simple bit rotation: 76543210 -> 65342710, but */
/* with a catch: it is only applied if the previous instruction did a */
/* memory write. Also, only opcodes at addresses with this bit pattern: */
/* xxxx xxx1 xxxx x1xx are encrypted. */
/* get the address of the next opcode */
A = cpu_getpc();
/* however if the previous instruction was JSR (which caused a write to */
/* the stack), fetch the address of the next instruction. */
A1 = cpu_getpreviouspc();
if (ROM[A1] == 0x20) /* JSR $xxxx */
A = cpu_readop_arg(A1+1) + 256 * cpu_readop_arg(A1+2);
/* If the address of the next instruction is xxxx xxx1 xxxx x1xx, decode it. */
if ((A & 0x0104) == 0x0104)
{
/* 76543210 -> 65342710 bit rotation */
ROM[A] = (RAM[A] & 0x13) | ((RAM[A] & 0x80) >> 5) | ((RAM[A] & 0x64) << 1)
| ((RAM[A] & 0x08) << 2);
}
}
static void btime_ram_w(int offset,int data)
{
extern unsigned char *RAM;
if (offset <= 0x07ff)
RAM[offset] = data;
else if (offset >= 0x0c00 && offset <= 0x0c0f)
btime_paletteram_w(offset - 0x0c00,data);
else if (offset >= 0x1000 && offset <= 0x13ff)
videoram_w(offset - 0x1000,data);
else if (offset >= 0x1400 && offset <= 0x17ff)
colorram_w(offset - 0x1400,data);
else if (offset >= 0x1800 && offset <= 0x1bff)
btime_mirrorvideoram_w(offset - 0x1800,data);
else if (offset >= 0x1c00 && offset <= 0x1fff)
btime_mirrorcolorram_w(offset - 0x1c00,data);
else if (offset == 0x4002)
btime_video_control_w(0,data);
else if (offset == 0x4003)
sound_command_w(0,data);
else if (offset == 0x4004)
bnj_scroll1_w(0,data);
btime_decrypt();
}
static void zoar_ram_w(int offset,int data)
{
int good = 0;
unsigned char *RAM = Machine->memory_region[Machine->drv->cpu[0].memory_region];
if (offset <= 0x07ff)
{ RAM[offset] = data; good = 1; }
else if (offset >= 0x8000 && offset <= 0x83ff)
{ videoram_w(offset - 0x8000,data); good = 1; }
else if (offset >= 0x8400 && offset <= 0x87ff)
{ colorram_w(offset - 0x8400,data); good = 1; }
else if (offset >= 0x8800 && offset <= 0x8bff)
{ btime_mirrorvideoram_w(offset - 0x8800,data); good = 1; }
else if (offset >= 0x8c00 && offset <= 0x8fff)
{ btime_mirrorcolorram_w(offset - 0x8c00,data); good = 1; }
else if (offset == 0x9000)
{ zoar_video_control_w(0, data); good = 1; }
else if (offset >= 0x9800 && offset <= 0x9803)
{ zoar_scrollram[offset - 0x9800] = data; good = 1; }
else if (offset == 0x9804)
{ bnj_scroll2_w(0,data); good = 1; }
else if (offset == 0x9805)
{ bnj_scroll1_w(0,data); good = 1; }
else if (offset == 0x9806)
{ sound_command_w(0,data); good = 1; }
btime_decrypt();
}
static struct MemoryReadAddress btime_readmem[] =
{
{ 0x0000, 0x07ff, MRA_RAM },
{ 0x1000, 0x17ff, MRA_RAM },
{ 0x1800, 0x1bff, btime_mirrorvideoram_r },
{ 0x1c00, 0x1fff, btime_mirrorcolorram_r },
{ 0x4000, 0x4000, input_port_0_r }, /* IN0 */
{ 0x4001, 0x4001, input_port_1_r }, /* IN1 */
{ 0x4002, 0x4002, input_port_2_r }, /* coin */
{ 0x4003, 0x4003, input_port_3_r }, /* DSW1 */
{ 0x4004, 0x4004, input_port_4_r }, /* DSW2 */
{ 0xb000, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress btime_writemem[] =
{
{ 0x0000, 0xffff, btime_ram_w }, /* override the following entries to */
/* support ROM decryption */
{ 0x0000, 0x07ff, MWA_RAM },
{ 0x0c00, 0x0c0f, btime_paletteram_w, &paletteram },
{ 0x1000, 0x13ff, videoram_w, &videoram, &videoram_size },
{ 0x1400, 0x17ff, colorram_w, &colorram },
{ 0x1800, 0x1bff, btime_mirrorvideoram_w },
{ 0x1c00, 0x1fff, btime_mirrorcolorram_w },
{ 0x4000, 0x4000, MWA_NOP },
{ 0x4002, 0x4002, btime_video_control_w },
{ 0x4003, 0x4003, sound_command_w },
{ 0x4004, 0x4004, bnj_scroll1_w },
{ -1 } /* end of table */
};
static struct MemoryReadAddress cookrace_readmem[] =
{
{ 0x0000, 0x03ff, MRA_RAM },
{ 0x0500, 0x3fff, MRA_ROM },
{ 0xc000, 0xc7ff, MRA_RAM },
{ 0xc800, 0xcbff, btime_mirrorvideoram_r },
{ 0xcc00, 0xcfff, btime_mirrorcolorram_r },
{ 0xd000, 0xd0ff, MRA_RAM }, /* background */
{ 0xd100, 0xd3ff, MRA_RAM }, /* ? */
{ 0xd400, 0xd7ff, MRA_RAM }, /* background? */
{ 0xe000, 0xe000, input_port_3_r }, /* DSW1 */
{ 0xe300, 0xe300, input_port_3_r }, /* mirror address used on high score name enter */
/* screen - could also be a bad ROM read */
{ 0xe001, 0xe001, input_port_4_r }, /* DSW2 */
{ 0xe002, 0xe002, input_port_0_r }, /* IN0 */
{ 0xe003, 0xe003, input_port_1_r }, /* IN1 */
{ 0xe004, 0xe004, input_port_2_r }, /* coin */
{ 0xfff9, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress cookrace_writemem[] =
{
{ 0x0000, 0x03ff, MWA_RAM },
{ 0x0500, 0x3fff, MWA_ROM },
{ 0xc000, 0xc3ff, videoram_w, &videoram, &videoram_size },
{ 0xc400, 0xc7ff, colorram_w, &colorram },
{ 0xc800, 0xcbff, btime_mirrorvideoram_w },
{ 0xcc00, 0xcfff, btime_mirrorcolorram_w },
{ 0xd000, 0xd0ff, MWA_RAM, &bnj_backgroundram, &bnj_backgroundram_size },
{ 0xd000, 0xd0ff, MWA_RAM }, /* background? */
{ 0xd100, 0xd3ff, MWA_RAM }, /* ? */
{ 0xd400, 0xd7ff, MWA_RAM, &bnj_backgroundram, &bnj_backgroundram_size },
{ 0xe000, 0xe000, bnj_video_control_w },
{ 0xe001, 0xe001, sound_command_w },
#if 0
{ 0x4004, 0x4004, bnj_scroll1_w },
#endif
{ 0xfff9, 0xffff, MWA_ROM },
{ -1 } /* end of table */
};
static struct MemoryReadAddress zoar_readmem[] =
{
{ 0x0000, 0x07ff, MRA_RAM },
{ 0x9800, 0x9800, input_port_3_r }, /* DSW 1 */
{ 0x9801, 0x9801, input_port_4_r }, /* DSW 2 */
{ 0x9802, 0x9802, input_port_0_r }, /* IN 0 */
{ 0x9803, 0x9803, input_port_1_r }, /* IN 1 */
{ 0x9804, 0x9804, input_port_2_r }, /* coin */
{ 0xd000, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress zoar_writemem[] =
{
{ 0x0000, 0xffff, zoar_ram_w }, /* override the following entries to */
/* support ROM decryption */
{ 0x0000, 0x07ff, MWA_RAM },
{ 0x8000, 0x83ff, videoram_w, &videoram, &videoram_size },
{ 0x8400, 0x87ff, colorram_w, &colorram },
{ 0x8800, 0x8bff, btime_mirrorvideoram_w },
{ 0x8c00, 0x8fff, btime_mirrorcolorram_w },
{ 0x9000, 0x9000, zoar_video_control_w },
{ 0x9800, 0x9803, MWA_RAM, &zoar_scrollram },
{ 0x9805, 0x9805, bnj_scroll2_w },
{ 0x9805, 0x9805, bnj_scroll1_w },
{ 0x9806, 0x9806, sound_command_w },
{ -1 } /* end of table */
};
static struct MemoryReadAddress eggs_readmem[] =
{
{ 0x0000, 0x07ff, MRA_RAM },
{ 0x1000, 0x17ff, MRA_RAM },
{ 0x1800, 0x1bff, btime_mirrorvideoram_r },
{ 0x1c00, 0x1fff, btime_mirrorcolorram_r },
{ 0x2000, 0x2000, input_port_2_r }, /* DSW1 */
{ 0x2001, 0x2001, input_port_3_r }, /* DSW2 */
{ 0x2002, 0x2002, input_port_0_r }, /* IN0 */
{ 0x2003, 0x2003, input_port_1_r }, /* IN1 */
{ 0x3000, 0x7fff, MRA_ROM },
{ 0xf000, 0xffff, MRA_ROM }, /* reset/interrupt vectors */
{ -1 } /* end of table */
};
static struct MemoryWriteAddress eggs_writemem[] =
{
{ 0x0000, 0x07ff, MWA_RAM },
{ 0x1000, 0x13ff, videoram_w, &videoram, &videoram_size },
{ 0x1400, 0x17ff, colorram_w, &colorram },
{ 0x1800, 0x1bff, btime_mirrorvideoram_w },
{ 0x1c00, 0x1fff, btime_mirrorcolorram_w },
{ 0x2000, 0x2000, btime_video_control_w },
{ 0x2001, 0x2001, MWA_NOP },
{ 0x2004, 0x2004, AY8910_control_port_0_w },
{ 0x2005, 0x2005, AY8910_write_port_0_w },
{ 0x2006, 0x2006, AY8910_control_port_1_w },
{ 0x2007, 0x2007, AY8910_write_port_1_w },
{ 0x3000, 0x7fff, MWA_ROM },
{ -1 } /* end of table */
};
static struct MemoryReadAddress lnc_readmem[] =
{
{ 0x0000, 0x3fff, MRA_RAM },
{ 0x7c00, 0x7fff, btime_mirrorvideoram_r },
{ 0x8000, 0x8000, input_port_3_r }, /* DSW1 */
{ 0x8001, 0x8001, input_port_4_r }, /* DSW2 */
{ 0x9000, 0x9000, input_port_0_r }, /* IN0 */
{ 0x9001, 0x9001, input_port_1_r }, /* IN1 */
{ 0x9002, 0x9002, input_port_2_r }, /* coin */
{ 0xc000, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress lnc_writemem[] =
{
{ 0x0000, 0x3bff, MWA_RAM },
{ 0x3c00, 0x3fff, lnc_videoram_w, &videoram, &videoram_size },
{ 0x7800, 0x7bff, MWA_RAM, &colorram },
{ 0x7c00, 0x7fff, lnc_mirrorvideoram_w },
{ 0x8000, 0x8000, MWA_NOP }, /* ??? */
{ 0x8001, 0x8001, lnc_video_control_w },
{ 0x8003, 0x8003, MWA_RAM, &lnc_charbank },
{ 0x9000, 0x9000, MWA_NOP }, /* ??? */
{ 0x9002, 0x9002, sound_command_w },
{ -1 } /* end of table */
};
static struct MemoryReadAddress bnj_readmem[] =
{
{ 0x0000, 0x07ff, MRA_RAM },
{ 0x1000, 0x1000, input_port_3_r }, /* DSW1 */
{ 0x1001, 0x1001, input_port_4_r }, /* DSW2 */
{ 0x1002, 0x1002, input_port_0_r }, /* IN0 */
{ 0x1003, 0x1003, input_port_1_r }, /* IN1 */
{ 0x1004, 0x1004, input_port_2_r }, /* coin */
{ 0x4000, 0x47ff, MRA_RAM },
{ 0x4800, 0x4bff, btime_mirrorvideoram_r },
{ 0x4c00, 0x4fff, btime_mirrorcolorram_r },
{ 0xa000, 0xffff, MRA_ROM },
{ -1 } /* end of table */
};
static struct MemoryWriteAddress bnj_writemem[] =
{
{ 0x0000, 0x07ff, MWA_RAM },
{ 0x1001, 0x1001, bnj_video_control_w },
{ 0x1002, 0x1002, sound_command_w },
{ 0x4000, 0x43ff, videoram_w, &videoram, &videoram_size },
{ 0x4400, 0x47ff, colorram_w, &colorram },
{ 0x4800, 0x4bff, btime_mirrorvideoram_w },
{ 0x4c00, 0x4fff, btime_mirrorcolorram_w },
{ 0x5000, 0x51ff, bnj_background_w, &bnj_backgroundram, &bnj_backgroundram_size },
{ 0x5400, 0x5400, bnj_scroll1_w },
{ 0x5800, 0x5800, bnj_scroll2_w },
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -