// license:BSD-3-Clause
// copyright-holders:ElSemi
/*
CRYSTAL SYSTEM by Brezzasoft (2001)
using VRender0 System on a Chip
The VRender0 (info at archive.org for http://www.mesdigital.com) chip contains:
- CPU Core SE3208 (info at www.adc.co.kr) @ 43Mhz
- 2 DMA chans
- 4 Timers
- 32 PIO pins
- PWM output
- 32 channels wavetable synth (8bit linear, 16bit linear and 8bit ulaw sample format)
- Custom 2D video rendering device (texture mapping, alphablend, roz)
The protection is a PIC deviced labeled SMART-IC in the rom board, I'm not sure how
it exactly works, but it supplies some opcodes that have been replaced with garbage
in the main program. I don't know if it traps reads and returns the correct ones when
reading from flash, or if it's interfaced by the main program after copying the program
from flash to ram and it provides the addresses and values to patch. I patch the flash
program with the correct data
MAME driver by ElSemi
The Crystal of Kings
Brezza Soft Corporation (Japan), 2001
This game runs on a small cartridge-based PCB known as the 'Crystal System'
The main PCB is small (approx 6" square) and contains only a few components. All of the processing
work is done by the large IC in the middle of the PCB. The system looks a bit like IGS's PGM System, in
that it's housed in a plastic case and has a single slot for insertion of a game cart. However this
system and the game carts are approx. half the size of the PGM carts.
On bootup, the screen is black and the system outputs a vertical white line on the right side of the screen.
The HSync is approx 20kHz, the screen is out of sync on a standard 15kHz arcade monitor.
After approx. 15-20 seconds, the screen changes to white and has some vertical stripes on it and the HSync
changes to 15kHz. After a few more seconds the game boots to a white screen and a blue 'Brezza Soft' logo.
Without a cart plugged in, the screen stays at the first vertical line screen.
Main PCB Layout
---------------
Brezza Soft MAGIC EYES AMG0110B
|----------------------------------------------------|
|TDA1519 VOL 3.6V_BATT SW1 SW2 SW3 |
|-| |
| DS1233 |
| |---| |
| GM76256 | | |
| DA1133A |-----| | | |
| HY57V651620 32.768kHz |MX27L| | | |
| DS1302 |1000 | | | |
|J |-------------| |-----| | | |
|A | |LED1 | | |
|M | |LED2 |CN1| |
|M HY57V651620 | VRENDERZERO | | | |
|A | | | | |
| | | | | |
| |-------------| HY57V651620 | | |
| | | |
| 14.31818MHz | | |
| PAL |---| |
| TD62003 |
|-| |
| |---------------| DSW(8) |
|-| CN2 |----------------------------------|
|---------------|
Notes:
GM76C256 : Hyundai GM76C256 32k x8 SRAM (SOP28)
MX27L1000 : Macronix MX27L1000QC-12 128k x8 EEPROM (BIOS, PLCC32)
PAL : Atmel ATF16V8-10PC PAL (DIP20)
HY57V651620: Hyundai HY57V651620 4M x16 SDRAM (SSOP54)
DA1311A : Philips DA1311A DAC (SOIC8)
DS1233 : Dallas DS1233 master reset IC (SOIC4)
DS1302 : Dallas DS1302 real time clock IC (DIP8)
VRENDERZERO: MESGraphics VRenderZERO (all-in-one main CPU/graphics/sound, QFP240)
SW1 : Push button reset switch
SW2 : Push button service switch
SW3 : Push button test switch
TDA1519 : Philips TDA1519 dual 6W stereo power amplifier (SIP9)
VOL : Master volume potentiometer
3.6V_BATT : 3.6 Volt NiCad battery 65mAh (for RTC)
TD62003 : Toshiba TD62003 PNP 50V 0.5A quad darlington switch, for driving coin meters (DIP16)
CN1 : PCI-type slot for extension riser board (for game cart connection at 90 degrees to the main PCB)
CN2 : IDC 34-way flat cable connector (purpose unknown)
VSync : 60Hz
Game cart PCB
-------------
Cart sticker: 'THE CRYSTAL OF KINGS BCSV0000'
PCB printing: Brezza Soft MAGIC EYES AMG0111B
|------------------------------|
| |
|PIC16xxx? |
| U8 U7 U6 U5 |
|3.57945Mhz |
| |
| |
| |
| |
|74HC138 |
| U4 U3 U2 U1 |
| |
| |
| |
|-| |-|
|--------------------------|
Notes:
The cart PCB is single sided and contains only...
1x 3.579545MHz crystal
1x 74HC138 logic chip
1x 18 pin unknown chip (DIP18, surface scratched but it's probably a PIC16xxx, labelled 'dgSMART-PR3 MAGIC EYES')
3x Intel E28F128J3A 128MBit surface mounted FlashROMs (TSOP56, labelled 'BREZZASOFT BCSV0004Fxx', xx=01, 02, 03)
Note: there are 8 spaces total for FlashROMs. Only U1, U2 & U3 are populated in this cart.
P's Attack (c) 2004 Uniana Co., Ltd
+----------54321---654321--654321---------------------------+
|VOL TICKET GUN_1P GUN_2P +---------|
| | |
+-+ | 256MB |
| CC-DAC | Compact |
+-+ EMUL* | Flash |
| | |
|5 +---+ +---------|
|6 | | |
|P | R | 25.1750MHz +--------------+|
|I | A | | 42Pin* ||
|N | M | +--------------+|
| | | +--------------+|
|C +---+ +------------+ | SYS ||
|O | | +--------------+|
|N +---+ | | |
|N | | |VRenderZERO+| |
|E SERVICE | R | | MagicEyes | +-------+ 62256* |
|C | A | | | | RAM | |
|T TEST | M | | | +-------+ 62256* |
|O | | +------------+ |
|R RESET +---+ |
| 14.31818MHz |
+-+ |
| EEPROM |
+-+ GAL DSW |
| |
| VGA PIC BAT3.6V* |
+-----------------------------------------------------------+
* denotes unpopulated device
RAM are Samsung K4S641632H-TC75
VGA is a standard PC 15 pin VGA connection
DSW is 2 switch dipswitch (switches 3-8 are unpopulated)
PIC is a Microchip PIC16C711-041/P (silkscreened on the PCB as COSTOM)
SYS is a ST M27C160 EPROM (silkscreened on the PCB as SYSTEM_ROM_32M)
GAL is a GAL16V8B (not dumped)
EMUL is an unpopulated 8 pin connector
EEPROM is a 93C86 16K 5.0v Serial EEPROM (2048x8-bit or 1024x16-bit)
CC-DAC is a TDA1311A Stereo Continuous Calibration DAC
P's Attack non JAMMA standard 56pin Edge Connector Pinout:
56pin Edge Connector
Solder Side | Parts Side
------------------------------------------------------------------
GND | A | 1 | GND
GND | B | 2 | GND
+5 | C | 3 | +5
+5 | D | 4 | +5
Player 1 Start Lamp | E | 5 | Coin Lamp
+12 | F | 6 | +12
------------ KEY ------------| G | 7 |------------ KEY -----------
Player 2 Start Lamp | H | 8 | Coin Counter
L Speaker (-) | J | 9 | L Speaker (+)
R Speaker (-) | K | 10| R Speaker (+)
Video Vertical Sync | L | 11|
Video Green | M | 12| Video Red
Video Sync | N | 13| Video Blue
Service Switch | P | 14| Video GND
Video Horizontal Sync | R | 15| Test Switch
| S | 16| Coin Switch
Start Player 2 | T | 17| Start Player 1
| U | 18|
| V | 19|
| W | 20|
| X | 21|
| Y | 22|
| a | 23|
| b | 24|
| d | 25|
| e | 26|
GND | f | 27| GND
GND | g | 28| GND
TICKET is a 5 pin connector:
1| LED
2| GND
3| OUT
4| IN
5| +12v
GUN_xP are 6 pin gun connectors (pins 3-6 match the UNICO sytle guns):
GUN-1P: Left (Blue) Gun Connector Pinout
1| GND
2| Solenoid
3| Sensor
4| +5V
5| Switch (Trigger)
6| GND
GUN-2P: Right (Pink) Gun Connector Pinout
1| GND
2| Solenoid
3| Sensor
4| +5V
5| Switch (Trigger)
6| GND
*/
#include "emu.h"
#include "cpu/se3208/se3208.h"
#include "machine/ds1302.h"
#include "machine/nvram.h"
#include "sound/vrender0.h"
#include "video/vrender0.h"
#include "screen.h"
#include "speaker.h"
#define IDLE_LOOP_SPEEDUP
class crystal_state : public driver_device
{
public:
crystal_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag),
m_sysregs(*this, "sysregs"),
m_workram(*this, "workram"),
m_vidregs(*this, "vidregs"),
m_textureram(*this, "textureram"),
m_frameram(*this, "frameram"),
m_reset_patch(*this, "reset_patch"),
m_maincpu(*this, "maincpu"),
m_vr0(*this, "vr0"),
m_ds1302(*this, "rtc"),
m_screen(*this, "screen")
{ }
/* memory pointers */
required_shared_ptr<uint32_t> m_sysregs;
required_shared_ptr<uint32_t> m_workram;
required_shared_ptr<uint32_t> m_vidregs;
required_shared_ptr<uint32_t> m_textureram;
required_shared_ptr<uint32_t> m_frameram;
optional_shared_ptr<uint32_t> m_reset_patch; // not needed for trivrus
/* devices */
required_device<cpu_device> m_maincpu;
required_device<vr0video_device> m_vr0;
required_device<ds1302_device> m_ds1302;
required_device<screen_device> m_screen;
#ifdef IDLE_LOOP_SPEEDUP
uint8_t m_FlipCntRead;
#endif
uint32_t m_Bank;
uint8_t m_FlipCount;
uint8_t m_IntHigh;
emu_timer *m_Timer[4];
uint32_t m_FlashCmd;
uint32_t m_PIO;
uint32_t m_DMActrl[2];
uint8_t m_OldPort4;
uint32_t *TimerRegsPtr(int which) const;
void TimerStart(int which);
DECLARE_READ32_MEMBER(FlipCount_r);
DECLARE_WRITE32_MEMBER(FlipCount_w);
DECLARE_READ32_MEMBER(Input_r);
DECLARE_WRITE32_MEMBER(IntAck_w);
DECLARE_WRITE32_MEMBER(Banksw_w);
DECLARE_WRITE32_MEMBER(Timer0_w);
DECLARE_READ32_MEMBER(Timer0_r);
DECLARE_WRITE32_MEMBER(Timer1_w);
DECLARE_READ32_MEMBER(Timer1_r);
DECLARE_WRITE32_MEMBER(Timer2_w);
DECLARE_READ32_MEMBER(Timer2_r);
DECLARE_WRITE32_MEMBER(Timer3_w);
DECLARE_READ32_MEMBER(Timer3_r);
DECLARE_READ32_MEMBER(FlashCmd_r);
DECLARE_WRITE32_MEMBER(FlashCmd_w);
DECLARE_READ32_MEMBER(PIO_r);
DECLARE_WRITE32_MEMBER(PIO_w);
DECLARE_READ32_MEMBER(DMA0_r);
DECLARE_WRITE32_MEMBER(DMA0_w);
DECLARE_READ32_MEMBER(DMA1_r);
DECLARE_WRITE32_MEMBER(DMA1_w);
void init_topbladv();
void init_officeye();
void init_crysking();
void init_evosocc();
void init_donghaer();
void init_psattack();
DECLARE_READ32_MEMBER(trivrus_input_r);
DECLARE_WRITE32_MEMBER(trivrus_input_w);
uint8_t m_trivrus_input;
DECLARE_READ32_MEMBER(crzyddz2_key_r);
DECLARE_WRITE32_MEMBER(crzyddz2_PIO_w);
uint8_t m_crzyddz2_prot;
virtual void machine_start() override;
virtual void machine_reset() override;
uint32_t screen_update_crystal(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect);
DECLARE_WRITE_LINE_MEMBER(screen_vblank_crystal);
INTERRUPT_GEN_MEMBER(crystal_interrupt);
TIMER_CALLBACK_MEMBER(Timercb);
IRQ_CALLBACK_MEMBER(icallback);
void crystal_banksw_postload();
void IntReq( int num );
inline void Timer_w( address_space &space, int which, uint32_t data, uint32_t mem_mask );
inline void DMA_w( address_space &space, int which, uint32_t data, uint32_t mem_mask );
void PatchReset( );
uint16_t GetVidReg( address_space &space, uint16_t reg );
void SetVidReg( address_space &space, uint16_t reg, uint16_t val );
void crospuzl(machine_config &config);
void crystal(machine_config &config);
void crzyddz2(machine_config &config);
void trivrus(machine_config &config);
void crospuzl_mem(address_map &map);
void crystal_mem(address_map &map);
void crzyddz2_mem(address_map &map);
void trivrus_mem(address_map &map);
};
void crystal_state::IntReq( int num )
{
address_space &space = m_maincpu->space(AS_PROGRAM);
uint32_t IntEn = space.read_dword(0x01800c08);
uint32_t IntPend = space.read_dword(0x01800c0c);
if (IntEn & (1 << num))
{
IntPend |= (1 << num);
space.write_dword(0x01800c0c, IntPend);
m_maincpu->set_input_line(SE3208_INT, ASSERT_LINE);
}
#ifdef IDLE_LOOP_SPEEDUP
m_FlipCntRead = 0;
m_maincpu->resume(SUSPEND_REASON_SPIN);
#endif
}
READ32_MEMBER(crystal_state::FlipCount_r)
{
#ifdef IDLE_LOOP_SPEEDUP
uint32_t IntPend = space.read_dword(0x01800c0c);
m_FlipCntRead++;
if (m_FlipCntRead >= 16 && !IntPend && m_FlipCount != 0)
m_maincpu->suspend(SUSPEND_REASON_SPIN, 1);
#endif
return ((uint32_t) m_FlipCount) << 16;
}
WRITE32_MEMBER(crystal_state::FlipCount_w)
{
if (ACCESSING_BITS_16_23)
{
int fc = (data >> 16) & 0xff;
if (fc == 1)
m_FlipCount++;
else if (fc == 0)
m_FlipCount = 0;
}
}
READ32_MEMBER(crystal_state::Input_r)
{
if (offset == 0)
return ioport("P1_P2")->read();
else if (offset == 1)
return ioport("P3_P4")->read();
else if( offset == 2)
{
uint8_t Port4 = ioport("SYSTEM")->read();
if (!(Port4 & 0x10) && ((m_OldPort4 ^ Port4) & 0x10)) //coin buttons trigger IRQs
IntReq(12);
if (!(Port4 & 0x20) && ((m_OldPort4 ^ Port4) & 0x20))
IntReq(19);
m_OldPort4 = Port4;
return /*dips*/ioport("DSW")->read() | (Port4 << 16);
}
return 0;
}
WRITE32_MEMBER(crystal_state::IntAck_w)
{
uint32_t IntPend = space.read_dword(0x01800c0c);
if (ACCESSING_BITS_0_7)
{
IntPend &= ~(1 << (data & 0x1f));
space.write_dword(0x01800c0c, IntPend);
if (!IntPend)
m_maincpu->set_input_line(SE3208_INT, CLEAR_LINE);
}
if (ACCESSING_BITS_8_15)
m_IntHigh = (data >> 8) & 7;
}
IRQ_CALLBACK_MEMBER(crystal_state::icallback)
{
address_space &space = m_maincpu->space(AS_PROGRAM);
uint32_t IntPend = space.read_dword(0x01800c0c);
int i;
for (i = 0; i < 32; ++i)
{
if (BIT(IntPend, i))
{
return (m_IntHigh << 5) | i;
}
}
return 0; //This should never happen
}
WRITE32_MEMBER(crystal_state::Banksw_w)
{
m_Bank = (data >> 1) & 7;
if (m_Bank <= 2)
membank("bank1")->set_base(memregion("user1")->base() + m_Bank * 0x1000000);
else
membank("bank1")->set_base(memregion("user2")->base());
}
uint32_t *crystal_state::TimerRegsPtr(int which) const
{
return &m_sysregs[0x1400/4 + which * 8/4];
}
void crystal_state::TimerStart(int which)
{
uint32_t *regs = TimerRegsPtr(which);
int PD = (regs[0] >> 8) & 0xff;
int TCV = regs[1] & 0xffff;
attotime period = attotime::from_hz(43000000) * ((PD + 1) * (TCV + 1));
m_Timer[which]->adjust(period);
// printf("timer %d start, PD = %x TCV = %x period = %s\n", which, PD, TCV, period.as_string());
}
TIMER_CALLBACK_MEMBER(crystal_state::Timercb)
{
int which = (int)(uintptr_t)ptr;
static const int num[] = { 0, 1, 9, 10 };
uint32_t *regs = TimerRegsPtr(which);
if (regs[0] & 2)
TimerStart(which);
else
regs[0] &= ~1;
IntReq(num[which]);
}
void crystal_state::Timer_w( address_space &space, int which, uint32_t data, uint32_t mem_mask )
{
uint32_t *regs = TimerRegsPtr(which);
uint32_t old = regs[0];
data = COMBINE_DATA(®s[0]);
if ((data ^ old) & 1)
{
if (data & 1)
{
TimerStart(which);
}
else
{
// Timer stop
m_Timer[which]->adjust(attotime::never);
// printf("timer %d stop\n", which);
}
}
}
WRITE32_MEMBER(crystal_state::Timer0_w)
{
Timer_w(space, 0, data, mem_mask);
}
READ32_MEMBER(crystal_state::Timer0_r)
{
return *TimerRegsPtr(0);
}
WRITE32_MEMBER(crystal_state::Timer1_w)
{
Timer_w(space, 1, data, mem_mask);
}
READ32_MEMBER(crystal_state::Timer1_r)
{
return *TimerRegsPtr(1);
}
WRITE32_MEMBER(crystal_state::Timer2_w)
{
Timer_w(space, 2, data, mem_mask);
}
READ32_MEMBER(crystal_state::Timer2_r)
{
return *TimerRegsPtr(2);
}
WRITE32_MEMBER(crystal_state::Timer3_w)
{
Timer_w(space, 3, data, mem_mask);
}
READ32_MEMBER(crystal_state::Timer3_r)
{
return *TimerRegsPtr(3);
}
READ32_MEMBER(crystal_state::FlashCmd_r)
{
if ((m_FlashCmd & 0xff) == 0xff)
{
if (m_Bank <= 2)
{
uint32_t *ptr = (uint32_t*)(memregion("user1")->base() + m_Bank * 0x1000000);
return ptr[0];
}
else
return 0xffffffff;
}
if ((m_FlashCmd & 0xff) == 0x90)
{
if (m_Bank <= 2)
return 0x00180089; //Intel 128MBit
else
return 0xffffffff;
}
return 0;
}
WRITE32_MEMBER(crystal_state::FlashCmd_w)
{
m_FlashCmd = data;
}
READ32_MEMBER(crystal_state::PIO_r)
{
return m_PIO;
}
WRITE32_MEMBER(crystal_state::PIO_w)
{
uint32_t RST = data & 0x01000000;
uint32_t CLK = data & 0x02000000;
uint32_t DAT = data & 0x10000000;
m_ds1302->ce_w(RST ? 1 : 0);
m_ds1302->io_w(DAT ? 1 : 0);
m_ds1302->sclk_w(CLK ? 1 : 0);
if (m_ds1302->io_r())
space.write_dword(0x01802008, space.read_dword(0x01802008) | 0x10000000);
else
space.write_dword(0x01802008, space.read_dword(0x01802008) & (~0x10000000));
COMBINE_DATA(&m_PIO);
}
void crystal_state::DMA_w( address_space &space, int which, uint32_t data, uint32_t mem_mask )
{
if (((data ^ m_DMActrl[which]) & (1 << 10)) && (data & (1 << 10))) //DMAOn
{
uint32_t CTR = data;
uint32_t SRC = space.read_dword(0x01800804 + which * 0x10);
uint32_t DST = space.read_dword(0x01800808 + which * 0x10);
uint32_t CNT = space.read_dword(0x0180080C + which * 0x10);
int i;
if (CTR & 0x2) //32 bits
{
for (i = 0; i < CNT; ++i)
{
uint32_t v = space.read_dword(SRC + i * 4);
space.write_dword(DST + i * 4, v);
}
}
else if (CTR & 0x1) //16 bits
{
for (i = 0; i < CNT; ++i)
{
uint16_t v = space.read_word(SRC + i * 2);
space.write_word(DST + i * 2, v);
}
}
else //8 bits
{
for (i = 0; i < CNT; ++i)
{
uint8_t v = space.read_byte(SRC + i);
space.write_byte(DST + i, v);
}
}
data &= ~(1 << 10);
space.write_dword(0x0180080C + which * 0x10, 0);
IntReq(7 + which);
}
COMBINE_DATA(&m_DMActrl[which]);
}
READ32_MEMBER(crystal_state::DMA0_r)
{
return m_DMActrl[0];
}
WRITE32_MEMBER(crystal_state::DMA0_w)
{
DMA_w(space, 0, data, mem_mask);
}
READ32_MEMBER(crystal_state::DMA1_r)
{
return m_DMActrl[1];
}
WRITE32_MEMBER(crystal_state::DMA1_w)
{
DMA_w(space, 1, data, mem_mask);
}
void crystal_state::crystal_mem(address_map &map)
{
map(0x00000000, 0x0001ffff).rom().nopw();
map(0x01200000, 0x0120000f).r(this, FUNC(crystal_state::Input_r));
map(0x01280000, 0x01280003).w(this, FUNC(crystal_state::Banksw_w));
map(0x01400000, 0x0140ffff).ram().share("nvram");
map(0x01800000, 0x0180ffff).ram().share("sysregs");
map(0x01800800, 0x01800803).rw(this, FUNC(crystal_state::DMA0_r), FUNC(crystal_state::DMA0_w));
map(0x01800810, 0x01800813).rw(this, FUNC(crystal_state::DMA1_r), FUNC(crystal_state::DMA1_w));
map(0x01800c04, 0x01800c07).w(this, FUNC(crystal_state::IntAck_w));
map(0x01801400, 0x01801403).rw(this, FUNC(crystal_state::Timer0_r), FUNC(crystal_state::Timer0_w));
map(0x01801408, 0x0180140b).rw(this, FUNC(crystal_state::Timer1_r), FUNC(crystal_state::Timer1_w));
map(0x01801410, 0x01801413).rw(this, FUNC(crystal_state::Timer2_r), FUNC(crystal_state::Timer2_w));
map(0x01801418, 0x0180141b).rw(this, FUNC(crystal_state::Timer3_r), FUNC(crystal_state::Timer3_w));
map(0x01802004, 0x01802007).rw(this, FUNC(crystal_state::PIO_r), FUNC(crystal_state::PIO_w));
map(0x02000000, 0x027fffff).ram().share("workram");
map(0x03000000, 0x0300ffff).ram().share("vidregs");
map(0x030000a4, 0x030000a7).rw(this, FUNC(crystal_state::FlipCount_r), FUNC(crystal_state::FlipCount_w));
map(0x03800000, 0x03ffffff).ram().share("textureram");
map(0x04000000, 0x047fffff).ram().share("frameram");
map(0x04800000, 0x04800fff).rw("vrender", FUNC(vrender0_device::vr0_snd_read), FUNC(vrender0_device::vr0_snd_write));
map(0x05000000, 0x05ffffff).bankr("bank1");
map(0x05000000, 0x05000003).rw(this, FUNC(crystal_state::FlashCmd_r), FUNC(crystal_state::FlashCmd_w));
map(0x44414F4C, 0x44414F7F).ram().share("reset_patch");
}
// Trivia R Us
// To do: touch panel, RTC
READ32_MEMBER(crystal_state::trivrus_input_r)
{
switch (m_trivrus_input)
{
case 1: return ioport("IN1")->read();
case 2: return ioport("IN2")->read();
case 3: return ioport("IN3")->read();
case 4: return ioport("IN4")->read();
case 5: return ioport("IN5")->read();
case 6: return ioport("DSW")->read();
}
logerror("%s: unknown input %02x read\n", machine().describe_context(), m_trivrus_input);
return 0xffffffff;
}
WRITE32_MEMBER(crystal_state::trivrus_input_w)
{
if (ACCESSING_BITS_0_7)
m_trivrus_input = data & 0xff;
}
void crystal_state::trivrus_mem(address_map &map)
{
map(0x00000000, 0x0007ffff).rom().nopw();
// 0x01280000 & 0x0000ffff (written at boot)
map(0x01500000, 0x01500003).rw(this, FUNC(crystal_state::trivrus_input_r), FUNC(crystal_state::trivrus_input_w));
// 0x01500010 & 0x000000ff = sec
// 0x01500010 & 0x00ff0000 = min
// 0x01500014 & 0x000000ff = hour
// 0x01500014 & 0x00ff0000 = day
// 0x01500018 & 0x000000ff = month
// 0x0150001c & 0x000000ff = year - 2000
map(0x01600000, 0x01607fff).ram().share("nvram");
map(0x01800000, 0x0180ffff).ram().share("sysregs");
map(0x01800800, 0x01800803).rw(this, FUNC(crystal_state::DMA0_r), FUNC(crystal_state::DMA0_w));
map(0x01800810, 0x01800813).rw(this, FUNC(crystal_state::DMA1_r), FUNC(crystal_state::DMA1_w));
map(0x01800c04, 0x01800c07).w(this, FUNC(crystal_state::IntAck_w));
map(0x01801400, 0x01801403).rw(this, FUNC(crystal_state::Timer0_r), FUNC(crystal_state::Timer0_w));
map(0x01801408, 0x0180140b).rw(this, FUNC(crystal_state::Timer1_r), FUNC(crystal_state::Timer1_w));
map(0x01801410, 0x01801413).rw(this, FUNC(crystal_state::Timer2_r), FUNC(crystal_state::Timer2_w));
map(0x01801418, 0x0180141b).rw(this, FUNC(crystal_state::Timer3_r), FUNC(crystal_state::Timer3_w));
map(0x01802004, 0x01802007).rw(this, FUNC(crystal_state::PIO_r), FUNC(crystal_state::PIO_w));
map(0x02000000, 0x027fffff).ram().share("workram");
map(0x03000000, 0x0300ffff).ram().share("vidregs");
map(0x030000a4, 0x030000a7).rw(this, FUNC(crystal_state::FlipCount_r), FUNC(crystal_state::FlipCount_w));
map(0x03800000, 0x03ffffff).ram().share("textureram");
map(0x04000000, 0x047fffff).ram().share("frameram");
map(0x04800000, 0x04800fff).rw("vrender", FUNC(vrender0_device::vr0_snd_read), FUNC(vrender0_device::vr0_snd_write));
map(0x05000000, 0x05ffffff).bankr("bank1");
map(0x05000000, 0x05000003).rw(this, FUNC(crystal_state::FlashCmd_r), FUNC(crystal_state::FlashCmd_w));
// AM_RANGE(0x44414F4C, 0x44414F7F) AM_RAM AM_SHARE("reset_patch")
}
void crystal_state::crospuzl_mem(address_map &map)
{
trivrus_mem(map);
map(0x01500000, 0x01500003).r(this, FUNC(crystal_state::FlashCmd_r));
map(0x01500100, 0x01500103).w(this, FUNC(crystal_state::FlashCmd_w));
map(0x01510000, 0x01510003).portr("IN0");
map(0x01511000, 0x01511003).portr("IN1");
map(0x01512000, 0x01512003).portr("IN2");
map(0x01513000, 0x01513003).portr("IN3");
}
// Crazy Dou Di Zhu II
// To do: HY04 (pic?) protection
WRITE32_MEMBER(crystal_state::crzyddz2_PIO_w)
{
COMBINE_DATA(&m_PIO);
if (ACCESSING_BITS_8_15)
{
int mux = (m_PIO >> 8) & 0x1f;
if (mux == 0x1f)
{
m_crzyddz2_prot = ((m_PIO >> 8) & 0xc0) ^ 0x40;
logerror("%s: PIO = %08x, prot = %02x\n", machine().describe_context(), m_PIO, m_crzyddz2_prot);
}
}
}
READ32_MEMBER(crystal_state::crzyddz2_key_r)
{
static const char *const key_names[] = { "KEY0", "KEY1", "KEY2", "KEY3", "KEY4" };
int mux = (m_PIO >> 8) & 0x1f;
uint8_t data = 0x3f;
for (int i = 0; i < sizeof(key_names)/sizeof(key_names[0]); ++i)
if (!BIT(mux,i))
data = ioport(key_names[i])->read();
/*
crzyddz2 in out
00 40
40 00
c0 80
*/
// m_crzyddz2_prot = (m_PIO >> 8) & 0xc0) ^ 0x40;
m_crzyddz2_prot = (machine().rand() & 0xc0);
return 0xffffff00 | data | m_crzyddz2_prot;
}
void crystal_state::crzyddz2_mem(address_map &map)
{
map(0x00000000, 0x00ffffff).rom().nopw();
map(0x01280000, 0x01280003).w(this, FUNC(crystal_state::Banksw_w));
map(0x01400000, 0x0140ffff).ram().share("nvram");
map(0x01500000, 0x01500003).portr("P1_P2");
map(0x01500004, 0x01500007).r(this, FUNC(crystal_state::crzyddz2_key_r));
map(0x01800000, 0x0180ffff).ram().share("sysregs");
map(0x01800800, 0x01800803).rw(this, FUNC(crystal_state::DMA0_r), FUNC(crystal_state::DMA0_w));
map(0x01800810, 0x01800813).rw(this, FUNC(crystal_state::DMA1_r), FUNC(crystal_state::DMA1_w));
map(0x01800c04, 0x01800c07).w(this, FUNC(crystal_state::IntAck_w));
map(0x01801400, 0x01801403).rw(this, FUNC(crystal_state::Timer0_r), FUNC(crystal_state::Timer0_w));
map(0x01801408, 0x0180140b).rw(this, FUNC(crystal_state::Timer1_r), FUNC(crystal_state::Timer1_w));
map(0x01801410, 0x01801413).rw(this, FUNC(crystal_state::Timer2_r), FUNC(crystal_state::Timer2_w));
map(0x01801418, 0x0180141b).rw(this, FUNC(crystal_state::Timer3_r), FUNC(crystal_state::Timer3_w));
map(0x01802004, 0x01802007).rw(this, FUNC(crystal_state::PIO_r), FUNC(crystal_state::crzyddz2_PIO_w));
map(0x02000000, 0x027fffff).ram().share("workram");
map(0x03000000, 0x0300ffff).ram().share("vidregs");
map(0x030000a4, 0x030000a7).rw(this, FUNC(crystal_state::FlipCount_r), FUNC(crystal_state::FlipCount_w));
map(0x03800000, 0x03ffffff).ram().share("textureram");
map(0x04000000, 0x047fffff).ram().share("frameram");
map(0x04800000, 0x04800fff).rw("vrender", FUNC(vrender0_device::vr0_snd_read), FUNC(vrender0_device::vr0_snd_write));
map(0x05000000, 0x05ffffff).bankr("bank1");
map(0x05000000, 0x05000003).rw(this, FUNC(crystal_state::FlashCmd_r), FUNC(crystal_state::FlashCmd_w));
// AM_RANGE(0x44414F4C, 0x44414F7F) AM_RAM AM_SHARE("reset_patch")
}
void crystal_state::PatchReset( )
{
if (!m_reset_patch)
return;
//The test menu reset routine seems buggy
//it reads the reset vector from 0x02000000 but it should be
//read from 0x00000000. At 0x2000000 there is the bios signature
//"LOADED VER....", so it jumps to "LOAD" in hex (0x44414F4C)
//I'll add some code there that makes the game stay in a loop
//reading the flip register so the idle skip works
/*
Loop1:
LDI 1,%R2
LDI 0x30000a6,%R1
STS %R2,(%R1,0x0)
loop:
LDI 0x30000a6,%R1
LDSU (%R1,0x0),%R2
CMP %R2,0x0000
JNZ loop
JMP Loop1
*/
#if 1
static const uint32_t Patch[] =
{
0x40c0ea01,
0xe906400a,
0x40c02a20,
0xe906400a,
0xa1d03a20,
0xdef4d4fa
};
memcpy(m_reset_patch, Patch, sizeof(Patch));
#else
static const uint8_t Patch[] =
{
0x01,0xEA,0xC0,0x40,0x0A,0x40,0x06,0xE9,
0x20,0x2A,0xC0,0x40,0x0A,0x40,0x06,0xE9,
0x20,0x3A,0xD0,0xA1,0xFA,0xD4,0xF4,0xDE
};
memcpy(m_reset_patch, Patch, sizeof(Patch));
#endif
}
void crystal_state::crystal_banksw_postload()
{
if (m_Bank <= 2)
membank("bank1")->set_base(memregion("user1")->base() + m_Bank * 0x1000000);
else
membank("bank1")->set_base(memregion("user2")->base());
}
void crystal_state::machine_start()
{
int i;
for (i = 0; i < 4; i++)
m_Timer[i] = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(crystal_state::Timercb),this), (void*)(uintptr_t)i);
PatchReset();
#ifdef IDLE_LOOP_SPEEDUP
save_item(NAME(m_FlipCntRead));
#endif
save_item(NAME(m_Bank));
save_item(NAME(m_FlipCount));
save_item(NAME(m_IntHigh));
save_item(NAME(m_FlashCmd));
save_item(NAME(m_PIO));
save_item(NAME(m_DMActrl));
save_item(NAME(m_OldPort4));
save_item(NAME(m_trivrus_input));
machine().save().register_postload(save_prepost_delegate(FUNC(crystal_state::crystal_banksw_postload), this));
}
void crystal_state::machine_reset()
{
int i;
memset(m_sysregs, 0, 0x10000);
memset(m_vidregs, 0, 0x10000);
m_FlipCount = 0;
m_IntHigh = 0;
m_Bank = 0;
membank("bank1")->set_base(memregion("user1")->base() + 0);
m_FlashCmd = 0xff;
m_OldPort4 = 0;
m_DMActrl[0] = 0;
m_DMActrl[1] = 0;
for (i = 0; i < 4; i++)
{
*TimerRegsPtr(i) = 0xff << 8;
m_Timer[i]->adjust(attotime::never);
}
machine().device<vrender0_device>("vrender")->set_areas(m_textureram, m_frameram);
#ifdef IDLE_LOOP_SPEEDUP
m_FlipCntRead = 0;
#endif
PatchReset();
m_crzyddz2_prot = 0x00;
}
uint16_t crystal_state::GetVidReg( address_space &space, uint16_t reg )
{
return space.read_word(0x03000000 + reg);
}
void crystal_state::SetVidReg( address_space &space, uint16_t reg, uint16_t val )
{
space.write_word(0x03000000 + reg, val);
}
uint32_t crystal_state::screen_update_crystal(screen_device &screen, bitmap_ind16 &bitmap, const rectangle &cliprect)
{
int xres = 320;
int yres = 240;
// probably more registers around here control height / interlace enable etc.
// 0x341c looks like height, but doesn't change for interlace mode.
xres = m_sysregs[0x340c / 4]+1;
if (xres > 640) xres = 640;
// force double height if 640 wide (probably a reg for this)
if (xres == 640) yres = 480;
rectangle visarea;
visarea.set(0, xres-1, 0, yres-1);
m_screen->configure(xres, yres, visarea, m_screen->frame_period().attoseconds() );
address_space &space = m_maincpu->space(AS_PROGRAM);
int DoFlip;
uint32_t B0 = 0x0;
uint32_t B1 = (GetVidReg(space, 0x90) & 0x8000) ? 0x400000 : 0x100000;
uint16_t *Front, *Back;
uint16_t *Visible, *DrawDest;
uint16_t *srcline;
int y;
uint16_t head, tail;
uint32_t width = screen.width();
if (GetVidReg(space, 0x8e) & 1)
{
Front = (uint16_t*) (m_frameram + B1 / 4);
Back = (uint16_t*) (m_frameram + B0 / 4);
}
else
{
Front = (uint16_t*) (m_frameram + B0 / 4);
Back = (uint16_t*) (m_frameram + B1 / 4);
}
Visible = (uint16_t*) Front;
// ERROR: This cast is NOT endian-safe without the use of BYTE/WORD/DWORD_XOR_* macros!
DrawDest = reinterpret_cast<uint16_t *>(m_frameram.target());
if (GetVidReg(space, 0x8c) & 0x80)
DrawDest = Front;
else
DrawDest = Back;
// DrawDest = Visible;
srcline = (uint16_t *) DrawDest;
DoFlip = 0;
head = GetVidReg(space, 0x82);
tail = GetVidReg(space, 0x80);
while ((head & 0x7ff) != (tail & 0x7ff))
{
// ERROR: This cast is NOT endian-safe without the use of BYTE/WORD/DWORD_XOR_* macros!
DoFlip = m_vr0->vrender0_ProcessPacket(0x03800000 + head * 64, DrawDest, reinterpret_cast<uint8_t*>(m_textureram.target()));
head++;
head &= 0x7ff;
if (DoFlip)
break;
}
if (DoFlip)
SetVidReg(space, 0x8e, GetVidReg(space, 0x8e) ^ 1);
srcline = (uint16_t *) Visible;
for (y = 0; y < screen.height(); y++)
memcpy(&bitmap.pix16(y), &srcline[y * 1024], width * 2);
return 0;
}
WRITE_LINE_MEMBER(crystal_state::screen_vblank_crystal)
{
// rising edge
if (state)
{
address_space &space = m_maincpu->space(AS_PROGRAM);
uint16_t head, tail;
int DoFlip = 0;
head = GetVidReg(space, 0x82);
tail = GetVidReg(space, 0x80);
while ((head & 0x7ff) != (tail & 0x7ff))
{
uint16_t Packet0 = space.read_word(0x03800000 + head * 64);
if (Packet0 & 0x81)
DoFlip = 1;
head++;
head &= 0x7ff;
if (DoFlip)
break;
}
SetVidReg(space, 0x82, head);
if (DoFlip)
{
if (m_FlipCount)
m_FlipCount--;
}
}
}
INTERRUPT_GEN_MEMBER(crystal_state::crystal_interrupt)
{
IntReq(24); //VRender0 VBlank
}
static INPUT_PORTS_START(crystal)
PORT_START("P1_P2")
PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1)
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2)
PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1)
PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2)
PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1)
PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2)
PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1)
PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2)
PORT_BIT( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1)
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2)
PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1)
PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2)
PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1)
PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2)
PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1)
PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2)
PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("P3_P4")
PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3)
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(4)
PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3)
PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(4)
PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3)
PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(4)
PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(3)
PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(4)
PORT_BIT( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(3)
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(4)
PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(3)
PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(4)
PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(3)
PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(4)
PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(3)
PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(4)
PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("SYSTEM")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_START3 )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_START4 )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_SERVICE_NO_TOGGLE( 0x80, IP_ACTIVE_LOW )
PORT_START("DSW")
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Pause ) )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Free_Play ) )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Test ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
static INPUT_PORTS_START(officeye)
PORT_START("P1_P2")
PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(2) PORT_NAME("P2 Red") // RED
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(2) PORT_NAME("P2 Green") // GREEN
PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(2) PORT_NAME("P2 Blue") // BLUE
PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_UNKNOWN )
//PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_START2 ) // where is start2?
PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_NAME("P1 Red") // RED
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(3) PORT_NAME("P3 Red")
PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_NAME("P1 Green") // GREEN
PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(3) PORT_NAME("P3 Green")
PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(1) PORT_NAME("P1 Blue") // BLUE
PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_PLAYER(3) PORT_NAME("P3 Blue")
PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_START1 )
PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_START3 )
PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("P3_P4")
PORT_BIT( 0x000000ff, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00ff0000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("SYSTEM")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_COIN1 )
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_COIN2 )
PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE1 )
PORT_SERVICE_NO_TOGGLE( 0x80, IP_ACTIVE_LOW )
PORT_START("DSW")
PORT_DIPNAME( 0x01, 0x01, DEF_STR( Pause ) )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Free_Play ) )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Test ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
INPUT_PORTS_END
static INPUT_PORTS_START(trivrus)
PORT_START("IN1")
PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Up") PORT_CODE(KEYCODE_UP)
PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Left/True") PORT_CODE(KEYCODE_LEFT)
PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Down") PORT_CODE(KEYCODE_DOWN)
PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN2")
PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Enter/Exit")
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("Next")
PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_OTHER ) PORT_NAME("Right/False") PORT_CODE(KEYCODE_RIGHT)
PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_IMPULSE(1)
PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN3")
PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("Sound")
PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN4")
PORT_BIT( 0x000000ff, IP_ACTIVE_LOW, IPT_OTHER )PORT_CODE(KEYCODE_9)
PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN5")
PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_SERVICE1 ) // Free Game
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_SERVICE_NO_TOGGLE( 0x08, IP_ACTIVE_LOW ) // Setup
PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("DSW")
PORT_DIPNAME( 0x01, 0x01, "Interlace?" )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, "Serial?" )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) ) // hangs at boot
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, "Touch Screen" )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
static INPUT_PORTS_START(crospuzl)
PORT_START("IN0")
PORT_DIPNAME( 0x01, 0x01, "DSW1" )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN1")
PORT_DIPNAME( 0x01, 0x01, "IN1" )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN2")
PORT_DIPNAME( 0x01, 0x01, "IN2" )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x80, 0x80, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x80, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_START("IN3")
PORT_DIPNAME( 0x01, 0x01, "IN3" )
PORT_DIPSETTING( 0x01, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x02, 0x02, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x02, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x04, 0x04, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x04, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x08, 0x08, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x08, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x10, 0x10, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x10, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x20, 0x20, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x20, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_DIPNAME( 0x40, 0x40, DEF_STR( Unknown ) )
PORT_DIPSETTING( 0x40, DEF_STR( Off ) )
PORT_DIPSETTING( 0x00, DEF_STR( On ) )
PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("PCB-SW1")
PORT_BIT( 0xffffff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
INPUT_PORTS_END
static INPUT_PORTS_START(crzyddz2)
PORT_START("P1_P2") // 1500002 & 1500000
PORT_BIT( 0x00000001, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) // up
PORT_BIT( 0x00000002, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) // down (next secret code)
PORT_BIT( 0x00000004, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) // left (inc secret code)
PORT_BIT( 0x00000008, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) // right (dec secret code)
PORT_BIT( 0x00000010, IP_ACTIVE_LOW, IPT_BUTTON1 ) // A
PORT_BIT( 0x00000020, IP_ACTIVE_LOW, IPT_BUTTON2 ) // B
PORT_BIT( 0x00000040, IP_ACTIVE_LOW, IPT_BUTTON3 ) // C (bet)
PORT_BIT( 0x00000080, IP_ACTIVE_LOW, IPT_BUTTON4 ) // D
PORT_BIT( 0x0000ff00, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00010000, IP_ACTIVE_LOW, IPT_START1 ) // start (secret code screen)
PORT_BIT( 0x00020000, IP_ACTIVE_LOW, IPT_SERVICE2 ) // .. 2 (next secret code / stats)
PORT_BIT( 0x00040000, IP_ACTIVE_LOW, IPT_SERVICE ) // .. 1 (secret code screen / service mode)
PORT_BIT( 0x00080000, IP_ACTIVE_LOW, IPT_SERVICE1 ) // .. 3 (inc secret code / credit)
PORT_BIT( 0x00100000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0x00200000, IP_ACTIVE_LOW, IPT_SERVICE3 ) // .. 4 (exit secret screen / clear credits)
PORT_BIT( 0x00400000, IP_ACTIVE_LOW, IPT_SERVICE4 ) // (reset and clear ram?)
PORT_BIT( 0x00800000, IP_ACTIVE_LOW, IPT_UNKNOWN )
PORT_BIT( 0xff000000, IP_ACTIVE_LOW, IPT_UNKNOWN )
// 1500004 (multiplexed by 1802005)
PORT_START("KEY0")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_A )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_E )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_I )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_M )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_KAN ) // kan
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_FLIP_FLOP ) // start?
PORT_START("KEY1")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_B )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_F )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_J )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_N )
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_REACH ) // ?
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_BET ) // ? + C
PORT_START("KEY2")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_C )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_G )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_K )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_CHI ) // chi
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_SCORE ) // ?
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
PORT_START("KEY3")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_D )
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_H )
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_L )
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_MAHJONG_PON ) // pon
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
PORT_START("KEY4")
PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_RON ) // ron
PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_MAHJONG_DOUBLE_UP ) // ?
PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) // nothing
PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_BIG ) // big
PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_SMALL ) // small + D
INPUT_PORTS_END
MACHINE_CONFIG_START(crystal_state::crystal)
MCFG_DEVICE_ADD("maincpu", SE3208, 43000000)
MCFG_DEVICE_PROGRAM_MAP(crystal_mem)
MCFG_DEVICE_VBLANK_INT_DRIVER("screen", crystal_state, crystal_interrupt)
MCFG_DEVICE_IRQ_ACKNOWLEDGE_DRIVER(crystal_state, icallback)
MCFG_NVRAM_ADD_0FILL("nvram")
MCFG_SCREEN_ADD("screen", RASTER)
MCFG_SCREEN_REFRESH_RATE(60)
MCFG_SCREEN_VBLANK_TIME(ATTOSECONDS_IN_USEC(0))
MCFG_SCREEN_SIZE(640, 480)
MCFG_SCREEN_VISIBLE_AREA(0, 639, 0, 479)
MCFG_SCREEN_UPDATE_DRIVER(crystal_state, screen_update_crystal)
MCFG_SCREEN_VBLANK_CALLBACK(WRITELINE(*this, crystal_state, screen_vblank_crystal))
MCFG_SCREEN_PALETTE("palette")
MCFG_DEVICE_ADD("vr0", VIDEO_VRENDER0, 0)
MCFG_VIDEO_VRENDER0_CPU("maincpu")
MCFG_PALETTE_ADD_RRRRRGGGGGGBBBBB("palette")
MCFG_DS1302_ADD("rtc", XTAL(32'768))
SPEAKER(config, "lspeaker").front_left();
SPEAKER(config, "rspeaker").front_right();
MCFG_SOUND_VRENDER0_ADD("vrender", 0)
MCFG_VR0_REGBASE(0x04800000)
MCFG_SOUND_ROUTE(0, "lspeaker", 1.0)
MCFG_SOUND_ROUTE(1, "rspeaker", 1.0)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(crystal_state::trivrus)
crystal(config);
MCFG_DEVICE_MODIFY("maincpu")
MCFG_DEVICE_PROGRAM_MAP(trivrus_mem)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(crystal_state::crospuzl)
crystal(config);
MCFG_DEVICE_MODIFY("maincpu")
MCFG_DEVICE_PROGRAM_MAP(crospuzl_mem)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(crystal_state::crzyddz2)
crystal(config);
MCFG_DEVICE_MODIFY("maincpu")
MCFG_DEVICE_PROGRAM_MAP(crzyddz2_mem)
MACHINE_CONFIG_END
ROM_START( crysbios )
ROM_REGION( 0x20000, "maincpu", 0 ) // bios
ROM_LOAD("mx27l1000.u14", 0x000000, 0x020000, CRC(beff39a9) SHA1(b6f6dda58d9c82273f9422c1bd623411e58982cb) )
ROM_REGION32_LE( 0x3000000, "user1", ROMREGION_ERASEFF ) // Flash
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF ) // Unmapped flash
ROM_END
ROM_START( crysking )
ROM_REGION( 0x20000, "maincpu", 0 ) // bios
ROM_LOAD("mx27l1000.u14", 0x000000, 0x020000, CRC(beff39a9) SHA1(b6f6dda58d9c82273f9422c1bd623411e58982cb))
ROM_REGION32_LE( 0x3000000, "user1", 0 ) // Flash
ROM_LOAD("bcsv0004f01.u1", 0x0000000, 0x1000000, CRC(8feff120) SHA1(2ea42fa893bff845b5b855e2556789f8354e9066) )
ROM_LOAD("bcsv0004f02.u2", 0x1000000, 0x1000000, CRC(0e799845) SHA1(419674ce043cb1efb18303f4cb7fdbbae642ee39) )
ROM_LOAD("bcsv0004f03.u3", 0x2000000, 0x1000000, CRC(659e2d17) SHA1(342c98f3f695ef4dea8b533612451c4d2fb58809) )
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF ) // Unmapped flash
ROM_END
ROM_START( evosocc )
ROM_REGION( 0x20000, "maincpu", 0 ) // bios
ROM_LOAD("mx27l1000.u14", 0x000000, 0x020000, CRC(beff39a9) SHA1(b6f6dda58d9c82273f9422c1bd623411e58982cb))
ROM_REGION32_LE( 0x3000000, "user1", 0 ) // Flash
ROM_LOAD("bcsv0001u01", 0x0000000, 0x1000000, CRC(2581a0ea) SHA1(ee483ac60a3ed00a21cb515974cec4af19916a7d) )
ROM_LOAD("bcsv0001u02", 0x1000000, 0x1000000, CRC(47ef1794) SHA1(f573706c17d1342b9b7aed9b40b8b648f0bf58db) )
ROM_LOAD("bcsv0001u03", 0x2000000, 0x1000000, CRC(f396a2ec) SHA1(f305eb10856fb5d4c229a6b09d6a2fb21b24ce66) )
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF ) // Unmapped flash
ROM_END
ROM_START( topbladv )
ROM_REGION( 0x20000, "maincpu", 0 ) // bios
ROM_LOAD("mx27l1000.u14", 0x000000, 0x020000, CRC(beff39a9) SHA1(b6f6dda58d9c82273f9422c1bd623411e58982cb))
ROM_REGION( 0x4300, "pic", 0 ) // pic16c727 - we don't have a core for this
ROM_LOAD("top_blade_v_pic16c727.bin", 0x000000, 0x4300, CRC(9cdea57b) SHA1(884156085f9e780cdf719aedc2e8a0fd5983613b) )
ROM_REGION32_LE( 0x3000000, "user1", 0 ) // Flash
ROM_LOAD("flash.u1", 0x0000000, 0x1000000, CRC(bd23f640) SHA1(1d22aa2c828642bb7c1dfea4e13f777f95acc701) )
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF ) // Unmapped flash
ROM_END
ROM_START( officeye )
ROM_REGION( 0x20000, "maincpu", 0 ) // bios (not the standard one)
ROM_LOAD("bios.u14", 0x000000, 0x020000, CRC(ffc57e90) SHA1(6b6a17fd4798dea9c7b880f3063be8494e7db302) )
ROM_REGION( 0x4280, "pic", 0 ) // pic16f84a - we don't have a core for this
ROM_LOAD("office_yeo_in_cheon_ha_pic16f84a.bin", 0x000000, 0x4280, CRC(7561cdf5) SHA1(eade592823a110019b4af81a7dc56d01f7d6589f) )
ROM_REGION32_LE( 0x3000000, "user1", 0 ) // Flash
ROM_LOAD("flash.u1", 0x0000000, 0x1000000, CRC(d3f3eec4) SHA1(ea728415bd4906964b7d37f4379a8a3bd42a1c2d) )
ROM_LOAD("flash.u2", 0x1000000, 0x1000000, CRC(e4f85d0a) SHA1(2ddfa6b3a30e69754aa9d96434ff3d37784bfa57) )
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF ) // Unmapped flash
ROM_END
ROM_START( donghaer )
ROM_REGION( 0x20000, "maincpu", 0 ) // bios
ROM_LOAD("mx27l1000.u14", 0x000000, 0x020000, CRC(beff39a9) SHA1(b6f6dda58d9c82273f9422c1bd623411e58982cb))
ROM_REGION( 0x4280, "pic", 0 ) // pic16f84a - we don't have a core for this (or the dump in this case)
ROM_LOAD("donghaer_pic16f84a.bin", 0x000000, 0x4280, NO_DUMP )
ROM_REGION32_LE( 0x3000000, "user1", 0 ) // Flash
ROM_LOAD( "u1", 0x0000000, 0x1000000, CRC(61217ad7) SHA1(2593f1356aa850f4f9aa5d00bec822aa59c59224) )
ROM_LOAD( "u2", 0x1000000, 0x1000000, CRC(6d82f1a5) SHA1(036bd45f0daac1ffeaa5ad9774fc1b56e3c75ff9) )
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF ) // Unmapped flash
ROM_END
ROM_START( trivrus )
ROM_REGION( 0x80000, "maincpu", 0 )
ROM_LOAD( "u4", 0x00000, 0x80000, CRC(2d2e9a11) SHA1(73e7b19a032eae21312ca80f8c42cc16725496a7) )
ROM_REGION32_LE( 0x3000000, "user1", ROMREGION_ERASEFF ) // Flash
ROM_LOAD( "u3", 0x000000, 0x1000010, CRC(ba901707) SHA1(e281ba07024cd19ef1ab72d2197014f7b1f4d30f) )
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF ) // Unmapped flash
ROM_END
ROM_START( crospuzl ) /* This PCB uses ADC 'Amazon-LF' SoC, EISC CPU core - However PCBs have been see with a standard VRenderZERO+ MagicEyes EISC chip */
ROM_REGION( 0x80010, "maincpu", 0 )
ROM_LOAD("en29lv040a.u5", 0x000000, 0x80010, CRC(d50e8500) SHA1(d681cd18cd0e48854c24291d417d2d6d28fe35c1) )
ROM_REGION32_LE( 0x8400010, "user1", ROMREGION_ERASEFF ) // Flash
// mostly empty, but still looks good
ROM_LOAD("k9f1g08u0a.riser", 0x000000, 0x8400010, CRC(7f3c88c3) SHA1(db3169a7b4caab754e9d911998a2ece13c65ce5b) )
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF ) // Unmapped flash
ROM_END
ROM_START( psattack )
ROM_REGION( 0x200000, "maincpu", 0 )
ROM_LOAD("5.sys", 0x000000, 0x200000, CRC(f09878e4) SHA1(25b8dbac47d3911615c8874746e420ece13e7181) )
ROM_REGION( 0x4010, "pic16c711", 0 )
ROM_LOAD("16c711.pic", 0x0000, 0x137b, CRC(617d8292) SHA1(d32d6054ce9db2e31efaf41015afcc78ed32f6aa) ) // raw dump
ROM_LOAD("16c711.bin", 0x0000, 0x4010, CRC(b316693f) SHA1(eba1f75043bd415268eedfdb95c475e73c14ff86) ) // converted to binary
DISK_REGION( "cfcard" )
DISK_IMAGE_READONLY( "psattack", 0, SHA1(e99cd0dafc33ec13bf56061f81dc7c0a181594ee) )
// keep driver happy
ROM_REGION32_LE( 0x3000000, "user1", ROMREGION_ERASEFF )
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF )
ROM_END
ROM_START( ddz )
ROM_REGION( 0xc00000, "maincpu", 0 )
ROM_LOAD("ddz.001.rom", 0x000000, 0x400000, CRC(b379f823) SHA1(531885b35d668d22c75a9759994f4aca6eacb046) )
ROM_LOAD("ddz.002.rom", 0x400000, 0x400000, CRC(285c744d) SHA1(2f8bc70825e55e3114015cb263e786df35cde275) )
ROM_LOAD("ddz.003.rom", 0x800000, 0x400000, CRC(61c9b5c9) SHA1(0438417398403456a1c49408881797a94aa86f49) )
// keep driver happy
ROM_REGION32_LE( 0x3000000, "user1", ROMREGION_ERASEFF )
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF )
ROM_END
/*
招级疯斗 - "Zhaoji Fengdou" - "Crazy Class"
Haze's notes:
fwiw, it's probably same PCB as the non-working 'ddz' in MAME, but different game.
there's some kind of encryption/scrambling going on, at the very least
Code:
Offset 0 1 2 3 4 5 6 7 8 9 A B C D E F
0007BE60 00 00 00 99 03 AD AF 00 00 00 82 00 03 AD 64 63 ™ ¯ ‚ dc
0007BE70 62 61 39 38 37 36 35 34 33 32 31 30 00 4E 61 4E ba9876543210 NaN
0007BE80 00 66 6E 49 02 0E 85 06 02 0E 84 04 02 0E 83 EA fnI … „ ƒê
0007BE90 02 0E 83 D6 02 0E 83 C8 02 0E 84 58 02 0E 84 12 ƒÖ ƒÈ „X „
0007BEA0 66 65 28 00 30 00 65 73 61 62 20 64 61 62 20 3A fe( 0 esab dab :
0007BEB0 66 74 6E 69 72 70 66 76 20 6E 69 20 67 75 62 00 ftnirpfv ni gub
0007BEC0 46 45 44 43 42 41 39 38 37 36 35 34 33 32 31 30 FEDCBA9876543210
0007BED0 00 29 6C 6C 75 6E 2E 00 00 00 8F 8E 02 0E 89 DC )llun. Ž ‰Ü
if you reverse the letters you get 'bug in vfprintf : bad base'
so I suspect the data is in reverse order and maybe some blocks scrambled about.
*/
ROM_START( crzclass ) // PCB marked MAH-JONG
ROM_REGION( 0xc00000, "maincpu", 0 )
ROM_LOAD("tjf-mahjong-rom1.bin", 0x000000, 0x400000, CRC(0a8af816) SHA1(9f292e847873078ed2b7584f463633cf9086c7e8) ) // SHARP LH28F320BJD-TTL80
ROM_LOAD("tjf-mahjong-rom2.bin", 0x400000, 0x400000, CRC(2a04e84a) SHA1(189b16fd4314fd2a5f8a1214618b5db83f8ac59a) ) // SHARP LH28F320BJD-TTL80
ROM_LOAD("tjf-mahjong-rom3.bin", 0x800000, 0x400000, CRC(1cacf3f9) SHA1(e6c88c98aeb7df4098f8e20f412018617005724d) ) // SHARP LH28F320BJD-TTL80
// rom4 not populated
// keep driver happy
ROM_REGION32_LE( 0x3000000, "user1", ROMREGION_ERASEFF )
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF )
ROM_END
/***************************************************************************
Crazy Dou Di Zhu II
Sealy, 2006
PCB Layout
----------
070405-fd-VER1.2
|--------------------------------------|
| PAL 27C322.U36 |
| BATTERY|
| M59PW1282 62256 14.31818MHz |
| W9864G66 |
| |
|J VRENDERZERO+ |
|A W9864G66 |
|M W9864G66 |
|M 8MHz |
|A HY04 0260F8A |
| 28.63636MHz |
| |
| VR1 TLDA1311 |
| TDA1519|
| 18WAY VOL 10WAY |
|--------------------------------------|
Notes:
0260F8A - unknown TQFP44
HY04 - rebadged DIP8 PIC - type unknown *
W9864G66 - Winbond 64MBit DRAM
M59PW1282 - ST Microelectronics 128MBit SOP44 FlashROM.
This is two 64MB SOP44 ROMs in one package
* The pins are:
1 ground
2 nothing
3 data (only active for 1/4 second when the playing cards or "PASS" shows in game next to each player)
4 nothing
5 nothing
6 clock
7 +5V (could be VPP for programming voltage)
8 +5V
***************************************************************************/
ROM_START( crzyddz2 )
ROM_REGION32_LE( 0x3000000, "user1", ROMREGION_ERASEFF ) // Flash
ROM_LOAD( "rom.u48", 0x000000, 0x1000000, CRC(0f3a1987) SHA1(6cad943846c79db31226676c7391f32216cfff79) )
ROM_REGION( 0x1000000, "maincpu", ROMREGION_ERASEFF )
ROM_COPY( "user1", 0x000000, 0x000000, 0x1000000 ) // copy flash here
ROM_LOAD( "27c322.u49", 0x000000, 0x0200000, CRC(b3177f39) SHA1(2a28bf8045bd2e053d88549b79fbc11f30ef9a32) ) // 1ST AND 2ND HALF IDENTICAL
ROM_CONTINUE( 0x000000, 0x0200000 )
ROM_REGION( 0x4280, "pic", 0 ) // hy04
ROM_LOAD("hy04", 0x000000, 0x4280, NO_DUMP )
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF ) // Unmapped flash
ROM_END
/***************************************************************************
Meng Hong Lou (Dream of the Red Chamber)
Sealy, 2004?
Red PCB, very similar to crzyddz2
***************************************************************************/
ROM_START( menghong )
ROM_REGION32_LE( 0x3000000, "user1", ROMREGION_ERASEFF ) // Flash
ROM_LOAD( "rom.u48", 0x000000, 0x1000000, CRC(e24257c4) SHA1(569d79a61ff6d35100ba5727069363146df9e0b7) )
ROM_REGION( 0x1000000, "maincpu", 0 )
ROM_COPY( "user1", 0x000000, 0x000000, 0x1000000 ) // copy flash here
ROM_LOAD( "060511_08-01-18.u49", 0x000000, 0x0200000, CRC(b0c12107) SHA1(b1753757bbdb7d996df563ac6abdc6b46676704b) ) // 27C160
ROM_REGION( 0x4280, "pic", 0 ) // hy04
ROM_LOAD("menghong_hy04", 0x000000, 0x4280, NO_DUMP )
ROM_REGION( 0x1000000, "user2", ROMREGION_ERASEFF ) // Unmapped flash
ROM_END
void crystal_state::init_crysking()
{
uint16_t *Rom = (uint16_t*) memregion("user1")->base();
//patch the data feed by the protection
Rom[WORD_XOR_LE(0x7bb6/2)] = 0xDF01;
Rom[WORD_XOR_LE(0x7bb8/2)] = 0x9C00;
Rom[WORD_XOR_LE(0x976a/2)] = 0x901C;
Rom[WORD_XOR_LE(0x976c/2)] = 0x9001;
Rom[WORD_XOR_LE(0x8096/2)] = 0x90FC;
Rom[WORD_XOR_LE(0x8098/2)] = 0x9001;
Rom[WORD_XOR_LE(0x8a52/2)] = 0x4000; //NOP
Rom[WORD_XOR_LE(0x8a54/2)] = 0x403c; //NOP
}
void crystal_state::init_evosocc()
{
uint16_t *Rom = (uint16_t*) memregion("user1")->base();
Rom += 0x1000000 * 2 / 2;
Rom[WORD_XOR_LE(0x97388E/2)] = 0x90FC; //PUSH R2..R7
Rom[WORD_XOR_LE(0x973890/2)] = 0x9001; //PUSH R0
Rom[WORD_XOR_LE(0x971058/2)] = 0x907C; //PUSH R2..R6
Rom[WORD_XOR_LE(0x971060/2)] = 0x9001; //PUSH R0
Rom[WORD_XOR_LE(0x978036/2)] = 0x900C; //PUSH R2-R3
Rom[WORD_XOR_LE(0x978038/2)] = 0x8303; //LD (%SP,0xC),R3
Rom[WORD_XOR_LE(0x974ED0/2)] = 0x90FC; //PUSH R7-R6-R5-R4-R3-R2
Rom[WORD_XOR_LE(0x974ED2/2)] = 0x9001; //PUSH R0
}
/* note on PIC protection from ElSemi (for actually emulating it instead of patching)
The PIC uses a software UART bit banged on a single output pin of the main CPU:
the data port is bit 0x20000000 on the PIO register, the same register where the EEPROM control lines are. The serial data is transmitted at 8 data bits, even parity, 1 stop bit. It's probably
tricky to get it working properly because it doesn't rely on a clock signal, and so, the pic and main cpu must run in parallel, and the bit lengths must match. The pic bit delay routine is just a loop.
also it seems that bit 0x40000000 is the PIC reset.
*/
void crystal_state::init_topbladv()
{
// patches based on analysis of PIC dump
uint16_t *Rom = (uint16_t*) memregion("user1")->base();
/*
PIC Protection data:
- RAM ADDR - --PATCH--
62 0f 02 02 fc 90 01 90
68 6a 02 02 04 90 01 90
2c cf 03 02 e9 df c2 c3
00 e0 03 02 01 90 00 92
*/
Rom[WORD_XOR_LE(0x12d7a/2)]=0x90FC; //PUSH R7-R6-R5-R4-R3-R2
Rom[WORD_XOR_LE(0x12d7c/2)]=0x9001; //PUSH R0
Rom[WORD_XOR_LE(0x18880/2)]=0x9004; //PUSH R2
Rom[WORD_XOR_LE(0x18882/2)]=0x9001; //PUSH R0
Rom[WORD_XOR_LE(0x2fe18/2)]=0x9001; //PUSH R0
Rom[WORD_XOR_LE(0x2fe1a/2)]=0x9200; //PUSH SR
Rom[WORD_XOR_LE(0x2ED44/2)]=0xDFE9; //CALL 0x3cf00
Rom[WORD_XOR_LE(0x2ED46/2)]=0xC3C2; //MOV %SR0,%DR1
}
void crystal_state::init_officeye()
{
// patches based on analysis of PIC dump
uint16_t *Rom = (uint16_t*) memregion("user1")->base();
/*
PIC Protection data:
- RAM ADDR - --PATCH--
0a 83 01 02 1c 90 01 90
50 85 01 02 7c 90 01 90
4c 99 05 02 04 90 01 90
3a c1 01 02 1c 90 01 90
*/
Rom[WORD_XOR_LE(0x9c9e/2)]=0x901C; //PUSH R4-R3-R2
Rom[WORD_XOR_LE(0x9ca0/2)]=0x9001; //PUSH R0
Rom[WORD_XOR_LE(0x9EE4/2)]=0x907C; //PUSH R6-R5-R4-R3-R2
Rom[WORD_XOR_LE(0x9EE6/2)]=0x9001; //PUSH R0
Rom[WORD_XOR_LE(0x4B2E0/2)]=0x9004; //PUSH R2
Rom[WORD_XOR_LE(0x4B2E2/2)]=0x9001; //PUSH R0
Rom[WORD_XOR_LE(0xDACE/2)]=0x901c; //PUSH R4-R3-R2
Rom[WORD_XOR_LE(0xDAD0/2)]=0x9001; //PUSH R0
}
void crystal_state::init_donghaer()
{
uint16_t *Rom = (uint16_t*)memregion("user1")->base();
Rom[WORD_XOR_LE(0x037A2 / 2)] = 0x9004; // PUSH %R2
Rom[WORD_XOR_LE(0x037A4 / 2)] = 0x8202; // LD (%SP,0x8),%R2
Rom[WORD_XOR_LE(0x03834 / 2)] = 0x9001; // PUSH %R0
Rom[WORD_XOR_LE(0x03836 / 2)] = 0x9200; // PUSH %SR
Rom[WORD_XOR_LE(0x0AC9E / 2)] = 0x9004; // PUSH %R2
Rom[WORD_XOR_LE(0x0ACA0 / 2)] = 0x4081; // LERI 0x81
Rom[WORD_XOR_LE(0x19C70 / 2)] = 0x900C; // PUSH %R2-%R3
Rom[WORD_XOR_LE(0x19C72 / 2)] = 0x9001; // PUSH %R0
}
void crystal_state::init_psattack()
{
}
GAME( 2001, crysbios, 0, crystal, crystal, crystal_state, empty_init, ROT0, "BrezzaSoft", "Crystal System BIOS", MACHINE_IS_BIOS_ROOT )
GAME( 2001, crysking, crysbios, crystal, crystal, crystal_state, init_crysking, ROT0, "BrezzaSoft", "The Crystal of Kings", 0 )
GAME( 2001, evosocc, crysbios, crystal, crystal, crystal_state, init_evosocc, ROT0, "Evoga", "Evolution Soccer", 0 )
GAME( 2003, topbladv, crysbios, crystal, crystal, crystal_state, init_topbladv, ROT0, "SonoKong / Expotato", "Top Blade V", 0 )
GAME( 2001, officeye, 0, crystal, officeye, crystal_state, init_officeye, ROT0, "Danbi", "Office Yeo In Cheon Ha (version 1.2)", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION ) // still has some instability issues
GAME( 2001, donghaer, 0, crystal, crystal, crystal_state, init_donghaer, ROT0, "Danbi", "Donggul Donggul Haerong", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION )
GAME( 2004?,menghong, 0, crzyddz2, crzyddz2, crystal_state, empty_init, ROT0, "Sealy", "Meng Hong Lou", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION )
GAME( 2006, crzyddz2, 0, crzyddz2, crzyddz2, crystal_state, empty_init, ROT0, "Sealy", "Crazy Dou Di Zhu II", MACHINE_NOT_WORKING | MACHINE_UNEMULATED_PROTECTION )
GAME( 2009, trivrus, 0, trivrus, trivrus, crystal_state, empty_init, ROT0, "AGT", "Trivia R Us (v1.07)", 0 ) // has a CF card instead of flash roms
GAME( 200?, crospuzl, 0, crospuzl, crospuzl, crystal_state, empty_init, ROT0, "<unknown>", "Cross Puzzle", MACHINE_NOT_WORKING )
GAME( 2004, psattack, 0, crystal, crystal, crystal_state, init_psattack, ROT0, "Uniana", "P's Attack", MACHINE_IS_SKELETON )
// looks like the same kind of hw from strings in the ROM, but scrambled / encrypted?
GAME( 200?, ddz, 0, crystal, crystal, crystal_state, empty_init, ROT0, "IGS?", "Dou Di Zhu", MACHINE_IS_SKELETON )
GAME( 200?, crzclass, 0, crystal, crystal, crystal_state, empty_init, ROT0, "TJF", "Zhaoji Fengdou", MACHINE_IS_SKELETON ) // 'Crazy Class'