/************************************************************************************************** Sega Saturn & Sega ST-V (Sega Titan Video) HW (c) 1994 Sega Driver by David Haywood, Angelo Salese, Olivier Galibert & Mariusz Wojcieszek SCSP driver provided by R.Belmont, based on ElSemi's SCSP sound chip emulator CD Block driver provided by ANY, based on sthief original emulator Many thanks to Guru, Fabien, Runik and Charles MacDonald for the help given. =================================================================================================== Notes: -To enter into an Advanced Test Mode,keep pressed the Test Button (F2) on the start-up. -Memo: Some tests done on the original & working PCB,to be implemented: -The AD-Stick returns 0x00 or a similar value. -The Ports E,F & G must return 0xff TODO: (Main issues) - decap the SH-1, used for CD block (needed especially for Sega Saturn) - IRQs: some games have some issues with timing accurate IRQs, check/fix all of them. - The Cart-Dev mode hangs even with the -dev bios,I would like to see what it does on the real HW. - IC13 games on the dev bios doesn't even load the cartridge / crashes the emulation at start-up, rom rearrange needed? - SCU DSP still has its fair share of issues, it also needs to be converted to CPU structure; - Add the RS232c interface (serial port),needed by fhboxers. - Video emulation bugs: check stvvdp2.c file. - Reimplement the idle skip if possible. - clean up the I/Os, by using per-game specific mapped ports and rewrite it by using 16-bit trampolines - Properly emulate the protection chips, used by several games (check stvprot.c for more info) - Move SCU device into its respective file; - Split ST-V and Saturn files properly; (per-game issues) - stress: accesses the Sound Memory Expansion Area (0x05a80000-0x05afffff), unknown purpose; - smleague / finlarch: it randomly hangs / crashes,it works if you use a ridiculous MCFG_INTERLEAVE number,might need strict SH-2 synching. - groovef / myfairld: why do we get 2 credits on startup? Cause might be by a communication with the M68k - myfairld: Apparently this game gives a black screen (either test mode and in-game mode),but let it wait for about 10 seconds and the game will load everything. This is because of a hellishly slow m68k sub-routine located at 54c2. Likely to not be a bug but an in-game design issue. - danchih: hanafuda panel doesn't work. - findlove: controls doesn't work? Playing with the debugger at location $6063720 it makes it get furter,but controls still doesn't work, missing irq? - batmanfr: Missing sound,caused by an extra ADSP chip which is on the cart.The CPU is a ADSP-2181,and it's the same used by NBA Jam Extreme (ZN game). - vfremix: when you play as Akira, there is a problem with third match: game doesn't upload all textures and tiles and doesn't enable display, although gameplay is normal - wait a while to get back to title screen after losing a match =================================================================================================== Hardware overview: ------------------ -two SH-2 CPUs,in a master/slave configuration.The master cpu is used to boot-up and to do the most of the work,the slave one does extra work that could be too much for a single cpu.They both shares all the existant devices; -a M68000 CPU,used to drive sound(the SCSP chip).The program is uploaded via the SH-2 cpus; -a SMPC (System Manager & Peripheral Control),used to drive all the devices on the board; -a SCU (System Control Unit),mainly used to do DMA operations and to drive interrupts,it also has a DSP; -an (optional for the ST-V) SH-1 CPU,used to be the CD driver; -An A-Bus,where the cart ROM area is located; -A B-Bus,where the Video Hardware & the SCU sections are located; -Two VDPs chips(named as 1 & 2),used for the video section: -VDP1 is used to render sprites & polygons. -VDP2 is for the tilemap system,there are: 4 effective normal layers; 2 roz layers; 1 back layer; 1 line layer; The VDP2 is capable of the following things (in order): -dynamic resolution (up to 704x512) & various interlacing modes; -mosaic process; -scrolling,scaling,horizontal & vertical cell scrolling & linescroll for the normal planes, the roz ones can also rotate; -versatile window system,used for various effects; -alpha-blending,refered as Color Calculation in the docs; -shadow effects; -global rgb brightness control,separate for every plane; ****************************************************************************************************/ #include "emu.h" #include "cpu/m68000/m68000.h" #include "machine/eeprom.h" #include "cpu/sh2/sh2.h" #include "machine/stvcd.h" #include "machine/scudsp.h" #include "sound/scsp.h" #include "sound/cdda.h" #include "machine/stvprot.h" #include "machine/smpc.h" #include "includes/stv.h" #include "imagedev/chd_cd.h" #include "imagedev/cartslot.h" #include "coreutil.h" /* TODO: do this in a verboselog style */ #define LOG_CDB 0 #define LOG_SCU 1 #define LOG_IRQ 0 #define LOG_IOGA 0 static int DectoBCD(int num) { int i, cnt = 0, tmp, res = 0; while (num > 0) { tmp = num; while (tmp >= 10) tmp %= 10; for (i=0; i 29 0074 30 0078 31 007c DMA Status Register 32 0080 DSP Program Control Port 33 0084 DSP Program RAM Data Port 34 0088 DSP Data RAM Address Port 35 008c DSP Data RAM Data Port 36 0090 Timer 0 Compare Register 37 0094 Timer 1 Set Data Register 38 0098 Timer 1 Mode Register 39 009c 40 00a0 Interrupt Mask Register 41 00a4 Interrupt Status Register 42 00a8 A-Bus Interrupt Acknowledge 43 00ac 44 00b0 A-Bus Set Register 45 00b4 46 00b8 A-Bus Refresh Register 47 00bc 48 00c0 49 00c4 SCU SDRAM Select Register 50 00c8 SCU Version Register 51 00cc 52 00cf =================================================================================== DMA Status Register(32-bit): xxxx xxxx x--- xx-- xx-- xx-- xx-- xx-- UNUSED ---- ---- -x-- ---- ---- ---- ---- ---- DMA DSP-Bus access ---- ---- --x- ---- ---- ---- ---- ---- DMA B-Bus access ---- ---- ---x ---- ---- ---- ---- ---- DMA A-Bus access ---- ---- ---- --x- ---- ---- ---- ---- DMA lv 1 interrupt ---- ---- ---- ---x ---- ---- ---- ---- DMA lv 0 interrupt ---- ---- ---- ---- --x- ---- ---- ---- DMA lv 2 in stand-by ---- ---- ---- ---- ---x ---- ---- ---- DMA lv 2 in operation ---- ---- ---- ---- ---- --x- ---- ---- DMA lv 1 in stand-by ---- ---- ---- ---- ---- ---x ---- ---- DMA lv 1 in operation ---- ---- ---- ---- ---- ---- --x- ---- DMA lv 0 in stand-by ---- ---- ---- ---- ---- ---- ---x ---- DMA lv 0 in operation ---- ---- ---- ---- ---- ---- ---- --x- DSP side DMA in stand-by ---- ---- ---- ---- ---- ---- ---- ---x DSP side DMA in operation **********************************************************************************/ /* DMA TODO: -Remove CD transfer DMA hack (tied with CD block bug(s)?) -Add timings(but how fast are each DMA?). -Add level priority & DMA status register. */ #define DIRECT_MODE(_lv_) (!(state->m_scu_regs[5+(_lv_*8)] & 0x01000000)) #define INDIRECT_MODE(_lv_) (state->m_scu_regs[5+(_lv_*8)] & 0x01000000) #define DRUP(_lv_) (state->m_scu_regs[5+(_lv_*8)] & 0x00010000) #define DWUP(_lv_) (state->m_scu_regs[5+(_lv_*8)] & 0x00000100) #define DMA_STATUS (state->m_scu_regs[31]) /*These macros sets the various DMA status flags.*/ #define DnMV_1(_ch_) DMA_STATUS|=(0x10 << 4 * _ch_) #define DnMV_0(_ch_) DMA_STATUS&=~(0x10 << 4 * _ch_) /*For area checking*/ #define BIOS_BUS(var) (var & 0x07000000) == 0 #define ABUS(_lv_) ((state->m_scu.src[_lv_] & 0x07000000) >= 0x02000000) && ((state->m_scu.src[_lv_] & 0x07000000) <= 0x04000000) #define BBUS(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05a00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05ffffff) #define VDP1_REGS(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05d00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05dfffff) #define VDP2(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05e00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05fdffff) #define WORK_RAM_L(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x00200000) && ((scu_##_lv_ & 0x07ffffff) <= 0x002fffff) #define WORK_RAM_H(var) (var & 0x07000000) == 0x06000000 #define SOUND_RAM(_lv_) ((scu_##_lv_ & 0x07ffffff) >= 0x05a00000) && ((scu_##_lv_ & 0x07ffffff) <= 0x05afffff) static void scu_do_transfer(running_machine &machine,UINT8 event) { saturn_state *state = machine.driver_data(); address_space *space = machine.device("maincpu")->memory().space(AS_PROGRAM); int i; for(i=0;i<3;i++) { if(state->m_scu.enable_mask[i] && state->m_scu.start_factor[i] == event) { if(DIRECT_MODE(i)) { scu_dma_direct(space,i); } else { scu_dma_indirect(space,i); } } } } /* test pending irqs */ static void scu_test_pending_irq(running_machine &machine) { saturn_state *state = machine.driver_data(); int i; const int irq_level[32] = { 0xf, 0xe, 0xd, 0xc, 0xb, 0xa, 0x9, 0x8, 0x8, 0x6, 0x6, 0x5, 0x3, 0x2, -1, -1, 0x7, 0x7, 0x7, 0x7, 0x4, 0x4, 0x4, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1 }; for(i=0;i<32;i++) { if((!(state->m_scu.ism & 1 << i)) && (state->m_scu.ist & 1 << i)) { if(irq_level[i] != -1) /* TODO: cheap check for undefined irqs */ { device_set_input_line_and_vector(state->m_maincpu, irq_level[i], HOLD_LINE, 0x40 + i); state->m_scu.ist &= ~(1 << i); return; /* avoid spurious irqs, correct? */ } } } } static READ32_HANDLER( saturn_scu_r ) { saturn_state *state = space->machine().driver_data(); UINT32 res; /*TODO: write only registers must return 0 or open bus */ switch(offset) { case 0x5c/4: // Super Major League and Shin Megami Tensei - Akuma Zensho reads from there (undocumented), DMA status mirror? if(LOG_SCU) logerror("(PC=%08x) DMA status reg read\n",cpu_get_pc(&space->device())); res = state->m_scu_regs[0x7c/4]; break; case 0x7c/4: if(LOG_SCU) logerror("(PC=%08x) DMA status reg read\n",cpu_get_pc(&space->device())); res = state->m_scu_regs[offset]; break; case 0x80/4: res = dsp_prg_ctrl_r(space); break; case 0x8c/4: if(LOG_SCU) logerror( "DSP mem read at %08X\n", state->m_scu_regs[34]); res = dsp_ram_addr_r(); break; case 0xa0/4: if(LOG_SCU) logerror("(PC=%08x) IRQ mask reg read %08x MASK=%08x\n",cpu_get_pc(&space->device()),mem_mask,state->m_scu_regs[0xa0/4]); res = state->m_scu.ism; break; case 0xa4/4: if(LOG_SCU) logerror("(PC=%08x) IRQ status reg read %08x MASK=%08x\n",cpu_get_pc(&space->device()),mem_mask,state->m_scu_regs[0xa0/4]); res = state->m_scu.ist; break; case 0xc8/4: logerror("(PC=%08x) SCU version reg read\n",cpu_get_pc(&space->device())); res = 0x00000004;/*SCU Version 4, OK? */ break; default: if(LOG_SCU) logerror("(PC=%08x) SCU reg read at %d = %08x\n",cpu_get_pc(&space->device()),offset,state->m_scu_regs[offset]); res = state->m_scu_regs[offset]; break; } return res; } #define DMA_CH ((offset & 0x18) / 8) static WRITE32_HANDLER( saturn_scu_w ) { saturn_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_scu_regs[offset]); switch(offset) { /*LV 0 DMA*/ case 0x00/4: case 0x20/4: case 0x40/4: state->m_scu.src[DMA_CH] = ((state->m_scu_regs[offset] & 0x07ffffff) >> 0); break; case 0x04/4: case 0x24/4: case 0x44/4: state->m_scu.dst[DMA_CH] = ((state->m_scu_regs[offset] & 0x07ffffff) >> 0); break; case 0x08/4: case 0x28/4: case 0x48/4: state->m_scu.size[DMA_CH] = ((state->m_scu_regs[offset] & ((offset == 2) ? 0x000fffff : 0xfff)) >> 0); break; case 0x0c/4: case 0x2c/4: case 0x4c/4: state->m_scu.src_add[DMA_CH] = (state->m_scu_regs[offset] & 0x100) ? 4 : 0; state->m_scu.dst_add[DMA_CH] = 1 << (state->m_scu_regs[offset] & 7); if(state->m_scu.dst_add[DMA_CH] == 1) { state->m_scu.dst_add[DMA_CH] = 0; } break; case 0x10/4: case 0x30/4: case 0x50/4: state->m_scu.enable_mask[DMA_CH] = (data & 0x100) >> 8; if(state->m_scu.enable_mask[DMA_CH] && state->m_scu.start_factor[DMA_CH] == 7 && state->m_scu_regs[offset] & 1) { if(DIRECT_MODE(DMA_CH)) { scu_dma_direct(space,DMA_CH); } else { scu_dma_indirect(space,DMA_CH); } state->m_scu_regs[offset]&=~1;//disable starting bit. } break; case 0x14/4: case 0x34/4: case 0x54/4: if(INDIRECT_MODE(DMA_CH)) { //if(LOG_SCU) logerror("Indirect Mode DMA lv %d set\n",DMA_CH); if(!DWUP(DMA_CH)) state->m_scu.index[DMA_CH] = state->m_scu.dst[DMA_CH]; } state->m_scu.start_factor[DMA_CH] = state->m_scu_regs[offset] & 7; break; case 0x60/4: if(LOG_SCU) logerror("DMA Forced Stop Register set = %02x\n",state->m_scu_regs[24]); break; case 0x7c/4: if(LOG_SCU) logerror("Warning: DMA status WRITE! Offset %02x(%d)\n",offset*4,offset); break; /*DSP section*/ case 0x80/4: /* TODO: you can't overwrite some flags with this */ dsp_prg_ctrl_w(space, state->m_scu_regs[offset]); if(LOG_SCU) logerror("SCU DSP: Program Control Port Access %08x\n",data); break; case 0x84/4: dsp_prg_data(state->m_scu_regs[offset]); if(LOG_SCU) logerror("SCU DSP: Program RAM Data Port Access %08x\n",data); break; case 0x88/4: dsp_ram_addr_ctrl(state->m_scu_regs[offset]); if(LOG_SCU) logerror("SCU DSP: Data RAM Address Port Access %08x\n",data); break; case 0x8c/4: dsp_ram_addr_w(state->m_scu_regs[offset]); if(LOG_SCU) logerror("SCU DSP: Data RAM Data Port Access %08x\n",data); break; case 0x90/4: /*if(LOG_SCU) logerror("timer 0 compare data = %03x\n",state->m_scu_regs[36]);*/ break; case 0x94/4: /*if(LOG_SCU) logerror("timer 1 set data = %08x\n",state->m_scu_regs[37]);*/ break; case 0x98/4: /*if(LOG_SCU) logerror("timer 1 mode data = %08x\n",state->m_scu_regs[38]);*/ break; case 0xa0/4: /* IRQ mask */ state->m_scu.ism = state->m_scu_regs[0xa0/4]; scu_test_pending_irq(space->machine()); break; case 0xa4/4: /* IRQ control */ if(LOG_SCU) logerror("PC=%08x IRQ status reg set:%08x %08x\n",cpu_get_pc(&space->device()),state->m_scu_regs[41],mem_mask); state->m_scu.ist &= state->m_scu_regs[offset]; break; case 0xa8/4: if(LOG_SCU) logerror("A-Bus IRQ ACK %08x\n",state->m_scu_regs[42]); break; case 0xc4/4: if(LOG_SCU) logerror("SCU SDRAM set: %02x\n",state->m_scu_regs[49]); break; default: if(LOG_SCU) logerror("Warning: unused SCU reg set %d = %08x\n",offset,data); } } /*Lv 0 DMA end irq*/ static TIMER_CALLBACK( dma_lv0_ended ) { saturn_state *state = machine.driver_data(); if(!(state->m_scu.ism & IRQ_DMALV0)) device_set_input_line_and_vector(state->m_maincpu, 5, HOLD_LINE, 0x4b); else state->m_scu.ist |= (IRQ_DMALV0); DnMV_0(0); } /*Lv 1 DMA end irq*/ static TIMER_CALLBACK( dma_lv1_ended ) { saturn_state *state = machine.driver_data(); if(!(state->m_scu.ism & IRQ_DMALV1)) device_set_input_line_and_vector(state->m_maincpu, 6, HOLD_LINE, 0x4a); else state->m_scu.ist |= (IRQ_DMALV1); DnMV_0(1); } /*Lv 2 DMA end irq*/ static TIMER_CALLBACK( dma_lv2_ended ) { saturn_state *state = machine.driver_data(); if(!(state->m_scu.ism & IRQ_DMALV2)) device_set_input_line_and_vector(state->m_maincpu, 6, HOLD_LINE, 0x49); else state->m_scu.ist |= (IRQ_DMALV2); DnMV_0(2); } static void scu_single_transfer(address_space *space, UINT32 src, UINT32 dst,UINT8 *src_shift) { UINT32 src_data; if(src & 1) { /* Road Blaster does a work ram h to color ram with offsetted source address, do some data rotation */ src_data = ((space->read_dword(src & 0x07fffffc) & 0x00ffffff)<<8); src_data |= ((space->read_dword((src & 0x07fffffc)+4) & 0xff000000) >> 24); src_data >>= (*src_shift)*16; } else src_data = space->read_dword(src & 0x07fffffc) >> (*src_shift)*16; space->write_word(dst,src_data); *src_shift ^= 1; } static void scu_dma_direct(address_space *space, UINT8 dma_ch) { saturn_state *state = space->machine().driver_data(); UINT32 tmp_src,tmp_dst,tmp_size; UINT8 cd_transfer_flag; if(state->m_scu.src_add[dma_ch] == 0 || (state->m_scu.dst_add[dma_ch] != 2 && state->m_scu.dst_add[dma_ch] != 4)) { if(LOG_SCU) printf("DMA lv %d transfer START\n" "Start %08x End %08x Size %04x\n",dma_ch,state->m_scu.src[dma_ch],state->m_scu.dst[dma_ch],state->m_scu.size[dma_ch]); if(LOG_SCU) printf("Start Add %04x Destination Add %04x\n",state->m_scu.src_add[dma_ch],state->m_scu.dst_add[dma_ch]); } /* TODO: Game Basic trips this, bogus transfer from BIOS area to VDP1? */ if(BIOS_BUS(state->m_scu.src[dma_ch])) popmessage("Warning: SCU transfer from BIOS area, contact MAMEdev"); DnMV_1(dma_ch); /* max size */ if(state->m_scu.size[dma_ch] == 0) { state->m_scu.size[dma_ch] = (dma_ch == 0) ? 0x00100000 : 0x1000; } tmp_src = tmp_dst = 0; tmp_size = state->m_scu.size[dma_ch]; if(!(DRUP(dma_ch))) tmp_src = state->m_scu.src[dma_ch]; if(!(DWUP(dma_ch))) tmp_dst = state->m_scu.dst[dma_ch]; cd_transfer_flag = state->m_scu.src_add[dma_ch] == 0 && state->m_scu.src[dma_ch] == 0x05818000; /* TODO: Many games directly accesses CD-ROM register 0x05818000, it must be a dword access with current implementation otherwise it won't work */ if(cd_transfer_flag) { int i; if(WORK_RAM_H(state->m_scu.dst[dma_ch])) state->m_scu.dst_add[dma_ch] = 4; else state->m_scu.dst_add[dma_ch] <<= 1; for (i = 0; i < state->m_scu.size[dma_ch];i+=state->m_scu.dst_add[dma_ch]) { space->write_dword(state->m_scu.dst[dma_ch],space->read_dword(state->m_scu.src[dma_ch])); if(state->m_scu.dst_add[dma_ch] == 8) space->write_dword(state->m_scu.dst[dma_ch]+4,space->read_dword(state->m_scu.src[dma_ch])); state->m_scu.src[dma_ch]+=state->m_scu.src_add[dma_ch]; state->m_scu.dst[dma_ch]+=state->m_scu.dst_add[dma_ch]; } } else { int i; UINT8 src_shift; src_shift = ((state->m_scu.src[dma_ch] & 2) >> 1) ^ 1; for (i = 0; i < state->m_scu.size[dma_ch];i+=2) { scu_single_transfer(space,state->m_scu.src[dma_ch],state->m_scu.dst[dma_ch],&src_shift); if(src_shift) state->m_scu.src[dma_ch]+=state->m_scu.src_add[dma_ch]; /* if target is Work RAM H, the add value is fixed, behaviour confirmed by Final Romance 2, Virtual Mahjong and Burning Rangers */ state->m_scu.dst[dma_ch]+=(WORK_RAM_H(state->m_scu.dst[dma_ch])) ? 2 : state->m_scu.dst_add[dma_ch]; } } state->m_scu.size[dma_ch] = tmp_size; if(!(DRUP(dma_ch))) state->m_scu.src[dma_ch] = tmp_src; if(!(DWUP(dma_ch))) state->m_scu.dst[dma_ch] = tmp_dst; { /*TODO: this is completely wrong HW-wise ... */ switch(dma_ch) { case 0: space->machine().scheduler().timer_set(attotime::from_usec(300), FUNC(dma_lv0_ended)); break; case 1: space->machine().scheduler().timer_set(attotime::from_usec(300), FUNC(dma_lv1_ended)); break; case 2: space->machine().scheduler().timer_set(attotime::from_usec(300), FUNC(dma_lv2_ended)); break; } } } static void scu_dma_indirect(address_space *space,UINT8 dma_ch) { saturn_state *state = space->machine().driver_data(); /*Helper to get out of the cycle*/ UINT8 job_done = 0; /*temporary storage for the transfer data*/ UINT32 tmp_src; UINT32 indirect_src,indirect_dst; INT32 indirect_size; DnMV_1(dma_ch); state->m_scu.index[dma_ch] = state->m_scu.dst[dma_ch]; do{ tmp_src = state->m_scu.index[dma_ch]; indirect_size = space->read_dword(state->m_scu.index[dma_ch]); indirect_src = space->read_dword(state->m_scu.index[dma_ch]+8); indirect_dst = space->read_dword(state->m_scu.index[dma_ch]+4); /*Indirect Mode end factor*/ if(indirect_src & 0x80000000) job_done = 1; if(state->m_scu.src_add[dma_ch] == 0 || (state->m_scu.dst_add[dma_ch] != 2)) { if(LOG_SCU) printf("DMA lv %d indirect mode transfer START\n" "Index %08x Start %08x End %08x Size %04x\n",dma_ch,tmp_src,indirect_src,indirect_dst,indirect_size); if(LOG_SCU) printf("Start Add %04x Destination Add %04x\n",state->m_scu.src_add[dma_ch],state->m_scu.dst_add[dma_ch]); } indirect_src &=0x07ffffff; indirect_dst &=0x07ffffff; indirect_size &= ((dma_ch == 0) ? 0xfffff : 0x3ffff); //TODO: Guardian Heroes sets up a 0x23000 transfer for the FMV? if(indirect_size == 0) { indirect_size = (dma_ch == 0) ? 0x00100000 : 0x2000; } { int i; UINT8 src_shift; src_shift = ((indirect_src & 2) >> 1) ^ 1; for (i = 0; i < indirect_size;i+=2) { scu_single_transfer(space,indirect_src,indirect_dst,&src_shift); if(src_shift) indirect_src+=state->m_scu.src_add[dma_ch]; indirect_dst+= (WORK_RAM_H(indirect_dst)) ? 2 : state->m_scu.dst_add[dma_ch]; } } //if(DRUP(0)) space->write_dword(tmp_src+8,state->m_scu.src[0]|job_done ? 0x80000000 : 0); //if(DWUP(0)) space->write_dword(tmp_src+4,state->m_scu.dst[0]); state->m_scu.index[dma_ch] = tmp_src+0xc; }while(job_done == 0); { /*TODO: this is completely wrong HW-wise ... */ switch(dma_ch) { case 0: space->machine().scheduler().timer_set(attotime::from_usec(300), FUNC(dma_lv0_ended)); break; case 1: space->machine().scheduler().timer_set(attotime::from_usec(300), FUNC(dma_lv1_ended)); break; case 2: space->machine().scheduler().timer_set(attotime::from_usec(300), FUNC(dma_lv2_ended)); break; } } } /**************************************************************************************/ static WRITE16_HANDLER( saturn_soundram_w ) { saturn_state *state = space->machine().driver_data(); //space->machine().scheduler().synchronize(); // force resync COMBINE_DATA(&state->m_sound_ram[offset]); } static READ16_HANDLER( saturn_soundram_r ) { saturn_state *state = space->machine().driver_data(); //space->machine().scheduler().synchronize(); // force resync return state->m_sound_ram[offset]; } /* communication,SLAVE CPU acquires data from the MASTER CPU and triggers an irq. */ static WRITE32_HANDLER( minit_w ) { saturn_state *state = space->machine().driver_data(); //logerror("cpu %s (PC=%08X) MINIT write = %08x\n", space->device().tag(), cpu_get_pc(&space->device()),data); space->machine().scheduler().boost_interleave(state->m_minit_boost_timeslice, attotime::from_usec(state->m_minit_boost)); space->machine().scheduler().trigger(1000); sh2_set_frt_input(state->m_slave, PULSE_LINE); } static WRITE32_HANDLER( sinit_w ) { saturn_state *state = space->machine().driver_data(); //logerror("cpu %s (PC=%08X) SINIT write = %08x\n", space->device().tag(), cpu_get_pc(&space->device()),data); space->machine().scheduler().boost_interleave(state->m_sinit_boost_timeslice, attotime::from_usec(state->m_sinit_boost)); sh2_set_frt_input(state->m_maincpu, PULSE_LINE); } static READ8_HANDLER(saturn_backupram_r) { saturn_state *state = space->machine().driver_data(); if(!(offset & 1)) return 0; // yes, it makes sure the "holes" are there. return state->m_backupram[offset >> 1] & 0xff; } static WRITE8_HANDLER(saturn_backupram_w) { saturn_state *state = space->machine().driver_data(); if(!(offset & 1)) return; state->m_backupram[offset >> 1] = data; } /* TODO: if you change the driver configuration then NVRAM contents gets screwed, needs mods in MAME framework */ static NVRAM_HANDLER(saturn) { saturn_state *state = machine.driver_data(); static const UINT32 BUP_SIZE = 32*1024; static const UINT32 EBUP_SIZE = 0;//0x100000; // TODO: can't support more than 8 Mbit UINT8 backup_file[(BUP_SIZE)+EBUP_SIZE+4]; static const UINT8 init[16] = { 'B', 'a', 'c', 'k', 'U', 'p', 'R', 'a', 'm', ' ', 'F', 'o', 'r', 'm', 'a', 't' }; UINT32 i; if (read_or_write) { for(i=0;im_backupram[i]; #if 0 for(i=0;im_cart_backupram[i]; #endif for(i=0;i<4;i++) backup_file[i+(BUP_SIZE)+EBUP_SIZE] = state->m_smpc.SMEM[i]; file->write(backup_file, (BUP_SIZE)+EBUP_SIZE+4); } else { if (file) { file->read(backup_file, (BUP_SIZE)+EBUP_SIZE+4); for(i=0;im_backupram[i] = backup_file[i]; #if 0 for(i=0;im_cart_backupram[i] = backup_file[i+BUP_SIZE]; #endif for(i=0;i<4;i++) state->m_smpc.SMEM[i] = backup_file[i+BUP_SIZE+EBUP_SIZE]; } else { UINT8 j; memset(state->m_backupram, 0, BUP_SIZE); for (i = 0; i < 4; i++) { for(j=0;j<16;j++) state->m_backupram[i*16+j] = init[j]; } #if 0 memset(state->m_cart_backupram, 0, EBUP_SIZE); for (i = 0; i < 32; i++) { for(j=0;j<16;j++) state->m_cart_backupram[i*16+j] = init[j]; } #endif memset(state->m_smpc.SMEM, 0, 4); // TODO: default for each region } } } static READ8_HANDLER( saturn_cart_type_r ) { saturn_state *state = space->machine().driver_data(); const int cart_ram_header[7] = { 0xff, 0x21, 0x22, 0x23, 0x24, 0x5a, 0x5c }; return cart_ram_header[state->m_cart_type]; } static ADDRESS_MAP_START( saturn_mem, AS_PROGRAM, 32 ) AM_RANGE(0x00000000, 0x0007ffff) AM_ROM AM_SHARE("share6") // bios AM_RANGE(0x00100000, 0x0010007f) AM_READWRITE8(saturn_SMPC_r, saturn_SMPC_w,0xffffffff) AM_RANGE(0x00180000, 0x0018ffff) AM_READWRITE8(saturn_backupram_r, saturn_backupram_w,0xffffffff) AM_SHARE("share1") AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_MIRROR(0x20100000) AM_SHARE("share2") AM_BASE_MEMBER(saturn_state,m_workram_l) AM_RANGE(0x01000000, 0x017fffff) AM_WRITE(minit_w) AM_RANGE(0x01800000, 0x01ffffff) AM_WRITE(sinit_w) AM_RANGE(0x02000000, 0x023fffff) AM_ROM AM_SHARE("share7") AM_REGION("maincpu", 0x80000) // cartridge space // AM_RANGE(0x02400000, 0x027fffff) AM_RAM //cart RAM area, dynamically allocated // AM_RANGE(0x04000000, 0x047fffff) AM_RAM //backup RAM area, dynamically allocated AM_RANGE(0x04fffffc, 0x04ffffff) AM_READ8(saturn_cart_type_r,0x000000ff) AM_RANGE(0x05800000, 0x0589ffff) AM_READWRITE(stvcd_r, stvcd_w) /* Sound */ AM_RANGE(0x05a00000, 0x05a7ffff) AM_READWRITE16(saturn_soundram_r, saturn_soundram_w,0xffffffff) AM_RANGE(0x05b00000, 0x05b00fff) AM_DEVREADWRITE16("scsp", scsp_r, scsp_w, 0xffffffff) /* VDP1 */ AM_RANGE(0x05c00000, 0x05c7ffff) AM_READWRITE(saturn_vdp1_vram_r, saturn_vdp1_vram_w) AM_RANGE(0x05c80000, 0x05cbffff) AM_READWRITE(saturn_vdp1_framebuffer0_r, saturn_vdp1_framebuffer0_w) AM_RANGE(0x05d00000, 0x05d0001f) AM_READWRITE16(saturn_vdp1_regs_r, saturn_vdp1_regs_w,0xffffffff) AM_RANGE(0x05e00000, 0x05efffff) AM_READWRITE(saturn_vdp2_vram_r, saturn_vdp2_vram_w) AM_RANGE(0x05f00000, 0x05f7ffff) AM_READWRITE(saturn_vdp2_cram_r, saturn_vdp2_cram_w) AM_RANGE(0x05f80000, 0x05fbffff) AM_READWRITE16(saturn_vdp2_regs_r, saturn_vdp2_regs_w,0xffffffff) AM_RANGE(0x05fe0000, 0x05fe00cf) AM_READWRITE(saturn_scu_r, saturn_scu_w) AM_RANGE(0x06000000, 0x060fffff) AM_RAM AM_MIRROR(0x21f00000) AM_SHARE("share3") AM_BASE_MEMBER(saturn_state,m_workram_h) AM_RANGE(0x20000000, 0x2007ffff) AM_ROM AM_SHARE("share6") // bios mirror AM_RANGE(0x22000000, 0x24ffffff) AM_ROM AM_SHARE("share7") // cart mirror AM_RANGE(0x45000000, 0x46ffffff) AM_WRITENOP AM_RANGE(0xc0000000, 0xc00007ff) AM_RAM // cache RAM, Dragon Ball Z sprites needs this ADDRESS_MAP_END static ADDRESS_MAP_START( stv_mem, AS_PROGRAM, 32 ) AM_RANGE(0x00000000, 0x0007ffff) AM_ROM AM_SHARE("share6") // bios AM_RANGE(0x00100000, 0x0010007f) AM_READWRITE8(stv_SMPC_r, stv_SMPC_w,0xffffffff) AM_RANGE(0x00180000, 0x0018ffff) AM_READWRITE8(saturn_backupram_r,saturn_backupram_w,0xffffffff) AM_SHARE("share1") AM_RANGE(0x00200000, 0x002fffff) AM_RAM AM_MIRROR(0x20100000) AM_SHARE("share2") AM_BASE_MEMBER(saturn_state,m_workram_l) // AM_RANGE(0x00400000, 0x0040001f) AM_READWRITE(stv_ioga_r32, stv_io_w32) AM_BASE_MEMBER(saturn_state,m_ioga) AM_SHARE("share4") AM_MIRROR(0x20) /* installed with per-game specific */ AM_RANGE(0x01000000, 0x017fffff) AM_WRITE(minit_w) AM_RANGE(0x01800000, 0x01ffffff) AM_WRITE(sinit_w) AM_RANGE(0x02000000, 0x04ffffff) AM_ROM AM_SHARE("share7") AM_REGION("abus", 0) // cartridge AM_RANGE(0x05800000, 0x0589ffff) AM_READWRITE(stvcd_r, stvcd_w) /* Sound */ AM_RANGE(0x05a00000, 0x05afffff) AM_READWRITE16(saturn_soundram_r, saturn_soundram_w,0xffffffff) AM_RANGE(0x05b00000, 0x05b00fff) AM_DEVREADWRITE16("scsp", scsp_r, scsp_w, 0xffffffff) /* VDP1 */ AM_RANGE(0x05c00000, 0x05c7ffff) AM_READWRITE(saturn_vdp1_vram_r, saturn_vdp1_vram_w) AM_RANGE(0x05c80000, 0x05cbffff) AM_READWRITE(saturn_vdp1_framebuffer0_r, saturn_vdp1_framebuffer0_w) AM_RANGE(0x05d00000, 0x05d0001f) AM_READWRITE16(saturn_vdp1_regs_r, saturn_vdp1_regs_w,0xffffffff) AM_RANGE(0x05e00000, 0x05efffff) AM_READWRITE(saturn_vdp2_vram_r, saturn_vdp2_vram_w) AM_RANGE(0x05f00000, 0x05f7ffff) AM_READWRITE(saturn_vdp2_cram_r, saturn_vdp2_cram_w) AM_RANGE(0x05f80000, 0x05fbffff) AM_READWRITE16(saturn_vdp2_regs_r, saturn_vdp2_regs_w,0xffffffff) AM_RANGE(0x05fe0000, 0x05fe00cf) AM_READWRITE(saturn_scu_r, saturn_scu_w) AM_RANGE(0x06000000, 0x060fffff) AM_RAM AM_MIRROR(0x21f00000) AM_SHARE("share3") AM_BASE_MEMBER(saturn_state,m_workram_h) AM_RANGE(0x20000000, 0x2007ffff) AM_ROM AM_SHARE("share6") // bios mirror AM_RANGE(0x22000000, 0x24ffffff) AM_ROM AM_SHARE("share7") // cart mirror AM_RANGE(0xc0000000, 0xc00007ff) AM_RAM // cache RAM ADDRESS_MAP_END static ADDRESS_MAP_START( sound_mem, AS_PROGRAM, 16 ) AM_RANGE(0x000000, 0x0fffff) AM_RAM AM_BASE_MEMBER(saturn_state,m_sound_ram) AM_RANGE(0x100000, 0x100fff) AM_DEVREADWRITE("scsp", scsp_r, scsp_w) ADDRESS_MAP_END /* keyboard code */ /* TODO: needs a proper keycode table */ static INPUT_CHANGED( key_stroke ) { saturn_state *state = field.machine().driver_data(); if(newval && !oldval) { state->m_keyb.data = ((UINT8)(FPTR)(param) & 0xff); state->m_keyb.status |= 8; } if(oldval && !newval) { //state->m_keyb.status &= ~8; state->m_keyb.data = 0; } } #define SATURN_PAD_P1(_mask_, _val_) \ PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 A") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P1 C") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 B") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P1 R") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P1 X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P1 Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P1 Z") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("P1 L") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0007, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) //read '1' when direct mode is polled #define SATURN_PAD_P2(_mask_, _val_) \ PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P2 A") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P2 C") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P2 B") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P2 R") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P2 X") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P2 Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P2 Z") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0008, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_NAME("P2 L") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0007, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) //read '1' when direct mode is polled #define MD_PAD_P1(_mask_, _val_) \ PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P1 A") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P1 C") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P1 B") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P1 Mode") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P1 X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P1 Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P1 Z") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x000f, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) //read '1' when direct mode is polled #define MD_PAD_P2(_mask_, _val_) \ PORT_BIT( 0x8000, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x4000, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x2000, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x1000, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0800, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0400, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("P2 A") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0200, IP_ACTIVE_LOW, IPT_BUTTON3 ) PORT_NAME("P2 C") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0100, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_NAME("P2 B") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0080, IP_ACTIVE_LOW, IPT_BUTTON8 ) PORT_NAME("P2 Mode") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0040, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_NAME("P2 X") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0020, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_NAME("P2 Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x0010, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_NAME("P2 Z") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) \ PORT_BIT( 0x000f, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("INPUT_TYPE", _mask_, PORTCOND_EQUALS, _val_) //read '1' when direct mode is polled #define SATURN_KEYBOARD PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x05) static INPUT_CHANGED( nmi_reset ) { saturn_state *state = field.machine().driver_data(); /* TODO: correct? */ if(!state->m_NMI_reset) return; /* TODO: NMI doesn't stay held on SH-2 core so we can't use ASSERT_LINE/CLEAR_LINE with that yet */ if(newval) device_set_input_line(state->m_maincpu, INPUT_LINE_NMI, PULSE_LINE); } static INPUT_CHANGED( tray_open ) { if(newval) stvcd_set_tray_open(field.machine()); } static INPUT_CHANGED( tray_close ) { if(newval) stvcd_set_tray_close(field.machine()); } static INPUT_PORTS_START( saturn ) PORT_START("RESET") /* hardwired buttons */ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED(nmi_reset,0) PORT_NAME("Reset Button") PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED(tray_open,0) PORT_NAME("Tray Open Button") PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_OTHER ) PORT_CHANGED(tray_close,0) PORT_NAME("Tray Close") PORT_START("JOY1") SATURN_PAD_P1(0x0f, 0) PORT_START("JOY2") SATURN_PAD_P2(0xf0, 0) /* TODO: there's no info about the keycode used on Saturn keyboard, following is trial & error with Game Basic software */ PORT_START("KEY0") // 0x00 - 0x07 PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_UNUSED) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F1") /*PORT_CODE(KEYCODE_F1)*/ PORT_CHANGED(key_stroke, 0x01) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED(key_stroke, 0x02) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F2") /*PORT_CODE(KEYCODE_F2)*/ PORT_CHANGED(key_stroke, 0x03) PORT_PLAYER(1) SATURN_KEYBOARD // RUN PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F3") /*PORT_CODE(KEYCODE_F3)*/ PORT_CHANGED(key_stroke, 0x04) PORT_PLAYER(1) SATURN_KEYBOARD // LIST PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F4") /*PORT_CODE(KEYCODE_F4)*/ PORT_CHANGED(key_stroke, 0x05) PORT_PLAYER(1) SATURN_KEYBOARD // EDIT PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F5") /*PORT_CODE(KEYCODE_F5)*/ PORT_CHANGED(key_stroke, 0x06) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("CLR SCR") PORT_CHANGED(key_stroke, 0x07) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEY1") // 0x08 - 0x0f PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x08) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F6") /*PORT_CODE(KEYCODE_F6)*/ PORT_CHANGED(key_stroke, 0x09) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F7") /*PORT_CODE(KEYCODE_F7)*/ PORT_CHANGED(key_stroke, 0x0a) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F8") /*PORT_CODE(KEYCODE_F8)*/ PORT_CHANGED(key_stroke, 0x0b) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F9") /*PORT_CODE(KEYCODE_F9)*/ PORT_CHANGED(key_stroke, 0x0c) PORT_PLAYER(1) SATURN_KEYBOARD // LIST again PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR('5')*/ PORT_CHANGED(key_stroke, 0x0d) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED(key_stroke, 0x0e) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x0f) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEY2") // 0x10 - 0x17 PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x10) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x11) PORT_PLAYER(1) SATURN_KEYBOARD /* TODO: break codes! */ PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("SHIFT") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED(key_stroke, 0x12) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("KANA SHIFT") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED(key_stroke, 0x13) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("(special keys)") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED(key_stroke, 0x14) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Q") PORT_CODE(KEYCODE_Q) PORT_CHAR('Q') PORT_CHANGED(key_stroke, 0x15) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("1") PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHANGED(key_stroke, 0x16) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x17) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEY3") // 0x18 - 0x1f PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x18) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x19) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Z") PORT_CODE(KEYCODE_Z) PORT_CHAR('Z') PORT_CHANGED(key_stroke, 0x1a) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("S") PORT_CODE(KEYCODE_S) PORT_CHAR('S') PORT_CHANGED(key_stroke, 0x1b) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A") PORT_CODE(KEYCODE_A) PORT_CHAR('A') PORT_CHANGED(key_stroke, 0x1c) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("W") PORT_CODE(KEYCODE_W) PORT_CHAR('W') PORT_CHANGED(key_stroke, 0x1d) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("2") PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHANGED(key_stroke, 0x1e) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x1f) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEY4") // 0x20 - 0x27 PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x20) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C") PORT_CODE(KEYCODE_C) PORT_CHAR('C') PORT_CHANGED(key_stroke, 0x21) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("X") PORT_CODE(KEYCODE_X) PORT_CHAR('X') PORT_CHANGED(key_stroke, 0x22) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D") PORT_CODE(KEYCODE_D) PORT_CHAR('D') PORT_CHANGED(key_stroke, 0x23) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E") PORT_CODE(KEYCODE_E) PORT_CHAR('E') PORT_CHANGED(key_stroke, 0x24) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4") PORT_CODE(KEYCODE_4) PORT_CHAR('4') PORT_CHANGED(key_stroke, 0x25) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("3") PORT_CODE(KEYCODE_3) PORT_CHAR('3') PORT_CHANGED(key_stroke, 0x26) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("4-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x27) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEY5") // 0x28 - 0x2f PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5-1") /*PORT_CODE(KEYCODE_F) PORT_CHAR('F')*/ PORT_CHANGED(key_stroke, 0x28) PORT_PLAYER(1) SATURN_KEYBOARD // another F? PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("SPACE") PORT_CODE(KEYCODE_SPACE) PORT_CHAR(' ') PORT_CHANGED(key_stroke, 0x29) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("V") PORT_CODE(KEYCODE_V) PORT_CHAR('V') PORT_CHANGED(key_stroke, 0x2a) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F") PORT_CODE(KEYCODE_F) PORT_CHAR('F') PORT_CHANGED(key_stroke, 0x2b) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("T") PORT_CODE(KEYCODE_T) PORT_CHAR('T') PORT_CHANGED(key_stroke, 0x2c) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("R") PORT_CODE(KEYCODE_R) PORT_CHAR('R') PORT_CHANGED(key_stroke, 0x2d) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5") PORT_CODE(KEYCODE_5) PORT_CHAR('5') PORT_CHANGED(key_stroke, 0x2e) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("5-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x2f) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEY6") // 0x30 - 0x37 PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x30) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("N") PORT_CODE(KEYCODE_N) PORT_CHAR('N') PORT_CHANGED(key_stroke, 0x31) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B") PORT_CODE(KEYCODE_B) PORT_CHAR('B') PORT_CHANGED(key_stroke, 0x32) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("H") PORT_CODE(KEYCODE_H) PORT_CHAR('H') PORT_CHANGED(key_stroke, 0x33) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("G") PORT_CODE(KEYCODE_G) PORT_CHAR('G') PORT_CHANGED(key_stroke, 0x34) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("Y") PORT_CODE(KEYCODE_Y) PORT_CHAR('Y') PORT_CHANGED(key_stroke, 0x35) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6") PORT_CODE(KEYCODE_6) PORT_CHAR('6') PORT_CHANGED(key_stroke, 0x36) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("6-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x37) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEY7") // 0x38 - 0x3f PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x38) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x39) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("M") PORT_CODE(KEYCODE_M) PORT_CHAR('M') PORT_CHANGED(key_stroke, 0x3a) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("J") PORT_CODE(KEYCODE_J) PORT_CHAR('J') PORT_CHANGED(key_stroke, 0x3b) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("U") PORT_CODE(KEYCODE_U) PORT_CHAR('U') PORT_CHANGED(key_stroke, 0x3c) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7") PORT_CODE(KEYCODE_7) PORT_CHAR('7') PORT_CHANGED(key_stroke, 0x3d) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8") PORT_CODE(KEYCODE_8) PORT_CHAR('8') PORT_CHANGED(key_stroke, 0x3e) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("7-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x3f) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEY8") // 0x40 - 0x47 PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x40) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(",") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x41) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("K") PORT_CODE(KEYCODE_K) PORT_CHAR('K') PORT_CHANGED(key_stroke, 0x42) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("I") PORT_CODE(KEYCODE_I) PORT_CHAR('I') PORT_CHANGED(key_stroke, 0x43) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("O") PORT_CODE(KEYCODE_O) PORT_CHAR('O') PORT_CHANGED(key_stroke, 0x44) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("0") PORT_CODE(KEYCODE_0) PORT_CHAR('0') PORT_CHANGED(key_stroke, 0x45) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9") PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHANGED(key_stroke, 0x46) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("8-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x47) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEY9") // 0x48 - 0x4f PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x48) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(".") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x49) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("/") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED(key_stroke, 0x4a) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("L") PORT_CODE(KEYCODE_L) PORT_CHAR('L') PORT_CHANGED(key_stroke, 0x4b) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(";") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED(key_stroke, 0x4c) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("P") PORT_CODE(KEYCODE_P) PORT_CHAR('P') PORT_CHANGED(key_stroke, 0x4d) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("- / =") PORT_CODE(KEYCODE_MINUS) PORT_CHAR('-') PORT_CHANGED(key_stroke, 0x4e) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("9-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x4f) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEYA") // 0x50 - 0x57 PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x50) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("\xC2\xA5") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x51) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME(":") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED(key_stroke, 0x52) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED(key_stroke, 0x53) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("@") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED(key_stroke, 0x54) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("^") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED(key_stroke, 0x55) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED(key_stroke, 0x56) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("A-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x57) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEYB") // 0x58 - 0x5f PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x58) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x59) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("ENTER") PORT_CODE(KEYCODE_ENTER) PORT_CHAR(0x0d) PORT_CHANGED(key_stroke, 0x5a) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("[") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED(key_stroke, 0x5b) PORT_PLAYER(1) SATURN_KEYBOARD // { PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED(key_stroke, 0x5c) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("]") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED(key_stroke, 0x5d) PORT_PLAYER(1) SATURN_KEYBOARD // } PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED(key_stroke, 0x5e) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("B-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x5f) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEYC") // 0x60 - 0x67 PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x60) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x61) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED(key_stroke, 0x62) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED(key_stroke, 0x63) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED(key_stroke, 0x64) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED(key_stroke, 0x65) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("BACKSPACE") PORT_CODE(KEYCODE_BACKSPACE) /* PORT_CHAR('6')*/ PORT_CHANGED(key_stroke, 0x66) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("C-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x67) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEYD") // 0x68 - 0x6f PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x68) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x69) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED(key_stroke, 0x6a) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED(key_stroke, 0x6b) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED(key_stroke, 0x6c) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED(key_stroke, 0x6d) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED(key_stroke, 0x6e) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("D-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x6f) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEYE") // 0x70 - 0x77 PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x70) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x71) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED(key_stroke, 0x72) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED(key_stroke, 0x73) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED(key_stroke, 0x74) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED(key_stroke, 0x75) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED(key_stroke, 0x76) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("E-8") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x77) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("KEYF") // 0x78 - 0x7f PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-1") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x78) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-2") /*PORT_CODE(KEYCODE_1) PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x79) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-3") /*PORT_CODE(KEYCODE_2) PORT_CHAR('2')*/ PORT_CHANGED(key_stroke, 0x7a) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-4") /*PORT_CODE(KEYCODE_3) PORT_CHAR('3')*/ PORT_CHANGED(key_stroke, 0x7b) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x10,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-5") /*PORT_CODE(KEYCODE_4) PORT_CHAR('4')*/ PORT_CHANGED(key_stroke, 0x7c) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x20,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-6") /*PORT_CODE(KEYCODE_5) PORT_CHAR(0xd)*/ PORT_CHANGED(key_stroke, 0x7d) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x40,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("F-7") /*PORT_CODE(KEYCODE_6) PORT_CHAR('6')*/ PORT_CHANGED(key_stroke, 0x7e) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x80,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("ESC") /*PORT_CODE(KEYCODE_7) PORT_CHAR('7')*/ PORT_CHANGED(key_stroke, 0x7f) PORT_PLAYER(1) SATURN_KEYBOARD //SYSTEM CONFIGURATION PORT_START("KEYS_1") // special keys PORT_BIT(0x01,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("UP") PORT_CODE(KEYCODE_UP) /*PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x78) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x02,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("DOWN") PORT_CODE(KEYCODE_DOWN) /*PORT_CHAR('1')*/ PORT_CHANGED(key_stroke, 0x79) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x04,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("LEFT") PORT_CODE(KEYCODE_LEFT) /*PORT_CHAR('2')*/ PORT_CHANGED(key_stroke, 0x7a) PORT_PLAYER(1) SATURN_KEYBOARD PORT_BIT(0x08,IP_ACTIVE_HIGH,IPT_KEYBOARD) PORT_NAME("RIGHT") PORT_CODE(KEYCODE_RIGHT) /*PORT_CHAR('3')*/ PORT_CHANGED(key_stroke, 0x7b) PORT_PLAYER(1) SATURN_KEYBOARD PORT_START("MOUSEB1") PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Pointer Left Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x04) PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Pointer Right Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x04) PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P1 Pointer Middle Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x04) PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P1 Pointer Start Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x04) PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P1 Mouse Left Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x08) PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P1 Mouse Right Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x08) PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P1 Mouse Middle Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x08) PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P1 Mouse Start Button") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x08) PORT_START("MOUSEX1") PORT_BIT(0xffff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_NAME("P1 Pointer X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x04) PORT_BIT(0xffff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_NAME("P1 Mouse X") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x08) PORT_START("MOUSEY1") PORT_BIT(0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_REVERSE PORT_NAME("P1 Pointer Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x04) PORT_BIT(0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_REVERSE PORT_NAME("P1 Mouse Y") PORT_PLAYER(1) PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x08) PORT_START("MOUSEB2") PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 Pointer Left Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x40) PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 Pointer Right Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x40) PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P2 Pointer Middle Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x40) PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P2 Pointer Start Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x40) PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_NAME("P2 Mouse Left Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x80) PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_NAME("P2 Mouse Right Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x80) PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_BUTTON3 ) PORT_NAME("P2 Mouse Middle Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x80) PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_START ) PORT_NAME("P2 Mouse Start Button") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x80) PORT_START("MOUSEX2") PORT_BIT(0xffff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_NAME("P2 Pointer X") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x40) PORT_BIT(0xffff, 0x00, IPT_MOUSE_X) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_NAME("P2 Mouse X") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x80) PORT_START("MOUSEY2") PORT_BIT(0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_REVERSE PORT_NAME("P2 Pointer Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x40) PORT_BIT(0xffff, 0x00, IPT_MOUSE_Y) PORT_SENSITIVITY(100) PORT_MINMAX(0x000, 0xffff) PORT_KEYDELTA(2) PORT_RESET PORT_REVERSE PORT_NAME("P2 Mouse Y") PORT_PLAYER(2) PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x80) PORT_START("AN_JOY1") SATURN_PAD_P1(0x0f, 0x01) // racing device SATURN_PAD_P1(0x0f, 0x02) // analog controller PORT_START("AN_JOY2") SATURN_PAD_P2(0xf0, 0x10) // racing device SATURN_PAD_P2(0xf0, 0x20) // analog controller PORT_START("AN_X1") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 Racing Stick X") PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x01) PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 AD Stick X") PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x02) PORT_START("AN_Y1") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 Racing Stick Y") PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x01) PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 AD Stick Y") PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x02) PORT_START("AN_Z1") PORT_BIT( 0xff, 0x00, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 Racing Stick Z") PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x01) PORT_BIT( 0xff, 0x00, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(1) PORT_NAME("P1 AD Stick Z") PORT_CONDITION("INPUT_TYPE", 0x0f, PORTCOND_EQUALS, 0x02) PORT_START("AN_X2") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 Racing Stick X") PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x10) PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 AD Stick X") PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x20) PORT_START("AN_Y2") PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 Racing Stick Y") PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x10) PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 AD Stick Y") PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x20) PORT_START("AN_Z2") PORT_BIT( 0xff, 0x00, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 Racing Stick Z") PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x10) PORT_BIT( 0xff, 0x00, IPT_AD_STICK_Z ) PORT_MINMAX(0x00, 0xff) PORT_SENSITIVITY(25) PORT_KEYDELTA(200) PORT_PLAYER(2) PORT_NAME("P2 AD Stick Z") PORT_CONDITION("INPUT_TYPE", 0xf0, PORTCOND_EQUALS, 0x20) PORT_START("MD_JOY1") MD_PAD_P1(0x0f, 0x06) // MD 3 buttons pad MD_PAD_P1(0x0f, 0x07) // MD 6 buttons pad PORT_START("MD_JOY2") MD_PAD_P2(0xf0, 0x60) // MD 3 buttons pad MD_PAD_P2(0xf0, 0x70) // MD 6 buttons pad PORT_START("CART_AREA") PORT_CONFNAME( 0x07, 0x06, "Cart Type" ) PORT_CONFSETTING( 0x00, "None" ) // PORT_CONFSETTING( 0x01, "4 Mbit backup RAM" ) // PORT_CONFSETTING( 0x02, "8 Mbit backup RAM" ) // PORT_CONFSETTING( 0x03, "16 Mbit backup RAM" ) // PORT_CONFSETTING( 0x04, "32 Mbit backup RAM" ) PORT_CONFSETTING( 0x05, "8 Mbit Cart RAM" ) PORT_CONFSETTING( 0x06, "32 Mbit Cart RAM" ) PORT_START("INPUT_TYPE") PORT_CONFNAME(0x0f,0x00,"Controller Port 1") PORT_CONFSETTING(0x00,"Digital Device (standard Saturn pad)") PORT_CONFSETTING(0x01,"Racing Device") /* steering wheel only */ PORT_CONFSETTING(0x02,"Analog Device") //Nights pad? // PORT_CONFSETTING(0x03,"Lightgun Device") PORT_CONFSETTING(0x04,"Trackball") // TODO: according to the docs this ID is labeled "Pointing Device" PORT_CONFSETTING(0x05,"Keyboard Device") PORT_CONFSETTING(0x06,"Megadrive 3B Pad") PORT_CONFSETTING(0x07,"Megadrive 6B Pad") PORT_CONFSETTING(0x08,"Saturn Mouse") // PORT_CONFSETTING(0x09,"") PORT_CONFNAME(0xf0,0x00,"Controller Port 2") PORT_CONFSETTING(0x00,"Digital Device (standard Saturn pad)") PORT_CONFSETTING(0x10,"Racing Device") PORT_CONFSETTING(0x20,"Analog Device") //Nights pad? // PORT_CONFSETTING(0x30,"Lightgun Device") PORT_CONFSETTING(0x40,"Pointing Device") // PORT_CONFSETTING(0x50,"Keyboard Device") PORT_CONFSETTING(0x60,"Megadrive 3B Pad") PORT_CONFSETTING(0x70,"Megadrive 6B Pad") PORT_CONFSETTING(0x80,"Saturn Mouse") PORT_CONFSETTING(0x90,"") INPUT_PORTS_END #define STV_PLAYER_INPUTS(_n_, _b1_, _b2_, _b3_,_b4_) \ PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_##_b1_ ) PORT_PLAYER(_n_) \ PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_##_b2_ ) PORT_PLAYER(_n_) \ PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_##_b3_ ) PORT_PLAYER(_n_) \ PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_##_b4_ ) PORT_PLAYER(_n_) \ PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(_n_) \ PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(_n_) \ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(_n_) \ PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(_n_) static INPUT_PORTS_START( stv ) PORT_START("DSW1") PORT_DIPNAME( 0x01, 0x01, "PDR1" ) 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_START("DSW2") PORT_DIPNAME( 0x01, 0x01, "PDR2" ) 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_START("PORTA") STV_PLAYER_INPUTS(1, BUTTON1, BUTTON2, BUTTON3, BUTTON4) PORT_START("PORTB") STV_PLAYER_INPUTS(2, BUTTON1, BUTTON2, BUTTON3, BUTTON4) PORT_START("PORTC") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_COIN2 ) PORT_SERVICE_NO_TOGGLE( 0x04, IP_ACTIVE_LOW ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_SERVICE1 ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(2) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("1P Push Switch") PORT_CODE(KEYCODE_7) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_SERVICE ) PORT_NAME("2P Push Switch") PORT_CODE(KEYCODE_8) PORT_START("PORTE") STV_PLAYER_INPUTS(3, BUTTON1, BUTTON2, BUTTON3, START) PORT_START("PORTF") STV_PLAYER_INPUTS(4, BUTTON1, BUTTON2, BUTTON3, START) INPUT_PORTS_END static INPUT_PORTS_START( stv6b ) PORT_INCLUDE( stv ) PORT_MODIFY("PORTA") PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_MODIFY("PORTB") PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_MODIFY("PORTE") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) /* Extra button layout, used by Power Instinct 3, Suikoenbu, Elan Doree, Golden Axe Duel & Astra SuperStars */ PORT_MODIFY("PORTF") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(1) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(1) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(1) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) PORT_PLAYER(2) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON5 ) PORT_PLAYER(2) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_PLAYER(2) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) INPUT_PORTS_END static INPUT_PORTS_START( critcrsh ) PORT_INCLUDE( stv ) PORT_MODIFY("PORTA") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_MODIFY("PORTB") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_MODIFY("PORTC") PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_NAME("Hammer Hit") PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_MODIFY("PORTE") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_MODIFY("PORTF") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("LIGHTX") /* mask default type sens delta min max */ PORT_BIT( 0x3f, 0x00, IPT_LIGHTGUN_X ) PORT_CROSSHAIR(X, 1.0, 0.0, 0) PORT_MINMAX(0,0x3f) PORT_SENSITIVITY(50) PORT_KEYDELTA(1) PORT_PLAYER(1) PORT_START("LIGHTY") PORT_BIT( 0x3f, 0x00, IPT_LIGHTGUN_Y ) PORT_CROSSHAIR(Y, 1.0, 0.0, 0) PORT_MINMAX(0x0,0x3f) PORT_SENSITIVITY(50) PORT_KEYDELTA(1) PORT_PLAYER(1) INPUT_PORTS_END /* Same as the regular one, but with an additional & optional mahjong panel */ static INPUT_PORTS_START( stvmp ) PORT_INCLUDE( stv ) PORT_MODIFY("PORTE") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_MODIFY("PORTF") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) /* Mahjong panel/player 1 side */ PORT_START("P1_KEY0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_KAN ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_E ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_A ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_M ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_MAHJONG_I ) PORT_START("P1_KEY1") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_RON ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_F ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_B ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_N ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_MAHJONG_J ) PORT_START("P1_KEY2") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_REACH ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_G ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_C ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_CHI ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_MAHJONG_K ) PORT_START("P1_KEY3") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_H ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_D ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_PON ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_MAHJONG_L ) PORT_START("P1_KEY4") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_FLIP_FLOP ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) /* Mahjong panel/player 2 side */ PORT_START("P2_KEY0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_KAN ) PORT_PLAYER(2) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START2 ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_E ) PORT_PLAYER(2) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_A ) PORT_PLAYER(2) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_M ) PORT_PLAYER(2) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_MAHJONG_I ) PORT_PLAYER(2) PORT_START("P2_KEY1") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_RON ) PORT_PLAYER(2) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_F ) PORT_PLAYER(2) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_B ) PORT_PLAYER(2) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_N ) PORT_PLAYER(2) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_MAHJONG_J ) PORT_PLAYER(2) PORT_START("P2_KEY2") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_REACH ) PORT_PLAYER(2) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_G ) PORT_PLAYER(2) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_C ) PORT_PLAYER(2) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_CHI ) PORT_PLAYER(2) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_MAHJONG_K ) PORT_PLAYER(2) PORT_START("P2_KEY3") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_H ) PORT_PLAYER(2) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_D ) PORT_PLAYER(2) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_PON ) PORT_PLAYER(2) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_MAHJONG_L ) PORT_PLAYER(2) PORT_START("P2_KEY4") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_FLIP_FLOP ) PORT_PLAYER(2) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNUSED ) INPUT_PORTS_END /* Micronet layout, routes joystick port to the mux! */ static INPUT_PORTS_START( myfairld ) PORT_INCLUDE( stv ) PORT_MODIFY("PORTA") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_MODIFY("PORTB") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_MODIFY("PORTC") PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_START ) PORT_PLAYER(1) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x01) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_MODIFY("PORTE") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_MODIFY("PORTF") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("P1_KEY0") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_KAN ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_START1 ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_E ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_A ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_M ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_MAHJONG_I ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x01) PORT_START("P1_KEY1") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_REACH ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_MAHJONG_BET ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_F ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_B ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_N ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_MAHJONG_J ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x01) PORT_START("P1_KEY2") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_MAHJONG_RON ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_G ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_C ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_CHI ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_MAHJONG_K ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x01) PORT_START("P1_KEY3") PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_MAHJONG_H ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_MAHJONG_D ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_MAHJONG_PON ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_MAHJONG_L ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x00) PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x01) PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x01) PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x01) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x01) PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) PORT_PLAYER(1) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x01) PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) PORT_PLAYER(1) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x01) PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_RIGHT ) PORT_PLAYER(1) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x01) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_LEFT ) PORT_PLAYER(1) PORT_CONDITION("IO_TYPE", 0x01, PORTCOND_EQUALS, 0x01) PORT_START("P1_KEY4") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) /* F/F is there, but these two games are single player so it isn't connected */ PORT_START("P2_KEY0") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("P2_KEY1") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("P2_KEY2") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("P2_KEY3") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("P2_KEY4") PORT_BIT( 0xff, IP_ACTIVE_LOW, IPT_UNUSED ) PORT_START("IO_TYPE") PORT_CONFNAME( 0x01, 0x00, "I/O Device type" ) PORT_CONFSETTING( 0x00, "Mahjong Panel" ) PORT_CONFSETTING( 0x01, "Joystick" ) INPUT_PORTS_END static const gfx_layout tiles8x8x4_layout = { 8,8, 0x100000/(32*8/8), 4, { 0, 1, 2, 3 }, { 0, 4, 8, 12, 16, 20, 24, 28 }, { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32 }, 32*8 }; static const gfx_layout tiles16x16x4_layout = { 16,16, 0x100000/(32*32/8), 4, { 0, 1, 2, 3 }, { 0, 4, 8, 12, 16, 20, 24, 28, 32*8+0, 32*8+4, 32*8+8, 32*8+12, 32*8+16, 32*8+20, 32*8+24, 32*8+28, }, { 0*32, 1*32, 2*32, 3*32, 4*32, 5*32, 6*32, 7*32, 32*16, 32*17,32*18, 32*19,32*20,32*21,32*22,32*23 }, 32*32 }; static const gfx_layout tiles8x8x8_layout = { 8,8, 0x100000/(32*8/8), 8, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 8, 16, 24, 32, 40, 48, 56 }, { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64 }, 32*8 /* really 64*8, but granularity is 32 bytes */ }; static const gfx_layout tiles16x16x8_layout = { 16,16, 0x100000/(64*16/8), 8, { 0, 1, 2, 3, 4, 5, 6, 7 }, { 0, 8, 16, 24, 32, 40, 48, 56, 64*8+0, 65*8, 66*8, 67*8, 68*8, 69*8, 70*8, 71*8 }, { 0*64, 1*64, 2*64, 3*64, 4*64, 5*64, 6*64, 7*64, 64*16, 64*17, 64*18, 64*19, 64*20, 64*21, 64*22, 64*23 }, 64*16 /* really 128*16, but granularity is 32 bytes */ }; static GFXDECODE_START( stv ) GFXDECODE_ENTRY( NULL, 0, tiles8x8x4_layout, 0x00, (0x80*(2+1)) ) GFXDECODE_ENTRY( NULL, 0, tiles16x16x4_layout, 0x00, (0x80*(2+1)) ) GFXDECODE_ENTRY( NULL, 0, tiles8x8x8_layout, 0x00, (0x08*(2+1)) ) GFXDECODE_ENTRY( NULL, 0, tiles16x16x8_layout, 0x00, (0x08*(2+1)) ) /* vdp1 .. pointless for drawing but can help us debug */ GFXDECODE_ENTRY( NULL, 0, tiles8x8x4_layout, 0x00, 0x100 ) GFXDECODE_ENTRY( NULL, 0, tiles16x16x4_layout, 0x00, 0x100 ) GFXDECODE_ENTRY( NULL, 0, tiles8x8x8_layout, 0x00, 0x20 ) GFXDECODE_ENTRY( NULL, 0, tiles16x16x8_layout, 0x00, 0x20 ) GFXDECODE_END static const sh2_cpu_core sh2_conf_master = { 0, NULL }; static const sh2_cpu_core sh2_conf_slave = { 1, NULL }; static int scsp_last_line = 0; static void scsp_irq(device_t *device, int irq) { saturn_state *state = device->machine().driver_data(); // don't bother the 68k if it's off if (!state->m_en_68k) { return; } if (irq > 0) { scsp_last_line = irq; cputag_set_input_line(device->machine(), "audiocpu", irq, ASSERT_LINE); } else if (irq < 0) { cputag_set_input_line(device->machine(), "audiocpu", -irq, CLEAR_LINE); } else { cputag_set_input_line(device->machine(), "audiocpu", scsp_last_line, CLEAR_LINE); } } static WRITE_LINE_DEVICE_HANDLER( scsp_to_main_irq ) { saturn_state *drvstate = device->machine().driver_data(); if(!(drvstate->m_scu.ism & IRQ_SOUND_REQ)) { device_set_input_line_and_vector(drvstate->m_maincpu, 9, HOLD_LINE, 0x46); scu_do_transfer(device->machine(),5); } else drvstate->m_scu.ist |= (IRQ_SOUND_REQ); } static const scsp_interface scsp_config = { 0, scsp_irq, DEVCB_LINE(scsp_to_main_irq) }; static TIMER_CALLBACK(stv_rtc_increment) { saturn_state *state = machine.driver_data(); static const UINT8 dpm[12] = { 0x31, 0x28, 0x31, 0x30, 0x31, 0x30, 0x31, 0x31, 0x30, 0x31, 0x30, 0x31 }; static int year_num, year_count; /* state->m_smpc.rtc_data[0] = DectoBCD(systime.local_time.year /100); state->m_smpc.rtc_data[1] = DectoBCD(systime.local_time.year %100); state->m_smpc.rtc_data[2] = (systime.local_time.weekday << 4) | (systime.local_time.month+1); state->m_smpc.rtc_data[3] = DectoBCD(systime.local_time.mday); state->m_smpc.rtc_data[4] = DectoBCD(systime.local_time.hour); state->m_smpc.rtc_data[5] = DectoBCD(systime.local_time.minute); state->m_smpc.rtc_data[6] = DectoBCD(systime.local_time.second); */ state->m_smpc.rtc_data[6]++; /* seconds from 9 -> 10*/ if((state->m_smpc.rtc_data[6] & 0x0f) >= 0x0a) { state->m_smpc.rtc_data[6]+=0x10; state->m_smpc.rtc_data[6]&=0xf0; } /* seconds from 59 -> 0 */ if((state->m_smpc.rtc_data[6] & 0xf0) >= 0x60) { state->m_smpc.rtc_data[5]++; state->m_smpc.rtc_data[6] = 0; } /* minutes from 9 -> 10 */ if((state->m_smpc.rtc_data[5] & 0x0f) >= 0x0a) { state->m_smpc.rtc_data[5]+=0x10; state->m_smpc.rtc_data[5]&=0xf0; } /* minutes from 59 -> 0 */ if((state->m_smpc.rtc_data[5] & 0xf0) >= 0x60) { state->m_smpc.rtc_data[4]++; state->m_smpc.rtc_data[5] = 0; } /* hours from 9 -> 10 */ if((state->m_smpc.rtc_data[4] & 0x0f) >= 0x0a) { state->m_smpc.rtc_data[4]+=0x10; state->m_smpc.rtc_data[4]&=0xf0; } /* hours from 23 -> 0 */ if((state->m_smpc.rtc_data[4] & 0xff) >= 0x24) { state->m_smpc.rtc_data[3]++; state->m_smpc.rtc_data[2]+=0x10; state->m_smpc.rtc_data[4] = 0; } /* week day name sunday -> monday */ if((state->m_smpc.rtc_data[2] & 0xf0) >= 0x70) { state->m_smpc.rtc_data[2]&=0x0f; } /* day number 9 -> 10 */ if((state->m_smpc.rtc_data[3] & 0x0f) >= 0x0a) { state->m_smpc.rtc_data[3]+=0x10; state->m_smpc.rtc_data[3]&=0xf0; } // year BCD to dec conversion (for the leap year stuff) { year_num = (state->m_smpc.rtc_data[1] & 0xf); for(year_count = 0; year_count < (state->m_smpc.rtc_data[1] & 0xf0); year_count += 0x10) year_num += 0xa; year_num += (state->m_smpc.rtc_data[0] & 0xf)*0x64; for(year_count = 0; year_count < (state->m_smpc.rtc_data[0] & 0xf0); year_count += 0x10) year_num += 0x3e8; } /* month +1 check */ /* the RTC have a range of 1980 - 2100, so we don't actually need to support the leap year special conditions */ if(((year_num % 4) == 0) && (state->m_smpc.rtc_data[2] & 0xf) == 2) { if((state->m_smpc.rtc_data[3] & 0xff) >= dpm[(state->m_smpc.rtc_data[2] & 0xf)-1]+1+1) { state->m_smpc.rtc_data[2]++; state->m_smpc.rtc_data[3] = 0x01; } } else if((state->m_smpc.rtc_data[3] & 0xff) >= dpm[(state->m_smpc.rtc_data[2] & 0xf)-1]+1){ state->m_smpc.rtc_data[2]++; state->m_smpc.rtc_data[3] = 0x01; } /* year +1 check */ if((state->m_smpc.rtc_data[2] & 0x0f) > 12) { state->m_smpc.rtc_data[1]++; state->m_smpc.rtc_data[2] = (state->m_smpc.rtc_data[2] & 0xf0) | 0x01; } /* year from 9 -> 10 */ if((state->m_smpc.rtc_data[1] & 0x0f) >= 0x0a) { state->m_smpc.rtc_data[1]+=0x10; state->m_smpc.rtc_data[1]&=0xf0; } /* year from 99 -> 100 */ if((state->m_smpc.rtc_data[1] & 0xf0) >= 0xa0) { state->m_smpc.rtc_data[0]++; state->m_smpc.rtc_data[1] = 0; } // probably not SO precise, here just for reference ... /* year from 999 -> 1000 */ //if((state->m_smpc.rtc_data[0] & 0x0f) >= 0x0a) { state->m_smpc.rtc_data[0]+=0x10; state->m_smpc.rtc_data[0]&=0xf0; } /* year from 9999 -> 0 */ //if((state->m_smpc.rtc_data[0] & 0xf0) >= 0xa0) { state->m_smpc.rtc_data[0] = 0; } //roll over } static MACHINE_START( stv ) { saturn_state *state = machine.driver_data(); system_time systime; machine.base_datetime(systime); state->m_maincpu = downcast( machine.device("maincpu") ); state->m_slave = downcast( machine.device("slave") ); state->m_audiocpu = downcast( machine.device("audiocpu") ); scsp_set_ram_base(machine.device("scsp"), state->m_sound_ram); // save states state_save_register_global_pointer(machine, state->m_scu_regs, 0x100/4); state_save_register_global_pointer(machine, state->m_scsp_regs, 0x1000/2); state_save_register_global(machine, state->m_NMI_reset); state_save_register_global(machine, state->m_en_68k); // state_save_register_global(machine, scanline); state_save_register_global(machine, state->m_smpc.IOSEL1); state_save_register_global(machine, state->m_smpc.IOSEL2); state_save_register_global(machine, state->m_smpc.EXLE1); state_save_register_global(machine, state->m_smpc.EXLE2); state_save_register_global(machine, state->m_smpc.PDR1); state_save_register_global(machine, state->m_smpc.PDR2); state_save_register_global(machine, state->m_port_sel); state_save_register_global(machine, state->m_mux_data); state_save_register_global(machine, scsp_last_line); stv_register_protection_savestates(machine); // machine/stvprot.c machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(stvcd_exit), &machine)); state->m_smpc.rtc_data[0] = DectoBCD(systime.local_time.year /100); state->m_smpc.rtc_data[1] = DectoBCD(systime.local_time.year %100); state->m_smpc.rtc_data[2] = (systime.local_time.weekday << 4) | (systime.local_time.month+1); state->m_smpc.rtc_data[3] = DectoBCD(systime.local_time.mday); state->m_smpc.rtc_data[4] = DectoBCD(systime.local_time.hour); state->m_smpc.rtc_data[5] = DectoBCD(systime.local_time.minute); state->m_smpc.rtc_data[6] = DectoBCD(systime.local_time.second); state->m_stv_rtc_timer = machine.scheduler().timer_alloc(FUNC(stv_rtc_increment)); } static MACHINE_START( saturn ) { saturn_state *state = machine.driver_data(); system_time systime; machine.base_datetime(systime); state->m_maincpu = downcast( machine.device("maincpu") ); state->m_slave = downcast( machine.device("slave") ); state->m_audiocpu = downcast( machine.device("audiocpu") ); scsp_set_ram_base(machine.device("scsp"), state->m_sound_ram); // save states state_save_register_global_pointer(machine, state->m_scu_regs, 0x100/4); state_save_register_global_pointer(machine, state->m_scsp_regs, 0x1000/2); state_save_register_global(machine, state->m_NMI_reset); state_save_register_global(machine, state->m_en_68k); state_save_register_global(machine, state->m_smpc.IOSEL1); state_save_register_global(machine, state->m_smpc.IOSEL2); state_save_register_global(machine, state->m_smpc.EXLE1); state_save_register_global(machine, state->m_smpc.EXLE2); state_save_register_global(machine, state->m_smpc.PDR1); state_save_register_global(machine, state->m_smpc.PDR2); // state_save_register_global(machine, state->m_port_sel); // state_save_register_global(machine, mux_data); state_save_register_global(machine, scsp_last_line); state_save_register_global(machine, state->m_smpc.intback_stage); state_save_register_global(machine, state->m_smpc.pmode); state_save_register_global(machine, state->m_smpc.SR); state_save_register_global_array(machine, state->m_smpc.SMEM); state_save_register_global_pointer(machine, state->m_cart_dram, 0x400000/4); machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(stvcd_exit), &machine)); state->m_smpc.rtc_data[0] = DectoBCD(systime.local_time.year /100); state->m_smpc.rtc_data[1] = DectoBCD(systime.local_time.year %100); state->m_smpc.rtc_data[2] = (systime.local_time.weekday << 4) | (systime.local_time.month+1); state->m_smpc.rtc_data[3] = DectoBCD(systime.local_time.mday); state->m_smpc.rtc_data[4] = DectoBCD(systime.local_time.hour); state->m_smpc.rtc_data[5] = DectoBCD(systime.local_time.minute); state->m_smpc.rtc_data[6] = DectoBCD(systime.local_time.second); state->m_stv_rtc_timer = machine.scheduler().timer_alloc(FUNC(stv_rtc_increment)); } /* (Preliminary) explanation about this: VBLANK-OUT is used at the start of the vblank period.It also sets the timer zero variable to 0. If the Timer Compare register is zero too,the Timer 0 irq is triggered. HBLANK-IN is used at the end of each scanline except when in VBLANK-IN/OUT periods. The timer 0 is also incremented by one at each HBLANK and checked with the value of the Timer Compare register;if equal,the timer 0 irq is triggered here too. Notice that the timer 0 compare register can be more than the VBLANK maximum range,in this case the timer 0 irq is simply never triggered.This is a known Sega Saturn/ST-V "bug". VBLANK-IN is used at the end of the vblank period. SCU register[36] is the timer zero compare register. SCU register[40] is for IRQ masking. TODO: - VDP1 timing and CEF emulation isn't accurate at all. */ static TIMER_DEVICE_CALLBACK( saturn_scanline ) { saturn_state *state = timer.machine().driver_data(); int scanline = param; int max_y = timer.machine().primary_screen->height(); int y_step,vblank_line; y_step = 2; if((max_y == 263 && state->m_vdp2.pal == 0) || (max_y == 313 && state->m_vdp2.pal == 1)) y_step = 1; vblank_line = (state->m_vdp2.pal) ? 288 : 240; //popmessage("%08x %d T0 %d T1 %d %08x",state->m_scu.ism ^ 0xffffffff,max_y,state->m_scu_regs[36],state->m_scu_regs[37],state->m_scu_regs[38]); if(scanline == (0)*y_step) { video_update_vdp1(timer.machine()); if(STV_VDP1_VBE) state->m_vdp1.framebuffer_clear_on_next_frame = 1; if(!(state->m_scu.ism & IRQ_VDP1_END)) { device_set_input_line_and_vector(state->m_maincpu, 0x2, HOLD_LINE, 0x4d); scu_do_transfer(timer.machine(),6); } else state->m_scu.ist |= (IRQ_VDP1_END); } if(scanline == 0*y_step) { if(!(state->m_scu.ism & IRQ_VBLANK_OUT)) { device_set_input_line_and_vector(state->m_maincpu, 0xe, HOLD_LINE, 0x41); scu_do_transfer(timer.machine(),1); } else state->m_scu.ist |= (IRQ_VBLANK_OUT); } else if(scanline == vblank_line*y_step) { if(!(state->m_scu.ism & IRQ_VBLANK_IN)) { device_set_input_line_and_vector(state->m_maincpu, 0xf, HOLD_LINE ,0x40); scu_do_transfer(timer.machine(),0); } else state->m_scu.ist |= (IRQ_VBLANK_IN); } else if((scanline % y_step) == 0 && scanline < vblank_line*y_step) { if(!(state->m_scu.ism & IRQ_HBLANK_IN)) { device_set_input_line_and_vector(state->m_maincpu, 0xd, HOLD_LINE, 0x42); scu_do_transfer(timer.machine(),2); } else state->m_scu.ist |= (IRQ_HBLANK_IN); } if(scanline == (state->m_scu_regs[36] & 0x3ff)*y_step) { if(!(state->m_scu.ism & IRQ_TIMER_0)) { device_set_input_line_and_vector(state->m_maincpu, 0xc, HOLD_LINE, 0x43 ); scu_do_transfer(timer.machine(),3); } else state->m_scu.ist |= (IRQ_TIMER_0); } /* TODO: this isn't completely correct */ if(state->m_scu_regs[38] & 0x1) { if((!(state->m_scu_regs[38] & 0x100) && (scanline % y_step) == 0) || ((state->m_scu_regs[38] & 0x100) && (scanline == (state->m_scu_regs[36] & 0x3ff)*y_step))) { if(!(state->m_scu.ism & IRQ_TIMER_1)) { device_set_input_line_and_vector(state->m_maincpu, 0xb, HOLD_LINE, 0x44 ); scu_do_transfer(timer.machine(),4); } else state->m_scu.ist |= (IRQ_TIMER_1); } } } static TIMER_DEVICE_CALLBACK( saturn_slave_scanline ) { saturn_state *state = timer.machine().driver_data(); int scanline = param; int max_y = timer.machine().primary_screen->height(); int y_step,vblank_line; y_step = 2; if((max_y == 263 && state->m_vdp2.pal == 0) || (max_y == 313 && state->m_vdp2.pal == 1)) y_step = 1; vblank_line = (state->m_vdp2.pal) ? 288 : 240; if(scanline == vblank_line*y_step) device_set_input_line_and_vector(state->m_slave, 0x6, HOLD_LINE, 0x43); else if((scanline % y_step) == 0 && scanline < vblank_line*y_step) device_set_input_line_and_vector(state->m_slave, 0x2, HOLD_LINE, 0x41); } /* Die Hard Trilogy tests RAM address 0x25e7ffe bit 2 with Slave during FRT minit irq, in-development tool for breaking execution of it? */ static READ32_HANDLER( saturn_null_ram_r ) { return 0xffffffff; } static WRITE32_HANDLER( saturn_null_ram_w ) { } static READ32_HANDLER( saturn_cart_dram0_r ) { saturn_state *state = space->machine().driver_data(); return state->m_cart_dram[offset]; } static WRITE32_HANDLER( saturn_cart_dram0_w ) { saturn_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_cart_dram[offset]); } static READ32_HANDLER( saturn_cart_dram1_r ) { saturn_state *state = space->machine().driver_data(); return state->m_cart_dram[offset+0x200000/4]; } static WRITE32_HANDLER( saturn_cart_dram1_w ) { saturn_state *state = space->machine().driver_data(); COMBINE_DATA(&state->m_cart_dram[offset+0x200000/4]); } static READ32_HANDLER( saturn_cs1_r ) { saturn_state *state = space->machine().driver_data(); UINT32 res; res = 0; //res = state->m_cart_backupram[offset*4+0] << 24; res |= state->m_cart_backupram[offset*2+0] << 16; //res |= state->m_cart_backupram[offset*4+2] << 8; res |= state->m_cart_backupram[offset*2+1] << 0; return res; } static WRITE32_HANDLER( saturn_cs1_w ) { saturn_state *state = space->machine().driver_data(); if(ACCESSING_BITS_16_23) state->m_cart_backupram[offset*2+0] = (data & 0x00ff0000) >> 16; if(ACCESSING_BITS_0_7) state->m_cart_backupram[offset*2+1] = (data & 0x000000ff) >> 0; } static MACHINE_RESET( saturn ) { saturn_state *state = machine.driver_data(); // don't let the slave cpu and the 68k go anywhere cputag_set_input_line(machine, "slave", INPUT_LINE_RESET, ASSERT_LINE); cputag_set_input_line(machine, "audiocpu", INPUT_LINE_RESET, ASSERT_LINE); state->m_smpc.SR = 0x40; // this bit is always on according to docs state->m_en_68k = 0; state->m_NMI_reset = 0; DMA_STATUS = 0; //memset(stv_m_workram_l, 0, 0x100000); //memset(stv_m_workram_h, 0, 0x100000); machine.device("maincpu")->set_unscaled_clock(MASTER_CLOCK_320/2); machine.device("slave")->set_unscaled_clock(MASTER_CLOCK_320/2); stvcd_reset( machine ); state->m_cart_type = input_port_read(machine,"CART_AREA") & 7; machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x02400000, 0x027fffff, FUNC(saturn_null_ram_r), FUNC(saturn_null_ram_w)); machine.device("slave")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x02400000, 0x027fffff, FUNC(saturn_null_ram_r), FUNC(saturn_null_ram_w)); if(state->m_cart_type == 5) { // AM_RANGE(0x02400000, 0x027fffff) AM_RAM //cart RAM area, dynamically allocated machine.device("maincpu")->memory().space(AS_PROGRAM)->nop_readwrite(0x02400000, 0x027fffff); machine.device("slave")->memory().space(AS_PROGRAM)->nop_readwrite(0x02400000, 0x027fffff); machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x02400000, 0x0247ffff, FUNC(saturn_cart_dram0_r), FUNC(saturn_cart_dram0_w)); machine.device("slave")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x02400000, 0x0247ffff, FUNC(saturn_cart_dram0_r), FUNC(saturn_cart_dram0_w)); machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x02600000, 0x0267ffff, FUNC(saturn_cart_dram1_r), FUNC(saturn_cart_dram1_w)); machine.device("slave")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x02600000, 0x0267ffff, FUNC(saturn_cart_dram1_r), FUNC(saturn_cart_dram1_w)); } if(state->m_cart_type == 6) { // AM_RANGE(0x02400000, 0x027fffff) AM_RAM //cart RAM area, dynamically allocated machine.device("maincpu")->memory().space(AS_PROGRAM)->nop_readwrite(0x02400000, 0x027fffff); machine.device("slave")->memory().space(AS_PROGRAM)->nop_readwrite(0x02400000, 0x027fffff); machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x02400000, 0x025fffff, FUNC(saturn_cart_dram0_r), FUNC(saturn_cart_dram0_w)); machine.device("slave")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x02400000, 0x025fffff, FUNC(saturn_cart_dram0_r), FUNC(saturn_cart_dram0_w)); machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x02600000, 0x027fffff, FUNC(saturn_cart_dram1_r), FUNC(saturn_cart_dram1_w)); machine.device("slave")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x02600000, 0x027fffff, FUNC(saturn_cart_dram1_r), FUNC(saturn_cart_dram1_w)); } machine.device("maincpu")->memory().space(AS_PROGRAM)->nop_readwrite(0x04000000, 0x047fffff); machine.device("slave")->memory().space(AS_PROGRAM)->nop_readwrite(0x04000000, 0x047fffff); if(state->m_cart_type > 0 && state->m_cart_type < 5) { // AM_RANGE(0x04000000, 0x047fffff) AM_RAM //backup RAM area, dynamically allocated UINT32 mask; mask = 0x7fffff >> (4-state->m_cart_type); //mask = 0x7fffff >> 4-4 = 0x7fffff 32mbit //mask = 0x7fffff >> 4-3 = 0x3fffff 16mbit //mask = 0x7fffff >> 4-2 = 0x1fffff 8mbit //mask = 0x7fffff >> 4-1 = 0x0fffff 4mbit machine.device("maincpu")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x04000000, 0x04000000 | mask, FUNC(saturn_cs1_r), FUNC(saturn_cs1_w)); machine.device("slave")->memory().space(AS_PROGRAM)->install_legacy_readwrite_handler(0x04000000, 0x04000000 | mask, FUNC(saturn_cs1_r), FUNC(saturn_cs1_w)); } /* TODO: default value is probably 7 */ state->m_scu.start_factor[0] = -1; state->m_scu.start_factor[1] = -1; state->m_scu.start_factor[2] = -1; state->m_vdp2.old_crmd = -1; state->m_vdp2.old_tvmd = -1; state->m_stv_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1)); } static MACHINE_RESET( stv ) { saturn_state *state = machine.driver_data(); // don't let the slave cpu and the 68k go anywhere cputag_set_input_line(machine, "slave", INPUT_LINE_RESET, ASSERT_LINE); cputag_set_input_line(machine, "audiocpu", INPUT_LINE_RESET, ASSERT_LINE); state->m_en_68k = 0; state->m_NMI_reset = 0; state->m_port_sel = state->m_mux_data = 0; machine.device("maincpu")->set_unscaled_clock(MASTER_CLOCK_320/2); machine.device("slave")->set_unscaled_clock(MASTER_CLOCK_320/2); stvcd_reset(machine); state->m_stv_rtc_timer->adjust(attotime::zero, 0, attotime::from_seconds(1)); state->m_prev_bankswitch = 0xff; /* TODO: default value is probably 7 */ state->m_scu.start_factor[0] = -1; state->m_scu.start_factor[1] = -1; state->m_scu.start_factor[2] = -1; state->m_vdp2.old_crmd = -1; state->m_vdp2.old_tvmd = -1; } struct cdrom_interface saturn_cdrom = { NULL, NULL }; static MACHINE_CONFIG_START( saturn, saturn_state ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", SH2, MASTER_CLOCK_352/2) // 28.6364 MHz MCFG_CPU_PROGRAM_MAP(saturn_mem) MCFG_CPU_CONFIG(sh2_conf_master) MCFG_TIMER_ADD_SCANLINE("scantimer", saturn_scanline, "screen", 0, 1) MCFG_CPU_ADD("slave", SH2, MASTER_CLOCK_352/2) // 28.6364 MHz MCFG_CPU_PROGRAM_MAP(saturn_mem) MCFG_CPU_CONFIG(sh2_conf_slave) MCFG_TIMER_ADD_SCANLINE("slave_scantimer", saturn_slave_scanline, "screen", 0, 1) MCFG_CPU_ADD("audiocpu", M68000, 11289600) //256 x 44100 Hz = 11.2896 MHz MCFG_CPU_PROGRAM_MAP(sound_mem) MCFG_MACHINE_START(saturn) MCFG_MACHINE_RESET(saturn) MCFG_NVRAM_HANDLER(saturn) MCFG_TIMER_ADD("sector_timer", stv_sector_cb) MCFG_TIMER_ADD("sh1_cmd", stv_sh1_sim) /* video hardware */ MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_320/8, 427, 0, 320, 263, 0, 224) #if NEW_VIDEO_CODE MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) MCFG_SCREEN_UPDATE(saturn) MCFG_PALETTE_LENGTH(2048+(2048*2))//standard palette + extra memory for rgb brightness. (TODO: remove AT LEAST the latter) #else MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB15) MCFG_SCREEN_UPDATE(stv_vdp2) MCFG_PALETTE_LENGTH(2048+(2048*2))//standard palette + extra memory for rgb brightness. #endif MCFG_GFXDECODE(stv) MCFG_VIDEO_START(stv_vdp2) MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") MCFG_SOUND_ADD("scsp", SCSP, 0) MCFG_SOUND_CONFIG(scsp_config) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) MCFG_SOUND_ADD("cdda", CDDA, 0) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) MCFG_CDROM_ADD( "cdrom", saturn_cdrom) MCFG_CARTSLOT_ADD("cart") MACHINE_CONFIG_END static MACHINE_CONFIG_START( stv, saturn_state ) /* basic machine hardware */ MCFG_CPU_ADD("maincpu", SH2, MASTER_CLOCK_352/2) // 28.6364 MHz MCFG_CPU_PROGRAM_MAP(stv_mem) MCFG_CPU_CONFIG(sh2_conf_master) MCFG_TIMER_ADD_SCANLINE("scantimer", saturn_scanline, "screen", 0, 1) MCFG_CPU_ADD("slave", SH2, MASTER_CLOCK_352/2) // 28.6364 MHz MCFG_CPU_PROGRAM_MAP(stv_mem) MCFG_CPU_CONFIG(sh2_conf_slave) MCFG_TIMER_ADD_SCANLINE("slave_scantimer", saturn_slave_scanline, "screen", 0, 1) MCFG_CPU_ADD("audiocpu", M68000, 11289600) //11.2896 MHz MCFG_CPU_PROGRAM_MAP(sound_mem) MCFG_MACHINE_START(stv) MCFG_MACHINE_RESET(stv) MCFG_EEPROM_93C46_ADD("eeprom") /* Actually 93c45 */ MCFG_TIMER_ADD("sector_timer", stv_sector_cb) MCFG_TIMER_ADD("sh1_cmd", stv_sh1_sim) /* video hardware */ MCFG_VIDEO_ATTRIBUTES(VIDEO_UPDATE_AFTER_VBLANK) MCFG_SCREEN_ADD("screen", RASTER) MCFG_SCREEN_RAW_PARAMS(MASTER_CLOCK_320/8, 427, 0, 320, 263, 0, 224) #if NEW_VIDEO_CODE MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB32) MCFG_SCREEN_UPDATE(saturn) MCFG_PALETTE_LENGTH(2048+(2048*2))//standard palette + extra memory for rgb brightness. (TODO: remove AT LEAST the latter) #else MCFG_SCREEN_FORMAT(BITMAP_FORMAT_RGB15) MCFG_SCREEN_UPDATE(stv_vdp2) MCFG_PALETTE_LENGTH(2048+(2048*2))//standard palette + extra memory for rgb brightness. #endif MCFG_GFXDECODE(stv) MCFG_VIDEO_START(stv_vdp2) MCFG_SPEAKER_STANDARD_STEREO("lspeaker", "rspeaker") MCFG_SOUND_ADD("scsp", SCSP, 0) MCFG_SOUND_CONFIG(scsp_config) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) MCFG_SOUND_ADD("cdda", CDDA, 0) MCFG_SOUND_ROUTE(0, "lspeaker", 1.0) MCFG_SOUND_ROUTE(1, "rspeaker", 1.0) MACHINE_CONFIG_END struct stv_cart_region { const char *tag; int slot; const char *region; }; static const struct stv_cart_region stv_cart_table[] = { { "cart1", 0, "game0" }, { "cart2", 1, "game1" }, { "cart3", 2, "game2" }, { "cart4", 3, "game3" }, { 0 } }; static DEVICE_IMAGE_LOAD( stv_cart ) { // saturn_state *state = image.device().machine().driver_data(); const struct stv_cart_region *stv_cart = &stv_cart_table[0], *this_cart; //const char *pcb_name; /* First, determine where this cart has to be loaded */ while (stv_cart->tag) { if (strcmp(stv_cart->tag, image.device().tag()) == 0) break; stv_cart++; } this_cart = stv_cart; if (image.software_entry() == NULL) return IMAGE_INIT_FAIL; UINT8 *ROM = image.device().machine().region(this_cart->region)->base(); UINT32 length = image.get_software_region_length("rom"); memcpy(ROM, image.get_software_region("rom"), length); /* fix endianess */ { UINT8 j[4]; int i; for(i=0;i(); state->m_saturn_region = rgn; state->m_vdp2.pal = (rgn == 12) ? 1 : 0; // set compatible options sh2drc_set_options(machine.device("maincpu"), SH2DRC_STRICT_VERIFY|SH2DRC_STRICT_PCREL); sh2drc_set_options(machine.device("slave"), SH2DRC_STRICT_VERIFY|SH2DRC_STRICT_PCREL); /* amount of time to boost interleave for on MINIT / SINIT, needed for communication to work */ state->m_minit_boost = 400; state->m_sinit_boost = 400; state->m_minit_boost_timeslice = attotime::zero; state->m_sinit_boost_timeslice = attotime::zero; state->m_scu_regs = auto_alloc_array(machine, UINT32, 0x100/4); state->m_scsp_regs = auto_alloc_array(machine, UINT16, 0x1000/2); state->m_cart_dram = auto_alloc_array(machine, UINT32, 0x400000/4); state->m_backupram = auto_alloc_array(machine, UINT8, 0x8000); state->m_cart_backupram = auto_alloc_array(machine, UINT8, 0x400000); } static DRIVER_INIT( saturnus ) { saturn_init_driver(machine, 4); } static DRIVER_INIT( saturneu ) { saturn_init_driver(machine, 12); } static DRIVER_INIT( saturnjp ) { saturn_init_driver(machine, 1); } /* Japanese Saturn */ ROM_START(saturnjp) ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ ROM_SYSTEM_BIOS(0, "101", "Japan v1.01 (941228)") ROMX_LOAD("sega_101.bin", 0x00000000, 0x00080000, CRC(224b752c) SHA1(df94c5b4d47eb3cc404d88b33a8fda237eaf4720), ROM_BIOS(1)) ROM_SYSTEM_BIOS(1, "1003", "Japan v1.003 (941012)") ROMX_LOAD("sega1003.bin", 0x00000000, 0x00080000, CRC(b3c63c25) SHA1(7b23b53d62de0f29a23e423d0fe751dfb469c2fa), ROM_BIOS(2)) ROM_SYSTEM_BIOS(2, "100", "Japan v1.00 (940921)") ROMX_LOAD("sega_100.bin", 0x00000000, 0x00080000, CRC(2aba43c2) SHA1(2b8cb4f87580683eb4d760e4ed210813d667f0a2), ROM_BIOS(3)) ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ ROM_COPY( "maincpu",0,0,0x080000) ROM_END /* Overseas Saturn */ ROM_START(saturn) ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ ROM_SYSTEM_BIOS(0, "101a", "Overseas v1.01a (941115)") /* Confirmed by ElBarto */ ROMX_LOAD("mpr-17933.bin", 0x00000000, 0x00080000, CRC(4afcf0fa) SHA1(faa8ea183a6d7bbe5d4e03bb1332519800d3fbc3), ROM_BIOS(1)) ROM_SYSTEM_BIOS(1, "100a", "Overseas v1.00a (941115)") ROMX_LOAD("sega_100a.bin", 0x00000000, 0x00080000, CRC(f90f0089) SHA1(3bb41feb82838ab9a35601ac666de5aacfd17a58), ROM_BIOS(2)) ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ ROM_COPY( "maincpu",0,0,0x080000) ROM_END ROM_START(saturneu) ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ ROM_SYSTEM_BIOS(0, "101a", "Overseas v1.01a (941115)") /* Confirmed by ElBarto */ ROMX_LOAD("mpr-17933.bin", 0x00000000, 0x00080000, CRC(4afcf0fa) SHA1(faa8ea183a6d7bbe5d4e03bb1332519800d3fbc3), ROM_BIOS(1)) ROM_SYSTEM_BIOS(1, "100a", "Overseas v1.00a (941115)") ROMX_LOAD("sega_100a.bin", 0x00000000, 0x00080000, CRC(f90f0089) SHA1(3bb41feb82838ab9a35601ac666de5aacfd17a58), ROM_BIOS(2)) ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ ROM_COPY( "maincpu",0,0,0x080000) ROM_END ROM_START(vsaturn) ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ ROM_LOAD("vsaturn.bin", 0x00000000, 0x00080000, CRC(e4d61811) SHA1(4154e11959f3d5639b11d7902b3a393a99fb5776)) ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ ROM_COPY( "maincpu",0,0,0x080000) ROM_END ROM_START(hisaturn) ROM_REGION( 0x480000, "maincpu", ROMREGION_ERASEFF ) /* SH2 code */ ROM_LOAD("hisaturn.bin", 0x00000000, 0x00080000, CRC(721e1b60) SHA1(49d8493008fa715ca0c94d99817a5439d6f2c796)) ROM_CART_LOAD("cart", 0x080000, 0x400000, ROM_NOMIRROR | ROM_OPTIONAL) ROM_REGION( 0x080000, "slave", 0 ) /* SH2 code */ ROM_COPY( "maincpu",0,0,0x080000) ROM_END /* YEAR NAME PARENT COMPAT MACHINE INPUT INIT COMPANY FULLNAME FLAGS */ CONS( 1994, saturn, 0, 0, saturn, saturn, saturnus, "Sega", "Saturn (USA)", GAME_NOT_WORKING ) CONS( 1994, saturnjp, saturn, 0, saturn, saturn, saturnjp, "Sega", "Saturn (Japan)", GAME_NOT_WORKING ) CONS( 1994, saturneu, saturn, 0, saturn, saturn, saturneu, "Sega", "Saturn (PAL)", GAME_NOT_WORKING ) CONS( 1995, vsaturn, saturn, 0, saturn, saturn, saturnjp, "JVC", "V-Saturn", GAME_NOT_WORKING ) CONS( 1995, hisaturn, saturn, 0, saturn, saturn, saturnjp, "Hitachi", "HiSaturn", GAME_NOT_WORKING ) #include "stv.c"