diff --git a/src/mame/misc/truco.cpp b/src/mame/misc/truco.cpp index 28a6b4a6537..8800502b9dd 100644 --- a/src/mame/misc/truco.cpp +++ b/src/mame/misc/truco.cpp @@ -1,25 +1,89 @@ // license:BSD-3-Clause -// copyright-holders: Ernesto Corvi, Roberto Fresca +// copyright-holders: Ernesto Corvi, Roberto Fresca, Grull Osgo -/****************************************************************************************************** +/**************************************************************************************************************** Truco-Tron - (c) 198? Playtronic SRL, Argentina. - Written by Ernesto Corvi - Additional work by Roberto Fresca. + Written by Ernesto Corvi, Roberto Fresca, and Grull Osgo. - Notes: +***************************************************************************************************************** - - The board uses a battery backed ram for protection, mapped at $7c00-$7fff. - - If the battery backup data is corrupt, it comes up with some sort of code entry screen. - - The game stores the current credits count in the battery backed ram. - - System clock is 12 Mhz. The CPU clock is unknown. - - The Alternate GFX mode is funky. Not only it has different bitmaps, but also the strings with the - game options are truncated. Title is also truncated. - - At least one bootleg board exist. + This appears to be the first arcade game fully designed in Argentina. The hardware, which is based on a M6809E CPU, + is unlike anything previously known. -******************************************************************************************************* + The game is based on Truco, a traditional and highly strategic Argentine card game. It's known for being difficult + to play, as the objective is to earn points by playing cards while bluffing about the hand you hold. + + For more about the rules of Truco, see the following links: + https://www.nhfournier.es/en/como-jugar/truco/ + https://www.wikihow.com/Play-Truco + + + Truco-tron focuses on the "1 player vs machine" mode (mano a mano), offering a unique arcade experience. + + All game and technical information, including the emulation and IC's recognition, was obtained + by reverse-engineering both the hardware and game code. + + The game has various settings hardcoded into non-volatile RAM, which are inaccessible to the user. + The entire RAM system is powered by a 3.6V lithium battery, which is monitored by a Maxim MAX691 device. + If power is lost or the battery drains, the game becomes inoperable and requires a fresh RAM image to function again. + + If the RAM contents are missing, a yellow password entry screen appears, but it serves no purpose. It’s believed that + the original design intended to show a repair screen, as the necessary values are hardcoded and ready to be injected. + However, the game code attempts to inject incorrect values, which results in garbage data and prevents the game from + booting properly. + + In normal arcade mode, defeating the machine rewards the player with a free game. + + Though marketed as an arcade game, Truco-tron also contains a hidden gambling mode that is inaccessible by default. + Enabling this mode requires substantial modifications, such as adding extra inputs and altering the PIA 6821 inputs + mask that hides them. Once activated, a supervisor key appears, providing two new inputs for adding and removing credits, + functioning as key-in and key-out. + + The gambling mode features a selectable risk level, allowing players to multiply their winnings but at the cost of + increasing the amount of credits at risk. + + Another hidden mode, likely used during development for debugging, enables the player to set their cards in the game, + allowing for a more controlled test environment. + + + How to Activate Gambling Mode + ----------------------------- + + Go to the machine's configuration menu and select the gambling game mode. + Introduce one credit, and then press the button to enter the credits screen. + Turn the supervisor key (hold the SERVICE button), and you can add credits using the standard coin mechanism + or the key-in button (Key Q). Use the joystick and game button to select the desired risk level. + To collect credits, use the TILT button as key-out (Key T). + + You can also press the BOOKS button to view the in/out counters on the credits screen. + There are jumpers, but they are just holes instead of actual jumpers. It seems they never anticipated a real + implementation. The effects and settings are visible below. + + + Easter Egg + ---------- + + Hidden within the game is an encrypted message, which appears after a specific combination of inputs is entered. + This can only be triggered when you have 8 credits in gambling mode and have lied about Flor. + + The hidden message reads: + "ESTE PROGRAMA DE JUEGO DE TRUCO PERTENECE A LOS PROPIETARIOS DE LA MARCA LANZA PERFUME" + + Reaching this message is incredibly complex, and if the wrong action is taken, a small red dot will appear, + causing the game to "suicide" itself. This will require the RAM contents to be reloaded in order for the game + to work again. + + + Additionally, the game features an unfinished alternate graphics mode with clipped strings, which can be switched + on using one of the jumpers. + + It is believed that only 300 of these boards were ever produced. + + +***************************************************************************************************************** Mini-board (6"x 7") silkscreened 8901 REV.C JAMMA connector. @@ -34,31 +98,31 @@ PCB layout: - .--------------------------------------------------. - |S T .---. .---. .---. .-. .-. .---. .-. | - |E R | | | U | | U | |U| |U| | U | |U| | - |R U | | | 2 | | 3 | |1| |5| | 1 | |1| | - |I C | U | | | | | |5| | | | 0 | |4| | - |E O | 1 | | | | | '-' '-' | | '-' | - | | | '---' '---' .-. '---' .-. | - |0 T | | |U| .-------. |U| | - |0 R | | |1| |BATTERY| |1| | - |0 O | | |2| | - + | |9| | - |0 N '---' '-' '-------' '-' | - | .-. .-, .---. .-. .---. .-. .-. .-. | - | |U| |U| | | |U| | | |U| |U| |U| | - | |1| |1| | | |1| | | |6| |7| |1| | - | |7| |8| | U | |6| | U | | | | | |3| P| - | '-' '-' | 4 | '-' | 9 | '-' '-' | | L| - | .----. | | | | .-. .-. '-' A| - | |Xtal| | | | | |U| |U| Y| - | '----' | | | | |1| |8| T| - | .-. | | | | |1| | | R| - | |U| '---' '---' '-' '-' O| - | |2|.---. N| - | |0||pot| I| - | '-''---' JAMMA C| - '----+++++++++++++++++++++++++++++-----------------' + .---------------------------------------------------. + |S T .---. .---. .---. .-. .-. .---. .-. | + |E R | | | U | | U | |U| |U| | U | |U| | + |R U | | | 2 | | 3 | |1| |5| | 1 | |1| | + |I C | U | | | | | |5| | | | 0 | |4| | + |E O | 1 | | | | | '-' '-' | | '-' | + | | | '---' '---' .-. '---' .-. | + |0 T | | |U| .-------. |U| | + |0 R | | |1| |BATTERY| |1|---.| + |0 O | | |2| | - + | |9|R12|| + |0 N '---' '-' '-------' '-'---'| + | .-. .-, .---. .-. .---. .-. .-. .-. | + | |U| |U| | | |U| | | |U| |U| |U| | + | |1| |1| | | |1| | | |6| |7| |1| | + | |7| |8| | U | |6| | U | | | | | |3| P| + | '-' '-' | 4 | '-' | 9 | '-' '-' | | L| + | .----. | | | | .-. .-. '-' A| + | |Xtal| | | | | |U| |U| Y| + | '----' | | | | |1| |8| T| + | .-. | | | | |1| | | R| + | |U| '---' '---' '-' '-' O| + | |2|.---. N| + | |0||R17| I| + | '-''---' JAMMA C| + '----+++++++++++++++++++++++++++++------------------' ||||||||||||||||||||||||||||| '---------------------------' @@ -88,19 +152,22 @@ - U19: 16-pin IC YES WATCHDOG MAXIM MAX691 Microprocessor Supervisory Circuits. - U20: 16-pin IC YES DARLINGTON ULN2003 7 NPN Darlington transistor pairs with high voltage and current capability. + - R12: 1K pot. Connected through legs 2 & 3 to MAX691 pin 9 (PFI), and a pull-up. + - R17: 100K pot. Connected to ULN2003 (pin 10), and then to audio out on the edge connector. - M6809 + + M6809E .---\/---. - GND 1| |40 !HALT <-- - --> !NMI 2| |39 ETAL <-- - PIA /IRQA & B --> !IRQ 3| |38 EXTAL <-- - --> !FIRQ 4| |37 !RES <-- PIA /RES & U19(15) MAX691 - <-- BS 5| |36 MRDY <-- + VSS/GND 1| |40 /HALT <-- + (*) --> /NMI 2| |39 TSC <-- + PIA /IRQA & B --> /IRQ 3| |38 LIC <-- + --> /FIRQ 4| |37 /RES <-- PIA /RES & U19(15) MAX691 + <-- BS 5| |36 AVMA <-- <-- BA 6| |35 Q <-- Vcc 7| U1 |34 E <-- PIA E (25) - PIA /RS0 (36) <-- A0 8| |33 !DMA <-- + PIA /RS0 (36) <-- A0 8| |33 BUSY <-- PIA /RS1 (35) <-- A1 9|Motorola|32 R/!W --> PIA R/W (21) - <-- A2 10| 6809 |31 D0 <-> PIA D0 (33) + <-- A2 10| 6809E |31 D0 <-> PIA D0 (33) <-- A3 11| |30 D1 <-> PIA D1 (32) <-- A4 12| |29 D2 <-> PIA D2 (31) <-- A5 13| |28 D3 <-> PIA D3 (30) @@ -113,9 +180,13 @@ <-- A12 20| |21 A13 --> '--------' + (*) /NMI is connected to U19 pin 10 (MAX691 /PFO line), + and then through a decoupler to pull-up. + + PIA 6821 .----\/----. - VSS |01 40| CA1 --- PIA CB1 (*) + VSS/GND |01 40| CA1 --- PIA CB1 (*) JAMMA S17 (2P_ST) - PA0 |02 39| CA2 --- U19(11). Watchdog/RESET JAMMA S14 (SRVSW) - PA1 |03 38| /IRQA - CPU M6809 !IRQ (03) JAMMA C26 (2P_SL) - PA2 |04 37| /IRQB - CPU M6809 !IRQ (03) @@ -131,9 +202,9 @@ JP1(6) - PB4 |14 27| D6 ---- CPU M6809 D6 (25) JP1(4) - PB5 |15 26| D7 ---- CPU M6809 D7 (24) JP1(2) - PB6 |16 25| E ----- CPU M6809 E (34) - U20(07) - PB7 |17 24| CS1 - PIA CA1 (*) - CB1 |18 23| /CS2 - U20(06) - CB2 |19 22| CS0 + U20(07) - PB7 |17 24| CS1 --- VCC (bridge with pin 20) + PIA CA1 (*) - CB1 |18 23| /CS2 -- PALCE16V8H (U16, pin 13) + U20(06) - CB2 |19 22| CS0 --- VCC (bridge with pin 20) VCC |20 21| R/W '----------' @@ -144,19 +215,21 @@ U19: *** MAX691 *** Maxim MAX691 Microprocessor Supervisory Circuit. (for battery backup power switching and watchdog). - MAX691 - .---\/---. - <----- [VBATT]--|01 16|--[PFI] ------> - <------ [VOUT]--|02 15|--[/PFO] -----> - VCC <------- [VCC]--|03 14|--[WDI] ------> PIA CA2 - GND <------- [GND]--|04 13|--[/CE OUT] --> - <--- [BATT ON]--|05 12|--[/CE IN] ---> GND - <-- [/LOWLINE]--|06 11|--[/WDO] -----> - * N/C <---- [OSC IN]--|07 10|--[/RESET] ---> CPU /RES (37) - * N/C <--- [OSC SEL]--|08 09|--[RESET] ----> - '--------' + MAX691 + .---\/---. + BATT+ <----- [VBATT]--|01 16|--[RESET] ----> + <------ [VOUT]--|02 15|--[/RESET] ---> CPU M6809 /RES (37) & CA2 (39); PIA /RES (34) + VCC <------- [VCC]--|03 14|--[/WDO] -----> + GND <------- [GND]--|04 13|--[/CE IN] ---> GND + <--- [BATT ON]--|05 12|--[/CE OUT] --> + <-- [/LOWLINE]--|06 11|--[WDI] ------> PIA CA2 + (*) N/C <---- [OSC IN]--|07 10|--[/PFO] -----> CPU M6809 /NMI (2) --> decoupling --> pullup (**) + (*) N/C <--- [OSC SEL]--|08 09|--[PFI] ------> R12 pot legs 2 & 3 + '--------' - * Set 1.6 seconds as WD timeout. + (*) Set 1.6 seconds as WD timeout. + (**) After a power failure, the MAX691 attacks the 6809E /NMI line through the /PFO line. + then the NMI routine put a register in RAM with the error, and halt the system. U20: *** ULN2003 *** High-voltage, high-current Darlington transistor array. @@ -169,11 +242,16 @@ PIA PB2 (12) <--|04 13|--> JAMMA(S08) Coin Counter 2 PIA PB3 (13) <--|05 12|--> JAMMA(C08) Coin Counter 1 PIA CB2 (19) <--|06 11|--> JAMMA(S26) - PIA PB7 (17) <--|07 10|--> CAP --> JAMMA(S10) +Speaker + PIA PB7 (17) <--|07 10|--> C1 (2.2 uF) --> R17 (100K pot) --> JAMMA(S10) +Speaker GND <--|08 09|--> VCC '--------' + Jumpers and hardcoded switches... + + There are two jumpers banks. + No pins to connect. The PCB has only the holes. + JP1: 01 --> GND 02 --> PIA PB6 (16) & R5(1K) --> VCC @@ -191,7 +269,46 @@ 06 --> Seems N/C -*******************************************************************************************************/ + JP1 JP2 + (+5V) PIA(PB6) + | | O--GND--O + .---R22---+---R5---+-------O O---R9---PIA(PB1) + | + PIA(/RES) PIA(PB5) + | O--GND--O + R22---(+5V)---R7--+---------O O---PIA(PB0)---R10--(+5V) + + + O--GND--O + (GND)---R22---R8---PIA(PB4)-----O O + + + R5 = 1K + R7 = 1K + R8 = 1K + R9 = 1K + R10 = 1K + R22 = 10K + + + + Game harcoded switches: + + 9Eh: 1 = No timeout / 0 = Game Timeout + ACh: 1 = Gamble Mode / 2 = Arcade Mode + 88h: 0 = Normal / 1 = Choose Cards + ABh: 0 = Input P0 No Masked / 1 = Masked (Default): Enables Service/Books key that show the counters. + + +***************************************************************************************************************** + + TODO: + + - Find the function of the P1-4 input line. + - Find the function of the JP2-2 from PIA PB0 + + +*****************************************************************************************************************/ #include "emu.h" @@ -201,22 +318,14 @@ #include "machine/watchdog.h" #include "sound/dac.h" #include "video/mc6845.h" +#include "machine/nvram.h" +#include "machine/ram.h" #include "emupal.h" #include "screen.h" #include "speaker.h" -// configurable logging -#define LOG_PIA (1U << 1) - -//#define VERBOSE (LOG_GENERAL | LOG_PIA) - -#include "logmacro.h" - -#define LOGPIA(...) LOGMASKED(LOG_PIA, __VA_ARGS__) - - namespace { class truco_state : public driver_device @@ -229,44 +338,48 @@ public: m_palette(*this, "palette"), m_dac(*this, "dac"), m_videoram(*this, "videoram"), - m_battery_ram(*this, "battery_ram"), - m_coin(*this, "COIN") + m_nvram(*this, "nvram"), + m_ram(*this, RAM_TAG), + m_coin(*this, "COIN"), + m_settings(*this, "SETTINGS") { } void truco(machine_config &config); protected: virtual void machine_start() override ATTR_COLD; - virtual void machine_reset() override ATTR_COLD; private: required_device m_maincpu; required_device m_watchdog; required_device m_palette; required_device m_dac; - required_shared_ptr m_videoram; - required_shared_ptr m_battery_ram; + required_device m_nvram; + required_device m_ram; required_ioport m_coin; + required_ioport m_settings; uint8_t m_trigger = 0; - void porta_w(uint8_t data); void pia_ca2_w(int state); void portb_w(uint8_t data); - void pia_irqa_w(int state); - void pia_irqb_w(int state); + uint8_t pia_ca1_r(); + uint8_t pia_cb1_r(); void palette(palette_device &palette) const; uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - INTERRUPT_GEN_MEMBER(interrupt); void main_map(address_map &map) ATTR_COLD; }; +/******************************************* +* Video Hardware * +*******************************************/ + void truco_state::palette(palette_device &palette) const { for (int i = 0; i < palette.entries(); i++) @@ -304,16 +417,21 @@ uint32_t truco_state::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, videoram += 0x80; } return 0; -} +} /******************************************* * Read/Write Handlers * *******************************************/ -void truco_state::porta_w(uint8_t data) +uint8_t truco_state::pia_ca1_r() { - LOGPIA("Port A writes: %2x\n", data); + return m_coin->read() & 1; +} + +uint8_t truco_state::pia_cb1_r() +{ + return m_coin->read() & 1; } void truco_state::pia_ca2_w(int state) @@ -327,24 +445,27 @@ void truco_state::pia_ca2_w(int state) setting 1.6 seconds as WD timeout. */ m_watchdog->watchdog_reset(); + + +/* Game harcoded switches: + + 9Eh: 1 = No timeout / 0 = Game Timeout + ACh: 1 = Gamble Mode / 2 = Arcade Mode + 88h: 0 = Normal / 1 = Choose Cards + ABh: 0 = Input P0 No Masked / 1 = Masked (Default) +*/ + m_ram->write(0x88, BIT(m_settings->read(), 1) & 1); + m_ram->write(0x9e, BIT(m_settings->read(), 2) & 1); + m_ram->write(0xac, BIT(m_settings->read(), 0) ? 2 : 1); + m_ram->write(0xab, BIT(m_settings->read(), 0) ? 0xfa : 0xff); // Enable counters switch via Service Key } void truco_state::portb_w(uint8_t data) { m_dac->write(BIT(data, 7)); // Isolated the bit for Delta-Sigma DAC - if (data & 0x7f) - LOGPIA("Port B writes: %2x\n", data); -} - -void truco_state::pia_irqa_w(int state) -{ - LOGPIA("PIA irq A: %2x\n", state); -} - -void truco_state::pia_irqb_w(int state) -{ - LOGPIA("PIA irq B: %2x\n", state); + machine().bookkeeping().coin_counter_w(0, BIT(data, 3)); // coin in + machine().bookkeeping().coin_counter_w(1, BIT(data, 2)); // coin out } @@ -354,9 +475,8 @@ void truco_state::pia_irqb_w(int state) void truco_state::main_map(address_map &map) { - map(0x0000, 0x17ff).ram(); // General purpose RAM + map(0x0000, 0x7fff).rw(m_ram, FUNC(ram_device::read), FUNC(ram_device::write)); // Battery backed RAM map(0x1800, 0x7bff).ram().share(m_videoram); - map(0x7c00, 0x7fff).ram().share(m_battery_ram); map(0x8000, 0x8003).rw("pia0", FUNC(pia6821_device::read), FUNC(pia6821_device::write)); map(0x8004, 0x8004).w("crtc", FUNC(mc6845_device::address_w)); map(0x8005, 0x8005).rw("crtc", FUNC(mc6845_device::register_r), FUNC(mc6845_device::register_w)); @@ -376,110 +496,65 @@ void truco_state::main_map(address_map &map) *******************************************/ static INPUT_PORTS_START( truco ) - PORT_START("P1") // IN0 - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_UNKNOWN ) // Connected to JAMMA S17 (P2 START) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) // Connected to JAMMA S14 (SERVICE SW) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) // Connected to JAMMA C26 (P2 SELECT) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) // Connected to JAMMA S16 (COIN2) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) // Connected to JAMMA S15 (TILT SW) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // Connected to JAMMA C22 (P1 BUTTON1) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) // Connected to JAMMA C18/21 (JOY UP & JOY RIGHT) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) // Connected to JAMMA C19/20 (JOY DOWN & JOY LEFT) + PORT_START("P1") + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_GAMBLE_SERVICE ) PORT_NAME("Keyout enable Key") // Connected to JAMMA S17 (P2 START) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_GAMBLE_BOOK ) // Connected to JAMMA S14 (SERVICE SW) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) PORT_NAME("P1-4")PORT_CODE(KEYCODE_D) // still not clear... Connected to JAMMA C26 (P2 SELECT) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_GAMBLE_KEYIN) // Connected to JAMMA S16 (COIN2) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_TILT ) PORT_NAME("Tilt / Keyout") // 'tilt' line. once turned the key behaves as keyout. + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON1 ) // Connected to JAMMA C22 (P1 BUTTON1) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_JOYSTICK_UP ) // Connected to JAMMA C18/21 (JOY UP & JOY RIGHT) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_JOYSTICK_DOWN ) // Connected to JAMMA C19/20 (JOY DOWN & JOY LEFT) - PORT_START("COIN") // IN1 + PORT_START("COIN") PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_COIN1 ) - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_UNKNOWN ) - PORT_START("JMPRS") // JP1-2 - PORT_DIPNAME( 0x01, 0x01, DEF_STR( Unknown ) ) + + PORT_START("JUMPERS") // JP1-2 + + PORT_DIPNAME( 0x01, 0x01, "JP2-2 - Unknown" ) PORT_DIPLOCATION("JP2:2") // JP2-2 (PB0) PORT_DIPSETTING ( 0x01, DEF_STR( Off ) ) PORT_DIPSETTING ( 0x00, DEF_STR( On ) ) - PORT_DIPNAME( 0x02, 0x02, "Alt. Graphics" ) - 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_DIPNAME( 0x02, 0x02, "Graphics" ) PORT_DIPLOCATION("JP2:1") // JP2-1 (PB1) + PORT_DIPSETTING ( 0x02, "Normal" ) + PORT_DIPSETTING ( 0x00, "Alt GFX" ) + +// The following jumper was designed to switch between arcade and gambling modes +// but the code was NOP'ed to avoid this option. + PORT_DIPNAME( 0x10, 0x10, "JP1-3 - Unused" ) PORT_DIPLOCATION("JP1:3") // JP1-3 (PB4) 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_DIPNAME( 0x60, 0x60, "Odds" ) PORT_DIPLOCATION("JP1:1,2") // JP1-1&2 (PB5 & PB6) + PORT_DIPSETTING ( 0x00, "100%" ) + PORT_DIPSETTING ( 0x20, " 80%" ) + PORT_DIPSETTING ( 0x40, " 75%" ) + PORT_DIPSETTING ( 0x60, " 70%" ) + PORT_BIT( 0x8c, IP_ACTIVE_LOW, IPT_UNUSED ) + + PORT_START("SETTINGS") // The hidden functions and modes... + PORT_CONFNAME( 0x01, 0x01, "Game Mode" ) + PORT_CONFSETTING( 0x01, "Arcade" ) + PORT_CONFSETTING( 0x00, "Gamble" ) + PORT_CONFNAME( 0x02, 0x00, "Draw Cards Mode" ) + PORT_CONFSETTING ( 0x02, "Manual Set" ) + PORT_CONFSETTING ( 0x00, "Normal" ) + PORT_CONFNAME( 0x04, 0x00, "Game Timer" ) + PORT_CONFSETTING ( 0x04, "Disabled" ) + PORT_CONFSETTING ( 0x00, "Normal" ) + INPUT_PORTS_END /******************************************* -* Machine Start & Reset * +* Machine Start * *******************************************/ void truco_state::machine_start() { save_item(NAME(m_trigger)); -} - -void truco_state::machine_reset() -{ - // Setup the data on the battery backed RAM - - // IRQ check - m_battery_ram[0x002] = 0x51; - m_battery_ram[0x024] = 0x49; - m_battery_ram[0x089] = 0x04; - m_battery_ram[0x170] = 0x12; - m_battery_ram[0x1a8] = 0xd5; - - // mainloop check - m_battery_ram[0x005] = 0x04; - m_battery_ram[0x22b] = 0x46; - m_battery_ram[0x236] = 0xfb; - m_battery_ram[0x2fe] = 0x1d; - m_battery_ram[0x359] = 0x5a; - - // boot check - int a = (m_battery_ram[0x000] << 8) | m_battery_ram[0x001]; - - a += 0x4d2; - - m_battery_ram[0x01d] = (a >> 8) & 0xff; - m_battery_ram[0x01e] = a & 0xff; - m_battery_ram[0x020] = m_battery_ram[0x011]; -} - - -/******************************************* -* Interrupts Handling * -*******************************************/ - -INTERRUPT_GEN_MEMBER(truco_state::interrupt) -{ - // coinup - - if (m_coin->read() & 1) - { - if (m_trigger == 0) - { - device.execute().set_input_line(M6809_IRQ_LINE, HOLD_LINE); - m_trigger++; - } - } - else - m_trigger = 0; + m_nvram->set_base(m_ram->pointer(), m_ram->size()); } @@ -490,29 +565,32 @@ INTERRUPT_GEN_MEMBER(truco_state::interrupt) void truco_state::truco(machine_config &config) { constexpr XTAL MASTER_CLOCK = XTAL(12'000'000); // confirmed - constexpr XTAL CPU_CLOCK = MASTER_CLOCK / 16; // guess - constexpr XTAL CRTC_CLOCK = MASTER_CLOCK / 8; // guess + constexpr XTAL CPU_CLOCK = MASTER_CLOCK / 16; // confirmed + constexpr XTAL CRTC_CLOCK = MASTER_CLOCK / 8; // confirmed // basic machine hardware - M6809(config, m_maincpu, CPU_CLOCK); + MC6809E(config, m_maincpu, CPU_CLOCK); m_maincpu->set_addrmap(AS_PROGRAM, &truco_state::main_map); - m_maincpu->set_vblank_int("screen", FUNC(truco_state::interrupt)); - WATCHDOG_TIMER(config, m_watchdog).set_time(attotime::from_msec(1600)); // 1.6 seconds + WATCHDOG_TIMER(config, m_watchdog).set_time(attotime::from_msec(1600)); // 1.6 seconds + + RAM(config, m_ram).set_default_size("32K"); + NVRAM(config, m_nvram, nvram_device::DEFAULT_ALL_0); pia6821_device &pia(PIA6821(config, "pia0")); pia.readpa_handler().set_ioport("P1"); - pia.readpb_handler().set_ioport("JMPRS"); - pia.writepa_handler().set(FUNC(truco_state::porta_w)); + pia.readpb_handler().set_ioport("JUMPERS"); pia.writepb_handler().set(FUNC(truco_state::portb_w)); pia.ca2_handler().set(FUNC(truco_state::pia_ca2_w)); - pia.irqa_handler().set(FUNC(truco_state::pia_irqa_w)); - pia.irqb_handler().set(FUNC(truco_state::pia_irqb_w)); - + pia.readca1_handler().set(FUNC(truco_state::pia_ca1_r)); + pia.readcb1_handler().set(FUNC(truco_state::pia_cb1_r)); + pia.irqa_handler().set_inputline(m_maincpu, M6809_IRQ_LINE); + pia.irqb_handler().set_inputline(m_maincpu, M6809_IRQ_LINE); + // video hardware screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); screen.set_refresh_hz(60); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); // not accurate + screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); screen.set_size(256, 192); screen.set_visarea_full(); screen.set_screen_update(FUNC(truco_state::screen_update)); @@ -530,20 +608,25 @@ void truco_state::truco(machine_config &config) } -/*************************************************************************** - - Game driver(s) - -***************************************************************************/ +/******************************************* +* ROM Load * +*******************************************/ ROM_START( truco ) ROM_REGION( 0x10000, "maincpu", 0 ) ROM_LOAD( "truco.u3", 0x08000, 0x4000, CRC(4642fb96) SHA1(e821f6fd582b141a5ca2d5bd53f817697048fb81) ) ROM_LOAD( "truco.u2", 0x0c000, 0x4000, CRC(ff355750) SHA1(1538f20b1919928ffca439e4046a104ddfbc756c) ) + + ROM_REGION( 0x8000, "nvram", 0 ) // default NVRAM, otherwise the game doesn't boot + ROM_LOAD( "truco_nvram.bin", 0x0000, 0x8000, CRC(70dba1e7) SHA1(0a0b2f2a59b7167ffefe1ef4214ca1794d442e34) ) ROM_END } // anonymous namespace +/********************************************* +* Game Drivers * +*********************************************/ + // YEAR NAME PARENT MACHINE INPUT STATE INIT ROT COMPANY FULLNAME FLAGS GAME( 198?, truco, 0, truco, truco, truco_state, empty_init, ROT0, "Playtronic SRL", "Truco-Tron", MACHINE_SUPPORTS_SAVE )