diff --git a/stella/Makefile b/stella/Makefile index 4baab5017..870be5acb 100644 --- a/stella/Makefile +++ b/stella/Makefile @@ -13,7 +13,7 @@ ## See the file "license" for information on usage and redistribution of ## this file, and for a DISCLAIMER OF ALL WARRANTIES. ## -## $Id: Makefile,v 1.23 2006-03-19 20:57:54 stephena Exp $ +## $Id: Makefile,v 1.24 2006-06-09 02:45:11 urchlay Exp $ ## ## Based on code from ScummVM - Scumm Interpreter ## Copyright (C) 2002-2004 The ScummVM project @@ -68,7 +68,7 @@ endif EXECUTABLE := stella$(EXEEXT) -all: $(EXECUTABLE) +all: tags $(EXECUTABLE) ###################################################################### @@ -250,3 +250,8 @@ gp2x-organize: cp -v -r $(srcdir)/docs/* $(srcdir)/gp2x/docs .PHONY: deb bundle test win32dist install uninstall + +# Use Exuberant ctags (the one from Slackware's vim package, for instance), +# not the one from emacs! +tags: + ctags `find . -name '*.[ch]xx' -o -name '*.c' -o -name '*.y'` || true diff --git a/stella/src/common/SoundSDL.cxx b/stella/src/common/SoundSDL.cxx index 5f3f28222..9e520cf19 100644 --- a/stella/src/common/SoundSDL.cxx +++ b/stella/src/common/SoundSDL.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: SoundSDL.cxx,v 1.29 2006-03-06 02:26:16 stephena Exp $ +// $Id: SoundSDL.cxx,v 1.30 2006-06-09 02:45:11 urchlay Exp $ //============================================================================ #ifdef SOUND_SUPPORT @@ -131,14 +131,14 @@ void SoundSDL::initialize() myIsMuted = false; myFragmentSizeLogBase2 = log((double)myHardwareSpec.samples) / log(2.0); -/* + /* cerr << "Freq: " << (int)myHardwareSpec.freq << endl; cerr << "Format: " << (int)myHardwareSpec.format << endl; cerr << "Channels: " << (int)myHardwareSpec.channels << endl; cerr << "Silence: " << (int)myHardwareSpec.silence << endl; cerr << "Samples: " << (int)myHardwareSpec.samples << endl; cerr << "Size: " << (int)myHardwareSpec.size << endl; -*/ + */ // Now initialize the TIASound object which will actually generate sound myTIASound.outputFrequency(myHardwareSpec.freq); diff --git a/stella/src/debugger/Equate.hxx b/stella/src/debugger/Equate.hxx index b83a8d710..3f2254f15 100644 --- a/stella/src/debugger/Equate.hxx +++ b/stella/src/debugger/Equate.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Equate.hxx,v 1.3 2005-06-21 18:46:33 stephena Exp $ +// $Id: Equate.hxx,v 1.4 2006-06-09 02:45:11 urchlay Exp $ //============================================================================ #ifndef EQUATE_HXX @@ -21,9 +21,24 @@ #include "bspf.hxx" +const int EQF_READ = 1; // Address can be read from +const int EQF_WRITE = 2; // Address can be written to +const int EQF_USER = 4; // Equate is user-defined, not built-in + +// When used in a search, EQF_ANY matches any type of label +const int EQF_ANY = 0; + +// When used in a search, EQF_ROM matches only ROM addresses, +// and EQF_RAM only matches RAM addresses. Both RAM and ROM addresses +// are by definition user-defined, since the built-in equates are +// for the TIA and RIOT only. +const int EQF_ROM = EQF_READ | EQF_USER; +const int EQF_RAM = EQF_WRITE | EQF_READ | EQF_USER; + struct Equate { - char *label; + string label; int address; + int flags; }; #endif diff --git a/stella/src/debugger/EquateList.cxx b/stella/src/debugger/EquateList.cxx index 0b3718c31..72125618b 100644 --- a/stella/src/debugger/EquateList.cxx +++ b/stella/src/debugger/EquateList.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: EquateList.cxx,v 1.21 2005-12-19 02:19:48 stephena Exp $ +// $Id: EquateList.cxx,v 1.22 2006-06-09 02:45:11 urchlay Exp $ //============================================================================ #include @@ -25,75 +25,177 @@ // built in labels static Equate hardCodedEquates[] = { - { "VSYNC", 0x00 }, - { "VBLANK", 0x01 }, - { "WSYNC", 0x02 }, - { "RSYNC", 0x03 }, - { "NUSIZ0", 0x04 }, - { "NUSIZ1", 0x05 }, - { "COLUP0", 0x06 }, - { "COLUP1", 0x07 }, - { "COLUPF", 0x08 }, - { "COLUBK", 0x09 }, - { "CTRLPF", 0x0A }, - { "REFP0", 0x0B }, - { "REFP1", 0x0C }, - { "PF0", 0x0D }, - { "PF1", 0x0E }, - { "PF2", 0x0F }, - { "RESP0", 0x10 }, - { "RESP1", 0x11 }, - { "RESM0", 0x12 }, - { "RESM1", 0x13 }, - { "RESBL", 0x14 }, - { "AUDC0", 0x15 }, - { "AUDC1", 0x16 }, - { "AUDF0", 0x17 }, - { "AUDF1", 0x18 }, - { "AUDV0", 0x19 }, - { "AUDV1", 0x1A }, - { "GRP0", 0x1B }, - { "GRP1", 0x1C }, - { "ENAM0", 0x1D }, - { "ENAM1", 0x1E }, - { "ENABL", 0x1F }, - { "HMP0", 0x20 }, - { "HMP1", 0x21 }, - { "HMM0", 0x22 }, - { "HMM1", 0x23 }, - { "HMBL", 0x24 }, - { "VDELP0", 0x25 }, - { "VDEL01", 0x26 }, - { "VDELP1", 0x26 }, - { "VDELBL", 0x27 }, - { "RESMP0", 0x28 }, - { "RESMP1", 0x29 }, - { "HMOVE", 0x2A }, - { "HMCLR", 0x2B }, - { "CXCLR", 0x2C }, - { "CXM0P", 0x30 }, - { "CXM1P", 0x31 }, - { "CXP0FB", 0x32 }, - { "CXP1FB", 0x33 }, - { "CXM0FB", 0x34 }, - { "CXM1FB", 0x35 }, - { "CXBLPF", 0x36 }, - { "CXPPMM", 0x37 }, - { "INPT0", 0x38 }, - { "INPT1", 0x39 }, - { "INPT2", 0x3A }, - { "INPT3", 0x3B }, - { "INPT4", 0x3C }, - { "INPT5", 0x3D }, - { "SWCHA", 0x0280 }, - { "SWCHB", 0x0282 }, - { "SWACNT", 0x281 }, - { "SWBCNT", 0x283 }, - { "INTIM", 0x0284 }, - { "TIM1T", 0x0294 }, - { "TIM8T", 0x0295 }, - { "TIM64T", 0x0296 }, - { "TIM1024T", 0x0297 } + +// Standard $00-based TIA write locations: + { "VSYNC", 0x00, EQF_WRITE }, + { "VBLANK", 0x01, EQF_WRITE }, + { "WSYNC", 0x02, EQF_WRITE }, + { "RSYNC", 0x03 , EQF_WRITE }, + { "NUSIZ0", 0x04, EQF_WRITE }, + { "NUSIZ1", 0x05, EQF_WRITE }, + { "COLUP0", 0x06, EQF_WRITE }, + { "COLUP1", 0x07, EQF_WRITE }, + { "COLUPF", 0x08, EQF_WRITE }, + { "COLUBK", 0x09, EQF_WRITE }, + { "CTRLPF", 0x0A, EQF_WRITE }, + { "REFP0", 0x0B, EQF_WRITE }, + { "REFP1", 0x0C, EQF_WRITE }, + { "PF0", 0x0D, EQF_WRITE }, + { "PF1", 0x0E, EQF_WRITE }, + { "PF2", 0x0F, EQF_WRITE }, + { "RESP0", 0x10, EQF_WRITE }, + { "RESP1", 0x11, EQF_WRITE }, + { "RESM0", 0x12, EQF_WRITE }, + { "RESM1", 0x13, EQF_WRITE }, + { "RESBL", 0x14, EQF_WRITE }, + { "AUDC0", 0x15, EQF_WRITE }, + { "AUDC1", 0x16, EQF_WRITE }, + { "AUDF0", 0x17, EQF_WRITE }, + { "AUDF1", 0x18, EQF_WRITE }, + { "AUDV0", 0x19, EQF_WRITE }, + { "AUDV1", 0x1A , EQF_WRITE }, + { "GRP0", 0x1B, EQF_WRITE }, + { "GRP1", 0x1C, EQF_WRITE }, + { "ENAM0", 0x1D, EQF_WRITE }, + { "ENAM1", 0x1E, EQF_WRITE }, + { "ENABL", 0x1F, EQF_WRITE }, + { "HMP0", 0x20, EQF_WRITE }, + { "HMP1", 0x21, EQF_WRITE }, + { "HMM0", 0x22, EQF_WRITE }, + { "HMM1", 0x23, EQF_WRITE }, + { "HMBL", 0x24, EQF_WRITE }, + { "VDELP0", 0x25, EQF_WRITE }, + { "VDEL01", 0x26, EQF_WRITE }, + { "VDELP1", 0x26, EQF_WRITE }, + { "VDELBL", 0x27, EQF_WRITE }, + { "RESMP0", 0x28, EQF_WRITE }, + { "RESMP1", 0x29, EQF_WRITE }, + { "HMOVE", 0x2A, EQF_WRITE }, + { "HMCLR", 0x2B, EQF_WRITE }, + { "CXCLR", 0x2C, EQF_WRITE }, + +// Mirrored $30-based TIA write locations: + { "VSYNC.30", 0x30, EQF_WRITE }, + { "VBLANK.30", 0x31, EQF_WRITE }, + { "WSYNC.30", 0x32, EQF_WRITE }, + { "RSYNC.30", 0x33 , EQF_WRITE }, + { "NUSIZ0.30", 0x34, EQF_WRITE }, + { "NUSIZ1.30", 0x35, EQF_WRITE }, + { "COLUP0.30", 0x36, EQF_WRITE }, + { "COLUP1.30", 0x37, EQF_WRITE }, + { "COLUPF.30", 0x38, EQF_WRITE }, + { "COLUBK.30", 0x39, EQF_WRITE }, + { "CTRLPF.30", 0x3A, EQF_WRITE }, + { "REFP0.30", 0x3B, EQF_WRITE }, + { "REFP1.30", 0x3C, EQF_WRITE }, + { "PF0.30", 0x3D, EQF_WRITE }, + { "PF1.30", 0x3E, EQF_WRITE }, + { "PF2.30", 0x3F, EQF_WRITE }, + { "RESP0.30", 0x40, EQF_WRITE }, + { "RESP1.30", 0x41, EQF_WRITE }, + { "RESM0.30", 0x42, EQF_WRITE }, + { "RESM1.30", 0x43, EQF_WRITE }, + { "RESBL.30", 0x44, EQF_WRITE }, + { "AUDC0.30", 0x45, EQF_WRITE }, + { "AUDC1.30", 0x46, EQF_WRITE }, + { "AUDF0.30", 0x47, EQF_WRITE }, + { "AUDF1.30", 0x48, EQF_WRITE }, + { "AUDV0.30", 0x49, EQF_WRITE }, + { "AUDV1.30", 0x4A , EQF_WRITE }, + { "GRP0.30", 0x4B, EQF_WRITE }, + { "GRP1.30", 0x4C, EQF_WRITE }, + { "ENAM0.30", 0x4D, EQF_WRITE }, + { "ENAM1.30", 0x4E, EQF_WRITE }, + { "ENABL.30", 0x4F, EQF_WRITE }, + { "HMP0.30", 0x50, EQF_WRITE }, + { "HMP1.30", 0x51, EQF_WRITE }, + { "HMM0.30", 0x52, EQF_WRITE }, + { "HMM1.30", 0x53, EQF_WRITE }, + { "HMBL.30", 0x54, EQF_WRITE }, + { "VDELP0.30", 0x55, EQF_WRITE }, + { "VDEL01.30", 0x56, EQF_WRITE }, + { "VDELP1.30", 0x56, EQF_WRITE }, + { "VDELBL.30", 0x57, EQF_WRITE }, + { "RESMP0.30", 0x58, EQF_WRITE }, + { "RESMP1.30", 0x59, EQF_WRITE }, + { "HMOVE.30", 0x5A, EQF_WRITE }, + { "HMCLR.30", 0x5B, EQF_WRITE }, + { "CXCLR.30", 0x5C, EQF_WRITE }, + +// Standard $00-based TIA read locations: + { "CXM0P", 0x00, EQF_READ }, + { "CXM1P", 0x01, EQF_READ }, + { "CXP0FB", 0x02, EQF_READ }, + { "CXP1FB", 0x03, EQF_READ }, + { "CXM0FB", 0x04, EQF_READ }, + { "CXM1FB", 0x05, EQF_READ }, + { "CXBLPF", 0x06, EQF_READ }, + { "CXPPMM", 0x07, EQF_READ }, + { "INPT0", 0x08, EQF_READ }, + { "INPT1", 0x09, EQF_READ }, + { "INPT2", 0x0A, EQF_READ }, + { "INPT3", 0x0B, EQF_READ }, + { "INPT4", 0x0C, EQF_READ }, + { "INPT5", 0x0D, EQF_READ }, + +// Mirrored $10-based TIA read locations: + { "CXM0P.10", 0x10, EQF_READ }, + { "CXM1P.10", 0x11, EQF_READ }, + { "CXP0FB.10", 0x12, EQF_READ }, + { "CXP1FB.10", 0x13, EQF_READ }, + { "CXM0FB.10", 0x14, EQF_READ }, + { "CXM1FB.10", 0x15, EQF_READ }, + { "CXBLPF.10", 0x16, EQF_READ }, + { "CXPPMM.10", 0x17, EQF_READ }, + { "INPT0.10", 0x18, EQF_READ }, + { "INPT1.10", 0x19, EQF_READ }, + { "INPT2.10", 0x1A, EQF_READ }, + { "INPT3.10", 0x1B, EQF_READ }, + { "INPT4.10", 0x1C, EQF_READ }, + { "INPT5.10", 0x1D, EQF_READ }, + +// Mirrored $20-based TIA read locations: + { "CXM0P.20", 0x20, EQF_READ }, + { "CXM1P.20", 0x21, EQF_READ }, + { "CXP0FB.20", 0x22, EQF_READ }, + { "CXP1FB.20", 0x23, EQF_READ }, + { "CXM0FB.20", 0x24, EQF_READ }, + { "CXM1FB.20", 0x25, EQF_READ }, + { "CXBLPF.20", 0x26, EQF_READ }, + { "CXPPMM.20", 0x27, EQF_READ }, + { "INPT0.20", 0x28, EQF_READ }, + { "INPT1.20", 0x29, EQF_READ }, + { "INPT2.20", 0x2A, EQF_READ }, + { "INPT3.20", 0x2B, EQF_READ }, + { "INPT4.20", 0x2C, EQF_READ }, + { "INPT5.20", 0x2D, EQF_READ }, + +// Mirrored $30-based TIA read locations: + { "CXM0P.30", 0x30, EQF_READ }, + { "CXM1P.30", 0x31, EQF_READ }, + { "CXP0FB.30", 0x32, EQF_READ }, + { "CXP1FB.30", 0x33, EQF_READ }, + { "CXM0FB.30", 0x34, EQF_READ }, + { "CXM1FB.30", 0x35, EQF_READ }, + { "CXBLPF.30", 0x36, EQF_READ }, + { "CXPPMM.30", 0x37, EQF_READ }, + { "INPT0.30", 0x38, EQF_READ }, + { "INPT1.30", 0x39, EQF_READ }, + { "INPT2.30", 0x3A, EQF_READ }, + { "INPT3.30", 0x3B, EQF_READ }, + { "INPT4.30", 0x3C, EQF_READ }, + { "INPT5.30", 0x3D, EQF_READ }, + +// Standard RIOT locations (read, write, or both): + { "SWCHA", 0x0280, EQF_READ | EQF_WRITE }, + { "SWCHB", 0x0282, EQF_READ | EQF_WRITE }, + { "SWACNT", 0x281, EQF_WRITE }, + { "SWBCNT", 0x283, EQF_WRITE }, + { "INTIM", 0x0284, EQF_READ }, + { "TIM1T", 0x0294, EQF_WRITE }, + { "TIM8T", 0x0295, EQF_WRITE }, + { "TIM64T", 0x0296, EQF_WRITE }, + { "TIM1024T", 0x0297, EQF_WRITE } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -103,11 +205,10 @@ EquateList::EquateList() for(int i=0; isecond; + else { + if(flags == EQF_ANY || flags == iter->second.flags) + return iter->second.label; + else + return nothing; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// DEPRECATED +const char *EquateList::getFormatted(int addr, int places) +{ + return getFormatted(addr, places, EQF_ANY); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // returns either the label, or a formatted hex string // if no label found. -const char *EquateList::getFormatted(int addr, int places) +const char *EquateList::getFormatted(int addr, int places, int flags) { static char fmt[10], buf[255]; - string res = getLabel(addr); + string res = getLabel(addr, flags); if(res != "") return res.c_str(); @@ -161,7 +280,7 @@ int EquateList::getAddress(const string& label) if(iter == myFwdMap.end()) return -1; else - return iter->second; + return iter->second.address; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -174,7 +293,9 @@ bool EquateList::undefine(string& label) } else { - myRevMap.erase( myRevMap.find(iter->second) ); // FIXME: error check? + // FIXME: error check? + // FIXME: memory leak! + myRevMap.erase( myRevMap.find(iter->second.address) ); myFwdMap.erase(iter); return true; } @@ -194,7 +315,7 @@ bool EquateList::saveFile(string file) labelToAddr::iterator iter; for(iter = myFwdMap.begin(); iter != myFwdMap.end(); iter++) { - sprintf(buf, "%-24s %04x \n", iter->first.c_str(), iter->second); + sprintf(buf, "%-24s %04x \n", iter->second.label.c_str(), iter->second.address); out << buf; } @@ -254,9 +375,14 @@ string EquateList::loadFile(string file) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EquateList::addEquate(string label, int address) { + Equate *e = new Equate; + e->label = label; + e->address = address; + e->flags = EQF_ANY; + undefine(label); - myFwdMap.insert(make_pair(label, address)); - myRevMap.insert(make_pair(address, label)); + myFwdMap.insert(make_pair(label, *e)); + myRevMap.insert(make_pair(address, *e)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/stella/src/debugger/EquateList.hxx b/stella/src/debugger/EquateList.hxx index 2980eb0fc..c1217065e 100644 --- a/stella/src/debugger/EquateList.hxx +++ b/stella/src/debugger/EquateList.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: EquateList.hxx,v 1.12 2005-12-09 01:16:13 stephena Exp $ +// $Id: EquateList.hxx,v 1.13 2006-06-09 02:45:11 urchlay Exp $ //============================================================================ #ifndef EQUATELIST_HXX @@ -27,8 +27,8 @@ using namespace std; -typedef map addrToLabel; -typedef map labelToAddr; +typedef map addrToLabel; +typedef map labelToAddr; typedef Common::Array Equates; @@ -37,9 +37,13 @@ class EquateList { EquateList(); ~EquateList(); const string& getLabel(int addr); + const string& getLabel(int addr, int flags); const char *getFormatted(int addr, int places); + const char *getFormatted(int addr, int places, const int flags); int getAddress(const string& label); + int getAddress(const string& label, const int flags); void addEquate(string label, int address); + // void addEquate(string label, int address, const int flags); bool saveFile(string file); string loadFile(string file); bool undefine(string& label); diff --git a/stella/src/debugger/gui/CpuWidget.cxx b/stella/src/debugger/gui/CpuWidget.cxx index a2e60549e..4311705fc 100644 --- a/stella/src/debugger/gui/CpuWidget.cxx +++ b/stella/src/debugger/gui/CpuWidget.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: CpuWidget.cxx,v 1.4 2006-02-22 17:38:04 stephena Exp $ +// $Id: CpuWidget.cxx,v 1.5 2006-06-09 02:45:11 urchlay Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -280,5 +280,5 @@ void CpuWidget::fillGrid() changed.push_back(state.PSbits[i] != oldstate.PSbits[i]); myPSRegister->setState(state.PSbits, changed); - myPCLabel->setEditString(dbg.equates()->getLabel(state.PC)); + myPCLabel->setEditString(dbg.equates()->getLabel(state.PC, EQF_ROM)); } diff --git a/stella/src/debugger/gui/RamWidget.cxx b/stella/src/debugger/gui/RamWidget.cxx index f794e7ba4..9f57acd00 100644 --- a/stella/src/debugger/gui/RamWidget.cxx +++ b/stella/src/debugger/gui/RamWidget.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: RamWidget.cxx,v 1.6 2006-05-04 17:45:24 stephena Exp $ +// $Id: RamWidget.cxx,v 1.7 2006-06-09 02:45:11 urchlay Exp $ // // Based on code from ScummVM - Scumm Interpreter // Copyright (C) 2002-2004 The ScummVM project @@ -183,7 +183,8 @@ void RamWidget::handleCommand(CommandSender* sender, int cmd, int data, int id) addr = myRamGrid->getSelectedAddr(); value = myRamGrid->getSelectedValue(); - buf = instance()->debugger().equates()->getLabel(addr+kRamStart).c_str(); + buf = instance()->debugger().equates()->getLabel( + addr+kRamStart, EQF_RAM).c_str(); if(*buf) myLabel->setEditString(buf); else myLabel->setEditString(""); diff --git a/stella/src/emucore/AtariVox.cxx b/stella/src/emucore/AtariVox.cxx new file mode 100644 index 000000000..b6c750491 --- /dev/null +++ b/stella/src/emucore/AtariVox.cxx @@ -0,0 +1,103 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team +// +// See the file "license" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id: AtariVox.cxx,v 1.1 2006-06-09 02:45:11 urchlay Exp $ +//============================================================================ + +#include "Event.hxx" +#include "AtariVox.hxx" + +#define DEBUG_ATARIVOX 1 + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +AtariVox::AtariVox(Jack jack, const Event& event) + : Controller(jack, event), + myPinState(0), + myShiftRegister(0), + myShiftCount(0) +{ + myType = Controller::AtariVox; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +AtariVox::~AtariVox() +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool AtariVox::read(DigitalPin pin) +{ + // For now, always return true, meaning the device is ready +/* + if(DEBUG_ATARIVOX) + cerr << "AtariVox: read from SWCHA" << endl; +*/ + return true; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Int32 AtariVox::read(AnalogPin) +{ + // Analog pins are not connected in AtariVox, so we have infinite resistance + return maximumResistance; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void AtariVox::write(DigitalPin pin, bool value) +{ + if(DEBUG_ATARIVOX) + cerr << "AtariVox: write to SWCHA" << endl; + + // Change the pin state based on value + switch(pin) + { + // Pin 1 is the DATA line, used to output serial data to the + // speakjet + case One: + if(DEBUG_ATARIVOX) + cerr << "AtariVox: value " << value << " written to DATA line" << endl; + myShiftRegister >>= 1; + myShiftRegister |= (value << 15); + // cerr << myShiftRegister << endl; + if(++myShiftCount == 10) { + myShiftCount = 0; + myShiftRegister >>= 6; + // cerr << "(<<6) == " << myShiftRegister << endl; + if(!(myShiftRegister & (1<<9))) + cerr << "AtariVox: bad start bit" << endl; + else if((myShiftRegister & 1)) + cerr << "AtariVox: bad stop bit" << endl; + else + cerr << "AtariVox: output byte " + << ((myShiftRegister >> 1) & 0xff) + << endl; + myShiftRegister = 0; + } + break; + + // Pin 2 is the SDA line, used to output data to the 24LC256 + // serial EEPROM, using the I2C protocol. + // I'm not even trying to emulate this right now :( + case Two: + if(DEBUG_ATARIVOX) + cerr << "AtariVox: value " << value << " written to SDA line" << endl; + break; + + case Three: + case Four: + default: + break; + } +} diff --git a/stella/src/emucore/AtariVox.hxx b/stella/src/emucore/AtariVox.hxx new file mode 100644 index 000000000..b5c21237d --- /dev/null +++ b/stella/src/emucore/AtariVox.hxx @@ -0,0 +1,93 @@ + +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2005 by Bradford W. Mott and the Stella team +// +// See the file "license" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +// +// $Id: AtariVox.hxx,v 1.1 2006-06-09 02:45:11 urchlay Exp $ +//============================================================================ + +#ifndef ATARIVOX_HXX +#define ATARIVOX_HXX + +#include "bspf.hxx" +#include "Control.hxx" + +/** + Alex Herbert's AtariVox "controller": A speech synthesizer and + storage device. + + @author B. Watson + @version $Id: AtariVox.hxx,v 1.1 2006-06-09 02:45:11 urchlay Exp $ +*/ +class AtariVox : public Controller +{ + public: + /** + Create a new AtariVox controller plugged into the specified jack + + @param jack The jack the controller is plugged into + @param event The event object to use for events + */ + AtariVox(Jack jack, const Event& event); + + /** + Destructor + */ + virtual ~AtariVox(); + + public: + /** + Read the value of the specified digital pin for this controller. + + @param pin The pin of the controller jack to read + @return The state of the pin + */ + virtual bool read(DigitalPin pin); + + /** + Read the resistance at the specified analog pin for this controller. + The returned value is the resistance measured in ohms. + + The AtariVox doesn't use the analog pins. + + @param pin The pin of the controller jack to read + @return The resistance at the specified pin + */ + virtual Int32 read(AnalogPin pin); + + /** + Write the given value to the specified digital pin for this + controller. Writing is only allowed to the pins associated + with the PIA. Therefore you cannot write to pin six. + + @param pin The pin of the controller jack to write to + @param value The value to write to the pin + */ + virtual void write(DigitalPin pin, bool value); + + private: + // State of the output pins + uInt8 myPinState; + + // Shift register. Data comes in serially: + // 1 start bit, always 0 + // 8 data bits, LSB first + // 1 stop bit, always 0 + uInt16 myShiftRegister; + + // How many bits have been shifted into the shift register? + uInt8 myShiftCount; +}; + +#endif diff --git a/stella/src/emucore/Console.cxx b/stella/src/emucore/Console.cxx index 7f3c18ffe..1aa6a259e 100644 --- a/stella/src/emucore/Console.cxx +++ b/stella/src/emucore/Console.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Console.cxx,v 1.89 2006-04-04 23:15:42 stephena Exp $ +// $Id: Console.cxx,v 1.90 2006-06-09 02:45:11 urchlay Exp $ //============================================================================ #include @@ -21,6 +21,7 @@ #include #include +#include "AtariVox.hxx" #include "Booster.hxx" #include "Cart.hxx" #include "Console.hxx" @@ -157,6 +158,10 @@ Console::Console(const uInt8* image, uInt32 size, const string& md5, { myControllers[1] = new Paddles(rightjack, *myEvent); } + else if(right == "ATARIVOX") + { + myControllers[1] = new AtariVox(rightjack, *myEvent); + } else { myControllers[1] = new Joystick(rightjack, *myEvent); diff --git a/stella/src/emucore/Control.hxx b/stella/src/emucore/Control.hxx index 1a50c949e..3ea3c3969 100644 --- a/stella/src/emucore/Control.hxx +++ b/stella/src/emucore/Control.hxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: Control.hxx,v 1.4 2005-11-12 22:59:20 stephena Exp $ +// $Id: Control.hxx,v 1.5 2006-06-09 02:45:11 urchlay Exp $ //============================================================================ #ifndef CONTROLLER_HXX @@ -55,7 +55,7 @@ class Event; of the controller from the prespective of the controller's jack. @author Bradford W. Mott - @version $Id: Control.hxx,v 1.4 2005-11-12 22:59:20 stephena Exp $ + @version $Id: Control.hxx,v 1.5 2006-06-09 02:45:11 urchlay Exp $ */ class Controller { @@ -73,7 +73,7 @@ class Controller */ enum Type { - BoosterGrip, Driving, Keyboard, Paddles, Joystick + BoosterGrip, Driving, Keyboard, Paddles, Joystick, AtariVox }; public: diff --git a/stella/src/emucore/M6532.cxx b/stella/src/emucore/M6532.cxx index d3ab9b699..6648ae81f 100644 --- a/stella/src/emucore/M6532.cxx +++ b/stella/src/emucore/M6532.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: M6532.cxx,v 1.6 2005-12-17 01:23:07 stephena Exp $ +// $Id: M6532.cxx,v 1.7 2006-06-09 02:45:11 urchlay Exp $ //============================================================================ #include @@ -238,6 +238,30 @@ void M6532::poke(uInt16 addr, uInt8 value) else if((addr & 0x07) == 0x01) // Port A Data Direction Register { myDDRA = value; + /* + 20060608 bkw: Not the most elegant thing in the world... + When a bit in the DDR is set as input, +5V is placed on its output + pin. When it's set as output, either +5V or 0V (depending on the + contents of SWCHA) will be placed on the output pin. + The standard macros for the AtariVox use this fact to send data + to the port. + + This code isn't 100% correct: it assumes the SWCHA bits are all 0. + This is good enough to emulate the AtariVox, if the programmer is + using SWACNT to do output (e.g. the SPKOUT macro from speakjet.inc) + and if he's leaving SWCHA alone. + + The inaccuracy here means that wrongly-written code will still + be able to drive the emulated AtariVox, even though it wouldn't + work on real hardware. + */ + Controller &c = myConsole.controller(Controller::Right); + if(c.type() == Controller::AtariVox) { + c.write(Controller::One, !(value & 0x01)); + c.write(Controller::Two, !(value & 0x02)); + c.write(Controller::Three, !(value & 0x04)); + c.write(Controller::Four, !(value & 0x08)); + } } else if((addr & 0x07) == 0x02) // Port B I/O Register (Console switches) { diff --git a/stella/src/emucore/m6502/src/M6502.cxx b/stella/src/emucore/m6502/src/M6502.cxx index 903abadc7..a7ca234a9 100644 --- a/stella/src/emucore/m6502/src/M6502.cxx +++ b/stella/src/emucore/m6502/src/M6502.cxx @@ -13,7 +13,7 @@ // See the file "license" for information on usage and redistribution of // this file, and for a DISCLAIMER OF ALL WARRANTIES. // -// $Id: M6502.cxx,v 1.15 2005-09-20 19:09:10 stephena Exp $ +// $Id: M6502.cxx,v 1.16 2006-06-09 02:45:11 urchlay Exp $ //============================================================================ #include "M6502.hxx" @@ -350,6 +350,60 @@ const char* M6502::ourInstructionMnemonicTable[256] = { }; #ifdef DEVELOPER_SUPPORT +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +// This needs to be a list of all 256 opcodes and the type of memory +// access they do (read, write, read/modify/write, or none). The +// disassemble() method will use this to figure out what kind of label +// to use in the disassembly. +//// const char* M6502::ourLabelTypeTable[256] = { +//// }; +//// +//// // disassemble() will use isXXX methods to determine what type of +//// // label to show to the user (e.g. isTIA == true means to show a +//// // non-user label; isRAM == true means to show a user r/w label, etc) +//// +//// // These methods were based on (and checked against) Kroko's +//// // 2600 memory map, found at +//// // http://www.qotile.net/minidig/docs/2600_mem_map.txt +//// +//// // is the address in RIOT RAM? +//// bool isRAM(int addr) { +//// int y = addr & 0xf00; +//// int z = addr & 0xff; +//// +//// return !isROM(addr) +//// && +//// z >= 0x80 +//// && +//// (y == 0 || y == 0x100 || y == 0x400 || y == 0x500 || +//// y == 0x800 || y == 0x900 || y == 0xc00 || y == 0xd00); +//// } +//// +//// // is the address one of the non-RAM RIOT areas? +//// bool isRIOT(int addr) { +//// int y = addr & 0xf00; +//// int z = addr & 0xff; +//// +//// return !isROM(addr) +//// && +//// z >= 0x80 +//// && +//// (y == 0x200 || y == 0x300 || y == 0x600 || y == 0x700 || +//// y == 0xa00 || y == 0xb00 || y == 0xe00 || y == 0xf00); +//// } +//// +//// // is the address in one of the TIA mirrors? +//// bool isTIA(int addr) { +//// int z = addr & 0xff; +//// return !isROM(addr) && (z < 0x80); +//// } +//// +//// // is the address in ROM? +//// bool isROM(int addr) { +//// // ROM addresses are $xnnn where x is odd +//// return addr % 8192 > 4095; +//// } + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void M6502::attach(Debugger& debugger) { diff --git a/stella/src/emucore/module.mk b/stella/src/emucore/module.mk index 0bc218869..9e3728c43 100644 --- a/stella/src/emucore/module.mk +++ b/stella/src/emucore/module.mk @@ -1,6 +1,7 @@ MODULE := src/emucore MODULE_OBJS := \ + src/emucore/AtariVox.o \ src/emucore/Booster.o \ src/emucore/Cart2K.o \ src/emucore/Cart3F.o \