Added call to "ctags" to Makefile. Shouldn't cause any problems for

people who don't have ctags installed.

WIP debugger equate restructuring.

WIP AtariVox emulation. Not very far along yet, but at the moment,
we're able to read the speech data output by vox_test.bin and spit out
the phoneme values on stderr.


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@1109 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
urchlay 2006-06-09 02:45:11 +00:00
parent 927a8cfd68
commit 21ebade382
14 changed files with 534 additions and 103 deletions

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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 <fstream>
@ -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; i<size; i++)
{
string l = hardCodedEquates[i].label;
int a = hardCodedEquates[i].address;
Equate e = hardCodedEquates[i];
myFwdMap.insert(make_pair(l, a));
myRevMap.insert(make_pair(a, l));
myFwdMap.insert(make_pair(e.label, e));
myRevMap.insert(make_pair(e.address, e));
}
calcSize();
}
@ -126,24 +227,42 @@ int EquateList::calcSize() {
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// DEPRECATED
const string& EquateList::getLabel(int addr)
{
return getLabel(addr, EQF_ANY);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const string& EquateList::getLabel(int addr, int flags)
{
static string nothing = "";
addrToLabel::const_iterator iter = myRevMap.find(addr);
if(iter == myRevMap.end())
return nothing;
else
return iter->second;
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));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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<int, string> addrToLabel;
typedef map<string, int> labelToAddr;
typedef map<int, Equate> addrToLabel;
typedef map<string, Equate> labelToAddr;
typedef Common::Array<Equate> 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);

View File

@ -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));
}

View File

@ -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("");

View File

@ -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;
}
}

View File

@ -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

View File

@ -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 <assert.h>
@ -21,6 +21,7 @@
#include <sstream>
#include <fstream>
#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);

View File

@ -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:

View File

@ -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 <assert.h>
@ -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)
{

View File

@ -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)
{

View File

@ -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 \