From cdb5ca42c689e4f58e27124c14a4b0fd5a9d05ea Mon Sep 17 00:00:00 2001 From: Sandro Ronco Date: Thu, 11 Jun 2020 19:54:45 +0200 Subject: Hyperscan updates: [Sandro Ronco] - Added emulation of the SPG290 CDServo - Added joypad inputs - Added RFID card support - Split SPG290 PPU, Timers and I2C into separate devices - Added a softlist for the RFID cards --- hash/hyperscan_card.xml | 5488 ++++++++++++++++++++++++++++++++ scripts/src/machine.lua | 20 + scripts/target/mame/mess.lua | 5 + src/devices/cpu/score/score.cpp | 43 +- src/devices/machine/spg290_cdservo.cpp | 422 +++ src/devices/machine/spg290_cdservo.h | 75 + src/devices/machine/spg290_i2c.cpp | 147 + src/devices/machine/spg290_i2c.h | 46 + src/devices/machine/spg290_ppu.cpp | 563 ++++ src/devices/machine/spg290_ppu.h | 85 + src/devices/machine/spg290_timer.cpp | 156 + src/devices/machine/spg290_timer.h | 43 + src/mame/drivers/spg29x.cpp | 681 ++-- src/mame/machine/hyperscan_card.cpp | 275 ++ src/mame/machine/hyperscan_card.h | 58 + src/mame/machine/hyperscan_ctrl.cpp | 106 + src/mame/machine/hyperscan_ctrl.h | 31 + 17 files changed, 7741 insertions(+), 503 deletions(-) create mode 100644 hash/hyperscan_card.xml create mode 100644 src/devices/machine/spg290_cdservo.cpp create mode 100644 src/devices/machine/spg290_cdservo.h create mode 100644 src/devices/machine/spg290_i2c.cpp create mode 100644 src/devices/machine/spg290_i2c.h create mode 100644 src/devices/machine/spg290_ppu.cpp create mode 100644 src/devices/machine/spg290_ppu.h create mode 100644 src/devices/machine/spg290_timer.cpp create mode 100644 src/devices/machine/spg290_timer.h create mode 100644 src/mame/machine/hyperscan_card.cpp create mode 100644 src/mame/machine/hyperscan_card.h create mode 100644 src/mame/machine/hyperscan_ctrl.cpp create mode 100644 src/mame/machine/hyperscan_ctrl.h diff --git a/hash/hyperscan_card.xml b/hash/hyperscan_card.xml new file mode 100644 index 00000000000..ecee1f10428 --- /dev/null +++ b/hash/hyperscan_card.xml @@ -0,0 +1,5488 @@ + + + + + + + Ben 10: Ben Tennyson (Character) + 2006 + Mattel + + + + + + + + + + Ben 10: Four Arms (Character) + 2006 + Mattel + + + + + + + + + + Ben 10: Stinkfly (Character) + 2006 + Mattel + + + + + + + + + + Ben 10: Ripjaws (Character) + 2006 + Mattel + + + + + + + + + + Ben 10: XLR8 (Character) + 2006 + Mattel + + + + + + + + + + Ben 10: Heatblast (Character) + 2006 + Mattel + + + + + + + + + + Ben 10: Wildmutt (Character) + 2006 + Mattel + + + + + + + + + + Ben 10: Diamondhead (Character) + 2006 + Mattel + + + + + + + + + + Ben 10: Ghostfreak (Character) + 2006 + Mattel + + + + + + + + + + Ben 10: Grey Matter (Character) + 2006 + Mattel + + + + + + + + + + Ben 10: Upgrade (Character) + 2006 + Mattel + + + + + + + + + + Ben 10: Shardblaster (Projectile Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Laser Wave (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Prismforce (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Crystal Shield (Defense Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Flamethrower (Projectile Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Thermostat (Speed Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Blast Furnace (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Firewall (Defense Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Razor Quills (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Feral Slashes (Speed Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Berzerker (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Sixth Sense (Defense Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Soul Sink (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Ectoslaught (Speed Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Spectral Shriek (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Fade Out (Defense Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: High Jump (Power Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Mini-Max (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Bounce Back (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Shrink Wrap (Defense Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Fliptail (Power Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Dive Bomb (Speed Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Bite Radius (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Scale Armor (Defense Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Nano Blast (Projectile Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Overclock (Speed Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Binary Blaster (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Diffuse (Defense Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Big Smack (Power Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Thunderclap (Speed Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Juggernaut (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Behemoth (Defense Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Goo Sting (Projectile Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Hive Mind (Speed Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Hyper Wing (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Stink Swarm (Defense Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Static Boom (Projectile Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Turbo Charge (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Gear Shift (Attack Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Spin Out (Defense Mod) + 2006 + Mattel + + + + + + + + + + Ben 10: Rust Belt (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Metal Fatigue (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Harpoon (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Deep Six (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: All Thumbs (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Flame Out (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Brain Drain (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Bio-Feedback (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Hyp-no! (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Reverse Psychology (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Snail Trail (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Surface Tension (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Hexa-Gone (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Smoke and Mirrors (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Short Circuit (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Ground Swell (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Shell Shock (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Out Claw (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Gravity Pull (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Astro-Nought (Villain Defense) + 2006 + Mattel + + + + + + + + + + Ben 10: Grandpa Max (Help) + 2006 + Mattel + + + + + + + + + + Ben 10: Gwen (Help) + 2006 + Mattel + + + + + + + + + + Ben 10: Four Arms (Ultimate) + 2006 + Mattel + + + + + + + + + + Ben 10: Stinkfly (Ultimate) + 2006 + Mattel + + + + + + + + + + Ben 10: Ripjaws (Ultimate) + 2006 + Mattel + + + + + + + + + + Ben 10: XLR8 (Ultimate) + 2006 + Mattel + + + + + + + + + + Ben 10: Heatblast (Ultimate) + 2006 + Mattel + + + + + + + + + + Ben 10: Wildmutt (Ultimate) + 2006 + Mattel + + + + + + + + + + Ben 10: Diamondhead (Ultimate) + 2006 + Mattel + + + + + + + + + + Ben 10: Ghostfreak (Ultimate) + 2006 + Mattel + + + + + + + + + + Ben 10: Grey Matter (Ultimate) + 2006 + Mattel + + + + + + + + + + Ben 10: Upgrade (Ultimate) + 2006 + Mattel + + + + + + + + + + + Ben 10: Omnicharge (Ultimate) + 2006 + Mattel + + + + + + + + + + + Ben 10: Backpack (Ultimate) + 2006 + Mattel + + + + + + + + + + IWL: Galacto The Magnificent (Character) + 2006 + Mattel + + + + + + + + + + IWL: Canned Heat (Character) + 2006 + Mattel + + + + + + + + + + IWL: Pan Quantum Duae (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Hercules Quantum Duae (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Aroma Borealis (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Pie in the Eye (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Growler da Pirate (Character) + 2006 + Mattel + + + + + + + + + + IWL: Lobstar (Character) + 2006 + Mattel + + + + + + + + + + IWL: Gibbonator (Character) + 2006 + Mattel + + + + + + + + + + IWL: Billy Ray The Evil Twins (Character) + 2006 + Mattel + + + + + + + + + + IWL: Uber Tuber (Character) + 2006 + Mattel + + + + + + + + + + IWL: The Mad Protoplasm (Character) + 2006 + Mattel + + + + + + + + + + IWL: Ultimate The Mad Protoplasm (Ultimate) + 2006 + Mattel + + + + + + + + + + IWL: Ultimate Gibbonator (Ultimate) + 2006 + Mattel + + + + + + + + + + IWL: Ultimate Galacto The Magnificent (Ultimate) + 2006 + Mattel + + + + + + + + + + IWL: Ultimate Canned Heat (Ultimate) + 2006 + Mattel + + + + + + + + + + IWL: Ultimate Billy Ray The Evil Twins (Ultimate) + 2006 + Mattel + + + + + + + + + + IWL: The Poser (Finishing) + 2006 + Mattel + + + + + + + + + + IWL: The Asimov (Finishing) + 2006 + Mattel + + + + + + + + + + IWL: Mercury Quantum Duae (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Atlas Quantum Duae (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Apollo Quantum Duae (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Unum Atlas Daum (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Mercollo (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Max Hercules Meyiotos (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Max Pan Meyiotos (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: El Mas Loco (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Metal Folding Chair Launcher (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Blinded by the Light (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Venus di Meltdown (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Vigor Trigger (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Can't Touch This (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: ACME Special Delivery (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Roid Rager (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Rain of Pain (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Jacob's Ladder (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Bad Dentist (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: The Milky Wake (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Black Hole (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Galaxy Shifter (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Interstellar Ka-Boom (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Caraba Chaba (Battle Mod) + 2006 + Mattel + + + + + + + + + + IWL: Express Delivery (Finishing) + 2006 + Mattel + + + + + + + + + + IWL: The Moon Shiner (Finishing) + 2006 + Mattel + + + + + + + + + + IWL: Davey Jones Locker (Finishing) + 2006 + Mattel + + + + + + + + + + IWL: The Banana Split (Finishing) + 2006 + Mattel + + + + + + + + + + IWL: The Freedom Fryer (Finishing) + 2006 + Mattel + + + + + + + + + + IWL: The Ecto-Squeeze (Finishing) + 2006 + Mattel + + + + + + + + + + IWL: Max Mercury Meyiotos (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Panules (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Unum Herculaum (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Unum Pan Daum (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Atlury (Game Mod) + 2006 + Mattel + + + + + + + + + + IWL: Tria Pan 3 (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Orion's Belt (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Planet Crusher (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: The Force... To Be Reckoned With (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Unum Apollo Daum (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Unum Mercury Daum (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Tria Hercules 3 (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Tria Apollo 3 (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Tria Mercury 3 (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Tria Atlas 3 (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Max Apollo Meyiotos (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Max Atlas Meyiotos (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Apocules (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Merculon (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Atules (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Atollus (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Panollo (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Panury (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Panlas (Game Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Star Gazer (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Cosmonut Cracker (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Warp Pile Driver (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Cosmic Crush (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Laser Eyeballs (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Tortoise (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Wise Guy (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Doll of Cement (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Jupiter Juice (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: The Foot of Ra (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Slap of 1000 Hands (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Mercury Heater (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: The Cleaner (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Arrffin' Annie The Chupacabra (Character) + 2006 + Mattel + + + + + + + + + + + IWL: Mandible (Character) + 2006 + Mattel + + + + + + + + + + + IWL: Matsumo Clodsan (Character) + 2006 + Mattel + + + + + + + + + + + IWL: Balthazaar The Bash-ful (Character) + 2006 + Mattel + + + + + + + + + + + IWL: The Fossil (Character) + 2006 + Mattel + + + + + + + + + + + IWL: Brother Beardsly (Character) + 2006 + Mattel + + + + + + + + + + + IWL: The Big Kahuna (Character) + 2006 + Mattel + + + + + + + + + + + IWL: Ultimate Arrffin' Annie The Chupacabra (Ultimate) + 2006 + Mattel + + + + + + + + + + + IWL: Ultimate Mandible (Ultimate) + 2006 + Mattel + + + + + + + + + + + IWL: Ultimate Matsumo Clodsan (Ultimate) + 2006 + Mattel + + + + + + + + + + + IWL: Ultimate Balthazaar The Bash-ful (Ultimate) + 2006 + Mattel + + + + + + + + + + + IWL: Ultimate Fossil (Ultimate) + 2006 + Mattel + + + + + + + + + + + IWL: Ultimate Brother Beardsly (Ultimate) + 2006 + Mattel + + + + + + + + + + + IWL: The Mutilator (Finishing) + 2006 + Mattel + + + + + + + + + + + IWL: A Plight of Fists (Finishing) + 2006 + Mattel + + + + + + + + + + + IWL: Eat My Dust (Finishing) + 2006 + Mattel + + + + + + + + + + + IWL: The Deadly Cream Pie (Finishing) + 2006 + Mattel + + + + + + + + + + + IWL: The Saber Tooth Cave Painting (Finishing) + 2006 + Mattel + + + + + + + + + + + IWL: The Dragon Bucket (Finishing) + 2006 + Mattel + + + + + + + + + + + IWL: Humuhumunukunuku Apua'a (Finishing) + 2006 + Mattel + + + + + + + + + + + IWL: Ultimate Lobstar (Character) + 2006 + Mattel + + + + + + + + + + + IWL: Ultimate Growler da Pirate (Character) + 2006 + Mattel + + + + + + + + + + + IWL: Ultimate Big Kahuna (Character) + 2006 + Mattel + + + + + + + + + + + IWL: Light Speed (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Rocket Boots (Battle Mod) + 2006 + Mattel + + + + + + + + + + + IWL: Aroma Borealis 2 (Battle Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Spider-Man (Character) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Captain America (Character) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Hulk (Character) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Thor (Character) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Wolverine (Character) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Human Torch (Character) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Iron Man (Character) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Storm (Character) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Elektra (Character) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Thing (Character) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Daredevil (Character) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Municipal Mayhem (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Jungle Tech (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Mount Fury (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Space-Station Omega (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Rat House Rumble (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Dread Field (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Techno Terror (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Chaos Laboratories (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Desolation Flats (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Target X (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Wretched Acres (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Back-Alley Bust Up (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Drab Town (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Scraps (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Fire Island Station (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Cavern Clash (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Force Factor (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Vanguard Forest (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Mountain Meltdown (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Wastes of Warfare (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Last Chance Bog (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Tunnels of Terror (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Lightning Ridge (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Biotronic (Area Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Mystery (Atmosphere Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Witching Hour (Atmosphere Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Thunderhead (Atmosphere Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Thick Soup (Atmosphere Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Snow Squall (Atmosphere Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Heat Wave (Atmosphere Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Below Zero (Atmosphere Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Gale Force (Atmosphere Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Doctor Doom (Boss Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Magneto (Boss Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Ultron (Boss Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Thanos (Boss Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Doctor Octopus (Boss Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Baron Zemo (Boss Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Venom (Villain Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Bullseye (Villain Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Hobgoblin (Villain Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Spiral (Villain Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Loki (Villain Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Lady Deathstrike (Villain Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Klaw (Villain Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Whirlwind (Villain Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Omega Red (Villain Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: The Owl (Villain Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Spider-Man Challenge (Story Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Captain America Challenge (Story Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Hulk Challenge (Story Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Thor Challenge (Story Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Wolverine Challenge (Story Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Human Torch Challenge (Story Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Iron Man Challenge (Story Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Storm Challenge (Story Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Elektra Challenge (Story Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Thing Challenge (Story Mod) + 2006 + Mattel + + + + + + + + + + Marvel Heroes: Daredevil Challenge (Story Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Spider-Man (Character) + 2006 + Mattel + + + + + + + + + + Spiderman: Black Widow (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Attitude Adjustment (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Fly Paper (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Daddy Long Legs (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Web Fluid (Arsenal Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Spider Bite (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: The Tarantula (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Trap Door Spider (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Octattack (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: The Bowling Ball (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Jumping Spider (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Goo Hammer (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Disguised (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Bad Habit (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Up And Away (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Shaky Ground (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Snap Back (Black Mod Suit) + 2006 + Mattel + + + + + + + + + + Spiderman: Black Flail (Black Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Spider Shield (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Super Slinger (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Spidey Sense (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Web O Mondo (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Slow Motion (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Air Evac (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Tuffanuff (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Arachnophobia (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Hang 'em High (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Safety Net (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Trip Web (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Camouflage (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Divine Reflex (Red Suit Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Sonic Drubbing (Enemy Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Tritium Card (Enemy Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Disintegrator (Enemy Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Spider Agility (Enemy Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Web of Steel (Enemy Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Ego Boost (Enemy Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Guilt Trip (Enemy Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: EZ Does It (Enemy Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Big Apple 1 (Mission Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Big Apple 2 (Mission Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Big Apple 3 (Mission Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Big Apple 4 (Mission Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Big Apple 5 (Mission Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Invincibility (Arsenal Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Spider Speed (Arsenal Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Super Strength (Arsenal Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Health Drink (Arsenal Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Stopwatch (Arsenal Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Web Flurry (Arsenal Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Light As A Feather (FX Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Super Jumper (FX Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Parade Route (FX Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Wacky Noises (FX Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Time Twist (FX Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Daily Bugle (FX Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Sound Mode (FX Mod) + 2006 + Mattel + + + + + + + + + + Spiderman: Quick Learner (Enemy Mod) + 2006 + Mattel + + + + + + + + + + + Spiderman: Comic Book Mode (FX Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Wolverine (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Lady Deathstrike (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Adamantium Claws (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Big Chill (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Cyborg Assault (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Strength Room (Danger Room) + 2006 + Mattel + + + + + + + + + + X-Men: Ultimate Wolverine (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Storm (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Cyclops (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Iceman (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Jean Grey/Phoenix (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Magneto (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Ultimate Jean Grey/Phoenix (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Mystique (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Omega Red (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Blob (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Adamantium Mayhem (Finishing Move) + 2006 + Mattel + + + + + + + + + + X-Men: Sun Burst (Finishing Move) + 2006 + Mattel + + + + + + + + + + X-Men: Devastating Optic Blast (Finishing Move) + 2006 + Mattel + + + + + + + + + + X-Men: Super Freeze (Finishing Move) + 2006 + Mattel + + + + + + + + + + X-Men: Mental Bolt (Finishing Move) + 2006 + Mattel + + + + + + + + + + X-Men: Shrapnel (Finishing Move) + 2006 + Mattel + + + + + + + + + + X-Men: Spinning Death (Finishing Move) + 2006 + Mattel + + + + + + + + + + X-Men: Rapid Fire Destruction (Finishing Move) + 2006 + Mattel + + + + + + + + + + X-Men: Lethal Injection (Finishing Move) + 2006 + Mattel + + + + + + + + + + X-Men: Gravity Press (Finishing Move) + 2006 + Mattel + + + + + + + + + + X-Men: Accelerated Healing (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Thunder n' Lightning (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Hover Hold (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Vapor-eyes (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Cool Head (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Below Zero (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Telepathic Touch (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Psychic Shield (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Metallic Mayhem (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Magnetic Maneuver (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Adamantium Skeleton (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Morph Queen (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Shapely Shifting (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Toxic Tentacles (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Red Guard (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Unstoppable Force (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Superhuman Resistant (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Projectile Shield (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Auto Duck (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Resurrect (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Melee Shield (Defense Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Triple Strike (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Half as Nice (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Projectile Vengeance (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Melee Vengeance (Attack Mod) + 2006 + Mattel + + + + + + + + + + X-Men: Professor X (Character) + 2006 + Mattel + + + + + + + + + + X-Men: Durability Room (Danger Room) + 2006 + Mattel + + + + + + + + + + X-Men: Speed Room (Danger Room) + 2006 + Mattel + + + + + + + + + + X-Men: Intelligence Room (Danger Room) + 2006 + Mattel + + + + + + + + + + X-Men: Fighting Skills Room (Danger Room) + 2006 + Mattel + + + + + + + + + + X-Men: Energy Projection Room (Danger Room) + 2006 + Mattel + + + + + + + + + + + X-Men: Gambit (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Colossus (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Nightcrawler (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Rogue (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Beast (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Juggernaut (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Toad (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Sabretooth (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Sabretooth (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Scarlet Witch (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Sentinel (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Death Dealer (Attack Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Kinetic Cover (Defense Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Brutal Force (Attack Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Steel-like Skin (Defense Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Teleportation (Attack Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Escape Artist (Defense Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Absorption (Attack Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Escape Flight (Defense Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Real McCoy (Attack Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Passive Aggression (Defense Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Power of Cyttorak (Attack Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Armored Helmet (Defense Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Amphibian Assault (Attack Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Goop Swoop (Defense Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Killer Instinct (Attack Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Rapid Recovery (Defense Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Chaos Magick (Attack Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Scarlet Leather (Defense Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Mutant Extermination (Attack Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Adaptive Mode (Defense Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: 52 Card Slice (Finishing Move) + 2006 + Mattel + + + + + + + + + + + X-Men: Power Driver (Finishing Move) + 2006 + Mattel + + + + + + + + + + + X-Men: Tele-Driver Spin (Finishing Move) + 2006 + Mattel + + + + + + + + + + + X-Men: Total Drain (Finishing Move) + 2006 + Mattel + + + + + + + + + + + X-Men: Irresistible Force (Finishing Move) + 2006 + Mattel + + + + + + + + + + + X-Men: Head Crush (Finishing Move) + 2006 + Mattel + + + + + + + + + + + X-Men: Toxic Spew (Finishing Move) + 2006 + Mattel + + + + + + + + + + + X-Men: Throat-Rip (Finishing Move) + 2006 + Mattel + + + + + + + + + + + X-Men: Thermonuclear Holocaust (Finishing Move) + 2006 + Mattel + + + + + + + + + + + X-Men: Dead Man's Hands (Finishing Move) + 2006 + Mattel + + + + + + + + + + + X-Men: Super Shield (Defense Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Auto Jump (Defense Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Reflective Mode (Attack Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Super Speed (Attack Mod) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Storm (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Cyclops (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Gambit (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Colossus (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Nightcrawler (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Iceman (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Rogue (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Beast (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Magneto (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Juggernaut (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Toad (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Mystique (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Lady Deathstrike (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Scarlet Witch (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Omega Red (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Blob (Character) + 2006 + Mattel + + + + + + + + + + + X-Men: Ultimate Sentinel (Character) + 2006 + Mattel + + + + + + + + diff --git a/scripts/src/machine.lua b/scripts/src/machine.lua index 621009924f9..266dec7fd49 100644 --- a/scripts/src/machine.lua +++ b/scripts/src/machine.lua @@ -2907,6 +2907,26 @@ if (MACHINES["SPG2XX"]~=null) then } end +--------------------------------------------------- +-- +--@src/devices/machine/spg290_cdservo.h,MACHINES["SPG290"] = true +--@src/devices/machine/spg290_timer.h,MACHINES["SPG290"] = true +--@src/devices/machine/spg290_i2c.h,MACHINES["SPG290"] = true +--@src/devices/machine/spg290_ppu.h,MACHINES["SPG290"] = true +--------------------------------------------------- + +if (MACHINES["SPG290"]~=null) then + files { + MAME_DIR .. "src/devices/machine/spg290_cdservo.cpp", + MAME_DIR .. "src/devices/machine/spg290_cdservo.h", + MAME_DIR .. "src/devices/machine/spg290_timer.cpp", + MAME_DIR .. "src/devices/machine/spg290_timer.h", + MAME_DIR .. "src/devices/machine/spg290_i2c.cpp", + MAME_DIR .. "src/devices/machine/spg290_i2c.h", + MAME_DIR .. "src/devices/machine/spg290_ppu.cpp", + MAME_DIR .. "src/devices/machine/spg290_ppu.h", + } +end --------------------------------------------------- -- --@src/devices/machine/stvcd.h,MACHINES["STVCD"] = true diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index d31ada36c32..08b3e2c96ff 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -650,6 +650,7 @@ MACHINES["SMIOC"] = true MACHINES["SEGA_SCU"] = true MACHINES["SMPC"] = true MACHINES["SPG2XX"] = true +MACHINES["SPG290"] = true MACHINES["STVCD"] = true MACHINES["SUN4C_MMU"] = true MACHINES["SWTPC8212"] = true @@ -3976,6 +3977,10 @@ files { MAME_DIR .. "src/mame/drivers/spg2xx_smarttv.cpp", MAME_DIR .. "src/mame/includes/spg2xx.h", MAME_DIR .. "src/mame/drivers/spg29x.cpp", + MAME_DIR .. "src/mame/machine/hyperscan_card.cpp", + MAME_DIR .. "src/mame/machine/hyperscan_card.h", + MAME_DIR .. "src/mame/machine/hyperscan_ctrl.cpp", + MAME_DIR .. "src/mame/machine/hyperscan_ctrl.h", MAME_DIR .. "src/mame/drivers/spg29x_lexibook_jg7425.cpp", MAME_DIR .. "src/mame/drivers/generalplus_gpl16250.cpp", MAME_DIR .. "src/mame/drivers/generalplus_gpl16250_rom.cpp", diff --git a/src/devices/cpu/score/score.cpp b/src/devices/cpu/score/score.cpp index a8666ac5828..0e306b55349 100644 --- a/src/devices/cpu/score/score.cpp +++ b/src/devices/cpu/score/score.cpp @@ -5,6 +5,12 @@ Sunplus Technology S+core by Sandro Ronco + TODO: + - unemulated opcodes + - irq priority + - instruction cycles + - cache + ******************************************************************************/ #include "emu.h" @@ -201,7 +207,7 @@ void score7_cpu_device::execute_run() break; } - m_icount -= 3; // FIXME: if available use correct cycles per instructions + m_icount -= 6; // FIXME: if available use correct cycles per instructions } while (m_icount > 0); } @@ -213,19 +219,13 @@ void score7_cpu_device::execute_run() void score7_cpu_device::execute_set_input(int inputnum, int state) { - switch (inputnum) + if (state) { - case 0: - if(state) + standard_irq_callback(inputnum); + if (inputnum > 0 && inputnum < 64) { - int vector = standard_irq_callback(0); - if (vector > 0 && vector < 64) - { - if((REG_PSR & 0x01) && state) - m_pending_interrupt[vector] = true; - } + m_pending_interrupt[inputnum] = true; } - break; } } @@ -276,7 +276,7 @@ bool score7_cpu_device::check_condition(uint8_t bc) int32_t score7_cpu_device::sign_extend(uint32_t data, uint8_t len) { - data &= (1 << len) - 1; + data &= (1ULL << len) - 1; uint32_t sign = 1 << (len - 1); return (data ^ sign) - sign; } @@ -1149,6 +1149,18 @@ void score7_cpu_device::op_rform1() case 0x05: // t! SET_T(check_condition(rd)); break; + case 0x08: // sll! + m_gpr[rd] = m_gpr[rd] << (m_gpr[ra] & 0x1f); + break; + case 0x09: // addc! + m_gpr[rd] = m_gpr[rd] + m_gpr[ra] + GET_C; + break; + case 0x0a: // srl! + m_gpr[rd] = m_gpr[rd] >> (m_gpr[ra] & 0x1f); + break; + case 0x0b: // sra! + m_gpr[rd] = sign_extend(m_gpr[rd] >> (m_gpr[ra] & 0x1f), 32 - (m_gpr[ra] & 0x1f)); + break; case 0x0c: // brl! if (check_condition_branch(rd)) { @@ -1275,7 +1287,12 @@ void score7_cpu_device::op_iform1a() switch(GET_I16_FUNC3(m_op)) { case 0x00: // addei! - unemulated_op("addei!"); + if (imm5 & 0x10) + m_gpr[rd] -= 1 << (imm5 & 0xf); + else + m_gpr[rd] += 1 << (imm5 & 0xf); + + // condition flags are invalid after this instruction break; case 0x01: // slli! m_gpr[rd] <<= imm5; diff --git a/src/devices/machine/spg290_cdservo.cpp b/src/devices/machine/spg290_cdservo.cpp new file mode 100644 index 00000000000..53415f093b5 --- /dev/null +++ b/src/devices/machine/spg290_cdservo.cpp @@ -0,0 +1,422 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco +/***************************************************************************** + + SPG290 CD Servo + +*****************************************************************************/ + +#include "emu.h" +#include "spg290_cdservo.h" +#include "coreutil.h" + + +#define SPG290_LEADIN_LEN 7500 +#define SPG290_LEADOUT_LEN 6750 + + +DEFINE_DEVICE_TYPE(SPG290_CDSERVO, spg290_cdservo_device, "spg290_cdservo", "SPG290 CDServo HLE") + + +spg290_cdservo_device::spg290_cdservo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SPG290_CDSERVO, tag, owner, clock) + , m_cdrom(*this, finder_base::DUMMY_TAG) + , m_irq_cb(*this) + , m_space_write_cb(*this) +{ +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void spg290_cdservo_device::device_start() +{ + m_irq_cb.resolve_safe(); + m_space_write_cb.resolve_safe(); + + m_cdtimer = timer_alloc(); + m_dsp_memory = std::make_unique(0x10000); + + save_item(NAME(m_addr)); + save_item(NAME(m_data)); + save_item(NAME(m_buf_start)); + save_item(NAME(m_buf_end)); + save_item(NAME(m_buf_ptr)); + save_item(NAME(m_speed)); + save_item(NAME(m_seek_min)); + save_item(NAME(m_seek_sec)); + save_item(NAME(m_seek_frm)); + save_item(NAME(m_seek_lba)); + save_item(NAME(m_sector_size)); + save_item(NAME(m_dsp_data)); + save_item(NAME(m_frame_found)); + save_item(NAME(m_control1)); + save_item(NAME(m_skip)); + save_item(NAME(m_dsp_regs)); + save_item(NAME(m_tot_sectors)); + save_item(NAME(m_cur_sector)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void spg290_cdservo_device::device_reset() +{ + m_addr = 0; + m_data = 0; + m_buf_start = 0; + m_buf_end = 0; + m_buf_ptr = 0; + m_speed = 1; + m_seek_min = 0; + m_seek_sec = 0; + m_seek_frm = 0; + m_seek_lba = 0; + m_sector_size = 0; + m_dsp_data = 0; + m_frame_found = false; + m_control1 = 0; + m_skip = 0; + + std::fill(std::begin(m_dsp_regs), std::end(m_dsp_regs), 0); + std::fill_n(m_dsp_memory.get(), 0x10000, 0); + + m_tot_sectors = 0; + m_cur_sector = 0; + m_qsub = nullptr; + + m_irq_cb(CLEAR_LINE); + + // generate Q subchannel + if (m_cdrom.found()) + { + auto *cdrom = m_cdrom->get_cdrom_file(); + if (cdrom != nullptr) + generate_qsub(cdrom); + } + + change_status(); +} + +void spg290_cdservo_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + if (!(m_control1 & 0x04) && m_cur_sector == m_seek_lba + SPG290_LEADIN_LEN) + { + uint8_t cdbuf[2448] = { 0 }; + + if (BIT(m_control0, 15)) // CDDA + { + cdrom_read_data(m_cdrom->get_cdrom_file(), m_cur_sector - 150 - SPG290_LEADIN_LEN, cdbuf, CD_TRACK_AUDIO); + + for (int i=0; i<2352; i++) + { + m_space_write_cb(m_buf_ptr++, cdbuf[i]); + if (m_buf_ptr > m_buf_end) + m_buf_ptr = m_buf_start; + } + } + else + { + cdrom_read_data(m_cdrom->get_cdrom_file(), m_cur_sector - 150 - SPG290_LEADIN_LEN, cdbuf, CD_TRACK_MODE1_RAW); + + // FIXME: this is required for load iso images + if (cdrom_get_track_type(m_cdrom->get_cdrom_file(), m_qsub[m_cur_sector * 12 + 1] - 1) == CD_TRACK_MODE1) + { + int lba = (bcd_2_dec(cdbuf[12]) * 60 + bcd_2_dec(cdbuf[13])) * 75 + bcd_2_dec(cdbuf[14]); + uint32_t msf = lba_to_msf(lba + 150); + cdbuf[12] = (msf >> 16) & 0xff; + cdbuf[13] = (msf >> 8) & 0xff; + cdbuf[14] = (msf >> 0) & 0xff; + } + + for (int i=0; i m_buf_end) + m_buf_ptr = m_buf_start; + } + } + + m_seek_lba++; + m_frame_found = true; + m_irq_cb(ASSERT_LINE); + } + + if (m_cur_sector < m_seek_lba + SPG290_LEADIN_LEN and m_cur_sector < m_tot_sectors) + m_cur_sector++; +} + +uint32_t spg290_cdservo_device::read(offs_t offset, uint32_t mem_mask) +{ + switch (offset << 2) + { + case 0x08: + return m_data; // CD servo DSP reply + case 0x0c: + return 0; // CD servo ready + case 0x40: + return m_control0; + case 0x44: + return m_control1; + case 0x48: + return m_seek_min; + case 0x4c: + return m_seek_sec; + case 0x50: + return m_seek_frm; + case 0x54: + return 0; // sector CRC error flags + case 0x60: + return m_buf_start; + case 0x64: + return m_buf_end; + case 0x68: + return m_buf_ptr; + case 0x6c: + return m_sector_size; + default: + logerror("[%s] %s: unknown read %x\n", tag(), machine().describe_context(), offset << 2); + } + + return 0; +} + +void spg290_cdservo_device::write(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + switch (offset << 2) + { + case 0x04: // CD servo DSP command + COMBINE_DATA(&m_addr); + break; + case 0x08: // CD servo DSP data + COMBINE_DATA(&m_data); + break; + case 0x0c: // CD servo DSP exec + if (ACCESSING_BITS_0_7) + { + if (data & 1) + servo_cmd_r(); + else + servo_cmd_w(); + } + break; + case 0x40: + COMBINE_DATA(&m_control0); + break; + case 0x44: + COMBINE_DATA(&m_control1); + m_seek_lba = (bcd_2_dec(m_seek_min) * 60 + bcd_2_dec(m_seek_sec)) * 75 + bcd_2_dec(m_seek_frm); + m_cur_sector = SPG290_LEADIN_LEN + m_seek_lba; // TODO: seek time + break; + case 0x48: + if (ACCESSING_BITS_0_7) + m_seek_min = data; + break; + case 0x4c: + if (ACCESSING_BITS_0_7) + m_seek_sec = data; + break; + case 0x50: + if (ACCESSING_BITS_0_7) + m_seek_frm = data; + break; + case 0x60: + COMBINE_DATA(&m_buf_start); + break; + case 0x54: + break; + case 0x64: + COMBINE_DATA(&m_buf_end); + break; + case 0x68: + COMBINE_DATA(&m_buf_ptr); + break; + case 0x6c: + COMBINE_DATA(&m_sector_size); + break; + default: + logerror("[%s] %s: unknown write %x = %x\n", tag(), machine().describe_context(), offset << 2, data); + } +} + +void spg290_cdservo_device::servo_cmd_r() +{ + if (m_addr == 0x079) + m_data = 0xe3; // servo status + else if (m_addr == 0x07b) + m_data = 0x06; // unknown, should be in the range 4-7 + else if (m_addr == 0x07c) + m_data = m_dsp_data >> 8; + else if (m_addr == 0x07d) + m_data = m_dsp_data; + else if (m_addr == 0x082) + m_data = 0x04; + else if (m_addr == 0x083) + m_data = machine().rand() & 0xff; + else if (m_addr == 0x307) + m_data = m_frame_found; + else if (m_addr >= 0x340 && m_addr <= 0x349) // read Q subchannel + m_data = m_qsub[m_cur_sector * 12 + (m_addr & 0x0f)]; + else if (m_addr == 0x34c) + m_data = 0x40; // Q subchannel ready + else if (m_addr == 0x506) + m_data = 0x04; // DSP ready + else if (m_addr >= 0x500 && m_addr < 0x50a) + m_data = m_dsp_regs[m_addr & 0x0f]; + else if (m_addr == 0x41f) + m_data = 0xff; // if zero cause servo timeout + else + m_data = 0; +} + + +void spg290_cdservo_device::servo_cmd_w() +{ + if (m_addr == 0x013) // skip n sectors + { + if (m_data & 0x01) + m_cur_sector += (m_data & 0x10) ? -m_skip : m_skip; + + if (m_cur_sector < 0) m_cur_sector = 0; + if (m_cur_sector >= m_tot_sectors) m_cur_sector = m_tot_sectors - 1; + } + else if (m_addr == 0x020) // speed + { + if (m_speed != 1 << (m_data & 0x03)) + { + m_speed = 1 << (m_data & 0x03); + change_status(); + } + } + else if (m_addr == 0x030) // Disc ID + { + // < 10 no disc + // < 97 CD-RW + // >= 97 CD-ROM + if (m_data == 0x13) + m_dsp_data = 8; + else + m_dsp_data = m_qsub ? 100 : 0; + } + else if (m_addr == 0x032) // DSP version + m_dsp_data = 0x0102; + else if (m_addr == 0x19a) + m_skip = (m_skip & 0x00ff) | (m_data << 8); + else if (m_addr == 0x29a) + m_skip = (m_skip & 0xff00) | m_data; + else if (m_addr == 0x307) + m_frame_found = false; + else if (m_addr == 0x505) // DSP memory + { + if ((m_data & 0x0f) == 0x02) // write + { + // maincpu upload the DSP code in 3 byte chunks + uint16_t addr = (m_dsp_regs[0] << 8) | m_dsp_regs[1]; + m_dsp_memory[addr] = (m_dsp_regs[2] << 16) | (m_dsp_regs[3] << 8) | m_dsp_regs[4]; + } + else if ((m_data & 0x0f) == 0x03) // read + { + uint16_t addr = (m_dsp_regs[0] << 8) | m_dsp_regs[1]; + m_dsp_regs[7] = (m_dsp_memory[addr] >> 16) & 0xff; + m_dsp_regs[8] = (m_dsp_memory[addr] >> 8) & 0xff; + m_dsp_regs[9] = (m_dsp_memory[addr] >> 0) & 0xff; + } + } + else if (m_addr >= 0x500 && m_addr < 0x50a) + m_dsp_regs[m_addr & 0x0f] = m_data; +} + + +void spg290_cdservo_device::change_status() +{ + if (m_speed == 0 || !m_cdrom.found() || !m_cdrom->get_cdrom_file()) + m_cdtimer->adjust(attotime::never); + else + m_cdtimer->adjust(attotime::from_hz(75 * m_speed), 0, attotime::from_hz(75 * m_speed)); +} + +void spg290_cdservo_device::add_qsub(int sector, uint8_t addrctrl, uint8_t track, uint8_t index, uint32_t rel_msf, uint32_t abs_msf, uint16_t crc16) +{ + uint8_t *dest = m_qsub.get() + sector * 12; + dest[0] = ((addrctrl & 0x0f) << 4) | ((addrctrl & 0xf0) >> 4); + dest[1] = track; + dest[2] = index; + dest[3] = rel_msf >> 16; + dest[4] = rel_msf >> 8; + dest[5] = rel_msf; + dest[6] = 0; + dest[7] = abs_msf >> 16; + dest[8] = abs_msf >> 8; + dest[9] = abs_msf; + dest[10] = crc16 >> 8; + dest[11] = crc16; +} + +void spg290_cdservo_device::generate_qsub(cdrom_file *cdrom) +{ + const cdrom_toc *toc = cdrom_get_toc(cdrom); + int numtracks = cdrom_get_last_track(cdrom); + uint32_t total_sectors = cdrom_get_track_start(cdrom, numtracks - 1) + toc->tracks[numtracks - 1].frames + 150; + + m_tot_sectors = SPG290_LEADIN_LEN + total_sectors + SPG290_LEADOUT_LEN; + m_qsub = std::make_unique(m_tot_sectors * 12); + + int lba = 0; + + // 7500 sectors lead-in + for (int s=0; s < SPG290_LEADIN_LEN; s += numtracks + 3) + { + if (lba < SPG290_LEADIN_LEN) add_qsub(lba++, 0x14, 0, 0xa0, lba_to_msf(s + 0), 1 << 16); // first track number + if (lba < SPG290_LEADIN_LEN) add_qsub(lba++, 0x14, 0, 0xa1, lba_to_msf(s + 1), numtracks << 16); // last track number + if (lba < SPG290_LEADIN_LEN) add_qsub(lba++, 0x14, 0, 0xa2, lba_to_msf(s + 2), lba_to_msf(total_sectors)); // start time of lead-out + + for(int track = 0; track < numtracks; track++) + { + uint32_t track_start = cdrom_get_track_start(cdrom, track) + 150; + if (lba < SPG290_LEADIN_LEN) + add_qsub(lba++, cdrom_get_adr_control(cdrom, track), 0, dec_2_bcd(track + 1), lba_to_msf(s + 3 + track), lba_to_msf(track_start)); + } + } + + // data tracks + for(int track = 0; track < numtracks; track++) + { + uint32_t control = cdrom_get_adr_control(cdrom, track); + uint32_t track_start = cdrom_get_track_start(cdrom, track); + + // pregap + uint32_t pregap = toc->tracks[track].pregap; + + // first track should have a 150 frames pregap + if (track == 0 && toc->tracks[0].pregap == 0) + pregap = 150; + else if (track != 0 && toc->tracks[0].pregap == 0) + track_start += 150; + + for(int s = 0; s < pregap; s++) + add_qsub(lba++, control, dec_2_bcd(track + 1), 0, lba_to_msf(s), lba_to_msf(track_start + s)); + + track_start += pregap; + + for(int s = 0; s < toc->tracks[track].frames; s++) + { + // TODO: if present use subcode from CHD + add_qsub(lba++, control, dec_2_bcd(track + 1), 1, lba_to_msf(s), lba_to_msf(track_start + s)); + } + + track_start += toc->tracks[track].frames; + + // postgap + for(int s = 0; s < toc->tracks[track].postgap; s++) + add_qsub(lba++, control, dec_2_bcd(track + 1), 2, lba_to_msf(s), lba_to_msf(track_start + s)); + + track_start += toc->tracks[track].postgap; + } + + // 6750 sectors lead-out + for(int s = 0; s < SPG290_LEADOUT_LEN; s++) + add_qsub(lba++, 0x14, 0xaa, 1, lba_to_msf(s), lba_to_msf(total_sectors + s)); +} diff --git a/src/devices/machine/spg290_cdservo.h b/src/devices/machine/spg290_cdservo.h new file mode 100644 index 00000000000..790e7b4c28d --- /dev/null +++ b/src/devices/machine/spg290_cdservo.h @@ -0,0 +1,75 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco + + +#ifndef MAME_MACHINE_SPG290_CDSERVO_H +#define MAME_MACHINE_SPG290_CDSERVO_H + +#pragma once + +#include "imagedev/chd_cd.h" + + +class spg290_cdservo_device : public device_t +{ +public: + spg290_cdservo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + template + spg290_cdservo_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&cdrom_tag) + : spg290_cdservo_device(mconfig, tag, owner, clock) + { + m_cdrom.set_tag(std::forward(cdrom_tag)); + } + + void write(offs_t offset, uint32_t data, uint32_t mem_mask); + uint32_t read(offs_t offset, uint32_t mem_mask); + + auto irq_cb() { return m_irq_cb.bind(); } + auto space_write_cb() { return m_space_write_cb.bind(); } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + +private: + void change_status(); + void add_qsub(int sector, uint8_t addrctrl, uint8_t track, uint8_t index, uint32_t rel_msf, uint32_t abs_msf, uint16_t crc16=0); + void generate_qsub(cdrom_file *cdrom); + void servo_cmd_r(); + void servo_cmd_w(); + + optional_device m_cdrom; + devcb_write_line m_irq_cb; + devcb_write8 m_space_write_cb; + + emu_timer *m_cdtimer; + + uint32_t m_addr; + uint32_t m_data; + uint32_t m_buf_start; + uint32_t m_buf_end; + uint32_t m_buf_ptr; + uint8_t m_speed; + uint8_t m_seek_min; + uint8_t m_seek_sec; + uint8_t m_seek_frm; + uint32_t m_seek_lba; + uint32_t m_sector_size; + uint32_t m_dsp_data; + bool m_frame_found; + uint32_t m_control0; + uint32_t m_control1; + uint16_t m_skip; + uint32_t m_dsp_regs[0x10]; + + std::unique_ptr m_dsp_memory; + std::unique_ptr m_qsub; + uint32_t m_tot_sectors; + int m_cur_sector; +}; + +DECLARE_DEVICE_TYPE(SPG290_CDSERVO, spg290_cdservo_device) + +#endif // MAME_MACHINE_SPG290_CDSERVO_H diff --git a/src/devices/machine/spg290_i2c.cpp b/src/devices/machine/spg290_i2c.cpp new file mode 100644 index 00000000000..94faef82598 --- /dev/null +++ b/src/devices/machine/spg290_i2c.cpp @@ -0,0 +1,147 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco +/***************************************************************************** + + SPG290 I2C + +*****************************************************************************/ + +#include "emu.h" +#include "spg290_i2c.h" + + +DEFINE_DEVICE_TYPE(SPG290_I2C, spg290_i2c_device, "spg290_i2c", "SPG290 I2C") + + +spg290_i2c_device::spg290_i2c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SPG290_I2C, tag, owner, clock) + , m_irq_cb(*this) + , m_i2c_read_cb(*this) + , m_i2c_write_cb(*this) +{ +} + +void spg290_i2c_device::device_start() +{ + m_irq_cb.resolve_safe(); + m_i2c_read_cb.resolve_safe(0); + m_i2c_write_cb.resolve_safe(); + m_i2c_timer = timer_alloc(); + + save_item(NAME(m_config)); + save_item(NAME(m_irq_control)); + save_item(NAME(m_clock_conf)); + save_item(NAME(m_id)); + save_item(NAME(m_port_addr)); + save_item(NAME(m_wdata)); + save_item(NAME(m_rdata)); +} + +void spg290_i2c_device::device_reset() +{ + m_config = 0; + m_irq_control = 0; + m_clock_conf = 0; + m_id = 0; + m_port_addr = 0; + m_wdata = 0; + m_rdata = 0; + + m_i2c_timer->adjust(attotime::never); + + m_irq_cb(CLEAR_LINE); +} + +void spg290_i2c_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + if (m_config & 0x40) + m_rdata = m_i2c_read_cb(m_port_addr); + else + m_i2c_write_cb(m_port_addr, m_wdata); + + // I2C ack + m_config |= (m_config & 7) << 3; + + // I2C IRQ + if (m_irq_control & 0x02) + { + m_irq_control |= 0x01; + m_irq_cb(ASSERT_LINE); + } +} + +uint32_t spg290_i2c_device::read(offs_t offset, uint32_t mem_mask) +{ + switch (offset << 2) + { + case 0x20: // I2C configuration + return m_config; + case 0x24: // Interrupt status + return m_irq_control; + case 0x28: // Clock setting + return m_clock_conf; + case 0x2c: // ID + return m_id; + case 0x30: // Port address + return m_port_addr; + case 0x34: // Write data + return m_wdata; + case 0x38: // Read data + return m_rdata; + default: + logerror("[%s] %s: unknown read %x\n", tag(), machine().describe_context(), offset << 2); + } + + return 0; +} + +void spg290_i2c_device::write(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + switch (offset << 2) + { + case 0x20: // I2C configuration + { + COMBINE_DATA(&m_config); + + const auto i2c_clk = attotime::from_hz(clock() / 4 / ((m_clock_conf & 0x3ff) + 1)); + + if (m_config & 0x0001) // Start 8 + m_i2c_timer->adjust(i2c_clk * (2 + 9 * 4)); + else if (m_config & 0x0002) // Start 16 + m_i2c_timer->adjust(i2c_clk * (2 + 9 * 5)); + else if (m_config & 0x0004) // Start N + m_i2c_timer->adjust(i2c_clk * (2 + 9 * 4), 0, i2c_clk * (2 + 9 * 4)); + else if (m_config & 0x0100) // Stop N + m_i2c_timer->adjust(attotime::never); + + break; + } + case 0x24: // Interrupt status + COMBINE_DATA(&m_irq_control); + + if (ACCESSING_BITS_0_7) + m_irq_control &= ~(data & 0x01); // IRQ ack + + if (!(m_irq_control & 0x01)) + m_irq_cb(CLEAR_LINE); + + break; + case 0x28: // Clock setting + COMBINE_DATA(&m_clock_conf); + break; + case 0x2c: // ID + COMBINE_DATA(&m_id); + break; + case 0x30: // Port address + COMBINE_DATA(&m_port_addr); + break; + case 0x34: // Write data + COMBINE_DATA(&m_wdata); + break; + case 0x38: // Read data + COMBINE_DATA(&m_rdata); + break; + default: + logerror("[%s] %s: unknown write %x = %x\n", tag(), machine().describe_context(), offset << 2, data); + } +} diff --git a/src/devices/machine/spg290_i2c.h b/src/devices/machine/spg290_i2c.h new file mode 100644 index 00000000000..9b6c35cd9d9 --- /dev/null +++ b/src/devices/machine/spg290_i2c.h @@ -0,0 +1,46 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco + + +#ifndef MAME_MACHINE_SPG290_I2C_H +#define MAME_MACHINE_SPG290_I2C_H + +#pragma once + +class spg290_i2c_device : public device_t +{ +public: + spg290_i2c_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + void write(offs_t offset, uint32_t data, uint32_t mem_mask); + uint32_t read(offs_t offset, uint32_t mem_mask); + + auto irq_cb() { return m_irq_cb.bind(); } + auto i2c_read_cb() { return m_i2c_read_cb.bind(); } + auto i2c_write_cb() { return m_i2c_write_cb.bind(); } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + +private: + devcb_write_line m_irq_cb; + devcb_read16 m_i2c_read_cb; + devcb_write16 m_i2c_write_cb; + + emu_timer *m_i2c_timer; + + uint32_t m_config; + uint32_t m_irq_control; + uint32_t m_clock_conf; + uint32_t m_id; + uint32_t m_port_addr; + uint32_t m_wdata; + uint32_t m_rdata; +}; + +DECLARE_DEVICE_TYPE(SPG290_I2C, spg290_i2c_device) + +#endif // MAME_MACHINE_SPG290_I2C_H diff --git a/src/devices/machine/spg290_ppu.cpp b/src/devices/machine/spg290_ppu.cpp new file mode 100644 index 00000000000..8f47d61bf18 --- /dev/null +++ b/src/devices/machine/spg290_ppu.cpp @@ -0,0 +1,563 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco +/***************************************************************************** + + SPG290 PPU + + TODO: + - Horizontal and vertical compression + - Characters flip + - Various graphics glitches + +*****************************************************************************/ + +#include "emu.h" +#include "spg290_ppu.h" + + +DEFINE_DEVICE_TYPE(SPG290_PPU, spg290_ppu_device, "spg290_ppu", "SPG290 PPU") + + +spg290_ppu_device::spg290_ppu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SPG290_PPU, tag, owner, clock) + , m_screen(*this, finder_base::DUMMY_TAG) + , m_sprite_palette_ram(*this, "sprite_palette_ram") + , m_char_palette_ram(*this, "char_palette_ram") + , m_hoffset_ram(*this, "hoffset_ram") + , m_voffset_ram(*this, "voffset_ram") + , m_sprite_ram(*this, "sprite_ram") + , m_vblank_irq_cb(*this) + , m_space_read_cb(*this) +{ +} + + +void spg290_ppu_device::map(address_map &map) +{ + map(0x0000, 0x00ff).rw(FUNC(spg290_ppu_device::regs_r), FUNC(spg290_ppu_device::regs_w)); + map(0x1000, 0x17ff).ram().share(m_char_palette_ram); + map(0x1800, 0x1fff).ram().share(m_sprite_palette_ram); + map(0x2000, 0x27ff).ram().share(m_hoffset_ram); + map(0x3000, 0x37ff).ram().share(m_voffset_ram); + map(0x4000, 0x4fff).ram().share(m_sprite_ram); +} + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void spg290_ppu_device::device_start() +{ + m_vblank_irq_cb.resolve_safe(); + m_space_read_cb.resolve_safe(0); + + save_item(NAME(m_control)); + save_item(NAME(m_sprite_control)); + save_item(NAME(m_irq_control)); + save_item(NAME(m_irq_status)); + save_item(NAME(m_sprite_max)); + save_item(NAME(m_sprite_buf_start)); + save_item(NAME(m_blend_mode)); + save_item(NAME(m_frame_buff)); + save_item(NAME(m_transrgb)); + save_item(NAME(m_vcomp_value)); + save_item(NAME(m_vcomp_offset)); + save_item(NAME(m_vcomp_step)); + save_item(NAME(m_irq_timing_v)); + save_item(NAME(m_irq_timing_h)); + save_item(NAME(m_vblank_lines)); + + save_item(STRUCT_MEMBER(m_txs, control)); + save_item(STRUCT_MEMBER(m_txs, attribute)); + save_item(STRUCT_MEMBER(m_txs, posx)); + save_item(STRUCT_MEMBER(m_txs, posy)); + save_item(STRUCT_MEMBER(m_txs, nptr)); + save_item(STRUCT_MEMBER(m_txs, blend)); + save_item(STRUCT_MEMBER(m_txs, buf_start)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void spg290_ppu_device::device_reset() +{ + m_control = 0; + m_sprite_control = 0; + m_irq_control = 0; + m_irq_status = 0; + m_sprite_max = 0; + m_sprite_buf_start = 0; + m_blend_mode = 0; + m_frame_buff[0] = 0; + m_frame_buff[1] = 0; + m_frame_buff[2] = 0; + m_transrgb = 0; + m_vcomp_value = 0; + m_vcomp_offset = 0; + m_vcomp_step = 0; + m_irq_timing_v = 0; + m_irq_timing_h = 0; + m_vblank_lines = 0; + memset(m_txs, 0, sizeof(m_txs)); + + m_vblank_irq_cb(CLEAR_LINE); +} + + +uint32_t spg290_ppu_device::regs_r(offs_t offset, uint32_t mem_mask) +{ + switch(offset << 2) + { + case 0x00: // PPU Control + return m_control; + case 0x04: // Sprite Control + return m_sprite_control; + case 0x08: // PPU Max Sprites + return m_sprite_max; + case 0x0c: // blend mode + return m_blend_mode; + case 0x10: // PPU Max Sprites + return m_transrgb; + case 0x20: // Text Layer 1 X pos + return m_txs[0].posx; + case 0x24: // Text Layer 1 Y pos + return m_txs[0].posy; + case 0x28: // Text Layer 1 attribute + return m_txs[0].attribute; + case 0x2c: // Text Layer 1 control + return m_txs[0].control; + case 0x30: // Text Layer 1 number ptr + return m_txs[0].nptr; + case 0x38: // Text Layer 1 buffer blend + return m_txs[0].blend; + case 0x3c: // Text Layer 2 X pos + return m_txs[1].posx; + case 0x40: // Text Layer 2 Y pos + return m_txs[1].posy; + case 0x44: // Text Layer 2 attribute + return m_txs[1].attribute; + case 0x48: // Text Layer 2 control + return m_txs[1].control; + case 0x4c: // Text Layer 2 number ptr + return m_txs[1].nptr; + case 0x54: // Text Layer 2 buffer blend + return m_txs[1].blend; + case 0x58: // Text Layer 3 X pos + return m_txs[2].posx; + case 0x5c: // Text Layer 3 Y pos + return m_txs[2].posy; + case 0x60: // Text Layer 3 attribute + return m_txs[2].attribute; + case 0x64: // Text Layer 3 control + return m_txs[2].control; + case 0x68: // Text Layer 3 number ptr + return m_txs[2].nptr; + case 0x70: // Tx3 buffer blend + return m_txs[2].blend; + case 0x74: // vertical comp value + return m_vcomp_value; + case 0x78: // vertical comp offset + return m_vcomp_offset; + case 0x7c: // vertical comp step + return m_vcomp_step; + case 0x80: // PPU IRQ Control + return m_irq_control; + case 0x84: // PPU IRQ ack + return m_irq_status; + case 0x88: // IRQTimingV + return m_irq_timing_v; + case 0x8c: // IRQTimingH + return m_irq_timing_h; + case 0x90: // vblank lines + return m_vblank_lines; + case 0x94: // lines count + return m_vblank_lines + m_screen->vpos(); + case 0xa0: case 0xa4: case 0xa8: // Tx1 buffer start + return m_txs[0].buf_start[offset & 3]; + case 0xac: case 0xb0: case 0xb4: // Tx2 buffer start + return m_txs[1].buf_start[(offset+1) & 3]; + case 0xb8: case 0xbc: case 0xc0: // Tx3 buffer starts + return m_txs[2].buf_start[(offset+2) & 3]; + case 0xc4: case 0xc8: case 0xcc: // frame buffer start + return m_frame_buff[(offset-1) & 3]; + case 0xd0: // Sprites buffer start + return m_sprite_buf_start; + default: + logerror("[%s] %s: unknown read %x\n", tag(), machine().describe_context(), offset << 2); + } + + return 0; +} + + +void spg290_ppu_device::regs_w(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + switch(offset << 2) + { + case 0x00: // PPU Control + COMBINE_DATA(&m_control); + break; + case 0x04: // Sprite Control + COMBINE_DATA(&m_sprite_control); + break; + case 0x08: // PPU Max Sprites + COMBINE_DATA(&m_sprite_max); + break; + case 0x0c: // blend mode + COMBINE_DATA(&m_blend_mode); + break; + case 0x10: // PPU Max Sprites + COMBINE_DATA(&m_transrgb); + break; + case 0x20: // Text Layer 1 X pos + COMBINE_DATA(&m_txs[0].posx); + break; + case 0x24: // Text Layer 1 Y pos + COMBINE_DATA(&m_txs[0].posy); + break; + case 0x28: // Text Layer 1 attribute + COMBINE_DATA(&m_txs[0].attribute); + break; + case 0x2c: // Text Layer 1 control + COMBINE_DATA(&m_txs[0].control); + break; + case 0x30: // Text Layer 1 number ptr + COMBINE_DATA(&m_txs[0].nptr); + break; + case 0x38: // Text Layer 1 buffer blend + COMBINE_DATA(&m_txs[0].blend); + break; + case 0x3c: // Text Layer 2 X pos + COMBINE_DATA(&m_txs[1].posx); + break; + case 0x40: // Text Layer 2 Y pos + COMBINE_DATA(&m_txs[1].posy); + break; + case 0x44: // Text Layer 2 attribute + COMBINE_DATA(&m_txs[1].attribute); + break; + case 0x48: // Text Layer 2 control + COMBINE_DATA(&m_txs[1].control); + break; + case 0x4c: // Text Layer 2 number ptr + COMBINE_DATA(&m_txs[1].nptr); + break; + case 0x54: // Text Layer 2 buffer blend + COMBINE_DATA(&m_txs[1].blend); + break; + case 0x58: // Text Layer 3 X pos + COMBINE_DATA(&m_txs[2].posx); + break; + case 0x5c: // Text Layer 3 Y pos + COMBINE_DATA(&m_txs[2].posy); + break; + case 0x60: // Text Layer 3 attribute + COMBINE_DATA(&m_txs[2].attribute); + break; + case 0x64: // Text Layer 3 control + COMBINE_DATA(&m_txs[2].control); + break; + case 0x68: // Text Layer 3 number ptr + COMBINE_DATA(&m_txs[2].nptr); + break; + case 0x70: // Tx3 buffer blend + COMBINE_DATA(&m_txs[2].blend); + break; + case 0x74: // vertical comp value + COMBINE_DATA(&m_vcomp_value); + break; + case 0x78: // vertical comp offset + COMBINE_DATA(&m_vcomp_offset); + break; + case 0x7c: // vertical comp step + COMBINE_DATA(&m_vcomp_step); + break; + case 0x80: // PPU IRQ Control + COMBINE_DATA(&m_irq_control); + m_irq_status &= m_irq_control; + break; + case 0x84: // PPU IRQ ack + if (ACCESSING_BITS_0_7) + { + m_irq_status &= ~data; + + if (!(m_irq_status & m_irq_control & 0x07)) + m_vblank_irq_cb(CLEAR_LINE); + } + break; + case 0x88: // IRQTimingV + COMBINE_DATA(&m_irq_timing_v); + break; + case 0x8c: // IRQTimingH + COMBINE_DATA(&m_irq_timing_h); + break; + case 0x90: // vblank lines + COMBINE_DATA(&m_vblank_lines); + break; + case 0xa0: case 0xa4: case 0xa8: // Tx1 buffer start + COMBINE_DATA(&m_txs[0].buf_start[offset & 3]); + break; + case 0xac: case 0xb0: case 0xb4: // Tx2 buffer start + COMBINE_DATA(&m_txs[1].buf_start[(offset+1) & 3]); + break; + case 0xb8: case 0xbc: case 0xc0: // Tx3 buffer starts + COMBINE_DATA(&m_txs[2].buf_start[(offset+2) & 3]); + break; + case 0xc4: case 0xc8: case 0xcc: // frame buffer start + COMBINE_DATA(&m_frame_buff[(offset-1) & 3]); + break; + case 0xd0: // Sprites buffer start + COMBINE_DATA(&m_sprite_buf_start); + break; + default: + logerror("[%s] %s: unknown write %x = %x\n", tag(), machine().describe_context(), offset << 2, data); + } +} + +void spg290_ppu_device::screen_vblank(int state) +{ + if (state && (m_irq_control & 0x01)) // VBlanking Start IRQ + { + m_irq_status |= 0x01; + m_vblank_irq_cb(ASSERT_LINE); + } + else if (!state && (m_irq_control & 0x02)) // VBlanking End IRQ + { + m_irq_status |= 0x02; + m_vblank_irq_cb(ASSERT_LINE); + } +} + +inline rgb_t spg290_ppu_device::blend_colors(const rgb_t &c0, const rgb_t &c1, uint8_t level) +{ + if (m_blend_mode & 1) + { + int r = (c0.r() * level / 63) - (c1.r() * (63 - level) / 63); + int g = (c0.b() * level / 63) - (c1.b() * (63 - level) / 63); + int b = (c0.b() * level / 63) - (c1.b() * (63 - level) / 63); + return rgb_t(r, g, b); + } + else + { + int r = (c0.r() * level / 63) + (c1.r() * (63 - level) / 63); + int g = (c0.b() * level / 63) + (c1.b() * (63 - level) / 63); + int b = (c0.b() * level / 63) + (c1.b() * (63 - level) / 63); + return rgb_t(r, g, b); + } +} + +inline void spg290_ppu_device::argb1555(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t posy, uint16_t posx, uint16_t argb, uint8_t blend) +{ + if (!(argb & 0x8000) && cliprect.contains(posx, posy)) + { + rgb_t color = rgb_t(pal5bit(argb >> 10), pal5bit(argb >> 5), pal5bit(argb >> 0)); + if (blend) + color = blend_colors(bitmap.pix32(posy, posx), color, blend); + + bitmap.pix32(posy, posx) = color; + } +} + +inline void spg290_ppu_device::rgb565(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t posy, uint16_t posx, uint16_t rgb, uint8_t blend) +{ + if ((!(m_transrgb & 0x10000) || (m_transrgb & 0xffff) != rgb) && cliprect.contains(posx, posy)) + { + rgb_t color = rgb_t(pal5bit(rgb >> 11), pal6bit(rgb >> 5), pal5bit(rgb >> 0)); + if (blend) + color = blend_colors(bitmap.pix32(posy, posx), color, blend); + + bitmap.pix32(posy, posx) = color; + } +} + +void spg290_ppu_device::blit_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t control, uint32_t attribute, uint32_t buf_start) +{ + uint16_t sprite_num = control & 0xffff; + uint16_t sprite_x = (control >> 16) & 0x3ff; + uint16_t sprite_y = (attribute >> 16) & 0x3ff; + uint8_t sprite_hsize = 8 << ((attribute >> 4) & 0x03); + uint8_t sprite_vsize = 8 << ((attribute >> 6) & 0x03); + uint8_t bit_pixel = ((attribute & 3) + 1) << 1; + uint8_t sprite_flip = (attribute >> 2) & 0x03; + uint16_t pen_bank = ((attribute >> 8) & 0x1f) * 0x10; + uint8_t blend = (attribute & 0x8000) ? (attribute >> 26) & 0x3f : 0; + uint8_t pixel_word = 32 / bit_pixel; + uint8_t pixel_byte = 8 / bit_pixel; + uint8_t word_line = sprite_hsize / pixel_word; + uint16_t pen_mask = (1 << bit_pixel) - 1; + + if (sprite_num == 0) + return; + + uint32_t sprite_base = buf_start + (sprite_num * (sprite_hsize * sprite_vsize * bit_pixel / 8)); + + if (sprite_x > cliprect.max_x) sprite_x = (sprite_x & 0x3ff) - 0x400; + if (sprite_y > cliprect.max_y) sprite_y = (sprite_y & 0x3ff) - 0x400; + + for (int y=0; y < sprite_vsize; y++) + for (int x=0; x < word_line; x++) + { + uint32_t data = m_space_read_cb(sprite_base + (y * word_line + x) * 4); + + for (int i=0; i < 4; i++) + { + for (int b=0; b < pixel_byte; b++) + { + int bitpos = i * pixel_byte + b; + uint16_t pen = (data >> (8 - (b + 1) * bit_pixel)) & pen_mask; + uint16_t posx = cliprect.min_x; + if (sprite_flip & 0x01) + posx += sprite_x + (sprite_hsize - (x * pixel_word + bitpos)); + else + posx += sprite_x + x * pixel_word + bitpos; + + uint16_t posy = cliprect.min_y; + if (sprite_flip & 0x02) + posy += sprite_y + (sprite_vsize - y); + else + posy += sprite_y + y; + + argb1555(bitmap, cliprect, posy, posx, m_sprite_palette_ram[(pen_bank + pen) & 0x1ff], blend); + } + + data >>= 8; + } + } +} + +void spg290_ppu_device::blit_bitmap(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t control, uint32_t attribute, int posy, int posx, uint32_t nptr, uint32_t buf_start, uint8_t blend) +{ + int max_x = cliprect.max_x + posx; + int max_y = cliprect.max_y + posy; + for (int y=0; y < max_y; y++) + { + int line = (control & 0x04) ? 0 : y; + uint32_t tx_start = m_space_read_cb(nptr + line * 4) * 2; + + for (int x=0; x < max_x; x+=2) + { + uint16_t px = cliprect.min_x + x; + uint16_t py = cliprect.min_y + y; + uint32_t data = m_space_read_cb(buf_start + tx_start + x * 2); + + for (int b=0; b < 2; b++) + { + if (control & 0x1000) + rgb565(bitmap, cliprect, py - posy, px + b - posx, data & 0xffff, blend); + else + argb1555(bitmap, cliprect, py - posy, px + b - posx, data & 0xffff, blend); + + data >>= 16; + } + } + } +} + +void spg290_ppu_device::blit_character(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t control, uint32_t attribute, int posy, int posx, uint32_t nptr, uint32_t buf_start, uint8_t blend) +{ + uint8_t hsize = 8 << ((attribute >> 4) & 0x03); + uint8_t vsize = 8 << ((attribute >> 6) & 0x03); + uint8_t bit_pixel = ((attribute & 3) + 1) << 1; + uint16_t pen_bank = ((attribute >> 8) & 0x1f) * 0x10; + //uint8_t char_flip = (attribute >> 2) & 0x03; + uint8_t pixel_word = 32 / bit_pixel; + uint8_t chars_line = 1024 / hsize; + uint16_t pen_mask = (1 << bit_pixel) - 1; + + int max_x = (cliprect.max_x + posx) / vsize + 1; + int max_y = (cliprect.max_y + posy) / hsize + 1; + + for (int y=0; y <= max_y; y++) + { + for (int x=0; x <= max_x; x++) + { + int line = (control & 0x04) ? 0 : y; + uint32_t addr = line * chars_line + x; + uint32_t char_id = m_space_read_cb(nptr + addr * 2); + + if (addr & 1) + char_id >>= 16; + + uint32_t char_addr = buf_start + (char_id & 0xffff) * hsize * vsize; + + for (int cy=0; cy < vsize; cy++) + { + uint32_t line_addr = char_addr + cy * hsize; + for (int cx=0; cx < hsize; cx++) + { + uint32_t data = m_space_read_cb(line_addr + (cx * bit_pixel) / 8); + uint16_t px = cliprect.min_x + x * hsize + cx; + uint16_t py = cliprect.min_y + y * vsize + cy; + uint16_t pen = (data >> ((cx % pixel_word) * bit_pixel)) & pen_mask; + uint16_t pix = m_char_palette_ram[(pen_bank + pen) & 0x3ff]; + + if (control & 0x1000) + rgb565(bitmap, cliprect, py - posy, px - posx, pix, blend); + else + argb1555(bitmap, cliprect, py - posy, px - posx, pix, blend); + } + } + } + } +} + + +uint32_t spg290_ppu_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) +{ + bitmap.fill(rgb_t::black(), cliprect); + + if (!(m_control & 0x1000)) + return 0; + + for (int depth=0; depth<4; depth++) + { + //if (machine().input().code_pressed(KEYCODE_1_PAD) && depth == 0) continue; + //if (machine().input().code_pressed(KEYCODE_2_PAD) && depth == 1) continue; + //if (machine().input().code_pressed(KEYCODE_3_PAD) && depth == 2) continue; + //if (machine().input().code_pressed(KEYCODE_4_PAD) && depth == 3) continue; + + // draw the bitmap/text layers + for (int l=0; l<3; l++) + { + //if (machine().input().code_pressed(KEYCODE_7_PAD) && l == 0) continue; + //if (machine().input().code_pressed(KEYCODE_8_PAD) && l == 1) continue; + //if (machine().input().code_pressed(KEYCODE_9_PAD) && l == 2) continue; + + if ((m_txs[l].control & 0x08) && ((m_txs[l].attribute >> 13) & 3) == depth) + { + uint8_t blend = (m_txs[l].control & 0x0100) ? m_txs[l].blend : 0; + + // posx is 10-bit two's complement + int posx = m_txs[l].posx & 0x3ff; + if (posx & 0x200) + posx = (posx & 0x3ff) - 0x400; + + // posy is 9-bit two's complement + int posy = m_txs[l].posy & 0x1ff; + if (posy & 0x100) + posy = (posy & 0x1ff) - 0x200; + + if (m_txs[l].control & 0x01) + blit_bitmap(bitmap, cliprect, m_txs[l].control, m_txs[l].attribute, posy, posx, m_txs[l].nptr, m_txs[l].buf_start[0], blend); + else + blit_character(bitmap, cliprect, m_txs[l].control, m_txs[l].attribute, posy, posx, m_txs[l].nptr, m_txs[l].buf_start[0], blend); + } + } + + //if (machine().input().code_pressed(KEYCODE_0_PAD)) continue; + + // draw the sprites + if (m_sprite_control & 1) + { + for (int i=0; i <= (m_sprite_max & 0x1ff); i++) + { + if (((m_sprite_ram[i * 2 + 1] >> 13) & 3) == depth) + blit_sprite(bitmap, cliprect, m_sprite_ram[i * 2], m_sprite_ram[i * 2 + 1], m_sprite_buf_start); + } + } + } + + return 0; +} diff --git a/src/devices/machine/spg290_ppu.h b/src/devices/machine/spg290_ppu.h new file mode 100644 index 00000000000..83960abe6d6 --- /dev/null +++ b/src/devices/machine/spg290_ppu.h @@ -0,0 +1,85 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco + + +#ifndef MAME_MACHINE_SPG290_PPU_H +#define MAME_MACHINE_SPG290_PPU_H + +#pragma once + +#include "screen.h" + + +class spg290_ppu_device : public device_t +{ +public: + spg290_ppu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + template + spg290_ppu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock, T &&screen_tag) + : spg290_ppu_device(mconfig, tag, owner, clock) + { + m_screen.set_tag(std::forward(screen_tag)); + } + + uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); + void screen_vblank(int state); + void map(address_map &map); + auto vblank_irq_cb() { return m_vblank_irq_cb.bind(); } + auto space_read_cb() { return m_space_read_cb.bind(); } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + uint32_t regs_r(offs_t offset, uint32_t mem_mask); + void regs_w(offs_t offset, uint32_t data, uint32_t mem_mask); + + rgb_t blend_colors(const rgb_t &c0, const rgb_t &c1, uint8_t level); + void argb1555(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t posy, uint16_t posx, uint16_t argb, uint8_t blend); + void rgb565(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t posy, uint16_t posx, uint16_t rgb, uint8_t blend); + void blit_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t control, uint32_t attribute, uint32_t buf_start); + void blit_bitmap(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t control, uint32_t attribute, int posy, int posx, uint32_t nptr, uint32_t buf_start, uint8_t blend); + void blit_character(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t control, uint32_t attribute, int posy, int posx, uint32_t nptr, uint32_t buf_start, uint8_t blend); + +private: + required_device m_screen; + required_shared_ptr m_sprite_palette_ram; + required_shared_ptr m_char_palette_ram; + required_shared_ptr m_hoffset_ram; + required_shared_ptr m_voffset_ram; + required_shared_ptr m_sprite_ram; + devcb_write_line m_vblank_irq_cb; + devcb_read32 m_space_read_cb; + + uint32_t m_control; + uint32_t m_sprite_control; + uint32_t m_irq_control; + uint32_t m_irq_status; + uint32_t m_sprite_max; + uint32_t m_sprite_buf_start; + uint32_t m_blend_mode; + uint32_t m_frame_buff[3]; + uint32_t m_transrgb; + uint32_t m_vcomp_value; + uint32_t m_vcomp_offset; + uint32_t m_vcomp_step; + uint32_t m_irq_timing_v; + uint32_t m_irq_timing_h; + uint32_t m_vblank_lines; + + struct spg290_ppu_tx_t + { + uint32_t control; + uint32_t attribute; + uint32_t posx; + uint32_t posy; + uint32_t nptr; + uint32_t blend; + uint32_t buf_start[3]; + } m_txs[3]; +}; + +DECLARE_DEVICE_TYPE(SPG290_PPU, spg290_ppu_device) + +#endif // MAME_MACHINE_SPG290_PPU_H diff --git a/src/devices/machine/spg290_timer.cpp b/src/devices/machine/spg290_timer.cpp new file mode 100644 index 00000000000..25ee7790e8b --- /dev/null +++ b/src/devices/machine/spg290_timer.cpp @@ -0,0 +1,156 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco +/***************************************************************************** + + SPG290 Timer + +*****************************************************************************/ + +#include "emu.h" +#include "spg290_timer.h" + + +DEFINE_DEVICE_TYPE(SPG290_TIMER, spg290_timer_device, "spg290_timer", "SPG290 Timer") + + +spg290_timer_device::spg290_timer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, SPG290_TIMER, tag, owner, clock) + , m_irq_cb(*this) +{ +} + +void spg290_timer_device::device_start() +{ + m_irq_cb.resolve_safe(); + m_tick_timer = timer_alloc(); + + save_item(NAME(m_enabled)); + save_item(NAME(m_control)); + save_item(NAME(m_control2)); + save_item(NAME(m_preload)); + save_item(NAME(m_counter)); + save_item(NAME(m_ccp)); + save_item(NAME(m_upcount)); +} + +void spg290_timer_device::device_reset() +{ + m_enabled = false; + m_control = 0; + m_control2 = 0; + m_preload = 0; + m_counter = 0; + m_ccp = 0; + m_upcount = 0; + + m_tick_timer->adjust(attotime::never); + + m_irq_cb(CLEAR_LINE); +} + +void spg290_timer_device::device_clock_changed() +{ + if (m_enabled) + m_tick_timer->adjust(attotime::from_hz(clock()), 0, attotime::from_hz(clock())); + else + m_tick_timer->adjust(attotime::never); +} + +void spg290_timer_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) +{ + if (!BIT(m_control, 31)) + return; + + switch ((m_control2 >> 30) & 0x03) + { + case 0: // Timer Mode + if (m_counter == 0xffff) + { + m_counter = m_preload & 0xffff; + if (BIT(m_control, 27)) + { + m_control |= 0x04000000; + m_irq_cb(ASSERT_LINE); + } + } + else + m_counter++; + break; + case 1: // Capture Mode + fatalerror("[%s] %s: unemulated timer Capture Mode\n", tag(), machine().describe_context()); + break; + case 2: // Comparison Mode + fatalerror("[%s] %s: unemulated timer Comparison Mode\n", tag(), machine().describe_context()); + break; + case 3: // PWM Mode + fatalerror("[%s] %s: unemulated timer PWM Mode\n", tag(), machine().describe_context()); + break; + } +} + +void spg290_timer_device::control_w(uint32_t data) +{ + bool enabled = data & 1; + if (m_enabled != enabled) + { + m_enabled = enabled; + spg290_timer_device::device_clock_changed(); + } + + if (data & 2) + m_counter = m_preload & 0xffff; +} + +uint32_t spg290_timer_device::read(offs_t offset, uint32_t mem_mask) +{ + switch (offset << 2) + { + case 0x00: // Control 1 + return m_control; + case 0x04: // Control 2 + return m_control2; + case 0x08: // Preload + return m_preload; + case 0x0c: // CCP + return m_ccp; + case 0x10: // Upcount + return m_upcount; + default: + logerror("[%s] %s: unknown read %x\n", tag(), machine().describe_context(), offset << 2); + } + + return 0; +} + + +void spg290_timer_device::write(offs_t offset, uint32_t data, uint32_t mem_mask) +{ + switch (offset << 2) + { + case 0x00: // Control 1 + COMBINE_DATA(&m_control); + + if (ACCESSING_BITS_24_31) + { + m_control &= ~(data & 0x04000000); // IRQ ack + + if (!(m_control & 0x04000000)) + m_irq_cb(CLEAR_LINE); + } + break; + case 0x04: // Control 2 + COMBINE_DATA(&m_control2); + break; + case 0x08: // Preload + COMBINE_DATA(&m_preload); + break; + case 0x0c: // CCP + COMBINE_DATA(&m_ccp); + break; + case 0x10: // Upcount + COMBINE_DATA(&m_upcount); + break; + default: + logerror("[%s] %s: unknown write %x = %x\n", tag(), machine().describe_context(), offset << 2, data); + } +} diff --git a/src/devices/machine/spg290_timer.h b/src/devices/machine/spg290_timer.h new file mode 100644 index 00000000000..44c399fbb64 --- /dev/null +++ b/src/devices/machine/spg290_timer.h @@ -0,0 +1,43 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco + + +#ifndef MAME_MACHINE_SPG290_TIMER_H +#define MAME_MACHINE_SPG290_TIMER_H + +#pragma once + +class spg290_timer_device : public device_t +{ +public: + spg290_timer_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + void write(offs_t offset, uint32_t data, uint32_t mem_mask); + uint32_t read(offs_t offset, uint32_t mem_mask); + void control_w(uint32_t data); + auto irq_cb() { return m_irq_cb.bind(); } + +protected: + virtual void device_start() override; + virtual void device_reset() override; + virtual void device_clock_changed() override; + + virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; + +private: + devcb_write_line m_irq_cb; + + emu_timer *m_tick_timer; + + bool m_enabled; + uint16_t m_counter; + uint32_t m_control; + uint32_t m_control2; + uint32_t m_preload; + uint32_t m_ccp; + uint32_t m_upcount; +}; + +DECLARE_DEVICE_TYPE(SPG290_TIMER, spg290_timer_device) + +#endif // MAME_MACHINE_SPG290_TIMER_H diff --git a/src/mame/drivers/spg29x.cpp b/src/mame/drivers/spg29x.cpp index c0405efc30a..8ca4f5133df 100644 --- a/src/mame/drivers/spg29x.cpp +++ b/src/mame/drivers/spg29x.cpp @@ -6,6 +6,18 @@ 08/17/2013 Skeleton driver by Sandro Ronco + HyperScan TODO: + - Various graphics glitches + - Sound + - X-Men hangs after the first match + - USB + + Hyperscan has a hidden test menu that can be accessed with a specific inputs sequence: + - During boot press and hold Select + Left Shoulder + Green until 'PLEASE WAIT' is shown on the screen + - Press and release Red, Red, Green, Green, Yellow, Blue + +**************************************************************************** + SPG290 Interrupt: Vector Source @@ -60,11 +72,15 @@ #include "emu.h" #include "cpu/score/score.h" +#include "machine/spg290_cdservo.h" +#include "machine/spg290_i2c.h" +#include "machine/spg290_ppu.h" +#include "machine/spg290_timer.h" +#include "machine/hyperscan_card.h" +#include "machine/hyperscan_ctrl.h" #include "screen.h" #include "softlist_dev.h" -#define LOG_SPG290_REGISTER_ACCESS (1) - class spg29x_game_state : public driver_device @@ -72,7 +88,14 @@ class spg29x_game_state : public driver_device public: spg29x_game_state(const machine_config &mconfig, device_type type, const char *tag) : driver_device(mconfig, type, tag), - m_maincpu(*this, "maincpu") + m_maincpu(*this, "maincpu"), + m_screen(*this, "screen"), + m_ppu(*this, "ppu"), + m_i2c(*this, "i2c"), + m_timers(*this, "timer%u", 0U), + m_hyperscan_card(*this, "card"), + m_hyperscan_ctrl(*this, "ctrl%u", 0U), + m_leds(*this, "led%u", 0U) { } void spg29x(machine_config &config); @@ -85,90 +108,32 @@ protected: private: virtual void machine_start() override; - virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override; uint32_t spg290_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect); - uint32_t spg290_regs_r(offs_t offset, uint32_t mem_mask = ~0); - void spg290_regs_w(offs_t offset, uint32_t data, uint32_t mem_mask = ~0); - void spg290_timers_update(); - DECLARE_WRITE_LINE_MEMBER(spg290_vblank_irq); - inline uint32_t spg290_read_mem(uint32_t offset); - inline void spg290_write_mem(uint32_t offset, uint32_t data); - void spg290_argb1555(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t posy, uint16_t posx, uint16_t argb); - void spg290_rgb565(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t posy, uint16_t posx, uint16_t rgb, uint32_t transrgb); - void spg290_blit_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t control, uint32_t attribute, uint32_t *palettes, uint32_t buf_start); - void spg290_blit_bitmap(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t control, uint32_t attribute, int posy, int posx, uint32_t nptr, uint32_t buf_start, uint32_t transrgb); - void spg290_blit_character(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t control, uint32_t attribute, int posy, int posx, uint32_t nptr, uint32_t buf_start, uint32_t transrgb); void spg290_mem(address_map &map); void spg290_bios_mem(address_map &map); - static const device_timer_id TIMER_SPG290 = 0; - static const device_timer_id TIMER_I2C = 1; - - struct spg290_miu - { - uint32_t status; - }; - - struct spg290_ppu - { - uint32_t control; - uint32_t irq_control; - uint32_t irq_status; - uint32_t sprite_max; - uint32_t sprite_buf_start; - uint32_t frame_buff[3]; - uint32_t palettes[0x200]; - uint32_t tx_hoffset[0x200]; - uint32_t tx_hcomp[0x200]; - uint32_t transrgb; - - struct ppu_spite - { - uint32_t control; - uint32_t attribute; - } sprites[0x200]; + void space_byte_w(offs_t offset, uint8_t data) { return m_maincpu->space(AS_PROGRAM).write_byte(offset, data); } + uint32_t space_dword_r(offs_t offset) { return m_maincpu->space(AS_PROGRAM).read_dword(offset); } - struct ppu_tx - { - uint32_t control; - uint32_t attribute; - uint32_t posx; - uint32_t posy; - uint32_t nptr; - uint32_t buf_start[3]; - } txs[3]; - }; - - struct spg290_timer - { - uint32_t control; - uint32_t control2; - uint16_t preload; - uint16_t counter; - }; + uint16_t i2c_r(offs_t offset); - struct spg290_i2c - { - uint32_t config; - uint32_t irq_control; - uint32_t clock; - uint8_t count; - uint32_t id; - uint32_t port_addr; - uint32_t wdata; - uint32_t rdata; - }; - - spg290_miu m_miu; - spg290_ppu m_ppu; - spg290_timer m_timers[6]; - spg290_i2c m_i2c; - emu_timer * m_update_timer; - emu_timer * m_i2c_timer; + required_device m_screen; + required_device m_ppu; + required_device m_i2c; + required_device_array m_timers; + optional_device m_hyperscan_card; + optional_device_array m_hyperscan_ctrl; + output_finder<8> m_leds; + void tve_control_w(offs_t offset, uint32_t data, uint32_t mem_mask); + void gpio_out_w(offs_t offset, uint32_t data, uint32_t mem_mask); + void timers_clk_sel_w(offs_t offset, uint32_t data, uint32_t mem_mask); + uint16_t m_tve_control; + uint8_t m_tve_fade_offset; + uint16_t m_gpio_out; }; class spg29x_nand_game_state : public spg29x_game_state @@ -209,438 +174,147 @@ private: - -#if LOG_SPG290_REGISTER_ACCESS -static void log_spg290_regs(device_t *device,uint8_t module, uint16_t reg, uint32_t mem_mask, bool write, uint32_t data=0) -{ - static const char *const modules_name[] = - { - "CSI", "PPU", "JPG", "TV", "LCD", "SPU", "CD", "MIU", "APBDMA", "BUFCTL","IRQCTL", "GPUBUF", "LDMDMA", - "BLNDMA", "TPGBUF", "AHBDEC", "GPIO", "SPI", "SIO", "I2C", "I2S", "UART", "TIMERS/RTC", "WDOG", "SD", - "FLASH", "ADC", "USB device", "USB host", "Reserved", "Reserved", "Reserved", "SFTCFG", "CKG", "MP4", - "MIU2", "ECC" - }; - - if (module < 0x25) - device->logerror("SPG: %-10s", modules_name[module]); - else - device->logerror("SPG: mod 0x%02x ", module); - - if (!write) - device->logerror(" R 0x%04x", reg); - else - device->logerror(" W 0x%04x = 0x%08x", reg, data); - - if (mem_mask != 0xffffffffu) - device->logerror(" (0x%08x)\n", mem_mask); - else - device->logerror("\n"); -} -#endif - - -uint32_t spg29x_game_state::spg290_regs_r(offs_t offset, uint32_t mem_mask) -{ - uint32_t addr = offset << 2; - uint32_t data = 0; - - if (addr == 0x010000) // PPU Control - { - data = m_ppu.control; - } - else if (addr == 0x010084) // PPU IRQ Status - { - data = m_ppu.irq_status; - } - if (addr == 0x07006c) // MIU Status - { - data = m_miu.status; - } - else if ((addr & 0xff0fff) == 0x160000) // Timer X Status - { - int idx = (offset>>10) & 0x0f; - data = m_timers[idx].control; - } - else if(addr == 0x130024) // I2C interrupt - { - data = m_i2c.irq_control; - } - else if(addr == 0x130034) // I2C write data - { - data = m_i2c.wdata; - } - else if(addr == 0x130038) // I2C data data - { - data = m_i2c.rdata; - } - -#if LOG_SPG290_REGISTER_ACCESS - //else - { - if (!machine().side_effects_disabled()) - log_spg290_regs(this,(offset >> 14) & 0xff, (offset<<2) & 0xffff, mem_mask, false); - } -#endif - - return data; -} - -void spg29x_game_state::spg290_regs_w(offs_t offset, uint32_t data, uint32_t mem_mask) +void spg29x_game_state::timers_clk_sel_w(offs_t offset, uint32_t data, uint32_t mem_mask) { - uint32_t addr = offset << 2; + auto clock = 27_MHz_XTAL / ((data & 0xff) + 1); - if (addr == 0x010000) // PPU Control + uint32_t mask = 0x100; + for(int i=0; i>3) & 3) | ((offset>>4) & 1)) - 1; - COMBINE_DATA(&m_ppu.txs[idx].posx); - } - else if (addr == 0x010024 || addr == 0x010040 || addr == 0x01005c) // Text Layers y pos - { - int idx = (((offset>>3) & 3) | ((offset>>4) & 1)) - 1; - COMBINE_DATA(&m_ppu.txs[idx].posy); - } - else if (addr == 0x010028 || addr == 0x010044 || addr == 0x010060) // Text Layers attribute - { - int idx = ((offset>>3) & 3) - 1; - COMBINE_DATA(&m_ppu.txs[idx].attribute); - } - else if (addr == 0x01002c || addr == 0x010048 || addr == 0x010064) // Text Layers control - { - int idx = ((offset>>3) & 3) - 1; - COMBINE_DATA(&m_ppu.txs[idx].control); - } - else if (addr == 0x010030 || addr == 0x01004c || addr == 0x010068) // Text Layers number ptr - { - int idx = ((offset>>3) & 3) - 1; - COMBINE_DATA(&m_ppu.txs[idx].nptr); - } - else if (addr == 0x010080) // PPU IRQ Control - { - COMBINE_DATA(&m_ppu.irq_control); - } - else if (addr == 0x010084) // PPU IRQ ack - { - if (ACCESSING_BITS_0_7) - m_ppu.irq_status &= ~data; - } - else if (addr >= 0x0100a0 && addr <= 0x0100a8) // Tx1 buffer start - { - COMBINE_DATA(&m_ppu.txs[0].buf_start[offset & 3]); - } - else if (addr >= 0x0100ac && addr <= 0x0100b4) // Tx2 buffer start - { - COMBINE_DATA(&m_ppu.txs[1].buf_start[(offset+1) & 3]); - } - else if (addr >= 0x0100b8 && addr <= 0x0100c0) // Tx3 buffer starts - { - COMBINE_DATA(&m_ppu.txs[2].buf_start[(offset+2) & 3]); - } - else if ((addr & 0xfff000) == 0x011000) // Palettes - { - COMBINE_DATA(&m_ppu.palettes[offset & 0x01ff]); - } - else if ((addr & 0xfff000) == 0x012000) // Tx horizontal offset - { - COMBINE_DATA(&m_ppu.tx_hoffset[offset & 0x01ff]); - } - else if ((addr & 0xfff000) == 0x013000) // Tx horizontal compression - { - COMBINE_DATA(&m_ppu.tx_hcomp[offset & 0x01ff]); - } - else if ((addr & 0xfff000) == 0x014000) // Sprite Control Registers - { - int idx = (offset>>1) & 0x1ff; - if (offset & 1) - COMBINE_DATA(&m_ppu.sprites[idx].attribute); + if (data & mask) + m_timers[i]->set_clock(32.768_kHz_XTAL); else - COMBINE_DATA(&m_ppu.sprites[idx].control); - } - else if (addr == 0x07005c) // MIU Status - { - COMBINE_DATA(&m_miu.status); - } - else if ((addr & 0xff0fff) == 0x160000) // Timer X Control 1 - { - int idx = (offset>>10) & 0x07; - COMBINE_DATA(&m_timers[idx].control); + m_timers[i]->set_clock(clock); - if (ACCESSING_BITS_24_31) - m_timers[idx].control &= ~(data & 0x04000000); // Timers IRQ ack + mask <<= 1; } - else if ((addr & 0xff0fff) == 0x160004) // Timer X Control 2 - { - int idx = (offset>>10) & 0x07; - COMBINE_DATA(&m_timers[idx].control2); - } - else if ((addr & 0xff0fff) == 0x160008) // Timer X Preload - { - int idx = (offset>>10) & 0x07; - COMBINE_DATA(&m_timers[idx].preload); - } - else if (addr == 0x2100e4) // Timer Source Clock Selection - { - const auto timers_clk = XTAL(27'000'000) / ((data & 0xff) + 1); - m_update_timer->adjust(attotime::from_hz(timers_clk), 0, attotime::from_hz(timers_clk)); - } - else if(addr == 0x130020) // I2C configuration - { - COMBINE_DATA(&m_i2c.config); - } - else if(addr == 0x130024) // I2C interrupt - { - COMBINE_DATA(&m_i2c.irq_control); - - if (ACCESSING_BITS_0_7) - m_i2c.irq_control &= ~(data & 0x00000001); // I2C IRQ ack - } - else if(addr == 0x130028) // I2C clock setting - { - COMBINE_DATA(&m_i2c.clock); - const auto i2c_clk = XTAL(27'000'000) / ((m_i2c.clock & 0x3ff) + 1); - m_i2c_timer->adjust(attotime::from_hz(i2c_clk), 0, attotime::from_hz(i2c_clk)); - } - else if(addr == 0x13002c) // I2C ID - { - COMBINE_DATA(&m_i2c.id); - } - else if(addr == 0x130030) // I2C port address - { - COMBINE_DATA(&m_i2c.port_addr); - } - else if(addr == 0x130034) // I2C write data - { - COMBINE_DATA(&m_i2c.wdata); - } - else if(addr == 0x130038) // I2C data data - { - COMBINE_DATA(&m_i2c.rdata); - } - else if(addr == 0x150000) // UART data - { - if (ACCESSING_BITS_0_7) - printf("%c", data & 0xff); - } - -#if LOG_SPG290_REGISTER_ACCESS - //else - { - if (!machine().side_effects_disabled()) - log_spg290_regs(this,(offset >> 14) & 0xff, (offset<<2) & 0xffff, mem_mask, true, data); - } -#endif -} - -inline uint32_t spg29x_game_state::spg290_read_mem(uint32_t offset) -{ - return m_maincpu->space(0).read_dword(offset); -} - -inline void spg29x_game_state::spg290_write_mem(uint32_t offset, uint32_t data) -{ - return m_maincpu->space(0).write_dword(offset, data); } -void spg29x_game_state::spg290_argb1555(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t posy, uint16_t posx, uint16_t argb) +void spg29x_game_state::tve_control_w(offs_t offset, uint32_t data, uint32_t mem_mask) { - if (!(argb & 0x8000) && cliprect.contains(posx, posy)) + COMBINE_DATA(&m_tve_control); + rectangle visarea; + switch(m_tve_control & 0xc) { - rgb_t color = rgb_t(pal5bit(argb >> 10), pal5bit(argb >> 5), pal5bit(argb >> 0)); - bitmap.pix32(posy, posx) = color; + case 0x0: // QVGA + visarea.set(0, 320-1, 0, 240-1); + break; + case 0x4: // VGA + visarea.set(0, 640-1, 0, 480-1); + break; + case 0x8: // HVGA + visarea.set(0, 640-1, 0, 240-1); + break; } -} -void spg29x_game_state::spg290_rgb565(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint16_t posy, uint16_t posx, uint16_t rgb, uint32_t transrgb) -{ - if ((!(transrgb & 0x10000) || (transrgb & 0xffff) != rgb) && cliprect.contains(posx, posy)) - { - rgb_t color = rgb_t(pal5bit(rgb >> 11), pal6bit(rgb >> 5), pal5bit(rgb >> 0)); - bitmap.pix32(posy, posx) = color; - } + int interlaced = m_tve_control & 1; + if (m_tve_control & 2) + m_screen->configure(864, 625, visarea, HZ_TO_ATTOSECONDS(27_MHz_XTAL) * 864 * 625 * (interlaced ? 2 : 1)); // PAL + else + m_screen->configure(858, 525, visarea, HZ_TO_ATTOSECONDS(27_MHz_XTAL) * 858 * 525 * (interlaced ? 2 : 1)); // NTSC } -void spg29x_game_state::spg290_blit_sprite(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t control, uint32_t attribute, uint32_t *palettes, uint32_t buf_start) +void spg29x_game_state::gpio_out_w(offs_t offset, uint32_t data, uint32_t mem_mask) { - uint32_t sprite_base = buf_start + ((control & 0xffff) << 8); - uint16_t sprite_x = (control >> 16) & 0x3ff; - uint16_t sprite_y = (attribute >> 16) & 0x3ff; - uint8_t sprite_hsize = 8 << ((attribute >> 4) & 0x03); - uint8_t sprite_vsize = 8 << ((attribute >> 6) & 0x03); - uint8_t bit_pixel = ((attribute & 3) + 1) << 1; - uint8_t pixel_word = 32 / bit_pixel; - uint8_t word_line = sprite_hsize / pixel_word; - uint8_t sprite_flip = (attribute >> 2) & 0x03; - - for (int y=0; y < sprite_vsize; y++) - for (int x=0; x < word_line; x++) - { - uint32_t data = spg290_read_mem(sprite_base + (y * pixel_word + x) * 4); + COMBINE_DATA(&m_gpio_out); - for (int b=0; b < pixel_word; b++) - { - uint16_t pen = ((data >> (b * bit_pixel)) & ((1 << bit_pixel) - 1)); - uint16_t posx; - if (sprite_flip & 0x01) - posx = sprite_x + (sprite_hsize - (x * word_line + b)); - else - posx = sprite_x + x * (word_line) + b; - - uint16_t posy; - if (sprite_flip & 0x02) - posy = sprite_y + (sprite_vsize - y); - else - posy = sprite_y + y; - - spg290_argb1555(bitmap, cliprect, posy, posx, palettes[pen]); - } - } + if (ACCESSING_BITS_0_7) + m_hyperscan_card->write(BIT(m_gpio_out,1)); + + for(int i=0; i<8; i++) + m_leds[i] = BIT(m_gpio_out, 5 + i); } -void spg29x_game_state::spg290_blit_bitmap(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t control, uint32_t attribute, int posy, int posx, uint32_t nptr, uint32_t buf_start, uint32_t transrgb) +uint16_t spg29x_game_state::i2c_r(offs_t offset) { - for (int y=0; y<512; y++) - { - int line = (control & 0x04) ? 0 : y; - uint32_t tx_start = spg290_read_mem(nptr + (posy + line) * 4); + int port = (offset >> 4) & 0x0f; - for (int x=0; x < 1024>>1; x++) - { - uint32_t data = spg290_read_mem(buf_start + (tx_start + posx) * 2 + x * 4); + if (port < 2) + return m_hyperscan_ctrl[port]->read(offset); - for (int b=0; b < 2; b++) - { - uint16_t posx = x * 2 + b; - uint16_t posy = y; - uint16_t pix = (data >> (b*16)) & 0xffff; - - if (control & 0x0080) - spg290_argb1555(bitmap, cliprect, posy, posx, pix); - if (control & 0x1000) - spg290_rgb565(bitmap, cliprect, posy, posx, pix, transrgb); - } - } - } -} - -void spg29x_game_state::spg290_blit_character(bitmap_rgb32 &bitmap, const rectangle &cliprect, uint32_t control, uint32_t attribute, int posy, int posx, uint32_t nptr, uint32_t buf_start, uint32_t transrgb) -{ - // TODO + return 0xffff; } - uint32_t spg29x_game_state::spg290_screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { - if (m_ppu.control & 0x1000) + m_ppu->screen_update(screen, bitmap, cliprect); + + if (m_tve_fade_offset) { - for (int depth=0; depth<4; depth++) - { - // draw the bitmap/text layers - for (int l=0; l<3; l++) - if ((m_ppu.txs[l].control & 0x08) && ((m_ppu.txs[l].attribute >> 13) & 3) == depth) - { - if (m_ppu.txs[l].control & 0x01) - spg290_blit_bitmap(bitmap, cliprect, m_ppu.txs[l].control, m_ppu.txs[l].attribute, m_ppu.txs[l].posy & 0x1ff, m_ppu.txs[l].posx & 0x1ff, m_ppu.txs[l].nptr, m_ppu.txs[l].buf_start[0], m_ppu.transrgb); - else - spg290_blit_character(bitmap, cliprect, m_ppu.txs[l].control, m_ppu.txs[l].attribute, m_ppu.txs[l].posy & 0x1ff, m_ppu.txs[l].posx & 0x1ff, m_ppu.txs[l].nptr, m_ppu.txs[l].buf_start[0], m_ppu.transrgb); - } - - // draw the sprites - for (int i=0; i<=(m_ppu.sprite_max & 0x1ff); i++) + int fade_offset = 255 - m_tve_fade_offset; + for (int y=0; y <= cliprect.max_y; y++) + for (int x=0; x <= cliprect.max_x; x++) { - if (((m_ppu.sprites[i].attribute >> 13) & 3) == depth) - spg290_blit_sprite(bitmap, cliprect, m_ppu.sprites[i].control, m_ppu.sprites[i].attribute, m_ppu.palettes, m_ppu.sprite_buf_start); + auto pix = rgb_t(bitmap.pix32(y, x)); + bitmap.pix32(y, x) = rgb_t(pix.r() * fade_offset / 255, pix.g() * fade_offset / 255, pix.b() * fade_offset / 255); } - } - } - else - { - bitmap.fill(rgb_t::black(), cliprect); } return 0; } -void spg29x_game_state::spg290_timers_update() -{ - for(auto & elem : m_timers) - if (elem.control & 0x80000000) - { - if (((elem.control2 >> 30) & 0x03) == 0x00) - { - if (elem.counter == 0xffff) - { - elem.counter = elem.preload; - if (elem.control & 0x08000000) - { - elem.control |= 0x04000000; - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 56); // SCORE7 - } - } - else - elem.counter++; - } - else - { - // TODO: capture, comparison and PWM mode - - } - } -} - -WRITE_LINE_MEMBER(spg29x_game_state::spg290_vblank_irq) -{ - if (state && m_ppu.irq_control & 0x01) // VBlanking Start IRQ - { - m_ppu.irq_status |= 0x01; - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 53); // SCORE7 - } - else if (!state && m_ppu.irq_control & 0x02) // VBlanking End IRQ - { - m_ppu.irq_status |= 0x02; - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 53); // SCORE7 - } -} - - -void spg29x_game_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) -{ - switch (id) - { - case TIMER_SPG290: - spg290_timers_update(); - break; - case TIMER_I2C: - if ((m_i2c.config & 0x40) && (m_i2c.config & 0x01)) - { - // TODO: replace with real I2C emulation - m_i2c.rdata = 0; - - m_maincpu->set_input_line_and_vector(0, HOLD_LINE, 39); // SCORE7 - } - break; - } -} - void spg29x_game_state::spg290_mem(address_map &map) { map.global_mask(0x1fffffff); map(0x00000000, 0x00ffffff).ram().mirror(0x07000000); - map(0x08000000, 0x09ffffff).rw(FUNC(spg29x_game_state::spg290_regs_r), FUNC(spg29x_game_state::spg290_regs_w)); + + map(0x08030000, 0x08030003).w(FUNC(spg29x_game_state::tve_control_w)).lr32(NAME([this](uint32_t data) { return m_tve_control; })); + map(0x0803000c, 0x0803000f).lw32(NAME([this](uint32_t data) { m_tve_fade_offset = data & 0xff; })); + map(0x0807006c, 0x0807006f).lr32(NAME([]() { return 0x01;})); // MUI Status: SDRAM is in the self-refresh mode + //map(0x08150000, 0x08150000).lw8(NAME([this](uint8_t data) { printf("%c", data); })); // UART + map(0x082100e4, 0x082100e7).w(FUNC(spg29x_game_state::timers_clk_sel_w)); // Timer Source Clock Selection + map(0x08240000, 0x0824000f).noprw(); + + //map(0x08000000, 0x0800ffff); // CSI + map(0x08010000, 0x0801ffff).m("ppu", FUNC(spg290_ppu_device::map)); + //map(0x08020000, 0x0802ffff); // JPG + //map(0x08030000, 0x0803ffff); // TV + //map(0x08040000, 0x0804ffff); // LCD + //map(0x08050000, 0x0805ffff); // SPU + map(0x08060000, 0x0806ffff).rw("cdservo", FUNC(spg290_cdservo_device::read), FUNC(spg290_cdservo_device::write)); + //map(0x08070000, 0x0807ffff); // MIU + //map(0x08080000, 0x0808ffff); // APBDMA + //map(0x08090000, 0x0809ffff); // BUFCTL + //map(0x080a0000, 0x080affff); // IRQCTL + //map(0x080b0000, 0x080bffff); // GPUBUF + //map(0x080c0000, 0x080cffff); // LDMDMA + //map(0x080d0000, 0x080dffff); // BLNDMA + //map(0x080e0000, 0x080effff); // TPGBUF + //map(0x080f0000, 0x080fffff); // AHBDEC + //map(0x08100000, 0x0810ffff); // GPIO + //map(0x08110000, 0x0811ffff); // SPI + //map(0x08120000, 0x0812ffff); // SIO + map(0x08130000, 0x0813ffff).rw("i2c", FUNC(spg290_i2c_device::read), FUNC(spg290_i2c_device::write)); + //map(0x08140000, 0x0814ffff); // I2S + //map(0x08150000, 0x0815ffff); // UART + map(0x08160000, 0x08160fff).rw(m_timers[0], FUNC(spg290_timer_device::read), FUNC(spg290_timer_device::write)); + map(0x08161000, 0x08161fff).rw(m_timers[1], FUNC(spg290_timer_device::read), FUNC(spg290_timer_device::write)); + map(0x08162000, 0x08162fff).rw(m_timers[2], FUNC(spg290_timer_device::read), FUNC(spg290_timer_device::write)); + map(0x08163000, 0x08163fff).rw(m_timers[3], FUNC(spg290_timer_device::read), FUNC(spg290_timer_device::write)); + map(0x08164000, 0x08164fff).rw(m_timers[4], FUNC(spg290_timer_device::read), FUNC(spg290_timer_device::write)); + map(0x08165000, 0x08165fff).rw(m_timers[5], FUNC(spg290_timer_device::read), FUNC(spg290_timer_device::write)); + //map(0x08166000, 0x08166fff); // RTC + //map(0x08170000, 0x0817ffff); // WDOG + //map(0x08180000, 0x0818ffff); // SD + //map(0x08190000, 0x0819ffff); // FLASH + //map(0x081a0000, 0x081affff); // ADC + //map(0x081b0000, 0x081bffff); // USB device + //map(0x081c0000, 0x081cffff); // USB host + //map(0x081d0000, 0x081dffff); // reserved + //map(0x081e0000, 0x081effff); // Reserved + //map(0x081f0000, 0x081fffff); // reserved + //map(0x08200000, 0x0820ffff); // SFTCFG + //map(0x08210000, 0x0821ffff); // CKG + map(0x0821006c, 0x0821006f).w(m_timers[0], FUNC(spg290_timer_device::control_w)); + map(0x08210070, 0x08210073).w(m_timers[1], FUNC(spg290_timer_device::control_w)); + map(0x08210074, 0x08210077).w(m_timers[2], FUNC(spg290_timer_device::control_w)); + map(0x08210078, 0x0821007b).w(m_timers[3], FUNC(spg290_timer_device::control_w)); + map(0x0821007c, 0x0821007f).w(m_timers[4], FUNC(spg290_timer_device::control_w)); + map(0x08210080, 0x08210083).w(m_timers[5], FUNC(spg290_timer_device::control_w)); + //map(0x08220000, 0x0822ffff); // MP4 + //map(0x08230000, 0x0823ffff); // MIU2 + //map(0x08240000, 0x0824ffff); // ECC + map(0x0a000000, 0x0a003fff).ram(); // internal SRAM map(0x0b000000, 0x0b007fff).rom().region("spg290", 0); // internal ROM } @@ -648,8 +322,9 @@ void spg29x_game_state::spg290_mem(address_map &map) void spg29x_game_state::spg290_bios_mem(address_map& map) { spg290_mem(map); - map(0x10000000, 0x100fffff).rom().region("bios", 0).mirror(0x0e000000); - map(0x11000000, 0x110fffff).rom().region("bios", 0).mirror(0x0e000000); + map(0x08200024, 0x08200027).w(FUNC(spg29x_game_state::gpio_out_w)).lr32(NAME([this]() { return m_gpio_out; })); + map(0x08200068, 0x0820006b).lr32(NAME([this]() { return m_hyperscan_card->read(); })); + map(0x10000000, 0x100fffff).rom().region("bios", 0).mirror(0x0ff00000); } /* Input ports */ @@ -659,16 +334,18 @@ INPUT_PORTS_END void spg29x_game_state::machine_start() { - m_update_timer = timer_alloc(TIMER_SPG290); - m_i2c_timer = timer_alloc(TIMER_I2C); + m_leds.resolve(); + + save_item(NAME(m_tve_control)); + save_item(NAME(m_tve_fade_offset)); + save_item(NAME(m_gpio_out)); } void spg29x_game_state::machine_reset() { - memset(&m_ppu, 0, sizeof(spg290_ppu)); - memset(&m_miu, 0, sizeof(spg290_miu)); - memset(&m_i2c, 0, sizeof(m_i2c)); - m_i2c_timer->adjust(attotime::never, 0, attotime::never); + m_tve_control = 0; + m_tve_fade_offset = 0; + m_gpio_out = 0; // disable JTAG m_maincpu->set_state_int(SCORE_CR + 29, 0x20000000); @@ -722,25 +399,49 @@ void spg29x_zone3d_game_state::machine_reset() void spg29x_game_state::spg29x(machine_config &config) { /* basic machine hardware */ - SCORE7(config, m_maincpu, XTAL(27'000'000) * 4); // 108MHz S+core 7 + SCORE7(config, m_maincpu, 27_MHz_XTAL * 4); // 108MHz S+core 7 m_maincpu->set_addrmap(AS_PROGRAM, &spg29x_game_state::spg290_mem); - SOFTWARE_LIST(config, "cd_list").set_original("hyperscan"); - /* video hardware */ - screen_device &screen(SCREEN(config, "screen", SCREEN_TYPE_RASTER)); - screen.set_refresh_hz(50); - screen.set_vblank_time(ATTOSECONDS_IN_USEC(2500)); /* not accurate */ - screen.set_screen_update(FUNC(spg29x_game_state::spg290_screen_update)); - screen.set_size(640, 480); - screen.set_visarea(0, 640-1, 0, 480-1); - screen.screen_vblank().set(FUNC(spg29x_game_state::spg290_vblank_irq)); + SCREEN(config, m_screen, SCREEN_TYPE_RASTER); + m_screen->set_raw(27_MHz_XTAL, 858, 0, 640, 525, 0, 480); + m_screen->set_screen_update(FUNC(spg29x_game_state::spg290_screen_update)); + m_screen->screen_vblank().set(m_ppu, FUNC(spg290_ppu_device::screen_vblank)); + + for (int i=0; i<6; i++) + { + SPG290_TIMER(config, m_timers[i], 27_MHz_XTAL); + m_timers[i]->irq_cb().set_inputline(m_maincpu, 56); + } + + SPG290_PPU(config, m_ppu, 27_MHz_XTAL, m_screen); + m_ppu->vblank_irq_cb().set_inputline(m_maincpu, 53); + m_ppu->space_read_cb().set(FUNC(spg29x_game_state::space_dword_r)); + + spg290_cdservo_device &cdservo(SPG290_CDSERVO(config, "cdservo", 27_MHz_XTAL, "cdrom")); + cdservo.irq_cb().set_inputline(m_maincpu, 60); + cdservo.space_write_cb().set(FUNC(spg29x_game_state::space_byte_w)); + + SPG290_I2C(config, m_i2c, 27_MHz_XTAL); + m_i2c->irq_cb().set_inputline(m_maincpu, 39); } void spg29x_game_state::hyperscan(machine_config &config) { spg29x(config); m_maincpu->set_addrmap(AS_PROGRAM, &spg29x_game_state::spg290_bios_mem); + + m_i2c->i2c_read_cb().set(FUNC(spg29x_game_state::i2c_r)); + + CDROM(config, "cdrom").set_interface("cdrom"); + + HYPERSCAN_CTRL(config, m_hyperscan_ctrl[0], 0); + HYPERSCAN_CTRL(config, m_hyperscan_ctrl[1], 0); + + HYPERSCAN_CARD(config, m_hyperscan_card, 0); + + SOFTWARE_LIST(config, "cd_list").set_original("hyperscan"); + SOFTWARE_LIST(config, "card_list").set_original("hyperscan_card"); } void spg29x_nand_game_state::nand_init(int blocksize, int blocksize_stripped) diff --git a/src/mame/machine/hyperscan_card.cpp b/src/mame/machine/hyperscan_card.cpp new file mode 100644 index 00000000000..2e1f87f2a38 --- /dev/null +++ b/src/mame/machine/hyperscan_card.cpp @@ -0,0 +1,275 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco +/***************************************************************************** + + Hyperscan RFID card + +*****************************************************************************/ + +#include "emu.h" +#include "hyperscan_card.h" + +//#define LOG_OUTPUT_FUNC printf +//#define VERBOSE 1 +#include "logmacro.h" + + +DEFINE_DEVICE_TYPE(HYPERSCAN_CARD, hyperscan_card_device, "hyperscan_card", "Hyperscan RFID card") + + +hyperscan_card_device::hyperscan_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, HYPERSCAN_CARD, tag, owner, clock) + , device_image_interface(mconfig, *this) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void hyperscan_card_device::device_start() +{ + save_item(NAME(m_state)); + save_item(NAME(m_bit_pos)); + save_item(NAME(m_data)); + save_item(NAME(m_cmd_buf)); + save_item(NAME(m_resp_buf)); + save_item(NAME(m_resp_idx)); + save_item(NAME(m_last_at)); + save_item(NAME(m_memory)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void hyperscan_card_device::device_reset() +{ + m_state = 0; + m_bit_pos = 0; + m_data = 0; + m_cmd_buf.clear(); + m_resp_buf.clear(); + m_resp_idx = 0; + m_last_at = attotime::zero; +} + +/*------------------------------------------------- + call_load() +-------------------------------------------------*/ + +image_init_result hyperscan_card_device::call_load() +{ + if (fread(m_memory, sizeof(m_memory)) != sizeof(m_memory)) + return image_init_result::FAIL; + + battery_load(m_memory, sizeof(m_memory), nullptr); + + return image_init_result::PASS; +} + + +/*------------------------------------------------- + call_unload() +-------------------------------------------------*/ + +void hyperscan_card_device::call_unload() +{ + memset(m_memory, 0, sizeof(m_memory)); +} + + +/*------------------------------------------------- + CRC +-------------------------------------------------*/ +uint16_t hyperscan_card_device::calc_crc(std::vector const &data) +{ + uint16_t crc = 0xffffU; + + for (auto b : data) + { + b ^= crc & 0xff; + b ^= b << 4; + + crc = (crc >> 8) ^ ((uint16_t)b << 8) ^ ((uint16_t)b << 3) ^ ((uint16_t)b >> 4); + } + + return ~crc; +} + + +void hyperscan_card_device::resp_add_byte(uint8_t data, bool add_parity) +{ + int parity = 1; + for (int i=0; i<8; i++) + { + int bit = BIT(data, i); + m_resp_buf.push_back(bit); + parity ^= bit; + } + + if (add_parity) + m_resp_buf.push_back(parity); +} + +void hyperscan_card_device::make_resp(std::vector const &data, bool add_crc) +{ + m_resp_idx = 0; + m_resp_buf.clear(); + + resp_add_byte(0x00, false); + resp_add_byte(0x80, false); + + for (auto b : data) + resp_add_byte(b, true); + + if (add_crc) + { + uint16_t crc = calc_crc(data); + resp_add_byte(crc, true); + resp_add_byte(crc >> 8, true); + } +} + +void hyperscan_card_device::check_command() +{ + std::vector buf; + + if (m_cmd_buf.size() == 1 && m_cmd_buf[0] == 0x26) // REQA + { + LOG("RFID: REQA\n"); + buf.clear(); + buf.push_back(0x00); // ATQA0 + buf.push_back(0x00); // ATQA1 + m_cmd_buf.clear(); + make_resp(buf, false); + } + else if (m_cmd_buf.size() == 1 && m_cmd_buf[0] == 0x52) // WUPA + { + LOG("RFID: WUPA\n"); + buf.clear(); + buf.push_back(0x00); // ATQA0 + buf.push_back(0x00); // ATQA1 + m_cmd_buf.clear(); + make_resp(buf, false); + } + else if (m_cmd_buf.size() == 9 && m_cmd_buf[0] == 0x78) // RID + { + LOG("RFID: RID\n"); + buf.clear(); + buf.push_back(0x11); // HR0 + buf.push_back(0x00); // HR1 + for (int i=0; i<4; i++) + buf.push_back(m_memory[i]); // UID + + m_cmd_buf.clear(); + make_resp(buf, true); + } + else if (m_cmd_buf.size() == 9 && m_cmd_buf[0] == 0x01) // READ + { + if (m_cmd_buf[1] >= sizeof(m_memory)) m_cmd_buf[1] %= sizeof(m_memory); + LOG("RFID: READ %x %02x\n", m_cmd_buf[1], m_memory[m_cmd_buf[1]]); + buf.clear(); + buf.push_back(m_cmd_buf[1]); // ADD + buf.push_back(m_memory[m_cmd_buf[1]]); // DATA + m_cmd_buf.clear(); + make_resp(buf, true); + } + else if (m_cmd_buf.size() == 9 && m_cmd_buf[0] == 0x00) // RALL + { + LOG("RFID: RALL\n"); + buf.clear(); + buf.push_back(0x11); // HR0 + buf.push_back(0x00); // HR1 + for (int i=0; i= sizeof(m_memory)) m_cmd_buf[1] %= sizeof(m_memory); + + if (m_memory[m_cmd_buf[1]] != m_cmd_buf[2]) + { + m_memory[m_cmd_buf[1]] = m_cmd_buf[2]; + battery_save(m_memory, sizeof(m_memory)); + } + + buf.clear(); + buf.push_back(m_cmd_buf[1]); // ADD + buf.push_back(m_cmd_buf[2]); // DATA + m_cmd_buf.clear(); + make_resp(buf, true); + } + else if (m_cmd_buf.size() == 9 && m_cmd_buf[0] == 0x1a) // WRITE-NE + { + LOG("RFID: WRITE-NE %x %02x\n", m_cmd_buf[1], m_cmd_buf[2]); + if (m_cmd_buf[1] >= sizeof(m_memory)) m_cmd_buf[1] %= sizeof(m_memory); + + if (m_memory[m_cmd_buf[1]] != (m_memory[m_cmd_buf[1]] | m_cmd_buf[2])) + { + m_memory[m_cmd_buf[1]] |= m_cmd_buf[2]; + battery_save(m_memory, sizeof(m_memory)); + } + + buf.clear(); + buf.push_back(m_cmd_buf[1]); // ADD + buf.push_back(m_cmd_buf[2]); // DATA + m_cmd_buf.clear(); + make_resp(buf, true); + } +} + +void hyperscan_card_device::write(int state) +{ + if (m_state == state || !is_loaded()) + return; + + m_state = state; + + // 13.56MHz + int clk = 13560000 / (machine().time() - m_last_at).as_hz(); + m_last_at = machine().time(); + + if (state) + return; + + if (clk < 1000) + { + if (clk < 500) + m_data &= ~(1 << m_bit_pos); + else + m_data |= 1 << m_bit_pos; + + m_bit_pos++; + + if ((m_cmd_buf.size() == 0 && m_bit_pos == 7) || m_bit_pos == 8) + { + if (m_cmd_buf.size() == 0) + m_data &= 0x7f; + + m_cmd_buf.push_back(m_data); + m_data = 0; + m_bit_pos = 0; + check_command(); + } + } + else if (clk < 5000) + { + m_bit_pos = 0; + m_data = 0; + if (m_resp_idx <= m_resp_buf.size() * 2) + m_resp_idx++; + } +} + +int hyperscan_card_device::read() +{ + if (is_loaded() && (m_resp_idx >> 1) < m_resp_buf.size()) + return m_resp_buf[m_resp_idx >> 1] ^ (m_resp_idx & 1); + + return 0; +} diff --git a/src/mame/machine/hyperscan_card.h b/src/mame/machine/hyperscan_card.h new file mode 100644 index 00000000000..c1d2cff450e --- /dev/null +++ b/src/mame/machine/hyperscan_card.h @@ -0,0 +1,58 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco + + +#ifndef MAME_MACHINE_HYPERSCAN_CARD_H +#define MAME_MACHINE_HYPERSCAN_CARD_H + +#pragma once + +#include "softlist_dev.h" + +class hyperscan_card_device : public device_t, + public device_image_interface +{ +public: + hyperscan_card_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + int read(); + void write(int state); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + // image-level overrides + virtual image_init_result call_load() override; + virtual void call_unload() override; + virtual iodevice_t image_type() const noexcept override { return IO_MEMCARD; } + virtual bool is_readable() const noexcept override { return true; } + virtual bool is_writeable() const noexcept override { return true; } + virtual bool is_creatable() const noexcept override { return false; } + virtual bool must_be_loaded() const noexcept override { return false; } + virtual bool is_reset_on_load() const noexcept override { return false; } + virtual const char *image_interface() const noexcept override { return "hyperscan_card"; } + virtual const char *file_extensions() const noexcept override { return "bin"; } + + // device_image_interface implementation + virtual const software_list_loader &get_software_list_loader() const override { return image_software_list_loader::instance(); } + +private: + uint16_t calc_crc(std::vector const &data); + void resp_add_byte(uint8_t data, bool add_parity); + void make_resp(std::vector const &data, bool add_crc); + void check_command(); + + int m_state; + int m_bit_pos; + uint8_t m_data; + std::vector m_cmd_buf; + std::vector m_resp_buf; + uint8_t m_resp_idx; + attotime m_last_at; + uint8_t m_memory[120]; +}; + +DECLARE_DEVICE_TYPE(HYPERSCAN_CARD, hyperscan_card_device) + +#endif // MAME_MACHINE_HYPERSCAN_CARD_H diff --git a/src/mame/machine/hyperscan_ctrl.cpp b/src/mame/machine/hyperscan_ctrl.cpp new file mode 100644 index 00000000000..c99972feab8 --- /dev/null +++ b/src/mame/machine/hyperscan_ctrl.cpp @@ -0,0 +1,106 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco +/***************************************************************************** + + Hyperscan controller + + The controller contains a SPC11122A MCU and a Winbond W55AD808 ADC. + + Pinouts: + + 3 4 + 2 I 5 + 1 I 6 + + 1: Brown : GND + 2: Yellow : DATA + 3: Grey : CLK + 4: Green : ENABLE + 5: Blue : RESET + 6: Red : VCC 3.3v + +*****************************************************************************/ + +#include "emu.h" +#include "hyperscan_ctrl.h" + + +DEFINE_DEVICE_TYPE(HYPERSCAN_CTRL, hyperscan_ctrl_device, "hyperscan_ctrl", "Hyperscan controller HLE") + + +hyperscan_ctrl_device::hyperscan_ctrl_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, HYPERSCAN_CTRL, tag, owner, clock) + , m_inputs(*this, "IN.%u", 0U) +{ +} + +static INPUT_PORTS_START( hyperscan_ctrl ) + PORT_START("IN.0") + PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_NAME("Blue") + PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_START) PORT_NAME("Start") + PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_SELECT) PORT_NAME("Select") + PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_NAME("Left Shoulder") + PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_BUTTON7) PORT_NAME("Right Shoulder") + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_NAME("Left Trigger") + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_BUTTON8) PORT_NAME("Right Trigger") + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_UNUSED) + + PORT_START("IN.1") + PORT_BIT(0x1f, IP_ACTIVE_HIGH, IPT_UNUSED) + PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_BUTTON2) PORT_NAME("Yellow") + PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_NAME("Red") + PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_BUTTON1) PORT_NAME("Green") + + PORT_START("IN.2") + PORT_BIT(0xff, 0x7f, IPT_AD_STICK_Y) PORT_NAME("Analog Y") PORT_REVERSE PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_CENTERDELTA(50) + + PORT_START("IN.3") + PORT_BIT(0xff, 0x7f, IPT_AD_STICK_X) PORT_NAME("Analog X") PORT_REVERSE PORT_SENSITIVITY(100) PORT_KEYDELTA(30) PORT_CENTERDELTA(50) +INPUT_PORTS_END + + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void hyperscan_ctrl_device::device_start() +{ + save_item(NAME(m_input_data)); +} + +//------------------------------------------------- +// device_reset - device-specific reset +//------------------------------------------------- + +void hyperscan_ctrl_device::device_reset() +{ + m_input_data[0] = m_input_data[1] = m_input_data[2] = m_input_data[3] = 0; +} + + +//------------------------------------------------- +// input_ports - device-specific input ports +//------------------------------------------------- + +ioport_constructor hyperscan_ctrl_device::device_input_ports() const +{ + return INPUT_PORTS_NAME( hyperscan_ctrl ); +} + + +uint16_t hyperscan_ctrl_device::read(offs_t offset) +{ + int port = (offset >> 4) & 0x0f; + int addr = offset & 0x0f; + + if (addr < 4) + { + m_input_data[addr] = m_inputs[addr]->read(); + return m_input_data[addr]; + } + else + { + // this is used to validate the inputs + return ((m_input_data[0] + m_input_data[1] + m_input_data[2] + m_input_data[3]) << 2) | port; + } +} diff --git a/src/mame/machine/hyperscan_ctrl.h b/src/mame/machine/hyperscan_ctrl.h new file mode 100644 index 00000000000..f85ce86b88a --- /dev/null +++ b/src/mame/machine/hyperscan_ctrl.h @@ -0,0 +1,31 @@ +// license:BSD-3-Clause +// copyright-holders:Sandro Ronco + + +#ifndef MAME_MACHINE_HYPERSCAN_CTRL_H +#define MAME_MACHINE_HYPERSCAN_CTRL_H + +#pragma once + +class hyperscan_ctrl_device : public device_t +{ +public: + hyperscan_ctrl_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock); + + uint16_t read(offs_t offset); + +protected: + virtual void device_start() override; + virtual void device_reset() override; + + // optional information overrides + virtual ioport_constructor device_input_ports() const override; + +private: + required_ioport_array<4> m_inputs; + uint8_t m_input_data[4]; +}; + +DECLARE_DEVICE_TYPE(HYPERSCAN_CTRL, hyperscan_ctrl_device) + +#endif // MAME_MACHINE_HYPERSCAN_CTRL_H -- cgit v1.2.3