rename
This commit is contained in:
65
tools/ucon64/src/console/boardnames
Normal file
65
tools/ucon64/src/console/boardnames
Normal file
@@ -0,0 +1,65 @@
|
||||
351258: UNROM
|
||||
351298: UNROM
|
||||
351908
|
||||
352026: TLROM (w/ LS32 for VROM enable control)
|
||||
51555: Acclaim, MMC3B mapper, PRG ROM, CHR ROM
|
||||
53361
|
||||
54425
|
||||
55741
|
||||
56504
|
||||
AMROM: LS161, VRAM, PRG-ROM
|
||||
ANROM: LS161+LS02 mapper, PRG-ROM, CHR-RAM
|
||||
AOROM: LS161 mapper, PRG-ROM, CHR-ROM
|
||||
BNROM: LS161, VRAM, PRG-ROM (Different LS161 bits? Only used on Deadly Towers)
|
||||
CNROM: LS161 mapper, PRG-ROM, CHR-ROM?/CHR-RAM
|
||||
COB: "Glop Top" style board
|
||||
CPROM: LS04, LS08, LS161, 32K ROM, 16K VRAM (bankswitched, Videomation only)
|
||||
DEIROM
|
||||
DEROM
|
||||
DRROM: MMC3, 4K of nametable RAM (for 4-screen), PRG-ROM, CHR-ROM (only in Gauntlet)
|
||||
EKROM
|
||||
ELROM: MMC5, PRG-ROM, CHR-ROM
|
||||
ETROM: MMC5, PRG-ROM, CHR-ROM, 2x 8k optionnal RAM (battery)
|
||||
EWROM: MMC5, PRG-ROM, CHR-ROM, 32k optionnal RAM (battery)
|
||||
GNROM: LS161 mapper, PRG ROM, CHR ROM
|
||||
HKROM: MMC6B, PRG-ROM, CHR-ROM, Battery
|
||||
MHROM: LS161 mapper, black blob chips. Mario Bros / Duck Hunt multi
|
||||
NES-B4: Same as TLROM
|
||||
NES-BTR: Sunsoft FME7 mapper, PRG ROM, CHR ROM, 8k optionnal RAM
|
||||
NES-QJ:
|
||||
NES-RROM: Same as NROM (Only used in Clu Clu land)
|
||||
NROM: No mapper, PRG-ROM, CHR-ROM
|
||||
PNROM: MMC2, PRG-ROM, CHR-ROM
|
||||
SAROM: MMC1B, PRG ROM, CHR ROM, optional 8k of RAM (battery)
|
||||
SBROM: MMC1A, PRG ROM, CHR ROM (only 32K of CHR ROM)
|
||||
SCEOROM
|
||||
SC1ROM: MMC1B, PRG ROM, CHR ROM
|
||||
SCROM: LS161, LS02, VRAM, PRG-ROM (Similar to UNROM)
|
||||
SEROM: MMC1B, PRG ROM, CHR ROM
|
||||
SFROM
|
||||
SGROM: MMC1B, PRG ROM, 8k CHR RAM
|
||||
SHROM
|
||||
SJROM
|
||||
SKROM: MMC1B, PRG ROM, CHR ROM, 8k optional RAM (battery)
|
||||
SL1ROM: MMC3, PRG ROM, CHR ROM, LS32 (for 128K 28 pin CHR ROMs)
|
||||
SL2ROM
|
||||
SL3ROM
|
||||
SLROM: MMC1A, PRG ROM, CHR ROM
|
||||
SLRROM
|
||||
SN1-ROM AW (Overlord only)
|
||||
SNROM: MMC1A, PRG ROM, CHR ROM/RAM ?, 8k optional RAM (battery)
|
||||
SOROM: MMC1B2, PRG ROM, VRAM, 16K of WRAM (Battery) Only 8K battery-backed
|
||||
SVROM: MMC1B2, PRG ROM, VRAM, WRAM (Battery)
|
||||
SUROM: MMC1B2, PRG ROM, CHR RAM/(ROM?), 8k battery-backed RAM (DW4???)
|
||||
TEROM: MMC3A, PRG ROM, CHR ROM, (32k ROMs)
|
||||
TFROM: MMC3B, PRG ROM, CHR ROM (64K of CHR only)
|
||||
TGROM: MMC3C, PRG ROM, VRAM (512K of PRG)
|
||||
TKROM: MMC3A, PRG ROM, CHR ROM, 8k optional RAM (battery)
|
||||
TL1ROM: Same as TLROM
|
||||
TLROM: MMC3B, PRG ROM, CHR ROM
|
||||
TLSROM: Same as TLROM
|
||||
TQROM: MMC3B+74HC32, PRG ROM, CHR ROM + 8k of CHR-RAM
|
||||
TSROM: MMC3A, PRG ROM, CHR ROM, 8k optionnal RAM
|
||||
TVROM: MMC3B, PRG ROM, CHR ROM, 4K of Nametable RAM (4-screen)
|
||||
UNROM: 74LS32+74LS161 mapper, 128k PRG, 8k CHR-RAM
|
||||
UOROM
|
||||
782
tools/ucon64/src/console/boardtable.txt
Normal file
782
tools/ucon64/src/console/boardtable.txt
Normal file
@@ -0,0 +1,782 @@
|
||||
Name |Maker |RR|Board
|
||||
--------------------------------------+--------------------+--+----------------
|
||||
10 Yard Fight |Nintendo |E |NROM
|
||||
110 in 1 (Canada?) |Supervision | |
|
||||
1942 |Capcom |C+|NROM
|
||||
1943 |Capcom |C+|UNROM
|
||||
6 in 1 |Caltron |A |
|
||||
720 |Mindscape |C |SGROM
|
||||
8 Eyes |Taxan |C-|TLROM
|
||||
A Boy and His Blob |Absolute |C |SLROM
|
||||
Abadox |Milton Bradley |C |SLROM
|
||||
Action 52 |Active Enterprises |A |
|
||||
Addams Family |Ocean |B |SLROM
|
||||
Adv of Bayou Billy |Konami |C-|SLROM
|
||||
Adv of Dino Riki |Hudson |C |CNROM
|
||||
Adv of Lolo |HAL |C+|SEROM
|
||||
Adv of Lolo 2 |HAL |B-|TEROM
|
||||
Adv of Lolo 3 |HAL |B+|SLROM
|
||||
Adv of Tom Saywer |Seta |B |SLROM
|
||||
Adventure Island |Hudson |D |CNROM
|
||||
Adventure Island 2 |Hudson |B-|TLROM
|
||||
Adventure Island 3 |Hudson |B |TLROM
|
||||
After Burner |Tengen |C+|
|
||||
Air Fortress |HAL |C |SJROM
|
||||
Airwolf |Acclaim |C |SHROM
|
||||
Al Unser Racing |Data East |C |SKROM
|
||||
Aladdin Deck Enhancer |Camerica |A+|
|
||||
Alfred Chicken |Mindscape |B+|UNROM
|
||||
Alien 3 |LJN |B+|55741
|
||||
Alien Syndrome |Tengen |C+|
|
||||
All Pro Basketball |Vic Tokai |C |SLROM
|
||||
Alpha Mission |SNK |C |CNROM
|
||||
Amagon |American Sammy |C |UNROM
|
||||
American Gladiators |Gametek |B-|SLROM
|
||||
Anticipation |Nintendo |C |SEROM
|
||||
Arch Rivals |Acclaim |C |AMROM
|
||||
Archon |Activision |B |UNROM
|
||||
Arkanoid |Taito |B+|CNROM
|
||||
Arkanoid Controller |Taito |A |
|
||||
Arkistas Ring |American Sammy |B |CNROM
|
||||
Astyanax |Jaleco |C |TLROM
|
||||
Athena |SNK |C |UNROM
|
||||
Athletic World |Bandai |B-|CNROM
|
||||
Attack/Killer Tomato |T*HQ |B-|SLROM
|
||||
Baby Boomer |Color Dreams |B-|
|
||||
Back to the Future |LJN |D |CNROM
|
||||
Back to the Future 2 & 3 |LJN |C |SLROM
|
||||
Bad Dudes |Data East |C |TLROM
|
||||
Bad News Baseball |Tecmo |B |SLROM
|
||||
Bad Street Brawler |Mattel |C |SGROM
|
||||
Balloon Fight |Nintendo |C |NROM
|
||||
Bandit Kings/China |Koei |B-|ETROM
|
||||
Barbie |Hi Tech |B |SLROM
|
||||
Bard's Tale |FCI |B-|SNROM
|
||||
Base Wars |Ultra |C |TKROM
|
||||
Baseball |Nintendo |E |NROM
|
||||
Baseball Simulator |Culture Brain |C+|SKROM
|
||||
Baseball Stars |SNK |C+|SKROM
|
||||
Baseball Stars 2 |Romstar |B+|TKROM
|
||||
Bases Loaded |Jaleco |E |SFROM
|
||||
Bases Loaded 2 |Jaleco |D |SL3ROM
|
||||
Bases Loaded 3 |Jaleco |C |TLROM
|
||||
Bases Loaded 4 |Jaleco |C+|TLROM
|
||||
Batman |Sunsoft |D |NES_B4
|
||||
Batman Return/Joker |Sunsoft |B-|NES_BTR
|
||||
Batman Returns |Konami |B+|TLROM
|
||||
Battle Chess |Data East |B+|SKROM
|
||||
Battle of Olympus |Broderbund |C |SGROM
|
||||
Battle Tank |Absolute |B |CNROM
|
||||
Battle Toads |Tradewest |D |AOROM
|
||||
Battle Toads & Double Dragon |Tradewest |B+|AOROM
|
||||
Battleship |Mindscape |B |CNROM
|
||||
Bee 52 |Camerica |B+|
|
||||
Beetlejuice |LJN |C+|AMROM
|
||||
Best of the Best |Electro Brain |B+|UOROM
|
||||
Bible Adventures |Wisdom Tree |B+|
|
||||
Bible Adventures (blue label) |Wisdom Tree |B+|
|
||||
Bible Buffet |Wisdom Tree |B+|
|
||||
Big Bird Hide & Speak |Hi Tech |B |SLROM
|
||||
Big Foot |Acclaim |B-|SLROM
|
||||
Big Nose Freaks Out |Camerica |A |
|
||||
Big Nose Freaks Out (Aladdin Cart) |Camerica |A+|
|
||||
Big Nose the Caveman |Camerica |B |
|
||||
Bill & Ted Adventure |LJN |C+|SLROM
|
||||
Bill Elliot NASCAR |Konami |C+|TSROM
|
||||
Bionic Commando |Capcom |C |SGROM
|
||||
Black Bass |Hot B |B |UNROM
|
||||
Blackjack |American Video |A-|
|
||||
Blades of Steel |Konami |D |UNROM
|
||||
Blaster Master |Sunsoft |D |SL2ROM
|
||||
Blue Marlin |Hot B |B+|TLROM
|
||||
Blues Brothers |Titus |B |UNROM
|
||||
Bo Jackson Baseball |Data East |C+|TSROM
|
||||
Bomberman |Hudson |C |NROM
|
||||
Bomberman 2 |Hudson |B |SNROM
|
||||
Bonks Adventure |Hudson |B+|TLROM
|
||||
Boulder Dash |JVC |B+|SEROM
|
||||
Break Time |FCI |B+|SFROM
|
||||
Breakthru |Data East |C |(SLROM)
|
||||
Bubble Bath Babes |Panesian |A+|
|
||||
Bubble Bobble |Taito |D |SFROM
|
||||
Bubble Bobble 2 |Taito |B |TLROM
|
||||
Bucky O'Hare |Konami |B |TLROM
|
||||
Bugs Bunny Birthday Blowout |Kemco |B |TSROM
|
||||
Bugs Bunny Castle |Kemco |B+|SBROM
|
||||
Bump & Jump |Vic Tokai |B-|CNROM
|
||||
Burai Fighter |Taxan |B-|TEROM
|
||||
Burger Time |Data East |B-|NROM
|
||||
Cabal |Milton Bradley |C |AMROM
|
||||
Caesars Palace |Virgin |B |UNROM
|
||||
California Games |Milton Bradley |C |UNROM
|
||||
Captain America |Data East |B |TLROM
|
||||
Captain Comic |Color Dreams |B |
|
||||
Captain Planet |Mindscape |B |TLROM
|
||||
Captain Skyhawk |Milton Bradley |C |AMROM
|
||||
Casino Kid |Sofel |C+|UNROM
|
||||
Casino Kid 2 |Sofel |B+|UNROM
|
||||
Castelian |Triffix |B |UNROM
|
||||
Castle of Deceit |Bunch Games |B |
|
||||
Castle of Dragon |Seta |B |UNROM
|
||||
Castlequest |Nexoft |B |CNROM
|
||||
Castlevania |Konami |E |UNROM
|
||||
Castlevania 2 |Konami |D |SLROM
|
||||
Castlevania 3 |Konami |C-|ELROM
|
||||
Caveman Games |Data East |B-|SLROM
|
||||
Challenge of the Dragon |Color Dreams |B |
|
||||
Championship Bowling |Romstar |B |CNROM
|
||||
Championship Pool |Mindscape |B+|UNROM
|
||||
Cheetahman II |Active Enterprises |A |
|
||||
Chessmaster |Hi Tech |B |SJROM
|
||||
Chiller |American Game Carts Inc|B+|
|
||||
Chubby Cherub |Bandai |B |NROM
|
||||
Circus Caper |Toho |B |SLROM
|
||||
City Connection |Jaleco |B |CNROM
|
||||
Clash at Demonhead |Vic Tokai |B-|SLROM
|
||||
Classic Concentration |Gametek |B-|UNROM
|
||||
Cliffhanger |Imagesoft |B |TLROM
|
||||
Clu Clu Land |Nintendo |B-|NES_RROM
|
||||
Cobra Command |Data East |C |SLROM
|
||||
Cobra Triangle |Nintendo |B-|ANROM
|
||||
Codename Viper |Capcom |C |TLROM
|
||||
Color A Dinosaur |Virgin |A-|UNROM
|
||||
Commando |Capcom |C |UNROM
|
||||
Conan |Mindscape |B |UNROM
|
||||
Conflict |Vic Tokai |C+|SKROM
|
||||
Conquest Crystal Palace |Asmik |C+|TLROM
|
||||
Contra |Konami |E |UNROM
|
||||
Contra Force |Konami |B |TLROM
|
||||
Cool World |Ocean |B |SLROM
|
||||
Cowboy Kid |Romstar |A-|TLROM
|
||||
Crash & the Boys Street Challange |American Technos |B |TLROM
|
||||
Crash Dummies |LJN |B |55741
|
||||
Crystal Mines |Color Dreams |B+|
|
||||
Crystalis |SNK |C |TKROM
|
||||
Cyberball |Jaleco |B |TLROM
|
||||
Cybernoid |Acclaim |C |CNROM
|
||||
Dance Aerobics |Nintendo |C+|SBROM
|
||||
Darkman |Ocean |B |SLROM
|
||||
Darkwing Duck |Capcom |B+|SLROM
|
||||
Dash Galaxy |Data East |C |CNROM
|
||||
Day Dreamin' Davey |HAL |B+|SLROM
|
||||
Days of Thunder |Mindscape |C+|TLROM
|
||||
Deadly Towers |Broderbund |C+|BNROM
|
||||
Death Race |American Game Carts Inc|B+|
|
||||
Deathbots |American Video |B+|
|
||||
Defender 2 |HAL |B |NROM
|
||||
Defender of the Crown |Ultra |C+|SGROM
|
||||
Defenders of Dynacron City |JVC |B |TLROM
|
||||
Deja Vu |Kemco |C+|TKROM
|
||||
Demon Sword |Taito |C+|SL1ROM
|
||||
Desert Commander |Kemco |C-|SKROM
|
||||
Destination Earthstar |Acclaim |C |CNROM
|
||||
Destiny/Emporer |Capcom |B-|SNROM
|
||||
Dick Tracy |Bandai |C+|UNROM
|
||||
Die Hard |Activision |B+|SLROM
|
||||
Dig Dug 2 |Bandai |B |NROM
|
||||
Digger |Milton Bradley |B+|AMROM
|
||||
Dirty Harry |Mindscape |C+|TLROM
|
||||
Disney Adventure |Capcom |B |SLROM
|
||||
Dizzy the Adventurer (Aladdin Cart) |Camerica |A+|
|
||||
Donkey Kong |Nintendo |B-|NROM
|
||||
Donkey Kong 3 |Nintendo |B-|NROM
|
||||
Donkey Kong Classics |Nintendo |B-|CNROM
|
||||
Donkey Kong Jr |Nintendo |B-|NROM
|
||||
Donkey Kong Jr Math |Nintendo |A-|NROM
|
||||
Double Dare |Gametek |B |AOROM
|
||||
Double Dragon |Tradewest |E |SLROM
|
||||
Double Dragon 2 |Acclaim |D |TL1ROM
|
||||
Double Dragon 3 |Acclaim |C+|TLROM
|
||||
Double Dribble |Konami |D |UNROM
|
||||
Double Strike |American Video |B+|
|
||||
Dr. Chaos |FCI |C |UNROM
|
||||
Dr. Jeckyl/Mr. Hyde |Bandai |C+|SFROM (SFDOROM)
|
||||
Dr. Mario |Nintendo |D |SEROM
|
||||
Dracula |Imagesoft |B |TSROM
|
||||
Dragon Fighter |Sofel |B |SLROM
|
||||
Dragon Power |Bandai |C |GNROM
|
||||
Dragon Spirit |Bandai |B |TLROM
|
||||
Dragon Strike |FCI |C |TLROM
|
||||
Dragon Warrior |Nintendo |E |SAROM
|
||||
Dragon Warrior 2 |Enix |C+|SNROM
|
||||
Dragon Warrior 3 |Enix |B+|SVROM
|
||||
Dragon Warrior 4 |Enix |B |SVROM
|
||||
Dragon's Lair |Imagesoft |B |UNROM
|
||||
Duck Hunt |Nintendo |F |NROM
|
||||
Duck Tales |Capcom |C+|UNROM
|
||||
Duck Tales 2 |Capcom |B+|UNROM
|
||||
Dudes with Attitude |American Video |B+|
|
||||
Dungeon Magic |Taito |C |SKROM
|
||||
Dusty Diamond All Star Softball |Broderbund |B-|SLROM
|
||||
Dyno Warz |Bandai |C+|SLROM
|
||||
Elevator Action |Taito |B-|NROM
|
||||
Eliminator Boat Duel |Electro Brain |C+|SLROM
|
||||
Empire Strikes Back |JVC |B |TLROM
|
||||
Excitebike |Nintendo |E |NROM
|
||||
Exodus |Wisdom Tree |B+|
|
||||
F 117 Stealth |Microprose |B+|TLROM
|
||||
F 15 City War |American Video |B |
|
||||
F 15 Strike Eagle |Microprose |B+|TLROM
|
||||
F1 Built to Win |Seta |B+|SKROM
|
||||
Family Feud |Gametek |B+|SHROM
|
||||
Fantastic Adv Dizzy (Aladdin Cart) |Camerica |A+|
|
||||
Fantastic Adventures of Dizzy |Camerica |B-|
|
||||
Fantasy Zone |Tengen |C |
|
||||
Faria |Nexoft |B+|SKROM
|
||||
Fast Break |Tradewest |C |SCROM
|
||||
Faxanadu |Nintendo |C-|SGROM
|
||||
Felix the Cat |Hudson |B+|TSROM
|
||||
Ferrari Grand Prix |Acclaim |B |SLROM
|
||||
Fester's Quest |Sunsoft |C |SLROM
|
||||
Fighting Golf |SNK |C |SLROM
|
||||
Final Fantasy |Nintendo |C+|SNROM
|
||||
Fire & Ice |Tecmo |A-|TLROM
|
||||
Fire Hawk |Camerica |B |
|
||||
Firehouse Rescue |Gametek |B |CNROM
|
||||
Fist of the North Star |Taxan |C+|UNROM
|
||||
Flight of the Intruder |Mindscape |B |UNROM
|
||||
Flintstones |Taito |C+|TLROM
|
||||
Flintstones 2 |Taito |A+|
|
||||
Flying Dragon |Culture Brain |C |UNROM
|
||||
Flying Warriors |Culture Brain |C |SLROM
|
||||
Frankenstein |Bandai |B+|SLRROM
|
||||
Freedom Force |Sunsoft |D |SLROM
|
||||
Friday The 13th |LJN |C-|CNROM
|
||||
Fun House |Hi Tech |B+|UNROM
|
||||
G I Joe |Taxan |B+|TLROM
|
||||
G I Joe Atlantis Factor |Capcom |C+|TLROM
|
||||
Galactic Crusader |Bunch Games |B |
|
||||
Galaga |Bandai |B |NROM
|
||||
Galaxy 5000 |Activision |A-|TLROM
|
||||
Game Action Replay |STD |A-|
|
||||
Game Genie |Galoob |D |
|
||||
Gargoyle's Quest 2 |Capcom |B+|TLROM
|
||||
Gauntlet (licensed) |Tengen |C |DRROM
|
||||
Gauntlet (unlicensed) |Tengen |C |
|
||||
Gauntlet 2 |Mindscape |C |TSROM
|
||||
Gemfire |Koei |B-|EKROM
|
||||
Genghis Kahn |Koei |C+|SOROM
|
||||
George Forman |Acclaim |B |55741
|
||||
Ghost & Goblins |Capcom |C |UNROM
|
||||
Ghost Lion |Kemco |B |SKROM
|
||||
Ghostbusters |Activision |B-|CNROM
|
||||
Ghostbusters 2 |Activision |B |SLROM
|
||||
Ghoul School |Electro Brain |B-|SLROM
|
||||
Gilligans Island |Bandai |B+|UNROM
|
||||
Goal |Jaleco |D |SL3ROM
|
||||
Goal 2 |Jaleco |B-|TLSROM
|
||||
Godzilla |Toho |C+|SLROM
|
||||
Godzilla 2 |Toho |B |SLROM
|
||||
Gold Metal Challenge |Capcom |B+|TKROM
|
||||
Golf |Nintendo |E |NROM
|
||||
Golf Grand Slam |Atlus |B+|SLROM
|
||||
Golf Power |Virgin |B+|SNROM
|
||||
Golgo 13 Top Secret Episode |Vic Tokai |D |SLROM
|
||||
Goonies 2 |Konami |C+|351258
|
||||
Gotcha |LJN |C |CNROM
|
||||
Gradius |Konami |C-|CNROM
|
||||
Great Waldo Search |T*HQ |B-|SLROM
|
||||
Gremlins 2 |Sunsoft |B-|TLROM
|
||||
Guardian Legend |Broderbund |C+|UNROM
|
||||
Guerrilla War |SNK |C |SLROM
|
||||
Gum Shoe |Nintendo |C+|GNROM
|
||||
Gun Nac |Ascii |B |TLROM
|
||||
Gunsmoke |Capcom |B-|UNROM
|
||||
Gyromite |Nintendo |E |NROM
|
||||
Gyruss |Ultra |C+|CNROM
|
||||
Harlem Globetrotters |Gametek |B |SLROM
|
||||
Hatris |Bullet Proof |A |SNROM
|
||||
Heavy Barrel |Data East |C |TLROM
|
||||
Heavy Shreddin' |Parker Brothers |B-|SLROM
|
||||
Heroes of the Lance |FCI |C |SKROM
|
||||
High Speed |Tradewest |B-|TQROM
|
||||
Hillsfar |FCI |B |SNROM
|
||||
Hogan's Alley |Nintendo |D |NROM
|
||||
Hollywood Squares |Gametek |B+|UNROM
|
||||
Home Alone |T*HQ |B-|TSROM
|
||||
Home Alone 2 |T*HQ |B-|TLROM
|
||||
Hook |Imagesoft |B |SLROM
|
||||
Hoops |Jaleco |D |SLROM
|
||||
Hot Slots |Panesian |A+|
|
||||
Hudson Hawk |Imagesoft |B |SLROM
|
||||
Hunt for Red October |Hi Tech |C |TLROM
|
||||
Hydlide |FCI |D |NROM
|
||||
I Can Remember |Gametek |B |CNROM
|
||||
Ice Climber |Nintendo |C+|NROM
|
||||
Ice Hockey |Nintendo |D |NROM
|
||||
Ikari Warriors |SNK |C-|UNROM
|
||||
Ikari Warriors 2 |SNK |C-|SGROM
|
||||
Ikari Warriors 3 |SNK |B-|SLROM
|
||||
Image Fight |Irem |B |TSROM
|
||||
Immortal |Electronic Arts |B |TLROM
|
||||
Impossible Mission 2 |American Video |A-|
|
||||
Impossible Mission 2 |SEI |B+|
|
||||
Indiana Jones Last Crusade |UBI Soft |B+|UNROM
|
||||
Indiana Jones Last Crusade |Taito |B+|SGROM
|
||||
Indiana Jones Temple of Doom |Tengen |B-|
|
||||
Indiana Jones Temple of Doom |Mindscape |C |TFROM
|
||||
Indy Heat |Tradewest |B |AMROM
|
||||
Infiltrator |Mindscape |B |TLROM
|
||||
Iron Tank |SNK |C |SLROM
|
||||
Isolated Warrior |NTVIC |B |TLROM
|
||||
Jack Nicklaus Golf |Konami |B-|351258
|
||||
Jackal |Konami |C |UNROM
|
||||
Jackie Chan Kung Fu |Hudson |B |TLROM
|
||||
James Bond Jr |T*HQ |B-|TLROM
|
||||
Jaws |LJN |D |CNROM
|
||||
Jeopardy |Gametek |C |AOROM
|
||||
Jeopardy 25th Anniversary |Gametek |C+|ANROM
|
||||
Jeopardy Jr |Gametek |C |ANROM
|
||||
Jeopardy Super |Gametek |B |SLROM
|
||||
Jetsons |Taito |B+|TLROM
|
||||
Jimmy Connors Tennis |UBI Soft |B+|UNROM
|
||||
Joe & Mac |Data East |B+|TLROM
|
||||
Jordan vs. Bird |Milton Bradley |C |UNROM
|
||||
Joshua |Wisdom Tree |B+|
|
||||
Journey to Silius |Sunsoft |C+|SLROM
|
||||
Joust |HAL |B |CNROM
|
||||
Jungle Book |Virgin |A-|TLROM
|
||||
Jurassic Park |Ocean |B |TSROM
|
||||
Karate Champ |Data East |C |CNROM
|
||||
Karate Kid |LJN |C |CNROM
|
||||
Karnov |Data East |C |DEIROM
|
||||
Kick Master |Taito |C+|TLROM
|
||||
Kickle Cubicle |Irem |B+|TLROM
|
||||
Kid Icarus |Nintendo |C-|SNROM
|
||||
Kid Klown |Kemco |B |TSROM
|
||||
Kid Kool |Vic Tokai |C+|UNROM
|
||||
Kid Niki |Data East |C |SGROM
|
||||
King Neptune's Adventure |Color Dreams |B+|
|
||||
King of Kings |Wisdom Tree |B+|
|
||||
King of Kings (cartoon mule) |Wisdom Tree |B+|
|
||||
King of the Ring |Acclaim |B+|55741
|
||||
Kings Knight |Square |C+|CNROM
|
||||
Kings of the Beach |Ultra |C |CNROM
|
||||
Kings Quest 5 |Konami |B+|TSROM
|
||||
Kirbys Adventure |Nintendo |B-|TKROM
|
||||
Kiwi Kraze |Taito |B+|TLROM
|
||||
Klash Ball |Sofel |B-|UNROM
|
||||
Klax |Tengen |B+|
|
||||
Knight Rider |Acclaim |B-|SCIROM
|
||||
Krazy Kreatures |American Video |B+|
|
||||
Krion Conquest |Vic Tokai |B |TLROM
|
||||
Krusty's Fun House |Acclaim |C+|TLROM
|
||||
Kung Fu |Nintendo |E |NROM
|
||||
Kung Fu Heroes |Culture Brain |C |CNROM
|
||||
L'Empereur |Koei |B |ETROM
|
||||
Laser Invasion |Konami |B-|ELROM
|
||||
Last Action Hero |Imagesoft |B+|TLROM
|
||||
Last Ninja |Jaleco |B-|TLROM
|
||||
Last Starfighter |Mindscape |C+|CNROM
|
||||
Legacy/Wizard |Broderbund |C |TFROM
|
||||
Legend of Kage |Taito |C-|CNROM
|
||||
Legendary Wings |Capcom |B |UNROM
|
||||
Legends/Diamond |Bandai |B+|TLROM
|
||||
Lemmings |Sunsoft |B-|SLROM
|
||||
Lethal Weapon |Ocean |B |SLROM
|
||||
Life Force |Konami |C |351258
|
||||
Linus Spacehead |Camerica |B |
|
||||
Linus Spacehead (Aladdin Cart) |Camerica |A+|
|
||||
Little League Baseball |SNK |B-|SLROM
|
||||
Little Mermaid |Capcom |B |UNROM
|
||||
Little Nemo |Capcom |B+|TLROM
|
||||
Little Ninja Brothers |Culture Brain |C |TLROM
|
||||
Little Sampson |Taito |B |TLROM
|
||||
Lode Runner |Broderbund |B |NROM
|
||||
Lone Ranger |Konami |B-|TLROM
|
||||
Loopz |Mindscape |B+|UNROM
|
||||
Low G Man |Taxan |C |TLROM
|
||||
Lunar Pool |FCI |C+|NROM
|
||||
M C Kids |Virgin |C+|TSROM
|
||||
M.U.L.E. |Mindscape |C+|SNROM
|
||||
Mach Rider |Nintendo |C-|NROM
|
||||
Mad Max |Mindscape |C+|TLROM
|
||||
Mafat Conspiracy |Vic Tokai |C |TLROM
|
||||
Magic Darts |Romstar |B |SLRROM
|
||||
Magic of Scheherazade |Culture Brain |C-|SLROM
|
||||
Magician |Taxan |A-|TKROM
|
||||
Magmax |FCI |C-|NROM
|
||||
Major League Baseball |LJN |E |CNROM
|
||||
Maniac Mansion |Jaleco |C+|SNROM
|
||||
Mappyland |Taxan |C+|TFROM
|
||||
Marble Madness |Milton Bradley |C+|ANROM
|
||||
Mario Brothers |Nintendo |B-|NROM
|
||||
Mario Is Missing |Mindscape |B |TLROM
|
||||
Mario Time Machine |Mindscape |A-|TLROM
|
||||
Marvel's X-Men |LJN |B-|UNROM
|
||||
Master Chu & the Drunkard Hu |Color Dreams |B |
|
||||
Maxi 15 |American Video |A |
|
||||
Mechanized Attack |SNK |C |SCROM
|
||||
Mega Man |Capcom |B-|UNROM
|
||||
Mega Man 2 |Capcom |C |SGROM
|
||||
Mega Man 3 |Capcom |C |TLROM
|
||||
Mega Man 4 |Capcom |B-|TGROM
|
||||
Mega Man 5 |Capcom |B |TLROM
|
||||
Mega Man 6 |Nintendo |B+|TGROM
|
||||
Menace Beach |Color Dreams |A-|
|
||||
Mendel Palace |Hudson |B |TLROM
|
||||
Mermaids of Atlantis |American Video |B+|
|
||||
Metal Fighter |Color Dreams |B |
|
||||
Metal Gear |Ultra |D |UNROM
|
||||
Metal Mech |Jaleco |B-|SLROM
|
||||
Metal Storm |Irem |B+|TLROM
|
||||
Metroid |Nintendo |D |SNROM
|
||||
Michael Andretti World GP |American Sammy |B-|TLROM
|
||||
Mickey Mousecapade |Capcom |C+|CNROM
|
||||
Mickey Numbers |Hi Tech |B+|TLROM
|
||||
Mickey's Safari in Letterland |Hi Tech |B+|55741
|
||||
Micro Machines |Camerica |A-|
|
||||
Micro Machines (Aladdin Cart) |Camerica |A+|
|
||||
Mig 29 |Camerica |C+|
|
||||
Might & Magic |American Sammy |B+|TKROM
|
||||
Mighty Bombjack |Tecmo |B |CNROM
|
||||
Mighty Final Fight |Capcom |B+|TLROM
|
||||
Mike Tyson's Punch Out |Nintendo |D |PNROM
|
||||
Millipede |HAL |B |NROM
|
||||
Milon's Secret Castle |Hudson |C |CNROM
|
||||
Miracle Piano |Mindscape |A-|SJROM
|
||||
Mission Cobra |Bunch Games |A-|
|
||||
Mission Impossible |Ultra |C+|352026
|
||||
Monopoly |Parker Brothers |B-|SLROM
|
||||
Monster in my Pocket |Konami |B+|TLROM
|
||||
Monster Party |Bandai |B |SLROM
|
||||
Monster Truck Rally |INTV |B |CNROM
|
||||
Moon Ranger |Bunch Games |C |
|
||||
Motor City Patrol |Matchbox |C+|SLROM
|
||||
Ms. Pacman |Namco |A |NROM
|
||||
Ms. Pacman |Tengen |B+|
|
||||
Muppet Adventure |Hi Tech |B |SGROM
|
||||
Muscle |Bandai |B-|NROM
|
||||
Mutant Virus |American Software |B+|SLROM
|
||||
Mystery Quest |Taxan |C+|CNROM
|
||||
NARC |Acclaim |C |AMROM
|
||||
NES Open Golf |Nintendo |B-|SNROM
|
||||
NFL Football |LJN |C |UNROM
|
||||
Nigel Mansell |Gametek |B+|SLROM
|
||||
Nightmare on Elm Street |LJN |B |AMROM
|
||||
Nightshade |Ultra |C+|TLROM
|
||||
Ninja Crusaders |American Sammy |B |TGROM
|
||||
Ninja Gaiden |Tecmo |E |SLROM
|
||||
Ninja Gaiden 2 |Tecmo |C-|TLROM
|
||||
Ninja Gaiden 3 |Tecmo |C+|TLROM
|
||||
Ninja Kid |Bandai |C+|CNROM
|
||||
Nombunagas Ambition |Koei |C |SOROM
|
||||
Nombunagas Ambition 2 |Koei |B |ETROM
|
||||
North & South |Kemco |B+|TSROM
|
||||
Operation Secret Storm |Color Dreams |A |
|
||||
Operation Wolf |Taito |D |SLROM
|
||||
ORB-3D |Hi Tech |C |SCROM
|
||||
Othello |Acclaim |C |NROM
|
||||
Overlord |Virgin |B-|SN1
|
||||
P'radikus Conflict |Color Dreams |B |
|
||||
Pac Man |Namco |A |56504
|
||||
Pac Man (licensed) |Tengen |B-|NROM
|
||||
Pac Man (unlicensed) |Tengen |B-|
|
||||
Pac Mania |Tengen |A |
|
||||
Palamedes |Hot B |B+|SEROM
|
||||
Panic Resturant |Taito |B |TLROM
|
||||
Paperboy |Mindscape |C |CNROM
|
||||
Paperboy 2 |Mindscape |B |UOROM
|
||||
Parodius (England) |Palcom | |
|
||||
Pebble Beach Golf |Bandai |C+|CNROM
|
||||
Peek A Boo Poker |Panesian |A+|
|
||||
Perfect Fit |Gametek |B |CNROM
|
||||
Pesterminator |Color Dreams |B |
|
||||
Peter Pan & the Pirates |T*HQ |B-|SFROM
|
||||
Phantom Fighter |FCI |C+|SGROM
|
||||
Pictionary |LJN |B-|SLROM
|
||||
Pinball |Nintendo |D |NROM
|
||||
Pinball Quest |Jaleco |B |SLROM
|
||||
Pinbot |Nintendo |B |TQROM
|
||||
Pipe Dream |Bullet Proof |B |CNROM
|
||||
Pirates |Ultra |B |SKROM
|
||||
Platoon |Sunsoft |D |SLROM
|
||||
Play Action Football |Nintendo |D |TLSROM
|
||||
Pool of Radiance |FCI |B+|TKROM
|
||||
Popeye |Nintendo |B-|NROM
|
||||
POW |SNK |C |SLROM
|
||||
Power Blade |Taito |B-|TLROM
|
||||
Power Blade 2 |Taito |B-|TLROM
|
||||
Power Punch 2 |American Softworks |B |TLROM
|
||||
Predator |Activision |C+|SLROM
|
||||
Prince of Persia |Virgin |C+|UNROM
|
||||
Princess Tomato |Hudson |B+|SGROM
|
||||
Pro Am |Nintendo |D |SEROM
|
||||
Pro Am 2 |Tradewest |B |AOROM
|
||||
Pro Sport Hockey |Jaleco |B+|TLSROM
|
||||
Pro Wrestling |Nintendo |D |UNROM
|
||||
Puggsly's Scavenger Hunt |Ocean |B |SLROM
|
||||
Punch Out |Nintendo |C+|PNROM
|
||||
Punisher |LJN |B |TLROM
|
||||
Puss N Boots |Electro Brain |B-|UNROM
|
||||
Puzzle |American Video |A-|
|
||||
Puzznic |Taito |B+|CNROM
|
||||
Pyramid |American Video |A-|
|
||||
Q*Bert |Ultra |B-|CNROM
|
||||
Qix |Taito |A |SNROM
|
||||
Quantum Fighter |HAL |B |TLROM
|
||||
Quarterback |Tradewest |D |CNROM
|
||||
Quattro Adventure |Camerica |B+|
|
||||
Quattro Adventure (Aladdin Cart) |Camerica |A+|
|
||||
Quattro Arcade |Camerica |A-|
|
||||
Quattro Sports |Camerica |B |
|
||||
Quattro Sports (Aladdin Cart) |Camerica |A+|
|
||||
Race America |Absolute |B+|SLROM
|
||||
Racket Attack |Jaleco |C-|SLROM
|
||||
Rad Gravity |Activision |B-|SLROM
|
||||
Rad Racer |Nintendo |D |SGROM
|
||||
Rad Racer 2 |Square |B-|TVROM
|
||||
Rad Racket |American Video |A-|
|
||||
Raid 2020 |Color Dreams |B |
|
||||
Raid on Bungling Bay |Broderbund |B |NROM
|
||||
Rainbow Island |Taito |B+|UNROM
|
||||
Rally Bike |Romstar |B |UNROM
|
||||
Rambo |Acclaim |E |UNROM
|
||||
Rampage |Data East |C+|TFROM
|
||||
Rampart |Jaleco |B |TLROM
|
||||
RBI Baseball (licensed) |Tengen |C+|DEROM
|
||||
RBI Baseball (unlicensed) |Tengen |C |
|
||||
RBI Baseball 2 |Tengen |C+|
|
||||
RBI Baseball 3 |Tengen |B-|
|
||||
Remote Control |Hi Tech |C |SLROM
|
||||
Ren + Stimpy Buckaroos |T*HQ |B-|TLROM
|
||||
Renegade |Taito |C-|UNROM
|
||||
Rescue |Kemco |C-|SLROM
|
||||
Rescue Rangers |Capcom |C+|SLROM
|
||||
Rescue Rangers 2 |Capcom |B+|SLROM
|
||||
Ring King |Data East |C |DEROM
|
||||
River City Ransom |American Technos |C |TLROM
|
||||
Road Blasters |Mindscape |C+|SLROM
|
||||
Road Runner |Tengen |B+|
|
||||
Robin Hood |Virgin |C+|SGROM
|
||||
Robo Cop |Data East |C |TL1ROM
|
||||
Robo Cop 2 |Data East |B-|SLROM
|
||||
Robo Cop 3 |Ocean |B |SLROM
|
||||
Robo Demons |Color Dreams |B |
|
||||
Robo Warrior |Jaleco |B |UNROM
|
||||
Rock N Ball |NTVIC |B |TFROM
|
||||
Rocket Ranger |Kemco |B-|SGROM
|
||||
Rocketeer |Bandai |B-|SGROM
|
||||
Rockin Kats |Atlus |B+|TLROM
|
||||
Rocky & Bullwinkle |T*HQ |B-|TLROM
|
||||
Roger Clemens |LJN |C |53361
|
||||
Roller Games |Ultra |B-|TLROM
|
||||
Rollerball |HAL |B |SFROM
|
||||
Rollerblade Racer |Hi Tech |B |53361
|
||||
Rolling Thunder |Tengen |C+|
|
||||
Romance/3 Kingdoms |Koei |C |SOROM
|
||||
Romance/3 Kingdoms 2 |Koei |B |EWROM
|
||||
Roundball |Mindscape |B-|TSROM
|
||||
Rush N Attack |Konami |D |UNROM
|
||||
Rygar |Tecmo |C |UNROM
|
||||
SCAT |Natsume |B |SLROM
|
||||
Secret Scout |Color Dreams |A |
|
||||
Section Z |Capcom |C |UNROM
|
||||
Seicross |FCI |D |NROM
|
||||
Sesame Street 1-2-3 |Hi Tech |C+|SEROM (SCROROM)
|
||||
Sesame Street 123/ABC |Hi Tech |B |SLROM
|
||||
Sesame Street A-B-C |Hi Tech |C+|SEROM
|
||||
Sesame Street Countdown |Hi Tech |A-|SLROM
|
||||
Shadow of the Ninja |Natsume |B |TLROM
|
||||
Shadowgate |Kemco |C+|TKROM
|
||||
Shatterhand |Jaleco |B-|TLROM
|
||||
Shingen the Ruler |Hot B |C |SNROM
|
||||
Shinobi |Tengen |C+|
|
||||
Shockwave |American Game Carts Inc|B |
|
||||
Shooting Range |Bandai |B |CNROM
|
||||
Short Order/Eggsplode |Nintendo |B+|SBROM
|
||||
Side Pocket |Data East |B |UNROM
|
||||
Silent Assault |Color Dreams |B |
|
||||
Silent Service |Ultra |C-|351258
|
||||
Silk Worm |American Sammy |C |SLROM
|
||||
Silver Surfer |Arcadia |B |TSROM
|
||||
Simpsons Bart Meets Radioactive Man |Acclaim |B+|55741
|
||||
Simpsons Bart Vs Space Mutants |Acclaim |D |SLROM
|
||||
Simpsons Bart Vs World |Acclaim |B-|53361
|
||||
Skate or Die |Ultra |D |351258
|
||||
Skate or Die 2 |Electronic Arts |B |SLROM
|
||||
Ski or Die |Ultra |B-|351908
|
||||
Skull & Crossbones |Tengen |B |
|
||||
Sky Kid |Sunsoft |B-|SCEOROM
|
||||
Sky Shark |Taito |D |SL1ROM
|
||||
Slalom |Nintendo |B-|NROM
|
||||
Smash TV |Acclaim |C+|51555
|
||||
Snake Rattle & Roll |Nintendo |C+|SEROM
|
||||
Snakes Revenge |Ultra |C |SLROM
|
||||
Snoopy Silly Sports |Kemco |B+|SLROM
|
||||
Snow Brothers |Capcom |B |SLROM
|
||||
Soccer |Nintendo |D |NROM
|
||||
Solar Jetman |Tradewest |C |AOROM
|
||||
Solitaire |American Video |A-|
|
||||
Soloman's Key |Tecmo |C+|CNROM
|
||||
Solstice |Imagesoft |C |ANROM
|
||||
Space Shuttle |Absolute |B+|SGROM
|
||||
Spelunker |Broderbund |C+|NROM
|
||||
Spiderman |LJN |B-|53361
|
||||
Spiritual Warfare |Wisdom Tree |B+|
|
||||
Spot |Arcadia |B-|SNROM
|
||||
Spy Hunter |Sunsoft |C |CNROM
|
||||
Spy vs. Spy |Kemco |B-|NROM
|
||||
Sqoon |Irem |B+|NROM
|
||||
Stack Up |Nintendo |A-|HVC
|
||||
Stadium Events |Bandai |B |
|
||||
Stanley |Electro Brain |B |TLROM
|
||||
Star Force |Tecmo |C+|CNROM
|
||||
Star Soldier |Taxan |C-|CNROM
|
||||
Star Trek 25th Anniversary |Ultra |B |TLROM
|
||||
Star Trek: The Next Generation |Absolute |A-|UNROM
|
||||
Star Tropics |Nintendo |C-|HKROM
|
||||
Star Voyager |Acclaim |C+|CNROM
|
||||
Star Wars |JVC |B |TSROM
|
||||
Starship Hector |Hudson |B-|UNROM
|
||||
Stealth ATF |Activision |C+|SLROM
|
||||
Stinger |Konami |B-|UNROM
|
||||
Street Cop |Bandai |A-|SLROM
|
||||
Street Fighter 2010 |Capcom |B |TLROM
|
||||
Strider |Capcom |C |SGROM
|
||||
Stunt Kids |Camerica |A-|
|
||||
Sunday Funday |Wisdom Tree |B+|
|
||||
Super C |Konami |C |352026
|
||||
Super Cars |Electro Brain |B+|UNROM
|
||||
Super Dodge Ball |Imagesoft |C |SLROM
|
||||
Super Glove Ball |Mattel |C |UNROM
|
||||
Super Mario Brothers |Nintendo |F |NROM
|
||||
Super Mario Brothers 2 |Nintendo |D |TSROM
|
||||
Super Mario Brothers 3 |Nintendo |D |TSROM
|
||||
Super Mario/Duck Hunt |Nintendo |F |MH
|
||||
Super Mario/Duck Hunt/Track Meet |Nintendo |C |COB
|
||||
Super Off Road |Tradewest |C-|AMROM
|
||||
Super Pitfall |Activision |C+|UNROM
|
||||
Super Spike V'Ball |Nintendo |C-|TLROM
|
||||
Super Spike/World Cup |Nintendo |B-|COB
|
||||
Super Sprint |Tengen |C |COB
|
||||
Super Spy Hunter |Sunsoft |B+|TLROM
|
||||
Super Team Games |Nintendo |C-|CNROM
|
||||
Superman |Kemco |B+|SLROM
|
||||
Swamp Thing |T*HQ |C+|SLROM
|
||||
Sword Master |Activision |A-|TLROM
|
||||
Swords & Serpents |Acclaim |B+|UNROM
|
||||
T&C Surf Design |LJN |E |CNROM
|
||||
Taboo |Tradewest |C+|SEROM
|
||||
Tag Team Wrestling |Data East |C |NROM
|
||||
Taggin Dragon |Bunch Games |B |
|
||||
Talespin |Capcom |B |SLROM
|
||||
Target Renegade |Taito |C+|SLROM
|
||||
Tecmo Baseball |Tecmo |C |SGROM
|
||||
Tecmo Basketball |Tecmo |C+|TKROM
|
||||
Tecmo Bowl |Tecmo |E |SLROM
|
||||
Tecmo Cup Soccer |Tecmo |B+|SLROM
|
||||
Tecmo Super Bowl |Tecmo |C-|TKROM
|
||||
Tecmo Wrestling |Tecmo |C |SLROM
|
||||
Teenage Turtles |Ultra |E |351908
|
||||
Teenage Turtles 2 |Ultra |D |TLROM
|
||||
Teenage Turtles 3 |Konami |B-|TLROM
|
||||
Teenage Turtles Tournament Fighters |Konami |B+|TLROM
|
||||
Tennis |Nintendo |D |NROM
|
||||
Terminator |Mindscape |B+|TLROM
|
||||
Terminator 2 Judgement Day |LJN |B-|53361
|
||||
Terra Cresta |Vic Tokai |B+|UNROM
|
||||
Tetris |Tengen |A-|
|
||||
Tetris |Nintendo |D |SEROM
|
||||
Tetris 2 |Nintendo |B-|TSROM
|
||||
Three Stooges |Activision |C+|SLROM
|
||||
Thrilla Safari |LJN |B |53361
|
||||
Thunder & Lightning |Romstar |B+|GNROM
|
||||
Thunderbirds |Activision |C+|SLROM
|
||||
Thundercade |American Sammy |C+|UNROM
|
||||
Tiger Heli |Acclaim |C+|CNROM
|
||||
Tiles of Fate |American Video |B+|
|
||||
Time Lord |Milton Bradley |C |AMROM
|
||||
Times of Lore |Toho |B-|UNROM
|
||||
Tiny Toon |Konami |C+|TLROM
|
||||
Tiny Toon Cartoon Workshop |Konami |B+|TSROM
|
||||
Tiny Toons 2 |Konami |B+|TLROM
|
||||
To The Earth |Nintendo |C+|TEROM
|
||||
Toki |Taito |B+|TLROM
|
||||
Tom & Jerry |Hi Tech |B+|TLROM
|
||||
Tombs & Treasures |Infocom |A-|SGROM
|
||||
Toobin |Tengen |B |
|
||||
Top Gun |Konami |D |351298
|
||||
Top Gun 2 |Konami |D |352026
|
||||
Top Players Tennis |Asmik |C+|SLROM
|
||||
Total Recall |Acclaim |D |UNROM
|
||||
Totally Rad |Jaleco |B-|TLROM
|
||||
Touchdown Fever |SNK |B+|SFROM
|
||||
Toxic Crusader |Bandai |B |TLROM
|
||||
Track & Field |Konami |D |CNROM
|
||||
Track & Field 2 |Konami |D |SLROM
|
||||
Treasure Master |American Softworks |A-|SLROM
|
||||
Trick Shooting |Nintendo |C+|SCROM
|
||||
Trog |Acclaim |B+|UNROM
|
||||
Trojan |Capcom |C |UNROM
|
||||
Trolls on Treasure Island |American Video |A-|
|
||||
Twin Cobra |American Sammy |C+|TLROM
|
||||
Twin Eagle |Romstar |C+|UNROM
|
||||
Ultima/Exodus |FCI |C-|SNROM
|
||||
Ultima/Quest Avatar |FCI |B |SNROM
|
||||
Ultima/War Destiny |FCI |B+|SNROM
|
||||
Ultimate Air Combat |Activision |B+|TLROM
|
||||
Ultimate Basketball |American Sammy |C |TLROM
|
||||
Ultimate League Soccer |American Video |A-|
|
||||
Ultimate Stuntman |Camerica |C+|
|
||||
Uncharted Waters |Koei |B-|ETROM
|
||||
Uninvited |Kemco |B+|TKROM
|
||||
Untouchables |Ocean |B-|SLROM
|
||||
Urban Champion |Nintendo |D |NROM
|
||||
Vegas Dream |HAL |B |SKROM
|
||||
Venice Beach Volleyball |American Video |A-|
|
||||
Vice Project Doom |American Sammy |C+|TLROM
|
||||
Videomation |T*HQ |B+|CPROM
|
||||
Vindicators |Tengen |C |
|
||||
Volleyball |Nintendo |C |NROM
|
||||
Wacky Races |Atlus |B+|TLROM
|
||||
Wall Street Kid |Sofel |B |UNROM
|
||||
Wally Bear and the No Gang |American Video |A-|
|
||||
Wario Woods |Nintendo |B+|TKROM
|
||||
Wayne Gretzky |T*HQ |C+|UNROM
|
||||
Wayne's World |T*HQ |B |TLROM
|
||||
Werewolf |Data East |C |TLROM
|
||||
Wheel/Fortune |Gametek |C |AOROM
|
||||
Wheel/Fortune/Family |Gametek |C |ANROM
|
||||
Wheel/Fortune/Junior |Gametek |C |ANROM
|
||||
Wheel/Fortune/Vanna |Gametek |B |AOROM
|
||||
Where in Time is Carmen |Konami |B |TSROM
|
||||
Where's Waldo |T*HQ |C+|TSROM
|
||||
Who Framed Roger Rabbit |LJN |B-|ANROM
|
||||
Whomp Em |Jaleco |B |TLROM
|
||||
Widget |Atlus |B |TLROM
|
||||
Wild Gunman |Nintendo |C |NROM
|
||||
Willow |Capcom |B-|SLROM
|
||||
Win Lose or Draw |Hi Tech |C |SGROM
|
||||
Winter Games |Acclaim |B-|UNROM
|
||||
Wizardry |Nexoft |C+|SKROM
|
||||
Wizardry 2 Knight of Diamonds |Ascii |B+|TKROM
|
||||
Wizards & Warriors |Acclaim |D |ANROM
|
||||
Wizards & Warriors 2 - Ironsword |Acclaim |D |AOROM
|
||||
Wizards & Warriors 3 |Acclaim |C-|54425
|
||||
Wolverine |LJN |B-|TLROM
|
||||
World Champ |Romstar |B+|TLROM
|
||||
World Championship Wrestling |FCI |D |TLROM
|
||||
World Class Track Meet |Nintendo |D |CNROM
|
||||
World Cup Soccer |Nintendo |C-|TLROM
|
||||
World Games |Milton Bradley |B-|ANROM
|
||||
World Runner 3D |Acclaim |C-|UNROM
|
||||
Wrath of the Black Manta |Taito |C+|SLROM
|
||||
Wrecking Crew |Nintendo |C+|NROM
|
||||
Wrestlemania |Acclaim |D |ANROM
|
||||
Wrestlemania Challenge |LJN |C-|UNROM
|
||||
Wrestlemania Steel Cage |LJN |C+|53361
|
||||
Wurm |Asmik |B-|TLROM
|
||||
Xenophobe |Sunsoft |B-|SFROM
|
||||
Xevious |Bandai |C+|NROM
|
||||
Xexyz |Hudson |C+|SLROM
|
||||
Yo Noid |Capcom |C+|SLROM
|
||||
Yoshi |Nintendo |C-|SFROM
|
||||
Yoshi's Cookie |Nintendo |B-|TFROM
|
||||
Young Indy |Jaleco |B+|TLROM
|
||||
Zanac |FCI |C+|UNROM
|
||||
Zelda |Nintendo |E |SNROM
|
||||
Zelda 2 |Nintendo |D |SKROM
|
||||
Zen |Konami |B |TLROM
|
||||
Zoda's Revenge, Startropics 2 |Nintendo |B-|HKROM
|
||||
Zombie Nation |Meldac |B |TLROM
|
||||
38
tools/ucon64/src/console/console.h
Normal file
38
tools/ucon64/src/console/console.h
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
console.h - single header for all console functions
|
||||
|
||||
Copyright (c) 2003 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef CONSOLE_H
|
||||
#define CONSOLE_H
|
||||
#include "dc.h"
|
||||
#include "gb.h"
|
||||
#include "gba.h"
|
||||
#include "genesis.h"
|
||||
#include "jaguar.h"
|
||||
#include "lynx.h"
|
||||
#include "n64.h"
|
||||
#include "neogeo.h"
|
||||
#include "nes.h"
|
||||
#include "ngp.h"
|
||||
#include "pce.h"
|
||||
#include "psx.h"
|
||||
#include "sms.h"
|
||||
#include "snes.h"
|
||||
#include "swan.h"
|
||||
#endif // CONSOLE_H
|
||||
646
tools/ucon64/src/console/dc.c
Normal file
646
tools/ucon64/src/console/dc.c
Normal file
@@ -0,0 +1,646 @@
|
||||
/*
|
||||
dc.c - Dreamcast support for uCON64
|
||||
|
||||
Copyright (c) 2004 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "misc/file.h"
|
||||
#include "misc/misc.h"
|
||||
#include "misc/property.h"
|
||||
#include "misc/string.h"
|
||||
#ifdef USE_ZLIB
|
||||
#include "misc/archive.h"
|
||||
#endif
|
||||
#include "misc/getopt2.h" // st_getopt2_t
|
||||
#include "ucon64.h"
|
||||
#include "ucon64_misc.h"
|
||||
#include "dc.h"
|
||||
|
||||
|
||||
const st_getopt2_t dc_usage[] =
|
||||
{
|
||||
{
|
||||
NULL, 0, 0, 0,
|
||||
NULL, "Dreamcast" /* "1998 SEGA http://www.sega.com" */,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"dc", 0, 0, UCON64_DC,
|
||||
NULL, "force recognition",
|
||||
&ucon64_wf[WF_OBJ_DC_SWITCH]
|
||||
},
|
||||
#if 0
|
||||
{
|
||||
"vms", 1, 0, UCON64_VMS,
|
||||
"SAV", "convert NES SAV file to a VMS file for use with NesterDC",
|
||||
NULL
|
||||
},
|
||||
#endif
|
||||
{
|
||||
"scr", 0, 0, UCON64_SCR,
|
||||
NULL, "scramble 1ST_READ.BIN for selfboot CDs",
|
||||
&ucon64_wf[WF_OBJ_DC_DEFAULT]
|
||||
},
|
||||
{
|
||||
"unscr", 0, 0, UCON64_UNSCR,
|
||||
NULL, "unscramble 1ST_READ.BIN for non-selfboot CDs",
|
||||
&ucon64_wf[WF_OBJ_DC_DEFAULT]
|
||||
},
|
||||
#if 0
|
||||
{
|
||||
"ip", 1, 0, UCON64_IP,
|
||||
"FILE", "extract ip.bin FILE from IMAGE; " OPTION_LONG_S "rom=IMAGE",
|
||||
NULL
|
||||
},
|
||||
#endif
|
||||
{
|
||||
"mkip", 0, 0, UCON64_MKIP,
|
||||
NULL, "generate IP.BIN file with default values",
|
||||
&ucon64_wf[WF_OBJ_DC_NO_ROM]
|
||||
},
|
||||
{
|
||||
"parse", 1, 0, UCON64_PARSE,
|
||||
"TEMPLATE", "parse TEMPLATE file into a IP.BIN;\n"
|
||||
"creates an empty template when TEMPLATE does not exist",
|
||||
&ucon64_wf[WF_OBJ_DC_NO_ROM]
|
||||
},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
calc_crc (const unsigned char *buf, int size)
|
||||
{
|
||||
int i, c, n = 0xffff;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
{
|
||||
n ^= (buf[i] << 8);
|
||||
for (c = 0; c < 8; c++)
|
||||
if (n & 0x8000)
|
||||
n = (n << 1) ^ 4129;
|
||||
else
|
||||
n = (n << 1);
|
||||
}
|
||||
return n & 0xffff;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
update_crc (char *ip)
|
||||
{
|
||||
int n = calc_crc ((unsigned char *) (ip + 0x40), 16);
|
||||
char buf[5];
|
||||
|
||||
sprintf (buf, "%04X", n);
|
||||
if (memcmp (buf, ip + 0x20, 4))
|
||||
{
|
||||
printf ("Setting CRC to %s (was %.4s)\n", buf, ip + 0x20);
|
||||
memcpy (ip + 0x20, buf, 4);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static unsigned int seed;
|
||||
|
||||
static void
|
||||
dc_srand (unsigned int n)
|
||||
{
|
||||
seed = n & 0xffff;
|
||||
}
|
||||
|
||||
|
||||
static unsigned int
|
||||
dc_rand ()
|
||||
{
|
||||
seed = (seed * 2109 + 9273) & 0x7fff;
|
||||
return (seed + 0xc000) & 0xffff;
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
// header for SAV -> VMS conversion
|
||||
static const uint8_t nstrsave_bin[1024] = {
|
||||
0x4e, 0x45, 0x53, 0x52, 0x4f, 0x4d, 0x2e, 0x4e, // 0x8 (8)
|
||||
0x45, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 (16)
|
||||
0x4e, 0x65, 0x73, 0x74, 0x65, 0x72, 0x44, 0x43, // 0x18 (24)
|
||||
0x20, 0x53, 0x61, 0x76, 0x65, 0x52, 0x61, 0x6d, // 0x20 (32)
|
||||
0x20, 0x46, 0x69, 0x6c, 0x65, 0x00, 0x00, 0x00, // 0x28 (40)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 (48)
|
||||
0x2a, 0x2a, 0x2a, 0x4e, 0x65, 0x73, 0x74, 0x65, // 0x38 (56)
|
||||
0x72, 0x44, 0x43, 0x2a, 0x2a, 0x2a, 0x00, 0x00, // 0x40 (64)
|
||||
0x01, 0x00, 0x00, 0x00, 0x01, 0x3f, 0x00, 0x00, // 0x48 (72)
|
||||
0x80, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 (80)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 (88)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 (96)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 (104)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 (112)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 (120)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 (128)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 (136)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 (144)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 (152)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xa0 (160)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xa8 (168)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xb0 (176)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xb8 (184)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc0 (192)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xc8 (200)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xd0 (208)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xd8 (216)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xe0 (224)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xe8 (232)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xf0 (240)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xf8 (248)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x100 (256)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x108 (264)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x110 (272)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x118 (280)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x120 (288)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x128 (296)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x130 (304)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x138 (312)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x140 (320)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x148 (328)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x150 (336)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x158 (344)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x160 (352)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x168 (360)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x170 (368)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x178 (376)
|
||||
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, // 0x180 (384)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x188 (392)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x190 (400)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x198 (408)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1a0 (416)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1a8 (424)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1b0 (432)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1b8 (440)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1c0 (448)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1c8 (456)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1d0 (464)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1d8 (472)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1e0 (480)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1e8 (488)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1f0 (496)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x1f8 (504)
|
||||
0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, 0x21, // 0x200 (512)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x208 (520)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x210 (528)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x218 (536)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x220 (544)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x228 (552)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x230 (560)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x238 (568)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x240 (576)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x248 (584)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x250 (592)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x258 (600)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x260 (608)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x268 (616)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x270 (624)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x278 (632)
|
||||
0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, 0x33, // 0x280 (640)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x288 (648)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x290 (656)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x298 (664)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2a0 (672)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2a8 (680)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2b0 (688)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2b8 (696)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2c0 (704)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2c8 (712)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2d0 (720)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2d8 (728)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2e0 (736)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2e8 (744)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2f0 (752)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x2f8 (760)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x300 (768)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x308 (776)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x310 (784)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x318 (792)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x320 (800)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x328 (808)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x330 (816)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x338 (824)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x340 (832)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x348 (840)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x350 (848)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x358 (856)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x360 (864)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x368 (872)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x370 (880)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x378 (888)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x380 (896)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x388 (904)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x390 (912)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x398 (920)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3a0 (928)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3a8 (936)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3b0 (944)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3b8 (952)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3c0 (960)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3c8 (968)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3d0 (976)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3d8 (984)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3e0 (992)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3e8 (1000)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3f0 (1008)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x3f8 (1016)
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // 0x400 (1024)
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
int
|
||||
dc_init (st_rominfo_t *rominfo)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
rominfo->console_usage = dc_usage[0].help;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
check_areasym (char *ptr, int len)
|
||||
{
|
||||
int i, a = 0;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
switch (ptr[i])
|
||||
{
|
||||
case 'J':
|
||||
a |= (1<<0);
|
||||
break;
|
||||
case 'U':
|
||||
a |= (1<<1);
|
||||
break;
|
||||
case 'E':
|
||||
a |= (1<<2);
|
||||
break;
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
fprintf (stderr, "ERROR: Unknown area symbol '%c'\n", ptr[i]);
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < len; i++)
|
||||
if ((a & (1<<i)) == 0)
|
||||
ptr[i] = ' ';
|
||||
else
|
||||
ptr[i] = "JUE"[i];
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
int pos;
|
||||
int len;
|
||||
int (*extra_check) (char *, int);
|
||||
char *def;
|
||||
char *comment;
|
||||
} st_templ_t;
|
||||
|
||||
|
||||
st_templ_t templ[] =
|
||||
{
|
||||
{"hardware_id", 0x0, 0x10, NULL, "SEGA SEGAKATANA", "Hardware ID (always \"SEGA SEGAKATANA\")"},
|
||||
{"maker_id", 0x10, 0x10, NULL, "SEGA ENTERPRISES", "Maker ID (always \"SEGA ENTERPRISES\")"},
|
||||
{"device_info", 0x20, 0x10, NULL, "0000 CD-ROM1/1", "Device Information"},
|
||||
{"area_symbols", 0x30, 0x8, check_areasym, "JUE", "Area Symbols"},
|
||||
{"peripherals", 0x38, 0x8, NULL, "E000F10", "Peripherals"},
|
||||
{"product_no", 0x40, 0xa, NULL, "T0000", "Product number (\"HDR-nnnn\" etc.)"},
|
||||
{"version", 0x4a, 0x6, NULL, "V1.000", "Product version"},
|
||||
{"release_date", 0x50, 0x10, NULL, "20000627", "Release date (YYYYMMDD)"},
|
||||
{"boot_filename", 0x60, 0x10, NULL, "1ST_READ.BIN", "Boot filename (usually \"1ST_READ.BIN\")"},
|
||||
{"sw_maker_name", 0x70, 0x10, NULL, "YOUR NAME HERE", "Name of the company that produced the disc"},
|
||||
{"game_title", 0x80, 0x80, NULL, "TITLE OF THE SOFTWARE", "Name of the software"},
|
||||
{NULL, 0, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
static int
|
||||
parse_templ (const char *templ_file, char *ip)
|
||||
{
|
||||
int filled_in[MAXBUFSIZE];
|
||||
static char buf[MAXBUFSIZE];
|
||||
int i;
|
||||
|
||||
memset (filled_in, 0, sizeof (filled_in));
|
||||
for (i = 0; templ[i].name; i++)
|
||||
{
|
||||
char *p = buf;
|
||||
get_property (templ_file, templ[i].name, p, templ[i].def);
|
||||
|
||||
strtriml (strtrimr (p));
|
||||
|
||||
if (!(*p))
|
||||
continue;
|
||||
|
||||
memset (ip + templ[i].pos, ' ', templ[i].len);
|
||||
|
||||
if ((int) strlen (p) > templ[i].len)
|
||||
{
|
||||
fprintf (stderr, "ERROR: Data for field \"%s\" is too long... stripping to %d chars\n",
|
||||
templ[i].name, templ[i].len);
|
||||
p[templ[i].len] = 0;
|
||||
}
|
||||
|
||||
memcpy (ip + templ[i].pos, p, strlen (p));
|
||||
|
||||
if (templ[i].extra_check)
|
||||
if (templ[i].extra_check (ip + templ[i].pos, templ[i].len) == -1)
|
||||
return -1;
|
||||
|
||||
filled_in[i] = 1;
|
||||
}
|
||||
|
||||
for (i = 0; templ[i].name; i++)
|
||||
if (!filled_in[i])
|
||||
{
|
||||
fprintf (stderr, "ERROR: Missing value for \"%s\"\n", templ[i].name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dc_parse (const char *templ_file)
|
||||
{
|
||||
char ip[0x8000], dest_name[FILENAME_MAX];
|
||||
|
||||
if (access (templ_file, F_OK) == -1)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
printf ("Creating empty template file: \"%s\"\n", templ_file);
|
||||
|
||||
for (i = 0; templ[i].name; i++)
|
||||
set_property (templ_file, templ[i].name, templ[i].def, templ[i].comment);
|
||||
|
||||
printf (ucon64_msg[WROTE], templ_file);
|
||||
}
|
||||
|
||||
if (parse_templ (templ_file, ip) == -1)
|
||||
return -1;
|
||||
|
||||
update_crc (ip);
|
||||
|
||||
strcpy (dest_name, "ip.bin");
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
|
||||
ucon64_fwrite (ip, 0, 0x8000, dest_name, "wb");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dc_mkip (void)
|
||||
{
|
||||
dc_parse ("default");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
load_chunk (FILE * fh, unsigned char *ptr, int32_t sz)
|
||||
{
|
||||
#define MAXCHUNK (2048*1024)
|
||||
static int idx[MAXCHUNK / 32];
|
||||
int32_t i;
|
||||
|
||||
/* Convert chunk size to number of slices */
|
||||
sz /= 32;
|
||||
|
||||
/* Initialize index table with unity,
|
||||
so that each slice gets loaded exactly once */
|
||||
for (i = 0; i < sz; i++)
|
||||
idx[i] = i;
|
||||
|
||||
for (i = sz - 1; i >= 0; --i)
|
||||
{
|
||||
/* Select a replacement index */
|
||||
int x = (dc_rand () * i) >> 16;
|
||||
|
||||
/* Swap */
|
||||
int tmp = idx[i];
|
||||
idx[i] = idx[x];
|
||||
idx[x] = tmp;
|
||||
|
||||
/* Load resulting slice */
|
||||
if (fread (ptr + 32 * idx[i], 1, 32, fh) != 32)
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
load_file (FILE * fh, unsigned char *ptr, uint32_t filesz)
|
||||
{
|
||||
uint32_t chunksz;
|
||||
|
||||
dc_srand (filesz);
|
||||
|
||||
/* Descramble 2 meg blocks for as long as possible, then
|
||||
gradually reduce the window down to 32 bytes (1 slice) */
|
||||
for (chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
|
||||
while (filesz >= chunksz)
|
||||
{
|
||||
load_chunk (fh, ptr, chunksz);
|
||||
filesz -= chunksz;
|
||||
ptr += chunksz;
|
||||
}
|
||||
|
||||
/* Load final incomplete slice */
|
||||
if (filesz)
|
||||
if (fread (ptr, 1, filesz, fh) != filesz)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
save_chunk (FILE * fh, unsigned char *ptr, int32_t sz)
|
||||
{
|
||||
static int idx[MAXCHUNK / 32];
|
||||
int32_t i;
|
||||
|
||||
/* Convert chunk size to number of slices */
|
||||
sz /= 32;
|
||||
|
||||
/* Initialize index table with unity,
|
||||
so that each slice gets saved exactly once */
|
||||
for (i = 0; i < sz; i++)
|
||||
idx[i] = i;
|
||||
|
||||
for (i = sz - 1; i >= 0; --i)
|
||||
{
|
||||
/* Select a replacement index */
|
||||
int x = (dc_rand () * i) >> 16;
|
||||
|
||||
/* Swap */
|
||||
int tmp = idx[i];
|
||||
idx[i] = idx[x];
|
||||
idx[x] = tmp;
|
||||
|
||||
/* Save resulting slice */
|
||||
if (fwrite (ptr + 32 * idx[i], 1, 32, fh) != 32)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
save_file (FILE * fh, unsigned char *ptr, uint32_t filesz)
|
||||
{
|
||||
uint32_t chunksz;
|
||||
|
||||
dc_srand (filesz);
|
||||
|
||||
/* Descramble 2 meg blocks for as long as possible, then
|
||||
gradually reduce the window down to 32 bytes (1 slice) */
|
||||
for (chunksz = MAXCHUNK; chunksz >= 32; chunksz >>= 1)
|
||||
while (filesz >= chunksz)
|
||||
{
|
||||
save_chunk (fh, ptr, chunksz);
|
||||
filesz -= chunksz;
|
||||
ptr += chunksz;
|
||||
}
|
||||
|
||||
/* Save final incomplete slice */
|
||||
if (filesz)
|
||||
if (fwrite (ptr, 1, filesz, fh) != filesz)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
descramble (const char *src, char *dst)
|
||||
{
|
||||
unsigned char *ptr = NULL;
|
||||
uint32_t sz = 0;
|
||||
FILE *fh;
|
||||
|
||||
if (!(fh = fopen (src, "rb")))
|
||||
return -1;
|
||||
|
||||
sz = fsizeof (src);
|
||||
if (!(ptr = (unsigned char *) malloc (sz)))
|
||||
return -1;
|
||||
|
||||
load_file (fh, ptr, sz);
|
||||
fclose (fh);
|
||||
|
||||
if (!(fh = fopen (dst, "wb")))
|
||||
return -1;
|
||||
|
||||
if (fwrite (ptr, 1, sz, fh) != sz)
|
||||
return -1;
|
||||
|
||||
fclose (fh);
|
||||
free (ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
scramble (const char *src, char *dst)
|
||||
{
|
||||
unsigned char *ptr = NULL;
|
||||
uint32_t sz = 0;
|
||||
FILE *fh;
|
||||
|
||||
if (!(fh = fopen (src, "rb")))
|
||||
return -1;
|
||||
|
||||
sz = fsizeof (src);
|
||||
|
||||
if (!(ptr = (unsigned char *) malloc (sz)))
|
||||
return -1;
|
||||
|
||||
if (fread (ptr, 1, sz, fh) != sz)
|
||||
return -1;
|
||||
|
||||
fclose (fh);
|
||||
|
||||
if (!(fh == fopen (dst, "wb")))
|
||||
return -1;
|
||||
save_file (fh, ptr, sz);
|
||||
|
||||
fclose (fh);
|
||||
|
||||
free (ptr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dc_scramble (void)
|
||||
{
|
||||
char dest_name[FILENAME_MAX];
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
|
||||
if (!scramble (ucon64.rom, dest_name))
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
else
|
||||
fprintf (stderr, ucon64_msg[WRITE_ERROR], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
dc_unscramble (void)
|
||||
{
|
||||
char dest_name[FILENAME_MAX];
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
|
||||
if (!descramble (ucon64.rom, dest_name))
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
else
|
||||
fprintf (stderr, ucon64_msg[WRITE_ERROR], dest_name);
|
||||
return 0;
|
||||
}
|
||||
29
tools/ucon64/src/console/dc.h
Normal file
29
tools/ucon64/src/console/dc.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
dc.h - Dreamcast support for uCON64
|
||||
|
||||
Copyright (c) 2004 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef DC_H
|
||||
#define DC_H
|
||||
extern int dc_init (st_rominfo_t *rominfo);
|
||||
extern const st_getopt2_t dc_usage[];
|
||||
extern int dc_parse (const char *template_file);
|
||||
extern int dc_mkip (void);
|
||||
extern int dc_scramble (void);
|
||||
extern int dc_unscramble (void);
|
||||
#endif
|
||||
703
tools/ucon64/src/console/gb.c
Normal file
703
tools/ucon64/src/console/gb.c
Normal file
@@ -0,0 +1,703 @@
|
||||
/*
|
||||
gb.c - Game Boy support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
Copyright (c) 2001 - 2004 dbjh
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "misc/file.h"
|
||||
#include "misc/misc.h"
|
||||
#include "misc/string.h"
|
||||
#ifdef USE_ZLIB
|
||||
#include "misc/archive.h"
|
||||
#endif
|
||||
#include "misc/getopt2.h" // st_getopt2_t
|
||||
#include "ucon64.h"
|
||||
#include "ucon64_misc.h"
|
||||
#include "console/nes.h"
|
||||
#include "backup/gbx.h"
|
||||
#include "backup/mgd.h"
|
||||
#include "backup/ssc.h"
|
||||
#include "patch/ips.h"
|
||||
#include "patch/bsl.h"
|
||||
#include "gb.h"
|
||||
|
||||
|
||||
#define GAMEBOY_HEADER_START 0x100
|
||||
#define GAMEBOY_HEADER_LEN (sizeof (st_gameboy_header_t))
|
||||
#define GB_NAME_LEN 15
|
||||
|
||||
const st_getopt2_t gameboy_usage[] =
|
||||
{
|
||||
{
|
||||
NULL, 0, 0, 0,
|
||||
NULL, "Game Boy/(Super GB)/GB Pocket/Color GB/(GB Advance)"
|
||||
/*"1989/1994/1996/1998/2001 Nintendo http://www.nintendo.com"*/,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"gb", 0, 0, UCON64_GB,
|
||||
NULL, "force recognition",
|
||||
&ucon64_wf[WF_OBJ_GB_SWITCH]
|
||||
},
|
||||
{
|
||||
"n", 1, 0, UCON64_N,
|
||||
"NEW_NAME", "change internal ROM name to NEW_NAME",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
|
||||
},
|
||||
{
|
||||
"logo", 0, 0, UCON64_LOGO,
|
||||
NULL, "restore ROM logo character data (offset: 0x104-0x134)",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
|
||||
},
|
||||
{
|
||||
"mgd", 0, 0, UCON64_MGD,
|
||||
NULL, "convert to Multi Game*/MGD2/RAW",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
|
||||
},
|
||||
{
|
||||
"ssc", 0, 0, UCON64_SSC,
|
||||
NULL, "convert to Super Smart Card/SSC",
|
||||
&ucon64_wf[WF_OBJ_GB_DEFAULT]
|
||||
},
|
||||
{
|
||||
"sgb", 0, 0, UCON64_SGB,
|
||||
NULL, "convert from GB Xchanger/GB/GBC to Super Backup Card/GX/GBX",
|
||||
&ucon64_wf[WF_OBJ_GB_DEFAULT]
|
||||
},
|
||||
{
|
||||
"gbx", 0, 0, UCON64_GBX,
|
||||
NULL, "convert from Super Backup Card/GX/GBX to GB Xchanger/GB/GBC",
|
||||
&ucon64_wf[WF_OBJ_GB_DEFAULT]
|
||||
},
|
||||
{
|
||||
"n2gb", 1, 0, UCON64_N2GB,
|
||||
"NESROM", "KAMI's FC EMUlator (NES emulator);\n"
|
||||
"ROM should be KAMI's FC Emulator ROM image\n"
|
||||
"NESROM should contain 16 kB of PRG data and 8 kB of CHR data",
|
||||
&ucon64_wf[WF_OBJ_GB_DEFAULT]
|
||||
},
|
||||
{
|
||||
"chk", 0, 0, UCON64_CHK,
|
||||
NULL, "fix ROM checksum",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
|
||||
},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
0148 ROM size:
|
||||
0 - 256kBit = 32kB = 2 banks
|
||||
1 - 512kBit = 64kB = 4 banks
|
||||
2 - 1Mb = 128kB = 8 banks
|
||||
3 - 2Mb = 256kB = 16 banks
|
||||
4 - 4Mb = 512kB = 32 banks
|
||||
0149 RAM size:
|
||||
0 - None
|
||||
1 - 16kBit = 2kB = 1 bank
|
||||
2 - 64kBit = 8kB = 1 bank
|
||||
3 - 256kBit = 32kB = 4 banks
|
||||
*/
|
||||
typedef struct st_gameboy_header
|
||||
{
|
||||
unsigned char opcode1; // 0x00 usually 0x00, NOP
|
||||
unsigned char opcode2; // 0x01 usually 0xc3, JP
|
||||
unsigned char start_low; // 0x02 first byte of parameter of JP
|
||||
unsigned char start_high; // 0x03 second byte
|
||||
unsigned char logo[GB_LOGODATA_LEN]; // 0x04
|
||||
unsigned char name[GB_NAME_LEN]; // 0x34
|
||||
unsigned char gb_type; // 0x43
|
||||
unsigned char maker_high; // 0x44
|
||||
unsigned char maker_low; // 0x45
|
||||
unsigned char pad;
|
||||
unsigned char rom_type; // 0x47
|
||||
unsigned char rom_size; // 0x48
|
||||
unsigned char sram_size; // 0x49
|
||||
unsigned char country; // 0x4a
|
||||
unsigned char maker; // 0x4b
|
||||
unsigned char version; // 0x4c
|
||||
unsigned char header_checksum; // 0x4d
|
||||
unsigned char checksum_high; // 0x4e
|
||||
unsigned char checksum_low; // 0x4f
|
||||
} st_gameboy_header_t;
|
||||
|
||||
static st_gameboy_header_t gameboy_header;
|
||||
const unsigned char gb_logodata[] = // Note: not a static variable
|
||||
{
|
||||
0xce, 0xed, 0x66, 0x66, 0xcc, 0x0d, 0x00, 0x0b,
|
||||
0x03, 0x73, 0x00, 0x83, 0x00, 0x0c, 0x00, 0x0d,
|
||||
0x00, 0x08, 0x11, 0x1f, 0x88, 0x89, 0x00, 0x0e,
|
||||
0xdc, 0xcc, 0x6e, 0xe6, 0xdd, 0xdd, 0xd9, 0x99,
|
||||
0xbb, 0xbb, 0x67, 0x63, 0x6e, 0x0e, 0xec, 0xcc,
|
||||
0xdd, 0xdc, 0x99, 0x9f, 0xbb, 0xb9, 0x33, 0x3e
|
||||
},
|
||||
rocket_logodata[] = // idem
|
||||
{
|
||||
0x11, 0x23, 0xf1, 0x1e, 0x01, 0x22, 0xf0, 0x00,
|
||||
0x08, 0x99, 0x78, 0x00, 0x08, 0x11, 0x9a, 0x48,
|
||||
0x11, 0x23, 0xf0, 0x0e, 0x70, 0x01, 0xf8, 0x80,
|
||||
0x22, 0x44, 0x44, 0x22, 0x22, 0x21, 0x00, 0x1e,
|
||||
0x99, 0x10, 0x00, 0x1e, 0x19, 0x22, 0x44, 0x22,
|
||||
0x22, 0x47, 0x00, 0x0e, 0x11, 0x22, 0x00, 0x00
|
||||
};
|
||||
|
||||
typedef struct st_gameboy_chksum
|
||||
{
|
||||
unsigned short value;
|
||||
unsigned char header;
|
||||
} st_gameboy_chksum_t;
|
||||
|
||||
static st_gameboy_chksum_t checksum;
|
||||
static st_gameboy_chksum_t gameboy_chksum (st_rominfo_t *rominfo);
|
||||
|
||||
|
||||
int
|
||||
gameboy_logo (st_rominfo_t *rominfo)
|
||||
{
|
||||
char dest_name[FILENAME_MAX];
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fwrite ((unsigned char *)
|
||||
((gameboy_header.rom_type >= 0x97 && gameboy_header.rom_type <= 0x99) ?
|
||||
rocket_logodata : gb_logodata),
|
||||
rominfo->buheader_len + GAMEBOY_HEADER_START + 4, GB_LOGODATA_LEN,
|
||||
dest_name, "r+b");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gameboy_n2gb (st_rominfo_t *rominfo, const char *nesrom)
|
||||
{
|
||||
#define EMULATOR_LEN 0x10000
|
||||
st_ines_header_t ines_header;
|
||||
int n = 0, crc = 0;
|
||||
unsigned char *buf;
|
||||
char dest_name[FILENAME_MAX];
|
||||
|
||||
if (ucon64.file_size - rominfo->buheader_len != EMULATOR_LEN)
|
||||
{
|
||||
fprintf (stderr, "ERROR: %s does not appear to be KAMI's FC emulator\n", ucon64.rom);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ucon64_fread (&ines_header, 0, INES_HEADER_LEN, nesrom);
|
||||
if (memcmp (ines_header.signature, INES_SIG_S, 4))
|
||||
{
|
||||
fprintf (stderr, "ERROR: Only NES ROMs with iNES header are supported\n");
|
||||
return -1;
|
||||
}
|
||||
if (ines_header.prg_size != 1 || ines_header.chr_size != 1)
|
||||
{
|
||||
fprintf (stderr,
|
||||
"ERROR: Only NES ROMs with 0.1250 Mb of ROM (PRG) and 0.0625 Mb of VROM (CHR)\n"
|
||||
" are supported by KAMI's FC emulator\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!(buf = (unsigned char *) malloc (ucon64.file_size)))
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], ucon64.file_size);
|
||||
return -1;
|
||||
}
|
||||
ucon64_fread (buf, 0, ucon64.file_size, ucon64.rom);
|
||||
ucon64_fread (rominfo->buheader_len + buf + 0x4000, INES_HEADER_LEN,
|
||||
0x4000 + 0x2000, nesrom); // read PRG & CHR data
|
||||
|
||||
for (n = 0; n < ucon64.file_size - rominfo->buheader_len; n++)
|
||||
{
|
||||
if ((n == GAMEBOY_HEADER_START + 0x4e) || (n == GAMEBOY_HEADER_START + 0x4f))
|
||||
continue;
|
||||
else
|
||||
crc += buf[rominfo->buheader_len + n];
|
||||
}
|
||||
|
||||
buf[rominfo->buheader_len + GAMEBOY_HEADER_START + 0x4e] = crc >> 8;
|
||||
buf[rominfo->buheader_len + GAMEBOY_HEADER_START + 0x4f] = crc;
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
ucon64_fwrite (buf, 0, ucon64.file_size, dest_name, "wb");
|
||||
|
||||
free (buf);
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
gameboy_convert_data (st_rominfo_t *rominfo, unsigned char *conversion_table,
|
||||
const char *suffix)
|
||||
{
|
||||
char dest_name[FILENAME_MAX], src_name[FILENAME_MAX];
|
||||
unsigned char buf[MAXBUFSIZE];
|
||||
int x, n, n_bytes;
|
||||
|
||||
strcpy (src_name, ucon64.rom);
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
set_suffix (dest_name, suffix);
|
||||
ucon64_file_handler (dest_name, src_name, 0);
|
||||
|
||||
x = rominfo->buheader_len;
|
||||
while ((n_bytes = ucon64_fread (buf, x, MAXBUFSIZE, src_name)))
|
||||
{
|
||||
for (n = 0; n < n_bytes; n++)
|
||||
buf[n] = conversion_table[(int) buf[n]];
|
||||
ucon64_fwrite (buf, x, n_bytes, dest_name, x == rominfo->buheader_len ? "wb" : "ab");
|
||||
x += n_bytes;
|
||||
}
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gameboy_gbx (st_rominfo_t *rominfo)
|
||||
{
|
||||
unsigned char gbx2gbc[] =
|
||||
{
|
||||
0xB4, 0xBC, 0xA4, 0xAC, 0x94, 0x9C, 0x84, 0x8C,
|
||||
0xF4, 0xFC, 0xE4, 0xEC, 0xD4, 0xDC, 0xC4, 0xCC,
|
||||
0x34, 0x3C, 0x24, 0x2C, 0x14, 0x1C, 0x04, 0x0C,
|
||||
0x74, 0x7C, 0x64, 0x6C, 0x54, 0x5C, 0x44, 0x4C,
|
||||
0xB5, 0xBD, 0xA5, 0xAD, 0x95, 0x9D, 0x85, 0x8D,
|
||||
0xF5, 0xFD, 0xE5, 0xED, 0xD5, 0xDD, 0xC5, 0xCD,
|
||||
0x35, 0x3D, 0x25, 0x2D, 0x15, 0x1D, 0x05, 0x0D,
|
||||
0x75, 0x7D, 0x65, 0x6D, 0x55, 0x5D, 0x45, 0x4D,
|
||||
0xB6, 0xBE, 0xA6, 0xAE, 0x96, 0x9E, 0x86, 0x8E,
|
||||
0xF6, 0xFE, 0xE6, 0xEE, 0xD6, 0xDE, 0xC6, 0xCE,
|
||||
0x36, 0x3E, 0x26, 0x2E, 0x16, 0x1E, 0x06, 0x0E,
|
||||
0x76, 0x7E, 0x66, 0x6E, 0x56, 0x5E, 0x46, 0x4E,
|
||||
0xB7, 0xBF, 0xA7, 0xAF, 0x97, 0x9F, 0x87, 0x8F,
|
||||
0xF7, 0xFF, 0xE7, 0xEF, 0xD7, 0xDF, 0xC7, 0xCF,
|
||||
0x37, 0x3F, 0x27, 0x2F, 0x17, 0x1F, 0x07, 0x0F,
|
||||
0x77, 0x7F, 0x67, 0x6F, 0x57, 0x5F, 0x47, 0x4F,
|
||||
0xB0, 0xB8, 0xA0, 0xA8, 0x90, 0x98, 0x80, 0x88,
|
||||
0xF0, 0xF8, 0xE0, 0xE8, 0xD0, 0xD8, 0xC0, 0xC8,
|
||||
0x30, 0x38, 0x20, 0x28, 0x10, 0x18, 0x00, 0x08,
|
||||
0x70, 0x78, 0x60, 0x68, 0x50, 0x58, 0x40, 0x48,
|
||||
0xB1, 0xB9, 0xA1, 0xA9, 0x91, 0x99, 0x81, 0x89,
|
||||
0xF1, 0xF9, 0xE1, 0xE9, 0xD1, 0xD9, 0xC1, 0xC9,
|
||||
0x31, 0x39, 0x21, 0x29, 0x11, 0x19, 0x01, 0x09,
|
||||
0x71, 0x79, 0x61, 0x69, 0x51, 0x59, 0x41, 0x49,
|
||||
0xB2, 0xBA, 0xA2, 0xAA, 0x92, 0x9A, 0x82, 0x8A,
|
||||
0xF2, 0xFA, 0xE2, 0xEA, 0xD2, 0xDA, 0xC2, 0xCA,
|
||||
0x32, 0x3A, 0x22, 0x2A, 0x12, 0x1A, 0x02, 0x0A,
|
||||
0x72, 0x7A, 0x62, 0x6A, 0x52, 0x5A, 0x42, 0x4A,
|
||||
0xB3, 0xBB, 0xA3, 0xAB, 0x93, 0x9B, 0x83, 0x8B,
|
||||
0xF3, 0xFB, 0xE3, 0xEB, 0xD3, 0xDB, 0xC3, 0xCB,
|
||||
0x33, 0x3B, 0x23, 0x2B, 0x13, 0x1B, 0x03, 0x0B,
|
||||
0x73, 0x7B, 0x63, 0x6B, 0x53, 0x5B, 0x43, 0x4B
|
||||
};
|
||||
const char *old_suffix = get_suffix (ucon64.rom), *new_suffix;
|
||||
new_suffix = stricmp (old_suffix, ".GBX") ? ".GB" : ".GBC";
|
||||
return gameboy_convert_data (rominfo, gbx2gbc, new_suffix);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gameboy_sgb (st_rominfo_t *rominfo)
|
||||
{
|
||||
unsigned char gbc2gbx[] =
|
||||
{
|
||||
0x96, 0xB6, 0xD6, 0xF6, 0x16, 0x36, 0x56, 0x76,
|
||||
0x97, 0xB7, 0xD7, 0xF7, 0x17, 0x37, 0x57, 0x77,
|
||||
0x94, 0xB4, 0xD4, 0xF4, 0x14, 0x34, 0x54, 0x74,
|
||||
0x95, 0xB5, 0xD5, 0xF5, 0x15, 0x35, 0x55, 0x75,
|
||||
0x92, 0xB2, 0xD2, 0xF2, 0x12, 0x32, 0x52, 0x72,
|
||||
0x93, 0xB3, 0xD3, 0xF3, 0x13, 0x33, 0x53, 0x73,
|
||||
0x90, 0xB0, 0xD0, 0xF0, 0x10, 0x30, 0x50, 0x70,
|
||||
0x91, 0xB1, 0xD1, 0xF1, 0x11, 0x31, 0x51, 0x71,
|
||||
0x9E, 0xBE, 0xDE, 0xFE, 0x1E, 0x3E, 0x5E, 0x7E,
|
||||
0x9F, 0xBF, 0xDF, 0xFF, 0x1F, 0x3F, 0x5F, 0x7F,
|
||||
0x9C, 0xBC, 0xDC, 0xFC, 0x1C, 0x3C, 0x5C, 0x7C,
|
||||
0x9D, 0xBD, 0xDD, 0xFD, 0x1D, 0x3D, 0x5D, 0x7D,
|
||||
0x9A, 0xBA, 0xDA, 0xFA, 0x1A, 0x3A, 0x5A, 0x7A,
|
||||
0x9B, 0xBB, 0xDB, 0xFB, 0x1B, 0x3B, 0x5B, 0x7B,
|
||||
0x98, 0xB8, 0xD8, 0xF8, 0x18, 0x38, 0x58, 0x78,
|
||||
0x99, 0xB9, 0xD9, 0xF9, 0x19, 0x39, 0x59, 0x79,
|
||||
0x86, 0xA6, 0xC6, 0xE6, 0x06, 0x26, 0x46, 0x66,
|
||||
0x87, 0xA7, 0xC7, 0xE7, 0x07, 0x27, 0x47, 0x67,
|
||||
0x84, 0xA4, 0xC4, 0xE4, 0x04, 0x24, 0x44, 0x64,
|
||||
0x85, 0xA5, 0xC5, 0xE5, 0x05, 0x25, 0x45, 0x65,
|
||||
0x82, 0xA2, 0xC2, 0xE2, 0x02, 0x22, 0x42, 0x62,
|
||||
0x83, 0xA3, 0xC3, 0xE3, 0x03, 0x23, 0x43, 0x63,
|
||||
0x80, 0xA0, 0xC0, 0xE0, 0x00, 0x20, 0x40, 0x60,
|
||||
0x81, 0xA1, 0xC1, 0xE1, 0x01, 0x21, 0x41, 0x61,
|
||||
0x8E, 0xAE, 0xCE, 0xEE, 0x0E, 0x2E, 0x4E, 0x6E,
|
||||
0x8F, 0xAF, 0xCF, 0xEF, 0x0F, 0x2F, 0x4F, 0x6F,
|
||||
0x8C, 0xAC, 0xCC, 0xEC, 0x0C, 0x2C, 0x4C, 0x6C,
|
||||
0x8D, 0xAD, 0xCD, 0xED, 0x0D, 0x2D, 0x4D, 0x6D,
|
||||
0x8A, 0xAA, 0xCA, 0xEA, 0x0A, 0x2A, 0x4A, 0x6A,
|
||||
0x8B, 0xAB, 0xCB, 0xEB, 0x0B, 0x2B, 0x4B, 0x6B,
|
||||
0x88, 0xA8, 0xC8, 0xE8, 0x08, 0x28, 0x48, 0x68,
|
||||
0x89, 0xA9, 0xC9, 0xE9, 0x09, 0x29, 0x49, 0x69
|
||||
};
|
||||
const char *old_suffix = get_suffix (ucon64.rom), *new_suffix;
|
||||
new_suffix = stricmp (old_suffix, ".GBC") ? ".GX" : ".GBX";
|
||||
return gameboy_convert_data (rominfo, gbc2gbx, new_suffix);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gameboy_n (st_rominfo_t *rominfo, const char *name)
|
||||
{
|
||||
char buf[GB_NAME_LEN], dest_name[FILENAME_MAX];
|
||||
|
||||
memset (buf, 0, GB_NAME_LEN);
|
||||
strncpy (buf, name, GB_NAME_LEN);
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fwrite (buf, rominfo->buheader_len + GAMEBOY_HEADER_START + 0x34,
|
||||
GB_NAME_LEN, dest_name, "r+b");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gameboy_chk (st_rominfo_t *rominfo)
|
||||
{
|
||||
char buf[4], dest_name[FILENAME_MAX];
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
|
||||
buf[0] = checksum.header;
|
||||
buf[1] = rominfo->current_internal_crc >> 8;
|
||||
buf[2] = rominfo->current_internal_crc;
|
||||
ucon64_fwrite (buf, rominfo->buheader_len + GAMEBOY_HEADER_START + 0x4d, 3,
|
||||
dest_name, "r+b");
|
||||
|
||||
dumper (stdout, buf, 3, GAMEBOY_HEADER_START + rominfo->buheader_len + 0x4d, DUMPER_HEX);
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gameboy_mgd (st_rominfo_t *rominfo)
|
||||
// TODO: convert the ROM data
|
||||
{
|
||||
char src_name[FILENAME_MAX], dest_name[FILENAME_MAX];
|
||||
int size = ucon64.file_size - rominfo->buheader_len;
|
||||
|
||||
strcpy (src_name, ucon64.rom);
|
||||
mgd_make_name (ucon64.rom, UCON64_GB, size, dest_name);
|
||||
ucon64_file_handler (dest_name, src_name, OF_FORCE_BASENAME);
|
||||
|
||||
fcopy (src_name, rominfo->buheader_len, size, dest_name, "wb");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
remove_temp_file ();
|
||||
|
||||
mgd_write_index_file ((char *) basename2 (dest_name), 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gameboy_ssc (st_rominfo_t *rominfo)
|
||||
// TODO: convert the ROM data
|
||||
{
|
||||
st_unknown_header_t header;
|
||||
char src_name[FILENAME_MAX], dest_name[FILENAME_MAX];
|
||||
const char *p = NULL;
|
||||
int size = ucon64.file_size - rominfo->buheader_len;
|
||||
|
||||
memset (&header, 0, UNKNOWN_HEADER_LEN);
|
||||
|
||||
header.size_low = size / 8192;
|
||||
header.size_high = size / 8192 >> 8;
|
||||
header.id1 = 0xaa;
|
||||
header.id2 = 0xbb;
|
||||
#if 0 // TODO: find out correct value. 2 is used for Magic Super Griffin
|
||||
header.type = 2;
|
||||
#endif
|
||||
|
||||
strcpy (src_name, ucon64.rom);
|
||||
p = basename2 (ucon64.rom);
|
||||
// TODO: find out if this is correct (giving the file name a prefix)
|
||||
if ((p[0] == 'G' || p[0] == 'g') && (p[1] == 'B' || p[1] == 'b'))
|
||||
strcpy (dest_name, p);
|
||||
else
|
||||
sprintf (dest_name, "gb%s", p);
|
||||
set_suffix (dest_name, ".gb");
|
||||
|
||||
ucon64_file_handler (dest_name, src_name, 0);
|
||||
ucon64_fwrite (&header, 0, UNKNOWN_HEADER_LEN, dest_name, "wb");
|
||||
fcopy (src_name, rominfo->buheader_len, size, dest_name, "ab");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
remove_temp_file ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gameboy_init (st_rominfo_t *rominfo)
|
||||
{
|
||||
int result = -1, value, x;
|
||||
char buf[MAXBUFSIZE];
|
||||
static const char *gameboy_romtype1[0x20] =
|
||||
{
|
||||
"ROM only",
|
||||
"ROM + MBC1",
|
||||
"ROM + MBC1 + RAM",
|
||||
"ROM + MBC1 + RAM + Battery",
|
||||
NULL,
|
||||
"ROM + MBC2",
|
||||
"ROM + MBC2 + Battery",
|
||||
NULL,
|
||||
"ROM + RAM", // correct? - dbjh
|
||||
"ROM + RAM + Battery", // correct? - dbjh
|
||||
NULL,
|
||||
"ROM + MMM01",
|
||||
"ROM + MMM01 + SRAM",
|
||||
"ROM + MMM01 + SRAM + Battery",
|
||||
NULL,
|
||||
"ROM + MBC3 + Battery + Timer",
|
||||
"ROM + MBC3 + RAM + Battery + Timer",
|
||||
"ROM + MBC3",
|
||||
"ROM + MBC3 + RAM",
|
||||
"ROM + MBC3 + RAM + Battery",
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"ROM + MBC5",
|
||||
"ROM + MBC5 + RAM",
|
||||
"ROM + MBC5 + RAM + Battery",
|
||||
"ROM + MBC5 + Rumble",
|
||||
"ROM + MBC5 + SRAM + Rumble",
|
||||
"ROM + MBC5 + SRAM + Battery + Rumble",
|
||||
"Nintendo Pocket Camera"
|
||||
},
|
||||
*gameboy_romtype2[3] =
|
||||
{
|
||||
"Rocket Games",
|
||||
NULL,
|
||||
"Rocket Games 2-in-1"
|
||||
},
|
||||
*gameboy_romtype3[3] =
|
||||
{
|
||||
"Bandai TAMA5",
|
||||
"Hudson HuC-3",
|
||||
"Hudson HuC-1"
|
||||
},
|
||||
*str;
|
||||
|
||||
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ? ucon64.buheader_len : 0;
|
||||
|
||||
ucon64_fread (&gameboy_header, rominfo->buheader_len + GAMEBOY_HEADER_START,
|
||||
GAMEBOY_HEADER_LEN, ucon64.rom);
|
||||
if (gameboy_header.opcode1 == 0x00 && gameboy_header.opcode2 == 0xc3)
|
||||
result = 0;
|
||||
else
|
||||
{
|
||||
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ?
|
||||
ucon64.buheader_len : (int) SSC_HEADER_LEN;
|
||||
|
||||
ucon64_fread (&gameboy_header, rominfo->buheader_len + GAMEBOY_HEADER_START,
|
||||
GAMEBOY_HEADER_LEN, ucon64.rom);
|
||||
if (gameboy_header.opcode1 == 0x00 && gameboy_header.opcode2 == 0xc3)
|
||||
result = 0;
|
||||
else
|
||||
result = -1;
|
||||
}
|
||||
if (ucon64.console == UCON64_GB)
|
||||
result = 0;
|
||||
|
||||
rominfo->header_start = GAMEBOY_HEADER_START;
|
||||
rominfo->header_len = GAMEBOY_HEADER_LEN;
|
||||
rominfo->header = &gameboy_header;
|
||||
|
||||
// internal ROM name
|
||||
strncpy (rominfo->name, (const char *) gameboy_header.name, GB_NAME_LEN);
|
||||
rominfo->name[GB_NAME_LEN] = 0; // terminate string
|
||||
|
||||
// ROM maker
|
||||
if (gameboy_header.maker == 0x33)
|
||||
{
|
||||
int ih = gameboy_header.maker_high <= '9' ?
|
||||
gameboy_header.maker_high - '0' : gameboy_header.maker_high - 'A' + 10,
|
||||
il = gameboy_header.maker_low <= '9' ?
|
||||
gameboy_header.maker_low - '0' : gameboy_header.maker_low - 'A' + 10;
|
||||
x = ih * 36 + il;
|
||||
}
|
||||
else
|
||||
x = (gameboy_header.maker >> 4) * 36 + (gameboy_header.maker & 0x0f);
|
||||
|
||||
/*
|
||||
I added the first if statement, because I didn't want to expand
|
||||
nintendo_maker by a large amount for only one publisher and because index 0
|
||||
is used when the publisher code is unknown (so it shouldn't be set to
|
||||
"Rocket Games"). - dbjh
|
||||
*/
|
||||
if (x == 33 * 36 + 33 || x == 0) // publisher code XX/00
|
||||
x = 2; // Rocket Games
|
||||
else if (x < 0 || x >= NINTENDO_MAKER_LEN)
|
||||
x = 0;
|
||||
rominfo->maker = NULL_TO_UNKNOWN_S (nintendo_maker[x]);
|
||||
|
||||
// ROM country
|
||||
rominfo->country = gameboy_header.country == 0 ? "Japan" : "U.S.A. & Europe";
|
||||
|
||||
// misc stuff
|
||||
// Don't move division by 4 to shift parameter (gameboy_header.rom_size can be < 2)
|
||||
sprintf (buf, "Internal size: %.4f Mb\n", (1 << gameboy_header.rom_size) / 4.0f);
|
||||
strcat (rominfo->misc, buf);
|
||||
|
||||
if (gameboy_header.rom_type <= 0x1f)
|
||||
str = NULL_TO_UNKNOWN_S (gameboy_romtype1[gameboy_header.rom_type]);
|
||||
else if (gameboy_header.rom_type >= 0x97 && gameboy_header.rom_type <= 0x99)
|
||||
str = gameboy_romtype2[gameboy_header.rom_type - 0x97];
|
||||
else if (gameboy_header.rom_type >= 0xfd)
|
||||
str = gameboy_romtype3[gameboy_header.rom_type - 0xfd];
|
||||
else
|
||||
str = "Unknown";
|
||||
sprintf (buf, "ROM type: %s\n", str);
|
||||
strcat (rominfo->misc, buf);
|
||||
|
||||
if (!gameboy_header.sram_size)
|
||||
sprintf (buf, "Save RAM: No\n");
|
||||
else
|
||||
{
|
||||
value = (gameboy_header.sram_size & 7) << 1; // 0/1/2/4/5
|
||||
if (value)
|
||||
value = 1 << (value - 1);
|
||||
|
||||
sprintf (buf, "Save RAM: Yes, %d kBytes\n", value);
|
||||
}
|
||||
strcat (rominfo->misc, buf);
|
||||
|
||||
sprintf (buf, "Version: 1.%d\n", gameboy_header.version);
|
||||
strcat (rominfo->misc, buf);
|
||||
|
||||
sprintf (buf, "Game Boy type: %s\n",
|
||||
(gameboy_header.gb_type == 0x80) ? "Color" :
|
||||
// (OFFSET (gameboy_header, 0x46) == 0x03) ? "Super" :
|
||||
"Standard (4 colors)");
|
||||
strcat (rominfo->misc, buf);
|
||||
|
||||
value = gameboy_header.start_high << 8;
|
||||
value += gameboy_header.start_low;
|
||||
sprintf (buf, "Start address: 0x%04x\n", value);
|
||||
strcat (rominfo->misc, buf);
|
||||
|
||||
strcat (rominfo->misc, "Logo data: ");
|
||||
if (memcmp (gameboy_header.logo,
|
||||
(gameboy_header.rom_type >= 0x97 && gameboy_header.rom_type <= 0x99) ?
|
||||
rocket_logodata : gb_logodata,
|
||||
GB_LOGODATA_LEN) == 0)
|
||||
{
|
||||
#ifdef USE_ANSI_COLOR
|
||||
if (ucon64.ansi_color)
|
||||
strcat (rominfo->misc, "\x1b[01;32mOk\x1b[0m");
|
||||
else
|
||||
#endif
|
||||
strcat (rominfo->misc, "Ok");
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_ANSI_COLOR
|
||||
if (ucon64.ansi_color)
|
||||
strcat (rominfo->misc, "\x1b[01;31mBad\x1b[0m");
|
||||
else
|
||||
#endif
|
||||
strcat (rominfo->misc, "Bad");
|
||||
}
|
||||
|
||||
if (!UCON64_ISSET (ucon64.do_not_calc_crc) && result == 0)
|
||||
{
|
||||
rominfo->has_internal_crc = 1;
|
||||
rominfo->internal_crc_len = 2;
|
||||
checksum = gameboy_chksum (rominfo);
|
||||
rominfo->current_internal_crc = checksum.value;
|
||||
|
||||
rominfo->internal_crc = (gameboy_header.checksum_high << 8) +
|
||||
gameboy_header.checksum_low;
|
||||
|
||||
x = gameboy_header.header_checksum;
|
||||
sprintf (rominfo->internal_crc2,
|
||||
"Header checksum: %s, 0x%02x (calculated) %c= 0x%02x (internal)",
|
||||
#ifdef USE_ANSI_COLOR
|
||||
ucon64.ansi_color ?
|
||||
((checksum.header == x) ?
|
||||
"\x1b[01;32mOk\x1b[0m" : "\x1b[01;31mBad\x1b[0m")
|
||||
:
|
||||
((checksum.header == x) ? "Ok" : "Bad"),
|
||||
#else
|
||||
(checksum.header == x) ? "Ok" : "Bad",
|
||||
#endif
|
||||
checksum.header, (checksum.header == x) ? '=' : '!', x);
|
||||
}
|
||||
|
||||
rominfo->console_usage = gameboy_usage[0].help;
|
||||
rominfo->copier_usage = (!rominfo->buheader_len ? mgd_usage[0].help : ssc_usage[0].help);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
st_gameboy_chksum_t
|
||||
gameboy_chksum (st_rominfo_t *rominfo)
|
||||
{
|
||||
st_gameboy_chksum_t sum = { 0, 0 };
|
||||
unsigned char *rom_buffer;
|
||||
int size = ucon64.file_size - rominfo->buheader_len, i;
|
||||
|
||||
if (!(rom_buffer = (unsigned char *) malloc (size)))
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], size);
|
||||
return sum;
|
||||
}
|
||||
ucon64_fread (rom_buffer, rominfo->buheader_len, size, ucon64.rom);
|
||||
|
||||
for (i = GAMEBOY_HEADER_START + 0x34; i < GAMEBOY_HEADER_START + 0x4d; i++)
|
||||
sum.header += ~rom_buffer[i];
|
||||
for (i = 0; i < size; i++)
|
||||
sum.value += rom_buffer[i];
|
||||
sum.value -= (rom_buffer[GAMEBOY_HEADER_START + 0x4d] - sum.header) +
|
||||
rom_buffer[GAMEBOY_HEADER_START + 0x4e] +
|
||||
rom_buffer[GAMEBOY_HEADER_START + 0x4f];
|
||||
|
||||
free (rom_buffer);
|
||||
|
||||
return sum;
|
||||
}
|
||||
39
tools/ucon64/src/console/gb.h
Normal file
39
tools/ucon64/src/console/gb.h
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
gb.h - Game Boy support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef GB_H
|
||||
#define GB_H
|
||||
|
||||
#define GB_LOGODATA_LEN 48
|
||||
|
||||
extern const st_getopt2_t gameboy_usage[];
|
||||
extern const unsigned char gb_logodata[], rocket_logodata[];
|
||||
|
||||
extern int gameboy_chk (st_rominfo_t *rominfo);
|
||||
extern int gameboy_gbx (st_rominfo_t *rominfo);
|
||||
extern int gameboy_mgd (st_rominfo_t *rominfo);
|
||||
extern int gameboy_n (st_rominfo_t *rominfo, const char *name);
|
||||
extern int gameboy_n2gb (st_rominfo_t *rominfo, const char *emu_rom);
|
||||
extern int gameboy_sgb (st_rominfo_t *rominfo);
|
||||
extern int gameboy_ssc (st_rominfo_t *rominfo);
|
||||
extern int gameboy_init (st_rominfo_t *rominfo);
|
||||
extern int gameboy_logo (st_rominfo_t *rominfo);
|
||||
|
||||
#endif
|
||||
850
tools/ucon64/src/console/gba.c
Normal file
850
tools/ucon64/src/console/gba.c
Normal file
@@ -0,0 +1,850 @@
|
||||
/*
|
||||
gba.c - Game Boy Advance support for uCON64
|
||||
|
||||
Copyright (c) 2001 NoisyB <noisyb@gmx.net>
|
||||
Copyright (c) 2001 - 2004 dbjh
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include "misc/file.h"
|
||||
#include "misc/misc.h"
|
||||
#include "misc/property.h"
|
||||
#ifdef USE_ZLIB
|
||||
#include "misc/archive.h"
|
||||
#endif
|
||||
#include "misc/getopt2.h" // st_getopt2_t
|
||||
#include "misc/string.h"
|
||||
#include "ucon64.h"
|
||||
#include "ucon64_misc.h"
|
||||
#include "gba.h"
|
||||
#include "backup/fal.h"
|
||||
|
||||
|
||||
#define GBA_NAME_LEN 12
|
||||
#define GBA_HEADER_START 0
|
||||
#define GBA_HEADER_LEN (sizeof (st_gba_header_t))
|
||||
|
||||
|
||||
static int gba_chksum (void);
|
||||
|
||||
const st_getopt2_t gba_usage[] =
|
||||
{
|
||||
{
|
||||
NULL, 0, 0, 0,
|
||||
NULL, "Game Boy Advance"/*"2001 Nintendo http://www.nintendo.com"*/,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"gba", 0, 0, UCON64_GBA,
|
||||
NULL, "force recognition",
|
||||
&ucon64_wf[WF_OBJ_GBA_SWITCH]
|
||||
},
|
||||
{
|
||||
"n", 1, 0, UCON64_N,
|
||||
"NEW_NAME", "change internal ROM name to NEW_NAME",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
|
||||
},
|
||||
{
|
||||
"logo", 0, 0, UCON64_LOGO,
|
||||
NULL, "restore ROM logo character data (offset: 0x04-0x9F)",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
|
||||
},
|
||||
{
|
||||
"chk", 0, 0, UCON64_CHK,
|
||||
NULL, "fix ROM header checksum",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
|
||||
},
|
||||
{
|
||||
"sram", 0, 0, UCON64_SRAM,
|
||||
NULL, "patch ROM for SRAM saving",
|
||||
&ucon64_wf[WF_OBJ_GBA_DEFAULT]
|
||||
},
|
||||
{
|
||||
"crp", 1, 0, UCON64_CRP,
|
||||
"WAIT_TIME", "slow down ROM access (\"crash patch\");\n"
|
||||
"WAIT_TIME=0 default in most crash patches\n"
|
||||
"WAIT_TIME=4 faster than 0, slower than 8\n"
|
||||
"WAIT_TIME=8 faster than 4, slower than 28\n"
|
||||
"WAIT_TIME=12 slowest cartridge access speed\n"
|
||||
"WAIT_TIME=16 faster than 28, but slower than 20\n"
|
||||
"WAIT_TIME=20 default in most original cartridges\n"
|
||||
"WAIT_TIME=24 fastest cartridge access speed\n"
|
||||
"WAIT_TIME=28 faster than 8 but slower than 16",
|
||||
&ucon64_wf[WF_OBJ_GBA_DEFAULT]
|
||||
},
|
||||
// "n 0 and 28, with a stepping of 4. I.e. 0, 4, 8, 12 ...\n"
|
||||
{
|
||||
"multi", 1, 0, UCON64_MULTI,
|
||||
"SIZE", "make multi-game file for use with FAL/F2A flash card, truncated\n"
|
||||
"to SIZE Mbit; file with loader must be specified first, then\n"
|
||||
"all the ROMs, multi-game file to create last",
|
||||
&ucon64_wf[WF_OBJ_ALL_INIT_PROBE_STOP]
|
||||
},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Offset 00h-03h - Start Address - A 32 bit ARM B command with jump destination
|
||||
to the start address of the program, cannot be manipulated
|
||||
with this tool, there's no reason.
|
||||
|
||||
Offset 04h-9fh - Nintendo logo character data - The fix Nintendo logo graphics
|
||||
needed to start a ROM on the real machine as it is verified
|
||||
by it.
|
||||
|
||||
Offset a0h-abh - Game title - The game title is an ASCII string, officially
|
||||
can use only ASCII characters between the ASCII code 20h and
|
||||
60h. Although it is not a strict rule for hobby programmers,
|
||||
it is fun to follow such a rules in my opinion. As I know
|
||||
developers can choose their own game title here describing
|
||||
the product in short.
|
||||
|
||||
Offset ach-afh - Game code - The 4 bytes long code of the game is an ASCII
|
||||
string too, officially can use only ASCII characters between
|
||||
the ASCII code 20h and 60h. The first letter is always A as I
|
||||
know, probably stands for GBA, so it won't change unless a
|
||||
higher hardware with backwards compatibility won't be
|
||||
introduced and this letter could hold some more infos about
|
||||
it. The second and third letters are the shortened version of
|
||||
the name of the game. And the fourth letter is the territory
|
||||
code. Don't afraid, there's no territory lockout, this is for
|
||||
information purposes only. So far as I know J stands for
|
||||
Japan and Asia, E stands for USA and the whole American
|
||||
continent and P stands for Europe, Australia and Africa
|
||||
(probably came from that these are the PAL video standard
|
||||
territories, but I could be wrong). Although it is not a
|
||||
strict rule for hobby programmers, it is fun to follow such a
|
||||
rules in my opinion. Developers get this 4 letter code right
|
||||
from Nintendo and they have to use that.
|
||||
|
||||
Offset b0h-b1h - Maker code - The 2 bytes long code of the developer company
|
||||
is an ASCII string too, officially can use only ASCII
|
||||
characters between the ASCII code 20h and 60h. Although it is
|
||||
not a strict rule for hobby programmers, it is fun to follow
|
||||
such a rules in my opinion. Developers get this 2 letter code
|
||||
right from Nintendo and they have to use that.
|
||||
|
||||
Offset b2h-b2h - 96h - Fixed 96h byte without any useful information.
|
||||
|
||||
Offset b3h-b3h - Main unit code - This hexadecimal byte is the destination
|
||||
hardware code. It is always 00h at the moment as it stands
|
||||
for Game Boy Advance, so it won't change in the future either
|
||||
unless a higher hardware with backwards compatibility won't
|
||||
be introduced and this byte could hold some more infos about
|
||||
it. There's no reason to change this or write something
|
||||
different than 00h into it.
|
||||
|
||||
Offset b4h-b4h - Device type - This hexadecimal byte is the device type code.
|
||||
It is always 00h as the only other possible value stands for
|
||||
a debugger cart what I assume won't be available on the
|
||||
streets and I assume even if a developer works with such a
|
||||
hardware, he or she doesn't have to change this byte, however
|
||||
he or she easily can of course. So there's no reason to
|
||||
change this or write something different than 00h into it.
|
||||
|
||||
Offset b5h-bbh - Reserved area - Fixed, 00h filled area without any useful
|
||||
information.
|
||||
|
||||
Offset bch-bch - Mask ROM version number - This hexadecimal byte holds the
|
||||
version number of the ROM. As I know it works somehow that
|
||||
way, the first published (and released on the streets) is
|
||||
always the first version and for that 00h is stored here. In
|
||||
the case it is getting updated, so in the same territory the
|
||||
very same game with the very same title is getting replaced
|
||||
with a new version, what is happening rarely, the number here
|
||||
is getting increased by one. So usually this byte holds 00h
|
||||
and there isn't too much reason to write something here and
|
||||
something else than 00h.
|
||||
|
||||
Offset bdh-bdh - Complement check - This hexadecimal byte have to be
|
||||
calculated automatically, when the whole header is in its
|
||||
final state, so nothing will change inside of it. (Manually
|
||||
it would be hard to calculate.) Add the bytes between offset
|
||||
a0h and bch together, take the number's two's complement and
|
||||
add 19h to the result. Store the lowest 8 bits here. Or
|
||||
calculate automatically with GBARM. The hardware is
|
||||
verifying this byte just like the Nintendo logo character
|
||||
data and in the case it isn't correct, the game won't start
|
||||
on the real machine.
|
||||
|
||||
Offset beh-bfh - Reserved area - Fixed, 00h filled area without any useful
|
||||
information.
|
||||
*/
|
||||
typedef struct st_gba_header
|
||||
{
|
||||
unsigned char start[4]; // 0x00
|
||||
unsigned char logo[GBA_LOGODATA_LEN]; // 0x04
|
||||
unsigned char name[GBA_NAME_LEN]; // 0xa0
|
||||
unsigned char game_id_prefix; // 0xac
|
||||
unsigned char game_id_low; // 0xad
|
||||
unsigned char game_id_high; // 0xae
|
||||
unsigned char game_id_country; // 0xaf
|
||||
unsigned char maker_high; // 0xb0
|
||||
unsigned char maker_low; // 0xb1
|
||||
unsigned char pad1;
|
||||
unsigned char gba_type; // 0xb3
|
||||
unsigned char device_type; // 0xb4
|
||||
unsigned char pad2[7];
|
||||
unsigned char version; // 0xbc
|
||||
unsigned char checksum; // 0xbd
|
||||
unsigned char pad3[2];
|
||||
} st_gba_header_t;
|
||||
|
||||
static st_gba_header_t gba_header;
|
||||
const unsigned char gba_logodata[] = // Note: not a static variable
|
||||
{
|
||||
0x24, 0xff, 0xae, 0x51,
|
||||
0x69, 0x9a, 0xa2, 0x21, 0x3d, 0x84, 0x82, 0x0a,
|
||||
0x84, 0xe4, 0x09, 0xad, 0x11, 0x24, 0x8b, 0x98,
|
||||
0xc0, 0x81, 0x7f, 0x21, 0xa3, 0x52, 0xbe, 0x19,
|
||||
0x93, 0x09, 0xce, 0x20, 0x10, 0x46, 0x4a, 0x4a,
|
||||
0xf8, 0x27, 0x31, 0xec, 0x58, 0xc7, 0xe8, 0x33,
|
||||
0x82, 0xe3, 0xce, 0xbf, 0x85, 0xf4, 0xdf, 0x94,
|
||||
0xce, 0x4b, 0x09, 0xc1, 0x94, 0x56, 0x8a, 0xc0,
|
||||
0x13, 0x72, 0xa7, 0xfc, 0x9f, 0x84, 0x4d, 0x73,
|
||||
0xa3, 0xca, 0x9a, 0x61, 0x58, 0x97, 0xa3, 0x27,
|
||||
0xfc, 0x03, 0x98, 0x76, 0x23, 0x1d, 0xc7, 0x61,
|
||||
0x03, 0x04, 0xae, 0x56, 0xbf, 0x38, 0x84, 0x00,
|
||||
0x40, 0xa7, 0x0e, 0xfd, 0xff, 0x52, 0xfe, 0x03,
|
||||
0x6f, 0x95, 0x30, 0xf1, 0x97, 0xfb, 0xc0, 0x85,
|
||||
0x60, 0xd6, 0x80, 0x25, 0xa9, 0x63, 0xbe, 0x03,
|
||||
0x01, 0x4e, 0x38, 0xe2, 0xf9, 0xa2, 0x34, 0xff,
|
||||
0xbb, 0x3e, 0x03, 0x44, 0x78, 0x00, 0x90, 0xcb,
|
||||
0x88, 0x11, 0x3a, 0x94, 0x65, 0xc0, 0x7c, 0x63,
|
||||
0x87, 0xf0, 0x3c, 0xaf, 0xd6, 0x25, 0xe4, 0x8b,
|
||||
0x38, 0x0a, 0xac, 0x72, 0x21, 0xd4, 0xf8, 0x07
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
gba_n (st_rominfo_t *rominfo, const char *name)
|
||||
{
|
||||
char buf[GBA_NAME_LEN], dest_name[FILENAME_MAX];
|
||||
|
||||
memset (buf, 0, GBA_NAME_LEN);
|
||||
strncpy (buf, name, GBA_NAME_LEN);
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fwrite (buf, GBA_HEADER_START + rominfo->buheader_len + 0xa0, GBA_NAME_LEN,
|
||||
dest_name, "r+b");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gba_logo (st_rominfo_t *rominfo)
|
||||
{
|
||||
char dest_name[FILENAME_MAX];
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fwrite (gba_logodata, GBA_HEADER_START + rominfo->buheader_len + 0x04,
|
||||
GBA_LOGODATA_LEN, dest_name, "r+b");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gba_chk (st_rominfo_t *rominfo)
|
||||
{
|
||||
char buf, dest_name[FILENAME_MAX];
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
|
||||
buf = rominfo->current_internal_crc;
|
||||
ucon64_fputc (dest_name, GBA_HEADER_START + rominfo->buheader_len + 0xbd,
|
||||
buf, "r+b");
|
||||
|
||||
dumper (stdout, &buf, 1, GBA_HEADER_START + rominfo->buheader_len + 0xbd, DUMPER_HEX);
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gba_sram (void)
|
||||
// This function is based on Omar Kilani's gbautil 1.1
|
||||
{
|
||||
unsigned char st_orig[2][10] =
|
||||
{
|
||||
{ 0x0E, 0x48, 0x39, 0x68, 0x01, 0x60, 0x0E, 0x48, 0x79, 0x68 },
|
||||
{ 0x13, 0x4B, 0x18, 0x60, 0x13, 0x48, 0x01, 0x60, 0x13, 0x49 }
|
||||
},
|
||||
st_repl[2][10] =
|
||||
{
|
||||
{ 0x00, 0x48, 0x00, 0x47, 0x01, 0xFF, 0xFF, 0x08, 0x79, 0x68 },
|
||||
{ 0x01, 0x4C, 0x20, 0x47, 0x00, 0x00, 0x01, 0xFF, 0xFF, 0x08 }
|
||||
},
|
||||
fl_orig[2][24] =
|
||||
{
|
||||
{
|
||||
0xD0, 0x20, 0x00, 0x05, 0x01, 0x88, 0x01, 0x22, 0x08, 0x1C,
|
||||
0x10, 0x40, 0x02, 0x1C, 0x11, 0x04, 0x08, 0x0C, 0x00, 0x28,
|
||||
0x01, 0xD0, 0x1B, 0xE0
|
||||
},
|
||||
{
|
||||
0xD0, 0x21, 0x09, 0x05, 0x01, 0x23, 0x0C, 0x4A, 0x08, 0x88,
|
||||
0x18, 0x40, 0x00, 0x28, 0x08, 0xD1, 0x10, 0x78, 0x00, 0x28,
|
||||
0xF8, 0xD0, 0x08, 0x88
|
||||
}
|
||||
},
|
||||
fl_repl[2][24] =
|
||||
{
|
||||
{
|
||||
0xE0, 0x20, 0x00, 0x05, 0x01, 0x88, 0x01, 0x22, 0x08, 0x1C,
|
||||
0x10, 0x40, 0x02, 0x1C, 0x11, 0x04, 0x08, 0x0C, 0x00, 0x28,
|
||||
0x01, 0xD0, 0x1B, 0xE0
|
||||
},
|
||||
{
|
||||
0xE0, 0x21, 0x09, 0x05, 0x01, 0x23, 0x0C, 0x4A, 0x08, 0x88,
|
||||
0x18, 0x40, 0x00, 0x28, 0x08, 0xD1, 0x10, 0x78, 0x00, 0x28,
|
||||
0xF8, 0xD0, 0x08, 0x88
|
||||
}
|
||||
},
|
||||
p_repl[2][188] =
|
||||
{
|
||||
{
|
||||
0x39, 0x68, 0x27, 0x48, 0x81, 0x42, 0x23, 0xD0, 0x89, 0x1C,
|
||||
0x08, 0x88, 0x01, 0x28, 0x02, 0xD1, 0x24, 0x48, 0x78, 0x60,
|
||||
0x33, 0xE0, 0x00, 0x23, 0x00, 0x22, 0x89, 0x1C, 0x10, 0xB4,
|
||||
0x01, 0x24, 0x08, 0x68, 0x20, 0x40, 0x5B, 0x00, 0x03, 0x43,
|
||||
0x89, 0x1C, 0x52, 0x1C, 0x06, 0x2A, 0xF7, 0xD1, 0x10, 0xBC,
|
||||
0x39, 0x60, 0xDB, 0x01, 0x02, 0x20, 0x00, 0x02, 0x1B, 0x18,
|
||||
0x0E, 0x20, 0x00, 0x06, 0x1B, 0x18, 0x7B, 0x60, 0x39, 0x1C,
|
||||
0x08, 0x31, 0x08, 0x88, 0x09, 0x38, 0x08, 0x80, 0x16, 0xE0,
|
||||
0x15, 0x49, 0x00, 0x23, 0x00, 0x22, 0x10, 0xB4, 0x01, 0x24,
|
||||
0x08, 0x68, 0x20, 0x40, 0x5B, 0x00, 0x03, 0x43, 0x89, 0x1C,
|
||||
0x52, 0x1C, 0x06, 0x2A, 0xF7, 0xD1, 0x10, 0xBC, 0xDB, 0x01,
|
||||
0x02, 0x20, 0x00, 0x02, 0x1B, 0x18, 0x0E, 0x20, 0x00, 0x06,
|
||||
0x1B, 0x18, 0x08, 0x3B, 0x3B, 0x60, 0x0B, 0x48, 0x39, 0x68,
|
||||
0x01, 0x60, 0x0A, 0x48, 0x79, 0x68, 0x01, 0x60, 0x0A, 0x48,
|
||||
0x39, 0x1C, 0x08, 0x31, 0x0A, 0x88, 0x80, 0x21, 0x09, 0x06,
|
||||
0x0A, 0x43, 0x02, 0x60, 0x07, 0x48, 0x00, 0x47, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0E, 0x04, 0x00,
|
||||
0x00, 0x0E, 0xD4, 0x00, 0x00, 0x04, 0xD8, 0x00, 0x00, 0x04,
|
||||
0xDC, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0x08
|
||||
},
|
||||
{
|
||||
0x22, 0x4C, 0x84, 0x42, 0x20, 0xD0, 0x80, 0x1C, 0x04, 0x88,
|
||||
0x01, 0x25, 0x2C, 0x40, 0x01, 0x2C, 0x02, 0xD1, 0x80, 0x1E,
|
||||
0x1E, 0x49, 0x2E, 0xE0, 0x00, 0x23, 0x00, 0x24, 0x80, 0x1C,
|
||||
0x40, 0xB4, 0x01, 0x26, 0x05, 0x68, 0x35, 0x40, 0x5B, 0x00,
|
||||
0x2B, 0x43, 0x80, 0x1C, 0x64, 0x1C, 0x06, 0x2C, 0xF7, 0xD1,
|
||||
0x40, 0xBC, 0xDB, 0x01, 0x02, 0x24, 0x24, 0x02, 0x1B, 0x19,
|
||||
0x0E, 0x24, 0x24, 0x06, 0x1B, 0x19, 0x19, 0x1C, 0x09, 0x3A,
|
||||
0x16, 0xE0, 0x12, 0x48, 0x00, 0x23, 0x00, 0x24, 0x40, 0xB4,
|
||||
0x01, 0x26, 0x05, 0x68, 0x35, 0x40, 0x5B, 0x00, 0x2B, 0x43,
|
||||
0x80, 0x1C, 0x64, 0x1C, 0x06, 0x2C, 0xF7, 0xD1, 0x40, 0xBC,
|
||||
0xDB, 0x01, 0x02, 0x24, 0x24, 0x02, 0x1B, 0x19, 0x0E, 0x24,
|
||||
0x24, 0x06, 0x1B, 0x19, 0x08, 0x3B, 0x18, 0x1C, 0x08, 0x4C,
|
||||
0x20, 0x60, 0x08, 0x4C, 0x21, 0x60, 0x08, 0x49, 0x80, 0x20,
|
||||
0x00, 0x06, 0x02, 0x43, 0x0A, 0x60, 0x06, 0x4C, 0x20, 0x47,
|
||||
0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x0E, 0x04, 0x00,
|
||||
0x00, 0x0E, 0xD4, 0x00, 0x00, 0x04, 0xD8, 0x00, 0x00, 0x04,
|
||||
0xDC, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xFF, 0x08
|
||||
}
|
||||
},
|
||||
major, minor, micro, *buffer, *bufferptr, *ptr, value;
|
||||
char dest_name[FILENAME_MAX];
|
||||
int p_size[2] = { 188, 168 }, p_off, st_off;
|
||||
unsigned int fsize = ucon64.file_size;
|
||||
FILE *destfile;
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
|
||||
if ((destfile = fopen (dest_name, "rb+")) == NULL)
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], dest_name);
|
||||
return -1;
|
||||
}
|
||||
if (!(buffer = (unsigned char *) malloc (fsize)))
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], fsize);
|
||||
fclose (destfile);
|
||||
exit (1);
|
||||
}
|
||||
if (fread (buffer, 1, fsize, destfile) != fsize)
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[READ_ERROR], dest_name);
|
||||
free (buffer);
|
||||
fclose (destfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
bufferptr = buffer + 160 + 12 + 4;
|
||||
|
||||
ptr = (unsigned char *) memmem2 (bufferptr, fsize, "EEPROM_", 7, 0);
|
||||
if (ptr == 0)
|
||||
{
|
||||
printf ("This ROM does not appear to use EEPROM saving\n");
|
||||
free (buffer);
|
||||
fclose (destfile);
|
||||
return -1;
|
||||
}
|
||||
major = ptr[8] - '0';
|
||||
minor = ptr[9] - '0';
|
||||
micro = ptr[10] - '0';
|
||||
if (ucon64.quiet < 0)
|
||||
printf ("version: %d.%d.%d; offset: 0x%08x\n",
|
||||
major, minor, micro, (int) (ptr - buffer));
|
||||
if (minor > 2)
|
||||
{
|
||||
fputs ("ERROR: ROMs with an EEPROM minor version higher than 2 are not supported\n", stderr);
|
||||
free (buffer);
|
||||
fclose (destfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr = (unsigned char *) memmem2 (bufferptr, fsize,
|
||||
fl_orig[minor - 1], sizeof (fl_orig[minor - 1]), 0);
|
||||
if (ptr == 0)
|
||||
{
|
||||
fputs ("ERROR: Could not find fl pattern. Perhaps this file is already patched?\n", stderr);
|
||||
free (buffer);
|
||||
fclose (destfile);
|
||||
return -1;
|
||||
}
|
||||
if (ucon64.quiet < 0)
|
||||
printf ("fl offset: 0x%08x\n", (int) (ptr - buffer));
|
||||
fseek (destfile, ptr - buffer, SEEK_SET);
|
||||
fwrite (fl_repl[minor - 1], 1, sizeof (fl_repl[minor - 1]), destfile);
|
||||
|
||||
ptr = buffer + fsize - 1;
|
||||
value = *ptr;
|
||||
do
|
||||
ptr--;
|
||||
while (*ptr == value && ptr - buffer > 0);
|
||||
|
||||
p_off = (ptr - buffer + 0xff) & ~0xff; // align at 256 byte boundary
|
||||
if (ucon64.quiet < 0)
|
||||
printf ("p_off: 0x%08x\n", p_off);
|
||||
// if the SRAM function won't fit at the end of the ROM, abort
|
||||
if ((minor == 1 && (int) (fsize - 188) < p_off) ||
|
||||
(minor == 2 && (int) (fsize - 168) < p_off))
|
||||
{
|
||||
fputs ("ERROR: Not enough room for SRAM function at end of ROM\n", stderr);
|
||||
free (buffer);
|
||||
fclose (destfile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ptr = (unsigned char *) memmem2 (bufferptr, fsize,
|
||||
st_orig[minor - 1], sizeof (st_orig[minor - 1]), 0);
|
||||
if (ptr == 0)
|
||||
{
|
||||
fputs ("ERROR: Could not find st pattern\n", stderr);
|
||||
free (buffer);
|
||||
fclose (destfile);
|
||||
return -1;
|
||||
}
|
||||
st_off = ptr - buffer;
|
||||
if (ucon64.quiet < 0)
|
||||
printf ("st offset: 0x%08x\n", st_off);
|
||||
|
||||
bufferptr = buffer + p_off;
|
||||
switch (minor)
|
||||
{
|
||||
case 1:
|
||||
// these are the offsets to the caller function, it handles all saving and
|
||||
// is at st_off
|
||||
p_repl[minor - 1][184] = (unsigned char) (st_off + 0x21);
|
||||
p_repl[minor - 1][186] = (unsigned char) (st_off >> 16);
|
||||
|
||||
if (*(bufferptr - 1) == 0xff)
|
||||
p_repl[minor - 1][185] = (unsigned char) (st_off >> 8);
|
||||
else
|
||||
{
|
||||
st_off += 0x1f;
|
||||
p_repl[minor - 1][185] = (unsigned char) (st_off >> 8);
|
||||
}
|
||||
|
||||
// tell the calling function where the SRAM function is (p_off)
|
||||
st_repl[minor - 1][5] = (unsigned char) (p_off >> 8);
|
||||
st_repl[minor - 1][6] = (unsigned char) (p_off >> 16);
|
||||
break;
|
||||
case 2:
|
||||
// offsets to the caller function
|
||||
p_repl[minor - 1][164] = (unsigned char) (st_off + 0x13);
|
||||
p_repl[minor - 1][165] = (unsigned char) (st_off >> 8);
|
||||
p_repl[minor - 1][166] = (unsigned char) (st_off >> 16);
|
||||
|
||||
// tell the calling function where the SRAM function is
|
||||
st_repl[minor - 1][7] = (unsigned char) (p_off >> 8);
|
||||
st_repl[minor - 1][8] = (unsigned char) (p_off >> 16);
|
||||
break;
|
||||
}
|
||||
fseek (destfile, st_off, SEEK_SET);
|
||||
fwrite (st_repl[minor - 1], 1, sizeof (st_repl[minor - 1]), destfile);
|
||||
fseek (destfile, p_off, SEEK_SET);
|
||||
fwrite (p_repl[minor - 1], 1, p_size[minor - 1], destfile);
|
||||
|
||||
free (buffer);
|
||||
fclose (destfile);
|
||||
|
||||
puts ("SRAM patch applied");
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gba_crp (st_rominfo_t *rominfo, const char *value)
|
||||
{
|
||||
FILE *srcfile, *destfile;
|
||||
int bytesread, n = 0;
|
||||
char buffer[32 * 1024], src_name[FILENAME_MAX], dest_name[FILENAME_MAX],
|
||||
replace[2], wait_time = atoi (value);
|
||||
|
||||
if (wait_time % 4 != 0 || wait_time > 28 || wait_time < 0)
|
||||
{
|
||||
fprintf (stderr, "ERROR: You specified an incorrect WAIT_TIME value\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
puts ("Applying crash patch...");
|
||||
|
||||
strcpy (src_name, ucon64.rom);
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, src_name, 0);
|
||||
if ((srcfile = fopen (src_name, "rb")) == NULL)
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], src_name);
|
||||
return -1;
|
||||
}
|
||||
if ((destfile = fopen (dest_name, "wb")) == NULL)
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], dest_name);
|
||||
return -1;
|
||||
}
|
||||
if (rominfo->buheader_len) // copy header (if present)
|
||||
{
|
||||
fread (buffer, 1, rominfo->buheader_len, srcfile);
|
||||
fwrite (buffer, 1, rominfo->buheader_len, destfile);
|
||||
}
|
||||
|
||||
replace[0] = wait_time;
|
||||
replace[1] = 0x40;
|
||||
while ((bytesread = fread (buffer, 1, 32 * 1024, srcfile)))
|
||||
{ // '!' == ASCII 33 (\x21), '*' == 42 (\x2a)
|
||||
n += change_mem (buffer, bytesread, "\x04\x02\x00\x04\x14\x40", 6, '*', '!', replace, 1, -1);
|
||||
n += change_mem (buffer, bytesread, "\x02\x00\x04\x14\x40\x00", 6, '*', '!', replace, 1, -2);
|
||||
n += change_mem (buffer, bytesread, "\x04\x02\x00\x04\xB4\x45", 6, '*', '!', replace, 2, -1);
|
||||
n += change_mem (buffer, bytesread, "\x3E\xE0\x00\x00\xB4\x45", 6, '*', '!', replace, 2, -1);
|
||||
n += change_mem (buffer, bytesread, "\x04\x02\x00\x04\x94\x44", 6, '*', '!', replace, 2, -1);
|
||||
|
||||
fwrite (buffer, 1, bytesread, destfile);
|
||||
}
|
||||
fclose (srcfile);
|
||||
fclose (destfile);
|
||||
|
||||
printf ("Found %d pattern%s\n", n, n != 1 ? "s" : "");
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
remove_temp_file ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gba_init (st_rominfo_t *rominfo)
|
||||
{
|
||||
int result = -1, value;
|
||||
char buf[MAXBUFSIZE];
|
||||
|
||||
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ?
|
||||
ucon64.buheader_len : 0;
|
||||
|
||||
ucon64_fread (&gba_header, GBA_HEADER_START +
|
||||
rominfo->buheader_len, GBA_HEADER_LEN, ucon64.rom);
|
||||
if (/*gba_header.game_id_prefix == 'A' && */ // 'B' in Mario vs. Donkey Kong
|
||||
gba_header.start[3] == 0xea && gba_header.pad1 == 0x96 && gba_header.gba_type == 0)
|
||||
result = 0;
|
||||
else
|
||||
{
|
||||
#if 0 // AFAIK (dbjh) GBA ROMs never have a header
|
||||
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ?
|
||||
ucon64.buheader_len : UNKNOWN_HEADER_LEN;
|
||||
|
||||
ucon64_fread (&gba_header, GBA_HEADER_START +
|
||||
rominfo->buheader_len, GBA_HEADER_LEN, ucon64.rom);
|
||||
if (gba_header.game_id_prefix == 'A' && gba_header.gba_type == 0)
|
||||
result = 0;
|
||||
else
|
||||
#endif
|
||||
result = -1;
|
||||
}
|
||||
if (ucon64.console == UCON64_GBA)
|
||||
result = 0;
|
||||
|
||||
rominfo->header_start = GBA_HEADER_START;
|
||||
rominfo->header_len = GBA_HEADER_LEN;
|
||||
rominfo->header = &gba_header;
|
||||
|
||||
// internal ROM name
|
||||
strncpy (rominfo->name, (const char *) gba_header.name, GBA_NAME_LEN);
|
||||
rominfo->name[GBA_NAME_LEN] = 0;
|
||||
|
||||
// ROM maker
|
||||
{
|
||||
int ih = gba_header.maker_high <= '9' ?
|
||||
gba_header.maker_high - '0' : gba_header.maker_high - 'A' + 10,
|
||||
il = gba_header.maker_low <= '9' ?
|
||||
gba_header.maker_low - '0' : gba_header.maker_low - 'A' + 10;
|
||||
value = ih * 36 + il;
|
||||
}
|
||||
if (value < 0 || value >= NINTENDO_MAKER_LEN)
|
||||
value = 0;
|
||||
rominfo->maker = NULL_TO_UNKNOWN_S (nintendo_maker[value]);
|
||||
|
||||
// ROM country
|
||||
rominfo->country =
|
||||
(gba_header.game_id_country == 'J') ? "Japan/Asia" :
|
||||
(gba_header.game_id_country == 'E') ? "U.S.A." :
|
||||
(gba_header.game_id_country == 'P') ? "Europe, Australia and Africa" :
|
||||
"Unknown country";
|
||||
|
||||
// misc stuff
|
||||
sprintf (buf, "Version: %d\n", gba_header.version);
|
||||
strcat (rominfo->misc, buf);
|
||||
|
||||
sprintf (buf, "Device type: 0x%02x\n", gba_header.device_type);
|
||||
strcat (rominfo->misc, buf);
|
||||
|
||||
/*
|
||||
start address = current address + (parameter of B instruction * 4) + 8
|
||||
gba_header.start[3] is opcode of B instruction (0xea)
|
||||
*/
|
||||
value = 0x8000008 +
|
||||
(gba_header.start[2] << 18 | gba_header.start[1] << 10 | gba_header.start[0] << 2);
|
||||
sprintf (buf, "Start address: 0x%08x\n", value);
|
||||
strcat (rominfo->misc, buf);
|
||||
|
||||
strcat (rominfo->misc, "Logo data: ");
|
||||
if (memcmp (gba_header.logo, gba_logodata, GBA_LOGODATA_LEN) == 0)
|
||||
{
|
||||
#ifdef USE_ANSI_COLOR
|
||||
if (ucon64.ansi_color)
|
||||
strcat (rominfo->misc, "\x1b[01;32mOk\x1b[0m");
|
||||
else
|
||||
#endif
|
||||
strcat (rominfo->misc, "Ok");
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef USE_ANSI_COLOR
|
||||
if (ucon64.ansi_color)
|
||||
strcat (rominfo->misc, "\x1b[01;31mBad\x1b[0m");
|
||||
else
|
||||
#endif
|
||||
strcat (rominfo->misc, "Bad");
|
||||
}
|
||||
|
||||
// internal ROM crc
|
||||
if (!UCON64_ISSET (ucon64.do_not_calc_crc) && result == 0)
|
||||
{
|
||||
rominfo->has_internal_crc = 1;
|
||||
rominfo->internal_crc_len = 1;
|
||||
rominfo->current_internal_crc = gba_chksum ();
|
||||
|
||||
rominfo->internal_crc = gba_header.checksum;
|
||||
rominfo->internal_crc2[0] = 0;
|
||||
}
|
||||
|
||||
rominfo->console_usage = gba_usage[0].help;
|
||||
// We use fal_usage, but we could just as well use f2a_usage
|
||||
rominfo->copier_usage = (!rominfo->buheader_len ? fal_usage[0].help : unknown_usage[0].help);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gba_chksum (void)
|
||||
// Note that this function only calculates the checksum of the internal header
|
||||
{
|
||||
unsigned char sum = 0x19, *ptr = (unsigned char *) &gba_header + 0xa0;
|
||||
|
||||
while (ptr < (unsigned char *) &gba_header + 0xbd)
|
||||
sum += *ptr++;
|
||||
sum = -sum;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
gba_multi (int truncate_size, char *multi_fname)
|
||||
// TODO: Check if 1024 Mbit multi-game files are supported by the FAL code
|
||||
{
|
||||
#define BUFSIZE (32 * 1024)
|
||||
int n, n_files, file_no, bytestowrite, byteswritten, totalsize = 0, done,
|
||||
truncated = 0, size_pow2_lesser = 1, size_pow2 = 1, truncate_size_ispow2 = 0;
|
||||
struct stat fstate;
|
||||
FILE *srcfile, *destfile;
|
||||
char buffer[BUFSIZE], fname[FILENAME_MAX], *fname_ptr;
|
||||
|
||||
if (truncate_size == 0)
|
||||
{
|
||||
fprintf (stderr, "ERROR: Can't make multi-game file of 0 bytes\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (truncate_size != 64 * MBIT && truncate_size != 128 * MBIT &&
|
||||
truncate_size != 256 * MBIT && truncate_size != 512 * MBIT &&
|
||||
truncate_size != 1024 * MBIT)
|
||||
{
|
||||
fprintf (stderr, "ERROR: Truncate size must be 64, 128, 256, 512 or 1024\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (multi_fname != NULL) // -xfalmulti
|
||||
{
|
||||
strcpy (fname, multi_fname);
|
||||
n_files = ucon64.argc;
|
||||
}
|
||||
else // -multi
|
||||
{
|
||||
strcpy (fname, ucon64.argv[ucon64.argc - 1]);
|
||||
n_files = ucon64.argc - 1;
|
||||
}
|
||||
|
||||
ucon64_file_handler (fname, NULL, OF_FORCE_BASENAME);
|
||||
if ((destfile = fopen (fname, "wb")) == NULL)
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], fname);
|
||||
return -1;
|
||||
}
|
||||
printf ("Creating multi-game file for FAL(/F2A): %s\n", fname);
|
||||
|
||||
file_no = 0;
|
||||
for (n = 1; n < n_files; n++)
|
||||
{
|
||||
if (access (ucon64.argv[n], F_OK))
|
||||
continue; // "file" does not exist (option)
|
||||
stat (ucon64.argv[n], &fstate);
|
||||
if (!S_ISREG (fstate.st_mode))
|
||||
continue;
|
||||
|
||||
if (file_no == 0)
|
||||
{
|
||||
if (multi_fname != NULL) // -xfalmulti
|
||||
{
|
||||
get_property_fname (ucon64.configfile, "gbaloader", fname, "loader.bin");
|
||||
if (access (fname, F_OK))
|
||||
{
|
||||
fprintf (stderr, "ERROR: Cannot open loader binary (%s)\n", fname);
|
||||
return -1;
|
||||
}
|
||||
fname_ptr = fname;
|
||||
// NOTE: loop counter is modified, because we have to insert
|
||||
// loader in the file list
|
||||
n--;
|
||||
}
|
||||
else // -multi
|
||||
fname_ptr = ucon64.argv[n];
|
||||
|
||||
printf ("Loader: %s\n", fname_ptr);
|
||||
if (fsizeof (fname_ptr) > 64 * 1024)
|
||||
printf ("WARNING: Are you sure %s is a loader binary?\n", fname_ptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
fname_ptr = ucon64.argv[n];
|
||||
printf ("ROM%d: %s\n", file_no, fname_ptr);
|
||||
}
|
||||
|
||||
if ((srcfile = fopen (fname_ptr, "rb")) == NULL)
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], fname_ptr);
|
||||
continue;
|
||||
}
|
||||
done = 0;
|
||||
byteswritten = 0; // # of bytes written per file
|
||||
while (!done)
|
||||
{
|
||||
bytestowrite = fread (buffer, 1, BUFSIZE, srcfile);
|
||||
if (totalsize + bytestowrite > truncate_size)
|
||||
{
|
||||
bytestowrite = truncate_size - totalsize;
|
||||
done = 1;
|
||||
truncated = 1;
|
||||
printf ("Output file is %d Mbit, truncating %s, skipping %d bytes\n",
|
||||
truncate_size / MBIT, fname_ptr,
|
||||
fsizeof (fname_ptr) - (byteswritten + bytestowrite));
|
||||
// DON'T use fstate.st_size, because file could be compressed
|
||||
}
|
||||
totalsize += bytestowrite;
|
||||
if (bytestowrite == 0)
|
||||
done = 1;
|
||||
fwrite (buffer, 1, bytestowrite, destfile);
|
||||
byteswritten += bytestowrite;
|
||||
}
|
||||
fclose (srcfile);
|
||||
if (truncated)
|
||||
break;
|
||||
file_no++;
|
||||
}
|
||||
fclose (destfile);
|
||||
|
||||
/*
|
||||
Display a notification if a truncate size was specified that is not exactly
|
||||
the size of one of the flash card sizes.
|
||||
*/
|
||||
n = truncate_size;
|
||||
while (n >>= 1)
|
||||
size_pow2 <<= 1;
|
||||
if (truncate_size == size_pow2)
|
||||
truncate_size_ispow2 = 1;
|
||||
|
||||
n = totalsize - 1;
|
||||
while (n >>= 1)
|
||||
size_pow2_lesser <<= 1;
|
||||
|
||||
size_pow2 = size_pow2_lesser << 1;
|
||||
|
||||
if (totalsize > 64 * MBIT && !truncate_size_ispow2)
|
||||
printf("\n"
|
||||
"NOTE: This multi-game file can only be written to a card >= %d Mbit.\n"
|
||||
" Use -multi=%d to create a file truncated to %d Mbit.\n"
|
||||
" Current size is %.5f Mbit\n", // 5 digits to have 1 byte resolution
|
||||
size_pow2 / MBIT, size_pow2_lesser / MBIT, size_pow2_lesser / MBIT,
|
||||
totalsize / (float) MBIT);
|
||||
|
||||
return 0;
|
||||
}
|
||||
37
tools/ucon64/src/console/gba.h
Normal file
37
tools/ucon64/src/console/gba.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
gba.h - Game Boy Advance support for uCON64
|
||||
|
||||
Copyright (c) 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef GBA_H
|
||||
#define GBA_H
|
||||
|
||||
#define GBA_LOGODATA_LEN 156
|
||||
|
||||
extern const st_getopt2_t gba_usage[];
|
||||
extern const unsigned char gba_logodata[];
|
||||
|
||||
extern int gba_chk (st_rominfo_t *rominfo);
|
||||
extern int gba_crp (st_rominfo_t *rominfo, const char *value);
|
||||
extern int gba_init (st_rominfo_t *rominfo);
|
||||
extern int gba_logo (st_rominfo_t *rominfo);
|
||||
extern int gba_n (st_rominfo_t *rominfo, const char *name);
|
||||
extern int gba_sram (void);
|
||||
extern int gba_multi (int truncate_size, char *fname);
|
||||
|
||||
#endif
|
||||
1728
tools/ucon64/src/console/genesis.c
Normal file
1728
tools/ucon64/src/console/genesis.c
Normal file
File diff suppressed because it is too large
Load Diff
43
tools/ucon64/src/console/genesis.h
Normal file
43
tools/ucon64/src/console/genesis.h
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
genesis.h - Sega Genesis/Mega Drive support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
Copyright (c) 2002 - 2003 dbjh
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef GENESIS_H
|
||||
#define GENESIS_H
|
||||
|
||||
typedef enum { SMD = 1, BIN, MGD_GEN } genesis_file_t;
|
||||
|
||||
extern const st_getopt2_t genesis_usage[];
|
||||
|
||||
extern genesis_file_t genesis_get_file_type (void);
|
||||
extern int genesis_1991 (st_rominfo_t *rominfo);
|
||||
extern int genesis_chk (st_rominfo_t *rominfo);
|
||||
extern int genesis_j (st_rominfo_t *rominfo);
|
||||
extern int genesis_n (st_rominfo_t *rominfo, const char *name);
|
||||
extern int genesis_n2 (st_rominfo_t *rominfo, const char *name);
|
||||
extern int genesis_s (st_rominfo_t *rominfo);
|
||||
extern int genesis_smd (st_rominfo_t *rominfo);
|
||||
extern int genesis_smds (void);
|
||||
extern int genesis_bin (st_rominfo_t *rominfo);
|
||||
extern int genesis_mgd (st_rominfo_t *rominfo);
|
||||
extern int genesis_multi (int truncate_size, char *fname);
|
||||
extern int genesis_init (st_rominfo_t *rominfo);
|
||||
extern int genesis_f (st_rominfo_t *rominfo);
|
||||
#endif
|
||||
109
tools/ucon64/src/console/jaguar.c
Normal file
109
tools/ucon64/src/console/jaguar.c
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
jaguar.c - Atari Jaguar support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include "misc/misc.h"
|
||||
#include "misc/file.h"
|
||||
#ifdef USE_ZLIB
|
||||
#include "misc/archive.h"
|
||||
#endif
|
||||
#include "misc/getopt2.h" // st_getopt2_t
|
||||
#include "ucon64.h"
|
||||
#include "ucon64_misc.h"
|
||||
#include "jaguar.h"
|
||||
|
||||
|
||||
const st_getopt2_t jaguar_usage[] =
|
||||
{
|
||||
{
|
||||
NULL, 0, 0, 0,
|
||||
NULL, "Panther(32bit prototype)/Jaguar64/Jaguar64 CD"/*"1989 Flare2/1993 Atari/1995 Atari"*/,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"jag", 0, 0, UCON64_JAG,
|
||||
NULL, "force recognition",
|
||||
&ucon64_wf[WF_OBJ_JAG_SWITCH]
|
||||
},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
typedef struct st_jaguar
|
||||
{
|
||||
char pad[16];
|
||||
} st_jaguar_t;
|
||||
#define JAGUAR_HEADER_START 0x400
|
||||
#define JAGUAR_HEADER_LEN (sizeof (st_jaguar_t))
|
||||
|
||||
st_jaguar_t jaguar_header;
|
||||
|
||||
|
||||
int
|
||||
jaguar_init (st_rominfo_t *rominfo)
|
||||
{
|
||||
int result = -1, x, value;
|
||||
|
||||
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ?
|
||||
ucon64.buheader_len : 0;
|
||||
|
||||
ucon64_fread (&jaguar_header, JAGUAR_HEADER_START +
|
||||
rominfo->buheader_len, JAGUAR_HEADER_LEN, ucon64.rom);
|
||||
value = 0;
|
||||
for (x = 0; x < 12; x++)
|
||||
value += OFFSET (jaguar_header, x);
|
||||
if (value == 0xb0)
|
||||
result = 0;
|
||||
else
|
||||
{
|
||||
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ?
|
||||
ucon64.buheader_len : (int) UNKNOWN_HEADER_LEN;
|
||||
|
||||
ucon64_fread (&jaguar_header, JAGUAR_HEADER_START +
|
||||
rominfo->buheader_len, JAGUAR_HEADER_LEN, ucon64.rom);
|
||||
value = 0;
|
||||
for (x = 0; x < 12; x++)
|
||||
value += OFFSET (jaguar_header, x);
|
||||
|
||||
if (value == 0xb0)
|
||||
result = 0;
|
||||
else
|
||||
result = -1;
|
||||
}
|
||||
if (ucon64.console == UCON64_JAG)
|
||||
result = 0;
|
||||
|
||||
rominfo->header_start = JAGUAR_HEADER_START;
|
||||
rominfo->header_len = JAGUAR_HEADER_LEN;
|
||||
rominfo->header = &jaguar_header;
|
||||
|
||||
rominfo->console_usage = jaguar_usage[0].help;
|
||||
rominfo->copier_usage = unknown_usage[0].help;
|
||||
|
||||
return result;
|
||||
}
|
||||
27
tools/ucon64/src/console/jaguar.h
Normal file
27
tools/ucon64/src/console/jaguar.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
jaguar.h - Atari Jaguar support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef JAGUAR_H
|
||||
#define JAGUAR_H
|
||||
|
||||
extern const st_getopt2_t jaguar_usage[];
|
||||
extern int jaguar_init (st_rominfo_t *rominfo);
|
||||
|
||||
#endif
|
||||
357
tools/ucon64/src/console/lynx.c
Normal file
357
tools/ucon64/src/console/lynx.c
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
lynx.c - Atari Lynx support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
Copyright (c) 2002 - 2003 dbjh
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "misc/bswap.h"
|
||||
#include "misc/file.h"
|
||||
#include "misc/misc.h"
|
||||
#ifdef USE_ZLIB
|
||||
#include "misc/archive.h"
|
||||
#endif
|
||||
#include "misc/getopt2.h" // st_getopt2_t
|
||||
#include "ucon64.h"
|
||||
#include "ucon64_misc.h"
|
||||
#include "lynx.h"
|
||||
|
||||
|
||||
const st_getopt2_t lynx_usage[] =
|
||||
{
|
||||
{
|
||||
NULL, 0, 0, 0,
|
||||
NULL, "Handy (prototype)/Lynx/Lynx II"/*"1987 Epyx/1989 Atari/1991 Atari"*/,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"lynx", 0, 0, UCON64_LYNX,
|
||||
NULL, "force recognition",
|
||||
&ucon64_wf[WF_OBJ_LYNX_SWITCH]
|
||||
},
|
||||
{
|
||||
"lyx", 0, 0, UCON64_LYX,
|
||||
NULL, "convert to LYX/RAW (strip 64 Bytes LNX header)",
|
||||
&ucon64_wf[WF_OBJ_LYNX_DEFAULT]
|
||||
},
|
||||
{
|
||||
"lnx", 0, 0, UCON64_LNX,
|
||||
NULL, "convert to LNX (uses default values for the header);\n"
|
||||
"adjust the LNX header with the following options",
|
||||
&ucon64_wf[WF_OBJ_LYNX_DEFAULT]
|
||||
},
|
||||
{
|
||||
"n", 1, 0, UCON64_N,
|
||||
"NEW_NAME", "change internal ROM name to NEW_NAME (LNX only)",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
|
||||
},
|
||||
{
|
||||
"nrot", 0, 0, UCON64_NROT,
|
||||
NULL, "set no rotation (LNX only)",
|
||||
&ucon64_wf[WF_OBJ_LYNX_DEFAULT]
|
||||
},
|
||||
{
|
||||
"rotl", 0, 0, UCON64_ROTL,
|
||||
NULL, "set rotation left (LNX only)",
|
||||
&ucon64_wf[WF_OBJ_LYNX_DEFAULT]
|
||||
},
|
||||
{
|
||||
"rotr", 0, 0, UCON64_ROTR,
|
||||
NULL, "set rotation right (LNX only)",
|
||||
&ucon64_wf[WF_OBJ_LYNX_DEFAULT]
|
||||
},
|
||||
{
|
||||
"b0", 1, 0, UCON64_B0,
|
||||
"N", "change Bank0 kBytes size to N={0,64,128,256,512} (LNX only)",
|
||||
&ucon64_wf[WF_OBJ_LYNX_DEFAULT]
|
||||
},
|
||||
{
|
||||
"b1", 1, 0, UCON64_B1,
|
||||
"N", "change Bank1 kBytes size to N={0,64,128,256,512} (LNX only)",
|
||||
&ucon64_wf[WF_OBJ_LYNX_DEFAULT]
|
||||
},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
const char *lynx_lyx_desc = "convert to LYX/RAW (strip 64 Bytes LNX header)";
|
||||
|
||||
//static const char *lnx_usage[] = "LNX header";
|
||||
#define LNX_HEADER_START 0
|
||||
#define LNX_HEADER_LEN (sizeof (st_lnx_header_t))
|
||||
|
||||
st_lnx_header_t lnx_header;
|
||||
|
||||
|
||||
int
|
||||
lynx_lyx (st_rominfo_t *rominfo)
|
||||
{
|
||||
char dest_name[FILENAME_MAX];
|
||||
|
||||
if (!rominfo->buheader_len)
|
||||
{
|
||||
fprintf (stderr, "ERROR: This is no LNX file\n\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
set_suffix (dest_name, ".lyx");
|
||||
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, rominfo->buheader_len, ucon64.file_size, dest_name, "wb");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lynx_lnx (st_rominfo_t *rominfo)
|
||||
{
|
||||
st_lnx_header_t header;
|
||||
char dest_name[FILENAME_MAX];
|
||||
int size = ucon64.file_size;
|
||||
|
||||
if (rominfo->buheader_len != 0)
|
||||
{
|
||||
fprintf (stderr, "ERROR: This seems to already be an LNX file\n\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
header.page_size_bank0 = size > 4 * MBIT ? 4 * MBIT / 256 : size / 256;
|
||||
header.page_size_bank1 = size > 4 * MBIT ? (size - (4 * MBIT)) / 256 : 0;
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
header.page_size_bank0 = bswap_16 (header.page_size_bank0);
|
||||
header.page_size_bank1 = bswap_16 (header.page_size_bank1);
|
||||
#endif
|
||||
|
||||
memset (header.cartname, 0, sizeof (header.cartname));
|
||||
memset (header.manufname, 0, sizeof (header.manufname));
|
||||
memset (header.spare, 0, sizeof (header.spare));
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
header.version = bswap_16 (1);
|
||||
#else
|
||||
header.version = 1;
|
||||
#endif
|
||||
|
||||
memcpy (header.magic, "LYNX", 4);
|
||||
header.rotation = 0;
|
||||
strncpy (header.cartname, ucon64.rom, sizeof (header.cartname));
|
||||
strcpy (header.manufname, "Atari");
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
set_suffix (dest_name, ".lnx");
|
||||
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
ucon64_fwrite (&header, 0, sizeof (st_lnx_header_t), dest_name, "wb");
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "ab");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
lynx_rot (st_rominfo_t *rominfo, int rotation)
|
||||
{
|
||||
st_lnx_header_t header;
|
||||
char dest_name[FILENAME_MAX];
|
||||
|
||||
if (!rominfo->buheader_len)
|
||||
{
|
||||
fprintf (stderr, "ERROR: This is no LNX file\n\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ucon64_fread (&header, 0, sizeof (st_lnx_header_t), ucon64.rom);
|
||||
|
||||
header.rotation = rotation; // header.rotation is an 8-bit field
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fwrite (&header, 0, sizeof (st_lnx_header_t), dest_name, "r+b");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lynx_nrot (st_rominfo_t *rominfo)
|
||||
{
|
||||
return lynx_rot (rominfo, 0); // no rotation
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lynx_rotl (st_rominfo_t *rominfo)
|
||||
{
|
||||
return lynx_rot (rominfo, 1); // rotate left
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lynx_rotr (st_rominfo_t *rominfo)
|
||||
{
|
||||
return lynx_rot (rominfo, 2); // rotate right
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lynx_n (st_rominfo_t *rominfo, const char *name)
|
||||
{
|
||||
st_lnx_header_t header;
|
||||
char dest_name[FILENAME_MAX];
|
||||
|
||||
if (!rominfo->buheader_len)
|
||||
{
|
||||
fprintf (stderr, "ERROR: This is no LNX file\n\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ucon64_fread (&header, 0, sizeof (st_lnx_header_t), ucon64.rom);
|
||||
|
||||
memset (header.cartname, 0, sizeof (header.cartname));
|
||||
strncpy (header.cartname, name, sizeof (header.cartname));
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fwrite (&header, 0, sizeof (st_lnx_header_t), dest_name, "r+b");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
lynx_b (st_rominfo_t *rominfo, int bank, const char *value)
|
||||
{
|
||||
st_lnx_header_t header;
|
||||
short int *bankvar;
|
||||
char dest_name[FILENAME_MAX];
|
||||
|
||||
if (!rominfo->buheader_len)
|
||||
{
|
||||
fprintf (stderr, "ERROR: This is no LNX file\n\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ucon64_fread (&header, 0, sizeof (st_lnx_header_t), ucon64.rom);
|
||||
|
||||
bankvar = (bank == 0 ? &header.page_size_bank0 : &header.page_size_bank1);
|
||||
if ((atol (value) % 64) != 0 || (atol (value) > 512))
|
||||
*bankvar = 0;
|
||||
else
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
*bankvar = bswap_16 (atol (value) * 4);
|
||||
#else
|
||||
*bankvar = atol (value) * 4;
|
||||
#endif
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fwrite (&header, 0, sizeof (st_lnx_header_t), dest_name, "r+b");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lynx_b0 (st_rominfo_t *rominfo, const char *value)
|
||||
{
|
||||
return lynx_b (rominfo, 0, value);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lynx_b1 (st_rominfo_t *rominfo, const char *value)
|
||||
{
|
||||
return lynx_b (rominfo, 1, value);
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
lynx_init (st_rominfo_t *rominfo)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
rominfo->console_usage = lynx_usage[0].help;
|
||||
rominfo->copier_usage = unknown_usage[0].help;
|
||||
|
||||
ucon64_fread (&lnx_header, 0, LNX_HEADER_LEN, ucon64.rom);
|
||||
if (!strncmp (lnx_header.magic, "LYNX", 4))
|
||||
result = 0;
|
||||
else
|
||||
result = -1;
|
||||
if (ucon64.console == UCON64_LYNX)
|
||||
result = 0;
|
||||
|
||||
if (!strncmp (lnx_header.magic, "LYNX", 4))
|
||||
{
|
||||
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ?
|
||||
ucon64.buheader_len : (int) LNX_HEADER_LEN;
|
||||
|
||||
if (UCON64_ISSET (ucon64.buheader_len) && !ucon64.buheader_len)
|
||||
return ucon64.console == UCON64_LYNX ? 0 : result;
|
||||
|
||||
ucon64_fread (&lnx_header, 0, LNX_HEADER_LEN, ucon64.rom);
|
||||
rominfo->buheader = &lnx_header;
|
||||
|
||||
// internal ROM name
|
||||
strcpy (rominfo->name, lnx_header.cartname);
|
||||
|
||||
// ROM maker
|
||||
rominfo->maker = lnx_header.manufname;
|
||||
|
||||
// misc stuff
|
||||
sprintf (rominfo->misc,
|
||||
"Internal Size: Bank0 %hd Bytes (%.4f Mb)\n"
|
||||
" Bank1 %hd Bytes (%.4f Mb)\n"
|
||||
"Version: %hd\n"
|
||||
"Rotation: %s",
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
bswap_16 (lnx_header.page_size_bank0) * 256,
|
||||
TOMBIT_F (bswap_16 (lnx_header.page_size_bank0) * 256),
|
||||
bswap_16 (lnx_header.page_size_bank1) * 256,
|
||||
TOMBIT_F (bswap_16 (lnx_header.page_size_bank1) * 256),
|
||||
bswap_16 (lnx_header.version),
|
||||
#else
|
||||
lnx_header.page_size_bank0 * 256,
|
||||
TOMBIT_F (lnx_header.page_size_bank0 * 256),
|
||||
lnx_header.page_size_bank1 * 256,
|
||||
TOMBIT_F (lnx_header.page_size_bank1 * 256),
|
||||
lnx_header.version,
|
||||
#endif
|
||||
(!lnx_header.rotation) ? "No" : ((lnx_header.rotation == 1) ? "Left" : "Right"));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
54
tools/ucon64/src/console/lynx.h
Normal file
54
tools/ucon64/src/console/lynx.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
lynx.h - Atari Lynx support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef LYNX_H
|
||||
#define LYNX_H
|
||||
typedef struct st_lnx_header
|
||||
{
|
||||
char magic[4];
|
||||
short int page_size_bank0;
|
||||
short int page_size_bank1;
|
||||
short int version;
|
||||
char cartname[32];
|
||||
char manufname[16];
|
||||
unsigned char rotation;
|
||||
unsigned char spare[5];
|
||||
} st_lnx_header_t;
|
||||
|
||||
|
||||
extern int lynxer_main(const char *FileName);
|
||||
|
||||
extern int lynx_b0 (st_rominfo_t *rominfo, const char *value);
|
||||
extern int lynx_b1 (st_rominfo_t *rominfo, const char *value);
|
||||
|
||||
extern int lynx_lnx (st_rominfo_t *rominfo);
|
||||
|
||||
extern int lynx_lyx (st_rominfo_t *rominfo);
|
||||
extern const char *lynx_lyx_desc;
|
||||
|
||||
extern int lynx_n (st_rominfo_t *rominfo, const char *name);
|
||||
extern int lynx_nrot (st_rominfo_t *rominfo);
|
||||
extern int lynx_rotl (st_rominfo_t *rominfo);
|
||||
extern int lynx_rotr (st_rominfo_t *rominfo);
|
||||
|
||||
extern int lynx_init (st_rominfo_t *rominfo);
|
||||
|
||||
extern const st_getopt2_t lynx_usage[];
|
||||
#endif // LYNX_H
|
||||
743
tools/ucon64/src/console/n64.c
Normal file
743
tools/ucon64/src/console/n64.c
Normal file
@@ -0,0 +1,743 @@
|
||||
/*
|
||||
n64.c - Nintendo 64 support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
Copyright (c) 2002 - 2004 dbjh
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "misc/chksum.h"
|
||||
#include "misc/file.h"
|
||||
#include "misc/misc.h"
|
||||
#ifdef USE_ZLIB
|
||||
#include "misc/archive.h"
|
||||
#endif
|
||||
#include "misc/getopt2.h" // st_getopt2_t
|
||||
#include "ucon64.h"
|
||||
#include "ucon64_misc.h"
|
||||
#include "n64.h"
|
||||
#include "patch/ips.h"
|
||||
#include "patch/aps.h"
|
||||
#include "backup/doctor64.h"
|
||||
#include "backup/doctor64jr.h"
|
||||
#include "backup/cd64.h"
|
||||
#include "backup/dex.h"
|
||||
#include "backup/z64.h"
|
||||
|
||||
|
||||
#define N64_HEADER_LEN (sizeof (st_n64_header_t))
|
||||
#define N64_SRAM_SIZE 512
|
||||
#define N64_NAME_LEN 20
|
||||
#define N64_BC_SIZE (0x1000 - N64_HEADER_LEN)
|
||||
#define LAC_ROM_SIZE 1310720
|
||||
|
||||
const st_getopt2_t n64_usage[] =
|
||||
{
|
||||
{
|
||||
NULL, 0, 0, 0,
|
||||
NULL, "Nintendo 64"/*"1996 Nintendo http://www.nintendo.com"*/,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"n64", 0, 0, UCON64_N64,
|
||||
NULL, "force recognition",
|
||||
&ucon64_wf[WF_OBJ_N64_SWITCH]
|
||||
},
|
||||
{
|
||||
"int", 0, 0, UCON64_INT,
|
||||
NULL, "force ROM is in interleaved format (2143, V64)",
|
||||
&ucon64_wf[WF_OBJ_ALL_SWITCH]
|
||||
},
|
||||
{
|
||||
"nint", 0, 0, UCON64_NINT,
|
||||
NULL, "force ROM is not in interleaved format (1234, Z64)",
|
||||
&ucon64_wf[WF_OBJ_ALL_SWITCH]
|
||||
},
|
||||
{
|
||||
"n", 1, 0, UCON64_N,
|
||||
"NEW_NAME", "change internal ROM name to NEW_NAME",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
|
||||
},
|
||||
{
|
||||
"v64", 0, 0, UCON64_V64,
|
||||
NULL, "convert to Doctor V64 (and compatibles/interleaved)",
|
||||
&ucon64_wf[WF_OBJ_N64_DEFAULT]
|
||||
},
|
||||
{
|
||||
"z64", 0, 0, UCON64_Z64,
|
||||
NULL, "convert to Mr. Backup Z64 (not interleaved)",
|
||||
&ucon64_wf[WF_OBJ_N64_DEFAULT]
|
||||
},
|
||||
{
|
||||
"dint", 0, 0, UCON64_DINT,
|
||||
NULL, "convert ROM to (non-)interleaved format (1234 <-> 2143)",
|
||||
&ucon64_wf[WF_OBJ_ALL_INIT_PROBE]
|
||||
},
|
||||
{
|
||||
"swap", 0, 0, UCON64_SWAP,
|
||||
NULL, "same as " OPTION_LONG_S "dint, byte-swap ROM",
|
||||
&ucon64_wf[WF_OBJ_ALL_INIT_PROBE]
|
||||
},
|
||||
{
|
||||
"swap2", 0, 0, UCON64_SWAP2,
|
||||
NULL, "word-swap ROM (1234 <-> 3412)",
|
||||
NULL
|
||||
},
|
||||
#if 0
|
||||
{
|
||||
"f", 0, 0, UCON64_F,
|
||||
NULL, "remove NTSC/PAL protection",
|
||||
NULL
|
||||
},
|
||||
#endif
|
||||
{
|
||||
"bot", 1, 0, UCON64_BOT,
|
||||
"BOOTCODE", "replace/extract BOOTCODE (4032 Bytes) in/from ROM;\n"
|
||||
"extracts automatically if BOOTCODE does not exist",
|
||||
&ucon64_wf[WF_OBJ_N64_DEFAULT]
|
||||
},
|
||||
{
|
||||
"lsram", 1, 0, UCON64_LSRAM,
|
||||
"SRAM", "LaC's SRAM upload tool; ROM should be LaC's ROM image\n"
|
||||
"the SRAM must have a size of 512 Bytes\n"
|
||||
"this option generates a ROM which can be used to transfer\n"
|
||||
"SRAMs to your cartridge's SRAM (EEPROM)",
|
||||
&ucon64_wf[WF_OBJ_N64_INIT_PROBE]
|
||||
},
|
||||
{
|
||||
"usms", 1, 0, UCON64_USMS,
|
||||
"SMSROM", "Jos Kwanten's UltraSMS (Sega Master System/Game Gear emulator);\n"
|
||||
"ROM should be Jos Kwanten's UltraSMS ROM image\n"
|
||||
"works only for SMS ROMs which are <= 4 Mb in size",
|
||||
&ucon64_wf[WF_OBJ_N64_DEFAULT]
|
||||
},
|
||||
{
|
||||
"chk", 0, 0, UCON64_CHK,
|
||||
NULL, "fix ROM checksum\n"
|
||||
"supports only 6102 and 6105 boot codes",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
|
||||
},
|
||||
#if 0
|
||||
{
|
||||
"bios", 1, 0, UCON64_BIOS,
|
||||
"BIOS", "enable backup in Doctor V64 BIOS",
|
||||
NULL
|
||||
},
|
||||
#endif
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
typedef struct st_n64_header
|
||||
{
|
||||
unsigned char pad[64];
|
||||
#if 0
|
||||
unsigned char validation[2];
|
||||
unsigned char compression;
|
||||
unsigned char pad1;
|
||||
unsigned long clockrate;
|
||||
unsigned long programcounter;
|
||||
unsigned long release;
|
||||
unsigned long crc1;
|
||||
unsigned long crc2;
|
||||
unsigned char pad2[8];
|
||||
unsigned char name[20];
|
||||
unsigned char pad3[7];
|
||||
unsigned char maker;
|
||||
unsigned char cartridgeid[2];
|
||||
unsigned char countrycode;
|
||||
unsigned char pad4;
|
||||
#endif
|
||||
} st_n64_header_t;
|
||||
|
||||
st_n64_header_t n64_header;
|
||||
|
||||
typedef struct st_n64_chksum
|
||||
{
|
||||
unsigned int crc1;
|
||||
unsigned int crc2;
|
||||
} st_n64_chksum_t;
|
||||
|
||||
static st_n64_chksum_t n64crc;
|
||||
static int n64_chksum (st_rominfo_t *rominfo, const char *filename);
|
||||
|
||||
|
||||
int
|
||||
n64_v64 (st_rominfo_t *rominfo)
|
||||
{
|
||||
char dest_name[FILENAME_MAX];
|
||||
|
||||
if (rominfo->interleaved)
|
||||
{
|
||||
fprintf (stderr, "ERROR: Already in V64 format\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
set_suffix (dest_name, ".v64");
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fbswap16 (dest_name, 0, ucon64.file_size);
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
n64_z64 (st_rominfo_t *rominfo)
|
||||
{
|
||||
char dest_name[FILENAME_MAX];
|
||||
|
||||
if (!rominfo->interleaved)
|
||||
{
|
||||
fprintf (stderr, "ERROR: Already in Z64 format\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
set_suffix (dest_name, ".z64");
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fbswap16 (dest_name, 0, ucon64.file_size);
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
n64_n (st_rominfo_t *rominfo, const char *name)
|
||||
{
|
||||
char buf[N64_NAME_LEN], dest_name[FILENAME_MAX];
|
||||
|
||||
memset (buf, ' ', N64_NAME_LEN);
|
||||
strncpy (buf, name, strlen (name) > N64_NAME_LEN ? N64_NAME_LEN : strlen (name));
|
||||
|
||||
if (rominfo->interleaved)
|
||||
ucon64_bswap16_n (buf, N64_NAME_LEN);
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fwrite (buf, rominfo->buheader_len + 32, N64_NAME_LEN, dest_name, "r+b");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
n64_f (st_rominfo_t *rominfo)
|
||||
{
|
||||
// TODO: PAL/NTSC fix
|
||||
(void) rominfo; // warning remover
|
||||
fputs ("ERROR: The function for cracking N64 region protections is not yet implemented\n", stderr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
n64_update_chksum (st_rominfo_t *rominfo, const char *filename, char *buf)
|
||||
{
|
||||
uint64_t crc;
|
||||
int x;
|
||||
|
||||
// n64crc is set by n64_chksum() when called from n64_init()
|
||||
crc = (((uint64_t) n64crc.crc1) << 32) | n64crc.crc2;
|
||||
for (x = 0; x < 8; x++)
|
||||
{
|
||||
buf[x] = (char) (crc >> 56);
|
||||
crc <<= 8;
|
||||
}
|
||||
if (rominfo->interleaved)
|
||||
ucon64_bswap16_n (buf, 8);
|
||||
ucon64_fwrite (buf, rominfo->buheader_len + 16, 8, filename, "r+b");
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
n64_chk (st_rominfo_t *rominfo)
|
||||
{
|
||||
char buf[8], dest_name[FILENAME_MAX];
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
|
||||
n64_update_chksum (rominfo, dest_name, buf);
|
||||
dumper (stdout, buf, 8, rominfo->buheader_len + 16, DUMPER_HEX);
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
n64_sram (st_rominfo_t *rominfo, const char *sramfile)
|
||||
// Function to insert an SRAM file in LaC's SRAM upload tool (which is an N64
|
||||
// program)
|
||||
{
|
||||
char sram[N64_SRAM_SIZE], dest_name[FILENAME_MAX], buf[8];
|
||||
|
||||
if (access (sramfile, F_OK))
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], sramfile);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (fsizeof (sramfile) != N64_SRAM_SIZE || ucon64.file_size != LAC_ROM_SIZE)
|
||||
{
|
||||
fprintf (stderr, "ERROR: ROM is not %d bytes and/or SRAM is not %d bytes\n",
|
||||
LAC_ROM_SIZE, N64_SRAM_SIZE);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
ucon64_fread (sram, 0, N64_SRAM_SIZE, sramfile);
|
||||
|
||||
if (rominfo->interleaved)
|
||||
ucon64_bswap16_n (sram, N64_SRAM_SIZE);
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fwrite (sram, 0x286c0, N64_SRAM_SIZE, dest_name, "r+b");
|
||||
n64_chksum (rominfo, dest_name); // calculate the checksum of the modified file
|
||||
n64_update_chksum (rominfo, dest_name, buf);
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
n64_bot (st_rominfo_t *rominfo, const char *bootfile)
|
||||
{
|
||||
char buf[N64_BC_SIZE], dest_name[FILENAME_MAX];
|
||||
|
||||
if (!access (bootfile, F_OK))
|
||||
{
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_fread (buf, 0, N64_BC_SIZE, bootfile);
|
||||
|
||||
if (rominfo->interleaved)
|
||||
ucon64_bswap16_n (buf, N64_BC_SIZE);
|
||||
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fwrite (buf, rominfo->buheader_len + N64_HEADER_LEN, N64_BC_SIZE,
|
||||
dest_name, "r+b");
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy (dest_name, bootfile);
|
||||
// set_suffix (dest_name, ".bot");
|
||||
ucon64_file_handler (dest_name, NULL, OF_FORCE_BASENAME | OF_FORCE_SUFFIX);
|
||||
fcopy (ucon64.rom, rominfo->buheader_len + N64_HEADER_LEN, N64_BC_SIZE,
|
||||
dest_name, "wb");
|
||||
|
||||
if (rominfo->interleaved)
|
||||
ucon64_fbswap16 (dest_name, 0, fsizeof (dest_name));
|
||||
}
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
n64_usms (st_rominfo_t *rominfo, const char *smsrom)
|
||||
{
|
||||
char dest_name[FILENAME_MAX], *usmsbuf;
|
||||
int size;
|
||||
|
||||
if (access (smsrom, F_OK))
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], smsrom);
|
||||
exit (1);
|
||||
}
|
||||
|
||||
size = fsizeof (smsrom);
|
||||
// must be smaller than 4 Mbit, 524288 bytes will be inserted
|
||||
// from 0x1b410 to 0x9b40f (0x7ffff)
|
||||
if (size > 4 * MBIT)
|
||||
{
|
||||
fprintf (stderr, "ERROR: The Sega Master System/Game Gear ROM must be 524288 bytes or less\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
if (!(usmsbuf = (char *) malloc (4 * MBIT)))
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[BUFFER_ERROR], 4 * MBIT);
|
||||
exit (1);
|
||||
}
|
||||
memset (usmsbuf, 0xff, 4 * MBIT);
|
||||
ucon64_fread (usmsbuf, 0, size, smsrom);
|
||||
|
||||
if (rominfo->interleaved)
|
||||
ucon64_bswap16_n (usmsbuf, size);
|
||||
|
||||
// Jos Kwanten's rominserter.exe produces a file named Patched.v64
|
||||
strcpy (dest_name, "Patched.v64");
|
||||
ucon64_file_handler (dest_name, NULL, OF_FORCE_BASENAME | OF_FORCE_SUFFIX);
|
||||
fcopy (ucon64.rom, rominfo->buheader_len, ucon64.file_size, dest_name, "wb");
|
||||
ucon64_fwrite (usmsbuf, rominfo->buheader_len + 0x01b410, 4 * MBIT, dest_name, "r+b");
|
||||
|
||||
free (usmsbuf);
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
n64_init (st_rominfo_t *rominfo)
|
||||
{
|
||||
int result = -1, x;
|
||||
unsigned int value = 0;
|
||||
#define N64_MAKER_MAX 0x50
|
||||
const char *n64_maker[N64_MAKER_MAX] =
|
||||
{
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, "Nintendo", NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, "Nintendo", NULL
|
||||
},
|
||||
#define N64_COUNTRY_MAX 0x5a
|
||||
*n64_country[N64_COUNTRY_MAX] =
|
||||
{
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, "Germany", "U.S.A.",
|
||||
"France", NULL, NULL, "Italy", "Japan",
|
||||
NULL, NULL, NULL, NULL, NULL,
|
||||
"Europe", NULL, NULL, "Spain", NULL,
|
||||
"Australia", NULL, NULL, "France, Germany, The Netherlands", NULL // Holland is an incorrect name for The Netherlands
|
||||
};
|
||||
|
||||
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ? ucon64.buheader_len : 0;
|
||||
|
||||
ucon64_fread (&n64_header, rominfo->buheader_len, N64_HEADER_LEN, ucon64.rom);
|
||||
|
||||
value = OFFSET (n64_header, 0);
|
||||
value += OFFSET (n64_header, 1) << 8;
|
||||
value += OFFSET (n64_header, 2) << 16;
|
||||
value += OFFSET (n64_header, 3) << 24;
|
||||
/*
|
||||
0x41123780 and 0x12418037 can be found in te following files:
|
||||
2 Blokes & An Armchair - Nintendo 64 Remix Remix (PD)
|
||||
Zelda Boot Emu V1 (PD)
|
||||
Zelda Boot Emu V2 (PD)
|
||||
*/
|
||||
if (value == 0x40123780 || value == 0x41123780) // 0x80371240, 0x80371241
|
||||
{
|
||||
rominfo->interleaved = 0;
|
||||
result = 0;
|
||||
}
|
||||
else if (value == 0x12408037 || value == 0x12418037) // 0x37804012, 0x37804112
|
||||
{
|
||||
rominfo->interleaved = 1;
|
||||
result = 0;
|
||||
}
|
||||
else
|
||||
result = -1;
|
||||
|
||||
if (UCON64_ISSET (ucon64.interleaved))
|
||||
rominfo->interleaved = ucon64.interleaved;
|
||||
if (ucon64.console == UCON64_N64)
|
||||
result = 0;
|
||||
|
||||
// internal ROM header
|
||||
rominfo->header_start = 0;
|
||||
rominfo->header_len = N64_HEADER_LEN;
|
||||
rominfo->header = &n64_header;
|
||||
|
||||
// internal ROM name
|
||||
strncpy (rominfo->name, (char *) &OFFSET (n64_header, 32), N64_NAME_LEN);
|
||||
if (rominfo->interleaved)
|
||||
ucon64_bswap16_n (rominfo->name, N64_NAME_LEN);
|
||||
rominfo->name[N64_NAME_LEN] = 0;
|
||||
|
||||
// ROM maker
|
||||
rominfo->maker = NULL_TO_UNKNOWN_S (n64_maker[MIN (OFFSET
|
||||
(n64_header, 59 ^ rominfo->interleaved), N64_MAKER_MAX - 1)]);
|
||||
|
||||
// ROM country
|
||||
rominfo->country = NULL_TO_UNKNOWN_S (n64_country[MIN (OFFSET
|
||||
(n64_header, 63 ^ (!rominfo->interleaved)), N64_COUNTRY_MAX - 1)]);
|
||||
|
||||
// CRC stuff
|
||||
if (!UCON64_ISSET (ucon64.do_not_calc_crc) && result == 0)
|
||||
{
|
||||
rominfo->has_internal_crc = 1;
|
||||
rominfo->internal_crc_len = 4;
|
||||
|
||||
n64_chksum (rominfo, ucon64.rom);
|
||||
rominfo->current_internal_crc = n64crc.crc1;
|
||||
|
||||
value = 0;
|
||||
for (x = 0; x < 4; x++)
|
||||
{
|
||||
rominfo->internal_crc <<= 8;
|
||||
rominfo->internal_crc += OFFSET (n64_header, 16 + (x ^ rominfo->interleaved));
|
||||
value <<= 8;
|
||||
value += OFFSET (n64_header, 20 + (x ^ rominfo->interleaved));
|
||||
}
|
||||
|
||||
sprintf (rominfo->internal_crc2,
|
||||
"2nd Checksum: %s, 0x%08x (calculated) %c= 0x%08x (internal)%s",
|
||||
#ifdef USE_ANSI_COLOR
|
||||
ucon64.ansi_color ?
|
||||
((n64crc.crc2 == value) ?
|
||||
"\x1b[01;32mOk\x1b[0m" : "\x1b[01;31mBad\x1b[0m")
|
||||
:
|
||||
((n64crc.crc2 == value) ? "Ok" : "Bad"),
|
||||
#else
|
||||
(n64crc.crc2 == value) ? "Ok" : "Bad",
|
||||
#endif
|
||||
n64crc.crc2,
|
||||
(n64crc.crc2 == value) ? '=' : '!', value,
|
||||
(n64crc.crc2 != value) ?
|
||||
"\nNOTE: The checksum routine supports only 6102 and 6105 boot codes" :
|
||||
"");
|
||||
}
|
||||
|
||||
rominfo->console_usage = n64_usage[0].help;
|
||||
rominfo->copier_usage = (!rominfo->buheader_len ?
|
||||
((!rominfo->interleaved) ? z64_usage[0].help : doctor64_usage[0].help) : unknown_usage[0].help);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
ROM check sum routine is based on chksum64 V1.2 by Andreas Sterbenz
|
||||
<stan@sbox.tu-graz.ac.at>, a program to calculate the ROM checksum of
|
||||
Nintendo 64 ROMs.
|
||||
*/
|
||||
#define ROL(i, b) (((i) << (b)) | ((i) >> (32 - (b))))
|
||||
#define BYTES2LONG(b, s) ( (b)[0^(s)] << 24 | \
|
||||
(b)[1^(s)] << 16 | \
|
||||
(b)[2^(s)] << 8 | \
|
||||
(b)[3^(s)] )
|
||||
|
||||
#define CHECKSUM_START 0x1000 //(N64_HEADER_LEN + N64_BC_SIZE)
|
||||
#define CHECKSUM_LENGTH 0x100000
|
||||
#define CHECKSUM_STARTVALUE1 0xf8ca4ddc
|
||||
#define CHECKSUM_STARTVALUE2 0xdf26f436
|
||||
#define CALC_CRC32 // see this as a marker, don't disable
|
||||
|
||||
int
|
||||
n64_chksum (st_rominfo_t *rominfo, const char *filename)
|
||||
{
|
||||
unsigned char bootcode_buf[CHECKSUM_START], chunk[MAXBUFSIZE & ~3]; // size must be a multiple of 4
|
||||
unsigned int i, c1, k1, k2, t1, t2, t3, t4, t5, t6, clen = CHECKSUM_LENGTH,
|
||||
rlen = (ucon64.file_size - rominfo->buheader_len) - CHECKSUM_START,
|
||||
n = 0, bootcode; // using ucon64.file_size is ok for n64_init() & n64_sram()
|
||||
FILE *file;
|
||||
#ifdef CALC_CRC32
|
||||
unsigned int scrc32 = 0, fcrc32 = 0; // search CRC32 & file CRC32
|
||||
unsigned char *crc32_mem;
|
||||
#endif
|
||||
|
||||
if (rlen < CHECKSUM_START + CHECKSUM_LENGTH)
|
||||
{
|
||||
#ifdef CALC_CRC32
|
||||
n = ucon64.file_size - rominfo->buheader_len;
|
||||
if ((crc32_mem = (unsigned char *) malloc (n)) == NULL)
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[BUFFER_ERROR], n);
|
||||
return -1;
|
||||
}
|
||||
ucon64_fread (crc32_mem, rominfo->buheader_len, n, filename);
|
||||
if (!rominfo->interleaved)
|
||||
{
|
||||
ucon64.fcrc32 = crc32 (0, crc32_mem, n);
|
||||
ucon64_bswap16_n (crc32_mem, n);
|
||||
}
|
||||
ucon64.crc32 = crc32 (0, crc32_mem, n);
|
||||
free (crc32_mem);
|
||||
#endif
|
||||
return -1; // ROM is too small
|
||||
}
|
||||
|
||||
if (!(file = fopen (filename, "rb")))
|
||||
return -1;
|
||||
|
||||
#ifdef CALC_CRC32
|
||||
if (!rominfo->interleaved)
|
||||
{
|
||||
if ((crc32_mem = (unsigned char *) malloc (MAXBUFSIZE)) == NULL)
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[BUFFER_ERROR], MAXBUFSIZE);
|
||||
fclose (file);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
else
|
||||
crc32_mem = chunk;
|
||||
|
||||
fseek (file, rominfo->buheader_len, SEEK_SET);
|
||||
fread (crc32_mem, 1, CHECKSUM_START, file);
|
||||
memcpy (bootcode_buf, crc32_mem + N64_HEADER_LEN, N64_BC_SIZE);
|
||||
if (!rominfo->interleaved)
|
||||
{
|
||||
fcrc32 = crc32 (0, crc32_mem, CHECKSUM_START);
|
||||
ucon64_bswap16_n (crc32_mem, CHECKSUM_START);
|
||||
}
|
||||
else
|
||||
ucon64_bswap16_n (bootcode_buf, N64_BC_SIZE);
|
||||
scrc32 = crc32 (0, crc32_mem, CHECKSUM_START);
|
||||
#else
|
||||
fseek (file, rominfo->buheader_len + N64_HEADER_LEN, SEEK_SET);
|
||||
fread (bootcode_buf, 1, N64_BC_SIZE, file);
|
||||
if (rominfo->interleaved)
|
||||
ucon64_bswap16_n (bootcode_buf, N64_BC_SIZE);
|
||||
#endif
|
||||
if (crc32 (0, bootcode_buf, N64_BC_SIZE) == 0x98bc2c86)
|
||||
{
|
||||
bootcode = 6105;
|
||||
i = CHECKSUM_STARTVALUE2;
|
||||
}
|
||||
else
|
||||
{
|
||||
bootcode = 0; // everything else
|
||||
i = CHECKSUM_STARTVALUE1;
|
||||
}
|
||||
|
||||
t1 = i;
|
||||
t2 = i;
|
||||
t3 = i;
|
||||
t4 = i;
|
||||
t5 = i;
|
||||
t6 = i;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (rlen > 0)
|
||||
{
|
||||
if ((n = fread (chunk, 1, MIN (sizeof (chunk), clen), file)))
|
||||
{
|
||||
#ifdef CALC_CRC32
|
||||
if (!rominfo->interleaved)
|
||||
{
|
||||
memcpy (crc32_mem, chunk, n);
|
||||
fcrc32 = crc32 (fcrc32, crc32_mem, n);
|
||||
ucon64_bswap16_n (crc32_mem, n);
|
||||
}
|
||||
scrc32 = crc32 (scrc32, crc32_mem, n);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
n = MIN (sizeof (chunk), clen);
|
||||
|
||||
n &= ~3;
|
||||
if (n == 0)
|
||||
break;
|
||||
for (i = 0; i < n; i += 4)
|
||||
{
|
||||
c1 = BYTES2LONG (&chunk[i], rominfo->interleaved);
|
||||
k1 = t6 + c1;
|
||||
if (k1 < t6)
|
||||
t4++;
|
||||
t6 = k1;
|
||||
t3 ^= c1;
|
||||
k2 = c1 & 0x1f;
|
||||
k1 = ROL (c1, k2);
|
||||
t5 += k1;
|
||||
if (c1 < t2)
|
||||
t2 ^= k1;
|
||||
else
|
||||
t2 ^= t6 ^ c1;
|
||||
|
||||
if (bootcode == 6105)
|
||||
{
|
||||
k1 = 0x710 + (i & 0xff);
|
||||
//t1 += BYTES2LONG (&bootcode_buf[k1], 0) ^ c1;
|
||||
t1 += ((bootcode_buf[k1] << 24) | (bootcode_buf[k1 + 1] << 16) |
|
||||
(bootcode_buf[k1 + 2] << 8) | (bootcode_buf[k1 + 3])) ^ c1;
|
||||
}
|
||||
else
|
||||
t1 += c1 ^ t5;
|
||||
}
|
||||
if (rlen > 0)
|
||||
{
|
||||
rlen -= n;
|
||||
if (rlen <= 0)
|
||||
memset (chunk, 0, sizeof (chunk));
|
||||
}
|
||||
clen -= n;
|
||||
}
|
||||
n64crc.crc1 = t6 ^ t4 ^ t3;
|
||||
n64crc.crc2 = t5 ^ t2 ^ t1;
|
||||
|
||||
#ifdef CALC_CRC32
|
||||
if (!rominfo->interleaved)
|
||||
{
|
||||
free (crc32_mem);
|
||||
crc32_mem = chunk;
|
||||
}
|
||||
while ((n = fread (crc32_mem, 1, sizeof (chunk), file)))
|
||||
{
|
||||
if (!rominfo->interleaved)
|
||||
{
|
||||
fcrc32 = crc32 (fcrc32, crc32_mem, n);
|
||||
ucon64_bswap16_n (crc32_mem, n);
|
||||
}
|
||||
scrc32 = crc32 (scrc32, crc32_mem, n);
|
||||
}
|
||||
|
||||
ucon64.crc32 = scrc32;
|
||||
if (!rominfo->interleaved)
|
||||
ucon64.fcrc32 = fcrc32;
|
||||
#endif
|
||||
|
||||
fclose (file);
|
||||
return 0;
|
||||
}
|
||||
37
tools/ucon64/src/console/n64.h
Normal file
37
tools/ucon64/src/console/n64.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
n64.h - Nintendo 64 support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef N64_H
|
||||
#define N64_H
|
||||
|
||||
extern const st_getopt2_t n64_usage[];
|
||||
|
||||
extern int n64_bot (st_rominfo_t *rominfo, const char *bootfile);
|
||||
extern int n64_chk (st_rominfo_t *rominfo);
|
||||
|
||||
extern int n64_f (st_rominfo_t *rominfo);
|
||||
extern int n64_init (st_rominfo_t *rominfo);
|
||||
extern int n64_n (st_rominfo_t *rominfo, const char *name);
|
||||
extern int n64_sram (st_rominfo_t *rominfo, const char *sramfile);
|
||||
extern int n64_usms (st_rominfo_t *rominfo, const char *smsrom);
|
||||
extern int n64_v64 (st_rominfo_t *rominfo);
|
||||
extern int n64_z64 (st_rominfo_t *rominfo);
|
||||
|
||||
#endif
|
||||
259
tools/ucon64/src/console/neogeo.c
Normal file
259
tools/ucon64/src/console/neogeo.c
Normal file
@@ -0,0 +1,259 @@
|
||||
/*
|
||||
neogeo.c - NeoGeo support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "misc/misc.h"
|
||||
#include "misc/file.h"
|
||||
#ifdef USE_ZLIB
|
||||
#include "misc/archive.h"
|
||||
#endif
|
||||
#include "misc/getopt2.h" // st_getopt2_t
|
||||
#include "ucon64.h"
|
||||
#include "ucon64_misc.h"
|
||||
#include "neogeo.h"
|
||||
|
||||
|
||||
const st_getopt2_t neogeo_usage[] =
|
||||
{
|
||||
{
|
||||
NULL, 0, 0, 0,
|
||||
NULL, "Neo Geo/Neo Geo CD(Z)/MVS"/*"1990/1994 SNK http://www.neogeo.co.jp"*/,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"ng", 0, 0, UCON64_NG,
|
||||
NULL, "force recognition",
|
||||
&ucon64_wf[WF_OBJ_NG_SWITCH]
|
||||
},
|
||||
#if 0
|
||||
" " OPTION_LONG_S "ns force ROM is not split\n"
|
||||
"TODO: " OPTION_LONG_S "mgd convert to Multi Game Doctor/MGD2/RAW\n"
|
||||
"TODO: " OPTION_LONG_S "mvs convert to Arcade/MVS\n"
|
||||
#endif
|
||||
{
|
||||
"bios", 1, 0, UCON64_BIOS,
|
||||
"BIOS", "convert NeoCD BIOS to work with NeoCD emulator" /*;\n"
|
||||
"http://www.illusion-city.com/neo/"*/,
|
||||
&ucon64_wf[WF_OBJ_NG_DEFAULT]
|
||||
},
|
||||
#if 0
|
||||
"TODO: " OPTION_S "j join split ROM"
|
||||
"TODO: " OPTION_S "s split ROM into 4Mb parts (for backup unit(s) with fdd)"
|
||||
"TODO: " OPTION_LONG_S "ngs convert Neo Geo sound to WAV; " OPTION_LONG_S "rom=*_m1.rom or *_v*.rom"
|
||||
#endif
|
||||
{
|
||||
"sam", 1, 0, UCON64_SAM,
|
||||
"SAMFILE", "convert SAM/M.A.M.E. sound to WAV",
|
||||
&ucon64_wf[WF_OBJ_NG_DEFAULT]
|
||||
},
|
||||
// "TODO: " OPTION_LONG_S "chkm check/fix Multiple Arcade Machine Emulator/M.A.M.E. ROMs;\n"
|
||||
// " " OPTION_LONG_S "rom=DIRECTORY"
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
static int sam2wav (const char *filename);
|
||||
|
||||
#define NEOGEO_HEADER_START 0
|
||||
#define NEOGEO_HEADER_LEN 0
|
||||
|
||||
|
||||
int
|
||||
neogeo_bios (const char *fname)
|
||||
{
|
||||
char dest_name[FILENAME_MAX];
|
||||
|
||||
strcpy (dest_name, fname);
|
||||
set_suffix (dest_name, ".tmp");
|
||||
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (fname, 0, MBIT, dest_name, "wb");
|
||||
ucon64_fbswap16 (dest_name, 0, MBIT);
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
neogeo_sam (const char *fname)
|
||||
{
|
||||
if (sam2wav (fname) == -1)
|
||||
fprintf (stderr, "ERROR: SAM header seems to be corrupt\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
neogeo_mgd (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
neogeo_mvs (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
neogeo_s (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
neogeo_init (st_rominfo_t *rominfo)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
rominfo->console_usage = neogeo_usage[0].help;
|
||||
rominfo->copier_usage = unknown_usage[0].help;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sam2wav (const char *filename)
|
||||
{
|
||||
unsigned char buf[32];
|
||||
FILE *fh, *fh2;
|
||||
unsigned datasize, wavesize, riffsize, freq, bits, rate;
|
||||
|
||||
if (fsizeof (filename) < 16)
|
||||
return -1;
|
||||
if (!(fh = fopen (filename, "rb")))
|
||||
return -1;
|
||||
|
||||
strcpy ((char *) buf, filename);
|
||||
set_suffix ((char *) buf, ".wav");
|
||||
|
||||
if (!(fh2 = fopen ((char *) buf, "wb")))
|
||||
return -1;
|
||||
fread (buf, 1, 4, fh);
|
||||
|
||||
if (strncmp ((char *) buf, "MAME", 4) != 0)
|
||||
return -1;
|
||||
fread (buf, 1, 4, fh);
|
||||
|
||||
datasize = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
|
||||
wavesize = /* "fmt " */ 4 + 4 + 4 + 2 + 2;
|
||||
riffsize = /* RIFF */ 4 + 4 + 4 + 4 + 4 + wavesize + datasize;
|
||||
|
||||
buf[0] = riffsize & 0xff;
|
||||
buf[1] = (riffsize >> 8) & 0xff;
|
||||
buf[2] = (riffsize >> 16) & 0xff;
|
||||
buf[3] = (riffsize >> 24) & 0xff;
|
||||
|
||||
fwrite ("RIFF", 1, 4, fh2);
|
||||
fwrite (buf, 1, 4, fh2);
|
||||
|
||||
fwrite ("WAVE", 1, 4, fh2);
|
||||
fwrite ("fmt ", 1, 4, fh2);
|
||||
|
||||
buf[0] = wavesize & 0xff;
|
||||
buf[1] = (wavesize >> 8) & 0xff;
|
||||
buf[2] = (wavesize >> 16) & 0xff;
|
||||
buf[3] = (wavesize >> 24) & 0xff;
|
||||
fwrite (buf, 1, 4, fh2);
|
||||
|
||||
/* number of channels - alway 1 for MAME samples */
|
||||
fwrite ("\001\000\001\000", 1, 4, fh2);
|
||||
|
||||
/* read frequency */
|
||||
fread (buf, 1, 4, fh);
|
||||
freq = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
|
||||
|
||||
/* write frequency */
|
||||
fwrite (buf, 1, 4, fh2);
|
||||
|
||||
/* read bits, amplitude and extension */
|
||||
fread (buf, 1, 4, fh);
|
||||
|
||||
bits = buf[0];
|
||||
|
||||
if (bits == 16)
|
||||
rate = freq * 2;
|
||||
else
|
||||
rate = freq;
|
||||
|
||||
buf[0] = rate & 0xff;
|
||||
buf[1] = (rate >> 8) & 0xff;
|
||||
buf[2] = (rate >> 16) & 0xff;
|
||||
buf[3] = (rate >> 24) & 0xff;
|
||||
|
||||
/* write bytes per second */
|
||||
fwrite (buf, 1, 4, fh2);
|
||||
|
||||
/* write alignment */
|
||||
if (bits == 16)
|
||||
fwrite ("\002\000", 1, 2, fh2);
|
||||
else
|
||||
fwrite ("\001\000", 1, 2, fh2);
|
||||
|
||||
buf[0] = bits & 0xff;
|
||||
buf[1] = (bits >> 8) & 0xff;
|
||||
|
||||
/* write bits per sample */
|
||||
fwrite (buf, 1, 2, fh2);
|
||||
fwrite ("data", 1, 4, fh2);
|
||||
|
||||
buf[0] = datasize & 0xff;
|
||||
buf[1] = (datasize >> 8) & 0xff;
|
||||
buf[2] = (datasize >> 16) & 0xff;
|
||||
buf[3] = (datasize >> 24) & 0xff;
|
||||
fwrite (buf, 1, 4, fh2);
|
||||
|
||||
if (bits == 16)
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (fread (buf, 1, 2, fh) != 2)
|
||||
break;
|
||||
fwrite (buf, 1, 2, fh2);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (fread (buf, 1, 1, fh) != 1)
|
||||
break;
|
||||
buf[0] = buf[0] ^ 0x80;
|
||||
fwrite (buf, 1, 1, fh2);
|
||||
}
|
||||
}
|
||||
fclose (fh2);
|
||||
fclose (fh);
|
||||
return 0;
|
||||
}
|
||||
33
tools/ucon64/src/console/neogeo.h
Normal file
33
tools/ucon64/src/console/neogeo.h
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
neogeo.h - NeoGeo support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef NEOGEO_H
|
||||
#define NEOGEO_H
|
||||
|
||||
extern int neogeo_bios (const char *fname);
|
||||
extern int neogeo_init (st_rominfo_t *rominfo);
|
||||
extern int neogeo_mgd (void);
|
||||
extern int neogeo_mvs (void);
|
||||
extern int neogeo_s (void);
|
||||
extern int neogeo_sam (const char *fname);
|
||||
|
||||
extern const st_getopt2_t neogeo_usage[];
|
||||
|
||||
#endif
|
||||
7707
tools/ucon64/src/console/nes.c
Normal file
7707
tools/ucon64/src/console/nes.c
Normal file
File diff suppressed because it is too large
Load Diff
236
tools/ucon64/src/console/nes.h
Normal file
236
tools/ucon64/src/console/nes.h
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
nes.h - Nintendo Entertainment System support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
Copyright (c) 2002 - 2003 dbjh
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef NES_H
|
||||
#define NES_H
|
||||
|
||||
typedef enum { INES = 1, UNIF, PASOFAMI, FFE, FDS, FAM } nes_file_t;
|
||||
|
||||
extern const st_getopt2_t nes_usage[];
|
||||
|
||||
/*
|
||||
iNES Format (.NES)
|
||||
------------------
|
||||
|
||||
Following the iNES header description (size = $10 bytes):
|
||||
|
||||
+--------+------+------------------------------------------+
|
||||
| Offset | Size | Content(s) |
|
||||
+--------+------+------------------------------------------+
|
||||
| 0 | 3 | 'NES' |
|
||||
| 3 | 1 | $1A |
|
||||
| 4 | 1 | 16K PRG-ROM page count (size=x*0x4000) |
|
||||
| 5 | 1 | 8K CHR-ROM page count (size=y*0x2000) |
|
||||
| 6 | 1 | ROM Control Byte #1 |
|
||||
| | | %####vTsM |
|
||||
| | | | ||||+- 0=Horizontal Mirroring |
|
||||
| | | | |||| 1=Vertical Mirroring |
|
||||
| | | | |||+-- 1=SaveRAM enabled ($6000) |
|
||||
| | | | ||+--- 1=Trainer data (512 bytes) |
|
||||
| | | | |+---- 1=Four-screen mirroring |
|
||||
| | | | | ($2000,$2400,$2800,$2C00) |
|
||||
| | | +--+----- Mapper # (lower 4-bits) |
|
||||
| 7 | 1 | ROM Control Byte #2 |
|
||||
| | | %####00PU |
|
||||
| | | | | |+- 1=VS Unisystem arcade |
|
||||
| | | | | +-- 1=Playchoice-10 arcade |
|
||||
| | | +--+----- Mapper # (upper 4-bits) |
|
||||
| 8-15 | 8 | $00 |
|
||||
| 16-.. | | Actual 16K PRG-ROM pages (in linear |
|
||||
| ... | | order). If a trainer exists, it precedes |
|
||||
| ... | | the first PRG-ROM bank. |
|
||||
| ..-EOF | | CHR-ROM pages (in ascending order). |
|
||||
+--------+------+------------------------------------------+
|
||||
|
||||
IMPORTANT: the iNES format DOES NOT support mappers greater than 255.
|
||||
There are a couple of Famicom mappers > 255. They use byte #7 (low 4 bits),
|
||||
which conflicts with VS Unisystem/PlayChoice-10 identification.
|
||||
*/
|
||||
|
||||
#define INES_SIG_S "NES\x1a"
|
||||
|
||||
// flags in st_ines_header_t.ctrl1
|
||||
#define INES_MIRROR 0x01
|
||||
#define INES_SRAM 0x02
|
||||
#define INES_TRAINER 0x04
|
||||
#define INES_4SCREEN 0x08
|
||||
|
||||
#define INES_HEADER_START 0
|
||||
#define INES_HEADER_LEN (sizeof (st_ines_header_t))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char signature[4]; // 0x4e,0x45,0x53,0x1a (NES file signature)
|
||||
unsigned char prg_size; // # 16 kB banks
|
||||
unsigned char chr_size; // # 8 kB banks
|
||||
unsigned char ctrl1;
|
||||
unsigned char ctrl2;
|
||||
unsigned int reserved1; // 0
|
||||
unsigned int reserved2; // 0
|
||||
} st_ines_header_t;
|
||||
|
||||
|
||||
#define UNIF_SIG_S "UNIF"
|
||||
#define UNIF_REVISION 8 // the "official" spec is at version 7 (10/08/2002)
|
||||
|
||||
// numeric values of id strings in little endian format, e.g.
|
||||
// UNIF_ID == 'F' << 24 | 'I' << 16 | 'N' << 8 | 'U'
|
||||
#define UNIF_ID 0x46494E55
|
||||
#define MAPR_ID 0x5250414D
|
||||
#define READ_ID 0x44414552
|
||||
#define NAME_ID 0x454D414E
|
||||
#define TVCI_ID 0x49435654
|
||||
#define DINF_ID 0x464E4944
|
||||
#define CTRL_ID 0x4C525443
|
||||
#define BATR_ID 0x52544142
|
||||
#define VROR_ID 0x524F5256
|
||||
#define MIRR_ID 0x5252494D
|
||||
|
||||
#define PCK0_ID 0x304B4350
|
||||
#define PCK1_ID 0x314B4350
|
||||
#define PCK2_ID 0x324B4350
|
||||
#define PCK3_ID 0x334B4350
|
||||
#define PCK4_ID 0x344B4350
|
||||
#define PCK5_ID 0x354B4350
|
||||
#define PCK6_ID 0x364B4350
|
||||
#define PCK7_ID 0x374B4350
|
||||
#define PCK8_ID 0x384B4350
|
||||
#define PCK9_ID 0x394B4350
|
||||
#define PCKA_ID 0x414B4350
|
||||
#define PCKB_ID 0x424B4350
|
||||
#define PCKC_ID 0x434B4350
|
||||
#define PCKD_ID 0x444B4350
|
||||
#define PCKE_ID 0x454B4350
|
||||
#define PCKF_ID 0x464B4350
|
||||
|
||||
#define CCK0_ID 0x304B4343
|
||||
#define CCK1_ID 0x314B4343
|
||||
#define CCK2_ID 0x324B4343
|
||||
#define CCK3_ID 0x334B4343
|
||||
#define CCK4_ID 0x344B4343
|
||||
#define CCK5_ID 0x354B4343
|
||||
#define CCK6_ID 0x364B4343
|
||||
#define CCK7_ID 0x374B4343
|
||||
#define CCK8_ID 0x384B4343
|
||||
#define CCK9_ID 0x394B4343
|
||||
#define CCKA_ID 0x414B4343
|
||||
#define CCKB_ID 0x424B4343
|
||||
#define CCKC_ID 0x434B4343
|
||||
#define CCKD_ID 0x444B4343
|
||||
#define CCKE_ID 0x454B4343
|
||||
#define CCKF_ID 0x464B4343
|
||||
|
||||
#define PRG0_ID 0x30475250
|
||||
#define PRG1_ID 0x31475250
|
||||
#define PRG2_ID 0x32475250
|
||||
#define PRG3_ID 0x33475250
|
||||
#define PRG4_ID 0x34475250
|
||||
#define PRG5_ID 0x35475250
|
||||
#define PRG6_ID 0x36475250
|
||||
#define PRG7_ID 0x37475250
|
||||
#define PRG8_ID 0x38475250
|
||||
#define PRG9_ID 0x39475250
|
||||
#define PRGA_ID 0x41475250
|
||||
#define PRGB_ID 0x42475250
|
||||
#define PRGC_ID 0x43475250
|
||||
#define PRGD_ID 0x44475250
|
||||
#define PRGE_ID 0x45475250
|
||||
#define PRGF_ID 0x46475250
|
||||
|
||||
#define CHR0_ID 0x30524843
|
||||
#define CHR1_ID 0x31524843
|
||||
#define CHR2_ID 0x32524843
|
||||
#define CHR3_ID 0x33524843
|
||||
#define CHR4_ID 0x34524843
|
||||
#define CHR5_ID 0x35524843
|
||||
#define CHR6_ID 0x36524843
|
||||
#define CHR7_ID 0x37524843
|
||||
#define CHR8_ID 0x38524843
|
||||
#define CHR9_ID 0x39524843
|
||||
#define CHRA_ID 0x41524843
|
||||
#define CHRB_ID 0x42524843
|
||||
#define CHRC_ID 0x43524843
|
||||
#define CHRD_ID 0x44524843
|
||||
#define CHRE_ID 0x45524843
|
||||
#define CHRF_ID 0x46524843
|
||||
|
||||
#if UNIF_REVISION > 7
|
||||
// UNIF revision 8 (if it ever comes out) will probably include this chunk type
|
||||
#define WRTR_ID 0x52545257
|
||||
#define WRTR_MARKER ';'
|
||||
#define WRTR_MARKER_S ";"
|
||||
#endif
|
||||
|
||||
#define BOARDNAME_MAXLEN 32 // chunk length, NOT string length
|
||||
// string lentgh = chunk length - 1
|
||||
#define UNIF_HEADER_START 0
|
||||
#define UNIF_HEADER_LEN (sizeof (st_unif_header_t))
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char signature[4]; // 0x55,0x4e,0x49,0x46 ("UNIF")
|
||||
unsigned int revision; // revision number
|
||||
unsigned char expansion[24]; // reserved
|
||||
} st_unif_header_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned int id; // chunk identification string
|
||||
unsigned int length; // data length, in little endian format
|
||||
void *data;
|
||||
} st_unif_chunk_t;
|
||||
|
||||
// DINF chunk data
|
||||
typedef struct
|
||||
{
|
||||
char dumper_name[100]; // name of the person who dumped the cart
|
||||
unsigned char day; // day of the month when cartridge was dumped
|
||||
unsigned char month; // month of the year when cartridge was dumped
|
||||
unsigned short year; // year during which the cartridge was dumped
|
||||
char dumper_agent[100]; // name of the ROM-dumping means used (ASCII-Z string)
|
||||
} st_dumper_info_t;
|
||||
|
||||
|
||||
#define FDS_SIG_S "FDS\x1A"
|
||||
#define FDS_HEADER_START 0
|
||||
#define FDS_HEADER_LEN 16
|
||||
|
||||
|
||||
// the FAM define is a guess based on FAM2FDS, more info is needed about the
|
||||
// FAM format
|
||||
#define FAM_HEADER_LEN 192
|
||||
|
||||
|
||||
extern int nes_fds (void);
|
||||
extern int nes_fdsl (st_rominfo_t *rominfo, char *output_str);
|
||||
extern int nes_n (const char *name);
|
||||
extern int nes_s (void);
|
||||
extern int nes_pasofami (void);
|
||||
extern int nes_ineshd (st_rominfo_t *rominfo);
|
||||
extern int nes_ffe (st_rominfo_t *rominfo);
|
||||
extern int nes_ines (void);
|
||||
extern int nes_init (st_rominfo_t *rominfo);
|
||||
extern int nes_unif (void);
|
||||
extern int nes_j (unsigned char **mem_image);
|
||||
extern int nes_dint (void);
|
||||
extern nes_file_t nes_get_file_type (void);
|
||||
|
||||
#endif // NES_H
|
||||
112
tools/ucon64/src/console/ngp.c
Normal file
112
tools/ucon64/src/console/ngp.c
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
ngp.c - NeoGeo Pocket support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
Copyright (c) 2001 Gulliver
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "misc/misc.h"
|
||||
#include "misc/file.h"
|
||||
#ifdef USE_ZLIB
|
||||
#include "misc/archive.h"
|
||||
#endif
|
||||
#include "misc/getopt2.h" // st_getopt2_t
|
||||
#include "ucon64.h"
|
||||
#include "ucon64_misc.h"
|
||||
#include "ngp.h"
|
||||
#include "backup/pl.h"
|
||||
|
||||
|
||||
const st_getopt2_t ngp_usage[] =
|
||||
{
|
||||
{
|
||||
NULL, 0, 0, 0,
|
||||
NULL, "Neo Geo Pocket/Neo Geo Pocket Color"/*"1998/1999 SNK http://www.neogeo.co.jp"*/,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"ngp", 0, 0, UCON64_NGP,
|
||||
NULL, "force recognition",
|
||||
&ucon64_wf[WF_OBJ_NGP_SWITCH]
|
||||
},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
typedef struct st_ngp_header
|
||||
{
|
||||
char pad[48];
|
||||
} st_ngp_header_t;
|
||||
|
||||
#define NGP_HEADER_START 0
|
||||
#define NGP_HEADER_LEN (sizeof (st_ngp_header_t))
|
||||
|
||||
|
||||
st_ngp_header_t ngp_header;
|
||||
|
||||
|
||||
int
|
||||
ngp_init (st_rominfo_t *rominfo)
|
||||
{
|
||||
int result = -1;
|
||||
char *snk_code = "COPYRIGHT BY SNK CORPORATION",
|
||||
*third_code = " LICENSED BY SNK CORPORATION", buf[MAXBUFSIZE];
|
||||
|
||||
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ? ucon64.buheader_len : 0;
|
||||
|
||||
ucon64_fread (&ngp_header, NGP_HEADER_START + rominfo->buheader_len,
|
||||
NGP_HEADER_LEN, ucon64.rom);
|
||||
|
||||
if (!strncmp ((const char *) &OFFSET (ngp_header, 0), snk_code, strlen (snk_code)) ||
|
||||
!strncmp ((const char *) &OFFSET (ngp_header, 0), third_code, strlen (third_code)))
|
||||
result = 0;
|
||||
else
|
||||
result = -1;
|
||||
if (ucon64.console == UCON64_NGP)
|
||||
result = 0;
|
||||
|
||||
rominfo->header_start = NGP_HEADER_START;
|
||||
rominfo->header_len = NGP_HEADER_LEN;
|
||||
rominfo->header = &ngp_header;
|
||||
|
||||
// internal ROM name
|
||||
strncpy (rominfo->name, (const char *) &OFFSET (ngp_header, 0x24), 12);
|
||||
rominfo->name[12] = 0;
|
||||
|
||||
// ROM maker
|
||||
rominfo->maker =
|
||||
!strncmp ((const char *) &OFFSET (ngp_header, 0), snk_code, strlen (snk_code)) ?
|
||||
"SNK" : "Third party";
|
||||
|
||||
// misc stuff
|
||||
sprintf (buf, "Mode: %s",
|
||||
(OFFSET (ngp_header, 0x23) == 0x00) ? "Mono" :
|
||||
(OFFSET (ngp_header, 0x23) == 0x10) ? "Color" :
|
||||
"Unknown");
|
||||
strcat (rominfo->misc, buf);
|
||||
|
||||
rominfo->console_usage = ngp_usage[0].help;
|
||||
rominfo->copier_usage = !rominfo->buheader_len ? pl_usage[0].help : unknown_usage[0].help;
|
||||
|
||||
return result;
|
||||
}
|
||||
26
tools/ucon64/src/console/ngp.h
Normal file
26
tools/ucon64/src/console/ngp.h
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
ngp.h - NeoGeo Pocket support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef NGP_H
|
||||
#define NGP_H
|
||||
|
||||
extern const st_getopt2_t ngp_usage[];
|
||||
extern int ngp_init (st_rominfo_t *rominfo);
|
||||
#endif
|
||||
1200
tools/ucon64/src/console/pce.c
Normal file
1200
tools/ucon64/src/console/pce.c
Normal file
File diff suppressed because it is too large
Load Diff
31
tools/ucon64/src/console/pce.h
Normal file
31
tools/ucon64/src/console/pce.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
pce.h - PC-Engine support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef PCE_H
|
||||
#define PCE_H
|
||||
extern const st_getopt2_t pcengine_usage[];
|
||||
|
||||
extern int pcengine_init (st_rominfo_t *rominfo);
|
||||
extern int pcengine_mgd (st_rominfo_t *rominfo);
|
||||
extern int pcengine_msg (st_rominfo_t *rominfo);
|
||||
extern int pcengine_swap (st_rominfo_t *rominfo);
|
||||
extern int pcengine_f (st_rominfo_t *rominfo);
|
||||
extern int pcengine_multi (int truncate_size, char *fname);
|
||||
#endif
|
||||
66
tools/ucon64/src/console/psx.c
Normal file
66
tools/ucon64/src/console/psx.c
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
psx.c - Playstation support for uCON64
|
||||
|
||||
Copyright (c) 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include "misc/misc.h"
|
||||
#include "misc/itypes.h"
|
||||
#ifdef USE_ZLIB
|
||||
#include "misc/archive.h"
|
||||
#endif
|
||||
#include "misc/getopt2.h" // st_getopt2_t
|
||||
#include "ucon64.h"
|
||||
#include "ucon64_misc.h"
|
||||
#include "psx.h"
|
||||
|
||||
|
||||
const st_getopt2_t psx_usage[] =
|
||||
{
|
||||
{
|
||||
NULL, 0, 0, 0,
|
||||
NULL, "Playstation (One)/Playstation 2 (CD only)"/*"1994/(2000) Sony http://www.playstation.com"*/,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"psx", 0, 0, UCON64_PSX,
|
||||
NULL, "force recognition",
|
||||
&ucon64_wf[WF_OBJ_PSX_SWITCH]
|
||||
},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
psx_init (st_rominfo_t *rominfo)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
rominfo->console_usage = psx_usage[0].help;
|
||||
// rominfo->copier_usage = cdrw_usage[0].help;
|
||||
|
||||
return result;
|
||||
}
|
||||
25
tools/ucon64/src/console/psx.h
Normal file
25
tools/ucon64/src/console/psx.h
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
psx.h - Playstation support for uCON64
|
||||
|
||||
Copyright (c) 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef PSX_H
|
||||
#define PSX_H
|
||||
extern int psx_init (st_rominfo_t *rominfo);
|
||||
extern const st_getopt2_t psx_usage[];
|
||||
#endif
|
||||
699
tools/ucon64/src/console/sms.c
Normal file
699
tools/ucon64/src/console/sms.c
Normal file
@@ -0,0 +1,699 @@
|
||||
/*
|
||||
sms.c - Sega Master System/Game Gear support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
Copyright (c) 2003 - 2004 dbjh
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <ctype.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <sys/stat.h>
|
||||
#include "misc/chksum.h"
|
||||
#include "misc/misc.h"
|
||||
#include "misc/string.h"
|
||||
#include "misc/file.h"
|
||||
#ifdef USE_ZLIB
|
||||
#include "misc/archive.h"
|
||||
#endif
|
||||
#include "misc/getopt2.h" // st_getopt2_t
|
||||
#include "ucon64.h"
|
||||
#include "ucon64_misc.h"
|
||||
#include "sms.h"
|
||||
#include "backup/mgd.h"
|
||||
#include "backup/smd.h"
|
||||
|
||||
|
||||
#define SMS_HEADER_START 0x7ff0
|
||||
#define SMS_HEADER_LEN (sizeof (st_sms_header_t))
|
||||
|
||||
static int sms_chksum (unsigned char *rom_buffer, int rom_size);
|
||||
|
||||
|
||||
const st_getopt2_t sms_usage[] =
|
||||
{
|
||||
{
|
||||
NULL, 0, 0, 0,
|
||||
NULL, "Sega Master System(II/III)/Game Gear (Handheld)"/*"1986/19XX SEGA http://www.sega.com"*/,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"sms", 0, 0, UCON64_SMS,
|
||||
NULL, "force recognition",
|
||||
&ucon64_wf[WF_OBJ_SMS_SWITCH]
|
||||
},
|
||||
{
|
||||
"int", 0, 0, UCON64_INT,
|
||||
NULL, "force ROM is in interleaved format (SMD)",
|
||||
&ucon64_wf[WF_OBJ_ALL_SWITCH]
|
||||
},
|
||||
{
|
||||
"nint", 0, 0, UCON64_NINT,
|
||||
NULL, "force ROM is not in interleaved format (RAW)",
|
||||
&ucon64_wf[WF_OBJ_ALL_SWITCH]
|
||||
},
|
||||
{
|
||||
"mgd", 0, 0, UCON64_MGD,
|
||||
NULL, "convert to Multi Game*/MGD2/MGH/RAW (gives SMS name)",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT_NO_SPLIT]
|
||||
},
|
||||
{
|
||||
"mgdgg", 0, 0, UCON64_MGDGG,
|
||||
NULL, "same as " OPTION_LONG_S "mgd, but gives GG name",
|
||||
&ucon64_wf[WF_OBJ_SMS_DEFAULT_NO_SPLIT]
|
||||
},
|
||||
{
|
||||
"smd", 0, 0, UCON64_SMD,
|
||||
NULL, "convert to Super Magic Drive/SMD",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT_NO_SPLIT]
|
||||
},
|
||||
{
|
||||
"smds", 0, 0, UCON64_SMDS,
|
||||
NULL, "convert emulator (*.srm) SRAM to Super Magic Drive/SMD",
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"chk", 0, 0, UCON64_CHK,
|
||||
NULL, "fix ROM checksum (SMS only)",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
|
||||
},
|
||||
{
|
||||
"multi", 1, 0, UCON64_MULTI,
|
||||
"SIZE", "make multi-game file for use with SMS-PRO/GG-PRO flash card,\n"
|
||||
"truncated to SIZE Mbit; file with loader must be specified\n"
|
||||
"first, then all the ROMs, multi-game file to create last",
|
||||
&ucon64_wf[WF_OBJ_ALL_INIT_PROBE_STOP]
|
||||
},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
typedef struct st_sms_header
|
||||
{
|
||||
char signature[8]; // "TMR "{"SEGA", "ALVS", "SMSC"}/"TMG SEGA"
|
||||
unsigned char pad[2]; // 8
|
||||
unsigned char checksum_low; // 10
|
||||
unsigned char checksum_high; // 11
|
||||
unsigned char partno_low; // 12
|
||||
unsigned char partno_high; // 13
|
||||
unsigned char version; // 14
|
||||
unsigned char checksum_range; // 15, and country info
|
||||
} st_sms_header_t;
|
||||
|
||||
static st_sms_header_t sms_header;
|
||||
static int is_gamegear;
|
||||
|
||||
|
||||
// see src/backup/mgd.h for the file naming scheme
|
||||
int
|
||||
sms_mgd (st_rominfo_t *rominfo, int console)
|
||||
{
|
||||
char src_name[FILENAME_MAX], dest_name[FILENAME_MAX];
|
||||
unsigned char *buffer;
|
||||
int size = ucon64.file_size - rominfo->buheader_len;
|
||||
|
||||
strcpy (src_name, ucon64.rom);
|
||||
mgd_make_name (ucon64.rom, console, size, dest_name);
|
||||
ucon64_file_handler (dest_name, src_name, OF_FORCE_BASENAME);
|
||||
|
||||
if (!(buffer = (unsigned char *) malloc (size)))
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], size);
|
||||
exit (1);
|
||||
}
|
||||
ucon64_fread (buffer, rominfo->buheader_len, size, src_name);
|
||||
if (rominfo->interleaved)
|
||||
smd_deinterleave (buffer, size);
|
||||
|
||||
ucon64_fwrite (buffer, 0, size, dest_name, "wb");
|
||||
free (buffer);
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
remove_temp_file ();
|
||||
|
||||
mgd_write_index_file ((char *) basename2 (dest_name), 1);
|
||||
|
||||
if (size <= 4 * MBIT)
|
||||
printf ("NOTE: It may be necessary to change the suffix in order to make the game work\n"
|
||||
" on an MGD2. You could try suffixes like .010, .024, .040, .048 or .078.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sms_smd (st_rominfo_t *rominfo)
|
||||
{
|
||||
st_smd_header_t header;
|
||||
char src_name[FILENAME_MAX], dest_name[FILENAME_MAX];
|
||||
unsigned char *buffer;
|
||||
int size = ucon64.file_size - rominfo->buheader_len;
|
||||
|
||||
memset (&header, 0, SMD_HEADER_LEN);
|
||||
header.size = size / 8192 >> 8;
|
||||
header.id0 = 3; //size / 8192;
|
||||
header.id1 = 0xaa;
|
||||
header.id2 = 0xbb;
|
||||
header.type = 6;
|
||||
|
||||
strcpy (src_name, ucon64.rom);
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
set_suffix (dest_name, ".smd");
|
||||
ucon64_file_handler (dest_name, src_name, 0);
|
||||
|
||||
if (!(buffer = (unsigned char *) malloc (size)))
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], size);
|
||||
exit (1);
|
||||
}
|
||||
ucon64_fread (buffer, rominfo->buheader_len, size, src_name);
|
||||
if (!rominfo->interleaved)
|
||||
smd_interleave (buffer, size);
|
||||
|
||||
ucon64_fwrite (&header, 0, SMD_HEADER_LEN, dest_name, "wb");
|
||||
ucon64_fwrite (buffer, rominfo->buheader_len, size, dest_name, "ab");
|
||||
free (buffer);
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
remove_temp_file ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sms_smds (void)
|
||||
{
|
||||
st_smd_header_t header;
|
||||
char src_name[FILENAME_MAX], dest_name[FILENAME_MAX];
|
||||
|
||||
memset (&header, 0, SMD_HEADER_LEN);
|
||||
header.id1 = 0xaa;
|
||||
header.id2 = 0xbb;
|
||||
header.type = 7; // SRAM file
|
||||
|
||||
strcpy (src_name, ucon64.rom);
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
set_suffix (dest_name, ".sav");
|
||||
ucon64_file_handler (dest_name, src_name, 0);
|
||||
|
||||
ucon64_fwrite (&header, 0, SMD_HEADER_LEN, dest_name, "wb");
|
||||
fcopy (src_name, 0, fsizeof (src_name), dest_name, "ab");
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
remove_temp_file ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sms_chk (st_rominfo_t *rominfo)
|
||||
{
|
||||
char buf[2], dest_name[FILENAME_MAX];
|
||||
int offset = rominfo->header_start + 10;
|
||||
|
||||
if (is_gamegear)
|
||||
{
|
||||
fprintf (stderr, "ERROR: This option works only for SMS (not Game Gear) files\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
|
||||
buf[0] = rominfo->current_internal_crc; // low byte
|
||||
buf[1] = rominfo->current_internal_crc >> 8; // high byte
|
||||
// change checksum
|
||||
if (rominfo->interleaved)
|
||||
{
|
||||
ucon64_fputc (dest_name, rominfo->buheader_len +
|
||||
(offset & ~0x3fff) + 0x2000 + (offset & 0x3fff) / 2, buf[0], "r+b");
|
||||
ucon64_fputc (dest_name, rominfo->buheader_len +
|
||||
(offset & ~0x3fff) + (offset & 0x3fff) / 2, buf[1], "r+b");
|
||||
}
|
||||
else
|
||||
ucon64_fwrite (buf, rominfo->buheader_len + offset, 2, dest_name, "r+b");
|
||||
|
||||
dumper (stdout, buf, 2, rominfo->buheader_len + offset, DUMPER_HEX);
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
write_game_table_entry (FILE *destfile, int file_no, int totalsize)
|
||||
{
|
||||
static int sram_page = 0, sram_msg_printed = 0;
|
||||
int n;
|
||||
unsigned char name[0x0c], flags = 0; // x, D (reserved), x, x, x, x, S1, S0
|
||||
const char *p;
|
||||
|
||||
fseek (destfile, 0x2000 + (file_no - 1) * 0x10, SEEK_SET);
|
||||
fputc (0xff, destfile); // 0x0 = 0xff
|
||||
|
||||
memset (name, ' ', 0x0c);
|
||||
p = basename2 (ucon64.rom);
|
||||
n = strlen (p);
|
||||
if (n > 0x0c)
|
||||
n = 0x0c;
|
||||
memcpy (name, p, n);
|
||||
for (n = 0; n < 0x0c; n++)
|
||||
{
|
||||
if (!isprint ((int) name[n]))
|
||||
name[n] = '.';
|
||||
else
|
||||
name[n] = toupper (name[n]); // loader only supports upper case characters
|
||||
}
|
||||
fwrite (name, 1, 0x0c, destfile); // 0x01 - 0x0c = name
|
||||
fputc (0, destfile); // 0x0d = 0
|
||||
fputc (totalsize / 16384, destfile); // 0x0e = bank code
|
||||
|
||||
if (sram_page > 3)
|
||||
{
|
||||
if (!sram_msg_printed)
|
||||
{
|
||||
puts ("NOTE: This ROM (and all following) will share SRAM with ROM 4");
|
||||
sram_msg_printed = 1;
|
||||
}
|
||||
sram_page = 3;
|
||||
}
|
||||
flags = sram_page++;
|
||||
|
||||
fputc (flags, destfile); // 0x1f = flags
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sms_multi (int truncate_size, char *fname)
|
||||
{
|
||||
#define BUFSIZE 0x20000
|
||||
// BUFSIZE must be a multiple of 16 kB (for deinterleaving) and larger than or
|
||||
// equal to 1 Mbit (for check sum calculation)
|
||||
int n, n_files, file_no, bytestowrite, byteswritten, totalsize = 0, done,
|
||||
truncated = 0, paddedsize, org_do_not_calc_crc = ucon64.do_not_calc_crc;
|
||||
struct stat fstate;
|
||||
FILE *srcfile, *destfile;
|
||||
char destname[FILENAME_MAX];
|
||||
unsigned char *buffer;
|
||||
|
||||
if (truncate_size == 0)
|
||||
{
|
||||
fprintf (stderr, "ERROR: Can't make multi-game file of 0 bytes\n");
|
||||
return -1;
|
||||
}
|
||||
if (!(buffer = (unsigned char *) malloc (BUFSIZE)))
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[FILE_BUFFER_ERROR], BUFSIZE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fname != NULL)
|
||||
{
|
||||
strcpy (destname, fname);
|
||||
n_files = ucon64.argc;
|
||||
}
|
||||
else
|
||||
{
|
||||
strcpy (destname, ucon64.argv[ucon64.argc - 1]);
|
||||
n_files = ucon64.argc - 1;
|
||||
}
|
||||
|
||||
ucon64_file_handler (destname, NULL, OF_FORCE_BASENAME);
|
||||
if ((destfile = fopen (destname, "w+b")) == NULL)
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], destname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf ("Creating multi-game file for SMS-PRO/GG-PRO: %s\n", destname);
|
||||
|
||||
file_no = 0;
|
||||
for (n = 1; n < n_files; n++)
|
||||
{
|
||||
if (access (ucon64.argv[n], F_OK))
|
||||
continue; // "file" does not exist (option)
|
||||
stat (ucon64.argv[n], &fstate);
|
||||
if (!S_ISREG (fstate.st_mode))
|
||||
continue;
|
||||
if (file_no == 32) // loader + 31 games
|
||||
{
|
||||
printf ("WARNING: A multi-game file can contain a maximum of 31 games. The other files\n"
|
||||
" are ignored.\n");
|
||||
break;
|
||||
}
|
||||
|
||||
ucon64.console = UCON64_UNKNOWN;
|
||||
ucon64.rom = ucon64.argv[n];
|
||||
ucon64.file_size = fsizeof (ucon64.rom);
|
||||
// DON'T use fstate.st_size, because file could be compressed
|
||||
ucon64.rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ?
|
||||
ucon64.buheader_len : 0;
|
||||
ucon64.rominfo->interleaved = UCON64_ISSET (ucon64.interleaved) ?
|
||||
ucon64.interleaved : 0;
|
||||
ucon64.do_not_calc_crc = 1;
|
||||
if (sms_init (ucon64.rominfo) != 0)
|
||||
printf ("WARNING: %s does not appear to be an SMS/GG ROM\n", ucon64.rom);
|
||||
|
||||
if ((srcfile = fopen (ucon64.rom, "rb")) == NULL)
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], ucon64.rom);
|
||||
continue;
|
||||
}
|
||||
if (ucon64.rominfo->buheader_len)
|
||||
fseek (srcfile, ucon64.rominfo->buheader_len, SEEK_SET);
|
||||
|
||||
if (file_no == 0)
|
||||
{
|
||||
printf ("Loader: %s\n", ucon64.rom);
|
||||
if (ucon64.file_size - ucon64.rominfo->buheader_len != 3 * 16384)
|
||||
printf ("WARNING: Are you sure %s is a loader binary?\n", ucon64.rom);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("ROM%d: %s\n", file_no, ucon64.rom);
|
||||
write_game_table_entry (destfile, file_no, totalsize);
|
||||
fseek (destfile, totalsize, SEEK_SET); // restore file pointer
|
||||
}
|
||||
file_no++;
|
||||
|
||||
done = 0;
|
||||
byteswritten = 0; // # of bytes written per file
|
||||
while (!done)
|
||||
{
|
||||
bytestowrite = fread (buffer, 1, BUFSIZE, srcfile);
|
||||
if (ucon64.rominfo->interleaved)
|
||||
smd_deinterleave (buffer, BUFSIZE);
|
||||
// yes, BUFSIZE. bytestowrite might not be n * 16 kB
|
||||
if (totalsize + bytestowrite > truncate_size)
|
||||
{
|
||||
bytestowrite = truncate_size - totalsize;
|
||||
done = 1;
|
||||
truncated = 1;
|
||||
printf ("Output file is %d Mbit, truncating %s, skipping %d bytes\n",
|
||||
truncate_size / MBIT, ucon64.rom, ucon64.file_size -
|
||||
ucon64.rominfo->buheader_len - (byteswritten + bytestowrite));
|
||||
}
|
||||
totalsize += bytestowrite;
|
||||
if (bytestowrite == 0)
|
||||
done = 1;
|
||||
fwrite (buffer, 1, bytestowrite, destfile);
|
||||
byteswritten += bytestowrite;
|
||||
}
|
||||
fclose (srcfile);
|
||||
if (truncated)
|
||||
break;
|
||||
|
||||
// games have to be aligned to (start at) a 16 kB boundary
|
||||
paddedsize = (totalsize + 16384 - 1) & ~(16384 - 1);
|
||||
// printf ("paddedsize: %d (%f); totalsize: %d (%f)\n",
|
||||
// paddedsize, paddedsize / (1.0 * MBIT), totalsize, totalsize / (1.0 * MBIT));
|
||||
if (paddedsize > totalsize)
|
||||
{
|
||||
if (paddedsize > truncate_size)
|
||||
{
|
||||
truncated = 1; // not *really* truncated
|
||||
paddedsize = truncate_size;
|
||||
}
|
||||
|
||||
memset (buffer, 0, BUFSIZE);
|
||||
while (totalsize < paddedsize)
|
||||
{
|
||||
bytestowrite = paddedsize - totalsize > BUFSIZE ?
|
||||
BUFSIZE : paddedsize - totalsize;
|
||||
fwrite (buffer, 1, bytestowrite, destfile);
|
||||
totalsize += bytestowrite;
|
||||
}
|
||||
}
|
||||
if (truncated)
|
||||
break;
|
||||
}
|
||||
// fill the next game table entry
|
||||
fseek (destfile, 0x2000 + (file_no - 1) * 0x10, SEEK_SET);
|
||||
fputc (0, destfile); // indicate no next game
|
||||
|
||||
/*
|
||||
The SMS requires the check sum to match the data. The ToToTEK loaders have
|
||||
the lower nibble of the "check sum range byte" set to 0x0f. Maybe ToToTEK
|
||||
will change this or maybe somebody else will write a loader. To avoid extra
|
||||
code to handle those cases we just overwite the value.
|
||||
We don't handle a GG multi-game file differently, because we cannot detect
|
||||
that the user intended to make such a file (other than by adding a new GG
|
||||
multi-game option). ToToTEK's GG loader has an SMS header.
|
||||
*/
|
||||
fseek (destfile, 0, SEEK_SET);
|
||||
n = fread (buffer, 1, 0x20000, destfile); // 0x0f => check sum range = 0x20000
|
||||
buffer[SMS_HEADER_START + 15] |= 0x0f; // overwrite check sum range byte
|
||||
sms_header.checksum_range = 0x0f; // sms_chksum() uses this variable
|
||||
n = sms_chksum (buffer, n);
|
||||
|
||||
buffer[SMS_HEADER_START + 10] = n; // low byte
|
||||
buffer[SMS_HEADER_START + 11] = n >> 8; // high byte
|
||||
fseek (destfile, SMS_HEADER_START + 10, SEEK_SET);
|
||||
fwrite (buffer + SMS_HEADER_START + 10, 1, 6, destfile);
|
||||
|
||||
fclose (destfile);
|
||||
ucon64.console = UCON64_SMS;
|
||||
ucon64.do_not_calc_crc = org_do_not_calc_crc;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
sms_testinterleaved (st_rominfo_t *rominfo)
|
||||
{
|
||||
unsigned char buf[0x4000] = { 0 };
|
||||
|
||||
ucon64_fread (buf, rominfo->buheader_len + 0x4000, // header in 2nd 16 kB block
|
||||
0x2000 + (SMS_HEADER_START - 0x4000 + 8) / 2, ucon64.rom);
|
||||
if (!(memcmp (buf + SMS_HEADER_START - 0x4000, "TMR SEGA", 8) &&
|
||||
memcmp (buf + SMS_HEADER_START - 0x4000, "TMR ALVS", 8) && // SMS
|
||||
memcmp (buf + SMS_HEADER_START - 0x4000, "TMR SMSC", 8) && // SMS (unofficial)
|
||||
memcmp (buf + SMS_HEADER_START - 0x4000, "TMG SEGA", 8))) // GG
|
||||
return 0;
|
||||
|
||||
smd_deinterleave (buf, 0x4000);
|
||||
if (!(memcmp (buf + SMS_HEADER_START - 0x4000, "TMR SEGA", 8) &&
|
||||
memcmp (buf + SMS_HEADER_START - 0x4000, "TMR ALVS", 8) &&
|
||||
memcmp (buf + SMS_HEADER_START - 0x4000, "TMR SMSC", 8) &&
|
||||
memcmp (buf + SMS_HEADER_START - 0x4000, "TMG SEGA", 8)))
|
||||
return 1;
|
||||
|
||||
return 0; // unknown, act as if it's not interleaved
|
||||
}
|
||||
|
||||
|
||||
#define SEARCHBUFSIZE (SMS_HEADER_START + 8 + 16 * 1024)
|
||||
#define N_SEARCH_STR 4
|
||||
static int
|
||||
sms_header_len (void)
|
||||
/*
|
||||
At first sight it seems reasonable to also determine whether the file is
|
||||
interleaved in this function. However, we run into a chicken-and-egg problem:
|
||||
in order to deinterleave the data we have to know the header length. And in
|
||||
order to determine the header length we have to know whether the file is
|
||||
interleaved :-) Of course we could assume the header has an even size, but it
|
||||
turns out that that is not always the case. For example, there is a copy of
|
||||
GG Shinobi (E) [b1] floating around with a "header" of 5 bytes.
|
||||
In short: this function works only for files that are not interleaved.
|
||||
*/
|
||||
{
|
||||
// first two hacks for Majesco Game Gear BIOS (U) [!]
|
||||
if (ucon64.file_size == 1024)
|
||||
return 0;
|
||||
else if (ucon64.file_size == 1024 + SMD_HEADER_LEN)
|
||||
return SMD_HEADER_LEN;
|
||||
else
|
||||
{
|
||||
char buffer[SEARCHBUFSIZE], *ptr, search_str[N_SEARCH_STR][9] =
|
||||
{ "TMR SEGA", "TMR ALVS", "TMR SMSC", "TMG SEGA" };
|
||||
int n;
|
||||
|
||||
ucon64_fread (buffer, 0, SEARCHBUFSIZE, ucon64.rom);
|
||||
|
||||
for (n = 0; n < N_SEARCH_STR; n++)
|
||||
if ((ptr = (char *)
|
||||
memmem2 (buffer, SEARCHBUFSIZE, search_str[n], 8, 0)) != NULL)
|
||||
return ptr - buffer - SMS_HEADER_START;
|
||||
|
||||
n = ucon64.file_size % (16 * 1024); // SMD_HEADER_LEN
|
||||
if (ucon64.file_size > n)
|
||||
return n;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#undef SEARCHBUFSIZE
|
||||
#undef N_SEARCH_STR
|
||||
|
||||
|
||||
int
|
||||
sms_init (st_rominfo_t *rominfo)
|
||||
{
|
||||
int result = -1, x;
|
||||
unsigned char buf[16384] = { 0 }, *rom_buffer;
|
||||
|
||||
is_gamegear = 0;
|
||||
memset (&sms_header, 0, SMS_HEADER_LEN);
|
||||
|
||||
if (UCON64_ISSET (ucon64.buheader_len)) // -hd, -nhd or -hdn option was specified
|
||||
rominfo->buheader_len = ucon64.buheader_len;
|
||||
else
|
||||
rominfo->buheader_len = sms_header_len ();
|
||||
|
||||
rominfo->interleaved = UCON64_ISSET (ucon64.interleaved) ?
|
||||
ucon64.interleaved : sms_testinterleaved (rominfo);
|
||||
|
||||
if (rominfo->interleaved)
|
||||
{
|
||||
ucon64_fread (buf, rominfo->buheader_len + 0x4000, // header in 2nd 16 kB block
|
||||
0x2000 + (SMS_HEADER_START - 0x4000 + SMS_HEADER_LEN) / 2, ucon64.rom);
|
||||
smd_deinterleave (buf, 0x4000);
|
||||
memcpy (&sms_header, buf + SMS_HEADER_START - 0x4000, SMS_HEADER_LEN);
|
||||
}
|
||||
else
|
||||
ucon64_fread (&sms_header, rominfo->buheader_len + SMS_HEADER_START,
|
||||
SMS_HEADER_LEN, ucon64.rom);
|
||||
|
||||
rominfo->header_start = SMS_HEADER_START;
|
||||
rominfo->header_len = SMS_HEADER_LEN;
|
||||
rominfo->header = &sms_header;
|
||||
|
||||
ucon64_fread (buf, 0, 11, ucon64.rom);
|
||||
// Note that the identification bytes are the same as for Genesis SMD files
|
||||
// The init function for Genesis files is called before this function so it
|
||||
// is alright to set result to 0
|
||||
if ((buf[8] == 0xaa && buf[9] == 0xbb && buf[10] == 6) ||
|
||||
!(memcmp (sms_header.signature, "TMR SEGA", 8) &&
|
||||
memcmp (sms_header.signature, "TMR ALVS", 8) && // SMS
|
||||
memcmp (sms_header.signature, "TMR SMSC", 8) && // SMS (unofficial)
|
||||
memcmp (sms_header.signature, "TMG SEGA", 8)) || // GG
|
||||
ucon64.console == UCON64_SMS)
|
||||
result = 0;
|
||||
else
|
||||
result = -1;
|
||||
|
||||
x = sms_header.checksum_range & 0xf0;
|
||||
if (x == 0x50 || x == 0x60 || x == 0x70)
|
||||
is_gamegear = 1;
|
||||
|
||||
switch (x)
|
||||
{
|
||||
case 0x30: // SMS, falling through
|
||||
case 0x50: // GG
|
||||
rominfo->country = "Japan";
|
||||
break;
|
||||
case 0x40: // SMS, falling through
|
||||
case 0x70: // GG
|
||||
rominfo->country = "U.S.A. & Europe";
|
||||
break;
|
||||
case 0x60: // GG
|
||||
rominfo->country = "Japan, U.S.A. & Europe";
|
||||
break;
|
||||
default:
|
||||
rominfo->country = "Unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
if (!UCON64_ISSET (ucon64.do_not_calc_crc) && result == 0)
|
||||
{
|
||||
int size = ucon64.file_size - rominfo->buheader_len;
|
||||
if (!(rom_buffer = (unsigned char *) malloc (size)))
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], size);
|
||||
return -1;
|
||||
}
|
||||
ucon64_fread (rom_buffer, rominfo->buheader_len, size, ucon64.rom);
|
||||
|
||||
if (rominfo->interleaved)
|
||||
{
|
||||
ucon64.fcrc32 = crc32 (0, rom_buffer, size);
|
||||
smd_deinterleave (rom_buffer, size);
|
||||
}
|
||||
ucon64.crc32 = crc32 (0, rom_buffer, size);
|
||||
|
||||
if (!is_gamegear)
|
||||
{
|
||||
rominfo->has_internal_crc = 1;
|
||||
rominfo->internal_crc_len = 2;
|
||||
rominfo->current_internal_crc = sms_chksum (rom_buffer, size);
|
||||
rominfo->internal_crc = sms_header.checksum_low;
|
||||
rominfo->internal_crc += sms_header.checksum_high << 8;
|
||||
}
|
||||
|
||||
free (rom_buffer);
|
||||
}
|
||||
|
||||
sprintf ((char *) buf, "Part number: 0x%04x\n",
|
||||
sms_header.partno_low + (sms_header.partno_high << 8) +
|
||||
((sms_header.version & 0xf0) << 12));
|
||||
strcat (rominfo->misc, (char *) buf);
|
||||
|
||||
sprintf ((char *) buf, "Version: %d", sms_header.version & 0xf);
|
||||
strcat (rominfo->misc, (char *) buf);
|
||||
|
||||
rominfo->console_usage = sms_usage[0].help;
|
||||
rominfo->copier_usage = rominfo->buheader_len ? smd_usage[0].help : mgd_usage[0].help;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
sms_chksum (unsigned char *rom_buffer, int rom_size)
|
||||
{
|
||||
unsigned short int sum;
|
||||
int i, i_end;
|
||||
|
||||
switch (sms_header.checksum_range & 0xf)
|
||||
{
|
||||
case 0xc:
|
||||
i_end = 0x7ff0;
|
||||
break;
|
||||
case 0xe: // falling through
|
||||
case 0xf:
|
||||
i_end = 0x20000;
|
||||
break;
|
||||
case 0:
|
||||
i_end = 0x40000;
|
||||
break;
|
||||
case 1:
|
||||
i_end = 0x80000;
|
||||
break;
|
||||
default:
|
||||
i_end = rom_size;
|
||||
break;
|
||||
}
|
||||
if (i_end > rom_size)
|
||||
i_end = rom_size;
|
||||
|
||||
sum = 0;
|
||||
for (i = 0; i < i_end; i++)
|
||||
sum += rom_buffer[i];
|
||||
|
||||
if (i_end >= (int) (SMS_HEADER_START + SMS_HEADER_LEN))
|
||||
for (i = SMS_HEADER_START; i < (int) (SMS_HEADER_START + SMS_HEADER_LEN); i++)
|
||||
sum -= rom_buffer[i];
|
||||
|
||||
return sum;
|
||||
}
|
||||
36
tools/ucon64/src/console/sms.h
Normal file
36
tools/ucon64/src/console/sms.h
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
sms.h - Sega Master System/Game Gear support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
Copyright (c) 2003 - 2004 dbjh
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef SMS_H
|
||||
#define SMS_H
|
||||
|
||||
extern const st_getopt2_t sms_usage[];
|
||||
|
||||
extern int sms_gg (st_rominfo_t *rominfo);
|
||||
extern int sms_ggd (st_rominfo_t *rominfo);
|
||||
extern int sms_gge (st_rominfo_t *rominfo);
|
||||
extern int sms_init (st_rominfo_t *rominfo);
|
||||
extern int sms_mgd (st_rominfo_t *rominfo, int console);
|
||||
extern int sms_smd (st_rominfo_t *rominfo);
|
||||
extern int sms_smds (void);
|
||||
extern int sms_chk (st_rominfo_t *rominfo);
|
||||
extern int sms_multi (int truncate_size, char *fname);
|
||||
#endif
|
||||
4404
tools/ucon64/src/console/snes.c
Normal file
4404
tools/ucon64/src/console/snes.c
Normal file
File diff suppressed because it is too large
Load Diff
65
tools/ucon64/src/console/snes.h
Normal file
65
tools/ucon64/src/console/snes.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
snes.h - Super NES support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
Copyright (c) 2001 - 2004 dbjh
|
||||
Copyright (c) 2002 - 2003 John Weidman
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef SNES_H
|
||||
#define SNES_H
|
||||
|
||||
#include "backup/fig.h" // for st_fig_header_t
|
||||
|
||||
#define SNES_HEADER_START 0x7fb0
|
||||
#define SNES_HIROM 0x8000
|
||||
#define SNES_EROM 0x400000 // "Extended" ROM, Hi or Lo
|
||||
|
||||
typedef enum { SWC = 1, GD3, UFO, FIG, MGD_SNES, SMC } snes_file_t;
|
||||
|
||||
extern const st_getopt2_t snes_usage[];
|
||||
|
||||
extern snes_file_t snes_get_file_type (void);
|
||||
extern int snes_buheader_info (st_rominfo_t *rominfo);
|
||||
extern int snes_chk (st_rominfo_t *rominfo);
|
||||
extern int snes_col (const char *color);
|
||||
extern int snes_demirror (st_rominfo_t *rominfo);
|
||||
extern int snes_densrt (st_rominfo_t *rominfo);
|
||||
extern int snes_dint (st_rominfo_t *rominfo);
|
||||
extern int snes_f (st_rominfo_t *rominfo);
|
||||
extern int snes_fig (st_rominfo_t *rominfo);
|
||||
extern int snes_figs (st_rominfo_t *rominfo);
|
||||
extern int snes_gd3 (st_rominfo_t *rominfo);
|
||||
extern int snes_gd3s (st_rominfo_t *rominfo);
|
||||
extern int snes_get_snes_hirom (void);
|
||||
extern int snes_init (st_rominfo_t *rominfo);
|
||||
extern int snes_j (st_rominfo_t *rominfo);
|
||||
extern int snes_k (st_rominfo_t *rominfo);
|
||||
extern int snes_l (st_rominfo_t *rominfo);
|
||||
extern int snes_make_gd_names (const char *filename, st_rominfo_t *rominfo, char **names);
|
||||
extern int snes_mgd (st_rominfo_t *rominfo);
|
||||
extern int snes_mgh (st_rominfo_t *rominfo);
|
||||
extern int snes_multi (int truncate_size, char *fname);
|
||||
extern int snes_n (st_rominfo_t *rominfo, const char *name);
|
||||
extern int snes_s (st_rominfo_t *rominfo);
|
||||
extern void snes_set_fig_header (st_rominfo_t *rominfo, st_fig_header_t *header);
|
||||
extern int snes_smc (st_rominfo_t *rominfo);
|
||||
extern int snes_swc (st_rominfo_t *rominfo);
|
||||
extern int snes_swcs (st_rominfo_t *rominfo);
|
||||
extern int snes_ufo (st_rominfo_t *rominfo);
|
||||
extern int snes_ufos (st_rominfo_t *rominfo);
|
||||
#endif // SNES_H
|
||||
206
tools/ucon64/src/console/swan.c
Normal file
206
tools/ucon64/src/console/swan.c
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
swan.c - WonderSwan support for uCON64
|
||||
|
||||
Copyright (c) 1999 - 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "misc/misc.h"
|
||||
#include "misc/file.h"
|
||||
#ifdef USE_ZLIB
|
||||
#include "misc/archive.h"
|
||||
#endif
|
||||
#include "misc/getopt2.h" // st_getopt2_t
|
||||
#include "ucon64.h"
|
||||
#include "ucon64_misc.h"
|
||||
#include "swan.h"
|
||||
|
||||
|
||||
static int swan_chksum (unsigned char *rom_buffer);
|
||||
|
||||
const st_getopt2_t swan_usage[] =
|
||||
{
|
||||
{
|
||||
NULL, 0, 0, 0,
|
||||
NULL, "WonderSwan/WonderSwan Color/SwanCrystal"/*"19XX/19XX/2002 Bandai"*/,
|
||||
NULL
|
||||
},
|
||||
{
|
||||
"swan", 0, 0, UCON64_SWAN,
|
||||
NULL, "force recognition",
|
||||
&ucon64_wf[WF_OBJ_SWAN_SWITCH]
|
||||
},
|
||||
{
|
||||
"chk", 0, 0, UCON64_CHK,
|
||||
NULL, "fix ROM checksum",
|
||||
&ucon64_wf[WF_OBJ_ALL_DEFAULT]
|
||||
},
|
||||
{NULL, 0, 0, 0, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
||||
typedef struct st_swan_header
|
||||
{
|
||||
char pad[10];
|
||||
} st_swan_header_t;
|
||||
#define SWAN_HEADER_START (ucon64.file_size - 10)
|
||||
#define SWAN_HEADER_LEN (sizeof (st_swan_header_t))
|
||||
|
||||
st_swan_header_t swan_header;
|
||||
|
||||
|
||||
int
|
||||
swan_chk (st_rominfo_t *rominfo)
|
||||
{
|
||||
char buf[3], dest_name[FILENAME_MAX];
|
||||
|
||||
strcpy (dest_name, ucon64.rom);
|
||||
ucon64_file_handler (dest_name, NULL, 0);
|
||||
fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
|
||||
|
||||
ucon64_fputc (dest_name, SWAN_HEADER_START + 8, rominfo->current_internal_crc, "r+b"); // low byte
|
||||
ucon64_fputc (dest_name, SWAN_HEADER_START + 9, rominfo->current_internal_crc >> 8, "r+b"); // high byte
|
||||
|
||||
ucon64_fread (buf, SWAN_HEADER_START + 8, 2, dest_name);
|
||||
dumper (stdout, buf, 2, SWAN_HEADER_START + 8, DUMPER_HEX);
|
||||
|
||||
printf (ucon64_msg[WROTE], dest_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Byte2 - Cartridge ID number for this developer
|
||||
|
||||
Byte3 - ?Unknown?
|
||||
00 - most roms
|
||||
01 - Dig2/BAN032 & soro/KGT007
|
||||
02 - Chocobo/BAN002
|
||||
03 - sdej/BAN006
|
||||
04 - srv2/BPR006
|
||||
|
||||
Byte4 - ROM Size:
|
||||
01 - ?
|
||||
02 - 4Mbit
|
||||
03 - 8Mbit
|
||||
04 - 16Mbit
|
||||
05 - ?
|
||||
06 - 32Mbit
|
||||
07 - ?
|
||||
08 - ?
|
||||
09 - 128Mbit
|
||||
|
||||
Byte5 - SRAM/EEPROM Size:
|
||||
00 - 0k
|
||||
01 - 64k SRAM
|
||||
02 - 256k SRAM
|
||||
10 - 1k EEPROM (MGH001/NAP001)
|
||||
20 - 16k EEPROM
|
||||
|
||||
Byte6 - Additional capabilities(?)
|
||||
04 - ?? game played in "horizontal" position (most roms)
|
||||
05 - ?? game played in "vertical" position
|
||||
10 - ?? (SUN003)
|
||||
*/
|
||||
int
|
||||
swan_init (st_rominfo_t *rominfo)
|
||||
{
|
||||
int result = -1;
|
||||
unsigned char *rom_buffer, buf[MAXBUFSIZE];
|
||||
#define SWAN_MAKER_MAX 0x30
|
||||
const char *swan_maker[SWAN_MAKER_MAX] =
|
||||
{
|
||||
"BAN", "BAN", NULL, NULL, NULL,
|
||||
"DTE", NULL, NULL, NULL, NULL,
|
||||
NULL, "SUM", "SUM", NULL, "BPR",
|
||||
NULL, NULL, NULL, "KNM", NULL,
|
||||
NULL, NULL, "KGT", NULL, NULL,
|
||||
NULL, NULL, "MGH", NULL, "BEC",
|
||||
"NAP", "BVL", NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, "KDK", NULL,
|
||||
"SQR", NULL, NULL, NULL, NULL,
|
||||
"NMC", NULL, NULL
|
||||
};
|
||||
|
||||
rominfo->buheader_len = UCON64_ISSET (ucon64.buheader_len) ? ucon64.buheader_len : 0;
|
||||
|
||||
ucon64_fread (&swan_header, SWAN_HEADER_START + rominfo->buheader_len,
|
||||
SWAN_HEADER_LEN, ucon64.rom);
|
||||
|
||||
rominfo->header = &swan_header;
|
||||
rominfo->header_start = SWAN_HEADER_START;
|
||||
rominfo->header_len = SWAN_HEADER_LEN;
|
||||
|
||||
// ROM maker
|
||||
rominfo->maker = NULL_TO_UNKNOWN_S (swan_maker[MIN (OFFSET (swan_header, 0),
|
||||
SWAN_MAKER_MAX - 1)]);
|
||||
|
||||
// misc stuff
|
||||
sprintf ((char *) buf, "Minimum supported system: %s",
|
||||
(!OFFSET (swan_header, 1) ? "WS Monochrome" : "WS Color"));
|
||||
strcat (rominfo->misc, (const char *) buf);
|
||||
|
||||
if (!(rom_buffer = (unsigned char *) malloc (ucon64.file_size)))
|
||||
{
|
||||
fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], ucon64.file_size);
|
||||
return -1;
|
||||
}
|
||||
ucon64_fread (rom_buffer, 0, ucon64.file_size, ucon64.rom);
|
||||
|
||||
rominfo->has_internal_crc = 1;
|
||||
rominfo->internal_crc_len = 2;
|
||||
|
||||
if (ucon64.file_size > 10) // header itself is already 10 bytes
|
||||
{
|
||||
rominfo->current_internal_crc = swan_chksum (rom_buffer);
|
||||
rominfo->internal_crc = OFFSET (swan_header, 8); // low byte of checksum
|
||||
rominfo->internal_crc += OFFSET (swan_header, 9) << 8; // high byte of checksum
|
||||
if (rominfo->current_internal_crc == rominfo->internal_crc)
|
||||
result = 0;
|
||||
else
|
||||
result = -1;
|
||||
}
|
||||
if (ucon64.console == UCON64_SWAN)
|
||||
result = 0;
|
||||
|
||||
rominfo->console_usage = swan_usage[0].help;
|
||||
rominfo->copier_usage = unknown_usage[0].help;
|
||||
|
||||
free (rom_buffer);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
swan_chksum (unsigned char *ptr)
|
||||
{
|
||||
unsigned int csum = 0, t;
|
||||
|
||||
if (ucon64.file_size % 4)
|
||||
return -1;
|
||||
|
||||
t = ucon64.file_size - 2;
|
||||
while (t-- > 0)
|
||||
csum += *ptr++;
|
||||
|
||||
return csum & 0xffff;
|
||||
}
|
||||
27
tools/ucon64/src/console/swan.h
Normal file
27
tools/ucon64/src/console/swan.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
swan.h - WonderSwan support for uCON64
|
||||
|
||||
Copyright (c) 2001 NoisyB <noisyb@gmx.net>
|
||||
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
#ifndef WSWAN_H
|
||||
#define WSWAN_H
|
||||
|
||||
extern int swan_init (st_rominfo_t *rominfo);
|
||||
extern const st_getopt2_t swan_usage[];
|
||||
extern int swan_chk (st_rominfo_t *rominfo);
|
||||
#endif
|
||||
Reference in New Issue
Block a user